1bbe50131413098bffed9186660c41f047d881596bungeman@google.com/*
2bbe50131413098bffed9186660c41f047d881596bungeman@google.com * Copyright 2006 The Android Open Source Project
3bbe50131413098bffed9186660c41f047d881596bungeman@google.com *
4bbe50131413098bffed9186660c41f047d881596bungeman@google.com * Use of this source code is governed by a BSD-style license that can be
5bbe50131413098bffed9186660c41f047d881596bungeman@google.com * found in the LICENSE file.
6bbe50131413098bffed9186660c41f047d881596bungeman@google.com */
7bbe50131413098bffed9186660c41f047d881596bungeman@google.com
8bbe50131413098bffed9186660c41f047d881596bungeman@google.com#ifndef SkGlyph_DEFINED
9bbe50131413098bffed9186660c41f047d881596bungeman@google.com#define SkGlyph_DEFINED
10bbe50131413098bffed9186660c41f047d881596bungeman@google.com
117c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby#include "SkArenaAlloc.h"
12c71239b9ff7d8c19dc03cb6c9081e7dc4e0947d2herb#include "SkChecksum.h"
13bbe50131413098bffed9186660c41f047d881596bungeman@google.com#include "SkFixed.h"
14bbe50131413098bffed9186660c41f047d881596bungeman@google.com#include "SkMask.h"
157c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby#include "SkTypes.h"
167c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby
17bbe50131413098bffed9186660c41f047d881596bungeman@google.com
18bbe50131413098bffed9186660c41f047d881596bungeman@google.comclass SkPath;
19b69d0e0ac45e13f667bc11a937dcb547072bc93dherbclass SkGlyphCache;
20bbe50131413098bffed9186660c41f047d881596bungeman@google.com
21bbe50131413098bffed9186660c41f047d881596bungeman@google.com// needs to be != to any valid SkMask::Format
22bbe50131413098bffed9186660c41f047d881596bungeman@google.com#define MASK_FORMAT_UNKNOWN         (0xFF)
23bbe50131413098bffed9186660c41f047d881596bungeman@google.com#define MASK_FORMAT_JUST_ADVANCE    MASK_FORMAT_UNKNOWN
24bbe50131413098bffed9186660c41f047d881596bungeman@google.com
25bbe50131413098bffed9186660c41f047d881596bungeman@google.com#define kMaxGlyphWidth (1<<13)
26bbe50131413098bffed9186660c41f047d881596bungeman@google.com
276e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner/** (glyph-index or unicode-point) + subpixel-pos */
286e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagnerstruct SkPackedID {
296e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    static constexpr uint32_t kImpossibleID = ~0;
30b69d0e0ac45e13f667bc11a937dcb547072bc93dherb    enum {
31b69d0e0ac45e13f667bc11a937dcb547072bc93dherb        kSubBits = 2,
32b69d0e0ac45e13f667bc11a937dcb547072bc93dherb        kSubMask = ((1 << kSubBits) - 1),
33b69d0e0ac45e13f667bc11a937dcb547072bc93dherb        kSubShift = 24, // must be large enough for glyphs and unichars
34b69d0e0ac45e13f667bc11a937dcb547072bc93dherb        kCodeMask = ((1 << kSubShift) - 1),
35b69d0e0ac45e13f667bc11a937dcb547072bc93dherb        // relative offsets for X and Y subpixel bits
36b69d0e0ac45e13f667bc11a937dcb547072bc93dherb        kSubShiftX = kSubBits,
37b69d0e0ac45e13f667bc11a937dcb547072bc93dherb        kSubShiftY = 0
38b69d0e0ac45e13f667bc11a937dcb547072bc93dherb    };
39b69d0e0ac45e13f667bc11a937dcb547072bc93dherb
406e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkPackedID(uint32_t code) {
416e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        SkASSERT(code <= kCodeMask);
426e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        SkASSERT(code != kImpossibleID);
436e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        fID = code;
446e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
456e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
466e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkPackedID(uint32_t code, SkFixed x, SkFixed y) {
476e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        SkASSERT(code <= kCodeMask);
486e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        x = FixedToSub(x);
496e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        y = FixedToSub(y);
506e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        uint32_t ID = (x << (kSubShift + kSubShiftX)) |
516e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner                      (y << (kSubShift + kSubShiftY)) |
526e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner                      code;
536e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        SkASSERT(ID != kImpossibleID);
546e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        fID = ID;
556e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
566e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
576e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    constexpr SkPackedID() : fID(kImpossibleID) {}
586e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
596e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    bool operator==(const SkPackedID& that) const {
606e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return fID == that.fID;
616e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
626e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    bool operator!=(const SkPackedID& that) const {
636e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return !(*this == that);
646e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
656e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
666e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    uint32_t code() const {
676e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return fID & kCodeMask;
686e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
696e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
706e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkFixed getSubXFixed() const {
716e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return SubToFixed(ID2SubX(fID));
726e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
736e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
746e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkFixed getSubYFixed() const {
756e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return SubToFixed(ID2SubY(fID));
766e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
776e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
786e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    uint32_t hash() const {
796e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return SkChecksum::CheapMix(fID);
806e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
816e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
826e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner// FIXME - This is needed because the Android framework directly accesses fID.
836e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner// Remove when fID accesses are cleaned up.
846e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
856e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    operator uint32_t() const { return fID; }
866e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner#endif
876e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
886e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagnerprivate:
896e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    static unsigned ID2SubX(uint32_t id) {
906e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return id >> (kSubShift + kSubShiftX);
916e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
926e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
936e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    static unsigned ID2SubY(uint32_t id) {
946e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return (id >> (kSubShift + kSubShiftY)) & kSubMask;
956e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
966e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
976e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    static unsigned FixedToSub(SkFixed n) {
986e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return (n >> (16 - kSubBits)) & kSubMask;
996e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
1006e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
1016e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    static SkFixed SubToFixed(unsigned sub) {
1026e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        SkASSERT(sub <= kSubMask);
1036e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return sub << (16 - kSubBits);
1046e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
1056e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
1066e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    uint32_t fID;
1076e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner};
1086e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
1096e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagnerstruct SkPackedGlyphID : public SkPackedID {
1106e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkPackedGlyphID(SkGlyphID code) : SkPackedID(code) { }
1116e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkPackedGlyphID(SkGlyphID code, SkFixed x, SkFixed y) : SkPackedID(code, x, y) { }
1126e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkPackedGlyphID() : SkPackedID() { }
1136e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkGlyphID code() const {
1146e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return SkTo<SkGlyphID>(SkPackedID::code());
1156e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
1166e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner};
1176e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
1186e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagnerstruct SkPackedUnicharID : public SkPackedID {
1196e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkPackedUnicharID(SkUnichar code) : SkPackedID(code) { }
1206e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkPackedUnicharID(SkUnichar code, SkFixed x, SkFixed y) : SkPackedID(code, x, y) { }
1216e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkPackedUnicharID() : SkPackedID() { }
1226e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkUnichar code() const {
1236e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return SkTo<SkUnichar>(SkPackedID::code());
1246e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    }
1256e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner};
1266e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner
1276e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben WagnerSK_BEGIN_REQUIRE_DENSE
1286e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagnerclass SkGlyph {
1290449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    // Support horizontal and vertical skipping strike-through / underlines.
1300449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    // The caller walks the linked list looking for a match. For a horizontal underline,
1310449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    // the fBounds contains the top and bottom of the underline. The fInterval pair contains the
1320449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    // beginning and end of of the intersection of the bounds and the glyph's path.
1330449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    // If interval[0] >= interval[1], no intesection was found.
1340449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    struct Intercept {
1350449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        Intercept* fNext;
1360449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        SkScalar   fBounds[2];    // for horz underlines, the boundaries in Y
1370449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        SkScalar   fInterval[2];  // the outside intersections of the axis and the glyph
1380449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    };
1390449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark
1400449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    struct PathData {
1410449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        Intercept* fIntercept;
1420449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        SkPath*    fPath;
1430449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    };
1440449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark
1450449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclarkpublic:
1466e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    static const SkFixed kSubpixelRound = SK_FixedHalf >> SkPackedID::kSubBits;
147bbe50131413098bffed9186660c41f047d881596bungeman@google.com    void*       fImage;
1480449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    PathData*   fPathData;
1496b3eacb0dfaeb3374d410c8c041bd39cd066e1eabenjaminwagner    float       fAdvanceX, fAdvanceY;
150bbe50131413098bffed9186660c41f047d881596bungeman@google.com
151bbe50131413098bffed9186660c41f047d881596bungeman@google.com    uint16_t    fWidth, fHeight;
152bbe50131413098bffed9186660c41f047d881596bungeman@google.com    int16_t     fTop, fLeft;
153bbe50131413098bffed9186660c41f047d881596bungeman@google.com
154bbe50131413098bffed9186660c41f047d881596bungeman@google.com    uint8_t     fMaskFormat;
155bbe50131413098bffed9186660c41f047d881596bungeman@google.com    int8_t      fRsbDelta, fLsbDelta;  // used by auto-kerning
156b2f7fce9e034c3b6749e75a129e7836df3529706Ben Wagner    int8_t      fForceBW;
157bbe50131413098bffed9186660c41f047d881596bungeman@google.com
1586e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    void initWithGlyphID(SkPackedGlyphID glyph_id) {
1596e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        fID             = glyph_id;
1606e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        fImage          = nullptr;
1616e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        fPathData       = nullptr;
1626e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        fMaskFormat     = MASK_FORMAT_UNKNOWN;
1636e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        fForceBW        = 0;
164e70de9e4f0b7bf73f7cd1a20dbabcb233ffbb7f1herb    }
165e70de9e4f0b7bf73f7cd1a20dbabcb233ffbb7f1herb
1667c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby    static size_t BitsToBytes(size_t bits) {
1677c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby        return (bits + 7) >> 3;
1687c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby    }
1697c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby
170bbe50131413098bffed9186660c41f047d881596bungeman@google.com    /**
171bbe50131413098bffed9186660c41f047d881596bungeman@google.com     *  Compute the rowbytes for the specified width and mask-format.
172bbe50131413098bffed9186660c41f047d881596bungeman@google.com     */
173bbe50131413098bffed9186660c41f047d881596bungeman@google.com    static unsigned ComputeRowBytes(unsigned width, SkMask::Format format) {
174bbe50131413098bffed9186660c41f047d881596bungeman@google.com        unsigned rb = width;
175bbe50131413098bffed9186660c41f047d881596bungeman@google.com        if (SkMask::kBW_Format == format) {
1767c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            rb = BitsToBytes(rb);
177d54d3fc82456f8789b3e4dff40faeb7b670bcf4breed        } else if (SkMask::kARGB32_Format == format) {
178bbe50131413098bffed9186660c41f047d881596bungeman@google.com            rb <<= 2;
179bbe50131413098bffed9186660c41f047d881596bungeman@google.com        } else if (SkMask::kLCD16_Format == format) {
180bbe50131413098bffed9186660c41f047d881596bungeman@google.com            rb = SkAlign4(rb << 1);
181bbe50131413098bffed9186660c41f047d881596bungeman@google.com        } else {
182bbe50131413098bffed9186660c41f047d881596bungeman@google.com            rb = SkAlign4(rb);
183bbe50131413098bffed9186660c41f047d881596bungeman@google.com        }
184bbe50131413098bffed9186660c41f047d881596bungeman@google.com        return rb;
185bbe50131413098bffed9186660c41f047d881596bungeman@google.com    }
186bbe50131413098bffed9186660c41f047d881596bungeman@google.com
1877c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby    size_t allocImage(SkArenaAlloc* alloc) {
1887c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby        size_t allocSize;
1897c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby        if (SkMask::kBW_Format == fMaskFormat) {
1907c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            allocSize = BitsToBytes(fWidth) * fHeight;
1917c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            fImage = alloc->makeArrayDefault<char>(allocSize);
1927c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby        } else if (SkMask::kARGB32_Format == fMaskFormat) {
1937c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            allocSize = fWidth * fHeight;
1947c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            fImage = alloc->makeArrayDefault<uint32_t>(fWidth * fHeight);
1957c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            allocSize *= sizeof(uint32_t);
1967c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby        } else if (SkMask::kLCD16_Format == fMaskFormat) {
1977c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            allocSize = SkAlign2(fWidth) * fHeight;
1987c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            fImage = alloc->makeArrayDefault<uint16_t>(allocSize);
1997c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            allocSize *= sizeof(uint16_t);
2007c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby        } else {
2017c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            allocSize = SkAlign4(fWidth) * fHeight;
2027c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby            fImage = alloc->makeArrayDefault<char>(allocSize);
2037c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby        }
2047c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby        return allocSize;
2057c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby    }
2067c5a806bf67e1818b0272a2ae8d854ae1fd72e82Herb Derby
207bbe50131413098bffed9186660c41f047d881596bungeman@google.com    unsigned rowBytes() const {
208bbe50131413098bffed9186660c41f047d881596bungeman@google.com        return ComputeRowBytes(fWidth, (SkMask::Format)fMaskFormat);
209bbe50131413098bffed9186660c41f047d881596bungeman@google.com    }
210bbe50131413098bffed9186660c41f047d881596bungeman@google.com
211bbe50131413098bffed9186660c41f047d881596bungeman@google.com    bool isJustAdvance() const {
212bbe50131413098bffed9186660c41f047d881596bungeman@google.com        return MASK_FORMAT_JUST_ADVANCE == fMaskFormat;
213bbe50131413098bffed9186660c41f047d881596bungeman@google.com    }
214bbe50131413098bffed9186660c41f047d881596bungeman@google.com
215bbe50131413098bffed9186660c41f047d881596bungeman@google.com    bool isFullMetrics() const {
216bbe50131413098bffed9186660c41f047d881596bungeman@google.com        return MASK_FORMAT_JUST_ADVANCE != fMaskFormat;
217bbe50131413098bffed9186660c41f047d881596bungeman@google.com    }
218bbe50131413098bffed9186660c41f047d881596bungeman@google.com
2196e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkGlyphID getGlyphID() const {
2206e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return fID.code();
221bbe50131413098bffed9186660c41f047d881596bungeman@google.com    }
222bbe50131413098bffed9186660c41f047d881596bungeman@google.com
2236e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkPackedGlyphID getPackedID() const {
2246e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return fID;
225bbe50131413098bffed9186660c41f047d881596bungeman@google.com    }
226bbe50131413098bffed9186660c41f047d881596bungeman@google.com
227bbe50131413098bffed9186660c41f047d881596bungeman@google.com    SkFixed getSubXFixed() const {
2286e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return fID.getSubXFixed();
229bbe50131413098bffed9186660c41f047d881596bungeman@google.com    }
230bbe50131413098bffed9186660c41f047d881596bungeman@google.com
231bbe50131413098bffed9186660c41f047d881596bungeman@google.com    SkFixed getSubYFixed() const {
2326e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        return fID.getSubYFixed();
233bbe50131413098bffed9186660c41f047d881596bungeman@google.com    }
234bbe50131413098bffed9186660c41f047d881596bungeman@google.com
235bbe50131413098bffed9186660c41f047d881596bungeman@google.com    size_t computeImageSize() const;
236bbe50131413098bffed9186660c41f047d881596bungeman@google.com
237bbe50131413098bffed9186660c41f047d881596bungeman@google.com    /** Call this to set all of the metrics fields to 0 (e.g. if the scaler
238bbe50131413098bffed9186660c41f047d881596bungeman@google.com        encounters an error measuring a glyph). Note: this does not alter the
239bbe50131413098bffed9186660c41f047d881596bungeman@google.com        fImage, fPath, fID, fMaskFormat fields.
240bbe50131413098bffed9186660c41f047d881596bungeman@google.com     */
241bbe50131413098bffed9186660c41f047d881596bungeman@google.com    void zeroMetrics();
242bbe50131413098bffed9186660c41f047d881596bungeman@google.com
243b69d0e0ac45e13f667bc11a937dcb547072bc93dherb    void toMask(SkMask* mask) const;
244b69d0e0ac45e13f667bc11a937dcb547072bc93dherb
245c71239b9ff7d8c19dc03cb6c9081e7dc4e0947d2herb    class HashTraits {
246c71239b9ff7d8c19dc03cb6c9081e7dc4e0947d2herb    public:
2476e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        static SkPackedGlyphID GetKey(const SkGlyph& glyph) {
248c71239b9ff7d8c19dc03cb6c9081e7dc4e0947d2herb            return glyph.fID;
249c71239b9ff7d8c19dc03cb6c9081e7dc4e0947d2herb        }
2506e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        static uint32_t Hash(SkPackedGlyphID glyphId) {
2516e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner            return glyphId.hash();
252c71239b9ff7d8c19dc03cb6c9081e7dc4e0947d2herb        }
253c71239b9ff7d8c19dc03cb6c9081e7dc4e0947d2herb    };
254c71239b9ff7d8c19dc03cb6c9081e7dc4e0947d2herb
255b69d0e0ac45e13f667bc11a937dcb547072bc93dherb private:
256b69d0e0ac45e13f667bc11a937dcb547072bc93dherb    // TODO(herb) remove friend statement after SkGlyphCache cleanup.
257b69d0e0ac45e13f667bc11a937dcb547072bc93dherb    friend class SkGlyphCache;
258b69d0e0ac45e13f667bc11a937dcb547072bc93dherb
2596e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner// FIXME - This is needed because the Android frame work directly accesses fID.
2606e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner// Remove when fID accesses are cleaned up.
261b69d0e0ac45e13f667bc11a937dcb547072bc93dherb#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
262b69d0e0ac45e13f667bc11a937dcb547072bc93dherb  public:
263b69d0e0ac45e13f667bc11a937dcb547072bc93dherb#endif
2646e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner    SkPackedGlyphID fID;
265bbe50131413098bffed9186660c41f047d881596bungeman@google.com};
266b68ce74bd197a9ca4becd53cbcfee825b8d08e0emtkleinSK_END_REQUIRE_DENSE
267bbe50131413098bffed9186660c41f047d881596bungeman@google.com
268bbe50131413098bffed9186660c41f047d881596bungeman@google.com#endif
269