| 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 "SkColorFilter.h" | 10 #include "SkColorFilter.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 bool enable) | 58 bool enable) |
| 59 : GrTextContext(context, pro
perties) { | 59 : GrTextContext(context, pro
perties) { |
| 60 #if SK_FORCE_DISTANCEFIELD_FONTS | 60 #if SK_FORCE_DISTANCEFIELD_FONTS |
| 61 fEnableDFRendering = true; | 61 fEnableDFRendering = true; |
| 62 #else | 62 #else |
| 63 fEnableDFRendering = enable; | 63 fEnableDFRendering = enable; |
| 64 #endif | 64 #endif |
| 65 fStrike = NULL; | 65 fStrike = NULL; |
| 66 fGammaTexture = NULL; | 66 fGammaTexture = NULL; |
| 67 | 67 |
| 68 fCurrTexture = NULL; |
| 68 fCurrVertex = 0; | 69 fCurrVertex = 0; |
| 69 fEffectTextureUniqueID = SK_InvalidUniqueID; | 70 fEffectTextureUniqueID = SK_InvalidUniqueID; |
| 70 fEffectColor = GrColor_ILLEGAL; | 71 fEffectColor = GrColor_ILLEGAL; |
| 71 fEffectFlags = 0; | 72 fEffectFlags = 0; |
| 72 | 73 |
| 73 fVertices = NULL; | 74 fVertices = NULL; |
| 75 fMaxVertices = 0; |
| 74 | 76 |
| 75 fVertexBounds.setLargestInverted(); | 77 fVertexBounds.setLargestInverted(); |
| 76 } | 78 } |
| 77 | 79 |
| 78 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { | 80 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { |
| 79 this->flushGlyphs(); | 81 this->flushGlyphs(); |
| 80 SkSafeSetNull(fGammaTexture); | 82 SkSafeSetNull(fGammaTexture); |
| 81 } | 83 } |
| 82 | 84 |
| 83 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { | 85 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 113 unsigned r = SkColorGetR(c); | 115 unsigned r = SkColorGetR(c); |
| 114 unsigned g = SkColorGetG(c); | 116 unsigned g = SkColorGetG(c); |
| 115 unsigned b = SkColorGetB(c); | 117 unsigned b = SkColorGetB(c); |
| 116 return GrColorPackRGBA(r, g, b, 0xff); | 118 return GrColorPackRGBA(r, g, b, 0xff); |
| 117 } | 119 } |
| 118 | 120 |
| 119 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
r) { | 121 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
r) { |
| 120 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_
FilterMode); | 122 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_
FilterMode); |
| 121 GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNon
e_FilterMode); | 123 GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNon
e_FilterMode); |
| 122 | 124 |
| 123 GrTexture* currTexture = fStrike->getTexture(); | 125 uint32_t textureUniqueID = fCurrTexture->getUniqueID(); |
| 124 SkASSERT(currTexture); | |
| 125 uint32_t textureUniqueID = currTexture->getUniqueID(); | |
| 126 | 126 |
| 127 // set up any flags | 127 // set up any flags |
| 128 uint32_t flags = 0; | 128 uint32_t flags = 0; |
| 129 flags |= fContext->getMatrix().isSimilarity() ? kSimilarity_DistanceFieldEff
ectFlag : 0; | 129 flags |= fContext->getMatrix().isSimilarity() ? kSimilarity_DistanceFieldEff
ectFlag : 0; |
| 130 flags |= fUseLCDText ? kUseLCD_DistanceFieldEffectFlag : 0; | 130 flags |= fUseLCDText ? kUseLCD_DistanceFieldEffectFlag : 0; |
| 131 flags |= fUseLCDText && fContext->getMatrix().rectStaysRect() ? | 131 flags |= fUseLCDText && fContext->getMatrix().rectStaysRect() ? |
| 132 kRectToRect_DistanceFieldEffectFlag : 0; | 132 kRectToRect_DistanceFieldEffectFlag : 0; |
| 133 bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout == | 133 bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout == |
| 134 fDeviceProperties.fGeometry.getLayout(); | 134 fDeviceProperties.fGeometry.getLayout(); |
| 135 flags |= fUseLCDText && useBGR ? kBGR_DistanceFieldEffectFlag : 0; | 135 flags |= fUseLCDText && useBGR ? kBGR_DistanceFieldEffectFlag : 0; |
| 136 | 136 |
| 137 // see if we need to create a new effect | 137 // see if we need to create a new effect |
| 138 if (textureUniqueID != fEffectTextureUniqueID || | 138 if (textureUniqueID != fEffectTextureUniqueID || |
| 139 filteredColor != fEffectColor || | 139 filteredColor != fEffectColor || |
| 140 flags != fEffectFlags) { | 140 flags != fEffectFlags) { |
| 141 if (fUseLCDText) { | 141 if (fUseLCDText) { |
| 142 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredCol
or); | 142 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredCol
or); |
| 143 fCachedEffect.reset(GrDistanceFieldLCDTextureEffect::Create(currText
ure, | 143 fCachedEffect.reset(GrDistanceFieldLCDTextureEffect::Create(fCurrTex
ture, |
| 144 params, | 144 params, |
| 145 fGammaTe
xture, | 145 fGammaTe
xture, |
| 146 gammaPar
ams, | 146 gammaPar
ams, |
| 147 colorNoP
reMul, | 147 colorNoP
reMul, |
| 148 flags)); | 148 flags)); |
| 149 } else { | 149 } else { |
| 150 #ifdef SK_GAMMA_APPLY_TO_A8 | 150 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 151 U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDevicePropertie
s.fGamma, | 151 U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDevicePropertie
s.fGamma, |
| 152 filteredColor); | 152 filteredColor); |
| 153 fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(currTexture
, | 153 fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(fCurrTextur
e, |
| 154 params, | 154 params, |
| 155 fGammaTextu
re, | 155 fGammaTextu
re, |
| 156 gammaParams
, | 156 gammaParams
, |
| 157 lum/255.f, | 157 lum/255.f, |
| 158 flags)); | 158 flags)); |
| 159 #else | 159 #else |
| 160 fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(currTexture
, | 160 fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(currTexture
, |
| 161 params, fla
gs)); | 161 params, fla
gs)); |
| 162 #endif | 162 #endif |
| 163 } | 163 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 //drawState->setColor(fPaint.getColor()); | 221 //drawState->setColor(fPaint.getColor()); |
| 222 // We're using per-vertex color. | 222 // We're using per-vertex color. |
| 223 SkASSERT(drawState->hasColorVertexAttribute()); | 223 SkASSERT(drawState->hasColorVertexAttribute()); |
| 224 drawState->setColor(0xFFFFFFFF); | 224 drawState->setColor(0xFFFFFFFF); |
| 225 } | 225 } |
| 226 int nGlyphs = fCurrVertex / 4; | 226 int nGlyphs = fCurrVertex / 4; |
| 227 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); | 227 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); |
| 228 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, | 228 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, |
| 229 nGlyphs, | 229 nGlyphs, |
| 230 4, 6, &fVertexBounds); | 230 4, 6, &fVertexBounds); |
| 231 fDrawTarget->resetVertexSource(); |
| 232 fVertices = NULL; |
| 233 fMaxVertices = 0; |
| 231 fCurrVertex = 0; | 234 fCurrVertex = 0; |
| 235 SkSafeSetNull(fCurrTexture); |
| 232 fVertexBounds.setLargestInverted(); | 236 fVertexBounds.setLargestInverted(); |
| 233 } | 237 } |
| 234 | |
| 235 fDrawTarget->resetVertexSource(); | |
| 236 fVertices = NULL; | |
| 237 } | 238 } |
| 238 | 239 |
| 239 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, | 240 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, |
| 240 SkFixed vx, SkFixed vy, | 241 SkFixed vx, SkFixed vy, |
| 241 GrFontScaler* scaler) { | 242 GrFontScaler* scaler) { |
| 243 if (NULL == fDrawTarget) { |
| 244 return; |
| 245 } |
| 246 |
| 247 if (NULL == fStrike) { |
| 248 fStrike = fContext->getFontCache()->getStrike(scaler, true); |
| 249 } |
| 250 |
| 242 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); | 251 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
| 243 if (NULL == glyph || glyph->fBounds.isEmpty()) { | 252 if (NULL == glyph || glyph->fBounds.isEmpty()) { |
| 244 return; | 253 return; |
| 245 } | 254 } |
| 246 | 255 |
| 247 SkScalar sx = SkFixedToScalar(vx); | 256 SkScalar sx = SkFixedToScalar(vx); |
| 248 SkScalar sy = SkFixedToScalar(vy); | 257 SkScalar sy = SkFixedToScalar(vy); |
| 249 /* | 258 /* |
| 250 // not valid, need to find a different solution for this | 259 // not valid, need to find a different solution for this |
| 251 vx += SkIntToFixed(glyph->fBounds.fLeft); | 260 vx += SkIntToFixed(glyph->fBounds.fLeft); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 } | 323 } |
| 315 | 324 |
| 316 HAS_ATLAS: | 325 HAS_ATLAS: |
| 317 SkASSERT(glyph->fPlot); | 326 SkASSERT(glyph->fPlot); |
| 318 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); | 327 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); |
| 319 glyph->fPlot->setDrawToken(drawToken); | 328 glyph->fPlot->setDrawToken(drawToken); |
| 320 | 329 |
| 321 GrTexture* texture = glyph->fPlot->texture(); | 330 GrTexture* texture = glyph->fPlot->texture(); |
| 322 SkASSERT(texture); | 331 SkASSERT(texture); |
| 323 | 332 |
| 333 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { |
| 334 this->flushGlyphs(); |
| 335 fCurrTexture = texture; |
| 336 fCurrTexture->ref(); |
| 337 } |
| 338 |
| 339 bool useColorVerts = !fUseLCDText; |
| 340 |
| 341 if (NULL == fVertices) { |
| 342 // If we need to reserve vertices allow the draw target to suggest |
| 343 // a number of verts to reserve and whether to perform a flush. |
| 344 fMaxVertices = kMinRequestedVerts; |
| 345 if (useColorVerts) { |
| 346 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttri
bs>( |
| 347 SK_ARRAY_COUNT(gTextVertexWi
thColorAttribs)); |
| 348 } else { |
| 349 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
| 350 SK_ARRAY_COUNT(gTextVertexAt
tribs)); |
| 351 } |
| 352 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); |
| 353 if (flush) { |
| 354 this->flushGlyphs(); |
| 355 fContext->flush(); |
| 356 if (useColorVerts) { |
| 357 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorA
ttribs>( |
| 358 SK_ARRAY_COUNT(gTextVertexWi
thColorAttribs)); |
| 359 } else { |
| 360 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
| 361 SK_ARRAY_COUNT(gTextVertexAt
tribs)); |
| 362 } |
| 363 } |
| 364 fMaxVertices = kDefaultRequestedVerts; |
| 365 // ignore return, no point in flushing again. |
| 366 fDrawTarget->geometryHints(&fMaxVertices, NULL); |
| 367 |
| 368 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); |
| 369 if (fMaxVertices < kMinRequestedVerts) { |
| 370 fMaxVertices = kDefaultRequestedVerts; |
| 371 } else if (fMaxVertices > maxQuadVertices) { |
| 372 // don't exceed the limit of the index buffer |
| 373 fMaxVertices = maxQuadVertices; |
| 374 } |
| 375 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, |
| 376 0, |
| 377 &fVertices, |
| 378 NULL); |
| 379 GrAlwaysAssert(success); |
| 380 } |
| 381 |
| 324 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); | 382 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); |
| 325 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); | 383 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); |
| 326 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn
set); | 384 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn
set); |
| 327 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField
Inset); | 385 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField
Inset); |
| 328 | 386 |
| 329 SkScalar scale = fTextRatio; | 387 SkScalar scale = fTextRatio; |
| 330 dx *= scale; | 388 dx *= scale; |
| 331 dy *= scale; | 389 dy *= scale; |
| 332 sx += dx; | 390 sx += dx; |
| 333 sy += dy; | 391 sy += dy; |
| 334 width *= scale; | 392 width *= scale; |
| 335 height *= scale; | 393 height *= scale; |
| 336 | 394 |
| 337 SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset); | 395 SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset); |
| 338 SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset); | 396 SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset); |
| 339 SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset); | 397 SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset); |
| 340 SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset)
; | 398 SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset)
; |
| 341 | 399 |
| 342 SkRect r; | 400 SkRect r; |
| 343 r.fLeft = SkFixedToFloat(sx); | 401 r.fLeft = sx; |
| 344 r.fTop = SkFixedToFloat(sy); | 402 r.fTop = sy; |
| 345 r.fRight = SkFixedToFloat(sx + width); | 403 r.fRight = sx + width; |
| 346 r.fBottom = SkFixedToFloat(sy + height); | 404 r.fBottom = sy + height; |
| 347 | 405 |
| 348 fVertexBounds.growToInclude(r); | 406 fVertexBounds.growToInclude(r); |
| 349 | 407 |
| 350 size_t vertSize = fUseLCDText ? (2 * sizeof(SkPoint)) | 408 size_t vertSize = fUseLCDText ? (2 * sizeof(SkPoint)) |
| 351 : (2 * sizeof(SkPoint) + sizeof(GrColor)); | 409 : (2 * sizeof(SkPoint) + sizeof(GrColor)); |
| 352 | 410 |
| 353 SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexSize()); | 411 SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexSize()); |
| 354 | 412 |
| 355 SkPoint* positions = reinterpret_cast<SkPoint*>( | 413 SkPoint* positions = reinterpret_cast<SkPoint*>( |
| 356 reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex); | 414 reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex); |
| 357 positions->setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom, vertSize); | 415 positions->setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom, vertSize); |
| 358 | 416 |
| 359 // The texture coords are last in both the with and without color vertex lay
outs. | 417 // The texture coords are last in both the with and without color vertex lay
outs. |
| 360 SkPoint* textureCoords = reinterpret_cast<SkPoint*>( | 418 SkPoint* textureCoords = reinterpret_cast<SkPoint*>( |
| 361 reinterpret_cast<intptr_t>(positions) + vertSize - sizeof(SkPoint))
; | 419 reinterpret_cast<intptr_t>(positions) + vertSize - sizeof(SkPoint))
; |
| 362 textureCoords->setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)), | 420 textureCoords->setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)), |
| 363 SkFixedToFloat(texture->normalizeFixedY(ty)), | 421 SkFixedToFloat(texture->normalizeFixedY(ty)), |
| 364 SkFixedToFloat(texture->normalizeFixedX(tx + tw)), | 422 SkFixedToFloat(texture->normalizeFixedX(tx + tw)), |
| 365 SkFixedToFloat(texture->normalizeFixedY(ty + th)), | 423 SkFixedToFloat(texture->normalizeFixedY(ty + th)), |
| 366 vertSize); | 424 vertSize); |
| 367 if (!fUseLCDText) { | 425 if (useColorVerts) { |
| 368 // color comes after position. | 426 // color comes after position. |
| 369 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); | 427 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); |
| 370 for (int i = 0; i < 4; ++i) { | 428 for (int i = 0; i < 4; ++i) { |
| 371 *colors = fPaint.getColor(); | 429 *colors = fPaint.getColor(); |
| 372 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(color
s) + vertSize); | 430 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(color
s) + vertSize); |
| 373 } | 431 } |
| 374 } | 432 } |
| 375 | 433 |
| 376 fCurrVertex += 4; | 434 fCurrVertex += 4; |
| 377 } | 435 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 SkASSERT(byteLength == 0 || text != NULL); | 515 SkASSERT(byteLength == 0 || text != NULL); |
| 458 | 516 |
| 459 // nothing to draw or can't draw | 517 // nothing to draw or can't draw |
| 460 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ | 518 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ |
| 461 || fSkPaint.getRasterizer()) { | 519 || fSkPaint.getRasterizer()) { |
| 462 return; | 520 return; |
| 463 } | 521 } |
| 464 | 522 |
| 465 this->init(paint, skPaint); | 523 this->init(paint, skPaint); |
| 466 | 524 |
| 467 if (NULL == fDrawTarget) { | |
| 468 return; | |
| 469 } | |
| 470 | |
| 471 SkScalar sizeRatio = fTextRatio; | 525 SkScalar sizeRatio = fTextRatio; |
| 472 | 526 |
| 473 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 527 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
| 474 | 528 |
| 475 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); | 529 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); |
| 476 SkGlyphCache* cache = autoCache.getCache(); | 530 SkGlyphCache* cache = autoCache.getCache(); |
| 477 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 531 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 478 if (NULL == fStrike) { | |
| 479 fStrike = fContext->getFontCache()->getStrike(fontScaler, true); | |
| 480 } | |
| 481 | 532 |
| 482 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); | 533 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); |
| 483 | 534 |
| 484 // allocate vertices | |
| 485 SkASSERT(NULL == fVertices); | |
| 486 if (!fUseLCDText) { | |
| 487 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>( | |
| 488 SK_ARRAY_COUNT(gTextVerte
xWithColorAttribs)); | |
| 489 } else { | |
| 490 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( | |
| 491 SK_ARRAY_COUNT(gTextVerte
xAttribs)); | |
| 492 } | |
| 493 int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); | |
| 494 bool success = fDrawTarget->reserveVertexAndIndexSpace(4*numGlyphs, | |
| 495 0, | |
| 496 &fVertices, | |
| 497 NULL); | |
| 498 GrAlwaysAssert(success); | |
| 499 | |
| 500 // need to measure first | 535 // need to measure first |
| 501 // TODO - generate positions and pre-load cache as well? | 536 // TODO - generate positions and pre-load cache as well? |
| 502 const char* stop = text + byteLength; | 537 const char* stop = text + byteLength; |
| 503 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { | 538 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { |
| 504 SkFixed stopX = 0; | 539 SkFixed stopX = 0; |
| 505 SkFixed stopY = 0; | 540 SkFixed stopY = 0; |
| 506 | 541 |
| 507 const char* textPtr = text; | 542 const char* textPtr = text; |
| 508 while (textPtr < stop) { | 543 while (textPtr < stop) { |
| 509 // don't need x, y here, since all subpixel variants will have the | 544 // don't need x, y here, since all subpixel variants will have the |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 SkASSERT(byteLength == 0 || text != NULL); | 592 SkASSERT(byteLength == 0 || text != NULL); |
| 558 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 593 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
| 559 | 594 |
| 560 // nothing to draw | 595 // nothing to draw |
| 561 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/)
{ | 596 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/)
{ |
| 562 return; | 597 return; |
| 563 } | 598 } |
| 564 | 599 |
| 565 this->init(paint, skPaint); | 600 this->init(paint, skPaint); |
| 566 | 601 |
| 567 if (NULL == fDrawTarget) { | |
| 568 return; | |
| 569 } | |
| 570 | |
| 571 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 602 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
| 572 | 603 |
| 573 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); | 604 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); |
| 574 SkGlyphCache* cache = autoCache.getCache(); | 605 SkGlyphCache* cache = autoCache.getCache(); |
| 575 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 606 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 576 if (NULL == fStrike) { | |
| 577 fStrike = fContext->getFontCache()->getStrike(fontScaler, true); | |
| 578 } | |
| 579 | |
| 580 // allocate vertices | |
| 581 SkASSERT(NULL == fVertices); | |
| 582 if (!fUseLCDText) { | |
| 583 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>( | |
| 584 SK_ARRAY_COUNT(gTextVerte
xWithColorAttribs)); | |
| 585 } else { | |
| 586 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( | |
| 587 SK_ARRAY_COUNT(gTextVerte
xAttribs)); | |
| 588 } | |
| 589 int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); | |
| 590 bool success = fDrawTarget->reserveVertexAndIndexSpace(4*numGlyphs, | |
| 591 0, | |
| 592 &fVertices, | |
| 593 NULL); | |
| 594 GrAlwaysAssert(success); | |
| 595 | 607 |
| 596 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); | 608 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); |
| 597 | 609 |
| 598 const char* stop = text + byteLength; | 610 const char* stop = text + byteLength; |
| 599 | 611 |
| 600 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { | 612 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { |
| 601 while (text < stop) { | 613 while (text < stop) { |
| 602 // the last 2 parameters are ignored | 614 // the last 2 parameters are ignored |
| 603 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 615 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
| 604 | 616 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 631 SkScalarToFixed(x) - (glyph.fAdvanceX >> a
lignShift), | 643 SkScalarToFixed(x) - (glyph.fAdvanceX >> a
lignShift), |
| 632 SkScalarToFixed(y) - (glyph.fAdvanceY >> a
lignShift), | 644 SkScalarToFixed(y) - (glyph.fAdvanceY >> a
lignShift), |
| 633 fontScaler); | 645 fontScaler); |
| 634 } | 646 } |
| 635 pos += scalarsPerPosition; | 647 pos += scalarsPerPosition; |
| 636 } | 648 } |
| 637 } | 649 } |
| 638 | 650 |
| 639 this->finish(); | 651 this->finish(); |
| 640 } | 652 } |
| OLD | NEW |