| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2015 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #include "GrTextUtils.h" | |
| 9 | |
| 10 #include "GrAtlasTextBlob.h" | |
| 11 #include "GrBatchFontCache.h" | |
| 12 #include "GrBlurUtils.h" | |
| 13 #include "GrContext.h" | |
| 14 #include "GrDrawContext.h" | |
| 15 #include "GrTextContext.h" | |
| 16 #include "SkDrawProcs.h" | |
| 17 #include "SkFindAndPlaceGlyph.h" | |
| 18 #include "SkGlyphCache.h" | |
| 19 #include "SkPaint.h" | |
| 20 #include "SkRect.h" | |
| 21 #include "SkTextMapStateProc.h" | |
| 22 #include "SkTextToPathIter.h" | |
| 23 | |
| 24 void GrTextUtils::DrawBmpText(GrAtlasTextBlob* blob, int runIndex, | |
| 25 GrBatchFontCache* fontCache, | |
| 26 SkGlyphCache* cache, const SkPaint& skPaint, | |
| 27 GrColor color, | |
| 28 const SkMatrix& viewMatrix, | |
| 29 const char text[], size_t byteLength, | |
| 30 SkScalar x, SkScalar y) { | |
| 31 SkASSERT(byteLength == 0 || text != nullptr); | |
| 32 | |
| 33 // nothing to draw | |
| 34 if (text == nullptr || byteLength == 0) { | |
| 35 return; | |
| 36 } | |
| 37 | |
| 38 GrBatchTextStrike* currStrike = nullptr; | |
| 39 | |
| 40 // Get GrFontScaler from cache | |
| 41 GrFontScaler* fontScaler = GrTextContext::GetGrFontScaler(cache); | |
| 42 | |
| 43 SkFindAndPlaceGlyph::ProcessText( | |
| 44 skPaint.getTextEncoding(), text, byteLength, | |
| 45 {x, y}, viewMatrix, skPaint.getTextAlign(), | |
| 46 cache, | |
| 47 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { | |
| 48 position += rounding; | |
| 49 BmpAppendGlyph( | |
| 50 blob, runIndex, fontCache, &currStrike, glyph, | |
| 51 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, | |
| 52 color, fontScaler); | |
| 53 } | |
| 54 ); | |
| 55 } | |
| 56 | |
| 57 void GrTextUtils::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex, | |
| 58 GrBatchFontCache* fontCache, | |
| 59 SkGlyphCache* cache, const SkPaint& skPaint, | |
| 60 GrColor color, | |
| 61 const SkMatrix& viewMatrix, | |
| 62 const char text[], size_t byteLength, | |
| 63 const SkScalar pos[], int scalarsPerPosition, | |
| 64 const SkPoint& offset) { | |
| 65 SkASSERT(byteLength == 0 || text != nullptr); | |
| 66 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | |
| 67 | |
| 68 // nothing to draw | |
| 69 if (text == nullptr || byteLength == 0) { | |
| 70 return; | |
| 71 } | |
| 72 | |
| 73 GrBatchTextStrike* currStrike = nullptr; | |
| 74 | |
| 75 // Get GrFontScaler from cache | |
| 76 GrFontScaler* fontScaler = GrTextContext::GetGrFontScaler(cache); | |
| 77 | |
| 78 SkFindAndPlaceGlyph::ProcessPosText( | |
| 79 skPaint.getTextEncoding(), text, byteLength, | |
| 80 offset, viewMatrix, pos, scalarsPerPosition, | |
| 81 skPaint.getTextAlign(), cache, | |
| 82 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { | |
| 83 position += rounding; | |
| 84 BmpAppendGlyph( | |
| 85 blob, runIndex, fontCache, &currStrike, glyph, | |
| 86 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, | |
| 87 color, fontScaler); | |
| 88 } | |
| 89 ); | |
| 90 } | |
| 91 | |
| 92 void GrTextUtils::BmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex, | |
| 93 GrBatchFontCache* fontCache, | |
| 94 GrBatchTextStrike** strike, const SkGlyph& skGl
yph, | |
| 95 int vx, int vy, GrColor color, GrFontScaler* sc
aler) { | |
| 96 if (!*strike) { | |
| 97 *strike = fontCache->getStrike(scaler); | |
| 98 } | |
| 99 | |
| 100 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), | |
| 101 skGlyph.getSubXFixed(), | |
| 102 skGlyph.getSubYFixed(), | |
| 103 GrGlyph::kCoverage_MaskStyle); | |
| 104 GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, scaler); | |
| 105 if (!glyph) { | |
| 106 return; | |
| 107 } | |
| 108 | |
| 109 int x = vx + glyph->fBounds.fLeft; | |
| 110 int y = vy + glyph->fBounds.fTop; | |
| 111 | |
| 112 // keep them as ints until we've done the clip-test | |
| 113 int width = glyph->fBounds.width(); | |
| 114 int height = glyph->fBounds.height(); | |
| 115 | |
| 116 SkRect r; | |
| 117 r.fLeft = SkIntToScalar(x); | |
| 118 r.fTop = SkIntToScalar(y); | |
| 119 r.fRight = r.fLeft + SkIntToScalar(width); | |
| 120 r.fBottom = r.fTop + SkIntToScalar(height); | |
| 121 | |
| 122 blob->appendGlyph(runIndex, r, color, *strike, glyph, scaler, skGlyph, | |
| 123 SkIntToScalar(vx), SkIntToScalar(vy), 1.0f, false); | |
| 124 } | |
| 125 | |
| 126 void GrTextUtils::DrawTextAsPath(GrContext* context, GrDrawContext* dc, | |
| 127 const GrClip& clip, | |
| 128 const SkPaint& skPaint, const SkMatrix& viewMat
rix, | |
| 129 const char text[], size_t byteLength, SkScalar
x, SkScalar y, | |
| 130 const SkIRect& clipBounds) { | |
| 131 SkTextToPathIter iter(text, byteLength, skPaint, true); | |
| 132 | |
| 133 SkMatrix matrix; | |
| 134 matrix.setScale(iter.getPathScale(), iter.getPathScale()); | |
| 135 matrix.postTranslate(x, y); | |
| 136 | |
| 137 const SkPath* iterPath; | |
| 138 SkScalar xpos, prevXPos = 0; | |
| 139 | |
| 140 while (iter.next(&iterPath, &xpos)) { | |
| 141 matrix.postTranslate(xpos - prevXPos, 0); | |
| 142 if (iterPath) { | |
| 143 const SkPaint& pnt = iter.getPaint(); | |
| 144 GrBlurUtils::drawPathWithMaskFilter(context, dc, clip, *iterPath, | |
| 145 pnt, viewMatrix, &matrix, clipBo
unds, false); | |
| 146 } | |
| 147 prevXPos = xpos; | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 void GrTextUtils::DrawPosTextAsPath(GrContext* context, | |
| 152 GrDrawContext* dc, | |
| 153 const SkSurfaceProps& props, | |
| 154 const GrClip& clip, | |
| 155 const SkPaint& origPaint, const SkMatrix& vi
ewMatrix, | |
| 156 const char text[], size_t byteLength, | |
| 157 const SkScalar pos[], int scalarsPerPosition
, | |
| 158 const SkPoint& offset, const SkIRect& clipBo
unds) { | |
| 159 // setup our std paint, in hopes of getting hits in the cache | |
| 160 SkPaint paint(origPaint); | |
| 161 SkScalar matrixScale = paint.setupForAsPaths(); | |
| 162 | |
| 163 SkMatrix matrix; | |
| 164 matrix.setScale(matrixScale, matrixScale); | |
| 165 | |
| 166 // Temporarily jam in kFill, so we only ever ask for the raw outline from th
e cache. | |
| 167 paint.setStyle(SkPaint::kFill_Style); | |
| 168 paint.setPathEffect(nullptr); | |
| 169 | |
| 170 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); | |
| 171 SkAutoGlyphCache autoCache(paint, &props, nullptr); | |
| 172 SkGlyphCache* cache = autoCache.getCache(); | |
| 173 | |
| 174 const char* stop = text + byteLength; | |
| 175 SkTextAlignProc alignProc(paint.getTextAlign()); | |
| 176 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); | |
| 177 | |
| 178 // Now restore the original settings, so we "draw" with whatever style/strok
ing. | |
| 179 paint.setStyle(origPaint.getStyle()); | |
| 180 paint.setPathEffect(origPaint.getPathEffect()); | |
| 181 | |
| 182 while (text < stop) { | |
| 183 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | |
| 184 if (glyph.fWidth) { | |
| 185 const SkPath* path = cache->findPath(glyph); | |
| 186 if (path) { | |
| 187 SkPoint tmsLoc; | |
| 188 tmsProc(pos, &tmsLoc); | |
| 189 SkPoint loc; | |
| 190 alignProc(tmsLoc, glyph, &loc); | |
| 191 | |
| 192 matrix[SkMatrix::kMTransX] = loc.fX; | |
| 193 matrix[SkMatrix::kMTransY] = loc.fY; | |
| 194 GrBlurUtils::drawPathWithMaskFilter(context, dc, clip, *path, pa
int, | |
| 195 viewMatrix, &matrix, clipBou
nds, false); | |
| 196 } | |
| 197 } | |
| 198 pos += scalarsPerPosition; | |
| 199 } | |
| 200 } | |
| OLD | NEW |