2 * Text layout/format tests
4 * Copyright 2012, 2014-2015 Nikolay Sivov for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/test.h"
31 static const WCHAR tahomaW
[] = {'T','a','h','o','m','a',0};
32 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
34 static DWRITE_SCRIPT_ANALYSIS g_sa
;
35 static DWRITE_SCRIPT_ANALYSIS g_control_sa
;
37 /* test IDWriteTextAnalysisSink */
38 static HRESULT WINAPI
analysissink_QueryInterface(IDWriteTextAnalysisSink
*iface
, REFIID riid
, void **obj
)
40 if (IsEqualIID(riid
, &IID_IDWriteTextAnalysisSink
) || IsEqualIID(riid
, &IID_IUnknown
))
50 static ULONG WINAPI
analysissink_AddRef(IDWriteTextAnalysisSink
*iface
)
55 static ULONG WINAPI
analysissink_Release(IDWriteTextAnalysisSink
*iface
)
60 static HRESULT WINAPI
analysissink_SetScriptAnalysis(IDWriteTextAnalysisSink
*iface
,
61 UINT32 position
, UINT32 length
, DWRITE_SCRIPT_ANALYSIS
const* sa
)
67 static HRESULT WINAPI
analysissink_SetLineBreakpoints(IDWriteTextAnalysisSink
*iface
,
68 UINT32 position
, UINT32 length
, DWRITE_LINE_BREAKPOINT
const* breakpoints
)
70 ok(0, "unexpected call\n");
74 static HRESULT WINAPI
analysissink_SetBidiLevel(IDWriteTextAnalysisSink
*iface
,
75 UINT32 position
, UINT32 length
, UINT8 explicitLevel
, UINT8 resolvedLevel
)
77 ok(0, "unexpected\n");
81 static HRESULT WINAPI
analysissink_SetNumberSubstitution(IDWriteTextAnalysisSink
*iface
,
82 UINT32 position
, UINT32 length
, IDWriteNumberSubstitution
* substitution
)
84 ok(0, "unexpected\n");
88 static IDWriteTextAnalysisSinkVtbl analysissinkvtbl
= {
89 analysissink_QueryInterface
,
92 analysissink_SetScriptAnalysis
,
93 analysissink_SetLineBreakpoints
,
94 analysissink_SetBidiLevel
,
95 analysissink_SetNumberSubstitution
98 static IDWriteTextAnalysisSink analysissink
= { &analysissinkvtbl
};
100 /* test IDWriteTextAnalysisSource */
101 static HRESULT WINAPI
analysissource_QueryInterface(IDWriteTextAnalysisSource
*iface
,
102 REFIID riid
, void **obj
)
104 ok(0, "QueryInterface not expected\n");
108 static ULONG WINAPI
analysissource_AddRef(IDWriteTextAnalysisSource
*iface
)
110 ok(0, "AddRef not expected\n");
114 static ULONG WINAPI
analysissource_Release(IDWriteTextAnalysisSource
*iface
)
116 ok(0, "Release not expected\n");
120 static const WCHAR
*g_source
;
122 static HRESULT WINAPI
analysissource_GetTextAtPosition(IDWriteTextAnalysisSource
*iface
,
123 UINT32 position
, WCHAR
const** text
, UINT32
* text_len
)
125 if (position
>= lstrlenW(g_source
))
132 *text
= &g_source
[position
];
133 *text_len
= lstrlenW(g_source
) - position
;
139 static HRESULT WINAPI
analysissource_GetTextBeforePosition(IDWriteTextAnalysisSource
*iface
,
140 UINT32 position
, WCHAR
const** text
, UINT32
* text_len
)
142 ok(0, "unexpected\n");
146 static DWRITE_READING_DIRECTION WINAPI
analysissource_GetParagraphReadingDirection(
147 IDWriteTextAnalysisSource
*iface
)
149 ok(0, "unexpected\n");
150 return DWRITE_READING_DIRECTION_RIGHT_TO_LEFT
;
153 static HRESULT WINAPI
analysissource_GetLocaleName(IDWriteTextAnalysisSource
*iface
,
154 UINT32 position
, UINT32
* text_len
, WCHAR
const** locale
)
161 static HRESULT WINAPI
analysissource_GetNumberSubstitution(IDWriteTextAnalysisSource
*iface
,
162 UINT32 position
, UINT32
* text_len
, IDWriteNumberSubstitution
**substitution
)
164 ok(0, "unexpected\n");
168 static IDWriteTextAnalysisSourceVtbl analysissourcevtbl
= {
169 analysissource_QueryInterface
,
170 analysissource_AddRef
,
171 analysissource_Release
,
172 analysissource_GetTextAtPosition
,
173 analysissource_GetTextBeforePosition
,
174 analysissource_GetParagraphReadingDirection
,
175 analysissource_GetLocaleName
,
176 analysissource_GetNumberSubstitution
179 static IDWriteTextAnalysisSource analysissource
= { &analysissourcevtbl
};
181 static IDWriteFactory
*create_factory(void)
183 IDWriteFactory
*factory
;
184 HRESULT hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED
, &IID_IDWriteFactory
, (IUnknown
**)&factory
);
185 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
189 /* obvious limitation is that only last script data is returned, so this
190 helper is suitable for single script strings only */
191 static void get_script_analysis(const WCHAR
*str
, UINT32 len
, DWRITE_SCRIPT_ANALYSIS
*sa
)
193 IDWriteTextAnalyzer
*analyzer
;
194 IDWriteFactory
*factory
;
199 factory
= create_factory();
200 hr
= IDWriteFactory_CreateTextAnalyzer(factory
, &analyzer
);
201 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
203 hr
= IDWriteTextAnalyzer_AnalyzeScript(analyzer
, &analysissource
, 0, len
, &analysissink
);
204 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
207 IDWriteFactory_Release(factory
);
210 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
211 static void _expect_ref(IUnknown
* obj
, ULONG ref
, int line
)
213 ULONG rc
= IUnknown_AddRef(obj
);
214 IUnknown_Release(obj
);
215 ok_(__FILE__
,line
)(rc
-1 == ref
, "expected refcount %d, got %d\n", ref
, rc
-1);
226 static const char *get_draw_kind_name(enum drawcall_kind kind
)
228 static const char *kind_names
[] = { "GLYPH_RUN", "UNDERLINE", "STRIKETHROUGH", "INLINE", "END_OF_SEQ" };
229 return kind
> DRAW_LAST_KIND
? "unknown" : kind_names
[kind
];
232 struct drawcall_entry
{
233 enum drawcall_kind kind
;
234 WCHAR string
[10]; /* only meaningful for DrawGlyphRun() */
237 struct drawcall_sequence
241 struct drawcall_entry
*sequence
;
244 struct drawtestcontext
{
245 enum drawcall_kind kind
;
252 #define NUM_CALL_SEQUENCES 1
253 #define RENDERER_ID 0
254 static struct drawcall_sequence
*sequences
[NUM_CALL_SEQUENCES
];
255 static struct drawcall_sequence
*expected_seq
[1];
257 static void add_call(struct drawcall_sequence
**seq
, int sequence_index
, const struct drawcall_entry
*call
)
259 struct drawcall_sequence
*call_seq
= seq
[sequence_index
];
261 if (!call_seq
->sequence
) {
263 call_seq
->sequence
= HeapAlloc(GetProcessHeap(), 0, call_seq
->size
* sizeof (struct drawcall_entry
));
266 if (call_seq
->count
== call_seq
->size
) {
268 call_seq
->sequence
= HeapReAlloc(GetProcessHeap(), 0,
270 call_seq
->size
* sizeof (struct drawcall_entry
));
273 assert(call_seq
->sequence
);
274 call_seq
->sequence
[call_seq
->count
++] = *call
;
277 static inline void flush_sequence(struct drawcall_sequence
**seg
, int sequence_index
)
279 struct drawcall_sequence
*call_seq
= seg
[sequence_index
];
281 HeapFree(GetProcessHeap(), 0, call_seq
->sequence
);
282 call_seq
->sequence
= NULL
;
283 call_seq
->count
= call_seq
->size
= 0;
286 static inline void flush_sequences(struct drawcall_sequence
**seq
, int n
)
289 for (i
= 0; i
< n
; i
++)
290 flush_sequence(seq
, i
);
293 static void init_call_sequences(struct drawcall_sequence
**seq
, int n
)
297 for (i
= 0; i
< n
; i
++)
298 seq
[i
] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct drawcall_sequence
));
301 static void ok_sequence_(struct drawcall_sequence
**seq
, int sequence_index
,
302 const struct drawcall_entry
*expected
, const char *context
, BOOL todo
,
303 const char *file
, int line
)
305 static const struct drawcall_entry end_of_sequence
= { DRAW_LAST_KIND
};
306 struct drawcall_sequence
*call_seq
= seq
[sequence_index
];
307 const struct drawcall_entry
*actual
, *sequence
;
310 add_call(seq
, sequence_index
, &end_of_sequence
);
312 sequence
= call_seq
->sequence
;
315 while (expected
->kind
!= DRAW_LAST_KIND
&& actual
->kind
!= DRAW_LAST_KIND
) {
316 if (expected
->kind
!= actual
->kind
) {
320 ok_(file
, line
) (0, "%s: call %s was expected, but got call %s instead\n",
321 context
, get_draw_kind_name(expected
->kind
), get_draw_kind_name(actual
->kind
));
323 flush_sequence(seq
, sequence_index
);
327 ok_(file
, line
) (0, "%s: call %s was expected, but got call %s instead\n",
328 context
, get_draw_kind_name(expected
->kind
), get_draw_kind_name(actual
->kind
));
330 else if (expected
->kind
== DRAW_GLYPHRUN
) {
331 int cmp
= lstrcmpW(expected
->string
, actual
->string
);
332 if (cmp
!= 0 && todo
) {
335 ok_(file
, line
) (0, "%s: glyphrun string %s was expected, but got %s instead\n",
336 context
, wine_dbgstr_w(expected
->string
), wine_dbgstr_w(actual
->string
));
339 ok_(file
, line
) (cmp
== 0, "%s: glyphrun string %s was expected, but got %s instead\n",
340 context
, wine_dbgstr_w(expected
->string
), wine_dbgstr_w(actual
->string
));
348 if (expected
->kind
!= DRAW_LAST_KIND
|| actual
->kind
!= DRAW_LAST_KIND
) {
350 ok_(file
, line
) (0, "%s: the call sequence is not complete: expected %s - actual %s\n",
351 context
, get_draw_kind_name(expected
->kind
), get_draw_kind_name(actual
->kind
));
355 else if (expected
->kind
!= DRAW_LAST_KIND
|| actual
->kind
!= DRAW_LAST_KIND
)
356 ok_(file
, line
) (0, "%s: the call sequence is not complete: expected %s - actual %s\n",
357 context
, get_draw_kind_name(expected
->kind
), get_draw_kind_name(actual
->kind
));
359 if (todo
&& !failcount
) /* succeeded yet marked todo */
361 ok_(file
, line
)(1, "%s: marked \"todo_wine\" but succeeds\n", context
);
363 flush_sequence(seq
, sequence_index
);
366 #define ok_sequence(seq, index, exp, contx, todo) \
367 ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__)
369 static HRESULT WINAPI
testrenderer_QI(IDWriteTextRenderer
*iface
, REFIID riid
, void **obj
)
371 if (IsEqualIID(riid
, &IID_IDWriteTextRenderer
) ||
372 IsEqualIID(riid
, &IID_IDWritePixelSnapping
) ||
373 IsEqualIID(riid
, &IID_IUnknown
)
381 /* IDWriteTextRenderer1 overrides drawing calls, ignore for now */
382 if (IsEqualIID(riid
, &IID_IDWriteTextRenderer1
))
383 return E_NOINTERFACE
;
385 ok(0, "unexpected QI %s\n", wine_dbgstr_guid(riid
));
386 return E_NOINTERFACE
;
389 static ULONG WINAPI
testrenderer_AddRef(IDWriteTextRenderer
*iface
)
394 static ULONG WINAPI
testrenderer_Release(IDWriteTextRenderer
*iface
)
399 static HRESULT WINAPI
testrenderer_IsPixelSnappingDisabled(IDWriteTextRenderer
*iface
,
400 void *client_drawingcontext
, BOOL
*disabled
)
406 static HRESULT WINAPI
testrenderer_GetCurrentTransform(IDWriteTextRenderer
*iface
,
407 void *client_drawingcontext
, DWRITE_MATRIX
*transform
)
409 transform
->m11
= 1.0;
410 transform
->m12
= 0.0;
411 transform
->m21
= 0.0;
412 transform
->m22
= 1.0;
418 static HRESULT WINAPI
testrenderer_GetPixelsPerDip(IDWriteTextRenderer
*iface
,
419 void *client_drawingcontext
, FLOAT
*pixels_per_dip
)
421 *pixels_per_dip
= 1.0;
425 static HRESULT WINAPI
testrenderer_DrawGlyphRun(IDWriteTextRenderer
*iface
,
426 void* client_drawingcontext
,
427 FLOAT baselineOriginX
,
428 FLOAT baselineOriginY
,
429 DWRITE_MEASURING_MODE mode
,
430 DWRITE_GLYPH_RUN
const *run
,
431 DWRITE_GLYPH_RUN_DESCRIPTION
const *descr
,
432 IUnknown
*drawing_effect
)
434 struct drawcall_entry entry
;
435 DWRITE_SCRIPT_ANALYSIS sa
;
437 ok(descr
->stringLength
< sizeof(entry
.string
)/sizeof(WCHAR
), "string is too long\n");
438 if (descr
->stringLength
&& descr
->stringLength
< sizeof(entry
.string
)/sizeof(WCHAR
)) {
439 memcpy(entry
.string
, descr
->string
, descr
->stringLength
*sizeof(WCHAR
));
440 entry
.string
[descr
->stringLength
] = 0;
445 /* see what's reported for control codes runs */
446 get_script_analysis(descr
->string
, descr
->stringLength
, &sa
);
447 if (sa
.script
== g_control_sa
.script
) {
448 /* glyphs are not reported at all for control code runs */
449 ok(run
->glyphCount
== 0, "got %u\n", run
->glyphCount
);
450 ok(run
->glyphAdvances
!= NULL
, "advances array %p\n", run
->glyphAdvances
);
451 ok(run
->glyphOffsets
!= NULL
, "offsets array %p\n", run
->glyphOffsets
);
452 ok(run
->fontFace
!= NULL
, "got %p\n", run
->fontFace
);
453 /* text positions are still valid */
454 ok(descr
->string
!= NULL
, "got string %p\n", descr
->string
);
455 ok(descr
->stringLength
> 0, "got string length %u\n", descr
->stringLength
);
456 ok(descr
->clusterMap
!= NULL
, "clustermap %p\n", descr
->clusterMap
);
459 entry
.kind
= DRAW_GLYPHRUN
;
460 add_call(sequences
, RENDERER_ID
, &entry
);
464 static HRESULT WINAPI
testrenderer_DrawUnderline(IDWriteTextRenderer
*iface
,
465 void *client_drawingcontext
,
466 FLOAT baselineOriginX
,
467 FLOAT baselineOriginY
,
468 DWRITE_UNDERLINE
const* underline
,
469 IUnknown
*drawing_effect
)
471 struct drawcall_entry entry
;
472 entry
.kind
= DRAW_UNDERLINE
;
473 add_call(sequences
, RENDERER_ID
, &entry
);
477 static HRESULT WINAPI
testrenderer_DrawStrikethrough(IDWriteTextRenderer
*iface
,
478 void *client_drawingcontext
,
479 FLOAT baselineOriginX
,
480 FLOAT baselineOriginY
,
481 DWRITE_STRIKETHROUGH
const* strikethrough
,
482 IUnknown
*drawing_effect
)
484 struct drawcall_entry entry
;
485 entry
.kind
= DRAW_STRIKETHROUGH
;
486 add_call(sequences
, RENDERER_ID
, &entry
);
490 static HRESULT WINAPI
testrenderer_DrawInlineObject(IDWriteTextRenderer
*iface
,
491 void *client_drawingcontext
,
494 IDWriteInlineObject
*object
,
497 IUnknown
*drawing_effect
)
499 struct drawcall_entry entry
;
500 entry
.kind
= DRAW_INLINE
;
501 add_call(sequences
, RENDERER_ID
, &entry
);
505 static const IDWriteTextRendererVtbl testrenderervtbl
= {
508 testrenderer_Release
,
509 testrenderer_IsPixelSnappingDisabled
,
510 testrenderer_GetCurrentTransform
,
511 testrenderer_GetPixelsPerDip
,
512 testrenderer_DrawGlyphRun
,
513 testrenderer_DrawUnderline
,
514 testrenderer_DrawStrikethrough
,
515 testrenderer_DrawInlineObject
518 static IDWriteTextRenderer testrenderer
= { &testrenderervtbl
};
520 /* test IDWriteInlineObject */
521 static HRESULT WINAPI
testinlineobj_QI(IDWriteInlineObject
*iface
, REFIID riid
, void **obj
)
523 if (IsEqualIID(riid
, &IID_IDWriteInlineObject
) || IsEqualIID(riid
, &IID_IUnknown
)) {
525 IDWriteInlineObject_AddRef(iface
);
530 return E_NOINTERFACE
;
533 static ULONG WINAPI
testinlineobj_AddRef(IDWriteInlineObject
*iface
)
538 static ULONG WINAPI
testinlineobj_Release(IDWriteInlineObject
*iface
)
543 static HRESULT WINAPI
testinlineobj_Draw(IDWriteInlineObject
*iface
,
544 void* client_drawingontext
, IDWriteTextRenderer
* renderer
,
545 FLOAT originX
, FLOAT originY
, BOOL is_sideways
, BOOL is_rtl
, IUnknown
*drawing_effect
)
547 ok(0, "unexpected call\n");
551 static HRESULT WINAPI
testinlineobj_GetMetrics(IDWriteInlineObject
*iface
, DWRITE_INLINE_OBJECT_METRICS
*metrics
)
553 metrics
->width
= 123.0;
557 static HRESULT WINAPI
testinlineobj_GetOverhangMetrics(IDWriteInlineObject
*iface
, DWRITE_OVERHANG_METRICS
*overhangs
)
559 ok(0, "unexpected call\n");
563 static HRESULT WINAPI
testinlineobj_GetBreakConditions(IDWriteInlineObject
*iface
, DWRITE_BREAK_CONDITION
*before
,
564 DWRITE_BREAK_CONDITION
*after
)
566 *before
= *after
= DWRITE_BREAK_CONDITION_MUST_BREAK
;
570 static IDWriteInlineObjectVtbl testinlineobjvtbl
= {
572 testinlineobj_AddRef
,
573 testinlineobj_Release
,
575 testinlineobj_GetMetrics
,
576 testinlineobj_GetOverhangMetrics
,
577 testinlineobj_GetBreakConditions
580 static IDWriteInlineObject testinlineobj
= { &testinlineobjvtbl
};
581 static IDWriteInlineObject testinlineobj2
= { &testinlineobjvtbl
};
583 static void test_CreateTextLayout(void)
585 static const WCHAR strW
[] = {'s','t','r','i','n','g',0};
586 IDWriteTextLayout2
*layout2
;
587 IDWriteTextLayout
*layout
;
588 IDWriteTextFormat
*format
;
589 IDWriteFactory
*factory
;
592 factory
= create_factory();
594 hr
= IDWriteFactory_CreateTextLayout(factory
, NULL
, 0, NULL
, 0.0, 0.0, &layout
);
595 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
597 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 6, NULL
, 0.0, 0.0, &layout
);
598 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
600 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 6, NULL
, 1.0, 0.0, &layout
);
601 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
603 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 6, NULL
, 0.0, 1.0, &layout
);
604 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
606 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 6, NULL
, 1000.0, 1000.0, &layout
);
607 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
609 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
610 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
611 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
613 EXPECT_REF(format
, 1);
614 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 6, format
, 1000.0, 1000.0, &layout
);
615 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
616 EXPECT_REF(format
, 1);
618 hr
= IDWriteTextLayout_QueryInterface(layout
, &IID_IDWriteTextLayout2
, (void**)&layout2
);
620 IDWriteTextLayout1
*layout1
;
621 IDWriteTextFormat1
*format1
;
622 IDWriteTextFormat
*format
;
624 hr
= IDWriteTextLayout2_QueryInterface(layout2
, &IID_IDWriteTextLayout1
, (void**)&layout1
);
625 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
626 IDWriteTextLayout1_Release(layout1
);
628 EXPECT_REF(layout2
, 2);
629 hr
= IDWriteTextLayout2_QueryInterface(layout2
, &IID_IDWriteTextFormat1
, (void**)&format1
);
630 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
631 EXPECT_REF(layout2
, 3);
633 hr
= IDWriteTextLayout2_QueryInterface(layout2
, &IID_IDWriteTextFormat
, (void**)&format
);
634 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
635 ok(format
== (IDWriteTextFormat
*)format1
, "got %p, %p\n", format
, format1
);
636 ok(format
!= (IDWriteTextFormat
*)layout2
, "got %p, %p\n", format
, layout2
);
637 EXPECT_REF(layout2
, 4);
639 hr
= IDWriteTextFormat_QueryInterface(format
, &IID_IDWriteTextLayout1
, (void**)&layout1
);
640 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
641 IDWriteTextLayout1_Release(layout1
);
643 IDWriteTextFormat1_Release(format1
);
644 IDWriteTextFormat_Release(format
);
646 hr
= IDWriteTextLayout_QueryInterface(layout
, &IID_IDWriteTextFormat1
, (void**)&format1
);
647 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
648 EXPECT_REF(layout2
, 3);
650 hr
= IDWriteTextLayout_QueryInterface(layout
, &IID_IDWriteTextFormat
, (void**)&format
);
651 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
652 ok(format
== (IDWriteTextFormat
*)format1
, "got %p, %p\n", format
, format1
);
653 EXPECT_REF(layout2
, 4);
655 IDWriteTextFormat1_Release(format1
);
656 IDWriteTextFormat_Release(format
);
657 IDWriteTextLayout2_Release(layout2
);
660 win_skip("IDWriteTextLayout2 is not supported.\n");
662 IDWriteTextLayout_Release(layout
);
663 IDWriteTextFormat_Release(format
);
664 IDWriteFactory_Release(factory
);
667 static void test_CreateGdiCompatibleTextLayout(void)
669 static const WCHAR strW
[] = {'s','t','r','i','n','g',0};
670 IDWriteTextLayout
*layout
;
671 IDWriteTextFormat
*format
;
672 IDWriteFactory
*factory
;
676 factory
= create_factory();
678 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(factory
, NULL
, 0, NULL
, 0.0, 0.0, 0.0, NULL
, FALSE
, &layout
);
679 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
681 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(factory
, strW
, 6, NULL
, 0.0, 0.0, 0.0, NULL
, FALSE
, &layout
);
682 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
684 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(factory
, strW
, 6, NULL
, 1.0, 0.0, 0.0, NULL
, FALSE
, &layout
);
685 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
687 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(factory
, strW
, 6, NULL
, 1.0, 0.0, 1.0, NULL
, FALSE
, &layout
);
688 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
690 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(factory
, strW
, 6, NULL
, 1000.0, 1000.0, 1.0, NULL
, FALSE
, &layout
);
691 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
693 /* create with text format */
694 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
695 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
696 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
697 EXPECT_REF(format
, 1);
699 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(factory
, strW
, 6, format
, 100.0, 100.0, 1.0, NULL
, FALSE
, &layout
);
700 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
701 EXPECT_REF(format
, 1);
702 EXPECT_REF(layout
, 1);
704 IDWriteTextLayout_AddRef(layout
);
705 EXPECT_REF(format
, 1);
706 EXPECT_REF(layout
, 2);
707 IDWriteTextLayout_Release(layout
);
708 IDWriteTextLayout_Release(layout
);
710 /* zero length string is okay */
711 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(factory
, strW
, 0, format
, 100.0, 100.0, 1.0, NULL
, FALSE
, &layout
);
712 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
714 dimension
= IDWriteTextLayout_GetMaxWidth(layout
);
715 ok(dimension
== 100.0, "got %f\n", dimension
);
717 dimension
= IDWriteTextLayout_GetMaxHeight(layout
);
718 ok(dimension
== 100.0, "got %f\n", dimension
);
720 IDWriteTextLayout_Release(layout
);
721 IDWriteTextFormat_Release(format
);
722 IDWriteFactory_Release(factory
);
725 static void test_CreateTextFormat(void)
727 IDWriteFontCollection
*collection
, *syscoll
;
728 DWRITE_PARAGRAPH_ALIGNMENT paralign
;
729 DWRITE_READING_DIRECTION readdir
;
730 DWRITE_WORD_WRAPPING wrapping
;
731 DWRITE_TEXT_ALIGNMENT align
;
732 DWRITE_FLOW_DIRECTION flow
;
733 DWRITE_LINE_SPACING_METHOD method
;
734 DWRITE_TRIMMING trimming
;
735 IDWriteTextFormat
*format
;
736 FLOAT spacing
, baseline
;
737 IDWriteInlineObject
*trimmingsign
;
738 IDWriteFactory
*factory
;
741 factory
= create_factory();
743 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
744 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
745 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
747 if (0) /* crashes on native */
748 hr
= IDWriteTextFormat_GetFontCollection(format
, NULL
);
751 hr
= IDWriteTextFormat_GetFontCollection(format
, &collection
);
752 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
753 ok(collection
!= NULL
, "got %p\n", collection
);
755 hr
= IDWriteFactory_GetSystemFontCollection(factory
, &syscoll
, FALSE
);
756 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
757 ok(collection
== syscoll
, "got %p, was %p\n", syscoll
, collection
);
758 IDWriteFontCollection_Release(syscoll
);
759 IDWriteFontCollection_Release(collection
);
761 /* default format properties */
762 align
= IDWriteTextFormat_GetTextAlignment(format
);
763 ok(align
== DWRITE_TEXT_ALIGNMENT_LEADING
, "got %d\n", align
);
765 paralign
= IDWriteTextFormat_GetParagraphAlignment(format
);
766 ok(paralign
== DWRITE_PARAGRAPH_ALIGNMENT_NEAR
, "got %d\n", paralign
);
768 wrapping
= IDWriteTextFormat_GetWordWrapping(format
);
769 ok(wrapping
== DWRITE_WORD_WRAPPING_WRAP
, "got %d\n", wrapping
);
771 readdir
= IDWriteTextFormat_GetReadingDirection(format
);
772 ok(readdir
== DWRITE_READING_DIRECTION_LEFT_TO_RIGHT
, "got %d\n", readdir
);
774 flow
= IDWriteTextFormat_GetFlowDirection(format
);
775 ok(flow
== DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM
, "got %d\n", flow
);
777 hr
= IDWriteTextFormat_GetLineSpacing(format
, &method
, &spacing
, &baseline
);
778 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
779 ok(spacing
== 0.0, "got %f\n", spacing
);
780 ok(baseline
== 0.0, "got %f\n", baseline
);
781 ok(method
== DWRITE_LINE_SPACING_METHOD_DEFAULT
, "got %d\n", method
);
783 trimming
.granularity
= DWRITE_TRIMMING_GRANULARITY_WORD
;
784 trimming
.delimiter
= 10;
785 trimming
.delimiterCount
= 10;
786 trimmingsign
= (void*)0xdeadbeef;
787 hr
= IDWriteTextFormat_GetTrimming(format
, &trimming
, &trimmingsign
);
788 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
789 ok(trimming
.granularity
== DWRITE_TRIMMING_GRANULARITY_NONE
, "got %d\n", trimming
.granularity
);
790 ok(trimming
.delimiter
== 0, "got %d\n", trimming
.delimiter
);
791 ok(trimming
.delimiterCount
== 0, "got %d\n", trimming
.delimiterCount
);
792 ok(trimmingsign
== NULL
, "got %p\n", trimmingsign
);
795 hr
= IDWriteTextFormat_SetTextAlignment(format
, DWRITE_TEXT_ALIGNMENT_LEADING
);
796 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
798 hr
= IDWriteTextFormat_SetParagraphAlignment(format
, DWRITE_PARAGRAPH_ALIGNMENT_NEAR
);
799 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
801 hr
= IDWriteTextFormat_SetWordWrapping(format
, DWRITE_WORD_WRAPPING_WRAP
);
802 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
804 hr
= IDWriteTextFormat_SetReadingDirection(format
, DWRITE_READING_DIRECTION_LEFT_TO_RIGHT
);
805 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
807 hr
= IDWriteTextFormat_SetFlowDirection(format
, DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM
);
808 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
810 hr
= IDWriteTextFormat_SetLineSpacing(format
, DWRITE_LINE_SPACING_METHOD_DEFAULT
, 0.0, 0.0);
811 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
813 hr
= IDWriteTextFormat_SetTrimming(format
, &trimming
, NULL
);
814 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
816 IDWriteTextFormat_Release(format
);
817 IDWriteFactory_Release(factory
);
820 static void test_GetLocaleName(void)
822 static const WCHAR strW
[] = {'s','t','r','i','n','g',0};
823 static const WCHAR ruW
[] = {'r','u',0};
824 IDWriteTextLayout
*layout
;
825 IDWriteTextFormat
*format
, *format2
;
826 IDWriteFactory
*factory
;
831 factory
= create_factory();
833 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
834 DWRITE_FONT_STRETCH_NORMAL
, 10.0, ruW
, &format
);
835 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
837 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(factory
, strW
, 0, format
, 100.0, 100.0, 1.0, NULL
, FALSE
, &layout
);
838 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
840 hr
= IDWriteTextLayout_QueryInterface(layout
, &IID_IDWriteTextFormat
, (void**)&format2
);
841 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
843 len
= IDWriteTextFormat_GetLocaleNameLength(format2
);
844 ok(len
== 2, "got %u\n", len
);
845 len
= IDWriteTextFormat_GetLocaleNameLength(format
);
846 ok(len
== 2, "got %u\n", len
);
847 hr
= IDWriteTextFormat_GetLocaleName(format2
, buff
, len
);
848 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
849 hr
= IDWriteTextFormat_GetLocaleName(format2
, buff
, len
+1);
850 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
851 ok(!lstrcmpW(buff
, ruW
), "got %s\n", wine_dbgstr_w(buff
));
852 hr
= IDWriteTextFormat_GetLocaleName(format
, buff
, len
);
853 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
854 hr
= IDWriteTextFormat_GetLocaleName(format
, buff
, len
+1);
855 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
856 ok(!lstrcmpW(buff
, ruW
), "got %s\n", wine_dbgstr_w(buff
));
858 IDWriteTextLayout_Release(layout
);
859 IDWriteTextFormat_Release(format
);
860 IDWriteTextFormat_Release(format2
);
861 IDWriteFactory_Release(factory
);
864 static void test_CreateEllipsisTrimmingSign(void)
866 DWRITE_BREAK_CONDITION before
, after
;
867 IDWriteTextFormat
*format
;
868 IDWriteInlineObject
*sign
;
869 IDWriteFactory
*factory
;
872 factory
= create_factory();
874 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
875 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
876 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
878 EXPECT_REF(format
, 1);
879 hr
= IDWriteFactory_CreateEllipsisTrimmingSign(factory
, format
, &sign
);
880 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
881 EXPECT_REF(format
, 1);
883 if (0) /* crashes on native */
884 hr
= IDWriteInlineObject_GetBreakConditions(sign
, NULL
, NULL
);
886 before
= after
= DWRITE_BREAK_CONDITION_CAN_BREAK
;
887 hr
= IDWriteInlineObject_GetBreakConditions(sign
, &before
, &after
);
888 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
889 ok(before
== DWRITE_BREAK_CONDITION_NEUTRAL
, "got %d\n", before
);
890 ok(after
== DWRITE_BREAK_CONDITION_NEUTRAL
, "got %d\n", after
);
892 IDWriteInlineObject_Release(sign
);
893 IDWriteTextFormat_Release(format
);
894 IDWriteFactory_Release(factory
);
897 static void test_fontweight(void)
899 static const WCHAR strW
[] = {'s','t','r','i','n','g',0};
900 static const WCHAR ruW
[] = {'r','u',0};
901 IDWriteTextFormat
*format
, *fmt2
;
902 IDWriteTextLayout
*layout
;
903 DWRITE_FONT_WEIGHT weight
;
904 DWRITE_TEXT_RANGE range
;
905 IDWriteFactory
*factory
;
909 factory
= create_factory();
911 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_BOLD
, DWRITE_FONT_STYLE_NORMAL
,
912 DWRITE_FONT_STRETCH_NORMAL
, 10.0, ruW
, &format
);
913 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
915 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(factory
, strW
, 6, format
, 100.0, 100.0, 1.0, NULL
, FALSE
, &layout
);
916 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
918 hr
= IDWriteTextLayout_QueryInterface(layout
, &IID_IDWriteTextFormat
, (void**)&fmt2
);
919 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
921 weight
= IDWriteTextFormat_GetFontWeight(fmt2
);
922 ok(weight
== DWRITE_FONT_WEIGHT_BOLD
, "got %u\n", weight
);
924 range
.startPosition
= range
.length
= 0;
925 hr
= IDWriteTextLayout_GetFontWeight(layout
, 0, &weight
, &range
);
926 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
928 ok(range
.startPosition
== 0 && range
.length
== ~0u, "got %u, %u\n", range
.startPosition
, range
.length
);
930 range
.startPosition
= 0;
932 hr
= IDWriteTextLayout_SetFontWeight(layout
, DWRITE_FONT_WEIGHT_NORMAL
, range
);
933 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
935 range
.startPosition
= range
.length
= 0;
936 hr
= IDWriteTextLayout_GetFontWeight(layout
, 0, &weight
, &range
);
937 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
938 ok(range
.startPosition
== 0 && range
.length
== 6, "got %u, %u\n", range
.startPosition
, range
.length
);
940 /* IDWriteTextFormat methods output doesn't reflect layout changes */
941 weight
= IDWriteTextFormat_GetFontWeight(fmt2
);
942 ok(weight
== DWRITE_FONT_WEIGHT_BOLD
, "got %u\n", weight
);
945 weight
= DWRITE_FONT_WEIGHT_BOLD
;
946 hr
= IDWriteTextLayout_GetFontWeight(layout
, 0, &weight
, &range
);
947 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
948 ok(weight
== DWRITE_FONT_WEIGHT_NORMAL
, "got %d\n", weight
);
949 ok(range
.length
== 6, "got %d\n", range
.length
);
951 size
= IDWriteTextLayout_GetMaxWidth(layout
);
952 ok(size
== 100.0, "got %.2f\n", size
);
954 hr
= IDWriteTextLayout_SetMaxWidth(layout
, 0.0);
955 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
957 size
= IDWriteTextLayout_GetMaxWidth(layout
);
958 ok(size
== 0.0, "got %.2f\n", size
);
960 hr
= IDWriteTextLayout_SetMaxWidth(layout
, -1.0);
961 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
963 size
= IDWriteTextLayout_GetMaxWidth(layout
);
964 ok(size
== 0.0, "got %.2f\n", size
);
966 hr
= IDWriteTextLayout_SetMaxWidth(layout
, 100.0);
967 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
969 size
= IDWriteTextLayout_GetMaxWidth(layout
);
970 ok(size
== 100.0, "got %.2f\n", size
);
972 size
= IDWriteTextLayout_GetMaxHeight(layout
);
973 ok(size
== 100.0, "got %.2f\n", size
);
975 hr
= IDWriteTextLayout_SetMaxHeight(layout
, 0.0);
976 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
978 size
= IDWriteTextLayout_GetMaxHeight(layout
);
979 ok(size
== 0.0, "got %.2f\n", size
);
981 hr
= IDWriteTextLayout_SetMaxHeight(layout
, -1.0);
982 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
984 size
= IDWriteTextLayout_GetMaxHeight(layout
);
985 ok(size
== 0.0, "got %.2f\n", size
);
987 hr
= IDWriteTextLayout_SetMaxHeight(layout
, 100.0);
988 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
990 size
= IDWriteTextLayout_GetMaxHeight(layout
);
991 ok(size
== 100.0, "got %.2f\n", size
);
993 IDWriteTextLayout_Release(layout
);
994 IDWriteTextFormat_Release(fmt2
);
995 IDWriteTextFormat_Release(format
);
996 IDWriteFactory_Release(factory
);
999 static void test_SetInlineObject(void)
1001 static const WCHAR strW
[] = {'s','t','r','i','n','g',0};
1002 static const WCHAR ruW
[] = {'r','u',0};
1004 IDWriteInlineObject
*inlineobj
, *inlineobj2
, *inlinetest
;
1005 IDWriteTextFormat
*format
;
1006 IDWriteTextLayout
*layout
;
1007 DWRITE_TEXT_RANGE range
, r2
;
1008 IDWriteFactory
*factory
;
1011 factory
= create_factory();
1013 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_BOLD
, DWRITE_FONT_STYLE_NORMAL
,
1014 DWRITE_FONT_STRETCH_NORMAL
, 10.0, ruW
, &format
);
1015 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1017 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(factory
, strW
, 6, format
, 100.0, 100.0, 1.0, NULL
, FALSE
, &layout
);
1018 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1020 hr
= IDWriteFactory_CreateEllipsisTrimmingSign(factory
, format
, &inlineobj
);
1021 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1023 hr
= IDWriteFactory_CreateEllipsisTrimmingSign(factory
, format
, &inlineobj2
);
1024 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1026 EXPECT_REF(inlineobj
, 1);
1027 EXPECT_REF(inlineobj2
, 1);
1029 inlinetest
= (void*)0x1;
1030 hr
= IDWriteTextLayout_GetInlineObject(layout
, 0, &inlinetest
, NULL
);
1031 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1032 ok(inlinetest
== NULL
, "got %p\n", inlinetest
);
1034 range
.startPosition
= 0;
1036 hr
= IDWriteTextLayout_SetInlineObject(layout
, inlineobj
, range
);
1037 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1039 EXPECT_REF(inlineobj
, 2);
1041 inlinetest
= (void*)0x1;
1042 hr
= IDWriteTextLayout_GetInlineObject(layout
, 2, &inlinetest
, NULL
);
1043 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1044 ok(inlinetest
== NULL
, "got %p\n", inlinetest
);
1047 r2
.startPosition
= r2
.length
= 100;
1048 hr
= IDWriteTextLayout_GetInlineObject(layout
, 0, &inlinetest
, &r2
);
1049 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1050 ok(inlinetest
== inlineobj
, "got %p\n", inlinetest
);
1051 ok(r2
.startPosition
== 0 && r2
.length
== 2, "got %d, %d\n", r2
.startPosition
, r2
.length
);
1052 IDWriteInlineObject_Release(inlinetest
);
1054 EXPECT_REF(inlineobj
, 2);
1056 /* get from somewhere inside a range */
1058 r2
.startPosition
= r2
.length
= 100;
1059 hr
= IDWriteTextLayout_GetInlineObject(layout
, 1, &inlinetest
, &r2
);
1060 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1061 ok(inlinetest
== inlineobj
, "got %p\n", inlinetest
);
1062 ok(r2
.startPosition
== 0 && r2
.length
== 2, "got %d, %d\n", r2
.startPosition
, r2
.length
);
1063 IDWriteInlineObject_Release(inlinetest
);
1065 EXPECT_REF(inlineobj
, 2);
1067 range
.startPosition
= 1;
1069 hr
= IDWriteTextLayout_SetInlineObject(layout
, inlineobj2
, range
);
1070 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1073 r2
.startPosition
= r2
.length
= 100;
1074 hr
= IDWriteTextLayout_GetInlineObject(layout
, 1, &inlinetest
, &r2
);
1075 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1076 ok(inlinetest
== inlineobj2
, "got %p\n", inlinetest
);
1077 ok(r2
.startPosition
== 1 && r2
.length
== 1, "got %d, %d\n", r2
.startPosition
, r2
.length
);
1078 IDWriteInlineObject_Release(inlinetest
);
1080 EXPECT_REF(inlineobj
, 2);
1081 EXPECT_REF(inlineobj2
, 2);
1084 r2
.startPosition
= r2
.length
= 100;
1085 hr
= IDWriteTextLayout_GetInlineObject(layout
, 0, &inlinetest
, &r2
);
1086 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1087 ok(inlinetest
== inlineobj
, "got %p\n", inlinetest
);
1088 ok(r2
.startPosition
== 0 && r2
.length
== 1, "got %d, %d\n", r2
.startPosition
, r2
.length
);
1089 IDWriteInlineObject_Release(inlinetest
);
1091 EXPECT_REF(inlineobj
, 2);
1093 range
.startPosition
= 1;
1095 hr
= IDWriteTextLayout_SetInlineObject(layout
, inlineobj
, range
);
1096 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1098 r2
.startPosition
= r2
.length
= 100;
1099 hr
= IDWriteTextLayout_GetInlineObject(layout
, 0, &inlinetest
, &r2
);
1100 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1101 ok(inlinetest
== inlineobj
, "got %p\n", inlinetest
);
1102 ok(r2
.startPosition
== 0 && r2
.length
== 2, "got %d, %d\n", r2
.startPosition
, r2
.length
);
1103 IDWriteInlineObject_Release(inlinetest
);
1105 EXPECT_REF(inlineobj
, 2);
1107 range
.startPosition
= 1;
1109 hr
= IDWriteTextLayout_SetInlineObject(layout
, inlineobj
, range
);
1110 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1112 EXPECT_REF(inlineobj
, 2);
1114 r2
.startPosition
= r2
.length
= 100;
1115 hr
= IDWriteTextLayout_GetInlineObject(layout
, 0, &inlinetest
, &r2
);
1116 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1117 ok(inlinetest
== inlineobj
, "got %p\n", inlinetest
);
1118 ok(r2
.startPosition
== 0 && r2
.length
== 3, "got %d, %d\n", r2
.startPosition
, r2
.length
);
1119 IDWriteInlineObject_Release(inlinetest
);
1121 EXPECT_REF(inlineobj
, 2);
1122 EXPECT_REF(inlineobj2
, 1);
1124 IDWriteTextLayout_Release(layout
);
1126 EXPECT_REF(inlineobj
, 1);
1128 IDWriteInlineObject_Release(inlineobj
);
1129 IDWriteInlineObject_Release(inlineobj2
);
1130 IDWriteTextFormat_Release(format
);
1131 IDWriteFactory_Release(factory
);
1134 /* drawing calls sequence doesn't depend on run order, instead all runs are
1135 drawn first, inline objects next and then underline/strikes */
1136 static const struct drawcall_entry draw_seq
[] = {
1137 { DRAW_GLYPHRUN
, {'s',0} },
1138 { DRAW_GLYPHRUN
, {'r','i',0} },
1139 { DRAW_GLYPHRUN
, {'n',0} },
1140 { DRAW_GLYPHRUN
, {'g',0} },
1143 { DRAW_STRIKETHROUGH
},
1147 static const struct drawcall_entry draw_seq2
[] = {
1148 { DRAW_GLYPHRUN
, {'s',0} },
1149 { DRAW_GLYPHRUN
, {'t',0} },
1150 { DRAW_GLYPHRUN
, {'r',0} },
1151 { DRAW_GLYPHRUN
, {'i',0} },
1152 { DRAW_GLYPHRUN
, {'n',0} },
1153 { DRAW_GLYPHRUN
, {'g',0} },
1157 static const struct drawcall_entry draw_seq3
[] = {
1159 { DRAW_GLYPHRUN
, {'a','b',0} },
1163 static const struct drawcall_entry draw_seq4
[] = {
1164 { DRAW_GLYPHRUN
, {'s','t','r',0} },
1165 { DRAW_GLYPHRUN
, {'i','n','g',0} },
1166 { DRAW_STRIKETHROUGH
},
1170 static const struct drawcall_entry draw_seq5
[] = {
1171 { DRAW_GLYPHRUN
, {'s','t',0} },
1172 { DRAW_GLYPHRUN
, {'r','i',0} },
1173 { DRAW_GLYPHRUN
, {'n','g',0} },
1174 { DRAW_STRIKETHROUGH
},
1178 static void test_Draw(void)
1180 static const WCHAR strW
[] = {'s','t','r','i','n','g',0};
1181 static const WCHAR str2W
[] = {0x202a,0x202c,'a','b',0};
1182 static const WCHAR ruW
[] = {'r','u',0};
1184 IDWriteInlineObject
*inlineobj
;
1185 IDWriteTextFormat
*format
;
1186 IDWriteTextLayout
*layout
;
1187 DWRITE_TEXT_RANGE range
;
1188 IDWriteFactory
*factory
;
1191 factory
= create_factory();
1193 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_BOLD
, DWRITE_FONT_STYLE_NORMAL
,
1194 DWRITE_FONT_STRETCH_NORMAL
, 10.0, ruW
, &format
);
1195 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1197 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 6, format
, 100.0, 100.0, &layout
);
1198 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1200 hr
= IDWriteFactory_CreateEllipsisTrimmingSign(factory
, format
, &inlineobj
);
1201 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1203 range
.startPosition
= 5;
1205 hr
= IDWriteTextLayout_SetStrikethrough(layout
, TRUE
, range
);
1206 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1208 range
.startPosition
= 1;
1210 hr
= IDWriteTextLayout_SetInlineObject(layout
, inlineobj
, range
);
1211 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1213 range
.startPosition
= 4;
1215 hr
= IDWriteTextLayout_SetDrawingEffect(layout
, (IUnknown
*)inlineobj
, range
);
1216 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1218 range
.startPosition
= 0;
1220 hr
= IDWriteTextLayout_SetUnderline(layout
, TRUE
, range
);
1221 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1223 flush_sequence(sequences
, RENDERER_ID
);
1224 hr
= IDWriteTextLayout_Draw(layout
, NULL
, &testrenderer
, 0.0, 0.0);
1225 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1226 ok_sequence(sequences
, RENDERER_ID
, draw_seq
, "draw test", TRUE
);
1227 IDWriteTextLayout_Release(layout
);
1229 /* with reduced width DrawGlyphRun() is called for every line */
1230 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 6, format
, 5.0, 100.0, &layout
);
1231 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1232 flush_sequence(sequences
, RENDERER_ID
);
1233 hr
= IDWriteTextLayout_Draw(layout
, NULL
, &testrenderer
, 0.0, 0.0);
1234 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1235 ok_sequence(sequences
, RENDERER_ID
, draw_seq2
, "draw test 2", TRUE
);
1236 IDWriteTextLayout_Release(layout
);
1238 /* string with control characters */
1239 hr
= IDWriteFactory_CreateTextLayout(factory
, str2W
, 4, format
, 500.0, 100.0, &layout
);
1240 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1241 flush_sequence(sequences
, RENDERER_ID
);
1242 hr
= IDWriteTextLayout_Draw(layout
, NULL
, &testrenderer
, 0.0, 0.0);
1243 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1244 ok_sequence(sequences
, RENDERER_ID
, draw_seq3
, "draw test 3", TRUE
);
1245 IDWriteTextLayout_Release(layout
);
1247 /* strikethrough splits ranges from renderer point of view, but doesn't break
1249 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 6, format
, 500.0, 100.0, &layout
);
1250 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1251 flush_sequence(sequences
, RENDERER_ID
);
1253 range
.startPosition
= 0;
1255 hr
= IDWriteTextLayout_SetStrikethrough(layout
, TRUE
, range
);
1256 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1258 hr
= IDWriteTextLayout_Draw(layout
, NULL
, &testrenderer
, 0.0, 0.0);
1259 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1260 ok_sequence(sequences
, RENDERER_ID
, draw_seq4
, "draw test 4", FALSE
);
1261 IDWriteTextLayout_Release(layout
);
1263 /* strikethrough somewhere in the middle */
1264 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 6, format
, 500.0, 100.0, &layout
);
1265 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1266 flush_sequence(sequences
, RENDERER_ID
);
1268 range
.startPosition
= 2;
1270 hr
= IDWriteTextLayout_SetStrikethrough(layout
, TRUE
, range
);
1271 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1273 hr
= IDWriteTextLayout_Draw(layout
, NULL
, &testrenderer
, 0.0, 0.0);
1274 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1275 ok_sequence(sequences
, RENDERER_ID
, draw_seq5
, "draw test 5", FALSE
);
1276 IDWriteTextLayout_Release(layout
);
1278 IDWriteTextFormat_Release(format
);
1279 IDWriteFactory_Release(factory
);
1282 static void test_typography(void)
1284 DWRITE_FONT_FEATURE feature
;
1285 IDWriteTypography
*typography
;
1286 IDWriteFactory
*factory
;
1290 factory
= create_factory();
1292 hr
= IDWriteFactory_CreateTypography(factory
, &typography
);
1293 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1295 feature
.nameTag
= DWRITE_FONT_FEATURE_TAG_KERNING
;
1296 feature
.parameter
= 1;
1297 hr
= IDWriteTypography_AddFontFeature(typography
, feature
);
1298 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1300 count
= IDWriteTypography_GetFontFeatureCount(typography
);
1301 ok(count
== 1, "got %u\n", count
);
1303 /* duplicated features work just fine */
1304 feature
.nameTag
= DWRITE_FONT_FEATURE_TAG_KERNING
;
1305 feature
.parameter
= 0;
1306 hr
= IDWriteTypography_AddFontFeature(typography
, feature
);
1307 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1309 count
= IDWriteTypography_GetFontFeatureCount(typography
);
1310 ok(count
== 2, "got %u\n", count
);
1312 memset(&feature
, 0, sizeof(feature
));
1313 hr
= IDWriteTypography_GetFontFeature(typography
, 0, &feature
);
1314 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1315 ok(feature
.nameTag
== DWRITE_FONT_FEATURE_TAG_KERNING
, "got tag %x\n", feature
.nameTag
);
1316 ok(feature
.parameter
== 1, "got %u\n", feature
.parameter
);
1318 memset(&feature
, 0, sizeof(feature
));
1319 hr
= IDWriteTypography_GetFontFeature(typography
, 1, &feature
);
1320 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1321 ok(feature
.nameTag
== DWRITE_FONT_FEATURE_TAG_KERNING
, "got tag %x\n", feature
.nameTag
);
1322 ok(feature
.parameter
== 0, "got %u\n", feature
.parameter
);
1324 hr
= IDWriteTypography_GetFontFeature(typography
, 2, &feature
);
1325 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1327 IDWriteTypography_Release(typography
);
1328 IDWriteFactory_Release(factory
);
1331 static void test_GetClusterMetrics(void)
1333 static const WCHAR str2W
[] = {0x202a,0x202c,'a',0};
1334 static const WCHAR strW
[] = {'a','b','c','d',0};
1335 DWRITE_INLINE_OBJECT_METRICS inline_metrics
;
1336 DWRITE_CLUSTER_METRICS metrics
[4];
1337 IDWriteTextLayout1
*layout1
;
1338 IDWriteInlineObject
*trimm
;
1339 IDWriteTextFormat
*format
;
1340 IDWriteTextLayout
*layout
;
1341 DWRITE_TEXT_RANGE range
;
1342 IDWriteFactory
*factory
;
1346 factory
= create_factory();
1348 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
1349 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
1350 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1352 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 4, format
, 1000.0, 1000.0, &layout
);
1353 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1356 hr
= IDWriteTextLayout_GetClusterMetrics(layout
, NULL
, 0, &count
);
1357 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1358 ok(count
== 4, "got %u\n", count
);
1360 /* check every cluster width */
1362 hr
= IDWriteTextLayout_GetClusterMetrics(layout
, metrics
, sizeof(metrics
)/sizeof(metrics
[0]), &count
);
1363 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1364 ok(count
== 4, "got %u\n", count
);
1365 for (i
= 0; i
< count
; i
++) {
1366 ok(metrics
[i
].width
> 0.0, "%u: got width %.2f\n", i
, metrics
[i
].width
);
1367 ok(metrics
[i
].length
== 1, "%u: got length %u\n", i
, metrics
[i
].length
);
1370 /* apply spacing and check widths again */
1371 if (IDWriteTextLayout_QueryInterface(layout
, &IID_IDWriteTextLayout1
, (void**)&layout1
) == S_OK
) {
1372 DWRITE_CLUSTER_METRICS metrics2
[4];
1373 FLOAT leading
, trailing
, min_advance
;
1374 DWRITE_TEXT_RANGE r
;
1376 leading
= trailing
= min_advance
= 2.0;
1377 hr
= IDWriteTextLayout1_GetCharacterSpacing(layout1
, 0, &leading
, &trailing
,
1378 &min_advance
, NULL
);
1380 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1381 ok(leading
== 0.0 && trailing
== 0.0 && min_advance
== 0.0,
1382 "got %.2f, %.2f, %.2f\n", leading
, trailing
, min_advance
);
1384 r
.startPosition
= 0;
1386 hr
= IDWriteTextLayout1_SetCharacterSpacing(layout1
, 10.0, 15.0, 0.0, r
);
1388 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1391 hr
= IDWriteTextLayout_GetClusterMetrics(layout
, metrics2
, sizeof(metrics2
)/sizeof(metrics2
[0]), &count
);
1392 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1393 ok(count
== 4, "got %u\n", count
);
1394 for (i
= 0; i
< count
; i
++) {
1396 ok(metrics2
[i
].width
> metrics
[i
].width
, "%u: got width %.2f, was %.2f\n", i
, metrics2
[i
].width
,
1398 ok(metrics2
[i
].length
== 1, "%u: got length %u\n", i
, metrics2
[i
].length
);
1401 /* back to defaults */
1402 r
.startPosition
= 0;
1404 hr
= IDWriteTextLayout1_SetCharacterSpacing(layout1
, 0.0, 0.0, 0.0, r
);
1406 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1408 IDWriteTextLayout1_Release(layout1
);
1411 win_skip("IDWriteTextLayout1 is not supported, cluster spacing test skipped.\n");
1413 hr
= IDWriteFactory_CreateEllipsisTrimmingSign(factory
, format
, &trimm
);
1414 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1416 range
.startPosition
= 0;
1418 hr
= IDWriteTextLayout_SetInlineObject(layout
, trimm
, range
);
1419 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1421 /* inline object takes a separate cluster, replaced codepoints number doesn't matter */
1423 hr
= IDWriteTextLayout_GetClusterMetrics(layout
, NULL
, 0, &count
);
1424 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1425 ok(count
== 3, "got %u\n", count
);
1428 memset(&metrics
, 0, sizeof(metrics
));
1429 hr
= IDWriteTextLayout_GetClusterMetrics(layout
, metrics
, 1, &count
);
1430 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1431 ok(count
== 3, "got %u\n", count
);
1432 ok(metrics
[0].length
== 2, "got %u\n", metrics
[0].length
);
1434 hr
= IDWriteInlineObject_GetMetrics(trimm
, &inline_metrics
);
1435 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1437 ok(inline_metrics
.width
> 0.0 && inline_metrics
.width
== metrics
[0].width
, "got %.2f, expected %.2f\n",
1438 inline_metrics
.width
, metrics
[0].width
);
1440 IDWriteTextLayout_Release(layout
);
1442 /* text with non-visual control codes */
1443 hr
= IDWriteFactory_CreateTextLayout(factory
, str2W
, 3, format
, 1000.0, 1000.0, &layout
);
1444 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1446 /* bidi control codes take a separate cluster */
1448 memset(metrics
, 0, sizeof(metrics
));
1449 hr
= IDWriteTextLayout_GetClusterMetrics(layout
, metrics
, 3, &count
);
1450 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1451 ok(count
== 3, "got %u\n", count
);
1453 ok(metrics
[0].width
== 0.0, "got %.2f\n", metrics
[0].width
);
1454 ok(metrics
[0].length
== 1, "got %d\n", metrics
[0].length
);
1455 ok(metrics
[0].canWrapLineAfter
== 0, "got %d\n", metrics
[0].canWrapLineAfter
);
1456 ok(metrics
[0].isWhitespace
== 0, "got %d\n", metrics
[0].isWhitespace
);
1457 ok(metrics
[0].isNewline
== 0, "got %d\n", metrics
[0].isNewline
);
1458 ok(metrics
[0].isSoftHyphen
== 0, "got %d\n", metrics
[0].isSoftHyphen
);
1459 ok(metrics
[0].isRightToLeft
== 0, "got %d\n", metrics
[0].isRightToLeft
);
1461 ok(metrics
[1].width
== 0.0, "got %.2f\n", metrics
[1].width
);
1462 ok(metrics
[1].length
== 1, "got %d\n", metrics
[1].length
);
1463 ok(metrics
[1].canWrapLineAfter
== 0, "got %d\n", metrics
[1].canWrapLineAfter
);
1464 ok(metrics
[1].isWhitespace
== 0, "got %d\n", metrics
[1].isWhitespace
);
1465 ok(metrics
[1].isNewline
== 0, "got %d\n", metrics
[1].isNewline
);
1466 ok(metrics
[1].isSoftHyphen
== 0, "got %d\n", metrics
[1].isSoftHyphen
);
1467 ok(metrics
[1].isRightToLeft
== 0, "got %d\n", metrics
[1].isRightToLeft
);
1469 ok(metrics
[2].width
> 0.0, "got %.2f\n", metrics
[2].width
);
1470 ok(metrics
[2].length
== 1, "got %d\n", metrics
[2].length
);
1472 ok(metrics
[2].canWrapLineAfter
== 1, "got %d\n", metrics
[2].canWrapLineAfter
);
1473 ok(metrics
[2].isWhitespace
== 0, "got %d\n", metrics
[2].isWhitespace
);
1474 ok(metrics
[2].isNewline
== 0, "got %d\n", metrics
[2].isNewline
);
1475 ok(metrics
[2].isSoftHyphen
== 0, "got %d\n", metrics
[2].isSoftHyphen
);
1476 ok(metrics
[2].isRightToLeft
== 0, "got %d\n", metrics
[2].isRightToLeft
);
1478 IDWriteTextLayout_Release(layout
);
1480 /* single inline object that fails to report its metrics */
1481 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 4, format
, 1000.0, 1000.0, &layout
);
1482 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1484 range
.startPosition
= 0;
1486 hr
= IDWriteTextLayout_SetInlineObject(layout
, &testinlineobj
, range
);
1487 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1490 memset(metrics
, 0, sizeof(metrics
));
1491 hr
= IDWriteTextLayout_GetClusterMetrics(layout
, metrics
, 3, &count
);
1492 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1493 ok(count
== 1, "got %u\n", count
);
1495 /* object sets a width to 123.0, but returns failure from GetMetrics() */
1496 ok(metrics
[0].width
== 0.0, "got %.2f\n", metrics
[0].width
);
1497 ok(metrics
[0].length
== 4, "got %d\n", metrics
[0].length
);
1499 ok(metrics
[0].canWrapLineAfter
== 1, "got %d\n", metrics
[0].canWrapLineAfter
);
1500 ok(metrics
[0].isWhitespace
== 0, "got %d\n", metrics
[0].isWhitespace
);
1501 ok(metrics
[0].isNewline
== 0, "got %d\n", metrics
[0].isNewline
);
1502 ok(metrics
[0].isSoftHyphen
== 0, "got %d\n", metrics
[0].isSoftHyphen
);
1503 ok(metrics
[0].isRightToLeft
== 0, "got %d\n", metrics
[0].isRightToLeft
);
1505 /* now set two inline object for [0,1] and [2,3], both fail to report break conditions */
1506 range
.startPosition
= 2;
1508 hr
= IDWriteTextLayout_SetInlineObject(layout
, &testinlineobj2
, range
);
1509 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1512 memset(metrics
, 0, sizeof(metrics
));
1513 hr
= IDWriteTextLayout_GetClusterMetrics(layout
, metrics
, 3, &count
);
1514 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1515 ok(count
== 2, "got %u\n", count
);
1517 ok(metrics
[0].width
== 0.0, "got %.2f\n", metrics
[0].width
);
1518 ok(metrics
[0].length
== 2, "got %d\n", metrics
[0].length
);
1519 ok(metrics
[0].canWrapLineAfter
== 0, "got %d\n", metrics
[0].canWrapLineAfter
);
1520 ok(metrics
[0].isWhitespace
== 0, "got %d\n", metrics
[0].isWhitespace
);
1521 ok(metrics
[0].isNewline
== 0, "got %d\n", metrics
[0].isNewline
);
1522 ok(metrics
[0].isSoftHyphen
== 0, "got %d\n", metrics
[0].isSoftHyphen
);
1523 ok(metrics
[0].isRightToLeft
== 0, "got %d\n", metrics
[0].isRightToLeft
);
1525 ok(metrics
[1].width
== 0.0, "got %.2f\n", metrics
[1].width
);
1526 ok(metrics
[1].length
== 2, "got %d\n", metrics
[1].length
);
1528 ok(metrics
[1].canWrapLineAfter
== 1, "got %d\n", metrics
[1].canWrapLineAfter
);
1529 ok(metrics
[1].isWhitespace
== 0, "got %d\n", metrics
[1].isWhitespace
);
1530 ok(metrics
[1].isNewline
== 0, "got %d\n", metrics
[1].isNewline
);
1531 ok(metrics
[1].isSoftHyphen
== 0, "got %d\n", metrics
[1].isSoftHyphen
);
1532 ok(metrics
[1].isRightToLeft
== 0, "got %d\n", metrics
[1].isRightToLeft
);
1534 IDWriteTextLayout_Release(layout
);
1536 IDWriteInlineObject_Release(trimm
);
1537 IDWriteTextFormat_Release(format
);
1538 IDWriteFactory_Release(factory
);
1541 static void test_SetLocaleName(void)
1543 static const WCHAR strW
[] = {'a','b','c','d',0};
1544 WCHAR buffW
[LOCALE_NAME_MAX_LENGTH
+sizeof(strW
)/sizeof(WCHAR
)];
1545 IDWriteTextFormat
*format
;
1546 IDWriteTextLayout
*layout
;
1547 DWRITE_TEXT_RANGE range
;
1548 IDWriteFactory
*factory
;
1551 factory
= create_factory();
1553 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
1554 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
1555 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1557 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 4, format
, 1000.0, 1000.0, &layout
);
1558 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1560 range
.startPosition
= 0;
1562 hr
= IDWriteTextLayout_SetLocaleName(layout
, enusW
, range
);
1563 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1565 hr
= IDWriteTextLayout_SetLocaleName(layout
, NULL
, range
);
1566 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1568 /* invalid locale name is allowed */
1569 hr
= IDWriteTextLayout_SetLocaleName(layout
, strW
, range
);
1570 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1572 hr
= IDWriteTextLayout_GetLocaleName(layout
, 0, NULL
, 0, NULL
);
1573 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1575 if (0) /* crashes on native */
1576 hr
= IDWriteTextLayout_GetLocaleName(layout
, 0, NULL
, 1, NULL
);
1579 hr
= IDWriteTextLayout_GetLocaleName(layout
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
), NULL
);
1580 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1581 ok(!lstrcmpW(buffW
, strW
), "got %s\n", wine_dbgstr_w(buffW
));
1583 /* get with a shorter buffer */
1585 hr
= IDWriteTextLayout_GetLocaleName(layout
, 0, buffW
, 1, NULL
);
1586 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "got 0x%08x\n", hr
);
1587 ok(buffW
[0] == 0, "got %x\n", buffW
[0]);
1589 /* name is too long */
1590 lstrcpyW(buffW
, strW
);
1591 while (lstrlenW(buffW
) <= LOCALE_NAME_MAX_LENGTH
)
1592 lstrcatW(buffW
, strW
);
1594 range
.startPosition
= 0;
1596 hr
= IDWriteTextLayout_SetLocaleName(layout
, buffW
, range
);
1597 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1600 hr
= IDWriteTextLayout_GetLocaleName(layout
, 0, buffW
, sizeof(buffW
)/sizeof(WCHAR
), NULL
);
1601 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1602 ok(!lstrcmpW(buffW
, strW
), "got %s\n", wine_dbgstr_w(buffW
));
1604 IDWriteTextLayout_Release(layout
);
1605 IDWriteTextFormat_Release(format
);
1606 IDWriteFactory_Release(factory
);
1609 static void test_SetPairKerning(void)
1611 static const WCHAR strW
[] = {'a','b','c','d',0};
1612 IDWriteTextLayout1
*layout1
;
1613 IDWriteTextFormat
*format
;
1614 IDWriteTextLayout
*layout
;
1615 DWRITE_TEXT_RANGE range
;
1616 IDWriteFactory
*factory
;
1620 factory
= create_factory();
1622 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
1623 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
1624 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1626 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 4, format
, 1000.0, 1000.0, &layout
);
1627 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1628 IDWriteTextFormat_Release(format
);
1630 hr
= IDWriteTextLayout_QueryInterface(layout
, &IID_IDWriteTextLayout1
, (void**)&layout1
);
1631 IDWriteTextLayout_Release(layout
);
1634 win_skip("SetPairKerning() is not supported.\n");
1635 IDWriteFactory_Release(factory
);
1639 if (0) { /* crashes on native */
1640 hr
= IDWriteTextLayout1_GetPairKerning(layout1
, 0, NULL
, NULL
);
1641 hr
= IDWriteTextLayout1_GetPairKerning(layout1
, 0, NULL
, &range
);
1644 hr
= IDWriteTextLayout1_GetPairKerning(layout1
, 0, &kerning
, NULL
);
1645 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1647 range
.startPosition
= 0;
1650 hr
= IDWriteTextLayout1_GetPairKerning(layout1
, 0, &kerning
, &range
);
1651 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1652 ok(!kerning
, "got %d\n", kerning
);
1654 range
.startPosition
= 0;
1656 hr
= IDWriteTextLayout1_SetPairKerning(layout1
, 2, range
);
1657 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1660 hr
= IDWriteTextLayout1_GetPairKerning(layout1
, 0, &kerning
, &range
);
1661 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1662 ok(kerning
== TRUE
, "got %d\n", kerning
);
1664 IDWriteTextLayout1_Release(layout1
);
1665 IDWriteFactory_Release(factory
);
1668 static void test_SetVerticalGlyphOrientation(void)
1670 static const WCHAR strW
[] = {'a','b','c','d',0};
1671 DWRITE_VERTICAL_GLYPH_ORIENTATION orientation
;
1672 IDWriteTextLayout2
*layout2
;
1673 IDWriteTextFormat
*format
;
1674 IDWriteTextLayout
*layout
;
1675 IDWriteFactory
*factory
;
1678 factory
= create_factory();
1680 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
1681 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
1682 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1684 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 4, format
, 1000.0, 1000.0, &layout
);
1685 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1686 IDWriteTextFormat_Release(format
);
1688 hr
= IDWriteTextLayout_QueryInterface(layout
, &IID_IDWriteTextLayout2
, (void**)&layout2
);
1689 IDWriteTextLayout_Release(layout
);
1692 win_skip("SetVerticalGlyphOrientation() is not supported.\n");
1693 IDWriteFactory_Release(factory
);
1697 orientation
= IDWriteTextLayout2_GetVerticalGlyphOrientation(layout2
);
1698 ok(orientation
== DWRITE_VERTICAL_GLYPH_ORIENTATION_DEFAULT
, "got %d\n", orientation
);
1700 hr
= IDWriteTextLayout2_SetVerticalGlyphOrientation(layout2
, DWRITE_VERTICAL_GLYPH_ORIENTATION_STACKED
+1);
1701 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1703 IDWriteTextLayout2_Release(layout2
);
1704 IDWriteFactory_Release(factory
);
1707 static void test_fallback(void)
1709 static const WCHAR strW
[] = {'a','b','c','d',0};
1710 IDWriteFontFallback
*fallback
, *fallback2
;
1711 IDWriteTextLayout2
*layout2
;
1712 IDWriteTextFormat1
*format1
;
1713 IDWriteTextFormat
*format
;
1714 IDWriteTextLayout
*layout
;
1715 IDWriteFactory2
*factory2
;
1716 IDWriteFactory
*factory
;
1719 factory
= create_factory();
1721 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
1722 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
1723 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1725 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 4, format
, 1000.0, 1000.0, &layout
);
1726 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1727 IDWriteTextFormat_Release(format
);
1729 hr
= IDWriteTextLayout_QueryInterface(layout
, &IID_IDWriteTextLayout2
, (void**)&layout2
);
1730 IDWriteTextLayout_Release(layout
);
1733 win_skip("GetFontFallback() is not supported.\n");
1734 IDWriteFactory_Release(factory
);
1738 if (0) /* crashes on native */
1739 hr
= IDWriteTextLayout2_GetFontFallback(layout2
, NULL
);
1741 fallback
= (void*)0xdeadbeef;
1742 hr
= IDWriteTextLayout2_GetFontFallback(layout2
, &fallback
);
1743 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1744 ok(fallback
== NULL
, "got %p\n", fallback
);
1746 hr
= IDWriteTextLayout2_QueryInterface(layout2
, &IID_IDWriteTextFormat1
, (void**)&format1
);
1747 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1749 fallback
= (void*)0xdeadbeef;
1750 hr
= IDWriteTextFormat1_GetFontFallback(format1
, &fallback
);
1751 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1752 ok(fallback
== NULL
, "got %p\n", fallback
);
1754 hr
= IDWriteFactory_QueryInterface(factory
, &IID_IDWriteFactory2
, (void**)&factory2
);
1755 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1758 hr
= IDWriteFactory2_GetSystemFontFallback(factory2
, &fallback
);
1760 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1762 ok(fallback
!= NULL
, "got %p\n", fallback
);
1764 hr
= IDWriteTextFormat1_SetFontFallback(format1
, fallback
);
1765 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1767 fallback2
= (void*)0xdeadbeef;
1768 hr
= IDWriteTextLayout2_GetFontFallback(layout2
, &fallback2
);
1769 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1770 ok(fallback2
== fallback
, "got %p\n", fallback2
);
1772 hr
= IDWriteTextLayout2_SetFontFallback(layout2
, NULL
);
1773 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1775 fallback2
= (void*)0xdeadbeef;
1776 hr
= IDWriteTextFormat1_GetFontFallback(format1
, &fallback2
);
1777 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1778 ok(fallback2
== NULL
, "got %p\n", fallback2
);
1780 IDWriteFontFallback_Release(fallback
);
1782 IDWriteTextFormat1_Release(format1
);
1783 IDWriteTextLayout2_Release(layout2
);
1784 IDWriteFactory_Release(factory
);
1787 static void test_DetermineMinWidth(void)
1789 static const WCHAR strW
[] = {'a','b','c','d',0};
1790 IDWriteTextFormat
*format
;
1791 IDWriteTextLayout
*layout
;
1792 IDWriteFactory
*factory
;
1796 factory
= create_factory();
1798 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
1799 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
1800 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1802 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, lstrlenW(strW
), format
, 1000.0, 1000.0, &layout
);
1803 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1805 hr
= IDWriteTextLayout_DetermineMinWidth(layout
, NULL
);
1806 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1809 hr
= IDWriteTextLayout_DetermineMinWidth(layout
, &minwidth
);
1810 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1811 ok(minwidth
> 0.0, "got %.2f\n", minwidth
);
1813 IDWriteTextLayout_Release(layout
);
1814 IDWriteTextFormat_Release(format
);
1817 static void test_SetFontSize(void)
1819 static const WCHAR strW
[] = {'a','b','c','d',0};
1820 IDWriteTextFormat
*format
;
1821 IDWriteTextLayout
*layout
;
1822 IDWriteFactory
*factory
;
1823 DWRITE_TEXT_RANGE r
;
1827 factory
= create_factory();
1829 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
1830 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
1831 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1833 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 4, format
, 1000.0, 1000.0, &layout
);
1834 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1836 r
.startPosition
= 1;
1839 hr
= IDWriteTextLayout_GetFontSize(layout
, 0, &size
, &r
);
1840 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1842 ok(r
.startPosition
== 0 && r
.length
== ~0u, "got %u, %u\n", r
.startPosition
, r
.length
);
1843 ok(size
== 10.0, "got %.2f\n", size
);
1845 r
.startPosition
= 1;
1847 hr
= IDWriteTextLayout_SetFontSize(layout
, 15.0, r
);
1848 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1851 hr
= IDWriteTextLayout_GetFontSize(layout
, 1, &size
, &r
);
1852 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1853 ok(size
== 15.0, "got %.2f\n", size
);
1855 r
.startPosition
= 0;
1857 hr
= IDWriteTextLayout_SetFontSize(layout
, 15.0, r
);
1858 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1861 hr
= IDWriteTextLayout_GetFontSize(layout
, 1, &size
, &r
);
1862 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1863 ok(size
== 15.0, "got %.2f\n", size
);
1866 hr
= IDWriteTextLayout_GetFontSize(layout
, 0, &size
, &r
);
1867 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1868 ok(r
.startPosition
== 0 && r
.length
== 4, "got %u, %u\n", r
.startPosition
, r
.length
);
1869 ok(size
== 15.0, "got %.2f\n", size
);
1872 r
.startPosition
= r
.length
= 0;
1873 hr
= IDWriteTextLayout_GetFontSize(layout
, 20, &size
, &r
);
1874 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1876 ok(r
.startPosition
== 4 && r
.length
== ~0u-4, "got %u, %u\n", r
.startPosition
, r
.length
);
1877 ok(size
== 10.0, "got %.2f\n", size
);
1879 r
.startPosition
= 100;
1881 hr
= IDWriteTextLayout_SetFontSize(layout
, 25.0, r
);
1882 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1885 r
.startPosition
= r
.length
= 0;
1886 hr
= IDWriteTextLayout_GetFontSize(layout
, 100, &size
, &r
);
1887 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1889 ok(r
.startPosition
== 100 && r
.length
== 4, "got %u, %u\n", r
.startPosition
, r
.length
);
1890 ok(size
== 25.0, "got %.2f\n", size
);
1892 IDWriteTextLayout_Release(layout
);
1893 IDWriteTextFormat_Release(format
);
1896 static void test_SetFontFamilyName(void)
1898 static const WCHAR arialW
[] = {'A','r','i','a','l',0};
1899 static const WCHAR strW
[] = {'a','b','c','d',0};
1900 IDWriteTextFormat
*format
;
1901 IDWriteTextLayout
*layout
;
1902 IDWriteFactory
*factory
;
1903 DWRITE_TEXT_RANGE r
;
1907 factory
= create_factory();
1909 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
1910 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
1911 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1913 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 4, format
, 1000.0, 1000.0, &layout
);
1914 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1916 r
.startPosition
= 1;
1919 hr
= IDWriteTextLayout_GetFontFamilyName(layout
, 1, nameW
, sizeof(nameW
)/sizeof(WCHAR
), &r
);
1920 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1922 ok(r
.startPosition
== 0 && r
.length
== ~0u, "got %u, %u\n", r
.startPosition
, r
.length
);
1924 r
.startPosition
= 1;
1926 hr
= IDWriteTextLayout_SetFontFamilyName(layout
, arialW
, r
);
1927 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1929 r
.startPosition
= 1;
1931 hr
= IDWriteTextLayout_GetFontFamilyName(layout
, 1, nameW
, sizeof(nameW
)/sizeof(WCHAR
), &r
);
1932 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1933 ok(r
.startPosition
== 1 && r
.length
== 1, "got %u, %u\n", r
.startPosition
, r
.length
);
1935 r
.startPosition
= 0;
1937 hr
= IDWriteTextLayout_SetFontFamilyName(layout
, arialW
, r
);
1938 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1941 hr
= IDWriteTextLayout_GetFontFamilyName(layout
, 1, nameW
, sizeof(nameW
)/sizeof(WCHAR
), &r
);
1942 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1943 ok(r
.startPosition
== 0 && r
.length
== 4, "got %u, %u\n", r
.startPosition
, r
.length
);
1944 ok(!lstrcmpW(nameW
, arialW
), "got name %s\n", wine_dbgstr_w(nameW
));
1946 IDWriteTextLayout_Release(layout
);
1947 IDWriteTextFormat_Release(format
);
1950 static void test_SetFontStyle(void)
1952 static const WCHAR strW
[] = {'a','b','c','d',0};
1953 IDWriteTextFormat
*format
;
1954 IDWriteTextLayout
*layout
;
1955 IDWriteFactory
*factory
;
1956 DWRITE_FONT_STYLE style
;
1957 DWRITE_TEXT_RANGE r
;
1960 factory
= create_factory();
1962 hr
= IDWriteFactory_CreateTextFormat(factory
, tahomaW
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
1963 DWRITE_FONT_STRETCH_NORMAL
, 10.0, enusW
, &format
);
1964 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1966 hr
= IDWriteFactory_CreateTextLayout(factory
, strW
, 4, format
, 1000.0, 1000.0, &layout
);
1967 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1969 r
.startPosition
= 1;
1971 hr
= IDWriteTextLayout_GetFontStyle(layout
, 0, &style
, &r
);
1972 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1974 ok(r
.startPosition
== 0 && r
.length
== ~0u, "got %u, %u\n", r
.startPosition
, r
.length
);
1975 ok(style
== DWRITE_FONT_STYLE_NORMAL
, "got %d\n", style
);
1977 r
.startPosition
= 1;
1979 hr
= IDWriteTextLayout_SetFontStyle(layout
, DWRITE_FONT_STYLE_ITALIC
, r
);
1980 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1982 style
= DWRITE_FONT_STYLE_NORMAL
;
1983 hr
= IDWriteTextLayout_GetFontStyle(layout
, 1, &style
, &r
);
1984 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1985 ok(style
== DWRITE_FONT_STYLE_ITALIC
, "got %d\n", style
);
1987 r
.startPosition
= 0;
1989 hr
= IDWriteTextLayout_SetFontStyle(layout
, DWRITE_FONT_STYLE_OBLIQUE
, r
);
1990 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1992 style
= DWRITE_FONT_STYLE_ITALIC
;
1993 hr
= IDWriteTextLayout_GetFontStyle(layout
, 1, &style
, &r
);
1994 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1995 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %d\n", style
);
1997 style
= DWRITE_FONT_STYLE_ITALIC
;
1998 hr
= IDWriteTextLayout_GetFontStyle(layout
, 0, &style
, &r
);
1999 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2000 ok(r
.startPosition
== 0 && r
.length
== 4, "got %u, %u\n", r
.startPosition
, r
.length
);
2001 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %d\n", style
);
2003 style
= DWRITE_FONT_STYLE_ITALIC
;
2004 r
.startPosition
= r
.length
= 0;
2005 hr
= IDWriteTextLayout_GetFontStyle(layout
, 20, &style
, &r
);
2006 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2008 ok(r
.startPosition
== 4 && r
.length
== ~0u-4, "got %u, %u\n", r
.startPosition
, r
.length
);
2009 ok(style
== DWRITE_FONT_STYLE_NORMAL
, "got %d\n", style
);
2011 r
.startPosition
= 100;
2013 hr
= IDWriteTextLayout_SetFontStyle(layout
, DWRITE_FONT_STYLE_OBLIQUE
, r
);
2014 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2016 style
= DWRITE_FONT_STYLE_NORMAL
;
2017 r
.startPosition
= r
.length
= 0;
2018 hr
= IDWriteTextLayout_GetFontStyle(layout
, 100, &style
, &r
);
2019 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2021 ok(r
.startPosition
== 100 && r
.length
== 4, "got %u, %u\n", r
.startPosition
, r
.length
);
2022 ok(style
== DWRITE_FONT_STYLE_OBLIQUE
, "got %d\n", style
);
2024 IDWriteTextLayout_Release(layout
);
2025 IDWriteTextFormat_Release(format
);
2030 static const WCHAR ctrlstrW
[] = {0x202a,0};
2031 IDWriteFactory
*factory
;
2033 if (!(factory
= create_factory())) {
2034 win_skip("failed to create factory\n");
2038 /* actual script ids are not fixed */
2039 get_script_analysis(ctrlstrW
, 1, &g_control_sa
);
2041 init_call_sequences(sequences
, NUM_CALL_SEQUENCES
);
2042 init_call_sequences(expected_seq
, 1);
2044 test_CreateTextLayout();
2045 test_CreateGdiCompatibleTextLayout();
2046 test_CreateTextFormat();
2047 test_GetLocaleName();
2048 test_CreateEllipsisTrimmingSign();
2050 test_SetInlineObject();
2053 test_GetClusterMetrics();
2054 test_SetLocaleName();
2055 test_SetPairKerning();
2056 test_SetVerticalGlyphOrientation();
2058 test_DetermineMinWidth();
2060 test_SetFontFamilyName();
2061 test_SetFontStyle();
2063 IDWriteFactory_Release(factory
);