| 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 30 matching lines...) Expand all Loading... |
| 41 bool enable) | 41 bool enable) |
| 42 : GrTextContext(context, pro
perties) { | 42 : GrTextContext(context, pro
perties) { |
| 43 #if SK_FORCE_DISTANCEFIELD_FONTS | 43 #if SK_FORCE_DISTANCEFIELD_FONTS |
| 44 fEnableDFRendering = true; | 44 fEnableDFRendering = true; |
| 45 #else | 45 #else |
| 46 fEnableDFRendering = enable; | 46 fEnableDFRendering = enable; |
| 47 #endif | 47 #endif |
| 48 fStrike = NULL; | 48 fStrike = NULL; |
| 49 fGammaTexture = NULL; | 49 fGammaTexture = NULL; |
| 50 | 50 |
| 51 fCurrTexture = NULL; | |
| 52 fCurrVertex = 0; | 51 fCurrVertex = 0; |
| 53 | 52 |
| 54 fVertices = NULL; | 53 fVertices = NULL; |
| 55 fMaxVertices = 0; | |
| 56 } | 54 } |
| 57 | 55 |
| 58 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { | 56 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { |
| 59 this->flushGlyphs(); | 57 this->flushGlyphs(); |
| 60 SkSafeSetNull(fGammaTexture); | 58 SkSafeSetNull(fGammaTexture); |
| 61 } | 59 } |
| 62 | 60 |
| 63 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { | 61 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { |
| 64 if (!fEnableDFRendering && !paint.isDistanceFieldTextTEMP()) { | 62 if (!fEnableDFRendering && !paint.isDistanceFieldTextTEMP()) { |
| 65 return false; | 63 return false; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 return; | 99 return; |
| 102 } | 100 } |
| 103 | 101 |
| 104 GrDrawState* drawState = fDrawTarget->drawState(); | 102 GrDrawState* drawState = fDrawTarget->drawState(); |
| 105 GrDrawState::AutoRestoreEffects are(drawState); | 103 GrDrawState::AutoRestoreEffects are(drawState); |
| 106 drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTa
rget()); | 104 drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTa
rget()); |
| 107 | 105 |
| 108 if (fCurrVertex > 0) { | 106 if (fCurrVertex > 0) { |
| 109 // setup our sampler state for our text texture/atlas | 107 // setup our sampler state for our text texture/atlas |
| 110 SkASSERT(SkIsAlign4(fCurrVertex)); | 108 SkASSERT(SkIsAlign4(fCurrVertex)); |
| 111 SkASSERT(fCurrTexture); | 109 GrTexture* currTexture = fStrike->getTexture(); |
| 110 SkASSERT(currTexture); |
| 112 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil
erp_FilterMode); | 111 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil
erp_FilterMode); |
| 113 GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::
kNone_FilterMode); | 112 GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::
kNone_FilterMode); |
| 114 | 113 |
| 115 // Effects could be stored with one of the cache objects (atlas?) | 114 // Effects could be stored with one of the cache objects (atlas?) |
| 116 SkColor filteredColor; | 115 SkColor filteredColor; |
| 117 SkColorFilter* colorFilter = fSkPaint.getColorFilter(); | 116 SkColorFilter* colorFilter = fSkPaint.getColorFilter(); |
| 118 if (NULL != colorFilter) { | 117 if (NULL != colorFilter) { |
| 119 filteredColor = colorFilter->filterColor(fSkPaint.getColor()); | 118 filteredColor = colorFilter->filterColor(fSkPaint.getColor()); |
| 120 } else { | 119 } else { |
| 121 filteredColor = fSkPaint.getColor(); | 120 filteredColor = fSkPaint.getColor(); |
| 122 } | 121 } |
| 123 if (fUseLCDText) { | 122 if (fUseLCDText) { |
| 124 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredCol
or); | 123 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredCol
or); |
| 125 bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout == | 124 bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout == |
| 126 fDeviceProperties.fG
eometry.getLayout(); | 125 fDeviceProperties.fG
eometry.getLayout(); |
| 127 drawState->addCoverageEffect(GrDistanceFieldLCDTextureEffect::Create
( | 126 drawState->addCoverageEffect(GrDistanceFieldLCDTextureEffect::Create
( |
| 128 fCurrTexture, | 127 currTexture, |
| 129 params, | 128 params, |
| 130 fGammaTexture, | 129 fGammaTexture, |
| 131 gammaParams, | 130 gammaParams, |
| 132 colorNoPreMul, | 131 colorNoPreMul, |
| 133 fContext->getMatrix(
).rectStaysRect() && | 132 fContext->getMatrix(
).rectStaysRect() && |
| 134 fContext->getMatrix(
).isSimilarity(), | 133 fContext->getMatrix(
).isSimilarity(), |
| 135 useBGR), | 134 useBGR), |
| 136 kGlyphCoordsAttributeIndex)->unref(); | 135 kGlyphCoordsAttributeIndex)->unref(); |
| 137 | 136 |
| 138 if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() || | 137 if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() || |
| 139 kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() || | 138 kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() || |
| 140 fPaint.numColorStages()) { | 139 fPaint.numColorStages()) { |
| 141 GrPrintf("LCD Text will not draw correctly.\n"); | 140 GrPrintf("LCD Text will not draw correctly.\n"); |
| 142 } | 141 } |
| 143 // We don't use the GrPaint's color in this case because it's been p
remultiplied by | 142 // We don't use the GrPaint's color in this case because it's been p
remultiplied by |
| 144 // alpha. Instead we feed in a non-premultiplied color, and multiply
its alpha by | 143 // alpha. Instead we feed in a non-premultiplied color, and multiply
its alpha by |
| 145 // the mask texture color. The end result is that we get | 144 // the mask texture color. The end result is that we get |
| 146 // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstCo
lor | 145 // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstCo
lor |
| 147 int a = SkColorGetA(fSkPaint.getColor()); | 146 int a = SkColorGetA(fSkPaint.getColor()); |
| 148 // paintAlpha | 147 // paintAlpha |
| 149 drawState->setColor(SkColorSetARGB(a, a, a, a)); | 148 drawState->setColor(SkColorSetARGB(a, a, a, a)); |
| 150 // paintColor | 149 // paintColor |
| 151 drawState->setBlendConstant(colorNoPreMul); | 150 drawState->setBlendConstant(colorNoPreMul); |
| 152 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); | 151 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); |
| 153 } else { | 152 } else { |
| 154 #ifdef SK_GAMMA_APPLY_TO_A8 | 153 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 155 U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDevicePropertie
s.fGamma, | 154 U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDevicePropertie
s.fGamma, |
| 156 filteredColor); | 155 filteredColor); |
| 157 drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create( | 156 drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create( |
| 158 fCurrTexture, para
ms, | 157 currTexture, param
s, |
| 159 fGammaTexture, gam
maParams, | 158 fGammaTexture, gam
maParams, |
| 160 lum/255.f, | 159 lum/255.f, |
| 161 fContext->getMatri
x().isSimilarity()), | 160 fContext->getMatri
x().isSimilarity()), |
| 162 kGlyphCoordsAttributeIndex)->unref(); | 161 kGlyphCoordsAttributeIndex)->unref(); |
| 163 #else | 162 #else |
| 164 drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create( | 163 drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create( |
| 165 fCurrTexture, para
ms, | 164 currTexture, param
s, |
| 166 fContext->getMatri
x().isSimilarity()), | 165 fContext->getMatri
x().isSimilarity()), |
| 167 kGlyphCoordsAttributeIndex)->unref(); | 166 kGlyphCoordsAttributeIndex)->unref(); |
| 168 #endif | 167 #endif |
| 169 // set back to normal in case we took LCD path previously. | 168 // set back to normal in case we took LCD path previously. |
| 170 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen
dCoeff()); | 169 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen
dCoeff()); |
| 171 drawState->setColor(fPaint.getColor()); | 170 drawState->setColor(fPaint.getColor()); |
| 172 } | 171 } |
| 173 | 172 |
| 174 int nGlyphs = fCurrVertex / 4; | 173 int nGlyphs = fCurrVertex / 4; |
| 175 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); | 174 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); |
| 176 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, | 175 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, |
| 177 nGlyphs, | 176 nGlyphs, |
| 178 4, 6); | 177 4, 6); |
| 179 fDrawTarget->resetVertexSource(); | |
| 180 fVertices = NULL; | |
| 181 fMaxVertices = 0; | |
| 182 fCurrVertex = 0; | 178 fCurrVertex = 0; |
| 183 SkSafeSetNull(fCurrTexture); | |
| 184 } | 179 } |
| 180 fDrawTarget->resetVertexSource(); |
| 181 fVertices = NULL; |
| 185 } | 182 } |
| 186 | 183 |
| 187 namespace { | 184 namespace { |
| 188 | 185 |
| 189 // position + texture coord | 186 // position + texture coord |
| 190 extern const GrVertexAttrib gTextVertexAttribs[] = { | 187 extern const GrVertexAttrib gTextVertexAttribs[] = { |
| 191 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, | 188 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, |
| 192 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding} | 189 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding} |
| 193 }; | 190 }; |
| 194 | 191 |
| 195 }; | 192 }; |
| 196 | 193 |
| 197 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, | 194 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, |
| 198 SkFixed vx, SkFixed vy, | 195 SkFixed vx, SkFixed vy, |
| 199 GrFontScaler* scaler) { | 196 GrFontScaler* scaler) { |
| 200 if (NULL == fDrawTarget) { | |
| 201 return; | |
| 202 } | |
| 203 if (NULL == fStrike) { | |
| 204 fStrike = fContext->getFontCache()->getStrike(scaler, true); | |
| 205 } | |
| 206 | |
| 207 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); | 197 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
| 208 if (NULL == glyph || glyph->fBounds.isEmpty()) { | 198 if (NULL == glyph || glyph->fBounds.isEmpty()) { |
| 209 return; | 199 return; |
| 210 } | 200 } |
| 211 | 201 |
| 212 SkScalar sx = SkFixedToScalar(vx); | 202 SkScalar sx = SkFixedToScalar(vx); |
| 213 SkScalar sy = SkFixedToScalar(vy); | 203 SkScalar sy = SkFixedToScalar(vy); |
| 214 /* | 204 /* |
| 215 // not valid, need to find a different solution for this | 205 // not valid, need to find a different solution for this |
| 216 vx += SkIntToFixed(glyph->fBounds.fLeft); | 206 vx += SkIntToFixed(glyph->fBounds.fLeft); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 } | 269 } |
| 280 | 270 |
| 281 HAS_ATLAS: | 271 HAS_ATLAS: |
| 282 SkASSERT(glyph->fPlot); | 272 SkASSERT(glyph->fPlot); |
| 283 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); | 273 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); |
| 284 glyph->fPlot->setDrawToken(drawToken); | 274 glyph->fPlot->setDrawToken(drawToken); |
| 285 | 275 |
| 286 GrTexture* texture = glyph->fPlot->texture(); | 276 GrTexture* texture = glyph->fPlot->texture(); |
| 287 SkASSERT(texture); | 277 SkASSERT(texture); |
| 288 | 278 |
| 289 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { | |
| 290 this->flushGlyphs(); | |
| 291 fCurrTexture = texture; | |
| 292 fCurrTexture->ref(); | |
| 293 } | |
| 294 | |
| 295 if (NULL == fVertices) { | |
| 296 // If we need to reserve vertices allow the draw target to suggest | |
| 297 // a number of verts to reserve and whether to perform a flush. | |
| 298 fMaxVertices = kMinRequestedVerts; | |
| 299 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( | |
| 300 SK_ARRAY_COUNT(gTextVertexAttribs)); | |
| 301 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); | |
| 302 if (flush) { | |
| 303 this->flushGlyphs(); | |
| 304 fContext->flush(); | |
| 305 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( | |
| 306 SK_ARRAY_COUNT(gTextVertexAttribs)); | |
| 307 } | |
| 308 fMaxVertices = kDefaultRequestedVerts; | |
| 309 // ignore return, no point in flushing again. | |
| 310 fDrawTarget->geometryHints(&fMaxVertices, NULL); | |
| 311 | |
| 312 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); | |
| 313 if (fMaxVertices < kMinRequestedVerts) { | |
| 314 fMaxVertices = kDefaultRequestedVerts; | |
| 315 } else if (fMaxVertices > maxQuadVertices) { | |
| 316 // don't exceed the limit of the index buffer | |
| 317 fMaxVertices = maxQuadVertices; | |
| 318 } | |
| 319 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, | |
| 320 0, | |
| 321 GrTCast<void**>(&
fVertices), | |
| 322 NULL); | |
| 323 GrAlwaysAssert(success); | |
| 324 SkASSERT(2*sizeof(SkPoint) == fDrawTarget->getDrawState().getVertexSize(
)); | |
| 325 } | |
| 326 | |
| 327 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); | 279 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); |
| 328 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); | 280 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); |
| 329 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn
set); | 281 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn
set); |
| 330 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField
Inset); | 282 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField
Inset); |
| 331 | 283 |
| 332 SkScalar scale = fTextRatio; | 284 SkScalar scale = fTextRatio; |
| 333 dx *= scale; | 285 dx *= scale; |
| 334 dy *= scale; | 286 dy *= scale; |
| 335 sx += dx; | 287 sx += dx; |
| 336 sy += dy; | 288 sy += dy; |
| 337 width *= scale; | 289 width *= scale; |
| 338 height *= scale; | 290 height *= scale; |
| 339 | 291 |
| 340 SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset); | 292 SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset); |
| 341 SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset); | 293 SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset); |
| 342 SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset); | 294 SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset); |
| 343 SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset)
; | 295 SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset)
; |
| 344 | 296 |
| 345 static const size_t kVertexSize = 2 * sizeof(SkPoint); | 297 static const size_t kVertexSize = 2 * sizeof(SkPoint); |
| 346 fVertices[2*fCurrVertex].setRectFan(sx, | 298 SkPoint* positions = reinterpret_cast<SkPoint*>( |
| 347 sy, | 299 reinterpret_cast<intptr_t>(fVertices) + kVertexS
ize * fCurrVertex); |
| 348 sx + width, | 300 positions->setRectFan(sx, |
| 349 sy + height, | 301 sy, |
| 350 kVertexSize); | 302 sx + width, |
| 351 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed
X(tx)), | 303 sy + height, |
| 304 kVertexSize); |
| 305 SkPoint* textureCoords = reinterpret_cast<SkPoint*>( |
| 306 reinterpret_cast<intptr_t>(positions) + kVertexSize
- sizeof(SkPoint)); |
| 307 textureCoords->setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)), |
| 352 SkFixedToFloat(texture->normalizeFixed
Y(ty)), | 308 SkFixedToFloat(texture->normalizeFixed
Y(ty)), |
| 353 SkFixedToFloat(texture->normalizeFixed
X(tx + tw)), | 309 SkFixedToFloat(texture->normalizeFixed
X(tx + tw)), |
| 354 SkFixedToFloat(texture->normalizeFixed
Y(ty + th)), | 310 SkFixedToFloat(texture->normalizeFixed
Y(ty + th)), |
| 355 kVertexSize); | 311 kVertexSize); |
| 356 fCurrVertex += 4; | 312 fCurrVertex += 4; |
| 357 } | 313 } |
| 358 | 314 |
| 359 inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint
& skPaint) { | 315 inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint
& skPaint) { |
| 360 GrTextContext::init(paint, skPaint); | 316 GrTextContext::init(paint, skPaint); |
| 361 | 317 |
| 362 fStrike = NULL; | 318 fStrike = NULL; |
| 363 | 319 |
| 364 fCurrTexture = NULL; | |
| 365 fCurrVertex = 0; | 320 fCurrVertex = 0; |
| 366 | 321 |
| 367 fVertices = NULL; | 322 fVertices = NULL; |
| 368 fMaxVertices = 0; | |
| 369 | 323 |
| 370 if (fSkPaint.getTextSize() <= kSmallDFFontLimit) { | 324 if (fSkPaint.getTextSize() <= kSmallDFFontLimit) { |
| 371 fTextRatio = fSkPaint.getTextSize()/kSmallDFFontSize; | 325 fTextRatio = fSkPaint.getTextSize()/kSmallDFFontSize; |
| 372 fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize)); | 326 fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize)); |
| 373 } else if (fSkPaint.getTextSize() <= kMediumDFFontLimit) { | 327 } else if (fSkPaint.getTextSize() <= kMediumDFFontLimit) { |
| 374 fTextRatio = fSkPaint.getTextSize()/kMediumDFFontSize; | 328 fTextRatio = fSkPaint.getTextSize()/kMediumDFFontSize; |
| 375 fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize)); | 329 fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize)); |
| 376 } else { | 330 } else { |
| 377 fTextRatio = fSkPaint.getTextSize()/kLargeDFFontSize; | 331 fTextRatio = fSkPaint.getTextSize()/kLargeDFFontSize; |
| 378 fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize)); | 332 fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize)); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 SkASSERT(byteLength == 0 || text != NULL); | 393 SkASSERT(byteLength == 0 || text != NULL); |
| 440 | 394 |
| 441 // nothing to draw or can't draw | 395 // nothing to draw or can't draw |
| 442 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ | 396 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ |
| 443 || fSkPaint.getRasterizer()) { | 397 || fSkPaint.getRasterizer()) { |
| 444 return; | 398 return; |
| 445 } | 399 } |
| 446 | 400 |
| 447 this->init(paint, skPaint); | 401 this->init(paint, skPaint); |
| 448 | 402 |
| 403 if (NULL == fDrawTarget) { |
| 404 return; |
| 405 } |
| 406 |
| 449 SkScalar sizeRatio = fTextRatio; | 407 SkScalar sizeRatio = fTextRatio; |
| 450 | 408 |
| 451 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 409 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
| 452 | 410 |
| 453 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); | 411 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); |
| 454 SkGlyphCache* cache = autoCache.getCache(); | 412 SkGlyphCache* cache = autoCache.getCache(); |
| 455 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 413 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 414 if (NULL == fStrike) { |
| 415 fStrike = fContext->getFontCache()->getStrike(fontScaler, true); |
| 416 } |
| 456 | 417 |
| 457 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); | 418 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); |
| 458 | 419 |
| 420 // allocate vertices |
| 421 SkASSERT(NULL == fVertices); |
| 422 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
| 423 SK_ARRAY_COUNT(g
TextVertexAttribs)); |
| 424 int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); |
| 425 bool success = fDrawTarget->reserveVertexAndIndexSpace(4*numGlyphs, |
| 426 0, |
| 427 &fVertices, |
| 428 NULL); |
| 429 GrAlwaysAssert(success); |
| 430 |
| 459 // need to measure first | 431 // need to measure first |
| 460 // TODO - generate positions and pre-load cache as well? | 432 // TODO - generate positions and pre-load cache as well? |
| 461 const char* stop = text + byteLength; | 433 const char* stop = text + byteLength; |
| 462 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { | 434 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { |
| 463 SkFixed stopX = 0; | 435 SkFixed stopX = 0; |
| 464 SkFixed stopY = 0; | 436 SkFixed stopY = 0; |
| 465 | 437 |
| 466 const char* textPtr = text; | 438 const char* textPtr = text; |
| 467 while (textPtr < stop) { | 439 while (textPtr < stop) { |
| 468 // don't need x, y here, since all subpixel variants will have the | 440 // 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... |
| 516 SkASSERT(byteLength == 0 || text != NULL); | 488 SkASSERT(byteLength == 0 || text != NULL); |
| 517 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 489 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
| 518 | 490 |
| 519 // nothing to draw | 491 // nothing to draw |
| 520 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/)
{ | 492 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/)
{ |
| 521 return; | 493 return; |
| 522 } | 494 } |
| 523 | 495 |
| 524 this->init(paint, skPaint); | 496 this->init(paint, skPaint); |
| 525 | 497 |
| 498 if (NULL == fDrawTarget) { |
| 499 return; |
| 500 } |
| 501 |
| 526 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 502 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
| 527 | 503 |
| 528 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); | 504 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); |
| 529 SkGlyphCache* cache = autoCache.getCache(); | 505 SkGlyphCache* cache = autoCache.getCache(); |
| 530 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 506 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 507 if (NULL == fStrike) { |
| 508 fStrike = fContext->getFontCache()->getStrike(fontScaler, true); |
| 509 } |
| 510 |
| 511 // allocate vertices |
| 512 SkASSERT(NULL == fVertices); |
| 513 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
| 514 SK_ARRAY_COUNT(g
TextVertexAttribs)); |
| 515 int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); |
| 516 bool success = fDrawTarget->reserveVertexAndIndexSpace(4*numGlyphs, |
| 517 0, |
| 518 &fVertices, |
| 519 NULL); |
| 520 GrAlwaysAssert(success); |
| 531 | 521 |
| 532 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); | 522 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); |
| 533 | 523 |
| 534 const char* stop = text + byteLength; | 524 const char* stop = text + byteLength; |
| 535 | 525 |
| 536 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { | 526 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { |
| 537 while (text < stop) { | 527 while (text < stop) { |
| 538 // the last 2 parameters are ignored | 528 // the last 2 parameters are ignored |
| 539 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 529 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
| 540 | 530 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 567 SkScalarToFixed(x) - (glyph.fAdvanceX >> a
lignShift), | 557 SkScalarToFixed(x) - (glyph.fAdvanceX >> a
lignShift), |
| 568 SkScalarToFixed(y) - (glyph.fAdvanceY >> a
lignShift), | 558 SkScalarToFixed(y) - (glyph.fAdvanceY >> a
lignShift), |
| 569 fontScaler); | 559 fontScaler); |
| 570 } | 560 } |
| 571 pos += scalarsPerPosition; | 561 pos += scalarsPerPosition; |
| 572 } | 562 } |
| 573 } | 563 } |
| 574 | 564 |
| 575 this->finish(); | 565 this->finish(); |
| 576 } | 566 } |
| OLD | NEW |