From 526fb6fa21267fb3749c57ccc9f94419ddf68233 Mon Sep 17 00:00:00 2001 From: rubidium Date: Thu, 4 Jul 2013 21:16:35 +0000 Subject: [PATCH] (svn r25559) [1.3] -Backport from trunk: - Fix: Possible reading of uninitialised memory due to undefined execution order (r25551) - Fix: [Windows] Race condition between two drawing threads could crash OpenTTD [FS#5571] (r25550) - Fix: ICU returns the width of the visual run as if the trailing space was added (in case a newline was added). This caused the width to be more than the requested width, but it would still be drawn correctly [FS#5626] (r25547) - Fix: Two small memory leaks (r25546) - Fix: [GS] The checks and validations for setting the extra text in the town window became too stringent [FS#5625] (r25544) --- src/gfx.cpp | 9 +++++---- src/gfx_layout.cpp | 6 ++++-- src/script/api/script_town.cpp | 3 +-- src/script/script_scanner.cpp | 1 + src/video/win32_v.cpp | 3 +++ 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/gfx.cpp b/src/gfx.cpp index f99c21baac..c37c305adb 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -302,11 +302,12 @@ static void SetColourRemap(TextColour colour) * 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 truncation Whether to perform string truncation 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 DrawLayoutLine(ParagraphLayout::Line *line, int y, int left, int right, StringAlignment align, bool underline) +static int DrawLayoutLine(ParagraphLayout::Line *line, int y, int left, int right, StringAlignment align, bool underline, bool truncation) { if (line->countRuns() == 0) return 0; @@ -331,7 +332,7 @@ static int DrawLayoutLine(ParagraphLayout::Line *line, int y, int left, int righ int min_x = left; // The minimum x position to draw normal glyphs on. int max_x = right; // The maximum x position to draw normal glyphs on. - bool truncation = max_w < w; // Whether we need to do truncation. + truncation &= max_w < w; // Whether we need to do truncation. int dot_width = 0; // Cache for the width of the dot. const Sprite *dot_sprite = NULL; // Cache for the sprite of the dot. @@ -458,7 +459,7 @@ int DrawString(int left, int right, int top, const char *str, TextColour colour, Layouter layout(str, INT32_MAX, colour, fontsize); if (layout.Length() == 0) return 0; - return DrawLayoutLine(*layout.Begin(), top, left, right, align, underline); + return DrawLayoutLine(*layout.Begin(), top, left, right, align, underline, true); } /** @@ -600,7 +601,7 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, const char *st last_line = y + line_height; if (first_line > y) first_line = y; - DrawLayoutLine(line, y, left, right, align, underline); + DrawLayoutLine(line, y, left, right, align, underline, false); } y += line_height; } diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index 6ce6078ebe..114c5c3e65 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -319,7 +319,8 @@ ParagraphLayout::Line *ParagraphLayout::nextLine(int max_width) } if (this->buffer == next_run) { - *l->Append() = new VisualRun(iter->second, begin, this->buffer - begin, l->getWidth()); + int w = l->getWidth(); + *l->Append() = new VisualRun(iter->second, begin, this->buffer - begin, w); iter++; assert(iter != this->runs.End()); @@ -365,7 +366,8 @@ ParagraphLayout::Line *ParagraphLayout::nextLine(int max_width) } if (l->Length() == 0 || last_char - begin != 0) { - *l->Append() = new VisualRun(iter->second, begin, last_char - begin, l->getWidth()); + int w = l->getWidth(); + *l->Append() = new VisualRun(iter->second, begin, last_char - begin, w); } return l; } diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp index cb8fb62d69..fa4b9c0c77 100644 --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.cpp @@ -43,10 +43,9 @@ CCountedPtr counter(text); EnforcePrecondition(false, text != NULL); - const char *encoded_text = text->GetDecodedText(); + const char *encoded_text = text->GetEncodedText(); EnforcePreconditionEncodedText(false, encoded_text); EnforcePrecondition(false, IsValidTown(town_id)); - EnforcePreconditionCustomError(false, ::Utf8StringLength(encoded_text) < MAX_LENGTH_TOWN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, 0, CMD_TOWN_SET_TEXT, encoded_text); } diff --git a/src/script/script_scanner.cpp b/src/script/script_scanner.cpp index 248b17f9a3..2197a55058 100644 --- a/src/script/script_scanner.cpp +++ b/src/script/script_scanner.cpp @@ -76,6 +76,7 @@ ScriptScanner::~ScriptScanner() this->Reset(); free(this->main_script); + free(this->tar_file); delete this->engine; } diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index c72b87bca8..922f8ba898 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -176,6 +176,7 @@ static void ClientSizeChanged(int w, int h) { /* allocate new dib section of the new size */ if (AllocateDibSection(w, h)) { + if (_draw_mutex != NULL) _draw_mutex->BeginCritical(); /* mark all palette colours dirty */ _cur_palette.first_dirty = 0; _cur_palette.count_dirty = 256; @@ -190,6 +191,8 @@ static void ClientSizeChanged(int w, int h) _screen.dst_ptr = _wnd.buffer_bits; UpdateWindows(); } + + if (_draw_mutex != NULL) _draw_mutex->EndCritical(); } }