| 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 |