Changeset - r20456:0170ff7ae55b
[Not reviewed]
master
0 1 0
rubidium - 11 years ago 2013-06-25 20:44:23
rubidium@openttd.org
(svn r25471) -Fix/Feature [FS#5481]: support for Brahmic scripts (e.g. Tamil and Thai)
1 file changed with 66 insertions and 64 deletions:
0 comments (0 inline, 0 general)
src/gfx.cpp
Show inline comments
 
@@ -742,50 +742,49 @@ static int DrawString(int left, int righ
 
 * @param right  The right most position to draw on.
 
 * @param top    The top most position to draw on.
 
 * @param str    String to draw.
 
 * @param colour Colour used for drawing the string, see DoDrawString() for details
 
 * @param align  The alignment of the string when drawing left-to-right. In the
 
 *               case a right-to-left language is chosen this is inverted so it
 
 *               will be drawn in the right direction.
 
 * @param underline Whether to underline what has been drawn or not.
 
 * @param fontsize The size of the initial characters.
 
 */
 
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 
	strecpy(buffer, str, lastof(buffer));
 
	DrawStringParams params(colour, fontsize);
 
	return DrawString(left, right, top, buffer, lastof(buffer), params, align, underline);
 
	Layouter layout(str, right - left + 1, colour, fontsize);
 
	if (layout.Length() == 0) return 0;
 

	
 
	return DrawLayoutLine(*layout.Begin(), top, left, right, align, underline);
 
}
 

	
 
/**
 
 * Draw string, possibly truncated to make it fit in its allocated space
 
 *
 
 * @param left   The left most position to draw on.
 
 * @param right  The right most position to draw on.
 
 * @param top    The top most position to draw on.
 
 * @param str    String to draw.
 
 * @param colour Colour used for drawing the string, see DoDrawString() for details
 
 * @param align  The alignment of the string when drawing left-to-right. In the
 
 *               case a right-to-left language is chosen this is inverted so it
 
 *               will be drawn in the right direction.
 
 * @param underline Whether to underline what has been drawn or not.
 
 * @param fontsize The size of the initial characters.
 
 */
 
int DrawString(int left, int right, int top, StringID str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 
	GetString(buffer, str, lastof(buffer));
 
	DrawStringParams params(colour, fontsize);
 
	return DrawString(left, right, top, buffer, lastof(buffer), params, align, underline);
 
	return DrawString(left, right, top, buffer, colour, align, underline, fontsize);
 
}
 

	
 
/**
 
 * 'Correct' a string to a maximum length. Longer strings will be cut into
 
 * additional lines at whitespace characters if possible. The string parameter
 
 * is modified with terminating characters mid-string which are the
 
 * placeholders for the newlines.
 
 * The string WILL be truncated if there was no whitespace for the current
 
 * line's maximum width.
 
 *
 
 * @note To know if the terminating '\0' is the string end or just a
 
 * newline, the returned 'num' value should be consulted. The num'th '\0',
 
@@ -911,82 +910,70 @@ static int GetMultilineStringHeight(cons
 
			default:           maxy = max<int>(maxy, y + fh);       break;
 
		}
 
	}
 
}
 

	
 

	
 
/**
 
 * Calculates height of string (in pixels). The string is changed to a multiline string if needed.
 
 * @param str string to check
 
 * @param maxw maximum string width
 
 * @return height of pixels of string when it is drawn
 
 */
 
static int GetStringHeight(const char *str, int maxw)
 
{
 
	Layouter layout(str, maxw);
 
	return layout.GetBounds().height;
 
}
 

	
 
/**
 
 * Calculates height of string (in pixels). The string is changed to a multiline string if needed.
 
 * @param str string to check
 
 * @param maxw maximum string width
 
 * @return height of pixels of string when it is drawn
 
 */
 
int GetStringHeight(StringID str, int maxw)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 

	
 
	GetString(buffer, str, lastof(buffer));
 

	
 
	uint32 tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw);
 

	
 
	return GetMultilineStringHeight(buffer, GB(tmp, 0, 16), FS_NORMAL);
 
	return GetStringHeight(buffer, maxw);
 
}
 

	
 
/**
 
 * Calculates number of lines of string. The string is changed to a multiline string if needed.
 
 * @param str string to check
 
 * @param maxw maximum string width
 
 * @return number of lines of string when it is drawn
 
 */
 
int GetStringLineCount(StringID str, int maxw)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 

	
 
	GetString(buffer, str, lastof(buffer));
 

	
 
	uint32 tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw);
 

	
 
	return 1 + GB(tmp, 0, 16);
 
	Layouter layout(buffer, maxw);
 
	return layout.Length();
 
}
 

	
 
/**
 
 * Calculate string bounding box for multi-line strings.
 
 * @param str        String to check.
 
 * @param suggestion Suggested bounding box.
 
 * @return Bounding box for the multi-line string, may be bigger than \a suggestion.
 
 */
 
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion)
 
{
 
	Dimension box = {suggestion.width, GetStringHeight(str, suggestion.width)};
 
	return box;
 
}
 

	
 

	
 
/**
 
 * Calculates height of string (in pixels). The string is changed to a multiline string if needed.
 
 * @param str string to check
 
 * @param maxw maximum string width
 
 * @return height of pixels of string when it is drawn
 
 */
 
int GetStringHeight(const char *str, int maxw)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 

	
 
	strecpy(buffer, str, lastof(buffer));
 

	
 
	uint32 tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw);
 

	
 
	return GetMultilineStringHeight(buffer, GB(tmp, 0, 16), FS_NORMAL);
 
}
 

	
 
