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 |