dwrite: Store locale name for each text range.

This commit is contained in:
Nikolay Sivov 2015-01-01 21:50:59 +03:00 committed by Alexandre Julliard
parent 3c28c0a2eb
commit aecec3847a
2 changed files with 128 additions and 13 deletions

View File

@ -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,

View File

@ -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);
}