mirror of
https://git.sr.ht/~calebccff/pbsplash
synced 2026-01-12 20:48:40 -09:00
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.
This commit is contained in:
parent
52cb0ae649
commit
080fcf60ca
1 changed files with 46 additions and 13 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue