Huw Davies : gdi32: Add support for drawing diagonal patterned lines.

Alexandre Julliard julliard at winehq.org
Fri May 6 13:44:08 CDT 2011


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Fri May  6 11:58:18 2011 +0100

gdi32: Add support for drawing diagonal patterned lines.

---

 dlls/gdi32/dibdrv/objects.c |   68 +++++++++++++++++++++++++++++++++++++++++--
 dlls/gdi32/tests/dib.c      |   20 ++++++++++++
 2 files changed, 85 insertions(+), 3 deletions(-)

diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index f58d9c2..a0e238e 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -583,6 +583,21 @@ static inline void get_dash_colors(const dibdrv_physdev *pdev, DWORD *and, DWORD
     }
 }
 
+static void dashed_pen_line_callback(dibdrv_physdev *pdev, INT x, INT y)
+{
+    RECT rect;
+    DWORD and, xor;
+
+    get_dash_colors(pdev, &and, &xor);
+    skip_dash(pdev, 1);
+    rect.left   = x;
+    rect.right  = x + 1;
+    rect.top    = y;
+    rect.bottom = y + 1;
+    pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, and, xor);
+    return;
+}
+
 static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end)
 {
     const WINEREGION *clip = get_wine_region(pdev->clip);
@@ -590,7 +605,6 @@ static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end)
     int i, dash_len;
     RECT rect;
     const dash_pos start_pos = pdev->dash_pos;
-    BOOL ret = TRUE;
 
     if(start->y == end->y) /* hline */
     {
@@ -749,11 +763,59 @@ static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end)
     }
     else
     {
-        ret = FALSE;
+        bres_params params;
+        INT dx = end->x - start->x;
+        INT dy = end->y - start->y;
+        INT i;
+
+        params.dx = abs(dx);
+        params.dy = abs(dy);
+        params.octant = get_octant_mask(dx, dy);
+        /* Octants 3, 5, 6 and 8 take a bias */
+        params.bias = (params.octant & 0xb4) ? 1 : 0;
+
+        for(i = 0; i < clip->numRects; i++)
+        {
+            POINT clipped_start, clipped_end;
+            int clip_status;
+            clip_status = clip_line(start, end, clip->rects + i, &params, &clipped_start, &clipped_end);
+
+            if(clip_status)
+            {
+                int m = abs(clipped_start.x - start->x);
+                int n = abs(clipped_start.y - start->y);
+                int err;
+                BOOL last_pt = FALSE;
+
+                pdev->dash_pos = start_pos;
+
+                if(is_xmajor(params.octant))
+                {
+                    err = 2 * params.dy - params.dx + m * 2 * params.dy - n * 2 * params.dx;
+                    skip_dash(pdev, m);
+                }
+                else
+                {
+                    err = 2 * params.dx - params.dy + n * 2 * params.dx - m * 2 * params.dy;
+                    skip_dash(pdev, n);
+                }
+                if(clip_status == 1 && (end->x != clipped_end.x || end->y != clipped_end.y)) last_pt = TRUE;
+
+                bres_line_with_bias(clipped_start.x, clipped_start.y, clipped_end.x, clipped_end.y, &params,
+                                    err, last_pt, dashed_pen_line_callback, pdev);
+
+                if(clip_status == 2) break; /* completely unclipped, so we can finish */
+            }
+        }
+        pdev->dash_pos = start_pos;
+        if(is_xmajor(params.octant))
+            skip_dash(pdev, params.dx);
+        else
+            skip_dash(pdev, params.dy);
     }
 
     release_wine_region(pdev->clip);
-    return ret;
+    return TRUE;
 }
 
 static const dash_pattern dash_patterns[4] =
diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c
index c6b2c90..196cbc5 100644
--- a/dlls/gdi32/tests/dib.c
+++ b/dlls/gdi32/tests/dib.c
@@ -88,6 +88,8 @@ static const char *sha1_graphics_a8r8g8b8[] =
     "c387917268455017aa0b28bed73aa6554044bbb3",
     "dcae44fee010dbf7a107797a503923fd8b1abe2e",
     "6c530622a025d872a642e8f950867884d7b136cb",
+    "7c07d91b8f68fb31821701b3dcb96de018bf0c66",
+    "b2261353decda2712b83538ab434a49ce21f3172",
     NULL
 };
 
@@ -393,6 +395,24 @@ static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sh
     compare_hash(bmi, bits, sha1, "clipped dashed vlines b -> t");
     memset(bits, 0xcc, dib_size);
 
+    for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
+    {
+        MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
+        LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
+    }
+    compare_hash(bmi, bits, sha1, "clipped dashed diagonal lines");
+    memset(bits, 0xcc, dib_size);
+
+    SetBkMode(hdc, OPAQUE);
+
+    for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
+    {
+        MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
+        LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
+    }
+    compare_hash(bmi, bits, sha1, "clipped opaque dashed diagonal lines");
+    memset(bits, 0xcc, dib_size);
+
     ExtSelectClipRgn(hdc, NULL, RGN_COPY);
 
     SelectObject(hdc, orig_brush);




More information about the wine-cvs mailing list