[Scummvm-cvs-logs] CVS: scummvm/graphics font.cpp,1.9,1.10 font.h,1.7,1.8

Max Horn fingolfin at users.sourceforge.net
Sun May 15 09:14:43 CEST 2005


Update of /cvsroot/scummvm/scummvm/graphics
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12556

Modified Files:
	font.cpp font.h 
Log Message:
Added Font::wordWrapText method

Index: font.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/graphics/font.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- font.cpp	2 May 2005 18:00:05 -0000	1.9
+++ font.cpp	15 May 2005 16:13:52 -0000	1.10
@@ -156,4 +156,92 @@
 }
 
 
+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

Index: font.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/graphics/font.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- font.h	2 May 2005 18:00:05 -0000	1.7
+++ font.h	15 May 2005 16:13:52 -0000	1.8
@@ -37,14 +37,6 @@
  * 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 @@
 	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;
 };
 
 





More information about the Scummvm-git-logs mailing list