blob: ac34d7b8166e73b248a8da0f7958d1aac119ee5c [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
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;
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +000029
bungeman@google.coma544f292012-11-20 18:52:23 +000030 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); }
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +000039
bungeman@google.coma544f292012-11-20 18:52:23 +000040 void advance(uint16_t num) {
41 fLocaPtr.shortOffset += num << fLocaFormat;
42 fCurrentGlyphOffset = fLocaFormat ? SkEndian_SwapBE32(*fLocaPtr.longOffset)
humper@google.com0e515772013-01-07 19:54:40 +000043 : uint32_t(SkEndian_SwapBE16(*fLocaPtr.shortOffset) << 1);
bungeman@google.coma544f292012-11-20 18:52:23 +000044 }
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;
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +000073
bungeman@google.coma544f292012-11-20 18:52:23 +000074 struct Simple {
75 SK_OT_USHORT endPtsOfContours[1/*numberOfContours*/];
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +000076
bungeman@google.coma544f292012-11-20 18:52:23 +000077 struct Instructions {
78 SK_OT_USHORT length;
79 SK_OT_BYTE data[1/*length*/];
80 };
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +000081
bungeman@google.coma544f292012-11-20 18:52:23 +000082 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 };
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +0000104
bungeman@google.coma544f292012-11-20 18:52:23 +0000105 //xCoordinates
106 //yCoordinates
107 };
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +0000108
bungeman@google.coma544f292012-11-20 18:52:23 +0000109 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);
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +0000143
bungeman@google.coma544f292012-11-20 18:52:23 +0000144 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
skia.committer@gmail.comb0a327e2012-11-21 02:02:25 +0000203
bungeman@google.coma544f292012-11-20 18:52:23 +0000204 /** 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