/*
 *    Text format and layout
 *
 * Copyright 2012, 2014-2017 Nikolay Sivov for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include <assert.h>
#include <stdarg.h>
#include <math.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "dwrite_private.h"
#include "scripts.h"

WINE_DEFAULT_DEBUG_CHANNEL(dwrite);

struct dwrite_textformat_data {
    WCHAR *family_name;
    UINT32 family_len;
    WCHAR *locale;
    UINT32 locale_len;

    DWRITE_FONT_WEIGHT weight;
    DWRITE_FONT_STYLE style;
    DWRITE_FONT_STRETCH stretch;

    DWRITE_PARAGRAPH_ALIGNMENT paralign;
    DWRITE_READING_DIRECTION readingdir;
    DWRITE_WORD_WRAPPING wrapping;
    BOOL last_line_wrapping;
    DWRITE_TEXT_ALIGNMENT textalignment;
    DWRITE_FLOW_DIRECTION flow;
    DWRITE_VERTICAL_GLYPH_ORIENTATION vertical_orientation;
    DWRITE_OPTICAL_ALIGNMENT optical_alignment;
    DWRITE_LINE_SPACING spacing;

    FLOAT fontsize;

    DWRITE_TRIMMING trimming;
    IDWriteInlineObject *trimmingsign;

    IDWriteFontCollection *collection;
    IDWriteFontFallback *fallback;
};

enum layout_range_attr_kind {
    LAYOUT_RANGE_ATTR_WEIGHT,
    LAYOUT_RANGE_ATTR_STYLE,
    LAYOUT_RANGE_ATTR_STRETCH,
    LAYOUT_RANGE_ATTR_FONTSIZE,
    LAYOUT_RANGE_ATTR_EFFECT,
    LAYOUT_RANGE_ATTR_INLINE,
    LAYOUT_RANGE_ATTR_UNDERLINE,
    LAYOUT_RANGE_ATTR_STRIKETHROUGH,
    LAYOUT_RANGE_ATTR_PAIR_KERNING,
    LAYOUT_RANGE_ATTR_FONTCOLL,
    LAYOUT_RANGE_ATTR_LOCALE,
    LAYOUT_RANGE_ATTR_FONTFAMILY,
    LAYOUT_RANGE_ATTR_SPACING,
    LAYOUT_RANGE_ATTR_TYPOGRAPHY
};

struct layout_range_attr_value {
    DWRITE_TEXT_RANGE range;
    union {
        DWRITE_FONT_WEIGHT weight;
        DWRITE_FONT_STYLE style;
        DWRITE_FONT_STRETCH stretch;
        FLOAT fontsize;
        IDWriteInlineObject *object;
        IUnknown *effect;
        BOOL underline;
        BOOL strikethrough;
        BOOL pair_kerning;
        IDWriteFontCollection *collection;
        const WCHAR *locale;
        const WCHAR *fontfamily;
        struct {
            FLOAT leading;
            FLOAT trailing;
            FLOAT min_advance;
        } spacing;
        IDWriteTypography *typography;
    } u;
};

enum layout_range_kind {
    LAYOUT_RANGE_REGULAR,
    LAYOUT_RANGE_UNDERLINE,
    LAYOUT_RANGE_STRIKETHROUGH,
    LAYOUT_RANGE_EFFECT,
    LAYOUT_RANGE_SPACING,
    LAYOUT_RANGE_TYPOGRAPHY
};

struct layout_range_header {
    struct list entry;
    enum layout_range_kind kind;
    DWRITE_TEXT_RANGE range;
};

struct layout_range {
    struct layout_range_header h;
    DWRITE_FONT_WEIGHT weight;
    DWRITE_FONT_STYLE style;
    FLOAT fontsize;
    DWRITE_FONT_STRETCH stretch;
    IDWriteInlineObject *object;
    BOOL pair_kerning;
    IDWriteFontCollection *collection;
    WCHAR locale[LOCALE_NAME_MAX_LENGTH];
    WCHAR *fontfamily;
};

struct layout_range_bool {
    struct layout_range_header h;
    BOOL value;
};

struct layout_range_iface {
    struct layout_range_header h;
    IUnknown *iface;
};

struct layout_range_spacing {
    struct layout_range_header h;
    FLOAT leading;
    FLOAT trailing;
    FLOAT min_advance;
};

enum layout_run_kind {
    LAYOUT_RUN_REGULAR,
    LAYOUT_RUN_INLINE
};

struct inline_object_run {
    IDWriteInlineObject *object;
    UINT16 length;
};

struct regular_layout_run {
    DWRITE_GLYPH_RUN_DESCRIPTION descr;
    DWRITE_GLYPH_RUN run;
    DWRITE_SCRIPT_ANALYSIS sa;
    UINT16 *glyphs;
    UINT16 *clustermap;
    FLOAT  *advances;
    DWRITE_GLYPH_OFFSET *offsets;
    UINT32 glyphcount; /* actual glyph count after shaping, not necessarily the same as reported to Draw() */
};

struct layout_run {
    struct list entry;
    enum layout_run_kind kind;
    union {
        struct inline_object_run object;
        struct regular_layout_run regular;
    } u;
    FLOAT baseline;
    FLOAT height;
    UINT32 start_position; /* run text position in range [0, layout-text-length) */
};

struct layout_effective_run {
    struct list entry;
    const struct layout_run *run; /* nominal run this one is based on */
    UINT32 start;           /* relative text position, 0 means first text position of a nominal run */
    UINT32 length;          /* length in codepoints that this run covers */
    UINT32 glyphcount;      /* total glyph count in this run */
    IUnknown *effect;       /* original reference is kept only at range level */
    D2D1_POINT_2F origin;   /* baseline origin */
    FLOAT align_dx;         /* adjustment from text alignment */
    FLOAT width;            /* run width */
    UINT16 *clustermap;     /* effective clustermap, allocated separately, is not reused from nominal map */
    UINT32 line;            /* 0-based line index in line metrics array */
    BOOL underlined;        /* set if this run is underlined */
    D2D1_RECT_F bbox;       /* ink run box, top == bottom means it wasn't estimated yet */
};

struct layout_effective_inline {
    struct list entry;
    IDWriteInlineObject *object;  /* inline object, set explicitly or added when trimming a line */
    IUnknown *effect;             /* original reference is kept only at range level */
    FLOAT baseline;
    D2D1_POINT_2F origin;         /* left top corner */
    FLOAT align_dx;               /* adjustment from text alignment */
    FLOAT width;                  /* object width as it's reported it */
    BOOL  is_sideways;            /* vertical flow direction flag passed to Draw */
    BOOL  is_rtl;                 /* bidi flag passed to Draw */
    UINT32 line;                  /* 0-based line index in line metrics array */
};

struct layout_underline {
    struct list entry;
    const struct layout_effective_run *run;
    DWRITE_UNDERLINE u;
};

struct layout_strikethrough {
    struct list entry;
    const struct layout_effective_run *run;
    DWRITE_STRIKETHROUGH s;
};

struct layout_cluster {
    const struct layout_run *run; /* link to nominal run this cluster belongs to */
    UINT32 position;        /* relative to run, first cluster has 0 position */
};

struct layout_line {
    FLOAT height;   /* height based on content */
    FLOAT baseline; /* baseline based on content */
};

enum layout_recompute_mask {
    RECOMPUTE_CLUSTERS            = 1 << 0,
    RECOMPUTE_MINIMAL_WIDTH       = 1 << 1,
    RECOMPUTE_LINES               = 1 << 2,
    RECOMPUTE_OVERHANGS           = 1 << 3,
    RECOMPUTE_LINES_AND_OVERHANGS = RECOMPUTE_LINES | RECOMPUTE_OVERHANGS,
    RECOMPUTE_EVERYTHING          = 0xffff
};

struct dwrite_textlayout {
    IDWriteTextLayout3 IDWriteTextLayout3_iface;
    IDWriteTextFormat1 IDWriteTextFormat1_iface;
    IDWriteTextAnalysisSink1 IDWriteTextAnalysisSink1_iface;
    IDWriteTextAnalysisSource1 IDWriteTextAnalysisSource1_iface;
    LONG ref;

    IDWriteFactory5 *factory;

    WCHAR *str;
    UINT32 len;
    struct dwrite_textformat_data format;
    struct list strike_ranges;
    struct list underline_ranges;
    struct list typographies;
    struct list effects;
    struct list spacing;
    struct list ranges;
    struct list runs;
    /* lists ready to use by Draw() */
    struct list eruns;
    struct list inlineobjects;
    struct list underlines;
    struct list strikethrough;
    USHORT recompute;

    DWRITE_LINE_BREAKPOINT *nominal_breakpoints;
    DWRITE_LINE_BREAKPOINT *actual_breakpoints;

    struct layout_cluster *clusters;
    DWRITE_CLUSTER_METRICS *clustermetrics;
    UINT32 cluster_count;
    FLOAT  minwidth;

    struct layout_line *lines;
    DWRITE_LINE_METRICS1 *linemetrics;
    UINT32 line_alloc;

    DWRITE_TEXT_METRICS1 metrics;
    DWRITE_OVERHANG_METRICS overhangs;

    DWRITE_MEASURING_MODE measuringmode;

    /* gdi-compatible layout specifics */
    FLOAT ppdip;
    DWRITE_MATRIX transform;
};

struct dwrite_textformat {
    IDWriteTextFormat2 IDWriteTextFormat2_iface;
    LONG ref;
    struct dwrite_textformat_data format;
};

struct dwrite_trimmingsign {
    IDWriteInlineObject IDWriteInlineObject_iface;
    LONG ref;

    IDWriteTextLayout *layout;
};

struct dwrite_typography {
    IDWriteTypography IDWriteTypography_iface;
    LONG ref;

    DWRITE_FONT_FEATURE *features;
    UINT32 allocated;
    UINT32 count;
};

static const IDWriteTextFormat2Vtbl dwritetextformatvtbl;

static void release_format_data(struct dwrite_textformat_data *data)
{
    if (data->collection) IDWriteFontCollection_Release(data->collection);
    if (data->fallback) IDWriteFontFallback_Release(data->fallback);
    if (data->trimmingsign) IDWriteInlineObject_Release(data->trimmingsign);
    heap_free(data->family_name);
    heap_free(data->locale);
}

static inline struct dwrite_textlayout *impl_from_IDWriteTextLayout3(IDWriteTextLayout3 *iface)
{
    return CONTAINING_RECORD(iface, struct dwrite_textlayout, IDWriteTextLayout3_iface);
}

static inline struct dwrite_textlayout *impl_layout_from_IDWriteTextFormat1(IDWriteTextFormat1 *iface)
{
    return CONTAINING_RECORD(iface, struct dwrite_textlayout, IDWriteTextFormat1_iface);
}

static inline struct dwrite_textlayout *impl_from_IDWriteTextAnalysisSink1(IDWriteTextAnalysisSink1 *iface)
{
    return CONTAINING_RECORD(iface, struct dwrite_textlayout, IDWriteTextAnalysisSink1_iface);
}

static inline struct dwrite_textlayout *impl_from_IDWriteTextAnalysisSource1(IDWriteTextAnalysisSource1 *iface)
{
    return CONTAINING_RECORD(iface, struct dwrite_textlayout, IDWriteTextAnalysisSource1_iface);
}

static inline struct dwrite_textformat *impl_from_IDWriteTextFormat2(IDWriteTextFormat2 *iface)
{
    return CONTAINING_RECORD(iface, struct dwrite_textformat, IDWriteTextFormat2_iface);
}

static struct dwrite_textformat *unsafe_impl_from_IDWriteTextFormat(IDWriteTextFormat*);

static inline struct dwrite_trimmingsign *impl_from_IDWriteInlineObject(IDWriteInlineObject *iface)
{
    return CONTAINING_RECORD(iface, struct dwrite_trimmingsign, IDWriteInlineObject_iface);
}

static inline struct dwrite_typography *impl_from_IDWriteTypography(IDWriteTypography *iface)
{
    return CONTAINING_RECORD(iface, struct dwrite_typography, IDWriteTypography_iface);
}

static inline const char *debugstr_rundescr(const DWRITE_GLYPH_RUN_DESCRIPTION *descr)
{
    return wine_dbg_sprintf("[%u,%u)", descr->textPosition, descr->textPosition + descr->stringLength);
}

static inline BOOL is_layout_gdi_compatible(struct dwrite_textlayout *layout)
{
    return layout->measuringmode != DWRITE_MEASURING_MODE_NATURAL;
}

static inline HRESULT format_set_textalignment(struct dwrite_textformat_data *format, DWRITE_TEXT_ALIGNMENT alignment,
    BOOL *changed)
{
    if ((UINT32)alignment > DWRITE_TEXT_ALIGNMENT_JUSTIFIED)
        return E_INVALIDARG;
    if (changed) *changed = format->textalignment != alignment;
    format->textalignment = alignment;
    return S_OK;
}

static inline HRESULT format_set_paralignment(struct dwrite_textformat_data *format,
    DWRITE_PARAGRAPH_ALIGNMENT alignment, BOOL *changed)
{
    if ((UINT32)alignment > DWRITE_PARAGRAPH_ALIGNMENT_CENTER)
        return E_INVALIDARG;
    if (changed) *changed = format->paralign != alignment;
    format->paralign = alignment;
    return S_OK;
}

static inline HRESULT format_set_readingdirection(struct dwrite_textformat_data *format,
    DWRITE_READING_DIRECTION direction, BOOL *changed)
{
    if ((UINT32)direction > DWRITE_READING_DIRECTION_BOTTOM_TO_TOP)
        return E_INVALIDARG;
    if (changed) *changed = format->readingdir != direction;
    format->readingdir = direction;
    return S_OK;
}

static inline HRESULT format_set_wordwrapping(struct dwrite_textformat_data *format,
    DWRITE_WORD_WRAPPING wrapping, BOOL *changed)
{
    if ((UINT32)wrapping > DWRITE_WORD_WRAPPING_CHARACTER)
        return E_INVALIDARG;
    if (changed) *changed = format->wrapping != wrapping;
    format->wrapping = wrapping;
    return S_OK;
}

static inline HRESULT format_set_flowdirection(struct dwrite_textformat_data *format,
    DWRITE_FLOW_DIRECTION direction, BOOL *changed)
{
    if ((UINT32)direction > DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT)
        return E_INVALIDARG;
    if (changed) *changed = format->flow != direction;
    format->flow = direction;
    return S_OK;
}

static inline HRESULT format_set_trimming(struct dwrite_textformat_data *format,
    DWRITE_TRIMMING const *trimming, IDWriteInlineObject *trimming_sign, BOOL *changed)
{
    if (changed)
        *changed = FALSE;

    if ((UINT32)trimming->granularity > DWRITE_TRIMMING_GRANULARITY_WORD)
        return E_INVALIDARG;

    if (changed) {
        *changed = !!memcmp(&format->trimming, trimming, sizeof(*trimming));
        if (format->trimmingsign != trimming_sign)
            *changed = TRUE;
    }

    format->trimming = *trimming;
    if (format->trimmingsign)
        IDWriteInlineObject_Release(format->trimmingsign);
    format->trimmingsign = trimming_sign;
    if (format->trimmingsign)
        IDWriteInlineObject_AddRef(format->trimmingsign);
    return S_OK;
}

static inline HRESULT format_set_linespacing(struct dwrite_textformat_data *format,
    DWRITE_LINE_SPACING const *spacing, BOOL *changed)
{
    if (spacing->height < 0.0f || spacing->leadingBefore < 0.0f || spacing->leadingBefore > 1.0f ||
        (UINT32)spacing->method > DWRITE_LINE_SPACING_METHOD_PROPORTIONAL)
        return E_INVALIDARG;

    if (changed)
        *changed = memcmp(spacing, &format->spacing, sizeof(*spacing));

    format->spacing = *spacing;
    return S_OK;
}

static HRESULT get_fontfallback_from_format(const struct dwrite_textformat_data *format, IDWriteFontFallback **fallback)
{
    *fallback = format->fallback;
    if (*fallback)
        IDWriteFontFallback_AddRef(*fallback);
    return S_OK;
}

static HRESULT set_fontfallback_for_format(struct dwrite_textformat_data *format, IDWriteFontFallback *fallback)
{
    if (format->fallback)
        IDWriteFontFallback_Release(format->fallback);
    format->fallback = fallback;
    if (fallback)
        IDWriteFontFallback_AddRef(fallback);
    return S_OK;
}

static HRESULT format_set_optical_alignment(struct dwrite_textformat_data *format,
    DWRITE_OPTICAL_ALIGNMENT alignment)
{
    if ((UINT32)alignment > DWRITE_OPTICAL_ALIGNMENT_NO_SIDE_BEARINGS)
        return E_INVALIDARG;
    format->optical_alignment = alignment;
    return S_OK;
}

static BOOL is_run_rtl(const struct layout_effective_run *run)
{
    return run->run->u.regular.run.bidiLevel & 1;
}

static struct layout_run *alloc_layout_run(enum layout_run_kind kind, UINT32 start_position)
{
    struct layout_run *ret;

    ret = heap_alloc(sizeof(*ret));
    if (!ret) return NULL;

    memset(ret, 0, sizeof(*ret));
    ret->kind = kind;
    if (kind == LAYOUT_RUN_REGULAR) {
        ret->u.regular.sa.script = Script_Unknown;
        ret->u.regular.sa.shapes = DWRITE_SCRIPT_SHAPES_DEFAULT;
    }
    ret->start_position = start_position;

    return ret;
}

static void free_layout_runs(struct dwrite_textlayout *layout)
{
    struct layout_run *cur, *cur2;
    LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->runs, struct layout_run, entry) {
        list_remove(&cur->entry);
        if (cur->kind == LAYOUT_RUN_REGULAR) {
            if (cur->u.regular.run.fontFace)
                IDWriteFontFace_Release(cur->u.regular.run.fontFace);
            heap_free(cur->u.regular.glyphs);
            heap_free(cur->u.regular.clustermap);
            heap_free(cur->u.regular.advances);
            heap_free(cur->u.regular.offsets);
        }
        heap_free(cur);
    }
}

static void free_layout_eruns(struct dwrite_textlayout *layout)
{
    struct layout_effective_inline *in, *in2;
    struct layout_effective_run *cur, *cur2;
    struct layout_strikethrough *s, *s2;
    struct layout_underline *u, *u2;

    LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->eruns, struct layout_effective_run, entry) {
        list_remove(&cur->entry);
        heap_free(cur->clustermap);
        heap_free(cur);
    }

    LIST_FOR_EACH_ENTRY_SAFE(in, in2, &layout->inlineobjects, struct layout_effective_inline, entry) {
        list_remove(&in->entry);
        heap_free(in);
    }

    LIST_FOR_EACH_ENTRY_SAFE(u, u2, &layout->underlines, struct layout_underline, entry) {
        list_remove(&u->entry);
        heap_free(u);
    }

    LIST_FOR_EACH_ENTRY_SAFE(s, s2, &layout->strikethrough, struct layout_strikethrough, entry) {
        list_remove(&s->entry);
        heap_free(s);
    }
}

/* Used to resolve break condition by forcing stronger condition over weaker. */
static inline DWRITE_BREAK_CONDITION override_break_condition(DWRITE_BREAK_CONDITION existingbreak, DWRITE_BREAK_CONDITION newbreak)
{
    switch (existingbreak) {
    case DWRITE_BREAK_CONDITION_NEUTRAL:
        return newbreak;
    case DWRITE_BREAK_CONDITION_CAN_BREAK:
        return newbreak == DWRITE_BREAK_CONDITION_NEUTRAL ? existingbreak : newbreak;
    /* let's keep stronger conditions as is */
    case DWRITE_BREAK_CONDITION_MAY_NOT_BREAK:
    case DWRITE_BREAK_CONDITION_MUST_BREAK:
        break;
    default:
        ERR("unknown break condition %d\n", existingbreak);
    }

    return existingbreak;
}

/* This helper should be used to get effective range length, in other words it returns number of text
   positions from range starting point to the end of the range, limited by layout text length */
static inline UINT32 get_clipped_range_length(const struct dwrite_textlayout *layout, const struct layout_range *range)
{
    if (range->h.range.startPosition + range->h.range.length <= layout->len)
        return range->h.range.length;
    return layout->len - range->h.range.startPosition;
}

/* Actual breakpoint data gets updated with break condition required by inline object set for range 'cur'. */
static HRESULT layout_update_breakpoints_range(struct dwrite_textlayout *layout, const struct layout_range *cur)
{
    DWRITE_BREAK_CONDITION before, after;
    UINT32 i, length;
    HRESULT hr;

    /* ignore returned conditions if failed */
    hr = IDWriteInlineObject_GetBreakConditions(cur->object, &before, &after);
    if (FAILED(hr))
        after = before = DWRITE_BREAK_CONDITION_NEUTRAL;

    if (!layout->actual_breakpoints) {
        layout->actual_breakpoints = heap_alloc(sizeof(DWRITE_LINE_BREAKPOINT)*layout->len);
        if (!layout->actual_breakpoints)
            return E_OUTOFMEMORY;
        memcpy(layout->actual_breakpoints, layout->nominal_breakpoints, sizeof(DWRITE_LINE_BREAKPOINT)*layout->len);
    }

    length = get_clipped_range_length(layout, cur);
    for (i = cur->h.range.startPosition; i < length + cur->h.range.startPosition; i++) {
        /* for first codepoint check if there's anything before it and update accordingly */
        if (i == cur->h.range.startPosition) {
            if (i > 0)
                layout->actual_breakpoints[i].breakConditionBefore = layout->actual_breakpoints[i-1].breakConditionAfter =
                    override_break_condition(layout->actual_breakpoints[i-1].breakConditionAfter, before);
            else
                layout->actual_breakpoints[i].breakConditionBefore = before;
            layout->actual_breakpoints[i].breakConditionAfter = DWRITE_BREAK_CONDITION_MAY_NOT_BREAK;
        }
        /* similar check for last codepoint */
        else if (i == cur->h.range.startPosition + length - 1) {
            if (i == layout->len - 1)
                layout->actual_breakpoints[i].breakConditionAfter = after;
            else
                layout->actual_breakpoints[i].breakConditionAfter = layout->actual_breakpoints[i+1].breakConditionBefore =
                    override_break_condition(layout->actual_breakpoints[i+1].breakConditionBefore, after);
            layout->actual_breakpoints[i].breakConditionBefore = DWRITE_BREAK_CONDITION_MAY_NOT_BREAK;
        }
        /* for all positions within a range disable breaks */
        else {
            layout->actual_breakpoints[i].breakConditionBefore = DWRITE_BREAK_CONDITION_MAY_NOT_BREAK;
            layout->actual_breakpoints[i].breakConditionAfter = DWRITE_BREAK_CONDITION_MAY_NOT_BREAK;
        }

        layout->actual_breakpoints[i].isWhitespace = 0;
        layout->actual_breakpoints[i].isSoftHyphen = 0;
    }

    return S_OK;
}

static struct layout_range *get_layout_range_by_pos(struct dwrite_textlayout *layout, UINT32 pos);

static inline DWRITE_LINE_BREAKPOINT get_effective_breakpoint(const struct dwrite_textlayout *layout, UINT32 pos)
{
    if (layout->actual_breakpoints)
        return layout->actual_breakpoints[pos];
    return layout->nominal_breakpoints[pos];
}

static inline void init_cluster_metrics(const struct dwrite_textlayout *layout, const struct regular_layout_run *run,
    UINT16 start_glyph, UINT16 stop_glyph, UINT32 stop_position, UINT16 length, DWRITE_CLUSTER_METRICS *metrics)
{
    UINT8 breakcondition;
    UINT32 position;
    UINT16 j;

    /* For clusters made of control chars we report zero glyphs, and we need zero cluster
       width as well; advances are already computed at this point and are not necessary zero. */
    metrics->width = 0.0f;
    if (run->run.glyphCount) {
        for (j = start_glyph; j < stop_glyph; j++)
            metrics->width += run->run.glyphAdvances[j];
    }
    metrics->length = length;

    position = run->descr.textPosition + stop_position;
    if (stop_glyph == run->glyphcount)
        breakcondition = get_effective_breakpoint(layout, position).breakConditionAfter;
    else {
        breakcondition = get_effective_breakpoint(layout, position).breakConditionBefore;
        if (stop_position) position -= 1;
    }

    metrics->canWrapLineAfter = breakcondition == DWRITE_BREAK_CONDITION_CAN_BREAK ||
                                breakcondition == DWRITE_BREAK_CONDITION_MUST_BREAK;
    if (metrics->length == 1) {
        DWRITE_LINE_BREAKPOINT bp = get_effective_breakpoint(layout, position);
        metrics->isWhitespace = bp.isWhitespace;
        metrics->isNewline = metrics->canWrapLineAfter && lb_is_newline_char(layout->str[position]);
        metrics->isSoftHyphen = bp.isSoftHyphen;
    }
    else {
        metrics->isWhitespace = 0;
        metrics->isNewline = 0;
        metrics->isSoftHyphen = 0;
    }
    metrics->isRightToLeft = run->run.bidiLevel & 1;
    metrics->padding = 0;
}

