From d8e42057e03fdc84737f6f9f0fe58235b4739aae Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 9 Oct 2017 10:47:04 +0300 Subject: [PATCH] dwrite: Recognize CBLC/CBDT image formats. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/dwrite/opentype.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++- dlls/dwrite/tests/font.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 71b90f9b746..431fac959ac 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -41,6 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); #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') +#define MS_CBLC_TAG DWRITE_MAKE_OPENTYPE_TAG('C','B','L','C') /* 'sbix' formats */ #define MS_PNG__TAG DWRITE_MAKE_OPENTYPE_TAG('p','n','g',' ') @@ -262,6 +263,30 @@ typedef struct { WORD numGlyphs; } maxp; +typedef struct { + WORD majorVersion; + WORD minorVersion; + DWORD numSizes; +} CBLCHeader; + +typedef struct { + BYTE res[12]; +} sbitLineMetrics; + +typedef struct { + DWORD indexSubTableArrayOffset; + DWORD indexTablesSize; + DWORD numberofIndexSubTables; + DWORD colorRef; + sbitLineMetrics hori; + sbitLineMetrics vert; + WORD startGlyphIndex; + WORD endGlyphIndex; + BYTE ppemX; + BYTE ppemY; + BYTE bitDepth; + BYTE flags; +} CBLCBitmapSizeTable; #include "poppack.h" enum OS2_FSSELECTION { @@ -2151,6 +2176,40 @@ static DWORD opentype_get_sbix_formats(IDWriteFontFace4 *fontface) return ret; } +static UINT32 opentype_get_cblc_formats(IDWriteFontFace4 *fontface) +{ + CBLCBitmapSizeTable *sizes; + UINT32 num_sizes, size, s; + BOOL exists = FALSE; + CBLCHeader *header; + UINT32 ret = 0; + void *context; + HRESULT hr; + + if (FAILED(hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_CBLC_TAG, (const void **)&header, &size, + &context, &exists))) + return 0; + + if (!exists) + return 0; + + num_sizes = GET_BE_DWORD(header->numSizes); + sizes = (CBLCBitmapSizeTable *)(header + 1); + + for (s = 0; s < num_sizes; s++) { + BYTE bpp = sizes->bitDepth; + + if (bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8) + ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG; + else if (bpp == 32) + ret |= DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8; + } + + IDWriteFontFace4_ReleaseFontTable(fontface, context); + + return ret; +} + UINT32 opentype_get_glyph_image_formats(IDWriteFontFace4 *fontface) { UINT32 ret = DWRITE_GLYPH_IMAGE_FORMATS_NONE; @@ -2170,7 +2229,9 @@ UINT32 opentype_get_glyph_image_formats(IDWriteFontFace4 *fontface) if (opentype_has_font_table(fontface, MS_SBIX_TAG)) ret |= opentype_get_sbix_formats(fontface); - /* TODO: handle embedded bitmaps tables */ + if (opentype_has_font_table(fontface, MS_CBLC_TAG)) + ret |= opentype_get_cblc_formats(fontface); + return ret; } diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index c579d944cc2..e22d682e422 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -48,6 +48,7 @@ #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') +#define MS_CBLC_TAG DWRITE_MAKE_OPENTYPE_TAG('C','B','L','C') /* 'sbix' formats */ #define MS_PNG__TAG DWRITE_MAKE_OPENTYPE_TAG('p','n','g',' ') @@ -337,6 +338,31 @@ typedef struct { } sbix_glyph_data; typedef struct { + WORD majorVersion; + WORD minorVersion; + DWORD numSizes; +} CBLCHeader; + +typedef struct { + BYTE res[12]; +} sbitLineMetrics; + +typedef struct { + DWORD indexSubTableArrayOffset; + DWORD indexTablesSize; + DWORD numberofIndexSubTables; + DWORD colorRef; + sbitLineMetrics hori; + sbitLineMetrics vert; + WORD startGlyphIndex; + WORD endGlyphIndex; + BYTE ppemX; + BYTE ppemY; + BYTE bitDepth; + BYTE flags; +} CBLCBitmapSizeTable; + +typedef struct { DWORD version; WORD numGlyphs; } maxp; @@ -7981,6 +8007,40 @@ static DWORD get_sbix_formats(IDWriteFontFace4 *fontface) return ret; } +static DWORD get_cblc_formats(IDWriteFontFace4 *fontface) +{ + CBLCBitmapSizeTable *sizes; + UINT32 num_sizes, size, s; + BOOL exists = FALSE; + CBLCHeader *header; + DWORD ret = 0; + void *context; + HRESULT hr; + + hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_CBLC_TAG, (const void **)&header, &size, &context, &exists); + ok(hr == S_OK, "TryGetFontTable() failed, %#x\n", hr); + ok(exists, "Expected CBLC table\n"); + + if (!exists) + return 0; + + num_sizes = GET_BE_DWORD(header->numSizes); + sizes = (CBLCBitmapSizeTable *)(header + 1); + + for (s = 0; s < num_sizes; s++) { + BYTE bpp = sizes->bitDepth; + + if (bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8) + ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG; + else if (bpp == 32) + ret |= DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8; + } + + IDWriteFontFace4_ReleaseFontTable(fontface, context); + + return ret; +} + static DWORD get_face_glyph_image_formats(IDWriteFontFace4 *fontface) { DWORD ret = DWRITE_GLYPH_IMAGE_FORMATS_NONE; @@ -8000,7 +8060,9 @@ static DWORD get_face_glyph_image_formats(IDWriteFontFace4 *fontface) if (face_has_table(fontface, MS_SBIX_TAG)) ret |= get_sbix_formats(fontface); - /* TODO: handle embedded bitmaps tables */ + if (face_has_table(fontface, MS_CBLC_TAG)) + ret |= get_cblc_formats(fontface); + return ret; } -- 2.11.4.GIT