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_STRETCH
,
65 LAYOUT_RANGE_ATTR_FONTSIZE
,
66 LAYOUT_RANGE_ATTR_EFFECT
,
67 LAYOUT_RANGE_ATTR_INLINE
,
68 LAYOUT_RANGE_ATTR_UNDERLINE
,
69 LAYOUT_RANGE_ATTR_STRIKETHROUGH
,
70 LAYOUT_RANGE_ATTR_FONTCOLL
73 struct layout_range_attr_value
{
74 DWRITE_TEXT_RANGE range
;
76 DWRITE_FONT_WEIGHT weight
;
77 DWRITE_FONT_STYLE style
;
78 DWRITE_FONT_STRETCH stretch
;
80 IDWriteInlineObject
*object
;
84 IDWriteFontCollection
*collection
;
90 DWRITE_TEXT_RANGE range
;
91 DWRITE_FONT_WEIGHT weight
;
92 DWRITE_FONT_STYLE style
;
94 DWRITE_FONT_STRETCH stretch
;
95 IDWriteInlineObject
*object
;
99 IDWriteFontCollection
*collection
;
102 struct dwrite_textlayout
{
103 IDWriteTextLayout IDWriteTextLayout_iface
;
108 struct dwrite_textformat_data format
;
114 struct dwrite_textformat
{
115 IDWriteTextFormat IDWriteTextFormat_iface
;
117 struct dwrite_textformat_data format
;
120 struct dwrite_trimmingsign
{
121 IDWriteInlineObject IDWriteInlineObject_iface
;
125 struct dwrite_typography
{
126 IDWriteTypography IDWriteTypography_iface
;
129 DWRITE_FONT_FEATURE
*features
;
134 static const IDWriteTextFormatVtbl dwritetextformatvtbl
;
136 static void release_format_data(struct dwrite_textformat_data
*data
)
138 if (data
->collection
) IDWriteFontCollection_Release(data
->collection
);
139 if (data
->trimmingsign
) IDWriteInlineObject_Release(data
->trimmingsign
);
140 heap_free(data
->family_name
);
141 heap_free(data
->locale
);
144 static inline struct dwrite_textlayout
*impl_from_IDWriteTextLayout(IDWriteTextLayout
*iface
)
146 return CONTAINING_RECORD(iface
, struct dwrite_textlayout
, IDWriteTextLayout_iface
);
149 static inline struct dwrite_textformat
*impl_from_IDWriteTextFormat(IDWriteTextFormat
*iface
)
151 return CONTAINING_RECORD(iface
, struct dwrite_textformat
, IDWriteTextFormat_iface
);
154 static inline struct dwrite_textformat
*unsafe_impl_from_IDWriteTextFormat(IDWriteTextFormat
*iface
)
156 return iface
->lpVtbl
== &dwritetextformatvtbl
? impl_from_IDWriteTextFormat(iface
) : NULL
;
159 static inline struct dwrite_trimmingsign
*impl_from_IDWriteInlineObject(IDWriteInlineObject
*iface
)
161 return CONTAINING_RECORD(iface
, struct dwrite_trimmingsign
, IDWriteInlineObject_iface
);
164 static inline struct dwrite_typography
*impl_from_IDWriteTypography(IDWriteTypography
*iface
)
166 return CONTAINING_RECORD(iface
, struct dwrite_typography
, IDWriteTypography_iface
);
169 /* To be used in IDWriteTextLayout methods to validate and fix passed range */
170 static inline BOOL
validate_text_range(struct dwrite_textlayout
*layout
, DWRITE_TEXT_RANGE
*r
)
172 if (r
->startPosition
>= layout
->len
)
175 if (r
->startPosition
+ r
->length
> layout
->len
)
176 r
->length
= layout
->len
- r
->startPosition
;
181 static BOOL
is_same_layout_attrvalue(struct layout_range
const *range
, enum layout_range_attr_kind attr
, struct layout_range_attr_value
*value
)
184 case LAYOUT_RANGE_ATTR_WEIGHT
:
185 return range
->weight
== value
->u
.weight
;
186 case LAYOUT_RANGE_ATTR_STYLE
:
187 return range
->style
== value
->u
.style
;
188 case LAYOUT_RANGE_ATTR_STRETCH
:
189 return range
->stretch
== value
->u
.stretch
;
190 case LAYOUT_RANGE_ATTR_FONTSIZE
:
191 return range
->fontsize
== value
->u
.fontsize
;
192 case LAYOUT_RANGE_ATTR_INLINE
:
193 return range
->object
== value
->u
.object
;
194 case LAYOUT_RANGE_ATTR_EFFECT
:
195 return range
->effect
== value
->u
.effect
;
196 case LAYOUT_RANGE_ATTR_UNDERLINE
:
197 return range
->underline
== value
->u
.underline
;
198 case LAYOUT_RANGE_ATTR_STRIKETHROUGH
:
199 return range
->strikethrough
== value
->u
.strikethrough
;
200 case LAYOUT_RANGE_ATTR_FONTCOLL
:
201 return range
->collection
== value
->u
.collection
;
209 static inline BOOL
is_same_layout_attributes(struct layout_range
const *left
, struct layout_range
const *right
)
211 return left
->weight
== right
->weight
&&
212 left
->style
== right
->style
&&
213 left
->stretch
== right
->stretch
&&
214 left
->fontsize
== right
->fontsize
&&
215 left
->object
== right
->object
&&
216 left
->effect
== right
->effect
&&
217 left
->underline
== right
->underline
&&
218 left
->strikethrough
== right
->strikethrough
&&
219 left
->collection
== right
->collection
;
222 static inline BOOL
is_same_text_range(const DWRITE_TEXT_RANGE
*left
, const DWRITE_TEXT_RANGE
*right
)
224 return left
->startPosition
== right
->startPosition
&& left
->length
== right
->length
;
227 /* Allocates range and inits it with default values from text format. */
228 static struct layout_range
*alloc_layout_range(struct dwrite_textlayout
*layout
, const DWRITE_TEXT_RANGE
*r
)
230 struct layout_range
*range
;
232 range
= heap_alloc(sizeof(*range
));
233 if (!range
) return NULL
;
236 range
->weight
= layout
->format
.weight
;
237 range
->style
= layout
->format
.style
;
238 range
->stretch
= layout
->format
.stretch
;
239 range
->fontsize
= layout
->format
.fontsize
;
240 range
->object
= NULL
;
241 range
->effect
= NULL
;
242 range
->underline
= FALSE
;
243 range
->strikethrough
= FALSE
;
244 range
->collection
= layout
->format
.collection
;
245 if (range
->collection
)
246 IDWriteFontCollection_AddRef(range
->collection
);
251 static struct layout_range
*alloc_layout_range_from(struct layout_range
*from
, const DWRITE_TEXT_RANGE
*r
)
253 struct layout_range
*range
;
255 range
= heap_alloc(sizeof(*range
));
256 if (!range
) return NULL
;
261 /* update refcounts */
263 IDWriteInlineObject_AddRef(range
->object
);
265 IUnknown_AddRef(range
->effect
);
266 if (range
->collection
)
267 IDWriteFontCollection_AddRef(range
->collection
);
272 static void free_layout_range(struct layout_range
*range
)
277 IDWriteInlineObject_Release(range
->object
);
279 IUnknown_Release(range
->effect
);
280 if (range
->collection
)
281 IDWriteFontCollection_Release(range
->collection
);
285 static void free_layout_ranges_list(struct dwrite_textlayout
*layout
)
287 struct layout_range
*cur
, *cur2
;
288 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &layout
->ranges
, struct layout_range
, entry
) {
289 list_remove(&cur
->entry
);
290 free_layout_range(cur
);
294 static struct layout_range
*find_outer_range(struct dwrite_textlayout
*layout
, const DWRITE_TEXT_RANGE
*range
)
296 struct layout_range
*cur
;
298 LIST_FOR_EACH_ENTRY(cur
, &layout
->ranges
, struct layout_range
, entry
) {
300 if (cur
->range
.startPosition
> range
->startPosition
)
303 if ((cur
->range
.startPosition
+ cur
->range
.length
< range
->startPosition
+ range
->length
) &&
304 (range
->startPosition
< cur
->range
.startPosition
+ cur
->range
.length
))
306 if (cur
->range
.startPosition
+ cur
->range
.length
>= range
->startPosition
+ range
->length
)
313 static struct layout_range
*get_layout_range_by_pos(struct dwrite_textlayout
*layout
, UINT32 pos
)
315 struct layout_range
*cur
;
317 LIST_FOR_EACH_ENTRY(cur
, &layout
->ranges
, struct layout_range
, entry
) {
318 DWRITE_TEXT_RANGE
*r
= &cur
->range
;
319 if (r
->startPosition
<= pos
&& pos
< r
->startPosition
+ r
->length
)
326 static BOOL
set_layout_range_attrval(struct layout_range
*dest
, enum layout_range_attr_kind attr
, struct layout_range_attr_value
*value
)
328 BOOL changed
= FALSE
;
331 case LAYOUT_RANGE_ATTR_WEIGHT
:
332 changed
= dest
->weight
!= value
->u
.weight
;
333 dest
->weight
= value
->u
.weight
;
335 case LAYOUT_RANGE_ATTR_STYLE
:
336 changed
= dest
->style
!= value
->u
.style
;
337 dest
->style
= value
->u
.style
;
339 case LAYOUT_RANGE_ATTR_STRETCH
:
340 changed
= dest
->stretch
!= value
->u
.stretch
;
341 dest
->stretch
= value
->u
.stretch
;
343 case LAYOUT_RANGE_ATTR_FONTSIZE
:
344 changed
= dest
->fontsize
!= value
->u
.fontsize
;
345 dest
->fontsize
= value
->u
.fontsize
;
347 case LAYOUT_RANGE_ATTR_INLINE
:
348 changed
= dest
->object
!= value
->u
.object
;
349 if (changed
&& dest
->object
)
350 IDWriteInlineObject_Release(dest
->object
);
351 dest
->object
= value
->u
.object
;
353 IDWriteInlineObject_AddRef(dest
->object
);
355 case LAYOUT_RANGE_ATTR_EFFECT
:
356 changed
= dest
->effect
!= value
->u
.effect
;
357 if (changed
&& dest
->effect
)
358 IUnknown_Release(dest
->effect
);
359 dest
->effect
= value
->u
.effect
;
361 IUnknown_AddRef(dest
->effect
);
363 case LAYOUT_RANGE_ATTR_UNDERLINE
:
364 changed
= dest
->underline
!= value
->u
.underline
;
365 dest
->underline
= value
->u
.underline
;
367 case LAYOUT_RANGE_ATTR_STRIKETHROUGH
:
368 changed
= dest
->strikethrough
!= value
->u
.strikethrough
;
369 dest
->strikethrough
= value
->u
.strikethrough
;
371 case LAYOUT_RANGE_ATTR_FONTCOLL
:
372 changed
= dest
->collection
!= value
->u
.collection
;
373 if (changed
&& dest
->collection
)
374 IDWriteFontCollection_Release(dest
->collection
);
375 dest
->collection
= value
->u
.collection
;
376 if (dest
->collection
)
377 IDWriteFontCollection_AddRef(dest
->collection
);
386 static inline BOOL
is_in_layout_range(const DWRITE_TEXT_RANGE
*outer
, const DWRITE_TEXT_RANGE
*inner
)
388 return (inner
->startPosition
>= outer
->startPosition
) &&
389 (inner
->startPosition
+ inner
->length
<= outer
->startPosition
+ outer
->length
);
392 static inline HRESULT
return_range(const struct layout_range
*range
, DWRITE_TEXT_RANGE
*r
)
394 if (r
) *r
= range
->range
;
398 /* Set attribute value for given range, does all needed splitting/merging of existing ranges. */
399 static HRESULT
set_layout_range_attr(struct dwrite_textlayout
*layout
, enum layout_range_attr_kind attr
, struct layout_range_attr_value
*value
)
401 struct layout_range
*outer
, *right
, *left
, *cur
;
402 struct list
*ranges
= &layout
->ranges
;
403 BOOL changed
= FALSE
;
406 /* If new range is completely within existing range, split existing range in two */
407 if ((outer
= find_outer_range(layout
, &value
->range
))) {
409 /* no need to add same range */
410 if (is_same_layout_attrvalue(outer
, attr
, value
))
413 /* for matching range bounds just replace data */
414 if (is_same_text_range(&outer
->range
, &value
->range
)) {
415 changed
= set_layout_range_attrval(outer
, attr
, value
);
419 /* add new range to the left */
420 if (value
->range
.startPosition
== outer
->range
.startPosition
) {
421 left
= alloc_layout_range_from(outer
, &value
->range
);
422 if (!left
) return E_OUTOFMEMORY
;
424 changed
= set_layout_range_attrval(left
, attr
, value
);
425 list_add_before(&outer
->entry
, &left
->entry
);
426 outer
->range
.startPosition
+= value
->range
.length
;
427 outer
->range
.length
-= value
->range
.length
;
431 /* add new range to the right */
432 if (value
->range
.startPosition
+ value
->range
.length
== outer
->range
.startPosition
+ outer
->range
.length
) {
433 right
= alloc_layout_range_from(outer
, &value
->range
);
434 if (!right
) return E_OUTOFMEMORY
;
436 changed
= set_layout_range_attrval(right
, attr
, value
);
437 list_add_after(&outer
->entry
, &right
->entry
);
438 outer
->range
.length
-= value
->range
.length
;
442 r
.startPosition
= value
->range
.startPosition
+ value
->range
.length
;
443 r
.length
= outer
->range
.length
+ outer
->range
.startPosition
- r
.startPosition
;
446 right
= alloc_layout_range_from(outer
, &r
);
447 /* new range in the middle */
448 cur
= alloc_layout_range_from(outer
, &value
->range
);
449 if (!right
|| !cur
) {
450 free_layout_range(right
);
451 free_layout_range(cur
);
452 return E_OUTOFMEMORY
;
455 /* reuse container range as a left part */
456 outer
->range
.length
= value
->range
.startPosition
- outer
->range
.startPosition
;
459 set_layout_range_attrval(cur
, attr
, value
);
461 list_add_after(&outer
->entry
, &cur
->entry
);
462 list_add_after(&cur
->entry
, &right
->entry
);
467 /* Now it's only possible that given range contains some existing ranges, fully or partially.
468 Update all of them. */
469 left
= get_layout_range_by_pos(layout
, value
->range
.startPosition
);
470 if (left
->range
.startPosition
== value
->range
.startPosition
)
471 changed
= set_layout_range_attrval(left
, attr
, value
);
472 else /* need to split */ {
473 r
.startPosition
= value
->range
.startPosition
;
474 r
.length
= left
->range
.length
- value
->range
.startPosition
+ left
->range
.startPosition
;
475 left
->range
.length
-= r
.length
;
476 cur
= alloc_layout_range_from(left
, &r
);
477 changed
= set_layout_range_attrval(cur
, attr
, value
);
478 list_add_after(&left
->entry
, &cur
->entry
);
480 cur
= LIST_ENTRY(list_next(ranges
, &left
->entry
), struct layout_range
, entry
);
482 /* for all existing ranges covered by new one update value */
483 while (is_in_layout_range(&value
->range
, &cur
->range
)) {
484 changed
= set_layout_range_attrval(cur
, attr
, value
);
485 cur
= LIST_ENTRY(list_next(ranges
, &cur
->entry
), struct layout_range
, entry
);
488 /* it's possible rightmost range intersects */
489 if (cur
&& (cur
->range
.startPosition
< value
->range
.startPosition
+ value
->range
.length
)) {
490 r
.startPosition
= cur
->range
.startPosition
;
491 r
.length
= value
->range
.startPosition
+ value
->range
.length
- cur
->range
.startPosition
;
492 left
= alloc_layout_range_from(cur
, &r
);
493 changed
= set_layout_range_attrval(left
, attr
, value
);
494 cur
->range
.startPosition
+= left
->range
.length
;
495 cur
->range
.length
-= left
->range
.length
;
496 list_add_before(&cur
->entry
, &left
->entry
);
501 struct list
*next
, *i
;
503 i
= list_head(ranges
);
504 while ((next
= list_next(ranges
, i
))) {
505 struct layout_range
*next_range
= LIST_ENTRY(next
, struct layout_range
, entry
);
507 cur
= LIST_ENTRY(i
, struct layout_range
, entry
);
508 if (is_same_layout_attributes(cur
, next_range
)) {
509 /* remove similar range */
510 cur
->range
.length
+= next_range
->range
.length
;
512 free_layout_range(next_range
);
515 i
= list_next(ranges
, i
);
522 static HRESULT WINAPI
dwritetextlayout_QueryInterface(IDWriteTextLayout
*iface
, REFIID riid
, void **obj
)
524 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
526 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
528 if (IsEqualIID(riid
, &IID_IUnknown
) ||
529 IsEqualIID(riid
, &IID_IDWriteTextFormat
) ||
530 IsEqualIID(riid
, &IID_IDWriteTextLayout
))
533 IDWriteTextLayout_AddRef(iface
);
539 return E_NOINTERFACE
;
542 static ULONG WINAPI
dwritetextlayout_AddRef(IDWriteTextLayout
*iface
)
544 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
545 ULONG ref
= InterlockedIncrement(&This
->ref
);
546 TRACE("(%p)->(%d)\n", This
, ref
);
550 static ULONG WINAPI
dwritetextlayout_Release(IDWriteTextLayout
*iface
)
552 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
553 ULONG ref
= InterlockedDecrement(&This
->ref
);
555 TRACE("(%p)->(%d)\n", This
, ref
);
558 free_layout_ranges_list(This
);
559 release_format_data(&This
->format
);
560 heap_free(This
->str
);
567 static HRESULT WINAPI
dwritetextlayout_SetTextAlignment(IDWriteTextLayout
*iface
, DWRITE_TEXT_ALIGNMENT alignment
)
569 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
570 FIXME("(%p)->(%d): stub\n", This
, alignment
);
574 static HRESULT WINAPI
dwritetextlayout_SetParagraphAlignment(IDWriteTextLayout
*iface
, DWRITE_PARAGRAPH_ALIGNMENT alignment
)
576 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
577 FIXME("(%p)->(%d): stub\n", This
, alignment
);
581 static HRESULT WINAPI
dwritetextlayout_SetWordWrapping(IDWriteTextLayout
*iface
, DWRITE_WORD_WRAPPING wrapping
)
583 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
584 FIXME("(%p)->(%d): stub\n", This
, wrapping
);
588 static HRESULT WINAPI
dwritetextlayout_SetReadingDirection(IDWriteTextLayout
*iface
, DWRITE_READING_DIRECTION direction
)
590 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
591 FIXME("(%p)->(%d): stub\n", This
, direction
);
595 static HRESULT WINAPI
dwritetextlayout_SetFlowDirection(IDWriteTextLayout
*iface
, DWRITE_FLOW_DIRECTION direction
)
597 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
598 FIXME("(%p)->(%d): stub\n", This
, direction
);
602 static HRESULT WINAPI
dwritetextlayout_SetIncrementalTabStop(IDWriteTextLayout
*iface
, FLOAT tabstop
)
604 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
605 FIXME("(%p)->(%f): stub\n", This
, tabstop
);
609 static HRESULT WINAPI
dwritetextlayout_SetTrimming(IDWriteTextLayout
*iface
, DWRITE_TRIMMING
const *trimming
,
610 IDWriteInlineObject
*trimming_sign
)
612 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
613 FIXME("(%p)->(%p %p): stub\n", This
, trimming
, trimming_sign
);
617 static HRESULT WINAPI
dwritetextlayout_SetLineSpacing(IDWriteTextLayout
*iface
, DWRITE_LINE_SPACING_METHOD spacing
,
618 FLOAT line_spacing
, FLOAT baseline
)
620 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
621 FIXME("(%p)->(%d %f %f): stub\n", This
, spacing
, line_spacing
, baseline
);
625 static DWRITE_TEXT_ALIGNMENT WINAPI
dwritetextlayout_GetTextAlignment(IDWriteTextLayout
*iface
)
627 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
628 TRACE("(%p)\n", This
);
629 return This
->format
.textalignment
;
632 static DWRITE_PARAGRAPH_ALIGNMENT WINAPI
dwritetextlayout_GetParagraphAlignment(IDWriteTextLayout
*iface
)
634 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
635 TRACE("(%p)\n", This
);
636 return This
->format
.paralign
;
639 static DWRITE_WORD_WRAPPING WINAPI
dwritetextlayout_GetWordWrapping(IDWriteTextLayout
*iface
)
641 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
642 FIXME("(%p): stub\n", This
);
643 return This
->format
.wrapping
;
646 static DWRITE_READING_DIRECTION WINAPI
dwritetextlayout_GetReadingDirection(IDWriteTextLayout
*iface
)
648 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
649 TRACE("(%p)\n", This
);
650 return This
->format
.readingdir
;
653 static DWRITE_FLOW_DIRECTION WINAPI
dwritetextlayout_GetFlowDirection(IDWriteTextLayout
*iface
)
655 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
656 TRACE("(%p)\n", This
);
657 return This
->format
.flow
;
660 static FLOAT WINAPI
dwritetextlayout_GetIncrementalTabStop(IDWriteTextLayout
*iface
)
662 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
663 FIXME("(%p): stub\n", This
);
667 static HRESULT WINAPI
dwritetextlayout_GetTrimming(IDWriteTextLayout
*iface
, DWRITE_TRIMMING
*options
,
668 IDWriteInlineObject
**trimming_sign
)
670 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
672 TRACE("(%p)->(%p %p)\n", This
, options
, trimming_sign
);
674 *options
= This
->format
.trimming
;
675 *trimming_sign
= This
->format
.trimmingsign
;
677 IDWriteInlineObject_AddRef(*trimming_sign
);
681 static HRESULT WINAPI
dwritetextlayout_GetLineSpacing(IDWriteTextLayout
*iface
, DWRITE_LINE_SPACING_METHOD
*method
,
682 FLOAT
*spacing
, FLOAT
*baseline
)
684 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
686 TRACE("(%p)->(%p %p %p)\n", This
, method
, spacing
, baseline
);
688 *method
= This
->format
.spacingmethod
;
689 *spacing
= This
->format
.spacing
;
690 *baseline
= This
->format
.baseline
;
694 static HRESULT WINAPI
dwritetextlayout_GetFontCollection(IDWriteTextLayout
*iface
, IDWriteFontCollection
**collection
)
696 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
698 TRACE("(%p)->(%p)\n", This
, collection
);
700 *collection
= This
->format
.collection
;
702 IDWriteFontCollection_AddRef(*collection
);
706 static UINT32 WINAPI
dwritetextlayout_GetFontFamilyNameLength(IDWriteTextLayout
*iface
)
708 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
709 TRACE("(%p)\n", This
);
710 return This
->format
.family_len
;
713 static HRESULT WINAPI
dwritetextlayout_GetFontFamilyName(IDWriteTextLayout
*iface
, WCHAR
*name
, UINT32 size
)
715 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
717 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
719 if (size
<= This
->format
.family_len
) return E_NOT_SUFFICIENT_BUFFER
;
720 strcpyW(name
, This
->format
.family_name
);
724 static DWRITE_FONT_WEIGHT WINAPI
dwritetextlayout_GetFontWeight(IDWriteTextLayout
*iface
)
726 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
727 TRACE("(%p)\n", This
);
728 return This
->format
.weight
;
731 static DWRITE_FONT_STYLE WINAPI
dwritetextlayout_GetFontStyle(IDWriteTextLayout
*iface
)
733 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
734 TRACE("(%p)\n", This
);
735 return This
->format
.style
;
738 static DWRITE_FONT_STRETCH WINAPI
dwritetextlayout_GetFontStretch(IDWriteTextLayout
*iface
)
740 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
741 TRACE("(%p)\n", This
);
742 return This
->format
.stretch
;
745 static FLOAT WINAPI
dwritetextlayout_GetFontSize(IDWriteTextLayout
*iface
)
747 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
748 TRACE("(%p)\n", This
);
749 return This
->format
.fontsize
;
752 static UINT32 WINAPI
dwritetextlayout_GetLocaleNameLength(IDWriteTextLayout
*iface
)
754 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
755 TRACE("(%p)\n", This
);
756 return This
->format
.locale_len
;
759 static HRESULT WINAPI
dwritetextlayout_GetLocaleName(IDWriteTextLayout
*iface
, WCHAR
*name
, UINT32 size
)
761 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
763 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
765 if (size
<= This
->format
.locale_len
) return E_NOT_SUFFICIENT_BUFFER
;
766 strcpyW(name
, This
->format
.locale
);
770 static HRESULT WINAPI
dwritetextlayout_SetMaxWidth(IDWriteTextLayout
*iface
, FLOAT maxWidth
)
772 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
773 TRACE("(%p)->(%.1f)\n", This
, maxWidth
);
774 This
->maxwidth
= maxWidth
;
778 static HRESULT WINAPI
dwritetextlayout_SetMaxHeight(IDWriteTextLayout
*iface
, FLOAT maxHeight
)
780 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
781 TRACE("(%p)->(%.1f)\n", This
, maxHeight
);
782 This
->maxheight
= maxHeight
;
786 static HRESULT WINAPI
dwritetextlayout_SetFontCollection(IDWriteTextLayout
*iface
, IDWriteFontCollection
* collection
, DWRITE_TEXT_RANGE range
)
788 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
789 struct layout_range_attr_value value
;
791 TRACE("(%p)->(%p %s)\n", This
, collection
, debugstr_range(&range
));
793 if (!validate_text_range(This
, &range
))
797 value
.u
.collection
= collection
;
798 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_FONTCOLL
, &value
);
801 static HRESULT WINAPI
dwritetextlayout_SetFontFamilyName(IDWriteTextLayout
*iface
, WCHAR
const *name
, DWRITE_TEXT_RANGE range
)
803 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
804 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(name
), debugstr_range(&range
));
808 static HRESULT WINAPI
dwritetextlayout_SetFontWeight(IDWriteTextLayout
*iface
, DWRITE_FONT_WEIGHT weight
, DWRITE_TEXT_RANGE range
)
810 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
811 struct layout_range_attr_value value
;
813 TRACE("(%p)->(%d %s)\n", This
, weight
, debugstr_range(&range
));
815 if (!validate_text_range(This
, &range
))
819 value
.u
.weight
= weight
;
820 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_WEIGHT
, &value
);
823 static HRESULT WINAPI
dwritetextlayout_SetFontStyle(IDWriteTextLayout
*iface
, DWRITE_FONT_STYLE style
, DWRITE_TEXT_RANGE range
)
825 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
826 struct layout_range_attr_value value
;
828 TRACE("(%p)->(%d %s)\n", This
, style
, debugstr_range(&range
));
830 if (!validate_text_range(This
, &range
))
834 value
.u
.style
= style
;
835 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_STYLE
, &value
);
838 static HRESULT WINAPI
dwritetextlayout_SetFontStretch(IDWriteTextLayout
*iface
, DWRITE_FONT_STRETCH stretch
, DWRITE_TEXT_RANGE range
)
840 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
841 struct layout_range_attr_value value
;
843 TRACE("(%p)->(%d %s)\n", This
, stretch
, debugstr_range(&range
));
845 if (!validate_text_range(This
, &range
))
849 value
.u
.stretch
= stretch
;
850 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_STRETCH
, &value
);
853 static HRESULT WINAPI
dwritetextlayout_SetFontSize(IDWriteTextLayout
*iface
, FLOAT size
, DWRITE_TEXT_RANGE range
)
855 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
856 struct layout_range_attr_value value
;
858 TRACE("(%p)->(%.2f %s)\n", This
, size
, debugstr_range(&range
));
860 if (!validate_text_range(This
, &range
))
864 value
.u
.fontsize
= size
;
865 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_FONTSIZE
, &value
);
868 static HRESULT WINAPI
dwritetextlayout_SetUnderline(IDWriteTextLayout
*iface
, BOOL underline
, DWRITE_TEXT_RANGE range
)
870 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
871 struct layout_range_attr_value value
;
873 TRACE("(%p)->(%d %s)\n", This
, underline
, debugstr_range(&range
));
875 if (!validate_text_range(This
, &range
))
879 value
.u
.underline
= underline
;
880 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_UNDERLINE
, &value
);
883 static HRESULT WINAPI
dwritetextlayout_SetStrikethrough(IDWriteTextLayout
*iface
, BOOL strikethrough
, DWRITE_TEXT_RANGE range
)
885 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
886 struct layout_range_attr_value value
;
888 TRACE("(%p)->(%d %s)\n", This
, strikethrough
, debugstr_range(&range
));
890 if (!validate_text_range(This
, &range
))
894 value
.u
.underline
= strikethrough
;
895 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_STRIKETHROUGH
, &value
);
898 static HRESULT WINAPI
dwritetextlayout_SetDrawingEffect(IDWriteTextLayout
*iface
, IUnknown
* effect
, DWRITE_TEXT_RANGE range
)
900 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
901 struct layout_range_attr_value value
;
903 TRACE("(%p)->(%p %s)\n", This
, effect
, debugstr_range(&range
));
905 if (!validate_text_range(This
, &range
))
909 value
.u
.effect
= effect
;
910 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_EFFECT
, &value
);
913 static HRESULT WINAPI
dwritetextlayout_SetInlineObject(IDWriteTextLayout
*iface
, IDWriteInlineObject
*object
, DWRITE_TEXT_RANGE r
)
915 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
916 struct layout_range_attr_value attr
;
918 TRACE("(%p)->(%p %s)\n", This
, object
, debugstr_range(&r
));
920 if (!validate_text_range(This
, &r
))
924 attr
.u
.object
= object
;
926 return set_layout_range_attr(This
, LAYOUT_RANGE_ATTR_INLINE
, &attr
);
929 static HRESULT WINAPI
dwritetextlayout_SetTypography(IDWriteTextLayout
*iface
, IDWriteTypography
* typography
, DWRITE_TEXT_RANGE range
)
931 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
932 FIXME("(%p)->(%p %s): stub\n", This
, typography
, debugstr_range(&range
));
936 static HRESULT WINAPI
dwritetextlayout_SetLocaleName(IDWriteTextLayout
*iface
, WCHAR
const* locale
, DWRITE_TEXT_RANGE range
)
938 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
939 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(locale
), debugstr_range(&range
));
943 static FLOAT WINAPI
dwritetextlayout_GetMaxWidth(IDWriteTextLayout
*iface
)
945 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
946 TRACE("(%p)\n", This
);
947 return This
->maxwidth
;
950 static FLOAT WINAPI
dwritetextlayout_GetMaxHeight(IDWriteTextLayout
*iface
)
952 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
953 TRACE("(%p)\n", This
);
954 return This
->maxheight
;
957 static HRESULT WINAPI
dwritetextlayout_layout_GetFontCollection(IDWriteTextLayout
*iface
, UINT32 position
,
958 IDWriteFontCollection
** collection
, DWRITE_TEXT_RANGE
*r
)
960 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
961 struct layout_range
*range
;
963 TRACE("(%p)->(%u %p %p)\n", This
, position
, collection
, r
);
965 range
= get_layout_range_by_pos(This
, position
);
966 *collection
= range
? range
->collection
: NULL
;
968 IDWriteFontCollection_AddRef(*collection
);
970 return return_range(range
, r
);
973 static HRESULT WINAPI
dwritetextlayout_layout_GetFontFamilyNameLength(IDWriteTextLayout
*iface
,
974 UINT32 pos
, UINT32
* len
, DWRITE_TEXT_RANGE
*range
)
976 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
977 FIXME("(%p)->(%d %p %p): stub\n", This
, pos
, len
, range
);
981 static HRESULT WINAPI
dwritetextlayout_layout_GetFontFamilyName(IDWriteTextLayout
*iface
,
982 UINT32 position
, WCHAR
* name
, UINT32 name_size
, DWRITE_TEXT_RANGE
*range
)
984 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
985 FIXME("(%p)->(%u %p %u %p): stub\n", This
, position
, name
, name_size
, range
);
989 static HRESULT WINAPI
dwritetextlayout_layout_GetFontWeight(IDWriteTextLayout
*iface
,
990 UINT32 position
, DWRITE_FONT_WEIGHT
*weight
, DWRITE_TEXT_RANGE
*r
)
992 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
993 struct layout_range
*range
;
995 TRACE("(%p)->(%u %p %p)\n", This
, position
, weight
, r
);
997 if (position
>= This
->len
)
1000 range
= get_layout_range_by_pos(This
, position
);
1001 *weight
= range
->weight
;
1003 return return_range(range
, r
);
1006 static HRESULT WINAPI
dwritetextlayout_layout_GetFontStyle(IDWriteTextLayout
*iface
,
1007 UINT32 position
, DWRITE_FONT_STYLE
*style
, DWRITE_TEXT_RANGE
*r
)
1009 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1010 struct layout_range
*range
;
1012 TRACE("(%p)->(%u %p %p)\n", This
, position
, style
, r
);
1014 if (position
>= This
->len
)
1017 range
= get_layout_range_by_pos(This
, position
);
1018 *style
= range
->style
;
1020 return return_range(range
, r
);
1023 static HRESULT WINAPI
dwritetextlayout_layout_GetFontStretch(IDWriteTextLayout
*iface
,
1024 UINT32 position
, DWRITE_FONT_STRETCH
*stretch
, DWRITE_TEXT_RANGE
*r
)
1026 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1027 struct layout_range
*range
;
1029 TRACE("(%p)->(%u %p %p)\n", This
, position
, stretch
, r
);
1031 if (position
>= This
->len
)
1034 range
= get_layout_range_by_pos(This
, position
);
1035 *stretch
= range
->stretch
;
1037 return return_range(range
, r
);
1040 static HRESULT WINAPI
dwritetextlayout_layout_GetFontSize(IDWriteTextLayout
*iface
,
1041 UINT32 position
, FLOAT
*size
, DWRITE_TEXT_RANGE
*r
)
1043 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1044 struct layout_range
*range
;
1046 TRACE("(%p)->(%u %p %p)\n", This
, position
, size
, r
);
1048 if (position
>= This
->len
)
1051 range
= get_layout_range_by_pos(This
, position
);
1052 *size
= range
->fontsize
;
1054 return return_range(range
, r
);
1057 static HRESULT WINAPI
dwritetextlayout_GetUnderline(IDWriteTextLayout
*iface
,
1058 UINT32 position
, BOOL
*underline
, DWRITE_TEXT_RANGE
*r
)
1060 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1061 struct layout_range
*range
;
1063 TRACE("(%p)->(%u %p %p)\n", This
, position
, underline
, r
);
1065 if (position
>= This
->len
)
1068 range
= get_layout_range_by_pos(This
, position
);
1069 *underline
= range
->underline
;
1071 return return_range(range
, r
);
1074 static HRESULT WINAPI
dwritetextlayout_GetStrikethrough(IDWriteTextLayout
*iface
,
1075 UINT32 position
, BOOL
*strikethrough
, DWRITE_TEXT_RANGE
*r
)
1077 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1078 struct layout_range
*range
;
1080 TRACE("(%p)->(%u %p %p)\n", This
, position
, strikethrough
, r
);
1082 if (position
>= This
->len
)
1085 range
= get_layout_range_by_pos(This
, position
);
1086 *strikethrough
= range
->strikethrough
;
1088 return return_range(range
, r
);
1091 static HRESULT WINAPI
dwritetextlayout_GetDrawingEffect(IDWriteTextLayout
*iface
,
1092 UINT32 position
, IUnknown
**effect
, DWRITE_TEXT_RANGE
*r
)
1094 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1095 struct layout_range
*range
;
1097 TRACE("(%p)->(%u %p %p)\n", This
, position
, effect
, r
);
1099 if (position
>= This
->len
)
1102 range
= get_layout_range_by_pos(This
, position
);
1103 *effect
= range
->effect
;
1105 IUnknown_AddRef(*effect
);
1107 return return_range(range
, r
);
1110 static HRESULT WINAPI
dwritetextlayout_GetInlineObject(IDWriteTextLayout
*iface
,
1111 UINT32 position
, IDWriteInlineObject
**object
, DWRITE_TEXT_RANGE
*r
)
1113 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1114 struct layout_range
*range
;
1116 TRACE("(%p)->(%u %p %p)\n", This
, position
, object
, r
);
1118 range
= get_layout_range_by_pos(This
, position
);
1119 *object
= range
? range
->object
: NULL
;
1121 IDWriteInlineObject_AddRef(*object
);
1123 return return_range(range
, r
);
1126 static HRESULT WINAPI
dwritetextlayout_GetTypography(IDWriteTextLayout
*iface
,
1127 UINT32 position
, IDWriteTypography
** typography
, DWRITE_TEXT_RANGE
*range
)
1129 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1130 FIXME("(%p)->(%u %p %p): stub\n", This
, position
, typography
, range
);
1134 static HRESULT WINAPI
dwritetextlayout_layout_GetLocaleNameLength(IDWriteTextLayout
*iface
,
1135 UINT32 position
, UINT32
* length
, DWRITE_TEXT_RANGE
*range
)
1137 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1138 FIXME("(%p)->(%u %p %p): stub\n", This
, position
, length
, range
);
1142 static HRESULT WINAPI
dwritetextlayout_layout_GetLocaleName(IDWriteTextLayout
*iface
,
1143 UINT32 position
, WCHAR
* name
, UINT32 name_size
, DWRITE_TEXT_RANGE
*range
)
1145 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1146 FIXME("(%p)->(%u %p %u %p): stub\n", This
, position
, name
, name_size
, range
);
1150 static HRESULT WINAPI
dwritetextlayout_Draw(IDWriteTextLayout
*iface
,
1151 void *context
, IDWriteTextRenderer
* renderer
, FLOAT originX
, FLOAT originY
)
1153 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1154 FIXME("(%p)->(%p %p %f %f): stub\n", This
, context
, renderer
, originX
, originY
);
1158 static HRESULT WINAPI
dwritetextlayout_GetLineMetrics(IDWriteTextLayout
*iface
,
1159 DWRITE_LINE_METRICS
*metrics
, UINT32 max_count
, UINT32
*actual_count
)
1161 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1162 FIXME("(%p)->(%p %u %p): stub\n", This
, metrics
, max_count
, actual_count
);
1166 static HRESULT WINAPI
dwritetextlayout_GetMetrics(IDWriteTextLayout
*iface
, DWRITE_TEXT_METRICS
*metrics
)
1168 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1169 FIXME("(%p)->(%p): stub\n", This
, metrics
);
1173 static HRESULT WINAPI
dwritetextlayout_GetOverhangMetrics(IDWriteTextLayout
*iface
, DWRITE_OVERHANG_METRICS
*overhangs
)
1175 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1176 FIXME("(%p)->(%p): stub\n", This
, overhangs
);
1180 static HRESULT WINAPI
dwritetextlayout_GetClusterMetrics(IDWriteTextLayout
*iface
,
1181 DWRITE_CLUSTER_METRICS
*metrics
, UINT32 max_count
, UINT32
* act_count
)
1183 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1184 FIXME("(%p)->(%p %u %p): stub\n", This
, metrics
, max_count
, act_count
);
1188 static HRESULT WINAPI
dwritetextlayout_DetermineMinWidth(IDWriteTextLayout
*iface
, FLOAT
* min_width
)
1190 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1191 FIXME("(%p)->(%p): stub\n", This
, min_width
);
1195 static HRESULT WINAPI
dwritetextlayout_HitTestPoint(IDWriteTextLayout
*iface
,
1196 FLOAT pointX
, FLOAT pointY
, BOOL
* is_trailinghit
, BOOL
* is_inside
, DWRITE_HIT_TEST_METRICS
*metrics
)
1198 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1199 FIXME("(%p)->(%f %f %p %p %p): stub\n", This
, pointX
, pointY
, is_trailinghit
, is_inside
, metrics
);
1203 static HRESULT WINAPI
dwritetextlayout_HitTestTextPosition(IDWriteTextLayout
*iface
,
1204 UINT32 textPosition
, BOOL is_trailinghit
, FLOAT
* pointX
, FLOAT
* pointY
, DWRITE_HIT_TEST_METRICS
*metrics
)
1206 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1207 FIXME("(%p)->(%u %d %p %p %p): stub\n", This
, textPosition
, is_trailinghit
, pointX
, pointY
, metrics
);
1211 static HRESULT WINAPI
dwritetextlayout_HitTestTextRange(IDWriteTextLayout
*iface
,
1212 UINT32 textPosition
, UINT32 textLength
, FLOAT originX
, FLOAT originY
,
1213 DWRITE_HIT_TEST_METRICS
*metrics
, UINT32 max_metricscount
, UINT32
* actual_metricscount
)
1215 struct dwrite_textlayout
*This
= impl_from_IDWriteTextLayout(iface
);
1216 FIXME("(%p)->(%u %u %f %f %p %u %p): stub\n", This
, textPosition
, textLength
, originX
, originY
, metrics
,
1217 max_metricscount
, actual_metricscount
);
1221 static const IDWriteTextLayoutVtbl dwritetextlayoutvtbl
= {
1222 dwritetextlayout_QueryInterface
,
1223 dwritetextlayout_AddRef
,
1224 dwritetextlayout_Release
,
1225 dwritetextlayout_SetTextAlignment
,
1226 dwritetextlayout_SetParagraphAlignment
,
1227 dwritetextlayout_SetWordWrapping
,
1228 dwritetextlayout_SetReadingDirection
,
1229 dwritetextlayout_SetFlowDirection
,
1230 dwritetextlayout_SetIncrementalTabStop
,
1231 dwritetextlayout_SetTrimming
,
1232 dwritetextlayout_SetLineSpacing
,
1233 dwritetextlayout_GetTextAlignment
,
1234 dwritetextlayout_GetParagraphAlignment
,
1235 dwritetextlayout_GetWordWrapping
,
1236 dwritetextlayout_GetReadingDirection
,
1237 dwritetextlayout_GetFlowDirection
,
1238 dwritetextlayout_GetIncrementalTabStop
,
1239 dwritetextlayout_GetTrimming
,
1240 dwritetextlayout_GetLineSpacing
,
1241 dwritetextlayout_GetFontCollection
,
1242 dwritetextlayout_GetFontFamilyNameLength
,
1243 dwritetextlayout_GetFontFamilyName
,
1244 dwritetextlayout_GetFontWeight
,
1245 dwritetextlayout_GetFontStyle
,
1246 dwritetextlayout_GetFontStretch
,
1247 dwritetextlayout_GetFontSize
,
1248 dwritetextlayout_GetLocaleNameLength
,
1249 dwritetextlayout_GetLocaleName
,
1250 dwritetextlayout_SetMaxWidth
,
1251 dwritetextlayout_SetMaxHeight
,
1252 dwritetextlayout_SetFontCollection
,
1253 dwritetextlayout_SetFontFamilyName
,
1254 dwritetextlayout_SetFontWeight
,
1255 dwritetextlayout_SetFontStyle
,
1256 dwritetextlayout_SetFontStretch
,
1257 dwritetextlayout_SetFontSize
,
1258 dwritetextlayout_SetUnderline
,
1259 dwritetextlayout_SetStrikethrough
,
1260 dwritetextlayout_SetDrawingEffect
,
1261 dwritetextlayout_SetInlineObject
,
1262 dwritetextlayout_SetTypography
,
1263 dwritetextlayout_SetLocaleName
,
1264 dwritetextlayout_GetMaxWidth
,
1265 dwritetextlayout_GetMaxHeight
,
1266 dwritetextlayout_layout_GetFontCollection
,
1267 dwritetextlayout_layout_GetFontFamilyNameLength
,
1268 dwritetextlayout_layout_GetFontFamilyName
,
1269 dwritetextlayout_layout_GetFontWeight
,
1270 dwritetextlayout_layout_GetFontStyle
,
1271 dwritetextlayout_layout_GetFontStretch
,
1272 dwritetextlayout_layout_GetFontSize
,
1273 dwritetextlayout_GetUnderline
,
1274 dwritetextlayout_GetStrikethrough
,
1275 dwritetextlayout_GetDrawingEffect
,
1276 dwritetextlayout_GetInlineObject
,
1277 dwritetextlayout_GetTypography
,
1278 dwritetextlayout_layout_GetLocaleNameLength
,
1279 dwritetextlayout_layout_GetLocaleName
,
1280 dwritetextlayout_Draw
,
1281 dwritetextlayout_GetLineMetrics
,
1282 dwritetextlayout_GetMetrics
,
1283 dwritetextlayout_GetOverhangMetrics
,
1284 dwritetextlayout_GetClusterMetrics
,
1285 dwritetextlayout_DetermineMinWidth
,
1286 dwritetextlayout_HitTestPoint
,
1287 dwritetextlayout_HitTestTextPosition
,
1288 dwritetextlayout_HitTestTextRange
1291 static void layout_format_from_textformat(struct dwrite_textlayout
*layout
, IDWriteTextFormat
*format
)
1293 struct dwrite_textformat
*f
;
1295 memset(&layout
->format
, 0, sizeof(layout
->format
));
1297 if ((f
= unsafe_impl_from_IDWriteTextFormat(format
)))
1299 layout
->format
= f
->format
;
1300 layout
->format
.locale
= heap_strdupW(f
->format
.locale
);
1301 layout
->format
.family_name
= heap_strdupW(f
->format
.family_name
);
1302 if (layout
->format
.trimmingsign
)
1303 IDWriteInlineObject_AddRef(layout
->format
.trimmingsign
);
1307 UINT32 locale_len
, family_len
;
1309 layout
->format
.weight
= IDWriteTextFormat_GetFontWeight(format
);
1310 layout
->format
.style
= IDWriteTextFormat_GetFontStyle(format
);
1311 layout
->format
.stretch
= IDWriteTextFormat_GetFontStretch(format
);
1312 layout
->format
.fontsize
= IDWriteTextFormat_GetFontSize(format
);
1313 layout
->format
.textalignment
= IDWriteTextFormat_GetTextAlignment(format
);
1314 layout
->format
.paralign
= IDWriteTextFormat_GetParagraphAlignment(format
);
1315 layout
->format
.wrapping
= IDWriteTextFormat_GetWordWrapping(format
);
1316 layout
->format
.readingdir
= IDWriteTextFormat_GetReadingDirection(format
);
1317 layout
->format
.flow
= IDWriteTextFormat_GetFlowDirection(format
);
1318 IDWriteTextFormat_GetLineSpacing(format
,
1319 &layout
->format
.spacingmethod
,
1320 &layout
->format
.spacing
,
1321 &layout
->format
.baseline
1323 IDWriteTextFormat_GetTrimming(format
, &layout
->format
.trimming
, &layout
->format
.trimmingsign
);
1325 /* locale name and length */
1326 locale_len
= IDWriteTextFormat_GetLocaleNameLength(format
);
1327 layout
->format
.locale
= heap_alloc((locale_len
+1)*sizeof(WCHAR
));
1328 IDWriteTextFormat_GetLocaleName(format
, layout
->format
.locale
, locale_len
+1);
1329 layout
->format
.locale_len
= locale_len
;
1331 /* font family name and length */
1332 family_len
= IDWriteTextFormat_GetFontFamilyNameLength(format
);
1333 layout
->format
.family_name
= heap_alloc((family_len
+1)*sizeof(WCHAR
));
1334 IDWriteTextFormat_GetFontFamilyName(format
, layout
->format
.family_name
, family_len
+1);
1335 layout
->format
.family_len
= family_len
;
1338 IDWriteTextFormat_GetFontCollection(format
, &layout
->format
.collection
);
1341 HRESULT
create_textlayout(const WCHAR
*str
, UINT32 len
, IDWriteTextFormat
*format
, FLOAT maxwidth
, FLOAT maxheight
, IDWriteTextLayout
**layout
)
1343 struct dwrite_textlayout
*This
;
1344 struct layout_range
*range
;
1345 DWRITE_TEXT_RANGE r
= { 0, len
};
1349 This
= heap_alloc(sizeof(struct dwrite_textlayout
));
1350 if (!This
) return E_OUTOFMEMORY
;
1352 This
->IDWriteTextLayout_iface
.lpVtbl
= &dwritetextlayoutvtbl
;
1354 This
->str
= heap_strdupnW(str
, len
);
1356 This
->maxwidth
= maxwidth
;
1357 This
->maxheight
= maxheight
;
1358 layout_format_from_textformat(This
, format
);
1360 list_init(&This
->ranges
);
1361 range
= alloc_layout_range(This
, &r
);
1363 IDWriteTextLayout_Release(&This
->IDWriteTextLayout_iface
);
1364 return E_OUTOFMEMORY
;
1366 list_add_head(&This
->ranges
, &range
->entry
);
1368 *layout
= &This
->IDWriteTextLayout_iface
;
1373 static HRESULT WINAPI
dwritetrimmingsign_QueryInterface(IDWriteInlineObject
*iface
, REFIID riid
, void **obj
)
1375 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1377 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1379 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteInlineObject
)) {
1381 IDWriteInlineObject_AddRef(iface
);
1386 return E_NOINTERFACE
;
1390 static ULONG WINAPI
dwritetrimmingsign_AddRef(IDWriteInlineObject
*iface
)
1392 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1393 ULONG ref
= InterlockedIncrement(&This
->ref
);
1394 TRACE("(%p)->(%d)\n", This
, ref
);
1398 static ULONG WINAPI
dwritetrimmingsign_Release(IDWriteInlineObject
*iface
)
1400 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1401 ULONG ref
= InterlockedDecrement(&This
->ref
);
1403 TRACE("(%p)->(%d)\n", This
, ref
);
1411 static HRESULT WINAPI
dwritetrimmingsign_Draw(IDWriteInlineObject
*iface
, void *context
, IDWriteTextRenderer
*renderer
,
1412 FLOAT originX
, FLOAT originY
, BOOL is_sideways
, BOOL is_rtl
, IUnknown
*drawing_effect
)
1414 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1415 FIXME("(%p)->(%p %p %f %f %d %d %p): stub\n", This
, context
, renderer
, originX
, originY
, is_sideways
, is_rtl
, drawing_effect
);
1419 static HRESULT WINAPI
dwritetrimmingsign_GetMetrics(IDWriteInlineObject
*iface
, DWRITE_INLINE_OBJECT_METRICS
*metrics
)
1421 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1422 FIXME("(%p)->(%p): stub\n", This
, metrics
);
1426 static HRESULT WINAPI
dwritetrimmingsign_GetOverhangMetrics(IDWriteInlineObject
*iface
, DWRITE_OVERHANG_METRICS
*overhangs
)
1428 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1429 FIXME("(%p)->(%p): stub\n", This
, overhangs
);
1433 static HRESULT WINAPI
dwritetrimmingsign_GetBreakConditions(IDWriteInlineObject
*iface
, DWRITE_BREAK_CONDITION
*before
,
1434 DWRITE_BREAK_CONDITION
*after
)
1436 struct dwrite_trimmingsign
*This
= impl_from_IDWriteInlineObject(iface
);
1438 TRACE("(%p)->(%p %p)\n", This
, before
, after
);
1440 *before
= *after
= DWRITE_BREAK_CONDITION_NEUTRAL
;
1444 static const IDWriteInlineObjectVtbl dwritetrimmingsignvtbl
= {
1445 dwritetrimmingsign_QueryInterface
,
1446 dwritetrimmingsign_AddRef
,
1447 dwritetrimmingsign_Release
,
1448 dwritetrimmingsign_Draw
,
1449 dwritetrimmingsign_GetMetrics
,
1450 dwritetrimmingsign_GetOverhangMetrics
,
1451 dwritetrimmingsign_GetBreakConditions
1454 HRESULT
create_trimmingsign(IDWriteInlineObject
**sign
)
1456 struct dwrite_trimmingsign
*This
;
1460 This
= heap_alloc(sizeof(struct dwrite_trimmingsign
));
1461 if (!This
) return E_OUTOFMEMORY
;
1463 This
->IDWriteInlineObject_iface
.lpVtbl
= &dwritetrimmingsignvtbl
;
1466 *sign
= &This
->IDWriteInlineObject_iface
;
1471 static HRESULT WINAPI
dwritetextformat_QueryInterface(IDWriteTextFormat
*iface
, REFIID riid
, void **obj
)
1473 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1475 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1477 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1478 IsEqualIID(riid
, &IID_IDWriteTextFormat
))
1481 IDWriteTextFormat_AddRef(iface
);
1487 return E_NOINTERFACE
;
1490 static ULONG WINAPI
dwritetextformat_AddRef(IDWriteTextFormat
*iface
)
1492 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1493 ULONG ref
= InterlockedIncrement(&This
->ref
);
1494 TRACE("(%p)->(%d)\n", This
, ref
);
1498 static ULONG WINAPI
dwritetextformat_Release(IDWriteTextFormat
*iface
)
1500 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1501 ULONG ref
= InterlockedDecrement(&This
->ref
);
1503 TRACE("(%p)->(%d)\n", This
, ref
);
1507 release_format_data(&This
->format
);
1514 static HRESULT WINAPI
dwritetextformat_SetTextAlignment(IDWriteTextFormat
*iface
, DWRITE_TEXT_ALIGNMENT alignment
)
1516 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1517 TRACE("(%p)->(%d)\n", This
, alignment
);
1518 This
->format
.textalignment
= alignment
;
1522 static HRESULT WINAPI
dwritetextformat_SetParagraphAlignment(IDWriteTextFormat
*iface
, DWRITE_PARAGRAPH_ALIGNMENT alignment
)
1524 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1525 TRACE("(%p)->(%d)\n", This
, alignment
);
1526 This
->format
.paralign
= alignment
;
1530 static HRESULT WINAPI
dwritetextformat_SetWordWrapping(IDWriteTextFormat
*iface
, DWRITE_WORD_WRAPPING wrapping
)
1532 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1533 TRACE("(%p)->(%d)\n", This
, wrapping
);
1534 This
->format
.wrapping
= wrapping
;
1538 static HRESULT WINAPI
dwritetextformat_SetReadingDirection(IDWriteTextFormat
*iface
, DWRITE_READING_DIRECTION direction
)
1540 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1541 TRACE("(%p)->(%d)\n", This
, direction
);
1542 This
->format
.readingdir
= direction
;
1546 static HRESULT WINAPI
dwritetextformat_SetFlowDirection(IDWriteTextFormat
*iface
, DWRITE_FLOW_DIRECTION direction
)
1548 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1549 TRACE("(%p)->(%d)\n", This
, direction
);
1550 This
->format
.flow
= direction
;
1554 static HRESULT WINAPI
dwritetextformat_SetIncrementalTabStop(IDWriteTextFormat
*iface
, FLOAT tabstop
)
1556 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1557 FIXME("(%p)->(%f): stub\n", This
, tabstop
);
1561 static HRESULT WINAPI
dwritetextformat_SetTrimming(IDWriteTextFormat
*iface
, DWRITE_TRIMMING
const *trimming
,
1562 IDWriteInlineObject
*trimming_sign
)
1564 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1565 TRACE("(%p)->(%p %p)\n", This
, trimming
, trimming_sign
);
1567 This
->format
.trimming
= *trimming
;
1568 if (This
->format
.trimmingsign
)
1569 IDWriteInlineObject_Release(This
->format
.trimmingsign
);
1570 This
->format
.trimmingsign
= trimming_sign
;
1571 if (This
->format
.trimmingsign
)
1572 IDWriteInlineObject_AddRef(This
->format
.trimmingsign
);
1576 static HRESULT WINAPI
dwritetextformat_SetLineSpacing(IDWriteTextFormat
*iface
, DWRITE_LINE_SPACING_METHOD method
,
1577 FLOAT spacing
, FLOAT baseline
)
1579 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1580 TRACE("(%p)->(%d %f %f)\n", This
, method
, spacing
, baseline
);
1581 This
->format
.spacingmethod
= method
;
1582 This
->format
.spacing
= spacing
;
1583 This
->format
.baseline
= baseline
;
1587 static DWRITE_TEXT_ALIGNMENT WINAPI
dwritetextformat_GetTextAlignment(IDWriteTextFormat
*iface
)
1589 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1590 TRACE("(%p)\n", This
);
1591 return This
->format
.textalignment
;
1594 static DWRITE_PARAGRAPH_ALIGNMENT WINAPI
dwritetextformat_GetParagraphAlignment(IDWriteTextFormat
*iface
)
1596 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1597 TRACE("(%p)\n", This
);
1598 return This
->format
.paralign
;
1601 static DWRITE_WORD_WRAPPING WINAPI
dwritetextformat_GetWordWrapping(IDWriteTextFormat
*iface
)
1603 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1604 TRACE("(%p)\n", This
);
1605 return This
->format
.wrapping
;
1608 static DWRITE_READING_DIRECTION WINAPI
dwritetextformat_GetReadingDirection(IDWriteTextFormat
*iface
)
1610 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1611 TRACE("(%p)\n", This
);
1612 return This
->format
.readingdir
;
1615 static DWRITE_FLOW_DIRECTION WINAPI
dwritetextformat_GetFlowDirection(IDWriteTextFormat
*iface
)
1617 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1618 TRACE("(%p)\n", This
);
1619 return This
->format
.flow
;
1622 static FLOAT WINAPI
dwritetextformat_GetIncrementalTabStop(IDWriteTextFormat
*iface
)
1624 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1625 FIXME("(%p): stub\n", This
);
1629 static HRESULT WINAPI
dwritetextformat_GetTrimming(IDWriteTextFormat
*iface
, DWRITE_TRIMMING
*options
,
1630 IDWriteInlineObject
**trimming_sign
)
1632 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1633 TRACE("(%p)->(%p %p)\n", This
, options
, trimming_sign
);
1635 *options
= This
->format
.trimming
;
1636 if ((*trimming_sign
= This
->format
.trimmingsign
))
1637 IDWriteInlineObject_AddRef(*trimming_sign
);
1642 static HRESULT WINAPI
dwritetextformat_GetLineSpacing(IDWriteTextFormat
*iface
, DWRITE_LINE_SPACING_METHOD
*method
,
1643 FLOAT
*spacing
, FLOAT
*baseline
)
1645 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1646 TRACE("(%p)->(%p %p %p)\n", This
, method
, spacing
, baseline
);
1648 *method
= This
->format
.spacingmethod
;
1649 *spacing
= This
->format
.spacing
;
1650 *baseline
= This
->format
.baseline
;
1654 static HRESULT WINAPI
dwritetextformat_GetFontCollection(IDWriteTextFormat
*iface
, IDWriteFontCollection
**collection
)
1656 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1658 TRACE("(%p)->(%p)\n", This
, collection
);
1660 *collection
= This
->format
.collection
;
1661 IDWriteFontCollection_AddRef(*collection
);
1666 static UINT32 WINAPI
dwritetextformat_GetFontFamilyNameLength(IDWriteTextFormat
*iface
)
1668 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1669 TRACE("(%p)\n", This
);
1670 return This
->format
.family_len
;
1673 static HRESULT WINAPI
dwritetextformat_GetFontFamilyName(IDWriteTextFormat
*iface
, WCHAR
*name
, UINT32 size
)
1675 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1677 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
1679 if (size
<= This
->format
.family_len
) return E_NOT_SUFFICIENT_BUFFER
;
1680 strcpyW(name
, This
->format
.family_name
);
1684 static DWRITE_FONT_WEIGHT WINAPI
dwritetextformat_GetFontWeight(IDWriteTextFormat
*iface
)
1686 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1687 TRACE("(%p)\n", This
);
1688 return This
->format
.weight
;
1691 static DWRITE_FONT_STYLE WINAPI
dwritetextformat_GetFontStyle(IDWriteTextFormat
*iface
)
1693 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1694 TRACE("(%p)\n", This
);
1695 return This
->format
.style
;
1698 static DWRITE_FONT_STRETCH WINAPI
dwritetextformat_GetFontStretch(IDWriteTextFormat
*iface
)
1700 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1701 TRACE("(%p)\n", This
);
1702 return This
->format
.stretch
;
1705 static FLOAT WINAPI
dwritetextformat_GetFontSize(IDWriteTextFormat
*iface
)
1707 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1708 TRACE("(%p)\n", This
);
1709 return This
->format
.fontsize
;
1712 static UINT32 WINAPI
dwritetextformat_GetLocaleNameLength(IDWriteTextFormat
*iface
)
1714 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1715 TRACE("(%p)\n", This
);
1716 return This
->format
.locale_len
;
1719 static HRESULT WINAPI
dwritetextformat_GetLocaleName(IDWriteTextFormat
*iface
, WCHAR
*name
, UINT32 size
)
1721 struct dwrite_textformat
*This
= impl_from_IDWriteTextFormat(iface
);
1723 TRACE("(%p)->(%p %u)\n", This
, name
, size
);
1725 if (size
<= This
->format
.locale_len
) return E_NOT_SUFFICIENT_BUFFER
;
1726 strcpyW(name
, This
->format
.locale
);
1730 static const IDWriteTextFormatVtbl dwritetextformatvtbl
= {
1731 dwritetextformat_QueryInterface
,
1732 dwritetextformat_AddRef
,
1733 dwritetextformat_Release
,
1734 dwritetextformat_SetTextAlignment
,
1735 dwritetextformat_SetParagraphAlignment
,
1736 dwritetextformat_SetWordWrapping
,
1737 dwritetextformat_SetReadingDirection
,
1738 dwritetextformat_SetFlowDirection
,
1739 dwritetextformat_SetIncrementalTabStop
,
1740 dwritetextformat_SetTrimming
,
1741 dwritetextformat_SetLineSpacing
,
1742 dwritetextformat_GetTextAlignment
,
1743 dwritetextformat_GetParagraphAlignment
,
1744 dwritetextformat_GetWordWrapping
,
1745 dwritetextformat_GetReadingDirection
,
1746 dwritetextformat_GetFlowDirection
,
1747 dwritetextformat_GetIncrementalTabStop
,
1748 dwritetextformat_GetTrimming
,
1749 dwritetextformat_GetLineSpacing
,
1750 dwritetextformat_GetFontCollection
,
1751 dwritetextformat_GetFontFamilyNameLength
,
1752 dwritetextformat_GetFontFamilyName
,
1753 dwritetextformat_GetFontWeight
,
1754 dwritetextformat_GetFontStyle
,
1755 dwritetextformat_GetFontStretch
,
1756 dwritetextformat_GetFontSize
,
1757 dwritetextformat_GetLocaleNameLength
,
1758 dwritetextformat_GetLocaleName
1761 HRESULT
create_textformat(const WCHAR
*family_name
, IDWriteFontCollection
*collection
, DWRITE_FONT_WEIGHT weight
, DWRITE_FONT_STYLE style
,
1762 DWRITE_FONT_STRETCH stretch
, FLOAT size
, const WCHAR
*locale
, IDWriteTextFormat
**format
)
1764 struct dwrite_textformat
*This
;
1768 This
= heap_alloc(sizeof(struct dwrite_textformat
));
1769 if (!This
) return E_OUTOFMEMORY
;
1771 This
->IDWriteTextFormat_iface
.lpVtbl
= &dwritetextformatvtbl
;
1773 This
->format
.family_name
= heap_strdupW(family_name
);
1774 This
->format
.family_len
= strlenW(family_name
);
1775 This
->format
.locale
= heap_strdupW(locale
);
1776 This
->format
.locale_len
= strlenW(locale
);
1777 This
->format
.weight
= weight
;
1778 This
->format
.style
= style
;
1779 This
->format
.fontsize
= size
;
1780 This
->format
.stretch
= stretch
;
1781 This
->format
.textalignment
= DWRITE_TEXT_ALIGNMENT_LEADING
;
1782 This
->format
.paralign
= DWRITE_PARAGRAPH_ALIGNMENT_NEAR
;
1783 This
->format
.wrapping
= DWRITE_WORD_WRAPPING_WRAP
;
1784 This
->format
.readingdir
= DWRITE_READING_DIRECTION_LEFT_TO_RIGHT
;
1785 This
->format
.flow
= DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM
;
1786 This
->format
.spacingmethod
= DWRITE_LINE_SPACING_METHOD_DEFAULT
;
1787 This
->format
.spacing
= 0.0;
1788 This
->format
.baseline
= 0.0;
1789 This
->format
.trimming
.granularity
= DWRITE_TRIMMING_GRANULARITY_NONE
;
1790 This
->format
.trimming
.delimiter
= 0;
1791 This
->format
.trimming
.delimiterCount
= 0;
1792 This
->format
.trimmingsign
= NULL
;
1796 This
->format
.collection
= collection
;
1797 IDWriteFontCollection_AddRef(collection
);
1800 ERR("Collection should always be set\n");
1802 *format
= &This
->IDWriteTextFormat_iface
;
1807 static HRESULT WINAPI
dwritetypography_QueryInterface(IDWriteTypography
*iface
, REFIID riid
, void **obj
)
1809 struct dwrite_typography
*typography
= impl_from_IDWriteTypography(iface
);
1811 TRACE("(%p)->(%s %p)\n", typography
, debugstr_guid(riid
), obj
);
1813 if (IsEqualIID(riid
, &IID_IDWriteTypography
) || IsEqualIID(riid
, &IID_IUnknown
)) {
1815 IDWriteTypography_AddRef(iface
);
1821 return E_NOINTERFACE
;
1824 static ULONG WINAPI
dwritetypography_AddRef(IDWriteTypography
*iface
)
1826 struct dwrite_typography
*typography
= impl_from_IDWriteTypography(iface
);
1827 ULONG ref
= InterlockedIncrement(&typography
->ref
);
1828 TRACE("(%p)->(%d)\n", typography
, ref
);
1832 static ULONG WINAPI
dwritetypography_Release(IDWriteTypography
*iface
)
1834 struct dwrite_typography
*typography
= impl_from_IDWriteTypography(iface
);
1835 ULONG ref
= InterlockedDecrement(&typography
->ref
);
1837 TRACE("(%p)->(%d)\n", typography
, ref
);
1840 heap_free(typography
->features
);
1841 heap_free(typography
);
1847 static HRESULT WINAPI
dwritetypography_AddFontFeature(IDWriteTypography
*iface
, DWRITE_FONT_FEATURE feature
)
1849 struct dwrite_typography
*typography
= impl_from_IDWriteTypography(iface
);
1851 TRACE("(%p)->(%x %u)\n", typography
, feature
.nameTag
, feature
.parameter
);
1853 if (typography
->count
== typography
->allocated
) {
1854 DWRITE_FONT_FEATURE
*ptr
= heap_realloc(typography
->features
, 2*typography
->allocated
*sizeof(DWRITE_FONT_FEATURE
));
1856 return E_OUTOFMEMORY
;
1858 typography
->features
= ptr
;
1859 typography
->allocated
*= 2;
1862 typography
->features
[typography
->count
++] = feature
;
1866 static UINT32 WINAPI
dwritetypography_GetFontFeatureCount(IDWriteTypography
*iface
)
1868 struct dwrite_typography
*typography
= impl_from_IDWriteTypography(iface
);
1869 TRACE("(%p)\n", typography
);
1870 return typography
->count
;
1873 static HRESULT WINAPI
dwritetypography_GetFontFeature(IDWriteTypography
*iface
, UINT32 index
, DWRITE_FONT_FEATURE
*feature
)
1875 struct dwrite_typography
*typography
= impl_from_IDWriteTypography(iface
);
1877 TRACE("(%p)->(%u %p)\n", typography
, index
, feature
);
1879 if (index
>= typography
->count
)
1880 return E_INVALIDARG
;
1882 *feature
= typography
->features
[index
];
1886 static const IDWriteTypographyVtbl dwritetypographyvtbl
= {
1887 dwritetypography_QueryInterface
,
1888 dwritetypography_AddRef
,
1889 dwritetypography_Release
,
1890 dwritetypography_AddFontFeature
,
1891 dwritetypography_GetFontFeatureCount
,
1892 dwritetypography_GetFontFeature
1895 HRESULT
create_typography(IDWriteTypography
**ret
)
1897 struct dwrite_typography
*typography
;
1901 typography
= heap_alloc(sizeof(*typography
));
1903 return E_OUTOFMEMORY
;
1905 typography
->IDWriteTypography_iface
.lpVtbl
= &dwritetypographyvtbl
;
1906 typography
->ref
= 1;
1907 typography
->allocated
= 2;
1908 typography
->count
= 0;
1910 typography
->features
= heap_alloc(typography
->allocated
*sizeof(DWRITE_FONT_FEATURE
));
1911 if (!typography
->features
) {
1912 heap_free(typography
);
1913 return E_OUTOFMEMORY
;
1916 *ret
= &typography
->IDWriteTypography_iface
;