/*
 * Opentype font interfaces for the Uniscribe Script Processor (usp10.dll)
 *
 * Copyright 2012 CodeWeavers, Aric Stewart
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 */
#include <stdarg.h>
#include <stdlib.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "usp10.h"
#include "winternl.h"

#include "usp10_internal.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(uniscribe);

#ifdef WORDS_BIGENDIAN
#define GET_BE_WORD(x) (x)
#define GET_BE_DWORD(x) (x)
#else
#define GET_BE_WORD(x) RtlUshortByteSwap(x)
#define GET_BE_DWORD(x) RtlUlongByteSwap(x)
#endif

#define round(x) (((x) < 0) ? (int)((x) - 0.5) : (int)((x) + 0.5))

/* These are all structures needed for the cmap format 12 table */
#define CMAP_TAG MS_MAKE_TAG('c', 'm', 'a', 'p')

typedef struct {
    WORD platformID;
    WORD encodingID;
    DWORD offset;
} CMAP_EncodingRecord;

typedef struct {
    WORD version;
    WORD numTables;
    CMAP_EncodingRecord tables[1];
} CMAP_Header;

typedef struct {
    DWORD startCharCode;
    DWORD endCharCode;
    DWORD startGlyphID;
} CMAP_SegmentedCoverage_group;

typedef struct {
    WORD format;
    WORD reserved;
    DWORD length;
    DWORD language;
    DWORD nGroups;
    CMAP_SegmentedCoverage_group groups[1];
} CMAP_SegmentedCoverage;

/* These are all structures needed for the GDEF table */
enum {BaseGlyph=1, LigatureGlyph, MarkGlyph, ComponentGlyph};

typedef struct {
    DWORD Version;
    WORD GlyphClassDef;
    WORD AttachList;
    WORD LigCaretList;
    WORD MarkAttachClassDef;
} GDEF_Header;

typedef struct {
    WORD ClassFormat;
    WORD StartGlyph;
    WORD GlyphCount;
    WORD ClassValueArray[1];
} OT_ClassDefFormat1;

typedef struct {
    WORD Start;
    WORD End;
    WORD Class;
} OT_ClassRangeRecord;

typedef struct {
    WORD ClassFormat;
    WORD ClassRangeCount;
    OT_ClassRangeRecord ClassRangeRecord[1];
} OT_ClassDefFormat2;

/* These are all structures needed for the GSUB table */

typedef struct {
    DWORD version;
    WORD ScriptList;
    WORD FeatureList;
    WORD LookupList;
} GSUB_Header;

typedef struct {
    CHAR ScriptTag[4];
    WORD Script;
} OT_ScriptRecord;

typedef struct {
    WORD ScriptCount;
    OT_ScriptRecord ScriptRecord[1];
} OT_ScriptList;

typedef struct {
    CHAR LangSysTag[4];
    WORD LangSys;
} OT_LangSysRecord;

typedef struct {
    WORD DefaultLangSys;
    WORD LangSysCount;
    OT_LangSysRecord LangSysRecord[1];
} OT_Script;

typedef struct {
    WORD LookupOrder; /* Reserved */
    WORD ReqFeatureIndex;
    WORD FeatureCount;
    WORD FeatureIndex[1];
} OT_LangSys;

typedef struct {
    CHAR FeatureTag[4];
    WORD Feature;
} OT_FeatureRecord;

typedef struct {
    WORD FeatureCount;
    OT_FeatureRecord FeatureRecord[1];
} OT_FeatureList;

typedef struct {
    WORD FeatureParams; /* Reserved */
    WORD LookupCount;
    WORD LookupListIndex[1];
} OT_Feature;

typedef struct {
    WORD LookupCount;
    WORD Lookup[1];
} OT_LookupList;

typedef struct {
    WORD LookupType;
    WORD LookupFlag;
    WORD SubTableCount;
    WORD SubTable[1];
} OT_LookupTable;

typedef struct {
    WORD CoverageFormat;
    WORD GlyphCount;
    WORD GlyphArray[1];
} OT_CoverageFormat1;

typedef struct {
    WORD Start;
    WORD End;
    WORD StartCoverageIndex;
} OT_RangeRecord;

typedef struct {
    WORD CoverageFormat;
    WORD RangeCount;
    OT_RangeRecord RangeRecord[1];
} OT_CoverageFormat2;

typedef struct {
    WORD SubstFormat; /* = 1 */
    WORD Coverage;
    WORD DeltaGlyphID;
} GSUB_SingleSubstFormat1;

typedef struct {
    WORD SubstFormat; /* = 2 */
    WORD Coverage;
    WORD GlyphCount;
    WORD Substitute[1];
}GSUB_SingleSubstFormat2;

typedef struct {
    WORD SubstFormat; /* = 1 */
    WORD Coverage;
    WORD SequenceCount;
    WORD Sequence[1];
}GSUB_MultipleSubstFormat1;

typedef struct {
    WORD GlyphCount;
    WORD Substitute[1];
}GSUB_Sequence;

typedef struct {
    WORD SubstFormat; /* = 1 */
    WORD Coverage;
    WORD LigSetCount;
    WORD LigatureSet[1];
}GSUB_LigatureSubstFormat1;

typedef struct {
    WORD LigatureCount;
    WORD Ligature[1];
}GSUB_LigatureSet;

typedef struct{
    WORD LigGlyph;
    WORD CompCount;
    WORD Component[1];
}GSUB_Ligature;

typedef struct{
    WORD SequenceIndex;
    WORD LookupListIndex;

}GSUB_SubstLookupRecord;

typedef struct{
    WORD SubstFormat;
    WORD Coverage;
    WORD SubRuleSetCount;
    WORD SubRuleSet[1];
}GSUB_ContextSubstFormat1;

typedef struct{
    WORD SubRuleCount;
    WORD SubRule[1];
}GSUB_SubRuleSet;

typedef struct {
    WORD GlyphCount;
    WORD SubstCount;
    WORD Input[1];
}GSUB_SubRule_1;

typedef struct {
    GSUB_SubstLookupRecord SubstLookupRecord[1];
}GSUB_SubRule_2;

typedef struct {
    WORD SubstFormat;
    WORD Coverage;
    WORD ClassDef;
    WORD SubClassSetCnt;
    WORD SubClassSet[1];
}GSUB_ContextSubstFormat2;

typedef struct {
    WORD SubClassRuleCnt;
    WORD SubClassRule[1];
}GSUB_SubClassSet;

typedef struct {
    WORD GlyphCount;
    WORD SubstCount;
    WORD Class[1];
}GSUB_SubClassRule_1;

typedef struct {
    GSUB_SubstLookupRecord SubstLookupRecord[1];
}GSUB_SubClassRule_2;

typedef struct{
    WORD SubstFormat; /* = 1 */
    WORD Coverage;
    WORD ChainSubRuleSetCount;
    WORD ChainSubRuleSet[1];
}GSUB_ChainContextSubstFormat1;

typedef struct {
    WORD SubstFormat; /* = 2 */
    WORD Coverage;
    WORD BacktrackClassDef;
    WORD InputClassDef;
    WORD LookaheadClassDef;
    WORD ChainSubClassSetCnt;
    WORD ChainSubClassSet[1];
}GSUB_ChainContextSubstFormat2;

typedef struct {
    WORD ChainSubClassRuleCnt;
    WORD ChainSubClassRule[1];
}GSUB_ChainSubClassSet;

typedef struct {
    WORD BacktrackGlyphCount;
    WORD Backtrack[1];
}GSUB_ChainSubClassRule_1;

typedef struct {
    WORD InputGlyphCount;
    WORD Input[1];
}GSUB_ChainSubClassRule_2;

typedef struct {
    WORD LookaheadGlyphCount;
    WORD LookAhead[1];
}GSUB_ChainSubClassRule_3;

typedef struct {
    WORD SubstCount;
    GSUB_SubstLookupRecord SubstLookupRecord[1];
}GSUB_ChainSubClassRule_4;

typedef struct {
    WORD SubstFormat; /* = 3 */
    WORD BacktrackGlyphCount;
    WORD Coverage[1];
}GSUB_ChainContextSubstFormat3_1;

typedef struct{
    WORD InputGlyphCount;
    WORD Coverage[1];
}GSUB_ChainContextSubstFormat3_2;

typedef struct{
    WORD LookaheadGlyphCount;
    WORD Coverage[1];
}GSUB_ChainContextSubstFormat3_3;

typedef struct{
    WORD SubstCount;
    GSUB_SubstLookupRecord SubstLookupRecord[1];
}GSUB_ChainContextSubstFormat3_4;

typedef struct {
    WORD SubstFormat; /* = 1 */
    WORD Coverage;
    WORD AlternateSetCount;
    WORD AlternateSet[1];
} GSUB_AlternateSubstFormat1;

typedef struct{
    WORD GlyphCount;
    WORD Alternate[1];
} GSUB_AlternateSet;

typedef struct {
    WORD SubstFormat;
    WORD ExtensionLookupType;
    DWORD ExtensionOffset;
} GSUB_ExtensionPosFormat1;

/* These are all structures needed for the GPOS table */

typedef struct {
    DWORD version;
    WORD ScriptList;
    WORD FeatureList;
    WORD LookupList;
} GPOS_Header;

typedef struct {
    WORD StartSize;
    WORD EndSize;
    WORD DeltaFormat;
    WORD DeltaValue[1];
} OT_DeviceTable;

typedef struct {
    WORD AnchorFormat;
    WORD XCoordinate;
    WORD YCoordinate;
} GPOS_AnchorFormat1;

typedef struct {
    WORD AnchorFormat;
    WORD XCoordinate;
    WORD YCoordinate;
    WORD AnchorPoint;
} GPOS_AnchorFormat2;

typedef struct {
    WORD AnchorFormat;
    WORD XCoordinate;
    WORD YCoordinate;
    WORD XDeviceTable;
    WORD YDeviceTable;
} GPOS_AnchorFormat3;

typedef struct {
    WORD XPlacement;
    WORD YPlacement;
    WORD XAdvance;
    WORD YAdvance;
    WORD XPlaDevice;
    WORD YPlaDevice;
    WORD XAdvDevice;
    WORD YAdvDevice;
} GPOS_ValueRecord;

typedef struct {
    WORD PosFormat;
    WORD Coverage;
    WORD ValueFormat;
    WORD Value[1];
} GPOS_SinglePosFormat1;

typedef struct {
    WORD PosFormat;
    WORD Coverage;
    WORD ValueFormat;
    WORD ValueCount;
    WORD Value[1];
} GPOS_SinglePosFormat2;

typedef struct {
    WORD PosFormat;
    WORD Coverage;
    WORD ValueFormat1;
    WORD ValueFormat2;
    WORD PairSetCount;
    WORD PairSetOffset[1];
} GPOS_PairPosFormat1;

typedef struct {
    WORD PosFormat;
    WORD Coverage;
    WORD ValueFormat1;
    WORD ValueFormat2;
    WORD ClassDef1;
    WORD ClassDef2;
    WORD Class1Count;
    WORD Class2Count;
    WORD Class1Record[1];
} GPOS_PairPosFormat2;

typedef struct {
    WORD SecondGlyph;
    WORD Value1[1];
    WORD Value2[1];
} GPOS_PairValueRecord;

typedef struct {
    WORD PairValueCount;
    GPOS_PairValueRecord PairValueRecord[1];
} GPOS_PairSet;

typedef struct {
    WORD EntryAnchor;
    WORD ExitAnchor;
} GPOS_EntryExitRecord;

typedef struct {
    WORD PosFormat;
    WORD Coverage;
    WORD EntryExitCount;
    GPOS_EntryExitRecord EntryExitRecord[1];
} GPOS_CursivePosFormat1;

typedef struct {
    WORD PosFormat;
    WORD MarkCoverage;
    WORD BaseCoverage;
    WORD ClassCount;
    WORD MarkArray;
    WORD BaseArray;
} GPOS_MarkBasePosFormat1;

typedef struct {
    WORD BaseAnchor[1];
} GPOS_BaseRecord;

typedef struct {
    WORD BaseCount;
    GPOS_BaseRecord BaseRecord[1];
} GPOS_BaseArray;

typedef struct {
    WORD Class;
    WORD MarkAnchor;
} GPOS_MarkRecord;

typedef struct {
    WORD MarkCount;
    GPOS_MarkRecord MarkRecord[1];
} GPOS_MarkArray;

typedef struct {
    WORD PosFormat;
    WORD MarkCoverage;
    WORD LigatureCoverage;
    WORD ClassCount;
    WORD MarkArray;
    WORD LigatureArray;
} GPOS_MarkLigPosFormat1;

typedef struct {
    WORD LigatureCount;
    WORD LigatureAttach[1];
} GPOS_LigatureArray;

typedef struct {
    WORD LigatureAnchor[1];
} GPOS_ComponentRecord;

typedef struct {
    WORD ComponentCount;
    GPOS_ComponentRecord ComponentRecord[1];
} GPOS_LigatureAttach;

typedef struct {
    WORD PosFormat;
    WORD Mark1Coverage;
    WORD Mark2Coverage;
    WORD ClassCount;
    WORD Mark1Array;
    WORD Mark2Array;
} GPOS_MarkMarkPosFormat1;

typedef struct {
    WORD Mark2Anchor[1];
} GPOS_Mark2Record;

typedef struct {
    WORD Mark2Count;
    GPOS_Mark2Record Mark2Record[1];
} GPOS_Mark2Array;

typedef struct {
    WORD SequenceIndex;
    WORD LookupListIndex;
} GPOS_PosLookupRecord;

typedef struct {
    WORD PosFormat;
    WORD Coverage;
    WORD ClassDef;
    WORD PosClassSetCnt;
    WORD PosClassSet[1];
} GPOS_ContextPosFormat2;