/**
 
 * Calculate string bounding box for multi-line strings.
 
 * @param str        String to check.
 
 * @param suggestion Suggested bounding box.
 
 * @return Bounding box for the multi-line string, may be bigger than \a suggestion.
 
 */
 
Dimension GetStringMultiLineBoundingBox(const char *str, const Dimension &suggestion)
 
{
 
	Dimension box = {suggestion.width, GetStringHeight(str, suggestion.width)};
 
	return box;
 
}
 

	
 
@@ -1095,90 +1082,105 @@ static int DrawStringMultiLine(int left,
 
 * @param top    The top most position to draw on.
 
 * @param bottom The bottom most position to draw on.
 
 * @param str    String to draw.
 
 * @param colour Colour used for drawing the string, see DoDrawString() for details
 
 * @param align  The horizontal and vertical alignment of the string.
 
 * @param underline Whether to underline all strings
 
 * @param fontsize The size of the initial characters.
 
 *
 
 * @return If \a align is #SA_BOTTOM, the top to where we have written, else the bottom to where we have written.
 
 */
 
int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 
	strecpy(buffer, str, lastof(buffer));
 
	return DrawStringMultiLine(left, right, top, bottom, buffer, lastof(buffer), colour, align, underline, fontsize);
 
	int maxw = right - left + 1;
 
	int maxh = bottom - top + 1;
 

	
 
	/* It makes no sense to even try if it can't be drawn anyway, or
 
	 * do we really want to support fonts of 0 or less pixels high? */
 
	if (maxh <= 0) return top;
 

	
 
	Layouter layout(str, maxw, colour, fontsize);
 
	int total_height = layout.GetBounds().height;
 
	int y;
 
	switch (align & SA_VERT_MASK) {
 
		case SA_TOP:
 
			y = top;
 
			break;
 

	
 
		case SA_VERT_CENTER:
 
			y = RoundDivSU(bottom + top - total_height, 2);
 
			break;
 

	
 
		case SA_BOTTOM:
 
			y = bottom - total_height;
 
			break;
 

	
 
		default: NOT_REACHED();
 
	}
 

	
 
	int last_line = top;
 
	int first_line = bottom;
 

	
 
	for (ParagraphLayout::Line **iter = layout.Begin(); iter != layout.End(); iter++) {
 
		ParagraphLayout::Line *line = *iter;
 

	
 
		int line_height = line->getLeading();
 
		if (y >= top && y < bottom) {
 
			last_line = y + line_height;
 
			if (first_line > y) first_line = y;
 

	
 
			DrawLayoutLine(line, y, left, right, align, underline);
 
		}
 
		y += line_height;
 
	}
 

	
 
	return ((align & SA_VERT_MASK) == SA_BOTTOM) ? first_line : last_line;
 
}
 

	
 
/**
 
 * Draw string, possibly over multiple lines.
 
 *
 
 * @param left   The left most position to draw on.
 
 * @param right  The right most position to draw on.
 
 * @param top    The top most position to draw on.
 
 * @param bottom The bottom most position to draw on.
 
 * @param str    String to draw.
 
 * @param colour Colour used for drawing the string, see DoDrawString() for details
 
 * @param align  The horizontal and vertical alignment of the string.
 
 * @param underline Whether to underline all strings
 
 * @param fontsize The size of the initial characters.
 
 *
 
 * @return If \a align is #SA_BOTTOM, the top to where we have written, else the bottom to where we have written.
 
 */
 
int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 
	GetString(buffer, str, lastof(buffer));
 
	return DrawStringMultiLine(left, right, top, bottom, buffer, lastof(buffer), colour, align, underline, fontsize);
 
	return DrawStringMultiLine(left, right, top, bottom, buffer, colour, align, underline, fontsize);
 
}
 

	
 
/**
 
 * Return the string dimension in pixels. The height and width are returned
 
 * in a single Dimension value. TINYFONT, BIGFONT modifiers are only
 
 * supported as the first character of the string. The returned dimensions
 
 * are therefore a rough estimation correct for all the current strings
 
 * but not every possible combination
 
 * @param str string to calculate pixel-width
 
 * @param start_fontsize Fontsize to start the text with
 
 * @return string width and height in pixels
 
 */
 
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
 
{
 
	FontSize size = start_fontsize;
 
	Dimension br;
 
	uint max_width;
 
	WChar c;
 

	
 
	br.width = br.height = max_width = 0;
 
	for (;;) {
 
		c = Utf8Consume(&str);
 
		if (c == 0) break;
 
		if (IsPrintable(c) && !IsTextDirectionChar(c)) {
 
			br.width += GetCharacterWidth(size, c);
 
		} else {
 
			switch (c) {
 
				case SCC_TINYFONT: size = FS_SMALL; break;
 
				case SCC_BIGFONT:  size = FS_LARGE; break;
 
				case '\n':
 
					br.height += GetCharacterHeight(size);
 
					if (br.width > max_width) max_width = br.width;
 
					br.width = 0;
 
					break;
 
			}
 
		}
 
	}
 
	br.height += GetCharacterHeight(size);
 

	
 
	br.width  = max(br.width, max_width);
 
	return br;
 
	Layouter layout(str, INT32_MAX, TC_FROMSTRING, start_fontsize);
 
	return layout.GetBounds();
 
}
 

	
 
/**
 
 * Get bounding box of a string. Uses parameters set by #DParam if needed.
 
 * Has the same restrictions as #GetStringBoundingBox(const char *str).
 
 * @param strid String to examine.
 
 * @return Width and height of the bounding box for the string in pixels.
 
 */
 
Dimension GetStringBoundingBox(StringID strid)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 

	
0 comments (0 inline, 0 general)