Huw Davies : gdi32: Draw single pixel wide, horizontal or vertical lines with the dib driver.

Alexandre Julliard julliard at winehq.org
Thu Apr 7 11:16:42 CDT 2011


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Apr  7 13:49:33 2011 +0100

gdi32: Draw single pixel wide, horizontal or vertical lines with the dib driver.

---

 dlls/gdi32/Makefile.in       |    1 +
 dlls/gdi32/clipping.c        |   13 -----------
 dlls/gdi32/dibdrv/dc.c       |    2 +-
 dlls/gdi32/dibdrv/dibdrv.h   |    6 +++++
 dlls/gdi32/dibdrv/graphics.c |   47 ++++++++++++++++++++++++++++++++++++++++
 dlls/gdi32/dibdrv/objects.c  |   49 ++++++++++++++++++++++++++++++++++++++++++
 dlls/gdi32/gdi_private.h     |    9 +++++++
 7 files changed, 113 insertions(+), 14 deletions(-)

diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in
index 4b070ac..6a04742 100644
--- a/dlls/gdi32/Makefile.in
+++ b/dlls/gdi32/Makefile.in
@@ -15,6 +15,7 @@ C_SRCS = \
 	dc.c \
 	dib.c \
 	dibdrv/dc.c \
+	dibdrv/graphics.c \
 	dibdrv/objects.c \
 	dibdrv/primitives.c \
 	driver.c \
diff --git a/dlls/gdi32/clipping.c b/dlls/gdi32/clipping.c
index 9d529ac..86b19f1 100644
--- a/dlls/gdi32/clipping.c
+++ b/dlls/gdi32/clipping.c
@@ -30,19 +30,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipping);
 
 
 /***********************************************************************
- *           get_clip_region
- *
- * Return the total clip region (if any).
- */
-static inline HRGN get_clip_region( DC * dc )
-{
-    if (dc->hMetaClipRgn) return dc->hMetaClipRgn;
-    if (dc->hMetaRgn) return dc->hMetaRgn;
-    return dc->hClipRgn;
-}
-
-
-/***********************************************************************
  *           get_clip_rect
  *
  * Compute a clip rectangle from its logical coordinates.
diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index 1a16260..78248dd 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -192,7 +192,7 @@ const DC_FUNCTIONS dib_driver =
     NULL,                               /* pGetTextMetrics */
     NULL,                               /* pIntersectClipRect */
     NULL,                               /* pInvertRgn */
-    NULL,                               /* pLineTo */
+    dibdrv_LineTo,                      /* pLineTo */
     NULL,                               /* pModifyWorldTransform */
     NULL,                               /* pMoveTo */
     NULL,                               /* pOffsetClipRgn */
diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index 2620e38..b7408ac 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+extern BOOL     CDECL dibdrv_LineTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
 extern HPEN     CDECL dibdrv_SelectPen( PHYSDEV dev, HPEN hpen ) DECLSPEC_HIDDEN;
 extern COLORREF CDECL dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
 
@@ -26,6 +27,11 @@ static inline dibdrv_physdev *get_dibdrv_pdev( PHYSDEV dev )
     return (dibdrv_physdev *)dev;
 }
 
+static inline DC *get_dibdrv_dc( PHYSDEV dev )
+{
+    return CONTAINING_RECORD( dev, DC, dibdrv );
+}
+
 typedef struct primitive_funcs
 {
     void        (* solid_rects)(const dib_info *dib, int num, RECT *rc, DWORD and, DWORD xor);
diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c
new file mode 100644
index 0000000..1e0de2f
--- /dev/null
+++ b/dlls/gdi32/dibdrv/graphics.c
@@ -0,0 +1,47 @@
+/*
+ * DIB driver graphics operations.
+ *
+ * Copyright 2011 Huw Davies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "gdi_private.h"
+#include "dibdrv.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dib);
+
+/***********************************************************************
+ *           dibdrv_LineTo
+ */
+BOOL CDECL dibdrv_LineTo( PHYSDEV dev, INT x, INT y )
+{
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pLineTo );
+    dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
+    POINT pts[2];
+
+    GetCurrentPositionEx(dev->hdc, pts);
+    pts[1].x = x;
+    pts[1].y = y;
+
+    LPtoDP(dev->hdc, pts, 2);
+
+    if(pdev->defer || !pdev->pen_line(pdev, pts, pts + 1))
+        return next->funcs->pLineTo( next, x, y );
+
+    return TRUE;
+}
diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index 88c9581..a26785a 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -89,6 +89,54 @@ void calc_and_xor_masks(INT rop, DWORD color, DWORD *and, DWORD *xor)
     *xor = (color & rop2_xor_array[rop-1][0]) | ((~color) & rop2_xor_array[rop-1][1]);
 }
 
+static inline void order_end_points(int *s, int *e)
+{
+    if(*s > *e)
+    {
+        int tmp;
+        tmp = *s + 1;
+        *s = *e + 1;
+        *e = tmp;
+    }
+}
+
+static inline BOOL pt_in_rect( const RECT *rect, POINT pt )
+{
+    return ((pt.x >= rect->left) && (pt.x < rect->right) &&
+            (pt.y >= rect->top) && (pt.y < rect->bottom));
+}
+
+static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end)
+{
+    RECT rc;
+    DC *dc = get_dibdrv_dc( &pdev->dev );
+
+    if(get_clip_region(dc) || !pt_in_rect(&dc->vis_rect, *start) || !pt_in_rect(&dc->vis_rect, *end))
+        return FALSE;
+
+    rc.left   = start->x;
+    rc.top    = start->y;
+    rc.right  = end->x;
+    rc.bottom = end->y;
+
+    if(rc.top == rc.bottom)
+    {
+        order_end_points(&rc.left, &rc.right);
+        rc.bottom++;
+        pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rc, pdev->pen_and, pdev->pen_xor);
+        return TRUE;
+    }
+    else if(rc.left == rc.right)
+    {
+        order_end_points(&rc.top, &rc.bottom);
+        rc.right++;
+        pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rc, pdev->pen_and, pdev->pen_xor);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
 /***********************************************************************
  *           dibdrv_SelectPen
  */
@@ -133,6 +181,7 @@ HPEN CDECL dibdrv_SelectPen( PHYSDEV dev, HPEN hpen )
     case PS_SOLID:
         if(logpen.lopnStyle & PS_GEOMETRIC) break;
         if(logpen.lopnWidth.x > 1) break;
+        pdev->pen_line = solid_pen_line;
         pdev->defer &= ~DEFER_PEN;
         break;
     default:
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 9a81afd..fc86b32 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -101,6 +101,7 @@ typedef struct dibdrv_physdev
 
     /* pen */
     DWORD pen_color, pen_and, pen_xor;
+    BOOL   (* pen_line)(struct dibdrv_physdev *pdev, POINT *start, POINT *end);
 } dibdrv_physdev;
 
 #define DEFER_FORMAT     1
@@ -399,6 +400,14 @@ extern INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp ) DECLSPEC_HIDDEN;
 /* clipping.c */
 extern void CLIPPING_UpdateGCRegion( DC * dc ) DECLSPEC_HIDDEN;
 
+/* Return the total clip region (if any) */
+static inline HRGN get_clip_region( DC * dc )
+{
+    if (dc->hMetaClipRgn) return dc->hMetaClipRgn;
+    if (dc->hMetaRgn) return dc->hMetaRgn;
+    return dc->hClipRgn;
+}
+
 /* dc.c */
 extern DC *alloc_dc_ptr( WORD magic ) DECLSPEC_HIDDEN;
 extern void free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list