blob: cd3922c4131a03adba4d0ec39e2699b13cbc1e02 [file] [log] [blame]
jvanverth@google.comd830d132013-11-11 20:54:09 +00001/*
2 * Copyright 2013 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 "GrDistanceFieldTextContext.h"
9#include "GrAtlas.h"
10#include "GrDrawTarget.h"
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +000011#include "GrDrawTargetCaps.h"
jvanverth@google.comd830d132013-11-11 20:54:09 +000012#include "GrFontScaler.h"
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +000013#include "SkGlyphCache.h"
jvanverth@google.comd830d132013-11-11 20:54:09 +000014#include "GrIndexBuffer.h"
15#include "GrTextStrike.h"
16#include "GrTextStrike_impl.h"
commit-bot@chromium.org9f94b912014-01-30 15:22:54 +000017#include "SkDraw.h"
commit-bot@chromium.orge8612d92014-01-28 22:02:07 +000018#include "SkGpuDevice.h"
jvanverth@google.comd830d132013-11-11 20:54:09 +000019#include "SkPath.h"
20#include "SkRTConf.h"
21#include "SkStrokeRec.h"
22#include "effects/GrDistanceFieldTextureEffect.h"
23
24static const int kGlyphCoordsAttributeIndex = 1;
25
commit-bot@chromium.orgdc5cd852014-04-02 19:24:32 +000026static const int kSmallDFFontSize = 32;
27static const int kSmallDFFontLimit = 32;
28static const int kMediumDFFontSize = 64;
29static const int kMediumDFFontLimit = 64;
30static const int kLargeDFFontSize = 128;
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +000031
jvanverth@google.comd830d132013-11-11 20:54:09 +000032SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
33 "Dump the contents of the font cache before every purge.");
34
commit-bot@chromium.orgae796122014-03-12 17:05:46 +000035#if SK_FORCE_DISTANCEFIELD_FONTS
36static const bool kForceDistanceFieldFonts = true;
37#else
38static const bool kForceDistanceFieldFonts = false;
39#endif
40
skia.committer@gmail.come5d70152014-01-29 07:01:48 +000041GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
commit-bot@chromium.orge8612d92014-01-28 22:02:07 +000042 const SkDeviceProperties& properties)
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +000043 : GrTextContext(context, properties) {
jvanverth@google.comd830d132013-11-11 20:54:09 +000044 fStrike = NULL;
45
46 fCurrTexture = NULL;
47 fCurrVertex = 0;
48
49 fVertices = NULL;
50 fMaxVertices = 0;
51}
52
53GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
54 this->flushGlyphs();
55}
56
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +000057bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) {
commit-bot@chromium.orgae796122014-03-12 17:05:46 +000058 return (kForceDistanceFieldFonts || paint.isDistanceFieldTextTEMP()) &&
commit-bot@chromium.orgb97c3ff2014-03-11 17:07:15 +000059 !paint.getRasterizer() && !paint.getMaskFilter() &&
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +000060 paint.getStyle() == SkPaint::kFill_Style &&
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +000061 fContext->getTextTarget()->caps()->shaderDerivativeSupport() &&
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +000062 !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix());
63}
64
jvanverth@google.comd830d132013-11-11 20:54:09 +000065static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
66 unsigned r = SkColorGetR(c);
67 unsigned g = SkColorGetG(c);
68 unsigned b = SkColorGetB(c);
69 return GrColorPackRGBA(r, g, b, 0xff);
70}
71
72void GrDistanceFieldTextContext::flushGlyphs() {
73 if (NULL == fDrawTarget) {
74 return;
75 }
76
77 GrDrawState* drawState = fDrawTarget->drawState();
78 GrDrawState::AutoRestoreEffects are(drawState);
79 drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget());
80
81 if (fCurrVertex > 0) {
82 // setup our sampler state for our text texture/atlas
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000083 SkASSERT(SkIsAlign4(fCurrVertex));
jvanverth@google.comd830d132013-11-11 20:54:09 +000084 SkASSERT(fCurrTexture);
85 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
86
commit-bot@chromium.org609ced42014-04-03 18:25:48 +000087 // Effects could be stored with one of the cache objects (atlas?)
88 if (fUseLCDText) {
89 bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout ==
90 fDeviceProperties.fGeometry.getLayout();
91 drawState->addCoverageEffect(GrDistanceFieldLCDTextureEffect::Create(
92 fCurrTexture,
93 params,
94 fContext->getMatrix().rectStaysRect() &&
95 fContext->getMatrix().isSimilarity(),
96 useBGR),
97 kGlyphCoordsAttributeIndex)->unref();
jvanverth@google.comd830d132013-11-11 20:54:09 +000098
jvanverth@google.comd830d132013-11-11 20:54:09 +000099 if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
100 kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
101 fPaint.numColorStages()) {
102 GrPrintf("LCD Text will not draw correctly.\n");
103 }
104 // We don't use the GrPaint's color in this case because it's been premultiplied by
105 // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by
106 // the mask texture color. The end result is that we get
107 // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000108 int a = SkColorGetA(fSkPaint.getColor());
jvanverth@google.comd830d132013-11-11 20:54:09 +0000109 // paintAlpha
110 drawState->setColor(SkColorSetARGB(a, a, a, a));
111 // paintColor
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000112 drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
jvanverth@google.comd830d132013-11-11 20:54:09 +0000113 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
114 } else {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000115 drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create(fCurrTexture, params,
116 fContext->getMatrix().isSimilarity()),
117 kGlyphCoordsAttributeIndex)->unref();
118
jvanverth@google.comd830d132013-11-11 20:54:09 +0000119 // set back to normal in case we took LCD path previously.
120 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
121 drawState->setColor(fPaint.getColor());
122 }
123
124 int nGlyphs = fCurrVertex / 4;
125 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
126 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
127 nGlyphs,
128 4, 6);
129 fDrawTarget->resetVertexSource();
130 fVertices = NULL;
131 fMaxVertices = 0;
132 fCurrVertex = 0;
133 SkSafeSetNull(fCurrTexture);
134 }
135}
136
137namespace {
138
139// position + texture coord
140extern const GrVertexAttrib gTextVertexAttribs[] = {
141 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000142 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}
jvanverth@google.comd830d132013-11-11 20:54:09 +0000143};
144
145};
146
147void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000148 SkFixed vx, SkFixed vy,
jvanverth@google.comd830d132013-11-11 20:54:09 +0000149 GrFontScaler* scaler) {
150 if (NULL == fDrawTarget) {
151 return;
152 }
153 if (NULL == fStrike) {
154 fStrike = fContext->getFontCache()->getStrike(scaler, true);
155 }
156
157 GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
158 if (NULL == glyph || glyph->fBounds.isEmpty()) {
159 return;
160 }
161
162 SkScalar sx = SkFixedToScalar(vx);
163 SkScalar sy = SkFixedToScalar(vy);
164/*
165 // not valid, need to find a different solution for this
166 vx += SkIntToFixed(glyph->fBounds.fLeft);
167 vy += SkIntToFixed(glyph->fBounds.fTop);
skia.committer@gmail.com11a253b2013-11-12 07:02:05 +0000168
jvanverth@google.comd830d132013-11-11 20:54:09 +0000169 // keep them as ints until we've done the clip-test
170 GrFixed width = glyph->fBounds.width();
171 GrFixed height = glyph->fBounds.height();
172
173 // check if we clipped out
174 if (true || NULL == glyph->fPlot) {
175 int x = vx >> 16;
176 int y = vy >> 16;
177 if (fClipRect.quickReject(x, y, x + width, y + height)) {
178// SkCLZ(3); // so we can set a break-point in the debugger
179 return;
180 }
181 }
182*/
183 if (NULL == glyph->fPlot) {
commit-bot@chromium.orgc9b2c882014-03-03 14:30:25 +0000184 if (fStrike->addGlyphToAtlas(glyph, scaler)) {
jvanverth@google.comd830d132013-11-11 20:54:09 +0000185 goto HAS_ATLAS;
186 }
187
188 // try to clear out an unused plot before we flush
commit-bot@chromium.orgc9b2c882014-03-03 14:30:25 +0000189 if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
190 fStrike->addGlyphToAtlas(glyph, scaler)) {
jvanverth@google.comd830d132013-11-11 20:54:09 +0000191 goto HAS_ATLAS;
192 }
193
194 if (c_DumpFontCache) {
195#ifdef SK_DEVELOPER
196 fContext->getFontCache()->dump();
197#endif
198 }
199
200 // before we purge the cache, we must flush any accumulated draws
201 this->flushGlyphs();
202 fContext->flush();
203
commit-bot@chromium.orgc9b2c882014-03-03 14:30:25 +0000204 // we should have an unused plot now
205 if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
206 fStrike->addGlyphToAtlas(glyph, scaler)) {
jvanverth@google.comd830d132013-11-11 20:54:09 +0000207 goto HAS_ATLAS;
208 }
209
210 if (NULL == glyph->fPath) {
211 SkPath* path = SkNEW(SkPath);
212 if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
213 // flag the glyph as being dead?
214 delete path;
215 return;
216 }
217 glyph->fPath = path;
218 }
219
220 GrContext::AutoMatrix am;
221 SkMatrix translate;
222 translate.setTranslate(sx, sy);
223 GrPaint tmpPaint(fPaint);
224 am.setPreConcat(fContext, translate, &tmpPaint);
225 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
226 fContext->drawPath(tmpPaint, *glyph->fPath, stroke);
227 return;
228 }
229
230HAS_ATLAS:
231 SkASSERT(glyph->fPlot);
232 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
233 glyph->fPlot->setDrawToken(drawToken);
234
235 GrTexture* texture = glyph->fPlot->texture();
236 SkASSERT(texture);
237
238 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
239 this->flushGlyphs();
240 fCurrTexture = texture;
241 fCurrTexture->ref();
242 }
243
244 if (NULL == fVertices) {
245 // If we need to reserve vertices allow the draw target to suggest
246 // a number of verts to reserve and whether to perform a flush.
247 fMaxVertices = kMinRequestedVerts;
248 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
249 SK_ARRAY_COUNT(gTextVertexAttribs));
250 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
251 if (flush) {
252 this->flushGlyphs();
253 fContext->flush();
254 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
255 SK_ARRAY_COUNT(gTextVertexAttribs));
256 }
257 fMaxVertices = kDefaultRequestedVerts;
258 // ignore return, no point in flushing again.
259 fDrawTarget->geometryHints(&fMaxVertices, NULL);
260
261 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
262 if (fMaxVertices < kMinRequestedVerts) {
263 fMaxVertices = kDefaultRequestedVerts;
264 } else if (fMaxVertices > maxQuadVertices) {
265 // don't exceed the limit of the index buffer
266 fMaxVertices = maxQuadVertices;
267 }
268 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
269 0,
270 GrTCast<void**>(&fVertices),
271 NULL);
272 GrAlwaysAssert(success);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000273 SkASSERT(2*sizeof(SkPoint) == fDrawTarget->getDrawState().getVertexSize());
jvanverth@google.comd830d132013-11-11 20:54:09 +0000274 }
275
276 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft);
277 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop);
278 SkScalar width = SkIntToScalar(glyph->fBounds.width());
279 SkScalar height = SkIntToScalar(glyph->fBounds.height());
280
281 SkScalar scale = fTextRatio;
282 dx *= scale;
283 dy *= scale;
284 sx += dx;
285 sy += dy;
286 width *= scale;
287 height *= scale;
skia.committer@gmail.coma3b53272014-02-15 03:02:15 +0000288
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000289 SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX);
290 SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY);
291 SkFixed tw = SkIntToFixed(glyph->fBounds.width());
292 SkFixed th = SkIntToFixed(glyph->fBounds.height());
jvanverth@google.comd830d132013-11-11 20:54:09 +0000293
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +0000294 static const size_t kVertexSize = 2 * sizeof(SkPoint);
jvanverth@google.comd830d132013-11-11 20:54:09 +0000295 fVertices[2*fCurrVertex].setRectFan(sx,
296 sy,
297 sx + width,
298 sy + height,
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +0000299 kVertexSize);
jvanverth@google.comd830d132013-11-11 20:54:09 +0000300 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)),
301 SkFixedToFloat(texture->normalizeFixedY(ty)),
302 SkFixedToFloat(texture->normalizeFixedX(tx + tw)),
303 SkFixedToFloat(texture->normalizeFixedY(ty + th)),
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +0000304 kVertexSize);
jvanverth@google.comd830d132013-11-11 20:54:09 +0000305 fCurrVertex += 4;
306}
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000307
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +0000308inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint& skPaint) {
309 GrTextContext::init(paint, skPaint);
310
311 fStrike = NULL;
312
313 fCurrTexture = NULL;
314 fCurrVertex = 0;
315
316 fVertices = NULL;
317 fMaxVertices = 0;
318
commit-bot@chromium.orgdc5cd852014-04-02 19:24:32 +0000319 if (fSkPaint.getTextSize() <= kSmallDFFontLimit) {
320 fTextRatio = fSkPaint.getTextSize()/kSmallDFFontSize;
321 fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize));
322 } else if (fSkPaint.getTextSize() <= kMediumDFFontLimit) {
323 fTextRatio = fSkPaint.getTextSize()/kMediumDFFontSize;
324 fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize));
325 } else {
326 fTextRatio = fSkPaint.getTextSize()/kLargeDFFontSize;
327 fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize));
328 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000329
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000330 fUseLCDText = fSkPaint.isLCDRenderText();
331
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +0000332 fSkPaint.setLCDRenderText(false);
333 fSkPaint.setAutohinted(false);
commit-bot@chromium.org0bed43c2014-03-14 21:22:38 +0000334 fSkPaint.setSubpixelText(true);
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +0000335}
336
337inline void GrDistanceFieldTextContext::finish() {
338 flushGlyphs();
339
340 GrTextContext::finish();
341}
342
343void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
344 const char text[], size_t byteLength,
commit-bot@chromium.orge8612d92014-01-28 22:02:07 +0000345 SkScalar x, SkScalar y) {
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000346 SkASSERT(byteLength == 0 || text != NULL);
347
commit-bot@chromium.orge8612d92014-01-28 22:02:07 +0000348 // nothing to draw or can't draw
349 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/
350 || fSkPaint.getRasterizer()) {
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000351 return;
352 }
skia.committer@gmail.come5d70152014-01-29 07:01:48 +0000353
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +0000354 this->init(paint, skPaint);
355
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000356 SkScalar sizeRatio = fTextRatio;
357
358 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
359
commit-bot@chromium.orge8612d92014-01-28 22:02:07 +0000360 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, NULL);
361 SkGlyphCache* cache = autoCache.getCache();
362 GrFontScaler* fontScaler = GetGrFontScaler(cache);
skia.committer@gmail.come5d70152014-01-29 07:01:48 +0000363
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000364 // need to measure first
365 // TODO - generate positions and pre-load cache as well?
366 const char* stop = text + byteLength;
367 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) {
368 SkFixed stopX = 0;
369 SkFixed stopY = 0;
370
371 const char* textPtr = text;
372 while (textPtr < stop) {
373 // don't need x, y here, since all subpixel variants will have the
374 // same advance
375 const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0);
376
377 stopX += glyph.fAdvanceX;
378 stopY += glyph.fAdvanceY;
379 }
380 SkASSERT(textPtr == stop);
381
382 SkScalar alignX = SkFixedToScalar(stopX)*sizeRatio;
383 SkScalar alignY = SkFixedToScalar(stopY)*sizeRatio;
384
385 if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) {
386 alignX = SkScalarHalf(alignX);
387 alignY = SkScalarHalf(alignY);
388 }
389
390 x -= alignX;
391 y -= alignY;
392 }
393
394 SkFixed fx = SkScalarToFixed(x) + SK_FixedHalf;
395 SkFixed fy = SkScalarToFixed(y) + SK_FixedHalf;
396 SkFixed fixedScale = SkScalarToFixed(sizeRatio);
397 while (text < stop) {
commit-bot@chromium.orga9dae712014-03-24 18:34:04 +0000398 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000399
400 if (glyph.fWidth) {
401 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
402 glyph.getSubXFixed(),
403 glyph.getSubYFixed()),
404 SkFixedFloorToFixed(fx),
405 SkFixedFloorToFixed(fy),
406 fontScaler);
407 }
408
409 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale);
410 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale);
411 }
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +0000412
413 this->finish();
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000414}
415
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +0000416void GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint,
417 const char text[], size_t byteLength,
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000418 const SkScalar pos[], SkScalar constY,
commit-bot@chromium.orge8612d92014-01-28 22:02:07 +0000419 int scalarsPerPosition) {
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000420
421 SkASSERT(byteLength == 0 || text != NULL);
422 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
423
424 // nothing to draw
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +0000425 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) {
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000426 return;
427 }
428
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +0000429 this->init(paint, skPaint);
430
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000431 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
432
commit-bot@chromium.orge8612d92014-01-28 22:02:07 +0000433 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, NULL);
434 SkGlyphCache* cache = autoCache.getCache();
435 GrFontScaler* fontScaler = GetGrFontScaler(cache);
skia.committer@gmail.come5d70152014-01-29 07:01:48 +0000436
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000437 const char* stop = text + byteLength;
438
439 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
440 while (text < stop) {
441 // the last 2 parameters are ignored
442 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
443
444 if (glyph.fWidth) {
445 SkScalar x = pos[0];
446 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1];
447
448 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
449 glyph.getSubXFixed(),
450 glyph.getSubYFixed()),
451 SkScalarToFixed(x) + SK_FixedHalf, //d1g.fHalfSampleX,
452 SkScalarToFixed(y) + SK_FixedHalf, //d1g.fHalfSampleY,
453 fontScaler);
454 }
455 pos += scalarsPerPosition;
456 }
457 } else {
458 int alignShift = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? 1 : 0;
459 while (text < stop) {
460 // the last 2 parameters are ignored
461 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
462
463 if (glyph.fWidth) {
464 SkScalar x = pos[0];
465 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1];
skia.committer@gmail.com22e96722013-12-20 07:01:36 +0000466
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000467 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
468 glyph.getSubXFixed(),
469 glyph.getSubYFixed()),
470 SkScalarToFixed(x) - (glyph.fAdvanceX >> alignShift)
471 + SK_FixedHalf, //d1g.fHalfSampleX,
472 SkScalarToFixed(y) - (glyph.fAdvanceY >> alignShift)
473 + SK_FixedHalf, //d1g.fHalfSampleY,
474 fontScaler);
475 }
476 pos += scalarsPerPosition;
477 }
478 }
commit-bot@chromium.orgcbbc4812014-01-30 22:05:47 +0000479
480 this->finish();
commit-bot@chromium.org8128d8c2013-12-19 16:12:25 +0000481}