This avoids swapping out the font if the next run uses the same style.
Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/riched20/context.c | 5 ++- dlls/riched20/editor.h | 3 +- dlls/riched20/editstr.h | 2 + dlls/riched20/paint.c | 13 ++---- dlls/riched20/para.c | 4 +- dlls/riched20/run.c | 23 +++++----- dlls/riched20/style.c | 94 +++++++++++++++++++++++------------------ dlls/riched20/wrap.c | 5 +-- 8 files changed, 75 insertions(+), 74 deletions(-)
diff --git a/dlls/riched20/context.c b/dlls/riched20/context.c index 2cdaeff328..66066b39e6 100644 --- a/dlls/riched20/context.c +++ b/dlls/riched20/context.c @@ -27,6 +27,8 @@ void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC) c->pt.x = 0; c->pt.y = 0; c->rcView = editor->rcFormat; + c->current_style = NULL; + c->orig_font = NULL; if (hDC) { c->dpi.cx = GetDeviceCaps(hDC, LOGPIXELSX); c->dpi.cy = GetDeviceCaps(hDC, LOGPIXELSY); @@ -41,5 +43,6 @@ void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
void ME_DestroyContext(ME_Context *c) { - if (c->hDC) ITextHost_TxReleaseDC(c->editor->texthost, c->hDC); + select_style( c, NULL ); + if (c->hDC) ITextHost_TxReleaseDC( c->editor->texthost, c->hDC ); } diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index 800f5882a7..1f033b4187 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -53,8 +53,7 @@ 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_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 select_style(ME_Context *c, ME_Style *s) DECLSPEC_HIDDEN; void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN; void ME_SaveTempStyle(ME_TextEditor *editor, ME_Style *style) DECLSPEC_HIDDEN; void ME_ClearTempStyle(ME_TextEditor *editor) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 2be903b4fd..a2e6f8584b 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -457,6 +457,8 @@ typedef struct tagME_Context RECT rcView; SIZE dpi; int nAvailWidth; + ME_Style *current_style; + HFONT orig_font;
/* those are valid inside ME_WrapTextParagraph and related */ ME_TextEditor *editor; diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index 675e0f7a12..94fe0516bd 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -290,11 +290,10 @@ static void draw_space( ME_Context *c, ME_Run *run, int x, int y, { COLORREF text_color = get_text_color( c, run->style, selected ); COLORREF old_text, old_back; - HFONT old_font = NULL; int y_offset = calc_y_offset( c, run->style ); static const WCHAR space[1] = {' '};
- old_font = ME_SelectStyleFont( c, run->style ); + select_style( c, run->style ); old_text = SetTextColor( hdc, text_color ); if (selected) old_back = SetBkColor( hdc, back_color );
@@ -302,7 +301,6 @@ static void draw_space( ME_Context *c, ME_Run *run, int x, int y,
if (selected) SetBkColor( hdc, old_back ); SetTextColor( hdc, old_text ); - ME_UnselectStyleFont( c, run->style, old_font );
draw_underline( c, run, x, y - y_offset, text_color ); } @@ -370,7 +368,6 @@ static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y, int nSelFrom, int nSelTo, int ymin, int cy) { HDC hDC = c->hDC; - HGDIOBJ hOldFont; int yOffset = 0; BOOL selected = (nSelFrom < run->len && nSelTo >= 0 && nSelFrom < nSelTo && !c->editor->bHideSelection && @@ -403,7 +400,7 @@ static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y, } }
- hOldFont = ME_SelectStyleFont( c, run->style ); + select_style( c, run->style );
if (sel_rgn) ExtSelectClipRgn( hDC, sel_rgn, RGN_DIFF );
@@ -430,8 +427,6 @@ static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y,
if (old_style_selected) PatBlt( hDC, sel_rect.left, ymin, sel_rect.right - sel_rect.left, cy, DSTINVERT ); - - ME_UnselectStyleFont(c, run->style, hOldFont); }
static void ME_DebugWrite(HDC hDC, const POINT *pt, LPCWSTR szText) { @@ -900,13 +895,12 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) static void draw_para_number( ME_Context *c, ME_DisplayItem *p ) { ME_Paragraph *para = &p->member.para; - HFONT old_font; int x, y; COLORREF old_text;
if (para->fmt.wNumbering) { - old_font = ME_SelectStyleFont( c, para->para_num.style ); + select_style( c, para->para_num.style ); old_text = SetTextColor( c->hDC, get_text_color( c, para->para_num.style, FALSE ) );
x = c->pt.x + para->para_num.pt.x; @@ -915,7 +909,6 @@ static void draw_para_number( ME_Context *c, ME_DisplayItem *p ) ExtTextOutW( c->hDC, x, y, 0, NULL, para->para_num.text->szData, para->para_num.text->nLen, NULL );
SetTextColor( c->hDC, old_text ); - ME_UnselectStyleFont( c, para->para_num.style, old_font ); } }
diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index 5b6cf77010..79f83573bf 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -399,7 +399,6 @@ void para_num_init( ME_Context *c, ME_Paragraph *para ) static const WCHAR bullet_font[] = {'S','y','m','b','o','l',0}; static const WCHAR bullet_str[] = {0xb7, 0}; static const WCHAR spaceW[] = {' ', 0}; - HFONT old_font; SIZE sz;
if (para->para_num.style && para->para_num.text) return; @@ -432,12 +431,11 @@ void para_num_init( ME_Context *c, ME_Paragraph *para ) para->para_num.text = ME_MakeStringConst( bullet_str, 1 ); }
- old_font = ME_SelectStyleFont( c, para->para_num.style ); + select_style( c, para->para_num.style ); GetTextExtentPointW( c->hDC, para->para_num.text->szData, para->para_num.text->nLen, &sz ); para->para_num.width = sz.cx; GetTextExtentPointW( c->hDC, spaceW, 1, &sz ); para->para_num.width += sz.cx; - ME_UnselectStyleFont( c, para->para_num.style, old_font ); }
void para_num_clear( struct para_num *pn ) diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index 6772e2f763..b5408320ca 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -459,7 +459,6 @@ int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BO ME_String *mask_text = NULL; WCHAR *str; int fit = 0; - HGDIOBJ hOldFont; SIZE sz, sz2, sz3; if (!run->len || cx <= 0) return 0; @@ -498,7 +497,7 @@ int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BO else str = get_text( run, 0 );
- hOldFont = ME_SelectStyleFont(c, run->style); + select_style(c, run->style); GetTextExtentExPointW(c->hDC, str, run->len, cx, &fit, NULL, &sz); if (closest && fit != run->len) @@ -511,7 +510,6 @@ int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BO
ME_DestroyString( mask_text );
- ME_UnselectStyleFont(c, run->style, hOldFont); return fit; }
@@ -533,15 +531,16 @@ int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest, B */ static void ME_GetTextExtent(ME_Context *c, LPCWSTR szText, int nChars, ME_Style *s, SIZE *size) { - HGDIOBJ hOldFont; - if (c->hDC) { - hOldFont = ME_SelectStyleFont(c, s); - GetTextExtentPoint32W(c->hDC, szText, nChars, size); - ME_UnselectStyleFont(c, s, hOldFont); - } else { - size->cx = 0; - size->cy = 0; - } + if (c->hDC) + { + select_style( c, s ); + GetTextExtentPoint32W( c->hDC, szText, nChars, size ); + } + else + { + size->cx = 0; + size->cy = 0; + } }
/****************************************************************************** diff --git a/dlls/riched20/style.c b/dlls/riched20/style.c index fca0cef6b3..8b9c2126b1 100644 --- a/dlls/riched20/style.c +++ b/dlls/riched20/style.c @@ -366,67 +366,77 @@ static void release_font_cache(ME_FontCacheItem *item) } }
-HFONT ME_SelectStyleFont( ME_Context *c, ME_Style *s ) +void select_style( ME_Context *c, ME_Style *s ) { HFONT old_font; LOGFONTW lf; int i, empty, age = 0x7FFFFFFF; ME_FontCacheItem *item;
- assert( s ); + if (c->current_style == s) return;
- ME_LogFontFromStyle( c, &lf, s ); - - for (i = 0; i < HFONT_CACHE_SIZE; i++) - c->editor->pFontCache[i].nAge++; - for (i = 0, empty = -1, age = 0; i < HFONT_CACHE_SIZE; i++) + if (s) { - item = &c->editor->pFontCache[i]; - if (!item->nRefs) + ME_LogFontFromStyle( c, &lf, s ); + + for (i = 0; i < HFONT_CACHE_SIZE; i++) + c->editor->pFontCache[i].nAge++; + for (i = 0, empty = -1, age = 0; i < HFONT_CACHE_SIZE; i++) { - if (item->nAge > age) + item = &c->editor->pFontCache[i]; + if (!item->nRefs) { - empty = i; - age = item->nAge; + if (item->nAge > age) + { + empty = i; + age = item->nAge; + } } + + if (item->hFont && ME_IsFontEqual( &item->lfSpecs, &lf )) + break; }
- if (item->hFont && ME_IsFontEqual( &item->lfSpecs, &lf )) - break; + if (i < HFONT_CACHE_SIZE) /* found */ + { + item = &c->editor->pFontCache[i]; + TRACE_(richedit_style)( "font reused %d\n", i ); + item->nRefs++; + } + else + { + assert(empty != -1); + item = &c->editor->pFontCache[empty]; + if (item->hFont) + { + TRACE_(richedit_style)( "font deleted %d\n", empty ); + DeleteObject(item->hFont); + item->hFont = NULL; + } + item->hFont = CreateFontIndirectW( &lf ); + TRACE_(richedit_style)( "font created %d\n", empty ); + item->nRefs = 1; + item->lfSpecs = lf; + } + s->font_cache = item; + old_font = SelectObject( c->hDC, item->hFont ); + GetTextMetricsW( c->hDC, &s->tm ); + if (!c->orig_font) c->orig_font = old_font; } - - if (i < HFONT_CACHE_SIZE) /* found */ + else { - item = &c->editor->pFontCache[i]; - TRACE_(richedit_style)( "font reused %d\n", i ); - item->nRefs++; + SelectObject( c->hDC, c->orig_font ); + c->orig_font = NULL; } - else + + if (c->current_style) { - assert(empty != -1); - item = &c->editor->pFontCache[empty]; - if (item->hFont) - { - TRACE_(richedit_style)( "font deleted %d\n", empty ); - DeleteObject(item->hFont); - item->hFont = NULL; - } - item->hFont = CreateFontIndirectW( &lf ); - TRACE_(richedit_style)( "font created %d\n", empty ); - item->nRefs = 1; - item->lfSpecs = lf; + release_font_cache( c->current_style->font_cache ); + c->current_style->font_cache = NULL; } - s->font_cache = item; - old_font = SelectObject( c->hDC, item->hFont ); - GetTextMetricsW( c->hDC, &s->tm ); - return old_font; -} + c->current_style = s;
-void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont) -{ - SelectObject(c->hDC, hOldFont); - release_font_cache(s->font_cache); - s->font_cache = NULL; + return; }
void ME_DestroyStyle(ME_Style *s) diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index a66137d42c..c3b5883dbf 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -65,7 +65,6 @@ static BOOL get_run_glyph_buffers( ME_Run *run ) static HRESULT shape_run( ME_Context *c, ME_Run *run ) { HRESULT hr; - HFONT old_font; int i;
if (!run->glyphs) @@ -82,7 +81,7 @@ static HRESULT shape_run( ME_Context *c, ME_Run *run ) run->clusters = heap_alloc( run->max_clusters * sizeof(WORD) ); }
- old_font = ME_SelectStyleFont( c, run->style ); + select_style( c, run->style ); while (1) { hr = ScriptShape( c->hDC, &run->style->script_cache, get_text( run, 0 ), run->len, run->max_glyphs, @@ -103,8 +102,6 @@ static HRESULT shape_run( ME_Context *c, ME_Run *run ) run->nWidth += run->advances[i]; }
- ME_UnselectStyleFont( c, run->style, old_font ); - return hr; }