| 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 "GrDrawContext.h" | 9 #include "GrDrawContext.h" |
| 10 #include "GrDrawTarget.h" | 10 #include "GrDrawTarget.h" |
| 11 #include "GrFontScaler.h" | 11 #include "GrFontScaler.h" |
| 12 #include "GrStrokeInfo.h" | 12 #include "GrStrokeInfo.h" |
| 13 #include "GrTextBlobCache.h" | 13 #include "GrTextBlobCache.h" |
| 14 #include "GrTexturePriv.h" | 14 #include "GrTexturePriv.h" |
| 15 #include "GrTextUtils.h" |
| 15 #include "GrVertexBuffer.h" | 16 #include "GrVertexBuffer.h" |
| 16 | 17 |
| 17 #include "SkAutoKern.h" | 18 #include "SkAutoKern.h" |
| 18 #include "SkColorPriv.h" | 19 #include "SkColorPriv.h" |
| 19 #include "SkColorFilter.h" | 20 #include "SkColorFilter.h" |
| 20 #include "SkDistanceFieldGen.h" | 21 #include "SkDistanceFieldGen.h" |
| 21 #include "SkDraw.h" | 22 #include "SkDraw.h" |
| 22 #include "SkDrawFilter.h" | 23 #include "SkDrawFilter.h" |
| 23 #include "SkDrawProcs.h" | 24 #include "SkDrawProcs.h" |
| 24 #include "SkFindAndPlaceGlyph.h" | 25 #include "SkFindAndPlaceGlyph.h" |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 fallbackTxt, fallbackPos, scalarsPerPo
sition, dfOffset); | 327 fallbackTxt, fallbackPos, scalarsPerPo
sition, dfOffset); |
| 327 } | 328 } |
| 328 } else if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { | 329 } else if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { |
| 329 cacheBlob->fRuns[run].fDrawAsPaths = true; | 330 cacheBlob->fRuns[run].fDrawAsPaths = true; |
| 330 } else { | 331 } else { |
| 331 cacheBlob->setHasBitmap(); | 332 cacheBlob->setHasBitmap(); |
| 332 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPa
int, &viewMatrix, | 333 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPa
int, &viewMatrix, |
| 333 false); | 334 false); |
| 334 switch (it.positioning()) { | 335 switch (it.positioning()) { |
| 335 case SkTextBlob::kDefault_Positioning: | 336 case SkTextBlob::kDefault_Positioning: |
| 336 this->internalDrawBMPText(cacheBlob, run, cache, runPaint, c
olor, viewMatrix, | 337 GrTextUtils::DrawBmpText(cacheBlob, run, fContext->getBatchF
ontCache(), |
| 337 (const char *)it.glyphs(), textLen
, | 338 cache, runPaint, color, viewMatrix, |
| 338 x + offset.x(), y + offset.y()); | 339 (const char *)it.glyphs(), textLen, |
| 340 x + offset.x(), y + offset.y()); |
| 339 break; | 341 break; |
| 340 case SkTextBlob::kHorizontal_Positioning: | 342 case SkTextBlob::kHorizontal_Positioning: |
| 341 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint
, color, viewMatrix, | 343 GrTextUtils::DrawBmpPosText(cacheBlob, run, fContext->getBat
chFontCache(), |
| 342 (const char*)it.glyphs(), textL
en, it.pos(), 1, | 344 cache, runPaint, color, viewMatr
ix, |
| 343 SkPoint::Make(x, y + offset.y()
)); | 345 (const char*)it.glyphs(), textLe
n, it.pos(), 1, |
| 346 SkPoint::Make(x, y + offset.y())
); |
| 344 break; | 347 break; |
| 345 case SkTextBlob::kFull_Positioning: | 348 case SkTextBlob::kFull_Positioning: |
| 346 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint
, color, viewMatrix, | 349 GrTextUtils::DrawBmpPosText(cacheBlob, run, fContext->getBat
chFontCache(), |
| 347 (const char*)it.glyphs(), textL
en, it.pos(), 2, | 350 cache, runPaint, color, viewMatr
ix, |
| 348 SkPoint::Make(x, y)); | 351 (const char*)it.glyphs(), textLe
n, it.pos(), 2, |
| 352 SkPoint::Make(x, y)); |
| 349 break; | 353 break; |
| 350 } | 354 } |
| 351 SkGlyphCache::AttachCache(cache); | 355 SkGlyphCache::AttachCache(cache); |
| 352 } | 356 } |
| 353 | 357 |
| 354 if (drawFilter) { | 358 if (drawFilter) { |
| 355 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. | 359 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. |
| 356 runPaint = skPaint; | 360 runPaint = skPaint; |
| 357 } | 361 } |
| 358 } | 362 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 SkASSERT(fallbackTxt.count()); | 429 SkASSERT(fallbackTxt.count()); |
| 426 blob->setHasBitmap(); | 430 blob->setHasBitmap(); |
| 427 Run& run = blob->fRuns[runIndex]; | 431 Run& run = blob->fRuns[runIndex]; |
| 428 // Push back a new subrun to fill and set the override descriptor | 432 // Push back a new subrun to fill and set the override descriptor |
| 429 run.push_back(); | 433 run.push_back(); |
| 430 run.fOverrideDescriptor.reset(new SkAutoDescriptor); | 434 run.fOverrideDescriptor.reset(new SkAutoDescriptor); |
| 431 skPaint.getScalerContextDescriptor(run.fOverrideDescriptor, | 435 skPaint.getScalerContextDescriptor(run.fOverrideDescriptor, |
| 432 fSurfaceProps, &viewMatrix, false); | 436 fSurfaceProps, &viewMatrix, false); |
| 433 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, | 437 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, |
| 434 run.fOverrideDescriptor->get
Desc()); | 438 run.fOverrideDescriptor->get
Desc()); |
| 435 this->internalDrawBMPPosText(blob, runIndex, cache, skPaint, color, viewMatr
ix, | 439 GrTextUtils::DrawBmpPosText(blob, runIndex, fContext->getBatchFontCache(), c
ache, skPaint, |
| 436 fallbackTxt.begin(), fallbackTxt.count(), | 440 color, viewMatrix, fallbackTxt.begin(), fallback
Txt.count(), |
| 437 fallbackPos.begin(), scalarsPerPosition, offset
); | 441 fallbackPos.begin(), scalarsPerPosition, offset)
; |
| 438 SkGlyphCache::AttachCache(cache); | 442 SkGlyphCache::AttachCache(cache); |
| 439 } | 443 } |
| 440 | 444 |
| 441 inline GrAtlasTextBlob* | 445 inline GrAtlasTextBlob* |
| 442 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint, | 446 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint, |
| 443 const SkMatrix& viewMatrix, SkPaint* dfPaint, | 447 const SkMatrix& viewMatrix, SkPaint* dfPaint, |
| 444 SkScalar* textRatio) { | 448 SkScalar* textRatio) { |
| 445 GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::k
GrayTextVASize); | 449 GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::k
GrayTextVASize); |
| 446 | 450 |
| 447 *dfPaint = origPaint; | 451 *dfPaint = origPaint; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 477 &offset, skPaint); | 481 &offset, skPaint); |
| 478 if (fallbackTxt.count()) { | 482 if (fallbackTxt.count()) { |
| 479 this->fallbackDrawPosText(blob, 0, clip, paint.getColor(), skPaint,
viewMatrix, | 483 this->fallbackDrawPosText(blob, 0, clip, paint.getColor(), skPaint,
viewMatrix, |
| 480 fallbackTxt, fallbackPos, 2, offset); | 484 fallbackTxt, fallbackPos, 2, offset); |
| 481 } | 485 } |
| 482 } else { | 486 } else { |
| 483 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::kGrayTextVASiz
e); | 487 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::kGrayTextVASiz
e); |
| 484 blob->fViewMatrix = viewMatrix; | 488 blob->fViewMatrix = viewMatrix; |
| 485 | 489 |
| 486 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa
trix, false); | 490 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa
trix, false); |
| 487 this->internalDrawBMPText(blob, 0, cache, skPaint, paint.getColor(), vie
wMatrix, text, | 491 GrTextUtils::DrawBmpText(blob, 0, fContext->getBatchFontCache(), cache,
skPaint, |
| 488 byteLength, x, y); | 492 paint.getColor(), viewMatrix, text, byteLength,
x, y); |
| 489 SkGlyphCache::AttachCache(cache); | 493 SkGlyphCache::AttachCache(cache); |
| 490 } | 494 } |
| 491 return blob; | 495 return blob; |
| 492 } | 496 } |
| 493 | 497 |
| 494 inline GrAtlasTextBlob* | 498 inline GrAtlasTextBlob* |
| 495 GrAtlasTextContext::createDrawPosTextBlob(const GrClip& clip, | 499 GrAtlasTextContext::createDrawPosTextBlob(const GrClip& clip, |
| 496 const GrPaint& paint, const SkPaint& s
kPaint, | 500 const GrPaint& paint, const SkPaint& s
kPaint, |
| 497 const SkMatrix& viewMatrix, | 501 const SkMatrix& viewMatrix, |
| 498 const char text[], size_t byteLength, | 502 const char text[], size_t byteLength, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 512 byteLength, pos, scalarsPerPosition, offset, | 516 byteLength, pos, scalarsPerPosition, offset, |
| 513 textRatio, &fallbackTxt, &fallbackPos); | 517 textRatio, &fallbackTxt, &fallbackPos); |
| 514 if (fallbackTxt.count()) { | 518 if (fallbackTxt.count()) { |
| 515 this->fallbackDrawPosText(blob, 0, clip, paint.getColor(), skPaint,
viewMatrix, | 519 this->fallbackDrawPosText(blob, 0, clip, paint.getColor(), skPaint,
viewMatrix, |
| 516 fallbackTxt, fallbackPos, scalarsPerPositi
on, offset); | 520 fallbackTxt, fallbackPos, scalarsPerPositi
on, offset); |
| 517 } | 521 } |
| 518 } else { | 522 } else { |
| 519 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::kGrayTextVASiz
e); | 523 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::kGrayTextVASiz
e); |
| 520 blob->fViewMatrix = viewMatrix; | 524 blob->fViewMatrix = viewMatrix; |
| 521 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa
trix, false); | 525 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa
trix, false); |
| 522 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(),
viewMatrix, text, | 526 GrTextUtils::DrawBmpPosText(blob, 0, fContext->getBatchFontCache(), cach
e, skPaint, |
| 523 byteLength, pos, scalarsPerPosition, offset
); | 527 paint.getColor(), viewMatrix, text, |
| 528 byteLength, pos, scalarsPerPosition, offset)
; |
| 524 SkGlyphCache::AttachCache(cache); | 529 SkGlyphCache::AttachCache(cache); |
| 525 } | 530 } |
| 526 return blob; | 531 return blob; |
| 527 } | 532 } |
| 528 | 533 |
| 529 void GrAtlasTextContext::onDrawText(GrDrawContext* dc, | 534 void GrAtlasTextContext::onDrawText(GrDrawContext* dc, |
| 530 const GrClip& clip, | 535 const GrClip& clip, |
| 531 const GrPaint& paint, const SkPaint& skPaint
, | 536 const GrPaint& paint, const SkPaint& skPaint
, |
| 532 const SkMatrix& viewMatrix, | 537 const SkMatrix& viewMatrix, |
| 533 const char text[], size_t byteLength, | 538 const char text[], size_t byteLength, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 549 SkAutoTUnref<GrAtlasTextBlob> blob( | 554 SkAutoTUnref<GrAtlasTextBlob> blob( |
| 550 this->createDrawPosTextBlob(clip, paint, skPaint, viewMatrix, | 555 this->createDrawPosTextBlob(clip, paint, skPaint, viewMatrix, |
| 551 text, byteLength, | 556 text, byteLength, |
| 552 pos, scalarsPerPosition, | 557 pos, scalarsPerPosition, |
| 553 offset, regionClipBounds)); | 558 offset, regionClipBounds)); |
| 554 | 559 |
| 555 blob->flushThrowaway(fContext, dc, fSurfaceProps, fDistanceAdjustTable, skPa
int, paint, clip, | 560 blob->flushThrowaway(fContext, dc, fSurfaceProps, fDistanceAdjustTable, skPa
int, paint, clip, |
| 556 regionClipBounds); | 561 regionClipBounds); |
| 557 } | 562 } |
| 558 | 563 |
| 559 void GrAtlasTextContext::internalDrawBMPText(GrAtlasTextBlob* blob, int runIndex
, | |
| 560 SkGlyphCache* cache, const SkPaint&
skPaint, | |
| 561 GrColor color, | |
| 562 const SkMatrix& viewMatrix, | |
| 563 const char text[], size_t byteLengt
h, | |
| 564 SkScalar x, SkScalar y) { | |
| 565 SkASSERT(byteLength == 0 || text != nullptr); | |
| 566 | |
| 567 // nothing to draw | |
| 568 if (text == nullptr || byteLength == 0) { | |
| 569 return; | |
| 570 } | |
| 571 | |
| 572 fCurrStrike = nullptr; | |
| 573 | |
| 574 // Get GrFontScaler from cache | |
| 575 GrFontScaler* fontScaler = GetGrFontScaler(cache); | |
| 576 | |
| 577 SkFindAndPlaceGlyph::ProcessText( | |
| 578 skPaint.getTextEncoding(), text, byteLength, | |
| 579 {x, y}, viewMatrix, skPaint.getTextAlign(), | |
| 580 cache, | |
| 581 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { | |
| 582 position += rounding; | |
| 583 this->bmpAppendGlyph( | |
| 584 blob, runIndex, glyph, | |
| 585 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, | |
| 586 color, fontScaler); | |
| 587 } | |
| 588 ); | |
| 589 } | |
| 590 | |
| 591 void GrAtlasTextContext::internalDrawBMPPosText(GrAtlasTextBlob* blob, int runIn
dex, | |
| 592 SkGlyphCache* cache, const SkPai
nt& skPaint, | |
| 593 GrColor color, | |
| 594 const SkMatrix& viewMatrix, | |
| 595 const char text[], size_t byteLe
ngth, | |
| 596 const SkScalar pos[], int scalar
sPerPosition, | |
| 597 const SkPoint& offset) { | |
| 598 SkASSERT(byteLength == 0 || text != nullptr); | |
| 599 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | |
| 600 | |
| 601 // nothing to draw | |
| 602 if (text == nullptr || byteLength == 0) { | |
| 603 return; | |
| 604 } | |
| 605 | |
| 606 fCurrStrike = nullptr; | |
| 607 | |
| 608 // Get GrFontScaler from cache | |
| 609 GrFontScaler* fontScaler = GetGrFontScaler(cache); | |
| 610 | |
| 611 SkFindAndPlaceGlyph::ProcessPosText( | |
| 612 skPaint.getTextEncoding(), text, byteLength, | |
| 613 offset, viewMatrix, pos, scalarsPerPosition, | |
| 614 skPaint.getTextAlign(), cache, | |
| 615 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { | |
| 616 position += rounding; | |
| 617 this->bmpAppendGlyph( | |
| 618 blob, runIndex, glyph, | |
| 619 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, | |
| 620 color, fontScaler); | |
| 621 } | |
| 622 ); | |
| 623 } | |
| 624 | |
| 625 void GrAtlasTextContext::internalDrawDFText(GrAtlasTextBlob* blob, int runIndex, | 564 void GrAtlasTextContext::internalDrawDFText(GrAtlasTextBlob* blob, int runIndex, |
| 626 const SkPaint& skPaint, GrColor colo
r, | 565 const SkPaint& skPaint, GrColor colo
r, |
| 627 const SkMatrix& viewMatrix, | 566 const SkMatrix& viewMatrix, |
| 628 const char text[], size_t byteLength
, | 567 const char text[], size_t byteLength
, |
| 629 SkScalar x, SkScalar y, | 568 SkScalar x, SkScalar y, |
| 630 SkScalar textRatio, | 569 SkScalar textRatio, |
| 631 SkTDArray<char>* fallbackTxt, | 570 SkTDArray<char>* fallbackTxt, |
| 632 SkTDArray<SkScalar>* fallbackPos, | 571 SkTDArray<SkScalar>* fallbackPos, |
| 633 SkPoint* offset, | 572 SkPoint* offset, |
| 634 const SkPaint& origPaint) { | 573 const SkPaint& origPaint) { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 } | 716 } |
| 778 } | 717 } |
| 779 } | 718 } |
| 780 pos += scalarsPerPosition; | 719 pos += scalarsPerPosition; |
| 781 } | 720 } |
| 782 } | 721 } |
| 783 | 722 |
| 784 SkGlyphCache::AttachCache(cache); | 723 SkGlyphCache::AttachCache(cache); |
| 785 } | 724 } |
| 786 | 725 |
| 787 void GrAtlasTextContext::bmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex, | |
| 788 const SkGlyph& skGlyph, | |
| 789 int vx, int vy, GrColor color, GrFontSca
ler* scaler) { | |
| 790 if (!fCurrStrike) { | |
| 791 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler); | |
| 792 } | |
| 793 | |
| 794 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), | |
| 795 skGlyph.getSubXFixed(), | |
| 796 skGlyph.getSubYFixed(), | |
| 797 GrGlyph::kCoverage_MaskStyle); | |
| 798 GrGlyph* glyph = fCurrStrike->getGlyph(skGlyph, id, scaler); | |
| 799 if (!glyph) { | |
| 800 return; | |
| 801 } | |
| 802 | |
| 803 int x = vx + glyph->fBounds.fLeft; | |
| 804 int y = vy + glyph->fBounds.fTop; | |
| 805 | |
| 806 // keep them as ints until we've done the clip-test | |
| 807 int width = glyph->fBounds.width(); | |
| 808 int height = glyph->fBounds.height(); | |
| 809 | |
| 810 SkRect r; | |
| 811 r.fLeft = SkIntToScalar(x); | |
| 812 r.fTop = SkIntToScalar(y); | |
| 813 r.fRight = r.fLeft + SkIntToScalar(width); | |
| 814 r.fBottom = r.fTop + SkIntToScalar(height); | |
| 815 | |
| 816 blob->appendGlyph(runIndex, r, color, fCurrStrike, glyph, scaler, skGlyph, | |
| 817 SkIntToScalar(vx), SkIntToScalar(vy), 1.0f, false); | |
| 818 } | |
| 819 | |
| 820 bool GrAtlasTextContext::dfAppendGlyph(GrAtlasTextBlob* blob, int runIndex, | 726 bool GrAtlasTextContext::dfAppendGlyph(GrAtlasTextBlob* blob, int runIndex, |
| 821 const SkGlyph& skGlyph, | 727 const SkGlyph& skGlyph, |
| 822 SkScalar sx, SkScalar sy, GrColor color, | 728 SkScalar sx, SkScalar sy, GrColor color, |
| 823 GrFontScaler* scaler, | 729 GrFontScaler* scaler, |
| 824 SkScalar textRatio, const SkMatrix& viewM
atrix) { | 730 SkScalar textRatio, const SkMatrix& viewM
atrix) { |
| 825 if (!fCurrStrike) { | 731 if (!fCurrStrike) { |
| 826 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler); | 732 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler); |
| 827 } | 733 } |
| 828 | 734 |
| 829 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), | 735 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 | 813 |
| 908 SkScalar transX = static_cast<SkScalar>(random->nextU()); | 814 SkScalar transX = static_cast<SkScalar>(random->nextU()); |
| 909 SkScalar transY = static_cast<SkScalar>(random->nextU()); | 815 SkScalar transY = static_cast<SkScalar>(random->nextU()); |
| 910 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0]
; | 816 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0]
; |
| 911 return blob->createBatch(info, textLen, 0, 0, color, transX, transY, skPaint
, | 817 return blob->createBatch(info, textLen, 0, 0, color, transX, transY, skPaint
, |
| 912 gSurfaceProps, gTextContext->dfAdjustTable(), | 818 gSurfaceProps, gTextContext->dfAdjustTable(), |
| 913 context->getBatchFontCache()); | 819 context->getBatchFontCache()); |
| 914 } | 820 } |
| 915 | 821 |
| 916 #endif | 822 #endif |
| OLD | NEW |