Additional OpenType tables.
https://codereview.appspot.com/6850075/


git-svn-id: http://skia.googlecode.com/svn/trunk@6509 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/sfnt/SkOTTable_glyf.h b/src/sfnt/SkOTTable_glyf.h
new file mode 100644
index 0000000..c6741a2
--- /dev/null
+++ b/src/sfnt/SkOTTable_glyf.h
@@ -0,0 +1,214 @@
+/*
+ * 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"
+#include "SkTypedEnum.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)
+                                              : SkEndian_SwapBE16(*fLocaPtr.shortOffset);
+        }
+        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