/*

  All clusters in a 'run' will be added to 'layout' data, starting at index pointed to by 'cluster'.
  On return 'cluster' is updated to point to next metrics struct to be filled in on next call.
  Note that there's no need to reallocate anything at this point as we allocate one cluster per
  codepoint initially.

*/
static void layout_set_cluster_metrics(struct dwrite_textlayout *layout, const struct layout_run *r, UINT32 *cluster)
{
    DWRITE_CLUSTER_METRICS *metrics = &layout->clustermetrics[*cluster];
    struct layout_cluster *c = &layout->clusters[*cluster];
    const struct regular_layout_run *run = &r->u.regular;
    UINT32 i, start = 0;

    assert(r->kind == LAYOUT_RUN_REGULAR);

    for (i = 0; i < run->descr.stringLength; i++) {
        BOOL end = i == run->descr.stringLength - 1;

        if (run->descr.clusterMap[start] != run->descr.clusterMap[i]) {
            init_cluster_metrics(layout, run, run->descr.clusterMap[start], run->descr.clusterMap[i], i,
                i - start, metrics);
            c->position = start;
            c->run = r;

            *cluster += 1;
            metrics++;
            c++;
            start = i;
        }

        if (end) {
            init_cluster_metrics(layout, run, run->descr.clusterMap[start], run->glyphcount, i,
                i - start + 1, metrics);
            c->position = start;
            c->run = r;

            *cluster += 1;
            return;
        }
    }
}

#define SCALE_FONT_METRIC(metric, emSize, metrics) ((FLOAT)(metric) * (emSize) / (FLOAT)(metrics)->designUnitsPerEm)

static void layout_get_font_metrics(struct dwrite_textlayout *layout, IDWriteFontFace *fontface, FLOAT emsize,
    DWRITE_FONT_METRICS *fontmetrics)
{
    if (is_layout_gdi_compatible(layout)) {
        HRESULT hr = IDWriteFontFace_GetGdiCompatibleMetrics(fontface, emsize, layout->ppdip, &layout->transform, fontmetrics);
        if (FAILED(hr))
            WARN("failed to get compat metrics, 0x%08x\n", hr);
    }
    else
        IDWriteFontFace_GetMetrics(fontface, fontmetrics);
}

static void layout_get_font_height(FLOAT emsize, DWRITE_FONT_METRICS *fontmetrics, FLOAT *baseline, FLOAT *height)
{
    *baseline = SCALE_FONT_METRIC(fontmetrics->ascent + fontmetrics->lineGap, emsize, fontmetrics);
    *height = SCALE_FONT_METRIC(fontmetrics->ascent + fontmetrics->descent + fontmetrics->lineGap, emsize, fontmetrics);
}

static HRESULT layout_itemize(struct dwrite_textlayout *layout)
{
    IDWriteTextAnalyzer *analyzer;
    struct layout_range *range;
    struct layout_run *r;
    HRESULT hr = S_OK;

    analyzer = get_text_analyzer();

    LIST_FOR_EACH_ENTRY(range, &layout->ranges, struct layout_range, h.entry) {
        /* We don't care about ranges that don't contain any text. */
        if (range->h.range.startPosition >= layout->len)
            break;

        /* Inline objects override actual text in range. */
        if (range->object) {
            hr = layout_update_breakpoints_range(layout, range);
            if (FAILED(hr))
                return hr;

            r = alloc_layout_run(LAYOUT_RUN_INLINE, range->h.range.startPosition);
            if (!r)
                return E_OUTOFMEMORY;

            r->u.object.object = range->object;
            r->u.object.length = get_clipped_range_length(layout, range);
            list_add_tail(&layout->runs, &r->entry);
            continue;
        }

        /* Initial splitting by script. */
        hr = IDWriteTextAnalyzer_AnalyzeScript(analyzer, (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface,
                range->h.range.startPosition, get_clipped_range_length(layout, range),
                (IDWriteTextAnalysisSink *)&layout->IDWriteTextAnalysisSink1_iface);
        if (FAILED(hr))
            break;

        /* Splitting further by bidi levels. */
        hr = IDWriteTextAnalyzer_AnalyzeBidi(analyzer, (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface,
                range->h.range.startPosition, get_clipped_range_length(layout, range),
                (IDWriteTextAnalysisSink *)&layout->IDWriteTextAnalysisSink1_iface);
        if (FAILED(hr))
            break;
    }

    return hr;
}

static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout)
{
    IDWriteFontCollection *sys_collection;
    IDWriteFontFallback *fallback = NULL;
    struct layout_range *range;
    struct layout_run *r;
    HRESULT hr;

    if (FAILED(hr = IDWriteFactory5_GetSystemFontCollection(layout->factory, FALSE,
            (IDWriteFontCollection1 **)&sys_collection, FALSE))) {
        WARN("Failed to get system collection, hr %#x.\n", hr);
        return hr;
    }

    if (layout->format.fallback) {
        fallback = layout->format.fallback;
        IDWriteFontFallback_AddRef(fallback);
    }
    else {
        if (FAILED(hr = IDWriteFactory5_GetSystemFontFallback(layout->factory, &fallback))) {
            WARN("Failed to get system fallback, hr %#x.\n", hr);
            goto fatal;
        }
    }

    LIST_FOR_EACH_ENTRY(r, &layout->runs, struct layout_run, entry) {
        struct regular_layout_run *run = &r->u.regular;
        IDWriteFont *font;
        UINT32 length;

        if (r->kind == LAYOUT_RUN_INLINE)
            continue;

        range = get_layout_range_by_pos(layout, run->descr.textPosition);

        if (run->sa.shapes == DWRITE_SCRIPT_SHAPES_NO_VISUAL) {
            IDWriteFontCollection *collection;

            collection = range->collection ? range->collection : sys_collection;

            if (FAILED(hr = create_matching_font(collection, range->fontfamily, range->weight, range->style,
                    range->stretch, &font))) {
                WARN("%s: failed to create matching font for non visual run, family %s, collection %p\n",
                        debugstr_rundescr(&run->descr), debugstr_w(range->fontfamily), range->collection);
                break;
            }

            hr = IDWriteFont_CreateFontFace(font, &run->run.fontFace);
            IDWriteFont_Release(font);
            if (FAILED(hr)) {
                WARN("Failed to create font face, hr %#x.\n", hr);
                break;
            }

            run->run.fontEmSize = range->fontsize;
            continue;
        }

        length = run->descr.stringLength;

        while (length) {
            UINT32 mapped_length;
            FLOAT scale;

            run = &r->u.regular;

            hr = IDWriteFontFallback_MapCharacters(fallback,
                (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface,
                run->descr.textPosition,
                run->descr.stringLength,
                range->collection,
                range->fontfamily,
                range->weight,
                range->style,
                range->stretch,
                &mapped_length,
                &font,
                &scale);
            if (FAILED(hr)) {
                WARN("%s: failed to map family %s, collection %p, hr %#x.\n", debugstr_rundescr(&run->descr),
                        debugstr_w(range->fontfamily), range->collection, hr);
                goto fatal;
            }

            hr = IDWriteFont_CreateFontFace(font, &run->run.fontFace);
            IDWriteFont_Release(font);
            if (FAILED(hr)) {
                WARN("Failed to create font face, hr %#x.\n", hr);
                goto fatal;
            }

            run->run.fontEmSize = range->fontsize * scale;

            if (mapped_length < length) {
                struct regular_layout_run *nextrun;
                struct layout_run *nextr;

                /* keep mapped part for current run, add another run for the rest */
                nextr = alloc_layout_run(LAYOUT_RUN_REGULAR, 0);
                if (!nextr) {
                    hr = E_OUTOFMEMORY;
                    goto fatal;
                }

                *nextr = *r;
                nextr->start_position = run->descr.textPosition + mapped_length;
                nextrun = &nextr->u.regular;
                nextrun->descr.textPosition = nextr->start_position;
                nextrun->descr.stringLength = run->descr.stringLength - mapped_length;
                nextrun->descr.string = &layout->str[nextrun->descr.textPosition];
                run->descr.stringLength = mapped_length;
                list_add_after(&r->entry, &nextr->entry);
                r = nextr;
            }

            length -= mapped_length;
        }
    }

fatal:
    IDWriteFontCollection_Release(sys_collection);
    if (fallback)
        IDWriteFontFallback_Release(fallback);

    return hr;
}

static HRESULT layout_shape_run(struct dwrite_textlayout *layout, struct regular_layout_run *run)
{
    DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props;
    DWRITE_SHAPING_TEXT_PROPERTIES *text_props;
    IDWriteTextAnalyzer *analyzer;
    struct layout_range *range;
    UINT32 max_count;
    HRESULT hr;

    range = get_layout_range_by_pos(layout, run->descr.textPosition);
    run->descr.localeName = range->locale;
    run->clustermap = heap_alloc(run->descr.stringLength * sizeof(*run->clustermap));

    max_count = 3 * run->descr.stringLength / 2 + 16;
    run->glyphs = heap_alloc(max_count * sizeof(*run->glyphs));
    if (!run->clustermap || !run->glyphs)
        return E_OUTOFMEMORY;

    text_props = heap_alloc(run->descr.stringLength * sizeof(*text_props));
    glyph_props = heap_alloc(max_count * sizeof(*glyph_props));
    if (!text_props || !glyph_props) {
        heap_free(text_props);
        heap_free(glyph_props);
        return E_OUTOFMEMORY;
    }

    analyzer = get_text_analyzer();

    for (;;) {
        hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, run->descr.string, run->descr.stringLength, run->run.fontFace,
                run->run.isSideways, run->run.bidiLevel & 1, &run->sa, run->descr.localeName, NULL /* FIXME */, NULL,
                NULL, 0, max_count, run->clustermap, text_props, run->glyphs, glyph_props, &run->glyphcount);
        if (hr == E_NOT_SUFFICIENT_BUFFER) {
            heap_free(run->glyphs);
            heap_free(glyph_props);

            max_count = run->glyphcount;

            run->glyphs = heap_alloc(max_count * sizeof(*run->glyphs));
            glyph_props = heap_alloc(max_count * sizeof(*glyph_props));
            if (!run->glyphs || !glyph_props) {
                hr = E_OUTOFMEMORY;
                break;
            }

            continue;
        }

        break;
    }

    if (FAILED(hr)) {
        heap_free(text_props);
        heap_free(glyph_props);
        WARN("%s: shaping failed, hr %#x.\n", debugstr_rundescr(&run->descr), hr);
        return hr;
    }

    run->run.glyphIndices = run->glyphs;
    run->descr.clusterMap = run->clustermap;

    run->advances = heap_alloc(run->glyphcount * sizeof(*run->advances));
    run->offsets = heap_alloc(run->glyphcount * sizeof(*run->offsets));
    if (!run->advances || !run->offsets)
        return E_OUTOFMEMORY;

    /* Get advances and offsets. */
    if (is_layout_gdi_compatible(layout))
        hr = IDWriteTextAnalyzer_GetGdiCompatibleGlyphPlacements(analyzer, run->descr.string, run->descr.clusterMap,
                text_props, run->descr.stringLength, run->run.glyphIndices, glyph_props, run->glyphcount,
                run->run.fontFace, run->run.fontEmSize, layout->ppdip, &layout->transform,
                layout->measuringmode == DWRITE_MEASURING_MODE_GDI_NATURAL, run->run.isSideways, run->run.bidiLevel & 1,
                &run->sa, run->descr.localeName, NULL, NULL, 0, run->advances, run->offsets);
    else
        hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, run->descr.string, run->descr.clusterMap, text_props,
                run->descr.stringLength, run->run.glyphIndices, glyph_props, run->glyphcount, run->run.fontFace,
                run->run.fontEmSize, run->run.isSideways, run->run.bidiLevel & 1, &run->sa, run->descr.localeName,
                NULL, NULL, 0, run->advances, run->offsets);

    heap_free(text_props);
    heap_free(glyph_props);
    if (FAILED(hr)) {
        memset(run->advances, 0, run->glyphcount * sizeof(*run->advances));
        memset(run->offsets, 0, run->glyphcount * sizeof(*run->offsets));
        WARN("%s: failed to get glyph placement info, hr %#x.\n", debugstr_rundescr(&run->descr), hr);
    }

    run->run.glyphAdvances = run->advances;
    run->run.glyphOffsets = run->offsets;

    /* Special treatment for runs that don't produce visual output, shaping code adds normal glyphs for them,
       with valid cluster map and potentially with non-zero advances; layout code exposes those as zero
       width clusters. */
    if (run->sa.shapes == DWRITE_SCRIPT_SHAPES_NO_VISUAL)
        run->run.glyphCount = 0;
    else
        run->run.glyphCount = run->glyphcount;

    return S_OK;
}

static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
{
    struct layout_run *r;
    UINT32 cluster = 0;
    HRESULT hr;

    free_layout_eruns(layout);
    free_layout_runs(layout);

    /* Cluster data arrays are allocated once, assuming one text position per cluster. */
    if (!layout->clustermetrics && layout->len) {
        layout->clustermetrics = heap_alloc(layout->len*sizeof(*layout->clustermetrics));
        layout->clusters = heap_alloc(layout->len*sizeof(*layout->clusters));
        if (!layout->clustermetrics || !layout->clusters) {
            heap_free(layout->clustermetrics);
            heap_free(layout->clusters);
            return E_OUTOFMEMORY;
        }
    }
    layout->cluster_count = 0;

    if (FAILED(hr = layout_itemize(layout))) {
        WARN("Itemization failed, hr %#x.\n", hr);
        return hr;
    }

    if (FAILED(hr = layout_resolve_fonts(layout))) {
        WARN("Failed to resolve layout fonts, hr %#x.\n", hr);
        return hr;
    }

    /* fill run info */
    LIST_FOR_EACH_ENTRY(r, &layout->runs, struct layout_run, entry) {
        struct regular_layout_run *run = &r->u.regular;
        DWRITE_FONT_METRICS fontmetrics = { 0 };

        /* we need to do very little in case of inline objects */
        if (r->kind == LAYOUT_RUN_INLINE) {
            DWRITE_CLUSTER_METRICS *metrics = &layout->clustermetrics[cluster];
            struct layout_cluster *c = &layout->clusters[cluster];
            DWRITE_INLINE_OBJECT_METRICS inlinemetrics;

            metrics->width = 0.0f;
            metrics->length = r->u.object.length;
            metrics->canWrapLineAfter = 0;
            metrics->isWhitespace = 0;
            metrics->isNewline = 0;
            metrics->isSoftHyphen = 0;
            metrics->isRightToLeft = 0;
            metrics->padding = 0;
            c->run = r;
            c->position = 0; /* there's always one cluster per inline object, so 0 is valid value */
            cluster++;

            /* it's not fatal if GetMetrics() fails, all returned metrics are ignored */
            hr = IDWriteInlineObject_GetMetrics(r->u.object.object, &inlinemetrics);
            if (FAILED(hr)) {
                memset(&inlinemetrics, 0, sizeof(inlinemetrics));
                hr = S_OK;
            }
            metrics->width = inlinemetrics.width;
            r->baseline = inlinemetrics.baseline;
            r->height = inlinemetrics.height;

            /* FIXME: use resolved breakpoints in this case too */

            continue;
        }

        if (FAILED(hr = layout_shape_run(layout, run)))
            WARN("%s: shaping failed, hr %#x.\n", debugstr_rundescr(&run->descr), hr);

        /* baseline derived from font metrics */
        layout_get_font_metrics(layout, run->run.fontFace, run->run.fontEmSize, &fontmetrics);
        layout_get_font_height(run->run.fontEmSize, &fontmetrics, &r->baseline, &r->height);

        layout_set_cluster_metrics(layout, r, &cluster);
    }

    if (hr == S_OK) {
        layout->cluster_count = cluster;
        if (cluster)
            layout->clustermetrics[cluster-1].canWrapLineAfter = 1;
    }

    return hr;
}

static HRESULT layout_compute(struct dwrite_textlayout *layout)
{
    HRESULT hr;

    if (!(layout->recompute & RECOMPUTE_CLUSTERS))
        return S_OK;

    /* nominal breakpoints are evaluated only once, because string never changes */
    if (!layout->nominal_breakpoints) {
        IDWriteTextAnalyzer *analyzer;

        layout->nominal_breakpoints = heap_alloc(layout->len * sizeof(*layout->nominal_breakpoints));
        if (!layout->nominal_breakpoints)
            return E_OUTOFMEMORY;

        analyzer = get_text_analyzer();

        if (FAILED(hr = IDWriteTextAnalyzer_AnalyzeLineBreakpoints(analyzer,
                (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface,
                0, layout->len, (IDWriteTextAnalysisSink *)&layout->IDWriteTextAnalysisSink1_iface)))
            WARN("Line breakpoints analysis failed, hr %#x.\n", hr);
    }

    heap_free(layout->actual_breakpoints);
    layout->actual_breakpoints = NULL;

    hr = layout_compute_runs(layout);

    if (TRACE_ON(dwrite)) {
        struct layout_run *cur;

        LIST_FOR_EACH_ENTRY(cur, &layout->runs, struct layout_run, entry) {
            if (cur->kind == LAYOUT_RUN_INLINE)
                TRACE("run inline object %p, len %u\n", cur->u.object.object, cur->u.object.length);
            else
                TRACE("run [%u,%u], len %u, bidilevel %u\n", cur->u.regular.descr.textPosition, cur->u.regular.descr.textPosition +
                    cur->u.regular.descr.stringLength-1, cur->u.regular.descr.stringLength, cur->u.regular.run.bidiLevel);
        }
    }

    layout->recompute &= ~RECOMPUTE_CLUSTERS;
    return hr;
}

static inline FLOAT get_cluster_range_width(struct dwrite_textlayout *layout, UINT32 start, UINT32 end)
{
    FLOAT width = 0.0f;
    for (; start < end; start++)
        width += layout->clustermetrics[start].width;
    return width;
}

static struct layout_range_header *get_layout_range_header_by_pos(struct list *ranges, UINT32 pos)
{
    struct layout_range_header *cur;

    LIST_FOR_EACH_ENTRY(cur, ranges, struct layout_range_header, entry) {
        DWRITE_TEXT_RANGE *r = &cur->range;
        if (r->startPosition <= pos && pos < r->startPosition + r->length)
            return cur;
    }

    return NULL;
}

static inline IUnknown *layout_get_effect_from_pos(struct dwrite_textlayout *layout, UINT32 pos)
{
    struct layout_range_header *h = get_layout_range_header_by_pos(&layout->effects, pos);
    return ((struct layout_range_iface*)h)->iface;
}

static inline BOOL layout_is_erun_rtl(const struct layout_effective_run *erun)
{
    return erun->run->u.regular.run.bidiLevel & 1;
}

/* A set of parameters that additionally splits resulting runs. It happens after shaping and all text processing,
   no glyph changes are possible. It's understandable for drawing effects, because DrawGlyphRun() reports them as
   one of the arguments, but it also happens for decorations, so every effective run has uniform
   underline/strikethough/effect tuple. */
struct layout_final_splitting_params {
    BOOL strikethrough;
    BOOL underline;
    IUnknown *effect;
};

static inline BOOL layout_get_strikethrough_from_pos(struct dwrite_textlayout *layout, UINT32 pos)
{
    struct layout_range_header *h = get_layout_range_header_by_pos(&layout->strike_ranges, pos);
    return ((struct layout_range_bool*)h)->value;
}

static inline BOOL layout_get_underline_from_pos(struct dwrite_textlayout *layout, UINT32 pos)
{
    struct layout_range_header *h = get_layout_range_header_by_pos(&layout->underline_ranges, pos);
    return ((struct layout_range_bool*)h)->value;
}

static void layout_splitting_params_from_pos(struct dwrite_textlayout *layout, UINT32 pos,
    struct layout_final_splitting_params *params)
{
    params->strikethrough = layout_get_strikethrough_from_pos(layout, pos);
    params->underline = layout_get_underline_from_pos(layout, pos);
    params->effect = layout_get_effect_from_pos(layout, pos);
}

static BOOL is_same_splitting_params(const struct layout_final_splitting_params *left,
    const struct layout_final_splitting_params *right)
{
    return left->strikethrough == right->strikethrough &&
           left->underline == right->underline &&
           left->effect == right->effect;
}

static void layout_get_erun_font_metrics(struct dwrite_textlayout *layout, struct layout_effective_run *erun,
    DWRITE_FONT_METRICS *metrics)
{
    memset(metrics, 0, sizeof(*metrics));
    if (is_layout_gdi_compatible(layout)) {
        HRESULT hr = IDWriteFontFace_GetGdiCompatibleMetrics(
            erun->run->u.regular.run.fontFace,
            erun->run->u.regular.run.fontEmSize,
            layout->ppdip,
            &layout->transform,
            metrics);
        if (FAILED(hr))
            WARN("failed to get font metrics, 0x%08x\n", hr);
    }
    else
        IDWriteFontFace_GetMetrics(erun->run->u.regular.run.fontFace, metrics);
}

/* Effective run is built from consecutive clusters of a single nominal run, 'first_cluster' is 0 based cluster index,
   'cluster_count' indicates how many clusters to add, including first one. */
static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const struct layout_run *r, UINT32 first_cluster,
    UINT32 cluster_count, UINT32 line, FLOAT origin_x, struct layout_final_splitting_params *params)
{
    BOOL is_rtl = layout->format.readingdir == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT;
    UINT32 i, start, length, last_cluster;
    struct layout_effective_run *run;

    if (r->kind == LAYOUT_RUN_INLINE) {
        struct layout_effective_inline *inlineobject;

        inlineobject = heap_alloc(sizeof(*inlineobject));
        if (!inlineobject)
            return E_OUTOFMEMORY;

        inlineobject->object = r->u.object.object;
        inlineobject->width = get_cluster_range_width(layout, first_cluster, first_cluster + cluster_count);
        inlineobject->origin.x = is_rtl ? origin_x - inlineobject->width : origin_x;
        inlineobject->origin.y = 0.0f; /* set after line is built */
        inlineobject->align_dx = 0.0f;
        inlineobject->baseline = r->baseline;

        /* It's not clear how these two are set, possibly directionality
           is derived from surrounding text (replaced text could have
           different ranges which differ in reading direction). */
        inlineobject->is_sideways = FALSE;
        inlineobject->is_rtl = FALSE;
        inlineobject->line = line;

        /* effect assigned from start position and on is used for inline objects */
        inlineobject->effect = layout_get_effect_from_pos(layout, layout->clusters[first_cluster].position +
                layout->clusters[first_cluster].run->start_position);

        list_add_tail(&layout->inlineobjects, &inlineobject->entry);
        return S_OK;
    }

    run = heap_alloc(sizeof(*run));
    if (!run)
        return E_OUTOFMEMORY;

    /* No need to iterate for that, use simple fact that:
       <last cluster position> = <first cluster position> + <sum of cluster lengths not including last one> */
    last_cluster = first_cluster + cluster_count - 1;
    length = layout->clusters[last_cluster].position - layout->clusters[first_cluster].position +
        layout->clustermetrics[last_cluster].length;

    run->clustermap = heap_alloc(sizeof(UINT16)*length);
    if (!run->clustermap) {
        heap_free(run);
        return E_OUTOFMEMORY;
    }

    run->run = r;
    run->start = start = layout->clusters[first_cluster].position;
    run->length = length;
    run->width = get_cluster_range_width(layout, first_cluster, first_cluster + cluster_count);
    memset(&run->bbox, 0, sizeof(run->bbox));

    /* Check if run direction matches paragraph direction, if it doesn't adjust by
       run width */
    if (layout_is_erun_rtl(run) ^ is_rtl)
        run->origin.x = is_rtl ? origin_x - run->width : origin_x + run->width;
    else
        run->origin.x = origin_x;

    run->origin.y = 0.0f; /* set after line is built */
    run->align_dx = 0.0f;
    run->line = line;

    if (r->u.regular.run.glyphCount) {
        /* Trim leading and trailing clusters. */
        run->glyphcount = r->u.regular.run.glyphCount - r->u.regular.clustermap[start];
        if (start + length < r->u.regular.descr.stringLength)
            run->glyphcount -= r->u.regular.run.glyphCount - r->u.regular.clustermap[start + length];
    }
    else
        run->glyphcount = 0;

    /* cluster map needs to be shifted */
    for (i = 0; i < length; i++)
        run->clustermap[i] = r->u.regular.clustermap[start + i] - r->u.regular.clustermap[start];

    run->effect = params->effect;
    run->underlined = params->underline;
    list_add_tail(&layout->eruns, &run->entry);

    /* Strikethrough style is guaranteed to be consistent within effective run,
       its width equals to run width, thickness and offset are derived from
       font metrics, rest of the values are from layout or run itself */
    if (params->strikethrough) {
        struct layout_strikethrough *s;
        DWRITE_FONT_METRICS metrics;

        s = heap_alloc(sizeof(*s));
        if (!s)
            return E_OUTOFMEMORY;

        layout_get_erun_font_metrics(layout, run, &metrics);
        s->s.width = get_cluster_range_width(layout, first_cluster, first_cluster + cluster_count);
        s->s.thickness = SCALE_FONT_METRIC(metrics.strikethroughThickness, r->u.regular.run.fontEmSize, &metrics);
        /* Negative offset moves it above baseline as Y coordinate grows downward. */
        s->s.offset = -SCALE_FONT_METRIC(metrics.strikethroughPosition, r->u.regular.run.fontEmSize, &metrics);
        s->s.readingDirection = layout->format.readingdir;
        s->s.flowDirection = layout->format.flow;
        s->s.localeName = r->u.regular.descr.localeName;
        s->s.measuringMode = layout->measuringmode;
        s->run = run;

        list_add_tail(&layout->strikethrough, &s->entry);
    }

    return S_OK;
}

