diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index b4833c24dbc..2665664e37c 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -775,6 +775,19 @@ static struct layout_range *get_layout_range_by_pos(struct dwrite_textlayout *la 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 *dest, enum layout_range_attr_kind attr, struct layout_range_attr_value *value) { BOOL changed = FALSE; @@ -797,20 +810,10 @@ static BOOL set_layout_range_attrval(struct layout_range *dest, enum layout_rang dest->fontsize = value->u.fontsize; break; case LAYOUT_RANGE_ATTR_INLINE: - changed = dest->object != value->u.object; - if (changed && dest->object) - IDWriteInlineObject_Release(dest->object); - dest->object = value->u.object; - if (dest->object) - IDWriteInlineObject_AddRef(dest->object); + changed = set_layout_range_iface_attr((IUnknown**)&dest->object, (IUnknown*)value->u.object); break; case LAYOUT_RANGE_ATTR_EFFECT: - changed = dest->effect != value->u.effect; - if (changed && dest->effect) - IUnknown_Release(dest->effect); - dest->effect = value->u.effect; - if (dest->effect) - IUnknown_AddRef(dest->effect); + changed = set_layout_range_iface_attr((IUnknown**)&dest->effect, (IUnknown*)value->u.effect); break; case LAYOUT_RANGE_ATTR_UNDERLINE: changed = dest->underline != value->u.underline; @@ -821,12 +824,7 @@ static BOOL set_layout_range_attrval(struct layout_range *dest, enum layout_rang dest->strikethrough = value->u.strikethrough; break; case LAYOUT_RANGE_ATTR_FONTCOLL: - changed = dest->collection != value->u.collection; - if (changed && dest->collection) - IDWriteFontCollection_Release(dest->collection); - dest->collection = value->u.collection; - if (dest->collection) - IDWriteFontCollection_AddRef(dest->collection); + changed = set_layout_range_iface_attr((IUnknown**)&dest->collection, (IUnknown*)value->u.collection); break; case LAYOUT_RANGE_ATTR_LOCALE: changed = strcmpW(dest->locale, value->u.locale) != 0; diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 98358a407a8..89c96e4ee55 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -691,6 +691,9 @@ static void test_SetInlineObject(void) hr = IDWriteFactory_CreateEllipsisTrimmingSign(factory, format, &inlineobj2); ok(hr == S_OK, "got 0x%08x\n", hr); + EXPECT_REF(inlineobj, 1); + EXPECT_REF(inlineobj2, 1); + inlinetest = (void*)0x1; hr = IDWriteTextLayout_GetInlineObject(layout, 0, &inlinetest, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); @@ -701,6 +704,8 @@ static void test_SetInlineObject(void) hr = IDWriteTextLayout_SetInlineObject(layout, inlineobj, range); ok(hr == S_OK, "got 0x%08x\n", hr); + EXPECT_REF(inlineobj, 2); + inlinetest = (void*)0x1; hr = IDWriteTextLayout_GetInlineObject(layout, 2, &inlinetest, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); @@ -714,6 +719,8 @@ static void test_SetInlineObject(void) ok(r2.startPosition == 0 && r2.length == 2, "got %d, %d\n", r2.startPosition, r2.length); IDWriteInlineObject_Release(inlinetest); + EXPECT_REF(inlineobj, 2); + /* get from somewhere inside a range */ inlinetest = NULL; r2.startPosition = r2.length = 100; @@ -723,6 +730,8 @@ static void test_SetInlineObject(void) ok(r2.startPosition == 0 && r2.length == 2, "got %d, %d\n", r2.startPosition, r2.length); IDWriteInlineObject_Release(inlinetest); + EXPECT_REF(inlineobj, 2); + range.startPosition = 1; range.length = 1; hr = IDWriteTextLayout_SetInlineObject(layout, inlineobj2, range); @@ -736,6 +745,9 @@ static void test_SetInlineObject(void) ok(r2.startPosition == 1 && r2.length == 1, "got %d, %d\n", r2.startPosition, r2.length); IDWriteInlineObject_Release(inlinetest); + EXPECT_REF(inlineobj, 2); + EXPECT_REF(inlineobj2, 2); + inlinetest = NULL; r2.startPosition = r2.length = 100; hr = IDWriteTextLayout_GetInlineObject(layout, 0, &inlinetest, &r2); @@ -744,6 +756,8 @@ static void test_SetInlineObject(void) ok(r2.startPosition == 0 && r2.length == 1, "got %d, %d\n", r2.startPosition, r2.length); IDWriteInlineObject_Release(inlinetest); + EXPECT_REF(inlineobj, 2); + range.startPosition = 1; range.length = 1; hr = IDWriteTextLayout_SetInlineObject(layout, inlineobj, range); @@ -756,11 +770,15 @@ static void test_SetInlineObject(void) ok(r2.startPosition == 0 && r2.length == 2, "got %d, %d\n", r2.startPosition, r2.length); IDWriteInlineObject_Release(inlinetest); + EXPECT_REF(inlineobj, 2); + range.startPosition = 1; range.length = 2; hr = IDWriteTextLayout_SetInlineObject(layout, inlineobj, range); ok(hr == S_OK, "got 0x%08x\n", hr); + EXPECT_REF(inlineobj, 2); + r2.startPosition = r2.length = 100; hr = IDWriteTextLayout_GetInlineObject(layout, 0, &inlinetest, &r2); ok(hr == S_OK, "got 0x%08x\n", hr); @@ -768,7 +786,15 @@ static void test_SetInlineObject(void) ok(r2.startPosition == 0 && r2.length == 3, "got %d, %d\n", r2.startPosition, r2.length); IDWriteInlineObject_Release(inlinetest); + EXPECT_REF(inlineobj, 2); + EXPECT_REF(inlineobj2, 1); + IDWriteTextLayout_Release(layout); + + EXPECT_REF(inlineobj, 1); + + IDWriteInlineObject_Release(inlineobj); + IDWriteInlineObject_Release(inlineobj2); IDWriteTextFormat_Release(format); }