summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2013-06-25 20:44:54 +0000
committerrubidium <rubidium@openttd.org>2013-06-25 20:44:54 +0000
commitf980d1a43c0b7f079acbab3057bb686b6ec9b86b (patch)
treea9e4062f39578fc2595224a742e9dc5efd009e45
parent8bbbb1b37ad620e99bca8af43d8c7144187f574b (diff)
downloadopenttd-f980d1a43c0b7f079acbab3057bb686b6ec9b86b.tar.xz
(svn r25472) -Cleanup: remove the old methods for drawing text
-rw-r--r--src/gfx.cpp537
1 files changed, 0 insertions, 537 deletions
diff --git a/src/gfx.cpp b/src/gfx.cpp
index a7406b9b5..9b65e7670 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -363,128 +363,6 @@ static void SetColourRemap(TextColour colour)
_colour_remap_ptr = _string_colourremap;
}
-#if !defined(WITH_ICU)
-static WChar *HandleBiDiAndArabicShapes(WChar *text) { return text; }
-#else
-#include <unicode/ubidi.h>
-#include <unicode/ushape.h>
-#include <unicode/ustring.h>
-
-/**
- * Function to be able to handle right-to-left text and Arabic chars properly.
- *
- * First: right-to-left (RTL) is stored 'logically' in almost all applications
- * and so do we. This means that their text is stored from right to the
- * left in memory and any non-RTL text (like numbers or English) are
- * then stored from left-to-right. When we want to actually draw the
- * text we need to reverse the RTL text in memory, which is what
- * happens in ubidi_writeReordered.
- * Second: Arabic characters "differ" based on their context. To draw the
- * correct variant we pass it through u_shapeArabic. This function can
- * add or remove some characters. This is the reason for the lastof
- * so we know till where we can fill the output.
- *
- * Sadly enough these functions work with a custom character format, UChar,
- * which isn't the same size as WChar. Because of that we need to transform
- * our text first to UChars and then back to something we can use.
- *
- * To be able to truncate strings properly you must truncate before passing to
- * this function. This way the logical begin of the string remains and the end
- * gets chopped of instead of the other way around.
- *
- * The reshaping of Arabic characters might increase or decrease the width of
- * the characters/string. So it might still overflow after truncation, though
- * the chance is fairly slim as most characters get shorter instead of longer.
- * @param buffer the buffer to read from/to
- * @param lastof the end of the buffer
- * @return the buffer to draw from
- */
-static WChar *HandleBiDiAndArabicShapes(WChar *buffer)
-{
- UChar input[DRAW_STRING_BUFFER];
- UChar intermediate[DRAW_STRING_BUFFER];
- static WChar output[DRAW_STRING_BUFFER];
-
- /* Transform from UTF-32 to internal ICU format of UTF-16. */
- UErrorCode err = U_ZERO_ERROR;
- int32_t length = 0;
- u_strFromUTF32(input, lengthof(input), &length, (UChar32 *)buffer, -1, &err);
- if (U_FAILURE(err)) return buffer;
-
- UBiDi *para = ubidi_openSized(length, 0, &err);
- if (para == NULL) return buffer;
-
- ubidi_setPara(para, input, length, _current_text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, NULL, &err);
- length = ubidi_writeReordered(para, intermediate, lengthof(intermediate), UBIDI_REMOVE_BIDI_CONTROLS, &err);
- length = u_shapeArabic(intermediate, length, input, lengthof(input), U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_LETTERS_SHAPE, &err);
- ubidi_close(para);
- if (U_FAILURE(err)) return buffer;
-
- /* Transform back to UTF-32. */
- u_strToUTF32((UChar32 *)output, lengthof(output), NULL, input, length, &err);
- if (U_FAILURE(err)) return buffer;
-
- /* u_strToUTF32 doesn't add a NUL charcter if the buffer is too small, be safe. */
- output[lengthof(output) - 1] = '\0';
- return output;
-}
-#endif /* WITH_ICU */
-
-
-/**
- * Truncate a given string to a maximum width if necessary.
- * If the string is truncated, add three dots ('...') to show this.
- * @param *str string that is checked and possibly truncated
- * @param maxw maximum width in pixels of the string
- * @param start_fontsize Fontsize to start the text with
- * @return new width of (truncated) string
- */
-static int TruncateString(char *str, int maxw, FontSize start_fontsize)
-{
- int w = 0;
- FontSize size = start_fontsize;
- int ddd, ddd_w;
-
- WChar c;
- char *ddd_pos;
-
- ddd_w = ddd = GetCharacterWidth(size, '.') * 3;
-
- for (ddd_pos = str; (c = Utf8Consume(const_cast<const char **>(&str))) != '\0'; ) {
- if (IsPrintable(c) && !IsTextDirectionChar(c)) {
- w += GetCharacterWidth(size, c);
-
- if (w > maxw) {
- /* string got too big... insert dotdotdot, but make sure we do not
- * print anything beyond the string termination character. */
- for (int i = 0; *ddd_pos != '\0' && i < 3; i++, ddd_pos++) *ddd_pos = '.';
- *ddd_pos = '\0';
- return ddd_w;
- }
- } else {
- if (c == SCC_TINYFONT) {
- size = FS_SMALL;
- ddd = GetCharacterWidth(size, '.') * 3;
- } else if (c == SCC_BIGFONT) {
- size = FS_LARGE;
- ddd = GetCharacterWidth(size, '.') * 3;
- } else if (c == '\n') {
- DEBUG(misc, 0, "Drawing string using newlines with DrawString instead of DrawStringMultiLine. Please notify the developers of this: [%s]", str);
- }
- }
-
- /* Remember the last position where three dots fit. */
- if (w + ddd < maxw) {
- ddd_w = w + ddd;
- ddd_pos = str;
- }
- }
-
- return w;
-}
-
-static int ReallyDoDrawString(const WChar *string, int x, int y, DrawStringParams &params, bool parse_string_also_when_clipped = false);
-
/**
* Drawing routine for drawing a laid out line of text.
* @param line String to draw.
@@ -633,109 +511,6 @@ static int DrawLayoutLine(ParagraphLayout::Line *line, int y, int left, int righ
}
/**
- * Get the real width of the string.
- * @param str the string to draw
- * @param start_fontsize Fontsize to start the text with
- * @return the width.
- */
-static int GetStringWidth(const WChar *str, FontSize start_fontsize)
-{
- FontSize size = start_fontsize;
- int max_width;
- int width;
- WChar c;
-
- width = max_width = 0;
- for (;;) {
- c = *str++;
- if (c == 0) break;
- if (IsPrintable(c) && !IsTextDirectionChar(c)) {
- width += GetCharacterWidth(size, c);
- } else {
- switch (c) {
- case SCC_TINYFONT: size = FS_SMALL; break;
- case SCC_BIGFONT: size = FS_LARGE; break;
- case '\n':
- max_width = max(max_width, width);
- break;
- }
- }
- }
-
- return max(max_width, width);
-}
-
-/**
- * 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 last The end of the string buffer to draw.
- * @param params Text drawing parameters.
- * @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 truncate Whether to truncate the string or not.
- *
- * @return In case of left or center alignment the right most pixel we have drawn to.
- * In case of right alignment the left most pixel we have drawn to.
- */
-static int DrawString(int left, int right, int top, char *str, const char *last, DrawStringParams &params, StringAlignment align, bool underline = false, bool truncate = true)
-{
- if (truncate) TruncateString(str, right - left + 1, params.fontsize);
-
- WChar draw_buffer[DRAW_STRING_BUFFER];
- WChar *p = draw_buffer;
-
- const char *text = str;
- for (WChar c = Utf8Consume(&text); c != '\0'; c = Utf8Consume(&text)) {
- *p++ = c;
- }
- *p++ = '\0';
-
- /* In case we have a RTL language we swap the alignment. */
- if (!(align & SA_FORCE) && _current_text_dir == TD_RTL && (align & SA_HOR_MASK) != SA_HOR_CENTER) align ^= SA_RIGHT;
-
- WChar *to_draw = HandleBiDiAndArabicShapes(draw_buffer);
- int w = GetStringWidth(to_draw, params.fontsize);
-
- /* right is the right most position to draw on. In this case we want to do
- * calculations with the width of the string. In comparison right can be
- * seen as lastof(todraw) and width as lengthof(todraw). They differ by 1.
- * So most +1/-1 additions are to move from lengthof to 'indices'.
- */
- switch (align & SA_HOR_MASK) {
- case SA_LEFT:
- /* right + 1 = left + w */
- right = left + w - 1;
- break;
-
- case SA_HOR_CENTER:
- left = RoundDivSU(right + 1 + left - w, 2);
- /* right + 1 = left + w */
- right = left + w - 1;
- break;
-
- case SA_RIGHT:
- left = right + 1 - w;
- break;
-
- default:
- NOT_REACHED();
- }
-
- ReallyDoDrawString(to_draw, left, top, params, !truncate);
- if (underline) {
- GfxFillRect(left, top + FONT_HEIGHT_NORMAL, right, top + FONT_HEIGHT_NORMAL, _string_colourremap[1]);
- }
-
- return (align & SA_HOR_MASK) == SA_RIGHT ? left : right;
-}
-
-/**
* Draw string, possibly truncated to make it fit in its allocated space
*
* @param left The left most position to draw on.
@@ -779,141 +554,6 @@ int DrawString(int left, int right, int top, StringID str, TextColour colour, St
}
/**
- * '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',
- * starting with index 0 is the real string end.
- *
- * @param str string to check and correct for length restrictions
- * @param last the last valid location (for '\0') in the buffer of str
- * @param maxw the maximum width the string can have on one line
- * @param size Fontsize to start the text with
- * @return return a 32bit wide number consisting of 2 packed values:
- * 0 - 15 the number of lines ADDED to the string
- * 16 - 31 the fontsize in which the length calculation was done at
- */
-static uint32 FormatStringLinebreaks(char *str, const char *last, int maxw, FontSize size = FS_NORMAL)
-{
- int num = 0;
-
- assert(maxw > 0);
-
- for (;;) {
- /* The character *after* the last space. */
- char *last_space = NULL;
- int w = 0;
-
- for (;;) {
- WChar c = Utf8Consume(const_cast<const char **>(&str));
- /* whitespace is where we will insert the line-break */
- if (IsWhitespace(c)) last_space = str;
-
- if (IsPrintable(c) && !IsTextDirectionChar(c)) {
- int char_w = GetCharacterWidth(size, c);
- w += char_w;
- if (w > maxw) {
- /* The string is longer than maximum width so we need to decide
- * what to do with it. */
- if (w == char_w) {
- /* The character is wider than allowed width; don't know
- * what to do with this case... bail out! */
- return num + (size << 16);
- }
- if (last_space == NULL) {
- /* No space has been found. Just terminate at our current
- * location. This usually happens for languages that do not
- * require spaces in strings, like Chinese, Japanese and
- * Korean. For other languages terminating mid-word might
- * not be the best, but terminating the whole string instead
- * of continuing the word at the next line is worse. */
- str = Utf8PrevChar(str);
- size_t len = strlen(str);
- char *terminator = str + len;
-
- /* The string location + length of the string + 1 for '\0'
- * always fits; otherwise there's no trailing '\0' and it
- * it not a valid string. */
- assert(terminator <= last);
- assert(*terminator == '\0');
-
- /* If the string is too long we have to terminate it earlier. */
- if (terminator == last) {
- /* Get the 'begin' of the previous character and make that
- * the terminator of the string; we truncate it 'early'. */
- *Utf8PrevChar(terminator) = '\0';
- len = strlen(str);
- }
- /* Also move the terminator! */
- memmove(str + 1, str, len + 1);
- *str = '\0';
- /* str needs to point to the character *after* the last space */
- str++;
- } else {
- /* A space is found; perfect place to terminate */
- str = last_space;
- }
- break;
- }
- } else {
- switch (c) {
- case '\0': return num + (size << 16);
- case SCC_TINYFONT: size = FS_SMALL; break;
- case SCC_BIGFONT: size = FS_LARGE; break;
- case '\n': goto end_of_inner_loop;
- }
- }
- }
-end_of_inner_loop:
- /* String didn't fit on line (or a '\n' was encountered), so 'dummy' terminate
- * and increase linecount. We use Utf8PrevChar() as also non 1 char long
- * whitespace separators are supported */
- num++;
- char *s = Utf8PrevChar(str);
- *s++ = '\0';
-
- /* In which case (see above) we will shift remainder to left and close the gap */
- if (str - s >= 1) {
- for (; str[-1] != '\0';) *s++ = *str++;
- }
- }
-}
-
-
-/**
- * Calculates height of string (in pixels). Accepts multiline string with '\0' as separators.
- * @param src string to check
- * @param num number of extra lines (output of FormatStringLinebreaks())
- * @param start_fontsize Fontsize to start the text with
- * @note assumes text won't be truncated. FormatStringLinebreaks() is a good way to ensure that.
- * @return height of pixels of string when it is drawn
- */
-static int GetMultilineStringHeight(const char *src, int num, FontSize start_fontsize)
-{
- int maxy = 0;
- int y = 0;
- int fh = GetCharacterHeight(start_fontsize);
-
- for (;;) {
- WChar c = Utf8Consume(&src);
-
- switch (c) {
- case 0: y += fh; if (--num < 0) return maxy; break;
- case '\n': y += fh; break;
- case SCC_TINYFONT: fh = GetCharacterHeight(FS_SMALL); break;
- case SCC_BIGFONT: fh = GetCharacterHeight(FS_LARGE); break;
- 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
@@ -985,103 +625,6 @@ Dimension GetStringMultiLineBoundingBox(const char *str, const Dimension &sugges
* @param top The top most position to draw on.
* @param bottom The bottom most position to draw on.
* @param str String to draw.
- * @param last The end of the string buffer 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.
- */
-static int DrawStringMultiLine(int left, int right, int top, int bottom, char *str, const char *last, TextColour colour, StringAlignment align, bool underline, FontSize 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;
-
- uint32 tmp = FormatStringLinebreaks(str, last, maxw);
- int num = GB(tmp, 0, 16) + 1;
-
- int mt = GetCharacterHeight((FontSize)GB(tmp, 16, 16));
- int total_height = num * mt;
-
- int skip_lines = 0;
- if (total_height > maxh) {
- if (maxh < mt) return top; // Not enough room for a single line.
- if ((align & SA_VERT_MASK) == SA_BOTTOM) {
- skip_lines = num;
- num = maxh / mt;
- skip_lines -= num;
- } else {
- num = maxh / mt;
- }
- total_height = num * mt;
- }
-
- 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 = str;
- DrawStringParams params(colour, fontsize);
- int written_top = bottom; // Uppermost position of rendering a line of text
- for (;;) {
- if (skip_lines == 0) {
- char buf2[DRAW_STRING_BUFFER];
- 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 (;;) {
- WChar c = Utf8Consume(&src);
- if (c == 0) {
- break;
- } 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;
- }
-}
-
-/**
- * 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
@@ -1202,86 +745,6 @@ void DrawCharCentered(WChar c, int x, int y, TextColour colour)
}
/**
- * Draw a string at the given coordinates with the given colour.
- * While drawing the string, parse it in case some formatting is specified,
- * like new colour, new size or even positioning.
- * @param string The string to draw. This is already bidi reordered.
- * @param x Offset from left side of the screen
- * @param y Offset from top side of the screen
- * @param params Text drawing parameters
- * @param parse_string_also_when_clipped
- * By default, always test the available space where to draw the string.
- * When in multiline drawing, it would already be done,
- * so no need to re-perform the same kind (more or less) of verifications.
- * It's not only an optimisation, it's also a way to ensures the string will be parsed
- * (as there are certain side effects on global variables, which are important for the next line)
- * @return the x-coordinates where the drawing has finished.
- * If nothing is drawn, the originally passed x-coordinate is returned
- */
-static int ReallyDoDrawString(const WChar *string, int x, int y, DrawStringParams &params, bool parse_string_also_when_clipped)
-{
- DrawPixelInfo *dpi = _cur_dpi;
- bool draw_shadow = GetDrawGlyphShadow(FS_NORMAL);
- WChar c;
- int xo = x;
-
- if (!parse_string_also_when_clipped) {
- /* in "mode multiline", the available space have been verified. Not in regular one.
- * So if the string cannot be drawn, return the original start to say so.*/
- if (x >= dpi->left + dpi->width || y >= dpi->top + dpi->height) return x;
- }
-
-switch_colour:;
- SetColourRemap(params.cur_colour);
-
-check_bounds:
- if (y + _max_char_height <= dpi->top || dpi->top + dpi->height <= y) {
-skip_char:;
- for (;;) {
- c = *string++;
- if (!IsPrintable(c)) goto skip_cont;
- }
- }
-
- for (;;) {
- c = *string++;
-skip_cont:;
- if (c == 0) {
- return x; // Nothing more to draw, get out. And here is the new x position
- }
- if (IsPrintable(c) && !IsTextDirectionChar(c)) {
- if (x >= dpi->left + dpi->width) goto skip_char;
- if (x + _max_char_width >= dpi->left) {
- const Sprite *glyph = GetGlyph(params.fontsize, c);
- if (draw_shadow && params.fontsize == FS_NORMAL && params.cur_colour != TC_BLACK && !(c >= SCC_SPRITE_START && c <= SCC_SPRITE_END)) {
- SetColourRemap(TC_BLACK);
- GfxMainBlitter(glyph, x + 1, y + 1, BM_COLOUR_REMAP);
- SetColourRemap(params.cur_colour);
- }
- GfxMainBlitter(glyph, x, y, BM_COLOUR_REMAP);
- }
- x += GetCharacterWidth(params.fontsize, c);
- } else if (c == '\n') { // newline = {}
- x = xo; // We require a new line, so the x coordinate is reset
- y += GetCharacterHeight(params.fontsize);
- goto check_bounds;
- } else if (c >= SCC_BLUE && c <= SCC_BLACK) { // change colour?
- params.SetColour((TextColour)(c - SCC_BLUE));
- goto switch_colour;
- } else if (c == SCC_PREVIOUS_COLOUR) { // revert to the previous colour
- params.SetPreviousColour();
- goto switch_colour;
- } else if (c == SCC_TINYFONT) { // {TINYFONT}
- params.SetFontSize(FS_SMALL);
- } else if (c == SCC_BIGFONT) { // {BIGFONT}
- params.SetFontSize(FS_LARGE);
- } else if (!IsTextDirectionChar(c)) {
- DEBUG(misc, 0, "[utf8] unknown string command character %d", c);
- }
- }
-}
-
-/**
* Get the size of a sprite.
* @param sprid Sprite to examine.
* @param [out] offset Optionally returns the sprite position offset.