1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2012 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkOTTable_glyf_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define SkOTTable_glyf_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkEndian.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "src/sfnt/SkOTTableTypes.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sfnt/SkOTTable_head.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "src/sfnt/SkOTTable_loca.h" 15*c8dee2aaSAndroid Build Coastguard Worker 16*c8dee2aaSAndroid Build Coastguard Worker #pragma pack(push, 1) 17*c8dee2aaSAndroid Build Coastguard Worker 18*c8dee2aaSAndroid Build Coastguard Worker struct SkOTTableGlyphData; 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker struct SkOTTableGlyph { 21*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_CHAR TAG0 = 'g'; 22*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_CHAR TAG1 = 'l'; 23*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_CHAR TAG2 = 'y'; 24*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_CHAR TAG3 = 'f'; 25*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_ULONG TAG = SkOTTableTAG<SkOTTableGlyph>::value; 26*c8dee2aaSAndroid Build Coastguard Worker 27*c8dee2aaSAndroid Build Coastguard Worker class Iterator { 28*c8dee2aaSAndroid Build Coastguard Worker public: IteratorSkOTTableGlyph29*c8dee2aaSAndroid Build Coastguard Worker Iterator(SkOTTableGlyph& glyf, 30*c8dee2aaSAndroid Build Coastguard Worker const SkOTTableIndexToLocation& loca, 31*c8dee2aaSAndroid Build Coastguard Worker SkOTTableHead::IndexToLocFormat locaFormat) 32*c8dee2aaSAndroid Build Coastguard Worker : fGlyf(glyf) 33*c8dee2aaSAndroid Build Coastguard Worker , fLoca(loca) 34*c8dee2aaSAndroid Build Coastguard Worker , fLocaFormat(locaFormat) 35*c8dee2aaSAndroid Build Coastguard Worker , fCurrentGlyph(0) 36*c8dee2aaSAndroid Build Coastguard Worker , fCurrentGlyphOffset(0) 37*c8dee2aaSAndroid Build Coastguard Worker { 38*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(locaFormat.value == SkOTTableHead::IndexToLocFormat::ShortOffsets || 39*c8dee2aaSAndroid Build Coastguard Worker locaFormat.value == SkOTTableHead::IndexToLocFormat::LongOffsets); 40*c8dee2aaSAndroid Build Coastguard Worker } 41*c8dee2aaSAndroid Build Coastguard Worker advanceSkOTTableGlyph42*c8dee2aaSAndroid Build Coastguard Worker void advance(uint16_t num) { 43*c8dee2aaSAndroid Build Coastguard Worker fCurrentGlyph += num; 44*c8dee2aaSAndroid Build Coastguard Worker if (fLocaFormat.value == SkOTTableHead::IndexToLocFormat::ShortOffsets) { 45*c8dee2aaSAndroid Build Coastguard Worker fCurrentGlyphOffset = 46*c8dee2aaSAndroid Build Coastguard Worker SkEndian_SwapBE16(fLoca.offsets.shortOffset[fCurrentGlyph]) << 1; 47*c8dee2aaSAndroid Build Coastguard Worker } else if (fLocaFormat.value == SkOTTableHead::IndexToLocFormat::LongOffsets) { 48*c8dee2aaSAndroid Build Coastguard Worker fCurrentGlyphOffset = SkEndian_SwapBE32(fLoca.offsets.longOffset[fCurrentGlyph]); 49*c8dee2aaSAndroid Build Coastguard Worker } 50*c8dee2aaSAndroid Build Coastguard Worker } nextSkOTTableGlyph51*c8dee2aaSAndroid Build Coastguard Worker SkOTTableGlyphData* next() { 52*c8dee2aaSAndroid Build Coastguard Worker uint32_t previousGlyphOffset = fCurrentGlyphOffset; 53*c8dee2aaSAndroid Build Coastguard Worker advance(1); 54*c8dee2aaSAndroid Build Coastguard Worker if (previousGlyphOffset == fCurrentGlyphOffset) { 55*c8dee2aaSAndroid Build Coastguard Worker return nullptr; 56*c8dee2aaSAndroid Build Coastguard Worker } else { 57*c8dee2aaSAndroid Build Coastguard Worker return reinterpret_cast<SkOTTableGlyphData*>( 58*c8dee2aaSAndroid Build Coastguard Worker reinterpret_cast<SK_OT_BYTE*>(&fGlyf) + previousGlyphOffset 59*c8dee2aaSAndroid Build Coastguard Worker ); 60*c8dee2aaSAndroid Build Coastguard Worker } 61*c8dee2aaSAndroid Build Coastguard Worker } 62*c8dee2aaSAndroid Build Coastguard Worker private: 63*c8dee2aaSAndroid Build Coastguard Worker SkOTTableGlyph& fGlyf; 64*c8dee2aaSAndroid Build Coastguard Worker const SkOTTableIndexToLocation& fLoca; 65*c8dee2aaSAndroid Build Coastguard Worker SkOTTableHead::IndexToLocFormat fLocaFormat; 66*c8dee2aaSAndroid Build Coastguard Worker uint32_t fCurrentGlyph; 67*c8dee2aaSAndroid Build Coastguard Worker uint32_t fCurrentGlyphOffset; 68*c8dee2aaSAndroid Build Coastguard Worker }; 69*c8dee2aaSAndroid Build Coastguard Worker }; 70*c8dee2aaSAndroid Build Coastguard Worker 71*c8dee2aaSAndroid Build Coastguard Worker struct SkOTTableGlyphData { 72*c8dee2aaSAndroid Build Coastguard Worker SK_OT_SHORT numberOfContours; //== -1 Composite, > 0 Simple 73*c8dee2aaSAndroid Build Coastguard Worker SK_OT_FWORD xMin; 74*c8dee2aaSAndroid Build Coastguard Worker SK_OT_FWORD yMin; 75*c8dee2aaSAndroid Build Coastguard Worker SK_OT_FWORD xMax; 76*c8dee2aaSAndroid Build Coastguard Worker SK_OT_FWORD yMax; 77*c8dee2aaSAndroid Build Coastguard Worker 78*c8dee2aaSAndroid Build Coastguard Worker struct Simple { 79*c8dee2aaSAndroid Build Coastguard Worker SK_OT_USHORT endPtsOfContours[1/*numberOfContours*/]; 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Worker struct Instructions { 82*c8dee2aaSAndroid Build Coastguard Worker SK_OT_USHORT length; 83*c8dee2aaSAndroid Build Coastguard Worker SK_OT_BYTE data[1/*length*/]; 84*c8dee2aaSAndroid Build Coastguard Worker }; 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker union Flags { 87*c8dee2aaSAndroid Build Coastguard Worker struct Field { 88*c8dee2aaSAndroid Build Coastguard Worker SK_OT_BYTE_BITFIELD( 89*c8dee2aaSAndroid Build Coastguard Worker OnCurve, 90*c8dee2aaSAndroid Build Coastguard Worker xShortVector, 91*c8dee2aaSAndroid Build Coastguard Worker yShortVector, 92*c8dee2aaSAndroid Build Coastguard Worker Repeat, 93*c8dee2aaSAndroid Build Coastguard Worker xIsSame_xShortVectorPositive, 94*c8dee2aaSAndroid Build Coastguard Worker yIsSame_yShortVectorPositive, 95*c8dee2aaSAndroid Build Coastguard Worker Reserved6, 96*c8dee2aaSAndroid Build Coastguard Worker Reserved7) 97*c8dee2aaSAndroid Build Coastguard Worker } field; 98*c8dee2aaSAndroid Build Coastguard Worker struct Raw { 99*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT OnCurveMask = SkTEndian_SwapBE16(1 << 0); 100*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT xShortVectorMask = SkTEndian_SwapBE16(1 << 1); 101*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT yShortVectorMask = SkTEndian_SwapBE16(1 << 2); 102*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT RepeatMask = SkTEndian_SwapBE16(1 << 3); 103*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT xIsSame_xShortVectorPositiveMask = SkTEndian_SwapBE16(1 << 4); 104*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT yIsSame_yShortVectorPositiveMask = SkTEndian_SwapBE16(1 << 5); 105*c8dee2aaSAndroid Build Coastguard Worker SK_OT_BYTE value; 106*c8dee2aaSAndroid Build Coastguard Worker } raw; 107*c8dee2aaSAndroid Build Coastguard Worker }; 108*c8dee2aaSAndroid Build Coastguard Worker 109*c8dee2aaSAndroid Build Coastguard Worker //xCoordinates 110*c8dee2aaSAndroid Build Coastguard Worker //yCoordinates 111*c8dee2aaSAndroid Build Coastguard Worker }; 112*c8dee2aaSAndroid Build Coastguard Worker 113*c8dee2aaSAndroid Build Coastguard Worker struct Composite { 114*c8dee2aaSAndroid Build Coastguard Worker struct Component { 115*c8dee2aaSAndroid Build Coastguard Worker union Flags { 116*c8dee2aaSAndroid Build Coastguard Worker struct Field { 117*c8dee2aaSAndroid Build Coastguard Worker //8-15 118*c8dee2aaSAndroid Build Coastguard Worker SK_OT_BYTE_BITFIELD( 119*c8dee2aaSAndroid Build Coastguard Worker WE_HAVE_INSTRUCTIONS, 120*c8dee2aaSAndroid Build Coastguard Worker USE_MY_METRICS, 121*c8dee2aaSAndroid Build Coastguard Worker OVERLAP_COMPOUND, 122*c8dee2aaSAndroid Build Coastguard Worker SCALED_COMPONENT_OFFSET, 123*c8dee2aaSAndroid Build Coastguard Worker UNSCALED_COMPONENT_OFFSET, 124*c8dee2aaSAndroid Build Coastguard Worker Reserved13, 125*c8dee2aaSAndroid Build Coastguard Worker Reserved14, 126*c8dee2aaSAndroid Build Coastguard Worker Reserved15) 127*c8dee2aaSAndroid Build Coastguard Worker //0-7 128*c8dee2aaSAndroid Build Coastguard Worker SK_OT_BYTE_BITFIELD( 129*c8dee2aaSAndroid Build Coastguard Worker ARG_1_AND_2_ARE_WORDS, 130*c8dee2aaSAndroid Build Coastguard Worker ARGS_ARE_XY_VALUES, 131*c8dee2aaSAndroid Build Coastguard Worker ROUND_XY_TO_GRID, 132*c8dee2aaSAndroid Build Coastguard Worker WE_HAVE_A_SCALE, 133*c8dee2aaSAndroid Build Coastguard Worker RESERVED, 134*c8dee2aaSAndroid Build Coastguard Worker MORE_COMPONENTS, 135*c8dee2aaSAndroid Build Coastguard Worker WE_HAVE_AN_X_AND_Y_SCALE, 136*c8dee2aaSAndroid Build Coastguard Worker WE_HAVE_A_TWO_BY_TWO) 137*c8dee2aaSAndroid Build Coastguard Worker } field; 138*c8dee2aaSAndroid Build Coastguard Worker struct Raw { 139*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT ARG_1_AND_2_ARE_WORDS_Mask = SkTEndian_SwapBE16(1 << 0); 140*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT ARGS_ARE_XY_VALUES_Mask = SkTEndian_SwapBE16(1 << 1); 141*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT ROUND_XY_TO_GRID_Mask = SkTEndian_SwapBE16(1 << 2); 142*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT WE_HAVE_A_SCALE_Mask = SkTEndian_SwapBE16(1 << 3); 143*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT RESERVED_Mask = SkTEndian_SwapBE16(1 << 4); 144*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT MORE_COMPONENTS_Mask = SkTEndian_SwapBE16(1 << 5); 145*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT WE_HAVE_AN_X_AND_Y_SCALE_Mask = SkTEndian_SwapBE16(1 << 6); 146*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT WE_HAVE_A_TWO_BY_TWO_Mask = SkTEndian_SwapBE16(1 << 7); 147*c8dee2aaSAndroid Build Coastguard Worker 148*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT WE_HAVE_INSTRUCTIONS_Mask = SkTEndian_SwapBE16(1 << 8); 149*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT USE_MY_METRICS_Mask = SkTEndian_SwapBE16(1 << 9); 150*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT OVERLAP_COMPOUND_Mask = SkTEndian_SwapBE16(1 << 10); 151*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT SCALED_COMPONENT_OFFSET_Mask = SkTEndian_SwapBE16(1 << 11); 152*c8dee2aaSAndroid Build Coastguard Worker static const SK_OT_USHORT UNSCALED_COMPONENT_OFFSET_mask = SkTEndian_SwapBE16(1 << 12); 153*c8dee2aaSAndroid Build Coastguard Worker //Reserved 154*c8dee2aaSAndroid Build Coastguard Worker //Reserved 155*c8dee2aaSAndroid Build Coastguard Worker //Reserved 156*c8dee2aaSAndroid Build Coastguard Worker SK_OT_USHORT value; 157*c8dee2aaSAndroid Build Coastguard Worker } raw; 158*c8dee2aaSAndroid Build Coastguard Worker } flags; 159*c8dee2aaSAndroid Build Coastguard Worker SK_OT_USHORT glyphIndex; 160*c8dee2aaSAndroid Build Coastguard Worker union Transform { 161*c8dee2aaSAndroid Build Coastguard Worker union Matrix { 162*c8dee2aaSAndroid Build Coastguard Worker /** !WE_HAVE_A_SCALE & !WE_HAVE_AN_X_AND_Y_SCALE & !WE_HAVE_A_TWO_BY_TWO */ 163*c8dee2aaSAndroid Build Coastguard Worker struct None { } none; 164*c8dee2aaSAndroid Build Coastguard Worker /** WE_HAVE_A_SCALE */ 165*c8dee2aaSAndroid Build Coastguard Worker struct Scale { 166*c8dee2aaSAndroid Build Coastguard Worker SK_OT_F2DOT14 a_d; 167*c8dee2aaSAndroid Build Coastguard Worker } scale; 168*c8dee2aaSAndroid Build Coastguard Worker /** WE_HAVE_AN_X_AND_Y_SCALE */ 169*c8dee2aaSAndroid Build Coastguard Worker struct ScaleXY { 170*c8dee2aaSAndroid Build Coastguard Worker SK_OT_F2DOT14 a; 171*c8dee2aaSAndroid Build Coastguard Worker SK_OT_F2DOT14 d; 172*c8dee2aaSAndroid Build Coastguard Worker } scaleXY; 173*c8dee2aaSAndroid Build Coastguard Worker /** WE_HAVE_A_TWO_BY_TWO */ 174*c8dee2aaSAndroid Build Coastguard Worker struct TwoByTwo { 175*c8dee2aaSAndroid Build Coastguard Worker SK_OT_F2DOT14 a; 176*c8dee2aaSAndroid Build Coastguard Worker SK_OT_F2DOT14 b; 177*c8dee2aaSAndroid Build Coastguard Worker SK_OT_F2DOT14 c; 178*c8dee2aaSAndroid Build Coastguard Worker SK_OT_F2DOT14 d; 179*c8dee2aaSAndroid Build Coastguard Worker } twoByTwo; 180*c8dee2aaSAndroid Build Coastguard Worker }; 181*c8dee2aaSAndroid Build Coastguard Worker /** ARG_1_AND_2_ARE_WORDS & ARGS_ARE_XY_VALUES */ 182*c8dee2aaSAndroid Build Coastguard Worker struct WordValue { 183*c8dee2aaSAndroid Build Coastguard Worker SK_OT_FWORD e; 184*c8dee2aaSAndroid Build Coastguard Worker SK_OT_FWORD f; 185*c8dee2aaSAndroid Build Coastguard Worker SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix; 186*c8dee2aaSAndroid Build Coastguard Worker } wordValue; 187*c8dee2aaSAndroid Build Coastguard Worker /** !ARG_1_AND_2_ARE_WORDS & ARGS_ARE_XY_VALUES */ 188*c8dee2aaSAndroid Build Coastguard Worker struct ByteValue { 189*c8dee2aaSAndroid Build Coastguard Worker SK_OT_CHAR e; 190*c8dee2aaSAndroid Build Coastguard Worker SK_OT_CHAR f; 191*c8dee2aaSAndroid Build Coastguard Worker SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix; 192*c8dee2aaSAndroid Build Coastguard Worker } byteValue; 193*c8dee2aaSAndroid Build Coastguard Worker /** ARG_1_AND_2_ARE_WORDS & !ARGS_ARE_XY_VALUES */ 194*c8dee2aaSAndroid Build Coastguard Worker struct WordIndex { 195*c8dee2aaSAndroid Build Coastguard Worker SK_OT_USHORT compoundPointIndex; 196*c8dee2aaSAndroid Build Coastguard Worker SK_OT_USHORT componentPointIndex; 197*c8dee2aaSAndroid Build Coastguard Worker SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix; 198*c8dee2aaSAndroid Build Coastguard Worker } wordIndex; 199*c8dee2aaSAndroid Build Coastguard Worker /** !ARG_1_AND_2_ARE_WORDS & !ARGS_ARE_XY_VALUES */ 200*c8dee2aaSAndroid Build Coastguard Worker struct ByteIndex { 201*c8dee2aaSAndroid Build Coastguard Worker SK_OT_BYTE compoundPointIndex; 202*c8dee2aaSAndroid Build Coastguard Worker SK_OT_BYTE componentPointIndex; 203*c8dee2aaSAndroid Build Coastguard Worker SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix; 204*c8dee2aaSAndroid Build Coastguard Worker } byteIndex; 205*c8dee2aaSAndroid Build Coastguard Worker } transform; 206*c8dee2aaSAndroid Build Coastguard Worker } component;//[] last element does not set MORE_COMPONENTS 207*c8dee2aaSAndroid Build Coastguard Worker 208*c8dee2aaSAndroid Build Coastguard Worker /** Comes after the last Component if the last component has WE_HAVE_INSTR. */ 209*c8dee2aaSAndroid Build Coastguard Worker struct Instructions { 210*c8dee2aaSAndroid Build Coastguard Worker SK_OT_USHORT length; 211*c8dee2aaSAndroid Build Coastguard Worker SK_OT_BYTE data[1/*length*/]; 212*c8dee2aaSAndroid Build Coastguard Worker }; 213*c8dee2aaSAndroid Build Coastguard Worker }; 214*c8dee2aaSAndroid Build Coastguard Worker }; 215*c8dee2aaSAndroid Build Coastguard Worker 216*c8dee2aaSAndroid Build Coastguard Worker #pragma pack(pop) 217*c8dee2aaSAndroid Build Coastguard Worker 218*c8dee2aaSAndroid Build Coastguard Worker #endif 219