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};
102 static IDWriteFactory
*create_factory(void)
104 IDWriteFactory
*factory
;
105 HRESULT hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory
);
106 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
110 static IDWriteFontFace
*create_fontface(IDWriteFactory
*factory
)
112 static const WCHAR tahomaW
[] = {'T','a','h','o','m','a',0};
113 IDWriteGdiInterop
*interop
;
114 IDWriteFontFace
*fontface
;
119 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
120 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
122 memset(&logfont
, 0, sizeof(logfont
));
123 logfont
.lfHeight
= 12;
124 logfont
.lfWidth
= 12;
125 logfont
.lfWeight
= FW_NORMAL
;
126 logfont
.lfItalic
= 1;
127 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
129 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
130 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
132 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
133 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
135 IDWriteFont_Release(font
);
136 IDWriteGdiInterop_Release(interop
);
141 static WCHAR
*create_testfontfile(const WCHAR
*filename
)
143 static WCHAR pathW
[MAX_PATH
];
149 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
150 lstrcatW(pathW
, filename
);
152 file
= CreateFileW(pathW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
153 ok(file
!= INVALID_HANDLE_VALUE
, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW
),
156 res
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
157 ok( res
!= 0, "couldn't find resource\n" );
158 ptr
= LockResource( LoadResource( GetModuleHandleA(NULL
), res
));
159 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleA(NULL
), res
), &written
, NULL
);
160 ok( written
== SizeofResource( GetModuleHandleA(NULL
), res
), "couldn't write resource\n" );
166 #define DELETE_FONTFILE(filename) _delete_testfontfile(filename, __LINE__)
167 static void _delete_testfontfile(const WCHAR
*filename
, int line
)
169 BOOL ret
= DeleteFileW(filename
);
170 ok_(__FILE__
,line
)(ret
, "failed to delete file %s, error %d\n", wine_dbgstr_w(filename
), GetLastError());
173 struct test_fontenumerator
175 IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface
;
179 IDWriteFontFile
*font_file
;
182 static inline struct test_fontenumerator
*impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator
* iface
)
184 return CONTAINING_RECORD(iface
, struct test_fontenumerator
, IDWriteFontFileEnumerator_iface
);
187 static HRESULT WINAPI
singlefontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
189 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
))
192 IDWriteFontFileEnumerator_AddRef(iface
);
195 return E_NOINTERFACE
;
198 static ULONG WINAPI
singlefontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
200 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
201 return InterlockedIncrement(&This
->ref
);
204 static ULONG WINAPI
singlefontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
206 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
207 ULONG ref
= InterlockedDecrement(&This
->ref
);
209 IDWriteFontFile_Release(This
->font_file
);
215 static HRESULT WINAPI
singlefontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**font_file
)
217 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
218 IDWriteFontFile_AddRef(This
->font_file
);
219 *font_file
= This
->font_file
;
223 static HRESULT WINAPI
singlefontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
225 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
227 if (This
->index
> 1) {
237 static const struct IDWriteFontFileEnumeratorVtbl singlefontfileenumeratorvtbl
=
239 singlefontfileenumerator_QueryInterface
,
240 singlefontfileenumerator_AddRef
,
241 singlefontfileenumerator_Release
,
242 singlefontfileenumerator_MoveNext
,
243 singlefontfileenumerator_GetCurrentFontFile
246 static HRESULT
create_enumerator(IDWriteFontFile
*font_file
, IDWriteFontFileEnumerator
**ret
)
248 struct test_fontenumerator
*enumerator
;
250 enumerator
= heap_alloc(sizeof(struct test_fontenumerator
));
252 return E_OUTOFMEMORY
;
254 enumerator
->IDWriteFontFileEnumerator_iface
.lpVtbl
= &singlefontfileenumeratorvtbl
;
256 enumerator
->index
= 0;
257 enumerator
->font_file
= font_file
;
258 IDWriteFontFile_AddRef(font_file
);
260 *ret
= &enumerator
->IDWriteFontFileEnumerator_iface
;
264 struct test_fontcollectionloader
266 IDWriteFontCollectionLoader IDWriteFontFileCollectionLoader_iface
;
267 IDWriteFontFileLoader
*loader
;
270 static inline struct test_fontcollectionloader
*impl_from_IDWriteFontFileCollectionLoader(IDWriteFontCollectionLoader
* iface
)
272 return CONTAINING_RECORD(iface
, struct test_fontcollectionloader
, IDWriteFontFileCollectionLoader_iface
);
275 static HRESULT WINAPI
resourcecollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
277 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontCollectionLoader
))
280 IDWriteFontCollectionLoader_AddRef(iface
);
283 return E_NOINTERFACE
;
286 static ULONG WINAPI
resourcecollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
291 static ULONG WINAPI
resourcecollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
296 static HRESULT WINAPI
resourcecollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
*factory
,
297 const void * collectionKey
, UINT32 collectionKeySize
, IDWriteFontFileEnumerator
** fontFileEnumerator
)
299 struct test_fontcollectionloader
*This
= impl_from_IDWriteFontFileCollectionLoader(iface
);
300 IDWriteFontFile
*font_file
;
303 IDWriteFactory_CreateCustomFontFileReference(factory
, collectionKey
, collectionKeySize
, This
->loader
, &font_file
);
305 hr
= create_enumerator(font_file
, fontFileEnumerator
);
306 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
308 IDWriteFontFile_Release(font_file
);
312 static const struct IDWriteFontCollectionLoaderVtbl resourcecollectionloadervtbl
= {
313 resourcecollectionloader_QueryInterface
,
314 resourcecollectionloader_AddRef
,
315 resourcecollectionloader_Release
,
316 resourcecollectionloader_CreateEnumeratorFromKey
319 /* Here is a functional custom font set of interfaces */
320 struct test_fontdatastream
322 IDWriteFontFileStream IDWriteFontFileStream_iface
;
329 static inline struct test_fontdatastream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
* iface
)
331 return CONTAINING_RECORD(iface
, struct test_fontdatastream
, IDWriteFontFileStream_iface
);
334 static HRESULT WINAPI
fontdatastream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
336 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
339 IDWriteFontFileStream_AddRef(iface
);
343 return E_NOINTERFACE
;
346 static ULONG WINAPI
fontdatastream_AddRef(IDWriteFontFileStream
*iface
)
348 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
349 ULONG ref
= InterlockedIncrement(&This
->ref
);
353 static ULONG WINAPI
fontdatastream_Release(IDWriteFontFileStream
*iface
)
355 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
356 ULONG ref
= InterlockedDecrement(&This
->ref
);
358 HeapFree(GetProcessHeap(), 0, This
);
362 static HRESULT WINAPI
fontdatastream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
364 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
365 *fragment_context
= NULL
;
366 if (offset
+fragment_size
> This
->size
)
368 *fragment_start
= NULL
;
373 *fragment_start
= (BYTE
*)This
->data
+ offset
;
378 static void WINAPI
fontdatastream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
383 static HRESULT WINAPI
fontdatastream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
385 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
390 static HRESULT WINAPI
fontdatastream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
395 static const IDWriteFontFileStreamVtbl fontdatastreamvtbl
=
397 fontdatastream_QueryInterface
,
398 fontdatastream_AddRef
,
399 fontdatastream_Release
,
400 fontdatastream_ReadFileFragment
,
401 fontdatastream_ReleaseFileFragment
,
402 fontdatastream_GetFileSize
,
403 fontdatastream_GetLastWriteTime
406 static HRESULT
create_fontdatastream(LPVOID data
, UINT size
, IDWriteFontFileStream
** iface
)
408 struct test_fontdatastream
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct test_fontdatastream
));
410 return E_OUTOFMEMORY
;
415 This
->IDWriteFontFileStream_iface
.lpVtbl
= &fontdatastreamvtbl
;
417 *iface
= &This
->IDWriteFontFileStream_iface
;
421 static HRESULT WINAPI
resourcefontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
423 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
429 return E_NOINTERFACE
;
432 static ULONG WINAPI
resourcefontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
437 static ULONG WINAPI
resourcefontfileloader_Release(IDWriteFontFileLoader
*iface
)
442 static HRESULT WINAPI
resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
448 mem
= LoadResource(GetModuleHandleA(NULL
), *(HRSRC
*)fontFileReferenceKey
);
449 ok(mem
!= NULL
, "Failed to lock font resource\n");
452 size
= SizeofResource(GetModuleHandleA(NULL
), *(HRSRC
*)fontFileReferenceKey
);
453 data
= LockResource(mem
);
454 return create_fontdatastream(data
, size
, fontFileStream
);
459 static const struct IDWriteFontFileLoaderVtbl resourcefontfileloadervtbl
= {
460 resourcefontfileloader_QueryInterface
,
461 resourcefontfileloader_AddRef
,
462 resourcefontfileloader_Release
,
463 resourcefontfileloader_CreateStreamFromKey
466 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
468 static D2D1_POINT_2F g_startpoints
[2];
469 static int g_startpoint_count
;
471 static HRESULT WINAPI
test_geometrysink_QueryInterface(ID2D1SimplifiedGeometrySink
*iface
, REFIID riid
, void **ret
)
473 if (IsEqualIID(riid
, &IID_ID2D1SimplifiedGeometrySink
) ||
474 IsEqualIID(riid
, &IID_IUnknown
))
477 ID2D1SimplifiedGeometrySink_AddRef(iface
);
482 return E_NOINTERFACE
;
485 static ULONG WINAPI
test_geometrysink_AddRef(ID2D1SimplifiedGeometrySink
*iface
)
490 static ULONG WINAPI
test_geometrysink_Release(ID2D1SimplifiedGeometrySink
*iface
)
495 static void WINAPI
test_geometrysink_SetFillMode(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FILL_MODE mode
)
497 CHECK_EXPECT(setfillmode
);
498 ok(mode
== D2D1_FILL_MODE_WINDING
, "fill mode %d\n", mode
);
501 static void WINAPI
test_geometrysink_SetSegmentFlags(ID2D1SimplifiedGeometrySink
*iface
, D2D1_PATH_SEGMENT flags
)
503 ok(0, "unexpected SetSegmentFlags() - flags %d\n", flags
);
506 static void WINAPI
test_geometrysink_BeginFigure(ID2D1SimplifiedGeometrySink
*iface
,
507 D2D1_POINT_2F startPoint
, D2D1_FIGURE_BEGIN figureBegin
)
509 ok(figureBegin
== D2D1_FIGURE_BEGIN_FILLED
, "begin figure %d\n", figureBegin
);
510 if (g_startpoint_count
< sizeof(g_startpoints
)/sizeof(g_startpoints
[0]))
511 g_startpoints
[g_startpoint_count
] = startPoint
;
512 g_startpoint_count
++;
515 static void WINAPI
test_geometrysink_AddLines(ID2D1SimplifiedGeometrySink
*iface
,
516 const D2D1_POINT_2F
*points
, UINT32 count
)
520 static void WINAPI
test_geometrysink_AddBeziers(ID2D1SimplifiedGeometrySink
*iface
,
521 const D2D1_BEZIER_SEGMENT
*beziers
, UINT32 count
)
525 static void WINAPI
test_geometrysink_EndFigure(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FIGURE_END figureEnd
)
527 ok(figureEnd
== D2D1_FIGURE_END_CLOSED
, "end figure %d\n", figureEnd
);
530 static HRESULT WINAPI
test_geometrysink_Close(ID2D1SimplifiedGeometrySink
*iface
)
532 ok(0, "unexpected Close()\n");
536 static const ID2D1SimplifiedGeometrySinkVtbl test_geometrysink_vtbl
= {
537 test_geometrysink_QueryInterface
,
538 test_geometrysink_AddRef
,
539 test_geometrysink_Release
,
540 test_geometrysink_SetFillMode
,
541 test_geometrysink_SetSegmentFlags
,
542 test_geometrysink_BeginFigure
,
543 test_geometrysink_AddLines
,
544 test_geometrysink_AddBeziers
,
545 test_geometrysink_EndFigure
,
546 test_geometrysink_Close
549 static void WINAPI
test_geometrysink2_BeginFigure(ID2D1SimplifiedGeometrySink
*iface
,
550 D2D1_POINT_2F startPoint
, D2D1_FIGURE_BEGIN figureBegin
)
552 ok(0, "unexpected call\n");
555 static void WINAPI
test_geometrysink2_AddLines(ID2D1SimplifiedGeometrySink
*iface
,
556 const D2D1_POINT_2F
*points
, UINT32 count
)
558 ok(0, "unexpected call\n");
561 static void WINAPI
test_geometrysink2_AddBeziers(ID2D1SimplifiedGeometrySink
*iface
,
562 const D2D1_BEZIER_SEGMENT
*beziers
, UINT32 count
)
564 ok(0, "unexpected call\n");
567 static void WINAPI
test_geometrysink2_EndFigure(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FIGURE_END figureEnd
)
569 ok(0, "unexpected call\n");
572 static const ID2D1SimplifiedGeometrySinkVtbl test_geometrysink2_vtbl
= {
573 test_geometrysink_QueryInterface
,
574 test_geometrysink_AddRef
,
575 test_geometrysink_Release
,
576 test_geometrysink_SetFillMode
,
577 test_geometrysink_SetSegmentFlags
,
578 test_geometrysink2_BeginFigure
,
579 test_geometrysink2_AddLines
,
580 test_geometrysink2_AddBeziers
,
581 test_geometrysink2_EndFigure
,
582 test_geometrysink_Close
585 static ID2D1SimplifiedGeometrySink test_geomsink
= { &test_geometrysink_vtbl
};
586 static ID2D1SimplifiedGeometrySink test_geomsink2
= { &test_geometrysink2_vtbl
};
588 static void test_CreateFontFromLOGFONT(void)
590 static const WCHAR tahomaspW
[] = {'T','a','h','o','m','a',' ',0};
591 IDWriteGdiInterop
*interop
;
592 DWRITE_FONT_WEIGHT weight
;
593 DWRITE_FONT_STYLE style
;
596 LONG weights
[][2] = {
597 {FW_NORMAL
, DWRITE_FONT_WEIGHT_NORMAL
},
598 {FW_BOLD
, DWRITE_FONT_WEIGHT_BOLD
},
599 { 0, DWRITE_FONT_WEIGHT_NORMAL
},
600 { 50, DWRITE_FONT_WEIGHT_NORMAL
},
601 {150, DWRITE_FONT_WEIGHT_NORMAL
},
602 {250, DWRITE_FONT_WEIGHT_NORMAL
},
603 {350, DWRITE_FONT_WEIGHT_NORMAL
},
604 {450, DWRITE_FONT_WEIGHT_NORMAL
},
605 {650, DWRITE_FONT_WEIGHT_BOLD
},
606 {750, DWRITE_FONT_WEIGHT_BOLD
},
607 {850, DWRITE_FONT_WEIGHT_BOLD
},
608 {950, DWRITE_FONT_WEIGHT_BOLD
},
609 {960, DWRITE_FONT_WEIGHT_BOLD
},
611 OUTLINETEXTMETRICW otm
;
612 IDWriteFactory
*factory
;
621 factory
= create_factory();
623 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
627 /* null out parameter crashes this call */
628 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, NULL
);
630 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, &font
);
631 EXPECT_HR(hr
, E_INVALIDARG
);
633 memset(&logfont
, 0, sizeof(logfont
));
634 logfont
.lfHeight
= 12;
635 logfont
.lfWidth
= 12;
636 logfont
.lfWeight
= FW_NORMAL
;
637 logfont
.lfItalic
= 1;
638 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
640 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
643 hfont
= CreateFontIndirectW(&logfont
);
644 hdc
= CreateCompatibleDC(0);
645 SelectObject(hdc
, hfont
);
647 otm
.otmSize
= sizeof(otm
);
648 r
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
649 ok(r
, "got %d\n", r
);
654 hr
= IDWriteFont_HasCharacter(font
, 0xd800, &exists
);
655 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
656 ok(exists
== FALSE
, "got %d\n", exists
);
659 hr
= IDWriteFont_HasCharacter(font
, 0x20, &exists
);
660 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
661 ok(exists
== TRUE
, "got %d\n", exists
);
663 /* now check properties */
664 weight
= IDWriteFont_GetWeight(font
);
665 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
, "got %d\n", weight
);
667 style
= IDWriteFont_GetStyle(font
);
668 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %d\n", style
);
670 ok(otm
.otmfsSelection
== 1, "got 0x%08x\n", otm
.otmfsSelection
);
672 ret
= IDWriteFont_IsSymbolFont(font
);
673 ok(!ret
, "got %d\n", ret
);
675 IDWriteFont_Release(font
);
678 for (i
= 0; i
< sizeof(weights
)/(2*sizeof(LONG
)); i
++)
680 memset(&logfont
, 0, sizeof(logfont
));
681 logfont
.lfHeight
= 12;
682 logfont
.lfWidth
= 12;
683 logfont
.lfWeight
= weights
[i
][0];
684 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
686 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
689 weight
= IDWriteFont_GetWeight(font
);
690 ok(weight
== weights
[i
][1],
691 "%d: got %d, expected %d\n", i
, weight
, weights
[i
][1]);
693 IDWriteFont_Release(font
);
696 /* weight not from enum */
697 memset(&logfont
, 0, sizeof(logfont
));
698 logfont
.lfHeight
= 12;
699 logfont
.lfWidth
= 12;
700 logfont
.lfWeight
= 550;
701 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
704 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
705 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
707 weight
= IDWriteFont_GetWeight(font
);
708 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
|| weight
== DWRITE_FONT_WEIGHT_BOLD
,
710 IDWriteFont_Release(font
);
712 /* empty or nonexistent face name */
713 memset(&logfont
, 0, sizeof(logfont
));
714 logfont
.lfHeight
= 12;
715 logfont
.lfWidth
= 12;
716 logfont
.lfWeight
= FW_NORMAL
;
717 lstrcpyW(logfont
.lfFaceName
, blahW
);
719 font
= (void*)0xdeadbeef;
720 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
721 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
722 ok(font
== NULL
, "got %p\n", font
);
724 /* Try with name 'Tahoma ' */
725 memset(&logfont
, 0, sizeof(logfont
));
726 logfont
.lfHeight
= 12;
727 logfont
.lfWidth
= 12;
728 logfont
.lfWeight
= FW_NORMAL
;
729 lstrcpyW(logfont
.lfFaceName
, tahomaspW
);
731 font
= (void*)0xdeadbeef;
732 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
733 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
734 ok(font
== NULL
, "got %p\n", font
);
736 /* empty string as a facename */
737 memset(&logfont
, 0, sizeof(logfont
));
738 logfont
.lfHeight
= 12;
739 logfont
.lfWidth
= 12;
740 logfont
.lfWeight
= FW_NORMAL
;
742 font
= (void*)0xdeadbeef;
743 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
744 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
745 ok(font
== NULL
, "got %p\n", font
);
747 IDWriteGdiInterop_Release(interop
);
748 IDWriteFactory_Release(factory
);
751 static void test_CreateBitmapRenderTarget(void)
753 IDWriteBitmapRenderTarget
*target
, *target2
;
754 IDWriteBitmapRenderTarget1
*target1
;
755 IDWriteGdiInterop
*interop
;
756 IDWriteFactory
*factory
;
768 factory
= create_factory();
770 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
774 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target
);
777 if (0) /* crashes on native */
778 hr
= IDWriteBitmapRenderTarget_GetSize(target
, NULL
);
780 size
.cx
= size
.cy
= -1;
781 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
783 ok(size
.cx
== 0, "got %d\n", size
.cx
);
784 ok(size
.cy
== 0, "got %d\n", size
.cy
);
787 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target2
);
789 ok(target
!= target2
, "got %p, %p\n", target2
, target
);
790 IDWriteBitmapRenderTarget_Release(target2
);
792 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
793 ok(hdc
!= NULL
, "got %p\n", hdc
);
796 ret
= GetGraphicsMode(hdc
);
797 ok(ret
== GM_ADVANCED
, "got %d\n", ret
);
799 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
800 ok(hbm
!= NULL
, "got %p\n", hbm
);
802 /* check DIB properties */
803 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
804 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
805 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
806 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
807 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
808 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
809 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
811 IDWriteBitmapRenderTarget_Release(target
);
813 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
814 ok(!hbm
, "got %p\n", hbm
);
817 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 10, 5, &target
);
820 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
821 ok(hdc
!= NULL
, "got %p\n", hdc
);
823 /* test context settings */
824 c
= GetTextColor(hdc
);
825 ok(c
== RGB(0, 0, 0), "got 0x%08x\n", c
);
826 ret
= GetBkMode(hdc
);
827 ok(ret
== OPAQUE
, "got %d\n", ret
);
829 ok(c
== RGB(255, 255, 255), "got 0x%08x\n", c
);
831 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
832 ok(hbm
!= NULL
, "got %p\n", hbm
);
834 /* check DIB properties */
835 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
836 ok(ret
== sizeof(ds
), "got %d\n", ret
);
837 ok(ds
.dsBm
.bmWidth
== 10, "got %d\n", ds
.dsBm
.bmWidth
);
838 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
839 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
840 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
841 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
843 size
.cx
= size
.cy
= -1;
844 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
846 ok(size
.cx
== 10, "got %d\n", size
.cx
);
847 ok(size
.cy
== 5, "got %d\n", size
.cy
);
849 /* resize to same size */
850 hr
= IDWriteBitmapRenderTarget_Resize(target
, 10, 5);
851 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
853 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
854 ok(hbm2
== hbm
, "got %p, %p\n", hbm2
, hbm
);
857 hr
= IDWriteBitmapRenderTarget_Resize(target
, 5, 5);
858 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
860 size
.cx
= size
.cy
= -1;
861 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
862 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
863 ok(size
.cx
== 5, "got %d\n", size
.cx
);
864 ok(size
.cy
== 5, "got %d\n", size
.cy
);
866 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
867 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
869 hr
= IDWriteBitmapRenderTarget_Resize(target
, 20, 5);
870 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
872 size
.cx
= size
.cy
= -1;
873 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
874 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
875 ok(size
.cx
== 20, "got %d\n", size
.cx
);
876 ok(size
.cy
== 5, "got %d\n", size
.cy
);
878 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
879 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
881 hr
= IDWriteBitmapRenderTarget_Resize(target
, 1, 5);
882 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
884 size
.cx
= size
.cy
= -1;
885 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
886 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
887 ok(size
.cx
== 1, "got %d\n", size
.cx
);
888 ok(size
.cy
== 5, "got %d\n", size
.cy
);
890 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
891 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
893 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
894 ok(ret
== sizeof(ds
), "got %d\n", ret
);
895 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
896 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
897 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
898 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
899 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
901 /* empty rectangle */
902 hr
= IDWriteBitmapRenderTarget_Resize(target
, 0, 5);
903 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
905 size
.cx
= size
.cy
= -1;
906 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
907 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
908 ok(size
.cx
== 0, "got %d\n", size
.cx
);
909 ok(size
.cy
== 5, "got %d\n", size
.cy
);
911 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
912 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
914 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
915 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
916 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
917 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
918 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
919 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
920 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
922 /* transform tests, current hdc transform is not immediately affected */
923 if (0) /* crashes on native */
924 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, NULL
);
926 memset(&m
, 0xcc, sizeof(m
));
927 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
928 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
929 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
);
930 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
931 ret
= GetWorldTransform(hdc
, &xform
);
932 ok(ret
, "got %d\n", ret
);
933 ok(xform
.eM11
== 1.0 && xform
.eM22
== 1.0 && xform
.eM12
== 0.0 && xform
.eM21
== 0.0, "got wrong transform\n");
934 ok(xform
.eDx
== 0.0 && xform
.eDy
== 0.0, "got %.1f,%.1f\n", xform
.eDx
, xform
.eDy
);
936 memset(&m
, 0, sizeof(m
));
937 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, &m
);
938 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
940 memset(&m
, 0xcc, sizeof(m
));
941 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
942 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
943 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
);
944 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
945 ret
= GetWorldTransform(hdc
, &xform
);
946 ok(ret
, "got %d\n", ret
);
947 ok(xform
.eM11
== 1.0 && xform
.eM22
== 1.0 && xform
.eM12
== 0.0 && xform
.eM21
== 0.0, "got wrong transform\n");
948 ok(xform
.eDx
== 0.0 && xform
.eDy
== 0.0, "got %.1f,%.1f\n", xform
.eDx
, xform
.eDy
);
950 memset(&m
, 0, sizeof(m
));
951 m
.m11
= 2.0; m
.m22
= 1.0;
952 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, &m
);
953 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
954 ret
= GetWorldTransform(hdc
, &xform
);
955 ok(ret
, "got %d\n", ret
);
956 ok(xform
.eM11
== 1.0 && xform
.eM22
== 1.0 && xform
.eM12
== 0.0 && xform
.eM21
== 0.0, "got wrong transform\n");
957 ok(xform
.eDx
== 0.0 && xform
.eDy
== 0.0, "got %.1f,%.1f\n", xform
.eDx
, xform
.eDy
);
959 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, NULL
);
960 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
962 memset(&m
, 0xcc, sizeof(m
));
963 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
964 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
965 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
);
966 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
969 pdip
= IDWriteBitmapRenderTarget_GetPixelsPerDip(target
);
970 ok(pdip
== 1.0, "got %.2f\n", pdip
);
972 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, 2.0);
973 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
975 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, -1.0);
976 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
978 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, 0.0);
979 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
981 pdip
= IDWriteBitmapRenderTarget_GetPixelsPerDip(target
);
982 ok(pdip
== 2.0, "got %.2f\n", pdip
);
984 hr
= IDWriteBitmapRenderTarget_QueryInterface(target
, &IID_IDWriteBitmapRenderTarget1
, (void**)&target1
);
986 DWRITE_TEXT_ANTIALIAS_MODE mode
;
988 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
989 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, "got %d\n", mode
);
991 hr
= IDWriteBitmapRenderTarget1_SetTextAntialiasMode(target1
, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
+1);
992 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
994 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
995 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, "got %d\n", mode
);
997 hr
= IDWriteBitmapRenderTarget1_SetTextAntialiasMode(target1
, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
);
998 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1000 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
1001 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
, "got %d\n", mode
);
1003 IDWriteBitmapRenderTarget1_Release(target1
);
1006 win_skip("IDWriteBitmapRenderTarget1 is not supported.\n");
1008 IDWriteBitmapRenderTarget_Release(target
);
1009 IDWriteGdiInterop_Release(interop
);
1010 IDWriteFactory_Release(factory
);
1013 static void test_GetFontFamily(void)
1015 IDWriteFontCollection
*collection
, *collection2
;
1016 IDWriteFontCollection
*syscoll
;
1017 IDWriteFontFamily
*family
, *family2
;
1018 IDWriteGdiInterop
*interop
;
1019 IDWriteFont
*font
, *font2
;
1020 IDWriteFactory
*factory
;
1024 factory
= create_factory();
1026 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1027 EXPECT_HR(hr
, S_OK
);
1029 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &syscoll
, FALSE
);
1030 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1032 memset(&logfont
, 0, sizeof(logfont
));
1033 logfont
.lfHeight
= 12;
1034 logfont
.lfWidth
= 12;
1035 logfont
.lfWeight
= FW_NORMAL
;
1036 logfont
.lfItalic
= 1;
1037 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1039 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1040 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1042 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
1043 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1044 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
1046 if (0) /* crashes on native */
1047 hr
= IDWriteFont_GetFontFamily(font
, NULL
);
1049 EXPECT_REF(font
, 1);
1050 hr
= IDWriteFont_GetFontFamily(font
, &family
);
1051 EXPECT_HR(hr
, S_OK
);
1052 EXPECT_REF(font
, 1);
1053 EXPECT_REF(family
, 2);
1055 hr
= IDWriteFont_GetFontFamily(font
, &family2
);
1056 EXPECT_HR(hr
, S_OK
);
1057 ok(family2
== family
, "got %p, previous %p\n", family2
, family
);
1058 EXPECT_REF(font
, 1);
1059 EXPECT_REF(family
, 3);
1060 IDWriteFontFamily_Release(family2
);
1062 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFamily
, (void**)&family2
);
1063 EXPECT_HR(hr
, E_NOINTERFACE
);
1064 ok(family2
== NULL
, "got %p\n", family2
);
1066 hr
= IDWriteFont_GetFontFamily(font2
, &family2
);
1067 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1068 ok(family2
!= family
, "got %p, %p\n", family2
, family
);
1071 hr
= IDWriteFontFamily_GetFontCollection(family
, &collection
);
1072 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1075 hr
= IDWriteFontFamily_GetFontCollection(family2
, &collection2
);
1076 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1077 ok(collection
== collection2
, "got %p, %p\n", collection
, collection2
);
1078 ok(collection
== syscoll
, "got %p, %p\n", collection
, syscoll
);
1080 IDWriteFontCollection_Release(syscoll
);
1081 IDWriteFontCollection_Release(collection2
);
1082 IDWriteFontCollection_Release(collection
);
1083 IDWriteFontFamily_Release(family2
);
1084 IDWriteFontFamily_Release(family
);
1085 IDWriteFont_Release(font
);
1086 IDWriteFont_Release(font2
);
1087 IDWriteGdiInterop_Release(interop
);
1088 IDWriteFactory_Release(factory
);
1091 static void test_GetFamilyNames(void)
1093 IDWriteFontFamily
*family
;
1094 IDWriteLocalizedStrings
*names
, *names2
;
1095 IDWriteGdiInterop
*interop
;
1096 IDWriteFactory
*factory
;
1103 factory
= create_factory();
1105 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1106 EXPECT_HR(hr
, S_OK
);
1108 memset(&logfont
, 0, sizeof(logfont
));
1109 logfont
.lfHeight
= 12;
1110 logfont
.lfWidth
= 12;
1111 logfont
.lfWeight
= FW_NORMAL
;
1112 logfont
.lfItalic
= 1;
1113 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1115 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1116 EXPECT_HR(hr
, S_OK
);
1118 hr
= IDWriteFont_GetFontFamily(font
, &family
);
1119 EXPECT_HR(hr
, S_OK
);
1121 if (0) /* crashes on native */
1122 hr
= IDWriteFontFamily_GetFamilyNames(family
, NULL
);
1124 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
1125 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1126 EXPECT_REF(names
, 1);
1128 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names2
);
1129 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1130 EXPECT_REF(names2
, 1);
1131 ok(names
!= names2
, "got %p, was %p\n", names2
, names
);
1133 IDWriteLocalizedStrings_Release(names2
);
1135 /* GetStringLength */
1136 if (0) /* crashes on native */
1137 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, NULL
);
1140 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 10, &len
);
1141 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1142 ok(len
== (UINT32
)-1, "got %u\n", len
);
1145 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, &len
);
1146 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1147 ok(len
> 0, "got %u\n", len
);
1150 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 0);
1151 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1153 hr
= IDWriteLocalizedStrings_GetString(names
, 10, NULL
, 0);
1154 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1157 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 100);
1160 hr
= IDWriteLocalizedStrings_GetString(names
, 10, buffer
, 100);
1161 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1162 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1165 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
-1);
1166 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1167 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1170 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
);
1171 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1172 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1175 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
+1);
1176 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1177 ok(buffer
[0] != 0, "got %x\n", buffer
[0]);
1179 IDWriteLocalizedStrings_Release(names
);
1181 IDWriteFontFamily_Release(family
);
1182 IDWriteFont_Release(font
);
1183 IDWriteGdiInterop_Release(interop
);
1184 IDWriteFactory_Release(factory
);
1187 static void test_CreateFontFace(void)
1189 IDWriteFontFace
*fontface
, *fontface2
;
1190 IDWriteFontCollection
*collection
;
1191 DWRITE_FONT_FILE_TYPE file_type
;
1192 DWRITE_FONT_FACE_TYPE face_type
;
1193 IDWriteGdiInterop
*interop
;
1194 IDWriteFont
*font
, *font2
;
1195 IDWriteFontFamily
*family
;
1196 IDWriteFactory
*factory
;
1197 IDWriteFontFile
*file
;
1204 factory
= create_factory();
1206 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1207 EXPECT_HR(hr
, S_OK
);
1209 memset(&logfont
, 0, sizeof(logfont
));
1210 logfont
.lfHeight
= 12;
1211 logfont
.lfWidth
= 12;
1212 logfont
.lfWeight
= FW_NORMAL
;
1213 logfont
.lfItalic
= 1;
1214 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1217 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1218 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1221 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
1222 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1223 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1225 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFace
, (void**)&fontface
);
1226 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1228 if (0) /* crashes on native */
1229 hr
= IDWriteFont_CreateFontFace(font
, NULL
);
1232 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1233 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1236 hr
= IDWriteFont_CreateFontFace(font
, &fontface2
);
1237 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1238 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1239 IDWriteFontFace_Release(fontface2
);
1242 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
1243 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1244 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1245 IDWriteFontFace_Release(fontface2
);
1247 IDWriteFont_Release(font2
);
1248 IDWriteFont_Release(font
);
1250 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFont
, (void**)&font
);
1251 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_NOTIMPL
), "got 0x%08x\n", hr
);
1253 IDWriteFontFace_Release(fontface
);
1254 IDWriteGdiInterop_Release(interop
);
1256 /* Create from system collection */
1257 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1258 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1260 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
1261 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1264 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1265 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1266 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1269 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1270 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font2
);
1271 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1272 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1275 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1276 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1279 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
1280 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1281 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1283 IDWriteFontFace_Release(fontface
);
1284 IDWriteFontFace_Release(fontface2
);
1285 IDWriteFont_Release(font2
);
1286 IDWriteFont_Release(font
);
1287 IDWriteFontFamily_Release(family
);
1288 IDWriteFontCollection_Release(collection
);
1290 /* IDWriteFactory::CreateFontFace() */
1291 path
= create_testfontfile(test_fontfile
);
1292 factory
= create_factory();
1294 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
1295 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1298 file_type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1299 face_type
= DWRITE_FONT_FACE_TYPE_CFF
;
1301 hr
= IDWriteFontFile_Analyze(file
, &supported
, &file_type
, &face_type
, &count
);
1302 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1303 ok(supported
== TRUE
, "got %i\n", supported
);
1304 ok(file_type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", file_type
);
1305 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face_type
);
1306 ok(count
== 1, "got %i\n", count
);
1308 /* try mismatching face type, the one that's not supported */
1309 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
== E_FAIL
, "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
);
1331 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1333 IDWriteFontFile_Release(file
);
1334 IDWriteFactory_Release(factory
);
1335 DELETE_FONTFILE(path
);
1338 static void test_GetMetrics(void)
1340 IDWriteGdiInterop
*interop
;
1341 DWRITE_FONT_METRICS metrics
;
1342 IDWriteFontFace
*fontface
;
1343 IDWriteFactory
*factory
;
1344 OUTLINETEXTMETRICW otm
;
1345 IDWriteFont1
*font1
;
1353 factory
= create_factory();
1355 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1356 EXPECT_HR(hr
, S_OK
);
1358 memset(&logfont
, 0, sizeof(logfont
));
1359 logfont
.lfHeight
= 12;
1360 logfont
.lfWidth
= 12;
1361 logfont
.lfWeight
= FW_NORMAL
;
1362 logfont
.lfItalic
= 1;
1363 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1365 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1366 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1368 hfont
= CreateFontIndirectW(&logfont
);
1369 hdc
= CreateCompatibleDC(0);
1370 SelectObject(hdc
, hfont
);
1372 otm
.otmSize
= sizeof(otm
);
1373 ret
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
1374 ok(ret
, "got %d\n", ret
);
1376 DeleteObject(hfont
);
1378 if (0) /* crashes on native */
1379 IDWriteFont_GetMetrics(font
, NULL
);
1381 memset(&metrics
, 0, sizeof(metrics
));
1382 IDWriteFont_GetMetrics(font
, &metrics
);
1384 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
1385 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
1386 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
1387 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
1388 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
1389 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
1390 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
1391 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
1392 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
1393 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
1395 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1396 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1398 memset(&metrics
, 0, sizeof(metrics
));
1399 IDWriteFontFace_GetMetrics(fontface
, &metrics
);
1401 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
1402 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
1403 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
1404 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
1405 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
1406 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
1407 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
1408 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
1409 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
1410 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
1412 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
1414 DWRITE_FONT_METRICS1 metrics1
;
1415 IDWriteFontFace1
*fontface1
;
1417 memset(&metrics1
, 0, sizeof(metrics1
));
1418 IDWriteFont1_GetMetrics(font1
, &metrics1
);
1420 ok(metrics1
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics1
.designUnitsPerEm
);
1421 ok(metrics1
.ascent
!= 0, "ascent %u\n", metrics1
.ascent
);
1422 ok(metrics1
.descent
!= 0, "descent %u\n", metrics1
.descent
);
1423 ok(metrics1
.lineGap
== 0, "lineGap %d\n", metrics1
.lineGap
);
1424 ok(metrics1
.capHeight
, "capHeight %u\n", metrics1
.capHeight
);
1425 ok(metrics1
.xHeight
!= 0, "xHeight %u\n", metrics1
.xHeight
);
1426 ok(metrics1
.underlinePosition
< 0, "underlinePosition %d\n", metrics1
.underlinePosition
);
1427 ok(metrics1
.underlineThickness
!= 0, "underlineThickness %u\n", metrics1
.underlineThickness
);
1428 ok(metrics1
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics1
.strikethroughPosition
);
1429 ok(metrics1
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics1
.strikethroughThickness
);
1430 ok(metrics1
.glyphBoxLeft
< 0, "glyphBoxLeft %d\n", metrics1
.glyphBoxLeft
);
1431 ok(metrics1
.glyphBoxTop
> 0, "glyphBoxTop %d\n", metrics1
.glyphBoxTop
);
1432 ok(metrics1
.glyphBoxRight
> 0, "glyphBoxRight %d\n", metrics1
.glyphBoxRight
);
1433 ok(metrics1
.glyphBoxBottom
< 0, "glyphBoxBottom %d\n", metrics1
.glyphBoxBottom
);
1434 ok(metrics1
.subscriptPositionY
< 0, "subscriptPositionY %d\n", metrics1
.subscriptPositionY
);
1435 ok(metrics1
.subscriptSizeX
> 0, "subscriptSizeX %d\n", metrics1
.subscriptSizeX
);
1436 ok(metrics1
.subscriptSizeY
> 0, "subscriptSizeY %d\n", metrics1
.subscriptSizeY
);
1437 ok(metrics1
.superscriptPositionY
> 0, "superscriptPositionY %d\n", metrics1
.superscriptPositionY
);
1438 ok(metrics1
.superscriptSizeX
> 0, "superscriptSizeX %d\n", metrics1
.superscriptSizeX
);
1439 ok(metrics1
.superscriptSizeY
> 0, "superscriptSizeY %d\n", metrics1
.superscriptSizeY
);
1440 ok(!metrics1
.hasTypographicMetrics
, "hasTypographicMetrics %d\n", metrics1
.hasTypographicMetrics
);
1442 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
1443 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1445 memset(&metrics1
, 0, sizeof(metrics1
));
1446 IDWriteFontFace1_GetMetrics(fontface1
, &metrics1
);
1448 ok(metrics1
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics1
.designUnitsPerEm
);
1449 ok(metrics1
.ascent
!= 0, "ascent %u\n", metrics1
.ascent
);
1450 ok(metrics1
.descent
!= 0, "descent %u\n", metrics1
.descent
);
1451 ok(metrics1
.lineGap
== 0, "lineGap %d\n", metrics1
.lineGap
);
1452 ok(metrics1
.capHeight
, "capHeight %u\n", metrics1
.capHeight
);
1453 ok(metrics1
.xHeight
!= 0, "xHeight %u\n", metrics1
.xHeight
);
1454 ok(metrics1
.underlinePosition
< 0, "underlinePosition %d\n", metrics1
.underlinePosition
);
1455 ok(metrics1
.underlineThickness
!= 0, "underlineThickness %u\n", metrics1
.underlineThickness
);
1456 ok(metrics1
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics1
.strikethroughPosition
);
1457 ok(metrics1
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics1
.strikethroughThickness
);
1458 ok(metrics1
.glyphBoxLeft
< 0, "glyphBoxLeft %d\n", metrics1
.glyphBoxLeft
);
1459 ok(metrics1
.glyphBoxTop
> 0, "glyphBoxTop %d\n", metrics1
.glyphBoxTop
);
1460 ok(metrics1
.glyphBoxRight
> 0, "glyphBoxRight %d\n", metrics1
.glyphBoxRight
);
1461 ok(metrics1
.glyphBoxBottom
< 0, "glyphBoxBottom %d\n", metrics1
.glyphBoxBottom
);
1462 ok(metrics1
.subscriptPositionY
< 0, "subscriptPositionY %d\n", metrics1
.subscriptPositionY
);
1463 ok(metrics1
.subscriptSizeX
> 0, "subscriptSizeX %d\n", metrics1
.subscriptSizeX
);
1464 ok(metrics1
.subscriptSizeY
> 0, "subscriptSizeY %d\n", metrics1
.subscriptSizeY
);
1465 ok(metrics1
.superscriptPositionY
> 0, "superscriptPositionY %d\n", metrics1
.superscriptPositionY
);
1466 ok(metrics1
.superscriptSizeX
> 0, "superscriptSizeX %d\n", metrics1
.superscriptSizeX
);
1467 ok(metrics1
.superscriptSizeY
> 0, "superscriptSizeY %d\n", metrics1
.superscriptSizeY
);
1468 ok(!metrics1
.hasTypographicMetrics
, "hasTypographicMetrics %d\n", metrics1
.hasTypographicMetrics
);
1470 IDWriteFontFace1_Release(fontface1
);
1471 IDWriteFont1_Release(font1
);
1474 win_skip("DWRITE_FONT_METRICS1 is not supported.\n");
1476 IDWriteFontFace_Release(fontface
);
1478 IDWriteFont_Release(font
);
1479 IDWriteGdiInterop_Release(interop
);
1480 IDWriteFactory_Release(factory
);
1483 static void test_system_fontcollection(void)
1485 IDWriteFontCollection
*collection
, *coll2
;
1486 IDWriteLocalFontFileLoader
*localloader
;
1487 IDWriteFactory
*factory
, *factory2
;
1488 IDWriteFontFileLoader
*loader
;
1489 IDWriteFontFamily
*family
;
1490 IDWriteFontFace
*fontface
;
1491 IDWriteFontFile
*file
;
1497 factory
= create_factory();
1499 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1500 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1502 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, FALSE
);
1503 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1504 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
1505 IDWriteFontCollection_Release(coll2
);
1507 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, TRUE
);
1508 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1509 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
1510 IDWriteFontCollection_Release(coll2
);
1512 factory2
= create_factory();
1513 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &coll2
, FALSE
);
1514 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1515 ok(coll2
!= collection
, "got %p, was %p\n", coll2
, collection
);
1516 IDWriteFontCollection_Release(coll2
);
1517 IDWriteFactory_Release(factory2
);
1519 i
= IDWriteFontCollection_GetFontFamilyCount(collection
);
1520 ok(i
, "got %u\n", i
);
1523 family
= (void*)0xdeadbeef;
1524 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
1525 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1526 ok(family
== NULL
, "got %p\n", family
);
1530 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaW
, &i
, &ret
);
1531 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1532 ok(ret
, "got %d\n", ret
);
1533 ok(i
!= (UINT32
)-1, "got %u\n", i
);
1537 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaUppercaseW
, &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
, tahomaStrangecaseW
, &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
);
1549 /* get back local file loader */
1550 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
1551 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1553 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1554 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1555 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1556 IDWriteFontFamily_Release(family
);
1558 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1559 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1560 IDWriteFont_Release(font
);
1564 hr
= IDWriteFontFace_GetFiles(fontface
, &i
, &file
);
1565 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1566 ok(file
!= NULL
, "got %p\n", file
);
1568 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
1569 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1570 IDWriteFontFile_Release(file
);
1572 hr
= IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
1573 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1574 IDWriteLocalFontFileLoader_Release(localloader
);
1576 /* local loader is not registered by default */
1577 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, loader
);
1578 ok(hr
== S_OK
|| broken(hr
== DWRITE_E_ALREADYREGISTERED
), "got 0x%08x\n", hr
);
1579 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, loader
);
1580 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "got 0x%08x\n", hr
);
1582 /* try with a different factory */
1583 factory2
= create_factory();
1584 hr
= IDWriteFactory_RegisterFontFileLoader(factory2
, loader
);
1585 ok(hr
== S_OK
|| broken(hr
== DWRITE_E_ALREADYREGISTERED
), "got 0x%08x\n", hr
);
1586 hr
= IDWriteFactory_RegisterFontFileLoader(factory2
, loader
);
1587 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1588 hr
= IDWriteFactory_UnregisterFontFileLoader(factory2
, loader
);
1589 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "got 0x%08x\n", hr
);
1590 hr
= IDWriteFactory_UnregisterFontFileLoader(factory2
, loader
);
1591 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1592 IDWriteFactory_Release(factory2
);
1594 IDWriteFontFileLoader_Release(loader
);
1598 hr
= IDWriteFontCollection_FindFamilyName(collection
, blahW
, &i
, &ret
);
1599 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1600 ok(!ret
, "got %d\n", ret
);
1601 ok(i
== (UINT32
)-1, "got %u\n", i
);
1603 IDWriteFontCollection_Release(collection
);
1604 IDWriteFactory_Release(factory
);
1607 static void test_ConvertFontFaceToLOGFONT(void)
1609 DWRITE_FONT_SIMULATIONS sim
;
1610 IDWriteGdiInterop
*interop
;
1611 IDWriteFontFace
*fontface
;
1612 IDWriteFactory
*factory
;
1617 factory
= create_factory();
1619 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1620 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1622 memset(&logfont
, 0, sizeof(logfont
));
1623 logfont
.lfHeight
= 12;
1624 logfont
.lfWidth
= 12;
1625 logfont
.lfEscapement
= 100;
1626 logfont
.lfWeight
= FW_NORMAL
;
1627 logfont
.lfItalic
= 1;
1628 logfont
.lfUnderline
= 1;
1629 logfont
.lfStrikeOut
= 1;
1631 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1633 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1634 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1636 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1637 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1639 sim
= IDWriteFont_GetSimulations(font
);
1640 ok(sim
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "sim %d\n", sim
);
1642 sim
= IDWriteFontFace_GetSimulations(fontface
);
1643 ok(sim
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "sim %d\n", sim
);
1645 IDWriteFont_Release(font
);
1647 if (0) /* crashes on native */
1649 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, NULL
, NULL
);
1650 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, NULL
);
1653 memset(&logfont
, 0xa, sizeof(logfont
));
1654 logfont
.lfFaceName
[0] = 0;
1656 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, &logfont
);
1657 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1658 ok(logfont
.lfHeight
== 0, "got %d\n", logfont
.lfHeight
);
1659 ok(logfont
.lfWidth
== 0, "got %d\n", logfont
.lfWidth
);
1660 ok(logfont
.lfWeight
== FW_NORMAL
, "got %d\n", logfont
.lfWeight
);
1661 ok(logfont
.lfEscapement
== 0, "got %d\n", logfont
.lfEscapement
);
1662 ok(logfont
.lfItalic
== 1, "got %d\n", logfont
.lfItalic
);
1663 ok(logfont
.lfUnderline
== 0, "got %d\n", logfont
.lfUnderline
);
1664 ok(logfont
.lfStrikeOut
== 0, "got %d\n", logfont
.lfStrikeOut
);
1665 ok(!lstrcmpW(logfont
.lfFaceName
, tahomaW
), "got %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
1667 IDWriteGdiInterop_Release(interop
);
1668 IDWriteFontFace_Release(fontface
);
1669 IDWriteFactory_Release(factory
);
1672 static HRESULT WINAPI
fontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
1674 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
))
1677 IDWriteFontFileEnumerator_AddRef(iface
);
1680 return E_NOINTERFACE
;
1683 static ULONG WINAPI
fontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
1688 static ULONG WINAPI
fontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
1693 static HRESULT WINAPI
fontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**file
)
1699 static HRESULT WINAPI
fontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
1705 static const struct IDWriteFontFileEnumeratorVtbl dwritefontfileenumeratorvtbl
=
1707 fontfileenumerator_QueryInterface
,
1708 fontfileenumerator_AddRef
,
1709 fontfileenumerator_Release
,
1710 fontfileenumerator_MoveNext
,
1711 fontfileenumerator_GetCurrentFontFile
,
1714 static HRESULT WINAPI
fontcollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
1720 static ULONG WINAPI
fontcollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
1725 static ULONG WINAPI
fontcollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
1730 static HRESULT WINAPI
fontcollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
*factory
, const void *key
,
1731 UINT32 key_size
, IDWriteFontFileEnumerator
**ret
)
1733 static IDWriteFontFileEnumerator enumerator
= { &dwritefontfileenumeratorvtbl
};
1738 static const struct IDWriteFontCollectionLoaderVtbl dwritefontcollectionloadervtbl
= {
1739 fontcollectionloader_QueryInterface
,
1740 fontcollectionloader_AddRef
,
1741 fontcollectionloader_Release
,
1742 fontcollectionloader_CreateEnumeratorFromKey
1745 static void test_CustomFontCollection(void)
1747 static const WCHAR fontnameW
[] = {'w','i','n','e','_','t','e','s','t',0};
1748 IDWriteFontCollectionLoader collection
= { &dwritefontcollectionloadervtbl
};
1749 IDWriteFontCollectionLoader collection2
= { &dwritefontcollectionloadervtbl
};
1750 IDWriteFontCollectionLoader collection3
= { &dwritefontcollectionloadervtbl
};
1751 IDWriteFontCollection
*font_collection
= NULL
;
1752 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
1753 struct test_fontcollectionloader resource_collection
= { { &resourcecollectionloadervtbl
}, &rloader
};
1754 IDWriteFontFamily
*family
, *family2
, *family3
;
1755 IDWriteFontFace
*idfontface
, *idfontface2
;
1756 IDWriteFontFile
*fontfile
, *fontfile2
;
1757 IDWriteLocalizedStrings
*string
;
1758 IDWriteFont
*idfont
, *idfont2
;
1759 IDWriteFactory
*factory
;
1760 UINT32 index
, count
;
1765 factory
= create_factory();
1767 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, NULL
);
1768 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1770 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, NULL
);
1771 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1773 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
1774 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1775 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection2
);
1776 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1777 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
1778 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1780 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1781 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1782 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
);
1783 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1785 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection3
, "Billy", 6, &font_collection
);
1786 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1788 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection
, "Billy", 6, &font_collection
);
1789 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1790 IDWriteFontCollection_Release(font_collection
);
1792 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection2
, "Billy", 6, &font_collection
);
1793 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1794 IDWriteFontCollection_Release(font_collection
);
1796 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, (IDWriteFontCollectionLoader
*)0xdeadbeef, "Billy", 6, &font_collection
);
1797 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1799 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1800 ok(font
!= NULL
, "Failed to find font resource\n");
1802 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
,
1803 &font
, sizeof(HRSRC
), &font_collection
);
1804 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1808 hr
= IDWriteFontCollection_FindFamilyName(font_collection
, fontnameW
, &index
, &exists
);
1809 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1810 ok(index
== 0, "got index %i\n", index
);
1811 ok(exists
, "got exists %i\n", exists
);
1813 count
= IDWriteFontCollection_GetFontFamilyCount(font_collection
);
1814 ok(count
== 1, "got %u\n", count
);
1817 hr
= IDWriteFontCollection_GetFontFamily(font_collection
, 0, &family
);
1818 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1819 EXPECT_REF(family
, 1);
1822 hr
= IDWriteFontCollection_GetFontFamily(font_collection
, 0, &family2
);
1823 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1824 EXPECT_REF(family2
, 1);
1825 ok(family
!= family2
, "got %p, %p\n", family
, family2
);
1827 hr
= IDWriteFontFamily_GetFont(family
, 0, &idfont
);
1828 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1829 EXPECT_REF(idfont
, 1);
1830 EXPECT_REF(family
, 2);
1831 hr
= IDWriteFontFamily_GetFont(family
, 0, &idfont2
);
1832 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1833 EXPECT_REF(idfont2
, 1);
1834 EXPECT_REF(family
, 3);
1835 ok(idfont
!= idfont2
, "got %p, %p\n", idfont
, idfont2
);
1836 IDWriteFont_Release(idfont2
);
1838 hr
= IDWriteFont_GetInformationalStrings(idfont
, DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE
, &string
, &exists
);
1839 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1840 ok(exists
, "got %d\n", exists
);
1841 EXPECT_REF(string
, 1);
1844 hr
= IDWriteFont_GetFontFamily(idfont
, &family3
);
1845 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1846 EXPECT_REF(family
, 3);
1847 ok(family
== family3
, "got %p, %p\n", family
, family3
);
1848 IDWriteFontFamily_Release(family3
);
1851 hr
= IDWriteFont_CreateFontFace(idfont
, &idfontface
);
1852 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1853 EXPECT_REF(idfont
, 1);
1856 hr
= IDWriteFontFamily_GetFont(family2
, 0, &idfont2
);
1857 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1858 EXPECT_REF(idfont2
, 1);
1859 EXPECT_REF(idfont
, 1);
1860 ok(idfont2
!= idfont
, "Font instances should not match\n");
1863 hr
= IDWriteFont_CreateFontFace(idfont2
, &idfontface2
);
1864 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1865 ok(idfontface2
== idfontface
, "fontfaces should match\n");
1869 hr
= IDWriteFontFace_GetFiles(idfontface
, &index
, &fontfile
);
1870 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1874 hr
= IDWriteFontFace_GetFiles(idfontface2
, &index
, &fontfile2
);
1875 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1876 ok(fontfile
== fontfile2
, "fontfiles should match\n");
1878 IDWriteFont_Release(idfont
);
1879 IDWriteFont_Release(idfont2
);
1880 IDWriteFontFile_Release(fontfile
);
1881 IDWriteFontFile_Release(fontfile2
);
1882 IDWriteFontFace_Release(idfontface
);
1883 IDWriteFontFace_Release(idfontface2
);
1884 IDWriteFontFamily_Release(family2
);
1885 IDWriteFontFamily_Release(family
);
1886 IDWriteFontCollection_Release(font_collection
);
1888 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
1889 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1890 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
1891 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1892 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection2
);
1893 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1894 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
);
1895 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1896 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
1897 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1899 IDWriteFactory_Release(factory
);
1902 static HRESULT WINAPI
fontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
1904 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
1907 IDWriteFontFileLoader_AddRef(iface
);
1912 return E_NOINTERFACE
;
1915 static ULONG WINAPI
fontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
1920 static ULONG WINAPI
fontfileloader_Release(IDWriteFontFileLoader
*iface
)
1925 static HRESULT WINAPI
fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
1930 static const struct IDWriteFontFileLoaderVtbl dwritefontfileloadervtbl
= {
1931 fontfileloader_QueryInterface
,
1932 fontfileloader_AddRef
,
1933 fontfileloader_Release
,
1934 fontfileloader_CreateStreamFromKey
1937 static void test_CreateCustomFontFileReference(void)
1939 IDWriteFontFileLoader floader
= { &dwritefontfileloadervtbl
};
1940 IDWriteFontFileLoader floader2
= { &dwritefontfileloadervtbl
};
1941 IDWriteFontFileLoader floader3
= { &dwritefontfileloadervtbl
};
1942 IDWriteFactory
*factory
, *factory2
;
1943 IDWriteFontFile
*file
, *file2
;
1945 DWRITE_FONT_FILE_TYPE file_type
;
1946 DWRITE_FONT_FACE_TYPE face_type
;
1948 IDWriteFontFace
*face
, *face2
;
1951 UINT32 codePoints
[1] = {0xa8};
1954 factory
= create_factory();
1955 factory2
= create_factory();
1957 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, NULL
);
1958 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1959 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
1960 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1961 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader2
);
1962 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1963 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
1964 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1965 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1966 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1969 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &file
);
1970 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1971 IDWriteFontFile_Release(file
);
1973 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader3
, &file
);
1974 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1976 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, NULL
, &file
);
1977 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1980 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &file
);
1981 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1983 file_type
= DWRITE_FONT_FILE_TYPE_TRUETYPE
;
1984 face_type
= DWRITE_FONT_FACE_TYPE_TRUETYPE
;
1987 hr
= IDWriteFontFile_Analyze(file
, &support
, &file_type
, &face_type
, &count
);
1988 ok(hr
== 0x8faecafe, "got 0x%08x\n", hr
);
1989 ok(support
== FALSE
, "got %i\n", support
);
1990 ok(file_type
== DWRITE_FONT_FILE_TYPE_UNKNOWN
, "got %i\n", file_type
);
1991 ok(face_type
== DWRITE_FONT_FACE_TYPE_UNKNOWN
, "got %i\n", face_type
);
1992 ok(count
== 0, "got %i\n", count
);
1994 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &file
, 0, 0, &face
);
1995 ok(hr
== 0x8faecafe, "got 0x%08x\n", hr
);
1996 IDWriteFontFile_Release(file
);
1998 fontrsrc
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1999 ok(fontrsrc
!= NULL
, "Failed to find font resource\n");
2001 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &fontrsrc
, sizeof(HRSRC
), &rloader
, &file
);
2002 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2004 file_type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
2005 face_type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
2008 hr
= IDWriteFontFile_Analyze(file
, &support
, &file_type
, &face_type
, &count
);
2009 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2010 ok(support
== TRUE
, "got %i\n", support
);
2011 ok(file_type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", file_type
);
2012 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face_type
);
2013 ok(count
== 1, "got %i\n", count
);
2016 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 1, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
2017 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2019 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
2020 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2022 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2023 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2024 /* fontface instances are reused starting with win7 */
2025 ok(face
== face2
|| broken(face
!= face2
), "got %p, %p\n", face
, face2
);
2026 IDWriteFontFace_Release(face2
);
2028 /* file was created with different factory */
2030 hr
= IDWriteFactory_CreateFontFace(factory2
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2032 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2034 IDWriteFontFace_Release(face2
);
2037 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &fontrsrc
, sizeof(HRSRC
), &rloader
, &file2
);
2038 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2039 ok(file
!= file2
, "got %p, %p\n", file
, file2
);
2041 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file2
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2042 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2043 /* fontface instances are reused starting with win7 */
2044 ok(face
== face2
|| broken(face
!= face2
), "got %p, %p\n", face
, face2
);
2045 IDWriteFontFace_Release(face2
);
2046 IDWriteFontFile_Release(file2
);
2048 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 0, NULL
);
2049 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2051 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 0, NULL
);
2052 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2054 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 0, indices
);
2055 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2057 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 0, indices
);
2058 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2060 indices
[0] = indices
[1] = 11;
2061 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 1, indices
);
2062 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2063 ok(indices
[0] == 0, "got index %i\n", indices
[0]);
2064 ok(indices
[1] == 11, "got index %i\n", indices
[1]);
2066 if (0) /* crashes on native */
2067 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 1, NULL
);
2069 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 1, indices
);
2070 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2071 ok(indices
[0] == 6, "got index %i\n", indices
[0]);
2072 IDWriteFontFace_Release(face
);
2073 IDWriteFontFile_Release(file
);
2075 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
2076 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2077 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
2078 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2079 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader2
);
2080 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2081 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
2082 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2084 IDWriteFactory_Release(factory2
);
2085 IDWriteFactory_Release(factory
);
2088 static void test_CreateFontFileReference(void)
2091 IDWriteFontFile
*ffile
= NULL
;
2093 DWRITE_FONT_FILE_TYPE type
;
2094 DWRITE_FONT_FACE_TYPE face
;
2096 IDWriteFontFace
*fface
= NULL
;
2097 IDWriteFactory
*factory
;
2100 path
= create_testfontfile(test_fontfile
);
2101 factory
= create_factory();
2103 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &ffile
);
2104 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2107 type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
2108 face
= DWRITE_FONT_FACE_TYPE_CFF
;
2110 hr
= IDWriteFontFile_Analyze(ffile
, &support
, &type
, &face
, &count
);
2111 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2112 ok(support
== TRUE
, "got %i\n", support
);
2113 ok(type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", type
);
2114 ok(face
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face
);
2115 ok(count
== 1, "got %i\n", count
);
2117 hr
= IDWriteFactory_CreateFontFace(factory
, face
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fface
);
2118 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2120 IDWriteFontFace_Release(fface
);
2121 IDWriteFontFile_Release(ffile
);
2122 IDWriteFactory_Release(factory
);
2124 DELETE_FONTFILE(path
);
2127 static void test_shared_isolated(void)
2129 IDWriteFactory
*isolated
, *isolated2
;
2130 IDWriteFactory
*shared
, *shared2
;
2135 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
2136 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2137 ok(shared
!= NULL
, "got %p\n", shared
);
2138 IDWriteFactory_Release(shared
);
2140 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
2141 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2143 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
2144 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2145 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
2147 IDWriteFactory_Release(shared
);
2148 IDWriteFactory_Release(shared2
);
2150 /* we got 2 references, released 2 - still same pointer is returned */
2151 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
2152 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2153 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
2154 IDWriteFactory_Release(shared2
);
2156 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated
);
2157 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2159 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
2160 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2161 ok(isolated
!= isolated2
, "got %p, and %p\n", isolated
, isolated2
);
2162 IDWriteFactory_Release(isolated2
);
2164 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
2165 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2166 ok(shared
!= isolated2
, "got %p, and %p\n", shared
, isolated2
);
2168 IDWriteFactory_Release(isolated
);
2169 IDWriteFactory_Release(isolated2
);
2172 static void test_GetUnicodeRanges(void)
2174 DWRITE_UNICODE_RANGE
*ranges
, r
;
2175 IDWriteFontFile
*ffile
= NULL
;
2176 IDWriteFontFace1
*fontface1
;
2177 IDWriteFontFace
*fontface
;
2178 IDWriteFactory
*factory
;
2183 factory
= create_factory();
2185 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
2186 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2188 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
2189 ok(font
!= NULL
, "Failed to find font resource\n");
2191 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &font
, sizeof(HRSRC
), &rloader
, &ffile
);
2192 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2194 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
2195 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2196 IDWriteFontFile_Release(ffile
);
2198 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
2199 IDWriteFontFace_Release(fontface
);
2201 win_skip("GetUnicodeRanges() is not supported.\n");
2202 IDWriteFactory_Release(factory
);
2207 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 0, NULL
, &count
);
2208 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
2209 ok(count
> 0, "got %u\n", count
);
2212 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, NULL
, &count
);
2213 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2214 ok(count
== 0, "got %u\n", count
);
2217 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, &r
, &count
);
2218 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
2219 ok(count
> 1, "got %u\n", count
);
2221 ranges
= heap_alloc(count
*sizeof(DWRITE_UNICODE_RANGE
));
2222 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, count
, ranges
, &count
);
2223 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2225 ranges
[0].first
= ranges
[0].last
= 0;
2226 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, ranges
, &count
);
2227 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
2228 ok(ranges
[0].first
!= 0 && ranges
[0].last
!= 0, "got 0x%x-0x%0x\n", ranges
[0].first
, ranges
[0].last
);
2232 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
2233 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2235 IDWriteFontFace1_Release(fontface1
);
2236 IDWriteFactory_Release(factory
);
2239 static void test_GetFontFromFontFace(void)
2241 IDWriteFontFace
*fontface
, *fontface2
;
2242 IDWriteFontCollection
*collection
;
2243 IDWriteFont
*font
, *font2
, *font3
;
2244 IDWriteFontFamily
*family
;
2245 IDWriteFactory
*factory
;
2246 IDWriteFontFile
*file
;
2250 factory
= create_factory();
2252 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2253 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2255 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2256 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2258 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2259 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2260 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2262 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2263 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2266 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font2
);
2267 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2268 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
2271 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font3
);
2272 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2273 ok(font3
!= font
&& font3
!= font2
, "got %p, %p, %p\n", font3
, font2
, font
);
2275 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
2276 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2277 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
2278 IDWriteFontFace_Release(fontface2
);
2280 hr
= IDWriteFont_CreateFontFace(font3
, &fontface2
);
2281 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2282 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
2283 IDWriteFontFace_Release(fontface2
);
2284 IDWriteFontFace_Release(fontface
);
2285 IDWriteFont_Release(font3
);
2286 IDWriteFactory_Release(factory
);
2288 /* fontface that wasn't created from this collection */
2289 factory
= create_factory();
2290 path
= create_testfontfile(test_fontfile
);
2292 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2293 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2295 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
2296 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2297 IDWriteFontFile_Release(file
);
2299 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font3
);
2300 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
2301 ok(font3
== NULL
, "got %p\n", font3
);
2302 IDWriteFontFace_Release(fontface
);
2304 IDWriteFont_Release(font
);
2305 IDWriteFont_Release(font2
);
2306 IDWriteFontFamily_Release(family
);
2307 IDWriteFontCollection_Release(collection
);
2308 IDWriteFactory_Release(factory
);
2309 DELETE_FONTFILE(path
);
2312 static IDWriteFont
*get_font(IDWriteFactory
*factory
, const WCHAR
*name
, DWRITE_FONT_STYLE style
)
2314 IDWriteFontCollection
*collection
;
2315 IDWriteFontFamily
*family
;
2316 IDWriteFont
*font
= NULL
;
2321 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2322 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2326 hr
= IDWriteFontCollection_FindFamilyName(collection
, name
, &index
, &exists
);
2327 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2328 if (!exists
) goto not_found
;
2330 hr
= IDWriteFontCollection_GetFontFamily(collection
, index
, &family
);
2331 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2333 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2334 DWRITE_FONT_STRETCH_NORMAL
, style
, &font
);
2335 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2337 IDWriteFontFamily_Release(family
);
2339 IDWriteFontCollection_Release(collection
);
2343 static IDWriteFont
*get_tahoma_instance(IDWriteFactory
*factory
, DWRITE_FONT_STYLE style
)
2345 IDWriteFont
*font
= get_font(factory
, tahomaW
, style
);
2346 ok(font
!= NULL
, "failed to get Tahoma\n");
2350 static void test_GetFirstMatchingFont(void)
2352 DWRITE_FONT_SIMULATIONS simulations
;
2353 IDWriteFont
*font
, *font2
;
2354 IDWriteFactory
*factory
;
2356 factory
= create_factory();
2358 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
2359 font2
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
2360 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
2361 IDWriteFont_Release(font
);
2362 IDWriteFont_Release(font2
);
2364 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_ITALIC
);
2365 simulations
= IDWriteFont_GetSimulations(font
);
2366 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "%d\n", simulations
);
2367 IDWriteFont_Release(font
);
2369 IDWriteFactory_Release(factory
);
2372 static void test_GetInformationalStrings(void)
2374 IDWriteLocalizedStrings
*strings
, *strings2
;
2375 IDWriteFontCollection
*collection
;
2376 IDWriteFontFamily
*family
;
2377 IDWriteFactory
*factory
;
2382 factory
= create_factory();
2384 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2385 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2387 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2388 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2390 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2391 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2392 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2395 strings
= (void*)0xdeadbeef;
2396 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
+1, &strings
, &exists
);
2397 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2398 ok(exists
== FALSE
, "got %d\n", exists
);
2399 ok(strings
== NULL
, "got %p\n", strings
);
2403 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_NONE
, &strings
, &exists
);
2404 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2405 ok(exists
== FALSE
, "got %d\n", exists
);
2409 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings
, &exists
);
2410 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2411 ok(exists
== TRUE
, "got %d\n", exists
);
2413 /* strings instance is not reused */
2415 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings2
, &exists
);
2416 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2417 ok(strings2
!= strings
, "got %p, %p\n", strings2
, strings
);
2419 IDWriteLocalizedStrings_Release(strings
);
2420 IDWriteLocalizedStrings_Release(strings2
);
2421 IDWriteFont_Release(font
);
2422 IDWriteFontFamily_Release(family
);
2423 IDWriteFontCollection_Release(collection
);
2424 IDWriteFactory_Release(factory
);
2427 static void test_GetGdiInterop(void)
2429 IDWriteGdiInterop
*interop
, *interop2
;
2430 IDWriteFactory
*factory
, *factory2
;
2435 factory
= create_factory();
2438 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2439 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2442 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop2
);
2443 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2444 ok(interop
== interop2
, "got %p, %p\n", interop
, interop2
);
2445 IDWriteGdiInterop_Release(interop2
);
2447 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory2
);
2448 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2450 /* each factory gets its own interop */
2452 hr
= IDWriteFactory_GetGdiInterop(factory2
, &interop2
);
2453 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2454 ok(interop
!= interop2
, "got %p, %p\n", interop
, interop2
);
2456 /* release factory - interop still works */
2457 IDWriteFactory_Release(factory2
);
2459 memset(&logfont
, 0, sizeof(logfont
));
2460 logfont
.lfHeight
= 12;
2461 logfont
.lfWidth
= 12;
2462 logfont
.lfWeight
= FW_NORMAL
;
2463 logfont
.lfItalic
= 1;
2464 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2466 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop2
, &logfont
, &font
);
2467 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2468 IDWriteFont_Release(font
);
2470 IDWriteGdiInterop_Release(interop2
);
2471 IDWriteGdiInterop_Release(interop
);
2472 IDWriteFactory_Release(factory
);
2475 static void test_CreateFontFaceFromHdc(void)
2477 IDWriteGdiInterop
*interop
;
2478 IDWriteFontFace
*fontface
;
2479 IDWriteFactory
*factory
;
2480 HFONT hfont
, oldhfont
;
2485 factory
= create_factory();
2488 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2489 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2491 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, NULL
, &fontface
);
2492 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2494 memset(&logfont
, 0, sizeof(logfont
));
2495 logfont
.lfHeight
= 12;
2496 logfont
.lfWidth
= 12;
2497 logfont
.lfWeight
= FW_NORMAL
;
2498 logfont
.lfItalic
= 1;
2499 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2501 hfont
= CreateFontIndirectW(&logfont
);
2502 hdc
= CreateCompatibleDC(0);
2503 oldhfont
= SelectObject(hdc
, hfont
);
2506 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, hdc
, &fontface
);
2507 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2508 IDWriteFontFace_Release(fontface
);
2509 DeleteObject(SelectObject(hdc
, oldhfont
));
2512 IDWriteGdiInterop_Release(interop
);
2513 IDWriteFactory_Release(factory
);
2516 static void test_GetSimulations(void)
2518 DWRITE_FONT_SIMULATIONS simulations
;
2519 IDWriteGdiInterop
*interop
;
2520 IDWriteFontFace
*fontface
;
2521 IDWriteFactory
*factory
;
2526 factory
= create_factory();
2528 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2529 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2531 memset(&logfont
, 0, sizeof(logfont
));
2532 logfont
.lfHeight
= 12;
2533 logfont
.lfWidth
= 12;
2534 logfont
.lfWeight
= FW_NORMAL
;
2535 logfont
.lfItalic
= 1;
2536 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2538 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2539 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2541 simulations
= IDWriteFont_GetSimulations(font
);
2542 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "got %d\n", simulations
);
2543 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2544 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2545 simulations
= IDWriteFontFace_GetSimulations(fontface
);
2546 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "got %d\n", simulations
);
2547 IDWriteFontFace_Release(fontface
);
2548 IDWriteFont_Release(font
);
2550 memset(&logfont
, 0, sizeof(logfont
));
2551 logfont
.lfHeight
= 12;
2552 logfont
.lfWidth
= 12;
2553 logfont
.lfWeight
= FW_NORMAL
;
2554 logfont
.lfItalic
= 0;
2555 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2557 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2558 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2560 simulations
= IDWriteFont_GetSimulations(font
);
2561 ok(simulations
== DWRITE_FONT_SIMULATIONS_NONE
, "got %d\n", simulations
);
2562 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2563 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2564 simulations
= IDWriteFontFace_GetSimulations(fontface
);
2565 ok(simulations
== DWRITE_FONT_SIMULATIONS_NONE
, "got %d\n", simulations
);
2566 IDWriteFontFace_Release(fontface
);
2567 IDWriteFont_Release(font
);
2569 IDWriteGdiInterop_Release(interop
);
2570 IDWriteFactory_Release(factory
);
2573 static void test_GetFaceNames(void)
2575 static const WCHAR obliqueW
[] = {'O','b','l','i','q','u','e',0};
2576 static const WCHAR enus2W
[] = {'e','n','-','U','s',0};
2577 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
2578 IDWriteLocalizedStrings
*strings
, *strings2
;
2579 IDWriteGdiInterop
*interop
;
2580 IDWriteFactory
*factory
;
2581 UINT32 count
, index
;
2588 factory
= create_factory();
2590 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2591 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2593 memset(&logfont
, 0, sizeof(logfont
));
2594 logfont
.lfHeight
= 12;
2595 logfont
.lfWidth
= 12;
2596 logfont
.lfWeight
= FW_NORMAL
;
2597 logfont
.lfItalic
= 1;
2598 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2600 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2601 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2603 hr
= IDWriteFont_GetFaceNames(font
, &strings
);
2604 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2606 hr
= IDWriteFont_GetFaceNames(font
, &strings2
);
2607 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2608 ok(strings
!= strings2
, "got %p, %p\n", strings2
, strings
);
2609 IDWriteLocalizedStrings_Release(strings2
);
2611 count
= IDWriteLocalizedStrings_GetCount(strings
);
2612 ok(count
== 1, "got %d\n", count
);
2616 hr
= IDWriteLocalizedStrings_FindLocaleName(strings
, enus2W
, &index
, &exists
);
2617 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2618 ok(index
== 0 && exists
, "got %d, %d\n", index
, exists
);
2621 hr
= IDWriteLocalizedStrings_GetLocaleNameLength(strings
, 1, &count
);
2622 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2623 ok(count
== ~0, "got %d\n", count
);
2625 /* for simulated faces names are also simulated */
2627 hr
= IDWriteLocalizedStrings_GetLocaleName(strings
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2628 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2629 ok(!lstrcmpW(buffW
, enusW
), "got %s\n", wine_dbgstr_w(buffW
));
2632 hr
= IDWriteLocalizedStrings_GetString(strings
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2633 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2634 ok(!lstrcmpW(buffW
, obliqueW
), "got %s\n", wine_dbgstr_w(buffW
));
2635 IDWriteLocalizedStrings_Release(strings
);
2637 IDWriteFont_Release(font
);
2638 IDWriteGdiInterop_Release(interop
);
2639 IDWriteFactory_Release(factory
);
2648 static void test_TryGetFontTable(void)
2650 IDWriteLocalFontFileLoader
*localloader
;
2651 WIN32_FILE_ATTRIBUTE_DATA info
;
2652 const struct local_refkey
*key
;
2653 IDWriteFontFileLoader
*loader
;
2654 const void *table
, *table2
;
2655 IDWriteFontFace
*fontface
;
2656 void *context
, *context2
;
2657 IDWriteFactory
*factory
;
2658 IDWriteFontFile
*file
;
2659 WCHAR buffW
[MAX_PATH
];
2665 path
= create_testfontfile(test_fontfile
);
2667 factory
= create_factory();
2669 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2670 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2674 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2675 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2676 ok(size
!= 0, "got %u\n", size
);
2678 ret
= GetFileAttributesExW(path
, GetFileExInfoStandard
, &info
);
2679 ok(ret
, "got %d\n", ret
);
2680 ok(!memcmp(&info
.ftLastWriteTime
, &key
->writetime
, sizeof(key
->writetime
)), "got wrong write time\n");
2682 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2683 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2684 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2685 IDWriteFontFileLoader_Release(loader
);
2687 hr
= IDWriteLocalFontFileLoader_GetFilePathLengthFromKey(localloader
, key
, size
, &len
);
2688 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2689 ok(lstrlenW(key
->name
) == len
, "path length %d\n", len
);
2691 hr
= IDWriteLocalFontFileLoader_GetFilePathFromKey(localloader
, key
, size
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2692 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2693 ok(!lstrcmpW(buffW
, key
->name
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(key
->name
));
2694 IDWriteLocalFontFileLoader_Release(localloader
);
2696 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, 0, &fontface
);
2697 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2700 context
= (void*)0xdeadbeef;
2702 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_CMAP_TAG
, &table
, &size
, &context
, &exists
);
2703 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2704 ok(exists
== TRUE
, "got %d\n", exists
);
2705 ok(context
== NULL
&& table
!= NULL
, "cmap: context %p, table %p\n", context
, table
);
2708 context2
= (void*)0xdeadbeef;
2710 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_CMAP_TAG
, &table2
, &size
, &context2
, &exists
);
2711 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2712 ok(exists
== TRUE
, "got %d\n", exists
);
2713 ok(context2
== context
&& table2
== table
, "cmap: context2 %p, table2 %p\n", context2
, table2
);
2715 IDWriteFontFace_ReleaseFontTable(fontface
, context2
);
2716 IDWriteFontFace_ReleaseFontTable(fontface
, context
);
2718 IDWriteFontFace_Release(fontface
);
2719 IDWriteFontFile_Release(file
);
2720 IDWriteFactory_Release(factory
);
2721 DELETE_FONTFILE(path
);
2724 static void test_ConvertFontToLOGFONT(void)
2726 IDWriteFactory
*factory
, *factory2
;
2727 IDWriteFontCollection
*collection
;
2728 IDWriteGdiInterop
*interop
;
2729 IDWriteFontFamily
*family
;
2735 factory
= create_factory();
2736 factory2
= create_factory();
2739 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2740 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2742 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &collection
, FALSE
);
2743 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2745 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2746 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2748 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2749 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2750 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2752 if (0) { /* crashes on native */
2753 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, NULL
, NULL
);
2754 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, &logfont
, NULL
);
2755 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, font
, NULL
, &system
);
2758 memset(&logfont
, 0xcc, sizeof(logfont
));
2760 hr
= IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, &logfont
, &system
);
2761 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2762 ok(!system
, "got %d\n", system
);
2763 ok(logfont
.lfFaceName
[0] == 0, "got face name %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
2767 logfont
.lfHeight
= 10;
2768 logfont
.lfWidth
= 11;
2769 logfont
.lfEscapement
= 10;
2770 logfont
.lfOrientation
= 10;
2771 logfont
.lfWeight
= 0;
2772 logfont
.lfItalic
= 1;
2773 logfont
.lfUnderline
= 1;
2774 logfont
.lfStrikeOut
= 1;
2775 logfont
.lfCharSet
= 0;
2776 logfont
.lfOutPrecision
= 0;
2777 logfont
.lfClipPrecision
= 0;
2778 logfont
.lfQuality
= 0;
2779 logfont
.lfPitchAndFamily
= 0;
2780 logfont
.lfFaceName
[0] = 0;
2782 hr
= IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, font
, &logfont
, &system
);
2783 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2784 ok(system
, "got %d\n", system
);
2786 ok(logfont
.lfHeight
== 0, "got %d\n", logfont
.lfHeight
);
2787 ok(logfont
.lfWidth
== 0, "got %d\n", logfont
.lfWidth
);
2788 ok(logfont
.lfEscapement
== 0, "got %d\n", logfont
.lfEscapement
);
2789 ok(logfont
.lfOrientation
== 0, "got %d\n", logfont
.lfOrientation
);
2790 ok(logfont
.lfWeight
> 0, "got %d\n", logfont
.lfWeight
);
2791 ok(logfont
.lfItalic
== 0, "got %d\n", logfont
.lfItalic
);
2792 ok(logfont
.lfUnderline
== 0, "got %d\n", logfont
.lfUnderline
);
2793 ok(logfont
.lfStrikeOut
== 0, "got %d\n", logfont
.lfStrikeOut
);
2794 ok(logfont
.lfCharSet
== DEFAULT_CHARSET
, "got %d\n", logfont
.lfCharSet
);
2795 ok(logfont
.lfOutPrecision
== OUT_OUTLINE_PRECIS
, "got %d\n", logfont
.lfOutPrecision
);
2796 ok(logfont
.lfClipPrecision
== 0, "got %d\n", logfont
.lfClipPrecision
);
2797 ok(logfont
.lfQuality
== 0, "got %d\n", logfont
.lfQuality
);
2798 ok(logfont
.lfPitchAndFamily
== 0, "got %d\n", logfont
.lfPitchAndFamily
);
2799 ok(logfont
.lfFaceName
[0] != 0, "got face name %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
2801 IDWriteFactory_Release(factory2
);
2803 IDWriteFontCollection_Release(collection
);
2804 IDWriteFontFamily_Release(family
);
2805 IDWriteFont_Release(font
);
2806 IDWriteGdiInterop_Release(interop
);
2807 IDWriteFactory_Release(factory
);
2810 static void test_CreateStreamFromKey(void)
2812 IDWriteLocalFontFileLoader
*localloader
;
2813 IDWriteFontFileStream
*stream
, *stream2
;
2814 IDWriteFontFileLoader
*loader
;
2815 IDWriteFactory
*factory
;
2816 IDWriteFontFile
*file
;
2823 factory
= create_factory();
2825 path
= create_testfontfile(test_fontfile
);
2827 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2828 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2832 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2833 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2834 ok(size
!= 0, "got %u\n", size
);
2836 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2837 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2838 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2839 IDWriteFontFileLoader_Release(loader
);
2841 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2842 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2843 EXPECT_REF(stream
, 1);
2845 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream2
);
2846 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2847 ok(stream
== stream2
|| broken(stream
!= stream2
) /* Win7 SP0 */, "got %p, %p\n", stream
, stream2
);
2848 if (stream
== stream2
)
2849 EXPECT_REF(stream
, 2);
2850 IDWriteFontFileStream_Release(stream
);
2851 IDWriteFontFileStream_Release(stream2
);
2853 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2854 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2855 EXPECT_REF(stream
, 1);
2858 hr
= IDWriteFontFileStream_GetLastWriteTime(stream
, &writetime
);
2859 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2860 ok(writetime
!= 0, "got %08x%08x\n", (UINT
)(writetime
>> 32), (UINT
)writetime
);
2862 IDWriteFontFileStream_Release(stream
);
2864 IDWriteLocalFontFileLoader_Release(localloader
);
2865 IDWriteFactory_Release(factory
);
2866 DELETE_FONTFILE(path
);
2869 static void test_ReadFileFragment(void)
2871 IDWriteLocalFontFileLoader
*localloader
;
2872 IDWriteFontFileStream
*stream
;
2873 IDWriteFontFileLoader
*loader
;
2874 IDWriteFactory
*factory
;
2875 IDWriteFontFile
*file
;
2876 const void *fragment
, *fragment2
;
2877 void *key
, *context
, *context2
;
2883 factory
= create_factory();
2885 path
= create_testfontfile(test_fontfile
);
2887 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2888 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2892 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2893 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2894 ok(size
!= 0, "got %u\n", size
);
2896 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2897 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2898 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2899 IDWriteFontFileLoader_Release(loader
);
2901 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2902 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2904 hr
= IDWriteFontFileStream_GetFileSize(stream
, &filesize
);
2905 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2907 /* reading past the end of the stream */
2908 fragment
= (void*)0xdeadbeef;
2909 context
= (void*)0xdeadbeef;
2910 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
+1, &context
);
2911 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2912 ok(context
== NULL
, "got %p\n", context
);
2913 ok(fragment
== NULL
, "got %p\n", fragment
);
2915 fragment
= (void*)0xdeadbeef;
2916 context
= (void*)0xdeadbeef;
2917 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
, &context
);
2918 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2919 ok(context
== NULL
, "got %p\n", context
);
2920 ok(fragment
!= NULL
, "got %p\n", fragment
);
2922 fragment2
= (void*)0xdeadbeef;
2923 context2
= (void*)0xdeadbeef;
2924 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment2
, 0, filesize
, &context2
);
2925 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2926 ok(context2
== NULL
, "got %p\n", context2
);
2927 ok(fragment
== fragment2
, "got %p, %p\n", fragment
, fragment2
);
2929 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
2930 IDWriteFontFileStream_ReleaseFileFragment(stream
, context2
);
2932 /* fragment is released, try again */
2933 fragment
= (void*)0xdeadbeef;
2934 context
= (void*)0xdeadbeef;
2935 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
, &context
);
2936 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2937 ok(context
== NULL
, "got %p\n", context
);
2938 ok(fragment
== fragment2
, "got %p, %p\n", fragment
, fragment2
);
2939 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
2941 IDWriteFontFileStream_Release(stream
);
2942 IDWriteLocalFontFileLoader_Release(localloader
);
2943 IDWriteFactory_Release(factory
);
2944 DELETE_FONTFILE(path
);
2947 static void test_GetDesignGlyphMetrics(void)
2949 DWRITE_GLYPH_METRICS metrics
[2];
2950 IDWriteFontFace
*fontface
;
2951 IDWriteFactory
*factory
;
2952 IDWriteFontFile
*file
;
2958 factory
= create_factory();
2960 path
= create_testfontfile(test_fontfile
);
2962 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2963 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2965 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
,
2966 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
2967 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2968 IDWriteFontFile_Release(file
);
2972 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &codepoint
, 1, &indices
[0]);
2973 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2974 ok(indices
[0] > 0, "got %u\n", indices
[0]);
2976 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, NULL
, 0, metrics
, FALSE
);
2977 ok(hr
== E_INVALIDARG
, "got 0x%08x\n",hr
);
2979 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, NULL
, 1, metrics
, FALSE
);
2980 ok(hr
== E_INVALIDARG
, "got 0x%08x\n",hr
);
2982 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, indices
, 0, metrics
, FALSE
);
2983 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2985 /* missing glyphs are ignored */
2987 memset(metrics
, 0xcc, sizeof(metrics
));
2988 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, indices
, 2, metrics
, FALSE
);
2989 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2990 ok(metrics
[0].advanceWidth
== 1000, "got %d\n", metrics
[0].advanceWidth
);
2991 ok(metrics
[1].advanceWidth
== 0, "got %d\n", metrics
[1].advanceWidth
);
2993 IDWriteFontFace_Release(fontface
);
2994 IDWriteFactory_Release(factory
);
2995 DELETE_FONTFILE(path
);
2998 static void test_IsMonospacedFont(void)
3000 static const WCHAR courierW
[] = {'C','o','u','r','i','e','r',' ','N','e','w',0};
3001 IDWriteFontCollection
*collection
;
3002 IDWriteFactory
*factory
;
3007 factory
= create_factory();
3008 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
3009 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3012 hr
= IDWriteFontCollection_FindFamilyName(collection
, courierW
, &index
, &exists
);
3013 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3015 IDWriteFontFamily
*family
;
3016 IDWriteFont1
*font1
;
3019 hr
= IDWriteFontCollection_GetFontFamily(collection
, index
, &family
);
3020 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3022 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
3023 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
3024 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3025 IDWriteFontFamily_Release(family
);
3027 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
3029 IDWriteFontFace1
*fontface1
;
3030 IDWriteFontFace
*fontface
;
3033 is_monospaced
= IDWriteFont1_IsMonospacedFont(font1
);
3034 ok(is_monospaced
, "got %d\n", is_monospaced
);
3036 hr
= IDWriteFont1_CreateFontFace(font1
, &fontface
);
3037 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3038 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3039 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3040 is_monospaced
= IDWriteFontFace1_IsMonospacedFont(fontface1
);
3041 ok(is_monospaced
, "got %d\n", is_monospaced
);
3042 IDWriteFontFace1_Release(fontface1
);
3044 IDWriteFontFace_Release(fontface
);
3045 IDWriteFont1_Release(font1
);
3048 win_skip("IsMonospacedFont() is not supported.\n");
3051 skip("Courier New font not found.\n");
3053 IDWriteFontCollection_Release(collection
);
3056 static void test_GetDesignGlyphAdvances(void)
3058 IDWriteFontFace1
*fontface1
;
3059 IDWriteFontFace
*fontface
;
3060 IDWriteFactory
*factory
;
3061 IDWriteFontFile
*file
;
3065 factory
= create_factory();
3067 path
= create_testfontfile(test_fontfile
);
3069 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3070 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3072 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
,
3073 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3074 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3075 IDWriteFontFile_Release(file
);
3077 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3085 hr
= IDWriteFontFace1_GetGlyphIndices(fontface1
, &codepoint
, 1, &index
);
3086 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3087 ok(index
> 0, "got %u\n", index
);
3090 hr
= IDWriteFontFace1_GetDesignGlyphAdvances(fontface1
, 1, &index
, &advance
, FALSE
);
3091 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3092 ok(advance
== 1000, "got %i\n", advance
);
3095 hr
= IDWriteFontFace1_GetDesignGlyphAdvances(fontface1
, 1, &index
, &advance
, TRUE
);
3096 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3098 ok(advance
== 2048, "got %i\n", advance
);
3100 IDWriteFontFace1_Release(fontface1
);
3103 win_skip("GetDesignGlyphAdvances() is not supported.\n");
3105 IDWriteFontFace_Release(fontface
);
3106 IDWriteFactory_Release(factory
);
3107 DELETE_FONTFILE(path
);
3110 static void test_GetGlyphRunOutline(void)
3112 DWRITE_GLYPH_OFFSET offsets
[2];
3113 IDWriteFactory
*factory
;
3114 IDWriteFontFile
*file
;
3115 IDWriteFontFace
*face
;
3122 path
= create_testfontfile(test_fontfile
);
3123 factory
= create_factory();
3125 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3126 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3128 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
3129 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3130 IDWriteFontFile_Release(file
);
3134 hr
= IDWriteFontFace_GetGlyphIndices(face
, &codepoint
, 1, glyphs
);
3135 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3136 ok(glyphs
[0] > 0, "got %u\n", glyphs
[0]);
3137 glyphs
[1] = glyphs
[0];
3139 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 2048.0, glyphs
, advances
, offsets
, 1, FALSE
, FALSE
, NULL
);
3140 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3142 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 2048.0, NULL
, NULL
, offsets
, 1, FALSE
, FALSE
, &test_geomsink
);
3143 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3148 offsets
[0].advanceOffset
= 1.0;
3149 offsets
[0].ascenderOffset
= 1.0;
3150 offsets
[1].advanceOffset
= 0.0;
3151 offsets
[1].ascenderOffset
= 0.0;
3153 /* default advances, no offsets */
3154 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3155 g_startpoint_count
= 0;
3156 SET_EXPECT(setfillmode
);
3157 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 2, FALSE
, FALSE
, &test_geomsink
);
3158 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3159 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3160 if (g_startpoint_count
== 2) {
3161 /* glyph advance of 500 is applied */
3162 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
);
3163 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
);
3165 CHECK_CALLED(setfillmode
);
3167 /* default advances, no offsets, RTL */
3168 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3169 g_startpoint_count
= 0;
3170 SET_EXPECT(setfillmode
);
3171 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 2, FALSE
, TRUE
, &test_geomsink
);
3172 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3173 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3174 if (g_startpoint_count
== 2) {
3175 /* advance is -500 now */
3176 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
);
3177 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
);
3179 CHECK_CALLED(setfillmode
);
3181 /* default advances, additional offsets */
3182 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3183 g_startpoint_count
= 0;
3184 SET_EXPECT(setfillmode
);
3185 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, offsets
, 2, FALSE
, FALSE
, &test_geomsink
);
3186 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3187 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3188 if (g_startpoint_count
== 2) {
3189 /* offsets applied to first contour */
3190 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
);
3191 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
);
3193 CHECK_CALLED(setfillmode
);
3195 /* default advances, additional offsets, RTL */
3196 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3197 g_startpoint_count
= 0;
3198 SET_EXPECT(setfillmode
);
3199 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, offsets
, 2, FALSE
, TRUE
, &test_geomsink
);
3200 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3201 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3202 if (g_startpoint_count
== 2) {
3203 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
);
3204 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
);
3206 CHECK_CALLED(setfillmode
);
3208 /* custom advances and offsets, offset turns total advance value to zero */
3209 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3210 g_startpoint_count
= 0;
3211 SET_EXPECT(setfillmode
);
3212 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, advances
, offsets
, 2, FALSE
, FALSE
, &test_geomsink
);
3213 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3214 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3215 if (g_startpoint_count
== 2) {
3216 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
);
3217 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
);
3219 CHECK_CALLED(setfillmode
);
3222 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 0, FALSE
, FALSE
, &test_geomsink2
);
3223 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3225 IDWriteFactory_Release(factory
);
3226 IDWriteFontFace_Release(face
);
3227 DELETE_FONTFILE(path
);
3230 factory
= create_factory();
3231 face
= create_fontface(factory
);
3235 hr
= IDWriteFontFace_GetGlyphIndices(face
, &codepoint
, 1, glyphs
);
3236 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3237 ok(glyphs
[0] > 0, "got %u\n", glyphs
[0]);
3239 SET_EXPECT(setfillmode
);
3240 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 1, FALSE
, FALSE
, &test_geomsink2
);
3241 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3242 CHECK_CALLED(setfillmode
);
3244 IDWriteFactory_Release(factory
);
3245 IDWriteFontFace_Release(face
);
3248 static void test_GetEudcFontCollection(void)
3250 IDWriteFontCollection
*coll
, *coll2
;
3251 IDWriteFactory1
*factory1
;
3252 IDWriteFactory
*factory
;
3255 factory
= create_factory();
3257 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory1
, (void**)&factory1
);
3258 IDWriteFactory_Release(factory
);
3260 win_skip("GetEudcFontCollection() is not supported.\n");
3264 hr
= IDWriteFactory1_GetEudcFontCollection(factory1
, &coll
, FALSE
);
3265 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3266 hr
= IDWriteFactory1_GetEudcFontCollection(factory1
, &coll2
, FALSE
);
3267 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3268 ok(coll
== coll2
, "got %p, %p\n", coll
, coll2
);
3269 IDWriteFontCollection_Release(coll
);
3270 IDWriteFontCollection_Release(coll2
);
3272 IDWriteFactory1_Release(factory1
);
3275 static void test_GetCaretMetrics(void)
3277 DWRITE_FONT_METRICS1 metrics
;
3278 IDWriteFontFace1
*fontface1
;
3279 DWRITE_CARET_METRICS caret
;
3280 IDWriteFontFace
*fontface
;
3281 IDWriteFactory
*factory
;
3282 IDWriteFontFile
*file
;
3287 path
= create_testfontfile(test_fontfile
);
3288 factory
= create_factory();
3290 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3291 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3293 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3294 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3295 IDWriteFontFile_Release(file
);
3297 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3298 IDWriteFontFace_Release(fontface
);
3300 win_skip("GetCaretMetrics() is not supported.\n");
3301 IDWriteFactory_Release(factory
);
3302 DELETE_FONTFILE(path
);
3306 memset(&caret
, 0xcc, sizeof(caret
));
3307 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
3308 ok(caret
.slopeRise
== 1, "got %d\n", caret
.slopeRise
);
3309 ok(caret
.slopeRun
== 0, "got %d\n", caret
.slopeRun
);
3310 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
3311 IDWriteFontFace1_Release(fontface1
);
3312 IDWriteFactory_Release(factory
);
3314 /* now with Tahoma Normal */
3315 factory
= create_factory();
3316 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
3317 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3318 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3319 IDWriteFont_Release(font
);
3320 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3321 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3322 IDWriteFontFace_Release(fontface
);
3324 memset(&caret
, 0xcc, sizeof(caret
));
3325 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
3326 ok(caret
.slopeRise
== 1, "got %d\n", caret
.slopeRise
);
3327 ok(caret
.slopeRun
== 0, "got %d\n", caret
.slopeRun
);
3328 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
3329 IDWriteFontFace1_Release(fontface1
);
3331 /* simulated italic */
3332 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_ITALIC
);
3333 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3334 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3335 IDWriteFont_Release(font
);
3336 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3337 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3338 IDWriteFontFace_Release(fontface
);
3340 IDWriteFontFace1_GetMetrics(fontface1
, &metrics
);
3342 memset(&caret
, 0xcc, sizeof(caret
));
3343 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
3344 ok(caret
.slopeRise
== metrics
.designUnitsPerEm
, "got %d\n", caret
.slopeRise
);
3345 ok(caret
.slopeRun
> 0, "got %d\n", caret
.slopeRun
);
3346 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
3347 IDWriteFontFace1_Release(fontface1
);
3349 IDWriteFactory_Release(factory
);
3350 DELETE_FONTFILE(path
);
3353 static void test_GetGlyphCount(void)
3355 IDWriteFontFace
*fontface
;
3356 IDWriteFactory
*factory
;
3357 IDWriteFontFile
*file
;
3362 path
= create_testfontfile(test_fontfile
);
3363 factory
= create_factory();
3365 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3366 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3368 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3369 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3370 IDWriteFontFile_Release(file
);
3372 count
= IDWriteFontFace_GetGlyphCount(fontface
);
3373 ok(count
== 7, "got %u\n", count
);
3375 IDWriteFontFace_Release(fontface
);
3376 IDWriteFactory_Release(factory
);
3377 DELETE_FONTFILE(path
);
3380 static void test_GetKerningPairAdjustments(void)
3382 IDWriteFontFace1
*fontface1
;
3383 IDWriteFontFace
*fontface
;
3384 IDWriteFactory
*factory
;
3385 IDWriteFontFile
*file
;
3389 path
= create_testfontfile(test_fontfile
);
3390 factory
= create_factory();
3392 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3393 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3395 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3396 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3397 IDWriteFontFile_Release(file
);
3399 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3401 INT32 adjustments
[1];
3403 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 0, NULL
, NULL
);
3404 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
3406 if (0) /* crashes on native */
3407 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 1, NULL
, NULL
);
3410 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 1, NULL
, adjustments
);
3411 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3412 ok(adjustments
[0] == 0, "got %d\n", adjustments
[0]);
3414 IDWriteFontFace1_Release(fontface1
);
3417 win_skip("GetKerningPairAdjustments() is not supported.\n");
3419 IDWriteFontFace_Release(fontface
);
3420 IDWriteFactory_Release(factory
);
3421 DELETE_FONTFILE(path
);
3424 static void test_CreateRenderingParams(void)
3426 IDWriteRenderingParams2
*params2
;
3427 IDWriteRenderingParams1
*params1
;
3428 IDWriteRenderingParams
*params
;
3429 DWRITE_RENDERING_MODE mode
;
3430 IDWriteFactory
*factory
;
3433 factory
= create_factory();
3435 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 1.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT
,
3436 DWRITE_RENDERING_MODE_DEFAULT
, ¶ms
);
3437 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3439 hr
= IDWriteRenderingParams_QueryInterface(params
, &IID_IDWriteRenderingParams1
, (void**)¶ms1
);
3443 /* test what enhanced contrast setting set by default to */
3444 enhcontrast
= IDWriteRenderingParams1_GetGrayscaleEnhancedContrast(params1
);
3445 ok(enhcontrast
== 1.0, "got %.2f\n", enhcontrast
);
3446 IDWriteRenderingParams1_Release(params1
);
3448 hr
= IDWriteRenderingParams_QueryInterface(params
, &IID_IDWriteRenderingParams2
, (void**)¶ms2
);
3450 DWRITE_GRID_FIT_MODE gridfit
;
3452 /* default gridfit mode */
3453 gridfit
= IDWriteRenderingParams2_GetGridFitMode(params2
);
3454 ok(gridfit
== DWRITE_GRID_FIT_MODE_DEFAULT
, "got %d\n", gridfit
);
3456 IDWriteRenderingParams2_Release(params2
);
3459 win_skip("IDWriteRenderingParams2 not supported.\n");
3462 win_skip("IDWriteRenderingParams1 not supported.\n");
3464 IDWriteRenderingParams_Release(params
);
3466 hr
= IDWriteFactory_CreateRenderingParams(factory
, ¶ms
);
3467 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3469 mode
= IDWriteRenderingParams_GetRenderingMode(params
);
3470 ok(mode
== DWRITE_RENDERING_MODE_DEFAULT
, "got %d\n", mode
);
3471 IDWriteRenderingParams_Release(params
);
3473 IDWriteFactory_Release(factory
);
3476 static void test_CreateGlyphRunAnalysis(void)
3478 static const DWRITE_RENDERING_MODE rendermodes
[] = {
3479 DWRITE_RENDERING_MODE_ALIASED
,
3480 DWRITE_RENDERING_MODE_GDI_CLASSIC
,
3481 DWRITE_RENDERING_MODE_GDI_NATURAL
,
3482 DWRITE_RENDERING_MODE_NATURAL
,
3483 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
,
3486 IDWriteGlyphRunAnalysis
*analysis
;
3487 IDWriteFactory
*factory
;
3488 DWRITE_GLYPH_RUN run
;
3489 IDWriteFontFace
*face
;
3490 UINT16 glyph
, glyphs
[10];
3495 DWRITE_GLYPH_OFFSET offset
;
3496 DWRITE_GLYPH_METRICS metrics
;
3497 DWRITE_FONT_METRICS fm
;
3500 factory
= create_factory();
3501 face
= create_fontface(factory
);
3505 hr
= IDWriteFontFace_GetGlyphIndices(face
, &ch
, 1, &glyph
);
3506 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3507 ok(glyph
> 0, "got %u\n", glyph
);
3509 hr
= IDWriteFontFace_GetDesignGlyphMetrics(face
, &glyph
, 1, &metrics
, FALSE
);
3510 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3511 advance
= metrics
.advanceWidth
;
3513 offset
.advanceOffset
= 0.0;
3514 offset
.ascenderOffset
= 0.0;
3516 run
.fontFace
= face
;
3517 run
.fontEmSize
= 24.0;
3519 run
.glyphIndices
= &glyph
;
3520 run
.glyphAdvances
= &advance
;
3521 run
.glyphOffsets
= &offset
;
3522 run
.isSideways
= FALSE
;
3525 /* default mode is not allowed */
3526 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3527 DWRITE_RENDERING_MODE_DEFAULT
, DWRITE_MEASURING_MODE_NATURAL
,
3528 0.0, 0.0, &analysis
);
3529 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3532 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3533 DWRITE_RENDERING_MODE_OUTLINE
, DWRITE_MEASURING_MODE_NATURAL
,
3534 0.0, 0.0, &analysis
);
3535 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3537 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3538 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3539 0.0, 0.0, &analysis
);
3540 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3542 /* invalid texture type */
3543 memset(&rect
, 0xcc, sizeof(rect
));
3544 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
+1, &rect
);
3545 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3546 ok(rect
.left
== 0 && rect
.right
== 0 &&
3547 rect
.top
== 0 && rect
.bottom
== 0, "unexpected rect\n");
3549 /* check how origin affects bounds */
3550 memset(&rect
, 0, sizeof(rect
));
3551 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3552 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3553 ok(!IsRectEmpty(&rect
), "got empty rect\n");
3554 IDWriteGlyphRunAnalysis_Release(analysis
);
3556 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3557 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3558 10.0, -5.0, &analysis
);
3559 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3561 memset(&rect2
, 0, sizeof(rect2
));
3562 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect2
);
3563 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3564 ok(!IsRectEmpty(&rect2
), "got empty rect\n");
3565 IDWriteGlyphRunAnalysis_Release(analysis
);
3567 ok(!EqualRect(&rect
, &rect2
), "got equal bounds\n");
3568 OffsetRect(&rect
, 10, -5);
3569 ok(EqualRect(&rect
, &rect2
), "got different bounds\n");
3571 for (i
= 0; i
< sizeof(rendermodes
)/sizeof(rendermodes
[0]); i
++) {
3572 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3573 rendermodes
[i
], DWRITE_MEASURING_MODE_NATURAL
,
3574 0.0, 0.0, &analysis
);
3575 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3577 if (rendermodes
[i
] == DWRITE_RENDERING_MODE_ALIASED
) {
3578 memset(&rect
, 0, sizeof(rect
));
3579 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3580 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3581 ok(!IsRectEmpty(&rect
), "got empty rect\n");
3583 rect
.left
= rect
.top
= 0;
3584 rect
.bottom
= rect
.right
= 1;
3585 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &rect
);
3586 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3587 ok(IsRectEmpty(&rect
), "unexpected empty rect\n");
3590 rect
.left
= rect
.top
= 0;
3591 rect
.bottom
= rect
.right
= 1;
3592 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3593 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3594 ok(IsRectEmpty(&rect
), "got empty rect\n");
3596 memset(&rect
, 0, sizeof(rect
));
3597 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &rect
);
3598 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3599 ok(!IsRectEmpty(&rect
), "got empty rect\n");
3602 IDWriteGlyphRunAnalysis_Release(analysis
);
3605 IDWriteFontFace_GetMetrics(run
.fontFace
, &fm
);
3607 /* check bbox for a single glyph run */
3608 for (run
.fontEmSize
= 1.0; run
.fontEmSize
<= 100.0; run
.fontEmSize
+= 1.0) {
3609 DWRITE_GLYPH_METRICS gm
;
3612 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3613 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
3614 0.0, 0.0, &analysis
);
3615 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3617 memset(&rect
, 0, sizeof(rect
));
3618 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3619 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3621 hr
= IDWriteFontFace_GetGdiCompatibleGlyphMetrics(run
.fontFace
, run
.fontEmSize
, 1.0, NULL
,
3622 DWRITE_MEASURING_MODE_GDI_CLASSIC
, run
.glyphIndices
, 1, &gm
, run
.isSideways
);
3623 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3625 /* metrics are in design units */
3626 bboxX
= (int)floorf((gm
.advanceWidth
- gm
.leftSideBearing
- gm
.rightSideBearing
) * run
.fontEmSize
/ fm
.designUnitsPerEm
+ 0.5f
);
3627 bboxY
= (int)floorf((gm
.advanceHeight
- gm
.topSideBearing
- gm
.bottomSideBearing
) * run
.fontEmSize
/ fm
.designUnitsPerEm
+ 0.5f
);
3629 rect
.right
-= rect
.left
;
3630 rect
.bottom
-= rect
.top
;
3631 ok(abs(bboxX
- rect
.right
) <= 2, "%.0f: bbox width %d, from metrics %d\n", run
.fontEmSize
, rect
.right
, bboxX
);
3632 ok(abs(bboxY
- rect
.bottom
) <= 2, "%.0f: bbox height %d, from metrics %d\n", run
.fontEmSize
, rect
.bottom
, bboxY
);
3634 IDWriteGlyphRunAnalysis_Release(analysis
);
3637 /* without offsets */
3638 run
.fontFace
= face
;
3639 run
.fontEmSize
= 24.0;
3641 run
.glyphIndices
= &glyph
;
3642 run
.glyphAdvances
= &advance
;
3643 run
.glyphOffsets
= NULL
;
3644 run
.isSideways
= FALSE
;
3647 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3648 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3649 0.0, 0.0, &analysis
);
3650 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3652 SetRectEmpty(&rect
);
3653 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3654 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3655 ok(!IsRectEmpty(&rect
), "got empty bounds\n");
3657 IDWriteGlyphRunAnalysis_Release(analysis
);
3659 /* without explicit advances */
3660 run
.fontFace
= face
;
3661 run
.fontEmSize
= 24.0;
3663 run
.glyphIndices
= &glyph
;
3664 run
.glyphAdvances
= NULL
;
3665 run
.glyphOffsets
= NULL
;
3666 run
.isSideways
= FALSE
;
3669 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3670 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3671 0.0, 0.0, &analysis
);
3672 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3674 SetRectEmpty(&rect
);
3675 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3676 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3677 ok(!IsRectEmpty(&rect
), "got empty bounds\n");
3679 IDWriteGlyphRunAnalysis_Release(analysis
);
3681 glyphs
[0] = glyphs
[1] = glyph
;
3682 run
.fontFace
= face
;
3683 run
.fontEmSize
= 24.0;
3685 run
.glyphIndices
= glyphs
;
3686 run
.glyphAdvances
= NULL
;
3687 run
.glyphOffsets
= NULL
;
3688 run
.isSideways
= FALSE
;
3691 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3692 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3693 0.0, 0.0, &analysis
);
3694 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3696 SetRectEmpty(&rect2
);
3697 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect2
);
3698 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3699 ok(!IsRectEmpty(&rect2
), "got empty bounds\n");
3700 ok(!EqualRect(&rect
, &rect2
), "got wrong rect2\n");
3702 IDWriteGlyphRunAnalysis_Release(analysis
);
3704 IDWriteFontFace_Release(face
);
3705 IDWriteFactory_Release(factory
);
3708 #define round(x) ((int)floor((x) + 0.5))
3739 #ifdef WORDS_BIGENDIAN
3740 #define GET_BE_WORD(x) (x)
3742 #define GET_BE_WORD(x) RtlUshortByteSwap(x)
3745 static const struct VDMX_group
*find_vdmx_group(const struct VDMX_Header
*hdr
)
3747 WORD num_ratios
, i
, group_offset
= 0;
3748 struct VDMX_Ratio
*ratios
= (struct VDMX_Ratio
*)(hdr
+ 1);
3749 BYTE dev_x_ratio
= 1, dev_y_ratio
= 1;
3751 num_ratios
= GET_BE_WORD(hdr
->numRatios
);
3753 for (i
= 0; i
< num_ratios
; i
++)
3755 if (!ratios
[i
].bCharSet
) continue;
3757 if ((ratios
[i
].xRatio
== 0 && ratios
[i
].yStartRatio
== 0 &&
3758 ratios
[i
].yEndRatio
== 0) ||
3759 (ratios
[i
].xRatio
== dev_x_ratio
&& ratios
[i
].yStartRatio
<= dev_y_ratio
&&
3760 ratios
[i
].yEndRatio
>= dev_y_ratio
))
3762 group_offset
= GET_BE_WORD(*((WORD
*)(ratios
+ num_ratios
) + i
));
3767 return (const struct VDMX_group
*)((BYTE
*)hdr
+ group_offset
);
3771 static BOOL
get_vdmx_size(const struct VDMX_group
*group
, int emsize
, int *a
, int *d
)
3774 const struct VDMX_vTable
*tables
;
3776 if (!group
) return FALSE
;
3778 recs
= GET_BE_WORD(group
->recs
);
3779 if (emsize
< group
->startsz
|| emsize
>= group
->endsz
) return FALSE
;
3781 tables
= (const struct VDMX_vTable
*)(group
+ 1);
3782 for (i
= 0; i
< recs
; i
++)
3784 WORD ppem
= GET_BE_WORD(tables
[i
].yPelHeight
);
3787 /* FIXME: Supposed to interpolate */
3788 trace("FIXME interpolate %d\n", emsize
);
3794 *a
= (SHORT
)GET_BE_WORD(tables
[i
].yMax
);
3795 *d
= -(SHORT
)GET_BE_WORD(tables
[i
].yMin
);
3802 static void test_metrics_cmp(FLOAT emsize
, const DWRITE_FONT_METRICS
*metrics
, const DWRITE_FONT_METRICS1
*expected
)
3804 ok(metrics
->designUnitsPerEm
== expected
->designUnitsPerEm
, "%.2f: emsize: got %u expect %u\n",
3805 emsize
, metrics
->designUnitsPerEm
, expected
->designUnitsPerEm
);
3806 ok(metrics
->ascent
== expected
->ascent
, "%.2f a: got %u expect %u\n",
3807 emsize
, metrics
->ascent
, expected
->ascent
);
3808 ok(metrics
->descent
== expected
->descent
, "%.2f d: got %u expect %u\n",
3809 emsize
, metrics
->descent
, expected
->descent
);
3810 ok(metrics
->lineGap
== expected
->lineGap
, "%.2f lg: got %d expect %d\n",
3811 emsize
, metrics
->lineGap
, expected
->lineGap
);
3812 ok(metrics
->capHeight
== expected
->capHeight
, "%.2f capH: got %u expect %u\n",
3813 emsize
, metrics
->capHeight
, expected
->capHeight
);
3814 ok(metrics
->xHeight
== expected
->xHeight
, "%.2f xH: got %u expect %u\n",
3815 emsize
, metrics
->xHeight
, expected
->xHeight
);
3816 ok(metrics
->underlinePosition
== expected
->underlinePosition
, "%.2f ulP: got %d expect %d\n",
3817 emsize
, metrics
->underlinePosition
, expected
->underlinePosition
);
3818 ok(metrics
->underlineThickness
== expected
->underlineThickness
, "%.2f ulTh: got %u expect %u\n",
3819 emsize
, metrics
->underlineThickness
, expected
->underlineThickness
);
3820 ok(metrics
->strikethroughPosition
== expected
->strikethroughPosition
, "%.2f stP: got %d expect %d\n",
3821 emsize
, metrics
->strikethroughPosition
, expected
->strikethroughPosition
);
3822 ok(metrics
->strikethroughThickness
== expected
->strikethroughThickness
, "%.2f stTh: got %u expect %u\n",
3823 emsize
, metrics
->strikethroughThickness
, expected
->strikethroughThickness
);
3826 static void test_metrics1_cmp(FLOAT emsize
, const DWRITE_FONT_METRICS1
*metrics
, const DWRITE_FONT_METRICS1
*expected
)
3828 ok(metrics
->designUnitsPerEm
== expected
->designUnitsPerEm
, "%.2f: emsize: got %u expect %u\n",
3829 emsize
, metrics
->designUnitsPerEm
, expected
->designUnitsPerEm
);
3830 ok(metrics
->ascent
== expected
->ascent
, "%.2f a: got %u expect %u\n",
3831 emsize
, metrics
->ascent
, expected
->ascent
);
3832 ok(metrics
->descent
== expected
->descent
, "%.2f d: got %u expect %u\n",
3833 emsize
, metrics
->descent
, expected
->descent
);
3834 ok(metrics
->lineGap
== expected
->lineGap
, "%.2f lg: got %d expect %d\n",
3835 emsize
, metrics
->lineGap
, expected
->lineGap
);
3836 ok(metrics
->capHeight
== expected
->capHeight
, "%.2f capH: got %u expect %u\n",
3837 emsize
, metrics
->capHeight
, expected
->capHeight
);
3838 ok(metrics
->xHeight
== expected
->xHeight
, "%.2f xH: got %u expect %u\n",
3839 emsize
, metrics
->xHeight
, expected
->xHeight
);
3840 ok(metrics
->underlinePosition
== expected
->underlinePosition
, "%.2f ulP: got %d expect %d\n",
3841 emsize
, metrics
->underlinePosition
, expected
->underlinePosition
);
3842 ok(metrics
->underlineThickness
== expected
->underlineThickness
, "%.2f ulTh: got %u expect %u\n",
3843 emsize
, metrics
->underlineThickness
, expected
->underlineThickness
);
3844 ok(metrics
->strikethroughPosition
== expected
->strikethroughPosition
, "%.2f stP: got %d expect %d\n",
3845 emsize
, metrics
->strikethroughPosition
, expected
->strikethroughPosition
);
3846 ok(metrics
->strikethroughThickness
== expected
->strikethroughThickness
, "%.2f stTh: got %u expect %u\n",
3847 emsize
, metrics
->strikethroughThickness
, expected
->strikethroughThickness
);
3848 ok(metrics
->glyphBoxLeft
== expected
->glyphBoxLeft
, "%.2f box left: got %d expect %d\n",
3849 emsize
, metrics
->glyphBoxLeft
, expected
->glyphBoxLeft
);
3850 if (0) { /* this is not consistent */
3851 ok(metrics
->glyphBoxTop
== expected
->glyphBoxTop
, "%.2f box top: got %d expect %d\n",
3852 emsize
, metrics
->glyphBoxTop
, expected
->glyphBoxTop
);
3853 ok(metrics
->glyphBoxRight
== expected
->glyphBoxRight
, "%.2f box right: got %d expect %d\n",
3854 emsize
, metrics
->glyphBoxRight
, expected
->glyphBoxRight
);
3856 ok(metrics
->glyphBoxBottom
== expected
->glyphBoxBottom
, "%.2f box bottom: got %d expect %d\n",
3857 emsize
, metrics
->glyphBoxBottom
, expected
->glyphBoxBottom
);
3858 ok(metrics
->subscriptPositionX
== expected
->subscriptPositionX
, "%.2f subX: got %d expect %d\n",
3859 emsize
, metrics
->subscriptPositionX
, expected
->subscriptPositionX
);
3860 ok(metrics
->subscriptPositionY
== expected
->subscriptPositionY
, "%.2f subY: got %d expect %d\n",
3861 emsize
, metrics
->subscriptPositionY
, expected
->subscriptPositionY
);
3862 ok(metrics
->subscriptSizeX
== expected
->subscriptSizeX
, "%.2f subsizeX: got %d expect %d\n",
3863 emsize
, metrics
->subscriptSizeX
, expected
->subscriptSizeX
);
3864 ok(metrics
->subscriptPositionY
== expected
->subscriptPositionY
, "%.2f subsizeY: got %d expect %d\n",
3865 emsize
, metrics
->subscriptSizeY
, expected
->subscriptSizeY
);
3866 ok(metrics
->superscriptPositionX
== expected
->superscriptPositionX
, "%.2f supX: got %d expect %d\n",
3867 emsize
, metrics
->superscriptPositionX
, expected
->superscriptPositionX
);
3869 ok(metrics
->superscriptPositionY
== expected
->superscriptPositionY
, "%.2f supY: got %d expect %d\n",
3870 emsize
, metrics
->superscriptPositionY
, expected
->superscriptPositionY
);
3871 ok(metrics
->superscriptSizeX
== expected
->superscriptSizeX
, "%.2f supsizeX: got %d expect %d\n",
3872 emsize
, metrics
->superscriptSizeX
, expected
->superscriptSizeX
);
3873 ok(metrics
->superscriptSizeY
== expected
->superscriptSizeY
, "%.2f supsizeY: got %d expect %d\n",
3874 emsize
, metrics
->superscriptSizeY
, expected
->superscriptSizeY
);
3875 ok(metrics
->hasTypographicMetrics
== expected
->hasTypographicMetrics
, "%.2f hastypo: got %d expect %d\n",
3876 emsize
, metrics
->hasTypographicMetrics
, expected
->hasTypographicMetrics
);
3879 struct compatmetrics_test
{
3885 static struct compatmetrics_test compatmetrics_tests
[] = {
3886 { { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, 1.0, 5.0 },
3887 { { 0.0, 0.0, 0.0, -1.0, 0.0, 0.0 }, 1.0, 5.0 },
3888 { { 0.0, 0.0, 0.0, -1.0, 0.0, 0.0 }, 2.0, 5.0 },
3889 { { 0.0, 0.0, 0.0, 3.0, 0.0, 0.0 }, 2.0, 5.0 },
3890 { { 0.0, 0.0, 0.0, -3.0, 0.0, 0.0 }, 2.0, 5.0 },
3891 { { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, 2.0, 5.0 },
3892 { { 1.0, 0.0, 0.0, 1.0, 5.0, 0.0 }, 2.0, 5.0 },
3893 { { 1.0, 0.0, 0.0, 1.0, 0.0, 5.0 }, 2.0, 5.0 },
3896 static void get_expected_metrics(IDWriteFontFace
*fontface
, struct compatmetrics_test
*ptr
,
3897 DWRITE_FONT_METRICS
*expected
)
3901 memset(expected
, 0, sizeof(*expected
));
3902 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(fontface
, ptr
->ppdip
* fabsf(ptr
->m
.m22
) * ptr
->emsize
, 1.0, NULL
, expected
);
3903 ok(hr
== S_OK
, "got %08x\n", hr
);
3906 static void test_GetGdiCompatibleMetrics_face(IDWriteFontFace
*face
)
3908 IDWriteFontFace1
*fontface1
= NULL
;
3910 DWRITE_FONT_METRICS design_metrics
, comp_metrics
;
3911 DWRITE_FONT_METRICS1 design_metrics1
, expected
;
3912 FLOAT emsize
, scale
;
3913 int ascent
, descent
;
3914 const struct VDMX_Header
*vdmx
;
3918 const struct VDMX_group
*vdmx_group
= NULL
;
3921 hr
= IDWriteFontFace_QueryInterface(face
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3923 win_skip("gdi compatible DWRITE_FONT_METRICS1 are not supported.\n");
3926 IDWriteFontFace1_GetMetrics(fontface1
, &design_metrics1
);
3927 memcpy(&design_metrics
, &design_metrics1
, sizeof(design_metrics
));
3930 IDWriteFontFace_GetMetrics(face
, &design_metrics
);
3932 hr
= IDWriteFontFace_TryGetFontTable(face
, MS_VDMX_TAG
, (const void **)&vdmx
,
3933 &vdmx_len
, &vdmx_ctx
, &exists
);
3934 if (hr
!= S_OK
|| !exists
)
3937 vdmx_group
= find_vdmx_group(vdmx
);
3939 /* negative emsize */
3940 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
3941 memset(&expected
, 0, sizeof(expected
));
3942 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, -10.0, 1.0, NULL
, &comp_metrics
);
3943 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
3944 test_metrics_cmp(0.0, &comp_metrics
, &expected
);
3947 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
3948 memset(&expected
, 0, sizeof(expected
));
3949 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 0.0, 1.0, NULL
, &comp_metrics
);
3950 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
3951 test_metrics_cmp(0.0, &comp_metrics
, &expected
);
3953 /* zero pixels per dip */
3954 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
3955 memset(&expected
, 0, sizeof(expected
));
3956 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 5.0, 0.0, NULL
, &comp_metrics
);
3957 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
3958 test_metrics_cmp(5.0, &comp_metrics
, &expected
);
3960 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
3961 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 5.0, -1.0, NULL
, &comp_metrics
);
3962 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
3963 test_metrics_cmp(5.0, &comp_metrics
, &expected
);
3965 for (i
= 0; i
< sizeof(compatmetrics_tests
)/sizeof(compatmetrics_tests
[0]); i
++) {
3966 struct compatmetrics_test
*ptr
= &compatmetrics_tests
[i
];
3968 get_expected_metrics(face
, ptr
, (DWRITE_FONT_METRICS
*)&expected
);
3969 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, ptr
->emsize
, ptr
->ppdip
, &ptr
->m
, &comp_metrics
);
3970 ok(hr
== S_OK
, "got %08x\n", hr
);
3971 test_metrics_cmp(ptr
->emsize
, &comp_metrics
, &expected
);
3974 for (emsize
= 5; emsize
<= design_metrics
.designUnitsPerEm
; emsize
++)
3976 DWRITE_FONT_METRICS1 comp_metrics1
, expected
;
3979 hr
= IDWriteFontFace1_GetGdiCompatibleMetrics(fontface1
, emsize
, 1.0, NULL
, &comp_metrics1
);
3980 ok(hr
== S_OK
, "got %08x\n", hr
);
3983 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, emsize
, 1.0, NULL
, &comp_metrics
);
3984 ok(hr
== S_OK
, "got %08x\n", hr
);
3987 scale
= emsize
/ design_metrics
.designUnitsPerEm
;
3988 if (!get_vdmx_size(vdmx_group
, emsize
, &ascent
, &descent
))
3990 ascent
= round(design_metrics
.ascent
* scale
);
3991 descent
= round(design_metrics
.descent
* scale
);
3994 expected
.designUnitsPerEm
= design_metrics
.designUnitsPerEm
;
3995 expected
.ascent
= round(ascent
/ scale
);
3996 expected
.descent
= round(descent
/ scale
);
3997 expected
.lineGap
= round(round(design_metrics
.lineGap
* scale
) / scale
);
3998 expected
.capHeight
= round(round(design_metrics
.capHeight
* scale
) / scale
);
3999 expected
.xHeight
= round(round(design_metrics
.xHeight
* scale
) / scale
);
4000 expected
.underlinePosition
= round(round(design_metrics
.underlinePosition
* scale
) / scale
);
4001 expected
.underlineThickness
= round(round(design_metrics
.underlineThickness
* scale
) / scale
);
4002 expected
.strikethroughPosition
= round(round(design_metrics
.strikethroughPosition
* scale
) / scale
);
4003 expected
.strikethroughThickness
= round(round(design_metrics
.strikethroughThickness
* scale
) / scale
);
4006 expected
.glyphBoxLeft
= round(round(design_metrics1
.glyphBoxLeft
* scale
) / scale
);
4008 if (0) { /* those two fail on Tahoma and Win7 */
4009 expected
.glyphBoxTop
= round(round(design_metrics1
.glyphBoxTop
* scale
) / scale
);
4010 expected
.glyphBoxRight
= round(round(design_metrics1
.glyphBoxRight
* scale
) / scale
);
4012 expected
.glyphBoxBottom
= round(round(design_metrics1
.glyphBoxBottom
* scale
) / scale
);
4013 expected
.subscriptPositionX
= round(round(design_metrics1
.subscriptPositionX
* scale
) / scale
);
4014 expected
.subscriptPositionY
= round(round(design_metrics1
.subscriptPositionY
* scale
) / scale
);
4015 expected
.subscriptSizeX
= round(round(design_metrics1
.subscriptSizeX
* scale
) / scale
);
4016 expected
.subscriptSizeY
= round(round(design_metrics1
.subscriptSizeY
* scale
) / scale
);
4017 expected
.superscriptPositionX
= round(round(design_metrics1
.superscriptPositionX
* scale
) / scale
);
4018 if (0) /* this fails for 3 emsizes, Tahoma from [5, 2048] range */
4019 expected
.superscriptPositionY
= round(round(design_metrics1
.superscriptPositionY
* scale
) / scale
);
4020 expected
.superscriptSizeX
= round(round(design_metrics1
.superscriptSizeX
* scale
) / scale
);
4021 expected
.superscriptSizeY
= round(round(design_metrics1
.superscriptSizeY
* scale
) / scale
);
4022 expected
.hasTypographicMetrics
= design_metrics1
.hasTypographicMetrics
;
4024 test_metrics1_cmp(emsize
, &comp_metrics1
, &expected
);
4027 test_metrics_cmp(emsize
, &comp_metrics
, &expected
);
4032 IDWriteFontFace1_Release(fontface1
);
4033 if (vdmx
) IDWriteFontFace_ReleaseFontTable(face
, vdmx_ctx
);
4036 static void test_GetGdiCompatibleMetrics(void)
4038 IDWriteFactory
*factory
;
4040 IDWriteFontFace
*fontface
;
4043 factory
= create_factory();
4045 font
= get_font(factory
, tahomaW
, DWRITE_FONT_STYLE_NORMAL
);
4046 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4047 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4048 IDWriteFont_Release(font
);
4049 test_GetGdiCompatibleMetrics_face(fontface
);
4050 IDWriteFontFace_Release(fontface
);
4052 font
= get_font(factory
, arialW
, DWRITE_FONT_STYLE_NORMAL
);
4054 skip("Skipping tests with Arial\n");
4057 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4058 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4059 IDWriteFont_Release(font
);
4061 test_GetGdiCompatibleMetrics_face(fontface
);
4062 IDWriteFontFace_Release(fontface
);
4065 IDWriteFactory_Release(factory
);
4068 static void test_GetPanose(void)
4070 IDWriteFactory
*factory
;
4071 IDWriteFont1
*font1
;
4075 factory
= create_factory();
4076 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
4078 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
4079 IDWriteFont_Release(font
);
4081 DWRITE_PANOSE panose
;
4083 if (0) /* crashes on native */
4084 IDWriteFont1_GetPanose(font1
, NULL
);
4086 memset(&panose
, 0, sizeof(panose
));
4087 IDWriteFont1_GetPanose(font1
, &panose
);
4088 ok(panose
.familyKind
== DWRITE_PANOSE_FAMILY_TEXT_DISPLAY
,
4089 "got %u\n", panose
.familyKind
);
4090 ok(panose
.text
.serifStyle
== DWRITE_PANOSE_SERIF_STYLE_NORMAL_SANS
,
4091 "got %u\n", panose
.text
.serifStyle
);
4092 ok(panose
.text
.weight
== DWRITE_PANOSE_WEIGHT_MEDIUM
,
4093 "got %u\n", panose
.text
.weight
);
4094 ok(panose
.text
.proportion
== DWRITE_PANOSE_PROPORTION_EVEN_WIDTH
,
4095 "got %u\n", panose
.text
.proportion
);
4096 ok(panose
.text
.contrast
== DWRITE_PANOSE_CONTRAST_VERY_LOW
,
4097 "got %u\n", panose
.text
.contrast
);
4098 ok(panose
.text
.strokeVariation
== DWRITE_PANOSE_STROKE_VARIATION_GRADUAL_VERTICAL
,
4099 "got %u\n", panose
.text
.strokeVariation
);
4100 ok(panose
.text
.armStyle
== DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_VERTICAL
,
4101 "got %u\n", panose
.text
.armStyle
);
4102 ok(panose
.text
.letterform
== DWRITE_PANOSE_LETTERFORM_NORMAL_BOXED
,
4103 "got %u\n", panose
.text
.letterform
);
4104 ok(panose
.text
.midline
== DWRITE_PANOSE_MIDLINE_STANDARD_TRIMMED
,
4105 "got %u\n", panose
.text
.midline
);
4106 ok(panose
.text
.xHeight
== DWRITE_PANOSE_XHEIGHT_CONSTANT_LARGE
,
4107 "got %u\n", panose
.text
.xHeight
);
4109 IDWriteFont1_Release(font1
);
4112 win_skip("GetPanose() is not supported.\n");
4114 IDWriteFactory_Release(factory
);
4117 static INT32
get_gdi_font_advance(HDC hdc
, FLOAT emsize
)
4124 memset(&logfont
, 0, sizeof(logfont
));
4125 logfont
.lfHeight
= (LONG
)-emsize
;
4126 logfont
.lfWeight
= FW_NORMAL
;
4127 logfont
.lfQuality
= CLEARTYPE_QUALITY
;
4128 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
4130 hfont
= CreateFontIndirectW(&logfont
);
4131 SelectObject(hdc
, hfont
);
4133 ret
= GetCharABCWidthsW(hdc
, 'A', 'A', &abc
);
4134 ok(ret
, "got %d\n", ret
);
4136 DeleteObject(hfont
);
4138 return abc
.abcA
+ abc
.abcB
+ abc
.abcC
;
4141 static void test_GetGdiCompatibleGlyphAdvances(void)
4143 IDWriteFontFace1
*fontface1
;
4144 IDWriteFontFace
*fontface
;
4145 IDWriteFactory
*factory
;
4152 DWRITE_FONT_METRICS1 fm
;
4155 factory
= create_factory();
4156 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
4158 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4159 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4160 IDWriteFont_Release(font
);
4162 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4163 IDWriteFontFace_Release(fontface
);
4166 IDWriteFactory_Release(factory
);
4167 win_skip("GetGdiCompatibleGlyphAdvances() is not supported\n");
4173 hr
= IDWriteFontFace1_GetGlyphIndices(fontface1
, &codepoint
, 1, &glyph
);
4174 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4175 ok(glyph
> 0, "got %u\n", glyph
);
4179 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 0.0,
4180 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4181 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4182 ok(advance
== 0, "got %d\n", advance
);
4184 /* negative emsize */
4186 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, -1.0,
4187 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4188 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4189 ok(advance
== 0, "got %d\n", advance
);
4193 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 1.0,
4194 0.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4195 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4196 ok(advance
== 0, "got %d\n", advance
);
4198 /* negative ppdip */
4200 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 1.0,
4201 -1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4202 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4203 ok(advance
== 0, "got %d\n", advance
);
4205 IDWriteFontFace1_GetMetrics(fontface1
, &fm
);
4207 hdc
= CreateCompatibleDC(0);
4209 for (emsize
= 1.0; emsize
<= fm
.designUnitsPerEm
; emsize
+= 1.0) {
4212 gdi_advance
= get_gdi_font_advance(hdc
, emsize
);
4213 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, emsize
,
4214 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4215 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4217 /* advance is in design units */
4218 advance
= (int)floorf(emsize
* advance
/ fm
.designUnitsPerEm
+ 0.5f
);
4219 ok((advance
- gdi_advance
) <= 2, "%.0f: got advance %d, expected %d\n", emsize
, advance
, gdi_advance
);
4224 IDWriteFactory_Release(factory
);
4227 static WORD
get_gasp_flags(IDWriteFontFace
*fontface
, FLOAT emsize
)
4229 WORD num_recs
, version
;
4238 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_GASP_TAG
,
4239 (const void**)&ptr
, &size
, &ctxt
, &exists
);
4240 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4245 version
= GET_BE_WORD( *ptr
++ );
4246 num_recs
= GET_BE_WORD( *ptr
++ );
4247 if (version
> 1 || size
< (num_recs
* 2 + 2) * sizeof(WORD
)) {
4248 ok(0, "unsupported gasp table: ver %d size %d recs %d\n", version
, size
, num_recs
);
4254 flags
= GET_BE_WORD( *(ptr
+ 1) );
4255 if (emsize
<= GET_BE_WORD( *ptr
)) break;
4260 IDWriteFontFace_ReleaseFontTable(fontface
, ctxt
);
4264 #define GASP_GRIDFIT 0x0001
4265 #define GASP_DOGRAY 0x0002
4266 #define GASP_SYMMETRIC_GRIDFIT 0x0004
4267 #define GASP_SYMMETRIC_SMOOTHING 0x0008
4269 static BOOL g_is_vista
;
4270 static DWRITE_RENDERING_MODE
get_expected_rendering_mode(FLOAT emsize
, WORD gasp
, DWRITE_MEASURING_MODE mode
,
4271 DWRITE_OUTLINE_THRESHOLD threshold
)
4273 static const FLOAT aa_threshold
= 100.0f
;
4274 static const FLOAT a_threshold
= 350.0f
;
4275 static const FLOAT naturalemsize
= 20.0f
;
4278 /* outline threshold */
4280 v
= mode
== DWRITE_MEASURING_MODE_NATURAL
? aa_threshold
: a_threshold
;
4282 v
= threshold
== DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
? aa_threshold
: a_threshold
;
4285 return DWRITE_RENDERING_MODE_OUTLINE
;
4289 case DWRITE_MEASURING_MODE_NATURAL
:
4290 if (!(gasp
& GASP_SYMMETRIC_SMOOTHING
) && (emsize
<= naturalemsize
))
4291 return DWRITE_RENDERING_MODE_NATURAL
;
4293 return DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
;
4294 case DWRITE_MEASURING_MODE_GDI_CLASSIC
:
4295 return DWRITE_RENDERING_MODE_GDI_CLASSIC
;
4296 case DWRITE_MEASURING_MODE_GDI_NATURAL
:
4297 return DWRITE_RENDERING_MODE_GDI_NATURAL
;
4302 /* should be unreachable */
4303 return DWRITE_RENDERING_MODE_DEFAULT
;
4306 static DWRITE_GRID_FIT_MODE
get_expected_gridfit_mode(FLOAT emsize
, WORD gasp
, DWRITE_MEASURING_MODE mode
,
4307 DWRITE_OUTLINE_THRESHOLD threshold
)
4309 static const FLOAT aa_threshold
= 100.0f
;
4310 static const FLOAT a_threshold
= 350.0f
;
4313 v
= threshold
== DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
? aa_threshold
: a_threshold
;
4315 return DWRITE_GRID_FIT_MODE_DISABLED
;
4317 if (mode
== DWRITE_MEASURING_MODE_GDI_CLASSIC
|| mode
== DWRITE_MEASURING_MODE_GDI_NATURAL
)
4318 return DWRITE_GRID_FIT_MODE_ENABLED
;
4320 return (gasp
& (GASP_GRIDFIT
|GASP_SYMMETRIC_GRIDFIT
)) ? DWRITE_GRID_FIT_MODE_ENABLED
: DWRITE_GRID_FIT_MODE_DISABLED
;
4323 struct recommendedmode_test
4325 DWRITE_MEASURING_MODE measuring
;
4326 DWRITE_OUTLINE_THRESHOLD threshold
;
4329 static const struct recommendedmode_test recmode_tests
[] = {
4330 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4331 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4332 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4335 static const struct recommendedmode_test recmode_tests1
[] = {
4336 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4337 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4338 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4339 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
4340 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
4341 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
4344 static void test_GetRecommendedRenderingMode(void)
4346 IDWriteRenderingParams
*params
;
4347 IDWriteFontFace2
*fontface2
;
4348 IDWriteFontFace1
*fontface1
;
4349 IDWriteFontFace
*fontface
;
4350 DWRITE_RENDERING_MODE mode
;
4351 IDWriteFactory
*factory
;
4355 factory
= create_factory();
4356 fontface
= create_fontface(factory
);
4359 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4361 win_skip("IDWriteFontFace1::GetRecommendedRenderingMode() is not supported.\n");
4364 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
4366 win_skip("IDWriteFontFace2::GetRecommendedRenderingMode() is not supported.\n");
4368 if (0) /* crashes on native */
4369 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 3.0, 1.0,
4370 DWRITE_MEASURING_MODE_GDI_CLASSIC
, NULL
, NULL
);
4373 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 3.0, 1.0,
4374 DWRITE_MEASURING_MODE_GDI_CLASSIC
, NULL
, &mode
);
4375 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4376 ok(mode
== DWRITE_RENDERING_MODE_DEFAULT
, "got %d\n", mode
);
4378 hr
= IDWriteFactory_CreateRenderingParams(factory
, ¶ms
);
4379 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4381 /* detect old dwrite version, that is using higher threshold value */
4382 g_is_vista
= fontface1
== NULL
;
4384 for (emsize
= 1.0; emsize
< 500.0; emsize
+= 1.0) {
4385 WORD gasp
= get_gasp_flags(fontface
, emsize
);
4386 DWRITE_RENDERING_MODE expected
;
4389 for (i
= 0; i
< sizeof(recmode_tests
)/sizeof(recmode_tests
[0]); i
++) {
4391 expected
= get_expected_rendering_mode(emsize
, gasp
, recmode_tests
[i
].measuring
, recmode_tests
[i
].threshold
);
4392 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, emsize
, 1.0, recmode_tests
[i
].measuring
, params
, &mode
);
4393 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4394 ok(mode
== expected
, "%.2f/%d: got %d, flags 0x%04x, expected %d\n", emsize
, i
, mode
, gasp
, expected
);
4397 /* IDWriteFontFace1 offers another variant of this method */
4399 for (i
= 0; i
< sizeof(recmode_tests1
)/sizeof(recmode_tests1
[0]); i
++) {
4401 expected
= get_expected_rendering_mode(emsize
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
4402 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, 96.0, 96.0,
4403 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
4404 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4405 ok(mode
== expected
, "%.2f/%d: got %d, flags 0x%04x, expected %d\n", emsize
, i
, mode
, gasp
, expected
);
4409 /* IDWriteFontFace2 - another one */
4411 DWRITE_GRID_FIT_MODE gridfit
, expected_gridfit
;
4413 for (i
= 0; i
< sizeof(recmode_tests1
)/sizeof(recmode_tests1
[0]); i
++) {
4415 expected
= get_expected_rendering_mode(emsize
, gasp
, recmode_tests1
[0].measuring
, recmode_tests1
[0].threshold
);
4416 expected_gridfit
= get_expected_gridfit_mode(emsize
, gasp
, recmode_tests1
[0].measuring
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
);
4417 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, emsize
, 96.0, 96.0,
4418 NULL
, FALSE
, recmode_tests1
[0].threshold
, recmode_tests1
[0].measuring
, params
, &mode
, &gridfit
);
4419 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4420 ok(mode
== expected
, "%.2f: got %d, flags 0x%04x, expected %d\n", emsize
, mode
, gasp
, expected
);
4421 ok(gridfit
== expected_gridfit
, "%.2f/%d: gridfit: got %d, flags 0x%04x, expected %d\n", emsize
, i
, gridfit
,
4422 gasp
, expected_gridfit
);
4427 IDWriteRenderingParams_Release(params
);
4429 /* test how parameters override returned modes */
4430 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 1.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT
,
4431 DWRITE_RENDERING_MODE_GDI_CLASSIC
, ¶ms
);
4432 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4435 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 500.0, 1.0, DWRITE_MEASURING_MODE_NATURAL
, params
, &mode
);
4436 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4437 ok(mode
== DWRITE_RENDERING_MODE_GDI_CLASSIC
, "got %d\n", mode
);
4439 IDWriteRenderingParams_Release(params
);
4442 IDWriteRenderingParams2
*params2
;
4443 IDWriteFactory2
*factory2
;
4444 DWRITE_GRID_FIT_MODE gridfit
;
4446 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory2
, (void**)&factory2
);
4447 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4449 hr
= IDWriteFactory2_CreateCustomRenderingParams(factory2
, 1.0, 0.0, 0.0, 0.5, DWRITE_PIXEL_GEOMETRY_FLAT
,
4450 DWRITE_RENDERING_MODE_OUTLINE
, DWRITE_GRID_FIT_MODE_ENABLED
, ¶ms2
);
4451 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4455 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, 5.0, 96.0, 96.0,
4456 NULL
, FALSE
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
4457 NULL
, &mode
, &gridfit
);
4458 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4459 ok(mode
== DWRITE_RENDERING_MODE_GDI_CLASSIC
, "got %d\n", mode
);
4460 ok(gridfit
== DWRITE_GRID_FIT_MODE_ENABLED
, "got %d\n", gridfit
);
4464 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, 5.0, 96.0, 96.0,
4465 NULL
, FALSE
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
4466 (IDWriteRenderingParams
*)params2
, &mode
, &gridfit
);
4467 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4468 ok(mode
== DWRITE_RENDERING_MODE_OUTLINE
, "got %d\n", mode
);
4469 ok(gridfit
== DWRITE_GRID_FIT_MODE_ENABLED
, "got %d\n", gridfit
);
4471 IDWriteRenderingParams2_Release(params2
);
4472 IDWriteFactory2_Release(factory2
);
4476 IDWriteFontFace2_Release(fontface2
);
4478 IDWriteFontFace1_Release(fontface1
);
4479 IDWriteFontFace_Release(fontface
);
4480 IDWriteFactory_Release(factory
);
4483 static inline BOOL
float_eq(FLOAT left
, FLOAT right
)
4485 int x
= *(int *)&left
;
4486 int y
= *(int *)&right
;
4493 return abs(x
- y
) <= 8;
4496 static void test_GetAlphaBlendParams(void)
4498 static const DWRITE_RENDERING_MODE rendermodes
[] = {
4499 DWRITE_RENDERING_MODE_ALIASED
,
4500 DWRITE_RENDERING_MODE_GDI_CLASSIC
,
4501 DWRITE_RENDERING_MODE_GDI_NATURAL
,
4502 DWRITE_RENDERING_MODE_NATURAL
,
4503 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
,
4506 IDWriteGlyphRunAnalysis
*analysis
;
4507 FLOAT gamma
, contrast
, ctlevel
;
4508 IDWriteRenderingParams
*params
;
4509 DWRITE_GLYPH_METRICS metrics
;
4510 DWRITE_GLYPH_OFFSET offset
;
4511 IDWriteFontFace
*fontface
;
4512 IDWriteFactory
*factory
;
4513 DWRITE_GLYPH_RUN run
;
4514 FLOAT advance
, expected_gdi_gamma
;
4521 factory
= create_factory();
4522 fontface
= create_fontface(factory
);
4526 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &ch
, 1, &glyph
);
4527 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4528 ok(glyph
> 0, "got %u\n", glyph
);
4530 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, &glyph
, 1, &metrics
, FALSE
);
4531 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4532 advance
= metrics
.advanceWidth
;
4534 offset
.advanceOffset
= 0.0;
4535 offset
.ascenderOffset
= 0.0;
4537 run
.fontFace
= fontface
;
4538 run
.fontEmSize
= 24.0;
4540 run
.glyphIndices
= &glyph
;
4541 run
.glyphAdvances
= &advance
;
4542 run
.glyphOffsets
= &offset
;
4543 run
.isSideways
= FALSE
;
4546 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 0.9, 0.3, 0.1, DWRITE_PIXEL_GEOMETRY_RGB
,
4547 DWRITE_RENDERING_MODE_DEFAULT
, ¶ms
);
4548 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4551 ret
= SystemParametersInfoW(SPI_GETFONTSMOOTHINGCONTRAST
, 0, &value
, 0);
4552 ok(ret
, "got %d\n", ret
);
4553 expected_gdi_gamma
= (FLOAT
)(value
/ 1000.0);
4555 for (i
= 0; i
< sizeof(rendermodes
)/sizeof(rendermodes
[0]); i
++) {
4556 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4557 rendermodes
[i
], DWRITE_MEASURING_MODE_NATURAL
,
4558 0.0, 0.0, &analysis
);
4559 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4561 gamma
= contrast
= ctlevel
= -1.0;
4562 hr
= IDWriteGlyphRunAnalysis_GetAlphaBlendParams(analysis
, NULL
, &gamma
, &contrast
, &ctlevel
);
4563 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4564 ok(gamma
== -1.0, "got %.2f\n", gamma
);
4565 ok(contrast
== -1.0, "got %.2f\n", contrast
);
4566 ok(ctlevel
== -1.0, "got %.2f\n", ctlevel
);
4568 gamma
= contrast
= ctlevel
= -1.0;
4569 hr
= IDWriteGlyphRunAnalysis_GetAlphaBlendParams(analysis
, params
, &gamma
, &contrast
, &ctlevel
);
4570 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4572 if (rendermodes
[i
] == DWRITE_RENDERING_MODE_GDI_CLASSIC
|| rendermodes
[i
] == DWRITE_RENDERING_MODE_GDI_NATURAL
) {
4573 ok(float_eq(gamma
, expected_gdi_gamma
), "got %.2f, expected %.2f\n", gamma
, expected_gdi_gamma
);
4574 ok(contrast
== 0.0f
, "got %.2f\n", contrast
);
4575 ok(ctlevel
== 1.0f
, "got %.2f\n", ctlevel
);
4578 ok(gamma
== 0.9f
, "got %.2f\n", gamma
);
4579 ok(contrast
== 0.3f
, "got %.2f\n", contrast
);
4580 ok(ctlevel
== 0.1f
, "got %.2f\n", ctlevel
);
4583 IDWriteGlyphRunAnalysis_Release(analysis
);
4586 IDWriteRenderingParams_Release(params
);
4587 IDWriteFontFace_Release(fontface
);
4588 IDWriteFactory_Release(factory
);
4591 static void test_CreateAlphaTexture(void)
4593 IDWriteGlyphRunAnalysis
*analysis
;
4594 DWRITE_GLYPH_METRICS metrics
;
4595 DWRITE_GLYPH_OFFSET offset
;
4596 IDWriteFontFace
*fontface
;
4597 IDWriteFactory
*factory
;
4598 DWRITE_GLYPH_RUN run
;
4606 factory
= create_factory();
4607 fontface
= create_fontface(factory
);
4611 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &ch
, 1, &glyph
);
4612 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4613 ok(glyph
> 0, "got %u\n", glyph
);
4615 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, &glyph
, 1, &metrics
, FALSE
);
4616 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4617 advance
= metrics
.advanceWidth
;
4619 offset
.advanceOffset
= 0.0;
4620 offset
.ascenderOffset
= 0.0;
4622 run
.fontFace
= fontface
;
4623 run
.fontEmSize
= 24.0;
4625 run
.glyphIndices
= &glyph
;
4626 run
.glyphAdvances
= &advance
;
4627 run
.glyphOffsets
= &offset
;
4628 run
.isSideways
= FALSE
;
4631 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4632 DWRITE_RENDERING_MODE_NATURAL
, DWRITE_MEASURING_MODE_NATURAL
,
4633 0.0, 0.0, &analysis
);
4634 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4636 SetRectEmpty(&bounds
);
4637 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &bounds
);
4638 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4639 ok(!IsRectEmpty(&bounds
), "got empty rect\n");
4640 size
= (bounds
.right
- bounds
.left
)*(bounds
.bottom
- bounds
.top
)*3;
4641 ok(sizeof(buff
) >= size
, "required %u\n", size
);
4643 /* invalid type value */
4644 memset(buff
, 0xcf, sizeof(buff
));
4645 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
+1, &bounds
, buff
, sizeof(buff
));
4646 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4647 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4649 memset(buff
, 0xcf, sizeof(buff
));
4650 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
, buff
, 2);
4651 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
4652 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4654 /* vista version allows texture type mismatch, mark it broken for now */
4655 memset(buff
, 0xcf, sizeof(buff
));
4656 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
, buff
, sizeof(buff
));
4657 ok(hr
== DWRITE_E_UNSUPPORTEDOPERATION
|| broken(hr
== S_OK
), "got 0x%08x\n", hr
);
4658 ok(buff
[0] == 0xcf || broken(buff
[0] == 0), "got %1x\n", buff
[0]);
4660 memset(buff
, 0xcf, sizeof(buff
));
4661 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &bounds
, buff
, size
-1);
4662 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
4663 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4665 IDWriteGlyphRunAnalysis_Release(analysis
);
4667 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4668 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
4669 0.0, 0.0, &analysis
);
4670 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4672 SetRectEmpty(&bounds
);
4673 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
);
4674 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4675 ok(!IsRectEmpty(&bounds
), "got empty rect\n");
4676 size
= (bounds
.right
- bounds
.left
)*(bounds
.bottom
- bounds
.top
);
4677 ok(sizeof(buff
) >= size
, "required %u\n", size
);
4679 memset(buff
, 0xcf, sizeof(buff
));
4680 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, NULL
, buff
, sizeof(buff
));
4681 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4682 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4684 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, NULL
, NULL
, sizeof(buff
));
4685 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4687 memset(buff
, 0xcf, sizeof(buff
));
4688 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, NULL
, buff
, 0);
4689 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4690 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4692 /* buffer size is not enough */
4693 memset(buff
, 0xcf, sizeof(buff
));
4694 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
, buff
, size
-1);
4695 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
4696 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4698 /* request texture for rectangle that doesn't intersect */
4699 memset(buff
, 0xcf, sizeof(buff
));
4701 OffsetRect(&r
, (bounds
.right
- bounds
.left
)*2, 0);
4702 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &r
, buff
, sizeof(buff
));
4703 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4704 ok(buff
[0] == 0, "got %1x\n", buff
[0]);
4706 memset(buff
, 0xcf, sizeof(buff
));
4708 OffsetRect(&r
, (bounds
.right
- bounds
.left
)*2, 0);
4709 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &r
, buff
, sizeof(buff
));
4710 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4711 ok(buff
[0] == 0, "got %1x\n", buff
[0]);
4713 /* request texture for rectangle that doesn't intersect, small buffer */
4714 memset(buff
, 0xcf, sizeof(buff
));
4716 OffsetRect(&r
, (bounds
.right
- bounds
.left
)*2, 0);
4717 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &r
, buff
, size
-1);
4718 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
4719 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
4721 /* vista version allows texture type mismatch, mark it broken for now */
4722 memset(buff
, 0xcf, sizeof(buff
));
4723 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &bounds
, buff
, sizeof(buff
));
4724 ok(hr
== DWRITE_E_UNSUPPORTEDOPERATION
|| broken(hr
== S_OK
), "got 0x%08x\n", hr
);
4725 ok(buff
[0] == 0xcf || broken(buff
[0] == 0), "got %1x\n", buff
[0]);
4727 IDWriteGlyphRunAnalysis_Release(analysis
);
4728 IDWriteFontFace_Release(fontface
);
4729 IDWriteFactory_Release(factory
);
4732 static void test_IsSymbolFont(void)
4734 static const WCHAR symbolW
[] = {'S','y','m','b','o','l',0};
4735 IDWriteFontCollection
*collection
;
4736 IDWriteFontFace
*fontface
;
4737 IDWriteFactory
*factory
;
4742 factory
= create_factory();
4745 fontface
= create_fontface(factory
);
4746 ret
= IDWriteFontFace_IsSymbolFont(fontface
);
4747 ok(!ret
, "got %d\n", ret
);
4749 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
4750 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4752 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font
);
4753 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4755 ret
= IDWriteFont_IsSymbolFont(font
);
4756 ok(!ret
, "got %d\n", ret
);
4758 IDWriteFontCollection_Release(collection
);
4759 IDWriteFont_Release(font
);
4760 IDWriteFontFace_Release(fontface
);
4763 font
= get_font(factory
, symbolW
, DWRITE_FONT_STYLE_NORMAL
);
4764 ret
= IDWriteFont_IsSymbolFont(font
);
4765 ok(ret
, "got %d\n", ret
);
4767 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4768 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4769 ret
= IDWriteFontFace_IsSymbolFont(fontface
);
4770 ok(ret
, "got %d\n", ret
);
4771 IDWriteFont_Release(font
);
4773 IDWriteFactory_Release(factory
);
4776 struct CPAL_Header_0
4779 USHORT numPaletteEntries
;
4781 USHORT numColorRecords
;
4782 ULONG offsetFirstColorRecord
;
4783 USHORT colorRecordIndices
[1];
4786 static void test_GetPaletteEntries(void)
4788 static const WCHAR emojiW
[] = {'S','e','g','o','e',' ','U','I',' ','E','m','o','j','i',0};
4789 IDWriteFontFace2
*fontface2
;
4790 IDWriteFontFace
*fontface
;
4791 IDWriteFactory
*factory
;
4793 DWRITE_COLOR_F color
;
4794 UINT32 palettecount
, entrycount
, size
, colorrecords
;
4796 const struct CPAL_Header_0
*cpal_header
;
4800 factory
= create_factory();
4802 /* Tahoma, no color support */
4803 fontface
= create_fontface(factory
);
4804 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
4805 IDWriteFontFace_Release(fontface
);
4807 IDWriteFactory_Release(factory
);
4808 win_skip("GetPaletteEntries() is not supported.\n");
4812 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, 0, 1, &color
);
4813 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
4814 IDWriteFontFace2_Release(fontface2
);
4816 /* Segoe UI Emoji, with color support */
4817 font
= get_font(factory
, emojiW
, DWRITE_FONT_STYLE_NORMAL
);
4819 IDWriteFactory_Release(factory
);
4820 skip("Segoe UI Emoji font not found.\n");
4824 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4825 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4826 IDWriteFont_Release(font
);
4828 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
4829 IDWriteFontFace_Release(fontface
);
4831 palettecount
= IDWriteFontFace2_GetColorPaletteCount(fontface2
);
4832 ok(palettecount
>= 1, "got %u\n", palettecount
);
4834 entrycount
= IDWriteFontFace2_GetPaletteEntryCount(fontface2
);
4835 ok(entrycount
>= 1, "got %u\n", entrycount
);
4838 hr
= IDWriteFontFace2_TryGetFontTable(fontface2
, MS_CPAL_TAG
, (const void**)&cpal_header
, &size
, &ctxt
, &exists
);
4839 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4840 ok(exists
, "got %d\n", exists
);
4841 colorrecords
= GET_BE_WORD(cpal_header
->numColorRecords
);
4842 ok(colorrecords
>= 1, "got %u\n", colorrecords
);
4844 /* invalid palette index */
4845 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
4846 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, palettecount
, 0, 1, &color
);
4847 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
4848 ok(color
.r
== 123.0 && color
.g
== 123.0 && color
.b
== 123.0 && color
.a
== 123.0,
4849 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
4851 /* invalid entry index */
4852 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
4853 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, entrycount
, 1, &color
);
4854 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4855 ok(color
.r
== 123.0 && color
.g
== 123.0 && color
.b
== 123.0 && color
.a
== 123.0,
4856 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
4858 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
4859 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, entrycount
- 1, 1, &color
);
4860 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4861 ok(color
.r
!= 123.0 && color
.g
!= 123.0 && color
.b
!= 123.0 && color
.a
!= 123.0,
4862 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
4864 /* zero return length */
4865 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
4866 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, 0, 0, &color
);
4867 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4868 ok(color
.r
== 123.0 && color
.g
== 123.0 && color
.b
== 123.0 && color
.a
== 123.0,
4869 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
4871 IDWriteFontFace2_Release(fontface2
);
4872 IDWriteFactory_Release(factory
);
4877 IDWriteFactory
*factory
;
4879 if (!(factory
= create_factory())) {
4880 win_skip("failed to create factory\n");
4884 test_CreateFontFromLOGFONT();
4885 test_CreateBitmapRenderTarget();
4886 test_GetFontFamily();
4887 test_GetFamilyNames();
4888 test_CreateFontFace();
4890 test_system_fontcollection();
4891 test_ConvertFontFaceToLOGFONT();
4892 test_CustomFontCollection();
4893 test_CreateCustomFontFileReference();
4894 test_CreateFontFileReference();
4895 test_shared_isolated();
4896 test_GetUnicodeRanges();
4897 test_GetFontFromFontFace();
4898 test_GetFirstMatchingFont();
4899 test_GetInformationalStrings();
4900 test_GetGdiInterop();
4901 test_CreateFontFaceFromHdc();
4902 test_GetSimulations();
4903 test_GetFaceNames();
4904 test_TryGetFontTable();
4905 test_ConvertFontToLOGFONT();
4906 test_CreateStreamFromKey();
4907 test_ReadFileFragment();
4908 test_GetDesignGlyphMetrics();
4909 test_GetDesignGlyphAdvances();
4910 test_IsMonospacedFont();
4911 test_GetGlyphRunOutline();
4912 test_GetEudcFontCollection();
4913 test_GetCaretMetrics();
4914 test_GetGlyphCount();
4915 test_GetKerningPairAdjustments();
4916 test_CreateRenderingParams();
4917 test_CreateGlyphRunAnalysis();
4918 test_GetGdiCompatibleMetrics();
4920 test_GetGdiCompatibleGlyphAdvances();
4921 test_GetRecommendedRenderingMode();
4922 test_GetAlphaBlendParams();
4923 test_CreateAlphaTexture();
4924 test_IsSymbolFont();
4925 test_GetPaletteEntries();
4927 IDWriteFactory_Release(factory
);