riched20: Support ITextFont instances detached from a range.

This commit is contained in:
Nikolay Sivov 2015-05-26 09:12:58 +03:00 committed by Alexandre Julliard
parent 324acd5f1e
commit 0cf3c2f3a1
2 changed files with 527 additions and 128 deletions

View File

@ -139,6 +139,67 @@ typedef struct ITextSelectionImpl ITextSelectionImpl;
typedef struct IOleClientSiteImpl IOleClientSiteImpl;
typedef struct ITextRangeImpl ITextRangeImpl;
enum textfont_prop_id {
FONT_ALLCAPS = 0,
FONT_ANIMATION,
FONT_BACKCOLOR,
FONT_BOLD,
FONT_EMBOSS,
FONT_FORECOLOR,
FONT_HIDDEN,
FONT_ENGRAVE,
FONT_ITALIC,
FONT_KERNING,
FONT_LANGID,
FONT_NAME,
FONT_OUTLINE,
FONT_POSITION,
FONT_PROTECTED,
FONT_SHADOW,
FONT_SIZE,
FONT_SMALLCAPS,
FONT_SPACING,
FONT_STRIKETHROUGH,
FONT_SUBSCRIPT,
FONT_SUPERSCRIPT,
FONT_UNDERLINE,
FONT_WEIGHT,
FONT_PROPID_LAST
};
static const DWORD textfont_prop_masks[] = {
CFM_ALLCAPS,
CFM_ANIMATION,
CFM_BACKCOLOR,
CFM_BOLD,
CFM_EMBOSS,
CFM_COLOR,
CFM_HIDDEN,
CFM_IMPRINT,
CFM_ITALIC,
CFM_KERNING,
CFM_LCID,
CFM_FACE,
CFM_OUTLINE,
CFM_OFFSET,
CFM_PROTECTED,
CFM_SHADOW,
CFM_SIZE,
CFM_SMALLCAPS,
CFM_SPACING,
CFM_STRIKEOUT,
CFM_SUBSCRIPT,
CFM_SUPERSCRIPT,
CFM_UNDERLINE,
CFM_WEIGHT
};
typedef union {
FLOAT f;
LONG l;
BSTR str;
} textfont_prop_val;
typedef struct IRichEditOleImpl {
IUnknown IUnknown_inner;
IRichEditOle IRichEditOle_iface;
@ -173,6 +234,7 @@ typedef struct ITextFontImpl {
LONG ref;
ITextRange *range;
textfont_prop_val props[FONT_PROPID_LAST];
} ITextFontImpl;
typedef struct ITextParaImpl {
@ -236,70 +298,9 @@ static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
}
static HRESULT create_textfont(ITextRange*, ITextFont**);
static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
static HRESULT create_textpara(ITextRange*, ITextPara**);
enum textfont_prop_id {
FONT_ALLCAPS = 0,
FONT_ANIMATION,
FONT_BACKCOLOR,
FONT_BOLD,
FONT_EMBOSS,
FONT_FORECOLOR,
FONT_HIDDEN,
FONT_ENGRAVE,
FONT_ITALIC,
FONT_KERNING,
FONT_LANGID,
FONT_NAME,
FONT_OUTLINE,
FONT_POSITION,
FONT_PROTECTED,
FONT_SHADOW,
FONT_SIZE,
FONT_SMALLCAPS,
FONT_SPACING,
FONT_STRIKETHROUGH,
FONT_SUBSCRIPT,
FONT_SUPERSCRIPT,
FONT_UNDERLINE,
FONT_WEIGHT,
FONT_PROPID_LAST
};
static const DWORD textfont_prop_masks[] = {
CFM_ALLCAPS,
CFM_ANIMATION,
CFM_BACKCOLOR,
CFM_BOLD,
CFM_EMBOSS,
CFM_COLOR,
CFM_HIDDEN,
CFM_IMPRINT,
CFM_ITALIC,
CFM_KERNING,
CFM_LCID,
CFM_FACE,
CFM_OUTLINE,
CFM_OFFSET,
CFM_PROTECTED,
CFM_SHADOW,
CFM_SIZE,
CFM_SMALLCAPS,
CFM_SPACING,
CFM_STRIKEOUT,
CFM_SUBSCRIPT,
CFM_SUPERSCRIPT,
CFM_UNDERLINE,
CFM_WEIGHT
};
typedef union {
FLOAT f;
LONG l;
BSTR str;
} textfont_prop_val;
static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
textfont_prop_val *right)
{
@ -416,20 +417,26 @@ static inline const IRichEditOleImpl *get_range_reole(ITextRange *range)
return reole;
}
static HRESULT get_textfont_prop(ITextRange *range, enum textfont_prop_id propid, textfont_prop_val *value)
static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
{
const IRichEditOleImpl *reole;
textfont_prop_val v;
LONG start, end, i;
HRESULT hr;
if (!(reole = get_range_reole(range)))
/* when font is not attached to any range use cached values */
if (!font->range) {
*value = font->props[propid];
return S_OK;
}
if (!(reole = get_range_reole(font->range)))
return CO_E_RELEASED;
init_textfont_prop_value(propid, value);
ITextRange_GetStart(range, &start);
ITextRange_GetEnd(range, &end);
ITextRange_GetStart(font->range, &start);
ITextRange_GetEnd(font->range, &end);
/* iterate trough a range to see if property value is consistent */
hr = get_textfont_prop_for_pos(reole, start, propid, &v);
@ -451,7 +458,7 @@ static HRESULT get_textfont_prop(ITextRange *range, enum textfont_prop_id propid
return S_OK;
}
static HRESULT get_textfont_propf(ITextRange *range, enum textfont_prop_id propid, FLOAT *value)
static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
{
textfont_prop_val v;
HRESULT hr;
@ -459,12 +466,12 @@ static HRESULT get_textfont_propf(ITextRange *range, enum textfont_prop_id propi
if (!value)
return E_INVALIDARG;
hr = get_textfont_prop(range, propid, &v);
hr = get_textfont_prop(font, propid, &v);
*value = v.f;
return hr;
}
static HRESULT get_textfont_propl(ITextRange *range, enum textfont_prop_id propid, LONG *value)
static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
{
textfont_prop_val v;
HRESULT hr;
@ -472,7 +479,7 @@ static HRESULT get_textfont_propl(ITextRange *range, enum textfont_prop_id propi
if (!value)
return E_INVALIDARG;
hr = get_textfont_prop(range, propid, &v);
hr = get_textfont_prop(font, propid, &v);
*value = v.l;
return hr;
}
@ -1346,7 +1353,7 @@ static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
if (!font)
return E_INVALIDARG;
return create_textfont(me, font);
return create_textfont(me, NULL, font);
}
static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *pFont)
@ -1870,7 +1877,9 @@ static ULONG WINAPI TextFont_Release(ITextFont *iface)
if (!ref)
{
ITextRange_Release(This->range);
if (This->range)
ITextRange_Release(This->range);
SysFreeString(This->props[FONT_NAME].str);
heap_free(This);
}
@ -1952,8 +1961,7 @@ static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
if (This->range && !get_range_reole(This->range))
return CO_E_RELEASED;
FIXME("not implemented\n");
return E_NOTIMPL;
return create_textfont(NULL, This, ret);
}
static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
@ -1977,6 +1985,100 @@ static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *
return E_NOTIMPL;
}
static void textfont_reset_to_default(ITextFontImpl *font)
{
enum textfont_prop_id id;
for (id = FONT_ALLCAPS; id < FONT_PROPID_LAST; id++) {
switch (id)
{
case FONT_ALLCAPS:
case FONT_ANIMATION:
case FONT_BOLD:
case FONT_EMBOSS:
case FONT_HIDDEN:
case FONT_ENGRAVE:
case FONT_ITALIC:
case FONT_OUTLINE:
case FONT_PROTECTED:
case FONT_SHADOW:
case FONT_SMALLCAPS:
case FONT_STRIKETHROUGH:
case FONT_SUBSCRIPT:
case FONT_SUPERSCRIPT:
case FONT_UNDERLINE:
font->props[id].l = tomFalse;
break;
case FONT_BACKCOLOR:
case FONT_FORECOLOR:
font->props[id].l = tomAutoColor;
break;
case FONT_KERNING:
case FONT_POSITION:
case FONT_SIZE:
case FONT_SPACING:
font->props[id].f = 0.0;
break;
case FONT_LANGID:
font->props[id].l = GetSystemDefaultLCID();
break;
case FONT_NAME: {
static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
SysFreeString(font->props[id].str);
font->props[id].str = SysAllocString(sysW);
break;
}
case FONT_WEIGHT:
font->props[id].l = FW_NORMAL;
break;
default:
FIXME("font property %d not handled\n", id);
}
}
}
static void textfont_reset_to_undefined(ITextFontImpl *font)
{
enum textfont_prop_id id;
for (id = FONT_ALLCAPS; id < FONT_PROPID_LAST; id++) {
switch (id)
{
case FONT_ALLCAPS:
case FONT_ANIMATION:
case FONT_BOLD:
case FONT_EMBOSS:
case FONT_HIDDEN:
case FONT_ENGRAVE:
case FONT_ITALIC:
case FONT_OUTLINE:
case FONT_PROTECTED:
case FONT_SHADOW:
case FONT_SMALLCAPS:
case FONT_STRIKETHROUGH:
case FONT_SUBSCRIPT:
case FONT_SUPERSCRIPT:
case FONT_UNDERLINE:
case FONT_BACKCOLOR:
case FONT_FORECOLOR:
case FONT_LANGID:
case FONT_WEIGHT:
font->props[id].l = tomUndefined;
break;
case FONT_KERNING:
case FONT_POSITION:
case FONT_SIZE:
case FONT_SPACING:
font->props[id].f = tomUndefined;
break;
case FONT_NAME:
break;
default:
FIXME("font property %d not handled\n", id);
}
}
}
static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
@ -1992,6 +2094,19 @@ static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
if (value == tomUndefined)
return E_INVALIDARG;
}
else {
switch (value)
{
/* reset to global defaults */
case tomDefault:
textfont_reset_to_default(This);
return S_OK;
/* all properties are set to tomUndefined, font name is retained */
case tomUndefined:
textfont_reset_to_undefined(This);
return S_OK;
}
}
FIXME("reset mode %d not supported\n", value);
return E_NOTIMPL;
@ -2014,8 +2129,8 @@ static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_ALLCAPS, value);
}
static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
@ -2028,8 +2143,8 @@ static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_ANIMATION, value);
}
static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
@ -2042,8 +2157,8 @@ static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_BACKCOLOR, value);
}
static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
@ -2057,7 +2172,7 @@ static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This->range, FONT_BOLD, value);
return get_textfont_propl(This, FONT_BOLD, value);
}
static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
@ -2070,8 +2185,8 @@ static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_EMBOSS, value);
}
static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
@ -2085,7 +2200,7 @@ static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This->range, FONT_FORECOLOR, value);
return get_textfont_propl(This, FONT_FORECOLOR, value);
}
static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
@ -2098,8 +2213,8 @@ static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_HIDDEN, value);
}
static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
@ -2112,8 +2227,8 @@ static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_ENGRAVE, value);
}
static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
@ -2127,7 +2242,7 @@ static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This->range, FONT_ITALIC, value);
return get_textfont_propl(This, FONT_ITALIC, value);
}
static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
@ -2140,8 +2255,8 @@ static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propf(This, FONT_KERNING, value);
}
static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
@ -2155,7 +2270,7 @@ static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This->range, FONT_LANGID, value);
return get_textfont_propl(This, FONT_LANGID, value);
}
static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
@ -2180,6 +2295,14 @@ static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
*value = NULL;
if (!This->range) {
if (This->props[FONT_NAME].str)
*value = SysAllocString(This->props[FONT_NAME].str);
else
*value = SysAllocStringLen(NULL, 0);
return *value ? S_OK : E_OUTOFMEMORY;
}
if (!(reole = get_range_reole(This->range)))
return CO_E_RELEASED;
@ -2204,8 +2327,8 @@ static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_OUTLINE, value);
}
static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
@ -2218,8 +2341,8 @@ static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propf(This, FONT_POSITION, value);
}
static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
@ -2232,8 +2355,8 @@ static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_PROTECTED, value);
}
static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
@ -2246,8 +2369,8 @@ static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_SHADOW, value);
}
static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
@ -2261,7 +2384,7 @@ static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propf(This->range, FONT_SIZE, value);
return get_textfont_propf(This, FONT_SIZE, value);
}
static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
@ -2274,8 +2397,8 @@ static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_SMALLCAPS, value);
}
static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
@ -2288,8 +2411,8 @@ static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propf(This, FONT_SPACING, value);
}
static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
@ -2303,7 +2426,7 @@ static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This->range, FONT_STRIKETHROUGH, value);
return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
}
static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
@ -2317,7 +2440,7 @@ static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This->range, FONT_SUBSCRIPT, value);
return get_textfont_propl(This, FONT_SUBSCRIPT, value);
}
static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
@ -2331,7 +2454,7 @@ static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This->range, FONT_SUPERSCRIPT, value);
return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
}
static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
@ -2345,7 +2468,7 @@ static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This->range, FONT_UNDERLINE, value);
return get_textfont_propl(This, FONT_UNDERLINE, value);
}
static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
@ -2358,8 +2481,8 @@ static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
{
ITextFontImpl *This = impl_from_ITextFont(iface);
FIXME("(%p)->(%p): stub\n", This, value);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, value);
return get_textfont_propl(This, FONT_WEIGHT, value);
}
static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
@ -2434,7 +2557,7 @@ static ITextFontVtbl textfontvtbl = {
TextFont_SetWeight
};
static HRESULT create_textfont(ITextRange *range, ITextFont **ret)
static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
{
ITextFontImpl *font;
@ -2445,8 +2568,19 @@ static HRESULT create_textfont(ITextRange *range, ITextFont **ret)
font->ITextFont_iface.lpVtbl = &textfontvtbl;
font->ref = 1;
font->range = range;
ITextRange_AddRef(range);
if (src) {
font->range = NULL;
memcpy(&font->props, &src->props, sizeof(font->props));
if (font->props[FONT_NAME].str)
font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
}
else {
font->range = range;
ITextRange_AddRef(range);
/* FIXME: copy current range attributes to a cache */
memset(&font->props, 0, sizeof(font->props));
}
*ret = &font->ITextFont_iface;
return S_OK;
@ -3562,7 +3696,7 @@ static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **f
if (!font)
return E_INVALIDARG;
return create_textfont((ITextRange*)me, font);
return create_textfont((ITextRange*)me, NULL, font);
}
static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *pFont)