typedef struct {
    WORD PosClassRuleCnt;
    WORD PosClassRule[1];
} GPOS_PosClassSet;

typedef struct {
    WORD GlyphCount;
    WORD PosCount;
    WORD Class[1];
} GPOS_PosClassRule_1;

typedef struct {
    GPOS_PosLookupRecord PosLookupRecord[1];
} GPOS_PosClassRule_2;

typedef struct {
    WORD PosFormat;
    WORD BacktrackGlyphCount;
    WORD Coverage[1];
} GPOS_ChainContextPosFormat3_1;

typedef struct {
    WORD InputGlyphCount;
    WORD Coverage[1];
} GPOS_ChainContextPosFormat3_2;

typedef struct {
    WORD LookaheadGlyphCount;
    WORD Coverage[1];
} GPOS_ChainContextPosFormat3_3;

typedef struct {
    WORD PosCount;
    GPOS_PosLookupRecord PosLookupRecord[1];
} GPOS_ChainContextPosFormat3_4;

typedef struct {
    WORD PosFormat;
    WORD ExtensionLookupType;
    DWORD ExtensionOffset;
} GPOS_ExtensionPosFormat1;

/**********
 * CMAP
 **********/

static VOID *load_CMAP_format12_table(HDC hdc, ScriptCache *psc)
{
    CMAP_Header *CMAP_Table = NULL;
    int length;
    int i;

    if (!psc->CMAP_Table)
    {
        length = GetFontData(hdc, CMAP_TAG , 0, NULL, 0);
        if (length != GDI_ERROR)
        {
            psc->CMAP_Table = HeapAlloc(GetProcessHeap(),0,length);
            GetFontData(hdc, CMAP_TAG , 0, psc->CMAP_Table, length);
            TRACE("Loaded cmap table of %i bytes\n",length);
        }
        else
            return NULL;
    }

    CMAP_Table = psc->CMAP_Table;

    for (i = 0; i < GET_BE_WORD(CMAP_Table->numTables); i++)
    {
        if ( (GET_BE_WORD(CMAP_Table->tables[i].platformID) == 3) &&
             (GET_BE_WORD(CMAP_Table->tables[i].encodingID) == 10) )
        {
            CMAP_SegmentedCoverage *format = (CMAP_SegmentedCoverage*)(((BYTE*)CMAP_Table) + GET_BE_DWORD(CMAP_Table->tables[i].offset));
            if (GET_BE_WORD(format->format) == 12)
                return format;
        }
    }
    return NULL;
}

static int compare_group(const void *a, const void* b)
{
    const DWORD *chr = a;
    const CMAP_SegmentedCoverage_group *group = b;

    if (*chr < GET_BE_DWORD(group->startCharCode))
        return -1;
    if (*chr > GET_BE_DWORD(group->endCharCode))
        return 1;
    return 0;
}

DWORD OpenType_CMAP_GetGlyphIndex(HDC hdc, ScriptCache *psc, DWORD utf32c, LPWORD pgi, DWORD flags)
{
    /* BMP: use gdi32 for ease */
    if (utf32c < 0x10000)
    {
        WCHAR ch = utf32c;
        return GetGlyphIndicesW(hdc,&ch, 1, pgi, flags);
    }

    if (!psc->CMAP_format12_Table)
        psc->CMAP_format12_Table = load_CMAP_format12_table(hdc, psc);

    if (flags & GGI_MARK_NONEXISTING_GLYPHS)
        *pgi = 0xffff;
    else
        *pgi = 0;

    if (psc->CMAP_format12_Table)
    {
        CMAP_SegmentedCoverage *format = NULL;
        CMAP_SegmentedCoverage_group *group = NULL;

        format = (CMAP_SegmentedCoverage *)psc->CMAP_format12_Table;

        group = bsearch(&utf32c, format->groups, GET_BE_DWORD(format->nGroups),
                        sizeof(CMAP_SegmentedCoverage_group), compare_group);

        if (group)
        {
            DWORD offset = utf32c - GET_BE_DWORD(group->startCharCode);
            *pgi = GET_BE_DWORD(group->startGlyphID) + offset;
            return 0;
        }
    }
    return 0;
}

/**********
 * GDEF
 **********/

static WORD OT_get_glyph_class(const void *table, WORD glyph)
{
    WORD class = 0;
    const OT_ClassDefFormat1 *cf1 = table;

    if (!table) return 0;

    if (GET_BE_WORD(cf1->ClassFormat) == 1)
    {
        if (glyph >= GET_BE_WORD(cf1->StartGlyph))
        {
            int index = glyph - GET_BE_WORD(cf1->StartGlyph);
            if (index < GET_BE_WORD(cf1->GlyphCount))
                class = GET_BE_WORD(cf1->ClassValueArray[index]);
        }
    }
    else if (GET_BE_WORD(cf1->ClassFormat) == 2)
    {
        const OT_ClassDefFormat2 *cf2 = table;
        int i, top;
        top = GET_BE_WORD(cf2->ClassRangeCount);
        for (i = 0; i < top; i++)
        {
            if (glyph >= GET_BE_WORD(cf2->ClassRangeRecord[i].Start) &&
                glyph <= GET_BE_WORD(cf2->ClassRangeRecord[i].End))
            {
                class = GET_BE_WORD(cf2->ClassRangeRecord[i].Class);
                break;
            }
        }
    }
    else
        ERR("Unknown Class Format %i\n",GET_BE_WORD(cf1->ClassFormat));

    return class;
}

void OpenType_GDEF_UpdateGlyphProps(ScriptCache *psc, const WORD *pwGlyphs, const WORD cGlyphs, WORD* pwLogClust, const WORD cChars, SCRIPT_GLYPHPROP *pGlyphProp)
{
    int i;
    void *glyph_class_table = NULL;

    if (psc->GDEF_Table)
    {
        const GDEF_Header *header = psc->GDEF_Table;
        WORD offset = GET_BE_WORD( header->GlyphClassDef );
        if (offset)
            glyph_class_table = (BYTE *)psc->GDEF_Table + offset;
    }

    for (i = 0; i < cGlyphs; i++)
    {
        WORD class;
        int char_count = 0;
        int k;

        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
        if (k >= 0)
        {
            for (; k < cChars && pwLogClust[k] == i; k++)
                char_count++;
        }

        class = OT_get_glyph_class( glyph_class_table, pwGlyphs[i] );

        switch (class)
        {
            case 0:
            case BaseGlyph:
                pGlyphProp[i].sva.fClusterStart = 1;
                pGlyphProp[i].sva.fDiacritic = 0;
                pGlyphProp[i].sva.fZeroWidth = 0;
                break;
            case LigatureGlyph:
                pGlyphProp[i].sva.fClusterStart = 1;
                pGlyphProp[i].sva.fDiacritic = 0;
                pGlyphProp[i].sva.fZeroWidth = 0;
                break;
            case MarkGlyph:
                pGlyphProp[i].sva.fClusterStart = 0;
                pGlyphProp[i].sva.fDiacritic = 1;
                pGlyphProp[i].sva.fZeroWidth = 1;
                break;
            case ComponentGlyph:
                pGlyphProp[i].sva.fClusterStart = 0;
                pGlyphProp[i].sva.fDiacritic = 0;
                pGlyphProp[i].sva.fZeroWidth = 0;
                break;
            default:
                ERR("Unknown glyph class %i\n",class);
                pGlyphProp[i].sva.fClusterStart = 1;
                pGlyphProp[i].sva.fDiacritic = 0;
                pGlyphProp[i].sva.fZeroWidth = 0;
        }

        if (char_count == 0)
            pGlyphProp[i].sva.fClusterStart = 0;
    }
}

/**********
 * GSUB
 **********/
static INT GSUB_apply_lookup(const OT_LookupList* lookup, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count);

static INT GSUB_is_glyph_covered(LPCVOID table , UINT glyph)
{
    const OT_CoverageFormat1* cf1;

    cf1 = table;

    if (GET_BE_WORD(cf1->CoverageFormat) == 1)
    {
        int count = GET_BE_WORD(cf1->GlyphCount);
        int i;
        TRACE("Coverage Format 1, %i glyphs\n",count);
        for (i = 0; i < count; i++)
            if (glyph == GET_BE_WORD(cf1->GlyphArray[i]))
                return i;
        return -1;
    }
    else if (GET_BE_WORD(cf1->CoverageFormat) == 2)
    {
        const OT_CoverageFormat2* cf2;
        int i;
        int count;
        cf2 = (const OT_CoverageFormat2*)cf1;

        count = GET_BE_WORD(cf2->RangeCount);
        TRACE("Coverage Format 2, %i ranges\n",count);
        for (i = 0; i < count; i++)
        {
            if (glyph < GET_BE_WORD(cf2->RangeRecord[i].Start))
                return -1;
            if ((glyph >= GET_BE_WORD(cf2->RangeRecord[i].Start)) &&
                (glyph <= GET_BE_WORD(cf2->RangeRecord[i].End)))
            {
                return (GET_BE_WORD(cf2->RangeRecord[i].StartCoverageIndex) +
                    glyph - GET_BE_WORD(cf2->RangeRecord[i].Start));
            }
        }
        return -1;
    }
    else
        ERR("Unknown CoverageFormat %i\n",GET_BE_WORD(cf1->CoverageFormat));

    return -1;
}

static const BYTE *GSUB_get_subtable(const OT_LookupTable *look, int index)
{
    int offset = GET_BE_WORD(look->SubTable[index]);

    if (GET_BE_WORD(look->LookupType) == 7)
    {
        const GSUB_ExtensionPosFormat1 *ext = (const GSUB_ExtensionPosFormat1 *)((const BYTE *)look + offset);
        if (GET_BE_WORD(ext->SubstFormat) == 1)
        {
            offset += GET_BE_DWORD(ext->ExtensionOffset);
        }
        else
        {
            FIXME("Unhandled Extension Substitution Format %i\n",GET_BE_WORD(ext->SubstFormat));
        }
    }
    return (const BYTE *)look + offset;
}

static INT GSUB_apply_SingleSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
{
    int j;
    TRACE("Single Substitution Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GSUB_SingleSubstFormat1 *ssf1 = (const GSUB_SingleSubstFormat1*)GSUB_get_subtable(look, j);
        if (GET_BE_WORD(ssf1->SubstFormat) == 1)
        {
            int offset = GET_BE_WORD(ssf1->Coverage);
            TRACE("  subtype 1, delta %i\n", GET_BE_WORD(ssf1->DeltaGlyphID));
            if (GSUB_is_glyph_covered((const BYTE*)ssf1+offset, glyphs[glyph_index]) != -1)
            {
                TRACE("  Glyph 0x%x ->",glyphs[glyph_index]);
                glyphs[glyph_index] = glyphs[glyph_index] + GET_BE_WORD(ssf1->DeltaGlyphID);
                TRACE(" 0x%x\n",glyphs[glyph_index]);
                return glyph_index + write_dir;
            }
        }
        else
        {
            const GSUB_SingleSubstFormat2 *ssf2;
            INT index;
            INT offset;

            ssf2 = (const GSUB_SingleSubstFormat2 *)ssf1;
            offset = GET_BE_WORD(ssf1->Coverage);
            TRACE("  subtype 2,  glyph count %i\n", GET_BE_WORD(ssf2->GlyphCount));
            index = GSUB_is_glyph_covered((const BYTE*)ssf2+offset, glyphs[glyph_index]);
            TRACE("  Coverage index %i\n",index);
            if (index != -1)
            {
                if (glyphs[glyph_index] == GET_BE_WORD(ssf2->Substitute[index]))
                    return GSUB_E_NOGLYPH;

                TRACE("    Glyph is 0x%x ->",glyphs[glyph_index]);
                glyphs[glyph_index] = GET_BE_WORD(ssf2->Substitute[index]);
                TRACE("0x%x\n",glyphs[glyph_index]);
                return glyph_index + write_dir;
            }
        }
    }
    return GSUB_E_NOGLYPH;
}

static INT GSUB_apply_MultipleSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
{
    int j;
    TRACE("Multiple Substitution Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        int offset, index;
        const GSUB_MultipleSubstFormat1 *msf1;
        msf1 = (const GSUB_MultipleSubstFormat1*)GSUB_get_subtable(look, j);

        offset = GET_BE_WORD(msf1->Coverage);
        index = GSUB_is_glyph_covered((const BYTE*)msf1+offset, glyphs[glyph_index]);
        if (index != -1)
        {
            const GSUB_Sequence *seq;
            int sub_count;
            int j;
            offset = GET_BE_WORD(msf1->Sequence[index]);
            seq = (const GSUB_Sequence*)((const BYTE*)msf1+offset);
            sub_count = GET_BE_WORD(seq->GlyphCount);
            TRACE("  Glyph 0x%x (+%i)->",glyphs[glyph_index],(sub_count-1));

            for (j = (*glyph_count)+(sub_count-1); j > glyph_index; j--)
                    glyphs[j] =glyphs[j-(sub_count-1)];

            for (j = 0; j < sub_count; j++)
                    if (write_dir < 0)
                        glyphs[glyph_index + (sub_count-1) - j] = GET_BE_WORD(seq->Substitute[j]);
                    else
                        glyphs[glyph_index + j] = GET_BE_WORD(seq->Substitute[j]);

            *glyph_count = *glyph_count + (sub_count - 1);

            if (TRACE_ON(uniscribe))
            {
                for (j = 0; j < sub_count; j++)
                    TRACE(" 0x%x",glyphs[glyph_index+j]);
                TRACE("\n");
            }

            if (write_dir > 0)
                return glyph_index + sub_count;
            else
                return glyph_index - 1;
        }
    }
    return GSUB_E_NOGLYPH;
}

static INT GSUB_apply_AlternateSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
{
    int j;
    TRACE("Alternate Substitution Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        int offset;
        const GSUB_AlternateSubstFormat1 *asf1;
        INT index;

        asf1 = (const GSUB_AlternateSubstFormat1*)GSUB_get_subtable(look, j);
        offset = GET_BE_WORD(asf1->Coverage);

        index = GSUB_is_glyph_covered((const BYTE*)asf1+offset, glyphs[glyph_index]);
        if (index != -1)
        {
            const GSUB_AlternateSet *as;
            offset =  GET_BE_WORD(asf1->AlternateSet[index]);
            as = (const GSUB_AlternateSet*)((const BYTE*)asf1+offset);
            FIXME("%i alternates, picking index 0\n",GET_BE_WORD(as->GlyphCount));
            if (glyphs[glyph_index] == GET_BE_WORD(as->Alternate[0]))
                return GSUB_E_NOGLYPH;

            TRACE("  Glyph 0x%x ->",glyphs[glyph_index]);
            glyphs[glyph_index] = GET_BE_WORD(as->Alternate[0]);
            TRACE(" 0x%x\n",glyphs[glyph_index]);
            return glyph_index + write_dir;
        }
    }
    return GSUB_E_NOGLYPH;
}

static INT GSUB_apply_LigatureSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
{
    int j;

    TRACE("Ligature Substitution Subtable\n");
    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GSUB_LigatureSubstFormat1 *lsf1;
        int offset,index;

        lsf1 = (const GSUB_LigatureSubstFormat1*)GSUB_get_subtable(look, j);
        offset = GET_BE_WORD(lsf1->Coverage);
        index = GSUB_is_glyph_covered((const BYTE*)lsf1+offset, glyphs[glyph_index]);
        TRACE("  Coverage index %i\n",index);
        if (index != -1)
        {
            const GSUB_LigatureSet *ls;
            int k, count;

            offset = GET_BE_WORD(lsf1->LigatureSet[index]);
            ls = (const GSUB_LigatureSet*)((const BYTE*)lsf1+offset);
            count = GET_BE_WORD(ls->LigatureCount);
            TRACE("  LigatureSet has %i members\n",count);
            for (k = 0; k < count; k++)
            {
                const GSUB_Ligature *lig;
                int CompCount,l,CompIndex;

                offset = GET_BE_WORD(ls->Ligature[k]);
                lig = (const GSUB_Ligature*)((const BYTE*)ls+offset);
                CompCount = GET_BE_WORD(lig->CompCount) - 1;
                CompIndex = glyph_index+write_dir;
                for (l = 0; l < CompCount && CompIndex >= 0 && CompIndex < *glyph_count; l++)
                {
                    int CompGlyph;
                    CompGlyph = GET_BE_WORD(lig->Component[l]);
                    if (CompGlyph != glyphs[CompIndex])
                        break;
                    CompIndex += write_dir;
                }
                if (l == CompCount)
                {
                    int replaceIdx = glyph_index;
                    if (write_dir < 0)
                        replaceIdx = glyph_index - CompCount;

                    TRACE("    Glyph is 0x%x (+%i) ->",glyphs[glyph_index],CompCount);
                    glyphs[replaceIdx] = GET_BE_WORD(lig->LigGlyph);
                    TRACE("0x%x\n",glyphs[replaceIdx]);
                    if (CompCount > 0)
                    {
                        int j;
                        for (j = replaceIdx + 1; j < *glyph_count; j++)
                            glyphs[j] =glyphs[j+CompCount];
                        *glyph_count = *glyph_count - CompCount;
                    }
                    return replaceIdx + write_dir;
                }
            }
        }
    }
    return GSUB_E_NOGLYPH;
}

static INT GSUB_apply_ContextSubst(const OT_LookupList* lookup, const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
{
    int j;
    TRACE("Context Substitution Subtable\n");
    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GSUB_ContextSubstFormat1 *csf1;

        csf1 = (const GSUB_ContextSubstFormat1*)GSUB_get_subtable(look, j);
        if (GET_BE_WORD(csf1->SubstFormat) == 1)
        {
            int offset, index;
            TRACE("Context Substitution Subtable: Class 1\n");
            offset = GET_BE_WORD(csf1->Coverage);
            index = GSUB_is_glyph_covered((const BYTE*)csf1+offset, glyphs[glyph_index]);
            TRACE("  Coverage index %i\n",index);
            if (index != -1)
            {
                int k, count;
                const GSUB_SubRuleSet *srs;
                offset = GET_BE_WORD(csf1->SubRuleSet[index]);
                srs = (const GSUB_SubRuleSet*)((const BYTE*)csf1+offset);
                count = GET_BE_WORD(srs->SubRuleCount);
                TRACE("  SubRuleSet has %i members\n",count);
                for (k = 0; k < count; k++)
                {
                    const GSUB_SubRule_1 *sr;
                    const GSUB_SubRule_2 *sr_2;
                    int g_count, l;
                    int newIndex = glyph_index;

                    offset = GET_BE_WORD(srs->SubRule[k]);
                    sr = (const GSUB_SubRule_1*)((const BYTE*)srs+offset);
                    g_count = GET_BE_WORD(sr->GlyphCount);
                    TRACE("   SubRule has %i glyphs\n",g_count);
                    for (l = 0; l < g_count-1; l++)
                        if (glyphs[glyph_index + (write_dir * (l+1))] != GET_BE_WORD(sr->Input[l])) break;

                    if (l < g_count-1)
                    {
                        TRACE("   Rule does not match\n");
                        continue;
                    }

                    TRACE("   Rule matches\n");
                    sr_2 = (const GSUB_SubRule_2*)((const BYTE*)sr+
                        FIELD_OFFSET(GSUB_SubRule_1, Input[g_count-1]));

                    for (l = 0; l < GET_BE_WORD(sr->SubstCount); l++)
                    {
                        int lookupIndex = GET_BE_WORD(sr_2->SubstLookupRecord[l].LookupListIndex);
                        int SequenceIndex = GET_BE_WORD(sr_2->SubstLookupRecord[l].SequenceIndex) * write_dir;

                        TRACE("   SUBST: %i -> %i %i\n",l, SequenceIndex, lookupIndex);
                        newIndex = GSUB_apply_lookup(lookup, lookupIndex, glyphs, glyph_index + SequenceIndex, write_dir, glyph_count);
                        if (newIndex == GSUB_E_NOGLYPH)
                        {
                            ERR("   Chain failed to generate a glyph\n");
                            continue;
                        }
                    }
                    return newIndex;
                }
            }
        }
        else if (GET_BE_WORD(csf1->SubstFormat) == 2)
        {
            const GSUB_ContextSubstFormat2 *csf2;
            const void *glyph_class_table;
            int offset, index;

            csf2 = (const GSUB_ContextSubstFormat2*)csf1;
            TRACE("Context Substitution Subtable: Class 2\n");
            offset = GET_BE_WORD(csf2->Coverage);
            index = GSUB_is_glyph_covered((const BYTE*)csf2+offset, glyphs[glyph_index]);
            TRACE("  Coverage index %i\n",index);
            if (index != -1)
            {
                int k, count, class;
                const GSUB_SubClassSet *scs;

                offset = GET_BE_WORD(csf2->ClassDef);
                glyph_class_table = (const BYTE *)csf2 + offset;

                class = OT_get_glyph_class(glyph_class_table,glyphs[glyph_index]);

                offset = GET_BE_WORD(csf2->SubClassSet[class]);
                if (offset == 0)
                {
                    TRACE("  No class rule table for class %i\n",class);
                    continue;
                }
                scs = (const GSUB_SubClassSet*)((const BYTE*)csf2+offset);
                count = GET_BE_WORD(scs->SubClassRuleCnt);
                TRACE("  SubClassSet has %i members\n",count);
                for (k = 0; k < count; k++)
                {
                    const GSUB_SubClassRule_1 *sr;
                    const GSUB_SubClassRule_2 *sr_2;
                    int g_count, l;
                    int newIndex = glyph_index;

                    offset = GET_BE_WORD(scs->SubClassRule[k]);
                    sr = (const GSUB_SubClassRule_1*)((const BYTE*)scs+offset);
                    g_count = GET_BE_WORD(sr->GlyphCount);
                    TRACE("   SubClassRule has %i glyphs classes\n",g_count);
                    for (l = 0; l < g_count-1; l++)
                    {
                        int g_class = OT_get_glyph_class(glyph_class_table, glyphs[glyph_index + (write_dir * (l+1))]);
                        if (g_class != GET_BE_WORD(sr->Class[l])) break;
                    }

                    if (l < g_count-1)
                    {
                        TRACE("   Rule does not match\n");
                        continue;
                    }

                    TRACE("   Rule matches\n");
                    sr_2 = (const GSUB_SubClassRule_2*)((const BYTE*)sr+
                        FIELD_OFFSET(GSUB_SubClassRule_1, Class[g_count-1]));

                    for (l = 0; l < GET_BE_WORD(sr->SubstCount); l++)
                    {
                        int lookupIndex = GET_BE_WORD(sr_2->SubstLookupRecord[l].LookupListIndex);
                        int SequenceIndex = GET_BE_WORD(sr_2->SubstLookupRecord[l].SequenceIndex) * write_dir;

                        TRACE("   SUBST: %i -> %i %i\n",l, SequenceIndex, lookupIndex);
                        newIndex = GSUB_apply_lookup(lookup, lookupIndex, glyphs, glyph_index + SequenceIndex, write_dir, glyph_count);
                        if (newIndex == GSUB_E_NOGLYPH)
                        {
                            ERR("   Chain failed to generate a glyph\n");
                            continue;
                        }
                    }
                    return newIndex;
                }
            }
        }
        else
            FIXME("Unhandled Context Substitution Format %i\n", GET_BE_WORD(csf1->SubstFormat));
    }
    return GSUB_E_NOGLYPH;
}

