From 7e50116b52f37a3a191cb207c1543ffdd3941c8a Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 12 Aug 2016 13:14:50 +0300 Subject: [PATCH] gdi32: Support special 'ttcf' tag in GetFontData(). Signed-off-by: Nikolay Sivov Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/gdi32/freetype.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 7b0ff942e3d..2e3b29a0832 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -210,8 +210,10 @@ MAKE_FUNCPTR(FcPatternGetString); #ifdef WORDS_BIGENDIAN #define GET_BE_WORD(x) (x) +#define GET_BE_DWORD(x) (x) #else #define GET_BE_WORD(x) RtlUshortByteSwap(x) +#define GET_BE_DWORD(x) RtlUlongByteSwap(x) #endif #define MS_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ @@ -223,6 +225,7 @@ MAKE_FUNCPTR(FcPatternGetString); #define MS_GASP_TAG MS_MAKE_TAG('g', 'a', 's', 'p') #define MS_GSUB_TAG MS_MAKE_TAG('G', 'S', 'U', 'B') #define MS_KERN_TAG MS_MAKE_TAG('k', 'e', 'r', 'n') +#define MS_TTCF_TAG MS_MAKE_TAG('t', 't', 'c', 'f') #define MS_VDMX_TAG MS_MAKE_TAG('V', 'D', 'M', 'X') /* 'gasp' flags */ @@ -424,6 +427,7 @@ struct tagGdiFont { GdiFont *base_font; VOID *GSUB_Table; const VOID *vert_feature; + ULONG ttc_item_offset; /* 0 if font is not a part of TrueType collection */ DWORD cache_num; DWORD instance_id; struct font_fileinfo *fileinfo; @@ -4549,6 +4553,9 @@ static FT_Face OpenFontFace(GdiFont *font, Face *face, LONG width, LONG height) font->ft_face = ft_face; if(FT_IS_SCALABLE(ft_face)) { + FT_ULong len; + DWORD header; + /* load the VDMX table if we have one */ font->ppem = load_VDMX(font, height); if(font->ppem == 0) @@ -4557,6 +4564,20 @@ static FT_Face OpenFontFace(GdiFont *font, Face *face, LONG width, LONG height) if((err = pFT_Set_Pixel_Sizes(ft_face, 0, font->ppem)) != 0) WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", 0, font->ppem, err); + + /* see if it's a TTC */ + len = sizeof(header); + if (!pFT_Load_Sfnt_Table(ft_face, 0, 0, (void*)&header, &len)) { + if (header == MS_TTCF_TAG) + { + len = sizeof(font->ttc_item_offset); + if (pFT_Load_Sfnt_Table(ft_face, 0, (3 + face->face_index) * sizeof(DWORD), + (void*)&font->ttc_item_offset, &len)) + font->ttc_item_offset = 0; + else + font->ttc_item_offset = GET_BE_DWORD(font->ttc_item_offset); + } + } } else { font->ppem = height; if((err = pFT_Set_Pixel_Sizes(ft_face, width, height)) != 0) @@ -4666,6 +4687,16 @@ static DWORD get_font_data( GdiFont *font, DWORD table, DWORD offset, LPVOID buf else len = cbData; + /* if font is a member of TTC, 'ttcf' tag allows reading from beginning of TTC file, + 0 tag means to read from start of collection member data. */ + if (font->ttc_item_offset) + { + if (table == MS_TTCF_TAG) + table = 0; + else if (table == 0) + offset += font->ttc_item_offset; + } + table = RtlUlongByteSwap( table ); /* MS tags differ in endianness from FT ones */ /* make sure value of len is the value freetype says it needs */