4 * Copyright 2012 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
28 #include "wine/test.h"
30 #define EXPECT_HR(hr,hr_exp) \
31 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
33 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
34 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
36 ULONG rc = IUnknown_AddRef(obj);
37 IUnknown_Release(obj);
38 ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
41 static IDWriteFactory *factory;
43 static const WCHAR tahomaW[] = {'T','a','h','o','m','a',0};
45 static void test_CreateFontFromLOGFONT(void)
47 static const WCHAR tahomaspW[] = {'T','a','h','o','m','a',' ',0};
48 static const WCHAR blahW[] = {'B','l','a','h','!',0};
49 IDWriteGdiInterop *interop;
50 DWRITE_FONT_WEIGHT weight;
51 DWRITE_FONT_STYLE style;
55 {FW_NORMAL, DWRITE_FONT_WEIGHT_NORMAL},
56 {FW_BOLD, DWRITE_FONT_WEIGHT_BOLD},
57 { 0, DWRITE_FONT_WEIGHT_NORMAL},
58 { 50, DWRITE_FONT_WEIGHT_NORMAL},
59 {150, DWRITE_FONT_WEIGHT_NORMAL},
60 {250, DWRITE_FONT_WEIGHT_NORMAL},
61 {350, DWRITE_FONT_WEIGHT_NORMAL},
62 {450, DWRITE_FONT_WEIGHT_NORMAL},
63 {650, DWRITE_FONT_WEIGHT_BOLD},
64 {750, DWRITE_FONT_WEIGHT_BOLD},
65 {850, DWRITE_FONT_WEIGHT_BOLD},
66 {950, DWRITE_FONT_WEIGHT_BOLD},
67 {960, DWRITE_FONT_WEIGHT_BOLD},
69 OUTLINETEXTMETRICW otm;
77 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
81 /* null out parameter crashes this call */
82 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, NULL, NULL);
84 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, NULL, &font);
85 EXPECT_HR(hr, E_INVALIDARG);
87 memset(&logfont, 0, sizeof(logfont));
88 logfont.lfHeight = 12;
90 logfont.lfWeight = FW_NORMAL;
92 lstrcpyW(logfont.lfFaceName, tahomaW);
94 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
97 hfont = CreateFontIndirectW(&logfont);
98 hdc = CreateCompatibleDC(0);
99 SelectObject(hdc, hfont);
101 otm.otmSize = sizeof(otm);
102 r = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
103 ok(r, "got %d\n", r);
107 /* now check properties */
108 weight = IDWriteFont_GetWeight(font);
109 ok(weight == DWRITE_FONT_WEIGHT_NORMAL, "got %d\n", weight);
111 style = IDWriteFont_GetStyle(font);
113 ok(style == DWRITE_FONT_STYLE_OBLIQUE, "got %d\n", style);
114 ok(otm.otmfsSelection == 1, "got 0x%08x\n", otm.otmfsSelection);
116 ret = IDWriteFont_IsSymbolFont(font);
117 ok(!ret, "got %d\n", ret);
119 IDWriteFont_Release(font);
122 for (i = 0; i < sizeof(weights)/(2*sizeof(LONG)); i++)
124 memset(&logfont, 0, sizeof(logfont));
125 logfont.lfHeight = 12;
126 logfont.lfWidth = 12;
127 logfont.lfWeight = weights[i][0];
128 lstrcpyW(logfont.lfFaceName, tahomaW);
130 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
133 weight = IDWriteFont_GetWeight(font);
134 ok(weight == weights[i][1],
135 "%d: got %d, expected %d\n", i, weight, weights[i][1]);
136 IDWriteFont_Release(font);
139 /* weight not from enum */
140 memset(&logfont, 0, sizeof(logfont));
141 logfont.lfHeight = 12;
142 logfont.lfWidth = 12;
143 logfont.lfWeight = 550;
144 lstrcpyW(logfont.lfFaceName, tahomaW);
146 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
149 weight = IDWriteFont_GetWeight(font);
150 ok(weight == DWRITE_FONT_WEIGHT_NORMAL || broken(weight == DWRITE_FONT_WEIGHT_BOLD) /* win7 w/o SP */,
152 IDWriteFont_Release(font);
154 /* empty or nonexistent face name */
155 memset(&logfont, 0, sizeof(logfont));
156 logfont.lfHeight = 12;
157 logfont.lfWidth = 12;
158 logfont.lfWeight = FW_NORMAL;
159 lstrcpyW(logfont.lfFaceName, blahW);
161 font = (void*)0xdeadbeef;
162 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
164 EXPECT_HR(hr, DWRITE_E_NOFONT);
165 ok(font == NULL, "got %p\n", font);
166 if(font) IDWriteFont_Release(font);
169 memset(&logfont, 0, sizeof(logfont));
170 logfont.lfHeight = 12;
171 logfont.lfWidth = 12;
172 logfont.lfWeight = FW_NORMAL;
173 lstrcpyW(logfont.lfFaceName, tahomaspW);
175 font = (void*)0xdeadbeef;
176 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
178 EXPECT_HR(hr, DWRITE_E_NOFONT);
179 ok(font == NULL, "got %p\n", font);
180 if(font) IDWriteFont_Release(font);
183 memset(&logfont, 0, sizeof(logfont));
184 logfont.lfHeight = 12;
185 logfont.lfWidth = 12;
186 logfont.lfWeight = FW_NORMAL;
188 font = (void*)0xdeadbeef;
189 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
191 EXPECT_HR(hr, DWRITE_E_NOFONT);
192 ok(font == NULL, "got %p\n", font);
193 if(font) IDWriteFont_Release(font);
196 IDWriteGdiInterop_Release(interop);
199 static void test_CreateBitmapRenderTarget(void)
201 IDWriteBitmapRenderTarget *target, *target2;
202 IDWriteGdiInterop *interop;
210 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
214 hr = IDWriteGdiInterop_CreateBitmapRenderTarget(interop, NULL, 0, 0, &target);
217 if (0) /* crashes on native */
218 hr = IDWriteBitmapRenderTarget_GetSize(target, NULL);
220 size.cx = size.cy = -1;
221 hr = IDWriteBitmapRenderTarget_GetSize(target, &size);
223 ok(size.cx == 0, "got %d\n", size.cx);
224 ok(size.cy == 0, "got %d\n", size.cy);
227 hr = IDWriteGdiInterop_CreateBitmapRenderTarget(interop, NULL, 0, 0, &target2);
229 ok(target != target2, "got %p, %p\n", target2, target);
230 IDWriteBitmapRenderTarget_Release(target2);
232 hdc = IDWriteBitmapRenderTarget_GetMemoryDC(target);
233 ok(hdc != NULL, "got %p\n", hdc);
235 hbm = GetCurrentObject(hdc, OBJ_BITMAP);
236 ok(hbm != NULL, "got %p\n", hbm);
238 /* check DIB properties */
239 ret = GetObjectW(hbm, sizeof(ds), &ds);
240 ok(ret == sizeof(BITMAP), "got %d\n", ret);
241 ok(ds.dsBm.bmWidth == 1, "got %d\n", ds.dsBm.bmWidth);
242 ok(ds.dsBm.bmHeight == 1, "got %d\n", ds.dsBm.bmHeight);
243 ok(ds.dsBm.bmPlanes == 1, "got %d\n", ds.dsBm.bmPlanes);
244 ok(ds.dsBm.bmBitsPixel == 1, "got %d\n", ds.dsBm.bmBitsPixel);
245 ok(!ds.dsBm.bmBits, "got %p\n", ds.dsBm.bmBits);
247 IDWriteBitmapRenderTarget_Release(target);
249 hbm = GetCurrentObject(hdc, OBJ_BITMAP);
250 ok(!hbm, "got %p\n", hbm);
253 hr = IDWriteGdiInterop_CreateBitmapRenderTarget(interop, NULL, 10, 5, &target);
256 hdc = IDWriteBitmapRenderTarget_GetMemoryDC(target);
257 ok(hdc != NULL, "got %p\n", hdc);
259 hbm = GetCurrentObject(hdc, OBJ_BITMAP);
260 ok(hbm != NULL, "got %p\n", hbm);
262 /* check DIB properties */
263 ret = GetObjectW(hbm, sizeof(ds), &ds);
264 ok(ret == sizeof(ds), "got %d\n", ret);
265 ok(ds.dsBm.bmWidth == 10, "got %d\n", ds.dsBm.bmWidth);
266 ok(ds.dsBm.bmHeight == 5, "got %d\n", ds.dsBm.bmHeight);
267 ok(ds.dsBm.bmPlanes == 1, "got %d\n", ds.dsBm.bmPlanes);
268 ok(ds.dsBm.bmBitsPixel == 32, "got %d\n", ds.dsBm.bmBitsPixel);
269 ok(ds.dsBm.bmBits != NULL, "got %p\n", ds.dsBm.bmBits);
271 size.cx = size.cy = -1;
272 hr = IDWriteBitmapRenderTarget_GetSize(target, &size);
274 ok(size.cx == 10, "got %d\n", size.cx);
275 ok(size.cy == 5, "got %d\n", size.cy);
277 IDWriteBitmapRenderTarget_Release(target);
279 IDWriteGdiInterop_Release(interop);
282 static void test_GetFontFamily(void)
284 IDWriteFontFamily *family, *family2;
285 IDWriteGdiInterop *interop;
290 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
293 memset(&logfont, 0, sizeof(logfont));
294 logfont.lfHeight = 12;
295 logfont.lfWidth = 12;
296 logfont.lfWeight = FW_NORMAL;
297 logfont.lfItalic = 1;
298 lstrcpyW(logfont.lfFaceName, tahomaW);
300 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
303 if (0) /* crashes on native */
304 hr = IDWriteFont_GetFontFamily(font, NULL);
307 hr = IDWriteFont_GetFontFamily(font, &family);
310 EXPECT_REF(family, 2);
312 hr = IDWriteFont_GetFontFamily(font, &family2);
314 ok(family2 == family, "got %p, previous %p\n", family2, family);
316 EXPECT_REF(family, 3);
317 IDWriteFontFamily_Release(family2);
319 hr = IDWriteFont_QueryInterface(font, &IID_IDWriteFontFamily, (void**)&family2);
320 EXPECT_HR(hr, E_NOINTERFACE);
321 ok(family2 == NULL, "got %p\n", family2);
323 IDWriteFontFamily_Release(family);
324 IDWriteFont_Release(font);
325 IDWriteGdiInterop_Release(interop);
328 static void test_GetFamilyNames(void)
330 IDWriteFontFamily *family;
331 IDWriteLocalizedStrings *names, *names2;
332 IDWriteGdiInterop *interop;
339 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
342 memset(&logfont, 0, sizeof(logfont));
343 logfont.lfHeight = 12;
344 logfont.lfWidth = 12;
345 logfont.lfWeight = FW_NORMAL;
346 logfont.lfItalic = 1;
347 lstrcpyW(logfont.lfFaceName, tahomaW);
349 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
352 hr = IDWriteFont_GetFontFamily(font, &family);
355 if (0) /* crashes on native */
356 hr = IDWriteFontFamily_GetFamilyNames(family, NULL);
358 hr = IDWriteFontFamily_GetFamilyNames(family, &names);
359 ok(hr == S_OK, "got 0x%08x\n", hr);
360 EXPECT_REF(names, 1);
362 hr = IDWriteFontFamily_GetFamilyNames(family, &names2);
363 ok(hr == S_OK, "got 0x%08x\n", hr);
364 EXPECT_REF(names2, 1);
365 ok(names != names2, "got %p, was %p\n", names2, names);
367 IDWriteLocalizedStrings_Release(names2);
369 /* GetStringLength */
370 if (0) /* crashes on native */
371 hr = IDWriteLocalizedStrings_GetStringLength(names, 0, NULL);
374 hr = IDWriteLocalizedStrings_GetStringLength(names, 10, &len);
375 ok(hr == E_FAIL, "got 0x%08x\n", hr);
376 ok(len == (UINT32)-1, "got %u\n", len);
379 hr = IDWriteLocalizedStrings_GetStringLength(names, 0, &len);
380 ok(hr == S_OK, "got 0x%08x\n", hr);
381 ok(len > 0, "got %u\n", len);
384 hr = IDWriteLocalizedStrings_GetString(names, 0, NULL, 0);
385 ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
387 hr = IDWriteLocalizedStrings_GetString(names, 10, NULL, 0);
388 ok(hr == E_FAIL, "got 0x%08x\n", hr);
391 hr = IDWriteLocalizedStrings_GetString(names, 0, NULL, 100);
394 hr = IDWriteLocalizedStrings_GetString(names, 10, buffer, 100);
395 ok(hr == E_FAIL, "got 0x%08x\n", hr);
396 ok(buffer[0] == 0, "got %x\n", buffer[0]);
399 hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len-1);
400 ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
401 ok(buffer[0] == 0, "got %x\n", buffer[0]);
404 hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len);
405 ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
406 ok(buffer[0] == 0, "got %x\n", buffer[0]);
409 hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len+1);
410 ok(hr == S_OK, "got 0x%08x\n", hr);
411 ok(buffer[0] != 0, "got %x\n", buffer[0]);
413 IDWriteLocalizedStrings_Release(names);
415 IDWriteFontFamily_Release(family);
416 IDWriteFont_Release(font);
417 IDWriteGdiInterop_Release(interop);
420 static void test_CreateFontFace(void)
422 IDWriteFontFace *fontface, *fontface2;
423 IDWriteGdiInterop *interop;
428 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
431 memset(&logfont, 0, sizeof(logfont));
432 logfont.lfHeight = 12;
433 logfont.lfWidth = 12;
434 logfont.lfWeight = FW_NORMAL;
435 logfont.lfItalic = 1;
436 lstrcpyW(logfont.lfFaceName, tahomaW);
438 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
439 ok(hr == S_OK, "got 0x%08x\n", hr);
441 hr = IDWriteFont_QueryInterface(font, &IID_IDWriteFontFace, (void**)&fontface);
442 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
444 if (0) /* crashes on native */
445 hr = IDWriteFont_CreateFontFace(font, NULL);
447 hr = IDWriteFont_CreateFontFace(font, &fontface);
448 ok(hr == S_OK, "got 0x%08x\n", hr);
450 EXPECT_REF(fontface, 2);
452 hr = IDWriteFont_CreateFontFace(font, &fontface2);
453 ok(hr == S_OK, "got 0x%08x\n", hr);
454 ok(fontface == fontface2, "got %p, was %p\n", fontface2, fontface);
455 EXPECT_REF(fontface, 3);
458 IDWriteFontFace_AddRef(fontface);
460 EXPECT_REF(fontface, 4);
461 IDWriteFontFace_Release(fontface);
462 IDWriteFontFace_Release(fontface);
464 IDWriteFontFace_Release(fontface);
465 IDWriteFont_Release(font);
466 IDWriteGdiInterop_Release(interop);
469 static void test_GetMetrics(void)
471 IDWriteGdiInterop *interop;
472 DWRITE_FONT_METRICS metrics;
473 OUTLINETEXTMETRICW otm;
481 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
484 memset(&logfont, 0, sizeof(logfont));
485 logfont.lfHeight = 12;
486 logfont.lfWidth = 12;
487 logfont.lfWeight = FW_NORMAL;
488 logfont.lfItalic = 1;
489 lstrcpyW(logfont.lfFaceName, tahomaW);
491 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
492 ok(hr == S_OK, "got 0x%08x\n", hr);
494 hfont = CreateFontIndirectW(&logfont);
495 hdc = CreateCompatibleDC(0);
496 SelectObject(hdc, hfont);
498 otm.otmSize = sizeof(otm);
499 ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
500 ok(ret, "got %d\n", ret);
504 if (0) /* crashes on native */
505 IDWriteFont_GetMetrics(font, NULL);
507 memset(&metrics, 0, sizeof(metrics));
508 IDWriteFont_GetMetrics(font, &metrics);
510 ok(metrics.designUnitsPerEm != 0, "designUnitsPerEm %u\n", metrics.designUnitsPerEm);
511 ok(metrics.ascent != 0, "ascent %u\n", metrics.ascent);
512 ok(metrics.descent != 0, "descent %u\n", metrics.descent);
514 ok(metrics.lineGap == 0, "lineGap %d\n", metrics.lineGap);
515 ok(metrics.capHeight, "capHeight %u\n", metrics.capHeight);
516 ok(metrics.xHeight != 0, "xHeight %u\n", metrics.xHeight);
517 ok(metrics.underlinePosition < 0, "underlinePosition %d\n", metrics.underlinePosition);
518 ok(metrics.underlineThickness != 0, "underlineThickness %u\n", metrics.underlineThickness);
519 ok(metrics.strikethroughPosition > 0, "strikethroughPosition %d\n", metrics.strikethroughPosition);
520 ok(metrics.strikethroughThickness != 0, "strikethroughThickness %u\n", metrics.strikethroughThickness);
522 IDWriteFont_Release(font);
523 IDWriteGdiInterop_Release(interop);
530 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, &IID_IDWriteFactory, (IUnknown**)&factory);
531 ok(hr == S_OK, "got 0x%08x\n", hr);
534 win_skip("failed to create factory\n");
538 test_CreateFontFromLOGFONT();
539 test_CreateBitmapRenderTarget();
540 test_GetFontFamily();
541 test_GetFamilyNames();
542 test_CreateFontFace();
545 IDWriteFactory_Release(factory);