diff options
author | Neil Hodgson <nyamatongwe@gmail.com> | 2024-02-29 15:15:03 +1100 |
---|---|---|
committer | Neil Hodgson <nyamatongwe@gmail.com> | 2024-02-29 15:15:03 +1100 |
commit | 899913225fe6cc67b30be125ef222ce93b87eb22 (patch) | |
tree | 90d66df3e0cc1fb815aad4b799566b26d8d6bb13 | |
parent | d09724bee7cc77bb6c8b327a6f2004cebe5ec9ba (diff) | |
download | scintilla-mirror-899913225fe6cc67b30be125ef222ce93b87eb22.tar.gz |
Improve layout when a text run contains left-to-right and right-to-left ranges.
-rw-r--r-- | doc/ScintillaHistory.html | 6 | ||||
-rwxr-xr-x | gtk/PlatGTK.cxx | 22 |
2 files changed, 28 insertions, 0 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 7c8e77510..ea9cb4532 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -598,6 +598,12 @@ Add APIs for saving and restoring undo history. </li> <li> + For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and + more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width + and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly + and over the suffix reasonably but not accurately. + </li> + <li> For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER. </li> diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx index 283dd7a4b..e7d6abd3d 100755 --- a/gtk/PlatGTK.cxx +++ b/gtk/PlatGTK.cxx @@ -36,6 +36,7 @@ #include "Scintilla.h" #include "ScintillaWidget.h" +#include "CharacterType.h" #include "XPM.h" #include "UniConversion.h" @@ -1085,6 +1086,27 @@ void SurfaceImpl::MeasureWidthsUTF8(const Font *font_, std::string_view text, XY } while (!iti.finished) { iti.Next(); + if (iti.curIndex < i) { + // Backwards movement indicater bidirectional. + // Divide into ASCII prefix and non-ASCII suffix as this is common case + // and produces accurate positions for the ASCII prefix. + size_t lenASCII=0; + while (lenASCII<text.length() && IsASCII(text[lenASCII])) { + lenASCII++; + } + const std::string_view asciiPrefix = text.substr(0, lenASCII); + const std::string_view bidiSuffix = text.substr(lenASCII); + // Recurse for ASCII prefix. + MeasureWidthsUTF8(font_, asciiPrefix, positions); + // Measure the whole bidiSuffix and spread its width evenly + const XYPOSITION endASCII = positions[lenASCII-1]; + const XYPOSITION widthBidi = WidthText(font_, bidiSuffix); + const XYPOSITION widthByteBidi = widthBidi / bidiSuffix.length(); + for (size_t bidiPos=0; bidiPos<bidiSuffix.length(); bidiPos++) { + positions[bidiPos+lenASCII] = endASCII + widthByteBidi * (bidiPos + 1); + } + return; + } const int places = iti.curIndex - i; while (i < iti.curIndex) { // Evenly distribute space among bytes of this cluster. |