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 |