4 * Copyright 2012, 2014 Nikolay Sivov for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/test.h"
28 #define EXPECT_HR(hr,hr_exp) \
29 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
31 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
32 static void _expect_ref(IUnknown
* obj
, ULONG ref
, int line
)
36 rc
= IUnknown_Release(obj
);
37 ok_(__FILE__
,line
)(rc
== ref
, "expected refcount %d, got %d\n", ref
, rc
);
40 static inline void *heap_alloc(size_t len
)
42 return HeapAlloc(GetProcessHeap(), 0, len
);
45 static inline BOOL
heap_free(void *mem
)
47 return HeapFree(GetProcessHeap(), 0, mem
);
50 static IDWriteFactory
*factory
;
52 static const WCHAR tahomaW
[] = {'T','a','h','o','m','a',0};
53 static const WCHAR blahW
[] = {'B','l','a','h','!',0};
55 /* Here is a functional custom font set of interfaces */
56 struct test_fontdatastream
58 IDWriteFontFileStream IDWriteFontFileStream_iface
;
65 static inline struct test_fontdatastream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
* iface
)
67 return CONTAINING_RECORD(iface
, struct test_fontdatastream
, IDWriteFontFileStream_iface
);
70 static HRESULT WINAPI
fontdatastream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
72 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
75 IDWriteFontFileStream_AddRef(iface
);
82 static ULONG WINAPI
fontdatastream_AddRef(IDWriteFontFileStream
*iface
)
84 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
85 ULONG ref
= InterlockedIncrement(&This
->ref
);
89 static ULONG WINAPI
fontdatastream_Release(IDWriteFontFileStream
*iface
)
91 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
92 ULONG ref
= InterlockedDecrement(&This
->ref
);
94 HeapFree(GetProcessHeap(), 0, This
);
98 static HRESULT WINAPI
fontdatastream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
100 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
101 *fragment_context
= NULL
;
102 if (offset
+fragment_size
> This
->size
)
104 *fragment_start
= NULL
;
109 *fragment_start
= (BYTE
*)This
->data
+ offset
;
114 static void WINAPI
fontdatastream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
119 static HRESULT WINAPI
fontdatastream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
121 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
126 static HRESULT WINAPI
fontdatastream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
131 static const IDWriteFontFileStreamVtbl fontdatastreamvtbl
=
133 fontdatastream_QueryInterface
,
134 fontdatastream_AddRef
,
135 fontdatastream_Release
,
136 fontdatastream_ReadFileFragment
,
137 fontdatastream_ReleaseFileFragment
,
138 fontdatastream_GetFileSize
,
139 fontdatastream_GetLastWriteTime
142 static HRESULT
create_fontdatastream(LPVOID data
, UINT size
, IDWriteFontFileStream
** iface
)
144 struct test_fontdatastream
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct test_fontdatastream
));
146 return E_OUTOFMEMORY
;
151 This
->IDWriteFontFileStream_iface
.lpVtbl
= &fontdatastreamvtbl
;
153 *iface
= &This
->IDWriteFontFileStream_iface
;
157 static HRESULT WINAPI
resourcefontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
159 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
165 return E_NOINTERFACE
;
168 static ULONG WINAPI
resourcefontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
173 static ULONG WINAPI
resourcefontfileloader_Release(IDWriteFontFileLoader
*iface
)
178 static HRESULT WINAPI
resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
184 mem
= LoadResource(GetModuleHandleA(NULL
), *(HRSRC
*)fontFileReferenceKey
);
185 ok(mem
!= NULL
, "Failed to lock font resource\n");
188 size
= SizeofResource(GetModuleHandleA(NULL
), *(HRSRC
*)fontFileReferenceKey
);
189 data
= LockResource(mem
);
190 return create_fontdatastream(data
, size
, fontFileStream
);
195 static const struct IDWriteFontFileLoaderVtbl resourcefontfileloadervtbl
= {
196 resourcefontfileloader_QueryInterface
,
197 resourcefontfileloader_AddRef
,
198 resourcefontfileloader_Release
,
199 resourcefontfileloader_CreateStreamFromKey
202 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
204 static void test_CreateFontFromLOGFONT(void)
206 static const WCHAR tahomaspW
[] = {'T','a','h','o','m','a',' ',0};
207 IDWriteGdiInterop
*interop
;
208 DWRITE_FONT_WEIGHT weight
;
209 DWRITE_FONT_STYLE style
;
212 LONG weights
[][2] = {
213 {FW_NORMAL
, DWRITE_FONT_WEIGHT_NORMAL
},
214 {FW_BOLD
, DWRITE_FONT_WEIGHT_BOLD
},
215 { 0, DWRITE_FONT_WEIGHT_NORMAL
},
216 { 50, DWRITE_FONT_WEIGHT_NORMAL
},
217 {150, DWRITE_FONT_WEIGHT_NORMAL
},
218 {250, DWRITE_FONT_WEIGHT_NORMAL
},
219 {350, DWRITE_FONT_WEIGHT_NORMAL
},
220 {450, DWRITE_FONT_WEIGHT_NORMAL
},
221 {650, DWRITE_FONT_WEIGHT_BOLD
},
222 {750, DWRITE_FONT_WEIGHT_BOLD
},
223 {850, DWRITE_FONT_WEIGHT_BOLD
},
224 {950, DWRITE_FONT_WEIGHT_BOLD
},
225 {960, DWRITE_FONT_WEIGHT_BOLD
},
227 OUTLINETEXTMETRICW otm
;
236 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
240 /* null out parameter crashes this call */
241 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, NULL
);
243 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, &font
);
244 EXPECT_HR(hr
, E_INVALIDARG
);
246 memset(&logfont
, 0, sizeof(logfont
));
247 logfont
.lfHeight
= 12;
248 logfont
.lfWidth
= 12;
249 logfont
.lfWeight
= FW_NORMAL
;
250 logfont
.lfItalic
= 1;
251 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
253 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
256 hfont
= CreateFontIndirectW(&logfont
);
257 hdc
= CreateCompatibleDC(0);
258 SelectObject(hdc
, hfont
);
260 otm
.otmSize
= sizeof(otm
);
261 r
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
262 ok(r
, "got %d\n", r
);
267 hr
= IDWriteFont_HasCharacter(font
, 0xd800, &exists
);
268 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
269 ok(exists
== FALSE
, "got %d\n", exists
);
272 hr
= IDWriteFont_HasCharacter(font
, 0x20, &exists
);
273 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
274 ok(exists
== TRUE
, "got %d\n", exists
);
276 /* now check properties */
277 weight
= IDWriteFont_GetWeight(font
);
278 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
, "got %d\n", weight
);
280 style
= IDWriteFont_GetStyle(font
);
282 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %d\n", style
);
283 ok(otm
.otmfsSelection
== 1, "got 0x%08x\n", otm
.otmfsSelection
);
285 ret
= IDWriteFont_IsSymbolFont(font
);
286 ok(!ret
, "got %d\n", ret
);
288 IDWriteFont_Release(font
);
291 for (i
= 0; i
< sizeof(weights
)/(2*sizeof(LONG
)); i
++)
293 memset(&logfont
, 0, sizeof(logfont
));
294 logfont
.lfHeight
= 12;
295 logfont
.lfWidth
= 12;
296 logfont
.lfWeight
= weights
[i
][0];
297 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
299 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
302 weight
= IDWriteFont_GetWeight(font
);
303 ok(weight
== weights
[i
][1],
304 "%d: got %d, expected %d\n", i
, weight
, weights
[i
][1]);
305 IDWriteFont_Release(font
);
308 /* weight not from enum */
309 memset(&logfont
, 0, sizeof(logfont
));
310 logfont
.lfHeight
= 12;
311 logfont
.lfWidth
= 12;
312 logfont
.lfWeight
= 550;
313 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
316 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
317 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
319 weight
= IDWriteFont_GetWeight(font
);
320 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
|| broken(weight
== DWRITE_FONT_WEIGHT_BOLD
) /* win7 w/o SP */,
322 IDWriteFont_Release(font
);
324 /* empty or nonexistent face name */
325 memset(&logfont
, 0, sizeof(logfont
));
326 logfont
.lfHeight
= 12;
327 logfont
.lfWidth
= 12;
328 logfont
.lfWeight
= FW_NORMAL
;
329 lstrcpyW(logfont
.lfFaceName
, blahW
);
331 font
= (void*)0xdeadbeef;
332 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
333 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
334 ok(font
== NULL
, "got %p\n", font
);
336 /* Try with name 'Tahoma ' */
337 memset(&logfont
, 0, sizeof(logfont
));
338 logfont
.lfHeight
= 12;
339 logfont
.lfWidth
= 12;
340 logfont
.lfWeight
= FW_NORMAL
;
341 lstrcpyW(logfont
.lfFaceName
, tahomaspW
);
343 font
= (void*)0xdeadbeef;
344 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
345 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
346 ok(font
== NULL
, "got %p\n", font
);
348 /* empty string as a facename */
349 memset(&logfont
, 0, sizeof(logfont
));
350 logfont
.lfHeight
= 12;
351 logfont
.lfWidth
= 12;
352 logfont
.lfWeight
= FW_NORMAL
;
354 font
= (void*)0xdeadbeef;
355 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
356 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
357 ok(font
== NULL
, "got %p\n", font
);
359 IDWriteGdiInterop_Release(interop
);
362 static void test_CreateBitmapRenderTarget(void)
364 IDWriteBitmapRenderTarget
*target
, *target2
;
365 IDWriteGdiInterop
*interop
;
374 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
378 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target
);
381 if (0) /* crashes on native */
382 hr
= IDWriteBitmapRenderTarget_GetSize(target
, NULL
);
384 size
.cx
= size
.cy
= -1;
385 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
387 ok(size
.cx
== 0, "got %d\n", size
.cx
);
388 ok(size
.cy
== 0, "got %d\n", size
.cy
);
391 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target2
);
393 ok(target
!= target2
, "got %p, %p\n", target2
, target
);
394 IDWriteBitmapRenderTarget_Release(target2
);
396 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
397 ok(hdc
!= NULL
, "got %p\n", hdc
);
399 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
400 ok(hbm
!= NULL
, "got %p\n", hbm
);
402 /* check DIB properties */
403 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
404 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
405 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
406 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
407 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
408 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
409 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
411 IDWriteBitmapRenderTarget_Release(target
);
413 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
414 ok(!hbm
, "got %p\n", hbm
);
417 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 10, 5, &target
);
420 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
421 ok(hdc
!= NULL
, "got %p\n", hdc
);
423 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
424 ok(hbm
!= NULL
, "got %p\n", hbm
);
426 /* check DIB properties */
427 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
428 ok(ret
== sizeof(ds
), "got %d\n", ret
);
429 ok(ds
.dsBm
.bmWidth
== 10, "got %d\n", ds
.dsBm
.bmWidth
);
430 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
431 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
432 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
433 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
435 size
.cx
= size
.cy
= -1;
436 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
438 ok(size
.cx
== 10, "got %d\n", size
.cx
);
439 ok(size
.cy
== 5, "got %d\n", size
.cy
);
441 /* resize to same size */
442 hr
= IDWriteBitmapRenderTarget_Resize(target
, 10, 5);
443 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
445 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
446 ok(hbm2
== hbm
, "got %p, %p\n", hbm2
, hbm
);
449 hr
= IDWriteBitmapRenderTarget_Resize(target
, 5, 5);
450 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
452 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
453 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
455 hr
= IDWriteBitmapRenderTarget_Resize(target
, 20, 5);
456 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
458 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
459 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
461 hr
= IDWriteBitmapRenderTarget_Resize(target
, 1, 5);
462 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
464 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
465 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
467 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
468 ok(ret
== sizeof(ds
), "got %d\n", ret
);
469 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
470 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
471 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
472 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
473 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
475 /* empty rectangle */
476 hr
= IDWriteBitmapRenderTarget_Resize(target
, 0, 5);
477 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
479 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
480 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
482 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
483 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
484 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
485 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
486 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
487 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
488 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
490 /* transform tests */
491 if (0) /* crashes on native */
492 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, NULL
);
494 memset(&m
, 0xcc, sizeof(m
));
495 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
496 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
497 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
);
498 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
500 IDWriteBitmapRenderTarget_Release(target
);
501 IDWriteGdiInterop_Release(interop
);
504 static void test_GetFontFamily(void)
506 IDWriteFontCollection
*collection
, *collection2
;
507 IDWriteFontCollection
*syscoll
;
508 IDWriteFontFamily
*family
, *family2
;
509 IDWriteGdiInterop
*interop
;
510 IDWriteFont
*font
, *font2
;
514 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
517 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &syscoll
, FALSE
);
518 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
520 memset(&logfont
, 0, sizeof(logfont
));
521 logfont
.lfHeight
= 12;
522 logfont
.lfWidth
= 12;
523 logfont
.lfWeight
= FW_NORMAL
;
524 logfont
.lfItalic
= 1;
525 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
527 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
528 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
530 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
531 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
532 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
534 if (0) /* crashes on native */
535 hr
= IDWriteFont_GetFontFamily(font
, NULL
);
538 hr
= IDWriteFont_GetFontFamily(font
, &family
);
541 EXPECT_REF(family
, 2);
543 hr
= IDWriteFont_GetFontFamily(font
, &family2
);
545 ok(family2
== family
, "got %p, previous %p\n", family2
, family
);
547 EXPECT_REF(family
, 3);
548 IDWriteFontFamily_Release(family2
);
550 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFamily
, (void**)&family2
);
551 EXPECT_HR(hr
, E_NOINTERFACE
);
552 ok(family2
== NULL
, "got %p\n", family2
);
554 hr
= IDWriteFont_GetFontFamily(font2
, &family2
);
555 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
556 ok(family2
!= family
, "got %p, %p\n", family2
, family
);
559 hr
= IDWriteFontFamily_GetFontCollection(family
, &collection
);
561 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
564 hr
= IDWriteFontFamily_GetFontCollection(family2
, &collection2
);
566 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
567 ok(collection
== collection2
, "got %p, %p\n", collection
, collection2
);
569 ok(collection
== syscoll
, "got %p, %p\n", collection
, syscoll
);
571 IDWriteFontCollection_Release(syscoll
);
573 IDWriteFontCollection_Release(collection2
);
575 IDWriteFontCollection_Release(collection
);
576 IDWriteFontFamily_Release(family2
);
577 IDWriteFontFamily_Release(family
);
578 IDWriteFont_Release(font
);
579 IDWriteFont_Release(font2
);
580 IDWriteGdiInterop_Release(interop
);
583 static void test_GetFamilyNames(void)
585 IDWriteFontFamily
*family
;
586 IDWriteLocalizedStrings
*names
, *names2
;
587 IDWriteGdiInterop
*interop
;
594 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
597 memset(&logfont
, 0, sizeof(logfont
));
598 logfont
.lfHeight
= 12;
599 logfont
.lfWidth
= 12;
600 logfont
.lfWeight
= FW_NORMAL
;
601 logfont
.lfItalic
= 1;
602 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
604 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
607 hr
= IDWriteFont_GetFontFamily(font
, &family
);
610 if (0) /* crashes on native */
611 hr
= IDWriteFontFamily_GetFamilyNames(family
, NULL
);
613 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
614 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
615 EXPECT_REF(names
, 1);
617 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names2
);
618 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
619 EXPECT_REF(names2
, 1);
620 ok(names
!= names2
, "got %p, was %p\n", names2
, names
);
622 IDWriteLocalizedStrings_Release(names2
);
624 /* GetStringLength */
625 if (0) /* crashes on native */
626 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, NULL
);
629 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 10, &len
);
630 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
631 ok(len
== (UINT32
)-1, "got %u\n", len
);
634 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, &len
);
635 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
636 ok(len
> 0, "got %u\n", len
);
639 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 0);
640 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
642 hr
= IDWriteLocalizedStrings_GetString(names
, 10, NULL
, 0);
643 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
646 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 100);
649 hr
= IDWriteLocalizedStrings_GetString(names
, 10, buffer
, 100);
650 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
651 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
654 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
-1);
655 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
656 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
659 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
);
660 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
661 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
664 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
+1);
665 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
666 ok(buffer
[0] != 0, "got %x\n", buffer
[0]);
668 IDWriteLocalizedStrings_Release(names
);
670 IDWriteFontFamily_Release(family
);
671 IDWriteFont_Release(font
);
672 IDWriteGdiInterop_Release(interop
);
675 static void test_CreateFontFace(void)
677 IDWriteFontFace
*fontface
, *fontface2
;
678 IDWriteGdiInterop
*interop
;
683 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
686 memset(&logfont
, 0, sizeof(logfont
));
687 logfont
.lfHeight
= 12;
688 logfont
.lfWidth
= 12;
689 logfont
.lfWeight
= FW_NORMAL
;
690 logfont
.lfItalic
= 1;
691 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
693 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
694 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
696 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFace
, (void**)&fontface
);
697 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
699 if (0) /* crashes on native */
700 hr
= IDWriteFont_CreateFontFace(font
, NULL
);
702 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
703 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
705 hr
= IDWriteFont_CreateFontFace(font
, &fontface2
);
706 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
707 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
708 /* the fontface refcount is increased here */
709 IDWriteFontFace_Release(fontface
);
710 IDWriteFont_Release(font
);
712 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFont
, (void**)&font
);
713 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_NOTIMPL
), "got 0x%08x\n", hr
);
715 IDWriteFontFace_Release(fontface
);
716 IDWriteGdiInterop_Release(interop
);
719 static void test_GetMetrics(void)
721 IDWriteGdiInterop
*interop
;
722 DWRITE_FONT_METRICS metrics
;
723 OUTLINETEXTMETRICW otm
;
731 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
734 memset(&logfont
, 0, sizeof(logfont
));
735 logfont
.lfHeight
= 12;
736 logfont
.lfWidth
= 12;
737 logfont
.lfWeight
= FW_NORMAL
;
738 logfont
.lfItalic
= 1;
739 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
741 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
742 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
744 hfont
= CreateFontIndirectW(&logfont
);
745 hdc
= CreateCompatibleDC(0);
746 SelectObject(hdc
, hfont
);
748 otm
.otmSize
= sizeof(otm
);
749 ret
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
750 ok(ret
, "got %d\n", ret
);
754 if (0) /* crashes on native */
755 IDWriteFont_GetMetrics(font
, NULL
);
757 memset(&metrics
, 0, sizeof(metrics
));
758 IDWriteFont_GetMetrics(font
, &metrics
);
760 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
761 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
762 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
764 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
765 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
766 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
767 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
768 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
769 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
770 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
772 IDWriteFont_Release(font
);
773 IDWriteGdiInterop_Release(interop
);
776 static void test_system_fontcollection(void)
778 IDWriteFontCollection
*collection
, *coll2
;
779 IDWriteFontFamily
*family
;
780 IDWriteFactory
*factory2
;
785 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
786 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
788 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, FALSE
);
789 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
790 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
791 IDWriteFontCollection_Release(coll2
);
793 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, TRUE
);
794 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
795 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
796 IDWriteFontCollection_Release(coll2
);
798 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory2
);
799 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
800 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &coll2
, FALSE
);
801 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
802 ok(coll2
!= collection
, "got %p, was %p\n", coll2
, collection
);
803 IDWriteFontCollection_Release(coll2
);
804 IDWriteFactory_Release(factory2
);
806 i
= IDWriteFontCollection_GetFontFamilyCount(collection
);
807 ok(i
, "got %u\n", i
);
810 family
= (void*)0xdeadbeef;
811 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
812 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
813 ok(family
== NULL
, "got %p\n", family
);
817 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaW
, &i
, &ret
);
818 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
819 ok(ret
, "got %d\n", ret
);
820 ok(i
!= (UINT32
)-1, "got %u\n", i
);
824 hr
= IDWriteFontCollection_FindFamilyName(collection
, blahW
, &i
, &ret
);
825 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
826 ok(!ret
, "got %d\n", ret
);
827 ok(i
== (UINT32
)-1, "got %u\n", i
);
829 IDWriteFontCollection_Release(collection
);
832 static void test_ConvertFontFaceToLOGFONT(void)
834 IDWriteGdiInterop
*interop
;
835 IDWriteFontFace
*fontface
;
840 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
841 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
843 memset(&logfont
, 0, sizeof(logfont
));
844 logfont
.lfHeight
= 12;
845 logfont
.lfWidth
= 12;
846 logfont
.lfEscapement
= 100;
847 logfont
.lfWeight
= FW_NORMAL
;
848 logfont
.lfItalic
= 1;
849 logfont
.lfUnderline
= 1;
850 logfont
.lfStrikeOut
= 1;
852 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
854 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
855 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
857 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
858 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
859 IDWriteFont_Release(font
);
861 if (0) /* crashes on native */
863 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, NULL
, NULL
);
864 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, NULL
);
867 memset(&logfont
, 0xa, sizeof(logfont
));
868 logfont
.lfFaceName
[0] = 0;
870 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, &logfont
);
871 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
872 ok(logfont
.lfHeight
== 0, "got %d\n", logfont
.lfHeight
);
873 ok(logfont
.lfWidth
== 0, "got %d\n", logfont
.lfWidth
);
874 ok(logfont
.lfWeight
== FW_NORMAL
, "got %d\n", logfont
.lfWeight
);
875 ok(logfont
.lfEscapement
== 0, "got %d\n", logfont
.lfEscapement
);
876 ok(logfont
.lfItalic
== 1, "got %d\n", logfont
.lfItalic
);
877 ok(logfont
.lfUnderline
== 0, "got %d\n", logfont
.lfUnderline
);
878 ok(logfont
.lfStrikeOut
== 0, "got %d\n", logfont
.lfStrikeOut
);
879 ok(!lstrcmpW(logfont
.lfFaceName
, tahomaW
), "got %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
881 IDWriteGdiInterop_Release(interop
);
882 IDWriteFontFace_Release(fontface
);
885 static HRESULT WINAPI
fontcollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
891 static ULONG WINAPI
fontcollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
896 static ULONG WINAPI
fontcollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
901 static HRESULT WINAPI
fontcollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
* factory
, const void * collectionKey
, UINT32 collectionKeySize
, IDWriteFontFileEnumerator
** fontFileEnumerator
)
906 static const struct IDWriteFontCollectionLoaderVtbl dwritefontcollectionloadervtbl
= {
907 fontcollectionloader_QueryInterface
,
908 fontcollectionloader_AddRef
,
909 fontcollectionloader_Release
,
910 fontcollectionloader_CreateEnumeratorFromKey
913 static void test_CustomFontCollection(void)
915 IDWriteFontCollectionLoader collection
= { &dwritefontcollectionloadervtbl
};
916 IDWriteFontCollectionLoader collection2
= { &dwritefontcollectionloadervtbl
};
919 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, NULL
);
920 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
922 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, NULL
);
923 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
925 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
926 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
927 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection2
);
928 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
929 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
930 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
932 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
933 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
934 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
935 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
936 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection2
);
937 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
940 static HRESULT WINAPI
fontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
942 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
945 IDWriteFontFileLoader_AddRef(iface
);
950 return E_NOINTERFACE
;
953 static ULONG WINAPI
fontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
958 static ULONG WINAPI
fontfileloader_Release(IDWriteFontFileLoader
*iface
)
963 static HRESULT WINAPI
fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
968 static const struct IDWriteFontFileLoaderVtbl dwritefontfileloadervtbl
= {
969 fontfileloader_QueryInterface
,
970 fontfileloader_AddRef
,
971 fontfileloader_Release
,
972 fontfileloader_CreateStreamFromKey
975 static void test_FontLoader(void)
977 IDWriteFontFileLoader floader
= { &dwritefontfileloadervtbl
};
978 IDWriteFontFileLoader floader2
= { &dwritefontfileloadervtbl
};
979 IDWriteFontFileLoader floader3
= { &dwritefontfileloadervtbl
};
980 IDWriteFontFile
*ffile
= NULL
;
982 DWRITE_FONT_FILE_TYPE type
= 1;
983 DWRITE_FONT_FACE_TYPE face
= 1;
985 IDWriteFontFace
*fface
= NULL
;
988 UINT32 codePoints
[1] = {0xa8};
991 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, NULL
);
992 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
993 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
994 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
995 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader2
);
996 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
997 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
998 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
999 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1000 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1002 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &ffile
);
1003 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1005 IDWriteFontFile_Release(ffile
);
1007 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader3
, &ffile
);
1008 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1010 IDWriteFontFile_Release(ffile
);
1012 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, NULL
, &ffile
);
1013 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1015 IDWriteFontFile_Release(ffile
);
1017 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &ffile
);
1018 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1019 IDWriteFontFile_Analyze(ffile
, &support
, &type
, &face
, &count
);
1020 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1021 ok(support
== FALSE
, "got %i\n", support
);
1022 ok(type
== DWRITE_FONT_FILE_TYPE_UNKNOWN
, "got %i\n", type
);
1023 ok(face
== DWRITE_FONT_FACE_TYPE_UNKNOWN
, "got %i\n", face
);
1024 ok(count
== 0, "got %i\n", count
);
1026 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &ffile
, 0, 0, &fface
);
1027 ok(hr
== 0x8faecafe, "got 0x%08x\n", hr
);
1028 IDWriteFontFile_Release(ffile
);
1030 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1031 ok(font
!= NULL
, "Failed to find font resource\n");
1034 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &font
, sizeof(HRSRC
), &rloader
, &ffile
);
1035 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1037 hr
= IDWriteFontFile_Analyze(ffile
, &support
, &type
, &face
, &count
);
1038 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1039 ok(support
== TRUE
, "got %i\n", support
);
1040 ok(type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", type
);
1041 ok(face
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face
);
1042 ok(count
== 1, "got %i\n", count
);
1045 hr
= IDWriteFactory_CreateFontFace(factory
, face
, 1, &ffile
, 1, DWRITE_FONT_SIMULATIONS_NONE
, &fface
);
1046 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1048 hr
= IDWriteFactory_CreateFontFace(factory
, face
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fface
);
1049 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1050 hr
= IDWriteFontFace_GetGlyphIndices(fface
, codePoints
, 1, indices
);
1051 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1052 ok(indices
[0] == 6, "got index %i\n",indices
[0]);
1053 IDWriteFontFace_Release(fface
);
1054 IDWriteFontFile_Release(ffile
);
1057 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
1058 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1059 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
1060 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1061 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader2
);
1062 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1063 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
1064 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1067 static void test_CreateFontFileReference(void)
1074 WCHAR font_name
[] = {'w','i','n','e','_','t','e','s','t','_','f','o','n','t','.','t','t','f',0};
1075 IDWriteFontFile
*ffile
= NULL
;
1077 DWRITE_FONT_FILE_TYPE type
= 1;
1078 DWRITE_FONT_FACE_TYPE face
= 1;
1080 IDWriteFontFace
*fface
= NULL
;
1082 file
= CreateFileW(font_name
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1083 ok( file
!= INVALID_HANDLE_VALUE
, "file creation failed\n" );
1084 if (file
== INVALID_HANDLE_VALUE
) return;
1086 res
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1087 ok( res
!= 0, "couldn't find resource\n" );
1088 ptr
= LockResource( LoadResource( GetModuleHandleA(NULL
), res
));
1089 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleA(NULL
), res
), &written
, NULL
);
1090 ok( written
== SizeofResource( GetModuleHandleA(NULL
), res
), "couldn't write resource\n" );
1091 CloseHandle( file
);
1093 hr
= IDWriteFactory_CreateFontFileReference(factory
, font_name
, NULL
, &ffile
);
1094 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1096 IDWriteFontFile_Analyze(ffile
, &support
, &type
, &face
, &count
);
1097 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1098 ok(support
== TRUE
, "got %i\n", support
);
1099 ok(type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", type
);
1100 ok(face
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face
);
1101 ok(count
== 1, "got %i\n", count
);
1103 hr
= IDWriteFactory_CreateFontFace(factory
, face
, 1, &ffile
, 0, 0, &fface
);
1104 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1106 IDWriteFontFace_Release(fface
);
1107 IDWriteFontFile_Release(ffile
);
1109 DeleteFileW(font_name
);
1112 static void test_shared_isolated(void)
1114 IDWriteFactory
*isolated
, *isolated2
;
1115 IDWriteFactory
*shared
, *shared2
;
1120 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
1121 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1122 ok(shared
!= NULL
, "got %p\n", shared
);
1123 IDWriteFactory_Release(shared
);
1125 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
1126 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1128 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
1129 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1130 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
1132 IDWriteFactory_Release(shared
);
1133 IDWriteFactory_Release(shared2
);
1135 /* we got 2 references, released 2 - still same pointer is returned */
1136 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
1137 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1138 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
1139 IDWriteFactory_Release(shared2
);
1141 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated
);
1142 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1144 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
1145 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1146 ok(isolated
!= isolated2
, "got %p, and %p\n", isolated
, isolated2
);
1147 IDWriteFactory_Release(isolated2
);
1149 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
1150 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1151 ok(shared
!= isolated2
, "got %p, and %p\n", shared
, isolated2
);
1153 IDWriteFactory_Release(isolated
);
1154 IDWriteFactory_Release(isolated2
);
1157 static void test_GetUnicodeRanges(void)
1159 DWRITE_UNICODE_RANGE
*ranges
, r
;
1160 IDWriteFontFile
*ffile
= NULL
;
1161 IDWriteFontFace1
*fontface1
;
1162 IDWriteFontFace
*fontface
;
1167 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
1168 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1170 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
1171 ok(font
!= NULL
, "Failed to find font resource\n");
1173 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &font
, sizeof(HRSRC
), &rloader
, &ffile
);
1174 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1176 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1177 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1178 IDWriteFontFile_Release(ffile
);
1180 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
1181 IDWriteFontFace_Release(fontface
);
1183 win_skip("GetUnicodeRanges() is not supported.\n");
1188 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 0, NULL
, &count
);
1189 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1190 ok(count
> 0, "got %u\n", count
);
1193 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, NULL
, &count
);
1194 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1195 ok(count
== 0, "got %u\n", count
);
1198 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, &r
, &count
);
1199 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1200 ok(count
> 1, "got %u\n", count
);
1202 ranges
= heap_alloc(count
*sizeof(DWRITE_UNICODE_RANGE
));
1203 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, count
, ranges
, &count
);
1204 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1206 ranges
[0].first
= ranges
[0].last
= 0;
1207 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, ranges
, &count
);
1208 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1209 ok(ranges
[0].first
!= 0 && ranges
[0].last
!= 0, "got 0x%x-0x%0x\n", ranges
[0].first
, ranges
[0].last
);
1213 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
1214 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1216 IDWriteFontFace1_Release(fontface1
);
1219 static void test_GetFontFromFontFace(void)
1221 IDWriteFontFace
*fontface
, *fontface2
;
1222 IDWriteFontCollection
*collection
;
1223 IDWriteFont
*font
, *font2
, *font3
;
1224 IDWriteFontFamily
*family
;
1227 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1228 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1230 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
1231 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1233 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1234 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1235 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1237 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1238 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1241 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font2
);
1243 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1244 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
1247 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font3
);
1249 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1250 ok(font3
!= font
&& font3
!= font2
, "got %p, %p, %p\n", font3
, font2
, font
);
1254 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
1255 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1256 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
1257 IDWriteFontFace_Release(fontface2
);
1261 hr
= IDWriteFont_CreateFontFace(font3
, &fontface2
);
1262 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1263 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
1264 IDWriteFontFace_Release(fontface2
);
1268 IDWriteFont_Release(font
);
1270 IDWriteFont_Release(font2
);
1272 IDWriteFont_Release(font3
);
1273 IDWriteFontFace_Release(fontface
);
1274 IDWriteFontFamily_Release(family
);
1275 IDWriteFontCollection_Release(collection
);
1278 static void test_GetFirstMatchingFont(void)
1280 IDWriteFontCollection
*collection
;
1281 IDWriteFont
*font
, *font2
;
1282 IDWriteFontFamily
*family
;
1285 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1286 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1288 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
1289 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1291 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1292 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1293 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1295 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1296 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font2
);
1297 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1298 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1300 IDWriteFont_Release(font
);
1301 IDWriteFont_Release(font2
);
1302 IDWriteFontFamily_Release(family
);
1303 IDWriteFontCollection_Release(collection
);
1306 static void test_GetInformationalStrings(void)
1308 IDWriteLocalizedStrings
*strings
, *strings2
;
1309 IDWriteFontCollection
*collection
;
1310 IDWriteFontFamily
*family
;
1315 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1316 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1318 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
1319 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1321 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1322 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1323 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1326 strings
= (void*)0xdeadbeef;
1327 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
+1, &strings
, &exists
);
1329 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1330 ok(exists
== FALSE
, "got %d\n", exists
);
1331 ok(strings
== NULL
, "got %p\n", strings
);
1335 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings
, &exists
);
1337 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1338 ok(exists
== TRUE
, "got %d\n", exists
);
1343 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_NONE
, &strings
, &exists
);
1345 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1346 ok(exists
== FALSE
, "got %d\n", exists
);
1349 /* strings instance is not reused */
1351 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings2
, &exists
);
1353 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1354 ok(strings2
!= strings
, "got %p, %p\n", strings2
, strings
);
1358 IDWriteLocalizedStrings_Release(strings
);
1360 IDWriteLocalizedStrings_Release(strings2
);
1361 IDWriteFont_Release(font
);
1362 IDWriteFontFamily_Release(family
);
1363 IDWriteFontCollection_Release(collection
);
1366 static void test_GetGdiInterop(void)
1368 IDWriteGdiInterop
*interop
, *interop2
;
1369 IDWriteFactory
*factory2
;
1375 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1376 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1379 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop2
);
1380 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1381 ok(interop
== interop2
, "got %p, %p\n", interop
, interop2
);
1382 IDWriteGdiInterop_Release(interop2
);
1384 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory2
);
1385 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1387 /* each factory gets its own interop */
1389 hr
= IDWriteFactory_GetGdiInterop(factory2
, &interop2
);
1390 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1391 ok(interop
!= interop2
, "got %p, %p\n", interop
, interop2
);
1393 /* release factory - interop still works */
1394 IDWriteFactory_Release(factory2
);
1396 memset(&logfont
, 0, sizeof(logfont
));
1397 logfont
.lfHeight
= 12;
1398 logfont
.lfWidth
= 12;
1399 logfont
.lfWeight
= FW_NORMAL
;
1400 logfont
.lfItalic
= 1;
1401 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1403 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop2
, &logfont
, &font
);
1404 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1406 IDWriteGdiInterop_Release(interop2
);
1407 IDWriteGdiInterop_Release(interop
);
1410 static void test_CreateFontFaceFromHdc(void)
1412 IDWriteGdiInterop
*interop
;
1413 IDWriteFontFace
*fontface
;
1414 HFONT hfont
, oldhfont
;
1420 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1421 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1423 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, NULL
, &fontface
);
1424 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1426 memset(&logfont
, 0, sizeof(logfont
));
1427 logfont
.lfHeight
= 12;
1428 logfont
.lfWidth
= 12;
1429 logfont
.lfWeight
= FW_NORMAL
;
1430 logfont
.lfItalic
= 1;
1431 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1433 hfont
= CreateFontIndirectW(&logfont
);
1434 hdc
= CreateCompatibleDC(0);
1435 oldhfont
= SelectObject(hdc
, hfont
);
1438 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, hdc
, &fontface
);
1439 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1440 IDWriteFontFace_Release(fontface
);
1441 DeleteObject(SelectObject(hdc
, oldhfont
));
1444 IDWriteGdiInterop_Release(interop
);
1451 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory
);
1452 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1455 win_skip("failed to create factory\n");
1459 test_CreateFontFromLOGFONT();
1460 test_CreateBitmapRenderTarget();
1461 test_GetFontFamily();
1462 test_GetFamilyNames();
1463 test_CreateFontFace();
1465 test_system_fontcollection();
1466 test_ConvertFontFaceToLOGFONT();
1467 test_CustomFontCollection();
1469 test_CreateFontFileReference();
1470 test_shared_isolated();
1471 test_GetUnicodeRanges();
1472 test_GetFontFromFontFace();
1473 test_GetFirstMatchingFont();
1474 test_GetInformationalStrings();
1475 test_GetGdiInterop();
1476 test_CreateFontFaceFromHdc();
1478 IDWriteFactory_Release(factory
);