Module: wine Branch: master Commit: b241276f50ba38f0e76b3c3645d059b22d30f652 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b241276f50ba38f0e76b3c3645...
Author: Huw Davies huw@codeweavers.com Date: Mon Nov 9 16:11:43 2015 +0000
riched20: Maintain a list of styles and reuse them if possible.
Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/riched20/editor.c | 8 ++++- dlls/riched20/editor.h | 3 +- dlls/riched20/editstr.h | 2 ++ dlls/riched20/run.c | 4 +-- dlls/riched20/style.c | 79 ++++++++++++++++++++++++++++++------------------- 5 files changed, 62 insertions(+), 34 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index ec584eb..bbb0cc0 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -533,7 +533,7 @@ void ME_RTFCharAttrHook(RTF_Info *info) ME_Style *style2; RTFFlushOutputBuffer(info); /* FIXME too slow ? how come ? */ - style2 = ME_ApplyStyle(info->style, &fmt); + style2 = ME_ApplyStyle(info->editor, info->style, &fmt); ME_ReleaseStyle(info->style); info->style = style2; info->styleChanged = TRUE; @@ -2920,6 +2920,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10, DWORD
ed->wheel_remain = 0;
+ list_init( &ed->style_list ); OleInitialize(NULL);
return ed; @@ -2929,6 +2930,7 @@ void ME_DestroyEditor(ME_TextEditor *editor) { ME_DisplayItem *pFirst = editor->pBuffer->pFirst; ME_DisplayItem *p = pFirst, *pNext = NULL; + ME_Style *s, *cursor2; int i;
ME_ClearTempStyle(editor); @@ -2938,6 +2940,10 @@ void ME_DestroyEditor(ME_TextEditor *editor) ME_DestroyDisplayItem(p); p = pNext; } + + LIST_FOR_EACH_ENTRY_SAFE( s, cursor2, &editor->style_list, ME_Style, entry ) + ME_DestroyStyle( s ); + ME_ReleaseStyle(editor->pBuffer->pDefaultStyle); for (i=0; i<HFONT_CACHE_SIZE; i++) { diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index f22f0e6..a63dea6 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -69,9 +69,10 @@ static inline const char *debugstr_run( const ME_Run *run ) /* style.c */ ME_Style *ME_MakeStyle(CHARFORMAT2W *style) DECLSPEC_HIDDEN; void ME_AddRefStyle(ME_Style *item) DECLSPEC_HIDDEN; +void ME_DestroyStyle(ME_Style *item) DECLSPEC_HIDDEN; void ME_ReleaseStyle(ME_Style *item) DECLSPEC_HIDDEN; ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) DECLSPEC_HIDDEN; -ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style) DECLSPEC_HIDDEN; +ME_Style *ME_ApplyStyle(ME_TextEditor *ed, ME_Style *sSrc, CHARFORMAT2W *style) DECLSPEC_HIDDEN; HFONT ME_SelectStyleFont(ME_Context *c, ME_Style *s) DECLSPEC_HIDDEN; void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont) DECLSPEC_HIDDEN; void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 3e98dac..be925db 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -78,6 +78,7 @@ typedef struct tagME_Style TEXTMETRICW tm; /* cached font metrics for the style */ int nRefs; /* reference count */ SCRIPT_CACHE script_cache; + struct list entry; } ME_Style;
typedef enum { @@ -444,6 +445,7 @@ typedef struct tagME_TextEditor
BOOL bMouseCaptured; int wheel_remain; + struct list style_list; } ME_TextEditor;
typedef struct tagME_Context diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index d261213..7016932 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -695,7 +695,7 @@ void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) ME_Style *s; if (!editor->pBuffer->pCharStyle) editor->pBuffer->pCharStyle = ME_GetInsertStyle(editor, 0); - s = ME_ApplyStyle(editor->pBuffer->pCharStyle, pFmt); + s = ME_ApplyStyle(editor, editor->pBuffer->pCharStyle, pFmt); ME_ReleaseStyle(editor->pBuffer->pCharStyle); editor->pBuffer->pCharStyle = s; } else { @@ -753,7 +753,7 @@ void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, C
for (run = start_run; run != end_run; run = ME_FindItemFwd( run, diRun )) { - ME_Style *new_style = ME_ApplyStyle(run->member.run.style, pFmt); + ME_Style *new_style = ME_ApplyStyle(editor, run->member.run.style, pFmt);
add_undo_set_char_fmt( editor, run->member.run.para->nCharOfs + run->member.run.nCharOfs, run->member.run.len, &run->member.run.style->fmt ); diff --git a/dlls/riched20/style.c b/dlls/riched20/style.c index 37f56d9..06c0e6f 100644 --- a/dlls/riched20/style.c +++ b/dlls/riched20/style.c @@ -150,21 +150,22 @@ ME_Style *ME_MakeStyle(CHARFORMAT2W *style) memset(&s->tm, 0, sizeof(s->tm)); s->tm.tmAscent = -1; s->script_cache = NULL; + list_init(&s->entry); all_refs++; TRACE_(richedit_style)("ME_MakeStyle %p, total refs=%d\n", s, all_refs); return s; }
#define COPY_STYLE_ITEM(mask, member) \ - if (style->dwMask & mask) { \ - s->fmt.dwMask |= mask;\ - s->fmt.member = style->member;\ + if (mod->dwMask & mask) { \ + fmt.dwMask |= mask;\ + fmt.member = mod->member;\ }
#define COPY_STYLE_ITEM_MEMCPY(mask, member) \ - if (style->dwMask & mask) { \ - s->fmt.dwMask |= mask;\ - CopyMemory(s->fmt.member, style->member, sizeof(style->member));\ + if (mod->dwMask & mask) { \ + fmt.dwMask |= mask;\ + CopyMemory(fmt.member, mod->member, sizeof(mod->member));\ }
void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) @@ -173,10 +174,12 @@ void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) pFmt->cbSize = sizeof(CHARFORMAT2W); }
-ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style) +ME_Style *ME_ApplyStyle(ME_TextEditor *editor, ME_Style *sSrc, CHARFORMAT2W *mod) { - ME_Style *s = ME_MakeStyle(&sSrc->fmt); - assert(style->cbSize == sizeof(CHARFORMAT2W)); + CHARFORMAT2W fmt = sSrc->fmt; + ME_Style *s; + + assert(mod->cbSize == sizeof(CHARFORMAT2W)); COPY_STYLE_ITEM(CFM_ANIMATION, bAnimation); COPY_STYLE_ITEM(CFM_BACKCOLOR, crBackColor); COPY_STYLE_ITEM(CFM_CHARSET, bCharSet); @@ -186,9 +189,9 @@ ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style) COPY_STYLE_ITEM(CFM_LCID, lcid); COPY_STYLE_ITEM(CFM_OFFSET, yOffset); COPY_STYLE_ITEM(CFM_REVAUTHOR, bRevAuthor); - if (style->dwMask & CFM_SIZE) { - s->fmt.dwMask |= CFM_SIZE; - s->fmt.yHeight = min(style->yHeight, yHeightCharPtsMost * 20); + if (mod->dwMask & CFM_SIZE) { + fmt.dwMask |= CFM_SIZE; + fmt.yHeight = min(mod->yHeight, yHeightCharPtsMost * 20); } COPY_STYLE_ITEM(CFM_SPACING, sSpacing); COPY_STYLE_ITEM(CFM_STYLE, sStyle); @@ -197,31 +200,46 @@ ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style) /* FIXME: this is not documented this way, but that's the more logical */ COPY_STYLE_ITEM(CFM_FACE, bPitchAndFamily);
- s->fmt.dwEffects &= ~(style->dwMask); - s->fmt.dwEffects |= style->dwEffects & style->dwMask; - s->fmt.dwMask |= style->dwMask; - if (style->dwMask & CFM_COLOR) + fmt.dwEffects &= ~(mod->dwMask); + fmt.dwEffects |= mod->dwEffects & mod->dwMask; + fmt.dwMask |= mod->dwMask; + if (mod->dwMask & CFM_COLOR) { - if (style->dwEffects & CFE_AUTOCOLOR) - s->fmt.dwEffects |= CFE_AUTOCOLOR; + if (mod->dwEffects & CFE_AUTOCOLOR) + fmt.dwEffects |= CFE_AUTOCOLOR; else - s->fmt.dwEffects &= ~CFE_AUTOCOLOR; + fmt.dwEffects &= ~CFE_AUTOCOLOR; } - if (style->dwMask & CFM_UNDERLINE) + if (mod->dwMask & CFM_UNDERLINE) { - s->fmt.dwMask |= CFM_UNDERLINETYPE; - s->fmt.bUnderlineType = (style->dwEffects & CFM_UNDERLINE) ? + fmt.dwMask |= CFM_UNDERLINETYPE; + fmt.bUnderlineType = (mod->dwEffects & CFM_UNDERLINE) ? CFU_CF1UNDERLINE : CFU_UNDERLINENONE; } - if (style->dwMask & CFM_BOLD && !(style->dwMask & CFM_WEIGHT)) + if (mod->dwMask & CFM_BOLD && !(mod->dwMask & CFM_WEIGHT)) { - s->fmt.wWeight = (style->dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL; - } else if (style->dwMask & CFM_WEIGHT && !(style->dwMask & CFM_BOLD)) { - if (style->wWeight > FW_NORMAL) - s->fmt.dwEffects |= CFE_BOLD; + fmt.wWeight = (mod->dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL; + } else if (mod->dwMask & CFM_WEIGHT && !(mod->dwMask & CFM_BOLD)) { + if (mod->wWeight > FW_NORMAL) + fmt.dwEffects |= CFE_BOLD; else - s->fmt.dwEffects &= ~CFE_BOLD; + fmt.dwEffects &= ~CFE_BOLD; + } + + LIST_FOR_EACH_ENTRY(s, &editor->style_list, ME_Style, entry) + { + if (!memcmp( &s->fmt, &fmt, sizeof(fmt) )) + { + TRACE_(richedit_style)("found existing style %p\n", s); + ME_AddRefStyle( s ); + return s; + } } + + s = ME_MakeStyle( &fmt ); + if (s) + list_add_head( &editor->style_list, &s->entry ); + TRACE_(richedit_style)("created new style %p\n", s); return s; }
@@ -423,8 +441,9 @@ void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont) s->font_cache = NULL; }
-static void ME_DestroyStyle(ME_Style *s) +void ME_DestroyStyle(ME_Style *s) { + list_remove( &s->entry ); if (s->font_cache) { release_font_cache( s->font_cache ); @@ -524,7 +543,7 @@ void ME_SetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *mod) ME_Style *style, *def = editor->pBuffer->pDefaultStyle;
assert(mod->cbSize == sizeof(CHARFORMAT2W)); - style = ME_ApplyStyle(def, mod); + style = ME_ApplyStyle(editor, def, mod); def->fmt = style->fmt; def->tm = style->tm; if (def->font_cache)