# HG changeset patch # User Niels Martin Hansen # Date 2021-04-03 17:48:34 # Node ID 0cae268be5b008f0ac3b226a60fa654323766216 # Parent e937361fa514264a97b2a7721e6dfbe39ec08d00 Fix: Layouter not taking stripped formatting codes into account when mapping visual coordinates to/from original string diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -207,6 +207,19 @@ Dimension Layouter::GetBounds() } /** + * Test whether a character is a non-printable formatting code + */ +static bool IsConsumedFormattingCode(WChar ch) +{ + if (ch >= SCC_BLUE && ch <= SCC_BLACK) return true; + if (ch == SCC_PUSH_COLOUR) return true; + if (ch == SCC_POP_COLOUR) return true; + if (ch >= SCC_FIRST_FONT && ch <= SCC_LAST_FONT) return true; + // All other characters defined in Unicode standard are assumed to be non-consumed. + return false; +} + +/** * Get the position of a character in the layout. * @param ch Character to get the position of. Must be an iterator of the string passed to the constructor. * @return Upper left corner of the character relative to the start of the string. @@ -228,7 +241,7 @@ Point Layouter::GetCharPosition(std::str auto str = this->string.begin(); while (str < ch) { WChar c = Utf8Consume(str); - index += line->GetInternalCharLength(c); + if (!IsConsumedFormattingCode(c)) index += line->GetInternalCharLength(c); } /* We couldn't find the code point index. */ @@ -282,7 +295,7 @@ ptrdiff_t Layouter::GetCharAtPosition(in if (cur_idx == index) return str - this->string.begin(); WChar c = Utf8Consume(str); - cur_idx += line->GetInternalCharLength(c); + if (!IsConsumedFormattingCode(c)) cur_idx += line->GetInternalCharLength(c); } } }