| 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" | |
| 10 #include "GrDrawContext.h" | 9 #include "GrDrawContext.h" |
| 11 #include "GrDrawTarget.h" | 10 #include "GrDrawTarget.h" |
| 12 #include "GrFontScaler.h" | 11 #include "GrFontScaler.h" |
| 13 #include "GrStrokeInfo.h" | 12 #include "GrStrokeInfo.h" |
| 14 #include "GrTextBlobCache.h" | 13 #include "GrTextBlobCache.h" |
| 15 #include "GrTexturePriv.h" | 14 #include "GrTexturePriv.h" |
| 16 #include "GrVertexBuffer.h" | 15 #include "GrVertexBuffer.h" |
| 17 | 16 |
| 18 #include "SkAutoKern.h" | 17 #include "SkAutoKern.h" |
| 19 #include "SkColorPriv.h" | 18 #include "SkColorPriv.h" |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 if (canCache) { | 196 if (canCache) { |
| 198 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, | 197 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, |
| 199 GrAtlasTextBlob::kGra
yTextVASize))); | 198 GrAtlasTextBlob::kGra
yTextVASize))); |
| 200 } else { | 199 } else { |
| 201 cacheBlob.reset(fCache->createBlob(blob, GrAtlasTextBlob::kGrayTextV
ASize)); | 200 cacheBlob.reset(fCache->createBlob(blob, GrAtlasTextBlob::kGrayTextV
ASize)); |
| 202 } | 201 } |
| 203 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat
rix, | 202 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat
rix, |
| 204 blob, x, y, drawFilter, clip); | 203 blob, x, y, drawFilter, clip); |
| 205 } | 204 } |
| 206 | 205 |
| 207 this->flush(blob, cacheBlob, dc, skPaint, grPaint, drawFilter, | 206 cacheBlob->flushCached(blob, fContext, dc, this, fSurfaceProps, fDistanceAdj
ustTable, skPaint, |
| 208 clip, viewMatrix, clipBounds, x, y, transX, transY); | 207 grPaint, drawFilter, clip, viewMatrix, clipBounds, x,
y, transX, transY); |
| 209 } | 208 } |
| 210 | 209 |
| 211 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, | 210 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, |
| 212 const SkMatrix& viewMatr
ix) { | 211 const SkMatrix& viewMatr
ix) { |
| 213 // TODO: support perspective (need getMaxScale replacement) | 212 // TODO: support perspective (need getMaxScale replacement) |
| 214 if (viewMatrix.hasPerspective()) { | 213 if (viewMatrix.hasPerspective()) { |
| 215 return false; | 214 return false; |
| 216 } | 215 } |
| 217 | 216 |
| 218 SkScalar maxScale = viewMatrix.getMaxScale(); | 217 SkScalar maxScale = viewMatrix.getMaxScale(); |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 | 528 |
| 530 void GrAtlasTextContext::onDrawText(GrDrawContext* dc, | 529 void GrAtlasTextContext::onDrawText(GrDrawContext* dc, |
| 531 const GrClip& clip, | 530 const GrClip& clip, |
| 532 const GrPaint& paint, const SkPaint& skPaint
, | 531 const GrPaint& paint, const SkPaint& skPaint
, |
| 533 const SkMatrix& viewMatrix, | 532 const SkMatrix& viewMatrix, |
| 534 const char text[], size_t byteLength, | 533 const char text[], size_t byteLength, |
| 535 SkScalar x, SkScalar y, const SkIRect& regio
nClipBounds) { | 534 SkScalar x, SkScalar y, const SkIRect& regio
nClipBounds) { |
| 536 SkAutoTUnref<GrAtlasTextBlob> blob( | 535 SkAutoTUnref<GrAtlasTextBlob> blob( |
| 537 this->createDrawTextBlob(clip, paint, skPaint, viewMatrix, | 536 this->createDrawTextBlob(clip, paint, skPaint, viewMatrix, |
| 538 text, byteLength, x, y, regionClipBounds)); | 537 text, byteLength, x, y, regionClipBounds)); |
| 539 this->flush(blob, dc, skPaint, paint, clip, regionClipBounds); | 538 blob->flushThrowaway(fContext, dc, fSurfaceProps, fDistanceAdjustTable, skPa
int, paint, |
| 539 clip, regionClipBounds); |
| 540 } | 540 } |
| 541 | 541 |
| 542 void GrAtlasTextContext::onDrawPosText(GrDrawContext* dc, | 542 void GrAtlasTextContext::onDrawPosText(GrDrawContext* dc, |
| 543 const GrClip& clip, | 543 const GrClip& clip, |
| 544 const GrPaint& paint, const SkPaint& skPa
int, | 544 const GrPaint& paint, const SkPaint& skPa
int, |
| 545 const SkMatrix& viewMatrix, | 545 const SkMatrix& viewMatrix, |
| 546 const char text[], size_t byteLength, | 546 const char text[], size_t byteLength, |
| 547 const SkScalar pos[], int scalarsPerPosit
ion, | 547 const SkScalar pos[], int scalarsPerPosit
ion, |
| 548 const SkPoint& offset, const SkIRect& reg
ionClipBounds) { | 548 const SkPoint& offset, const SkIRect& reg
ionClipBounds) { |
| 549 SkAutoTUnref<GrAtlasTextBlob> blob( | 549 SkAutoTUnref<GrAtlasTextBlob> blob( |
| 550 this->createDrawPosTextBlob(clip, paint, skPaint, viewMatrix, | 550 this->createDrawPosTextBlob(clip, paint, skPaint, viewMatrix, |
| 551 text, byteLength, | 551 text, byteLength, |
| 552 pos, scalarsPerPosition, | 552 pos, scalarsPerPosition, |
| 553 offset, regionClipBounds)); | 553 offset, regionClipBounds)); |
| 554 | 554 |
| 555 this->flush(blob, dc, skPaint, paint, clip, regionClipBounds); | 555 blob->flushThrowaway(fContext, dc, fSurfaceProps, fDistanceAdjustTable, skPa
int, paint, clip, |
| 556 regionClipBounds); |
| 556 } | 557 } |
| 557 | 558 |
| 558 void GrAtlasTextContext::internalDrawBMPText(GrAtlasTextBlob* blob, int runIndex
, | 559 void GrAtlasTextContext::internalDrawBMPText(GrAtlasTextBlob* blob, int runIndex
, |
| 559 SkGlyphCache* cache, const SkPaint&
skPaint, | 560 SkGlyphCache* cache, const SkPaint&
skPaint, |
| 560 GrColor color, | 561 GrColor color, |
| 561 const SkMatrix& viewMatrix, | 562 const SkMatrix& viewMatrix, |
| 562 const char text[], size_t byteLengt
h, | 563 const char text[], size_t byteLengt
h, |
| 563 SkScalar x, SkScalar y) { | 564 SkScalar x, SkScalar y) { |
| 564 SkASSERT(byteLength == 0 || text != nullptr); | 565 SkASSERT(byteLength == 0 || text != nullptr); |
| 565 | 566 |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 height *= scale; | 852 height *= scale; |
| 852 sx += dx; | 853 sx += dx; |
| 853 sy += dy; | 854 sy += dy; |
| 854 SkRect glyphRect = SkRect::MakeXYWH(sx, sy, width, height); | 855 SkRect glyphRect = SkRect::MakeXYWH(sx, sy, width, height); |
| 855 | 856 |
| 856 blob->appendGlyph(runIndex, glyphRect, color, fCurrStrike, glyph, scaler, sk
Glyph, | 857 blob->appendGlyph(runIndex, glyphRect, color, fCurrStrike, glyph, scaler, sk
Glyph, |
| 857 sx - dx, sy - dy, scale, true); | 858 sx - dx, sy - dy, scale, true); |
| 858 return true; | 859 return true; |
| 859 } | 860 } |
| 860 | 861 |
| 861 void GrAtlasTextContext::flushRunAsPaths(GrDrawContext* dc, | |
| 862 const SkTextBlobRunIterator& it, | |
| 863 const GrClip& clip, const SkPaint& skPa
int, | |
| 864 SkDrawFilter* drawFilter, const SkMatri
x& viewMatrix, | |
| 865 const SkIRect& clipBounds, SkScalar x,
SkScalar y) { | |
| 866 SkPaint runPaint = skPaint; | |
| 867 | |
| 868 size_t textLen = it.glyphCount() * sizeof(uint16_t); | |
| 869 const SkPoint& offset = it.offset(); | |
| 870 | |
| 871 it.applyFontToPaint(&runPaint); | |
| 872 | |
| 873 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type))
{ | |
| 874 return; | |
| 875 } | |
| 876 | |
| 877 runPaint.setFlags(FilterTextFlags(fSurfaceProps, runPaint)); | |
| 878 | |
| 879 switch (it.positioning()) { | |
| 880 case SkTextBlob::kDefault_Positioning: | |
| 881 this->drawTextAsPath(dc, clip, runPaint, viewMatrix, | |
| 882 (const char *)it.glyphs(), | |
| 883 textLen, x + offset.x(), y + offset.y(), clipBo
unds); | |
| 884 break; | |
| 885 case SkTextBlob::kHorizontal_Positioning: | |
| 886 this->drawPosTextAsPath(dc, clip, runPaint, viewMatrix, | |
| 887 (const char*)it.glyphs(), | |
| 888 textLen, it.pos(), 1, SkPoint::Make(x, y + o
ffset.y()), | |
| 889 clipBounds); | |
| 890 break; | |
| 891 case SkTextBlob::kFull_Positioning: | |
| 892 this->drawPosTextAsPath(dc, clip, runPaint, viewMatrix, | |
| 893 (const char*)it.glyphs(), | |
| 894 textLen, it.pos(), 2, SkPoint::Make(x, y), c
lipBounds); | |
| 895 break; | |
| 896 } | |
| 897 } | |
| 898 | |
| 899 inline GrDrawBatch* | |
| 900 GrAtlasTextContext::createBatch(GrAtlasTextBlob* cacheBlob, const PerSubRunInfo&
info, | |
| 901 int glyphCount, int run, int subRun, | |
| 902 GrColor color, SkScalar transX, SkScalar transY, | |
| 903 const SkPaint& skPaint) { | |
| 904 GrMaskFormat format = info.maskFormat(); | |
| 905 GrColor subRunColor; | |
| 906 if (kARGB_GrMaskFormat == format) { | |
| 907 uint8_t paintAlpha = skPaint.getAlpha(); | |
| 908 subRunColor = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAl
pha); | |
| 909 } else { | |
| 910 subRunColor = color; | |
| 911 } | |
| 912 | |
| 913 GrAtlasTextBatch* batch; | |
| 914 if (info.drawAsDistanceFields()) { | |
| 915 SkColor filteredColor; | |
| 916 SkColorFilter* colorFilter = skPaint.getColorFilter(); | |
| 917 if (colorFilter) { | |
| 918 filteredColor = colorFilter->filterColor(skPaint.getColor()); | |
| 919 } else { | |
| 920 filteredColor = skPaint.getColor(); | |
| 921 } | |
| 922 bool useBGR = SkPixelGeometryIsBGR(fSurfaceProps.pixelGeometry()); | |
| 923 batch = GrAtlasTextBatch::CreateDistanceField(glyphCount, fContext->getB
atchFontCache(), | |
| 924 fDistanceAdjustTable, filt
eredColor, | |
| 925 info.hasUseLCDText(), useB
GR); | |
| 926 } else { | |
| 927 batch = GrAtlasTextBatch::CreateBitmap(format, glyphCount, fContext->get
BatchFontCache()); | |
| 928 } | |
| 929 GrAtlasTextBatch::Geometry& geometry = batch->geometry(); | |
| 930 geometry.fBlob = SkRef(cacheBlob); | |
| 931 geometry.fRun = run; | |
| 932 geometry.fSubRun = subRun; | |
| 933 geometry.fColor = subRunColor; | |
| 934 geometry.fTransX = transX; | |
| 935 geometry.fTransY = transY; | |
| 936 batch->init(); | |
| 937 | |
| 938 return batch; | |
| 939 } | |
| 940 | |
| 941 inline void GrAtlasTextContext::flushRun(GrDrawContext* dc, GrPipelineBuilder* p
ipelineBuilder, | |
| 942 GrAtlasTextBlob* cacheBlob, int run, Gr
Color color, | |
| 943 SkScalar transX, SkScalar transY, | |
| 944 const SkPaint& skPaint) { | |
| 945 for (int subRun = 0; subRun < cacheBlob->fRuns[run].fSubRunInfo.count(); sub
Run++) { | |
| 946 const PerSubRunInfo& info = cacheBlob->fRuns[run].fSubRunInfo[subRun]; | |
| 947 int glyphCount = info.glyphCount(); | |
| 948 if (0 == glyphCount) { | |
| 949 continue; | |
| 950 } | |
| 951 | |
| 952 SkAutoTUnref<GrDrawBatch> batch(this->createBatch(cacheBlob, info, glyph
Count, run, | |
| 953 subRun, color, transX,
transY, | |
| 954 skPaint)); | |
| 955 dc->drawBatch(pipelineBuilder, batch); | |
| 956 } | |
| 957 } | |
| 958 | |
| 959 inline void GrAtlasTextContext::flushBigGlyphs(GrAtlasTextBlob* cacheBlob, | |
| 960 GrDrawContext* dc, | |
| 961 const GrClip& clip, const SkPaint
& skPaint, | |
| 962 SkScalar transX, SkScalar transY, | |
| 963 const SkIRect& clipBounds) { | |
| 964 if (!cacheBlob->fBigGlyphs.count()) { | |
| 965 return; | |
| 966 } | |
| 967 | |
| 968 for (int i = 0; i < cacheBlob->fBigGlyphs.count(); i++) { | |
| 969 GrAtlasTextBlob::BigGlyph& bigGlyph = cacheBlob->fBigGlyphs[i]; | |
| 970 bigGlyph.fVx += transX; | |
| 971 bigGlyph.fVy += transY; | |
| 972 SkMatrix ctm; | |
| 973 ctm.setScale(bigGlyph.fScale, bigGlyph.fScale); | |
| 974 ctm.postTranslate(bigGlyph.fVx, bigGlyph.fVy); | |
| 975 if (bigGlyph.fApplyVM) { | |
| 976 ctm.postConcat(cacheBlob->fViewMatrix); | |
| 977 } | |
| 978 | |
| 979 GrBlurUtils::drawPathWithMaskFilter(fContext, dc, clip, bigGlyph.fPath, | |
| 980 skPaint, ctm, nullptr, clipBounds, f
alse); | |
| 981 } | |
| 982 } | |
| 983 | |
| 984 void GrAtlasTextContext::flush(const SkTextBlob* blob, | |
| 985 GrAtlasTextBlob* cacheBlob, | |
| 986 GrDrawContext* dc, | |
| 987 const SkPaint& skPaint, | |
| 988 const GrPaint& grPaint, | |
| 989 SkDrawFilter* drawFilter, | |
| 990 const GrClip& clip, | |
| 991 const SkMatrix& viewMatrix, | |
| 992 const SkIRect& clipBounds, | |
| 993 SkScalar x, SkScalar y, | |
| 994 SkScalar transX, SkScalar transY) { | |
| 995 // We loop through the runs of the blob, flushing each. If any run is too l
arge, then we flush | |
| 996 // it as paths | |
| 997 GrPipelineBuilder pipelineBuilder(grPaint, dc->accessRenderTarget(), clip); | |
| 998 | |
| 999 GrColor color = grPaint.getColor(); | |
| 1000 | |
| 1001 SkTextBlobRunIterator it(blob); | |
| 1002 for (int run = 0; !it.done(); it.next(), run++) { | |
| 1003 if (cacheBlob->fRuns[run].fDrawAsPaths) { | |
| 1004 this->flushRunAsPaths(dc, it, clip, skPaint, | |
| 1005 drawFilter, viewMatrix, clipBounds, x, y); | |
| 1006 continue; | |
| 1007 } | |
| 1008 cacheBlob->fRuns[run].fVertexBounds.offset(transX, transY); | |
| 1009 this->flushRun(dc, &pipelineBuilder, cacheBlob, run, color, | |
| 1010 transX, transY, skPaint); | |
| 1011 } | |
| 1012 | |
| 1013 // Now flush big glyphs | |
| 1014 this->flushBigGlyphs(cacheBlob, dc, clip, skPaint, transX, transY, clipBound
s); | |
| 1015 } | |
| 1016 | |
| 1017 void GrAtlasTextContext::flush(GrAtlasTextBlob* cacheBlob, | |
| 1018 GrDrawContext* dc, | |
| 1019 const SkPaint& skPaint, | |
| 1020 const GrPaint& grPaint, | |
| 1021 const GrClip& clip, | |
| 1022 const SkIRect& clipBounds) { | |
| 1023 GrPipelineBuilder pipelineBuilder(grPaint, dc->accessRenderTarget(), clip); | |
| 1024 | |
| 1025 GrColor color = grPaint.getColor(); | |
| 1026 for (int run = 0; run < cacheBlob->fRunCount; run++) { | |
| 1027 this->flushRun(dc, &pipelineBuilder, cacheBlob, run, color, 0, 0, skPain
t); | |
| 1028 } | |
| 1029 | |
| 1030 // Now flush big glyphs | |
| 1031 this->flushBigGlyphs(cacheBlob, dc, clip, skPaint, 0, 0, clipBounds); | |
| 1032 } | |
| 1033 | |
| 1034 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 862 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 1035 | 863 |
| 1036 #ifdef GR_TEST_UTILS | 864 #ifdef GR_TEST_UTILS |
| 1037 | 865 |
| 1038 DRAW_BATCH_TEST_DEFINE(TextBlobBatch) { | 866 DRAW_BATCH_TEST_DEFINE(TextBlobBatch) { |
| 1039 static uint32_t gContextID = SK_InvalidGenID; | 867 static uint32_t gContextID = SK_InvalidGenID; |
| 1040 static GrAtlasTextContext* gTextContext = nullptr; | 868 static GrAtlasTextContext* gTextContext = nullptr; |
| 1041 static SkSurfaceProps gSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType
); | 869 static SkSurfaceProps gSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType
); |
| 1042 | 870 |
| 1043 if (context->uniqueID() != gContextID) { | 871 if (context->uniqueID() != gContextID) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1073 | 901 |
| 1074 // right now we don't handle textblobs, nor do we handle drawPosText. Since
we only | 902 // right now we don't handle textblobs, nor do we handle drawPosText. Since
we only |
| 1075 // intend to test the batch with this unit test, that is okay. | 903 // intend to test the batch with this unit test, that is okay. |
| 1076 SkAutoTUnref<GrAtlasTextBlob> blob( | 904 SkAutoTUnref<GrAtlasTextBlob> blob( |
| 1077 gTextContext->createDrawTextBlob(clip, grPaint, skPaint, viewMatrix,
text, | 905 gTextContext->createDrawTextBlob(clip, grPaint, skPaint, viewMatrix,
text, |
| 1078 static_cast<size_t>(textLen), 0, 0,
noClip)); | 906 static_cast<size_t>(textLen), 0, 0,
noClip)); |
| 1079 | 907 |
| 1080 SkScalar transX = static_cast<SkScalar>(random->nextU()); | 908 SkScalar transX = static_cast<SkScalar>(random->nextU()); |
| 1081 SkScalar transY = static_cast<SkScalar>(random->nextU()); | 909 SkScalar transY = static_cast<SkScalar>(random->nextU()); |
| 1082 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0]
; | 910 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0]
; |
| 1083 return gTextContext->createBatch(blob, info, textLen, 0, 0, color, transX, t
ransY, skPaint); | 911 return blob->createBatch(info, textLen, 0, 0, color, transX, transY, skPaint
, |
| 912 gSurfaceProps, gTextContext->dfAdjustTable(), |
| 913 context->getBatchFontCache()); |
| 1084 } | 914 } |
| 1085 | 915 |
| 1086 #endif | 916 #endif |
| OLD | NEW |