4 * Copyright 2012, 2014-2016 Nikolay Sivov for CodeWeavers
5 * Copyright 2014 Aric Stewart for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include "wine/test.h"
35 #define MS_CMAP_TAG DWRITE_MAKE_OPENTYPE_TAG('c','m','a','p')
36 #define MS_VDMX_TAG DWRITE_MAKE_OPENTYPE_TAG('V','D','M','X')
37 #define MS_GASP_TAG DWRITE_MAKE_OPENTYPE_TAG('g','a','s','p')
38 #define MS_CPAL_TAG DWRITE_MAKE_OPENTYPE_TAG('C','P','A','L')
39 #define MS_0S2_TAG DWRITE_MAKE_OPENTYPE_TAG('O','S','/','2')
40 #define MS_HEAD_TAG DWRITE_MAKE_OPENTYPE_TAG('h','e','a','d')
41 #define MS_HHEA_TAG DWRITE_MAKE_OPENTYPE_TAG('h','h','e','a')
42 #define MS_POST_TAG DWRITE_MAKE_OPENTYPE_TAG('p','o','s','t')
43 #define MS_GSUB_TAG DWRITE_MAKE_OPENTYPE_TAG('G','S','U','B')
45 #ifdef WORDS_BIGENDIAN
46 #define GET_BE_WORD(x) (x)
47 #define GET_BE_DWORD(x) (x)
49 #define GET_BE_WORD(x) RtlUshortByteSwap(x)
50 #define GET_BE_DWORD(x) RtlUlongByteSwap(x)
53 #define EXPECT_HR(hr,hr_exp) \
54 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
56 #define DEFINE_EXPECT(func) \
57 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
59 #define SET_EXPECT(func) \
60 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
62 #define CHECK_EXPECT2(func) \
64 ok(expect_ ##func, "unexpected call " #func "\n"); \
65 called_ ## func = TRUE; \
68 #define CHECK_EXPECT(func) \
70 CHECK_EXPECT2(func); \
71 expect_ ## func = FALSE; \
74 #define CHECK_CALLED(func) \
76 ok(called_ ## func, "expected " #func "\n"); \
77 expect_ ## func = called_ ## func = FALSE; \
80 #define CLEAR_CALLED(func) \
81 expect_ ## func = called_ ## func = FALSE
83 DEFINE_EXPECT(setfillmode
);
85 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
86 static void _expect_ref(IUnknown
* obj
, ULONG ref
, int line
)
90 rc
= IUnknown_Release(obj
);
91 ok_(__FILE__
,line
)(rc
== ref
, "expected refcount %d, got %d\n", ref
, rc
);
94 static inline void *heap_alloc(size_t len
)
96 return HeapAlloc(GetProcessHeap(), 0, len
);
99 static inline BOOL
heap_free(void *mem
)
101 return HeapFree(GetProcessHeap(), 0, mem
);
104 static const WCHAR test_fontfile
[] = {'w','i','n','e','_','t','e','s','t','_','f','o','n','t','.','t','t','f',0};
105 static const WCHAR tahomaW
[] = {'T','a','h','o','m','a',0};
106 static const WCHAR arialW
[] = {'A','r','i','a','l',0};
107 static const WCHAR tahomaUppercaseW
[] = {'T','A','H','O','M','A',0};
108 static const WCHAR tahomaStrangecaseW
[] = {'t','A','h','O','m','A',0};
109 static const WCHAR blahW
[] = {'B','l','a','h','!',0};
110 static const WCHAR emojiW
[] = {'S','e','g','o','e',' ','U','I',' ','E','m','o','j','i',0};
112 /* PANOSE is 10 bytes in size, need to pack the structure properly */
113 #include "pshpack2.h"
129 USHORT lowestRecPPEM
;
130 SHORT direction_hint
;
132 SHORT glyphdata_format
;
135 enum TT_HEAD_MACSTYLE
137 TT_HEAD_MACSTYLE_BOLD
= 1 << 0,
138 TT_HEAD_MACSTYLE_ITALIC
= 1 << 1,
139 TT_HEAD_MACSTYLE_UNDERLINE
= 1 << 2,
140 TT_HEAD_MACSTYLE_OUTLINE
= 1 << 3,
141 TT_HEAD_MACSTYLE_SHADOW
= 1 << 4,
142 TT_HEAD_MACSTYLE_CONDENSED
= 1 << 5,
143 TT_HEAD_MACSTYLE_EXTENDED
= 1 << 6,
150 USHORT usWeightClass
;
153 SHORT ySubscriptXSize
;
154 SHORT ySubscriptYSize
;
155 SHORT ySubscriptXOffset
;
156 SHORT ySubscriptYOffset
;
157 SHORT ySuperscriptXSize
;
158 SHORT ySuperscriptYSize
;
159 SHORT ySuperscriptXOffset
;
160 SHORT ySuperscriptYOffset
;
161 SHORT yStrikeoutSize
;
162 SHORT yStrikeoutPosition
;
165 ULONG ulUnicodeRange1
;
166 ULONG ulUnicodeRange2
;
167 ULONG ulUnicodeRange3
;
168 ULONG ulUnicodeRange4
;
171 USHORT usFirstCharIndex
;
172 USHORT usLastCharIndex
;
173 /* According to the Apple spec, original version didn't have the below fields,
174 * version numbers were taken from the OpenType spec.
176 /* version 0 (TrueType 1.5) */
177 USHORT sTypoAscender
;
178 USHORT sTypoDescender
;
182 /* version 1 (TrueType 1.66) */
183 ULONG ulCodePageRange1
;
184 ULONG ulCodePageRange2
;
185 /* version 2 (OpenType 1.2) */
188 USHORT usDefaultChar
;
193 enum OS2_FSSELECTION
{
194 OS2_FSSELECTION_ITALIC
= 1 << 0,
195 OS2_FSSELECTION_UNDERSCORE
= 1 << 1,
196 OS2_FSSELECTION_NEGATIVE
= 1 << 2,
197 OS2_FSSELECTION_OUTLINED
= 1 << 3,
198 OS2_FSSELECTION_STRIKEOUT
= 1 << 4,
199 OS2_FSSELECTION_BOLD
= 1 << 5,
200 OS2_FSSELECTION_REGULAR
= 1 << 6,
201 OS2_FSSELECTION_USE_TYPO_METRICS
= 1 << 7,
202 OS2_FSSELECTION_WWS
= 1 << 8,
203 OS2_FSSELECTION_OBLIQUE
= 1 << 9
209 SHORT underlinePosition
;
210 SHORT underlineThickness
;
223 USHORT advanceWidthMax
;
224 SHORT minLeftSideBearing
;
225 SHORT minRightSideBearing
;
227 SHORT caretSlopeRise
;
231 SHORT metricDataFormat
;
232 USHORT numberOfHMetrics
;
249 OT_FeatureRecord FeatureRecord
[1];
255 WORD LookupListIndex
[1];
274 } GSUB_SingleSubstFormat1
;
281 } GSUB_SingleSubstFormat2
;
285 WORD ExtensionLookupType
;
286 DWORD ExtensionOffset
;
287 } GSUB_ExtensionPosFormat1
;
291 static IDWriteFactory
*create_factory(void)
293 IDWriteFactory
*factory
;
294 HRESULT hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory
);
295 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
299 static IDWriteFontFace
*create_fontface(IDWriteFactory
*factory
)
301 static const WCHAR tahomaW
[] = {'T','a','h','o','m','a',0};
302 IDWriteGdiInterop
*interop
;
303 IDWriteFontFace
*fontface
;
308 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
309 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
311 memset(&logfont
, 0, sizeof(logfont
));
312 logfont
.lfHeight
= 12;
313 logfont
.lfWidth
= 12;
314 logfont
.lfWeight
= FW_NORMAL
;
315 logfont
.lfItalic
= 1;
316 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
318 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
319 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
321 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
322 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
324 IDWriteFont_Release(font
);
325 IDWriteGdiInterop_Release(interop
);
330 static IDWriteFont
*get_font(IDWriteFactory
*factory
, const WCHAR
*name
, DWRITE_FONT_STYLE style
)
332 IDWriteFontCollection
*collection
;
333 IDWriteFontFamily
*family
;
334 IDWriteFont
*font
= NULL
;
339 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
340 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
344 hr
= IDWriteFontCollection_FindFamilyName(collection
, name
, &index
, &exists
);
345 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
346 if (!exists
) goto not_found
;
348 hr
= IDWriteFontCollection_GetFontFamily(collection
, index
, &family
);
349 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
351 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
352 DWRITE_FONT_STRETCH_NORMAL
, style
, &font
);
353 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
355 IDWriteFontFamily_Release(family
);
357 IDWriteFontCollection_Release(collection
);
361 static IDWriteFont
*get_tahoma_instance(IDWriteFactory
*factory
, DWRITE_FONT_STYLE style
)
363 IDWriteFont
*font
= get_font(factory
, tahomaW
, style
);
364 ok(font
!= NULL
, "failed to get Tahoma\n");
368 static WCHAR
*create_testfontfile(const WCHAR
*filename
)
370 static WCHAR pathW
[MAX_PATH
];
376 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
377 lstrcatW(pathW
, filename
);
379 file
= CreateFileW(pathW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
380 ok(file
!= INVALID_HANDLE_VALUE
, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW
),
383 res
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
384 ok( res
!= 0, "couldn't find resource\n" );
385 ptr
= LockResource( LoadResource( GetModuleHandleA(NULL
), res
));
386 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleA(NULL
), res
), &written
, NULL
);
387 ok( written
== SizeofResource( GetModuleHandleA(NULL
), res
), "couldn't write resource\n" );
393 #define DELETE_FONTFILE(filename) _delete_testfontfile(filename, __LINE__)
394 static void _delete_testfontfile(const WCHAR
*filename
, int line
)
396 BOOL ret
= DeleteFileW(filename
);
397 ok_(__FILE__
,line
)(ret
, "failed to delete file %s, error %d\n", wine_dbgstr_w(filename
), GetLastError());
400 struct test_fontenumerator
402 IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface
;
406 IDWriteFontFile
*font_file
;
409 static inline struct test_fontenumerator
*impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator
* iface
)
411 return CONTAINING_RECORD(iface
, struct test_fontenumerator
, IDWriteFontFileEnumerator_iface
);
414 static HRESULT WINAPI
singlefontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
416 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
))
419 IDWriteFontFileEnumerator_AddRef(iface
);
422 return E_NOINTERFACE
;
425 static ULONG WINAPI
singlefontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
427 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
428 return InterlockedIncrement(&This
->ref
);
431 static ULONG WINAPI
singlefontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
433 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
434 ULONG ref
= InterlockedDecrement(&This
->ref
);
436 IDWriteFontFile_Release(This
->font_file
);
442 static HRESULT WINAPI
singlefontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**font_file
)
444 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
445 IDWriteFontFile_AddRef(This
->font_file
);
446 *font_file
= This
->font_file
;
450 static HRESULT WINAPI
singlefontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
452 struct test_fontenumerator
*This
= impl_from_IDWriteFontFileEnumerator(iface
);
454 if (This
->index
> 1) {
464 static const struct IDWriteFontFileEnumeratorVtbl singlefontfileenumeratorvtbl
=
466 singlefontfileenumerator_QueryInterface
,
467 singlefontfileenumerator_AddRef
,
468 singlefontfileenumerator_Release
,
469 singlefontfileenumerator_MoveNext
,
470 singlefontfileenumerator_GetCurrentFontFile
473 static HRESULT
create_enumerator(IDWriteFontFile
*font_file
, IDWriteFontFileEnumerator
**ret
)
475 struct test_fontenumerator
*enumerator
;
477 enumerator
= heap_alloc(sizeof(struct test_fontenumerator
));
479 return E_OUTOFMEMORY
;
481 enumerator
->IDWriteFontFileEnumerator_iface
.lpVtbl
= &singlefontfileenumeratorvtbl
;
483 enumerator
->index
= 0;
484 enumerator
->font_file
= font_file
;
485 IDWriteFontFile_AddRef(font_file
);
487 *ret
= &enumerator
->IDWriteFontFileEnumerator_iface
;
491 struct test_fontcollectionloader
493 IDWriteFontCollectionLoader IDWriteFontFileCollectionLoader_iface
;
494 IDWriteFontFileLoader
*loader
;
497 static inline struct test_fontcollectionloader
*impl_from_IDWriteFontFileCollectionLoader(IDWriteFontCollectionLoader
* iface
)
499 return CONTAINING_RECORD(iface
, struct test_fontcollectionloader
, IDWriteFontFileCollectionLoader_iface
);
502 static HRESULT WINAPI
resourcecollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
504 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontCollectionLoader
))
507 IDWriteFontCollectionLoader_AddRef(iface
);
510 return E_NOINTERFACE
;
513 static ULONG WINAPI
resourcecollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
518 static ULONG WINAPI
resourcecollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
523 static HRESULT WINAPI
resourcecollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
*factory
,
524 const void * collectionKey
, UINT32 collectionKeySize
, IDWriteFontFileEnumerator
** fontFileEnumerator
)
526 struct test_fontcollectionloader
*This
= impl_from_IDWriteFontFileCollectionLoader(iface
);
527 IDWriteFontFile
*font_file
;
530 IDWriteFactory_CreateCustomFontFileReference(factory
, collectionKey
, collectionKeySize
, This
->loader
, &font_file
);
532 hr
= create_enumerator(font_file
, fontFileEnumerator
);
533 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
535 IDWriteFontFile_Release(font_file
);
539 static const struct IDWriteFontCollectionLoaderVtbl resourcecollectionloadervtbl
= {
540 resourcecollectionloader_QueryInterface
,
541 resourcecollectionloader_AddRef
,
542 resourcecollectionloader_Release
,
543 resourcecollectionloader_CreateEnumeratorFromKey
546 /* Here is a functional custom font set of interfaces */
547 struct test_fontdatastream
549 IDWriteFontFileStream IDWriteFontFileStream_iface
;
556 static inline struct test_fontdatastream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
* iface
)
558 return CONTAINING_RECORD(iface
, struct test_fontdatastream
, IDWriteFontFileStream_iface
);
561 static HRESULT WINAPI
fontdatastream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
563 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
566 IDWriteFontFileStream_AddRef(iface
);
570 return E_NOINTERFACE
;
573 static ULONG WINAPI
fontdatastream_AddRef(IDWriteFontFileStream
*iface
)
575 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
576 ULONG ref
= InterlockedIncrement(&This
->ref
);
580 static ULONG WINAPI
fontdatastream_Release(IDWriteFontFileStream
*iface
)
582 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
583 ULONG ref
= InterlockedDecrement(&This
->ref
);
585 HeapFree(GetProcessHeap(), 0, This
);
589 static HRESULT WINAPI
fontdatastream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
591 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
592 *fragment_context
= NULL
;
593 if (offset
+fragment_size
> This
->size
)
595 *fragment_start
= NULL
;
600 *fragment_start
= (BYTE
*)This
->data
+ offset
;
605 static void WINAPI
fontdatastream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
610 static HRESULT WINAPI
fontdatastream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
612 struct test_fontdatastream
*This
= impl_from_IDWriteFontFileStream(iface
);
617 static HRESULT WINAPI
fontdatastream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
622 static const IDWriteFontFileStreamVtbl fontdatastreamvtbl
=
624 fontdatastream_QueryInterface
,
625 fontdatastream_AddRef
,
626 fontdatastream_Release
,
627 fontdatastream_ReadFileFragment
,
628 fontdatastream_ReleaseFileFragment
,
629 fontdatastream_GetFileSize
,
630 fontdatastream_GetLastWriteTime
633 static HRESULT
create_fontdatastream(LPVOID data
, UINT size
, IDWriteFontFileStream
** iface
)
635 struct test_fontdatastream
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct test_fontdatastream
));
637 return E_OUTOFMEMORY
;
642 This
->IDWriteFontFileStream_iface
.lpVtbl
= &fontdatastreamvtbl
;
644 *iface
= &This
->IDWriteFontFileStream_iface
;
648 static HRESULT WINAPI
resourcefontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
650 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
656 return E_NOINTERFACE
;
659 static ULONG WINAPI
resourcefontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
664 static ULONG WINAPI
resourcefontfileloader_Release(IDWriteFontFileLoader
*iface
)
669 static HRESULT WINAPI
resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *ref_key
, UINT32 key_size
,
670 IDWriteFontFileStream
**stream
)
676 mem
= LoadResource(GetModuleHandleA(NULL
), *(HRSRC
*)ref_key
);
677 ok(mem
!= NULL
, "Failed to lock font resource\n");
680 size
= SizeofResource(GetModuleHandleA(NULL
), *(HRSRC
*)ref_key
);
681 data
= LockResource(mem
);
682 return create_fontdatastream(data
, size
, stream
);
687 static const struct IDWriteFontFileLoaderVtbl resourcefontfileloadervtbl
= {
688 resourcefontfileloader_QueryInterface
,
689 resourcefontfileloader_AddRef
,
690 resourcefontfileloader_Release
,
691 resourcefontfileloader_CreateStreamFromKey
694 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
696 static D2D1_POINT_2F g_startpoints
[2];
697 static int g_startpoint_count
;
699 static HRESULT WINAPI
test_geometrysink_QueryInterface(ID2D1SimplifiedGeometrySink
*iface
, REFIID riid
, void **ret
)
701 if (IsEqualIID(riid
, &IID_ID2D1SimplifiedGeometrySink
) ||
702 IsEqualIID(riid
, &IID_IUnknown
))
705 ID2D1SimplifiedGeometrySink_AddRef(iface
);
710 return E_NOINTERFACE
;
713 static ULONG WINAPI
test_geometrysink_AddRef(ID2D1SimplifiedGeometrySink
*iface
)
718 static ULONG WINAPI
test_geometrysink_Release(ID2D1SimplifiedGeometrySink
*iface
)
723 static void WINAPI
test_geometrysink_SetFillMode(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FILL_MODE mode
)
725 CHECK_EXPECT(setfillmode
);
726 ok(mode
== D2D1_FILL_MODE_WINDING
, "fill mode %d\n", mode
);
729 static void WINAPI
test_geometrysink_SetSegmentFlags(ID2D1SimplifiedGeometrySink
*iface
, D2D1_PATH_SEGMENT flags
)
731 ok(0, "unexpected SetSegmentFlags() - flags %d\n", flags
);
734 static void WINAPI
test_geometrysink_BeginFigure(ID2D1SimplifiedGeometrySink
*iface
,
735 D2D1_POINT_2F startPoint
, D2D1_FIGURE_BEGIN figureBegin
)
737 ok(figureBegin
== D2D1_FIGURE_BEGIN_FILLED
, "begin figure %d\n", figureBegin
);
738 if (g_startpoint_count
< sizeof(g_startpoints
)/sizeof(g_startpoints
[0]))
739 g_startpoints
[g_startpoint_count
] = startPoint
;
740 g_startpoint_count
++;
743 static void WINAPI
test_geometrysink_AddLines(ID2D1SimplifiedGeometrySink
*iface
,
744 const D2D1_POINT_2F
*points
, UINT32 count
)
748 static void WINAPI
test_geometrysink_AddBeziers(ID2D1SimplifiedGeometrySink
*iface
,
749 const D2D1_BEZIER_SEGMENT
*beziers
, UINT32 count
)
753 static void WINAPI
test_geometrysink_EndFigure(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FIGURE_END figureEnd
)
755 ok(figureEnd
== D2D1_FIGURE_END_CLOSED
, "end figure %d\n", figureEnd
);
758 static HRESULT WINAPI
test_geometrysink_Close(ID2D1SimplifiedGeometrySink
*iface
)
760 ok(0, "unexpected Close()\n");
764 static const ID2D1SimplifiedGeometrySinkVtbl test_geometrysink_vtbl
= {
765 test_geometrysink_QueryInterface
,
766 test_geometrysink_AddRef
,
767 test_geometrysink_Release
,
768 test_geometrysink_SetFillMode
,
769 test_geometrysink_SetSegmentFlags
,
770 test_geometrysink_BeginFigure
,
771 test_geometrysink_AddLines
,
772 test_geometrysink_AddBeziers
,
773 test_geometrysink_EndFigure
,
774 test_geometrysink_Close
777 static void WINAPI
test_geometrysink2_BeginFigure(ID2D1SimplifiedGeometrySink
*iface
,
778 D2D1_POINT_2F startPoint
, D2D1_FIGURE_BEGIN figureBegin
)
780 ok(0, "unexpected call\n");
783 static void WINAPI
test_geometrysink2_AddLines(ID2D1SimplifiedGeometrySink
*iface
,
784 const D2D1_POINT_2F
*points
, UINT32 count
)
786 ok(0, "unexpected call\n");
789 static void WINAPI
test_geometrysink2_AddBeziers(ID2D1SimplifiedGeometrySink
*iface
,
790 const D2D1_BEZIER_SEGMENT
*beziers
, UINT32 count
)
792 ok(0, "unexpected call\n");
795 static void WINAPI
test_geometrysink2_EndFigure(ID2D1SimplifiedGeometrySink
*iface
, D2D1_FIGURE_END figureEnd
)
797 ok(0, "unexpected call\n");
800 static const ID2D1SimplifiedGeometrySinkVtbl test_geometrysink2_vtbl
= {
801 test_geometrysink_QueryInterface
,
802 test_geometrysink_AddRef
,
803 test_geometrysink_Release
,
804 test_geometrysink_SetFillMode
,
805 test_geometrysink_SetSegmentFlags
,
806 test_geometrysink2_BeginFigure
,
807 test_geometrysink2_AddLines
,
808 test_geometrysink2_AddBeziers
,
809 test_geometrysink2_EndFigure
,
810 test_geometrysink_Close
813 static ID2D1SimplifiedGeometrySink test_geomsink
= { &test_geometrysink_vtbl
};
814 static ID2D1SimplifiedGeometrySink test_geomsink2
= { &test_geometrysink2_vtbl
};
816 static void test_CreateFontFromLOGFONT(void)
818 static const WCHAR tahomaspW
[] = {'T','a','h','o','m','a',' ',0};
819 IDWriteGdiInterop1
*interop1
;
820 IDWriteGdiInterop
*interop
;
821 DWRITE_FONT_WEIGHT weight
;
822 DWRITE_FONT_STYLE style
;
825 LONG weights
[][2] = {
826 {FW_NORMAL
, DWRITE_FONT_WEIGHT_NORMAL
},
827 {FW_BOLD
, DWRITE_FONT_WEIGHT_BOLD
},
828 { 0, DWRITE_FONT_WEIGHT_NORMAL
},
829 { 50, DWRITE_FONT_WEIGHT_NORMAL
},
830 {150, DWRITE_FONT_WEIGHT_NORMAL
},
831 {250, DWRITE_FONT_WEIGHT_NORMAL
},
832 {350, DWRITE_FONT_WEIGHT_NORMAL
},
833 {450, DWRITE_FONT_WEIGHT_NORMAL
},
834 {650, DWRITE_FONT_WEIGHT_BOLD
},
835 {750, DWRITE_FONT_WEIGHT_BOLD
},
836 {850, DWRITE_FONT_WEIGHT_BOLD
},
837 {950, DWRITE_FONT_WEIGHT_BOLD
},
838 {960, DWRITE_FONT_WEIGHT_BOLD
},
840 OUTLINETEXTMETRICW otm
;
841 IDWriteFactory
*factory
;
850 factory
= create_factory();
852 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
856 /* null out parameter crashes this call */
857 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, NULL
);
859 font
= (void*)0xdeadbeef;
860 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, NULL
, &font
);
861 EXPECT_HR(hr
, E_INVALIDARG
);
862 ok(font
== NULL
, "got %p\n", font
);
864 memset(&logfont
, 0, sizeof(logfont
));
865 logfont
.lfHeight
= 12;
866 logfont
.lfWidth
= 12;
867 logfont
.lfWeight
= FW_NORMAL
;
868 logfont
.lfItalic
= 1;
869 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
871 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
874 hfont
= CreateFontIndirectW(&logfont
);
875 hdc
= CreateCompatibleDC(0);
876 SelectObject(hdc
, hfont
);
878 otm
.otmSize
= sizeof(otm
);
879 r
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
880 ok(r
, "got %d\n", r
);
885 hr
= IDWriteFont_HasCharacter(font
, 0xd800, &exists
);
886 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
887 ok(exists
== FALSE
, "got %d\n", exists
);
890 hr
= IDWriteFont_HasCharacter(font
, 0x20, &exists
);
891 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
892 ok(exists
== TRUE
, "got %d\n", exists
);
894 /* now check properties */
895 weight
= IDWriteFont_GetWeight(font
);
896 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
, "got %d\n", weight
);
898 style
= IDWriteFont_GetStyle(font
);
899 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %d\n", style
);
900 ok(otm
.otmfsSelection
& 1, "got 0x%08x\n", otm
.otmfsSelection
);
902 ret
= IDWriteFont_IsSymbolFont(font
);
903 ok(!ret
, "got %d\n", ret
);
905 IDWriteFont_Release(font
);
908 for (i
= 0; i
< sizeof(weights
)/(2*sizeof(LONG
)); i
++)
910 memset(&logfont
, 0, sizeof(logfont
));
911 logfont
.lfHeight
= 12;
912 logfont
.lfWidth
= 12;
913 logfont
.lfWeight
= weights
[i
][0];
914 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
916 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
919 weight
= IDWriteFont_GetWeight(font
);
920 ok(weight
== weights
[i
][1],
921 "%d: got %d, expected %d\n", i
, weight
, weights
[i
][1]);
923 IDWriteFont_Release(font
);
926 /* weight not from enum */
927 memset(&logfont
, 0, sizeof(logfont
));
928 logfont
.lfHeight
= 12;
929 logfont
.lfWidth
= 12;
930 logfont
.lfWeight
= 550;
931 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
934 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
935 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
937 weight
= IDWriteFont_GetWeight(font
);
938 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
|| weight
== DWRITE_FONT_WEIGHT_BOLD
,
940 IDWriteFont_Release(font
);
942 /* empty or nonexistent face name */
943 memset(&logfont
, 0, sizeof(logfont
));
944 logfont
.lfHeight
= 12;
945 logfont
.lfWidth
= 12;
946 logfont
.lfWeight
= FW_NORMAL
;
947 lstrcpyW(logfont
.lfFaceName
, blahW
);
949 font
= (void*)0xdeadbeef;
950 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
951 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
952 ok(font
== NULL
, "got %p\n", font
);
954 /* Try with name 'Tahoma ' */
955 memset(&logfont
, 0, sizeof(logfont
));
956 logfont
.lfHeight
= 12;
957 logfont
.lfWidth
= 12;
958 logfont
.lfWeight
= FW_NORMAL
;
959 lstrcpyW(logfont
.lfFaceName
, tahomaspW
);
961 font
= (void*)0xdeadbeef;
962 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
963 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
964 ok(font
== NULL
, "got %p\n", font
);
966 /* empty string as a facename */
967 memset(&logfont
, 0, sizeof(logfont
));
968 logfont
.lfHeight
= 12;
969 logfont
.lfWidth
= 12;
970 logfont
.lfWeight
= FW_NORMAL
;
972 font
= (void*)0xdeadbeef;
973 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
974 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
975 ok(font
== NULL
, "got %p\n", font
);
977 /* IDWriteGdiInterop1::CreateFontFromLOGFONT() */
978 hr
= IDWriteGdiInterop_QueryInterface(interop
, &IID_IDWriteGdiInterop1
, (void**)&interop1
);
980 memset(&logfont
, 0, sizeof(logfont
));
981 logfont
.lfHeight
= 12;
982 logfont
.lfWidth
= 12;
983 logfont
.lfWeight
= FW_NORMAL
;
984 logfont
.lfItalic
= 1;
985 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
987 hr
= IDWriteGdiInterop1_CreateFontFromLOGFONT(interop1
, &logfont
, NULL
, &font
);
988 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
990 IDWriteFont_Release(font
);
991 IDWriteGdiInterop1_Release(interop1
);
994 win_skip("IDWriteGdiInterop1 is not supported, skipping CreateFontFromLOGFONT() tests.\n");
996 IDWriteGdiInterop_Release(interop
);
997 IDWriteFactory_Release(factory
);
1000 static void test_CreateBitmapRenderTarget(void)
1002 IDWriteBitmapRenderTarget
*target
, *target2
;
1003 IDWriteBitmapRenderTarget1
*target1
;
1004 IDWriteGdiInterop
*interop
;
1005 IDWriteFactory
*factory
;
1017 factory
= create_factory();
1019 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1020 EXPECT_HR(hr
, S_OK
);
1023 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target
);
1024 EXPECT_HR(hr
, S_OK
);
1026 if (0) /* crashes on native */
1027 hr
= IDWriteBitmapRenderTarget_GetSize(target
, NULL
);
1029 size
.cx
= size
.cy
= -1;
1030 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
1031 EXPECT_HR(hr
, S_OK
);
1032 ok(size
.cx
== 0, "got %d\n", size
.cx
);
1033 ok(size
.cy
== 0, "got %d\n", size
.cy
);
1036 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 0, 0, &target2
);
1037 EXPECT_HR(hr
, S_OK
);
1038 ok(target
!= target2
, "got %p, %p\n", target2
, target
);
1039 IDWriteBitmapRenderTarget_Release(target2
);
1041 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
1042 ok(hdc
!= NULL
, "got %p\n", hdc
);
1045 ret
= GetGraphicsMode(hdc
);
1046 ok(ret
== GM_ADVANCED
, "got %d\n", ret
);
1048 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
1049 ok(hbm
!= NULL
, "got %p\n", hbm
);
1051 /* check DIB properties */
1052 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
1053 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
1054 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
1055 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
1056 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
1057 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
1058 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
1060 IDWriteBitmapRenderTarget_Release(target
);
1062 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
1063 ok(!hbm
, "got %p\n", hbm
);
1066 hr
= IDWriteGdiInterop_CreateBitmapRenderTarget(interop
, NULL
, 10, 5, &target
);
1067 EXPECT_HR(hr
, S_OK
);
1069 hdc
= IDWriteBitmapRenderTarget_GetMemoryDC(target
);
1070 ok(hdc
!= NULL
, "got %p\n", hdc
);
1072 /* test context settings */
1073 c
= GetTextColor(hdc
);
1074 ok(c
== RGB(0, 0, 0), "got 0x%08x\n", c
);
1075 ret
= GetBkMode(hdc
);
1076 ok(ret
== OPAQUE
, "got %d\n", ret
);
1077 c
= GetBkColor(hdc
);
1078 ok(c
== RGB(255, 255, 255), "got 0x%08x\n", c
);
1080 hbm
= GetCurrentObject(hdc
, OBJ_BITMAP
);
1081 ok(hbm
!= NULL
, "got %p\n", hbm
);
1083 /* check DIB properties */
1084 ret
= GetObjectW(hbm
, sizeof(ds
), &ds
);
1085 ok(ret
== sizeof(ds
), "got %d\n", ret
);
1086 ok(ds
.dsBm
.bmWidth
== 10, "got %d\n", ds
.dsBm
.bmWidth
);
1087 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
1088 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
1089 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
1090 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
1092 size
.cx
= size
.cy
= -1;
1093 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
1094 EXPECT_HR(hr
, S_OK
);
1095 ok(size
.cx
== 10, "got %d\n", size
.cx
);
1096 ok(size
.cy
== 5, "got %d\n", size
.cy
);
1098 /* resize to same size */
1099 hr
= IDWriteBitmapRenderTarget_Resize(target
, 10, 5);
1100 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1102 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
1103 ok(hbm2
== hbm
, "got %p, %p\n", hbm2
, hbm
);
1106 hr
= IDWriteBitmapRenderTarget_Resize(target
, 5, 5);
1107 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1109 size
.cx
= size
.cy
= -1;
1110 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
1111 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1112 ok(size
.cx
== 5, "got %d\n", size
.cx
);
1113 ok(size
.cy
== 5, "got %d\n", size
.cy
);
1115 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
1116 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
1118 hr
= IDWriteBitmapRenderTarget_Resize(target
, 20, 5);
1119 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1121 size
.cx
= size
.cy
= -1;
1122 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
1123 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1124 ok(size
.cx
== 20, "got %d\n", size
.cx
);
1125 ok(size
.cy
== 5, "got %d\n", size
.cy
);
1127 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
1128 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
1130 hr
= IDWriteBitmapRenderTarget_Resize(target
, 1, 5);
1131 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1133 size
.cx
= size
.cy
= -1;
1134 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
1135 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1136 ok(size
.cx
== 1, "got %d\n", size
.cx
);
1137 ok(size
.cy
== 5, "got %d\n", size
.cy
);
1139 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
1140 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
1142 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
1143 ok(ret
== sizeof(ds
), "got %d\n", ret
);
1144 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
1145 ok(ds
.dsBm
.bmHeight
== 5, "got %d\n", ds
.dsBm
.bmHeight
);
1146 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
1147 ok(ds
.dsBm
.bmBitsPixel
== 32, "got %d\n", ds
.dsBm
.bmBitsPixel
);
1148 ok(ds
.dsBm
.bmBits
!= NULL
, "got %p\n", ds
.dsBm
.bmBits
);
1150 /* empty rectangle */
1151 hr
= IDWriteBitmapRenderTarget_Resize(target
, 0, 5);
1152 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1154 size
.cx
= size
.cy
= -1;
1155 hr
= IDWriteBitmapRenderTarget_GetSize(target
, &size
);
1156 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1157 ok(size
.cx
== 0, "got %d\n", size
.cx
);
1158 ok(size
.cy
== 5, "got %d\n", size
.cy
);
1160 hbm2
= GetCurrentObject(hdc
, OBJ_BITMAP
);
1161 ok(hbm2
!= hbm
, "got %p, %p\n", hbm2
, hbm
);
1163 ret
= GetObjectW(hbm2
, sizeof(ds
), &ds
);
1164 ok(ret
== sizeof(BITMAP
), "got %d\n", ret
);
1165 ok(ds
.dsBm
.bmWidth
== 1, "got %d\n", ds
.dsBm
.bmWidth
);
1166 ok(ds
.dsBm
.bmHeight
== 1, "got %d\n", ds
.dsBm
.bmHeight
);
1167 ok(ds
.dsBm
.bmPlanes
== 1, "got %d\n", ds
.dsBm
.bmPlanes
);
1168 ok(ds
.dsBm
.bmBitsPixel
== 1, "got %d\n", ds
.dsBm
.bmBitsPixel
);
1169 ok(!ds
.dsBm
.bmBits
, "got %p\n", ds
.dsBm
.bmBits
);
1171 /* transform tests, current hdc transform is not immediately affected */
1172 if (0) /* crashes on native */
1173 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, NULL
);
1175 memset(&m
, 0xcc, sizeof(m
));
1176 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
1177 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1178 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
);
1179 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
1180 ret
= GetWorldTransform(hdc
, &xform
);
1181 ok(ret
, "got %d\n", ret
);
1182 ok(xform
.eM11
== 1.0 && xform
.eM22
== 1.0 && xform
.eM12
== 0.0 && xform
.eM21
== 0.0, "got wrong transform\n");
1183 ok(xform
.eDx
== 0.0 && xform
.eDy
== 0.0, "got %.1f,%.1f\n", xform
.eDx
, xform
.eDy
);
1185 memset(&m
, 0, sizeof(m
));
1186 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, &m
);
1187 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1189 memset(&m
, 0xcc, sizeof(m
));
1190 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
1191 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1192 ok(m
.m11
== 0.0 && m
.m22
== 0.0 && m
.m12
== 0.0 && m
.m21
== 0.0, "got %.1f,%.1f,%.1f,%.1f\n", m
.m11
, m
.m22
, m
.m12
, m
.m21
);
1193 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
1194 ret
= GetWorldTransform(hdc
, &xform
);
1195 ok(ret
, "got %d\n", ret
);
1196 ok(xform
.eM11
== 1.0 && xform
.eM22
== 1.0 && xform
.eM12
== 0.0 && xform
.eM21
== 0.0, "got wrong transform\n");
1197 ok(xform
.eDx
== 0.0 && xform
.eDy
== 0.0, "got %.1f,%.1f\n", xform
.eDx
, xform
.eDy
);
1199 memset(&m
, 0, sizeof(m
));
1200 m
.m11
= 2.0; m
.m22
= 1.0;
1201 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, &m
);
1202 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1203 ret
= GetWorldTransform(hdc
, &xform
);
1204 ok(ret
, "got %d\n", ret
);
1205 ok(xform
.eM11
== 1.0 && xform
.eM22
== 1.0 && xform
.eM12
== 0.0 && xform
.eM21
== 0.0, "got wrong transform\n");
1206 ok(xform
.eDx
== 0.0 && xform
.eDy
== 0.0, "got %.1f,%.1f\n", xform
.eDx
, xform
.eDy
);
1208 hr
= IDWriteBitmapRenderTarget_SetCurrentTransform(target
, NULL
);
1209 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1211 memset(&m
, 0xcc, sizeof(m
));
1212 hr
= IDWriteBitmapRenderTarget_GetCurrentTransform(target
, &m
);
1213 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1214 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
);
1215 ok(m
.dx
== 0.0 && m
.dy
== 0.0, "got %.1f,%.1f\n", m
.dx
, m
.dy
);
1217 /* pixels per dip */
1218 pdip
= IDWriteBitmapRenderTarget_GetPixelsPerDip(target
);
1219 ok(pdip
== 1.0, "got %.2f\n", pdip
);
1221 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, 2.0);
1222 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1224 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, -1.0);
1225 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1227 hr
= IDWriteBitmapRenderTarget_SetPixelsPerDip(target
, 0.0);
1228 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1230 pdip
= IDWriteBitmapRenderTarget_GetPixelsPerDip(target
);
1231 ok(pdip
== 2.0, "got %.2f\n", pdip
);
1233 hr
= IDWriteBitmapRenderTarget_QueryInterface(target
, &IID_IDWriteBitmapRenderTarget1
, (void**)&target1
);
1235 DWRITE_TEXT_ANTIALIAS_MODE mode
;
1237 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
1238 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, "got %d\n", mode
);
1240 hr
= IDWriteBitmapRenderTarget1_SetTextAntialiasMode(target1
, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
+1);
1241 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1243 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
1244 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, "got %d\n", mode
);
1246 hr
= IDWriteBitmapRenderTarget1_SetTextAntialiasMode(target1
, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
);
1247 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1249 mode
= IDWriteBitmapRenderTarget1_GetTextAntialiasMode(target1
);
1250 ok(mode
== DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
, "got %d\n", mode
);
1252 IDWriteBitmapRenderTarget1_Release(target1
);
1255 win_skip("IDWriteBitmapRenderTarget1 is not supported.\n");
1257 IDWriteBitmapRenderTarget_Release(target
);
1258 IDWriteGdiInterop_Release(interop
);
1259 IDWriteFactory_Release(factory
);
1262 static void test_GetFontFamily(void)
1264 IDWriteFontCollection
*collection
, *collection2
;
1265 IDWriteFontCollection
*syscoll
;
1266 IDWriteFontFamily
*family
, *family2
;
1267 IDWriteFontFamily1
*family1
;
1268 IDWriteGdiInterop
*interop
;
1269 IDWriteFont
*font
, *font2
;
1270 IDWriteFactory
*factory
;
1274 factory
= create_factory();
1276 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1277 EXPECT_HR(hr
, S_OK
);
1279 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &syscoll
, FALSE
);
1280 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1282 memset(&logfont
, 0, sizeof(logfont
));
1283 logfont
.lfHeight
= 12;
1284 logfont
.lfWidth
= 12;
1285 logfont
.lfWeight
= FW_NORMAL
;
1286 logfont
.lfItalic
= 1;
1287 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1289 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1290 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1292 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
1293 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1294 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
1296 if (0) /* crashes on native */
1297 hr
= IDWriteFont_GetFontFamily(font
, NULL
);
1299 EXPECT_REF(font
, 1);
1300 hr
= IDWriteFont_GetFontFamily(font
, &family
);
1301 EXPECT_HR(hr
, S_OK
);
1302 EXPECT_REF(font
, 1);
1303 EXPECT_REF(family
, 2);
1305 hr
= IDWriteFont_GetFontFamily(font
, &family2
);
1306 EXPECT_HR(hr
, S_OK
);
1307 ok(family2
== family
, "got %p, previous %p\n", family2
, family
);
1308 EXPECT_REF(font
, 1);
1309 EXPECT_REF(family
, 3);
1310 IDWriteFontFamily_Release(family2
);
1312 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFamily
, (void**)&family2
);
1313 EXPECT_HR(hr
, E_NOINTERFACE
);
1314 ok(family2
== NULL
, "got %p\n", family2
);
1316 hr
= IDWriteFont_GetFontFamily(font2
, &family2
);
1317 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1318 ok(family2
!= family
, "got %p, %p\n", family2
, family
);
1321 hr
= IDWriteFontFamily_GetFontCollection(family
, &collection
);
1322 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1325 hr
= IDWriteFontFamily_GetFontCollection(family2
, &collection2
);
1326 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1327 ok(collection
== collection2
, "got %p, %p\n", collection
, collection2
);
1328 ok(collection
== syscoll
, "got %p, %p\n", collection
, syscoll
);
1330 IDWriteFont_Release(font
);
1331 IDWriteFont_Release(font2
);
1333 hr
= IDWriteFontFamily_QueryInterface(family
, &IID_IDWriteFontFamily1
, (void**)&family1
);
1335 IDWriteFontFaceReference
*ref
, *ref1
;
1336 IDWriteFontList
*fontlist
;
1337 IDWriteFont3
*font3
;
1338 IDWriteFont1
*font1
;
1340 font3
= (void*)0xdeadbeef;
1341 hr
= IDWriteFontFamily1_GetFont(family1
, ~0u, &font3
);
1342 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1343 ok(font3
== NULL
, "got %p\n", font3
);
1345 hr
= IDWriteFontFamily1_GetFont(family1
, 0, &font3
);
1346 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1348 hr
= IDWriteFont3_QueryInterface(font3
, &IID_IDWriteFont
, (void**)&font
);
1349 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1350 IDWriteFont_Release(font
);
1352 hr
= IDWriteFont3_QueryInterface(font3
, &IID_IDWriteFont1
, (void**)&font1
);
1353 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1354 IDWriteFont1_Release(font1
);
1356 hr
= IDWriteFontFamily1_QueryInterface(family1
, &IID_IDWriteFontList1
, (void**)&fontlist
);
1357 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1359 hr
= IDWriteFontFamily1_QueryInterface(family1
, &IID_IDWriteFontList
, (void**)&fontlist
);
1360 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1361 IDWriteFontList_Release(fontlist
);
1363 IDWriteFont3_Release(font3
);
1365 hr
= IDWriteFontFamily1_GetFontFaceReference(family1
, 0, &ref
);
1366 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1368 hr
= IDWriteFontFamily1_GetFontFaceReference(family1
, 0, &ref1
);
1369 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1370 ok(ref
!= ref1
, "got %p, %p\n", ref
, ref1
);
1372 IDWriteFontFaceReference_Release(ref
);
1373 IDWriteFontFaceReference_Release(ref1
);
1375 IDWriteFontFamily1_Release(family1
);
1378 win_skip("IDWriteFontFamily1 is not supported.\n");
1380 IDWriteFontCollection_Release(syscoll
);
1381 IDWriteFontCollection_Release(collection2
);
1382 IDWriteFontCollection_Release(collection
);
1383 IDWriteFontFamily_Release(family2
);
1384 IDWriteFontFamily_Release(family
);
1385 IDWriteGdiInterop_Release(interop
);
1386 IDWriteFactory_Release(factory
);
1389 static void test_GetFamilyNames(void)
1391 IDWriteFontFamily
*family
;
1392 IDWriteLocalizedStrings
*names
, *names2
;
1393 IDWriteGdiInterop
*interop
;
1394 IDWriteFactory
*factory
;
1401 factory
= create_factory();
1403 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1404 EXPECT_HR(hr
, S_OK
);
1406 memset(&logfont
, 0, sizeof(logfont
));
1407 logfont
.lfHeight
= 12;
1408 logfont
.lfWidth
= 12;
1409 logfont
.lfWeight
= FW_NORMAL
;
1410 logfont
.lfItalic
= 1;
1411 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1413 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1414 EXPECT_HR(hr
, S_OK
);
1416 hr
= IDWriteFont_GetFontFamily(font
, &family
);
1417 EXPECT_HR(hr
, S_OK
);
1419 if (0) /* crashes on native */
1420 hr
= IDWriteFontFamily_GetFamilyNames(family
, NULL
);
1422 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
1423 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1424 EXPECT_REF(names
, 1);
1426 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names2
);
1427 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1428 EXPECT_REF(names2
, 1);
1429 ok(names
!= names2
, "got %p, was %p\n", names2
, names
);
1431 IDWriteLocalizedStrings_Release(names2
);
1433 /* GetStringLength */
1434 if (0) /* crashes on native */
1435 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, NULL
);
1438 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 10, &len
);
1439 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1440 ok(len
== (UINT32
)-1, "got %u\n", len
);
1443 hr
= IDWriteLocalizedStrings_GetStringLength(names
, 0, &len
);
1444 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1445 ok(len
> 0, "got %u\n", len
);
1448 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 0);
1449 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1451 hr
= IDWriteLocalizedStrings_GetString(names
, 10, NULL
, 0);
1452 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1455 hr
= IDWriteLocalizedStrings_GetString(names
, 0, NULL
, 100);
1458 hr
= IDWriteLocalizedStrings_GetString(names
, 10, buffer
, 100);
1459 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
1460 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1463 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
-1);
1464 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1465 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1468 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
);
1469 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1470 ok(buffer
[0] == 0, "got %x\n", buffer
[0]);
1473 hr
= IDWriteLocalizedStrings_GetString(names
, 0, buffer
, len
+1);
1474 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1475 ok(buffer
[0] != 0, "got %x\n", buffer
[0]);
1477 IDWriteLocalizedStrings_Release(names
);
1479 IDWriteFontFamily_Release(family
);
1480 IDWriteFont_Release(font
);
1481 IDWriteGdiInterop_Release(interop
);
1482 IDWriteFactory_Release(factory
);
1485 static void test_CreateFontFace(void)
1487 IDWriteFontFace
*fontface
, *fontface2
;
1488 IDWriteFontCollection
*collection
;
1489 DWRITE_FONT_FILE_TYPE file_type
;
1490 DWRITE_FONT_FACE_TYPE face_type
;
1491 IDWriteGdiInterop
*interop
;
1492 IDWriteFont
*font
, *font2
;
1493 IDWriteFontFamily
*family
;
1494 IDWriteFactory
*factory
;
1495 IDWriteFontFile
*file
;
1502 factory
= create_factory();
1504 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1505 EXPECT_HR(hr
, S_OK
);
1507 memset(&logfont
, 0, sizeof(logfont
));
1508 logfont
.lfHeight
= 12;
1509 logfont
.lfWidth
= 12;
1510 logfont
.lfWeight
= FW_NORMAL
;
1511 logfont
.lfItalic
= 1;
1512 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1515 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1516 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1519 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font2
);
1520 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1521 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1523 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFontFace
, (void**)&fontface
);
1524 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1526 if (0) /* crashes on native */
1527 hr
= IDWriteFont_CreateFontFace(font
, NULL
);
1530 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1531 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1534 hr
= IDWriteFont_CreateFontFace(font
, &fontface2
);
1535 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1536 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1537 IDWriteFontFace_Release(fontface2
);
1540 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
1541 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1542 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1543 IDWriteFontFace_Release(fontface2
);
1545 IDWriteFont_Release(font2
);
1546 IDWriteFont_Release(font
);
1548 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFont
, (void**)&font
);
1549 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_NOTIMPL
), "got 0x%08x\n", hr
);
1551 IDWriteFontFace_Release(fontface
);
1552 IDWriteGdiInterop_Release(interop
);
1554 /* Create from system collection */
1555 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
1556 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1558 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
1559 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1562 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1563 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
1564 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1567 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
1568 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font2
);
1569 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1570 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1573 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1574 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1577 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
1578 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1579 ok(fontface
== fontface2
, "got %p, was %p\n", fontface2
, fontface
);
1581 IDWriteFontFace_Release(fontface
);
1582 IDWriteFontFace_Release(fontface2
);
1583 IDWriteFont_Release(font2
);
1584 IDWriteFont_Release(font
);
1585 IDWriteFontFamily_Release(family
);
1586 IDWriteFontCollection_Release(collection
);
1588 /* IDWriteFactory::CreateFontFace() */
1589 path
= create_testfontfile(test_fontfile
);
1590 factory
= create_factory();
1592 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
1593 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
1596 file_type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1597 face_type
= DWRITE_FONT_FACE_TYPE_CFF
;
1599 hr
= IDWriteFontFile_Analyze(file
, &supported
, &file_type
, &face_type
, &count
);
1600 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1601 ok(supported
== TRUE
, "got %i\n", supported
);
1602 ok(file_type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", file_type
);
1603 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face_type
);
1604 ok(count
== 1, "got %i\n", count
);
1606 /* invalid simulation flags */
1607 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &file
, 0, ~0u, &fontface
);
1608 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1610 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &file
, 0, 0xf, &fontface
);
1611 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1613 /* try mismatching face type, the one that's not supported */
1614 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1615 ok(hr
== DWRITE_E_FILEFORMAT
, "got 0x%08x\n", hr
);
1617 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_OPENTYPE_COLLECTION
, 1, &file
, 0,
1618 DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1619 ok(hr
== DWRITE_E_FILEFORMAT
|| broken(hr
== E_FAIL
) /* < win10 */, "got 0x%08x\n", hr
);
1621 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_RAW_CFF
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1623 ok(hr
== DWRITE_E_UNSUPPORTEDOPERATION
|| broken(hr
== E_INVALIDARG
) /* older versions */, "got 0x%08x\n", hr
);
1625 fontface
= (void*)0xdeadbeef;
1626 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TYPE1
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1627 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1628 ok(fontface
== NULL
, "got %p\n", fontface
);
1630 fontface
= (void*)0xdeadbeef;
1631 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_VECTOR
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1632 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1633 ok(fontface
== NULL
, "got %p\n", fontface
);
1635 fontface
= (void*)0xdeadbeef;
1636 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_BITMAP
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1637 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1638 ok(fontface
== NULL
, "got %p\n", fontface
);
1641 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_UNKNOWN
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
1643 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
) /* < win10 */, "got 0x%08x\n", hr
);
1645 ok(fontface
!= NULL
, "got %p\n", fontface
);
1646 face_type
= IDWriteFontFace_GetType(fontface
);
1647 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %d\n", face_type
);
1648 IDWriteFontFace_Release(fontface
);
1651 IDWriteFontFile_Release(file
);
1652 IDWriteFactory_Release(factory
);
1653 DELETE_FONTFILE(path
);
1656 static void get_expected_font_metrics(IDWriteFontFace
*fontface
, DWRITE_FONT_METRICS1
*metrics
)
1658 void *os2_context
, *head_context
, *post_context
, *hhea_context
;
1659 const TT_OS2_V2
*tt_os2
;
1660 const TT_HEAD
*tt_head
;
1661 const TT_POST
*tt_post
;
1662 const TT_HHEA
*tt_hhea
;
1667 memset(metrics
, 0, sizeof(*metrics
));
1669 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_0S2_TAG
, (const void**)&tt_os2
, &size
, &os2_context
, &exists
);
1670 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1671 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_HEAD_TAG
, (const void**)&tt_head
, &size
, &head_context
, &exists
);
1672 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1673 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_HHEA_TAG
, (const void**)&tt_hhea
, &size
, &hhea_context
, &exists
);
1674 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1675 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_POST_TAG
, (const void**)&tt_post
, &size
, &post_context
, &exists
);
1676 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1679 metrics
->designUnitsPerEm
= GET_BE_WORD(tt_head
->unitsPerEm
);
1680 metrics
->glyphBoxLeft
= GET_BE_WORD(tt_head
->xMin
);
1681 metrics
->glyphBoxTop
= GET_BE_WORD(tt_head
->yMax
);
1682 metrics
->glyphBoxRight
= GET_BE_WORD(tt_head
->xMax
);
1683 metrics
->glyphBoxBottom
= GET_BE_WORD(tt_head
->yMin
);
1687 if (GET_BE_WORD(tt_os2
->fsSelection
) & OS2_FSSELECTION_USE_TYPO_METRICS
) {
1688 SHORT descent
= GET_BE_WORD(tt_os2
->sTypoDescender
);
1689 metrics
->ascent
= GET_BE_WORD(tt_os2
->sTypoAscender
);
1690 metrics
->descent
= descent
< 0 ? -descent
: 0;
1691 metrics
->lineGap
= GET_BE_WORD(tt_os2
->sTypoLineGap
);
1692 metrics
->hasTypographicMetrics
= TRUE
;
1695 metrics
->ascent
= GET_BE_WORD(tt_os2
->usWinAscent
);
1696 /* Some fonts have usWinDescent value stored as signed short, which could be wrongly
1697 interpreted as large unsigned value. */
1698 metrics
->descent
= abs((SHORT
)GET_BE_WORD(tt_os2
->usWinDescent
));
1701 SHORT descender
= (SHORT
)GET_BE_WORD(tt_hhea
->descender
);
1704 linegap
= GET_BE_WORD(tt_hhea
->ascender
) + abs(descender
) + GET_BE_WORD(tt_hhea
->linegap
) -
1705 metrics
->ascent
- metrics
->descent
;
1706 metrics
->lineGap
= linegap
> 0 ? linegap
: 0;
1710 metrics
->strikethroughPosition
= GET_BE_WORD(tt_os2
->yStrikeoutPosition
);
1711 metrics
->strikethroughThickness
= GET_BE_WORD(tt_os2
->yStrikeoutSize
);
1713 metrics
->subscriptPositionX
= GET_BE_WORD(tt_os2
->ySubscriptXOffset
);
1714 metrics
->subscriptPositionY
= -GET_BE_WORD(tt_os2
->ySubscriptYOffset
);
1715 metrics
->subscriptSizeX
= GET_BE_WORD(tt_os2
->ySubscriptXSize
);
1716 metrics
->subscriptSizeY
= GET_BE_WORD(tt_os2
->ySubscriptYSize
);
1717 metrics
->superscriptPositionX
= GET_BE_WORD(tt_os2
->ySuperscriptXOffset
);
1718 metrics
->superscriptPositionY
= GET_BE_WORD(tt_os2
->ySuperscriptYOffset
);
1719 metrics
->superscriptSizeX
= GET_BE_WORD(tt_os2
->ySuperscriptXSize
);
1720 metrics
->superscriptSizeY
= GET_BE_WORD(tt_os2
->ySuperscriptYSize
);
1724 metrics
->underlinePosition
= GET_BE_WORD(tt_post
->underlinePosition
);
1725 metrics
->underlineThickness
= GET_BE_WORD(tt_post
->underlineThickness
);
1728 if (metrics
->strikethroughThickness
|| metrics
->underlineThickness
) {
1729 if (!metrics
->strikethroughThickness
)
1730 metrics
->strikethroughThickness
= metrics
->underlineThickness
;
1731 if (!metrics
->underlineThickness
)
1732 metrics
->underlineThickness
= metrics
->strikethroughThickness
;
1735 metrics
->strikethroughThickness
= metrics
->designUnitsPerEm
/ 14;
1736 metrics
->underlineThickness
= metrics
->designUnitsPerEm
/ 14;
1740 IDWriteFontFace_ReleaseFontTable(fontface
, os2_context
);
1742 IDWriteFontFace_ReleaseFontTable(fontface
, head_context
);
1744 IDWriteFontFace_ReleaseFontTable(fontface
, hhea_context
);
1746 IDWriteFontFace_ReleaseFontTable(fontface
, post_context
);
1749 static void check_font_metrics(const WCHAR
*nameW
, BOOL has_metrics1
, const DWRITE_FONT_METRICS
*got
,
1750 const DWRITE_FONT_METRICS1
*expected
)
1752 ok(got
->designUnitsPerEm
== expected
->designUnitsPerEm
, "font %s: designUnitsPerEm %u, expected %u\n",
1753 wine_dbgstr_w(nameW
), got
->designUnitsPerEm
, expected
->designUnitsPerEm
);
1754 ok(got
->ascent
== expected
->ascent
, "font %s: ascent %u, expected %u\n", wine_dbgstr_w(nameW
), got
->ascent
,
1756 ok(got
->descent
== expected
->descent
, "font %s: descent %u, expected %u\n", wine_dbgstr_w(nameW
), got
->descent
,
1758 ok(got
->lineGap
== expected
->lineGap
, "font %s: lineGap %d, expected %d\n", wine_dbgstr_w(nameW
), got
->lineGap
,
1760 ok(got
->underlinePosition
== expected
->underlinePosition
, "font %s: underlinePosition %d, expected %d\n",
1761 wine_dbgstr_w(nameW
), got
->underlinePosition
, expected
->underlinePosition
);
1762 ok(got
->underlineThickness
== expected
->underlineThickness
, "font %s: underlineThickness %u, "
1763 "expected %u\n", wine_dbgstr_w(nameW
), got
->underlineThickness
, expected
->underlineThickness
);
1764 ok(got
->strikethroughPosition
== expected
->strikethroughPosition
, "font %s: strikethroughPosition %d, expected %d\n",
1765 wine_dbgstr_w(nameW
), got
->strikethroughPosition
, expected
->strikethroughPosition
);
1766 ok(got
->strikethroughThickness
== expected
->strikethroughThickness
, "font %s: strikethroughThickness %u, "
1767 "expected %u\n", wine_dbgstr_w(nameW
), got
->strikethroughThickness
, expected
->strikethroughThickness
);
1770 const DWRITE_FONT_METRICS1
*m1
= (const DWRITE_FONT_METRICS1
*)got
;
1771 ok(m1
->hasTypographicMetrics
== expected
->hasTypographicMetrics
, "font %s: hasTypographicMetrics %d, "
1772 "expected %d\n", wine_dbgstr_w(nameW
), m1
->hasTypographicMetrics
, expected
->hasTypographicMetrics
);
1773 ok(m1
->glyphBoxLeft
== expected
->glyphBoxLeft
, "font %s: glyphBoxLeft %d, expected %d\n", wine_dbgstr_w(nameW
),
1774 m1
->glyphBoxLeft
, expected
->glyphBoxLeft
);
1775 ok(m1
->glyphBoxTop
== expected
->glyphBoxTop
, "font %s: glyphBoxTop %d, expected %d\n", wine_dbgstr_w(nameW
),
1776 m1
->glyphBoxTop
, expected
->glyphBoxTop
);
1777 ok(m1
->glyphBoxRight
== expected
->glyphBoxRight
, "font %s: glyphBoxRight %d, expected %d\n", wine_dbgstr_w(nameW
),
1778 m1
->glyphBoxRight
, expected
->glyphBoxRight
);
1779 ok(m1
->glyphBoxBottom
== expected
->glyphBoxBottom
, "font %s: glyphBoxBottom %d, expected %d\n", wine_dbgstr_w(nameW
),
1780 m1
->glyphBoxBottom
, expected
->glyphBoxBottom
);
1782 ok(m1
->subscriptPositionX
== expected
->subscriptPositionX
, "font %s: subscriptPositionX %d, expected %d\n",
1783 wine_dbgstr_w(nameW
), m1
->subscriptPositionX
, expected
->subscriptPositionX
);
1784 ok(m1
->subscriptPositionY
== expected
->subscriptPositionY
, "font %s: subscriptPositionY %d, expected %d\n",
1785 wine_dbgstr_w(nameW
), m1
->subscriptPositionY
, expected
->subscriptPositionY
);
1786 ok(m1
->subscriptSizeX
== expected
->subscriptSizeX
, "font %s: subscriptSizeX %d, expected %d\n",
1787 wine_dbgstr_w(nameW
), m1
->subscriptSizeX
, expected
->subscriptSizeX
);
1788 ok(m1
->subscriptSizeY
== expected
->subscriptSizeY
, "font %s: subscriptSizeY %d, expected %d\n",
1789 wine_dbgstr_w(nameW
), m1
->subscriptSizeY
, expected
->subscriptSizeY
);
1790 ok(m1
->superscriptPositionX
== expected
->superscriptPositionX
, "font %s: superscriptPositionX %d, expected %d\n",
1791 wine_dbgstr_w(nameW
), m1
->superscriptPositionX
, expected
->superscriptPositionX
);
1792 ok(m1
->superscriptPositionY
== expected
->superscriptPositionY
, "font %s: superscriptPositionY %d, expected %d\n",
1793 wine_dbgstr_w(nameW
), m1
->superscriptPositionY
, expected
->superscriptPositionY
);
1794 ok(m1
->superscriptSizeX
== expected
->superscriptSizeX
, "font %s: superscriptSizeX %d, expected %d\n",
1795 wine_dbgstr_w(nameW
), m1
->superscriptSizeX
, expected
->superscriptSizeX
);
1796 ok(m1
->superscriptSizeY
== expected
->superscriptSizeY
, "font %s: superscriptSizeY %d, expected %d\n",
1797 wine_dbgstr_w(nameW
), m1
->superscriptSizeY
, expected
->superscriptSizeY
);
1801 static void get_enus_string(IDWriteLocalizedStrings
*strings
, WCHAR
*buff
, UINT32 size
)
1803 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
1804 BOOL exists
= FALSE
;
1808 hr
= IDWriteLocalizedStrings_FindLocaleName(strings
, enusW
, &index
, &exists
);
1809 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1810 ok(exists
, "got %d\n", exists
);
1812 hr
= IDWriteLocalizedStrings_GetString(strings
, index
, buff
, size
);
1813 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1816 static void test_GetMetrics(void)
1818 DWRITE_FONT_METRICS metrics
, metrics2
;
1819 IDWriteFontCollection
*syscollection
;
1820 IDWriteGdiInterop
*interop
;
1821 IDWriteFontFace
*fontface
;
1822 IDWriteFactory
*factory
;
1823 OUTLINETEXTMETRICW otm
;
1824 IDWriteFontFile
*file
;
1825 IDWriteFont1
*font1
;
1834 factory
= create_factory();
1836 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
1837 EXPECT_HR(hr
, S_OK
);
1839 memset(&logfont
, 0, sizeof(logfont
));
1840 logfont
.lfHeight
= 12;
1841 logfont
.lfWidth
= 12;
1842 logfont
.lfWeight
= FW_NORMAL
;
1843 logfont
.lfItalic
= 1;
1844 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
1846 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
1847 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1849 hfont
= CreateFontIndirectW(&logfont
);
1850 hdc
= CreateCompatibleDC(0);
1851 SelectObject(hdc
, hfont
);
1853 otm
.otmSize
= sizeof(otm
);
1854 ret
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
1855 ok(ret
, "got %d\n", ret
);
1857 DeleteObject(hfont
);
1859 if (0) /* crashes on native */
1860 IDWriteFont_GetMetrics(font
, NULL
);
1862 memset(&metrics
, 0, sizeof(metrics
));
1863 IDWriteFont_GetMetrics(font
, &metrics
);
1865 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
1866 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
1867 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
1868 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
1869 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
1870 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
1871 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
1872 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
1873 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
1874 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
1876 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1877 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1879 memset(&metrics
, 0, sizeof(metrics
));
1880 IDWriteFontFace_GetMetrics(fontface
, &metrics
);
1882 ok(metrics
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics
.designUnitsPerEm
);
1883 ok(metrics
.ascent
!= 0, "ascent %u\n", metrics
.ascent
);
1884 ok(metrics
.descent
!= 0, "descent %u\n", metrics
.descent
);
1885 ok(metrics
.lineGap
== 0, "lineGap %d\n", metrics
.lineGap
);
1886 ok(metrics
.capHeight
, "capHeight %u\n", metrics
.capHeight
);
1887 ok(metrics
.xHeight
!= 0, "xHeight %u\n", metrics
.xHeight
);
1888 ok(metrics
.underlinePosition
< 0, "underlinePosition %d\n", metrics
.underlinePosition
);
1889 ok(metrics
.underlineThickness
!= 0, "underlineThickness %u\n", metrics
.underlineThickness
);
1890 ok(metrics
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics
.strikethroughPosition
);
1891 ok(metrics
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics
.strikethroughThickness
);
1893 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
1895 DWRITE_FONT_METRICS1 metrics1
;
1896 IDWriteFontFace1
*fontface1
;
1898 memset(&metrics1
, 0, sizeof(metrics1
));
1899 IDWriteFont1_GetMetrics(font1
, &metrics1
);
1901 ok(metrics1
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics1
.designUnitsPerEm
);
1902 ok(metrics1
.ascent
!= 0, "ascent %u\n", metrics1
.ascent
);
1903 ok(metrics1
.descent
!= 0, "descent %u\n", metrics1
.descent
);
1904 ok(metrics1
.lineGap
== 0, "lineGap %d\n", metrics1
.lineGap
);
1905 ok(metrics1
.capHeight
, "capHeight %u\n", metrics1
.capHeight
);
1906 ok(metrics1
.xHeight
!= 0, "xHeight %u\n", metrics1
.xHeight
);
1907 ok(metrics1
.underlinePosition
< 0, "underlinePosition %d\n", metrics1
.underlinePosition
);
1908 ok(metrics1
.underlineThickness
!= 0, "underlineThickness %u\n", metrics1
.underlineThickness
);
1909 ok(metrics1
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics1
.strikethroughPosition
);
1910 ok(metrics1
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics1
.strikethroughThickness
);
1911 ok(metrics1
.glyphBoxLeft
< 0, "glyphBoxLeft %d\n", metrics1
.glyphBoxLeft
);
1912 ok(metrics1
.glyphBoxTop
> 0, "glyphBoxTop %d\n", metrics1
.glyphBoxTop
);
1913 ok(metrics1
.glyphBoxRight
> 0, "glyphBoxRight %d\n", metrics1
.glyphBoxRight
);
1914 ok(metrics1
.glyphBoxBottom
< 0, "glyphBoxBottom %d\n", metrics1
.glyphBoxBottom
);
1915 ok(metrics1
.subscriptPositionY
< 0, "subscriptPositionY %d\n", metrics1
.subscriptPositionY
);
1916 ok(metrics1
.subscriptSizeX
> 0, "subscriptSizeX %d\n", metrics1
.subscriptSizeX
);
1917 ok(metrics1
.subscriptSizeY
> 0, "subscriptSizeY %d\n", metrics1
.subscriptSizeY
);
1918 ok(metrics1
.superscriptPositionY
> 0, "superscriptPositionY %d\n", metrics1
.superscriptPositionY
);
1919 ok(metrics1
.superscriptSizeX
> 0, "superscriptSizeX %d\n", metrics1
.superscriptSizeX
);
1920 ok(metrics1
.superscriptSizeY
> 0, "superscriptSizeY %d\n", metrics1
.superscriptSizeY
);
1921 ok(!metrics1
.hasTypographicMetrics
, "hasTypographicMetrics %d\n", metrics1
.hasTypographicMetrics
);
1923 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
1924 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1926 memset(&metrics1
, 0, sizeof(metrics1
));
1927 IDWriteFontFace1_GetMetrics(fontface1
, &metrics1
);
1929 ok(metrics1
.designUnitsPerEm
!= 0, "designUnitsPerEm %u\n", metrics1
.designUnitsPerEm
);
1930 ok(metrics1
.ascent
!= 0, "ascent %u\n", metrics1
.ascent
);
1931 ok(metrics1
.descent
!= 0, "descent %u\n", metrics1
.descent
);
1932 ok(metrics1
.lineGap
== 0, "lineGap %d\n", metrics1
.lineGap
);
1933 ok(metrics1
.capHeight
, "capHeight %u\n", metrics1
.capHeight
);
1934 ok(metrics1
.xHeight
!= 0, "xHeight %u\n", metrics1
.xHeight
);
1935 ok(metrics1
.underlinePosition
< 0, "underlinePosition %d\n", metrics1
.underlinePosition
);
1936 ok(metrics1
.underlineThickness
!= 0, "underlineThickness %u\n", metrics1
.underlineThickness
);
1937 ok(metrics1
.strikethroughPosition
> 0, "strikethroughPosition %d\n", metrics1
.strikethroughPosition
);
1938 ok(metrics1
.strikethroughThickness
!= 0, "strikethroughThickness %u\n", metrics1
.strikethroughThickness
);
1939 ok(metrics1
.glyphBoxLeft
< 0, "glyphBoxLeft %d\n", metrics1
.glyphBoxLeft
);
1940 ok(metrics1
.glyphBoxTop
> 0, "glyphBoxTop %d\n", metrics1
.glyphBoxTop
);
1941 ok(metrics1
.glyphBoxRight
> 0, "glyphBoxRight %d\n", metrics1
.glyphBoxRight
);
1942 ok(metrics1
.glyphBoxBottom
< 0, "glyphBoxBottom %d\n", metrics1
.glyphBoxBottom
);
1943 ok(metrics1
.subscriptPositionY
< 0, "subscriptPositionY %d\n", metrics1
.subscriptPositionY
);
1944 ok(metrics1
.subscriptSizeX
> 0, "subscriptSizeX %d\n", metrics1
.subscriptSizeX
);
1945 ok(metrics1
.subscriptSizeY
> 0, "subscriptSizeY %d\n", metrics1
.subscriptSizeY
);
1946 ok(metrics1
.superscriptPositionY
> 0, "superscriptPositionY %d\n", metrics1
.superscriptPositionY
);
1947 ok(metrics1
.superscriptSizeX
> 0, "superscriptSizeX %d\n", metrics1
.superscriptSizeX
);
1948 ok(metrics1
.superscriptSizeY
> 0, "superscriptSizeY %d\n", metrics1
.superscriptSizeY
);
1949 ok(!metrics1
.hasTypographicMetrics
, "hasTypographicMetrics %d\n", metrics1
.hasTypographicMetrics
);
1951 IDWriteFontFace1_Release(fontface1
);
1952 IDWriteFont1_Release(font1
);
1955 win_skip("DWRITE_FONT_METRICS1 is not supported.\n");
1957 IDWriteFontFace_Release(fontface
);
1958 IDWriteFont_Release(font
);
1959 IDWriteGdiInterop_Release(interop
);
1961 /* bold simulation affects returned font metrics */
1962 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
1964 /* create regulat Tahoma with bold simulation */
1965 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
1966 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1969 hr
= IDWriteFontFace_GetFiles(fontface
, &count
, &file
);
1970 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1972 IDWriteFontFace_GetMetrics(fontface
, &metrics
);
1973 ok(IDWriteFontFace_GetSimulations(fontface
) == 0, "wrong simulations flags\n");
1974 IDWriteFontFace_Release(fontface
);
1976 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
,
1977 0, DWRITE_FONT_SIMULATIONS_BOLD
, &fontface
);
1978 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1979 IDWriteFontFace_GetMetrics(fontface
, &metrics2
);
1980 ok(IDWriteFontFace_GetSimulations(fontface
) == DWRITE_FONT_SIMULATIONS_BOLD
, "wrong simulations flags\n");
1982 ok(metrics
.ascent
== metrics2
.ascent
, "got %u, %u\n", metrics2
.ascent
, metrics
.ascent
);
1983 ok(metrics
.descent
== metrics2
.descent
, "got %u, %u\n", metrics2
.descent
, metrics
.descent
);
1984 ok(metrics
.lineGap
== metrics2
.lineGap
, "got %d, %d\n", metrics2
.lineGap
, metrics
.lineGap
);
1985 ok(metrics
.capHeight
== metrics2
.capHeight
, "got %u, %u\n", metrics2
.capHeight
, metrics
.capHeight
);
1986 ok(metrics
.xHeight
== metrics2
.xHeight
, "got %u, %u\n", metrics2
.xHeight
, metrics
.xHeight
);
1987 ok(metrics
.underlinePosition
== metrics2
.underlinePosition
, "got %d, %d\n", metrics2
.underlinePosition
,
1988 metrics
.underlinePosition
);
1989 ok(metrics
.underlineThickness
== metrics2
.underlineThickness
, "got %u, %u\n", metrics2
.underlineThickness
,
1990 metrics
.underlineThickness
);
1991 ok(metrics
.strikethroughPosition
== metrics2
.strikethroughPosition
, "got %d, %d\n", metrics2
.strikethroughPosition
,
1992 metrics
.strikethroughPosition
);
1993 ok(metrics
.strikethroughThickness
== metrics2
.strikethroughThickness
, "got %u, %u\n", metrics2
.strikethroughThickness
,
1994 metrics
.strikethroughThickness
);
1996 IDWriteFontFile_Release(file
);
1997 IDWriteFont_Release(font
);
1999 /* test metrics for whole system collection */
2000 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &syscollection
, FALSE
);
2001 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2002 count
= IDWriteFontCollection_GetFontFamilyCount(syscollection
);
2004 for (i
= 0; i
< count
; i
++) {
2005 DWRITE_FONT_METRICS1 expected_metrics
, metrics1
;
2006 IDWriteLocalizedStrings
*names
;
2007 IDWriteFontFace1
*fontface1
;
2008 IDWriteFontFamily
*family
;
2012 hr
= IDWriteFontCollection_GetFontFamily(syscollection
, i
, &family
);
2013 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2015 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STRETCH_NORMAL
,
2016 DWRITE_FONT_STYLE_NORMAL
, &font
);
2017 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2019 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2020 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2023 IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
2025 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
2026 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2028 get_enus_string(names
, nameW
, sizeof(nameW
)/sizeof(nameW
[0]));
2030 IDWriteLocalizedStrings_Release(names
);
2031 IDWriteFont_Release(font
);
2033 get_expected_font_metrics(fontface
, &expected_metrics
);
2035 IDWriteFontFace1_GetMetrics(fontface1
, &metrics1
);
2036 check_font_metrics(nameW
, TRUE
, (const DWRITE_FONT_METRICS
*)&metrics1
, &expected_metrics
);
2039 IDWriteFontFace_GetMetrics(fontface
, &metrics
);
2040 check_font_metrics(nameW
, FALSE
, &metrics
, &expected_metrics
);
2044 IDWriteFontFace1_Release(fontface1
);
2045 IDWriteFontFace_Release(fontface
);
2046 IDWriteFontFamily_Release(family
);
2048 IDWriteFontCollection_Release(syscollection
);
2049 IDWriteFactory_Release(factory
);
2052 static void test_system_fontcollection(void)
2054 IDWriteFontCollection
*collection
, *coll2
;
2055 IDWriteLocalFontFileLoader
*localloader
;
2056 IDWriteFontCollection1
*collection1
;
2057 IDWriteFactory
*factory
, *factory2
;
2058 IDWriteFontFileLoader
*loader
;
2059 IDWriteFontFamily
*family
;
2060 IDWriteFontFace
*fontface
;
2061 IDWriteFontFile
*file
;
2067 factory
= create_factory();
2069 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2070 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2072 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, FALSE
);
2073 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2074 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
2075 IDWriteFontCollection_Release(coll2
);
2077 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &coll2
, TRUE
);
2078 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2079 ok(coll2
== collection
, "got %p, was %p\n", coll2
, collection
);
2080 IDWriteFontCollection_Release(coll2
);
2082 factory2
= create_factory();
2083 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &coll2
, FALSE
);
2084 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2085 ok(coll2
!= collection
, "got %p, was %p\n", coll2
, collection
);
2086 IDWriteFontCollection_Release(coll2
);
2087 IDWriteFactory_Release(factory2
);
2089 i
= IDWriteFontCollection_GetFontFamilyCount(collection
);
2090 ok(i
, "got %u\n", i
);
2093 family
= (void*)0xdeadbeef;
2094 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
2095 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2096 ok(family
== NULL
, "got %p\n", family
);
2100 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaW
, &i
, &ret
);
2101 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2102 ok(ret
, "got %d\n", ret
);
2103 ok(i
!= (UINT32
)-1, "got %u\n", i
);
2107 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaUppercaseW
, &i
, &ret
);
2108 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2109 ok(ret
, "got %d\n", ret
);
2110 ok(i
!= (UINT32
)-1, "got %u\n", i
);
2114 hr
= IDWriteFontCollection_FindFamilyName(collection
, tahomaStrangecaseW
, &i
, &ret
);
2115 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2116 ok(ret
, "got %d\n", ret
);
2117 ok(i
!= (UINT32
)-1, "got %u\n", i
);
2119 /* get back local file loader */
2120 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
2121 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2123 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
2124 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
2125 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2126 IDWriteFontFamily_Release(family
);
2128 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2129 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2130 IDWriteFont_Release(font
);
2134 hr
= IDWriteFontFace_GetFiles(fontface
, &i
, &file
);
2135 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2136 ok(file
!= NULL
, "got %p\n", file
);
2138 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2139 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2140 IDWriteFontFile_Release(file
);
2142 hr
= IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
2143 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2144 IDWriteLocalFontFileLoader_Release(localloader
);
2146 /* local loader is not registered by default */
2147 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, loader
);
2148 ok(hr
== S_OK
|| broken(hr
== DWRITE_E_ALREADYREGISTERED
), "got 0x%08x\n", hr
);
2149 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, loader
);
2150 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "got 0x%08x\n", hr
);
2152 /* try with a different factory */
2153 factory2
= create_factory();
2154 hr
= IDWriteFactory_RegisterFontFileLoader(factory2
, loader
);
2155 ok(hr
== S_OK
|| broken(hr
== DWRITE_E_ALREADYREGISTERED
), "got 0x%08x\n", hr
);
2156 hr
= IDWriteFactory_RegisterFontFileLoader(factory2
, loader
);
2157 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
2158 hr
= IDWriteFactory_UnregisterFontFileLoader(factory2
, loader
);
2159 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "got 0x%08x\n", hr
);
2160 hr
= IDWriteFactory_UnregisterFontFileLoader(factory2
, loader
);
2161 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2162 IDWriteFactory_Release(factory2
);
2164 IDWriteFontFileLoader_Release(loader
);
2168 hr
= IDWriteFontCollection_FindFamilyName(collection
, blahW
, &i
, &ret
);
2169 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2170 ok(!ret
, "got %d\n", ret
);
2171 ok(i
== (UINT32
)-1, "got %u\n", i
);
2173 hr
= IDWriteFontCollection_QueryInterface(collection
, &IID_IDWriteFontCollection1
, (void**)&collection1
);
2175 IDWriteFontFamily1
*family1
;
2177 hr
= IDWriteFontCollection1_QueryInterface(collection1
, &IID_IDWriteFontCollection
, (void**)&coll2
);
2178 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2179 ok(coll2
== collection
, "got %p, %p\n", collection
, coll2
);
2180 IDWriteFontCollection_Release(coll2
);
2182 family1
= (void*)0xdeadbeef;
2183 hr
= IDWriteFontCollection1_GetFontFamily(collection1
, ~0u, &family1
);
2184 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
2185 ok(family1
== NULL
, "got %p\n", family1
);
2187 hr
= IDWriteFontCollection1_GetFontFamily(collection1
, 0, &family1
);
2188 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2189 IDWriteFontFamily1_Release(family1
);
2190 IDWriteFontCollection1_Release(collection1
);
2193 win_skip("IDWriteFontCollection1 is not supported.\n");
2195 IDWriteFontCollection_Release(collection
);
2196 IDWriteFactory_Release(factory
);
2199 static void get_logfont_from_font(IDWriteFont
*font
, LOGFONTW
*logfont
)
2201 void *os2_context
, *head_context
;
2202 IDWriteLocalizedStrings
*names
;
2203 DWRITE_FONT_SIMULATIONS sim
;
2204 IDWriteFontFace
*fontface
;
2205 const TT_OS2_V2
*tt_os2
;
2206 DWRITE_FONT_STYLE style
;
2207 const TT_HEAD
*tt_head
;
2213 /* These are rendering time properties. */
2214 logfont
->lfHeight
= 0;
2215 logfont
->lfWidth
= 0;
2216 logfont
->lfEscapement
= 0;
2217 logfont
->lfOrientation
= 0;
2218 logfont
->lfUnderline
= 0;
2219 logfont
->lfStrikeOut
= 0;
2221 logfont
->lfWeight
= 0;
2222 logfont
->lfItalic
= 0;
2224 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2225 ok(hr
== S_OK
, "Failed to create font face, %#x\n", hr
);
2227 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_0S2_TAG
, (const void **)&tt_os2
, &size
,
2228 &os2_context
, &exists
);
2229 ok(hr
== S_OK
, "Failed to get OS/2 table, %#x\n", hr
);
2231 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_HEAD_TAG
, (const void **)&tt_head
, &size
,
2232 &head_context
, &exists
);
2233 ok(hr
== S_OK
, "Failed to get head table, %#x\n", hr
);
2235 sim
= IDWriteFont_GetSimulations(font
);
2238 weight
= FW_REGULAR
;
2240 USHORT usWeightClass
= GET_BE_WORD(tt_os2
->usWeightClass
);
2242 if (usWeightClass
>= 1 && usWeightClass
<= 9)
2243 usWeightClass
*= 100;
2245 if (usWeightClass
> DWRITE_FONT_WEIGHT_ULTRA_BLACK
)
2246 weight
= DWRITE_FONT_WEIGHT_ULTRA_BLACK
;
2247 else if (usWeightClass
> 0)
2248 weight
= usWeightClass
;
2251 USHORT macStyle
= GET_BE_WORD(tt_head
->macStyle
);
2252 if (macStyle
& TT_HEAD_MACSTYLE_BOLD
)
2253 weight
= DWRITE_FONT_WEIGHT_BOLD
;
2255 if (sim
& DWRITE_FONT_SIMULATIONS_BOLD
)
2256 weight
+= (FW_BOLD
- FW_REGULAR
) / 2 + 1;
2257 logfont
->lfWeight
= weight
;
2260 if (IDWriteFont_GetSimulations(font
) & DWRITE_FONT_SIMULATIONS_OBLIQUE
)
2261 logfont
->lfItalic
= 1;
2263 style
= IDWriteFont_GetStyle(font
);
2264 if (!logfont
->lfItalic
&& ((style
== DWRITE_FONT_STYLE_ITALIC
) || (style
== DWRITE_FONT_STYLE_OBLIQUE
))) {
2266 USHORT fsSelection
= GET_BE_WORD(tt_os2
->fsSelection
);
2267 logfont
->lfItalic
= !!(fsSelection
& OS2_FSSELECTION_ITALIC
);
2270 USHORT macStyle
= GET_BE_WORD(tt_head
->macStyle
);
2271 logfont
->lfItalic
= !!(macStyle
& TT_HEAD_MACSTYLE_ITALIC
);
2277 logfont
->lfFaceName
[0] = 0;
2278 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &names
, &exists
);
2279 if (SUCCEEDED(hr
)) {
2281 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
2282 WCHAR localeW
[LOCALE_NAME_MAX_LENGTH
];
2285 /* Fallback to en-us if there's no string for user locale. */
2287 if (GetSystemDefaultLocaleName(localeW
, sizeof(localeW
)/sizeof(WCHAR
)))
2288 IDWriteLocalizedStrings_FindLocaleName(names
, localeW
, &index
, &exists
);
2291 IDWriteLocalizedStrings_FindLocaleName(names
, enusW
, &index
, &exists
);
2294 IDWriteLocalizedStrings_GetString(names
, index
, logfont
->lfFaceName
, sizeof(logfont
->lfFaceName
)/sizeof(WCHAR
));
2297 IDWriteLocalizedStrings_Release(names
);
2301 IDWriteFontFace_ReleaseFontTable(fontface
, os2_context
);
2303 IDWriteFontFace_ReleaseFontTable(fontface
, head_context
);
2304 IDWriteFontFace_Release(fontface
);
2307 static void test_ConvertFontFaceToLOGFONT(void)
2309 IDWriteGdiInterop
*interop
;
2310 IDWriteFontFace
*fontface
;
2311 IDWriteFactory
*factory
;
2315 IDWriteFontCollection
*collection
;
2317 factory
= create_factory();
2319 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
2320 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2322 if (0) /* crashes on native */
2324 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, NULL
, NULL
);
2325 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, NULL
);
2327 memset(&logfont
, 0xcc, sizeof(logfont
));
2328 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, NULL
, &logfont
);
2329 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2330 ok(logfont
.lfFaceName
[0] == 0, "got face name %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
2332 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
2333 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2335 count
= IDWriteFontCollection_GetFontFamilyCount(collection
);
2336 for (i
= 0; i
< count
; i
++) {
2337 WCHAR nameW
[128], familynameW
[64], facenameW
[64];
2338 IDWriteLocalizedStrings
*names
;
2339 DWRITE_FONT_SIMULATIONS sim
;
2340 IDWriteFontFamily
*family
;
2341 UINT32 font_count
, j
;
2345 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
2346 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2348 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
2349 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2351 get_enus_string(names
, familynameW
, sizeof(familynameW
)/sizeof(familynameW
[0]));
2352 IDWriteLocalizedStrings_Release(names
);
2354 font_count
= IDWriteFontFamily_GetFontCount(family
);
2356 for (j
= 0; j
< font_count
; j
++) {
2357 static const WCHAR spaceW
[] = {' ', 0};
2358 IDWriteFontFace
*fontface
;
2360 hr
= IDWriteFontFamily_GetFont(family
, j
, &font
);
2361 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2363 hr
= IDWriteFont_GetFaceNames(font
, &names
);
2364 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2366 get_enus_string(names
, facenameW
, sizeof(facenameW
)/sizeof(facenameW
[0]));
2367 IDWriteLocalizedStrings_Release(names
);
2369 lstrcpyW(nameW
, familynameW
);
2370 lstrcatW(nameW
, spaceW
);
2371 lstrcatW(nameW
, facenameW
);
2373 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
2374 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2376 memset(&logfont
, 0xcc, sizeof(logfont
));
2377 hr
= IDWriteGdiInterop_ConvertFontFaceToLOGFONT(interop
, fontface
, &logfont
);
2378 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2380 sim
= IDWriteFontFace_GetSimulations(fontface
);
2382 get_logfont_from_font(font
, &lf
);
2383 ok(logfont
.lfWeight
== lf
.lfWeight
, "%s: unexpected lfWeight %d, expected lfWeight %d, font weight %d, "
2384 "bold simulation %s\n", wine_dbgstr_w(nameW
), logfont
.lfWeight
, lf
.lfWeight
, IDWriteFont_GetWeight(font
),
2385 sim
& DWRITE_FONT_SIMULATIONS_BOLD
? "yes" : "no");
2386 ok(logfont
.lfItalic
== lf
.lfItalic
, "%s: unexpected italic flag %d, oblique simulation %s\n",
2387 wine_dbgstr_w(nameW
), logfont
.lfItalic
, sim
& DWRITE_FONT_SIMULATIONS_OBLIQUE
? "yes" : "no");
2388 ok(!lstrcmpW(logfont
.lfFaceName
, lf
.lfFaceName
), "%s: unexpected facename %s, expected %s\n",
2389 wine_dbgstr_w(nameW
), wine_dbgstr_w(logfont
.lfFaceName
), wine_dbgstr_w(lf
.lfFaceName
));
2391 ok(logfont
.lfOutPrecision
== OUT_OUTLINE_PRECIS
, "%s: unexpected output precision %d\n", wine_dbgstr_w(nameW
),
2392 logfont
.lfOutPrecision
);
2393 ok(logfont
.lfClipPrecision
== CLIP_DEFAULT_PRECIS
, "%s: unexpected clipping precision %d\n", wine_dbgstr_w(nameW
),
2394 logfont
.lfClipPrecision
);
2395 ok(logfont
.lfQuality
== DEFAULT_QUALITY
, "%s: unexpected quality %d\n", wine_dbgstr_w(nameW
), logfont
.lfQuality
);
2396 ok(logfont
.lfPitchAndFamily
== DEFAULT_PITCH
, "%s: unexpected pitch %d\n", wine_dbgstr_w(nameW
),
2397 logfont
.lfPitchAndFamily
);
2399 IDWriteFontFace_Release(fontface
);
2400 IDWriteFont_Release(font
);
2403 IDWriteFontFamily_Release(family
);
2406 IDWriteFontCollection_Release(collection
);
2407 IDWriteGdiInterop_Release(interop
);
2408 IDWriteFactory_Release(factory
);
2411 static HRESULT WINAPI
fontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
2413 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
))
2416 IDWriteFontFileEnumerator_AddRef(iface
);
2419 return E_NOINTERFACE
;
2422 static ULONG WINAPI
fontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
2427 static ULONG WINAPI
fontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
2432 static HRESULT WINAPI
fontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**file
)
2438 static HRESULT WINAPI
fontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
2444 static const struct IDWriteFontFileEnumeratorVtbl dwritefontfileenumeratorvtbl
=
2446 fontfileenumerator_QueryInterface
,
2447 fontfileenumerator_AddRef
,
2448 fontfileenumerator_Release
,
2449 fontfileenumerator_MoveNext
,
2450 fontfileenumerator_GetCurrentFontFile
,
2453 static HRESULT WINAPI
fontcollectionloader_QueryInterface(IDWriteFontCollectionLoader
*iface
, REFIID riid
, void **obj
)
2459 static ULONG WINAPI
fontcollectionloader_AddRef(IDWriteFontCollectionLoader
*iface
)
2464 static ULONG WINAPI
fontcollectionloader_Release(IDWriteFontCollectionLoader
*iface
)
2469 static HRESULT WINAPI
fontcollectionloader_CreateEnumeratorFromKey(IDWriteFontCollectionLoader
*iface
, IDWriteFactory
*factory
, const void *key
,
2470 UINT32 key_size
, IDWriteFontFileEnumerator
**ret
)
2472 static IDWriteFontFileEnumerator enumerator
= { &dwritefontfileenumeratorvtbl
};
2477 static const struct IDWriteFontCollectionLoaderVtbl dwritefontcollectionloadervtbl
= {
2478 fontcollectionloader_QueryInterface
,
2479 fontcollectionloader_AddRef
,
2480 fontcollectionloader_Release
,
2481 fontcollectionloader_CreateEnumeratorFromKey
2484 static void test_CustomFontCollection(void)
2486 static const WCHAR fontnameW
[] = {'w','i','n','e','_','t','e','s','t',0};
2487 IDWriteFontCollectionLoader collection
= { &dwritefontcollectionloadervtbl
};
2488 IDWriteFontCollectionLoader collection2
= { &dwritefontcollectionloadervtbl
};
2489 IDWriteFontCollectionLoader collection3
= { &dwritefontcollectionloadervtbl
};
2490 IDWriteFontCollection
*font_collection
= NULL
;
2491 static IDWriteFontFileLoader rloader
= { &resourcefontfileloadervtbl
};
2492 struct test_fontcollectionloader resource_collection
= { { &resourcecollectionloadervtbl
}, &rloader
};
2493 IDWriteFontFamily
*family
, *family2
, *family3
;
2494 IDWriteFontFace
*idfontface
, *idfontface2
;
2495 IDWriteFontFile
*fontfile
, *fontfile2
;
2496 IDWriteLocalizedStrings
*string
;
2497 IDWriteFont
*idfont
, *idfont2
;
2498 IDWriteFactory
*factory
;
2499 UINT32 index
, count
;
2504 factory
= create_factory();
2506 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, NULL
);
2507 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2509 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, NULL
);
2510 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2512 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
2513 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2514 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection2
);
2515 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2516 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &collection
);
2517 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
2519 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
2520 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2521 hr
= IDWriteFactory_RegisterFontCollectionLoader(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
);
2522 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2524 font_collection
= (void*)0xdeadbeef;
2525 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection3
, "Billy", 6, &font_collection
);
2526 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2527 ok(font_collection
== NULL
, "got %p\n", font_collection
);
2529 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection
, "Billy", 6, &font_collection
);
2530 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2531 IDWriteFontCollection_Release(font_collection
);
2533 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &collection2
, "Billy", 6, &font_collection
);
2534 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2535 IDWriteFontCollection_Release(font_collection
);
2537 font_collection
= (void*)0xdeadbeef;
2538 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, (IDWriteFontCollectionLoader
*)0xdeadbeef, "Billy", 6, &font_collection
);
2539 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2540 ok(font_collection
== NULL
, "got %p\n", font_collection
);
2542 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
2543 ok(font
!= NULL
, "Failed to find font resource\n");
2545 hr
= IDWriteFactory_CreateCustomFontCollection(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
,
2546 &font
, sizeof(HRSRC
), &font_collection
);
2547 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2551 hr
= IDWriteFontCollection_FindFamilyName(font_collection
, fontnameW
, &index
, &exists
);
2552 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2553 ok(index
== 0, "got index %i\n", index
);
2554 ok(exists
, "got exists %i\n", exists
);
2556 count
= IDWriteFontCollection_GetFontFamilyCount(font_collection
);
2557 ok(count
== 1, "got %u\n", count
);
2560 hr
= IDWriteFontCollection_GetFontFamily(font_collection
, 0, &family
);
2561 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2562 EXPECT_REF(family
, 1);
2565 hr
= IDWriteFontCollection_GetFontFamily(font_collection
, 0, &family2
);
2566 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2567 EXPECT_REF(family2
, 1);
2568 ok(family
!= family2
, "got %p, %p\n", family
, family2
);
2570 hr
= IDWriteFontFamily_GetFont(family
, 0, &idfont
);
2571 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2572 EXPECT_REF(idfont
, 1);
2573 EXPECT_REF(family
, 2);
2574 hr
= IDWriteFontFamily_GetFont(family
, 0, &idfont2
);
2575 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2576 EXPECT_REF(idfont2
, 1);
2577 EXPECT_REF(family
, 3);
2578 ok(idfont
!= idfont2
, "got %p, %p\n", idfont
, idfont2
);
2579 IDWriteFont_Release(idfont2
);
2581 hr
= IDWriteFont_GetInformationalStrings(idfont
, DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE
, &string
, &exists
);
2582 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2583 ok(exists
, "got %d\n", exists
);
2584 EXPECT_REF(string
, 1);
2585 IDWriteLocalizedStrings_Release(string
);
2588 hr
= IDWriteFont_GetFontFamily(idfont
, &family3
);
2589 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2590 EXPECT_REF(family
, 3);
2591 ok(family
== family3
, "got %p, %p\n", family
, family3
);
2592 IDWriteFontFamily_Release(family3
);
2595 hr
= IDWriteFont_CreateFontFace(idfont
, &idfontface
);
2596 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2597 EXPECT_REF(idfont
, 1);
2600 hr
= IDWriteFontFamily_GetFont(family2
, 0, &idfont2
);
2601 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2602 EXPECT_REF(idfont2
, 1);
2603 EXPECT_REF(idfont
, 1);
2604 ok(idfont2
!= idfont
, "Font instances should not match\n");
2607 hr
= IDWriteFont_CreateFontFace(idfont2
, &idfontface2
);
2608 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2609 ok(idfontface2
== idfontface
, "fontfaces should match\n");
2613 hr
= IDWriteFontFace_GetFiles(idfontface
, &index
, &fontfile
);
2614 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2618 hr
= IDWriteFontFace_GetFiles(idfontface2
, &index
, &fontfile2
);
2619 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2620 ok(fontfile
== fontfile2
, "fontfiles should match\n");
2622 IDWriteFont_Release(idfont
);
2623 IDWriteFont_Release(idfont2
);
2624 IDWriteFontFile_Release(fontfile
);
2625 IDWriteFontFile_Release(fontfile2
);
2626 IDWriteFontFace_Release(idfontface
);
2627 IDWriteFontFace_Release(idfontface2
);
2628 IDWriteFontFamily_Release(family2
);
2629 IDWriteFontFamily_Release(family
);
2630 IDWriteFontCollection_Release(font_collection
);
2632 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
2633 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2634 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection
);
2635 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2636 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &collection2
);
2637 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2638 hr
= IDWriteFactory_UnregisterFontCollectionLoader(factory
, &resource_collection
.IDWriteFontFileCollectionLoader_iface
);
2639 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2640 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
2641 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2643 IDWriteFactory_Release(factory
);
2646 static HRESULT WINAPI
fontfileloader_QueryInterface(IDWriteFontFileLoader
*iface
, REFIID riid
, void **obj
)
2648 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
))
2651 IDWriteFontFileLoader_AddRef(iface
);
2656 return E_NOINTERFACE
;
2659 static ULONG WINAPI
fontfileloader_AddRef(IDWriteFontFileLoader
*iface
)
2664 static ULONG WINAPI
fontfileloader_Release(IDWriteFontFileLoader
*iface
)
2669 static HRESULT WINAPI
fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader
*iface
, const void *ref_key
, UINT32 key_size
,
2670 IDWriteFontFileStream
**stream
)
2675 static const struct IDWriteFontFileLoaderVtbl dwritefontfileloadervtbl
= {
2676 fontfileloader_QueryInterface
,
2677 fontfileloader_AddRef
,
2678 fontfileloader_Release
,
2679 fontfileloader_CreateStreamFromKey
2682 static void test_CreateCustomFontFileReference(void)
2684 IDWriteFontFileLoader floader
= { &dwritefontfileloadervtbl
};
2685 IDWriteFontFileLoader floader2
= { &dwritefontfileloadervtbl
};
2686 IDWriteFontFileLoader floader3
= { &dwritefontfileloadervtbl
};
2687 IDWriteFactory
*factory
, *factory2
;
2688 IDWriteFontFileLoader
*loader
;
2689 IDWriteFontFile
*file
, *file2
;
2691 DWRITE_FONT_FILE_TYPE file_type
;
2692 DWRITE_FONT_FACE_TYPE face_type
;
2694 IDWriteFontFace
*face
, *face2
;
2697 UINT32 codePoints
[1] = {0xa8};
2703 path
= create_testfontfile(test_fontfile
);
2705 factory
= create_factory();
2706 factory2
= create_factory();
2708 if (0) { /* crashes on win10 */
2709 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, NULL
);
2710 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2712 /* local loader is accepted too */
2713 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
2714 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2716 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
2717 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2719 hr
= IDWriteFontFile_GetReferenceKey(file
, &key
, &key_size
);
2720 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2722 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, key
, key_size
, loader
, &file2
);
2723 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2725 IDWriteFontFile_Release(file2
);
2726 IDWriteFontFile_Release(file
);
2727 IDWriteFontFileLoader_Release(loader
);
2729 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
2730 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2731 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader2
);
2732 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2733 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &floader
);
2734 ok(hr
== DWRITE_E_ALREADYREGISTERED
, "got 0x%08x\n", hr
);
2735 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
2736 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2739 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &file
);
2740 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2741 IDWriteFontFile_Release(file
);
2743 file
= (void*)0xdeadbeef;
2744 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader3
, &file
);
2745 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2746 ok(file
== NULL
, "got %p\n", file
);
2748 file
= (void*)0xdeadbeef;
2749 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, NULL
, &file
);
2750 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2751 ok(file
== NULL
, "got %p\n", file
);
2754 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, "test", 4, &floader
, &file
);
2755 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2757 file_type
= DWRITE_FONT_FILE_TYPE_TRUETYPE
;
2758 face_type
= DWRITE_FONT_FACE_TYPE_TRUETYPE
;
2761 hr
= IDWriteFontFile_Analyze(file
, &support
, &file_type
, &face_type
, &count
);
2762 ok(hr
== 0x8faecafe, "got 0x%08x\n", hr
);
2763 ok(support
== FALSE
, "got %i\n", support
);
2764 ok(file_type
== DWRITE_FONT_FILE_TYPE_UNKNOWN
, "got %i\n", file_type
);
2765 ok(face_type
== DWRITE_FONT_FACE_TYPE_UNKNOWN
, "got %i\n", face_type
);
2766 ok(count
== 0, "got %i\n", count
);
2768 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_CFF
, 1, &file
, 0, 0, &face
);
2769 ok(hr
== 0x8faecafe, "got 0x%08x\n", hr
);
2770 IDWriteFontFile_Release(file
);
2772 fontrsrc
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
2773 ok(fontrsrc
!= NULL
, "Failed to find font resource\n");
2775 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &fontrsrc
, sizeof(HRSRC
), &rloader
, &file
);
2776 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2778 file_type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
2779 face_type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
2782 hr
= IDWriteFontFile_Analyze(file
, &support
, &file_type
, &face_type
, &count
);
2783 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2784 ok(support
== TRUE
, "got %i\n", support
);
2785 ok(file_type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", file_type
);
2786 ok(face_type
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face_type
);
2787 ok(count
== 1, "got %i\n", count
);
2790 face
= (void*)0xdeadbeef;
2791 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 1, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
2792 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2793 ok(face
== NULL
, "got %p\n", face
);
2795 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
2796 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2798 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2799 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2800 /* fontface instances are reused starting with win7 */
2801 ok(face
== face2
|| broken(face
!= face2
), "got %p, %p\n", face
, face2
);
2802 IDWriteFontFace_Release(face2
);
2804 /* file was created with different factory */
2806 hr
= IDWriteFactory_CreateFontFace(factory2
, face_type
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2808 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2810 IDWriteFontFace_Release(face2
);
2813 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &fontrsrc
, sizeof(HRSRC
), &rloader
, &file2
);
2814 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2815 ok(file
!= file2
, "got %p, %p\n", file
, file2
);
2817 hr
= IDWriteFactory_CreateFontFace(factory
, face_type
, 1, &file2
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face2
);
2818 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2819 /* fontface instances are reused starting with win7 */
2820 ok(face
== face2
|| broken(face
!= face2
), "got %p, %p\n", face
, face2
);
2821 IDWriteFontFace_Release(face2
);
2822 IDWriteFontFile_Release(file2
);
2824 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 0, NULL
);
2825 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2827 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 0, NULL
);
2828 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2830 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 0, indices
);
2831 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2833 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 0, indices
);
2834 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
2836 indices
[0] = indices
[1] = 11;
2837 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 1, indices
);
2838 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2839 ok(indices
[0] == 0, "got index %i\n", indices
[0]);
2840 ok(indices
[1] == 11, "got index %i\n", indices
[1]);
2842 if (0) /* crashes on native */
2843 hr
= IDWriteFontFace_GetGlyphIndices(face
, NULL
, 1, NULL
);
2845 hr
= IDWriteFontFace_GetGlyphIndices(face
, codePoints
, 1, indices
);
2846 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2847 ok(indices
[0] == 6, "got index %i\n", indices
[0]);
2848 IDWriteFontFace_Release(face
);
2849 IDWriteFontFile_Release(file
);
2851 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
2852 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2853 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader
);
2854 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2855 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &floader2
);
2856 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2857 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
2858 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2860 IDWriteFactory_Release(factory2
);
2861 IDWriteFactory_Release(factory
);
2862 DELETE_FONTFILE(path
);
2865 static void test_CreateFontFileReference(void)
2868 IDWriteFontFile
*ffile
= NULL
;
2870 DWRITE_FONT_FILE_TYPE type
;
2871 DWRITE_FONT_FACE_TYPE face
;
2873 IDWriteFontFace
*fface
= NULL
;
2874 IDWriteFactory
*factory
;
2877 path
= create_testfontfile(test_fontfile
);
2878 factory
= create_factory();
2880 ffile
= (void*)0xdeadbeef;
2881 hr
= IDWriteFactory_CreateFontFileReference(factory
, NULL
, NULL
, &ffile
);
2882 ok(hr
== E_INVALIDARG
, "got 0x%08x\n",hr
);
2883 ok(ffile
== NULL
, "got %p\n", ffile
);
2885 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &ffile
);
2886 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
2889 type
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
2890 face
= DWRITE_FONT_FACE_TYPE_CFF
;
2892 hr
= IDWriteFontFile_Analyze(ffile
, &support
, &type
, &face
, &count
);
2893 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2894 ok(support
== TRUE
, "got %i\n", support
);
2895 ok(type
== DWRITE_FONT_FILE_TYPE_TRUETYPE
, "got %i\n", type
);
2896 ok(face
== DWRITE_FONT_FACE_TYPE_TRUETYPE
, "got %i\n", face
);
2897 ok(count
== 1, "got %i\n", count
);
2899 hr
= IDWriteFactory_CreateFontFace(factory
, face
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fface
);
2900 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2902 IDWriteFontFace_Release(fface
);
2903 IDWriteFontFile_Release(ffile
);
2904 IDWriteFactory_Release(factory
);
2906 DELETE_FONTFILE(path
);
2909 static void test_shared_isolated(void)
2911 IDWriteFactory
*isolated
, *isolated2
;
2912 IDWriteFactory
*shared
, *shared2
;
2917 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
2918 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2919 ok(shared
!= NULL
, "got %p\n", shared
);
2920 IDWriteFactory_Release(shared
);
2922 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared
);
2923 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2925 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
2926 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2927 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
2928 IDWriteFactory_Release(shared2
);
2930 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IUnknown
, (IUnknown
**)&shared2
);
2931 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2932 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
2934 IDWriteFactory_Release(shared
);
2935 IDWriteFactory_Release(shared2
);
2937 /* we got 2 references, released 2 - still same pointer is returned */
2938 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&shared2
);
2939 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2940 ok(shared
== shared2
, "got %p, and %p\n", shared
, shared2
);
2941 IDWriteFactory_Release(shared2
);
2943 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated
);
2944 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2946 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
2947 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2948 ok(isolated
!= isolated2
, "got %p, and %p\n", isolated
, isolated2
);
2949 IDWriteFactory_Release(isolated2
);
2951 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IUnknown
, (IUnknown
**)&isolated2
);
2952 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2953 IDWriteFactory_Release(isolated2
);
2955 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
+1, &IID_IDWriteFactory
, (IUnknown
**)&isolated2
);
2956 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2957 ok(shared
!= isolated2
, "got %p, and %p\n", shared
, isolated2
);
2959 IDWriteFactory_Release(isolated
);
2960 IDWriteFactory_Release(isolated2
);
2963 static void test_GetUnicodeRanges(void)
2965 DWRITE_UNICODE_RANGE
*ranges
, r
;
2966 IDWriteFontFile
*ffile
= NULL
;
2967 IDWriteFontFace1
*fontface1
;
2968 IDWriteFontFace
*fontface
;
2969 IDWriteFactory
*factory
;
2974 factory
= create_factory();
2976 hr
= IDWriteFactory_RegisterFontFileLoader(factory
, &rloader
);
2977 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2979 font
= FindResourceA(GetModuleHandleA(NULL
), (LPCSTR
)MAKEINTRESOURCE(1), (LPCSTR
)RT_RCDATA
);
2980 ok(font
!= NULL
, "Failed to find font resource\n");
2982 hr
= IDWriteFactory_CreateCustomFontFileReference(factory
, &font
, sizeof(HRSRC
), &rloader
, &ffile
);
2983 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2985 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &ffile
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
2986 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2987 IDWriteFontFile_Release(ffile
);
2989 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
2990 IDWriteFontFace_Release(fontface
);
2992 win_skip("GetUnicodeRanges() is not supported.\n");
2993 IDWriteFactory_Release(factory
);
2998 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 0, NULL
, &count
);
2999 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
3000 ok(count
> 0, "got %u\n", count
);
3003 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, NULL
, &count
);
3004 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3005 ok(count
== 0, "got %u\n", count
);
3008 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, &r
, &count
);
3009 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
3010 ok(count
> 1, "got %u\n", count
);
3012 ranges
= heap_alloc(count
*sizeof(DWRITE_UNICODE_RANGE
));
3013 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, count
, ranges
, &count
);
3014 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3016 ranges
[0].first
= ranges
[0].last
= 0;
3017 hr
= IDWriteFontFace1_GetUnicodeRanges(fontface1
, 1, ranges
, &count
);
3018 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
3019 ok(ranges
[0].first
!= 0 && ranges
[0].last
!= 0, "got 0x%x-0x%0x\n", ranges
[0].first
, ranges
[0].last
);
3023 hr
= IDWriteFactory_UnregisterFontFileLoader(factory
, &rloader
);
3024 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3026 IDWriteFontFace1_Release(fontface1
);
3027 IDWriteFactory_Release(factory
);
3030 static void test_GetFontFromFontFace(void)
3032 IDWriteFontFace
*fontface
, *fontface2
;
3033 IDWriteFontCollection
*collection
;
3034 IDWriteFont
*font
, *font2
, *font3
;
3035 IDWriteFontFamily
*family
;
3036 IDWriteFactory
*factory
;
3037 IDWriteFontFile
*file
;
3041 factory
= create_factory();
3043 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
3044 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3046 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
3047 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3049 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
3050 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
3051 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3053 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3054 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3057 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font2
);
3058 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3059 ok(font2
!= font
, "got %p, %p\n", font2
, font
);
3062 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font3
);
3063 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3064 ok(font3
!= font
&& font3
!= font2
, "got %p, %p, %p\n", font3
, font2
, font
);
3066 hr
= IDWriteFont_CreateFontFace(font2
, &fontface2
);
3067 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3068 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
3069 IDWriteFontFace_Release(fontface2
);
3071 hr
= IDWriteFont_CreateFontFace(font3
, &fontface2
);
3072 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3073 ok(fontface2
== fontface
, "got %p, %p\n", fontface2
, fontface
);
3074 IDWriteFontFace_Release(fontface2
);
3075 IDWriteFontFace_Release(fontface
);
3076 IDWriteFont_Release(font3
);
3077 IDWriteFactory_Release(factory
);
3079 /* fontface that wasn't created from this collection */
3080 factory
= create_factory();
3081 path
= create_testfontfile(test_fontfile
);
3083 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3084 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3086 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3087 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3088 IDWriteFontFile_Release(file
);
3090 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font3
);
3091 ok(hr
== DWRITE_E_NOFONT
, "got 0x%08x\n", hr
);
3092 ok(font3
== NULL
, "got %p\n", font3
);
3093 IDWriteFontFace_Release(fontface
);
3095 IDWriteFont_Release(font
);
3096 IDWriteFont_Release(font2
);
3097 IDWriteFontFamily_Release(family
);
3098 IDWriteFontCollection_Release(collection
);
3099 IDWriteFactory_Release(factory
);
3100 DELETE_FONTFILE(path
);
3103 static void test_GetFirstMatchingFont(void)
3105 DWRITE_FONT_SIMULATIONS simulations
;
3106 IDWriteFontCollection
*collection
;
3107 IDWriteFontFamily
*family
;
3108 IDWriteFont
*font
, *font2
;
3109 IDWriteFactory
*factory
;
3112 factory
= create_factory();
3114 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
3115 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3117 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
3118 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3120 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
3121 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
3122 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3124 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
3125 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font2
);
3126 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3127 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
3128 IDWriteFont_Release(font
);
3129 IDWriteFont_Release(font2
);
3131 /* out-of-range font props are allowed */
3132 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, 1000, DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
3133 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3134 IDWriteFont_Release(font
);
3136 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
, 10, DWRITE_FONT_STYLE_NORMAL
, &font
);
3137 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3138 IDWriteFont_Release(font
);
3140 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STRETCH_NORMAL
,
3142 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3143 IDWriteFont_Release(font
);
3145 IDWriteFontFamily_Release(family
);
3147 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_ITALIC
);
3148 simulations
= IDWriteFont_GetSimulations(font
);
3149 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "%d\n", simulations
);
3150 IDWriteFont_Release(font
);
3152 IDWriteFontCollection_Release(collection
);
3153 IDWriteFactory_Release(factory
);
3156 static void test_GetMatchingFonts(void)
3158 IDWriteFontCollection
*collection
;
3159 IDWriteFontFamily
*family
;
3160 IDWriteFactory
*factory
;
3161 IDWriteFontList
*fontlist
, *fontlist2
;
3162 IDWriteFontList1
*fontlist1
;
3165 factory
= create_factory();
3167 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
3168 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3170 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
3171 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3173 /* out-of-range font props are allowed */
3174 hr
= IDWriteFontFamily_GetMatchingFonts(family
, 1000, DWRITE_FONT_STRETCH_NORMAL
,
3175 DWRITE_FONT_STYLE_NORMAL
, &fontlist
);
3176 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3177 IDWriteFontList_Release(fontlist
);
3179 hr
= IDWriteFontFamily_GetMatchingFonts(family
, DWRITE_FONT_WEIGHT_NORMAL
, 10,
3180 DWRITE_FONT_STYLE_NORMAL
, &fontlist
);
3181 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3182 IDWriteFontList_Release(fontlist
);
3184 hr
= IDWriteFontFamily_GetMatchingFonts(family
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STRETCH_NORMAL
,
3186 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3187 IDWriteFontList_Release(fontlist
);
3189 hr
= IDWriteFontFamily_GetMatchingFonts(family
, DWRITE_FONT_WEIGHT_NORMAL
,
3190 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &fontlist
);
3191 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3193 hr
= IDWriteFontFamily_GetMatchingFonts(family
, DWRITE_FONT_WEIGHT_NORMAL
,
3194 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &fontlist2
);
3195 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3196 ok(fontlist
!= fontlist2
, "got %p, %p\n", fontlist
, fontlist2
);
3197 IDWriteFontList_Release(fontlist2
);
3199 hr
= IDWriteFontList_QueryInterface(fontlist
, &IID_IDWriteFontList1
, (void**)&fontlist1
);
3201 IDWriteFontFaceReference
*ref
, *ref1
;
3205 count
= IDWriteFontList1_GetFontCount(fontlist1
);
3206 ok(count
> 0, "got %u\n", count
);
3208 font
= (void*)0xdeadbeef;
3209 hr
= IDWriteFontList1_GetFont(fontlist1
, ~0u, &font
);
3210 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
3211 ok(font
== NULL
, "got %p\n", font
);
3213 font
= (void*)0xdeadbeef;
3214 hr
= IDWriteFontList1_GetFont(fontlist1
, count
, &font
);
3215 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
3216 ok(font
== NULL
, "got %p\n", font
);
3218 hr
= IDWriteFontList1_GetFont(fontlist1
, 0, &font
);
3219 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3220 IDWriteFont3_Release(font
);
3222 hr
= IDWriteFontList1_GetFontFaceReference(fontlist1
, 0, &ref
);
3223 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3225 hr
= IDWriteFontList1_GetFontFaceReference(fontlist1
, 0, &ref1
);
3226 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3227 ok(ref
!= ref1
, "got %p, %p\n", ref
, ref1
);
3229 IDWriteFontFaceReference_Release(ref1
);
3230 IDWriteFontFaceReference_Release(ref
);
3231 IDWriteFontList1_Release(fontlist1
);
3234 win_skip("IDWriteFontList1 is not supported.\n");
3236 IDWriteFontList_Release(fontlist
);
3237 IDWriteFontFamily_Release(family
);
3239 IDWriteFontCollection_Release(collection
);
3240 IDWriteFactory_Release(factory
);
3243 static void test_GetInformationalStrings(void)
3245 IDWriteLocalizedStrings
*strings
, *strings2
;
3246 IDWriteFontCollection
*collection
;
3247 IDWriteFontFamily
*family
;
3248 IDWriteFactory
*factory
;
3253 factory
= create_factory();
3255 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
3256 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3258 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
3259 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3261 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
3262 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
3263 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3266 strings
= (void*)0xdeadbeef;
3267 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
+1, &strings
, &exists
);
3268 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3269 ok(exists
== FALSE
, "got %d\n", exists
);
3270 ok(strings
== NULL
, "got %p\n", strings
);
3274 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_NONE
, &strings
, &exists
);
3275 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3276 ok(exists
== FALSE
, "got %d\n", exists
);
3280 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings
, &exists
);
3281 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3282 ok(exists
== TRUE
, "got %d\n", exists
);
3284 /* strings instance is not reused */
3286 hr
= IDWriteFont_GetInformationalStrings(font
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &strings2
, &exists
);
3287 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3288 ok(strings2
!= strings
, "got %p, %p\n", strings2
, strings
);
3290 IDWriteLocalizedStrings_Release(strings
);
3291 IDWriteLocalizedStrings_Release(strings2
);
3292 IDWriteFont_Release(font
);
3293 IDWriteFontFamily_Release(family
);
3294 IDWriteFontCollection_Release(collection
);
3295 IDWriteFactory_Release(factory
);
3298 static void test_GetGdiInterop(void)
3300 IDWriteGdiInterop
*interop
, *interop2
;
3301 IDWriteFactory
*factory
, *factory2
;
3306 factory
= create_factory();
3309 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
3310 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3313 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop2
);
3314 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3315 ok(interop
== interop2
, "got %p, %p\n", interop
, interop2
);
3316 IDWriteGdiInterop_Release(interop2
);
3318 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory2
);
3319 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3321 /* each factory gets its own interop */
3323 hr
= IDWriteFactory_GetGdiInterop(factory2
, &interop2
);
3324 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3325 ok(interop
!= interop2
, "got %p, %p\n", interop
, interop2
);
3327 /* release factory - interop still works */
3328 IDWriteFactory_Release(factory2
);
3330 memset(&logfont
, 0, sizeof(logfont
));
3331 logfont
.lfHeight
= 12;
3332 logfont
.lfWidth
= 12;
3333 logfont
.lfWeight
= FW_NORMAL
;
3334 logfont
.lfItalic
= 1;
3335 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
3337 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop2
, &logfont
, &font
);
3338 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3339 IDWriteFont_Release(font
);
3341 IDWriteGdiInterop_Release(interop2
);
3342 IDWriteGdiInterop_Release(interop
);
3343 IDWriteFactory_Release(factory
);
3346 static void test_CreateFontFaceFromHdc(void)
3348 IDWriteGdiInterop
*interop
;
3349 IDWriteFontFace
*fontface
;
3350 IDWriteFactory
*factory
;
3351 HFONT hfont
, oldhfont
;
3356 factory
= create_factory();
3359 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
3360 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3362 fontface
= (void*)0xdeadbeef;
3363 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, NULL
, &fontface
);
3364 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3365 ok(fontface
== NULL
, "got %p\n", fontface
);
3367 memset(&logfont
, 0, sizeof(logfont
));
3368 logfont
.lfHeight
= 12;
3369 logfont
.lfWidth
= 12;
3370 logfont
.lfWeight
= FW_NORMAL
;
3371 logfont
.lfItalic
= 1;
3372 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
3374 hfont
= CreateFontIndirectW(&logfont
);
3375 hdc
= CreateCompatibleDC(0);
3376 oldhfont
= SelectObject(hdc
, hfont
);
3379 hr
= IDWriteGdiInterop_CreateFontFaceFromHdc(interop
, hdc
, &fontface
);
3380 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3381 IDWriteFontFace_Release(fontface
);
3382 DeleteObject(SelectObject(hdc
, oldhfont
));
3385 IDWriteGdiInterop_Release(interop
);
3386 IDWriteFactory_Release(factory
);
3389 static void test_GetSimulations(void)
3391 DWRITE_FONT_SIMULATIONS simulations
;
3392 IDWriteGdiInterop
*interop
;
3393 IDWriteFontFace
*fontface
;
3394 IDWriteFactory
*factory
;
3399 factory
= create_factory();
3401 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
3402 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3404 memset(&logfont
, 0, sizeof(logfont
));
3405 logfont
.lfHeight
= 12;
3406 logfont
.lfWidth
= 12;
3407 logfont
.lfWeight
= FW_NORMAL
;
3408 logfont
.lfItalic
= 1;
3409 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
3411 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
3412 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3414 simulations
= IDWriteFont_GetSimulations(font
);
3415 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "got %d\n", simulations
);
3416 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3417 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3418 simulations
= IDWriteFontFace_GetSimulations(fontface
);
3419 ok(simulations
== DWRITE_FONT_SIMULATIONS_OBLIQUE
, "got %d\n", simulations
);
3420 IDWriteFontFace_Release(fontface
);
3421 IDWriteFont_Release(font
);
3423 memset(&logfont
, 0, sizeof(logfont
));
3424 logfont
.lfHeight
= 12;
3425 logfont
.lfWidth
= 12;
3426 logfont
.lfWeight
= FW_NORMAL
;
3427 logfont
.lfItalic
= 0;
3428 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
3430 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
3431 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3433 simulations
= IDWriteFont_GetSimulations(font
);
3434 ok(simulations
== DWRITE_FONT_SIMULATIONS_NONE
, "got %d\n", simulations
);
3435 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
3436 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3437 simulations
= IDWriteFontFace_GetSimulations(fontface
);
3438 ok(simulations
== DWRITE_FONT_SIMULATIONS_NONE
, "got %d\n", simulations
);
3439 IDWriteFontFace_Release(fontface
);
3440 IDWriteFont_Release(font
);
3442 IDWriteGdiInterop_Release(interop
);
3443 IDWriteFactory_Release(factory
);
3446 static void test_GetFaceNames(void)
3448 static const WCHAR obliqueW
[] = {'O','b','l','i','q','u','e',0};
3449 static const WCHAR enus2W
[] = {'e','n','-','U','s',0};
3450 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
3451 IDWriteLocalizedStrings
*strings
, *strings2
;
3452 IDWriteGdiInterop
*interop
;
3453 IDWriteFactory
*factory
;
3454 UINT32 count
, index
;
3461 factory
= create_factory();
3463 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
3464 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3466 memset(&logfont
, 0, sizeof(logfont
));
3467 logfont
.lfHeight
= 12;
3468 logfont
.lfWidth
= 12;
3469 logfont
.lfWeight
= FW_NORMAL
;
3470 logfont
.lfItalic
= 1;
3471 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
3473 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(interop
, &logfont
, &font
);
3474 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3476 hr
= IDWriteFont_GetFaceNames(font
, &strings
);
3477 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3479 hr
= IDWriteFont_GetFaceNames(font
, &strings2
);
3480 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3481 ok(strings
!= strings2
, "got %p, %p\n", strings2
, strings
);
3482 IDWriteLocalizedStrings_Release(strings2
);
3484 count
= IDWriteLocalizedStrings_GetCount(strings
);
3485 ok(count
== 1, "got %d\n", count
);
3489 hr
= IDWriteLocalizedStrings_FindLocaleName(strings
, enus2W
, &index
, &exists
);
3490 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3491 ok(index
== 0 && exists
, "got %d, %d\n", index
, exists
);
3494 hr
= IDWriteLocalizedStrings_GetLocaleNameLength(strings
, 1, &count
);
3495 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
3496 ok(count
== ~0, "got %d\n", count
);
3498 /* for simulated faces names are also simulated */
3500 hr
= IDWriteLocalizedStrings_GetLocaleName(strings
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
3501 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3502 ok(!lstrcmpW(buffW
, enusW
), "got %s\n", wine_dbgstr_w(buffW
));
3505 hr
= IDWriteLocalizedStrings_GetString(strings
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
3506 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3507 ok(!lstrcmpW(buffW
, obliqueW
), "got %s\n", wine_dbgstr_w(buffW
));
3508 IDWriteLocalizedStrings_Release(strings
);
3510 IDWriteFont_Release(font
);
3511 IDWriteGdiInterop_Release(interop
);
3512 IDWriteFactory_Release(factory
);
3521 static void test_TryGetFontTable(void)
3523 IDWriteLocalFontFileLoader
*localloader
;
3524 WIN32_FILE_ATTRIBUTE_DATA info
;
3525 const struct local_refkey
*key
;
3526 IDWriteFontFileLoader
*loader
;
3527 const void *table
, *table2
;
3528 IDWriteFontFace
*fontface
;
3529 void *context
, *context2
;
3530 IDWriteFactory
*factory
;
3531 IDWriteFontFile
*file
;
3532 WCHAR buffW
[MAX_PATH
];
3538 path
= create_testfontfile(test_fontfile
);
3540 factory
= create_factory();
3542 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3543 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3547 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
3548 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3549 ok(size
!= 0, "got %u\n", size
);
3551 ret
= GetFileAttributesExW(path
, GetFileExInfoStandard
, &info
);
3552 ok(ret
, "got %d\n", ret
);
3553 ok(!memcmp(&info
.ftLastWriteTime
, &key
->writetime
, sizeof(key
->writetime
)), "got wrong write time\n");
3555 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
3556 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3557 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
3558 IDWriteFontFileLoader_Release(loader
);
3560 hr
= IDWriteLocalFontFileLoader_GetFilePathLengthFromKey(localloader
, key
, size
, &len
);
3561 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3562 ok(lstrlenW(key
->name
) == len
, "path length %d\n", len
);
3564 hr
= IDWriteLocalFontFileLoader_GetFilePathFromKey(localloader
, key
, size
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
3565 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3566 ok(!lstrcmpW(buffW
, key
->name
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(key
->name
));
3567 IDWriteLocalFontFileLoader_Release(localloader
);
3569 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, 0, &fontface
);
3570 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3573 context
= (void*)0xdeadbeef;
3575 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_CMAP_TAG
, &table
, &size
, &context
, &exists
);
3576 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3577 ok(exists
== TRUE
, "got %d\n", exists
);
3578 ok(context
== NULL
&& table
!= NULL
, "cmap: context %p, table %p\n", context
, table
);
3581 context2
= (void*)0xdeadbeef;
3583 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_CMAP_TAG
, &table2
, &size
, &context2
, &exists
);
3584 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3585 ok(exists
== TRUE
, "got %d\n", exists
);
3586 ok(context2
== context
&& table2
== table
, "cmap: context2 %p, table2 %p\n", context2
, table2
);
3588 IDWriteFontFace_ReleaseFontTable(fontface
, context2
);
3589 IDWriteFontFace_ReleaseFontTable(fontface
, context
);
3591 /* table does not exist */
3593 context
= (void*)0xdeadbeef;
3594 table
= (void*)0xdeadbeef;
3595 hr
= IDWriteFontFace_TryGetFontTable(fontface
, 0xabababab, &table
, &size
, &context
, &exists
);
3596 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3597 ok(exists
== FALSE
, "got %d\n", exists
);
3598 ok(context
== NULL
&& table
== NULL
, "got context %p, table pointer %p\n", context
, table
);
3600 IDWriteFontFace_Release(fontface
);
3601 IDWriteFontFile_Release(file
);
3602 IDWriteFactory_Release(factory
);
3603 DELETE_FONTFILE(path
);
3606 static void test_ConvertFontToLOGFONT(void)
3608 IDWriteFactory
*factory
, *factory2
;
3609 IDWriteFontCollection
*collection
;
3610 IDWriteGdiInterop
*interop
;
3611 IDWriteFontFamily
*family
;
3618 factory
= create_factory();
3619 factory2
= create_factory();
3622 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
3623 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3625 hr
= IDWriteFactory_GetSystemFontCollection(factory2
, &collection
, FALSE
);
3626 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3628 hr
= IDWriteFontCollection_GetFontFamily(collection
, 0, &family
);
3629 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3631 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
3632 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
3633 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3635 if (0) { /* crashes on native */
3636 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, NULL
, NULL
);
3637 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, &logfont
, NULL
);
3638 IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, font
, NULL
, &system
);
3641 memset(&logfont
, 0xcc, sizeof(logfont
));
3643 hr
= IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, NULL
, &logfont
, &system
);
3644 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3645 ok(!system
, "got %d\n", system
);
3646 ok(logfont
.lfFaceName
[0] == 0, "got face name %s\n", wine_dbgstr_w(logfont
.lfFaceName
));
3648 count
= IDWriteFontCollection_GetFontFamilyCount(collection
);
3649 for (i
= 0; i
< count
; i
++) {
3650 WCHAR nameW
[128], familynameW
[64], facenameW
[64];
3651 IDWriteLocalizedStrings
*names
;
3652 DWRITE_FONT_SIMULATIONS sim
;
3653 IDWriteFontFamily
*family
;
3654 UINT32 font_count
, j
;
3658 hr
= IDWriteFontCollection_GetFontFamily(collection
, i
, &family
);
3659 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3661 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
3662 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3664 get_enus_string(names
, familynameW
, sizeof(familynameW
)/sizeof(familynameW
[0]));
3665 IDWriteLocalizedStrings_Release(names
);
3667 font_count
= IDWriteFontFamily_GetFontCount(family
);
3669 for (j
= 0; j
< font_count
; j
++) {
3670 static const WCHAR spaceW
[] = {' ', 0};
3672 hr
= IDWriteFontFamily_GetFont(family
, j
, &font
);
3673 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3675 hr
= IDWriteFont_GetFaceNames(font
, &names
);
3676 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3678 get_enus_string(names
, facenameW
, sizeof(facenameW
)/sizeof(facenameW
[0]));
3679 IDWriteLocalizedStrings_Release(names
);
3681 lstrcpyW(nameW
, familynameW
);
3682 lstrcatW(nameW
, spaceW
);
3683 lstrcatW(nameW
, facenameW
);
3686 memset(&logfont
, 0xcc, sizeof(logfont
));
3687 hr
= IDWriteGdiInterop_ConvertFontToLOGFONT(interop
, font
, &logfont
, &system
);
3688 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3689 ok(system
, "got %d\n", system
);
3691 sim
= IDWriteFont_GetSimulations(font
);
3693 get_logfont_from_font(font
, &lf
);
3694 ok(logfont
.lfWeight
== lf
.lfWeight
, "%s: unexpected lfWeight %d, expected lfWeight %d, font weight %d, "
3695 "bold simulation %s\n", wine_dbgstr_w(nameW
), logfont
.lfWeight
, lf
.lfWeight
, IDWriteFont_GetWeight(font
),
3696 sim
& DWRITE_FONT_SIMULATIONS_BOLD
? "yes" : "no");
3697 ok(logfont
.lfItalic
== lf
.lfItalic
, "%s: unexpected italic flag %d, oblique simulation %s\n",
3698 wine_dbgstr_w(nameW
), logfont
.lfItalic
, sim
& DWRITE_FONT_SIMULATIONS_OBLIQUE
? "yes" : "no");
3699 ok(!lstrcmpW(logfont
.lfFaceName
, lf
.lfFaceName
), "%s: unexpected facename %s, expected %s\n",
3700 wine_dbgstr_w(nameW
), wine_dbgstr_w(logfont
.lfFaceName
), wine_dbgstr_w(lf
.lfFaceName
));
3702 ok(logfont
.lfOutPrecision
== OUT_OUTLINE_PRECIS
, "%s: unexpected output precision %d\n", wine_dbgstr_w(nameW
),
3703 logfont
.lfOutPrecision
);
3704 ok(logfont
.lfClipPrecision
== CLIP_DEFAULT_PRECIS
, "%s: unexpected clipping precision %d\n", wine_dbgstr_w(nameW
),
3705 logfont
.lfClipPrecision
);
3706 ok(logfont
.lfQuality
== DEFAULT_QUALITY
, "%s: unexpected quality %d\n", wine_dbgstr_w(nameW
), logfont
.lfQuality
);
3707 ok(logfont
.lfPitchAndFamily
== DEFAULT_PITCH
, "%s: unexpected pitch %d\n", wine_dbgstr_w(nameW
),
3708 logfont
.lfPitchAndFamily
);
3710 IDWriteFont_Release(font
);
3713 IDWriteFontFamily_Release(family
);
3716 IDWriteFactory_Release(factory2
);
3718 IDWriteFontCollection_Release(collection
);
3719 IDWriteFontFamily_Release(family
);
3720 IDWriteFont_Release(font
);
3721 IDWriteGdiInterop_Release(interop
);
3722 IDWriteFactory_Release(factory
);
3725 static void test_CreateStreamFromKey(void)
3727 IDWriteLocalFontFileLoader
*localloader
;
3728 IDWriteFontFileStream
*stream
, *stream2
;
3729 IDWriteFontFileLoader
*loader
;
3730 IDWriteFactory
*factory
;
3731 IDWriteFontFile
*file
;
3738 factory
= create_factory();
3740 path
= create_testfontfile(test_fontfile
);
3742 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3743 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3747 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
3748 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3749 ok(size
!= 0, "got %u\n", size
);
3751 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
3752 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3753 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
3754 IDWriteFontFileLoader_Release(loader
);
3756 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
3757 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3758 EXPECT_REF(stream
, 1);
3760 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream2
);
3761 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3762 ok(stream
== stream2
|| broken(stream
!= stream2
) /* Win7 SP0 */, "got %p, %p\n", stream
, stream2
);
3763 if (stream
== stream2
)
3764 EXPECT_REF(stream
, 2);
3765 IDWriteFontFileStream_Release(stream
);
3766 IDWriteFontFileStream_Release(stream2
);
3768 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
3769 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3770 EXPECT_REF(stream
, 1);
3773 hr
= IDWriteFontFileStream_GetLastWriteTime(stream
, &writetime
);
3774 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3775 ok(writetime
!= 0, "got %08x%08x\n", (UINT
)(writetime
>> 32), (UINT
)writetime
);
3777 IDWriteFontFileStream_Release(stream
);
3778 IDWriteFontFile_Release(file
);
3780 IDWriteLocalFontFileLoader_Release(localloader
);
3781 IDWriteFactory_Release(factory
);
3782 DELETE_FONTFILE(path
);
3785 static void test_ReadFileFragment(void)
3787 IDWriteLocalFontFileLoader
*localloader
;
3788 IDWriteFontFileStream
*stream
;
3789 IDWriteFontFileLoader
*loader
;
3790 IDWriteFactory
*factory
;
3791 IDWriteFontFile
*file
;
3792 const void *fragment
, *fragment2
;
3793 void *key
, *context
, *context2
;
3799 factory
= create_factory();
3801 path
= create_testfontfile(test_fontfile
);
3803 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3804 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3808 hr
= IDWriteFontFile_GetReferenceKey(file
, (const void**)&key
, &size
);
3809 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3810 ok(size
!= 0, "got %u\n", size
);
3812 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
3813 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3814 IDWriteFontFileLoader_QueryInterface(loader
, &IID_IDWriteLocalFontFileLoader
, (void**)&localloader
);
3815 IDWriteFontFileLoader_Release(loader
);
3817 hr
= IDWriteLocalFontFileLoader_CreateStreamFromKey(localloader
, key
, size
, &stream
);
3818 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3820 hr
= IDWriteFontFileStream_GetFileSize(stream
, &filesize
);
3821 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3823 /* reading past the end of the stream */
3824 fragment
= (void*)0xdeadbeef;
3825 context
= (void*)0xdeadbeef;
3826 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
+1, &context
);
3827 ok(hr
== E_FAIL
, "got 0x%08x\n", hr
);
3828 ok(context
== NULL
, "got %p\n", context
);
3829 ok(fragment
== NULL
, "got %p\n", fragment
);
3831 fragment
= (void*)0xdeadbeef;
3832 context
= (void*)0xdeadbeef;
3833 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
, &context
);
3834 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3835 ok(context
== NULL
, "got %p\n", context
);
3836 ok(fragment
!= NULL
, "got %p\n", fragment
);
3838 fragment2
= (void*)0xdeadbeef;
3839 context2
= (void*)0xdeadbeef;
3840 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment2
, 0, filesize
, &context2
);
3841 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3842 ok(context2
== NULL
, "got %p\n", context2
);
3843 ok(fragment
== fragment2
, "got %p, %p\n", fragment
, fragment2
);
3845 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
3846 IDWriteFontFileStream_ReleaseFileFragment(stream
, context2
);
3848 /* fragment is released, try again */
3849 fragment
= (void*)0xdeadbeef;
3850 context
= (void*)0xdeadbeef;
3851 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &fragment
, 0, filesize
, &context
);
3852 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3853 ok(context
== NULL
, "got %p\n", context
);
3854 ok(fragment
== fragment2
, "got %p, %p\n", fragment
, fragment2
);
3855 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
3857 IDWriteFontFile_Release(file
);
3858 IDWriteFontFileStream_Release(stream
);
3859 IDWriteLocalFontFileLoader_Release(localloader
);
3860 IDWriteFactory_Release(factory
);
3861 DELETE_FONTFILE(path
);
3864 static void test_GetDesignGlyphMetrics(void)
3866 DWRITE_GLYPH_METRICS metrics
[2];
3867 IDWriteFontFace
*fontface
;
3868 IDWriteFactory
*factory
;
3869 IDWriteFontFile
*file
;
3875 factory
= create_factory();
3877 path
= create_testfontfile(test_fontfile
);
3879 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3880 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3882 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
,
3883 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3884 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3885 IDWriteFontFile_Release(file
);
3889 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &codepoint
, 1, &indices
[0]);
3890 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3891 ok(indices
[0] > 0, "got %u\n", indices
[0]);
3893 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, NULL
, 0, metrics
, FALSE
);
3894 ok(hr
== E_INVALIDARG
, "got 0x%08x\n",hr
);
3896 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, NULL
, 1, metrics
, FALSE
);
3897 ok(hr
== E_INVALIDARG
, "got 0x%08x\n",hr
);
3899 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, indices
, 0, metrics
, FALSE
);
3900 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3902 /* missing glyphs are ignored */
3904 memset(metrics
, 0xcc, sizeof(metrics
));
3905 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, indices
, 2, metrics
, FALSE
);
3906 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
3907 ok(metrics
[0].advanceWidth
== 1000, "got %d\n", metrics
[0].advanceWidth
);
3908 ok(metrics
[1].advanceWidth
== 0, "got %d\n", metrics
[1].advanceWidth
);
3910 IDWriteFontFace_Release(fontface
);
3911 IDWriteFactory_Release(factory
);
3912 DELETE_FONTFILE(path
);
3915 static void test_IsMonospacedFont(void)
3917 static const WCHAR courierW
[] = {'C','o','u','r','i','e','r',' ','N','e','w',0};
3918 IDWriteFontCollection
*collection
;
3919 IDWriteFactory
*factory
;
3924 factory
= create_factory();
3925 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
3926 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3929 hr
= IDWriteFontCollection_FindFamilyName(collection
, courierW
, &index
, &exists
);
3930 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3932 IDWriteFontFamily
*family
;
3933 IDWriteFont1
*font1
;
3936 hr
= IDWriteFontCollection_GetFontFamily(collection
, index
, &family
);
3937 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3939 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
,
3940 DWRITE_FONT_STRETCH_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, &font
);
3941 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3942 IDWriteFontFamily_Release(family
);
3944 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
3946 IDWriteFontFace1
*fontface1
;
3947 IDWriteFontFace
*fontface
;
3950 is_monospaced
= IDWriteFont1_IsMonospacedFont(font1
);
3951 ok(is_monospaced
, "got %d\n", is_monospaced
);
3953 hr
= IDWriteFont1_CreateFontFace(font1
, &fontface
);
3954 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3955 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
3956 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3957 is_monospaced
= IDWriteFontFace1_IsMonospacedFont(fontface1
);
3958 ok(is_monospaced
, "got %d\n", is_monospaced
);
3959 IDWriteFontFace1_Release(fontface1
);
3961 IDWriteFontFace_Release(fontface
);
3962 IDWriteFont1_Release(font1
);
3965 win_skip("IsMonospacedFont() is not supported.\n");
3968 skip("Courier New font not found.\n");
3970 IDWriteFontCollection_Release(collection
);
3973 static void test_GetDesignGlyphAdvances(void)
3975 IDWriteFontFace1
*fontface1
;
3976 IDWriteFontFace
*fontface
;
3977 IDWriteFactory
*factory
;
3978 IDWriteFontFile
*file
;
3982 factory
= create_factory();
3984 path
= create_testfontfile(test_fontfile
);
3986 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
3987 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3989 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
,
3990 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
3991 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3992 IDWriteFontFile_Release(file
);
3994 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4002 hr
= IDWriteFontFace1_GetGlyphIndices(fontface1
, &codepoint
, 1, &index
);
4003 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4004 ok(index
> 0, "got %u\n", index
);
4007 hr
= IDWriteFontFace1_GetDesignGlyphAdvances(fontface1
, 1, &index
, &advance
, FALSE
);
4008 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4009 ok(advance
== 1000, "got %i\n", advance
);
4012 hr
= IDWriteFontFace1_GetDesignGlyphAdvances(fontface1
, 1, &index
, &advance
, TRUE
);
4013 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4015 ok(advance
== 2048, "got %i\n", advance
);
4017 IDWriteFontFace1_Release(fontface1
);
4020 win_skip("GetDesignGlyphAdvances() is not supported.\n");
4022 IDWriteFontFace_Release(fontface
);
4023 IDWriteFactory_Release(factory
);
4024 DELETE_FONTFILE(path
);
4027 static void test_GetGlyphRunOutline(void)
4029 DWRITE_GLYPH_OFFSET offsets
[2];
4030 IDWriteFactory
*factory
;
4031 IDWriteFontFile
*file
;
4032 IDWriteFontFace
*face
;
4039 path
= create_testfontfile(test_fontfile
);
4040 factory
= create_factory();
4042 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
4043 ok(hr
== S_OK
, "got 0x%08x\n",hr
);
4045 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
4046 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4047 IDWriteFontFile_Release(file
);
4051 hr
= IDWriteFontFace_GetGlyphIndices(face
, &codepoint
, 1, glyphs
);
4052 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4053 ok(glyphs
[0] > 0, "got %u\n", glyphs
[0]);
4054 glyphs
[1] = glyphs
[0];
4056 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 2048.0, glyphs
, advances
, offsets
, 1, FALSE
, FALSE
, NULL
);
4057 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4059 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 2048.0, NULL
, NULL
, offsets
, 1, FALSE
, FALSE
, &test_geomsink
);
4060 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4065 offsets
[0].advanceOffset
= 1.0;
4066 offsets
[0].ascenderOffset
= 1.0;
4067 offsets
[1].advanceOffset
= 0.0;
4068 offsets
[1].ascenderOffset
= 0.0;
4070 /* default advances, no offsets */
4071 memset(g_startpoints
, 0, sizeof(g_startpoints
));
4072 g_startpoint_count
= 0;
4073 SET_EXPECT(setfillmode
);
4074 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 2, FALSE
, FALSE
, &test_geomsink
);
4075 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4076 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
4077 if (g_startpoint_count
== 2) {
4078 /* glyph advance of 500 is applied */
4079 ok(g_startpoints
[0].x
== 229.5 && g_startpoints
[0].y
== -629.0, "0: got (%.2f,%.2f)\n", g_startpoints
[0].x
, g_startpoints
[0].y
);
4080 ok(g_startpoints
[1].x
== 729.5 && g_startpoints
[1].y
== -629.0, "1: got (%.2f,%.2f)\n", g_startpoints
[1].x
, g_startpoints
[1].y
);
4082 CHECK_CALLED(setfillmode
);
4084 /* default advances, no offsets, RTL */
4085 memset(g_startpoints
, 0, sizeof(g_startpoints
));
4086 g_startpoint_count
= 0;
4087 SET_EXPECT(setfillmode
);
4088 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 2, FALSE
, TRUE
, &test_geomsink
);
4089 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4090 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
4091 if (g_startpoint_count
== 2) {
4092 /* advance is -500 now */
4093 ok(g_startpoints
[0].x
== -270.5 && g_startpoints
[0].y
== -629.0, "0: got (%.2f,%.2f)\n", g_startpoints
[0].x
, g_startpoints
[0].y
);
4094 ok(g_startpoints
[1].x
== -770.5 && g_startpoints
[1].y
== -629.0, "1: got (%.2f,%.2f)\n", g_startpoints
[1].x
, g_startpoints
[1].y
);
4096 CHECK_CALLED(setfillmode
);
4098 /* default advances, additional offsets */
4099 memset(g_startpoints
, 0, sizeof(g_startpoints
));
4100 g_startpoint_count
= 0;
4101 SET_EXPECT(setfillmode
);
4102 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, offsets
, 2, FALSE
, FALSE
, &test_geomsink
);
4103 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4104 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
4105 if (g_startpoint_count
== 2) {
4106 /* offsets applied to first contour */
4107 ok(g_startpoints
[0].x
== 230.5 && g_startpoints
[0].y
== -630.0, "0: got (%.2f,%.2f)\n", g_startpoints
[0].x
, g_startpoints
[0].y
);
4108 ok(g_startpoints
[1].x
== 729.5 && g_startpoints
[1].y
== -629.0, "1: got (%.2f,%.2f)\n", g_startpoints
[1].x
, g_startpoints
[1].y
);
4110 CHECK_CALLED(setfillmode
);
4112 /* default advances, additional offsets, RTL */
4113 memset(g_startpoints
, 0, sizeof(g_startpoints
));
4114 g_startpoint_count
= 0;
4115 SET_EXPECT(setfillmode
);
4116 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, offsets
, 2, FALSE
, TRUE
, &test_geomsink
);
4117 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4118 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
4119 if (g_startpoint_count
== 2) {
4120 ok(g_startpoints
[0].x
== -271.5 && g_startpoints
[0].y
== -630.0, "0: got (%.2f,%.2f)\n", g_startpoints
[0].x
, g_startpoints
[0].y
);
4121 ok(g_startpoints
[1].x
== -770.5 && g_startpoints
[1].y
== -629.0, "1: got (%.2f,%.2f)\n", g_startpoints
[1].x
, g_startpoints
[1].y
);
4123 CHECK_CALLED(setfillmode
);
4125 /* custom advances and offsets, offset turns total advance value to zero */
4126 memset(g_startpoints
, 0, sizeof(g_startpoints
));
4127 g_startpoint_count
= 0;
4128 SET_EXPECT(setfillmode
);
4129 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, advances
, offsets
, 2, FALSE
, FALSE
, &test_geomsink
);
4130 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4131 ok(g_startpoint_count
== 2, "got %d\n", g_startpoint_count
);
4132 if (g_startpoint_count
== 2) {
4133 ok(g_startpoints
[0].x
== 230.5 && g_startpoints
[0].y
== -630.0, "0: got (%.2f,%.2f)\n", g_startpoints
[0].x
, g_startpoints
[0].y
);
4134 ok(g_startpoints
[1].x
== 230.5 && g_startpoints
[1].y
== -629.0, "1: got (%.2f,%.2f)\n", g_startpoints
[1].x
, g_startpoints
[1].y
);
4136 CHECK_CALLED(setfillmode
);
4139 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 0, FALSE
, FALSE
, &test_geomsink2
);
4140 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4142 IDWriteFactory_Release(factory
);
4143 IDWriteFontFace_Release(face
);
4144 DELETE_FONTFILE(path
);
4147 factory
= create_factory();
4148 face
= create_fontface(factory
);
4152 hr
= IDWriteFontFace_GetGlyphIndices(face
, &codepoint
, 1, glyphs
);
4153 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4154 ok(glyphs
[0] > 0, "got %u\n", glyphs
[0]);
4156 SET_EXPECT(setfillmode
);
4157 hr
= IDWriteFontFace_GetGlyphRunOutline(face
, 1024.0, glyphs
, NULL
, NULL
, 1, FALSE
, FALSE
, &test_geomsink2
);
4158 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4159 CHECK_CALLED(setfillmode
);
4161 IDWriteFactory_Release(factory
);
4162 IDWriteFontFace_Release(face
);
4165 static void test_GetEudcFontCollection(void)
4167 IDWriteFontCollection
*coll
, *coll2
;
4168 IDWriteFactory1
*factory1
;
4169 IDWriteFactory
*factory
;
4172 factory
= create_factory();
4174 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory1
, (void**)&factory1
);
4175 IDWriteFactory_Release(factory
);
4177 win_skip("GetEudcFontCollection() is not supported.\n");
4181 hr
= IDWriteFactory1_GetEudcFontCollection(factory1
, &coll
, FALSE
);
4182 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4183 hr
= IDWriteFactory1_GetEudcFontCollection(factory1
, &coll2
, FALSE
);
4184 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4185 ok(coll
== coll2
, "got %p, %p\n", coll
, coll2
);
4186 IDWriteFontCollection_Release(coll
);
4187 IDWriteFontCollection_Release(coll2
);
4189 IDWriteFactory1_Release(factory1
);
4192 static void test_GetCaretMetrics(void)
4194 DWRITE_FONT_METRICS1 metrics
;
4195 IDWriteFontFace1
*fontface1
;
4196 DWRITE_CARET_METRICS caret
;
4197 IDWriteFontFace
*fontface
;
4198 IDWriteFactory
*factory
;
4199 IDWriteFontFile
*file
;
4204 path
= create_testfontfile(test_fontfile
);
4205 factory
= create_factory();
4207 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
4208 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4210 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
4211 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4212 IDWriteFontFile_Release(file
);
4214 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4215 IDWriteFontFace_Release(fontface
);
4217 win_skip("GetCaretMetrics() is not supported.\n");
4218 IDWriteFactory_Release(factory
);
4219 DELETE_FONTFILE(path
);
4223 memset(&caret
, 0xcc, sizeof(caret
));
4224 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
4225 ok(caret
.slopeRise
== 1, "got %d\n", caret
.slopeRise
);
4226 ok(caret
.slopeRun
== 0, "got %d\n", caret
.slopeRun
);
4227 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
4228 IDWriteFontFace1_Release(fontface1
);
4229 IDWriteFactory_Release(factory
);
4231 /* now with Tahoma Normal */
4232 factory
= create_factory();
4233 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
4234 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4235 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4236 IDWriteFont_Release(font
);
4237 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4238 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4239 IDWriteFontFace_Release(fontface
);
4241 memset(&caret
, 0xcc, sizeof(caret
));
4242 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
4243 ok(caret
.slopeRise
== 1, "got %d\n", caret
.slopeRise
);
4244 ok(caret
.slopeRun
== 0, "got %d\n", caret
.slopeRun
);
4245 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
4246 IDWriteFontFace1_Release(fontface1
);
4248 /* simulated italic */
4249 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_ITALIC
);
4250 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
4251 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4252 IDWriteFont_Release(font
);
4253 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4254 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4255 IDWriteFontFace_Release(fontface
);
4257 IDWriteFontFace1_GetMetrics(fontface1
, &metrics
);
4259 memset(&caret
, 0xcc, sizeof(caret
));
4260 IDWriteFontFace1_GetCaretMetrics(fontface1
, &caret
);
4261 ok(caret
.slopeRise
== metrics
.designUnitsPerEm
, "got %d\n", caret
.slopeRise
);
4262 ok(caret
.slopeRun
> 0, "got %d\n", caret
.slopeRun
);
4263 ok(caret
.offset
== 0, "got %d\n", caret
.offset
);
4264 IDWriteFontFace1_Release(fontface1
);
4266 IDWriteFactory_Release(factory
);
4267 DELETE_FONTFILE(path
);
4270 static void test_GetGlyphCount(void)
4272 IDWriteFontFace
*fontface
;
4273 IDWriteFactory
*factory
;
4274 IDWriteFontFile
*file
;
4279 path
= create_testfontfile(test_fontfile
);
4280 factory
= create_factory();
4282 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
4283 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4285 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
4286 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4287 IDWriteFontFile_Release(file
);
4289 count
= IDWriteFontFace_GetGlyphCount(fontface
);
4290 ok(count
== 7, "got %u\n", count
);
4292 IDWriteFontFace_Release(fontface
);
4293 IDWriteFactory_Release(factory
);
4294 DELETE_FONTFILE(path
);
4297 static void test_GetKerningPairAdjustments(void)
4299 IDWriteFontFace1
*fontface1
;
4300 IDWriteFontFace
*fontface
;
4301 IDWriteFactory
*factory
;
4302 IDWriteFontFile
*file
;
4306 path
= create_testfontfile(test_fontfile
);
4307 factory
= create_factory();
4309 hr
= IDWriteFactory_CreateFontFileReference(factory
, path
, NULL
, &file
);
4310 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4312 hr
= IDWriteFactory_CreateFontFace(factory
, DWRITE_FONT_FACE_TYPE_TRUETYPE
, 1, &file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &fontface
);
4313 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4314 IDWriteFontFile_Release(file
);
4316 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4318 INT32 adjustments
[1];
4320 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 0, NULL
, NULL
);
4321 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* win8 */, "got 0x%08x\n", hr
);
4323 if (0) /* crashes on native */
4324 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 1, NULL
, NULL
);
4327 hr
= IDWriteFontFace1_GetKerningPairAdjustments(fontface1
, 1, NULL
, adjustments
);
4328 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4329 ok(adjustments
[0] == 0, "got %d\n", adjustments
[0]);
4331 IDWriteFontFace1_Release(fontface1
);
4334 win_skip("GetKerningPairAdjustments() is not supported.\n");
4336 IDWriteFontFace_Release(fontface
);
4337 IDWriteFactory_Release(factory
);
4338 DELETE_FONTFILE(path
);
4341 static void test_CreateRenderingParams(void)
4343 IDWriteRenderingParams2
*params2
;
4344 IDWriteRenderingParams1
*params1
;
4345 IDWriteRenderingParams
*params
;
4346 DWRITE_RENDERING_MODE mode
;
4347 IDWriteFactory3
*factory3
;
4348 IDWriteFactory
*factory
;
4351 factory
= create_factory();
4353 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 1.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT
,
4354 DWRITE_RENDERING_MODE_DEFAULT
, ¶ms
);
4355 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4357 hr
= IDWriteRenderingParams_QueryInterface(params
, &IID_IDWriteRenderingParams1
, (void**)¶ms1
);
4361 /* test what enhanced contrast setting set by default to */
4362 enhcontrast
= IDWriteRenderingParams1_GetGrayscaleEnhancedContrast(params1
);
4363 ok(enhcontrast
== 1.0, "got %.2f\n", enhcontrast
);
4364 IDWriteRenderingParams1_Release(params1
);
4366 hr
= IDWriteRenderingParams_QueryInterface(params
, &IID_IDWriteRenderingParams2
, (void**)¶ms2
);
4368 DWRITE_GRID_FIT_MODE gridfit
;
4370 /* default gridfit mode */
4371 gridfit
= IDWriteRenderingParams2_GetGridFitMode(params2
);
4372 ok(gridfit
== DWRITE_GRID_FIT_MODE_DEFAULT
, "got %d\n", gridfit
);
4374 IDWriteRenderingParams2_Release(params2
);
4377 win_skip("IDWriteRenderingParams2 not supported.\n");
4380 win_skip("IDWriteRenderingParams1 not supported.\n");
4382 IDWriteRenderingParams_Release(params
);
4384 hr
= IDWriteFactory_CreateRenderingParams(factory
, ¶ms
);
4385 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4387 mode
= IDWriteRenderingParams_GetRenderingMode(params
);
4388 ok(mode
== DWRITE_RENDERING_MODE_DEFAULT
, "got %d\n", mode
);
4389 IDWriteRenderingParams_Release(params
);
4391 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory3
, (void**)&factory3
);
4393 IDWriteRenderingParams3
*params3
;
4395 hr
= IDWriteFactory3_CreateCustomRenderingParams(factory3
, 1.0f
, 0.0f
, 0.0f
, 1.0f
, DWRITE_PIXEL_GEOMETRY_FLAT
,
4396 DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
4397 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4399 hr
= IDWriteRenderingParams3_QueryInterface(params3
, &IID_IDWriteRenderingParams
, (void**)¶ms
);
4400 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4402 mode
= IDWriteRenderingParams_GetRenderingMode(params
);
4403 ok(mode
== DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
, "got %d\n", mode
);
4405 IDWriteRenderingParams_Release(params
);
4406 IDWriteRenderingParams3_Release(params3
);
4407 IDWriteFactory3_Release(factory3
);
4410 win_skip("IDWriteRenderingParams3 not supported.\n");
4412 IDWriteFactory_Release(factory
);
4415 static void test_CreateGlyphRunAnalysis(void)
4417 static const DWRITE_RENDERING_MODE rendermodes
[] = {
4418 DWRITE_RENDERING_MODE_ALIASED
,
4419 DWRITE_RENDERING_MODE_GDI_CLASSIC
,
4420 DWRITE_RENDERING_MODE_GDI_NATURAL
,
4421 DWRITE_RENDERING_MODE_NATURAL
,
4422 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
,
4425 IDWriteGlyphRunAnalysis
*analysis
, *analysis2
;
4426 IDWriteFactory
*factory
;
4427 DWRITE_GLYPH_RUN run
;
4428 IDWriteFontFace
*face
;
4429 UINT16 glyph
, glyphs
[10];
4434 DWRITE_GLYPH_OFFSET offsets
[2];
4435 DWRITE_GLYPH_METRICS metrics
;
4436 DWRITE_FONT_METRICS fm
;
4440 factory
= create_factory();
4441 face
= create_fontface(factory
);
4445 hr
= IDWriteFontFace_GetGlyphIndices(face
, &ch
, 1, &glyph
);
4446 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4447 ok(glyph
> 0, "got %u\n", glyph
);
4449 hr
= IDWriteFontFace_GetDesignGlyphMetrics(face
, &glyph
, 1, &metrics
, FALSE
);
4450 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4451 advances
[0] = metrics
.advanceWidth
;
4453 offsets
[0].advanceOffset
= 0.0;
4454 offsets
[0].ascenderOffset
= 0.0;
4456 run
.fontFace
= face
;
4457 run
.fontEmSize
= 24.0;
4459 run
.glyphIndices
= &glyph
;
4460 run
.glyphAdvances
= advances
;
4461 run
.glyphOffsets
= offsets
;
4462 run
.isSideways
= FALSE
;
4466 analysis
= (void*)0xdeadbeef;
4467 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 0.0, NULL
,
4468 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4469 0.0, 0.0, &analysis
);
4470 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4471 ok(analysis
== NULL
, "got %p\n", analysis
);
4473 /* negative ppdip */
4474 analysis
= (void*)0xdeadbeef;
4475 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, -1.0, NULL
,
4476 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4477 0.0, 0.0, &analysis
);
4478 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4479 ok(analysis
== NULL
, "got %p\n", analysis
);
4481 /* default mode is not allowed */
4482 analysis
= (void*)0xdeadbeef;
4483 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4484 DWRITE_RENDERING_MODE_DEFAULT
, DWRITE_MEASURING_MODE_NATURAL
,
4485 0.0, 0.0, &analysis
);
4486 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4487 ok(analysis
== NULL
, "got %p\n", analysis
);
4490 analysis
= (void*)0xdeadbeef;
4491 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4492 DWRITE_RENDERING_MODE_OUTLINE
, DWRITE_MEASURING_MODE_NATURAL
,
4493 0.0, 0.0, &analysis
);
4494 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4495 ok(analysis
== NULL
, "got %p\n", analysis
);
4497 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4498 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4499 0.0, 0.0, &analysis
);
4500 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4502 /* invalid texture type */
4503 memset(&rect
, 0xcc, sizeof(rect
));
4504 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
+1, &rect
);
4505 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
4506 ok(rect
.left
== 0 && rect
.right
== 0 &&
4507 rect
.top
== 0 && rect
.bottom
== 0, "unexpected rect\n");
4509 /* check how origin affects bounds */
4510 SetRectEmpty(&rect
);
4511 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
4512 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4513 ok(!IsRectEmpty(&rect
), "got empty rect\n");
4514 IDWriteGlyphRunAnalysis_Release(analysis
);
4517 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 2.0, NULL
,
4518 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4519 0.0, 0.0, &analysis
);
4520 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4521 SetRectEmpty(&rect2
);
4522 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect2
);
4523 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4524 ok(rect
.right
- rect
.left
< rect2
.right
- rect2
.left
, "expected wider rect\n");
4525 ok(rect
.bottom
- rect
.top
< rect2
.bottom
- rect2
.top
, "expected taller rect\n");
4526 IDWriteGlyphRunAnalysis_Release(analysis
);
4528 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4529 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4530 10.0, -5.0, &analysis
);
4531 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4533 SetRectEmpty(&rect2
);
4534 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect2
);
4535 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4536 ok(!IsRectEmpty(&rect2
), "got empty rect\n");
4537 IDWriteGlyphRunAnalysis_Release(analysis
);
4539 ok(!EqualRect(&rect
, &rect2
), "got equal bounds\n");
4540 OffsetRect(&rect
, 10, -5);
4541 ok(EqualRect(&rect
, &rect2
), "got different bounds\n");
4543 for (i
= 0; i
< sizeof(rendermodes
)/sizeof(rendermodes
[0]); i
++) {
4544 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4545 rendermodes
[i
], DWRITE_MEASURING_MODE_NATURAL
,
4546 0.0, 0.0, &analysis
);
4547 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4549 if (rendermodes
[i
] == DWRITE_RENDERING_MODE_ALIASED
) {
4550 SetRectEmpty(&rect
);
4551 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
4552 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4553 ok(!IsRectEmpty(&rect
), "got empty rect\n");
4555 SetRect(&rect
, 0, 0, 1, 1);
4556 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &rect
);
4557 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4558 ok(IsRectEmpty(&rect
), "unexpected empty rect\n");
4561 SetRect(&rect
, 0, 0, 1, 1);
4562 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
4563 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4564 ok(IsRectEmpty(&rect
), "got empty rect\n");
4566 SetRectEmpty(&rect
);
4567 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &rect
);
4568 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4569 ok(!IsRectEmpty(&rect
), "got empty rect\n");
4572 IDWriteGlyphRunAnalysis_Release(analysis
);
4575 IDWriteFontFace_GetMetrics(run
.fontFace
, &fm
);
4577 /* check bbox for a single glyph run */
4578 for (run
.fontEmSize
= 1.0; run
.fontEmSize
<= 100.0; run
.fontEmSize
+= 1.0) {
4579 DWRITE_GLYPH_METRICS gm
;
4582 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4583 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
4584 0.0, 0.0, &analysis
);
4585 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4587 SetRectEmpty(&rect
);
4588 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
4589 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4591 hr
= IDWriteFontFace_GetGdiCompatibleGlyphMetrics(run
.fontFace
, run
.fontEmSize
, 1.0, NULL
,
4592 DWRITE_MEASURING_MODE_GDI_CLASSIC
, run
.glyphIndices
, 1, &gm
, run
.isSideways
);
4593 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4595 /* metrics are in design units */
4596 bboxX
= (int)floorf((gm
.advanceWidth
- gm
.leftSideBearing
- gm
.rightSideBearing
) * run
.fontEmSize
/ fm
.designUnitsPerEm
+ 0.5f
);
4597 bboxY
= (int)floorf((gm
.advanceHeight
- gm
.topSideBearing
- gm
.bottomSideBearing
) * run
.fontEmSize
/ fm
.designUnitsPerEm
+ 0.5f
);
4599 rect
.right
-= rect
.left
;
4600 rect
.bottom
-= rect
.top
;
4601 ok(abs(bboxX
- rect
.right
) <= 2, "%.0f: bbox width %d, from metrics %d\n", run
.fontEmSize
, rect
.right
, bboxX
);
4602 ok(abs(bboxY
- rect
.bottom
) <= 2, "%.0f: bbox height %d, from metrics %d\n", run
.fontEmSize
, rect
.bottom
, bboxY
);
4604 IDWriteGlyphRunAnalysis_Release(analysis
);
4607 /* without offsets */
4608 run
.fontFace
= face
;
4609 run
.fontEmSize
= 24.0;
4611 run
.glyphIndices
= &glyph
;
4612 run
.glyphAdvances
= advances
;
4613 run
.glyphOffsets
= NULL
;
4614 run
.isSideways
= FALSE
;
4617 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4618 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4619 0.0, 0.0, &analysis
);
4620 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4622 SetRectEmpty(&rect
);
4623 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
4624 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4625 ok(!IsRectEmpty(&rect
), "got empty bounds\n");
4627 IDWriteGlyphRunAnalysis_Release(analysis
);
4629 /* without explicit advances */
4630 run
.fontFace
= face
;
4631 run
.fontEmSize
= 24.0;
4633 run
.glyphIndices
= &glyph
;
4634 run
.glyphAdvances
= NULL
;
4635 run
.glyphOffsets
= NULL
;
4636 run
.isSideways
= FALSE
;
4639 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4640 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4641 0.0, 0.0, &analysis
);
4642 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4644 SetRectEmpty(&rect
);
4645 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
4646 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4647 ok(!IsRectEmpty(&rect
), "got empty bounds\n");
4649 IDWriteGlyphRunAnalysis_Release(analysis
);
4651 /* test that advances are scaled according to ppdip too */
4652 glyphs
[0] = glyphs
[1] = glyph
;
4653 advances
[0] = advances
[1] = 100.0f
;
4654 run
.fontFace
= face
;
4655 run
.fontEmSize
= 24.0;
4657 run
.glyphIndices
= glyphs
;
4658 run
.glyphAdvances
= advances
;
4659 run
.glyphOffsets
= NULL
;
4660 run
.isSideways
= FALSE
;
4663 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4664 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4665 0.0, 0.0, &analysis
);
4666 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4668 SetRectEmpty(&rect2
);
4669 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect2
);
4670 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4671 ok(!IsRectEmpty(&rect2
), "got empty bounds\n");
4672 ok(!EqualRect(&rect
, &rect2
), "got wrong rect2\n");
4673 ok((rect2
.right
- rect
.left
) > advances
[0], "got rect width %d for advance %f\n", rect
.right
- rect
.left
, advances
[0]);
4674 IDWriteGlyphRunAnalysis_Release(analysis
);
4676 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 2.0, NULL
,
4677 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4678 0.0, 0.0, &analysis
);
4679 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4681 SetRectEmpty(&rect
);
4682 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
4683 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4684 ok((rect
.right
- rect
.left
) > 2 * advances
[0], "got rect width %d for advance %f\n", rect
.right
- rect
.left
, advances
[0]);
4685 IDWriteGlyphRunAnalysis_Release(analysis
);
4687 /* with scaling transform */
4688 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
4689 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4690 0.0, 0.0, &analysis
);
4691 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4693 SetRectEmpty(&rect
);
4694 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect
);
4695 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4696 ok(!IsRectEmpty(&rect
), "got rect width %d\n", rect
.right
- rect
.left
);
4697 IDWriteGlyphRunAnalysis_Release(analysis
);
4699 memset(&m
, 0, sizeof(m
));
4702 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, &m
,
4703 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4704 0.0, 0.0, &analysis
);
4705 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4707 SetRectEmpty(&rect2
);
4708 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &rect2
);
4709 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4710 ok((rect2
.right
- rect2
.left
) > (rect
.right
- rect
.left
), "got rect width %d\n", rect2
.right
- rect2
.left
);
4712 /* instances are not reused for same runs */
4713 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, &m
,
4714 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_NATURAL
,
4715 0.0, 0.0, &analysis2
);
4716 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4717 ok(analysis2
!= analysis
, "got %p, previous instance %p\n", analysis2
, analysis
);
4718 IDWriteGlyphRunAnalysis_Release(analysis2
);
4720 IDWriteGlyphRunAnalysis_Release(analysis
);
4722 IDWriteFontFace_Release(face
);
4723 IDWriteFactory_Release(factory
);
4726 #define round(x) ((int)floor((x) + 0.5))
4757 static const struct VDMX_group
*find_vdmx_group(const struct VDMX_Header
*hdr
)
4759 WORD num_ratios
, i
, group_offset
= 0;
4760 struct VDMX_Ratio
*ratios
= (struct VDMX_Ratio
*)(hdr
+ 1);
4761 BYTE dev_x_ratio
= 1, dev_y_ratio
= 1;
4763 num_ratios
= GET_BE_WORD(hdr
->numRatios
);
4765 for (i
= 0; i
< num_ratios
; i
++)
4767 if (!ratios
[i
].bCharSet
) continue;
4769 if ((ratios
[i
].xRatio
== 0 && ratios
[i
].yStartRatio
== 0 &&
4770 ratios
[i
].yEndRatio
== 0) ||
4771 (ratios
[i
].xRatio
== dev_x_ratio
&& ratios
[i
].yStartRatio
<= dev_y_ratio
&&
4772 ratios
[i
].yEndRatio
>= dev_y_ratio
))
4774 group_offset
= GET_BE_WORD(*((WORD
*)(ratios
+ num_ratios
) + i
));
4779 return (const struct VDMX_group
*)((BYTE
*)hdr
+ group_offset
);
4783 static BOOL
get_vdmx_size(const struct VDMX_group
*group
, int emsize
, int *a
, int *d
)
4786 const struct VDMX_vTable
*tables
;
4788 if (!group
) return FALSE
;
4790 recs
= GET_BE_WORD(group
->recs
);
4791 if (emsize
< group
->startsz
|| emsize
>= group
->endsz
) return FALSE
;
4793 tables
= (const struct VDMX_vTable
*)(group
+ 1);
4794 for (i
= 0; i
< recs
; i
++)
4796 WORD ppem
= GET_BE_WORD(tables
[i
].yPelHeight
);
4799 /* FIXME: Supposed to interpolate */
4800 trace("FIXME interpolate %d\n", emsize
);
4806 *a
= (SHORT
)GET_BE_WORD(tables
[i
].yMax
);
4807 *d
= -(SHORT
)GET_BE_WORD(tables
[i
].yMin
);
4814 static void test_metrics_cmp(FLOAT emsize
, const DWRITE_FONT_METRICS
*metrics
, const DWRITE_FONT_METRICS1
*expected
)
4816 ok(metrics
->designUnitsPerEm
== expected
->designUnitsPerEm
, "%.2f: emsize: got %u expect %u\n",
4817 emsize
, metrics
->designUnitsPerEm
, expected
->designUnitsPerEm
);
4818 ok(metrics
->ascent
== expected
->ascent
, "%.2f a: got %u expect %u\n",
4819 emsize
, metrics
->ascent
, expected
->ascent
);
4820 ok(metrics
->descent
== expected
->descent
, "%.2f d: got %u expect %u\n",
4821 emsize
, metrics
->descent
, expected
->descent
);
4822 ok(metrics
->lineGap
== expected
->lineGap
, "%.2f lg: got %d expect %d\n",
4823 emsize
, metrics
->lineGap
, expected
->lineGap
);
4824 ok(metrics
->capHeight
== expected
->capHeight
, "%.2f capH: got %u expect %u\n",
4825 emsize
, metrics
->capHeight
, expected
->capHeight
);
4826 ok(metrics
->xHeight
== expected
->xHeight
, "%.2f xH: got %u expect %u\n",
4827 emsize
, metrics
->xHeight
, expected
->xHeight
);
4828 ok(metrics
->underlinePosition
== expected
->underlinePosition
, "%.2f ulP: got %d expect %d\n",
4829 emsize
, metrics
->underlinePosition
, expected
->underlinePosition
);
4830 ok(metrics
->underlineThickness
== expected
->underlineThickness
, "%.2f ulTh: got %u expect %u\n",
4831 emsize
, metrics
->underlineThickness
, expected
->underlineThickness
);
4832 ok(metrics
->strikethroughPosition
== expected
->strikethroughPosition
, "%.2f stP: got %d expect %d\n",
4833 emsize
, metrics
->strikethroughPosition
, expected
->strikethroughPosition
);
4834 ok(metrics
->strikethroughThickness
== expected
->strikethroughThickness
, "%.2f stTh: got %u expect %u\n",
4835 emsize
, metrics
->strikethroughThickness
, expected
->strikethroughThickness
);
4838 static void test_metrics1_cmp(FLOAT emsize
, const DWRITE_FONT_METRICS1
*metrics
, const DWRITE_FONT_METRICS1
*expected
)
4840 ok(metrics
->designUnitsPerEm
== expected
->designUnitsPerEm
, "%.2f: emsize: got %u expect %u\n",
4841 emsize
, metrics
->designUnitsPerEm
, expected
->designUnitsPerEm
);
4842 ok(metrics
->ascent
== expected
->ascent
, "%.2f a: got %u expect %u\n",
4843 emsize
, metrics
->ascent
, expected
->ascent
);
4844 ok(metrics
->descent
== expected
->descent
, "%.2f d: got %u expect %u\n",
4845 emsize
, metrics
->descent
, expected
->descent
);
4846 ok(metrics
->lineGap
== expected
->lineGap
, "%.2f lg: got %d expect %d\n",
4847 emsize
, metrics
->lineGap
, expected
->lineGap
);
4848 ok(metrics
->capHeight
== expected
->capHeight
, "%.2f capH: got %u expect %u\n",
4849 emsize
, metrics
->capHeight
, expected
->capHeight
);
4850 ok(metrics
->xHeight
== expected
->xHeight
, "%.2f xH: got %u expect %u\n",
4851 emsize
, metrics
->xHeight
, expected
->xHeight
);
4852 ok(metrics
->underlinePosition
== expected
->underlinePosition
, "%.2f ulP: got %d expect %d\n",
4853 emsize
, metrics
->underlinePosition
, expected
->underlinePosition
);
4854 ok(metrics
->underlineThickness
== expected
->underlineThickness
, "%.2f ulTh: got %u expect %u\n",
4855 emsize
, metrics
->underlineThickness
, expected
->underlineThickness
);
4856 ok(metrics
->strikethroughPosition
== expected
->strikethroughPosition
, "%.2f stP: got %d expect %d\n",
4857 emsize
, metrics
->strikethroughPosition
, expected
->strikethroughPosition
);
4858 ok(metrics
->strikethroughThickness
== expected
->strikethroughThickness
, "%.2f stTh: got %u expect %u\n",
4859 emsize
, metrics
->strikethroughThickness
, expected
->strikethroughThickness
);
4860 ok(metrics
->glyphBoxLeft
== expected
->glyphBoxLeft
, "%.2f box left: got %d expect %d\n",
4861 emsize
, metrics
->glyphBoxLeft
, expected
->glyphBoxLeft
);
4862 if (0) { /* this is not consistent */
4863 ok(metrics
->glyphBoxTop
== expected
->glyphBoxTop
, "%.2f box top: got %d expect %d\n",
4864 emsize
, metrics
->glyphBoxTop
, expected
->glyphBoxTop
);
4865 ok(metrics
->glyphBoxRight
== expected
->glyphBoxRight
, "%.2f box right: got %d expect %d\n",
4866 emsize
, metrics
->glyphBoxRight
, expected
->glyphBoxRight
);
4868 ok(metrics
->glyphBoxBottom
== expected
->glyphBoxBottom
, "%.2f box bottom: got %d expect %d\n",
4869 emsize
, metrics
->glyphBoxBottom
, expected
->glyphBoxBottom
);
4870 ok(metrics
->subscriptPositionX
== expected
->subscriptPositionX
, "%.2f subX: got %d expect %d\n",
4871 emsize
, metrics
->subscriptPositionX
, expected
->subscriptPositionX
);
4872 ok(metrics
->subscriptPositionY
== expected
->subscriptPositionY
, "%.2f subY: got %d expect %d\n",
4873 emsize
, metrics
->subscriptPositionY
, expected
->subscriptPositionY
);
4874 ok(metrics
->subscriptSizeX
== expected
->subscriptSizeX
, "%.2f subsizeX: got %d expect %d\n",
4875 emsize
, metrics
->subscriptSizeX
, expected
->subscriptSizeX
);
4876 ok(metrics
->subscriptPositionY
== expected
->subscriptPositionY
, "%.2f subsizeY: got %d expect %d\n",
4877 emsize
, metrics
->subscriptSizeY
, expected
->subscriptSizeY
);
4878 ok(metrics
->superscriptPositionX
== expected
->superscriptPositionX
, "%.2f supX: got %d expect %d\n",
4879 emsize
, metrics
->superscriptPositionX
, expected
->superscriptPositionX
);
4881 ok(metrics
->superscriptPositionY
== expected
->superscriptPositionY
, "%.2f supY: got %d expect %d\n",
4882 emsize
, metrics
->superscriptPositionY
, expected
->superscriptPositionY
);
4883 ok(metrics
->superscriptSizeX
== expected
->superscriptSizeX
, "%.2f supsizeX: got %d expect %d\n",
4884 emsize
, metrics
->superscriptSizeX
, expected
->superscriptSizeX
);
4885 ok(metrics
->superscriptSizeY
== expected
->superscriptSizeY
, "%.2f supsizeY: got %d expect %d\n",
4886 emsize
, metrics
->superscriptSizeY
, expected
->superscriptSizeY
);
4887 ok(metrics
->hasTypographicMetrics
== expected
->hasTypographicMetrics
, "%.2f hastypo: got %d expect %d\n",
4888 emsize
, metrics
->hasTypographicMetrics
, expected
->hasTypographicMetrics
);
4891 struct compatmetrics_test
{
4897 static struct compatmetrics_test compatmetrics_tests
[] = {
4898 { { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, 1.0, 5.0 },
4899 { { 0.0, 0.0, 0.0, -1.0, 0.0, 0.0 }, 1.0, 5.0 },
4900 { { 0.0, 0.0, 0.0, -1.0, 0.0, 0.0 }, 2.0, 5.0 },
4901 { { 0.0, 0.0, 0.0, 3.0, 0.0, 0.0 }, 2.0, 5.0 },
4902 { { 0.0, 0.0, 0.0, -3.0, 0.0, 0.0 }, 2.0, 5.0 },
4903 { { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, 2.0, 5.0 },
4904 { { 1.0, 0.0, 0.0, 1.0, 5.0, 0.0 }, 2.0, 5.0 },
4905 { { 1.0, 0.0, 0.0, 1.0, 0.0, 5.0 }, 2.0, 5.0 },
4908 static void get_expected_metrics(IDWriteFontFace
*fontface
, struct compatmetrics_test
*ptr
,
4909 DWRITE_FONT_METRICS
*expected
)
4913 memset(expected
, 0, sizeof(*expected
));
4914 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(fontface
, ptr
->ppdip
* fabsf(ptr
->m
.m22
) * ptr
->emsize
, 1.0, NULL
, expected
);
4915 ok(hr
== S_OK
, "got %08x\n", hr
);
4918 static void test_GetGdiCompatibleMetrics_face(IDWriteFontFace
*face
)
4920 IDWriteFontFace1
*fontface1
= NULL
;
4922 DWRITE_FONT_METRICS design_metrics
, comp_metrics
;
4923 DWRITE_FONT_METRICS1 design_metrics1
, expected
;
4924 FLOAT emsize
, scale
;
4925 int ascent
, descent
;
4926 const struct VDMX_Header
*vdmx
;
4930 const struct VDMX_group
*vdmx_group
= NULL
;
4933 hr
= IDWriteFontFace_QueryInterface(face
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
4935 win_skip("gdi compatible DWRITE_FONT_METRICS1 are not supported.\n");
4938 IDWriteFontFace1_GetMetrics(fontface1
, &design_metrics1
);
4939 memcpy(&design_metrics
, &design_metrics1
, sizeof(design_metrics
));
4942 IDWriteFontFace_GetMetrics(face
, &design_metrics
);
4944 hr
= IDWriteFontFace_TryGetFontTable(face
, MS_VDMX_TAG
, (const void **)&vdmx
,
4945 &vdmx_len
, &vdmx_ctx
, &exists
);
4946 if (hr
!= S_OK
|| !exists
)
4949 vdmx_group
= find_vdmx_group(vdmx
);
4951 /* negative emsize */
4952 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
4953 memset(&expected
, 0, sizeof(expected
));
4954 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, -10.0, 1.0, NULL
, &comp_metrics
);
4955 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
4956 test_metrics_cmp(0.0, &comp_metrics
, &expected
);
4959 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
4960 memset(&expected
, 0, sizeof(expected
));
4961 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 0.0, 1.0, NULL
, &comp_metrics
);
4962 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
4963 test_metrics_cmp(0.0, &comp_metrics
, &expected
);
4965 /* zero pixels per dip */
4966 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
4967 memset(&expected
, 0, sizeof(expected
));
4968 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 5.0, 0.0, NULL
, &comp_metrics
);
4969 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
4970 test_metrics_cmp(5.0, &comp_metrics
, &expected
);
4972 memset(&comp_metrics
, 0xcc, sizeof(comp_metrics
));
4973 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, 5.0, -1.0, NULL
, &comp_metrics
);
4974 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
4975 test_metrics_cmp(5.0, &comp_metrics
, &expected
);
4977 for (i
= 0; i
< sizeof(compatmetrics_tests
)/sizeof(compatmetrics_tests
[0]); i
++) {
4978 struct compatmetrics_test
*ptr
= &compatmetrics_tests
[i
];
4980 get_expected_metrics(face
, ptr
, (DWRITE_FONT_METRICS
*)&expected
);
4981 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, ptr
->emsize
, ptr
->ppdip
, &ptr
->m
, &comp_metrics
);
4982 ok(hr
== S_OK
, "got %08x\n", hr
);
4983 test_metrics_cmp(ptr
->emsize
, &comp_metrics
, &expected
);
4986 for (emsize
= 5; emsize
<= design_metrics
.designUnitsPerEm
; emsize
++)
4988 DWRITE_FONT_METRICS1 comp_metrics1
, expected
;
4991 hr
= IDWriteFontFace1_GetGdiCompatibleMetrics(fontface1
, emsize
, 1.0, NULL
, &comp_metrics1
);
4992 ok(hr
== S_OK
, "got %08x\n", hr
);
4995 hr
= IDWriteFontFace_GetGdiCompatibleMetrics(face
, emsize
, 1.0, NULL
, &comp_metrics
);
4996 ok(hr
== S_OK
, "got %08x\n", hr
);
4999 scale
= emsize
/ design_metrics
.designUnitsPerEm
;
5000 if (!get_vdmx_size(vdmx_group
, emsize
, &ascent
, &descent
))
5002 ascent
= round(design_metrics
.ascent
* scale
);
5003 descent
= round(design_metrics
.descent
* scale
);
5006 expected
.designUnitsPerEm
= design_metrics
.designUnitsPerEm
;
5007 expected
.ascent
= round(ascent
/ scale
);
5008 expected
.descent
= round(descent
/ scale
);
5009 expected
.lineGap
= round(round(design_metrics
.lineGap
* scale
) / scale
);
5010 expected
.capHeight
= round(round(design_metrics
.capHeight
* scale
) / scale
);
5011 expected
.xHeight
= round(round(design_metrics
.xHeight
* scale
) / scale
);
5012 expected
.underlinePosition
= round(round(design_metrics
.underlinePosition
* scale
) / scale
);
5013 expected
.underlineThickness
= round(round(design_metrics
.underlineThickness
* scale
) / scale
);
5014 expected
.strikethroughPosition
= round(round(design_metrics
.strikethroughPosition
* scale
) / scale
);
5015 expected
.strikethroughThickness
= round(round(design_metrics
.strikethroughThickness
* scale
) / scale
);
5018 expected
.glyphBoxLeft
= round(round(design_metrics1
.glyphBoxLeft
* scale
) / scale
);
5020 if (0) { /* those two fail on Tahoma and Win7 */
5021 expected
.glyphBoxTop
= round(round(design_metrics1
.glyphBoxTop
* scale
) / scale
);
5022 expected
.glyphBoxRight
= round(round(design_metrics1
.glyphBoxRight
* scale
) / scale
);
5024 expected
.glyphBoxBottom
= round(round(design_metrics1
.glyphBoxBottom
* scale
) / scale
);
5025 expected
.subscriptPositionX
= round(round(design_metrics1
.subscriptPositionX
* scale
) / scale
);
5026 expected
.subscriptPositionY
= round(round(design_metrics1
.subscriptPositionY
* scale
) / scale
);
5027 expected
.subscriptSizeX
= round(round(design_metrics1
.subscriptSizeX
* scale
) / scale
);
5028 expected
.subscriptSizeY
= round(round(design_metrics1
.subscriptSizeY
* scale
) / scale
);
5029 expected
.superscriptPositionX
= round(round(design_metrics1
.superscriptPositionX
* scale
) / scale
);
5030 if (0) /* this fails for 3 emsizes, Tahoma from [5, 2048] range */ {
5031 expected
.superscriptPositionY
= round(round(design_metrics1
.superscriptPositionY
* scale
) / scale
);
5033 expected
.superscriptSizeX
= round(round(design_metrics1
.superscriptSizeX
* scale
) / scale
);
5034 expected
.superscriptSizeY
= round(round(design_metrics1
.superscriptSizeY
* scale
) / scale
);
5035 expected
.hasTypographicMetrics
= design_metrics1
.hasTypographicMetrics
;
5037 test_metrics1_cmp(emsize
, &comp_metrics1
, &expected
);
5040 test_metrics_cmp(emsize
, &comp_metrics
, &expected
);
5045 IDWriteFontFace1_Release(fontface1
);
5046 if (vdmx
) IDWriteFontFace_ReleaseFontTable(face
, vdmx_ctx
);
5049 static void test_GetGdiCompatibleMetrics(void)
5051 IDWriteFactory
*factory
;
5053 IDWriteFontFace
*fontface
;
5056 factory
= create_factory();
5058 font
= get_font(factory
, tahomaW
, DWRITE_FONT_STYLE_NORMAL
);
5059 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
5060 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5061 IDWriteFont_Release(font
);
5062 test_GetGdiCompatibleMetrics_face(fontface
);
5063 IDWriteFontFace_Release(fontface
);
5065 font
= get_font(factory
, arialW
, DWRITE_FONT_STYLE_NORMAL
);
5067 skip("Skipping tests with Arial\n");
5070 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
5071 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5072 IDWriteFont_Release(font
);
5074 test_GetGdiCompatibleMetrics_face(fontface
);
5075 IDWriteFontFace_Release(fontface
);
5078 IDWriteFactory_Release(factory
);
5081 static void test_GetPanose(void)
5083 IDWriteFactory
*factory
;
5084 IDWriteFont1
*font1
;
5088 factory
= create_factory();
5089 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
5091 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont1
, (void**)&font1
);
5092 IDWriteFont_Release(font
);
5094 IDWriteFontFace3
*fontface3
;
5095 IDWriteFontFace
*fontface
;
5096 DWRITE_PANOSE panose
;
5098 if (0) /* crashes on native */
5099 IDWriteFont1_GetPanose(font1
, NULL
);
5101 memset(&panose
, 0, sizeof(panose
));
5102 IDWriteFont1_GetPanose(font1
, &panose
);
5103 ok(panose
.familyKind
== DWRITE_PANOSE_FAMILY_TEXT_DISPLAY
,
5104 "got %u\n", panose
.familyKind
);
5105 ok(panose
.text
.serifStyle
== DWRITE_PANOSE_SERIF_STYLE_NORMAL_SANS
,
5106 "got %u\n", panose
.text
.serifStyle
);
5107 ok(panose
.text
.weight
== DWRITE_PANOSE_WEIGHT_MEDIUM
,
5108 "got %u\n", panose
.text
.weight
);
5109 ok(panose
.text
.proportion
== DWRITE_PANOSE_PROPORTION_EVEN_WIDTH
,
5110 "got %u\n", panose
.text
.proportion
);
5111 ok(panose
.text
.contrast
== DWRITE_PANOSE_CONTRAST_VERY_LOW
,
5112 "got %u\n", panose
.text
.contrast
);
5113 ok(panose
.text
.strokeVariation
== DWRITE_PANOSE_STROKE_VARIATION_GRADUAL_VERTICAL
,
5114 "got %u\n", panose
.text
.strokeVariation
);
5115 ok(panose
.text
.armStyle
== DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_VERTICAL
,
5116 "got %u\n", panose
.text
.armStyle
);
5117 ok(panose
.text
.letterform
== DWRITE_PANOSE_LETTERFORM_NORMAL_BOXED
,
5118 "got %u\n", panose
.text
.letterform
);
5119 ok(panose
.text
.midline
== DWRITE_PANOSE_MIDLINE_STANDARD_TRIMMED
,
5120 "got %u\n", panose
.text
.midline
);
5121 ok(panose
.text
.xHeight
== DWRITE_PANOSE_XHEIGHT_CONSTANT_LARGE
,
5122 "got %u\n", panose
.text
.xHeight
);
5124 hr
= IDWriteFont1_CreateFontFace(font1
, &fontface
);
5125 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5127 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace3
, (void**)&fontface3
);
5128 IDWriteFontFace_Release(fontface
);
5130 DWRITE_PANOSE panose2
;
5132 IDWriteFontFace3_GetPanose(fontface3
, &panose2
);
5133 ok(!memcmp(&panose
, &panose2
, sizeof(panose
)), "wrong panose data\n");
5135 IDWriteFontFace3_Release(fontface3
);
5138 IDWriteFont1_Release(font1
);
5141 win_skip("GetPanose() is not supported.\n");
5143 IDWriteFactory_Release(factory
);
5146 static INT32
get_gdi_font_advance(HDC hdc
, FLOAT emsize
)
5153 memset(&logfont
, 0, sizeof(logfont
));
5154 logfont
.lfHeight
= (LONG
)-emsize
;
5155 logfont
.lfWeight
= FW_NORMAL
;
5156 logfont
.lfQuality
= CLEARTYPE_QUALITY
;
5157 lstrcpyW(logfont
.lfFaceName
, tahomaW
);
5159 hfont
= CreateFontIndirectW(&logfont
);
5160 SelectObject(hdc
, hfont
);
5162 ret
= GetCharABCWidthsW(hdc
, 'A', 'A', &abc
);
5163 ok(ret
, "got %d\n", ret
);
5165 DeleteObject(hfont
);
5167 return abc
.abcA
+ abc
.abcB
+ abc
.abcC
;
5170 static void test_GetGdiCompatibleGlyphAdvances(void)
5172 IDWriteFontFace1
*fontface1
;
5173 IDWriteFontFace
*fontface
;
5174 IDWriteFactory
*factory
;
5181 DWRITE_FONT_METRICS1 fm
;
5184 factory
= create_factory();
5185 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
5187 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
5188 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5189 IDWriteFont_Release(font
);
5191 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
5192 IDWriteFontFace_Release(fontface
);
5195 IDWriteFactory_Release(factory
);
5196 win_skip("GetGdiCompatibleGlyphAdvances() is not supported\n");
5202 hr
= IDWriteFontFace1_GetGlyphIndices(fontface1
, &codepoint
, 1, &glyph
);
5203 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5204 ok(glyph
> 0, "got %u\n", glyph
);
5208 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 0.0,
5209 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
5210 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5211 ok(advance
== 0, "got %d\n", advance
);
5213 /* negative emsize */
5215 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, -1.0,
5216 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
5217 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
5218 ok(advance
== 0, "got %d\n", advance
);
5222 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 1.0,
5223 0.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
5224 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
5225 ok(advance
== 0, "got %d\n", advance
);
5227 /* negative ppdip */
5229 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, 1.0,
5230 -1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
5231 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
5232 ok(advance
== 0, "got %d\n", advance
);
5234 IDWriteFontFace1_GetMetrics(fontface1
, &fm
);
5236 hdc
= CreateCompatibleDC(0);
5238 for (emsize
= 1.0; emsize
<= fm
.designUnitsPerEm
; emsize
+= 1.0) {
5241 gdi_advance
= get_gdi_font_advance(hdc
, emsize
);
5242 hr
= IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, emsize
,
5243 1.0, NULL
, FALSE
, FALSE
, 1, &glyph
, &advance
);
5244 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5246 /* advance is in design units */
5247 advance
= (int)floorf(emsize
* advance
/ fm
.designUnitsPerEm
+ 0.5f
);
5248 ok((advance
- gdi_advance
) <= 2, "%.0f: got advance %d, expected %d\n", emsize
, advance
, gdi_advance
);
5253 IDWriteFactory_Release(factory
);
5256 static WORD
get_gasp_flags(IDWriteFontFace
*fontface
, FLOAT emsize
, FLOAT ppdip
)
5258 WORD num_recs
, version
;
5269 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_GASP_TAG
,
5270 (const void**)&ptr
, &size
, &ctxt
, &exists
);
5271 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5276 version
= GET_BE_WORD( *ptr
++ );
5277 num_recs
= GET_BE_WORD( *ptr
++ );
5278 if (version
> 1 || size
< (num_recs
* 2 + 2) * sizeof(WORD
)) {
5279 ok(0, "unsupported gasp table: ver %d size %d recs %d\n", version
, size
, num_recs
);
5285 flags
= GET_BE_WORD( *(ptr
+ 1) );
5286 if (emsize
<= GET_BE_WORD( *ptr
)) break;
5291 IDWriteFontFace_ReleaseFontTable(fontface
, ctxt
);
5295 #define GASP_GRIDFIT 0x0001
5296 #define GASP_DOGRAY 0x0002
5297 #define GASP_SYMMETRIC_GRIDFIT 0x0004
5298 #define GASP_SYMMETRIC_SMOOTHING 0x0008
5300 static BOOL g_is_vista
;
5301 static DWRITE_RENDERING_MODE
get_expected_rendering_mode(FLOAT emsize
, WORD gasp
, DWRITE_MEASURING_MODE mode
,
5302 DWRITE_OUTLINE_THRESHOLD threshold
)
5304 static const FLOAT aa_threshold
= 100.0f
;
5305 static const FLOAT a_threshold
= 350.0f
;
5306 static const FLOAT naturalemsize
= 20.0f
;
5309 /* outline threshold */
5311 v
= mode
== DWRITE_MEASURING_MODE_NATURAL
? aa_threshold
: a_threshold
;
5313 v
= threshold
== DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
? aa_threshold
: a_threshold
;
5316 return DWRITE_RENDERING_MODE_OUTLINE
;
5320 case DWRITE_MEASURING_MODE_NATURAL
:
5321 if (!(gasp
& GASP_SYMMETRIC_SMOOTHING
) && (emsize
<= naturalemsize
))
5322 return DWRITE_RENDERING_MODE_NATURAL
;
5324 return DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
;
5325 case DWRITE_MEASURING_MODE_GDI_CLASSIC
:
5326 return DWRITE_RENDERING_MODE_GDI_CLASSIC
;
5327 case DWRITE_MEASURING_MODE_GDI_NATURAL
:
5328 return DWRITE_RENDERING_MODE_GDI_NATURAL
;
5333 /* should be unreachable */
5334 return DWRITE_RENDERING_MODE_DEFAULT
;
5337 static DWRITE_GRID_FIT_MODE
get_expected_gridfit_mode(FLOAT emsize
, WORD gasp
, DWRITE_MEASURING_MODE mode
,
5338 DWRITE_OUTLINE_THRESHOLD threshold
)
5340 static const FLOAT aa_threshold
= 100.0f
;
5341 static const FLOAT a_threshold
= 350.0f
;
5344 v
= threshold
== DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
? aa_threshold
: a_threshold
;
5346 return DWRITE_GRID_FIT_MODE_DISABLED
;
5348 if (mode
== DWRITE_MEASURING_MODE_GDI_CLASSIC
|| mode
== DWRITE_MEASURING_MODE_GDI_NATURAL
)
5349 return DWRITE_GRID_FIT_MODE_ENABLED
;
5351 return (gasp
& (GASP_GRIDFIT
|GASP_SYMMETRIC_GRIDFIT
)) ? DWRITE_GRID_FIT_MODE_ENABLED
: DWRITE_GRID_FIT_MODE_DISABLED
;
5354 struct recommendedmode_test
5356 DWRITE_MEASURING_MODE measuring
;
5357 DWRITE_OUTLINE_THRESHOLD threshold
;
5360 static const struct recommendedmode_test recmode_tests
[] = {
5361 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
5362 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
5363 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
5366 static const struct recommendedmode_test recmode_tests1
[] = {
5367 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
5368 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
5369 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
},
5370 { DWRITE_MEASURING_MODE_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
5371 { DWRITE_MEASURING_MODE_GDI_CLASSIC
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
5372 { DWRITE_MEASURING_MODE_GDI_NATURAL
, DWRITE_OUTLINE_THRESHOLD_ALIASED
},
5375 static void test_GetRecommendedRenderingMode(void)
5377 IDWriteRenderingParams
*params
;
5378 IDWriteFontFace3
*fontface3
;
5379 IDWriteFontFace2
*fontface2
;
5380 IDWriteFontFace1
*fontface1
;
5381 IDWriteFontFace
*fontface
;
5382 DWRITE_RENDERING_MODE mode
;
5383 IDWriteFactory
*factory
;
5387 factory
= create_factory();
5388 fontface
= create_fontface(factory
);
5391 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
5393 win_skip("IDWriteFontFace1::GetRecommendedRenderingMode() is not supported.\n");
5396 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
5398 win_skip("IDWriteFontFace2::GetRecommendedRenderingMode() is not supported.\n");
5401 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace3
, (void**)&fontface3
);
5403 win_skip("IDWriteFontFace3::GetRecommendedRenderingMode() is not supported.\n");
5405 if (0) /* crashes on native */
5406 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 3.0, 1.0,
5407 DWRITE_MEASURING_MODE_GDI_CLASSIC
, NULL
, NULL
);
5410 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 3.0, 1.0,
5411 DWRITE_MEASURING_MODE_GDI_CLASSIC
, NULL
, &mode
);
5412 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
5413 ok(mode
== DWRITE_RENDERING_MODE_DEFAULT
, "got %d\n", mode
);
5415 hr
= IDWriteFactory_CreateRenderingParams(factory
, ¶ms
);
5416 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5418 /* detect old dwrite version, that is using higher threshold value */
5419 g_is_vista
= fontface1
== NULL
;
5421 for (emsize
= 1.0; emsize
< 500.0; emsize
+= 1.0) {
5422 DWRITE_RENDERING_MODE expected
;
5427 for (i
= 0; i
< sizeof(recmode_tests
)/sizeof(recmode_tests
[0]); i
++) {
5430 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5431 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests
[i
].measuring
, recmode_tests
[i
].threshold
);
5432 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, emsize
, ppdip
, recmode_tests
[i
].measuring
, params
, &mode
);
5433 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5434 ok(mode
== expected
, "%.2f/%d: got %d, ppdip %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, ppdip
, gasp
, expected
);
5436 /* some ppdip variants */
5439 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5440 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests
[i
].measuring
, recmode_tests
[i
].threshold
);
5441 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, emsize
, ppdip
, recmode_tests
[i
].measuring
, params
, &mode
);
5442 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5443 ok(mode
== expected
, "%.2f/%d: got %d, ppdip %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, ppdip
, gasp
, expected
);
5445 /* Only test larger sizes to workaround Win7 differences, where unscaled natural emsize threshold is used;
5446 Win8 and Win10 handle this as expected. */
5447 if (emsize
> 20.0f
) {
5450 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5451 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests
[i
].measuring
, recmode_tests
[i
].threshold
);
5452 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, emsize
, ppdip
, recmode_tests
[i
].measuring
, params
, &mode
);
5453 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5454 ok(mode
== expected
, "%.2f/%d: got %d, ppdip %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, ppdip
, gasp
, expected
);
5458 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5459 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests
[i
].measuring
, recmode_tests
[i
].threshold
);
5460 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, emsize
, ppdip
, recmode_tests
[i
].measuring
, params
, &mode
);
5461 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5462 ok(mode
== expected
, "%.2f/%d: got %d, ppdip %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, ppdip
, gasp
, expected
);
5466 /* IDWriteFontFace1 offers another variant of this method */
5468 for (i
= 0; i
< sizeof(recmode_tests1
)/sizeof(recmode_tests1
[0]); i
++) {
5472 dpi
= 96.0f
* ppdip
;
5474 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5475 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5476 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
, dpi
,
5477 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
5478 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5479 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
5481 /* Only test larger sizes to workaround Win7 differences, where unscaled natural emsize threshold is used;
5482 Win8 and Win10 handle this as expected. */
5483 if (emsize
> 20.0f
) {
5485 dpi
= 96.0f
* ppdip
;
5487 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5488 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5489 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
, dpi
,
5490 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
5491 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5492 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
5495 dpi
= 96.0f
* ppdip
;
5497 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5498 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5499 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
, dpi
,
5500 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
5501 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5502 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
5504 /* try different dpis for X and Y direction */
5506 dpi
= 96.0f
* ppdip
;
5508 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5509 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5510 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
* 0.5f
, dpi
,
5511 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
5512 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5513 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
5516 dpi
= 96.0f
* ppdip
;
5518 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5519 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5520 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
, dpi
* 0.5f
,
5521 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
5522 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5523 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
5526 dpi
= 96.0f
* ppdip
;
5528 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5529 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5530 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
* 0.5f
, dpi
,
5531 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
5532 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5533 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
5536 dpi
= 96.0f
* ppdip
;
5538 gasp
= get_gasp_flags(fontface
, emsize
, ppdip
);
5539 expected
= get_expected_rendering_mode(emsize
* ppdip
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5540 hr
= IDWriteFontFace1_GetRecommendedRenderingMode(fontface1
, emsize
, dpi
, dpi
* 0.5f
,
5541 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, &mode
);
5542 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5543 ok(mode
== expected
, "%.2f/%d: got %d, dpi %f, flags 0x%04x, expected %d\n", emsize
, i
, mode
, dpi
, gasp
, expected
);
5548 /* IDWriteFontFace2 - another one */
5550 DWRITE_GRID_FIT_MODE gridfit
, expected_gridfit
;
5552 gasp
= get_gasp_flags(fontface
, emsize
, 1.0f
);
5553 for (i
= 0; i
< sizeof(recmode_tests1
)/sizeof(recmode_tests1
[0]); i
++) {
5555 expected
= get_expected_rendering_mode(emsize
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5556 expected_gridfit
= get_expected_gridfit_mode(emsize
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5557 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, emsize
, 96.0f
, 96.0f
,
5558 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, params
, &mode
, &gridfit
);
5559 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5560 ok(mode
== expected
, "%.2f: got %d, flags 0x%04x, expected %d\n", emsize
, mode
, gasp
, expected
);
5561 ok(gridfit
== expected_gridfit
, "%.2f/%d: gridfit: got %d, flags 0x%04x, expected %d\n", emsize
, i
, gridfit
,
5562 gasp
, expected_gridfit
);
5566 /* IDWriteFontFace3 - and another one */
5568 DWRITE_GRID_FIT_MODE gridfit
, expected_gridfit
;
5569 DWRITE_RENDERING_MODE1 mode1
, expected1
;
5571 gasp
= get_gasp_flags(fontface
, emsize
, 1.0f
);
5572 for (i
= 0; i
< sizeof(recmode_tests1
)/sizeof(recmode_tests1
[0]); i
++) {
5574 expected1
= get_expected_rendering_mode(emsize
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5575 expected_gridfit
= get_expected_gridfit_mode(emsize
, gasp
, recmode_tests1
[i
].measuring
, recmode_tests1
[i
].threshold
);
5576 hr
= IDWriteFontFace3_GetRecommendedRenderingMode(fontface3
, emsize
, 96.0f
, 96.0f
,
5577 NULL
, FALSE
, recmode_tests1
[i
].threshold
, recmode_tests1
[i
].measuring
, params
, &mode1
, &gridfit
);
5578 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5579 ok(mode1
== expected1
, "%.2f: got %d, flags 0x%04x, expected %d\n", emsize
, mode1
, gasp
, expected1
);
5580 ok(gridfit
== expected_gridfit
, "%.2f/%d: gridfit: got %d, flags 0x%04x, expected %d\n", emsize
, i
, gridfit
,
5581 gasp
, expected_gridfit
);
5586 IDWriteRenderingParams_Release(params
);
5588 /* test how parameters override returned modes */
5589 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 1.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT
,
5590 DWRITE_RENDERING_MODE_GDI_CLASSIC
, ¶ms
);
5591 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5594 hr
= IDWriteFontFace_GetRecommendedRenderingMode(fontface
, 500.0, 1.0, DWRITE_MEASURING_MODE_NATURAL
, params
, &mode
);
5595 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5596 ok(mode
== DWRITE_RENDERING_MODE_GDI_CLASSIC
, "got %d\n", mode
);
5598 IDWriteRenderingParams_Release(params
);
5601 IDWriteRenderingParams2
*params2
;
5602 IDWriteFactory2
*factory2
;
5603 DWRITE_GRID_FIT_MODE gridfit
;
5605 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory2
, (void**)&factory2
);
5606 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5608 hr
= IDWriteFactory2_CreateCustomRenderingParams(factory2
, 1.0, 0.0, 0.0, 0.5, DWRITE_PIXEL_GEOMETRY_FLAT
,
5609 DWRITE_RENDERING_MODE_OUTLINE
, DWRITE_GRID_FIT_MODE_ENABLED
, ¶ms2
);
5610 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5614 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, 5.0, 96.0, 96.0,
5615 NULL
, FALSE
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
5616 NULL
, &mode
, &gridfit
);
5617 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5618 ok(mode
== DWRITE_RENDERING_MODE_GDI_CLASSIC
, "got %d\n", mode
);
5619 ok(gridfit
== DWRITE_GRID_FIT_MODE_ENABLED
, "got %d\n", gridfit
);
5623 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, 5.0, 96.0, 96.0,
5624 NULL
, FALSE
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
5625 (IDWriteRenderingParams
*)params2
, &mode
, &gridfit
);
5626 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5627 ok(mode
== DWRITE_RENDERING_MODE_OUTLINE
, "got %d\n", mode
);
5628 ok(gridfit
== DWRITE_GRID_FIT_MODE_ENABLED
, "got %d\n", gridfit
);
5630 IDWriteRenderingParams2_Release(params2
);
5631 IDWriteFactory2_Release(factory2
);
5635 IDWriteRenderingParams3
*params3
;
5636 IDWriteRenderingParams2
*params2
;
5637 IDWriteRenderingParams
*params
;
5638 IDWriteFactory3
*factory3
;
5639 DWRITE_GRID_FIT_MODE gridfit
;
5640 DWRITE_RENDERING_MODE1 mode1
;
5642 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory3
, (void**)&factory3
);
5643 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5645 hr
= IDWriteFactory3_CreateCustomRenderingParams(factory3
, 1.0f
, 0.0f
, 0.0f
, 0.5f
, DWRITE_PIXEL_GEOMETRY_FLAT
,
5646 DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED
, DWRITE_GRID_FIT_MODE_ENABLED
, ¶ms3
);
5647 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5649 mode1
= IDWriteRenderingParams3_GetRenderingMode1(params3
);
5650 ok(mode1
== DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED
, "got %d\n", mode1
);
5652 mode1
= IDWriteRenderingParams3_GetRenderingMode(params3
);
5653 ok(mode1
== DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC
, "got %d\n", mode1
);
5655 hr
= IDWriteRenderingParams3_QueryInterface(params3
, &IID_IDWriteRenderingParams
, (void**)¶ms
);
5656 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5657 ok(params
== (IDWriteRenderingParams
*)params3
, "got %p, %p\n", params3
, params
);
5658 mode
= IDWriteRenderingParams_GetRenderingMode(params
);
5659 ok(mode
== DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
, "got %d\n", mode
);
5660 IDWriteRenderingParams_Release(params
);
5662 hr
= IDWriteRenderingParams3_QueryInterface(params3
, &IID_IDWriteRenderingParams2
, (void**)¶ms2
);
5663 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5664 ok(params2
== (IDWriteRenderingParams2
*)params3
, "got %p, %p\n", params3
, params2
);
5665 mode
= IDWriteRenderingParams2_GetRenderingMode(params2
);
5666 ok(mode
== DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
, "got %d\n", mode
);
5667 IDWriteRenderingParams2_Release(params2
);
5671 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, 5.0f
, 96.0f
, 96.0f
,
5672 NULL
, FALSE
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
5673 NULL
, &mode
, &gridfit
);
5674 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5675 ok(mode
== DWRITE_RENDERING_MODE_GDI_CLASSIC
, "got %d\n", mode
);
5676 ok(gridfit
== DWRITE_GRID_FIT_MODE_ENABLED
, "got %d\n", gridfit
);
5680 hr
= IDWriteFontFace2_GetRecommendedRenderingMode(fontface2
, 5.0f
, 96.0f
, 96.0f
,
5681 NULL
, FALSE
, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
5682 (IDWriteRenderingParams
*)params3
, &mode
, &gridfit
);
5683 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5684 ok(mode
== DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
, "got %d\n", mode
);
5685 ok(gridfit
== DWRITE_GRID_FIT_MODE_ENABLED
, "got %d\n", gridfit
);
5687 IDWriteRenderingParams3_Release(params3
);
5688 IDWriteFactory3_Release(factory3
);
5692 IDWriteFontFace3_Release(fontface3
);
5694 IDWriteFontFace2_Release(fontface2
);
5696 IDWriteFontFace1_Release(fontface1
);
5697 IDWriteFontFace_Release(fontface
);
5698 IDWriteFactory_Release(factory
);
5701 static inline BOOL
float_eq(FLOAT left
, FLOAT right
)
5703 int x
= *(int *)&left
;
5704 int y
= *(int *)&right
;
5711 return abs(x
- y
) <= 8;
5714 static void test_GetAlphaBlendParams(void)
5716 static const DWRITE_RENDERING_MODE rendermodes
[] = {
5717 DWRITE_RENDERING_MODE_ALIASED
,
5718 DWRITE_RENDERING_MODE_GDI_CLASSIC
,
5719 DWRITE_RENDERING_MODE_GDI_NATURAL
,
5720 DWRITE_RENDERING_MODE_NATURAL
,
5721 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
,
5724 IDWriteGlyphRunAnalysis
*analysis
;
5725 FLOAT gamma
, contrast
, ctlevel
;
5726 IDWriteRenderingParams
*params
;
5727 DWRITE_GLYPH_METRICS metrics
;
5728 DWRITE_GLYPH_OFFSET offset
;
5729 IDWriteFontFace
*fontface
;
5730 IDWriteFactory
*factory
;
5731 DWRITE_GLYPH_RUN run
;
5732 FLOAT advance
, expected_gdi_gamma
;
5739 factory
= create_factory();
5740 fontface
= create_fontface(factory
);
5744 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &ch
, 1, &glyph
);
5745 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5746 ok(glyph
> 0, "got %u\n", glyph
);
5748 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, &glyph
, 1, &metrics
, FALSE
);
5749 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5750 advance
= metrics
.advanceWidth
;
5752 offset
.advanceOffset
= 0.0;
5753 offset
.ascenderOffset
= 0.0;
5755 run
.fontFace
= fontface
;
5756 run
.fontEmSize
= 24.0;
5758 run
.glyphIndices
= &glyph
;
5759 run
.glyphAdvances
= &advance
;
5760 run
.glyphOffsets
= &offset
;
5761 run
.isSideways
= FALSE
;
5764 hr
= IDWriteFactory_CreateCustomRenderingParams(factory
, 0.9, 0.3, 0.1, DWRITE_PIXEL_GEOMETRY_RGB
,
5765 DWRITE_RENDERING_MODE_DEFAULT
, ¶ms
);
5766 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5769 ret
= SystemParametersInfoW(SPI_GETFONTSMOOTHINGCONTRAST
, 0, &value
, 0);
5770 ok(ret
, "got %d\n", ret
);
5771 expected_gdi_gamma
= (FLOAT
)(value
/ 1000.0);
5773 for (i
= 0; i
< sizeof(rendermodes
)/sizeof(rendermodes
[0]); i
++) {
5774 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
5775 rendermodes
[i
], DWRITE_MEASURING_MODE_NATURAL
,
5776 0.0, 0.0, &analysis
);
5777 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5779 gamma
= contrast
= ctlevel
= -1.0;
5780 hr
= IDWriteGlyphRunAnalysis_GetAlphaBlendParams(analysis
, NULL
, &gamma
, &contrast
, &ctlevel
);
5781 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
5782 ok(gamma
== -1.0, "got %.2f\n", gamma
);
5783 ok(contrast
== -1.0, "got %.2f\n", contrast
);
5784 ok(ctlevel
== -1.0, "got %.2f\n", ctlevel
);
5786 gamma
= contrast
= ctlevel
= -1.0;
5787 hr
= IDWriteGlyphRunAnalysis_GetAlphaBlendParams(analysis
, params
, &gamma
, &contrast
, &ctlevel
);
5788 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5790 if (rendermodes
[i
] == DWRITE_RENDERING_MODE_GDI_CLASSIC
|| rendermodes
[i
] == DWRITE_RENDERING_MODE_GDI_NATURAL
) {
5791 ok(float_eq(gamma
, expected_gdi_gamma
), "got %.2f, expected %.2f\n", gamma
, expected_gdi_gamma
);
5792 ok(contrast
== 0.0f
, "got %.2f\n", contrast
);
5793 ok(ctlevel
== 1.0f
, "got %.2f\n", ctlevel
);
5796 ok(gamma
== 0.9f
, "got %.2f\n", gamma
);
5797 ok(contrast
== 0.3f
, "got %.2f\n", contrast
);
5798 ok(ctlevel
== 0.1f
, "got %.2f\n", ctlevel
);
5801 IDWriteGlyphRunAnalysis_Release(analysis
);
5804 IDWriteRenderingParams_Release(params
);
5805 IDWriteFontFace_Release(fontface
);
5806 IDWriteFactory_Release(factory
);
5809 static void test_CreateAlphaTexture(void)
5811 IDWriteGlyphRunAnalysis
*analysis
;
5812 DWRITE_GLYPH_METRICS metrics
;
5813 DWRITE_GLYPH_OFFSET offset
;
5814 IDWriteFontFace
*fontface
;
5815 IDWriteFactory
*factory
;
5816 DWRITE_GLYPH_RUN run
;
5824 factory
= create_factory();
5825 fontface
= create_fontface(factory
);
5829 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &ch
, 1, &glyph
);
5830 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5831 ok(glyph
> 0, "got %u\n", glyph
);
5833 hr
= IDWriteFontFace_GetDesignGlyphMetrics(fontface
, &glyph
, 1, &metrics
, FALSE
);
5834 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5835 advance
= metrics
.advanceWidth
;
5837 offset
.advanceOffset
= 0.0;
5838 offset
.ascenderOffset
= 0.0;
5840 run
.fontFace
= fontface
;
5841 run
.fontEmSize
= 24.0;
5843 run
.glyphIndices
= &glyph
;
5844 run
.glyphAdvances
= &advance
;
5845 run
.glyphOffsets
= &offset
;
5846 run
.isSideways
= FALSE
;
5849 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
5850 DWRITE_RENDERING_MODE_NATURAL
, DWRITE_MEASURING_MODE_NATURAL
,
5851 0.0, 0.0, &analysis
);
5852 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5854 SetRectEmpty(&bounds
);
5855 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &bounds
);
5856 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5857 ok(!IsRectEmpty(&bounds
), "got empty rect\n");
5858 size
= (bounds
.right
- bounds
.left
)*(bounds
.bottom
- bounds
.top
)*3;
5859 ok(sizeof(buff
) >= size
, "required %u\n", size
);
5861 /* invalid type value */
5862 memset(buff
, 0xcf, sizeof(buff
));
5863 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
+1, &bounds
, buff
, sizeof(buff
));
5864 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
5865 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
5867 memset(buff
, 0xcf, sizeof(buff
));
5868 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
, buff
, 2);
5869 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
5870 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
5872 /* vista version allows texture type mismatch, mark it broken for now */
5873 memset(buff
, 0xcf, sizeof(buff
));
5874 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
, buff
, sizeof(buff
));
5875 ok(hr
== DWRITE_E_UNSUPPORTEDOPERATION
|| broken(hr
== S_OK
), "got 0x%08x\n", hr
);
5876 ok(buff
[0] == 0xcf || broken(buff
[0] == 0), "got %1x\n", buff
[0]);
5878 memset(buff
, 0xcf, sizeof(buff
));
5879 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &bounds
, buff
, size
-1);
5880 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
5881 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
5883 IDWriteGlyphRunAnalysis_Release(analysis
);
5885 hr
= IDWriteFactory_CreateGlyphRunAnalysis(factory
, &run
, 1.0, NULL
,
5886 DWRITE_RENDERING_MODE_ALIASED
, DWRITE_MEASURING_MODE_GDI_CLASSIC
,
5887 0.0, 0.0, &analysis
);
5888 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5890 SetRectEmpty(&bounds
);
5891 hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
);
5892 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5893 ok(!IsRectEmpty(&bounds
), "got empty rect\n");
5894 size
= (bounds
.right
- bounds
.left
)*(bounds
.bottom
- bounds
.top
);
5895 ok(sizeof(buff
) >= size
, "required %u\n", size
);
5897 memset(buff
, 0xcf, sizeof(buff
));
5898 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, NULL
, buff
, sizeof(buff
));
5899 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
5900 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
5902 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, NULL
, NULL
, sizeof(buff
));
5903 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
5905 memset(buff
, 0xcf, sizeof(buff
));
5906 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, NULL
, buff
, 0);
5907 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
5908 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
5910 /* buffer size is not enough */
5911 memset(buff
, 0xcf, sizeof(buff
));
5912 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &bounds
, buff
, size
-1);
5913 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
5914 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
5916 /* request texture for rectangle that doesn't intersect */
5917 memset(buff
, 0xcf, sizeof(buff
));
5919 OffsetRect(&r
, (bounds
.right
- bounds
.left
)*2, 0);
5920 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &r
, buff
, sizeof(buff
));
5921 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5922 ok(buff
[0] == 0, "got %1x\n", buff
[0]);
5924 memset(buff
, 0xcf, sizeof(buff
));
5926 OffsetRect(&r
, (bounds
.right
- bounds
.left
)*2, 0);
5927 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &r
, buff
, sizeof(buff
));
5928 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5929 ok(buff
[0] == 0, "got %1x\n", buff
[0]);
5931 /* request texture for rectangle that doesn't intersect, small buffer */
5932 memset(buff
, 0xcf, sizeof(buff
));
5934 OffsetRect(&r
, (bounds
.right
- bounds
.left
)*2, 0);
5935 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_ALIASED_1x1
, &r
, buff
, size
-1);
5936 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
5937 ok(buff
[0] == 0xcf, "got %1x\n", buff
[0]);
5939 /* vista version allows texture type mismatch, mark it broken for now */
5940 memset(buff
, 0xcf, sizeof(buff
));
5941 hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
, DWRITE_TEXTURE_CLEARTYPE_3x1
, &bounds
, buff
, sizeof(buff
));
5942 ok(hr
== DWRITE_E_UNSUPPORTEDOPERATION
|| broken(hr
== S_OK
), "got 0x%08x\n", hr
);
5943 ok(buff
[0] == 0xcf || broken(buff
[0] == 0), "got %1x\n", buff
[0]);
5945 IDWriteGlyphRunAnalysis_Release(analysis
);
5946 IDWriteFontFace_Release(fontface
);
5947 IDWriteFactory_Release(factory
);
5950 static void test_IsSymbolFont(void)
5952 static const WCHAR symbolW
[] = {'S','y','m','b','o','l',0};
5953 IDWriteFontCollection
*collection
;
5954 IDWriteFontFace
*fontface
;
5955 IDWriteFactory
*factory
;
5960 factory
= create_factory();
5963 fontface
= create_fontface(factory
);
5964 ret
= IDWriteFontFace_IsSymbolFont(fontface
);
5965 ok(!ret
, "got %d\n", ret
);
5967 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &collection
, FALSE
);
5968 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5970 hr
= IDWriteFontCollection_GetFontFromFontFace(collection
, fontface
, &font
);
5971 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5973 ret
= IDWriteFont_IsSymbolFont(font
);
5974 ok(!ret
, "got %d\n", ret
);
5976 IDWriteFontCollection_Release(collection
);
5977 IDWriteFont_Release(font
);
5978 IDWriteFontFace_Release(fontface
);
5981 font
= get_font(factory
, symbolW
, DWRITE_FONT_STYLE_NORMAL
);
5982 ret
= IDWriteFont_IsSymbolFont(font
);
5983 ok(ret
, "got %d\n", ret
);
5985 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
5986 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
5987 ret
= IDWriteFontFace_IsSymbolFont(fontface
);
5988 ok(ret
, "got %d\n", ret
);
5989 IDWriteFont_Release(font
);
5991 IDWriteFactory_Release(factory
);
5994 struct CPAL_Header_0
5997 USHORT numPaletteEntries
;
5999 USHORT numColorRecords
;
6000 ULONG offsetFirstColorRecord
;
6001 USHORT colorRecordIndices
[1];
6004 static void test_GetPaletteEntries(void)
6006 IDWriteFontFace2
*fontface2
;
6007 IDWriteFontFace
*fontface
;
6008 IDWriteFactory
*factory
;
6010 DWRITE_COLOR_F color
;
6011 UINT32 palettecount
, entrycount
, size
, colorrecords
;
6013 const struct CPAL_Header_0
*cpal_header
;
6017 factory
= create_factory();
6019 /* Tahoma, no color support */
6020 fontface
= create_fontface(factory
);
6021 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
6022 IDWriteFontFace_Release(fontface
);
6024 IDWriteFactory_Release(factory
);
6025 win_skip("GetPaletteEntries() is not supported.\n");
6029 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, 0, 1, &color
);
6030 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
6031 IDWriteFontFace2_Release(fontface2
);
6033 /* Segoe UI Emoji, with color support */
6034 font
= get_font(factory
, emojiW
, DWRITE_FONT_STYLE_NORMAL
);
6036 IDWriteFactory_Release(factory
);
6037 skip("Segoe UI Emoji font not found.\n");
6041 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
6042 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6043 IDWriteFont_Release(font
);
6045 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
6046 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6047 IDWriteFontFace_Release(fontface
);
6049 palettecount
= IDWriteFontFace2_GetColorPaletteCount(fontface2
);
6050 ok(palettecount
>= 1, "got %u\n", palettecount
);
6052 entrycount
= IDWriteFontFace2_GetPaletteEntryCount(fontface2
);
6053 ok(entrycount
>= 1, "got %u\n", entrycount
);
6056 hr
= IDWriteFontFace2_TryGetFontTable(fontface2
, MS_CPAL_TAG
, (const void**)&cpal_header
, &size
, &ctxt
, &exists
);
6057 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6058 ok(exists
, "got %d\n", exists
);
6059 colorrecords
= GET_BE_WORD(cpal_header
->numColorRecords
);
6060 ok(colorrecords
>= 1, "got %u\n", colorrecords
);
6062 /* invalid palette index */
6063 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
6064 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, palettecount
, 0, 1, &color
);
6065 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
6066 ok(color
.r
== 123.0 && color
.g
== 123.0 && color
.b
== 123.0 && color
.a
== 123.0,
6067 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
6069 /* invalid entry index */
6070 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
6071 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, entrycount
, 1, &color
);
6072 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
6073 ok(color
.r
== 123.0 && color
.g
== 123.0 && color
.b
== 123.0 && color
.a
== 123.0,
6074 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
6076 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
6077 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, entrycount
- 1, 1, &color
);
6078 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6079 ok(color
.r
!= 123.0 && color
.g
!= 123.0 && color
.b
!= 123.0 && color
.a
!= 123.0,
6080 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
6082 /* zero return length */
6083 color
.r
= color
.g
= color
.b
= color
.a
= 123.0;
6084 hr
= IDWriteFontFace2_GetPaletteEntries(fontface2
, 0, 0, 0, &color
);
6085 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6086 ok(color
.r
== 123.0 && color
.g
== 123.0 && color
.b
== 123.0 && color
.a
== 123.0,
6087 "got wrong color %.2fx%.2fx%.2fx%.2f\n", color
.r
, color
.g
, color
.b
, color
.a
);
6089 IDWriteFontFace2_Release(fontface2
);
6090 IDWriteFactory_Release(factory
);
6093 static void test_TranslateColorGlyphRun(void)
6095 IDWriteColorGlyphRunEnumerator
*layers
;
6096 const DWRITE_COLOR_GLYPH_RUN
*colorrun
;
6097 IDWriteFontFace2
*fontface2
;
6098 IDWriteFontFace
*fontface
;
6099 IDWriteFactory2
*factory2
;
6100 IDWriteFactory
*factory
;
6101 DWRITE_GLYPH_RUN run
;
6102 UINT32 codepoints
[2];
6108 factory
= create_factory();
6110 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory2
, (void**)&factory2
);
6111 IDWriteFactory_Release(factory
);
6113 win_skip("TranslateColorGlyphRun() is not supported.\n");
6117 /* Tahoma, no color support */
6118 fontface
= create_fontface((IDWriteFactory
*)factory2
);
6120 codepoints
[0] = 'A';
6121 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, codepoints
, 1, glyphs
);
6122 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6124 run
.fontFace
= fontface
;
6125 run
.fontEmSize
= 20.0f
;
6127 run
.glyphIndices
= glyphs
;
6128 run
.glyphAdvances
= NULL
;
6129 run
.glyphOffsets
= NULL
;
6130 run
.isSideways
= FALSE
;
6133 layers
= (void*)0xdeadbeef;
6134 hr
= IDWriteFactory2_TranslateColorGlyphRun(factory2
, 0.0, 0.0, &run
, NULL
,
6135 DWRITE_MEASURING_MODE_NATURAL
, NULL
, 0, &layers
);
6136 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
6137 ok(layers
== NULL
, "got %p\n", layers
);
6138 IDWriteFontFace_Release(fontface
);
6140 /* Segoe UI Emoji, with color support */
6141 font
= get_font((IDWriteFactory
*)factory2
, emojiW
, DWRITE_FONT_STYLE_NORMAL
);
6143 IDWriteFactory2_Release(factory2
);
6144 skip("Segoe UI Emoji font not found.\n");
6148 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
6149 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6150 IDWriteFont_Release(font
);
6152 codepoints
[0] = 0x26c4;
6153 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, codepoints
, 1, glyphs
);
6154 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6156 run
.fontFace
= fontface
;
6159 hr
= IDWriteFactory2_TranslateColorGlyphRun(factory2
, 0.0, 0.0, &run
, NULL
,
6160 DWRITE_MEASURING_MODE_NATURAL
, NULL
, 0, &layers
);
6161 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6162 ok(layers
!= NULL
, "got %p\n", layers
);
6166 hr
= IDWriteColorGlyphRunEnumerator_MoveNext(layers
, &hasrun
);
6167 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6172 hr
= IDWriteColorGlyphRunEnumerator_GetCurrentRun(layers
, &colorrun
);
6173 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6174 ok(colorrun
->glyphRun
.fontFace
!= NULL
, "got fontface %p\n", colorrun
->glyphRun
.fontFace
);
6175 ok(colorrun
->glyphRun
.fontEmSize
== 20.0f
, "got wrong font size %f\n", colorrun
->glyphRun
.fontEmSize
);
6176 ok(colorrun
->glyphRun
.glyphCount
> 0, "got wrong glyph count %u\n", colorrun
->glyphRun
.glyphCount
);
6177 ok(colorrun
->glyphRun
.glyphIndices
!= NULL
, "got null glyph indices %p\n", colorrun
->glyphRun
.glyphIndices
);
6178 ok(colorrun
->glyphRun
.glyphAdvances
!= NULL
, "got null glyph advances %p\n", colorrun
->glyphRun
.glyphAdvances
);
6181 /* iterated all way through */
6182 hr
= IDWriteColorGlyphRunEnumerator_GetCurrentRun(layers
, &colorrun
);
6183 ok(hr
== E_NOT_VALID_STATE
, "got 0x%08x\n", hr
);
6185 IDWriteColorGlyphRunEnumerator_Release(layers
);
6187 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace2
, (void**)&fontface2
);
6188 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6190 /* invalid palette index */
6191 layers
= (void*)0xdeadbeef;
6192 hr
= IDWriteFactory2_TranslateColorGlyphRun(factory2
, 0.0f
, 0.0f
, &run
, NULL
,
6193 DWRITE_MEASURING_MODE_NATURAL
, NULL
, IDWriteFontFace2_GetColorPaletteCount(fontface2
),
6195 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
6196 ok(layers
== NULL
, "got %p\n", layers
);
6199 hr
= IDWriteFactory2_TranslateColorGlyphRun(factory2
, 0.0f
, 0.0f
, &run
, NULL
,
6200 DWRITE_MEASURING_MODE_NATURAL
, NULL
, IDWriteFontFace2_GetColorPaletteCount(fontface2
) - 1,
6202 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6203 IDWriteColorGlyphRunEnumerator_Release(layers
);
6205 /* color font, glyph without color info */
6206 codepoints
[0] = 'A';
6207 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, codepoints
, 1, glyphs
);
6208 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6210 layers
= (void*)0xdeadbeef;
6211 hr
= IDWriteFactory2_TranslateColorGlyphRun(factory2
, 0.0, 0.0, &run
, NULL
,
6212 DWRITE_MEASURING_MODE_NATURAL
, NULL
, 0, &layers
);
6213 ok(hr
== DWRITE_E_NOCOLOR
, "got 0x%08x\n", hr
);
6214 ok(layers
== NULL
, "got %p\n", layers
);
6216 /* one glyph with, one without */
6217 codepoints
[0] = 'A';
6218 codepoints
[1] = 0x26c4;
6220 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, codepoints
, 2, glyphs
);
6221 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6226 hr
= IDWriteFactory2_TranslateColorGlyphRun(factory2
, 0.0, 0.0, &run
, NULL
,
6227 DWRITE_MEASURING_MODE_NATURAL
, NULL
, 0, &layers
);
6228 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6229 ok(layers
!= NULL
, "got %p\n", layers
);
6230 IDWriteColorGlyphRunEnumerator_Release(layers
);
6232 IDWriteFontFace2_Release(fontface2
);
6233 IDWriteFontFace_Release(fontface
);
6234 IDWriteFactory2_Release(factory2
);
6237 static void test_HasCharacter(void)
6239 IDWriteFactory3
*factory3
;
6240 IDWriteFactory
*factory
;
6241 IDWriteFont3
*font3
;
6246 factory
= create_factory();
6248 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_NORMAL
);
6249 ok(font
!= NULL
, "failed to create font\n");
6251 /* Win8 is broken, QI claims to support IDWriteFont3, but in fact it does not */
6252 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory3
, (void**)&factory3
);
6254 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont3
, (void**)&font3
);
6255 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6257 ret
= IDWriteFont3_HasCharacter(font3
, 'A');
6258 ok(ret
, "got %d\n", ret
);
6260 IDWriteFont3_Release(font3
);
6261 IDWriteFactory3_Release(factory3
);
6264 win_skip("IDWriteFont3 is not supported.\n");
6266 IDWriteFont_Release(font
);
6267 IDWriteFactory_Release(factory
);
6270 static void test_CreateFontFaceReference(void)
6272 static const WCHAR dummyW
[] = {'d','u','m','m','y',0};
6273 IDWriteFontFace3
*fontface
, *fontface1
;
6274 IDWriteFontFaceReference
*ref
, *ref1
;
6275 IDWriteFontFile
*file
, *file1
;
6276 IDWriteFactory3
*factory3
;
6277 IDWriteFactory
*factory
;
6278 IDWriteFont3
*font3
;
6285 factory
= create_factory();
6287 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory3
, (void**)&factory3
);
6288 IDWriteFactory_Release(factory
);
6290 win_skip("CreateFontFaceReference() is not supported.\n");
6294 path
= create_testfontfile(test_fontfile
);
6296 hr
= IDWriteFactory3_CreateFontFaceReference(factory3
, NULL
, NULL
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &ref
);
6297 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
6299 /* out of range simulation flags */
6300 hr
= IDWriteFactory3_CreateFontFaceReference(factory3
, path
, NULL
, 0, ~0u, &ref
);
6301 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
6303 /* test file is not a collection, but reference could still be created with non-zero face index */
6304 hr
= IDWriteFactory3_CreateFontFaceReference(factory3
, path
, NULL
, 1, DWRITE_FONT_SIMULATIONS_NONE
, &ref
);
6305 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6307 index
= IDWriteFontFaceReference_GetFontFaceIndex(ref
);
6308 ok(index
== 1, "got %u\n", index
);
6310 hr
= IDWriteFontFaceReference_GetFontFile(ref
, &file
);
6311 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6312 IDWriteFontFile_Release(file
);
6314 hr
= IDWriteFontFaceReference_CreateFontFace(ref
, &fontface
);
6316 ok(hr
== DWRITE_E_FILEFORMAT
, "got 0x%08x\n", hr
);
6318 IDWriteFontFaceReference_Release(ref
);
6320 /* path however has to be valid */
6321 hr
= IDWriteFactory3_CreateFontFaceReference(factory3
, dummyW
, NULL
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &ref
);
6323 ok(hr
== DWRITE_E_FILENOTFOUND
, "got 0x%08x\n", hr
);
6325 IDWriteFontFaceReference_Release(ref
);
6327 EXPECT_REF(factory3
, 1);
6328 hr
= IDWriteFactory3_CreateFontFaceReference(factory3
, path
, NULL
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &ref
);
6329 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6330 EXPECT_REF(factory3
, 2);
6332 /* new file is returned */
6333 hr
= IDWriteFontFaceReference_GetFontFile(ref
, &file
);
6334 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6336 hr
= IDWriteFontFaceReference_GetFontFile(ref
, &file1
);
6337 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6338 ok(file
!= file1
, "got %p, previous file %p\n", file1
, file
);
6340 IDWriteFontFile_Release(file
);
6341 IDWriteFontFile_Release(file1
);
6343 /* references are not reused */
6344 hr
= IDWriteFactory3_CreateFontFaceReference(factory3
, path
, NULL
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &ref1
);
6345 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6346 ok(ref1
!= ref
, "got %p, previous ref %p\n", ref1
, ref
);
6348 /* created fontfaces are cached */
6349 hr
= IDWriteFontFaceReference_CreateFontFace(ref
, &fontface
);
6350 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6352 hr
= IDWriteFontFaceReference_CreateFontFace(ref1
, &fontface1
);
6353 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6354 ok(fontface
== fontface1
, "got %p, expected %p\n", fontface1
, fontface
);
6355 IDWriteFontFace3_Release(fontface
);
6356 IDWriteFontFace3_Release(fontface1
);
6358 /* reference equality */
6359 ret
= IDWriteFontFaceReference_Equals(ref
, ref1
);
6360 ok(ret
, "got %d\n", ret
);
6361 IDWriteFontFaceReference_Release(ref1
);
6363 hr
= IDWriteFactory3_CreateFontFaceReference(factory3
, path
, NULL
, 1, DWRITE_FONT_SIMULATIONS_NONE
, &ref1
);
6364 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6365 ret
= IDWriteFontFaceReference_Equals(ref
, ref1
);
6366 ok(!ret
, "got %d\n", ret
);
6367 IDWriteFontFaceReference_Release(ref1
);
6369 hr
= IDWriteFactory3_CreateFontFaceReference(factory3
, path
, NULL
, 0, DWRITE_FONT_SIMULATIONS_BOLD
, &ref1
);
6370 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6371 ret
= IDWriteFontFaceReference_Equals(ref
, ref1
);
6372 ok(!ret
, "got %d\n", ret
);
6373 IDWriteFontFaceReference_Release(ref1
);
6375 IDWriteFontFaceReference_Release(ref
);
6377 /* create reference from a file */
6378 hr
= IDWriteFactory3_CreateFontFileReference(factory3
, path
, NULL
, &file
);
6379 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6381 hr
= IDWriteFactory3_CreateFontFaceReference_(factory3
, file
, 0, DWRITE_FONT_SIMULATIONS_NONE
, &ref
);
6382 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6384 hr
= IDWriteFontFaceReference_GetFontFile(ref
, &file1
);
6385 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6386 ok(file
!= file1
, "got %p, previous file %p\n", file1
, file
);
6388 IDWriteFontFaceReference_Release(ref
);
6389 IDWriteFontFile_Release(file
);
6390 IDWriteFontFile_Release(file1
);
6392 /* references returned from IDWriteFont3 */
6393 font
= get_tahoma_instance((IDWriteFactory
*)factory3
, DWRITE_FONT_STYLE_NORMAL
);
6394 hr
= IDWriteFont_QueryInterface(font
, &IID_IDWriteFont3
, (void**)&font3
);
6395 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6396 IDWriteFont_Release(font
);
6398 hr
= IDWriteFont3_GetFontFaceReference(font3
, &ref
);
6399 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6401 hr
= IDWriteFont3_GetFontFaceReference(font3
, &ref1
);
6402 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6403 ok(ref
!= ref1
, "got %p, %p\n", ref1
, ref
);
6405 IDWriteFontFaceReference_Release(ref
);
6406 IDWriteFontFaceReference_Release(ref1
);
6408 /* references returned from IDWriteFontFace3 */
6409 hr
= IDWriteFont3_CreateFontFace(font3
, &fontface
);
6410 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6412 hr
= IDWriteFontFace3_GetFontFaceReference(fontface
, &ref
);
6414 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6416 hr
= IDWriteFontFace3_GetFontFaceReference(fontface
, &ref1
);
6418 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6420 ok(ref
== ref1
, "got %p, %p\n", ref1
, ref
);
6423 hr
= IDWriteFontFaceReference_CreateFontFace(ref
, &fontface1
);
6424 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6425 ok(fontface1
== fontface
, "got %p, %p\n", fontface1
, fontface
);
6426 IDWriteFontFace3_Release(fontface1
);
6428 IDWriteFontFaceReference_Release(ref
);
6429 IDWriteFontFaceReference_Release(ref1
);
6431 IDWriteFontFace3_Release(fontface
);
6432 IDWriteFont3_Release(font3
);
6434 IDWriteFactory3_Release(factory3
);
6435 DELETE_FONTFILE(path
);
6438 static void get_expected_fontsig(IDWriteFont
*font
, FONTSIGNATURE
*fontsig
)
6441 IDWriteFontFace
*fontface
;
6442 const TT_OS2_V2
*tt_os2
;
6447 memset(fontsig
, 0, sizeof(*fontsig
));
6449 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
6450 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6452 hr
= IDWriteFontFace_TryGetFontTable(fontface
, MS_0S2_TAG
, (const void**)&tt_os2
, &size
, &os2_context
, &exists
);
6453 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6456 fontsig
->fsUsb
[0] = GET_BE_DWORD(tt_os2
->ulUnicodeRange1
);
6457 fontsig
->fsUsb
[1] = GET_BE_DWORD(tt_os2
->ulUnicodeRange2
);
6458 fontsig
->fsUsb
[2] = GET_BE_DWORD(tt_os2
->ulUnicodeRange3
);
6459 fontsig
->fsUsb
[3] = GET_BE_DWORD(tt_os2
->ulUnicodeRange4
);
6461 if (GET_BE_WORD(tt_os2
->version
) == 0) {
6462 fontsig
->fsCsb
[0] = 0;
6463 fontsig
->fsCsb
[1] = 0;
6466 fontsig
->fsCsb
[0] = GET_BE_DWORD(tt_os2
->ulCodePageRange1
);
6467 fontsig
->fsCsb
[1] = GET_BE_DWORD(tt_os2
->ulCodePageRange2
);
6470 IDWriteFontFace_ReleaseFontTable(fontface
, os2_context
);
6473 IDWriteFontFace_Release(fontface
);
6476 static void test_GetFontSignature(void)
6478 IDWriteFontCollection
*syscollection
;
6479 IDWriteGdiInterop1
*interop1
;
6480 IDWriteGdiInterop
*interop
;
6481 IDWriteFactory
*factory
;
6482 FONTSIGNATURE fontsig
;
6486 factory
= create_factory();
6488 hr
= IDWriteFactory_GetGdiInterop(factory
, &interop
);
6489 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6491 hr
= IDWriteGdiInterop_QueryInterface(interop
, &IID_IDWriteGdiInterop1
, (void**)&interop1
);
6492 IDWriteGdiInterop_Release(interop
);
6494 win_skip("GetFontSignature() is not supported.\n");
6495 IDWriteGdiInterop_Release(interop
);
6496 IDWriteFactory_Release(factory
);
6499 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6501 hr
= IDWriteGdiInterop1_GetFontSignature(interop1
, NULL
, &fontsig
);
6502 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
6504 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &syscollection
, FALSE
);
6505 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6506 count
= IDWriteFontCollection_GetFontFamilyCount(syscollection
);
6508 for (i
= 0; i
< count
; i
++) {
6509 FONTSIGNATURE expected_signature
;
6510 IDWriteLocalizedStrings
*names
;
6511 IDWriteFontFamily
*family
;
6515 hr
= IDWriteFontCollection_GetFontFamily(syscollection
, i
, &family
);
6516 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6518 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STRETCH_NORMAL
,
6519 DWRITE_FONT_STYLE_NORMAL
, &font
);
6520 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6522 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
6523 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6525 get_enus_string(names
, nameW
, sizeof(nameW
)/sizeof(nameW
[0]));
6527 IDWriteLocalizedStrings_Release(names
);
6529 hr
= IDWriteGdiInterop1_GetFontSignature(interop1
, font
, &fontsig
);
6530 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6532 get_expected_fontsig(font
, &expected_signature
);
6534 ok(fontsig
.fsUsb
[0] == expected_signature
.fsUsb
[0], "%s: fsUsb[0] %#x, expected %#x\n", wine_dbgstr_w(nameW
),
6535 fontsig
.fsUsb
[0], expected_signature
.fsUsb
[0]);
6536 ok(fontsig
.fsUsb
[1] == expected_signature
.fsUsb
[1], "%s: fsUsb[1] %#x, expected %#x\n", wine_dbgstr_w(nameW
),
6537 fontsig
.fsUsb
[1], expected_signature
.fsUsb
[1]);
6538 ok(fontsig
.fsUsb
[2] == expected_signature
.fsUsb
[2], "%s: fsUsb[2] %#x, expected %#x\n", wine_dbgstr_w(nameW
),
6539 fontsig
.fsUsb
[2], expected_signature
.fsUsb
[2]);
6540 ok(fontsig
.fsUsb
[3] == expected_signature
.fsUsb
[3], "%s: fsUsb[3] %#x, expected %#x\n", wine_dbgstr_w(nameW
),
6541 fontsig
.fsUsb
[3], expected_signature
.fsUsb
[3]);
6543 ok(fontsig
.fsCsb
[0] == expected_signature
.fsCsb
[0], "%s: fsCsb[0] %#x, expected %#x\n", wine_dbgstr_w(nameW
),
6544 fontsig
.fsCsb
[0], expected_signature
.fsCsb
[0]);
6545 ok(fontsig
.fsCsb
[1] == expected_signature
.fsCsb
[1], "%s: fsCsb[1] %#x, expected %#x\n", wine_dbgstr_w(nameW
),
6546 fontsig
.fsCsb
[1], expected_signature
.fsCsb
[1]);
6548 IDWriteFont_Release(font
);
6549 IDWriteFontFamily_Release(family
);
6552 IDWriteGdiInterop1_Release(interop1
);
6553 IDWriteFontCollection_Release(syscollection
);
6554 IDWriteFactory_Release(factory
);
6557 static void test_font_properties(void)
6559 IDWriteFontFace3
*fontface3
;
6560 IDWriteFontFace
*fontface
;
6561 IDWriteFactory
*factory
;
6562 DWRITE_FONT_STYLE style
;
6566 factory
= create_factory();
6568 /* this creates simulated font */
6569 font
= get_tahoma_instance(factory
, DWRITE_FONT_STYLE_ITALIC
);
6571 style
= IDWriteFont_GetStyle(font
);
6572 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %u\n", style
);
6574 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
6575 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6577 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace3
, (void**)&fontface3
);
6578 IDWriteFontFace_Release(fontface
);
6580 style
= IDWriteFontFace3_GetStyle(fontface3
);
6581 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %u\n", style
);
6583 IDWriteFontFace3_Release(fontface3
);
6586 IDWriteFont_Release(font
);
6587 IDWriteFactory_Release(factory
);
6590 static BOOL
has_vertical_glyph_variants(IDWriteFontFace1
*fontface
)
6592 const OT_FeatureList
*featurelist
;
6593 const OT_LookupList
*lookup_list
;
6594 BOOL exists
= FALSE
, ret
= FALSE
;
6595 const GSUB_Header
*header
;
6602 hr
= IDWriteFontFace1_TryGetFontTable(fontface
, MS_GSUB_TAG
, &data
, &size
, &context
, &exists
);
6603 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6609 featurelist
= (OT_FeatureList
*)((BYTE
*)header
+ GET_BE_WORD(header
->FeatureList
));
6610 lookup_list
= (const OT_LookupList
*)((BYTE
*)header
+ GET_BE_WORD(header
->LookupList
));
6612 for (i
= 0; i
< GET_BE_WORD(featurelist
->FeatureCount
); i
++) {
6613 if (*(UINT32
*)featurelist
->FeatureRecord
[i
].FeatureTag
== DWRITE_FONT_FEATURE_TAG_VERTICAL_WRITING
) {
6614 const OT_Feature
*feature
= (const OT_Feature
*)((BYTE
*)featurelist
+ GET_BE_WORD(featurelist
->FeatureRecord
[i
].Feature
));
6615 UINT16 lookup_count
= GET_BE_WORD(feature
->LookupCount
), i
, index
, count
, type
;
6616 const GSUB_SingleSubstFormat2
*subst2
;
6617 const OT_LookupTable
*lookup_table
;
6620 if (lookup_count
== 0)
6623 for (i
= 0; i
< lookup_count
; i
++) {
6624 /* check if lookup is empty */
6625 index
= GET_BE_WORD(feature
->LookupListIndex
[i
]);
6626 lookup_table
= (const OT_LookupTable
*)((BYTE
*)lookup_list
+ GET_BE_WORD(lookup_list
->Lookup
[index
]));
6628 type
= GET_BE_WORD(lookup_table
->LookupType
);
6629 ok(type
== 1 || type
== 7, "got unexpected lookup type %u\n", type
);
6631 count
= GET_BE_WORD(lookup_table
->SubTableCount
);
6635 ok(count
> 0, "got unexpected subtable count %u\n", count
);
6637 offset
= GET_BE_WORD(lookup_table
->SubTable
[0]);
6639 const GSUB_ExtensionPosFormat1
*ext
= (const GSUB_ExtensionPosFormat1
*)((const BYTE
*)lookup_table
+ offset
);
6640 if (GET_BE_WORD(ext
->SubstFormat
) == 1)
6641 offset
+= GET_BE_DWORD(ext
->ExtensionOffset
);
6643 ok(0, "Unhandled Extension Substitution Format %u\n", GET_BE_WORD(ext
->SubstFormat
));
6646 subst2
= (const GSUB_SingleSubstFormat2
*)((BYTE
*)lookup_table
+ offset
);
6647 index
= GET_BE_WORD(subst2
->SubstFormat
);
6649 ok(0, "validate Single Substitution Format 1\n");
6650 else if (index
== 2) {
6651 /* SimSun-ExtB has 0 glyph count for this substitution */
6652 if (GET_BE_WORD(subst2
->GlyphCount
) > 0) {
6658 ok(0, "unknown Single Substitution Format, %u\n", index
);
6663 IDWriteFontFace1_ReleaseFontTable(fontface
, context
);
6668 static void test_HasVerticalGlyphVariants(void)
6670 IDWriteFontCollection
*syscollection
;
6671 IDWriteFontFace1
*fontface1
;
6672 IDWriteFontFace
*fontface
;
6673 IDWriteFactory
*factory
;
6677 factory
= create_factory();
6678 fontface
= create_fontface(factory
);
6680 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
6681 IDWriteFontFace_Release(fontface
);
6683 win_skip("HasVerticalGlyphVariants() is not supported.\n");
6684 IDWriteFactory_Release(factory
);
6687 IDWriteFontFace1_Release(fontface1
);
6689 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &syscollection
, FALSE
);
6690 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6691 count
= IDWriteFontCollection_GetFontFamilyCount(syscollection
);
6693 for (i
= 0; i
< count
; i
++) {
6694 IDWriteLocalizedStrings
*names
;
6695 BOOL expected_vert
, has_vert
;
6696 IDWriteFontFamily
*family
;
6700 hr
= IDWriteFontCollection_GetFontFamily(syscollection
, i
, &family
);
6701 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6703 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STRETCH_NORMAL
,
6704 DWRITE_FONT_STYLE_NORMAL
, &font
);
6705 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6707 hr
= IDWriteFont_CreateFontFace(font
, &fontface
);
6708 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6710 hr
= IDWriteFontFace_QueryInterface(fontface
, &IID_IDWriteFontFace1
, (void**)&fontface1
);
6711 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6713 hr
= IDWriteFontFamily_GetFamilyNames(family
, &names
);
6714 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
6716 get_enus_string(names
, nameW
, sizeof(nameW
)/sizeof(nameW
[0]));
6718 expected_vert
= has_vertical_glyph_variants(fontface1
);
6719 has_vert
= IDWriteFontFace1_HasVerticalGlyphVariants(fontface1
);
6721 ok(expected_vert
== has_vert
, "%s: expected vertical feature %d, got %d\n",
6722 wine_dbgstr_w(nameW
), expected_vert
, has_vert
);
6724 IDWriteLocalizedStrings_Release(names
);
6725 IDWriteFont_Release(font
);
6727 IDWriteFontFace1_Release(fontface1
);
6728 IDWriteFontFace_Release(fontface
);
6729 IDWriteFontFamily_Release(family
);
6732 IDWriteFontCollection_Release(syscollection
);
6733 IDWriteFactory_Release(factory
);
6738 IDWriteFactory
*factory
;
6740 if (!(factory
= create_factory())) {
6741 win_skip("failed to create factory\n");
6745 test_CreateFontFromLOGFONT();
6746 test_CreateBitmapRenderTarget();
6747 test_GetFontFamily();
6748 test_GetFamilyNames();
6749 test_CreateFontFace();
6751 test_system_fontcollection();
6752 test_ConvertFontFaceToLOGFONT();
6753 test_CustomFontCollection();
6754 test_CreateCustomFontFileReference();
6755 test_CreateFontFileReference();
6756 test_shared_isolated();
6757 test_GetUnicodeRanges();
6758 test_GetFontFromFontFace();
6759 test_GetFirstMatchingFont();
6760 test_GetMatchingFonts();
6761 test_GetInformationalStrings();
6762 test_GetGdiInterop();
6763 test_CreateFontFaceFromHdc();
6764 test_GetSimulations();
6765 test_GetFaceNames();
6766 test_TryGetFontTable();
6767 test_ConvertFontToLOGFONT();
6768 test_CreateStreamFromKey();
6769 test_ReadFileFragment();
6770 test_GetDesignGlyphMetrics();
6771 test_GetDesignGlyphAdvances();
6772 test_IsMonospacedFont();
6773 test_GetGlyphRunOutline();
6774 test_GetEudcFontCollection();
6775 test_GetCaretMetrics();
6776 test_GetGlyphCount();
6777 test_GetKerningPairAdjustments();
6778 test_CreateRenderingParams();
6779 test_CreateGlyphRunAnalysis();
6780 test_GetGdiCompatibleMetrics();
6782 test_GetGdiCompatibleGlyphAdvances();
6783 test_GetRecommendedRenderingMode();
6784 test_GetAlphaBlendParams();
6785 test_CreateAlphaTexture();
6786 test_IsSymbolFont();
6787 test_GetPaletteEntries();
6788 test_TranslateColorGlyphRun();
6789 test_HasCharacter();
6790 test_CreateFontFaceReference();
6791 test_GetFontSignature();
6792 test_font_properties();
6793 test_HasVerticalGlyphVariants();
6795 IDWriteFactory_Release(factory
);