Draw underline and strikeout using Polygon to more closely mimic what Windows does

Dmitry Timoshkov dmitry at baikal.ru
Mon Sep 26 02:41:35 CDT 2005


Hello,

my sample program which tests ExtTextOut shows that Windows does not draw
underline and strikeout using a pen, but most likely uses Polygon for that,
and the resulting figure has an outline with parameters of the currently
selected pen. Simultaneously the patch avoids calling GetTextMetricsW
to retrieve the bitmap font metrics and uses the results of the previous
call.

Huw asked me to send these changes separately of the patch which implements
ExtTextOut on an open path.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Draw underline and strikeout using Polygon to more closely mimic
    what Windows does.

--- cvs/hq/wine/dlls/gdi/font.c	2005-09-22 13:31:35.000000000 +0900
+++ wine/dlls/gdi/font.c	2005-09-26 16:18:23.000000000 +0900
@@ -2057,11 +2057,16 @@ done:
         int underlineWidth, strikeoutWidth;
         UINT size = GetOutlineTextMetricsW(hdc, 0, NULL);
         OUTLINETEXTMETRICW* otm = NULL;
+        POINT pts[5];
+        HPEN hpen = 0;
+        HBRUSH hbrush = CreateSolidBrush(GetTextColor(hdc));
+
+        hbrush = SelectObject(hdc, hbrush);
+        if (!PATH_IsPathOpen(dc->path))
+            hpen = SelectObject(hdc, GetStockObject(NULL_PEN));
 
         if(!size)
         {
-            TEXTMETRICW tm;
-            GetTextMetricsW(hdc, &tm);
             underlinePos = 0;
             underlineWidth = tm.tmAscent / 20 + 1;
             strikeoutPos = tm.tmAscent / 2;
@@ -2080,35 +2085,39 @@ done:
 
         if(lf.lfUnderline)
         {
-            POINT pts[2], oldpt;
-            HPEN hpen = CreatePen(PS_SOLID, underlineWidth, GetTextColor(hdc));
-            hpen = SelectObject(hdc, hpen);
-            pts[0].x = x;
-            pts[0].y = y;
-            pts[1].x = x + xwidth;
-            pts[1].y = y - ywidth;
-            DPtoLP(hdc, pts, 2);
-            MoveToEx(hdc, pts[0].x - underlinePos * sinEsc, pts[0].y - underlinePos * cosEsc, &oldpt);
-            LineTo(hdc, pts[1].x - underlinePos * sinEsc, pts[1].y - underlinePos * cosEsc);
-            MoveToEx(hdc, oldpt.x, oldpt.y, NULL);
-            DeleteObject(SelectObject(hdc, hpen));
+            pts[0].x = x - underlinePos * sinEsc;
+            pts[0].y = y - underlinePos * cosEsc;
+            pts[1].x = x + xwidth - underlinePos * sinEsc;
+            pts[1].y = y - ywidth - underlinePos * cosEsc;
+            pts[2].x = pts[1].x + underlineWidth * sinEsc;
+            pts[2].y = pts[1].y + underlineWidth * cosEsc;
+            pts[3].x = pts[0].x + underlineWidth * sinEsc;
+            pts[3].y = pts[0].y + underlineWidth * cosEsc;
+            pts[4].x = pts[0].x;
+            pts[4].y = pts[0].y;
+            DPtoLP(hdc, pts, 5);
+            Polygon(hdc, pts, 5);
         }
 
         if(lf.lfStrikeOut)
         {
-            POINT pts[2], oldpt;
-            HPEN hpen = CreatePen(PS_SOLID, strikeoutWidth, GetTextColor(hdc));
-            hpen = SelectObject(hdc, hpen);
-            pts[0].x = x;
-            pts[0].y = y;
-            pts[1].x = x + xwidth;
-            pts[1].y = y - ywidth;
-            DPtoLP(hdc, pts, 2);
-            MoveToEx(hdc, pts[0].x - strikeoutPos * sinEsc, pts[0].y - strikeoutPos * cosEsc, &oldpt);
-            LineTo(hdc, pts[1].x - strikeoutPos * sinEsc, pts[1].y - strikeoutPos * cosEsc);
-            MoveToEx(hdc, oldpt.x, oldpt.y, NULL);
-            DeleteObject(SelectObject(hdc, hpen));
+            pts[0].x = x - strikeoutPos * sinEsc;
+            pts[0].y = y - strikeoutPos * cosEsc;
+            pts[1].x = x + xwidth - strikeoutPos * sinEsc;
+            pts[1].y = y - ywidth - strikeoutPos * cosEsc;
+            pts[2].x = pts[1].x + strikeoutWidth * sinEsc;
+            pts[2].y = pts[1].y + strikeoutWidth * cosEsc;
+            pts[3].x = pts[0].x + strikeoutWidth * sinEsc;
+            pts[3].y = pts[0].y + strikeoutWidth * cosEsc;
+            pts[4].x = pts[0].x;
+            pts[4].y = pts[0].y;
+            DPtoLP(hdc, pts, 5);
+            Polygon(hdc, pts, 5);
         }
+
+        if (hpen) SelectObject(hdc, hpen);
+        hbrush = SelectObject(hdc, hbrush);
+        DeleteObject(hbrush);
     }
 
     return ret;






More information about the wine-patches mailing list