--- vcl/source/glyphs/gcach_layout.cxx 2009-08-11 12:51:42.000000000 +0200 +++ vcl/source/glyphs/gcach_layout.cxx 2009-08-13 15:51:34.000000000 +0200 @@ -36,6 +36,8 @@ #include #include +#include + #include #include @@ -110,7 +112,12 @@ int nGlyphWidth = 0; GlyphItem aPrevItem; bool bRightToLeft; - for( int nCharPos = -1; rArgs.GetNextPos( &nCharPos, &bRightToLeft ); ) + + int nCharPos = -1; + bool hasNextPos = rArgs.GetNextPos( &nCharPos, &bRightToLeft ); + bool isAfterEnd = false; + bool bFoundPrintable = false; + while ( hasNextPos || ( isAfterEnd && ( !bFoundPrintable || nCharPos < rArgs.mnLength ) ) ) { sal_UCS4 cChar = rArgs.mpStr[ nCharPos ]; if( (cChar >= 0xD800) && (cChar <= 0xDFFF) ) @@ -123,33 +130,68 @@ if( bRightToLeft ) cChar = GetMirroredChar( cChar ); - int nGlyphIndex = rFont.GetGlyphIndex( cChar ); - // when glyph fallback is needed update LayoutArgs - if( !nGlyphIndex ) { - rArgs.NeedFallback( nCharPos, bRightToLeft ); - if( cChar >= 0x10000 ) // handle surrogate pairs - rArgs.NeedFallback( nCharPos+1, bRightToLeft ); - } - // apply pair kerning to prev glyph if requested - if( SAL_LAYOUT_KERNING_PAIRS & rArgs.mnFlags ) + // Only handle the printable characters + if ( u_isprint( UChar32( cChar ) ) ) { - int nKernValue = rFont.GetGlyphKernValue( nOldGlyphId, nGlyphIndex ); - nGlyphWidth += nKernValue; - aPrevItem.mnNewWidth = nGlyphWidth; + int nGlyphIndex = rFont.GetGlyphIndex( cChar ); + // when glyph fallback is needed update LayoutArgs + if( !nGlyphIndex ) + { + rArgs.NeedFallback( nCharPos, bRightToLeft ); + if( cChar >= 0x10000 ) // handle surrogate pairs + rArgs.NeedFallback( nCharPos+1, bRightToLeft ); + } + + // apply pair kerning to prev glyph if requested + if( SAL_LAYOUT_KERNING_PAIRS & rArgs.mnFlags ) + { + int nKernValue = rFont.GetGlyphKernValue( nOldGlyphId, nGlyphIndex ); + nGlyphWidth += nKernValue; + aPrevItem.mnNewWidth = nGlyphWidth; + } + + // finish previous glyph + if( nOldGlyphId >= 0 ) + { + rLayout.AppendGlyph( aPrevItem ); + } + + aNewPos.X() += nGlyphWidth; + + // prepare GlyphItem for appending it in next round + if ( !isAfterEnd ) + { + nOldGlyphId = nGlyphIndex; + const GlyphMetric& rGM = rFont.GetGlyphMetric( nGlyphIndex ); + nGlyphWidth = rGM.GetCharWidth(); + int nGlyphFlags = bRightToLeft ? GlyphItem::IS_RTL_GLYPH : 0; + + aPrevItem = GlyphItem( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth ); + } + + // No need to signal the printable chars before the end of the runs + bFoundPrintable = isAfterEnd; } - // finish previous glyph - if( nOldGlyphId >= 0 ) - rLayout.AppendGlyph( aPrevItem ); - aNewPos.X() += nGlyphWidth; - - // prepare GlyphItem for appending it in next round - nOldGlyphId = nGlyphIndex; - const GlyphMetric& rGM = rFont.GetGlyphMetric( nGlyphIndex ); - nGlyphWidth = rGM.GetCharWidth(); - int nGlyphFlags = bRightToLeft ? GlyphItem::IS_RTL_GLYPH : 0; - aPrevItem = GlyphItem( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth ); + if ( !isAfterEnd ) + { + // Check if we have some more characters + // Get the next position + hasNextPos = rArgs.GetNextPos( &nCharPos, &bRightToLeft ); + + if ( !hasNextPos && nCharPos < rArgs.mnLength ) + isAfterEnd = true; + } + else + { + nCharPos++; + if ( bFoundPrintable ) + { + isAfterEnd = false; + nOldGlyphId = -1; + } + } } // append last glyph item if any