dwrite: Fix the way drawing effects are reported for inline objects.
This commit is contained in:
parent
6655b0c93a
commit
b7fb00e9aa
|
@ -95,7 +95,8 @@ struct layout_range_attr_value {
|
||||||
|
|
||||||
enum layout_range_kind {
|
enum layout_range_kind {
|
||||||
LAYOUT_RANGE_REGULAR,
|
LAYOUT_RANGE_REGULAR,
|
||||||
LAYOUT_RANGE_STRIKETHROUGH
|
LAYOUT_RANGE_STRIKETHROUGH,
|
||||||
|
LAYOUT_RANGE_EFFECT
|
||||||
};
|
};
|
||||||
|
|
||||||
struct layout_range_header {
|
struct layout_range_header {
|
||||||
|
@ -111,7 +112,6 @@ struct layout_range {
|
||||||
FLOAT fontsize;
|
FLOAT fontsize;
|
||||||
DWRITE_FONT_STRETCH stretch;
|
DWRITE_FONT_STRETCH stretch;
|
||||||
IDWriteInlineObject *object;
|
IDWriteInlineObject *object;
|
||||||
IUnknown *effect;
|
|
||||||
BOOL underline;
|
BOOL underline;
|
||||||
BOOL pair_kerning;
|
BOOL pair_kerning;
|
||||||
IDWriteFontCollection *collection;
|
IDWriteFontCollection *collection;
|
||||||
|
@ -124,6 +124,11 @@ struct layout_range_bool {
|
||||||
BOOL value;
|
BOOL value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct layout_range_effect {
|
||||||
|
struct layout_range_header h;
|
||||||
|
IUnknown *effect;
|
||||||
|
};
|
||||||
|
|
||||||
enum layout_run_kind {
|
enum layout_run_kind {
|
||||||
LAYOUT_RUN_REGULAR,
|
LAYOUT_RUN_REGULAR,
|
||||||
LAYOUT_RUN_INLINE
|
LAYOUT_RUN_INLINE
|
||||||
|
@ -153,7 +158,6 @@ struct layout_run {
|
||||||
struct inline_object_run object;
|
struct inline_object_run object;
|
||||||
struct regular_layout_run regular;
|
struct regular_layout_run regular;
|
||||||
} u;
|
} u;
|
||||||
IUnknown *effect;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct layout_effective_run {
|
struct layout_effective_run {
|
||||||
|
@ -170,6 +174,7 @@ struct layout_effective_run {
|
||||||
struct layout_effective_inline {
|
struct layout_effective_inline {
|
||||||
struct list entry;
|
struct list entry;
|
||||||
IDWriteInlineObject *object;
|
IDWriteInlineObject *object;
|
||||||
|
IUnknown *effect;
|
||||||
FLOAT origin_x;
|
FLOAT origin_x;
|
||||||
FLOAT origin_y;
|
FLOAT origin_y;
|
||||||
BOOL is_sideways;
|
BOOL is_sideways;
|
||||||
|
@ -207,6 +212,7 @@ struct dwrite_textlayout {
|
||||||
FLOAT maxwidth;
|
FLOAT maxwidth;
|
||||||
FLOAT maxheight;
|
FLOAT maxheight;
|
||||||
struct list strike_ranges;
|
struct list strike_ranges;
|
||||||
|
struct list effects;
|
||||||
struct list ranges;
|
struct list ranges;
|
||||||
struct list runs;
|
struct list runs;
|
||||||
/* lists ready to use by Draw() */
|
/* lists ready to use by Draw() */
|
||||||
|
@ -601,7 +607,6 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
||||||
|
|
||||||
r->u.object.object = range->object;
|
r->u.object.object = range->object;
|
||||||
r->u.object.length = get_clipped_range_length(layout, range);
|
r->u.object.length = get_clipped_range_length(layout, range);
|
||||||
r->effect = range->effect;
|
|
||||||
list_add_tail(&layout->runs, &r->entry);
|
list_add_tail(&layout->runs, &r->entry);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -661,7 +666,6 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
range = get_layout_range_by_pos(layout, run->descr.textPosition);
|
range = get_layout_range_by_pos(layout, run->descr.textPosition);
|
||||||
r->effect = range->effect;
|
|
||||||
|
|
||||||
hr = IDWriteFontCollection_FindFamilyName(range->collection, range->fontfamily, &index, &exists);
|
hr = IDWriteFontCollection_FindFamilyName(range->collection, range->fontfamily, &index, &exists);
|
||||||
if (FAILED(hr) || !exists) {
|
if (FAILED(hr) || !exists) {
|
||||||
|
@ -844,6 +848,25 @@ static inline FLOAT get_cluster_range_width(struct dwrite_textlayout *layout, UI
|
||||||
return 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_effect*)h)->effect;
|
||||||
|
}
|
||||||
|
|
||||||
/* Effective run is built from consecutive clusters of a single nominal run, 'first_cluster' is 0 based cluster index,
|
/* 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. */
|
'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,
|
static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const struct layout_run *r, UINT32 first_cluster,
|
||||||
|
@ -867,6 +890,10 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
|
||||||
different ranges which differ in reading direction). */
|
different ranges which differ in reading direction). */
|
||||||
inlineobject->is_sideways = FALSE;
|
inlineobject->is_sideways = FALSE;
|
||||||
inlineobject->is_rtl = FALSE;
|
inlineobject->is_rtl = FALSE;
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
list_add_tail(&layout->inlineobjects, &inlineobject->entry);
|
list_add_tail(&layout->inlineobjects, &inlineobject->entry);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -970,19 +997,6 @@ static HRESULT layout_set_line_metrics(struct dwrite_textlayout *layout, DWRITE_
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 BOOL layout_get_strikethrough_from_pos(struct dwrite_textlayout *layout, UINT32 pos)
|
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);
|
struct layout_range_header *h = get_layout_range_header_by_pos(&layout->strike_ranges, pos);
|
||||||
|
@ -1090,6 +1104,7 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
|
||||||
|
|
||||||
static BOOL is_same_layout_attrvalue(struct layout_range_header const *h, enum layout_range_attr_kind attr, struct layout_range_attr_value *value)
|
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_effect const *range_effect = (struct layout_range_effect*)h;
|
||||||
struct layout_range_bool const *range_bool = (struct layout_range_bool*)h;
|
struct layout_range_bool const *range_bool = (struct layout_range_bool*)h;
|
||||||
struct layout_range const *range = (struct layout_range*)h;
|
struct layout_range const *range = (struct layout_range*)h;
|
||||||
|
|
||||||
|
@ -1105,7 +1120,7 @@ static BOOL is_same_layout_attrvalue(struct layout_range_header const *h, enum l
|
||||||
case LAYOUT_RANGE_ATTR_INLINE:
|
case LAYOUT_RANGE_ATTR_INLINE:
|
||||||
return range->object == value->u.object;
|
return range->object == value->u.object;
|
||||||
case LAYOUT_RANGE_ATTR_EFFECT:
|
case LAYOUT_RANGE_ATTR_EFFECT:
|
||||||
return range->effect == value->u.effect;
|
return range_effect->effect == value->u.effect;
|
||||||
case LAYOUT_RANGE_ATTR_UNDERLINE:
|
case LAYOUT_RANGE_ATTR_UNDERLINE:
|
||||||
return range->underline == value->u.underline;
|
return range->underline == value->u.underline;
|
||||||
case LAYOUT_RANGE_ATTR_STRIKETHROUGH:
|
case LAYOUT_RANGE_ATTR_STRIKETHROUGH:
|
||||||
|
@ -1138,7 +1153,6 @@ static inline BOOL is_same_layout_attributes(struct layout_range_header const *h
|
||||||
left->stretch == right->stretch &&
|
left->stretch == right->stretch &&
|
||||||
left->fontsize == right->fontsize &&
|
left->fontsize == right->fontsize &&
|
||||||
left->object == right->object &&
|
left->object == right->object &&
|
||||||
left->effect == right->effect &&
|
|
||||||
left->underline == right->underline &&
|
left->underline == right->underline &&
|
||||||
left->pair_kerning == right->pair_kerning &&
|
left->pair_kerning == right->pair_kerning &&
|
||||||
left->collection == right->collection &&
|
left->collection == right->collection &&
|
||||||
|
@ -1151,6 +1165,12 @@ static inline BOOL is_same_layout_attributes(struct layout_range_header const *h
|
||||||
struct layout_range_bool const *right = (struct layout_range_bool const*)hright;
|
struct layout_range_bool const *right = (struct layout_range_bool const*)hright;
|
||||||
return left->value == right->value;
|
return left->value == right->value;
|
||||||
}
|
}
|
||||||
|
case LAYOUT_RANGE_EFFECT:
|
||||||
|
{
|
||||||
|
struct layout_range_effect const *left = (struct layout_range_effect const*)hleft;
|
||||||
|
struct layout_range_effect const *right = (struct layout_range_effect const*)hright;
|
||||||
|
return left->effect == right->effect;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
FIXME("unknown range kind %d\n", hleft->kind);
|
FIXME("unknown range kind %d\n", hleft->kind);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1182,7 +1202,6 @@ static struct layout_range_header *alloc_layout_range(struct dwrite_textlayout *
|
||||||
range->stretch = layout->format.stretch;
|
range->stretch = layout->format.stretch;
|
||||||
range->fontsize = layout->format.fontsize;
|
range->fontsize = layout->format.fontsize;
|
||||||
range->object = NULL;
|
range->object = NULL;
|
||||||
range->effect = NULL;
|
|
||||||
range->underline = FALSE;
|
range->underline = FALSE;
|
||||||
range->pair_kerning = FALSE;
|
range->pair_kerning = FALSE;
|
||||||
|
|
||||||
|
@ -1211,6 +1230,17 @@ static struct layout_range_header *alloc_layout_range(struct dwrite_textlayout *
|
||||||
h = &range->h;
|
h = &range->h;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case LAYOUT_RANGE_EFFECT:
|
||||||
|
{
|
||||||
|
struct layout_range_effect *range;
|
||||||
|
|
||||||
|
range = heap_alloc(sizeof(*range));
|
||||||
|
if (!range) return NULL;
|
||||||
|
|
||||||
|
range->effect = NULL;
|
||||||
|
h = &range->h;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
FIXME("unknown range kind %d\n", kind);
|
FIXME("unknown range kind %d\n", kind);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1244,8 +1274,6 @@ static struct layout_range_header *alloc_layout_range_from(struct layout_range_h
|
||||||
/* update refcounts */
|
/* update refcounts */
|
||||||
if (range->object)
|
if (range->object)
|
||||||
IDWriteInlineObject_AddRef(range->object);
|
IDWriteInlineObject_AddRef(range->object);
|
||||||
if (range->effect)
|
|
||||||
IUnknown_AddRef(range->effect);
|
|
||||||
if (range->collection)
|
if (range->collection)
|
||||||
IDWriteFontCollection_AddRef(range->collection);
|
IDWriteFontCollection_AddRef(range->collection);
|
||||||
ret = &range->h;
|
ret = &range->h;
|
||||||
|
@ -1260,6 +1288,17 @@ static struct layout_range_header *alloc_layout_range_from(struct layout_range_h
|
||||||
ret = &strike->h;
|
ret = &strike->h;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case LAYOUT_RANGE_EFFECT:
|
||||||
|
{
|
||||||
|
struct layout_range_effect *effect = heap_alloc(sizeof(*effect));
|
||||||
|
if (!effect) return NULL;
|
||||||
|
|
||||||
|
*effect = *(struct layout_range_effect*)h;
|
||||||
|
if (effect->effect)
|
||||||
|
IUnknown_AddRef(effect->effect);
|
||||||
|
ret = &effect->h;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
FIXME("unknown range kind %d\n", h->kind);
|
FIXME("unknown range kind %d\n", h->kind);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1274,16 +1313,28 @@ static void free_layout_range(struct layout_range_header *h)
|
||||||
if (!h)
|
if (!h)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (h->kind == LAYOUT_RANGE_REGULAR) {
|
switch (h->kind)
|
||||||
|
{
|
||||||
|
case LAYOUT_RANGE_REGULAR:
|
||||||
|
{
|
||||||
struct layout_range *range = (struct layout_range*)h;
|
struct layout_range *range = (struct layout_range*)h;
|
||||||
|
|
||||||
if (range->object)
|
if (range->object)
|
||||||
IDWriteInlineObject_Release(range->object);
|
IDWriteInlineObject_Release(range->object);
|
||||||
if (range->effect)
|
|
||||||
IUnknown_Release(range->effect);
|
|
||||||
if (range->collection)
|
if (range->collection)
|
||||||
IDWriteFontCollection_Release(range->collection);
|
IDWriteFontCollection_Release(range->collection);
|
||||||
heap_free(range->fontfamily);
|
heap_free(range->fontfamily);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LAYOUT_RANGE_EFFECT:
|
||||||
|
{
|
||||||
|
struct layout_range_effect *effect = (struct layout_range_effect*)h;
|
||||||
|
if (effect->effect)
|
||||||
|
IUnknown_Release(effect->effect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
heap_free(h);
|
heap_free(h);
|
||||||
|
@ -1302,6 +1353,11 @@ static void free_layout_ranges_list(struct dwrite_textlayout *layout)
|
||||||
list_remove(&cur->entry);
|
list_remove(&cur->entry);
|
||||||
free_layout_range(cur);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct layout_range_header *find_outer_range(struct list *ranges, const DWRITE_TEXT_RANGE *range)
|
static struct layout_range_header *find_outer_range(struct list *ranges, const DWRITE_TEXT_RANGE *range)
|
||||||
|
@ -1351,6 +1407,7 @@ static inline BOOL set_layout_range_iface_attr(IUnknown **dest, IUnknown *value)
|
||||||
|
|
||||||
static BOOL set_layout_range_attrval(struct layout_range_header *h, enum layout_range_attr_kind attr, struct layout_range_attr_value *value)
|
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_effect *dest_effect = (struct layout_range_effect*)h;
|
||||||
struct layout_range_bool *dest_bool = (struct layout_range_bool*)h;
|
struct layout_range_bool *dest_bool = (struct layout_range_bool*)h;
|
||||||
struct layout_range *dest = (struct layout_range*)h;
|
struct layout_range *dest = (struct layout_range*)h;
|
||||||
|
|
||||||
|
@ -1377,7 +1434,7 @@ static BOOL set_layout_range_attrval(struct layout_range_header *h, enum layout_
|
||||||
changed = set_layout_range_iface_attr((IUnknown**)&dest->object, (IUnknown*)value->u.object);
|
changed = set_layout_range_iface_attr((IUnknown**)&dest->object, (IUnknown*)value->u.object);
|
||||||
break;
|
break;
|
||||||
case LAYOUT_RANGE_ATTR_EFFECT:
|
case LAYOUT_RANGE_ATTR_EFFECT:
|
||||||
changed = set_layout_range_iface_attr((IUnknown**)&dest->effect, (IUnknown*)value->u.effect);
|
changed = set_layout_range_iface_attr((IUnknown**)&dest_effect->effect, (IUnknown*)value->u.effect);
|
||||||
break;
|
break;
|
||||||
case LAYOUT_RANGE_ATTR_UNDERLINE:
|
case LAYOUT_RANGE_ATTR_UNDERLINE:
|
||||||
changed = dest->underline != value->u.underline;
|
changed = dest->underline != value->u.underline;
|
||||||
|
@ -1444,7 +1501,6 @@ static HRESULT set_layout_range_attr(struct dwrite_textlayout *layout, enum layo
|
||||||
case LAYOUT_RANGE_ATTR_STYLE:
|
case LAYOUT_RANGE_ATTR_STYLE:
|
||||||
case LAYOUT_RANGE_ATTR_STRETCH:
|
case LAYOUT_RANGE_ATTR_STRETCH:
|
||||||
case LAYOUT_RANGE_ATTR_FONTSIZE:
|
case LAYOUT_RANGE_ATTR_FONTSIZE:
|
||||||
case LAYOUT_RANGE_ATTR_EFFECT:
|
|
||||||
case LAYOUT_RANGE_ATTR_INLINE:
|
case LAYOUT_RANGE_ATTR_INLINE:
|
||||||
case LAYOUT_RANGE_ATTR_UNDERLINE:
|
case LAYOUT_RANGE_ATTR_UNDERLINE:
|
||||||
case LAYOUT_RANGE_ATTR_PAIR_KERNING:
|
case LAYOUT_RANGE_ATTR_PAIR_KERNING:
|
||||||
|
@ -1456,6 +1512,9 @@ static HRESULT set_layout_range_attr(struct dwrite_textlayout *layout, enum layo
|
||||||
case LAYOUT_RANGE_ATTR_STRIKETHROUGH:
|
case LAYOUT_RANGE_ATTR_STRIKETHROUGH:
|
||||||
ranges = &layout->strike_ranges;
|
ranges = &layout->strike_ranges;
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_RANGE_ATTR_EFFECT:
|
||||||
|
ranges = &layout->effects;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("unknown attr kind %d\n", attr);
|
FIXME("unknown attr kind %d\n", attr);
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
@ -2191,14 +2250,11 @@ static HRESULT WINAPI dwritetextlayout_GetDrawingEffect(IDWriteTextLayout2 *ifac
|
||||||
UINT32 position, IUnknown **effect, DWRITE_TEXT_RANGE *r)
|
UINT32 position, IUnknown **effect, DWRITE_TEXT_RANGE *r)
|
||||||
{
|
{
|
||||||
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
|
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
|
||||||
struct layout_range *range;
|
struct layout_range_effect *range;
|
||||||
|
|
||||||
TRACE("(%p)->(%u %p %p)\n", This, position, effect, r);
|
TRACE("(%p)->(%u %p %p)\n", This, position, effect, r);
|
||||||
|
|
||||||
if (position >= This->len)
|
range = (struct layout_range_effect*)get_layout_range_header_by_pos(&This->effects, position);
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
range = get_layout_range_by_pos(This, position);
|
|
||||||
*effect = range->effect;
|
*effect = range->effect;
|
||||||
if (*effect)
|
if (*effect)
|
||||||
IUnknown_AddRef(*effect);
|
IUnknown_AddRef(*effect);
|
||||||
|
@ -2297,7 +2353,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
|
||||||
DWRITE_MEASURING_MODE_NATURAL,
|
DWRITE_MEASURING_MODE_NATURAL,
|
||||||
&glyph_run,
|
&glyph_run,
|
||||||
&descr,
|
&descr,
|
||||||
run->run->effect);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. Inline objects */
|
/* 2. Inline objects */
|
||||||
|
@ -2309,7 +2365,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
|
||||||
inlineobject->object,
|
inlineobject->object,
|
||||||
inlineobject->is_sideways,
|
inlineobject->is_sideways,
|
||||||
inlineobject->is_rtl,
|
inlineobject->is_rtl,
|
||||||
run->run->effect);
|
inlineobject->effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: 3. Underlines */
|
/* TODO: 3. Underlines */
|
||||||
|
@ -2321,7 +2377,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
|
||||||
s->run->origin_x,
|
s->run->origin_x,
|
||||||
s->run->origin_y,
|
s->run->origin_y,
|
||||||
&s->s,
|
&s->s,
|
||||||
s->run->run->effect);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -3254,7 +3310,7 @@ static HRESULT layout_format_from_textformat(struct dwrite_textlayout *layout, I
|
||||||
|
|
||||||
static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, struct dwrite_textlayout *layout)
|
static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, struct dwrite_textlayout *layout)
|
||||||
{
|
{
|
||||||
struct layout_range_header *range, *strike;
|
struct layout_range_header *range, *strike, *effect;
|
||||||
DWRITE_TEXT_RANGE r = { 0, ~0u };
|
DWRITE_TEXT_RANGE r = { 0, ~0u };
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -3282,6 +3338,7 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
|
||||||
list_init(&layout->runs);
|
list_init(&layout->runs);
|
||||||
list_init(&layout->ranges);
|
list_init(&layout->ranges);
|
||||||
list_init(&layout->strike_ranges);
|
list_init(&layout->strike_ranges);
|
||||||
|
list_init(&layout->effects);
|
||||||
memset(&layout->format, 0, sizeof(layout->format));
|
memset(&layout->format, 0, sizeof(layout->format));
|
||||||
|
|
||||||
layout->gdicompatible = FALSE;
|
layout->gdicompatible = FALSE;
|
||||||
|
@ -3301,15 +3358,18 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
|
||||||
|
|
||||||
range = alloc_layout_range(layout, &r, LAYOUT_RANGE_REGULAR);
|
range = alloc_layout_range(layout, &r, LAYOUT_RANGE_REGULAR);
|
||||||
strike = alloc_layout_range(layout, &r, LAYOUT_RANGE_STRIKETHROUGH);
|
strike = alloc_layout_range(layout, &r, LAYOUT_RANGE_STRIKETHROUGH);
|
||||||
if (!range || !strike) {
|
effect = alloc_layout_range(layout, &r, LAYOUT_RANGE_EFFECT);
|
||||||
|
if (!range || !strike || !effect) {
|
||||||
free_layout_range(range);
|
free_layout_range(range);
|
||||||
free_layout_range(strike);
|
free_layout_range(strike);
|
||||||
|
free_layout_range(effect);
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_add_head(&layout->ranges, &range->entry);
|
list_add_head(&layout->ranges, &range->entry);
|
||||||
list_add_head(&layout->strike_ranges, &strike->entry);
|
list_add_head(&layout->strike_ranges, &strike->entry);
|
||||||
|
list_add_head(&layout->effects, &effect->entry);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
|
@ -215,18 +215,39 @@ static void _expect_ref(IUnknown* obj, ULONG ref, int line)
|
||||||
ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
|
ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum drawcall_kind {
|
enum drawcall_modifiers_kind {
|
||||||
DRAW_GLYPHRUN = 0,
|
DRAW_EFFECT = 0x1000
|
||||||
DRAW_UNDERLINE,
|
|
||||||
DRAW_STRIKETHROUGH,
|
|
||||||
DRAW_INLINE,
|
|
||||||
DRAW_LAST_KIND
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *get_draw_kind_name(enum drawcall_kind kind)
|
enum drawcall_kind {
|
||||||
|
DRAW_GLYPHRUN = 0,
|
||||||
|
DRAW_UNDERLINE = 1,
|
||||||
|
DRAW_STRIKETHROUGH = 2,
|
||||||
|
DRAW_INLINE = 3,
|
||||||
|
DRAW_LAST_KIND = 4,
|
||||||
|
DRAW_TOTAL_KINDS = 5,
|
||||||
|
DRAW_KINDS_MASK = 0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *get_draw_kind_name(unsigned short kind)
|
||||||
{
|
{
|
||||||
static const char *kind_names[] = { "GLYPH_RUN", "UNDERLINE", "STRIKETHROUGH", "INLINE", "END_OF_SEQ" };
|
static const char *kind_names[] = {
|
||||||
return kind > DRAW_LAST_KIND ? "unknown" : kind_names[kind];
|
"GLYPH_RUN",
|
||||||
|
"UNDERLINE",
|
||||||
|
"STRIKETHROUGH",
|
||||||
|
"INLINE",
|
||||||
|
"END_OF_SEQ",
|
||||||
|
|
||||||
|
"GLYPH_RUN|EFFECT",
|
||||||
|
"UNDERLINE|EFFECT",
|
||||||
|
"STRIKETHROUGH|EFFECT",
|
||||||
|
"INLINE|EFFECT",
|
||||||
|
"END_OF_SEQ"
|
||||||
|
};
|
||||||
|
if ((kind & DRAW_KINDS_MASK) > DRAW_LAST_KIND)
|
||||||
|
return "unknown";
|
||||||
|
return (kind & DRAW_EFFECT) ? kind_names[(kind & DRAW_KINDS_MASK) + DRAW_TOTAL_KINDS] :
|
||||||
|
kind_names[kind];
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drawcall_entry {
|
struct drawcall_entry {
|
||||||
|
@ -242,7 +263,7 @@ struct drawcall_sequence
|
||||||
};
|
};
|
||||||
|
|
||||||
struct drawtestcontext {
|
struct drawtestcontext {
|
||||||
enum drawcall_kind kind;
|
unsigned short kind;
|
||||||
BOOL todo;
|
BOOL todo;
|
||||||
int *failcount;
|
int *failcount;
|
||||||
const char *file;
|
const char *file;
|
||||||
|
@ -327,7 +348,7 @@ static void ok_sequence_(struct drawcall_sequence **seq, int sequence_index,
|
||||||
ok_(file, line) (0, "%s: call %s was expected, but got call %s instead\n",
|
ok_(file, line) (0, "%s: call %s was expected, but got call %s instead\n",
|
||||||
context, get_draw_kind_name(expected->kind), get_draw_kind_name(actual->kind));
|
context, get_draw_kind_name(expected->kind), get_draw_kind_name(actual->kind));
|
||||||
}
|
}
|
||||||
else if (expected->kind == DRAW_GLYPHRUN) {
|
else if ((expected->kind & DRAW_KINDS_MASK) == DRAW_GLYPHRUN) {
|
||||||
int cmp = lstrcmpW(expected->string, actual->string);
|
int cmp = lstrcmpW(expected->string, actual->string);
|
||||||
if (cmp != 0 && todo) {
|
if (cmp != 0 && todo) {
|
||||||
failcount++;
|
failcount++;
|
||||||
|
@ -424,7 +445,7 @@ static HRESULT WINAPI testrenderer_DrawGlyphRun(IDWriteTextRenderer *iface,
|
||||||
DWRITE_MEASURING_MODE mode,
|
DWRITE_MEASURING_MODE mode,
|
||||||
DWRITE_GLYPH_RUN const *run,
|
DWRITE_GLYPH_RUN const *run,
|
||||||
DWRITE_GLYPH_RUN_DESCRIPTION const *descr,
|
DWRITE_GLYPH_RUN_DESCRIPTION const *descr,
|
||||||
IUnknown *drawing_effect)
|
IUnknown *effect)
|
||||||
{
|
{
|
||||||
struct drawcall_entry entry;
|
struct drawcall_entry entry;
|
||||||
DWRITE_SCRIPT_ANALYSIS sa;
|
DWRITE_SCRIPT_ANALYSIS sa;
|
||||||
|
@ -452,6 +473,8 @@ static HRESULT WINAPI testrenderer_DrawGlyphRun(IDWriteTextRenderer *iface,
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.kind = DRAW_GLYPHRUN;
|
entry.kind = DRAW_GLYPHRUN;
|
||||||
|
if (effect)
|
||||||
|
entry.kind |= DRAW_EFFECT;
|
||||||
add_call(sequences, RENDERER_ID, &entry);
|
add_call(sequences, RENDERER_ID, &entry);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -461,10 +484,12 @@ static HRESULT WINAPI testrenderer_DrawUnderline(IDWriteTextRenderer *iface,
|
||||||
FLOAT baselineOriginX,
|
FLOAT baselineOriginX,
|
||||||
FLOAT baselineOriginY,
|
FLOAT baselineOriginY,
|
||||||
DWRITE_UNDERLINE const* underline,
|
DWRITE_UNDERLINE const* underline,
|
||||||
IUnknown *drawing_effect)
|
IUnknown *effect)
|
||||||
{
|
{
|
||||||
struct drawcall_entry entry;
|
struct drawcall_entry entry;
|
||||||
entry.kind = DRAW_UNDERLINE;
|
entry.kind = DRAW_UNDERLINE;
|
||||||
|
if (effect)
|
||||||
|
entry.kind |= DRAW_EFFECT;
|
||||||
add_call(sequences, RENDERER_ID, &entry);
|
add_call(sequences, RENDERER_ID, &entry);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -474,10 +499,12 @@ static HRESULT WINAPI testrenderer_DrawStrikethrough(IDWriteTextRenderer *iface,
|
||||||
FLOAT baselineOriginX,
|
FLOAT baselineOriginX,
|
||||||
FLOAT baselineOriginY,
|
FLOAT baselineOriginY,
|
||||||
DWRITE_STRIKETHROUGH const* strikethrough,
|
DWRITE_STRIKETHROUGH const* strikethrough,
|
||||||
IUnknown *drawing_effect)
|
IUnknown *effect)
|
||||||
{
|
{
|
||||||
struct drawcall_entry entry;
|
struct drawcall_entry entry;
|
||||||
entry.kind = DRAW_STRIKETHROUGH;
|
entry.kind = DRAW_STRIKETHROUGH;
|
||||||
|
if (effect)
|
||||||
|
entry.kind |= DRAW_EFFECT;
|
||||||
add_call(sequences, RENDERER_ID, &entry);
|
add_call(sequences, RENDERER_ID, &entry);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -489,10 +516,12 @@ static HRESULT WINAPI testrenderer_DrawInlineObject(IDWriteTextRenderer *iface,
|
||||||
IDWriteInlineObject *object,
|
IDWriteInlineObject *object,
|
||||||
BOOL is_sideways,
|
BOOL is_sideways,
|
||||||
BOOL is_rtl,
|
BOOL is_rtl,
|
||||||
IUnknown *drawing_effect)
|
IUnknown *effect)
|
||||||
{
|
{
|
||||||
struct drawcall_entry entry;
|
struct drawcall_entry entry;
|
||||||
entry.kind = DRAW_INLINE;
|
entry.kind = DRAW_INLINE;
|
||||||
|
if (effect)
|
||||||
|
entry.kind |= DRAW_EFFECT;
|
||||||
add_call(sequences, RENDERER_ID, &entry);
|
add_call(sequences, RENDERER_ID, &entry);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -575,6 +604,36 @@ static IDWriteInlineObjectVtbl testinlineobjvtbl = {
|
||||||
static IDWriteInlineObject testinlineobj = { &testinlineobjvtbl };
|
static IDWriteInlineObject testinlineobj = { &testinlineobjvtbl };
|
||||||
static IDWriteInlineObject testinlineobj2 = { &testinlineobjvtbl };
|
static IDWriteInlineObject testinlineobj2 = { &testinlineobjvtbl };
|
||||||
|
|
||||||
|
static HRESULT WINAPI testeffect_QI(IUnknown *iface, REFIID riid, void **obj)
|
||||||
|
{
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown)) {
|
||||||
|
*obj = iface;
|
||||||
|
IUnknown_AddRef(iface);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*obj = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI testeffect_AddRef(IUnknown *iface)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI testeffect_Release(IUnknown *iface)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IUnknownVtbl testeffectvtbl = {
|
||||||
|
testeffect_QI,
|
||||||
|
testeffect_AddRef,
|
||||||
|
testeffect_Release
|
||||||
|
};
|
||||||
|
|
||||||
|
static IUnknown testeffect = { &testeffectvtbl };
|
||||||
|
|
||||||
static void test_CreateTextLayout(void)
|
static void test_CreateTextLayout(void)
|
||||||
{
|
{
|
||||||
static const WCHAR strW[] = {'s','t','r','i','n','g',0};
|
static const WCHAR strW[] = {'s','t','r','i','n','g',0};
|
||||||
|
@ -1156,7 +1215,7 @@ static void test_SetInlineObject(void)
|
||||||
static const struct drawcall_entry draw_seq[] = {
|
static const struct drawcall_entry draw_seq[] = {
|
||||||
{ DRAW_GLYPHRUN, {'s',0} },
|
{ DRAW_GLYPHRUN, {'s',0} },
|
||||||
{ DRAW_GLYPHRUN, {'r','i',0} },
|
{ DRAW_GLYPHRUN, {'r','i',0} },
|
||||||
{ DRAW_GLYPHRUN, {'n',0} },
|
{ DRAW_GLYPHRUN|DRAW_EFFECT, {'n',0} },
|
||||||
{ DRAW_GLYPHRUN, {'g',0} },
|
{ DRAW_GLYPHRUN, {'g',0} },
|
||||||
{ DRAW_INLINE },
|
{ DRAW_INLINE },
|
||||||
{ DRAW_UNDERLINE },
|
{ DRAW_UNDERLINE },
|
||||||
|
@ -2438,6 +2497,153 @@ static void test_SetFlowDirection(void)
|
||||||
IDWriteFactory_Release(factory);
|
IDWriteFactory_Release(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct drawcall_entry draweffect_seq[] = {
|
||||||
|
{ DRAW_GLYPHRUN|DRAW_EFFECT, {'a','e',0x0300,0} },
|
||||||
|
{ DRAW_GLYPHRUN, {'d',0} },
|
||||||
|
{ DRAW_LAST_KIND }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct drawcall_entry draweffect2_seq[] = {
|
||||||
|
{ DRAW_GLYPHRUN|DRAW_EFFECT, {'a','e',0} },
|
||||||
|
{ DRAW_GLYPHRUN, {'c','d',0} },
|
||||||
|
{ DRAW_LAST_KIND }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct drawcall_entry draweffect3_seq[] = {
|
||||||
|
{ DRAW_INLINE|DRAW_EFFECT },
|
||||||
|
{ DRAW_LAST_KIND }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct drawcall_entry draweffect4_seq[] = {
|
||||||
|
{ DRAW_INLINE },
|
||||||
|
{ DRAW_LAST_KIND }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_SetDrawingEffect(void)
|
||||||
|
{
|
||||||
|
static const WCHAR strW[] = {'a','e',0x0300,'d',0}; /* accent grave */
|
||||||
|
static const WCHAR str2W[] = {'a','e','c','d',0};
|
||||||
|
IDWriteInlineObject *sign;
|
||||||
|
IDWriteTextFormat *format;
|
||||||
|
IDWriteTextLayout *layout;
|
||||||
|
IDWriteFactory *factory;
|
||||||
|
DWRITE_TEXT_RANGE r;
|
||||||
|
IUnknown *unk;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
factory = create_factory();
|
||||||
|
|
||||||
|
hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
|
||||||
|
DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* string with combining mark */
|
||||||
|
hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 500.0, 1000.0, &layout);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* set effect past the end of text */
|
||||||
|
r.startPosition = 100;
|
||||||
|
r.length = 10;
|
||||||
|
hr = IDWriteTextLayout_SetDrawingEffect(layout, &testeffect, r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
r.startPosition = r.length = 0;
|
||||||
|
hr = IDWriteTextLayout_GetDrawingEffect(layout, 101, &unk, &r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
ok(r.startPosition == 100 && r.length == 10, "got %u, %u\n", r.startPosition, r.length);
|
||||||
|
|
||||||
|
r.startPosition = r.length = 0;
|
||||||
|
unk = (void*)0xdeadbeef;
|
||||||
|
hr = IDWriteTextLayout_GetDrawingEffect(layout, 1000, &unk, &r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
ok(r.startPosition == 110 && r.length == ~0u-110, "got %u, %u\n", r.startPosition, r.length);
|
||||||
|
ok(unk == NULL, "got %p\n", unk);
|
||||||
|
|
||||||
|
/* effect is applied to clusters, not individual text positions */
|
||||||
|
r.startPosition = 0;
|
||||||
|
r.length = 2;
|
||||||
|
hr = IDWriteTextLayout_SetDrawingEffect(layout, &testeffect, r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
flush_sequence(sequences, RENDERER_ID);
|
||||||
|
hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
ok_sequence(sequences, RENDERER_ID, draweffect_seq, "effect draw test", TRUE);
|
||||||
|
IDWriteTextLayout_Release(layout);
|
||||||
|
|
||||||
|
/* simple string */
|
||||||
|
hr = IDWriteFactory_CreateTextLayout(factory, str2W, 4, format, 500.0, 1000.0, &layout);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
r.startPosition = 0;
|
||||||
|
r.length = 2;
|
||||||
|
hr = IDWriteTextLayout_SetDrawingEffect(layout, &testeffect, r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
flush_sequence(sequences, RENDERER_ID);
|
||||||
|
hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
ok_sequence(sequences, RENDERER_ID, draweffect2_seq, "effect draw test 2", TRUE);
|
||||||
|
IDWriteTextLayout_Release(layout);
|
||||||
|
|
||||||
|
/* Inline object - effect set for same range */
|
||||||
|
hr = IDWriteFactory_CreateEllipsisTrimmingSign(factory, format, &sign);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IDWriteFactory_CreateTextLayout(factory, str2W, 4, format, 500.0, 1000.0, &layout);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
r.startPosition = 0;
|
||||||
|
r.length = 4;
|
||||||
|
hr = IDWriteTextLayout_SetInlineObject(layout, sign, r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IDWriteTextLayout_SetDrawingEffect(layout, &testeffect, r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
flush_sequence(sequences, RENDERER_ID);
|
||||||
|
hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
ok_sequence(sequences, RENDERER_ID, draweffect3_seq, "effect draw test 3", FALSE);
|
||||||
|
|
||||||
|
/* now set effect somewhere inside a range replaced by inline object */
|
||||||
|
hr = IDWriteTextLayout_SetDrawingEffect(layout, NULL, r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
r.startPosition = 1;
|
||||||
|
r.length = 1;
|
||||||
|
hr = IDWriteTextLayout_SetDrawingEffect(layout, &testeffect, r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* no effect is reported in this case */
|
||||||
|
flush_sequence(sequences, RENDERER_ID);
|
||||||
|
hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
ok_sequence(sequences, RENDERER_ID, draweffect4_seq, "effect draw test 4", FALSE);
|
||||||
|
|
||||||
|
r.startPosition = 0;
|
||||||
|
r.length = 4;
|
||||||
|
hr = IDWriteTextLayout_SetDrawingEffect(layout, NULL, r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
r.startPosition = 0;
|
||||||
|
r.length = 1;
|
||||||
|
hr = IDWriteTextLayout_SetDrawingEffect(layout, &testeffect, r);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* first range position is all that matters for inline ranges */
|
||||||
|
flush_sequence(sequences, RENDERER_ID);
|
||||||
|
hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
ok_sequence(sequences, RENDERER_ID, draweffect3_seq, "effect draw test 5", FALSE);
|
||||||
|
|
||||||
|
IDWriteTextLayout_Release(layout);
|
||||||
|
|
||||||
|
IDWriteInlineObject_Release(sign);
|
||||||
|
IDWriteTextFormat_Release(format);
|
||||||
|
IDWriteFactory_Release(factory);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(layout)
|
START_TEST(layout)
|
||||||
{
|
{
|
||||||
static const WCHAR ctrlstrW[] = {0x202a,0};
|
static const WCHAR ctrlstrW[] = {0x202a,0};
|
||||||
|
@ -2476,6 +2682,7 @@ START_TEST(layout)
|
||||||
test_SetStrikethrough();
|
test_SetStrikethrough();
|
||||||
test_GetMetrics();
|
test_GetMetrics();
|
||||||
test_SetFlowDirection();
|
test_SetFlowDirection();
|
||||||
|
test_SetDrawingEffect();
|
||||||
|
|
||||||
IDWriteFactory_Release(factory);
|
IDWriteFactory_Release(factory);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue