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
19struct SkOTTableGlyphData;
20
21extern uint8_t const * const SK_OT_GlyphData_NoOutline;
22
23struct 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:
32        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
40        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        }
45        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
67struct 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