Nikolay Sivov : riched20: Implement SetFont().

Alexandre Julliard julliard at wine.codeweavers.com
Fri May 29 05:29:48 CDT 2015


Module: wine
Branch: master
Commit: 054eecb2bf3f3a2f2eb80252df468e4ad20ff4b2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=054eecb2bf3f3a2f2eb80252df468e4ad20ff4b2

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu May 28 12:36:23 2015 +0300

riched20: Implement SetFont().

---

 dlls/riched20/richole.c       | 189 ++++++++++++++++++++++++++++++++++++++++--
 dlls/riched20/tests/richole.c |  88 ++++++++++++++++++++
 2 files changed, 271 insertions(+), 6 deletions(-)

diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c
index e35f561..5b8cad5 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -421,6 +421,11 @@ static inline FLOAT twips_to_points(LONG value)
     return value * 72.0 / 1440;
 }
 
+static inline FLOAT points_to_twips(FLOAT value)
+{
+    return value * 1440 / 72.0;
+}
+
 static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, enum textfont_prop_id propid,
     textfont_prop_val *value)
 {
@@ -502,6 +507,166 @@ static inline const IRichEditOleImpl *get_range_reole(ITextRange *range)
     return reole;
 }
 
+static void textrange_set_font(ITextRange *range, ITextFont *font)
+{
+    CHARFORMAT2W fmt;
+    LONG value;
+    BSTR str;
+    FLOAT f;
+
+#define CHARFORMAT_SET_B_FIELD(mask, value) \
+    if (value != tomUndefined) { \
+        fmt.dwMask |= CFM_##mask; \
+        if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
+    } \
+
+    /* fill format data from font */
+    memset(&fmt, 0, sizeof(fmt));
+    fmt.cbSize = sizeof(fmt);
+
+    value = tomUndefined;
+    ITextFont_GetAllCaps(font, &value);
+    CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
+
+    value = tomUndefined;
+    ITextFont_GetBold(font, &value);
+    CHARFORMAT_SET_B_FIELD(BOLD, value);
+
+    value = tomUndefined;
+    ITextFont_GetEmboss(font, &value);
+    CHARFORMAT_SET_B_FIELD(EMBOSS, value);
+
+    value = tomUndefined;
+    ITextFont_GetHidden(font, &value);
+    CHARFORMAT_SET_B_FIELD(HIDDEN, value);
+
+    value = tomUndefined;
+    ITextFont_GetEngrave(font, &value);
+    CHARFORMAT_SET_B_FIELD(IMPRINT, value);
+
+    value = tomUndefined;
+    ITextFont_GetItalic(font, &value);
+    CHARFORMAT_SET_B_FIELD(ITALIC, value);
+
+    value = tomUndefined;
+    ITextFont_GetOutline(font, &value);
+    CHARFORMAT_SET_B_FIELD(OUTLINE, value);
+
+    value = tomUndefined;
+    ITextFont_GetProtected(font, &value);
+    CHARFORMAT_SET_B_FIELD(PROTECTED, value);
+
+    value = tomUndefined;
+    ITextFont_GetShadow(font, &value);
+    CHARFORMAT_SET_B_FIELD(SHADOW, value);
+
+    value = tomUndefined;
+    ITextFont_GetSmallCaps(font, &value);
+    CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
+
+    value = tomUndefined;
+    ITextFont_GetStrikeThrough(font, &value);
+    CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
+
+    value = tomUndefined;
+    ITextFont_GetSubscript(font, &value);
+    CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value);
+
+    value = tomUndefined;
+    ITextFont_GetSuperscript(font, &value);
+    CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
+
+    value = tomUndefined;
+    ITextFont_GetUnderline(font, &value);
+    CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
+
+#undef CHARFORMAT_SET_B_FIELD
+
+    value = tomUndefined;
+    ITextFont_GetAnimation(font, &value);
+    if (value != tomUndefined) {
+        fmt.dwMask |= CFM_ANIMATION;
+        fmt.bAnimation = value;
+    }
+
+    value = tomUndefined;
+    ITextFont_GetBackColor(font, &value);
+    if (value != tomUndefined) {
+        fmt.dwMask |= CFM_BACKCOLOR;
+        if (value == tomAutoColor)
+            fmt.dwEffects |= CFE_AUTOBACKCOLOR;
+        else
+            fmt.crBackColor = value;
+    }
+
+    value = tomUndefined;
+    ITextFont_GetForeColor(font, &value);
+    if (value != tomUndefined) {
+        fmt.dwMask |= CFM_COLOR;
+        if (value == tomAutoColor)
+            fmt.dwEffects |= CFE_AUTOCOLOR;
+        else
+            fmt.crTextColor = value;
+    }
+
+    value = tomUndefined;
+    ITextFont_GetKerning(font, &f);
+    if (f != tomUndefined) {
+        fmt.dwMask |= CFM_KERNING;
+        fmt.wKerning = points_to_twips(f);
+    }
+
+    value = tomUndefined;
+    ITextFont_GetLanguageID(font, &value);
+    if (value != tomUndefined) {
+        fmt.dwMask |= CFM_LCID;
+        fmt.lcid = value;
+    }
+
+    if (ITextFont_GetName(font, &str) == S_OK) {
+        fmt.dwMask |= CFM_FACE;
+        lstrcpynW(fmt.szFaceName, str, sizeof(fmt.szFaceName)/sizeof(WCHAR));
+        SysFreeString(str);
+    }
+
+    ITextFont_GetPosition(font, &f);
+    if (f != tomUndefined) {
+        fmt.dwMask |= CFM_OFFSET;
+        fmt.yOffset = points_to_twips(f);
+    }
+
+    ITextFont_GetSize(font, &f);
+    if (f != tomUndefined) {
+        fmt.dwMask |= CFM_SIZE;
+        fmt.yHeight = points_to_twips(f);
+    }
+
+    ITextFont_GetSpacing(font, &f);
+    if (f != tomUndefined) {
+        fmt.dwMask |= CFM_SPACING;
+        fmt.sSpacing = f;
+    }
+
+    ITextFont_GetWeight(font, &value);
+    if (value != tomUndefined) {
+        fmt.dwMask |= CFM_WEIGHT;
+        fmt.wWeight = value;
+    }
+
+    if (fmt.dwMask) {
+        const IRichEditOleImpl *reole = get_range_reole(range);
+        ME_Cursor from, to;
+        LONG start, end;
+
+        ITextRange_GetStart(range, &start);
+        ITextRange_GetEnd(range, &end);
+
+        ME_CursorFromCharOfs(reole->editor, start, &from);
+        ME_CursorFromCharOfs(reole->editor, end, &to);
+        ME_SetCharFormat(reole->editor, &from, &to, &fmt);
+    }
+}
+
 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
 {
     const IRichEditOleImpl *reole;
@@ -1638,14 +1803,20 @@ static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
     return create_textfont(me, NULL, font);
 }
 
