2 * Text format and layout
4 * Copyright 2012, 2014 Nikolay Sivov for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "dwrite_private.h"
30 #include "wine/list.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(dwrite
);
34 struct dwrite_textformat_data
{
40 DWRITE_FONT_WEIGHT weight
;
41 DWRITE_FONT_STYLE style
;
42 DWRITE_FONT_STRETCH stretch
;
44 DWRITE_PARAGRAPH_ALIGNMENT paralign
;
45 DWRITE_READING_DIRECTION readingdir
;
46 DWRITE_WORD_WRAPPING wrapping
;
47 DWRITE_TEXT_ALIGNMENT textalignment
;
48 DWRITE_FLOW_DIRECTION flow
;
49 DWRITE_LINE_SPACING_METHOD spacingmethod
;
55 DWRITE_TRIMMING trimming
;
56 IDWriteInlineObject
*trimmingsign
;
58 IDWriteFontCollection
*collection
;
61 enum layout_range_attr_kind
{
62 LAYOUT_RANGE_ATTR_WEIGHT
,
63 LAYOUT_RANGE_ATTR_STYLE
,
64 LAYOUT_RANGE_ATTR_EFFECT
,
65 LAYOUT_RANGE_ATTR_INLINE
,
66 LAYOUT_RANGE_ATTR_UNDERLINE
,
67 LAYOUT_RANGE_ATTR_STRIKETHROUGH
70 struct layout_range_attr_value
{
71 DWRITE_TEXT_RANGE range
;
73 DWRITE_FONT_WEIGHT weight
;
74 DWRITE_FONT_STYLE style
;
75 IDWriteInlineObject
*object
;
84 DWRITE_TEXT_RANGE range
;
85 DWRITE_FONT_WEIGHT weight
;
86 DWRITE_FONT_STYLE style
;
87 IDWriteInlineObject
*object
;
93 struct dwrite_textlayout
{
94 IDWriteTextLayout IDWriteTextLayout_iface
;
99 struct dwrite_textformat_data format
;
105 struct dwrite_textformat
{
106 IDWriteTextFormat IDWriteTextFormat_iface
;
108 struct dwrite_textformat_data format
;
111 struct dwrite_trimmingsign
{
112 IDWriteInlineObject IDWriteInlineObject_iface
;
116 static const IDWriteTextFormatVtbl dwritetextformatvtbl
;
118 static void release_format_data(struct dwrite_textformat_data
*data
)
120 if (data
->collection
) IDWriteFontCollection_Release(data
->collection
);
121 if (data
->trimmingsign
) IDWriteInlineObject_Release(data
->trimmingsign
);
122 heap_free(data
->family_name
);
123 heap_free(data
->locale
);
126 static inline struct dwrite_textlayout
*impl_from_IDWriteTextLayout(IDWriteTextLayout
*iface
)
128 return CONTAINING_RECORD(iface
, struct dwrite_textlayout
, IDWriteTextLayout_iface
);
131 static inline struct dwrite_textformat
*impl_from_IDWriteTextFormat(IDWriteTextFormat
*iface
)
133 return CONTAINING_RECORD(iface
, struct dwrite_textformat
, IDWriteTextFormat_iface
);
136 static inline struct dwrite_textformat
*unsafe_impl_from_IDWriteTextFormat(IDWriteTextFormat
*iface
)
138 return iface
->lpVtbl
== &dwritetextformatvtbl
? impl_from_IDWriteTextFormat(iface
) : NULL
;
141 static inline struct dwrite_trimmingsign
*impl_from_IDWriteInlineObject(IDWriteInlineObject
*iface
)
143 return CONTAINING_RECORD(iface
, struct dwrite_trimmingsign
, IDWriteInlineObject_iface
);
146 /* To be used in IDWriteTextLayout methods to validate and fix passed range */
147 static inline BOOL
validate_text_range(struct dwrite_textlayout
*layout
, DWRITE_TEXT_RANGE
*r
)
149 if (r
->startPosition
>= layout
->len
)
152 if (r
->startPosition
+ r
->length
> layout
->len
)
153 r
->length
= layout
->len
- r
->startPosition
;
158 static BOOL
is_same_layout_attrvalue(struct layout_range
const *range
, enum layout_range_attr_kind attr
, struct layout_range_attr_value
*value
)
161 case LAYOUT_RANGE_ATTR_WEIGHT
:
162 return range
->weight
== value
->u
.weight
;
163 case LAYOUT_RANGE_ATTR_STYLE
:
164 return range
->style
== value
->u
.style
;
165 case LAYOUT_RANGE_ATTR_INLINE
:
166 return range
->object
== value
->u
.object
;
167 case LAYOUT_RANGE_ATTR_EFFECT
:
168 return range
->effect
== value
->u
.effect
;
169 case LAYOUT_RANGE_ATTR_UNDERLINE
:
170 return range
->underline
== value
->u
.underline
;
171 case LAYOUT_RANGE_ATTR_STRIKETHROUGH
:
172 return range
->strikethrough
== value
->u
.strikethrough
;
180 static inline BOOL
is_same_layout_attributes(struct layout_range
const *left
, struct layout_range
const *right
)
182 return left
->weight
== right
->weight
&&
183 left
->style
== right
->style
&&
184 left
->object
== right
->object
&&
185 left
->effect
== right
->effect
&&
186 left
->underline
== right
->underline
&&
187 left
->strikethrough
== right
->strikethrough
;
190 static inline BOOL
is_same_text_range(const DWRITE_TEXT_RANGE
*left
, const DWRITE_TEXT_RANGE
*right
)
192 return left
->startPosition
== right
->startPosition
&& left
->length
== right
->length
;
195 /* Allocates range and inits it with default values from text format. */
196 static struct layout_range
*alloc_layout_range(struct dwrite_textlayout
*layout
, const DWRITE_TEXT_RANGE
*r
)
198 struct layout_range
*range
;
200 range
= heap_alloc(sizeof(*range
));
201 if (!range
) return NULL
;
204 range
->weight
= layout
->format
.weight
;
205 range
->style
= layout
->format
.style
;
206 range
->object
= NULL
;
207 range
->effect
= NULL
;
208 range
->underline
= FALSE
;
209 range
->strikethrough
= FALSE
;
214 static struct layout_range
*alloc_layout_range_from(struct layout_range
*from
, const DWRITE_TEXT_RANGE
*r
)
216 struct layout_range
*range
;
218 range
= heap_alloc(sizeof(*range
));
219 if (!range
) return NULL
;
224 /* update refcounts */
226 IDWriteInlineObject_AddRef(range
->object
);
228 IUnknown_AddRef(range
->effect
);
233 static void free_layout_range(struct layout_range
*range
)
236 IDWriteInlineObject_Release(range
->object
);
238 IUnknown_Release(range
->effect
);
242 static void free_layout_ranges_list(struct list
*ranges
)
244 struct layout_range
*cur
, *cur2
;
245 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, ranges
, struct layout_range
, entry
) {
246 list_remove(&cur
->entry
);
247 free_layout_range(cur
);
251 static struct layout_range
*find_outer_range(struct list
*ranges
, const DWRITE_TEXT_RANGE
*range
)
253 struct layout_range
*cur
;
255 LIST_FOR_EACH_ENTRY(cur
, ranges
, struct layout_range
, entry
) {
257 if (cur
->range
.startPosition
> range
->startPosition
)
260 if ((cur
->range
.startPosition
+ cur
->range
.length
< range
->startPosition
+ range
->length
) &&
261 (range
->startPosition
< cur
->range
.startPosition
+ cur
->range
.length
))
263 if (cur
->range
.startPosition
+ cur
->range
.length
>= range
->startPosition
+ range
->length
)
270 static struct layout_range
*get_layout_range_by_pos(struct list
*ranges
, UINT32 pos
)
272 struct layout_range
*cur
;
274 LIST_FOR_EACH_ENTRY(cur
, ranges
, struct layout_range
, entry
) {
275 DWRITE_TEXT_RANGE
*r
= &cur
->range
;
276 if (r
->startPosition
<= pos
&& pos
< r
->startPosition
+ r
->length
)
283 static BOOL
set_layout_range_attrval(struct layout_range
*dest
, enum layout_range_attr_kind attr
, struct layout_range_attr_value
*value
)
285 BOOL changed
= FALSE
;
288 case LAYOUT_RANGE_ATTR_WEIGHT
:
289 changed
= dest
->weight
!= value
->u
.weight
;
290 dest
->weight
= value
->u
.weight
;
292 case LAYOUT_RANGE_ATTR_STYLE
:
293 changed
= dest
->style
!= value
->u
.style
;
294 dest
->style
= value
->u
.style
;
296 case LAYOUT_RANGE_ATTR_INLINE
:
297 changed
= dest
->object
!= value
->u
.object
;
298 if (changed
&& dest
->object
)
299 IDWriteInlineObject_Release(dest
->object
);
300 dest
->object
= value
->u
.object
;
302 IDWriteInlineObject_AddRef(dest
->object
);
304 case LAYOUT_RANGE_ATTR_EFFECT
:
305 changed
= dest
->effect
!= value
->u
.effect
;
306 if (changed
&& dest
->effect
)
307 IUnknown_Release(dest
->effect
);
308 dest
->effect
= value
->u
.effect
;
310 IUnknown_AddRef(dest
->effect
);
312 case LAYOUT_RANGE_ATTR_UNDERLINE
:
313 changed
= dest
->underline
!= value
->u
.underline
;
314 dest
->underline
= value
->u
.underline
;
316 case LAYOUT_RANGE_ATTR_STRIKETHROUGH
:
317 changed
= dest
->strikethrough
!= value
->u
.strikethrough
;
318 dest
->strikethrough
= value
->u
.strikethrough
;
327 static inline BOOL
is_in_layout_range(const DWRITE_TEXT_RANGE
*outer
, const DWRITE_TEXT_RANGE
*inner
)
329 return (inner
->startPosition
>= outer
->startPosition
) &&
330 (inner
->startPosition
+ inner
->length
<= outer
->startPosition
+ outer
->length
);
333 /* Set attribute value for given range, does all needed splitting/merging of existing ranges. */
334 static HRESULT
set_layout_range_attr(struct dwrite_textlayout
*layout
, enum layout_range_attr_kind attr
, struct layout_range_attr_value
*value
)
336 struct layout_range
*outer
, *right
, *left
, *cur
;
337 struct list
*ranges
= &layout
->ranges
;
338 BOOL changed
= FALSE
;
341 /* If new range is completely within existing range, split existing range in two */
342 if ((outer
= find_outer_range(ranges
, &value
->range
))) {
344 /* no need to add same range */
345 if (is_same_layout_attrvalue(outer
, attr
, value
))
348 /* for matching range bounds just replace data */
349 if (is_same_text_range(&outer
->range
, &value
->range
)) {
350 changed
= set_layout_range_attrval(outer
, attr
, value
);
354 /* add new range to the left */
355 if (value
->range
.startPosition
== outer
->range
.startPosition
) {
356 left
= alloc_layout_range_from(outer
, &value
->range
);
357 if (!left
) return E_OUTOFMEMORY
;
359 changed
= set_layout_range_attrval(left
, attr
, value
);
360 list_add_before(&outer
->entry
, &left
->entry
);
361 outer
->range
.startPosition
+= value
->range
.length
;
362 outer
->range
.length
-= value
->range
.length
;
366 /* add new range to the right */
367 if (value
->range
.startPosition
+ value
->range
.length
== outer
->range
.startPosition
+ outer
->range
.length
) {
368 right
= alloc_layout_range_from(outer
, &value
->range
);
369 if (!right
) return E_OUTOFMEMORY
;
371 changed
= set_layout_range_attrval(right
, attr
, value
);
372 list_add_after(&outer
->entry
, &right
->entry
);
373 outer
->range
.length
-= value
->range
.length
;
377 r
.startPosition
= value
->range
.startPosition
+ value
->range
.length
;
378 r
.length
= outer
->range
.length
+ outer
->range
.startPosition
- r
.startPosition
;
381 right
= alloc_layout_range_from(outer
, &r
);
382 /* new range in the middle */
383 cur
= alloc_layout_range_from(outer
, &value
->range
);
384 if (!right
|| !cur
) {
385 free_layout_range(right
);
386 free_layout_range(cur
);
387 return E_OUTOFMEMORY
;
390 /* reuse container range as a left part */
391 outer
->range
.length
= value
->range
.startPosition
- outer
->range
.startPosition
;
394 set_layout_range_attrval(cur
, attr
, value
);
396 list_add_after(&outer
->entry
, &cur
->entry
);
397 list_add_after(&cur
->entry
, &right
->entry
);
402 /* Now it's only possible that given range contains some existing ranges, fully or partially.
403 Update all of them. */
404 left
= get_layout_range_by_pos(ranges
, value
->range
.startPosition
);
405 if (left
->range
.startPosition
== value
->range
.startPosition
)
406 changed
= set_layout_range_attrval(left
, attr
, value
);
407 else /* need to split */ {
408 r
.startPosition
= value
->range
.startPosition
;
409 r
.length
= left
->range
.length
- value
->range
.startPosition
+ left
->range
.startPosition
;
410 left
->range
.length
-= r
.length
;
411 cur
= alloc_layout_range_from(left
, &r
);
412 changed
= set_layout_range_attrval(cur
, attr
, value
);
413 list_add_after(&left
->entry
, &cur
->entry
);
415 cur
= LIST_ENTRY(list_next(ranges
, &left
->entry
), struct layout_range
, entry
);
417 /* for all existing ranges covered by new one update value */
418 while (is_in_layout_range(&value
->range
, &cur
->range
)) {
419 changed
= set_layout_range_attrval(cur
, attr
, value
);
420 cur
= LIST_ENTRY(list_next(ranges
, &cur
->entry
), struct layout_range
, entry
);
423 /* it's possible rightmost range intersects */
424 if (cur
&& (cur
->range
.startPosition
< value
->range
.startPosition
+ value
->range
.length
)) {
425 r
.startPosition
= cur
->range
.startPosition
;
426 r
.length
= value
->range
.startPosition
+ value
->range
.length
- cur
->range
.startPosition
;
427 left
= alloc_layout_range_from(cur
, &r
);
428 changed
= set_layout_range_attrval(left
, attr
, value
);
429 cur
->range
.startPosition
+= left
->range
.length
;
430 cur
->range
.length
-= left
->range
.length
;
431 list_add_before(&cur
->entry
, &left
->entry
);
436 struct list
*next
, *i
;
438 i
= list_head(ranges
);
439 while ((next
= list_next(ranges
, i
))) {
440 struct layout_range
*next_range
= LIST_ENTRY(next
, struct layout_range
, entry
);
442 cur
= LIST_ENTRY(i
, struct layout_range
, entry
);
443 if (is_same_layout_attributes(cur
, next_range
)) {
444 /* remove similar range */
445 cur
->range
.length
+= next_range
->range
.length
;
447 free_layout_range(next_range
);
450 i
= list_next(ranges
, i
);
457 static HRESULT WINAPI
dwritetextlayout_QueryInterface(IDWriteTextLayout
*iface
, REFIID riid
, void **obj
)
459 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
461 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
463 if (IsEqualIID(riid
, &IID_IUnknown
) ||
464 IsEqualIID(riid
, &IID_IDWriteTextFormat
) ||
465 IsEqualIID(riid
, &IID_IDWriteTextLayout
))
468 IDWriteTextLayout_AddRef(iface
);
474 return E_NOINTERFACE
;
477 static ULONG WINAPI
dwritetextlayout_AddRef(IDWriteTextLayout
*iface
)
479 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
480 ULONG ref
= InterlockedIncrement(&This
->ref
);
481 TRACE("(%p)->(%d)\n", This
, ref
);
485 static ULONG WINAPI
dwritetextlayout_Release(IDWriteTextLayout
*iface
)
487 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
488 ULONG ref
= InterlockedDecrement(&This
->ref
);
490 TRACE("(%p)->(%d)\n", This
, ref
);
493 free_layout_ranges_list(&This
->ranges
);
494 release_format_data(&This
->format
);
495 heap_free(This
->str
);
502 static HRESULT WINAPI
dwritetextlayout_SetTextAlignment(IDWriteTextLayout
*iface
, DWRITE_TEXT_ALIGNMENT alignment
)
504 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
505 FIXME("(%p)->(%d): stub\n", This
, alignment
);
509 static HRESULT WINAPI
dwritetextlayout_SetParagraphAlignment(IDWriteTextLayout
*iface
, DWRITE_PARAGRAPH_ALIGNMENT alignment
)
511 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
512 FIXME("(%p)->(%d): stub\n", This
, alignment
);
516 static HRESULT WINAPI
dwritetextlayout_SetWordWrapping(IDWriteTextLayout
*iface
, DWRITE_WORD_WRAPPING wrapping
)
518 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
519 FIXME("(%p)->(%d): stub\n", This
, wrapping
);
523 static HRESULT WINAPI
dwritetextlayout_SetReadingDirection(IDWriteTextLayout
*iface
, DWRITE_READING_DIRECTION direction
)
525 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
526 FIXME("(%p)->(%d): stub\n", This
, direction
);
530 static HRESULT WINAPI
dwritetextlayout_SetFlowDirection(IDWriteTextLayout
*iface
, DWRITE_FLOW_DIRECTION direction
)
532 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
533 FIXME("(%p)->(%d): stub\n", This
, direction
);
537 static HRESULT WINAPI
dwritetextlayout_SetIncrementalTabStop(IDWriteTextLayout
*iface
, FLOAT tabstop
)
539 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
540 FIXME("(%p)->(%f): stub\n", This
, tabstop
);
544 static HRESULT WINAPI
dwritetextlayout_SetTrimming(IDWriteTextLayout
*iface
, DWRITE_TRIMMING
const *trimming
,
545 IDWriteInlineObject
*trimming_sign
)
547 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
548 FIXME("(%p)->(%p %p): stub\n", This
, trimming
, trimming_sign
);
552 static HRESULT WINAPI
dwritetextlayout_SetLineSpacing(IDWriteTextLayout
*iface
, DWRITE_LINE_SPACING_METHOD spacing
,
553 FLOAT line_spacing
, FLOAT baseline
)
555 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
556 FIXME("(%p)->(%d %f %f): stub\n", This
, spacing
, line_spacing
, baseline
);
560 static DWRITE_TEXT_ALIGNMENT WINAPI
dwritetextlayout_GetTextAlignment(IDWriteTextLayout
*iface
)
562 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
563 FIXME("(%p): stub\n", This
);
564 return DWRITE_TEXT_ALIGNMENT_LEADING
;
567 static DWRITE_PARAGRAPH_ALIGNMENT WINAPI
dwritetextlayout_GetParagraphAlignment(IDWriteTextLayout
*iface
)
569 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
570 FIXME("(%p): stub\n", This
);
571 return DWRITE_PARAGRAPH_ALIGNMENT_NEAR
;
574 static DWRITE_WORD_WRAPPING WINAPI
dwritetextlayout_GetWordWrapping(IDWriteTextLayout
*iface
)
576 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
577 FIXME("(%p): stub\n", This
);
578 return DWRITE_WORD_WRAPPING_NO_WRAP
;
581 static DWRITE_READING_DIRECTION WINAPI
dwritetextlayout_GetReadingDirection(IDWriteTextLayout
*iface
)
583 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
584 FIXME("(%p): stub\n", This
);
585 return DWRITE_READING_DIRECTION_LEFT_TO_RIGHT
;
588 static DWRITE_FLOW_DIRECTION WINAPI
dwritetextlayout_GetFlowDirection(IDWriteTextLayout
*iface
)
590 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
591 FIXME("(%p): stub\n", This
);
592 return DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM
;
595 static FLOAT WINAPI
dwritetextlayout_GetIncrementalTabStop(IDWriteTextLayout
*iface
)
597 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
598 FIXME("(%p): stub\n", This
);
602 static HRESULT WINAPI
dwritetextlayout_GetTrimming(IDWriteTextLayout
*iface
, DWRITE_TRIMMING
*options
,
603 IDWriteInlineObject
**trimming_sign
)
605 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
606 FIXME("(%p)->(%p %p): stub\n", This
, options
, trimming_sign
);
610 static HRESULT WINAPI
dwritetextlayout_GetLineSpacing(IDWriteTextLayout
*iface
, DWRITE_LINE_SPACING_METHOD
*method
,
611 FLOAT
*spacing
, FLOAT
*baseline
)
613 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
614 FIXME("(%p)->(%p %p %p): stub\n", This
, method
, spacing
, baseline
);
618 static HRESULT WINAPI
dwritetextlayout_GetFontCollection(IDWriteTextLayout
*iface
, IDWriteFontCollection
**collection
)
620 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
621 FIXME("(%p)->(%p): stub\n", This
, collection
);
625 static UINT32 WINAPI
dwritetextlayout_GetFontFamilyNameLength(IDWriteTextLayout
*iface
)
627 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
628 FIXME("(%p): stub\n", This
);
632 static HRESULT WINAPI
dwritetextlayout_GetFontFamilyName(IDWriteTextLayout
*iface
, WCHAR
*name
, UINT32 size
)
634 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
635 FIXME("(%p)->(%p %u): stub\n", This
, name
, size
);
639 static DWRITE_FONT_WEIGHT WINAPI
dwritetextlayout_GetFontWeight(IDWriteTextLayout
*iface
)
641 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
642 FIXME("(%p): stub\n", This
);
643 return DWRITE_FONT_WEIGHT_NORMAL
;
646 static DWRITE_FONT_STYLE WINAPI
dwritetextlayout_GetFontStyle(IDWriteTextLayout
*iface
)
648 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
649 FIXME("(%p): stub\n", This
);
650 return DWRITE_FONT_STYLE_NORMAL
;
653 static DWRITE_FONT_STRETCH WINAPI
dwritetextlayout_GetFontStretch(IDWriteTextLayout
*iface
)
655 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
656 FIXME("(%p): stub\n", This
);
657 return DWRITE_FONT_STRETCH_NORMAL
;
660 static FLOAT WINAPI
dwritetextlayout_GetFontSize(IDWriteTextLayout
*iface
)
662 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
663 FIXME("(%p): stub\n", This
);
667 static UINT32 WINAPI
dwritetextlayout_GetLocaleNameLength(IDWriteTextLayout
*iface
)
669 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
670 TRACE("(%p)\n", This
);
671 return This
->format
.locale_len
;
674 static HRESULT WINAPI
dwritetextlayout_GetLocaleName(IDWriteTextLayout
*iface
, WCHAR
*name
, UINT32 size
)
676 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
678 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
680 if (size
<= This
->format
.locale_len
) return E_NOT_SUFFICIENT_BUFFER
;
681 strcpyW(name
, This
->format
.locale
);
685 static HRESULT WINAPI
dwritetextlayout_SetMaxWidth(IDWriteTextLayout
*iface
, FLOAT maxWidth
)
687 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
688 TRACE("(%p)->(%.1f)\n", This
, maxWidth
);
689 This
->maxwidth
= maxWidth
;
693 static HRESULT WINAPI
dwritetextlayout_SetMaxHeight(IDWriteTextLayout
*iface
, FLOAT maxHeight
)
695 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
696 TRACE("(%p)->(%.1f)\n", This
, maxHeight
);
697 This
->maxheight
= maxHeight
;
701 static HRESULT WINAPI
dwritetextlayout_SetFontCollection(IDWriteTextLayout
*iface
, IDWriteFontCollection
* collection
, DWRITE_TEXT_RANGE range
)
703 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
704 FIXME("(%p)->(%p %s): stub\n", This
, collection
, debugstr_range(&range
));
708 static HRESULT WINAPI
dwritetextlayout_SetFontFamilyName(IDWriteTextLayout
*iface
, WCHAR
const *name
, DWRITE_TEXT_RANGE range
)
710 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
711 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(name
), debugstr_range(&range
));
715 static HRESULT WINAPI
dwritetextlayout_SetFontWeight(IDWriteTextLayout
*iface
, DWRITE_FONT_WEIGHT weight
, DWRITE_TEXT_RANGE range
)
717 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
718 struct layout_range_attr_value value
;
720 TRACE("(%p)->(%d %s)\n", This
, weight
, debugstr_range(&range
));
722 if (!validate_text_range(This
, &range
))
726 value
.u
.weight
= weight
;
727 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_WEIGHT
, &value
);
730 static HRESULT WINAPI
dwritetextlayout_SetFontStyle(IDWriteTextLayout
*iface
, DWRITE_FONT_STYLE style
, DWRITE_TEXT_RANGE range
)
732 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
733 struct layout_range_attr_value value
;
735 TRACE("(%p)->(%d %s)\n", This
, style
, debugstr_range(&range
));
737 if (!validate_text_range(This
, &range
))
741 value
.u
.style
= style
;
742 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_STYLE
, &value
);
745 static HRESULT WINAPI
dwritetextlayout_SetFontStretch(IDWriteTextLayout
*iface
, DWRITE_FONT_STRETCH stretch
, DWRITE_TEXT_RANGE range
)
747 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
748 FIXME("(%p)->(%d %s): stub\n", This
, stretch
, debugstr_range(&range
));
752 static HRESULT WINAPI
dwritetextlayout_SetFontSize(IDWriteTextLayout
*iface
, FLOAT size
, DWRITE_TEXT_RANGE range
)
754 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
755 FIXME("(%p)->(%f %s): stub\n", This
, size
, debugstr_range(&range
));
759 static HRESULT WINAPI
dwritetextlayout_SetUnderline(IDWriteTextLayout
*iface
, BOOL underline
, DWRITE_TEXT_RANGE range
)
761 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
762 struct layout_range_attr_value value
;
764 TRACE("(%p)->(%d %s)\n", This
, underline
, debugstr_range(&range
));
766 if (!validate_text_range(This
, &range
))
770 value
.u
.underline
= underline
;
771 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_UNDERLINE
, &value
);
774 static HRESULT WINAPI
dwritetextlayout_SetStrikethrough(IDWriteTextLayout
*iface
, BOOL strikethrough
, DWRITE_TEXT_RANGE range
)
776 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
777 struct layout_range_attr_value value
;
779 TRACE("(%p)->(%d %s)\n", This
, strikethrough
, debugstr_range(&range
));
781 if (!validate_text_range(This
, &range
))
785 value
.u
.underline
= strikethrough
;
786 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_STRIKETHROUGH
, &value
);
789 static HRESULT WINAPI
dwritetextlayout_SetDrawingEffect(IDWriteTextLayout
*iface
, IUnknown
* effect
, DWRITE_TEXT_RANGE range
)
791 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
792 struct layout_range_attr_value value
;
794 TRACE("(%p)->(%p %s)\n", This
, effect
, debugstr_range(&range
));
796 if (!validate_text_range(This
, &range
))
800 value
.u
.effect
= effect
;
801 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_EFFECT
, &value
);
804 static HRESULT WINAPI
dwritetextlayout_SetInlineObject(IDWriteTextLayout
*iface
, IDWriteInlineObject
*object
, DWRITE_TEXT_RANGE r
)
806 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
807 struct layout_range_attr_value attr
;
809 TRACE("(%p)->(%p %s)\n", This
, object
, debugstr_range(&r
));
811 if (!validate_text_range(This
, &r
))
815 attr
.u
.object
= object
;
817 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_INLINE
, &attr
);
820 static HRESULT WINAPI
dwritetextlayout_SetTypography(IDWriteTextLayout
*iface
, IDWriteTypography
* typography
, DWRITE_TEXT_RANGE range
)
822 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
823 FIXME("(%p)->(%p %s): stub\n", This
, typography
, debugstr_range(&range
));
827 static HRESULT WINAPI
dwritetextlayout_SetLocaleName(IDWriteTextLayout
*iface
, WCHAR
const* locale
, DWRITE_TEXT_RANGE range
)
829 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
830 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(locale
), debugstr_range(&range
));
834 static FLOAT WINAPI
dwritetextlayout_GetMaxWidth(IDWriteTextLayout
*iface
)
836 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
837 TRACE("(%p)\n", This
);
838 return This
->maxwidth
;
841 static FLOAT WINAPI
dwritetextlayout_GetMaxHeight(IDWriteTextLayout
*iface
)
843 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
844 TRACE("(%p)\n", This
);
845 return This
->maxheight
;
848 static HRESULT WINAPI
dwritetextlayout_layout_GetFontCollection(IDWriteTextLayout
*iface
, UINT32 pos
,
849 IDWriteFontCollection
** collection
, DWRITE_TEXT_RANGE
*range
)
851 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
852 FIXME("(%p)->(%p %p): stub\n", This
, collection
, range
);
856 static HRESULT WINAPI
dwritetextlayout_layout_GetFontFamilyNameLength(IDWriteTextLayout
*iface
,
857 UINT32 pos
, UINT32
* len
, DWRITE_TEXT_RANGE
*range
)
859 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
860 FIXME("(%p)->(%d %p %p): stub\n", This
, pos
, len
, range
);
864 static HRESULT WINAPI
dwritetextlayout_layout_GetFontFamilyName(IDWriteTextLayout
*iface
,
865 UINT32 position
, WCHAR
* name
, UINT32 name_size
, DWRITE_TEXT_RANGE
*range
)
867 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
868 FIXME("(%p)->(%u %p %u %p): stub\n", This
, position
, name
, name_size
, range
);
872 static HRESULT WINAPI
dwritetextlayout_layout_GetFontWeight(IDWriteTextLayout
*iface
,
873 UINT32 position
, DWRITE_FONT_WEIGHT
*weight
, DWRITE_TEXT_RANGE
*r
)
875 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
876 struct layout_range
*range
;
878 TRACE("(%p)->(%u %p %p)\n", This
, position
, weight
, r
);
880 if (position
>= This
->len
)
883 range
= get_layout_range_by_pos(&This
->ranges
, position
);
884 *weight
= range
->weight
;
885 if (r
) *r
= range
->range
;
890 static HRESULT WINAPI
dwritetextlayout_layout_GetFontStyle(IDWriteTextLayout
*iface
,
891 UINT32 position
, DWRITE_FONT_STYLE
*style
, DWRITE_TEXT_RANGE
*r
)
893 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
894 struct layout_range
*range
;
896 TRACE("(%p)->(%u %p %p)\n", This
, position
, style
, r
);
898 if (position
>= This
->len
)
901 range
= get_layout_range_by_pos(&This
->ranges
, position
);
902 *style
= range
->style
;
903 if (r
) *r
= range
->range
;
908 static HRESULT WINAPI
dwritetextlayout_layout_GetFontStretch(IDWriteTextLayout
*iface
,
909 UINT32 position
, DWRITE_FONT_STRETCH
*stretch
, DWRITE_TEXT_RANGE
*range
)
911 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
912 FIXME("(%p)->(%u %p %p): stub\n", This
, position
, stretch
, range
);
916 static HRESULT WINAPI
dwritetextlayout_layout_GetFontSize(IDWriteTextLayout
*iface
,
917 UINT32 position
, FLOAT
*size
, DWRITE_TEXT_RANGE
*range
)
919 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
920 FIXME("(%p)->(%u %p %p): stub\n", This
, position
, size
, range
);
924 static HRESULT WINAPI
dwritetextlayout_GetUnderline(IDWriteTextLayout
*iface
,
925 UINT32 position
, BOOL
*underline
, DWRITE_TEXT_RANGE
*r
)
927 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
928 struct layout_range
*range
;
930 TRACE("(%p)->(%u %p %p)\n", This
, position
, underline
, r
);
932 if (position
>= This
->len
)
935 range
= get_layout_range_by_pos(&This
->ranges
, position
);
936 *underline
= range
->underline
;
937 if (r
) *r
= range
->range
;
942 static HRESULT WINAPI
dwritetextlayout_GetStrikethrough(IDWriteTextLayout
*iface
,
943 UINT32 position
, BOOL
*strikethrough
, DWRITE_TEXT_RANGE
*r
)
945 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
946 struct layout_range
*range
;
948 TRACE("(%p)->(%u %p %p)\n", This
, position
, strikethrough
, r
);
950 if (position
>= This
->len
)
953 range
= get_layout_range_by_pos(&This
->ranges
, position
);
954 *strikethrough
= range
->strikethrough
;
955 if (r
) *r
= range
->range
;
960 static HRESULT WINAPI
dwritetextlayout_GetDrawingEffect(IDWriteTextLayout
*iface
,
961 UINT32 position
, IUnknown
**effect
, DWRITE_TEXT_RANGE
*r
)
963 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
964 struct layout_range
*range
;
966 TRACE("(%p)->(%u %p %p)\n", This
, position
, effect
, r
);
968 if (position
>= This
->len
)
971 range
= get_layout_range_by_pos(&This
->ranges
, position
);
972 *effect
= range
->effect
;
974 IUnknown_AddRef(*effect
);
975 if (r
) *r
= range
->range
;
980 static HRESULT WINAPI
dwritetextlayout_GetInlineObject(IDWriteTextLayout
*iface
,
981 UINT32 position
, IDWriteInlineObject
**object
, DWRITE_TEXT_RANGE
*r
)
983 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
984 struct layout_range
*range
;
986 TRACE("(%p)->(%u %p %p)\n", This
, position
, object
, r
);
988 range
= get_layout_range_by_pos(&This
->ranges
, position
);
989 *object
= range
? range
->object
: NULL
;
991 IDWriteInlineObject_AddRef(*object
);
992 if (r
) *r
= range
->range
;
997 static HRESULT WINAPI
dwritetextlayout_GetTypography(IDWriteTextLayout
*iface
,
998 UINT32 position
, IDWriteTypography
** typography
, DWRITE_TEXT_RANGE
*range
)
1000 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1001 FIXME("(%p)->(%u %p %p): stub\n", This
, position
, typography
, range
);
1005 static HRESULT WINAPI
dwritetextlayout_layout_GetLocaleNameLength(IDWriteTextLayout
*iface
,
1006 UINT32 position
, UINT32
* length
, DWRITE_TEXT_RANGE
*range
)
1008 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1009 FIXME("(%p)->(%u %p %p): stub\n", This
, position
, length
, range
);
1013 static HRESULT WINAPI
dwritetextlayout_layout_GetLocaleName(IDWriteTextLayout
*iface
,
1014 UINT32 position
, WCHAR
* name
, UINT32 name_size
, DWRITE_TEXT_RANGE
*range
)
1016 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1017 FIXME("(%p)->(%u %p %u %p): stub\n", This
, position
, name
, name_size
, range
);
1021 static HRESULT WINAPI
dwritetextlayout_Draw(IDWriteTextLayout
*iface
,
1022 void *context
, IDWriteTextRenderer
* renderer
, FLOAT originX
, FLOAT originY
)
1024 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1025 FIXME("(%p)->(%p %p %f %f): stub\n", This
, context
, renderer
, originX
, originY
);
1029 static HRESULT WINAPI
dwritetextlayout_GetLineMetrics(IDWriteTextLayout
*iface
,
1030 DWRITE_LINE_METRICS
*metrics
, UINT32 max_count
, UINT32
*actual_count
)
1032 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1033 FIXME("(%p)->(%p %u %p): stub\n", This
, metrics
, max_count
, actual_count
);
1037 static HRESULT WINAPI
dwritetextlayout_GetMetrics(IDWriteTextLayout
*iface
, DWRITE_TEXT_METRICS
*metrics
)
1039 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1040 FIXME("(%p)->(%p): stub\n", This
, metrics
);
1044 static HRESULT WINAPI
dwritetextlayout_GetOverhangMetrics(IDWriteTextLayout
*iface
, DWRITE_OVERHANG_METRICS
*overhangs
)
1046 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1047 FIXME("(%p)->(%p): stub\n", This
, overhangs
);
1051 static HRESULT WINAPI
dwritetextlayout_GetClusterMetrics(IDWriteTextLayout
*iface
,
1052 DWRITE_CLUSTER_METRICS
*metrics
, UINT32 max_count
, UINT32
* act_count
)
1054 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1055 FIXME("(%p)->(%p %u %p): stub\n", This
, metrics
, max_count
, act_count
);
1059 static HRESULT WINAPI
dwritetextlayout_DetermineMinWidth(IDWriteTextLayout
*iface
, FLOAT
* min_width
)
1061 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1062 FIXME("(%p)->(%p): stub\n", This
, min_width
);
1066 static HRESULT WINAPI
dwritetextlayout_HitTestPoint(IDWriteTextLayout
*iface
,
1067 FLOAT pointX
, FLOAT pointY
, BOOL
* is_trailinghit
, BOOL
* is_inside
, DWRITE_HIT_TEST_METRICS
*metrics
)
1069 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1070 FIXME("(%p)->(%f %f %p %p %p): stub\n", This
, pointX
, pointY
, is_trailinghit
, is_inside
, metrics
);
1074 static HRESULT WINAPI
dwritetextlayout_HitTestTextPosition(IDWriteTextLayout
*iface
,
1075 UINT32 textPosition
, BOOL is_trailinghit
, FLOAT
* pointX
, FLOAT
* pointY
, DWRITE_HIT_TEST_METRICS
*metrics
)
1077 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1078 FIXME("(%p)->(%u %d %p %p %p): stub\n", This
, textPosition
, is_trailinghit
, pointX
, pointY
, metrics
);
1082 static HRESULT WINAPI
dwritetextlayout_HitTestTextRange(IDWriteTextLayout
*iface
,
1083 UINT32 textPosition
, UINT32 textLength
, FLOAT originX
, FLOAT originY
,
1084 DWRITE_HIT_TEST_METRICS
*metrics
, UINT32 max_metricscount
, UINT32
* actual_metricscount
)
1086 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1087 FIXME("(%p)->(%u %u %f %f %p %u %p): stub\n", This
, textPosition
, textLength
, originX
, originY
, metrics
,
1088 max_metricscount
, actual_metricscount
);
1092 static const IDWriteTextLayoutVtbl dwritetextlayoutvtbl
= {
1093 dwritetextlayout_QueryInterface
,
1094 dwritetextlayout_AddRef
,
1095 dwritetextlayout_Release
,
1096 dwritetextlayout_SetTextAlignment
,
1097 dwritetextlayout_SetParagraphAlignment
,
1098 dwritetextlayout_SetWordWrapping
,
1099 dwritetextlayout_SetReadingDirection
,
1100 dwritetextlayout_SetFlowDirection
,
1101 dwritetextlayout_SetIncrementalTabStop
,
1102 dwritetextlayout_SetTrimming
,
1103 dwritetextlayout_SetLineSpacing
,
1104 dwritetextlayout_GetTextAlignment
,
1105 dwritetextlayout_GetParagraphAlignment
,
1106 dwritetextlayout_GetWordWrapping
,
1107 dwritetextlayout_GetReadingDirection
,
1108 dwritetextlayout_GetFlowDirection
,
1109 dwritetextlayout_GetIncrementalTabStop
,
1110 dwritetextlayout_GetTrimming
,
1111 dwritetextlayout_GetLineSpacing
,
1112 dwritetextlayout_GetFontCollection
,
1113 dwritetextlayout_GetFontFamilyNameLength
,
1114 dwritetextlayout_GetFontFamilyName
,
1115 dwritetextlayout_GetFontWeight
,
1116 dwritetextlayout_GetFontStyle
,
1117 dwritetextlayout_GetFontStretch
,
1118 dwritetextlayout_GetFontSize
,
1119 dwritetextlayout_GetLocaleNameLength
,
1120 dwritetextlayout_GetLocaleName
,
1121 dwritetextlayout_SetMaxWidth
,
1122 dwritetextlayout_SetMaxHeight
,
1123 dwritetextlayout_SetFontCollection
,
1124 dwritetextlayout_SetFontFamilyName
,
1125 dwritetextlayout_SetFontWeight
,
1126 dwritetextlayout_SetFontStyle
,
1127 dwritetextlayout_SetFontStretch
,
1128 dwritetextlayout_SetFontSize
,
1129 dwritetextlayout_SetUnderline
,
1130 dwritetextlayout_SetStrikethrough
,
1131 dwritetextlayout_SetDrawingEffect
,
1132 dwritetextlayout_SetInlineObject
,
1133 dwritetextlayout_SetTypography
,
1134 dwritetextlayout_SetLocaleName
,
1135 dwritetextlayout_GetMaxWidth
,
1136 dwritetextlayout_GetMaxHeight
,
1137 dwritetextlayout_layout_GetFontCollection
,
1138 dwritetextlayout_layout_GetFontFamilyNameLength
,
1139 dwritetextlayout_layout_GetFontFamilyName
,
1140 dwritetextlayout_layout_GetFontWeight
,
1141 dwritetextlayout_layout_GetFontStyle
,
1142 dwritetextlayout_layout_GetFontStretch
,
1143 dwritetextlayout_layout_GetFontSize
,
1144 dwritetextlayout_GetUnderline
,
1145 dwritetextlayout_GetStrikethrough
,
1146 dwritetextlayout_GetDrawingEffect
,
1147 dwritetextlayout_GetInlineObject
,
1148 dwritetextlayout_GetTypography
,
1149 dwritetextlayout_layout_GetLocaleNameLength
,
1150 dwritetextlayout_layout_GetLocaleName
,
1151 dwritetextlayout_Draw
,
1152 dwritetextlayout_GetLineMetrics
,
1153 dwritetextlayout_GetMetrics
,
1154 dwritetextlayout_GetOverhangMetrics
,
1155 dwritetextlayout_GetClusterMetrics
,
1156 dwritetextlayout_DetermineMinWidth
,
1157 dwritetextlayout_HitTestPoint
,
1158 dwritetextlayout_HitTestTextPosition
,
1159 dwritetextlayout_HitTestTextRange
1162 static void layout_format_from_textformat(struct dwrite_textlayout
*layout
, IDWriteTextFormat
*format
)
1164 struct dwrite_textformat
*f
;
1166 memset(&layout
->format
, 0, sizeof(layout
->format
));
1168 if ((f
= unsafe_impl_from_IDWriteTextFormat(format
)))
1170 layout
->format
= f
->format
;
1171 layout
->format
.locale
= heap_strdupW(f
->format
.locale
);
1172 layout
->format
.family_name
= heap_strdupW(f
->format
.family_name
);
1173 if (layout
->format
.trimmingsign
)
1174 IDWriteInlineObject_AddRef(layout
->format
.trimmingsign
);
1178 UINT32 locale_len
, family_len
;
1180 layout
->format
.weight
= IDWriteTextFormat_GetFontWeight(format
);
1181 layout
->format
.style
= IDWriteTextFormat_GetFontStyle(format
);
1182 layout
->format
.stretch
= IDWriteTextFormat_GetFontStretch(format
);
1183 layout
->format
.size
= IDWriteTextFormat_GetFontSize(format
);
1184 layout
->format
.textalignment
= IDWriteTextFormat_GetTextAlignment(format
);
1185 layout
->format
.paralign
= IDWriteTextFormat_GetParagraphAlignment(format
);
1186 layout
->format
.wrapping
= IDWriteTextFormat_GetWordWrapping(format
);
1187 layout
->format
.readingdir
= IDWriteTextFormat_GetReadingDirection(format
);
1188 layout
->format
.flow
= IDWriteTextFormat_GetFlowDirection(format
);
1189 IDWriteTextFormat_GetLineSpacing(format
,
1190 &layout
->format
.spacingmethod
,
1191 &layout
->format
.spacing
,
1192 &layout
->format
.baseline
1194 IDWriteTextFormat_GetTrimming(format
, &layout
->format
.trimming
, &layout
->format
.trimmingsign
);
1196 /* locale name and length */
1197 locale_len
= IDWriteTextFormat_GetLocaleNameLength(format
);
1198 layout
->format
.locale
= heap_alloc((locale_len
+1)*sizeof(WCHAR
));
1199 IDWriteTextFormat_GetLocaleName(format
, layout
->format
.locale
, locale_len
+1);
1200 layout
->format
.locale_len
= locale_len
;
1202 /* font family name and length */
1203 family_len
= IDWriteTextFormat_GetFontFamilyNameLength(format
);
1204 layout
->format
.family_name
= heap_alloc((family_len
+1)*sizeof(WCHAR
));
1205 IDWriteTextFormat_GetFontFamilyName(format
, layout
->format
.family_name
, family_len
+1);
1206 layout
->format
.family_len
= family_len
;
1209 IDWriteTextFormat_GetFontCollection(format
, &layout
->format
.collection
);
1212 HRESULT
create_textlayout(const WCHAR
*str
, UINT32 len
, IDWriteTextFormat
*format
, FLOAT maxwidth
, FLOAT maxheight
, IDWriteTextLayout
**layout
)
1214 struct dwrite_textlayout
*This
;
1215 struct layout_range
*range
;
1216 DWRITE_TEXT_RANGE r
= { 0, len
};
1220 This
= heap_alloc(sizeof(struct dwrite_textlayout
));
1221 if (!This
) return E_OUTOFMEMORY
;
1223 This
->IDWriteTextLayout_iface
.lpVtbl
= &dwritetextlayoutvtbl
;
1225 This
->str
= heap_strdupnW(str
, len
);
1227 This
->maxwidth
= maxwidth
;
1228 This
->maxheight
= maxheight
;
1229 layout_format_from_textformat(This
, format
);
1231 list_init(&This
->ranges
);
1232 range
= alloc_layout_range(This
, &r
);
1234 IDWriteTextLayout_Release(&This
->IDWriteTextLayout_iface
);
1235 return E_OUTOFMEMORY
;
1237 list_add_head(&This
->ranges
, &range
->entry
);
1239 *layout
= &This
->IDWriteTextLayout_iface
;
1244 static HRESULT WINAPI
dwritetrimmingsign_QueryInterface(IDWriteInlineObject
*iface
, REFIID riid
, void **obj
)
1246 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1248 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1250 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteInlineObject
)) {
1252 IDWriteInlineObject_AddRef(iface
);
1257 return E_NOINTERFACE
;
1261 static ULONG WINAPI
dwritetrimmingsign_AddRef(IDWriteInlineObject
*iface
)
1263 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1264 ULONG ref
= InterlockedIncrement(&This
->ref
);
1265 TRACE("(%p)->(%d)\n", This
, ref
);
1269 static ULONG WINAPI
dwritetrimmingsign_Release(IDWriteInlineObject
*iface
)
1271 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1272 ULONG ref
= InterlockedDecrement(&This
->ref
);
1274 TRACE("(%p)->(%d)\n", This
, ref
);
1282 static HRESULT WINAPI
dwritetrimmingsign_Draw(IDWriteInlineObject
*iface
, void *context
, IDWriteTextRenderer
*renderer
,
1283 FLOAT originX
, FLOAT originY
, BOOL is_sideways
, BOOL is_rtl
, IUnknown
*drawing_effect
)
1285 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1286 FIXME("(%p)->(%p %p %f %f %d %d %p): stub\n", This
, context
, renderer
, originX
, originY
, is_sideways
, is_rtl
, drawing_effect
);
1290 static HRESULT WINAPI
dwritetrimmingsign_GetMetrics(IDWriteInlineObject
*iface
, DWRITE_INLINE_OBJECT_METRICS
*metrics
)
1292 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1293 FIXME("(%p)->(%p): stub\n", This
, metrics
);
1297 static HRESULT WINAPI
dwritetrimmingsign_GetOverhangMetrics(IDWriteInlineObject
*iface
, DWRITE_OVERHANG_METRICS
*overhangs
)
1299 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1300 FIXME("(%p)->(%p): stub\n", This
, overhangs
);
1304 static HRESULT WINAPI
dwritetrimmingsign_GetBreakConditions(IDWriteInlineObject
*iface
, DWRITE_BREAK_CONDITION
*before
,
1305 DWRITE_BREAK_CONDITION
*after
)
1307 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1309 TRACE("(%p)->(%p %p)\n", This
, before
, after
);
1311 *before
= *after
= DWRITE_BREAK_CONDITION_NEUTRAL
;
1315 static const IDWriteInlineObjectVtbl dwritetrimmingsignvtbl
= {
1316 dwritetrimmingsign_QueryInterface
,
1317 dwritetrimmingsign_AddRef
,
1318 dwritetrimmingsign_Release
,
1319 dwritetrimmingsign_Draw
,
1320 dwritetrimmingsign_GetMetrics
,
1321 dwritetrimmingsign_GetOverhangMetrics
,
1322 dwritetrimmingsign_GetBreakConditions
1325 HRESULT
create_trimmingsign(IDWriteInlineObject
**sign
)
1327 struct dwrite_trimmingsign
*This
;
1331 This
= heap_alloc(sizeof(struct dwrite_trimmingsign
));
1332 if (!This
) return E_OUTOFMEMORY
;
1334 This
->IDWriteInlineObject_iface
.lpVtbl
= &dwritetrimmingsignvtbl
;
1337 *sign
= &This
->IDWriteInlineObject_iface
;
1342 static HRESULT WINAPI
dwritetextformat_QueryInterface(IDWriteTextFormat
*iface
, REFIID riid
, void **obj
)
1344 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1346 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1348 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1349 IsEqualIID(riid
, &IID_IDWriteTextFormat
))
1352 IDWriteTextFormat_AddRef(iface
);
1358 return E_NOINTERFACE
;
1361 static ULONG WINAPI
dwritetextformat_AddRef(IDWriteTextFormat
*iface
)
1363 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1364 ULONG ref
= InterlockedIncrement(&This
->ref
);
1365 TRACE("(%p)->(%d)\n", This
, ref
);
1369 static ULONG WINAPI
dwritetextformat_Release(IDWriteTextFormat
*iface
)
1371 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1372 ULONG ref
= InterlockedDecrement(&This
->ref
);
1374 TRACE("(%p)->(%d)\n", This
, ref
);
1378 release_format_data(&This
->format
);
1385 static HRESULT WINAPI
dwritetextformat_SetTextAlignment(IDWriteTextFormat
*iface
, DWRITE_TEXT_ALIGNMENT alignment
)
1387 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1388 TRACE("(%p)->(%d)\n", This
, alignment
);
1389 This
->format
.textalignment
= alignment
;
1393 static HRESULT WINAPI
dwritetextformat_SetParagraphAlignment(IDWriteTextFormat
*iface
, DWRITE_PARAGRAPH_ALIGNMENT alignment
)
1395 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1396 TRACE("(%p)->(%d)\n", This
, alignment
);
1397 This
->format
.paralign
= alignment
;
1401 static HRESULT WINAPI
dwritetextformat_SetWordWrapping(IDWriteTextFormat
*iface
, DWRITE_WORD_WRAPPING wrapping
)
1403 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1404 TRACE("(%p)->(%d)\n", This
, wrapping
);
1405 This
->format
.wrapping
= wrapping
;
1409 static HRESULT WINAPI
dwritetextformat_SetReadingDirection(IDWriteTextFormat
*iface
, DWRITE_READING_DIRECTION direction
)
1411 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1412 TRACE("(%p)->(%d)\n", This
, direction
);
1413 This
->format
.readingdir
= direction
;
1417 static HRESULT WINAPI
dwritetextformat_SetFlowDirection(IDWriteTextFormat
*iface
, DWRITE_FLOW_DIRECTION direction
)
1419 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1420 TRACE("(%p)->(%d)\n", This
, direction
);
1421 This
->format
.flow
= direction
;
1425 static HRESULT WINAPI
dwritetextformat_SetIncrementalTabStop(IDWriteTextFormat
*iface
, FLOAT tabstop
)
1427 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1428 FIXME("(%p)->(%f): stub\n", This
, tabstop
);
1432 static HRESULT WINAPI
dwritetextformat_SetTrimming(IDWriteTextFormat
*iface
, DWRITE_TRIMMING
const *trimming
,
1433 IDWriteInlineObject
*trimming_sign
)
1435 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1436 TRACE("(%p)->(%p %p)\n", This
, trimming
, trimming_sign
);
1438 This
->format
.trimming
= *trimming
;
1439 if (This
->format
.trimmingsign
)
1440 IDWriteInlineObject_Release(This
->format
.trimmingsign
);
1441 This
->format
.trimmingsign
= trimming_sign
;
1442 if (This
->format
.trimmingsign
)
1443 IDWriteInlineObject_AddRef(This
->format
.trimmingsign
);
1447 static HRESULT WINAPI
dwritetextformat_SetLineSpacing(IDWriteTextFormat
*iface
, DWRITE_LINE_SPACING_METHOD method
,
1448 FLOAT spacing
, FLOAT baseline
)
1450 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1451 TRACE("(%p)->(%d %f %f)\n", This
, method
, spacing
, baseline
);
1452 This
->format
.spacingmethod
= method
;
1453 This
->format
.spacing
= spacing
;
1454 This
->format
.baseline
= baseline
;
1458 static DWRITE_TEXT_ALIGNMENT WINAPI
dwritetextformat_GetTextAlignment(IDWriteTextFormat
*iface
)
1460 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1461 TRACE("(%p)\n", This
);
1462 return This
->format
.textalignment
;
1465 static DWRITE_PARAGRAPH_ALIGNMENT WINAPI
dwritetextformat_GetParagraphAlignment(IDWriteTextFormat
*iface
)
1467 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1468 TRACE("(%p)\n", This
);
1469 return This
->format
.paralign
;
1472 static DWRITE_WORD_WRAPPING WINAPI
dwritetextformat_GetWordWrapping(IDWriteTextFormat
*iface
)
1474 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1475 TRACE("(%p)\n", This
);
1476 return This
->format
.wrapping
;
1479 static DWRITE_READING_DIRECTION WINAPI
dwritetextformat_GetReadingDirection(IDWriteTextFormat
*iface
)
1481 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1482 TRACE("(%p)\n", This
);
1483 return This
->format
.readingdir
;
1486 static DWRITE_FLOW_DIRECTION WINAPI
dwritetextformat_GetFlowDirection(IDWriteTextFormat
*iface
)
1488 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1489 TRACE("(%p)\n", This
);
1490 return This
->format
.flow
;
1493 static FLOAT WINAPI
dwritetextformat_GetIncrementalTabStop(IDWriteTextFormat
*iface
)
1495 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1496 FIXME("(%p): stub\n", This
);
1500 static HRESULT WINAPI
dwritetextformat_GetTrimming(IDWriteTextFormat
*iface
, DWRITE_TRIMMING
*options
,
1501 IDWriteInlineObject
**trimming_sign
)
1503 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1504 TRACE("(%p)->(%p %p)\n", This
, options
, trimming_sign
);
1506 *options
= This
->format
.trimming
;
1507 if ((*trimming_sign
= This
->format
.trimmingsign
))
1508 IDWriteInlineObject_AddRef(*trimming_sign
);
1513 static HRESULT WINAPI
dwritetextformat_GetLineSpacing(IDWriteTextFormat
*iface
, DWRITE_LINE_SPACING_METHOD
*method
,
1514 FLOAT
*spacing
, FLOAT
*baseline
)
1516 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1517 TRACE("(%p)->(%p %p %p)\n", This
, method
, spacing
, baseline
);
1519 *method
= This
->format
.spacingmethod
;
1520 *spacing
= This
->format
.spacing
;
1521 *baseline
= This
->format
.baseline
;
1525 static HRESULT WINAPI
dwritetextformat_GetFontCollection(IDWriteTextFormat
*iface
, IDWriteFontCollection
**collection
)
1527 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1529 TRACE("(%p)->(%p)\n", This
, collection
);
1531 *collection
= This
->format
.collection
;
1532 IDWriteFontCollection_AddRef(*collection
);
1537 static UINT32 WINAPI
dwritetextformat_GetFontFamilyNameLength(IDWriteTextFormat
*iface
)
1539 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1540 TRACE("(%p)\n", This
);
1541 return This
->format
.family_len
;
1544 static HRESULT WINAPI
dwritetextformat_GetFontFamilyName(IDWriteTextFormat
*iface
, WCHAR
*name
, UINT32 size
)
1546 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1548 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
1550 if (size
<= This
->format
.family_len
) return E_NOT_SUFFICIENT_BUFFER
;
1551 strcpyW(name
, This
->format
.family_name
);
1555 static DWRITE_FONT_WEIGHT WINAPI
dwritetextformat_GetFontWeight(IDWriteTextFormat
*iface
)
1557 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1558 TRACE("(%p)\n", This
);
1559 return This
->format
.weight
;
1562 static DWRITE_FONT_STYLE WINAPI
dwritetextformat_GetFontStyle(IDWriteTextFormat
*iface
)
1564 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1565 TRACE("(%p)\n", This
);
1566 return This
->format
.style
;
1569 static DWRITE_FONT_STRETCH WINAPI
dwritetextformat_GetFontStretch(IDWriteTextFormat
*iface
)
1571 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1572 TRACE("(%p)\n", This
);
1573 return This
->format
.stretch
;
1576 static FLOAT WINAPI
dwritetextformat_GetFontSize(IDWriteTextFormat
*iface
)
1578 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1579 TRACE("(%p)\n", This
);
1580 return This
->format
.size
;
1583 static UINT32 WINAPI
dwritetextformat_GetLocaleNameLength(IDWriteTextFormat
*iface
)
1585 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1586 TRACE("(%p)\n", This
);
1587 return This
->format
.locale_len
;
1590 static HRESULT WINAPI
dwritetextformat_GetLocaleName(IDWriteTextFormat
*iface
, WCHAR
*name
, UINT32 size
)
1592 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1594 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
1596 if (size
<= This
->format
.locale_len
) return E_NOT_SUFFICIENT_BUFFER
;
1597 strcpyW(name
, This
->format
.locale
);
1601 static const IDWriteTextFormatVtbl dwritetextformatvtbl
= {
1602 dwritetextformat_QueryInterface
,
1603 dwritetextformat_AddRef
,
1604 dwritetextformat_Release
,
1605 dwritetextformat_SetTextAlignment
,
1606 dwritetextformat_SetParagraphAlignment
,
1607 dwritetextformat_SetWordWrapping
,
1608 dwritetextformat_SetReadingDirection
,
1609 dwritetextformat_SetFlowDirection
,
1610 dwritetextformat_SetIncrementalTabStop
,
1611 dwritetextformat_SetTrimming
,
1612 dwritetextformat_SetLineSpacing
,
1613 dwritetextformat_GetTextAlignment
,
1614 dwritetextformat_GetParagraphAlignment
,
1615 dwritetextformat_GetWordWrapping
,
1616 dwritetextformat_GetReadingDirection
,
1617 dwritetextformat_GetFlowDirection
,
1618 dwritetextformat_GetIncrementalTabStop
,
1619 dwritetextformat_GetTrimming
,
1620 dwritetextformat_GetLineSpacing
,
1621 dwritetextformat_GetFontCollection
,
1622 dwritetextformat_GetFontFamilyNameLength
,
1623 dwritetextformat_GetFontFamilyName
,
1624 dwritetextformat_GetFontWeight
,
1625 dwritetextformat_GetFontStyle
,
1626 dwritetextformat_GetFontStretch
,
1627 dwritetextformat_GetFontSize
,
1628 dwritetextformat_GetLocaleNameLength
,
1629 dwritetextformat_GetLocaleName
1632 HRESULT
create_textformat(const WCHAR
*family_name
, IDWriteFontCollection
*collection
, DWRITE_FONT_WEIGHT weight
, DWRITE_FONT_STYLE style
,
1633 DWRITE_FONT_STRETCH stretch
, FLOAT size
, const WCHAR
*locale
, IDWriteTextFormat
**format
)
1635 struct dwrite_textformat
*This
;
1639 This
= heap_alloc(sizeof(struct dwrite_textformat
));
1640 if (!This
) return E_OUTOFMEMORY
;
1642 This
->IDWriteTextFormat_iface
.lpVtbl
= &dwritetextformatvtbl
;
1644 This
->format
.family_name
= heap_strdupW(family_name
);
1645 This
->format
.family_len
= strlenW(family_name
);
1646 This
->format
.locale
= heap_strdupW(locale
);
1647 This
->format
.locale_len
= strlenW(locale
);
1648 This
->format
.weight
= weight
;
1649 This
->format
.style
= style
;
1650 This
->format
.size
= size
;
1651 This
->format
.stretch
= stretch
;
1652 This
->format
.textalignment
= DWRITE_TEXT_ALIGNMENT_LEADING
;
1653 This
->format
.paralign
= DWRITE_PARAGRAPH_ALIGNMENT_NEAR
;
1654 This
->format
.wrapping
= DWRITE_WORD_WRAPPING_WRAP
;
1655 This
->format
.readingdir
= DWRITE_READING_DIRECTION_LEFT_TO_RIGHT
;
1656 This
->format
.flow
= DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM
;
1657 This
->format
.spacingmethod
= DWRITE_LINE_SPACING_METHOD_DEFAULT
;
1658 This
->format
.spacing
= 0.0;
1659 This
->format
.baseline
= 0.0;
1660 This
->format
.trimming
.granularity
= DWRITE_TRIMMING_GRANULARITY_NONE
;
1661 This
->format
.trimming
.delimiter
= 0;
1662 This
->format
.trimming
.delimiterCount
= 0;
1663 This
->format
.trimmingsign
= NULL
;
1667 This
->format
.collection
= collection
;
1668 IDWriteFontCollection_AddRef(collection
);
1672 HRESULT hr
= get_system_fontcollection(&This
->format
.collection
);
1675 IDWriteTextFormat_Release(&This
->IDWriteTextFormat_iface
);
1680 *format
= &This
->IDWriteTextFormat_iface
;