summaryrefslogtreecommitdiff
path: root/src/gfx_layout.cpp
diff options
context:
space:
mode:
authormichi_cc <michi_cc@openttd.org>2013-08-05 20:35:23 +0000
committermichi_cc <michi_cc@openttd.org>2013-08-05 20:35:23 +0000
commit33f3cf3a5daeaf9e6e5b5414696f93676249bc41 (patch)
tree9de7c6fec9a311f66a3e598cdb3286cfdd1cadff /src/gfx_layout.cpp
parent9d7ec75fc0a396b47f91a5f7ec4bea59024fea5f (diff)
downloadopenttd-33f3cf3a5daeaf9e6e5b5414696f93676249bc41.tar.xz
(svn r25651) -Fix: Textbuf caret rendering for complex scripts (e.g. Tamil).
Diffstat (limited to 'src/gfx_layout.cpp')
-rw-r--r--src/gfx_layout.cpp55
1 files changed, 54 insertions, 1 deletions
diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp
index b47709374..165edee3b 100644
--- a/src/gfx_layout.cpp
+++ b/src/gfx_layout.cpp
@@ -423,7 +423,7 @@ ParagraphLayout *Layouter::GetParagraphLayout(WChar *buff, WChar *buff_end, Font
* @param colour The colour of the font.
* @param fontsize The size of font to use.
*/
-Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsize)
+Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsize) : string(str)
{
FontState state(colour, fontsize);
WChar c = 0;
@@ -513,6 +513,59 @@ Dimension Layouter::GetBounds()
}
/**
+ * Get the position of a character in the layout.
+ * @param ch Character to get the position of.
+ * @return Upper left corner of the character relative to the start of the string.
+ * @note Will only work right for single-line strings.
+ */
+Point Layouter::GetCharPosition(const char *ch) const
+{
+ /* Find the code point index which corresponds to the char
+ * pointer into our UTF-8 source string. */
+ size_t index = 0;
+ const char *str = this->string;
+ while (str < ch) {
+ WChar c;
+ size_t len = Utf8Decode(&c, str);
+ if (c == '\0' || c == '\n') break;
+ str += len;
+#ifdef WITH_ICU
+ /* ICU uses UTF-16 internally which means we need to account for surrogate pairs. */
+ index += len < 4 ? 1 : 2;
+#else
+ index++;
+#endif
+ }
+
+ if (str == ch) {
+ /* Valid character. */
+ const ParagraphLayout::Line *line = *this->Begin();
+
+ /* Pointer to the end-of-string/line marker? Return total line width. */
+ if (*ch == '\0' || *ch == '\n') {
+ Point p = { line->getWidth(), 0 };
+ return p;
+ }
+
+ /* Scan all runs until we've found our code point index. */
+ 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++) {
+ /* Matching glyph? Return position. */
+ if ((size_t)run->getGlyphToCharMap()[i] == index) {
+ Point p = { run->getPositions()[i * 2], run->getPositions()[i * 2 + 1] };
+ return p;
+ }
+ }
+ }
+ }
+
+ Point p = { 0, 0 };
+ return p;
+}
+
+/**
* Get a static font instance.
*/
Font *Layouter::GetFont(FontSize size, TextColour colour)