From 1c0cf0efb324a72d843dcdf97b056703be387f7c Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 26 May 2015 09:15:40 +0300 Subject: [PATCH] riched20: Implement tomTrackParms/tomCacheParms. --- dlls/riched20/riched_tom.idl | 3 + dlls/riched20/richole.c | 152 +++++++++++++++++++++++++++++----- dlls/riched20/tests/richole.c | 55 +++++++++++- include/tom.idl | 3 + 4 files changed, 189 insertions(+), 24 deletions(-) diff --git a/dlls/riched20/riched_tom.idl b/dlls/riched20/riched_tom.idl index 4cacbe08704..7aab8bb7784 100644 --- a/dlls/riched20/riched_tom.idl +++ b/dlls/riched20/riched_tom.idl @@ -159,6 +159,8 @@ typedef enum tagTomConstants tomPrimaryFooterStory = 9, tomFirstPageHeaderStory = 10, tomFirstPageFooterStory = 11, + + /* ITextFont animation property */ tomNoAnimation = 0, tomLasVegasLights = 1, tomBlinkingBackground = 2, @@ -169,6 +171,7 @@ typedef enum tagTomConstants tomWipeDown = 7, tomWipeRight = 8, tomAnimationMax = 8, + tomLowerCase = 0, tomUpperCase = 1, tomTitleCase = 2, diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c index 016f8708cac..eb803e7a32b 100644 --- a/dlls/riched20/richole.c +++ b/dlls/riched20/richole.c @@ -164,7 +164,8 @@ enum textfont_prop_id { FONT_SUPERSCRIPT, FONT_UNDERLINE, FONT_WEIGHT, - FONT_PROPID_LAST + FONT_PROPID_LAST, + FONT_PROPID_FIRST = FONT_ALLCAPS }; static const DWORD textfont_prop_masks[] = { @@ -235,6 +236,7 @@ typedef struct ITextFontImpl { ITextRange *range; textfont_prop_val props[FONT_PROPID_LAST]; + BOOL get_cache_enabled; } ITextFontImpl; typedef struct ITextParaImpl { @@ -306,18 +308,32 @@ static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, te { switch (propid) { + case FONT_ALLCAPS: + case FONT_ANIMATION: + case FONT_BACKCOLOR: case FONT_BOLD: + case FONT_EMBOSS: case FONT_FORECOLOR: + case FONT_HIDDEN: + case FONT_ENGRAVE: case FONT_ITALIC: + case FONT_KERNING: case FONT_LANGID: + 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_WEIGHT: return left->l == right->l; case FONT_NAME: return !strcmpW(left->str, right->str); + case FONT_POSITION: case FONT_SIZE: + case FONT_SPACING: return left->f == right->f; default: FIXME("unhandled font property %d\n", propid); @@ -329,20 +345,34 @@ static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfo { switch (propid) { + case FONT_ALLCAPS: + case FONT_ANIMATION: + case FONT_BACKCOLOR: case FONT_BOLD: + case FONT_EMBOSS: case FONT_FORECOLOR: + case FONT_HIDDEN: + case FONT_ENGRAVE: case FONT_ITALIC: + case FONT_KERNING: case FONT_LANGID: + 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_WEIGHT: v->l = tomUndefined; return; case FONT_NAME: v->str = NULL; return; + case FONT_POSITION: case FONT_SIZE: + case FONT_SPACING: v->f = tomUndefined; return; default: @@ -369,15 +399,36 @@ static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, switch (propid) { + case FONT_ALLCAPS: + value->l = fmt.dwEffects & CFE_ALLCAPS ? tomTrue : tomFalse; + break; + case FONT_ANIMATION: + value->l = fmt.bAnimation; + break; + case FONT_BACKCOLOR: + value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor; + break; case FONT_BOLD: value->l = fmt.dwEffects & CFE_BOLD ? tomTrue : tomFalse; break; + case FONT_EMBOSS: + value->l = fmt.dwEffects & CFE_EMBOSS ? tomTrue : tomFalse; + break; case FONT_FORECOLOR: value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor; break; + case FONT_HIDDEN: + value->l = fmt.dwEffects & CFE_HIDDEN ? tomTrue : tomFalse; + break; + case FONT_ENGRAVE: + value->l = fmt.dwEffects & CFE_IMPRINT ? tomTrue : tomFalse; + break; case FONT_ITALIC: value->l = fmt.dwEffects & CFE_ITALIC ? tomTrue : tomFalse; break; + case FONT_KERNING: + value->f = fmt.wKerning; + break; case FONT_LANGID: value->l = fmt.lcid; break; @@ -387,9 +438,27 @@ static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, if (!value->str) return E_OUTOFMEMORY; break; + case FONT_OUTLINE: + value->l = fmt.dwEffects & CFE_OUTLINE ? tomTrue : tomFalse; + break; + case FONT_POSITION: + value->f = fmt.yOffset; + break; + case FONT_PROTECTED: + value->l = fmt.dwEffects & CFE_PROTECTED ? tomTrue : tomFalse; + break; + case FONT_SHADOW: + value->l = fmt.dwEffects & CFE_SHADOW ? tomTrue : tomFalse; + break; case FONT_SIZE: value->f = fmt.yHeight; break; + case FONT_SMALLCAPS: + value->l = fmt.dwEffects & CFE_SMALLCAPS ? tomTrue : tomFalse; + break; + case FONT_SPACING: + value->f = fmt.sSpacing; + break; case FONT_STRIKETHROUGH: value->l = fmt.dwEffects & CFE_STRIKEOUT ? tomTrue : tomFalse; break; @@ -402,6 +471,9 @@ static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, case FONT_UNDERLINE: value->l = fmt.dwEffects & CFE_UNDERLINE ? tomTrue : tomFalse; break; + case FONT_WEIGHT: + value->l = fmt.wWeight; + break; default: FIXME("unhandled font property %d\n", propid); return E_FAIL; @@ -425,7 +497,7 @@ static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_i HRESULT hr; /* when font is not attached to any range use cached values */ - if (!font->range) { + if (!font->range || font->get_cache_enabled) { *value = font->props[propid]; return S_OK; } @@ -484,6 +556,33 @@ static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_ return hr; } +static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret) +{ + const IRichEditOleImpl *reole; + textfont_prop_val v; + HRESULT hr; + LONG start; + + if (!(reole = get_range_reole(range))) + return CO_E_RELEASED; + + ITextRange_GetStart(range, &start); + hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v); + *ret = v.str; + return hr; +} + +static void textfont_cache_range_props(ITextFontImpl *font) +{ + enum textfont_prop_id propid; + for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) { + if (propid == FONT_NAME) + textfont_getname_from_range(font->range, &font->props[propid].str); + else + get_textfont_prop(font, propid, &font->props[propid]); + } +} + static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj) { IRichEditOleImpl *This = impl_from_IUnknown(iface); @@ -1989,7 +2088,7 @@ static void textfont_reset_to_default(ITextFontImpl *font) { enum textfont_prop_id id; - for (id = FONT_ALLCAPS; id < FONT_PROPID_LAST; id++) { + for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) { switch (id) { case FONT_ALLCAPS: @@ -2041,7 +2140,7 @@ static void textfont_reset_to_undefined(ITextFontImpl *font) { enum textfont_prop_id id; - for (id = FONT_ALLCAPS; id < FONT_PROPID_LAST; id++) { + for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) { switch (id) { case FONT_ALLCAPS: @@ -2091,8 +2190,22 @@ static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value) if (!get_range_reole(This->range)) return CO_E_RELEASED; - if (value == tomUndefined) + switch (value) + { + case tomUndefined: return E_INVALIDARG; + case tomCacheParms: + textfont_cache_range_props(This); + This->get_cache_enabled = TRUE; + break; + case tomTrackParms: + This->get_cache_enabled = FALSE; + break; + default: + FIXME("reset mode %d not supported\n", value); + } + + return S_OK; } else { switch (value) @@ -2105,6 +2218,11 @@ static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value) case tomUndefined: textfont_reset_to_undefined(This); return S_OK; + case tomApplyNow: + case tomApplyLater: + case tomTrackParms: + case tomCacheParms: + return S_OK; } } @@ -2283,10 +2401,6 @@ static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value) static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value) { ITextFontImpl *This = impl_from_ITextFont(iface); - const IRichEditOleImpl *reole; - textfont_prop_val v; - LONG start; - HRESULT hr; TRACE("(%p)->(%p)\n", This, value); @@ -2303,18 +2417,7 @@ static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value) return *value ? S_OK : E_OUTOFMEMORY; } - if (!(reole = get_range_reole(This->range))) - return CO_E_RELEASED; - - init_textfont_prop_value(FONT_NAME, &v); - - ITextRange_GetStart(This->range, &start); - hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v); - if (FAILED(hr)) - return hr; - - *value = v.str; - return S_OK; + return textfont_getname_from_range(This->range, value); } static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value) @@ -2571,6 +2674,7 @@ static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITex if (src) { font->range = NULL; + font->get_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); @@ -2578,8 +2682,10 @@ static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITex else { font->range = range; ITextRange_AddRef(range); - /* FIXME: copy current range attributes to a cache */ - memset(&font->props, 0, sizeof(font->props)); + + /* cache current properties */ + font->get_cache_enabled = FALSE; + textfont_cache_range_props(font); } *ret = &font->ITextFont_iface; diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c index 3389112fa8b..72cb1db967f 100644 --- a/dlls/riched20/tests/richole.c +++ b/dlls/riched20/tests/richole.c @@ -2200,7 +2200,23 @@ static void test_ITextFont(void) hr = ITextFont_GetDuplicate(font2, &font3); ok(hr == S_OK, "got 0x%08x\n", hr); - test_textfont_global_defaults(font3); + test_textfont_global_defaults(font2); + + hr = ITextFont_Reset(font2, tomApplyNow); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_global_defaults(font2); + + hr = ITextFont_Reset(font2, tomApplyLater); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_global_defaults(font2); + + hr = ITextFont_Reset(font2, tomTrackParms); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_global_defaults(font2); + + hr = ITextFont_Reset(font2, tomCacheParms); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_global_defaults(font2); ITextFont_Release(font3); ITextFont_Release(font2); @@ -2239,6 +2255,43 @@ static void test_ITextFont(void) ok(hr == S_OK, "got 0x%08x\n", hr); ok(value != tomUndefined, "got %d\n", value); + /* tomCacheParms/tomTrackParms */ + hr = ITextFont_Reset(font, tomCacheParms); + 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); + + memset(&cf, 0, sizeof(cf)); + cf.cbSize = sizeof(CHARFORMAT2A); + cf.dwMask = CFM_ITALIC; + + cf.dwEffects = CFE_ITALIC; + SendMessageA(hwnd, EM_SETSEL, 0, 10); + ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + + /* still cached value */ + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextFont_Reset(font, tomTrackParms); + 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 == tomTrue, "got %d\n", value); + + /* switch back to cache - value retained */ + hr = ITextFont_Reset(font, tomCacheParms); + 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 == tomTrue, "got %d\n", value); + ITextRange_Release(range); ITextFont_Release(font); release_interfaces(&hwnd, &reOle, &doc, NULL); diff --git a/include/tom.idl b/include/tom.idl index 343906d7afc..245a41b323f 100644 --- a/include/tom.idl +++ b/include/tom.idl @@ -146,6 +146,8 @@ typedef enum tagTomConstants tomPrimaryFooterStory = 9, tomFirstPageHeaderStory = 10, tomFirstPageFooterStory = 11, + + /* ITextFont animation property */ tomNoAnimation = 0, tomLasVegasLights = 1, tomBlinkingBackground = 2, @@ -156,6 +158,7 @@ typedef enum tagTomConstants tomWipeDown = 7, tomWipeRight = 8, tomAnimationMax = 8, + tomLowerCase = 0, tomUpperCase = 1, tomTitleCase = 2,