static void layout_apply_line_spacing(struct dwrite_textlayout *layout, UINT32 line)
{
    switch (layout->format.spacing.method)
    {
    case DWRITE_LINE_SPACING_METHOD_DEFAULT:
        layout->linemetrics[line].height = layout->lines[line].height;
        layout->linemetrics[line].baseline = layout->lines[line].baseline;
        break;
    case DWRITE_LINE_SPACING_METHOD_UNIFORM:
        layout->linemetrics[line].height = layout->format.spacing.height;
        layout->linemetrics[line].baseline = layout->format.spacing.baseline;
        break;
    case DWRITE_LINE_SPACING_METHOD_PROPORTIONAL:
        layout->linemetrics[line].height = layout->lines[line].height * layout->format.spacing.height;
        layout->linemetrics[line].baseline = layout->lines[line].baseline * layout->format.spacing.baseline;
        break;
    default:
        ERR("Unknown spacing method %u\n", layout->format.spacing.method);
    }
}

static HRESULT layout_set_line_metrics(struct dwrite_textlayout *layout, DWRITE_LINE_METRICS1 *metrics)
{
    UINT32 i = layout->metrics.lineCount;

    if (!layout->line_alloc) {
        layout->line_alloc = 5;
        layout->linemetrics = heap_alloc(layout->line_alloc * sizeof(*layout->linemetrics));
        layout->lines = heap_alloc(layout->line_alloc * sizeof(*layout->lines));
        if (!layout->linemetrics || !layout->lines) {
            heap_free(layout->linemetrics);
            heap_free(layout->lines);
            layout->linemetrics = NULL;
            layout->lines = NULL;
            return E_OUTOFMEMORY;
        }
    }

    if (layout->metrics.lineCount == layout->line_alloc) {
        DWRITE_LINE_METRICS1 *metrics;
        struct layout_line *lines;

        if ((metrics = heap_realloc(layout->linemetrics, layout->line_alloc * 2 * sizeof(*layout->linemetrics))))
            layout->linemetrics = metrics;
        if ((lines = heap_realloc(layout->lines, layout->line_alloc * 2 * sizeof(*layout->lines))))
            layout->lines = lines;

        if (!metrics || !lines)
            return E_OUTOFMEMORY;

        layout->line_alloc *= 2;
    }

    layout->linemetrics[i] = *metrics;
    layout->lines[i].height = metrics->height;
    layout->lines[i].baseline = metrics->baseline;

    if (layout->format.spacing.method != DWRITE_LINE_SPACING_METHOD_DEFAULT)
        layout_apply_line_spacing(layout, i);

    layout->metrics.lineCount++;
    return S_OK;
}

static inline struct layout_effective_run *layout_get_next_erun(struct dwrite_textlayout *layout,
    const struct layout_effective_run *cur)
{
    struct list *e;

    if (!cur)
        e = list_head(&layout->eruns);
    else
        e = list_next(&layout->eruns, &cur->entry);
    if (!e)
        return NULL;
    return LIST_ENTRY(e, struct layout_effective_run, entry);
}

static inline struct layout_effective_run *layout_get_prev_erun(struct dwrite_textlayout *layout,
    const struct layout_effective_run *cur)
{
    struct list *e;

    if (!cur)
        e = list_tail(&layout->eruns);
    else
        e = list_prev(&layout->eruns, &cur->entry);
    if (!e)
        return NULL;
    return LIST_ENTRY(e, struct layout_effective_run, entry);
}

static inline struct layout_effective_inline *layout_get_next_inline_run(struct dwrite_textlayout *layout,
    const struct layout_effective_inline *cur)
{
    struct list *e;

    if (!cur)
        e = list_head(&layout->inlineobjects);
    else
        e = list_next(&layout->inlineobjects, &cur->entry);
    if (!e)
        return NULL;
    return LIST_ENTRY(e, struct layout_effective_inline, entry);
}

static FLOAT layout_get_line_width(struct dwrite_textlayout *layout,
    struct layout_effective_run *erun, struct layout_effective_inline *inrun, UINT32 line)
{
    FLOAT width = 0.0f;

    while (erun && erun->line == line) {
        width += erun->width;
        erun = layout_get_next_erun(layout, erun);
        if (!erun)
            break;
    }

    while (inrun && inrun->line == line) {
        width += inrun->width;
        inrun = layout_get_next_inline_run(layout, inrun);
        if (!inrun)
            break;
    }

    return width;
}

static inline BOOL should_skip_transform(const DWRITE_MATRIX *m, FLOAT *det)
{
    *det = m->m11 * m->m22 - m->m12 * m->m21;
    /* on certain conditions we can skip transform */
    return (!memcmp(m, &identity, sizeof(*m)) || fabsf(*det) <= 1e-10f);
}

static inline void layout_apply_snapping(D2D1_POINT_2F *vec, BOOL skiptransform, FLOAT ppdip,
    const DWRITE_MATRIX *m, FLOAT det)
{
    if (!skiptransform) {
        D2D1_POINT_2F vec2;

        /* apply transform */
        vec->x *= ppdip;
        vec->y *= ppdip;

        vec2.x = m->m11 * vec->x + m->m21 * vec->y + m->dx;
        vec2.y = m->m12 * vec->x + m->m22 * vec->y + m->dy;

        /* snap */
        vec2.x = floorf(vec2.x + 0.5f);
        vec2.y = floorf(vec2.y + 0.5f);

        /* apply inverted transform, we don't care about X component at this point */
        vec->x = (m->m22 * vec2.x - m->m21 * vec2.y + m->m21 * m->dy - m->m22 * m->dx) / det;
        vec->x /= ppdip;

        vec->y = (-m->m12 * vec2.x + m->m11 * vec2.y - (m->m11 * m->dy - m->m12 * m->dx)) / det;
        vec->y /= ppdip;
    }
    else {
        vec->x = floorf(vec->x * ppdip + 0.5f) / ppdip;
        vec->y = floorf(vec->y * ppdip + 0.5f) / ppdip;
    }
}

static void layout_apply_leading_alignment(struct dwrite_textlayout *layout)
{
    BOOL is_rtl = layout->format.readingdir == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT;
    struct layout_effective_inline *inrun;
    struct layout_effective_run *erun;

    erun = layout_get_next_erun(layout, NULL);
    inrun = layout_get_next_inline_run(layout, NULL);

    while (erun) {
        erun->align_dx = 0.0f;
        erun = layout_get_next_erun(layout, erun);
    }

    while (inrun) {
        inrun->align_dx = 0.0f;
        inrun = layout_get_next_inline_run(layout, inrun);
    }

    layout->metrics.left = is_rtl ? layout->metrics.layoutWidth - layout->metrics.width : 0.0f;
}

static void layout_apply_trailing_alignment(struct dwrite_textlayout *layout)
{
    BOOL is_rtl = layout->format.readingdir == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT;
    struct layout_effective_inline *inrun;
    struct layout_effective_run *erun;
    UINT32 line;

    erun = layout_get_next_erun(layout, NULL);
    inrun = layout_get_next_inline_run(layout, NULL);

    for (line = 0; line < layout->metrics.lineCount; line++) {
        FLOAT width = layout_get_line_width(layout, erun, inrun, line);
        FLOAT shift = layout->metrics.layoutWidth - width;

        if (is_rtl)
            shift *= -1.0f;

        while (erun && erun->line == line) {
            erun->align_dx = shift;
            erun = layout_get_next_erun(layout, erun);
        }

        while (inrun && inrun->line == line) {
            inrun->align_dx = shift;
            inrun = layout_get_next_inline_run(layout, inrun);
        }
    }

    layout->metrics.left = is_rtl ? 0.0f : layout->metrics.layoutWidth - layout->metrics.width;
}

static inline FLOAT layout_get_centered_shift(struct dwrite_textlayout *layout, BOOL skiptransform,
    FLOAT width, FLOAT det)
{
    if (is_layout_gdi_compatible(layout)) {
        D2D1_POINT_2F vec = { layout->metrics.layoutWidth - width, 0.0f};
        layout_apply_snapping(&vec, skiptransform, layout->ppdip, &layout->transform, det);
        return floorf(vec.x / 2.0f);
    }
    else
        return (layout->metrics.layoutWidth - width) / 2.0f;
}

static void layout_apply_centered_alignment(struct dwrite_textlayout *layout)
{
    BOOL is_rtl = layout->format.readingdir == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT;
    struct layout_effective_inline *inrun;
    struct layout_effective_run *erun;
    BOOL skiptransform;
    UINT32 line;
    FLOAT det;

    erun = layout_get_next_erun(layout, NULL);
    inrun = layout_get_next_inline_run(layout, NULL);

    skiptransform = should_skip_transform(&layout->transform, &det);

    for (line = 0; line < layout->metrics.lineCount; line++) {
        FLOAT width = layout_get_line_width(layout, erun, inrun, line);
        FLOAT shift = layout_get_centered_shift(layout, skiptransform, width, det);

        if (is_rtl)
            shift *= -1.0f;

        while (erun && erun->line == line) {
            erun->align_dx = shift;
            erun = layout_get_next_erun(layout, erun);
        }

        while (inrun && inrun->line == line) {
            inrun->align_dx = shift;
            inrun = layout_get_next_inline_run(layout, inrun);
        }
    }

    layout->metrics.left = (layout->metrics.layoutWidth - layout->metrics.width) / 2.0f;
}

static void layout_apply_text_alignment(struct dwrite_textlayout *layout)
{
    switch (layout->format.textalignment)
    {
    case DWRITE_TEXT_ALIGNMENT_LEADING:
        layout_apply_leading_alignment(layout);
        break;
    case DWRITE_TEXT_ALIGNMENT_TRAILING:
        layout_apply_trailing_alignment(layout);
        break;
    case DWRITE_TEXT_ALIGNMENT_CENTER:
        layout_apply_centered_alignment(layout);
        break;
    case DWRITE_TEXT_ALIGNMENT_JUSTIFIED:
        FIXME("alignment %d not implemented\n", layout->format.textalignment);
        break;
    default:
        ;
    }
}

static void layout_apply_par_alignment(struct dwrite_textlayout *layout)
{
    struct layout_effective_inline *inrun;
    struct layout_effective_run *erun;
    FLOAT origin_y = 0.0f;
    UINT32 line;

    /* alignment mode defines origin, after that all run origins are updated
       the same way */

    switch (layout->format.paralign)
    {
    case DWRITE_PARAGRAPH_ALIGNMENT_NEAR:
        origin_y = 0.0f;
        break;
    case DWRITE_PARAGRAPH_ALIGNMENT_FAR:
        origin_y = layout->metrics.layoutHeight - layout->metrics.height;
        break;
    case DWRITE_PARAGRAPH_ALIGNMENT_CENTER:
        origin_y = (layout->metrics.layoutHeight - layout->metrics.height) / 2.0f;
        break;
    default:
        ;
    }

    layout->metrics.top = origin_y;

    erun = layout_get_next_erun(layout, NULL);
    inrun = layout_get_next_inline_run(layout, NULL);
    for (line = 0; line < layout->metrics.lineCount; line++) {
        FLOAT pos_y = origin_y + layout->linemetrics[line].baseline;

        while (erun && erun->line == line) {
            erun->origin.y = pos_y;
            erun = layout_get_next_erun(layout, erun);
        }

        while (inrun && inrun->line == line) {
            inrun->origin.y = pos_y - inrun->baseline;
            inrun = layout_get_next_inline_run(layout, inrun);
        }

        origin_y += layout->linemetrics[line].height;
    }
}

struct layout_underline_splitting_params {
    const WCHAR *locale; /* points to range data, no additional allocation */
    IUnknown *effect;    /* does not hold another reference */
};

static void init_u_splitting_params_from_erun(struct layout_effective_run *erun,
    struct layout_underline_splitting_params *params)
{
    params->locale = erun->run->u.regular.descr.localeName;
    params->effect = erun->effect;
}

static BOOL is_same_u_splitting(struct layout_underline_splitting_params *left,
    struct layout_underline_splitting_params *right)
{
    return left->effect == right->effect && !strcmpiW(left->locale, right->locale);
}

static HRESULT layout_add_underline(struct dwrite_textlayout *layout, struct layout_effective_run *first,
    struct layout_effective_run *last)
{
    FLOAT thickness, offset, runheight;
    struct layout_effective_run *cur;
    DWRITE_FONT_METRICS metrics;

    if (first == layout_get_prev_erun(layout, last)) {
        layout_get_erun_font_metrics(layout, first, &metrics);
        thickness = SCALE_FONT_METRIC(metrics.underlineThickness, first->run->u.regular.run.fontEmSize, &metrics);
        offset = SCALE_FONT_METRIC(metrics.underlinePosition, first->run->u.regular.run.fontEmSize, &metrics);
        runheight = SCALE_FONT_METRIC(metrics.capHeight, first->run->u.regular.run.fontEmSize, &metrics);
    }
    else {
        FLOAT width = 0.0f;

        /* Single underline is added for consecutive underlined runs. In this case underline parameters are
           calculated as weighted average, where run width acts as a weight. */
        thickness = offset = runheight = 0.0f;
        cur = first;
        do {
            layout_get_erun_font_metrics(layout, cur, &metrics);

            thickness += SCALE_FONT_METRIC(metrics.underlineThickness, cur->run->u.regular.run.fontEmSize, &metrics) * cur->width;
            offset += SCALE_FONT_METRIC(metrics.underlinePosition, cur->run->u.regular.run.fontEmSize, &metrics) * cur->width;
            runheight = max(SCALE_FONT_METRIC(metrics.capHeight, cur->run->u.regular.run.fontEmSize, &metrics), runheight);
            width += cur->width;

            cur = layout_get_next_erun(layout, cur);
        } while (cur != last);

        thickness /= width;
        offset /= width;
    }

    cur = first;
    do {
        struct layout_underline_splitting_params params, prev_params;
        struct layout_effective_run *next, *w;
        struct layout_underline *u;

        init_u_splitting_params_from_erun(cur, &prev_params);
        while ((next = layout_get_next_erun(layout, cur)) != last) {
            init_u_splitting_params_from_erun(next, &params);
            if (!is_same_u_splitting(&prev_params, &params))
                break;
            cur = next;
        }

        u = heap_alloc(sizeof(*u));
        if (!u)
            return E_OUTOFMEMORY;

        w = cur;
        u->u.width = 0.0f;
        while (w != next) {
            u->u.width += w->width;
            w = layout_get_next_erun(layout, w);
        }

        u->u.thickness = thickness;
        /* Font metrics convention is to have it negative when below baseline, for rendering
           however Y grows from baseline down for horizontal baseline. */
        u->u.offset = -offset;
        u->u.runHeight = runheight;
        u->u.readingDirection = is_run_rtl(cur) ? DWRITE_READING_DIRECTION_RIGHT_TO_LEFT :
            DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
        u->u.flowDirection = layout->format.flow;
        u->u.localeName = cur->run->u.regular.descr.localeName;
        u->u.measuringMode = layout->measuringmode;
        u->run = cur;
        list_add_tail(&layout->underlines, &u->entry);

        cur = next;
    } while (cur != last);

    return S_OK;
}

/* Adds zero width line, metrics are derived from font at specified text position. */
static HRESULT layout_set_dummy_line_metrics(struct dwrite_textlayout *layout, UINT32 pos)
{
    DWRITE_LINE_METRICS1 metrics = { 0 };
    DWRITE_FONT_METRICS fontmetrics;
    struct layout_range *range;
    IDWriteFontFace *fontface;
    IDWriteFont *font;
    HRESULT hr;

    range = get_layout_range_by_pos(layout, pos);
    hr = create_matching_font(range->collection,
        range->fontfamily,
        range->weight,
        range->style,
        range->stretch,
        &font);
    if (FAILED(hr))
        return hr;
    hr = IDWriteFont_CreateFontFace(font, &fontface);
    IDWriteFont_Release(font);
    if (FAILED(hr))
        return hr;

    layout_get_font_metrics(layout, fontface, range->fontsize, &fontmetrics);
    layout_get_font_height(range->fontsize, &fontmetrics, &metrics.baseline, &metrics.height);
    IDWriteFontFace_Release(fontface);

    return layout_set_line_metrics(layout, &metrics);
}

static void layout_add_line(struct dwrite_textlayout *layout, UINT32 first_cluster, UINT32 last_cluster,
        UINT32 *textpos)
{
    BOOL is_rtl = layout->format.readingdir == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT;
    struct layout_final_splitting_params params, prev_params;
    DWRITE_INLINE_OBJECT_METRICS sign_metrics = { 0 };
    UINT32 line = layout->metrics.lineCount, i;
    DWRITE_LINE_METRICS1 metrics = { 0 };
    UINT32 index, start, pos = *textpos;
    FLOAT descent, trailingspacewidth;
    BOOL append_trimming_run = FALSE;
    const struct layout_run *run;
    FLOAT width, origin_x;
    HRESULT hr;

    /* Take a look at clusters we got for this line in reverse order to set trailing properties for current line */
    for (index = last_cluster, trailingspacewidth = 0.0f; index >= first_cluster; index--) {
        DWRITE_CLUSTER_METRICS *cluster = &layout->clustermetrics[index];
        struct layout_cluster *lc = &layout->clusters[index];
        WCHAR ch;

        /* This also filters out clusters added from inline objects, those are never
           treated as a white space. */
        if (!cluster->isWhitespace)
            break;

        /* Every isNewline cluster is also isWhitespace, but not every
           newline character cluster has isNewline set, so go back to original string. */
        ch = lc->run->u.regular.descr.string[lc->position];
        if (cluster->length == 1 && lb_is_newline_char(ch))
            metrics.newlineLength += cluster->length;

        metrics.trailingWhitespaceLength += cluster->length;
        trailingspacewidth += cluster->width;
    }

    /* Line metrics length includes trailing whitespace length too */
    for (i = first_cluster; i <= last_cluster; i++)
        metrics.length += layout->clustermetrics[i].length;

    /* Ignore trailing whitespaces */
    while (last_cluster > first_cluster) {
        if (!layout->clustermetrics[last_cluster].isWhitespace)
            break;

        last_cluster--;
    }

    /* Does not include trailing space width */
    width = get_cluster_range_width(layout, first_cluster, last_cluster + 1);

    /* Append trimming run if necessary */
    if (width > layout->metrics.layoutWidth && layout->format.trimmingsign != NULL &&
            layout->format.trimming.granularity != DWRITE_TRIMMING_GRANULARITY_NONE) {
        FLOAT trimmed_width = width;

        hr = IDWriteInlineObject_GetMetrics(layout->format.trimmingsign, &sign_metrics);
        if (SUCCEEDED(hr)) {
            while (last_cluster > first_cluster) {
                if (trimmed_width + sign_metrics.width <= layout->metrics.layoutWidth)
                    break;
                if (layout->format.trimming.granularity == DWRITE_TRIMMING_GRANULARITY_CHARACTER)
                    trimmed_width -= layout->clustermetrics[last_cluster--].width;
                else {
                    while (last_cluster > first_cluster) {
                        trimmed_width -= layout->clustermetrics[last_cluster].width;
                        if (layout->clustermetrics[last_cluster--].canWrapLineAfter)
                            break;
                    }
                }
            }
            append_trimming_run = TRUE;
        }
        else
            WARN("Failed to get trimming sign metrics, lines won't be trimmed, hr %#x.\n", hr);

        width = trimmed_width + sign_metrics.width;
    }

    layout_splitting_params_from_pos(layout, pos, &params);
    prev_params = params;
    run = layout->clusters[first_cluster].run;

    /* Form runs from a range of clusters; this is what will be reported with DrawGlyphRun() */
    origin_x = is_rtl ? layout->metrics.layoutWidth : 0.0f;
    for (start = first_cluster, i = first_cluster; i <= last_cluster; i++) {
        layout_splitting_params_from_pos(layout, pos, &params);

        if (run != layout->clusters[i].run || !is_same_splitting_params(&prev_params, &params)) {
            hr = layout_add_effective_run(layout, run, start, i - start, line, origin_x, &prev_params);
            if (FAILED(hr))
                return;

            origin_x += is_rtl ? -get_cluster_range_width(layout, start, i) :
                get_cluster_range_width(layout, start, i);
            run = layout->clusters[i].run;
            start = i;
        }

        prev_params = params;
        pos += layout->clustermetrics[i].length;
    }

    /* Final run from what's left from cluster range */
    hr = layout_add_effective_run(layout, run, start, i - start, line, origin_x, &prev_params);
    if (FAILED(hr))
        return;

    if (append_trimming_run) {
        struct layout_effective_inline *trimming_sign;

        trimming_sign = heap_alloc(sizeof(*trimming_sign));
        if (!trimming_sign)
            return;

        trimming_sign->object = layout->format.trimmingsign;
        trimming_sign->width = sign_metrics.width;
        origin_x += is_rtl ? -get_cluster_range_width(layout, start, i) : get_cluster_range_width(layout, start, i);
        trimming_sign->origin.x = is_rtl ? origin_x - trimming_sign->width : origin_x;
        trimming_sign->origin.y = 0.0f; /* set after line is built */
        trimming_sign->align_dx = 0.0f;
        trimming_sign->baseline = sign_metrics.baseline;

        trimming_sign->is_sideways = FALSE;
        trimming_sign->is_rtl = FALSE;
        trimming_sign->line = line;

        trimming_sign->effect = layout_get_effect_from_pos(layout, layout->clusters[i].position +
                layout->clusters[i].run->start_position);

        list_add_tail(&layout->inlineobjects, &trimming_sign->entry);
    }

    /* Look for max baseline and descent for this line */
    for (index = first_cluster, metrics.baseline = 0.0f, descent = 0.0f; index <= last_cluster; index++) {
        const struct layout_run *cur = layout->clusters[index].run;
        FLOAT cur_descent = cur->height - cur->baseline;

        if (cur->baseline > metrics.baseline)
            metrics.baseline = cur->baseline;
        if (cur_descent > descent)
            descent = cur_descent;
    }

    layout->metrics.width = max(width, layout->metrics.width);
    layout->metrics.widthIncludingTrailingWhitespace = max(width + trailingspacewidth,
        layout->metrics.widthIncludingTrailingWhitespace);

    metrics.height = descent + metrics.baseline;
    metrics.isTrimmed = append_trimming_run || width > layout->metrics.layoutWidth;
    layout_set_line_metrics(layout, &metrics);

    *textpos += metrics.length;
}

static void layout_set_line_positions(struct dwrite_textlayout *layout)
{
    struct layout_effective_inline *inrun;
    struct layout_effective_run *erun;
    FLOAT origin_y;
    UINT32 line;

    /* Now all line info is here, update effective runs positions in flow direction */
    erun = layout_get_next_erun(layout, NULL);
    inrun = layout_get_next_inline_run(layout, NULL);

    for (line = 0, origin_y = 0.0f; line < layout->metrics.lineCount; line++) {
        FLOAT pos_y = origin_y + layout->linemetrics[line].baseline;

        /* For all runs on this line */
        while (erun && erun->line == line) {
            erun->origin.y = pos_y;
            erun = layout_get_next_erun(layout, erun);
        }

        /* Same for inline runs */
        while (inrun && inrun->line == line) {
            inrun->origin.y = pos_y - inrun->baseline;
            inrun = layout_get_next_inline_run(layout, inrun);
        }

        origin_y += layout->linemetrics[line].height;
    }

    layout->metrics.height = origin_y;

    /* Initial paragraph alignment is always near */
    if (layout->format.paralign != DWRITE_PARAGRAPH_ALIGNMENT_NEAR)
        layout_apply_par_alignment(layout);
}

static BOOL layout_can_wrap_after(const struct dwrite_textlayout *layout, UINT32 cluster)
{
    if (layout->format.wrapping == DWRITE_WORD_WRAPPING_CHARACTER)
        return TRUE;

    return layout->clustermetrics[cluster].canWrapLineAfter;
}

