plumb PackedGlyphID for path serialization

The packedGlyphID is needed to create a serialized form for
PathSubRuns.

+ param alignments.

Change-Id: Idc48e44c46078330434e36f1e972884388a10bd9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/512718
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2022-02-24 09:36:06 -05:00 committed by SkCQ
parent a83b8c6a78
commit 0b2a5b9a03
5 changed files with 20 additions and 38 deletions

View File

@ -105,12 +105,6 @@ public:
fV.glyph = glyph;
SkDEBUGCODE(fTag = kGlyph);
return *this;
}
SkGlyphVariant& operator= (const SkPath* path) {
fV.path = path;
SkDEBUGCODE(fTag = kPath);
return *this;
}
SkGlyphVariant& operator= (SkDrawable* drawable) {
fV.drawable = drawable;
@ -122,10 +116,6 @@ public:
SkASSERT(fTag == kGlyph);
return fV.glyph;
}
const SkPath* path() const {
SkASSERT(fTag == kPath);
return fV.path;
}
SkDrawable* drawable() const {
SkASSERT(fTag == kDrawable);
return fV.drawable;
@ -137,13 +127,11 @@ public:
operator SkPackedGlyphID() const { return this->packedID(); }
operator const SkGlyph*() const { return this->glyph(); }
operator const SkPath*() const { return this->path(); }
operator const SkDrawable*()const { return this->drawable(); }
private:
union {
const SkGlyph* glyph;
const SkPath* path;
SkDrawable* drawable;
SkPackedGlyphID packedID;
} fV;
@ -153,14 +141,13 @@ private:
kEmpty,
kPackedID,
kGlyph,
kPath,
kDrawable,
} fTag{kEmpty};
#endif
};
// A buffer for converting SkPackedGlyph to SkGlyph* or SkPath*. Initially the buffer contains
// SkPackedGlyphIDs, but those are used to lookup SkGlyph*/SkPath* which are then copied over the
// A buffer for converting SkPackedGlyph to SkGlyph*s. Initially the buffer contains
// SkPackedGlyphIDs, but those are used to lookup SkGlyph*s which are then copied over the
// SkPackedGlyphIDs.
class SkDrawableGlyphBuffer {
public:
@ -180,7 +167,7 @@ public:
//
// The positions are calculated integer positions in devices space, and the mapping of the
// the source origin through the initial matrix is returned. It is given that these positions
// are only reused when the blob is translated by an integral amount. Thus the shifted
// are only reused when the blob is translated by an integral amount. Thus, the shifted
// positions are given by the following equation where (ix, iy) is the integer positions of
// the glyph, initialMappedOrigin is (0,0) in source mapped to the device using the initial
// matrix, and newMappedOrigin is (0,0) in source mapped to the device using the current
@ -213,15 +200,6 @@ public:
fAcceptedSize++;
}
// Store the path in the next slot, using the position information located at index from.
void accept(const SkPath* path, size_t from) {
SkASSERT(fPhase == kProcess);
SkASSERT(fAcceptedSize <= from);
fPositions[fAcceptedSize] = fPositions[from];
fMultiBuffer[fAcceptedSize] = path;
fAcceptedSize++;
}
// Store drawable in the next slot, using the position information located at index from.
void accept(SkDrawable* drawable, size_t from) {
SkASSERT(fPhase == kProcess);

View File

@ -123,7 +123,7 @@ void SkGlyphRunListPainter::drawForBitmapDevice(
|| (stroking && !hairline);
if (!needsExactCTM) {
for (auto [variant, pos] : fAccepted.accepted()) {
const SkPath* path = variant.path();
const SkPath* path = variant.glyph()->path();
SkMatrix m;
SkPoint translate = drawOrigin + pos;
m.setScaleTranslate(strikeToSourceScale, strikeToSourceScale,
@ -134,7 +134,7 @@ void SkGlyphRunListPainter::drawForBitmapDevice(
}
} else {
for (auto [variant, pos] : fAccepted.accepted()) {
const SkPath* path = variant.path();
const SkPath* path = variant.glyph()->path();
SkMatrix m;
SkPoint translate = drawOrigin + pos;
m.setScaleTranslate(strikeToSourceScale, strikeToSourceScale,

View File

@ -59,12 +59,12 @@ SkGlyphDigest SkScalerCache::addGlyph(SkGlyph* glyph) {
return digest;
}
std::tuple<const SkPath*, size_t> SkScalerCache::preparePath(SkGlyph* glyph) {
size_t SkScalerCache::preparePath(SkGlyph* glyph) {
size_t delta = 0;
if (glyph->setPath(&fAlloc, fScalerContext.get())) {
delta = glyph->path()->approximateBytesUsed();
}
return {glyph->path(), delta};
return delta;
}
std::tuple<const SkPath*, size_t> SkScalerCache::mergePath(
@ -116,7 +116,7 @@ std::tuple<SkSpan<const SkGlyph*>, size_t> SkScalerCache::internalPrepare(
auto [glyph, size] = this->glyph(SkPackedGlyphID{glyphID});
delta += size;
if (pathDetail == kMetricsAndPath) {
auto [_, pathSize] = this->preparePath(glyph);
size_t pathSize = this->preparePath(glyph);
delta += pathSize;
}
*cursor++ = glyph;
@ -259,11 +259,11 @@ size_t SkScalerCache::prepareForPathDrawing(
size_t delta = this->commonFilterLoop(accepted,
[&](size_t i, SkGlyphDigest digest, SkPoint pos) SK_REQUIRES(fMu) {
SkGlyph* glyph = fGlyphForIndex[digest.index()];
auto [path, pathSize] = this->preparePath(glyph);
auto pathSize = this->preparePath(glyph);
pathDelta += pathSize;
if (path != nullptr) {
if (glyph->path() != nullptr) {
// Save off the path to draw later.
accepted->accept(path, i);
accepted->accept(glyph, i);
} else {
// Glyph does not have a path.
rejected->reject(i, digest.maxDimension());

View File

@ -104,7 +104,7 @@ private:
std::tuple<const void*, size_t> prepareImage(SkGlyph* glyph) SK_REQUIRES(fMu);
// If the path has never been set, then use the scaler context to add the glyph.
std::tuple<const SkPath*, size_t> preparePath(SkGlyph*) SK_REQUIRES(fMu);
size_t preparePath(SkGlyph*) SK_REQUIRES(fMu);
// If the drawable has never been set, then use the scaler context to add the glyph.
std::tuple<SkDrawable*, size_t> prepareDrawable(SkGlyph*) SK_REQUIRES(fMu);

View File

@ -12,6 +12,7 @@
#include "include/private/chromium/GrSlug.h"
#include "include/private/chromium/SkChromeRemoteGlyphCache.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkMaskFilterBase.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkPaintPriv.h"
@ -430,6 +431,8 @@ private:
struct PathAndPosition {
SkPath fPath;
SkPoint fPosition;
// Support for serialization.
SkPackedGlyphID fPackedID;
};
const bool fIsAntiAliased;
const SkScalar fStrikeToSourceScale;
@ -463,7 +466,8 @@ PathOpSubmitter PathOpSubmitter::Make(const SkZip<SkGlyphVariant, SkPoint>& acce
accepted.size(),
[&](int i){
auto [variant, pos] = accepted[i];
return PathAndPosition{*variant.path(), pos};
const SkGlyph& glyph = *variant.glyph();
return PathAndPosition{*glyph.path(), pos, glyph.getPackedID()};
});
SkSpan<PathAndPosition> paths{pathData.get(), accepted.size()};
@ -1548,9 +1552,9 @@ GrSubRunOwner SDFTSubRun::Make(const GrTextReferenceFrame* referenceFrame,
}
GrSubRunOwner SDFTSubRun::MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
const SkStrikeClient* client) {
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
const SkStrikeClient* client) {
SkRect sourceBounds = buffer.readRect();
int useLCD = buffer.readInt();
int isAntiAliased = buffer.readInt();