mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-01 05:11:09 +00:00
Added Font::wordWrapText method
svn-id: r18109
This commit is contained in:
parent
aedd11b353
commit
4d5073b154
@ -156,4 +156,92 @@ void Font::drawString(Surface *dst, const Common::String &s, int x, int y, int w
|
||||
}
|
||||
|
||||
|
||||
struct WordWrapper {
|
||||
Common::StringList &lines;
|
||||
int actualMaxLineWidth;
|
||||
|
||||
WordWrapper(Common::StringList &l) : lines(l), actualMaxLineWidth(0) {
|
||||
}
|
||||
|
||||
void add(Common::String &line, int &w) {
|
||||
if (actualMaxLineWidth < w)
|
||||
actualMaxLineWidth = w;
|
||||
|
||||
lines.push_back(line);
|
||||
|
||||
line.clear();
|
||||
w = 0;
|
||||
}
|
||||
};
|
||||
|
||||
int Font::wordWrapText(const Common::String &str, int maxWidth, Common::StringList &lines) const {
|
||||
WordWrapper wrapper(lines);
|
||||
Common::String line;
|
||||
Common::String tmpStr;
|
||||
int lineWidth = 0;
|
||||
int tmpWidth = 0;
|
||||
|
||||
// The rough idea behind this algorithm is as follows:
|
||||
// We accumulate characters into the string tmpStr. Whenever a full word
|
||||
// has been gathered together this way, we 'commit' it to the line buffer
|
||||
// 'line', i.e. we add tmpStr to the end of line, then clear it. Before
|
||||
// we do that, we check whether it would cause 'line' to exceed maxWidth;
|
||||
// in that case, we first add line to lines, then reset it.
|
||||
//
|
||||
// If a newline character is read, then we also add line to lines and clear it.
|
||||
//
|
||||
// Special care has to be taken to account for 'words' that exceed the width
|
||||
// of a line. If we encounter such a word, we have to wrap it over multiple
|
||||
// lines.
|
||||
|
||||
for (Common::String::const_iterator x = str.begin(); x != str.end(); ++x) {
|
||||
const char c = *x;
|
||||
const int w = getCharWidth(c);
|
||||
|
||||
// If this char is a whitespace, then it represents a potential
|
||||
// 'wrap point' where wrapping could take place. Everything that
|
||||
// came before it can now safely be added to the line, as we know
|
||||
// that it will not have to be wrapped.
|
||||
if (isspace(c)) {
|
||||
line += tmpStr;
|
||||
lineWidth += tmpWidth;
|
||||
|
||||
tmpStr.clear();
|
||||
tmpWidth = 0;
|
||||
}
|
||||
|
||||
// If we encounter a line break (\n), the line is complete.
|
||||
if (c == '\n') {
|
||||
wrapper.add(line, lineWidth);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the max line width would be exceeded by adding this char,
|
||||
// insert a line break.
|
||||
if (lineWidth + tmpWidth + w > maxWidth) {
|
||||
// Commit what we have so far, *if* we have anything.
|
||||
// If line is empty, then we are looking at a word
|
||||
// which exceeds the maximum line width.
|
||||
if (lineWidth > 0) {
|
||||
wrapper.add(line, lineWidth);
|
||||
} else {
|
||||
wrapper.add(tmpStr, tmpWidth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tmpWidth += w;
|
||||
tmpStr += c;
|
||||
}
|
||||
|
||||
// If some text is left over, add it as the final line
|
||||
line += tmpStr;
|
||||
lineWidth += tmpWidth;
|
||||
if (lineWidth > 0) {
|
||||
wrapper.add(line, lineWidth);
|
||||
}
|
||||
return wrapper.actualMaxLineWidth;
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
@ -37,14 +37,6 @@ enum TextAlignment {
|
||||
* Instances of this class represent a distinct font, with a built-in renderer.
|
||||
* @todo Maybe move the high-level methods (drawString etc.) to a separate
|
||||
* FontRenderer class? That way, we could have different variants... ?
|
||||
* @todo Add more parameters to drawString, or additional similar methods,
|
||||
* featuring abilities like
|
||||
* - rendering with wrap-around instead of inserting an ellipsis or
|
||||
* cutting them; needs a 'height' parameter
|
||||
* - rendering multi-line strings (essentially, invoke the regular
|
||||
* drawString for each line, and advance one line)
|
||||
* - combinations of the two above: honor line feeds, and also wrap
|
||||
* overlong lines
|
||||
*/
|
||||
class Font {
|
||||
public:
|
||||
@ -55,7 +47,26 @@ public:
|
||||
virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const = 0;
|
||||
|
||||
void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlignment align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
|
||||
|
||||
/**
|
||||
* Compute and return the width the string str has when rendered using this font.
|
||||
*/
|
||||
int getStringWidth(const Common::String &str) const;
|
||||
|
||||
/**
|
||||
* Take a text (which may contain newlines characters) and word wrap it so thata
|
||||
* no text line is wider than maxWidth pixels. If necessary, additional line breaks
|
||||
* are generated, preferably between words (i.e. were whitespaces are).
|
||||
* The resulting lines are appended to the string list lines.
|
||||
* It returns the maximal width of any of the new lines (i.e. a value which is less
|
||||
* or equal to maxWidth).
|
||||
*
|
||||
* @param str the string to word wrap
|
||||
* @param maxWidth the maximum width a line may have
|
||||
* @param lines the string list to which the text lines from str are appended
|
||||
* @return the maximal width of any of the lines added to lines
|
||||
*/
|
||||
int wordWrapText(const Common::String &str, int maxWidth, Common::StringList &lines) const;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user