static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
{
    BOOL is_rtl = layout->format.readingdir == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT;
    struct layout_effective_run *erun, *first_underlined;
    UINT32 i, start, textpos, last_breaking_point;
    DWRITE_LINE_METRICS1 metrics;
    FLOAT width;
    UINT32 line;
    HRESULT hr;

    if (!(layout->recompute & RECOMPUTE_LINES))
        return S_OK;

    free_layout_eruns(layout);

    hr = layout_compute(layout);
    if (FAILED(hr))
        return hr;

    layout->metrics.lineCount = 0;
    memset(&metrics, 0, sizeof(metrics));

    layout->metrics.height = 0.0f;
    layout->metrics.width = 0.0f;
    layout->metrics.widthIncludingTrailingWhitespace = 0.0f;

    last_breaking_point = ~0u;

    for (i = 0, start = 0, width = 0.0f, textpos = 0; i < layout->cluster_count; i++) {
        BOOL overflow = FALSE;

        while (i < layout->cluster_count && !layout->clustermetrics[i].isNewline) {
            /* Check for overflow */
            overflow = ((width + layout->clustermetrics[i].width > layout->metrics.layoutWidth) &&
                    (layout->format.wrapping != DWRITE_WORD_WRAPPING_NO_WRAP));
            if (overflow)
                break;

            if (layout_can_wrap_after(layout, i))
                last_breaking_point = i;
            width += layout->clustermetrics[i].width;
            i++;
        }
        i = min(i, layout->cluster_count - 1);

        /* Ignore if overflown on whitespace */
        if (overflow && !(layout->clustermetrics[i].isWhitespace && layout_can_wrap_after(layout, i))) {
            /* Use most recently found breaking point */
            if (last_breaking_point != ~0u) {
                i = last_breaking_point;
                last_breaking_point = ~0u;
            }
            else {
                /* Otherwise proceed forward to next newline or breaking point */
                for (; i < layout->cluster_count; i++)
                    if (layout_can_wrap_after(layout, i) || layout->clustermetrics[i].isNewline)
                        break;
            }
        }
        i = min(i, layout->cluster_count - 1);

        layout_add_line(layout, start, i, &textpos);
        start = i + 1;
        width = 0.0f;
    }

    /* Add dummy line if:
       - there's no text, metrics come from first range in this case;
       - last ended with a mandatory break, metrics come from last text position.
    */
    if (layout->len == 0)
        hr = layout_set_dummy_line_metrics(layout, 0);
    else if (layout->clustermetrics[layout->cluster_count - 1].isNewline)
        hr = layout_set_dummy_line_metrics(layout, layout->len - 1);
    if (FAILED(hr))
        return hr;

    layout->metrics.left = is_rtl ? layout->metrics.layoutWidth - layout->metrics.width : 0.0f;
    layout->metrics.top = 0.0f;
    layout->metrics.maxBidiReorderingDepth = 1; /* FIXME */

    /* Add explicit underlined runs */
    erun = layout_get_next_erun(layout, NULL);
    first_underlined = erun && erun->underlined ? erun : NULL;
    for (line = 0; line < layout->metrics.lineCount; line++) {
        while (erun && erun->line == line) {
            erun = layout_get_next_erun(layout, erun);

            if (first_underlined && (!erun || !erun->underlined)) {
                layout_add_underline(layout, first_underlined, erun);
                first_underlined = NULL;
            }
            else if (!first_underlined && erun && erun->underlined)
                first_underlined = erun;
        }
    }

    /* Position runs in flow direction */
    layout_set_line_positions(layout);

    /* Initial alignment is always leading */
    if (layout->format.textalignment != DWRITE_TEXT_ALIGNMENT_LEADING)
        layout_apply_text_alignment(layout);

    layout->recompute &= ~RECOMPUTE_LINES;
    return hr;
}

static BOOL is_same_layout_attrvalue(struct layout_range_header const *h, enum layout_range_attr_kind attr,
        struct layout_range_attr_value *value)
{
    struct layout_range_spacing const *range_spacing = (struct layout_range_spacing*)h;
    struct layout_range_iface const *range_iface = (struct layout_range_iface*)h;
    struct layout_range_bool const *range_bool = (struct layout_range_bool*)h;
    struct layout_range const *range = (struct layout_range*)h;

    switch (attr) {
    case LAYOUT_RANGE_ATTR_WEIGHT:
        return range->weight == value->u.weight;
    case LAYOUT_RANGE_ATTR_STYLE:
        return range->style == value->u.style;
    case LAYOUT_RANGE_ATTR_STRETCH:
        return range->stretch == value->u.stretch;
    case LAYOUT_RANGE_ATTR_FONTSIZE:
        return range->fontsize == value->u.fontsize;
    case LAYOUT_RANGE_ATTR_INLINE:
        return range->object == value->u.object;
    case LAYOUT_RANGE_ATTR_EFFECT:
        return range_iface->iface == value->u.effect;
    case LAYOUT_RANGE_ATTR_UNDERLINE:
        return range_bool->value == value->u.underline;
    case LAYOUT_RANGE_ATTR_STRIKETHROUGH:
        return range_bool->value == value->u.strikethrough;
    case LAYOUT_RANGE_ATTR_PAIR_KERNING:
        return range->pair_kerning == value->u.pair_kerning;
    case LAYOUT_RANGE_ATTR_FONTCOLL:
        return range->collection == value->u.collection;
    case LAYOUT_RANGE_ATTR_LOCALE:
        return strcmpiW(range->locale, value->u.locale) == 0;
    case LAYOUT_RANGE_ATTR_FONTFAMILY:
        return strcmpW(range->fontfamily, value->u.fontfamily) == 0;
    case LAYOUT_RANGE_ATTR_SPACING:
        return range_spacing->leading == value->u.spacing.leading &&
               range_spacing->trailing == value->u.spacing.trailing &&
               range_spacing->min_advance == value->u.spacing.min_advance;
    case LAYOUT_RANGE_ATTR_TYPOGRAPHY:
        return range_iface->iface == (IUnknown*)value->u.typography;
    default:
        ;
    }

    return FALSE;
}

static inline BOOL is_same_layout_attributes(struct layout_range_header const *hleft, struct layout_range_header const *hright)
{
    switch (hleft->kind)
    {
    case LAYOUT_RANGE_REGULAR:
    {
        struct layout_range const *left = (struct layout_range const*)hleft;
        struct layout_range const *right = (struct layout_range const*)hright;
        return left->weight == right->weight &&
               left->style  == right->style &&
               left->stretch == right->stretch &&
               left->fontsize == right->fontsize &&
               left->object == right->object &&
               left->pair_kerning == right->pair_kerning &&
               left->collection == right->collection &&
              !strcmpiW(left->locale, right->locale) &&
              !strcmpW(left->fontfamily, right->fontfamily);
    }
    case LAYOUT_RANGE_UNDERLINE:
    case LAYOUT_RANGE_STRIKETHROUGH:
    {
        struct layout_range_bool const *left = (struct layout_range_bool const*)hleft;
        struct layout_range_bool const *right = (struct layout_range_bool const*)hright;
        return left->value == right->value;
    }
    case LAYOUT_RANGE_EFFECT:
    case LAYOUT_RANGE_TYPOGRAPHY:
    {
        struct layout_range_iface const *left = (struct layout_range_iface const*)hleft;
        struct layout_range_iface const *right = (struct layout_range_iface const*)hright;
        return left->iface == right->iface;
    }
    case LAYOUT_RANGE_SPACING:
    {
        struct layout_range_spacing const *left = (struct layout_range_spacing const*)hleft;
        struct layout_range_spacing const *right = (struct layout_range_spacing const*)hright;
        return left->leading == right->leading &&
               left->trailing == right->trailing &&
               left->min_advance == right->min_advance;
    }
    default:
        FIXME("unknown range kind %d\n", hleft->kind);
        return FALSE;
    }
}

static inline BOOL is_same_text_range(const DWRITE_TEXT_RANGE *left, const DWRITE_TEXT_RANGE *right)
{
    return left->startPosition == right->startPosition && left->length == right->length;
}

/* Allocates range and inits it with default values from text format. */
static struct layout_range_header *alloc_layout_range(struct dwrite_textlayout *layout, const DWRITE_TEXT_RANGE *r,
    enum layout_range_kind kind)
{
    struct layout_range_header *h;

    switch (kind)
    {
    case LAYOUT_RANGE_REGULAR:
    {
        struct layout_range *range;

        range = heap_alloc(sizeof(*range));
        if (!range) return NULL;

        range->weight = layout->format.weight;
        range->style  = layout->format.style;
        range->stretch = layout->format.stretch;
        range->fontsize = layout->format.fontsize;
        range->object = NULL;
        range->pair_kerning = FALSE;

        range->fontfamily = heap_strdupW(layout->format.family_name);
        if (!range->fontfamily) {
            heap_free(range);
            return NULL;
        }

        range->collection = layout->format.collection;
        if (range->collection)
            IDWriteFontCollection_AddRef(range->collection);
        strcpyW(range->locale, layout->format.locale);

        h = &range->h;
        break;
    }
    case LAYOUT_RANGE_UNDERLINE:
    case LAYOUT_RANGE_STRIKETHROUGH:
    {
        struct layout_range_bool *range;

        range = heap_alloc(sizeof(*range));
        if (!range) return NULL;

        range->value = FALSE;
        h = &range->h;
        break;
    }
    case LAYOUT_RANGE_EFFECT:
    case LAYOUT_RANGE_TYPOGRAPHY:
    {
        struct layout_range_iface *range;

        range = heap_alloc(sizeof(*range));
        if (!range) return NULL;

        range->iface = NULL;
        h = &range->h;
        break;
    }
    case LAYOUT_RANGE_SPACING:
    {
        struct layout_range_spacing *range;

        range = heap_alloc(sizeof(*range));
        if (!range) return NULL;

        range->leading = 0.0f;
        range->trailing = 0.0f;
        range->min_advance = 0.0f;
        h = &range->h;
        break;
    }
    default:
        FIXME("unknown range kind %d\n", kind);
        return NULL;
    }

    h->kind = kind;
    h->range = *r;
    return h;
}

static struct layout_range_header *alloc_layout_range_from(struct layout_range_header *h, const DWRITE_TEXT_RANGE *r)
{
    struct layout_range_header *ret;

    switch (h->kind)
    {
    case LAYOUT_RANGE_REGULAR:
    {
        struct layout_range *from = (struct layout_range*)h;

        struct layout_range *range = heap_alloc(sizeof(*range));
        if (!range) return NULL;

        *range = *from;
        range->fontfamily = heap_strdupW(from->fontfamily);
        if (!range->fontfamily) {
            heap_free(range);
            return NULL;
        }

        /* update refcounts */
        if (range->object)
            IDWriteInlineObject_AddRef(range->object);
        if (range->collection)
            IDWriteFontCollection_AddRef(range->collection);
        ret = &range->h;
        break;
    }
    case LAYOUT_RANGE_UNDERLINE:
    case LAYOUT_RANGE_STRIKETHROUGH:
    {
        struct layout_range_bool *strike = heap_alloc(sizeof(*strike));
        if (!strike) return NULL;

        *strike = *(struct layout_range_bool*)h;
        ret = &strike->h;
        break;
    }
    case LAYOUT_RANGE_EFFECT:
    case LAYOUT_RANGE_TYPOGRAPHY:
    {
        struct layout_range_iface *effect = heap_alloc(sizeof(*effect));
        if (!effect) return NULL;

        *effect = *(struct layout_range_iface*)h;
        if (effect->iface)
            IUnknown_AddRef(effect->iface);
        ret = &effect->h;
        break;
    }
    case LAYOUT_RANGE_SPACING:
    {
        struct layout_range_spacing *spacing = heap_alloc(sizeof(*spacing));
        if (!spacing) return NULL;

        *spacing = *(struct layout_range_spacing*)h;
        ret = &spacing->h;
        break;
    }
    default:
        FIXME("unknown range kind %d\n", h->kind);
        return NULL;
    }

    ret->range = *r;
    return ret;
}

static void free_layout_range(struct layout_range_header *h)
{
    if (!h)
        return;

    switch (h->kind)
    {
    case LAYOUT_RANGE_REGULAR:
    {
        struct layout_range *range = (struct layout_range*)h;

        if (range->object)
            IDWriteInlineObject_Release(range->object);
        if (range->collection)
            IDWriteFontCollection_Release(range->collection);
        heap_free(range->fontfamily);
        break;
    }
    case LAYOUT_RANGE_EFFECT:
    case LAYOUT_RANGE_TYPOGRAPHY:
    {
        struct layout_range_iface *range = (struct layout_range_iface*)h;
        if (range->iface)
            IUnknown_Release(range->iface);
        break;
    }
    default:
        ;
    }

    heap_free(h);
}

static void free_layout_ranges_list(struct dwrite_textlayout *layout)
{
    struct layout_range_header *cur, *cur2;

    LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->ranges, struct layout_range_header, entry) {
        list_remove(&cur->entry);
        free_layout_range(cur);
    }

    LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->underline_ranges, struct layout_range_header, entry) {
        list_remove(&cur->entry);
        free_layout_range(cur);
    }

    LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->strike_ranges, struct layout_range_header, entry) {
        list_remove(&cur->entry);
        free_layout_range(cur);
    }

    LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->effects, struct layout_range_header, entry) {
        list_remove(&cur->entry);
        free_layout_range(cur);
    }

    LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->spacing, struct layout_range_header, entry) {
        list_remove(&cur->entry);
        free_layout_range(cur);
    }

    LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->typographies, struct layout_range_header, entry) {
        list_remove(&cur->entry);
        free_layout_range(cur);
    }
}

static struct layout_range_header *find_outer_range(struct list *ranges, const DWRITE_TEXT_RANGE *range)
{
    struct layout_range_header *cur;

    LIST_FOR_EACH_ENTRY(cur, ranges, struct layout_range_header, entry) {

        if (cur->range.startPosition > range->startPosition)
            return NULL;

        if ((cur->range.startPosition + cur->range.length < range->startPosition + range->length) &&
            (range->startPosition < cur->range.startPosition + cur->range.length))
            return NULL;
        if (cur->range.startPosition + cur->range.length >= range->startPosition + range->length)
            return cur;
    }

    return NULL;
}

static struct layout_range *get_layout_range_by_pos(struct dwrite_textlayout *layout, UINT32 pos)
{
    struct layout_range *cur;

    LIST_FOR_EACH_ENTRY(cur, &layout->ranges, struct layout_range, h.entry) {
        DWRITE_TEXT_RANGE *r = &cur->h.range;
        if (r->startPosition <= pos && pos < r->startPosition + r->length)
            return cur;
    }

    return NULL;
}

static inline BOOL set_layout_range_iface_attr(IUnknown **dest, IUnknown *value)
{
    if (*dest == value) return FALSE;

    if (*dest)
        IUnknown_Release(*dest);
    *dest = value;
    if (*dest)
        IUnknown_AddRef(*dest);

    return TRUE;
}

static BOOL set_layout_range_attrval(struct layout_range_header *h, enum layout_range_attr_kind attr, struct layout_range_attr_value *value)
{
    struct layout_range_spacing *dest_spacing = (struct layout_range_spacing*)h;
    struct layout_range_iface *dest_iface = (struct layout_range_iface*)h;
    struct layout_range_bool *dest_bool = (struct layout_range_bool*)h;
    struct layout_range *dest = (struct layout_range*)h;

    BOOL changed = FALSE;

    switch (attr) {
    case LAYOUT_RANGE_ATTR_WEIGHT:
        changed = dest->weight != value->u.weight;
        dest->weight = value->u.weight;
        break;
    case LAYOUT_RANGE_ATTR_STYLE:
        changed = dest->style != value->u.style;
        dest->style = value->u.style;
        break;
    case LAYOUT_RANGE_ATTR_STRETCH:
        changed = dest->stretch != value->u.stretch;
        dest->stretch = value->u.stretch;
        break;
    case LAYOUT_RANGE_ATTR_FONTSIZE:
        changed = dest->fontsize != value->u.fontsize;
        dest->fontsize = value->u.fontsize;
        break;
    case LAYOUT_RANGE_ATTR_INLINE:
        changed = set_layout_range_iface_attr((IUnknown**)&dest->object, (IUnknown*)value->u.object);
        break;
    case LAYOUT_RANGE_ATTR_EFFECT:
        changed = set_layout_range_iface_attr((IUnknown**)&dest_iface->iface, (IUnknown*)value->u.effect);
        break;
    case LAYOUT_RANGE_ATTR_UNDERLINE:
        changed = dest_bool->value != value->u.underline;
        dest_bool->value = value->u.underline;
        break;
    case LAYOUT_RANGE_ATTR_STRIKETHROUGH:
        changed = dest_bool->value != value->u.strikethrough;
        dest_bool->value = value->u.strikethrough;
        break;
    case LAYOUT_RANGE_ATTR_PAIR_KERNING:
        changed = dest->pair_kerning != value->u.pair_kerning;
        dest->pair_kerning = value->u.pair_kerning;
        break;
    case LAYOUT_RANGE_ATTR_FONTCOLL:
        changed = set_layout_range_iface_attr((IUnknown**)&dest->collection, (IUnknown*)value->u.collection);
        break;
    case LAYOUT_RANGE_ATTR_LOCALE:
        changed = strcmpiW(dest->locale, value->u.locale) != 0;
        if (changed) {
            strcpyW(dest->locale, value->u.locale);
            strlwrW(dest->locale);
        }
        break;
    case LAYOUT_RANGE_ATTR_FONTFAMILY:
        changed = strcmpW(dest->fontfamily, value->u.fontfamily) != 0;
        if (changed) {
            heap_free(dest->fontfamily);
            dest->fontfamily = heap_strdupW(value->u.fontfamily);
        }
        break;
    case LAYOUT_RANGE_ATTR_SPACING:
        changed = dest_spacing->leading != value->u.spacing.leading ||
            dest_spacing->trailing != value->u.spacing.trailing ||
            dest_spacing->min_advance != value->u.spacing.min_advance;
        dest_spacing->leading = value->u.spacing.leading;
        dest_spacing->trailing = value->u.spacing.trailing;
        dest_spacing->min_advance = value->u.spacing.min_advance;
        break;
    case LAYOUT_RANGE_ATTR_TYPOGRAPHY:
        changed = set_layout_range_iface_attr((IUnknown**)&dest_iface->iface, (IUnknown*)value->u.typography);
        break;
    default:
        ;
    }

    return changed;
}

static inline BOOL is_in_layout_range(const DWRITE_TEXT_RANGE *outer, const DWRITE_TEXT_RANGE *inner)
{
    return (inner->startPosition >= outer->startPosition) &&
           (inner->startPosition + inner->length <= outer->startPosition + outer->length);
}

static inline HRESULT return_range(const struct layout_range_header *h, DWRITE_TEXT_RANGE *r)
{
    if (r) *r = h->range;
    return S_OK;
}

/* Sets attribute value for given range, does all needed splitting/merging of existing ranges. */
static HRESULT set_layout_range_attr(struct dwrite_textlayout *layout, enum layout_range_attr_kind attr, struct layout_range_attr_value *value)
{
    struct layout_range_header *cur, *right, *left, *outer;
    BOOL changed = FALSE;
    struct list *ranges;
    DWRITE_TEXT_RANGE r;

    /* ignore zero length ranges */
    if (value->range.length == 0)
        return S_OK;

    /* select from ranges lists */
    switch (attr)
    {
    case LAYOUT_RANGE_ATTR_WEIGHT:
    case LAYOUT_RANGE_ATTR_STYLE:
    case LAYOUT_RANGE_ATTR_STRETCH:
    case LAYOUT_RANGE_ATTR_FONTSIZE:
    case LAYOUT_RANGE_ATTR_INLINE:
    case LAYOUT_RANGE_ATTR_PAIR_KERNING:
    case LAYOUT_RANGE_ATTR_FONTCOLL:
    case LAYOUT_RANGE_ATTR_LOCALE:
    case LAYOUT_RANGE_ATTR_FONTFAMILY:
        ranges = &layout->ranges;
        break;
    case LAYOUT_RANGE_ATTR_UNDERLINE:
        ranges = &layout->underline_ranges;
        break;
    case LAYOUT_RANGE_ATTR_STRIKETHROUGH:
        ranges = &layout->strike_ranges;
        break;
    case LAYOUT_RANGE_ATTR_EFFECT:
        ranges = &layout->effects;
        break;
    case LAYOUT_RANGE_ATTR_SPACING:
        ranges = &layout->spacing;
        break;
    case LAYOUT_RANGE_ATTR_TYPOGRAPHY:
        ranges = &layout->typographies;
        break;
    default:
        FIXME("unknown attr kind %d\n", attr);
        return E_FAIL;
    }

    /* If new range is completely within existing range, split existing range in two */
    if ((outer = find_outer_range(ranges, &value->range))) {

        /* no need to add same range */
        if (is_same_layout_attrvalue(outer, attr, value))
            return S_OK;

        /* for matching range bounds just replace data */
        if (is_same_text_range(&outer->range, &value->range)) {
            changed = set_layout_range_attrval(outer, attr, value);
            goto done;
        }

        /* add new range to the left */
        if (value->range.startPosition == outer->range.startPosition) {
            left = alloc_layout_range_from(outer, &value->range);
            if (!left) return E_OUTOFMEMORY;

            changed = set_layout_range_attrval(left, attr, value);
            list_add_before(&outer->entry, &left->entry);
            outer->range.startPosition += value->range.length;
            outer->range.length -= value->range.length;
            goto done;
        }

        /* add new range to the right */
        if (value->range.startPosition + value->range.length == outer->range.startPosition + outer->range.length) {
            right = alloc_layout_range_from(outer, &value->range);
            if (!right) return E_OUTOFMEMORY;

            changed = set_layout_range_attrval(right, attr, value);
            list_add_after(&outer->entry, &right->entry);
            outer->range.length -= value->range.length;
            goto done;
        }

        r.startPosition = value->range.startPosition + value->range.length;
        r.length = outer->range.length + outer->range.startPosition - r.startPosition;

        /* right part */
        right = alloc_layout_range_from(outer, &r);
        /* new range in the middle */
        cur = alloc_layout_range_from(outer, &value->range);
        if (!right || !cur) {
            free_layout_range(right);
            free_layout_range(cur);
            return E_OUTOFMEMORY;
        }

        /* reuse container range as a left part */
        outer->range.length = value->range.startPosition - outer->range.startPosition;

        /* new part */
        set_layout_range_attrval(cur, attr, value);

        list_add_after(&outer->entry, &cur->entry);
        list_add_after(&cur->entry, &right->entry);

        layout->recompute = RECOMPUTE_EVERYTHING;
        return S_OK;
    }

    /* Now it's only possible that given range contains some existing ranges, fully or partially.
       Update all of them. */
    left = get_layout_range_header_by_pos(ranges, value->range.startPosition);
    if (left->range.startPosition == value->range.startPosition)
        changed = set_layout_range_attrval(left, attr, value);
    else /* need to split */ {
        r.startPosition = value->range.startPosition;
        r.length = left->range.length - value->range.startPosition + left->range.startPosition;
        left->range.length -= r.length;
        cur = alloc_layout_range_from(left, &r);
        changed = set_layout_range_attrval(cur, attr, value);
        list_add_after(&left->entry, &cur->entry);
    }
    cur = LIST_ENTRY(list_next(ranges, &left->entry), struct layout_range_header, entry);

    /* for all existing ranges covered by new one update value */
    while (cur && is_in_layout_range(&value->range, &cur->range)) {
        changed |= set_layout_range_attrval(cur, attr, value);
        cur = LIST_ENTRY(list_next(ranges, &cur->entry), struct layout_range_header, entry);
    }

    /* it's possible rightmost range intersects */
    if (cur && (cur->range.startPosition < value->range.startPosition + value->range.length)) {
        r.startPosition = cur->range.startPosition;
        r.length = value->range.startPosition + value->range.length - cur->range.startPosition;
        left = alloc_layout_range_from(cur, &r);
        changed |= set_layout_range_attrval(left, attr, value);
        cur->range.startPosition += left->range.length;
        cur->range.length -= left->range.length;
        list_add_before(&cur->entry, &left->entry);
    }

done:
    if (changed) {
        struct list *next, *i;

        layout->recompute = RECOMPUTE_EVERYTHING;
        i = list_head(ranges);
        while ((next = list_next(ranges, i))) {
            struct layout_range_header *next_range = LIST_ENTRY(next, struct layout_range_header, entry);

            cur = LIST_ENTRY(i, struct layout_range_header, entry);
            if (is_same_layout_attributes(cur, next_range)) {
                /* remove similar range */
                cur->range.length += next_range->range.length;
                list_remove(next);
                free_layout_range(next_range);
            }
            else
                i = list_next(ranges, i);
        }
    }

    return S_OK;
}

static inline const WCHAR *get_string_attribute_ptr(struct layout_range *range, enum layout_range_attr_kind kind)
{
    const WCHAR *str;

    switch (kind) {
        case LAYOUT_RANGE_ATTR_LOCALE:
            str = range->locale;
            break;
        case LAYOUT_RANGE_ATTR_FONTFAMILY:
            str = range->fontfamily;
            break;
        default:
            str = NULL;
    }

    return str;
}

