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 |