1 /* 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 "src/base/SkEndian.h" 12 #include "src/sfnt/SkOTTableTypes.h" 13 #include "src/sfnt/SkOTTable_head.h" 14 #include "src/sfnt/SkOTTable_loca.h" 15 16 #pragma pack(push, 1) 17 18 struct SkOTTableGlyphData; 19 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; 26 27 class Iterator { 28 public: IteratorSkOTTableGlyph29 Iterator(SkOTTableGlyph& glyf, 30 const SkOTTableIndexToLocation& loca, 31 SkOTTableHead::IndexToLocFormat locaFormat) 32 : fGlyf(glyf) 33 , fLoca(loca) 34 , fLocaFormat(locaFormat) 35 , fCurrentGlyph(0) 36 , fCurrentGlyphOffset(0) 37 { 38 SkASSERT(locaFormat.value == SkOTTableHead::IndexToLocFormat::ShortOffsets || 39 locaFormat.value == SkOTTableHead::IndexToLocFormat::LongOffsets); 40 } 41 advanceSkOTTableGlyph42 void advance(uint16_t num) { 43 fCurrentGlyph += num; 44 if (fLocaFormat.value == SkOTTableHead::IndexToLocFormat::ShortOffsets) { 45 fCurrentGlyphOffset = 46 SkEndian_SwapBE16(fLoca.offsets.shortOffset[fCurrentGlyph]) << 1; 47 } else if (fLocaFormat.value == SkOTTableHead::IndexToLocFormat::LongOffsets) { 48 fCurrentGlyphOffset = SkEndian_SwapBE32(fLoca.offsets.longOffset[fCurrentGlyph]); 49 } 50 } nextSkOTTableGlyph51 SkOTTableGlyphData* next() { 52 uint32_t previousGlyphOffset = fCurrentGlyphOffset; 53 advance(1); 54 if (previousGlyphOffset == fCurrentGlyphOffset) { 55 return nullptr; 56 } else { 57 return reinterpret_cast<SkOTTableGlyphData*>( 58 reinterpret_cast<SK_OT_BYTE*>(&fGlyf) + previousGlyphOffset 59 ); 60 } 61 } 62 private: 63 SkOTTableGlyph& fGlyf; 64 const SkOTTableIndexToLocation& fLoca; 65 SkOTTableHead::IndexToLocFormat fLocaFormat; 66 uint32_t fCurrentGlyph; 67 uint32_t fCurrentGlyphOffset; 68 }; 69 }; 70 71 struct SkOTTableGlyphData { 72 SK_OT_SHORT numberOfContours; //== -1 Composite, > 0 Simple 73 SK_OT_FWORD xMin; 74 SK_OT_FWORD yMin; 75 SK_OT_FWORD xMax; 76 SK_OT_FWORD yMax; 77 78 struct Simple { 79 SK_OT_USHORT endPtsOfContours[1/*numberOfContours*/]; 80 81 struct Instructions { 82 SK_OT_USHORT length; 83 SK_OT_BYTE data[1/*length*/]; 84 }; 85 86 union Flags { 87 struct Field { 88 SK_OT_BYTE_BITFIELD( 89 OnCurve, 90 xShortVector, 91 yShortVector, 92 Repeat, 93 xIsSame_xShortVectorPositive, 94 yIsSame_yShortVectorPositive, 95 Reserved6, 96 Reserved7) 97 } field; 98 struct Raw { 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); 105 SK_OT_BYTE value; 106 } raw; 107 }; 108 109 //xCoordinates 110 //yCoordinates 111 }; 112 113 struct Composite { 114 struct Component { 115 union Flags { 116 struct Field { 117 //8-15 118 SK_OT_BYTE_BITFIELD( 119 WE_HAVE_INSTRUCTIONS, 120 USE_MY_METRICS, 121 OVERLAP_COMPOUND, 122 SCALED_COMPONENT_OFFSET, 123 UNSCALED_COMPONENT_OFFSET, 124 Reserved13, 125 Reserved14, 126 Reserved15) 127 //0-7 128 SK_OT_BYTE_BITFIELD( 129 ARG_1_AND_2_ARE_WORDS, 130 ARGS_ARE_XY_VALUES, 131 ROUND_XY_TO_GRID, 132 WE_HAVE_A_SCALE, 133 RESERVED, 134 MORE_COMPONENTS, 135 WE_HAVE_AN_X_AND_Y_SCALE, 136 WE_HAVE_A_TWO_BY_TWO) 137 } field; 138 struct Raw { 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); 147 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); 153 //Reserved 154 //Reserved 155 //Reserved 156 SK_OT_USHORT value; 157 } raw; 158 } flags; 159 SK_OT_USHORT glyphIndex; 160 union Transform { 161 union Matrix { 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 */ 165 struct Scale { 166 SK_OT_F2DOT14 a_d; 167 } scale; 168 /** WE_HAVE_AN_X_AND_Y_SCALE */ 169 struct ScaleXY { 170 SK_OT_F2DOT14 a; 171 SK_OT_F2DOT14 d; 172 } scaleXY; 173 /** WE_HAVE_A_TWO_BY_TWO */ 174 struct TwoByTwo { 175 SK_OT_F2DOT14 a; 176 SK_OT_F2DOT14 b; 177 SK_OT_F2DOT14 c; 178 SK_OT_F2DOT14 d; 179 } twoByTwo; 180 }; 181 /** ARG_1_AND_2_ARE_WORDS & ARGS_ARE_XY_VALUES */ 182 struct WordValue { 183 SK_OT_FWORD e; 184 SK_OT_FWORD f; 185 SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix; 186 } wordValue; 187 /** !ARG_1_AND_2_ARE_WORDS & ARGS_ARE_XY_VALUES */ 188 struct ByteValue { 189 SK_OT_CHAR e; 190 SK_OT_CHAR f; 191 SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix; 192 } byteValue; 193 /** ARG_1_AND_2_ARE_WORDS & !ARGS_ARE_XY_VALUES */ 194 struct WordIndex { 195 SK_OT_USHORT compoundPointIndex; 196 SK_OT_USHORT componentPointIndex; 197 SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix; 198 } wordIndex; 199 /** !ARG_1_AND_2_ARE_WORDS & !ARGS_ARE_XY_VALUES */ 200 struct ByteIndex { 201 SK_OT_BYTE compoundPointIndex; 202 SK_OT_BYTE componentPointIndex; 203 SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix; 204 } byteIndex; 205 } transform; 206 } component;//[] last element does not set MORE_COMPONENTS 207 208 /** Comes after the last Component if the last component has WE_HAVE_INSTR. */ 209 struct Instructions { 210 SK_OT_USHORT length; 211 SK_OT_BYTE data[1/*length*/]; 212 }; 213 }; 214 }; 215 216 #pragma pack(pop) 217 218 #endif 219