Aric Stewart : usp10: Implement GPOS Pair Adjustment Positioning Subtable.
Alexandre Julliard
julliard at winehq.org
Mon Jul 16 14:14:30 CDT 2012
Module: wine
Branch: master
Commit: 5a45e3474141536b02cfc4e924be3aacbd6ad2c5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5a45e3474141536b02cfc4e924be3aacbd6ad2c5
Author: Aric Stewart <aric at codeweavers.com>
Date: Mon Jul 16 07:24:16 2012 -0500
usp10: Implement GPOS Pair Adjustment Positioning Subtable.
---
dlls/usp10/opentype.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 112 insertions(+), 0 deletions(-)
diff --git a/dlls/usp10/opentype.c b/dlls/usp10/opentype.c
index b3913bf..9ffdf28 100644
--- a/dlls/usp10/opentype.c
+++ b/dlls/usp10/opentype.c
@@ -334,6 +334,26 @@ typedef struct {
typedef struct {
WORD PosFormat;
+ WORD Coverage;
+ WORD ValueFormat1;
+ WORD ValueFormat2;
+ WORD PairSetCount;
+ WORD PairSetOffset[1];
+} GPOS_PairPosFormat1;
+
+typedef struct {
+ WORD SecondGlyph;
+ WORD Value1[1];
+ WORD Value2[1];
+} GPOS_PairValueRecord;
+
+typedef struct {
+ WORD PairValueCount;
+ GPOS_PairValueRecord PairValueRecord[1];
+} GPOS_PairSet;
+
+typedef struct {
+ WORD PosFormat;
WORD MarkCoverage;
WORD BaseCoverage;
WORD ClassCount;
@@ -1083,6 +1103,67 @@ static VOID GPOS_apply_SingleAdjustment(const OT_LookupTable *look, const WORD *
}
}
+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)
+{
+ int j;
+
+ TRACE("Pair Adjustment Positioning Subtable\n");
+
+ for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
+ {
+ const GPOS_PairPosFormat1 *ppf1;
+ WORD offset = GET_BE_WORD(look->SubTable[j]);
+ ppf1 = (const GPOS_PairPosFormat1*)((const BYTE*)look+offset);
+ if (GET_BE_WORD(ppf1->PosFormat) == 1)
+ {
+ offset = GET_BE_WORD(ppf1->Coverage);
+ if (GSUB_is_glyph_covered((const BYTE*)ppf1+offset, glyphs[glyph_index]) != -1)
+ {
+ int i;
+ int count = GET_BE_WORD(ppf1->PairSetCount);
+ for (i = 0; i < count; i++)
+ {
+ int k;
+ int pair_count;
+ const GPOS_PairSet *ps;
+ offset = GET_BE_WORD(ppf1->PairSetOffset[i]);
+ ps = (const GPOS_PairSet*)((const BYTE*)ppf1+offset);
+ pair_count = GET_BE_WORD(ps->PairValueCount);
+ for (k = 0; k < pair_count; k++)
+ {
+ if (glyphs[glyph_index+write_dir] == GET_BE_WORD(ps->PairValueRecord[k].SecondGlyph))
+ {
+ 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);
+ }
+ 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);
+ return glyph_index+2;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ FIXME("Pair Adjustment Positioning: Format %i Unhandled\n",GET_BE_WORD(ppf1->PosFormat));
+ }
+ 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)
{
int j;
@@ -1179,6 +1260,37 @@ static INT GPOS_apply_lookup(LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, I
FIXME("Unhandled adjustment to Y advancement\n");
}
}
+ case 2:
+ {
+ POINT advance[2]= {{0,0},{0,0}};
+ 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);
+ 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 += (int)(devX+0.5);
+ pGoffset[glyph_index].dv += (int)(devY+0.5);
+ }
+ if (advance[0].x || advance[0].y)
+ {
+ GPOS_convert_design_units_to_device(lpotm, lplogfont, advance[0].x, advance[0].y, &devX, &devY);
+ piAdvance[glyph_index] += (int)(devX+0.5);
+ }
+ 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 += (int)(devX+0.5);
+ pGoffset[glyph_index + write_dir].dv += (int)(devY+0.5);
+ }
+ if (advance[1].x || advance[1].y)
+ {
+ GPOS_convert_design_units_to_device(lpotm, lplogfont, advance[1].x, advance[1].y, &devX, &devY);
+ piAdvance[glyph_index + write_dir] += (int)(devX+0.5);
+ }
+ return index;
+ }
case 4:
{
double devX, devY;
More information about the wine-cvs
mailing list