[PATCH 2/7] dwrite: Store per-range typography property
Nikolay Sivov
nsivov at codeweavers.com
Fri Dec 25 06:57:57 CST 2015
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/dwrite/layout.c | 101 +++++++++++++++++++++++++++++++--------------
dlls/dwrite/tests/layout.c | 57 +++++++++++++++++++++++++
2 files changed, 126 insertions(+), 32 deletions(-)
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index 22c36a3..66998b6 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -74,7 +74,8 @@ enum layout_range_attr_kind {
LAYOUT_RANGE_ATTR_FONTCOLL,
LAYOUT_RANGE_ATTR_LOCALE,
LAYOUT_RANGE_ATTR_FONTFAMILY,
- LAYOUT_RANGE_ATTR_SPACING
+ LAYOUT_RANGE_ATTR_SPACING,
+ LAYOUT_RANGE_ATTR_TYPOGRAPHY
};
struct layout_range_attr_value {
@@ -93,6 +94,7 @@ struct layout_range_attr_value {
const WCHAR *locale;
const WCHAR *fontfamily;
FLOAT spacing[3]; /* in arguments order - leading, trailing, advance */
+ IDWriteTypography *typography;
} u;
};
@@ -100,7 +102,8 @@ enum layout_range_kind {
LAYOUT_RANGE_REGULAR,
LAYOUT_RANGE_STRIKETHROUGH,
LAYOUT_RANGE_EFFECT,
- LAYOUT_RANGE_SPACING
+ LAYOUT_RANGE_SPACING,
+ LAYOUT_RANGE_TYPOGRAPHY
};
struct layout_range_header {
@@ -128,9 +131,9 @@ struct layout_range_bool {
BOOL value;
};
-struct layout_range_effect {
+struct layout_range_iface {
struct layout_range_header h;
- IUnknown *effect;
+ IUnknown *iface;
};
struct layout_range_spacing {
@@ -229,6 +232,7 @@ struct dwrite_textlayout {
UINT32 len;
struct dwrite_textformat_data format;
struct list strike_ranges;
+ struct list typographies;
struct list effects;
struct list spacing;
struct list ranges;
@@ -961,7 +965,7 @@ static struct layout_range_header *get_layout_range_header_by_pos(struct list *r
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;
+ return ((struct layout_range_iface*)h)->iface;
}
static inline BOOL layout_is_erun_rtl(const struct layout_effective_run *erun)
@@ -1557,7 +1561,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)
{
struct layout_range_spacing const *range_spacing = (struct layout_range_spacing*)h;
- struct layout_range_effect const *range_effect = (struct layout_range_effect*)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;
@@ -1573,7 +1577,7 @@ static BOOL is_same_layout_attrvalue(struct layout_range_header const *h, enum l
case LAYOUT_RANGE_ATTR_INLINE:
return range->object == value->u.object;
case LAYOUT_RANGE_ATTR_EFFECT:
- return range_effect->effect == value->u.effect;
+ return range_iface->iface == value->u.effect;
case LAYOUT_RANGE_ATTR_UNDERLINE:
return range->underline == value->u.underline;
case LAYOUT_RANGE_ATTR_STRIKETHROUGH:
@@ -1590,6 +1594,8 @@ static BOOL is_same_layout_attrvalue(struct layout_range_header const *h, enum l
return range_spacing->leading == value->u.spacing[0] &&
range_spacing->trailing == value->u.spacing[1] &&
range_spacing->min_advance == value->u.spacing[2];
+ case LAYOUT_RANGE_ATTR_TYPOGRAPHY:
+ return range_iface->iface == (IUnknown*)value->u.typography;
default:
;
}
@@ -1623,10 +1629,11 @@ static inline BOOL is_same_layout_attributes(struct layout_range_header const *h
return left->value == right->value;
}
case LAYOUT_RANGE_EFFECT:
+ case LAYOUT_RANGE_TYPOGRAPHY:
{
- 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;
+ 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:
{
@@ -1696,13 +1703,14 @@ static struct layout_range_header *alloc_layout_range(struct dwrite_textlayout *
break;
}
case LAYOUT_RANGE_EFFECT:
+ case LAYOUT_RANGE_TYPOGRAPHY:
{
- struct layout_range_effect *range;
+ struct layout_range_iface *range;
range = heap_alloc(sizeof(*range));
if (!range) return NULL;
- range->effect = NULL;
+ range->iface = NULL;
h = &range->h;
break;
}
@@ -1767,13 +1775,14 @@ static struct layout_range_header *alloc_layout_range_from(struct layout_range_h
break;
}
case LAYOUT_RANGE_EFFECT:
+ case LAYOUT_RANGE_TYPOGRAPHY:
{
- struct layout_range_effect *effect = heap_alloc(sizeof(*effect));
+ struct layout_range_iface *effect = heap_alloc(sizeof(*effect));
if (!effect) return NULL;
- *effect = *(struct layout_range_effect*)h;
- if (effect->effect)
- IUnknown_AddRef(effect->effect);
+ *effect = *(struct layout_range_iface*)h;
+ if (effect->iface)
+ IUnknown_AddRef(effect->iface);
ret = &effect->h;
break;
}
@@ -1814,10 +1823,11 @@ static void free_layout_range(struct layout_range_header *h)
break;
}
case LAYOUT_RANGE_EFFECT:
+ case LAYOUT_RANGE_TYPOGRAPHY:
{
- struct layout_range_effect *effect = (struct layout_range_effect*)h;
- if (effect->effect)
- IUnknown_Release(effect->effect);
+ struct layout_range_iface *range = (struct layout_range_iface*)h;
+ if (range->iface)
+ IUnknown_Release(range->iface);
break;
}
default:
@@ -1850,6 +1860,11 @@ static void free_layout_ranges_list(struct dwrite_textlayout *layout)
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)
@@ -1900,7 +1915,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)
{
struct layout_range_spacing *dest_spacing = (struct layout_range_spacing*)h;
- struct layout_range_effect *dest_effect = (struct layout_range_effect*)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;
@@ -1927,7 +1942,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);
break;
case LAYOUT_RANGE_ATTR_EFFECT:
- changed = set_layout_range_iface_attr((IUnknown**)&dest_effect->effect, (IUnknown*)value->u.effect);
+ changed = set_layout_range_iface_attr((IUnknown**)&dest_iface->iface, (IUnknown*)value->u.effect);
break;
case LAYOUT_RANGE_ATTR_UNDERLINE:
changed = dest->underline != value->u.underline;
@@ -1964,6 +1979,9 @@ static BOOL set_layout_range_attrval(struct layout_range_header *h, enum layout_
dest_spacing->trailing = value->u.spacing[1];
dest_spacing->min_advance = value->u.spacing[2];
break;
+ case LAYOUT_RANGE_ATTR_TYPOGRAPHY:
+ changed = set_layout_range_iface_attr((IUnknown**)&dest_iface->iface, (IUnknown*)value->u.typography);
+ break;
default:
;
}
@@ -2019,6 +2037,9 @@ static HRESULT set_layout_range_attr(struct dwrite_textlayout *layout, enum layo
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;
@@ -2576,8 +2597,13 @@ static HRESULT WINAPI dwritetextlayout_SetInlineObject(IDWriteTextLayout2 *iface
static HRESULT WINAPI dwritetextlayout_SetTypography(IDWriteTextLayout2 *iface, IDWriteTypography* typography, DWRITE_TEXT_RANGE range)
{
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
- FIXME("(%p)->(%p %s): stub\n", This, typography, debugstr_range(&range));
- return E_NOTIMPL;
+ 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(IDWriteTextLayout2 *iface, WCHAR const* locale, DWRITE_TEXT_RANGE range)
@@ -2735,12 +2761,12 @@ static HRESULT WINAPI dwritetextlayout_GetDrawingEffect(IDWriteTextLayout2 *ifac
UINT32 position, IUnknown **effect, DWRITE_TEXT_RANGE *r)
{
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
- struct layout_range_effect *range;
+ struct layout_range_iface *range;
TRACE("(%p)->(%u %p %p)\n", This, position, effect, r);
- range = (struct layout_range_effect*)get_layout_range_header_by_pos(&This->effects, position);
- *effect = range->effect;
+ range = (struct layout_range_iface*)get_layout_range_header_by_pos(&This->effects, position);
+ *effect = range->iface;
if (*effect)
IUnknown_AddRef(*effect);
@@ -2767,11 +2793,19 @@ static HRESULT WINAPI dwritetextlayout_GetInlineObject(IDWriteTextLayout2 *iface
}
static HRESULT WINAPI dwritetextlayout_GetTypography(IDWriteTextLayout2 *iface,
- UINT32 position, IDWriteTypography** typography, DWRITE_TEXT_RANGE *range)
+ UINT32 position, IDWriteTypography** typography, DWRITE_TEXT_RANGE *r)
{
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
- FIXME("(%p)->(%u %p %p): stub\n", This, position, typography, range);
- return E_NOTIMPL;
+ 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(IDWriteTextLayout2 *iface,
@@ -3921,8 +3955,8 @@ 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)
{
- struct layout_range_header *range, *strike, *effect, *spacing;
- DWRITE_TEXT_RANGE r = { 0, ~0u };
+ struct layout_range_header *range, *strike, *effect, *spacing, *typography;
+ static const DWRITE_TEXT_RANGE r = { 0, ~0u };
HRESULT hr;
layout->IDWriteTextLayout2_iface.lpVtbl = &dwritetextlayoutvtbl;
@@ -3948,6 +3982,7 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
list_init(&layout->strike_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 = maxwidth;
@@ -3971,7 +4006,8 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
strike = alloc_layout_range(layout, &r, LAYOUT_RANGE_STRIKETHROUGH);
effect = alloc_layout_range(layout, &r, LAYOUT_RANGE_EFFECT);
spacing = alloc_layout_range(layout, &r, LAYOUT_RANGE_SPACING);
- if (!range || !strike || !effect || !spacing) {
+ typography = alloc_layout_range(layout, &r, LAYOUT_RANGE_TYPOGRAPHY);
+ if (!range || !strike || !effect || !spacing || !typography) {
free_layout_range(range);
free_layout_range(strike);
free_layout_range(effect);
@@ -3984,6 +4020,7 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
list_add_head(&layout->strike_ranges, &strike->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:
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index 5e38a07..186e257 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -4074,6 +4074,62 @@ if (0) /* crashes on native */
IDWriteFactory2_Release(factory2);
}
+static void test_SetTypography(void)
+{
+ static const WCHAR strW[] = {'a','f','i','b',0};
+ IDWriteTypography *typography, *typography2;
+ IDWriteTextFormat *format;
+ IDWriteTextLayout *layout;
+ DWRITE_TEXT_RANGE range;
+ IDWriteFactory *factory;
+ 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);
+
+ hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ IDWriteTextFormat_Release(format);
+
+ hr = IDWriteFactory_CreateTypography(factory, &typography);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ EXPECT_REF(typography, 1);
+ range.startPosition = 0;
+ range.length = 2;
+ hr = IDWriteTextLayout_SetTypography(layout, typography, range);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ EXPECT_REF(typography, 2);
+
+ hr = IDWriteTextLayout_GetTypography(layout, 0, &typography2, NULL);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(typography2 == typography, "got %p, expected %p\n", typography2, typography);
+ IDWriteTypography_Release(typography2);
+ IDWriteTypography_Release(typography);
+
+ hr = IDWriteFactory_CreateTypography(factory, &typography2);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ range.startPosition = 0;
+ range.length = 1;
+ hr = IDWriteTextLayout_SetTypography(layout, typography2, range);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ EXPECT_REF(typography2, 2);
+ IDWriteTypography_Release(typography2);
+
+ hr = IDWriteTextLayout_GetTypography(layout, 0, &typography, &range);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(range.length == 1, "got %u\n", range.length);
+
+ IDWriteTypography_Release(typography);
+
+ IDWriteTextLayout_Release(layout);
+ IDWriteFactory_Release(factory);
+}
+
START_TEST(layout)
{
static const WCHAR ctrlstrW[] = {0x202a,0};
@@ -4121,6 +4177,7 @@ START_TEST(layout)
test_SetWordWrapping();
test_MapCharacters();
test_FontFallbackBuilder();
+ test_SetTypography();
IDWriteFactory_Release(factory);
}
--
2.6.4
More information about the wine-patches
mailing list