static INT GSUB_apply_ChainContextSubst(const OT_LookupList* lookup, const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
{
    int j;

    TRACE("Chaining Contextual Substitution Subtable\n");
    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GSUB_ChainContextSubstFormat1 *ccsf1;
        int offset;
        int dirLookahead = write_dir;
        int dirBacktrack = -1 * write_dir;

        ccsf1 = (const GSUB_ChainContextSubstFormat1*)GSUB_get_subtable(look, j);
        if (GET_BE_WORD(ccsf1->SubstFormat) == 1)
        {
            static int once;
            if (!once++)
                FIXME("  TODO: subtype 1 (Simple context glyph substitution)\n");
            continue;
        }
        else if (GET_BE_WORD(ccsf1->SubstFormat) == 2)
        {
            int newIndex = glyph_index;
            WORD offset, count;
            const void *backtrack_class_table;
            const void *input_class_table;
            const void *lookahead_class_table;
            int i;
            WORD class;

            const GSUB_ChainContextSubstFormat2 *ccsf2 = (const GSUB_ChainContextSubstFormat2*)ccsf1;
            const GSUB_ChainSubClassSet *csc;

            TRACE("  subtype 2 (Class-based Chaining Context Glyph Substitution)\n");

            offset = GET_BE_WORD(ccsf2->Coverage);

            if (GSUB_is_glyph_covered((const BYTE*)ccsf2+offset, glyphs[glyph_index]) == -1)
            {
                TRACE("Glyph not covered\n");
                continue;
            }
            offset = GET_BE_WORD(ccsf2->BacktrackClassDef);
            backtrack_class_table = (const BYTE*)ccsf2+offset;
            offset = GET_BE_WORD(ccsf2->InputClassDef);
            input_class_table = (const BYTE*)ccsf2+offset;
            offset = GET_BE_WORD(ccsf2->LookaheadClassDef);
            lookahead_class_table = (const BYTE*)ccsf2+offset;
            count =  GET_BE_WORD(ccsf2->ChainSubClassSetCnt);

            class = OT_get_glyph_class(input_class_table, glyphs[glyph_index]);
            offset = GET_BE_WORD(ccsf2->ChainSubClassSet[class]);

            if (offset == 0)
            {
                TRACE("No rules for class\n");
                continue;
            }

            csc = (const GSUB_ChainSubClassSet*)((BYTE*)ccsf2+offset);
            count = GET_BE_WORD(csc->ChainSubClassRuleCnt);

            TRACE("%i rules to check\n",count);

            for (i = 0; i < count; i++)
            {
                int k;
                int indexGlyphs;
                const GSUB_ChainSubClassRule_1 *cscr_1;
                const GSUB_ChainSubClassRule_2 *cscr_2;
                const GSUB_ChainSubClassRule_3 *cscr_3;
                const GSUB_ChainSubClassRule_4 *cscr_4;

                offset = GET_BE_WORD(csc->ChainSubClassRule[i]);
                cscr_1 = (const GSUB_ChainSubClassRule_1*)((BYTE*)csc+offset);

                for (k = 0; k < GET_BE_WORD(cscr_1->BacktrackGlyphCount); k++)
                {
                    WORD target_class = GET_BE_WORD(cscr_1->Backtrack[k]);
                    WORD glyph_class = OT_get_glyph_class(backtrack_class_table, glyphs[glyph_index + (dirBacktrack * (k+1))]);
                    if (target_class != glyph_class)
                        break;
                }
                if (k != GET_BE_WORD(cscr_1->BacktrackGlyphCount))
                    continue;
                TRACE("Matched Backtrack\n");

                cscr_2 = (const GSUB_ChainSubClassRule_2*)((BYTE *)cscr_1 +
                    FIELD_OFFSET(GSUB_ChainSubClassRule_1, Backtrack[GET_BE_WORD(cscr_1->BacktrackGlyphCount)]));

                indexGlyphs = GET_BE_WORD(cscr_2->InputGlyphCount);
                for (k = 0; k < indexGlyphs - 1; k++)
                {
                    WORD target_class = GET_BE_WORD(cscr_2->Input[k]);
                    WORD glyph_class = OT_get_glyph_class(input_class_table, glyphs[glyph_index + (write_dir * (k+1))]);
                    if (target_class != glyph_class)
                        break;
                }
                if (k != indexGlyphs-1)
                    continue;
                TRACE("Matched IndexGlyphs\n");

                cscr_3 = (const GSUB_ChainSubClassRule_3*)((BYTE *)cscr_2 +
                        FIELD_OFFSET(GSUB_ChainSubClassRule_2, Input[GET_BE_WORD(cscr_2->InputGlyphCount)-1]));

                for (k = 0; k < GET_BE_WORD(cscr_3->LookaheadGlyphCount); k++)
                {
                    WORD target_class = GET_BE_WORD(cscr_3->LookAhead[k]);
                    WORD glyph_class = OT_get_glyph_class(lookahead_class_table, glyphs[glyph_index + (dirLookahead * (indexGlyphs+k))]);
                    if (target_class != glyph_class)
                        break;
                }
                if (k != GET_BE_WORD(cscr_3->LookaheadGlyphCount))
                    continue;
                TRACE("Matched LookAhead\n");

                cscr_4 = (const GSUB_ChainSubClassRule_4*)((BYTE *)cscr_3 +
                        FIELD_OFFSET(GSUB_ChainSubClassRule_3, LookAhead[GET_BE_WORD(cscr_3->LookaheadGlyphCount)]));

                if (GET_BE_WORD(cscr_4->SubstCount))
                {
                    for (k = 0; k < GET_BE_WORD(cscr_4->SubstCount); k++)
                    {
                        int lookupIndex = GET_BE_WORD(cscr_4->SubstLookupRecord[k].LookupListIndex);
                        int SequenceIndex = GET_BE_WORD(cscr_4->SubstLookupRecord[k].SequenceIndex) * write_dir;

                        TRACE("SUBST: %i -> %i %i\n",k, SequenceIndex, lookupIndex);
                        newIndex = GSUB_apply_lookup(lookup, lookupIndex, glyphs, glyph_index + SequenceIndex, write_dir, glyph_count);
                        if (newIndex == GSUB_E_NOGLYPH)
                        {
                            ERR("Chain failed to generate a glyph\n");
                            continue;
                        }
                    }
                    return newIndex;
                }
                else return GSUB_E_NOGLYPH;
            }
        }
        else if (GET_BE_WORD(ccsf1->SubstFormat) == 3)
        {
            int k;
            int indexGlyphs;
            const GSUB_ChainContextSubstFormat3_1 *ccsf3_1;
            const GSUB_ChainContextSubstFormat3_2 *ccsf3_2;
            const GSUB_ChainContextSubstFormat3_3 *ccsf3_3;
            const GSUB_ChainContextSubstFormat3_4 *ccsf3_4;
            int newIndex = glyph_index;

            ccsf3_1 = (const GSUB_ChainContextSubstFormat3_1 *)ccsf1;

            TRACE("  subtype 3 (Coverage-based Chaining Context Glyph Substitution)\n");

            for (k = 0; k < GET_BE_WORD(ccsf3_1->BacktrackGlyphCount); k++)
            {
                offset = GET_BE_WORD(ccsf3_1->Coverage[k]);
                if (GSUB_is_glyph_covered((const BYTE*)ccsf3_1+offset, glyphs[glyph_index + (dirBacktrack * (k+1))]) == -1)
                    break;
            }
            if (k != GET_BE_WORD(ccsf3_1->BacktrackGlyphCount))
                continue;
            TRACE("Matched Backtrack\n");

            ccsf3_2 = (const GSUB_ChainContextSubstFormat3_2 *)((BYTE *)ccsf1 +
                    FIELD_OFFSET(GSUB_ChainContextSubstFormat3_1, Coverage[GET_BE_WORD(ccsf3_1->BacktrackGlyphCount)]));

            indexGlyphs = GET_BE_WORD(ccsf3_2->InputGlyphCount);
            for (k = 0; k < indexGlyphs; k++)
            {
                offset = GET_BE_WORD(ccsf3_2->Coverage[k]);
                if (GSUB_is_glyph_covered((const BYTE*)ccsf3_1+offset, glyphs[glyph_index + (write_dir * k)]) == -1)
                    break;
            }
            if (k != indexGlyphs)
                continue;
            TRACE("Matched IndexGlyphs\n");

            ccsf3_3 = (const GSUB_ChainContextSubstFormat3_3 *)((BYTE *)ccsf3_2 +
                    FIELD_OFFSET(GSUB_ChainContextSubstFormat3_2, Coverage[GET_BE_WORD(ccsf3_2->InputGlyphCount)]));

            for (k = 0; k < GET_BE_WORD(ccsf3_3->LookaheadGlyphCount); k++)
            {
                offset = GET_BE_WORD(ccsf3_3->Coverage[k]);
                if (GSUB_is_glyph_covered((const BYTE*)ccsf3_1+offset, glyphs[glyph_index + (dirLookahead * (indexGlyphs + k))]) == -1)
                    break;
            }
            if (k != GET_BE_WORD(ccsf3_3->LookaheadGlyphCount))
                continue;
            TRACE("Matched LookAhead\n");

            ccsf3_4 = (const GSUB_ChainContextSubstFormat3_4 *)((BYTE *)ccsf3_3 +
                    FIELD_OFFSET(GSUB_ChainContextSubstFormat3_3, Coverage[GET_BE_WORD(ccsf3_3->LookaheadGlyphCount)]));

            if (GET_BE_WORD(ccsf3_4->SubstCount))
            {
                for (k = 0; k < GET_BE_WORD(ccsf3_4->SubstCount); k++)
                {
                    int lookupIndex = GET_BE_WORD(ccsf3_4->SubstLookupRecord[k].LookupListIndex);
                    int SequenceIndex = GET_BE_WORD(ccsf3_4->SubstLookupRecord[k].SequenceIndex) * write_dir;

                    TRACE("SUBST: %i -> %i %i\n",k, SequenceIndex, lookupIndex);
                    newIndex = GSUB_apply_lookup(lookup, lookupIndex, glyphs, glyph_index + SequenceIndex, write_dir, glyph_count);
                    if (newIndex == GSUB_E_NOGLYPH)
                    {
                        ERR("Chain failed to generate a glyph\n");
                        continue;
                    }
                }
                return newIndex;
            }
            else return GSUB_E_NOGLYPH;
        }
    }
    return GSUB_E_NOGLYPH;
}

static INT GSUB_apply_lookup(const OT_LookupList* lookup, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
{
    int offset;
    int type;
    const OT_LookupTable *look;

    offset = GET_BE_WORD(lookup->Lookup[lookup_index]);
    look = (const OT_LookupTable*)((const BYTE*)lookup + offset);
    type = GET_BE_WORD(look->LookupType);
    TRACE("type %i, flag %x, subtables %i\n",type,GET_BE_WORD(look->LookupFlag),GET_BE_WORD(look->SubTableCount));
    if (type == 7)
    {
        if (GET_BE_WORD(look->SubTableCount))
        {
            const GSUB_ExtensionPosFormat1 *ext = (const GSUB_ExtensionPosFormat1 *)((const BYTE *)look + GET_BE_WORD(look->SubTable[0]));
            if (GET_BE_WORD(ext->SubstFormat) == 1)
            {
                type = GET_BE_WORD(ext->ExtensionLookupType);
                TRACE("extension type %i\n",type);
            }
            else
            {
                FIXME("Unhandled Extension Substitution Format %i\n",GET_BE_WORD(ext->SubstFormat));
            }
        }
        else
        {
            WARN("lookup type is Extension Substitution but no extension subtable exists\n");
        }
    }
    switch(type)
    {
        case 1:
            return GSUB_apply_SingleSubst(look, glyphs, glyph_index, write_dir, glyph_count);
        case 2:
            return GSUB_apply_MultipleSubst(look, glyphs, glyph_index, write_dir, glyph_count);
        case 3:
            return GSUB_apply_AlternateSubst(look, glyphs, glyph_index, write_dir, glyph_count);
        case 4:
            return GSUB_apply_LigatureSubst(look, glyphs, glyph_index, write_dir, glyph_count);
        case 5:
            return GSUB_apply_ContextSubst(lookup, look, glyphs, glyph_index, write_dir, glyph_count);
        case 6:
            return GSUB_apply_ChainContextSubst(lookup, look, glyphs, glyph_index, write_dir, glyph_count);
        case 7:
            FIXME("Extension Substitution types not valid here\n");
            break;
        default:
            FIXME("We do not handle SubType %i\n",type);
    }
    return GSUB_E_NOGLYPH;
}

INT OpenType_apply_GSUB_lookup(LPCVOID table, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
{
    const GSUB_Header *header = (const GSUB_Header *)table;
    const OT_LookupList *lookup = (const OT_LookupList*)((const BYTE*)header + GET_BE_WORD(header->LookupList));

    return GSUB_apply_lookup(lookup, lookup_index, glyphs, glyph_index, write_dir, glyph_count);
}

/**********
 * GPOS
 **********/
static INT GPOS_apply_lookup(ScriptCache *psc, LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, const SCRIPT_ANALYSIS *analysis, INT* piAdvance,
                             const OT_LookupList* lookup, INT lookup_index, const WORD *glyphs, INT glyph_index, INT glyph_count, GOFFSET *pGoffset);

static INT GPOS_get_device_table_value(const OT_DeviceTable *DeviceTable, WORD ppem)
{
    static const WORD mask[3] = {3,0xf,0xff};
    if (DeviceTable && ppem >= GET_BE_WORD(DeviceTable->StartSize) && ppem  <= GET_BE_WORD(DeviceTable->EndSize))
    {
        int format = GET_BE_WORD(DeviceTable->DeltaFormat);
        int index = ppem - GET_BE_WORD(DeviceTable->StartSize);
        int value;
        TRACE("device table, format %i, index %i\n",format, index);
        index = index << format;
        value = (DeviceTable->DeltaValue[index/sizeof(WORD)] << (index%sizeof(WORD)))&mask[format-1];
        TRACE("offset %i, value %i\n",index, value);
        if (value > mask[format-1]/2)
            value = -1 * ((mask[format-1]+1) - value);
        return value;
    }
    return 0;
}

static VOID GPOS_get_anchor_values(LPCVOID table, LPPOINT pt, WORD ppem)
{
    const GPOS_AnchorFormat1* anchor1 = (const GPOS_AnchorFormat1*)table;

    switch (GET_BE_WORD(anchor1->AnchorFormat))
    {
        case 1:
        {
            TRACE("Anchor Format 1\n");
            pt->x = (short)GET_BE_WORD(anchor1->XCoordinate);
            pt->y = (short)GET_BE_WORD(anchor1->YCoordinate);
            break;
        }
        case 2:
        {
            const GPOS_AnchorFormat2* anchor2 = (const GPOS_AnchorFormat2*)table;
            TRACE("Anchor Format 2\n");
            pt->x = (short)GET_BE_WORD(anchor2->XCoordinate);
            pt->y = (short)GET_BE_WORD(anchor2->YCoordinate);
            break;
        }
        case 3:
        {
            int offset;
            const GPOS_AnchorFormat3* anchor3 = (const GPOS_AnchorFormat3*)table;
            TRACE("Anchor Format 3\n");
            pt->x = (short)GET_BE_WORD(anchor3->XCoordinate);
            pt->y = (short)GET_BE_WORD(anchor3->YCoordinate);
            offset = GET_BE_WORD(anchor3->XDeviceTable);
            TRACE("ppem %i\n",ppem);
            if (offset)
            {
                const OT_DeviceTable* DeviceTableX = NULL;
                DeviceTableX = (const OT_DeviceTable*)((const BYTE*)anchor3 + offset);
                pt->x += GPOS_get_device_table_value(DeviceTableX, ppem);
            }
            offset = GET_BE_WORD(anchor3->YDeviceTable);
            if (offset)
            {
                const OT_DeviceTable* DeviceTableY = NULL;
                DeviceTableY = (const OT_DeviceTable*)((const BYTE*)anchor3 + offset);
                pt->y += GPOS_get_device_table_value(DeviceTableY, ppem);
            }
            break;
        }
        default:
            ERR("Unknown Anchor Format %i\n",GET_BE_WORD(anchor1->AnchorFormat));
            pt->x = 0;
            pt->y = 0;
    }
}

static void GPOS_convert_design_units_to_device(LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, int desX, int desY, double *devX, double *devY)
{
    int emHeight = lpotm->otmTextMetrics.tmAscent + lpotm->otmTextMetrics.tmDescent - lpotm->otmTextMetrics.tmInternalLeading;

    TRACE("emHeight %i lfWidth %i\n",emHeight, lplogfont->lfWidth);
    *devX = (desX * emHeight) / (double)lpotm->otmEMSquare;
    *devY = (desY * emHeight) / (double)lpotm->otmEMSquare;
    if (lplogfont->lfWidth)
        FIXME("Font with lfWidth set not handled properly\n");
}

static INT GPOS_get_value_record(WORD ValueFormat, const WORD data[], GPOS_ValueRecord *record)
{
    INT offset = 0;
    if (ValueFormat & 0x0001) { if (data) record->XPlacement = GET_BE_WORD(data[offset]); offset++; }
    if (ValueFormat & 0x0002) { if (data) record->YPlacement = GET_BE_WORD(data[offset]); offset++; }
    if (ValueFormat & 0x0004) { if (data) record->XAdvance   = GET_BE_WORD(data[offset]); offset++; }
    if (ValueFormat & 0x0008) { if (data) record->YAdvance   = GET_BE_WORD(data[offset]); offset++; }
    if (ValueFormat & 0x0010) { if (data) record->XPlaDevice = GET_BE_WORD(data[offset]); offset++; }
    if (ValueFormat & 0x0020) { if (data) record->YPlaDevice = GET_BE_WORD(data[offset]); offset++; }
    if (ValueFormat & 0x0040) { if (data) record->XAdvDevice = GET_BE_WORD(data[offset]); offset++; }
    if (ValueFormat & 0x0080) { if (data) record->YAdvDevice = GET_BE_WORD(data[offset]); offset++; }
    return offset;
}

static VOID GPOS_get_value_record_offsets(const BYTE* head, GPOS_ValueRecord *ValueRecord,  WORD ValueFormat, INT ppem, LPPOINT ptPlacement, LPPOINT ptAdvance)
{
    if (ValueFormat & 0x0001) ptPlacement->x += (short)ValueRecord->XPlacement;
    if (ValueFormat & 0x0002) ptPlacement->y += (short)ValueRecord->YPlacement;
    if (ValueFormat & 0x0004) ptAdvance->x += (short)ValueRecord->XAdvance;
    if (ValueFormat & 0x0008) ptAdvance->y += (short)ValueRecord->YAdvance;
    if (ValueFormat & 0x0010) ptPlacement->x += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->XPlaDevice), ppem);
    if (ValueFormat & 0x0020) ptPlacement->y += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->YPlaDevice), ppem);
    if (ValueFormat & 0x0040) ptAdvance->x += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->XAdvDevice), ppem);
    if (ValueFormat & 0x0080) ptAdvance->y += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->YAdvDevice), ppem);
    if (ValueFormat & 0xFF00) FIXME("Unhandled Value Format %x\n",ValueFormat&0xFF00);
}

