From 64faf03cf3248d6fed7b89d9246e4b13f20300db Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 26 May 2015 09:17:02 +0300 Subject: [PATCH] riched20: Initial support for changing font properties. --- dlls/riched20/richole.c | 90 ++++++++++++++++++++++++++++++++++++++++++- dlls/riched20/tests/richole.c | 49 +++++++++++++++++++++++ 2 files changed, 137 insertions(+), 2 deletions(-) diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c index eb803e7a32b..063522bd902 100644 --- a/dlls/riched20/richole.c +++ b/dlls/riched20/richole.c @@ -237,6 +237,7 @@ typedef struct ITextFontImpl { ITextRange *range; textfont_prop_val props[FONT_PROPID_LAST]; BOOL get_cache_enabled; + BOOL set_cache_enabled; } ITextFontImpl; typedef struct ITextParaImpl { @@ -556,6 +557,75 @@ static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_ return hr; } +/* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */ +static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value) +{ + const IRichEditOleImpl *reole; + ME_Cursor from, to; + CHARFORMAT2W fmt; + LONG start, end; + + /* when font is not attached to any range use cache */ + if (!font->range || font->set_cache_enabled) { + font->props[propid] = *value; + return S_OK; + } + + if (!(reole = get_range_reole(font->range))) + return CO_E_RELEASED; + + memset(&fmt, 0, sizeof(fmt)); + fmt.cbSize = sizeof(fmt); + fmt.dwMask = textfont_prop_masks[propid]; + + switch (propid) + { + case FONT_ITALIC: + fmt.dwEffects = value->l == tomTrue ? CFE_ITALIC : 0; + break; + default: + FIXME("unhandled font property %d\n", propid); + return E_FAIL; + } + + ITextRange_GetStart(font->range, &start); + ITextRange_GetEnd(font->range, &end); + + ME_CursorFromCharOfs(reole->editor, start, &from); + ME_CursorFromCharOfs(reole->editor, end, &to); + ME_SetCharFormat(reole->editor, &from, &to, &fmt); + + return S_OK; +} + +static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value) +{ + textfont_prop_val v; + + switch (value) + { + case tomUndefined: + return S_OK; + case tomToggle: { + LONG oldvalue; + get_textfont_propl(font, propid, &oldvalue); + if (oldvalue == tomFalse) + value = tomTrue; + else if (oldvalue == tomTrue) + value = tomFalse; + else + return E_INVALIDARG; + /* fallthrough */ + } + case tomTrue: + case tomFalse: + v.l = value; + return set_textfont_prop(font, propid, &v); + default: + return E_INVALIDARG; + } +} + static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret) { const IRichEditOleImpl *reole; @@ -2178,6 +2248,13 @@ static void textfont_reset_to_undefined(ITextFontImpl *font) } } +static void textfont_apply_range_props(ITextFontImpl *font) +{ + enum textfont_prop_id propid; + for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) + set_textfont_prop(font, propid, &font->props[propid]); +} + static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value) { ITextFontImpl *This = impl_from_ITextFont(iface); @@ -2201,6 +2278,13 @@ static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value) case tomTrackParms: This->get_cache_enabled = FALSE; break; + case tomApplyLater: + This->set_cache_enabled = TRUE; + break; + case tomApplyNow: + This->set_cache_enabled = FALSE; + textfont_apply_range_props(This); + break; default: FIXME("reset mode %d not supported\n", value); } @@ -2366,8 +2450,8 @@ static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value) static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value) { ITextFontImpl *This = impl_from_ITextFont(iface); - FIXME("(%p)->(%d): stub\n", This, value); - return E_NOTIMPL; + TRACE("(%p)->(%d)\n", This, value); + return set_textfont_propd(This, FONT_ITALIC, value); } static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value) @@ -2675,6 +2759,7 @@ static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITex if (src) { font->range = NULL; font->get_cache_enabled = TRUE; + font->set_cache_enabled = TRUE; 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); @@ -2685,6 +2770,7 @@ static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITex /* cache current properties */ font->get_cache_enabled = FALSE; + font->set_cache_enabled = FALSE; textfont_cache_range_props(font); } diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c index 72cb1db967f..adb96c33166 100644 --- a/dlls/riched20/tests/richole.c +++ b/dlls/riched20/tests/richole.c @@ -2214,6 +2214,13 @@ static void test_ITextFont(void) ok(hr == S_OK, "got 0x%08x\n", hr); test_textfont_global_defaults(font2); + hr = ITextFont_SetItalic(font2, tomUndefined); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + hr = ITextFont_Reset(font2, tomCacheParms); ok(hr == S_OK, "got 0x%08x\n", hr); test_textfont_global_defaults(font2); @@ -2292,6 +2299,48 @@ static void test_ITextFont(void) ok(hr == S_OK, "got 0x%08x\n", hr); ok(value == tomTrue, "got %d\n", value); + /* tomApplyLater */ + hr = ITextFont_Reset(font, tomApplyLater); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_SetItalic(font, tomFalse); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + cf.dwEffects = 0; + SendMessageA(hwnd, EM_SETSEL, 0, 10); + ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + ok((cf.dwEffects & CFE_ITALIC) == CFE_ITALIC, "got 0x%08x\n", cf.dwEffects); + + hr = ITextFont_Reset(font, tomApplyNow); + ok(hr == S_OK, "got 0x%08x\n", hr); + + cf.dwEffects = 0; + SendMessageA(hwnd, EM_SETSEL, 0, 10); + ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects); + + hr = ITextFont_SetItalic(font, tomUndefined); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextFont_SetItalic(font, tomAutoColor); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + cf.dwEffects = 0; + SendMessageA(hwnd, EM_SETSEL, 0, 10); + ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects); + ITextRange_Release(range); ITextFont_Release(font); release_interfaces(&hwnd, &reOle, &doc, NULL); -- 2.11.4.GIT