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
32 #include "wine/test.h"
34 #define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
35 ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
36 ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
38 #define MS_CMAP_TAG MS_MAKE_TAG('c','m','a','p')
39 #define MS_VDMX_TAG MS_MAKE_TAG('V','D','M','X')
40 #define MS_GASP_TAG MS_MAKE_TAG('g','a','s','p')
42 #define EXPECT_HR(hr,hr_exp) \
43 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
45 #define DEFINE_EXPECT(func) \
46 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
48 #define SET_EXPECT(func) \
49 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
51 #define CHECK_EXPECT2(func) \
53 ok(expect_ ##func, "unexpected call " #func "\n"); \
54 called_ ## func = TRUE; \
57 #define CHECK_EXPECT(func) \
59 CHECK_EXPECT2(func); \
60 expect_ ## func = FALSE; \
63 #define CHECK_CALLED(func) \
65 ok(called_ ## func, "expected " #func "\n"); \
66 expect_ ## func = called_ ## func = FALSE; \
69 #define CLEAR_CALLED(func) \
70 expect_ ## func = called_ ## func = FALSE
72 DEFINE_EXPECT(setfillmode
);
74 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
75 static void _expect_ref(IUnknown
* obj
, ULONG ref
, int line
)
79 rc
= IUnknown_Release(obj
);
80 ok_(__FILE__
,line
)(rc
== ref
, "expected refcount %d, got %d\n", ref
, rc
);
83 static inline void *heap_alloc(size_t len
)
85 return HeapAlloc(GetProcessHeap(), 0, len
);
88 static inline BOOL
heap_free(void *mem
)
90 return HeapFree(GetProcessHeap(), 0, mem
);
93 static const WCHAR test_fontfile
[] = {'w','i','n','e','_','t','e','s','t','_','f','o','n','t','.','t','t','f',0};
94 static const WCHAR tahomaW
[] = {'T','a','h','o','m','a',0};
95 static const WCHAR arialW
[] = {'A','r','i','a','l',0};
96 static const WCHAR tahomaUppercaseW
[] = {'T','A','H','O','M','A',0};
97 static const WCHAR tahomaStrangecaseW
[] = {'t','A','h','O','m','A',0};
98 static const WCHAR blahW
[] = {'B','l','a','h','!',0};
100 static IDWriteFactory
*create_factory(void)
102 IDWriteFactory
*factory
;
103 HRESULT hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory
);
104 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
108 static IDWriteFontFace
*create_fontface(IDWriteFactory
*factory
)
110 static const WCHAR tahomaW
[] = {'T','a','h','o','m','a',0};
111 IDWriteGdiInterop
*interop
;
112 IDWriteFontFace
*fontface
;
117 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
118 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
120 memset(&logfont
, 0, sizeof(logfont
));
121 logfont
.lfHeight
= 12;
122 logfont
.lfWidth
= 12;
123 logfont
.lfWeight
= FW_NORMAL
;
124 logfont
.lfItalic
= 1;
125 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
127 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
128 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
130 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
131 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
133 IDWriteFont_Release(font
);
134 IDWriteGdiInterop_Release(interop
);
139 static WCHAR
*create_testfontfile(const WCHAR
*filename
)
141 static WCHAR pathW
[MAX_PATH
];
147 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
148 lstrcatW(pathW
, filename
);
150 file
= CreateFileW(pathW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
151 ok(file
!= INVALID_HANDLE_VALUE
, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW
),
154 res
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
155 ok( res
!= 0, "couldn't find resource\n" );
156 ptr
= LockResource( LoadResource( GetModuleHandleA(NULL
), res
));
157 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleA(NULL
), res
), &written
, NULL
);
158 ok( written
== SizeofResource( GetModuleHandleA(NULL
), res
), "couldn't write resource\n" );
164 #define DELETE_FONTFILE(filename) _delete_testfontfile(filename, __LINE__)
165 static void _delete_testfontfile(const WCHAR
*filename
, int line
)
167 BOOL ret
= DeleteFileW(filename
);
168 ok_(__FILE__
,line
)(ret
, "failed to delete file %s, error %d\n", wine_dbgstr_w(filename
), GetLastError());
171 struct test_fontenumerator
173 IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface
;
177 IDWriteFontFile
*font_file
;
180 static inline struct test_fontenumerator
*impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator
* iface
)
182 return CONTAINING_RECORD(iface
, struct test_fontenumerator
, IDWriteFontFileEnumerator_iface
);
185 static HRESULT WINAPI
singlefontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
187 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
))
190 IDWriteFontFileEnumerator_AddRef(iface
);
193 return E_NOINTERFACE
;
196 static ULONG WINAPI
singlefontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
198 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
199 return InterlockedIncrement(&This
->ref
);
202 static ULONG WINAPI
singlefontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
204 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
205 ULONG ref
= InterlockedDecrement(&This
->ref
);
207 IDWriteFontFile_Release(This
->font_file
);
213 static HRESULT WINAPI
singlefontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**font_file
)
215 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
216 IDWriteFontFile_AddRef(This
->font_file
);
217 *font_file
= This
->font_file
;
221 static HRESULT WINAPI
singlefontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
223 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
225 if (This
->index
> 1) {
235 static const struct IDWriteFontFileEnumeratorVtbl singlefontfileenumeratorvtbl
=
237 singlefontfileenumerator_QueryInterface
,
238 singlefontfileenumerator_AddRef
,
239 singlefontfileenumerator_Release
,
240 singlefontfileenumerator_MoveNext
,
241 singlefontfileenumerator_GetCurrentFontFile
244 static HRESULT
create_enumerator(IDWriteFontFile
*font_file
, IDWriteFontFileEnumerator
**ret
)
246 struct test_fontenumerator
*enumerator
;
248 enumerator
= heap_alloc(sizeof(struct test_fontenumerator
));
250 return E_OUTOFMEMORY
;
252 enumerator
->IDWriteFontFileEnumerator_iface
.lpVtbl
= &singlefontfileenumeratorvtbl
;
254 enumerator
->index
= 0;
255 enumerator
->font_file
= font_file
;
256 IDWriteFontFile_AddRef(font_file
);
258 *ret
= &enumerator
->IDWriteFontFileEnumerator_iface
;
262 struct test_fontcollectionloader
264 IDWriteFontCollectionLoader IDWriteFontFileCollectionLoader_iface
;
265 IDWriteFontFileLoader
*loader
;
268 static inline struct test_fontcollectionloader
*impl_from_IDWriteFontFileCollectionLoader(IDWriteFontCollectionLoader
* iface
)
270 return CONTAINING_RECORD(iface
, struct test_fontcollectionloader
, IDWriteFontFileCollectionLoader_iface
);
273 static HRESULT WINAPI
resourcecollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
275 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontCollectionLoader
))
278 IDWriteFontCollectionLoader_AddRef(iface
);
281 return E_NOINTERFACE
;
284 static ULONG WINAPI
resourcecollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
289 static ULONG WINAPI
resourcecollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
294 static HRESULT WINAPI
resourcecollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
*factory
,
295 const void * collectionKey
, UINT32 collectionKeySize
, IDWriteFontFileEnumerator
** fontFileEnumerator
)
297 struct test_fontcollectionloader
*This
= impl_from_IDWriteFontFileCollectionLoader(iface
);
298 IDWriteFontFile
*font_file
;
301 IDWriteFactory_CreateCustomFontFileReference(factory
, collectionKey
, collectionKeySize
, This
->loader
, &font_file
);
303 hr
= create_enumerator(font_file
, fontFileEnumerator
);
304 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
306 IDWriteFontFile_Release(font_file
);
310 static const struct IDWriteFontCollectionLoaderVtbl resourcecollectionloadervtbl
= {
311 resourcecollectionloader_QueryInterface
,
312 resourcecollectionloader_AddRef
,
313 resourcecollectionloader_Release
,
314 resourcecollectionloader_CreateEnumeratorFromKey
317 /* Here is a functional custom font set of interfaces */
318 struct test_fontdatastream
320 IDWriteFontFileStream IDWriteFontFileStream_iface
;
327 static inline struct test_fontdatastream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
* iface
)
329 return CONTAINING_RECORD(iface
, struct test_fontdatastream
, IDWriteFontFileStream_iface
);
332 static HRESULT WINAPI
fontdatastream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
334 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
337 IDWriteFontFileStream_AddRef(iface
);
341 return E_NOINTERFACE
;
344 static ULONG WINAPI
fontdatastream_AddRef(IDWriteFontFileStream
*iface
)
346 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
347 ULONG ref
= InterlockedIncrement(&This
->ref
);
351 static ULONG WINAPI
fontdatastream_Release(IDWriteFontFileStream
*iface
)
353 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
354 ULONG ref
= InterlockedDecrement(&This
->ref
);
356 HeapFree(GetProcessHeap(), 0, This
);
360 static HRESULT WINAPI
fontdatastream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
362 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
363 *fragment_context
= NULL
;
364 if (offset
+fragment_size
> This
->size
)
366 *fragment_start
= NULL
;
371 *fragment_start
= (BYTE
*)This
->data
+ offset
;
376 static void WINAPI
fontdatastream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
381 static HRESULT WINAPI
fontdatastream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
383 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
388 static HRESULT WINAPI
fontdatastream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
393 static const IDWriteFontFileStreamVtbl fontdatastreamvtbl
=
395 fontdatastream_QueryInterface
,
396 fontdatastream_AddRef
,
397 fontdatastream_Release
,
398 fontdatastream_ReadFileFragment
,
399 fontdatastream_ReleaseFileFragment
,
400 fontdatastream_GetFileSize
,
401 fontdatastream_GetLastWriteTime
404 static HRESULT
create_fontdatastream(LPVOID data
, UINT size
, IDWriteFontFileStream
** iface
)
406 struct test_fontdatastream
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct test_fontdatastream
));
408 return E_OUTOFMEMORY
;
413 This
->IDWriteFontFileStream_iface
.lpVtbl
= &fontdatastreamvtbl
;
415 *iface
= &This
->IDWriteFontFileStream_iface
;
419 static HRESULT WINAPI
resourcefontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
421 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
427 return E_NOINTERFACE
;
430 static ULONG WINAPI
resourcefontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
435 static ULONG WINAPI
resourcefontfileloader_Release(IDWriteFontFileLoader
*iface
)
440 static HRESULT WINAPI
resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
446 mem
= LoadResource(GetModuleHandleA(NULL
), *(HRSRC
*)fontFileReferenceKey
);
447 ok(mem
!= NULL
, "Failed to lock font resource\n");
450 size
= SizeofResource(GetModuleHandleA(NULL
), *(HRSRC
*)fontFileReferenceKey
);
451 data
= LockResource(mem
);
452 return create_fontdatastream(data
, size
, fontFileStream
);
457 static const struct IDWriteFontFileLoaderVtbl resourcefontfileloadervtbl
= {
458 resourcefontfileloader_QueryInterface
,
459 resourcefontfileloader_AddRef
,
460 resourcefontfileloader_Release
,
461 resourcefontfileloader_CreateStreamFromKey
464 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
466 static D2D1_POINT_2F g_startpoints
[2];
467 static int g_startpoint_count
;
469 static HRESULT WINAPI
test_geometrysink_QueryInterface(ID2D1SimplifiedGeometrySink
*iface
, REFIID riid
, void **ret
)
471 if (IsEqualIID(riid
, &IID_ID2D1SimplifiedGeometrySink
) ||
472 IsEqualIID(riid
, &IID_IUnknown
))
475 ID2D1SimplifiedGeometrySink_AddRef(iface
);
480 return E_NOINTERFACE
;
483 static ULONG WINAPI
test_geometrysink_AddRef(ID2D1SimplifiedGeometrySink
*iface
)
488 static ULONG WINAPI
test_geometrysink_Release(ID2D1SimplifiedGeometrySink
*iface
)
493 static void WINAPI
test_geometrysink_SetFillMode(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FILL_MODE mode
)
495 CHECK_EXPECT(setfillmode
);
496 ok(mode
== D2D1_FILL_MODE_WINDING
, "fill mode %d\n", mode
);
499 static void WINAPI
test_geometrysink_SetSegmentFlags(ID2D1SimplifiedGeometrySink
*iface
, D2D1_PATH_SEGMENT flags
)
501 ok(0, "unexpected SetSegmentFlags() - flags %d\n", flags
);
504 static void WINAPI
test_geometrysink_BeginFigure(ID2D1SimplifiedGeometrySink
*iface
,
505 D2D1_POINT_2F startPoint
, D2D1_FIGURE_BEGIN figureBegin
)
507 ok(figureBegin
== D2D1_FIGURE_BEGIN_FILLED
, "begin figure %d\n", figureBegin
);
508 if (g_startpoint_count
< sizeof(g_startpoints
)/sizeof(g_startpoints
[0]))
509 g_startpoints
[g_startpoint_count
] = startPoint
;
510 g_startpoint_count
++;
513 static void WINAPI
test_geometrysink_AddLines(ID2D1SimplifiedGeometrySink
*iface
,
514 const D2D1_POINT_2F
*points
, UINT32 count
)
518 static void WINAPI
test_geometrysink_AddBeziers(ID2D1SimplifiedGeometrySink
*iface
,
519 const D2D1_BEZIER_SEGMENT
*beziers
, UINT32 count
)
523 static void WINAPI
test_geometrysink_EndFigure(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FIGURE_END figureEnd
)
525 ok(figureEnd
== D2D1_FIGURE_END_CLOSED
, "end figure %d\n", figureEnd
);
528 static HRESULT WINAPI
test_geometrysink_Close(ID2D1SimplifiedGeometrySink
*iface
)
530 ok(0, "unexpected Close()\n");
534 static const ID2D1SimplifiedGeometrySinkVtbl test_geometrysink_vtbl
= {
535 test_geometrysink_QueryInterface
,
536 test_geometrysink_AddRef
,
537 test_geometrysink_Release
,
538 test_geometrysink_SetFillMode
,
539 test_geometrysink_SetSegmentFlags
,
540 test_geometrysink_BeginFigure
,
541 test_geometrysink_AddLines
,
542 test_geometrysink_AddBeziers
,
543 test_geometrysink_EndFigure
,
544 test_geometrysink_Close
547 static void WINAPI
test_geometrysink2_BeginFigure(ID2D1SimplifiedGeometrySink
*iface
,
548 D2D1_POINT_2F startPoint
, D2D1_FIGURE_BEGIN figureBegin
)
550 ok(0, "unexpected call\n");
553 static void WINAPI
test_geometrysink2_AddLines(ID2D1SimplifiedGeometrySink
*iface
,
554 const D2D1_POINT_2F
*points
, UINT32 count
)
556 ok(0, "unexpected call\n");
559 static void WINAPI
test_geometrysink2_AddBeziers(ID2D1SimplifiedGeometrySink
*iface
,
560 const D2D1_BEZIER_SEGMENT
*beziers
, UINT32 count
)
562 ok(0, "unexpected call\n");
565 static void WINAPI
test_geometrysink2_EndFigure(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FIGURE_END figureEnd
)
567 ok(0, "unexpected call\n");
570 static const ID2D1SimplifiedGeometrySinkVtbl test_geometrysink2_vtbl
= {
571 test_geometrysink_QueryInterface
,
572 test_geometrysink_AddRef
,
573 test_geometrysink_Release
,
574 test_geometrysink_SetFillMode
,
575 test_geometrysink_SetSegmentFlags
,
576 test_geometrysink2_BeginFigure
,
577 test_geometrysink2_AddLines
,
578 test_geometrysink2_AddBeziers
,
579 test_geometrysink2_EndFigure
,
580 test_geometrysink_Close
583 static ID2D1SimplifiedGeometrySink test_geomsink
= { &test_geometrysink_vtbl
};
584 static ID2D1SimplifiedGeometrySink test_geomsink2
= { &test_geometrysink2_vtbl
};
586 static void test_CreateFontFromLOGFONT(void)
588 static const WCHAR tahomaspW
[] = {'T','a','h','o','m','a',' ',0};
589 IDWriteGdiInterop
*interop
;
590 DWRITE_FONT_WEIGHT weight
;
591 DWRITE_FONT_STYLE style
;
594 LONG weights
[][2] = {
595 {FW_NORMAL
, DWRITE_FONT_WEIGHT_NORMAL
},
596 {FW_BOLD
, DWRITE_FONT_WEIGHT_BOLD
},
597 { 0, DWRITE_FONT_WEIGHT_NORMAL
},
598 { 50, DWRITE_FONT_WEIGHT_NORMAL
},
599 {150, DWRITE_FONT_WEIGHT_NORMAL
},
600 {250, DWRITE_FONT_WEIGHT_NORMAL
},
601 {350, DWRITE_FONT_WEIGHT_NORMAL
},
602 {450, DWRITE_FONT_WEIGHT_NORMAL
},
603 {650, DWRITE_FONT_WEIGHT_BOLD
},
604 {750, DWRITE_FONT_WEIGHT_BOLD
},
605 {850, DWRITE_FONT_WEIGHT_BOLD
},
606 {950, DWRITE_FONT_WEIGHT_BOLD
},
607 {960, DWRITE_FONT_WEIGHT_BOLD
},
609 OUTLINETEXTMETRICW otm
;
610 IDWriteFactory
*factory
;
619 factory
= create_factory();
621 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
625 /* null out parameter crashes this call */
626 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, NULL
);
628 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, &font
);
629 EXPECT_HR(hr
, E_INVALIDARG
);
631 memset(&logfont
, 0, sizeof(logfont
));
632 logfont
.lfHeight
= 12;
633 logfont
.lfWidth
= 12;
634 logfont
.lfWeight
= FW_NORMAL
;
635 logfont
.lfItalic
= 1;
636 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
638 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
641 hfont
= CreateFontIndirectW(&logfont
);
642 hdc
= CreateCompatibleDC(0);
643 SelectObject(hdc
, hfont
);
645 otm
.otmSize
= sizeof(otm
);
646 r
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
647 ok(r
, "got %d\n", r
);
652 hr
= IDWriteFont_HasCharacter(font
, 0xd800, &exists
);
653 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
654 ok(exists
== FALSE
, "got %d\n", exists
);
657 hr
= IDWriteFont_HasCharacter(font
, 0x20, &exists
);
658 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
659 ok(exists
== TRUE
, "got %d\n", exists
);
661 /* now check properties */
662 weight
= IDWriteFont_GetWeight(font
);
663 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
, "got %d\n", weight
);
665 style
= IDWriteFont_GetStyle(font
);
666 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %d\n", style
);
668 ok(otm
.otmfsSelection
== 1, "got 0x%08x\n", otm
.otmfsSelection
);
670 ret
= IDWriteFont_IsSymbolFont(font
);
671 ok(!ret
, "got %d\n", ret
);
673 IDWriteFont_Release(font
);
676 for (i
= 0; i
< sizeof(weights
)/(2*sizeof(LONG
)); i
++)
678 memset(&logfont
, 0, sizeof(logfont
));
679 logfont
.lfHeight
= 12;
680 logfont
.lfWidth
= 12;
681 logfont
.lfWeight
= weights
[i
][0];
682 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
684 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
687 weight
= IDWriteFont_GetWeight(font
);
688 ok(weight
== weights
[i
][1],
689 "%d: got %d, expected %d\n", i
, weight
, weights
[i
][1]);
691 IDWriteFont_Release(font
);
694 /* weight not from enum */
695 memset(&logfont
, 0, sizeof(logfont
));
696 logfont
.lfHeight
= 12;
697 logfont
.lfWidth
= 12;
698 logfont
.lfWeight
= 550;
699 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
702 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
703 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
705 weight
= IDWriteFont_GetWeight(font
);
706 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
|| broken(weight
== DWRITE_FONT_WEIGHT_BOLD
) /* win7 w/o SP */,
708 IDWriteFont_Release(font
);
710 /* empty or nonexistent face name */
711 memset(&logfont
, 0, sizeof(logfont
));
712 logfont
.lfHeight
= 12;
713 logfont
.lfWidth
= 12;
714 logfont
.lfWeight
= FW_NORMAL
;
715 lstrcpyW(logfont
.lfFaceName
, blahW
);
717 font
= (void*)0xdeadbeef;
718 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
719 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
720 ok(font
== NULL
, "got %p\n", font
);
722 /* Try with name 'Tahoma ' */
723 memset(&logfont
, 0, sizeof(logfont
));
724 logfont
.lfHeight
= 12;
725 logfont
.lfWidth
= 12;
726 logfont
.lfWeight
= FW_NORMAL
;
727 lstrcpyW(logfont
.lfFaceName
, tahomaspW
);
729 font
= (void*)0xdeadbeef;
730 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
731 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
732 ok(font
== NULL
, "got %p\n", font
);
734 /* empty string as a facename */
735 memset(&logfont
, 0, sizeof(logfont
));
736 logfont
.lfHeight
= 12;
737 logfont
.lfWidth
= 12;
738 logfont
.lfWeight
= FW_NORMAL
;
740 font
= (void*)0xdeadbeef;
741 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
742 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
743 ok(font
== NULL
, "got %p\n", font
);
745 IDWriteGdiInterop_Release(interop
);
746 IDWriteFactory_Release(factory
);
749 static void test_CreateBitmapRenderTarget(void)
751 IDWriteBitmapRenderTarget
*target
, *target2
;
752 IDWriteBitmapRenderTarget1
*target1
;
753 IDWriteGdiInterop
*interop
;
754 IDWriteFactory
*factory
;
765 factory
= create_factory();
767 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
771 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target
);
774 if (0) /* crashes on native */
775 hr
= IDWriteBitmapRenderTarget_GetSize(target
, NULL
);
777 size
.cx
= size
.cy
= -1;
778 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
780 ok(size
.cx
== 0, "got %d\n", size
.cx
);
781 ok(size
.cy
== 0, "got %d\n", size
.cy
);
784 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target2
);
786 ok(target
!= target2
, "got %p, %p\n", target2
, target
);
787 IDWriteBitmapRenderTarget_Release(target2
);
789 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
790 ok(hdc
!= NULL
, "got %p\n", hdc
);
792 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
793 ok(hbm
!= NULL
, "got %p\n", hbm
);
795 /* check DIB properties */
796 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
797 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
798 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
799 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
800 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
801 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
802 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
804 IDWriteBitmapRenderTarget_Release(target
);
806 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
807 ok(!hbm
, "got %p\n", hbm
);
810 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 10, 5, &target
);
813 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
814 ok(hdc
!= NULL
, "got %p\n", hdc
);
816 /* test context settings */
817 c
= GetTextColor(hdc
);
818 ok(c
== RGB(0, 0, 0), "got 0x%08x\n", c
);
819 ret
= GetBkMode(hdc
);
820 ok(ret
== OPAQUE
, "got %d\n", ret
);
822 ok(c
== RGB(255, 255, 255), "got 0x%08x\n", c
);
824 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
825 ok(hbm
!= NULL
, "got %p\n", hbm
);
827 /* check DIB properties */
828 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
829 ok(ret
== sizeof(ds
), "got %d\n", ret
);
830 ok(ds
.dsBm
.bmWidth
== 10, "got %d\n", ds
.dsBm
.bmWidth
);
831 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
832 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
833 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
834 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
836 size
.cx
= size
.cy
= -1;
837 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
839 ok(size
.cx
== 10, "got %d\n", size
.cx
);
840 ok(size
.cy
== 5, "got %d\n", size
.cy
);
842 /* resize to same size */
843 hr
= IDWriteBitmapRenderTarget_Resize(target
, 10, 5);
844 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
846 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
847 ok(hbm2
== hbm
, "got %p, %p\n", hbm2
, hbm
);
850 hr
= IDWriteBitmapRenderTarget_Resize(target
, 5, 5);
851 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
853 size
.cx
= size
.cy
= -1;
854 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
855 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
856 ok(size
.cx
== 5, "got %d\n", size
.cx
);
857 ok(size
.cy
== 5, "got %d\n", size
.cy
);
859 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
860 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
862 hr
= IDWriteBitmapRenderTarget_Resize(target
, 20, 5);
863 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
865 size
.cx
= size
.cy
= -1;
866 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
867 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
868 ok(size
.cx
== 20, "got %d\n", size
.cx
);
869 ok(size
.cy
== 5, "got %d\n", size
.cy
);
871 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
872 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
874 hr
= IDWriteBitmapRenderTarget_Resize(target
, 1, 5);
875 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
877 size
.cx
= size
.cy
= -1;
878 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
879 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
880 ok(size
.cx
== 1, "got %d\n", size
.cx
);
881 ok(size
.cy
== 5, "got %d\n", size
.cy
);
883 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
884 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
886 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
887 ok(ret
== sizeof(ds
), "got %d\n", ret
);
888 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
889 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
890 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
891 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
892 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
894 /* empty rectangle */
895 hr
= IDWriteBitmapRenderTarget_Resize(target
, 0, 5);
896 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
898 size
.cx
= size
.cy
= -1;
899 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
900 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
901 ok(size
.cx
== 0, "got %d\n", size
.cx
);
902 ok(size
.cy
== 5, "got %d\n", size
.cy
);
904 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
905 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
907 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
908 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
909 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
910 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
911 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
912 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
913 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
915 /* transform tests */
916 if (0) /* crashes on native */
917 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, NULL
);
919 memset(&m
, 0xcc, sizeof(m
));
920 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
921 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
922 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
);
923 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
925 memset(&m
, 0, sizeof(m
));
926 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, &m
);
927 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
929 memset(&m
, 0xcc, sizeof(m
));
930 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
931 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
932 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
);
933 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
935 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, NULL
);
936 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
938 memset(&m
, 0xcc, sizeof(m
));
939 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
940 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
941 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
);
942 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
945 pdip
= IDWriteBitmapRenderTarget_GetPixelsPerDip(target
);
946 ok(pdip
== 1.0, "got %.2f\n", pdip
);
948 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, 2.0);
949 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
951 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, -1.0);
952 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
954 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, 0.0);
955 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
957 pdip
= IDWriteBitmapRenderTarget_GetPixelsPerDip(target
);
958 ok(pdip
== 2.0, "got %.2f\n", pdip
);
960 hr
= IDWriteBitmapRenderTarget_QueryInterface(target
, &IID_IDWriteBitmapRenderTarget1
, (void**)&target1
);
962 DWRITE_TEXT_ANTIALIAS_MODE mode
;
964 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
965 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, "got %d\n", mode
);
967 hr
= IDWriteBitmapRenderTarget1_SetTextAntialiasMode(target1
, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
+1);
968 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
970 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
971 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, "got %d\n", mode
);
973 hr
= IDWriteBitmapRenderTarget1_SetTextAntialiasMode(target1
, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
);
974 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
976 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
977 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
, "got %d\n", mode
);
979 IDWriteBitmapRenderTarget1_Release(target1
);
982 win_skip("IDWriteBitmapRenderTarget1 is not supported.\n");
984 IDWriteBitmapRenderTarget_Release(target
);
985 IDWriteGdiInterop_Release(interop
);
986 IDWriteFactory_Release(factory
);
989 static void test_GetFontFamily(void)
991 IDWriteFontCollection
*collection
, *collection2
;
992 IDWriteFontCollection
*syscoll
;
993 IDWriteFontFamily
*family
, *family2
;
994 IDWriteGdiInterop
*interop
;
995 IDWriteFont
*font
, *font2
;
996 IDWriteFactory
*factory
;
1000 factory
= create_factory();
1002 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1003 EXPECT_HR(hr
, S_OK
);
1005 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &syscoll
, FALSE
);
1006 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1008 memset(&logfont
, 0, sizeof(logfont
));
1009 logfont
.lfHeight
= 12;
1010 logfont
.lfWidth
= 12;
1011 logfont
.lfWeight
= FW_NORMAL
;
1012 logfont
.lfItalic
= 1;
1013 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1015 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1016 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1018 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
1019 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1020 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
1022 if (0) /* crashes on native */
1023 hr
= IDWriteFont_GetFontFamily(font
, NULL
);
1025 EXPECT_REF(font
, 1);
1026 hr
= IDWriteFont_GetFontFamily(font
, &family
);
1027 EXPECT_HR(hr
, S_OK
);
1028 EXPECT_REF(font
, 1);
1029 EXPECT_REF(family
, 2);
1031 hr
= IDWriteFont_GetFontFamily(font
, &family2
);
1032 EXPECT_HR(hr
, S_OK
);
1033 ok(family2
== family
, "got %p, previous %p\n", family2
, family
);
1034 EXPECT_REF(font
, 1);
1035 EXPECT_REF(family
, 3);
1036 IDWriteFontFamily_Release(family2
);
1038 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFamily
, (void**)&family2
);
1039 EXPECT_HR(hr
, E_NOINTERFACE
);
1040 ok(family2
== NULL
, "got %p\n", family2
);
1042 hr
= IDWriteFont_GetFontFamily(font2
, &family2
);
1043 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1044 ok(family2
!= family
, "got %p, %p\n", family2
, family
);
1047 hr
= IDWriteFontFamily_GetFontCollection(family
, &collection
);
1048 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1051 hr
= IDWriteFontFamily_GetFontCollection(family2
, &collection2
);
1052 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1053 ok(collection
== collection2
, "got %p, %p\n", collection
, collection2
);
1054 ok(collection
== syscoll
, "got %p, %p\n", collection
, syscoll
);
1056 IDWriteFontCollection_Release(syscoll
);
1057 IDWriteFontCollection_Release(collection2
);
1058 IDWriteFontCollection_Release(collection
);
1059 IDWriteFontFamily_Release(family2
);
1060 IDWriteFontFamily_Release(family
);
1061 IDWriteFont_Release(font
);
1062 IDWriteFont_Release(font2
);
1063 IDWriteGdiInterop_Release(interop
);
1064 IDWriteFactory_Release(factory
);
1067 static void test_GetFamilyNames(void)
1069 IDWriteFontFamily
*family
;
1070 IDWriteLocalizedStrings
*names
, *names2
;
1071 IDWriteGdiInterop
*interop
;
1072 IDWriteFactory
*factory
;
1079 factory
= create_factory();
1081 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1082 EXPECT_HR(hr
, S_OK
);
1084 memset(&logfont
, 0, sizeof(logfont
));
1085 logfont
.lfHeight
= 12;
1086 logfont
.lfWidth
= 12;
1087 logfont
.lfWeight
= FW_NORMAL
;
1088 logfont
.lfItalic
= 1;
1089 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1091 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1092 EXPECT_HR(hr
, S_OK
);
1094 hr
= IDWriteFont_GetFontFamily(font
, &family
);
1095 EXPECT_HR(hr
, S_OK
);
1097 if (0) /* crashes on native */
1098 hr
= IDWriteFontFamily_GetFamilyNames(family
, NULL
);
1100 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
1101 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1102 EXPECT_REF(names
, 1);
1104 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names2
);
1105 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1106 EXPECT_REF(names2
, 1);
1107 ok(names
!= names2
, "got %p, was %p\n", names2
, names
);
1109 IDWriteLocalizedStrings_Release(names2
);
1111 /* GetStringLength */
1112 if (0) /* crashes on native */
1113 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, NULL
);
1116 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 10, &len
);
1117 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1118 ok(len
== (UINT32
)-1, "got %u\n", len
);
1121 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, &len
);
1122 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1123 ok(len
> 0, "got %u\n", len
);
1126 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 0);
1127 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1129 hr
= IDWriteLocalizedStrings_GetString(names
, 10, NULL
, 0);
1130 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1133 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 100);
1136 hr
= IDWriteLocalizedStrings_GetString(names
, 10, buffer
, 100);
1137 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1138 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1141 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
-1);
1142 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1143 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1146 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
);
1147 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1148 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1151 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
+1);
1152 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1153 ok(buffer
[0] != 0, "got %x\n", buffer
[0]);
1155 IDWriteLocalizedStrings_Release(names
);
1157 IDWriteFontFamily_Release(family
);
1158 IDWriteFont_Release(font
);
1159 IDWriteGdiInterop_Release(interop
);
1160 IDWriteFactory_Release(factory
);
1163 static void test_CreateFontFace(void)
1165 IDWriteFontFace
*fontface
, *fontface2
;
1166 IDWriteFontCollection
*collection
;
1167 DWRITE_FONT_FILE_TYPE file_type
;
1168 DWRITE_FONT_FACE_TYPE face_type
;
1169 IDWriteGdiInterop
*interop
;
1170 IDWriteFont
*font
, *font2
;
1171 IDWriteFontFamily
*family
;
1172 IDWriteFactory
*factory
;
1173 IDWriteFontFile
*file
;
1180 factory
= create_factory();
1182 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1183 EXPECT_HR(hr
, S_OK
);
1185 memset(&logfont
, 0, sizeof(logfont
));
1186 logfont
.lfHeight
= 12;
1187 logfont
.lfWidth
= 12;
1188 logfont
.lfWeight
= FW_NORMAL
;
1189 logfont
.lfItalic
= 1;
1190 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1193 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1194 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1197 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
1198 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1199 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1201 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFace
, (void**)&fontface
);
1202 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1204 if (0) /* crashes on native */
1205 hr
= IDWriteFont_CreateFontFace(font
, NULL
);
1208 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1209 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1212 hr
= IDWriteFont_CreateFontFace(font
, &fontface2
);
1213 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1214 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1215 IDWriteFontFace_Release(fontface2
);
1218 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
1219 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1220 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1221 IDWriteFontFace_Release(fontface2
);
1223 IDWriteFont_Release(font2
);
1224 IDWriteFont_Release(font
);
1226 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFont
, (void**)&font
);
1227 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_NOTIMPL
), "got 0x%08x\n", hr
);
1229 IDWriteFontFace_Release(fontface
);
1230 IDWriteGdiInterop_Release(interop
);
1232 /* Create from system collection */
1233 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1234 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1236 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
1237 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1240 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1241 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1242 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1245 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1246 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font2
);
1247 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1248 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1251 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1252 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1255 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
1256 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1257 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1259 IDWriteFontFace_Release(fontface
);
1260 IDWriteFontFace_Release(fontface2
);
1261 IDWriteFont_Release(font2
);
1262 IDWriteFont_Release(font
);
1263 IDWriteFontFamily_Release(family
);
1264 IDWriteFontCollection_Release(collection
);
1266 /* IDWriteFactory::CreateFontFace() */
1267 path
= create_testfontfile(test_fontfile
);
1268 factory
= create_factory();
1270 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
1271 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1274 file_type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1275 face_type
= DWRITE_FONT_FACE_TYPE_CFF
;
1277 hr
= IDWriteFontFile_Analyze(file
, &supported
, &file_type
, &face_type
, &count
);
1278 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1279 ok(supported
== TRUE
, "got %i\n", supported
);
1280 ok(file_type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", file_type
);
1281 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face_type
);
1282 ok(count
== 1, "got %i\n", count
);
1284 /* try mismatching face type, the one that's not supported */
1285 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1287 ok(hr
== DWRITE_E_FILEFORMAT
, "got 0x%08x\n", hr
);
1289 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION
, 1, &file
, 0,
1290 DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1291 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1293 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_RAW_CFF
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1295 ok(hr
== DWRITE_E_UNSUPPORTEDOPERATION
|| broken(hr
== E_INVALIDARG
) /* older versions */, "got 0x%08x\n", hr
);
1297 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TYPE1
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1298 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1300 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_VECTOR
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1301 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1303 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_BITMAP
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1304 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1306 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_UNKNOWN
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1307 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1309 IDWriteFontFile_Release(file
);
1310 IDWriteFactory_Release(factory
);
1311 DELETE_FONTFILE(path
);
1314 static void test_GetMetrics(void)
1316 IDWriteGdiInterop
*interop
;
1317 DWRITE_FONT_METRICS metrics
;
1318 IDWriteFontFace
*fontface
;
1319 IDWriteFactory
*factory
;
1320 OUTLINETEXTMETRICW otm
;
1321 IDWriteFont1
*font1
;
1329 factory
= create_factory();
1331 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1332 EXPECT_HR(hr
, S_OK
);
1334 memset(&logfont
, 0, sizeof(logfont
));
1335 logfont
.lfHeight
= 12;
1336 logfont
.lfWidth
= 12;
1337 logfont
.lfWeight
= FW_NORMAL
;
1338 logfont
.lfItalic
= 1;
1339 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1341 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1342 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1344 hfont
= CreateFontIndirectW(&logfont
);
1345 hdc
= CreateCompatibleDC(0);
1346 SelectObject(hdc
, hfont
);
1348 otm
.otmSize
= sizeof(otm
);
1349 ret
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
1350 ok(ret
, "got %d\n", ret
);
1352 DeleteObject(hfont
);
1354 if (0) /* crashes on native */
1355 IDWriteFont_GetMetrics(font
, NULL
);
1357 memset(&metrics
, 0, sizeof(metrics
));
1358 IDWriteFont_GetMetrics(font
, &metrics
);
1360 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
1361 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
1362 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
1363 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
1364 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
1365 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
1366 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
1367 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
1368 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
1369 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
1371 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1372 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1374 memset(&metrics
, 0, sizeof(metrics
));
1375 IDWriteFontFace_GetMetrics(fontface
, &metrics
);
1377 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
1378 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
1379 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
1380 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
1381 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
1382 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
1383 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
1384 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
1385 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
1386 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
1388 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
1390 DWRITE_FONT_METRICS1 metrics1
;
1391 IDWriteFontFace1
*fontface1
;
1393 memset(&metrics1
, 0, sizeof(metrics1
));
1394 IDWriteFont1_GetMetrics(font1
, &metrics1
);
1396 ok(metrics1
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics1
.designUnitsPerEm
);
1397 ok(metrics1
.ascent
!= 0, "ascent %u\n", metrics1
.ascent
);
1398 ok(metrics1
.descent
!= 0, "descent %u\n", metrics1
.descent
);
1399 ok(metrics1
.lineGap
== 0, "lineGap %d\n", metrics1
.lineGap
);
1400 ok(metrics1
.capHeight
, "capHeight %u\n", metrics1
.capHeight
);
1401 ok(metrics1
.xHeight
!= 0, "xHeight %u\n", metrics1
.xHeight
);
1402 ok(metrics1
.underlinePosition
< 0, "underlinePosition %d\n", metrics1
.underlinePosition
);
1403 ok(metrics1
.underlineThickness
!= 0, "underlineThickness %u\n", metrics1
.underlineThickness
);
1404 ok(metrics1
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics1
.strikethroughPosition
);
1405 ok(metrics1
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics1
.strikethroughThickness
);
1406 ok(metrics1
.glyphBoxLeft
< 0, "glyphBoxLeft %d\n", metrics1
.glyphBoxLeft
);
1407 ok(metrics1
.glyphBoxTop
> 0, "glyphBoxTop %d\n", metrics1
.glyphBoxTop
);
1408 ok(metrics1
.glyphBoxRight
> 0, "glyphBoxRight %d\n", metrics1
.glyphBoxRight
);
1409 ok(metrics1
.glyphBoxBottom
< 0, "glyphBoxBottom %d\n", metrics1
.glyphBoxBottom
);
1410 ok(metrics1
.subscriptPositionY
< 0, "subscriptPositionY %d\n", metrics1
.subscriptPositionY
);
1411 ok(metrics1
.subscriptSizeX
> 0, "subscriptSizeX %d\n", metrics1
.subscriptSizeX
);
1412 ok(metrics1
.subscriptSizeY
> 0, "subscriptSizeY %d\n", metrics1
.subscriptSizeY
);
1413 ok(metrics1
.superscriptPositionY
> 0, "superscriptPositionY %d\n", metrics1
.superscriptPositionY
);
1414 ok(metrics1
.superscriptSizeX
> 0, "superscriptSizeX %d\n", metrics1
.superscriptSizeX
);
1415 ok(metrics1
.superscriptSizeY
> 0, "superscriptSizeY %d\n", metrics1
.superscriptSizeY
);
1416 ok(!metrics1
.hasTypographicMetrics
, "hasTypographicMetrics %d\n", metrics1
.hasTypographicMetrics
);
1418 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
1419 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1421 memset(&metrics1
, 0, sizeof(metrics1
));
1422 IDWriteFontFace1_GetMetrics(fontface1
, &metrics1
);
1424 ok(metrics1
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics1
.designUnitsPerEm
);
1425 ok(metrics1
.ascent
!= 0, "ascent %u\n", metrics1
.ascent
);
1426 ok(metrics1
.descent
!= 0, "descent %u\n", metrics1
.descent
);
1427 ok(metrics1
.lineGap
== 0, "lineGap %d\n", metrics1
.lineGap
);
1428 ok(metrics1
.capHeight
, "capHeight %u\n", metrics1
.capHeight
);
1429 ok(metrics1
.xHeight
!= 0, "xHeight %u\n", metrics1
.xHeight
);
1430 ok(metrics1
.underlinePosition
< 0, "underlinePosition %d\n", metrics1
.underlinePosition
);
1431 ok(metrics1
.underlineThickness
!= 0, "underlineThickness %u\n", metrics1
.underlineThickness
);
1432 ok(metrics1
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics1
.strikethroughPosition
);
1433 ok(metrics1
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics1
.strikethroughThickness
);
1434 ok(metrics1
.glyphBoxLeft
< 0, "glyphBoxLeft %d\n", metrics1
.glyphBoxLeft
);
1435 ok(metrics1
.glyphBoxTop
> 0, "glyphBoxTop %d\n", metrics1
.glyphBoxTop
);
1436 ok(metrics1
.glyphBoxRight
> 0, "glyphBoxRight %d\n", metrics1
.glyphBoxRight
);
1437 ok(metrics1
.glyphBoxBottom
< 0, "glyphBoxBottom %d\n", metrics1
.glyphBoxBottom
);
1438 ok(metrics1
.subscriptPositionY
< 0, "subscriptPositionY %d\n", metrics1
.subscriptPositionY
);
1439 ok(metrics1
.subscriptSizeX
> 0, "subscriptSizeX %d\n", metrics1
.subscriptSizeX
);
1440 ok(metrics1
.subscriptSizeY
> 0, "subscriptSizeY %d\n", metrics1
.subscriptSizeY
);
1441 ok(metrics1
.superscriptPositionY
> 0, "superscriptPositionY %d\n", metrics1
.superscriptPositionY
);
1442 ok(metrics1
.superscriptSizeX
> 0, "superscriptSizeX %d\n", metrics1
.superscriptSizeX
);
1443 ok(metrics1
.superscriptSizeY
> 0, "superscriptSizeY %d\n", metrics1
.superscriptSizeY
);
1444 ok(!metrics1
.hasTypographicMetrics
, "hasTypographicMetrics %d\n", metrics1
.hasTypographicMetrics
);
1446 IDWriteFontFace1_Release(fontface1
);
1447 IDWriteFont1_Release(font1
);
1450 win_skip("DWRITE_FONT_METRICS1 is not supported.\n");
1452 IDWriteFontFace_Release(fontface
);
1454 IDWriteFont_Release(font
);
1455 IDWriteGdiInterop_Release(interop
);
1456 IDWriteFactory_Release(factory
);
1459 static void test_system_fontcollection(void)
1461 IDWriteFontCollection
*collection
, *coll2
;
1462 IDWriteLocalFontFileLoader
*localloader
;
1463 IDWriteFactory
*factory
, *factory2
;
1464 IDWriteFontFileLoader
*loader
;
1465 IDWriteFontFamily
*family
;
1466 IDWriteFontFace
*fontface
;
1467 IDWriteFontFile
*file
;
1473 factory
= create_factory();
1475 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1476 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1478 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, FALSE
);
1479 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1480 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
1481 IDWriteFontCollection_Release(coll2
);
1483 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, TRUE
);
1484 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1485 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
1486 IDWriteFontCollection_Release(coll2
);
1488 factory2
= create_factory();
1489 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &coll2
, FALSE
);
1490 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1491 ok(coll2
!= collection
, "got %p, was %p\n", coll2
, collection
);
1492 IDWriteFontCollection_Release(coll2
);
1493 IDWriteFactory_Release(factory2
);
1495 i
= IDWriteFontCollection_GetFontFamilyCount(collection
);
1496 ok(i
, "got %u\n", i
);
1499 family
= (void*)0xdeadbeef;
1500 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
1501 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1502 ok(family
== NULL
, "got %p\n", family
);
1506 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaW
, &i
, &ret
);
1507 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1508 ok(ret
, "got %d\n", ret
);
1509 ok(i
!= (UINT32
)-1, "got %u\n", i
);
1513 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaUppercaseW
, &i
, &ret
);
1514 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1515 ok(ret
, "got %d\n", ret
);
1516 ok(i
!= (UINT32
)-1, "got %u\n", i
);
1520 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaStrangecaseW
, &i
, &ret
);
1521 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1522 ok(ret
, "got %d\n", ret
);
1523 ok(i
!= (UINT32
)-1, "got %u\n", i
);
1525 /* get back local file loader */
1526 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
1527 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1529 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1530 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1531 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1532 IDWriteFontFamily_Release(family
);
1534 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1535 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1536 IDWriteFont_Release(font
);
1540 hr
= IDWriteFontFace_GetFiles(fontface
, &i
, &file
);
1541 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1542 ok(file
!= NULL
, "got %p\n", file
);
1544 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
1545 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1546 IDWriteFontFile_Release(file
);
1548 hr
= IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
1549 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1550 IDWriteLocalFontFileLoader_Release(localloader
);
1552 /* local loader is not registered by default */
1553 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, loader
);
1554 ok(hr
== S_OK
|| broken(hr
== DWRITE_E_ALREADYREGISTERED
), "got 0x%08x\n", hr
);
1555 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, loader
);
1556 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "got 0x%08x\n", hr
);
1558 /* try with a different factory */
1559 factory2
= create_factory();
1560 hr
= IDWriteFactory_RegisterFontFileLoader(factory2
, loader
);
1561 ok(hr
== S_OK
|| broken(hr
== DWRITE_E_ALREADYREGISTERED
), "got 0x%08x\n", hr
);
1562 hr
= IDWriteFactory_RegisterFontFileLoader(factory2
, loader
);
1563 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1564 hr
= IDWriteFactory_UnregisterFontFileLoader(factory2
, loader
);
1565 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "got 0x%08x\n", hr
);
1566 hr
= IDWriteFactory_UnregisterFontFileLoader(factory2
, loader
);
1567 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1568 IDWriteFactory_Release(factory2
);
1570 IDWriteFontFileLoader_Release(loader
);
1574 hr
= IDWriteFontCollection_FindFamilyName(collection
, blahW
, &i
, &ret
);
1575 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1576 ok(!ret
, "got %d\n", ret
);
1577 ok(i
== (UINT32
)-1, "got %u\n", i
);
1579 IDWriteFontCollection_Release(collection
);
1580 IDWriteFactory_Release(factory
);
1583 static void test_ConvertFontFaceToLOGFONT(void)
1585 DWRITE_FONT_SIMULATIONS sim
;
1586 IDWriteGdiInterop
*interop
;
1587 IDWriteFontFace
*fontface
;
1588 IDWriteFactory
*factory
;
1593 factory
= create_factory();
1595 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1596 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1598 memset(&logfont
, 0, sizeof(logfont
));
1599 logfont
.lfHeight
= 12;
1600 logfont
.lfWidth
= 12;
1601 logfont
.lfEscapement
= 100;
1602 logfont
.lfWeight
= FW_NORMAL
;
1603 logfont
.lfItalic
= 1;
1604 logfont
.lfUnderline
= 1;
1605 logfont
.lfStrikeOut
= 1;
1607 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1609 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1610 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1612 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1613 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1615 sim
= IDWriteFont_GetSimulations(font
);
1616 ok(sim
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "sim %d\n", sim
);
1618 sim
= IDWriteFontFace_GetSimulations(fontface
);
1619 ok(sim
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "sim %d\n", sim
);
1621 IDWriteFont_Release(font
);
1623 if (0) /* crashes on native */
1625 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, NULL
, NULL
);
1626 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, NULL
);
1629 memset(&logfont
, 0xa, sizeof(logfont
));
1630 logfont
.lfFaceName
[0] = 0;
1632 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, &logfont
);
1633 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1634 ok(logfont
.lfHeight
== 0, "got %d\n", logfont
.lfHeight
);
1635 ok(logfont
.lfWidth
== 0, "got %d\n", logfont
.lfWidth
);
1636 ok(logfont
.lfWeight
== FW_NORMAL
, "got %d\n", logfont
.lfWeight
);
1637 ok(logfont
.lfEscapement
== 0, "got %d\n", logfont
.lfEscapement
);
1638 ok(logfont
.lfItalic
== 1, "got %d\n", logfont
.lfItalic
);
1639 ok(logfont
.lfUnderline
== 0, "got %d\n", logfont
.lfUnderline
);
1640 ok(logfont
.lfStrikeOut
== 0, "got %d\n", logfont
.lfStrikeOut
);
1641 ok(!lstrcmpW(logfont
.lfFaceName
, tahomaW
), "got %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
1643 IDWriteGdiInterop_Release(interop
);
1644 IDWriteFontFace_Release(fontface
);
1645 IDWriteFactory_Release(factory
);
1648 static HRESULT WINAPI
fontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
1650 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
))
1653 IDWriteFontFileEnumerator_AddRef(iface
);
1656 return E_NOINTERFACE
;
1659 static ULONG WINAPI
fontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
1664 static ULONG WINAPI
fontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
1669 static HRESULT WINAPI
fontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**file
)
1675 static HRESULT WINAPI
fontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
1681 static const struct IDWriteFontFileEnumeratorVtbl dwritefontfileenumeratorvtbl
=
1683 fontfileenumerator_QueryInterface
,
1684 fontfileenumerator_AddRef
,
1685 fontfileenumerator_Release
,
1686 fontfileenumerator_MoveNext
,
1687 fontfileenumerator_GetCurrentFontFile
,
1690 static HRESULT WINAPI
fontcollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
1696 static ULONG WINAPI
fontcollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
1701 static ULONG WINAPI
fontcollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
1706 static HRESULT WINAPI
fontcollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
*factory
, const void *key
,
1707 UINT32 key_size
, IDWriteFontFileEnumerator
**ret
)
1709 static IDWriteFontFileEnumerator enumerator
= { &dwritefontfileenumeratorvtbl
};
1714 static const struct IDWriteFontCollectionLoaderVtbl dwritefontcollectionloadervtbl
= {
1715 fontcollectionloader_QueryInterface
,
1716 fontcollectionloader_AddRef
,
1717 fontcollectionloader_Release
,
1718 fontcollectionloader_CreateEnumeratorFromKey
1721 static void test_CustomFontCollection(void)
1723 static const WCHAR fontnameW
[] = {'w','i','n','e','_','t','e','s','t',0};
1724 IDWriteFontCollectionLoader collection
= { &dwritefontcollectionloadervtbl
};
1725 IDWriteFontCollectionLoader collection2
= { &dwritefontcollectionloadervtbl
};
1726 IDWriteFontCollectionLoader collection3
= { &dwritefontcollectionloadervtbl
};
1727 IDWriteFontCollection
*font_collection
= NULL
;
1728 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
1729 struct test_fontcollectionloader resource_collection
= { { &resourcecollectionloadervtbl
}, &rloader
};
1730 IDWriteFontFamily
*family
, *family2
, *family3
;
1731 IDWriteFontFace
*idfontface
, *idfontface2
;
1732 IDWriteFontFile
*fontfile
, *fontfile2
;
1733 IDWriteLocalizedStrings
*string
;
1734 IDWriteFont
*idfont
, *idfont2
;
1735 IDWriteFactory
*factory
;
1736 UINT32 index
, count
;
1741 factory
= create_factory();
1743 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, NULL
);
1744 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1746 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, NULL
);
1747 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1749 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
1750 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1751 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection2
);
1752 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1753 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
1754 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1756 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1757 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1758 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
);
1759 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1761 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection3
, "Billy", 6, &font_collection
);
1762 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1764 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection
, "Billy", 6, &font_collection
);
1765 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1766 IDWriteFontCollection_Release(font_collection
);
1768 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection2
, "Billy", 6, &font_collection
);
1769 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1770 IDWriteFontCollection_Release(font_collection
);
1772 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, (IDWriteFontCollectionLoader
*)0xdeadbeef, "Billy", 6, &font_collection
);
1773 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1775 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1776 ok(font
!= NULL
, "Failed to find font resource\n");
1778 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
,
1779 &font
, sizeof(HRSRC
), &font_collection
);
1780 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1784 hr
= IDWriteFontCollection_FindFamilyName(font_collection
, fontnameW
, &index
, &exists
);
1785 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1786 ok(index
== 0, "got index %i\n", index
);
1787 ok(exists
, "got exists %i\n", exists
);
1789 count
= IDWriteFontCollection_GetFontFamilyCount(font_collection
);
1790 ok(count
== 1, "got %u\n", count
);
1793 hr
= IDWriteFontCollection_GetFontFamily(font_collection
, 0, &family
);
1794 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1795 EXPECT_REF(family
, 1);
1798 hr
= IDWriteFontCollection_GetFontFamily(font_collection
, 0, &family2
);
1799 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1800 EXPECT_REF(family2
, 1);
1801 ok(family
!= family2
, "got %p, %p\n", family
, family2
);
1803 hr
= IDWriteFontFamily_GetFont(family
, 0, &idfont
);
1804 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1805 EXPECT_REF(idfont
, 1);
1806 EXPECT_REF(family
, 2);
1807 hr
= IDWriteFontFamily_GetFont(family
, 0, &idfont2
);
1808 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1809 EXPECT_REF(idfont2
, 1);
1810 EXPECT_REF(family
, 3);
1811 ok(idfont
!= idfont2
, "got %p, %p\n", idfont
, idfont2
);
1812 IDWriteFont_Release(idfont2
);
1814 hr
= IDWriteFont_GetInformationalStrings(idfont
, DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE
, &string
, &exists
);
1815 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1816 ok(exists
, "got %d\n", exists
);
1817 EXPECT_REF(string
, 1);
1820 hr
= IDWriteFont_GetFontFamily(idfont
, &family3
);
1821 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1822 EXPECT_REF(family
, 3);
1823 ok(family
== family3
, "got %p, %p\n", family
, family3
);
1824 IDWriteFontFamily_Release(family3
);
1827 hr
= IDWriteFont_CreateFontFace(idfont
, &idfontface
);
1828 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1829 EXPECT_REF(idfont
, 1);
1832 hr
= IDWriteFontFamily_GetFont(family2
, 0, &idfont2
);
1833 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1834 EXPECT_REF(idfont2
, 1);
1835 EXPECT_REF(idfont
, 1);
1836 ok(idfont2
!= idfont
, "Font instances should not match\n");
1839 hr
= IDWriteFont_CreateFontFace(idfont2
, &idfontface2
);
1840 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1841 ok(idfontface2
== idfontface
, "fontfaces should match\n");
1845 hr
= IDWriteFontFace_GetFiles(idfontface
, &index
, &fontfile
);
1846 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1850 hr
= IDWriteFontFace_GetFiles(idfontface2
, &index
, &fontfile2
);
1851 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1852 ok(fontfile
== fontfile2
, "fontfiles should match\n");
1854 IDWriteFont_Release(idfont
);
1855 IDWriteFont_Release(idfont2
);
1856 IDWriteFontFile_Release(fontfile
);
1857 IDWriteFontFile_Release(fontfile2
);
1858 IDWriteFontFace_Release(idfontface
);
1859 IDWriteFontFace_Release(idfontface2
);
1860 IDWriteFontFamily_Release(family2
);
1861 IDWriteFontFamily_Release(family
);
1862 IDWriteFontCollection_Release(font_collection
);
1864 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
1865 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1866 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
1867 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1868 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection2
);
1869 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1870 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
);
1871 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1872 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
1873 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1875 IDWriteFactory_Release(factory
);
1878 static HRESULT WINAPI
fontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
1880 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
1883 IDWriteFontFileLoader_AddRef(iface
);
1888 return E_NOINTERFACE
;
1891 static ULONG WINAPI
fontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
1896 static ULONG WINAPI
fontfileloader_Release(IDWriteFontFileLoader
*iface
)
1901 static HRESULT WINAPI
fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
1906 static const struct IDWriteFontFileLoaderVtbl dwritefontfileloadervtbl
= {
1907 fontfileloader_QueryInterface
,
1908 fontfileloader_AddRef
,
1909 fontfileloader_Release
,
1910 fontfileloader_CreateStreamFromKey
1913 static void test_CreateCustomFontFileReference(void)
1915 IDWriteFontFileLoader floader
= { &dwritefontfileloadervtbl
};
1916 IDWriteFontFileLoader floader2
= { &dwritefontfileloadervtbl
};
1917 IDWriteFontFileLoader floader3
= { &dwritefontfileloadervtbl
};
1918 IDWriteFactory
*factory
, *factory2
;
1919 IDWriteFontFile
*file
, *file2
;
1921 DWRITE_FONT_FILE_TYPE file_type
;
1922 DWRITE_FONT_FACE_TYPE face_type
;
1924 IDWriteFontFace
*face
, *face2
;
1927 UINT32 codePoints
[1] = {0xa8};
1930 factory
= create_factory();
1931 factory2
= create_factory();
1933 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, NULL
);
1934 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1935 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
1936 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1937 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader2
);
1938 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1939 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
1940 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1941 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1942 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1945 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &file
);
1946 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1947 IDWriteFontFile_Release(file
);
1949 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader3
, &file
);
1950 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1952 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, NULL
, &file
);
1953 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1956 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &file
);
1957 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1959 file_type
= DWRITE_FONT_FILE_TYPE_TRUETYPE
;
1960 face_type
= DWRITE_FONT_FACE_TYPE_TRUETYPE
;
1963 hr
= IDWriteFontFile_Analyze(file
, &support
, &file_type
, &face_type
, &count
);
1964 ok(hr
== 0x8faecafe, "got 0x%08x\n", hr
);
1965 ok(support
== FALSE
, "got %i\n", support
);
1966 ok(file_type
== DWRITE_FONT_FILE_TYPE_UNKNOWN
, "got %i\n", file_type
);
1967 ok(face_type
== DWRITE_FONT_FACE_TYPE_UNKNOWN
, "got %i\n", face_type
);
1968 ok(count
== 0, "got %i\n", count
);
1970 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &file
, 0, 0, &face
);
1971 ok(hr
== 0x8faecafe, "got 0x%08x\n", hr
);
1972 IDWriteFontFile_Release(file
);
1974 fontrsrc
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1975 ok(fontrsrc
!= NULL
, "Failed to find font resource\n");
1977 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &fontrsrc
, sizeof(HRSRC
), &rloader
, &file
);
1978 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1980 file_type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1981 face_type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1984 hr
= IDWriteFontFile_Analyze(file
, &support
, &file_type
, &face_type
, &count
);
1985 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1986 ok(support
== TRUE
, "got %i\n", support
);
1987 ok(file_type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", file_type
);
1988 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face_type
);
1989 ok(count
== 1, "got %i\n", count
);
1992 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 1, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
1993 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1995 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
1996 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1998 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
1999 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2000 /* fontface instances are reused starting with win7 */
2001 ok(face
== face2
|| broken(face
!= face2
), "got %p, %p\n", face
, face2
);
2002 IDWriteFontFace_Release(face2
);
2004 /* file was created with different factory */
2006 hr
= IDWriteFactory_CreateFontFace(factory2
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2008 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2010 IDWriteFontFace_Release(face2
);
2013 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &fontrsrc
, sizeof(HRSRC
), &rloader
, &file2
);
2014 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2015 ok(file
!= file2
, "got %p, %p\n", file
, file2
);
2017 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file2
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2018 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2019 /* fontface instances are reused starting with win7 */
2020 ok(face
== face2
|| broken(face
!= face2
), "got %p, %p\n", face
, face2
);
2021 IDWriteFontFace_Release(face2
);
2022 IDWriteFontFile_Release(file2
);
2024 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 0, NULL
);
2025 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2027 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 0, NULL
);
2028 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2030 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 0, indices
);
2031 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2033 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 0, indices
);
2034 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2036 indices
[0] = indices
[1] = 11;
2037 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 1, indices
);
2038 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2039 ok(indices
[0] == 0, "got index %i\n", indices
[0]);
2040 ok(indices
[1] == 11, "got index %i\n", indices
[1]);
2042 if (0) /* crashes on native */
2043 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 1, NULL
);
2045 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 1, indices
);
2046 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2047 ok(indices
[0] == 6, "got index %i\n", indices
[0]);
2048 IDWriteFontFace_Release(face
);
2049 IDWriteFontFile_Release(file
);
2051 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
2052 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2053 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
2054 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2055 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader2
);
2056 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2057 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
2058 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2060 IDWriteFactory_Release(factory2
);
2061 IDWriteFactory_Release(factory
);
2064 static void test_CreateFontFileReference(void)
2067 IDWriteFontFile
*ffile
= NULL
;
2069 DWRITE_FONT_FILE_TYPE type
;
2070 DWRITE_FONT_FACE_TYPE face
;
2072 IDWriteFontFace
*fface
= NULL
;
2073 IDWriteFactory
*factory
;
2076 path
= create_testfontfile(test_fontfile
);
2077 factory
= create_factory();
2079 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &ffile
);
2080 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2083 type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
2084 face
= DWRITE_FONT_FACE_TYPE_CFF
;
2086 hr
= IDWriteFontFile_Analyze(ffile
, &support
, &type
, &face
, &count
);
2087 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2088 ok(support
== TRUE
, "got %i\n", support
);
2089 ok(type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", type
);
2090 ok(face
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face
);
2091 ok(count
== 1, "got %i\n", count
);
2093 hr
= IDWriteFactory_CreateFontFace(factory
, face
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fface
);
2094 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2096 IDWriteFontFace_Release(fface
);
2097 IDWriteFontFile_Release(ffile
);
2098 IDWriteFactory_Release(factory
);
2100 DELETE_FONTFILE(path
);
2103 static void test_shared_isolated(void)
2105 IDWriteFactory
*isolated
, *isolated2
;
2106 IDWriteFactory
*shared
, *shared2
;
2111 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
2112 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2113 ok(shared
!= NULL
, "got %p\n", shared
);
2114 IDWriteFactory_Release(shared
);
2116 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
2117 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2119 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
2120 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2121 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
2123 IDWriteFactory_Release(shared
);
2124 IDWriteFactory_Release(shared2
);
2126 /* we got 2 references, released 2 - still same pointer is returned */
2127 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
2128 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2129 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
2130 IDWriteFactory_Release(shared2
);
2132 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated
);
2133 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2135 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
2136 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2137 ok(isolated
!= isolated2
, "got %p, and %p\n", isolated
, isolated2
);
2138 IDWriteFactory_Release(isolated2
);
2140 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
2141 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2142 ok(shared
!= isolated2
, "got %p, and %p\n", shared
, isolated2
);
2144 IDWriteFactory_Release(isolated
);
2145 IDWriteFactory_Release(isolated2
);
2148 static void test_GetUnicodeRanges(void)
2150 DWRITE_UNICODE_RANGE
*ranges
, r
;
2151 IDWriteFontFile
*ffile
= NULL
;
2152 IDWriteFontFace1
*fontface1
;
2153 IDWriteFontFace
*fontface
;
2154 IDWriteFactory
*factory
;
2159 factory
= create_factory();
2161 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
2162 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2164 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
2165 ok(font
!= NULL
, "Failed to find font resource\n");
2167 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &font
, sizeof(HRSRC
), &rloader
, &ffile
);
2168 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2170 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
2171 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2172 IDWriteFontFile_Release(ffile
);
2174 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
2175 IDWriteFontFace_Release(fontface
);
2177 win_skip("GetUnicodeRanges() is not supported.\n");
2178 IDWriteFactory_Release(factory
);
2183 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 0, NULL
, &count
);
2184 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
2185 ok(count
> 0, "got %u\n", count
);
2188 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, NULL
, &count
);
2189 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2190 ok(count
== 0, "got %u\n", count
);
2193 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, &r
, &count
);
2194 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
2195 ok(count
> 1, "got %u\n", count
);
2197 ranges
= heap_alloc(count
*sizeof(DWRITE_UNICODE_RANGE
));
2198 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, count
, ranges
, &count
);
2199 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2201 ranges
[0].first
= ranges
[0].last
= 0;
2202 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, ranges
, &count
);
2203 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
2204 ok(ranges
[0].first
!= 0 && ranges
[0].last
!= 0, "got 0x%x-0x%0x\n", ranges
[0].first
, ranges
[0].last
);
2208 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
2209 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2211 IDWriteFontFace1_Release(fontface1
);
2212 IDWriteFactory_Release(factory
);
2215 static void test_GetFontFromFontFace(void)
2217 IDWriteFontFace
*fontface
, *fontface2
;
2218 IDWriteFontCollection
*collection
;
2219 IDWriteFont
*font
, *font2
, *font3
;
2220 IDWriteFontFamily
*family
;
2221 IDWriteFactory
*factory
;
2222 IDWriteFontFile
*file
;
2226 factory
= create_factory();
2228 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2229 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2231 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2232 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2234 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2235 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2236 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2238 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2239 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2242 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font2
);
2243 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2244 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
2247 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font3
);
2248 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2249 ok(font3
!= font
&& font3
!= font2
, "got %p, %p, %p\n", font3
, font2
, font
);
2251 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
2252 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2253 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
2254 IDWriteFontFace_Release(fontface2
);
2256 hr
= IDWriteFont_CreateFontFace(font3
, &fontface2
);
2257 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2258 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
2259 IDWriteFontFace_Release(fontface2
);
2260 IDWriteFontFace_Release(fontface
);
2261 IDWriteFont_Release(font3
);
2262 IDWriteFactory_Release(factory
);
2264 /* fontface that wasn't created from this collection */
2265 factory
= create_factory();
2266 path
= create_testfontfile(test_fontfile
);
2268 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2269 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2271 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
2272 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2273 IDWriteFontFile_Release(file
);
2275 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font3
);
2276 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
2277 ok(font3
== NULL
, "got %p\n", font3
);
2278 IDWriteFontFace_Release(fontface
);
2280 IDWriteFont_Release(font
);
2281 IDWriteFont_Release(font2
);
2282 IDWriteFontFamily_Release(family
);
2283 IDWriteFontCollection_Release(collection
);
2284 IDWriteFactory_Release(factory
);
2285 DELETE_FONTFILE(path
);
2288 static IDWriteFont
*get_font(IDWriteFactory
*factory
, const WCHAR
*name
, DWRITE_FONT_STYLE style
)
2290 IDWriteFontCollection
*collection
;
2291 IDWriteFontFamily
*family
;
2292 IDWriteFont
*font
= NULL
;
2297 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2298 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2302 hr
= IDWriteFontCollection_FindFamilyName(collection
, name
, &index
, &exists
);
2303 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2304 if (!exists
) goto not_found
;
2306 hr
= IDWriteFontCollection_GetFontFamily(collection
, index
, &family
);
2307 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2309 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2310 DWRITE_FONT_STRETCH_NORMAL
, style
, &font
);
2311 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2313 IDWriteFontFamily_Release(family
);
2315 IDWriteFontCollection_Release(collection
);
2319 static IDWriteFont
*get_tahoma_instance(IDWriteFactory
*factory
, DWRITE_FONT_STYLE style
)
2321 IDWriteFont
*font
= get_font(factory
, tahomaW
, style
);
2322 ok(font
!= NULL
, "failed to get Tahoma\n");
2326 static void test_GetFirstMatchingFont(void)
2328 DWRITE_FONT_SIMULATIONS simulations
;
2329 IDWriteFont
*font
, *font2
;
2330 IDWriteFactory
*factory
;
2332 factory
= create_factory();
2334 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
2335 font2
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
2336 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
2337 IDWriteFont_Release(font
);
2338 IDWriteFont_Release(font2
);
2340 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_ITALIC
);
2341 simulations
= IDWriteFont_GetSimulations(font
);
2342 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "%d\n", simulations
);
2343 IDWriteFont_Release(font
);
2345 IDWriteFactory_Release(factory
);
2348 static void test_GetInformationalStrings(void)
2350 IDWriteLocalizedStrings
*strings
, *strings2
;
2351 IDWriteFontCollection
*collection
;
2352 IDWriteFontFamily
*family
;
2353 IDWriteFactory
*factory
;
2358 factory
= create_factory();
2360 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2361 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2363 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2364 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2366 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2367 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2368 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2371 strings
= (void*)0xdeadbeef;
2372 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
+1, &strings
, &exists
);
2373 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2374 ok(exists
== FALSE
, "got %d\n", exists
);
2375 ok(strings
== NULL
, "got %p\n", strings
);
2379 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_NONE
, &strings
, &exists
);
2380 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2381 ok(exists
== FALSE
, "got %d\n", exists
);
2385 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings
, &exists
);
2386 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2387 ok(exists
== TRUE
, "got %d\n", exists
);
2389 /* strings instance is not reused */
2391 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings2
, &exists
);
2392 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2393 ok(strings2
!= strings
, "got %p, %p\n", strings2
, strings
);
2395 IDWriteLocalizedStrings_Release(strings
);
2396 IDWriteLocalizedStrings_Release(strings2
);
2397 IDWriteFont_Release(font
);
2398 IDWriteFontFamily_Release(family
);
2399 IDWriteFontCollection_Release(collection
);
2400 IDWriteFactory_Release(factory
);
2403 static void test_GetGdiInterop(void)
2405 IDWriteGdiInterop
*interop
, *interop2
;
2406 IDWriteFactory
*factory
, *factory2
;
2411 factory
= create_factory();
2414 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2415 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2418 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop2
);
2419 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2420 ok(interop
== interop2
, "got %p, %p\n", interop
, interop2
);
2421 IDWriteGdiInterop_Release(interop2
);
2423 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory2
);
2424 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2426 /* each factory gets its own interop */
2428 hr
= IDWriteFactory_GetGdiInterop(factory2
, &interop2
);
2429 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2430 ok(interop
!= interop2
, "got %p, %p\n", interop
, interop2
);
2432 /* release factory - interop still works */
2433 IDWriteFactory_Release(factory2
);
2435 memset(&logfont
, 0, sizeof(logfont
));
2436 logfont
.lfHeight
= 12;
2437 logfont
.lfWidth
= 12;
2438 logfont
.lfWeight
= FW_NORMAL
;
2439 logfont
.lfItalic
= 1;
2440 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2442 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop2
, &logfont
, &font
);
2443 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2444 IDWriteFont_Release(font
);
2446 IDWriteGdiInterop_Release(interop2
);
2447 IDWriteGdiInterop_Release(interop
);
2448 IDWriteFactory_Release(factory
);
2451 static void test_CreateFontFaceFromHdc(void)
2453 IDWriteGdiInterop
*interop
;
2454 IDWriteFontFace
*fontface
;
2455 IDWriteFactory
*factory
;
2456 HFONT hfont
, oldhfont
;
2461 factory
= create_factory();
2464 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2465 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2467 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, NULL
, &fontface
);
2468 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2470 memset(&logfont
, 0, sizeof(logfont
));
2471 logfont
.lfHeight
= 12;
2472 logfont
.lfWidth
= 12;
2473 logfont
.lfWeight
= FW_NORMAL
;
2474 logfont
.lfItalic
= 1;
2475 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2477 hfont
= CreateFontIndirectW(&logfont
);
2478 hdc
= CreateCompatibleDC(0);
2479 oldhfont
= SelectObject(hdc
, hfont
);
2482 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, hdc
, &fontface
);
2483 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2484 IDWriteFontFace_Release(fontface
);
2485 DeleteObject(SelectObject(hdc
, oldhfont
));
2488 IDWriteGdiInterop_Release(interop
);
2489 IDWriteFactory_Release(factory
);
2492 static void test_GetSimulations(void)
2494 DWRITE_FONT_SIMULATIONS simulations
;
2495 IDWriteGdiInterop
*interop
;
2496 IDWriteFontFace
*fontface
;
2497 IDWriteFactory
*factory
;
2502 factory
= create_factory();
2504 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2505 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2507 memset(&logfont
, 0, sizeof(logfont
));
2508 logfont
.lfHeight
= 12;
2509 logfont
.lfWidth
= 12;
2510 logfont
.lfWeight
= FW_NORMAL
;
2511 logfont
.lfItalic
= 1;
2512 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2514 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2515 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2517 simulations
= IDWriteFont_GetSimulations(font
);
2518 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "got %d\n", simulations
);
2519 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2520 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2521 simulations
= IDWriteFontFace_GetSimulations(fontface
);
2522 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "got %d\n", simulations
);
2523 IDWriteFontFace_Release(fontface
);
2524 IDWriteFont_Release(font
);
2526 memset(&logfont
, 0, sizeof(logfont
));
2527 logfont
.lfHeight
= 12;
2528 logfont
.lfWidth
= 12;
2529 logfont
.lfWeight
= FW_NORMAL
;
2530 logfont
.lfItalic
= 0;
2531 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2533 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2534 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2536 simulations
= IDWriteFont_GetSimulations(font
);
2537 ok(simulations
== DWRITE_FONT_SIMULATIONS_NONE
, "got %d\n", simulations
);
2538 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2539 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2540 simulations
= IDWriteFontFace_GetSimulations(fontface
);
2541 ok(simulations
== DWRITE_FONT_SIMULATIONS_NONE
, "got %d\n", simulations
);
2542 IDWriteFontFace_Release(fontface
);
2543 IDWriteFont_Release(font
);
2545 IDWriteGdiInterop_Release(interop
);
2546 IDWriteFactory_Release(factory
);
2549 static void test_GetFaceNames(void)
2551 static const WCHAR obliqueW
[] = {'O','b','l','i','q','u','e',0};
2552 static const WCHAR enus2W
[] = {'e','n','-','U','s',0};
2553 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
2554 IDWriteLocalizedStrings
*strings
, *strings2
;
2555 IDWriteGdiInterop
*interop
;
2556 IDWriteFactory
*factory
;
2557 UINT32 count
, index
;
2564 factory
= create_factory();
2566 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2567 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2569 memset(&logfont
, 0, sizeof(logfont
));
2570 logfont
.lfHeight
= 12;
2571 logfont
.lfWidth
= 12;
2572 logfont
.lfWeight
= FW_NORMAL
;
2573 logfont
.lfItalic
= 1;
2574 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2576 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2577 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2579 hr
= IDWriteFont_GetFaceNames(font
, &strings
);
2580 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2582 hr
= IDWriteFont_GetFaceNames(font
, &strings2
);
2583 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2584 ok(strings
!= strings2
, "got %p, %p\n", strings2
, strings
);
2585 IDWriteLocalizedStrings_Release(strings2
);
2587 count
= IDWriteLocalizedStrings_GetCount(strings
);
2588 ok(count
== 1, "got %d\n", count
);
2592 hr
= IDWriteLocalizedStrings_FindLocaleName(strings
, enus2W
, &index
, &exists
);
2593 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2594 ok(index
== 0 && exists
, "got %d, %d\n", index
, exists
);
2597 hr
= IDWriteLocalizedStrings_GetLocaleNameLength(strings
, 1, &count
);
2598 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2599 ok(count
== ~0, "got %d\n", count
);
2601 /* for simulated faces names are also simulated */
2603 hr
= IDWriteLocalizedStrings_GetLocaleName(strings
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2604 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2605 ok(!lstrcmpW(buffW
, enusW
), "got %s\n", wine_dbgstr_w(buffW
));
2608 hr
= IDWriteLocalizedStrings_GetString(strings
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2609 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2610 ok(!lstrcmpW(buffW
, obliqueW
), "got %s\n", wine_dbgstr_w(buffW
));
2611 IDWriteLocalizedStrings_Release(strings
);
2613 IDWriteFont_Release(font
);
2614 IDWriteGdiInterop_Release(interop
);
2615 IDWriteFactory_Release(factory
);
2624 static void test_TryGetFontTable(void)
2626 IDWriteLocalFontFileLoader
*localloader
;
2627 WIN32_FILE_ATTRIBUTE_DATA info
;
2628 const struct local_refkey
*key
;
2629 IDWriteFontFileLoader
*loader
;
2630 const void *table
, *table2
;
2631 IDWriteFontFace
*fontface
;
2632 void *context
, *context2
;
2633 IDWriteFactory
*factory
;
2634 IDWriteFontFile
*file
;
2635 WCHAR buffW
[MAX_PATH
];
2641 path
= create_testfontfile(test_fontfile
);
2643 factory
= create_factory();
2645 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2646 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2650 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2651 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2652 ok(size
!= 0, "got %u\n", size
);
2654 ret
= GetFileAttributesExW(path
, GetFileExInfoStandard
, &info
);
2655 ok(ret
, "got %d\n", ret
);
2656 ok(!memcmp(&info
.ftLastWriteTime
, &key
->writetime
, sizeof(key
->writetime
)), "got wrong write time\n");
2658 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2659 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2660 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2661 IDWriteFontFileLoader_Release(loader
);
2663 hr
= IDWriteLocalFontFileLoader_GetFilePathLengthFromKey(localloader
, key
, size
, &len
);
2664 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2665 ok(lstrlenW(key
->name
) == len
, "path length %d\n", len
);
2667 hr
= IDWriteLocalFontFileLoader_GetFilePathFromKey(localloader
, key
, size
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2668 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2669 ok(!lstrcmpW(buffW
, key
->name
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(key
->name
));
2670 IDWriteLocalFontFileLoader_Release(localloader
);
2672 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, 0, &fontface
);
2673 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2676 context
= (void*)0xdeadbeef;
2678 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_CMAP_TAG
, &table
, &size
, &context
, &exists
);
2679 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2680 ok(exists
== TRUE
, "got %d\n", exists
);
2681 ok(context
== NULL
&& table
!= NULL
, "cmap: context %p, table %p\n", context
, table
);
2684 context2
= (void*)0xdeadbeef;
2686 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_CMAP_TAG
, &table2
, &size
, &context2
, &exists
);
2687 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2688 ok(exists
== TRUE
, "got %d\n", exists
);
2689 ok(context2
== context
&& table2
== table
, "cmap: context2 %p, table2 %p\n", context2
, table2
);
2691 IDWriteFontFace_ReleaseFontTable(fontface
, context2
);
2692 IDWriteFontFace_ReleaseFontTable(fontface
, context
);
2694 IDWriteFontFace_Release(fontface
);
2695 IDWriteFontFile_Release(file
);
2696 IDWriteFactory_Release(factory
);
2697 DELETE_FONTFILE(path
);
2700 static void test_ConvertFontToLOGFONT(void)
2702 IDWriteFactory
*factory
, *factory2
;
2703 IDWriteFontCollection
*collection
;
2704 IDWriteGdiInterop
*interop
;
2705 IDWriteFontFamily
*family
;
2711 factory
= create_factory();
2712 factory2
= create_factory();
2715 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2716 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2718 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &collection
, FALSE
);
2719 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2721 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2722 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2724 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2725 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2726 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2728 if (0) { /* crashes on native */
2729 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, NULL
, NULL
);
2730 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, &logfont
, NULL
);
2731 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, font
, NULL
, &system
);
2734 hr
= IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, &logfont
, &system
);
2735 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2736 ok(!system
, "got %d\n", system
);
2739 memset(&logfont
, 0, sizeof(logfont
));
2740 hr
= IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, font
, &logfont
, &system
);
2741 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2742 ok(system
, "got %d\n", system
);
2743 ok(logfont
.lfFaceName
[0] != 0, "got face name %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
2745 IDWriteFactory_Release(factory2
);
2747 IDWriteFontCollection_Release(collection
);
2748 IDWriteFontFamily_Release(family
);
2749 IDWriteFont_Release(font
);
2750 IDWriteGdiInterop_Release(interop
);
2751 IDWriteFactory_Release(factory
);
2754 static void test_CreateStreamFromKey(void)
2756 IDWriteLocalFontFileLoader
*localloader
;
2757 IDWriteFontFileStream
*stream
, *stream2
;
2758 IDWriteFontFileLoader
*loader
;
2759 IDWriteFactory
*factory
;
2760 IDWriteFontFile
*file
;
2767 factory
= create_factory();
2769 path
= create_testfontfile(test_fontfile
);
2771 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2772 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2776 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2777 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2778 ok(size
!= 0, "got %u\n", size
);
2780 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2781 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2782 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2783 IDWriteFontFileLoader_Release(loader
);
2785 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2786 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2787 EXPECT_REF(stream
, 1);
2789 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream2
);
2790 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2791 ok(stream
== stream2
|| broken(stream
!= stream2
) /* Win7 SP0 */, "got %p, %p\n", stream
, stream2
);
2792 if (stream
== stream2
)
2793 EXPECT_REF(stream
, 2);
2794 IDWriteFontFileStream_Release(stream
);
2795 IDWriteFontFileStream_Release(stream2
);
2797 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2798 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2799 EXPECT_REF(stream
, 1);
2802 hr
= IDWriteFontFileStream_GetLastWriteTime(stream
, &writetime
);
2803 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2804 ok(writetime
!= 0, "got %08x%08x\n", (UINT
)(writetime
>> 32), (UINT
)writetime
);
2806 IDWriteFontFileStream_Release(stream
);
2808 IDWriteLocalFontFileLoader_Release(localloader
);
2809 IDWriteFactory_Release(factory
);
2810 DELETE_FONTFILE(path
);
2813 static void test_ReadFileFragment(void)
2815 IDWriteLocalFontFileLoader
*localloader
;
2816 IDWriteFontFileStream
*stream
;
2817 IDWriteFontFileLoader
*loader
;
2818 IDWriteFactory
*factory
;
2819 IDWriteFontFile
*file
;
2820 const void *fragment
, *fragment2
;
2821 void *key
, *context
, *context2
;
2827 factory
= create_factory();
2829 path
= create_testfontfile(test_fontfile
);
2831 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2832 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2836 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2837 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2838 ok(size
!= 0, "got %u\n", size
);
2840 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2841 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2842 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2843 IDWriteFontFileLoader_Release(loader
);
2845 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2846 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2848 hr
= IDWriteFontFileStream_GetFileSize(stream
, &filesize
);
2849 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2851 /* reading past the end of the stream */
2852 fragment
= (void*)0xdeadbeef;
2853 context
= (void*)0xdeadbeef;
2854 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
+1, &context
);
2855 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2856 ok(context
== NULL
, "got %p\n", context
);
2857 ok(fragment
== NULL
, "got %p\n", fragment
);
2859 fragment
= (void*)0xdeadbeef;
2860 context
= (void*)0xdeadbeef;
2861 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
, &context
);
2862 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2863 ok(context
== NULL
, "got %p\n", context
);
2864 ok(fragment
!= NULL
, "got %p\n", fragment
);
2866 fragment2
= (void*)0xdeadbeef;
2867 context2
= (void*)0xdeadbeef;
2868 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment2
, 0, filesize
, &context2
);
2869 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2870 ok(context2
== NULL
, "got %p\n", context2
);
2871 ok(fragment
== fragment2
, "got %p, %p\n", fragment
, fragment2
);
2873 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
2874 IDWriteFontFileStream_ReleaseFileFragment(stream
, context2
);
2876 /* fragment is released, try again */
2877 fragment
= (void*)0xdeadbeef;
2878 context
= (void*)0xdeadbeef;
2879 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
, &context
);
2880 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2881 ok(context
== NULL
, "got %p\n", context
);
2882 ok(fragment
== fragment2
, "got %p, %p\n", fragment
, fragment2
);
2883 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
2885 IDWriteFontFileStream_Release(stream
);
2886 IDWriteLocalFontFileLoader_Release(localloader
);
2887 IDWriteFactory_Release(factory
);
2888 DELETE_FONTFILE(path
);
2891 static void test_GetDesignGlyphMetrics(void)
2893 DWRITE_GLYPH_METRICS metrics
[2];
2894 IDWriteFontFace
*fontface
;
2895 IDWriteFactory
*factory
;
2896 IDWriteFontFile
*file
;
2902 factory
= create_factory();
2904 path
= create_testfontfile(test_fontfile
);
2906 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2907 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2909 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
,
2910 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
2911 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2912 IDWriteFontFile_Release(file
);
2916 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &codepoint
, 1, &indices
[0]);
2917 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2918 ok(indices
[0] > 0, "got %u\n", indices
[0]);
2920 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, NULL
, 0, metrics
, FALSE
);
2921 ok(hr
== E_INVALIDARG
, "got 0x%08x\n",hr
);
2923 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, NULL
, 1, metrics
, FALSE
);
2924 ok(hr
== E_INVALIDARG
, "got 0x%08x\n",hr
);
2926 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, indices
, 0, metrics
, FALSE
);
2927 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2929 /* missing glyphs are ignored */
2931 memset(metrics
, 0xcc, sizeof(metrics
));
2932 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, indices
, 2, metrics
, FALSE
);
2933 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2934 ok(metrics
[0].advanceWidth
== 1000, "got %d\n", metrics
[0].advanceWidth
);
2935 ok(metrics
[1].advanceWidth
== 0, "got %d\n", metrics
[1].advanceWidth
);
2937 IDWriteFontFace_Release(fontface
);
2938 IDWriteFactory_Release(factory
);
2939 DELETE_FONTFILE(path
);
2942 static void test_IsMonospacedFont(void)
2944 static const WCHAR courierW
[] = {'C','o','u','r','i','e','r',' ','N','e','w',0};
2945 IDWriteFontCollection
*collection
;
2946 IDWriteFactory
*factory
;
2951 factory
= create_factory();
2952 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2953 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2956 hr
= IDWriteFontCollection_FindFamilyName(collection
, courierW
, &index
, &exists
);
2957 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2959 IDWriteFontFamily
*family
;
2960 IDWriteFont1
*font1
;
2963 hr
= IDWriteFontCollection_GetFontFamily(collection
, index
, &family
);
2964 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2966 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2967 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2968 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2969 IDWriteFontFamily_Release(family
);
2971 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
2973 IDWriteFontFace1
*fontface1
;
2974 IDWriteFontFace
*fontface
;
2977 is_monospaced
= IDWriteFont1_IsMonospacedFont(font1
);
2978 ok(is_monospaced
, "got %d\n", is_monospaced
);
2980 hr
= IDWriteFont1_CreateFontFace(font1
, &fontface
);
2981 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2982 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
2983 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2984 is_monospaced
= IDWriteFontFace1_IsMonospacedFont(fontface1
);
2985 ok(is_monospaced
, "got %d\n", is_monospaced
);
2986 IDWriteFontFace1_Release(fontface1
);
2988 IDWriteFontFace_Release(fontface
);
2989 IDWriteFont1_Release(font1
);
2992 win_skip("IsMonospacedFont() is not supported.\n");
2995 skip("Courier New font not found.\n");
2997 IDWriteFontCollection_Release(collection
);
3000 static void test_GetDesignGlyphAdvances(void)
3002 IDWriteFontFace1
*fontface1
;
3003 IDWriteFontFace
*fontface
;
3004 IDWriteFactory
*factory
;
3005 IDWriteFontFile
*file
;
3009 factory
= create_factory();
3011 path
= create_testfontfile(test_fontfile
);
3013 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3014 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3016 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
,
3017 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3018 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3019 IDWriteFontFile_Release(file
);
3021 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3029 hr
= IDWriteFontFace1_GetGlyphIndices(fontface1
, &codepoint
, 1, &index
);
3030 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3031 ok(index
> 0, "got %u\n", index
);
3034 hr
= IDWriteFontFace1_GetDesignGlyphAdvances(fontface1
, 1, &index
, &advance
, FALSE
);
3035 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3036 ok(advance
== 1000, "got %i\n", advance
);
3039 hr
= IDWriteFontFace1_GetDesignGlyphAdvances(fontface1
, 1, &index
, &advance
, TRUE
);
3040 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3041 ok(advance
== 2048, "got %i\n", advance
);
3043 IDWriteFontFace1_Release(fontface1
);
3046 win_skip("GetDesignGlyphAdvances() is not supported.\n");
3048 IDWriteFontFace_Release(fontface
);
3049 IDWriteFactory_Release(factory
);
3050 DELETE_FONTFILE(path
);
3053 static void test_GetGlyphRunOutline(void)
3055 DWRITE_GLYPH_OFFSET offsets
[2];
3056 IDWriteFactory
*factory
;
3057 IDWriteFontFile
*file
;
3058 IDWriteFontFace
*face
;
3065 path
= create_testfontfile(test_fontfile
);
3066 factory
= create_factory();
3068 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3069 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3071 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
3072 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3073 IDWriteFontFile_Release(file
);
3077 hr
= IDWriteFontFace_GetGlyphIndices(face
, &codepoint
, 1, glyphs
);
3078 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3079 ok(glyphs
[0] > 0, "got %u\n", glyphs
[0]);
3080 glyphs
[1] = glyphs
[0];
3082 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 2048.0, glyphs
, advances
, offsets
, 1, FALSE
, FALSE
, NULL
);
3083 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3085 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 2048.0, NULL
, NULL
, offsets
, 1, FALSE
, FALSE
, &test_geomsink
);
3086 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3091 offsets
[0].advanceOffset
= 1.0;
3092 offsets
[0].ascenderOffset
= 1.0;
3093 offsets
[1].advanceOffset
= 0.0;
3094 offsets
[1].ascenderOffset
= 0.0;
3096 /* default advances, no offsets */
3097 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3098 g_startpoint_count
= 0;
3099 SET_EXPECT(setfillmode
);
3100 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 2, FALSE
, FALSE
, &test_geomsink
);
3101 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3102 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3103 if (g_startpoint_count
== 2) {
3104 /* glyph advance of 500 is applied */
3105 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
);
3106 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
);
3108 CHECK_CALLED(setfillmode
);
3110 /* default advances, no offsets, RTL */
3111 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3112 g_startpoint_count
= 0;
3113 SET_EXPECT(setfillmode
);
3114 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 2, FALSE
, TRUE
, &test_geomsink
);
3115 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3116 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3117 if (g_startpoint_count
== 2) {
3118 /* advance is -500 now */
3119 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
);
3120 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
);
3122 CHECK_CALLED(setfillmode
);
3124 /* default advances, additional offsets */
3125 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3126 g_startpoint_count
= 0;
3127 SET_EXPECT(setfillmode
);
3128 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, offsets
, 2, FALSE
, FALSE
, &test_geomsink
);
3129 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3130 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3131 if (g_startpoint_count
== 2) {
3132 /* offsets applied to first contour */
3133 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
);
3134 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
);
3136 CHECK_CALLED(setfillmode
);
3138 /* default advances, additional offsets, RTL */
3139 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3140 g_startpoint_count
= 0;
3141 SET_EXPECT(setfillmode
);
3142 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, offsets
, 2, FALSE
, TRUE
, &test_geomsink
);
3143 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3144 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3145 if (g_startpoint_count
== 2) {
3146 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
);
3147 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
);
3149 CHECK_CALLED(setfillmode
);
3151 /* custom advances and offsets, offset turns total advance value to zero */
3152 memset(g_startpoints
, 0, sizeof(g_startpoints
));
3153 g_startpoint_count
= 0;
3154 SET_EXPECT(setfillmode
);
3155 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, advances
, offsets
, 2, FALSE
, FALSE
, &test_geomsink
);
3156 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3157 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
3158 if (g_startpoint_count
== 2) {
3159 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
);
3160 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
);
3162 CHECK_CALLED(setfillmode
);
3165 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 0, FALSE
, FALSE
, &test_geomsink2
);
3166 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3168 IDWriteFactory_Release(factory
);
3169 IDWriteFontFace_Release(face
);
3170 DELETE_FONTFILE(path
);
3173 factory
= create_factory();
3174 face
= create_fontface(factory
);
3178 hr
= IDWriteFontFace_GetGlyphIndices(face
, &codepoint
, 1, glyphs
);
3179 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3180 ok(glyphs
[0] > 0, "got %u\n", glyphs
[0]);
3182 SET_EXPECT(setfillmode
);
3183 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 1, FALSE
, FALSE
, &test_geomsink2
);
3184 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3185 CHECK_CALLED(setfillmode
);
3187 IDWriteFactory_Release(factory
);
3188 IDWriteFontFace_Release(face
);
3191 static void test_GetEudcFontCollection(void)
3193 IDWriteFontCollection
*coll
, *coll2
;
3194 IDWriteFactory1
*factory1
;
3195 IDWriteFactory
*factory
;
3198 factory
= create_factory();
3200 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory1
, (void**)&factory1
);
3201 IDWriteFactory_Release(factory
);
3203 win_skip("GetEudcFontCollection() is not supported.\n");
3207 hr
= IDWriteFactory1_GetEudcFontCollection(factory1
, &coll
, FALSE
);
3208 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3209 hr
= IDWriteFactory1_GetEudcFontCollection(factory1
, &coll2
, FALSE
);
3210 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3211 ok(coll
== coll2
, "got %p, %p\n", coll
, coll2
);
3212 IDWriteFontCollection_Release(coll
);
3213 IDWriteFontCollection_Release(coll2
);
3215 IDWriteFactory1_Release(factory1
);
3218 static void test_GetCaretMetrics(void)
3220 DWRITE_FONT_METRICS1 metrics
;
3221 IDWriteFontFace1
*fontface1
;
3222 DWRITE_CARET_METRICS caret
;
3223 IDWriteFontFace
*fontface
;
3224 IDWriteFactory
*factory
;
3225 IDWriteFontFile
*file
;
3230 path
= create_testfontfile(test_fontfile
);
3231 factory
= create_factory();
3233 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3234 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3236 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3237 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3238 IDWriteFontFile_Release(file
);
3240 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3241 IDWriteFontFace_Release(fontface
);
3243 win_skip("GetCaretMetrics() is not supported.\n");
3244 IDWriteFactory_Release(factory
);
3245 DELETE_FONTFILE(path
);
3249 memset(&caret
, 0xcc, sizeof(caret
));
3250 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
3251 ok(caret
.slopeRise
== 1, "got %d\n", caret
.slopeRise
);
3252 ok(caret
.slopeRun
== 0, "got %d\n", caret
.slopeRun
);
3253 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
3254 IDWriteFontFace1_Release(fontface1
);
3255 IDWriteFactory_Release(factory
);
3257 /* now with Tahoma Normal */
3258 factory
= create_factory();
3259 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
3260 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3261 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3262 IDWriteFont_Release(font
);
3263 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3264 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3265 IDWriteFontFace_Release(fontface
);
3267 memset(&caret
, 0xcc, sizeof(caret
));
3268 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
3269 ok(caret
.slopeRise
== 1, "got %d\n", caret
.slopeRise
);
3270 ok(caret
.slopeRun
== 0, "got %d\n", caret
.slopeRun
);
3271 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
3272 IDWriteFontFace1_Release(fontface1
);
3274 /* simulated italic */
3275 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_ITALIC
);
3276 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3277 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3278 IDWriteFont_Release(font
);
3279 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3280 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3281 IDWriteFontFace_Release(fontface
);
3283 IDWriteFontFace1_GetMetrics(fontface1
, &metrics
);
3285 memset(&caret
, 0xcc, sizeof(caret
));
3286 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
3287 ok(caret
.slopeRise
== metrics
.designUnitsPerEm
, "got %d\n", caret
.slopeRise
);
3288 ok(caret
.slopeRun
> 0, "got %d\n", caret
.slopeRun
);
3289 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
3290 IDWriteFontFace1_Release(fontface1
);
3292 IDWriteFactory_Release(factory
);
3293 DELETE_FONTFILE(path
);
3296 static void test_GetGlyphCount(void)
3298 IDWriteFontFace
*fontface
;
3299 IDWriteFactory
*factory
;
3300 IDWriteFontFile
*file
;
3305 path
= create_testfontfile(test_fontfile
);
3306 factory
= create_factory();
3308 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3309 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3311 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3312 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3313 IDWriteFontFile_Release(file
);
3315 count
= IDWriteFontFace_GetGlyphCount(fontface
);
3316 ok(count
== 7, "got %u\n", count
);
3318 IDWriteFontFace_Release(fontface
);
3319 IDWriteFactory_Release(factory
);
3320 DELETE_FONTFILE(path
);
3323 static void test_GetKerningPairAdjustments(void)
3325 IDWriteFontFace1
*fontface1
;
3326 IDWriteFontFace
*fontface
;
3327 IDWriteFactory
*factory
;
3328 IDWriteFontFile
*file
;
3332 path
= create_testfontfile(test_fontfile
);
3333 factory
= create_factory();
3335 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3336 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3338 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3339 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3340 IDWriteFontFile_Release(file
);
3342 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3344 INT32 adjustments
[1];
3346 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 0, NULL
, NULL
);
3347 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
3349 if (0) /* crashes on native */
3350 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 1, NULL
, NULL
);
3353 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 1, NULL
, adjustments
);
3354 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3355 ok(adjustments
[0] == 0, "got %d\n", adjustments
[0]);
3357 IDWriteFontFace1_Release(fontface1
);
3360 win_skip("GetKerningPairAdjustments() is not supported.\n");
3362 IDWriteFontFace_Release(fontface
);
3363 IDWriteFactory_Release(factory
);
3364 DELETE_FONTFILE(path
);
3367 static void test_CreateRenderingParams(void)
3369 IDWriteRenderingParams2
*params2
;
3370 IDWriteRenderingParams1
*params1
;
3371 IDWriteRenderingParams
*params
;
3372 DWRITE_RENDERING_MODE mode
;
3373 IDWriteFactory
*factory
;
3376 factory
= create_factory();
3378 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 1.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT
,
3379 DWRITE_RENDERING_MODE_DEFAULT
, ¶ms
);
3380 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3382 hr
= IDWriteRenderingParams_QueryInterface(params
, &IID_IDWriteRenderingParams1
, (void**)¶ms1
);
3386 /* test what enhanced contrast setting set by default to */
3387 enhcontrast
= IDWriteRenderingParams1_GetGrayscaleEnhancedContrast(params1
);
3388 ok(enhcontrast
== 1.0, "got %.2f\n", enhcontrast
);
3389 IDWriteRenderingParams1_Release(params1
);
3391 hr
= IDWriteRenderingParams_QueryInterface(params
, &IID_IDWriteRenderingParams2
, (void**)¶ms2
);
3393 DWRITE_GRID_FIT_MODE gridfit
;
3395 /* default gridfit mode */
3396 gridfit
= IDWriteRenderingParams2_GetGridFitMode(params2
);
3397 ok(gridfit
== DWRITE_GRID_FIT_MODE_DEFAULT
, "got %d\n", gridfit
);
3399 IDWriteRenderingParams2_Release(params2
);
3402 win_skip("IDWriteRenderingParams2 not supported.\n");
3405 win_skip("IDWriteRenderingParams1 not supported.\n");
3407 IDWriteRenderingParams_Release(params
);
3409 hr
= IDWriteFactory_CreateRenderingParams(factory
, ¶ms
);
3410 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3412 mode
= IDWriteRenderingParams_GetRenderingMode(params
);
3413 ok(mode
== DWRITE_RENDERING_MODE_DEFAULT
, "got %d\n", mode
);
3414 IDWriteRenderingParams_Release(params
);
3416 IDWriteFactory_Release(factory
);
3419 static void test_CreateGlyphRunAnalysis(void)
3421 static const DWRITE_RENDERING_MODE rendermodes
[] = {
3422 DWRITE_RENDERING_MODE_ALIASED
,
3423 DWRITE_RENDERING_MODE_GDI_CLASSIC
,
3424 DWRITE_RENDERING_MODE_GDI_NATURAL
,
3425 DWRITE_RENDERING_MODE_NATURAL
,
3426 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
,
3429 IDWriteGlyphRunAnalysis
*analysis
;
3430 IDWriteFactory
*factory
;
3431 DWRITE_GLYPH_RUN run
;
3432 IDWriteFontFace
*face
;
3438 DWRITE_GLYPH_OFFSET offset
;
3439 DWRITE_GLYPH_METRICS metrics
;
3440 DWRITE_FONT_METRICS fm
;
3443 factory
= create_factory();
3444 face
= create_fontface(factory
);
3448 hr
= IDWriteFontFace_GetGlyphIndices(face
, &ch
, 1, &glyph
);
3449 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3450 ok(glyph
> 0, "got %u\n", glyph
);
3452 hr
= IDWriteFontFace_GetDesignGlyphMetrics(face
, &glyph
, 1, &metrics
, FALSE
);
3453 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3454 advance
= metrics
.advanceWidth
;
3456 offset
.advanceOffset
= 0.0;
3457 offset
.ascenderOffset
= 0.0;
3459 run
.fontFace
= face
;
3460 run
.fontEmSize
= 24.0;
3462 run
.glyphIndices
= &glyph
;
3463 run
.glyphAdvances
= &advance
;
3464 run
.glyphOffsets
= &offset
;
3465 run
.isSideways
= FALSE
;
3468 /* default mode is not allowed */
3469 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3470 DWRITE_RENDERING_MODE_DEFAULT
, DWRITE_MEASURING_MODE_NATURAL
,
3471 0.0, 0.0, &analysis
);
3472 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3475 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3476 DWRITE_RENDERING_MODE_OUTLINE
, DWRITE_MEASURING_MODE_NATURAL
,
3477 0.0, 0.0, &analysis
);
3478 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3480 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3481 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
3482 0.0, 0.0, &analysis
);
3483 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3485 /* invalid texture type */
3486 memset(&rect
, 0xcc, sizeof(rect
));
3487 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
+1, &rect
);
3488 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3489 ok(rect
.left
== 0 && rect
.right
== 0 &&
3490 rect
.top
== 0 && rect
.bottom
== 0, "unexpected rect\n");
3491 IDWriteGlyphRunAnalysis_Release(analysis
);
3493 for (i
= 0; i
< sizeof(rendermodes
)/sizeof(rendermodes
[0]); i
++) {
3494 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3495 rendermodes
[i
], DWRITE_MEASURING_MODE_NATURAL
,
3496 0.0, 0.0, &analysis
);
3497 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3499 if (rendermodes
[i
] == DWRITE_RENDERING_MODE_ALIASED
) {
3500 memset(&rect
, 0, sizeof(rect
));
3501 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3503 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3504 ok(!IsRectEmpty(&rect
), "got empty rect\n");
3506 rect
.left
= rect
.top
= 0;
3507 rect
.bottom
= rect
.right
= 1;
3508 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &rect
);
3509 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3510 ok(IsRectEmpty(&rect
), "unexpected empty rect\n");
3513 rect
.left
= rect
.top
= 0;
3514 rect
.bottom
= rect
.right
= 1;
3515 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3516 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3517 ok(IsRectEmpty(&rect
), "got empty rect\n");
3519 memset(&rect
, 0, sizeof(rect
));
3520 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &rect
);
3522 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3523 ok(!IsRectEmpty(&rect
), "got empty rect\n");
3527 IDWriteGlyphRunAnalysis_Release(analysis
);
3530 IDWriteFontFace_GetMetrics(run
.fontFace
, &fm
);
3532 /* check bbox for a single glyph run */
3533 for (run
.fontEmSize
= 1.0; run
.fontEmSize
<= 100.0; run
.fontEmSize
+= 1.0) {
3534 DWRITE_GLYPH_METRICS gm
;
3537 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
3538 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
3539 0.0, 0.0, &analysis
);
3540 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3542 memset(&rect
, 0, sizeof(rect
));
3543 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
3545 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3549 hr
= IDWriteFontFace_GetGdiCompatibleGlyphMetrics(run
.fontFace
, run
.fontEmSize
, 1.0, NULL
,
3550 DWRITE_MEASURING_MODE_GDI_CLASSIC
, run
.glyphIndices
, 1, &gm
, run
.isSideways
);
3551 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3553 /* metrics are in design units */
3554 bboxX
= (int)floorf((gm
.advanceWidth
- gm
.leftSideBearing
- gm
.rightSideBearing
) * run
.fontEmSize
/ fm
.designUnitsPerEm
+ 0.5f
);
3555 bboxY
= (int)floorf((gm
.advanceHeight
- gm
.topSideBearing
- gm
.bottomSideBearing
) * run
.fontEmSize
/ fm
.designUnitsPerEm
+ 0.5f
);
3557 rect
.right
-= rect
.left
;
3558 rect
.bottom
-= rect
.top
;
3559 ok(abs(bboxX
- rect
.right
) <= 1, "%.0f: bbox width %d, from metrics %d\n", run
.fontEmSize
, rect
.right
, bboxX
);
3560 ok(abs(bboxY
- rect
.bottom
) <= 1, "%.0f: bbox height %d, from metrics %d\n", run
.fontEmSize
, rect
.bottom
, bboxY
);
3562 IDWriteGlyphRunAnalysis_Release(analysis
);
3565 IDWriteFontFace_Release(face
);
3566 IDWriteFactory_Release(factory
);
3569 #define round(x) ((int)floor((x) + 0.5))
3600 #ifdef WORDS_BIGENDIAN
3601 #define GET_BE_WORD(x) (x)
3603 #define GET_BE_WORD(x) RtlUshortByteSwap(x)
3606 static const struct VDMX_group
*find_vdmx_group(const struct VDMX_Header
*hdr
)
3608 WORD num_ratios
, i
, group_offset
= 0;
3609 struct VDMX_Ratio
*ratios
= (struct VDMX_Ratio
*)(hdr
+ 1);
3610 BYTE dev_x_ratio
= 1, dev_y_ratio
= 1;
3612 num_ratios
= GET_BE_WORD(hdr
->numRatios
);
3614 for (i
= 0; i
< num_ratios
; i
++)
3616 if (!ratios
[i
].bCharSet
) continue;
3618 if ((ratios
[i
].xRatio
== 0 && ratios
[i
].yStartRatio
== 0 &&
3619 ratios
[i
].yEndRatio
== 0) ||
3620 (ratios
[i
].xRatio
== dev_x_ratio
&& ratios
[i
].yStartRatio
<= dev_y_ratio
&&
3621 ratios
[i
].yEndRatio
>= dev_y_ratio
))
3623 group_offset
= GET_BE_WORD(*((WORD
*)(ratios
+ num_ratios
) + i
));
3628 return (const struct VDMX_group
*)((BYTE
*)hdr
+ group_offset
);
3632 static BOOL
get_vdmx_size(const struct VDMX_group
*group
, int emsize
, int *a
, int *d
)
3635 const struct VDMX_vTable
*tables
;
3637 if (!group
) return FALSE
;
3639 recs
= GET_BE_WORD(group
->recs
);
3640 if (emsize
< group
->startsz
|| emsize
>= group
->endsz
) return FALSE
;
3642 tables
= (const struct VDMX_vTable
*)(group
+ 1);
3643 for (i
= 0; i
< recs
; i
++)
3645 WORD ppem
= GET_BE_WORD(tables
[i
].yPelHeight
);
3648 /* FIXME: Supposed to interpolate */
3649 trace("FIXME interpolate %d\n", emsize
);
3655 *a
= (SHORT
)GET_BE_WORD(tables
[i
].yMax
);
3656 *d
= -(SHORT
)GET_BE_WORD(tables
[i
].yMin
);
3663 static void test_metrics_cmp(FLOAT emsize
, const DWRITE_FONT_METRICS
*metrics
, const DWRITE_FONT_METRICS1
*expected
)
3665 ok(metrics
->designUnitsPerEm
== expected
->designUnitsPerEm
, "%.2f: emsize: got %u expect %u\n",
3666 emsize
, metrics
->designUnitsPerEm
, expected
->designUnitsPerEm
);
3667 ok(metrics
->ascent
== expected
->ascent
, "%.2f a: got %u expect %u\n",
3668 emsize
, metrics
->ascent
, expected
->ascent
);
3669 ok(metrics
->descent
== expected
->descent
, "%.2f d: got %u expect %u\n",
3670 emsize
, metrics
->descent
, expected
->descent
);
3671 ok(metrics
->lineGap
== expected
->lineGap
, "%.2f lg: got %d expect %d\n",
3672 emsize
, metrics
->lineGap
, expected
->lineGap
);
3673 ok(metrics
->capHeight
== expected
->capHeight
, "%.2f capH: got %u expect %u\n",
3674 emsize
, metrics
->capHeight
, expected
->capHeight
);
3675 ok(metrics
->xHeight
== expected
->xHeight
, "%.2f xH: got %u expect %u\n",
3676 emsize
, metrics
->xHeight
, expected
->xHeight
);
3677 ok(metrics
->underlinePosition
== expected
->underlinePosition
, "%.2f ulP: got %d expect %d\n",
3678 emsize
, metrics
->underlinePosition
, expected
->underlinePosition
);
3679 ok(metrics
->underlineThickness
== expected
->underlineThickness
, "%.2f ulTh: got %u expect %u\n",
3680 emsize
, metrics
->underlineThickness
, expected
->underlineThickness
);
3681 ok(metrics
->strikethroughPosition
== expected
->strikethroughPosition
, "%.2f stP: got %d expect %d\n",
3682 emsize
, metrics
->strikethroughPosition
, expected
->strikethroughPosition
);
3683 ok(metrics
->strikethroughThickness
== expected
->strikethroughThickness
, "%.2f stTh: got %u expect %u\n",
3684 emsize
, metrics
->strikethroughThickness
, expected
->strikethroughThickness
);
3687 static void test_metrics1_cmp(FLOAT emsize
, const DWRITE_FONT_METRICS1
*metrics
, const DWRITE_FONT_METRICS1
*expected
)
3689 ok(metrics
->designUnitsPerEm
== expected
->designUnitsPerEm
, "%.2f: emsize: got %u expect %u\n",
3690 emsize
, metrics
->designUnitsPerEm
, expected
->designUnitsPerEm
);
3691 ok(metrics
->ascent
== expected
->ascent
, "%.2f a: got %u expect %u\n",
3692 emsize
, metrics
->ascent
, expected
->ascent
);
3693 ok(metrics
->descent
== expected
->descent
, "%.2f d: got %u expect %u\n",
3694 emsize
, metrics
->descent
, expected
->descent
);
3695 ok(metrics
->lineGap
== expected
->lineGap
, "%.2f lg: got %d expect %d\n",
3696 emsize
, metrics
->lineGap
, expected
->lineGap
);
3697 ok(metrics
->capHeight
== expected
->capHeight
, "%.2f capH: got %u expect %u\n",
3698 emsize
, metrics
->capHeight
, expected
->capHeight
);
3699 ok(metrics
->xHeight
== expected
->xHeight
, "%.2f xH: got %u expect %u\n",
3700 emsize
, metrics
->xHeight
, expected
->xHeight
);
3701 ok(metrics
->underlinePosition
== expected
->underlinePosition
, "%.2f ulP: got %d expect %d\n",
3702 emsize
, metrics
->underlinePosition
, expected
->underlinePosition
);
3703 ok(metrics
->underlineThickness
== expected
->underlineThickness
, "%.2f ulTh: got %u expect %u\n",
3704 emsize
, metrics
->underlineThickness
, expected
->underlineThickness
);
3705 ok(metrics
->strikethroughPosition
== expected
->strikethroughPosition
, "%.2f stP: got %d expect %d\n",
3706 emsize
, metrics
->strikethroughPosition
, expected
->strikethroughPosition
);
3707 ok(metrics
->strikethroughThickness
== expected
->strikethroughThickness
, "%.2f stTh: got %u expect %u\n",
3708 emsize
, metrics
->strikethroughThickness
, expected
->strikethroughThickness
);
3709 ok(metrics
->glyphBoxLeft
== expected
->glyphBoxLeft
, "%.2f box left: got %d expect %d\n",
3710 emsize
, metrics
->glyphBoxLeft
, expected
->glyphBoxLeft
);
3711 if (0) { /* this is not consistent */
3712 ok(metrics
->glyphBoxTop
== expected
->glyphBoxTop
, "%.2f box top: got %d expect %d\n",
3713 emsize
, metrics
->glyphBoxTop
, expected
->glyphBoxTop
);
3714 ok(metrics
->glyphBoxRight
== expected
->glyphBoxRight
, "%.2f box right: got %d expect %d\n",
3715 emsize
, metrics
->glyphBoxRight
, expected
->glyphBoxRight
);
3717 ok(metrics
->glyphBoxBottom
== expected
->glyphBoxBottom
, "%.2f box bottom: got %d expect %d\n",
3718 emsize
, metrics
->glyphBoxBottom
, expected
->glyphBoxBottom
);
3719 ok(metrics
->subscriptPositionX
== expected
->subscriptPositionX
, "%.2f subX: got %d expect %d\n",
3720 emsize
, metrics
->subscriptPositionX
, expected
->subscriptPositionX
);
3721 ok(metrics
->subscriptPositionY
== expected
->subscriptPositionY
, "%.2f subY: got %d expect %d\n",
3722 emsize
, metrics
->subscriptPositionY
, expected
->subscriptPositionY
);
3723 ok(metrics
->subscriptSizeX
== expected
->subscriptSizeX
, "%.2f subsizeX: got %d expect %d\n",
3724 emsize
, metrics
->subscriptSizeX
, expected
->subscriptSizeX
);
3725 ok(metrics
->subscriptPositionY
== expected
->subscriptPositionY
, "%.2f subsizeY: got %d expect %d\n",
3726 emsize
, metrics
->subscriptSizeY
, expected
->subscriptSizeY
);
3727 ok(metrics
->superscriptPositionX
== expected
->superscriptPositionX
, "%.2f supX: got %d expect %d\n",
3728 emsize
, metrics
->superscriptPositionX
, expected
->superscriptPositionX
);
3730 ok(metrics
->superscriptPositionY
== expected
->superscriptPositionY
, "%.2f supY: got %d expect %d\n",
3731 emsize
, metrics
->superscriptPositionY
, expected
->superscriptPositionY
);
3732 ok(metrics
->superscriptSizeX
== expected
->superscriptSizeX
, "%.2f supsizeX: got %d expect %d\n",
3733 emsize
, metrics
->superscriptSizeX
, expected
->superscriptSizeX
);
3734 ok(metrics
->superscriptSizeY
== expected
->superscriptSizeY
, "%.2f supsizeY: got %d expect %d\n",
3735 emsize
, metrics
->superscriptSizeY
, expected
->superscriptSizeY
);
3736 ok(metrics
->hasTypographicMetrics
== expected
->hasTypographicMetrics
, "%.2f hastypo: got %d expect %d\n",
3737 emsize
, metrics
->hasTypographicMetrics
, expected
->hasTypographicMetrics
);
3740 struct compatmetrics_test
{
3746 static struct compatmetrics_test compatmetrics_tests
[] = {
3747 { { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, 1.0, 5.0 },
3748 { { 0.0, 0.0, 0.0, -1.0, 0.0, 0.0 }, 1.0, 5.0 },
3749 { { 0.0, 0.0, 0.0, -1.0, 0.0, 0.0 }, 2.0, 5.0 },
3750 { { 0.0, 0.0, 0.0, 3.0, 0.0, 0.0 }, 2.0, 5.0 },
3751 { { 0.0, 0.0, 0.0, -3.0, 0.0, 0.0 }, 2.0, 5.0 },
3752 { { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, 2.0, 5.0 },
3753 { { 1.0, 0.0, 0.0, 1.0, 5.0, 0.0 }, 2.0, 5.0 },
3754 { { 1.0, 0.0, 0.0, 1.0, 0.0, 5.0 }, 2.0, 5.0 },
3757 static void get_expected_metrics(IDWriteFontFace
*fontface
, struct compatmetrics_test
*ptr
,
3758 DWRITE_FONT_METRICS
*expected
)
3762 memset(expected
, 0, sizeof(*expected
));
3763 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(fontface
, ptr
->ppdip
* fabsf(ptr
->m
.m22
) * ptr
->emsize
, 1.0, NULL
, expected
);
3764 ok(hr
== S_OK
, "got %08x\n", hr
);
3767 static void test_GetGdiCompatibleMetrics_face(IDWriteFontFace
*face
)
3769 IDWriteFontFace1
*fontface1
= NULL
;
3771 DWRITE_FONT_METRICS design_metrics
, comp_metrics
;
3772 DWRITE_FONT_METRICS1 design_metrics1
, expected
;
3773 FLOAT emsize
, scale
;
3774 int ascent
, descent
;
3775 const struct VDMX_Header
*vdmx
;
3779 const struct VDMX_group
*vdmx_group
= NULL
;
3782 hr
= IDWriteFontFace_QueryInterface(face
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3784 win_skip("gdi compatible DWRITE_FONT_METRICS1 are not supported.\n");
3787 IDWriteFontFace1_GetMetrics(fontface1
, &design_metrics1
);
3788 memcpy(&design_metrics
, &design_metrics1
, sizeof(design_metrics
));
3791 IDWriteFontFace_GetMetrics(face
, &design_metrics
);
3793 hr
= IDWriteFontFace_TryGetFontTable(face
, MS_VDMX_TAG
, (const void **)&vdmx
,
3794 &vdmx_len
, &vdmx_ctx
, &exists
);
3795 if (hr
!= S_OK
|| !exists
)
3798 vdmx_group
= find_vdmx_group(vdmx
);
3800 /* negative emsize */
3801 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
3802 memset(&expected
, 0, sizeof(expected
));
3803 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, -10.0, 1.0, NULL
, &comp_metrics
);
3804 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
3805 test_metrics_cmp(0.0, &comp_metrics
, &expected
);
3808 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
3809 memset(&expected
, 0, sizeof(expected
));
3810 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 0.0, 1.0, NULL
, &comp_metrics
);
3811 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
3812 test_metrics_cmp(0.0, &comp_metrics
, &expected
);
3814 /* zero pixels per dip */
3815 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
3816 memset(&expected
, 0, sizeof(expected
));
3817 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 5.0, 0.0, NULL
, &comp_metrics
);
3818 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
3819 test_metrics_cmp(5.0, &comp_metrics
, &expected
);
3821 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
3822 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 5.0, -1.0, NULL
, &comp_metrics
);
3823 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
3824 test_metrics_cmp(5.0, &comp_metrics
, &expected
);
3826 for (i
= 0; i
< sizeof(compatmetrics_tests
)/sizeof(compatmetrics_tests
[0]); i
++) {
3827 struct compatmetrics_test
*ptr
= &compatmetrics_tests
[i
];
3829 get_expected_metrics(face
, ptr
, (DWRITE_FONT_METRICS
*)&expected
);
3830 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, ptr
->emsize
, ptr
->ppdip
, &ptr
->m
, &comp_metrics
);
3831 ok(hr
== S_OK
, "got %08x\n", hr
);
3832 test_metrics_cmp(ptr
->emsize
, &comp_metrics
, &expected
);
3835 for (emsize
= 5; emsize
<= design_metrics
.designUnitsPerEm
; emsize
++)
3837 DWRITE_FONT_METRICS1 comp_metrics1
, expected
;
3840 hr
= IDWriteFontFace1_GetGdiCompatibleMetrics(fontface1
, emsize
, 1.0, NULL
, &comp_metrics1
);
3841 ok(hr
== S_OK
, "got %08x\n", hr
);
3844 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, emsize
, 1.0, NULL
, &comp_metrics
);
3845 ok(hr
== S_OK
, "got %08x\n", hr
);
3848 scale
= emsize
/ design_metrics
.designUnitsPerEm
;
3849 if (!get_vdmx_size(vdmx_group
, emsize
, &ascent
, &descent
))
3851 ascent
= round(design_metrics
.ascent
* scale
);
3852 descent
= round(design_metrics
.descent
* scale
);
3855 expected
.designUnitsPerEm
= design_metrics
.designUnitsPerEm
;
3856 expected
.ascent
= round(ascent
/ scale
);
3857 expected
.descent
= round(descent
/ scale
);
3858 expected
.lineGap
= round(round(design_metrics
.lineGap
* scale
) / scale
);
3859 expected
.capHeight
= round(round(design_metrics
.capHeight
* scale
) / scale
);
3860 expected
.xHeight
= round(round(design_metrics
.xHeight
* scale
) / scale
);
3861 expected
.underlinePosition
= round(round(design_metrics
.underlinePosition
* scale
) / scale
);
3862 expected
.underlineThickness
= round(round(design_metrics
.underlineThickness
* scale
) / scale
);
3863 expected
.strikethroughPosition
= round(round(design_metrics
.strikethroughPosition
* scale
) / scale
);
3864 expected
.strikethroughThickness
= round(round(design_metrics
.strikethroughThickness
* scale
) / scale
);
3867 expected
.glyphBoxLeft
= round(round(design_metrics1
.glyphBoxLeft
* scale
) / scale
);
3869 if (0) { /* those two fail on Tahoma and Win7 */
3870 expected
.glyphBoxTop
= round(round(design_metrics1
.glyphBoxTop
* scale
) / scale
);
3871 expected
.glyphBoxRight
= round(round(design_metrics1
.glyphBoxRight
* scale
) / scale
);
3873 expected
.glyphBoxBottom
= round(round(design_metrics1
.glyphBoxBottom
* scale
) / scale
);
3874 expected
.subscriptPositionX
= round(round(design_metrics1
.subscriptPositionX
* scale
) / scale
);
3875 expected
.subscriptPositionY
= round(round(design_metrics1
.subscriptPositionY
* scale
) / scale
);
3876 expected
.subscriptSizeX
= round(round(design_metrics1
.subscriptSizeX
* scale
) / scale
);
3877 expected
.subscriptSizeY
= round(round(design_metrics1
.subscriptSizeY
* scale
) / scale
);
3878 expected
.superscriptPositionX
= round(round(design_metrics1
.superscriptPositionX
* scale
) / scale
);
3879 if (0) /* this fails for 3 emsizes, Tahoma from [5, 2048] range */
3880 expected
.superscriptPositionY
= round(round(design_metrics1
.superscriptPositionY
* scale
) / scale
);
3881 expected
.superscriptSizeX
= round(round(design_metrics1
.superscriptSizeX
* scale
) / scale
);
3882 expected
.superscriptSizeY
= round(round(design_metrics1
.superscriptSizeY
* scale
) / scale
);
3883 expected
.hasTypographicMetrics
= design_metrics1
.hasTypographicMetrics
;
3885 test_metrics1_cmp(emsize
, &comp_metrics1
, &expected
);
3888 test_metrics_cmp(emsize
, &comp_metrics
, &expected
);
3893 IDWriteFontFace1_Release(fontface1
);
3894 if (vdmx
) IDWriteFontFace_ReleaseFontTable(face
, vdmx_ctx
);
3897 static void test_GetGdiCompatibleMetrics(void)
3899 IDWriteFactory
*factory
;
3901 IDWriteFontFace
*fontface
;
3904 factory
= create_factory();
3906 font
= get_font(factory
, tahomaW
, DWRITE_FONT_STYLE_NORMAL
);
3907 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3908 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3909 IDWriteFont_Release(font
);
3910 test_GetGdiCompatibleMetrics_face(fontface
);
3911 IDWriteFontFace_Release(fontface
);
3913 font
= get_font(factory
, arialW
, DWRITE_FONT_STYLE_NORMAL
);
3915 skip("Skipping tests with Arial\n");
3918 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3919 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3920 IDWriteFont_Release(font
);
3922 test_GetGdiCompatibleMetrics_face(fontface
);
3923 IDWriteFontFace_Release(fontface
);
3926 IDWriteFactory_Release(factory
);
3929 static void test_GetPanose(void)
3931 IDWriteFactory
*factory
;
3932 IDWriteFont1
*font1
;
3936 factory
= create_factory();
3937 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
3939 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
3940 IDWriteFont_Release(font
);
3942 DWRITE_PANOSE panose
;
3944 if (0) /* crashes on native */
3945 IDWriteFont1_GetPanose(font1
, NULL
);
3947 memset(&panose
, 0, sizeof(panose
));
3948 IDWriteFont1_GetPanose(font1
, &panose
);
3949 ok(panose
.familyKind
== DWRITE_PANOSE_FAMILY_TEXT_DISPLAY
,
3950 "got %u\n", panose
.familyKind
);
3951 ok(panose
.text
.serifStyle
== DWRITE_PANOSE_SERIF_STYLE_NORMAL_SANS
,
3952 "got %u\n", panose
.text
.serifStyle
);
3953 ok(panose
.text
.weight
== DWRITE_PANOSE_WEIGHT_MEDIUM
,
3954 "got %u\n", panose
.text
.weight
);
3955 ok(panose
.text
.proportion
== DWRITE_PANOSE_PROPORTION_EVEN_WIDTH
,
3956 "got %u\n", panose
.text
.proportion
);
3957 ok(panose
.text
.contrast
== DWRITE_PANOSE_CONTRAST_VERY_LOW
,
3958 "got %u\n", panose
.text
.contrast
);
3959 ok(panose
.text
.strokeVariation
== DWRITE_PANOSE_STROKE_VARIATION_GRADUAL_VERTICAL
,
3960 "got %u\n", panose
.text
.strokeVariation
);
3961 ok(panose
.text
.armStyle
== DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_VERTICAL
,
3962 "got %u\n", panose
.text
.armStyle
);
3963 ok(panose
.text
.letterform
== DWRITE_PANOSE_LETTERFORM_NORMAL_BOXED
,
3964 "got %u\n", panose
.text
.letterform
);
3965 ok(panose
.text
.midline
== DWRITE_PANOSE_MIDLINE_STANDARD_TRIMMED
,
3966 "got %u\n", panose
.text
.midline
);
3967 ok(panose
.text
.xHeight
== DWRITE_PANOSE_XHEIGHT_CONSTANT_LARGE
,
3968 "got %u\n", panose
.text
.xHeight
);
3970 IDWriteFont1_Release(font1
);
3973 win_skip("GetPanose() is not supported.\n");
3975 IDWriteFactory_Release(factory
);
3978 static INT32
get_gdi_font_advance(HDC hdc
, FLOAT emsize
)
3985 memset(&logfont
, 0, sizeof(logfont
));
3986 logfont
.lfHeight
= (LONG
)-emsize
;
3987 logfont
.lfWeight
= FW_NORMAL
;
3988 logfont
.lfQuality
= CLEARTYPE_QUALITY
;
3989 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
3991 hfont
= CreateFontIndirectW(&logfont
);
3992 SelectObject(hdc
, hfont
);
3994 ret
= GetCharABCWidthsW(hdc
, 'A', 'A', &abc
);
3995 ok(ret
, "got %d\n", ret
);
3997 DeleteObject(hfont
);
3999 return abc
.abcA
+ abc
.abcB
+ abc
.abcC
;
4002 static void test_GetGdiCompatibleGlyphAdvances(void)
4004 IDWriteFontFace1
*fontface1
;
4005 IDWriteFontFace
*fontface
;
4006 IDWriteFactory
*factory
;
4013 DWRITE_FONT_METRICS1 fm
;
4016 factory
= create_factory();
4017 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
4019 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4020 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4021 IDWriteFont_Release(font
);
4023 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4024 IDWriteFontFace_Release(fontface
);
4027 IDWriteFactory_Release(factory
);
4028 win_skip("GetGdiCompatibleGlyphAdvances() is not supported\n");
4034 hr
= IDWriteFontFace1_GetGlyphIndices(fontface1
, &codepoint
, 1, &glyph
);
4035 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4036 ok(glyph
> 0, "got %u\n", glyph
);
4040 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 0.0,
4041 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4042 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4043 ok(advance
== 0, "got %d\n", advance
);
4045 /* negative emsize */
4047 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, -1.0,
4048 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4049 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4050 ok(advance
== 0, "got %d\n", advance
);
4054 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 1.0,
4055 0.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4056 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4057 ok(advance
== 0, "got %d\n", advance
);
4059 /* negative ppdip */
4061 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 1.0,
4062 -1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4063 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4064 ok(advance
== 0, "got %d\n", advance
);
4066 IDWriteFontFace1_GetMetrics(fontface1
, &fm
);
4068 hdc
= CreateCompatibleDC(0);
4070 for (emsize
= 1.0; emsize
<= fm
.designUnitsPerEm
; emsize
+= 1.0) {
4073 gdi_advance
= get_gdi_font_advance(hdc
, emsize
);
4074 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, emsize
,
4075 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
4076 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4078 /* advance is in design units */
4079 advance
= (int)floorf(emsize
* advance
/ fm
.designUnitsPerEm
+ 0.5f
);
4081 /* allow 1 pixel difference for large sizes, for Tahoma this happens for 16 sizes in [1, 2048] range */
4083 ok((advance
- gdi_advance
) <= 1, "%.0f: got advance %d, expected %d\n", emsize
, advance
, gdi_advance
);
4085 ok(gdi_advance
== advance
, "%.0f: got advance %d, expected %d\n", emsize
, advance
, gdi_advance
);
4090 IDWriteFactory_Release(factory
);
4093 static WORD
get_gasp_flags(IDWriteFontFace
*fontface
, FLOAT emsize
)
4095 WORD num_recs
, version
;
4104 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_GASP_TAG
,
4105 (const void**)&ptr
, &size
, &ctxt
, &exists
);
4106 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4111 version
= GET_BE_WORD( *ptr
++ );
4112 num_recs
= GET_BE_WORD( *ptr
++ );
4113 if (version
> 1 || size
< (num_recs
* 2 + 2) * sizeof(WORD
)) {
4114 ok(0, "unsupported gasp table: ver %d size %d recs %d\n", version
, size
, num_recs
);
4120 flags
= GET_BE_WORD( *(ptr
+ 1) );
4121 if (emsize
<= GET_BE_WORD( *ptr
)) break;
4126 IDWriteFontFace_ReleaseFontTable(fontface
, ctxt
);
4130 #define GASP_GRIDFIT 0x0001
4131 #define GASP_DOGRAY 0x0002
4132 #define GASP_SYMMETRIC_GRIDFIT 0x0004
4133 #define GASP_SYMMETRIC_SMOOTHING 0x0008
4135 static BOOL g_is_vista
;
4136 static DWRITE_RENDERING_MODE
get_expected_rendering_mode(FLOAT emsize
, WORD gasp
, DWRITE_MEASURING_MODE mode
,
4137 DWRITE_OUTLINE_THRESHOLD threshold
)
4139 static const FLOAT aa_threshold
= 100.0f
;
4140 static const FLOAT a_threshold
= 350.0f
;
4141 static const FLOAT naturalemsize
= 20.0f
;
4144 /* outline threshold */
4146 v
= mode
== DWRITE_MEASURING_MODE_NATURAL
? aa_threshold
: a_threshold
;
4148 v
= threshold
== DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
? aa_threshold
: a_threshold
;
4151 return DWRITE_RENDERING_MODE_OUTLINE
;
4155 case DWRITE_MEASURING_MODE_NATURAL
:
4156 if (!(gasp
& GASP_SYMMETRIC_SMOOTHING
) && (emsize
<= naturalemsize
))
4157 return DWRITE_RENDERING_MODE_NATURAL
;
4159 return DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
;
4160 case DWRITE_MEASURING_MODE_GDI_CLASSIC
:
4161 return DWRITE_RENDERING_MODE_GDI_CLASSIC
;
4162 case DWRITE_MEASURING_MODE_GDI_NATURAL
:
4163 return DWRITE_RENDERING_MODE_GDI_NATURAL
;
4168 /* should be unreachable */
4169 return DWRITE_RENDERING_MODE_DEFAULT
;
4172 static DWRITE_GRID_FIT_MODE
get_expected_gridfit_mode(FLOAT emsize
, WORD gasp
, DWRITE_MEASURING_MODE mode
,
4173 DWRITE_OUTLINE_THRESHOLD threshold
)
4175 static const FLOAT aa_threshold
= 100.0f
;
4176 static const FLOAT a_threshold
= 350.0f
;
4179 v
= threshold
== DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
? aa_threshold
: a_threshold
;
4181 return DWRITE_GRID_FIT_MODE_DISABLED
;
4183 if (mode
== DWRITE_MEASURING_MODE_GDI_CLASSIC
|| mode
== DWRITE_MEASURING_MODE_GDI_NATURAL
)
4184 return DWRITE_GRID_FIT_MODE_ENABLED
;
4186 return (gasp
& (GASP_GRIDFIT
|GASP_SYMMETRIC_GRIDFIT
)) ? DWRITE_GRID_FIT_MODE_ENABLED
: DWRITE_GRID_FIT_MODE_DISABLED
;
4189 struct recommendedmode_test
4191 DWRITE_MEASURING_MODE measuring
;
4192 DWRITE_OUTLINE_THRESHOLD threshold
;
4195 static const struct recommendedmode_test recmode_tests
[] = {
4196 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4197 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4198 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4201 static const struct recommendedmode_test recmode_tests1
[] = {
4202 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4203 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4204 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
4205 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
4206 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
4207 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
4210 static void test_GetRecommendedRenderingMode(void)
4212 IDWriteRenderingParams
*params
;
4213 IDWriteFontFace2
*fontface2
;
4214 IDWriteFontFace1
*fontface1
;
4215 IDWriteFontFace
*fontface
;
4216 DWRITE_RENDERING_MODE mode
;
4217 IDWriteFactory
*factory
;
4221 factory
= create_factory();
4222 fontface
= create_fontface(factory
);
4225 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4227 win_skip("IDWriteFontFace1::GetRecommendedRenderingMode() is not supported.\n");
4230 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
4232 win_skip("IDWriteFontFace2::GetRecommendedRenderingMode() is not supported.\n");
4234 if (0) /* crashes on native */
4235 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 3.0, 1.0,
4236 DWRITE_MEASURING_MODE_GDI_CLASSIC
, NULL
, NULL
);
4239 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 3.0, 1.0,
4240 DWRITE_MEASURING_MODE_GDI_CLASSIC
, NULL
, &mode
);
4241 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4242 ok(mode
== DWRITE_RENDERING_MODE_DEFAULT
, "got %d\n", mode
);
4244 hr
= IDWriteFactory_CreateRenderingParams(factory
, ¶ms
);
4245 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4247 /* detect old dwrite version, that is using higher threshold value */
4248 g_is_vista
= fontface1
== NULL
;
4250 for (emsize
= 1.0; emsize
< 500.0; emsize
+= 1.0) {
4251 WORD gasp
= get_gasp_flags(fontface
, emsize
);
4252 DWRITE_RENDERING_MODE expected
;
4255 for (i
= 0; i
< sizeof(recmode_tests
)/sizeof(recmode_tests
[0]); i
++) {
4257 expected
= get_expected_rendering_mode(emsize
, gasp
, recmode_tests
[i
].measuring
, recmode_tests
[i
].threshold
);
4258 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, emsize
, 1.0, recmode_tests
[i
].measuring
, params
, &mode
);
4259 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4260 ok(mode
== expected
, "%.2f/%d: got %d, flags 0x%04x, expected %d\n", emsize
, i
, mode
, gasp
, expected
);
4263 /* IDWriteFontFace1 offers another variant of this method */
4265 for (i
= 0; i
< sizeof(recmode_tests1
)/sizeof(recmode_tests1
[0]); i
++) {
4267 expected
= get_expected_rendering_mode(emsize
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
4268 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, 96.0, 96.0,
4269 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
4270 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4271 ok(mode
== expected
, "%.2f/%d: got %d, flags 0x%04x, expected %d\n", emsize
, i
, mode
, gasp
, expected
);
4275 /* IDWriteFontFace2 - another one */
4277 DWRITE_GRID_FIT_MODE gridfit
, expected_gridfit
;
4279 for (i
= 0; i
< sizeof(recmode_tests1
)/sizeof(recmode_tests1
[0]); i
++) {
4281 expected
= get_expected_rendering_mode(emsize
, gasp
, recmode_tests1
[0].measuring
, recmode_tests1
[0].threshold
);
4282 expected_gridfit
= get_expected_gridfit_mode(emsize
, gasp
, recmode_tests1
[0].measuring
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
);
4283 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, emsize
, 96.0, 96.0,
4284 NULL
, FALSE
, recmode_tests1
[0].threshold
, recmode_tests1
[0].measuring
, params
, &mode
, &gridfit
);
4285 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4286 ok(mode
== expected
, "%.2f: got %d, flags 0x%04x, expected %d\n", emsize
, mode
, gasp
, expected
);
4287 ok(gridfit
== expected_gridfit
, "%.2f/%d: gridfit: got %d, flags 0x%04x, expected %d\n", emsize
, i
, gridfit
,
4288 gasp
, expected_gridfit
);
4293 IDWriteRenderingParams_Release(params
);
4295 /* test how parameters override returned modes */
4296 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 1.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT
,
4297 DWRITE_RENDERING_MODE_GDI_CLASSIC
, ¶ms
);
4298 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4301 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 500.0, 1.0, DWRITE_MEASURING_MODE_NATURAL
, params
, &mode
);
4302 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4303 ok(mode
== DWRITE_RENDERING_MODE_GDI_CLASSIC
, "got %d\n", mode
);
4305 IDWriteRenderingParams_Release(params
);
4308 IDWriteRenderingParams2
*params2
;
4309 IDWriteFactory2
*factory2
;
4310 DWRITE_GRID_FIT_MODE gridfit
;
4312 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory2
, (void**)&factory2
);
4313 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4315 hr
= IDWriteFactory2_CreateCustomRenderingParams(factory2
, 1.0, 0.0, 0.0, 0.5, DWRITE_PIXEL_GEOMETRY_FLAT
,
4316 DWRITE_RENDERING_MODE_OUTLINE
, DWRITE_GRID_FIT_MODE_ENABLED
, ¶ms2
);
4317 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4321 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, 5.0, 96.0, 96.0,
4322 NULL
, FALSE
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
4323 NULL
, &mode
, &gridfit
);
4324 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4325 ok(mode
== DWRITE_RENDERING_MODE_GDI_CLASSIC
, "got %d\n", mode
);
4326 ok(gridfit
== DWRITE_GRID_FIT_MODE_ENABLED
, "got %d\n", gridfit
);
4330 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, 5.0, 96.0, 96.0,
4331 NULL
, FALSE
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
4332 (IDWriteRenderingParams
*)params2
, &mode
, &gridfit
);
4333 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4334 ok(mode
== DWRITE_RENDERING_MODE_OUTLINE
, "got %d\n", mode
);
4335 ok(gridfit
== DWRITE_GRID_FIT_MODE_ENABLED
, "got %d\n", gridfit
);
4337 IDWriteRenderingParams2_Release(params2
);
4338 IDWriteFactory2_Release(factory2
);
4342 IDWriteFontFace2_Release(fontface2
);
4344 IDWriteFontFace1_Release(fontface1
);
4345 IDWriteFontFace_Release(fontface
);
4346 IDWriteFactory_Release(factory
);
4351 IDWriteFactory
*factory
;
4353 if (!(factory
= create_factory())) {
4354 win_skip("failed to create factory\n");
4358 test_CreateFontFromLOGFONT();
4359 test_CreateBitmapRenderTarget();
4360 test_GetFontFamily();
4361 test_GetFamilyNames();
4362 test_CreateFontFace();
4364 test_system_fontcollection();
4365 test_ConvertFontFaceToLOGFONT();
4366 test_CustomFontCollection();
4367 test_CreateCustomFontFileReference();
4368 test_CreateFontFileReference();
4369 test_shared_isolated();
4370 test_GetUnicodeRanges();
4371 test_GetFontFromFontFace();
4372 test_GetFirstMatchingFont();
4373 test_GetInformationalStrings();
4374 test_GetGdiInterop();
4375 test_CreateFontFaceFromHdc();
4376 test_GetSimulations();
4377 test_GetFaceNames();
4378 test_TryGetFontTable();
4379 test_ConvertFontToLOGFONT();
4380 test_CreateStreamFromKey();
4381 test_ReadFileFragment();
4382 test_GetDesignGlyphMetrics();
4383 test_GetDesignGlyphAdvances();
4384 test_IsMonospacedFont();
4385 test_GetGlyphRunOutline();
4386 test_GetEudcFontCollection();
4387 test_GetCaretMetrics();
4388 test_GetGlyphCount();
4389 test_GetKerningPairAdjustments();
4390 test_CreateRenderingParams();
4391 test_CreateGlyphRunAnalysis();
4392 test_GetGdiCompatibleMetrics();
4394 test_GetGdiCompatibleGlyphAdvances();
4395 test_GetRecommendedRenderingMode();
4397 IDWriteFactory_Release(factory
);