This avoids swapping out the font if the next run uses the same style.
Signed-off-by: Huw Davies <huw(a)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;
}
--
2.18.0