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

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

Issue 335573002: Extract "text align proc" functions as reusable classes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: address review comments Created 6 years, 6 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/core/SkTextMapStateProc.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 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" 21 #include "SkAutoKern.h"
22 #include "SkDraw.h" 22 #include "SkDraw.h"
23 #include "SkDrawProcs.h"
23 #include "SkGlyphCache.h" 24 #include "SkGlyphCache.h"
24 #include "SkGpuDevice.h" 25 #include "SkGpuDevice.h"
25 #include "SkGr.h" 26 #include "SkGr.h"
27 #include "SkTextMapStateProc.h"
26 28
27 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, 29 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
28 "Dump the contents of the font cache before every purge."); 30 "Dump the contents of the font cache before every purge.");
29 31
30 static const int kGlyphCoordsNoColorAttributeIndex = 1; 32 static const int kGlyphCoordsNoColorAttributeIndex = 1;
31 static const int kGlyphCoordsWithColorAttributeIndex = 2; 33 static const int kGlyphCoordsWithColorAttributeIndex = 2;
32 34
33 namespace { 35 namespace {
34 // position + texture coord 36 // position + texture coord
35 extern const GrVertexAttrib gTextVertexAttribs[] = { 37 extern const GrVertexAttrib gTextVertexAttribs[] = {
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 fontScaler); 258 fontScaler);
257 } 259 }
258 260
259 fx += glyph.fAdvanceX; 261 fx += glyph.fAdvanceX;
260 fy += glyph.fAdvanceY; 262 fy += glyph.fAdvanceY;
261 } 263 }
262 264
263 this->finish(); 265 this->finish();
264 } 266 }
265 267
266 ///////////////////////////////////////////////////////////////////////////////
267 // Copied from SkDraw
268
269 // last parameter is interpreted as SkFixed [x, y]
270 // return the fixed position, which may be rounded or not by the caller
271 // e.g. subpixel doesn't round
272 typedef void (*AlignProc)(const SkPoint&, const SkGlyph&, SkIPoint*);
273
274 static void leftAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* ds t) {
275 dst->set(SkScalarToFixed(loc.fX), SkScalarToFixed(loc.fY));
276 }
277
278 static void centerAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* dst) {
279 dst->set(SkScalarToFixed(loc.fX) - (glyph.fAdvanceX >> 1),
280 SkScalarToFixed(loc.fY) - (glyph.fAdvanceY >> 1));
281 }
282
283 static void rightAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* d st) {
284 dst->set(SkScalarToFixed(loc.fX) - glyph.fAdvanceX,
285 SkScalarToFixed(loc.fY) - glyph.fAdvanceY);
286 }
287
288 static AlignProc pick_align_proc(SkPaint::Align align) {
289 static const AlignProc gProcs[] = {
290 leftAlignProc, centerAlignProc, rightAlignProc
291 };
292
293 SkASSERT((unsigned)align < SK_ARRAY_COUNT(gProcs));
294
295 return gProcs[align];
296 }
297
298 class BitmapTextMapState {
299 public:
300 mutable SkPoint fLoc;
301
302 BitmapTextMapState(const SkMatrix& matrix, SkScalar y)
303 : fMatrix(matrix), fProc(matrix.getMapXYProc()), fY(y) {}
304
305 typedef void (*Proc)(const BitmapTextMapState&, const SkScalar pos[]);
306
307 Proc pickProc(int scalarsPerPosition);
308
309 private:
310 const SkMatrix& fMatrix;
311 SkMatrix::MapXYProc fProc;
312 SkScalar fY; // ignored by MapXYProc
313 // these are only used by Only... procs
314 SkScalar fScaleX, fTransX, fTransformedY;
315
316 static void MapXProc(const BitmapTextMapState& state, const SkScalar pos[]) {
317 state.fProc(state.fMatrix, *pos, state.fY, &state.fLoc);
318 }
319
320 static void MapXYProc(const BitmapTextMapState& state, const SkScalar pos[]) {
321 state.fProc(state.fMatrix, pos[0], pos[1], &state.fLoc);
322 }
323
324 static void MapOnlyScaleXProc(const BitmapTextMapState& state,
325 const SkScalar pos[]) {
326 state.fLoc.set(SkScalarMul(state.fScaleX, *pos) + state.fTransX,
327 state.fTransformedY);
328 }
329
330 static void MapOnlyTransXProc(const BitmapTextMapState& state,
331 const SkScalar pos[]) {
332 state.fLoc.set(*pos + state.fTransX, state.fTransformedY);
333 }
334 };
335
336 BitmapTextMapState::Proc BitmapTextMapState::pickProc(int scalarsPerPosition) {
337 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
338
339 if (1 == scalarsPerPosition) {
340 unsigned mtype = fMatrix.getType();
341 if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) {
342 return MapXProc;
343 } else {
344 fScaleX = fMatrix.getScaleX();
345 fTransX = fMatrix.getTranslateX();
346 fTransformedY = SkScalarMul(fY, fMatrix.getScaleY()) +
347 fMatrix.getTranslateY();
348 return (mtype & SkMatrix::kScale_Mask) ?
349 MapOnlyScaleXProc : MapOnlyTransXProc;
350 }
351 } else {
352 return MapXYProc;
353 }
354 }
355
356 ///////////////////////////////////////////////////////////////////////////////
357
358 void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPai nt, 268 void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPai nt,
359 const char text[], size_t byteLength, 269 const char text[], size_t byteLength,
360 const SkScalar pos[], SkScalar constY, 270 const SkScalar pos[], SkScalar constY,
361 int scalarsPerPosition) { 271 int scalarsPerPosition) {
362 SkASSERT(byteLength == 0 || text != NULL); 272 SkASSERT(byteLength == 0 || text != NULL);
363 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); 273 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
364 274
365 // nothing to draw 275 // nothing to draw
366 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) { 276 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) {
367 return; 277 return;
368 } 278 }
369 279
370 this->init(paint, skPaint); 280 this->init(paint, skPaint);
371 281
372 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 282 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
373 283
374 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMa trix()); 284 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMa trix());
375 SkGlyphCache* cache = autoCache.getCache(); 285 SkGlyphCache* cache = autoCache.getCache();
376 GrFontScaler* fontScaler = GetGrFontScaler(cache); 286 GrFontScaler* fontScaler = GetGrFontScaler(cache);
377 287
378 // store original matrix before we reset, so we can use it to transform posi tions 288 // store original matrix before we reset, so we can use it to transform posi tions
379 SkMatrix ctm = fContext->getMatrix(); 289 SkMatrix ctm = fContext->getMatrix();
380 GrContext::AutoMatrix autoMatrix; 290 GrContext::AutoMatrix autoMatrix;
381 autoMatrix.setIdentity(fContext, &fPaint); 291 autoMatrix.setIdentity(fContext, &fPaint);
382 292
383 const char* stop = text + byteLength; 293 const char* stop = text + byteLength;
384 AlignProc alignProc = pick_align_proc(fSkPaint.getTextAlign()); 294 SkTextAlignProc alignProc(fSkPaint.getTextAlign());
385 BitmapTextMapState tms(ctm, constY); 295 SkTextMapStateProc tmsProc(ctm, constY, scalarsPerPosition);
386 BitmapTextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition);
387 SkFixed halfSampleX = 0, halfSampleY = 0; 296 SkFixed halfSampleX = 0, halfSampleY = 0;
388 297
389 if (cache->isSubpixel()) { 298 if (cache->isSubpixel()) {
390 // maybe we should skip the rounding if linearText is set 299 // maybe we should skip the rounding if linearText is set
391 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(ctm); 300 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(ctm);
392 301
393 SkFixed fxMask = ~0; 302 SkFixed fxMask = ~0;
394 SkFixed fyMask = ~0; 303 SkFixed fyMask = ~0;
395 if (kX_SkAxisAlignment == baseline) { 304 if (kX_SkAxisAlignment == baseline) {
396 fyMask = 0; 305 fyMask = 0;
397 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX 306 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
398 halfSampleY = SK_FixedHalf; 307 halfSampleY = SK_FixedHalf;
399 #endif 308 #endif
400 } else if (kY_SkAxisAlignment == baseline) { 309 } else if (kY_SkAxisAlignment == baseline) {
401 fxMask = 0; 310 fxMask = 0;
402 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX 311 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
403 halfSampleX = SK_FixedHalf; 312 halfSampleX = SK_FixedHalf;
404 #endif 313 #endif
405 } 314 }
406 315
407 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { 316 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
408 while (text < stop) { 317 while (text < stop) {
409 tmsProc(tms, pos); 318 SkPoint tmsLoc;
410 SkFixed fx = SkScalarToFixed(tms.fLoc.fX) + halfSampleX; 319 tmsProc(pos, &tmsLoc);
411 SkFixed fy = SkScalarToFixed(tms.fLoc.fY) + halfSampleY; 320 SkFixed fx = SkScalarToFixed(tmsLoc.fX) + halfSampleX;
321 SkFixed fy = SkScalarToFixed(tmsLoc.fY) + halfSampleY;
412 322
413 const SkGlyph& glyph = glyphCacheProc(cache, &text, 323 const SkGlyph& glyph = glyphCacheProc(cache, &text,
414 fx & fxMask, fy & fyMask); 324 fx & fxMask, fy & fyMask);
415 325
416 if (glyph.fWidth) { 326 if (glyph.fWidth) {
417 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), 327 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
418 glyph.getSubXFixed(), 328 glyph.getSubXFixed(),
419 glyph.getSubYFixed()), 329 glyph.getSubYFixed()),
420 SkFixedFloorToFixed(fx), 330 SkFixedFloorToFixed(fx),
421 SkFixedFloorToFixed(fy), 331 SkFixedFloorToFixed(fy),
422 fontScaler); 332 fontScaler);
423 } 333 }
424 pos += scalarsPerPosition; 334 pos += scalarsPerPosition;
425 } 335 }
426 } else { 336 } else {
427 while (text < stop) { 337 while (text < stop) {
428 const char* currentText = text; 338 const char* currentText = text;
429 const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0); 339 const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0);
430 340
431 if (metricGlyph.fWidth) { 341 if (metricGlyph.fWidth) {
432 SkDEBUGCODE(SkFixed prevAdvX = metricGlyph.fAdvanceX;) 342 SkDEBUGCODE(SkFixed prevAdvX = metricGlyph.fAdvanceX;)
433 SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;) 343 SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;)
434 344 SkPoint tmsLoc;
435 tmsProc(tms, pos); 345 tmsProc(pos, &tmsLoc);
436 SkIPoint fixedLoc; 346 SkIPoint fixedLoc;
437 alignProc(tms.fLoc, metricGlyph, &fixedLoc); 347 alignProc(tmsLoc, metricGlyph, &fixedLoc);
438 348
439 SkFixed fx = fixedLoc.fX + halfSampleX; 349 SkFixed fx = fixedLoc.fX + halfSampleX;
440 SkFixed fy = fixedLoc.fY + halfSampleY; 350 SkFixed fy = fixedLoc.fY + halfSampleY;
441 351
442 // have to call again, now that we've been "aligned" 352 // have to call again, now that we've been "aligned"
443 const SkGlyph& glyph = glyphCacheProc(cache, &currentText, 353 const SkGlyph& glyph = glyphCacheProc(cache, &currentText,
444 fx & fxMask, fy & fyMa sk); 354 fx & fxMask, fy & fyMa sk);
445 // the assumption is that the metrics haven't changed 355 // the assumption is that the metrics haven't changed
446 SkASSERT(prevAdvX == glyph.fAdvanceX); 356 SkASSERT(prevAdvX == glyph.fAdvanceX);
447 SkASSERT(prevAdvY == glyph.fAdvanceY); 357 SkASSERT(prevAdvY == glyph.fAdvanceY);
(...skipping 10 matching lines...) Expand all
458 } 368 }
459 } 369 }
460 } else { // not subpixel 370 } else { // not subpixel
461 371
462 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { 372 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
463 while (text < stop) { 373 while (text < stop) {
464 // the last 2 parameters are ignored 374 // the last 2 parameters are ignored
465 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 375 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
466 376
467 if (glyph.fWidth) { 377 if (glyph.fWidth) {
468 tmsProc(tms, pos); 378 SkPoint tmsLoc;
379 tmsProc(pos, &tmsLoc);
469 380
470 SkFixed fx = SkScalarToFixed(tms.fLoc.fX) + SK_FixedHalf; // halfSampleX; 381 SkFixed fx = SkScalarToFixed(tmsLoc.fX) + SK_FixedHalf; //ha lfSampleX;
471 SkFixed fy = SkScalarToFixed(tms.fLoc.fY) + SK_FixedHalf; // halfSampleY; 382 SkFixed fy = SkScalarToFixed(tmsLoc.fY) + SK_FixedHalf; //ha lfSampleY;
472 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), 383 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
473 glyph.getSubXFixed(), 384 glyph.getSubXFixed(),
474 glyph.getSubYFixed()), 385 glyph.getSubYFixed()),
475 SkFixedFloorToFixed(fx), 386 SkFixedFloorToFixed(fx),
476 SkFixedFloorToFixed(fy), 387 SkFixedFloorToFixed(fy),
477 fontScaler); 388 fontScaler);
478 } 389 }
479 pos += scalarsPerPosition; 390 pos += scalarsPerPosition;
480 } 391 }
481 } else { 392 } else {
482 while (text < stop) { 393 while (text < stop) {
483 // the last 2 parameters are ignored 394 // the last 2 parameters are ignored
484 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 395 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
485 396
486 if (glyph.fWidth) { 397 if (glyph.fWidth) {
487 tmsProc(tms, pos); 398 SkPoint tmsLoc;
399 tmsProc(pos, &tmsLoc);
488 400
489 SkIPoint fixedLoc; 401 SkIPoint fixedLoc;
490 alignProc(tms.fLoc, glyph, &fixedLoc); 402 alignProc(tmsLoc, glyph, &fixedLoc);
491 403
492 SkFixed fx = fixedLoc.fX + SK_FixedHalf; //halfSampleX; 404 SkFixed fx = fixedLoc.fX + SK_FixedHalf; //halfSampleX;
493 SkFixed fy = fixedLoc.fY + SK_FixedHalf; //halfSampleY; 405 SkFixed fy = fixedLoc.fY + SK_FixedHalf; //halfSampleY;
494 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), 406 this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
495 glyph.getSubXFixed(), 407 glyph.getSubXFixed(),
496 glyph.getSubYFixed()), 408 glyph.getSubYFixed()),
497 SkFixedFloorToFixed(fx), 409 SkFixedFloorToFixed(fx),
498 SkFixedFloorToFixed(fy), 410 SkFixedFloorToFixed(fy),
499 fontScaler); 411 fontScaler);
500 } 412 }
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 if (useColorVerts) { 591 if (useColorVerts) {
680 // color comes after position. 592 // color comes after position.
681 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); 593 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1);
682 for (int i = 0; i < 4; ++i) { 594 for (int i = 0; i < 4; ++i) {
683 *colors = fPaint.getColor(); 595 *colors = fPaint.getColor();
684 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(colors ) + vertSize); 596 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(colors ) + vertSize);
685 } 597 }
686 } 598 }
687 fCurrVertex += 4; 599 fCurrVertex += 4;
688 } 600 }
OLDNEW
« no previous file with comments | « src/core/SkTextMapStateProc.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698