|
|
@@ -1056,12 +1056,26 @@ Vector2f WidgetTextInput::FormatText()
|
|
|
line_position.x += ElementUtilities::GetStringWidth(text_element, pre_selection);
|
|
|
}
|
|
|
|
|
|
+ // Return the extra kerning that would result in joining two strings.
|
|
|
+ auto GetKerningBetween = [this](const String& left, const String& right) -> float {
|
|
|
+ if (left.empty() || right.empty())
|
|
|
+ return 0.0f;
|
|
|
+ // We could join the whole string, and compare the result of the joined width to the individual widths of each string. Instead, we just take the
|
|
|
+ // two neighboring characters from each string and compare the string width with and without kerning, which should be much faster.
|
|
|
+ const Character left_back = StringUtilities::ToCharacter(StringUtilities::SeekBackwardUTF8(&left.back(), &left.front()));
|
|
|
+ const String right_front_u8 = right.substr(0, size_t(StringUtilities::SeekForwardUTF8(right.c_str() + 1, right.c_str() + right.size()) - right.c_str()));
|
|
|
+ const int width_kerning = ElementUtilities::GetStringWidth(text_element, right_front_u8, left_back);
|
|
|
+ const int width_no_kerning = ElementUtilities::GetStringWidth(text_element, right_front_u8, Character::Null);
|
|
|
+ return float(width_kerning - width_no_kerning);
|
|
|
+ };
|
|
|
+
|
|
|
// If there is any selected text on this line, place it in the selected text element and
|
|
|
// generate the geometry for its background.
|
|
|
if (!selection.empty())
|
|
|
{
|
|
|
+ line_position.x += GetKerningBetween(pre_selection, selection);
|
|
|
selected_text_element->AddLine(line_position, selection);
|
|
|
- int selection_width = ElementUtilities::GetStringWidth(selected_text_element, selection);
|
|
|
+ const int selection_width = ElementUtilities::GetStringWidth(selected_text_element, selection);
|
|
|
|
|
|
selection_vertices.resize(selection_vertices.size() + 4);
|
|
|
selection_indices.resize(selection_indices.size() + 6);
|
|
|
@@ -1073,7 +1087,10 @@ Vector2f WidgetTextInput::FormatText()
|
|
|
// If there is any unselected text after the selection on this line, place it in the
|
|
|
// standard text element after the selected text.
|
|
|
if (!post_selection.empty())
|
|
|
+ {
|
|
|
+ line_position.x += GetKerningBetween(selection, post_selection);
|
|
|
text_element->AddLine(line_position, post_selection);
|
|
|
+ }
|
|
|
|
|
|
|
|
|
// Update variables for the next line.
|