| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 {kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kEffect_GrVe
rtexAttribBinding} | 53 {kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kEffect_GrVe
rtexAttribBinding} |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 static const size_t kTextVAColorSize = 2 * sizeof(SkPoint) + sizeof(GrColor); | 56 static const size_t kTextVAColorSize = 2 * sizeof(SkPoint) + sizeof(GrColor); |
| 57 | 57 |
| 58 }; | 58 }; |
| 59 | 59 |
| 60 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, | 60 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, |
| 61 const SkDeviceProperties&
properties, | 61 const SkDeviceProperties&
properties, |
| 62 bool enable) | 62 bool enable) |
| 63 : GrTextContext(context, pro
perties) { | 63 : GrTextContext(context, pro
perties) |
| 64 , fStrike(NULL) |
| 64 #if SK_FORCE_DISTANCEFIELD_FONTS | 65 #if SK_FORCE_DISTANCEFIELD_FONTS |
| 65 fEnableDFRendering = true; | 66 , fEnableDFRendering(true) |
| 66 #else | 67 #else |
| 67 fEnableDFRendering = enable; | 68 , fEnableDFRendering(enable) |
| 68 #endif | 69 #endif |
| 69 fStrike = NULL; | 70 , fEffectTextureUniqueID(SK_
InvalidUniqueID) |
| 70 fGammaTexture = NULL; | 71 , fEffectColor(GrColor_ILLEG
AL) |
| 71 | 72 , fEffectFlags(0) |
| 72 fCurrTexture = NULL; | 73 , fGammaTexture(NULL) |
| 73 fCurrVertex = 0; | 74 , fVertices(NULL) |
| 74 fEffectTextureUniqueID = SK_InvalidUniqueID; | 75 , fVertexCount(0) |
| 75 fEffectColor = GrColor_ILLEGAL; | 76 , fCurrVertex(0) { |
| 76 fEffectFlags = 0; | |
| 77 | |
| 78 fVertices = NULL; | |
| 79 fMaxVertices = 0; | |
| 80 | |
| 81 fVertexBounds.setLargestInverted(); | 77 fVertexBounds.setLargestInverted(); |
| 82 } | 78 } |
| 83 | 79 |
| 84 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { | 80 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { |
| 85 this->flushGlyphs(); | 81 this->flushGlyphs(); |
| 86 SkSafeSetNull(fGammaTexture); | 82 SkSafeSetNull(fGammaTexture); |
| 87 } | 83 } |
| 88 | 84 |
| 89 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { | 85 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { |
| 90 if (!fEnableDFRendering && !paint.isDistanceFieldTextTEMP()) { | 86 if (!fEnableDFRendering && !paint.isDistanceFieldTextTEMP()) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 119 unsigned r = SkColorGetR(c); | 115 unsigned r = SkColorGetR(c); |
| 120 unsigned g = SkColorGetG(c); | 116 unsigned g = SkColorGetG(c); |
| 121 unsigned b = SkColorGetB(c); | 117 unsigned b = SkColorGetB(c); |
| 122 return GrColorPackRGBA(r, g, b, 0xff); | 118 return GrColorPackRGBA(r, g, b, 0xff); |
| 123 } | 119 } |
| 124 | 120 |
| 125 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
r) { | 121 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
r) { |
| 126 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_
FilterMode); | 122 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_
FilterMode); |
| 127 GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNon
e_FilterMode); | 123 GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNon
e_FilterMode); |
| 128 | 124 |
| 129 uint32_t textureUniqueID = fCurrTexture->getUniqueID(); | 125 GrTexture* currTexture = fStrike->getTexture(); |
| 126 SkASSERT(currTexture); |
| 127 uint32_t textureUniqueID = currTexture->getUniqueID(); |
| 130 | 128 |
| 131 // set up any flags | 129 // set up any flags |
| 132 uint32_t flags = 0; | 130 uint32_t flags = 0; |
| 133 flags |= fContext->getMatrix().isSimilarity() ? kSimilarity_DistanceFieldEff
ectFlag : 0; | 131 flags |= fContext->getMatrix().isSimilarity() ? kSimilarity_DistanceFieldEff
ectFlag : 0; |
| 134 flags |= fUseLCDText ? kUseLCD_DistanceFieldEffectFlag : 0; | 132 flags |= fUseLCDText ? kUseLCD_DistanceFieldEffectFlag : 0; |
| 135 flags |= fUseLCDText && fContext->getMatrix().rectStaysRect() ? | 133 flags |= fUseLCDText && fContext->getMatrix().rectStaysRect() ? |
| 136 kRectToRect_DistanceFieldEffectFlag : 0; | 134 kRectToRect_DistanceFieldEffectFlag : 0; |
| 137 bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout == | 135 bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout == |
| 138 fDeviceProperties.fGeometry.getLayout(); | 136 fDeviceProperties.fGeometry.getLayout(); |
| 139 flags |= fUseLCDText && useBGR ? kBGR_DistanceFieldEffectFlag : 0; | 137 flags |= fUseLCDText && useBGR ? kBGR_DistanceFieldEffectFlag : 0; |
| 140 | 138 |
| 141 // see if we need to create a new effect | 139 // see if we need to create a new effect |
| 142 if (textureUniqueID != fEffectTextureUniqueID || | 140 if (textureUniqueID != fEffectTextureUniqueID || |
| 143 filteredColor != fEffectColor || | 141 filteredColor != fEffectColor || |
| 144 flags != fEffectFlags) { | 142 flags != fEffectFlags) { |
| 145 if (fUseLCDText) { | 143 if (fUseLCDText) { |
| 146 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredCol
or); | 144 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredCol
or); |
| 147 fCachedEffect.reset(GrDistanceFieldLCDTextureEffect::Create(fCurrTex
ture, | 145 fCachedEffect.reset(GrDistanceFieldLCDTextureEffect::Create(currText
ure, |
| 148 params, | 146 params, |
| 149 fGammaTe
xture, | 147 fGammaTe
xture, |
| 150 gammaPar
ams, | 148 gammaPar
ams, |
| 151 colorNoP
reMul, | 149 colorNoP
reMul, |
| 152 flags)); | 150 flags)); |
| 153 } else { | 151 } else { |
| 154 #ifdef SK_GAMMA_APPLY_TO_A8 | 152 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 155 U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDevicePropertie
s.fGamma, | 153 U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDevicePropertie
s.fGamma, |
| 156 filteredColor); | 154 filteredColor); |
| 157 fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(fCurrTextur
e, | 155 fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(currTexture
, |
| 158 params, | 156 params, |
| 159 fGammaTextu
re, | 157 fGammaTextu
re, |
| 160 gammaParams
, | 158 gammaParams
, |
| 161 lum/255.f, | 159 lum/255.f, |
| 162 flags)); | 160 flags)); |
| 163 #else | 161 #else |
| 164 fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(fCurrTextur
e, | 162 fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(currTexture
, |
| 165 params, fla
gs)); | 163 params, fla
gs)); |
| 166 #endif | 164 #endif |
| 167 } | 165 } |
| 168 fEffectTextureUniqueID = textureUniqueID; | 166 fEffectTextureUniqueID = textureUniqueID; |
| 169 fEffectColor = filteredColor; | 167 fEffectColor = filteredColor; |
| 170 fEffectFlags = flags; | 168 fEffectFlags = flags; |
| 171 } | 169 } |
| 172 | 170 |
| 173 } | 171 } |
| 174 | 172 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 // set back to normal in case we took LCD path previously. | 221 // set back to normal in case we took LCD path previously. |
| 224 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen
dCoeff()); | 222 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen
dCoeff()); |
| 225 // We're using per-vertex color. | 223 // We're using per-vertex color. |
| 226 SkASSERT(drawState->hasColorVertexAttribute()); | 224 SkASSERT(drawState->hasColorVertexAttribute()); |
| 227 } | 225 } |
| 228 int nGlyphs = fCurrVertex / 4; | 226 int nGlyphs = fCurrVertex / 4; |
| 229 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); | 227 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); |
| 230 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, | 228 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, |
| 231 nGlyphs, | 229 nGlyphs, |
| 232 4, 6, &fVertexBounds); | 230 4, 6, &fVertexBounds); |
| 233 fDrawTarget->resetVertexSource(); | |
| 234 fVertices = NULL; | |
| 235 fMaxVertices = 0; | |
| 236 fCurrVertex = 0; | 231 fCurrVertex = 0; |
| 237 SkSafeSetNull(fCurrTexture); | |
| 238 fVertexBounds.setLargestInverted(); | 232 fVertexBounds.setLargestInverted(); |
| 239 } | 233 } |
| 234 |
| 235 fDrawTarget->resetVertexSource(); |
| 236 fVertices = NULL; |
| 240 } | 237 } |
| 241 | 238 |
| 242 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, | 239 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, |
| 243 SkFixed vx, SkFixed vy, | 240 SkFixed vx, SkFixed vy, |
| 244 GrFontScaler* scaler) { | 241 GrFontScaler* scaler) { |
| 245 if (NULL == fDrawTarget) { | |
| 246 return; | |
| 247 } | |
| 248 | |
| 249 if (NULL == fStrike) { | |
| 250 fStrike = fContext->getFontCache()->getStrike(scaler, true); | |
| 251 } | |
| 252 | |
| 253 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); | 242 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
| 254 if (NULL == glyph || glyph->fBounds.isEmpty()) { | 243 if (NULL == glyph || glyph->fBounds.isEmpty()) { |
| 255 return; | 244 return; |
| 256 } | 245 } |
| 257 | 246 |
| 258 SkScalar sx = SkFixedToScalar(vx); | 247 SkScalar sx = SkFixedToScalar(vx); |
| 259 SkScalar sy = SkFixedToScalar(vy); | 248 SkScalar sy = SkFixedToScalar(vy); |
| 260 /* | 249 /* |
| 261 // not valid, need to find a different solution for this | 250 // not valid, need to find a different solution for this |
| 262 vx += SkIntToFixed(glyph->fBounds.fLeft); | 251 vx += SkIntToFixed(glyph->fBounds.fLeft); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 286 fStrike->addGlyphToAtlas(glyph, scaler)) { | 275 fStrike->addGlyphToAtlas(glyph, scaler)) { |
| 287 goto HAS_ATLAS; | 276 goto HAS_ATLAS; |
| 288 } | 277 } |
| 289 | 278 |
| 290 if (c_DumpFontCache) { | 279 if (c_DumpFontCache) { |
| 291 #ifdef SK_DEVELOPER | 280 #ifdef SK_DEVELOPER |
| 292 fContext->getFontCache()->dump(); | 281 fContext->getFontCache()->dump(); |
| 293 #endif | 282 #endif |
| 294 } | 283 } |
| 295 | 284 |
| 296 // before we purge the cache, we must flush any accumulated draws | 285 // flush any accumulated draws to allow us to free up a plot |
| 286 int remainingVertexCount = fVertexCount - fCurrVertex; |
| 297 this->flushGlyphs(); | 287 this->flushGlyphs(); |
| 298 fContext->flush(); | 288 fContext->flush(); |
| 299 | 289 |
| 290 // need to reallocate the vertex buffer for the remaining glyphs |
| 291 fVertexCount = remainingVertexCount; |
| 292 bool success = fDrawTarget->reserveVertexAndIndexSpace(fVertexCount, |
| 293 0, |
| 294 &fVertices, |
| 295 NULL); |
| 296 GrAlwaysAssert(success); |
| 297 |
| 300 // we should have an unused plot now | 298 // we should have an unused plot now |
| 301 if (fContext->getFontCache()->freeUnusedPlot(fStrike) && | 299 if (fContext->getFontCache()->freeUnusedPlot(fStrike) && |
| 302 fStrike->addGlyphToAtlas(glyph, scaler)) { | 300 fStrike->addGlyphToAtlas(glyph, scaler)) { |
| 303 goto HAS_ATLAS; | 301 goto HAS_ATLAS; |
| 304 } | 302 } |
| 305 | 303 |
| 306 if (NULL == glyph->fPath) { | 304 if (NULL == glyph->fPath) { |
| 307 SkPath* path = SkNEW(SkPath); | 305 SkPath* path = SkNEW(SkPath); |
| 308 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { | 306 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { |
| 309 // flag the glyph as being dead? | 307 // flag the glyph as being dead? |
| (...skipping 15 matching lines...) Expand all Loading... |
| 325 } | 323 } |
| 326 | 324 |
| 327 HAS_ATLAS: | 325 HAS_ATLAS: |
| 328 SkASSERT(glyph->fPlot); | 326 SkASSERT(glyph->fPlot); |
| 329 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); | 327 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); |
| 330 glyph->fPlot->setDrawToken(drawToken); | 328 glyph->fPlot->setDrawToken(drawToken); |
| 331 | 329 |
| 332 GrTexture* texture = glyph->fPlot->texture(); | 330 GrTexture* texture = glyph->fPlot->texture(); |
| 333 SkASSERT(texture); | 331 SkASSERT(texture); |
| 334 | 332 |
| 335 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { | |
| 336 this->flushGlyphs(); | |
| 337 fCurrTexture = texture; | |
| 338 fCurrTexture->ref(); | |
| 339 } | |
| 340 | |
| 341 bool useColorVerts = !fUseLCDText; | |
| 342 | |
| 343 if (NULL == fVertices) { | |
| 344 // If we need to reserve vertices allow the draw target to suggest | |
| 345 // a number of verts to reserve and whether to perform a flush. | |
| 346 fMaxVertices = kMinRequestedVerts; | |
| 347 if (useColorVerts) { | |
| 348 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttri
bs>( | |
| 349 SK_ARRAY_COUNT(gTextVertexWi
thColorAttribs), | |
| 350 kTextVAColorSize); | |
| 351 } else { | |
| 352 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( | |
| 353 SK_ARRAY_COUNT(gTextVertexAt
tribs), | |
| 354 kTextVASize); | |
| 355 } | |
| 356 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); | |
| 357 if (flush) { | |
| 358 this->flushGlyphs(); | |
| 359 fContext->flush(); | |
| 360 if (useColorVerts) { | |
| 361 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorA
ttribs>( | |
| 362 SK_ARRAY_COUNT(gTextVertexWi
thColorAttribs), | |
| 363 kTextVAColorSize); | |
| 364 } else { | |
| 365 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( | |
| 366 SK_ARRAY_COUNT(gTextVertexAt
tribs), | |
| 367 kTextVASize); | |
| 368 } | |
| 369 } | |
| 370 fMaxVertices = kDefaultRequestedVerts; | |
| 371 // ignore return, no point in flushing again. | |
| 372 fDrawTarget->geometryHints(&fMaxVertices, NULL); | |
| 373 | |
| 374 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); | |
| 375 if (fMaxVertices < kMinRequestedVerts) { | |
| 376 fMaxVertices = kDefaultRequestedVerts; | |
| 377 } else if (fMaxVertices > maxQuadVertices) { | |
| 378 // don't exceed the limit of the index buffer | |
| 379 fMaxVertices = maxQuadVertices; | |
| 380 } | |
| 381 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, | |
| 382 0, | |
| 383 &fVertices, | |
| 384 NULL); | |
| 385 GrAlwaysAssert(success); | |
| 386 } | |
| 387 | |
| 388 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); | 333 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); |
| 389 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); | 334 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); |
| 390 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn
set); | 335 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn
set); |
| 391 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField
Inset); | 336 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField
Inset); |
| 392 | 337 |
| 393 SkScalar scale = fTextRatio; | 338 SkScalar scale = fTextRatio; |
| 394 dx *= scale; | 339 dx *= scale; |
| 395 dy *= scale; | 340 dy *= scale; |
| 396 sx += dx; | 341 sx += dx; |
| 397 sy += dy; | 342 sy += dy; |
| 398 width *= scale; | 343 width *= scale; |
| 399 height *= scale; | 344 height *= scale; |
| 400 | 345 |
| 401 SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset); | 346 SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset); |
| 402 SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset); | 347 SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset); |
| 403 SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset); | 348 SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset); |
| 404 SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset)
; | 349 SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset)
; |
| 405 | 350 |
| 406 SkRect r; | 351 SkRect r; |
| 407 r.fLeft = sx; | 352 r.fLeft = sx; |
| 408 r.fTop = sy; | 353 r.fTop = sy; |
| 409 r.fRight = sx + width; | 354 r.fRight = sx + width; |
| 410 r.fBottom = sy + height; | 355 r.fBottom = sy + height; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 421 positions->setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom, vertSize); | 366 positions->setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom, vertSize); |
| 422 | 367 |
| 423 // The texture coords are last in both the with and without color vertex lay
outs. | 368 // The texture coords are last in both the with and without color vertex lay
outs. |
| 424 SkPoint* textureCoords = reinterpret_cast<SkPoint*>( | 369 SkPoint* textureCoords = reinterpret_cast<SkPoint*>( |
| 425 reinterpret_cast<intptr_t>(positions) + vertSize - sizeof(SkPoint))
; | 370 reinterpret_cast<intptr_t>(positions) + vertSize - sizeof(SkPoint))
; |
| 426 textureCoords->setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)), | 371 textureCoords->setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)), |
| 427 SkFixedToFloat(texture->normalizeFixedY(ty)), | 372 SkFixedToFloat(texture->normalizeFixedY(ty)), |
| 428 SkFixedToFloat(texture->normalizeFixedX(tx + tw)), | 373 SkFixedToFloat(texture->normalizeFixedX(tx + tw)), |
| 429 SkFixedToFloat(texture->normalizeFixedY(ty + th)), | 374 SkFixedToFloat(texture->normalizeFixedY(ty + th)), |
| 430 vertSize); | 375 vertSize); |
| 431 if (useColorVerts) { | 376 if (!fUseLCDText) { |
| 432 if (0xFF == GrColorUnpackA(fPaint.getColor())) { | 377 if (0xFF == GrColorUnpackA(fPaint.getColor())) { |
| 433 fDrawTarget->drawState()->setHint(GrDrawState::kVertexColorsAreOpaqu
e_Hint, true); | 378 fDrawTarget->drawState()->setHint(GrDrawState::kVertexColorsAreOpaqu
e_Hint, true); |
| 434 } | 379 } |
| 435 // color comes after position. | 380 // color comes after position. |
| 436 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); | 381 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); |
| 437 for (int i = 0; i < 4; ++i) { | 382 for (int i = 0; i < 4; ++i) { |
| 438 *colors = fPaint.getColor(); | 383 *colors = fPaint.getColor(); |
| 439 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(color
s) + vertSize); | 384 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(color
s) + vertSize); |
| 440 } | 385 } |
| 441 } | 386 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 return; | 456 return; |
| 512 } | 457 } |
| 513 | 458 |
| 514 context->writeTexturePixels(*gammaTexture, | 459 context->writeTexturePixels(*gammaTexture, |
| 515 0, 0, width, height, | 460 0, 0, width, height, |
| 516 (*gammaTexture)->config(), data.get(), 0, | 461 (*gammaTexture)->config(), data.get(), 0, |
| 517 GrContext::kDontFlush_PixelOpsFlag); | 462 GrContext::kDontFlush_PixelOpsFlag); |
| 518 } | 463 } |
| 519 } | 464 } |
| 520 | 465 |
| 466 void GrDistanceFieldTextContext::allocateVertices(const char text[], size_t byte
Length) { |
| 467 SkASSERT(NULL == fVertices); |
| 468 if (!fUseLCDText) { |
| 469 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>( |
| 470 SK_ARRAY_COUNT(gTextVertexWi
thColorAttribs), |
| 471 kTextVAColorSize); |
| 472 } else { |
| 473 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
| 474 SK_ARRAY_COUNT(gTextVertexAt
tribs), |
| 475 kTextVASize); |
| 476 } |
| 477 fVertexCount = 4*fSkPaint.textToGlyphs(text, byteLength, NULL); |
| 478 bool success = fDrawTarget->reserveVertexAndIndexSpace(fVertexCount, |
| 479 0, |
| 480 &fVertices, |
| 481 NULL); |
| 482 GrAlwaysAssert(success); |
| 483 } |
| 484 |
| 521 void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& s
kPaint, | 485 void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& s
kPaint, |
| 522 const char text[], size_t byteLength, | 486 const char text[], size_t byteLength, |
| 523 SkScalar x, SkScalar y) { | 487 SkScalar x, SkScalar y) { |
| 524 SkASSERT(byteLength == 0 || text != NULL); | 488 SkASSERT(byteLength == 0 || text != NULL); |
| 525 | 489 |
| 526 // nothing to draw or can't draw | 490 // nothing to draw or can't draw |
| 527 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ | 491 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ |
| 528 || fSkPaint.getRasterizer()) { | 492 || fSkPaint.getRasterizer()) { |
| 529 return; | 493 return; |
| 530 } | 494 } |
| 531 | 495 |
| 532 this->init(paint, skPaint); | 496 this->init(paint, skPaint); |
| 533 | 497 |
| 498 if (NULL == fDrawTarget) { |
| 499 return; |
| 500 } |
| 501 |
| 534 SkScalar sizeRatio = fTextRatio; | 502 SkScalar sizeRatio = fTextRatio; |
| 535 | 503 |
| 536 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 504 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
| 537 | 505 |
| 538 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); | 506 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); |
| 539 SkGlyphCache* cache = autoCache.getCache(); | 507 SkGlyphCache* cache = autoCache.getCache(); |
| 540 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 508 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 509 if (NULL == fStrike) { |
| 510 fStrike = fContext->getFontCache()->getStrike(fontScaler, true); |
| 511 } |
| 541 | 512 |
| 542 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); | 513 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); |
| 543 | 514 |
| 515 this->allocateVertices(text, byteLength); |
| 516 |
| 544 // need to measure first | 517 // need to measure first |
| 545 // TODO - generate positions and pre-load cache as well? | 518 // TODO - generate positions and pre-load cache as well? |
| 546 const char* stop = text + byteLength; | 519 const char* stop = text + byteLength; |
| 547 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { | 520 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { |
| 548 SkFixed stopX = 0; | 521 SkFixed stopX = 0; |
| 549 SkFixed stopY = 0; | 522 SkFixed stopY = 0; |
| 550 | 523 |
| 551 const char* textPtr = text; | 524 const char* textPtr = text; |
| 552 while (textPtr < stop) { | 525 while (textPtr < stop) { |
| 553 // don't need x, y here, since all subpixel variants will have the | 526 // 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... |
| 601 SkASSERT(byteLength == 0 || text != NULL); | 574 SkASSERT(byteLength == 0 || text != NULL); |
| 602 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 575 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
| 603 | 576 |
| 604 // nothing to draw | 577 // nothing to draw |
| 605 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/)
{ | 578 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/)
{ |
| 606 return; | 579 return; |
| 607 } | 580 } |
| 608 | 581 |
| 609 this->init(paint, skPaint); | 582 this->init(paint, skPaint); |
| 610 | 583 |
| 584 if (NULL == fDrawTarget) { |
| 585 return; |
| 586 } |
| 587 |
| 611 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 588 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
| 612 | 589 |
| 613 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); | 590 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); |
| 614 SkGlyphCache* cache = autoCache.getCache(); | 591 SkGlyphCache* cache = autoCache.getCache(); |
| 615 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 592 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 593 if (NULL == fStrike) { |
| 594 fStrike = fContext->getFontCache()->getStrike(fontScaler, true); |
| 595 } |
| 616 | 596 |
| 617 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); | 597 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); |
| 618 | 598 |
| 599 this->allocateVertices(text, byteLength); |
| 600 |
| 619 const char* stop = text + byteLength; | 601 const char* stop = text + byteLength; |
| 620 | 602 |
| 621 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { | 603 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { |
| 622 while (text < stop) { | 604 while (text < stop) { |
| 623 // the last 2 parameters are ignored | 605 // the last 2 parameters are ignored |
| 624 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 606 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
| 625 | 607 |
| 626 if (glyph.fWidth) { | 608 if (glyph.fWidth) { |
| 627 SkScalar x = pos[0]; | 609 SkScalar x = pos[0]; |
| 628 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1]; | 610 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1]; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 652 SkScalarToFixed(x) - (glyph.fAdvanceX >> a
lignShift), | 634 SkScalarToFixed(x) - (glyph.fAdvanceX >> a
lignShift), |
| 653 SkScalarToFixed(y) - (glyph.fAdvanceY >> a
lignShift), | 635 SkScalarToFixed(y) - (glyph.fAdvanceY >> a
lignShift), |
| 654 fontScaler); | 636 fontScaler); |
| 655 } | 637 } |
| 656 pos += scalarsPerPosition; | 638 pos += scalarsPerPosition; |
| 657 } | 639 } |
| 658 } | 640 } |
| 659 | 641 |
| 660 this->finish(); | 642 this->finish(); |
| 661 } | 643 } |
| OLD | NEW |