OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrDistanceFieldTextContext.h" | 8 #include "GrDistanceFieldTextContext.h" |
9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
10 #include "GrDrawTarget.h" | 10 #include "GrDrawTarget.h" |
11 #include "GrFontScaler.h" | 11 #include "GrFontScaler.h" |
12 #include "SkGlyphCache.h" | 12 #include "SkGlyphCache.h" |
13 #include "GrIndexBuffer.h" | 13 #include "GrIndexBuffer.h" |
14 #include "GrTextStrike.h" | 14 #include "GrTextStrike.h" |
15 #include "GrTextStrike_impl.h" | 15 #include "GrTextStrike_impl.h" |
| 16 #include "SkGpuDevice.h" |
16 #include "SkPath.h" | 17 #include "SkPath.h" |
17 #include "SkRTConf.h" | 18 #include "SkRTConf.h" |
18 #include "SkStrokeRec.h" | 19 #include "SkStrokeRec.h" |
19 #include "effects/GrDistanceFieldTextureEffect.h" | 20 #include "effects/GrDistanceFieldTextureEffect.h" |
20 | 21 |
21 static const int kGlyphCoordsAttributeIndex = 1; | 22 static const int kGlyphCoordsAttributeIndex = 1; |
22 | 23 |
23 static const int kBaseDFFontSize = 32; | 24 static const int kBaseDFFontSize = 32; |
24 | 25 |
25 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, | 26 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, |
26 "Dump the contents of the font cache before every purge."); | 27 "Dump the contents of the font cache before every purge."); |
27 | 28 |
28 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, | 29 GrDistanceFieldTextContext::GrDistanceFieldTextContext(SkGpuDevice* device, |
29 const GrPaint& grPaint, | 30 const GrPaint& grPaint, |
30 const SkPaint& skPaint) | 31 const SkPaint& skPaint) |
31 : GrTextContext(context, gr
Paint, skPaint) { | 32 : GrTextContext(device, grP
aint, skPaint) { |
32 fStrike = NULL; | 33 fStrike = NULL; |
33 | 34 |
34 fCurrTexture = NULL; | 35 fCurrTexture = NULL; |
35 fCurrVertex = 0; | 36 fCurrVertex = 0; |
36 | 37 |
37 fVertices = NULL; | 38 fVertices = NULL; |
38 fMaxVertices = 0; | 39 fMaxVertices = 0; |
39 | 40 |
40 fTextRatio = fSkPaint.getTextSize()/kBaseDFFontSize; | 41 fTextRatio = fSkPaint.getTextSize()/kBaseDFFontSize; |
41 | 42 |
(...skipping 12 matching lines...) Expand all Loading... |
54 unsigned g = SkColorGetG(c); | 55 unsigned g = SkColorGetG(c); |
55 unsigned b = SkColorGetB(c); | 56 unsigned b = SkColorGetB(c); |
56 return GrColorPackRGBA(r, g, b, 0xff); | 57 return GrColorPackRGBA(r, g, b, 0xff); |
57 } | 58 } |
58 | 59 |
59 void GrDistanceFieldTextContext::flushGlyphs() { | 60 void GrDistanceFieldTextContext::flushGlyphs() { |
60 if (NULL == fDrawTarget) { | 61 if (NULL == fDrawTarget) { |
61 return; | 62 return; |
62 } | 63 } |
63 | 64 |
| 65 GrContext* context = fDevice->context(); |
64 GrDrawState* drawState = fDrawTarget->drawState(); | 66 GrDrawState* drawState = fDrawTarget->drawState(); |
65 GrDrawState::AutoRestoreEffects are(drawState); | 67 GrDrawState::AutoRestoreEffects are(drawState); |
66 drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTa
rget()); | 68 drawState->setFromPaint(fPaint, context->getMatrix(), context->getRenderTarg
et()); |
67 | 69 |
68 if (fCurrVertex > 0) { | 70 if (fCurrVertex > 0) { |
69 // setup our sampler state for our text texture/atlas | 71 // setup our sampler state for our text texture/atlas |
70 SkASSERT(GrIsALIGN4(fCurrVertex)); | 72 SkASSERT(GrIsALIGN4(fCurrVertex)); |
71 SkASSERT(fCurrTexture); | 73 SkASSERT(fCurrTexture); |
72 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil
erp_FilterMode); | 74 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil
erp_FilterMode); |
73 | 75 |
74 // This effect could be stored with one of the cache objects (atlas?) | 76 // This effect could be stored with one of the cache objects (atlas?) |
75 drawState->addCoverageEffect( | 77 drawState->addCoverageEffect( |
76 GrDistanceFieldTextureEffect::Create(fCurrTextur
e, params), | 78 GrDistanceFieldTextureEffect::Create(fCurrTextur
e, params), |
(...skipping 15 matching lines...) Expand all Loading... |
92 // paintColor | 94 // paintColor |
93 drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPain
t.getColor())); | 95 drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPain
t.getColor())); |
94 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); | 96 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); |
95 } else { | 97 } else { |
96 // set back to normal in case we took LCD path previously. | 98 // set back to normal in case we took LCD path previously. |
97 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen
dCoeff()); | 99 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen
dCoeff()); |
98 drawState->setColor(fPaint.getColor()); | 100 drawState->setColor(fPaint.getColor()); |
99 } | 101 } |
100 | 102 |
101 int nGlyphs = fCurrVertex / 4; | 103 int nGlyphs = fCurrVertex / 4; |
102 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); | 104 fDrawTarget->setIndexSourceToBuffer(context->getQuadIndexBuffer()); |
103 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, | 105 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, |
104 nGlyphs, | 106 nGlyphs, |
105 4, 6); | 107 4, 6); |
106 fDrawTarget->resetVertexSource(); | 108 fDrawTarget->resetVertexSource(); |
107 fVertices = NULL; | 109 fVertices = NULL; |
108 fMaxVertices = 0; | 110 fMaxVertices = 0; |
109 fCurrVertex = 0; | 111 fCurrVertex = 0; |
110 SkSafeSetNull(fCurrTexture); | 112 SkSafeSetNull(fCurrTexture); |
111 } | 113 } |
112 } | 114 } |
113 | 115 |
114 namespace { | 116 namespace { |
115 | 117 |
116 // position + texture coord | 118 // position + texture coord |
117 extern const GrVertexAttrib gTextVertexAttribs[] = { | 119 extern const GrVertexAttrib gTextVertexAttribs[] = { |
118 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, | 120 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, |
119 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} | 121 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} |
120 }; | 122 }; |
121 | 123 |
122 }; | 124 }; |
123 | 125 |
124 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, | 126 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, |
125 GrFixed vx, GrFixed vy, | 127 GrFixed vx, GrFixed vy, |
126 GrFontScaler* scaler) { | 128 GrFontScaler* scaler) { |
127 if (NULL == fDrawTarget) { | 129 if (NULL == fDrawTarget) { |
128 return; | 130 return; |
129 } | 131 } |
| 132 GrContext* context = fDevice->context(); |
130 if (NULL == fStrike) { | 133 if (NULL == fStrike) { |
131 fStrike = fContext->getFontCache()->getStrike(scaler, true); | 134 fStrike = context->getFontCache()->getStrike(scaler, true); |
132 } | 135 } |
133 | 136 |
134 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); | 137 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
135 if (NULL == glyph || glyph->fBounds.isEmpty()) { | 138 if (NULL == glyph || glyph->fBounds.isEmpty()) { |
136 return; | 139 return; |
137 } | 140 } |
138 | 141 |
139 SkScalar sx = SkFixedToScalar(vx); | 142 SkScalar sx = SkFixedToScalar(vx); |
140 SkScalar sy = SkFixedToScalar(vy); | 143 SkScalar sy = SkFixedToScalar(vy); |
141 /* | 144 /* |
(...skipping 14 matching lines...) Expand all Loading... |
156 return; | 159 return; |
157 } | 160 } |
158 } | 161 } |
159 */ | 162 */ |
160 if (NULL == glyph->fPlot) { | 163 if (NULL == glyph->fPlot) { |
161 if (fStrike->getGlyphAtlas(glyph, scaler)) { | 164 if (fStrike->getGlyphAtlas(glyph, scaler)) { |
162 goto HAS_ATLAS; | 165 goto HAS_ATLAS; |
163 } | 166 } |
164 | 167 |
165 // try to clear out an unused plot before we flush | 168 // try to clear out an unused plot before we flush |
166 fContext->getFontCache()->freePlotExceptFor(fStrike); | 169 context->getFontCache()->freePlotExceptFor(fStrike); |
167 if (fStrike->getGlyphAtlas(glyph, scaler)) { | 170 if (fStrike->getGlyphAtlas(glyph, scaler)) { |
168 goto HAS_ATLAS; | 171 goto HAS_ATLAS; |
169 } | 172 } |
170 | 173 |
171 if (c_DumpFontCache) { | 174 if (c_DumpFontCache) { |
172 #ifdef SK_DEVELOPER | 175 #ifdef SK_DEVELOPER |
173 fContext->getFontCache()->dump(); | 176 context->getFontCache()->dump(); |
174 #endif | 177 #endif |
175 } | 178 } |
176 | 179 |
177 // before we purge the cache, we must flush any accumulated draws | 180 // before we purge the cache, we must flush any accumulated draws |
178 this->flushGlyphs(); | 181 this->flushGlyphs(); |
179 fContext->flush(); | 182 context->flush(); |
180 | 183 |
181 // try to purge | 184 // try to purge |
182 fContext->getFontCache()->purgeExceptFor(fStrike); | 185 context->getFontCache()->purgeExceptFor(fStrike); |
183 // need to use new flush count here | 186 // need to use new flush count here |
184 if (fStrike->getGlyphAtlas(glyph, scaler)) { | 187 if (fStrike->getGlyphAtlas(glyph, scaler)) { |
185 goto HAS_ATLAS; | 188 goto HAS_ATLAS; |
186 } | 189 } |
187 | 190 |
188 if (NULL == glyph->fPath) { | 191 if (NULL == glyph->fPath) { |
189 SkPath* path = SkNEW(SkPath); | 192 SkPath* path = SkNEW(SkPath); |
190 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { | 193 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { |
191 // flag the glyph as being dead? | 194 // flag the glyph as being dead? |
192 delete path; | 195 delete path; |
193 return; | 196 return; |
194 } | 197 } |
195 glyph->fPath = path; | 198 glyph->fPath = path; |
196 } | 199 } |
197 | 200 |
198 GrContext::AutoMatrix am; | 201 GrContext::AutoMatrix am; |
199 SkMatrix translate; | 202 SkMatrix translate; |
200 translate.setTranslate(sx, sy); | 203 translate.setTranslate(sx, sy); |
201 GrPaint tmpPaint(fPaint); | 204 GrPaint tmpPaint(fPaint); |
202 am.setPreConcat(fContext, translate, &tmpPaint); | 205 am.setPreConcat(context, translate, &tmpPaint); |
203 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 206 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
204 fContext->drawPath(tmpPaint, *glyph->fPath, stroke); | 207 context->drawPath(tmpPaint, *glyph->fPath, stroke); |
205 return; | 208 return; |
206 } | 209 } |
207 | 210 |
208 HAS_ATLAS: | 211 HAS_ATLAS: |
209 SkASSERT(glyph->fPlot); | 212 SkASSERT(glyph->fPlot); |
210 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); | 213 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); |
211 glyph->fPlot->setDrawToken(drawToken); | 214 glyph->fPlot->setDrawToken(drawToken); |
212 | 215 |
213 GrTexture* texture = glyph->fPlot->texture(); | 216 GrTexture* texture = glyph->fPlot->texture(); |
214 SkASSERT(texture); | 217 SkASSERT(texture); |
215 | 218 |
216 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { | 219 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { |
217 this->flushGlyphs(); | 220 this->flushGlyphs(); |
218 fCurrTexture = texture; | 221 fCurrTexture = texture; |
219 fCurrTexture->ref(); | 222 fCurrTexture->ref(); |
220 } | 223 } |
221 | 224 |
222 if (NULL == fVertices) { | 225 if (NULL == fVertices) { |
223 // If we need to reserve vertices allow the draw target to suggest | 226 // If we need to reserve vertices allow the draw target to suggest |
224 // a number of verts to reserve and whether to perform a flush. | 227 // a number of verts to reserve and whether to perform a flush. |
225 fMaxVertices = kMinRequestedVerts; | 228 fMaxVertices = kMinRequestedVerts; |
226 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( | 229 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
227 SK_ARRAY_COUNT(gTextVertexAttribs)); | 230 SK_ARRAY_COUNT(gTextVertexAttribs)); |
228 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); | 231 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); |
229 if (flush) { | 232 if (flush) { |
230 this->flushGlyphs(); | 233 this->flushGlyphs(); |
231 fContext->flush(); | 234 context->flush(); |
232 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( | 235 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
233 SK_ARRAY_COUNT(gTextVertexAttribs)); | 236 SK_ARRAY_COUNT(gTextVertexAttribs)); |
234 } | 237 } |
235 fMaxVertices = kDefaultRequestedVerts; | 238 fMaxVertices = kDefaultRequestedVerts; |
236 // ignore return, no point in flushing again. | 239 // ignore return, no point in flushing again. |
237 fDrawTarget->geometryHints(&fMaxVertices, NULL); | 240 fDrawTarget->geometryHints(&fMaxVertices, NULL); |
238 | 241 |
239 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); | 242 int maxQuadVertices = 4 * context->getQuadIndexBuffer()->maxQuads(); |
240 if (fMaxVertices < kMinRequestedVerts) { | 243 if (fMaxVertices < kMinRequestedVerts) { |
241 fMaxVertices = kDefaultRequestedVerts; | 244 fMaxVertices = kDefaultRequestedVerts; |
242 } else if (fMaxVertices > maxQuadVertices) { | 245 } else if (fMaxVertices > maxQuadVertices) { |
243 // don't exceed the limit of the index buffer | 246 // don't exceed the limit of the index buffer |
244 fMaxVertices = maxQuadVertices; | 247 fMaxVertices = maxQuadVertices; |
245 } | 248 } |
246 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, | 249 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, |
247 0, | 250 0, |
248 GrTCast<void**>(&
fVertices), | 251 GrTCast<void**>(&
fVertices), |
249 NULL); | 252 NULL); |
(...skipping 26 matching lines...) Expand all Loading... |
276 2 * sizeof(SkPoint)); | 279 2 * sizeof(SkPoint)); |
277 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed
X(tx)), | 280 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed
X(tx)), |
278 SkFixedToFloat(texture->normalizeFixed
Y(ty)), | 281 SkFixedToFloat(texture->normalizeFixed
Y(ty)), |
279 SkFixedToFloat(texture->normalizeFixed
X(tx + tw)), | 282 SkFixedToFloat(texture->normalizeFixed
X(tx + tw)), |
280 SkFixedToFloat(texture->normalizeFixed
Y(ty + th)), | 283 SkFixedToFloat(texture->normalizeFixed
Y(ty + th)), |
281 2 * sizeof(SkPoint)); | 284 2 * sizeof(SkPoint)); |
282 fCurrVertex += 4; | 285 fCurrVertex += 4; |
283 } | 286 } |
284 | 287 |
285 void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength, | 288 void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength, |
286 SkScalar x, SkScalar y, SkGlyphCache*
cache, | 289 SkScalar x, SkScalar y) { |
287 GrFontScaler* fontScaler) { | |
288 SkASSERT(byteLength == 0 || text != NULL); | 290 SkASSERT(byteLength == 0 || text != NULL); |
289 | 291 |
290 // nothing to draw | 292 // nothing to draw or can't draw |
291 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/)
{ | 293 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ |
| 294 || fSkPaint.getRasterizer()) { |
292 return; | 295 return; |
293 } | 296 } |
294 | 297 |
295 SkScalar sizeRatio = fTextRatio; | 298 SkScalar sizeRatio = fTextRatio; |
296 | 299 |
297 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 300 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
298 | 301 |
| 302 SkAutoGlyphCache autoCache(fSkPaint, &fDevice->getDeviceProperties(), NUL
L); |
| 303 SkGlyphCache* cache = autoCache.getCache(); |
| 304 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 305 |
299 // need to measure first | 306 // need to measure first |
300 // TODO - generate positions and pre-load cache as well? | 307 // TODO - generate positions and pre-load cache as well? |
301 const char* stop = text + byteLength; | 308 const char* stop = text + byteLength; |
302 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { | 309 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { |
303 SkFixed stopX = 0; | 310 SkFixed stopX = 0; |
304 SkFixed stopY = 0; | 311 SkFixed stopY = 0; |
305 | 312 |
306 const char* textPtr = text; | 313 const char* textPtr = text; |
307 while (textPtr < stop) { | 314 while (textPtr < stop) { |
308 // don't need x, y here, since all subpixel variants will have the | 315 // don't need x, y here, since all subpixel variants will have the |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 fontScaler); | 348 fontScaler); |
342 } | 349 } |
343 | 350 |
344 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale); | 351 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale); |
345 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale); | 352 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale); |
346 } | 353 } |
347 } | 354 } |
348 | 355 |
349 void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLengt
h, | 356 void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLengt
h, |
350 const SkScalar pos[], SkScalar cons
tY, | 357 const SkScalar pos[], SkScalar cons
tY, |
351 int scalarsPerPosition, | 358 int scalarsPerPosition) { |
352 SkGlyphCache* cache, GrFontScaler*
fontScaler) { | |
353 | 359 |
354 SkASSERT(byteLength == 0 || text != NULL); | 360 SkASSERT(byteLength == 0 || text != NULL); |
355 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 361 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
356 | 362 |
357 // nothing to draw | 363 // nothing to draw |
358 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/)
{ | 364 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ |
| 365 || fSkPaint.getRasterizer()) { |
359 return; | 366 return; |
360 } | 367 } |
361 | 368 |
362 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 369 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
363 | 370 |
| 371 SkAutoGlyphCache autoCache(fSkPaint, &fDevice->getDeviceProperties(), NUL
L); |
| 372 SkGlyphCache* cache = autoCache.getCache(); |
| 373 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 374 |
364 const char* stop = text + byteLength; | 375 const char* stop = text + byteLength; |
365 | 376 |
366 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { | 377 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { |
367 while (text < stop) { | 378 while (text < stop) { |
368 // the last 2 parameters are ignored | 379 // the last 2 parameters are ignored |
369 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 380 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
370 | 381 |
371 if (glyph.fWidth) { | 382 if (glyph.fWidth) { |
372 SkScalar x = pos[0]; | 383 SkScalar x = pos[0]; |
373 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1]; | 384 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1]; |
(...skipping 23 matching lines...) Expand all Loading... |
397 SkScalarToFixed(x) - (glyph.fAdvanceX >> a
lignShift) | 408 SkScalarToFixed(x) - (glyph.fAdvanceX >> a
lignShift) |
398 + SK_FixedHalf, //d1g.fHalfSampleX, | 409 + SK_FixedHalf, //d1g.fHalfSampleX, |
399 SkScalarToFixed(y) - (glyph.fAdvanceY >> a
lignShift) | 410 SkScalarToFixed(y) - (glyph.fAdvanceY >> a
lignShift) |
400 + SK_FixedHalf, //d1g.fHalfSampleY, | 411 + SK_FixedHalf, //d1g.fHalfSampleY, |
401 fontScaler); | 412 fontScaler); |
402 } | 413 } |
403 pos += scalarsPerPosition; | 414 pos += scalarsPerPosition; |
404 } | 415 } |
405 } | 416 } |
406 } | 417 } |
OLD | NEW |