static const BYTE *GPOS_get_subtable(const OT_LookupTable *look, int index)
{
    int offset = GET_BE_WORD(look->SubTable[index]);

    if (GET_BE_WORD(look->LookupType) == 9)
    {
        const GPOS_ExtensionPosFormat1 *ext = (const GPOS_ExtensionPosFormat1 *)((const BYTE *)look + offset);
        if (GET_BE_WORD(ext->PosFormat) == 1)
        {
            offset += GET_BE_DWORD(ext->ExtensionOffset);
        }
        else
        {
            FIXME("Unhandled Extension Positioning Format %i\n",GET_BE_WORD(ext->PosFormat));
        }
    }
    return (const BYTE *)look + offset;
}

static VOID GPOS_apply_SingleAdjustment(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, INT glyph_index,
                                        INT glyph_count, INT ppem, LPPOINT ptAdjust, LPPOINT ptAdvance)
{
    int j;

    TRACE("Single Adjustment Positioning Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GPOS_SinglePosFormat1 *spf1 = (const GPOS_SinglePosFormat1*)GPOS_get_subtable(look, j);
        WORD offset;
        if (GET_BE_WORD(spf1->PosFormat) == 1)
        {
            offset = GET_BE_WORD(spf1->Coverage);
            if (GSUB_is_glyph_covered((const BYTE*)spf1+offset, glyphs[glyph_index]) != -1)
            {
                GPOS_ValueRecord ValueRecord = {0,0,0,0,0,0,0,0};
                WORD ValueFormat = GET_BE_WORD(spf1->ValueFormat);
                GPOS_get_value_record(ValueFormat, spf1->Value, &ValueRecord);
                GPOS_get_value_record_offsets((const BYTE*)spf1, &ValueRecord,  ValueFormat, ppem, ptAdjust, ptAdvance);
                TRACE("Glyph Adjusted by %i,%i\n",ValueRecord.XPlacement,ValueRecord.YPlacement);
            }
        }
        else if (GET_BE_WORD(spf1->PosFormat) == 2)
        {
            int index;
            const GPOS_SinglePosFormat2 *spf2;
            spf2 = (const GPOS_SinglePosFormat2*)spf1;
            offset = GET_BE_WORD(spf2->Coverage);
            index  = GSUB_is_glyph_covered((const BYTE*)spf2+offset, glyphs[glyph_index]);
            if (index != -1)
            {
                int size;
                GPOS_ValueRecord ValueRecord = {0,0,0,0,0,0,0,0};
                WORD ValueFormat = GET_BE_WORD(spf2->ValueFormat);
                size = GPOS_get_value_record(ValueFormat, spf2->Value, &ValueRecord);
                if (index > 0)
                {
                    offset = size * index;
                    GPOS_get_value_record(ValueFormat, &spf2->Value[offset], &ValueRecord);
                }
                GPOS_get_value_record_offsets((const BYTE*)spf2, &ValueRecord,  ValueFormat, ppem, ptAdjust, ptAdvance);
                TRACE("Glyph Adjusted by %i,%i\n",ValueRecord.XPlacement,ValueRecord.YPlacement);
            }
        }
        else
            FIXME("Single Adjustment Positioning: Format %i Unhandled\n",GET_BE_WORD(spf1->PosFormat));
    }
}

static void apply_pair_value( const void *pos_table, WORD val_fmt1, WORD val_fmt2, const WORD *pair,
                              INT ppem, POINT *adjust, POINT *advance )
{
    GPOS_ValueRecord val_rec1 = {0,0,0,0,0,0,0,0};
    GPOS_ValueRecord val_rec2 = {0,0,0,0,0,0,0,0};
    INT size;

    size = GPOS_get_value_record( val_fmt1, pair, &val_rec1 );
    GPOS_get_value_record( val_fmt2, pair + size, &val_rec2 );

    if (val_fmt1)
    {
        GPOS_get_value_record_offsets( pos_table, &val_rec1, val_fmt1, ppem, adjust, advance );
        TRACE( "Glyph 1 resulting cumulative offset is %s design units\n", wine_dbgstr_point(&adjust[0]) );
        TRACE( "Glyph 1 resulting cumulative advance is %s design units\n", wine_dbgstr_point(&advance[0]) );
    }
    if (val_fmt2)
    {
        GPOS_get_value_record_offsets( pos_table, &val_rec2, val_fmt2, ppem, adjust + 1, advance + 1 );
        TRACE( "Glyph 2 resulting cumulative offset is %s design units\n", wine_dbgstr_point(&adjust[1]) );
        TRACE( "Glyph 2 resulting cumulative advance is %s design units\n", wine_dbgstr_point(&advance[1]) );
    }
}

static INT GPOS_apply_PairAdjustment(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, INT glyph_index,
                                     INT glyph_count, INT ppem, LPPOINT ptAdjust, LPPOINT ptAdvance)
{
    int j;
    int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;

    if (glyph_index + write_dir < 0 || glyph_index + write_dir >= glyph_count) return glyph_index + 1;

    TRACE("Pair Adjustment Positioning Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GPOS_PairPosFormat1 *ppf1 = (const GPOS_PairPosFormat1*)GPOS_get_subtable(look, j);
        WORD offset;
        if (GET_BE_WORD(ppf1->PosFormat) == 1)
        {
            int index;
            WORD ValueFormat1 = GET_BE_WORD(ppf1->ValueFormat1);
            WORD ValueFormat2 = GET_BE_WORD(ppf1->ValueFormat2);
            INT val_fmt1_size = GPOS_get_value_record( ValueFormat1, NULL, NULL );
            INT val_fmt2_size = GPOS_get_value_record( ValueFormat2, NULL, NULL );
            offset = GET_BE_WORD(ppf1->Coverage);
            index = GSUB_is_glyph_covered((const BYTE*)ppf1+offset, glyphs[glyph_index]);
            if (index != -1 && index < GET_BE_WORD(ppf1->PairSetCount))
            {
                int k;
                int pair_count;
                const GPOS_PairSet *ps;
                const GPOS_PairValueRecord *pair_val_rec;
                offset = GET_BE_WORD(ppf1->PairSetOffset[index]);
                ps = (const GPOS_PairSet*)((const BYTE*)ppf1+offset);
                pair_count = GET_BE_WORD(ps->PairValueCount);
                pair_val_rec = ps->PairValueRecord;
                for (k = 0; k < pair_count; k++)
                {
                    WORD second_glyph = GET_BE_WORD(pair_val_rec->SecondGlyph);
                    if (glyphs[glyph_index+write_dir] == second_glyph)
                    {
                        int next = 1;
                        TRACE("Format 1: Found Pair %x,%x\n",glyphs[glyph_index],glyphs[glyph_index+write_dir]);
                        apply_pair_value( ppf1, ValueFormat1, ValueFormat2, pair_val_rec->Value1, ppem, ptAdjust, ptAdvance );
                        if (ValueFormat2) next++;
                        return glyph_index + next;
                    }
                    pair_val_rec = (const GPOS_PairValueRecord *)(pair_val_rec->Value1 + val_fmt1_size + val_fmt2_size);
                }
            }
        }
        else if (GET_BE_WORD(ppf1->PosFormat) == 2)
        {
            const GPOS_PairPosFormat2 *ppf2 = (const GPOS_PairPosFormat2*)ppf1;
            int index;
            WORD ValueFormat1 = GET_BE_WORD( ppf2->ValueFormat1 );
            WORD ValueFormat2 = GET_BE_WORD( ppf2->ValueFormat2 );
            INT val_fmt1_size = GPOS_get_value_record( ValueFormat1, NULL, NULL );
            INT val_fmt2_size = GPOS_get_value_record( ValueFormat2, NULL, NULL );
            WORD class1_count = GET_BE_WORD( ppf2->Class1Count );
            WORD class2_count = GET_BE_WORD( ppf2->Class2Count );

            offset = GET_BE_WORD( ppf2->Coverage );
            index = GSUB_is_glyph_covered( (const BYTE*)ppf2 + offset, glyphs[glyph_index] );
            if (index != -1)
            {
                WORD class1, class2;
                class1 = OT_get_glyph_class( (const BYTE *)ppf2 + GET_BE_WORD(ppf2->ClassDef1), glyphs[glyph_index] );
                class2 = OT_get_glyph_class( (const BYTE *)ppf2 + GET_BE_WORD(ppf2->ClassDef2), glyphs[glyph_index + write_dir] );
                if (class1 < class1_count && class2 < class2_count)
                {
                    const WORD *pair_val = ppf2->Class1Record + (class1 * class2_count + class2) * (val_fmt1_size + val_fmt2_size);
                    int next = 1;

                    TRACE( "Format 2: Found Pair %x,%x\n", glyphs[glyph_index], glyphs[glyph_index + write_dir] );

                    apply_pair_value( ppf2, ValueFormat1, ValueFormat2, pair_val, ppem, ptAdjust, ptAdvance );
                    if (ValueFormat2) next++;
                    return glyph_index + next;
                }
            }
        }
        else
            FIXME("Pair Adjustment Positioning: Format %i Unhandled\n",GET_BE_WORD(ppf1->PosFormat));
    }
    return glyph_index+1;
}

static VOID GPOS_apply_CursiveAttachment(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, INT glyph_index,
                                     INT glyph_count, INT ppem, LPPOINT pt)
{
    int j;
    int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;

    if (glyph_index + write_dir < 0 || glyph_index + write_dir >= glyph_count) return;

    TRACE("Cursive Attachment Positioning Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GPOS_CursivePosFormat1 *cpf1 = (const GPOS_CursivePosFormat1 *)GPOS_get_subtable(look, j);
        if (GET_BE_WORD(cpf1->PosFormat) == 1)
        {
            int index_exit, index_entry;
            WORD offset = GET_BE_WORD( cpf1->Coverage );
            index_exit = GSUB_is_glyph_covered((const BYTE*)cpf1+offset, glyphs[glyph_index]);
            if (index_exit != -1 && cpf1->EntryExitRecord[index_exit].ExitAnchor!= 0)
            {
                index_entry = GSUB_is_glyph_covered((const BYTE*)cpf1+offset, glyphs[glyph_index+write_dir]);
                if (index_entry != -1 && cpf1->EntryExitRecord[index_entry].EntryAnchor != 0)
                {
                    POINT exit_pt, entry_pt;
                    offset = GET_BE_WORD(cpf1->EntryExitRecord[index_exit].ExitAnchor);
                    GPOS_get_anchor_values((const BYTE*)cpf1 + offset, &exit_pt, ppem);
                    offset = GET_BE_WORD(cpf1->EntryExitRecord[index_entry].EntryAnchor);
                    GPOS_get_anchor_values((const BYTE*)cpf1 + offset, &entry_pt, ppem);
                    TRACE("Found linkage %x[%s] %x[%s]\n",glyphs[glyph_index], wine_dbgstr_point(&exit_pt), glyphs[glyph_index+write_dir], wine_dbgstr_point(&entry_pt));
                    pt->x = entry_pt.x - exit_pt.x;
                    pt->y = entry_pt.y - exit_pt.y;
                    return;
                }
            }
        }
        else
            FIXME("Cursive Attachment Positioning: Format %i Unhandled\n",GET_BE_WORD(cpf1->PosFormat));
    }
    return;
}

