• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkGlyph_DEFINED
9 #define SkGlyph_DEFINED
10 
11 #include "SkTypes.h"
12 #include "SkFixed.h"
13 #include "SkMask.h"
14 
15 class SkPath;
16 
17 // needs to be != to any valid SkMask::Format
18 #define MASK_FORMAT_UNKNOWN         (0xFF)
19 #define MASK_FORMAT_JUST_ADVANCE    MASK_FORMAT_UNKNOWN
20 
21 #define kMaxGlyphWidth (1<<13)
22 
23 struct SkGlyph {
24     void*       fImage;
25     SkPath*     fPath;
26     SkFixed     fAdvanceX, fAdvanceY;
27 
28     uint32_t    fID;
29     uint16_t    fWidth, fHeight;
30     int16_t     fTop, fLeft;
31 
32     uint8_t     fMaskFormat;
33     int8_t      fRsbDelta, fLsbDelta;  // used by auto-kerning
34 
initSkGlyph35     void init(uint32_t id) {
36         fID             = id;
37         fImage          = NULL;
38         fPath           = NULL;
39         fMaskFormat     = MASK_FORMAT_UNKNOWN;
40     }
41 
42     /**
43      *  Compute the rowbytes for the specified width and mask-format.
44      */
ComputeRowBytesSkGlyph45     static unsigned ComputeRowBytes(unsigned width, SkMask::Format format) {
46         unsigned rb = width;
47         if (SkMask::kBW_Format == format) {
48             rb = (rb + 7) >> 3;
49         } else if (SkMask::kARGB32_Format == format ||
50                    SkMask::kLCD32_Format == format)
51         {
52             rb <<= 2;
53         } else if (SkMask::kLCD16_Format == format) {
54             rb = SkAlign4(rb << 1);
55         } else {
56             rb = SkAlign4(rb);
57         }
58         return rb;
59     }
60 
rowBytesSkGlyph61     unsigned rowBytes() const {
62         return ComputeRowBytes(fWidth, (SkMask::Format)fMaskFormat);
63     }
64 
isJustAdvanceSkGlyph65     bool isJustAdvance() const {
66         return MASK_FORMAT_JUST_ADVANCE == fMaskFormat;
67     }
68 
isFullMetricsSkGlyph69     bool isFullMetrics() const {
70         return MASK_FORMAT_JUST_ADVANCE != fMaskFormat;
71     }
72 
getGlyphIDSkGlyph73     uint16_t getGlyphID() const {
74         return ID2Code(fID);
75     }
76 
getGlyphIDSkGlyph77     unsigned getGlyphID(unsigned baseGlyphCount) const {
78         unsigned code = ID2Code(fID);
79         SkASSERT(code >= baseGlyphCount);
80         return code - baseGlyphCount;
81     }
82 
getSubXSkGlyph83     unsigned getSubX() const {
84         return ID2SubX(fID);
85     }
86 
getSubXFixedSkGlyph87     SkFixed getSubXFixed() const {
88         return SubToFixed(ID2SubX(fID));
89     }
90 
getSubYFixedSkGlyph91     SkFixed getSubYFixed() const {
92         return SubToFixed(ID2SubY(fID));
93     }
94 
95     size_t computeImageSize() const;
96 
97     /** Call this to set all of the metrics fields to 0 (e.g. if the scaler
98         encounters an error measuring a glyph). Note: this does not alter the
99         fImage, fPath, fID, fMaskFormat fields.
100      */
101     void zeroMetrics();
102 
103     enum {
104         kSubBits = 2,
105         kSubMask = ((1 << kSubBits) - 1),
106         kSubShift = 24, // must be large enough for glyphs and unichars
107         kCodeMask = ((1 << kSubShift) - 1),
108         // relative offsets for X and Y subpixel bits
109         kSubShiftX = kSubBits,
110         kSubShiftY = 0
111     };
112 
ID2CodeSkGlyph113     static unsigned ID2Code(uint32_t id) {
114         return id & kCodeMask;
115     }
116 
ID2SubXSkGlyph117     static unsigned ID2SubX(uint32_t id) {
118         return id >> (kSubShift + kSubShiftX);
119     }
120 
ID2SubYSkGlyph121     static unsigned ID2SubY(uint32_t id) {
122         return (id >> (kSubShift + kSubShiftY)) & kSubMask;
123     }
124 
FixedToSubSkGlyph125     static unsigned FixedToSub(SkFixed n) {
126         return (n >> (16 - kSubBits)) & kSubMask;
127     }
128 
SubToFixedSkGlyph129     static SkFixed SubToFixed(unsigned sub) {
130         SkASSERT(sub <= kSubMask);
131         return sub << (16 - kSubBits);
132     }
133 
MakeIDSkGlyph134     static uint32_t MakeID(unsigned code) {
135         return code;
136     }
137 
MakeIDSkGlyph138     static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) {
139         SkASSERT(code <= kCodeMask);
140         x = FixedToSub(x);
141         y = FixedToSub(y);
142         return (x << (kSubShift + kSubShiftX)) |
143                (y << (kSubShift + kSubShiftY)) |
144                code;
145     }
146 
147     void toMask(SkMask* mask) const;
148 };
149 
150 #endif
151