blob: 98c4b2021dd9a0ff74ef04378407d25865da2bca [file] [log] [blame]
bungeman@google.coma544f292012-11-20 18:52:23 +00001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#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"
bungeman@google.coma544f292012-11-20 18:52:23 +000015
16#pragma pack(push, 1)
17
18struct SkOTTableGlyphData;
19
20extern uint8_t const * const SK_OT_GlyphData_NoOutline;
21
22struct 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;
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +000028
bungeman@google.coma544f292012-11-20 18:52:23 +000029 class Iterator {
30 public:
31 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); }
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +000038
bungeman@google.coma544f292012-11-20 18:52:23 +000039 void advance(uint16_t num) {
40 fLocaPtr.shortOffset += num << fLocaFormat;
41 fCurrentGlyphOffset = fLocaFormat ? SkEndian_SwapBE32(*fLocaPtr.longOffset)
humper@google.com0e515772013-01-07 19:54:40 +000042 : uint32_t(SkEndian_SwapBE16(*fLocaPtr.shortOffset) << 1);
bungeman@google.coma544f292012-11-20 18:52:23 +000043 }
44 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
66struct 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;
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +000072
bungeman@google.coma544f292012-11-20 18:52:23 +000073 struct Simple {
74 SK_OT_USHORT endPtsOfContours[1/*numberOfContours*/];
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +000075
bungeman@google.coma544f292012-11-20 18:52:23 +000076 struct Instructions {
77 SK_OT_USHORT length;
78 SK_OT_BYTE data[1/*length*/];
79 };
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +000080
bungeman@google.coma544f292012-11-20 18:52:23 +000081 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 };
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +0000103
bungeman@google.coma544f292012-11-20 18:52:23 +0000104 //xCoordinates
105 //yCoordinates
106 };
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +0000107
bungeman@google.coma544f292012-11-20 18:52:23 +0000108 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);
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +0000142
bungeman@google.coma544f292012-11-20 18:52:23 +0000143 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
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +0000202
bungeman@google.coma544f292012-11-20 18:52:23 +0000203 /** 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