aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil Hodgson <nyamatongwe@gmail.com>2024-02-29 15:15:03 +1100
committerNeil Hodgson <nyamatongwe@gmail.com>2024-02-29 15:15:03 +1100
commit899913225fe6cc67b30be125ef222ce93b87eb22 (patch)
tree90d66df3e0cc1fb815aad4b799566b26d8d6bb13
parentd09724bee7cc77bb6c8b327a6f2004cebe5ec9ba (diff)
downloadscintilla-mirror-899913225fe6cc67b30be125ef222ce93b87eb22.tar.gz
Improve layout when a text run contains left-to-right and right-to-left ranges.
-rw-r--r--doc/ScintillaHistory.html6
-rwxr-xr-xgtk/PlatGTK.cxx22
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.