mirror of https://github.com/OpenTTD/OpenTTD
Fix d6ccfdb: GetCharPosition failed for RTL text. (#12710)
Changes in d6ccfdb
assumed that character indexes only incremented, which is not true for RTL text.
pull/12714/head
parent
d9cadb49b0
commit
676d64037d
|
@ -11,6 +11,7 @@
|
||||||
#include "core/math_func.hpp"
|
#include "core/math_func.hpp"
|
||||||
#include "gfx_layout.h"
|
#include "gfx_layout.h"
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
|
#include "strings_func.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include "table/control_codes.h"
|
#include "table/control_codes.h"
|
||||||
|
@ -231,7 +232,7 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
|
||||||
|
|
||||||
/* Pointer to the end-of-string marker? Return total line width. */
|
/* Pointer to the end-of-string marker? Return total line width. */
|
||||||
if (ch == this->string.end()) {
|
if (ch == this->string.end()) {
|
||||||
Point p = { line->GetWidth(), 0 };
|
Point p = {_current_text_dir == TD_LTR ? line->GetWidth() : 0, 0};
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,8 +246,8 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initial position, returned if character not found. */
|
/* Initial position, returned if character not found. */
|
||||||
static const std::vector<Point> zero = { {0, 0} };
|
const Point initial_position = {_current_text_dir == TD_LTR ? 0 : line->GetWidth(), 0};
|
||||||
auto position = zero.begin();
|
const Point *position = &initial_position;
|
||||||
|
|
||||||
/* We couldn't find the code point index. */
|
/* We couldn't find the code point index. */
|
||||||
if (str != ch) return *position;
|
if (str != ch) return *position;
|
||||||
|
@ -254,24 +255,26 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
|
||||||
/* Valid character. */
|
/* Valid character. */
|
||||||
|
|
||||||
/* Scan all runs until we've found our code point index. */
|
/* Scan all runs until we've found our code point index. */
|
||||||
|
size_t best_index = SIZE_MAX;
|
||||||
for (int run_index = 0; run_index < line->CountRuns(); run_index++) {
|
for (int run_index = 0; run_index < line->CountRuns(); run_index++) {
|
||||||
const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index);
|
const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index);
|
||||||
const auto &positions = run.GetPositions();
|
const auto &positions = run.GetPositions();
|
||||||
const auto &charmap = run.GetGlyphToCharMap();
|
const auto &charmap = run.GetGlyphToCharMap();
|
||||||
|
|
||||||
/* Run starts after our character, use the last found position. */
|
auto itp = positions.begin();
|
||||||
if (static_cast<size_t>(charmap.front()) > index) return *position;
|
for (auto it = charmap.begin(); it != charmap.end(); ++it, ++itp) {
|
||||||
|
const size_t cur_index = static_cast<size_t>(*it);
|
||||||
|
/* Found exact character match? */
|
||||||
|
if (cur_index == index) return *itp;
|
||||||
|
|
||||||
position = positions.begin();
|
/* If the character we are looking for has been combined with other characters to form a ligature then
|
||||||
for (auto it = charmap.begin(); it != charmap.end(); /* nothing */) {
|
* we may not be able to find an exact match. We don't actually know if our character is part of a
|
||||||
/* Plain honest-to-$deity match. */
|
* ligature. In this case we will aim to select the first character of the ligature instead, so the best
|
||||||
if (static_cast<size_t>(*it) == index) return *position;
|
* index is the index nearest to but lower than the desired index. */
|
||||||
++it;
|
if (cur_index < index && (best_index < cur_index || best_index == SIZE_MAX)) {
|
||||||
if (it == charmap.end()) break;
|
best_index = cur_index;
|
||||||
|
position = &*itp;
|
||||||
/* We just passed our character, it's probably a ligature, use the last found position. */
|
}
|
||||||
if (static_cast<size_t>(*it) > index) return *position;
|
|
||||||
++position;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue