Clean up glyph id handling.
authorBen Wagner <bungeman@google.com>
Fri, 11 Nov 2016 19:31:06 +0000 (14:31 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 11 Nov 2016 21:59:54 +0000 (21:59 +0000)
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>
15 files changed:
src/core/SkGlyph.h
src/core/SkGlyphCache.cpp
src/core/SkGlyphCache.h
src/core/SkScalerContext.cpp
src/core/SkScalerContext.h
src/fonts/SkGScalerContext.cpp
src/fonts/SkRandomScalerContext.cpp
src/fonts/SkTestScalerContext.cpp
src/fonts/SkTestScalerContext.h
src/gpu/GrPathRendering.cpp
src/ports/SkFontHost_FreeType.cpp
src/ports/SkFontHost_mac.cpp
src/ports/SkFontHost_win.cpp
src/ports/SkScalerContext_win_dw.cpp
src/ports/SkScalerContext_win_dw.h

index 04f9296b556ae6e98f0bf48a30f89bd32343c657..73f8704f6498d1e4a26566acac7af47a943722e1 100644 (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
 
index 7526bbf256155ce61b9b9dc1e391275248473d8f..c1abcd1f26b60943421f5eb9615c23f2ac54e185 100644 (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);
         }
     }
index 863b2c82fbd575d95b6236aed8db5a888b153895..8cb5337737efcb76e58c4eaadee068f7e5c3fec0 100644 (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;
index 581e1020341c7cbce6835c5f09aba94a71e7a2f6..c06222d4d8832ee5e343cf989babcce633bb35dd 100644 (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));
index 61f94ad0064344f41ff0d521ffb6c3f7b4523d7e..7bfdb92a52c97088283026caeec482ae8bf48ddc 100644 (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.
index 53d385437e86b8920a8b1bff94f6209fae48cc4d..9da05492e6ce2d64ca7b43b0d283881de59404c6 100644 (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);
 }
 
index 96a2619876c095385fe58978625c86533a8e0017..55c7fb30d4a4f1833dac6282e0af3cba94b3da82 100644 (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) {
index 7a97ca8bba5a7e5cb2ab6bf6b7043392ea7a1dae..d84571d310c5e782021d980f826a1f8bb50e231b 100644 (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);
     }
index 90945970fa3563b6fb6dc8766f0c2c08b30cd327..217e57c2a468cfc2aab4ed6a483c9870825cba4d 100644 (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;
index ae5bcf643a6564818ef0e245cc522544b6335361..18d000a17793f061f45b3a6650d6d1acfcc50e54 100644 (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; }
index 2eaf2bf06e86c1dae3139f7a3a125a7e53da617d..0a4e63688d336d8adb486ad9c663afe516a305af 100644 (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;
     }
index a9b9a2a70e3c9341605ca80e3f90f7866548b343..a9f6bb0a6eb79c7907b2f7e92aea2b367755d0ee 100644 (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();
index 77465ceff41ff2af37ce6a57c234cac6d7439869..9229be6d301b0dd95f9d86818df0c4fff3e2fc82 100644 (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);
 
index c83542f47a0324644d95074e96f549ef0826e3ba..10afb5a0ca466ca08ef2bdd456fed206162c44ce 100644 (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.
index bcb7ab47dbdd5ab4774f1d1ee0fa39370c8738f3..7b45c320caf9313b90759b27d8635cdfb4365290 100644 (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: