Alexandre Julliard : gdi32: Implement returning a region for 1-pixel wide solid pen lines.

Alexandre Julliard julliard at winehq.org
Thu Dec 29 12:15:44 CST 2011


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Dec 28 12:21:07 2011 +0100

gdi32: Implement returning a region for 1-pixel wide solid pen lines.

---

 dlls/gdi32/dibdrv/objects.c |  136 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 128 insertions(+), 8 deletions(-)

diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index bf821f2..bb68029 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -631,21 +631,141 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end, DWORD
     return TRUE;
 }
 
+static BOOL solid_pen_line_region( dibdrv_physdev *pdev, POINT *start, POINT *end, HRGN region )
+{
+    RECT rect;
+
+    rect.left   = start->x;
+    rect.top    = start->y;
+    rect.right  = start->x + 1;
+    rect.bottom = start->y + 1;
+
+    if (start->y == end->y)
+    {
+        rect.right = end->x;
+        order_end_points(&rect.left, &rect.right);
+        add_rect_to_region( region, &rect );
+    }
+    else if(start->x == end->x)
+    {
+        rect.bottom = end->y;
+        order_end_points(&rect.top, &rect.bottom);
+        add_rect_to_region( region, &rect );
+    }
+    else
+    {
+        INT dx = end->x - start->x, dy = end->y - start->y;
+        INT abs_dx = abs(dx), abs_dy = abs(dy);
+        DWORD octant = get_octant_mask(dx, dy);
+        INT bias = get_bias( octant );
+
+        if (is_xmajor( octant ))
+        {
+            int y_inc = is_y_increasing( octant ) ? 1 : -1;
+            int err_add_1 = 2 * abs_dy - 2 * abs_dx;
+            int err_add_2 = 2 * abs_dy;
+            int err = 2 * abs_dy - abs_dx;
+
+            if (is_x_increasing( octant ))
+            {
+                for (rect.right = start->x + 1; rect.right <= end->x; rect.right++)
+                {
+                    if (err + bias > 0)
+                    {
+                        add_rect_to_region( region, &rect );
+                        rect.left = rect.right;
+                        rect.top += y_inc;
+                        rect.bottom += y_inc;
+                        err += err_add_1;
+                    }
+                    else err += err_add_2;
+                }
+            }
+            else
+            {
+                for (rect.left = start->x; rect.left > end->x; rect.left--)
+                {
+                    if (err + bias > 0)
+                    {
+                        add_rect_to_region( region, &rect );
+                        rect.right = rect.left;
+                        rect.top += y_inc;
+                        rect.bottom += y_inc;
+                        err += err_add_1;
+                    }
+                    else err += err_add_2;
+                }
+            }
+        }
+        else
+        {
+            int x_inc = is_x_increasing( octant ) ? 1 : -1;
+            int err_add_1 = 2 * abs_dx - 2 * abs_dy;
+            int err_add_2 = 2 * abs_dx;
+            int err = 2 * abs_dx - abs_dy;
+
+            if (is_y_increasing( octant ))
+            {
+                for (rect.bottom = start->y + 1; rect.bottom <= end->y; rect.bottom++)
+                {
+                    if (err + bias > 0)
+                    {
+                        add_rect_to_region( region, &rect );
+                        rect.top = rect.bottom;
+                        rect.left += x_inc;
+                        rect.right += x_inc;
+                        err += err_add_1;
+                    }
+                    else err += err_add_2;
+                }
+            }
+            else
+            {
+                for (rect.top = start->y; rect.top > end->y; rect.top--)
+                {
+                    if (err + bias > 0)
+                    {
+                        add_rect_to_region( region, &rect );
+                        rect.bottom = rect.top;
+                        rect.left += x_inc;
+                        rect.right += x_inc;
+                        err += err_add_1;
+                    }
+                    else err += err_add_2;
+                }
+            }
+        }
+        /* add final rect */
+        add_rect_to_region( region, &rect );
+    }
+    return TRUE;
+}
+
 static BOOL solid_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL close, HRGN region)
 {
     int i;
-    DWORD color, and, xor;
-
-    color = get_pixel_color( pdev, pdev->pen_colorref, TRUE );
-    calc_and_xor_masks( GetROP2(pdev->dev.hdc), color, &and, &xor );
 
     assert( num >= 2 );
-    for (i = 0; i < num - 1; i++)
-        if (!solid_pen_line( pdev, pts + i, pts + i + 1, and, xor ))
-            return FALSE;
 
-    if (close) return solid_pen_line( pdev, pts + num - 1, pts, and, xor );
+    if (region)
+    {
+        for (i = 0; i < num - 1; i++)
+            if (!solid_pen_line_region( pdev, pts + i, pts + i + 1, region ))
+                return FALSE;
+        if (close) return solid_pen_line_region( pdev, pts + num - 1, pts, region );
+    }
+    else
+    {
+        DWORD color, and, xor;
+
+        color = get_pixel_color( pdev, pdev->pen_colorref, TRUE );
+        calc_and_xor_masks( GetROP2(pdev->dev.hdc), color, &and, &xor );
 
+        for (i = 0; i < num - 1; i++)
+            if (!solid_pen_line( pdev, pts + i, pts + i + 1, and, xor ))
+                return FALSE;
+        if (close) return solid_pen_line( pdev, pts + num - 1, pts, and, xor );
+    }
     return TRUE;
 }
 




More information about the wine-cvs mailing list