Nikolay Sivov : dwrite: Store locale name for each text range.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Jan 5 15:01:27 CST 2015
Module: wine
Branch: master
Commit: aecec3847a75cbb53df7b8f7a2225967e686a45b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=aecec3847a75cbb53df7b8f7a2225967e686a45b
Author: Nikolay Sivov <nsivov at 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);
}
More information about the wine-cvs
mailing list