Module: wine Branch: master Commit: aecec3847a75cbb53df7b8f7a2225967e686a45b URL: http://source.winehq.org/git/wine.git/?a=commit;h=aecec3847a75cbb53df7b8f7a2...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Thu Jan 1 21:50:59 2015 +0300
dwrite: Store locale name for each text range.
---
dlls/dwrite/layout.c | 74 ++++++++++++++++++++++++++++++++++++++-------- dlls/dwrite/tests/layout.c | 67 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 13 deletions(-)
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index ba35713..0ddb0b4 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -67,7 +67,8 @@ enum layout_range_attr_kind { LAYOUT_RANGE_ATTR_INLINE, LAYOUT_RANGE_ATTR_UNDERLINE, LAYOUT_RANGE_ATTR_STRIKETHROUGH, - LAYOUT_RANGE_ATTR_FONTCOLL + LAYOUT_RANGE_ATTR_FONTCOLL, + LAYOUT_RANGE_ATTR_LOCALE };
struct layout_range_attr_value { @@ -82,6 +83,7 @@ struct layout_range_attr_value { BOOL underline; BOOL strikethrough; IDWriteFontCollection *collection; + const WCHAR *locale; } u; };
@@ -97,6 +99,7 @@ struct layout_range { BOOL underline; BOOL strikethrough; IDWriteFontCollection *collection; + WCHAR locale[LOCALE_NAME_MAX_LENGTH]; };
struct layout_run { @@ -402,6 +405,8 @@ static BOOL is_same_layout_attrvalue(struct layout_range const *range, enum layo return range->strikethrough == value->u.strikethrough; case LAYOUT_RANGE_ATTR_FONTCOLL: return range->collection == value->u.collection; + case LAYOUT_RANGE_ATTR_LOCALE: + return strcmpW(range->locale, value->u.locale) == 0; default: ; } @@ -447,6 +452,7 @@ static struct layout_range *alloc_layout_range(struct dwrite_textlayout *layout, range->collection = layout->format.collection; if (range->collection) IDWriteFontCollection_AddRef(range->collection); + strcpyW(range->locale, layout->format.locale);
return range; } @@ -579,6 +585,11 @@ static BOOL set_layout_range_attrval(struct layout_range *dest, enum layout_rang if (dest->collection) IDWriteFontCollection_AddRef(dest->collection); break; + case LAYOUT_RANGE_ATTR_LOCALE: + changed = strcmpW(dest->locale, value->u.locale) != 0; + if (changed) + strcpyW(dest->locale, value->u.locale); + break; default: ; } @@ -1127,17 +1138,17 @@ static HRESULT WINAPI dwritetextlayout_SetDrawingEffect(IDWriteTextLayout2 *ifac return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_EFFECT, &value); }
-static HRESULT WINAPI dwritetextlayout_SetInlineObject(IDWriteTextLayout2 *iface, IDWriteInlineObject *object, DWRITE_TEXT_RANGE r) +static HRESULT WINAPI dwritetextlayout_SetInlineObject(IDWriteTextLayout2 *iface, IDWriteInlineObject *object, DWRITE_TEXT_RANGE range) { struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface); struct layout_range_attr_value attr;
- TRACE("(%p)->(%p %s)\n", This, object, debugstr_range(&r)); + TRACE("(%p)->(%p %s)\n", This, object, debugstr_range(&range));
- if (!validate_text_range(This, &r)) + if (!validate_text_range(This, &range)) return S_OK;
- attr.range = r; + attr.range = range; attr.u.object = object;
return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_INLINE, &attr); @@ -1153,8 +1164,20 @@ static HRESULT WINAPI dwritetextlayout_SetTypography(IDWriteTextLayout2 *iface, static HRESULT WINAPI dwritetextlayout_SetLocaleName(IDWriteTextLayout2 *iface, WCHAR const* locale, DWRITE_TEXT_RANGE range) { struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface); - FIXME("(%p)->(%s %s): stub\n", This, debugstr_w(locale), debugstr_range(&range)); - return E_NOTIMPL; + struct layout_range_attr_value attr; + + TRACE("(%p)->(%s %s)\n", This, debugstr_w(locale), debugstr_range(&range)); + + if (!locale || strlenW(locale) > LOCALE_NAME_MAX_LENGTH-1) + return E_INVALIDARG; + + if (!validate_text_range(This, &range)) + return S_OK; + + attr.range = range; + attr.u.locale = locale; + + return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_LOCALE, &attr); }
static FLOAT WINAPI dwritetextlayout_GetMaxWidth(IDWriteTextLayout2 *iface) @@ -1349,19 +1372,44 @@ static HRESULT WINAPI dwritetextlayout_GetTypography(IDWriteTextLayout2 *iface, }
static HRESULT WINAPI dwritetextlayout_layout_GetLocaleNameLength(IDWriteTextLayout2 *iface, - UINT32 position, UINT32* length, DWRITE_TEXT_RANGE *range) + UINT32 position, UINT32* length, DWRITE_TEXT_RANGE *r) { struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface); - FIXME("(%p)->(%u %p %p): stub\n", This, position, length, range); - return E_NOTIMPL; + struct layout_range *range; + + TRACE("(%p)->(%u %p %p)\n", This, position, length, r); + + range = get_layout_range_by_pos(This, position); + if (!range) { + *length = 0; + return S_OK; + } + + *length = strlenW(range->locale); + return return_range(range, r); }
static HRESULT WINAPI dwritetextlayout_layout_GetLocaleName(IDWriteTextLayout2 *iface, - UINT32 position, WCHAR* name, UINT32 name_size, DWRITE_TEXT_RANGE *range) + UINT32 position, WCHAR* locale, UINT32 length, DWRITE_TEXT_RANGE *r) { struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface); - FIXME("(%p)->(%u %p %u %p): stub\n", This, position, name, name_size, range); - return E_NOTIMPL; + struct layout_range *range; + + TRACE("(%p)->(%u %p %u %p)\n", This, position, locale, length, r); + + if (length == 0) + return E_INVALIDARG; + + locale[0] = 0; + range = get_layout_range_by_pos(This, position); + if (!range) + return E_INVALIDARG; + + if (length < strlenW(range->locale) + 1) + return E_NOT_SUFFICIENT_BUFFER; + + strcpyW(locale, range->locale); + return return_range(range, r); }
static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface, diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index de3e544..b90d7af 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -924,6 +924,72 @@ todo_wine { IDWriteTextFormat_Release(format); }
+static void test_SetLocaleName(void) +{ + static const WCHAR strW[] = {'a','b','c','d',0}; + WCHAR buffW[LOCALE_NAME_MAX_LENGTH+5]; + IDWriteTextFormat *format; + IDWriteTextLayout *layout; + DWRITE_TEXT_RANGE range; + HRESULT hr; + + 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); + + range.startPosition = 0; + range.length = 1; + hr = IDWriteTextLayout_SetLocaleName(layout, enusW, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteTextLayout_SetLocaleName(layout, NULL, range); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + /* invalid locale name is allowed */ + hr = IDWriteTextLayout_SetLocaleName(layout, strW, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteTextLayout_GetLocaleName(layout, 0, NULL, 0, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + +if (0) /* crashes on native */ + hr = IDWriteTextLayout_GetLocaleName(layout, 0, NULL, 1, NULL); + + buffW[0] = 0; + hr = IDWriteTextLayout_GetLocaleName(layout, 0, buffW, sizeof(buffW)/sizeof(WCHAR), NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(buffW, strW), "got %s\n", wine_dbgstr_w(buffW)); + + /* get with a shorter buffer */ + buffW[0] = 0xa; + hr = IDWriteTextLayout_GetLocaleName(layout, 0, buffW, 1, NULL); + ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr); + ok(buffW[0] == 0, "got %x\n", buffW[0]); + + /* name is too long */ + lstrcpyW(buffW, strW); + while (lstrlenW(buffW) < LOCALE_NAME_MAX_LENGTH) { + lstrcatW(buffW, strW); + } + lstrcatW(buffW, strW); + + range.startPosition = 0; + range.length = 1; + hr = IDWriteTextLayout_SetLocaleName(layout, buffW, range); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + buffW[0] = 0; + hr = IDWriteTextLayout_GetLocaleName(layout, 0, buffW, sizeof(buffW)/sizeof(WCHAR), NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(buffW, strW), "got %s\n", wine_dbgstr_w(buffW)); + + IDWriteTextLayout_Release(layout); + IDWriteTextFormat_Release(format); +} + START_TEST(layout) { HRESULT hr; @@ -949,6 +1015,7 @@ START_TEST(layout) test_draw_sequence(); test_typography(); test_GetClusterMetrics(); + test_SetLocaleName();
IDWriteFactory_Release(factory); }