Huw Davies : riched20: Simplify selection painting by drawing a selected run twice with appropriate clipping .

Alexandre Julliard julliard at winehq.org
Thu Feb 14 15:01:32 CST 2013


Module: wine
Branch: master
Commit: ab6bb56988c000c44c2bcf38aa77eb7baa23ca55
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ab6bb56988c000c44c2bcf38aa77eb7baa23ca55

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Feb 14 14:16:23 2013 +0000

riched20: Simplify selection painting by drawing a selected run twice with appropriate clipping.

---

 dlls/riched20/paint.c |  118 +++++++++++++++++++++++++------------------------
 1 files changed, 60 insertions(+), 58 deletions(-)

diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index af93869..e4bd9e6 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -305,89 +305,91 @@ static void get_selection_rect( ME_Context *c, ME_Run *run, int from, int to, in
     return;
 }
 
+
+static void draw_text( ME_Context *c, ME_Run *run, int x, int y, const WCHAR *text, BOOL selected, RECT *sel_rect )
+{
+    COLORREF text_color = get_text_color( c, run->style, selected );
+    COLORREF back_color = selected ? ITextHost_TxGetSysColor( c->editor->texthost, COLOR_HIGHLIGHT ) : 0;
+    COLORREF old_text, old_back;
+    HPEN pen;
+
+    old_text = SetTextColor( c->hDC, text_color );
+    if (selected) old_back = SetBkColor( c->hDC, back_color );
+
+    ExtTextOutW( c->hDC, x, y, selected ? ETO_OPAQUE : 0, sel_rect, text, run->len, NULL );
+
+    if (selected) SetBkColor( c->hDC, old_back );
+    SetTextColor( c->hDC, old_text );
+
+    get_underline_pen( run->style, text_color, &pen );
+    if (pen)
+    {
+        HPEN old_pen = SelectObject( c->hDC, pen );
+        MoveToEx( c->hDC, x, y + 1, NULL );
+        LineTo( c->hDC, x + run->nWidth, y + 1 );
+        SelectObject( c->hDC, old_pen );
+        DeleteObject( pen );
+    }
+
+    return;
+}
+
+
 static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y, LPCWSTR szText,
                                  int nSelFrom, int nSelTo, int ymin, int cy)
 {
   HDC hDC = c->hDC;
   HGDIOBJ hOldFont;
-  COLORREF rgbOld;
   int yOffset = 0;
-  COLORREF      rgb;
-  HPEN hPen = NULL, hOldPen = NULL;
-  BOOL bHighlightedText = (nSelFrom < run->len && nSelTo >= 0
-                           && nSelFrom < nSelTo && !c->editor->bHideSelection);
+  BOOL selected = (nSelFrom < run->len && nSelTo >= 0
+                   && nSelFrom < nSelTo && !c->editor->bHideSelection);
+  BOOL old_style_selected = FALSE;
   RECT sel_rect;
+  HRGN clip = NULL, sel_rgn = NULL;
 
   yOffset = calc_y_offset( c, run->style );
 
-  rgb = get_text_color( c, run->style, FALSE );
-
-  if (bHighlightedText)
+  if (selected)
   {
     nSelFrom = max( 0, nSelFrom );
     nSelTo = min( run->len, nSelTo );
     get_selection_rect( c, run, nSelFrom, nSelTo, cy, &sel_rect );
     OffsetRect( &sel_rect, x, ymin );
-  }
-
-  hOldFont = ME_SelectStyleFont(c, run->style);
 
-  get_underline_pen( run->style, rgb, &hPen );
-  if (hPen) hOldPen = SelectObject( hDC, hPen );
-
-  rgbOld = SetTextColor(hDC, rgb);
-  if (bHighlightedText && !c->editor->bEmulateVersion10)
-  {
-    COLORREF rgbBackOld;
-    /* FIXME: should use textmetrics info for Descent info */
-    if (hPen)
-      MoveToEx(hDC, x, y - yOffset + 1, NULL);
-    if (sel_rect.left > x)
+    if (c->editor->bEmulateVersion10)
     {
-      ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nSelFrom, NULL);
-      if (hPen)
-        LineTo(hDC, sel_rect.left, y - yOffset + 1);
+      old_style_selected = TRUE;
+      selected = FALSE;
     }
-    SetTextColor( hDC, get_text_color( c, run->style, TRUE ) );
-    rgbBackOld = SetBkColor(hDC, ITextHost_TxGetSysColor(c->editor->texthost,
-                                                         COLOR_HIGHLIGHT));
-    ExtTextOutW(hDC, sel_rect.left, y-yOffset, ETO_OPAQUE, &sel_rect,
-                szText+nSelFrom, nSelTo-nSelFrom, NULL);
-    if (hPen)
-      LineTo(hDC, sel_rect.right, y - yOffset + 1);
-    SetBkColor(hDC, rgbBackOld);
-    if (sel_rect.right < x + run->nWidth)
+    else
     {
-      SetTextColor(hDC, rgb);
-      ExtTextOutW(hDC, sel_rect.right, y-yOffset, 0, NULL, szText+nSelTo,
-                  run->len - nSelTo, NULL);
-      if (hPen)
-        LineTo(hDC, x + run->nWidth, y - yOffset + 1);
+      sel_rgn = CreateRectRgnIndirect( &sel_rect );
+      clip = CreateRectRgn( 0, 0, 0, 0 );
+      if (GetClipRgn( hDC, clip ) != 1)
+      {
+        DeleteObject( clip );
+        clip = NULL;
+      }
     }
   }
-  else
-  {
-    ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, run->len, NULL);
 
-    /* FIXME: should use textmetrics info for Descent info */
-    if (hPen)
-    {
-      MoveToEx(hDC, x, y - yOffset + 1, NULL);
-      LineTo(hDC, x + run->nWidth, y - yOffset + 1);
-    }
-
-    if (bHighlightedText) /* v1.0 inverts the selection */
-    {
-      PatBlt(hDC, sel_rect.left, ymin, sel_rect.right - sel_rect.left, cy, DSTINVERT);
-    }
-  }
+  hOldFont = ME_SelectStyleFont( c, run->style );
 
-  if (hPen)
+  if (sel_rgn) ExtSelectClipRgn( hDC, sel_rgn, RGN_DIFF );
+  draw_text( c, run, x, y - yOffset, szText, FALSE, NULL );
+  if (sel_rgn)
   {
-    SelectObject(hDC, hOldPen);
-    DeleteObject(hPen);
+    ExtSelectClipRgn( hDC, clip, RGN_COPY );
+    ExtSelectClipRgn( hDC, sel_rgn, RGN_AND );
+    draw_text( c, run, x, y - yOffset, szText, TRUE, &sel_rect );
+    ExtSelectClipRgn( hDC, clip, RGN_COPY );
+    if (clip) DeleteObject( clip );
+    DeleteObject( sel_rgn );
   }
-  SetTextColor(hDC, rgbOld);
+
+  if (old_style_selected)
+    PatBlt( hDC, sel_rect.left, ymin, sel_rect.right - sel_rect.left, cy, DSTINVERT );
+
   ME_UnselectStyleFont(c, run->style, hOldFont);
 }
 




More information about the wine-cvs mailing list