aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkPaint.h32
-rw-r--r--src/core/SkGlyphCache.cpp14
-rw-r--r--src/core/SkGlyphCache.h15
-rw-r--r--src/core/SkPaint.cpp432
-rw-r--r--src/core/SkScalerContext.cpp419
-rw-r--r--src/core/SkScalerContext.h49
-rw-r--r--src/core/SkTypeface.cpp11
-rw-r--r--src/gpu/text/GrAtlasTextBlob.cpp3
-rw-r--r--src/gpu/text/GrAtlasTextContext.cpp4
-rw-r--r--src/gpu/text/GrStencilAndCoverTextContext.cpp5
10 files changed, 491 insertions, 493 deletions
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index 5e5240ad4a..530b3d42b4 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -30,13 +30,11 @@ class SkMaskFilter;
class SkPath;
class SkPathEffect;
struct SkPoint;
-struct SkScalerContextEffects;
class SkShader;
class SkSurfaceProps;
class SkTextBlob;
class SkTypeface;
-
/** \class SkPaint
SkPaint controls options applied when drawing and measuring. SkPaint collects all
options outside of the SkCanvas clip and SkCanvas matrix.
@@ -1680,20 +1678,6 @@ private:
SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
int* count, SkRect* bounds) const;
- void getScalerContextDescriptor(SkScalerContextEffects*, SkAutoDescriptor*,
- const SkSurfaceProps* surfaceProps,
- uint32_t scalerContextFlags, const SkMatrix*) const;
-
- SkGlyphCache* detachCache(const SkSurfaceProps* surfaceProps,
- uint32_t scalerContextFlags,
- const SkMatrix*) const;
-
- void descriptorProc(const SkSurfaceProps* surfaceProps, uint32_t scalerContextFlags,
- const SkMatrix* deviceMatrix,
- void (*proc)(SkTypeface*, const SkScalerContextEffects&,
- const SkDescriptor*, void*),
- void* context) const;
-
/*
* The luminance color is used to determine which Gamma Canonical color to map to. This is
* really only used by backends which want to cache glyph masks, and need some way to know if
@@ -1728,20 +1712,20 @@ private:
static SkScalar MaxCacheSize2(SkScalar maxLimit);
+ friend class GrAtlasTextBlob;
+ friend class GrAtlasTextContext;
+ friend class GrGLPathRendering;
+ friend class GrPathRendering;
+ friend class GrStencilAndCoverTextContext;
+ friend class GrTextUtils;
friend class SkAutoGlyphCache;
friend class SkAutoGlyphCacheNoGamma;
+ friend class SkCanonicalizePaint;
friend class SkCanvas;
friend class SkDraw;
friend class SkPDFDevice;
- friend class GrAtlasTextBlob;
- friend class GrAtlasTextContext;
- friend class GrStencilAndCoverTextContext;
- friend class GrPathRendering;
- friend class GrTextUtils;
- friend class GrGLPathRendering;
- friend class SkScalerContext;
+ friend class SkScalerContext; // for computeLuminanceColor()
friend class SkTextBaseIter;
- friend class SkCanonicalizePaint;
};
#endif
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp
index 9ddf70cc4d..16f18639bd 100644
--- a/src/core/SkGlyphCache.cpp
+++ b/src/core/SkGlyphCache.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+
#include "SkGlyphCache.h"
#include "SkGlyphCache_Globals.h"
#include "SkGraphics.h"
@@ -810,3 +811,16 @@ void SkGraphics::PurgeFontCache() {
// TODO(herb): clean up TLS apis.
size_t SkGraphics::GetTLSFontCacheLimit() { return 0; }
void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { }
+
+SkGlyphCache* SkGlyphCache::DetachCacheUsingPaint(const SkPaint& paint,
+ const SkSurfaceProps* surfaceProps,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix* deviceMatrix) {
+ SkAutoDescriptor ad;
+ SkScalerContextEffects effects;
+
+ auto desc = SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
+ paint, surfaceProps, scalerContextFlags, deviceMatrix, &ad, &effects);
+
+ return SkGlyphCache::DetachCache(paint.getTypeface(), effects, desc);
+}
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index 834db7ada0..052e07277e 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -138,6 +138,11 @@ public:
return VisitCache(typeface, effects, desc, DetachProc, nullptr);
}
+ static SkGlyphCache* DetachCacheUsingPaint(const SkPaint& paint,
+ const SkSurfaceProps* surfaceProps,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix* deviceMatrix);
+
static void Dump();
/** Dump memory usage statistics of all the attaches caches in the process using the
@@ -262,15 +267,17 @@ public:
SkAutoGlyphCache(const SkPaint& paint,
const SkSurfaceProps* surfaceProps,
const SkMatrix* matrix)
- : INHERITED(paint.detachCache(surfaceProps,
- SkScalerContextFlags::kFakeGammaAndBoostContrast,
- matrix))
+ : INHERITED(
+ SkGlyphCache::DetachCacheUsingPaint(
+ paint, surfaceProps,
+ SkScalerContextFlags::kFakeGammaAndBoostContrast, matrix))
{}
SkAutoGlyphCache(const SkPaint& paint,
const SkSurfaceProps* surfaceProps,
SkScalerContextFlags scalerContextFlags,
const SkMatrix* matrix)
- : INHERITED(paint.detachCache(surfaceProps, scalerContextFlags, matrix))
+ : INHERITED(
+ SkGlyphCache::DetachCacheUsingPaint(paint, surfaceProps, scalerContextFlags, matrix))
{}
private:
using INHERITED = std::unique_ptr<SkGlyphCache, SkGlyphCache::AttachCacheFunctor>;
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 0686c3b017..2e5d22c538 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -398,11 +398,6 @@ SkScalar SkPaint::MaxCacheSize2(SkScalar maxLimit) {
#include "SkGlyphCache.h"
#include "SkUtils.h"
-static void DetachDescProc(SkTypeface* typeface, const SkScalerContextEffects& effects,
- const SkDescriptor* desc, void* context) {
- *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(typeface, effects, desc);
-}
-
int SkPaint::textToGlyphs(const void* textData, size_t byteLength, uint16_t glyphs[]) const {
if (byteLength == 0) {
return 0;
@@ -915,11 +910,6 @@ static bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) {
return false; // don't detach the cache
}
-static void FontMetricsDescProc(SkTypeface* typeface, const SkScalerContextEffects& effects,
- const SkDescriptor* desc, void* context) {
- SkGlyphCache::VisitCache(typeface, effects, desc, FontMetricsCacheProc, context);
-}
-
SkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const {
SkCanonicalizePaint canon(*this);
const SkPaint& paint = canon.getPaint();
@@ -936,8 +926,13 @@ SkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const {
metrics = &storage;
}
- paint.descriptorProc(nullptr, SkScalerContextFlags::kNone, zoomPtr,
- FontMetricsDescProc, metrics);
+ SkAutoDescriptor ad;
+ SkScalerContextEffects effects;
+
+ auto desc = SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
+ paint, nullptr, SkScalerContextFlags::kNone, zoomPtr, &ad, &effects);
+
+ SkGlyphCache::VisitCache(paint.getTypeface(), effects, desc, FontMetricsCacheProc, metrics);
if (scale) {
SkPaintPriv::ScaleFontMetrics(metrics, scale);
@@ -1217,31 +1212,6 @@ SkRect SkPaint::getFontBounds() const {
return bounds;
}
-static SkMask::Format compute_mask_format(const SkPaint& paint) {
- uint32_t flags = paint.getFlags();
-
- // Antialiasing being disabled trumps all other settings.
- if (!(flags & SkPaint::kAntiAlias_Flag)) {
- return SkMask::kBW_Format;
- }
-
- if (flags & SkPaint::kLCDRenderText_Flag) {
- return SkMask::kLCD16_Format;
- }
-
- return SkMask::kA8_Format;
-}
-
-// if linear-text is on, then we force hinting to be off (since that's sort of
-// the point of linear-text.
-static SkPaint::Hinting computeHinting(const SkPaint& paint) {
- SkPaint::Hinting h = paint.getHinting();
- if (paint.isLinearText()) {
- h = SkPaint::kNo_Hinting;
- }
- return h;
-}
-
// return true if the paint is just a single color (i.e. not a shader). If its
// a shader, then we can't compute a const luminance for it :(
static bool justAColor(const SkPaint& paint, SkColor* color) {
@@ -1270,250 +1240,6 @@ SkColor SkPaint::computeLuminanceColor() const {
#define assert_byte(x) SkASSERT(0 == ((x) >> 8))
-// Beyond this size, LCD doesn't appreciably improve quality, but it always
-// cost more RAM and draws slower, so we set a cap.
-#ifndef SK_MAX_SIZE_FOR_LCDTEXT
- #define SK_MAX_SIZE_FOR_LCDTEXT 48
-#endif
-
-const SkScalar gMaxSize2ForLCDText = SK_MAX_SIZE_FOR_LCDTEXT * SK_MAX_SIZE_FOR_LCDTEXT;
-
-static bool too_big_for_lcd(const SkScalerContextRec& rec, bool checkPost2x2) {
- if (checkPost2x2) {
- SkScalar area = rec.fPost2x2[0][0] * rec.fPost2x2[1][1] -
- rec.fPost2x2[1][0] * rec.fPost2x2[0][1];
- area *= rec.fTextSize * rec.fTextSize;
- return area > gMaxSize2ForLCDText;
- } else {
- return rec.fTextSize > SK_MAX_SIZE_FOR_LCDTEXT;
- }
-}
-
-/*
- * Return the scalar with only limited fractional precision. Used to consolidate matrices
- * that vary only slightly when we create our key into the font cache, since the font scaler
- * typically returns the same looking resuts for tiny changes in the matrix.
- */
-static SkScalar sk_relax(SkScalar x) {
- SkScalar n = SkScalarRoundToScalar(x * 1024);
- return n / 1024.0f;
-}
-
-void SkScalerContext::MakeRecAndEffects(const SkPaint& paint,
- const SkSurfaceProps* surfaceProps,
- const SkMatrix* deviceMatrix,
- SkScalerContextFlags scalerContextFlags,
- SkScalerContextRec* rec,
- SkScalerContextEffects* effects) {
- SkASSERT(deviceMatrix == nullptr || !deviceMatrix->hasPerspective());
-
- SkTypeface* typeface = paint.getTypeface();
- if (nullptr == typeface) {
- typeface = SkTypeface::GetDefaultTypeface();
- }
- rec->fFontID = typeface->uniqueID();
- rec->fTextSize = paint.getTextSize();
- rec->fPreScaleX = paint.getTextScaleX();
- rec->fPreSkewX = paint.getTextSkewX();
-
- bool checkPost2x2 = false;
-
- if (deviceMatrix) {
- const SkMatrix::TypeMask mask = deviceMatrix->getType();
- if (mask & SkMatrix::kScale_Mask) {
- rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX());
- rec->fPost2x2[1][1] = sk_relax(deviceMatrix->getScaleY());
- checkPost2x2 = true;
- } else {
- rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
- }
- if (mask & SkMatrix::kAffine_Mask) {
- rec->fPost2x2[0][1] = sk_relax(deviceMatrix->getSkewX());
- rec->fPost2x2[1][0] = sk_relax(deviceMatrix->getSkewY());
- checkPost2x2 = true;
- } else {
- rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
- }
- } else {
- rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
- rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
- }
-
- SkPaint::Style style = paint.getStyle();
- SkScalar strokeWidth = paint.getStrokeWidth();
-
- unsigned flags = 0;
-
- if (paint.isFakeBoldText()) {
-#ifdef SK_USE_FREETYPE_EMBOLDEN
- flags |= SkScalerContext::kEmbolden_Flag;
-#else
- SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(),
- kStdFakeBoldInterpKeys,
- kStdFakeBoldInterpValues,
- kStdFakeBoldInterpLength);
- SkScalar extra = paint.getTextSize() * fakeBoldScale;
-
- if (style == SkPaint::kFill_Style) {
- style = SkPaint::kStrokeAndFill_Style;
- strokeWidth = extra; // ignore paint's strokeWidth if it was "fill"
- } else {
- strokeWidth += extra;
- }
-#endif
- }
-
- if (paint.isDevKernText()) {
- flags |= SkScalerContext::kDevKernText_Flag;
- }
-
- if (style != SkPaint::kFill_Style && strokeWidth > 0) {
- rec->fFrameWidth = strokeWidth;
- rec->fMiterLimit = paint.getStrokeMiter();
- rec->fStrokeJoin = SkToU8(paint.getStrokeJoin());
- rec->fStrokeCap = SkToU8(paint.getStrokeCap());
-
- if (style == SkPaint::kStrokeAndFill_Style) {
- flags |= SkScalerContext::kFrameAndFill_Flag;
- }
- } else {
- rec->fFrameWidth = 0;
- rec->fMiterLimit = 0;
- rec->fStrokeJoin = 0;
- rec->fStrokeCap = 0;
- }
-
- rec->fMaskFormat = SkToU8(compute_mask_format(paint));
-
- if (SkMask::kLCD16_Format == rec->fMaskFormat) {
- if (too_big_for_lcd(*rec, checkPost2x2)) {
- rec->fMaskFormat = SkMask::kA8_Format;
- flags |= SkScalerContext::kGenA8FromLCD_Flag;
- } else {
- SkPixelGeometry geometry = surfaceProps
- ? surfaceProps->pixelGeometry()
- : SkSurfacePropsDefaultPixelGeometry();
- switch (geometry) {
- case kUnknown_SkPixelGeometry:
- // eeek, can't support LCD
- rec->fMaskFormat = SkMask::kA8_Format;
- flags |= SkScalerContext::kGenA8FromLCD_Flag;
- break;
- case kRGB_H_SkPixelGeometry:
- // our default, do nothing.
- break;
- case kBGR_H_SkPixelGeometry:
- flags |= SkScalerContext::kLCD_BGROrder_Flag;
- break;
- case kRGB_V_SkPixelGeometry:
- flags |= SkScalerContext::kLCD_Vertical_Flag;
- break;
- case kBGR_V_SkPixelGeometry:
- flags |= SkScalerContext::kLCD_Vertical_Flag;
- flags |= SkScalerContext::kLCD_BGROrder_Flag;
- break;
- }
- }
- }
-
- if (paint.isEmbeddedBitmapText()) {
- flags |= SkScalerContext::kEmbeddedBitmapText_Flag;
- }
- if (paint.isSubpixelText()) {
- flags |= SkScalerContext::kSubpixelPositioning_Flag;
- }
- if (paint.isAutohinted()) {
- flags |= SkScalerContext::kForceAutohinting_Flag;
- }
- if (paint.isVerticalText()) {
- flags |= SkScalerContext::kVertical_Flag;
- }
- if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) {
- flags |= SkScalerContext::kGenA8FromLCD_Flag;
- }
- rec->fFlags = SkToU16(flags);
-
- // these modify fFlags, so do them after assigning fFlags
- rec->setHinting(computeHinting(paint));
-
- rec->setLuminanceColor(paint.computeLuminanceColor());
-
- // For now always set the paint gamma equal to the device gamma.
- // The math in SkMaskGamma can handle them being different,
- // but it requires superluminous masks when
- // Ex : deviceGamma(x) < paintGamma(x) and x is sufficiently large.
- rec->setDeviceGamma(SK_GAMMA_EXPONENT);
- rec->setPaintGamma(SK_GAMMA_EXPONENT);
-
-#ifdef SK_GAMMA_CONTRAST
- rec->setContrast(SK_GAMMA_CONTRAST);
-#else
- // A value of 0.5 for SK_GAMMA_CONTRAST appears to be a good compromise.
- // With lower values small text appears washed out (though correctly so).
- // With higher values lcd fringing is worse and the smoothing effect of
- // partial coverage is diminished.
- rec->setContrast(0.5f);
-#endif
-
- rec->fReservedAlign = 0;
-
- // Allow the fonthost to modify our rec before we use it as a key into the
- // cache. This way if we're asking for something that they will ignore,
- // they can modify our rec up front, so we don't create duplicate cache
- // entries.
- typeface->onFilterRec(rec);
-
- if (!SkToBool(scalerContextFlags & SkScalerContextFlags::kFakeGamma)) {
- rec->ignoreGamma();
- }
- if (!SkToBool(scalerContextFlags & SkScalerContextFlags::kBoostContrast)) {
- rec->setContrast(0);
- }
-
- new (effects) SkScalerContextEffects{paint};
- if (effects->fPathEffect) {
- rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion
- // seems like we could support kLCD as well at this point...
- }
- if (effects->fMaskFilter) {
- // force antialiasing with maskfilters
- rec->fMaskFormat = SkMask::kA8_Format;
- // Pre-blend is not currently applied to filtered text.
- // The primary filter is blur, for which contrast makes no sense,
- // and for which the destination guess error is more visible.
- // Also, all existing users of blur have calibrated for linear.
- rec->ignorePreBlend();
- }
-
- // If we're asking for A8, we force the colorlum to be gray, since that
- // limits the number of unique entries, and the scaler will only look at
- // the lum of one of them.
- switch (rec->fMaskFormat) {
- case SkMask::kLCD16_Format: {
- // filter down the luminance color to a finite number of bits
- SkColor color = rec->getLuminanceColor();
- rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color));
- break;
- }
- case SkMask::kA8_Format: {
- // filter down the luminance to a single component, since A8 can't
- // use per-component information
- SkColor color = rec->getLuminanceColor();
- U8CPU lum = SkComputeLuminance(SkColorGetR(color),
- SkColorGetG(color),
- SkColorGetB(color));
- // reduce to our finite number of bits
- color = SkColorSetRGB(lum, lum, lum);
- rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color));
- break;
- }
- case SkMask::kBW_Format:
- // No need to differentiate gamma or apply contrast if we're BW
- rec->ignorePreBlend();
- break;
- }
-}
-
/**
* In order to call cachedDeviceLuminance, cachedPaintLuminance, or
* cachedMaskGamma the caller must hold the gMaskGammaCacheMutex and continue
@@ -1548,46 +1274,6 @@ static const SkMaskGamma& cachedMaskGamma(SkScalar contrast, SkScalar paintGamma
return *gMaskGamma;
}
-void SkPaint::getScalerContextDescriptor(SkScalerContextEffects* effects,
- SkAutoDescriptor* ad,
- const SkSurfaceProps* surfaceProps,
- uint32_t scalerContextFlags,
- const SkMatrix* deviceMatrix) const {
- SkScalerContextRec rec;
-
- SkScalerContext::MakeRecAndEffects(
- *this, surfaceProps, deviceMatrix, (SkScalerContextFlags)scalerContextFlags, &rec, effects);
- auto alloc = [ad](size_t size) {
- ad->reset(size);
- return ad->getDesc();
- };
- SkScalerContext::CreateDescriptorGivenRecAndEffects(rec, *effects, alloc);
-}
-
-void SkPaint::descriptorProc(const SkSurfaceProps* surfaceProps,
- uint32_t scalerContextFlags,
- const SkMatrix* deviceMatrix,
- void (*proc)(SkTypeface*, const SkScalerContextEffects&,
- const SkDescriptor*, void*),
- void* context) const {
- SkAutoDescriptor ad;
- SkScalerContextEffects effects;
-
- this->getScalerContextDescriptor(&effects, &ad, surfaceProps, scalerContextFlags,
- deviceMatrix);
-
- auto desc = ad.getDesc();
- proc(fTypeface.get(), effects, desc, context);
-}
-
-SkGlyphCache* SkPaint::detachCache(const SkSurfaceProps* surfaceProps,
- uint32_t scalerContextFlags,
- const SkMatrix* deviceMatrix) const {
- SkGlyphCache* cache;
- this->descriptorProc(surfaceProps, scalerContextFlags, deviceMatrix, DetachDescProc, &cache);
- return cache;
-}
-
/**
* Expands fDeviceGamma, fPaintGamma, fContrast, and fLumBits into a mask pre-blend.
@@ -1632,106 +1318,6 @@ bool SkScalerContext::GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, Sk
return true;
}
-size_t SkScalerContext::CalculateSizeAndFlatten(
- const SkScalerContextRec& rec,
- const SkScalerContextEffects& effects,
- SkBinaryWriteBuffer* pathEffectBuffer,
- SkBinaryWriteBuffer* maskFilterBuffer) {
- size_t descSize = sizeof(rec);
- int entryCount = 1;
-
- if (effects.fPathEffect) {
- effects.fPathEffect->flatten(*pathEffectBuffer);
- descSize += pathEffectBuffer->bytesWritten();
- entryCount += 1;
- }
- if (effects.fMaskFilter) {
- effects.fMaskFilter->flatten(*maskFilterBuffer);
- descSize += maskFilterBuffer->bytesWritten();
- entryCount += 1;
- }
-
- descSize += SkDescriptor::ComputeOverhead(entryCount);
- return descSize;
-}
-
-#ifdef SK_DEBUG
-#define TEST_DESC
-#endif
-
-#ifdef TEST_DESC
-static void test_desc(const SkScalerContextRec& rec,
- const SkScalerContextEffects& effects,
- SkBinaryWriteBuffer* peBuffer,
- SkBinaryWriteBuffer* mfBuffer,
- const SkDescriptor* desc) {
- // Check that we completely write the bytes in desc (our key), and that
- // there are no uninitialized bytes. If there were, then we would get
- // false-misses (or worse, false-hits) in our fontcache.
- //
- // We do this buy filling 2 others, one with 0s and the other with 1s
- // and create those, and then check that all 3 are identical.
- SkAutoDescriptor ad1(desc->getLength());
- SkAutoDescriptor ad2(desc->getLength());
- SkDescriptor* desc1 = ad1.getDesc();
- SkDescriptor* desc2 = ad2.getDesc();
-
- memset(desc1, 0x00, desc->getLength());
- memset(desc2, 0xFF, desc->getLength());
-
- desc1->init();
- desc2->init();
- desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
- desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
-
- auto add_flattenable = [](SkDescriptor* desc, uint32_t tag,
- SkBinaryWriteBuffer* buffer) {
- buffer->writeToMemory(desc->addEntry(tag, buffer->bytesWritten(), nullptr));
- };
-
- if (effects.fPathEffect) {
- add_flattenable(desc1, kPathEffect_SkDescriptorTag, peBuffer);
- add_flattenable(desc2, kPathEffect_SkDescriptorTag, peBuffer);
- }
- if (effects.fMaskFilter) {
- add_flattenable(desc1, kMaskFilter_SkDescriptorTag, mfBuffer);
- add_flattenable(desc2, kMaskFilter_SkDescriptorTag, mfBuffer);
- }
-
- SkASSERT(desc->getLength() == desc1->getLength());
- SkASSERT(desc->getLength() == desc2->getLength());
- desc1->computeChecksum();
- desc2->computeChecksum();
- SkASSERT(!memcmp(desc, desc1, desc->getLength()));
- SkASSERT(!memcmp(desc, desc2, desc->getLength()));
-}
-#endif
-
-void SkScalerContext::GenerateDescriptor(const SkScalerContextRec& rec,
- const SkScalerContextEffects& effects,
- SkBinaryWriteBuffer* pathEffectBuffer,
- SkBinaryWriteBuffer* maskFilterBuffer,
- SkDescriptor* desc) {
- desc->init();
- desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
-
- auto add = [&desc](uint32_t tag, SkBinaryWriteBuffer* buffer) {
- buffer->writeToMemory(desc->addEntry(tag, buffer->bytesWritten(), nullptr));
- };
-
- if (effects.fPathEffect) {
- add(kPathEffect_SkDescriptorTag, pathEffectBuffer);
- }
- if (effects.fMaskFilter) {
- add(kMaskFilter_SkDescriptorTag, maskFilterBuffer);
- }
-
- desc->computeChecksum();
- #ifdef TEST_DESC
- test_desc(rec, effects, pathEffectBuffer, maskFilterBuffer, desc);
- #endif
-}
-
///////////////////////////////////////////////////////////////////////////////
#include "SkStream.h"
@@ -2171,7 +1757,9 @@ SkTextBaseIter::SkTextBaseIter(const char text[], size_t length,
}
// SRGBTODO: Is this correct?
- fCache = fPaint.detachCache(nullptr, SkScalerContextFlags::kFakeGammaAndBoostContrast, nullptr);
+ fCache = SkGlyphCache::DetachCacheUsingPaint(fPaint, nullptr,
+ SkScalerContextFlags::kFakeGammaAndBoostContrast,
+ nullptr);
SkPaint::Style style = SkPaint::kFill_Style;
sk_sp<SkPathEffect> pe;
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index d082232986..f1ac9c18da 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -5,6 +5,8 @@
* found in the LICENSE file.
*/
+#include "SkGlyphCache.h"
+#include "SkPaint.h"
#include "SkScalerContext.h"
#include "SkAutoMalloc.h"
@@ -23,6 +25,8 @@
#include "SkReadBuffer.h"
#include "SkStroke.h"
#include "SkStrokeRec.h"
+#include "SkSurfacePriv.h"
+#include "SkTextFormatParams.h"
#include "SkWriteBuffer.h"
void SkGlyph::toMask(SkMask* mask) const {
@@ -835,3 +839,418 @@ std::unique_ptr<SkScalerContext> SkTypeface::createScalerContext(
}
return c;
}
+
+/*
+ * Return the scalar with only limited fractional precision. Used to consolidate matrices
+ * that vary only slightly when we create our key into the font cache, since the font scaler
+ * typically returns the same looking resuts for tiny changes in the matrix.
+ */
+static SkScalar sk_relax(SkScalar x) {
+ SkScalar n = SkScalarRoundToScalar(x * 1024);
+ return n / 1024.0f;
+}
+
+static SkMask::Format compute_mask_format(const SkPaint& paint) {
+ uint32_t flags = paint.getFlags();
+
+ // Antialiasing being disabled trumps all other settings.
+ if (!(flags & SkPaint::kAntiAlias_Flag)) {
+ return SkMask::kBW_Format;
+ }
+
+ if (flags & SkPaint::kLCDRenderText_Flag) {
+ return SkMask::kLCD16_Format;
+ }
+
+ return SkMask::kA8_Format;
+}
+
+// Beyond this size, LCD doesn't appreciably improve quality, but it always
+// cost more RAM and draws slower, so we set a cap.
+#ifndef SK_MAX_SIZE_FOR_LCDTEXT
+ #define SK_MAX_SIZE_FOR_LCDTEXT 48
+#endif
+
+const SkScalar gMaxSize2ForLCDText = SK_MAX_SIZE_FOR_LCDTEXT * SK_MAX_SIZE_FOR_LCDTEXT;
+
+static bool too_big_for_lcd(const SkScalerContextRec& rec, bool checkPost2x2) {
+ if (checkPost2x2) {
+ SkScalar area = rec.fPost2x2[0][0] * rec.fPost2x2[1][1] -
+ rec.fPost2x2[1][0] * rec.fPost2x2[0][1];
+ area *= rec.fTextSize * rec.fTextSize;
+ return area > gMaxSize2ForLCDText;
+ } else {
+ return rec.fTextSize > SK_MAX_SIZE_FOR_LCDTEXT;
+ }
+}
+
+// if linear-text is on, then we force hinting to be off (since that's sort of
+// the point of linear-text.
+static SkPaint::Hinting computeHinting(const SkPaint& paint) {
+ SkPaint::Hinting h = paint.getHinting();
+ if (paint.isLinearText()) {
+ h = SkPaint::kNo_Hinting;
+ }
+ return h;
+}
+
+// The only reason this is not file static is because it needs the context of SkScalerContext to
+// access SkPaint::computeLuminanceColor.
+void SkScalerContext::MakeRecAndEffects(const SkPaint& paint,
+ const SkSurfaceProps* surfaceProps,
+ const SkMatrix* deviceMatrix,
+ SkScalerContextFlags scalerContextFlags,
+ SkScalerContextRec* rec,
+ SkScalerContextEffects* effects) {
+ SkASSERT(deviceMatrix == nullptr || !deviceMatrix->hasPerspective());
+
+ SkTypeface* typeface = paint.getTypeface();
+ if (nullptr == typeface) {
+ typeface = SkTypeface::GetDefaultTypeface();
+ }
+ rec->fFontID = typeface->uniqueID();
+ rec->fTextSize = paint.getTextSize();
+ rec->fPreScaleX = paint.getTextScaleX();
+ rec->fPreSkewX = paint.getTextSkewX();
+
+ bool checkPost2x2 = false;
+
+ if (deviceMatrix) {
+ const SkMatrix::TypeMask mask = deviceMatrix->getType();
+ if (mask & SkMatrix::kScale_Mask) {
+ rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX());
+ rec->fPost2x2[1][1] = sk_relax(deviceMatrix->getScaleY());
+ checkPost2x2 = true;
+ } else {
+ rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
+ }
+ if (mask & SkMatrix::kAffine_Mask) {
+ rec->fPost2x2[0][1] = sk_relax(deviceMatrix->getSkewX());
+ rec->fPost2x2[1][0] = sk_relax(deviceMatrix->getSkewY());
+ checkPost2x2 = true;
+ } else {
+ rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
+ }
+ } else {
+ rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
+ rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
+ }
+
+ SkPaint::Style style = paint.getStyle();
+ SkScalar strokeWidth = paint.getStrokeWidth();
+
+ unsigned flags = 0;
+
+ if (paint.isFakeBoldText()) {
+#ifdef SK_USE_FREETYPE_EMBOLDEN
+ flags |= SkScalerContext::kEmbolden_Flag;
+#else
+ SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(),
+ kStdFakeBoldInterpKeys,
+ kStdFakeBoldInterpValues,
+ kStdFakeBoldInterpLength);
+ SkScalar extra = paint.getTextSize() * fakeBoldScale;
+
+ if (style == SkPaint::kFill_Style) {
+ style = SkPaint::kStrokeAndFill_Style;
+ strokeWidth = extra; // ignore paint's strokeWidth if it was "fill"
+ } else {
+ strokeWidth += extra;
+ }
+#endif
+ }
+
+ if (paint.isDevKernText()) {
+ flags |= SkScalerContext::kDevKernText_Flag;
+ }
+
+ if (style != SkPaint::kFill_Style && strokeWidth > 0) {
+ rec->fFrameWidth = strokeWidth;
+ rec->fMiterLimit = paint.getStrokeMiter();
+ rec->fStrokeJoin = SkToU8(paint.getStrokeJoin());
+ rec->fStrokeCap = SkToU8(paint.getStrokeCap());
+
+ if (style == SkPaint::kStrokeAndFill_Style) {
+ flags |= SkScalerContext::kFrameAndFill_Flag;
+ }
+ } else {
+ rec->fFrameWidth = 0;
+ rec->fMiterLimit = 0;
+ rec->fStrokeJoin = 0;
+ rec->fStrokeCap = 0;
+ }
+
+ rec->fMaskFormat = SkToU8(compute_mask_format(paint));
+
+ if (SkMask::kLCD16_Format == rec->fMaskFormat) {
+ if (too_big_for_lcd(*rec, checkPost2x2)) {
+ rec->fMaskFormat = SkMask::kA8_Format;
+ flags |= SkScalerContext::kGenA8FromLCD_Flag;
+ } else {
+ SkPixelGeometry geometry = surfaceProps
+ ? surfaceProps->pixelGeometry()
+ : SkSurfacePropsDefaultPixelGeometry();
+ switch (geometry) {
+ case kUnknown_SkPixelGeometry:
+ // eeek, can't support LCD
+ rec->fMaskFormat = SkMask::kA8_Format;
+ flags |= SkScalerContext::kGenA8FromLCD_Flag;
+ break;
+ case kRGB_H_SkPixelGeometry:
+ // our default, do nothing.
+ break;
+ case kBGR_H_SkPixelGeometry:
+ flags |= SkScalerContext::kLCD_BGROrder_Flag;
+ break;
+ case kRGB_V_SkPixelGeometry:
+ flags |= SkScalerContext::kLCD_Vertical_Flag;
+ break;
+ case kBGR_V_SkPixelGeometry:
+ flags |= SkScalerContext::kLCD_Vertical_Flag;
+ flags |= SkScalerContext::kLCD_BGROrder_Flag;
+ break;
+ }
+ }
+ }
+
+ if (paint.isEmbeddedBitmapText()) {
+ flags |= SkScalerContext::kEmbeddedBitmapText_Flag;
+ }
+ if (paint.isSubpixelText()) {
+ flags |= SkScalerContext::kSubpixelPositioning_Flag;
+ }
+ if (paint.isAutohinted()) {
+ flags |= SkScalerContext::kForceAutohinting_Flag;
+ }
+ if (paint.isVerticalText()) {
+ flags |= SkScalerContext::kVertical_Flag;
+ }
+ if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) {
+ flags |= SkScalerContext::kGenA8FromLCD_Flag;
+ }
+ rec->fFlags = SkToU16(flags);
+
+ // these modify fFlags, so do them after assigning fFlags
+ rec->setHinting(computeHinting(paint));
+
+ rec->setLuminanceColor(paint.computeLuminanceColor());
+
+ // For now always set the paint gamma equal to the device gamma.
+ // The math in SkMaskGamma can handle them being different,
+ // but it requires superluminous masks when
+ // Ex : deviceGamma(x) < paintGamma(x) and x is sufficiently large.
+ rec->setDeviceGamma(SK_GAMMA_EXPONENT);
+ rec->setPaintGamma(SK_GAMMA_EXPONENT);
+
+#ifdef SK_GAMMA_CONTRAST
+ rec->setContrast(SK_GAMMA_CONTRAST);
+#else
+ // A value of 0.5 for SK_GAMMA_CONTRAST appears to be a good compromise.
+ // With lower values small text appears washed out (though correctly so).
+ // With higher values lcd fringing is worse and the smoothing effect of
+ // partial coverage is diminished.
+ rec->setContrast(0.5f);
+#endif
+
+ rec->fReservedAlign = 0;
+
+ // Allow the fonthost to modify our rec before we use it as a key into the
+ // cache. This way if we're asking for something that they will ignore,
+ // they can modify our rec up front, so we don't create duplicate cache
+ // entries.
+ typeface->onFilterRec(rec);
+
+ if (!SkToBool(scalerContextFlags & SkScalerContextFlags::kFakeGamma)) {
+ rec->ignoreGamma();
+ }
+ if (!SkToBool(scalerContextFlags & SkScalerContextFlags::kBoostContrast)) {
+ rec->setContrast(0);
+ }
+
+ new (effects) SkScalerContextEffects{paint};
+ if (effects->fPathEffect) {
+ rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion
+ // seems like we could support kLCD as well at this point...
+ }
+ if (effects->fMaskFilter) {
+ // force antialiasing with maskfilters
+ rec->fMaskFormat = SkMask::kA8_Format;
+ // Pre-blend is not currently applied to filtered text.
+ // The primary filter is blur, for which contrast makes no sense,
+ // and for which the destination guess error is more visible.
+ // Also, all existing users of blur have calibrated for linear.
+ rec->ignorePreBlend();
+ }
+
+ // If we're asking for A8, we force the colorlum to be gray, since that
+ // limits the number of unique entries, and the scaler will only look at
+ // the lum of one of them.
+ switch (rec->fMaskFormat) {
+ case SkMask::kLCD16_Format: {
+ // filter down the luminance color to a finite number of bits
+ SkColor color = rec->getLuminanceColor();
+ rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color));
+ break;
+ }
+ case SkMask::kA8_Format: {
+ // filter down the luminance to a single component, since A8 can't
+ // use per-component information
+ SkColor color = rec->getLuminanceColor();
+ U8CPU lum = SkComputeLuminance(SkColorGetR(color),
+ SkColorGetG(color),
+ SkColorGetB(color));
+ // reduce to our finite number of bits
+ color = SkColorSetRGB(lum, lum, lum);
+ rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color));
+ break;
+ }
+ case SkMask::kBW_Format:
+ // No need to differentiate gamma or apply contrast if we're BW
+ rec->ignorePreBlend();
+ break;
+ }
+}
+
+
+SkDescriptor* SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
+ const SkPaint& paint, const SkSurfaceProps* surfaceProps,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix* deviceMatrix, SkAutoDescriptor* ad,
+ SkScalerContextEffects* effects) {
+
+ SkScalerContextRec rec;
+ MakeRecAndEffects(paint, surfaceProps, deviceMatrix, scalerContextFlags, &rec, effects);
+ return AutoDescriptorGivenRecAndEffects(rec, *effects, ad);
+}
+
+static size_t calculate_size_and_flatten(
+ const SkScalerContextRec& rec,
+ const SkScalerContextEffects& effects,
+ SkBinaryWriteBuffer* pathEffectBuffer,
+ SkBinaryWriteBuffer* maskFilterBuffer)
+{
+ size_t descSize = sizeof(rec);
+ int entryCount = 1;
+
+ if (effects.fPathEffect) {
+ effects.fPathEffect->flatten(*pathEffectBuffer);
+ descSize += pathEffectBuffer->bytesWritten();
+ entryCount += 1;
+ }
+ if (effects.fMaskFilter) {
+ effects.fMaskFilter->flatten(*maskFilterBuffer);
+ descSize += maskFilterBuffer->bytesWritten();
+ entryCount += 1;
+ }
+
+ descSize += SkDescriptor::ComputeOverhead(entryCount);
+ return descSize;
+}
+
+#ifdef SK_DEBUG
+ #define TEST_DESC
+#endif
+
+#ifdef TEST_DESC
+static void test_desc(const SkScalerContextRec& rec,
+ const SkScalerContextEffects& effects,
+ SkBinaryWriteBuffer* peBuffer,
+ SkBinaryWriteBuffer* mfBuffer,
+ const SkDescriptor* desc) {
+ // Check that we completely write the bytes in desc (our key), and that
+ // there are no uninitialized bytes. If there were, then we would get
+ // false-misses (or worse, false-hits) in our fontcache.
+ //
+ // We do this buy filling 2 others, one with 0s and the other with 1s
+ // and create those, and then check that all 3 are identical.
+ SkAutoDescriptor ad1(desc->getLength());
+ SkAutoDescriptor ad2(desc->getLength());
+ SkDescriptor* desc1 = ad1.getDesc();
+ SkDescriptor* desc2 = ad2.getDesc();
+
+ memset(desc1, 0x00, desc->getLength());
+ memset(desc2, 0xFF, desc->getLength());
+
+ desc1->init();
+ desc2->init();
+ desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
+ desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
+
+ auto add_flattenable = [](SkDescriptor* desc, uint32_t tag,
+ SkBinaryWriteBuffer* buffer) {
+ buffer->writeToMemory(desc->addEntry(tag, buffer->bytesWritten(), nullptr));
+ };
+
+ if (effects.fPathEffect) {
+ add_flattenable(desc1, kPathEffect_SkDescriptorTag, peBuffer);
+ add_flattenable(desc2, kPathEffect_SkDescriptorTag, peBuffer);
+ }
+ if (effects.fMaskFilter) {
+ add_flattenable(desc1, kMaskFilter_SkDescriptorTag, mfBuffer);
+ add_flattenable(desc2, kMaskFilter_SkDescriptorTag, mfBuffer);
+ }
+
+ SkASSERT(desc->getLength() == desc1->getLength());
+ SkASSERT(desc->getLength() == desc2->getLength());
+ desc1->computeChecksum();
+ desc2->computeChecksum();
+ SkASSERT(!memcmp(desc, desc1, desc->getLength()));
+ SkASSERT(!memcmp(desc, desc2, desc->getLength()));
+}
+#endif
+
+void generate_descriptor(
+ const SkScalerContextRec& rec,
+ const SkScalerContextEffects& effects,
+ SkBinaryWriteBuffer* pathEffectBuffer,
+ SkBinaryWriteBuffer* maskFilterBuffer,
+ SkDescriptor* desc)
+{
+ desc->init();
+ desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
+
+ auto add = [&desc](uint32_t tag, SkBinaryWriteBuffer* buffer) {
+ buffer->writeToMemory(desc->addEntry(tag, buffer->bytesWritten(), nullptr));
+ };
+
+ if (effects.fPathEffect) {
+ add(kPathEffect_SkDescriptorTag, pathEffectBuffer);
+ }
+ if (effects.fMaskFilter) {
+ add(kMaskFilter_SkDescriptorTag, maskFilterBuffer);
+ }
+
+ desc->computeChecksum();
+#ifdef TEST_DESC
+ test_desc(rec, effects, pathEffectBuffer, maskFilterBuffer, desc);
+#endif
+}
+
+SkDescriptor* SkScalerContext::AutoDescriptorGivenRecAndEffects(
+ const SkScalerContextRec& rec,
+ const SkScalerContextEffects& effects,
+ SkAutoDescriptor* ad)
+{
+ SkBinaryWriteBuffer peBuffer, mfBuffer;
+
+ ad->reset(calculate_size_and_flatten(rec, effects, &peBuffer, &mfBuffer));
+
+ generate_descriptor(rec, effects, &peBuffer, &mfBuffer, ad->getDesc());
+
+ return ad->getDesc();
+}
+
+std::unique_ptr<SkDescriptor> SkScalerContext::DescriptorGivenRecAndEffects(
+ const SkScalerContextRec& rec,
+ const SkScalerContextEffects& effects)
+{
+ SkBinaryWriteBuffer peBuffer, mfBuffer;
+
+ auto desc = SkDescriptor::Alloc(calculate_size_and_flatten(rec, effects, &peBuffer, &mfBuffer));
+
+ generate_descriptor(rec, effects, &peBuffer, &mfBuffer, desc.get());
+
+ return desc;
+}
+
+
diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h
index 90cac5dc96..05d12637b2 100644
--- a/src/core/SkScalerContext.h
+++ b/src/core/SkScalerContext.h
@@ -8,6 +8,8 @@
#ifndef SkScalerContext_DEFINED
#define SkScalerContext_DEFINED
+#include <memory>
+
#include "SkGlyph.h"
#include "SkMask.h"
#include "SkMaskFilter.h"
@@ -17,6 +19,7 @@
#include "SkTypeface.h"
#include "SkWriteBuffer.h"
+class SkAutoDescriptor;
class SkDescriptor;
class SkMaskFilter;
class SkPathEffect;
@@ -46,7 +49,6 @@ enum SkAxisAlignment {
kY_SkAxisAlignment
};
-
/*
* To allow this to be forward-declared, it must be its own typename, rather
* than a nested struct inside SkScalerContext (where it started).
@@ -280,11 +282,14 @@ public:
SkScalerContextRec* rec,
SkScalerContextEffects* effects);
- template <typename A>
- static auto CreateDescriptorGivenRecAndEffects(
- const SkScalerContextRec &rec,
- const SkScalerContextEffects &effects,
- A alloc) -> decltype(alloc((size_t)0));
+ static SkDescriptor* AutoDescriptorGivenRecAndEffects(
+ const SkScalerContextRec& rec,
+ const SkScalerContextEffects& effects,
+ SkAutoDescriptor* ad);
+
+ static std::unique_ptr<SkDescriptor> DescriptorGivenRecAndEffects(
+ const SkScalerContextRec& rec,
+ const SkScalerContextEffects& effects);
static SkMaskGamma::PreBlend GetMaskPreBlend(const SkScalerContextRec& rec);
@@ -300,6 +305,12 @@ public:
*/
SkAxisAlignment computeAxisAlignmentForHText();
+ static SkDescriptor* CreateDescriptorAndEffectsUsingPaint(
+ const SkPaint& paint, const SkSurfaceProps* surfaceProps,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix* deviceMatrix, SkAutoDescriptor* ad,
+ SkScalerContextEffects* effects);
+
protected:
SkScalerContextRec fRec;
@@ -353,16 +364,6 @@ protected:
void forceOffGenerateImageFromPath() { fGenerateImageFromPath = false; }
private:
- static size_t CalculateSizeAndFlatten(const SkScalerContextRec& rec,
- const SkScalerContextEffects& effects,
- SkBinaryWriteBuffer* pathEffectBuffer,
- SkBinaryWriteBuffer* maskFilterBuffer);
- static void GenerateDescriptor(const SkScalerContextRec& rec,
- const SkScalerContextEffects& effects,
- SkBinaryWriteBuffer* pathEffectBuffer,
- SkBinaryWriteBuffer* maskFilterBuffer,
- SkDescriptor* desc);
-
friend class SkRandomScalerContext; // For debug purposes
// never null
@@ -389,22 +390,6 @@ private:
const SkMaskGamma::PreBlend fPreBlendForFilter;
};
-template <typename A>
-inline auto SkScalerContext::CreateDescriptorGivenRecAndEffects(
- const SkScalerContextRec &rec,
- const SkScalerContextEffects &effects,
- A alloc) -> decltype(alloc((size_t)0)) {
-
- SkBinaryWriteBuffer peBuffer, mfBuffer;
-
- auto desc = alloc(CalculateSizeAndFlatten(rec, effects, &peBuffer, &mfBuffer));
-
- GenerateDescriptor(rec, effects, &peBuffer, &mfBuffer, &(*desc));
-
- return desc;
-}
-
-
#define kRec_SkDescriptorTag SkSetFourByteTag('s', 'r', 'e', 'c')
#define kPathEffect_SkDescriptorTag SkSetFourByteTag('p', 't', 'h', 'e')
#define kMaskFilter_SkDescriptorTag SkSetFourByteTag('m', 's', 'k', 'f')
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index b47f8c3c13..d3191e2d39 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -341,16 +341,15 @@ bool SkTypeface::onComputeBounds(SkRect* bounds) const {
SkScalerContextRec rec;
SkScalerContextEffects effects;
+
SkScalerContext::MakeRecAndEffects(
paint, nullptr, nullptr, SkScalerContextFlags::kNone, &rec, &effects);
- SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1));
- SkDescriptor* desc = ad.getDesc();
- desc->init();
- desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
-
+ SkAutoDescriptor ad;
SkScalerContextEffects noeffects;
- std::unique_ptr<SkScalerContext> ctx = this->createScalerContext(noeffects, desc, true);
+ SkScalerContext::AutoDescriptorGivenRecAndEffects(rec, noeffects, &ad);
+
+ std::unique_ptr<SkScalerContext> ctx = this->createScalerContext(noeffects, ad.getDesc(), true);
if (!ctx) {
return false;
}
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 7fce4ba856..887addd25c 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -59,7 +59,8 @@ SkGlyphCache* GrAtlasTextBlob::setupCache(int runIndex,
SkAutoDescriptor* desc = run->fOverrideDescriptor.get() ? run->fOverrideDescriptor.get() :
&run->fDescriptor;
SkScalerContextEffects effects;
- skPaint.getScalerContextDescriptor(&effects, desc, &props, scalerContextFlags, viewMatrix);
+ SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
+ skPaint, &props, scalerContextFlags, viewMatrix, desc, &effects);
run->fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
run->fPathEffect = sk_ref_sp(effects.fPathEffect);
run->fMaskFilter = sk_ref_sp(effects.fMaskFilter);
diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp
index 41c46466ac..1dce4e0d44 100644
--- a/src/gpu/text/GrAtlasTextContext.cpp
+++ b/src/gpu/text/GrAtlasTextContext.cpp
@@ -602,8 +602,8 @@ void GrAtlasTextContext::drawDFText(GrAtlasTextBlob* blob, int runIndex,
SkScalerContextEffects effects;
// We apply the fake-gamma by altering the distance in the shader, so we ignore the
// passed-in scaler context flags. (It's only used when we fall-back to bitmap text).
- skPaint.getScalerContextDescriptor(&effects, &desc, &props, SkScalerContextFlags::kNone,
- nullptr);
+ SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
+ skPaint, &props, SkScalerContextFlags::kNone, nullptr, &desc, &effects);
SkGlyphCache* origPaintCache =
SkGlyphCache::DetachCache(skPaint.getTypeface(), effects, desc.getDesc());
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index 2170f0a486..5c45f220ce 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -605,8 +605,9 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
SkGlyphCache* GrStencilAndCoverTextContext::TextRun::getGlyphCache() const {
if (!fDetachedGlyphCache) {
- fDetachedGlyphCache = fFont.detachCache(nullptr, SkScalerContextFlags::kNone,
- nullptr);
+ fDetachedGlyphCache = SkGlyphCache::DetachCacheUsingPaint(fFont, nullptr,
+ SkScalerContextFlags::kNone,
+ nullptr);
}
return fDetachedGlyphCache;
}