static int GPOS_apply_MarkToBase(ScriptCache *psc, const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, INT glyph_index, INT glyph_count, INT ppem, LPPOINT pt)
{
    int j;
    int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
    void *glyph_class_table = NULL;
    int rc = -1;

    if (psc->GDEF_Table)
    {
        const GDEF_Header *header = psc->GDEF_Table;
        WORD offset = GET_BE_WORD( header->GlyphClassDef );
        if (offset)
            glyph_class_table = (BYTE *)psc->GDEF_Table + offset;
    }

    TRACE("MarkToBase Attachment Positioning Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GPOS_MarkBasePosFormat1 *mbpf1 = (const GPOS_MarkBasePosFormat1 *)GPOS_get_subtable(look, j);
        if (GET_BE_WORD(mbpf1->PosFormat) == 1)
        {
            int offset = GET_BE_WORD(mbpf1->MarkCoverage);
            int mark_index;
            mark_index = GSUB_is_glyph_covered((const BYTE*)mbpf1+offset, glyphs[glyph_index]);
            if (mark_index != -1)
            {
                int base_index;
                int base_glyph = glyph_index - write_dir;

                if (glyph_class_table)
                {
                    while (OT_get_glyph_class(glyph_class_table, glyphs[base_glyph]) == MarkGlyph && base_glyph > 0 && base_glyph < glyph_count)
                        base_glyph -= write_dir;
                }

                offset = GET_BE_WORD(mbpf1->BaseCoverage);
                base_index = GSUB_is_glyph_covered((const BYTE*)mbpf1+offset, glyphs[base_glyph]);
                if (base_index != -1)
                {
                    const GPOS_MarkArray *ma;
                    const GPOS_MarkRecord *mr;
                    const GPOS_BaseArray *ba;
                    const GPOS_BaseRecord *br;
                    int mark_class;
                    int class_count = GET_BE_WORD(mbpf1->ClassCount);
                    int baserecord_size;
                    POINT base_pt;
                    POINT mark_pt;
                    TRACE("Mark %x(%i) and base %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[base_glyph], base_index);
                    offset = GET_BE_WORD(mbpf1->MarkArray);
                    ma = (const GPOS_MarkArray*)((const BYTE*)mbpf1 + offset);
                    if (mark_index > GET_BE_WORD(ma->MarkCount))
                    {
                        ERR("Mark index exceeded mark count\n");
                        return -1;
                    }
                    mr = &ma->MarkRecord[mark_index];
                    mark_class = GET_BE_WORD(mr->Class);
                    TRACE("Mark Class %i total classes %i\n",mark_class,class_count);
                    offset = GET_BE_WORD(mbpf1->BaseArray);
                    ba = (const GPOS_BaseArray*)((const BYTE*)mbpf1 + offset);
                    baserecord_size = class_count * sizeof(WORD);
                    br = (const GPOS_BaseRecord*)((const BYTE*)ba + sizeof(WORD) + (baserecord_size * base_index));
                    offset = GET_BE_WORD(br->BaseAnchor[mark_class]);
                    GPOS_get_anchor_values((const BYTE*)ba + offset, &base_pt, ppem);
                    offset = GET_BE_WORD(mr->MarkAnchor);
                    GPOS_get_anchor_values((const BYTE*)ma + offset, &mark_pt, ppem);
                    TRACE("Offset on base is %s design units\n",wine_dbgstr_point(&base_pt));
                    TRACE("Offset on mark is %s design units\n",wine_dbgstr_point(&mark_pt));
                    pt->x += base_pt.x - mark_pt.x;
                    pt->y += base_pt.y - mark_pt.y;
                    TRACE("Resulting cumulative offset is %s design units\n",wine_dbgstr_point(pt));
                    rc = base_glyph;
                }
            }
        }
        else
            FIXME("Unhandled Mark To Base Format %i\n",GET_BE_WORD(mbpf1->PosFormat));
    }
    return rc;
}

static VOID GPOS_apply_MarkToLigature(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, INT glyph_index,
                                      INT glyph_count, INT ppem, LPPOINT pt)
{
    int j;
    int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;

    TRACE("MarkToLigature Attachment Positioning Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GPOS_MarkLigPosFormat1 *mlpf1 = (const GPOS_MarkLigPosFormat1 *)GPOS_get_subtable(look, j);
        if (GET_BE_WORD(mlpf1->PosFormat) == 1)
        {
            int offset = GET_BE_WORD(mlpf1->MarkCoverage);
            int mark_index;
            mark_index = GSUB_is_glyph_covered((const BYTE*)mlpf1+offset, glyphs[glyph_index]);
            if (mark_index != -1)
            {
                int ligature_index;
                offset = GET_BE_WORD(mlpf1->LigatureCoverage);
                ligature_index = GSUB_is_glyph_covered((const BYTE*)mlpf1+offset, glyphs[glyph_index - write_dir]);
                if (ligature_index != -1)
                {
                    const GPOS_MarkArray *ma;
                    const GPOS_MarkRecord *mr;

                    const GPOS_LigatureArray *la;
                    const GPOS_LigatureAttach *lt;
                    int mark_class;
                    int class_count = GET_BE_WORD(mlpf1->ClassCount);
                    int component_count;
                    int component_size;
                    int i;
                    POINT ligature_pt;
                    POINT mark_pt;

                    TRACE("Mark %x(%i) and ligature %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[glyph_index - write_dir], ligature_index);
                    offset = GET_BE_WORD(mlpf1->MarkArray);
                    ma = (const GPOS_MarkArray*)((const BYTE*)mlpf1 + offset);
                    if (mark_index > GET_BE_WORD(ma->MarkCount))
                    {
                        ERR("Mark index exceeded mark count\n");
                        return;
                    }
                    mr = &ma->MarkRecord[mark_index];
                    mark_class = GET_BE_WORD(mr->Class);
                    TRACE("Mark Class %i total classes %i\n",mark_class,class_count);
                    offset = GET_BE_WORD(mlpf1->LigatureArray);
                    la = (const GPOS_LigatureArray*)((const BYTE*)mlpf1 + offset);
                    if (ligature_index > GET_BE_WORD(la->LigatureCount))
                    {
                        ERR("Ligature index exceeded ligature count\n");
                        return;
                    }
                    offset = GET_BE_WORD(la->LigatureAttach[ligature_index]);
                    lt = (const GPOS_LigatureAttach*)((const BYTE*)la + offset);

                    component_count = GET_BE_WORD(lt->ComponentCount);
                    component_size = class_count * sizeof(WORD);
                    offset = 0;
                    for (i = 0; i < component_count && !offset; i++)
                    {
                        int k;
                        const GPOS_ComponentRecord *cr = (const GPOS_ComponentRecord*)((const BYTE*)lt->ComponentRecord + (component_size * i));
                        for (k = 0; k < class_count && !offset; k++)
                            offset = GET_BE_WORD(cr->LigatureAnchor[k]);
                        cr = (const GPOS_ComponentRecord*)((const BYTE*)cr + component_size);
                    }
                    if (!offset)
                    {
                        ERR("Failed to find avalible ligature connection point\n");
                        return;
                    }

                    GPOS_get_anchor_values((const BYTE*)lt + offset, &ligature_pt, ppem);
                    offset = GET_BE_WORD(mr->MarkAnchor);
                    GPOS_get_anchor_values((const BYTE*)ma + offset, &mark_pt, ppem);
                    TRACE("Offset on ligature is %s design units\n",wine_dbgstr_point(&ligature_pt));
                    TRACE("Offset on mark is %s design units\n",wine_dbgstr_point(&mark_pt));
                    pt->x += ligature_pt.x - mark_pt.x;
                    pt->y += ligature_pt.y - mark_pt.y;
                    TRACE("Resulting cumulative offset is %s design units\n",wine_dbgstr_point(pt));
                }
            }
        }
        else
            FIXME("Unhandled Mark To Ligature Format %i\n",GET_BE_WORD(mlpf1->PosFormat));
    }
}

static BOOL GPOS_apply_MarkToMark(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, INT glyph_index,
                                  INT glyph_count, INT ppem, LPPOINT pt)
{
    int j;
    BOOL rc = FALSE;
    int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;

    TRACE("MarkToMark Attachment Positioning Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GPOS_MarkMarkPosFormat1 *mmpf1 = (const GPOS_MarkMarkPosFormat1 *)GPOS_get_subtable(look, j);
        if (GET_BE_WORD(mmpf1->PosFormat) == 1)
        {
            int offset = GET_BE_WORD(mmpf1->Mark1Coverage);
            int mark_index;
            mark_index = GSUB_is_glyph_covered((const BYTE*)mmpf1+offset, glyphs[glyph_index]);
            if (mark_index != -1)
            {
                int mark2_index;
                offset = GET_BE_WORD(mmpf1->Mark2Coverage);
                mark2_index = GSUB_is_glyph_covered((const BYTE*)mmpf1+offset, glyphs[glyph_index - write_dir]);
                if (mark2_index != -1)
                {
                    const GPOS_MarkArray *ma;
                    const GPOS_MarkRecord *mr;
                    const GPOS_Mark2Array *m2a;
                    const GPOS_Mark2Record *m2r;
                    int mark_class;
                    int class_count = GET_BE_WORD(mmpf1->ClassCount);
                    int mark2record_size;
                    POINT mark2_pt;
                    POINT mark_pt;
                    TRACE("Mark %x(%i) and Mark2 %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[glyph_index - write_dir], mark2_index);
                    offset = GET_BE_WORD(mmpf1->Mark1Array);
                    ma = (const GPOS_MarkArray*)((const BYTE*)mmpf1 + offset);
                    if (mark_index > GET_BE_WORD(ma->MarkCount))
                    {
                        ERR("Mark index exceeded mark count\n");
                        return FALSE;
                    }
                    mr = &ma->MarkRecord[mark_index];
                    mark_class = GET_BE_WORD(mr->Class);
                    TRACE("Mark Class %i total classes %i\n",mark_class,class_count);
                    offset = GET_BE_WORD(mmpf1->Mark2Array);
                    m2a = (const GPOS_Mark2Array*)((const BYTE*)mmpf1 + offset);
                    mark2record_size = class_count * sizeof(WORD);
                    m2r = (const GPOS_Mark2Record*)((const BYTE*)m2a + sizeof(WORD) + (mark2record_size * mark2_index));
                    offset = GET_BE_WORD(m2r->Mark2Anchor[mark_class]);
                    GPOS_get_anchor_values((const BYTE*)m2a + offset, &mark2_pt, ppem);
                    offset = GET_BE_WORD(mr->MarkAnchor);
                    GPOS_get_anchor_values((const BYTE*)ma + offset, &mark_pt, ppem);
                    TRACE("Offset on mark2 is %s design units\n",wine_dbgstr_point(&mark2_pt));
                    TRACE("Offset on mark is %s design units\n",wine_dbgstr_point(&mark_pt));
                    pt->x += mark2_pt.x - mark_pt.x;
                    pt->y += mark2_pt.y - mark_pt.y;
                    TRACE("Resulting cumulative offset is %s design units\n",wine_dbgstr_point(pt));
                    rc = TRUE;
                }
            }
        }
        else
            FIXME("Unhandled Mark To Mark Format %i\n",GET_BE_WORD(mmpf1->PosFormat));
    }
    return rc;
}

static INT GPOS_apply_ContextPos(ScriptCache *psc, LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, const SCRIPT_ANALYSIS *analysis, INT* piAdvance,
                                      const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, INT glyph_index,
                                      INT glyph_count, INT ppem, GOFFSET *pGoffset)
{
    int j;
    int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;

    TRACE("Contextual Positioning Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        const GPOS_ContextPosFormat2 *cpf2 = (GPOS_ContextPosFormat2*)GPOS_get_subtable(look, j);

        if (GET_BE_WORD(cpf2->PosFormat) == 1)
        {
            static int once;
            if (!once++)
                FIXME("  TODO: subtype 1\n");
            continue;
        }
        else if (GET_BE_WORD(cpf2->PosFormat) == 2)
        {
            WORD offset = GET_BE_WORD(cpf2->Coverage);
            int index;

            TRACE("Contextual Positioning Subtable: Format 2\n");

            index = GSUB_is_glyph_covered((const BYTE*)cpf2+offset, glyphs[glyph_index]);
            TRACE("Coverage index %i\n",index);
            if (index != -1)
            {
                int k, count, class;
                const GPOS_PosClassSet *pcs;
                const void *glyph_class_table = NULL;

                offset = GET_BE_WORD(cpf2->ClassDef);
                glyph_class_table = (const BYTE *)cpf2 + offset;

                class = OT_get_glyph_class(glyph_class_table,glyphs[glyph_index]);

                offset = GET_BE_WORD(cpf2->PosClassSet[class]);
                if (offset == 0)
                {
                    TRACE("No class rule table for class %i\n",class);
                    continue;
                }
                pcs = (const GPOS_PosClassSet*)((const BYTE*)cpf2+offset);
                count = GET_BE_WORD(pcs->PosClassRuleCnt);
                TRACE("PosClassSet has %i members\n",count);
                for (k = 0; k < count; k++)
                {
                    const GPOS_PosClassRule_1 *pr;
                    const GPOS_PosClassRule_2 *pr_2;
                    int g_count, l;

                    offset = GET_BE_WORD(pcs->PosClassRule[k]);
                    pr = (const GPOS_PosClassRule_1*)((const BYTE*)pcs+offset);
                    g_count = GET_BE_WORD(pr->GlyphCount);
                    TRACE("PosClassRule has %i glyphs classes\n",g_count);
                    for (l = 0; l < g_count-1; l++)
                    {
                        int g_class = OT_get_glyph_class(glyph_class_table, glyphs[glyph_index + (write_dir * (l+1))]);
                        if (g_class != GET_BE_WORD(pr->Class[l])) break;
                    }

                    if (l < g_count-1)
                    {
                        TRACE("Rule does not match\n");
                        continue;
                    }

                    TRACE("Rule matches\n");
                    pr_2 = (const GPOS_PosClassRule_2*)((const BYTE*)pr+
                        FIELD_OFFSET(GPOS_PosClassRule_1, Class[g_count-1]));

                    for (l = 0; l < GET_BE_WORD(pr->PosCount); l++)
                    {
                        int lookupIndex = GET_BE_WORD(pr_2->PosLookupRecord[l].LookupListIndex);
                        int SequenceIndex = GET_BE_WORD(pr_2->PosLookupRecord[l].SequenceIndex) * write_dir;

                        TRACE("Position: %i -> %i %i\n",l, SequenceIndex, lookupIndex);
                        GPOS_apply_lookup(psc, lpotm, lplogfont, analysis, piAdvance, lookup, lookupIndex, glyphs, glyph_index + SequenceIndex, glyph_count, pGoffset);
                    }
                    return glyph_index + 1;
                }
            }

            TRACE("Not covered\n");
            continue;
        }
        else if (GET_BE_WORD(cpf2->PosFormat) == 3)
        {
            static int once;
            if (!once++)
                FIXME("  TODO: subtype 3\n");
            continue;
        }
        else
            FIXME("Unhandled Contextual Positioning Format %i\n",GET_BE_WORD(cpf2->PosFormat));
    }
    return glyph_index + 1;
}

static INT GPOS_apply_ChainContextPos(ScriptCache *psc, LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, const SCRIPT_ANALYSIS *analysis, INT* piAdvance,
                                      const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, INT glyph_index,
                                      INT glyph_count, INT ppem, GOFFSET *pGoffset)
{
    int j;
    int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;

    TRACE("Chaining Contextual Positioning Subtable\n");

    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
    {
        int offset;
        const GPOS_ChainContextPosFormat3_1 *ccpf3 = (GPOS_ChainContextPosFormat3_1 *)GPOS_get_subtable(look, j);
        int dirLookahead = write_dir;
        int dirBacktrack = -1 * write_dir;

        if (GET_BE_WORD(ccpf3->PosFormat) == 1)
        {
            static int once;
            if (!once++)
                FIXME("  TODO: subtype 1 (Simple Chaining Context Glyph Positioning)\n");
            continue;
        }
        else if (GET_BE_WORD(ccpf3->PosFormat) == 2)
        {
            static int once;
            if (!once++)
                FIXME("  TODO: subtype 2 (Class-based Chaining Context Glyph Positioning)\n");
            continue;
        }
        else if (GET_BE_WORD(ccpf3->PosFormat) == 3)
        {
            int k;
            int indexGlyphs;
            const GPOS_ChainContextPosFormat3_2 *ccpf3_2;
            const GPOS_ChainContextPosFormat3_3 *ccpf3_3;
            const GPOS_ChainContextPosFormat3_4 *ccpf3_4;

            TRACE("  subtype 3 (Coverage-based Chaining Context Glyph Positioning)\n");

            for (k = 0; k < GET_BE_WORD(ccpf3->BacktrackGlyphCount); k++)
            {
                offset = GET_BE_WORD(ccpf3->Coverage[k]);
                if (GSUB_is_glyph_covered((const BYTE*)ccpf3+offset, glyphs[glyph_index + (dirBacktrack * (k+1))]) == -1)
                    break;
            }
            if (k != GET_BE_WORD(ccpf3->BacktrackGlyphCount))
                continue;
            TRACE("Matched Backtrack\n");

            ccpf3_2 = (const GPOS_ChainContextPosFormat3_2*)((BYTE *)ccpf3 +
                    FIELD_OFFSET(GPOS_ChainContextPosFormat3_1, Coverage[GET_BE_WORD(ccpf3->BacktrackGlyphCount)]));

            indexGlyphs = GET_BE_WORD(ccpf3_2->InputGlyphCount);
            for (k = 0; k < indexGlyphs; k++)
            {
                offset = GET_BE_WORD(ccpf3_2->Coverage[k]);
                if (GSUB_is_glyph_covered((const BYTE*)ccpf3+offset, glyphs[glyph_index + (write_dir * k)]) == -1)
                    break;
            }
            if (k != indexGlyphs)
                continue;
            TRACE("Matched IndexGlyphs\n");

            ccpf3_3 = (const GPOS_ChainContextPosFormat3_3*)((BYTE *)ccpf3_2 +
                    FIELD_OFFSET(GPOS_ChainContextPosFormat3_2, Coverage[GET_BE_WORD(ccpf3_2->InputGlyphCount)]));

            for (k = 0; k < GET_BE_WORD(ccpf3_3->LookaheadGlyphCount); k++)
            {
                offset = GET_BE_WORD(ccpf3_3->Coverage[k]);
                if (GSUB_is_glyph_covered((const BYTE*)ccpf3+offset, glyphs[glyph_index + (dirLookahead * (indexGlyphs + k))]) == -1)
                    break;
            }
            if (k != GET_BE_WORD(ccpf3_3->LookaheadGlyphCount))
                continue;
            TRACE("Matched LookAhead\n");

            ccpf3_4 = (const GPOS_ChainContextPosFormat3_4*)((BYTE *)ccpf3_3 +
                    FIELD_OFFSET(GPOS_ChainContextPosFormat3_3, Coverage[GET_BE_WORD(ccpf3_3->LookaheadGlyphCount)]));

            if (GET_BE_WORD(ccpf3_4->PosCount))
            {
                for (k = 0; k < GET_BE_WORD(ccpf3_4->PosCount); k++)
                {
                    int lookupIndex = GET_BE_WORD(ccpf3_4->PosLookupRecord[k].LookupListIndex);
                    int SequenceIndex = GET_BE_WORD(ccpf3_4->PosLookupRecord[k].SequenceIndex) * write_dir;

                    TRACE("Position: %i -> %i %i\n",k, SequenceIndex, lookupIndex);
                    GPOS_apply_lookup(psc, lpotm, lplogfont, analysis, piAdvance, lookup, lookupIndex, glyphs, glyph_index + SequenceIndex, glyph_count, pGoffset);
                }
                return glyph_index + indexGlyphs + GET_BE_WORD(ccpf3_3->LookaheadGlyphCount);
            }
            else return glyph_index + 1;
        }
        else
            FIXME("Unhandled Chaining Contextual Positioning Format %i\n",GET_BE_WORD(ccpf3->PosFormat));
    }
    return glyph_index + 1;
}

static INT GPOS_apply_lookup(ScriptCache *psc, LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, const SCRIPT_ANALYSIS *analysis, INT* piAdvance, const OT_LookupList* lookup, INT lookup_index, const WORD *glyphs, INT glyph_index, INT glyph_count, GOFFSET *pGoffset)
{
    int offset;
    const OT_LookupTable *look;
    int ppem = lpotm->otmTextMetrics.tmAscent + lpotm->otmTextMetrics.tmDescent - lpotm->otmTextMetrics.tmInternalLeading;
    WORD type;

    offset = GET_BE_WORD(lookup->Lookup[lookup_index]);
    look = (const OT_LookupTable*)((const BYTE*)lookup + offset);
    type = GET_BE_WORD(look->LookupType);
    TRACE("type %i, flag %x, subtables %i\n",type,GET_BE_WORD(look->LookupFlag),GET_BE_WORD(look->SubTableCount));
    if (type == 9)
    {
        if (GET_BE_WORD(look->SubTableCount))
        {
            const GPOS_ExtensionPosFormat1 *ext = (const GPOS_ExtensionPosFormat1 *)((const BYTE *)look + GET_BE_WORD(look->SubTable[0]));
            if (GET_BE_WORD(ext->PosFormat) == 1)
            {
                type = GET_BE_WORD(ext->ExtensionLookupType);
                TRACE("extension type %i\n",type);
            }
            else
            {
                FIXME("Unhandled Extension Positioning Format %i\n",GET_BE_WORD(ext->PosFormat));
            }
        }
        else
        {
            WARN("lookup type is Extension Positioning but no extension subtable exists\n");
        }
    }
    switch (type)
    {
        case 1:
        {
            double devX, devY;
            POINT adjust = {0,0};
            POINT advance = {0,0};
            GPOS_apply_SingleAdjustment(look, analysis, glyphs, glyph_index, glyph_count, ppem, &adjust, &advance);
            if (adjust.x || adjust.y)
            {
                GPOS_convert_design_units_to_device(lpotm, lplogfont, adjust.x, adjust.y, &devX, &devY);
                pGoffset[glyph_index].du += round(devX);
                pGoffset[glyph_index].dv += round(devY);
            }
            if (advance.x || advance.y)
            {
                GPOS_convert_design_units_to_device(lpotm, lplogfont, advance.x, advance.y, &devX, &devY);
                piAdvance[glyph_index] += round(devX);
                if (advance.y)
                    FIXME("Unhandled adjustment to Y advancement\n");
            }
            break;
        }
        case 2:
        {
            POINT advance[2]= {{0,0},{0,0}};
            POINT adjust[2]= {{0,0},{0,0}};
            double devX, devY;
            int index;
            int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
            int offset_sign = (analysis->fRTL && analysis->fLogicalOrder) ? -1 : 1;

            index = GPOS_apply_PairAdjustment(look, analysis, glyphs, glyph_index, glyph_count, ppem, adjust, advance);
            if (adjust[0].x || adjust[0].y)
            {
                GPOS_convert_design_units_to_device(lpotm, lplogfont, adjust[0].x, adjust[0].y, &devX, &devY);
                pGoffset[glyph_index].du += round(devX) * offset_sign;
                pGoffset[glyph_index].dv += round(devY);
            }
            if (advance[0].x || advance[0].y)
            {
                GPOS_convert_design_units_to_device(lpotm, lplogfont, advance[0].x, advance[0].y, &devX, &devY);
                piAdvance[glyph_index] += round(devX);
            }
            if (adjust[1].x || adjust[1].y)
            {
                GPOS_convert_design_units_to_device(lpotm, lplogfont, adjust[1].x, adjust[1].y, &devX, &devY);
                pGoffset[glyph_index + write_dir].du += round(devX) * offset_sign;
                pGoffset[glyph_index + write_dir].dv += round(devY);
            }
            if (advance[1].x || advance[1].y)
            {
                GPOS_convert_design_units_to_device(lpotm, lplogfont, advance[1].x, advance[1].y, &devX, &devY);
                piAdvance[glyph_index + write_dir] += round(devX);
            }
            return index;
        }
        case 3:
        {
            POINT desU = {0,0};
            double devX, devY;
            int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;

            GPOS_apply_CursiveAttachment(look, analysis, glyphs, glyph_index, glyph_count, ppem, &desU);
            if (desU.x || desU.y)
            {
                GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
                /* Windows does not appear to apply X offsets here */
                pGoffset[glyph_index].dv = round(devY) + pGoffset[glyph_index+write_dir].dv;
            }
            break;
        }
        case 4:
        {
            double devX, devY;
            POINT desU = {0,0};
            int base_index = GPOS_apply_MarkToBase(psc, look, analysis, glyphs, glyph_index, glyph_count, ppem, &desU);
            if (base_index != -1)
            {
                GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
                if (!analysis->fRTL) pGoffset[glyph_index].du = round(devX) - piAdvance[base_index];
                else
                {
                    if (analysis->fLogicalOrder) devX *= -1;
                    pGoffset[glyph_index].du = round(devX);
                }
                pGoffset[glyph_index].dv = round(devY);
            }
            break;
        }
        case 5:
        {
            double devX, devY;
            POINT desU = {0,0};
            GPOS_apply_MarkToLigature(look, analysis, glyphs, glyph_index, glyph_count, ppem, &desU);
            if (desU.x || desU.y)
            {
                GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
                pGoffset[glyph_index].du = (round(devX) - piAdvance[glyph_index-1]);
                pGoffset[glyph_index].dv = round(devY);
            }
            break;
        }
        case 6:
        {
            double devX, devY;
            POINT desU = {0,0};
            int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
            if (GPOS_apply_MarkToMark(look, analysis, glyphs, glyph_index, glyph_count, ppem, &desU))
            {
                GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
                if (analysis->fRTL && analysis->fLogicalOrder) devX *= -1;
                pGoffset[glyph_index].du = round(devX) + pGoffset[glyph_index - write_dir].du;
                pGoffset[glyph_index].dv = round(devY) + pGoffset[glyph_index - write_dir].dv;
            }
            break;
        }
        case 7:
            return GPOS_apply_ContextPos(psc, lpotm, lplogfont, analysis, piAdvance, lookup, look, glyphs, glyph_index, glyph_count, ppem, pGoffset);
        case 8:
        {
            return GPOS_apply_ChainContextPos(psc, lpotm, lplogfont, analysis, piAdvance, lookup, look, glyphs, glyph_index, glyph_count, ppem, pGoffset);
        }
        default:
            FIXME("We do not handle SubType %i\n",type);
    }
    return glyph_index+1;
}

INT OpenType_apply_GPOS_lookup(ScriptCache *psc, LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, const SCRIPT_ANALYSIS *analysis, INT* piAdvance, INT lookup_index, const WORD *glyphs, INT glyph_index, INT glyph_count, GOFFSET *pGoffset)
{
    const GPOS_Header *header = (const GPOS_Header *)psc->GPOS_Table;
    const OT_LookupList *lookup = (const OT_LookupList*)((const BYTE*)header + GET_BE_WORD(header->LookupList));

    return GPOS_apply_lookup(psc, lpotm, lplogfont, analysis, piAdvance, lookup, lookup_index, glyphs, glyph_index, glyph_count, pGoffset);
}

static void GSUB_initialize_script_cache(ScriptCache *psc)
{
    int i;

    if (psc->GSUB_Table)
    {
        const OT_ScriptList *script;
        const GSUB_Header* header = (const GSUB_Header*)psc->GSUB_Table;
        script = (const OT_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList));
        psc->script_count = GET_BE_WORD(script->ScriptCount);
        TRACE("initializing %i scripts in this font\n",psc->script_count);
        if (psc->script_count)
        {
            psc->scripts = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LoadedScript) * psc->script_count);
            for (i = 0; i < psc->script_count; i++)
            {
                int offset = GET_BE_WORD(script->ScriptRecord[i].Script);
                psc->scripts[i].tag = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]);
                psc->scripts[i].gsub_table = ((const BYTE*)script + offset);
            }
        }
    }
}

