Nikolay Sivov : riched20: Initial support for changing font properties.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue May 26 09:14:35 CDT 2015
Module: wine
Branch: master
Commit: 64faf03cf3248d6fed7b89d9246e4b13f20300db
URL: http://source.winehq.org/git/wine.git/?a=commit;h=64faf03cf3248d6fed7b89d9246e4b13f20300db
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Tue May 26 09:17:02 2015 +0300
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 eb803e7..063522b 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 72cb1db..adb96c3 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);
More information about the wine-cvs
mailing list