4 * Copyright 2012, 2014 Nikolay Sivov for CodeWeavers
5 * Copyright 2014 Aric Stewart for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include "wine/test.h"
35 #define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
36 ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
37 ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
39 #define MS_CMAP_TAG MS_MAKE_TAG('c','m','a','p')
40 #define MS_VDMX_TAG MS_MAKE_TAG('V','D','M','X')
41 #define MS_GASP_TAG MS_MAKE_TAG('g','a','s','p')
42 #define MS_CPAL_TAG MS_MAKE_TAG('C','P','A','L')
44 #define EXPECT_HR(hr,hr_exp) \
45 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
47 #define DEFINE_EXPECT(func) \
48 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
50 #define SET_EXPECT(func) \
51 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
53 #define CHECK_EXPECT2(func) \
55 ok(expect_ ##func, "unexpected call " #func "\n"); \
56 called_ ## func = TRUE; \
59 #define CHECK_EXPECT(func) \
61 CHECK_EXPECT2(func); \
62 expect_ ## func = FALSE; \
65 #define CHECK_CALLED(func) \
67 ok(called_ ## func, "expected " #func "\n"); \
68 expect_ ## func = called_ ## func = FALSE; \
71 #define CLEAR_CALLED(func) \
72 expect_ ## func = called_ ## func = FALSE
74 DEFINE_EXPECT(setfillmode
);
76 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
77 static void _expect_ref(IUnknown
* obj
, ULONG ref
, int line
)
81 rc
= IUnknown_Release(obj
);
82 ok_(__FILE__
,line
)(rc
== ref
, "expected refcount %d, got %d\n", ref
, rc
);
85 static inline void *heap_alloc(size_t len
)
87 return HeapAlloc(GetProcessHeap(), 0, len
);
90 static inline BOOL
heap_free(void *mem
)
92 return HeapFree(GetProcessHeap(), 0, mem
);
95 static const WCHAR test_fontfile
[] = {'w','i','n','e','_','t','e','s','t','_','f','o','n','t','.','t','t','f',0};
96 static const WCHAR tahomaW
[] = {'T','a','h','o','m','a',0};
97 static const WCHAR arialW
[] = {'A','r','i','a','l',0};
98 static const WCHAR tahomaUppercaseW
[] = {'T','A','H','O','M','A',0};
99 static const WCHAR tahomaStrangecaseW
[] = {'t','A','h','O','m','A',0};
100 static const WCHAR blahW
[] = {'B','l','a','h','!',0};
101 static const WCHAR emojiW
[] = {'S','e','g','o','e',' ','U','I',' ','E','m','o','j','i',0};
103 static IDWriteFactory
*create_factory(void)
105 IDWriteFactory
*factory
;
106 HRESULT hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory
);
107 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
111 static IDWriteFontFace
*create_fontface(IDWriteFactory
*factory
)
113 static const WCHAR tahomaW
[] = {'T','a','h','o','m','a',0};
114 IDWriteGdiInterop
*interop
;
115 IDWriteFontFace
*fontface
;
120 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
121 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
123 memset(&logfont
, 0, sizeof(logfont
));
124 logfont
.lfHeight
= 12;
125 logfont
.lfWidth
= 12;
126 logfont
.lfWeight
= FW_NORMAL
;
127 logfont
.lfItalic
= 1;
128 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
130 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
131 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
133 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
134 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
136 IDWriteFont_Release(font
);
137 IDWriteGdiInterop_Release(interop
);
142 static WCHAR
*create_testfontfile(const WCHAR
*filename
)
144 static WCHAR pathW
[MAX_PATH
];
150 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
151 lstrcatW(pathW
, filename
);
153 file
= CreateFileW(pathW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
154 ok(file
!= INVALID_HANDLE_VALUE
, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW
),
157 res
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
158 ok( res
!= 0, "couldn't find resource\n" );
159 ptr
= LockResource( LoadResource( GetModuleHandleA(NULL
), res
));
160 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleA(NULL
), res
), &written
, NULL
);
161 ok( written
== SizeofResource( GetModuleHandleA(NULL
), res
), "couldn't write resource\n" );
167 #define DELETE_FONTFILE(filename) _delete_testfontfile(filename, __LINE__)
168 static void _delete_testfontfile(const WCHAR
*filename
, int line
)
170 BOOL ret
= DeleteFileW(filename
);
171 ok_(__FILE__
,line
)(ret
, "failed to delete file %s, error %d\n", wine_dbgstr_w(filename
), GetLastError());
174 struct test_fontenumerator
176 IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface
;
180 IDWriteFontFile
*font_file
;
183 static inline struct test_fontenumerator
*impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator
* iface
)
185 return CONTAINING_RECORD(iface
, struct test_fontenumerator
, IDWriteFontFileEnumerator_iface
);
188 static HRESULT WINAPI
singlefontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
190 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
))
193 IDWriteFontFileEnumerator_AddRef(iface
);
196 return E_NOINTERFACE
;
199 static ULONG WINAPI
singlefontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
201 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
202 return InterlockedIncrement(&This
->ref
);
205 static ULONG WINAPI
singlefontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
207 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
208 ULONG ref
= InterlockedDecrement(&This
->ref
);
210 IDWriteFontFile_Release(This
->font_file
);
216 static HRESULT WINAPI
singlefontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**font_file
)
218 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
219 IDWriteFontFile_AddRef(This
->font_file
);
220 *font_file
= This
->font_file
;
224 static HRESULT WINAPI
singlefontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
226 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
228 if (This
->index
> 1) {
238 static const struct IDWriteFontFileEnumeratorVtbl singlefontfileenumeratorvtbl
=
240 singlefontfileenumerator_QueryInterface
,
241 singlefontfileenumerator_AddRef
,
242 singlefontfileenumerator_Release
,
243 singlefontfileenumerator_MoveNext
,
244 singlefontfileenumerator_GetCurrentFontFile
247 static HRESULT
create_enumerator(IDWriteFontFile
*font_file
, IDWriteFontFileEnumerator
**ret
)
249 struct test_fontenumerator
*enumerator
;
251 enumerator
= heap_alloc(sizeof(struct test_fontenumerator
));
253 return E_OUTOFMEMORY
;
255 enumerator
->IDWriteFontFileEnumerator_iface
.lpVtbl
= &singlefontfileenumeratorvtbl
;
257 enumerator
->index
= 0;
258 enumerator
->font_file
= font_file
;
259 IDWriteFontFile_AddRef(font_file
);
261 *ret
= &enumerator
->IDWriteFontFileEnumerator_iface
;
265 struct test_fontcollectionloader
267 IDWriteFontCollectionLoader IDWriteFontFileCollectionLoader_iface
;
268 IDWriteFontFileLoader
*loader
;
271 static inline struct test_fontcollectionloader
*impl_from_IDWriteFontFileCollectionLoader(IDWriteFontCollectionLoader
* iface
)
273 return CONTAINING_RECORD(iface
, struct test_fontcollectionloader
, IDWriteFontFileCollectionLoader_iface
);
276 static HRESULT WINAPI
resourcecollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
278 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontCollectionLoader
))
281 IDWriteFontCollectionLoader_AddRef(iface
);
284 return E_NOINTERFACE
;
287 static ULONG WINAPI
resourcecollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
292 static ULONG WINAPI
resourcecollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
297 static HRESULT WINAPI
resourcecollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
*factory
,
298 const void * collectionKey
, UINT32 collectionKeySize
, IDWriteFontFileEnumerator
** fontFileEnumerator
)
300 struct test_fontcollectionloader
*This
= impl_from_IDWriteFontFileCollectionLoader(iface
);
301 IDWriteFontFile
*font_file
;
304 IDWriteFactory_CreateCustomFontFileReference(factory
, collectionKey
, collectionKeySize
, This
->loader
, &font_file
);
306 hr
= create_enumerator(font_file
, fontFileEnumerator
);
307 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
309 IDWriteFontFile_Release(font_file
);
313 static const struct IDWriteFontCollectionLoaderVtbl resourcecollectionloadervtbl
= {
314 resourcecollectionloader_QueryInterface
,
315 resourcecollectionloader_AddRef
,
316 resourcecollectionloader_Release
,
317 resourcecollectionloader_CreateEnumeratorFromKey
320 /* Here is a functional custom font set of interfaces */
321 struct test_fontdatastream
323 IDWriteFontFileStream IDWriteFontFileStream_iface
;
330 static inline struct test_fontdatastream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
* iface
)
332 return CONTAINING_RECORD(iface
, struct test_fontdatastream
, IDWriteFontFileStream_iface
);
335 static HRESULT WINAPI
fontdatastream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
337 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
340 IDWriteFontFileStream_AddRef(iface
);
344 return E_NOINTERFACE
;
347 static ULONG WINAPI
fontdatastream_AddRef(IDWriteFontFileStream
*iface
)
349 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
350 ULONG ref
= InterlockedIncrement(&This
->ref
);
354 static ULONG WINAPI
fontdatastream_Release(IDWriteFontFileStream
*iface
)
356 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
357 ULONG ref
= InterlockedDecrement(&This
->ref
);
359 HeapFree(GetProcessHeap(), 0, This
);
363 static HRESULT WINAPI
fontdatastream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
365 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
366 *fragment_context
= NULL
;
367 if (offset
+fragment_size
> This
->size
)
369 *fragment_start
= NULL
;
374 *fragment_start
= (BYTE
*)This
->data
+ offset
;
379 static void WINAPI
fontdatastream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
384 static HRESULT WINAPI
fontdatastream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
386 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
391 static HRESULT WINAPI
fontdatastream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
396 static const IDWriteFontFileStreamVtbl fontdatastreamvtbl
=
398 fontdatastream_QueryInterface
,
399 fontdatastream_AddRef
,
400 fontdatastream_Release
,
401 fontdatastream_ReadFileFragment
,
402 fontdatastream_ReleaseFileFragment
,
403 fontdatastream_GetFileSize
,
404 fontdatastream_GetLastWriteTime
407 static HRESULT
create_fontdatastream(LPVOID data
, UINT size
, IDWriteFontFileStream
** iface
)
409 struct test_fontdatastream
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct test_fontdatastream
));
411 return E_OUTOFMEMORY
;
416 This
->IDWriteFontFileStream_iface
.lpVtbl
= &fontdatastreamvtbl
;
418 *iface
= &This
->IDWriteFontFileStream_iface
;
422 static HRESULT WINAPI
resourcefontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
424 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
430 return E_NOINTERFACE
;
433 static ULONG WINAPI
resourcefontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
438 static ULONG WINAPI
resourcefontfileloader_Release(IDWriteFontFileLoader
*iface
)
443 static HRESULT WINAPI
resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
449 mem
= LoadResource(GetModuleHandleA(NULL
), *(HRSRC
*)fontFileReferenceKey
);
450 ok(mem
!= NULL
, "Failed to lock font resource\n");
453 size
= SizeofResource(GetModuleHandleA(NULL
), *(HRSRC
*)fontFileReferenceKey
);
454 data
= LockResource(mem
);
455 return create_fontdatastream(data
, size
, fontFileStream
);
460 static const struct IDWriteFontFileLoaderVtbl resourcefontfileloadervtbl
= {
461 resourcefontfileloader_QueryInterface
,
462 resourcefontfileloader_AddRef
,
463 resourcefontfileloader_Release
,
464 resourcefontfileloader_CreateStreamFromKey
467 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
469 static D2D1_POINT_2F g_startpoints
[2];
470 static int g_startpoint_count
;
472 static HRESULT WINAPI
test_geometrysink_QueryInterface(ID2D1SimplifiedGeometrySink
*iface
, REFIID riid
, void **ret
)
474 if (IsEqualIID(riid
, &IID_ID2D1SimplifiedGeometrySink
) ||
475 IsEqualIID(riid
, &IID_IUnknown
))
478 ID2D1SimplifiedGeometrySink_AddRef(iface
);
483 return E_NOINTERFACE
;
486 static ULONG WINAPI
test_geometrysink_AddRef(ID2D1SimplifiedGeometrySink
*iface
)
491 static ULONG WINAPI
test_geometrysink_Release(ID2D1SimplifiedGeometrySink
*iface
)
496 static void WINAPI
test_geometrysink_SetFillMode(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FILL_MODE mode
)
498 CHECK_EXPECT(setfillmode
);
499 ok(mode
== D2D1_FILL_MODE_WINDING
, "fill mode %d\n", mode
);
502 static void WINAPI
test_geometrysink_SetSegmentFlags(ID2D1SimplifiedGeometrySink
*iface
, D2D1_PATH_SEGMENT flags
)
504 ok(0, "unexpected SetSegmentFlags() - flags %d\n", flags
);
507 static void WINAPI
test_geometrysink_BeginFigure(ID2D1SimplifiedGeometrySink
*iface
,
508 D2D1_POINT_2F startPoint
, D2D1_FIGURE_BEGIN figureBegin
)
510 ok(figureBegin
== D2D1_FIGURE_BEGIN_FILLED
, "begin figure %d\n", figureBegin
);
511 if (g_startpoint_count
< sizeof(g_startpoints
)/sizeof(g_startpoints
[0]))
512 g_startpoints
[g_startpoint_count
] = startPoint
;
513 g_startpoint_count
++;
516 static void WINAPI
test_geometrysink_AddLines(ID2D1SimplifiedGeometrySink
*iface
,
517 const D2D1_POINT_2F
*points
, UINT32 count
)
521 static void WINAPI
test_geometrysink_AddBeziers(ID2D1SimplifiedGeometrySink
*iface
,
522 const D2D1_BEZIER_SEGMENT
*beziers
, UINT32 count
)
526 static void WINAPI
test_geometrysink_EndFigure(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FIGURE_END figureEnd
)
528 ok(figureEnd
== D2D1_FIGURE_END_CLOSED
, "end figure %d\n", figureEnd
);
531 static HRESULT WINAPI
test_geometrysink_Close(ID2D1SimplifiedGeometrySink
*iface
)
533 ok(0, "unexpected Close()\n");
537 static const ID2D1SimplifiedGeometrySinkVtbl test_geometrysink_vtbl
= {
538 test_geometrysink_QueryInterface
,
539 test_geometrysink_AddRef
,
540 test_geometrysink_Release
,
541 test_geometrysink_SetFillMode
,
542 test_geometrysink_SetSegmentFlags
,
543 test_geometrysink_BeginFigure
,
544 test_geometrysink_AddLines
,
545 test_geometrysink_AddBeziers
,
546 test_geometrysink_EndFigure
,
547 test_geometrysink_Close
550 static void WINAPI
test_geometrysink2_BeginFigure(ID2D1SimplifiedGeometrySink
*iface
,
551 D2D1_POINT_2F startPoint
, D2D1_FIGURE_BEGIN figureBegin
)
553 ok(0, "unexpected call\n");
556 static void WINAPI
test_geometrysink2_AddLines(ID2D1SimplifiedGeometrySink
*iface
,
557 const D2D1_POINT_2F
*points
, UINT32 count
)
559 ok(0, "unexpected call\n");
562 static void WINAPI
test_geometrysink2_AddBeziers(ID2D1SimplifiedGeometrySink
*iface
,
563 const D2D1_BEZIER_SEGMENT
*beziers
, UINT32 count
)
565 ok(0, "unexpected call\n");
568 static void WINAPI
test_geometrysink2_EndFigure(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FIGURE_END figureEnd
)
570 ok(0, "unexpected call\n");
573 static const ID2D1SimplifiedGeometrySinkVtbl test_geometrysink2_vtbl
= {
574 test_geometrysink_QueryInterface
,
575 test_geometrysink_AddRef
,
576 test_geometrysink_Release
,
577 test_geometrysink_SetFillMode
,
578 test_geometrysink_SetSegmentFlags
,
579 test_geometrysink2_BeginFigure
,
580 test_geometrysink2_AddLines
,
581 test_geometrysink2_AddBeziers
,
582 test_geometrysink2_EndFigure
,
583 test_geometrysink_Close
586 static ID2D1SimplifiedGeometrySink test_geomsink
= { &test_geometrysink_vtbl
};
587 static ID2D1SimplifiedGeometrySink test_geomsink2
= { &test_geometrysink2_vtbl
};
589 static void test_CreateFontFromLOGFONT(void)
591 static const WCHAR tahomaspW
[] = {'T','a','h','o','m','a',' ',0};
592 IDWriteGdiInterop
*interop
;
593 DWRITE_FONT_WEIGHT weight
;
594 DWRITE_FONT_STYLE style
;
597 LONG weights
[][2] = {
598 {FW_NORMAL
, DWRITE_FONT_WEIGHT_NORMAL
},
599 {FW_BOLD
, DWRITE_FONT_WEIGHT_BOLD
},
600 { 0, DWRITE_FONT_WEIGHT_NORMAL
},
601 { 50, DWRITE_FONT_WEIGHT_NORMAL
},
602 {150, DWRITE_FONT_WEIGHT_NORMAL
},
603 {250, DWRITE_FONT_WEIGHT_NORMAL
},
604 {350, DWRITE_FONT_WEIGHT_NORMAL
},
605 {450, DWRITE_FONT_WEIGHT_NORMAL
},
606 {650, DWRITE_FONT_WEIGHT_BOLD
},
607 {750, DWRITE_FONT_WEIGHT_BOLD
},
608 {850, DWRITE_FONT_WEIGHT_BOLD
},
609 {950, DWRITE_FONT_WEIGHT_BOLD
},
610 {960, DWRITE_FONT_WEIGHT_BOLD
},
612 OUTLINETEXTMETRICW otm
;
613 IDWriteFactory
*factory
;
622 factory
= create_factory();
624 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
628 /* null out parameter crashes this call */
629 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, NULL
);
631 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, &font
);
632 EXPECT_HR(hr
, E_INVALIDARG
);
634 memset(&logfont
, 0, sizeof(logfont
));
635 logfont
.lfHeight
= 12;
636 logfont
.lfWidth
= 12;
637 logfont
.lfWeight
= FW_NORMAL
;
638 logfont
.lfItalic
= 1;
639 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
641 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
644 hfont
= CreateFontIndirectW(&logfont
);
645 hdc
= CreateCompatibleDC(0);
646 SelectObject(hdc
, hfont
);
648 otm
.otmSize
= sizeof(otm
);
649 r
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
650 ok(r
, "got %d\n", r
);
655 hr
= IDWriteFont_HasCharacter(font
, 0xd800, &exists
);
656 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
657 ok(exists
== FALSE
, "got %d\n", exists
);
660 hr
= IDWriteFont_HasCharacter(font
, 0x20, &exists
);
661 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
662 ok(exists
== TRUE
, "got %d\n", exists
);
664 /* now check properties */
665 weight
= IDWriteFont_GetWeight(font
);
666 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
, "got %d\n", weight
);
668 style
= IDWriteFont_GetStyle(font
);
669 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %d\n", style
);
671 ok(otm
.otmfsSelection
== 1, "got 0x%08x\n", otm
.otmfsSelection
);
673 ret
= IDWriteFont_IsSymbolFont(font
);
674 ok(!ret
, "got %d\n", ret
);
676 IDWriteFont_Release(font
);
679 for (i
= 0; i
< sizeof(weights
)/(2*sizeof(LONG
)); i
++)
681 memset(&logfont
, 0, sizeof(logfont
));
682 logfont
.lfHeight
= 12;
683 logfont
.lfWidth
= 12;
684 logfont
.lfWeight
= weights
[i
][0];
685 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
687 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
690 weight
= IDWriteFont_GetWeight(font
);
691 ok(weight
== weights
[i
][1],
692 "%d: got %d, expected %d\n", i
, weight
, weights
[i
][1]);
694 IDWriteFont_Release(font
);
697 /* weight not from enum */
698 memset(&logfont
, 0, sizeof(logfont
));
699 logfont
.lfHeight
= 12;
700 logfont
.lfWidth
= 12;
701 logfont
.lfWeight
= 550;
702 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
705 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
706 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
708 weight
= IDWriteFont_GetWeight(font
);
709 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
|| weight
== DWRITE_FONT_WEIGHT_BOLD
,
711 IDWriteFont_Release(font
);
713 /* empty or nonexistent face name */
714 memset(&logfont
, 0, sizeof(logfont
));
715 logfont
.lfHeight
= 12;
716 logfont
.lfWidth
= 12;
717 logfont
.lfWeight
= FW_NORMAL
;
718 lstrcpyW(logfont
.lfFaceName
, blahW
);
720 font
= (void*)0xdeadbeef;
721 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
722 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
723 ok(font
== NULL
, "got %p\n", font
);
725 /* Try with name 'Tahoma ' */
726 memset(&logfont
, 0, sizeof(logfont
));
727 logfont
.lfHeight
= 12;
728 logfont
.lfWidth
= 12;
729 logfont
.lfWeight
= FW_NORMAL
;
730 lstrcpyW(logfont
.lfFaceName
, tahomaspW
);
732 font
= (void*)0xdeadbeef;
733 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
734 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
735 ok(font
== NULL
, "got %p\n", font
);
737 /* empty string as a facename */
738 memset(&logfont
, 0, sizeof(logfont
));
739 logfont
.lfHeight
= 12;
740 logfont
.lfWidth
= 12;
741 logfont
.lfWeight
= FW_NORMAL
;
743 font
= (void*)0xdeadbeef;
744 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
745 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
746 ok(font
== NULL
, "got %p\n", font
);
748 IDWriteGdiInterop_Release(interop
);
749 IDWriteFactory_Release(factory
);
752 static void test_CreateBitmapRenderTarget(void)
754 IDWriteBitmapRenderTarget
*target
, *target2
;
755 IDWriteBitmapRenderTarget1
*target1
;
756 IDWriteGdiInterop
*interop
;
757 IDWriteFactory
*factory
;
769 factory
= create_factory();
771 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
775 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target
);
778 if (0) /* crashes on native */
779 hr
= IDWriteBitmapRenderTarget_GetSize(target
, NULL
);
781 size
.cx
= size
.cy
= -1;
782 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
784 ok(size
.cx
== 0, "got %d\n", size
.cx
);
785 ok(size
.cy
== 0, "got %d\n", size
.cy
);
788 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target2
);
790 ok(target
!= target2
, "got %p, %p\n", target2
, target
);
791 IDWriteBitmapRenderTarget_Release(target2
);
793 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
794 ok(hdc
!= NULL
, "got %p\n", hdc
);
797 ret
= GetGraphicsMode(hdc
);
798 ok(ret
== GM_ADVANCED
, "got %d\n", ret
);
800 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
801 ok(hbm
!= NULL
, "got %p\n", hbm
);
803 /* check DIB properties */
804 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
805 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
806 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
807 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
808 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
809 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
810 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
812 IDWriteBitmapRenderTarget_Release(target
);
814 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
815 ok(!hbm
, "got %p\n", hbm
);
818 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 10, 5, &target
);
821 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
822 ok(hdc
!= NULL
, "got %p\n", hdc
);
824 /* test context settings */
825 c
= GetTextColor(hdc
);
826 ok(c
== RGB(0, 0, 0), "got 0x%08x\n", c
);
827 ret
= GetBkMode(hdc
);
828 ok(ret
== OPAQUE
, "got %d\n", ret
);
830 ok(c
== RGB(255, 255, 255), "got 0x%08x\n", c
);
832 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
833 ok(hbm
!= NULL
, "got %p\n", hbm
);
835 /* check DIB properties */
836 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
837 ok(ret
== sizeof(ds
), "got %d\n", ret
);
838 ok(ds
.dsBm
.bmWidth
== 10, "got %d\n", ds
.dsBm
.bmWidth
);
839 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
840 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
841 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
842 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
844 size
.cx
= size
.cy
= -1;
845 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
847 ok(size
.cx
== 10, "got %d\n", size
.cx
);
848 ok(size
.cy
== 5, "got %d\n", size
.cy
);
850 /* resize to same size */
851 hr
= IDWriteBitmapRenderTarget_Resize(target
, 10, 5);
852 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
854 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
855 ok(hbm2
== hbm
, "got %p, %p\n", hbm2
, hbm
);
858 hr
= IDWriteBitmapRenderTarget_Resize(target
, 5, 5);
859 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
861 size
.cx
= size
.cy
= -1;
862 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
863 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
864 ok(size
.cx
== 5, "got %d\n", size
.cx
);
865 ok(size
.cy
== 5, "got %d\n", size
.cy
);
867 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
868 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
870 hr
= IDWriteBitmapRenderTarget_Resize(target
, 20, 5);
871 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
873 size
.cx
= size
.cy
= -1;
874 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
875 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
876 ok(size
.cx
== 20, "got %d\n", size
.cx
);
877 ok(size
.cy
== 5, "got %d\n", size
.cy
);
879 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
880 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
882 hr
= IDWriteBitmapRenderTarget_Resize(target
, 1, 5);
883 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
885 size
.cx
= size
.cy
= -1;
886 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
887 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
888 ok(size
.cx
== 1, "got %d\n", size
.cx
);
889 ok(size
.cy
== 5, "got %d\n", size
.cy
);
891 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
892 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
894 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
895 ok(ret
== sizeof(ds
), "got %d\n", ret
);
896 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
897 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
898 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
899 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
900 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
902 /* empty rectangle */
903 hr
= IDWriteBitmapRenderTarget_Resize(target
, 0, 5);
904 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
906 size
.cx
= size
.cy
= -1;
907 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
908 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
909 ok(size
.cx
== 0, "got %d\n", size
.cx
);
910 ok(size
.cy
== 5, "got %d\n", size
.cy
);
912 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
913 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
915 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
916 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
917 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
918 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
919 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
920 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
921 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
923 /* transform tests, current hdc transform is not immediately affected */
924 if (0) /* crashes on native */
925 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, NULL
);
927 memset(&m
, 0xcc, sizeof(m
));
928 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
929 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
930 ok(m
.m11
== 1.0 && m
.m22
== 1.0 && m
.m12
== 0.0 && m
.m21
== 0.0, "got %.1f,%.1f,%.1f,%.1f\n", m
.m11
, m
.m22
, m
.m12
, m
.m21
);
931 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
932 ret
= GetWorldTransform(hdc
, &xform
);
933 ok(ret
, "got %d\n", ret
);
934 ok(xform
.eM11
== 1.0 && xform
.eM22
== 1.0 && xform
.eM12
== 0.0 && xform
.eM21
== 0.0, "got wrong transform\n");
935 ok(xform
.eDx
== 0.0 && xform
.eDy
== 0.0, "got %.1f,%.1f\n", xform
.eDx
, xform
.eDy
);
937 memset(&m
, 0, sizeof(m
));
938 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, &m
);
939 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
941 memset(&m
, 0xcc, sizeof(m
));
942 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
943 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
944 ok(m
.m11
== 0.0 && m
.m22
== 0.0 && m
.m12
== 0.0 && m
.m21
== 0.0, "got %.1f,%.1f,%.1f,%.1f\n", m
.m11
, m
.m22
, m
.m12
, m
.m21
);
945 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
946 ret
= GetWorldTransform(hdc
, &xform
);
947 ok(ret
, "got %d\n", ret
);
948 ok(xform
.eM11
== 1.0 && xform
.eM22
== 1.0 && xform
.eM12
== 0.0 && xform
.eM21
== 0.0, "got wrong transform\n");
949 ok(xform
.eDx
== 0.0 && xform
.eDy
== 0.0, "got %.1f,%.1f\n", xform
.eDx
, xform
.eDy
);
951 memset(&m
, 0, sizeof(m
));
952 m
.m11
= 2.0; m
.m22
= 1.0;
953 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, &m
);
954 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
955 ret
= GetWorldTransform(hdc
, &xform
);
956 ok(ret
, "got %d\n", ret
);
957 ok(xform
.eM11
== 1.0 && xform
.eM22
== 1.0 && xform
.eM12
== 0.0 && xform
.eM21
== 0.0, "got wrong transform\n");
958 ok(xform
.eDx
== 0.0 && xform
.eDy
== 0.0, "got %.1f,%.1f\n", xform
.eDx
, xform
.eDy
);
960 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, NULL
);
961 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
963 memset(&m
, 0xcc, sizeof(m
));
964 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
965 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
966 ok(m
.m11
== 1.0 && m
.m22
== 1.0 && m
.m12
== 0.0 && m
.m21
== 0.0, "got %.1f,%.1f,%.1f,%.1f\n", m
.m11
, m
.m22
, m
.m12
, m
.m21
);
967 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
970 pdip
= IDWriteBitmapRenderTarget_GetPixelsPerDip(target
);
971 ok(pdip
== 1.0, "got %.2f\n", pdip
);
973 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, 2.0);
974 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
976 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, -1.0);
977 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
979 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, 0.0);
980 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
982 pdip
= IDWriteBitmapRenderTarget_GetPixelsPerDip(target
);
983 ok(pdip
== 2.0, "got %.2f\n", pdip
);
985 hr
= IDWriteBitmapRenderTarget_QueryInterface(target
, &IID_IDWriteBitmapRenderTarget1
, (void**)&target1
);
987 DWRITE_TEXT_ANTIALIAS_MODE mode
;
989 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
990 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, "got %d\n", mode
);
992 hr
= IDWriteBitmapRenderTarget1_SetTextAntialiasMode(target1
, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
+1);
993 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
995 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
996 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, "got %d\n", mode
);
998 hr
= IDWriteBitmapRenderTarget1_SetTextAntialiasMode(target1
, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
);
999 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1001 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
1002 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
, "got %d\n", mode
);
1004 IDWriteBitmapRenderTarget1_Release(target1
);
1007 win_skip("IDWriteBitmapRenderTarget1 is not supported.\n");
1009 IDWriteBitmapRenderTarget_Release(target
);
1010 IDWriteGdiInterop_Release(interop
);
1011 IDWriteFactory_Release(factory
);
1014 static void test_GetFontFamily(void)
1016 IDWriteFontCollection
*collection
, *collection2
;
1017 IDWriteFontCollection
*syscoll
;
1018 IDWriteFontFamily
*family
, *family2
;
1019 IDWriteGdiInterop
*interop
;
1020 IDWriteFont
*font
, *font2
;
1021 IDWriteFactory
*factory
;
1025 factory
= create_factory();
1027 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1028 EXPECT_HR(hr
, S_OK
);
1030 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &syscoll
, FALSE
);
1031 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1033 memset(&logfont
, 0, sizeof(logfont
));
1034 logfont
.lfHeight
= 12;
1035 logfont
.lfWidth
= 12;
1036 logfont
.lfWeight
= FW_NORMAL
;
1037 logfont
.lfItalic
= 1;
1038 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1040 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1041 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1043 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
1044 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1045 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
1047 if (0) /* crashes on native */
1048 hr
= IDWriteFont_GetFontFamily(font
, NULL
);
1050 EXPECT_REF(font
, 1);
1051 hr
= IDWriteFont_GetFontFamily(font
, &family
);
1052 EXPECT_HR(hr
, S_OK
);
1053 EXPECT_REF(font
, 1);
1054 EXPECT_REF(family
, 2);
1056 hr
= IDWriteFont_GetFontFamily(font
, &family2
);
1057 EXPECT_HR(hr
, S_OK
);
1058 ok(family2
== family
, "got %p, previous %p\n", family2
, family
);
1059 EXPECT_REF(font
, 1);
1060 EXPECT_REF(family
, 3);
1061 IDWriteFontFamily_Release(family2
);
1063 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFamily
, (void**)&family2
);
1064 EXPECT_HR(hr
, E_NOINTERFACE
);
1065 ok(family2
== NULL
, "got %p\n", family2
);
1067 hr
= IDWriteFont_GetFontFamily(font2
, &family2
);
1068 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1069 ok(family2
!= family
, "got %p, %p\n", family2
, family
);
1072 hr
= IDWriteFontFamily_GetFontCollection(family
, &collection
);
1073 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1076 hr
= IDWriteFontFamily_GetFontCollection(family2
, &collection2
);
1077 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1078 ok(collection
== collection2
, "got %p, %p\n", collection
, collection2
);
1079 ok(collection
== syscoll
, "got %p, %p\n", collection
, syscoll
);
1081 IDWriteFontCollection_Release(syscoll
);
1082 IDWriteFontCollection_Release(collection2
);
1083 IDWriteFontCollection_Release(collection
);
1084 IDWriteFontFamily_Release(family2
);
1085 IDWriteFontFamily_Release(family
);
1086 IDWriteFont_Release(font
);
1087 IDWriteFont_Release(font2
);
1088 IDWriteGdiInterop_Release(interop
);
1089 IDWriteFactory_Release(factory
);
1092 static void test_GetFamilyNames(void)
1094 IDWriteFontFamily
*family
;
1095 IDWriteLocalizedStrings
*names
, *names2
;
1096 IDWriteGdiInterop
*interop
;
1097 IDWriteFactory
*factory
;
1104 factory
= create_factory();
1106 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1107 EXPECT_HR(hr
, S_OK
);
1109 memset(&logfont
, 0, sizeof(logfont
));
1110 logfont
.lfHeight
= 12;
1111 logfont
.lfWidth
= 12;
1112 logfont
.lfWeight
= FW_NORMAL
;
1113 logfont
.lfItalic
= 1;
1114 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1116 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1117 EXPECT_HR(hr
, S_OK
);
1119 hr
= IDWriteFont_GetFontFamily(font
, &family
);
1120 EXPECT_HR(hr
, S_OK
);
1122 if (0) /* crashes on native */
1123 hr
= IDWriteFontFamily_GetFamilyNames(family
, NULL
);
1125 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
1126 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1127 EXPECT_REF(names
, 1);
1129 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names2
);
1130 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1131 EXPECT_REF(names2
, 1);
1132 ok(names
!= names2
, "got %p, was %p\n", names2
, names
);
1134 IDWriteLocalizedStrings_Release(names2
);
1136 /* GetStringLength */
1137 if (0) /* crashes on native */
1138 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, NULL
);
1141 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 10, &len
);
1142 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1143 ok(len
== (UINT32
)-1, "got %u\n", len
);
1146 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, &len
);
1147 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1148 ok(len
> 0, "got %u\n", len
);
1151 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 0);
1152 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1154 hr
= IDWriteLocalizedStrings_GetString(names
, 10, NULL
, 0);
1155 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1158 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 100);
1161 hr
= IDWriteLocalizedStrings_GetString(names
, 10, buffer
, 100);
1162 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1163 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1166 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
-1);
1167 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1168 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1171 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
);
1172 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1173 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1176 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
+1);
1177 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1178 ok(buffer
[0] != 0, "got %x\n", buffer
[0]);
1180 IDWriteLocalizedStrings_Release(names
);
1182 IDWriteFontFamily_Release(family
);
1183 IDWriteFont_Release(font
);
1184 IDWriteGdiInterop_Release(interop
);
1185 IDWriteFactory_Release(factory
);
1188 static void test_CreateFontFace(void)
1190 IDWriteFontFace
*fontface
, *fontface2
;
1191 IDWriteFontCollection
*collection
;
1192 DWRITE_FONT_FILE_TYPE file_type
;
1193 DWRITE_FONT_FACE_TYPE face_type
;
1194 IDWriteGdiInterop
*interop
;
1195 IDWriteFont
*font
, *font2
;
1196 IDWriteFontFamily
*family
;
1197 IDWriteFactory
*factory
;
1198 IDWriteFontFile
*file
;
1205 factory
= create_factory();
1207 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1208 EXPECT_HR(hr
, S_OK
);
1210 memset(&logfont
, 0, sizeof(logfont
));
1211 logfont
.lfHeight
= 12;
1212 logfont
.lfWidth
= 12;
1213 logfont
.lfWeight
= FW_NORMAL
;
1214 logfont
.lfItalic
= 1;
1215 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1218 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1219 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1222 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
1223 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1224 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1226 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFace
, (void**)&fontface
);
1227 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1229 if (0) /* crashes on native */
1230 hr
= IDWriteFont_CreateFontFace(font
, NULL
);
1233 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1234 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1237 hr
= IDWriteFont_CreateFontFace(font
, &fontface2
);
1238 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1239 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1240 IDWriteFontFace_Release(fontface2
);
1243 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
1244 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1245 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1246 IDWriteFontFace_Release(fontface2
);
1248 IDWriteFont_Release(font2
);
1249 IDWriteFont_Release(font
);
1251 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFont
, (void**)&font
);
1252 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_NOTIMPL
), "got 0x%08x\n", hr
);
1254 IDWriteFontFace_Release(fontface
);
1255 IDWriteGdiInterop_Release(interop
);
1257 /* Create from system collection */
1258 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1259 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1261 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
1262 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1265 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1266 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1267 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1270 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1271 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font2
);
1272 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1273 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1276 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1277 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1280 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
1281 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1282 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1284 IDWriteFontFace_Release(fontface
);
1285 IDWriteFontFace_Release(fontface2
);
1286 IDWriteFont_Release(font2
);
1287 IDWriteFont_Release(font
);
1288 IDWriteFontFamily_Release(family
);
1289 IDWriteFontCollection_Release(collection
);
1291 /* IDWriteFactory::CreateFontFace() */
1292 path
= create_testfontfile(test_fontfile
);
1293 factory
= create_factory();
1295 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
1296 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1299 file_type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1300 face_type
= DWRITE_FONT_FACE_TYPE_CFF
;
1302 hr
= IDWriteFontFile_Analyze(file
, &supported
, &file_type
, &face_type
, &count
);
1303 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1304 ok(supported
== TRUE
, "got %i\n", supported
);
1305 ok(file_type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", file_type
);
1306 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face_type
);
1307 ok(count
== 1, "got %i\n", count
);
1309 /* try mismatching face type, the one that's not supported */
1310 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1311 ok(hr
== DWRITE_E_FILEFORMAT
, "got 0x%08x\n", hr
);
1313 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION
, 1, &file
, 0,
1314 DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1315 ok(hr
== DWRITE_E_FILEFORMAT
|| broken(hr
== E_FAIL
) /* < win10 */, "got 0x%08x\n", hr
);
1317 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_RAW_CFF
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1319 ok(hr
== DWRITE_E_UNSUPPORTEDOPERATION
|| broken(hr
== E_INVALIDARG
) /* older versions */, "got 0x%08x\n", hr
);
1321 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TYPE1
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1322 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1324 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_VECTOR
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1325 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1327 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_BITMAP
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1328 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1330 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_UNKNOWN
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1332 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
) /* < win10 */, "got 0x%08x\n", hr
);
1334 ok(fontface
!= NULL
, "got %p\n", fontface
);
1335 face_type
= IDWriteFontFace_GetType(fontface
);
1336 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %d\n", face_type
);
1337 IDWriteFontFace_Release(fontface
);
1340 IDWriteFontFile_Release(file
);
1341 IDWriteFactory_Release(factory
);
1342 DELETE_FONTFILE(path
);
1345 static void test_GetMetrics(void)
1347 IDWriteGdiInterop
*interop
;
1348 DWRITE_FONT_METRICS metrics
;
1349 IDWriteFontFace
*fontface
;
1350 IDWriteFactory
*factory
;
1351 OUTLINETEXTMETRICW otm
;
1352 IDWriteFont1
*font1
;
1360 factory
= create_factory();
1362 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1363 EXPECT_HR(hr
, S_OK
);
1365 memset(&logfont
, 0, sizeof(logfont
));
1366 logfont
.lfHeight
= 12;
1367 logfont
.lfWidth
= 12;
1368 logfont
.lfWeight
= FW_NORMAL
;
1369 logfont
.lfItalic
= 1;
1370 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1372 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1373 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1375 hfont
= CreateFontIndirectW(&logfont
);
1376 hdc
= CreateCompatibleDC(0);
1377 SelectObject(hdc
, hfont
);
1379 otm
.otmSize
= sizeof(otm
);
1380 ret
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
1381 ok(ret
, "got %d\n", ret
);
1383 DeleteObject(hfont
);
1385 if (0) /* crashes on native */
1386 IDWriteFont_GetMetrics(font
, NULL
);
1388 memset(&metrics
, 0, sizeof(metrics
));
1389 IDWriteFont_GetMetrics(font
, &metrics
);
1391 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
1392 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
1393 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
1394 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
1395 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
1396 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
1397 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
1398 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
1399 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
1400 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
1402 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1403 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1405 memset(&metrics
, 0, sizeof(metrics
));
1406 IDWriteFontFace_GetMetrics(fontface
, &metrics
);
1408 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
1409 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
1410 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
1411 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
1412 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
1413 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
1414 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
1415 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
1416 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
1417 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
1419 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
1421 DWRITE_FONT_METRICS1 metrics1
;
1422 IDWriteFontFace1
*fontface1
;
1424 memset(&metrics1
, 0, sizeof(metrics1
));
1425 IDWriteFont1_GetMetrics(font1
, &metrics1
);
1427 ok(metrics1
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics1
.designUnitsPerEm
);
1428 ok(metrics1
.ascent
!= 0, "ascent %u\n", metrics1
.ascent
);
1429 ok(metrics1
.descent
!= 0, "descent %u\n", metrics1
.descent
);
1430 ok(metrics1
.lineGap
== 0, "lineGap %d\n", metrics1
.lineGap
);
1431 ok(metrics1
.capHeight
, "capHeight %u\n", metrics1
.capHeight
);
1432 ok(metrics1
.xHeight
!= 0, "xHeight %u\n", metrics1
.xHeight
);
1433 ok(metrics1
.underlinePosition
< 0, "underlinePosition %d\n", metrics1
.underlinePosition
);
1434 ok(metrics1
.underlineThickness
!= 0, "underlineThickness %u\n", metrics1
.underlineThickness
);
1435 ok(metrics1
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics1
.strikethroughPosition
);
1436 ok(metrics1
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics1
.strikethroughThickness
);
1437 ok(metrics1
.glyphBoxLeft
< 0, "glyphBoxLeft %d\n", metrics1
.glyphBoxLeft
);
1438 ok(metrics1
.glyphBoxTop
> 0, "glyphBoxTop %d\n", metrics1
.glyphBoxTop
);
1439 ok(metrics1
.glyphBoxRight
> 0, "glyphBoxRight %d\n", metrics1
.glyphBoxRight
);
1440 ok(metrics1
.glyphBoxBottom
< 0, "glyphBoxBottom %d\n", metrics1
.glyphBoxBottom
);
1441 ok(metrics1
.subscriptPositionY
< 0, "subscriptPositionY %d\n", metrics1
.subscriptPositionY
);
1442 ok(metrics1
.subscriptSizeX
> 0, "subscriptSizeX %d\n", metrics1
.subscriptSizeX
);
1443 ok(metrics1
.subscriptSizeY
> 0, "subscriptSizeY %d\n", metrics1
.subscriptSizeY
);
1444 ok(metrics1
.superscriptPositionY
> 0, "superscriptPositionY %d\n", metrics1
.superscriptPositionY
);
1445 ok(metrics1
.superscriptSizeX
> 0, "superscriptSizeX %d\n", metrics1
.superscriptSizeX
);
1446 ok(metrics1
.superscriptSizeY
> 0, "superscriptSizeY %d\n", metrics1
.superscriptSizeY
);
1447 ok(!metrics1
.hasTypographicMetrics
, "hasTypographicMetrics %d\n", metrics1
.hasTypographicMetrics
);
1449 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
1450 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1452 memset(&metrics1
, 0, sizeof(metrics1
));
1453 IDWriteFontFace1_GetMetrics(fontface1
, &metrics1
);
1455 ok(metrics1
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics1
.designUnitsPerEm
);
1456 ok(metrics1
.ascent
!= 0, "ascent %u\n", metrics1
.ascent
);
1457 ok(metrics1
.descent
!= 0, "descent %u\n", metrics1
.descent
);
1458 ok(metrics1
.lineGap
== 0, "lineGap %d\n", metrics1
.lineGap
);
1459 ok(metrics1
.capHeight
, "capHeight %u\n", metrics1
.capHeight
);
1460 ok(metrics1
.xHeight
!= 0, "xHeight %u\n", metrics1
.xHeight
);
1461 ok(metrics1
.underlinePosition
< 0, "underlinePosition %d\n", metrics1
.underlinePosition
);
1462 ok(metrics1
.underlineThickness
!= 0, "underlineThickness %u\n", metrics1
.underlineThickness
);
1463 ok(metrics1
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics1
.strikethroughPosition
);
1464 ok(metrics1
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics1
.strikethroughThickness
);
1465 ok(metrics1
.glyphBoxLeft
< 0, "glyphBoxLeft %d\n", metrics1
.glyphBoxLeft
);
1466 ok(metrics1
.glyphBoxTop
> 0, "glyphBoxTop %d\n", metrics1
.glyphBoxTop
);
1467 ok(metrics1
.glyphBoxRight
> 0, "glyphBoxRight %d\n", metrics1
.glyphBoxRight
);
1468 ok(metrics1
.glyphBoxBottom
< 0, "glyphBoxBottom %d\n", metrics1
.glyphBoxBottom
);
1469 ok(metrics1
.subscriptPositionY
< 0, "subscriptPositionY %d\n", metrics1
.subscriptPositionY
);
1470 ok(metrics1
.subscriptSizeX
> 0, "subscriptSizeX %d\n", metrics1
.subscriptSizeX
);
1471 ok(metrics1
.subscriptSizeY
> 0, "subscriptSizeY %d\n", metrics1
.subscriptSizeY
);
1472 ok(metrics1
.superscriptPositionY
> 0, "superscriptPositionY %d\n", metrics1
.superscriptPositionY
);
1473 ok(metrics1
.superscriptSizeX
> 0, "superscriptSizeX %d\n", metrics1
.superscriptSizeX
);
1474 ok(metrics1
.superscriptSizeY
> 0, "superscriptSizeY %d\n", metrics1
.superscriptSizeY
);
1475 ok(!metrics1
.hasTypographicMetrics
, "hasTypographicMetrics %d\n", metrics1
.hasTypographicMetrics
);
1477 IDWriteFontFace1_Release(fontface1
);
1478 IDWriteFont1_Release(font1
);
1481 win_skip("DWRITE_FONT_METRICS1 is not supported.\n");
1483 IDWriteFontFace_Release(fontface
);
1485 IDWriteFont_Release(font
);
1486 IDWriteGdiInterop_Release(interop
);
1487 IDWriteFactory_Release(factory
);
1490 static void test_system_fontcollection(void)
1492 IDWriteFontCollection
*collection
, *coll2
;
1493 IDWriteLocalFontFileLoader
*localloader
;
1494 IDWriteFactory
*factory
, *factory2
;
1495 IDWriteFontFileLoader
*loader
;
1496 IDWriteFontFamily
*family
;
1497 IDWriteFontFace
*fontface
;
1498 IDWriteFontFile
*file
;
1504 factory
= create_factory();
1506 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1507 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1509 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, FALSE
);
1510 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1511 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
1512 IDWriteFontCollection_Release(coll2
);
1514 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, TRUE
);
1515 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1516 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
1517 IDWriteFontCollection_Release(coll2
);
1519 factory2
= create_factory();
1520 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &coll2
, FALSE
);
1521 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1522 ok(coll2
!= collection
, "got %p, was %p\n", coll2
, collection
);
1523 IDWriteFontCollection_Release(coll2
);
1524 IDWriteFactory_Release(factory2
);
1526 i
= IDWriteFontCollection_GetFontFamilyCount(collection
);
1527 ok(i
, "got %u\n", i
);
1530 family
= (void*)0xdeadbeef;
1531 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
1532 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1533 ok(family
== NULL
, "got %p\n", family
);
1537 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaW
, &i
, &ret
);
1538 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1539 ok(ret
, "got %d\n", ret
);
1540 ok(i
!= (UINT32
)-1, "got %u\n", i
);
1544 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaUppercaseW
, &i
, &ret
);
1545 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1546 ok(ret
, "got %d\n", ret
);
1547 ok(i
!= (UINT32
)-1, "got %u\n", i
);
1551 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaStrangecaseW
, &i
, &ret
);
1552 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1553 ok(ret
, "got %d\n", ret
);
1554 ok(i
!= (UINT32
)-1, "got %u\n", i
);
1556 /* get back local file loader */
1557 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
1558 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1560 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1561 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1562 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1563 IDWriteFontFamily_Release(family
);
1565 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1566 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1567 IDWriteFont_Release(font
);
1571 hr
= IDWriteFontFace_GetFiles(fontface
, &i
, &file
);
1572 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1573 ok(file
!= NULL
, "got %p\n", file
);
1575 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
1576 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1577 IDWriteFontFile_Release(file
);
1579 hr
= IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
1580 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1581 IDWriteLocalFontFileLoader_Release(localloader
);
1583 /* local loader is not registered by default */
1584 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, loader
);
1585 ok(hr
== S_OK
|| broken(hr
== DWRITE_E_ALREADYREGISTERED
), "got 0x%08x\n", hr
);
1586 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, loader
);
1587 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "got 0x%08x\n", hr
);
1589 /* try with a different factory */
1590 factory2
= create_factory();
1591 hr
= IDWriteFactory_RegisterFontFileLoader(factory2
, loader
);
1592 ok(hr
== S_OK
|| broken(hr
== DWRITE_E_ALREADYREGISTERED
), "got 0x%08x\n", hr
);
1593 hr
= IDWriteFactory_RegisterFontFileLoader(factory2
, loader
);
1594 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1595 hr
= IDWriteFactory_UnregisterFontFileLoader(factory2
, loader
);
1596 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "got 0x%08x\n", hr
);
1597 hr
= IDWriteFactory_UnregisterFontFileLoader(factory2
, loader
);
1598 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1599 IDWriteFactory_Release(factory2
);
1601 IDWriteFontFileLoader_Release(loader
);
1605 hr
= IDWriteFontCollection_FindFamilyName(collection
, blahW
, &i
, &ret
);
1606 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1607 ok(!ret
, "got %d\n", ret
);
1608 ok(i
== (UINT32
)-1, "got %u\n", i
);
1610 IDWriteFontCollection_Release(collection
);
1611 IDWriteFactory_Release(factory
);
1614 static void test_ConvertFontFaceToLOGFONT(void)
1616 DWRITE_FONT_SIMULATIONS sim
;
1617 IDWriteGdiInterop
*interop
;
1618 IDWriteFontFace
*fontface
;
1619 IDWriteFactory
*factory
;
1624 factory
= create_factory();
1626 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1627 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1629 memset(&logfont
, 0, sizeof(logfont
));
1630 logfont
.lfHeight
= 12;
1631 logfont
.lfWidth
= 12;
1632 logfont
.lfEscapement
= 100;
1633 logfont
.lfWeight
= FW_NORMAL
;
1634 logfont
.lfItalic
= 1;
1635 logfont
.lfUnderline
= 1;
1636 logfont
.lfStrikeOut
= 1;
1638 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1640 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1641 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1643 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1644 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1646 sim
= IDWriteFont_GetSimulations(font
);
1647 ok(sim
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "sim %d\n", sim
);
1649 sim
= IDWriteFontFace_GetSimulations(fontface
);
1650 ok(sim
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "sim %d\n", sim
);
1652 IDWriteFont_Release(font
);
1654 if (0) /* crashes on native */
1656 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, NULL
, NULL
);
1657 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, NULL
);
1660 memset(&logfont
, 0xa, sizeof(logfont
));
1661 logfont
.lfFaceName
[0] = 0;
1663 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, &logfont
);
1664 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1665 ok(logfont
.lfHeight
== 0, "got %d\n", logfont
.lfHeight
);
1666 ok(logfont
.lfWidth
== 0, "got %d\n", logfont
.lfWidth
);
1667 ok(logfont
.lfWeight
== FW_NORMAL
, "got %d\n", logfont
.lfWeight
);
1668 ok(logfont
.lfEscapement
== 0, "got %d\n", logfont
.lfEscapement
);
1669 ok(logfont
.lfItalic
== 1, "got %d\n", logfont
.lfItalic
);
1670 ok(logfont
.lfUnderline
== 0, "got %d\n", logfont
.lfUnderline
);
1671 ok(logfont
.lfStrikeOut
== 0, "got %d\n", logfont
.lfStrikeOut
);
1672 ok(!lstrcmpW(logfont
.lfFaceName
, tahomaW
), "got %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
1674 IDWriteGdiInterop_Release(interop
);
1675 IDWriteFontFace_Release(fontface
);
1676 IDWriteFactory_Release(factory
);
1679 static HRESULT WINAPI
fontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
1681 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
))
1684 IDWriteFontFileEnumerator_AddRef(iface
);
1687 return E_NOINTERFACE
;
1690 static ULONG WINAPI
fontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
1695 static ULONG WINAPI
fontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
1700 static HRESULT WINAPI
fontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**file
)
1706 static HRESULT WINAPI
fontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
1712 static const struct IDWriteFontFileEnumeratorVtbl dwritefontfileenumeratorvtbl
=
1714 fontfileenumerator_QueryInterface
,
1715 fontfileenumerator_AddRef
,
1716 fontfileenumerator_Release
,
1717 fontfileenumerator_MoveNext
,
1718 fontfileenumerator_GetCurrentFontFile
,
1721 static HRESULT WINAPI
fontcollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
1727 static ULONG WINAPI
fontcollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
1732 static ULONG WINAPI
fontcollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
1737 static HRESULT WINAPI
fontcollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
*factory
, const void *key
,
1738 UINT32 key_size
, IDWriteFontFileEnumerator
**ret
)
1740 static IDWriteFontFileEnumerator enumerator
= { &dwritefontfileenumeratorvtbl
};
1745 static const struct IDWriteFontCollectionLoaderVtbl dwritefontcollectionloadervtbl
= {
1746 fontcollectionloader_QueryInterface
,
1747 fontcollectionloader_AddRef
,
1748 fontcollectionloader_Release
,
1749 fontcollectionloader_CreateEnumeratorFromKey
1752 static void test_CustomFontCollection(void)
1754 static const WCHAR fontnameW
[] = {'w','i','n','e','_','t','e','s','t',0};
1755 IDWriteFontCollectionLoader collection
= { &dwritefontcollectionloadervtbl
};
1756 IDWriteFontCollectionLoader collection2
= { &dwritefontcollectionloadervtbl
};
1757 IDWriteFontCollectionLoader collection3
= { &dwritefontcollectionloadervtbl
};
1758 IDWriteFontCollection
*font_collection
= NULL
;
1759 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
1760 struct test_fontcollectionloader resource_collection
= { { &resourcecollectionloadervtbl
}, &rloader
};
1761 IDWriteFontFamily
*family
, *family2
, *family3
;
1762 IDWriteFontFace
*idfontface
, *idfontface2
;
1763 IDWriteFontFile
*fontfile
, *fontfile2
;
1764 IDWriteLocalizedStrings
*string
;
1765 IDWriteFont
*idfont
, *idfont2
;
1766 IDWriteFactory
*factory
;
1767 UINT32 index
, count
;
1772 factory
= create_factory();
1774 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, NULL
);
1775 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1777 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, NULL
);
1778 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1780 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
1781 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1782 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection2
);
1783 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1784 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
1785 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1787 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1788 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1789 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
);
1790 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1792 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection3
, "Billy", 6, &font_collection
);
1793 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1795 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection
, "Billy", 6, &font_collection
);
1796 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1797 IDWriteFontCollection_Release(font_collection
);
1799 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection2
, "Billy", 6, &font_collection
);
1800 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1801 IDWriteFontCollection_Release(font_collection
);
1803 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, (IDWriteFontCollectionLoader
*)0xdeadbeef, "Billy", 6, &font_collection
);
1804 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1806 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1807 ok(font
!= NULL
, "Failed to find font resource\n");
1809 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
,
1810 &font
, sizeof(HRSRC
), &font_collection
);
1811 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1815 hr
= IDWriteFontCollection_FindFamilyName(font_collection
, fontnameW
, &index
, &exists
);
1816 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1817 ok(index
== 0, "got index %i\n", index
);
1818 ok(exists
, "got exists %i\n", exists
);
1820 count
= IDWriteFontCollection_GetFontFamilyCount(font_collection
);
1821 ok(count
== 1, "got %u\n", count
);
1824 hr
= IDWriteFontCollection_GetFontFamily(font_collection
, 0, &family
);
1825 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1826 EXPECT_REF(family
, 1);
1829 hr
= IDWriteFontCollection_GetFontFamily(font_collection
, 0, &family2
);
1830 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1831 EXPECT_REF(family2
, 1);
1832 ok(family
!= family2
, "got %p, %p\n", family
, family2
);
1834 hr
= IDWriteFontFamily_GetFont(family
, 0, &idfont
);
1835 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1836 EXPECT_REF(idfont
, 1);
1837 EXPECT_REF(family
, 2);
1838 hr
= IDWriteFontFamily_GetFont(family
, 0, &idfont2
);
1839 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1840 EXPECT_REF(idfont2
, 1);
1841 EXPECT_REF(family
, 3);
1842 ok(idfont
!= idfont2
, "got %p, %p\n", idfont
, idfont2
);
1843 IDWriteFont_Release(idfont2
);
1845 hr
= IDWriteFont_GetInformationalStrings(idfont
, DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE
, &string
, &exists
);
1846 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1847 ok(exists
, "got %d\n", exists
);
1848 EXPECT_REF(string
, 1);
1849 IDWriteLocalizedStrings_Release(string
);
1852 hr
= IDWriteFont_GetFontFamily(idfont
, &family3
);
1853 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1854 EXPECT_REF(family
, 3);
1855 ok(family
== family3
, "got %p, %p\n", family
, family3
);
1856 IDWriteFontFamily_Release(family3
);
1859 hr
= IDWriteFont_CreateFontFace(idfont
, &idfontface
);
1860 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1861 EXPECT_REF(idfont
, 1);
1864 hr
= IDWriteFontFamily_GetFont(family2
, 0, &idfont2
);
1865 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1866 EXPECT_REF(idfont2
, 1);
1867 EXPECT_REF(idfont
, 1);
1868 ok(idfont2
!= idfont
, "Font instances should not match\n");
1871 hr
= IDWriteFont_CreateFontFace(idfont2
, &idfontface2
);
1872 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1873 ok(idfontface2
== idfontface
, "fontfaces should match\n");
1877 hr
= IDWriteFontFace_GetFiles(idfontface
, &index
, &fontfile
);
1878 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1882 hr
= IDWriteFontFace_GetFiles(idfontface2
, &index
, &fontfile2
);
1883 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1884 ok(fontfile
== fontfile2
, "fontfiles should match\n");
1886 IDWriteFont_Release(idfont
);
1887 IDWriteFont_Release(idfont2
);
1888 IDWriteFontFile_Release(fontfile
);
1889 IDWriteFontFile_Release(fontfile2
);
1890 IDWriteFontFace_Release(idfontface
);
1891 IDWriteFontFace_Release(idfontface2
);
1892 IDWriteFontFamily_Release(family2
);
1893 IDWriteFontFamily_Release(family
);
1894 IDWriteFontCollection_Release(font_collection
);
1896 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
1897 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1898 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
1899 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1900 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection2
);
1901 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1902 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
);
1903 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1904 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
1905 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1907 IDWriteFactory_Release(factory
);
1910 static HRESULT WINAPI
fontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
1912 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
1915 IDWriteFontFileLoader_AddRef(iface
);
1920 return E_NOINTERFACE
;
1923 static ULONG WINAPI
fontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
1928 static ULONG WINAPI
fontfileloader_Release(IDWriteFontFileLoader
*iface
)
1933 static HRESULT WINAPI
fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
1938 static const struct IDWriteFontFileLoaderVtbl dwritefontfileloadervtbl
= {
1939 fontfileloader_QueryInterface
,
1940 fontfileloader_AddRef
,
1941 fontfileloader_Release
,
1942 fontfileloader_CreateStreamFromKey
1945 static void test_CreateCustomFontFileReference(void)
1947 IDWriteFontFileLoader floader
= { &dwritefontfileloadervtbl
};
1948 IDWriteFontFileLoader floader2
= { &dwritefontfileloadervtbl
};
1949 IDWriteFontFileLoader floader3
= { &dwritefontfileloadervtbl
};
1950 IDWriteFactory
*factory
, *factory2
;
1951 IDWriteFontFile
*file
, *file2
;
1953 DWRITE_FONT_FILE_TYPE file_type
;
1954 DWRITE_FONT_FACE_TYPE face_type
;
1956 IDWriteFontFace
*face
, *face2
;
1959 UINT32 codePoints
[1] = {0xa8};
1962 factory
= create_factory();
1963 factory2
= create_factory();
1965 if (0) { /* crashes on win10 */
1966 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, NULL
);
1967 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1969 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
1970 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1971 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader2
);
1972 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1973 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
1974 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1975 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1976 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1979 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &file
);
1980 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1981 IDWriteFontFile_Release(file
);
1983 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader3
, &file
);
1984 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1986 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, NULL
, &file
);
1987 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1990 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &file
);
1991 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1993 file_type
= DWRITE_FONT_FILE_TYPE_TRUETYPE
;
1994 face_type
= DWRITE_FONT_FACE_TYPE_TRUETYPE
;
1997 hr
= IDWriteFontFile_Analyze(file
, &support
, &file_type
, &face_type
, &count
);
1998 ok(hr
== 0x8faecafe, "got 0x%08x\n", hr
);
1999 ok(support
== FALSE
, "got %i\n", support
);
2000 ok(file_type
== DWRITE_FONT_FILE_TYPE_UNKNOWN
, "got %i\n", file_type
);
2001 ok(face_type
== DWRITE_FONT_FACE_TYPE_UNKNOWN
, "got %i\n", face_type
);
2002 ok(count
== 0, "got %i\n", count
);
2004 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &file
, 0, 0, &face
);
2005 ok(hr
== 0x8faecafe, "got 0x%08x\n", hr
);
2006 IDWriteFontFile_Release(file
);
2008 fontrsrc
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
2009 ok(fontrsrc
!= NULL
, "Failed to find font resource\n");
2011 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &fontrsrc
, sizeof(HRSRC
), &rloader
, &file
);
2012 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2014 file_type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
2015 face_type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
2018 hr
= IDWriteFontFile_Analyze(file
, &support
, &file_type
, &face_type
, &count
);
2019 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2020 ok(support
== TRUE
, "got %i\n", support
);
2021 ok(file_type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", file_type
);
2022 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face_type
);
2023 ok(count
== 1, "got %i\n", count
);
2026 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 1, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
2027 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2029 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
2030 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2032 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2033 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2034 /* fontface instances are reused starting with win7 */
2035 ok(face
== face2
|| broken(face
!= face2
), "got %p, %p\n", face
, face2
);
2036 IDWriteFontFace_Release(face2
);
2038 /* file was created with different factory */
2040 hr
= IDWriteFactory_CreateFontFace(factory2
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2042 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2044 IDWriteFontFace_Release(face2
);
2047 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &fontrsrc
, sizeof(HRSRC
), &rloader
, &file2
);
2048 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2049 ok(file
!= file2
, "got %p, %p\n", file
, file2
);
2051 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file2
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2052 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2053 /* fontface instances are reused starting with win7 */
2054 ok(face
== face2
|| broken(face
!= face2
), "got %p, %p\n", face
, face2
);
2055 IDWriteFontFace_Release(face2
);
2056 IDWriteFontFile_Release(file2
);
2058 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 0, NULL
);
2059 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2061 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 0, NULL
);
2062 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2064 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 0, indices
);
2065 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2067 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 0, indices
);
2068 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2070 indices
[0] = indices
[1] = 11;
2071 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 1, indices
);
2072 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2073 ok(indices
[0] == 0, "got index %i\n", indices
[0]);
2074 ok(indices
[1] == 11, "got index %i\n", indices
[1]);
2076 if (0) /* crashes on native */
2077 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 1, NULL
);
2079 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 1, indices
);
2080 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2081 ok(indices
[0] == 6, "got index %i\n", indices
[0]);
2082 IDWriteFontFace_Release(face
);
2083 IDWriteFontFile_Release(file
);
2085 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
2086 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2087 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
2088 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2089 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader2
);
2090 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2091 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
2092 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2094 IDWriteFactory_Release(factory2
);
2095 IDWriteFactory_Release(factory
);
2098 static void test_CreateFontFileReference(void)
2101 IDWriteFontFile
*ffile
= NULL
;
2103 DWRITE_FONT_FILE_TYPE type
;
2104 DWRITE_FONT_FACE_TYPE face
;
2106 IDWriteFontFace
*fface
= NULL
;
2107 IDWriteFactory
*factory
;
2110 path
= create_testfontfile(test_fontfile
);
2111 factory
= create_factory();
2113 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &ffile
);
2114 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2117 type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
2118 face
= DWRITE_FONT_FACE_TYPE_CFF
;
2120 hr
= IDWriteFontFile_Analyze(ffile
, &support
, &type
, &face
, &count
);
2121 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2122 ok(support
== TRUE
, "got %i\n", support
);
2123 ok(type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", type
);
2124 ok(face
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face
);
2125 ok(count
== 1, "got %i\n", count
);
2127 hr
= IDWriteFactory_CreateFontFace(factory
, face
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fface
);
2128 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2130 IDWriteFontFace_Release(fface
);
2131 IDWriteFontFile_Release(ffile
);
2132 IDWriteFactory_Release(factory
);
2134 DELETE_FONTFILE(path
);
2137 static void test_shared_isolated(void)
2139 IDWriteFactory
*isolated
, *isolated2
;
2140 IDWriteFactory
*shared
, *shared2
;
2145 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
2146 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2147 ok(shared
!= NULL
, "got %p\n", shared
);
2148 IDWriteFactory_Release(shared
);
2150 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
2151 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2153 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
2154 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2155 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
2157 IDWriteFactory_Release(shared
);
2158 IDWriteFactory_Release(shared2
);
2160 /* we got 2 references, released 2 - still same pointer is returned */
2161 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
2162 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2163 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
2164 IDWriteFactory_Release(shared2
);
2166 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated
);
2167 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2169 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
2170 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2171 ok(isolated
!= isolated2
, "got %p, and %p\n", isolated
, isolated2
);
2172 IDWriteFactory_Release(isolated2
);
2174 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
2175 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2176 ok(shared
!= isolated2
, "got %p, and %p\n", shared
, isolated2
);
2178 IDWriteFactory_Release(isolated
);
2179 IDWriteFactory_Release(isolated2
);
2182 static void test_GetUnicodeRanges(void)
2184 DWRITE_UNICODE_RANGE
*ranges
, r
;
2185 IDWriteFontFile
*ffile
= NULL
;
2186 IDWriteFontFace1
*fontface1
;
2187 IDWriteFontFace
*fontface
;
2188 IDWriteFactory
*factory
;
2193 factory
= create_factory();
2195 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
2196 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2198 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
2199 ok(font
!= NULL
, "Failed to find font resource\n");
2201 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &font
, sizeof(HRSRC
), &rloader
, &ffile
);
2202 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2204 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
2205 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2206 IDWriteFontFile_Release(ffile
);
2208 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
2209 IDWriteFontFace_Release(fontface
);
2211 win_skip("GetUnicodeRanges() is not supported.\n");
2212 IDWriteFactory_Release(factory
);
2217 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 0, NULL
, &count
);
2218 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
2219 ok(count
> 0, "got %u\n", count
);
2222 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, NULL
, &count
);
2223 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2224 ok(count
== 0, "got %u\n", count
);
2227 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, &r
, &count
);
2228 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
2229 ok(count
> 1, "got %u\n", count
);
2231 ranges
= heap_alloc(count
*sizeof(DWRITE_UNICODE_RANGE
));
2232 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, count
, ranges
, &count
);
2233 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2235 ranges
[0].first
= ranges
[0].last
= 0;
2236 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, ranges
, &count
);
2237 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
2238 ok(ranges
[0].first
!= 0 && ranges
[0].last
!= 0, "got 0x%x-0x%0x\n", ranges
[0].first
, ranges
[0].last
);
2242 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
2243 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2245 IDWriteFontFace1_Release(fontface1
);
2246 IDWriteFactory_Release(factory
);
2249 static void test_GetFontFromFontFace(void)
2251 IDWriteFontFace
*fontface
, *fontface2
;
2252 IDWriteFontCollection
*collection
;
2253 IDWriteFont
*font
, *font2
, *font3
;
2254 IDWriteFontFamily
*family
;
2255 IDWriteFactory
*factory
;
2256 IDWriteFontFile
*file
;
2260 factory
= create_factory();
2262 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2263 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2265 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2266 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2268 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2269 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2270 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2272 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2273 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2276 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font2
);
2277 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2278 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
2281 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font3
);
2282 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2283 ok(font3
!= font
&& font3
!= font2
, "got %p, %p, %p\n", font3
, font2
, font
);
2285 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
2286 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2287 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
2288 IDWriteFontFace_Release(fontface2
);
2290 hr
= IDWriteFont_CreateFontFace(font3
, &fontface2
);
2291 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2292 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
2293 IDWriteFontFace_Release(fontface2
);
2294 IDWriteFontFace_Release(fontface
);
2295 IDWriteFont_Release(font3
);
2296 IDWriteFactory_Release(factory
);
2298 /* fontface that wasn't created from this collection */
2299 factory
= create_factory();
2300 path
= create_testfontfile(test_fontfile
);
2302 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2303 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2305 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
2306 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2307 IDWriteFontFile_Release(file
);
2309 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font3
);
2310 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
2311 ok(font3
== NULL
, "got %p\n", font3
);
2312 IDWriteFontFace_Release(fontface
);
2314 IDWriteFont_Release(font
);
2315 IDWriteFont_Release(font2
);
2316 IDWriteFontFamily_Release(family
);
2317 IDWriteFontCollection_Release(collection
);
2318 IDWriteFactory_Release(factory
);
2319 DELETE_FONTFILE(path
);
2322 static IDWriteFont
*get_font(IDWriteFactory
*factory
, const WCHAR
*name
, DWRITE_FONT_STYLE style
)
2324 IDWriteFontCollection
*collection
;
2325 IDWriteFontFamily
*family
;
2326 IDWriteFont
*font
= NULL
;
2331 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2332 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2336 hr
= IDWriteFontCollection_FindFamilyName(collection
, name
, &index
, &exists
);
2337 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2338 if (!exists
) goto not_found
;
2340 hr
= IDWriteFontCollection_GetFontFamily(collection
, index
, &family
);
2341 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2343 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2344 DWRITE_FONT_STRETCH_NORMAL
, style
, &font
);
2345 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2347 IDWriteFontFamily_Release(family
);
2349 IDWriteFontCollection_Release(collection
);
2353 static IDWriteFont
*get_tahoma_instance(IDWriteFactory
*factory
, DWRITE_FONT_STYLE style
)
2355 IDWriteFont
*font
= get_font(factory
, tahomaW
, style
);
2356 ok(font
!= NULL
, "failed to get Tahoma\n");
2360 static void test_GetFirstMatchingFont(void)
2362 DWRITE_FONT_SIMULATIONS simulations
;
2363 IDWriteFont
*font
, *font2
;
2364 IDWriteFactory
*factory
;
2366 factory
= create_factory();
2368 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
2369 font2
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
2370 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
2371 IDWriteFont_Release(font
);
2372 IDWriteFont_Release(font2
);
2374 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_ITALIC
);
2375 simulations
= IDWriteFont_GetSimulations(font
);
2376 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "%d\n", simulations
);
2377 IDWriteFont_Release(font
);
2379 IDWriteFactory_Release(factory
);
2382 static void test_GetInformationalStrings(void)
2384 IDWriteLocalizedStrings
*strings
, *strings2
;
2385 IDWriteFontCollection
*collection
;
2386 IDWriteFontFamily
*family
;
2387 IDWriteFactory
*factory
;
2392 factory
= create_factory();
2394 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2395 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2397 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2398 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2400 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2401 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2402 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2405 strings
= (void*)0xdeadbeef;
2406 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
+1, &strings
, &exists
);
2407 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2408 ok(exists
== FALSE
, "got %d\n", exists
);
2409 ok(strings
== NULL
, "got %p\n", strings
);
2413 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_NONE
, &strings
, &exists
);
2414 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2415 ok(exists
== FALSE
, "got %d\n", exists
);
2419 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings
, &exists
);
2420 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2421 ok(exists
== TRUE
, "got %d\n", exists
);
2423 /* strings instance is not reused */
2425 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings2
, &exists
);
2426 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2427 ok(strings2
!= strings
, "got %p, %p\n", strings2
, strings
);
2429 IDWriteLocalizedStrings_Release(strings
);
2430 IDWriteLocalizedStrings_Release(strings2
);
2431 IDWriteFont_Release(font
);
2432 IDWriteFontFamily_Release(family
);
2433 IDWriteFontCollection_Release(collection
);
2434 IDWriteFactory_Release(factory
);
2437 static void test_GetGdiInterop(void)
2439 IDWriteGdiInterop
*interop
, *interop2
;
2440 IDWriteFactory
*factory
, *factory2
;
2445 factory
= create_factory();
2448 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2449 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2452 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop2
);
2453 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2454 ok(interop
== interop2
, "got %p, %p\n", interop
, interop2
);
2455 IDWriteGdiInterop_Release(interop2
);
2457 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory2
);
2458 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2460 /* each factory gets its own interop */
2462 hr
= IDWriteFactory_GetGdiInterop(factory2
, &interop2
);
2463 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2464 ok(interop
!= interop2
, "got %p, %p\n", interop
, interop2
);
2466 /* release factory - interop still works */
2467 IDWriteFactory_Release(factory2
);
2469 memset(&logfont
, 0, sizeof(logfont
));
2470 logfont
.lfHeight
= 12;
2471 logfont
.lfWidth
= 12;
2472 logfont
.lfWeight
= FW_NORMAL
;
2473 logfont
.lfItalic
= 1;
2474 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2476 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop2
, &logfont
, &font
);
2477 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2478 IDWriteFont_Release(font
);
2480 IDWriteGdiInterop_Release(interop2
);
2481 IDWriteGdiInterop_Release(interop
);
2482 IDWriteFactory_Release(factory
);
2485 static void test_CreateFontFaceFromHdc(void)
2487 IDWriteGdiInterop
*interop
;
2488 IDWriteFontFace
*fontface
;
2489 IDWriteFactory
*factory
;
2490 HFONT hfont
, oldhfont
;
2495 factory
= create_factory();
2498 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2499 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2501 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, NULL
, &fontface
);
2502 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2504 memset(&logfont
, 0, sizeof(logfont
));
2505 logfont
.lfHeight
= 12;
2506 logfont
.lfWidth
= 12;
2507 logfont
.lfWeight
= FW_NORMAL
;
2508 logfont
.lfItalic
= 1;
2509 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2511 hfont
= CreateFontIndirectW(&logfont
);
2512 hdc
= CreateCompatibleDC(0);
2513 oldhfont
= SelectObject(hdc
, hfont
);
2516 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, hdc
, &fontface
);
2517 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2518 IDWriteFontFace_Release(fontface
);
2519 DeleteObject(SelectObject(hdc
, oldhfont
));
2522 IDWriteGdiInterop_Release(interop
);
2523 IDWriteFactory_Release(factory
);
2526 static void test_GetSimulations(void)
2528 DWRITE_FONT_SIMULATIONS simulations
;
2529 IDWriteGdiInterop
*interop
;
2530 IDWriteFontFace
*fontface
;
2531 IDWriteFactory
*factory
;
2536 factory
= create_factory();
2538 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2539 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2541 memset(&logfont
, 0, sizeof(logfont
));
2542 logfont
.lfHeight
= 12;
2543 logfont
.lfWidth
= 12;
2544 logfont
.lfWeight
= FW_NORMAL
;
2545 logfont
.lfItalic
= 1;
2546 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2548 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2549 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2551 simulations
= IDWriteFont_GetSimulations(font
);
2552 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "got %d\n", simulations
);
2553 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2554 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2555 simulations
= IDWriteFontFace_GetSimulations(fontface
);
2556 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "got %d\n", simulations
);
2557 IDWriteFontFace_Release(fontface
);
2558 IDWriteFont_Release(font
);
2560 memset(&logfont
, 0, sizeof(logfont
));
2561 logfont
.lfHeight
= 12;
2562 logfont
.lfWidth
= 12;
2563 logfont
.lfWeight
= FW_NORMAL
;
2564 logfont
.lfItalic
= 0;
2565 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2567 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2568 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2570 simulations
= IDWriteFont_GetSimulations(font
);
2571 ok(simulations
== DWRITE_FONT_SIMULATIONS_NONE
, "got %d\n", simulations
);
2572 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2573 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2574 simulations
= IDWriteFontFace_GetSimulations(fontface
);
2575 ok(simulations
== DWRITE_FONT_SIMULATIONS_NONE
, "got %d\n", simulations
);
2576 IDWriteFontFace_Release(fontface
);
2577 IDWriteFont_Release(font
);
2579 IDWriteGdiInterop_Release(interop
);
2580 IDWriteFactory_Release(factory
);
2583 static void test_GetFaceNames(void)
2585 static const WCHAR obliqueW
[] = {'O','b','l','i','q','u','e',0};
2586 static const WCHAR enus2W
[] = {'e','n','-','U','s',0};
2587 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
2588 IDWriteLocalizedStrings
*strings
, *strings2
;
2589 IDWriteGdiInterop
*interop
;
2590 IDWriteFactory
*factory
;
2591 UINT32 count
, index
;
2598 factory
= create_factory();
2600 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2601 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2603 memset(&logfont
, 0, sizeof(logfont
));
2604 logfont
.lfHeight
= 12;
2605 logfont
.lfWidth
= 12;
2606 logfont
.lfWeight
= FW_NORMAL
;
2607 logfont
.lfItalic
= 1;
2608 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2610 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2611 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2613 hr
= IDWriteFont_GetFaceNames(font
, &strings
);
2614 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2616 hr
= IDWriteFont_GetFaceNames(font
, &strings2
);
2617 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2618 ok(strings
!= strings2
, "got %p, %p\n", strings2
, strings
);
2619 IDWriteLocalizedStrings_Release(strings2
);
2621 count
= IDWriteLocalizedStrings_GetCount(strings
);
2622 ok(count
== 1, "got %d\n", count
);
2626 hr
= IDWriteLocalizedStrings_FindLocaleName(strings
, enus2W
, &index
, &exists
);
2627 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2628 ok(index
== 0 && exists
, "got %d, %d\n", index
, exists
);
2631 hr
= IDWriteLocalizedStrings_GetLocaleNameLength(strings
, 1, &count
);
2632 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2633 ok(count
== ~0, "got %d\n", count
);
2635 /* for simulated faces names are also simulated */
2637 hr
= IDWriteLocalizedStrings_GetLocaleName(strings
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2638 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2639 ok(!lstrcmpW(buffW
, enusW
), "got %s\n", wine_dbgstr_w(buffW
));
2642 hr
= IDWriteLocalizedStrings_GetString(strings
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2643 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2644 ok(!lstrcmpW(buffW
, obliqueW
), "got %s\n", wine_dbgstr_w(buffW
));
2645 IDWriteLocalizedStrings_Release(strings
);
2647 IDWriteFont_Release(font
);
2648 IDWriteGdiInterop_Release(interop
);
2649 IDWriteFactory_Release(factory
);
2658 static void test_TryGetFontTable(void)
2660 IDWriteLocalFontFileLoader
*localloader
;
2661 WIN32_FILE_ATTRIBUTE_DATA info
;
2662 const struct local_refkey
*key
;
2663 IDWriteFontFileLoader
*loader
;
2664 const void *table
, *table2
;
2665 IDWriteFontFace
*fontface
;
2666 void *context
, *context2
;
2667 IDWriteFactory
*factory
;
2668 IDWriteFontFile
*file
;
2669 WCHAR buffW
[MAX_PATH
];
2675 path
= create_testfontfile(test_fontfile
);
2677 factory
= create_factory();
2679 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2680 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2684 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2685 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2686 ok(size
!= 0, "got %u\n", size
);
2688 ret
= GetFileAttributesExW(path
, GetFileExInfoStandard
, &info
);
2689 ok(ret
, "got %d\n", ret
);
2690 ok(!memcmp(&info
.ftLastWriteTime
, &key
->writetime
, sizeof(key
->writetime
)), "got wrong write time\n");
2692 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2693 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2694 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2695 IDWriteFontFileLoader_Release(loader
);
2697 hr
= IDWriteLocalFontFileLoader_GetFilePathLengthFromKey(localloader
, key
, size
, &len
);
2698 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2699 ok(lstrlenW(key
->name
) == len
, "path length %d\n", len
);
2701 hr
= IDWriteLocalFontFileLoader_GetFilePathFromKey(localloader
, key
, size
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2702 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2703 ok(!lstrcmpW(buffW
, key
->name
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(key
->name
));
2704 IDWriteLocalFontFileLoader_Release(localloader
);
2706 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, 0, &fontface
);
2707 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2710 context
= (void*)0xdeadbeef;
2712 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_CMAP_TAG
, &table
, &size
, &context
, &exists
);
2713 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2714 ok(exists
== TRUE
, "got %d\n", exists
);
2715 ok(context
== NULL
&& table
!= NULL
, "cmap: context %p, table %p\n", context
, table
);
2718 context2
= (void*)0xdeadbeef;
2720 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_CMAP_TAG
, &table2
, &size
, &context2
, &exists
);
2721 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2722 ok(exists
== TRUE
, "got %d\n", exists
);
2723 ok(context2
== context
&& table2
== table
, "cmap: context2 %p, table2 %p\n", context2
, table2
);
2725 IDWriteFontFace_ReleaseFontTable(fontface
, context2
);
2726 IDWriteFontFace_ReleaseFontTable(fontface
, context
);
2728 IDWriteFontFace_Release(fontface
);
2729 IDWriteFontFile_Release(file
);
2730 IDWriteFactory_Release(factory
);
2731 DELETE_FONTFILE(path
);
2734 static void test_ConvertFontToLOGFONT(void)
2736 IDWriteFactory
*factory
, *factory2
;
2737 IDWriteFontCollection
*collection
;
2738 IDWriteGdiInterop
*interop
;
2739 IDWriteFontFamily
*family
;
2745 factory
= create_factory();
2746 factory2
= create_factory();
2749 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2750 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2752 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &collection
, FALSE
);
2753 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2755 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2756 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2758 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2759 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2760 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2762 if (0) { /* crashes on native */
2763 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, NULL
, NULL
);
2764 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, &logfont
, NULL
);
2765 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, font
, NULL
, &system
);
2768 memset(&logfont
, 0xcc, sizeof(logfont
));
2770 hr
= IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, &logfont
, &system
);
2771 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2772 ok(!system
, "got %d\n", system
);
2773 ok(logfont
.lfFaceName
[0] == 0, "got face name %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
2777 logfont
.lfHeight
= 10;
2778 logfont
.lfWidth
= 11;
2779 logfont
.lfEscapement
= 10;
2780 logfont
.lfOrientation
= 10;
2781 logfont
.lfWeight
= 0;
2782 logfont
.lfItalic
= 1;
2783 logfont
.lfUnderline
= 1;
2784 logfont
.lfStrikeOut
= 1;
2785 logfont
.lfCharSet
= 0;
2786 logfont
.lfOutPrecision
= 0;
2787 logfont
.lfClipPrecision
= 0;
2788 logfont
.lfQuality
= 0;
2789 logfont
.lfPitchAndFamily
= 0;
2790 logfont
.lfFaceName
[0] = 0;
2792 hr
= IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, font
, &logfont
, &system
);
2793 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2794 ok(system
, "got %d\n", system
);
2796 ok(logfont
.lfHeight
== 0, "got %d\n", logfont
.lfHeight
);
2797 ok(logfont
.lfWidth
== 0, "got %d\n", logfont
.lfWidth
);
2798 ok(logfont
.lfEscapement
== 0, "got %d\n", logfont
.lfEscapement
);
2799 ok(logfont
.lfOrientation
== 0, "got %d\n", logfont
.lfOrientation
);
2800 ok(logfont
.lfWeight
> 0, "got %d\n", logfont
.lfWeight
);
2801 ok(logfont
.lfItalic
== 0, "got %d\n", logfont
.lfItalic
);
2802 ok(logfont
.lfUnderline
== 0, "got %d\n", logfont
.lfUnderline
);
2803 ok(logfont
.lfStrikeOut
== 0, "got %d\n", logfont
.lfStrikeOut
);
2804 ok(logfont
.lfCharSet
== DEFAULT_CHARSET
, "got %d\n", logfont
.lfCharSet
);
2805 ok(logfont
.lfOutPrecision
== OUT_OUTLINE_PRECIS
, "got %d\n", logfont
.lfOutPrecision
);
2806 ok(logfont
.lfClipPrecision
== 0, "got %d\n", logfont
.lfClipPrecision
);
2807 ok(logfont
.lfQuality
== 0, "got %d\n", logfont
.lfQuality
);
2808 ok(logfont
.lfPitchAndFamily
== 0, "got %d\n", logfont
.lfPitchAndFamily
);
2809 ok(logfont
.lfFaceName
[0] != 0, "got face name %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
2811 IDWriteFactory_Release(factory2
);
2813 IDWriteFontCollection_Release(collection
);
2814 IDWriteFontFamily_Release(family
);
2815 IDWriteFont_Release(font
);
2816 IDWriteGdiInterop_Release(interop
);
2817 IDWriteFactory_Release(factory
);
2820 static void test_CreateStreamFromKey(void)
2822 IDWriteLocalFontFileLoader
*localloader
;
2823 IDWriteFontFileStream
*stream
, *stream2
;
2824 IDWriteFontFileLoader
*loader
;
2825 IDWriteFactory
*factory
;
2826 IDWriteFontFile
*file
;
2833 factory
= create_factory();
2835 path
= create_testfontfile(test_fontfile
);
2837 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2838 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2842 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2843 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2844 ok(size
!= 0, "got %u\n", size
);
2846 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2847 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2848 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2849 IDWriteFontFileLoader_Release(loader
);
2851 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2852 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2853 EXPECT_REF(stream
, 1);
2855 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream2
);
2856 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2857 ok(stream
== stream2
|| broken(stream
!= stream2
) /* Win7 SP0 */, "got %p, %p\n", stream
, stream2
);
2858 if (stream
== stream2
)
2859 EXPECT_REF(stream
, 2);
2860 IDWriteFontFileStream_Release(stream
);
2861 IDWriteFontFileStream_Release(stream2
);
2863 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2864 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2865 EXPECT_REF(stream
, 1);
2868 hr
= IDWriteFontFileStream_GetLastWriteTime(stream
, &writetime
);
2869 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2870 ok(writetime
!= 0, "got %08x%08x\n", (UINT
)(writetime
>> 32), (UINT
)writetime
);
2872 IDWriteFontFileStream_Release(stream
);
2873 IDWriteFontFile_Release(file
);
2875 IDWriteLocalFontFileLoader_Release(localloader
);
2876 IDWriteFactory_Release(factory
);
2877 DELETE_FONTFILE(path
);
2880 static void test_ReadFileFragment(void)
2882 IDWriteLocalFontFileLoader
*localloader
;
2883 IDWriteFontFileStream
*stream
;
2884 IDWriteFontFileLoader
*loader
;
2885 IDWriteFactory
*factory
;
2886 IDWriteFontFile
*file
;
2887 const void *fragment
, *fragment2
;
2888 void *key
, *context
, *context2
;
2894 factory
= create_factory();
2896 path
= create_testfontfile(test_fontfile
);
2898 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2899 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2903 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2904 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2905 ok(size
!= 0, "got %u\n", size
);
2907 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2908 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2909 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2910 IDWriteFontFileLoader_Release(loader
);
2912 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2913 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2915 hr
= IDWriteFontFileStream_GetFileSize(stream
, &filesize
);
2916 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2918 /* reading past the end of the stream */
2919 fragment
= (void*)0xdeadbeef;
2920 context
= (void*)0xdeadbeef;
2921 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
+1, &context
);
2922 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2923 ok(context
== NULL
, "got %p\n", context
);
2924 ok(fragment
== NULL
, "got %p\n", fragment
);
2926 fragment
= (void*)0xdeadbeef;
2927 context
= (void*)0xdeadbeef;
2928 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
, &context
);
2929 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2930 ok(context
== NULL
, "got %p\n", context
);
2931 ok(fragment
!= NULL
, "got %p\n", fragment
);
2933 fragment2
= (void*)0xdeadbeef;
2934 context2
= (void*)0xdeadbeef;
2935 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment2
, 0, filesize
, &context2
);
2936 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2937 ok(context2
== NULL
, "got %p\n", context2
);
2938 ok(fragment
== fragment2
, "got %p, %p\n", fragment
, fragment2
);
2940 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
2941 IDWriteFontFileStream_ReleaseFileFragment(stream
, context2
);
2943 /* fragment is released, try again */
2944 fragment
= (void*)0xdeadbeef;
2945 context
= (void*)0xdeadbeef;
2946 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
, &context
);
2947 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2948 ok(context
== NULL
, "got %p\n", context
);
2949 ok(fragment
== fragment2
, "got %p, %p\n", fragment
, fragment2
);
2950 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
2952 IDWriteFontFile_Release(file
);
2953 IDWriteFontFileStream_Release(stream
);
2954 IDWriteLocalFontFileLoader_Release(localloader
);
2955 IDWriteFactory_Release(factory
);
2956 DELETE_FONTFILE(path
);
2959 static void test_GetDesignGlyphMetrics(void)
2961 DWRITE_GLYPH_METRICS metrics
[2];
2962 IDWriteFontFace
*fontface
;
2963 IDWriteFactory
*factory
;
2964 IDWriteFontFile
*file
;
2970 factory
= create_factory();
2972 path
= create_testfontfile(test_fontfile
);
2974 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2975 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2977 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
,
2978 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
2979 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2980 IDWriteFontFile_Release(file
);
2984 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &codepoint
, 1, &indices
[0]);
2985 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2986 ok(indices
[0] > 0, "got %u\n", indices
[0]);
2988 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, NULL
, 0, metrics
, FALSE
);
2989 ok(hr
== E_INVALIDARG
, "got 0x%08x\n",hr
);
2991 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, NULL
, 1, metrics
, FALSE
);
2992 ok(hr
== E_INVALIDARG
, "got 0x%08x\n",hr
);
2994 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, indices
, 0, metrics
, FALSE
);
2995 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2997 /* missing glyphs are ignored */
2999 memset(metrics
, 0xcc, sizeof(metrics
));
3000 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, indices
, 2, metrics
, FALSE
);
3001 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3002 ok(metrics
[0].advanceWidth
== 1000, "got %d\n", metrics
[0].advanceWidth
);
3003 ok(metrics
[1].advanceWidth
== 0, "got %d\n", metrics
[1].advanceWidth
);
3005 IDWriteFontFace_Release(fontface
);
3006 IDWriteFactory_Release(factory
);
3007 DELETE_FONTFILE(path
);
3010 static void test_IsMonospacedFont(void)
3012 static const WCHAR courierW
[] = {'C','o','u','r','i','e','r',' ','N','e','w',0};
3013 IDWriteFontCollection
*collection
;
3014 IDWriteFactory
*factory
;
3019 factory
= create_factory();
3020 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
3021 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3024 hr
= IDWriteFontCollection_FindFamilyName(collection
, courierW
, &index
, &exists
);
3025 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3027 IDWriteFontFamily
*family
;
3028 IDWriteFont1
*font1
;
3031 hr
= IDWriteFontCollection_GetFontFamily(collection
, index
, &family
);
3032 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3034 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
3035 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
3036 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3037 IDWriteFontFamily_Release(family
);
3039 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
3041 IDWriteFontFace1
*fontface1
;
3042 IDWriteFontFace
*fontface
;
3045 is_monospaced
= IDWriteFont1_IsMonospacedFont(font1
);
3046 ok(is_monospaced
, "got %d\n", is_monospaced
);
3048 hr
= IDWriteFont1_CreateFontFace(font1
, &fontface
);
3049 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3050 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3051 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3052 is_monospaced
= IDWriteFontFace1_IsMonospacedFont(fontface1
);
3053 ok(is_monospaced
, "got %d\n", is_monospaced
);
3054 IDWriteFontFace1_Release(fontface1
);
3056 IDWriteFontFace_Release(fontface
);
3057 IDWriteFont1_Release(font1
);
3060 win_skip("IsMonospacedFont() is not supported.\n");
3063 skip("Courier New font not found.\n");
3065 IDWriteFontCollection_Release(collection
);
3068 static void test_GetDesignGlyphAdvances(void)
3070 IDWriteFontFace1
*fontface1
;
3071 IDWriteFontFace
*fontface
;
3072 IDWriteFactory
*factory
;
3073 IDWriteFontFile
*file
;
3077 factory
= create_factory();
3079 path
= create_testfontfile(test_fontfile
);
3081 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3082 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3084 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
,
3085 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3086 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3087 IDWriteFontFile_Release(file
);
3089 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3097 hr
= IDWriteFontFace1_GetGlyphIndices(fontface1
, &codepoint
, 1, &index
);
3098 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3099 ok(index
> 0, "got %u\n", index
);
3102 hr
= IDWriteFontFace1_GetDesignGlyphAdvances(fontface1
, 1, &index
, &advance
, FALSE
);
3103 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3104 ok(advance
== 1000, "got %i\n", advance
);
3107 hr
= IDWriteFontFace1_GetDesignGlyphAdvances(fontface1
, 1, &index
, &advance
, TRUE
);
3108 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3110 ok(advance
== 2048, "got %i\n", advance
);
3112 IDWriteFontFace1_Release(fontface1
);
3115 win_skip("GetDesignGlyphAdvances() is not supported.\n");
3117 IDWriteFontFace_Release(fontface
);
3118 IDWriteFactory_Release(factory
);
3119 DELETE_FONTFILE(path
);
3122 static void test_GetGlyphRunOutline(void)
3124 DWRITE_GLYPH_OFFSET offsets
[2];
3125 IDWriteFactory
*factory
;
3126 IDWriteFontFile
*file
;
3127 IDWriteFontFace
*face
;
3134 path
= create_testfontfile(test_fontfile
);
3135 factory
= create_factory();
3137 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3138 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3140 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
3141 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3142 IDWriteFontFile_Release(file
);
3146 hr
= IDWriteFontFace_GetGlyphIndices(face
, &codepoint
, 1, glyphs
);
3147 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3148 ok(glyphs
[0] > 0, "got %u\n", glyphs
[0]);
3149 glyphs
[1] = glyphs
[0];
3151 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 2048.0, glyphs
, advances
, offsets
, 1, FALSE
, FALSE
, NULL
);
3152 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3154 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 2048.0, NULL
, NULL
, offsets
, 1, FALSE
, FALSE
, &test_geomsink
);
3155 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3160 offsets
[0].advanceOffset
= 1.0;
3161 offsets
[0].ascenderOffset
= 1.0;
3162 offsets
[1].advanceOffset
= 0.0;
3163 offsets
[1].ascenderOffset
= 0.0;
3165 /* default advances, no offsets */
3166 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3167 g_startpoint_count
= 0;
3168 SET_EXPECT(setfillmode
);
3169 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 2, FALSE
, FALSE
, &test_geomsink
);
3170 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3171 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3172 if (g_startpoint_count
== 2) {
3173 /* glyph advance of 500 is applied */
3174 ok(g_startpoints
[0].x
== 229.5 && g_startpoints
[0].y
== -629.0, "0: got (%.2f,%.2f)\n", g_startpoints
[0].x
, g_startpoints
[0].y
);
3175 ok(g_startpoints
[1].x
== 729.5 && g_startpoints
[1].y
== -629.0, "1: got (%.2f,%.2f)\n", g_startpoints
[1].x
, g_startpoints
[1].y
);
3177 CHECK_CALLED(setfillmode
);
3179 /* default advances, no offsets, RTL */
3180 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3181 g_startpoint_count
= 0;
3182 SET_EXPECT(setfillmode
);
3183 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 2, FALSE
, TRUE
, &test_geomsink
);
3184 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3185 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3186 if (g_startpoint_count
== 2) {
3187 /* advance is -500 now */
3188 ok(g_startpoints
[0].x
== -270.5 && g_startpoints
[0].y
== -629.0, "0: got (%.2f,%.2f)\n", g_startpoints
[0].x
, g_startpoints
[0].y
);
3189 ok(g_startpoints
[1].x
== -770.5 && g_startpoints
[1].y
== -629.0, "1: got (%.2f,%.2f)\n", g_startpoints
[1].x
, g_startpoints
[1].y
);
3191 CHECK_CALLED(setfillmode
);
3193 /* default advances, additional offsets */
3194 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3195 g_startpoint_count
= 0;
3196 SET_EXPECT(setfillmode
);
3197 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, offsets
, 2, FALSE
, FALSE
, &test_geomsink
);
3198 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3199 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3200 if (g_startpoint_count
== 2) {
3201 /* offsets applied to first contour */
3202 ok(g_startpoints
[0].x
== 230.5 && g_startpoints
[0].y
== -630.0, "0: got (%.2f,%.2f)\n", g_startpoints
[0].x
, g_startpoints
[0].y
);
3203 ok(g_startpoints
[1].x
== 729.5 && g_startpoints
[1].y
== -629.0, "1: got (%.2f,%.2f)\n", g_startpoints
[1].x
, g_startpoints
[1].y
);
3205 CHECK_CALLED(setfillmode
);
3207 /* default advances, additional offsets, RTL */
3208 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3209 g_startpoint_count
= 0;
3210 SET_EXPECT(setfillmode
);
3211 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, offsets
, 2, FALSE
, TRUE
, &test_geomsink
);
3212 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3213 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3214 if (g_startpoint_count
== 2) {
3215 ok(g_startpoints
[0].x
== -271.5 && g_startpoints
[0].y
== -630.0, "0: got (%.2f,%.2f)\n", g_startpoints
[0].x
, g_startpoints
[0].y
);
3216 ok(g_startpoints
[1].x
== -770.5 && g_startpoints
[1].y
== -629.0, "1: got (%.2f,%.2f)\n", g_startpoints
[1].x
, g_startpoints
[1].y
);
3218 CHECK_CALLED(setfillmode
);
3220 /* custom advances and offsets, offset turns total advance value to zero */
3221 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3222 g_startpoint_count
= 0;
3223 SET_EXPECT(setfillmode
);
3224 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, advances
, offsets
, 2, FALSE
, FALSE
, &test_geomsink
);
3225 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3226 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3227 if (g_startpoint_count
== 2) {
3228 ok(g_startpoints
[0].x
== 230.5 && g_startpoints
[0].y
== -630.0, "0: got (%.2f,%.2f)\n", g_startpoints
[0].x
, g_startpoints
[0].y
);
3229 ok(g_startpoints
[1].x
== 230.5 && g_startpoints
[1].y
== -629.0, "1: got (%.2f,%.2f)\n", g_startpoints
[1].x
, g_startpoints
[1].y
);
3231 CHECK_CALLED(setfillmode
);
3234 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 0, FALSE
, FALSE
, &test_geomsink2
);
3235 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3237 IDWriteFactory_Release(factory
);
3238 IDWriteFontFace_Release(face
);
3239 DELETE_FONTFILE(path
);
3242 factory
= create_factory();
3243 face
= create_fontface(factory
);
3247 hr
= IDWriteFontFace_GetGlyphIndices(face
, &codepoint
, 1, glyphs
);
3248 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3249 ok(glyphs
[0] > 0, "got %u\n", glyphs
[0]);
3251 SET_EXPECT(setfillmode
);
3252 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 1, FALSE
, FALSE
, &test_geomsink2
);
3253 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3254 CHECK_CALLED(setfillmode
);
3256 IDWriteFactory_Release(factory
);
3257 IDWriteFontFace_Release(face
);
3260 static void test_GetEudcFontCollection(void)
3262 IDWriteFontCollection
*coll
, *coll2
;
3263 IDWriteFactory1
*factory1
;
3264 IDWriteFactory
*factory
;
3267 factory
= create_factory();
3269 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory1
, (void**)&factory1
);
3270 IDWriteFactory_Release(factory
);
3272 win_skip("GetEudcFontCollection() is not supported.\n");
3276 hr
= IDWriteFactory1_GetEudcFontCollection(factory1
, &coll
, FALSE
);
3277 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3278 hr
= IDWriteFactory1_GetEudcFontCollection(factory1
, &coll2
, FALSE
);
3279 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3280 ok(coll
== coll2
, "got %p, %p\n", coll
, coll2
);
3281 IDWriteFontCollection_Release(coll
);
3282 IDWriteFontCollection_Release(coll2
);
3284 IDWriteFactory1_Release(factory1
);
3287 static void test_GetCaretMetrics(void)
3289 DWRITE_FONT_METRICS1 metrics
;
3290 IDWriteFontFace1
*fontface1
;
3291 DWRITE_CARET_METRICS caret
;
3292 IDWriteFontFace
*fontface
;
3293 IDWriteFactory
*factory
;
3294 IDWriteFontFile
*file
;
3299 path
= create_testfontfile(test_fontfile
);
3300 factory
= create_factory();
3302 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3303 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3305 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3306 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3307 IDWriteFontFile_Release(file
);
3309 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3310 IDWriteFontFace_Release(fontface
);
3312 win_skip("GetCaretMetrics() is not supported.\n");
3313 IDWriteFactory_Release(factory
);
3314 DELETE_FONTFILE(path
);
3318 memset(&caret
, 0xcc, sizeof(caret
));
3319 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
3320 ok(caret
.slopeRise
== 1, "got %d\n", caret
.slopeRise
);
3321 ok(caret
.slopeRun
== 0, "got %d\n", caret
.slopeRun
);
3322 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
3323 IDWriteFontFace1_Release(fontface1
);
3324 IDWriteFactory_Release(factory
);
3326 /* now with Tahoma Normal */
3327 factory
= create_factory();
3328 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
3329 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3330 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3331 IDWriteFont_Release(font
);
3332 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3333 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3334 IDWriteFontFace_Release(fontface
);
3336 memset(&caret
, 0xcc, sizeof(caret
));
3337 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
3338 ok(caret
.slopeRise
== 1, "got %d\n", caret
.slopeRise
);
3339 ok(caret
.slopeRun
== 0, "got %d\n", caret
.slopeRun
);
3340 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
3341 IDWriteFontFace1_Release(fontface1
);
3343 /* simulated italic */
3344 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_ITALIC
);
3345 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3346 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3347 IDWriteFont_Release(font
);
3348 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3349 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3350 IDWriteFontFace_Release(fontface
);
3352 IDWriteFontFace1_GetMetrics(fontface1
, &metrics
);
3354 memset(&caret
, 0xcc, sizeof(caret
));
3355 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
3356 ok(caret
.slopeRise
== metrics
.designUnitsPerEm
, "got %d\n", caret
.slopeRise
);
3357 ok(caret
.slopeRun
> 0, "got %d\n", caret
.slopeRun
);
3358 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
3359 IDWriteFontFace1_Release(fontface1
);
3361 IDWriteFactory_Release(factory
);
3362 DELETE_FONTFILE(path
);
3365 static void test_GetGlyphCount(void)
3367 IDWriteFontFace
*fontface
;
3368 IDWriteFactory
*factory
;
3369 IDWriteFontFile
*file
;
3374 path
= create_testfontfile(test_fontfile
);
3375 factory
= create_factory();
3377 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3378 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3380 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3381 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3382 IDWriteFontFile_Release(file
);
3384 count
= IDWriteFontFace_GetGlyphCount(fontface
);
3385 ok(count
== 7, "got %u\n", count
);
3387 IDWriteFontFace_Release(fontface
);
3388 IDWriteFactory_Release(factory
);
3389 DELETE_FONTFILE(path
);
3392 static void test_GetKerningPairAdjustments(void)
3394 IDWriteFontFace1
*fontface1
;
3395 IDWriteFontFace
*fontface
;
3396 IDWriteFactory
*factory
;
3397 IDWriteFontFile
*file
;
3401 path
= create_testfontfile(test_fontfile
);
3402 factory
= create_factory();
3404 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3405 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3407 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3408 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3409 IDWriteFontFile_Release(file
);
3411 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3413 INT32 adjustments
[1];
3415 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 0, NULL
, NULL
);
3416 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
3418 if (0) /* crashes on native */
3419 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 1, NULL
, NULL
);
3422 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 1, NULL
, adjustments
);
3423 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3424 ok(adjustments
[0] == 0, "got %d\n", adjustments
[0]);
3426 IDWriteFontFace1_Release(fontface1
);
3429 win_skip("GetKerningPairAdjustments() is not supported.\n");
3431 IDWriteFontFace_Release(fontface
);
3432 IDWriteFactory_Release(factory
);
3433 DELETE_FONTFILE(path
);
3436 static void test_CreateRenderingParams(void)
3438 IDWriteRenderingParams2
*params2
;
3439 IDWriteRenderingParams1
*params1
;
3440 IDWriteRenderingParams
*params
;
3441 DWRITE_RENDERING_MODE mode
;
3442 IDWriteFactory
*factory
;
3445 factory
= create_factory();
3447 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 1.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT
,
3448 DWRITE_RENDERING_MODE_DEFAULT
, ¶ms
);
3449 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3451 hr
= IDWriteRenderingParams_QueryInterface(params
, &IID_IDWriteRenderingParams1
, (void**)¶ms1
);
3455 /* test what enhanced contrast setting set by default to */
3456 enhcontrast
= IDWriteRenderingParams1_GetGrayscaleEnhancedContrast(params1
);
3457 ok(enhcontrast
== 1.0, "got %.2f\n", enhcontrast
);
3458 IDWriteRenderingParams1_Release(params1
);
3460 hr
= IDWriteRenderingParams_QueryInterface(params
, &IID_IDWriteRenderingParams2
, (void**)¶ms2
);
3462 DWRITE_GRID_FIT_MODE gridfit
;
3464 /* default gridfit mode */
3465 gridfit
= IDWriteRenderingParams2_GetGridFitMode(params2
);
3466 ok(gridfit
== DWRITE_GRID_FIT_MODE_DEFAULT
, "got %d\n", gridfit
);
3468 IDWriteRenderingParams2_Release(params2
);
3471 win_skip("IDWriteRenderingParams2 not supported.\n");
3474 win_skip("IDWriteRenderingParams1 not supported.\n");
3476 IDWriteRenderingParams_Release(params
);
3478 hr
= IDWriteFactory_CreateRenderingParams(factory
, ¶ms
);
3479 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3481 mode
= IDWriteRenderingParams_GetRenderingMode(params
);
3482 ok(mode
== DWRITE_RENDERING_MODE_DEFAULT
, "got %d\n", mode
);
3483 IDWriteRenderingParams_Release(params
);
3485 IDWriteFactory_Release(factory
);
3488 static void test_CreateGlyphRunAnalysis(void)
3490 static const DWRITE_RENDERING_MODE rendermodes
[] = {
3491 DWRITE_RENDERING_MODE_ALIASED
,
3492 DWRITE_RENDERING_MODE_GDI_CLASSIC
,
3493 DWRITE_RENDERING_MODE_GDI_NATURAL
,
3494 DWRITE_RENDERING_MODE_NATURAL
,
3495 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
,
3498 IDWriteGlyphRunAnalysis
*analysis
, *analysis2
;
3499 IDWriteFactory
*factory
;
3500 DWRITE_GLYPH_RUN run
;
3501 IDWriteFontFace
*face
;
3502 UINT16 glyph
, glyphs
[10];
3507 DWRITE_GLYPH_OFFSET offsets
[2];
3508 DWRITE_GLYPH_METRICS metrics
;
3509 DWRITE_FONT_METRICS fm
;
3513 factory
= create_factory();
3514 face
= create_fontface(factory
);
3518 hr
= IDWriteFontFace_GetGlyphIndices(face
, &ch
, 1, &glyph
);
3519 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3520 ok(glyph
> 0, "got %u\n", glyph
);
3522 hr
= IDWriteFontFace_GetDesignGlyphMetrics(face
, &glyph
, 1, &metrics
, FALSE
);
3523 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3524 advances
[0] = metrics
.advanceWidth
;
3526 offsets
[0].advanceOffset
= 0.0;
3527 offsets
[0].ascenderOffset
= 0.0;
3529 run
.fontFace
= face
;
3530 run
.fontEmSize
= 24.0;
3532 run
.glyphIndices
= &glyph
;
3533 run
.glyphAdvances
= advances
;
3534 run
.glyphOffsets
= offsets
;
3535 run
.isSideways
= FALSE
;
3539 analysis
= (void*)0xdeadbeef;
3540 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 0.0, NULL
,
3541 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3542 0.0, 0.0, &analysis
);
3543 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3544 ok(analysis
== NULL
, "got %p\n", analysis
);
3546 /* negative ppdip */
3547 analysis
= (void*)0xdeadbeef;
3548 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, -1.0, NULL
,
3549 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3550 0.0, 0.0, &analysis
);
3551 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3552 ok(analysis
== NULL
, "got %p\n", analysis
);
3554 /* default mode is not allowed */
3555 analysis
= (void*)0xdeadbeef;
3556 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3557 DWRITE_RENDERING_MODE_DEFAULT
, DWRITE_MEASURING_MODE_NATURAL
,
3558 0.0, 0.0, &analysis
);
3559 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3560 ok(analysis
== NULL
, "got %p\n", analysis
);
3563 analysis
= (void*)0xdeadbeef;
3564 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3565 DWRITE_RENDERING_MODE_OUTLINE
, DWRITE_MEASURING_MODE_NATURAL
,
3566 0.0, 0.0, &analysis
);
3567 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3568 ok(analysis
== NULL
, "got %p\n", analysis
);
3570 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3571 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3572 0.0, 0.0, &analysis
);
3573 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3575 /* invalid texture type */
3576 memset(&rect
, 0xcc, sizeof(rect
));
3577 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
+1, &rect
);
3578 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3579 ok(rect
.left
== 0 && rect
.right
== 0 &&
3580 rect
.top
== 0 && rect
.bottom
== 0, "unexpected rect\n");
3582 /* check how origin affects bounds */
3583 memset(&rect
, 0, sizeof(rect
));
3584 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3585 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3586 ok(!IsRectEmpty(&rect
), "got empty rect\n");
3587 IDWriteGlyphRunAnalysis_Release(analysis
);
3590 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 2.0, NULL
,
3591 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3592 0.0, 0.0, &analysis
);
3593 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3594 memset(&rect2
, 0, sizeof(rect2
));
3595 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect2
);
3596 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3597 ok(rect
.right
- rect
.left
< rect2
.right
- rect2
.left
, "expected wider rect\n");
3598 ok(rect
.bottom
- rect
.top
< rect2
.bottom
- rect2
.top
, "expected taller rect\n");
3599 IDWriteGlyphRunAnalysis_Release(analysis
);
3601 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3602 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3603 10.0, -5.0, &analysis
);
3604 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3606 memset(&rect2
, 0, sizeof(rect2
));
3607 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect2
);
3608 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3609 ok(!IsRectEmpty(&rect2
), "got empty rect\n");
3610 IDWriteGlyphRunAnalysis_Release(analysis
);
3612 ok(!EqualRect(&rect
, &rect2
), "got equal bounds\n");
3613 OffsetRect(&rect
, 10, -5);
3614 ok(EqualRect(&rect
, &rect2
), "got different bounds\n");
3616 for (i
= 0; i
< sizeof(rendermodes
)/sizeof(rendermodes
[0]); i
++) {
3617 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3618 rendermodes
[i
], DWRITE_MEASURING_MODE_NATURAL
,
3619 0.0, 0.0, &analysis
);
3620 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3622 if (rendermodes
[i
] == DWRITE_RENDERING_MODE_ALIASED
) {
3623 memset(&rect
, 0, sizeof(rect
));
3624 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3625 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3626 ok(!IsRectEmpty(&rect
), "got empty rect\n");
3628 rect
.left
= rect
.top
= 0;
3629 rect
.bottom
= rect
.right
= 1;
3630 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &rect
);
3631 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3632 ok(IsRectEmpty(&rect
), "unexpected empty rect\n");
3635 rect
.left
= rect
.top
= 0;
3636 rect
.bottom
= rect
.right
= 1;
3637 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3638 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3639 ok(IsRectEmpty(&rect
), "got empty rect\n");
3641 memset(&rect
, 0, sizeof(rect
));
3642 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &rect
);
3643 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3644 ok(!IsRectEmpty(&rect
), "got empty rect\n");
3647 IDWriteGlyphRunAnalysis_Release(analysis
);
3650 IDWriteFontFace_GetMetrics(run
.fontFace
, &fm
);
3652 /* check bbox for a single glyph run */
3653 for (run
.fontEmSize
= 1.0; run
.fontEmSize
<= 100.0; run
.fontEmSize
+= 1.0) {
3654 DWRITE_GLYPH_METRICS gm
;
3657 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3658 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
3659 0.0, 0.0, &analysis
);
3660 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3662 memset(&rect
, 0, sizeof(rect
));
3663 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3664 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3666 hr
= IDWriteFontFace_GetGdiCompatibleGlyphMetrics(run
.fontFace
, run
.fontEmSize
, 1.0, NULL
,
3667 DWRITE_MEASURING_MODE_GDI_CLASSIC
, run
.glyphIndices
, 1, &gm
, run
.isSideways
);
3668 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3670 /* metrics are in design units */
3671 bboxX
= (int)floorf((gm
.advanceWidth
- gm
.leftSideBearing
- gm
.rightSideBearing
) * run
.fontEmSize
/ fm
.designUnitsPerEm
+ 0.5f
);
3672 bboxY
= (int)floorf((gm
.advanceHeight
- gm
.topSideBearing
- gm
.bottomSideBearing
) * run
.fontEmSize
/ fm
.designUnitsPerEm
+ 0.5f
);
3674 rect
.right
-= rect
.left
;
3675 rect
.bottom
-= rect
.top
;
3676 ok(abs(bboxX
- rect
.right
) <= 2, "%.0f: bbox width %d, from metrics %d\n", run
.fontEmSize
, rect
.right
, bboxX
);
3677 ok(abs(bboxY
- rect
.bottom
) <= 2, "%.0f: bbox height %d, from metrics %d\n", run
.fontEmSize
, rect
.bottom
, bboxY
);
3679 IDWriteGlyphRunAnalysis_Release(analysis
);
3682 /* without offsets */
3683 run
.fontFace
= face
;
3684 run
.fontEmSize
= 24.0;
3686 run
.glyphIndices
= &glyph
;
3687 run
.glyphAdvances
= advances
;
3688 run
.glyphOffsets
= NULL
;
3689 run
.isSideways
= FALSE
;
3692 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3693 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3694 0.0, 0.0, &analysis
);
3695 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3697 SetRectEmpty(&rect
);
3698 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3699 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3700 ok(!IsRectEmpty(&rect
), "got empty bounds\n");
3702 IDWriteGlyphRunAnalysis_Release(analysis
);
3704 /* without explicit advances */
3705 run
.fontFace
= face
;
3706 run
.fontEmSize
= 24.0;
3708 run
.glyphIndices
= &glyph
;
3709 run
.glyphAdvances
= NULL
;
3710 run
.glyphOffsets
= NULL
;
3711 run
.isSideways
= FALSE
;
3714 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3715 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3716 0.0, 0.0, &analysis
);
3717 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3719 SetRectEmpty(&rect
);
3720 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3721 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3722 ok(!IsRectEmpty(&rect
), "got empty bounds\n");
3724 IDWriteGlyphRunAnalysis_Release(analysis
);
3726 /* test that advances are scaled according to ppdip too */
3727 glyphs
[0] = glyphs
[1] = glyph
;
3728 advances
[0] = advances
[1] = 100.0f
;
3729 run
.fontFace
= face
;
3730 run
.fontEmSize
= 24.0;
3732 run
.glyphIndices
= glyphs
;
3733 run
.glyphAdvances
= advances
;
3734 run
.glyphOffsets
= NULL
;
3735 run
.isSideways
= FALSE
;
3738 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3739 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3740 0.0, 0.0, &analysis
);
3741 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3743 SetRectEmpty(&rect2
);
3744 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect2
);
3745 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3746 ok(!IsRectEmpty(&rect2
), "got empty bounds\n");
3747 ok(!EqualRect(&rect
, &rect2
), "got wrong rect2\n");
3748 ok((rect2
.right
- rect
.left
) > advances
[0], "got rect width %d for advance %f\n", rect
.right
- rect
.left
, advances
[0]);
3749 IDWriteGlyphRunAnalysis_Release(analysis
);
3751 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 2.0, NULL
,
3752 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3753 0.0, 0.0, &analysis
);
3754 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3756 SetRectEmpty(&rect
);
3757 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3758 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3759 ok((rect
.right
- rect
.left
) > 2 * advances
[0], "got rect width %d for advance %f\n", rect
.right
- rect
.left
, advances
[0]);
3760 IDWriteGlyphRunAnalysis_Release(analysis
);
3762 /* with scaling transform */
3763 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3764 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3765 0.0, 0.0, &analysis
);
3766 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3768 SetRectEmpty(&rect
);
3769 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3770 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3771 ok(!IsRectEmpty(&rect
), "got rect width %d\n", rect
.right
- rect
.left
);
3772 IDWriteGlyphRunAnalysis_Release(analysis
);
3774 memset(&m
, 0, sizeof(m
));
3777 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, &m
,
3778 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3779 0.0, 0.0, &analysis
);
3780 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3782 SetRectEmpty(&rect2
);
3783 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect2
);
3784 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3785 ok((rect2
.right
- rect2
.left
) > (rect
.right
- rect
.left
), "got rect width %d\n", rect2
.right
- rect2
.left
);
3787 /* instances are not reused for same runs */
3788 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, &m
,
3789 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3790 0.0, 0.0, &analysis2
);
3791 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3792 ok(analysis2
!= analysis
, "got %p, previous instance %p\n", analysis2
, analysis
);
3793 IDWriteGlyphRunAnalysis_Release(analysis2
);
3795 IDWriteGlyphRunAnalysis_Release(analysis
);
3797 IDWriteFontFace_Release(face
);
3798 IDWriteFactory_Release(factory
);
3801 #define round(x) ((int)floor((x) + 0.5))
3832 #ifdef WORDS_BIGENDIAN
3833 #define GET_BE_WORD(x) (x)
3835 #define GET_BE_WORD(x) RtlUshortByteSwap(x)
3838 static const struct VDMX_group
*find_vdmx_group(const struct VDMX_Header
*hdr
)
3840 WORD num_ratios
, i
, group_offset
= 0;
3841 struct VDMX_Ratio
*ratios
= (struct VDMX_Ratio
*)(hdr
+ 1);
3842 BYTE dev_x_ratio
= 1, dev_y_ratio
= 1;
3844 num_ratios
= GET_BE_WORD(hdr
->numRatios
);
3846 for (i
= 0; i
< num_ratios
; i
++)
3848 if (!ratios
[i
].bCharSet
) continue;
3850 if ((ratios
[i
].xRatio
== 0 && ratios
[i
].yStartRatio
== 0 &&
3851 ratios
[i
].yEndRatio
== 0) ||
3852 (ratios
[i
].xRatio
== dev_x_ratio
&& ratios
[i
].yStartRatio
<= dev_y_ratio
&&
3853 ratios
[i
].yEndRatio
>= dev_y_ratio
))
3855 group_offset
= GET_BE_WORD(*((WORD
*)(ratios
+ num_ratios
) + i
));
3860 return (const struct VDMX_group
*)((BYTE
*)hdr
+ group_offset
);
3864 static BOOL
get_vdmx_size(const struct VDMX_group
*group
, int emsize
, int *a
, int *d
)
3867 const struct VDMX_vTable
*tables
;
3869 if (!group
) return FALSE
;
3871 recs
= GET_BE_WORD(group
->recs
);
3872 if (emsize
< group
->startsz
|| emsize
>= group
->endsz
) return FALSE
;
3874 tables
= (const struct VDMX_vTable
*)(group
+ 1);
3875 for (i
= 0; i
< recs
; i
++)
3877 WORD ppem
= GET_BE_WORD(tables
[i
].yPelHeight
);
3880 /* FIXME: Supposed to interpolate */
3881 trace("FIXME interpolate %d\n", emsize
);
3887 *a
= (SHORT
)GET_BE_WORD(tables
[i
].yMax
);
3888 *d
= -(SHORT
)GET_BE_WORD(tables
[i
].yMin
);
3895 static void test_metrics_cmp(FLOAT emsize
, const DWRITE_FONT_METRICS
*metrics
, const DWRITE_FONT_METRICS1
*expected
)
3897 ok(metrics
->designUnitsPerEm
== expected
->designUnitsPerEm
, "%.2f: emsize: got %u expect %u\n",
3898 emsize
, metrics
->designUnitsPerEm
, expected
->designUnitsPerEm
);
3899 ok(metrics
->ascent
== expected
->ascent
, "%.2f a: got %u expect %u\n",
3900 emsize
, metrics
->ascent
, expected
->ascent
);
3901 ok(metrics
->descent
== expected
->descent
, "%.2f d: got %u expect %u\n",
3902 emsize
, metrics
->descent
, expected
->descent
);
3903 ok(metrics
->lineGap
== expected
->lineGap
, "%.2f lg: got %d expect %d\n",
3904 emsize
, metrics
->lineGap
, expected
->lineGap
);
3905 ok(metrics
->capHeight
== expected
->capHeight
, "%.2f capH: got %u expect %u\n",
3906 emsize
, metrics
->capHeight
, expected
->capHeight
);
3907 ok(metrics
->xHeight
== expected
->xHeight
, "%.2f xH: got %u expect %u\n",
3908 emsize
, metrics
->xHeight
, expected
->xHeight
);
3909 ok(metrics
->underlinePosition
== expected
->underlinePosition
, "%.2f ulP: got %d expect %d\n",
3910 emsize
, metrics
->underlinePosition
, expected
->underlinePosition
);
3911 ok(metrics
->underlineThickness
== expected
->underlineThickness
, "%.2f ulTh: got %u expect %u\n",
3912 emsize
, metrics
->underlineThickness
, expected
->underlineThickness
);
3913 ok(metrics
->strikethroughPosition
== expected
->strikethroughPosition
, "%.2f stP: got %d expect %d\n",
3914 emsize
, metrics
->strikethroughPosition
, expected
->strikethroughPosition
);
3915 ok(metrics
->strikethroughThickness
== expected
->strikethroughThickness
, "%.2f stTh: got %u expect %u\n",
3916 emsize
, metrics
->strikethroughThickness
, expected
->strikethroughThickness
);
3919 static void test_metrics1_cmp(FLOAT emsize
, const DWRITE_FONT_METRICS1
*metrics
, const DWRITE_FONT_METRICS1
*expected
)
3921 ok(metrics
->designUnitsPerEm
== expected
->designUnitsPerEm
, "%.2f: emsize: got %u expect %u\n",
3922 emsize
, metrics
->designUnitsPerEm
, expected
->designUnitsPerEm
);
3923 ok(metrics
->ascent
== expected
->ascent
, "%.2f a: got %u expect %u\n",
3924 emsize
, metrics
->ascent
, expected
->ascent
);
3925 ok(metrics
->descent
== expected
->descent
, "%.2f d: got %u expect %u\n",
3926 emsize
, metrics
->descent
, expected
->descent
);
3927 ok(metrics
->lineGap
== expected
->lineGap
, "%.2f lg: got %d expect %d\n",
3928 emsize
, metrics
->lineGap
, expected
->lineGap
);
3929 ok(metrics
->capHeight
== expected
->capHeight
, "%.2f capH: got %u expect %u\n",
3930 emsize
, metrics
->capHeight
, expected
->capHeight
);
3931 ok(metrics
->xHeight
== expected
->xHeight
, "%.2f xH: got %u expect %u\n",
3932 emsize
, metrics
->xHeight
, expected
->xHeight
);
3933 ok(metrics
->underlinePosition
== expected
->underlinePosition
, "%.2f ulP: got %d expect %d\n",
3934 emsize
, metrics
->underlinePosition
, expected
->underlinePosition
);
3935 ok(metrics
->underlineThickness
== expected
->underlineThickness
, "%.2f ulTh: got %u expect %u\n",
3936 emsize
, metrics
->underlineThickness
, expected
->underlineThickness
);
3937 ok(metrics
->strikethroughPosition
== expected
->strikethroughPosition
, "%.2f stP: got %d expect %d\n",
3938 emsize
, metrics
->strikethroughPosition
, expected
->strikethroughPosition
);
3939 ok(metrics
->strikethroughThickness
== expected
->strikethroughThickness
, "%.2f stTh: got %u expect %u\n",
3940 emsize
, metrics
->strikethroughThickness
, expected
->strikethroughThickness
);
3941 ok(metrics
->glyphBoxLeft
== expected
->glyphBoxLeft
, "%.2f box left: got %d expect %d\n",
3942 emsize
, metrics
->glyphBoxLeft
, expected
->glyphBoxLeft
);
3943 if (0) { /* this is not consistent */
3944 ok(metrics
->glyphBoxTop
== expected
->glyphBoxTop
, "%.2f box top: got %d expect %d\n",
3945 emsize
, metrics
->glyphBoxTop
, expected
->glyphBoxTop
);
3946 ok(metrics
->glyphBoxRight
== expected
->glyphBoxRight
, "%.2f box right: got %d expect %d\n",
3947 emsize
, metrics
->glyphBoxRight
, expected
->glyphBoxRight
);
3949 ok(metrics
->glyphBoxBottom
== expected
->glyphBoxBottom
, "%.2f box bottom: got %d expect %d\n",
3950 emsize
, metrics
->glyphBoxBottom
, expected
->glyphBoxBottom
);
3951 ok(metrics
->subscriptPositionX
== expected
->subscriptPositionX
, "%.2f subX: got %d expect %d\n",
3952 emsize
, metrics
->subscriptPositionX
, expected
->subscriptPositionX
);
3953 ok(metrics
->subscriptPositionY
== expected
->subscriptPositionY
, "%.2f subY: got %d expect %d\n",
3954 emsize
, metrics
->subscriptPositionY
, expected
->subscriptPositionY
);
3955 ok(metrics
->subscriptSizeX
== expected
->subscriptSizeX
, "%.2f subsizeX: got %d expect %d\n",
3956 emsize
, metrics
->subscriptSizeX
, expected
->subscriptSizeX
);
3957 ok(metrics
->subscriptPositionY
== expected
->subscriptPositionY
, "%.2f subsizeY: got %d expect %d\n",
3958 emsize
, metrics
->subscriptSizeY
, expected
->subscriptSizeY
);
3959 ok(metrics
->superscriptPositionX
== expected
->superscriptPositionX
, "%.2f supX: got %d expect %d\n",
3960 emsize
, metrics
->superscriptPositionX
, expected
->superscriptPositionX
);
3962 ok(metrics
->superscriptPositionY
== expected
->superscriptPositionY
, "%.2f supY: got %d expect %d\n",
3963 emsize
, metrics
->superscriptPositionY
, expected
->superscriptPositionY
);
3964 ok(metrics
->superscriptSizeX
== expected
->superscriptSizeX
, "%.2f supsizeX: got %d expect %d\n",
3965 emsize
, metrics
->superscriptSizeX
, expected
->superscriptSizeX
);
3966 ok(metrics
->superscriptSizeY
== expected
->superscriptSizeY
, "%.2f supsizeY: got %d expect %d\n",
3967 emsize
, metrics
->superscriptSizeY
, expected
->superscriptSizeY
);
3968 ok(metrics
->hasTypographicMetrics
== expected
->hasTypographicMetrics
, "%.2f hastypo: got %d expect %d\n",
3969 emsize
, metrics
->hasTypographicMetrics
, expected
->hasTypographicMetrics
);
3972 struct compatmetrics_test
{
3978 static struct compatmetrics_test compatmetrics_tests
[] = {
3979 { { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, 1.0, 5.0 },
3980 { { 0.0, 0.0, 0.0, -1.0, 0.0, 0.0 }, 1.0, 5.0 },
3981 { { 0.0, 0.0, 0.0, -1.0, 0.0, 0.0 }, 2.0, 5.0 },
3982 { { 0.0, 0.0, 0.0, 3.0, 0.0, 0.0 }, 2.0, 5.0 },
3983 { { 0.0, 0.0, 0.0, -3.0, 0.0, 0.0 }, 2.0, 5.0 },
3984 { { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, 2.0, 5.0 },
3985 { { 1.0, 0.0, 0.0, 1.0, 5.0, 0.0 }, 2.0, 5.0 },
3986 { { 1.0, 0.0, 0.0, 1.0, 0.0, 5.0 }, 2.0, 5.0 },
3989 static void get_expected_metrics(IDWriteFontFace
*fontface
, struct compatmetrics_test
*ptr
,
3990 DWRITE_FONT_METRICS
*expected
)
3994 memset(expected
, 0, sizeof(*expected
));
3995 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(fontface
, ptr
->ppdip
* fabsf(ptr
->m
.m22
) * ptr
->emsize
, 1.0, NULL
, expected
);
3996 ok(hr
== S_OK
, "got %08x\n", hr
);
3999 static void test_GetGdiCompatibleMetrics_face(IDWriteFontFace
*face
)
4001 IDWriteFontFace1
*fontface1
= NULL
;
4003 DWRITE_FONT_METRICS design_metrics
, comp_metrics
;
4004 DWRITE_FONT_METRICS1 design_metrics1
, expected
;
4005 FLOAT emsize
, scale
;
4006 int ascent
, descent
;
4007 const struct VDMX_Header
*vdmx
;
4011 const struct VDMX_group
*vdmx_group
= NULL
;
4014 hr
= IDWriteFontFace_QueryInterface(face
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4016 win_skip("gdi compatible DWRITE_FONT_METRICS1 are not supported.\n");
4019 IDWriteFontFace1_GetMetrics(fontface1
, &design_metrics1
);
4020 memcpy(&design_metrics
, &design_metrics1
, sizeof(design_metrics
));
4023 IDWriteFontFace_GetMetrics(face
, &design_metrics
);
4025 hr
= IDWriteFontFace_TryGetFontTable(face
, MS_VDMX_TAG
, (const void **)&vdmx
,
4026 &vdmx_len
, &vdmx_ctx
, &exists
);
4027 if (hr
!= S_OK
|| !exists
)
4030 vdmx_group
= find_vdmx_group(vdmx
);
4032 /* negative emsize */
4033 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
4034 memset(&expected
, 0, sizeof(expected
));
4035 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, -10.0, 1.0, NULL
, &comp_metrics
);
4036 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
4037 test_metrics_cmp(0.0, &comp_metrics
, &expected
);
4040 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
4041 memset(&expected
, 0, sizeof(expected
));
4042 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 0.0, 1.0, NULL
, &comp_metrics
);
4043 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
4044 test_metrics_cmp(0.0, &comp_metrics
, &expected
);
4046 /* zero pixels per dip */
4047 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
4048 memset(&expected
, 0, sizeof(expected
));
4049 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 5.0, 0.0, NULL
, &comp_metrics
);
4050 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
4051 test_metrics_cmp(5.0, &comp_metrics
, &expected
);
4053 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
4054 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 5.0, -1.0, NULL
, &comp_metrics
);
4055 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
4056 test_metrics_cmp(5.0, &comp_metrics
, &expected
);
4058 for (i
= 0; i
< sizeof(compatmetrics_tests
)/sizeof(compatmetrics_tests
[0]); i
++) {
4059 struct compatmetrics_test
*ptr
= &compatmetrics_tests
[i
];
4061 get_expected_metrics(face
, ptr
, (DWRITE_FONT_METRICS
*)&expected
);
4062 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, ptr
->emsize
, ptr
->ppdip
, &ptr
->m
, &comp_metrics
);
4063 ok(hr
== S_OK
, "got %08x\n", hr
);
4064 test_metrics_cmp(ptr
->emsize
, &comp_metrics
, &expected
);
4067 for (emsize
= 5; emsize
<= design_metrics
.designUnitsPerEm
; emsize
++)
4069 DWRITE_FONT_METRICS1 comp_metrics1
, expected
;
4072 hr
= IDWriteFontFace1_GetGdiCompatibleMetrics(fontface1
, emsize
, 1.0, NULL
, &comp_metrics1
);
4073 ok(hr
== S_OK
, "got %08x\n", hr
);
4076 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, emsize
, 1.0, NULL
, &comp_metrics
);
4077 ok(hr
== S_OK
, "got %08x\n", hr
);
4080 scale
= emsize
/ design_metrics
.designUnitsPerEm
;
4081 if (!get_vdmx_size(vdmx_group
, emsize
, &ascent
, &descent
))
4083 ascent
= round(design_metrics
.ascent
* scale
);
4084 descent
= round(design_metrics
.descent
* scale
);
4087 expected
.designUnitsPerEm
= design_metrics
.designUnitsPerEm
;
4088 expected
.ascent
= round(ascent
/ scale
);
4089 expected
.descent
= round(descent
/ scale
);
4090 expected
.lineGap
= round(round(design_metrics
.lineGap
* scale
) / scale
);
4091 expected
.capHeight
= round(round(design_metrics
.capHeight
* scale
) / scale
);
4092 expected
.xHeight
= round(round(design_metrics
.xHeight
* scale
) / scale
);
4093 expected
.underlinePosition
= round(round(design_metrics
.underlinePosition
* scale
) / scale
);
4094 expected
.underlineThickness
= round(round(design_metrics
.underlineThickness
* scale
) / scale
);
4095 expected
.strikethroughPosition
= round(round(design_metrics
.strikethroughPosition
* scale
) / scale
);
4096 expected
.strikethroughThickness
= round(round(design_metrics
.strikethroughThickness
* scale
) / scale
);
4099 expected
.glyphBoxLeft
= round(round(design_metrics1
.glyphBoxLeft
* scale
) / scale
);
4101 if (0) { /* those two fail on Tahoma and Win7 */
4102 expected
.glyphBoxTop
= round(round(design_metrics1
.glyphBoxTop
* scale
) / scale
);
4103 expected
.glyphBoxRight
= round(round(design_metrics1
.glyphBoxRight
* scale
) / scale
);
4105 expected
.glyphBoxBottom
= round(round(design_metrics1
.glyphBoxBottom
* scale
) / scale
);
4106 expected
.subscriptPositionX
= round(round(design_metrics1
.subscriptPositionX
* scale
) / scale
);
4107 expected
.subscriptPositionY
= round(round(design_metrics1
.subscriptPositionY
* scale
) / scale
);
4108 expected
.subscriptSizeX
= round(round(design_metrics1
.subscriptSizeX
* scale
) / scale
);
4109 expected
.subscriptSizeY
= round(round(design_metrics1
.subscriptSizeY
* scale
) / scale
);
4110 expected
.superscriptPositionX
= round(round(design_metrics1
.superscriptPositionX
* scale
) / scale
);
4111 if (0) /* this fails for 3 emsizes, Tahoma from [5, 2048] range */
4112 expected
.superscriptPositionY
= round(round(design_metrics1
.superscriptPositionY
* scale
) / scale
);
4113 expected
.superscriptSizeX
= round(round(design_metrics1
.superscriptSizeX
* scale
) / scale
);
4114 expected
.superscriptSizeY
= round(round(design_metrics1
.superscriptSizeY
* scale
) / scale
);
4115 expected
.hasTypographicMetrics
= design_metrics1
.hasTypographicMetrics
;
4117 test_metrics1_cmp(emsize
, &comp_metrics1
, &expected
);
4120 test_metrics_cmp(emsize
, &comp_metrics
, &expected
);
4125 IDWriteFontFace1_Release(fontface1
);
4126 if (vdmx
) IDWriteFontFace_ReleaseFontTable(face
, vdmx_ctx
);
4129 static void test_GetGdiCompatibleMetrics(void)
4131 IDWriteFactory
*factory
;
4133 IDWriteFontFace
*fontface
;
4136 factory
= create_factory();
4138 font
= get_font(factory
, tahomaW
, DWRITE_FONT_STYLE_NORMAL
);
4139 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4140 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4141 IDWriteFont_Release(font
);
4142 test_GetGdiCompatibleMetrics_face(fontface
);
4143 IDWriteFontFace_Release(fontface
);
4145 font
= get_font(factory
, arialW
, DWRITE_FONT_STYLE_NORMAL
);
4147 skip("Skipping tests with Arial\n");
4150 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4151 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4152 IDWriteFont_Release(font
);
4154 test_GetGdiCompatibleMetrics_face(fontface
);
4155 IDWriteFontFace_Release(fontface
);
4158 IDWriteFactory_Release(factory
);
4161 static void test_GetPanose(void)
4163 IDWriteFactory
*factory
;
4164 IDWriteFont1
*font1
;
4168 factory
= create_factory();
4169 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
4171 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
4172 IDWriteFont_Release(font
);
4174 DWRITE_PANOSE panose
;
4176 if (0) /* crashes on native */
4177 IDWriteFont1_GetPanose(font1
, NULL
);
4179 memset(&panose
, 0, sizeof(panose
));
4180 IDWriteFont1_GetPanose(font1
, &panose
);
4181 ok(panose
.familyKind
== DWRITE_PANOSE_FAMILY_TEXT_DISPLAY
,
4182 "got %u\n", panose
.familyKind
);
4183 ok(panose
.text
.serifStyle
== DWRITE_PANOSE_SERIF_STYLE_NORMAL_SANS
,
4184 "got %u\n", panose
.text
.serifStyle
);
4185 ok(panose
.text
.weight
== DWRITE_PANOSE_WEIGHT_MEDIUM
,
4186 "got %u\n", panose
.text
.weight
);
4187 ok(panose
.text
.proportion
== DWRITE_PANOSE_PROPORTION_EVEN_WIDTH
,
4188 "got %u\n", panose
.text
.proportion
);
4189 ok(panose
.text
.contrast
== DWRITE_PANOSE_CONTRAST_VERY_LOW
,
4190 "got %u\n", panose
.text
.contrast
);
4191 ok(panose
.text
.strokeVariation
== DWRITE_PANOSE_STROKE_VARIATION_GRADUAL_VERTICAL
,
4192 "got %u\n", panose
.text
.strokeVariation
);
4193 ok(panose
.text
.armStyle
== DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_VERTICAL
,
4194 "got %u\n", panose
.text
.armStyle
);
4195 ok(panose
.text
.letterform
== DWRITE_PANOSE_LETTERFORM_NORMAL_BOXED
,
4196 "got %u\n", panose
.text
.letterform
);
4197 ok(panose
.text
.midline
== DWRITE_PANOSE_MIDLINE_STANDARD_TRIMMED
,
4198 "got %u\n", panose
.text
.midline
);
4199 ok(panose
.text
.xHeight
== DWRITE_PANOSE_XHEIGHT_CONSTANT_LARGE
,
4200 "got %u\n", panose
.text
.xHeight
);
4202 IDWriteFont1_Release(font1
);
4205 win_skip("GetPanose() is not supported.\n");
4207 IDWriteFactory_Release(factory
);
4210 static INT32
get_gdi_font_advance(HDC hdc
, FLOAT emsize
)
4217 memset(&logfont
, 0, sizeof(logfont
));
4218 logfont
.lfHeight
= (LONG
)-emsize
;
4219 logfont
.lfWeight
= FW_NORMAL
;
4220 logfont
.lfQuality
= CLEARTYPE_QUALITY
;
4221 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
4223 hfont
= CreateFontIndirectW(&logfont
);
4224 SelectObject(hdc
, hfont
);
4226 ret
= GetCharABCWidthsW(hdc
, 'A', 'A', &abc
);
4227 ok(ret
, "got %d\n", ret
);
4229 DeleteObject(hfont
);
4231 return abc
.abcA
+ abc
.abcB
+ abc
.abcC
;
4234 static void test_GetGdiCompatibleGlyphAdvances(void)
4236 IDWriteFontFace1
*fontface1
;
4237 IDWriteFontFace
*fontface
;
4238 IDWriteFactory
*factory
;
4245 DWRITE_FONT_METRICS1 fm
;
4248 factory
= create_factory();
4249 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
4251 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4252 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4253 IDWriteFont_Release(font
);
4255 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4256 IDWriteFontFace_Release(fontface
);
4259 IDWriteFactory_Release(factory
);
4260 win_skip("GetGdiCompatibleGlyphAdvances() is not supported\n");
4266 hr
= IDWriteFontFace1_GetGlyphIndices(fontface1
, &codepoint
, 1, &glyph
);
4267 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4268 ok(glyph
> 0, "got %u\n", glyph
);
4272 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 0.0,
4273 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4274 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4275 ok(advance
== 0, "got %d\n", advance
);
4277 /* negative emsize */
4279 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, -1.0,
4280 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4281 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4282 ok(advance
== 0, "got %d\n", advance
);
4286 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 1.0,
4287 0.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4288 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4289 ok(advance
== 0, "got %d\n", advance
);
4291 /* negative ppdip */
4293 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 1.0,
4294 -1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4295 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4296 ok(advance
== 0, "got %d\n", advance
);
4298 IDWriteFontFace1_GetMetrics(fontface1
, &fm
);
4300 hdc
= CreateCompatibleDC(0);
4302 for (emsize
= 1.0; emsize
<= fm
.designUnitsPerEm
; emsize
+= 1.0) {
4305 gdi_advance
= get_gdi_font_advance(hdc
, emsize
);
4306 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, emsize
,
4307 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4308 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4310 /* advance is in design units */
4311 advance
= (int)floorf(emsize
* advance
/ fm
.designUnitsPerEm
+ 0.5f
);
4312 ok((advance
- gdi_advance
) <= 2, "%.0f: got advance %d, expected %d\n", emsize
, advance
, gdi_advance
);
4317 IDWriteFactory_Release(factory
);
4320 static WORD
get_gasp_flags(IDWriteFontFace
*fontface
, FLOAT emsize
, FLOAT ppdip
)
4322 WORD num_recs
, version
;
4333 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_GASP_TAG
,
4334 (const void**)&ptr
, &size
, &ctxt
, &exists
);
4335 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4340 version
= GET_BE_WORD( *ptr
++ );
4341 num_recs
= GET_BE_WORD( *ptr
++ );
4342 if (version
> 1 || size
< (num_recs
* 2 + 2) * sizeof(WORD
)) {
4343 ok(0, "unsupported gasp table: ver %d size %d recs %d\n", version
, size
, num_recs
);
4349 flags
= GET_BE_WORD( *(ptr
+ 1) );
4350 if (emsize
<= GET_BE_WORD( *ptr
)) break;
4355 IDWriteFontFace_ReleaseFontTable(fontface
, ctxt
);
4359 #define GASP_GRIDFIT 0x0001
4360 #define GASP_DOGRAY 0x0002
4361 #define GASP_SYMMETRIC_GRIDFIT 0x0004
4362 #define GASP_SYMMETRIC_SMOOTHING 0x0008
4364 static BOOL g_is_vista
;
4365 static DWRITE_RENDERING_MODE
get_expected_rendering_mode(FLOAT emsize
, WORD gasp
, DWRITE_MEASURING_MODE mode
,
4366 DWRITE_OUTLINE_THRESHOLD threshold
)
4368 static const FLOAT aa_threshold
= 100.0f
;
4369 static const FLOAT a_threshold
= 350.0f
;
4370 static const FLOAT naturalemsize
= 20.0f
;
4373 /* outline threshold */
4375 v
= mode
== DWRITE_MEASURING_MODE_NATURAL
? aa_threshold
: a_threshold
;
4377 v
= threshold
== DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
? aa_threshold
: a_threshold
;
4380 return DWRITE_RENDERING_MODE_OUTLINE
;
4384 case DWRITE_MEASURING_MODE_NATURAL
:
4385 if (!(gasp
& GASP_SYMMETRIC_SMOOTHING
) && (emsize
<= naturalemsize
))
4386 return DWRITE_RENDERING_MODE_NATURAL
;
4388 return DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
;
4389 case DWRITE_MEASURING_MODE_GDI_CLASSIC
:
4390 return DWRITE_RENDERING_MODE_GDI_CLASSIC
;
4391 case DWRITE_MEASURING_MODE_GDI_NATURAL
:
4392 return DWRITE_RENDERING_MODE_GDI_NATURAL
;
4397 /* should be unreachable */
4398 return DWRITE_RENDERING_MODE_DEFAULT
;
4401 static DWRITE_GRID_FIT_MODE
get_expected_gridfit_mode(FLOAT emsize
, WORD gasp
, DWRITE_MEASURING_MODE mode
,
4402 DWRITE_OUTLINE_THRESHOLD threshold
)
4404 static const FLOAT aa_threshold
= 100.0f
;
4405 static const FLOAT a_threshold
= 350.0f
;
4408 v
= threshold
== DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
? aa_threshold
: a_threshold
;
4410 return DWRITE_GRID_FIT_MODE_DISABLED
;
4412 if (mode
== DWRITE_MEASURING_MODE_GDI_CLASSIC
|| mode
== DWRITE_MEASURING_MODE_GDI_NATURAL
)
4413 return DWRITE_GRID_FIT_MODE_ENABLED
;
4415 return (gasp
& (GASP_GRIDFIT
|GASP_SYMMETRIC_GRIDFIT
)) ? DWRITE_GRID_FIT_MODE_ENABLED
: DWRITE_GRID_FIT_MODE_DISABLED
;
4418 struct recommendedmode_test
4420 DWRITE_MEASURING_MODE measuring
;
4421 DWRITE_OUTLINE_THRESHOLD threshold
;
4424 static const struct recommendedmode_test recmode_tests
[] = {
4425 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4426 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4427 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4430 static const struct recommendedmode_test recmode_tests1
[] = {
4431 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4432 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4433 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4434 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
4435 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
4436 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
4439 static void test_GetRecommendedRenderingMode(void)
4441 IDWriteRenderingParams
*params
;
4442 IDWriteFontFace2
*fontface2
;
4443 IDWriteFontFace1
*fontface1
;
4444 IDWriteFontFace
*fontface
;
4445 DWRITE_RENDERING_MODE mode
;
4446 IDWriteFactory
*factory
;
4450 factory
= create_factory();
4451 fontface
= create_fontface(factory
);
4454 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4456 win_skip("IDWriteFontFace1::GetRecommendedRenderingMode() is not supported.\n");
4459 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
4461 win_skip("IDWriteFontFace2::GetRecommendedRenderingMode() is not supported.\n");
4463 if (0) /* crashes on native */
4464 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 3.0, 1.0,
4465 DWRITE_MEASURING_MODE_GDI_CLASSIC
, NULL
, NULL
);
4468 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 3.0, 1.0,
4469 DWRITE_MEASURING_MODE_GDI_CLASSIC
, NULL
, &mode
);
4470 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4471 ok(mode
== DWRITE_RENDERING_MODE_DEFAULT
, "got %d\n", mode
);
4473 hr
= IDWriteFactory_CreateRenderingParams(factory
, ¶ms
);
4474 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4476 /* detect old dwrite version, that is using higher threshold value */
4477 g_is_vista
= fontface1
== NULL
;
4479 for (emsize
= 1.0; emsize
< 500.0; emsize
+= 1.0) {
4480 DWRITE_RENDERING_MODE expected
;
4485 for (i
= 0; i
< sizeof(recmode_tests
)/sizeof(recmode_tests
[0]); i
++) {
4488 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4489 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests
[i
].measuring
, recmode_tests
[i
].threshold
);
4490 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, emsize
, ppdip
, recmode_tests
[i
].measuring
, params
, &mode
);
4491 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4492 ok(mode
== expected
, "%.2f/%d: got %d, ppdip %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, ppdip
, gasp
, expected
);
4494 /* some ppdip variants */
4497 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4498 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests
[i
].measuring
, recmode_tests
[i
].threshold
);
4499 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, emsize
, ppdip
, recmode_tests
[i
].measuring
, params
, &mode
);
4500 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4501 ok(mode
== expected
, "%.2f/%d: got %d, ppdip %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, ppdip
, gasp
, expected
);
4503 /* Only test larger sizes to workaround Win7 differences, where unscaled natural emsize threshold is used;
4504 Win8 and Win10 handle this as expected. */
4505 if (emsize
> 20.0f
) {
4508 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4509 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests
[i
].measuring
, recmode_tests
[i
].threshold
);
4510 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, emsize
, ppdip
, recmode_tests
[i
].measuring
, params
, &mode
);
4511 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4512 ok(mode
== expected
, "%.2f/%d: got %d, ppdip %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, ppdip
, gasp
, expected
);
4516 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4517 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests
[i
].measuring
, recmode_tests
[i
].threshold
);
4518 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, emsize
, ppdip
, recmode_tests
[i
].measuring
, params
, &mode
);
4519 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4520 ok(mode
== expected
, "%.2f/%d: got %d, ppdip %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, ppdip
, gasp
, expected
);
4524 /* IDWriteFontFace1 offers another variant of this method */
4526 for (i
= 0; i
< sizeof(recmode_tests1
)/sizeof(recmode_tests1
[0]); i
++) {
4530 dpi
= 96.0f
* ppdip
;
4532 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4533 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
4534 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
, dpi
,
4535 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
4536 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4537 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
4539 /* Only test larger sizes to workaround Win7 differences, where unscaled natural emsize threshold is used;
4540 Win8 and Win10 handle this as expected. */
4541 if (emsize
> 20.0f
) {
4543 dpi
= 96.0f
* ppdip
;
4545 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4546 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
4547 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
, dpi
,
4548 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
4549 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4550 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
4553 dpi
= 96.0f
* ppdip
;
4555 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4556 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
4557 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
, dpi
,
4558 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
4559 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4560 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
4562 /* try different dpis for X and Y direction */
4564 dpi
= 96.0f
* ppdip
;
4566 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4567 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
4568 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
* 0.5f
, dpi
,
4569 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
4570 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4571 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
4574 dpi
= 96.0f
* ppdip
;
4576 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4577 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
4578 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
, dpi
* 0.5f
,
4579 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
4580 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4581 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
4584 dpi
= 96.0f
* ppdip
;
4586 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4587 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
4588 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
* 0.5f
, dpi
,
4589 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
4590 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4591 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
4594 dpi
= 96.0f
* ppdip
;
4596 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
4597 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
4598 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
, dpi
* 0.5f
,
4599 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
4600 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4601 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
4606 /* IDWriteFontFace2 - another one */
4608 DWRITE_GRID_FIT_MODE gridfit
, expected_gridfit
;
4610 gasp
= get_gasp_flags(fontface
, emsize
, 1.0f
);
4611 for (i
= 0; i
< sizeof(recmode_tests1
)/sizeof(recmode_tests1
[0]); i
++) {
4613 expected
= get_expected_rendering_mode(emsize
, gasp
, recmode_tests1
[0].measuring
, recmode_tests1
[0].threshold
);
4614 expected_gridfit
= get_expected_gridfit_mode(emsize
, gasp
, recmode_tests1
[0].measuring
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
);
4615 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, emsize
, 96.0, 96.0,
4616 NULL
, FALSE
, recmode_tests1
[0].threshold
, recmode_tests1
[0].measuring
, params
, &mode
, &gridfit
);
4617 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4618 ok(mode
== expected
, "%.2f: got %d, flags 0x%04x, expected %d\n", emsize
, mode
, gasp
, expected
);
4619 ok(gridfit
== expected_gridfit
, "%.2f/%d: gridfit: got %d, flags 0x%04x, expected %d\n", emsize
, i
, gridfit
,
4620 gasp
, expected_gridfit
);
4625 IDWriteRenderingParams_Release(params
);
4627 /* test how parameters override returned modes */
4628 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 1.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT
,
4629 DWRITE_RENDERING_MODE_GDI_CLASSIC
, ¶ms
);
4630 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4633 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 500.0, 1.0, DWRITE_MEASURING_MODE_NATURAL
, params
, &mode
);
4634 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4635 ok(mode
== DWRITE_RENDERING_MODE_GDI_CLASSIC
, "got %d\n", mode
);
4637 IDWriteRenderingParams_Release(params
);
4640 IDWriteRenderingParams2
*params2
;
4641 IDWriteFactory2
*factory2
;
4642 DWRITE_GRID_FIT_MODE gridfit
;
4644 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory2
, (void**)&factory2
);
4645 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4647 hr
= IDWriteFactory2_CreateCustomRenderingParams(factory2
, 1.0, 0.0, 0.0, 0.5, DWRITE_PIXEL_GEOMETRY_FLAT
,
4648 DWRITE_RENDERING_MODE_OUTLINE
, DWRITE_GRID_FIT_MODE_ENABLED
, ¶ms2
);
4649 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4653 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, 5.0, 96.0, 96.0,
4654 NULL
, FALSE
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
4655 NULL
, &mode
, &gridfit
);
4656 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4657 ok(mode
== DWRITE_RENDERING_MODE_GDI_CLASSIC
, "got %d\n", mode
);
4658 ok(gridfit
== DWRITE_GRID_FIT_MODE_ENABLED
, "got %d\n", gridfit
);
4662 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, 5.0, 96.0, 96.0,
4663 NULL
, FALSE
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
4664 (IDWriteRenderingParams
*)params2
, &mode
, &gridfit
);
4665 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4666 ok(mode
== DWRITE_RENDERING_MODE_OUTLINE
, "got %d\n", mode
);
4667 ok(gridfit
== DWRITE_GRID_FIT_MODE_ENABLED
, "got %d\n", gridfit
);
4669 IDWriteRenderingParams2_Release(params2
);
4670 IDWriteFactory2_Release(factory2
);
4674 IDWriteFontFace2_Release(fontface2
);
4676 IDWriteFontFace1_Release(fontface1
);
4677 IDWriteFontFace_Release(fontface
);
4678 IDWriteFactory_Release(factory
);
4681 static inline BOOL
float_eq(FLOAT left
, FLOAT right
)
4683 int x
= *(int *)&left
;
4684 int y
= *(int *)&right
;
4691 return abs(x
- y
) <= 8;
4694 static void test_GetAlphaBlendParams(void)
4696 static const DWRITE_RENDERING_MODE rendermodes
[] = {
4697 DWRITE_RENDERING_MODE_ALIASED
,
4698 DWRITE_RENDERING_MODE_GDI_CLASSIC
,
4699 DWRITE_RENDERING_MODE_GDI_NATURAL
,
4700 DWRITE_RENDERING_MODE_NATURAL
,
4701 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
,
4704 IDWriteGlyphRunAnalysis
*analysis
;
4705 FLOAT gamma
, contrast
, ctlevel
;
4706 IDWriteRenderingParams
*params
;
4707 DWRITE_GLYPH_METRICS metrics
;
4708 DWRITE_GLYPH_OFFSET offset
;
4709 IDWriteFontFace
*fontface
;
4710 IDWriteFactory
*factory
;
4711 DWRITE_GLYPH_RUN run
;
4712 FLOAT advance
, expected_gdi_gamma
;
4719 factory
= create_factory();
4720 fontface
= create_fontface(factory
);
4724 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &ch
, 1, &glyph
);
4725 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4726 ok(glyph
> 0, "got %u\n", glyph
);
4728 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, &glyph
, 1, &metrics
, FALSE
);
4729 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4730 advance
= metrics
.advanceWidth
;
4732 offset
.advanceOffset
= 0.0;
4733 offset
.ascenderOffset
= 0.0;
4735 run
.fontFace
= fontface
;
4736 run
.fontEmSize
= 24.0;
4738 run
.glyphIndices
= &glyph
;
4739 run
.glyphAdvances
= &advance
;
4740 run
.glyphOffsets
= &offset
;
4741 run
.isSideways
= FALSE
;
4744 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 0.9, 0.3, 0.1, DWRITE_PIXEL_GEOMETRY_RGB
,
4745 DWRITE_RENDERING_MODE_DEFAULT
, ¶ms
);
4746 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4749 ret
= SystemParametersInfoW(SPI_GETFONTSMOOTHINGCONTRAST
, 0, &value
, 0);
4750 ok(ret
, "got %d\n", ret
);
4751 expected_gdi_gamma
= (FLOAT
)(value
/ 1000.0);
4753 for (i
= 0; i
< sizeof(rendermodes
)/sizeof(rendermodes
[0]); i
++) {
4754 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4755 rendermodes
[i
], DWRITE_MEASURING_MODE_NATURAL
,
4756 0.0, 0.0, &analysis
);
4757 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4759 gamma
= contrast
= ctlevel
= -1.0;
4760 hr
= IDWriteGlyphRunAnalysis_GetAlphaBlendParams(analysis
, NULL
, &gamma
, &contrast
, &ctlevel
);
4761 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4762 ok(gamma
== -1.0, "got %.2f\n", gamma
);
4763 ok(contrast
== -1.0, "got %.2f\n", contrast
);
4764 ok(ctlevel
== -1.0, "got %.2f\n", ctlevel
);
4766 gamma
= contrast
= ctlevel
= -1.0;
4767 hr
= IDWriteGlyphRunAnalysis_GetAlphaBlendParams(analysis
, params
, &gamma
, &contrast
, &ctlevel
);
4768 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4770 if (rendermodes
[i
] == DWRITE_RENDERING_MODE_GDI_CLASSIC
|| rendermodes
[i
] == DWRITE_RENDERING_MODE_GDI_NATURAL
) {
4771 ok(float_eq(gamma
, expected_gdi_gamma
), "got %.2f, expected %.2f\n", gamma
, expected_gdi_gamma
);
4772 ok(contrast
== 0.0f
, "got %.2f\n", contrast
);
4773 ok(ctlevel
== 1.0f
, "got %.2f\n", ctlevel
);
4776 ok(gamma
== 0.9f
, "got %.2f\n", gamma
);
4777 ok(contrast
== 0.3f
, "got %.2f\n", contrast
);
4778 ok(ctlevel
== 0.1f
, "got %.2f\n", ctlevel
);
4781 IDWriteGlyphRunAnalysis_Release(analysis
);
4784 IDWriteRenderingParams_Release(params
);
4785 IDWriteFontFace_Release(fontface
);
4786 IDWriteFactory_Release(factory
);
4789 static void test_CreateAlphaTexture(void)
4791 IDWriteGlyphRunAnalysis
*analysis
;
4792 DWRITE_GLYPH_METRICS metrics
;
4793 DWRITE_GLYPH_OFFSET offset
;
4794 IDWriteFontFace
*fontface
;
4795 IDWriteFactory
*factory
;
4796 DWRITE_GLYPH_RUN run
;
4804 factory
= create_factory();
4805 fontface
= create_fontface(factory
);
4809 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &ch
, 1, &glyph
);
4810 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4811 ok(glyph
> 0, "got %u\n", glyph
);
4813 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, &glyph
, 1, &metrics
, FALSE
);
4814 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4815 advance
= metrics
.advanceWidth
;
4817 offset
.advanceOffset
= 0.0;
4818 offset
.ascenderOffset
= 0.0;
4820 run
.fontFace
= fontface
;
4821 run
.fontEmSize
= 24.0;
4823 run
.glyphIndices
= &glyph
;
4824 run
.glyphAdvances
= &advance
;
4825 run
.glyphOffsets
= &offset
;
4826 run
.isSideways
= FALSE
;
4829 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4830 DWRITE_RENDERING_MODE_NATURAL
, DWRITE_MEASURING_MODE_NATURAL
,
4831 0.0, 0.0, &analysis
);
4832 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4834 SetRectEmpty(&bounds
);
4835 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &bounds
);
4836 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4837 ok(!IsRectEmpty(&bounds
), "got empty rect\n");
4838 size
= (bounds
.right
- bounds
.left
)*(bounds
.bottom
- bounds
.top
)*3;
4839 ok(sizeof(buff
) >= size
, "required %u\n", size
);
4841 /* invalid type value */
4842 memset(buff
, 0xcf, sizeof(buff
));
4843 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
+1, &bounds
, buff
, sizeof(buff
));
4844 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4845 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4847 memset(buff
, 0xcf, sizeof(buff
));
4848 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
, buff
, 2);
4849 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
4850 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4852 /* vista version allows texture type mismatch, mark it broken for now */
4853 memset(buff
, 0xcf, sizeof(buff
));
4854 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
, buff
, sizeof(buff
));
4855 ok(hr
== DWRITE_E_UNSUPPORTEDOPERATION
|| broken(hr
== S_OK
), "got 0x%08x\n", hr
);
4856 ok(buff
[0] == 0xcf || broken(buff
[0] == 0), "got %1x\n", buff
[0]);
4858 memset(buff
, 0xcf, sizeof(buff
));
4859 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &bounds
, buff
, size
-1);
4860 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
4861 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4863 IDWriteGlyphRunAnalysis_Release(analysis
);
4865 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4866 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
4867 0.0, 0.0, &analysis
);
4868 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4870 SetRectEmpty(&bounds
);
4871 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
);
4872 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4873 ok(!IsRectEmpty(&bounds
), "got empty rect\n");
4874 size
= (bounds
.right
- bounds
.left
)*(bounds
.bottom
- bounds
.top
);
4875 ok(sizeof(buff
) >= size
, "required %u\n", size
);
4877 memset(buff
, 0xcf, sizeof(buff
));
4878 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, NULL
, buff
, sizeof(buff
));
4879 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4880 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4882 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, NULL
, NULL
, sizeof(buff
));
4883 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4885 memset(buff
, 0xcf, sizeof(buff
));
4886 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, NULL
, buff
, 0);
4887 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4888 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4890 /* buffer size is not enough */
4891 memset(buff
, 0xcf, sizeof(buff
));
4892 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
, buff
, size
-1);
4893 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
4894 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4896 /* request texture for rectangle that doesn't intersect */
4897 memset(buff
, 0xcf, sizeof(buff
));
4899 OffsetRect(&r
, (bounds
.right
- bounds
.left
)*2, 0);
4900 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &r
, buff
, sizeof(buff
));
4901 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4902 ok(buff
[0] == 0, "got %1x\n", buff
[0]);
4904 memset(buff
, 0xcf, sizeof(buff
));
4906 OffsetRect(&r
, (bounds
.right
- bounds
.left
)*2, 0);
4907 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &r
, buff
, sizeof(buff
));
4908 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4909 ok(buff
[0] == 0, "got %1x\n", buff
[0]);
4911 /* request texture for rectangle that doesn't intersect, small buffer */
4912 memset(buff
, 0xcf, sizeof(buff
));
4914 OffsetRect(&r
, (bounds
.right
- bounds
.left
)*2, 0);
4915 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &r
, buff
, size
-1);
4916 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
4917 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4919 /* vista version allows texture type mismatch, mark it broken for now */
4920 memset(buff
, 0xcf, sizeof(buff
));
4921 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &bounds
, buff
, sizeof(buff
));
4922 ok(hr
== DWRITE_E_UNSUPPORTEDOPERATION
|| broken(hr
== S_OK
), "got 0x%08x\n", hr
);
4923 ok(buff
[0] == 0xcf || broken(buff
[0] == 0), "got %1x\n", buff
[0]);
4925 IDWriteGlyphRunAnalysis_Release(analysis
);
4926 IDWriteFontFace_Release(fontface
);
4927 IDWriteFactory_Release(factory
);
4930 static void test_IsSymbolFont(void)
4932 static const WCHAR symbolW
[] = {'S','y','m','b','o','l',0};
4933 IDWriteFontCollection
*collection
;
4934 IDWriteFontFace
*fontface
;
4935 IDWriteFactory
*factory
;
4940 factory
= create_factory();
4943 fontface
= create_fontface(factory
);
4944 ret
= IDWriteFontFace_IsSymbolFont(fontface
);
4945 ok(!ret
, "got %d\n", ret
);
4947 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
4948 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4950 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font
);
4951 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4953 ret
= IDWriteFont_IsSymbolFont(font
);
4954 ok(!ret
, "got %d\n", ret
);
4956 IDWriteFontCollection_Release(collection
);
4957 IDWriteFont_Release(font
);
4958 IDWriteFontFace_Release(fontface
);
4961 font
= get_font(factory
, symbolW
, DWRITE_FONT_STYLE_NORMAL
);
4962 ret
= IDWriteFont_IsSymbolFont(font
);
4963 ok(ret
, "got %d\n", ret
);
4965 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4966 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4967 ret
= IDWriteFontFace_IsSymbolFont(fontface
);
4968 ok(ret
, "got %d\n", ret
);
4969 IDWriteFont_Release(font
);
4971 IDWriteFactory_Release(factory
);
4974 struct CPAL_Header_0
4977 USHORT numPaletteEntries
;
4979 USHORT numColorRecords
;
4980 ULONG offsetFirstColorRecord
;
4981 USHORT colorRecordIndices
[1];
4984 static void test_GetPaletteEntries(void)
4986 IDWriteFontFace2
*fontface2
;
4987 IDWriteFontFace
*fontface
;
4988 IDWriteFactory
*factory
;
4990 DWRITE_COLOR_F color
;
4991 UINT32 palettecount
, entrycount
, size
, colorrecords
;
4993 const struct CPAL_Header_0
*cpal_header
;
4997 factory
= create_factory();
4999 /* Tahoma, no color support */
5000 fontface
= create_fontface(factory
);
5001 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
5002 IDWriteFontFace_Release(fontface
);
5004 IDWriteFactory_Release(factory
);
5005 win_skip("GetPaletteEntries() is not supported.\n");
5009 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, 0, 1, &color
);
5010 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
5011 IDWriteFontFace2_Release(fontface2
);
5013 /* Segoe UI Emoji, with color support */
5014 font
= get_font(factory
, emojiW
, DWRITE_FONT_STYLE_NORMAL
);
5016 IDWriteFactory_Release(factory
);
5017 skip("Segoe UI Emoji font not found.\n");
5021 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
5022 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5023 IDWriteFont_Release(font
);
5025 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
5026 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5027 IDWriteFontFace_Release(fontface
);
5029 palettecount
= IDWriteFontFace2_GetColorPaletteCount(fontface2
);
5030 ok(palettecount
>= 1, "got %u\n", palettecount
);
5032 entrycount
= IDWriteFontFace2_GetPaletteEntryCount(fontface2
);
5033 ok(entrycount
>= 1, "got %u\n", entrycount
);
5036 hr
= IDWriteFontFace2_TryGetFontTable(fontface2
, MS_CPAL_TAG
, (const void**)&cpal_header
, &size
, &ctxt
, &exists
);
5037 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5038 ok(exists
, "got %d\n", exists
);
5039 colorrecords
= GET_BE_WORD(cpal_header
->numColorRecords
);
5040 ok(colorrecords
>= 1, "got %u\n", colorrecords
);
5042 /* invalid palette index */
5043 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
5044 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, palettecount
, 0, 1, &color
);
5045 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
5046 ok(color
.r
== 123.0 && color
.g
== 123.0 && color
.b
== 123.0 && color
.a
== 123.0,
5047 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
5049 /* invalid entry index */
5050 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
5051 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, entrycount
, 1, &color
);
5052 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
5053 ok(color
.r
== 123.0 && color
.g
== 123.0 && color
.b
== 123.0 && color
.a
== 123.0,
5054 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
5056 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
5057 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, entrycount
- 1, 1, &color
);
5058 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5059 ok(color
.r
!= 123.0 && color
.g
!= 123.0 && color
.b
!= 123.0 && color
.a
!= 123.0,
5060 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
5062 /* zero return length */
5063 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
5064 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, 0, 0, &color
);
5065 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5066 ok(color
.r
== 123.0 && color
.g
== 123.0 && color
.b
== 123.0 && color
.a
== 123.0,
5067 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
5069 IDWriteFontFace2_Release(fontface2
);
5070 IDWriteFactory_Release(factory
);
5073 static void test_TranslateColorGlyphRun(void)
5075 IDWriteColorGlyphRunEnumerator
*layers
;
5076 const DWRITE_COLOR_GLYPH_RUN
*colorrun
;
5077 IDWriteFontFace
*fontface
;
5078 IDWriteFactory2
*factory2
;
5079 IDWriteFactory
*factory
;
5080 DWRITE_GLYPH_RUN run
;
5081 UINT32 codepoints
[2];
5087 factory
= create_factory();
5089 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory2
, (void**)&factory2
);
5090 IDWriteFactory_Release(factory
);
5092 win_skip("TranslateColorGlyphRun() is not supported.\n");
5096 /* Tahoma, no color support */
5097 fontface
= create_fontface((IDWriteFactory
*)factory2
);
5099 codepoints
[0] = 'A';
5100 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, codepoints
, 1, glyphs
);
5101 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5103 run
.fontFace
= fontface
;
5104 run
.fontEmSize
= 20.0f
;
5106 run
.glyphIndices
= glyphs
;
5107 run
.glyphAdvances
= NULL
;
5108 run
.glyphOffsets
= NULL
;
5109 run
.isSideways
= FALSE
;
5112 layers
= (void*)0xdeadbeef;
5113 hr
= IDWriteFactory2_TranslateColorGlyphRun(factory2
, 0.0, 0.0, &run
, NULL
,
5114 DWRITE_MEASURING_MODE_NATURAL
, NULL
, 0, &layers
);
5115 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
5116 ok(layers
== NULL
, "got %p\n", layers
);
5117 IDWriteFontFace_Release(fontface
);
5119 /* Segoe UI Emoji, with color support */
5120 font
= get_font((IDWriteFactory
*)factory2
, emojiW
, DWRITE_FONT_STYLE_NORMAL
);
5122 IDWriteFactory2_Release(factory2
);
5123 skip("Segoe UI Emoji font not found.\n");
5127 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
5128 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5129 IDWriteFont_Release(font
);
5131 codepoints
[0] = 0x26c4;
5132 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, codepoints
, 1, glyphs
);
5133 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5135 run
.fontFace
= fontface
;
5138 hr
= IDWriteFactory2_TranslateColorGlyphRun(factory2
, 0.0, 0.0, &run
, NULL
,
5139 DWRITE_MEASURING_MODE_NATURAL
, NULL
, 0, &layers
);
5140 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5141 ok(layers
!= NULL
, "got %p\n", layers
);
5145 hr
= IDWriteColorGlyphRunEnumerator_MoveNext(layers
, &hasrun
);
5147 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5153 /* iterated all way through */
5154 hr
= IDWriteColorGlyphRunEnumerator_GetCurrentRun(layers
, &colorrun
);
5156 ok(hr
== E_NOT_VALID_STATE
, "got 0x%08x\n", hr
);
5158 IDWriteColorGlyphRunEnumerator_Release(layers
);
5160 /* color font, glyph without color info */
5161 codepoints
[0] = 'A';
5162 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, codepoints
, 1, glyphs
);
5163 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5165 layers
= (void*)0xdeadbeef;
5166 hr
= IDWriteFactory2_TranslateColorGlyphRun(factory2
, 0.0, 0.0, &run
, NULL
,
5167 DWRITE_MEASURING_MODE_NATURAL
, NULL
, 0, &layers
);
5169 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
5170 ok(layers
== NULL
, "got %p\n", layers
);
5172 /* one glyph with, one without */
5173 codepoints
[0] = 'A';
5174 codepoints
[1] = 0x26c4;
5176 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, codepoints
, 2, glyphs
);
5177 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5182 hr
= IDWriteFactory2_TranslateColorGlyphRun(factory2
, 0.0, 0.0, &run
, NULL
,
5183 DWRITE_MEASURING_MODE_NATURAL
, NULL
, 0, &layers
);
5184 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5185 ok(layers
!= NULL
, "got %p\n", layers
);
5186 IDWriteColorGlyphRunEnumerator_Release(layers
);
5188 IDWriteFontFace_Release(fontface
);
5189 IDWriteFactory2_Release(factory2
);
5194 IDWriteFactory
*factory
;
5196 if (!(factory
= create_factory())) {
5197 win_skip("failed to create factory\n");
5201 test_CreateFontFromLOGFONT();
5202 test_CreateBitmapRenderTarget();
5203 test_GetFontFamily();
5204 test_GetFamilyNames();
5205 test_CreateFontFace();
5207 test_system_fontcollection();
5208 test_ConvertFontFaceToLOGFONT();
5209 test_CustomFontCollection();
5210 test_CreateCustomFontFileReference();
5211 test_CreateFontFileReference();
5212 test_shared_isolated();
5213 test_GetUnicodeRanges();
5214 test_GetFontFromFontFace();
5215 test_GetFirstMatchingFont();
5216 test_GetInformationalStrings();
5217 test_GetGdiInterop();
5218 test_CreateFontFaceFromHdc();
5219 test_GetSimulations();
5220 test_GetFaceNames();
5221 test_TryGetFontTable();
5222 test_ConvertFontToLOGFONT();
5223 test_CreateStreamFromKey();
5224 test_ReadFileFragment();
5225 test_GetDesignGlyphMetrics();
5226 test_GetDesignGlyphAdvances();
5227 test_IsMonospacedFont();
5228 test_GetGlyphRunOutline();
5229 test_GetEudcFontCollection();
5230 test_GetCaretMetrics();
5231 test_GetGlyphCount();
5232 test_GetKerningPairAdjustments();
5233 test_CreateRenderingParams();
5234 test_CreateGlyphRunAnalysis();
5235 test_GetGdiCompatibleMetrics();
5237 test_GetGdiCompatibleGlyphAdvances();
5238 test_GetRecommendedRenderingMode();
5239 test_GetAlphaBlendParams();
5240 test_CreateAlphaTexture();
5241 test_IsSymbolFont();
5242 test_GetPaletteEntries();
5243 test_TranslateColorGlyphRun();
5245 IDWriteFactory_Release(factory
);