static HRESULT get_string_attribute_length(struct dwrite_textlayout *layout, enum layout_range_attr_kind kind, UINT32 position,
    UINT32 *length, DWRITE_TEXT_RANGE *r)
{
    struct layout_range *range;
    const WCHAR *str;

    range = get_layout_range_by_pos(layout, position);
    if (!range) {
        *length = 0;
        return S_OK;
    }

    str = get_string_attribute_ptr(range, kind);
    *length = strlenW(str);
    return return_range(&range->h, r);
}

static HRESULT get_string_attribute_value(struct dwrite_textlayout *layout, enum layout_range_attr_kind kind, UINT32 position,
    WCHAR *ret, UINT32 length, DWRITE_TEXT_RANGE *r)
{
    struct layout_range *range;
    const WCHAR *str;

    if (length == 0)
        return E_INVALIDARG;

    ret[0] = 0;
    range = get_layout_range_by_pos(layout, position);
    if (!range)
        return E_INVALIDARG;

    str = get_string_attribute_ptr(range, kind);
    if (length < strlenW(str) + 1)
        return E_NOT_SUFFICIENT_BUFFER;

    strcpyW(ret, str);
    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_QueryInterface(IDWriteTextLayout3 *iface, REFIID riid, void **obj)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if (IsEqualIID(riid, &IID_IDWriteTextLayout3) ||
        IsEqualIID(riid, &IID_IDWriteTextLayout2) ||
        IsEqualIID(riid, &IID_IDWriteTextLayout1) ||
        IsEqualIID(riid, &IID_IDWriteTextLayout) ||
        IsEqualIID(riid, &IID_IUnknown))
    {
        *obj = iface;
    }
    else if (IsEqualIID(riid, &IID_IDWriteTextFormat1) ||
             IsEqualIID(riid, &IID_IDWriteTextFormat))
        *obj = &This->IDWriteTextFormat1_iface;

    if (*obj) {
        IDWriteTextLayout3_AddRef(iface);
        return S_OK;
    }

    WARN("%s not implemented.\n", debugstr_guid(riid));

    return E_NOINTERFACE;
}

static ULONG WINAPI dwritetextlayout_AddRef(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI dwritetextlayout_Release(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref) {
        IDWriteFactory5_Release(This->factory);
        free_layout_ranges_list(This);
        free_layout_eruns(This);
        free_layout_runs(This);
        release_format_data(&This->format);
        heap_free(This->nominal_breakpoints);
        heap_free(This->actual_breakpoints);
        heap_free(This->clustermetrics);
        heap_free(This->clusters);
        heap_free(This->linemetrics);
        heap_free(This->lines);
        heap_free(This->str);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI dwritetextlayout_SetTextAlignment(IDWriteTextLayout3 *iface, DWRITE_TEXT_ALIGNMENT alignment)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_SetTextAlignment(&This->IDWriteTextFormat1_iface, alignment);
}

static HRESULT WINAPI dwritetextlayout_SetParagraphAlignment(IDWriteTextLayout3 *iface, DWRITE_PARAGRAPH_ALIGNMENT alignment)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_SetParagraphAlignment(&This->IDWriteTextFormat1_iface, alignment);
}

static HRESULT WINAPI dwritetextlayout_SetWordWrapping(IDWriteTextLayout3 *iface, DWRITE_WORD_WRAPPING wrapping)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_SetWordWrapping(&This->IDWriteTextFormat1_iface, wrapping);
}

static HRESULT WINAPI dwritetextlayout_SetReadingDirection(IDWriteTextLayout3 *iface, DWRITE_READING_DIRECTION direction)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_SetReadingDirection(&This->IDWriteTextFormat1_iface, direction);
}

static HRESULT WINAPI dwritetextlayout_SetFlowDirection(IDWriteTextLayout3 *iface, DWRITE_FLOW_DIRECTION direction)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%d)\n", This, direction);
    return IDWriteTextFormat1_SetFlowDirection(&This->IDWriteTextFormat1_iface, direction);
}

static HRESULT WINAPI dwritetextlayout_SetIncrementalTabStop(IDWriteTextLayout3 *iface, FLOAT tabstop)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%.2f)\n", This, tabstop);
    return IDWriteTextFormat1_SetIncrementalTabStop(&This->IDWriteTextFormat1_iface, tabstop);
}

static HRESULT WINAPI dwritetextlayout_SetTrimming(IDWriteTextLayout3 *iface, DWRITE_TRIMMING const *trimming,
    IDWriteInlineObject *trimming_sign)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%p %p)\n", This, trimming, trimming_sign);
    return IDWriteTextFormat1_SetTrimming(&This->IDWriteTextFormat1_iface, trimming, trimming_sign);
}

static HRESULT WINAPI dwritetextlayout_SetLineSpacing(IDWriteTextLayout3 *iface, DWRITE_LINE_SPACING_METHOD spacing,
    FLOAT line_spacing, FLOAT baseline)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%d %.2f %.2f)\n", This, spacing, line_spacing, baseline);
    return IDWriteTextFormat1_SetLineSpacing(&This->IDWriteTextFormat1_iface, spacing, line_spacing, baseline);
}

static DWRITE_TEXT_ALIGNMENT WINAPI dwritetextlayout_GetTextAlignment(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetTextAlignment(&This->IDWriteTextFormat1_iface);
}

static DWRITE_PARAGRAPH_ALIGNMENT WINAPI dwritetextlayout_GetParagraphAlignment(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetParagraphAlignment(&This->IDWriteTextFormat1_iface);
}

static DWRITE_WORD_WRAPPING WINAPI dwritetextlayout_GetWordWrapping(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetWordWrapping(&This->IDWriteTextFormat1_iface);
}

static DWRITE_READING_DIRECTION WINAPI dwritetextlayout_GetReadingDirection(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetReadingDirection(&This->IDWriteTextFormat1_iface);
}

static DWRITE_FLOW_DIRECTION WINAPI dwritetextlayout_GetFlowDirection(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetFlowDirection(&This->IDWriteTextFormat1_iface);
}

static FLOAT WINAPI dwritetextlayout_GetIncrementalTabStop(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetIncrementalTabStop(&This->IDWriteTextFormat1_iface);
}

static HRESULT WINAPI dwritetextlayout_GetTrimming(IDWriteTextLayout3 *iface, DWRITE_TRIMMING *options,
    IDWriteInlineObject **trimming_sign)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetTrimming(&This->IDWriteTextFormat1_iface, options, trimming_sign);
}

static HRESULT WINAPI dwritetextlayout_GetLineSpacing(IDWriteTextLayout3 *iface, DWRITE_LINE_SPACING_METHOD *method,
    FLOAT *spacing, FLOAT *baseline)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat_GetLineSpacing((IDWriteTextFormat*)&This->IDWriteTextFormat1_iface, method, spacing, baseline);
}

static HRESULT WINAPI dwritetextlayout_GetFontCollection(IDWriteTextLayout3 *iface, IDWriteFontCollection **collection)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetFontCollection(&This->IDWriteTextFormat1_iface, collection);
}

static UINT32 WINAPI dwritetextlayout_GetFontFamilyNameLength(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetFontFamilyNameLength(&This->IDWriteTextFormat1_iface);
}

static HRESULT WINAPI dwritetextlayout_GetFontFamilyName(IDWriteTextLayout3 *iface, WCHAR *name, UINT32 size)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetFontFamilyName(&This->IDWriteTextFormat1_iface, name, size);
}

static DWRITE_FONT_WEIGHT WINAPI dwritetextlayout_GetFontWeight(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetFontWeight(&This->IDWriteTextFormat1_iface);
}

static DWRITE_FONT_STYLE WINAPI dwritetextlayout_GetFontStyle(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetFontStyle(&This->IDWriteTextFormat1_iface);
}

static DWRITE_FONT_STRETCH WINAPI dwritetextlayout_GetFontStretch(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetFontStretch(&This->IDWriteTextFormat1_iface);
}

static FLOAT WINAPI dwritetextlayout_GetFontSize(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetFontSize(&This->IDWriteTextFormat1_iface);
}

static UINT32 WINAPI dwritetextlayout_GetLocaleNameLength(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetLocaleNameLength(&This->IDWriteTextFormat1_iface);
}

static HRESULT WINAPI dwritetextlayout_GetLocaleName(IDWriteTextLayout3 *iface, WCHAR *name, UINT32 size)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    return IDWriteTextFormat1_GetLocaleName(&This->IDWriteTextFormat1_iface, name, size);
}

static HRESULT WINAPI dwritetextlayout_SetMaxWidth(IDWriteTextLayout3 *iface, FLOAT maxWidth)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    BOOL changed;

    TRACE("(%p)->(%.2f)\n", This, maxWidth);

    if (maxWidth < 0.0f)
        return E_INVALIDARG;

    changed = This->metrics.layoutWidth != maxWidth;
    This->metrics.layoutWidth = maxWidth;

    if (changed)
        This->recompute |= RECOMPUTE_LINES_AND_OVERHANGS;
    return S_OK;
}

static HRESULT WINAPI dwritetextlayout_SetMaxHeight(IDWriteTextLayout3 *iface, FLOAT maxHeight)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    BOOL changed;

    TRACE("(%p)->(%.2f)\n", This, maxHeight);

    if (maxHeight < 0.0f)
        return E_INVALIDARG;

    changed = This->metrics.layoutHeight != maxHeight;
    This->metrics.layoutHeight = maxHeight;

    if (changed)
        This->recompute |= RECOMPUTE_LINES_AND_OVERHANGS;
    return S_OK;
}

static HRESULT WINAPI dwritetextlayout_SetFontCollection(IDWriteTextLayout3 *iface, IDWriteFontCollection* collection, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%p %s)\n", This, collection, debugstr_range(&range));

    value.range = range;
    value.u.collection = collection;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_FONTCOLL, &value);
}

static HRESULT WINAPI dwritetextlayout_SetFontFamilyName(IDWriteTextLayout3 *iface, WCHAR const *name, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%s %s)\n", This, debugstr_w(name), debugstr_range(&range));

    if (!name)
        return E_INVALIDARG;

    value.range = range;
    value.u.fontfamily = name;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_FONTFAMILY, &value);
}

static HRESULT WINAPI dwritetextlayout_SetFontWeight(IDWriteTextLayout3 *iface, DWRITE_FONT_WEIGHT weight, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%d %s)\n", This, weight, debugstr_range(&range));

    if ((UINT32)weight > DWRITE_FONT_WEIGHT_ULTRA_BLACK)
        return E_INVALIDARG;

    value.range = range;
    value.u.weight = weight;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_WEIGHT, &value);
}

static HRESULT WINAPI dwritetextlayout_SetFontStyle(IDWriteTextLayout3 *iface, DWRITE_FONT_STYLE style, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%d %s)\n", This, style, debugstr_range(&range));

    if ((UINT32)style > DWRITE_FONT_STYLE_ITALIC)
        return E_INVALIDARG;

    value.range = range;
    value.u.style = style;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_STYLE, &value);
}

static HRESULT WINAPI dwritetextlayout_SetFontStretch(IDWriteTextLayout3 *iface, DWRITE_FONT_STRETCH stretch, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%d %s)\n", This, stretch, debugstr_range(&range));

    if (stretch == DWRITE_FONT_STRETCH_UNDEFINED || (UINT32)stretch > DWRITE_FONT_STRETCH_ULTRA_EXPANDED)
        return E_INVALIDARG;

    value.range = range;
    value.u.stretch = stretch;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_STRETCH, &value);
}

static HRESULT WINAPI dwritetextlayout_SetFontSize(IDWriteTextLayout3 *iface, FLOAT size, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%.2f %s)\n", This, size, debugstr_range(&range));

    if (size <= 0.0f)
        return E_INVALIDARG;

    value.range = range;
    value.u.fontsize = size;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_FONTSIZE, &value);
}

static HRESULT WINAPI dwritetextlayout_SetUnderline(IDWriteTextLayout3 *iface, BOOL underline, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%d %s)\n", This, underline, debugstr_range(&range));

    value.range = range;
    value.u.underline = underline;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_UNDERLINE, &value);
}

static HRESULT WINAPI dwritetextlayout_SetStrikethrough(IDWriteTextLayout3 *iface, BOOL strikethrough, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%d %s)\n", This, strikethrough, debugstr_range(&range));

    value.range = range;
    value.u.strikethrough = strikethrough;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_STRIKETHROUGH, &value);
}

static HRESULT WINAPI dwritetextlayout_SetDrawingEffect(IDWriteTextLayout3 *iface, IUnknown* effect, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%p %s)\n", This, effect, debugstr_range(&range));

    value.range = range;
    value.u.effect = effect;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_EFFECT, &value);
}

static HRESULT WINAPI dwritetextlayout_SetInlineObject(IDWriteTextLayout3 *iface, IDWriteInlineObject *object, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%p %s)\n", This, object, debugstr_range(&range));

    value.range = range;
    value.u.object = object;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_INLINE, &value);
}

static HRESULT WINAPI dwritetextlayout_SetTypography(IDWriteTextLayout3 *iface, IDWriteTypography* typography, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%p %s)\n", This, typography, debugstr_range(&range));

    value.range = range;
    value.u.typography = typography;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_TYPOGRAPHY, &value);
}

static HRESULT WINAPI dwritetextlayout_SetLocaleName(IDWriteTextLayout3 *iface, WCHAR const* locale, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%s %s)\n", This, debugstr_w(locale), debugstr_range(&range));

    if (!locale || strlenW(locale) > LOCALE_NAME_MAX_LENGTH-1)
        return E_INVALIDARG;

    value.range = range;
    value.u.locale = locale;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_LOCALE, &value);
}

static FLOAT WINAPI dwritetextlayout_GetMaxWidth(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)\n", This);
    return This->metrics.layoutWidth;
}

static FLOAT WINAPI dwritetextlayout_GetMaxHeight(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)\n", This);
    return This->metrics.layoutHeight;
}

static HRESULT WINAPI dwritetextlayout_layout_GetFontCollection(IDWriteTextLayout3 *iface, UINT32 position,
    IDWriteFontCollection** collection, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, collection, r);

    if (position >= This->len)
        return S_OK;

    range = get_layout_range_by_pos(This, position);
    *collection = range->collection;
    if (*collection)
        IDWriteFontCollection_AddRef(*collection);

    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_layout_GetFontFamilyNameLength(IDWriteTextLayout3 *iface,
    UINT32 position, UINT32 *length, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%d %p %p)\n", This, position, length, r);
    return get_string_attribute_length(This, LAYOUT_RANGE_ATTR_FONTFAMILY, position, length, r);
}

static HRESULT WINAPI dwritetextlayout_layout_GetFontFamilyName(IDWriteTextLayout3 *iface,
    UINT32 position, WCHAR *name, UINT32 length, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%u %p %u %p)\n", This, position, name, length, r);
    return get_string_attribute_value(This, LAYOUT_RANGE_ATTR_FONTFAMILY, position, name, length, r);
}

static HRESULT WINAPI dwritetextlayout_layout_GetFontWeight(IDWriteTextLayout3 *iface,
    UINT32 position, DWRITE_FONT_WEIGHT *weight, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, weight, r);

    if (position >= This->len)
        return S_OK;

    range = get_layout_range_by_pos(This, position);
    *weight = range->weight;

    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_layout_GetFontStyle(IDWriteTextLayout3 *iface,
    UINT32 position, DWRITE_FONT_STYLE *style, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, style, r);

    range = get_layout_range_by_pos(This, position);
    *style = range->style;
    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_layout_GetFontStretch(IDWriteTextLayout3 *iface,
    UINT32 position, DWRITE_FONT_STRETCH *stretch, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, stretch, r);

    range = get_layout_range_by_pos(This, position);
    *stretch = range->stretch;
    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_layout_GetFontSize(IDWriteTextLayout3 *iface,
    UINT32 position, FLOAT *size, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, size, r);

    range = get_layout_range_by_pos(This, position);
    *size = range->fontsize;
    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_GetUnderline(IDWriteTextLayout3 *iface,
    UINT32 position, BOOL *underline, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_bool *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, underline, r);

    range = (struct layout_range_bool*)get_layout_range_header_by_pos(&This->underline_ranges, position);
    *underline = range->value;

    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_GetStrikethrough(IDWriteTextLayout3 *iface,
    UINT32 position, BOOL *strikethrough, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_bool *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, strikethrough, r);

    range = (struct layout_range_bool*)get_layout_range_header_by_pos(&This->strike_ranges, position);
    *strikethrough = range->value;

    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_GetDrawingEffect(IDWriteTextLayout3 *iface,
    UINT32 position, IUnknown **effect, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_iface *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, effect, r);

    range = (struct layout_range_iface*)get_layout_range_header_by_pos(&This->effects, position);
    *effect = range->iface;
    if (*effect)
        IUnknown_AddRef(*effect);

    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_GetInlineObject(IDWriteTextLayout3 *iface,
    UINT32 position, IDWriteInlineObject **object, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, object, r);

    if (position >= This->len)
        return S_OK;

    range = get_layout_range_by_pos(This, position);
    *object = range->object;
    if (*object)
        IDWriteInlineObject_AddRef(*object);

    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_GetTypography(IDWriteTextLayout3 *iface,
    UINT32 position, IDWriteTypography** typography, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_iface *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, typography, r);

    range = (struct layout_range_iface*)get_layout_range_header_by_pos(&This->typographies, position);
    *typography = (IDWriteTypography*)range->iface;
    if (*typography)
        IDWriteTypography_AddRef(*typography);

    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout_layout_GetLocaleNameLength(IDWriteTextLayout3 *iface,
    UINT32 position, UINT32* length, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%u %p %p)\n", This, position, length, r);
    return get_string_attribute_length(This, LAYOUT_RANGE_ATTR_LOCALE, position, length, r);
}

static HRESULT WINAPI dwritetextlayout_layout_GetLocaleName(IDWriteTextLayout3 *iface,
    UINT32 position, WCHAR* locale, UINT32 length, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%u %p %u %p)\n", This, position, locale, length, r);
    return get_string_attribute_value(This, LAYOUT_RANGE_ATTR_LOCALE, position, locale, length, r);
}

static inline FLOAT renderer_apply_snapping(FLOAT coord, BOOL skiptransform, FLOAT ppdip, FLOAT det,
    const DWRITE_MATRIX *m)
{
    D2D1_POINT_2F vec, vec2;

    if (!skiptransform) {
        /* apply transform */
        vec.x = 0.0f;
        vec.y = coord * ppdip;

        vec2.x = m->m11 * vec.x + m->m21 * vec.y + m->dx;
        vec2.y = m->m12 * vec.x + m->m22 * vec.y + m->dy;

        /* snap */
        vec2.x = floorf(vec2.x + 0.5f);
        vec2.y = floorf(vec2.y + 0.5f);

        /* apply inverted transform, we don't care about X component at this point */
        vec.y = (-m->m12 * vec2.x + m->m11 * vec2.y - (m->m11 * m->dy - m->m12 * m->dx)) / det;
        vec.y /= ppdip;
    }
    else
        vec.y = floorf(coord * ppdip + 0.5f) / ppdip;

    return vec.y;
}

static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout3 *iface,
    void *context, IDWriteTextRenderer* renderer, FLOAT origin_x, FLOAT origin_y)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    BOOL disabled = FALSE, skiptransform = FALSE;
    struct layout_effective_inline *inlineobject;
    struct layout_effective_run *run;
    struct layout_strikethrough *s;
    struct layout_underline *u;
    FLOAT det = 0.0f, ppdip = 0.0f;
    DWRITE_MATRIX m = { 0 };
    HRESULT hr;

    TRACE("(%p)->(%p %p %.2f %.2f)\n", This, context, renderer, origin_x, origin_y);

    hr = layout_compute_effective_runs(This);
    if (FAILED(hr))
        return hr;

    hr = IDWriteTextRenderer_IsPixelSnappingDisabled(renderer, context, &disabled);
    if (FAILED(hr))
        return hr;

    if (!disabled) {
        hr = IDWriteTextRenderer_GetPixelsPerDip(renderer, context, &ppdip);
        if (FAILED(hr))
            return hr;

        hr = IDWriteTextRenderer_GetCurrentTransform(renderer, context, &m);
        if (FAILED(hr))
            return hr;

        /* it's only allowed to have a diagonal/antidiagonal transform matrix */
        if (ppdip <= 0.0f ||
            (m.m11 * m.m22 != 0.0f && (m.m12 != 0.0f || m.m21 != 0.0f)) ||
            (m.m12 * m.m21 != 0.0f && (m.m11 != 0.0f || m.m22 != 0.0f)))
            disabled = TRUE;
        else
            skiptransform = should_skip_transform(&m, &det);
    }

#define SNAP_COORD(x) (disabled ? (x) : renderer_apply_snapping((x), skiptransform, ppdip, det, &m))
    /* 1. Regular runs */
    LIST_FOR_EACH_ENTRY(run, &This->eruns, struct layout_effective_run, entry) {
        const struct regular_layout_run *regular = &run->run->u.regular;
        UINT32 start_glyph = regular->clustermap[run->start];
        DWRITE_GLYPH_RUN_DESCRIPTION descr;
        DWRITE_GLYPH_RUN glyph_run;

        /* Everything but cluster map will be reused from nominal run, as we only need
           to adjust some pointers. Cluster map however is rebuilt when effective run is added,
           it can't be reused because it has to start with 0 index for each reported run. */
        glyph_run = regular->run;
        glyph_run.glyphCount = run->glyphcount;

        /* fixup glyph data arrays */
        glyph_run.glyphIndices += start_glyph;
        glyph_run.glyphAdvances += start_glyph;
        glyph_run.glyphOffsets += start_glyph;

        /* description */
        descr = regular->descr;
        descr.stringLength = run->length;
        descr.string += run->start;
        descr.clusterMap = run->clustermap;
        descr.textPosition += run->start;

        /* return value is ignored */
        IDWriteTextRenderer_DrawGlyphRun(renderer,
            context,
            run->origin.x + run->align_dx + origin_x,
            SNAP_COORD(run->origin.y + origin_y),
            This->measuringmode,
            &glyph_run,
            &descr,
            run->effect);
    }

    /* 2. Inline objects */
    LIST_FOR_EACH_ENTRY(inlineobject, &This->inlineobjects, struct layout_effective_inline, entry) {
        IDWriteTextRenderer_DrawInlineObject(renderer,
            context,
            inlineobject->origin.x + inlineobject->align_dx + origin_x,
            SNAP_COORD(inlineobject->origin.y + origin_y),
            inlineobject->object,
            inlineobject->is_sideways,
            inlineobject->is_rtl,
            inlineobject->effect);
    }

    /* 3. Underlines */
    LIST_FOR_EACH_ENTRY(u, &This->underlines, struct layout_underline, entry) {
        IDWriteTextRenderer_DrawUnderline(renderer,
            context,
            /* horizontal underline always grows from left to right, width is always added to origin regardless of run direction */
            (is_run_rtl(u->run) ? u->run->origin.x - u->run->width : u->run->origin.x) + u->run->align_dx + origin_x,
            SNAP_COORD(u->run->origin.y + origin_y),
            &u->u,
            u->run->effect);
    }

    /* 4. Strikethrough */
    LIST_FOR_EACH_ENTRY(s, &This->strikethrough, struct layout_strikethrough, entry) {
        IDWriteTextRenderer_DrawStrikethrough(renderer,
            context,
            s->run->origin.x + s->run->align_dx + origin_x,
            SNAP_COORD(s->run->origin.y + origin_y),
            &s->s,
            s->run->effect);
    }
#undef SNAP_COORD

    return S_OK;
}

static HRESULT WINAPI dwritetextlayout_GetLineMetrics(IDWriteTextLayout3 *iface,
    DWRITE_LINE_METRICS *metrics, UINT32 max_count, UINT32 *count)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    HRESULT hr;

    TRACE("(%p)->(%p %u %p)\n", This, metrics, max_count, count);

    hr = layout_compute_effective_runs(This);
    if (FAILED(hr))
        return hr;

    if (metrics) {
        UINT32 i, c = min(max_count, This->metrics.lineCount);
        for (i = 0; i < c; i++)
            memcpy(metrics + i, This->linemetrics + i, sizeof(*metrics));
    }

    *count = This->metrics.lineCount;
    return max_count >= This->metrics.lineCount ? S_OK : E_NOT_SUFFICIENT_BUFFER;
}

static HRESULT WINAPI dwritetextlayout_GetMetrics(IDWriteTextLayout3 *iface, DWRITE_TEXT_METRICS *metrics)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    DWRITE_TEXT_METRICS1 metrics1;
    HRESULT hr;

    TRACE("(%p)->(%p)\n", This, metrics);

    hr = IDWriteTextLayout3_GetMetrics(iface, &metrics1);
    if (hr == S_OK)
        memcpy(metrics, &metrics1, sizeof(*metrics));

    return hr;
}

static void scale_glyph_bbox(RECT *bbox, FLOAT emSize, UINT16 units_per_em, D2D1_RECT_F *ret)
{
#define SCALE(x) ((FLOAT)x * emSize / (FLOAT)units_per_em)
    ret->left = SCALE(bbox->left);
    ret->right = SCALE(bbox->right);
    ret->top = SCALE(bbox->top);
    ret->bottom = SCALE(bbox->bottom);
#undef SCALE
}

