OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 #include "GrAtlasTextContext.h" | 7 #include "GrAtlasTextContext.h" |
8 | 8 |
9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 } | 84 } |
85 | 85 |
86 bool GrAtlasTextContext::canDraw(const GrRenderTarget*, | 86 bool GrAtlasTextContext::canDraw(const GrRenderTarget*, |
87 const GrClip&, | 87 const GrClip&, |
88 const GrPaint&, | 88 const GrPaint&, |
89 const SkPaint& skPaint, | 89 const SkPaint& skPaint, |
90 const SkMatrix& viewMatrix) { | 90 const SkMatrix& viewMatrix) { |
91 return !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix); | 91 return !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix); |
92 } | 92 } |
93 | 93 |
| 94 GrColor GrAtlasTextContext::ComputeCanonicalColor(const SkPaint& paint, bool lcd
) { |
| 95 GrColor canonicalColor = paint.computeLuminanceColor(); |
| 96 if (lcd) { |
| 97 // This is the correct computation, but there are tons of cases where LC
D can be overridden. |
| 98 // For now we just regenerate if any run in a textblob has LCD. |
| 99 // TODO figure out where all of these overrides are and see if we can in
corporate that logic |
| 100 // at a higher level *OR* use sRGB |
| 101 SkASSERT(false); |
| 102 //canonicalColor = SkMaskGamma::CanonicalColor(canonicalColor); |
| 103 } else { |
| 104 // A8, though can have mixed BMP text but it shouldn't matter because BM
P text won't have |
| 105 // gamma corrected masks anyways, nor color |
| 106 U8CPU lum = SkComputeLuminance(SkColorGetR(canonicalColor), |
| 107 SkColorGetG(canonicalColor), |
| 108 SkColorGetB(canonicalColor)); |
| 109 // reduce to our finite number of bits |
| 110 canonicalColor = SkMaskGamma::CanonicalColor(SkColorSetRGB(lum, lum, lum
)); |
| 111 } |
| 112 return canonicalColor; |
| 113 } |
| 114 |
| 115 // TODO if this function ever shows up in profiling, then we can compute this va
lue when the |
| 116 // textblob is being built and cache it. However, for the time being textblobs
mostly only have 1 |
| 117 // run so this is not a big deal to compute here. |
| 118 bool GrAtlasTextContext::HasLCD(const SkTextBlob* blob) { |
| 119 SkTextBlob::RunIterator it(blob); |
| 120 for (; !it.done(); it.next()) { |
| 121 if (it.isLCD()) { |
| 122 return true; |
| 123 } |
| 124 } |
| 125 return false; |
| 126 } |
| 127 |
94 bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTr
ansY, | 128 bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTr
ansY, |
95 const BitmapTextBlob& blob, const Sk
Paint& paint, | 129 const BitmapTextBlob& blob, const Sk
Paint& paint, |
96 const SkMaskFilter::BlurRec& blurRec
, | 130 const SkMaskFilter::BlurRec& blurRec
, |
97 const SkMatrix& viewMatrix, SkScalar
x, SkScalar y) { | 131 const SkMatrix& viewMatrix, SkScalar
x, SkScalar y) { |
98 // Color can affect the mask | 132 // If we have LCD text then our canonical color will be set to transparent,
in this case we have |
99 // TODO we can adjust the color within specific gamma slots | 133 // to regenerate the blob on any color change |
100 if (blob.fColor != paint.getColor()) { | 134 if (blob.fKey.fCanonicalColor == SK_ColorTRANSPARENT && blob.fPaintColor !=
paint.getColor()) { |
101 return true; | 135 return true; |
102 } | 136 } |
103 | 137 |
104 if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { | 138 if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { |
105 return true; | 139 return true; |
106 } | 140 } |
107 | 141 |
108 if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(view
Matrix)) { | 142 if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(view
Matrix)) { |
109 return true; | 143 return true; |
110 } | 144 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v
iewMatrix, false); | 207 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v
iewMatrix, false); |
174 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | 208 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); |
175 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc())
; | 209 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc())
; |
176 } | 210 } |
177 | 211 |
178 void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, | 212 void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, |
179 const SkPaint& skPaint, const SkMatrix& vi
ewMatrix, | 213 const SkPaint& skPaint, const SkMatrix& vi
ewMatrix, |
180 const SkTextBlob* blob, SkScalar x, SkScal
ar y, | 214 const SkTextBlob* blob, SkScalar x, SkScal
ar y, |
181 SkDrawFilter* drawFilter, const SkIRect& c
lipBounds) { | 215 SkDrawFilter* drawFilter, const SkIRect& c
lipBounds) { |
182 SkAutoTUnref<BitmapTextBlob> cacheBlob; | 216 SkAutoTUnref<BitmapTextBlob> cacheBlob; |
183 | |
184 SkMaskFilter::BlurRec blurRec; | 217 SkMaskFilter::BlurRec blurRec; |
185 BitmapTextBlob::Key key; | 218 BitmapTextBlob::Key key; |
186 // It might be worth caching these things, but its not clear at this time | 219 // It might be worth caching these things, but its not clear at this time |
187 // TODO for animated mask filters, this will fill up our cache. We need a s
afeguard here | 220 // TODO for animated mask filters, this will fill up our cache. We need a s
afeguard here |
188 const SkMaskFilter* mf = skPaint.getMaskFilter(); | 221 const SkMaskFilter* mf = skPaint.getMaskFilter(); |
189 bool canCache = !(skPaint.getPathEffect() || | 222 bool canCache = !(skPaint.getPathEffect() || |
190 (mf && !mf->asABlur(&blurRec)) || | 223 (mf && !mf->asABlur(&blurRec)) || |
191 drawFilter); | 224 drawFilter); |
192 | 225 |
193 if (canCache) { | 226 if (canCache) { |
| 227 bool hasLCD = HasLCD(blob); |
| 228 // TODO we want to figure out a way to be able to use the canonical colo
r on LCD text, |
| 229 // see the note on ComputeCanonicalColor above. We pick a dummy value f
or LCD text to |
| 230 // ensure we always match the same key |
| 231 GrColor canonicalColor = hasLCD ? SK_ColorTRANSPARENT : |
| 232 ComputeCanonicalColor(skPaint, hasLCD)
; |
| 233 |
194 key.fUniqueID = blob->uniqueID(); | 234 key.fUniqueID = blob->uniqueID(); |
195 key.fStyle = skPaint.getStyle(); | 235 key.fStyle = skPaint.getStyle(); |
196 key.fHasBlur = SkToBool(mf); | 236 key.fHasBlur = SkToBool(mf); |
| 237 key.fCanonicalColor = canonicalColor; |
197 cacheBlob.reset(SkSafeRef(fCache->find(key))); | 238 cacheBlob.reset(SkSafeRef(fCache->find(key))); |
198 } | 239 } |
199 | 240 |
200 SkIRect clipRect; | 241 SkIRect clipRect; |
201 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 242 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
202 | 243 |
203 SkScalar transX = 0.f; | 244 SkScalar transX = 0.f; |
204 SkScalar transY = 0.f; | 245 SkScalar transY = 0.f; |
205 | 246 |
| 247 // Though for the time being runs in the textblob can override the paint, th
ey only touch font |
| 248 // info. |
| 249 GrPaint grPaint; |
| 250 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); |
| 251 |
206 if (cacheBlob) { | 252 if (cacheBlob) { |
207 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, blurRec, v
iewMatrix, x, y)) { | 253 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, blurRec, v
iewMatrix, x, y)) { |
208 // We have to remake the blob because changes may invalidate our mas
ks. | 254 // We have to remake the blob because changes may invalidate our mas
ks. |
209 // TODO we could probably get away reuse most of the time if the poi
nter is unique, | 255 // TODO we could probably get away reuse most of the time if the poi
nter is unique, |
210 // but we'd have to clear the subrun information | 256 // but we'd have to clear the subrun information |
211 fCache->remove(cacheBlob); | 257 fCache->remove(cacheBlob); |
212 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, | 258 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, |
213 kGrayTextVASize))); | 259 kGrayTextVASize))); |
214 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y,
drawFilter, | 260 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie
wMatrix, blob, x, y, |
215 clipRect); | 261 drawFilter, clipRect); |
216 } else { | 262 } else { |
217 // If we can reuse the blob, then make sure we update the blob's vie
wmatrix and x/y | 263 // If we can reuse the blob, then make sure we update the blob's vie
wmatrix, and x/y |
218 // offsets to reflect the results of any translations we may apply i
n generateGeometry | 264 // offsets |
219 cacheBlob->fViewMatrix = viewMatrix; | 265 cacheBlob->fViewMatrix = viewMatrix; |
220 cacheBlob->fX = x; | 266 cacheBlob->fX = x; |
221 cacheBlob->fY = y; | 267 cacheBlob->fY = y; |
222 fCache->makeMRU(cacheBlob); | 268 fCache->makeMRU(cacheBlob); |
223 } | 269 } |
224 } else { | 270 } else { |
225 if (canCache) { | 271 if (canCache) { |
226 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, | 272 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, |
227 kGrayTextVASize))); | 273 kGrayTextVASize))); |
228 } else { | 274 } else { |
229 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize)); | 275 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize)); |
230 } | 276 } |
231 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra
wFilter, clipRect); | 277 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat
rix, blob, x, y, |
| 278 drawFilter, clipRect); |
232 } | 279 } |
233 | 280 |
234 // Though for the time being runs in the textblob can override the paint, th
ey only touch font | 281 cacheBlob->fPaintColor = skPaint.getColor(); |
235 // info. | |
236 GrPaint grPaint; | |
237 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); | |
238 | |
239 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint
, drawFilter, | 282 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint
, drawFilter, |
240 clip, viewMatrix, clipBounds, x, y, transX, transY); | 283 clip, viewMatrix, clipBounds, x, y, transX, transY); |
241 } | 284 } |
242 | 285 |
243 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob, | 286 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob, |
244 const SkPaint& skPaint, const SkMatr
ix& viewMatrix, | 287 const SkPaint& skPaint, GrColor colo
r, |
| 288 const SkMatrix& viewMatrix, |
245 const SkTextBlob* blob, SkScalar x,
SkScalar y, | 289 const SkTextBlob* blob, SkScalar x,
SkScalar y, |
246 SkDrawFilter* drawFilter, const SkIR
ect& clipRect) { | 290 SkDrawFilter* drawFilter, const SkIR
ect& clipRect) { |
247 cacheBlob->fViewMatrix = viewMatrix; | 291 cacheBlob->fViewMatrix = viewMatrix; |
248 cacheBlob->fX = x; | 292 cacheBlob->fX = x; |
249 cacheBlob->fY = y; | 293 cacheBlob->fY = y; |
250 cacheBlob->fColor = skPaint.getColor(); | |
251 | 294 |
252 // Regenerate textblob | 295 // Regenerate textblob |
253 SkPaint runPaint = skPaint; | 296 SkPaint runPaint = skPaint; |
254 SkTextBlob::RunIterator it(blob); | 297 SkTextBlob::RunIterator it(blob); |
255 for (int run = 0; !it.done(); it.next(), run++) { | 298 for (int run = 0; !it.done(); it.next(), run++) { |
256 int glyphCount = it.glyphCount(); | 299 int glyphCount = it.glyphCount(); |
257 size_t textLen = glyphCount * sizeof(uint16_t); | 300 size_t textLen = glyphCount * sizeof(uint16_t); |
258 const SkPoint& offset = it.offset(); | 301 const SkPoint& offset = it.offset(); |
259 // applyFontToPaint() always overwrites the exact same attributes, | 302 // applyFontToPaint() always overwrites the exact same attributes, |
260 // so it is safe to not re-seed the paint for this reason. | 303 // so it is safe to not re-seed the paint for this reason. |
(...skipping 22 matching lines...) Expand all Loading... |
283 } | 326 } |
284 | 327 |
285 if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { | 328 if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { |
286 cacheBlob->fRuns[run].fDrawAsPaths = true; | 329 cacheBlob->fRuns[run].fDrawAsPaths = true; |
287 continue; | 330 continue; |
288 } | 331 } |
289 cacheBlob->fRuns[run].fDrawAsPaths = false; | 332 cacheBlob->fRuns[run].fDrawAsPaths = false; |
290 | 333 |
291 switch (it.positioning()) { | 334 switch (it.positioning()) { |
292 case SkTextBlob::kDefault_Positioning: | 335 case SkTextBlob::kDefault_Positioning: |
293 this->internalDrawText(cacheBlob, run, cache, runPaint, viewMatr
ix, | 336 this->internalDrawText(cacheBlob, run, cache, runPaint, color, v
iewMatrix, |
294 (const char *)it.glyphs(), textLen, | 337 (const char *)it.glyphs(), textLen, |
295 x + offset.x(), y + offset.y(), clipRect)
; | 338 x + offset.x(), y + offset.y(), clipRect)
; |
296 break; | 339 break; |
297 case SkTextBlob::kHorizontal_Positioning: | 340 case SkTextBlob::kHorizontal_Positioning: |
298 this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewM
atrix, | 341 this->internalDrawPosText(cacheBlob, run, cache, runPaint, color
, viewMatrix, |
299 (const char*)it.glyphs(), textLen, it.
pos(), 1, | 342 (const char*)it.glyphs(), textLen, it.
pos(), 1, |
300 SkPoint::Make(x, y + offset.y()), clip
Rect); | 343 SkPoint::Make(x, y + offset.y()), clip
Rect); |
301 break; | 344 break; |
302 case SkTextBlob::kFull_Positioning: | 345 case SkTextBlob::kFull_Positioning: |
303 this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewM
atrix, | 346 this->internalDrawPosText(cacheBlob, run, cache, runPaint, color
, viewMatrix, |
304 (const char*)it.glyphs(), textLen, it.
pos(), 2, | 347 (const char*)it.glyphs(), textLen, it.
pos(), 2, |
305 SkPoint::Make(x, y), clipRect); | 348 SkPoint::Make(x, y), clipRect); |
306 break; | 349 break; |
307 } | 350 } |
308 | 351 |
309 if (drawFilter) { | 352 if (drawFilter) { |
310 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. | 353 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. |
311 runPaint = skPaint; | 354 runPaint = skPaint; |
312 } | 355 } |
313 | 356 |
(...skipping 10 matching lines...) Expand all Loading... |
324 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex
tVASize)); | 367 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex
tVASize)); |
325 blob->fViewMatrix = viewMatrix; | 368 blob->fViewMatrix = viewMatrix; |
326 blob->fX = x; | 369 blob->fX = x; |
327 blob->fY = y; | 370 blob->fY = y; |
328 | 371 |
329 SkIRect clipRect; | 372 SkIRect clipRect; |
330 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 373 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
331 | 374 |
332 // setup cache | 375 // setup cache |
333 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; | 376 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; |
334 this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength
, x, y, clipRect); | 377 this->internalDrawText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix
, text, byteLength, |
| 378 x, y, clipRect); |
335 SkGlyphCache::AttachCache(cache); | 379 SkGlyphCache::AttachCache(cache); |
336 | 380 |
337 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip, viewM
atrix); | 381 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip, viewM
atrix); |
338 } | 382 } |
339 | 383 |
340 void GrAtlasTextContext::internalDrawText(BitmapTextBlob* blob, int runIndex, | 384 void GrAtlasTextContext::internalDrawText(BitmapTextBlob* blob, int runIndex, |
341 SkGlyphCache* cache, const SkPaint& sk
Paint, | 385 SkGlyphCache* cache, const SkPaint& sk
Paint, |
| 386 GrColor color, |
342 const SkMatrix& viewMatrix, | 387 const SkMatrix& viewMatrix, |
343 const char text[], size_t byteLength, | 388 const char text[], size_t byteLength, |
344 SkScalar x, SkScalar y, const SkIRect&
clipRect) { | 389 SkScalar x, SkScalar y, const SkIRect&
clipRect) { |
345 SkASSERT(byteLength == 0 || text != NULL); | 390 SkASSERT(byteLength == 0 || text != NULL); |
346 | 391 |
347 // nothing to draw | 392 // nothing to draw |
348 if (text == NULL || byteLength == 0) { | 393 if (text == NULL || byteLength == 0) { |
349 return; | 394 return; |
350 } | 395 } |
351 | 396 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 | 455 |
411 if (glyph.fWidth) { | 456 if (glyph.fWidth) { |
412 this->appendGlyph(blob, | 457 this->appendGlyph(blob, |
413 runIndex, | 458 runIndex, |
414 GrGlyph::Pack(glyph.getGlyphID(), | 459 GrGlyph::Pack(glyph.getGlyphID(), |
415 glyph.getSubXFixed(), | 460 glyph.getSubXFixed(), |
416 glyph.getSubYFixed(), | 461 glyph.getSubYFixed(), |
417 GrGlyph::kCoverage_MaskStyle), | 462 GrGlyph::kCoverage_MaskStyle), |
418 Sk48Dot16FloorToInt(fx), | 463 Sk48Dot16FloorToInt(fx), |
419 Sk48Dot16FloorToInt(fy), | 464 Sk48Dot16FloorToInt(fy), |
420 skPaint.getColor(), | 465 color, |
421 fontScaler, | 466 fontScaler, |
422 clipRect); | 467 clipRect); |
423 } | 468 } |
424 | 469 |
425 fx += glyph.fAdvanceX; | 470 fx += glyph.fAdvanceX; |
426 fy += glyph.fAdvanceY; | 471 fy += glyph.fAdvanceY; |
427 } | 472 } |
428 } | 473 } |
429 | 474 |
430 void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, | 475 void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, |
431 const GrPaint& paint, const SkPaint& skPa
int, | 476 const GrPaint& paint, const SkPaint& skPa
int, |
432 const SkMatrix& viewMatrix, | 477 const SkMatrix& viewMatrix, |
433 const char text[], size_t byteLength, | 478 const char text[], size_t byteLength, |
434 const SkScalar pos[], int scalarsPerPosit
ion, | 479 const SkScalar pos[], int scalarsPerPosit
ion, |
435 const SkPoint& offset, const SkIRect& reg
ionClipBounds) { | 480 const SkPoint& offset, const SkIRect& reg
ionClipBounds) { |
436 int glyphCount = skPaint.countText(text, byteLength); | 481 int glyphCount = skPaint.countText(text, byteLength); |
437 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex
tVASize)); | 482 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex
tVASize)); |
438 blob->fViewMatrix = viewMatrix; | 483 blob->fViewMatrix = viewMatrix; |
439 | 484 |
440 SkIRect clipRect; | 485 SkIRect clipRect; |
441 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 486 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
442 | 487 |
443 // setup cache | 488 // setup cache |
444 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; | 489 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; |
445 this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLen
gth, pos, | 490 this->internalDrawPosText(blob, 0, cache, skPaint, paint.getColor(), viewMat
rix, text, |
446 scalarsPerPosition, offset, clipRect); | 491 byteLength, pos, scalarsPerPosition, offset, clipR
ect); |
447 SkGlyphCache::AttachCache(cache); | 492 SkGlyphCache::AttachCache(cache); |
448 | 493 |
449 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip, viewM
atrix); | 494 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip, viewM
atrix); |
450 } | 495 } |
451 | 496 |
452 void GrAtlasTextContext::internalDrawPosText(BitmapTextBlob* blob, int runIndex, | 497 void GrAtlasTextContext::internalDrawPosText(BitmapTextBlob* blob, int runIndex, |
453 SkGlyphCache* cache, const SkPaint&
skPaint, | 498 SkGlyphCache* cache, const SkPaint&
skPaint, |
| 499 GrColor color, |
454 const SkMatrix& viewMatrix, | 500 const SkMatrix& viewMatrix, |
455 const char text[], size_t byteLengt
h, | 501 const char text[], size_t byteLengt
h, |
456 const SkScalar pos[], int scalarsPe
rPosition, | 502 const SkScalar pos[], int scalarsPe
rPosition, |
457 const SkPoint& offset, const SkIRec
t& clipRect) { | 503 const SkPoint& offset, const SkIRec
t& clipRect) { |
458 SkASSERT(byteLength == 0 || text != NULL); | 504 SkASSERT(byteLength == 0 || text != NULL); |
459 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 505 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
460 | 506 |
461 // nothing to draw | 507 // nothing to draw |
462 if (text == NULL || byteLength == 0) { | 508 if (text == NULL || byteLength == 0) { |
463 return; | 509 return; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 | 547 |
502 if (glyph.fWidth) { | 548 if (glyph.fWidth) { |
503 this->appendGlyph(blob, | 549 this->appendGlyph(blob, |
504 runIndex, | 550 runIndex, |
505 GrGlyph::Pack(glyph.getGlyphID(), | 551 GrGlyph::Pack(glyph.getGlyphID(), |
506 glyph.getSubXFixed(), | 552 glyph.getSubXFixed(), |
507 glyph.getSubYFixed(), | 553 glyph.getSubYFixed(), |
508 GrGlyph::kCoverage_MaskStyle
), | 554 GrGlyph::kCoverage_MaskStyle
), |
509 Sk48Dot16FloorToInt(fx), | 555 Sk48Dot16FloorToInt(fx), |
510 Sk48Dot16FloorToInt(fy), | 556 Sk48Dot16FloorToInt(fy), |
511 skPaint.getColor(), | 557 color, |
512 fontScaler, | 558 fontScaler, |
513 clipRect); | 559 clipRect); |
514 } | 560 } |
515 pos += scalarsPerPosition; | 561 pos += scalarsPerPosition; |
516 } | 562 } |
517 } else { | 563 } else { |
518 while (text < stop) { | 564 while (text < stop) { |
519 const char* currentText = text; | 565 const char* currentText = text; |
520 const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0); | 566 const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0); |
521 | 567 |
(...skipping 17 matching lines...) Expand all Loading... |
539 SkASSERT(glyph.fWidth); | 585 SkASSERT(glyph.fWidth); |
540 | 586 |
541 this->appendGlyph(blob, | 587 this->appendGlyph(blob, |
542 runIndex, | 588 runIndex, |
543 GrGlyph::Pack(glyph.getGlyphID(), | 589 GrGlyph::Pack(glyph.getGlyphID(), |
544 glyph.getSubXFixed(), | 590 glyph.getSubXFixed(), |
545 glyph.getSubYFixed(), | 591 glyph.getSubYFixed(), |
546 GrGlyph::kCoverage_MaskStyle
), | 592 GrGlyph::kCoverage_MaskStyle
), |
547 Sk48Dot16FloorToInt(fx), | 593 Sk48Dot16FloorToInt(fx), |
548 Sk48Dot16FloorToInt(fy), | 594 Sk48Dot16FloorToInt(fy), |
549 skPaint.getColor(), | 595 color, |
550 fontScaler, | 596 fontScaler, |
551 clipRect); | 597 clipRect); |
552 } | 598 } |
553 pos += scalarsPerPosition; | 599 pos += scalarsPerPosition; |
554 } | 600 } |
555 } | 601 } |
556 } else { // not subpixel | 602 } else { // not subpixel |
557 | 603 |
558 if (SkPaint::kLeft_Align == skPaint.getTextAlign()) { | 604 if (SkPaint::kLeft_Align == skPaint.getTextAlign()) { |
559 while (text < stop) { | 605 while (text < stop) { |
560 // the last 2 parameters are ignored | 606 // the last 2 parameters are ignored |
561 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 607 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
562 | 608 |
563 if (glyph.fWidth) { | 609 if (glyph.fWidth) { |
564 SkPoint tmsLoc; | 610 SkPoint tmsLoc; |
565 tmsProc(pos, &tmsLoc); | 611 tmsProc(pos, &tmsLoc); |
566 | 612 |
567 Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + SK_ScalarHalf);
//halfSampleX; | 613 Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + SK_ScalarHalf);
//halfSampleX; |
568 Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf);
//halfSampleY; | 614 Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf);
//halfSampleY; |
569 this->appendGlyph(blob, | 615 this->appendGlyph(blob, |
570 runIndex, | 616 runIndex, |
571 GrGlyph::Pack(glyph.getGlyphID(), | 617 GrGlyph::Pack(glyph.getGlyphID(), |
572 glyph.getSubXFixed(), | 618 glyph.getSubXFixed(), |
573 glyph.getSubYFixed(), | 619 glyph.getSubYFixed(), |
574 GrGlyph::kCoverage_MaskStyle
), | 620 GrGlyph::kCoverage_MaskStyle
), |
575 Sk48Dot16FloorToInt(fx), | 621 Sk48Dot16FloorToInt(fx), |
576 Sk48Dot16FloorToInt(fy), | 622 Sk48Dot16FloorToInt(fy), |
577 skPaint.getColor(), | 623 color, |
578 fontScaler, | 624 fontScaler, |
579 clipRect); | 625 clipRect); |
580 } | 626 } |
581 pos += scalarsPerPosition; | 627 pos += scalarsPerPosition; |
582 } | 628 } |
583 } else { | 629 } else { |
584 while (text < stop) { | 630 while (text < stop) { |
585 // the last 2 parameters are ignored | 631 // the last 2 parameters are ignored |
586 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 632 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
587 | 633 |
588 if (glyph.fWidth) { | 634 if (glyph.fWidth) { |
589 SkPoint tmsLoc; | 635 SkPoint tmsLoc; |
590 tmsProc(pos, &tmsLoc); | 636 tmsProc(pos, &tmsLoc); |
591 | 637 |
592 SkPoint alignLoc; | 638 SkPoint alignLoc; |
593 alignProc(tmsLoc, glyph, &alignLoc); | 639 alignProc(tmsLoc, glyph, &alignLoc); |
594 | 640 |
595 Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + SK_ScalarHalf
); //halfSampleX; | 641 Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + SK_ScalarHalf
); //halfSampleX; |
596 Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf
); //halfSampleY; | 642 Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf
); //halfSampleY; |
597 this->appendGlyph(blob, | 643 this->appendGlyph(blob, |
598 runIndex, | 644 runIndex, |
599 GrGlyph::Pack(glyph.getGlyphID(), | 645 GrGlyph::Pack(glyph.getGlyphID(), |
600 glyph.getSubXFixed(), | 646 glyph.getSubXFixed(), |
601 glyph.getSubYFixed(), | 647 glyph.getSubYFixed(), |
602 GrGlyph::kCoverage_MaskStyle
), | 648 GrGlyph::kCoverage_MaskStyle
), |
603 Sk48Dot16FloorToInt(fx), | 649 Sk48Dot16FloorToInt(fx), |
604 Sk48Dot16FloorToInt(fy), | 650 Sk48Dot16FloorToInt(fy), |
605 skPaint.getColor(), | 651 color, |
606 fontScaler, | 652 fontScaler, |
607 clipRect); | 653 clipRect); |
608 } | 654 } |
609 pos += scalarsPerPosition; | 655 pos += scalarsPerPosition; |
610 } | 656 } |
611 } | 657 } |
612 } | 658 } |
613 } | 659 } |
614 | 660 |
615 void GrAtlasTextContext::appendGlyph(BitmapTextBlob* blob, int runIndex, GrGlyph
::PackedID packed, | 661 void GrAtlasTextContext::appendGlyph(BitmapTextBlob* blob, int runIndex, GrGlyph
::PackedID packed, |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 | 1278 |
1233 GrColor color = grPaint.getColor(); | 1279 GrColor color = grPaint.getColor(); |
1234 uint8_t paintAlpha = skPaint.getAlpha(); | 1280 uint8_t paintAlpha = skPaint.getAlpha(); |
1235 for (int run = 0; run < cacheBlob->fRunCount; run++) { | 1281 for (int run = 0; run < cacheBlob->fRunCount; run++) { |
1236 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, paintAlp
ha, 0, 0); | 1282 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, paintAlp
ha, 0, 0); |
1237 } | 1283 } |
1238 | 1284 |
1239 // Now flush big glyphs | 1285 // Now flush big glyphs |
1240 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); | 1286 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); |
1241 } | 1287 } |
OLD | NEW |