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