Drawing complex scripts with pango.

From: Martin Sevior <msevior_at_gmail.com>
Date: Mon Aug 17 2009 - 09:22:40 CEST

Hi everyone,
                 Bug 12284 nepali text selection oddities,

http://bugzilla.abisource.com/show_bug.cgi?id=12284

See the effect in this screenshot:

http://bugzilla.abisource.com/attachment.cgi?id=5028

Is caused by the same effect that makes characters "dance" around on
the screen as we select them.

The problem is that pango doesn't like rendering starting from the
middle of a run characters. For roman text it's left-more position is
undefined to within one pixel. For complex scripts like Nepalese where
two or more unicode values are combined to make one glyph pango just
doesn't draw the string.

The problem is in fp_TextRun::_draw(...)

The problem code is this:

                // reset the iterator
                text.setPosition(iIterPos);
                m_pRenderInfo->m_iOffset = iMyOffset;
                m_pRenderInfo->m_iLength =
iSegmentOffset[iSegment+1]-iSegmentOffset[iSegment];
                m_pRenderInfo->m_xoff = iX;
                m_pRenderInfo->m_yoff = yTopOfRun;
                painter.renderChars(*m_pRenderInfo);

and in particular setting m_pRenderInfo->m_iOffset and m_pRenderInfo->m_iLength.

If we replace this with code with and always do one complete draw for
the run, rather than draw in segments

        pG->setColor(getFGColor());
        if(iVisDir == UT_BIDI_RTL)
                iX -= getWidth();
        m_pRenderInfo->m_iOffset = 0;
        m_pRenderInfo->m_iLength = getLength();
        m_pRenderInfo->m_xoff = iX;
        m_pRenderInfo->m_yoff = yTopOfRun;
        painter.renderChars(*m_pRenderInfo);

The dancing characters and fixed and we draw correctly. The downside
is that we always use the some color for the foreground text instead
of the
fancy color selection we currently with this code:

                if(bSegmentSelected[iSegment])
                {
                        pG->setColor(_getView()->getColorSelForeground());
                }
                else
                {
                        pG->setColor(getFGColor());
                }

I'm personally happy to give up the fancy color. I know that uwog
didn't not like to do this, but that was before this selection bug
showed up.

What are peoples opinions on how to proceed? My impression is that for
complex scripts the output of pango is undefined if you attempt to
draw in the middle of a run.

Cheers,

Martin
Received on Mon Aug 17 09:23:21 2009

This archive was generated by hypermail 2.1.8 : Mon Aug 17 2009 - 09:23:21 CEST