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

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

Issue 213123014: Revert of Implement text rendering with NVPR (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 8 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') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2014 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 "GrStencilAndCoverTextContext.h"
9 #include "GrDrawTarget.h"
10 #include "GrFontScaler.h"
11 #include "GrGpu.h"
12 #include "GrPath.h"
13 #include "GrTextStrike.h"
14 #include "GrTextStrike_impl.h"
15 #include "SkAutoKern.h"
16 #include "SkDraw.h"
17 #include "SkGlyphCache.h"
18 #include "SkGpuDevice.h"
19 #include "SkPath.h"
20
21 static const int kBaseSCFontSize = 64;
22 static const int kMaxReservedGlyphs = 64;
23
24 GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(
25 GrContext* context, const SkDeviceProperties& properties)
26 : GrTextContext(context, properties)
27 , fStroke(SkStrokeRec::kFill_InitStyle) {
28 }
29
30 GrStencilAndCoverTextContext::~GrStencilAndCoverTextContext() {
31 }
32
33 void GrStencilAndCoverTextContext::drawText(const GrPaint& paint,
34 const SkPaint& skPaint,
35 const char text[],
36 size_t byteLength,
37 SkScalar x, SkScalar y) {
38 SkASSERT(byteLength == 0 || text != NULL);
39
40 // nothing to draw
41 if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) {
42 return;
43 }
44
45 this->init(paint, skPaint, byteLength);
46
47
48 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
49 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, NULL);
50 SkGlyphCache* cache = autoCache.getCache();
51 GrFontScaler* scaler = GetGrFontScaler(cache);
52 GrTextStrike* strike =
53 fContext->getFontCache()->getStrike(scaler, true);
54
55 const char* stop = text + byteLength;
56
57 // Measure first if needed.
58 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) {
59 SkFixed stopX = 0;
60 SkFixed stopY = 0;
61
62 const char* textPtr = text;
63 while (textPtr < stop) {
64 // don't need x, y here, since all subpixel variants will have the
65 // same advance
66 const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0);
67
68 stopX += glyph.fAdvanceX;
69 stopY += glyph.fAdvanceY;
70 }
71 SkASSERT(textPtr == stop);
72
73 SkScalar alignX = SkFixedToScalar(stopX) * fTextRatio;
74 SkScalar alignY = SkFixedToScalar(stopY) * fTextRatio;
75
76 if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) {
77 alignX = SkScalarHalf(alignX);
78 alignY = SkScalarHalf(alignY);
79 }
80
81 x -= alignX;
82 y -= alignY;
83 }
84
85 SkAutoKern autokern;
86
87 SkFixed fx = SkScalarToFixed(x) + SK_FixedHalf;
88 SkFixed fy = SkScalarToFixed(y) + SK_FixedHalf;
89 SkFixed fixedSizeRatio = SkScalarToFixed(fTextRatio);
90
91 while (text < stop) {
92 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
93
94 fx += SkFixedMul_portable(autokern.adjust(glyph), fixedSizeRatio);
95
96 if (glyph.fWidth) {
97 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
98 glyph.getSubXFixed(),
99 glyph.getSubYFixed()),
100 SkPoint::Make(SkFixedToScalar(fx),
101 SkFixedToScalar(fy)),
102 strike,
103 scaler);
104 }
105
106 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedSizeRatio);
107 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedSizeRatio);
108 }
109
110 this->finish();
111 }
112
113 void GrStencilAndCoverTextContext::drawPosText(const GrPaint& paint, const SkPai nt& skPaint,
114 const char text[],
115 size_t byteLength,
116 const SkScalar pos[],
117 SkScalar constY,
118 int scalarsPerPosition) {
119 SkASSERT(byteLength == 0 || text != NULL);
120 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
121
122 // nothing to draw
123 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) {
124 return;
125 }
126
127 this->init(paint, skPaint, byteLength);
128
129 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
130
131 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, NULL);
132 SkGlyphCache* cache = autoCache.getCache();
133 GrFontScaler* scaler = GetGrFontScaler(cache);
134 GrTextStrike* strike =
135 fContext->getFontCache()->getStrike(scaler, true);
136
137 const char* stop = text + byteLength;
138
139 SkTDArray<const GrPath*> paths;
140 SkTDArray<SkMatrix> transforms;
141
142 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
143 while (text < stop) {
144 // the last 2 parameters are ignored
145 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
146
147 if (glyph.fWidth) {
148 SkScalar x = pos[0];
149 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1];
150 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
151 glyph.getSubXFixed(),
152 glyph.getSubYFixed()),
153 SkPoint::Make(x, y),
154 strike,
155 scaler);
156 }
157
158 pos += scalarsPerPosition;
159 }
160 } else {
161 int alignShift = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? 1 : 0;
162 while (text < stop) {
163 // the last 2 parameters are ignored
164 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
165
166 if (glyph.fWidth) {
167 SkScalar x = pos[0];
168 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1];
169 x -= SkFixedToScalar((glyph.fAdvanceX >> alignShift));
170 y -= SkFixedToScalar((glyph.fAdvanceY >> alignShift));
171
172 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
173 glyph.getSubXFixed(),
174 glyph.getSubYFixed()),
175 SkPoint::Make(x, y),
176 strike,
177 scaler);
178 }
179 pos += scalarsPerPosition;
180 }
181 }
182
183 this->finish();
184 }
185
186 bool GrStencilAndCoverTextContext::canDraw(const SkPaint& paint) {
187 return !paint.getRasterizer()
188 && !paint.getMaskFilter()
189 && (paint.getStyle() == SkPaint::kFill_Style
190 || paint.getStrokeWidth() > 0);
191
192 }
193
194 static bool has_thick_frame(const SkPaint& paint) {
195 return paint.getStrokeWidth() > 0 &&
196 paint.getStyle() != SkPaint::kFill_Style;
197 }
198
199 void GrStencilAndCoverTextContext::init(const GrPaint& paint,
200 const SkPaint& skPaint,
201 size_t textByteLength) {
202 GrTextContext::init(paint, skPaint);
203 fTextRatio = fSkPaint.getTextSize() / kBaseSCFontSize;
204 fSkPaint.setTextSize(SkIntToScalar(kBaseSCFontSize));
205 fSkPaint.setLCDRenderText(false);
206 fSkPaint.setAutohinted(false);
207 fSkPaint.setSubpixelText(true);
208 if (has_thick_frame(fSkPaint)) {
209 // Compensate the glyphs being scaled up by fTextRatio, by scaling the
210 // stroke down.
211 fSkPaint.setStrokeWidth(fSkPaint.getStrokeWidth() / fTextRatio);
212 }
213 fStroke = SkStrokeRec(fSkPaint);
214
215 // Make glyph cache produce paths geometry for fill. We will stroke them
216 // by passing fStroke to drawPath.
217 fSkPaint.setStyle(SkPaint::kFill_Style);
218
219 fStateRestore.set(fDrawTarget->drawState());
220
221 fDrawTarget->drawState()->setFromPaint(fPaint, fContext->getMatrix(),
222 fContext->getRenderTarget());
223
224 GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
225 kZero_StencilOp,
226 kZero_StencilOp,
227 kNotEqual_StencilFunc,
228 0xffff,
229 0x0000,
230 0xffff);
231
232 *fDrawTarget->drawState()->stencil() = kStencilPass;
233
234 size_t reserveAmount;
235 switch (skPaint.getTextEncoding()) {
236 default:
237 SkASSERT(false);
238 case SkPaint::kUTF8_TextEncoding:
239 reserveAmount = textByteLength;
240 break;
241 case SkPaint::kUTF16_TextEncoding:
242 reserveAmount = textByteLength / 2;
243 break;
244 case SkPaint::kUTF32_TextEncoding:
245 case SkPaint::kGlyphID_TextEncoding:
246 reserveAmount = textByteLength / 4;
247 break;
248 }
249 fPaths.setReserve(reserveAmount);
250 fTransforms.setReserve(reserveAmount);
251 }
252
253 inline void GrStencilAndCoverTextContext::appendGlyph(GrGlyph::PackedID glyphID,
254 const SkPoint& pos,
255 GrTextStrike* strike,
256 GrFontScaler* scaler) {
257 GrGlyph* glyph = strike->getGlyph(glyphID, scaler);
258
259 if (scaler->getGlyphPath(glyph->glyphID(), &fTmpPath)) {
260 *fPaths.append() = fContext->createPath(fTmpPath, fStroke);
261 SkMatrix* t = fTransforms.append();
262 t->setTranslate(pos.fX, pos.fY);
263 t->preScale(fTextRatio, fTextRatio);
264 }
265 }
266
267 void GrStencilAndCoverTextContext::finish() {
268 if (fPaths.count() > 0) {
269 fDrawTarget->drawPaths(static_cast<size_t>(fPaths.count()),
270 fPaths.begin(), fTransforms.begin(),
271 SkPath::kWinding_FillType, fStroke.getStyle());
272 for (int i = 0; i < fPaths.count(); ++i) {
273 fPaths[i]->unref();
274 }
275 if (fPaths.count() > kMaxReservedGlyphs) {
276 fPaths.reset();
277 fTransforms.reset();
278 } else {
279 fPaths.rewind();
280 fTransforms.rewind();
281 }
282 }
283 fTmpPath.reset();
284
285 fDrawTarget->drawState()->stencil()->setDisabled();
286 fStateRestore.set(NULL);
287 GrTextContext::finish();
288 }
289
OLDNEW
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698