/*
|
* Copyright 2012 Google Inc.
|
*
|
* Use of this source code is governed by a BSD-style license that can be
|
* found in the LICENSE file.
|
*/
|
|
#ifndef SkOTTable_glyf_DEFINED
|
#define SkOTTable_glyf_DEFINED
|
|
#include "SkEndian.h"
|
#include "SkOTTableTypes.h"
|
#include "SkOTTable_head.h"
|
#include "SkOTTable_loca.h"
|
|
#pragma pack(push, 1)
|
|
struct SkOTTableGlyphData;
|
|
extern uint8_t const * const SK_OT_GlyphData_NoOutline;
|
|
struct SkOTTableGlyph {
|
static const SK_OT_CHAR TAG0 = 'g';
|
static const SK_OT_CHAR TAG1 = 'l';
|
static const SK_OT_CHAR TAG2 = 'y';
|
static const SK_OT_CHAR TAG3 = 'f';
|
static const SK_OT_ULONG TAG = SkOTTableTAG<SkOTTableGlyph>::value;
|
|
class Iterator {
|
public:
|
Iterator(const SkOTTableGlyph& glyf,
|
const SkOTTableIndexToLocation& loca,
|
SkOTTableHead::IndexToLocFormat locaFormat)
|
: fGlyf(glyf)
|
, fLocaFormat(SkOTTableHead::IndexToLocFormat::ShortOffsets == locaFormat.value ? 0 : 1)
|
, fCurrentGlyphOffset(0)
|
{ fLocaPtr.shortOffset = reinterpret_cast<const SK_OT_USHORT*>(&loca); }
|
|
void advance(uint16_t num) {
|
fLocaPtr.shortOffset += num << fLocaFormat;
|
fCurrentGlyphOffset = fLocaFormat ? SkEndian_SwapBE32(*fLocaPtr.longOffset)
|
: uint32_t(SkEndian_SwapBE16(*fLocaPtr.shortOffset) << 1);
|
}
|
const SkOTTableGlyphData* next() {
|
uint32_t previousGlyphOffset = fCurrentGlyphOffset;
|
advance(1);
|
if (previousGlyphOffset == fCurrentGlyphOffset) {
|
return reinterpret_cast<const SkOTTableGlyphData*>(&SK_OT_GlyphData_NoOutline);
|
} else {
|
return reinterpret_cast<const SkOTTableGlyphData*>(
|
reinterpret_cast<const SK_OT_BYTE*>(&fGlyf) + previousGlyphOffset
|
);
|
}
|
}
|
private:
|
const SkOTTableGlyph& fGlyf;
|
uint16_t fLocaFormat; //0 or 1
|
uint32_t fCurrentGlyphOffset;
|
union LocaPtr {
|
const SK_OT_USHORT* shortOffset;
|
const SK_OT_ULONG* longOffset;
|
} fLocaPtr;
|
};
|
};
|
|
struct SkOTTableGlyphData {
|
SK_OT_SHORT numberOfContours; //== -1 Composite, > 0 Simple
|
SK_OT_FWORD xMin;
|
SK_OT_FWORD yMin;
|
SK_OT_FWORD xMax;
|
SK_OT_FWORD yMax;
|
|
struct Simple {
|
SK_OT_USHORT endPtsOfContours[1/*numberOfContours*/];
|
|
struct Instructions {
|
SK_OT_USHORT length;
|
SK_OT_BYTE data[1/*length*/];
|
};
|
|
union Flags {
|
struct Field {
|
SK_OT_BYTE_BITFIELD(
|
OnCurve,
|
xShortVector,
|
yShortVector,
|
Repeat,
|
xIsSame_xShortVectorPositive,
|
yIsSame_yShortVectorPositive,
|
Reserved6,
|
Reserved7)
|
} field;
|
struct Raw {
|
static const SK_OT_USHORT OnCurveMask = SkTEndian_SwapBE16(1 << 0);
|
static const SK_OT_USHORT xShortVectorMask = SkTEndian_SwapBE16(1 << 1);
|
static const SK_OT_USHORT yShortVectorMask = SkTEndian_SwapBE16(1 << 2);
|
static const SK_OT_USHORT RepeatMask = SkTEndian_SwapBE16(1 << 3);
|
static const SK_OT_USHORT xIsSame_xShortVectorPositiveMask = SkTEndian_SwapBE16(1 << 4);
|
static const SK_OT_USHORT yIsSame_yShortVectorPositiveMask = SkTEndian_SwapBE16(1 << 5);
|
SK_OT_BYTE value;
|
} raw;
|
};
|
|
//xCoordinates
|
//yCoordinates
|
};
|
|
struct Composite {
|
struct Component {
|
union Flags {
|
struct Field {
|
//8-15
|
SK_OT_BYTE_BITFIELD(
|
WE_HAVE_INSTRUCTIONS,
|
USE_MY_METRICS,
|
OVERLAP_COMPOUND,
|
SCALED_COMPONENT_OFFSET,
|
UNSCALED_COMPONENT_OFFSET,
|
Reserved13,
|
Reserved14,
|
Reserved15)
|
//0-7
|
SK_OT_BYTE_BITFIELD(
|
ARG_1_AND_2_ARE_WORDS,
|
ARGS_ARE_XY_VALUES,
|
ROUND_XY_TO_GRID,
|
WE_HAVE_A_SCALE,
|
RESERVED,
|
MORE_COMPONENTS,
|
WE_HAVE_AN_X_AND_Y_SCALE,
|
WE_HAVE_A_TWO_BY_TWO)
|
} field;
|
struct Raw {
|
static const SK_OT_USHORT ARG_1_AND_2_ARE_WORDS_Mask = SkTEndian_SwapBE16(1 << 0);
|
static const SK_OT_USHORT ARGS_ARE_XY_VALUES_Mask = SkTEndian_SwapBE16(1 << 1);
|
static const SK_OT_USHORT ROUND_XY_TO_GRID_Mask = SkTEndian_SwapBE16(1 << 2);
|
static const SK_OT_USHORT WE_HAVE_A_SCALE_Mask = SkTEndian_SwapBE16(1 << 3);
|
static const SK_OT_USHORT RESERVED_Mask = SkTEndian_SwapBE16(1 << 4);
|
static const SK_OT_USHORT MORE_COMPONENTS_Mask = SkTEndian_SwapBE16(1 << 5);
|
static const SK_OT_USHORT WE_HAVE_AN_X_AND_Y_SCALE_Mask = SkTEndian_SwapBE16(1 << 6);
|
static const SK_OT_USHORT WE_HAVE_A_TWO_BY_TWO_Mask = SkTEndian_SwapBE16(1 << 7);
|
|
static const SK_OT_USHORT WE_HAVE_INSTRUCTIONS_Mask = SkTEndian_SwapBE16(1 << 8);
|
static const SK_OT_USHORT USE_MY_METRICS_Mask = SkTEndian_SwapBE16(1 << 9);
|
static const SK_OT_USHORT OVERLAP_COMPOUND_Mask = SkTEndian_SwapBE16(1 << 10);
|
static const SK_OT_USHORT SCALED_COMPONENT_OFFSET_Mask = SkTEndian_SwapBE16(1 << 11);
|
static const SK_OT_USHORT UNSCALED_COMPONENT_OFFSET_mask = SkTEndian_SwapBE16(1 << 12);
|
//Reserved
|
//Reserved
|
//Reserved
|
SK_OT_USHORT value;
|
} raw;
|
} flags;
|
SK_OT_USHORT glyphIndex;
|
union Transform {
|
union Matrix {
|
/** !WE_HAVE_A_SCALE & !WE_HAVE_AN_X_AND_Y_SCALE & !WE_HAVE_A_TWO_BY_TWO */
|
struct None { } none;
|
/** WE_HAVE_A_SCALE */
|
struct Scale {
|
SK_OT_F2DOT14 a_d;
|
} scale;
|
/** WE_HAVE_AN_X_AND_Y_SCALE */
|
struct ScaleXY {
|
SK_OT_F2DOT14 a;
|
SK_OT_F2DOT14 d;
|
} scaleXY;
|
/** WE_HAVE_A_TWO_BY_TWO */
|
struct TwoByTwo {
|
SK_OT_F2DOT14 a;
|
SK_OT_F2DOT14 b;
|
SK_OT_F2DOT14 c;
|
SK_OT_F2DOT14 d;
|
} twoByTwo;
|
};
|
/** ARG_1_AND_2_ARE_WORDS & ARGS_ARE_XY_VALUES */
|
struct WordValue {
|
SK_OT_FWORD e;
|
SK_OT_FWORD f;
|
SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
|
} wordValue;
|
/** !ARG_1_AND_2_ARE_WORDS & ARGS_ARE_XY_VALUES */
|
struct ByteValue {
|
SK_OT_CHAR e;
|
SK_OT_CHAR f;
|
SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
|
} byteValue;
|
/** ARG_1_AND_2_ARE_WORDS & !ARGS_ARE_XY_VALUES */
|
struct WordIndex {
|
SK_OT_USHORT compoundPointIndex;
|
SK_OT_USHORT componentPointIndex;
|
SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
|
} wordIndex;
|
/** !ARG_1_AND_2_ARE_WORDS & !ARGS_ARE_XY_VALUES */
|
struct ByteIndex {
|
SK_OT_BYTE compoundPointIndex;
|
SK_OT_BYTE componentPointIndex;
|
SkOTTableGlyphData::Composite::Component::Transform::Matrix matrix;
|
} byteIndex;
|
} transform;
|
} component;//[] last element does not set MORE_COMPONENTS
|
|
/** Comes after the last Component if the last component has WE_HAVE_INSTR. */
|
struct Instructions {
|
SK_OT_USHORT length;
|
SK_OT_BYTE data[1/*length*/];
|
};
|
};
|
};
|
|
#pragma pack(pop)
|
|
#endif
|