diff options
Diffstat (limited to 'src/gfx_layout.cpp')
-rw-r--r-- | src/gfx_layout.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index 165edee3b..4d1d382d6 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -566,6 +566,50 @@ Point Layouter::GetCharPosition(const char *ch) const } /** + * Get the character that is at a position. + * @param x Position in the string. + * @return Pointer to the character at the position or NULL if no character is at the position. + */ +const char *Layouter::GetCharAtPosition(int x) const +{ + const ParagraphLayout::Line *line = *this->Begin();; + + for (int run_index = 0; run_index < line->countRuns(); run_index++) { + const ParagraphLayout::VisualRun *run = line->getVisualRun(run_index); + + for (int i = 0; i < run->getGlyphCount(); i++) { + /* Not a valid glyph (empty). */ + if (run->getGlyphs()[i] == 0xFFFF) continue; + + int begin_x = run->getPositions()[i * 2]; + int end_x = run->getPositions()[i * 2 + 2]; + + if (IsInsideMM(x, begin_x, end_x)) { + /* Found our glyph, now convert to UTF-8 string index. */ + size_t index = run->getGlyphToCharMap()[i]; + + size_t cur_idx = 0; + for (const char *str = this->string; *str != '\0'; ) { + if (cur_idx == index) return str; + + WChar c; + size_t len = Utf8Decode(&c, str); +#ifdef WITH_ICU + /* ICU uses UTF-16 internally which means we need to account for surrogate pairs. */ + cur_idx += len < 4 ? 1 : 2; +#else + cur_idx++; +#endif + str += len; + } + } + } + } + + return NULL; +} + +/** * Get a static font instance. */ Font *Layouter::GetFont(FontSize size, TextColour colour) |