| 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 |