static void d2d_rect_offset(D2D1_RECT_F *rect, FLOAT x, FLOAT y)
{
    rect->left += x;
    rect->right += x;
    rect->top += y;
    rect->bottom += y;
}

static BOOL d2d_rect_is_empty(const D2D1_RECT_F *rect)
{
    return ((rect->left >= rect->right) || (rect->top >= rect->bottom));
}

static void d2d_rect_union(D2D1_RECT_F *dst, const D2D1_RECT_F *src)
{
    if (d2d_rect_is_empty(dst)) {
        if (d2d_rect_is_empty(src)) {
            dst->left = dst->right = dst->top = dst->bottom = 0.0f;
            return;
        }
        else
            *dst = *src;
    }
    else {
        if (!d2d_rect_is_empty(src)) {
            dst->left   = min(dst->left, src->left);
            dst->right  = max(dst->right, src->right);
            dst->top    = min(dst->top, src->top);
            dst->bottom = max(dst->bottom, src->bottom);
        }
    }
}

static void layout_get_erun_bbox(struct dwrite_textlayout *layout, struct layout_effective_run *run, D2D1_RECT_F *bbox)
{
    const struct regular_layout_run *regular = &run->run->u.regular;
    UINT32 start_glyph = regular->clustermap[run->start];
    const DWRITE_GLYPH_RUN *glyph_run = &regular->run;
    DWRITE_FONT_METRICS font_metrics;
    D2D1_POINT_2F origin = { 0 };
    UINT32 i;

    if (run->bbox.top == run->bbox.bottom) {
        IDWriteFontFace_GetMetrics(glyph_run->fontFace, &font_metrics);

        for (i = 0; i < run->glyphcount; i++) {
            D2D1_RECT_F glyph_bbox;
            RECT design_bbox;

            freetype_get_design_glyph_bbox((IDWriteFontFace4 *)glyph_run->fontFace, font_metrics.designUnitsPerEm,
                    glyph_run->glyphIndices[i + start_glyph], &design_bbox);

            scale_glyph_bbox(&design_bbox, glyph_run->fontEmSize, font_metrics.designUnitsPerEm, &glyph_bbox);
            d2d_rect_offset(&glyph_bbox, origin.x + glyph_run->glyphOffsets[i + start_glyph].advanceOffset,
                    origin.y + glyph_run->glyphOffsets[i + start_glyph].ascenderOffset);
            d2d_rect_union(&run->bbox, &glyph_bbox);

            /* FIXME: take care of vertical/rtl */
            origin.x += glyph_run->glyphAdvances[i + start_glyph];
       }
    }

    *bbox = run->bbox;
    d2d_rect_offset(bbox, run->origin.x + run->align_dx, run->origin.y);
}

static void layout_get_inlineobj_bbox(struct dwrite_textlayout *layout, struct layout_effective_inline *run,
        D2D1_RECT_F *bbox)
{
    DWRITE_OVERHANG_METRICS overhang_metrics = { 0 };
    DWRITE_INLINE_OBJECT_METRICS metrics = { 0 };
    HRESULT hr;

    if (FAILED(hr = IDWriteInlineObject_GetMetrics(run->object, &metrics))) {
        WARN("Failed to get inline object metrics, hr %#x.\n", hr);
        memset(bbox, 0, sizeof(*bbox));
        return;
    }

    bbox->left = run->origin.x + run->align_dx;
    bbox->right = bbox->left + metrics.width;
    bbox->top = run->origin.y;
    bbox->bottom = bbox->top + metrics.height;

    IDWriteInlineObject_GetOverhangMetrics(run->object, &overhang_metrics);

    bbox->left -= overhang_metrics.left;
    bbox->right += overhang_metrics.right;
    bbox->top -= overhang_metrics.top;
    bbox->bottom += overhang_metrics.bottom;
}

static HRESULT WINAPI dwritetextlayout_GetOverhangMetrics(IDWriteTextLayout3 *iface,
        DWRITE_OVERHANG_METRICS *overhangs)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_effective_inline *inline_run;
    struct layout_effective_run *run;
    D2D1_RECT_F bbox = { 0 };
    HRESULT hr;

    TRACE("(%p)->(%p)\n", This, overhangs);

    memset(overhangs, 0, sizeof(*overhangs));

    if (!(This->recompute & RECOMPUTE_OVERHANGS)) {
        *overhangs = This->overhangs;
        return S_OK;
    }

    hr = layout_compute_effective_runs(This);
    if (FAILED(hr))
        return hr;

    LIST_FOR_EACH_ENTRY(run, &This->eruns, struct layout_effective_run, entry) {
        D2D1_RECT_F run_bbox;

        layout_get_erun_bbox(This, run, &run_bbox);
        d2d_rect_union(&bbox, &run_bbox);
    }

    LIST_FOR_EACH_ENTRY(inline_run, &This->inlineobjects, struct layout_effective_inline, entry) {
        D2D1_RECT_F object_bbox;

        layout_get_inlineobj_bbox(This, inline_run, &object_bbox);
        d2d_rect_union(&bbox, &object_bbox);
    }

    /* Deltas from layout box. */
    This->overhangs.left = -bbox.left;
    This->overhangs.top = -bbox.top;
    This->overhangs.right = bbox.right - This->metrics.layoutWidth;
    This->overhangs.bottom = bbox.bottom - This->metrics.layoutHeight;
    This->recompute &= ~RECOMPUTE_OVERHANGS;

    *overhangs = This->overhangs;

    return S_OK;
}

static HRESULT WINAPI dwritetextlayout_GetClusterMetrics(IDWriteTextLayout3 *iface,
    DWRITE_CLUSTER_METRICS *metrics, UINT32 max_count, UINT32 *count)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    HRESULT hr;

    TRACE("(%p)->(%p %u %p)\n", This, metrics, max_count, count);

    hr = layout_compute(This);
    if (FAILED(hr))
        return hr;

    if (metrics)
        memcpy(metrics, This->clustermetrics, sizeof(DWRITE_CLUSTER_METRICS)*min(max_count, This->cluster_count));

    *count = This->cluster_count;
    return max_count >= This->cluster_count ? S_OK : E_NOT_SUFFICIENT_BUFFER;
}

static HRESULT WINAPI dwritetextlayout_DetermineMinWidth(IDWriteTextLayout3 *iface, FLOAT* min_width)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    UINT32 start;
    FLOAT width;
    HRESULT hr;

    TRACE("(%p)->(%p)\n", This, min_width);

    if (!min_width)
        return E_INVALIDARG;

    if (!(This->recompute & RECOMPUTE_MINIMAL_WIDTH))
        goto width_done;

    *min_width = 0.0f;
    hr = layout_compute(This);
    if (FAILED(hr))
        return hr;

    /* Find widest word without emergency breaking between clusters, trailing whitespaces
       preceding breaking point do not contribute to word width. */
    for (start = 0; start < This->cluster_count;) {
        UINT32 end = start, j, next;

        /* Last cluster always could be wrapped after. */
        while (!This->clustermetrics[end].canWrapLineAfter)
            end++;
        /* make is so current cluster range that we can wrap after is [start,end) */
        end++;

        next = end;

        /* Ignore trailing whitespace clusters, in case of single space range will
           be reduced to empty range, or [start,start+1). */
        while (end > start && This->clustermetrics[end-1].isWhitespace)
            end--;

        /* check if cluster range exceeds last minimal width */
        width = 0.0f;
        for (j = start; j < end; j++)
            width += This->clustermetrics[j].width;

        start = next;

        if (width > This->minwidth)
            This->minwidth = width;
    }
    This->recompute &= ~RECOMPUTE_MINIMAL_WIDTH;

width_done:
    *min_width = This->minwidth;
    return S_OK;
}

static HRESULT WINAPI dwritetextlayout_HitTestPoint(IDWriteTextLayout3 *iface,
    FLOAT pointX, FLOAT pointY, BOOL* is_trailinghit, BOOL* is_inside, DWRITE_HIT_TEST_METRICS *metrics)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    FIXME("(%p)->(%f %f %p %p %p): stub\n", This, pointX, pointY, is_trailinghit, is_inside, metrics);
    return E_NOTIMPL;
}

static HRESULT WINAPI dwritetextlayout_HitTestTextPosition(IDWriteTextLayout3 *iface,
    UINT32 textPosition, BOOL is_trailinghit, FLOAT* pointX, FLOAT* pointY, DWRITE_HIT_TEST_METRICS *metrics)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    FIXME("(%p)->(%u %d %p %p %p): stub\n", This, textPosition, is_trailinghit, pointX, pointY, metrics);
    return E_NOTIMPL;
}

static HRESULT WINAPI dwritetextlayout_HitTestTextRange(IDWriteTextLayout3 *iface,
    UINT32 textPosition, UINT32 textLength, FLOAT originX, FLOAT originY,
    DWRITE_HIT_TEST_METRICS *metrics, UINT32 max_metricscount, UINT32* actual_metricscount)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    FIXME("(%p)->(%u %u %f %f %p %u %p): stub\n", This, textPosition, textLength, originX, originY, metrics,
        max_metricscount, actual_metricscount);
    return E_NOTIMPL;
}

static HRESULT WINAPI dwritetextlayout1_SetPairKerning(IDWriteTextLayout3 *iface, BOOL is_pairkerning_enabled,
        DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%d %s)\n", This, is_pairkerning_enabled, debugstr_range(&range));

    value.range = range;
    value.u.pair_kerning = !!is_pairkerning_enabled;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_PAIR_KERNING, &value);
}

static HRESULT WINAPI dwritetextlayout1_GetPairKerning(IDWriteTextLayout3 *iface, UINT32 position, BOOL *is_pairkerning_enabled,
        DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range *range;

    TRACE("(%p)->(%u %p %p)\n", This, position, is_pairkerning_enabled, r);

    if (position >= This->len)
        return S_OK;

    range = get_layout_range_by_pos(This, position);
    *is_pairkerning_enabled = range->pair_kerning;

    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout1_SetCharacterSpacing(IDWriteTextLayout3 *iface, FLOAT leading, FLOAT trailing,
    FLOAT min_advance, DWRITE_TEXT_RANGE range)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_attr_value value;

    TRACE("(%p)->(%.2f %.2f %.2f %s)\n", This, leading, trailing, min_advance, debugstr_range(&range));

    if (min_advance < 0.0f)
        return E_INVALIDARG;

    value.range = range;
    value.u.spacing.leading = leading;
    value.u.spacing.trailing = trailing;
    value.u.spacing.min_advance = min_advance;
    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_SPACING, &value);
}

static HRESULT WINAPI dwritetextlayout1_GetCharacterSpacing(IDWriteTextLayout3 *iface, UINT32 position, FLOAT *leading,
    FLOAT *trailing, FLOAT *min_advance, DWRITE_TEXT_RANGE *r)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    struct layout_range_spacing *range;

    TRACE("(%p)->(%u %p %p %p %p)\n", This, position, leading, trailing, min_advance, r);

    range = (struct layout_range_spacing*)get_layout_range_header_by_pos(&This->spacing, position);
    *leading = range->leading;
    *trailing = range->trailing;
    *min_advance = range->min_advance;

    return return_range(&range->h, r);
}

static HRESULT WINAPI dwritetextlayout2_GetMetrics(IDWriteTextLayout3 *iface, DWRITE_TEXT_METRICS1 *metrics)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    HRESULT hr;

    TRACE("(%p)->(%p)\n", This, metrics);

    hr = layout_compute_effective_runs(This);
    if (FAILED(hr))
        return hr;

    *metrics = This->metrics;
    return S_OK;
}

static HRESULT WINAPI dwritetextlayout2_SetVerticalGlyphOrientation(IDWriteTextLayout3 *iface, DWRITE_VERTICAL_GLYPH_ORIENTATION orientation)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);

    TRACE("(%p)->(%d)\n", This, orientation);

    if ((UINT32)orientation > DWRITE_VERTICAL_GLYPH_ORIENTATION_STACKED)
        return E_INVALIDARG;

    This->format.vertical_orientation = orientation;
    return S_OK;
}

static DWRITE_VERTICAL_GLYPH_ORIENTATION WINAPI dwritetextlayout2_GetVerticalGlyphOrientation(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)\n", This);
    return This->format.vertical_orientation;
}

static HRESULT WINAPI dwritetextlayout2_SetLastLineWrapping(IDWriteTextLayout3 *iface, BOOL lastline_wrapping_enabled)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%d)\n", This, lastline_wrapping_enabled);
    return IDWriteTextFormat1_SetLastLineWrapping(&This->IDWriteTextFormat1_iface, lastline_wrapping_enabled);
}

static BOOL WINAPI dwritetextlayout2_GetLastLineWrapping(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)\n", This);
    return IDWriteTextFormat1_GetLastLineWrapping(&This->IDWriteTextFormat1_iface);
}

static HRESULT WINAPI dwritetextlayout2_SetOpticalAlignment(IDWriteTextLayout3 *iface, DWRITE_OPTICAL_ALIGNMENT alignment)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%d)\n", This, alignment);
    return IDWriteTextFormat1_SetOpticalAlignment(&This->IDWriteTextFormat1_iface, alignment);
}

static DWRITE_OPTICAL_ALIGNMENT WINAPI dwritetextlayout2_GetOpticalAlignment(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)\n", This);
    return IDWriteTextFormat1_GetOpticalAlignment(&This->IDWriteTextFormat1_iface);
}

static HRESULT WINAPI dwritetextlayout2_SetFontFallback(IDWriteTextLayout3 *iface, IDWriteFontFallback *fallback)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%p)\n", This, fallback);
    return set_fontfallback_for_format(&This->format, fallback);
}

static HRESULT WINAPI dwritetextlayout2_GetFontFallback(IDWriteTextLayout3 *iface, IDWriteFontFallback **fallback)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    TRACE("(%p)->(%p)\n", This, fallback);
    return get_fontfallback_from_format(&This->format, fallback);
}

static HRESULT WINAPI dwritetextlayout3_InvalidateLayout(IDWriteTextLayout3 *iface)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);

    TRACE("(%p)\n", This);

    This->recompute = RECOMPUTE_EVERYTHING;
    return S_OK;
}

static HRESULT WINAPI dwritetextlayout3_SetLineSpacing(IDWriteTextLayout3 *iface, DWRITE_LINE_SPACING const *spacing)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    BOOL changed;
    HRESULT hr;

    TRACE("(%p)->(%p)\n", This, spacing);

    hr = format_set_linespacing(&This->format, spacing, &changed);
    if (FAILED(hr))
        return hr;

    if (changed) {
        if (!(This->recompute & RECOMPUTE_LINES)) {
            UINT32 line;

            for (line = 0; line < This->metrics.lineCount; line++)
                layout_apply_line_spacing(This, line);

            layout_set_line_positions(This);
        }

        This->recompute |= RECOMPUTE_OVERHANGS;
    }

    return S_OK;
}

static HRESULT WINAPI dwritetextlayout3_GetLineSpacing(IDWriteTextLayout3 *iface, DWRITE_LINE_SPACING *spacing)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);

    TRACE("(%p)->(%p)\n", This, spacing);

    *spacing = This->format.spacing;
    return S_OK;
}

static HRESULT WINAPI dwritetextlayout3_GetLineMetrics(IDWriteTextLayout3 *iface, DWRITE_LINE_METRICS1 *metrics,
    UINT32 max_count, UINT32 *count)
{
    struct dwrite_textlayout *This = impl_from_IDWriteTextLayout3(iface);
    HRESULT hr;

    TRACE("(%p)->(%p %u %p)\n", This, metrics, max_count, count);

    hr = layout_compute_effective_runs(This);
    if (FAILED(hr))
        return hr;

    if (metrics)
        memcpy(metrics, This->linemetrics, sizeof(*metrics) * min(max_count, This->metrics.lineCount));

    *count = This->metrics.lineCount;
    return max_count >= This->metrics.lineCount ? S_OK : E_NOT_SUFFICIENT_BUFFER;
}

static const IDWriteTextLayout3Vtbl dwritetextlayoutvtbl = {
    dwritetextlayout_QueryInterface,
    dwritetextlayout_AddRef,
    dwritetextlayout_Release,
    dwritetextlayout_SetTextAlignment,
    dwritetextlayout_SetParagraphAlignment,
    dwritetextlayout_SetWordWrapping,
    dwritetextlayout_SetReadingDirection,
    dwritetextlayout_SetFlowDirection,
    dwritetextlayout_SetIncrementalTabStop,
    dwritetextlayout_SetTrimming,
    dwritetextlayout_SetLineSpacing,
    dwritetextlayout_GetTextAlignment,
    dwritetextlayout_GetParagraphAlignment,
    dwritetextlayout_GetWordWrapping,
    dwritetextlayout_GetReadingDirection,
    dwritetextlayout_GetFlowDirection,
    dwritetextlayout_GetIncrementalTabStop,
    dwritetextlayout_GetTrimming,
    dwritetextlayout_GetLineSpacing,
    dwritetextlayout_GetFontCollection,
    dwritetextlayout_GetFontFamilyNameLength,
    dwritetextlayout_GetFontFamilyName,
    dwritetextlayout_GetFontWeight,
    dwritetextlayout_GetFontStyle,
    dwritetextlayout_GetFontStretch,
    dwritetextlayout_GetFontSize,
    dwritetextlayout_GetLocaleNameLength,
    dwritetextlayout_GetLocaleName,
    dwritetextlayout_SetMaxWidth,
    dwritetextlayout_SetMaxHeight,
    dwritetextlayout_SetFontCollection,
    dwritetextlayout_SetFontFamilyName,
    dwritetextlayout_SetFontWeight,
    dwritetextlayout_SetFontStyle,
    dwritetextlayout_SetFontStretch,
    dwritetextlayout_SetFontSize,
    dwritetextlayout_SetUnderline,
    dwritetextlayout_SetStrikethrough,
    dwritetextlayout_SetDrawingEffect,
    dwritetextlayout_SetInlineObject,
    dwritetextlayout_SetTypography,
    dwritetextlayout_SetLocaleName,
    dwritetextlayout_GetMaxWidth,
    dwritetextlayout_GetMaxHeight,
    dwritetextlayout_layout_GetFontCollection,
    dwritetextlayout_layout_GetFontFamilyNameLength,
    dwritetextlayout_layout_GetFontFamilyName,
    dwritetextlayout_layout_GetFontWeight,
    dwritetextlayout_layout_GetFontStyle,
    dwritetextlayout_layout_GetFontStretch,
    dwritetextlayout_layout_GetFontSize,
    dwritetextlayout_GetUnderline,
    dwritetextlayout_GetStrikethrough,
    dwritetextlayout_GetDrawingEffect,
    dwritetextlayout_GetInlineObject,
    dwritetextlayout_GetTypography,
    dwritetextlayout_layout_GetLocaleNameLength,
    dwritetextlayout_layout_GetLocaleName,
    dwritetextlayout_Draw,
    dwritetextlayout_GetLineMetrics,
    dwritetextlayout_GetMetrics,
    dwritetextlayout_GetOverhangMetrics,
    dwritetextlayout_GetClusterMetrics,
    dwritetextlayout_DetermineMinWidth,
    dwritetextlayout_HitTestPoint,
    dwritetextlayout_HitTestTextPosition,
    dwritetextlayout_HitTestTextRange,
    dwritetextlayout1_SetPairKerning,
    dwritetextlayout1_GetPairKerning,
    dwritetextlayout1_SetCharacterSpacing,
    dwritetextlayout1_GetCharacterSpacing,
    dwritetextlayout2_GetMetrics,
    dwritetextlayout2_SetVerticalGlyphOrientation,
    dwritetextlayout2_GetVerticalGlyphOrientation,
    dwritetextlayout2_SetLastLineWrapping,
    dwritetextlayout2_GetLastLineWrapping,
    dwritetextlayout2_SetOpticalAlignment,
    dwritetextlayout2_GetOpticalAlignment,
    dwritetextlayout2_SetFontFallback,
    dwritetextlayout2_GetFontFallback,
    dwritetextlayout3_InvalidateLayout,
    dwritetextlayout3_SetLineSpacing,
    dwritetextlayout3_GetLineSpacing,
    dwritetextlayout3_GetLineMetrics
};

static HRESULT WINAPI dwritetextformat_layout_QueryInterface(IDWriteTextFormat1 *iface, REFIID riid, void **obj)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
    return IDWriteTextLayout3_QueryInterface(&This->IDWriteTextLayout3_iface, riid, obj);
}

static ULONG WINAPI dwritetextformat_layout_AddRef(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    return IDWriteTextLayout3_AddRef(&This->IDWriteTextLayout3_iface);
}

static ULONG WINAPI dwritetextformat_layout_Release(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    return IDWriteTextLayout3_Release(&This->IDWriteTextLayout3_iface);
}

static HRESULT WINAPI dwritetextformat_layout_SetTextAlignment(IDWriteTextFormat1 *iface, DWRITE_TEXT_ALIGNMENT alignment)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    BOOL changed;
    HRESULT hr;

    TRACE("(%p)->(%d)\n", This, alignment);

    hr = format_set_textalignment(&This->format, alignment, &changed);
    if (FAILED(hr))
        return hr;

    if (changed) {
        /* if layout is not ready there's nothing to align */
        if (!(This->recompute & RECOMPUTE_LINES))
            layout_apply_text_alignment(This);
        This->recompute |= RECOMPUTE_OVERHANGS;
    }

    return S_OK;
}

static HRESULT WINAPI dwritetextformat_layout_SetParagraphAlignment(IDWriteTextFormat1 *iface, DWRITE_PARAGRAPH_ALIGNMENT alignment)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    BOOL changed;
    HRESULT hr;

    TRACE("(%p)->(%d)\n", This, alignment);

    hr = format_set_paralignment(&This->format, alignment, &changed);
    if (FAILED(hr))
        return hr;

    if (changed) {
        /* if layout is not ready there's nothing to align */
        if (!(This->recompute & RECOMPUTE_LINES))
            layout_apply_par_alignment(This);
        This->recompute |= RECOMPUTE_OVERHANGS;
    }

    return S_OK;
}

static HRESULT WINAPI dwritetextformat_layout_SetWordWrapping(IDWriteTextFormat1 *iface, DWRITE_WORD_WRAPPING wrapping)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    BOOL changed;
    HRESULT hr;

    TRACE("(%p)->(%d)\n", This, wrapping);

    hr = format_set_wordwrapping(&This->format, wrapping, &changed);
    if (FAILED(hr))
        return hr;

    if (changed)
        This->recompute |= RECOMPUTE_LINES_AND_OVERHANGS;

    return S_OK;
}

static HRESULT WINAPI dwritetextformat_layout_SetReadingDirection(IDWriteTextFormat1 *iface, DWRITE_READING_DIRECTION direction)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    BOOL changed;
    HRESULT hr;

    TRACE("(%p)->(%d)\n", This, direction);

    hr = format_set_readingdirection(&This->format, direction, &changed);
    if (FAILED(hr))
        return hr;

    if (changed)
        This->recompute = RECOMPUTE_EVERYTHING;

    return S_OK;
}

static HRESULT WINAPI dwritetextformat_layout_SetFlowDirection(IDWriteTextFormat1 *iface, DWRITE_FLOW_DIRECTION direction)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    BOOL changed;
    HRESULT hr;

    TRACE("(%p)->(%d)\n", This, direction);

    hr = format_set_flowdirection(&This->format, direction, &changed);
    if (FAILED(hr))
        return hr;

    if (changed)
        This->recompute = RECOMPUTE_EVERYTHING;

    return S_OK;
}

static HRESULT WINAPI dwritetextformat_layout_SetIncrementalTabStop(IDWriteTextFormat1 *iface, FLOAT tabstop)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    FIXME("(%p)->(%f): stub\n", This, tabstop);
    return E_NOTIMPL;
}

static HRESULT WINAPI dwritetextformat_layout_SetTrimming(IDWriteTextFormat1 *iface, DWRITE_TRIMMING const *trimming,
    IDWriteInlineObject *trimming_sign)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    BOOL changed;
    HRESULT hr;

    TRACE("(%p)->(%p %p)\n", This, trimming, trimming_sign);

    hr = format_set_trimming(&This->format, trimming, trimming_sign, &changed);

    if (changed)
        This->recompute |= RECOMPUTE_LINES_AND_OVERHANGS;

    return hr;
}

static HRESULT WINAPI dwritetextformat_layout_SetLineSpacing(IDWriteTextFormat1 *iface, DWRITE_LINE_SPACING_METHOD method,
    FLOAT height, FLOAT baseline)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    DWRITE_LINE_SPACING spacing;

    TRACE("(%p)->(%d %f %f)\n", This, method, height, baseline);

    spacing = This->format.spacing;
    spacing.method = method;
    spacing.height = height;
    spacing.baseline = baseline;
    return IDWriteTextLayout3_SetLineSpacing(&This->IDWriteTextLayout3_iface, &spacing);
}

