Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: src/gpu/GrStencilAndCoverTextContext.cpp

Issue 1375353004: Add TextRun object to nvpr text (Closed) Base URL: https://skia.googlesource.com/skia.git@upload1_simplify
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 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 7
8 #include "GrStencilAndCoverTextContext.h" 8 #include "GrStencilAndCoverTextContext.h"
9 #include "GrAtlasTextContext.h" 9 #include "GrAtlasTextContext.h"
10 #include "GrDrawContext.h" 10 #include "GrDrawContext.h"
11 #include "GrDrawTarget.h" 11 #include "GrDrawTarget.h"
12 #include "GrPath.h" 12 #include "GrPath.h"
13 #include "GrPathRange.h" 13 #include "GrPathRange.h"
14 #include "GrResourceProvider.h" 14 #include "GrResourceProvider.h"
15 #include "SkAutoKern.h" 15 #include "SkAutoKern.h"
16 #include "SkDraw.h" 16 #include "SkDraw.h"
17 #include "SkDrawProcs.h" 17 #include "SkDrawProcs.h"
18 #include "SkGlyphCache.h" 18 #include "SkGlyphCache.h"
19 #include "SkGpuDevice.h" 19 #include "SkGpuDevice.h"
20 #include "SkPath.h" 20 #include "SkPath.h"
21 #include "SkTextMapStateProc.h" 21 #include "SkTextMapStateProc.h"
22 #include "SkTextFormatParams.h" 22 #include "SkTextFormatParams.h"
23 23
24 #include "batches/GrDrawPathBatch.h" 24 #include "batches/GrDrawPathBatch.h"
25 25
26 GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(GrContext* context, 26 GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(GrContext* context,
27 const SkSurfaceProps& surfaceProps) 27 const SkSurfaceProps& surfaceProps)
28 : INHERITED(context, surfaceProps) 28 : INHERITED(context, surfaceProps) {
29 , fDraw(nullptr)
30 , fStroke(SkStrokeRec::kFill_InitStyle) {
31 } 29 }
32 30
33 GrStencilAndCoverTextContext* 31 GrStencilAndCoverTextContext*
34 GrStencilAndCoverTextContext::Create(GrContext* context, const SkSurfaceProps& s urfaceProps) { 32 GrStencilAndCoverTextContext::Create(GrContext* context, const SkSurfaceProps& s urfaceProps) {
35 GrStencilAndCoverTextContext* textContext = 33 GrStencilAndCoverTextContext* textContext =
36 new GrStencilAndCoverTextContext(context, surfaceProps); 34 new GrStencilAndCoverTextContext(context, surfaceProps);
37 textContext->fFallbackTextContext = GrAtlasTextContext::Create(context, surf aceProps); 35 textContext->fFallbackTextContext = GrAtlasTextContext::Create(context, surf aceProps);
38 36
39 return textContext; 37 return textContext;
40 } 38 }
(...skipping 23 matching lines...) Expand all
64 62
65 void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget* rt, 63 void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget* rt,
66 const GrClip& clip, 64 const GrClip& clip,
67 const GrPaint& paint, 65 const GrPaint& paint,
68 const SkPaint& skPaint, 66 const SkPaint& skPaint,
69 const SkMatrix& viewMatrix, 67 const SkMatrix& viewMatrix,
70 const char text[], 68 const char text[],
71 size_t byteLength, 69 size_t byteLength,
72 SkScalar x, SkScalar y, 70 SkScalar x, SkScalar y,
73 const SkIRect& regionClipBounds) { 71 const SkIRect& regionClipBounds) {
72 TextRun run(skPaint);
73 run.setText(text, byteLength, x, y, fContext, &fSurfaceProps);
74 run.draw(dc, rt, clip, paint, viewMatrix, regionClipBounds, fFallbackTextCon text, skPaint);
75 }
76
77 void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarg et* rt,
78 const GrClip& clip,
79 const GrPaint& paint,
80 const SkPaint& skPaint,
81 const SkMatrix& viewMatrix,
82 const char text[],
83 size_t byteLength,
84 const SkScalar pos[],
85 int scalarsPerPosition,
86 const SkPoint& offset,
87 const SkIRect& regionClipBounds ) {
88 TextRun run(skPaint);
89 run.setPosText(text, byteLength, pos, scalarsPerPosition, offset, fContext, &fSurfaceProps);
90 run.draw(dc, rt, clip, paint, viewMatrix, regionClipBounds, fFallbackTextCon text, skPaint);
91 }
92
93 //////////////////////////////////////////////////////////////////////////////// ////////////////////
94
95 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
96 : fStroke(fontAndStroke),
97 fFont(fontAndStroke) {
98 SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported.
99
100 // Setting to "fill" ensures that no strokes get baked into font outlines. ( We use the GPU path
101 // rendering API for stroking).
102 fFont.setStyle(SkPaint::kFill_Style);
103
104 if (fFont.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle ()) {
105 // Instead of letting fake bold get baked into the glyph outlines, do it with GPU stroke.
106 SkScalar fakeBoldScale = SkScalarInterpFunc(fFont.getTextSize(),
107 kStdFakeBoldInterpKeys,
108 kStdFakeBoldInterpValues,
109 kStdFakeBoldInterpLength);
110 SkScalar extra = SkScalarMul(fFont.getTextSize(), fakeBoldScale);
111 fStroke.setStrokeStyle(fStroke.needToApply() ? fStroke.getWidth() + extr a : extra,
112 true /*strokeAndFill*/);
113
114 fFont.setFakeBoldText(false);
115 }
116
117 if (!fFont.getPathEffect() && !fStroke.isDashed()) {
118 // We can draw the glyphs from canonically sized paths.
119 fTextRatio = fFont.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
120 fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fFont.getTextS ize();
121
122 // Compensate for the glyphs being scaled by fTextRatio.
123 if (!fStroke.isFillStyle()) {
124 fStroke.setStrokeStyle(fStroke.getWidth() / fTextRatio,
125 SkStrokeRec::kStrokeAndFill_Style == fStroke. getStyle());
126 }
127
128 fFont.setLinearText(true);
129 fFont.setLCDRenderText(false);
130 fFont.setAutohinted(false);
131 fFont.setHinting(SkPaint::kNo_Hinting);
132 fFont.setSubpixelText(true);
133 fFont.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
134
135 fUsingRawGlyphPaths = SK_Scalar1 == fFont.getTextScaleX() &&
136 0 == fFont.getTextSkewX() &&
137 !fFont.isFakeBoldText() &&
138 !fFont.isVerticalText();
139 } else {
140 fTextRatio = fTextInverseRatio = 1.0f;
141 fUsingRawGlyphPaths = false;
142 }
143
144 // When drawing from canonically sized paths, the actual local coords are fT extRatio * coords.
145 fLocalMatrix.setScale(fTextRatio, fTextRatio);
146 }
147
148 GrStencilAndCoverTextContext::TextRun::~TextRun() {
149 }
150
151 void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by teLength,
152 SkScalar x, SkScalar y, GrCo ntext* ctx,
153 const SkSurfaceProps* surfac eProps) {
74 SkASSERT(byteLength == 0 || text != nullptr); 154 SkASSERT(byteLength == 0 || text != nullptr);
75 155
76 if (text == nullptr || byteLength == 0 /*|| fRC->isEmpty()*/) { 156 SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr);
77 return; 157 SkGlyphCache* glyphCache = autoGlyphCache.getCache();
78 }
79 158
80 this->init(rt, clip, paint, skPaint, byteLength, viewMatrix, regionClipBound s); 159 fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache),
160 GrPathRendering::kTranslate_PathTransfor mType,
161 fFont.countText(text, byteLength)));
81 162
82 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 163 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
83 164
84 const char* stop = text + byteLength; 165 const char* stop = text + byteLength;
85 166
86 // Measure first if needed. 167 // Measure first if needed.
87 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { 168 if (fFont.getTextAlign() != SkPaint::kLeft_Align) {
88 SkFixed stopX = 0; 169 SkFixed stopX = 0;
89 SkFixed stopY = 0; 170 SkFixed stopY = 0;
90 171
91 const char* textPtr = text; 172 const char* textPtr = text;
92 while (textPtr < stop) { 173 while (textPtr < stop) {
93 // We don't need x, y here, since all subpixel variants will have th e 174 // We don't need x, y here, since all subpixel variants will have th e
94 // same advance. 175 // same advance.
95 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &textPtr, 0, 0); 176 const SkGlyph& glyph = glyphCacheProc(glyphCache, &textPtr, 0, 0);
96 177
97 stopX += glyph.fAdvanceX; 178 stopX += glyph.fAdvanceX;
98 stopY += glyph.fAdvanceY; 179 stopY += glyph.fAdvanceY;
99 } 180 }
100 SkASSERT(textPtr == stop); 181 SkASSERT(textPtr == stop);
101 182
102 SkScalar alignX = SkFixedToScalar(stopX) * fTextRatio; 183 SkScalar alignX = SkFixedToScalar(stopX) * fTextRatio;
103 SkScalar alignY = SkFixedToScalar(stopY) * fTextRatio; 184 SkScalar alignY = SkFixedToScalar(stopY) * fTextRatio;
104 185
105 if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) { 186 if (fFont.getTextAlign() == SkPaint::kCenter_Align) {
106 alignX = SkScalarHalf(alignX); 187 alignX = SkScalarHalf(alignX);
107 alignY = SkScalarHalf(alignY); 188 alignY = SkScalarHalf(alignY);
108 } 189 }
109 190
110 x -= alignX; 191 x -= alignX;
111 y -= alignY; 192 y -= alignY;
112 } 193 }
113 194
114 SkAutoKern autokern; 195 SkAutoKern autokern;
115 196
116 SkFixed fixedSizeRatio = SkScalarToFixed(fTextRatio); 197 SkFixed fixedSizeRatio = SkScalarToFixed(fTextRatio);
117 198
118 SkFixed fx = SkScalarToFixed(x); 199 SkFixed fx = SkScalarToFixed(x);
119 SkFixed fy = SkScalarToFixed(y); 200 SkFixed fy = SkScalarToFixed(y);
120 while (text < stop) { 201 while (text < stop) {
121 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0); 202 const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
122 fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio); 203 fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio);
123 if (glyph.fWidth) { 204 if (glyph.fWidth) {
124 this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedT oScalar(fy))); 205 this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedT oScalar(fy)));
125 } 206 }
126 207
127 fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio); 208 fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio);
128 fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio); 209 fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio);
129 } 210 }
130
131 this->finish(dc);
132 } 211 }
133 212
134 void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarg et* rt, 213 void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength,
135 const GrClip& clip, 214 const SkScalar pos[], int scalarsPerPosition,
136 const GrPaint& paint, 215 const SkPoint& offset, Gr Context* ctx,
137 const SkPaint& skPaint, 216 const SkSurfaceProps* sur faceProps) {
138 const SkMatrix& viewMatrix,
139 const char text[],
140 size_t byteLength,
141 const SkScalar pos[],
142 int scalarsPerPosition,
143 const SkPoint& offset,
144 const SkIRect& regionClipBounds ) {
145 SkASSERT(byteLength == 0 || text != nullptr); 217 SkASSERT(byteLength == 0 || text != nullptr);
146 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); 218 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
147 219
148 // nothing to draw 220 SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr);
149 if (text == nullptr || byteLength == 0/* || fRC->isEmpty()*/) { 221 SkGlyphCache* glyphCache = autoGlyphCache.getCache();
150 return;
151 }
152 222
153 this->init(rt, clip, paint, skPaint, byteLength, viewMatrix, regionClipBound s); 223 fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache),
224 GrPathRendering::kTranslate_PathTransfor mType,
225 fFont.countText(text, byteLength)));
154 226
155 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 227 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
156 228
157 const char* stop = text + byteLength; 229 const char* stop = text + byteLength;
158 230
159 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); 231 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
160 SkTextAlignProc alignProc(fSkPaint.getTextAlign()); 232 SkTextAlignProc alignProc(fFont.getTextAlign());
161 while (text < stop) { 233 while (text < stop) {
162 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0); 234 const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
163 if (glyph.fWidth) { 235 if (glyph.fWidth) {
164 SkPoint tmsLoc; 236 SkPoint tmsLoc;
165 tmsProc(pos, &tmsLoc); 237 tmsProc(pos, &tmsLoc);
166 SkPoint loc; 238 SkPoint loc;
167 alignProc(tmsLoc, glyph, &loc); 239 alignProc(tmsLoc, glyph, &loc);
168 240
169 this->appendGlyph(glyph, loc); 241 this->appendGlyph(glyph, loc);
170 } 242 }
171 pos += scalarsPerPosition; 243 pos += scalarsPerPosition;
172 } 244 }
173
174 this->finish(dc);
175 } 245 }
176 246
177 static GrPathRange* get_gr_glyphs(GrContext* ctx, 247 GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx,
178 const SkTypeface* typeface, 248 SkGlyphCache* g lyphCache) {
179 const SkDescriptor* desc, 249 SkTypeface* typeface = fUsingRawGlyphPaths ? fFont.getTypeface()
180 const GrStrokeInfo& stroke) { 250 : glyphCache->getScalerContext()- >getTypeface();
251 const SkDescriptor* desc = fUsingRawGlyphPaths ? nullptr : &glyphCache->getD escriptor();
181 252
182 static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::GenerateDom ain(); 253 static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::GenerateDom ain();
183 int strokeDataCount = stroke.computeUniqueKeyFragmentData32Cnt(); 254 int strokeDataCount = fStroke.computeUniqueKeyFragmentData32Cnt();
184 GrUniqueKey glyphKey; 255 GrUniqueKey glyphKey;
185 GrUniqueKey::Builder builder(&glyphKey, kPathGlyphDomain, 2 + strokeDataCoun t); 256 GrUniqueKey::Builder builder(&glyphKey, kPathGlyphDomain, 2 + strokeDataCoun t);
186 reinterpret_cast<uint32_t&>(builder[0]) = desc ? desc->getChecksum() : 0; 257 reinterpret_cast<uint32_t&>(builder[0]) = desc ? desc->getChecksum() : 0;
187 reinterpret_cast<uint32_t&>(builder[1]) = typeface ? typeface->uniqueID() : 0; 258 reinterpret_cast<uint32_t&>(builder[1]) = typeface ? typeface->uniqueID() : 0;
188 if (strokeDataCount > 0) { 259 if (strokeDataCount > 0) {
189 stroke.asUniqueKeyFragment(&builder[2]); 260 fStroke.asUniqueKeyFragment(&builder[2]);
190 } 261 }
191 builder.finish(); 262 builder.finish();
192 263
193 SkAutoTUnref<GrPathRange> glyphs( 264 SkAutoTUnref<GrPathRange> glyphs(
194 static_cast<GrPathRange*>( 265 static_cast<GrPathRange*>(
195 ctx->resourceProvider()->findAndRefResourceByUniqueKey(glyphKey))); 266 ctx->resourceProvider()->findAndRefResourceByUniqueKey(glyphKey)));
196 if (nullptr == glyphs) { 267 if (nullptr == glyphs) {
197 glyphs.reset(ctx->resourceProvider()->createGlyphs(typeface, desc, strok e)); 268 glyphs.reset(ctx->resourceProvider()->createGlyphs(typeface, desc, fStro ke));
198 ctx->resourceProvider()->assignUniqueKeyToResource(glyphKey, glyphs); 269 ctx->resourceProvider()->assignUniqueKeyToResource(glyphKey, glyphs);
199 } else { 270 } else {
200 SkASSERT(nullptr == desc || glyphs->isEqualTo(*desc)); 271 SkASSERT(nullptr == desc || glyphs->isEqualTo(*desc));
201 } 272 }
202 273
203 return glyphs.detach(); 274 return glyphs.detach();
204 } 275 }
205 276
206 void GrStencilAndCoverTextContext::init(GrRenderTarget* rt, 277 inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl yph,
207 const GrClip& clip, 278 const SkPoint& po s) {
208 const GrPaint& paint,
209 const SkPaint& skPaint,
210 size_t textByteLength,
211 const SkMatrix& viewMatrix,
212 const SkIRect& regionClipBounds) {
213 fClip = clip;
214
215 fRenderTarget.reset(SkRef(rt));
216
217 fRegionClipBounds = regionClipBounds;
218 fClip.getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(), &fClipRect);
219
220 fPaint = paint;
221 fSkPaint = skPaint;
222
223 // Don't bake strokes into the glyph outlines. We will stroke the glyphs usi ng the GPU instead.
224 fStroke = GrStrokeInfo(fSkPaint);
225 fSkPaint.setStyle(SkPaint::kFill_Style);
226
227 SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported.
228
229 if (fSkPaint.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getSt yle()) {
230 // Instead of baking fake bold into the glyph outlines, do it with the G PU stroke.
231 SkScalar fakeBoldScale = SkScalarInterpFunc(fSkPaint.getTextSize(),
232 kStdFakeBoldInterpKeys,
233 kStdFakeBoldInterpValues,
234 kStdFakeBoldInterpLength);
235 SkScalar extra = SkScalarMul(fSkPaint.getTextSize(), fakeBoldScale);
236 fStroke.setStrokeStyle(fStroke.needToApply() ? fStroke.getWidth() + extr a : extra,
237 true /*strokeAndFill*/);
238
239 fSkPaint.setFakeBoldText(false);
240 }
241
242 bool canUseRawPaths;
243 if (!fStroke.isDashed()) {
244 // We can draw the glyphs from canonically sized paths.
245 fTextRatio = fSkPaint.getTextSize() / SkPaint::kCanonicalTextSizeForPath s;
246 fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fSkPaint.getTe xtSize();
247
248 // Compensate for the glyphs being scaled by fTextRatio.
249 if (!fStroke.isFillStyle()) {
250 fStroke.setStrokeStyle(fStroke.getWidth() / fTextRatio,
251 SkStrokeRec::kStrokeAndFill_Style == fStroke. getStyle());
252 }
253
254 fSkPaint.setLinearText(true);
255 fSkPaint.setLCDRenderText(false);
256 fSkPaint.setAutohinted(false);
257 fSkPaint.setHinting(SkPaint::kNo_Hinting);
258 fSkPaint.setSubpixelText(true);
259 fSkPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)) ;
260
261 canUseRawPaths = SK_Scalar1 == fSkPaint.getTextScaleX() &&
262 0 == fSkPaint.getTextSkewX() &&
263 !fSkPaint.isFakeBoldText() &&
264 !fSkPaint.isVerticalText();
265 } else {
266 fTextRatio = fTextInverseRatio = 1.0f;
267 canUseRawPaths = false;
268 }
269
270 fViewMatrix = viewMatrix;
271 fViewMatrix.preScale(fTextRatio, fTextRatio);
272 fLocalMatrix.setScale(fTextRatio, fTextRatio);
273
274 fGlyphCache = fSkPaint.detachCache(&fSurfaceProps, nullptr, true /*ignoreGam ma*/);
275 fGlyphs = canUseRawPaths ?
276 get_gr_glyphs(fContext, fSkPaint.getTypeface(), nullptr, fStro ke) :
277 get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTy peface(),
278 &fGlyphCache->getDescriptor(), fStroke);
279 }
280
281 inline void GrStencilAndCoverTextContext::appendGlyph(const SkGlyph& glyph, cons t SkPoint& pos) {
282 // Stick the glyphs we can't draw into the fallback arrays. 279 // Stick the glyphs we can't draw into the fallback arrays.
283 if (SkMask::kARGB32_Format == glyph.fMaskFormat) { 280 if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
284 fFallbackIndices.push_back(glyph.getGlyphID()); 281 fFallbackIndices.push_back(glyph.getGlyphID());
285 fFallbackPositions.push_back(pos); 282 fFallbackPositions.push_back(pos);
286 } else { 283 } else {
287 // TODO: infer the reserve count from the text length.
288 if (!fDraw) {
289 fDraw = GrPathRangeDraw::Create(fGlyphs,
290 GrPathRendering::kTranslate_PathTran sformType,
291 64);
292 }
293 float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * p os.y() }; 284 float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * p os.y() };
294 fDraw->append(glyph.getGlyphID(), translate); 285 fDraw->append(glyph.getGlyphID(), translate);
295 } 286 }
296 } 287 }
297 288
298 void GrStencilAndCoverTextContext::flush(GrDrawContext* dc) { 289 void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc,
299 if (fDraw) { 290 GrRenderTarget* rt,
300 SkASSERT(fDraw->count()); 291 const GrClip& clip,
292 const GrPaint& paint,
293 const SkMatrix& viewMatrix,
294 const SkIRect& regionClipBounds ,
295 GrTextContext* fallbackTextCont ext,
296 const SkPaint& originalSkPaint) const {
297 SkASSERT(fDraw);
301 298
302 // We should only be flushing about once every run. However, if this im pacts performance 299 if (fDraw->count()) {
303 // we could move the creation of the GrPipelineBuilder earlier. 300 GrPipelineBuilder pipelineBuilder(paint, rt, clip);
304 GrPipelineBuilder pipelineBuilder(fPaint, fRenderTarget, fClip); 301 SkASSERT(rt->isStencilBufferMultisampled() || !paint.isAntiAlias());
305 SkASSERT(fRenderTarget->isStencilBufferMultisampled() || !fPaint.isAntiA lias()); 302 pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, paint.isA ntiAlias());
306 pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, fPaint.is AntiAlias());
307 303
308 GR_STATIC_CONST_SAME_STENCIL(kStencilPass, 304 GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
309 kZero_StencilOp, 305 kZero_StencilOp,
310 kKeep_StencilOp, 306 kKeep_StencilOp,
311 kNotEqual_StencilFunc, 307 kNotEqual_StencilFunc,
312 0xffff, 308 0xffff,
313 0x0000, 309 0x0000,
314 0xffff); 310 0xffff);
315 311
316 *pipelineBuilder.stencil() = kStencilPass; 312 *pipelineBuilder.stencil() = kStencilPass;
317 313
318 dc->drawPathsFromRange(&pipelineBuilder, fViewMatrix, fLocalMatrix, fPai nt.getColor(), 314 SkMatrix drawMatrix(viewMatrix);
319 fDraw, GrPathRendering::kWinding_FillType); 315 drawMatrix.preScale(fTextRatio, fTextRatio);
320 fDraw->unref(); 316
321 fDraw = nullptr; 317 dc->drawPathsFromRange(&pipelineBuilder, drawMatrix, fLocalMatrix, paint .getColor(), fDraw,
318 GrPathRendering::kWinding_FillType);
322 } 319 }
323 320
324 if (fFallbackIndices.count()) { 321 if (fFallbackIndices.count()) {
325 SkASSERT(fFallbackPositions.count() == fFallbackIndices.count()); 322 SkASSERT(fFallbackPositions.count() == fFallbackIndices.count());
326 323
327 SkPaint fallbackSkPaint(fSkPaint); 324 enum { kPreservedFlags = SkPaint::kFakeBoldText_Flag | SkPaint::kLinearT ext_Flag |
325 SkPaint::kLCDRenderText_Flag | SkPaint::kAutoHi nting_Flag };
326
327 SkPaint fallbackSkPaint(originalSkPaint);
328 fStroke.applyToPaint(&fallbackSkPaint); 328 fStroke.applyToPaint(&fallbackSkPaint);
329 if (!fStroke.isFillStyle()) { 329 if (!fStroke.isFillStyle()) {
330 fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio); 330 fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio);
331 } 331 }
332 fallbackSkPaint.setTextAlign(SkPaint::kLeft_Align); // Align has already been accounted for. 332 fallbackSkPaint.setTextAlign(SkPaint::kLeft_Align); // Align has already been accounted for.
333 fallbackSkPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 333 fallbackSkPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
334 fallbackSkPaint.setHinting(fFont.getHinting());
335 fallbackSkPaint.setFlags((fFont.getFlags() & kPreservedFlags) |
336 (originalSkPaint.getFlags() & ~kPreservedFlags) );
334 // No need for subpixel positioning with bitmap glyphs. TODO: revisit if non-bitmap color 337 // No need for subpixel positioning with bitmap glyphs. TODO: revisit if non-bitmap color
335 // glyphs show up and https://code.google.com/p/skia/issues/detail?id=44 08 gets resolved. 338 // glyphs show up and https://code.google.com/p/skia/issues/detail?id=44 08 gets resolved.
336 fallbackSkPaint.setSubpixelText(false); 339 fallbackSkPaint.setSubpixelText(false);
337 fallbackSkPaint.setTextSize(fSkPaint.getTextSize() * fTextRatio); 340 fallbackSkPaint.setTextSize(fFont.getTextSize() * fTextRatio);
338 341
339 SkMatrix fallbackMatrix(fViewMatrix); 342 fallbackTextContext->drawPosText(dc, rt, clip, paint, fallbackSkPaint, v iewMatrix,
340 fallbackMatrix.preScale(fTextInverseRatio, fTextInverseRatio); 343 (char*)fFallbackIndices.begin(),
341 344 sizeof(uint16_t) * fFallbackIndices.cou nt(),
342 fFallbackTextContext->drawPosText(dc, fRenderTarget, fClip, fPaint, fall backSkPaint, 345 fFallbackPositions[0].asScalars(), 2, S kPoint::Make(0, 0),
343 fallbackMatrix, (char*)fFallbackIndice s.begin(), 346 regionClipBounds);
344 sizeof(uint16_t) * fFallbackIndices.co unt(),
345 fFallbackPositions[0].asScalars(), 2, SkPoint::Make(0, 0),
346 fRegionClipBounds);
347 fFallbackIndices.reset();
348 fFallbackPositions.reset();
349 } 347 }
350 } 348 }
351
352 void GrStencilAndCoverTextContext::finish(GrDrawContext* dc) {
353 this->flush(dc);
354
355 SkASSERT(!fDraw);
356 SkASSERT(!fFallbackIndices.count());
357 SkASSERT(!fFallbackPositions.count());
358
359 fGlyphs->unref();
360 fGlyphs = nullptr;
361
362 SkGlyphCache::AttachCache(fGlyphCache);
363 fGlyphCache = nullptr;
364 }
OLDNEW
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698