-static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *pFont)
+static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
 {
     ITextRangeImpl *This = impl_from_ITextRange(me);
+
+    TRACE("(%p)->(%p)\n", This, font);
+
+    if (!font)
+        return E_INVALIDARG;
+
     if (!This->reOle)
         return CO_E_RELEASED;
 
-    FIXME("not implemented %p\n", This);
-    return E_NOTIMPL;
+    textrange_set_font(me, font);
+    return S_OK;
 }
 
 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
@@ -4086,14 +4257,20 @@ static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **f
     return create_textfont((ITextRange*)me, NULL, font);
 }
 
-static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *pFont)
+static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
 {
     ITextSelectionImpl *This = impl_from_ITextSelection(me);
+
+    TRACE("(%p)->(%p)\n", This, font);
+
+    if (!font)
+        return E_INVALIDARG;
+
     if (!This->reOle)
         return CO_E_RELEASED;
 
-    FIXME("not implemented\n");
-    return E_NOTIMPL;
+    textrange_set_font((ITextRange*)me, font);
+    return S_OK;
 }
 
 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c
index 35fd59c..09ab939 100644
--- a/dlls/riched20/tests/richole.c
+++ b/dlls/riched20/tests/richole.c
@@ -2923,6 +2923,93 @@ static void test_GetStoryType(void)
   ITextSelection_Release(selection);
 }
 
