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>
This commit is contained in:
parent
f47aab6167
commit
b241276f50
|
@ -533,7 +533,7 @@ void ME_RTFCharAttrHook(RTF_Info *info)
|
||||||
ME_Style *style2;
|
ME_Style *style2;
|
||||||
RTFFlushOutputBuffer(info);
|
RTFFlushOutputBuffer(info);
|
||||||
/* FIXME too slow ? how come ? */
|
/* FIXME too slow ? how come ? */
|
||||||
style2 = ME_ApplyStyle(info->style, &fmt);
|
style2 = ME_ApplyStyle(info->editor, info->style, &fmt);
|
||||||
ME_ReleaseStyle(info->style);
|
ME_ReleaseStyle(info->style);
|
||||||
info->style = style2;
|
info->style = style2;
|
||||||
info->styleChanged = TRUE;
|
info->styleChanged = TRUE;
|
||||||
|
@ -2920,6 +2920,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10, DWORD
|
||||||
|
|
||||||
ed->wheel_remain = 0;
|
ed->wheel_remain = 0;
|
||||||
|
|
||||||
|
list_init( &ed->style_list );
|
||||||
OleInitialize(NULL);
|
OleInitialize(NULL);
|
||||||
|
|
||||||
return ed;
|
return ed;
|
||||||
|
@ -2929,6 +2930,7 @@ void ME_DestroyEditor(ME_TextEditor *editor)
|
||||||
{
|
{
|
||||||
ME_DisplayItem *pFirst = editor->pBuffer->pFirst;
|
ME_DisplayItem *pFirst = editor->pBuffer->pFirst;
|
||||||
ME_DisplayItem *p = pFirst, *pNext = NULL;
|
ME_DisplayItem *p = pFirst, *pNext = NULL;
|
||||||
|
ME_Style *s, *cursor2;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ME_ClearTempStyle(editor);
|
ME_ClearTempStyle(editor);
|
||||||
|
@ -2938,6 +2940,10 @@ void ME_DestroyEditor(ME_TextEditor *editor)
|
||||||
ME_DestroyDisplayItem(p);
|
ME_DestroyDisplayItem(p);
|
||||||
p = pNext;
|
p = pNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY_SAFE( s, cursor2, &editor->style_list, ME_Style, entry )
|
||||||
|
ME_DestroyStyle( s );
|
||||||
|
|
||||||
ME_ReleaseStyle(editor->pBuffer->pDefaultStyle);
|
ME_ReleaseStyle(editor->pBuffer->pDefaultStyle);
|
||||||
for (i=0; i<HFONT_CACHE_SIZE; i++)
|
for (i=0; i<HFONT_CACHE_SIZE; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,9 +69,10 @@ static inline const char *debugstr_run( const ME_Run *run )
|
||||||
/* style.c */
|
/* style.c */
|
||||||
ME_Style *ME_MakeStyle(CHARFORMAT2W *style) DECLSPEC_HIDDEN;
|
ME_Style *ME_MakeStyle(CHARFORMAT2W *style) DECLSPEC_HIDDEN;
|
||||||
void ME_AddRefStyle(ME_Style *item) 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;
|
void ME_ReleaseStyle(ME_Style *item) DECLSPEC_HIDDEN;
|
||||||
ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) 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;
|
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_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont) DECLSPEC_HIDDEN;
|
||||||
void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN;
|
void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -78,6 +78,7 @@ typedef struct tagME_Style
|
||||||
TEXTMETRICW tm; /* cached font metrics for the style */
|
TEXTMETRICW tm; /* cached font metrics for the style */
|
||||||
int nRefs; /* reference count */
|
int nRefs; /* reference count */
|
||||||
SCRIPT_CACHE script_cache;
|
SCRIPT_CACHE script_cache;
|
||||||
|
struct list entry;
|
||||||
} ME_Style;
|
} ME_Style;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -444,6 +445,7 @@ typedef struct tagME_TextEditor
|
||||||
|
|
||||||
BOOL bMouseCaptured;
|
BOOL bMouseCaptured;
|
||||||
int wheel_remain;
|
int wheel_remain;
|
||||||
|
struct list style_list;
|
||||||
} ME_TextEditor;
|
} ME_TextEditor;
|
||||||
|
|
||||||
typedef struct tagME_Context
|
typedef struct tagME_Context
|
||||||
|
|
|
@ -695,7 +695,7 @@ void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
|
||||||
ME_Style *s;
|
ME_Style *s;
|
||||||
if (!editor->pBuffer->pCharStyle)
|
if (!editor->pBuffer->pCharStyle)
|
||||||
editor->pBuffer->pCharStyle = ME_GetInsertStyle(editor, 0);
|
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);
|
ME_ReleaseStyle(editor->pBuffer->pCharStyle);
|
||||||
editor->pBuffer->pCharStyle = s;
|
editor->pBuffer->pCharStyle = s;
|
||||||
} else {
|
} 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 ))
|
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,
|
add_undo_set_char_fmt( editor, run->member.run.para->nCharOfs + run->member.run.nCharOfs,
|
||||||
run->member.run.len, &run->member.run.style->fmt );
|
run->member.run.len, &run->member.run.style->fmt );
|
||||||
|
|
|
@ -150,21 +150,22 @@ ME_Style *ME_MakeStyle(CHARFORMAT2W *style)
|
||||||
memset(&s->tm, 0, sizeof(s->tm));
|
memset(&s->tm, 0, sizeof(s->tm));
|
||||||
s->tm.tmAscent = -1;
|
s->tm.tmAscent = -1;
|
||||||
s->script_cache = NULL;
|
s->script_cache = NULL;
|
||||||
|
list_init(&s->entry);
|
||||||
all_refs++;
|
all_refs++;
|
||||||
TRACE_(richedit_style)("ME_MakeStyle %p, total refs=%d\n", s, all_refs);
|
TRACE_(richedit_style)("ME_MakeStyle %p, total refs=%d\n", s, all_refs);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COPY_STYLE_ITEM(mask, member) \
|
#define COPY_STYLE_ITEM(mask, member) \
|
||||||
if (style->dwMask & mask) { \
|
if (mod->dwMask & mask) { \
|
||||||
s->fmt.dwMask |= mask;\
|
fmt.dwMask |= mask;\
|
||||||
s->fmt.member = style->member;\
|
fmt.member = mod->member;\
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COPY_STYLE_ITEM_MEMCPY(mask, member) \
|
#define COPY_STYLE_ITEM_MEMCPY(mask, member) \
|
||||||
if (style->dwMask & mask) { \
|
if (mod->dwMask & mask) { \
|
||||||
s->fmt.dwMask |= mask;\
|
fmt.dwMask |= mask;\
|
||||||
CopyMemory(s->fmt.member, style->member, sizeof(style->member));\
|
CopyMemory(fmt.member, mod->member, sizeof(mod->member));\
|
||||||
}
|
}
|
||||||
|
|
||||||
void ME_InitCharFormat2W(CHARFORMAT2W *pFmt)
|
void ME_InitCharFormat2W(CHARFORMAT2W *pFmt)
|
||||||
|
@ -173,10 +174,12 @@ void ME_InitCharFormat2W(CHARFORMAT2W *pFmt)
|
||||||
pFmt->cbSize = sizeof(CHARFORMAT2W);
|
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);
|
CHARFORMAT2W fmt = sSrc->fmt;
|
||||||
assert(style->cbSize == sizeof(CHARFORMAT2W));
|
ME_Style *s;
|
||||||
|
|
||||||
|
assert(mod->cbSize == sizeof(CHARFORMAT2W));
|
||||||
COPY_STYLE_ITEM(CFM_ANIMATION, bAnimation);
|
COPY_STYLE_ITEM(CFM_ANIMATION, bAnimation);
|
||||||
COPY_STYLE_ITEM(CFM_BACKCOLOR, crBackColor);
|
COPY_STYLE_ITEM(CFM_BACKCOLOR, crBackColor);
|
||||||
COPY_STYLE_ITEM(CFM_CHARSET, bCharSet);
|
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_LCID, lcid);
|
||||||
COPY_STYLE_ITEM(CFM_OFFSET, yOffset);
|
COPY_STYLE_ITEM(CFM_OFFSET, yOffset);
|
||||||
COPY_STYLE_ITEM(CFM_REVAUTHOR, bRevAuthor);
|
COPY_STYLE_ITEM(CFM_REVAUTHOR, bRevAuthor);
|
||||||
if (style->dwMask & CFM_SIZE) {
|
if (mod->dwMask & CFM_SIZE) {
|
||||||
s->fmt.dwMask |= CFM_SIZE;
|
fmt.dwMask |= CFM_SIZE;
|
||||||
s->fmt.yHeight = min(style->yHeight, yHeightCharPtsMost * 20);
|
fmt.yHeight = min(mod->yHeight, yHeightCharPtsMost * 20);
|
||||||
}
|
}
|
||||||
COPY_STYLE_ITEM(CFM_SPACING, sSpacing);
|
COPY_STYLE_ITEM(CFM_SPACING, sSpacing);
|
||||||
COPY_STYLE_ITEM(CFM_STYLE, sStyle);
|
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 */
|
/* FIXME: this is not documented this way, but that's the more logical */
|
||||||
COPY_STYLE_ITEM(CFM_FACE, bPitchAndFamily);
|
COPY_STYLE_ITEM(CFM_FACE, bPitchAndFamily);
|
||||||
|
|
||||||
s->fmt.dwEffects &= ~(style->dwMask);
|
fmt.dwEffects &= ~(mod->dwMask);
|
||||||
s->fmt.dwEffects |= style->dwEffects & style->dwMask;
|
fmt.dwEffects |= mod->dwEffects & mod->dwMask;
|
||||||
s->fmt.dwMask |= style->dwMask;
|
fmt.dwMask |= mod->dwMask;
|
||||||
if (style->dwMask & CFM_COLOR)
|
if (mod->dwMask & CFM_COLOR)
|
||||||
{
|
{
|
||||||
if (style->dwEffects & CFE_AUTOCOLOR)
|
if (mod->dwEffects & CFE_AUTOCOLOR)
|
||||||
s->fmt.dwEffects |= CFE_AUTOCOLOR;
|
fmt.dwEffects |= CFE_AUTOCOLOR;
|
||||||
else
|
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;
|
fmt.dwMask |= CFM_UNDERLINETYPE;
|
||||||
s->fmt.bUnderlineType = (style->dwEffects & CFM_UNDERLINE) ?
|
fmt.bUnderlineType = (mod->dwEffects & CFM_UNDERLINE) ?
|
||||||
CFU_CF1UNDERLINE : CFU_UNDERLINENONE;
|
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;
|
fmt.wWeight = (mod->dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL;
|
||||||
} else if (style->dwMask & CFM_WEIGHT && !(style->dwMask & CFM_BOLD)) {
|
} else if (mod->dwMask & CFM_WEIGHT && !(mod->dwMask & CFM_BOLD)) {
|
||||||
if (style->wWeight > FW_NORMAL)
|
if (mod->wWeight > FW_NORMAL)
|
||||||
s->fmt.dwEffects |= CFE_BOLD;
|
fmt.dwEffects |= CFE_BOLD;
|
||||||
else
|
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;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,8 +441,9 @@ void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont)
|
||||||
s->font_cache = NULL;
|
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)
|
if (s->font_cache)
|
||||||
{
|
{
|
||||||
release_font_cache( 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;
|
ME_Style *style, *def = editor->pBuffer->pDefaultStyle;
|
||||||
|
|
||||||
assert(mod->cbSize == sizeof(CHARFORMAT2W));
|
assert(mod->cbSize == sizeof(CHARFORMAT2W));
|
||||||
style = ME_ApplyStyle(def, mod);
|
style = ME_ApplyStyle(editor, def, mod);
|
||||||
def->fmt = style->fmt;
|
def->fmt = style->fmt;
|
||||||
def->tm = style->tm;
|
def->tm = style->tm;
|
||||||
if (def->font_cache)
|
if (def->font_cache)
|
||||||
|
|
Loading…
Reference in New Issue