View File

@ -37,6 +37,8 @@ static HMODULE hmoduleRichEdit;
DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
static void _expect_ref(IUnknown* obj, ULONG ref, int line)
{
@ -1808,9 +1810,259 @@ static void test_detached_font_getters(ITextFont *font, BOOL duplicate)
ok(hr == hrexp, "got 0x%08x\n", hr);
}
static void test_textfont_global_defaults(ITextFont *font)
{
float valuef;
LONG value;
HRESULT hr;
BSTR str;
value = tomUndefined;
hr = ITextFont_GetAllCaps(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetAnimation(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetBackColor(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomAutoColor, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetBold(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse || value == tomTrue, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetEmboss(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetForeColor(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomAutoColor, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetHidden(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetEngrave(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetItalic(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
valuef = 1.0;
hr = ITextFont_GetKerning(font, &valuef);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(valuef == 0.0, "got %.2f\n", valuef);
value = tomUndefined;
hr = ITextFont_GetLanguageID(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == GetSystemDefaultLCID(), "got %d\n", value);
str = NULL;
hr = ITextFont_GetName(font, &str);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(!lstrcmpW(sysW, str), "%s\n", wine_dbgstr_w(str));
SysFreeString(str);
value = tomUndefined;
hr = ITextFont_GetOutline(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
valuef = 1.0;
hr = ITextFont_GetPosition(font, &valuef);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(valuef == 0.0, "got %.2f\n", valuef);
value = tomUndefined;
hr = ITextFont_GetProtected(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetShadow(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
valuef = 0.0;
hr = ITextFont_GetSize(font, &valuef);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(valuef >= 0.0, "got %.2f\n", valuef);
value = tomUndefined;
hr = ITextFont_GetSmallCaps(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
valuef = 1.0;
hr = ITextFont_GetSpacing(font, &valuef);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(valuef == 0.0, "got %.2f\n", valuef);
value = tomUndefined;
hr = ITextFont_GetStrikeThrough(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetSubscript(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetSuperscript(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetUnderline(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomFalse, "got %d\n", value);
value = tomUndefined;
hr = ITextFont_GetWeight(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == FW_NORMAL || value == FW_BOLD, "got %d\n", value);
}
static void test_textfont_undefined(ITextFont *font)
{
float valuef;
LONG value;
HRESULT hr;
value = tomFalse;
hr = ITextFont_GetAllCaps(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetAnimation(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetBackColor(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetBold(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetEmboss(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetForeColor(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetHidden(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetEngrave(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetItalic(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
valuef = 0.0;
hr = ITextFont_GetKerning(font, &valuef);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(valuef == tomUndefined, "got %.2f\n", valuef);
value = tomFalse;
hr = ITextFont_GetLanguageID(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetOutline(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
valuef = 0.0;
hr = ITextFont_GetPosition(font, &valuef);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(valuef == tomUndefined, "got %.2f\n", valuef);
value = tomFalse;
hr = ITextFont_GetProtected(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetShadow(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
valuef = 0.0;
hr = ITextFont_GetSize(font, &valuef);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(valuef == tomUndefined, "got %.2f\n", valuef);
value = tomFalse;
hr = ITextFont_GetSmallCaps(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
valuef = 0.0;
hr = ITextFont_GetSpacing(font, &valuef);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(valuef == tomUndefined, "got %.2f\n", valuef);
value = tomFalse;
hr = ITextFont_GetStrikeThrough(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetSubscript(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetSuperscript(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetUnderline(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
value = tomFalse;
hr = ITextFont_GetWeight(font, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
}
static void test_ITextFont(void)
{
static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
static const WCHAR arialW[] = {'A','r','i','a','l',0};
static const CHAR test_text1[] = "TestSomeText";
ITextFont *font, *font2, *font3;
@ -1885,10 +2137,11 @@ static void test_ITextFont(void)
hr = ITextFont_GetDuplicate(font, NULL);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
EXPECT_REF(range, 2);
font2 = NULL;
hr = ITextFont_GetDuplicate(font, &font2);
todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
EXPECT_REF(range, 2);
/* set whole range to italic */
cf.cbSize = sizeof(CHARFORMAT2A);
@ -1905,7 +2158,6 @@ todo_wine
ok(value == tomTrue, "got %d\n", value);
/* duplicate retains original value */
if (font2) {
value = tomTrue;
hr = ITextFont_GetItalic(font2, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
@ -1915,7 +2167,7 @@ if (font2) {
hr = ITextFont_GetDuplicate(font2, &font3);
ok(hr == S_OK, "got 0x%08x\n", hr);
ITextFont_Release(font3);
}
ITextRange_Release(range);
release_interfaces(&hwnd, &reOle, &doc, NULL);
@ -1923,7 +2175,6 @@ if (font2) {
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
test_detached_font_getters(font, FALSE);
if (font2) {
test_detached_font_getters(font2, TRUE);
/* get a duplicate of detached font */
@ -1937,17 +2188,22 @@ if (font2) {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value != tomUndefined, "got %d\n", value);
/* reset to undefined for attached font */
/* reset to undefined for deatached font */
hr = ITextFont_Reset(font2, tomUndefined);
ok(hr == S_OK, "got 0x%08x\n", hr);
test_textfont_undefined(font2);
value = tomTrue;
hr = ITextFont_GetBold(font2, &value);
/* font is detached, default means global TOM defaults */
hr = ITextFont_Reset(font2, tomDefault);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == tomUndefined, "got %d\n", value);
test_textfont_global_defaults(font2);
hr = ITextFont_GetDuplicate(font2, &font3);
ok(hr == S_OK, "got 0x%08x\n", hr);
test_textfont_global_defaults(font3);
ITextFont_Release(font3);
ITextFont_Release(font2);
}
font2 = (void*)0xdeadbeef;
hr = ITextFont_GetDuplicate(font, &font2);
@ -2011,10 +2267,19 @@ static void test_Delete(void)
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 4, "got %d\n", value);
hr = ITextRange_Delete(range2, tomCharacter, 0, NULL);
todo_wine
/* unit type doesn't matter is count is 0 */
value = 0;
hr = ITextRange_Delete(range2, tomSentence, 0, &value);
todo_wine {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 1, "got %d\n", value);
}
value = 1;
hr = ITextRange_Delete(range2, tomCharacter, 0, &value);
todo_wine {
ok(hr == S_FALSE, "got 0x%08x\n", hr);
ok(value == 0, "got %d\n", value);
}
hr = ITextRange_GetEnd(range, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine