[QScintilla] Wrong highlighting when text contains non-ascii characters

Phil Thompson phil at riverbankcomputing.com
Tue Nov 23 11:08:31 GMT 2010


On Mon, 22 Nov 2010 17:02:38 -0500, Mikhail Murzin <mezomish at gmail.com>
wrote:
> Hi folks,
> 
> Found the following issue: QScintilla highlights wrong ranges with
> SCI_INDICATORFILLRANGE
> if the text contains non-ascii characters.
> 
> Here is a code to reproduce:
> 
> #include <QApplication>
> #include <QFile>
> #include <Qsci/QsciScintilla.h>
> 
> int main(int argc, char* argv[]) {
>     QApplication app(argc, argv);
> 
>     if ( argc < 2 ) {
>         return 0;
>     }
> 
>     QsciScintilla sci;
>     sci.setUtf8(true);
> #ifdef Q_OS_WIN32
>     sci.setFont(QFont("Courier New", 10));
> #else
>     sci.setFont(QFont("Monospace", 10));
> #endif
> 
>     QFile file(argv[1]);
>     if ( file.open(QIODevice::ReadOnly) ) {
>         sci.read(&file);
>         file.close();
>     }
> 
>     int lineCount = sci.lines();
>     for ( int line = 0; line < lineCount; ++line ) {
>         // getting the position for the line's beginning
>         long linePos =
> sci.SendScintilla(QsciScintilla::SCI_POSITIONFROMLINE, line);
>         // highlighting exactly 10 characters starting from the 5th
> character
>         sci.SendScintilla(QsciScintilla::SCI_INDICATORFILLRANGE, linePos
+
> 5, 10);
>     }
> 
>     sci.resize(500, 150);
>     sci.show();
> 
>     return app.exec();
> }
> 
> 
> The code is pretty much self-explanatory but just to be clear: trying to
> highlight exactly 10 characters starting from the 5th character of each
> line.
> As you can see it's not always 10 characters highlighted and it can be
any
> number from 5 to 10 (depending on how many non-ascii symbols are there
in
> highlighting region).
> Also highlighting not always starts at the 5th character (depending on
how
> many non-ascii characters are there before the highlighting region).
> Looks like somewhere in highlighting code byte count is used instead of
> character count - that's why it works for ASCII chars but doesn't work
for
> non-ASCII.
> 
> Here is the screenshot:
> http://dl.dropbox.com/u/6404414/qscintilla_hl_bug.png
> Here is the archive with the code above and a text file to test with:
> http://dl.dropbox.com/u/6404414/hlexample.zip (launch the app with
> "test.txt" passed as the 1st argument).

Character positions are not the same as byte positions - you need to
convert between the two using QsciScintilla::positionFromLineIndex().

Change the body of your loop to...

    int start = sci.positionFromLineIndex(line, 5);
    int end = sci.positionFromLineIndex(line, 10);

    sci.SendScintilla(QsciScintilla::SCI_INDICATORFILLRANGE, start, end -
start);

Phil


More information about the QScintilla mailing list