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