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 dwrite_textlayout
*layout
)
244 struct layout_range
*cur
, *cur2
;
245 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &layout
->ranges
, struct layout_range
, entry
) {
246 list_remove(&cur
->entry
);
247 free_layout_range(cur
);
251 static struct layout_range
*find_outer_range(struct dwrite_textlayout
*layout
, const DWRITE_TEXT_RANGE
*range
)
253 struct layout_range
*cur
;
255 LIST_FOR_EACH_ENTRY(cur
, &layout
->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 dwrite_textlayout
*layout
, UINT32 pos
)
272 struct layout_range
*cur
;
274 LIST_FOR_EACH_ENTRY(cur
, &layout
->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(layout
, &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(layout
, 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
);
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 TRACE("(%p)\n", This
);
564 return This
->format
.textalignment
;
567 static DWRITE_PARAGRAPH_ALIGNMENT WINAPI
dwritetextlayout_GetParagraphAlignment(IDWriteTextLayout
*iface
)
569 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
570 TRACE("(%p)\n", This
);
571 return This
->format
.paralign
;
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 This
->format
.wrapping
;
581 static DWRITE_READING_DIRECTION WINAPI
dwritetextlayout_GetReadingDirection(IDWriteTextLayout
*iface
)
583 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
584 TRACE("(%p)\n", This
);
585 return This
->format
.readingdir
;
588 static DWRITE_FLOW_DIRECTION WINAPI
dwritetextlayout_GetFlowDirection(IDWriteTextLayout
*iface
)
590 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
591 TRACE("(%p)\n", This
);
592 return This
->format
.flow
;
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
);
607 TRACE("(%p)->(%p %p)\n", This
, options
, trimming_sign
);
609 *options
= This
->format
.trimming
;
610 *trimming_sign
= This
->format
.trimmingsign
;
612 IDWriteInlineObject_AddRef(*trimming_sign
);
616 static HRESULT WINAPI
dwritetextlayout_GetLineSpacing(IDWriteTextLayout
*iface
, DWRITE_LINE_SPACING_METHOD
*method
,
617 FLOAT
*spacing
, FLOAT
*baseline
)
619 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
621 TRACE("(%p)->(%p %p %p)\n", This
, method
, spacing
, baseline
);
623 *method
= This
->format
.spacingmethod
;
624 *spacing
= This
->format
.spacing
;
625 *baseline
= This
->format
.baseline
;
629 static HRESULT WINAPI
dwritetextlayout_GetFontCollection(IDWriteTextLayout
*iface
, IDWriteFontCollection
**collection
)
631 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
633 TRACE("(%p)->(%p)\n", This
, collection
);
635 *collection
= This
->format
.collection
;
637 IDWriteFontCollection_AddRef(*collection
);
641 static UINT32 WINAPI
dwritetextlayout_GetFontFamilyNameLength(IDWriteTextLayout
*iface
)
643 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
644 TRACE("(%p)\n", This
);
645 return This
->format
.family_len
;
648 static HRESULT WINAPI
dwritetextlayout_GetFontFamilyName(IDWriteTextLayout
*iface
, WCHAR
*name
, UINT32 size
)
650 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
652 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
654 if (size
<= This
->format
.family_len
) return E_NOT_SUFFICIENT_BUFFER
;
655 strcpyW(name
, This
->format
.family_name
);
659 static DWRITE_FONT_WEIGHT WINAPI
dwritetextlayout_GetFontWeight(IDWriteTextLayout
*iface
)
661 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
662 TRACE("(%p)\n", This
);
663 return This
->format
.weight
;
666 static DWRITE_FONT_STYLE WINAPI
dwritetextlayout_GetFontStyle(IDWriteTextLayout
*iface
)
668 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
669 TRACE("(%p)\n", This
);
670 return This
->format
.style
;
673 static DWRITE_FONT_STRETCH WINAPI
dwritetextlayout_GetFontStretch(IDWriteTextLayout
*iface
)
675 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
676 TRACE("(%p)\n", This
);
677 return This
->format
.stretch
;
680 static FLOAT WINAPI
dwritetextlayout_GetFontSize(IDWriteTextLayout
*iface
)
682 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
683 TRACE("(%p)\n", This
);
684 return This
->format
.size
;
687 static UINT32 WINAPI
dwritetextlayout_GetLocaleNameLength(IDWriteTextLayout
*iface
)
689 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
690 TRACE("(%p)\n", This
);
691 return This
->format
.locale_len
;
694 static HRESULT WINAPI
dwritetextlayout_GetLocaleName(IDWriteTextLayout
*iface
, WCHAR
*name
, UINT32 size
)
696 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
698 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
700 if (size
<= This
->format
.locale_len
) return E_NOT_SUFFICIENT_BUFFER
;
701 strcpyW(name
, This
->format
.locale
);
705 static HRESULT WINAPI
dwritetextlayout_SetMaxWidth(IDWriteTextLayout
*iface
, FLOAT maxWidth
)
707 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
708 TRACE("(%p)->(%.1f)\n", This
, maxWidth
);
709 This
->maxwidth
= maxWidth
;
713 static HRESULT WINAPI
dwritetextlayout_SetMaxHeight(IDWriteTextLayout
*iface
, FLOAT maxHeight
)
715 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
716 TRACE("(%p)->(%.1f)\n", This
, maxHeight
);
717 This
->maxheight
= maxHeight
;
721 static HRESULT WINAPI
dwritetextlayout_SetFontCollection(IDWriteTextLayout
*iface
, IDWriteFontCollection
* collection
, DWRITE_TEXT_RANGE range
)
723 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
724 FIXME("(%p)->(%p %s): stub\n", This
, collection
, debugstr_range(&range
));
728 static HRESULT WINAPI
dwritetextlayout_SetFontFamilyName(IDWriteTextLayout
*iface
, WCHAR
const *name
, DWRITE_TEXT_RANGE range
)
730 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
731 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(name
), debugstr_range(&range
));
735 static HRESULT WINAPI
dwritetextlayout_SetFontWeight(IDWriteTextLayout
*iface
, DWRITE_FONT_WEIGHT weight
, DWRITE_TEXT_RANGE range
)
737 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
738 struct layout_range_attr_value value
;
740 TRACE("(%p)->(%d %s)\n", This
, weight
, debugstr_range(&range
));
742 if (!validate_text_range(This
, &range
))
746 value
.u
.weight
= weight
;
747 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_WEIGHT
, &value
);
750 static HRESULT WINAPI
dwritetextlayout_SetFontStyle(IDWriteTextLayout
*iface
, DWRITE_FONT_STYLE style
, DWRITE_TEXT_RANGE range
)
752 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
753 struct layout_range_attr_value value
;
755 TRACE("(%p)->(%d %s)\n", This
, style
, debugstr_range(&range
));
757 if (!validate_text_range(This
, &range
))
761 value
.u
.style
= style
;
762 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_STYLE
, &value
);
765 static HRESULT WINAPI
dwritetextlayout_SetFontStretch(IDWriteTextLayout
*iface
, DWRITE_FONT_STRETCH stretch
, DWRITE_TEXT_RANGE range
)
767 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
768 FIXME("(%p)->(%d %s): stub\n", This
, stretch
, debugstr_range(&range
));
772 static HRESULT WINAPI
dwritetextlayout_SetFontSize(IDWriteTextLayout
*iface
, FLOAT size
, DWRITE_TEXT_RANGE range
)
774 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
775 FIXME("(%p)->(%f %s): stub\n", This
, size
, debugstr_range(&range
));
779 static HRESULT WINAPI
dwritetextlayout_SetUnderline(IDWriteTextLayout
*iface
, BOOL underline
, DWRITE_TEXT_RANGE range
)
781 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
782 struct layout_range_attr_value value
;
784 TRACE("(%p)->(%d %s)\n", This
, underline
, debugstr_range(&range
));
786 if (!validate_text_range(This
, &range
))
790 value
.u
.underline
= underline
;
791 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_UNDERLINE
, &value
);
794 static HRESULT WINAPI
dwritetextlayout_SetStrikethrough(IDWriteTextLayout
*iface
, BOOL strikethrough
, DWRITE_TEXT_RANGE range
)
796 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
797 struct layout_range_attr_value value
;
799 TRACE("(%p)->(%d %s)\n", This
, strikethrough
, debugstr_range(&range
));
801 if (!validate_text_range(This
, &range
))
805 value
.u
.underline
= strikethrough
;
806 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_STRIKETHROUGH
, &value
);
809 static HRESULT WINAPI
dwritetextlayout_SetDrawingEffect(IDWriteTextLayout
*iface
, IUnknown
* effect
, DWRITE_TEXT_RANGE range
)
811 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
812 struct layout_range_attr_value value
;
814 TRACE("(%p)->(%p %s)\n", This
, effect
, debugstr_range(&range
));
816 if (!validate_text_range(This
, &range
))
820 value
.u
.effect
= effect
;
821 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_EFFECT
, &value
);
824 static HRESULT WINAPI
dwritetextlayout_SetInlineObject(IDWriteTextLayout
*iface
, IDWriteInlineObject
*object
, DWRITE_TEXT_RANGE r
)
826 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
827 struct layout_range_attr_value attr
;
829 TRACE("(%p)->(%p %s)\n", This
, object
, debugstr_range(&r
));
831 if (!validate_text_range(This
, &r
))
835 attr
.u
.object
= object
;
837 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_INLINE
, &attr
);
840 static HRESULT WINAPI
dwritetextlayout_SetTypography(IDWriteTextLayout
*iface
, IDWriteTypography
* typography
, DWRITE_TEXT_RANGE range
)
842 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
843 FIXME("(%p)->(%p %s): stub\n", This
, typography
, debugstr_range(&range
));
847 static HRESULT WINAPI
dwritetextlayout_SetLocaleName(IDWriteTextLayout
*iface
, WCHAR
const* locale
, DWRITE_TEXT_RANGE range
)
849 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
850 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(locale
), debugstr_range(&range
));
854 static FLOAT WINAPI
dwritetextlayout_GetMaxWidth(IDWriteTextLayout
*iface
)
856 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
857 TRACE("(%p)\n", This
);
858 return This
->maxwidth
;
861 static FLOAT WINAPI
dwritetextlayout_GetMaxHeight(IDWriteTextLayout
*iface
)
863 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
864 TRACE("(%p)\n", This
);
865 return This
->maxheight
;
868 static HRESULT WINAPI
dwritetextlayout_layout_GetFontCollection(IDWriteTextLayout
*iface
, UINT32 pos
,
869 IDWriteFontCollection
** collection
, DWRITE_TEXT_RANGE
*range
)
871 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
872 FIXME("(%p)->(%p %p): stub\n", This
, collection
, range
);
876 static HRESULT WINAPI
dwritetextlayout_layout_GetFontFamilyNameLength(IDWriteTextLayout
*iface
,
877 UINT32 pos
, UINT32
* len
, DWRITE_TEXT_RANGE
*range
)
879 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
880 FIXME("(%p)->(%d %p %p): stub\n", This
, pos
, len
, range
);
884 static HRESULT WINAPI
dwritetextlayout_layout_GetFontFamilyName(IDWriteTextLayout
*iface
,
885 UINT32 position
, WCHAR
* name
, UINT32 name_size
, DWRITE_TEXT_RANGE
*range
)
887 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
888 FIXME("(%p)->(%u %p %u %p): stub\n", This
, position
, name
, name_size
, range
);
892 static HRESULT WINAPI
dwritetextlayout_layout_GetFontWeight(IDWriteTextLayout
*iface
,
893 UINT32 position
, DWRITE_FONT_WEIGHT
*weight
, DWRITE_TEXT_RANGE
*r
)
895 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
896 struct layout_range
*range
;
898 TRACE("(%p)->(%u %p %p)\n", This
, position
, weight
, r
);
900 if (position
>= This
->len
)
903 range
= get_layout_range_by_pos(This
, position
);
904 *weight
= range
->weight
;
905 if (r
) *r
= range
->range
;
910 static HRESULT WINAPI
dwritetextlayout_layout_GetFontStyle(IDWriteTextLayout
*iface
,
911 UINT32 position
, DWRITE_FONT_STYLE
*style
, DWRITE_TEXT_RANGE
*r
)
913 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
914 struct layout_range
*range
;
916 TRACE("(%p)->(%u %p %p)\n", This
, position
, style
, r
);
918 if (position
>= This
->len
)
921 range
= get_layout_range_by_pos(This
, position
);
922 *style
= range
->style
;
923 if (r
) *r
= range
->range
;
928 static HRESULT WINAPI
dwritetextlayout_layout_GetFontStretch(IDWriteTextLayout
*iface
,
929 UINT32 position
, DWRITE_FONT_STRETCH
*stretch
, DWRITE_TEXT_RANGE
*range
)
931 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
932 FIXME("(%p)->(%u %p %p): stub\n", This
, position
, stretch
, range
);
936 static HRESULT WINAPI
dwritetextlayout_layout_GetFontSize(IDWriteTextLayout
*iface
,
937 UINT32 position
, FLOAT
*size
, DWRITE_TEXT_RANGE
*range
)
939 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
940 FIXME("(%p)->(%u %p %p): stub\n", This
, position
, size
, range
);
944 static HRESULT WINAPI
dwritetextlayout_GetUnderline(IDWriteTextLayout
*iface
,
945 UINT32 position
, BOOL
*underline
, DWRITE_TEXT_RANGE
*r
)
947 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
948 struct layout_range
*range
;
950 TRACE("(%p)->(%u %p %p)\n", This
, position
, underline
, r
);
952 if (position
>= This
->len
)
955 range
= get_layout_range_by_pos(This
, position
);
956 *underline
= range
->underline
;
957 if (r
) *r
= range
->range
;
962 static HRESULT WINAPI
dwritetextlayout_GetStrikethrough(IDWriteTextLayout
*iface
,
963 UINT32 position
, BOOL
*strikethrough
, DWRITE_TEXT_RANGE
*r
)
965 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
966 struct layout_range
*range
;
968 TRACE("(%p)->(%u %p %p)\n", This
, position
, strikethrough
, r
);
970 if (position
>= This
->len
)
973 range
= get_layout_range_by_pos(This
, position
);
974 *strikethrough
= range
->strikethrough
;
975 if (r
) *r
= range
->range
;
980 static HRESULT WINAPI
dwritetextlayout_GetDrawingEffect(IDWriteTextLayout
*iface
,
981 UINT32 position
, IUnknown
**effect
, 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
, effect
, r
);
988 if (position
>= This
->len
)
991 range
= get_layout_range_by_pos(This
, position
);
992 *effect
= range
->effect
;
994 IUnknown_AddRef(*effect
);
995 if (r
) *r
= range
->range
;
1000 static HRESULT WINAPI
dwritetextlayout_GetInlineObject(IDWriteTextLayout
*iface
,
1001 UINT32 position
, IDWriteInlineObject
**object
, DWRITE_TEXT_RANGE
*r
)
1003 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1004 struct layout_range
*range
;
1006 TRACE("(%p)->(%u %p %p)\n", This
, position
, object
, r
);
1008 range
= get_layout_range_by_pos(This
, position
);
1009 *object
= range
? range
->object
: NULL
;
1011 IDWriteInlineObject_AddRef(*object
);
1012 if (r
) *r
= range
->range
;
1017 static HRESULT WINAPI
dwritetextlayout_GetTypography(IDWriteTextLayout
*iface
,
1018 UINT32 position
, IDWriteTypography
** typography
, DWRITE_TEXT_RANGE
*range
)
1020 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1021 FIXME("(%p)->(%u %p %p): stub\n", This
, position
, typography
, range
);
1025 static HRESULT WINAPI
dwritetextlayout_layout_GetLocaleNameLength(IDWriteTextLayout
*iface
,
1026 UINT32 position
, UINT32
* length
, DWRITE_TEXT_RANGE
*range
)
1028 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1029 FIXME("(%p)->(%u %p %p): stub\n", This
, position
, length
, range
);
1033 static HRESULT WINAPI
dwritetextlayout_layout_GetLocaleName(IDWriteTextLayout
*iface
,
1034 UINT32 position
, WCHAR
* name
, UINT32 name_size
, DWRITE_TEXT_RANGE
*range
)
1036 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1037 FIXME("(%p)->(%u %p %u %p): stub\n", This
, position
, name
, name_size
, range
);
1041 static HRESULT WINAPI
dwritetextlayout_Draw(IDWriteTextLayout
*iface
,
1042 void *context
, IDWriteTextRenderer
* renderer
, FLOAT originX
, FLOAT originY
)
1044 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1045 FIXME("(%p)->(%p %p %f %f): stub\n", This
, context
, renderer
, originX
, originY
);
1049 static HRESULT WINAPI
dwritetextlayout_GetLineMetrics(IDWriteTextLayout
*iface
,
1050 DWRITE_LINE_METRICS
*metrics
, UINT32 max_count
, UINT32
*actual_count
)
1052 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1053 FIXME("(%p)->(%p %u %p): stub\n", This
, metrics
, max_count
, actual_count
);
1057 static HRESULT WINAPI
dwritetextlayout_GetMetrics(IDWriteTextLayout
*iface
, DWRITE_TEXT_METRICS
*metrics
)
1059 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1060 FIXME("(%p)->(%p): stub\n", This
, metrics
);
1064 static HRESULT WINAPI
dwritetextlayout_GetOverhangMetrics(IDWriteTextLayout
*iface
, DWRITE_OVERHANG_METRICS
*overhangs
)
1066 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1067 FIXME("(%p)->(%p): stub\n", This
, overhangs
);
1071 static HRESULT WINAPI
dwritetextlayout_GetClusterMetrics(IDWriteTextLayout
*iface
,
1072 DWRITE_CLUSTER_METRICS
*metrics
, UINT32 max_count
, UINT32
* act_count
)
1074 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1075 FIXME("(%p)->(%p %u %p): stub\n", This
, metrics
, max_count
, act_count
);
1079 static HRESULT WINAPI
dwritetextlayout_DetermineMinWidth(IDWriteTextLayout
*iface
, FLOAT
* min_width
)
1081 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1082 FIXME("(%p)->(%p): stub\n", This
, min_width
);
1086 static HRESULT WINAPI
dwritetextlayout_HitTestPoint(IDWriteTextLayout
*iface
,
1087 FLOAT pointX
, FLOAT pointY
, BOOL
* is_trailinghit
, BOOL
* is_inside
, DWRITE_HIT_TEST_METRICS
*metrics
)
1089 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1090 FIXME("(%p)->(%f %f %p %p %p): stub\n", This
, pointX
, pointY
, is_trailinghit
, is_inside
, metrics
);
1094 static HRESULT WINAPI
dwritetextlayout_HitTestTextPosition(IDWriteTextLayout
*iface
,
1095 UINT32 textPosition
, BOOL is_trailinghit
, FLOAT
* pointX
, FLOAT
* pointY
, DWRITE_HIT_TEST_METRICS
*metrics
)
1097 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1098 FIXME("(%p)->(%u %d %p %p %p): stub\n", This
, textPosition
, is_trailinghit
, pointX
, pointY
, metrics
);
1102 static HRESULT WINAPI
dwritetextlayout_HitTestTextRange(IDWriteTextLayout
*iface
,
1103 UINT32 textPosition
, UINT32 textLength
, FLOAT originX
, FLOAT originY
,
1104 DWRITE_HIT_TEST_METRICS
*metrics
, UINT32 max_metricscount
, UINT32
* actual_metricscount
)
1106 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1107 FIXME("(%p)->(%u %u %f %f %p %u %p): stub\n", This
, textPosition
, textLength
, originX
, originY
, metrics
,
1108 max_metricscount
, actual_metricscount
);
1112 static const IDWriteTextLayoutVtbl dwritetextlayoutvtbl
= {
1113 dwritetextlayout_QueryInterface
,
1114 dwritetextlayout_AddRef
,
1115 dwritetextlayout_Release
,
1116 dwritetextlayout_SetTextAlignment
,
1117 dwritetextlayout_SetParagraphAlignment
,
1118 dwritetextlayout_SetWordWrapping
,
1119 dwritetextlayout_SetReadingDirection
,
1120 dwritetextlayout_SetFlowDirection
,
1121 dwritetextlayout_SetIncrementalTabStop
,
1122 dwritetextlayout_SetTrimming
,
1123 dwritetextlayout_SetLineSpacing
,
1124 dwritetextlayout_GetTextAlignment
,
1125 dwritetextlayout_GetParagraphAlignment
,
1126 dwritetextlayout_GetWordWrapping
,
1127 dwritetextlayout_GetReadingDirection
,
1128 dwritetextlayout_GetFlowDirection
,
1129 dwritetextlayout_GetIncrementalTabStop
,
1130 dwritetextlayout_GetTrimming
,
1131 dwritetextlayout_GetLineSpacing
,
1132 dwritetextlayout_GetFontCollection
,
1133 dwritetextlayout_GetFontFamilyNameLength
,
1134 dwritetextlayout_GetFontFamilyName
,
1135 dwritetextlayout_GetFontWeight
,
1136 dwritetextlayout_GetFontStyle
,
1137 dwritetextlayout_GetFontStretch
,
1138 dwritetextlayout_GetFontSize
,
1139 dwritetextlayout_GetLocaleNameLength
,
1140 dwritetextlayout_GetLocaleName
,
1141 dwritetextlayout_SetMaxWidth
,
1142 dwritetextlayout_SetMaxHeight
,
1143 dwritetextlayout_SetFontCollection
,
1144 dwritetextlayout_SetFontFamilyName
,
1145 dwritetextlayout_SetFontWeight
,
1146 dwritetextlayout_SetFontStyle
,
1147 dwritetextlayout_SetFontStretch
,
1148 dwritetextlayout_SetFontSize
,
1149 dwritetextlayout_SetUnderline
,
1150 dwritetextlayout_SetStrikethrough
,
1151 dwritetextlayout_SetDrawingEffect
,
1152 dwritetextlayout_SetInlineObject
,
1153 dwritetextlayout_SetTypography
,
1154 dwritetextlayout_SetLocaleName
,
1155 dwritetextlayout_GetMaxWidth
,
1156 dwritetextlayout_GetMaxHeight
,
1157 dwritetextlayout_layout_GetFontCollection
,
1158 dwritetextlayout_layout_GetFontFamilyNameLength
,
1159 dwritetextlayout_layout_GetFontFamilyName
,
1160 dwritetextlayout_layout_GetFontWeight
,
1161 dwritetextlayout_layout_GetFontStyle
,
1162 dwritetextlayout_layout_GetFontStretch
,
1163 dwritetextlayout_layout_GetFontSize
,
1164 dwritetextlayout_GetUnderline
,
1165 dwritetextlayout_GetStrikethrough
,
1166 dwritetextlayout_GetDrawingEffect
,
1167 dwritetextlayout_GetInlineObject
,
1168 dwritetextlayout_GetTypography
,
1169 dwritetextlayout_layout_GetLocaleNameLength
,
1170 dwritetextlayout_layout_GetLocaleName
,
1171 dwritetextlayout_Draw
,
1172 dwritetextlayout_GetLineMetrics
,
1173 dwritetextlayout_GetMetrics
,
1174 dwritetextlayout_GetOverhangMetrics
,
1175 dwritetextlayout_GetClusterMetrics
,
1176 dwritetextlayout_DetermineMinWidth
,
1177 dwritetextlayout_HitTestPoint
,
1178 dwritetextlayout_HitTestTextPosition
,
1179 dwritetextlayout_HitTestTextRange
1182 static void layout_format_from_textformat(struct dwrite_textlayout
*layout
, IDWriteTextFormat
*format
)
1184 struct dwrite_textformat
*f
;
1186 memset(&layout
->format
, 0, sizeof(layout
->format
));
1188 if ((f
= unsafe_impl_from_IDWriteTextFormat(format
)))
1190 layout
->format
= f
->format
;
1191 layout
->format
.locale
= heap_strdupW(f
->format
.locale
);
1192 layout
->format
.family_name
= heap_strdupW(f
->format
.family_name
);
1193 if (layout
->format
.trimmingsign
)
1194 IDWriteInlineObject_AddRef(layout
->format
.trimmingsign
);
1198 UINT32 locale_len
, family_len
;
1200 layout
->format
.weight
= IDWriteTextFormat_GetFontWeight(format
);
1201 layout
->format
.style
= IDWriteTextFormat_GetFontStyle(format
);
1202 layout
->format
.stretch
= IDWriteTextFormat_GetFontStretch(format
);
1203 layout
->format
.size
= IDWriteTextFormat_GetFontSize(format
);
1204 layout
->format
.textalignment
= IDWriteTextFormat_GetTextAlignment(format
);
1205 layout
->format
.paralign
= IDWriteTextFormat_GetParagraphAlignment(format
);
1206 layout
->format
.wrapping
= IDWriteTextFormat_GetWordWrapping(format
);
1207 layout
->format
.readingdir
= IDWriteTextFormat_GetReadingDirection(format
);
1208 layout
->format
.flow
= IDWriteTextFormat_GetFlowDirection(format
);
1209 IDWriteTextFormat_GetLineSpacing(format
,
1210 &layout
->format
.spacingmethod
,
1211 &layout
->format
.spacing
,
1212 &layout
->format
.baseline
1214 IDWriteTextFormat_GetTrimming(format
, &layout
->format
.trimming
, &layout
->format
.trimmingsign
);
1216 /* locale name and length */
1217 locale_len
= IDWriteTextFormat_GetLocaleNameLength(format
);
1218 layout
->format
.locale
= heap_alloc((locale_len
+1)*sizeof(WCHAR
));
1219 IDWriteTextFormat_GetLocaleName(format
, layout
->format
.locale
, locale_len
+1);
1220 layout
->format
.locale_len
= locale_len
;
1222 /* font family name and length */
1223 family_len
= IDWriteTextFormat_GetFontFamilyNameLength(format
);
1224 layout
->format
.family_name
= heap_alloc((family_len
+1)*sizeof(WCHAR
));
1225 IDWriteTextFormat_GetFontFamilyName(format
, layout
->format
.family_name
, family_len
+1);
1226 layout
->format
.family_len
= family_len
;
1229 IDWriteTextFormat_GetFontCollection(format
, &layout
->format
.collection
);
1232 HRESULT
create_textlayout(const WCHAR
*str
, UINT32 len
, IDWriteTextFormat
*format
, FLOAT maxwidth
, FLOAT maxheight
, IDWriteTextLayout
**layout
)
1234 struct dwrite_textlayout
*This
;
1235 struct layout_range
*range
;
1236 DWRITE_TEXT_RANGE r
= { 0, len
};
1240 This
= heap_alloc(sizeof(struct dwrite_textlayout
));
1241 if (!This
) return E_OUTOFMEMORY
;
1243 This
->IDWriteTextLayout_iface
.lpVtbl
= &dwritetextlayoutvtbl
;
1245 This
->str
= heap_strdupnW(str
, len
);
1247 This
->maxwidth
= maxwidth
;
1248 This
->maxheight
= maxheight
;
1249 layout_format_from_textformat(This
, format
);
1251 list_init(&This
->ranges
);
1252 range
= alloc_layout_range(This
, &r
);
1254 IDWriteTextLayout_Release(&This
->IDWriteTextLayout_iface
);
1255 return E_OUTOFMEMORY
;
1257 list_add_head(&This
->ranges
, &range
->entry
);
1259 *layout
= &This
->IDWriteTextLayout_iface
;
1264 static HRESULT WINAPI
dwritetrimmingsign_QueryInterface(IDWriteInlineObject
*iface
, REFIID riid
, void **obj
)
1266 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1268 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1270 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteInlineObject
)) {
1272 IDWriteInlineObject_AddRef(iface
);
1277 return E_NOINTERFACE
;
1281 static ULONG WINAPI
dwritetrimmingsign_AddRef(IDWriteInlineObject
*iface
)
1283 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1284 ULONG ref
= InterlockedIncrement(&This
->ref
);
1285 TRACE("(%p)->(%d)\n", This
, ref
);
1289 static ULONG WINAPI
dwritetrimmingsign_Release(IDWriteInlineObject
*iface
)
1291 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1292 ULONG ref
= InterlockedDecrement(&This
->ref
);
1294 TRACE("(%p)->(%d)\n", This
, ref
);
1302 static HRESULT WINAPI
dwritetrimmingsign_Draw(IDWriteInlineObject
*iface
, void *context
, IDWriteTextRenderer
*renderer
,
1303 FLOAT originX
, FLOAT originY
, BOOL is_sideways
, BOOL is_rtl
, IUnknown
*drawing_effect
)
1305 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1306 FIXME("(%p)->(%p %p %f %f %d %d %p): stub\n", This
, context
, renderer
, originX
, originY
, is_sideways
, is_rtl
, drawing_effect
);
1310 static HRESULT WINAPI
dwritetrimmingsign_GetMetrics(IDWriteInlineObject
*iface
, DWRITE_INLINE_OBJECT_METRICS
*metrics
)
1312 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1313 FIXME("(%p)->(%p): stub\n", This
, metrics
);
1317 static HRESULT WINAPI
dwritetrimmingsign_GetOverhangMetrics(IDWriteInlineObject
*iface
, DWRITE_OVERHANG_METRICS
*overhangs
)
1319 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1320 FIXME("(%p)->(%p): stub\n", This
, overhangs
);
1324 static HRESULT WINAPI
dwritetrimmingsign_GetBreakConditions(IDWriteInlineObject
*iface
, DWRITE_BREAK_CONDITION
*before
,
1325 DWRITE_BREAK_CONDITION
*after
)
1327 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1329 TRACE("(%p)->(%p %p)\n", This
, before
, after
);
1331 *before
= *after
= DWRITE_BREAK_CONDITION_NEUTRAL
;
1335 static const IDWriteInlineObjectVtbl dwritetrimmingsignvtbl
= {
1336 dwritetrimmingsign_QueryInterface
,
1337 dwritetrimmingsign_AddRef
,
1338 dwritetrimmingsign_Release
,
1339 dwritetrimmingsign_Draw
,
1340 dwritetrimmingsign_GetMetrics
,
1341 dwritetrimmingsign_GetOverhangMetrics
,
1342 dwritetrimmingsign_GetBreakConditions
1345 HRESULT
create_trimmingsign(IDWriteInlineObject
**sign
)
1347 struct dwrite_trimmingsign
*This
;
1351 This
= heap_alloc(sizeof(struct dwrite_trimmingsign
));
1352 if (!This
) return E_OUTOFMEMORY
;
1354 This
->IDWriteInlineObject_iface
.lpVtbl
= &dwritetrimmingsignvtbl
;
1357 *sign
= &This
->IDWriteInlineObject_iface
;
1362 static HRESULT WINAPI
dwritetextformat_QueryInterface(IDWriteTextFormat
*iface
, REFIID riid
, void **obj
)
1364 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1366 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1368 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1369 IsEqualIID(riid
, &IID_IDWriteTextFormat
))
1372 IDWriteTextFormat_AddRef(iface
);
1378 return E_NOINTERFACE
;
1381 static ULONG WINAPI
dwritetextformat_AddRef(IDWriteTextFormat
*iface
)
1383 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1384 ULONG ref
= InterlockedIncrement(&This
->ref
);
1385 TRACE("(%p)->(%d)\n", This
, ref
);
1389 static ULONG WINAPI
dwritetextformat_Release(IDWriteTextFormat
*iface
)
1391 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1392 ULONG ref
= InterlockedDecrement(&This
->ref
);
1394 TRACE("(%p)->(%d)\n", This
, ref
);
1398 release_format_data(&This
->format
);
1405 static HRESULT WINAPI
dwritetextformat_SetTextAlignment(IDWriteTextFormat
*iface
, DWRITE_TEXT_ALIGNMENT alignment
)
1407 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1408 TRACE("(%p)->(%d)\n", This
, alignment
);
1409 This
->format
.textalignment
= alignment
;
1413 static HRESULT WINAPI
dwritetextformat_SetParagraphAlignment(IDWriteTextFormat
*iface
, DWRITE_PARAGRAPH_ALIGNMENT alignment
)
1415 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1416 TRACE("(%p)->(%d)\n", This
, alignment
);
1417 This
->format
.paralign
= alignment
;
1421 static HRESULT WINAPI
dwritetextformat_SetWordWrapping(IDWriteTextFormat
*iface
, DWRITE_WORD_WRAPPING wrapping
)
1423 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1424 TRACE("(%p)->(%d)\n", This
, wrapping
);
1425 This
->format
.wrapping
= wrapping
;
1429 static HRESULT WINAPI
dwritetextformat_SetReadingDirection(IDWriteTextFormat
*iface
, DWRITE_READING_DIRECTION direction
)
1431 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1432 TRACE("(%p)->(%d)\n", This
, direction
);
1433 This
->format
.readingdir
= direction
;
1437 static HRESULT WINAPI
dwritetextformat_SetFlowDirection(IDWriteTextFormat
*iface
, DWRITE_FLOW_DIRECTION direction
)
1439 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1440 TRACE("(%p)->(%d)\n", This
, direction
);
1441 This
->format
.flow
= direction
;
1445 static HRESULT WINAPI
dwritetextformat_SetIncrementalTabStop(IDWriteTextFormat
*iface
, FLOAT tabstop
)
1447 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1448 FIXME("(%p)->(%f): stub\n", This
, tabstop
);
1452 static HRESULT WINAPI
dwritetextformat_SetTrimming(IDWriteTextFormat
*iface
, DWRITE_TRIMMING
const *trimming
,
1453 IDWriteInlineObject
*trimming_sign
)
1455 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1456 TRACE("(%p)->(%p %p)\n", This
, trimming
, trimming_sign
);
1458 This
->format
.trimming
= *trimming
;
1459 if (This
->format
.trimmingsign
)
1460 IDWriteInlineObject_Release(This
->format
.trimmingsign
);
1461 This
->format
.trimmingsign
= trimming_sign
;
1462 if (This
->format
.trimmingsign
)
1463 IDWriteInlineObject_AddRef(This
->format
.trimmingsign
);
1467 static HRESULT WINAPI
dwritetextformat_SetLineSpacing(IDWriteTextFormat
*iface
, DWRITE_LINE_SPACING_METHOD method
,
1468 FLOAT spacing
, FLOAT baseline
)
1470 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1471 TRACE("(%p)->(%d %f %f)\n", This
, method
, spacing
, baseline
);
1472 This
->format
.spacingmethod
= method
;
1473 This
->format
.spacing
= spacing
;
1474 This
->format
.baseline
= baseline
;
1478 static DWRITE_TEXT_ALIGNMENT WINAPI
dwritetextformat_GetTextAlignment(IDWriteTextFormat
*iface
)
1480 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1481 TRACE("(%p)\n", This
);
1482 return This
->format
.textalignment
;
1485 static DWRITE_PARAGRAPH_ALIGNMENT WINAPI
dwritetextformat_GetParagraphAlignment(IDWriteTextFormat
*iface
)
1487 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1488 TRACE("(%p)\n", This
);
1489 return This
->format
.paralign
;
1492 static DWRITE_WORD_WRAPPING WINAPI
dwritetextformat_GetWordWrapping(IDWriteTextFormat
*iface
)
1494 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1495 TRACE("(%p)\n", This
);
1496 return This
->format
.wrapping
;
1499 static DWRITE_READING_DIRECTION WINAPI
dwritetextformat_GetReadingDirection(IDWriteTextFormat
*iface
)
1501 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1502 TRACE("(%p)\n", This
);
1503 return This
->format
.readingdir
;
1506 static DWRITE_FLOW_DIRECTION WINAPI
dwritetextformat_GetFlowDirection(IDWriteTextFormat
*iface
)
1508 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1509 TRACE("(%p)\n", This
);
1510 return This
->format
.flow
;
1513 static FLOAT WINAPI
dwritetextformat_GetIncrementalTabStop(IDWriteTextFormat
*iface
)
1515 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1516 FIXME("(%p): stub\n", This
);
1520 static HRESULT WINAPI
dwritetextformat_GetTrimming(IDWriteTextFormat
*iface
, DWRITE_TRIMMING
*options
,
1521 IDWriteInlineObject
**trimming_sign
)
1523 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1524 TRACE("(%p)->(%p %p)\n", This
, options
, trimming_sign
);
1526 *options
= This
->format
.trimming
;
1527 if ((*trimming_sign
= This
->format
.trimmingsign
))
1528 IDWriteInlineObject_AddRef(*trimming_sign
);
1533 static HRESULT WINAPI
dwritetextformat_GetLineSpacing(IDWriteTextFormat
*iface
, DWRITE_LINE_SPACING_METHOD
*method
,
1534 FLOAT
*spacing
, FLOAT
*baseline
)
1536 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1537 TRACE("(%p)->(%p %p %p)\n", This
, method
, spacing
, baseline
);
1539 *method
= This
->format
.spacingmethod
;
1540 *spacing
= This
->format
.spacing
;
1541 *baseline
= This
->format
.baseline
;
1545 static HRESULT WINAPI
dwritetextformat_GetFontCollection(IDWriteTextFormat
*iface
, IDWriteFontCollection
**collection
)
1547 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1549 TRACE("(%p)->(%p)\n", This
, collection
);
1551 *collection
= This
->format
.collection
;
1552 IDWriteFontCollection_AddRef(*collection
);
1557 static UINT32 WINAPI
dwritetextformat_GetFontFamilyNameLength(IDWriteTextFormat
*iface
)
1559 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1560 TRACE("(%p)\n", This
);
1561 return This
->format
.family_len
;
1564 static HRESULT WINAPI
dwritetextformat_GetFontFamilyName(IDWriteTextFormat
*iface
, WCHAR
*name
, UINT32 size
)
1566 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1568 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
1570 if (size
<= This
->format
.family_len
) return E_NOT_SUFFICIENT_BUFFER
;
1571 strcpyW(name
, This
->format
.family_name
);
1575 static DWRITE_FONT_WEIGHT WINAPI
dwritetextformat_GetFontWeight(IDWriteTextFormat
*iface
)
1577 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1578 TRACE("(%p)\n", This
);
1579 return This
->format
.weight
;
1582 static DWRITE_FONT_STYLE WINAPI
dwritetextformat_GetFontStyle(IDWriteTextFormat
*iface
)
1584 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1585 TRACE("(%p)\n", This
);
1586 return This
->format
.style
;
1589 static DWRITE_FONT_STRETCH WINAPI
dwritetextformat_GetFontStretch(IDWriteTextFormat
*iface
)
1591 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1592 TRACE("(%p)\n", This
);
1593 return This
->format
.stretch
;
1596 static FLOAT WINAPI
dwritetextformat_GetFontSize(IDWriteTextFormat
*iface
)
1598 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1599 TRACE("(%p)\n", This
);
1600 return This
->format
.size
;
1603 static UINT32 WINAPI
dwritetextformat_GetLocaleNameLength(IDWriteTextFormat
*iface
)
1605 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1606 TRACE("(%p)\n", This
);
1607 return This
->format
.locale_len
;
1610 static HRESULT WINAPI
dwritetextformat_GetLocaleName(IDWriteTextFormat
*iface
, WCHAR
*name
, UINT32 size
)
1612 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1614 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
1616 if (size
<= This
->format
.locale_len
) return E_NOT_SUFFICIENT_BUFFER
;
1617 strcpyW(name
, This
->format
.locale
);
1621 static const IDWriteTextFormatVtbl dwritetextformatvtbl
= {
1622 dwritetextformat_QueryInterface
,
1623 dwritetextformat_AddRef
,
1624 dwritetextformat_Release
,
1625 dwritetextformat_SetTextAlignment
,
1626 dwritetextformat_SetParagraphAlignment
,
1627 dwritetextformat_SetWordWrapping
,
1628 dwritetextformat_SetReadingDirection
,
1629 dwritetextformat_SetFlowDirection
,
1630 dwritetextformat_SetIncrementalTabStop
,
1631 dwritetextformat_SetTrimming
,
1632 dwritetextformat_SetLineSpacing
,
1633 dwritetextformat_GetTextAlignment
,
1634 dwritetextformat_GetParagraphAlignment
,
1635 dwritetextformat_GetWordWrapping
,
1636 dwritetextformat_GetReadingDirection
,
1637 dwritetextformat_GetFlowDirection
,
1638 dwritetextformat_GetIncrementalTabStop
,
1639 dwritetextformat_GetTrimming
,
1640 dwritetextformat_GetLineSpacing
,
1641 dwritetextformat_GetFontCollection
,
1642 dwritetextformat_GetFontFamilyNameLength
,
1643 dwritetextformat_GetFontFamilyName
,
1644 dwritetextformat_GetFontWeight
,
1645 dwritetextformat_GetFontStyle
,
1646 dwritetextformat_GetFontStretch
,
1647 dwritetextformat_GetFontSize
,
1648 dwritetextformat_GetLocaleNameLength
,
1649 dwritetextformat_GetLocaleName
1652 HRESULT
create_textformat(const WCHAR
*family_name
, IDWriteFontCollection
*collection
, DWRITE_FONT_WEIGHT weight
, DWRITE_FONT_STYLE style
,
1653 DWRITE_FONT_STRETCH stretch
, FLOAT size
, const WCHAR
*locale
, IDWriteTextFormat
**format
)
1655 struct dwrite_textformat
*This
;
1659 This
= heap_alloc(sizeof(struct dwrite_textformat
));
1660 if (!This
) return E_OUTOFMEMORY
;
1662 This
->IDWriteTextFormat_iface
.lpVtbl
= &dwritetextformatvtbl
;
1664 This
->format
.family_name
= heap_strdupW(family_name
);
1665 This
->format
.family_len
= strlenW(family_name
);
1666 This
->format
.locale
= heap_strdupW(locale
);
1667 This
->format
.locale_len
= strlenW(locale
);
1668 This
->format
.weight
= weight
;
1669 This
->format
.style
= style
;
1670 This
->format
.size
= size
;
1671 This
->format
.stretch
= stretch
;
1672 This
->format
.textalignment
= DWRITE_TEXT_ALIGNMENT_LEADING
;
1673 This
->format
.paralign
= DWRITE_PARAGRAPH_ALIGNMENT_NEAR
;
1674 This
->format
.wrapping
= DWRITE_WORD_WRAPPING_WRAP
;
1675 This
->format
.readingdir
= DWRITE_READING_DIRECTION_LEFT_TO_RIGHT
;
1676 This
->format
.flow
= DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM
;
1677 This
->format
.spacingmethod
= DWRITE_LINE_SPACING_METHOD_DEFAULT
;
1678 This
->format
.spacing
= 0.0;
1679 This
->format
.baseline
= 0.0;
1680 This
->format
.trimming
.granularity
= DWRITE_TRIMMING_GRANULARITY_NONE
;
1681 This
->format
.trimming
.delimiter
= 0;
1682 This
->format
.trimming
.delimiterCount
= 0;
1683 This
->format
.trimmingsign
= NULL
;
1687 This
->format
.collection
= collection
;
1688 IDWriteFontCollection_AddRef(collection
);
1692 HRESULT hr
= get_system_fontcollection(&This
->format
.collection
);
1695 IDWriteTextFormat_Release(&This
->IDWriteTextFormat_iface
);
1700 *format
= &This
->IDWriteTextFormat_iface
;