1
0
Fork 0

(svn r20045) -Add: Allow SA_BOTTOM alignment in DrawStringMultiLine().

release/1.1
alberth 2010-07-02 13:55:45 +00:00
parent e3bb01a7c4
commit ddb0f1a614
1 changed files with 50 additions and 15 deletions

View File

@ -827,7 +827,7 @@ Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestio
* @param align The horizontal and vertical alignment of the string. * @param align The horizontal and vertical alignment of the string.
* @param underline Whether to underline all strings * @param underline Whether to underline all strings
* *
* @return The bottom to where we have written. * @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) int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour, StringAlignment align, bool underline)
{ {
@ -847,38 +847,73 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str,
int mt = GetCharacterHeight((FontSize)GB(tmp, 16, 16)); int mt = GetCharacterHeight((FontSize)GB(tmp, 16, 16));
int total_height = num * mt; int total_height = num * mt;
int skip_lines = 0;
if (total_height > maxh) { if (total_height > maxh) {
/* Check there's room enough for at least one line. */ if (maxh < mt) return top; // Not enough room for a single line.
if (maxh < mt) return top; if ((align & SA_VERT_MASK) == SA_BOTTOM) {
skip_lines = num;
num = maxh / mt; num = maxh / mt;
skip_lines -= num;
} else {
num = maxh / mt;
}
total_height = num * mt; total_height = num * mt;
} }
int y = ((align & SA_VERT_MASK) == SA_VERT_CENTER) ? RoundDivSU(bottom + top - total_height, 2) : top; 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();
}
const char *src = buffer; const char *src = buffer;
DrawStringParams params(colour); DrawStringParams params(colour);
int written_top = bottom; // Uppermost position of rendering a line of text
for (;;) { for (;;) {
char buf2[DRAW_STRING_BUFFER]; if (skip_lines == 0) {
strecpy(buf2, src, lastof(buf2)); char buf2[DRAW_STRING_BUFFER];
DrawString(left, right, y, buf2, lastof(buf2), params, align, underline, false); strecpy(buf2, src, lastof(buf2));
DrawString(left, right, y, buf2, lastof(buf2), params, align, underline, false);
if (written_top > y) written_top = y;
y += mt;
num--;
}
for (;;) { for (;;) {
WChar c = Utf8Consume(&src); WChar c = Utf8Consume(&src);
if (c == 0) { if (c == 0) {
y += mt;
if (--num <= 0) {
return y;
}
break; break;
} else if (c == SCC_SETX) { } else if (c == SCC_SETX) {
src++; src++;
} else if (c == SCC_SETXY) { } else if (c == SCC_SETXY) {
src += 2; src += 2;
} else if (skip_lines > 0) {
/* Skipped drawing, so do additional processing to update params. */
if (c >= SCC_BLUE && c <= SCC_BLACK) {
params.SetColour((TextColour)(c - SCC_BLUE));
} else if (c == SCC_PREVIOUS_COLOUR) { // Revert to the previous colour.
params.SetPreviousColour();
} else if (c == SCC_TINYFONT) {
params.SetFontSize(FS_SMALL);
} else if (c == SCC_BIGFONT) {
params.SetFontSize(FS_LARGE);
}
} }
} }
if (skip_lines > 0) skip_lines--;
if (num == 0) return ((align & SA_VERT_MASK) == SA_BOTTOM) ? written_top : y;
} }
} }