[ros-dev] [ros-diffs] [jgardou] 58375: [USP10] - sync to WINE-1.5.24 This gets wordpad performance to a bearable state when gdebug output is on

Sylvain Petreolle spetreolle at yahoo.fr
Wed Feb 27 19:00:08 UTC 2013


I definitely say yes.
Other parts of the code can be affected by non-inclusion of some headers.
(see the msi problem we got)
 
Kind regards,
Sylvain Petreolle


>________________________________
> De : Jérôme Gardou <jerome.gardou at reactos.org>
>À : ros-dev at reactos.org 
>Envoyé le : Mercredi 27 février 2013 15h15
>Objet : Re: [ros-dev] [ros-diffs] [jgardou] 58375: [USP10] - sync to WINE-1.5.24 This gets wordpad performance to a bearable state when gdebug output is on
> 
>Hey Amine.
>
>I know I broke your _awesome_ work on header inclusion for this one, but 
>do we really want to keep a diff file on wine modules for this ?
>
>Bye.
>Jérôme
>
>jgardou at svn.reactos.org a écrit :
>> Author: jgardou
>> Date: Wed Feb 27 14:11:44 2013
>> New Revision: 58375
>>
>> URL: http://svn.reactos.org/svn/reactos?rev=58375&view=rev
>> Log:
>> [USP10]
>>   - sync to WINE-1.5.24
>> This gets wordpad performance to a bearable state when gdebug output is on
>>
>> Modified:
>>      trunk/reactos/dll/win32/usp10/bidi.c
>>      trunk/reactos/dll/win32/usp10/breaking.c
>>      trunk/reactos/dll/win32/usp10/indic.c
>>      trunk/reactos/dll/win32/usp10/indicsyllable.c
>>      trunk/reactos/dll/win32/usp10/linebreak.c
>>      trunk/reactos/dll/win32/usp10/mirror.c
>>      trunk/reactos/dll/win32/usp10/opentype.c
>>      trunk/reactos/dll/win32/usp10/shape.c
>>      trunk/reactos/dll/win32/usp10/shaping.c
>>      trunk/reactos/dll/win32/usp10/usp10.c
>>      trunk/reactos/dll/win32/usp10/usp10_internal.h
>>      trunk/reactos/dll/win32/usp10/usp10_ros.diff
>>      trunk/reactos/media/doc/README.WINE
>>
>> Modified: trunk/reactos/dll/win32/usp10/bidi.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/bidi.c?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/bidi.c [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/bidi.c [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -41,16 +41,16 @@
>>    * has been modified.
>>    */
>>
>> -#include <config.h>
>> -
>> -//#include <stdarg.h>
>> -#include <windef.h>
>> -//#include "winbase.h"
>> -#include <wingdi.h>
>> -//#include "winnls.h"
>> -#include <usp10.h>
>> -#include <wine/unicode.h>
>> -#include <wine/debug.h>
>> +#include "config.h"
>> +
>> +#include <stdarg.h>
>> +#include "windef.h"
>> +#include "winbase.h"
>> +#include "wingdi.h"
>> +#include "winnls.h"
>> +#include "usp10.h"
>> +#include "wine/unicode.h"
>> +#include "wine/debug.h"
>>
>>   #include "usp10_internal.h"
>>
>> @@ -872,11 +872,13 @@
>>           reverse(pIndexs, ich);
>>       }
>>
>> -    if (newlevel > 1)
>> +    if (newlevel >= 0)
>>       {
>>           ich = 0;
>>           for (; ich < cch; ich++)
>> -            if (plevel[ich] > level)
>> +            if (plevel[ich] < level)
>> +                break;
>> +            else if (plevel[ich] > level)
>>                   ich += BIDI_ReorderL2vLevel(level + 1, pIndexs + ich, plevel + ich,
>>                   cch - ich, fReverse) - 1;
>>       }
>>
>> Modified: trunk/reactos/dll/win32/usp10/breaking.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/breaking.c?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/breaking.c [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/breaking.c [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -18,20 +18,20 @@
>>    * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
>>    *
>>    */
>> -#include <config.h>
>> +#include "config.h"
>>   #include <stdarg.h>
>> -//#include <stdio.h>
>> -//#include <stdlib.h>
>> -
>> -#include <windef.h>
>> -#include <winbase.h>
>> -//#include "winuser.h"
>> -#include <wingdi.h>
>> -//#include "winnls.h"
>> -#include <usp10.h>
>> -//#include "winternl.h"
>> -
>> -#include <wine/debug.h>
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +
>> +#include "windef.h"
>> +#include "winbase.h"
>> +#include "winuser.h"
>> +#include "wingdi.h"
>> +#include "winnls.h"
>> +#include "usp10.h"
>> +#include "winternl.h"
>> +
>> +#include "wine/debug.h"
>>   #include "usp10_internal.h"
>>
>>   WINE_DEFAULT_DEBUG_CHANNEL(uniscribe);
>> @@ -132,7 +132,7 @@
>>               case b_NL:
>>               case b_BK:
>>                   if (i < count-1) else_break(&break_before[i+1],b_r);
>> -                    else_break(&break_before[i],b_x);
>> +                else_break(&break_before[i],b_x);
>>                   break;
>>               /* LB7 */
>>               case b_SP:
>>
>> Modified: trunk/reactos/dll/win32/usp10/indic.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/indic.c?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/indic.c [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/indic.c [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -18,20 +18,20 @@
>>    * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
>>    *
>>    */
>> -#include <config.h>
>> +#include "config.h"
>>   #include <stdarg.h>
>> -//#include <stdio.h>
>> -//#include <stdlib.h>
>> -
>> -#include <windef.h>
>> -#include <winbase.h>
>> -//#include "winuser.h"
>> -#include <wingdi.h>
>> -//#include "winnls.h"
>> -#include <usp10.h>
>> -//#include "winternl.h"
>> -
>> -#include <wine/debug.h>
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +
>> +#include "windef.h"
>> +#include "winbase.h"
>> +#include "winuser.h"
>> +#include "wingdi.h"
>> +#include "winnls.h"
>> +#include "usp10.h"
>> +#include "winternl.h"
>> +
>> +#include "wine/debug.h"
>>   #include "usp10_internal.h"
>>
>>   WINE_DEFAULT_DEBUG_CHANNEL(uniscribe);
>>
>> Modified: trunk/reactos/dll/win32/usp10/indicsyllable.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/indicsyllable.c?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/indicsyllable.c [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/indicsyllable.c [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -3,7 +3,7 @@
>>   /*       and from http://www.unicode.org/Public/6.0.0/ucd/IndicMatraCategory.txt */
>>   /* DO NOT EDIT!! */
>>
>> -//#include "wine/unicode.h"
>> +#include "wine/unicode.h"
>>
>>   const unsigned short indic_syllabic_table[2624] =
>>   {
>>
>> Modified: trunk/reactos/dll/win32/usp10/linebreak.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/linebreak.c?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/linebreak.c [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/linebreak.c [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -2,7 +2,7 @@
>>   /* generated from http://www.unicode.org/Public/6.0.0/ucd/LineBreak.txt */
>>   /* DO NOT EDIT!! */
>>
>> -//#include "wine/unicode.h"
>> +#include "wine/unicode.h"
>>
>>   const unsigned short wine_linebreak_table[6800] =
>>   {
>>
>> Modified: trunk/reactos/dll/win32/usp10/mirror.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/mirror.c?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/mirror.c [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/mirror.c [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -2,7 +2,7 @@
>>   /* generated from http://www.unicode.org/Public/6.0.0/ucd/BidiMirroring.txt */
>>   /* DO NOT EDIT!! */
>>
>> -#include <wine/unicode.h>
>> +#include "wine/unicode.h"
>>
>>   const WCHAR wine_mirror_map[3292] =
>>   {
>>
>> Modified: trunk/reactos/dll/win32/usp10/opentype.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/opentype.c?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/opentype.c [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/opentype.c [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -21,17 +21,17 @@
>>   #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 "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>
>> +#include "wine/debug.h"
>>
>>   WINE_DEFAULT_DEBUG_CHANNEL(uniscribe);
>>
>> @@ -76,8 +76,6 @@
>>   } CMAP_SegmentedCoverage;
>>
>>   /* These are all structures needed for the GDEF table */
>> -#define GDEF_TAG MS_MAKE_TAG('G', 'D', 'E', 'F')
>> -
>>   enum {BaseGlyph=1, LigatureGlyph, MarkGlyph, ComponentGlyph};
>>
>>   typedef struct {
>> @@ -93,19 +91,19 @@
>>       WORD StartGlyph;
>>       WORD GlyphCount;
>>       WORD ClassValueArray[1];
>> -} GDEF_ClassDefFormat1;
>> +} OT_ClassDefFormat1;
>>
>>   typedef struct {
>>       WORD Start;
>>       WORD End;
>>       WORD Class;
>> -} GDEF_ClassRangeRecord;
>> +} OT_ClassRangeRecord;
>>
>>   typedef struct {
>>       WORD ClassFormat;
>>       WORD ClassRangeCount;
>> -    GDEF_ClassRangeRecord ClassRangeRecord[1];
>> -} GDEF_ClassDefFormat2;
>> +    OT_ClassRangeRecord ClassRangeRecord[1];
>> +} OT_ClassDefFormat2;
>>
>>   /* These are all structures needed for the GSUB table */
>>
>> @@ -352,6 +350,18 @@
>>   } 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];
>> @@ -361,6 +371,18 @@
>>       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;
>> @@ -392,6 +414,29 @@
>>
>>   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;
>> @@ -525,20 +570,13 @@
>>    * GDEF
>>    **********/
>>
>> -static WORD GDEF_get_glyph_class(const GDEF_Header *header, WORD glyph)
>> -{
>> -    int offset;
>> +static WORD OT_get_glyph_class(const void *table, WORD glyph)
>> +{
>>       WORD class = 0;
>> -    const GDEF_ClassDefFormat1 *cf1;
>> -
>> -    if (!header)
>> -        return 0;
>> -
>> -    offset = GET_BE_WORD(header->GlyphClassDef);
>> -    if (!offset)
>> -        return 0;
>> -
>> -    cf1 = (GDEF_ClassDefFormat1*)(((BYTE*)header)+offset);
>> +    const OT_ClassDefFormat1 *cf1 = table;
>> +
>> +    if (!table) return 0;
>> +
>>       if (GET_BE_WORD(cf1->ClassFormat) == 1)
>>       {
>>           if (glyph >= GET_BE_WORD(cf1->StartGlyph))
>> @@ -550,7 +588,7 @@
>>       }
>>       else if (GET_BE_WORD(cf1->ClassFormat) == 2)
>>       {
>> -        const GDEF_ClassDefFormat2 *cf2 = (GDEF_ClassDefFormat2*)cf1;
>> +        const OT_ClassDefFormat2 *cf2 = table;
>>           int i, top;
>>           top = GET_BE_WORD(cf2->ClassRangeCount);
>>           for (i = 0; i < top; i++)
>> @@ -569,25 +607,18 @@
>>       return class;
>>   }
>>
>> -static VOID *load_gdef_table(HDC hdc)
>> -{
>> -    VOID* GDEF_Table = NULL;
>> -    int length = GetFontData(hdc, GDEF_TAG , 0, NULL, 0);
>> -    if (length != GDI_ERROR)
>> -    {
>> -        GDEF_Table = HeapAlloc(GetProcessHeap(),0,length);
>> -        GetFontData(hdc, GDEF_TAG , 0, GDEF_Table, length);
>> -        TRACE("Loaded GDEF table of %i bytes\n",length);
>> -    }
>> -    return GDEF_Table;
>> -}
>> -
>> -void OpenType_GDEF_UpdateGlyphProps(HDC hdc, ScriptCache *psc, const WORD *pwGlyphs, const WORD cGlyphs, WORD* pwLogClust, const WORD cChars, SCRIPT_GLYPHPROP *pGlyphProp)
>> +void OpenType_GDEF_UpdateGlyphProps(ScriptCache *psc, const WORD *pwGlyphs, const WORD cGlyphs, WORD* pwLogClust, const WORD cChars, SCRIPT_GLYPHPROP *pGlyphProp)
>>   {
>>       int i;
>> -
>> -    if (!psc->GDEF_Table)
>> -        psc->GDEF_Table = load_gdef_table(hdc);
>> +    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++)
>>       {
>> @@ -602,7 +633,7 @@
>>                   char_count++;
>>           }
>>
>> -        class = GDEF_get_glyph_class(psc->GDEF_Table, pwGlyphs[i]);
>> +        class = OT_get_glyph_class( glyph_class_table, pwGlyphs[i] );
>>
>>           switch (class)
>>           {
>> @@ -1023,7 +1054,8 @@
>>   /**********
>>    * GPOS
>>    **********/
>> -static INT GPOS_apply_lookup(LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, INT* piAdvance, const OT_LookupList* lookup, INT lookup_index, const WORD *glyphs, INT glyph_index, INT write_dir, INT glyph_count, GOFFSET *pGoffset);
>> +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)
>>   {
>> @@ -1110,14 +1142,14 @@
>>   static INT GPOS_get_value_record(WORD ValueFormat, const WORD data[], GPOS_ValueRecord *record)
>>   {
>>       INT offset = 0;
>> -    if (ValueFormat & 0x0001) record->XPlacement = GET_BE_WORD(data[offset++]);
>> -    if (ValueFormat & 0x0002) record->YPlacement = GET_BE_WORD(data[offset++]);
>> -    if (ValueFormat & 0x0004) record->XAdvance = GET_BE_WORD(data[offset++]);
>> -    if (ValueFormat & 0x0008) record->YAdvance = GET_BE_WORD(data[offset++]);
>> -    if (ValueFormat & 0x0010) record->XPlaDevice = GET_BE_WORD(data[offset++]);
>> -    if (ValueFormat & 0x0020) record->YPlaDevice = GET_BE_WORD(data[offset++]);
>> -    if (ValueFormat & 0x0040) record->XAdvDevice = GET_BE_WORD(data[offset++]);
>> -    if (ValueFormat & 0x0080) record->YAdvDevice = GET_BE_WORD(data[offset++]);
>> +    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;
>>   }
>>
>> @@ -1134,7 +1166,8 @@
>>       if (ValueFormat & 0xFF00) FIXME("Unhandled Value Format %x\n",ValueFormat&0xFF00);
>>   }
>>
>> -static VOID GPOS_apply_SingleAdjustment(const OT_LookupTable *look, const WORD *glyphs, INT glyph_index, INT write_dir, INT glyph_count, INT ppem, LPPOINT ptAdjust, LPPOINT ptAdvance)
>> +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;
>>
>> @@ -1184,9 +1217,37 @@
>>       }
>>   }
>>
>> -static INT GPOS_apply_PairAdjustment(const OT_LookupTable *look, const WORD *glyphs, INT glyph_index, INT write_dir, INT glyph_count, INT ppem, LPPOINT ptAdjust, LPPOINT ptAdvance)
>> +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 %i,%i design units\n", adjust[0].x, adjust[0].y );
>> +        TRACE( "Glyph 1 resulting cumulative advance is %i,%i design units\n", advance[0].x, advance[0].y );
>> +    }
>> +    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 %i,%i design units\n", adjust[1].x, adjust[1].y );
>> +        TRACE( "Glyph 2 resulting cumulative advance is %i,%i design units\n", advance[1].x, advance[1].y );
>> +    }
>> +}
>> +
>> +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");
>>
>> @@ -1198,6 +1259,10 @@
>>           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))
>> @@ -1205,40 +1270,54 @@
>>                   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(ps->PairValueRecord[k].SecondGlyph);
>> +                    WORD second_glyph = GET_BE_WORD(pair_val_rec->SecondGlyph);
>>                       if (glyphs[glyph_index+write_dir] == second_glyph)
>>                       {
>>                           int next = 1;
>> -                        GPOS_ValueRecord ValueRecord1 = {0,0,0,0,0,0,0,0};
>> -                        GPOS_ValueRecord ValueRecord2 = {0,0,0,0,0,0,0,0};
>> -                        WORD ValueFormat1 = GET_BE_WORD(ppf1->ValueFormat1);
>> -                        WORD ValueFormat2 = GET_BE_WORD(ppf1->ValueFormat2);
>> -
>>                           TRACE("Format 1: Found Pair %x,%x\n",glyphs[glyph_index],glyphs[glyph_index+write_dir]);
>> -
>> -                        offset = GPOS_get_value_record(ValueFormat1, ps->PairValueRecord[k].Value1, &ValueRecord1);
>> -                        GPOS_get_value_record(ValueFormat2, (WORD*)((const BYTE*)(ps->PairValueRecord[k].Value2)+offset), &ValueRecord2);
>> -                        if (ValueFormat1)
>> -                        {
>> -                            GPOS_get_value_record_offsets((const BYTE*)ppf1, &ValueRecord1,  ValueFormat1, ppem, &ptAdjust[0], &ptAdvance[0]);
>> -                            TRACE("Glyph 1 resulting cumulative offset is %i,%i design units\n",ptAdjust[0].x,ptAdjust[0].y);
>> -                            TRACE("Glyph 1 resulting cumulative advance is %i,%i design units\n",ptAdvance[0].x,ptAdvance[0].y);
>> -                        }
>> -                        if (ValueFormat2)
>> -                        {
>> -                            GPOS_get_value_record_offsets((const BYTE*)ppf1, &ValueRecord2,  ValueFormat2, ppem, &ptAdjust[1], &ptAdvance[1]);
>> -                            TRACE("Glyph 2 resulting cumulative offset is %i,%i design units\n",ptAdjust[1].x,ptAdjust[1].y);
>> -                            TRACE("Glyph 2 resulting cumulative advance is %i,%i design units\n",ptAdvance[1].x,ptAdvance[1].y);
>> -                            next++;
>> -                        }
>> -                        if (next)
>> -                            return glyph_index + next;
>> +                        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*)((const BYTE*)look + offset);
>> +            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;
>>                   }
>>               }
>>           }
>> @@ -1248,9 +1327,63 @@
>>       return glyph_index+1;
>>   }
>>
>> -static VOID GPOS_apply_MarkToBase(const OT_LookupTable *look, const WORD *glyphs, INT glyph_index, INT write_dir, INT glyph_count, INT ppem, LPPOINT pt)
>> +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;
>> +        WORD offset = GET_BE_WORD(look->SubTable[j]);
>> +        cpf1 = (const GPOS_CursivePosFormat1*)((const BYTE*)look+offset);
>> +        if (GET_BE_WORD(cpf1->PosFormat) == 1)
>> +        {
>> +            int index_exit, index_entry;
>> +            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[%i,%i] %x[%i,%i]\n",glyphs[glyph_index], exit_pt.x,exit_pt.y, glyphs[glyph_index+write_dir], entry_pt.x, entry_pt.y);
>> +                    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");
>>
>> @@ -1268,8 +1401,16 @@
>>               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[glyph_index - write_dir]);
>> +                base_index = GSUB_is_glyph_covered((const BYTE*)mbpf1+offset, glyphs[base_glyph]);
>>                   if (base_index != -1)
>>                   {
>>                       const GPOS_MarkArray *ma;
>> @@ -1281,13 +1422,13 @@
>>                       int baserecord_size;
>>                       POINT base_pt;
>>                       POINT mark_pt;
>> -                    TRACE("Mark %x(%i) and base %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[glyph_index - write_dir], base_index);
>> +                    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 exeeded mark count\n");
>> -                        return;
>> +                        return -1;
>>                       }
>>                       mr = &ma->MarkRecord[mark_index];
>>                       mark_class = GET_BE_WORD(mr->Class);
>> @@ -1305,17 +1446,115 @@
>>                       pt->x += base_pt.x - mark_pt.x;
>>                       pt->y += base_pt.y - mark_pt.y;
>>                       TRACE("Resulting cumulative offset is %i,%i design units\n",pt->x,pt->y);
>> +                    rc = base_glyph;
>>                   }
>>               }
>>           }
>>           else
>>               FIXME("Unhandled Mark To Base Format %i\n",GET_BE_WORD(mbpf1->PosFormat));
>>       }
>> -}
>> -
>> -static VOID GPOS_apply_MarkToMark(const OT_LookupTable *look, const WORD *glyphs, INT glyph_index, INT write_dir, INT glyph_count, INT ppem, LPPOINT pt)
>> +    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++)
>> +    {
>> +        int offset;
>> +        const GPOS_MarkLigPosFormat1 *mlpf1;
>> +        offset = GET_BE_WORD(look->SubTable[j]);
>> +        mlpf1 = (const GPOS_MarkLigPosFormat1*)((const BYTE*)look+offset);
>> +        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 exeeded 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 exeeded 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 %i,%i design units\n",ligature_pt.x,ligature_pt.y);
>> +                    TRACE("Offset on mark is %i,%i design units\n",mark_pt.x, mark_pt.y);
>> +                    pt->x += ligature_pt.x - mark_pt.x;
>> +                    pt->y += ligature_pt.y - mark_pt.y;
>> +                    TRACE("Resulting cumulative offset is %i,%i design units\n",pt->x,pt->y);
>> +                }
>> +            }
>> +        }
>> +        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");
>>
>> @@ -1352,7 +1591,7 @@
>>                       if (mark_index > GET_BE_WORD(ma->MarkCount))
>>                       {
>>                           ERR("Mark index exeeded mark count\n");
>> -                        return;
>> +                        return FALSE;
>>                       }
>>                       mr = &ma->MarkRecord[mark_index];
>>                       mark_class = GET_BE_WORD(mr->Class);
>> @@ -1370,17 +1609,22 @@
>>                       pt->x += mark2_pt.x - mark_pt.x;
>>                       pt->y += mark2_pt.y - mark_pt.y;
>>                       TRACE("Resulting cumulative offset is %i,%i design units\n",pt->x,pt->y);
>> +                    rc = TRUE;
>>                   }
>>               }
>>           }
>>           else
>>               FIXME("Unhandled Mark To Mark Format %i\n",GET_BE_WORD(mmpf1->PosFormat));
>>       }
>> -}
>> -
>> -static INT GPOS_apply_ChainContextPos(LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, INT* piAdvance, const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, INT glyph_index, INT write_dir, INT glyph_count, INT ppem, GOFFSET *pGoffset)
>> +    return rc;
>> +}
>> +
>> +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");
>>
>> @@ -1462,7 +1706,7 @@
>>                       int SequenceIndex = GET_BE_WORD(ccpf3_4->PosLookupRecord[k].SequenceIndex) * write_dir;
>>
>>                       TRACE("Position: %i -> %i %i\n",k, SequenceIndex, lookupIndex);
>> -                    GPOS_apply_lookup(lpotm, lplogfont, piAdvance, lookup, lookupIndex, glyphs, glyph_index + SequenceIndex, write_dir, glyph_count, pGoffset);
>> +                    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);
>>               }
>> @@ -1474,7 +1718,7 @@
>>       return glyph_index + 1;
>>   }
>>
>> -static INT GPOS_apply_lookup(LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, INT* piAdvance, const OT_LookupList* lookup, INT lookup_index, const WORD *glyphs, INT glyph_index, INT write_dir, INT glyph_count, GOFFSET *pGoffset)
>> +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;
>> @@ -1490,7 +1734,7 @@
>>               double devX, devY;
>>               POINT adjust = {0,0};
>>               POINT advance = {0,0};
>> -            GPOS_apply_SingleAdjustment(look, glyphs, glyph_index, write_dir, glyph_count, ppem, &adjust, &advance);
>> +            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);
>> @@ -1512,11 +1756,14 @@
>>               POINT adjust[2]= {{0,0},{0,0}};
>>               double devX, devY;
>>               int index;
>> -            index = GPOS_apply_PairAdjustment(look, glyphs, glyph_index, write_dir, glyph_count, ppem, adjust, advance);
>> +            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);
>> +                pGoffset[glyph_index].du += round(devX) * offset_sign;
>>                   pGoffset[glyph_index].dv += round(devY);
>>               }
>>               if (advance[0].x || advance[0].y)
>> @@ -1527,7 +1774,7 @@
>>               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);
>> +                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)
>> @@ -1537,35 +1784,69 @@
>>               }
>>               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};
>> -            GPOS_apply_MarkToBase(look, glyphs, glyph_index, write_dir, glyph_count, ppem, &desU);
>> -            if (desU.x || desU.y)
>> +            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);
>> -                pGoffset[glyph_index].du += (round(devX) - piAdvance[glyph_index-1]);
>> -                pGoffset[glyph_index].dv += round(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 6:
>> +        case 5:
>>           {
>>               double devX, devY;
>>               POINT desU = {0,0};
>> -            GPOS_apply_MarkToMark(look, glyphs, glyph_index, write_dir, glyph_count, ppem, &desU);
>> +            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) + pGoffset[glyph_index-1].du;
>> -                pGoffset[glyph_index].dv += round(devY) + pGoffset[glyph_index-1].dv;
>> +                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 8:
>>           {
>> -            return GPOS_apply_ChainContextPos(lpotm, lplogfont, piAdvance, lookup, look, glyphs, glyph_index, write_dir, glyph_count, ppem, pGoffset);
>> +            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",GET_BE_WORD(look->LookupType));
>> @@ -1573,12 +1854,12 @@
>>       return glyph_index+1;
>>   }
>>
>> -INT OpenType_apply_GPOS_lookup(LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, INT* piAdvance, LPCVOID table, INT lookup_index, const WORD *glyphs, INT glyph_index, INT write_dir, INT glyph_count, GOFFSET *pGoffset)
>> -{
>> -    const GPOS_Header *header = (const GPOS_Header *)table;
>> +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(lpotm, lplogfont, piAdvance, lookup, lookup_index, glyphs, glyph_index, write_dir, glyph_count, pGoffset);
>> +    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)
>> @@ -1617,6 +1898,9 @@
>>       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;
>> @@ -1660,10 +1944,11 @@
>>
>>   static void _initialize_script_cache(ScriptCache *psc)
>>   {
>> -    if (!psc->script_count)
>> +    if (!psc->scripts_initialized)
>>       {
>>           GSUB_initialize_script_cache(psc);
>>           GPOS_expand_script_cache(psc);
>> +        psc->scripts_initialized = TRUE;
>>       }
>>   }
>>
>> @@ -1748,6 +2033,10 @@
>>       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;
>> @@ -1791,10 +2080,11 @@
>>
>>   static void _initialize_language_cache(LoadedScript *script)
>>   {
>> -    if (!script->language_count)
>> +    if (!script->languages_initialized)
>>       {
>>           GSUB_initialize_language_cache(script);
>>           GPOS_expand_language_cache(script);
>> +        script->languages_initialized = TRUE;
>>       }
>>   }
>>
>> @@ -1893,6 +2183,7 @@
>>                   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;
>>               }
>>           }
>>       }
>> @@ -1912,6 +2203,10 @@
>>       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;
>> @@ -1933,10 +2228,11 @@
>>                   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]);
>> -            }
>> -        }
>> -    }
>> -    else if (count)
>> +                language->features[i].tableType = FEATURE_GPOS_TABLE;
>> +            }
>> +        }
>> +    }
>> +    else
>>       {
>>           language->features = HeapReAlloc(GetProcessHeap(),0,language->features, sizeof(LoadedFeature)*(language->feature_count + count));
>>
>> @@ -1954,6 +2250,7 @@
>>               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;
>>       }
>> @@ -1961,14 +2258,15 @@
>>
>>   static void _initialize_feature_cache(ScriptCache *psc, LoadedLanguage *language)
>>   {
>> -    if (!language->feature_count)
>> +    if (!language->features_initialized)
>>       {
>>           GSUB_initialize_feature_cache(psc->GSUB_Table, language);
>>           GPOS_expand_feature_cache(psc->GPOS_Table, language);
>> -    }
>> -}
>> -
>> -HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature** feature)
>> +        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;
>> @@ -2019,7 +2317,15 @@
>>
>>       _initialize_feature_cache(psc, language);
>>
>> -    *pcTags = language->feature_count;
>> +    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;
>> @@ -2029,11 +2335,15 @@
>>       for (i = 0; i < language->feature_count; i++)
>>       {
>>           if (i < cMaxTags)
>> -            pFeatureTags[i] = language->features[i].tag;
>> +        {
>> +            if (!tableType || language->features[i].tableType == tableType)
>> +                pFeatureTags[i] = language->features[i].tag;
>> +        }
>>
>>           if (searchingFor)
>>           {
>> -            if (searchingFor == language->features[i].tag)
>> +            if ((searchingFor == language->features[i].tag) &&
>> +                (!tableType || language->features[i].tableType == tableType))
>>               {
>>                   pFeatureTags[0] = language->features[i].tag;
>>                   *pcTags = 1;
>>
>> Modified: trunk/reactos/dll/win32/usp10/shape.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/shape.c?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/shape.c [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/shape.c [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -19,19 +19,19 @@
>>    *
>>    */
>>   #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 <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>
>> +#include "wine/debug.h"
>>
>>   WINE_DEFAULT_DEBUG_CHANNEL(uniscribe);
>>
>> @@ -41,6 +41,7 @@
>>   typedef VOID (*ContextualShapingProc)(HDC, ScriptCache*, SCRIPT_ANALYSIS*,
>>                                         WCHAR*, INT, WORD*, INT*, INT, WORD*);
>>
>> +static void ContextualShape_Control(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust);
>>   static void ContextualShape_Arabic(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust);
>>   static void ContextualShape_Hebrew(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust);
>>   static void ContextualShape_Syriac(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust);
>> @@ -63,7 +64,9 @@
>>
>>   typedef VOID (*ShapeCharGlyphPropProc)( HDC , ScriptCache*, SCRIPT_ANALYSIS*, const WCHAR*, const INT, const WORD*, const INT, WORD*, SCRIPT_CHARPROP*, SCRIPT_GLYPHPROP*);
>>
>> -static void ShapeCharGlyphProp_Default( HDC hdc, ScriptCache* psc, SCRIPT_ANALYSIS* psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD* pwLogClust, SCRIPT_CHARPROP* pCharProp, SCRIPT_GLYPHPROP* pGlyphProp);
>> +static void ShapeCharGlyphProp_Default( ScriptCache* psc, SCRIPT_ANALYSIS* psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD* pwLogClust, SCRIPT_CHARPROP* pCharProp, SCRIPT_GLYPHPROP* pGlyphProp);
>> +static void ShapeCharGlyphProp_Control( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP* pCharProp, SCRIPT_GLYPHPROP *pGlyphProp );
>> +static void ShapeCharGlyphProp_Latin( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP* pCharProp, SCRIPT_GLYPHPROP *pGlyphProp );
>>   static void ShapeCharGlyphProp_Arabic( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP* pCharProp, SCRIPT_GLYPHPROP *pGlyphProp );
>>   static void ShapeCharGlyphProp_Hebrew( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP* pCharProp, SCRIPT_GLYPHPROP *pGlyphProp );
>>   static void ShapeCharGlyphProp_Thai( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProp, SCRIPT_GLYPHPROP *pGlyphProp );
>> @@ -142,6 +145,8 @@
>>
>>   static OPENTYPE_FEATURE_RECORD latin_features[] =
>>   {
>> +    { MS_MAKE_TAG('l','o','c','l'), 1},
>> +    { MS_MAKE_TAG('c','c','m','p'), 1},
>>       { MS_MAKE_TAG('l','i','g','a'), 1},
>>       { MS_MAKE_TAG('c','l','i','g'), 1},
>>   };
>> @@ -182,6 +187,7 @@
>>
>>   static OPENTYPE_FEATURE_RECORD hebrew_features[] =
>>   {
>> +    { MS_MAKE_TAG('c','c','m','p'), 1},
>>       { MS_MAKE_TAG('d','l','i','g'), 0},
>>   };
>>
>> @@ -450,14 +456,14 @@
>>   static const ScriptShapeData ShapingData[] =
>>   {
>>       {{ standard_features, 2}, {NULL, 0}, NULL, 0, NULL, NULL},
>> -    {{ latin_features, 2}, {latin_gpos_features, 3}, NULL, 0, NULL, NULL},
>> -    {{ latin_features, 2}, {latin_gpos_features, 3}, NULL, 0, NULL, NULL},
>> -    {{ latin_features, 2}, {latin_gpos_features, 3}, NULL, 0, NULL, NULL},
>> -    {{ standard_features, 2}, {NULL, 0}, NULL, 0, NULL, NULL},
>> -    {{ latin_features, 2}, {latin_gpos_features, 3}, NULL, 0, NULL, NULL},
>> +    {{ latin_features, 4}, {latin_gpos_features, 3}, NULL, 0, NULL, ShapeCharGlyphProp_Latin},
>> +    {{ latin_features, 4}, {latin_gpos_features, 3}, NULL, 0, NULL, ShapeCharGlyphProp_Latin},
>> +    {{ latin_features, 4}, {latin_gpos_features, 3}, NULL, 0, NULL, ShapeCharGlyphProp_Latin},
>> +    {{ standard_features, 2}, {NULL, 0}, NULL, 0, ContextualShape_Control, ShapeCharGlyphProp_Control},
>> +    {{ latin_features, 4}, {latin_gpos_features, 3}, NULL, 0, NULL, ShapeCharGlyphProp_Latin},
>>       {{ arabic_features, 6}, {arabic_gpos_features, 4}, required_arabic_features, 0, ContextualShape_Arabic, ShapeCharGlyphProp_Arabic},
>>       {{ arabic_features, 6}, {arabic_gpos_features, 4}, required_arabic_features, 0, ContextualShape_Arabic, ShapeCharGlyphProp_Arabic},
>> -    {{ hebrew_features, 1}, {hebrew_gpos_features, 2}, NULL, 0, ContextualShape_Hebrew, ShapeCharGlyphProp_Hebrew},
>> +    {{ hebrew_features, 2}, {hebrew_gpos_features, 2}, NULL, 0, ContextualShape_Hebrew, ShapeCharGlyphProp_Hebrew},
>>       {{ syriac_features, 4}, {syriac_gpos_features, 3}, required_syriac_features, 0, ContextualShape_Syriac, ShapeCharGlyphProp_None},
>>       {{ arabic_features, 6}, {arabic_gpos_features, 4}, required_arabic_features, 0, ContextualShape_Arabic, ShapeCharGlyphProp_Arabic},
>>       {{ NULL, 0}, {NULL, 0}, NULL, 0, ContextualShape_Thaana, ShapeCharGlyphProp_None},
>> @@ -494,7 +500,7 @@
>>       {{ devanagari_features, 6}, {devanagari_gpos_features, 4}, required_telugu_features, MS_MAKE_TAG('m','l','m','2'), ContextualShape_Malayalam, ShapeCharGlyphProp_Malayalam},
>>       {{ devanagari_features, 6}, {devanagari_gpos_features, 4}, required_telugu_features, MS_MAKE_TAG('m','l','m','2'), ContextualShape_Malayalam, NULL},
>>       {{ standard_features, 2}, {NULL, 0}, NULL, 0, NULL, NULL},
>> -    {{ latin_features, 2}, {latin_gpos_features, 3}, NULL, 0, NULL, NULL},
>> +    {{ latin_features, 4}, {latin_gpos_features, 3}, NULL, 0, NULL, ShapeCharGlyphProp_Latin},
>>       {{ standard_features, 2}, {NULL, 0}, NULL, 0, NULL, NULL},
>>       {{ myanmar_features, 2}, {NULL, 0}, NULL, 0, NULL, NULL},
>>       {{ myanmar_features, 2}, {NULL, 0}, NULL, 0, NULL, NULL},
>> @@ -528,8 +534,8 @@
>>       {{ NULL, 0}, {NULL, 0}, NULL, 0, NULL, NULL},
>>       {{ NULL, 0}, {NULL, 0}, NULL, 0, NULL, NULL},
>>       {{ NULL, 0}, {NULL, 0}, NULL, 0, NULL, NULL},
>> -    {{ hebrew_features, 1}, {hebrew_gpos_features, 2}, NULL, 0, ContextualShape_Hebrew, NULL},
>> -    {{ latin_features, 2}, {latin_gpos_features, 3}, NULL, 0, NULL, NULL},
>> +    {{ hebrew_features, 2}, {hebrew_gpos_features, 2}, NULL, 0, ContextualShape_Hebrew, NULL},
>> +    {{ latin_features, 4}, {latin_gpos_features, 3}, NULL, 0, NULL, ShapeCharGlyphProp_Latin},
>>       {{ thai_features, 1}, {thai_gpos_features, 3}, NULL, 0, ContextualShape_Thai, ShapeCharGlyphProp_Thai},
>>   };
>>
>> @@ -602,7 +608,7 @@
>>       }
>>   }
>>
>> -static LoadedFeature* load_OT_feature(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache *psc, const char* feat)
>> +static LoadedFeature* load_OT_feature(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache *psc, char tableType, const char* feat)
>>   {
>>       LoadedFeature *feature = NULL;
>>
>> @@ -611,7 +617,7 @@
>>           int attempt = 2;
>>           OPENTYPE_TAG tags;
>>           OPENTYPE_TAG language;
>> -        OPENTYPE_TAG script;
>> +        OPENTYPE_TAG script = 0x00000000;
>>           int cTags;
>>
>>           do
>> @@ -623,13 +629,13 @@
>>                   language = MS_MAKE_TAG('d','f','l','t');
>>               attempt--;
>>
>> -            OpenType_GetFontFeatureTags(psc, script, language, FALSE, MS_MAKE_TAG(feat[0],feat[1],feat[2],feat[3]), 1, &tags, &cTags, &feature);
>> +            OpenType_GetFontFeatureTags(psc, script, language, FALSE, MS_MAKE_TAG(feat[0],feat[1],feat[2],feat[3]), tableType, 1, &tags, &cTags, &feature);
>>
>>           } while(attempt && !feature);
>>
>>           /* try in the default (latin) table */
>> -        if (!feature)
>> -            OpenType_GetFontFeatureTags(psc, MS_MAKE_TAG('l','a','t','n'), MS_MAKE_TAG('d','f','l','t'), FALSE, MS_MAKE_TAG(feat[0],feat[1],feat[2],feat[3]), 1, &tags, &cTags, &feature);
>> +        if (!feature && !script)
>> +            OpenType_GetFontFeatureTags(psc, MS_MAKE_TAG('l','a','t','n'), MS_MAKE_TAG('d','f','l','t'), FALSE, MS_MAKE_TAG(feat[0],feat[1],feat[2],feat[3]), tableType, 1, &tags, &cTags, &feature);
>>       }
>>
>>       TRACE("Feature %s located at %p\n",debugstr_an(feat,4),feature);
>> @@ -640,7 +646,7 @@
>>   {
>>       LoadedFeature *feature;
>>
>> -    feature = load_OT_feature(hdc, psa, psc, feat);
>> +    feature = load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, feat);
>>       if (!feature)
>>           return GSUB_E_NOFEATURE;
>>
>> @@ -672,6 +678,19 @@
>>           TRACE("Loaded GPOS table of %i bytes\n",length);
>>       }
>>       return GPOS_Table;
>> +}
>> +
>> +static VOID *load_gdef_table(HDC hdc)
>> +{
>> +    VOID* GDEF_Table = NULL;
>> +    int length = GetFontData(hdc, MS_MAKE_TAG('G', 'D', 'E', 'F'), 0, NULL, 0);
>> +    if (length != GDI_ERROR)
>> +    {
>> +        GDEF_Table = HeapAlloc(GetProcessHeap(),0,length);
>> +        GetFontData(hdc, MS_MAKE_TAG('G', 'D', 'E', 'F'), 0, GDEF_Table, length);
>> +        TRACE("Loaded GDEF table of %i bytes\n",length);
>> +    }
>> +    return GDEF_Table;
>>   }
>>
>>   static VOID load_ot_tables(HDC hdc, ScriptCache *psc)
>> @@ -680,6 +699,8 @@
>>           psc->GSUB_Table = load_gsub_table(hdc);
>>       if (!psc->GPOS_Table)
>>           psc->GPOS_Table = load_gpos_table(hdc);
>> +    if (!psc->GDEF_Table)
>> +        psc->GDEF_Table = load_gdef_table(hdc);
>>   }
>>
>>   INT SHAPE_does_GSUB_feature_apply_to_chars(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, const WCHAR *chars, INT write_dir, INT count, const char* feature)
>> @@ -825,7 +846,7 @@
>>           LoadedFeature *feature;
>>           int lookup_index;
>>
>> -        feature = load_OT_feature(hdc, psa, psc, feat);
>> +        feature = load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, feat);
>>           if (!feature)
>>               return GSUB_E_NOFEATURE;
>>
>> @@ -859,7 +880,7 @@
>>       return GSUB_E_NOFEATURE;
>>   }
>>
>> -static VOID GPOS_apply_feature(LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, INT* piAdvance, LPCVOID header, LoadedFeature *feature, const WORD *glyphs, INT write_dir, INT glyph_count, GOFFSET *pGoffset)
>> +static VOID GPOS_apply_feature(ScriptCache *psc, LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, const SCRIPT_ANALYSIS *analysis, INT* piAdvance, LoadedFeature *feature, const WORD *glyphs, INT glyph_count, GOFFSET *pGoffset)
>>   {
>>       int i;
>>
>> @@ -868,7 +889,7 @@
>>       {
>>           int j;
>>           for (j = 0; j < glyph_count; )
>> -            j = OpenType_apply_GPOS_lookup(lpotm, lplogfont, piAdvance, header, feature->lookups[i], glyphs, j, write_dir, glyph_count, pGoffset);
>> +            j = OpenType_apply_GPOS_lookup(psc, lpotm, lplogfont, analysis, piAdvance, feature->lookups[i], glyphs, j, glyph_count, pGoffset);
>>       }
>>   }
>>
>> @@ -920,6 +941,23 @@
>>       }
>>
>>       HeapFree(GetProcessHeap(),0,context_type);
>> +}
>> +
>> +static void ContextualShape_Control(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust)
>> +{
>> +    int i;
>> +    for (i=0; i < cChars; i++)
>> +    {
>> +        switch (pwcChars[i])
>> +        {
>> +            case 0x000D: pwOutGlyphs[i] = psc->sfp.wgBlank; break;
>> +            default:
>> +                if (pwcChars[i] < 0x1C)
>> +                    pwOutGlyphs[i] = psc->sfp.wgDefault;
>> +                else
>> +                    pwOutGlyphs[i] = psc->sfp.wgBlank;
>> +        }
>> +    }
>>   }
>>
>>   static WCHAR neighbour_char(int i, int delta, const WCHAR* chars, INT cchLen)
>> @@ -2020,17 +2058,17 @@
>>   {
>>       int c;
>>       int overall_shift = 0;
>> -    LoadedFeature *locl = (modern)?load_OT_feature(hdc, psa, psc, "locl"):NULL;
>> -    LoadedFeature *nukt = load_OT_feature(hdc, psa, psc, "nukt");
>> -    LoadedFeature *akhn = load_OT_feature(hdc, psa, psc, "akhn");
>> -    LoadedFeature *rkrf = (modern)?load_OT_feature(hdc, psa, psc, "rkrf"):NULL;
>> -    LoadedFeature *pstf = load_OT_feature(hdc, psa, psc, "pstf");
>> -    LoadedFeature *vatu = (!rkrf)?load_OT_feature(hdc, psa, psc, "vatu"):NULL;
>> -    LoadedFeature *cjct = (modern)?load_OT_feature(hdc, psa, psc, "cjct"):NULL;
>> -    BOOL rphf = (load_OT_feature(hdc, psa, psc, "rphf") != NULL);
>> -    BOOL pref = (load_OT_feature(hdc, psa, psc, "pref") != NULL);
>> -    BOOL blwf = (load_OT_feature(hdc, psa, psc, "blwf") != NULL);
>> -    BOOL half = (load_OT_feature(hdc, psa, psc, "half") != NULL);
>> +    LoadedFeature *locl = (modern)?load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "locl"):NULL;
>> +    LoadedFeature *nukt = load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "nukt");
>> +    LoadedFeature *akhn = load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "akhn");
>> +    LoadedFeature *rkrf = (modern)?load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "rkrf"):NULL;
>> +    LoadedFeature *pstf = load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "pstf");
>> +    LoadedFeature *vatu = (!rkrf)?load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "vatu"):NULL;
>> +    LoadedFeature *cjct = (modern)?load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "cjct"):NULL;
>> +    BOOL rphf = (load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "rphf") != NULL);
>> +    BOOL pref = (load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "pref") != NULL);
>> +    BOOL blwf = (load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "blwf") != NULL);
>> +    BOOL half = (load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "half") != NULL);
>>       IndicSyllable glyph_indexs;
>>
>>       for (c = 0; c < syllable_count; c++)
>> @@ -2739,8 +2777,6 @@
>>       else
>>           dirL = 1;
>>
>> -    load_ot_tables(hdc, psc);
>> -
>>       if (!psc->GSUB_Table)
>>           return;
>>
>> @@ -2783,7 +2819,7 @@
>>       HeapFree(GetProcessHeap(),0,context_shape);
>>   }
>>
>> -static void ShapeCharGlyphProp_Default( HDC hdc, ScriptCache* psc, SCRIPT_ANALYSIS* psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD* pwLogClust, SCRIPT_CHARPROP* pCharProp, SCRIPT_GLYPHPROP* pGlyphProp)
>> +static void ShapeCharGlyphProp_Default( ScriptCache* psc, SCRIPT_ANALYSIS* psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD* pwLogClust, SCRIPT_CHARPROP* pCharProp, SCRIPT_GLYPHPROP* pGlyphProp)
>>   {
>>       int i,k;
>>
>> @@ -2811,8 +2847,35 @@
>>               pGlyphProp[i].sva.uJustification = SCRIPT_JUSTIFY_CHARACTER;
>>       }
>>
>> -    OpenType_GDEF_UpdateGlyphProps(hdc, psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>> +    OpenType_GDEF_UpdateGlyphProps(psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>>       UpdateClustersFromGlyphProp(cGlyphs, cChars, pwLogClust, pGlyphProp);
>> +}
>> +
>> +static void ShapeCharGlyphProp_Latin( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProp, SCRIPT_GLYPHPROP *pGlyphProp )
>> +{
>> +    int i;
>> +
>> +    ShapeCharGlyphProp_Default( psc, psa, pwcChars, cChars, pwGlyphs, cGlyphs, pwLogClust, pCharProp, pGlyphProp);
>> +
>> +    for (i = 0; i < cGlyphs; i++)
>> +        if (pGlyphProp[i].sva.fZeroWidth)
>> +            pGlyphProp[i].sva.uJustification = SCRIPT_JUSTIFY_NONE;
>> +}
>> +
>> +static void ShapeCharGlyphProp_Control( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProp, SCRIPT_GLYPHPROP *pGlyphProp )
>> +{
>> +    int i;
>> +    for (i = 0; i < cGlyphs; i++)
>> +    {
>> +        pGlyphProp[i].sva.fClusterStart = 1;
>> +        pGlyphProp[i].sva.fDiacritic = 0;
>> +        pGlyphProp[i].sva.uJustification = SCRIPT_JUSTIFY_BLANK;
>> +
>> +        if (pwGlyphs[i] == psc->sfp.wgDefault)
>> +            pGlyphProp[i].sva.fZeroWidth = 0;
>> +        else
>> +            pGlyphProp[i].sva.fZeroWidth = 1;
>> +    }
>>   }
>>
>>   static void ShapeCharGlyphProp_Arabic( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProp, SCRIPT_GLYPHPROP *pGlyphProp )
>> @@ -2920,7 +2983,7 @@
>>               pGlyphProp[i].sva.uJustification = SCRIPT_JUSTIFY_NONE;
>>       }
>>
>> -    OpenType_GDEF_UpdateGlyphProps(hdc, psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>> +    OpenType_GDEF_UpdateGlyphProps(psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>>       UpdateClustersFromGlyphProp(cGlyphs, cChars, pwLogClust, pGlyphProp);
>>       HeapFree(GetProcessHeap(),0,spaces);
>>   }
>> @@ -2951,7 +3014,7 @@
>>           }
>>       }
>>
>> -    OpenType_GDEF_UpdateGlyphProps(hdc, psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>> +    OpenType_GDEF_UpdateGlyphProps(psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>>       UpdateClustersFromGlyphProp(cGlyphs, cChars, pwLogClust, pGlyphProp);
>>   }
>>
>> @@ -2972,7 +3035,7 @@
>>           dirL = 1;
>>       }
>>
>> -    OpenType_GDEF_UpdateGlyphProps(hdc, psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>> +    OpenType_GDEF_UpdateGlyphProps(psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>>
>>       for (i = 0; i < cGlyphs; i++)
>>       {
>> @@ -3040,7 +3103,7 @@
>>           else
>>               pGlyphProp[i].sva.uJustification = SCRIPT_JUSTIFY_NONE;
>>       }
>> -    OpenType_GDEF_UpdateGlyphProps(hdc, psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>> +    OpenType_GDEF_UpdateGlyphProps(psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>>       UpdateClustersFromGlyphProp(cGlyphs, cChars, pwLogClust, pGlyphProp);
>>   }
>>
>> @@ -3071,7 +3134,7 @@
>>           else
>>               pGlyphProp[i].sva.uJustification = SCRIPT_JUSTIFY_NONE;
>>       }
>> -    OpenType_GDEF_UpdateGlyphProps(hdc, psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>> +    OpenType_GDEF_UpdateGlyphProps(psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>>       UpdateClustersFromGlyphProp(cGlyphs, cChars, pwLogClust, pGlyphProp);
>>
>>       /* Tibeten script does not set sva.fDiacritic or sva.fZeroWidth */
>> @@ -3089,7 +3152,7 @@
>>   {
>>       int i,k;
>>
>> -    OpenType_GDEF_UpdateGlyphProps(hdc, psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>> +    OpenType_GDEF_UpdateGlyphProps(psc, pwGlyphs, cGlyphs, pwLogClust, cChars, pGlyphProp);
>>       for (i = 0; i < cGlyphs; i++)
>>       {
>>           int char_index[20];
>> @@ -3233,10 +3296,12 @@
>>
>>   void SHAPE_CharGlyphProp(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProp, SCRIPT_GLYPHPROP *pGlyphProp)
>>   {
>> +    load_ot_tables(hdc, psc);
>> +
>>       if (ShapingData[psa->eScript].charGlyphPropProc)
>>           ShapingData[psa->eScript].charGlyphPropProc(hdc, psc, psa, pwcChars, cChars, pwGlyphs, cGlyphs, pwLogClust, pCharProp, pGlyphProp);
>>       else
>> -        ShapeCharGlyphProp_Default(hdc, psc, psa, pwcChars, cChars, pwGlyphs, cGlyphs, pwLogClust, pCharProp, pGlyphProp);
>> +        ShapeCharGlyphProp_Default(psc, psa, pwcChars, cChars, pwGlyphs, cGlyphs, pwLogClust, pCharProp, pGlyphProp);
>>   }
>>
>>   void SHAPE_ContextualShaping(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust)
>> @@ -3284,7 +3349,6 @@
>>   {
>>       const TEXTRANGE_PROPERTIES *rpRangeProperties;
>>       int i;
>> -    INT dirL;
>>
>>       rpRangeProperties = &ShapingData[psa->eScript].defaultGPOSTextRange;
>>
>> @@ -3296,22 +3360,17 @@
>>       if (!psc->GPOS_Table || !psc->otm)
>>           return;
>>
>> -    if (!psa->fLogicalOrder && psa->fRTL)
>> -        dirL = -1;
>> -    else
>> -        dirL = 1;
>> -
>>       for (i = 0; i < rpRangeProperties->cotfRecords; i++)
>>       {
>>           if (rpRangeProperties->potfRecords[i].lParameter > 0)
>>           {
>>               LoadedFeature *feature;
>>
>> -            feature = load_OT_feature(hdc, psa, psc, (const char*)&rpRangeProperties->potfRecords[i].tagFeature);
>> +            feature = load_OT_feature(hdc, psa, psc, FEATURE_GPOS_TABLE, (const char*)&rpRangeProperties->potfRecords[i].tagFeature);
>>               if (!feature)
>>                   continue;
>>
>> -            GPOS_apply_feature(psc->otm, &psc->lf, piAdvance, psc->GPOS_Table, feature, pwGlyphs, dirL, cGlyphs, pGoffset);
>> +            GPOS_apply_feature(psc, psc->otm, &psc->lf, psa, piAdvance, feature, pwGlyphs, cGlyphs, pGoffset);
>>           }
>>       }
>>   }
>> @@ -3330,7 +3389,7 @@
>>       i = 0;
>>       while (ShapingData[psa->eScript].requiredFeatures[i])
>>       {
>> -        feature = load_OT_feature(hdc, psa, psc, ShapingData[psa->eScript].requiredFeatures[i]);
>> +        feature = load_OT_feature(hdc, psa, psc, FEATURE_ALL_TABLES, ShapingData[psa->eScript].requiredFeatures[i]);
>>           if (feature)
>>               return S_OK;
>>           i++;
>> @@ -3401,7 +3460,7 @@
>>           filter = TRUE;
>>       }
>>
>> -    hr = OpenType_GetFontFeatureTags(psc, tagScript, tagLangSys, filter, 0x00000000, cMaxTags, pFeatureTags, pcTags, NULL);
>> +    hr = OpenType_GetFontFeatureTags(psc, tagScript, tagLangSys, filter, 0x00000000, FEATURE_ALL_TABLES, cMaxTags, pFeatureTags, pcTags, NULL);
>>
>>       if (FAILED(hr))
>>           *pcTags = 0;
>>
>> Modified: trunk/reactos/dll/win32/usp10/shaping.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/shaping.c?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/shaping.c [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/shaping.c [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -2,7 +2,7 @@
>>   /* generated from http://www.unicode.org/Public/6.0.0/ucd/ArabicShaping.txt */
>>   /* DO NOT EDIT!! */
>>
>> -//#include "wine/unicode.h"
>> +#include "wine/unicode.h"
>>
>>   const unsigned short wine_shaping_table[2656] =
>>   {
>>
>> Modified: trunk/reactos/dll/win32/usp10/usp10.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/usp10.c?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/usp10.c [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/usp10.c [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -25,20 +25,20 @@
>>    */
>>
>>   #include <stdarg.h>
>> -//#include <stdlib.h>
>> -
>> -#include <windef.h>
>> -//#include "winbase.h"
>> -#include <wingdi.h>
>> -#include <winuser.h>
>> -//#include "winnls.h"
>> -#include <winreg.h>
>> -#include <usp10.h>
>> +#include <stdlib.h>
>> +
>> +#include "windef.h"
>> +#include "winbase.h"
>> +#include "wingdi.h"
>> +#include "winuser.h"
>> +#include "winnls.h"
>> +#include "winreg.h"
>> +#include "usp10.h"
>>
>>   #include "usp10_internal.h"
>>
>> -#include <wine/debug.h>
>> -#include <wine/unicode.h>
>> +#include "wine/debug.h"
>> +#include "wine/unicode.h"
>>
>>   WINE_DEFAULT_DEBUG_CHANNEL(uniscribe);
>>
>> @@ -513,7 +513,7 @@
>>        {0x53, 0, 1, 1, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
>>        MS_MAKE_TAG('k','h','m','r'),
>>        {'D','a','u','n','P','e','n','h'}},
>> -    {{Script_Khmer, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
>> +    {{Script_Khmer_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
>>        {0x53, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
>>        MS_MAKE_TAG('k','h','m','r'),
>>        {'D','a','u','n','P','e','n','h'}},
>> @@ -999,23 +999,6 @@
>>   }
>>
>>   /***********************************************************************
>> - *      DllMain
>> - *
>> - */
>> -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
>> -{
>> -    switch(fdwReason)
>> -    {
>> -    case DLL_PROCESS_ATTACH:
>> -        DisableThreadLibraryCalls(hInstDLL);
>> -        break;
>> -    case DLL_PROCESS_DETACH:
>> -        break;
>> -    }
>> -    return TRUE;
>> -}
>> -
>> -/***********************************************************************
>>    *      ScriptFreeCache (USP10.@)
>>    *
>>    * Free a script cache.
>> @@ -1060,6 +1043,9 @@
>>                       heap_free(((ScriptCache *)*psc)->scripts[i].languages[j].features[k].lookups);
>>                   heap_free(((ScriptCache *)*psc)->scripts[i].languages[j].features);
>>               }
>> +            for (j = 0; j < ((ScriptCache *)*psc)->scripts[i].default_language.feature_count; j++)
>> +                heap_free(((ScriptCache *)*psc)->scripts[i].default_language.features[j].lookups);
>> +            heap_free(((ScriptCache *)*psc)->scripts[i].default_language.features);
>>               heap_free(((ScriptCache *)*psc)->scripts[i].languages);
>>           }
>>           heap_free(((ScriptCache *)*psc)->scripts);
>> @@ -1270,28 +1256,11 @@
>>       };
>>   }
>>
>> -/***********************************************************************
>> - *      ScriptItemizeOpenType (USP10.@)
>> - *
>> - * Split a Unicode string into shapeable parts.
>> - *
>> - * PARAMS
>> - *  pwcInChars  [I] String to split.
>> - *  cInChars    [I] Number of characters in pwcInChars.
>> - *  cMaxItems   [I] Maximum number of items to return.
>> - *  psControl   [I] Pointer to a SCRIPT_CONTROL structure.
>> - *  psState     [I] Pointer to a SCRIPT_STATE structure.
>> - *  pItems      [O] Buffer to receive SCRIPT_ITEM structures.
>> - *  pScriptTags [O] Buffer to receive OPENTYPE_TAGs.
>> - *  pcItems     [O] Number of script items returned.
>> - *
>> - * RETURNS
>> - *  Success: S_OK
>> - *  Failure: Non-zero HRESULT value.
>> - */
>> -HRESULT WINAPI ScriptItemizeOpenType(const WCHAR *pwcInChars, int cInChars, int cMaxItems,
>> -                             const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState,
>> -                             SCRIPT_ITEM *pItems, OPENTYPE_TAG *pScriptTags, int *pcItems)
>> +
>> +static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
>> +                int cMaxItems, const SCRIPT_CONTROL *psControl,
>> +                const SCRIPT_STATE *psState, SCRIPT_ITEM *pItems,
>> +                OPENTYPE_TAG *pScriptTags, int *pcItems)
>>   {
>>
>>   #define Numeric_space 0x0020
>> @@ -1346,8 +1315,36 @@
>>               forceLevels = TRUE;
>>
>>           /* Diacritical marks merge with other scripts */
>> -        if (scripts[i] == Script_Diacritical && i > 0)
>> -                scripts[i] = scripts[i-1];
>> +        if (scripts[i] == Script_Diacritical)
>> +        {
>> +            if (i > 0)
>> +            {
>> +                if (pScriptTags)
>> +                    scripts[i] = scripts[i-1];
>> +                else
>> +                {
>> +                    int j;
>> +                    BOOL asian = FALSE;
>> +                    WORD first_script = scripts[i-1];
>> +                    for (j = i-1; j >= 0 &&  scripts[j] == first_script && pwcInChars[j] != Numeric_space; j--)
>> +                    {
>> +                        WORD original = scripts[j];
>> +                        if (original == Script_Ideograph || original == Script_Kana || original == Script_Yi || original == Script_CJK_Han || original == Script_Bopomofo)
>> +                        {
>> +                            asian = TRUE;
>> +                            break;
>> +                        }
>> +                        if (original != Script_MathAlpha && scriptInformation[scripts[j]].props.fComplex)
>> +                            break;
>> +                        scripts[j] = scripts[i];
>> +                        if (original == Script_Punctuation2)
>> +                            break;
>> +                    }
>> +                    if (scriptInformation[scripts[j]].props.fComplex || asian)
>> +                        scripts[i] = scripts[j];
>> +                }
>> +            }
>> +        }
>>       }
>>
>>       for (i = 0; i < cInChars; i++)
>> @@ -1496,7 +1493,8 @@
>>
>>       pItems[index].iCharPos = 0;
>>       pItems[index].a = scriptInformation[scripts[cnt]].a;
>> -    pScriptTags[index] = scriptInformation[scripts[cnt]].scriptTag;
>> +    if (pScriptTags)
>> +        pScriptTags[index] = scriptInformation[scripts[cnt]].scriptTag;
>>
>>       if (strength && strength[cnt] == BIDI_STRONG)
>>           str = strength[cnt];
>> @@ -1590,7 +1588,8 @@
>>               memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
>>
>>               pItems[index].a = scriptInformation[New_Script].a;
>> -            pScriptTags[index] = scriptInformation[New_Script].scriptTag;
>> +            if (pScriptTags)
>> +                pScriptTags[index] = scriptInformation[New_Script].scriptTag;
>>               if (levels)
>>               {
>>                   if (levels[cnt] == 0)
>> @@ -1633,6 +1632,32 @@
>>   }
>>
>>   /***********************************************************************
>> + *      ScriptItemizeOpenType (USP10.@)
>> + *
>> + * Split a Unicode string into shapeable parts.
>> + *
>> + * PARAMS
>> + *  pwcInChars  [I] String to split.
>> + *  cInChars    [I] Number of characters in pwcInChars.
>> + *  cMaxItems   [I] Maximum number of items to return.
>> + *  psControl   [I] Pointer to a SCRIPT_CONTROL structure.
>> + *  psState     [I] Pointer to a SCRIPT_STATE structure.
>> + *  pItems      [O] Buffer to receive SCRIPT_ITEM structures.
>> + *  pScriptTags [O] Buffer to receive OPENTYPE_TAGs.
>> + *  pcItems     [O] Number of script items returned.
>> + *
>> + * RETURNS
>> + *  Success: S_OK
>> + *  Failure: Non-zero HRESULT value.
>> + */
>> +HRESULT WINAPI ScriptItemizeOpenType(const WCHAR *pwcInChars, int cInChars, int cMaxItems,
>> +                             const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState,
>> +                             SCRIPT_ITEM *pItems, OPENTYPE_TAG *pScriptTags, int *pcItems)
>> +{
>> +    return _ItemizeInternal(pwcInChars, cInChars, cMaxItems, psControl, psState, pItems, pScriptTags, pcItems);
>> +}
>> +
>> +/***********************************************************************
>>    *      ScriptItemize (USP10.@)
>>    *
>>    * Split a Unicode string into shapeable parts.
>> @@ -1654,15 +1679,7 @@
>>                                const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState,
>>                                SCRIPT_ITEM *pItems, int *pcItems)
>>   {
>> -    OPENTYPE_TAG *discarded_tags;
>> -    HRESULT res;
>> -
>> -    discarded_tags = heap_alloc(cMaxItems * sizeof(OPENTYPE_TAG));
>> -    if (!discarded_tags)
>> -        return E_OUTOFMEMORY;
>> -    res = ScriptItemizeOpenType(pwcInChars, cInChars, cMaxItems, psControl, psState, pItems, discarded_tags, pcItems);
>> -    heap_free(discarded_tags);
>> -    return res;
>> +    return _ItemizeInternal(pwcInChars, cInChars, cMaxItems, psControl, psState, pItems, NULL, pcItems);
>>   }
>>
>>   static inline int getGivenTabWidth(ScriptCache *psc, SCRIPT_TABDEF *pTabdef, int charPos, int current_x)
>> @@ -1847,7 +1864,7 @@
>>       hr = ScriptItemize(pString, cString, num_items, &sControl, &sState, analysis->pItem,
>>                          &analysis->numItems);
>>
>> -    if FAILED(hr)
>> +    if (FAILED(hr))
>>       {
>>           if (hr == E_OUTOFMEMORY)
>>               hr = E_INVALIDARG;
>> @@ -1935,7 +1952,7 @@
>>               if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && analysis->pItem[i].a.eScript == Script_Hangul)
>>                   analysis->pItem[i].a.fNoGlyphIndex = TRUE;
>>
>> -            if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && !scriptInformation[analysis->pItem[i].a.eScript].props.fComplex)
>> +            if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && !scriptInformation[analysis->pItem[i].a.eScript].props.fComplex && !analysis->pItem[i].a.fRTL)
>>                   analysis->pItem[i].a.fNoGlyphIndex = TRUE;
>>
>>               hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos],
>> @@ -3237,8 +3254,9 @@
>>                                const int *piJustify, const GOFFSET *pGoffset)
>>   {
>>       HRESULT hr = S_OK;
>> -    INT i;
>> +    INT i, dir = 1;
>>       INT *lpDx;
>> +    WORD *reordered_glyphs = (WORD *)pwGlyphs;
>>
>>       TRACE("(%p, %p, %d, %d, %04x, %p, %p, %p, %d, %p, %d, %p, %p, %p)\n",
>>            hdc, psc, x, y, fuOptions, lprc, psa, pwcReserved, iReserved, pwGlyphs, cGlyphs,
>> @@ -3253,67 +3271,50 @@
>>           fuOptions |= ETO_GLYPH_INDEX;                             /* Say don't do translation to glyph */
>>
>>       lpDx = heap_alloc(cGlyphs * sizeof(INT) * 2);
>> -
>> -    if (pGoffset)
>> -    {
>> +    if (!lpDx) return E_OUTOFMEMORY;
>> +    fuOptions |= ETO_PDY;
>> +
>> +    if (psa->fRTL && psa->fLogicalOrder)
>> +    {
>> +        reordered_glyphs = heap_alloc( cGlyphs * sizeof(WORD) );
>> +        if (!reordered_glyphs)
>> +        {
>> +            heap_free( lpDx );
>> +            return E_OUTOFMEMORY;
>> +        }
>> +
>>           for (i = 0; i < cGlyphs; i++)
>> -            if (!(fuOptions&ETO_PDY) && pGoffset[i].dv)
>> -                fuOptions |= ETO_PDY;
>> -    }
>> +            reordered_glyphs[i] = pwGlyphs[cGlyphs - 1 - i];
>> +        dir = -1;
>> +    }
>> +
>>       for (i = 0; i < cGlyphs; i++)
>>       {
>> -        int idx = i;
>> -        if (fuOptions&ETO_PDY)
>> -        {
>> -            idx *=2;
>> -            lpDx[idx+1] = 0;
>> -        }
>> -        lpDx[idx] = piAdvance[i];
>> -    }
>> -    if (pGoffset)
>> -    {
>> -        for (i = 1; i < cGlyphs; i++)
>> -        {
>> -            int idx = i;
>> -            int prev_idx = i-1;
>> -            if (fuOptions&ETO_PDY)
>> +        int orig_index = (dir > 0) ? i : cGlyphs - 1 - i;
>> +        lpDx[i * 2] = piAdvance[orig_index];
>> +        lpDx[i * 2 + 1] = 0;
>> +
>> +        if (pGoffset)
>> +        {
>> +            if (i == 0)
>>               {
>> -                idx*=2;
>> -                prev_idx = idx-2;
>> +                x += pGoffset[orig_index].du * dir;
>> +                y += pGoffset[orig_index].dv;
>>               }
>> -            lpDx[prev_idx] += pGoffset[i].du;
>> -            lpDx[idx] -= pGoffset[i].du;
>> -            if (fuOptions&ETO_PDY)
>> +            else
>>               {
>> -                lpDx[prev_idx+1] += pGoffset[i].dv;
>> -                lpDx[idx+1] -= pGoffset[i].dv;
>> +                lpDx[(i - 1) * 2]     += pGoffset[orig_index].du * dir;
>> +                lpDx[(i - 1) * 2 + 1] += pGoffset[orig_index].dv;
>>               }
>> -        }
>> -    }
>> -
>> -    if (psa->fRTL && psa->fLogicalOrder)
>> -    {
>> -        int i;
>> -        WORD *rtlGlyphs;
>> -
>> -        rtlGlyphs = heap_alloc(cGlyphs * sizeof(WORD));
>> -        if (!rtlGlyphs)
>> -        {
>> -            heap_free(lpDx);
>> -            return E_OUTOFMEMORY;
>> -        }
>> -
>> -        for (i = 0; i < cGlyphs; i++)
>> -            rtlGlyphs[i] = pwGlyphs[cGlyphs-1-i];
>> -
>> -        if (!ExtTextOutW(hdc, x, y, fuOptions, lprc, rtlGlyphs, cGlyphs, lpDx))
>> -            hr = S_FALSE;
>> -        heap_free(rtlGlyphs);
>> -    }
>> -    else
>> -        if (!ExtTextOutW(hdc, x, y, fuOptions, lprc, pwGlyphs, cGlyphs, lpDx))
>> -            hr = S_FALSE;
>> -
>> +            lpDx[i * 2]     -= pGoffset[orig_index].du * dir;
>> +            lpDx[i * 2 + 1] -= pGoffset[orig_index].dv;
>> +        }
>> +    }
>> +
>> +    if (!ExtTextOutW(hdc, x, y, fuOptions, lprc, reordered_glyphs, cGlyphs, lpDx))
>> +        hr = S_FALSE;
>> +
>> +    if (reordered_glyphs != pwGlyphs) heap_free( reordered_glyphs );
>>       heap_free(lpDx);
>>
>>       return hr;
>>
>> Modified: trunk/reactos/dll/win32/usp10/usp10_internal.h
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/usp10_internal.h?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/usp10_internal.h [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/usp10_internal.h [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -128,8 +128,13 @@
>>   #define GSUB_E_NOFEATURE -2
>>   #define GSUB_E_NOGLYPH -1
>>
>> +#define FEATURE_ALL_TABLES 0
>> +#define FEATURE_GSUB_TABLE 1
>> +#define FEATURE_GPOS_TABLE 2
>> +
>>   typedef struct {
>>       OPENTYPE_TAG tag;
>> +    CHAR tableType;
>>       LPCVOID  feature;
>>       INT lookup_count;
>>       WORD *lookups;
>> @@ -139,6 +144,7 @@
>>       OPENTYPE_TAG tag;
>>       LPCVOID gsub_table;
>>       LPCVOID gpos_table;
>> +    BOOL features_initialized;
>>       INT feature_count;
>>       LoadedFeature *features;
>>   } LoadedLanguage;
>> @@ -148,6 +154,7 @@
>>       LPCVOID gsub_table;
>>       LPCVOID gpos_table;
>>       LoadedLanguage default_language;
>> +    BOOL languages_initialized;
>>       INT language_count;
>>       LoadedLanguage *languages;
>>   } LoadedScript;
>> @@ -169,6 +176,7 @@
>>       LPVOID CMAP_Table;
>>       LPVOID CMAP_format12_Table;
>>       LPVOID GPOS_Table;
>> +    BOOL scripts_initialized;
>>       INT script_count;
>>       LoadedScript *scripts;
>>
>> @@ -223,7 +231,7 @@
>>   INT BIDI_ReorderL2vLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse) DECLSPEC_HIDDEN;
>>   void SHAPE_ContextualShaping(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust) DECLSPEC_HIDDEN;
>>   void SHAPE_ApplyDefaultOpentypeFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, INT cChars, WORD *pwLogClust) DECLSPEC_HIDDEN;
>> -void SHAPE_ApplyOpenTypePositions(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WORD* pwGlyphs, INT cGlyphs, int *piAdvance, GOFFSET *pGoffset );
>> +void SHAPE_ApplyOpenTypePositions(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WORD* pwGlyphs, INT cGlyphs, int *piAdvance, GOFFSET *pGoffset ) DECLSPEC_HIDDEN;
>>   HRESULT SHAPE_CheckFontForRequiredFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa) DECLSPEC_HIDDEN;
>>   void SHAPE_CharGlyphProp(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProp, SCRIPT_GLYPHPROP *pGlyphProp) DECLSPEC_HIDDEN;
>>   INT SHAPE_does_GSUB_feature_apply_to_chars(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, const WCHAR *chars, INT write_dir, INT count, const char* feature) DECLSPEC_HIDDEN;
>> @@ -237,9 +245,9 @@
>>   void BREAK_line(const WCHAR *chars, int count, const SCRIPT_ANALYSIS *sa, SCRIPT_LOGATTR *la) DECLSPEC_HIDDEN;
>>
>>   DWORD OpenType_CMAP_GetGlyphIndex(HDC hdc, ScriptCache *psc, DWORD utf32c, LPWORD pgi, DWORD flags) DECLSPEC_HIDDEN;
>> -void OpenType_GDEF_UpdateGlyphProps(HDC hdc, ScriptCache *psc, const WORD *pwGlyphs, const WORD cGlyphs, WORD* pwLogClust, const WORD cChars, SCRIPT_GLYPHPROP *pGlyphProp) DECLSPEC_HIDDEN;
>> +void OpenType_GDEF_UpdateGlyphProps(ScriptCache *psc, const WORD *pwGlyphs, const WORD cGlyphs, WORD* pwLogClust, const WORD cChars, SCRIPT_GLYPHPROP *pGlyphProp) DECLSPEC_HIDDEN;
>>   INT OpenType_apply_GSUB_lookup(LPCVOID table, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count) DECLSPEC_HIDDEN;
>> -INT OpenType_apply_GPOS_lookup(LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, INT* piAdvance, LPCVOID table, INT lookup_index, const WORD *glyphs, INT glyph_index, INT write_dir, INT glyph_count, GOFFSET *pGoffset) DECLSPEC_HIDDEN;
>> +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) DECLSPEC_HIDDEN;
>>   HRESULT OpenType_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags) DECLSPEC_HIDDEN;
>>   HRESULT OpenType_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags) DECLSPEC_HIDDEN;
>> -HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature** feature) DECLSPEC_HIDDEN;
>> +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) DECLSPEC_HIDDEN;
>>
>> Modified: trunk/reactos/dll/win32/usp10/usp10_ros.diff
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/usp10_ros.diff?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/dll/win32/usp10/usp10_ros.diff [iso-8859-1] (original)
>> +++ trunk/reactos/dll/win32/usp10/usp10_ros.diff [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -2,7 +2,7 @@
>>   ===================================================================
>>   --- usp10.c     (revision 54504)
>>   +++ usp10.c     (working copy)
>> -@@ -3621,3 +3621,9 @@
>> +@@ -3746,3 +3746,9 @@
>>
>>        return SHAPE_GetFontFeatureTags(hdc, (ScriptCache *)*psc, psa, tagScript, tagLangSys, cMaxTags, pFeatureTags, pcTags);
>>    }
>>
>> Modified: trunk/reactos/media/doc/README.WINE
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=58375&r1=58374&r2=58375&view=diff
>> ==============================================================================
>> --- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original)
>> +++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Wed Feb 27 14:11:44 2013
>> @@ -179,7 +179,7 @@
>>   reactos/dll/win32/updspapi        # Synced to Wine-1.5.4
>>   reactos/dll/win32/url             # Synced to Wine-1.5.19
>>   reactos/dll/win32/urlmon          # Autosync
>> -reactos/dll/win32/usp10           # Synced to Wine-1.5.19
>> +reactos/dll/win32/usp10           # Synced to Wine-1.5.24
>>   reactos/dll/win32/uxtheme         # Forked
>>   reactos/dll/win32/version         # Autosync
>>   reactos/dll/win32/wer             # Autosync
>>
>>
>
>_______________________________________________
>Ros-dev mailing list
>Ros-dev at reactos.org
>http://www.reactos.org/mailman/listinfo/ros-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.reactos.org/pipermail/ros-dev/attachments/20130227/d29336d8/attachment-0001.html>


More information about the Ros-dev mailing list