static DWRITE_TEXT_ALIGNMENT WINAPI dwritetextformat_layout_GetTextAlignment(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.textalignment;
}

static DWRITE_PARAGRAPH_ALIGNMENT WINAPI dwritetextformat_layout_GetParagraphAlignment(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.paralign;
}

static DWRITE_WORD_WRAPPING WINAPI dwritetextformat_layout_GetWordWrapping(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.wrapping;
}

static DWRITE_READING_DIRECTION WINAPI dwritetextformat_layout_GetReadingDirection(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.readingdir;
}

static DWRITE_FLOW_DIRECTION WINAPI dwritetextformat_layout_GetFlowDirection(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.flow;
}

static FLOAT WINAPI dwritetextformat_layout_GetIncrementalTabStop(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    FIXME("(%p): stub\n", This);
    return 0.0f;
}

static HRESULT WINAPI dwritetextformat_layout_GetTrimming(IDWriteTextFormat1 *iface, DWRITE_TRIMMING *options,
    IDWriteInlineObject **trimming_sign)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);

    TRACE("(%p)->(%p %p)\n", This, options, trimming_sign);

    *options = This->format.trimming;
    *trimming_sign = This->format.trimmingsign;
    if (*trimming_sign)
        IDWriteInlineObject_AddRef(*trimming_sign);
    return S_OK;
}

static HRESULT WINAPI dwritetextformat_layout_GetLineSpacing(IDWriteTextFormat1 *iface, DWRITE_LINE_SPACING_METHOD *method,
    FLOAT *spacing, FLOAT *baseline)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);

    TRACE("(%p)->(%p %p %p)\n", This, method, spacing, baseline);

    *method = This->format.spacing.method;
    *spacing = This->format.spacing.height;
    *baseline = This->format.spacing.baseline;
    return S_OK;
}

static HRESULT WINAPI dwritetextformat_layout_GetFontCollection(IDWriteTextFormat1 *iface, IDWriteFontCollection **collection)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);

    TRACE("(%p)->(%p)\n", This, collection);

    *collection = This->format.collection;
    if (*collection)
        IDWriteFontCollection_AddRef(*collection);
    return S_OK;
}

static UINT32 WINAPI dwritetextformat_layout_GetFontFamilyNameLength(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.family_len;
}

static HRESULT WINAPI dwritetextformat_layout_GetFontFamilyName(IDWriteTextFormat1 *iface, WCHAR *name, UINT32 size)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);

    TRACE("(%p)->(%p %u)\n", This, name, size);

    if (size <= This->format.family_len) return E_NOT_SUFFICIENT_BUFFER;
    strcpyW(name, This->format.family_name);
    return S_OK;
}

static DWRITE_FONT_WEIGHT WINAPI dwritetextformat_layout_GetFontWeight(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.weight;
}

static DWRITE_FONT_STYLE WINAPI dwritetextformat_layout_GetFontStyle(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.style;
}

static DWRITE_FONT_STRETCH WINAPI dwritetextformat_layout_GetFontStretch(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.stretch;
}

static FLOAT WINAPI dwritetextformat_layout_GetFontSize(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.fontsize;
}

static UINT32 WINAPI dwritetextformat_layout_GetLocaleNameLength(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.locale_len;
}

static HRESULT WINAPI dwritetextformat_layout_GetLocaleName(IDWriteTextFormat1 *iface, WCHAR *name, UINT32 size)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);

    TRACE("(%p)->(%p %u)\n", This, name, size);

    if (size <= This->format.locale_len) return E_NOT_SUFFICIENT_BUFFER;
    strcpyW(name, This->format.locale);
    return S_OK;
}

static HRESULT WINAPI dwritetextformat1_layout_SetVerticalGlyphOrientation(IDWriteTextFormat1 *iface, DWRITE_VERTICAL_GLYPH_ORIENTATION orientation)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    FIXME("(%p)->(%d): stub\n", This, orientation);
    return E_NOTIMPL;
}

static DWRITE_VERTICAL_GLYPH_ORIENTATION WINAPI dwritetextformat1_layout_GetVerticalGlyphOrientation(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    FIXME("(%p): stub\n", This);
    return DWRITE_VERTICAL_GLYPH_ORIENTATION_DEFAULT;
}

static HRESULT WINAPI dwritetextformat1_layout_SetLastLineWrapping(IDWriteTextFormat1 *iface, BOOL lastline_wrapping_enabled)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);

    TRACE("(%p)->(%d)\n", This, lastline_wrapping_enabled);

    This->format.last_line_wrapping = !!lastline_wrapping_enabled;
    return S_OK;
}

static BOOL WINAPI dwritetextformat1_layout_GetLastLineWrapping(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.last_line_wrapping;
}

static HRESULT WINAPI dwritetextformat1_layout_SetOpticalAlignment(IDWriteTextFormat1 *iface, DWRITE_OPTICAL_ALIGNMENT alignment)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)->(%d)\n", This, alignment);
    return format_set_optical_alignment(&This->format, alignment);
}

static DWRITE_OPTICAL_ALIGNMENT WINAPI dwritetextformat1_layout_GetOpticalAlignment(IDWriteTextFormat1 *iface)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)\n", This);
    return This->format.optical_alignment;
}

static HRESULT WINAPI dwritetextformat1_layout_SetFontFallback(IDWriteTextFormat1 *iface, IDWriteFontFallback *fallback)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)->(%p)\n", This, fallback);
    return IDWriteTextLayout3_SetFontFallback(&This->IDWriteTextLayout3_iface, fallback);
}

static HRESULT WINAPI dwritetextformat1_layout_GetFontFallback(IDWriteTextFormat1 *iface, IDWriteFontFallback **fallback)
{
    struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface);
    TRACE("(%p)->(%p)\n", This, fallback);
    return IDWriteTextLayout3_GetFontFallback(&This->IDWriteTextLayout3_iface, fallback);
}

static const IDWriteTextFormat1Vtbl dwritetextformat1_layout_vtbl = {
    dwritetextformat_layout_QueryInterface,
    dwritetextformat_layout_AddRef,
    dwritetextformat_layout_Release,
    dwritetextformat_layout_SetTextAlignment,
    dwritetextformat_layout_SetParagraphAlignment,
    dwritetextformat_layout_SetWordWrapping,
    dwritetextformat_layout_SetReadingDirection,
    dwritetextformat_layout_SetFlowDirection,
    dwritetextformat_layout_SetIncrementalTabStop,
    dwritetextformat_layout_SetTrimming,
    dwritetextformat_layout_SetLineSpacing,
    dwritetextformat_layout_GetTextAlignment,
    dwritetextformat_layout_GetParagraphAlignment,
    dwritetextformat_layout_GetWordWrapping,
    dwritetextformat_layout_GetReadingDirection,
    dwritetextformat_layout_GetFlowDirection,
    dwritetextformat_layout_GetIncrementalTabStop,
    dwritetextformat_layout_GetTrimming,
    dwritetextformat_layout_GetLineSpacing,
    dwritetextformat_layout_GetFontCollection,
    dwritetextformat_layout_GetFontFamilyNameLength,
    dwritetextformat_layout_GetFontFamilyName,
    dwritetextformat_layout_GetFontWeight,
    dwritetextformat_layout_GetFontStyle,
    dwritetextformat_layout_GetFontStretch,
    dwritetextformat_layout_GetFontSize,
    dwritetextformat_layout_GetLocaleNameLength,
    dwritetextformat_layout_GetLocaleName,
    dwritetextformat1_layout_SetVerticalGlyphOrientation,
    dwritetextformat1_layout_GetVerticalGlyphOrientation,
    dwritetextformat1_layout_SetLastLineWrapping,
    dwritetextformat1_layout_GetLastLineWrapping,
    dwritetextformat1_layout_SetOpticalAlignment,
    dwritetextformat1_layout_GetOpticalAlignment,
    dwritetextformat1_layout_SetFontFallback,
    dwritetextformat1_layout_GetFontFallback,
};

static HRESULT WINAPI dwritetextlayout_sink_QueryInterface(IDWriteTextAnalysisSink1 *iface,
    REFIID riid, void **obj)
{
    if (IsEqualIID(riid, &IID_IDWriteTextAnalysisSink1) ||
        IsEqualIID(riid, &IID_IDWriteTextAnalysisSink) ||
        IsEqualIID(riid, &IID_IUnknown))
    {
        *obj = iface;
        IDWriteTextAnalysisSink1_AddRef(iface);
        return S_OK;
    }

    WARN("%s not implemented.\n", debugstr_guid(riid));

    *obj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI dwritetextlayout_sink_AddRef(IDWriteTextAnalysisSink1 *iface)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink1(iface);
    return IDWriteTextLayout3_AddRef(&layout->IDWriteTextLayout3_iface);
}

static ULONG WINAPI dwritetextlayout_sink_Release(IDWriteTextAnalysisSink1 *iface)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink1(iface);
    return IDWriteTextLayout3_Release(&layout->IDWriteTextLayout3_iface);
}

static HRESULT WINAPI dwritetextlayout_sink_SetScriptAnalysis(IDWriteTextAnalysisSink1 *iface,
    UINT32 position, UINT32 length, DWRITE_SCRIPT_ANALYSIS const* sa)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink1(iface);
    struct layout_run *run;

    TRACE("[%u,%u) script=%u:%s\n", position, position + length, sa->script, debugstr_sa_script(sa->script));

    run = alloc_layout_run(LAYOUT_RUN_REGULAR, position);
    if (!run)
        return E_OUTOFMEMORY;

    run->u.regular.descr.string = &layout->str[position];
    run->u.regular.descr.stringLength = length;
    run->u.regular.descr.textPosition = position;
    run->u.regular.sa = *sa;
    list_add_tail(&layout->runs, &run->entry);
    return S_OK;
}

static HRESULT WINAPI dwritetextlayout_sink_SetLineBreakpoints(IDWriteTextAnalysisSink1 *iface,
    UINT32 position, UINT32 length, DWRITE_LINE_BREAKPOINT const* breakpoints)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink1(iface);

    if (position + length > layout->len)
        return E_FAIL;

    memcpy(&layout->nominal_breakpoints[position], breakpoints, length*sizeof(DWRITE_LINE_BREAKPOINT));
    return S_OK;
}

static HRESULT WINAPI dwritetextlayout_sink_SetBidiLevel(IDWriteTextAnalysisSink1 *iface, UINT32 position,
    UINT32 length, UINT8 explicitLevel, UINT8 resolvedLevel)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink1(iface);
    struct layout_run *cur_run;

    TRACE("[%u,%u) %u %u\n", position, position + length, explicitLevel, resolvedLevel);

    LIST_FOR_EACH_ENTRY(cur_run, &layout->runs, struct layout_run, entry) {
        struct regular_layout_run *cur = &cur_run->u.regular;
        struct layout_run *run;

        if (cur_run->kind == LAYOUT_RUN_INLINE)
            continue;

        /* FIXME: levels are reported in a natural forward direction, so start loop from a run we ended on */
        if (position < cur->descr.textPosition || position >= cur->descr.textPosition + cur->descr.stringLength)
            continue;

        /* full hit - just set run level */
        if (cur->descr.textPosition == position && cur->descr.stringLength == length) {
            cur->run.bidiLevel = resolvedLevel;
            break;
        }

        /* current run is fully covered, move to next one */
        if (cur->descr.textPosition == position && cur->descr.stringLength < length) {
            cur->run.bidiLevel = resolvedLevel;
            position += cur->descr.stringLength;
            length -= cur->descr.stringLength;
            continue;
        }

        /* all fully covered runs are processed at this point, reuse existing run for remaining
           reported bidi range and add another run for the rest of original one */

        run = alloc_layout_run(LAYOUT_RUN_REGULAR, position + length);
        if (!run)
            return E_OUTOFMEMORY;

        *run = *cur_run;
        run->u.regular.descr.textPosition = position + length;
        run->u.regular.descr.stringLength = cur->descr.stringLength - length;
        run->u.regular.descr.string = &layout->str[position + length];

        /* reduce existing run */
        cur->run.bidiLevel = resolvedLevel;
        cur->descr.stringLength = length;

        list_add_after(&cur_run->entry, &run->entry);
        break;
    }

    return S_OK;
}

static HRESULT WINAPI dwritetextlayout_sink_SetNumberSubstitution(IDWriteTextAnalysisSink1 *iface,
    UINT32 position, UINT32 length, IDWriteNumberSubstitution* substitution)
{
    return E_NOTIMPL;
}

static HRESULT WINAPI dwritetextlayout_sink_SetGlyphOrientation(IDWriteTextAnalysisSink1 *iface,
    UINT32 position, UINT32 length, DWRITE_GLYPH_ORIENTATION_ANGLE angle, UINT8 adjusted_bidi_level,
    BOOL is_sideways, BOOL is_rtl)
{
    return E_NOTIMPL;
}

static const IDWriteTextAnalysisSink1Vtbl dwritetextlayoutsinkvtbl = {
    dwritetextlayout_sink_QueryInterface,
    dwritetextlayout_sink_AddRef,
    dwritetextlayout_sink_Release,
    dwritetextlayout_sink_SetScriptAnalysis,
    dwritetextlayout_sink_SetLineBreakpoints,
    dwritetextlayout_sink_SetBidiLevel,
    dwritetextlayout_sink_SetNumberSubstitution,
    dwritetextlayout_sink_SetGlyphOrientation
};

static HRESULT WINAPI dwritetextlayout_source_QueryInterface(IDWriteTextAnalysisSource1 *iface,
    REFIID riid, void **obj)
{
    if (IsEqualIID(riid, &IID_IDWriteTextAnalysisSource1) ||
        IsEqualIID(riid, &IID_IDWriteTextAnalysisSource) ||
        IsEqualIID(riid, &IID_IUnknown))
    {
        *obj = iface;
        IDWriteTextAnalysisSource1_AddRef(iface);
        return S_OK;
    }

    WARN("%s not implemented.\n", debugstr_guid(riid));

    *obj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI dwritetextlayout_source_AddRef(IDWriteTextAnalysisSource1 *iface)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface);
    return IDWriteTextLayout3_AddRef(&layout->IDWriteTextLayout3_iface);
}

static ULONG WINAPI dwritetextlayout_source_Release(IDWriteTextAnalysisSource1 *iface)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface);
    return IDWriteTextLayout3_Release(&layout->IDWriteTextLayout3_iface);
}

static HRESULT WINAPI dwritetextlayout_source_GetTextAtPosition(IDWriteTextAnalysisSource1 *iface,
    UINT32 position, WCHAR const** text, UINT32* text_len)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface);

    TRACE("(%p)->(%u %p %p)\n", layout, position, text, text_len);

    if (position < layout->len) {
        *text = &layout->str[position];
        *text_len = layout->len - position;
    }
    else {
        *text = NULL;
        *text_len = 0;
    }

    return S_OK;
}

static HRESULT WINAPI dwritetextlayout_source_GetTextBeforePosition(IDWriteTextAnalysisSource1 *iface,
    UINT32 position, WCHAR const** text, UINT32* text_len)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface);

    TRACE("(%p)->(%u %p %p)\n", layout, position, text, text_len);

    if (position > 0 && position < layout->len) {
        *text = layout->str;
        *text_len = position;
    }
    else {
        *text = NULL;
        *text_len = 0;
    }

    return S_OK;
}

static DWRITE_READING_DIRECTION WINAPI dwritetextlayout_source_GetParagraphReadingDirection(IDWriteTextAnalysisSource1 *iface)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface);
    return IDWriteTextLayout3_GetReadingDirection(&layout->IDWriteTextLayout3_iface);
}

static HRESULT WINAPI dwritetextlayout_source_GetLocaleName(IDWriteTextAnalysisSource1 *iface,
    UINT32 position, UINT32* text_len, WCHAR const** locale)
{
    struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface);
    struct layout_range *range = get_layout_range_by_pos(layout, position);

    if (position < layout->len) {
        struct layout_range *next;

        *locale = range->locale;
        *text_len = range->h.range.length - position;

        next = LIST_ENTRY(list_next(&layout->ranges, &range->h.entry), struct layout_range, h.entry);
        while (next && next->h.range.startPosition < layout->len && !strcmpW(range->locale, next->locale)) {
            *text_len += next->h.range.length;
            next = LIST_ENTRY(list_next(&layout->ranges, &next->h.entry), struct layout_range, h.entry);
        }

        *text_len = min(*text_len, layout->len - position);
    }
    else {
        *locale = NULL;
        *text_len = 0;
    }

    return S_OK;
}

static HRESULT WINAPI dwritetextlayout_source_GetNumberSubstitution(IDWriteTextAnalysisSource1 *iface,
    UINT32 position, UINT32* text_len, IDWriteNumberSubstitution **substitution)
{
    FIXME("%u %p %p: stub\n", position, text_len, substitution);
    return E_NOTIMPL;
}

static HRESULT WINAPI dwritetextlayout_source_GetVerticalGlyphOrientation(IDWriteTextAnalysisSource1 *iface,
    UINT32 position, UINT32 *length, DWRITE_VERTICAL_GLYPH_ORIENTATION *orientation, UINT8 *bidi_level)
{
    FIXME("%u %p %p %p: stub\n", position, length, orientation, bidi_level);
    return E_NOTIMPL;
}

static const IDWriteTextAnalysisSource1Vtbl dwritetextlayoutsourcevtbl = {
    dwritetextlayout_source_QueryInterface,
    dwritetextlayout_source_AddRef,
    dwritetextlayout_source_Release,
    dwritetextlayout_source_GetTextAtPosition,
    dwritetextlayout_source_GetTextBeforePosition,
    dwritetextlayout_source_GetParagraphReadingDirection,
    dwritetextlayout_source_GetLocaleName,
    dwritetextlayout_source_GetNumberSubstitution,
    dwritetextlayout_source_GetVerticalGlyphOrientation
};

static HRESULT layout_format_from_textformat(struct dwrite_textlayout *layout, IDWriteTextFormat *format)
{
    struct dwrite_textformat *textformat;
    IDWriteTextFormat1 *format1;
    UINT32 len;
    HRESULT hr;

    if ((textformat = unsafe_impl_from_IDWriteTextFormat(format))) {
        layout->format = textformat->format;

        layout->format.locale = heap_strdupW(textformat->format.locale);
        layout->format.family_name = heap_strdupW(textformat->format.family_name);
        if (!layout->format.locale || !layout->format.family_name)
        {
            heap_free(layout->format.locale);
            heap_free(layout->format.family_name);
            return E_OUTOFMEMORY;
        }

        if (layout->format.trimmingsign)
            IDWriteInlineObject_AddRef(layout->format.trimmingsign);
        if (layout->format.collection)
            IDWriteFontCollection_AddRef(layout->format.collection);
        if (layout->format.fallback)
            IDWriteFontFallback_AddRef(layout->format.fallback);

        return S_OK;
    }

    layout->format.weight  = IDWriteTextFormat_GetFontWeight(format);
    layout->format.style   = IDWriteTextFormat_GetFontStyle(format);
    layout->format.stretch = IDWriteTextFormat_GetFontStretch(format);
    layout->format.fontsize= IDWriteTextFormat_GetFontSize(format);
    layout->format.textalignment = IDWriteTextFormat_GetTextAlignment(format);
    layout->format.paralign = IDWriteTextFormat_GetParagraphAlignment(format);
    layout->format.wrapping = IDWriteTextFormat_GetWordWrapping(format);
    layout->format.readingdir = IDWriteTextFormat_GetReadingDirection(format);
    layout->format.flow = IDWriteTextFormat_GetFlowDirection(format);
    layout->format.fallback = NULL;
    layout->format.spacing.leadingBefore = 0.0f;
    layout->format.spacing.fontLineGapUsage = DWRITE_FONT_LINE_GAP_USAGE_DEFAULT;
    hr = IDWriteTextFormat_GetLineSpacing(format, &layout->format.spacing.method,
        &layout->format.spacing.height, &layout->format.spacing.baseline);
    if (FAILED(hr))
        return hr;

    hr = IDWriteTextFormat_GetTrimming(format, &layout->format.trimming, &layout->format.trimmingsign);
    if (FAILED(hr))
        return hr;

    /* locale name and length */
    len = IDWriteTextFormat_GetLocaleNameLength(format);
    layout->format.locale = heap_alloc((len+1)*sizeof(WCHAR));
    if (!layout->format.locale)
        return E_OUTOFMEMORY;

    hr = IDWriteTextFormat_GetLocaleName(format, layout->format.locale, len+1);
    if (FAILED(hr))
        return hr;
    layout->format.locale_len = len;

    /* font family name and length */
    len = IDWriteTextFormat_GetFontFamilyNameLength(format);
    layout->format.family_name = heap_alloc((len+1)*sizeof(WCHAR));
    if (!layout->format.family_name)
        return E_OUTOFMEMORY;

    hr = IDWriteTextFormat_GetFontFamilyName(format, layout->format.family_name, len+1);
    if (FAILED(hr))
        return hr;
    layout->format.family_len = len;

    hr = IDWriteTextFormat_QueryInterface(format, &IID_IDWriteTextFormat1, (void**)&format1);
    if (hr == S_OK) {
        IDWriteTextFormat2 *format2;

        layout->format.vertical_orientation = IDWriteTextFormat1_GetVerticalGlyphOrientation(format1);
        layout->format.optical_alignment = IDWriteTextFormat1_GetOpticalAlignment(format1);
        IDWriteTextFormat1_GetFontFallback(format1, &layout->format.fallback);

        if (IDWriteTextFormat1_QueryInterface(format1, &IID_IDWriteTextFormat2, (void**)&format2) == S_OK) {
            IDWriteTextFormat2_GetLineSpacing(format2, &layout->format.spacing);
            IDWriteTextFormat2_Release(format2);
        }

        IDWriteTextFormat1_Release(format1);
    }
    else {
        layout->format.vertical_orientation = DWRITE_VERTICAL_GLYPH_ORIENTATION_DEFAULT;
        layout->format.optical_alignment = DWRITE_OPTICAL_ALIGNMENT_NONE;
    }

    return IDWriteTextFormat_GetFontCollection(format, &layout->format.collection);
}

static HRESULT init_textlayout(const struct textlayout_desc *desc, struct dwrite_textlayout *layout)
{
    struct layout_range_header *range, *strike, *underline, *effect, *spacing, *typography;
    static const DWRITE_TEXT_RANGE r = { 0, ~0u };
    HRESULT hr;

    layout->IDWriteTextLayout3_iface.lpVtbl = &dwritetextlayoutvtbl;
    layout->IDWriteTextFormat1_iface.lpVtbl = &dwritetextformat1_layout_vtbl;
    layout->IDWriteTextAnalysisSink1_iface.lpVtbl = &dwritetextlayoutsinkvtbl;
    layout->IDWriteTextAnalysisSource1_iface.lpVtbl = &dwritetextlayoutsourcevtbl;
    layout->ref = 1;
    layout->len = desc->length;
    layout->recompute = RECOMPUTE_EVERYTHING;
    layout->nominal_breakpoints = NULL;
    layout->actual_breakpoints = NULL;
    layout->cluster_count = 0;
    layout->clustermetrics = NULL;
    layout->clusters = NULL;
    layout->linemetrics = NULL;
    layout->lines = NULL;
    layout->line_alloc = 0;
    layout->minwidth = 0.0f;
    list_init(&layout->eruns);
    list_init(&layout->inlineobjects);
    list_init(&layout->underlines);
    list_init(&layout->strikethrough);
    list_init(&layout->runs);
    list_init(&layout->ranges);
    list_init(&layout->strike_ranges);
    list_init(&layout->underline_ranges);
    list_init(&layout->effects);
    list_init(&layout->spacing);
    list_init(&layout->typographies);
    memset(&layout->format, 0, sizeof(layout->format));
    memset(&layout->metrics, 0, sizeof(layout->metrics));
    layout->metrics.layoutWidth = desc->max_width;
    layout->metrics.layoutHeight = desc->max_height;
    layout->measuringmode = DWRITE_MEASURING_MODE_NATURAL;

    layout->ppdip = 0.0f;
    memset(&layout->transform, 0, sizeof(layout->transform));

    layout->str = heap_strdupnW(desc->string, desc->length);
    if (desc->length && !layout->str) {
        hr = E_OUTOFMEMORY;
        goto fail;
    }

    hr = layout_format_from_textformat(layout, desc->format);
    if (FAILED(hr))
        goto fail;

    range = alloc_layout_range(layout, &r, LAYOUT_RANGE_REGULAR);
    strike = alloc_layout_range(layout, &r, LAYOUT_RANGE_STRIKETHROUGH);
    underline = alloc_layout_range(layout, &r, LAYOUT_RANGE_UNDERLINE);
    effect = alloc_layout_range(layout, &r, LAYOUT_RANGE_EFFECT);
    spacing = alloc_layout_range(layout, &r, LAYOUT_RANGE_SPACING);
    typography = alloc_layout_range(layout, &r, LAYOUT_RANGE_TYPOGRAPHY);
    if (!range || !strike || !effect || !spacing || !typography || !underline) {
        free_layout_range(range);
        free_layout_range(strike);
        free_layout_range(underline);
        free_layout_range(effect);
        free_layout_range(spacing);
        free_layout_range(typography);
        hr = E_OUTOFMEMORY;
        goto fail;
    }

    if (desc->is_gdi_compatible)
        layout->measuringmode = desc->use_gdi_natural ? DWRITE_MEASURING_MODE_GDI_NATURAL : DWRITE_MEASURING_MODE_GDI_CLASSIC;
    else
        layout->measuringmode = DWRITE_MEASURING_MODE_NATURAL;
    layout->ppdip = desc->ppdip;
    layout->transform = desc->transform ? *desc->transform : identity;

    layout->factory = desc->factory;
    IDWriteFactory5_AddRef(layout->factory);
    list_add_head(&layout->ranges, &range->entry);
    list_add_head(&layout->strike_ranges, &strike->entry);
    list_add_head(&layout->underline_ranges, &underline->entry);
    list_add_head(&layout->effects, &effect->entry);
    list_add_head(&layout->spacing, &spacing->entry);
    list_add_head(&layout->typographies, &typography->entry);
    return S_OK;

fail:
    IDWriteTextLayout3_Release(&layout->IDWriteTextLayout3_iface);
    return hr;
}

