[PATCH 4/6] riched20: Allow the style to remain selected in the context.

Huw Davies huw at codeweavers.com
Mon Aug 19 03:44:51 CDT 2019


This avoids swapping out the font if the next run uses the same style.

Signed-off-by: Huw Davies <huw at 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




More information about the wine-devel mailing list