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