Support for right-to-left languages

Caleb Rouleau crouleau at salesforce.com
Fri Jun 23 00:51:00 BST 2023


Thank you Phil for your response and consideration!

In case anyone else is running into this same issue, I will share
some results from my investigation into the issue I shared. I was able to
do some hacking in the Scintilla source code to fix it. It seems like
Scintilla is getting its positions array from QScintilla and that array
isn't in the correct order in some cases where right-to-left text is
involved. The hack below solved the issue for my product (and it works for
the example application as well). I'm still seeing other right to left text
weirdness though so more work is required to get things fully working.

Of course without full support for right-to-left text, all I can do is
write hacks like these to make my users a bit happier. It's unlikely that I
will be able to fix everything. And I will need to re-apply each hack every
time I upgrade my QScintilla version.

Thanks!
Caleb

diff --git a/scintilla/src/EditView.cpp b/scintilla/src/EditView.cpp
index 4a9dc1f..0b20028 100644
--- a/scintilla/src/EditView.cpp
+++ b/scintilla/src/EditView.cpp
@@ -1661,11 +1661,43 @@ void EditView::DrawForeground(Surface *surface,
const EditModel &model, const Vi
         const Sci::Position iDoc = i + posLineStart;

         PRectangle rcSegment = rcLine;
-        rcSegment.left = ll->positions[ts.start] + xStart -
static_cast<XYPOSITION>(subLineStart);
-        rcSegment.right = ll->positions[ts.end()] + xStart -
static_cast<XYPOSITION>(subLineStart);
-        // Only try to draw if really visible - enhances performance by
not calling environment to
+
+        // This patch prevents a bug where
+        // lines containing only right-to-left text would not be drawn
+        // so user would see a blank line for them.
+
+        // For right-to-left text, I've seen ll->positions be out-of-order,
+        // inside the SurfaceImpl::MeasureWidth function
+        // so in order to get left and right correct, we must loop through
+        // the whole array.
+        int start = ts.start;
+        int end = ts.end();
+        XYPOSITION minimum = ll->positions[start];
+        XYPOSITION maximum = ll->positions[start];
+        for (int i = start; i <= end; i++) {
+            XYPOSITION current = ll->positions[i];
+            if (current > maximum) {
+                maximum = current;
+            }
+            if (current < minimum) {
+                minimum = current;
+            }
+        }
+        rcSegment.left = minimum + xStart -
static_cast<XYPOSITION>(subLineStart);
+        rcSegment.right = maximum + xStart -
static_cast<XYPOSITION>(subLineStart);
+        // Only try to draw if visible - enhances performance by not
calling environment to
         // draw strings that are completely past the right side of the
window.
-        if (rcSegment.Intersects(rcLine)) {
+        // Also draw if left == right because this could mean that there
is nothing to draw
+        // so it shouldn't impact performance much or it could mean that
we are hitting an
+        // issue where
+        // text_line.cursorToX(i_char + code_units) in
SurfaceImpl::MeasureWidth in PlatQt.cpp
+        // is returning 0.0 for a line containing a single hebrew or other
right-to-left
+        // character instead of a positive
+        // number like it does for a single english character.
+        bool emptyOrRightToLeftText = rcSegment.right == rcSegment.left;
+        if (rcSegment.Intersects(rcLine) || emptyOrRightToLeftText) {
+
             const int styleMain = ll->styles[i];
             ColourDesired textFore = vsDraw.styles[styleMain].fore;
             FontAlias textFont = vsDraw.styles[styleMain].font;
-- 

On Wed, Jun 14, 2023 at 2:37 AM Phil Thompson <phil at riverbankcomputing.com>
wrote:

> On 14/06/2023 05:45, Caleb Rouleau wrote:
> > Hi,
> >
> > I really appreciate QScintilla. Thanks for writing it and maintaining
> > it!
> >
> > I was wondering what the state of support for right-to-left languages
> > like
> > Arabic and Hebrew should be in QScintilla. (I don't see any mention of
> > support in the documentation but I may be missing it!) I'm also
> > wondering
> > whether you plan to work to improve this support in the future. I see
> > on
> > the Scintilla website (1) that Scintilla has "limited experimental"
> > support
> > for these languages on Windows. I read this thread on GitHub (2) that
> > shows
> > that this support might be desirable for other projects than just mine.
> >
> > Here's an issue that I'm having with right-to-left languages:
> > 1. On a Windows 10 machine, install Hebrew or Arabic language support.
> > 2. Build the example application that comes with QScintilla against Qt
> > 5.15
> > and QScintilla 2.14.0 and run it.
> > 3. Use Windows UI to switch your keyboard to Hebrew or Arabic.
> > 4. Type "asdf" on your keyboard into the example application. Since
> > your
> > keyboard is in Arabic or Hebrew mode, this should type "شسيب" or
> > "שדגכ".
> > However, no text is visible.
> > 5. Switch your keyboard back to English.
> > 6. Type "asdf". Suddenly the Arabic or Hebrew text appears and you
> > should
> > see something like "שדגכasdf"
> >
> > Is there something that I can do differently to make the right-to-left
> > text
> > appear immediately instead of only showing when there is also
> > left-to-right
> > text in the same box?
> >
> > It seems likely that this issue happens on other versions of Qt and
> > versions of Windows as well, but I haven't tested it yet.
>
> At the moment this just isn't supported.  It has to be fully supported
> in the underlying Scintilla code.
>
> QScintilla is based on a relatively old version of Scintilla - I haven't
> kept up to date because, IMHO, newer versions haven't added much that is
> generally useful. If the support was added to Scintilla then I'd
> consider updating to it.
>
> Phil
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/qscintilla/attachments/20230622/3854b60f/attachment.htm>


More information about the QScintilla mailing list