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 "GrBlurUtils.h" | 9 #include "GrBlurUtils.h" |
10 #include "GrDrawContext.h" | 10 #include "GrDrawContext.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 } | 142 } |
143 } | 143 } |
144 } | 144 } |
145 } | 145 } |
146 | 146 |
147 GrAtlasTextContext* GrAtlasTextContext::Create(GrContext* context, | 147 GrAtlasTextContext* GrAtlasTextContext::Create(GrContext* context, |
148 const SkSurfaceProps& surfaceProp
s) { | 148 const SkSurfaceProps& surfaceProp
s) { |
149 return new GrAtlasTextContext(context, surfaceProps); | 149 return new GrAtlasTextContext(context, surfaceProps); |
150 } | 150 } |
151 | 151 |
152 bool GrAtlasTextContext::canDraw(const GrRenderTarget*, | 152 bool GrAtlasTextContext::canDraw(const SkPaint& skPaint, const SkMatrix& viewMat
rix) { |
153 const GrClip&, | |
154 const GrPaint&, | |
155 const SkPaint& skPaint, | |
156 const SkMatrix& viewMatrix) { | |
157 return this->canDrawAsDistanceFields(skPaint, viewMatrix) || | 153 return this->canDrawAsDistanceFields(skPaint, viewMatrix) || |
158 !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix); | 154 !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix); |
159 } | 155 } |
160 | 156 |
161 GrColor GrAtlasTextContext::ComputeCanonicalColor(const SkPaint& paint, bool lcd
) { | 157 GrColor GrAtlasTextContext::ComputeCanonicalColor(const SkPaint& paint, bool lcd
) { |
162 GrColor canonicalColor = paint.computeLuminanceColor(); | 158 GrColor canonicalColor = paint.computeLuminanceColor(); |
163 if (lcd) { | 159 if (lcd) { |
164 // This is the correct computation, but there are tons of cases where LC
D can be overridden. | 160 // This is the correct computation, but there are tons of cases where LC
D can be overridden. |
165 // For now we just regenerate if any run in a textblob has LCD. | 161 // For now we just regenerate if any run in a textblob has LCD. |
166 // TODO figure out where all of these overrides are and see if we can in
corporate that logic | 162 // TODO figure out where all of these overrides are and see if we can in
corporate that logic |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 ComputeCanonicalColor(skPaint, hasLCD)
; | 324 ComputeCanonicalColor(skPaint, hasLCD)
; |
329 | 325 |
330 key.fPixelGeometry = pixelGeometry; | 326 key.fPixelGeometry = pixelGeometry; |
331 key.fUniqueID = blob->uniqueID(); | 327 key.fUniqueID = blob->uniqueID(); |
332 key.fStyle = skPaint.getStyle(); | 328 key.fStyle = skPaint.getStyle(); |
333 key.fHasBlur = SkToBool(mf); | 329 key.fHasBlur = SkToBool(mf); |
334 key.fCanonicalColor = canonicalColor; | 330 key.fCanonicalColor = canonicalColor; |
335 cacheBlob.reset(SkSafeRef(fCache->find(key))); | 331 cacheBlob.reset(SkSafeRef(fCache->find(key))); |
336 } | 332 } |
337 | 333 |
338 SkIRect clipRect; | |
339 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | |
340 | |
341 SkScalar transX = 0.f; | 334 SkScalar transX = 0.f; |
342 SkScalar transY = 0.f; | 335 SkScalar transY = 0.f; |
343 | 336 |
344 // Though for the time being runs in the textblob can override the paint, th
ey only touch font | 337 // Though for the time being runs in the textblob can override the paint, th
ey only touch font |
345 // info. | 338 // info. |
346 GrPaint grPaint; | 339 GrPaint grPaint; |
347 if (!SkPaintToGrPaint(fContext, skPaint, viewMatrix, &grPaint)) { | 340 if (!SkPaintToGrPaint(fContext, skPaint, viewMatrix, &grPaint)) { |
348 return; | 341 return; |
349 } | 342 } |
350 | 343 |
351 if (cacheBlob) { | 344 if (cacheBlob) { |
352 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, grPaint.ge
tColor(), blurRec, | 345 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, grPaint.ge
tColor(), blurRec, |
353 viewMatrix, x, y)) { | 346 viewMatrix, x, y)) { |
354 // We have to remake the blob because changes may invalidate our mas
ks. | 347 // We have to remake the blob because changes may invalidate our mas
ks. |
355 // TODO we could probably get away reuse most of the time if the poi
nter is unique, | 348 // TODO we could probably get away reuse most of the time if the poi
nter is unique, |
356 // but we'd have to clear the subrun information | 349 // but we'd have to clear the subrun information |
357 fCache->remove(cacheBlob); | 350 fCache->remove(cacheBlob); |
358 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, | 351 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, |
359 GrAtlasTextBatch::kGr
ayTextVASize))); | 352 GrAtlasTextBatch::kGr
ayTextVASize))); |
360 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie
wMatrix, | 353 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie
wMatrix, |
361 blob, x, y, drawFilter, clipRect, rt, clip)
; | 354 blob, x, y, drawFilter, clip); |
362 } else { | 355 } else { |
363 // If we can reuse the blob, then make sure we update the blob's vie
wmatrix, and x/y | 356 // If we can reuse the blob, then make sure we update the blob's vie
wmatrix, and x/y |
364 // offsets. Note, we offset the vertex bounds right before flushing | 357 // offsets. Note, we offset the vertex bounds right before flushing |
365 cacheBlob->fViewMatrix = viewMatrix; | 358 cacheBlob->fViewMatrix = viewMatrix; |
366 cacheBlob->fX = x; | 359 cacheBlob->fX = x; |
367 cacheBlob->fY = y; | 360 cacheBlob->fY = y; |
368 fCache->makeMRU(cacheBlob); | 361 fCache->makeMRU(cacheBlob); |
369 #ifdef CACHE_SANITY_CHECK | 362 #ifdef CACHE_SANITY_CHECK |
370 { | 363 { |
371 int glyphCount = 0; | 364 int glyphCount = 0; |
372 int runCount = 0; | 365 int runCount = 0; |
373 GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob); | 366 GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob); |
374 SkAutoTUnref<GrAtlasTextBlob> sanityBlob(fCache->createBlob(glyp
hCount, runCount, | 367 SkAutoTUnref<GrAtlasTextBlob> sanityBlob(fCache->createBlob(glyp
hCount, runCount, |
375 kGra
yTextVASize)); | 368 kGra
yTextVASize)); |
376 GrTextBlobCache::SetupCacheBlobKey(sanityBlob, key, blurRec, skP
aint); | 369 GrTextBlobCache::SetupCacheBlobKey(sanityBlob, key, blurRec, skP
aint); |
377 this->regenerateTextBlob(sanityBlob, skPaint, grPaint.getColor()
, viewMatrix, | 370 this->regenerateTextBlob(sanityBlob, skPaint, grPaint.getColor()
, viewMatrix, |
378 blob, x, y, drawFilter, clipRect, rt, c
lip); | 371 blob, x, y, drawFilter, clip); |
379 GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob); | 372 GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob); |
380 } | 373 } |
381 | 374 |
382 #endif | 375 #endif |
383 } | 376 } |
384 } else { | 377 } else { |
385 if (canCache) { | 378 if (canCache) { |
386 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, | 379 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, |
387 GrAtlasTextBatch::kGr
ayTextVASize))); | 380 GrAtlasTextBatch::kGr
ayTextVASize))); |
388 } else { | 381 } else { |
389 cacheBlob.reset(fCache->createBlob(blob, GrAtlasTextBatch::kGrayText
VASize)); | 382 cacheBlob.reset(fCache->createBlob(blob, GrAtlasTextBatch::kGrayText
VASize)); |
390 } | 383 } |
391 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat
rix, | 384 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat
rix, |
392 blob, x, y, drawFilter, clipRect, rt, clip); | 385 blob, x, y, drawFilter, clip); |
393 } | 386 } |
394 | 387 |
395 this->flush(blob, cacheBlob, dc, rt, skPaint, grPaint, drawFilter, | 388 this->flush(blob, cacheBlob, dc, rt, skPaint, grPaint, drawFilter, |
396 clip, viewMatrix, clipBounds, x, y, transX, transY); | 389 clip, viewMatrix, clipBounds, x, y, transX, transY); |
397 } | 390 } |
398 | 391 |
399 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, | 392 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, |
400 const SkMatrix& viewMatr
ix) { | 393 const SkMatrix& viewMatr
ix) { |
401 // TODO: support perspective (need getMaxScale replacement) | 394 // TODO: support perspective (need getMaxScale replacement) |
402 if (viewMatrix.hasPerspective()) { | 395 if (viewMatrix.hasPerspective()) { |
(...skipping 29 matching lines...) Expand all Loading... |
432 return false; | 425 return false; |
433 } | 426 } |
434 | 427 |
435 return true; | 428 return true; |
436 } | 429 } |
437 | 430 |
438 void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob, | 431 void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob, |
439 const SkPaint& skPaint, GrColor colo
r, | 432 const SkPaint& skPaint, GrColor colo
r, |
440 const SkMatrix& viewMatrix, | 433 const SkMatrix& viewMatrix, |
441 const SkTextBlob* blob, SkScalar x,
SkScalar y, | 434 const SkTextBlob* blob, SkScalar x,
SkScalar y, |
442 SkDrawFilter* drawFilter, const SkIR
ect& clipRect, | 435 SkDrawFilter* drawFilter, |
443 GrRenderTarget* rt, const GrClip& cl
ip) { | 436 const GrClip& clip) { |
444 // The color here is the GrPaint color, and it is used to determine whether
we | 437 // The color here is the GrPaint color, and it is used to determine whether
we |
445 // have to regenerate LCD text blobs. | 438 // have to regenerate LCD text blobs. |
446 // We use this color vs the SkPaint color because it has the colorfilter app
lied. | 439 // We use this color vs the SkPaint color because it has the colorfilter app
lied. |
447 cacheBlob->fPaintColor = color; | 440 cacheBlob->fPaintColor = color; |
448 cacheBlob->fViewMatrix = viewMatrix; | 441 cacheBlob->fViewMatrix = viewMatrix; |
449 cacheBlob->fX = x; | 442 cacheBlob->fX = x; |
450 cacheBlob->fY = y; | 443 cacheBlob->fY = y; |
451 | 444 |
452 // Regenerate textblob | 445 // Regenerate textblob |
453 SkPaint runPaint = skPaint; | 446 SkPaint runPaint = skPaint; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 subRun.fDrawAsDistanceFields = true; | 484 subRun.fDrawAsDistanceFields = true; |
492 | 485 |
493 SkTDArray<char> fallbackTxt; | 486 SkTDArray<char> fallbackTxt; |
494 SkTDArray<SkScalar> fallbackPos; | 487 SkTDArray<SkScalar> fallbackPos; |
495 SkPoint dfOffset; | 488 SkPoint dfOffset; |
496 int scalarsPerPosition = 2; | 489 int scalarsPerPosition = 2; |
497 switch (it.positioning()) { | 490 switch (it.positioning()) { |
498 case SkTextBlob::kDefault_Positioning: { | 491 case SkTextBlob::kDefault_Positioning: { |
499 this->internalDrawDFText(cacheBlob, run, dfPaint, color, vie
wMatrix, | 492 this->internalDrawDFText(cacheBlob, run, dfPaint, color, vie
wMatrix, |
500 (const char *)it.glyphs(), textLen, | 493 (const char *)it.glyphs(), textLen, |
501 x + offset.x(), y + offset.y(), cli
pRect, textRatio, | 494 x + offset.x(), y + offset.y(), tex
tRatio, |
502 &fallbackTxt, &fallbackPos, &dfOffs
et, runPaint); | 495 &fallbackTxt, &fallbackPos, &dfOffs
et, runPaint); |
503 break; | 496 break; |
504 } | 497 } |
505 case SkTextBlob::kHorizontal_Positioning: { | 498 case SkTextBlob::kHorizontal_Positioning: { |
506 scalarsPerPosition = 1; | 499 scalarsPerPosition = 1; |
507 dfOffset = SkPoint::Make(x, y + offset.y()); | 500 dfOffset = SkPoint::Make(x, y + offset.y()); |
508 this->internalDrawDFPosText(cacheBlob, run, dfPaint, color,
viewMatrix, | 501 this->internalDrawDFPosText(cacheBlob, run, dfPaint, color,
viewMatrix, |
509 (const char*)it.glyphs(), textLe
n, it.pos(), | 502 (const char*)it.glyphs(), textLe
n, it.pos(), |
510 scalarsPerPosition, dfOffset, cl
ipRect, textRatio, | 503 scalarsPerPosition, dfOffset, te
xtRatio, |
511 &fallbackTxt, &fallbackPos); | 504 &fallbackTxt, &fallbackPos); |
512 break; | 505 break; |
513 } | 506 } |
514 case SkTextBlob::kFull_Positioning: { | 507 case SkTextBlob::kFull_Positioning: { |
515 dfOffset = SkPoint::Make(x, y); | 508 dfOffset = SkPoint::Make(x, y); |
516 this->internalDrawDFPosText(cacheBlob, run, dfPaint, color,
viewMatrix, | 509 this->internalDrawDFPosText(cacheBlob, run, dfPaint, color,
viewMatrix, |
517 (const char*)it.glyphs(), textLe
n, it.pos(), | 510 (const char*)it.glyphs(), textLe
n, it.pos(), |
518 scalarsPerPosition, dfOffset, cl
ipRect, textRatio, | 511 scalarsPerPosition, dfOffset, te
xtRatio, |
519 &fallbackTxt, &fallbackPos); | 512 &fallbackTxt, &fallbackPos); |
520 break; | 513 break; |
521 } | 514 } |
522 } | 515 } |
523 if (fallbackTxt.count()) { | 516 if (fallbackTxt.count()) { |
524 this->fallbackDrawPosText(cacheBlob, run, rt, clip, color, runPa
int, viewMatrix, | 517 this->fallbackDrawPosText(cacheBlob, run, clip, color, runPaint,
viewMatrix, |
525 fallbackTxt, fallbackPos, scalarsPerPo
sition, dfOffset, | 518 fallbackTxt, fallbackPos, scalarsPerPo
sition, dfOffset); |
526 clipRect); | |
527 } | 519 } |
528 } else if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { | 520 } else if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { |
529 cacheBlob->fRuns[run].fDrawAsPaths = true; | 521 cacheBlob->fRuns[run].fDrawAsPaths = true; |
530 } else { | 522 } else { |
531 cacheBlob->setHasBitmap(); | 523 cacheBlob->setHasBitmap(); |
532 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPa
int, &viewMatrix, | 524 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPa
int, &viewMatrix, |
533 false); | 525 false); |
534 switch (it.positioning()) { | 526 switch (it.positioning()) { |
535 case SkTextBlob::kDefault_Positioning: | 527 case SkTextBlob::kDefault_Positioning: |
536 this->internalDrawBMPText(cacheBlob, run, cache, runPaint, c
olor, viewMatrix, | 528 this->internalDrawBMPText(cacheBlob, run, cache, runPaint, c
olor, viewMatrix, |
537 (const char *)it.glyphs(), textLen
, | 529 (const char *)it.glyphs(), textLen
, |
538 x + offset.x(), y + offset.y(), cl
ipRect); | 530 x + offset.x(), y + offset.y()); |
539 break; | 531 break; |
540 case SkTextBlob::kHorizontal_Positioning: | 532 case SkTextBlob::kHorizontal_Positioning: |
541 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint
, color, viewMatrix, | 533 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint
, color, viewMatrix, |
542 (const char*)it.glyphs(), textL
en, it.pos(), 1, | 534 (const char*)it.glyphs(), textL
en, it.pos(), 1, |
543 SkPoint::Make(x, y + offset.y()
), clipRect); | 535 SkPoint::Make(x, y + offset.y()
)); |
544 break; | 536 break; |
545 case SkTextBlob::kFull_Positioning: | 537 case SkTextBlob::kFull_Positioning: |
546 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint
, color, viewMatrix, | 538 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint
, color, viewMatrix, |
547 (const char*)it.glyphs(), textL
en, it.pos(), 2, | 539 (const char*)it.glyphs(), textL
en, it.pos(), 2, |
548 SkPoint::Make(x, y), clipRect); | 540 SkPoint::Make(x, y)); |
549 break; | 541 break; |
550 } | 542 } |
551 SkGlyphCache::AttachCache(cache); | 543 SkGlyphCache::AttachCache(cache); |
552 } | 544 } |
553 | 545 |
554 if (drawFilter) { | 546 if (drawFilter) { |
555 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. | 547 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. |
556 runPaint = skPaint; | 548 runPaint = skPaint; |
557 } | 549 } |
558 } | 550 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 blob->fMinMaxScale = SkMinScalar(dfMaskScaleCeil / scaledTextSize, blob->fMi
nMaxScale); | 599 blob->fMinMaxScale = SkMinScalar(dfMaskScaleCeil / scaledTextSize, blob->fMi
nMaxScale); |
608 | 600 |
609 skPaint->setLCDRenderText(false); | 601 skPaint->setLCDRenderText(false); |
610 skPaint->setAutohinted(false); | 602 skPaint->setAutohinted(false); |
611 skPaint->setHinting(SkPaint::kNormal_Hinting); | 603 skPaint->setHinting(SkPaint::kNormal_Hinting); |
612 skPaint->setSubpixelText(true); | 604 skPaint->setSubpixelText(true); |
613 } | 605 } |
614 | 606 |
615 inline void GrAtlasTextContext::fallbackDrawPosText(GrAtlasTextBlob* blob, | 607 inline void GrAtlasTextContext::fallbackDrawPosText(GrAtlasTextBlob* blob, |
616 int runIndex, | 608 int runIndex, |
617 GrRenderTarget* rt, const Gr
Clip& clip, | 609 const GrClip& clip, |
618 GrColor color, | 610 GrColor color, |
619 const SkPaint& skPaint, | 611 const SkPaint& skPaint, |
620 const SkMatrix& viewMatrix, | 612 const SkMatrix& viewMatrix, |
621 const SkTDArray<char>& fallb
ackTxt, | 613 const SkTDArray<char>& fallb
ackTxt, |
622 const SkTDArray<SkScalar>& f
allbackPos, | 614 const SkTDArray<SkScalar>& f
allbackPos, |
623 int scalarsPerPosition, | 615 int scalarsPerPosition, |
624 const SkPoint& offset, | 616 const SkPoint& offset) { |
625 const SkIRect& clipRect) { | |
626 SkASSERT(fallbackTxt.count()); | 617 SkASSERT(fallbackTxt.count()); |
627 blob->setHasBitmap(); | 618 blob->setHasBitmap(); |
628 Run& run = blob->fRuns[runIndex]; | 619 Run& run = blob->fRuns[runIndex]; |
629 // Push back a new subrun to fill and set the override descriptor | 620 // Push back a new subrun to fill and set the override descriptor |
630 run.push_back(); | 621 run.push_back(); |
631 run.fOverrideDescriptor.reset(new SkAutoDescriptor); | 622 run.fOverrideDescriptor.reset(new SkAutoDescriptor); |
632 skPaint.getScalerContextDescriptor(run.fOverrideDescriptor, | 623 skPaint.getScalerContextDescriptor(run.fOverrideDescriptor, |
633 fSurfaceProps, &viewMatrix, false); | 624 fSurfaceProps, &viewMatrix, false); |
634 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, | 625 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, |
635 run.fOverrideDescriptor->get
Desc()); | 626 run.fOverrideDescriptor->get
Desc()); |
636 this->internalDrawBMPPosText(blob, runIndex, cache, skPaint, color, viewMatr
ix, | 627 this->internalDrawBMPPosText(blob, runIndex, cache, skPaint, color, viewMatr
ix, |
637 fallbackTxt.begin(), fallbackTxt.count(), | 628 fallbackTxt.begin(), fallbackTxt.count(), |
638 fallbackPos.begin(), scalarsPerPosition, offset
, clipRect); | 629 fallbackPos.begin(), scalarsPerPosition, offset
); |
639 SkGlyphCache::AttachCache(cache); | 630 SkGlyphCache::AttachCache(cache); |
640 } | 631 } |
641 | 632 |
642 inline GrAtlasTextBlob* | 633 inline GrAtlasTextBlob* |
643 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint, | 634 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint, |
644 const SkMatrix& viewMatrix, SkPaint* dfPaint, | 635 const SkMatrix& viewMatrix, SkPaint* dfPaint, |
645 SkScalar* textRatio) { | 636 SkScalar* textRatio) { |
646 GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBatch::
kGrayTextVASize); | 637 GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBatch::
kGrayTextVASize); |
647 | 638 |
648 *dfPaint = origPaint; | 639 *dfPaint = origPaint; |
649 this->initDistanceFieldPaint(blob, dfPaint, textRatio, viewMatrix); | 640 this->initDistanceFieldPaint(blob, dfPaint, textRatio, viewMatrix); |
650 blob->fViewMatrix = viewMatrix; | 641 blob->fViewMatrix = viewMatrix; |
651 Run& run = blob->fRuns[0]; | 642 Run& run = blob->fRuns[0]; |
652 PerSubRunInfo& subRun = run.fSubRunInfo.back(); | 643 PerSubRunInfo& subRun = run.fSubRunInfo.back(); |
653 subRun.fUseLCDText = origPaint.isLCDRenderText(); | 644 subRun.fUseLCDText = origPaint.isLCDRenderText(); |
654 subRun.fDrawAsDistanceFields = true; | 645 subRun.fDrawAsDistanceFields = true; |
655 | 646 |
656 return blob; | 647 return blob; |
657 } | 648 } |
658 | 649 |
659 inline GrAtlasTextBlob* | 650 inline GrAtlasTextBlob* |
660 GrAtlasTextContext::createDrawTextBlob(GrRenderTarget* rt, const GrClip& clip, | 651 GrAtlasTextContext::createDrawTextBlob(const GrClip& clip, |
661 const GrPaint& paint, const SkPaint& skPa
int, | 652 const GrPaint& paint, const SkPaint& skPa
int, |
662 const SkMatrix& viewMatrix, | 653 const SkMatrix& viewMatrix, |
663 const char text[], size_t byteLength, | 654 const char text[], size_t byteLength, |
664 SkScalar x, SkScalar y, const SkIRect& re
gionClipBounds) { | 655 SkScalar x, SkScalar y, const SkIRect& re
gionClipBounds) { |
665 int glyphCount = skPaint.countText(text, byteLength); | 656 int glyphCount = skPaint.countText(text, byteLength); |
666 SkIRect clipRect; | |
667 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | |
668 | 657 |
669 GrAtlasTextBlob* blob; | 658 GrAtlasTextBlob* blob; |
670 if (this->canDrawAsDistanceFields(skPaint, viewMatrix)) { | 659 if (this->canDrawAsDistanceFields(skPaint, viewMatrix)) { |
671 SkPaint dfPaint; | 660 SkPaint dfPaint; |
672 SkScalar textRatio; | 661 SkScalar textRatio; |
673 blob = this->setupDFBlob(glyphCount, skPaint, viewMatrix, &dfPaint, &tex
tRatio); | 662 blob = this->setupDFBlob(glyphCount, skPaint, viewMatrix, &dfPaint, &tex
tRatio); |
674 | 663 |
675 SkTDArray<char> fallbackTxt; | 664 SkTDArray<char> fallbackTxt; |
676 SkTDArray<SkScalar> fallbackPos; | 665 SkTDArray<SkScalar> fallbackPos; |
677 SkPoint offset; | 666 SkPoint offset; |
678 this->internalDrawDFText(blob, 0, dfPaint, paint.getColor(), viewMatrix,
text, | 667 this->internalDrawDFText(blob, 0, dfPaint, paint.getColor(), viewMatrix,
text, |
679 byteLength, x, y, clipRect, textRatio, &fallbac
kTxt, &fallbackPos, | 668 byteLength, x, y, textRatio, &fallbackTxt, &fal
lbackPos, |
680 &offset, skPaint); | 669 &offset, skPaint); |
681 if (fallbackTxt.count()) { | 670 if (fallbackTxt.count()) { |
682 this->fallbackDrawPosText(blob, 0, rt, clip, paint.getColor(), skPai
nt, viewMatrix, | 671 this->fallbackDrawPosText(blob, 0, clip, paint.getColor(), skPaint,
viewMatrix, |
683 fallbackTxt, fallbackPos, 2, offset, clipR
ect); | 672 fallbackTxt, fallbackPos, 2, offset); |
684 } | 673 } |
685 } else { | 674 } else { |
686 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBatch::kGrayTextVASi
ze); | 675 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBatch::kGrayTextVASi
ze); |
687 blob->fViewMatrix = viewMatrix; | 676 blob->fViewMatrix = viewMatrix; |
688 | 677 |
689 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa
trix, false); | 678 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa
trix, false); |
690 this->internalDrawBMPText(blob, 0, cache, skPaint, paint.getColor(), vie
wMatrix, text, | 679 this->internalDrawBMPText(blob, 0, cache, skPaint, paint.getColor(), vie
wMatrix, text, |
691 byteLength, x, y, clipRect); | 680 byteLength, x, y); |
692 SkGlyphCache::AttachCache(cache); | 681 SkGlyphCache::AttachCache(cache); |
693 } | 682 } |
694 return blob; | 683 return blob; |
695 } | 684 } |
696 | 685 |
697 inline GrAtlasTextBlob* | 686 inline GrAtlasTextBlob* |
698 GrAtlasTextContext::createDrawPosTextBlob(GrRenderTarget* rt, const GrClip& clip
, | 687 GrAtlasTextContext::createDrawPosTextBlob(const GrClip& clip, |
699 const GrPaint& paint, const SkPaint& s
kPaint, | 688 const GrPaint& paint, const SkPaint& s
kPaint, |
700 const SkMatrix& viewMatrix, | 689 const SkMatrix& viewMatrix, |
701 const char text[], size_t byteLength, | 690 const char text[], size_t byteLength, |
702 const SkScalar pos[], int scalarsPerPo
sition, | 691 const SkScalar pos[], int scalarsPerPo
sition, |
703 const SkPoint& offset, const SkIRect&
regionClipBounds) { | 692 const SkPoint& offset, const SkIRect&
regionClipBounds) { |
704 int glyphCount = skPaint.countText(text, byteLength); | 693 int glyphCount = skPaint.countText(text, byteLength); |
705 | 694 |
706 SkIRect clipRect; | |
707 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | |
708 | |
709 GrAtlasTextBlob* blob; | 695 GrAtlasTextBlob* blob; |
710 if (this->canDrawAsDistanceFields(skPaint, viewMatrix)) { | 696 if (this->canDrawAsDistanceFields(skPaint, viewMatrix)) { |
711 SkPaint dfPaint; | 697 SkPaint dfPaint; |
712 SkScalar textRatio; | 698 SkScalar textRatio; |
713 blob = this->setupDFBlob(glyphCount, skPaint, viewMatrix, &dfPaint, &tex
tRatio); | 699 blob = this->setupDFBlob(glyphCount, skPaint, viewMatrix, &dfPaint, &tex
tRatio); |
714 | 700 |
715 SkTDArray<char> fallbackTxt; | 701 SkTDArray<char> fallbackTxt; |
716 SkTDArray<SkScalar> fallbackPos; | 702 SkTDArray<SkScalar> fallbackPos; |
717 this->internalDrawDFPosText(blob, 0, dfPaint, paint.getColor(), viewMatr
ix, text, | 703 this->internalDrawDFPosText(blob, 0, dfPaint, paint.getColor(), viewMatr
ix, text, |
718 byteLength, pos, scalarsPerPosition, offset,
clipRect, | 704 byteLength, pos, scalarsPerPosition, offset, |
719 textRatio, &fallbackTxt, &fallbackPos); | 705 textRatio, &fallbackTxt, &fallbackPos); |
720 if (fallbackTxt.count()) { | 706 if (fallbackTxt.count()) { |
721 this->fallbackDrawPosText(blob, 0, rt, clip, paint.getColor(), skPai
nt, viewMatrix, | 707 this->fallbackDrawPosText(blob, 0, clip, paint.getColor(), skPaint,
viewMatrix, |
722 fallbackTxt, fallbackPos, scalarsPerPositi
on, offset, | 708 fallbackTxt, fallbackPos, scalarsPerPositi
on, offset); |
723 clipRect); | |
724 } | 709 } |
725 } else { | 710 } else { |
726 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBatch::kGrayTextVASi
ze); | 711 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBatch::kGrayTextVASi
ze); |
727 blob->fViewMatrix = viewMatrix; | 712 blob->fViewMatrix = viewMatrix; |
728 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa
trix, false); | 713 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa
trix, false); |
729 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(),
viewMatrix, text, | 714 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(),
viewMatrix, text, |
730 byteLength, pos, scalarsPerPosition, offset
, clipRect); | 715 byteLength, pos, scalarsPerPosition, offset
); |
731 SkGlyphCache::AttachCache(cache); | 716 SkGlyphCache::AttachCache(cache); |
732 } | 717 } |
733 return blob; | 718 return blob; |
734 } | 719 } |
735 | 720 |
736 void GrAtlasTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget* rt, | 721 void GrAtlasTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget* rt, |
737 const GrClip& clip, | 722 const GrClip& clip, |
738 const GrPaint& paint, const SkPaint& skPaint
, | 723 const GrPaint& paint, const SkPaint& skPaint
, |
739 const SkMatrix& viewMatrix, | 724 const SkMatrix& viewMatrix, |
740 const char text[], size_t byteLength, | 725 const char text[], size_t byteLength, |
741 SkScalar x, SkScalar y, const SkIRect& regio
nClipBounds) { | 726 SkScalar x, SkScalar y, const SkIRect& regio
nClipBounds) { |
742 SkAutoTUnref<GrAtlasTextBlob> blob( | 727 SkAutoTUnref<GrAtlasTextBlob> blob( |
743 this->createDrawTextBlob(rt, clip, paint, skPaint, viewMatrix, | 728 this->createDrawTextBlob(clip, paint, skPaint, viewMatrix, |
744 text, byteLength, x, y, regionClipBounds)); | 729 text, byteLength, x, y, regionClipBounds)); |
745 this->flush(blob, dc, rt, skPaint, paint, clip, regionClipBounds); | 730 this->flush(blob, dc, rt, skPaint, paint, clip, regionClipBounds); |
746 } | 731 } |
747 | 732 |
748 void GrAtlasTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarget* rt, | 733 void GrAtlasTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarget* rt, |
749 const GrClip& clip, | 734 const GrClip& clip, |
750 const GrPaint& paint, const SkPaint& skPa
int, | 735 const GrPaint& paint, const SkPaint& skPa
int, |
751 const SkMatrix& viewMatrix, | 736 const SkMatrix& viewMatrix, |
752 const char text[], size_t byteLength, | 737 const char text[], size_t byteLength, |
753 const SkScalar pos[], int scalarsPerPosit
ion, | 738 const SkScalar pos[], int scalarsPerPosit
ion, |
754 const SkPoint& offset, const SkIRect& reg
ionClipBounds) { | 739 const SkPoint& offset, const SkIRect& reg
ionClipBounds) { |
755 SkAutoTUnref<GrAtlasTextBlob> blob( | 740 SkAutoTUnref<GrAtlasTextBlob> blob( |
756 this->createDrawPosTextBlob(rt, clip, paint, skPaint, viewMatrix, | 741 this->createDrawPosTextBlob(clip, paint, skPaint, viewMatrix, |
757 text, byteLength, | 742 text, byteLength, |
758 pos, scalarsPerPosition, | 743 pos, scalarsPerPosition, |
759 offset, regionClipBounds)); | 744 offset, regionClipBounds)); |
760 | 745 |
761 this->flush(blob, dc, rt, skPaint, paint, clip, regionClipBounds); | 746 this->flush(blob, dc, rt, skPaint, paint, clip, regionClipBounds); |
762 } | 747 } |
763 | 748 |
764 void GrAtlasTextContext::internalDrawBMPText(GrAtlasTextBlob* blob, int runIndex
, | 749 void GrAtlasTextContext::internalDrawBMPText(GrAtlasTextBlob* blob, int runIndex
, |
765 SkGlyphCache* cache, const SkPaint&
skPaint, | 750 SkGlyphCache* cache, const SkPaint&
skPaint, |
766 GrColor color, | 751 GrColor color, |
767 const SkMatrix& viewMatrix, | 752 const SkMatrix& viewMatrix, |
768 const char text[], size_t byteLengt
h, | 753 const char text[], size_t byteLengt
h, |
769 SkScalar x, SkScalar y, const SkIRe
ct& clipRect) { | 754 SkScalar x, SkScalar y) { |
770 SkASSERT(byteLength == 0 || text != nullptr); | 755 SkASSERT(byteLength == 0 || text != nullptr); |
771 | 756 |
772 // nothing to draw | 757 // nothing to draw |
773 if (text == nullptr || byteLength == 0) { | 758 if (text == nullptr || byteLength == 0) { |
774 return; | 759 return; |
775 } | 760 } |
776 | 761 |
777 fCurrStrike = nullptr; | 762 fCurrStrike = nullptr; |
778 | 763 |
779 // Get GrFontScaler from cache | 764 // Get GrFontScaler from cache |
780 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 765 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
781 | 766 |
782 SkFindAndPlaceGlyph::ProcessText( | 767 SkFindAndPlaceGlyph::ProcessText( |
783 skPaint.getTextEncoding(), text, byteLength, | 768 skPaint.getTextEncoding(), text, byteLength, |
784 {x, y}, viewMatrix, skPaint.getTextAlign(), | 769 {x, y}, viewMatrix, skPaint.getTextAlign(), |
785 cache, | 770 cache, |
786 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { | 771 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { |
787 position += rounding; | 772 position += rounding; |
788 this->bmpAppendGlyph( | 773 this->bmpAppendGlyph( |
789 blob, runIndex, glyph, | 774 blob, runIndex, glyph, |
790 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, | 775 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, |
791 color, fontScaler, clipRect); | 776 color, fontScaler); |
792 } | 777 } |
793 ); | 778 ); |
794 } | 779 } |
795 | 780 |
796 void GrAtlasTextContext::internalDrawBMPPosText(GrAtlasTextBlob* blob, int runIn
dex, | 781 void GrAtlasTextContext::internalDrawBMPPosText(GrAtlasTextBlob* blob, int runIn
dex, |
797 SkGlyphCache* cache, const SkPai
nt& skPaint, | 782 SkGlyphCache* cache, const SkPai
nt& skPaint, |
798 GrColor color, | 783 GrColor color, |
799 const SkMatrix& viewMatrix, | 784 const SkMatrix& viewMatrix, |
800 const char text[], size_t byteLe
ngth, | 785 const char text[], size_t byteLe
ngth, |
801 const SkScalar pos[], int scalar
sPerPosition, | 786 const SkScalar pos[], int scalar
sPerPosition, |
802 const SkPoint& offset, const SkI
Rect& clipRect) { | 787 const SkPoint& offset) { |
803 SkASSERT(byteLength == 0 || text != nullptr); | 788 SkASSERT(byteLength == 0 || text != nullptr); |
804 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 789 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
805 | 790 |
806 // nothing to draw | 791 // nothing to draw |
807 if (text == nullptr || byteLength == 0) { | 792 if (text == nullptr || byteLength == 0) { |
808 return; | 793 return; |
809 } | 794 } |
810 | 795 |
811 fCurrStrike = nullptr; | 796 fCurrStrike = nullptr; |
812 | 797 |
813 // Get GrFontScaler from cache | 798 // Get GrFontScaler from cache |
814 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 799 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
815 | 800 |
816 SkFindAndPlaceGlyph::ProcessPosText( | 801 SkFindAndPlaceGlyph::ProcessPosText( |
817 skPaint.getTextEncoding(), text, byteLength, | 802 skPaint.getTextEncoding(), text, byteLength, |
818 offset, viewMatrix, pos, scalarsPerPosition, | 803 offset, viewMatrix, pos, scalarsPerPosition, |
819 skPaint.getTextAlign(), cache, | 804 skPaint.getTextAlign(), cache, |
820 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { | 805 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { |
821 position += rounding; | 806 position += rounding; |
822 this->bmpAppendGlyph( | 807 this->bmpAppendGlyph( |
823 blob, runIndex, glyph, | 808 blob, runIndex, glyph, |
824 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, | 809 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, |
825 color, fontScaler, clipRect); | 810 color, fontScaler); |
826 } | 811 } |
827 ); | 812 ); |
828 } | 813 } |
829 | 814 |
830 void GrAtlasTextContext::internalDrawDFText(GrAtlasTextBlob* blob, int runIndex, | 815 void GrAtlasTextContext::internalDrawDFText(GrAtlasTextBlob* blob, int runIndex, |
831 const SkPaint& skPaint, GrColor colo
r, | 816 const SkPaint& skPaint, GrColor colo
r, |
832 const SkMatrix& viewMatrix, | 817 const SkMatrix& viewMatrix, |
833 const char text[], size_t byteLength
, | 818 const char text[], size_t byteLength
, |
834 SkScalar x, SkScalar y, const SkIRec
t& clipRect, | 819 SkScalar x, SkScalar y, |
835 SkScalar textRatio, | 820 SkScalar textRatio, |
836 SkTDArray<char>* fallbackTxt, | 821 SkTDArray<char>* fallbackTxt, |
837 SkTDArray<SkScalar>* fallbackPos, | 822 SkTDArray<SkScalar>* fallbackPos, |
838 SkPoint* offset, | 823 SkPoint* offset, |
839 const SkPaint& origPaint) { | 824 const SkPaint& origPaint) { |
840 SkASSERT(byteLength == 0 || text != nullptr); | 825 SkASSERT(byteLength == 0 || text != nullptr); |
841 | 826 |
842 // nothing to draw | 827 // nothing to draw |
843 if (text == nullptr || byteLength == 0) { | 828 if (text == nullptr || byteLength == 0) { |
844 return; | 829 return; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 alignY = SkScalarHalf(alignY); | 875 alignY = SkScalarHalf(alignY); |
891 } else if (origPaint.getTextAlign() == SkPaint::kLeft_Align) { | 876 } else if (origPaint.getTextAlign() == SkPaint::kLeft_Align) { |
892 alignX = 0; | 877 alignX = 0; |
893 alignY = 0; | 878 alignY = 0; |
894 } | 879 } |
895 x -= alignX; | 880 x -= alignX; |
896 y -= alignY; | 881 y -= alignY; |
897 *offset = SkPoint::Make(x, y); | 882 *offset = SkPoint::Make(x, y); |
898 | 883 |
899 this->internalDrawDFPosText(blob, runIndex, skPaint, color, viewMatrix, text
, byteLength, | 884 this->internalDrawDFPosText(blob, runIndex, skPaint, color, viewMatrix, text
, byteLength, |
900 positions.begin(), 2, *offset, clipRect, textRat
io, fallbackTxt, | 885 positions.begin(), 2, *offset, textRatio, fallba
ckTxt, |
901 fallbackPos); | 886 fallbackPos); |
902 } | 887 } |
903 | 888 |
904 void GrAtlasTextContext::internalDrawDFPosText(GrAtlasTextBlob* blob, int runInd
ex, | 889 void GrAtlasTextContext::internalDrawDFPosText(GrAtlasTextBlob* blob, int runInd
ex, |
905 const SkPaint& skPaint, GrColor c
olor, | 890 const SkPaint& skPaint, GrColor c
olor, |
906 const SkMatrix& viewMatrix, | 891 const SkMatrix& viewMatrix, |
907 const char text[], size_t byteLen
gth, | 892 const char text[], size_t byteLen
gth, |
908 const SkScalar pos[], int scalars
PerPosition, | 893 const SkScalar pos[], int scalars
PerPosition, |
909 const SkPoint& offset, const SkIR
ect& clipRect, | 894 const SkPoint& offset, |
910 SkScalar textRatio, | 895 SkScalar textRatio, |
911 SkTDArray<char>* fallbackTxt, | 896 SkTDArray<char>* fallbackTxt, |
912 SkTDArray<SkScalar>* fallbackPos)
{ | 897 SkTDArray<SkScalar>* fallbackPos)
{ |
913 | 898 |
914 SkASSERT(byteLength == 0 || text != nullptr); | 899 SkASSERT(byteLength == 0 || text != nullptr); |
915 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 900 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
916 | 901 |
917 // nothing to draw | 902 // nothing to draw |
918 if (text == nullptr || byteLength == 0) { | 903 if (text == nullptr || byteLength == 0) { |
919 return; | 904 return; |
(...skipping 13 matching lines...) Expand all Loading... |
933 // the last 2 parameters are ignored | 918 // the last 2 parameters are ignored |
934 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 919 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
935 | 920 |
936 if (glyph.fWidth) { | 921 if (glyph.fWidth) { |
937 SkScalar x = offset.x() + pos[0]; | 922 SkScalar x = offset.x() + pos[0]; |
938 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; | 923 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; |
939 | 924 |
940 if (!this->dfAppendGlyph(blob, | 925 if (!this->dfAppendGlyph(blob, |
941 runIndex, | 926 runIndex, |
942 glyph, | 927 glyph, |
943 x, y, color, fontScaler, clipRect, | 928 x, y, color, fontScaler, |
944 textRatio, viewMatrix)) { | 929 textRatio, viewMatrix)) { |
945 // couldn't append, send to fallback | 930 // couldn't append, send to fallback |
946 fallbackTxt->append(SkToInt(text-lastText), lastText); | 931 fallbackTxt->append(SkToInt(text-lastText), lastText); |
947 *fallbackPos->append() = pos[0]; | 932 *fallbackPos->append() = pos[0]; |
948 if (2 == scalarsPerPosition) { | 933 if (2 == scalarsPerPosition) { |
949 *fallbackPos->append() = pos[1]; | 934 *fallbackPos->append() = pos[1]; |
950 } | 935 } |
951 } | 936 } |
952 } | 937 } |
953 pos += scalarsPerPosition; | 938 pos += scalarsPerPosition; |
(...skipping 11 matching lines...) Expand all Loading... |
965 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; | 950 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; |
966 | 951 |
967 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX) * alignMul
* textRatio; | 952 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX) * alignMul
* textRatio; |
968 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY) * alignMul
* textRatio; | 953 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY) * alignMul
* textRatio; |
969 | 954 |
970 if (!this->dfAppendGlyph(blob, | 955 if (!this->dfAppendGlyph(blob, |
971 runIndex, | 956 runIndex, |
972 glyph, | 957 glyph, |
973 x - advanceX, y - advanceY, color, | 958 x - advanceX, y - advanceY, color, |
974 fontScaler, | 959 fontScaler, |
975 clipRect, | |
976 textRatio, | 960 textRatio, |
977 viewMatrix)) { | 961 viewMatrix)) { |
978 // couldn't append, send to fallback | 962 // couldn't append, send to fallback |
979 fallbackTxt->append(SkToInt(text-lastText), lastText); | 963 fallbackTxt->append(SkToInt(text-lastText), lastText); |
980 *fallbackPos->append() = pos[0]; | 964 *fallbackPos->append() = pos[0]; |
981 if (2 == scalarsPerPosition) { | 965 if (2 == scalarsPerPosition) { |
982 *fallbackPos->append() = pos[1]; | 966 *fallbackPos->append() = pos[1]; |
983 } | 967 } |
984 } | 968 } |
985 } | 969 } |
986 pos += scalarsPerPosition; | 970 pos += scalarsPerPosition; |
987 } | 971 } |
988 } | 972 } |
989 | 973 |
990 SkGlyphCache::AttachCache(cache); | 974 SkGlyphCache::AttachCache(cache); |
991 } | 975 } |
992 | 976 |
993 void GrAtlasTextContext::bmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex, | 977 void GrAtlasTextContext::bmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex, |
994 const SkGlyph& skGlyph, | 978 const SkGlyph& skGlyph, |
995 int vx, int vy, GrColor color, GrFontSca
ler* scaler, | 979 int vx, int vy, GrColor color, GrFontSca
ler* scaler) { |
996 const SkIRect& clipRect) { | |
997 Run& run = blob->fRuns[runIndex]; | 980 Run& run = blob->fRuns[runIndex]; |
998 if (!fCurrStrike) { | 981 if (!fCurrStrike) { |
999 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler); | 982 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler); |
1000 } | 983 } |
1001 | 984 |
1002 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), | 985 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), |
1003 skGlyph.getSubXFixed(), | 986 skGlyph.getSubXFixed(), |
1004 skGlyph.getSubYFixed(), | 987 skGlyph.getSubYFixed(), |
1005 GrGlyph::kCoverage_MaskStyle); | 988 GrGlyph::kCoverage_MaskStyle); |
1006 GrGlyph* glyph = fCurrStrike->getGlyph(skGlyph, id, scaler); | 989 GrGlyph* glyph = fCurrStrike->getGlyph(skGlyph, id, scaler); |
1007 if (!glyph) { | 990 if (!glyph) { |
1008 return; | 991 return; |
1009 } | 992 } |
1010 | 993 |
1011 int x = vx + glyph->fBounds.fLeft; | 994 int x = vx + glyph->fBounds.fLeft; |
1012 int y = vy + glyph->fBounds.fTop; | 995 int y = vy + glyph->fBounds.fTop; |
1013 | 996 |
1014 // keep them as ints until we've done the clip-test | 997 // keep them as ints until we've done the clip-test |
1015 int width = glyph->fBounds.width(); | 998 int width = glyph->fBounds.width(); |
1016 int height = glyph->fBounds.height(); | 999 int height = glyph->fBounds.height(); |
1017 | 1000 |
1018 #if 0 | |
1019 // Not checking the clip bounds might introduce a performance regression. H
owever, its not | |
1020 // clear if this is still true today with the larger tiles we use in Chrome.
For repositionable | |
1021 // blobs, we want to make sure we have all of the glyphs, so clipping them o
ut is not ideal. | |
1022 // We could store the cliprect in the key, but then we'd lose the ability to
do integer scrolls | |
1023 // TODO verify this | |
1024 // check if we clipped out | |
1025 if (clipRect.quickReject(x, y, x + width, y + height)) { | |
1026 return; | |
1027 } | |
1028 #endif | |
1029 | |
1030 // If the glyph is too large we fall back to paths | 1001 // If the glyph is too large we fall back to paths |
1031 if (glyph->fTooLargeForAtlas) { | 1002 if (glyph->fTooLargeForAtlas) { |
1032 this->appendGlyphPath(blob, glyph, scaler, skGlyph, SkIntToScalar(vx), S
kIntToScalar(vy)); | 1003 this->appendGlyphPath(blob, glyph, scaler, skGlyph, SkIntToScalar(vx), S
kIntToScalar(vy)); |
1033 return; | 1004 return; |
1034 } | 1005 } |
1035 | 1006 |
1036 GrMaskFormat format = glyph->fMaskFormat; | 1007 GrMaskFormat format = glyph->fMaskFormat; |
1037 | 1008 |
1038 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); | 1009 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); |
1039 if (run.fInitialized && subRun->fMaskFormat != format) { | 1010 if (run.fInitialized && subRun->fMaskFormat != format) { |
(...skipping 14 matching lines...) Expand all Loading... |
1054 r.fBottom = r.fTop + SkIntToScalar(height); | 1025 r.fBottom = r.fTop + SkIntToScalar(height); |
1055 subRun->fMaskFormat = format; | 1026 subRun->fMaskFormat = format; |
1056 this->appendGlyphCommon(blob, &run, subRun, r, color, vertexStride, kA8_GrMa
skFormat == format, | 1027 this->appendGlyphCommon(blob, &run, subRun, r, color, vertexStride, kA8_GrMa
skFormat == format, |
1057 glyph); | 1028 glyph); |
1058 } | 1029 } |
1059 | 1030 |
1060 bool GrAtlasTextContext::dfAppendGlyph(GrAtlasTextBlob* blob, int runIndex, | 1031 bool GrAtlasTextContext::dfAppendGlyph(GrAtlasTextBlob* blob, int runIndex, |
1061 const SkGlyph& skGlyph, | 1032 const SkGlyph& skGlyph, |
1062 SkScalar sx, SkScalar sy, GrColor color, | 1033 SkScalar sx, SkScalar sy, GrColor color, |
1063 GrFontScaler* scaler, | 1034 GrFontScaler* scaler, |
1064 const SkIRect& clipRect, | |
1065 SkScalar textRatio, const SkMatrix& viewM
atrix) { | 1035 SkScalar textRatio, const SkMatrix& viewM
atrix) { |
1066 Run& run = blob->fRuns[runIndex]; | 1036 Run& run = blob->fRuns[runIndex]; |
1067 if (!fCurrStrike) { | 1037 if (!fCurrStrike) { |
1068 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler); | 1038 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler); |
1069 } | 1039 } |
1070 | 1040 |
1071 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), | 1041 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), |
1072 skGlyph.getSubXFixed(), | 1042 skGlyph.getSubXFixed(), |
1073 skGlyph.getSubYFixed(), | 1043 skGlyph.getSubYFixed(), |
1074 GrGlyph::kDistance_MaskStyle); | 1044 GrGlyph::kDistance_MaskStyle); |
(...skipping 14 matching lines...) Expand all Loading... |
1089 | 1059 |
1090 SkScalar scale = textRatio; | 1060 SkScalar scale = textRatio; |
1091 dx *= scale; | 1061 dx *= scale; |
1092 dy *= scale; | 1062 dy *= scale; |
1093 width *= scale; | 1063 width *= scale; |
1094 height *= scale; | 1064 height *= scale; |
1095 sx += dx; | 1065 sx += dx; |
1096 sy += dy; | 1066 sy += dy; |
1097 SkRect glyphRect = SkRect::MakeXYWH(sx, sy, width, height); | 1067 SkRect glyphRect = SkRect::MakeXYWH(sx, sy, width, height); |
1098 | 1068 |
1099 #if 0 | |
1100 // check if we clipped out | |
1101 SkRect dstRect; | |
1102 viewMatrix.mapRect(&dstRect, glyphRect); | |
1103 if (clipRect.quickReject(SkScalarTruncToInt(dstRect.left()), | |
1104 SkScalarTruncToInt(dstRect.top()), | |
1105 SkScalarTruncToInt(dstRect.right()), | |
1106 SkScalarTruncToInt(dstRect.bottom()))) { | |
1107 return true; | |
1108 } | |
1109 #endif | |
1110 | |
1111 // TODO combine with the above | 1069 // TODO combine with the above |
1112 // If the glyph is too large we fall back to paths | 1070 // If the glyph is too large we fall back to paths |
1113 if (glyph->fTooLargeForAtlas) { | 1071 if (glyph->fTooLargeForAtlas) { |
1114 this->appendGlyphPath(blob, glyph, scaler, skGlyph, sx - dx, sy - dy, sc
ale, true); | 1072 this->appendGlyphPath(blob, glyph, scaler, skGlyph, sx - dx, sy - dy, sc
ale, true); |
1115 return true; | 1073 return true; |
1116 } | 1074 } |
1117 | 1075 |
1118 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); | 1076 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); |
1119 if (!run.fInitialized) { | 1077 if (!run.fInitialized) { |
1120 subRun->fStrike.reset(SkRef(fCurrStrike)); | 1078 subRun->fStrike.reset(SkRef(fCurrStrike)); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1397 if (context->uniqueID() != gContextID) { | 1355 if (context->uniqueID() != gContextID) { |
1398 gContextID = context->uniqueID(); | 1356 gContextID = context->uniqueID(); |
1399 delete gTextContext; | 1357 delete gTextContext; |
1400 | 1358 |
1401 // We don't yet test the fall back to paths in the GrTextContext base cl
ass. This is mostly | 1359 // We don't yet test the fall back to paths in the GrTextContext base cl
ass. This is mostly |
1402 // because we don't really want to have a gpu device here. | 1360 // because we don't really want to have a gpu device here. |
1403 // We enable distance fields by twiddling a knob on the paint | 1361 // We enable distance fields by twiddling a knob on the paint |
1404 gTextContext = GrAtlasTextContext::Create(context, gSurfaceProps); | 1362 gTextContext = GrAtlasTextContext::Create(context, gSurfaceProps); |
1405 } | 1363 } |
1406 | 1364 |
1407 // create dummy render target | |
1408 GrSurfaceDesc desc; | |
1409 desc.fFlags = kRenderTarget_GrSurfaceFlag; | |
1410 desc.fWidth = 1024; | |
1411 desc.fHeight = 1024; | |
1412 desc.fConfig = kRGBA_8888_GrPixelConfig; | |
1413 desc.fSampleCnt = 0; | |
1414 SkAutoTUnref<GrTexture> texture(context->textureProvider()->createTexture(de
sc, true, nullptr, 0)); | |
1415 SkASSERT(texture); | |
1416 SkASSERT(nullptr != texture->asRenderTarget()); | |
1417 GrRenderTarget* rt = texture->asRenderTarget(); | |
1418 | |
1419 // Setup dummy SkPaint / GrPaint | 1365 // Setup dummy SkPaint / GrPaint |
1420 GrColor color = GrRandomColor(random); | 1366 GrColor color = GrRandomColor(random); |
1421 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | 1367 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); |
1422 SkPaint skPaint; | 1368 SkPaint skPaint; |
1423 skPaint.setColor(color); | 1369 skPaint.setColor(color); |
1424 skPaint.setLCDRenderText(random->nextBool()); | 1370 skPaint.setLCDRenderText(random->nextBool()); |
1425 skPaint.setAntiAlias(skPaint.isLCDRenderText() ? true : random->nextBool()); | 1371 skPaint.setAntiAlias(skPaint.isLCDRenderText() ? true : random->nextBool()); |
1426 skPaint.setSubpixelText(random->nextBool()); | 1372 skPaint.setSubpixelText(random->nextBool()); |
1427 | 1373 |
1428 GrPaint grPaint; | 1374 GrPaint grPaint; |
1429 if (!SkPaintToGrPaint(context, skPaint, viewMatrix, &grPaint)) { | 1375 if (!SkPaintToGrPaint(context, skPaint, viewMatrix, &grPaint)) { |
1430 SkFAIL("couldn't convert paint\n"); | 1376 SkFAIL("couldn't convert paint\n"); |
1431 } | 1377 } |
1432 | 1378 |
1433 const char* text = "The quick brown fox jumps over the lazy dog."; | 1379 const char* text = "The quick brown fox jumps over the lazy dog."; |
1434 int textLen = (int)strlen(text); | 1380 int textLen = (int)strlen(text); |
1435 | 1381 |
1436 // Setup clip | 1382 // Setup clip |
1437 GrClip clip; | 1383 GrClip clip; |
1438 SkIRect noClip = SkIRect::MakeLargest(); | 1384 SkIRect noClip = SkIRect::MakeLargest(); |
1439 | 1385 |
1440 // right now we don't handle textblobs, nor do we handle drawPosText. Since
we only | 1386 // right now we don't handle textblobs, nor do we handle drawPosText. Since
we only |
1441 // intend to test the batch with this unit test, that is okay. | 1387 // intend to test the batch with this unit test, that is okay. |
1442 SkAutoTUnref<GrAtlasTextBlob> blob( | 1388 SkAutoTUnref<GrAtlasTextBlob> blob( |
1443 gTextContext->createDrawTextBlob(rt, clip, grPaint, skPaint, viewMat
rix, text, | 1389 gTextContext->createDrawTextBlob(clip, grPaint, skPaint, viewMatrix,
text, |
1444 static_cast<size_t>(textLen), 0, 0,
noClip)); | 1390 static_cast<size_t>(textLen), 0, 0,
noClip)); |
1445 | 1391 |
1446 SkScalar transX = static_cast<SkScalar>(random->nextU()); | 1392 SkScalar transX = static_cast<SkScalar>(random->nextU()); |
1447 SkScalar transY = static_cast<SkScalar>(random->nextU()); | 1393 SkScalar transY = static_cast<SkScalar>(random->nextU()); |
1448 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0]
; | 1394 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0]
; |
1449 return gTextContext->createBatch(blob, info, textLen, 0, 0, color, transX, t
ransY, skPaint); | 1395 return gTextContext->createBatch(blob, info, textLen, 0, 0, color, transX, t
ransY, skPaint); |
1450 } | 1396 } |
1451 | 1397 |
1452 #endif | 1398 #endif |
OLD | NEW |