FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string) { FBrokenLines lines[128]; // Support up to 128 lines (should be plenty) const BYTE *space = NULL, *start = string; size_t i, ii; int c, w, nw; FString lastcolor, linecolor; bool lastWasSpace = false; int kerning = font->GetDefaultKerning (); i = w = 0; while ( (c = *string++) && i < countof(lines) ) { if (c == TEXTCOLOR_ESCAPE) { if (*string) { if (*string == '[') { const BYTE *start = string; while (*string != ']' && *string != '\0') { string++; } if (*string != '\0') { string++; } lastcolor = FString((const char *)start, string - start); } else { lastcolor = *string++; } } continue; } if (isspace(c)) { if (!lastWasSpace) { space = string - 1; lastWasSpace = true; } } else { lastWasSpace = false; } nw = font->GetCharWidth (c); if ((w > 0 && w + nw > maxwidth) || c == '\n') { // Time to break the line if (!space) space = string - 1; breakit (&lines[i], font, start, space, linecolor); if (c == '\n') { lastcolor = ""; // Why, oh why, did I do it like this? } linecolor = lastcolor; i++; w = 0; lastWasSpace = false; start = space; space = NULL; while (*start && isspace (*start) && *start != '\n') start++; if (*start == '\n') start++; else while (*start && isspace (*start)) start++; string = start; } else { w += nw + kerning; } } // String here is pointing one character after the '\0' if (i < countof(lines) && --string - start >= 1) { const BYTE *s = start; while (s < string) { // If there is any non-white space in the remainder of the string, add it. if (!isspace (*s++)) { breakit (&lines[i++], font, start, string, linecolor); break; } } } // Make a copy of the broken lines and return them FBrokenLines *broken = new FBrokenLines[i+1]; for (ii = 0; ii < i; ++ii) { broken[ii] = lines[ii]; } broken[ii].Width = -1; return broken; }
brokenlines_t* V_BreakLines(const OFont* font, int maxwidth, const byte* string) { brokenlines_t lines[128]; // Support up to 128 lines (should be plenty) const byte* space = NULL; const byte* start = string; int c, i = 0; bool lastWasSpace = false; int width = 0; while ( (c = *string++) ) { if (c == 0x8a) { if (*string) string++; continue; } if (isspace(c)) { if (!lastWasSpace) { space = string - 1; lastWasSpace = true; } } else lastWasSpace = false; int charwidth = font->getTextWidth(c); // Time to break the line if (width + charwidth > maxwidth || c == '\n') { if (!space) space = string - 1; breakit(&lines[i], start, space, font); i++; width = 0; lastWasSpace = false; start = space; space = NULL; while (*start && isspace(*start) && *start != '\n') start++; if (*start == '\n') start++; else { while (*start && isspace(*start)) start++; } string = start; } else { width += charwidth; } } if (string - start > 1) { const byte* s = start; while (s < string) { if (!isspace(*s++)) { breakit(&lines[i++], start, string, font); break; } } } // Make a copy of the broken lines and return them brokenlines_t *broken = new brokenlines_t[i+1]; memcpy(broken, lines, sizeof(brokenlines_t) * i); broken[i].string = NULL; broken[i].width = -1; return broken; }