From: Nikolay Sivov Subject: [PATCH] dwrite/tests: Some tests for DWRITE_FONT_FACE_TYPE_RAW_CFF Message-Id: <1447854131-30303-1-git-send-email-nsivov@codeweavers.com> Date: Wed, 18 Nov 2015 16:42:11 +0300 Signed-off-by: Nikolay Sivov --- dlls/dwrite/tests/Makefile.in | 3 +- dlls/dwrite/tests/font.c | 230 ++++++++++++++++++++++++++++++++- dlls/dwrite/tests/resource.rc | 2 + dlls/dwrite/tests/wine_test_cff.otf | Bin 0 -> 1900 bytes dlls/dwrite/tests/wine_test_cff.sfd | 244 ++++++++++++++++++++++++++++++++++++ 5 files changed, 473 insertions(+), 6 deletions(-) create mode 100644 dlls/dwrite/tests/wine_test_cff.otf create mode 100644 dlls/dwrite/tests/wine_test_cff.sfd diff --git a/dlls/dwrite/tests/Makefile.in b/dlls/dwrite/tests/Makefile.in index 7fbf9e3..b7bb25a 100644 --- a/dlls/dwrite/tests/Makefile.in +++ b/dlls/dwrite/tests/Makefile.in @@ -7,6 +7,7 @@ C_SRCS = \ layout.c FONT_SRCS = \ - wine_test.sfd + wine_test.sfd \ + wine_test_cff.sfd RC_SRCS = resource.rc diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 681f010..2e2b5fa 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -1,7 +1,7 @@ /* * Font related tests * - * Copyright 2012, 2014 Nikolay Sivov for CodeWeavers + * Copyright 2012, 2014-2015 Nikolay Sivov for CodeWeavers * Copyright 2014 Aric Stewart for CodeWeavers * * This library is free software; you can redistribute it and/or @@ -40,6 +40,7 @@ #define MS_VDMX_TAG MS_MAKE_TAG('V','D','M','X') #define MS_GASP_TAG MS_MAKE_TAG('g','a','s','p') #define MS_CPAL_TAG MS_MAKE_TAG('C','P','A','L') +#define MS_CFF_TAG MS_MAKE_TAG('C','F','F',' ') #define EXPECT_HR(hr,hr_exp) \ ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp) @@ -139,7 +140,7 @@ static IDWriteFontFace *create_fontface(IDWriteFactory *factory) return fontface; } -static WCHAR *create_testfontfile(const WCHAR *filename) +static WCHAR *create_testfontfile_from_res(WORD resid, const WCHAR *filename) { static WCHAR pathW[MAX_PATH]; DWORD written; @@ -154,7 +155,7 @@ static WCHAR *create_testfontfile(const WCHAR *filename) ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW), GetLastError()); - res = FindResourceA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(1), (LPCSTR)RT_RCDATA); + res = FindResourceA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(resid), (LPCSTR)RT_RCDATA); ok( res != 0, "couldn't find resource\n" ); ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res )); WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL ); @@ -164,6 +165,11 @@ static WCHAR *create_testfontfile(const WCHAR *filename) return pathW; } +static WCHAR *create_testfontfile(const WCHAR *filename) +{ + return create_testfontfile_from_res(1, filename); +} + #define DELETE_FONTFILE(filename) _delete_testfontfile(filename, __LINE__) static void _delete_testfontfile(const WCHAR *filename, int line) { @@ -440,7 +446,8 @@ static ULONG WINAPI resourcefontfileloader_Release(IDWriteFontFileLoader *iface) return 1; } -static HRESULT WINAPI resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileStream **fontFileStream) +static HRESULT WINAPI resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, IDWriteFontFileStream **fontFileStream) { LPVOID data; DWORD size; @@ -1930,7 +1937,8 @@ static ULONG WINAPI fontfileloader_Release(IDWriteFontFileLoader *iface) return 1; } -static HRESULT WINAPI fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileStream **fontFileStream) +static HRESULT WINAPI fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, IDWriteFontFileStream **fontFileStream) { return 0x8faecafe; } @@ -1942,6 +1950,114 @@ static const struct IDWriteFontFileLoaderVtbl dwritefontfileloadervtbl = { fontfileloader_CreateStreamFromKey }; +struct raw_cff_stream { + IDWriteFontFileStream IDWriteFontFileStream_iface; + LONG ref; + const char *data; + UINT64 length; +}; + +static inline struct raw_cff_stream *impl_from_IDwriteFontFileStream(IDWriteFontFileStream *iface) +{ + return CONTAINING_RECORD(iface, struct raw_cff_stream, IDWriteFontFileStream_iface); +} + +static HRESULT WINAPI raw_cff_stream_QueryInterface(IDWriteFontFileStream *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IDWriteFontFileStream) || IsEqualIID(riid, &IID_IUnknown)) { + *obj = iface; + IDWriteFontFileStream_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI raw_cff_stream_AddRef(IDWriteFontFileStream *iface) +{ + struct raw_cff_stream *stream = impl_from_IDwriteFontFileStream(iface); + return InterlockedIncrement(&stream->ref); +} + +static ULONG WINAPI raw_cff_stream_Release(IDWriteFontFileStream *iface) +{ + struct raw_cff_stream *stream = impl_from_IDwriteFontFileStream(iface); + ULONG ref = InterlockedDecrement(&stream->ref); + + if (!ref) + HeapFree(GetProcessHeap(), 0, stream); + + return ref; +} + +static HRESULT WINAPI raw_cff_stream_ReadFileFragment(IDWriteFontFileStream *iface, const void **fragment_start, + UINT64 offset, UINT64 fragment_size, void **context) +{ + struct raw_cff_stream *stream = impl_from_IDwriteFontFileStream(iface); + + *context = NULL; + + if (offset + fragment_size > stream->length) { + *fragment_start = NULL; + return E_FAIL; + } + + *fragment_start = stream->data + offset; + return S_OK; +} + +static void WINAPI raw_cff_stream_ReleaseFileFragment(IDWriteFontFileStream *iface, void *context) +{ +} + +static HRESULT WINAPI raw_cff_stream_GetFileSize(IDWriteFontFileStream *iface, UINT64 *size) +{ + struct raw_cff_stream *stream = impl_from_IDwriteFontFileStream(iface); + *size = stream->length; + return S_OK; +} + +static HRESULT WINAPI raw_cff_stream_GetLastWriteTime(IDWriteFontFileStream *iface, UINT64 *writetime) +{ + *writetime = 0; + return S_OK; +} + +static const IDWriteFontFileStreamVtbl raw_cff_stream_vtbl = { + raw_cff_stream_QueryInterface, + raw_cff_stream_AddRef, + raw_cff_stream_Release, + raw_cff_stream_ReadFileFragment, + raw_cff_stream_ReleaseFileFragment, + raw_cff_stream_GetFileSize, + raw_cff_stream_GetLastWriteTime +}; + +static HRESULT WINAPI fontfileloader_raw_cff_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *reference_key, + UINT32 reference_key_size, IDWriteFontFileStream **ret) +{ + struct raw_cff_stream *stream; + + ok(reference_key_size > 0, "wrong key size %u\n", reference_key_size); + + stream = HeapAlloc(GetProcessHeap(), 0, sizeof(*stream)); + stream->IDWriteFontFileStream_iface.lpVtbl = &raw_cff_stream_vtbl; + stream->ref = 1; + stream->data = reference_key; + stream->length = reference_key_size; + + *ret = &stream->IDWriteFontFileStream_iface; + return S_OK; +} + +static const struct IDWriteFontFileLoaderVtbl raw_cff_fileloadervtbl = { + fontfileloader_QueryInterface, + fontfileloader_AddRef, + fontfileloader_Release, + fontfileloader_raw_cff_CreateStreamFromKey +}; + static void test_CreateCustomFontFileReference(void) { IDWriteFontFileLoader floader = { &dwritefontfileloadervtbl }; @@ -5189,6 +5305,109 @@ todo_wine { IDWriteFactory2_Release(factory2); } +static void test_raw_cff(void) +{ + static const WCHAR test_cff_file[] = {'w','i','n','e','_','t','e','s','t','_','f','o','n','t','_','c','f','f','.','o','t','f',0}; + IDWriteFontFileLoader cffloader = { &raw_cff_fileloadervtbl }; + IDWriteFontFile *cff_file, *raw_cff_file, *file; + DWRITE_FONT_FILE_TYPE filetype; + DWRITE_FONT_FACE_TYPE facetype; + DWRITE_FONT_METRICS metrics; + IDWriteFontFace *cff_face; + IDWriteFactory *factory; + BOOL exists, supported; + const void *cff_table; + void *cff_context; + UINT32 cff_size; + WCHAR *path; + HRESULT hr; + UINT32 num; + + factory = create_factory(); + + /* create CFF test file, and locate 'CFF ' table */ + path = create_testfontfile_from_res(2, test_cff_file); + hr = IDWriteFactory_CreateFontFileReference(factory, path, NULL, &cff_file); + ok(hr == S_OK, "got 0x%08x\n",hr); + + hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_CFF, 1, &cff_file, 0, DWRITE_FONT_SIMULATIONS_NONE, &cff_face); + ok(hr == S_OK, "got 0x%08x\n", hr); + + exists = FALSE; + hr = IDWriteFontFace_TryGetFontTable(cff_face, MS_CFF_TAG, &cff_table, &cff_size, &cff_context, &exists); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(exists, "got %d\n", exists); + + hr = IDWriteFactory_RegisterFontFileLoader(factory, &cffloader); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFactory_CreateCustomFontFileReference(factory, cff_table, cff_size, &cffloader, &raw_cff_file); + ok(hr == S_OK, "got 0x%08x\n", hr); + IDWriteFontFace_ReleaseFontTable(cff_face, cff_context); + IDWriteFontFace_Release(cff_face); + + supported = TRUE; + filetype = DWRITE_FONT_FILE_TYPE_TRUETYPE; + facetype = DWRITE_FONT_FACE_TYPE_TRUETYPE; + num = 1; + hr = IDWriteFontFile_Analyze(raw_cff_file, &supported, &filetype, &facetype, &num); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(num == 0, "got %u\n", num); + ok(filetype == DWRITE_FONT_FILE_TYPE_UNKNOWN, "got %d\n", filetype); + ok(facetype == DWRITE_FONT_FACE_TYPE_UNKNOWN, "got %d\n", filetype); + ok(!supported, "got %d\n", supported); + + facetype = DWRITE_FONT_FACE_TYPE_UNKNOWN; + hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_RAW_CFF, 1, &raw_cff_file, 0, DWRITE_FONT_SIMULATIONS_NONE, + &cff_face); +todo_wine + ok(hr == S_OK || broken(hr == E_INVALIDARG) /* vista does not support this */, "got 0x%08x\n", hr); + + if (hr == S_OK) { + /* try *RAW_CFF font face methods */ + facetype = IDWriteFontFace_GetType(cff_face); + ok(facetype == DWRITE_FONT_FACE_TYPE_RAW_CFF, "got %d\n", facetype); + + num = 1; + hr = IDWriteFontFace_GetFiles(cff_face, &num, &file); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(num == 1, "got %u\n", num); + ok(file == raw_cff_file, "got %p, %p\n", file, raw_cff_file); + IDWriteFontFile_Release(file); + + num = IDWriteFontFace_GetIndex(cff_face); + ok(num == 0, "got %u\n", num); + + memset(&metrics, 0xcc, sizeof(metrics)); + IDWriteFontFace_GetMetrics(cff_face, &metrics); + ok(metrics.designUnitsPerEm == 1000, "got %u\n", metrics.designUnitsPerEm); + ok(metrics.ascent == 0, "got %u\n", metrics.ascent); + ok(metrics.descent == 0, "got %u\n", metrics.descent); + ok(metrics.lineGap == 0, "got %d\n", metrics.lineGap); + ok(metrics.capHeight == 0, "got %u\n", metrics.capHeight); + ok(metrics.xHeight == 0, "got %u\n", metrics.xHeight); + ok(metrics.underlinePosition == 0, "got %d\n", metrics.underlinePosition); + ok(metrics.underlineThickness == 0, "got %u\n", metrics.underlineThickness); + ok(metrics.strikethroughPosition == 0, "got %d\n", metrics.strikethroughPosition); + ok(metrics.strikethroughThickness == 0, "got %u\n", metrics.strikethroughThickness); + + num = IDWriteFontFace_GetGlyphCount(cff_face); + ok(num > 0, "got %u\n", num); + IDWriteFontFace_Release(cff_face); + + /* try with regular CFF type */ + hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_CFF, 1, &raw_cff_file, 0, DWRITE_FONT_SIMULATIONS_NONE, + &cff_face); + ok(hr == DWRITE_E_FILEFORMAT, "got 0x%08x\n", hr); + } + + IDWriteFactory_UnregisterFontFileLoader(factory, &cffloader); + IDWriteFontFile_Release(raw_cff_file); + IDWriteFontFile_Release(cff_file); + IDWriteFactory_Release(factory); + DELETE_FONTFILE(path); +} + START_TEST(font) { IDWriteFactory *factory; @@ -5241,6 +5460,7 @@ START_TEST(font) test_IsSymbolFont(); test_GetPaletteEntries(); test_TranslateColorGlyphRun(); + test_raw_cff(); IDWriteFactory_Release(factory); } diff --git a/dlls/dwrite/tests/resource.rc b/dlls/dwrite/tests/resource.rc index b761ebc..7bd85cb 100644 --- a/dlls/dwrite/tests/resource.rc +++ b/dlls/dwrite/tests/resource.rc @@ -22,3 +22,5 @@ /* @makedep: wine_test.ttf */ 1 RCDATA wine_test.ttf +/* @makedep: wine_test_cff.otf */ +2 RCDATA wine_test_cff.otf diff --git a/dlls/dwrite/tests/wine_test_cff.otf b/dlls/dwrite/tests/wine_test_cff.otf new file mode 100644 index 0000000000000000000000000000000000000000..c9d2cd5153b1b4c6c4a293538c78490c941ac966 GIT binary patch literal 1900 zcmcIlUrbw79RAL|w*|VUAX^!lig&sxdl1* zOLU=2e3;4bVM7xiNWnkTr>Susr2=;`-=Fnv1GT<@+aW@;nN%)5$q-viGSlx^R%PmvU?W3+){X zw_?i0<43s%xrC1Yhb?T zDF+fGvr{${&6M5Akwo<4@0K2Au0=rGJC&Nw$k!1fKbm1GW~$GoFAopbAO8h=^gGHh zf9Rvd%6wp}AkOLMDc3?%S~kY$=eG(tBP@S$&dOxl?6C$QC63U<9dS=Bs4Zz~7nkf= z+(w7csfC-P(-fadI~7kx@dOTFRX61^oY76(qH)K^guMeFKB#CP!P5>FsAE-ZZ!Usm z2kQvnTL&Ac6CMY<&>*@T?56%DR#X^uTrtdUV}V9YI#`1jOAgj?3@Z*c=<}(;oZK*7!ye+?!H|1GsRh-?7ZJ=i1t~OO$s_;&1m9h%*MeSVwD*gWe|3d!1 z%kR*a7u0uUcM~uS2q8R`s{x_$NV`k*C_N}jEn4Xzy|mwGDd3%D>D61FSv3~C#(Mda zVsX>s3gG?v0MHP?r}qW0KOnwogiFP{(S*nGB%WiBjT&Fh zSIm?){rTLR#pkZ)1`4N-ewcIlirIOkD)(Jq8aR5oV5z<;J?6jB?vkjF4Be3O$9!I* zC7*xUQq-1b$`}2g6;pmGe~t`UL+&*RFTIrO)vUzc{2DJRjqpbz5>5I173DCHv)mRq zt{GC^&9A*HO)AXIx#e0++0y>=h}0%I9-d`h|sT)^g;9SF8M>()*pYEmFC+ zZ32o#t=eh9SDN3K^UtizZ{F{2@t|ROR(k7lUJp-C-F6>)Gfa-^_*9{I1uV(7+b`m8 W--Sr<6|(Wq@&)@%_OvDQPx>c!o_etW literal 0 HcmV?d00001 diff --git a/dlls/dwrite/tests/wine_test_cff.sfd b/dlls/dwrite/tests/wine_test_cff.sfd new file mode 100644 index 0000000..1719a01 --- /dev/null +++ b/dlls/dwrite/tests/wine_test_cff.sfd @@ -0,0 +1,244 @@ +SplineFontDB: 3.0 +FontName: wine_test +FullName: wine_test +FamilyName: wine_test +Weight: Medium +Copyright: Copyright (c) 2010 Dmitry Timoshkov +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -100.098 +UnderlineWidth: 49.8047 +Ascent: 800 +Descent: 200 +sfntRevision: 0x00010000 +LayerCount: 2 +Layer: 0 1 "Back" 1 +Layer: 1 1 "Fore" 0 +XUID: [1021 905 592216984 1247726] +FSType: 0 +OS2Version: 2 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +PfmFamily: 17 +TTFWeight: 500 +TTFWidth: 5 +LineGap: 90 +VLineGap: 0 +Panose: 2 0 6 3 0 0 0 0 0 0 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 90 +OS2WinAscent: 800 +OS2WinAOffset: 0 +OS2WinDescent: 200 +OS2WinDOffset: 0 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2SubXSize: 650 +OS2SubYSize: 700 +OS2SubXOff: 0 +OS2SubYOff: 140 +OS2SupXSize: 650 +OS2SupYSize: 700 +OS2SupXOff: 0 +OS2SupYOff: 480 +OS2StrikeYSize: 50 +OS2StrikeYPos: 259 +OS2Vendor: 'Wine' +OS2CodePages: 00000001.00000000 +OS2UnicodeRanges: 00000001.00000000.00000000.00000000 +MarkAttachClasses: 1 +DEI: 91125 +ShortTable: cvt 2 + 68 + 1297 +EndShort +ShortTable: maxp 16 + 1 + 0 + 4 + 8 + 2 + 0 + 0 + 2 + 0 + 1 + 1 + 0 + 64 + 46 + 0 + 0 +EndShort +LangName: 1033 "" "" "" "Wine : wine_test : 4-11-2010" +GaspTable: 1 65535 2 0 +Encoding: UnicodeBmp +UnicodeInterp: none +NameList: Adobe Glyph List +DisplaySize: -24 +AntiAlias: 1 +FitToEm: 1 +WinInfo: 43 43 16 +BeginPrivate: 0 +EndPrivate +BeginChars: 65539 7 + +StartChar: .notdef +Encoding: 65536 -1 0 +AltUni2: 00fffb.ffffffff.0 00fffc.ffffffff.0 00fffd.ffffffff.0 00fffe.ffffffff.0 +Width: 365 +Flags: W +TtInstrs: +PUSHB_2 + 1 + 0 +MDAP[rnd] +ALIGNRP +PUSHB_3 + 7 + 4 + 0 +MIRP[min,rnd,black] +SHP[rp2] +PUSHB_2 + 6 + 5 +MDRP[rp0,min,rnd,grey] +ALIGNRP +PUSHB_3 + 3 + 2 + 0 +MIRP[min,rnd,black] +SHP[rp2] +SVTCA[y-axis] +PUSHB_2 + 3 + 0 +MDAP[rnd] +ALIGNRP +PUSHB_3 + 5 + 4 + 0 +MIRP[min,rnd,black] +SHP[rp2] +PUSHB_3 + 7 + 6 + 1 +MIRP[rp0,min,rnd,grey] +ALIGNRP +PUSHB_3 + 1 + 2 + 0 +MIRP[min,rnd,black] +SHP[rp2] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +33 0 m 1,0,-1 + 33 667 l 1,1,-1 + 299 667 l 1,2,-1 + 299 0 l 1,3,-1 + 33 0 l 1,0,-1 +66 33 m 1,4,-1 + 266 33 l 1,5,-1 + 266 633 l 1,6,-1 + 66 633 l 1,7,-1 + 66 33 l 1,4,-1 +EndSplineSet +EndChar + +StartChar: .null +Encoding: 65537 -1 1 +Width: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: nonmarkingreturn +Encoding: 65538 -1 2 +Width: 333 +Flags: W +LayerCount: 2 +EndChar + +StartChar: exclam +Encoding: 33 33 3 +Width: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: dieresis +Encoding: 168 168 4 +Width: 488 +VWidth: 0 +Flags: W +LayerCount: 2 +Fore +SplineSet +303 403 m 1,0,1 + 372 380 372 380 349 311 c 1,2,-1 + 303 403 l 1,0,1 +76 159 m 0,3,-1 +124 378 m 1,4,5 + 151 408 151 408 183 375 c 1,6,7 + 201 356 201 356 183 337 c 0,8,9 + 151 303 151 303 124 336 c 0,10,11 + 105 359 105 359 124 378 c 1,4,5 +124 378 m 1,12,13 + 105 359 105 359 124 336 c 0,14,15 + 150 304 150 304 183 337 c 0,16,17 + 201 355 201 355 183 375 c 1,18,19 + 151 408 151 408 124 378 c 1,12,13 +EndSplineSet +EndChar + +StartChar: A +Encoding: 65 65 5 +Width: 488 +VWidth: 0 +Flags: W +LayerCount: 2 +Fore +SplineSet +224 614 m 25,0,-1 + 226 800 l 1,1,-1 + 190 800 l 1,2,-1 + 240 886 l 1,3,-1 + 297 800 l 1,4,-1 + 259 800 l 1,5,-1 + 255 614 l 1,6,-1 + 224 614 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: D +Encoding: 68 68 6 +Width: 488 +VWidth: 0 +Flags: W +LayerCount: 2 +Fore +SplineSet +225 -15 m 25,0,-1 + 227 -201 l 1,1,-1 + 191 -201 l 1,2,-1 + 241 -287 l 1,3,-1 + 298 -201 l 1,4,-1 + 260 -200 l 1,5,-1 + 256 -15 l 1,6,-1 + 225 -15 l 25,0,-1 +EndSplineSet +EndChar +EndChars +EndSplineFont -- 2.6.2