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