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
27 #include "wine/test.h"
29 #define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
30 ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
31 ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
33 #define MS_CMAP_TAG MS_MAKE_TAG('c','m','a','p')
35 #define EXPECT_HR(hr,hr_exp) \
36 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
38 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
39 static void _expect_ref(IUnknown
* obj
, ULONG ref
, int line
)
43 rc
= IUnknown_Release(obj
);
44 ok_(__FILE__
,line
)(rc
== ref
, "expected refcount %d, got %d\n", ref
, rc
);
47 static inline void *heap_alloc(size_t len
)
49 return HeapAlloc(GetProcessHeap(), 0, len
);
52 static inline BOOL
heap_free(void *mem
)
54 return HeapFree(GetProcessHeap(), 0, mem
);
57 static const WCHAR test_fontfile
[] = {'w','i','n','e','_','t','e','s','t','_','f','o','n','t','.','t','t','f',0};
58 static const WCHAR tahomaW
[] = {'T','a','h','o','m','a',0};
59 static const WCHAR blahW
[] = {'B','l','a','h','!',0};
61 static IDWriteFactory
*create_factory(void)
63 IDWriteFactory
*factory
;
64 HRESULT hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory
);
65 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
69 struct test_fontenumerator
71 IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface
;
75 IDWriteFontFile
*font_file
;
78 static inline struct test_fontenumerator
*impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator
* iface
)
80 return CONTAINING_RECORD(iface
, struct test_fontenumerator
, IDWriteFontFileEnumerator_iface
);
83 static HRESULT WINAPI
singlefontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
85 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
))
88 IDWriteFontFileEnumerator_AddRef(iface
);
94 static ULONG WINAPI
singlefontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
96 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
97 return InterlockedIncrement(&This
->ref
);
100 static ULONG WINAPI
singlefontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
102 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
103 ULONG ref
= InterlockedDecrement(&This
->ref
);
105 IDWriteFontFile_Release(This
->font_file
);
111 static HRESULT WINAPI
singlefontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**font_file
)
113 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
114 IDWriteFontFile_AddRef(This
->font_file
);
115 *font_file
= This
->font_file
;
119 static HRESULT WINAPI
singlefontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
121 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
123 if (This
->index
> 1) {
133 static const struct IDWriteFontFileEnumeratorVtbl singlefontfileenumeratorvtbl
=
135 singlefontfileenumerator_QueryInterface
,
136 singlefontfileenumerator_AddRef
,
137 singlefontfileenumerator_Release
,
138 singlefontfileenumerator_MoveNext
,
139 singlefontfileenumerator_GetCurrentFontFile
142 static HRESULT
create_enumerator(IDWriteFontFile
*font_file
, IDWriteFontFileEnumerator
**ret
)
144 struct test_fontenumerator
*enumerator
;
146 enumerator
= heap_alloc(sizeof(struct test_fontenumerator
));
148 return E_OUTOFMEMORY
;
150 enumerator
->IDWriteFontFileEnumerator_iface
.lpVtbl
= &singlefontfileenumeratorvtbl
;
152 enumerator
->index
= 0;
153 enumerator
->font_file
= font_file
;
154 IDWriteFontFile_AddRef(font_file
);
156 *ret
= &enumerator
->IDWriteFontFileEnumerator_iface
;
160 struct test_fontcollectionloader
162 IDWriteFontCollectionLoader IDWriteFontFileCollectionLoader_iface
;
163 IDWriteFontFileLoader
*loader
;
166 static inline struct test_fontcollectionloader
*impl_from_IDWriteFontFileCollectionLoader(IDWriteFontCollectionLoader
* iface
)
168 return CONTAINING_RECORD(iface
, struct test_fontcollectionloader
, IDWriteFontFileCollectionLoader_iface
);
171 static HRESULT WINAPI
resourcecollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
173 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontCollectionLoader
))
176 IDWriteFontCollectionLoader_AddRef(iface
);
179 return E_NOINTERFACE
;
182 static ULONG WINAPI
resourcecollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
187 static ULONG WINAPI
resourcecollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
192 static HRESULT WINAPI
resourcecollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
*factory
,
193 const void * collectionKey
, UINT32 collectionKeySize
, IDWriteFontFileEnumerator
** fontFileEnumerator
)
195 struct test_fontcollectionloader
*This
= impl_from_IDWriteFontFileCollectionLoader(iface
);
196 IDWriteFontFile
*font_file
;
199 IDWriteFactory_CreateCustomFontFileReference(factory
, collectionKey
, collectionKeySize
, This
->loader
, &font_file
);
201 hr
= create_enumerator(font_file
, fontFileEnumerator
);
202 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
204 IDWriteFontFile_Release(font_file
);
208 static const struct IDWriteFontCollectionLoaderVtbl resourcecollectionloadervtbl
= {
209 resourcecollectionloader_QueryInterface
,
210 resourcecollectionloader_AddRef
,
211 resourcecollectionloader_Release
,
212 resourcecollectionloader_CreateEnumeratorFromKey
215 /* Here is a functional custom font set of interfaces */
216 struct test_fontdatastream
218 IDWriteFontFileStream IDWriteFontFileStream_iface
;
225 static inline struct test_fontdatastream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
* iface
)
227 return CONTAINING_RECORD(iface
, struct test_fontdatastream
, IDWriteFontFileStream_iface
);
230 static HRESULT WINAPI
fontdatastream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
232 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
235 IDWriteFontFileStream_AddRef(iface
);
239 return E_NOINTERFACE
;
242 static ULONG WINAPI
fontdatastream_AddRef(IDWriteFontFileStream
*iface
)
244 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
245 ULONG ref
= InterlockedIncrement(&This
->ref
);
249 static ULONG WINAPI
fontdatastream_Release(IDWriteFontFileStream
*iface
)
251 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
252 ULONG ref
= InterlockedDecrement(&This
->ref
);
254 HeapFree(GetProcessHeap(), 0, This
);
258 static HRESULT WINAPI
fontdatastream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
260 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
261 *fragment_context
= NULL
;
262 if (offset
+fragment_size
> This
->size
)
264 *fragment_start
= NULL
;
269 *fragment_start
= (BYTE
*)This
->data
+ offset
;
274 static void WINAPI
fontdatastream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
279 static HRESULT WINAPI
fontdatastream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
281 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
286 static HRESULT WINAPI
fontdatastream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
291 static const IDWriteFontFileStreamVtbl fontdatastreamvtbl
=
293 fontdatastream_QueryInterface
,
294 fontdatastream_AddRef
,
295 fontdatastream_Release
,
296 fontdatastream_ReadFileFragment
,
297 fontdatastream_ReleaseFileFragment
,
298 fontdatastream_GetFileSize
,
299 fontdatastream_GetLastWriteTime
302 static HRESULT
create_fontdatastream(LPVOID data
, UINT size
, IDWriteFontFileStream
** iface
)
304 struct test_fontdatastream
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct test_fontdatastream
));
306 return E_OUTOFMEMORY
;
311 This
->IDWriteFontFileStream_iface
.lpVtbl
= &fontdatastreamvtbl
;
313 *iface
= &This
->IDWriteFontFileStream_iface
;
317 static HRESULT WINAPI
resourcefontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
319 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
325 return E_NOINTERFACE
;
328 static ULONG WINAPI
resourcefontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
333 static ULONG WINAPI
resourcefontfileloader_Release(IDWriteFontFileLoader
*iface
)
338 static HRESULT WINAPI
resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
344 mem
= LoadResource(GetModuleHandleA(NULL
), *(HRSRC
*)fontFileReferenceKey
);
345 ok(mem
!= NULL
, "Failed to lock font resource\n");
348 size
= SizeofResource(GetModuleHandleA(NULL
), *(HRSRC
*)fontFileReferenceKey
);
349 data
= LockResource(mem
);
350 return create_fontdatastream(data
, size
, fontFileStream
);
355 static const struct IDWriteFontFileLoaderVtbl resourcefontfileloadervtbl
= {
356 resourcefontfileloader_QueryInterface
,
357 resourcefontfileloader_AddRef
,
358 resourcefontfileloader_Release
,
359 resourcefontfileloader_CreateStreamFromKey
362 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
364 static void test_CreateFontFromLOGFONT(void)
366 static const WCHAR tahomaspW
[] = {'T','a','h','o','m','a',' ',0};
367 IDWriteGdiInterop
*interop
;
368 DWRITE_FONT_WEIGHT weight
;
369 DWRITE_FONT_STYLE style
;
372 LONG weights
[][2] = {
373 {FW_NORMAL
, DWRITE_FONT_WEIGHT_NORMAL
},
374 {FW_BOLD
, DWRITE_FONT_WEIGHT_BOLD
},
375 { 0, DWRITE_FONT_WEIGHT_NORMAL
},
376 { 50, DWRITE_FONT_WEIGHT_NORMAL
},
377 {150, DWRITE_FONT_WEIGHT_NORMAL
},
378 {250, DWRITE_FONT_WEIGHT_NORMAL
},
379 {350, DWRITE_FONT_WEIGHT_NORMAL
},
380 {450, DWRITE_FONT_WEIGHT_NORMAL
},
381 {650, DWRITE_FONT_WEIGHT_BOLD
},
382 {750, DWRITE_FONT_WEIGHT_BOLD
},
383 {850, DWRITE_FONT_WEIGHT_BOLD
},
384 {950, DWRITE_FONT_WEIGHT_BOLD
},
385 {960, DWRITE_FONT_WEIGHT_BOLD
},
387 OUTLINETEXTMETRICW otm
;
388 IDWriteFactory
*factory
;
397 factory
= create_factory();
399 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
403 /* null out parameter crashes this call */
404 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, NULL
);
406 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, &font
);
407 EXPECT_HR(hr
, E_INVALIDARG
);
409 memset(&logfont
, 0, sizeof(logfont
));
410 logfont
.lfHeight
= 12;
411 logfont
.lfWidth
= 12;
412 logfont
.lfWeight
= FW_NORMAL
;
413 logfont
.lfItalic
= 1;
414 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
416 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
419 hfont
= CreateFontIndirectW(&logfont
);
420 hdc
= CreateCompatibleDC(0);
421 SelectObject(hdc
, hfont
);
423 otm
.otmSize
= sizeof(otm
);
424 r
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
425 ok(r
, "got %d\n", r
);
430 hr
= IDWriteFont_HasCharacter(font
, 0xd800, &exists
);
431 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
432 ok(exists
== FALSE
, "got %d\n", exists
);
435 hr
= IDWriteFont_HasCharacter(font
, 0x20, &exists
);
436 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
437 ok(exists
== TRUE
, "got %d\n", exists
);
439 /* now check properties */
440 weight
= IDWriteFont_GetWeight(font
);
441 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
, "got %d\n", weight
);
443 style
= IDWriteFont_GetStyle(font
);
445 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %d\n", style
);
446 ok(otm
.otmfsSelection
== 1, "got 0x%08x\n", otm
.otmfsSelection
);
448 ret
= IDWriteFont_IsSymbolFont(font
);
449 ok(!ret
, "got %d\n", ret
);
451 IDWriteFont_Release(font
);
454 for (i
= 0; i
< sizeof(weights
)/(2*sizeof(LONG
)); i
++)
456 memset(&logfont
, 0, sizeof(logfont
));
457 logfont
.lfHeight
= 12;
458 logfont
.lfWidth
= 12;
459 logfont
.lfWeight
= weights
[i
][0];
460 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
462 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
465 weight
= IDWriteFont_GetWeight(font
);
466 ok(weight
== weights
[i
][1],
467 "%d: got %d, expected %d\n", i
, weight
, weights
[i
][1]);
469 IDWriteFont_Release(font
);
472 /* weight not from enum */
473 memset(&logfont
, 0, sizeof(logfont
));
474 logfont
.lfHeight
= 12;
475 logfont
.lfWidth
= 12;
476 logfont
.lfWeight
= 550;
477 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
480 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
481 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
483 weight
= IDWriteFont_GetWeight(font
);
484 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
|| broken(weight
== DWRITE_FONT_WEIGHT_BOLD
) /* win7 w/o SP */,
486 IDWriteFont_Release(font
);
488 /* empty or nonexistent face name */
489 memset(&logfont
, 0, sizeof(logfont
));
490 logfont
.lfHeight
= 12;
491 logfont
.lfWidth
= 12;
492 logfont
.lfWeight
= FW_NORMAL
;
493 lstrcpyW(logfont
.lfFaceName
, blahW
);
495 font
= (void*)0xdeadbeef;
496 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
497 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
498 ok(font
== NULL
, "got %p\n", font
);
500 /* Try with name 'Tahoma ' */
501 memset(&logfont
, 0, sizeof(logfont
));
502 logfont
.lfHeight
= 12;
503 logfont
.lfWidth
= 12;
504 logfont
.lfWeight
= FW_NORMAL
;
505 lstrcpyW(logfont
.lfFaceName
, tahomaspW
);
507 font
= (void*)0xdeadbeef;
508 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
509 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
510 ok(font
== NULL
, "got %p\n", font
);
512 /* empty string as a facename */
513 memset(&logfont
, 0, sizeof(logfont
));
514 logfont
.lfHeight
= 12;
515 logfont
.lfWidth
= 12;
516 logfont
.lfWeight
= FW_NORMAL
;
518 font
= (void*)0xdeadbeef;
519 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
520 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
521 ok(font
== NULL
, "got %p\n", font
);
523 IDWriteGdiInterop_Release(interop
);
524 IDWriteFactory_Release(factory
);
527 static void test_CreateBitmapRenderTarget(void)
529 IDWriteBitmapRenderTarget
*target
, *target2
;
530 IDWriteBitmapRenderTarget1
*target1
;
531 IDWriteGdiInterop
*interop
;
532 IDWriteFactory
*factory
;
542 factory
= create_factory();
544 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
548 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target
);
551 if (0) /* crashes on native */
552 hr
= IDWriteBitmapRenderTarget_GetSize(target
, NULL
);
554 size
.cx
= size
.cy
= -1;
555 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
557 ok(size
.cx
== 0, "got %d\n", size
.cx
);
558 ok(size
.cy
== 0, "got %d\n", size
.cy
);
561 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target2
);
563 ok(target
!= target2
, "got %p, %p\n", target2
, target
);
564 IDWriteBitmapRenderTarget_Release(target2
);
566 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
567 ok(hdc
!= NULL
, "got %p\n", hdc
);
569 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
570 ok(hbm
!= NULL
, "got %p\n", hbm
);
572 /* check DIB properties */
573 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
574 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
575 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
576 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
577 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
578 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
579 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
581 IDWriteBitmapRenderTarget_Release(target
);
583 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
584 ok(!hbm
, "got %p\n", hbm
);
587 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 10, 5, &target
);
590 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
591 ok(hdc
!= NULL
, "got %p\n", hdc
);
593 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
594 ok(hbm
!= NULL
, "got %p\n", hbm
);
596 /* check DIB properties */
597 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
598 ok(ret
== sizeof(ds
), "got %d\n", ret
);
599 ok(ds
.dsBm
.bmWidth
== 10, "got %d\n", ds
.dsBm
.bmWidth
);
600 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
601 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
602 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
603 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
605 size
.cx
= size
.cy
= -1;
606 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
608 ok(size
.cx
== 10, "got %d\n", size
.cx
);
609 ok(size
.cy
== 5, "got %d\n", size
.cy
);
611 /* resize to same size */
612 hr
= IDWriteBitmapRenderTarget_Resize(target
, 10, 5);
613 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
615 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
616 ok(hbm2
== hbm
, "got %p, %p\n", hbm2
, hbm
);
619 hr
= IDWriteBitmapRenderTarget_Resize(target
, 5, 5);
620 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
622 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
623 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
625 hr
= IDWriteBitmapRenderTarget_Resize(target
, 20, 5);
626 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
628 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
629 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
631 hr
= IDWriteBitmapRenderTarget_Resize(target
, 1, 5);
632 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
634 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
635 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
637 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
638 ok(ret
== sizeof(ds
), "got %d\n", ret
);
639 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
640 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
641 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
642 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
643 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
645 /* empty rectangle */
646 hr
= IDWriteBitmapRenderTarget_Resize(target
, 0, 5);
647 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
649 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
650 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
652 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
653 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
654 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
655 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
656 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
657 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
658 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
660 /* transform tests */
661 if (0) /* crashes on native */
662 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, NULL
);
664 memset(&m
, 0xcc, sizeof(m
));
665 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
666 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
667 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
);
668 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
670 memset(&m
, 0, sizeof(m
));
671 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, &m
);
672 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
674 memset(&m
, 0xcc, sizeof(m
));
675 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
676 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
677 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
);
678 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
680 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, NULL
);
681 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
683 memset(&m
, 0xcc, sizeof(m
));
684 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
685 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
686 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
);
687 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
690 pdip
= IDWriteBitmapRenderTarget_GetPixelsPerDip(target
);
691 ok(pdip
== 1.0, "got %.2f\n", pdip
);
693 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, 2.0);
694 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
696 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, -1.0);
697 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
699 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, 0.0);
700 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
702 pdip
= IDWriteBitmapRenderTarget_GetPixelsPerDip(target
);
703 ok(pdip
== 2.0, "got %.2f\n", pdip
);
705 hr
= IDWriteBitmapRenderTarget_QueryInterface(target
, &IID_IDWriteBitmapRenderTarget1
, (void**)&target1
);
707 DWRITE_TEXT_ANTIALIAS_MODE mode
;
709 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
710 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, "got %d\n", mode
);
712 hr
= IDWriteBitmapRenderTarget1_SetTextAntialiasMode(target1
, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
+1);
713 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
715 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
716 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, "got %d\n", mode
);
718 hr
= IDWriteBitmapRenderTarget1_SetTextAntialiasMode(target1
, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
);
719 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
721 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
722 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
, "got %d\n", mode
);
724 IDWriteBitmapRenderTarget1_Release(target1
);
727 win_skip("IDWriteBitmapRenderTarget1 is not supported.\n");
729 IDWriteBitmapRenderTarget_Release(target
);
730 IDWriteGdiInterop_Release(interop
);
731 IDWriteFactory_Release(factory
);
734 static void test_GetFontFamily(void)
736 IDWriteFontCollection
*collection
, *collection2
;
737 IDWriteFontCollection
*syscoll
;
738 IDWriteFontFamily
*family
, *family2
;
739 IDWriteGdiInterop
*interop
;
740 IDWriteFont
*font
, *font2
;
741 IDWriteFactory
*factory
;
745 factory
= create_factory();
747 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
750 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &syscoll
, FALSE
);
751 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
753 memset(&logfont
, 0, sizeof(logfont
));
754 logfont
.lfHeight
= 12;
755 logfont
.lfWidth
= 12;
756 logfont
.lfWeight
= FW_NORMAL
;
757 logfont
.lfItalic
= 1;
758 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
760 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
761 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
763 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
764 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
765 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
767 if (0) /* crashes on native */
768 hr
= IDWriteFont_GetFontFamily(font
, NULL
);
771 hr
= IDWriteFont_GetFontFamily(font
, &family
);
774 EXPECT_REF(family
, 2);
776 hr
= IDWriteFont_GetFontFamily(font
, &family2
);
778 ok(family2
== family
, "got %p, previous %p\n", family2
, family
);
780 EXPECT_REF(family
, 3);
781 IDWriteFontFamily_Release(family2
);
783 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFamily
, (void**)&family2
);
784 EXPECT_HR(hr
, E_NOINTERFACE
);
785 ok(family2
== NULL
, "got %p\n", family2
);
787 hr
= IDWriteFont_GetFontFamily(font2
, &family2
);
788 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
789 ok(family2
!= family
, "got %p, %p\n", family2
, family
);
792 hr
= IDWriteFontFamily_GetFontCollection(family
, &collection
);
793 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
796 hr
= IDWriteFontFamily_GetFontCollection(family2
, &collection2
);
797 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
798 ok(collection
== collection2
, "got %p, %p\n", collection
, collection2
);
799 ok(collection
== syscoll
, "got %p, %p\n", collection
, syscoll
);
801 IDWriteFontCollection_Release(syscoll
);
802 IDWriteFontCollection_Release(collection2
);
803 IDWriteFontCollection_Release(collection
);
804 IDWriteFontFamily_Release(family2
);
805 IDWriteFontFamily_Release(family
);
806 IDWriteFont_Release(font
);
807 IDWriteFont_Release(font2
);
808 IDWriteGdiInterop_Release(interop
);
809 IDWriteFactory_Release(factory
);
812 static void test_GetFamilyNames(void)
814 IDWriteFontFamily
*family
;
815 IDWriteLocalizedStrings
*names
, *names2
;
816 IDWriteGdiInterop
*interop
;
817 IDWriteFactory
*factory
;
824 factory
= create_factory();
826 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
829 memset(&logfont
, 0, sizeof(logfont
));
830 logfont
.lfHeight
= 12;
831 logfont
.lfWidth
= 12;
832 logfont
.lfWeight
= FW_NORMAL
;
833 logfont
.lfItalic
= 1;
834 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
836 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
839 hr
= IDWriteFont_GetFontFamily(font
, &family
);
842 if (0) /* crashes on native */
843 hr
= IDWriteFontFamily_GetFamilyNames(family
, NULL
);
845 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
846 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
847 EXPECT_REF(names
, 1);
849 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names2
);
850 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
851 EXPECT_REF(names2
, 1);
852 ok(names
!= names2
, "got %p, was %p\n", names2
, names
);
854 IDWriteLocalizedStrings_Release(names2
);
856 /* GetStringLength */
857 if (0) /* crashes on native */
858 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, NULL
);
861 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 10, &len
);
862 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
863 ok(len
== (UINT32
)-1, "got %u\n", len
);
866 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, &len
);
867 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
868 ok(len
> 0, "got %u\n", len
);
871 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 0);
872 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
874 hr
= IDWriteLocalizedStrings_GetString(names
, 10, NULL
, 0);
875 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
878 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 100);
881 hr
= IDWriteLocalizedStrings_GetString(names
, 10, buffer
, 100);
882 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
883 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
886 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
-1);
887 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
888 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
891 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
);
892 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
893 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
896 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
+1);
897 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
898 ok(buffer
[0] != 0, "got %x\n", buffer
[0]);
900 IDWriteLocalizedStrings_Release(names
);
902 IDWriteFontFamily_Release(family
);
903 IDWriteFont_Release(font
);
904 IDWriteGdiInterop_Release(interop
);
905 IDWriteFactory_Release(factory
);
908 static void test_CreateFontFace(void)
910 IDWriteFontFace
*fontface
, *fontface2
;
911 IDWriteFontCollection
*collection
;
912 IDWriteGdiInterop
*interop
;
913 IDWriteFont
*font
, *font2
;
914 IDWriteFontFamily
*family
;
915 IDWriteFactory
*factory
;
919 factory
= create_factory();
921 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
924 memset(&logfont
, 0, sizeof(logfont
));
925 logfont
.lfHeight
= 12;
926 logfont
.lfWidth
= 12;
927 logfont
.lfWeight
= FW_NORMAL
;
928 logfont
.lfItalic
= 1;
929 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
932 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
933 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
936 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
937 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
938 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
940 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFace
, (void**)&fontface
);
941 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
943 if (0) /* crashes on native */
944 hr
= IDWriteFont_CreateFontFace(font
, NULL
);
947 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
948 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
951 hr
= IDWriteFont_CreateFontFace(font
, &fontface2
);
952 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
953 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
954 IDWriteFontFace_Release(fontface2
);
957 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
958 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
959 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
960 IDWriteFontFace_Release(fontface2
);
962 IDWriteFont_Release(font2
);
963 IDWriteFont_Release(font
);
965 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFont
, (void**)&font
);
966 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_NOTIMPL
), "got 0x%08x\n", hr
);
968 IDWriteFontFace_Release(fontface
);
969 IDWriteGdiInterop_Release(interop
);
971 /* Create from system collection */
972 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
973 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
975 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
976 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
979 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
980 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
981 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
984 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
985 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font2
);
986 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
987 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
990 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
991 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
994 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
995 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
996 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
998 IDWriteFontFace_Release(fontface
);
999 IDWriteFontFace_Release(fontface2
);
1000 IDWriteFont_Release(font2
);
1001 IDWriteFont_Release(font
);
1002 IDWriteFontFamily_Release(family
);
1003 IDWriteFontCollection_Release(collection
);
1004 IDWriteFactory_Release(factory
);
1007 static void test_GetMetrics(void)
1009 IDWriteGdiInterop
*interop
;
1010 DWRITE_FONT_METRICS metrics
;
1011 IDWriteFontFace
*fontface
;
1012 IDWriteFactory
*factory
;
1013 OUTLINETEXTMETRICW otm
;
1014 IDWriteFont1
*font1
;
1022 factory
= create_factory();
1024 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1025 EXPECT_HR(hr
, S_OK
);
1027 memset(&logfont
, 0, sizeof(logfont
));
1028 logfont
.lfHeight
= 12;
1029 logfont
.lfWidth
= 12;
1030 logfont
.lfWeight
= FW_NORMAL
;
1031 logfont
.lfItalic
= 1;
1032 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1034 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1035 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1037 hfont
= CreateFontIndirectW(&logfont
);
1038 hdc
= CreateCompatibleDC(0);
1039 SelectObject(hdc
, hfont
);
1041 otm
.otmSize
= sizeof(otm
);
1042 ret
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
1043 ok(ret
, "got %d\n", ret
);
1045 DeleteObject(hfont
);
1047 if (0) /* crashes on native */
1048 IDWriteFont_GetMetrics(font
, NULL
);
1050 memset(&metrics
, 0, sizeof(metrics
));
1051 IDWriteFont_GetMetrics(font
, &metrics
);
1053 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
1054 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
1055 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
1057 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
1058 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
1059 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
1060 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
1061 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
1062 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
1063 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
1065 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1066 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1068 memset(&metrics
, 0, sizeof(metrics
));
1069 IDWriteFontFace_GetMetrics(fontface
, &metrics
);
1071 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
1072 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
1073 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
1075 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
1076 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
1077 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
1078 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
1079 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
1080 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
1081 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
1083 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
1085 DWRITE_FONT_METRICS1 metrics1
;
1086 IDWriteFontFace1
*fontface1
;
1088 memset(&metrics1
, 0, sizeof(metrics1
));
1089 IDWriteFont1_GetMetrics(font1
, &metrics1
);
1091 ok(metrics1
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics1
.designUnitsPerEm
);
1092 ok(metrics1
.ascent
!= 0, "ascent %u\n", metrics1
.ascent
);
1093 ok(metrics1
.descent
!= 0, "descent %u\n", metrics1
.descent
);
1095 ok(metrics1
.lineGap
== 0, "lineGap %d\n", metrics1
.lineGap
);
1096 ok(metrics1
.capHeight
, "capHeight %u\n", metrics1
.capHeight
);
1097 ok(metrics1
.xHeight
!= 0, "xHeight %u\n", metrics1
.xHeight
);
1098 ok(metrics1
.underlinePosition
< 0, "underlinePosition %d\n", metrics1
.underlinePosition
);
1099 ok(metrics1
.underlineThickness
!= 0, "underlineThickness %u\n", metrics1
.underlineThickness
);
1100 ok(metrics1
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics1
.strikethroughPosition
);
1101 ok(metrics1
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics1
.strikethroughThickness
);
1102 ok(metrics1
.glyphBoxLeft
< 0, "glyphBoxLeft %d\n", metrics1
.glyphBoxLeft
);
1103 ok(metrics1
.glyphBoxTop
> 0, "glyphBoxTop %d\n", metrics1
.glyphBoxTop
);
1104 ok(metrics1
.glyphBoxRight
> 0, "glyphBoxRight %d\n", metrics1
.glyphBoxRight
);
1105 ok(metrics1
.glyphBoxBottom
< 0, "glyphBoxBottom %d\n", metrics1
.glyphBoxBottom
);
1106 ok(metrics1
.subscriptPositionY
< 0, "subscriptPositionY %d\n", metrics1
.subscriptPositionY
);
1107 ok(metrics1
.subscriptSizeX
> 0, "subscriptSizeX %d\n", metrics1
.subscriptSizeX
);
1108 ok(metrics1
.subscriptSizeY
> 0, "subscriptSizeY %d\n", metrics1
.subscriptSizeY
);
1109 ok(metrics1
.superscriptPositionY
> 0, "superscriptPositionY %d\n", metrics1
.superscriptPositionY
);
1110 ok(metrics1
.superscriptSizeX
> 0, "superscriptSizeX %d\n", metrics1
.superscriptSizeX
);
1111 ok(metrics1
.superscriptSizeY
> 0, "superscriptSizeY %d\n", metrics1
.superscriptSizeY
);
1112 ok(!metrics1
.hasTypographicMetrics
, "hasTypographicMetrics %d\n", metrics1
.hasTypographicMetrics
);
1114 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
1115 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1117 memset(&metrics1
, 0, sizeof(metrics1
));
1118 IDWriteFontFace1_GetMetrics(fontface1
, &metrics1
);
1120 ok(metrics1
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics1
.designUnitsPerEm
);
1121 ok(metrics1
.ascent
!= 0, "ascent %u\n", metrics1
.ascent
);
1122 ok(metrics1
.descent
!= 0, "descent %u\n", metrics1
.descent
);
1124 ok(metrics1
.lineGap
== 0, "lineGap %d\n", metrics1
.lineGap
);
1125 ok(metrics1
.capHeight
, "capHeight %u\n", metrics1
.capHeight
);
1126 ok(metrics1
.xHeight
!= 0, "xHeight %u\n", metrics1
.xHeight
);
1127 ok(metrics1
.underlinePosition
< 0, "underlinePosition %d\n", metrics1
.underlinePosition
);
1128 ok(metrics1
.underlineThickness
!= 0, "underlineThickness %u\n", metrics1
.underlineThickness
);
1129 ok(metrics1
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics1
.strikethroughPosition
);
1130 ok(metrics1
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics1
.strikethroughThickness
);
1131 ok(metrics1
.glyphBoxLeft
< 0, "glyphBoxLeft %d\n", metrics1
.glyphBoxLeft
);
1132 ok(metrics1
.glyphBoxTop
> 0, "glyphBoxTop %d\n", metrics1
.glyphBoxTop
);
1133 ok(metrics1
.glyphBoxRight
> 0, "glyphBoxRight %d\n", metrics1
.glyphBoxRight
);
1134 ok(metrics1
.glyphBoxBottom
< 0, "glyphBoxBottom %d\n", metrics1
.glyphBoxBottom
);
1135 ok(metrics1
.subscriptPositionY
< 0, "subscriptPositionY %d\n", metrics1
.subscriptPositionY
);
1136 ok(metrics1
.subscriptSizeX
> 0, "subscriptSizeX %d\n", metrics1
.subscriptSizeX
);
1137 ok(metrics1
.subscriptSizeY
> 0, "subscriptSizeY %d\n", metrics1
.subscriptSizeY
);
1138 ok(metrics1
.superscriptPositionY
> 0, "superscriptPositionY %d\n", metrics1
.superscriptPositionY
);
1139 ok(metrics1
.superscriptSizeX
> 0, "superscriptSizeX %d\n", metrics1
.superscriptSizeX
);
1140 ok(metrics1
.superscriptSizeY
> 0, "superscriptSizeY %d\n", metrics1
.superscriptSizeY
);
1141 ok(!metrics1
.hasTypographicMetrics
, "hasTypographicMetrics %d\n", metrics1
.hasTypographicMetrics
);
1143 IDWriteFontFace1_Release(fontface1
);
1144 IDWriteFont1_Release(font1
);
1147 win_skip("DWRITE_FONT_METRICS1 is not supported.\n");
1149 IDWriteFontFace_Release(fontface
);
1151 IDWriteFont_Release(font
);
1152 IDWriteGdiInterop_Release(interop
);
1153 IDWriteFactory_Release(factory
);
1156 static void test_system_fontcollection(void)
1158 IDWriteFontCollection
*collection
, *coll2
;
1159 IDWriteLocalFontFileLoader
*localloader
;
1160 IDWriteFactory
*factory
, *factory2
;
1161 IDWriteFontFileLoader
*loader
;
1162 IDWriteFontFamily
*family
;
1163 IDWriteFontFace
*fontface
;
1164 IDWriteFontFile
*file
;
1170 factory
= create_factory();
1172 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1173 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1175 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, FALSE
);
1176 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1177 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
1178 IDWriteFontCollection_Release(coll2
);
1180 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, TRUE
);
1181 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1182 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
1183 IDWriteFontCollection_Release(coll2
);
1185 factory2
= create_factory();
1186 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &coll2
, FALSE
);
1187 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1188 ok(coll2
!= collection
, "got %p, was %p\n", coll2
, collection
);
1189 IDWriteFontCollection_Release(coll2
);
1190 IDWriteFactory_Release(factory2
);
1192 i
= IDWriteFontCollection_GetFontFamilyCount(collection
);
1193 ok(i
, "got %u\n", i
);
1196 family
= (void*)0xdeadbeef;
1197 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
1198 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1199 ok(family
== NULL
, "got %p\n", family
);
1203 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaW
, &i
, &ret
);
1204 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1205 ok(ret
, "got %d\n", ret
);
1206 ok(i
!= (UINT32
)-1, "got %u\n", i
);
1208 /* get back local file loader */
1209 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
1210 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1212 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1213 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1214 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1215 IDWriteFontFamily_Release(family
);
1217 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1218 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1219 IDWriteFont_Release(font
);
1223 hr
= IDWriteFontFace_GetFiles(fontface
, &i
, &file
);
1224 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1225 ok(file
!= NULL
, "got %p\n", file
);
1227 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
1228 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1229 IDWriteFontFile_Release(file
);
1231 hr
= IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
1232 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1233 IDWriteLocalFontFileLoader_Release(localloader
);
1235 /* local loader is not registered by default */
1236 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, loader
);
1237 ok(hr
== S_OK
|| broken(hr
== DWRITE_E_ALREADYREGISTERED
), "got 0x%08x\n", hr
);
1238 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, loader
);
1239 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "got 0x%08x\n", hr
);
1241 /* try with a different factory */
1242 factory2
= create_factory();
1243 hr
= IDWriteFactory_RegisterFontFileLoader(factory2
, loader
);
1244 ok(hr
== S_OK
|| broken(hr
== DWRITE_E_ALREADYREGISTERED
), "got 0x%08x\n", hr
);
1245 hr
= IDWriteFactory_RegisterFontFileLoader(factory2
, loader
);
1246 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1247 hr
= IDWriteFactory_UnregisterFontFileLoader(factory2
, loader
);
1248 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "got 0x%08x\n", hr
);
1249 hr
= IDWriteFactory_UnregisterFontFileLoader(factory2
, loader
);
1250 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1251 IDWriteFactory_Release(factory2
);
1253 IDWriteFontFileLoader_Release(loader
);
1257 hr
= IDWriteFontCollection_FindFamilyName(collection
, blahW
, &i
, &ret
);
1258 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1259 ok(!ret
, "got %d\n", ret
);
1260 ok(i
== (UINT32
)-1, "got %u\n", i
);
1262 IDWriteFontCollection_Release(collection
);
1263 IDWriteFactory_Release(factory
);
1266 static void test_ConvertFontFaceToLOGFONT(void)
1268 DWRITE_FONT_SIMULATIONS sim
;
1269 IDWriteGdiInterop
*interop
;
1270 IDWriteFontFace
*fontface
;
1271 IDWriteFactory
*factory
;
1276 factory
= create_factory();
1278 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1279 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1281 memset(&logfont
, 0, sizeof(logfont
));
1282 logfont
.lfHeight
= 12;
1283 logfont
.lfWidth
= 12;
1284 logfont
.lfEscapement
= 100;
1285 logfont
.lfWeight
= FW_NORMAL
;
1286 logfont
.lfItalic
= 1;
1287 logfont
.lfUnderline
= 1;
1288 logfont
.lfStrikeOut
= 1;
1290 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1292 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1293 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1295 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1296 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1298 sim
= IDWriteFont_GetSimulations(font
);
1299 ok(sim
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "sim %d\n", sim
);
1301 sim
= IDWriteFontFace_GetSimulations(fontface
);
1302 ok(sim
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "sim %d\n", sim
);
1304 IDWriteFont_Release(font
);
1306 if (0) /* crashes on native */
1308 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, NULL
, NULL
);
1309 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, NULL
);
1312 memset(&logfont
, 0xa, sizeof(logfont
));
1313 logfont
.lfFaceName
[0] = 0;
1315 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, &logfont
);
1316 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1317 ok(logfont
.lfHeight
== 0, "got %d\n", logfont
.lfHeight
);
1318 ok(logfont
.lfWidth
== 0, "got %d\n", logfont
.lfWidth
);
1319 ok(logfont
.lfWeight
== FW_NORMAL
, "got %d\n", logfont
.lfWeight
);
1320 ok(logfont
.lfEscapement
== 0, "got %d\n", logfont
.lfEscapement
);
1321 ok(logfont
.lfItalic
== 1, "got %d\n", logfont
.lfItalic
);
1322 ok(logfont
.lfUnderline
== 0, "got %d\n", logfont
.lfUnderline
);
1323 ok(logfont
.lfStrikeOut
== 0, "got %d\n", logfont
.lfStrikeOut
);
1325 ok(!lstrcmpW(logfont
.lfFaceName
, tahomaW
), "got %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
1327 IDWriteGdiInterop_Release(interop
);
1328 IDWriteFontFace_Release(fontface
);
1329 IDWriteFactory_Release(factory
);
1332 static HRESULT WINAPI
fontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
1334 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
))
1337 IDWriteFontFileEnumerator_AddRef(iface
);
1340 return E_NOINTERFACE
;
1343 static ULONG WINAPI
fontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
1348 static ULONG WINAPI
fontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
1353 static HRESULT WINAPI
fontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**file
)
1359 static HRESULT WINAPI
fontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
1365 static const struct IDWriteFontFileEnumeratorVtbl dwritefontfileenumeratorvtbl
=
1367 fontfileenumerator_QueryInterface
,
1368 fontfileenumerator_AddRef
,
1369 fontfileenumerator_Release
,
1370 fontfileenumerator_MoveNext
,
1371 fontfileenumerator_GetCurrentFontFile
,
1374 static HRESULT WINAPI
fontcollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
1380 static ULONG WINAPI
fontcollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
1385 static ULONG WINAPI
fontcollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
1390 static HRESULT WINAPI
fontcollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
*factory
, const void *key
,
1391 UINT32 key_size
, IDWriteFontFileEnumerator
**ret
)
1393 static IDWriteFontFileEnumerator enumerator
= { &dwritefontfileenumeratorvtbl
};
1398 static const struct IDWriteFontCollectionLoaderVtbl dwritefontcollectionloadervtbl
= {
1399 fontcollectionloader_QueryInterface
,
1400 fontcollectionloader_AddRef
,
1401 fontcollectionloader_Release
,
1402 fontcollectionloader_CreateEnumeratorFromKey
1405 static void test_CustomFontCollection(void)
1407 static const WCHAR fontnameW
[] = {'w','i','n','e','_','t','e','s','t',0};
1408 IDWriteFontCollectionLoader collection
= { &dwritefontcollectionloadervtbl
};
1409 IDWriteFontCollectionLoader collection2
= { &dwritefontcollectionloadervtbl
};
1410 IDWriteFontCollectionLoader collection3
= { &dwritefontcollectionloadervtbl
};
1411 IDWriteFontCollection
*font_collection
= NULL
;
1412 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
1413 struct test_fontcollectionloader resource_collection
= { { &resourcecollectionloadervtbl
}, &rloader
};
1414 IDWriteFontFamily
*family
, *family2
, *family3
;
1415 IDWriteFontFace
*idfontface
, *idfontface2
;
1416 IDWriteFontFile
*fontfile
, *fontfile2
;
1417 IDWriteLocalizedStrings
*string
;
1418 IDWriteFont
*idfont
, *idfont2
;
1419 IDWriteFactory
*factory
;
1420 UINT32 index
, count
;
1425 factory
= create_factory();
1427 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, NULL
);
1428 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1430 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, NULL
);
1431 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1433 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
1434 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1435 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection2
);
1436 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1437 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
1438 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1440 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1441 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1442 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
);
1443 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1445 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection3
, "Billy", 6, &font_collection
);
1446 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1448 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection
, "Billy", 6, &font_collection
);
1449 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1450 IDWriteFontCollection_Release(font_collection
);
1452 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection2
, "Billy", 6, &font_collection
);
1453 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1454 IDWriteFontCollection_Release(font_collection
);
1456 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, (IDWriteFontCollectionLoader
*)0xdeadbeef, "Billy", 6, &font_collection
);
1457 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1459 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1460 ok(font
!= NULL
, "Failed to find font resource\n");
1462 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
,
1463 &font
, sizeof(HRSRC
), &font_collection
);
1464 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1468 hr
= IDWriteFontCollection_FindFamilyName(font_collection
, fontnameW
, &index
, &exists
);
1469 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1470 ok(index
== 0, "got index %i\n", index
);
1471 ok(exists
, "got exists %i\n", exists
);
1473 count
= IDWriteFontCollection_GetFontFamilyCount(font_collection
);
1474 ok(count
== 1, "got %u\n", count
);
1477 hr
= IDWriteFontCollection_GetFontFamily(font_collection
, 0, &family
);
1478 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1479 EXPECT_REF(family
, 1);
1482 hr
= IDWriteFontCollection_GetFontFamily(font_collection
, 0, &family2
);
1483 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1484 EXPECT_REF(family2
, 1);
1485 ok(family
!= family2
, "got %p, %p\n", family
, family2
);
1487 hr
= IDWriteFontFamily_GetFont(family
, 0, &idfont
);
1488 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1489 EXPECT_REF(idfont
, 1);
1490 EXPECT_REF(family
, 2);
1491 hr
= IDWriteFontFamily_GetFont(family
, 0, &idfont2
);
1492 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1493 EXPECT_REF(idfont2
, 1);
1494 EXPECT_REF(family
, 3);
1495 ok(idfont
!= idfont2
, "got %p, %p\n", idfont
, idfont2
);
1496 IDWriteFont_Release(idfont2
);
1498 hr
= IDWriteFont_GetInformationalStrings(idfont
, DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE
, &string
, &exists
);
1499 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1500 ok(exists
, "got %d\n", exists
);
1501 EXPECT_REF(string
, 1);
1504 hr
= IDWriteFont_GetFontFamily(idfont
, &family3
);
1505 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1506 EXPECT_REF(family
, 3);
1507 ok(family
== family3
, "got %p, %p\n", family
, family3
);
1508 IDWriteFontFamily_Release(family3
);
1511 hr
= IDWriteFont_CreateFontFace(idfont
, &idfontface
);
1512 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1513 EXPECT_REF(idfont
, 1);
1516 hr
= IDWriteFontFamily_GetFont(family2
, 0, &idfont2
);
1517 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1518 EXPECT_REF(idfont2
, 1);
1519 EXPECT_REF(idfont
, 1);
1520 ok(idfont2
!= idfont
, "Font instances shoudl not match\n");
1523 hr
= IDWriteFont_CreateFontFace(idfont2
, &idfontface2
);
1524 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1525 ok(idfontface2
== idfontface
, "fontfaces should match\n");
1529 hr
= IDWriteFontFace_GetFiles(idfontface
, &index
, &fontfile
);
1530 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1534 hr
= IDWriteFontFace_GetFiles(idfontface2
, &index
, &fontfile2
);
1535 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1536 ok(fontfile
== fontfile2
, "fontfiles should match\n");
1538 IDWriteFont_Release(idfont
);
1539 IDWriteFont_Release(idfont2
);
1540 IDWriteFontFile_Release(fontfile
);
1541 IDWriteFontFile_Release(fontfile2
);
1542 IDWriteFontFace_Release(idfontface
);
1543 IDWriteFontFace_Release(idfontface2
);
1544 IDWriteFontFamily_Release(family2
);
1545 IDWriteFontFamily_Release(family
);
1546 IDWriteFontCollection_Release(font_collection
);
1548 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
1549 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1550 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
1551 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1552 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection2
);
1553 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1554 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
);
1555 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1556 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
1557 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1559 IDWriteFactory_Release(factory
);
1562 static HRESULT WINAPI
fontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
1564 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
1567 IDWriteFontFileLoader_AddRef(iface
);
1572 return E_NOINTERFACE
;
1575 static ULONG WINAPI
fontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
1580 static ULONG WINAPI
fontfileloader_Release(IDWriteFontFileLoader
*iface
)
1585 static HRESULT WINAPI
fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
1590 static const struct IDWriteFontFileLoaderVtbl dwritefontfileloadervtbl
= {
1591 fontfileloader_QueryInterface
,
1592 fontfileloader_AddRef
,
1593 fontfileloader_Release
,
1594 fontfileloader_CreateStreamFromKey
1597 static void test_CreateCustomFontFileReference(void)
1599 IDWriteFontFileLoader floader
= { &dwritefontfileloadervtbl
};
1600 IDWriteFontFileLoader floader2
= { &dwritefontfileloadervtbl
};
1601 IDWriteFontFileLoader floader3
= { &dwritefontfileloadervtbl
};
1602 IDWriteFactory
*factory
, *factory2
;
1603 IDWriteFontFile
*file
, *file2
;
1605 DWRITE_FONT_FILE_TYPE file_type
;
1606 DWRITE_FONT_FACE_TYPE face_type
;
1608 IDWriteFontFace
*face
, *face2
;
1611 UINT32 codePoints
[1] = {0xa8};
1614 factory
= create_factory();
1615 factory2
= create_factory();
1617 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, NULL
);
1618 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1619 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
1620 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1621 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader2
);
1622 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1623 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
1624 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
1625 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1626 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1629 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &file
);
1630 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1631 IDWriteFontFile_Release(file
);
1633 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader3
, &file
);
1634 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1636 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, NULL
, &file
);
1637 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1640 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &file
);
1641 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1643 file_type
= DWRITE_FONT_FILE_TYPE_TRUETYPE
;
1644 face_type
= DWRITE_FONT_FACE_TYPE_TRUETYPE
;
1647 IDWriteFontFile_Analyze(file
, &support
, &file_type
, &face_type
, &count
);
1648 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1649 ok(support
== FALSE
, "got %i\n", support
);
1650 ok(file_type
== DWRITE_FONT_FILE_TYPE_UNKNOWN
, "got %i\n", file_type
);
1651 ok(face_type
== DWRITE_FONT_FACE_TYPE_UNKNOWN
, "got %i\n", face_type
);
1652 ok(count
== 0, "got %i\n", count
);
1654 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &file
, 0, 0, &face
);
1655 ok(hr
== 0x8faecafe, "got 0x%08x\n", hr
);
1656 IDWriteFontFile_Release(file
);
1658 fontrsrc
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1659 ok(fontrsrc
!= NULL
, "Failed to find font resource\n");
1661 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &fontrsrc
, sizeof(HRSRC
), &rloader
, &file
);
1662 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1664 file_type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1665 face_type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1668 hr
= IDWriteFontFile_Analyze(file
, &support
, &file_type
, &face_type
, &count
);
1669 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1670 ok(support
== TRUE
, "got %i\n", support
);
1671 ok(file_type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", file_type
);
1672 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face_type
);
1673 ok(count
== 1, "got %i\n", count
);
1676 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 1, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
1677 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1679 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
1680 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1682 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
1683 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1684 /* fontface instances are reused starting with win7 */
1685 ok(face
== face2
|| broken(face
!= face2
), "got %p, %p\n", face
, face2
);
1686 IDWriteFontFace_Release(face2
);
1688 /* file was created with different factory */
1690 hr
= IDWriteFactory_CreateFontFace(factory2
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
1692 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1694 IDWriteFontFace_Release(face2
);
1697 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &fontrsrc
, sizeof(HRSRC
), &rloader
, &file2
);
1698 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1699 ok(file
!= file2
, "got %p, %p\n", file
, file2
);
1701 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file2
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
1702 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1703 /* fontface instances are reused starting with win7 */
1704 ok(face
== face2
|| broken(face
!= face2
), "got %p, %p\n", face
, face2
);
1705 IDWriteFontFace_Release(face2
);
1706 IDWriteFontFile_Release(file2
);
1708 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 1, indices
);
1709 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1710 ok(indices
[0] == 6, "got index %i\n", indices
[0]);
1711 IDWriteFontFace_Release(face
);
1712 IDWriteFontFile_Release(file
);
1714 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
1715 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1716 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
1717 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1718 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader2
);
1719 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1720 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
1721 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1723 IDWriteFactory_Release(factory2
);
1724 IDWriteFactory_Release(factory
);
1727 static void create_testfontfile(const WCHAR
*filename
)
1733 file
= CreateFileW(filename
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1734 ok( file
!= INVALID_HANDLE_VALUE
, "file creation failed\n" );
1736 res
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1737 ok( res
!= 0, "couldn't find resource\n" );
1738 ptr
= LockResource( LoadResource( GetModuleHandleA(NULL
), res
));
1739 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleA(NULL
), res
), &written
, NULL
);
1740 ok( written
== SizeofResource( GetModuleHandleA(NULL
), res
), "couldn't write resource\n" );
1741 CloseHandle( file
);
1744 static void test_CreateFontFileReference(void)
1747 IDWriteFontFile
*ffile
= NULL
;
1749 DWRITE_FONT_FILE_TYPE type
;
1750 DWRITE_FONT_FACE_TYPE face
;
1752 IDWriteFontFace
*fface
= NULL
;
1753 IDWriteFactory
*factory
;
1755 create_testfontfile(test_fontfile
);
1756 factory
= create_factory();
1758 hr
= IDWriteFactory_CreateFontFileReference(factory
, test_fontfile
, NULL
, &ffile
);
1759 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1762 type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1763 face
= DWRITE_FONT_FACE_TYPE_CFF
;
1765 hr
= IDWriteFontFile_Analyze(ffile
, &support
, &type
, &face
, &count
);
1766 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1767 ok(support
== TRUE
, "got %i\n", support
);
1768 ok(type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", type
);
1769 ok(face
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face
);
1770 ok(count
== 1, "got %i\n", count
);
1772 hr
= IDWriteFactory_CreateFontFace(factory
, face
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fface
);
1773 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1775 IDWriteFontFace_Release(fface
);
1776 IDWriteFontFile_Release(ffile
);
1777 IDWriteFactory_Release(factory
);
1779 DeleteFileW(test_fontfile
);
1782 static void test_shared_isolated(void)
1784 IDWriteFactory
*isolated
, *isolated2
;
1785 IDWriteFactory
*shared
, *shared2
;
1790 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
1791 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1792 ok(shared
!= NULL
, "got %p\n", shared
);
1793 IDWriteFactory_Release(shared
);
1795 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
1796 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1798 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
1799 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1800 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
1802 IDWriteFactory_Release(shared
);
1803 IDWriteFactory_Release(shared2
);
1805 /* we got 2 references, released 2 - still same pointer is returned */
1806 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
1807 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1808 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
1809 IDWriteFactory_Release(shared2
);
1811 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated
);
1812 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1814 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
1815 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1816 ok(isolated
!= isolated2
, "got %p, and %p\n", isolated
, isolated2
);
1817 IDWriteFactory_Release(isolated2
);
1819 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
1820 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1821 ok(shared
!= isolated2
, "got %p, and %p\n", shared
, isolated2
);
1823 IDWriteFactory_Release(isolated
);
1824 IDWriteFactory_Release(isolated2
);
1827 static void test_GetUnicodeRanges(void)
1829 DWRITE_UNICODE_RANGE
*ranges
, r
;
1830 IDWriteFontFile
*ffile
= NULL
;
1831 IDWriteFontFace1
*fontface1
;
1832 IDWriteFontFace
*fontface
;
1833 IDWriteFactory
*factory
;
1838 factory
= create_factory();
1840 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1841 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1843 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1844 ok(font
!= NULL
, "Failed to find font resource\n");
1846 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &font
, sizeof(HRSRC
), &rloader
, &ffile
);
1847 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1849 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1850 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1851 IDWriteFontFile_Release(ffile
);
1853 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
1854 IDWriteFontFace_Release(fontface
);
1856 win_skip("GetUnicodeRanges() is not supported.\n");
1857 IDWriteFactory_Release(factory
);
1862 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 0, NULL
, &count
);
1863 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1864 ok(count
> 0, "got %u\n", count
);
1867 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, NULL
, &count
);
1868 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1869 ok(count
== 0, "got %u\n", count
);
1872 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, &r
, &count
);
1873 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1874 ok(count
> 1, "got %u\n", count
);
1876 ranges
= heap_alloc(count
*sizeof(DWRITE_UNICODE_RANGE
));
1877 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, count
, ranges
, &count
);
1878 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1880 ranges
[0].first
= ranges
[0].last
= 0;
1881 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, ranges
, &count
);
1882 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1883 ok(ranges
[0].first
!= 0 && ranges
[0].last
!= 0, "got 0x%x-0x%0x\n", ranges
[0].first
, ranges
[0].last
);
1887 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
1888 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1890 IDWriteFontFace1_Release(fontface1
);
1891 IDWriteFactory_Release(factory
);
1894 static void test_GetFontFromFontFace(void)
1896 IDWriteFontFace
*fontface
, *fontface2
;
1897 IDWriteFontCollection
*collection
;
1898 IDWriteFont
*font
, *font2
, *font3
;
1899 IDWriteFontFamily
*family
;
1900 IDWriteFactory
*factory
;
1903 factory
= create_factory();
1905 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1906 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1908 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
1909 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1911 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1912 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1913 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1915 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1916 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1919 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font2
);
1920 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1921 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
1924 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font3
);
1925 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1926 ok(font3
!= font
&& font3
!= font2
, "got %p, %p, %p\n", font3
, font2
, font
);
1928 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
1929 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1930 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
1931 IDWriteFontFace_Release(fontface2
);
1933 hr
= IDWriteFont_CreateFontFace(font3
, &fontface2
);
1934 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1935 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
1936 IDWriteFontFace_Release(fontface2
);
1938 IDWriteFont_Release(font
);
1939 IDWriteFont_Release(font2
);
1940 IDWriteFont_Release(font3
);
1941 IDWriteFontFace_Release(fontface
);
1942 IDWriteFontFamily_Release(family
);
1943 IDWriteFontCollection_Release(collection
);
1944 IDWriteFactory_Release(factory
);
1947 static void test_GetFirstMatchingFont(void)
1949 DWRITE_FONT_SIMULATIONS simulations
;
1950 IDWriteFontCollection
*collection
;
1951 IDWriteFont
*font
, *font2
;
1952 IDWriteFontFamily
*family
;
1953 IDWriteFactory
*factory
;
1958 factory
= create_factory();
1960 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1961 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1965 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaW
, &index
, &exists
);
1966 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1967 ok(exists
, "got %d\n", exists
);
1969 hr
= IDWriteFontCollection_GetFontFamily(collection
, index
, &family
);
1970 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1972 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1973 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1974 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1976 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1977 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font2
);
1978 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1979 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1980 IDWriteFont_Release(font
);
1982 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1983 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_ITALIC
, &font
);
1984 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1986 simulations
= IDWriteFont_GetSimulations(font
);
1987 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "%d\n", simulations
);
1989 IDWriteFont_Release(font
);
1990 IDWriteFont_Release(font2
);
1991 IDWriteFontFamily_Release(family
);
1992 IDWriteFontCollection_Release(collection
);
1993 IDWriteFactory_Release(factory
);
1996 static void test_GetInformationalStrings(void)
1998 IDWriteLocalizedStrings
*strings
, *strings2
;
1999 IDWriteFontCollection
*collection
;
2000 IDWriteFontFamily
*family
;
2001 IDWriteFactory
*factory
;
2006 factory
= create_factory();
2008 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2009 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2011 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2012 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2014 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2015 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2016 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2019 strings
= (void*)0xdeadbeef;
2020 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
+1, &strings
, &exists
);
2021 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2022 ok(exists
== FALSE
, "got %d\n", exists
);
2023 ok(strings
== NULL
, "got %p\n", strings
);
2027 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_NONE
, &strings
, &exists
);
2028 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2029 ok(exists
== FALSE
, "got %d\n", exists
);
2033 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings
, &exists
);
2034 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2035 ok(exists
== TRUE
, "got %d\n", exists
);
2037 /* strings instance is not reused */
2039 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings2
, &exists
);
2040 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2041 ok(strings2
!= strings
, "got %p, %p\n", strings2
, strings
);
2043 IDWriteLocalizedStrings_Release(strings
);
2044 IDWriteLocalizedStrings_Release(strings2
);
2045 IDWriteFont_Release(font
);
2046 IDWriteFontFamily_Release(family
);
2047 IDWriteFontCollection_Release(collection
);
2048 IDWriteFactory_Release(factory
);
2051 static void test_GetGdiInterop(void)
2053 IDWriteGdiInterop
*interop
, *interop2
;
2054 IDWriteFactory
*factory
, *factory2
;
2059 factory
= create_factory();
2062 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2063 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2066 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop2
);
2067 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2068 ok(interop
== interop2
, "got %p, %p\n", interop
, interop2
);
2069 IDWriteGdiInterop_Release(interop2
);
2071 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory2
);
2072 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2074 /* each factory gets its own interop */
2076 hr
= IDWriteFactory_GetGdiInterop(factory2
, &interop2
);
2077 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2078 ok(interop
!= interop2
, "got %p, %p\n", interop
, interop2
);
2080 /* release factory - interop still works */
2081 IDWriteFactory_Release(factory2
);
2083 memset(&logfont
, 0, sizeof(logfont
));
2084 logfont
.lfHeight
= 12;
2085 logfont
.lfWidth
= 12;
2086 logfont
.lfWeight
= FW_NORMAL
;
2087 logfont
.lfItalic
= 1;
2088 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2090 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop2
, &logfont
, &font
);
2091 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2093 IDWriteGdiInterop_Release(interop2
);
2094 IDWriteGdiInterop_Release(interop
);
2095 IDWriteFactory_Release(factory
);
2098 static void test_CreateFontFaceFromHdc(void)
2100 IDWriteGdiInterop
*interop
;
2101 IDWriteFontFace
*fontface
;
2102 IDWriteFactory
*factory
;
2103 HFONT hfont
, oldhfont
;
2108 factory
= create_factory();
2111 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2112 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2114 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, NULL
, &fontface
);
2115 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2117 memset(&logfont
, 0, sizeof(logfont
));
2118 logfont
.lfHeight
= 12;
2119 logfont
.lfWidth
= 12;
2120 logfont
.lfWeight
= FW_NORMAL
;
2121 logfont
.lfItalic
= 1;
2122 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2124 hfont
= CreateFontIndirectW(&logfont
);
2125 hdc
= CreateCompatibleDC(0);
2126 oldhfont
= SelectObject(hdc
, hfont
);
2129 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, hdc
, &fontface
);
2130 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2131 IDWriteFontFace_Release(fontface
);
2132 DeleteObject(SelectObject(hdc
, oldhfont
));
2135 IDWriteGdiInterop_Release(interop
);
2136 IDWriteFactory_Release(factory
);
2139 static void test_GetSimulations(void)
2141 DWRITE_FONT_SIMULATIONS simulations
;
2142 IDWriteGdiInterop
*interop
;
2143 IDWriteFontFace
*fontface
;
2144 IDWriteFactory
*factory
;
2149 factory
= create_factory();
2151 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2152 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2154 memset(&logfont
, 0, sizeof(logfont
));
2155 logfont
.lfHeight
= 12;
2156 logfont
.lfWidth
= 12;
2157 logfont
.lfWeight
= FW_NORMAL
;
2158 logfont
.lfItalic
= 1;
2159 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2161 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2162 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2164 simulations
= IDWriteFont_GetSimulations(font
);
2165 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "got %d\n", simulations
);
2166 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2167 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2168 simulations
= IDWriteFontFace_GetSimulations(fontface
);
2169 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "got %d\n", simulations
);
2170 IDWriteFontFace_Release(fontface
);
2171 IDWriteFont_Release(font
);
2173 memset(&logfont
, 0, sizeof(logfont
));
2174 logfont
.lfHeight
= 12;
2175 logfont
.lfWidth
= 12;
2176 logfont
.lfWeight
= FW_NORMAL
;
2177 logfont
.lfItalic
= 0;
2178 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2180 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2181 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2183 simulations
= IDWriteFont_GetSimulations(font
);
2184 ok(simulations
== DWRITE_FONT_SIMULATIONS_NONE
, "got %d\n", simulations
);
2185 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2186 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2187 simulations
= IDWriteFontFace_GetSimulations(fontface
);
2188 ok(simulations
== DWRITE_FONT_SIMULATIONS_NONE
, "got %d\n", simulations
);
2189 IDWriteFontFace_Release(fontface
);
2190 IDWriteFont_Release(font
);
2192 IDWriteGdiInterop_Release(interop
);
2193 IDWriteFactory_Release(factory
);
2196 static void test_GetFaceNames(void)
2198 static const WCHAR obliqueW
[] = {'O','b','l','i','q','u','e',0};
2199 static const WCHAR enus2W
[] = {'e','n','-','U','s',0};
2200 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
2201 IDWriteLocalizedStrings
*strings
, *strings2
;
2202 IDWriteGdiInterop
*interop
;
2203 IDWriteFactory
*factory
;
2204 UINT32 count
, index
;
2211 factory
= create_factory();
2213 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2214 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2216 memset(&logfont
, 0, sizeof(logfont
));
2217 logfont
.lfHeight
= 12;
2218 logfont
.lfWidth
= 12;
2219 logfont
.lfWeight
= FW_NORMAL
;
2220 logfont
.lfItalic
= 1;
2221 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
2223 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
2224 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2226 hr
= IDWriteFont_GetFaceNames(font
, &strings
);
2227 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2229 hr
= IDWriteFont_GetFaceNames(font
, &strings2
);
2230 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2231 ok(strings
!= strings2
, "got %p, %p\n", strings2
, strings
);
2232 IDWriteLocalizedStrings_Release(strings2
);
2234 count
= IDWriteLocalizedStrings_GetCount(strings
);
2235 ok(count
== 1, "got %d\n", count
);
2239 hr
= IDWriteLocalizedStrings_FindLocaleName(strings
, enus2W
, &index
, &exists
);
2240 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2241 ok(index
== 0 && exists
, "got %d, %d\n", index
, exists
);
2244 hr
= IDWriteLocalizedStrings_GetLocaleNameLength(strings
, 1, &count
);
2245 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2246 ok(count
== ~0, "got %d\n", count
);
2248 /* for simulated faces names are also simulated */
2250 hr
= IDWriteLocalizedStrings_GetLocaleName(strings
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2251 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2252 ok(!lstrcmpW(buffW
, enusW
), "got %s\n", wine_dbgstr_w(buffW
));
2255 hr
= IDWriteLocalizedStrings_GetString(strings
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2256 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2257 ok(!lstrcmpW(buffW
, obliqueW
), "got %s\n", wine_dbgstr_w(buffW
));
2258 IDWriteLocalizedStrings_Release(strings
);
2260 IDWriteFont_Release(font
);
2261 IDWriteGdiInterop_Release(interop
);
2262 IDWriteFactory_Release(factory
);
2271 static void test_TryGetFontTable(void)
2273 IDWriteLocalFontFileLoader
*localloader
;
2274 WIN32_FILE_ATTRIBUTE_DATA info
;
2275 const struct local_refkey
*key
;
2276 IDWriteFontFileLoader
*loader
;
2277 const void *table
, *table2
;
2278 IDWriteFontFace
*fontface
;
2279 void *context
, *context2
;
2280 IDWriteFactory
*factory
;
2281 IDWriteFontFile
*file
;
2282 WCHAR buffW
[MAX_PATH
];
2287 create_testfontfile(test_fontfile
);
2289 factory
= create_factory();
2291 hr
= IDWriteFactory_CreateFontFileReference(factory
, test_fontfile
, NULL
, &file
);
2292 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2296 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2297 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2298 ok(size
!= 0, "got %u\n", size
);
2300 ret
= GetFileAttributesExW(test_fontfile
, GetFileExInfoStandard
, &info
);
2301 ok(ret
, "got %d\n", ret
);
2302 ok(!memcmp(&info
.ftLastWriteTime
, &key
->writetime
, sizeof(key
->writetime
)), "got wrong write time\n");
2304 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2305 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2306 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2307 IDWriteFontFileLoader_Release(loader
);
2309 hr
= IDWriteLocalFontFileLoader_GetFilePathLengthFromKey(localloader
, key
, size
, &len
);
2310 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2311 ok(lstrlenW(key
->name
) == len
, "path length %d\n", len
);
2313 hr
= IDWriteLocalFontFileLoader_GetFilePathFromKey(localloader
, key
, size
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
2314 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2315 ok(!lstrcmpW(buffW
, key
->name
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(key
->name
));
2316 IDWriteLocalFontFileLoader_Release(localloader
);
2318 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, 0, &fontface
);
2319 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2322 context
= (void*)0xdeadbeef;
2324 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_CMAP_TAG
, &table
, &size
, &context
, &exists
);
2325 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2326 ok(exists
== TRUE
, "got %d\n", exists
);
2328 ok(context
== NULL
&& table
!= NULL
, "cmap: context %p, table %p\n", context
, table
);
2331 context2
= (void*)0xdeadbeef;
2333 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_CMAP_TAG
, &table2
, &size
, &context2
, &exists
);
2334 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2335 ok(exists
== TRUE
, "got %d\n", exists
);
2337 ok(context2
== context
&& table2
== table
, "cmap: context2 %p, table2 %p\n", context2
, table2
);
2339 IDWriteFontFace_ReleaseFontTable(fontface
, context2
);
2340 IDWriteFontFace_ReleaseFontTable(fontface
, context
);
2342 IDWriteFontFace_Release(fontface
);
2343 IDWriteFontFile_Release(file
);
2344 IDWriteFactory_Release(factory
);
2345 DeleteFileW(test_fontfile
);
2348 static void test_ConvertFontToLOGFONT(void)
2350 IDWriteFactory
*factory
, *factory2
;
2351 IDWriteFontCollection
*collection
;
2352 IDWriteGdiInterop
*interop
;
2353 IDWriteFontFamily
*family
;
2359 factory
= create_factory();
2360 factory2
= create_factory();
2363 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2364 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2366 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &collection
, FALSE
);
2367 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2369 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
2370 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2372 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2373 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2374 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2376 if (0) { /* crashes on native */
2377 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, NULL
, NULL
);
2378 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, &logfont
, NULL
);
2379 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, font
, NULL
, &system
);
2382 hr
= IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, &logfont
, &system
);
2383 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2384 ok(!system
, "got %d\n", system
);
2387 memset(&logfont
, 0, sizeof(logfont
));
2388 hr
= IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, font
, &logfont
, &system
);
2389 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2390 ok(system
, "got %d\n", system
);
2391 ok(logfont
.lfFaceName
[0] != 0, "got face name %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
2393 IDWriteFactory_Release(factory2
);
2395 IDWriteFontCollection_Release(collection
);
2396 IDWriteFontFamily_Release(family
);
2397 IDWriteFont_Release(font
);
2398 IDWriteGdiInterop_Release(interop
);
2399 IDWriteFactory_Release(factory
);
2402 static void test_CreateStreamFromKey(void)
2404 IDWriteLocalFontFileLoader
*localloader
;
2405 IDWriteFontFileStream
*stream
, *stream2
;
2406 IDWriteFontFileLoader
*loader
;
2407 IDWriteFactory
*factory
;
2408 IDWriteFontFile
*file
;
2414 factory
= create_factory();
2416 create_testfontfile(test_fontfile
);
2418 hr
= IDWriteFactory_CreateFontFileReference(factory
, test_fontfile
, NULL
, &file
);
2419 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2423 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2424 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2425 ok(size
!= 0, "got %u\n", size
);
2427 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2428 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2429 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2430 IDWriteFontFileLoader_Release(loader
);
2432 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2433 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2434 EXPECT_REF(stream
, 1);
2436 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream2
);
2437 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2438 ok(stream
== stream2
, "got %p, %p\n", stream
, stream2
);
2439 EXPECT_REF(stream
, 2);
2440 IDWriteFontFileStream_Release(stream
);
2441 IDWriteFontFileStream_Release(stream2
);
2443 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2444 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2445 EXPECT_REF(stream
, 1);
2448 hr
= IDWriteFontFileStream_GetLastWriteTime(stream
, &writetime
);
2449 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2450 ok(writetime
!= 0, "got %08x%08x\n", (UINT
)(writetime
>> 32), (UINT
)writetime
);
2452 IDWriteFontFileStream_Release(stream
);
2454 IDWriteLocalFontFileLoader_Release(localloader
);
2455 IDWriteFactory_Release(factory
);
2456 DeleteFileW(test_fontfile
);
2459 static void test_ReadFileFragment(void)
2461 IDWriteLocalFontFileLoader
*localloader
;
2462 IDWriteFontFileStream
*stream
;
2463 IDWriteFontFileLoader
*loader
;
2464 IDWriteFactory
*factory
;
2465 IDWriteFontFile
*file
;
2466 const void *fragment
, *fragment2
;
2467 void *key
, *context
, *context2
;
2472 factory
= create_factory();
2474 create_testfontfile(test_fontfile
);
2476 hr
= IDWriteFactory_CreateFontFileReference(factory
, test_fontfile
, NULL
, &file
);
2477 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2481 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
2482 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2483 ok(size
!= 0, "got %u\n", size
);
2485 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2486 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2487 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2488 IDWriteFontFileLoader_Release(loader
);
2490 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
2491 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2493 hr
= IDWriteFontFileStream_GetFileSize(stream
, &filesize
);
2494 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2496 /* reading past the end of the stream */
2497 fragment
= (void*)0xdeadbeef;
2498 context
= (void*)0xdeadbeef;
2499 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
+1, &context
);
2500 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2501 ok(context
== NULL
, "got %p\n", context
);
2502 ok(fragment
== NULL
, "got %p\n", fragment
);
2504 fragment
= (void*)0xdeadbeef;
2505 context
= (void*)0xdeadbeef;
2506 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
, &context
);
2507 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2508 ok(context
== NULL
, "got %p\n", context
);
2509 ok(fragment
!= NULL
, "got %p\n", fragment
);
2511 fragment2
= (void*)0xdeadbeef;
2512 context2
= (void*)0xdeadbeef;
2513 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment2
, 0, filesize
, &context2
);
2514 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2515 ok(context2
== NULL
, "got %p\n", context2
);
2516 ok(fragment
== fragment2
, "got %p, %p\n", fragment
, fragment2
);
2518 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
2519 IDWriteFontFileStream_ReleaseFileFragment(stream
, context2
);
2521 /* fragment is released, try again */
2522 fragment
= (void*)0xdeadbeef;
2523 context
= (void*)0xdeadbeef;
2524 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
, &context
);
2525 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2526 ok(context
== NULL
, "got %p\n", context
);
2527 ok(fragment
== fragment2
, "got %p, %p\n", fragment
, fragment2
);
2528 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
2530 IDWriteFontFileStream_Release(stream
);
2531 IDWriteLocalFontFileLoader_Release(localloader
);
2532 IDWriteFactory_Release(factory
);
2533 DeleteFileW(test_fontfile
);
2538 IDWriteFactory
*factory
;
2540 if (!(factory
= create_factory())) {
2541 win_skip("failed to create factory\n");
2545 test_CreateFontFromLOGFONT();
2546 test_CreateBitmapRenderTarget();
2547 test_GetFontFamily();
2548 test_GetFamilyNames();
2549 test_CreateFontFace();
2551 test_system_fontcollection();
2552 test_ConvertFontFaceToLOGFONT();
2553 test_CustomFontCollection();
2554 test_CreateCustomFontFileReference();
2555 test_CreateFontFileReference();
2556 test_shared_isolated();
2557 test_GetUnicodeRanges();
2558 test_GetFontFromFontFace();
2559 test_GetFirstMatchingFont();
2560 test_GetInformationalStrings();
2561 test_GetGdiInterop();
2562 test_CreateFontFaceFromHdc();
2563 test_GetSimulations();
2564 test_GetFaceNames();
2565 test_TryGetFontTable();
2566 test_ConvertFontToLOGFONT();
2567 test_CreateStreamFromKey();
2568 test_ReadFileFragment();
2570 IDWriteFactory_Release(factory
);