OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrTextUtils.h" | 8 #include "GrTextUtils.h" |
9 | 9 |
10 #include "GrAtlasTextBlob.h" | 10 #include "GrAtlasTextBlob.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 // nothing to draw | 49 // nothing to draw |
50 if (text == nullptr || byteLength == 0) { | 50 if (text == nullptr || byteLength == 0) { |
51 return; | 51 return; |
52 } | 52 } |
53 | 53 |
54 // Ensure the blob is set for bitmaptext | 54 // Ensure the blob is set for bitmaptext |
55 blob->setHasBitmap(); | 55 blob->setHasBitmap(); |
56 | 56 |
57 GrBatchTextStrike* currStrike = nullptr; | 57 GrBatchTextStrike* currStrike = nullptr; |
58 | 58 |
59 // Get GrFontScaler from cache | |
60 SkGlyphCache* cache = blob->setupCache(runIndex, props, scalerContextFlags,
skPaint, | 59 SkGlyphCache* cache = blob->setupCache(runIndex, props, scalerContextFlags,
skPaint, |
61 &viewMatrix); | 60 &viewMatrix); |
62 GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache); | |
63 | |
64 SkFindAndPlaceGlyph::ProcessText( | 61 SkFindAndPlaceGlyph::ProcessText( |
65 skPaint.getTextEncoding(), text, byteLength, | 62 skPaint.getTextEncoding(), text, byteLength, |
66 {x, y}, viewMatrix, skPaint.getTextAlign(), | 63 {x, y}, viewMatrix, skPaint.getTextAlign(), |
67 cache, | 64 cache, |
68 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { | 65 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { |
69 position += rounding; | 66 position += rounding; |
70 BmpAppendGlyph( | 67 BmpAppendGlyph( |
71 blob, runIndex, fontCache, &currStrike, glyph, | 68 blob, runIndex, fontCache, &currStrike, glyph, |
72 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, | 69 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, |
73 color, fontScaler); | 70 color, cache); |
74 } | 71 } |
75 ); | 72 ); |
76 | 73 |
77 SkGlyphCache::AttachCache(cache); | 74 SkGlyphCache::AttachCache(cache); |
78 } | 75 } |
79 | 76 |
80 void GrTextUtils::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex, | 77 void GrTextUtils::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex, |
81 GrBatchFontCache* fontCache, | 78 GrBatchFontCache* fontCache, |
82 const SkSurfaceProps& props, const SkPaint& skP
aint, | 79 const SkSurfaceProps& props, const SkPaint& skP
aint, |
83 GrColor color, uint32_t scalerContextFlags, | 80 GrColor color, uint32_t scalerContextFlags, |
84 const SkMatrix& viewMatrix, | 81 const SkMatrix& viewMatrix, |
85 const char text[], size_t byteLength, | 82 const char text[], size_t byteLength, |
86 const SkScalar pos[], int scalarsPerPosition, | 83 const SkScalar pos[], int scalarsPerPosition, |
87 const SkPoint& offset) { | 84 const SkPoint& offset) { |
88 SkASSERT(byteLength == 0 || text != nullptr); | 85 SkASSERT(byteLength == 0 || text != nullptr); |
89 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 86 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
90 | 87 |
91 // nothing to draw | 88 // nothing to draw |
92 if (text == nullptr || byteLength == 0) { | 89 if (text == nullptr || byteLength == 0) { |
93 return; | 90 return; |
94 } | 91 } |
95 | 92 |
96 // Ensure the blob is set for bitmaptext | 93 // Ensure the blob is set for bitmaptext |
97 blob->setHasBitmap(); | 94 blob->setHasBitmap(); |
98 | 95 |
99 GrBatchTextStrike* currStrike = nullptr; | 96 GrBatchTextStrike* currStrike = nullptr; |
100 | 97 |
101 // Get GrFontScaler from cache | |
102 SkGlyphCache* cache = blob->setupCache(runIndex, props, scalerContextFlags,
skPaint, | 98 SkGlyphCache* cache = blob->setupCache(runIndex, props, scalerContextFlags,
skPaint, |
103 &viewMatrix); | 99 &viewMatrix); |
104 GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache); | |
105 | 100 |
106 SkFindAndPlaceGlyph::ProcessPosText( | 101 SkFindAndPlaceGlyph::ProcessPosText( |
107 skPaint.getTextEncoding(), text, byteLength, | 102 skPaint.getTextEncoding(), text, byteLength, |
108 offset, viewMatrix, pos, scalarsPerPosition, | 103 offset, viewMatrix, pos, scalarsPerPosition, |
109 skPaint.getTextAlign(), cache, | 104 skPaint.getTextAlign(), cache, |
110 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { | 105 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { |
111 position += rounding; | 106 position += rounding; |
112 BmpAppendGlyph( | 107 BmpAppendGlyph( |
113 blob, runIndex, fontCache, &currStrike, glyph, | 108 blob, runIndex, fontCache, &currStrike, glyph, |
114 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, | 109 SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY)
, |
115 color, fontScaler); | 110 color, cache); |
116 } | 111 } |
117 ); | 112 ); |
118 | 113 |
119 SkGlyphCache::AttachCache(cache); | 114 SkGlyphCache::AttachCache(cache); |
120 } | 115 } |
121 | 116 |
122 void GrTextUtils::BmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex, | 117 void GrTextUtils::BmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex, |
123 GrBatchFontCache* fontCache, | 118 GrBatchFontCache* fontCache, |
124 GrBatchTextStrike** strike, const SkGlyph& skGl
yph, | 119 GrBatchTextStrike** strike, const SkGlyph& skGl
yph, |
125 int vx, int vy, GrColor color, GrFontScaler* sc
aler) { | 120 int vx, int vy, GrColor color, SkGlyphCache* ca
che) { |
126 if (!*strike) { | 121 if (!*strike) { |
127 *strike = fontCache->getStrike(scaler); | 122 *strike = fontCache->getStrike(cache); |
128 } | 123 } |
129 | 124 |
130 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), | 125 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), |
131 skGlyph.getSubXFixed(), | 126 skGlyph.getSubXFixed(), |
132 skGlyph.getSubYFixed(), | 127 skGlyph.getSubYFixed(), |
133 GrGlyph::kCoverage_MaskStyle); | 128 GrGlyph::kCoverage_MaskStyle); |
134 GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, scaler); | 129 GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, cache); |
135 if (!glyph) { | 130 if (!glyph) { |
136 return; | 131 return; |
137 } | 132 } |
138 | 133 |
139 int x = vx + glyph->fBounds.fLeft; | 134 int x = vx + glyph->fBounds.fLeft; |
140 int y = vy + glyph->fBounds.fTop; | 135 int y = vy + glyph->fBounds.fTop; |
141 | 136 |
142 // keep them as ints until we've done the clip-test | 137 // keep them as ints until we've done the clip-test |
143 int width = glyph->fBounds.width(); | 138 int width = glyph->fBounds.width(); |
144 int height = glyph->fBounds.height(); | 139 int height = glyph->fBounds.height(); |
145 | 140 |
146 SkRect r; | 141 SkRect r; |
147 r.fLeft = SkIntToScalar(x); | 142 r.fLeft = SkIntToScalar(x); |
148 r.fTop = SkIntToScalar(y); | 143 r.fTop = SkIntToScalar(y); |
149 r.fRight = r.fLeft + SkIntToScalar(width); | 144 r.fRight = r.fLeft + SkIntToScalar(width); |
150 r.fBottom = r.fTop + SkIntToScalar(height); | 145 r.fBottom = r.fTop + SkIntToScalar(height); |
151 | 146 |
152 blob->appendGlyph(runIndex, r, color, *strike, glyph, scaler, skGlyph, | 147 blob->appendGlyph(runIndex, r, color, *strike, glyph, cache, skGlyph, |
153 SkIntToScalar(vx), SkIntToScalar(vy), 1.0f, false); | 148 SkIntToScalar(vx), SkIntToScalar(vy), 1.0f, false); |
154 } | 149 } |
155 | 150 |
156 bool GrTextUtils::CanDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix
& viewMatrix, | 151 bool GrTextUtils::CanDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix
& viewMatrix, |
157 const SkSurfaceProps& props, const GrS
haderCaps& caps) { | 152 const SkSurfaceProps& props, const GrS
haderCaps& caps) { |
158 // TODO: support perspective (need getMaxScale replacement) | 153 // TODO: support perspective (need getMaxScale replacement) |
159 if (viewMatrix.hasPerspective()) { | 154 if (viewMatrix.hasPerspective()) { |
160 return false; | 155 return false; |
161 } | 156 } |
162 | 157 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 blob->setHasDistanceField(); | 339 blob->setHasDistanceField(); |
345 blob->setSubRunHasDistanceFields(runIndex, origPaint.isLCDRenderText()); | 340 blob->setSubRunHasDistanceFields(runIndex, origPaint.isLCDRenderText()); |
346 | 341 |
347 GrBatchTextStrike* currStrike = nullptr; | 342 GrBatchTextStrike* currStrike = nullptr; |
348 | 343 |
349 // We apply the fake-gamma by altering the distance in the shader, so we ign
ore the | 344 // We apply the fake-gamma by altering the distance in the shader, so we ign
ore the |
350 // passed-in scaler context flags. (It's only used when we fall-back to bitm
ap text). | 345 // passed-in scaler context flags. (It's only used when we fall-back to bitm
ap text). |
351 SkGlyphCache* cache = blob->setupCache(runIndex, props, SkPaint::kNone_Scale
rContextFlags, | 346 SkGlyphCache* cache = blob->setupCache(runIndex, props, SkPaint::kNone_Scale
rContextFlags, |
352 dfPaint, nullptr); | 347 dfPaint, nullptr); |
353 SkPaint::GlyphCacheProc glyphCacheProc = dfPaint.getGlyphCacheProc(true); | 348 SkPaint::GlyphCacheProc glyphCacheProc = dfPaint.getGlyphCacheProc(true); |
354 GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache); | |
355 | 349 |
356 const char* stop = text + byteLength; | 350 const char* stop = text + byteLength; |
357 | 351 |
358 if (SkPaint::kLeft_Align == dfPaint.getTextAlign()) { | 352 if (SkPaint::kLeft_Align == dfPaint.getTextAlign()) { |
359 while (text < stop) { | 353 while (text < stop) { |
360 const char* lastText = text; | 354 const char* lastText = text; |
361 // the last 2 parameters are ignored | 355 // the last 2 parameters are ignored |
362 const SkGlyph& glyph = glyphCacheProc(cache, &text); | 356 const SkGlyph& glyph = glyphCacheProc(cache, &text); |
363 | 357 |
364 if (glyph.fWidth) { | 358 if (glyph.fWidth) { |
365 SkScalar x = offset.x() + pos[0]; | 359 SkScalar x = offset.x() + pos[0]; |
366 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; | 360 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; |
367 | 361 |
368 if (!DfAppendGlyph(blob, | 362 if (!DfAppendGlyph(blob, |
369 runIndex, | 363 runIndex, |
370 fontCache, | 364 fontCache, |
371 &currStrike, | 365 &currStrike, |
372 glyph, | 366 glyph, |
373 x, y, color, fontScaler, | 367 x, y, color, cache, |
374 textRatio, viewMatrix)) { | 368 textRatio, viewMatrix)) { |
375 // couldn't append, send to fallback | 369 // couldn't append, send to fallback |
376 fallbackTxt.append(SkToInt(text-lastText), lastText); | 370 fallbackTxt.append(SkToInt(text-lastText), lastText); |
377 *fallbackPos.append() = pos[0]; | 371 *fallbackPos.append() = pos[0]; |
378 if (2 == scalarsPerPosition) { | 372 if (2 == scalarsPerPosition) { |
379 *fallbackPos.append() = pos[1]; | 373 *fallbackPos.append() = pos[1]; |
380 } | 374 } |
381 } | 375 } |
382 } | 376 } |
383 pos += scalarsPerPosition; | 377 pos += scalarsPerPosition; |
(...skipping 12 matching lines...) Expand all Loading... |
396 | 390 |
397 SkScalar advanceX = SkFloatToScalar(glyph.fAdvanceX) * alignMul
* textRatio; | 391 SkScalar advanceX = SkFloatToScalar(glyph.fAdvanceX) * alignMul
* textRatio; |
398 SkScalar advanceY = SkFloatToScalar(glyph.fAdvanceY) * alignMul
* textRatio; | 392 SkScalar advanceY = SkFloatToScalar(glyph.fAdvanceY) * alignMul
* textRatio; |
399 | 393 |
400 if (!DfAppendGlyph(blob, | 394 if (!DfAppendGlyph(blob, |
401 runIndex, | 395 runIndex, |
402 fontCache, | 396 fontCache, |
403 &currStrike, | 397 &currStrike, |
404 glyph, | 398 glyph, |
405 x - advanceX, y - advanceY, color, | 399 x - advanceX, y - advanceY, color, |
406 fontScaler, | 400 cache, |
407 textRatio, | 401 textRatio, |
408 viewMatrix)) { | 402 viewMatrix)) { |
409 // couldn't append, send to fallback | 403 // couldn't append, send to fallback |
410 fallbackTxt.append(SkToInt(text-lastText), lastText); | 404 fallbackTxt.append(SkToInt(text-lastText), lastText); |
411 *fallbackPos.append() = pos[0]; | 405 *fallbackPos.append() = pos[0]; |
412 if (2 == scalarsPerPosition) { | 406 if (2 == scalarsPerPosition) { |
413 *fallbackPos.append() = pos[1]; | 407 *fallbackPos.append() = pos[1]; |
414 } | 408 } |
415 } | 409 } |
416 } | 410 } |
417 pos += scalarsPerPosition; | 411 pos += scalarsPerPosition; |
418 } | 412 } |
419 } | 413 } |
420 | 414 |
421 SkGlyphCache::AttachCache(cache); | 415 SkGlyphCache::AttachCache(cache); |
422 if (fallbackTxt.count()) { | 416 if (fallbackTxt.count()) { |
423 blob->initOverride(runIndex); | 417 blob->initOverride(runIndex); |
424 GrTextUtils::DrawBmpPosText(blob, runIndex, fontCache, props, | 418 GrTextUtils::DrawBmpPosText(blob, runIndex, fontCache, props, |
425 origPaint, origPaint.getColor(), scalerConte
xtFlags, viewMatrix, | 419 origPaint, origPaint.getColor(), scalerConte
xtFlags, viewMatrix, |
426 fallbackTxt.begin(), fallbackTxt.count(), | 420 fallbackTxt.begin(), fallbackTxt.count(), |
427 fallbackPos.begin(), scalarsPerPosition, off
set); | 421 fallbackPos.begin(), scalarsPerPosition, off
set); |
428 } | 422 } |
429 } | 423 } |
430 | 424 |
431 bool GrTextUtils::DfAppendGlyph(GrAtlasTextBlob* blob, int runIndex, GrBatchFont
Cache* cache, | 425 bool GrTextUtils::DfAppendGlyph(GrAtlasTextBlob* blob, int runIndex, GrBatchFont
Cache* cache, |
432 GrBatchTextStrike** strike, const SkGlyph& skGly
ph, | 426 GrBatchTextStrike** strike, const SkGlyph& skGly
ph, |
433 SkScalar sx, SkScalar sy, GrColor color, | 427 SkScalar sx, SkScalar sy, GrColor color, |
434 GrFontScaler* scaler, | 428 SkGlyphCache* glyphCache, |
435 SkScalar textRatio, const SkMatrix& viewMatrix)
{ | 429 SkScalar textRatio, const SkMatrix& viewMatrix)
{ |
436 if (!*strike) { | 430 if (!*strike) { |
437 *strike = cache->getStrike(scaler); | 431 *strike = cache->getStrike(glyphCache); |
438 } | 432 } |
439 | 433 |
440 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), | 434 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(), |
441 skGlyph.getSubXFixed(), | 435 skGlyph.getSubXFixed(), |
442 skGlyph.getSubYFixed(), | 436 skGlyph.getSubYFixed(), |
443 GrGlyph::kDistance_MaskStyle); | 437 GrGlyph::kDistance_MaskStyle); |
444 GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, scaler); | 438 GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, glyphCache); |
445 if (!glyph) { | 439 if (!glyph) { |
446 return true; | 440 return true; |
447 } | 441 } |
448 | 442 |
449 // fallback to color glyph support | 443 // fallback to color glyph support |
450 if (kA8_GrMaskFormat != glyph->fMaskFormat) { | 444 if (kA8_GrMaskFormat != glyph->fMaskFormat) { |
451 return false; | 445 return false; |
452 } | 446 } |
453 | 447 |
454 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); | 448 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); |
455 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); | 449 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); |
456 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2 * SK_DistanceField
Inset); | 450 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2 * SK_DistanceField
Inset); |
457 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2 * SK_DistanceFie
ldInset); | 451 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2 * SK_DistanceFie
ldInset); |
458 | 452 |
459 SkScalar scale = textRatio; | 453 SkScalar scale = textRatio; |
460 dx *= scale; | 454 dx *= scale; |
461 dy *= scale; | 455 dy *= scale; |
462 width *= scale; | 456 width *= scale; |
463 height *= scale; | 457 height *= scale; |
464 sx += dx; | 458 sx += dx; |
465 sy += dy; | 459 sy += dy; |
466 SkRect glyphRect = SkRect::MakeXYWH(sx, sy, width, height); | 460 SkRect glyphRect = SkRect::MakeXYWH(sx, sy, width, height); |
467 | 461 |
468 blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, scaler, skGlyp
h, | 462 blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, glyphCache, sk
Glyph, |
469 sx - dx, sy - dy, scale, true); | 463 sx - dx, sy - dy, scale, true); |
470 return true; | 464 return true; |
471 } | 465 } |
472 | 466 |
473 void GrTextUtils::DrawTextAsPath(GrContext* context, GrDrawContext* dc, | 467 void GrTextUtils::DrawTextAsPath(GrContext* context, GrDrawContext* dc, |
474 const GrClip& clip, | 468 const GrClip& clip, |
475 const SkPaint& skPaint, const SkMatrix& viewMat
rix, | 469 const SkPaint& skPaint, const SkMatrix& viewMat
rix, |
476 const char text[], size_t byteLength, SkScalar
x, SkScalar y, | 470 const char text[], size_t byteLength, SkScalar
x, SkScalar y, |
477 const SkIRect& clipBounds) { | 471 const SkIRect& clipBounds) { |
478 SkTextToPathIter iter(text, byteLength, skPaint, true); | 472 SkTextToPathIter iter(text, byteLength, skPaint, true); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 return flags; | 556 return flags; |
563 } | 557 } |
564 | 558 |
565 if (kUnknown_SkPixelGeometry == surfaceProps.pixelGeometry() || ShouldDisabl
eLCD(paint)) { | 559 if (kUnknown_SkPixelGeometry == surfaceProps.pixelGeometry() || ShouldDisabl
eLCD(paint)) { |
566 flags &= ~SkPaint::kLCDRenderText_Flag; | 560 flags &= ~SkPaint::kLCDRenderText_Flag; |
567 flags |= SkPaint::kGenA8FromLCD_Flag; | 561 flags |= SkPaint::kGenA8FromLCD_Flag; |
568 } | 562 } |
569 | 563 |
570 return flags; | 564 return flags; |
571 } | 565 } |
572 | |
573 static void glyph_cache_aux_proc(void* data) { | |
574 GrFontScaler* scaler = (GrFontScaler*)data; | |
575 delete scaler; | |
576 } | |
577 | |
578 GrFontScaler* GrTextUtils::GetGrFontScaler(SkGlyphCache* cache) { | |
579 void* auxData; | |
580 GrFontScaler* scaler = nullptr; | |
581 | |
582 if (cache->getAuxProcData(glyph_cache_aux_proc, &auxData)) { | |
583 scaler = (GrFontScaler*)auxData; | |
584 } | |
585 if (nullptr == scaler) { | |
586 scaler = new GrFontScaler(cache); | |
587 cache->setAuxProc(glyph_cache_aux_proc, scaler); | |
588 } | |
589 | |
590 return scaler; | |
591 } | |
OLD | NEW |