Module: wine Branch: master Commit: 7cb57e2ee852531110130e90c97280307f0584db URL: http://source.winehq.org/git/wine.git/?a=commit;h=7cb57e2ee852531110130e90c9...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Tue Apr 25 08:54:42 2017 +0300
dwrite: Extract supported image formats from 'sbix' table.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/dwrite/opentype.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ dlls/dwrite/tests/font.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 99531a6..1651729 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -38,6 +38,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); #define MS_CFF__TAG DWRITE_MAKE_OPENTYPE_TAG('C','F','F',' ') #define MS_COLR_TAG DWRITE_MAKE_OPENTYPE_TAG('C','O','L','R') #define MS_SVG__TAG DWRITE_MAKE_OPENTYPE_TAG('S','V','G',' ') +#define MS_SBIX_TAG DWRITE_MAKE_OPENTYPE_TAG('s','b','i','x') +#define MS_MAXP_TAG DWRITE_MAKE_OPENTYPE_TAG('m','a','x','p') + +/* 'sbix' formats */ +#define MS_PNG__TAG DWRITE_MAKE_OPENTYPE_TAG('p','n','g',' ') +#define MS_JPG__TAG DWRITE_MAKE_OPENTYPE_TAG('j','p','g',' ') +#define MS_TIFF_TAG DWRITE_MAKE_OPENTYPE_TAG('t','i','f','f')
#ifdef WORDS_BIGENDIAN #define GET_BE_WORD(x) (x) @@ -226,6 +233,31 @@ typedef struct { USHORT numberOfHMetrics; } TT_HHEA;
+typedef struct { + WORD version; + WORD flags; + DWORD numStrikes; + DWORD strikeOffset[1]; +} sbix_header; + +typedef struct { + WORD ppem; + WORD ppi; + DWORD glyphDataOffsets[1]; +} sbix_strike; + +typedef struct { + WORD originOffsetX; + WORD originOffsetY; + DWORD graphicType; + BYTE data[1]; +} sbix_glyph_data; + +typedef struct { + DWORD version; + WORD numGlyphs; +} maxp; + #include "poppack.h"
enum OS2_FSSELECTION { @@ -2057,6 +2089,71 @@ static BOOL opentype_has_font_table(IDWriteFontFace4 *fontface, UINT32 tag) return exists; }
+static DWORD opentype_get_sbix_formats(IDWriteFontFace4 *fontface) +{ + UINT32 size, s, num_strikes; + const sbix_header *header; + UINT16 g, num_glyphs; + BOOL exists = FALSE; + const maxp *maxp; + const void *data; + DWORD ret = 0; + void *context; + HRESULT hr; + + hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_MAXP_TAG, &data, &size, &context, &exists); + if (FAILED(hr) || !exists) + return 0; + + maxp = data; + num_glyphs = GET_BE_WORD(maxp->numGlyphs); + + IDWriteFontFace4_ReleaseFontTable(fontface, context); + + if (FAILED(IDWriteFontFace4_TryGetFontTable(fontface, MS_SBIX_TAG, &data, &size, &context, &exists))) { + WARN("Failed to get 'sbix' table, %#x\n", hr); + return 0; + } + + header = data; + num_strikes = GET_BE_DWORD(header->numStrikes); + + for (s = 0; s < num_strikes; s++) { + sbix_strike *strike = (sbix_strike *)((BYTE *)header + GET_BE_DWORD(header->strikeOffset[s])); + + for (g = 0; g < num_glyphs; g++) { + DWORD offset = GET_BE_DWORD(strike->glyphDataOffsets[g]); + DWORD offset_next = GET_BE_DWORD(strike->glyphDataOffsets[g + 1]); + sbix_glyph_data *glyph_data; + DWORD format; + + if (offset == offset_next) + continue; + + glyph_data = (sbix_glyph_data *)((BYTE *)strike + offset); + switch (format = glyph_data->graphicType) + { + case MS_PNG__TAG: + ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG; + break; + case MS_JPG__TAG: + ret |= DWRITE_GLYPH_IMAGE_FORMATS_JPEG; + break; + case MS_TIFF_TAG: + ret |= DWRITE_GLYPH_IMAGE_FORMATS_TIFF; + break; + default: + format = GET_BE_DWORD(format); + FIXME("unexpected bitmap format %s\n", debugstr_an((char *)&format, 4)); + } + } + } + + IDWriteFontFace4_ReleaseFontTable(fontface, context); + + return ret; +} + UINT32 opentype_get_glyph_image_formats(IDWriteFontFace4 *fontface) { UINT32 ret = DWRITE_GLYPH_IMAGE_FORMATS_NONE; @@ -2073,6 +2170,9 @@ UINT32 opentype_get_glyph_image_formats(IDWriteFontFace4 *fontface) if (opentype_has_font_table(fontface, MS_SVG__TAG)) ret |= DWRITE_GLYPH_IMAGE_FORMATS_SVG;
+ if (opentype_has_font_table(fontface, MS_SBIX_TAG)) + ret |= opentype_get_sbix_formats(fontface); + /* TODO: handle embedded bitmaps tables */ return ret; } diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 9fd8258..980278e 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -46,6 +46,13 @@ #define MS_CFF__TAG DWRITE_MAKE_OPENTYPE_TAG('C','F','F',' ') #define MS_COLR_TAG DWRITE_MAKE_OPENTYPE_TAG('C','O','L','R') #define MS_SVG__TAG DWRITE_MAKE_OPENTYPE_TAG('S','V','G',' ') +#define MS_SBIX_TAG DWRITE_MAKE_OPENTYPE_TAG('s','b','i','x') +#define MS_MAXP_TAG DWRITE_MAKE_OPENTYPE_TAG('m','a','x','p') + +/* 'sbix' formats */ +#define MS_PNG__TAG DWRITE_MAKE_OPENTYPE_TAG('p','n','g',' ') +#define MS_JPG__TAG DWRITE_MAKE_OPENTYPE_TAG('j','p','g',' ') +#define MS_TIFF_TAG DWRITE_MAKE_OPENTYPE_TAG('t','i','f','f')
#ifdef WORDS_BIGENDIAN #define GET_BE_WORD(x) (x) @@ -302,6 +309,31 @@ typedef struct { DWORD ExtensionOffset; } GSUB_ExtensionPosFormat1;
+typedef struct { + WORD version; + WORD flags; + DWORD numStrikes; + DWORD strikeOffset[1]; +} sbix_header; + +typedef struct { + WORD ppem; + WORD ppi; + DWORD glyphDataOffsets[1]; +} sbix_strike; + +typedef struct { + WORD originOffsetX; + WORD originOffsetY; + DWORD graphicType; + BYTE data[1]; +} sbix_glyph_data; + +typedef struct { + DWORD version; + WORD numGlyphs; +} maxp; + #include "poppack.h"
static IDWriteFactory *create_factory(void) @@ -7424,6 +7456,70 @@ static BOOL face_has_table(IDWriteFontFace4 *fontface, UINT32 tag) return exists; }
+static DWORD get_sbix_formats(IDWriteFontFace4 *fontface) +{ + UINT32 size, s, num_strikes; + const sbix_header *header; + UINT16 g, num_glyphs; + BOOL exists = FALSE; + const maxp *maxp; + const void *data; + DWORD ret = 0; + void *context; + HRESULT hr; + + hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_MAXP_TAG, &data, &size, &context, &exists); + ok(hr == S_OK, "TryGetFontTable() failed, %#x\n", hr); + ok(exists, "Expected maxp table\n"); + + if (!exists) + return 0; + + maxp = data; + num_glyphs = GET_BE_WORD(maxp->numGlyphs); + + hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_SBIX_TAG, &data, &size, &context, &exists); + ok(hr == S_OK, "TryGetFontTable() failed, %#x\n", hr); + ok(exists, "Expected sbix table\n"); + + header = data; + num_strikes = GET_BE_DWORD(header->numStrikes); + + for (s = 0; s < num_strikes; s++) { + sbix_strike *strike = (sbix_strike *)((BYTE *)header + GET_BE_DWORD(header->strikeOffset[s])); + + for (g = 0; g < num_glyphs; g++) { + DWORD offset = GET_BE_DWORD(strike->glyphDataOffsets[g]); + DWORD offset_next = GET_BE_DWORD(strike->glyphDataOffsets[g + 1]); + sbix_glyph_data *glyph_data; + DWORD format; + + if (offset == offset_next) + continue; + + glyph_data = (sbix_glyph_data *)((BYTE *)strike + offset); + switch (format = glyph_data->graphicType) + { + case MS_PNG__TAG: + ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG; + break; + case MS_JPG__TAG: + ret |= DWRITE_GLYPH_IMAGE_FORMATS_JPEG; + break; + case MS_TIFF_TAG: + ret |= DWRITE_GLYPH_IMAGE_FORMATS_TIFF; + break; + default: + ok(0, "unexpected format, %#x\n", GET_BE_DWORD(format)); + } + } + } + + IDWriteFontFace4_ReleaseFontTable(fontface, context); + + return ret; +} + static DWORD get_face_glyph_image_formats(IDWriteFontFace4 *fontface) { DWORD ret = DWRITE_GLYPH_IMAGE_FORMATS_NONE; @@ -7440,6 +7536,9 @@ static DWORD get_face_glyph_image_formats(IDWriteFontFace4 *fontface) if (face_has_table(fontface, MS_SVG__TAG)) ret |= DWRITE_GLYPH_IMAGE_FORMATS_SVG;
+ if (face_has_table(fontface, MS_SBIX_TAG)) + ret |= get_sbix_formats(fontface); + /* TODO: handle embedded bitmaps tables */ return ret; }