Compare commits

...

2 commits
0.3.0 ... main

Author SHA1 Message Date
Caleb Connolly
080fcf60ca
line split mid-word instead of hanging
The line splitting implementation would look behind to find a space to
split on. This does not work if the line is one long word (like a URL),
and this implementation would hang as a result.

Add support for splitting mid-word in this case and prevent pbsplash
from hanging.
2023-03-06 01:12:31 +00:00
Caleb Connolly
52cb0ae649
nanosvgrast: small cleanup 2023-03-06 00:28:35 +00:00
2 changed files with 46 additions and 14 deletions

View file

@ -1421,7 +1421,6 @@ void nsvgRasterizeText(NSVGrasterizer* r,
if (i == 0 && strcmp(shape->id, "OpenSansRegular") == 0) if (i == 0 && strcmp(shape->id, "OpenSansRegular") == 0)
tx = xStart - charWidth; tx = xStart - charWidth;
//tx -= shape->horizAdvX * scale * 0.5;
if (shape->fill.type != NSVG_PAINT_NONE) { if (shape->fill.type != NSVG_PAINT_NONE) {
nsvg__resetPool(r); nsvg__resetPool(r);

View file

@ -156,6 +156,15 @@ static void draw_text(const NSVGimage *font, const char *text, int x, int y, int
nsvgDeleteRasterizer(rast); nsvgDeleteRasterizer(rast);
} }
static inline float getShapeWidth(const NSVGimage *font, const NSVGshape *shape)
{
if (shape) {
return shape->horizAdvX;
} else {
return font->defaultHorizAdv;
}
}
/* /*
* Get the dimensions of a string in pixels. * Get the dimensions of a string in pixels.
* based on the font size and the font SVG file. * based on the font size and the font SVG file.
@ -163,46 +172,70 @@ static void draw_text(const NSVGimage *font, const char *text, int x, int y, int
static const char *getTextDimensions(const NSVGimage *font, const char *text, float scale, static const char *getTextDimensions(const NSVGimage *font, const char *text, float scale,
int *width, int *height) int *width, int *height)
{ {
int i; int i, j;
int fontHeight = (font->fontAscent - font->fontDescent) * scale; int fontHeight = (font->fontAscent - font->fontDescent) * scale;
int maxWidth = 0; int maxWidth = 0;
if (text == NULL) if (text == NULL)
return text; return text;
char *out_text = zalloc(strlen(text) + 1); // Pre-allocate 3x the size to account for any word splitting
char *out_text = zalloc(strlen(text) * 3 + 1);
*width = 2; // font->defaultHorizAdv * scale; *width = 2; // font->defaultHorizAdv * scale;
// The height is simply the height of the font * the scale factor // The height is simply the height of the font * the scale factor
*height = fontHeight; *height = fontHeight;
NSVGshape **shapes = nsvgGetTextShapes(font, text, strlen(text)); NSVGshape **shapes = nsvgGetTextShapes(font, text, strlen(text));
bool line_has_space = false;
// Iterate over every glyph in the string to get the total width // Iterate over every glyph in the string to get the total width
for (i = 0; text[i] != '\0'; i++) { // and handle line-splitting
for (i = 0, j = 0; text[i] != '\0'; i++, j++) {
NSVGshape *shape = shapes[i]; NSVGshape *shape = shapes[i];
out_text[i] = text[i]; out_text[j] = text[i];
if (*width > screenWidth * 0.95) { if (*width > screenWidth * 0.95) {
while (out_text[i] != ' ' && i > 0) if (!line_has_space)
i--; i--;
out_text[i] = '\n'; if (!line_has_space) {
if (i < 1) {
fprintf(stderr,
"ERROR: Text is too long to fit on screen!");
goto out;
}
} else {
int old_j = j;
while (out_text[j] != ' ' && j > 0) {
j--;
}
i = i - (old_j - j);
if (i <= 0) {
line_has_space = false;
fprintf(stderr,
"ERROR: Text is too long to fit on screen!");
goto out;
}
}
out_text[j] = '\n';
} }
if (out_text[i] == '\n') { if (out_text[j] == '\n') {
printf("LINE SPLIT, %d %s\n", i, out_text);
line_has_space = false;
*height += fontHeight; *height += fontHeight;
maxWidth = *width > maxWidth ? *width : maxWidth; maxWidth = *width > maxWidth ? *width : maxWidth;
*width = 0; *width = 0;
continue; continue;
} else if (text[i] == ' ') {
printf("SPACE! %s\n", out_text);
line_has_space = true;
} }
if (shape) { *width += round(getShapeWidth(font, shape) * scale);
*width += (float)shapes[i]->horizAdvX * scale;
} else {
*width += font->defaultHorizAdv * scale;
}
} }
*width = *width > maxWidth ? *width : maxWidth; *width = *width > maxWidth ? *width : maxWidth;
out:
free(shapes); free(shapes);
return out_text; return out_text;
} }