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