Version: (using KDE KDE 3.3.2) Installed from: Debian testing/unstable Packages OS: Linux When selecting text written in devanagari, compound characters are "uncompounded", ie. instead of seeing one character, you see the consonant followed by the diacritic marks. When the selection reaches the end of the compound character, this character comes back to its normal shape. It seems to misbehave in the same way with all scripts from brahmi origin.
please create an attachment of or include a link to an example of what you describe
SVN commit 532315 by savernik: Fixed text mutation at selection boundaries for complex scripts. Big thanks to Simon Hausmann who did all the grunt work. I applied some optimisations to restrict clipping and double repaints to those inline text boxes which contain selection boundaries. BUG: 101009 CCMAIL: hausmann@kde.org M +35 -53 render_text.cpp --- branches/KDE/3.5/kdelibs/khtml/rendering/render_text.cpp #532314:532315 @@ -140,10 +140,33 @@ p->setPen(hc); //kdDebug( 6040 ) << "textRun::painting(" << QConstString(text->str->s + m_start, m_len).string().left(30) << ") at(" << m_x+tx << "/" << m_y+ty << ")" << endl; + + const bool needClipping = startPos != 0 || endPos != m_len; + + if (needClipping) { + p->save(); + + int visualSelectionStart = f->width(text->str->s, text->str->l, m_start, startPos); + int visualSelectionEnd = f->width(text->str->s, text->str->l, m_start, endPos); + int visualSelectionWidth = visualSelectionEnd - visualSelectionStart; + if (m_reversed) { + visualSelectionStart = f->width(text->str->s, text->str->l, m_start, m_len) - visualSelectionEnd; + } + + QRect selectionRect(m_x + tx + visualSelectionStart, m_y + ty, visualSelectionWidth, height()); + QRegion r(selectionRect); + if (p->hasClipping()) + r &= p->clipRegion(QPainter::CoordPainter); + p->setClipRegion(r, QPainter::CoordPainter); + } + f->drawText(p, m_x + tx, m_y + ty + m_baseline, text->str->s, text->str->l, - m_start, m_len, m_toAdd, - m_reversed ? QPainter::RTL : QPainter::LTR, - startPos, endPos, hbg, m_y + ty, height(), deco); + m_start, m_len, m_toAdd, + m_reversed ? QPainter::RTL : QPainter::LTR, + needClipping ? 0 : startPos, needClipping ? m_len : endPos, + hbg, m_y + ty, height(), deco); + + if (needClipping) p->restore(); } void InlineTextBox::paintDecoration( QPainter *pt, const Font *f, int _tx, int _ty, int deco) @@ -922,55 +945,17 @@ } #endif + const int offset = s->m_start; + const int sPos = kMax( startPos - offset, 0 ); + const int ePos = kMin( endPos - offset, int( s->m_len ) ); if (s->m_len > 0 && pI.phase != PaintActionSelection) { - if (!haveSelection) { - //kdDebug( 6040 ) << "RenderObject::paintObject(" << QConstString(str->s + s->m_start, s->m_len).string() << ") at(" << s->m_x+tx << "/" << s->m_y+ty << ")" << endl; -#ifndef APPLE_CHANGES - if (_style->textShadow()) - s->paintShadow(pI.p, font, tx, ty, _style->textShadow()); -#endif + //kdDebug( 6040 ) << "RenderObject::paintObject(" << QConstString(str->s + s->m_start, s->m_len).string() << ") at(" << s->m_x+tx << "/" << s->m_y+ty << ")" << endl; + if (_style->textShadow()) + s->paintShadow(pI.p, font, tx, ty, _style->textShadow()); // kdDebug(6040) << QConstString(str->s + s->m_start, s->m_len).string().left(40) << endl; - font->drawText(pI.p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, str->l, s->m_start, s->m_len, - s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR); - } - else { - int offset = s->m_start; - int sPos = kMax( startPos - offset, 0 ); - int ePos = kMin( endPos - offset, int( s->m_len ) ); -// selected text is always separate in konqueror -#ifdef APPLE_CHANGES - if (paintSelectedTextSeparately) { -#endif -#ifndef APPLE_CHANGES - if (_style->textShadow()) - s->paintShadow(pI.p, font, tx, ty, _style->textShadow()); -#endif - if (sPos >= ePos) - font->drawText(pI.p, s->m_x + tx, s->m_y + ty + s->m_baseline, - str->s, str->l, s->m_start, s->m_len, - s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR); - else { - if (sPos-1 >= 0) - font->drawText(pI.p, s->m_x + tx, s->m_y + ty + s->m_baseline, - str->s, str->l, s->m_start, s->m_len, - s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, 0, sPos); - if (ePos < s->m_len) - font->drawText(pI.p, s->m_x + tx, s->m_y + ty + s->m_baseline, - str->s, str->l, s->m_start, s->m_len, - s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, ePos, s->m_len); - } -#ifdef APPLE_CHANGES - } - - if ( sPos < ePos ) { - if (selectionColor != p->pen().color()) - p->setPen(selectionColor); - - font->drawText(pI.p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, - str->l, s->m_start, s->m_len, - s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, sPos, ePos); - } -#endif + if (!haveSelection || sPos != 0 || ePos != s->m_len) { + font->drawText(pI.p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, str->l, s->m_start, s->m_len, + s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR); } } @@ -981,9 +966,6 @@ } if (haveSelection && pI.phase == PaintActionSelection) { - int offset = s->m_start; - int sPos = kMax( startPos - offset, 0 ); - int ePos = kMin( endPos - offset, int( s->m_len ) ); //kdDebug(6040) << this << " paintSelection with startPos=" << sPos << " endPos=" << ePos << endl; if ( sPos < ePos ) s->paintSelection(font, this, pI.p, _style, tx, ty, sPos, ePos, d);
This commit broke selection e.g. on bugs.kde.org. If I hover word "devangari", painted hover is over letters "n devanga". Primary selection contains correct word bug painting has some weird offset.
Thanks Leo, your fix works fine ;-D
You need to log in before you can comment on or make changes to this bug.