HRESULT create_textlayout(const struct textlayout_desc *desc, IDWriteTextLayout **ret)
{
    struct dwrite_textlayout *layout;
    HRESULT hr;

    *ret = NULL;

    if (!desc->format || !desc->string)
        return E_INVALIDARG;

    layout = heap_alloc(sizeof(struct dwrite_textlayout));
    if (!layout) return E_OUTOFMEMORY;

    hr = init_textlayout(desc, layout);
    if (hr == S_OK)
        *ret = (IDWriteTextLayout*)&layout->IDWriteTextLayout3_iface;

    return hr;
}

static HRESULT WINAPI dwritetrimmingsign_QueryInterface(IDWriteInlineObject *iface, REFIID riid, void **obj)
{
    struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteInlineObject)) {
        *obj = iface;
        IDWriteInlineObject_AddRef(iface);
        return S_OK;
    }

    WARN("%s not implemented.\n", debugstr_guid(riid));

    *obj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI dwritetrimmingsign_AddRef(IDWriteInlineObject *iface)
{
    struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI dwritetrimmingsign_Release(IDWriteInlineObject *iface)
{
    struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref) {
        IDWriteTextLayout_Release(This->layout);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI dwritetrimmingsign_Draw(IDWriteInlineObject *iface, void *context, IDWriteTextRenderer *renderer,
    FLOAT originX, FLOAT originY, BOOL is_sideways, BOOL is_rtl, IUnknown *effect)
{
    struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
    DWRITE_LINE_METRICS line;
    UINT32 line_count;

    TRACE("(%p)->(%p %p %.2f %.2f %d %d %p)\n", This, context, renderer, originX, originY,
            is_sideways, is_rtl, effect);

    IDWriteTextLayout_GetLineMetrics(This->layout, &line, 1, &line_count);
    return IDWriteTextLayout_Draw(This->layout, context, renderer, originX, originY - line.baseline);
}

static HRESULT WINAPI dwritetrimmingsign_GetMetrics(IDWriteInlineObject *iface, DWRITE_INLINE_OBJECT_METRICS *ret)
{
    struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
    DWRITE_TEXT_METRICS metrics;
    HRESULT hr;

    TRACE("(%p)->(%p)\n", This, ret);

    hr = IDWriteTextLayout_GetMetrics(This->layout, &metrics);
    if (FAILED(hr)) {
        memset(ret, 0, sizeof(*ret));
        return hr;
    }

    ret->width = metrics.width;
    ret->height = 0.0f;
    ret->baseline = 0.0f;
    ret->supportsSideways = FALSE;
    return S_OK;
}

static HRESULT WINAPI dwritetrimmingsign_GetOverhangMetrics(IDWriteInlineObject *iface, DWRITE_OVERHANG_METRICS *overhangs)
{
    struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);
    TRACE("(%p)->(%p)\n", This, overhangs);
    return IDWriteTextLayout_GetOverhangMetrics(This->layout, overhangs);
}

static HRESULT WINAPI dwritetrimmingsign_GetBreakConditions(IDWriteInlineObject *iface, DWRITE_BREAK_CONDITION *before,
        DWRITE_BREAK_CONDITION *after)
{
    struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface);

    TRACE("(%p)->(%p %p)\n", This, before, after);

    *before = *after = DWRITE_BREAK_CONDITION_NEUTRAL;
    return S_OK;
}

static const IDWriteInlineObjectVtbl dwritetrimmingsignvtbl = {
    dwritetrimmingsign_QueryInterface,
    dwritetrimmingsign_AddRef,
    dwritetrimmingsign_Release,
    dwritetrimmingsign_Draw,
    dwritetrimmingsign_GetMetrics,
    dwritetrimmingsign_GetOverhangMetrics,
    dwritetrimmingsign_GetBreakConditions
};

static inline BOOL is_reading_direction_horz(DWRITE_READING_DIRECTION direction)
{
    return (direction == DWRITE_READING_DIRECTION_LEFT_TO_RIGHT) ||
           (direction == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT);
}

static inline BOOL is_reading_direction_vert(DWRITE_READING_DIRECTION direction)
{
    return (direction == DWRITE_READING_DIRECTION_TOP_TO_BOTTOM) ||
           (direction == DWRITE_READING_DIRECTION_BOTTOM_TO_TOP);
}

static inline BOOL is_flow_direction_horz(DWRITE_FLOW_DIRECTION direction)
{
    return (direction == DWRITE_FLOW_DIRECTION_LEFT_TO_RIGHT) ||
           (direction == DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT);
}

static inline BOOL is_flow_direction_vert(DWRITE_FLOW_DIRECTION direction)
{
    return (direction == DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM) ||
           (direction == DWRITE_FLOW_DIRECTION_BOTTOM_TO_TOP);
}

HRESULT create_trimmingsign(IDWriteFactory5 *factory, IDWriteTextFormat *format, IDWriteInlineObject **sign)
{
    static const WCHAR ellipsisW = 0x2026;
    struct dwrite_trimmingsign *This;
    DWRITE_READING_DIRECTION reading;
    DWRITE_FLOW_DIRECTION flow;
    HRESULT hr;

    *sign = NULL;

    /* Validate reading/flow direction here, layout creation won't complain about
       invalid combinations. */
    reading = IDWriteTextFormat_GetReadingDirection(format);
    flow = IDWriteTextFormat_GetFlowDirection(format);

    if ((is_reading_direction_horz(reading) && is_flow_direction_horz(flow)) ||
        (is_reading_direction_vert(reading) && is_flow_direction_vert(flow)))
        return DWRITE_E_FLOWDIRECTIONCONFLICTS;

    This = heap_alloc(sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;

    This->IDWriteInlineObject_iface.lpVtbl = &dwritetrimmingsignvtbl;
    This->ref = 1;

    hr = IDWriteFactory5_CreateTextLayout(factory, &ellipsisW, 1, format, 0.0f, 0.0f, &This->layout);
    if (FAILED(hr)) {
        heap_free(This);
        return hr;
    }

    IDWriteTextLayout_SetWordWrapping(This->layout, DWRITE_WORD_WRAPPING_NO_WRAP);
    IDWriteTextLayout_SetParagraphAlignment(This->layout, DWRITE_PARAGRAPH_ALIGNMENT_NEAR);
    IDWriteTextLayout_SetTextAlignment(This->layout, DWRITE_TEXT_ALIGNMENT_LEADING);

    *sign = &This->IDWriteInlineObject_iface;

    return S_OK;
}

static HRESULT WINAPI dwritetextformat_QueryInterface(IDWriteTextFormat2 *iface, REFIID riid, void **obj)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    if (IsEqualIID(riid, &IID_IDWriteTextFormat2) ||
        IsEqualIID(riid, &IID_IDWriteTextFormat1) ||
        IsEqualIID(riid, &IID_IDWriteTextFormat)  ||
        IsEqualIID(riid, &IID_IUnknown))
    {
        *obj = iface;
        IDWriteTextFormat2_AddRef(iface);
        return S_OK;
    }

    WARN("%s not implemented.\n", debugstr_guid(riid));

    *obj = NULL;

    return E_NOINTERFACE;
}

static ULONG WINAPI dwritetextformat_AddRef(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI dwritetextformat_Release(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
    {
        release_format_data(&This->format);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI dwritetextformat_SetTextAlignment(IDWriteTextFormat2 *iface, DWRITE_TEXT_ALIGNMENT alignment)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%d)\n", This, alignment);
    return format_set_textalignment(&This->format, alignment, NULL);
}

static HRESULT WINAPI dwritetextformat_SetParagraphAlignment(IDWriteTextFormat2 *iface, DWRITE_PARAGRAPH_ALIGNMENT alignment)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%d)\n", This, alignment);
    return format_set_paralignment(&This->format, alignment, NULL);
}

static HRESULT WINAPI dwritetextformat_SetWordWrapping(IDWriteTextFormat2 *iface, DWRITE_WORD_WRAPPING wrapping)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%d)\n", This, wrapping);
    return format_set_wordwrapping(&This->format, wrapping, NULL);
}

static HRESULT WINAPI dwritetextformat_SetReadingDirection(IDWriteTextFormat2 *iface, DWRITE_READING_DIRECTION direction)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%d)\n", This, direction);
    return format_set_readingdirection(&This->format, direction, NULL);
}

static HRESULT WINAPI dwritetextformat_SetFlowDirection(IDWriteTextFormat2 *iface, DWRITE_FLOW_DIRECTION direction)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%d)\n", This, direction);
    return format_set_flowdirection(&This->format, direction, NULL);
}

static HRESULT WINAPI dwritetextformat_SetIncrementalTabStop(IDWriteTextFormat2 *iface, FLOAT tabstop)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    FIXME("(%p)->(%f): stub\n", This, tabstop);
    return E_NOTIMPL;
}

static HRESULT WINAPI dwritetextformat_SetTrimming(IDWriteTextFormat2 *iface, DWRITE_TRIMMING const *trimming,
    IDWriteInlineObject *trimming_sign)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%p %p)\n", This, trimming, trimming_sign);
    return format_set_trimming(&This->format, trimming, trimming_sign, NULL);
}

static HRESULT WINAPI dwritetextformat_SetLineSpacing(IDWriteTextFormat2 *iface, DWRITE_LINE_SPACING_METHOD method,
    FLOAT height, FLOAT baseline)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    DWRITE_LINE_SPACING spacing;

    TRACE("(%p)->(%d %f %f)\n", This, method, height, baseline);

    spacing = This->format.spacing;
    spacing.method = method;
    spacing.height = height;
    spacing.baseline = baseline;

    return format_set_linespacing(&This->format, &spacing, NULL);
}

static DWRITE_TEXT_ALIGNMENT WINAPI dwritetextformat_GetTextAlignment(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.textalignment;
}

static DWRITE_PARAGRAPH_ALIGNMENT WINAPI dwritetextformat_GetParagraphAlignment(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.paralign;
}

static DWRITE_WORD_WRAPPING WINAPI dwritetextformat_GetWordWrapping(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.wrapping;
}

static DWRITE_READING_DIRECTION WINAPI dwritetextformat_GetReadingDirection(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.readingdir;
}

static DWRITE_FLOW_DIRECTION WINAPI dwritetextformat_GetFlowDirection(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.flow;
}

static FLOAT WINAPI dwritetextformat_GetIncrementalTabStop(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    FIXME("(%p): stub\n", This);
    return 0.0f;
}

static HRESULT WINAPI dwritetextformat_GetTrimming(IDWriteTextFormat2 *iface, DWRITE_TRIMMING *options,
    IDWriteInlineObject **trimming_sign)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%p %p)\n", This, options, trimming_sign);

    *options = This->format.trimming;
    if ((*trimming_sign = This->format.trimmingsign))
        IDWriteInlineObject_AddRef(*trimming_sign);

    return S_OK;
}

static HRESULT WINAPI dwritetextformat_GetLineSpacing(IDWriteTextFormat2 *iface, DWRITE_LINE_SPACING_METHOD *method,
    FLOAT *spacing, FLOAT *baseline)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%p %p %p)\n", This, method, spacing, baseline);

    *method = This->format.spacing.method;
    *spacing = This->format.spacing.height;
    *baseline = This->format.spacing.baseline;
    return S_OK;
}

static HRESULT WINAPI dwritetextformat_GetFontCollection(IDWriteTextFormat2 *iface, IDWriteFontCollection **collection)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);

    TRACE("(%p)->(%p)\n", This, collection);

    *collection = This->format.collection;
    IDWriteFontCollection_AddRef(*collection);

    return S_OK;
}

static UINT32 WINAPI dwritetextformat_GetFontFamilyNameLength(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.family_len;
}

static HRESULT WINAPI dwritetextformat_GetFontFamilyName(IDWriteTextFormat2 *iface, WCHAR *name, UINT32 size)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);

    TRACE("(%p)->(%p %u)\n", This, name, size);

    if (size <= This->format.family_len) return E_NOT_SUFFICIENT_BUFFER;
    strcpyW(name, This->format.family_name);
    return S_OK;
}

static DWRITE_FONT_WEIGHT WINAPI dwritetextformat_GetFontWeight(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.weight;
}

static DWRITE_FONT_STYLE WINAPI dwritetextformat_GetFontStyle(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.style;
}

static DWRITE_FONT_STRETCH WINAPI dwritetextformat_GetFontStretch(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.stretch;
}

static FLOAT WINAPI dwritetextformat_GetFontSize(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.fontsize;
}

static UINT32 WINAPI dwritetextformat_GetLocaleNameLength(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.locale_len;
}

static HRESULT WINAPI dwritetextformat_GetLocaleName(IDWriteTextFormat2 *iface, WCHAR *name, UINT32 size)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);

    TRACE("(%p)->(%p %u)\n", This, name, size);

    if (size <= This->format.locale_len) return E_NOT_SUFFICIENT_BUFFER;
    strcpyW(name, This->format.locale);
    return S_OK;
}

static HRESULT WINAPI dwritetextformat1_SetVerticalGlyphOrientation(IDWriteTextFormat2 *iface, DWRITE_VERTICAL_GLYPH_ORIENTATION orientation)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);

    TRACE("(%p)->(%d)\n", This, orientation);

    if ((UINT32)orientation > DWRITE_VERTICAL_GLYPH_ORIENTATION_STACKED)
        return E_INVALIDARG;

    This->format.vertical_orientation = orientation;
    return S_OK;
}

static DWRITE_VERTICAL_GLYPH_ORIENTATION WINAPI dwritetextformat1_GetVerticalGlyphOrientation(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.vertical_orientation;
}

static HRESULT WINAPI dwritetextformat1_SetLastLineWrapping(IDWriteTextFormat2 *iface, BOOL lastline_wrapping_enabled)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);

    TRACE("(%p)->(%d)\n", This, lastline_wrapping_enabled);

    This->format.last_line_wrapping = !!lastline_wrapping_enabled;
    return S_OK;
}

static BOOL WINAPI dwritetextformat1_GetLastLineWrapping(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.last_line_wrapping;
}

static HRESULT WINAPI dwritetextformat1_SetOpticalAlignment(IDWriteTextFormat2 *iface, DWRITE_OPTICAL_ALIGNMENT alignment)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%d)\n", This, alignment);
    return format_set_optical_alignment(&This->format, alignment);
}

static DWRITE_OPTICAL_ALIGNMENT WINAPI dwritetextformat1_GetOpticalAlignment(IDWriteTextFormat2 *iface)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)\n", This);
    return This->format.optical_alignment;
}

static HRESULT WINAPI dwritetextformat1_SetFontFallback(IDWriteTextFormat2 *iface, IDWriteFontFallback *fallback)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%p)\n", This, fallback);
    return set_fontfallback_for_format(&This->format, fallback);
}

static HRESULT WINAPI dwritetextformat1_GetFontFallback(IDWriteTextFormat2 *iface, IDWriteFontFallback **fallback)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%p)\n", This, fallback);
    return get_fontfallback_from_format(&This->format, fallback);
}

static HRESULT WINAPI dwritetextformat2_SetLineSpacing(IDWriteTextFormat2 *iface, DWRITE_LINE_SPACING const *spacing)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);
    TRACE("(%p)->(%p)\n", This, spacing);
    return format_set_linespacing(&This->format, spacing, NULL);
}

static HRESULT WINAPI dwritetextformat2_GetLineSpacing(IDWriteTextFormat2 *iface, DWRITE_LINE_SPACING *spacing)
{
    struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface);

    TRACE("(%p)->(%p)\n", This, spacing);

    *spacing = This->format.spacing;
    return S_OK;
}

static const IDWriteTextFormat2Vtbl dwritetextformatvtbl = {
    dwritetextformat_QueryInterface,
    dwritetextformat_AddRef,
    dwritetextformat_Release,
    dwritetextformat_SetTextAlignment,
    dwritetextformat_SetParagraphAlignment,
    dwritetextformat_SetWordWrapping,
    dwritetextformat_SetReadingDirection,
    dwritetextformat_SetFlowDirection,
    dwritetextformat_SetIncrementalTabStop,
    dwritetextformat_SetTrimming,
    dwritetextformat_SetLineSpacing,
    dwritetextformat_GetTextAlignment,
    dwritetextformat_GetParagraphAlignment,
    dwritetextformat_GetWordWrapping,
    dwritetextformat_GetReadingDirection,
    dwritetextformat_GetFlowDirection,
    dwritetextformat_GetIncrementalTabStop,
    dwritetextformat_GetTrimming,
    dwritetextformat_GetLineSpacing,
    dwritetextformat_GetFontCollection,
    dwritetextformat_GetFontFamilyNameLength,
    dwritetextformat_GetFontFamilyName,
    dwritetextformat_GetFontWeight,
    dwritetextformat_GetFontStyle,
    dwritetextformat_GetFontStretch,
    dwritetextformat_GetFontSize,
    dwritetextformat_GetLocaleNameLength,
    dwritetextformat_GetLocaleName,
    dwritetextformat1_SetVerticalGlyphOrientation,
    dwritetextformat1_GetVerticalGlyphOrientation,
    dwritetextformat1_SetLastLineWrapping,
    dwritetextformat1_GetLastLineWrapping,
    dwritetextformat1_SetOpticalAlignment,
    dwritetextformat1_GetOpticalAlignment,
    dwritetextformat1_SetFontFallback,
    dwritetextformat1_GetFontFallback,
    dwritetextformat2_SetLineSpacing,
    dwritetextformat2_GetLineSpacing
};

static struct dwrite_textformat *unsafe_impl_from_IDWriteTextFormat(IDWriteTextFormat *iface)
{
    return (iface->lpVtbl == (IDWriteTextFormatVtbl*)&dwritetextformatvtbl) ?
        CONTAINING_RECORD(iface, struct dwrite_textformat, IDWriteTextFormat2_iface) : NULL;
}

HRESULT create_textformat(const WCHAR *family_name, IDWriteFontCollection *collection, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style,
    DWRITE_FONT_STRETCH stretch, FLOAT size, const WCHAR *locale, IDWriteTextFormat **format)
{
    struct dwrite_textformat *This;

    *format = NULL;

    if (size <= 0.0f)
        return E_INVALIDARG;

    if (((UINT32)weight > DWRITE_FONT_WEIGHT_ULTRA_BLACK) ||
        ((UINT32)stretch > DWRITE_FONT_STRETCH_ULTRA_EXPANDED) ||
        ((UINT32)style > DWRITE_FONT_STYLE_ITALIC))
        return E_INVALIDARG;

    This = heap_alloc(sizeof(struct dwrite_textformat));
    if (!This) return E_OUTOFMEMORY;

    This->IDWriteTextFormat2_iface.lpVtbl = &dwritetextformatvtbl;
    This->ref = 1;
    This->format.family_name = heap_strdupW(family_name);
    This->format.family_len = strlenW(family_name);
    This->format.locale = heap_strdupW(locale);
    This->format.locale_len = strlenW(locale);
    /* force locale name to lower case, layout will inherit this modified value */
    strlwrW(This->format.locale);
    This->format.weight = weight;
    This->format.style = style;
    This->format.fontsize = size;
    This->format.stretch = stretch;
    This->format.textalignment = DWRITE_TEXT_ALIGNMENT_LEADING;
    This->format.optical_alignment = DWRITE_OPTICAL_ALIGNMENT_NONE;
    This->format.paralign = DWRITE_PARAGRAPH_ALIGNMENT_NEAR;
    This->format.wrapping = DWRITE_WORD_WRAPPING_WRAP;
    This->format.last_line_wrapping = TRUE;
    This->format.readingdir = DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
    This->format.flow = DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM;
    This->format.spacing.method = DWRITE_LINE_SPACING_METHOD_DEFAULT;
    This->format.spacing.height = 0.0f;
    This->format.spacing.baseline = 0.0f;
    This->format.spacing.leadingBefore = 0.0f;
    This->format.spacing.fontLineGapUsage = DWRITE_FONT_LINE_GAP_USAGE_DEFAULT;
    This->format.vertical_orientation = DWRITE_VERTICAL_GLYPH_ORIENTATION_DEFAULT;
    This->format.trimming.granularity = DWRITE_TRIMMING_GRANULARITY_NONE;
    This->format.trimming.delimiter = 0;
    This->format.trimming.delimiterCount = 0;
    This->format.trimmingsign = NULL;
    This->format.collection = collection;
    This->format.fallback = NULL;
    IDWriteFontCollection_AddRef(collection);

    *format = (IDWriteTextFormat*)&This->IDWriteTextFormat2_iface;

    return S_OK;
}

static HRESULT WINAPI dwritetypography_QueryInterface(IDWriteTypography *iface, REFIID riid, void **obj)
{
    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);

    TRACE("(%p)->(%s %p)\n", typography, debugstr_guid(riid), obj);

    if (IsEqualIID(riid, &IID_IDWriteTypography) || IsEqualIID(riid, &IID_IUnknown)) {
        *obj = iface;
        IDWriteTypography_AddRef(iface);
        return S_OK;
    }

    WARN("%s not implemented.\n", debugstr_guid(riid));

    *obj = NULL;

    return E_NOINTERFACE;
}

static ULONG WINAPI dwritetypography_AddRef(IDWriteTypography *iface)
{
    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
    ULONG ref = InterlockedIncrement(&typography->ref);
    TRACE("(%p)->(%d)\n", typography, ref);
    return ref;
}

static ULONG WINAPI dwritetypography_Release(IDWriteTypography *iface)
{
    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
    ULONG ref = InterlockedDecrement(&typography->ref);

    TRACE("(%p)->(%d)\n", typography, ref);

    if (!ref) {
        heap_free(typography->features);
        heap_free(typography);
    }

    return ref;
}

static HRESULT WINAPI dwritetypography_AddFontFeature(IDWriteTypography *iface, DWRITE_FONT_FEATURE feature)
{
    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);

    TRACE("(%p)->(%x %u)\n", typography, feature.nameTag, feature.parameter);

    if (typography->count == typography->allocated) {
        DWRITE_FONT_FEATURE *ptr = heap_realloc(typography->features, 2*typography->allocated*sizeof(DWRITE_FONT_FEATURE));
        if (!ptr)
            return E_OUTOFMEMORY;

        typography->features = ptr;
        typography->allocated *= 2;
    }

    typography->features[typography->count++] = feature;
    return S_OK;
}

static UINT32 WINAPI dwritetypography_GetFontFeatureCount(IDWriteTypography *iface)
{
    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
    TRACE("(%p)\n", typography);
    return typography->count;
}

static HRESULT WINAPI dwritetypography_GetFontFeature(IDWriteTypography *iface, UINT32 index, DWRITE_FONT_FEATURE *feature)
{
    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);

    TRACE("(%p)->(%u %p)\n", typography, index, feature);

    if (index >= typography->count)
        return E_INVALIDARG;

    *feature = typography->features[index];
    return S_OK;
}

static const IDWriteTypographyVtbl dwritetypographyvtbl = {
    dwritetypography_QueryInterface,
    dwritetypography_AddRef,
    dwritetypography_Release,
    dwritetypography_AddFontFeature,
    dwritetypography_GetFontFeatureCount,
    dwritetypography_GetFontFeature
};

HRESULT create_typography(IDWriteTypography **ret)
{
    struct dwrite_typography *typography;

    *ret = NULL;

    typography = heap_alloc(sizeof(*typography));
    if (!typography)
        return E_OUTOFMEMORY;

    typography->IDWriteTypography_iface.lpVtbl = &dwritetypographyvtbl;
    typography->ref = 1;
    typography->allocated = 2;
    typography->count = 0;

    typography->features = heap_alloc(typography->allocated*sizeof(DWRITE_FONT_FEATURE));
    if (!typography->features) {
        heap_free(typography);
        return E_OUTOFMEMORY;
    }

    *ret = &typography->IDWriteTypography_iface;
    return S_OK;
}