static void GPOS_expand_script_cache(ScriptCache *psc)
{
    int i, count;
    const OT_ScriptList *script;
    const GPOS_Header* header = (const GPOS_Header*)psc->GPOS_Table;

    if (!header)
        return;

    script = (const OT_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList));
    count = GET_BE_WORD(script->ScriptCount);

    if (!count)
        return;

    if (!psc->script_count)
    {
        psc->script_count = count;
        TRACE("initializing %i scripts in this font\n",psc->script_count);
        if (psc->script_count)
        {
            psc->scripts = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LoadedScript) * psc->script_count);
            for (i = 0; i < psc->script_count; i++)
            {
                int offset = GET_BE_WORD(script->ScriptRecord[i].Script);
                psc->scripts[i].tag = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]);
                psc->scripts[i].gpos_table = ((const BYTE*)script + offset);
            }
        }
    }
    else
    {
        for (i = 0; i < count; i++)
        {
            int j;
            int offset = GET_BE_WORD(script->ScriptRecord[i].Script);
            OPENTYPE_TAG tag = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]);
            for (j = 0; j < psc->script_count; j++)
            {
                if (psc->scripts[j].tag == tag)
                {
                    psc->scripts[j].gpos_table = ((const BYTE*)script + offset);
                    break;
                }
            }
            if (j == psc->script_count)
            {
                psc->script_count++;
                psc->scripts = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,psc->scripts, sizeof(LoadedScript) * psc->script_count);
                psc->scripts[j].tag = tag;
                psc->scripts[j].gpos_table = ((const BYTE*)script + offset);
            }
        }
    }
}

