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