Skip to content

Commit

Permalink
Fix: Layouter not taking stripped formatting codes into account when …
Browse files Browse the repository at this point in the history
…mapping visual coordinates to/from original string
  • Loading branch information
nielsmh committed Jun 22, 2023
1 parent 22233ed commit b4c4c37
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions src/gfx_layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,20 @@ Dimension Layouter::GetBounds()
return d;
}

/**
* 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;
if (!IsPrintable(ch)) return false;
// Minor risk: Not testing IsTextDirectionChar(ch) because it's not known whether the layouter supported RTL
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.
Expand All @@ -228,7 +242,7 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
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. */
Expand Down Expand Up @@ -282,7 +296,7 @@ ptrdiff_t Layouter::GetCharAtPosition(int x) const
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);
}
}
}
Expand Down

0 comments on commit b4c4c37

Please sign in to comment.