Clean up glyph id handling.

Extract SkPackedID and its strongly typed subclasses SkPackedGlyphID and
SkPackedUnicharID out of SkGlyph. This simplifies the code handling
these types, as well as making it clearer that we wouuld eventually like
to get away from this scheme.

Changes SkScalerContext::getPath to take SkPackedGlyphID.
Changes SkScalerContext::generatePath to take SkGlyphID.

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4722

Change-Id: I365c0c618b7ae0d348272155fac7761a69faa920
Reviewed-on: https://skia-review.googlesource.com/4722
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
Ben Wagner 2016-11-11 14:31:06 -05:00 committed by Skia Commit-Bot
parent bf7b620b1e
commit 6e9ac12495
15 changed files with 196 additions and 178 deletions

View File

@ -22,8 +22,9 @@ class SkGlyphCache;
#define kMaxGlyphWidth (1<<13)
SK_BEGIN_REQUIRE_DENSE
class SkGlyph {
/** (glyph-index or unicode-point) + subpixel-pos */
struct SkPackedID {
static constexpr uint32_t kImpossibleID = ~0;
enum {
kSubBits = 2,
kSubMask = ((1 << kSubBits) - 1),
@ -34,6 +35,95 @@ class SkGlyph {
kSubShiftY = 0
};
SkPackedID(uint32_t code) {
SkASSERT(code <= kCodeMask);
SkASSERT(code != kImpossibleID);
fID = code;
}
SkPackedID(uint32_t code, SkFixed x, SkFixed y) {
SkASSERT(code <= kCodeMask);
x = FixedToSub(x);
y = FixedToSub(y);
uint32_t ID = (x << (kSubShift + kSubShiftX)) |
(y << (kSubShift + kSubShiftY)) |
code;
SkASSERT(ID != kImpossibleID);
fID = ID;
}
constexpr SkPackedID() : fID(kImpossibleID) {}
bool operator==(const SkPackedID& that) const {
return fID == that.fID;
}
bool operator!=(const SkPackedID& that) const {
return !(*this == that);
}
uint32_t code() const {
return fID & kCodeMask;
}
SkFixed getSubXFixed() const {
return SubToFixed(ID2SubX(fID));
}
SkFixed getSubYFixed() const {
return SubToFixed(ID2SubY(fID));
}
uint32_t hash() const {
return SkChecksum::CheapMix(fID);
}
// FIXME - This is needed because the Android framework directly accesses fID.
// Remove when fID accesses are cleaned up.
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
operator uint32_t() const { return fID; }
#endif
private:
static unsigned ID2SubX(uint32_t id) {
return id >> (kSubShift + kSubShiftX);
}
static unsigned ID2SubY(uint32_t id) {
return (id >> (kSubShift + kSubShiftY)) & kSubMask;
}
static unsigned FixedToSub(SkFixed n) {
return (n >> (16 - kSubBits)) & kSubMask;
}
static SkFixed SubToFixed(unsigned sub) {
SkASSERT(sub <= kSubMask);
return sub << (16 - kSubBits);
}
uint32_t fID;
};
struct SkPackedGlyphID : public SkPackedID {
SkPackedGlyphID(SkGlyphID code) : SkPackedID(code) { }
SkPackedGlyphID(SkGlyphID code, SkFixed x, SkFixed y) : SkPackedID(code, x, y) { }
SkPackedGlyphID() : SkPackedID() { }
SkGlyphID code() const {
return SkTo<SkGlyphID>(SkPackedID::code());
}
};
struct SkPackedUnicharID : public SkPackedID {
SkPackedUnicharID(SkUnichar code) : SkPackedID(code) { }
SkPackedUnicharID(SkUnichar code, SkFixed x, SkFixed y) : SkPackedID(code, x, y) { }
SkPackedUnicharID() : SkPackedID() { }
SkUnichar code() const {
return SkTo<SkUnichar>(SkPackedID::code());
}
};
SK_BEGIN_REQUIRE_DENSE
class SkGlyph {
// Support horizontal and vertical skipping strike-through / underlines.
// The caller walks the linked list looking for a match. For a horizontal underline,
// the fBounds contains the top and bottom of the underline. The fInterval pair contains the
@ -51,9 +141,7 @@ class SkGlyph {
};
public:
static const SkFixed kSubpixelRound = SK_FixedHalf >> SkGlyph::kSubBits;
// A value that can never be generated by MakeID.
static const uint32_t kImpossibleID = ~0;
static const SkFixed kSubpixelRound = SK_FixedHalf >> SkPackedID::kSubBits;
void* fImage;
PathData* fPathData;
float fAdvanceX, fAdvanceY;
@ -65,16 +153,12 @@ public:
int8_t fRsbDelta, fLsbDelta; // used by auto-kerning
int8_t fForceBW;
void initWithGlyphID(uint32_t glyph_id) {
this->initCommon(MakeID(glyph_id));
}
void initGlyphIdFrom(const SkGlyph& glyph) {
this->initCommon(glyph.fID);
}
void initGlyphFromCombinedID(uint32_t combined_id) {
this->initCommon(combined_id);
void initWithGlyphID(SkPackedGlyphID glyph_id) {
fID = glyph_id;
fImage = nullptr;
fPathData = nullptr;
fMaskFormat = MASK_FORMAT_UNKNOWN;
fForceBW = 0;
}
/**
@ -106,20 +190,20 @@ public:
return MASK_FORMAT_JUST_ADVANCE != fMaskFormat;
}
uint16_t getGlyphID() const {
return ID2Code(fID);
SkGlyphID getGlyphID() const {
return fID.code();
}
unsigned getSubX() const {
return ID2SubX(fID);
SkPackedGlyphID getPackedID() const {
return fID;
}
SkFixed getSubXFixed() const {
return SubToFixed(ID2SubX(fID));
return fID.getSubXFixed();
}
SkFixed getSubYFixed() const {
return SubToFixed(ID2SubY(fID));
return fID.getSubYFixed();
}
size_t computeImageSize() const;
@ -134,11 +218,11 @@ public:
class HashTraits {
public:
static uint32_t GetKey(const SkGlyph& glyph) {
static SkPackedGlyphID GetKey(const SkGlyph& glyph) {
return glyph.fID;
}
static uint32_t Hash(uint32_t glyphId) {
return SkChecksum::CheapMix(glyphId);
static uint32_t Hash(SkPackedGlyphID glyphId) {
return glyphId.hash();
}
};
@ -146,58 +230,12 @@ public:
// TODO(herb) remove friend statement after SkGlyphCache cleanup.
friend class SkGlyphCache;
void initCommon(uint32_t id) {
fID = id;
fImage = nullptr;
fPathData = nullptr;
fMaskFormat = MASK_FORMAT_UNKNOWN;
fForceBW = 0;
}
static unsigned ID2Code(uint32_t id) {
return id & kCodeMask;
}
static unsigned ID2SubX(uint32_t id) {
return id >> (kSubShift + kSubShiftX);
}
static unsigned ID2SubY(uint32_t id) {
return (id >> (kSubShift + kSubShiftY)) & kSubMask;
}
static unsigned FixedToSub(SkFixed n) {
return (n >> (16 - kSubBits)) & kSubMask;
}
static SkFixed SubToFixed(unsigned sub) {
SkASSERT(sub <= kSubMask);
return sub << (16 - kSubBits);
}
static uint32_t MakeID(unsigned code) {
SkASSERT(code <= kCodeMask);
SkASSERT(code != kImpossibleID);
return code;
}
static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) {
SkASSERT(code <= kCodeMask);
x = FixedToSub(x);
y = FixedToSub(y);
uint32_t ID = (x << (kSubShift + kSubShiftX)) |
(y << (kSubShift + kSubShiftY)) |
code;
SkASSERT(ID != kImpossibleID);
return ID;
}
// FIXME - This is needed because the Android frame work directly
// accesses fID. Remove when fID accesses are cleaned up.
// FIXME - This is needed because the Android frame work directly accesses fID.
// Remove when fID accesses are cleaned up.
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
public:
#endif
uint32_t fID;
SkPackedGlyphID fID;
};
SK_END_REQUIRE_DENSE

View File

@ -60,19 +60,12 @@ SkGlyphCache::~SkGlyphCache() {
});
}
SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(PackedUnicharID packedUnicharID) {
if (nullptr == fPackedUnicharIDToPackedGlyphID.get()) {
// Allocate the array.
fPackedUnicharIDToPackedGlyphID.reset(kHashCount);
// Initialize array to map character and position with the impossible glyph ID. This
// represents no mapping.
for (int i = 0; i <kHashCount; ++i) {
fPackedUnicharIDToPackedGlyphID[i].fPackedUnicharID = SkGlyph::kImpossibleID;
fPackedUnicharIDToPackedGlyphID[i].fPackedGlyphID = 0;
}
SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(SkPackedUnicharID packedUnicharID) {
if (!fPackedUnicharIDToPackedGlyphID) {
fPackedUnicharIDToPackedGlyphID.reset(new CharGlyphRec[kHashCount]);
}
return &fPackedUnicharIDToPackedGlyphID[SkChecksum::CheapMix(packedUnicharID) & kHashMask];
return &fPackedUnicharIDToPackedGlyphID[packedUnicharID.hash() & kHashMask];
}
///////////////////////////////////////////////////////////////////////////////
@ -83,24 +76,24 @@ SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(PackedUnicharID packed
#define VALIDATE()
#endif
uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) {
SkGlyphID SkGlyphCache::unicharToGlyph(SkUnichar charCode) {
VALIDATE();
PackedUnicharID packedUnicharID = SkGlyph::MakeID(charCode);
SkPackedUnicharID packedUnicharID(charCode);
CharGlyphRec* rec = this->getCharGlyphRec(packedUnicharID);
if (rec->fPackedUnicharID == packedUnicharID) {
// The glyph exists in the unichar to glyph mapping cache. Return it.
return SkGlyph::ID2Code(rec->fPackedGlyphID);
return rec->fPackedGlyphID.code();
} else {
// The glyph is not in the unichar to glyph mapping cache. Insert it.
rec->fPackedUnicharID = packedUnicharID;
uint16_t glyphID = fScalerContext->charToGlyphID(charCode);
rec->fPackedGlyphID = SkGlyph::MakeID(glyphID);
SkGlyphID glyphID = fScalerContext->charToGlyphID(charCode);
rec->fPackedGlyphID = SkPackedGlyphID(glyphID);
return glyphID;
}
}
SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) {
SkUnichar SkGlyphCache::glyphToUnichar(SkGlyphID glyphID) {
return fScalerContext->glyphIDToChar(glyphID);
}
@ -121,7 +114,7 @@ const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) {
const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) {
VALIDATE();
PackedGlyphID packedGlyphID = SkGlyph::MakeID(glyphID);
SkPackedGlyphID packedGlyphID(glyphID);
return *this->lookupByPackedGlyphID(packedGlyphID, kJustAdvance_MetricsType);
}
@ -139,32 +132,27 @@ const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, SkFixed x, Sk
const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) {
VALIDATE();
PackedGlyphID packedGlyphID = SkGlyph::MakeID(glyphID);
SkPackedGlyphID packedGlyphID(glyphID);
return *this->lookupByPackedGlyphID(packedGlyphID, kFull_MetricsType);
}
const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFixed y) {
VALIDATE();
PackedGlyphID packedGlyphID = SkGlyph::MakeID(glyphID, x, y);
SkPackedGlyphID packedGlyphID(glyphID, x, y);
return *this->lookupByPackedGlyphID(packedGlyphID, kFull_MetricsType);
}
SkGlyph* SkGlyphCache::lookupByChar(SkUnichar charCode, MetricsType type, SkFixed x, SkFixed y) {
PackedUnicharID id = SkGlyph::MakeID(charCode, x, y);
SkPackedUnicharID id(charCode, x, y);
CharGlyphRec* rec = this->getCharGlyphRec(id);
if (rec->fPackedUnicharID != id) {
// this ID is based on the UniChar
rec->fPackedUnicharID = id;
// this ID is based on the glyph index
PackedGlyphID combinedID = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode), x, y);
rec->fPackedGlyphID = combinedID;
return this->lookupByPackedGlyphID(combinedID, type);
} else {
return this->lookupByPackedGlyphID(rec->fPackedGlyphID, type);
rec->fPackedGlyphID = SkPackedGlyphID(fScalerContext->charToGlyphID(charCode), x, y);
}
return this->lookupByPackedGlyphID(rec->fPackedGlyphID, type);
}
SkGlyph* SkGlyphCache::lookupByPackedGlyphID(PackedGlyphID packedGlyphID, MetricsType type) {
SkGlyph* SkGlyphCache::lookupByPackedGlyphID(SkPackedGlyphID packedGlyphID, MetricsType type) {
SkGlyph* glyph = fGlyphMap.find(packedGlyphID);
if (nullptr == glyph) {
@ -177,13 +165,13 @@ SkGlyph* SkGlyphCache::lookupByPackedGlyphID(PackedGlyphID packedGlyphID, Metric
return glyph;
}
SkGlyph* SkGlyphCache::allocateNewGlyph(PackedGlyphID packedGlyphID, MetricsType mtype) {
SkGlyph* SkGlyphCache::allocateNewGlyph(SkPackedGlyphID packedGlyphID, MetricsType mtype) {
fMemoryUsed += sizeof(SkGlyph);
SkGlyph* glyphPtr;
{
SkGlyph glyph;
glyph.initGlyphFromCombinedID(packedGlyphID);
glyph.initWithGlyphID(packedGlyphID);
glyphPtr = fGlyphMap.set(glyph);
}
@ -194,7 +182,7 @@ SkGlyph* SkGlyphCache::allocateNewGlyph(PackedGlyphID packedGlyphID, MetricsType
fScalerContext->getMetrics(glyphPtr);
}
SkASSERT(glyphPtr->fID != SkGlyph::kImpossibleID);
SkASSERT(glyphPtr->fID != SkPackedGlyphID());
return glyphPtr;
}
@ -226,7 +214,7 @@ const SkPath* SkGlyphCache::findPath(const SkGlyph& glyph) {
const_cast<SkGlyph&>(glyph).fPathData = pathData;
pathData->fIntercept = nullptr;
SkPath* path = pathData->fPath = new SkPath;
fScalerContext->getPath(glyph, path);
fScalerContext->getPath(glyph.getPackedID(), path);
fMemoryUsed += sizeof(SkPath) + path->countPoints() * sizeof(SkPoint);
}
}

View File

@ -39,7 +39,7 @@ public:
getGlyphIDMetrics instead.
*/
const SkGlyph& getUnicharAdvance(SkUnichar);
const SkGlyph& getGlyphIDAdvance(uint16_t);
const SkGlyph& getGlyphIDAdvance(SkGlyphID);
/** Returns a glyph with all fields valid except fImage and fPath, which may be null. If they
are null, call findImage or findPath for those. If they are not null, then they are valid.
@ -48,7 +48,7 @@ public:
fAdvance/fDevKern fields, call those instead.
*/
const SkGlyph& getUnicharMetrics(SkUnichar);
const SkGlyph& getGlyphIDMetrics(uint16_t);
const SkGlyph& getGlyphIDMetrics(SkGlyphID);
/** These are variants that take the device position of the glyph. Call these only if you are
drawing in subpixel mode. Passing 0, 0 is effectively the same as calling the variants
@ -60,11 +60,11 @@ public:
/** Return the glyphID for the specified Unichar. If the char has already been seen, use the
existing cache entry. If not, ask the scalercontext to compute it for us.
*/
uint16_t unicharToGlyph(SkUnichar);
SkGlyphID unicharToGlyph(SkUnichar);
/** Map the glyph to its Unicode equivalent. Unmappable glyphs map to a character code of zero.
*/
SkUnichar glyphToUnichar(uint16_t);
SkUnichar glyphToUnichar(SkGlyphID);
/** Returns the number of glyphs for this strike.
*/
@ -187,12 +187,9 @@ private:
kHashMask = kHashCount - 1
};
typedef uint32_t PackedGlyphID; // glyph-index + subpixel-pos
typedef uint32_t PackedUnicharID; // unichar + subpixel-pos
struct CharGlyphRec {
PackedUnicharID fPackedUnicharID;
PackedGlyphID fPackedGlyphID;
SkPackedUnicharID fPackedUnicharID;
SkPackedGlyphID fPackedGlyphID;
};
SkGlyphCache(const SkDescriptor*, std::unique_ptr<SkScalerContext>);
@ -201,19 +198,19 @@ private:
// Return the SkGlyph* associated with MakeID. The id parameter is the
// combined glyph/x/y id generated by MakeID. If it is just a glyph id
// then x and y are assumed to be zero.
SkGlyph* lookupByPackedGlyphID(PackedGlyphID packedGlyphID, MetricsType type);
SkGlyph* lookupByPackedGlyphID(SkPackedGlyphID packedGlyphID, MetricsType type);
// Return a SkGlyph* associated with unicode id and position x and y.
SkGlyph* lookupByChar(SkUnichar id, MetricsType type, SkFixed x = 0, SkFixed y = 0);
// Return a new SkGlyph for the glyph ID and subpixel position id. Limit the amount
// of work using type.
SkGlyph* allocateNewGlyph(PackedGlyphID packedGlyphID, MetricsType type);
SkGlyph* allocateNewGlyph(SkPackedGlyphID packedGlyphID, MetricsType type);
static bool DetachProc(const SkGlyphCache*, void*) { return true; }
// The id arg is a combined id generated by MakeID.
CharGlyphRec* getCharGlyphRec(PackedUnicharID id);
CharGlyphRec* getCharGlyphRec(SkPackedUnicharID id);
static void OffsetResults(const SkGlyph::Intercept* intercept, SkScalar scale,
SkScalar xPos, SkScalar* array, int* count);
@ -236,11 +233,11 @@ private:
SkPaint::FontMetrics fFontMetrics;
// Map from a combined GlyphID and sub-pixel position to a SkGlyph.
SkTHashTable<SkGlyph, PackedGlyphID, SkGlyph::HashTraits> fGlyphMap;
SkTHashTable<SkGlyph, SkPackedGlyphID, SkGlyph::HashTraits> fGlyphMap;
SkChunkAlloc fGlyphAlloc;
SkAutoTArray<CharGlyphRec> fPackedUnicharIDToPackedGlyphID;
std::unique_ptr<CharGlyphRec[]> fPackedUnicharIDToPackedGlyphID;
// used to track (approx) how much ram is tied-up in this cache
size_t fMemoryUsed;

View File

@ -131,7 +131,7 @@ void SkScalerContext::getMetrics(SkGlyph* glyph) {
SkPath devPath, fillPath;
SkMatrix fillToDevMatrix;
this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
this->internalGetPath(glyph->getPackedID(), &fillPath, &devPath, &fillToDevMatrix);
if (fRasterizer) {
SkMask mask;
@ -462,7 +462,7 @@ void SkScalerContext::getImage(const SkGlyph& origGlyph) {
SkMask::kARGB32_Format != origGlyph.fMaskFormat);
if (fMaskFilter) { // restore the prefilter bounds
tmpGlyph.initGlyphIdFrom(origGlyph);
tmpGlyph.initWithGlyphID(origGlyph.getPackedID());
// need the original bounds, sans our maskfilter
SkMaskFilter* mf = fMaskFilter.release(); // temp disable
@ -487,7 +487,7 @@ void SkScalerContext::getImage(const SkGlyph& origGlyph) {
SkMatrix fillToDevMatrix;
SkMask mask;
this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
this->internalGetPath(glyph->getPackedID(), &fillPath, &devPath, &fillToDevMatrix);
glyph->toMask(&mask);
if (fRasterizer) {
@ -564,8 +564,8 @@ void SkScalerContext::getImage(const SkGlyph& origGlyph) {
}
}
void SkScalerContext::getPath(const SkGlyph& glyph, SkPath* path) {
this->internalGetPath(glyph, nullptr, path, nullptr);
void SkScalerContext::getPath(SkPackedGlyphID glyphID, SkPath* path) {
this->internalGetPath(glyphID, nullptr, path, nullptr);
}
void SkScalerContext::getFontMetrics(SkPaint::FontMetrics* fm) {
@ -578,14 +578,14 @@ SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) {
///////////////////////////////////////////////////////////////////////////////
void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
SkPath* devPath, SkMatrix* fillToDevMatrix) {
void SkScalerContext::internalGetPath(SkPackedGlyphID glyphID, SkPath* fillPath,
SkPath* devPath, SkMatrix* fillToDevMatrix) {
SkPath path;
generatePath(glyph, &path);
generatePath(glyphID.code(), &path);
if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
SkFixed dx = glyph.getSubXFixed();
SkFixed dy = glyph.getSubYFixed();
SkFixed dx = glyphID.getSubXFixed();
SkFixed dy = glyphID.getSubYFixed();
if (dx | dy) {
path.offset(SkFixedToScalar(dx), SkFixedToScalar(dy));
}
@ -850,7 +850,7 @@ protected:
glyph->zeroMetrics();
}
void generateImage(const SkGlyph& glyph) override {}
void generatePath(const SkGlyph& glyph, SkPath* path) override {}
void generatePath(SkGlyphID glyph, SkPath* path) override {}
void generateFontMetrics(SkPaint::FontMetrics* metrics) override {
if (metrics) {
sk_bzero(metrics, sizeof(*metrics));

View File

@ -8,13 +8,13 @@
#ifndef SkScalerContext_DEFINED
#define SkScalerContext_DEFINED
#include "SkGlyph.h"
#include "SkMask.h"
#include "SkMaskGamma.h"
#include "SkMatrix.h"
#include "SkPaint.h"
#include "SkTypeface.h"
class SkGlyph;
class SkDescriptor;
class SkMaskFilter;
class SkPathEffect;
@ -248,7 +248,7 @@ public:
void getAdvance(SkGlyph*);
void getMetrics(SkGlyph*);
void getImage(const SkGlyph&);
void getPath(const SkGlyph&, SkPath*);
void getPath(SkPackedGlyphID, SkPath*);
void getFontMetrics(SkPaint::FontMetrics*);
/** Return the size in bytes of the associated gamma lookup table
@ -309,11 +309,8 @@ protected:
/** Sets the passed path to the glyph outline.
* If this cannot be done the path is set to empty;
* this is indistinguishable from a glyph with an empty path.
* This does not set glyph.fPath.
*
* TODO: path is always glyph.fPath, no reason to pass separately.
*/
virtual void generatePath(const SkGlyph& glyph, SkPath* path) = 0;
virtual void generatePath(SkGlyphID glyphId, SkPath* path) = 0;
/** Retrieves font metrics. */
virtual void generateFontMetrics(SkPaint::FontMetrics*) = 0;
@ -350,7 +347,7 @@ private:
// calling generateImage.
bool fGenerateImageFromPath;
void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
void internalGetPath(SkPackedGlyphID id, SkPath* fillPath,
SkPath* devPath, SkMatrix* fillToDevMatrix);
// SkMaskGamma::PreBlend converts linear masks to gamma correcting masks.

View File

@ -53,7 +53,7 @@ protected:
void generateAdvance(SkGlyph*) override;
void generateMetrics(SkGlyph*) override;
void generateImage(const SkGlyph&) override;
void generatePath(const SkGlyph&, SkPath*) override;
void generatePath(SkGlyphID, SkPath*) override;
void generateFontMetrics(SkPaint::FontMetrics*) override;
private:
@ -89,7 +89,7 @@ void SkGScalerContext::generateMetrics(SkGlyph* glyph) {
glyph->fAdvanceY = SkScalarToFloat(advance.fY);
SkPath path;
fProxy->getPath(*glyph, &path);
fProxy->getPath(glyph->getPackedID(), &path);
path.transform(fMatrix);
SkRect storage;
@ -109,7 +109,7 @@ void SkGScalerContext::generateMetrics(SkGlyph* glyph) {
void SkGScalerContext::generateImage(const SkGlyph& glyph) {
if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
SkPath path;
fProxy->getPath(glyph, &path);
fProxy->getPath(glyph.getPackedID(), &path);
SkBitmap bm;
bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
@ -126,8 +126,8 @@ void SkGScalerContext::generateImage(const SkGlyph& glyph) {
}
}
void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) {
fProxy->getPath(glyph, path);
void SkGScalerContext::generatePath(SkGlyphID glyph, SkPath* path) {
fProxy->getPath(SkPackedGlyphID(glyph), path);
path->transform(fMatrix);
}

View File

@ -25,7 +25,7 @@ protected:
void generateAdvance(SkGlyph*) override;
void generateMetrics(SkGlyph*) override;
void generateImage(const SkGlyph&) override;
void generatePath(const SkGlyph&, SkPath*) override;
void generatePath(SkGlyphID, SkPath*) override;
void generateFontMetrics(SkPaint::FontMetrics*) override;
private:
@ -84,7 +84,7 @@ void SkRandomScalerContext::generateMetrics(SkGlyph* glyph) {
}
if (SkMask::kARGB32_Format == format) {
SkPath path;
fProxy->getPath(*glyph, &path);
fProxy->getPath(glyph->getPackedID(), &path);
SkRect storage;
const SkPaint& paint = this->getRandomTypeface()->paint();
@ -101,7 +101,7 @@ void SkRandomScalerContext::generateMetrics(SkGlyph* glyph) {
SkPath devPath, fillPath;
SkMatrix fillToDevMatrix;
this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
this->internalGetPath(glyph->getPackedID(), &fillPath, &devPath, &fillToDevMatrix);
// just use devPath
const SkIRect ir = devPath.getBounds().roundOut();
@ -154,7 +154,7 @@ void SkRandomScalerContext::generateImage(const SkGlyph& glyph) {
if (!fFakeIt) {
if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
SkPath path;
fProxy->getPath(glyph, &path);
fProxy->getPath(glyph.getPackedID(), &path);
SkBitmap bm;
bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
@ -175,8 +175,8 @@ void SkRandomScalerContext::generateImage(const SkGlyph& glyph) {
}
}
void SkRandomScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) {
fProxy->getPath(glyph, path);
void SkRandomScalerContext::generatePath(SkGlyphID glyph, SkPath* path) {
fProxy->generatePath(glyph, path);
}
void SkRandomScalerContext::generateFontMetrics(SkPaint::FontMetrics* metrics) {

View File

@ -137,8 +137,8 @@ void SkTestTypeface::getMetrics(SkGlyph* glyph) {
glyph->fAdvanceY = 0;
}
void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) {
*path = *fTestFont->fPaths[glyph.getGlyphID()];
void SkTestTypeface::getPath(SkGlyphID glyph, SkPath* path) {
*path = *fTestFont->fPaths[glyph];
}
void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
@ -236,7 +236,7 @@ protected:
glyph->fAdvanceY = SkScalarToFloat(advance.fY);
SkPath path;
this->getTestTypeface()->getPath(*glyph, &path);
this->getTestTypeface()->getPath(glyph->getGlyphID(), &path);
path.transform(fMatrix);
SkRect storage;
@ -254,7 +254,7 @@ protected:
void generateImage(const SkGlyph& glyph) override {
SkPath path;
this->getTestTypeface()->getPath(glyph, &path);
this->getTestTypeface()->getPath(glyph.getGlyphID(), &path);
SkBitmap bm;
bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
@ -270,7 +270,7 @@ protected:
canvas.drawPath(path, paint);
}
void generatePath(const SkGlyph& glyph, SkPath* path) override {
void generatePath(SkGlyphID glyph, SkPath* path) override {
this->getTestTypeface()->getPath(glyph, path);
path->transform(fMatrix);
}

View File

@ -60,7 +60,7 @@ public:
void getAdvance(SkGlyph* glyph);
void getFontMetrics(SkPaint::FontMetrics* metrics);
void getMetrics(SkGlyph* glyph);
void getPath(const SkGlyph& glyph, SkPath* path);
void getPath(SkGlyphID glyph, SkPath* path);
protected:
SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
const SkDescriptor* desc) const override;

View File

@ -58,9 +58,7 @@ public:
}
void generatePath(int glyphID, SkPath* out) override {
SkGlyph skGlyph;
skGlyph.initWithGlyphID(glyphID);
fScalerContext->getPath(skGlyph, out);
fScalerContext->getPath(glyphID, out);
}
#ifdef SK_DEBUG
bool isEqualTo(const SkDescriptor& desc) const override { return *fDesc == desc; }

View File

@ -195,7 +195,7 @@ protected:
void generateAdvance(SkGlyph* glyph) override;
void generateMetrics(SkGlyph* glyph) override;
void generateImage(const SkGlyph& glyph) override;
void generatePath(const SkGlyph& glyph, SkPath* path) override;
void generatePath(SkGlyphID glyphID, SkPath* path) override;
void generateFontMetrics(SkPaint::FontMetrics*) override;
SkUnichar generateGlyphToChar(uint16_t glyph) override;
@ -1212,7 +1212,7 @@ void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
}
void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path) {
void SkScalerContext_FreeType::generatePath(SkGlyphID glyphID, SkPath* path) {
SkAutoMutexAcquire ac(gFTMutex);
SkASSERT(path);
@ -1226,11 +1226,11 @@ void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path)
flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
FT_Error err = FT_Load_Glyph( fFace, glyph.getGlyphID(), flags);
FT_Error err = FT_Load_Glyph(fFace, glyphID, flags);
if (err != 0) {
SkDEBUGF(("SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:%d flags:%d) returned 0x%x\n",
glyph.getGlyphID(), flags, err));
glyphID, flags, err));
path->reset();
return;
}

View File

@ -702,7 +702,7 @@ protected:
void generateAdvance(SkGlyph* glyph) override;
void generateMetrics(SkGlyph* glyph) override;
void generateImage(const SkGlyph& glyph) override;
void generatePath(const SkGlyph& glyph, SkPath* path) override;
void generatePath(SkGlyphID glyph, SkPath* path) override;
void generateFontMetrics(SkPaint::FontMetrics*) override;
private:
@ -1373,7 +1373,7 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
*/
#define kScaleForSubPixelPositionHinting (4.0f)
void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) {
void SkScalerContext_Mac::generatePath(SkGlyphID glyph, SkPath* path) {
AUTO_CG_LOCK();
SkScalar scaleX = SK_Scalar1;
@ -1408,7 +1408,7 @@ void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) {
xform = CGAffineTransformConcat(fTransform, scale);
}
CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID();
CGGlyph cgGlyph = SkTo<CGGlyph>(glyph);
AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(fCTFont, cgGlyph, &xform));
path->reset();

View File

@ -546,11 +546,11 @@ protected:
void generateAdvance(SkGlyph* glyph) override;
void generateMetrics(SkGlyph* glyph) override;
void generateImage(const SkGlyph& glyph) override;
void generatePath(const SkGlyph& glyph, SkPath* path) override;
void generatePath(SkGlyphID glyph, SkPath* path) override;
void generateFontMetrics(SkPaint::FontMetrics*) override;
private:
DWORD getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
DWORD getGDIGlyphPath(SkGlyphID glyph, UINT flags,
SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf);
HDCOffscreen fOffscreen;
@ -1589,22 +1589,22 @@ static bool sk_path_from_gdi_paths(SkPath* path, const uint8_t* glyphbuf, DWORD
return true;
}
DWORD SkScalerContext_GDI::getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf)
DWORD SkScalerContext_GDI::getGDIGlyphPath(SkGlyphID glyph, UINT flags,
SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf)
{
GLYPHMETRICS gm;
DWORD total_size = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, BUFFERSIZE, glyphbuf->get(), &fMat22);
DWORD total_size = GetGlyphOutlineW(fDDC, glyph, flags, &gm, BUFFERSIZE, glyphbuf->get(), &fMat22);
// Sometimes GetGlyphOutlineW returns a number larger than BUFFERSIZE even if BUFFERSIZE > 0.
// It has been verified that this does not involve a buffer overrun.
if (GDI_ERROR == total_size || total_size > BUFFERSIZE) {
// GDI_ERROR because the BUFFERSIZE was too small, or because the data was not accessible.
// When the data is not accessable GetGlyphOutlineW fails rather quickly,
// so just try to get the size. If that fails then ensure the data is accessible.
total_size = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, 0, nullptr, &fMat22);
total_size = GetGlyphOutlineW(fDDC, glyph, flags, &gm, 0, nullptr, &fMat22);
if (GDI_ERROR == total_size) {
LogFontTypeface::EnsureAccessible(this->getTypeface());
total_size = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, 0, nullptr, &fMat22);
total_size = GetGlyphOutlineW(fDDC, glyph, flags, &gm, 0, nullptr, &fMat22);
if (GDI_ERROR == total_size) {
// GetGlyphOutlineW is known to fail for some characters, such as spaces.
// In these cases, just return that the glyph does not have a shape.
@ -1614,10 +1614,10 @@ DWORD SkScalerContext_GDI::getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
glyphbuf->reset(total_size);
DWORD ret = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, total_size, glyphbuf->get(), &fMat22);
DWORD ret = GetGlyphOutlineW(fDDC, glyph, flags, &gm, total_size, glyphbuf->get(), &fMat22);
if (GDI_ERROR == ret) {
LogFontTypeface::EnsureAccessible(this->getTypeface());
ret = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, total_size, glyphbuf->get(), &fMat22);
ret = GetGlyphOutlineW(fDDC, glyph, flags, &gm, total_size, glyphbuf->get(), &fMat22);
if (GDI_ERROR == ret) {
SkASSERT(false);
return 0;
@ -1627,7 +1627,7 @@ DWORD SkScalerContext_GDI::getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
return total_size;
}
void SkScalerContext_GDI::generatePath(const SkGlyph& glyph, SkPath* path) {
void SkScalerContext_GDI::generatePath(SkGlyphID glyph, SkPath* path) {
SkASSERT(path);
SkASSERT(fDDC);

View File

@ -887,7 +887,7 @@ void SkScalerContext_DW::generateImage(const SkGlyph& glyph) {
}
}
void SkScalerContext_DW::generatePath(const SkGlyph& glyph, SkPath* path) {
void SkScalerContext_DW::generatePath(SkGlyphID glyph, SkPath* path) {
SkASSERT(path);
path->reset();
@ -895,7 +895,7 @@ void SkScalerContext_DW::generatePath(const SkGlyph& glyph, SkPath* path) {
SkTScopedComPtr<IDWriteGeometrySink> geometryToPath;
HRVM(SkDWriteGeometrySink::Create(path, &geometryToPath),
"Could not create geometry to path converter.");
uint16_t glyphId = glyph.getGlyphID();
UINT16 glyphId = SkTo<UINT16>(glyph);
{
SkAutoExclusive l(DWriteFactoryMutex);
//TODO: convert to<->from DIUs? This would make a difference if hinting.

View File

@ -34,7 +34,7 @@ protected:
void generateAdvance(SkGlyph* glyph) override;
void generateMetrics(SkGlyph* glyph) override;
void generateImage(const SkGlyph& glyph) override;
void generatePath(const SkGlyph& glyph, SkPath* path) override;
void generatePath(SkGlyphID glyph, SkPath* path) override;
void generateFontMetrics(SkPaint::FontMetrics*) override;
private: