2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef SkOTTable_glyf_DEFINED
9 #define SkOTTable_glyf_DEFINED
11 #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"
18 struct SkOTTableGlyphData;
20 struct SkOTTableGlyph {
21 static const SK_OT_CHAR TAG0 = 'g';
22 static const SK_OT_CHAR TAG1 = 'l';
23 static const SK_OT_CHAR TAG2 = 'y';
24 static const SK_OT_CHAR TAG3 = 'f';
25 static const SK_OT_ULONG TAG = SkOTTableTAG<SkOTTableGlyph>::value;
29 Iterator(SkOTTableGlyph& glyf,
30 const SkOTTableIndexToLocation& loca,
31 SkOTTableHead::IndexToLocFormat locaFormat)
34 , fLocaFormat(locaFormat)
36 , fCurrentGlyphOffset(0)
38 SkASSERT(locaFormat.value == SkOTTableHead::IndexToLocFormat::ShortOffsets ||
39 locaFormat.value == SkOTTableHead::IndexToLocFormat::LongOffsets);
42 void advance(uint16_t num) {
44 if (fLocaFormat.value == SkOTTableHead::IndexToLocFormat::ShortOffsets) {
46 SkEndian_SwapBE16(fLoca.offsets.shortOffset[fCurrentGlyph]) << 1;
47 } else if (fLocaFormat.value == SkOTTableHead::IndexToLocFormat::LongOffsets) {
48 fCurrentGlyphOffset = SkEndian_SwapBE32(fLoca.offsets.longOffset[fCurrentGlyph]);
51 SkOTTableGlyphData* next() {
52 uint32_t previousGlyphOffset = fCurrentGlyphOffset;
54 if (previousGlyphOffset == fCurrentGlyphOffset) {
57 return reinterpret_cast<SkOTTableGlyphData*>(
58 reinterpret_cast<SK_OT_BYTE*>(&fGlyf) + previousGlyphOffset
63 SkOTTableGlyph& fGlyf;
64 const SkOTTableIndexToLocation& fLoca;
65 SkOTTableHead::IndexToLocFormat fLocaFormat;
66 uint32_t fCurrentGlyph;
67 uint32_t fCurrentGlyphOffset;
71 struct SkOTTableGlyphData {
72 SK_OT_SHORT numberOfContours; //== -1 Composite, > 0 Simple
79 SK_OT_USHORT endPtsOfContours[1/*numberOfContours*/];
83 SK_OT_BYTE data[1/*length*/];
93 xIsSame_xShortVectorPositive,
94 yIsSame_yShortVectorPositive,
99 static const SK_OT_USHORT OnCurveMask = SkTEndian_SwapBE16(1 << 0);
100 static const SK_OT_USHORT xShortVectorMask = SkTEndian_SwapBE16(1 << 1);
101 static const SK_OT_USHORT yShortVectorMask = SkTEndian_SwapBE16(1 << 2);
102 static const SK_OT_USHORT RepeatMask = SkTEndian_SwapBE16(1 << 3);
103 static const SK_OT_USHORT xIsSame_xShortVectorPositiveMask = SkTEndian_SwapBE16(1 << 4);
104 static const SK_OT_USHORT yIsSame_yShortVectorPositiveMask = SkTEndian_SwapBE16(1 << 5);
119 WE_HAVE_INSTRUCTIONS,
122 SCALED_COMPONENT_OFFSET,
123 UNSCALED_COMPONENT_OFFSET,
129 ARG_1_AND_2_ARE_WORDS,
135 WE_HAVE_AN_X_AND_Y_SCALE,
136 WE_HAVE_A_TWO_BY_TWO)
139 static const SK_OT_USHORT ARG_1_AND_2_ARE_WORDS_Mask = SkTEndian_SwapBE16(1 << 0);
140 static const SK_OT_USHORT ARGS_ARE_XY_VALUES_Mask = SkTEndian_SwapBE16(1 << 1);
141 static const SK_OT_USHORT ROUND_XY_TO_GRID_Mask = SkTEndian_SwapBE16(1 << 2);
142 static const SK_OT_USHORT WE_HAVE_A_SCALE_Mask = SkTEndian_SwapBE16(1 << 3);
143 static const SK_OT_USHORT RESERVED_Mask = SkTEndian_SwapBE16(1 << 4);
144 static const SK_OT_USHORT MORE_COMPONENTS_Mask = SkTEndian_SwapBE16(1 << 5);
145 static const SK_OT_USHORT WE_HAVE_AN_X_AND_Y_SCALE_Mask = SkTEndian_SwapBE16(1 << 6);
146 static const SK_OT_USHORT WE_HAVE_A_TWO_BY_TWO_Mask = SkTEndian_SwapBE16(1 << 7);
148 static const SK_OT_USHORT WE_HAVE_INSTRUCTIONS_Mask = SkTEndian_SwapBE16(1 << 8);
149 static const SK_OT_USHORT USE_MY_METRICS_Mask = SkTEndian_SwapBE16(1 << 9);
150 static const SK_OT_USHORT OVERLAP_COMPOUND_Mask = SkTEndian_SwapBE16(1 << 10);
151 static const SK_OT_USHORT SCALED_COMPONENT_OFFSET_Mask = SkTEndian_SwapBE16(1 << 11);
152 static const SK_OT_USHORT UNSCALED_COMPONENT_OFFSET_mask = SkTEndian_SwapBE16(1 << 12);
159 SK_OT_USHORT glyphIndex;
162 /** !WE_HAVE_A_SCALE & !WE_HAVE_AN_X_AND_Y_SCALE & !WE_HAVE_A_TWO_BY_TWO */
163 struct None { } none;
164 /** WE_HAVE_A_SCALE */
168 /** WE_HAVE_AN_X_AND_Y_SCALE */
173 /** WE_HAVE_A_TWO_BY_TWO */
181 /** ARG_1_AND_2_ARE_WORDS & ARGS_ARE_XY_VALUES */
185 SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
187 /** !ARG_1_AND_2_ARE_WORDS & ARGS_ARE_XY_VALUES */
191 SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
193 /** ARG_1_AND_2_ARE_WORDS & !ARGS_ARE_XY_VALUES */
195 SK_OT_USHORT compoundPointIndex;
196 SK_OT_USHORT componentPointIndex;
197 SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
199 /** !ARG_1_AND_2_ARE_WORDS & !ARGS_ARE_XY_VALUES */
201 SK_OT_BYTE compoundPointIndex;
202 SK_OT_BYTE componentPointIndex;
203 SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
206 } component;//[] last element does not set MORE_COMPONENTS
208 /** Comes after the last Component if the last component has WE_HAVE_INSTR. */
209 struct Instructions {
211 SK_OT_BYTE data[1/*length*/];