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

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

Issue 141863005: Add standalone drawText for GrTextContext. (Closed) Base URL: https://skia.googlesource.com/skia.git@issue2018-factory
Patch Set: Some clean-up work. Created 6 years, 10 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
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 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 "GrBitmapTextContext.h" 8 #include "GrBitmapTextContext.h"
9 #include "GrAtlas.h" 9 #include "GrAtlas.h"
10 #include "GrDrawTarget.h" 10 #include "GrDrawTarget.h"
11 #include "GrFontScaler.h" 11 #include "GrFontScaler.h"
12 #include "GrIndexBuffer.h" 12 #include "GrIndexBuffer.h"
13 #include "GrTextStrike.h" 13 #include "GrTextStrike.h"
14 #include "GrTextStrike_impl.h" 14 #include "GrTextStrike_impl.h"
15 #include "SkColorPriv.h" 15 #include "SkColorPriv.h"
16 #include "SkPath.h" 16 #include "SkPath.h"
17 #include "SkRTConf.h" 17 #include "SkRTConf.h"
18 #include "SkStrokeRec.h" 18 #include "SkStrokeRec.h"
19 #include "effects/GrCustomCoordsTextureEffect.h" 19 #include "effects/GrCustomCoordsTextureEffect.h"
20 20
21 #include "SkAutoKern.h"
22 #include "SkGlyphCache.h"
23 #include "SkGpuDevice.h"
24 #include "SkGr.h"
25
21 static const int kGlyphCoordsAttributeIndex = 1; 26 static const int kGlyphCoordsAttributeIndex = 1;
22 27
23 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, 28 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
24 "Dump the contents of the font cache before every purge."); 29 "Dump the contents of the font cache before every purge.");
25 30
26 GrBitmapTextContext::GrBitmapTextContext(GrContext* context, const GrPaint& pain t, 31 GrBitmapTextContext::GrBitmapTextContext(SkGpuDevice* device, const GrPaint& pai nt,
27 const SkPaint& skPaint) : 32 const SkPaint& skPaint) :
28 GrTextContext(context, paint, skPaint) { 33 GrTextContext(device, paint, skPaint) {
29 fAutoMatrix.setIdentity(fContext, &fPaint);
30
31 fStrike = NULL; 34 fStrike = NULL;
32 35
33 fCurrTexture = NULL; 36 fCurrTexture = NULL;
34 fCurrVertex = 0; 37 fCurrVertex = 0;
35 38
36 fVertices = NULL; 39 fVertices = NULL;
37 fMaxVertices = 0; 40 fMaxVertices = 0;
38 } 41 }
39 42
40 GrBitmapTextContext::~GrBitmapTextContext() { 43 GrBitmapTextContext::~GrBitmapTextContext() {
41 this->flushGlyphs(); 44 this->flushGlyphs();
42 } 45 }
43 46
44 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { 47 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
45 unsigned r = SkColorGetR(c); 48 unsigned r = SkColorGetR(c);
46 unsigned g = SkColorGetG(c); 49 unsigned g = SkColorGetG(c);
47 unsigned b = SkColorGetB(c); 50 unsigned b = SkColorGetB(c);
48 return GrColorPackRGBA(r, g, b, 0xff); 51 return GrColorPackRGBA(r, g, b, 0xff);
49 } 52 }
50 53
51 void GrBitmapTextContext::flushGlyphs() { 54 void GrBitmapTextContext::flushGlyphs() {
52 if (NULL == fDrawTarget) { 55 if (NULL == fDrawTarget) {
53 return; 56 return;
54 } 57 }
55 58
59 GrContext* context = fDevice->context();
60
56 GrDrawState* drawState = fDrawTarget->drawState(); 61 GrDrawState* drawState = fDrawTarget->drawState();
57 GrDrawState::AutoRestoreEffects are(drawState); 62 GrDrawState::AutoRestoreEffects are(drawState);
58 drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget()); 63 drawState->setFromPaint(fPaint, SkMatrix::I(), context->getRenderTarget());
59 64
60 if (fCurrVertex > 0) { 65 if (fCurrVertex > 0) {
61 // setup our sampler state for our text texture/atlas 66 // setup our sampler state for our text texture/atlas
62 SkASSERT(GrIsALIGN4(fCurrVertex)); 67 SkASSERT(GrIsALIGN4(fCurrVertex));
63 SkASSERT(fCurrTexture); 68 SkASSERT(fCurrTexture);
64 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNon e_FilterMode); 69 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNon e_FilterMode);
65 70
66 // This effect could be stored with one of the cache objects (atlas?) 71 // This effect could be stored with one of the cache objects (atlas?)
67 drawState->addCoverageEffect( 72 drawState->addCoverageEffect(
68 GrCustomCoordsTextureEffect::Create(fCurrTexture , params), 73 GrCustomCoordsTextureEffect::Create(fCurrTexture , params),
(...skipping 18 matching lines...) Expand all
87 // paintColor 92 // paintColor
88 drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPain t.getColor())); 93 drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPain t.getColor()));
89 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); 94 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
90 } else { 95 } else {
91 // set back to normal in case we took LCD path previously. 96 // set back to normal in case we took LCD path previously.
92 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen dCoeff()); 97 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen dCoeff());
93 drawState->setColor(fPaint.getColor()); 98 drawState->setColor(fPaint.getColor());
94 } 99 }
95 100
96 int nGlyphs = fCurrVertex / 4; 101 int nGlyphs = fCurrVertex / 4;
97 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); 102 fDrawTarget->setIndexSourceToBuffer(context->getQuadIndexBuffer());
98 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, 103 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
99 nGlyphs, 104 nGlyphs,
100 4, 6); 105 4, 6);
101 106
102 fDrawTarget->resetVertexSource(); 107 fDrawTarget->resetVertexSource();
103 fVertices = NULL; 108 fVertices = NULL;
104 fMaxVertices = 0; 109 fMaxVertices = 0;
105 fCurrVertex = 0; 110 fCurrVertex = 0;
106 SkSafeSetNull(fCurrTexture); 111 SkSafeSetNull(fCurrTexture);
107 } 112 }
108 } 113 }
109 114
115 void GrBitmapTextContext::drawText(const char text[], size_t byteLength,
116 SkScalar x, SkScalar y) {
117 SkASSERT(byteLength == 0 || text != NULL);
118
119 // nothing to draw
120 if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) {
121 return;
122 }
123
124 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
125
126 GrContext* context = fDevice->context();
127 SkAutoGlyphCache autoCache(fSkPaint, &fDevice->getDeviceProperties(), &co ntext->getMatrix());
128 SkGlyphCache* cache = autoCache.getCache();
129 GrFontScaler* fontScaler = GetGrFontScaler(cache);
130
131 // transform our starting point
132 {
133 SkPoint loc;
134 context->getMatrix().mapXY(x, y, &loc);
135 x = loc.fX;
136 y = loc.fY;
137 }
138
139 // need to measure first
140 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) {
141 SkVector stop;
142
143 MeasureText(cache, glyphCacheProc, text, byteLength, &stop);
144
145 SkScalar stopX = stop.fX;
146 SkScalar stopY = stop.fY;
147
148 if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) {
149 stopX = SkScalarHalf(stopX);
150 stopY = SkScalarHalf(stopY);
151 }
152 x -= stopX;
153 y -= stopY;
154 }
155
156 const char* stop = text + byteLength;
157
158 SkAutoKern autokern;
159
160 SkFixed fxMask = ~0;
161 SkFixed fyMask = ~0;
162 SkFixed halfSampleX, halfSampleY;
163 if (cache->isSubpixel()) {
164 halfSampleX = halfSampleY = (SK_FixedHalf >> SkGlyph::kSubBits);
165 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(context->getMa trix());
166 if (kX_SkAxisAlignment == baseline) {
167 fyMask = 0;
168 halfSampleY = SK_FixedHalf;
169 } else if (kY_SkAxisAlignment == baseline) {
170 fxMask = 0;
171 halfSampleX = SK_FixedHalf;
172 }
173 } else {
174 halfSampleX = halfSampleY = SK_FixedHalf;
175 }
176
177 SkFixed fx = SkScalarToFixed(x) + halfSampleX;
178 SkFixed fy = SkScalarToFixed(y) + halfSampleY;
179
180 GrContext::AutoMatrix autoMatrix;
181 autoMatrix.setIdentity(fDevice->context(), &fPaint);
182
183 while (text < stop) {
184 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fy Mask);
185
186 fx += autokern.adjust(glyph);
187
188 if (glyph.fWidth) {
189 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
190 glyph.getSubXFixed(),
191 glyph.getSubYFixed()),
192 SkFixedFloorToFixed(fx),
193 SkFixedFloorToFixed(fy),
194 fontScaler);
195 }
196
197 fx += glyph.fAdvanceX;
198 fy += glyph.fAdvanceY;
199 }
200 }
201
202 ///////////////////////////////////////////////////////////////////////////////
203 // Copied from SkDraw
204
205 // last parameter is interpreted as SkFixed [x, y]
206 // return the fixed position, which may be rounded or not by the caller
207 // e.g. subpixel doesn't round
208 typedef void (*AlignProc)(const SkPoint&, const SkGlyph&, SkIPoint*);
209
210 static void leftAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* ds t) {
211 dst->set(SkScalarToFixed(loc.fX), SkScalarToFixed(loc.fY));
212 }
213
214 static void centerAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* dst) {
215 dst->set(SkScalarToFixed(loc.fX) - (glyph.fAdvanceX >> 1),
216 SkScalarToFixed(loc.fY) - (glyph.fAdvanceY >> 1));
217 }
218
219 static void rightAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* d st) {
220 dst->set(SkScalarToFixed(loc.fX) - glyph.fAdvanceX,
221 SkScalarToFixed(loc.fY) - glyph.fAdvanceY);
222 }
223
224 static AlignProc pick_align_proc(SkPaint::Align align) {
225 static const AlignProc gProcs[] = {
226 leftAlignProc, centerAlignProc, rightAlignProc
227 };
228
229 SkASSERT((unsigned)align < SK_ARRAY_COUNT(gProcs));
230
231 return gProcs[align];
232 }
233
234 typedef void (*AlignProc_scalar)(const SkPoint&, const SkGlyph&, SkPoint*);
235
236 static void leftAlignProc_scalar(const SkPoint& loc, const SkGlyph& glyph, SkPoi nt* dst) {
237 dst->set(loc.fX, loc.fY);
238 }
239
240 static void centerAlignProc_scalar(const SkPoint& loc, const SkGlyph& glyph, SkP oint* dst) {
241 dst->set(loc.fX - SkFixedToScalar(glyph.fAdvanceX >> 1),
242 loc.fY - SkFixedToScalar(glyph.fAdvanceY >> 1));
243 }
244
245 static void rightAlignProc_scalar(const SkPoint& loc, const SkGlyph& glyph, SkPo int* dst) {
246 dst->set(loc.fX - SkFixedToScalar(glyph.fAdvanceX),
247 loc.fY - SkFixedToScalar(glyph.fAdvanceY));
248 }
249
250 static AlignProc_scalar pick_align_proc_scalar(SkPaint::Align align) {
251 static const AlignProc_scalar gProcs[] = {
252 leftAlignProc_scalar, centerAlignProc_scalar, rightAlignProc_scalar
253 };
254
255 SkASSERT((unsigned)align < SK_ARRAY_COUNT(gProcs));
256
257 return gProcs[align];
258 }
259
260 class BitmapTextMapState {
261 public:
262 mutable SkPoint fLoc;
263
264 BitmapTextMapState(const SkMatrix& matrix, SkScalar y)
265 : fMatrix(matrix), fProc(matrix.getMapXYProc()), fY(y) {}
266
267 typedef void (*Proc)(const BitmapTextMapState&, const SkScalar pos[]);
268
269 Proc pickProc(int scalarsPerPosition);
270
271 private:
272 const SkMatrix& fMatrix;
273 SkMatrix::MapXYProc fProc;
274 SkScalar fY; // ignored by MapXYProc
275 // these are only used by Only... procs
276 SkScalar fScaleX, fTransX, fTransformedY;
277
278 static void MapXProc(const BitmapTextMapState& state, const SkScalar pos[]) {
279 state.fProc(state.fMatrix, *pos, state.fY, &state.fLoc);
280 }
281
282 static void MapXYProc(const BitmapTextMapState& state, const SkScalar pos[]) {
283 state.fProc(state.fMatrix, pos[0], pos[1], &state.fLoc);
284 }
285
286 static void MapOnlyScaleXProc(const BitmapTextMapState& state,
287 const SkScalar pos[]) {
288 state.fLoc.set(SkScalarMul(state.fScaleX, *pos) + state.fTransX,
289 state.fTransformedY);
290 }
291
292 static void MapOnlyTransXProc(const BitmapTextMapState& state,
293 const SkScalar pos[]) {
294 state.fLoc.set(*pos + state.fTransX, state.fTransformedY);
295 }
296 };
297
298 BitmapTextMapState::Proc BitmapTextMapState::pickProc(int scalarsPerPosition) {
299 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
300
301 if (1 == scalarsPerPosition) {
302 unsigned mtype = fMatrix.getType();
303 if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) {
304 return MapXProc;
305 } else {
306 fScaleX = fMatrix.getScaleX();
307 fTransX = fMatrix.getTranslateX();
308 fTransformedY = SkScalarMul(fY, fMatrix.getScaleY()) +
309 fMatrix.getTranslateY();
310 return (mtype & SkMatrix::kScale_Mask) ?
311 MapOnlyScaleXProc : MapOnlyTransXProc;
312 }
313 } else {
314 return MapXYProc;
315 }
316 }
317
318 ///////////////////////////////////////////////////////////////////////////////
319
320 void GrBitmapTextContext::drawPosText(const char text[], size_t byteLength,
321 const SkScalar pos[], SkScalar constY,
322 int scalarsPerPosition) {
323 SkASSERT(byteLength == 0 || text != NULL);
324 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
325
326 // nothing to draw
327 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) {
328 return;
329 }
330
331 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
332
333 GrContext* context = fDevice->context();
334 SkAutoGlyphCache autoCache(fSkPaint, &fDevice->getDeviceProperties(), &co ntext->getMatrix());
335 SkGlyphCache* cache = autoCache.getCache();
336 GrFontScaler* fontScaler = GetGrFontScaler(cache);
337
338 // store original matrix before we reset, so we can use it to transform posi tions
339 SkMatrix ctm = context->getMatrix();
340 GrContext::AutoMatrix autoMatrix;
341 autoMatrix.setIdentity(fDevice->context(), &fPaint);
342
343 const char* stop = text + byteLength;
344 AlignProc alignProc = pick_align_proc(fSkPaint.getTextAlign());
345 BitmapTextMapState tms(ctm, constY);
346 BitmapTextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition);
347 SkFixed halfSampleX = 0, halfSampleY = 0;
348
349 if (cache->isSubpixel()) {
350 // maybe we should skip the rounding if linearText is set
351 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(ctm);
352
353 SkFixed fxMask = ~0;
354 SkFixed fyMask = ~0;
355 if (kX_SkAxisAlignment == baseline) {
356 fyMask = 0;
357 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
358 halfSampleY = SK_FixedHalf;
359 #endif
360 } else if (kY_SkAxisAlignment == baseline) {
361 fxMask = 0;
362 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
363 halfSampleX = SK_FixedHalf;
364 #endif
365 }
366
367 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
368 while (text < stop) {
369 tmsProc(tms, pos);
370 SkFixed fx = SkScalarToFixed(tms.fLoc.fX) + halfSampleX;
371 SkFixed fy = SkScalarToFixed(tms.fLoc.fY) + halfSampleY;
372
373 const SkGlyph& glyph = glyphCacheProc(cache, &text,
374 fx & fxMask, fy & fyMask);
375
376 if (glyph.fWidth) {
377 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
378 glyph.getSubXFixed(),
379 glyph.getSubYFixed()),
380 SkFixedFloorToFixed(fx),
381 SkFixedFloorToFixed(fy),
382 fontScaler);
383 }
384 pos += scalarsPerPosition;
385 }
386 } else {
387 while (text < stop) {
388 const char* currentText = text;
389 const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0);
390
391 if (metricGlyph.fWidth) {
392 SkDEBUGCODE(SkFixed prevAdvX = metricGlyph.fAdvanceX;)
393 SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;)
394
395 tmsProc(tms, pos);
396 SkIPoint fixedLoc;
397 alignProc(tms.fLoc, metricGlyph, &fixedLoc);
398
399 SkFixed fx = fixedLoc.fX + halfSampleX;
400 SkFixed fy = fixedLoc.fY + halfSampleY;
401
402 // have to call again, now that we've been "aligned"
403 const SkGlyph& glyph = glyphCacheProc(cache, &currentText,
404 fx & fxMask, fy & fyMa sk);
405 // the assumption is that the metrics haven't changed
406 SkASSERT(prevAdvX == glyph.fAdvanceX);
407 SkASSERT(prevAdvY == glyph.fAdvanceY);
408 SkASSERT(glyph.fWidth);
409
410 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
411 glyph.getSubXFixed(),
412 glyph.getSubYFixed()),
413 SkFixedFloorToFixed(fx),
414 SkFixedFloorToFixed(fy),
415 fontScaler);
416 }
417 pos += scalarsPerPosition;
418 }
419 }
420 } else { // not subpixel
421
422 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
423 while (text < stop) {
424 // the last 2 parameters are ignored
425 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
426
427 if (glyph.fWidth) {
428 tmsProc(tms, pos);
429
430 SkFixed fx = SkScalarToFixed(tms.fLoc.fX) + SK_FixedHalf; // halfSampleX;
431 SkFixed fy = SkScalarToFixed(tms.fLoc.fY) + SK_FixedHalf; // halfSampleY;
432 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
433 glyph.getSubXFixed(),
434 glyph.getSubYFixed()),
435 SkFixedFloorToFixed(fx),
436 SkFixedFloorToFixed(fy),
437 fontScaler);
438 }
439 pos += scalarsPerPosition;
440 }
441 } else {
442 while (text < stop) {
443 // the last 2 parameters are ignored
444 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
445
446 if (glyph.fWidth) {
447 tmsProc(tms, pos);
448
449 SkIPoint fixedLoc;
450 alignProc(tms.fLoc, glyph, &fixedLoc);
451
452 SkFixed fx = fixedLoc.fX + SK_FixedHalf; //halfSampleX;
453 SkFixed fy = fixedLoc.fY + SK_FixedHalf; //halfSampleY;
454 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
455 glyph.getSubXFixed(),
456 glyph.getSubYFixed()),
457 SkFixedFloorToFixed(fx),
458 SkFixedFloorToFixed(fy),
459 fontScaler);
460 }
461 pos += scalarsPerPosition;
462 }
463 }
464 }
465 }
466
110 namespace { 467 namespace {
111 468
112 // position + texture coord 469 // position + texture coord
113 extern const GrVertexAttrib gTextVertexAttribs[] = { 470 extern const GrVertexAttrib gTextVertexAttribs[] = {
114 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 471 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
115 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} 472 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
116 }; 473 };
117 474
118 }; 475 };
119 476
120 void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed, 477 void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
121 GrFixed vx, GrFixed vy, 478 GrFixed vx, GrFixed vy,
122 GrFontScaler* scaler) { 479 GrFontScaler* scaler) {
123 if (NULL == fDrawTarget) { 480 if (NULL == fDrawTarget) {
124 return; 481 return;
125 } 482 }
483
484 GrContext* context = fDevice->context();
485
126 if (NULL == fStrike) { 486 if (NULL == fStrike) {
127 #if SK_DISTANCEFIELD_FONTS 487 #if SK_DISTANCEFIELD_FONTS
128 fStrike = fContext->getFontCache()->getStrike(scaler, false); 488 fStrike = context->getFontCache()->getStrike(scaler, false);
129 #else 489 #else
130 fStrike = fContext->getFontCache()->getStrike(scaler); 490 fStrike = context->getFontCache()->getStrike(scaler);
131 #endif 491 #endif
132 } 492 }
133 493
134 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); 494 GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
135 if (NULL == glyph || glyph->fBounds.isEmpty()) { 495 if (NULL == glyph || glyph->fBounds.isEmpty()) {
136 return; 496 return;
137 } 497 }
138 498
139 vx += SkIntToFixed(glyph->fBounds.fLeft); 499 vx += SkIntToFixed(glyph->fBounds.fLeft);
140 vy += SkIntToFixed(glyph->fBounds.fTop); 500 vy += SkIntToFixed(glyph->fBounds.fTop);
(...skipping 11 matching lines...) Expand all
152 return; 512 return;
153 } 513 }
154 } 514 }
155 515
156 if (NULL == glyph->fPlot) { 516 if (NULL == glyph->fPlot) {
157 if (fStrike->getGlyphAtlas(glyph, scaler)) { 517 if (fStrike->getGlyphAtlas(glyph, scaler)) {
158 goto HAS_ATLAS; 518 goto HAS_ATLAS;
159 } 519 }
160 520
161 // try to clear out an unused plot before we flush 521 // try to clear out an unused plot before we flush
162 fContext->getFontCache()->freePlotExceptFor(fStrike); 522 context->getFontCache()->freePlotExceptFor(fStrike);
163 if (fStrike->getGlyphAtlas(glyph, scaler)) { 523 if (fStrike->getGlyphAtlas(glyph, scaler)) {
164 goto HAS_ATLAS; 524 goto HAS_ATLAS;
165 } 525 }
166 526
167 if (c_DumpFontCache) { 527 if (c_DumpFontCache) {
168 #ifdef SK_DEVELOPER 528 #ifdef SK_DEVELOPER
169 fContext->getFontCache()->dump(); 529 context->getFontCache()->dump();
170 #endif 530 #endif
171 } 531 }
172 532
173 // before we purge the cache, we must flush any accumulated draws 533 // before we purge the cache, we must flush any accumulated draws
174 this->flushGlyphs(); 534 this->flushGlyphs();
175 fContext->flush(); 535 context->flush();
176 536
177 // try to purge 537 // try to purge
178 fContext->getFontCache()->purgeExceptFor(fStrike); 538 context->getFontCache()->purgeExceptFor(fStrike);
179 // need to use new flush count here 539 // need to use new flush count here
180 if (fStrike->getGlyphAtlas(glyph, scaler)) { 540 if (fStrike->getGlyphAtlas(glyph, scaler)) {
181 goto HAS_ATLAS; 541 goto HAS_ATLAS;
182 } 542 }
183 543
184 if (NULL == glyph->fPath) { 544 if (NULL == glyph->fPath) {
185 SkPath* path = SkNEW(SkPath); 545 SkPath* path = SkNEW(SkPath);
186 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { 546 if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
187 // flag the glyph as being dead? 547 // flag the glyph as being dead?
188 delete path; 548 delete path;
189 return; 549 return;
190 } 550 }
191 glyph->fPath = path; 551 glyph->fPath = path;
192 } 552 }
193 553
194 GrContext::AutoMatrix am; 554 GrContext::AutoMatrix am;
195 SkMatrix translate; 555 SkMatrix translate;
196 translate.setTranslate(SkFixedToScalar(vx - SkIntToFixed(glyph->fBounds. fLeft)), 556 translate.setTranslate(SkFixedToScalar(vx - SkIntToFixed(glyph->fBounds. fLeft)),
197 SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds. fTop))); 557 SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds. fTop)));
198 GrPaint tmpPaint(fPaint); 558 GrPaint tmpPaint(fPaint);
199 am.setPreConcat(fContext, translate, &tmpPaint); 559 am.setPreConcat(context, translate, &tmpPaint);
200 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 560 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
201 fContext->drawPath(tmpPaint, *glyph->fPath, stroke); 561 context->drawPath(tmpPaint, *glyph->fPath, stroke);
202 return; 562 return;
203 } 563 }
204 564
205 HAS_ATLAS: 565 HAS_ATLAS:
206 SkASSERT(glyph->fPlot); 566 SkASSERT(glyph->fPlot);
207 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); 567 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
208 glyph->fPlot->setDrawToken(drawToken); 568 glyph->fPlot->setDrawToken(drawToken);
209 569
210 // now promote them to fixed (TODO: Rethink using fixed pt). 570 // now promote them to fixed (TODO: Rethink using fixed pt).
211 width = SkIntToFixed(width); 571 width = SkIntToFixed(width);
(...skipping 10 matching lines...) Expand all
222 582
223 if (NULL == fVertices) { 583 if (NULL == fVertices) {
224 // If we need to reserve vertices allow the draw target to suggest 584 // If we need to reserve vertices allow the draw target to suggest
225 // a number of verts to reserve and whether to perform a flush. 585 // a number of verts to reserve and whether to perform a flush.
226 fMaxVertices = kMinRequestedVerts; 586 fMaxVertices = kMinRequestedVerts;
227 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( 587 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
228 SK_ARRAY_COUNT(gTextVertexAttribs)); 588 SK_ARRAY_COUNT(gTextVertexAttribs));
229 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); 589 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
230 if (flush) { 590 if (flush) {
231 this->flushGlyphs(); 591 this->flushGlyphs();
232 fContext->flush(); 592 context->flush();
233 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( 593 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
234 SK_ARRAY_COUNT(gTextVertexAttribs)); 594 SK_ARRAY_COUNT(gTextVertexAttribs));
235 } 595 }
236 fMaxVertices = kDefaultRequestedVerts; 596 fMaxVertices = kDefaultRequestedVerts;
237 // ignore return, no point in flushing again. 597 // ignore return, no point in flushing again.
238 fDrawTarget->geometryHints(&fMaxVertices, NULL); 598 fDrawTarget->geometryHints(&fMaxVertices, NULL);
239 599
240 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); 600 int maxQuadVertices = 4 * context->getQuadIndexBuffer()->maxQuads();
241 if (fMaxVertices < kMinRequestedVerts) { 601 if (fMaxVertices < kMinRequestedVerts) {
242 fMaxVertices = kDefaultRequestedVerts; 602 fMaxVertices = kDefaultRequestedVerts;
243 } else if (fMaxVertices > maxQuadVertices) { 603 } else if (fMaxVertices > maxQuadVertices) {
244 // don't exceed the limit of the index buffer 604 // don't exceed the limit of the index buffer
245 fMaxVertices = maxQuadVertices; 605 fMaxVertices = maxQuadVertices;
246 } 606 }
247 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, 607 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
248 0, 608 0,
249 GrTCast<void**>(& fVertices), 609 GrTCast<void**>(& fVertices),
250 NULL); 610 NULL);
251 GrAlwaysAssert(success); 611 GrAlwaysAssert(success);
252 SkASSERT(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize( )); 612 SkASSERT(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize( ));
253 } 613 }
254 614
255 GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX); 615 GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX);
256 GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY); 616 GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY);
257 617
258 fVertices[2*fCurrVertex].setRectFan(SkFixedToFloat(vx), 618 fVertices[2*fCurrVertex].setRectFan(SkFixedToFloat(vx),
259 SkFixedToFloat(vy), 619 SkFixedToFloat(vy),
260 SkFixedToFloat(vx + width), 620 SkFixedToFloat(vx + width),
261 SkFixedToFloat(vy + height), 621 SkFixedToFloat(vy + height),
262 2 * sizeof(SkPoint)); 622 2 * sizeof(SkPoint));
263 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)), 623 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)),
264 SkFixedToFloat(texture->normalizeFixed Y(ty)), 624 SkFixedToFloat(texture->normalizeFixed Y(ty)),
265 SkFixedToFloat(texture->normalizeFixed X(tx + width)), 625 SkFixedToFloat(texture->normalizeFixed X(tx + width)),
266 SkFixedToFloat(texture->normalizeFixed Y(ty + height)), 626 SkFixedToFloat(texture->normalizeFixed Y(ty + height)),
267 2 * sizeof(SkPoint)); 627 2 * sizeof(SkPoint));
268 fCurrVertex += 4; 628 fCurrVertex += 4;
269 } 629 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698