• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 Google Inc.
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 SkOTTable_glyf_DEFINED
9 #define SkOTTable_glyf_DEFINED
10 
11 #include "SkEndian.h"
12 #include "SkOTTableTypes.h"
13 #include "SkOTTable_head.h"
14 #include "SkOTTable_loca.h"
15 #include "SkTypedEnum.h"
16 
17 #pragma pack(push, 1)
18 
19 struct SkOTTableGlyphData;
20 
21 extern uint8_t const * const SK_OT_GlyphData_NoOutline;
22 
23 struct SkOTTableGlyph {
24     static const SK_OT_CHAR TAG0 = 'g';
25     static const SK_OT_CHAR TAG1 = 'l';
26     static const SK_OT_CHAR TAG2 = 'y';
27     static const SK_OT_CHAR TAG3 = 'f';
28     static const SK_OT_ULONG TAG = SkOTTableTAG<SkOTTableGlyph>::value;
29 
30     class Iterator {
31     public:
IteratorSkOTTableGlyph32         Iterator(const SkOTTableGlyph& glyf,
33                  const SkOTTableIndexToLocation& loca,
34                  SkOTTableHead::IndexToLocFormat locaFormat)
35         : fGlyf(glyf)
36         , fLocaFormat(SkOTTableHead::IndexToLocFormat::ShortOffsets == locaFormat.value ? 0 : 1)
37         , fCurrentGlyphOffset(0)
38         { fLocaPtr.shortOffset = reinterpret_cast<const SK_OT_USHORT*>(&loca); }
39 
advanceSkOTTableGlyph40         void advance(uint16_t num) {
41             fLocaPtr.shortOffset += num << fLocaFormat;
42             fCurrentGlyphOffset = fLocaFormat ? SkEndian_SwapBE32(*fLocaPtr.longOffset)
43                                               : uint32_t(SkEndian_SwapBE16(*fLocaPtr.shortOffset) << 1);
44         }
nextSkOTTableGlyph45         const SkOTTableGlyphData* next() {
46             uint32_t previousGlyphOffset = fCurrentGlyphOffset;
47             advance(1);
48             if (previousGlyphOffset == fCurrentGlyphOffset) {
49                 return reinterpret_cast<const SkOTTableGlyphData*>(&SK_OT_GlyphData_NoOutline);
50             } else {
51                 return reinterpret_cast<const SkOTTableGlyphData*>(
52                     reinterpret_cast<const SK_OT_BYTE*>(&fGlyf) + previousGlyphOffset
53                 );
54             }
55         }
56     private:
57         const SkOTTableGlyph& fGlyf;
58         uint16_t fLocaFormat; //0 or 1
59         uint32_t fCurrentGlyphOffset;
60         union LocaPtr {
61             const SK_OT_USHORT* shortOffset;
62             const SK_OT_ULONG* longOffset;
63         } fLocaPtr;
64     };
65 };
66 
67 struct SkOTTableGlyphData {
68     SK_OT_SHORT numberOfContours; //== -1 Composite, > 0 Simple
69     SK_OT_FWORD xMin;
70     SK_OT_FWORD yMin;
71     SK_OT_FWORD xMax;
72     SK_OT_FWORD yMax;
73 
74     struct Simple {
75         SK_OT_USHORT endPtsOfContours[1/*numberOfContours*/];
76 
77         struct Instructions {
78             SK_OT_USHORT length;
79             SK_OT_BYTE data[1/*length*/];
80         };
81 
82         union Flags {
83             struct Field {
84                 SK_OT_BYTE_BITFIELD(
85                     OnCurve,
86                     xShortVector,
87                     yShortVector,
88                     Repeat,
89                     xIsSame_xShortVectorPositive,
90                     yIsSame_yShortVectorPositive,
91                     Reserved6,
92                     Reserved7)
93             } field;
94             struct Raw {
95                 static const SK_OT_USHORT OnCurveMask = SkTEndian_SwapBE16(1 << 0);
96                 static const SK_OT_USHORT xShortVectorMask = SkTEndian_SwapBE16(1 << 1);
97                 static const SK_OT_USHORT yShortVectorMask = SkTEndian_SwapBE16(1 << 2);
98                 static const SK_OT_USHORT RepeatMask = SkTEndian_SwapBE16(1 << 3);
99                 static const SK_OT_USHORT xIsSame_xShortVectorPositiveMask = SkTEndian_SwapBE16(1 << 4);
100                 static const SK_OT_USHORT yIsSame_yShortVectorPositiveMask = SkTEndian_SwapBE16(1 << 5);
101                 SK_OT_BYTE value;
102             } raw;
103         };
104 
105         //xCoordinates
106         //yCoordinates
107     };
108 
109     struct Composite {
110         struct Component {
111             union Flags {
112                 struct Field {
113                     //8-15
114                     SK_OT_BYTE_BITFIELD(
115                         WE_HAVE_INSTRUCTIONS,
116                         USE_MY_METRICS,
117                         OVERLAP_COMPOUND,
118                         SCALED_COMPONENT_OFFSET,
119                         UNSCALED_COMPONENT_OFFSET,
120                         Reserved13,
121                         Reserved14,
122                         Reserved15)
123                     //0-7
124                     SK_OT_BYTE_BITFIELD(
125                         ARG_1_AND_2_ARE_WORDS,
126                         ARGS_ARE_XY_VALUES,
127                         ROUND_XY_TO_GRID,
128                         WE_HAVE_A_SCALE,
129                         RESERVED,
130                         MORE_COMPONENTS,
131                         WE_HAVE_AN_X_AND_Y_SCALE,
132                         WE_HAVE_A_TWO_BY_TWO)
133                 } field;
134                 struct Raw {
135                     static const SK_OT_USHORT ARG_1_AND_2_ARE_WORDS_Mask = SkTEndian_SwapBE16(1 << 0);
136                     static const SK_OT_USHORT ARGS_ARE_XY_VALUES_Mask = SkTEndian_SwapBE16(1 << 1);
137                     static const SK_OT_USHORT ROUND_XY_TO_GRID_Mask = SkTEndian_SwapBE16(1 << 2);
138                     static const SK_OT_USHORT WE_HAVE_A_SCALE_Mask = SkTEndian_SwapBE16(1 << 3);
139                     static const SK_OT_USHORT RESERVED_Mask = SkTEndian_SwapBE16(1 << 4);
140                     static const SK_OT_USHORT MORE_COMPONENTS_Mask = SkTEndian_SwapBE16(1 << 5);
141                     static const SK_OT_USHORT WE_HAVE_AN_X_AND_Y_SCALE_Mask = SkTEndian_SwapBE16(1 << 6);
142                     static const SK_OT_USHORT WE_HAVE_A_TWO_BY_TWO_Mask = SkTEndian_SwapBE16(1 << 7);
143 
144                     static const SK_OT_USHORT WE_HAVE_INSTRUCTIONS_Mask = SkTEndian_SwapBE16(1 << 8);
145                     static const SK_OT_USHORT USE_MY_METRICS_Mask = SkTEndian_SwapBE16(1 << 9);
146                     static const SK_OT_USHORT OVERLAP_COMPOUND_Mask = SkTEndian_SwapBE16(1 << 10);
147                     static const SK_OT_USHORT SCALED_COMPONENT_OFFSET_Mask = SkTEndian_SwapBE16(1 << 11);
148                     static const SK_OT_USHORT UNSCALED_COMPONENT_OFFSET_mask = SkTEndian_SwapBE16(1 << 12);
149                     //Reserved
150                     //Reserved
151                     //Reserved
152                     SK_OT_USHORT value;
153                 } raw;
154             } flags;
155             SK_OT_USHORT glyphIndex;
156             union Transform {
157                 union Matrix {
158                     /** !WE_HAVE_A_SCALE & !WE_HAVE_AN_X_AND_Y_SCALE & !WE_HAVE_A_TWO_BY_TWO */
159                     struct None { } none;
160                     /** WE_HAVE_A_SCALE */
161                     struct Scale {
162                         SK_OT_F2DOT14 a_d;
163                     } scale;
164                     /** WE_HAVE_AN_X_AND_Y_SCALE */
165                     struct ScaleXY {
166                         SK_OT_F2DOT14 a;
167                         SK_OT_F2DOT14 d;
168                     } scaleXY;
169                     /** WE_HAVE_A_TWO_BY_TWO */
170                     struct TwoByTwo {
171                         SK_OT_F2DOT14 a;
172                         SK_OT_F2DOT14 b;
173                         SK_OT_F2DOT14 c;
174                         SK_OT_F2DOT14 d;
175                     } twoByTwo;
176                 };
177                 /** ARG_1_AND_2_ARE_WORDS & ARGS_ARE_XY_VALUES */
178                 struct WordValue {
179                     SK_OT_FWORD e;
180                     SK_OT_FWORD f;
181                     SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
182                 } wordValue;
183                 /** !ARG_1_AND_2_ARE_WORDS & ARGS_ARE_XY_VALUES */
184                 struct ByteValue {
185                     SK_OT_CHAR e;
186                     SK_OT_CHAR f;
187                     SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
188                 } byteValue;
189                 /** ARG_1_AND_2_ARE_WORDS & !ARGS_ARE_XY_VALUES */
190                 struct WordIndex {
191                     SK_OT_USHORT compoundPointIndex;
192                     SK_OT_USHORT componentPointIndex;
193                     SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
194                 } wordIndex;
195                 /** !ARG_1_AND_2_ARE_WORDS & !ARGS_ARE_XY_VALUES */
196                 struct ByteIndex {
197                     SK_OT_BYTE compoundPointIndex;
198                     SK_OT_BYTE componentPointIndex;
199                     SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
200                 } byteIndex;
201             } transform;
202         } component;//[] last element does not set MORE_COMPONENTS
203 
204         /** Comes after the last Component if the last component has WE_HAVE_INSTR. */
205         struct Instructions {
206             SK_OT_USHORT length;
207             SK_OT_BYTE data[1/*length*/];
208         };
209     };
210 };
211 
212 #pragma pack(pop)
213 
214 #endif
215