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