diff --git a/thirdparty/scintilla/qt/ScintillaEditBase/PlatQt.cpp b/thirdparty/scintilla/qt/ScintillaEditBase/PlatQt.cpp index 08948138a..7c394292b 100644 --- a/thirdparty/scintilla/qt/ScintillaEditBase/PlatQt.cpp +++ b/thirdparty/scintilla/qt/ScintillaEditBase/PlatQt.cpp @@ -667,16 +667,29 @@ void SurfaceImpl::MeasureWidths(const Font *font, QTextLine tl = tlay.createLine(); tlay.endLayout(); if (mode.codePage == SC_CP_UTF8) { + // Measure each character's advance width independently and accumulate in + // logical (document) order, rather than using QTextLine::cursorToX(), which + // returns *visual* bidi-reordered positions. Scintilla's EditView code relies + // on positions[] being monotonically non-decreasing in logical order to place + // styled runs, the caret, and selection highlights; for RTL text (e.g. Hebrew), + // cursorToX() violates that invariant and pushes glyphs outside the visible + // clip rectangle, making them appear invisible. + QFontMetricsF metrics(*FontPointer(font), GetPaintDevice()); int fit = su.size(); int ui=0; size_t i=0; + XYPOSITION cumulativeWidth = 0; while (ui= QT_VERSION_CHECK(6, 0, 0) + cumulativeWidth += metrics.horizontalAdvance(su.mid(ui, codeUnits)); +#else + cumulativeWidth += metrics.width(su.mid(ui, codeUnits)); +#endif for (size_t bytePos=0; (bytePos(text.length())); - QTextLayout tlay(su, *FontPointer(font), GetPaintDevice()); - tlay.beginLayout(); - QTextLine tl = tlay.createLine(); - tlay.endLayout(); + QFontMetricsF metrics(*FontPointer(font), GetPaintDevice()); int fit = su.size(); int ui=0; size_t i=0; + XYPOSITION cumulativeWidth = 0; while (ui= QT_VERSION_CHECK(6, 0, 0) + cumulativeWidth += metrics.horizontalAdvance(su.mid(ui, codeUnits)); +#else + cumulativeWidth += metrics.width(su.mid(ui, codeUnits)); +#endif for (size_t bytePos=0; (bytePos