+static void test_SetFont(void)
+{
+  static const CHAR test_text1[] = "TestSomeText";
+  IRichEditOle *reOle = NULL;
+  ITextDocument *doc = NULL;
+  ITextSelection *selection;
+  ITextRange *range, *range2;
+  ITextFont *font, *font2;
+  LONG value;
+  HRESULT hr;
+  HWND hwnd;
+
+  create_interfaces(&hwnd, &reOle, &doc, &selection);
+  SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
+  SendMessageA(hwnd, EM_SETSEL, 1, 2);
+
+  hr = ITextDocument_Range(doc, 0, 4, &range);
+  ok(hr == S_OK, "got 0x%08x\n", hr);
+
+  hr = ITextDocument_Range(doc, 5, 2, &range2);
+  ok(hr == S_OK, "got 0x%08x\n", hr);
+
+  EXPECT_REF(range, 1);
+  hr = ITextRange_GetFont(range, &font);
+  ok(hr == S_OK, "got 0x%08x\n", hr);
+  EXPECT_REF(range, 2);
+
+  EXPECT_REF(range2, 1);
+  hr = ITextRange_GetFont(range2, &font2);
+  ok(hr == S_OK, "got 0x%08x\n", hr);
+  EXPECT_REF(range2, 2);
+
+  hr = ITextRange_SetFont(range, NULL);
+  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+  /* setting same font, no-op */
+  EXPECT_REF(range, 2);
+  hr = ITextRange_SetFont(range, font);
+  ok(hr == S_OK, "got 0x%08x\n", hr);
+  EXPECT_REF(range, 2);
+
+  EXPECT_REF(range2, 2);
+  EXPECT_REF(range, 2);
+  hr = ITextRange_SetFont(range, font2);
+  ok(hr == S_OK, "got 0x%08x\n", hr);
+  EXPECT_REF(range2, 2);
+  EXPECT_REF(range, 2);
+
+  /* originaly range 0-4 is non-italic */
+  value = tomTrue;
+  hr = ITextFont_GetItalic(font, &value);
+  ok(hr == S_OK, "got 0x%08x\n", hr);
+  ok(value == tomFalse, "got %d\n", value);
+
+  /* set range 5-2 to italic, then set this font to range 0-4 */
+  hr = ITextFont_SetItalic(font2, tomTrue);
+  ok(hr == S_OK, "got 0x%08x\n", hr);
+
+  hr = ITextRange_SetFont(range, font2);
+  ok(hr == S_OK, "got 0x%08x\n", hr);
+
+  value = tomFalse;
+  hr = ITextFont_GetItalic(font, &value);
+  ok(hr == S_OK, "got 0x%08x\n", hr);
+  ok(value == tomTrue, "got %d\n", value);
+
+  release_interfaces(&hwnd, &reOle, &doc, NULL);
+
+  hr = ITextRange_SetFont(range, NULL);
+  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+  hr = ITextRange_SetFont(range, font);
+  ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
+
+  hr = ITextSelection_SetFont(selection, NULL);
+  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+  hr = ITextSelection_SetFont(selection, font);
+  ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
+
+  ITextFont_Release(font);
+  ITextFont_Release(font2);
+  ITextRange_Release(range);
+  ITextRange_Release(range2);
+  ITextSelection_Release(selection);
+}
+
 START_TEST(richole)
 {
   /* Must explicitly LoadLibrary(). The test has no references to functions in
@@ -2954,4 +3041,5 @@ START_TEST(richole)
   test_ITextRange_IsEqual();
   test_Select();
   test_GetStoryType();
+  test_SetFont();
 }




More information about the wine-cvs mailing list