[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