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 #include "GrAtlasTextContext.h" | 7 #include "GrAtlasTextContext.h" |
8 | 8 |
9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16); | 44 static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16); |
45 | 45 |
46 static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + sizeof
(SkIPoint16); | 46 static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + sizeof
(SkIPoint16); |
47 | 47 |
48 static const int kMinDFFontSize = 18; | 48 static const int kMinDFFontSize = 18; |
49 static const int kSmallDFFontSize = 32; | 49 static const int kSmallDFFontSize = 32; |
50 static const int kSmallDFFontLimit = 32; | 50 static const int kSmallDFFontLimit = 32; |
51 static const int kMediumDFFontSize = 72; | 51 static const int kMediumDFFontSize = 72; |
52 static const int kMediumDFFontLimit = 72; | 52 static const int kMediumDFFontLimit = 72; |
53 static const int kLargeDFFontSize = 162; | 53 static const int kLargeDFFontSize = 162; |
| 54 static const int kLargeDFFontLimit = 2 * kLargeDFFontSize; |
54 | 55 |
55 SkDEBUGCODE(static const int kExpectedDistanceAdjustTableSize = 8;) | 56 SkDEBUGCODE(static const int kExpectedDistanceAdjustTableSize = 8;) |
56 static const int kDistanceAdjustLumShift = 5; | 57 static const int kDistanceAdjustLumShift = 5; |
57 | 58 |
58 static const int kVerticesPerGlyph = 4; | 59 static const int kVerticesPerGlyph = 4; |
59 static const int kIndicesPerGlyph = 6; | 60 static const int kIndicesPerGlyph = 6; |
60 | 61 |
61 static size_t get_vertex_stride(GrMaskFormat maskFormat) { | 62 static size_t get_vertex_stride(GrMaskFormat maskFormat) { |
62 switch (maskFormat) { | 63 switch (maskFormat) { |
63 case kA8_GrMaskFormat: | 64 case kA8_GrMaskFormat: |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 // bounds above on translation | 320 // bounds above on translation |
320 blob.fTotalXError += SkScalarAbs(SkScalarFraction(transX)); | 321 blob.fTotalXError += SkScalarAbs(SkScalarFraction(transX)); |
321 blob.fTotalYError += SkScalarAbs(SkScalarFraction(transY)); | 322 blob.fTotalYError += SkScalarAbs(SkScalarFraction(transY)); |
322 if (blob.fTotalXError > kMinDiscernableTranslation || | 323 if (blob.fTotalXError > kMinDiscernableTranslation || |
323 blob.fTotalYError > kMinDiscernableTranslation) { | 324 blob.fTotalYError > kMinDiscernableTranslation) { |
324 SkDebugf("Exceeding error threshold for bitmap text translation"); | 325 SkDebugf("Exceeding error threshold for bitmap text translation"); |
325 } | 326 } |
326 #endif | 327 #endif |
327 (*outTransX) = transX; | 328 (*outTransX) = transX; |
328 (*outTransY) = transY; | 329 (*outTransY) = transY; |
329 } else { | 330 } else if (blob.hasDistanceField()) { |
330 SkASSERT(blob.hasDistanceField()); | |
331 // A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would resul
t in a different | 331 // A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would resul
t in a different |
332 // distance field being generated, so we have to regenerate in those cas
es | 332 // distance field being generated, so we have to regenerate in those cas
es |
333 SkScalar newMaxScale = viewMatrix.getMaxScale(); | 333 SkScalar newMaxScale = viewMatrix.getMaxScale(); |
334 SkScalar oldMaxScale = blob.fViewMatrix.getMaxScale(); | 334 SkScalar oldMaxScale = blob.fViewMatrix.getMaxScale(); |
335 SkScalar scaleAdjust = newMaxScale / oldMaxScale; | 335 SkScalar scaleAdjust = newMaxScale / oldMaxScale; |
336 if (scaleAdjust < blob.fMaxMinScale || scaleAdjust > blob.fMinMaxScale)
{ | 336 if (scaleAdjust < blob.fMaxMinScale || scaleAdjust > blob.fMinMaxScale)
{ |
337 return true; | 337 return true; |
338 } | 338 } |
339 | 339 |
340 (*outTransX) = x - blob.fX; | 340 (*outTransX) = x - blob.fX; |
341 (*outTransY) = y - blob.fY; | 341 (*outTransY) = y - blob.fY; |
342 } | 342 } |
| 343 // It is possible that a blob has neither distanceField nor bitmaptext. Thi
s is in the case |
| 344 // when all of the runs inside the blob are drawn as paths. In this case, w
e always regenerate |
| 345 // the blob anyways at flush time, so no need to regenerate explicitly |
343 | 346 |
344 return false; | 347 return false; |
345 } | 348 } |
346 | 349 |
347 | 350 |
348 inline SkGlyphCache* GrAtlasTextContext::setupCache(BitmapTextBlob::Run* run, | 351 inline SkGlyphCache* GrAtlasTextContext::setupCache(BitmapTextBlob::Run* run, |
349 const SkPaint& skPaint, | 352 const SkPaint& skPaint, |
350 const SkMatrix* viewMatrix, | 353 const SkMatrix* viewMatrix, |
351 bool noGamma) { | 354 bool noGamma) { |
352 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, vi
ewMatrix, noGamma); | 355 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, vi
ewMatrix, noGamma); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 const SkMatrix& viewMatr
ix) { | 437 const SkMatrix& viewMatr
ix) { |
435 // TODO: support perspective (need getMaxScale replacement) | 438 // TODO: support perspective (need getMaxScale replacement) |
436 if (viewMatrix.hasPerspective()) { | 439 if (viewMatrix.hasPerspective()) { |
437 return false; | 440 return false; |
438 } | 441 } |
439 | 442 |
440 SkScalar maxScale = viewMatrix.getMaxScale(); | 443 SkScalar maxScale = viewMatrix.getMaxScale(); |
441 SkScalar scaledTextSize = maxScale*skPaint.getTextSize(); | 444 SkScalar scaledTextSize = maxScale*skPaint.getTextSize(); |
442 // Hinted text looks far better at small resolutions | 445 // Hinted text looks far better at small resolutions |
443 // Scaling up beyond 2x yields undesireable artifacts | 446 // Scaling up beyond 2x yields undesireable artifacts |
444 if (scaledTextSize < kMinDFFontSize || scaledTextSize > 2 * kLargeDFFontSize
) { | 447 if (scaledTextSize < kMinDFFontSize || scaledTextSize > kLargeDFFontLimit) { |
445 return false; | 448 return false; |
446 } | 449 } |
447 | 450 |
448 if (!fEnableDFRendering && !skPaint.isDistanceFieldTextTEMP() && | 451 if (!fEnableDFRendering && !skPaint.isDistanceFieldTextTEMP() && |
449 scaledTextSize < kLargeDFFontSize) { | 452 scaledTextSize < kLargeDFFontSize) { |
450 return false; | 453 return false; |
451 } | 454 } |
452 | 455 |
453 // rasterizers and mask filters modify alpha, which doesn't | 456 // rasterizers and mask filters modify alpha, which doesn't |
454 // translate well to distance | 457 // translate well to distance |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) { | 607 if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) { |
605 scaledTextSize *= maxScale; | 608 scaledTextSize *= maxScale; |
606 } | 609 } |
607 | 610 |
608 // We have three sizes of distance field text, and within each size 'bucket'
there is a floor | 611 // We have three sizes of distance field text, and within each size 'bucket'
there is a floor |
609 // and ceiling. A scale outside of this range would require regenerating th
e distance fields | 612 // and ceiling. A scale outside of this range would require regenerating th
e distance fields |
610 SkScalar dfMaskScaleFloor; | 613 SkScalar dfMaskScaleFloor; |
611 SkScalar dfMaskScaleCeil; | 614 SkScalar dfMaskScaleCeil; |
612 if (scaledTextSize <= kSmallDFFontLimit) { | 615 if (scaledTextSize <= kSmallDFFontLimit) { |
613 dfMaskScaleFloor = kMinDFFontSize; | 616 dfMaskScaleFloor = kMinDFFontSize; |
614 dfMaskScaleCeil = kMediumDFFontLimit; | 617 dfMaskScaleCeil = kSmallDFFontLimit; |
615 *textRatio = textSize / kSmallDFFontSize; | 618 *textRatio = textSize / kSmallDFFontSize; |
616 skPaint->setTextSize(SkIntToScalar(kSmallDFFontSize)); | 619 skPaint->setTextSize(SkIntToScalar(kSmallDFFontSize)); |
617 } else if (scaledTextSize <= kMediumDFFontLimit) { | 620 } else if (scaledTextSize <= kMediumDFFontLimit) { |
618 dfMaskScaleFloor = kMediumDFFontLimit; | 621 dfMaskScaleFloor = kSmallDFFontLimit; |
619 dfMaskScaleCeil = kLargeDFFontSize; | 622 dfMaskScaleCeil = kMediumDFFontLimit; |
620 *textRatio = textSize / kMediumDFFontSize; | 623 *textRatio = textSize / kMediumDFFontSize; |
621 skPaint->setTextSize(SkIntToScalar(kMediumDFFontSize)); | 624 skPaint->setTextSize(SkIntToScalar(kMediumDFFontSize)); |
622 } else { | 625 } else { |
623 dfMaskScaleFloor = kLargeDFFontSize; | 626 dfMaskScaleFloor = kMediumDFFontLimit; |
624 dfMaskScaleCeil = 2 * kLargeDFFontSize; | 627 dfMaskScaleCeil = kLargeDFFontLimit; |
625 *textRatio = textSize / kLargeDFFontSize; | 628 *textRatio = textSize / kLargeDFFontSize; |
626 skPaint->setTextSize(SkIntToScalar(kLargeDFFontSize)); | 629 skPaint->setTextSize(SkIntToScalar(kLargeDFFontSize)); |
627 } | 630 } |
628 | 631 |
629 // Because there can be multiple runs in the blob, we want the overall maxMi
nScale, and | 632 // Because there can be multiple runs in the blob, we want the overall maxMi
nScale, and |
630 // minMaxScale to make regeneration decisions. Specifically, we want the ma
ximum minimum scale | 633 // minMaxScale to make regeneration decisions. Specifically, we want the ma
ximum minimum scale |
631 // we can tolerate before we'd drop to a lower mip size, and the minimum max
imum scale we can | 634 // we can tolerate before we'd drop to a lower mip size, and the minimum max
imum scale we can |
632 // tolerate before we'd have to move to a large mip size. When we actually
test these values | 635 // tolerate before we'd have to move to a large mip size. When we actually
test these values |
633 // we look at the delta in scale between the new viewmatrix and the old view
matrix, and test | 636 // we look at the delta in scale between the new viewmatrix and the old view
matrix, and test |
634 // against these values to decide if we can reuse or not(ie, will a given sc
ale change our mip | 637 // against these values to decide if we can reuse or not(ie, will a given sc
ale change our mip |
635 // level) | 638 // level) |
| 639 SkASSERT(dfMaskScaleFloor <= scaledTextSize && scaledTextSize <= dfMaskScale
Ceil); |
636 blob->fMaxMinScale = SkMaxScalar(dfMaskScaleFloor / scaledTextSize, blob->fM
axMinScale); | 640 blob->fMaxMinScale = SkMaxScalar(dfMaskScaleFloor / scaledTextSize, blob->fM
axMinScale); |
637 blob->fMinMaxScale = SkMinScalar(dfMaskScaleCeil / scaledTextSize, blob->fMi
nMaxScale); | 641 blob->fMinMaxScale = SkMinScalar(dfMaskScaleCeil / scaledTextSize, blob->fMi
nMaxScale); |
638 | 642 |
639 skPaint->setLCDRenderText(false); | 643 skPaint->setLCDRenderText(false); |
640 skPaint->setAutohinted(false); | 644 skPaint->setAutohinted(false); |
641 skPaint->setHinting(SkPaint::kNormal_Hinting); | 645 skPaint->setHinting(SkPaint::kNormal_Hinting); |
642 skPaint->setSubpixelText(true); | 646 skPaint->setSubpixelText(true); |
643 } | 647 } |
644 | 648 |
645 inline void GrAtlasTextContext::fallbackDrawPosText(BitmapTextBlob* blob, | 649 inline void GrAtlasTextContext::fallbackDrawPosText(BitmapTextBlob* blob, |
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2160 pipelineBuilder.setFromPaint(grPaint, rt, clip); | 2164 pipelineBuilder.setFromPaint(grPaint, rt, clip); |
2161 | 2165 |
2162 GrColor color = grPaint.getColor(); | 2166 GrColor color = grPaint.getColor(); |
2163 for (int run = 0; run < cacheBlob->fRunCount; run++) { | 2167 for (int run = 0; run < cacheBlob->fRunCount; run++) { |
2164 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, 0, 0, sk
Paint); | 2168 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, 0, 0, sk
Paint); |
2165 } | 2169 } |
2166 | 2170 |
2167 // Now flush big glyphs | 2171 // Now flush big glyphs |
2168 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); | 2172 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); |
2169 } | 2173 } |
OLD | NEW |