View | Details | Raw Unified | Return to issue 26519
Collapse All | Expand All

(-)vcl/source/glyphs/gcach_layout.cxx (-24 / +66 lines)
Lines 36-41 Link Here
36
#include <vcl/sallayout.hxx>
36
#include <vcl/sallayout.hxx>
37
#include <vcl/salgdi.hxx>
37
#include <vcl/salgdi.hxx>
38
38
39
#include <unicode/uchar.h>
40
39
#include <vcl/svapp.hxx>
41
#include <vcl/svapp.hxx>
40
42
41
#include <sal/alloca.h>
43
#include <sal/alloca.h>
Lines 110-116 Link Here
110
    int nGlyphWidth = 0;
112
    int nGlyphWidth = 0;
111
    GlyphItem aPrevItem;
113
    GlyphItem aPrevItem;
112
    bool bRightToLeft;
114
    bool bRightToLeft;
113
    for( int nCharPos = -1; rArgs.GetNextPos( &nCharPos, &bRightToLeft ); )
115
116
    int nCharPos = -1;
117
    bool hasNextPos = rArgs.GetNextPos( &nCharPos, &bRightToLeft );
118
    bool isAfterEnd = false;
119
    bool bFoundPrintable = false;
120
    while ( hasNextPos || ( isAfterEnd && ( !bFoundPrintable || nCharPos < rArgs.mnLength ) ) )
114
    {
121
    {
115
        sal_UCS4 cChar = rArgs.mpStr[ nCharPos ];
122
        sal_UCS4 cChar = rArgs.mpStr[ nCharPos ];
116
        if( (cChar >= 0xD800) && (cChar <= 0xDFFF) )
123
        if( (cChar >= 0xD800) && (cChar <= 0xDFFF) )
Lines 123-155 Link Here
123
130
124
        if( bRightToLeft )
131
        if( bRightToLeft )
125
            cChar = GetMirroredChar( cChar );
132
            cChar = GetMirroredChar( cChar );
126
        int nGlyphIndex = rFont.GetGlyphIndex( cChar );
127
        // when glyph fallback is needed update LayoutArgs
128
        if( !nGlyphIndex ) {
129
            rArgs.NeedFallback( nCharPos, bRightToLeft );
130
        if( cChar >= 0x10000 ) // handle surrogate pairs
131
                rArgs.NeedFallback( nCharPos+1, bRightToLeft );
132
    }
133
133
134
        // apply pair kerning to prev glyph if requested
134
        // Only handle the printable characters
135
        if( SAL_LAYOUT_KERNING_PAIRS & rArgs.mnFlags )
135
        if ( u_isprint( UChar32( cChar ) ) )
136
        {
136
        {
137
            int nKernValue = rFont.GetGlyphKernValue( nOldGlyphId, nGlyphIndex );
137
            int nGlyphIndex = rFont.GetGlyphIndex( cChar );
138
            nGlyphWidth += nKernValue;
138
            // when glyph fallback is needed update LayoutArgs
139
            aPrevItem.mnNewWidth = nGlyphWidth;
139
            if( !nGlyphIndex ) 
140
            {
141
                rArgs.NeedFallback( nCharPos, bRightToLeft );
142
                if( cChar >= 0x10000 ) // handle surrogate pairs
143
                    rArgs.NeedFallback( nCharPos+1, bRightToLeft );
144
            }
145
146
            // apply pair kerning to prev glyph if requested
147
            if( SAL_LAYOUT_KERNING_PAIRS & rArgs.mnFlags )
148
            {
149
                int nKernValue = rFont.GetGlyphKernValue( nOldGlyphId, nGlyphIndex );
150
                nGlyphWidth += nKernValue;
151
                aPrevItem.mnNewWidth = nGlyphWidth;
152
            }
153
154
            // finish previous glyph
155
            if( nOldGlyphId >= 0 )
156
            {
157
                rLayout.AppendGlyph( aPrevItem );
158
            }
159
160
            aNewPos.X() += nGlyphWidth;
161
162
            // prepare GlyphItem for appending it in next round
163
            if ( !isAfterEnd ) 
164
            {
165
                nOldGlyphId = nGlyphIndex;
166
                const GlyphMetric& rGM = rFont.GetGlyphMetric( nGlyphIndex );
167
                nGlyphWidth = rGM.GetCharWidth();
168
                int nGlyphFlags = bRightToLeft ? GlyphItem::IS_RTL_GLYPH : 0;
169
170
                aPrevItem = GlyphItem( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth );
171
            }
172
173
            // No need to signal the printable chars before the end of the runs
174
            bFoundPrintable = isAfterEnd;
140
        }
175
        }
141
176
142
        // finish previous glyph
177
        if ( !isAfterEnd )
143
        if( nOldGlyphId >= 0 )
178
        {
144
            rLayout.AppendGlyph( aPrevItem );
179
            // Check if we have some more characters
145
        aNewPos.X() += nGlyphWidth;
180
            // Get the next position
146
181
            hasNextPos = rArgs.GetNextPos( &nCharPos, &bRightToLeft );
147
        // prepare GlyphItem for appending it in next round
182
148
        nOldGlyphId = nGlyphIndex;
183
            if ( !hasNextPos && nCharPos < rArgs.mnLength )
149
        const GlyphMetric& rGM = rFont.GetGlyphMetric( nGlyphIndex );
184
                isAfterEnd = true;
150
        nGlyphWidth = rGM.GetCharWidth();
185
        } 
151
        int nGlyphFlags = bRightToLeft ? GlyphItem::IS_RTL_GLYPH : 0;
186
        else 
152
        aPrevItem = GlyphItem( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth );
187
        {
188
            nCharPos++;
189
            if ( bFoundPrintable ) 
190
            {
191
                isAfterEnd = false;
192
                nOldGlyphId = -1;
193
            }
194
        }
153
    }
195
    }
154
196
155
    // append last glyph item if any
197
    // append last glyph item if any

Return to issue 26519