dwrite: Support family name attribute for ranges.

This commit is contained in:
Nikolay Sivov 2015-01-02 22:22:40 +03:00 committed by Alexandre Julliard
parent ed398419bc
commit 9661f129e0
1 changed files with 102 additions and 37 deletions

View File

@ -68,7 +68,8 @@ enum layout_range_attr_kind {
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 LAYOUT_RANGE_ATTR_LOCALE,
LAYOUT_RANGE_ATTR_FONTFAMILY
}; };
struct layout_range_attr_value { struct layout_range_attr_value {
@ -84,6 +85,7 @@ struct layout_range_attr_value {
BOOL strikethrough; BOOL strikethrough;
IDWriteFontCollection *collection; IDWriteFontCollection *collection;
const WCHAR *locale; const WCHAR *locale;
const WCHAR *fontfamily;
} u; } u;
}; };
@ -100,6 +102,7 @@ struct layout_range {
BOOL strikethrough; BOOL strikethrough;
IDWriteFontCollection *collection; IDWriteFontCollection *collection;
WCHAR locale[LOCALE_NAME_MAX_LENGTH]; WCHAR locale[LOCALE_NAME_MAX_LENGTH];
WCHAR *fontfamily;
}; };
struct layout_run { struct layout_run {
@ -407,6 +410,8 @@ static BOOL is_same_layout_attrvalue(struct layout_range const *range, enum layo
return range->collection == value->u.collection; return range->collection == value->u.collection;
case LAYOUT_RANGE_ATTR_LOCALE: case LAYOUT_RANGE_ATTR_LOCALE:
return strcmpW(range->locale, value->u.locale) == 0; return strcmpW(range->locale, value->u.locale) == 0;
case LAYOUT_RANGE_ATTR_FONTFAMILY:
return strcmpW(range->fontfamily, value->u.fontfamily) == 0;
default: default:
; ;
} }
@ -425,7 +430,8 @@ static inline BOOL is_same_layout_attributes(struct layout_range const *left, st
left->underline == right->underline && left->underline == right->underline &&
left->strikethrough == right->strikethrough && left->strikethrough == right->strikethrough &&
left->collection == right->collection && left->collection == right->collection &&
!strcmpW(left->locale, right->locale); !strcmpW(left->locale, right->locale) &&
!strcmpW(left->fontfamily, right->fontfamily);
} }
static inline BOOL is_same_text_range(const DWRITE_TEXT_RANGE *left, const DWRITE_TEXT_RANGE *right) static inline BOOL is_same_text_range(const DWRITE_TEXT_RANGE *left, const DWRITE_TEXT_RANGE *right)
@ -450,6 +456,13 @@ static struct layout_range *alloc_layout_range(struct dwrite_textlayout *layout,
range->effect = NULL; range->effect = NULL;
range->underline = FALSE; range->underline = FALSE;
range->strikethrough = FALSE; range->strikethrough = FALSE;
range->fontfamily = heap_strdupW(layout->format.family_name);
if (!range->fontfamily) {
heap_free(range);
return NULL;
}
range->collection = layout->format.collection; range->collection = layout->format.collection;
if (range->collection) if (range->collection)
IDWriteFontCollection_AddRef(range->collection); IDWriteFontCollection_AddRef(range->collection);
@ -489,6 +502,7 @@ static void free_layout_range(struct layout_range *range)
IUnknown_Release(range->effect); IUnknown_Release(range->effect);
if (range->collection) if (range->collection)
IDWriteFontCollection_Release(range->collection); IDWriteFontCollection_Release(range->collection);
heap_free(range->fontfamily);
heap_free(range); heap_free(range);
} }
@ -591,6 +605,13 @@ static BOOL set_layout_range_attrval(struct layout_range *dest, enum layout_rang
if (changed) if (changed)
strcpyW(dest->locale, value->u.locale); strcpyW(dest->locale, value->u.locale);
break; break;
case LAYOUT_RANGE_ATTR_FONTFAMILY:
changed = strcmpW(dest->fontfamily, value->u.fontfamily) != 0;
if (changed) {
heap_free(dest->fontfamily);
dest->fontfamily = heap_strdupW(value->u.fontfamily);
}
break;
default: default:
; ;
} }
@ -735,6 +756,63 @@ done:
return S_OK; return S_OK;
} }
static inline const WCHAR *get_string_attribute_ptr(struct layout_range *range, enum layout_range_attr_kind kind)
{
const WCHAR *str;
switch (kind) {
case LAYOUT_RANGE_ATTR_LOCALE:
str = range->locale;
break;
case LAYOUT_RANGE_ATTR_FONTFAMILY:
str = range->fontfamily;
break;
default:
str = NULL;
}
return str;
}
static HRESULT get_string_attribute_length(struct dwrite_textlayout *layout, enum layout_range_attr_kind kind, UINT32 position,
UINT32 *length, DWRITE_TEXT_RANGE *r)
{
struct layout_range *range;
const WCHAR *str;
range = get_layout_range_by_pos(layout, position);
if (!range) {
*length = 0;
return S_OK;
}
str = get_string_attribute_ptr(range, kind);
*length = strlenW(str);
return return_range(range, r);
}
static HRESULT get_string_attribute_value(struct dwrite_textlayout *layout, enum layout_range_attr_kind kind, UINT32 position,
WCHAR *ret, UINT32 length, DWRITE_TEXT_RANGE *r)
{
struct layout_range *range;
const WCHAR *str;
if (length == 0)
return E_INVALIDARG;
ret[0] = 0;
range = get_layout_range_by_pos(layout, position);
if (!range)
return E_INVALIDARG;
str = get_string_attribute_ptr(range, kind);
if (length < strlenW(str) + 1)
return E_NOT_SUFFICIENT_BUFFER;
strcpyW(ret, str);
return return_range(range, r);
}
static HRESULT WINAPI dwritetextlayout_QueryInterface(IDWriteTextLayout2 *iface, REFIID riid, void **obj) static HRESULT WINAPI dwritetextlayout_QueryInterface(IDWriteTextLayout2 *iface, REFIID riid, void **obj)
{ {
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface); struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
@ -1030,8 +1108,20 @@ static HRESULT WINAPI dwritetextlayout_SetFontCollection(IDWriteTextLayout2 *ifa
static HRESULT WINAPI dwritetextlayout_SetFontFamilyName(IDWriteTextLayout2 *iface, WCHAR const *name, DWRITE_TEXT_RANGE range) static HRESULT WINAPI dwritetextlayout_SetFontFamilyName(IDWriteTextLayout2 *iface, WCHAR const *name, 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(name), debugstr_range(&range)); struct layout_range_attr_value value;
return E_NOTIMPL;
TRACE("(%p)->(%s %s)\n", This, debugstr_w(name), debugstr_range(&range));
if (!name)
return E_INVALIDARG;
if (!validate_text_range(This, &range))
return S_OK;
value.range = range;
value.u.fontfamily = name;
return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_FONTFAMILY, &value);
} }
static HRESULT WINAPI dwritetextlayout_SetFontWeight(IDWriteTextLayout2 *iface, DWRITE_FONT_WEIGHT weight, DWRITE_TEXT_RANGE range) static HRESULT WINAPI dwritetextlayout_SetFontWeight(IDWriteTextLayout2 *iface, DWRITE_FONT_WEIGHT weight, DWRITE_TEXT_RANGE range)
@ -1212,19 +1302,19 @@ static HRESULT WINAPI dwritetextlayout_layout_GetFontCollection(IDWriteTextLayou
} }
static HRESULT WINAPI dwritetextlayout_layout_GetFontFamilyNameLength(IDWriteTextLayout2 *iface, static HRESULT WINAPI dwritetextlayout_layout_GetFontFamilyNameLength(IDWriteTextLayout2 *iface,
UINT32 pos, UINT32* len, 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)->(%d %p %p): stub\n", This, pos, len, range); TRACE("(%p)->(%d %p %p)\n", This, position, length, r);
return E_NOTIMPL; return get_string_attribute_length(This, LAYOUT_RANGE_ATTR_FONTFAMILY, position, length, r);
} }
static HRESULT WINAPI dwritetextlayout_layout_GetFontFamilyName(IDWriteTextLayout2 *iface, static HRESULT WINAPI dwritetextlayout_layout_GetFontFamilyName(IDWriteTextLayout2 *iface,
UINT32 position, WCHAR* name, UINT32 name_size, DWRITE_TEXT_RANGE *range) UINT32 position, WCHAR *name, 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); TRACE("(%p)->(%u %p %u %p)\n", This, position, name, length, r);
return E_NOTIMPL; return get_string_attribute_value(This, LAYOUT_RANGE_ATTR_FONTFAMILY, position, name, length, r);
} }
static HRESULT WINAPI dwritetextlayout_layout_GetFontWeight(IDWriteTextLayout2 *iface, static HRESULT WINAPI dwritetextlayout_layout_GetFontWeight(IDWriteTextLayout2 *iface,
@ -1376,41 +1466,16 @@ static HRESULT WINAPI dwritetextlayout_layout_GetLocaleNameLength(IDWriteTextLay
UINT32 position, UINT32* length, DWRITE_TEXT_RANGE *r) UINT32 position, UINT32* length, DWRITE_TEXT_RANGE *r)
{ {
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface); struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
struct layout_range *range;
TRACE("(%p)->(%u %p %p)\n", This, position, length, r); TRACE("(%p)->(%u %p %p)\n", This, position, length, r);
return get_string_attribute_length(This, LAYOUT_RANGE_ATTR_LOCALE, 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* locale, UINT32 length, DWRITE_TEXT_RANGE *r) 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);
struct layout_range *range;
TRACE("(%p)->(%u %p %u %p)\n", This, position, locale, length, r); TRACE("(%p)->(%u %p %u %p)\n", This, position, locale, length, r);
return get_string_attribute_value(This, LAYOUT_RANGE_ATTR_LOCALE, 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,