bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 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 "SkEndian.h" |
| 12 | #include "SkOTTableTypes.h" |
| 13 | #include "SkOTTable_head.h" |
| 14 | #include "SkOTTable_loca.h" |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 15 | |
| 16 | #pragma pack(push, 1) |
| 17 | |
| 18 | struct SkOTTableGlyphData; |
| 19 | |
| 20 | extern uint8_t const * const SK_OT_GlyphData_NoOutline; |
| 21 | |
| 22 | struct 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.com | b0a327e | 2012-11-21 02:02:25 +0000 | [diff] [blame] | 28 | |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 29 | 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.com | b0a327e | 2012-11-21 02:02:25 +0000 | [diff] [blame] | 38 | |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 39 | void advance(uint16_t num) { |
| 40 | fLocaPtr.shortOffset += num << fLocaFormat; |
| 41 | fCurrentGlyphOffset = fLocaFormat ? SkEndian_SwapBE32(*fLocaPtr.longOffset) |
humper@google.com | 0e51577 | 2013-01-07 19:54:40 +0000 | [diff] [blame] | 42 | : uint32_t(SkEndian_SwapBE16(*fLocaPtr.shortOffset) << 1); |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 43 | } |
| 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 | |
| 66 | struct 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.com | b0a327e | 2012-11-21 02:02:25 +0000 | [diff] [blame] | 72 | |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 73 | struct Simple { |
| 74 | SK_OT_USHORT endPtsOfContours[1/*numberOfContours*/]; |
skia.committer@gmail.com | b0a327e | 2012-11-21 02:02:25 +0000 | [diff] [blame] | 75 | |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 76 | struct Instructions { |
| 77 | SK_OT_USHORT length; |
| 78 | SK_OT_BYTE data[1/*length*/]; |
| 79 | }; |
skia.committer@gmail.com | b0a327e | 2012-11-21 02:02:25 +0000 | [diff] [blame] | 80 | |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 81 | 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.com | b0a327e | 2012-11-21 02:02:25 +0000 | [diff] [blame] | 103 | |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 104 | //xCoordinates |
| 105 | //yCoordinates |
| 106 | }; |
skia.committer@gmail.com | b0a327e | 2012-11-21 02:02:25 +0000 | [diff] [blame] | 107 | |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 108 | 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.com | b0a327e | 2012-11-21 02:02:25 +0000 | [diff] [blame] | 142 | |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 143 | 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.com | b0a327e | 2012-11-21 02:02:25 +0000 | [diff] [blame] | 202 | |
bungeman@google.com | a544f29 | 2012-11-20 18:52:23 +0000 | [diff] [blame] | 203 | /** 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 |