dwrite: Store pixels per dip value for a render target.
[wine.git] / dlls / dwrite / tests / font.c
blobe76dd6aad2f113068cbfe98d8a9339832cea2611
1 /*
2 * Font related tests
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
21 #define COBJMACROS
23 #include "windows.h"
24 #include "dwrite_1.h"
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)
34 ULONG rc;
35 IUnknown_AddRef(obj);
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 const WCHAR tahomaW[] = {'T','a','h','o','m','a',0};
51 static const WCHAR blahW[] = {'B','l','a','h','!',0};
53 static IDWriteFactory *create_factory(void)
55 IDWriteFactory *factory;
56 HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, &IID_IDWriteFactory, (IUnknown**)&factory);
57 ok(hr == S_OK, "got 0x%08x\n", hr);
58 return factory;
61 /* Here is a functional custom font set of interfaces */
62 struct test_fontdatastream
64 IDWriteFontFileStream IDWriteFontFileStream_iface;
65 LONG ref;
67 LPVOID data;
68 DWORD size;
71 static inline struct test_fontdatastream *impl_from_IDWriteFontFileStream(IDWriteFontFileStream* iface)
73 return CONTAINING_RECORD(iface, struct test_fontdatastream, IDWriteFontFileStream_iface);
76 static HRESULT WINAPI fontdatastream_QueryInterface(IDWriteFontFileStream *iface, REFIID riid, void **obj)
78 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteFontFileStream))
80 *obj = iface;
81 IDWriteFontFileStream_AddRef(iface);
82 return S_OK;
84 *obj = NULL;
85 return E_NOINTERFACE;
88 static ULONG WINAPI fontdatastream_AddRef(IDWriteFontFileStream *iface)
90 struct test_fontdatastream *This = impl_from_IDWriteFontFileStream(iface);
91 ULONG ref = InterlockedIncrement(&This->ref);
92 return ref;
95 static ULONG WINAPI fontdatastream_Release(IDWriteFontFileStream *iface)
97 struct test_fontdatastream *This = impl_from_IDWriteFontFileStream(iface);
98 ULONG ref = InterlockedDecrement(&This->ref);
99 if (ref == 0)
100 HeapFree(GetProcessHeap(), 0, This);
101 return ref;
104 static HRESULT WINAPI fontdatastream_ReadFileFragment(IDWriteFontFileStream *iface, void const **fragment_start, UINT64 offset, UINT64 fragment_size, void **fragment_context)
106 struct test_fontdatastream *This = impl_from_IDWriteFontFileStream(iface);
107 *fragment_context = NULL;
108 if (offset+fragment_size > This->size)
110 *fragment_start = NULL;
111 return E_FAIL;
113 else
115 *fragment_start = (BYTE*)This->data + offset;
116 return S_OK;
120 static void WINAPI fontdatastream_ReleaseFileFragment(IDWriteFontFileStream *iface, void *fragment_context)
122 /* Do Nothing */
125 static HRESULT WINAPI fontdatastream_GetFileSize(IDWriteFontFileStream *iface, UINT64 *size)
127 struct test_fontdatastream *This = impl_from_IDWriteFontFileStream(iface);
128 *size = This->size;
129 return S_OK;
132 static HRESULT WINAPI fontdatastream_GetLastWriteTime(IDWriteFontFileStream *iface, UINT64 *last_writetime)
134 return E_NOTIMPL;
137 static const IDWriteFontFileStreamVtbl fontdatastreamvtbl =
139 fontdatastream_QueryInterface,
140 fontdatastream_AddRef,
141 fontdatastream_Release,
142 fontdatastream_ReadFileFragment,
143 fontdatastream_ReleaseFileFragment,
144 fontdatastream_GetFileSize,
145 fontdatastream_GetLastWriteTime
148 static HRESULT create_fontdatastream(LPVOID data, UINT size, IDWriteFontFileStream** iface)
150 struct test_fontdatastream *This = HeapAlloc(GetProcessHeap(), 0, sizeof(struct test_fontdatastream));
151 if (!This)
152 return E_OUTOFMEMORY;
154 This->data = data;
155 This->size = size;
156 This->ref = 1;
157 This->IDWriteFontFileStream_iface.lpVtbl = &fontdatastreamvtbl;
159 *iface = &This->IDWriteFontFileStream_iface;
160 return S_OK;
163 static HRESULT WINAPI resourcefontfileloader_QueryInterface(IDWriteFontFileLoader *iface, REFIID riid, void **obj)
165 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteFontFileLoader))
167 *obj = iface;
168 return S_OK;
170 *obj = NULL;
171 return E_NOINTERFACE;
174 static ULONG WINAPI resourcefontfileloader_AddRef(IDWriteFontFileLoader *iface)
176 return 2;
179 static ULONG WINAPI resourcefontfileloader_Release(IDWriteFontFileLoader *iface)
181 return 1;
184 static HRESULT WINAPI resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileStream **fontFileStream)
186 LPVOID data;
187 DWORD size;
188 HGLOBAL mem;
190 mem = LoadResource(GetModuleHandleA(NULL), *(HRSRC*)fontFileReferenceKey);
191 ok(mem != NULL, "Failed to lock font resource\n");
192 if (mem)
194 size = SizeofResource(GetModuleHandleA(NULL), *(HRSRC*)fontFileReferenceKey);
195 data = LockResource(mem);
196 return create_fontdatastream(data, size, fontFileStream);
198 return E_FAIL;
201 static const struct IDWriteFontFileLoaderVtbl resourcefontfileloadervtbl = {
202 resourcefontfileloader_QueryInterface,
203 resourcefontfileloader_AddRef,
204 resourcefontfileloader_Release,
205 resourcefontfileloader_CreateStreamFromKey
208 static IDWriteFontFileLoader rloader = { &resourcefontfileloadervtbl };
210 static void test_CreateFontFromLOGFONT(void)
212 static const WCHAR tahomaspW[] = {'T','a','h','o','m','a',' ',0};
213 IDWriteGdiInterop *interop;
214 DWRITE_FONT_WEIGHT weight;
215 DWRITE_FONT_STYLE style;
216 IDWriteFont *font;
217 LOGFONTW logfont;
218 LONG weights[][2] = {
219 {FW_NORMAL, DWRITE_FONT_WEIGHT_NORMAL},
220 {FW_BOLD, DWRITE_FONT_WEIGHT_BOLD},
221 { 0, DWRITE_FONT_WEIGHT_NORMAL},
222 { 50, DWRITE_FONT_WEIGHT_NORMAL},
223 {150, DWRITE_FONT_WEIGHT_NORMAL},
224 {250, DWRITE_FONT_WEIGHT_NORMAL},
225 {350, DWRITE_FONT_WEIGHT_NORMAL},
226 {450, DWRITE_FONT_WEIGHT_NORMAL},
227 {650, DWRITE_FONT_WEIGHT_BOLD},
228 {750, DWRITE_FONT_WEIGHT_BOLD},
229 {850, DWRITE_FONT_WEIGHT_BOLD},
230 {950, DWRITE_FONT_WEIGHT_BOLD},
231 {960, DWRITE_FONT_WEIGHT_BOLD},
233 OUTLINETEXTMETRICW otm;
234 IDWriteFactory *factory;
235 HRESULT hr;
236 BOOL ret;
237 HDC hdc;
238 HFONT hfont;
239 BOOL exists;
240 int i;
241 UINT r;
243 factory = create_factory();
245 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
246 EXPECT_HR(hr, S_OK);
248 if (0)
249 /* null out parameter crashes this call */
250 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, NULL, NULL);
252 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, NULL, &font);
253 EXPECT_HR(hr, E_INVALIDARG);
255 memset(&logfont, 0, sizeof(logfont));
256 logfont.lfHeight = 12;
257 logfont.lfWidth = 12;
258 logfont.lfWeight = FW_NORMAL;
259 logfont.lfItalic = 1;
260 lstrcpyW(logfont.lfFaceName, tahomaW);
262 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
263 EXPECT_HR(hr, S_OK);
265 hfont = CreateFontIndirectW(&logfont);
266 hdc = CreateCompatibleDC(0);
267 SelectObject(hdc, hfont);
269 otm.otmSize = sizeof(otm);
270 r = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
271 ok(r, "got %d\n", r);
272 DeleteDC(hdc);
273 DeleteObject(hfont);
275 exists = TRUE;
276 hr = IDWriteFont_HasCharacter(font, 0xd800, &exists);
277 ok(hr == S_OK, "got 0x%08x\n", hr);
278 ok(exists == FALSE, "got %d\n", exists);
280 exists = FALSE;
281 hr = IDWriteFont_HasCharacter(font, 0x20, &exists);
282 ok(hr == S_OK, "got 0x%08x\n", hr);
283 ok(exists == TRUE, "got %d\n", exists);
285 /* now check properties */
286 weight = IDWriteFont_GetWeight(font);
287 ok(weight == DWRITE_FONT_WEIGHT_NORMAL, "got %d\n", weight);
289 style = IDWriteFont_GetStyle(font);
290 todo_wine {
291 ok(style == DWRITE_FONT_STYLE_OBLIQUE, "got %d\n", style);
292 ok(otm.otmfsSelection == 1, "got 0x%08x\n", otm.otmfsSelection);
294 ret = IDWriteFont_IsSymbolFont(font);
295 ok(!ret, "got %d\n", ret);
297 IDWriteFont_Release(font);
299 /* weight values */
300 for (i = 0; i < sizeof(weights)/(2*sizeof(LONG)); i++)
302 memset(&logfont, 0, sizeof(logfont));
303 logfont.lfHeight = 12;
304 logfont.lfWidth = 12;
305 logfont.lfWeight = weights[i][0];
306 lstrcpyW(logfont.lfFaceName, tahomaW);
308 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
309 EXPECT_HR(hr, S_OK);
311 weight = IDWriteFont_GetWeight(font);
312 ok(weight == weights[i][1],
313 "%d: got %d, expected %d\n", i, weight, weights[i][1]);
315 IDWriteFont_Release(font);
318 /* weight not from enum */
319 memset(&logfont, 0, sizeof(logfont));
320 logfont.lfHeight = 12;
321 logfont.lfWidth = 12;
322 logfont.lfWeight = 550;
323 lstrcpyW(logfont.lfFaceName, tahomaW);
325 font = NULL;
326 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
327 ok(hr == S_OK, "got 0x%08x\n", hr);
329 weight = IDWriteFont_GetWeight(font);
330 ok(weight == DWRITE_FONT_WEIGHT_NORMAL || broken(weight == DWRITE_FONT_WEIGHT_BOLD) /* win7 w/o SP */,
331 "got %d\n", weight);
332 IDWriteFont_Release(font);
334 /* empty or nonexistent face name */
335 memset(&logfont, 0, sizeof(logfont));
336 logfont.lfHeight = 12;
337 logfont.lfWidth = 12;
338 logfont.lfWeight = FW_NORMAL;
339 lstrcpyW(logfont.lfFaceName, blahW);
341 font = (void*)0xdeadbeef;
342 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
343 ok(hr == DWRITE_E_NOFONT, "got 0x%08x\n", hr);
344 ok(font == NULL, "got %p\n", font);
346 /* Try with name 'Tahoma ' */
347 memset(&logfont, 0, sizeof(logfont));
348 logfont.lfHeight = 12;
349 logfont.lfWidth = 12;
350 logfont.lfWeight = FW_NORMAL;
351 lstrcpyW(logfont.lfFaceName, tahomaspW);
353 font = (void*)0xdeadbeef;
354 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
355 ok(hr == DWRITE_E_NOFONT, "got 0x%08x\n", hr);
356 ok(font == NULL, "got %p\n", font);
358 /* empty string as a facename */
359 memset(&logfont, 0, sizeof(logfont));
360 logfont.lfHeight = 12;
361 logfont.lfWidth = 12;
362 logfont.lfWeight = FW_NORMAL;
364 font = (void*)0xdeadbeef;
365 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
366 ok(hr == DWRITE_E_NOFONT, "got 0x%08x\n", hr);
367 ok(font == NULL, "got %p\n", font);
369 IDWriteGdiInterop_Release(interop);
370 IDWriteFactory_Release(factory);
373 static void test_CreateBitmapRenderTarget(void)
375 IDWriteBitmapRenderTarget *target, *target2;
376 IDWriteGdiInterop *interop;
377 IDWriteFactory *factory;
378 HBITMAP hbm, hbm2;
379 DWRITE_MATRIX m;
380 DIBSECTION ds;
381 HRESULT hr;
382 FLOAT pdip;
383 SIZE size;
384 HDC hdc;
385 int ret;
387 factory = create_factory();
389 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
390 EXPECT_HR(hr, S_OK);
392 target = NULL;
393 hr = IDWriteGdiInterop_CreateBitmapRenderTarget(interop, NULL, 0, 0, &target);
394 EXPECT_HR(hr, S_OK);
396 if (0) /* crashes on native */
397 hr = IDWriteBitmapRenderTarget_GetSize(target, NULL);
399 size.cx = size.cy = -1;
400 hr = IDWriteBitmapRenderTarget_GetSize(target, &size);
401 EXPECT_HR(hr, S_OK);
402 ok(size.cx == 0, "got %d\n", size.cx);
403 ok(size.cy == 0, "got %d\n", size.cy);
405 target2 = NULL;
406 hr = IDWriteGdiInterop_CreateBitmapRenderTarget(interop, NULL, 0, 0, &target2);
407 EXPECT_HR(hr, S_OK);
408 ok(target != target2, "got %p, %p\n", target2, target);
409 IDWriteBitmapRenderTarget_Release(target2);
411 hdc = IDWriteBitmapRenderTarget_GetMemoryDC(target);
412 ok(hdc != NULL, "got %p\n", hdc);
414 hbm = GetCurrentObject(hdc, OBJ_BITMAP);
415 ok(hbm != NULL, "got %p\n", hbm);
417 /* check DIB properties */
418 ret = GetObjectW(hbm, sizeof(ds), &ds);
419 ok(ret == sizeof(BITMAP), "got %d\n", ret);
420 ok(ds.dsBm.bmWidth == 1, "got %d\n", ds.dsBm.bmWidth);
421 ok(ds.dsBm.bmHeight == 1, "got %d\n", ds.dsBm.bmHeight);
422 ok(ds.dsBm.bmPlanes == 1, "got %d\n", ds.dsBm.bmPlanes);
423 ok(ds.dsBm.bmBitsPixel == 1, "got %d\n", ds.dsBm.bmBitsPixel);
424 ok(!ds.dsBm.bmBits, "got %p\n", ds.dsBm.bmBits);
426 IDWriteBitmapRenderTarget_Release(target);
428 hbm = GetCurrentObject(hdc, OBJ_BITMAP);
429 ok(!hbm, "got %p\n", hbm);
431 target = NULL;
432 hr = IDWriteGdiInterop_CreateBitmapRenderTarget(interop, NULL, 10, 5, &target);
433 EXPECT_HR(hr, S_OK);
435 hdc = IDWriteBitmapRenderTarget_GetMemoryDC(target);
436 ok(hdc != NULL, "got %p\n", hdc);
438 hbm = GetCurrentObject(hdc, OBJ_BITMAP);
439 ok(hbm != NULL, "got %p\n", hbm);
441 /* check DIB properties */
442 ret = GetObjectW(hbm, sizeof(ds), &ds);
443 ok(ret == sizeof(ds), "got %d\n", ret);
444 ok(ds.dsBm.bmWidth == 10, "got %d\n", ds.dsBm.bmWidth);
445 ok(ds.dsBm.bmHeight == 5, "got %d\n", ds.dsBm.bmHeight);
446 ok(ds.dsBm.bmPlanes == 1, "got %d\n", ds.dsBm.bmPlanes);
447 ok(ds.dsBm.bmBitsPixel == 32, "got %d\n", ds.dsBm.bmBitsPixel);
448 ok(ds.dsBm.bmBits != NULL, "got %p\n", ds.dsBm.bmBits);
450 size.cx = size.cy = -1;
451 hr = IDWriteBitmapRenderTarget_GetSize(target, &size);
452 EXPECT_HR(hr, S_OK);
453 ok(size.cx == 10, "got %d\n", size.cx);
454 ok(size.cy == 5, "got %d\n", size.cy);
456 /* resize to same size */
457 hr = IDWriteBitmapRenderTarget_Resize(target, 10, 5);
458 ok(hr == S_OK, "got 0x%08x\n", hr);
460 hbm2 = GetCurrentObject(hdc, OBJ_BITMAP);
461 ok(hbm2 == hbm, "got %p, %p\n", hbm2, hbm);
463 /* shrink */
464 hr = IDWriteBitmapRenderTarget_Resize(target, 5, 5);
465 ok(hr == S_OK, "got 0x%08x\n", hr);
467 hbm2 = GetCurrentObject(hdc, OBJ_BITMAP);
468 ok(hbm2 != hbm, "got %p, %p\n", hbm2, hbm);
470 hr = IDWriteBitmapRenderTarget_Resize(target, 20, 5);
471 ok(hr == S_OK, "got 0x%08x\n", hr);
473 hbm2 = GetCurrentObject(hdc, OBJ_BITMAP);
474 ok(hbm2 != hbm, "got %p, %p\n", hbm2, hbm);
476 hr = IDWriteBitmapRenderTarget_Resize(target, 1, 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(ds), "got %d\n", ret);
484 ok(ds.dsBm.bmWidth == 1, "got %d\n", ds.dsBm.bmWidth);
485 ok(ds.dsBm.bmHeight == 5, "got %d\n", ds.dsBm.bmHeight);
486 ok(ds.dsBm.bmPlanes == 1, "got %d\n", ds.dsBm.bmPlanes);
487 ok(ds.dsBm.bmBitsPixel == 32, "got %d\n", ds.dsBm.bmBitsPixel);
488 ok(ds.dsBm.bmBits != NULL, "got %p\n", ds.dsBm.bmBits);
490 /* empty rectangle */
491 hr = IDWriteBitmapRenderTarget_Resize(target, 0, 5);
492 ok(hr == S_OK, "got 0x%08x\n", hr);
494 hbm2 = GetCurrentObject(hdc, OBJ_BITMAP);
495 ok(hbm2 != hbm, "got %p, %p\n", hbm2, hbm);
497 ret = GetObjectW(hbm2, sizeof(ds), &ds);
498 ok(ret == sizeof(BITMAP), "got %d\n", ret);
499 ok(ds.dsBm.bmWidth == 1, "got %d\n", ds.dsBm.bmWidth);
500 ok(ds.dsBm.bmHeight == 1, "got %d\n", ds.dsBm.bmHeight);
501 ok(ds.dsBm.bmPlanes == 1, "got %d\n", ds.dsBm.bmPlanes);
502 ok(ds.dsBm.bmBitsPixel == 1, "got %d\n", ds.dsBm.bmBitsPixel);
503 ok(!ds.dsBm.bmBits, "got %p\n", ds.dsBm.bmBits);
505 /* transform tests */
506 if (0) /* crashes on native */
507 hr = IDWriteBitmapRenderTarget_GetCurrentTransform(target, NULL);
509 memset(&m, 0xcc, sizeof(m));
510 hr = IDWriteBitmapRenderTarget_GetCurrentTransform(target, &m);
511 ok(hr == S_OK, "got 0x%08x\n", hr);
512 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);
513 ok(m.dx == 0.0 && m.dy == 0.0, "got %.1f,%.1f\n", m.dx, m.dy);
515 /* pixels per dip */
516 pdip = IDWriteBitmapRenderTarget_GetPixelsPerDip(target);
517 ok(pdip == 1.0, "got %.2f\n", pdip);
519 hr = IDWriteBitmapRenderTarget_SetPixelsPerDip(target, 2.0);
520 ok(hr == S_OK, "got 0x%08x\n", hr);
522 hr = IDWriteBitmapRenderTarget_SetPixelsPerDip(target, -1.0);
523 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
525 hr = IDWriteBitmapRenderTarget_SetPixelsPerDip(target, 0.0);
526 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
528 pdip = IDWriteBitmapRenderTarget_GetPixelsPerDip(target);
529 ok(pdip == 2.0, "got %.2f\n", pdip);
531 IDWriteBitmapRenderTarget_Release(target);
532 IDWriteGdiInterop_Release(interop);
533 IDWriteFactory_Release(factory);
536 static void test_GetFontFamily(void)
538 IDWriteFontCollection *collection, *collection2;
539 IDWriteFontCollection *syscoll;
540 IDWriteFontFamily *family, *family2;
541 IDWriteGdiInterop *interop;
542 IDWriteFont *font, *font2;
543 IDWriteFactory *factory;
544 LOGFONTW logfont;
545 HRESULT hr;
547 factory = create_factory();
549 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
550 EXPECT_HR(hr, S_OK);
552 hr = IDWriteFactory_GetSystemFontCollection(factory, &syscoll, FALSE);
553 ok(hr == S_OK, "got 0x%08x\n", hr);
555 memset(&logfont, 0, sizeof(logfont));
556 logfont.lfHeight = 12;
557 logfont.lfWidth = 12;
558 logfont.lfWeight = FW_NORMAL;
559 logfont.lfItalic = 1;
560 lstrcpyW(logfont.lfFaceName, tahomaW);
562 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
563 ok(hr == S_OK, "got 0x%08x\n", hr);
565 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font2);
566 ok(hr == S_OK, "got 0x%08x\n", hr);
567 ok(font2 != font, "got %p, %p\n", font2, font);
569 if (0) /* crashes on native */
570 hr = IDWriteFont_GetFontFamily(font, NULL);
572 EXPECT_REF(font, 1);
573 hr = IDWriteFont_GetFontFamily(font, &family);
574 EXPECT_HR(hr, S_OK);
575 EXPECT_REF(font, 1);
576 EXPECT_REF(family, 2);
578 hr = IDWriteFont_GetFontFamily(font, &family2);
579 EXPECT_HR(hr, S_OK);
580 ok(family2 == family, "got %p, previous %p\n", family2, family);
581 EXPECT_REF(font, 1);
582 EXPECT_REF(family, 3);
583 IDWriteFontFamily_Release(family2);
585 hr = IDWriteFont_QueryInterface(font, &IID_IDWriteFontFamily, (void**)&family2);
586 EXPECT_HR(hr, E_NOINTERFACE);
587 ok(family2 == NULL, "got %p\n", family2);
589 hr = IDWriteFont_GetFontFamily(font2, &family2);
590 ok(hr == S_OK, "got 0x%08x\n", hr);
591 ok(family2 != family, "got %p, %p\n", family2, family);
593 collection = NULL;
594 hr = IDWriteFontFamily_GetFontCollection(family, &collection);
595 ok(hr == S_OK, "got 0x%08x\n", hr);
597 collection2 = NULL;
598 hr = IDWriteFontFamily_GetFontCollection(family2, &collection2);
599 ok(hr == S_OK, "got 0x%08x\n", hr);
600 ok(collection == collection2, "got %p, %p\n", collection, collection2);
601 ok(collection == syscoll, "got %p, %p\n", collection, syscoll);
603 IDWriteFontCollection_Release(syscoll);
604 IDWriteFontCollection_Release(collection2);
605 IDWriteFontCollection_Release(collection);
606 IDWriteFontFamily_Release(family2);
607 IDWriteFontFamily_Release(family);
608 IDWriteFont_Release(font);
609 IDWriteFont_Release(font2);
610 IDWriteGdiInterop_Release(interop);
611 IDWriteFactory_Release(factory);
614 static void test_GetFamilyNames(void)
616 IDWriteFontFamily *family;
617 IDWriteLocalizedStrings *names, *names2;
618 IDWriteGdiInterop *interop;
619 IDWriteFactory *factory;
620 IDWriteFont *font;
621 LOGFONTW logfont;
622 WCHAR buffer[100];
623 HRESULT hr;
624 UINT32 len;
626 factory = create_factory();
628 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
629 EXPECT_HR(hr, S_OK);
631 memset(&logfont, 0, sizeof(logfont));
632 logfont.lfHeight = 12;
633 logfont.lfWidth = 12;
634 logfont.lfWeight = FW_NORMAL;
635 logfont.lfItalic = 1;
636 lstrcpyW(logfont.lfFaceName, tahomaW);
638 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
639 EXPECT_HR(hr, S_OK);
641 hr = IDWriteFont_GetFontFamily(font, &family);
642 EXPECT_HR(hr, S_OK);
644 if (0) /* crashes on native */
645 hr = IDWriteFontFamily_GetFamilyNames(family, NULL);
647 hr = IDWriteFontFamily_GetFamilyNames(family, &names);
648 ok(hr == S_OK, "got 0x%08x\n", hr);
649 EXPECT_REF(names, 1);
651 hr = IDWriteFontFamily_GetFamilyNames(family, &names2);
652 ok(hr == S_OK, "got 0x%08x\n", hr);
653 EXPECT_REF(names2, 1);
654 ok(names != names2, "got %p, was %p\n", names2, names);
656 IDWriteLocalizedStrings_Release(names2);
658 /* GetStringLength */
659 if (0) /* crashes on native */
660 hr = IDWriteLocalizedStrings_GetStringLength(names, 0, NULL);
662 len = 100;
663 hr = IDWriteLocalizedStrings_GetStringLength(names, 10, &len);
664 ok(hr == E_FAIL, "got 0x%08x\n", hr);
665 ok(len == (UINT32)-1, "got %u\n", len);
667 len = 0;
668 hr = IDWriteLocalizedStrings_GetStringLength(names, 0, &len);
669 ok(hr == S_OK, "got 0x%08x\n", hr);
670 ok(len > 0, "got %u\n", len);
672 /* GetString */
673 hr = IDWriteLocalizedStrings_GetString(names, 0, NULL, 0);
674 ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
676 hr = IDWriteLocalizedStrings_GetString(names, 10, NULL, 0);
677 ok(hr == E_FAIL, "got 0x%08x\n", hr);
679 if (0)
680 hr = IDWriteLocalizedStrings_GetString(names, 0, NULL, 100);
682 buffer[0] = 1;
683 hr = IDWriteLocalizedStrings_GetString(names, 10, buffer, 100);
684 ok(hr == E_FAIL, "got 0x%08x\n", hr);
685 ok(buffer[0] == 0, "got %x\n", buffer[0]);
687 buffer[0] = 1;
688 hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len-1);
689 ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
690 ok(buffer[0] == 0, "got %x\n", buffer[0]);
692 buffer[0] = 1;
693 hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len);
694 ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
695 ok(buffer[0] == 0, "got %x\n", buffer[0]);
697 buffer[0] = 0;
698 hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len+1);
699 ok(hr == S_OK, "got 0x%08x\n", hr);
700 ok(buffer[0] != 0, "got %x\n", buffer[0]);
702 IDWriteLocalizedStrings_Release(names);
704 IDWriteFontFamily_Release(family);
705 IDWriteFont_Release(font);
706 IDWriteGdiInterop_Release(interop);
707 IDWriteFactory_Release(factory);
710 static void test_CreateFontFace(void)
712 IDWriteFontFace *fontface, *fontface2;
713 IDWriteFontCollection *collection;
714 IDWriteGdiInterop *interop;
715 IDWriteFont *font, *font2;
716 IDWriteFontFamily *family;
717 IDWriteFactory *factory;
718 LOGFONTW logfont;
719 HRESULT hr;
721 factory = create_factory();
723 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
724 EXPECT_HR(hr, S_OK);
726 memset(&logfont, 0, sizeof(logfont));
727 logfont.lfHeight = 12;
728 logfont.lfWidth = 12;
729 logfont.lfWeight = FW_NORMAL;
730 logfont.lfItalic = 1;
731 lstrcpyW(logfont.lfFaceName, tahomaW);
733 font = NULL;
734 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
735 ok(hr == S_OK, "got 0x%08x\n", hr);
737 font2 = NULL;
738 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font2);
739 ok(hr == S_OK, "got 0x%08x\n", hr);
740 ok(font != font2, "got %p, %p\n", font, font2);
742 hr = IDWriteFont_QueryInterface(font, &IID_IDWriteFontFace, (void**)&fontface);
743 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
745 if (0) /* crashes on native */
746 hr = IDWriteFont_CreateFontFace(font, NULL);
748 fontface = NULL;
749 hr = IDWriteFont_CreateFontFace(font, &fontface);
750 ok(hr == S_OK, "got 0x%08x\n", hr);
752 fontface2 = NULL;
753 hr = IDWriteFont_CreateFontFace(font, &fontface2);
754 ok(hr == S_OK, "got 0x%08x\n", hr);
755 ok(fontface == fontface2, "got %p, was %p\n", fontface2, fontface);
756 IDWriteFontFace_Release(fontface2);
758 fontface2 = NULL;
759 hr = IDWriteFont_CreateFontFace(font2, &fontface2);
760 ok(hr == S_OK, "got 0x%08x\n", hr);
761 ok(fontface == fontface2, "got %p, was %p\n", fontface2, fontface);
762 IDWriteFontFace_Release(fontface2);
764 IDWriteFont_Release(font2);
765 IDWriteFont_Release(font);
767 hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFont, (void**)&font);
768 ok(hr == E_NOINTERFACE || broken(hr == E_NOTIMPL), "got 0x%08x\n", hr);
770 IDWriteFontFace_Release(fontface);
771 IDWriteGdiInterop_Release(interop);
773 /* Create from system collection */
774 hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE);
775 ok(hr == S_OK, "got 0x%08x\n", hr);
777 hr = IDWriteFontCollection_GetFontFamily(collection, 0, &family);
778 ok(hr == S_OK, "got 0x%08x\n", hr);
780 font = NULL;
781 hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
782 DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font);
783 ok(hr == S_OK, "got 0x%08x\n", hr);
785 font2 = NULL;
786 hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
787 DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font2);
788 ok(hr == S_OK, "got 0x%08x\n", hr);
789 ok(font != font2, "got %p, %p\n", font, font2);
791 fontface = NULL;
792 hr = IDWriteFont_CreateFontFace(font, &fontface);
793 ok(hr == S_OK, "got 0x%08x\n", hr);
795 fontface2 = NULL;
796 hr = IDWriteFont_CreateFontFace(font2, &fontface2);
797 ok(hr == S_OK, "got 0x%08x\n", hr);
798 ok(fontface == fontface2, "got %p, was %p\n", fontface2, fontface);
800 IDWriteFontFace_Release(fontface);
801 IDWriteFontFace_Release(fontface2);
802 IDWriteFont_Release(font2);
803 IDWriteFont_Release(font);
804 IDWriteFontFamily_Release(family);
805 IDWriteFontCollection_Release(collection);
806 IDWriteFactory_Release(factory);
809 static void test_GetMetrics(void)
811 IDWriteGdiInterop *interop;
812 DWRITE_FONT_METRICS metrics;
813 IDWriteFactory *factory;
814 OUTLINETEXTMETRICW otm;
815 IDWriteFont *font;
816 LOGFONTW logfont;
817 HRESULT hr;
818 HDC hdc;
819 HFONT hfont;
820 int ret;
822 factory = create_factory();
824 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
825 EXPECT_HR(hr, S_OK);
827 memset(&logfont, 0, sizeof(logfont));
828 logfont.lfHeight = 12;
829 logfont.lfWidth = 12;
830 logfont.lfWeight = FW_NORMAL;
831 logfont.lfItalic = 1;
832 lstrcpyW(logfont.lfFaceName, tahomaW);
834 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
835 ok(hr == S_OK, "got 0x%08x\n", hr);
837 hfont = CreateFontIndirectW(&logfont);
838 hdc = CreateCompatibleDC(0);
839 SelectObject(hdc, hfont);
841 otm.otmSize = sizeof(otm);
842 ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
843 ok(ret, "got %d\n", ret);
844 DeleteDC(hdc);
845 DeleteObject(hfont);
847 if (0) /* crashes on native */
848 IDWriteFont_GetMetrics(font, NULL);
850 memset(&metrics, 0, sizeof(metrics));
851 IDWriteFont_GetMetrics(font, &metrics);
853 ok(metrics.designUnitsPerEm != 0, "designUnitsPerEm %u\n", metrics.designUnitsPerEm);
854 ok(metrics.ascent != 0, "ascent %u\n", metrics.ascent);
855 ok(metrics.descent != 0, "descent %u\n", metrics.descent);
856 todo_wine
857 ok(metrics.lineGap == 0, "lineGap %d\n", metrics.lineGap);
858 ok(metrics.capHeight, "capHeight %u\n", metrics.capHeight);
859 ok(metrics.xHeight != 0, "xHeight %u\n", metrics.xHeight);
860 ok(metrics.underlinePosition < 0, "underlinePosition %d\n", metrics.underlinePosition);
861 ok(metrics.underlineThickness != 0, "underlineThickness %u\n", metrics.underlineThickness);
862 ok(metrics.strikethroughPosition > 0, "strikethroughPosition %d\n", metrics.strikethroughPosition);
863 ok(metrics.strikethroughThickness != 0, "strikethroughThickness %u\n", metrics.strikethroughThickness);
865 IDWriteFont_Release(font);
866 IDWriteGdiInterop_Release(interop);
867 IDWriteFactory_Release(factory);
870 static void test_system_fontcollection(void)
872 IDWriteFontCollection *collection, *coll2;
873 IDWriteLocalFontFileLoader *localloader;
874 IDWriteFactory *factory, *factory2;
875 IDWriteFontFileLoader *loader;
876 IDWriteFontFamily *family;
877 IDWriteFontFace *fontface;
878 IDWriteFontFile *file;
879 IDWriteFont *font;
880 HRESULT hr;
881 UINT32 i;
882 BOOL ret;
884 factory = create_factory();
886 hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE);
887 ok(hr == S_OK, "got 0x%08x\n", hr);
889 hr = IDWriteFactory_GetSystemFontCollection(factory, &coll2, FALSE);
890 ok(hr == S_OK, "got 0x%08x\n", hr);
891 ok(coll2 == collection, "got %p, was %p\n", coll2, collection);
892 IDWriteFontCollection_Release(coll2);
894 hr = IDWriteFactory_GetSystemFontCollection(factory, &coll2, TRUE);
895 ok(hr == S_OK, "got 0x%08x\n", hr);
896 ok(coll2 == collection, "got %p, was %p\n", coll2, collection);
897 IDWriteFontCollection_Release(coll2);
899 factory2 = create_factory();
900 hr = IDWriteFactory_GetSystemFontCollection(factory2, &coll2, FALSE);
901 ok(hr == S_OK, "got 0x%08x\n", hr);
902 ok(coll2 != collection, "got %p, was %p\n", coll2, collection);
903 IDWriteFontCollection_Release(coll2);
904 IDWriteFactory_Release(factory2);
906 i = IDWriteFontCollection_GetFontFamilyCount(collection);
907 ok(i, "got %u\n", i);
909 /* invalid index */
910 family = (void*)0xdeadbeef;
911 hr = IDWriteFontCollection_GetFontFamily(collection, i, &family);
912 ok(hr == E_FAIL, "got 0x%08x\n", hr);
913 ok(family == NULL, "got %p\n", family);
915 ret = FALSE;
916 i = (UINT32)-1;
917 hr = IDWriteFontCollection_FindFamilyName(collection, tahomaW, &i, &ret);
918 ok(hr == S_OK, "got 0x%08x\n", hr);
919 ok(ret, "got %d\n", ret);
920 ok(i != (UINT32)-1, "got %u\n", i);
922 /* get back local file loader */
923 hr = IDWriteFontCollection_GetFontFamily(collection, i, &family);
924 ok(hr == S_OK, "got 0x%08x\n", hr);
926 hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
927 DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font);
928 ok(hr == S_OK, "got 0x%08x\n", hr);
929 IDWriteFontFamily_Release(family);
931 hr = IDWriteFont_CreateFontFace(font, &fontface);
932 ok(hr == S_OK, "got 0x%08x\n", hr);
933 IDWriteFont_Release(font);
935 i = 1;
936 file = NULL;
937 hr = IDWriteFontFace_GetFiles(fontface, &i, &file);
938 ok(hr == S_OK, "got 0x%08x\n", hr);
939 ok(file != NULL, "got %p\n", file);
941 hr = IDWriteFontFile_GetLoader(file, &loader);
942 ok(hr == S_OK, "got 0x%08x\n", hr);
943 IDWriteFontFile_Release(file);
945 hr = IDWriteFontFileLoader_QueryInterface(loader, &IID_IDWriteLocalFontFileLoader, (void**)&localloader);
946 ok(hr == S_OK, "got 0x%08x\n", hr);
947 IDWriteLocalFontFileLoader_Release(localloader);
949 /* local loader is not registered by default */
950 hr = IDWriteFactory_RegisterFontFileLoader(factory, loader);
951 ok(hr == S_OK || broken(hr == DWRITE_E_ALREADYREGISTERED), "got 0x%08x\n", hr);
952 hr = IDWriteFactory_UnregisterFontFileLoader(factory, loader);
953 ok(hr == S_OK || broken(hr == E_INVALIDARG), "got 0x%08x\n", hr);
955 /* try with a different factory */
956 factory2 = create_factory();
957 hr = IDWriteFactory_RegisterFontFileLoader(factory2, loader);
958 ok(hr == S_OK || broken(hr == DWRITE_E_ALREADYREGISTERED), "got 0x%08x\n", hr);
959 hr = IDWriteFactory_RegisterFontFileLoader(factory2, loader);
960 ok(hr == DWRITE_E_ALREADYREGISTERED, "got 0x%08x\n", hr);
961 hr = IDWriteFactory_UnregisterFontFileLoader(factory2, loader);
962 ok(hr == S_OK || broken(hr == E_INVALIDARG), "got 0x%08x\n", hr);
963 hr = IDWriteFactory_UnregisterFontFileLoader(factory2, loader);
964 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
965 IDWriteFactory_Release(factory2);
967 IDWriteFontFileLoader_Release(loader);
969 ret = TRUE;
970 i = 0;
971 hr = IDWriteFontCollection_FindFamilyName(collection, blahW, &i, &ret);
972 ok(hr == S_OK, "got 0x%08x\n", hr);
973 ok(!ret, "got %d\n", ret);
974 ok(i == (UINT32)-1, "got %u\n", i);
976 IDWriteFontCollection_Release(collection);
977 IDWriteFactory_Release(factory);
980 static void test_ConvertFontFaceToLOGFONT(void)
982 IDWriteGdiInterop *interop;
983 IDWriteFontFace *fontface;
984 IDWriteFactory *factory;
985 IDWriteFont *font;
986 LOGFONTW logfont;
987 HRESULT hr;
989 factory = create_factory();
991 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
992 ok(hr == S_OK, "got 0x%08x\n", hr);
994 memset(&logfont, 0, sizeof(logfont));
995 logfont.lfHeight = 12;
996 logfont.lfWidth = 12;
997 logfont.lfEscapement = 100;
998 logfont.lfWeight = FW_NORMAL;
999 logfont.lfItalic = 1;
1000 logfont.lfUnderline = 1;
1001 logfont.lfStrikeOut = 1;
1003 lstrcpyW(logfont.lfFaceName, tahomaW);
1005 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
1006 ok(hr == S_OK, "got 0x%08x\n", hr);
1008 hr = IDWriteFont_CreateFontFace(font, &fontface);
1009 ok(hr == S_OK, "got 0x%08x\n", hr);
1010 IDWriteFont_Release(font);
1012 if (0) /* crashes on native */
1014 hr = IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop, NULL, NULL);
1015 hr = IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop, fontface, NULL);
1018 memset(&logfont, 0xa, sizeof(logfont));
1019 logfont.lfFaceName[0] = 0;
1021 hr = IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop, fontface, &logfont);
1022 ok(hr == S_OK, "got 0x%08x\n", hr);
1023 ok(logfont.lfHeight == 0, "got %d\n", logfont.lfHeight);
1024 ok(logfont.lfWidth == 0, "got %d\n", logfont.lfWidth);
1025 ok(logfont.lfWeight == FW_NORMAL, "got %d\n", logfont.lfWeight);
1026 ok(logfont.lfEscapement == 0, "got %d\n", logfont.lfEscapement);
1027 ok(logfont.lfItalic == 1, "got %d\n", logfont.lfItalic);
1028 ok(logfont.lfUnderline == 0, "got %d\n", logfont.lfUnderline);
1029 ok(logfont.lfStrikeOut == 0, "got %d\n", logfont.lfStrikeOut);
1030 todo_wine
1031 ok(!lstrcmpW(logfont.lfFaceName, tahomaW), "got %s\n", wine_dbgstr_w(logfont.lfFaceName));
1033 IDWriteGdiInterop_Release(interop);
1034 IDWriteFontFace_Release(fontface);
1035 IDWriteFactory_Release(factory);
1038 static HRESULT WINAPI fontcollectionloader_QueryInterface(IDWriteFontCollectionLoader *iface, REFIID riid, void **obj)
1040 *obj = iface;
1041 return S_OK;
1044 static ULONG WINAPI fontcollectionloader_AddRef(IDWriteFontCollectionLoader *iface)
1046 return 2;
1049 static ULONG WINAPI fontcollectionloader_Release(IDWriteFontCollectionLoader *iface)
1051 return 1;
1054 static HRESULT WINAPI fontcollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader *iface, IDWriteFactory * factory, const void * collectionKey, UINT32 collectionKeySize, IDWriteFontFileEnumerator ** fontFileEnumerator)
1056 return S_OK;
1059 static const struct IDWriteFontCollectionLoaderVtbl dwritefontcollectionloadervtbl = {
1060 fontcollectionloader_QueryInterface,
1061 fontcollectionloader_AddRef,
1062 fontcollectionloader_Release,
1063 fontcollectionloader_CreateEnumeratorFromKey
1066 static void test_CustomFontCollection(void)
1068 IDWriteFontCollectionLoader collection = { &dwritefontcollectionloadervtbl };
1069 IDWriteFontCollectionLoader collection2 = { &dwritefontcollectionloadervtbl };
1070 IDWriteFactory *factory;
1071 HRESULT hr;
1073 factory = create_factory();
1075 hr = IDWriteFactory_RegisterFontCollectionLoader(factory, NULL);
1076 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1078 hr = IDWriteFactory_UnregisterFontCollectionLoader(factory, NULL);
1079 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1081 hr = IDWriteFactory_RegisterFontCollectionLoader(factory, &collection);
1082 ok(hr == S_OK, "got 0x%08x\n", hr);
1083 hr = IDWriteFactory_RegisterFontCollectionLoader(factory, &collection2);
1084 ok(hr == S_OK, "got 0x%08x\n", hr);
1085 hr = IDWriteFactory_RegisterFontCollectionLoader(factory, &collection);
1086 ok(hr == DWRITE_E_ALREADYREGISTERED, "got 0x%08x\n", hr);
1088 hr = IDWriteFactory_UnregisterFontCollectionLoader(factory, &collection);
1089 ok(hr == S_OK, "got 0x%08x\n", hr);
1090 hr = IDWriteFactory_UnregisterFontCollectionLoader(factory, &collection);
1091 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1092 hr = IDWriteFactory_UnregisterFontCollectionLoader(factory, &collection2);
1093 ok(hr == S_OK, "got 0x%08x\n", hr);
1095 IDWriteFactory_Release(factory);
1098 static HRESULT WINAPI fontfileloader_QueryInterface(IDWriteFontFileLoader *iface, REFIID riid, void **obj)
1100 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteFontFileLoader))
1102 *obj = iface;
1103 IDWriteFontFileLoader_AddRef(iface);
1104 return S_OK;
1107 *obj = NULL;
1108 return E_NOINTERFACE;
1111 static ULONG WINAPI fontfileloader_AddRef(IDWriteFontFileLoader *iface)
1113 return 2;
1116 static ULONG WINAPI fontfileloader_Release(IDWriteFontFileLoader *iface)
1118 return 1;
1121 static HRESULT WINAPI fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileStream **fontFileStream)
1123 return 0x8faecafe;
1126 static const struct IDWriteFontFileLoaderVtbl dwritefontfileloadervtbl = {
1127 fontfileloader_QueryInterface,
1128 fontfileloader_AddRef,
1129 fontfileloader_Release,
1130 fontfileloader_CreateStreamFromKey
1133 static void test_CreateCustomFontFileReference(void)
1135 IDWriteFontFileLoader floader = { &dwritefontfileloadervtbl };
1136 IDWriteFontFileLoader floader2 = { &dwritefontfileloadervtbl };
1137 IDWriteFontFileLoader floader3 = { &dwritefontfileloadervtbl };
1138 IDWriteFactory *factory, *factory2;
1139 IDWriteFontFile *file, *file2;
1140 BOOL support;
1141 DWRITE_FONT_FILE_TYPE file_type;
1142 DWRITE_FONT_FACE_TYPE face_type;
1143 UINT32 count;
1144 IDWriteFontFace *face, *face2;
1145 HRESULT hr;
1146 HRSRC fontrsrc;
1147 UINT32 codePoints[1] = {0xa8};
1148 UINT16 indices[1];
1150 factory = create_factory();
1151 factory2 = create_factory();
1153 hr = IDWriteFactory_RegisterFontFileLoader(factory, NULL);
1154 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1155 hr = IDWriteFactory_RegisterFontFileLoader(factory, &floader);
1156 ok(hr == S_OK, "got 0x%08x\n", hr);
1157 hr = IDWriteFactory_RegisterFontFileLoader(factory, &floader2);
1158 ok(hr == S_OK, "got 0x%08x\n", hr);
1159 hr = IDWriteFactory_RegisterFontFileLoader(factory, &floader);
1160 ok(hr == DWRITE_E_ALREADYREGISTERED, "got 0x%08x\n", hr);
1161 hr = IDWriteFactory_RegisterFontFileLoader(factory, &rloader);
1162 ok(hr == S_OK, "got 0x%08x\n", hr);
1164 file = NULL;
1165 hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, &floader, &file);
1166 ok(hr == S_OK, "got 0x%08x\n", hr);
1167 IDWriteFontFile_Release(file);
1169 hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, &floader3, &file);
1170 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1172 hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, NULL, &file);
1173 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1175 file = NULL;
1176 hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, &floader, &file);
1177 ok(hr == S_OK, "got 0x%08x\n", hr);
1179 file_type = DWRITE_FONT_FILE_TYPE_TRUETYPE;
1180 face_type = DWRITE_FONT_FACE_TYPE_TRUETYPE;
1181 support = TRUE;
1182 count = 1;
1183 IDWriteFontFile_Analyze(file, &support, &file_type, &face_type, &count);
1184 ok(hr == S_OK, "got 0x%08x\n", hr);
1185 ok(support == FALSE, "got %i\n", support);
1186 ok(file_type == DWRITE_FONT_FILE_TYPE_UNKNOWN, "got %i\n", file_type);
1187 ok(face_type == DWRITE_FONT_FACE_TYPE_UNKNOWN, "got %i\n", face_type);
1188 ok(count == 0, "got %i\n", count);
1190 hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_CFF, 1, &file, 0, 0, &face);
1191 ok(hr == 0x8faecafe, "got 0x%08x\n", hr);
1192 IDWriteFontFile_Release(file);
1194 fontrsrc = FindResourceA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(1), (LPCSTR)RT_RCDATA);
1195 ok(fontrsrc != NULL, "Failed to find font resource\n");
1197 hr = IDWriteFactory_CreateCustomFontFileReference(factory, &fontrsrc, sizeof(HRSRC), &rloader, &file);
1198 ok(hr == S_OK, "got 0x%08x\n", hr);
1200 file_type = DWRITE_FONT_FILE_TYPE_UNKNOWN;
1201 face_type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
1202 support = FALSE;
1203 count = 0;
1204 hr = IDWriteFontFile_Analyze(file, &support, &file_type, &face_type, &count);
1205 ok(hr == S_OK, "got 0x%08x\n", hr);
1206 ok(support == TRUE, "got %i\n", support);
1207 ok(file_type == DWRITE_FONT_FILE_TYPE_TRUETYPE, "got %i\n", file_type);
1208 ok(face_type == DWRITE_FONT_FACE_TYPE_TRUETYPE, "got %i\n", face_type);
1209 ok(count == 1, "got %i\n", count);
1211 /* invalid index */
1212 hr = IDWriteFactory_CreateFontFace(factory, face_type, 1, &file, 1, DWRITE_FONT_SIMULATIONS_NONE, &face);
1213 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1215 hr = IDWriteFactory_CreateFontFace(factory, face_type, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &face);
1216 ok(hr == S_OK, "got 0x%08x\n", hr);
1218 hr = IDWriteFactory_CreateFontFace(factory, face_type, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &face2);
1219 ok(hr == S_OK, "got 0x%08x\n", hr);
1220 /* fontface instances are reused starting with win7 */
1221 ok(face == face2 || broken(face != face2), "got %p, %p\n", face, face2);
1222 IDWriteFontFace_Release(face2);
1224 /* file was created with different factory */
1225 face2 = NULL;
1226 hr = IDWriteFactory_CreateFontFace(factory2, face_type, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &face2);
1227 todo_wine
1228 ok(hr == S_OK, "got 0x%08x\n", hr);
1229 if (face2)
1230 IDWriteFontFace_Release(face2);
1232 file2 = NULL;
1233 hr = IDWriteFactory_CreateCustomFontFileReference(factory, &fontrsrc, sizeof(HRSRC), &rloader, &file2);
1234 ok(hr == S_OK, "got 0x%08x\n", hr);
1235 ok(file != file2, "got %p, %p\n", file, file2);
1237 hr = IDWriteFactory_CreateFontFace(factory, face_type, 1, &file2, 0, DWRITE_FONT_SIMULATIONS_NONE, &face2);
1238 ok(hr == S_OK, "got 0x%08x\n", hr);
1239 /* fontface instances are reused starting with win7 */
1240 ok(face == face2 || broken(face != face2), "got %p, %p\n", face, face2);
1241 IDWriteFontFace_Release(face2);
1242 IDWriteFontFile_Release(file2);
1244 hr = IDWriteFontFace_GetGlyphIndices(face, codePoints, 1, indices);
1245 ok(hr == S_OK, "got 0x%08x\n", hr);
1246 ok(indices[0] == 6, "got index %i\n", indices[0]);
1247 IDWriteFontFace_Release(face);
1248 IDWriteFontFile_Release(file);
1250 hr = IDWriteFactory_UnregisterFontFileLoader(factory, &floader);
1251 ok(hr == S_OK, "got 0x%08x\n", hr);
1252 hr = IDWriteFactory_UnregisterFontFileLoader(factory, &floader);
1253 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1254 hr = IDWriteFactory_UnregisterFontFileLoader(factory, &floader2);
1255 ok(hr == S_OK, "got 0x%08x\n", hr);
1256 hr = IDWriteFactory_UnregisterFontFileLoader(factory, &rloader);
1257 ok(hr == S_OK, "got 0x%08x\n", hr);
1259 IDWriteFactory_Release(factory2);
1260 IDWriteFactory_Release(factory);
1263 static void test_CreateFontFileReference(void)
1265 DWORD written;
1266 HANDLE file;
1267 HRSRC res;
1268 void *ptr;
1269 HRESULT hr;
1270 WCHAR font_name[] = {'w','i','n','e','_','t','e','s','t','_','f','o','n','t','.','t','t','f',0};
1271 IDWriteFontFile *ffile = NULL;
1272 BOOL support = 1;
1273 DWRITE_FONT_FILE_TYPE type = 1;
1274 DWRITE_FONT_FACE_TYPE face = 1;
1275 UINT32 count = 1;
1276 IDWriteFontFace *fface = NULL;
1277 IDWriteFactory *factory;
1279 file = CreateFileW(font_name, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1280 ok( file != INVALID_HANDLE_VALUE, "file creation failed\n" );
1282 res = FindResourceA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(1), (LPCSTR)RT_RCDATA);
1283 ok( res != 0, "couldn't find resource\n" );
1284 ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
1285 WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
1286 ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
1287 CloseHandle( file );
1289 factory = create_factory();
1291 hr = IDWriteFactory_CreateFontFileReference(factory, font_name, NULL, &ffile);
1292 ok(hr == S_OK, "got 0x%08x\n",hr);
1294 IDWriteFontFile_Analyze(ffile, &support, &type, &face, &count);
1295 ok(hr == S_OK, "got 0x%08x\n", hr);
1296 ok(support == TRUE, "got %i\n", support);
1297 ok(type == DWRITE_FONT_FILE_TYPE_TRUETYPE, "got %i\n", type);
1298 ok(face == DWRITE_FONT_FACE_TYPE_TRUETYPE, "got %i\n", face);
1299 ok(count == 1, "got %i\n", count);
1301 hr = IDWriteFactory_CreateFontFace(factory, face, 1, &ffile, 0, DWRITE_FONT_SIMULATIONS_NONE, &fface);
1302 ok(hr == S_OK, "got 0x%08x\n", hr);
1304 IDWriteFontFace_Release(fface);
1305 IDWriteFontFile_Release(ffile);
1306 IDWriteFactory_Release(factory);
1308 DeleteFileW(font_name);
1311 static void test_shared_isolated(void)
1313 IDWriteFactory *isolated, *isolated2;
1314 IDWriteFactory *shared, *shared2;
1315 HRESULT hr;
1317 /* invalid type */
1318 shared = NULL;
1319 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED+1, &IID_IDWriteFactory, (IUnknown**)&shared);
1320 ok(hr == S_OK, "got 0x%08x\n", hr);
1321 ok(shared != NULL, "got %p\n", shared);
1322 IDWriteFactory_Release(shared);
1324 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown**)&shared);
1325 ok(hr == S_OK, "got 0x%08x\n", hr);
1327 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown**)&shared2);
1328 ok(hr == S_OK, "got 0x%08x\n", hr);
1329 ok(shared == shared2, "got %p, and %p\n", shared, shared2);
1331 IDWriteFactory_Release(shared);
1332 IDWriteFactory_Release(shared2);
1334 /* we got 2 references, released 2 - still same pointer is returned */
1335 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown**)&shared2);
1336 ok(hr == S_OK, "got 0x%08x\n", hr);
1337 ok(shared == shared2, "got %p, and %p\n", shared, shared2);
1338 IDWriteFactory_Release(shared2);
1340 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, &IID_IDWriteFactory, (IUnknown**)&isolated);
1341 ok(hr == S_OK, "got 0x%08x\n", hr);
1343 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, &IID_IDWriteFactory, (IUnknown**)&isolated2);
1344 ok(hr == S_OK, "got 0x%08x\n", hr);
1345 ok(isolated != isolated2, "got %p, and %p\n", isolated, isolated2);
1346 IDWriteFactory_Release(isolated2);
1348 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED+1, &IID_IDWriteFactory, (IUnknown**)&isolated2);
1349 ok(hr == S_OK, "got 0x%08x\n", hr);
1350 ok(shared != isolated2, "got %p, and %p\n", shared, isolated2);
1352 IDWriteFactory_Release(isolated);
1353 IDWriteFactory_Release(isolated2);
1356 static void test_GetUnicodeRanges(void)
1358 DWRITE_UNICODE_RANGE *ranges, r;
1359 IDWriteFontFile *ffile = NULL;
1360 IDWriteFontFace1 *fontface1;
1361 IDWriteFontFace *fontface;
1362 IDWriteFactory *factory;
1363 UINT32 count;
1364 HRESULT hr;
1365 HRSRC font;
1367 factory = create_factory();
1369 hr = IDWriteFactory_RegisterFontFileLoader(factory, &rloader);
1370 ok(hr == S_OK, "got 0x%08x\n", hr);
1372 font = FindResourceA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(1), (LPCSTR)RT_RCDATA);
1373 ok(font != NULL, "Failed to find font resource\n");
1375 hr = IDWriteFactory_CreateCustomFontFileReference(factory, &font, sizeof(HRSRC), &rloader, &ffile);
1376 ok(hr == S_OK, "got 0x%08x\n", hr);
1378 hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &ffile, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface);
1379 ok(hr == S_OK, "got 0x%08x\n", hr);
1380 IDWriteFontFile_Release(ffile);
1382 hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1);
1383 IDWriteFontFace_Release(fontface);
1384 if (hr != S_OK) {
1385 win_skip("GetUnicodeRanges() is not supported.\n");
1386 IDWriteFactory_Release(factory);
1387 return;
1390 count = 0;
1391 hr = IDWriteFontFace1_GetUnicodeRanges(fontface1, 0, NULL, &count);
1392 ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
1393 ok(count > 0, "got %u\n", count);
1395 count = 1;
1396 hr = IDWriteFontFace1_GetUnicodeRanges(fontface1, 1, NULL, &count);
1397 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1398 ok(count == 0, "got %u\n", count);
1400 count = 0;
1401 hr = IDWriteFontFace1_GetUnicodeRanges(fontface1, 1, &r, &count);
1402 ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
1403 ok(count > 1, "got %u\n", count);
1405 ranges = heap_alloc(count*sizeof(DWRITE_UNICODE_RANGE));
1406 hr = IDWriteFontFace1_GetUnicodeRanges(fontface1, count, ranges, &count);
1407 ok(hr == S_OK, "got 0x%08x\n", hr);
1409 ranges[0].first = ranges[0].last = 0;
1410 hr = IDWriteFontFace1_GetUnicodeRanges(fontface1, 1, ranges, &count);
1411 ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
1412 ok(ranges[0].first != 0 && ranges[0].last != 0, "got 0x%x-0x%0x\n", ranges[0].first, ranges[0].last);
1414 heap_free(ranges);
1416 hr = IDWriteFactory_UnregisterFontFileLoader(factory, &rloader);
1417 ok(hr == S_OK, "got 0x%08x\n", hr);
1419 IDWriteFontFace1_Release(fontface1);
1420 IDWriteFactory_Release(factory);
1423 static void test_GetFontFromFontFace(void)
1425 IDWriteFontFace *fontface, *fontface2;
1426 IDWriteFontCollection *collection;
1427 IDWriteFont *font, *font2, *font3;
1428 IDWriteFontFamily *family;
1429 IDWriteFactory *factory;
1430 HRESULT hr;
1432 factory = create_factory();
1434 hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE);
1435 ok(hr == S_OK, "got 0x%08x\n", hr);
1437 hr = IDWriteFontCollection_GetFontFamily(collection, 0, &family);
1438 ok(hr == S_OK, "got 0x%08x\n", hr);
1440 hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
1441 DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font);
1442 ok(hr == S_OK, "got 0x%08x\n", hr);
1444 hr = IDWriteFont_CreateFontFace(font, &fontface);
1445 ok(hr == S_OK, "got 0x%08x\n", hr);
1447 font2 = NULL;
1448 hr = IDWriteFontCollection_GetFontFromFontFace(collection, fontface, &font2);
1449 ok(hr == S_OK, "got 0x%08x\n", hr);
1450 ok(font2 != font, "got %p, %p\n", font2, font);
1452 font3 = NULL;
1453 hr = IDWriteFontCollection_GetFontFromFontFace(collection, fontface, &font3);
1454 ok(hr == S_OK, "got 0x%08x\n", hr);
1455 ok(font3 != font && font3 != font2, "got %p, %p, %p\n", font3, font2, font);
1457 hr = IDWriteFont_CreateFontFace(font2, &fontface2);
1458 ok(hr == S_OK, "got 0x%08x\n", hr);
1459 ok(fontface2 == fontface, "got %p, %p\n", fontface2, fontface);
1460 IDWriteFontFace_Release(fontface2);
1462 hr = IDWriteFont_CreateFontFace(font3, &fontface2);
1463 ok(hr == S_OK, "got 0x%08x\n", hr);
1464 ok(fontface2 == fontface, "got %p, %p\n", fontface2, fontface);
1465 IDWriteFontFace_Release(fontface2);
1467 IDWriteFont_Release(font);
1468 IDWriteFont_Release(font2);
1469 IDWriteFont_Release(font3);
1470 IDWriteFontFace_Release(fontface);
1471 IDWriteFontFamily_Release(family);
1472 IDWriteFontCollection_Release(collection);
1473 IDWriteFactory_Release(factory);
1476 static void test_GetFirstMatchingFont(void)
1478 DWRITE_FONT_SIMULATIONS simulations;
1479 IDWriteFontCollection *collection;
1480 IDWriteFont *font, *font2;
1481 IDWriteFontFamily *family;
1482 IDWriteFactory *factory;
1483 UINT32 index;
1484 BOOL exists;
1485 HRESULT hr;
1487 factory = create_factory();
1489 hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE);
1490 ok(hr == S_OK, "got 0x%08x\n", hr);
1492 index = ~0;
1493 exists = FALSE;
1494 hr = IDWriteFontCollection_FindFamilyName(collection, tahomaW, &index, &exists);
1495 ok(hr == S_OK, "got 0x%08x\n", hr);
1496 ok(exists, "got %d\n", exists);
1498 hr = IDWriteFontCollection_GetFontFamily(collection, index, &family);
1499 ok(hr == S_OK, "got 0x%08x\n", hr);
1501 hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
1502 DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font);
1503 ok(hr == S_OK, "got 0x%08x\n", hr);
1505 hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
1506 DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font2);
1507 ok(hr == S_OK, "got 0x%08x\n", hr);
1508 ok(font != font2, "got %p, %p\n", font, font2);
1509 IDWriteFont_Release(font);
1511 hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
1512 DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_ITALIC, &font);
1513 ok(hr == S_OK, "got 0x%08x\n", hr);
1515 simulations = IDWriteFont_GetSimulations(font);
1516 todo_wine
1517 ok(simulations == DWRITE_FONT_SIMULATIONS_OBLIQUE, "%d\n", simulations);
1519 IDWriteFont_Release(font);
1520 IDWriteFont_Release(font2);
1521 IDWriteFontFamily_Release(family);
1522 IDWriteFontCollection_Release(collection);
1523 IDWriteFactory_Release(factory);
1526 static void test_GetInformationalStrings(void)
1528 IDWriteLocalizedStrings *strings, *strings2;
1529 IDWriteFontCollection *collection;
1530 IDWriteFontFamily *family;
1531 IDWriteFactory *factory;
1532 IDWriteFont *font;
1533 BOOL exists;
1534 HRESULT hr;
1536 factory = create_factory();
1538 hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE);
1539 ok(hr == S_OK, "got 0x%08x\n", hr);
1541 hr = IDWriteFontCollection_GetFontFamily(collection, 0, &family);
1542 ok(hr == S_OK, "got 0x%08x\n", hr);
1544 hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
1545 DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font);
1546 ok(hr == S_OK, "got 0x%08x\n", hr);
1548 exists = TRUE;
1549 strings = (void*)0xdeadbeef;
1550 hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME+1, &strings, &exists);
1551 ok(hr == S_OK, "got 0x%08x\n", hr);
1552 ok(exists == FALSE, "got %d\n", exists);
1553 ok(strings == NULL, "got %p\n", strings);
1555 exists = TRUE;
1556 strings = NULL;
1557 hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_NONE, &strings, &exists);
1558 ok(hr == S_OK, "got 0x%08x\n", hr);
1559 ok(exists == FALSE, "got %d\n", exists);
1561 exists = FALSE;
1562 strings = NULL;
1563 hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &exists);
1564 ok(hr == S_OK, "got 0x%08x\n", hr);
1565 ok(exists == TRUE, "got %d\n", exists);
1567 /* strings instance is not reused */
1568 strings2 = NULL;
1569 hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings2, &exists);
1570 ok(hr == S_OK, "got 0x%08x\n", hr);
1571 ok(strings2 != strings, "got %p, %p\n", strings2, strings);
1573 IDWriteLocalizedStrings_Release(strings);
1574 IDWriteLocalizedStrings_Release(strings2);
1575 IDWriteFont_Release(font);
1576 IDWriteFontFamily_Release(family);
1577 IDWriteFontCollection_Release(collection);
1578 IDWriteFactory_Release(factory);
1581 static void test_GetGdiInterop(void)
1583 IDWriteGdiInterop *interop, *interop2;
1584 IDWriteFactory *factory, *factory2;
1585 IDWriteFont *font;
1586 LOGFONTW logfont;
1587 HRESULT hr;
1589 factory = create_factory();
1591 interop = NULL;
1592 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
1593 ok(hr == S_OK, "got 0x%08x\n", hr);
1595 interop2 = NULL;
1596 hr = IDWriteFactory_GetGdiInterop(factory, &interop2);
1597 ok(hr == S_OK, "got 0x%08x\n", hr);
1598 ok(interop == interop2, "got %p, %p\n", interop, interop2);
1599 IDWriteGdiInterop_Release(interop2);
1601 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, &IID_IDWriteFactory, (IUnknown**)&factory2);
1602 ok(hr == S_OK, "got 0x%08x\n", hr);
1604 /* each factory gets its own interop */
1605 interop2 = NULL;
1606 hr = IDWriteFactory_GetGdiInterop(factory2, &interop2);
1607 ok(hr == S_OK, "got 0x%08x\n", hr);
1608 ok(interop != interop2, "got %p, %p\n", interop, interop2);
1610 /* release factory - interop still works */
1611 IDWriteFactory_Release(factory2);
1613 memset(&logfont, 0, sizeof(logfont));
1614 logfont.lfHeight = 12;
1615 logfont.lfWidth = 12;
1616 logfont.lfWeight = FW_NORMAL;
1617 logfont.lfItalic = 1;
1618 lstrcpyW(logfont.lfFaceName, tahomaW);
1620 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop2, &logfont, &font);
1621 ok(hr == S_OK, "got 0x%08x\n", hr);
1623 IDWriteGdiInterop_Release(interop2);
1624 IDWriteGdiInterop_Release(interop);
1625 IDWriteFactory_Release(factory);
1628 static void test_CreateFontFaceFromHdc(void)
1630 IDWriteGdiInterop *interop;
1631 IDWriteFontFace *fontface;
1632 IDWriteFactory *factory;
1633 HFONT hfont, oldhfont;
1634 LOGFONTW logfont;
1635 HRESULT hr;
1636 HDC hdc;
1638 factory = create_factory();
1640 interop = NULL;
1641 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
1642 ok(hr == S_OK, "got 0x%08x\n", hr);
1644 hr = IDWriteGdiInterop_CreateFontFaceFromHdc(interop, NULL, &fontface);
1645 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1647 memset(&logfont, 0, sizeof(logfont));
1648 logfont.lfHeight = 12;
1649 logfont.lfWidth = 12;
1650 logfont.lfWeight = FW_NORMAL;
1651 logfont.lfItalic = 1;
1652 lstrcpyW(logfont.lfFaceName, tahomaW);
1654 hfont = CreateFontIndirectW(&logfont);
1655 hdc = CreateCompatibleDC(0);
1656 oldhfont = SelectObject(hdc, hfont);
1658 fontface = NULL;
1659 hr = IDWriteGdiInterop_CreateFontFaceFromHdc(interop, hdc, &fontface);
1660 ok(hr == S_OK, "got 0x%08x\n", hr);
1661 IDWriteFontFace_Release(fontface);
1662 DeleteObject(SelectObject(hdc, oldhfont));
1663 DeleteDC(hdc);
1665 IDWriteGdiInterop_Release(interop);
1666 IDWriteFactory_Release(factory);
1669 static void test_GetSimulations(void)
1671 DWRITE_FONT_SIMULATIONS simulations;
1672 IDWriteGdiInterop *interop;
1673 IDWriteFontFace *fontface;
1674 IDWriteFactory *factory;
1675 IDWriteFont *font;
1676 LOGFONTW logfont;
1677 HRESULT hr;
1679 factory = create_factory();
1681 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
1682 ok(hr == S_OK, "got 0x%08x\n", hr);
1684 memset(&logfont, 0, sizeof(logfont));
1685 logfont.lfHeight = 12;
1686 logfont.lfWidth = 12;
1687 logfont.lfWeight = FW_NORMAL;
1688 logfont.lfItalic = 1;
1689 lstrcpyW(logfont.lfFaceName, tahomaW);
1691 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
1692 ok(hr == S_OK, "got 0x%08x\n", hr);
1694 simulations = IDWriteFont_GetSimulations(font);
1695 todo_wine
1696 ok(simulations == DWRITE_FONT_SIMULATIONS_OBLIQUE, "got %d\n", simulations);
1697 hr = IDWriteFont_CreateFontFace(font, &fontface);
1698 ok(hr == S_OK, "got 0x%08x\n", hr);
1699 simulations = IDWriteFontFace_GetSimulations(fontface);
1700 todo_wine
1701 ok(simulations == DWRITE_FONT_SIMULATIONS_OBLIQUE, "got %d\n", simulations);
1702 IDWriteFontFace_Release(fontface);
1703 IDWriteFont_Release(font);
1705 memset(&logfont, 0, sizeof(logfont));
1706 logfont.lfHeight = 12;
1707 logfont.lfWidth = 12;
1708 logfont.lfWeight = FW_NORMAL;
1709 logfont.lfItalic = 0;
1710 lstrcpyW(logfont.lfFaceName, tahomaW);
1712 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
1713 ok(hr == S_OK, "got 0x%08x\n", hr);
1715 simulations = IDWriteFont_GetSimulations(font);
1716 ok(simulations == 0, "got %d\n", simulations);
1717 hr = IDWriteFont_CreateFontFace(font, &fontface);
1718 ok(hr == S_OK, "got 0x%08x\n", hr);
1719 simulations = IDWriteFontFace_GetSimulations(fontface);
1720 ok(simulations == 0, "got %d\n", simulations);
1721 IDWriteFontFace_Release(fontface);
1722 IDWriteFont_Release(font);
1724 IDWriteGdiInterop_Release(interop);
1725 IDWriteFactory_Release(factory);
1728 START_TEST(font)
1730 IDWriteFactory *factory;
1732 if (!(factory = create_factory())) {
1733 win_skip("failed to create factory\n");
1734 return;
1737 test_CreateFontFromLOGFONT();
1738 test_CreateBitmapRenderTarget();
1739 test_GetFontFamily();
1740 test_GetFamilyNames();
1741 test_CreateFontFace();
1742 test_GetMetrics();
1743 test_system_fontcollection();
1744 test_ConvertFontFaceToLOGFONT();
1745 test_CustomFontCollection();
1746 test_CreateCustomFontFileReference();
1747 test_CreateFontFileReference();
1748 test_shared_isolated();
1749 test_GetUnicodeRanges();
1750 test_GetFontFromFontFace();
1751 test_GetFirstMatchingFont();
1752 test_GetInformationalStrings();
1753 test_GetGdiInterop();
1754 test_CreateFontFaceFromHdc();
1755 test_GetSimulations();
1757 IDWriteFactory_Release(factory);