Aric Stewart : usp10: Implement GPOS Anchor formats.
Alexandre Julliard
julliard at winehq.org
Mon Jul 16 14:14:30 CDT 2012
Module: wine
Branch: master
Commit: 69351a9cea4f48fe7e4f907bad89d5714094f6fc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=69351a9cea4f48fe7e4f907bad89d5714094f6fc
Author: Aric Stewart <aric at codeweavers.com>
Date: Mon Jul 16 07:23:53 2012 -0500
usp10: Implement GPOS Anchor formats.
---
dlls/usp10/opentype.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 98 insertions(+), 0 deletions(-)
diff --git a/dlls/usp10/opentype.c b/dlls/usp10/opentype.c
index b875594..8434789 100644
--- a/dlls/usp10/opentype.c
+++ b/dlls/usp10/opentype.c
@@ -286,6 +286,34 @@ typedef struct {
WORD LookupList;
} GPOS_Header;
+typedef struct {
+ WORD StartSize;
+ WORD EndSize;
+ WORD DeltaFormat;
+ WORD DeltaValue[1];
+} OT_DeviceTable;
+
+typedef struct {
+ WORD AnchorFormat;
+ WORD XCoordinate;
+ WORD YCoordinate;
+} GPOS_AnchorFormat1;
+
+typedef struct {
+ WORD AnchorFormat;
+ WORD XCoordinate;
+ WORD YCoordinate;
+ WORD AnchorPoint;
+} GPOS_AnchorFormat2;
+
+typedef struct {
+ WORD AnchorFormat;
+ WORD XCoordinate;
+ WORD YCoordinate;
+ WORD XDeviceTable;
+ WORD YDeviceTable;
+} GPOS_AnchorFormat3;
+
/**********
* CMAP
**********/
@@ -872,6 +900,76 @@ INT OpenType_apply_GSUB_lookup(LPCVOID table, INT lookup_index, WORD *glyphs, IN
/**********
* GPOS
**********/
+static INT GPOS_get_device_table_value(const OT_DeviceTable *DeviceTable, WORD ppem)
+{
+ static const WORD mask[3] = {3,0xf,0xff};
+ if (DeviceTable && ppem >= GET_BE_WORD(DeviceTable->StartSize) && ppem <= GET_BE_WORD(DeviceTable->EndSize))
+ {
+ int format = GET_BE_WORD(DeviceTable->DeltaFormat);
+ int index = ppem - GET_BE_WORD(DeviceTable->StartSize);
+ int value;
+ TRACE("device table, format %i, index %i\n",format, index);
+ index = index << format;
+ value = (DeviceTable->DeltaValue[index/sizeof(WORD)] << (index%sizeof(WORD)))&mask[format-1];
+ TRACE("offset %i, value %i\n",index, value);
+ if (value > mask[format-1]/2)
+ value = -1 * ((mask[format-1]+1) - value);
+ return value;
+ }
+ return 0;
+}
+
+static VOID GPOS_get_anchor_values(LPCVOID table, LPPOINT pt, WORD ppem)
+{
+ const GPOS_AnchorFormat1* anchor1 = (const GPOS_AnchorFormat1*)table;
+
+ switch (GET_BE_WORD(anchor1->AnchorFormat))
+ {
+ case 1:
+ {
+ TRACE("Anchor Format 1\n");
+ pt->x = (short)GET_BE_WORD(anchor1->XCoordinate);
+ pt->y = (short)GET_BE_WORD(anchor1->YCoordinate);
+ break;
+ }
+ case 2:
+ {
+ const GPOS_AnchorFormat2* anchor2 = (const GPOS_AnchorFormat2*)table;
+ TRACE("Anchor Format 2\n");
+ pt->x = (short)GET_BE_WORD(anchor2->XCoordinate);
+ pt->y = (short)GET_BE_WORD(anchor2->YCoordinate);
+ break;
+ }
+ case 3:
+ {
+ int offset;
+ const GPOS_AnchorFormat3* anchor3 = (const GPOS_AnchorFormat3*)table;
+ TRACE("Anchor Format 3\n");
+ pt->x = (short)GET_BE_WORD(anchor3->XCoordinate);
+ pt->y = (short)GET_BE_WORD(anchor3->YCoordinate);
+ offset = GET_BE_WORD(anchor3->XDeviceTable);
+ TRACE("ppem %i\n",ppem);
+ if (offset)
+ {
+ const OT_DeviceTable* DeviceTableX = NULL;
+ DeviceTableX = (const OT_DeviceTable*)((const BYTE*)anchor3 + offset);
+ pt->x += GPOS_get_device_table_value(DeviceTableX, ppem);
+ }
+ offset = GET_BE_WORD(anchor3->YDeviceTable);
+ if (offset)
+ {
+ const OT_DeviceTable* DeviceTableY = NULL;
+ DeviceTableY = (const OT_DeviceTable*)((const BYTE*)anchor3 + offset);
+ pt->y += GPOS_get_device_table_value(DeviceTableY, ppem);
+ }
+ break;
+ }
+ default:
+ ERR("Unknown Anchor Format %i\n",GET_BE_WORD(anchor1->AnchorFormat));
+ pt->x = 0;
+ pt->y = 0;
+ }
+}
static 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)
{
More information about the wine-cvs
mailing list