Remove GrFontScaler class.
This class is now effectively a set of helpers for interacting with a SkGlyphCache by GrBatchTextStrike. The class is deleted and the code is made into static functions in GrBatchFontCache.cpp
BUG=chromium:608566
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1985163002
Review-Url: https://codereview.chromium.org/1985163002
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index dc16c2c..5c55aec 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -316,8 +316,6 @@
'<(skia_src_path)/gpu/text/GrBatchFontCache.h',
'<(skia_src_path)/gpu/text/GrDistanceFieldAdjustTable.cpp',
'<(skia_src_path)/gpu/text/GrDistanceFieldAdjustTable.h',
- '<(skia_src_path)/gpu/text/GrFontScaler.cpp',
- '<(skia_src_path)/gpu/text/GrFontScaler.h',
'<(skia_src_path)/gpu/text/GrStencilAndCoverTextContext.cpp',
'<(skia_src_path)/gpu/text/GrStencilAndCoverTextContext.h',
'<(skia_src_path)/gpu/text/GrTextBlobCache.cpp',
diff --git a/src/gpu/batches/GrAtlasTextBatch.cpp b/src/gpu/batches/GrAtlasTextBatch.cpp
index bdf6986..2da4938 100644
--- a/src/gpu/batches/GrAtlasTextBatch.cpp
+++ b/src/gpu/batches/GrAtlasTextBatch.cpp
@@ -136,7 +136,6 @@
// in a row
const SkDescriptor* desc = nullptr;
SkGlyphCache* cache = nullptr;
- GrFontScaler* scaler = nullptr;
SkTypeface* typeface = nullptr;
GrBlobRegenHelper helper(this, target, &flushInfo);
@@ -148,7 +147,7 @@
void* blobVertices;
int subRunGlyphCount;
blob->regenInBatch(target, fFontCache, &helper, args.fRun, args.fSubRun, &cache,
- &typeface, &scaler, &desc, vertexStride, args.fViewMatrix, args.fX,
+ &typeface, &desc, vertexStride, args.fViewMatrix, args.fX,
args.fY, args.fColor, &blobVertices, &byteCount, &subRunGlyphCount);
// now copy all vertices
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 03260a6..54af7af 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -48,7 +48,6 @@
return cacheBlob;
}
-
SkGlyphCache* GrAtlasTextBlob::setupCache(int runIndex,
const SkSurfaceProps& props,
uint32_t scalerContextFlags,
@@ -69,12 +68,12 @@
GrColor color,
GrBatchTextStrike* strike,
GrGlyph* glyph,
- GrFontScaler* scaler, const SkGlyph& skGlyph,
+ SkGlyphCache* cache, const SkGlyph& skGlyph,
SkScalar x, SkScalar y, SkScalar scale, bool applyVM) {
// If the glyph is too large we fall back to paths
if (glyph->fTooLargeForAtlas) {
- this->appendLargeGlyph(glyph, scaler, skGlyph, x, y, scale, applyVM);
+ this->appendLargeGlyph(glyph, cache, skGlyph, x, y, scale, applyVM);
return;
}
@@ -152,10 +151,10 @@
subRun->glyphAppended();
}
-void GrAtlasTextBlob::appendLargeGlyph(GrGlyph* glyph, GrFontScaler* scaler, const SkGlyph& skGlyph,
+void GrAtlasTextBlob::appendLargeGlyph(GrGlyph* glyph, SkGlyphCache* cache, const SkGlyph& skGlyph,
SkScalar x, SkScalar y, SkScalar scale, bool applyVM) {
if (nullptr == glyph->fPath) {
- const SkPath* glyphPath = scaler->getGlyphPath(skGlyph);
+ const SkPath* glyphPath = cache->findPath(skGlyph);
if (!glyphPath) {
return;
}
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index e0e9bb8..788eaba 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -160,7 +160,7 @@
GrColor color,
GrBatchTextStrike* strike,
GrGlyph* glyph,
- GrFontScaler* scaler, const SkGlyph& skGlyph,
+ SkGlyphCache*, const SkGlyph& skGlyph,
SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
static size_t GetVertexStride(GrMaskFormat maskFormat) {
@@ -258,8 +258,7 @@
void regenInBatch(GrDrawBatch::Target* target, GrBatchFontCache* fontCache,
GrBlobRegenHelper *helper, int run, int subRun, SkGlyphCache** cache,
- SkTypeface** typeface, GrFontScaler** scaler,
- const SkDescriptor** desc, size_t vertexStride,
+ SkTypeface** typeface, const SkDescriptor** desc, size_t vertexStride,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
GrColor color,
void** vertices, size_t* byteCount, int* glyphCount);
@@ -286,7 +285,7 @@
, fMinMaxScale(SK_ScalarMax)
, fTextType(0) {}
- void appendLargeGlyph(GrGlyph* glyph, GrFontScaler* scaler, const SkGlyph& skGlyph,
+ void appendLargeGlyph(GrGlyph* glyph, SkGlyphCache* cache, const SkGlyph& skGlyph,
SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
inline void flushRun(GrDrawContext* dc, GrPipelineBuilder* pipelineBuilder, const GrClip&,
@@ -491,8 +490,7 @@
GrBatchFontCache* fontCache,
GrBlobRegenHelper* helper,
Run* run, Run::SubRunInfo* info, SkGlyphCache** cache,
- SkTypeface** typeface, GrFontScaler** scaler,
- const SkDescriptor** desc,
+ SkTypeface** typeface, const SkDescriptor** desc,
int glyphCount, size_t vertexStride,
GrColor color, SkScalar transX,
SkScalar transY) const;
diff --git a/src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp b/src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp
index 94bfb1b..e5a8956 100644
--- a/src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp
+++ b/src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp
@@ -143,7 +143,7 @@
GrBlobRegenHelper *helper,
Run* run,
Run::SubRunInfo* info, SkGlyphCache** cache,
- SkTypeface** typeface, GrFontScaler** scaler,
+ SkTypeface** typeface,
const SkDescriptor** desc,
int glyphCount, size_t vertexStride,
GrColor color, SkScalar transX,
@@ -166,12 +166,11 @@
}
*desc = newDesc;
*cache = SkGlyphCache::DetachCache(run->fTypeface, run->fEffects, *desc);
- *scaler = GrTextUtils::GetGrFontScaler(*cache);
*typeface = run->fTypeface;
}
if (regenGlyphs) {
- strike = fontCache->getStrike(*scaler);
+ strike = fontCache->getStrike(*cache);
} else {
strike = info->strike();
}
@@ -188,20 +187,20 @@
// Get the id from the old glyph, and use the new strike to lookup
// the glyph.
GrGlyph::PackedID id = fGlyphs[glyphOffset]->fPackedID;
- fGlyphs[glyphOffset] = strike->getGlyph(id, info->maskFormat(), *scaler);
+ fGlyphs[glyphOffset] = strike->getGlyph(id, info->maskFormat(), *cache);
SkASSERT(id == fGlyphs[glyphOffset]->fPackedID);
}
glyph = fGlyphs[glyphOffset];
SkASSERT(glyph && glyph->fMaskFormat == info->maskFormat());
if (!fontCache->hasGlyph(glyph) &&
- !strike->addGlyphToAtlas(target, glyph, *scaler, info->maskFormat())) {
+ !strike->addGlyphToAtlas(target, glyph, *cache, info->maskFormat())) {
helper->flush();
brokenRun = glyphIdx > 0;
SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(target,
glyph,
- *scaler,
+ *cache,
info->maskFormat());
SkASSERT(success);
}
@@ -248,17 +247,16 @@
kRegenColTexGlyph = kRegenCol | kRegenGlyph,
};
-#define REGEN_ARGS target, fontCache, helper, &run, &info, cache, typeface, scaler, desc, \
+#define REGEN_ARGS target, fontCache, helper, &run, &info, cache, typeface, desc, \
*glyphCount, vertexStride, color, transX, transY
void GrAtlasTextBlob::regenInBatch(GrDrawBatch::Target* target,
GrBatchFontCache* fontCache,
GrBlobRegenHelper *helper,
int runIndex, int subRunIndex, SkGlyphCache** cache,
- SkTypeface** typeface, GrFontScaler** scaler,
- const SkDescriptor** desc, size_t vertexStride,
- const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
- GrColor color,
+ SkTypeface** typeface, const SkDescriptor** desc,
+ size_t vertexStride, const SkMatrix& viewMatrix,
+ SkScalar x, SkScalar y, GrColor color,
void** vertices, size_t* byteCount, int* glyphCount) {
Run& run = fRuns[runIndex];
Run::SubRunInfo& info = run.fSubRunInfo[subRunIndex];
diff --git a/src/gpu/text/GrBatchFontCache.cpp b/src/gpu/text/GrBatchFontCache.cpp
index 06e1994..faafc16 100644
--- a/src/gpu/text/GrBatchFontCache.cpp
+++ b/src/gpu/text/GrBatchFontCache.cpp
@@ -15,8 +15,6 @@
#include "SkDistanceFieldGen.h"
-///////////////////////////////////////////////////////////////////////////////
-
bool GrBatchFontCache::initAtlas(GrMaskFormat format) {
int index = MaskFormatToAtlasIndex(format);
if (!fAtlases[index]) {
@@ -145,6 +143,160 @@
///////////////////////////////////////////////////////////////////////////////
+static inline GrMaskFormat get_packed_glyph_mask_format(const SkGlyph& glyph) {
+ SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
+ switch (format) {
+ case SkMask::kBW_Format:
+ // fall through to kA8 -- we store BW glyphs in our 8-bit cache
+ case SkMask::kA8_Format:
+ return kA8_GrMaskFormat;
+ case SkMask::kLCD16_Format:
+ return kA565_GrMaskFormat;
+ case SkMask::kARGB32_Format:
+ return kARGB_GrMaskFormat;
+ default:
+ SkDEBUGFAIL("unsupported SkMask::Format");
+ return kA8_GrMaskFormat;
+ }
+}
+
+static inline bool get_packed_glyph_bounds(SkGlyphCache* cache, const SkGlyph& glyph,
+ SkIRect* bounds) {
+#if 1
+ // crbug:510931
+ // Retrieving the image from the cache can actually change the mask format.
+ cache->findImage(glyph);
+#endif
+ bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
+
+ return true;
+}
+
+static inline bool get_packed_glyph_df_bounds(SkGlyphCache* cache, const SkGlyph& glyph,
+ SkIRect* bounds) {
+#if 1
+ // crbug:510931
+ // Retrieving the image from the cache can actually change the mask format.
+ cache->findImage(glyph);
+#endif
+ bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
+ bounds->outset(SK_DistanceFieldPad, SK_DistanceFieldPad);
+
+ return true;
+}
+
+// expands each bit in a bitmask to 0 or ~0 of type INT_TYPE. Used to expand a BW glyph mask to
+// A8, RGB565, or RGBA8888.
+template <typename INT_TYPE>
+static void expand_bits(INT_TYPE* dst,
+ const uint8_t* src,
+ int width,
+ int height,
+ int dstRowBytes,
+ int srcRowBytes) {
+ for (int i = 0; i < height; ++i) {
+ int rowWritesLeft = width;
+ const uint8_t* s = src;
+ INT_TYPE* d = dst;
+ while (rowWritesLeft > 0) {
+ unsigned mask = *s++;
+ for (int i = 7; i >= 0 && rowWritesLeft; --i, --rowWritesLeft) {
+ *d++ = (mask & (1 << i)) ? (INT_TYPE)(~0UL) : 0;
+ }
+ }
+ dst = reinterpret_cast<INT_TYPE*>(reinterpret_cast<intptr_t>(dst) + dstRowBytes);
+ src += srcRowBytes;
+ }
+}
+
+static bool get_packed_glyph_image(SkGlyphCache* cache, const SkGlyph& glyph, int width,
+ int height, int dstRB, GrMaskFormat expectedMaskFormat,
+ void* dst) {
+ SkASSERT(glyph.fWidth == width);
+ SkASSERT(glyph.fHeight == height);
+ const void* src = cache->findImage(glyph);
+ if (nullptr == src) {
+ return false;
+ }
+
+ // crbug:510931
+ // Retrieving the image from the cache can actually change the mask format. This case is very
+ // uncommon so for now we just draw a clear box for these glyphs.
+ if (get_packed_glyph_mask_format(glyph) != expectedMaskFormat) {
+ const int bpp = GrMaskFormatBytesPerPixel(expectedMaskFormat);
+ for (int y = 0; y < height; y++) {
+ sk_bzero(dst, width * bpp);
+ dst = (char*)dst + dstRB;
+ }
+ return true;
+ }
+
+ int srcRB = glyph.rowBytes();
+ // The windows font host sometimes has BW glyphs in a non-BW strike. So it is important here to
+ // check the glyph's format, not the strike's format, and to be able to convert to any of the
+ // GrMaskFormats.
+ if (SkMask::kBW_Format == glyph.fMaskFormat) {
+ // expand bits to our mask type
+ const uint8_t* bits = reinterpret_cast<const uint8_t*>(src);
+ switch (expectedMaskFormat) {
+ case kA8_GrMaskFormat:{
+ uint8_t* bytes = reinterpret_cast<uint8_t*>(dst);
+ expand_bits(bytes, bits, width, height, dstRB, srcRB);
+ break;
+ }
+ case kA565_GrMaskFormat: {
+ uint16_t* rgb565 = reinterpret_cast<uint16_t*>(dst);
+ expand_bits(rgb565, bits, width, height, dstRB, srcRB);
+ break;
+ }
+ default:
+ SkFAIL("Invalid GrMaskFormat");
+ }
+ } else if (srcRB == dstRB) {
+ memcpy(dst, src, dstRB * height);
+ } else {
+ const int bbp = GrMaskFormatBytesPerPixel(expectedMaskFormat);
+ for (int y = 0; y < height; y++) {
+ memcpy(dst, src, width * bbp);
+ src = (const char*)src + srcRB;
+ dst = (char*)dst + dstRB;
+ }
+ }
+ return true;
+}
+
+static bool get_packed_glyph_df_image(SkGlyphCache* cache, const SkGlyph& glyph,
+ int width, int height, void* dst) {
+ SkASSERT(glyph.fWidth + 2*SK_DistanceFieldPad == width);
+ SkASSERT(glyph.fHeight + 2*SK_DistanceFieldPad == height);
+ const void* image = cache->findImage(glyph);
+ if (nullptr == image) {
+ return false;
+ }
+ // now generate the distance field
+ SkASSERT(dst);
+ SkMask::Format maskFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
+ if (SkMask::kA8_Format == maskFormat) {
+ // make the distance field from the image
+ SkGenerateDistanceFieldFromA8Image((unsigned char*)dst,
+ (unsigned char*)image,
+ glyph.fWidth, glyph.fHeight,
+ glyph.rowBytes());
+ } else if (SkMask::kBW_Format == maskFormat) {
+ // make the distance field from the image
+ SkGenerateDistanceFieldFromBWImage((unsigned char*)dst,
+ (unsigned char*)image,
+ glyph.fWidth, glyph.fHeight,
+ glyph.rowBytes());
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
/*
The text strike is specific to a given font/style/matrix setup, which is
represented by the GrHostFontScaler object we are given in getGlyph().
@@ -169,18 +321,18 @@
}
GrGlyph* GrBatchTextStrike::generateGlyph(const SkGlyph& skGlyph, GrGlyph::PackedID packed,
- GrFontScaler* scaler) {
+ SkGlyphCache* cache) {
SkIRect bounds;
if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(packed)) {
- if (!scaler->getPackedGlyphDFBounds(skGlyph, &bounds)) {
+ if (!get_packed_glyph_df_bounds(cache, skGlyph, &bounds)) {
return nullptr;
}
} else {
- if (!scaler->getPackedGlyphBounds(skGlyph, &bounds)) {
+ if (!get_packed_glyph_bounds(cache, skGlyph, &bounds)) {
return nullptr;
}
}
- GrMaskFormat format = scaler->getPackedGlyphMaskFormat(skGlyph);
+ GrMaskFormat format = get_packed_glyph_mask_format(skGlyph);
GrGlyph* glyph = (GrGlyph*)fPool.alloc(sizeof(GrGlyph));
glyph->init(packed, bounds, format);
@@ -202,10 +354,10 @@
bool GrBatchTextStrike::addGlyphToAtlas(GrDrawBatch::Target* target,
GrGlyph* glyph,
- GrFontScaler* scaler,
+ SkGlyphCache* cache,
GrMaskFormat expectedMaskFormat) {
SkASSERT(glyph);
- SkASSERT(scaler);
+ SkASSERT(cache);
SkASSERT(fCache.find(glyph->fPackedID));
int bytesPerPixel = GrMaskFormatBytesPerPixel(expectedMaskFormat);
@@ -213,16 +365,16 @@
size_t size = glyph->fBounds.area() * bytesPerPixel;
SkAutoSMalloc<1024> storage(size);
- const SkGlyph& skGlyph = scaler->grToSkGlyph(glyph->fPackedID);
+ const SkGlyph& skGlyph = GrToSkGlyph(cache, glyph->fPackedID);
if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(glyph->fPackedID)) {
- if (!scaler->getPackedGlyphDFImage(skGlyph, glyph->width(), glyph->height(),
- storage.get())) {
+ if (!get_packed_glyph_df_image(cache, skGlyph, glyph->width(), glyph->height(),
+ storage.get())) {
return false;
}
} else {
- if (!scaler->getPackedGlyphImage(skGlyph, glyph->width(), glyph->height(),
- glyph->width() * bytesPerPixel, expectedMaskFormat,
- storage.get())) {
+ if (!get_packed_glyph_image(cache, skGlyph, glyph->width(), glyph->height(),
+ glyph->width() * bytesPerPixel, expectedMaskFormat,
+ storage.get())) {
return false;
}
}
diff --git a/src/gpu/text/GrBatchFontCache.h b/src/gpu/text/GrBatchFontCache.h
index 4429885..42612fe 100644
--- a/src/gpu/text/GrBatchFontCache.h
+++ b/src/gpu/text/GrBatchFontCache.h
@@ -9,9 +9,8 @@
#define GrBatchFontCache_DEFINED
#include "GrBatchAtlas.h"
-#include "GrFontScaler.h"
#include "GrGlyph.h"
-#include "SkGlyph.h"
+#include "SkGlyphCache.h"
#include "SkTDynamicHash.h"
#include "SkVarAlloc.h"
@@ -20,9 +19,9 @@
/**
* The GrBatchTextStrike manages a pool of CPU backing memory for GrGlyphs. This backing memory
- * is indexed by a PackedID and GrFontScaler. The GrFontScaler is what actually creates the mask.
- * The GrBatchTextStrike may outlive the generating GrFontScaler. However, it retains a copy
- * of it's SkDescriptor as a key to access (or regenerate) the GrFontScaler. GrBatchTextStrikes are
+ * is indexed by a PackedID and SkGlyphCache. The SkGlyphCache is what actually creates the mask.
+ * The GrBatchTextStrike may outlive the generating SkGlyphCache. However, it retains a copy
+ * of it's SkDescriptor as a key to access (or regenerate) the SkGlyphCache. GrBatchTextStrikes are
* created by and owned by a GrBatchFontCache.
*/
class GrBatchTextStrike : public SkNVRefCnt<GrBatchTextStrike> {
@@ -32,10 +31,10 @@
~GrBatchTextStrike();
inline GrGlyph* getGlyph(const SkGlyph& skGlyph, GrGlyph::PackedID packed,
- GrFontScaler* scaler) {
+ SkGlyphCache* cache) {
GrGlyph* glyph = fCache.find(packed);
if (nullptr == glyph) {
- glyph = this->generateGlyph(skGlyph, packed, scaler);
+ glyph = this->generateGlyph(skGlyph, packed, cache);
}
return glyph;
}
@@ -46,14 +45,14 @@
// skbug:4143 crbug:510931
inline GrGlyph* getGlyph(GrGlyph::PackedID packed,
GrMaskFormat expectedMaskFormat,
- GrFontScaler* scaler) {
+ SkGlyphCache* cache) {
GrGlyph* glyph = fCache.find(packed);
if (nullptr == glyph) {
// We could return this to the caller, but in practice it adds code complexity for
// potentially little benefit(ie, if the glyph is not in our font cache, then its not
// in the atlas and we're going to be doing a texture upload anyways).
- const SkGlyph& skGlyph = scaler->grToSkGlyph(packed);
- glyph = this->generateGlyph(skGlyph, packed, scaler);
+ const SkGlyph& skGlyph = GrToSkGlyph(cache, packed);
+ glyph = this->generateGlyph(skGlyph, packed, cache);
glyph->fMaskFormat = expectedMaskFormat;
}
return glyph;
@@ -64,7 +63,7 @@
// happen.
// TODO we can handle some of these cases if we really want to, but the long term solution is to
// get the actual glyph image itself when we get the glyph metrics.
- bool addGlyphToAtlas(GrDrawBatch::Target*, GrGlyph*, GrFontScaler*,
+ bool addGlyphToAtlas(GrDrawBatch::Target*, GrGlyph*, SkGlyphCache*,
GrMaskFormat expectedMaskFormat);
// testing
@@ -91,13 +90,19 @@
int fAtlasedGlyphs;
bool fIsAbandoned;
- GrGlyph* generateGlyph(const SkGlyph&, GrGlyph::PackedID, GrFontScaler*);
+ static const SkGlyph& GrToSkGlyph(SkGlyphCache* cache, GrGlyph::PackedID id) {
+ return cache->getGlyphIDMetrics(GrGlyph::UnpackID(id),
+ GrGlyph::UnpackFixedX(id),
+ GrGlyph::UnpackFixedY(id));
+ }
+
+ GrGlyph* generateGlyph(const SkGlyph&, GrGlyph::PackedID, SkGlyphCache*);
friend class GrBatchFontCache;
};
/*
- * GrBatchFontCache manages strikes which are indexed by a GrFontScaler. These strikes can then be
+ * GrBatchFontCache manages strikes which are indexed by a SkGlyphCache. These strikes can then be
* used to individual Glyph Masks. The GrBatchFontCache also manages GrBatchAtlases, though this is
* more or less transparent to the client(aside from atlasGeneration, described below).
* Note - we used to initialize the backing atlas for the GrBatchFontCache at initialization time.
@@ -112,10 +117,10 @@
// another client of the cache may cause the strike to be purged while it is still reffed.
// Therefore, the caller must check GrBatchTextStrike::isAbandoned() if there are other
// interactions with the cache since the strike was received.
- inline GrBatchTextStrike* getStrike(GrFontScaler* scaler) {
- GrBatchTextStrike* strike = fCache.find(scaler->getKey());
+ inline GrBatchTextStrike* getStrike(const SkGlyphCache* cache) {
+ GrBatchTextStrike* strike = fCache.find(cache->getDescriptor());
if (nullptr == strike) {
- strike = this->generateStrike(scaler);
+ strike = this->generateStrike(cache);
}
return strike;
}
@@ -207,8 +212,8 @@
bool initAtlas(GrMaskFormat);
- GrBatchTextStrike* generateStrike(GrFontScaler* scaler) {
- GrBatchTextStrike* strike = new GrBatchTextStrike(this, scaler->getKey());
+ GrBatchTextStrike* generateStrike(const SkGlyphCache* cache) {
+ GrBatchTextStrike* strike = new GrBatchTextStrike(this, cache->getDescriptor());
fCache.add(strike);
return strike;
}
diff --git a/src/gpu/text/GrFontScaler.cpp b/src/gpu/text/GrFontScaler.cpp
deleted file mode 100644
index 796f4d4..0000000
--- a/src/gpu/text/GrFontScaler.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrFontScaler.h"
-#include "SkDescriptor.h"
-#include "SkDistanceFieldGen.h"
-#include "SkGlyphCache.h"
-
-///////////////////////////////////////////////////////////////////////////////
-
-GrFontScaler::GrFontScaler(SkGlyphCache* strike) {
- fStrike = strike;
-}
-
-const SkDescriptor& GrFontScaler::getKey() { return fStrike->getDescriptor(); }
-
-GrMaskFormat GrFontScaler::getPackedGlyphMaskFormat(const SkGlyph& glyph) const {
- SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
- switch (format) {
- case SkMask::kBW_Format:
- // fall through to kA8 -- we store BW glyphs in our 8-bit cache
- case SkMask::kA8_Format:
- return kA8_GrMaskFormat;
- case SkMask::kLCD16_Format:
- return kA565_GrMaskFormat;
- case SkMask::kARGB32_Format:
- return kARGB_GrMaskFormat;
- default:
- SkDEBUGFAIL("unsupported SkMask::Format");
- return kA8_GrMaskFormat;
- }
-}
-
-bool GrFontScaler::getPackedGlyphBounds(const SkGlyph& glyph, SkIRect* bounds) {
-#if 1
- // crbug:510931
- // Retrieving the image from the cache can actually change the mask format.
- fStrike->findImage(glyph);
-#endif
- bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
-
- return true;
-}
-
-bool GrFontScaler::getPackedGlyphDFBounds(const SkGlyph& glyph, SkIRect* bounds) {
-#if 1
- // crbug:510931
- // Retrieving the image from the cache can actually change the mask format.
- fStrike->findImage(glyph);
-#endif
- bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
- bounds->outset(SK_DistanceFieldPad, SK_DistanceFieldPad);
-
- return true;
-}
-
-namespace {
-// expands each bit in a bitmask to 0 or ~0 of type INT_TYPE. Used to expand a BW glyph mask to
-// A8, RGB565, or RGBA8888.
-template <typename INT_TYPE>
-void expand_bits(INT_TYPE* dst,
- const uint8_t* src,
- int width,
- int height,
- int dstRowBytes,
- int srcRowBytes) {
- for (int i = 0; i < height; ++i) {
- int rowWritesLeft = width;
- const uint8_t* s = src;
- INT_TYPE* d = dst;
- while (rowWritesLeft > 0) {
- unsigned mask = *s++;
- for (int i = 7; i >= 0 && rowWritesLeft; --i, --rowWritesLeft) {
- *d++ = (mask & (1 << i)) ? (INT_TYPE)(~0UL) : 0;
- }
- }
- dst = reinterpret_cast<INT_TYPE*>(reinterpret_cast<intptr_t>(dst) + dstRowBytes);
- src += srcRowBytes;
- }
-}
-}
-
-bool GrFontScaler::getPackedGlyphImage(const SkGlyph& glyph, int width, int height, int dstRB,
- GrMaskFormat expectedMaskFormat, void* dst) {
- SkASSERT(glyph.fWidth == width);
- SkASSERT(glyph.fHeight == height);
- const void* src = fStrike->findImage(glyph);
- if (nullptr == src) {
- return false;
- }
-
- // crbug:510931
- // Retrieving the image from the cache can actually change the mask format. This case is very
- // uncommon so for now we just draw a clear box for these glyphs.
- if (getPackedGlyphMaskFormat(glyph) != expectedMaskFormat) {
- const int bpp = GrMaskFormatBytesPerPixel(expectedMaskFormat);
- for (int y = 0; y < height; y++) {
- sk_bzero(dst, width * bpp);
- dst = (char*)dst + dstRB;
- }
- return true;
- }
-
- int srcRB = glyph.rowBytes();
- // The windows font host sometimes has BW glyphs in a non-BW strike. So it is important here to
- // check the glyph's format, not the strike's format, and to be able to convert to any of the
- // GrMaskFormats.
- if (SkMask::kBW_Format == glyph.fMaskFormat) {
- // expand bits to our mask type
- const uint8_t* bits = reinterpret_cast<const uint8_t*>(src);
- switch (expectedMaskFormat) {
- case kA8_GrMaskFormat:{
- uint8_t* bytes = reinterpret_cast<uint8_t*>(dst);
- expand_bits(bytes, bits, width, height, dstRB, srcRB);
- break;
- }
- case kA565_GrMaskFormat: {
- uint16_t* rgb565 = reinterpret_cast<uint16_t*>(dst);
- expand_bits(rgb565, bits, width, height, dstRB, srcRB);
- break;
- }
- default:
- SkFAIL("Invalid GrMaskFormat");
- }
- } else if (srcRB == dstRB) {
- memcpy(dst, src, dstRB * height);
- } else {
- const int bbp = GrMaskFormatBytesPerPixel(expectedMaskFormat);
- for (int y = 0; y < height; y++) {
- memcpy(dst, src, width * bbp);
- src = (const char*)src + srcRB;
- dst = (char*)dst + dstRB;
- }
- }
- return true;
-}
-
-bool GrFontScaler::getPackedGlyphDFImage(const SkGlyph& glyph, int width, int height, void* dst) {
- SkASSERT(glyph.fWidth + 2*SK_DistanceFieldPad == width);
- SkASSERT(glyph.fHeight + 2*SK_DistanceFieldPad == height);
- const void* image = fStrike->findImage(glyph);
- if (nullptr == image) {
- return false;
- }
- // now generate the distance field
- SkASSERT(dst);
- SkMask::Format maskFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
- if (SkMask::kA8_Format == maskFormat) {
- // make the distance field from the image
- SkGenerateDistanceFieldFromA8Image((unsigned char*)dst,
- (unsigned char*)image,
- glyph.fWidth, glyph.fHeight,
- glyph.rowBytes());
- } else if (SkMask::kBW_Format == maskFormat) {
- // make the distance field from the image
- SkGenerateDistanceFieldFromBWImage((unsigned char*)dst,
- (unsigned char*)image,
- glyph.fWidth, glyph.fHeight,
- glyph.rowBytes());
- } else {
- return false;
- }
-
- return true;
-}
-
-const SkPath* GrFontScaler::getGlyphPath(const SkGlyph& glyph) {
- return fStrike->findPath(glyph);
-}
-
-const SkGlyph& GrFontScaler::grToSkGlyph(GrGlyph::PackedID id) {
- return fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(id),
- GrGlyph::UnpackFixedX(id),
- GrGlyph::UnpackFixedY(id));
-}
diff --git a/src/gpu/text/GrFontScaler.h b/src/gpu/text/GrFontScaler.h
deleted file mode 100644
index 41cce99..0000000
--- a/src/gpu/text/GrFontScaler.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrFontScaler_DEFINED
-#define GrFontScaler_DEFINED
-
-#include "GrGlyph.h"
-#include "GrTypes.h"
-
-#include "SkDescriptor.h"
-
-class SkGlyph;
-class SkPath;
-
-/*
- * This is Gr's interface to the host platform's font scaler.
- *
- * The client is responsible for instantiating this. The instance is created
- * for a specific font+size+matrix.
- */
-class GrFontScaler final : public SkNoncopyable {
-public:
- explicit GrFontScaler(SkGlyphCache* strike);
-
- const SkDescriptor& getKey();
- GrMaskFormat getPackedGlyphMaskFormat(const SkGlyph&) const;
- bool getPackedGlyphBounds(const SkGlyph&, SkIRect* bounds);
- bool getPackedGlyphImage(const SkGlyph&, int width, int height, int rowBytes,
- GrMaskFormat expectedMaskFormat, void* image);
- bool getPackedGlyphDFBounds(const SkGlyph&, SkIRect* bounds);
- bool getPackedGlyphDFImage(const SkGlyph&, int width, int height, void* image);
- const SkPath* getGlyphPath(const SkGlyph&);
- const SkGlyph& grToSkGlyph(GrGlyph::PackedID);
-
-private:
- // The SkGlyphCache actually owns this GrFontScaler. The GrFontScaler is deleted when the
- // SkGlyphCache is deleted.
- SkGlyphCache* fStrike;
-
- typedef SkNoncopyable INHERITED;
-};
-
-#endif
diff --git a/src/gpu/text/GrTextUtils.cpp b/src/gpu/text/GrTextUtils.cpp
index da2b3e2..9205d2f 100644
--- a/src/gpu/text/GrTextUtils.cpp
+++ b/src/gpu/text/GrTextUtils.cpp
@@ -56,11 +56,8 @@
GrBatchTextStrike* currStrike = nullptr;
- // Get GrFontScaler from cache
SkGlyphCache* cache = blob->setupCache(runIndex, props, scalerContextFlags, skPaint,
&viewMatrix);
- GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache);
-
SkFindAndPlaceGlyph::ProcessText(
skPaint.getTextEncoding(), text, byteLength,
{x, y}, viewMatrix, skPaint.getTextAlign(),
@@ -70,7 +67,7 @@
BmpAppendGlyph(
blob, runIndex, fontCache, &currStrike, glyph,
SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY),
- color, fontScaler);
+ color, cache);
}
);
@@ -98,10 +95,8 @@
GrBatchTextStrike* currStrike = nullptr;
- // Get GrFontScaler from cache
SkGlyphCache* cache = blob->setupCache(runIndex, props, scalerContextFlags, skPaint,
&viewMatrix);
- GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache);
SkFindAndPlaceGlyph::ProcessPosText(
skPaint.getTextEncoding(), text, byteLength,
@@ -112,7 +107,7 @@
BmpAppendGlyph(
blob, runIndex, fontCache, &currStrike, glyph,
SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY),
- color, fontScaler);
+ color, cache);
}
);
@@ -122,16 +117,16 @@
void GrTextUtils::BmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
GrBatchFontCache* fontCache,
GrBatchTextStrike** strike, const SkGlyph& skGlyph,
- int vx, int vy, GrColor color, GrFontScaler* scaler) {
+ int vx, int vy, GrColor color, SkGlyphCache* cache) {
if (!*strike) {
- *strike = fontCache->getStrike(scaler);
+ *strike = fontCache->getStrike(cache);
}
GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
skGlyph.getSubXFixed(),
skGlyph.getSubYFixed(),
GrGlyph::kCoverage_MaskStyle);
- GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, scaler);
+ GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, cache);
if (!glyph) {
return;
}
@@ -149,7 +144,7 @@
r.fRight = r.fLeft + SkIntToScalar(width);
r.fBottom = r.fTop + SkIntToScalar(height);
- blob->appendGlyph(runIndex, r, color, *strike, glyph, scaler, skGlyph,
+ blob->appendGlyph(runIndex, r, color, *strike, glyph, cache, skGlyph,
SkIntToScalar(vx), SkIntToScalar(vy), 1.0f, false);
}
@@ -351,7 +346,6 @@
SkGlyphCache* cache = blob->setupCache(runIndex, props, SkPaint::kNone_ScalerContextFlags,
dfPaint, nullptr);
SkPaint::GlyphCacheProc glyphCacheProc = dfPaint.getGlyphCacheProc(true);
- GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache);
const char* stop = text + byteLength;
@@ -370,7 +364,7 @@
fontCache,
&currStrike,
glyph,
- x, y, color, fontScaler,
+ x, y, color, cache,
textRatio, viewMatrix)) {
// couldn't append, send to fallback
fallbackTxt.append(SkToInt(text-lastText), lastText);
@@ -403,7 +397,7 @@
&currStrike,
glyph,
x - advanceX, y - advanceY, color,
- fontScaler,
+ cache,
textRatio,
viewMatrix)) {
// couldn't append, send to fallback
@@ -431,17 +425,17 @@
bool GrTextUtils::DfAppendGlyph(GrAtlasTextBlob* blob, int runIndex, GrBatchFontCache* cache,
GrBatchTextStrike** strike, const SkGlyph& skGlyph,
SkScalar sx, SkScalar sy, GrColor color,
- GrFontScaler* scaler,
+ SkGlyphCache* glyphCache,
SkScalar textRatio, const SkMatrix& viewMatrix) {
if (!*strike) {
- *strike = cache->getStrike(scaler);
+ *strike = cache->getStrike(glyphCache);
}
GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
skGlyph.getSubXFixed(),
skGlyph.getSubYFixed(),
GrGlyph::kDistance_MaskStyle);
- GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, scaler);
+ GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, glyphCache);
if (!glyph) {
return true;
}
@@ -465,7 +459,7 @@
sy += dy;
SkRect glyphRect = SkRect::MakeXYWH(sx, sy, width, height);
- blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, scaler, skGlyph,
+ blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, glyphCache, skGlyph,
sx - dx, sy - dy, scale, true);
return true;
}
@@ -569,23 +563,3 @@
return flags;
}
-
-static void glyph_cache_aux_proc(void* data) {
- GrFontScaler* scaler = (GrFontScaler*)data;
- delete scaler;
-}
-
-GrFontScaler* GrTextUtils::GetGrFontScaler(SkGlyphCache* cache) {
- void* auxData;
- GrFontScaler* scaler = nullptr;
-
- if (cache->getAuxProcData(glyph_cache_aux_proc, &auxData)) {
- scaler = (GrFontScaler*)auxData;
- }
- if (nullptr == scaler) {
- scaler = new GrFontScaler(cache);
- cache->setAuxProc(glyph_cache_aux_proc, scaler);
- }
-
- return scaler;
-}
diff --git a/src/gpu/text/GrTextUtils.h b/src/gpu/text/GrTextUtils.h
index 7823473..c218ab7 100644
--- a/src/gpu/text/GrTextUtils.h
+++ b/src/gpu/text/GrTextUtils.h
@@ -18,7 +18,6 @@
class GrClip;
class GrContext;
class GrDrawContext;
-class GrFontScaler;
class GrShaderCaps;
class SkGlyph;
class SkMatrix;
@@ -85,7 +84,6 @@
static bool ShouldDisableLCD(const SkPaint& paint);
- static GrFontScaler* GetGrFontScaler(SkGlyphCache* cache);
static uint32_t FilterTextFlags(const SkSurfaceProps& surfaceProps, const SkPaint& paint);
private:
@@ -96,12 +94,12 @@
static void BmpAppendGlyph(GrAtlasTextBlob*, int runIndex, GrBatchFontCache*,
GrBatchTextStrike**, const SkGlyph&, int left, int top,
- GrColor color, GrFontScaler*);
+ GrColor color, SkGlyphCache*);
static bool DfAppendGlyph(GrAtlasTextBlob*, int runIndex, GrBatchFontCache*,
GrBatchTextStrike**, const SkGlyph&,
SkScalar sx, SkScalar sy, GrColor color,
- GrFontScaler* scaler,
+ SkGlyphCache* cache,
SkScalar textRatio, const SkMatrix& viewMatrix);
};