static void _initialize_script_cache(ScriptCache *psc)
{
    if (!psc->scripts_initialized)
    {
        GSUB_initialize_script_cache(psc);
        GPOS_expand_script_cache(psc);
        psc->scripts_initialized = TRUE;
    }
}

HRESULT OpenType_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags)
{
    int i;
    HRESULT rc = S_OK;

    _initialize_script_cache(psc);

    *pcTags = psc->script_count;

    if (!searchingFor && cMaxTags < *pcTags)
        rc = E_OUTOFMEMORY;
    else if (searchingFor)
        rc = USP_E_SCRIPT_NOT_IN_FONT;

    for (i = 0; i < psc->script_count; i++)
    {
        if (i < cMaxTags)
            pScriptTags[i] = psc->scripts[i].tag;

        if (searchingFor)
        {
            if (searchingFor == psc->scripts[i].tag)
            {
                pScriptTags[0] = psc->scripts[i].tag;
                *pcTags = 1;
                rc = S_OK;
                break;
            }
        }
    }
    return rc;
}

static void GSUB_initialize_language_cache(LoadedScript *script)
{
    int i;

    if (script->gsub_table)
    {
        DWORD offset;
        const OT_Script* table = script->gsub_table;
        script->language_count = GET_BE_WORD(table->LangSysCount);
        offset = GET_BE_WORD(table->DefaultLangSys);
        if (offset)
        {
            script->default_language.tag = MS_MAKE_TAG('d','f','l','t');
            script->default_language.gsub_table = (const BYTE*)table + offset;
        }

        if (script->language_count)
        {
            TRACE("Deflang %p, LangCount %i\n",script->default_language.gsub_table, script->language_count);

            script->languages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LoadedLanguage) * script->language_count);

            for (i = 0; i < script->language_count; i++)
            {
                int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys);
                script->languages[i].tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]);
                script->languages[i].gsub_table = ((const BYTE*)table + offset);
            }
        }
    }
}

static void GPOS_expand_language_cache(LoadedScript *script)
{
    int count;
    const OT_Script* table = script->gpos_table;
    DWORD offset;

    if (!table)
        return;

    offset = GET_BE_WORD(table->DefaultLangSys);
    if (offset)
        script->default_language.gpos_table = (const BYTE*)table + offset;

    count = GET_BE_WORD(table->LangSysCount);

    TRACE("Deflang %p, LangCount %i\n",script->default_language.gpos_table, count);

    if (!count)
        return;

    if (!script->language_count)
    {
        int i;
        script->language_count = count;

        script->languages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LoadedLanguage) * script->language_count);

        for (i = 0; i < script->language_count; i++)
        {
            int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys);
            script->languages[i].tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]);
            script->languages[i].gpos_table = ((const BYTE*)table + offset);
        }
    }
    else if (count)
    {
        int i,j;
        for (i = 0; i < count; i++)
        {
            int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys);
            OPENTYPE_TAG tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]);

            for (j = 0; j < script->language_count; j++)
            {
                if (script->languages[j].tag == tag)
                {
                    script->languages[j].gpos_table = ((const BYTE*)table + offset);
                    break;
                }
            }
            if (j == script->language_count)
            {
                script->language_count++;
                script->languages = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,script->languages, sizeof(LoadedLanguage) * script->language_count);
                script->languages[j].tag = tag;
                script->languages[j].gpos_table = ((const BYTE*)table + offset);
            }
        }
    }
}

static void _initialize_language_cache(LoadedScript *script)
{
    if (!script->languages_initialized)
    {
        GSUB_initialize_language_cache(script);
        GPOS_expand_language_cache(script);
        script->languages_initialized = TRUE;
    }
}

HRESULT OpenType_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags)
{
    int i;
    HRESULT rc = S_OK;
    LoadedScript *script = NULL;

    _initialize_script_cache(psc);

    for (i = 0; i < psc->script_count; i++)
    {
         if (psc->scripts[i].tag == script_tag)
         {
            script = &psc->scripts[i];
            break;
         }
    }

    if (!script)
        return E_INVALIDARG;

    _initialize_language_cache(script);

    if (!searchingFor && cMaxTags < script->language_count)
        rc = E_OUTOFMEMORY;
    else if (searchingFor)
        rc = E_INVALIDARG;

    *pcTags = script->language_count;

    for (i = 0; i < script->language_count; i++)
    {
        if (i < cMaxTags)
            pLanguageTags[i] = script->languages[i].tag;

        if (searchingFor)
        {
            if (searchingFor == script->languages[i].tag)
            {
                pLanguageTags[0] = script->languages[i].tag;
                *pcTags = 1;
                rc = S_OK;
                break;
            }
        }
    }

    if (script->default_language.gsub_table)
    {
        if (i < cMaxTags)
            pLanguageTags[i] = script->default_language.tag;

        if (searchingFor  && FAILED(rc))
        {
            pLanguageTags[0] = script->default_language.tag;
        }
        i++;
        *pcTags = (*pcTags) + 1;
    }

    return rc;
}


static void GSUB_initialize_feature_cache(LPCVOID table, LoadedLanguage *language)
{
    int i;

    if (language->gsub_table)
    {
        const OT_LangSys *lang = language->gsub_table;
        const GSUB_Header *header = (const GSUB_Header *)table;
        const OT_FeatureList *feature_list;

        language->feature_count = GET_BE_WORD(lang->FeatureCount);
        TRACE("%i features\n",language->feature_count);

        if (language->feature_count)
        {
            language->features = HeapAlloc(GetProcessHeap(),0,sizeof(LoadedFeature)*language->feature_count);

            feature_list = (const OT_FeatureList*)((const BYTE*)header + GET_BE_WORD(header->FeatureList));

            for (i = 0; i < language->feature_count; i++)
            {
                const OT_Feature *feature;
                int j;
                int index = GET_BE_WORD(lang->FeatureIndex[i]);

                language->features[i].tag = MS_MAKE_TAG(feature_list->FeatureRecord[index].FeatureTag[0], feature_list->FeatureRecord[index].FeatureTag[1], feature_list->FeatureRecord[index].FeatureTag[2], feature_list->FeatureRecord[index].FeatureTag[3]);
                language->features[i].feature = ((const BYTE*)feature_list + GET_BE_WORD(feature_list->FeatureRecord[index].Feature));
                feature = (const OT_Feature*)language->features[i].feature;
                language->features[i].lookup_count = GET_BE_WORD(feature->LookupCount);
                language->features[i].lookups = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * language->features[i].lookup_count);
                for (j = 0; j < language->features[i].lookup_count; j++)
                    language->features[i].lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
                language->features[i].tableType = FEATURE_GSUB_TABLE;
            }
        }
    }
}

static void GPOS_expand_feature_cache(LPCVOID table, LoadedLanguage *language)
{
    int i, count;
    const OT_LangSys *lang = language->gpos_table;
    const GPOS_Header *header = (const GPOS_Header *)table;
    const OT_FeatureList *feature_list;

    if (!lang)
        return;

    count = GET_BE_WORD(lang->FeatureCount);
    feature_list = (const OT_FeatureList*)((const BYTE*)header + GET_BE_WORD(header->FeatureList));

    TRACE("%i features\n",count);

    if (!count)
        return;

    if (!language->feature_count)
    {
        language->feature_count = count;

        if (language->feature_count)
        {
            language->features = HeapAlloc(GetProcessHeap(),0,sizeof(LoadedFeature)*language->feature_count);

            for (i = 0; i < language->feature_count; i++)
            {
                const OT_Feature *feature;
                int j;
                int index = GET_BE_WORD(lang->FeatureIndex[i]);

                language->features[i].tag = MS_MAKE_TAG(feature_list->FeatureRecord[index].FeatureTag[0], feature_list->FeatureRecord[index].FeatureTag[1], feature_list->FeatureRecord[index].FeatureTag[2], feature_list->FeatureRecord[index].FeatureTag[3]);
                language->features[i].feature = ((const BYTE*)feature_list + GET_BE_WORD(feature_list->FeatureRecord[index].Feature));
                feature = (const OT_Feature*)language->features[i].feature;
                language->features[i].lookup_count = GET_BE_WORD(feature->LookupCount);
                language->features[i].lookups = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * language->features[i].lookup_count);
                for (j = 0; j < language->features[i].lookup_count; j++)
                    language->features[i].lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
                language->features[i].tableType = FEATURE_GPOS_TABLE;
            }
        }
    }
    else
    {
        language->features = HeapReAlloc(GetProcessHeap(),0,language->features, sizeof(LoadedFeature)*(language->feature_count + count));

        for (i = 0; i < count; i++)
        {
            const OT_Feature *feature;
            int j;
            int index = GET_BE_WORD(lang->FeatureIndex[i]);
            int idx = language->feature_count + i;

            language->features[idx].tag = MS_MAKE_TAG(feature_list->FeatureRecord[index].FeatureTag[0], feature_list->FeatureRecord[index].FeatureTag[1], feature_list->FeatureRecord[index].FeatureTag[2], feature_list->FeatureRecord[index].FeatureTag[3]);
            language->features[idx].feature = ((const BYTE*)feature_list + GET_BE_WORD(feature_list->FeatureRecord[index].Feature));
            feature = (const OT_Feature*)language->features[idx].feature;
            language->features[idx].lookup_count = GET_BE_WORD(feature->LookupCount);
            language->features[idx].lookups = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * language->features[idx].lookup_count);
            for (j = 0; j < language->features[idx].lookup_count; j++)
                language->features[idx].lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
            language->features[idx].tableType = FEATURE_GPOS_TABLE;
        }
        language->feature_count += count;
    }
}

static void _initialize_feature_cache(ScriptCache *psc, LoadedLanguage *language)
{
    if (!language->features_initialized)
    {
        GSUB_initialize_feature_cache(psc->GSUB_Table, language);
        GPOS_expand_feature_cache(psc->GPOS_Table, language);
        language->features_initialized = TRUE;
    }
}

HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, char tableType, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature** feature)
{
    int i;
    HRESULT rc = S_OK;
    LoadedScript *script = NULL;
    LoadedLanguage *language = NULL;

    _initialize_script_cache(psc);

    for (i = 0; i < psc->script_count; i++)
    {
        if (psc->scripts[i].tag == script_tag)
        {
            script = &psc->scripts[i];
            break;
        }
    }

    if (!script)
    {
        *pcTags = 0;
        if (!filtered)
            return S_OK;
        else
            return E_INVALIDARG;
    }

    _initialize_language_cache(script);

    if ((script->default_language.gsub_table || script->default_language.gpos_table) && script->default_language.tag == language_tag)
        language = &script->default_language;
    else
    {
        for (i = 0; i < script->language_count; i++)
        {
            if (script->languages[i].tag == language_tag)
            {
                language = &script->languages[i];
                break;
            }
        }
    }

    if (!language)
    {
        *pcTags = 0;
        return S_OK;
    }

    _initialize_feature_cache(psc, language);

    if (tableType)
    {
        *pcTags = 0;
        for (i = 0; i < language->feature_count; i++)
            if (language->features[i].tableType == tableType)
                *pcTags = (*pcTags)+1;
    }
    else
        *pcTags = language->feature_count;

    if (!searchingFor && cMaxTags < *pcTags)
        rc = E_OUTOFMEMORY;
    else if (searchingFor)
        rc = E_INVALIDARG;

    for (i = 0; i < language->feature_count; i++)
    {
        if (i < cMaxTags)
        {
            if (!tableType || language->features[i].tableType == tableType)
                pFeatureTags[i] = language->features[i].tag;
        }

        if (searchingFor)
        {
            if ((searchingFor == language->features[i].tag) &&
                (!tableType || language->features[i].tableType == tableType))
            {
                pFeatureTags[0] = language->features[i].tag;
                *pcTags = 1;
                if (feature)
                    *feature = &language->features[i];
                rc = S_OK;
                break;
            }
        }
    }
    return rc;
}
