18838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org/*
28838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org * Copyright 2006 The Android Open Source Project
38838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org *
48838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org * Use of this source code is governed by a BSD-style license that can be
58838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org * found in the LICENSE file.
68838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org */
78838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
88838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org#ifndef SkGlyph_DEFINED
98838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org#define SkGlyph_DEFINED
108838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
118838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org#include "SkTypes.h"
128838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org#include "SkFixed.h"
138838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org#include "SkMask.h"
148838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
158838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.orgclass SkPath;
168838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
178838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org// needs to be != to any valid SkMask::Format
188838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org#define MASK_FORMAT_UNKNOWN         (0xFF)
198838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org#define MASK_FORMAT_JUST_ADVANCE    MASK_FORMAT_UNKNOWN
208838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
218838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org#define kMaxGlyphWidth (1<<13)
228838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
238838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.orgstruct SkGlyph {
248838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    void*       fImage;
258838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    SkPath*     fPath;
268838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    SkFixed     fAdvanceX, fAdvanceY;
278838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
288838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    uint32_t    fID;
298838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    uint16_t    fWidth, fHeight;
308838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    int16_t     fTop, fLeft;
318838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
328838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    uint8_t     fMaskFormat;
338838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    int8_t      fRsbDelta, fLsbDelta;  // used by auto-kerning
348838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
358838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    void init(uint32_t id) {
368838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        fID             = id;
378838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        fImage          = NULL;
388838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        fPath           = NULL;
398838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        fMaskFormat     = MASK_FORMAT_UNKNOWN;
408838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
418838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
428838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    /**
438838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org     *  Compute the rowbytes for the specified width and mask-format.
448838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org     */
458838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    static unsigned ComputeRowBytes(unsigned width, SkMask::Format format) {
468838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        unsigned rb = width;
478838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        if (SkMask::kBW_Format == format) {
488838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org            rb = (rb + 7) >> 3;
498838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        } else if (SkMask::kARGB32_Format == format ||
508838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org                   SkMask::kLCD32_Format == format)
518838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        {
528838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org            rb <<= 2;
538838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        } else if (SkMask::kLCD16_Format == format) {
548838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org            rb = SkAlign4(rb << 1);
558838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        } else {
568838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org            rb = SkAlign4(rb);
578838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        }
588838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return rb;
598838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
608838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
618838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    unsigned rowBytes() const {
628838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return ComputeRowBytes(fWidth, (SkMask::Format)fMaskFormat);
638838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
648838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
658838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    bool isJustAdvance() const {
668838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return MASK_FORMAT_JUST_ADVANCE == fMaskFormat;
678838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
688838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
698838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    bool isFullMetrics() const {
708838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return MASK_FORMAT_JUST_ADVANCE != fMaskFormat;
718838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
728838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
738838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    uint16_t getGlyphID() const {
748838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return ID2Code(fID);
758838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
768838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
778838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    unsigned getGlyphID(unsigned baseGlyphCount) const {
788838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        unsigned code = ID2Code(fID);
798838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        SkASSERT(code >= baseGlyphCount);
808838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return code - baseGlyphCount;
818838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
828838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
838838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    unsigned getSubX() const {
848838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return ID2SubX(fID);
858838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
868838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
878838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    SkFixed getSubXFixed() const {
888838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return SubToFixed(ID2SubX(fID));
898838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
908838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
918838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    SkFixed getSubYFixed() const {
928838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return SubToFixed(ID2SubY(fID));
938838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
948838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
958838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    size_t computeImageSize() const;
968838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
978838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    /** Call this to set all of the metrics fields to 0 (e.g. if the scaler
988838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        encounters an error measuring a glyph). Note: this does not alter the
998838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        fImage, fPath, fID, fMaskFormat fields.
1008838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org     */
1018838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    void zeroMetrics();
1028838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
1038838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    enum {
1048838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        kSubBits = 2,
1058838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        kSubMask = ((1 << kSubBits) - 1),
1068838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        kSubShift = 24, // must be large enough for glyphs and unichars
1078838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        kCodeMask = ((1 << kSubShift) - 1),
1088838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        // relative offsets for X and Y subpixel bits
1098838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        kSubShiftX = kSubBits,
1108838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        kSubShiftY = 0
1118838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    };
1128838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
1138838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    static unsigned ID2Code(uint32_t id) {
1148838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return id & kCodeMask;
1158838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
1168838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
1178838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    static unsigned ID2SubX(uint32_t id) {
1188838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return id >> (kSubShift + kSubShiftX);
1198838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
1208838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
1218838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    static unsigned ID2SubY(uint32_t id) {
1228838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return (id >> (kSubShift + kSubShiftY)) & kSubMask;
1238838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
1248838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
1258838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    static unsigned FixedToSub(SkFixed n) {
1268838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return (n >> (16 - kSubBits)) & kSubMask;
1278838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
1288838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
1298838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    static SkFixed SubToFixed(unsigned sub) {
1308838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        SkASSERT(sub <= kSubMask);
1318838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return sub << (16 - kSubBits);
1328838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
1338838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
1348838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    static uint32_t MakeID(unsigned code) {
1358838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return code;
1368838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
1378838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
1388838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) {
1398838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        SkASSERT(code <= kCodeMask);
1408838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        x = FixedToSub(x);
1418838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        y = FixedToSub(y);
1428838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org        return (x << (kSubShift + kSubShiftX)) |
1438838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org               (y << (kSubShift + kSubShiftY)) |
1448838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org               code;
1458838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    }
1468838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
1478838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org    void toMask(SkMask* mask) const;
1488838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org};
1498838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org
1508838847b09138780a368d0d24dbcfc5e76e7148cmike@reedtribe.org#endif
151