configure: Fix detection of gnutls on Ubuntu 14.10.
[wine.git] / dlls / dwrite / layout.c
blob6d8145dc7e836959a4c6dd1919294dcfecefe1b9
1 /*
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
21 #define COBJMACROS
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "dwrite_private.h"
29 #include "wine/list.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
33 struct dwrite_textformat_data {
34 WCHAR *family_name;
35 UINT32 family_len;
36 WCHAR *locale;
37 UINT32 locale_len;
39 DWRITE_FONT_WEIGHT weight;
40 DWRITE_FONT_STYLE style;
41 DWRITE_FONT_STRETCH stretch;
43 DWRITE_PARAGRAPH_ALIGNMENT paralign;
44 DWRITE_READING_DIRECTION readingdir;
45 DWRITE_WORD_WRAPPING wrapping;
46 DWRITE_TEXT_ALIGNMENT textalignment;
47 DWRITE_FLOW_DIRECTION flow;
48 DWRITE_LINE_SPACING_METHOD spacingmethod;
50 FLOAT spacing;
51 FLOAT baseline;
52 FLOAT fontsize;
54 DWRITE_TRIMMING trimming;
55 IDWriteInlineObject *trimmingsign;
57 IDWriteFontCollection *collection;
60 enum layout_range_attr_kind {
61 LAYOUT_RANGE_ATTR_WEIGHT,
62 LAYOUT_RANGE_ATTR_STYLE,
63 LAYOUT_RANGE_ATTR_STRETCH,
64 LAYOUT_RANGE_ATTR_FONTSIZE,
65 LAYOUT_RANGE_ATTR_EFFECT,
66 LAYOUT_RANGE_ATTR_INLINE,
67 LAYOUT_RANGE_ATTR_UNDERLINE,
68 LAYOUT_RANGE_ATTR_STRIKETHROUGH,
69 LAYOUT_RANGE_ATTR_FONTCOLL
72 struct layout_range_attr_value {
73 DWRITE_TEXT_RANGE range;
74 union {
75 DWRITE_FONT_WEIGHT weight;
76 DWRITE_FONT_STYLE style;
77 DWRITE_FONT_STRETCH stretch;
78 FLOAT fontsize;
79 IDWriteInlineObject *object;
80 IUnknown *effect;
81 BOOL underline;
82 BOOL strikethrough;
83 IDWriteFontCollection *collection;
84 } u;
87 struct layout_range {
88 struct list entry;
89 DWRITE_TEXT_RANGE range;
90 DWRITE_FONT_WEIGHT weight;
91 DWRITE_FONT_STYLE style;
92 FLOAT fontsize;
93 DWRITE_FONT_STRETCH stretch;
94 IDWriteInlineObject *object;
95 IUnknown *effect;
96 BOOL underline;
97 BOOL strikethrough;
98 IDWriteFontCollection *collection;
101 struct dwrite_textlayout {
102 IDWriteTextLayout2 IDWriteTextLayout2_iface;
103 LONG ref;
105 WCHAR *str;
106 UINT32 len;
107 struct dwrite_textformat_data format;
108 FLOAT maxwidth;
109 FLOAT maxheight;
110 struct list ranges;
113 struct dwrite_textformat {
114 IDWriteTextFormat1 IDWriteTextFormat1_iface;
115 LONG ref;
116 struct dwrite_textformat_data format;
119 struct dwrite_trimmingsign {
120 IDWriteInlineObject IDWriteInlineObject_iface;
121 LONG ref;
124 struct dwrite_typography {
125 IDWriteTypography IDWriteTypography_iface;
126 LONG ref;
128 DWRITE_FONT_FEATURE *features;
129 UINT32 allocated;
130 UINT32 count;
133 static const IDWriteTextFormat1Vtbl dwritetextformatvtbl;
135 static void release_format_data(struct dwrite_textformat_data *data)
137 if (data->collection) IDWriteFontCollection_Release(data->collection);
138 if (data->trimmingsign) IDWriteInlineObject_Release(data->trimmingsign);
139 heap_free(data->family_name);
140 heap_free(data->locale);
143 static inline struct dwrite_textlayout *impl_from_IDWriteTextLayout2(IDWriteTextLayout2 *iface)
145 return CONTAINING_RECORD(iface, struct dwrite_textlayout, IDWriteTextLayout2_iface);
148 static inline struct dwrite_textformat *impl_from_IDWriteTextFormat1(IDWriteTextFormat1 *iface)
150 return CONTAINING_RECORD(iface, struct dwrite_textformat, IDWriteTextFormat1_iface);
153 static inline struct dwrite_textformat *unsafe_impl_from_IDWriteTextFormat1(IDWriteTextFormat1 *iface)
155 return iface->lpVtbl == &dwritetextformatvtbl ? impl_from_IDWriteTextFormat1(iface) : NULL;
158 static inline struct dwrite_trimmingsign *impl_from_IDWriteInlineObject(IDWriteInlineObject *iface)
160 return CONTAINING_RECORD(iface, struct dwrite_trimmingsign, IDWriteInlineObject_iface);
163 static inline struct dwrite_typography *impl_from_IDWriteTypography(IDWriteTypography *iface)
165 return CONTAINING_RECORD(iface, struct dwrite_typography, IDWriteTypography_iface);
168 /* To be used in IDWriteTextLayout methods to validate and fix passed range */
169 static inline BOOL validate_text_range(struct dwrite_textlayout *layout, DWRITE_TEXT_RANGE *r)
171 if (r->startPosition >= layout->len)
172 return FALSE;
174 if (r->startPosition + r->length > layout->len)
175 r->length = layout->len - r->startPosition;
177 return TRUE;
180 static BOOL is_same_layout_attrvalue(struct layout_range const *range, enum layout_range_attr_kind attr, struct layout_range_attr_value *value)
182 switch (attr) {
183 case LAYOUT_RANGE_ATTR_WEIGHT:
184 return range->weight == value->u.weight;
185 case LAYOUT_RANGE_ATTR_STYLE:
186 return range->style == value->u.style;
187 case LAYOUT_RANGE_ATTR_STRETCH:
188 return range->stretch == value->u.stretch;
189 case LAYOUT_RANGE_ATTR_FONTSIZE:
190 return range->fontsize == value->u.fontsize;
191 case LAYOUT_RANGE_ATTR_INLINE:
192 return range->object == value->u.object;
193 case LAYOUT_RANGE_ATTR_EFFECT:
194 return range->effect == value->u.effect;
195 case LAYOUT_RANGE_ATTR_UNDERLINE:
196 return range->underline == value->u.underline;
197 case LAYOUT_RANGE_ATTR_STRIKETHROUGH:
198 return range->strikethrough == value->u.strikethrough;
199 case LAYOUT_RANGE_ATTR_FONTCOLL:
200 return range->collection == value->u.collection;
201 default:
205 return FALSE;
208 static inline BOOL is_same_layout_attributes(struct layout_range const *left, struct layout_range const *right)
210 return left->weight == right->weight &&
211 left->style == right->style &&
212 left->stretch == right->stretch &&
213 left->fontsize == right->fontsize &&
214 left->object == right->object &&
215 left->effect == right->effect &&
216 left->underline == right->underline &&
217 left->strikethrough == right->strikethrough &&
218 left->collection == right->collection;
221 static inline BOOL is_same_text_range(const DWRITE_TEXT_RANGE *left, const DWRITE_TEXT_RANGE *right)
223 return left->startPosition == right->startPosition && left->length == right->length;
226 /* Allocates range and inits it with default values from text format. */
227 static struct layout_range *alloc_layout_range(struct dwrite_textlayout *layout, const DWRITE_TEXT_RANGE *r)
229 struct layout_range *range;
231 range = heap_alloc(sizeof(*range));
232 if (!range) return NULL;
234 range->range = *r;
235 range->weight = layout->format.weight;
236 range->style = layout->format.style;
237 range->stretch = layout->format.stretch;
238 range->fontsize = layout->format.fontsize;
239 range->object = NULL;
240 range->effect = NULL;
241 range->underline = FALSE;
242 range->strikethrough = FALSE;
243 range->collection = layout->format.collection;
244 if (range->collection)
245 IDWriteFontCollection_AddRef(range->collection);
247 return range;
250 static struct layout_range *alloc_layout_range_from(struct layout_range *from, const DWRITE_TEXT_RANGE *r)
252 struct layout_range *range;
254 range = heap_alloc(sizeof(*range));
255 if (!range) return NULL;
257 *range = *from;
258 range->range = *r;
260 /* update refcounts */
261 if (range->object)
262 IDWriteInlineObject_AddRef(range->object);
263 if (range->effect)
264 IUnknown_AddRef(range->effect);
265 if (range->collection)
266 IDWriteFontCollection_AddRef(range->collection);
268 return range;
271 static void free_layout_range(struct layout_range *range)
273 if (!range)
274 return;
275 if (range->object)
276 IDWriteInlineObject_Release(range->object);
277 if (range->effect)
278 IUnknown_Release(range->effect);
279 if (range->collection)
280 IDWriteFontCollection_Release(range->collection);
281 heap_free(range);
284 static void free_layout_ranges_list(struct dwrite_textlayout *layout)
286 struct layout_range *cur, *cur2;
287 LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->ranges, struct layout_range, entry) {
288 list_remove(&cur->entry);
289 free_layout_range(cur);
293 static struct layout_range *find_outer_range(struct dwrite_textlayout *layout, const DWRITE_TEXT_RANGE *range)
295 struct layout_range *cur;
297 LIST_FOR_EACH_ENTRY(cur, &layout->ranges, struct layout_range, entry) {
299 if (cur->range.startPosition > range->startPosition)
300 return NULL;
302 if ((cur->range.startPosition + cur->range.length < range->startPosition + range->length) &&
303 (range->startPosition < cur->range.startPosition + cur->range.length))
304 return NULL;
305 if (cur->range.startPosition + cur->range.length >= range->startPosition + range->length)
306 return cur;
309 return NULL;
312 static struct layout_range *get_layout_range_by_pos(struct dwrite_textlayout *layout, UINT32 pos)
314 struct layout_range *cur;
316 LIST_FOR_EACH_ENTRY(cur, &layout->ranges, struct layout_range, entry) {
317 DWRITE_TEXT_RANGE *r = &cur->range;
318 if (r->startPosition <= pos && pos < r->startPosition + r->length)
319 return cur;
322 return NULL;
325 static BOOL set_layout_range_attrval(struct layout_range *dest, enum layout_range_attr_kind attr, struct layout_range_attr_value *value)
327 BOOL changed = FALSE;
329 switch (attr) {
330 case LAYOUT_RANGE_ATTR_WEIGHT:
331 changed = dest->weight != value->u.weight;
332 dest->weight = value->u.weight;
333 break;
334 case LAYOUT_RANGE_ATTR_STYLE:
335 changed = dest->style != value->u.style;
336 dest->style = value->u.style;
337 break;
338 case LAYOUT_RANGE_ATTR_STRETCH:
339 changed = dest->stretch != value->u.stretch;
340 dest->stretch = value->u.stretch;
341 break;
342 case LAYOUT_RANGE_ATTR_FONTSIZE:
343 changed = dest->fontsize != value->u.fontsize;
344 dest->fontsize = value->u.fontsize;
345 break;
346 case LAYOUT_RANGE_ATTR_INLINE:
347 changed = dest->object != value->u.object;
348 if (changed && dest->object)
349 IDWriteInlineObject_Release(dest->object);
350 dest->object = value->u.object;
351 if (dest->object)
352 IDWriteInlineObject_AddRef(dest->object);
353 break;
354 case LAYOUT_RANGE_ATTR_EFFECT:
355 changed = dest->effect != value->u.effect;
356 if (changed && dest->effect)
357 IUnknown_Release(dest->effect);
358 dest->effect = value->u.effect;
359 if (dest->effect)
360 IUnknown_AddRef(dest->effect);
361 break;
362 case LAYOUT_RANGE_ATTR_UNDERLINE:
363 changed = dest->underline != value->u.underline;
364 dest->underline = value->u.underline;
365 break;
366 case LAYOUT_RANGE_ATTR_STRIKETHROUGH:
367 changed = dest->strikethrough != value->u.strikethrough;
368 dest->strikethrough = value->u.strikethrough;
369 break;
370 case LAYOUT_RANGE_ATTR_FONTCOLL:
371 changed = dest->collection != value->u.collection;
372 if (changed && dest->collection)
373 IDWriteFontCollection_Release(dest->collection);
374 dest->collection = value->u.collection;
375 if (dest->collection)
376 IDWriteFontCollection_AddRef(dest->collection);
377 break;
378 default:
382 return changed;
385 static inline BOOL is_in_layout_range(const DWRITE_TEXT_RANGE *outer, const DWRITE_TEXT_RANGE *inner)
387 return (inner->startPosition >= outer->startPosition) &&
388 (inner->startPosition + inner->length <= outer->startPosition + outer->length);
391 static inline HRESULT return_range(const struct layout_range *range, DWRITE_TEXT_RANGE *r)
393 if (r) *r = range->range;
394 return S_OK;
397 /* Set attribute value for given range, does all needed splitting/merging of existing ranges. */
398 static HRESULT set_layout_range_attr(struct dwrite_textlayout *layout, enum layout_range_attr_kind attr, struct layout_range_attr_value *value)
400 struct layout_range *outer, *right, *left, *cur;
401 struct list *ranges = &layout->ranges;
402 BOOL changed = FALSE;
403 DWRITE_TEXT_RANGE r;
405 /* If new range is completely within existing range, split existing range in two */
406 if ((outer = find_outer_range(layout, &value->range))) {
408 /* no need to add same range */
409 if (is_same_layout_attrvalue(outer, attr, value))
410 return S_OK;
412 /* for matching range bounds just replace data */
413 if (is_same_text_range(&outer->range, &value->range)) {
414 changed = set_layout_range_attrval(outer, attr, value);
415 goto done;
418 /* add new range to the left */
419 if (value->range.startPosition == outer->range.startPosition) {
420 left = alloc_layout_range_from(outer, &value->range);
421 if (!left) return E_OUTOFMEMORY;
423 changed = set_layout_range_attrval(left, attr, value);
424 list_add_before(&outer->entry, &left->entry);
425 outer->range.startPosition += value->range.length;
426 outer->range.length -= value->range.length;
427 goto done;
430 /* add new range to the right */
431 if (value->range.startPosition + value->range.length == outer->range.startPosition + outer->range.length) {
432 right = alloc_layout_range_from(outer, &value->range);
433 if (!right) return E_OUTOFMEMORY;
435 changed = set_layout_range_attrval(right, attr, value);
436 list_add_after(&outer->entry, &right->entry);
437 outer->range.length -= value->range.length;
438 goto done;
441 r.startPosition = value->range.startPosition + value->range.length;
442 r.length = outer->range.length + outer->range.startPosition - r.startPosition;
444 /* right part */
445 right = alloc_layout_range_from(outer, &r);
446 /* new range in the middle */
447 cur = alloc_layout_range_from(outer, &value->range);
448 if (!right || !cur) {
449 free_layout_range(right);
450 free_layout_range(cur);
451 return E_OUTOFMEMORY;
454 /* reuse container range as a left part */
455 outer->range.length = value->range.startPosition - outer->range.startPosition;
457 /* new part */
458 set_layout_range_attrval(cur, attr, value);
460 list_add_after(&outer->entry, &cur->entry);
461 list_add_after(&cur->entry, &right->entry);
463 return S_OK;
466 /* Now it's only possible that given range contains some existing ranges, fully or partially.
467 Update all of them. */
468 left = get_layout_range_by_pos(layout, value->range.startPosition);
469 if (left->range.startPosition == value->range.startPosition)
470 changed = set_layout_range_attrval(left, attr, value);
471 else /* need to split */ {
472 r.startPosition = value->range.startPosition;
473 r.length = left->range.length - value->range.startPosition + left->range.startPosition;
474 left->range.length -= r.length;
475 cur = alloc_layout_range_from(left, &r);
476 changed = set_layout_range_attrval(cur, attr, value);
477 list_add_after(&left->entry, &cur->entry);
479 cur = LIST_ENTRY(list_next(ranges, &left->entry), struct layout_range, entry);
481 /* for all existing ranges covered by new one update value */
482 while (is_in_layout_range(&value->range, &cur->range)) {
483 changed = set_layout_range_attrval(cur, attr, value);
484 cur = LIST_ENTRY(list_next(ranges, &cur->entry), struct layout_range, entry);
487 /* it's possible rightmost range intersects */
488 if (cur && (cur->range.startPosition < value->range.startPosition + value->range.length)) {
489 r.startPosition = cur->range.startPosition;
490 r.length = value->range.startPosition + value->range.length - cur->range.startPosition;
491 left = alloc_layout_range_from(cur, &r);
492 changed = set_layout_range_attrval(left, attr, value);
493 cur->range.startPosition += left->range.length;
494 cur->range.length -= left->range.length;
495 list_add_before(&cur->entry, &left->entry);
498 done:
499 if (changed) {
500 struct list *next, *i;
502 i = list_head(ranges);
503 while ((next = list_next(ranges, i))) {
504 struct layout_range *next_range = LIST_ENTRY(next, struct layout_range, entry);
506 cur = LIST_ENTRY(i, struct layout_range, entry);
507 if (is_same_layout_attributes(cur, next_range)) {
508 /* remove similar range */
509 cur->range.length += next_range->range.length;
510 list_remove(next);
511 free_layout_range(next_range);
513 else
514 i = list_next(ranges, i);
518 return S_OK;
521 static HRESULT WINAPI dwritetextlayout_QueryInterface(IDWriteTextLayout2 *iface, REFIID riid, void **obj)
523 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
525 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
527 if (IsEqualIID(riid, &IID_IDWriteTextLayout2) ||
528 IsEqualIID(riid, &IID_IDWriteTextLayout1) ||
529 IsEqualIID(riid, &IID_IDWriteTextLayout) ||
530 IsEqualIID(riid, &IID_IDWriteTextFormat) ||
531 IsEqualIID(riid, &IID_IUnknown))
533 *obj = iface;
534 IDWriteTextLayout2_AddRef(iface);
535 return S_OK;
538 *obj = NULL;
540 return E_NOINTERFACE;
543 static ULONG WINAPI dwritetextlayout_AddRef(IDWriteTextLayout2 *iface)
545 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
546 ULONG ref = InterlockedIncrement(&This->ref);
547 TRACE("(%p)->(%d)\n", This, ref);
548 return ref;
551 static ULONG WINAPI dwritetextlayout_Release(IDWriteTextLayout2 *iface)
553 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
554 ULONG ref = InterlockedDecrement(&This->ref);
556 TRACE("(%p)->(%d)\n", This, ref);
558 if (!ref) {
559 free_layout_ranges_list(This);
560 release_format_data(&This->format);
561 heap_free(This->str);
562 heap_free(This);
565 return ref;
568 static HRESULT WINAPI dwritetextlayout_SetTextAlignment(IDWriteTextLayout2 *iface, DWRITE_TEXT_ALIGNMENT alignment)
570 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
571 FIXME("(%p)->(%d): stub\n", This, alignment);
572 return E_NOTIMPL;
575 static HRESULT WINAPI dwritetextlayout_SetParagraphAlignment(IDWriteTextLayout2 *iface, DWRITE_PARAGRAPH_ALIGNMENT alignment)
577 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
578 FIXME("(%p)->(%d): stub\n", This, alignment);
579 return E_NOTIMPL;
582 static HRESULT WINAPI dwritetextlayout_SetWordWrapping(IDWriteTextLayout2 *iface, DWRITE_WORD_WRAPPING wrapping)
584 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
585 FIXME("(%p)->(%d): stub\n", This, wrapping);
586 return E_NOTIMPL;
589 static HRESULT WINAPI dwritetextlayout_SetReadingDirection(IDWriteTextLayout2 *iface, DWRITE_READING_DIRECTION direction)
591 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
592 FIXME("(%p)->(%d): stub\n", This, direction);
593 return E_NOTIMPL;
596 static HRESULT WINAPI dwritetextlayout_SetFlowDirection(IDWriteTextLayout2 *iface, DWRITE_FLOW_DIRECTION direction)
598 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
599 FIXME("(%p)->(%d): stub\n", This, direction);
600 return E_NOTIMPL;
603 static HRESULT WINAPI dwritetextlayout_SetIncrementalTabStop(IDWriteTextLayout2 *iface, FLOAT tabstop)
605 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
606 FIXME("(%p)->(%f): stub\n", This, tabstop);
607 return E_NOTIMPL;
610 static HRESULT WINAPI dwritetextlayout_SetTrimming(IDWriteTextLayout2 *iface, DWRITE_TRIMMING const *trimming,
611 IDWriteInlineObject *trimming_sign)
613 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
614 FIXME("(%p)->(%p %p): stub\n", This, trimming, trimming_sign);
615 return E_NOTIMPL;
618 static HRESULT WINAPI dwritetextlayout_SetLineSpacing(IDWriteTextLayout2 *iface, DWRITE_LINE_SPACING_METHOD spacing,
619 FLOAT line_spacing, FLOAT baseline)
621 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
622 FIXME("(%p)->(%d %f %f): stub\n", This, spacing, line_spacing, baseline);
623 return E_NOTIMPL;
626 static DWRITE_TEXT_ALIGNMENT WINAPI dwritetextlayout_GetTextAlignment(IDWriteTextLayout2 *iface)
628 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
629 TRACE("(%p)\n", This);
630 return This->format.textalignment;
633 static DWRITE_PARAGRAPH_ALIGNMENT WINAPI dwritetextlayout_GetParagraphAlignment(IDWriteTextLayout2 *iface)
635 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
636 TRACE("(%p)\n", This);
637 return This->format.paralign;
640 static DWRITE_WORD_WRAPPING WINAPI dwritetextlayout_GetWordWrapping(IDWriteTextLayout2 *iface)
642 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
643 FIXME("(%p): stub\n", This);
644 return This->format.wrapping;
647 static DWRITE_READING_DIRECTION WINAPI dwritetextlayout_GetReadingDirection(IDWriteTextLayout2 *iface)
649 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
650 TRACE("(%p)\n", This);
651 return This->format.readingdir;
654 static DWRITE_FLOW_DIRECTION WINAPI dwritetextlayout_GetFlowDirection(IDWriteTextLayout2 *iface)
656 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
657 TRACE("(%p)\n", This);
658 return This->format.flow;
661 static FLOAT WINAPI dwritetextlayout_GetIncrementalTabStop(IDWriteTextLayout2 *iface)
663 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
664 FIXME("(%p): stub\n", This);
665 return 0.0;
668 static HRESULT WINAPI dwritetextlayout_GetTrimming(IDWriteTextLayout2 *iface, DWRITE_TRIMMING *options,
669 IDWriteInlineObject **trimming_sign)
671 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
673 TRACE("(%p)->(%p %p)\n", This, options, trimming_sign);
675 *options = This->format.trimming;
676 *trimming_sign = This->format.trimmingsign;
677 if (*trimming_sign)
678 IDWriteInlineObject_AddRef(*trimming_sign);
679 return S_OK;
682 static HRESULT WINAPI dwritetextlayout_GetLineSpacing(IDWriteTextLayout2 *iface, DWRITE_LINE_SPACING_METHOD *method,
683 FLOAT *spacing, FLOAT *baseline)
685 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
687 TRACE("(%p)->(%p %p %p)\n", This, method, spacing, baseline);
689 *method = This->format.spacingmethod;
690 *spacing = This->format.spacing;
691 *baseline = This->format.baseline;
692 return S_OK;
695 static HRESULT WINAPI dwritetextlayout_GetFontCollection(IDWriteTextLayout2 *iface, IDWriteFontCollection **collection)
697 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
699 TRACE("(%p)->(%p)\n", This, collection);
701 *collection = This->format.collection;
702 if (*collection)
703 IDWriteFontCollection_AddRef(*collection);
704 return S_OK;
707 static UINT32 WINAPI dwritetextlayout_GetFontFamilyNameLength(IDWriteTextLayout2 *iface)
709 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
710 TRACE("(%p)\n", This);
711 return This->format.family_len;
714 static HRESULT WINAPI dwritetextlayout_GetFontFamilyName(IDWriteTextLayout2 *iface, WCHAR *name, UINT32 size)
716 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
718 TRACE("(%p)->(%p %u)\n", This, name, size);
720 if (size <= This->format.family_len) return E_NOT_SUFFICIENT_BUFFER;
721 strcpyW(name, This->format.family_name);
722 return S_OK;
725 static DWRITE_FONT_WEIGHT WINAPI dwritetextlayout_GetFontWeight(IDWriteTextLayout2 *iface)
727 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
728 TRACE("(%p)\n", This);
729 return This->format.weight;
732 static DWRITE_FONT_STYLE WINAPI dwritetextlayout_GetFontStyle(IDWriteTextLayout2 *iface)
734 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
735 TRACE("(%p)\n", This);
736 return This->format.style;
739 static DWRITE_FONT_STRETCH WINAPI dwritetextlayout_GetFontStretch(IDWriteTextLayout2 *iface)
741 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
742 TRACE("(%p)\n", This);
743 return This->format.stretch;
746 static FLOAT WINAPI dwritetextlayout_GetFontSize(IDWriteTextLayout2 *iface)
748 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
749 TRACE("(%p)\n", This);
750 return This->format.fontsize;
753 static UINT32 WINAPI dwritetextlayout_GetLocaleNameLength(IDWriteTextLayout2 *iface)
755 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
756 TRACE("(%p)\n", This);
757 return This->format.locale_len;
760 static HRESULT WINAPI dwritetextlayout_GetLocaleName(IDWriteTextLayout2 *iface, WCHAR *name, UINT32 size)
762 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
764 TRACE("(%p)->(%p %u)\n", This, name, size);
766 if (size <= This->format.locale_len) return E_NOT_SUFFICIENT_BUFFER;
767 strcpyW(name, This->format.locale);
768 return S_OK;
771 static HRESULT WINAPI dwritetextlayout_SetMaxWidth(IDWriteTextLayout2 *iface, FLOAT maxWidth)
773 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
774 TRACE("(%p)->(%.1f)\n", This, maxWidth);
776 if (maxWidth < 0.0)
777 return E_INVALIDARG;
779 This->maxwidth = maxWidth;
780 return S_OK;
783 static HRESULT WINAPI dwritetextlayout_SetMaxHeight(IDWriteTextLayout2 *iface, FLOAT maxHeight)
785 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
786 TRACE("(%p)->(%.1f)\n", This, maxHeight);
788 if (maxHeight < 0.0)
789 return E_INVALIDARG;
791 This->maxheight = maxHeight;
792 return S_OK;
795 static HRESULT WINAPI dwritetextlayout_SetFontCollection(IDWriteTextLayout2 *iface, IDWriteFontCollection* collection, DWRITE_TEXT_RANGE range)
797 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
798 struct layout_range_attr_value value;
800 TRACE("(%p)->(%p %s)\n", This, collection, debugstr_range(&range));
802 if (!validate_text_range(This, &range))
803 return S_OK;
805 value.range = range;
806 value.u.collection = collection;
807 return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_FONTCOLL, &value);
810 static HRESULT WINAPI dwritetextlayout_SetFontFamilyName(IDWriteTextLayout2 *iface, WCHAR const *name, DWRITE_TEXT_RANGE range)
812 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
813 FIXME("(%p)->(%s %s): stub\n", This, debugstr_w(name), debugstr_range(&range));
814 return E_NOTIMPL;
817 static HRESULT WINAPI dwritetextlayout_SetFontWeight(IDWriteTextLayout2 *iface, DWRITE_FONT_WEIGHT weight, DWRITE_TEXT_RANGE range)
819 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
820 struct layout_range_attr_value value;
822 TRACE("(%p)->(%d %s)\n", This, weight, debugstr_range(&range));
824 if (!validate_text_range(This, &range))
825 return S_OK;
827 value.range = range;
828 value.u.weight = weight;
829 return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_WEIGHT, &value);
832 static HRESULT WINAPI dwritetextlayout_SetFontStyle(IDWriteTextLayout2 *iface, DWRITE_FONT_STYLE style, DWRITE_TEXT_RANGE range)
834 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
835 struct layout_range_attr_value value;
837 TRACE("(%p)->(%d %s)\n", This, style, debugstr_range(&range));
839 if (!validate_text_range(This, &range))
840 return S_OK;
842 value.range = range;
843 value.u.style = style;
844 return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_STYLE, &value);
847 static HRESULT WINAPI dwritetextlayout_SetFontStretch(IDWriteTextLayout2 *iface, DWRITE_FONT_STRETCH stretch, DWRITE_TEXT_RANGE range)
849 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
850 struct layout_range_attr_value value;
852 TRACE("(%p)->(%d %s)\n", This, stretch, debugstr_range(&range));
854 if (!validate_text_range(This, &range))
855 return S_OK;
857 value.range = range;
858 value.u.stretch = stretch;
859 return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_STRETCH, &value);
862 static HRESULT WINAPI dwritetextlayout_SetFontSize(IDWriteTextLayout2 *iface, FLOAT size, DWRITE_TEXT_RANGE range)
864 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
865 struct layout_range_attr_value value;
867 TRACE("(%p)->(%.2f %s)\n", This, size, debugstr_range(&range));
869 if (!validate_text_range(This, &range))
870 return S_OK;
872 value.range = range;
873 value.u.fontsize = size;
874 return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_FONTSIZE, &value);
877 static HRESULT WINAPI dwritetextlayout_SetUnderline(IDWriteTextLayout2 *iface, BOOL underline, DWRITE_TEXT_RANGE range)
879 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
880 struct layout_range_attr_value value;
882 TRACE("(%p)->(%d %s)\n", This, underline, debugstr_range(&range));
884 if (!validate_text_range(This, &range))
885 return S_OK;
887 value.range = range;
888 value.u.underline = underline;
889 return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_UNDERLINE, &value);
892 static HRESULT WINAPI dwritetextlayout_SetStrikethrough(IDWriteTextLayout2 *iface, BOOL strikethrough, DWRITE_TEXT_RANGE range)
894 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
895 struct layout_range_attr_value value;
897 TRACE("(%p)->(%d %s)\n", This, strikethrough, debugstr_range(&range));
899 if (!validate_text_range(This, &range))
900 return S_OK;
902 value.range = range;
903 value.u.underline = strikethrough;
904 return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_STRIKETHROUGH, &value);
907 static HRESULT WINAPI dwritetextlayout_SetDrawingEffect(IDWriteTextLayout2 *iface, IUnknown* effect, DWRITE_TEXT_RANGE range)
909 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
910 struct layout_range_attr_value value;
912 TRACE("(%p)->(%p %s)\n", This, effect, debugstr_range(&range));
914 if (!validate_text_range(This, &range))
915 return S_OK;
917 value.range = range;
918 value.u.effect = effect;
919 return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_EFFECT, &value);
922 static HRESULT WINAPI dwritetextlayout_SetInlineObject(IDWriteTextLayout2 *iface, IDWriteInlineObject *object, DWRITE_TEXT_RANGE r)
924 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
925 struct layout_range_attr_value attr;
927 TRACE("(%p)->(%p %s)\n", This, object, debugstr_range(&r));
929 if (!validate_text_range(This, &r))
930 return S_OK;
932 attr.range = r;
933 attr.u.object = object;
935 return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_INLINE, &attr);
938 static HRESULT WINAPI dwritetextlayout_SetTypography(IDWriteTextLayout2 *iface, IDWriteTypography* typography, DWRITE_TEXT_RANGE range)
940 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
941 FIXME("(%p)->(%p %s): stub\n", This, typography, debugstr_range(&range));
942 return E_NOTIMPL;
945 static HRESULT WINAPI dwritetextlayout_SetLocaleName(IDWriteTextLayout2 *iface, WCHAR const* locale, DWRITE_TEXT_RANGE range)
947 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
948 FIXME("(%p)->(%s %s): stub\n", This, debugstr_w(locale), debugstr_range(&range));
949 return E_NOTIMPL;
952 static FLOAT WINAPI dwritetextlayout_GetMaxWidth(IDWriteTextLayout2 *iface)
954 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
955 TRACE("(%p)\n", This);
956 return This->maxwidth;
959 static FLOAT WINAPI dwritetextlayout_GetMaxHeight(IDWriteTextLayout2 *iface)
961 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
962 TRACE("(%p)\n", This);
963 return This->maxheight;
966 static HRESULT WINAPI dwritetextlayout_layout_GetFontCollection(IDWriteTextLayout2 *iface, UINT32 position,
967 IDWriteFontCollection** collection, DWRITE_TEXT_RANGE *r)
969 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
970 struct layout_range *range;
972 TRACE("(%p)->(%u %p %p)\n", This, position, collection, r);
974 range = get_layout_range_by_pos(This, position);
975 *collection = range ? range->collection : NULL;
976 if (*collection)
977 IDWriteFontCollection_AddRef(*collection);
979 return return_range(range, r);
982 static HRESULT WINAPI dwritetextlayout_layout_GetFontFamilyNameLength(IDWriteTextLayout2 *iface,
983 UINT32 pos, UINT32* len, DWRITE_TEXT_RANGE *range)
985 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
986 FIXME("(%p)->(%d %p %p): stub\n", This, pos, len, range);
987 return E_NOTIMPL;
990 static HRESULT WINAPI dwritetextlayout_layout_GetFontFamilyName(IDWriteTextLayout2 *iface,
991 UINT32 position, WCHAR* name, UINT32 name_size, DWRITE_TEXT_RANGE *range)
993 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
994 FIXME("(%p)->(%u %p %u %p): stub\n", This, position, name, name_size, range);
995 return E_NOTIMPL;
998 static HRESULT WINAPI dwritetextlayout_layout_GetFontWeight(IDWriteTextLayout2 *iface,
999 UINT32 position, DWRITE_FONT_WEIGHT *weight, DWRITE_TEXT_RANGE *r)
1001 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1002 struct layout_range *range;
1004 TRACE("(%p)->(%u %p %p)\n", This, position, weight, r);
1006 if (position >= This->len)
1007 return S_OK;
1009 range = get_layout_range_by_pos(This, position);
1010 *weight = range->weight;
1012 return return_range(range, r);
1015 static HRESULT WINAPI dwritetextlayout_layout_GetFontStyle(IDWriteTextLayout2 *iface,
1016 UINT32 position, DWRITE_FONT_STYLE *style, DWRITE_TEXT_RANGE *r)
1018 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1019 struct layout_range *range;
1021 TRACE("(%p)->(%u %p %p)\n", This, position, style, r);
1023 if (position >= This->len)
1024 return S_OK;
1026 range = get_layout_range_by_pos(This, position);
1027 *style = range->style;
1029 return return_range(range, r);
1032 static HRESULT WINAPI dwritetextlayout_layout_GetFontStretch(IDWriteTextLayout2 *iface,
1033 UINT32 position, DWRITE_FONT_STRETCH *stretch, DWRITE_TEXT_RANGE *r)
1035 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1036 struct layout_range *range;
1038 TRACE("(%p)->(%u %p %p)\n", This, position, stretch, r);
1040 if (position >= This->len)
1041 return S_OK;
1043 range = get_layout_range_by_pos(This, position);
1044 *stretch = range->stretch;
1046 return return_range(range, r);
1049 static HRESULT WINAPI dwritetextlayout_layout_GetFontSize(IDWriteTextLayout2 *iface,
1050 UINT32 position, FLOAT *size, DWRITE_TEXT_RANGE *r)
1052 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1053 struct layout_range *range;
1055 TRACE("(%p)->(%u %p %p)\n", This, position, size, r);
1057 if (position >= This->len)
1058 return S_OK;
1060 range = get_layout_range_by_pos(This, position);
1061 *size = range->fontsize;
1063 return return_range(range, r);
1066 static HRESULT WINAPI dwritetextlayout_GetUnderline(IDWriteTextLayout2 *iface,
1067 UINT32 position, BOOL *underline, DWRITE_TEXT_RANGE *r)
1069 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1070 struct layout_range *range;
1072 TRACE("(%p)->(%u %p %p)\n", This, position, underline, r);
1074 if (position >= This->len)
1075 return S_OK;
1077 range = get_layout_range_by_pos(This, position);
1078 *underline = range->underline;
1080 return return_range(range, r);
1083 static HRESULT WINAPI dwritetextlayout_GetStrikethrough(IDWriteTextLayout2 *iface,
1084 UINT32 position, BOOL *strikethrough, DWRITE_TEXT_RANGE *r)
1086 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1087 struct layout_range *range;
1089 TRACE("(%p)->(%u %p %p)\n", This, position, strikethrough, r);
1091 if (position >= This->len)
1092 return S_OK;
1094 range = get_layout_range_by_pos(This, position);
1095 *strikethrough = range->strikethrough;
1097 return return_range(range, r);
1100 static HRESULT WINAPI dwritetextlayout_GetDrawingEffect(IDWriteTextLayout2 *iface,
1101 UINT32 position, IUnknown **effect, DWRITE_TEXT_RANGE *r)
1103 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1104 struct layout_range *range;
1106 TRACE("(%p)->(%u %p %p)\n", This, position, effect, r);
1108 if (position >= This->len)
1109 return S_OK;
1111 range = get_layout_range_by_pos(This, position);
1112 *effect = range->effect;
1113 if (*effect)
1114 IUnknown_AddRef(*effect);
1116 return return_range(range, r);
1119 static HRESULT WINAPI dwritetextlayout_GetInlineObject(IDWriteTextLayout2 *iface,
1120 UINT32 position, IDWriteInlineObject **object, DWRITE_TEXT_RANGE *r)
1122 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1123 struct layout_range *range;
1125 TRACE("(%p)->(%u %p %p)\n", This, position, object, r);
1127 range = get_layout_range_by_pos(This, position);
1128 *object = range ? range->object : NULL;
1129 if (*object)
1130 IDWriteInlineObject_AddRef(*object);
1132 return return_range(range, r);
1135 static HRESULT WINAPI dwritetextlayout_GetTypography(IDWriteTextLayout2 *iface,
1136 UINT32 position, IDWriteTypography** typography, DWRITE_TEXT_RANGE *range)
1138 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1139 FIXME("(%p)->(%u %p %p): stub\n", This, position, typography, range);
1140 return E_NOTIMPL;
1143 static HRESULT WINAPI dwritetextlayout_layout_GetLocaleNameLength(IDWriteTextLayout2 *iface,
1144 UINT32 position, UINT32* length, DWRITE_TEXT_RANGE *range)
1146 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1147 FIXME("(%p)->(%u %p %p): stub\n", This, position, length, range);
1148 return E_NOTIMPL;
1151 static HRESULT WINAPI dwritetextlayout_layout_GetLocaleName(IDWriteTextLayout2 *iface,
1152 UINT32 position, WCHAR* name, UINT32 name_size, DWRITE_TEXT_RANGE *range)
1154 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1155 FIXME("(%p)->(%u %p %u %p): stub\n", This, position, name, name_size, range);
1156 return E_NOTIMPL;
1159 static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
1160 void *context, IDWriteTextRenderer* renderer, FLOAT originX, FLOAT originY)
1162 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1163 FIXME("(%p)->(%p %p %f %f): stub\n", This, context, renderer, originX, originY);
1164 return E_NOTIMPL;
1167 static HRESULT WINAPI dwritetextlayout_GetLineMetrics(IDWriteTextLayout2 *iface,
1168 DWRITE_LINE_METRICS *metrics, UINT32 max_count, UINT32 *actual_count)
1170 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1171 FIXME("(%p)->(%p %u %p): stub\n", This, metrics, max_count, actual_count);
1172 return E_NOTIMPL;
1175 static HRESULT WINAPI dwritetextlayout_GetMetrics(IDWriteTextLayout2 *iface, DWRITE_TEXT_METRICS *metrics)
1177 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1178 FIXME("(%p)->(%p): stub\n", This, metrics);
1179 return E_NOTIMPL;
1182 static HRESULT WINAPI dwritetextlayout_GetOverhangMetrics(IDWriteTextLayout2 *iface, DWRITE_OVERHANG_METRICS *overhangs)
1184 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1185 FIXME("(%p)->(%p): stub\n", This, overhangs);
1186 return E_NOTIMPL;
1189 static HRESULT WINAPI dwritetextlayout_GetClusterMetrics(IDWriteTextLayout2 *iface,
1190 DWRITE_CLUSTER_METRICS *metrics, UINT32 max_count, UINT32* act_count)
1192 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1193 FIXME("(%p)->(%p %u %p): stub\n", This, metrics, max_count, act_count);
1194 return E_NOTIMPL;
1197 static HRESULT WINAPI dwritetextlayout_DetermineMinWidth(IDWriteTextLayout2 *iface, FLOAT* min_width)
1199 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1200 FIXME("(%p)->(%p): stub\n", This, min_width);
1201 return E_NOTIMPL;
1204 static HRESULT WINAPI dwritetextlayout_HitTestPoint(IDWriteTextLayout2 *iface,
1205 FLOAT pointX, FLOAT pointY, BOOL* is_trailinghit, BOOL* is_inside, DWRITE_HIT_TEST_METRICS *metrics)
1207 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1208 FIXME("(%p)->(%f %f %p %p %p): stub\n", This, pointX, pointY, is_trailinghit, is_inside, metrics);
1209 return E_NOTIMPL;
1212 static HRESULT WINAPI dwritetextlayout_HitTestTextPosition(IDWriteTextLayout2 *iface,
1213 UINT32 textPosition, BOOL is_trailinghit, FLOAT* pointX, FLOAT* pointY, DWRITE_HIT_TEST_METRICS *metrics)
1215 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1216 FIXME("(%p)->(%u %d %p %p %p): stub\n", This, textPosition, is_trailinghit, pointX, pointY, metrics);
1217 return E_NOTIMPL;
1220 static HRESULT WINAPI dwritetextlayout_HitTestTextRange(IDWriteTextLayout2 *iface,
1221 UINT32 textPosition, UINT32 textLength, FLOAT originX, FLOAT originY,
1222 DWRITE_HIT_TEST_METRICS *metrics, UINT32 max_metricscount, UINT32* actual_metricscount)
1224 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1225 FIXME("(%p)->(%u %u %f %f %p %u %p): stub\n", This, textPosition, textLength, originX, originY, metrics,
1226 max_metricscount, actual_metricscount);
1227 return E_NOTIMPL;
1230 static HRESULT WINAPI dwritetextlayout1_SetPairKerning(IDWriteTextLayout2 *iface, BOOL is_pairkerning_enabled,
1231 DWRITE_TEXT_RANGE range)
1233 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1234 FIXME("(%p)->(%d %s): stub\n", This, is_pairkerning_enabled, debugstr_range(&range));
1235 return E_NOTIMPL;
1238 static HRESULT WINAPI dwritetextlayout1_GetPairKerning(IDWriteTextLayout2 *iface, UINT32 position, BOOL *is_pairkerning_enabled,
1239 DWRITE_TEXT_RANGE *range)
1241 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1242 FIXME("(%p)->(%p %p): stub\n", This, is_pairkerning_enabled, range);
1243 return E_NOTIMPL;
1246 static HRESULT WINAPI dwritetextlayout1_SetCharacterSpacing(IDWriteTextLayout2 *iface, FLOAT leading_spacing, FLOAT trailing_spacing,
1247 FLOAT minimum_advance_width, DWRITE_TEXT_RANGE range)
1249 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1250 FIXME("(%p)->(%f %f %f %s): stub\n", This, leading_spacing, trailing_spacing, minimum_advance_width, debugstr_range(&range));
1251 return E_NOTIMPL;
1254 static HRESULT WINAPI dwritetextlayout1_GetCharacterSpacing(IDWriteTextLayout2 *iface, UINT32 position, FLOAT* leading_spacing,
1255 FLOAT* trailing_spacing, FLOAT* minimum_advance_width, DWRITE_TEXT_RANGE *range)
1257 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1258 FIXME("(%p)->(%u %p %p %p %p): stub\n", This, position, leading_spacing, trailing_spacing, minimum_advance_width, range);
1259 return E_NOTIMPL;
1262 static HRESULT WINAPI dwritetextlayout2_GetMetrics(IDWriteTextLayout2 *iface, DWRITE_TEXT_METRICS1 *metrics)
1264 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1265 FIXME("(%p)->(%p): stub\n", This, metrics);
1266 return E_NOTIMPL;
1269 static HRESULT WINAPI dwritetextlayout2_SetVerticalGlyphOrientation(IDWriteTextLayout2 *iface, DWRITE_VERTICAL_GLYPH_ORIENTATION orientation)
1271 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1272 FIXME("(%p)->(%d): stub\n", This, orientation);
1273 return E_NOTIMPL;
1276 static DWRITE_VERTICAL_GLYPH_ORIENTATION WINAPI dwritetextlayout2_GetVerticalGlyphOrientation(IDWriteTextLayout2 *iface)
1278 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1279 FIXME("(%p): stub\n", This);
1280 return DWRITE_VERTICAL_GLYPH_ORIENTATION_DEFAULT;
1283 static HRESULT WINAPI dwritetextlayout2_SetLastLineWrapping(IDWriteTextLayout2 *iface, BOOL lastline_wrapping_enabled)
1285 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1286 FIXME("(%p)->(%d): stub\n", This, lastline_wrapping_enabled);
1287 return E_NOTIMPL;
1290 static BOOL WINAPI dwritetextlayout2_GetLastLineWrapping(IDWriteTextLayout2 *iface)
1292 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1293 FIXME("(%p): stub\n", This);
1294 return FALSE;
1297 static HRESULT WINAPI dwritetextlayout2_SetOpticalAlignment(IDWriteTextLayout2 *iface, DWRITE_OPTICAL_ALIGNMENT alignment)
1299 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1300 FIXME("(%p)->(%d): stub\n", This, alignment);
1301 return E_NOTIMPL;
1304 static DWRITE_OPTICAL_ALIGNMENT WINAPI dwritetextlayout2_GetOpticalAlignment(IDWriteTextLayout2 *iface)
1306 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1307 FIXME("(%p): stub\n", This);
1308 return DWRITE_OPTICAL_ALIGNMENT_NONE;
1311 static HRESULT WINAPI dwritetextlayout2_SetFontFallback(IDWriteTextLayout2 *iface, IDWriteFontFallback *fallback)
1313 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1314 FIXME("(%p)->(%p): stub\n", This, fallback);
1315 return E_NOTIMPL;
1318 static HRESULT WINAPI dwritetextlayout2_GetFontFallback(IDWriteTextLayout2 *iface, IDWriteFontFallback **fallback)
1320 struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
1321 FIXME("(%p)->(%p): stub\n", This, fallback);
1322 return E_NOTIMPL;
1325 static const IDWriteTextLayout2Vtbl dwritetextlayoutvtbl = {
1326 dwritetextlayout_QueryInterface,
1327 dwritetextlayout_AddRef,
1328 dwritetextlayout_Release,
1329 dwritetextlayout_SetTextAlignment,
1330 dwritetextlayout_SetParagraphAlignment,
1331 dwritetextlayout_SetWordWrapping,
1332 dwritetextlayout_SetReadingDirection,
1333 dwritetextlayout_SetFlowDirection,
1334 dwritetextlayout_SetIncrementalTabStop,
1335 dwritetextlayout_SetTrimming,
1336 dwritetextlayout_SetLineSpacing,
1337 dwritetextlayout_GetTextAlignment,
1338 dwritetextlayout_GetParagraphAlignment,
1339 dwritetextlayout_GetWordWrapping,
1340 dwritetextlayout_GetReadingDirection,
1341 dwritetextlayout_GetFlowDirection,
1342 dwritetextlayout_GetIncrementalTabStop,
1343 dwritetextlayout_GetTrimming,
1344 dwritetextlayout_GetLineSpacing,
1345 dwritetextlayout_GetFontCollection,
1346 dwritetextlayout_GetFontFamilyNameLength,
1347 dwritetextlayout_GetFontFamilyName,
1348 dwritetextlayout_GetFontWeight,
1349 dwritetextlayout_GetFontStyle,
1350 dwritetextlayout_GetFontStretch,
1351 dwritetextlayout_GetFontSize,
1352 dwritetextlayout_GetLocaleNameLength,
1353 dwritetextlayout_GetLocaleName,
1354 dwritetextlayout_SetMaxWidth,
1355 dwritetextlayout_SetMaxHeight,
1356 dwritetextlayout_SetFontCollection,
1357 dwritetextlayout_SetFontFamilyName,
1358 dwritetextlayout_SetFontWeight,
1359 dwritetextlayout_SetFontStyle,
1360 dwritetextlayout_SetFontStretch,
1361 dwritetextlayout_SetFontSize,
1362 dwritetextlayout_SetUnderline,
1363 dwritetextlayout_SetStrikethrough,
1364 dwritetextlayout_SetDrawingEffect,
1365 dwritetextlayout_SetInlineObject,
1366 dwritetextlayout_SetTypography,
1367 dwritetextlayout_SetLocaleName,
1368 dwritetextlayout_GetMaxWidth,
1369 dwritetextlayout_GetMaxHeight,
1370 dwritetextlayout_layout_GetFontCollection,
1371 dwritetextlayout_layout_GetFontFamilyNameLength,
1372 dwritetextlayout_layout_GetFontFamilyName,
1373 dwritetextlayout_layout_GetFontWeight,
1374 dwritetextlayout_layout_GetFontStyle,
1375 dwritetextlayout_layout_GetFontStretch,
1376 dwritetextlayout_layout_GetFontSize,
1377 dwritetextlayout_GetUnderline,
1378 dwritetextlayout_GetStrikethrough,
1379 dwritetextlayout_GetDrawingEffect,
1380 dwritetextlayout_GetInlineObject,
1381 dwritetextlayout_GetTypography,
1382 dwritetextlayout_layout_GetLocaleNameLength,
1383 dwritetextlayout_layout_GetLocaleName,
1384 dwritetextlayout_Draw,
1385 dwritetextlayout_GetLineMetrics,
1386 dwritetextlayout_GetMetrics,
1387 dwritetextlayout_GetOverhangMetrics,
1388 dwritetextlayout_GetClusterMetrics,
1389 dwritetextlayout_DetermineMinWidth,
1390 dwritetextlayout_HitTestPoint,
1391 dwritetextlayout_HitTestTextPosition,
1392 dwritetextlayout_HitTestTextRange,
1393 dwritetextlayout1_SetPairKerning,
1394 dwritetextlayout1_GetPairKerning,
1395 dwritetextlayout1_SetCharacterSpacing,
1396 dwritetextlayout1_GetCharacterSpacing,
1397 dwritetextlayout2_GetMetrics,
1398 dwritetextlayout2_SetVerticalGlyphOrientation,
1399 dwritetextlayout2_GetVerticalGlyphOrientation,
1400 dwritetextlayout2_SetLastLineWrapping,
1401 dwritetextlayout2_GetLastLineWrapping,
1402 dwritetextlayout2_SetOpticalAlignment,
1403 dwritetextlayout2_GetOpticalAlignment,
1404 dwritetextlayout2_SetFontFallback,
1405 dwritetextlayout2_GetFontFallback
1408 static void layout_format_from_textformat(struct dwrite_textlayout *layout, IDWriteTextFormat *format)
1410 struct dwrite_textformat *f;
1412 memset(&layout->format, 0, sizeof(layout->format));
1414 if ((f = unsafe_impl_from_IDWriteTextFormat1((IDWriteTextFormat1*)format)))
1416 layout->format = f->format;
1417 layout->format.locale = heap_strdupW(f->format.locale);
1418 layout->format.family_name = heap_strdupW(f->format.family_name);
1419 if (layout->format.trimmingsign)
1420 IDWriteInlineObject_AddRef(layout->format.trimmingsign);
1422 else
1424 UINT32 locale_len, family_len;
1426 layout->format.weight = IDWriteTextFormat_GetFontWeight(format);
1427 layout->format.style = IDWriteTextFormat_GetFontStyle(format);
1428 layout->format.stretch = IDWriteTextFormat_GetFontStretch(format);
1429 layout->format.fontsize= IDWriteTextFormat_GetFontSize(format);
1430 layout->format.textalignment = IDWriteTextFormat_GetTextAlignment(format);
1431 layout->format.paralign = IDWriteTextFormat_GetParagraphAlignment(format);
1432 layout->format.wrapping = IDWriteTextFormat_GetWordWrapping(format);
1433 layout->format.readingdir = IDWriteTextFormat_GetReadingDirection(format);
1434 layout->format.flow = IDWriteTextFormat_GetFlowDirection(format);
1435 IDWriteTextFormat_GetLineSpacing(format,
1436 &layout->format.spacingmethod,
1437 &layout->format.spacing,
1438 &layout->format.baseline
1440 IDWriteTextFormat_GetTrimming(format, &layout->format.trimming, &layout->format.trimmingsign);
1442 /* locale name and length */
1443 locale_len = IDWriteTextFormat_GetLocaleNameLength(format);
1444 layout->format.locale = heap_alloc((locale_len+1)*sizeof(WCHAR));
1445 IDWriteTextFormat_GetLocaleName(format, layout->format.locale, locale_len+1);
1446 layout->format.locale_len = locale_len;
1448 /* font family name and length */
1449 family_len = IDWriteTextFormat_GetFontFamilyNameLength(format);
1450 layout->format.family_name = heap_alloc((family_len+1)*sizeof(WCHAR));
1451 IDWriteTextFormat_GetFontFamilyName(format, layout->format.family_name, family_len+1);
1452 layout->format.family_len = family_len;
1455 IDWriteTextFormat_GetFontCollection(format, &layout->format.collection);
1458 HRESULT create_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, IDWriteTextLayout **layout)
1460 struct dwrite_textlayout *This;
1461 struct layout_range *range;
1462 DWRITE_TEXT_RANGE r = { 0, len };
1464 *layout = NULL;
1466 This = heap_alloc(sizeof(struct dwrite_textlayout));
1467 if (!This) return E_OUTOFMEMORY;
1469 This->IDWriteTextLayout2_iface.lpVtbl = &dwritetextlayoutvtbl;
1470 This->ref = 1;
1471 This->str = heap_strdupnW(str, len);
1472 This->len = len;
1473 This->maxwidth = maxwidth;
1474 This->maxheight = maxheight;
1475 layout_format_from_textformat(This, format);
1477 list_init(&This->ranges);
1478 range = alloc_layout_range(This, &r);
1479 if (!range) {
1480 IDWriteTextLayout2_Release(&This->IDWriteTextLayout2_iface);
1481 return E_OUTOFMEMORY;
1483 list_add_head(&This->ranges, &range->entry);
1485 *layout = (IDWriteTextLayout*)&This->IDWriteTextLayout2_iface;
1487 return S_OK;
1490 static HRESULT WINAPI dwritetrimmingsign_QueryInterface(IDWriteInlineObject *iface, REFIID riid, void **obj)
1492 struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
1494 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
1496 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteInlineObject)) {
1497 *obj = iface;
1498 IDWriteInlineObject_AddRef(iface);
1499 return S_OK;
1502 *obj = NULL;
1503 return E_NOINTERFACE;
1507 static ULONG WINAPI dwritetrimmingsign_AddRef(IDWriteInlineObject *iface)
1509 struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
1510 ULONG ref = InterlockedIncrement(&This->ref);
1511 TRACE("(%p)->(%d)\n", This, ref);
1512 return ref;
1515 static ULONG WINAPI dwritetrimmingsign_Release(IDWriteInlineObject *iface)
1517 struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
1518 ULONG ref = InterlockedDecrement(&This->ref);
1520 TRACE("(%p)->(%d)\n", This, ref);
1522 if (!ref)
1523 heap_free(This);
1525 return ref;
1528 static HRESULT WINAPI dwritetrimmingsign_Draw(IDWriteInlineObject *iface, void *context, IDWriteTextRenderer *renderer,
1529 FLOAT originX, FLOAT originY, BOOL is_sideways, BOOL is_rtl, IUnknown *drawing_effect)
1531 struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
1532 FIXME("(%p)->(%p %p %f %f %d %d %p): stub\n", This, context, renderer, originX, originY, is_sideways, is_rtl, drawing_effect);
1533 return E_NOTIMPL;
1536 static HRESULT WINAPI dwritetrimmingsign_GetMetrics(IDWriteInlineObject *iface, DWRITE_INLINE_OBJECT_METRICS *metrics)
1538 struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
1539 FIXME("(%p)->(%p): stub\n", This, metrics);
1540 return E_NOTIMPL;
1543 static HRESULT WINAPI dwritetrimmingsign_GetOverhangMetrics(IDWriteInlineObject *iface, DWRITE_OVERHANG_METRICS *overhangs)
1545 struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
1546 FIXME("(%p)->(%p): stub\n", This, overhangs);
1547 return E_NOTIMPL;
1550 static HRESULT WINAPI dwritetrimmingsign_GetBreakConditions(IDWriteInlineObject *iface, DWRITE_BREAK_CONDITION *before,
1551 DWRITE_BREAK_CONDITION *after)
1553 struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
1555 TRACE("(%p)->(%p %p)\n", This, before, after);
1557 *before = *after = DWRITE_BREAK_CONDITION_NEUTRAL;
1558 return S_OK;
1561 static const IDWriteInlineObjectVtbl dwritetrimmingsignvtbl = {
1562 dwritetrimmingsign_QueryInterface,
1563 dwritetrimmingsign_AddRef,
1564 dwritetrimmingsign_Release,
1565 dwritetrimmingsign_Draw,
1566 dwritetrimmingsign_GetMetrics,
1567 dwritetrimmingsign_GetOverhangMetrics,
1568 dwritetrimmingsign_GetBreakConditions
1571 HRESULT create_trimmingsign(IDWriteInlineObject **sign)
1573 struct dwrite_trimmingsign *This;
1575 *sign = NULL;
1577 This = heap_alloc(sizeof(struct dwrite_trimmingsign));
1578 if (!This) return E_OUTOFMEMORY;
1580 This->IDWriteInlineObject_iface.lpVtbl = &dwritetrimmingsignvtbl;
1581 This->ref = 1;
1583 *sign = &This->IDWriteInlineObject_iface;
1585 return S_OK;
1588 static HRESULT WINAPI dwritetextformat_QueryInterface(IDWriteTextFormat1 *iface, REFIID riid, void **obj)
1590 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1592 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
1594 if (IsEqualIID(riid, &IID_IDWriteTextFormat1) ||
1595 IsEqualIID(riid, &IID_IDWriteTextFormat) ||
1596 IsEqualIID(riid, &IID_IUnknown))
1598 *obj = iface;
1599 IDWriteTextFormat1_AddRef(iface);
1600 return S_OK;
1603 *obj = NULL;
1605 return E_NOINTERFACE;
1608 static ULONG WINAPI dwritetextformat_AddRef(IDWriteTextFormat1 *iface)
1610 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1611 ULONG ref = InterlockedIncrement(&This->ref);
1612 TRACE("(%p)->(%d)\n", This, ref);
1613 return ref;
1616 static ULONG WINAPI dwritetextformat_Release(IDWriteTextFormat1 *iface)
1618 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1619 ULONG ref = InterlockedDecrement(&This->ref);
1621 TRACE("(%p)->(%d)\n", This, ref);
1623 if (!ref)
1625 release_format_data(&This->format);
1626 heap_free(This);
1629 return ref;
1632 static HRESULT WINAPI dwritetextformat_SetTextAlignment(IDWriteTextFormat1 *iface, DWRITE_TEXT_ALIGNMENT alignment)
1634 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1635 TRACE("(%p)->(%d)\n", This, alignment);
1636 This->format.textalignment = alignment;
1637 return S_OK;
1640 static HRESULT WINAPI dwritetextformat_SetParagraphAlignment(IDWriteTextFormat1 *iface, DWRITE_PARAGRAPH_ALIGNMENT alignment)
1642 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1643 TRACE("(%p)->(%d)\n", This, alignment);
1644 This->format.paralign = alignment;
1645 return S_OK;
1648 static HRESULT WINAPI dwritetextformat_SetWordWrapping(IDWriteTextFormat1 *iface, DWRITE_WORD_WRAPPING wrapping)
1650 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1651 TRACE("(%p)->(%d)\n", This, wrapping);
1652 This->format.wrapping = wrapping;
1653 return S_OK;
1656 static HRESULT WINAPI dwritetextformat_SetReadingDirection(IDWriteTextFormat1 *iface, DWRITE_READING_DIRECTION direction)
1658 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1659 TRACE("(%p)->(%d)\n", This, direction);
1660 This->format.readingdir = direction;
1661 return S_OK;
1664 static HRESULT WINAPI dwritetextformat_SetFlowDirection(IDWriteTextFormat1 *iface, DWRITE_FLOW_DIRECTION direction)
1666 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1667 TRACE("(%p)->(%d)\n", This, direction);
1668 This->format.flow = direction;
1669 return S_OK;
1672 static HRESULT WINAPI dwritetextformat_SetIncrementalTabStop(IDWriteTextFormat1 *iface, FLOAT tabstop)
1674 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1675 FIXME("(%p)->(%f): stub\n", This, tabstop);
1676 return E_NOTIMPL;
1679 static HRESULT WINAPI dwritetextformat_SetTrimming(IDWriteTextFormat1 *iface, DWRITE_TRIMMING const *trimming,
1680 IDWriteInlineObject *trimming_sign)
1682 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1683 TRACE("(%p)->(%p %p)\n", This, trimming, trimming_sign);
1685 This->format.trimming = *trimming;
1686 if (This->format.trimmingsign)
1687 IDWriteInlineObject_Release(This->format.trimmingsign);
1688 This->format.trimmingsign = trimming_sign;
1689 if (This->format.trimmingsign)
1690 IDWriteInlineObject_AddRef(This->format.trimmingsign);
1691 return S_OK;
1694 static HRESULT WINAPI dwritetextformat_SetLineSpacing(IDWriteTextFormat1 *iface, DWRITE_LINE_SPACING_METHOD method,
1695 FLOAT spacing, FLOAT baseline)
1697 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1698 TRACE("(%p)->(%d %f %f)\n", This, method, spacing, baseline);
1699 This->format.spacingmethod = method;
1700 This->format.spacing = spacing;
1701 This->format.baseline = baseline;
1702 return S_OK;
1705 static DWRITE_TEXT_ALIGNMENT WINAPI dwritetextformat_GetTextAlignment(IDWriteTextFormat1 *iface)
1707 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1708 TRACE("(%p)\n", This);
1709 return This->format.textalignment;
1712 static DWRITE_PARAGRAPH_ALIGNMENT WINAPI dwritetextformat_GetParagraphAlignment(IDWriteTextFormat1 *iface)
1714 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1715 TRACE("(%p)\n", This);
1716 return This->format.paralign;
1719 static DWRITE_WORD_WRAPPING WINAPI dwritetextformat_GetWordWrapping(IDWriteTextFormat1 *iface)
1721 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1722 TRACE("(%p)\n", This);
1723 return This->format.wrapping;
1726 static DWRITE_READING_DIRECTION WINAPI dwritetextformat_GetReadingDirection(IDWriteTextFormat1 *iface)
1728 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1729 TRACE("(%p)\n", This);
1730 return This->format.readingdir;
1733 static DWRITE_FLOW_DIRECTION WINAPI dwritetextformat_GetFlowDirection(IDWriteTextFormat1 *iface)
1735 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1736 TRACE("(%p)\n", This);
1737 return This->format.flow;
1740 static FLOAT WINAPI dwritetextformat_GetIncrementalTabStop(IDWriteTextFormat1 *iface)
1742 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1743 FIXME("(%p): stub\n", This);
1744 return 0.0;
1747 static HRESULT WINAPI dwritetextformat_GetTrimming(IDWriteTextFormat1 *iface, DWRITE_TRIMMING *options,
1748 IDWriteInlineObject **trimming_sign)
1750 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1751 TRACE("(%p)->(%p %p)\n", This, options, trimming_sign);
1753 *options = This->format.trimming;
1754 if ((*trimming_sign = This->format.trimmingsign))
1755 IDWriteInlineObject_AddRef(*trimming_sign);
1757 return S_OK;
1760 static HRESULT WINAPI dwritetextformat_GetLineSpacing(IDWriteTextFormat1 *iface, DWRITE_LINE_SPACING_METHOD *method,
1761 FLOAT *spacing, FLOAT *baseline)
1763 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1764 TRACE("(%p)->(%p %p %p)\n", This, method, spacing, baseline);
1766 *method = This->format.spacingmethod;
1767 *spacing = This->format.spacing;
1768 *baseline = This->format.baseline;
1769 return S_OK;
1772 static HRESULT WINAPI dwritetextformat_GetFontCollection(IDWriteTextFormat1 *iface, IDWriteFontCollection **collection)
1774 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1776 TRACE("(%p)->(%p)\n", This, collection);
1778 *collection = This->format.collection;
1779 IDWriteFontCollection_AddRef(*collection);
1781 return S_OK;
1784 static UINT32 WINAPI dwritetextformat_GetFontFamilyNameLength(IDWriteTextFormat1 *iface)
1786 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1787 TRACE("(%p)\n", This);
1788 return This->format.family_len;
1791 static HRESULT WINAPI dwritetextformat_GetFontFamilyName(IDWriteTextFormat1 *iface, WCHAR *name, UINT32 size)
1793 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1795 TRACE("(%p)->(%p %u)\n", This, name, size);
1797 if (size <= This->format.family_len) return E_NOT_SUFFICIENT_BUFFER;
1798 strcpyW(name, This->format.family_name);
1799 return S_OK;
1802 static DWRITE_FONT_WEIGHT WINAPI dwritetextformat_GetFontWeight(IDWriteTextFormat1 *iface)
1804 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1805 TRACE("(%p)\n", This);
1806 return This->format.weight;
1809 static DWRITE_FONT_STYLE WINAPI dwritetextformat_GetFontStyle(IDWriteTextFormat1 *iface)
1811 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1812 TRACE("(%p)\n", This);
1813 return This->format.style;
1816 static DWRITE_FONT_STRETCH WINAPI dwritetextformat_GetFontStretch(IDWriteTextFormat1 *iface)
1818 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1819 TRACE("(%p)\n", This);
1820 return This->format.stretch;
1823 static FLOAT WINAPI dwritetextformat_GetFontSize(IDWriteTextFormat1 *iface)
1825 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1826 TRACE("(%p)\n", This);
1827 return This->format.fontsize;
1830 static UINT32 WINAPI dwritetextformat_GetLocaleNameLength(IDWriteTextFormat1 *iface)
1832 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1833 TRACE("(%p)\n", This);
1834 return This->format.locale_len;
1837 static HRESULT WINAPI dwritetextformat_GetLocaleName(IDWriteTextFormat1 *iface, WCHAR *name, UINT32 size)
1839 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1841 TRACE("(%p)->(%p %u)\n", This, name, size);
1843 if (size <= This->format.locale_len) return E_NOT_SUFFICIENT_BUFFER;
1844 strcpyW(name, This->format.locale);
1845 return S_OK;
1848 static HRESULT WINAPI dwritetextformat1_SetVerticalGlyphOrientation(IDWriteTextFormat1 *iface, DWRITE_VERTICAL_GLYPH_ORIENTATION orientation)
1850 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1851 FIXME("(%p)->(%d): stub\n", This, orientation);
1852 return E_NOTIMPL;
1855 static DWRITE_VERTICAL_GLYPH_ORIENTATION WINAPI dwritetextformat1_GetVerticalGlyphOrientation(IDWriteTextFormat1 *iface)
1857 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1858 FIXME("(%p): stub\n", This);
1859 return DWRITE_VERTICAL_GLYPH_ORIENTATION_DEFAULT;
1862 static HRESULT WINAPI dwritetextformat1_SetLastLineWrapping(IDWriteTextFormat1 *iface, BOOL lastline_wrapping_enabled)
1864 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1865 FIXME("(%p)->(%d): stub\n", This, lastline_wrapping_enabled);
1866 return E_NOTIMPL;
1869 static BOOL WINAPI dwritetextformat1_GetLastLineWrapping(IDWriteTextFormat1 *iface)
1871 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1872 FIXME("(%p): stub\n", This);
1873 return FALSE;
1876 static HRESULT WINAPI dwritetextformat1_SetOpticalAlignment(IDWriteTextFormat1 *iface, DWRITE_OPTICAL_ALIGNMENT alignment)
1878 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1879 FIXME("(%p)->(%d): stub\n", This, alignment);
1880 return E_NOTIMPL;
1883 static DWRITE_OPTICAL_ALIGNMENT WINAPI dwritetextformat1_GetOpticalAlignment(IDWriteTextFormat1 *iface)
1885 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1886 FIXME("(%p): stub\n", This);
1887 return DWRITE_OPTICAL_ALIGNMENT_NONE;
1890 static HRESULT WINAPI dwritetextformat1_SetFontFallback(IDWriteTextFormat1 *iface, IDWriteFontFallback *fallback)
1892 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1893 FIXME("(%p)->(%p): stub\n", This, fallback);
1894 return E_NOTIMPL;
1897 static HRESULT WINAPI dwritetextformat1_GetFontFallback(IDWriteTextFormat1 *iface, IDWriteFontFallback **fallback)
1899 struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
1900 FIXME("(%p)->(%p): stub\n", This, fallback);
1901 return E_NOTIMPL;
1904 static const IDWriteTextFormat1Vtbl dwritetextformatvtbl = {
1905 dwritetextformat_QueryInterface,
1906 dwritetextformat_AddRef,
1907 dwritetextformat_Release,
1908 dwritetextformat_SetTextAlignment,
1909 dwritetextformat_SetParagraphAlignment,
1910 dwritetextformat_SetWordWrapping,
1911 dwritetextformat_SetReadingDirection,
1912 dwritetextformat_SetFlowDirection,
1913 dwritetextformat_SetIncrementalTabStop,
1914 dwritetextformat_SetTrimming,
1915 dwritetextformat_SetLineSpacing,
1916 dwritetextformat_GetTextAlignment,
1917 dwritetextformat_GetParagraphAlignment,
1918 dwritetextformat_GetWordWrapping,
1919 dwritetextformat_GetReadingDirection,
1920 dwritetextformat_GetFlowDirection,
1921 dwritetextformat_GetIncrementalTabStop,
1922 dwritetextformat_GetTrimming,
1923 dwritetextformat_GetLineSpacing,
1924 dwritetextformat_GetFontCollection,
1925 dwritetextformat_GetFontFamilyNameLength,
1926 dwritetextformat_GetFontFamilyName,
1927 dwritetextformat_GetFontWeight,
1928 dwritetextformat_GetFontStyle,
1929 dwritetextformat_GetFontStretch,
1930 dwritetextformat_GetFontSize,
1931 dwritetextformat_GetLocaleNameLength,
1932 dwritetextformat_GetLocaleName,
1933 dwritetextformat1_SetVerticalGlyphOrientation,
1934 dwritetextformat1_GetVerticalGlyphOrientation,
1935 dwritetextformat1_SetLastLineWrapping,
1936 dwritetextformat1_GetLastLineWrapping,
1937 dwritetextformat1_SetOpticalAlignment,
1938 dwritetextformat1_GetOpticalAlignment,
1939 dwritetextformat1_SetFontFallback,
1940 dwritetextformat1_GetFontFallback
1943 HRESULT create_textformat(const WCHAR *family_name, IDWriteFontCollection *collection, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style,
1944 DWRITE_FONT_STRETCH stretch, FLOAT size, const WCHAR *locale, IDWriteTextFormat **format)
1946 struct dwrite_textformat *This;
1948 *format = NULL;
1950 This = heap_alloc(sizeof(struct dwrite_textformat));
1951 if (!This) return E_OUTOFMEMORY;
1953 This->IDWriteTextFormat1_iface.lpVtbl = &dwritetextformatvtbl;
1954 This->ref = 1;
1955 This->format.family_name = heap_strdupW(family_name);
1956 This->format.family_len = strlenW(family_name);
1957 This->format.locale = heap_strdupW(locale);
1958 This->format.locale_len = strlenW(locale);
1959 This->format.weight = weight;
1960 This->format.style = style;
1961 This->format.fontsize = size;
1962 This->format.stretch = stretch;
1963 This->format.textalignment = DWRITE_TEXT_ALIGNMENT_LEADING;
1964 This->format.paralign = DWRITE_PARAGRAPH_ALIGNMENT_NEAR;
1965 This->format.wrapping = DWRITE_WORD_WRAPPING_WRAP;
1966 This->format.readingdir = DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
1967 This->format.flow = DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM;
1968 This->format.spacingmethod = DWRITE_LINE_SPACING_METHOD_DEFAULT;
1969 This->format.spacing = 0.0;
1970 This->format.baseline = 0.0;
1971 This->format.trimming.granularity = DWRITE_TRIMMING_GRANULARITY_NONE;
1972 This->format.trimming.delimiter = 0;
1973 This->format.trimming.delimiterCount = 0;
1974 This->format.trimmingsign = NULL;
1976 if (collection)
1978 This->format.collection = collection;
1979 IDWriteFontCollection_AddRef(collection);
1981 else
1982 ERR("Collection should always be set\n");
1984 *format = (IDWriteTextFormat*)&This->IDWriteTextFormat1_iface;
1986 return S_OK;
1989 static HRESULT WINAPI dwritetypography_QueryInterface(IDWriteTypography *iface, REFIID riid, void **obj)
1991 struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
1993 TRACE("(%p)->(%s %p)\n", typography, debugstr_guid(riid), obj);
1995 if (IsEqualIID(riid, &IID_IDWriteTypography) || IsEqualIID(riid, &IID_IUnknown)) {
1996 *obj = iface;
1997 IDWriteTypography_AddRef(iface);
1998 return S_OK;
2001 *obj = NULL;
2003 return E_NOINTERFACE;
2006 static ULONG WINAPI dwritetypography_AddRef(IDWriteTypography *iface)
2008 struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
2009 ULONG ref = InterlockedIncrement(&typography->ref);
2010 TRACE("(%p)->(%d)\n", typography, ref);
2011 return ref;
2014 static ULONG WINAPI dwritetypography_Release(IDWriteTypography *iface)
2016 struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
2017 ULONG ref = InterlockedDecrement(&typography->ref);
2019 TRACE("(%p)->(%d)\n", typography, ref);
2021 if (!ref) {
2022 heap_free(typography->features);
2023 heap_free(typography);
2026 return ref;
2029 static HRESULT WINAPI dwritetypography_AddFontFeature(IDWriteTypography *iface, DWRITE_FONT_FEATURE feature)
2031 struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
2033 TRACE("(%p)->(%x %u)\n", typography, feature.nameTag, feature.parameter);
2035 if (typography->count == typography->allocated) {
2036 DWRITE_FONT_FEATURE *ptr = heap_realloc(typography->features, 2*typography->allocated*sizeof(DWRITE_FONT_FEATURE));
2037 if (!ptr)
2038 return E_OUTOFMEMORY;
2040 typography->features = ptr;
2041 typography->allocated *= 2;
2044 typography->features[typography->count++] = feature;
2045 return S_OK;
2048 static UINT32 WINAPI dwritetypography_GetFontFeatureCount(IDWriteTypography *iface)
2050 struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
2051 TRACE("(%p)\n", typography);
2052 return typography->count;
2055 static HRESULT WINAPI dwritetypography_GetFontFeature(IDWriteTypography *iface, UINT32 index, DWRITE_FONT_FEATURE *feature)
2057 struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
2059 TRACE("(%p)->(%u %p)\n", typography, index, feature);
2061 if (index >= typography->count)
2062 return E_INVALIDARG;
2064 *feature = typography->features[index];
2065 return S_OK;
2068 static const IDWriteTypographyVtbl dwritetypographyvtbl = {
2069 dwritetypography_QueryInterface,
2070 dwritetypography_AddRef,
2071 dwritetypography_Release,
2072 dwritetypography_AddFontFeature,
2073 dwritetypography_GetFontFeatureCount,
2074 dwritetypography_GetFontFeature
2077 HRESULT create_typography(IDWriteTypography **ret)
2079 struct dwrite_typography *typography;
2081 *ret = NULL;
2083 typography = heap_alloc(sizeof(*typography));
2084 if (!typography)
2085 return E_OUTOFMEMORY;
2087 typography->IDWriteTypography_iface.lpVtbl = &dwritetypographyvtbl;
2088 typography->ref = 1;
2089 typography->allocated = 2;
2090 typography->count = 0;
2092 typography->features = heap_alloc(typography->allocated*sizeof(DWRITE_FONT_FEATURE));
2093 if (!typography->features) {
2094 heap_free(typography);
2095 return E_OUTOFMEMORY;
2098 *ret = &typography->IDWriteTypography_iface;
2099 return S_OK;