dwrite: Store locale name for each text range.
This commit is contained in:
parent
3c28c0a2eb
commit
aecec3847a
@ -67,7 +67,8 @@ enum layout_range_attr_kind {
|
|||||||
LAYOUT_RANGE_ATTR_INLINE,
|
LAYOUT_RANGE_ATTR_INLINE,
|
||||||
LAYOUT_RANGE_ATTR_UNDERLINE,
|
LAYOUT_RANGE_ATTR_UNDERLINE,
|
||||||
LAYOUT_RANGE_ATTR_STRIKETHROUGH,
|
LAYOUT_RANGE_ATTR_STRIKETHROUGH,
|
||||||
LAYOUT_RANGE_ATTR_FONTCOLL
|
LAYOUT_RANGE_ATTR_FONTCOLL,
|
||||||
|
LAYOUT_RANGE_ATTR_LOCALE
|
||||||
};
|
};
|
||||||
|
|
||||||
struct layout_range_attr_value {
|
struct layout_range_attr_value {
|
||||||
@ -82,6 +83,7 @@ struct layout_range_attr_value {
|
|||||||
BOOL underline;
|
BOOL underline;
|
||||||
BOOL strikethrough;
|
BOOL strikethrough;
|
||||||
IDWriteFontCollection *collection;
|
IDWriteFontCollection *collection;
|
||||||
|
const WCHAR *locale;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -97,6 +99,7 @@ struct layout_range {
|
|||||||
BOOL underline;
|
BOOL underline;
|
||||||
BOOL strikethrough;
|
BOOL strikethrough;
|
||||||
IDWriteFontCollection *collection;
|
IDWriteFontCollection *collection;
|
||||||
|
WCHAR locale[LOCALE_NAME_MAX_LENGTH];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct layout_run {
|
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;
|
return range->strikethrough == value->u.strikethrough;
|
||||||
case LAYOUT_RANGE_ATTR_FONTCOLL:
|
case LAYOUT_RANGE_ATTR_FONTCOLL:
|
||||||
return range->collection == value->u.collection;
|
return range->collection == value->u.collection;
|
||||||
|
case LAYOUT_RANGE_ATTR_LOCALE:
|
||||||
|
return strcmpW(range->locale, value->u.locale) == 0;
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@ -447,6 +452,7 @@ static struct layout_range *alloc_layout_range(struct dwrite_textlayout *layout,
|
|||||||
range->collection = layout->format.collection;
|
range->collection = layout->format.collection;
|
||||||
if (range->collection)
|
if (range->collection)
|
||||||
IDWriteFontCollection_AddRef(range->collection);
|
IDWriteFontCollection_AddRef(range->collection);
|
||||||
|
strcpyW(range->locale, layout->format.locale);
|
||||||
|
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
@ -579,6 +585,11 @@ static BOOL set_layout_range_attrval(struct layout_range *dest, enum layout_rang
|
|||||||
if (dest->collection)
|
if (dest->collection)
|
||||||
IDWriteFontCollection_AddRef(dest->collection);
|
IDWriteFontCollection_AddRef(dest->collection);
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_RANGE_ATTR_LOCALE:
|
||||||
|
changed = strcmpW(dest->locale, value->u.locale) != 0;
|
||||||
|
if (changed)
|
||||||
|
strcpyW(dest->locale, value->u.locale);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@ -1127,17 +1138,17 @@ static HRESULT WINAPI dwritetextlayout_SetDrawingEffect(IDWriteTextLayout2 *ifac
|
|||||||
return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_EFFECT, &value);
|
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 dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
|
||||||
struct layout_range_attr_value attr;
|
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;
|
return S_OK;
|
||||||
|
|
||||||
attr.range = r;
|
attr.range = range;
|
||||||
attr.u.object = object;
|
attr.u.object = object;
|
||||||
|
|
||||||
return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_INLINE, &attr);
|
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)
|
static HRESULT WINAPI dwritetextlayout_SetLocaleName(IDWriteTextLayout2 *iface, WCHAR const* locale, DWRITE_TEXT_RANGE range)
|
||||||
{
|
{
|
||||||
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
|
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
|
||||||
FIXME("(%p)->(%s %s): stub\n", This, debugstr_w(locale), debugstr_range(&range));
|
struct layout_range_attr_value attr;
|
||||||
return E_NOTIMPL;
|
|
||||||
|
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)
|
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,
|
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);
|
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
|
||||||
FIXME("(%p)->(%u %p %p): stub\n", This, position, length, range);
|
struct layout_range *range;
|
||||||
return E_NOTIMPL;
|
|
||||||
|
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,
|
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);
|
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
|
||||||
FIXME("(%p)->(%u %p %u %p): stub\n", This, position, name, name_size, range);
|
struct layout_range *range;
|
||||||
return E_NOTIMPL;
|
|
||||||
|
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,
|
static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
|
||||||
|
@ -924,6 +924,72 @@ todo_wine {
|
|||||||
IDWriteTextFormat_Release(format);
|
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)
|
START_TEST(layout)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
@ -949,6 +1015,7 @@ START_TEST(layout)
|
|||||||
test_draw_sequence();
|
test_draw_sequence();
|
||||||
test_typography();
|
test_typography();
|
||||||
test_GetClusterMetrics();
|
test_GetClusterMetrics();
|
||||||
|
test_SetLocaleName();
|
||||||
|
|
||||||
IDWriteFactory_Release(factory);
|
IDWriteFactory_Release(factory);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user