Make fPathData private and add API for paths
The new API eliminates all need to access the path inner workings.
There are some uses of the cast (SkGlyph*) these are to facilitate
the larger change this is a part of. The will be eliminated when all
is done.
Some of the code has been changed to use strike->glyph(id) and SkGlyph*
to help with the flow of the code.
Change-Id: Id8dc84076f56e1e39450367a0440d15954dbdc71
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/220523
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index 8b78272..ba675de 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -460,6 +460,12 @@
*/
int getVerbs(uint8_t verbs[], int max) const;
+ /** Returns the approximate byte size of the SkPath in memory.
+
+ @return approximate size
+ */
+ size_t approximateBytesUsed() const;
+
/** Exchanges the verb array, SkPoint array, weights, and SkPath::FillType with other.
Cached state is also exchanged. swap() internally exchanges pointers, so
it is lightweight and does not allocate memory.
diff --git a/src/core/SkFont.cpp b/src/core/SkFont.cpp
index e9881e0..3026148 100644
--- a/src/core/SkFont.cpp
+++ b/src/core/SkFont.cpp
@@ -355,14 +355,14 @@
void (*proc)(const SkPath*, const SkMatrix&, void*), void* ctx) const {
SkFont font(*this);
SkScalar scale = font.setupForAsPaths(nullptr);
- const SkMatrix mx = SkMatrix::MakeScale(scale, scale);
+ const SkMatrix mx = SkMatrix::MakeScale(scale);
SkStrikeSpec strikeSpec = SkStrikeSpec::MakeCanonicalized(font);
auto exclusive = strikeSpec.findOrCreateExclusiveStrike();
auto cache = exclusive.get();
for (int i = 0; i < count; ++i) {
- proc(cache->findPath(cache->getGlyphIDMetrics(glyphs[i])), mx, ctx);
+ proc(cache->preparePath(cache->glyph(glyphs[i])), mx, ctx);
}
}
diff --git a/src/core/SkGlyph.cpp b/src/core/SkGlyph.cpp
index 420ea32..817df32 100644
--- a/src/core/SkGlyph.cpp
+++ b/src/core/SkGlyph.cpp
@@ -117,18 +117,47 @@
return 0u;
}
-SkPath* SkGlyph::addPath(SkScalerContext* scalerContext, SkArenaAlloc* alloc) {
- if (!this->isEmpty()) {
- if (fPathData == nullptr) {
- fPathData = alloc->make<SkGlyph::PathData>();
- if (scalerContext->getPath(this->getPackedID(), &fPathData->fPath)) {
- fPathData->fPath.updateBoundsCache();
- fPathData->fPath.getGenerationID();
- fPathData->fHasPath = true;
- }
- }
+void SkGlyph::installPath(SkArenaAlloc* alloc, const SkPath* path) {
+ SkASSERT(fPathData == nullptr);
+ SkASSERT(!this->setPathHasBeenCalled());
+ fPathData = alloc->make<SkGlyph::PathData>();
+ if (path != nullptr) {
+ fPathData->fPath = *path;
+ fPathData->fPath.updateBoundsCache();
+ fPathData->fPath.getGenerationID();
+ fPathData->fHasPath = true;
}
- return this->path();
+}
+
+bool SkGlyph::setPath(SkArenaAlloc* alloc, SkScalerContext* scalerContext) {
+ if (!this->setPathHasBeenCalled()) {
+ SkPath path;
+ if (scalerContext->getPath(this->getPackedID(), &path)) {
+ this->installPath(alloc, &path);
+ } else {
+ this->installPath(alloc, nullptr);
+ }
+ return this->path() != nullptr;
+ }
+
+ return false;
+}
+
+bool SkGlyph::setPath(SkArenaAlloc* alloc, const SkPath* path) {
+ if (!this->setPathHasBeenCalled()) {
+ this->installPath(alloc, path);
+ return this->path() != nullptr;
+ }
+ return false;
+}
+
+const SkPath* SkGlyph::path() const {
+ // setPath must have been called previously.
+ SkASSERT(this->setPathHasBeenCalled());
+ if (fPathData->fHasPath) {
+ return &fPathData->fPath;
+ }
+ return nullptr;
}
static std::tuple<SkScalar, SkScalar> calculate_path_gap(
@@ -136,7 +165,7 @@
// Left and Right of an ever expanding gap around the path.
SkScalar left = SK_ScalarMax,
- right = SK_ScalarMin;
+ right = SK_ScalarMin;
auto expandGap = [&left, &right](SkScalar v) {
left = SkTMin(left, v);
right = SkTMax(right, v);
diff --git a/src/core/SkGlyph.h b/src/core/SkGlyph.h
index 06c8879..95bda63 100644
--- a/src/core/SkGlyph.h
+++ b/src/core/SkGlyph.h
@@ -153,21 +153,26 @@
SkMask mask(SkPoint position) const;
- SkPath* addPath(SkScalerContext*, SkArenaAlloc*);
+ // If we haven't already tried to associate a path to this glyph
+ // (i.e. setPathHasBeenCalled() returns false), then use the
+ // SkScalerContext or SkPath argument to try to do so. N.B. this
+ // may still result in no path being associated with this glyph,
+ // e.g. if you pass a null SkPath or the typeface is bitmap-only.
+ //
+ // This setPath() call is sticky... once you call it, the glyph
+ // stays in its state permanently, ignoring any future calls.
+ //
+ // Returns true if this is the first time you called setPath()
+ // and there actually is a path; call path() to get it.
+ bool setPath(SkArenaAlloc* alloc, SkScalerContext* scalerContext);
+ bool setPath(SkArenaAlloc* alloc, const SkPath* path);
- SkPath* path() const {
- return fPathData != nullptr && fPathData->fHasPath ? &fPathData->fPath : nullptr;
- }
+ // Returns true if that path has been set.
+ bool setPathHasBeenCalled() const { return fPathData != nullptr; }
- bool hasPath() const {
- // Need to have called getMetrics before calling findPath.
- SkASSERT(fMaskFormat != MASK_FORMAT_UNKNOWN);
-
- // Find path must have been called to use this call.
- SkASSERT(fPathData != nullptr);
-
- return fPathData != nullptr && fPathData->fHasPath;
- }
+ // Return a pointer to the path if it exists, otherwise return nullptr. Only works if the
+ // path was previously set.
+ const SkPath* path() const;
int maxDimension() const {
// width and height are only defined if a metrics call was made.
@@ -190,11 +195,6 @@
void* fImage = nullptr;
- // Path data has tricky state. If the glyph isEmpty, then fPathData should always be nullptr,
- // else if fPathData is not null, then a path has been requested. The fPath field of fPathData
- // may still be null after the request meaning that there is no path for this glyph.
- PathData* fPathData = nullptr;
-
// The width and height of the glyph mask.
uint16_t fWidth = 0,
fHeight = 0;
@@ -239,6 +239,14 @@
bool fHasPath{false};
};
+ // path == nullptr indicates there is no path.
+ void installPath(SkArenaAlloc* alloc, const SkPath* path);
+
+ // Path data has tricky state. If the glyph isEmpty, then fPathData should always be nullptr,
+ // else if fPathData is not null, then a path has been requested. The fPath field of fPathData
+ // may still be null after the request meaning that there is no path for this glyph.
+ PathData* fPathData = nullptr;
+
// The advance for this glyph.
float fAdvanceX = 0,
fAdvanceY = 0;
diff --git a/src/core/SkGlyphRunPainter.cpp b/src/core/SkGlyphRunPainter.cpp
index 061bc17..d086fe0 100644
--- a/src/core/SkGlyphRunPainter.cpp
+++ b/src/core/SkGlyphRunPainter.cpp
@@ -167,16 +167,16 @@
if (check_glyph_position(position)
&& !glyph.isEmpty()
&& glyph.fMaskFormat != SkMask::kARGB32_Format
- && glyph.hasPath())
+ && glyph.path() != nullptr)
{
// Only draw a path if it exists, and this is not a color glyph.
pathsAndPositions.push_back(SkPathPos{glyph.path(), position});
} else {
// TODO: this is here to have chrome layout tests pass. Remove this when
// fallback for CPU works.
- strike->generatePath(glyph);
- if (check_glyph_position(position) && !glyph.isEmpty() && glyph.hasPath()) {
- pathsAndPositions.push_back(SkPathPos{glyph.path(), position});
+ const SkPath* path = strike->preparePath((SkGlyph*) &glyph);
+ if (check_glyph_position(position) && !glyph.isEmpty() && path != nullptr) {
+ pathsAndPositions.push_back(SkPathPos{path, position});
}
}
}
@@ -394,7 +394,8 @@
&& glyph.maxDimension() <= SkStrikeCommon::kSkSideTooBigForAtlas) {
// SDF mask will work.
fGlyphPos[glyphsWithMaskCount++] = glyphPos;
- } else if (glyph.fMaskFormat != SkMask::kARGB32_Format && glyph.hasPath()) {
+ } else if (glyph.fMaskFormat != SkMask::kARGB32_Format
+ && glyph.path() != nullptr) {
// If not color but too big, use a path.
fPaths.push_back(glyphPos);
} else {
@@ -455,7 +456,8 @@
SkPoint position = glyphPos.position;
if (glyph.isEmpty()) {
// do nothing
- } else if (glyph.fMaskFormat != SkMask::kARGB32_Format && glyph.hasPath()) {
+ } else if (glyph.fMaskFormat != SkMask::kARGB32_Format
+ && glyph.path() != nullptr) {
// Place paths in fGlyphPos
fGlyphPos[glyphsWithPathCount++] = glyphPos;
} else {
@@ -512,7 +514,8 @@
if (glyph.maxDimension() <= SkStrikeCommon::kSkSideTooBigForAtlas) {
fGlyphPos[glyphsWithMaskCount++] = glyphPos;
- } else if (glyph.fMaskFormat != SkMask::kARGB32_Format && glyph.hasPath()) {
+ } else if (glyph.fMaskFormat != SkMask::kARGB32_Format
+ && glyph.path() != nullptr) {
fPaths.push_back(glyphPos);
} else {
addFallback(glyph, origin + glyphRun.positions()[glyphPos.index]);
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 8ab8ff4..98b2a51 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -700,6 +700,17 @@
return fPathRef->countVerbs();
}
+size_t SkPath::approximateBytesUsed() const {
+ size_t size = sizeof (SkPath);
+ if (fPathRef != nullptr) {
+ size += fPathRef->countPoints() * sizeof(SkPoint)
+ + fPathRef->countVerbs()
+ + fPathRef->countWeights() * sizeof(SkScalar);
+ }
+
+ return size;
+}
+
bool SkPath::getLastPt(SkPoint* lastPt) const {
SkDEBUGCODE(this->validate();)
diff --git a/src/core/SkRemoteGlyphCache.cpp b/src/core/SkRemoteGlyphCache.cpp
index 51b31b9..f7c78bf 100644
--- a/src/core/SkRemoteGlyphCache.cpp
+++ b/src/core/SkRemoteGlyphCache.cpp
@@ -165,25 +165,6 @@
// Paths use a SkWriter32 which requires 4 byte alignment.
static const size_t kPathAlignment = 4u;
-bool read_path(Deserializer* deserializer, SkGlyph* glyph, SkStrike* cache) {
- uint64_t pathSize = 0u;
- if (!deserializer->read<uint64_t>(&pathSize)) return false;
-
- if (pathSize == 0u) {
- cache->initializePath(glyph, nullptr, 0u);
- return true;
- }
-
- auto* path = deserializer->read(pathSize, kPathAlignment);
- if (!path) return false;
-
- // Don't overwrite the path if we already have one. We could have used a fallback if the
- // glyph was missing earlier.
- if (glyph->fPathData != nullptr) return true;
-
- return cache->initializePath(glyph, path, pathSize);
-}
-
size_t SkDescriptorMapOperators::operator()(const SkDescriptor* key) const {
return key->getChecksum();
}
@@ -579,20 +560,15 @@
//
// A key reason for no path is the fact that the glyph is a color image or is a bitmap only
// font.
-void SkStrikeServer::SkGlyphCacheState::generatePath(const SkGlyph& glyph) {
+const SkPath* SkStrikeServer::SkGlyphCacheState::preparePath(SkGlyph* glyph) {
// Check to see if we have processed this glyph for a path before.
- if (glyph.fPathData == nullptr) {
-
- // Never checked for a path before. Add the path now.
- auto path = const_cast<SkGlyph&>(glyph).addPath(fContext.get(), &fAlloc);
- if (path != nullptr) {
-
- // A path was added make sure to send it to the GPU.
- fCachedGlyphPaths.add(glyph.getPackedID());
- fPendingGlyphPaths.push_back(glyph.getPackedID());
- }
+ if (glyph->setPath(&fAlloc, fContext.get())) {
+ // A path was added make sure to send it to the GPU.
+ fCachedGlyphPaths.add(glyph->getPackedID());
+ fPendingGlyphPaths.push_back(glyph->getPackedID());
}
+ return glyph->path();
}
void SkStrikeServer::SkGlyphCacheState::writeGlyphPath(const SkPackedGlyphID& glyphID,
@@ -644,18 +620,13 @@
// The glyph is too big for the atlas, but it is not color, so it is handled with a
// path.
- if (glyphPtr->fPathData == nullptr) {
-
- // Never checked for a path before. Add the path now.
- const_cast<SkGlyph&>(*glyphPtr).addPath(fContext.get(), &fAlloc);
-
+ if (glyphPtr->setPath(&fAlloc, fContext.get())) {
// Always send the path data, even if its not available, to make sure empty
// paths are not incorrectly assumed to be cache misses.
fCachedGlyphPaths.add(glyphPtr->getPackedID());
fPendingGlyphPaths.push_back(glyphPtr->getPackedID());
}
} else {
-
// This will be handled by the fallback strike.
SkASSERT(glyphPtr->maxDimension() > maxDimension
&& glyphPtr->fMaskFormat == SkMask::kARGB32_Format);
@@ -821,15 +792,19 @@
SkGlyph* allocatedGlyph = strike->getRawGlyphByID(glyph->getPackedID());
- // Update the glyph unless it's already got a path (from fallback),
- // preserving any image that might be present.
- if (allocatedGlyph->fPathData == nullptr) {
- auto* glyphImage = allocatedGlyph->fImage;
- *allocatedGlyph = *glyph;
- allocatedGlyph->fImage = glyphImage;
+ SkPath* pathPtr = nullptr;
+ SkPath path;
+ uint64_t pathSize = 0u;
+ if (!deserializer.read<uint64_t>(&pathSize)) READ_FAILURE
+
+ if (pathSize > 0) {
+ auto* pathData = deserializer.read(pathSize, kPathAlignment);
+ if (!pathData) READ_FAILURE
+ if (!path.readFromMemory(const_cast<const void*>(pathData), pathSize)) READ_FAILURE
+ pathPtr = &path;
}
- if (!read_path(&deserializer, allocatedGlyph, strike.get())) READ_FAILURE
+ strike->preparePath(allocatedGlyph, pathPtr);
}
}
diff --git a/src/core/SkRemoteGlyphCacheImpl.h b/src/core/SkRemoteGlyphCacheImpl.h
index 696c844..99d0824 100644
--- a/src/core/SkRemoteGlyphCacheImpl.h
+++ b/src/core/SkRemoteGlyphCacheImpl.h
@@ -46,7 +46,7 @@
PreparationDetail detail,
SkGlyphPos results[]) override;
- void generatePath(const SkGlyph& glyph) override;
+ const SkPath* preparePath(SkGlyph* glyph) override;
void onAboutToExitScope() override {}
diff --git a/src/core/SkStrike.cpp b/src/core/SkStrike.cpp
index 3f78048..da693ca 100644
--- a/src/core/SkStrike.cpp
+++ b/src/core/SkStrike.cpp
@@ -16,12 +16,6 @@
#include "src/core/SkMakeUnique.h"
#include <cctype>
-namespace {
-size_t compute_path_size(const SkPath& path) {
- return sizeof(SkPath) + path.countPoints() * sizeof(SkPoint);
-}
-} // namespace
-
SkStrike::SkStrike(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
@@ -71,6 +65,10 @@
return this->glyph(SkPackedGlyphID{glyphID});
}
+SkGlyph* SkStrike::glyphOrNull(SkPackedGlyphID id) const {
+ return fGlyphMap.findOrNull(id);
+}
+
SkGlyph* SkStrike::getRawGlyphByID(SkPackedGlyphID id) {
return this->uninitializedGlyph(id);
}
@@ -90,6 +88,20 @@
return *this->glyph(packedGlyphID);
}
+const SkPath* SkStrike::preparePath(SkGlyph* glyph) {
+ if (glyph->setPath(&fAlloc, fScalerContext.get())) {
+ fMemoryUsed += glyph->path()->approximateBytesUsed();
+ }
+ return glyph->path();
+}
+
+const SkPath* SkStrike::preparePath(SkGlyph* glyph, const SkPath* path) {
+ if (glyph->setPath(&fAlloc, path)) {
+ fMemoryUsed += glyph->path()->approximateBytesUsed();
+ }
+ return glyph->path();
+}
+
const SkDescriptor& SkStrike::getDescriptor() const {
return *fDesc.getDesc();
}
@@ -148,46 +160,6 @@
}
}
-const SkPath* SkStrike::findPath(const SkGlyph& glyph) {
-
- if (!glyph.isEmpty()) {
- // If the path already exists, return it.
- if (glyph.fPathData != nullptr) {
- if (glyph.fPathData->fHasPath) {
- return &glyph.fPathData->fPath;
- }
- return nullptr;
- }
-
- const_cast<SkGlyph&>(glyph).addPath(fScalerContext.get(), &fAlloc);
- if (glyph.fPathData != nullptr) {
- fMemoryUsed += compute_path_size(glyph.fPathData->fPath);
- }
-
- return glyph.path();
- }
-
- return nullptr;
-}
-
-bool SkStrike::initializePath(SkGlyph* glyph, const volatile void* data, size_t size) {
- SkASSERT(!glyph->fPathData);
-
- if (glyph->fWidth) {
- SkGlyph::PathData* pathData = fAlloc.make<SkGlyph::PathData>();
- glyph->fPathData = pathData;
- if (size == 0u) return true;
-
- auto path = skstd::make_unique<SkPath>();
- if (!pathData->fPath.readFromMemory(const_cast<const void*>(data), size)) {
- return false;
- }
- fMemoryUsed += compute_path_size(glyph->fPathData->fPath);
- pathData->fHasPath = true;
- }
-
- return true;
-}
bool SkStrike::belongsToCache(const SkGlyph* glyph) const {
return glyph && fGlyphMap.findOrNull(glyph->getPackedID()) == glyph;
@@ -250,7 +222,7 @@
}
} else if (glyph.fMaskFormat != SkMask::kARGB32_Format) {
// The out of atlas glyph is not color so we can draw it using paths.
- this->findPath(glyph);
+ this->preparePath(const_cast<SkGlyph*>(&glyph));
} else {
// This will be handled by the fallback strike.
SkASSERT(glyph.maxDimension() > maxDimension
@@ -285,10 +257,6 @@
SkDebugf("%s\n", msg.c_str());
}
-void SkStrike::generatePath(const SkGlyph& glyph) {
- if (!glyph.isEmpty()) { this->findPath(glyph); }
-}
-
void SkStrike::onAboutToExitScope() { }
#ifdef SK_DEBUG
@@ -299,8 +267,8 @@
if (glyphPtr->fImage) {
memoryUsed += glyphPtr->computeImageSize();
}
- if (glyphPtr->fPathData) {
- memoryUsed += compute_path_size(glyphPtr->fPathData->fPath);
+ if (glyphPtr->setPathHasBeenCalled() && glyphPtr->path() != nullptr) {
+ memoryUsed += glyphPtr->path()->approximateBytesUsed();
}
});
SkASSERT(fMemoryUsed == memoryUsed);
diff --git a/src/core/SkStrike.h b/src/core/SkStrike.h
index 019576a..49aeb84 100644
--- a/src/core/SkStrike.h
+++ b/src/core/SkStrike.h
@@ -66,9 +66,18 @@
SkGlyph* glyph(SkPackedGlyphID id);
SkGlyph* glyph(SkGlyphID);
+ // Return a glyph or nullptr if it does not exits in the strike.
+ SkGlyph* glyphOrNull(SkPackedGlyphID id) const;
+
// Return a glyph. Create it if it doesn't exist, but zero the data.
SkGlyph* uninitializedGlyph(SkPackedGlyphID id);
+ // If the path has never been set, then use the scaler context to add the glyph.
+ const SkPath* preparePath(SkGlyph*) override;
+
+ // If the path has never been set, then add a path to glyph.
+ const SkPath* preparePath(SkGlyph* glyph, const SkPath* path);
+
void getAdvances(SkSpan<const SkGlyphID>, SkPoint[]);
/** Returns the number of glyphs for this strike.
@@ -93,16 +102,6 @@
void findIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos,
SkGlyph* , SkScalar* array, int* count);
- /** Return the Path associated with the glyph. If it has not been generated this will trigger
- that.
- */
- const SkPath* findPath(const SkGlyph&);
-
- /** Initializes the path associated with the glyph with |data|. Returns false if
- * data is invalid.
- */
- bool initializePath(SkGlyph*, const volatile void* data, size_t size);
-
/** Fallback glyphs used during font remoting if the original glyph can't be found.
*/
bool belongsToCache(const SkGlyph* glyph) const;
@@ -131,8 +130,6 @@
const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) override;
- void generatePath(const SkGlyph& glyph) override;
-
const SkDescriptor& getDescriptor() const override;
SkSpan<const SkGlyphPos> prepareForDrawing(const SkGlyphID glyphIDs[],
diff --git a/src/core/SkStrikeCache.cpp b/src/core/SkStrikeCache.cpp
index 747e4cd..26d376b 100644
--- a/src/core/SkStrikeCache.cpp
+++ b/src/core/SkStrikeCache.cpp
@@ -46,8 +46,8 @@
glyphIDs, positions, n, maxDimension, detail, results);
}
- void generatePath(const SkGlyph& glyph) override {
- fStrike.generatePath(glyph);
+ const SkPath* preparePath(SkGlyph* glyph) override {
+ return fStrike.preparePath(glyph);
}
const SkDescriptor& getDescriptor() const override {
@@ -349,12 +349,11 @@
// There is also a problem with accounting for cache size with shared path data.
for (Node* node = internalGetHead(); node != nullptr; node = node->fNext) {
if (loose_compare(node->fStrike.getDescriptor(), desc)) {
- if (node->fStrike.isGlyphCached(glyphID, 0, 0)) {
- SkGlyph* from = node->fStrike.getRawGlyphByID(SkPackedGlyphID(glyphID));
- if (from->fPathData != nullptr) {
+ if (SkGlyph *from = node->fStrike.glyphOrNull(SkPackedGlyphID{glyphID})) {
+ if (from->setPathHasBeenCalled() && from->path() != nullptr) {
// We can just copy the path out by value here, so no need to worry
// about the lifetime of this desperate-match node.
- *path = from->fPathData->fPath;
+ *path = *from->path();
return true;
}
}
diff --git a/src/core/SkStrikeInterface.h b/src/core/SkStrikeInterface.h
index 30250cd..a49aefc 100644
--- a/src/core/SkStrikeInterface.h
+++ b/src/core/SkStrikeInterface.h
@@ -70,8 +70,9 @@
SkGlyphPos results[]) = 0;
virtual const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) = 0;
- // TODO: Deprecated. Do not use. Remove when ARGB fallback for bitmap device paths is working.
- virtual void generatePath(const SkGlyph& glyph) = 0;
+
+ // If glyph does not have an existing path, then add a path to glyph using a scaler context.
+ virtual const SkPath* preparePath(SkGlyph* glyph) = 0;
virtual void onAboutToExitScope() = 0;
struct Deleter {
diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp
index 99517b5..37a5cd6 100644
--- a/src/core/SkTextBlob.cpp
+++ b/src/core/SkTextBlob.cpp
@@ -941,11 +941,11 @@
bool TextInterceptsIter::next(SkScalar* array, int* count) {
SkASSERT(fGlyphs < fStop);
- const SkGlyph& glyph = fCache->getGlyphIDMetrics(*fGlyphs++);
+ SkGlyph* glyph = fCache->glyph(*fGlyphs++);
fXPos += fPrevAdvance * fScale;
- fPrevAdvance = SkFloatToScalar(glyph.advanceX());
- if (fCache->findPath(glyph)) {
- fCache->findIntercepts(fBounds, fScale, fXPos, const_cast<SkGlyph*>(&glyph), array, count);
+ fPrevAdvance = glyph->advanceX();
+ if (fCache->preparePath(glyph) != nullptr) {
+ fCache->findIntercepts(fBounds, fScale, fXPos, glyph, array, count);
}
return fGlyphs < fStop;
}
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 7781f26..35f4dfe 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -778,12 +778,12 @@
if (fontType == SkAdvancedTypefaceMetrics::kOther_Font) {
return false;
}
- const SkGlyph& glyph = cache->getGlyphIDMetrics(gid);
- if (glyph.isEmpty()) {
+ SkGlyph* glyph = cache->glyph(gid);
+ if (glyph->isEmpty()) {
return false;
}
- bool bitmapOnly = nullptr == cache->findPath(glyph);
+ bool bitmapOnly = nullptr == cache->preparePath(glyph);
bool convertedToType3 = (font->getType() == SkAdvancedTypefaceMetrics::kOther_Font);
return convertedToType3 != bitmapOnly;
}
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index b3076bb..afe2ba7 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -181,8 +181,8 @@
}
static bool has_outline_glyph(SkGlyphID gid, SkStrike* cache) {
- const SkGlyph& glyph = cache->getGlyphIDMetrics(gid);
- return glyph.isEmpty() || cache->findPath(glyph);
+ SkGlyph* glyph = cache->glyph(gid);
+ return glyph->isEmpty() || cache->preparePath(glyph);
}
SkPDFFont* SkPDFFont::GetFontResource(SkPDFDocument* doc,
@@ -569,25 +569,24 @@
characterName.set("g0");
} else {
characterName.printf("g%X", gID);
- const SkGlyph& glyph = cache->getGlyphIDMetrics(gID);
- advance = SkFloatToScalar(glyph.advanceX());
- glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop,
- glyph.fWidth, glyph.fHeight);
+ SkGlyph* glyph = cache->glyph(gID);
+ advance = glyph->advanceX();
+ glyphBBox = SkIRect::MakeXYWH(glyph->fLeft, glyph->fTop,
+ glyph->fWidth, glyph->fHeight);
bbox.join(glyphBBox);
- const SkPath* path = cache->findPath(glyph);
+ const SkPath* path = cache->preparePath(glyph);
SkDynamicMemoryWStream content;
if (path && !path->isEmpty()) {
- setGlyphWidthAndBoundingBox(SkFloatToScalar(glyph.advanceX()), glyphBBox, &content);
+ setGlyphWidthAndBoundingBox(glyph->advanceX(), glyphBBox, &content);
SkPDFUtils::EmitPath(*path, SkPaint::kFill_Style, &content);
SkPDFUtils::PaintPath(SkPaint::kFill_Style, path->getFillType(), &content);
} else {
auto pimg = to_image(gID, cache.get());
if (!pimg.fImage) {
- setGlyphWidthAndBoundingBox(SkFloatToScalar(glyph.advanceX()), glyphBBox,
- &content);
+ setGlyphWidthAndBoundingBox(glyph->advanceX(), glyphBBox, &content);
} else {
imageGlyphs.emplace_back(gID, SkPDFSerializeImage(pimg.fImage.get(), doc));
- SkPDFUtils::AppendScalar(SkFloatToScalar(glyph.advanceX()), &content);
+ SkPDFUtils::AppendScalar(glyph->advanceX(), &content);
content.writeText(" 0 d0\n");
content.writeDecAsText(pimg.fImage->width());
content.writeText(" 0 0 ");