________________________________
De : Jérôme Gardou <jerome.gardou(a)reactos.org>
À : ros-dev(a)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(a)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…
==============================================================================
--- 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…
==============================================================================
--- 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?re…
==============================================================================
--- 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/indicsylla…
==============================================================================
--- 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.…
==============================================================================
--- 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?r…
==============================================================================
--- 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…
==============================================================================
--- 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?re…
==============================================================================
--- 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?…
==============================================================================
--- 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?re…
==============================================================================
--- 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_inte…
==============================================================================
--- 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.…
==============================================================================
--- 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=…
==============================================================================
--- 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(a)reactos.org