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

This commit is contained in:
Huw Davies 2011-04-07 13:49:33 +01:00 committed by Alexandre Julliard
parent d5d4603062
commit 1e27c95125
7 changed files with 113 additions and 14 deletions

View file

@ -15,6 +15,7 @@ C_SRCS = \
dc.c \
dib.c \
dibdrv/dc.c \
dibdrv/graphics.c \
dibdrv/objects.c \
dibdrv/primitives.c \
driver.c \

View file

@ -29,19 +29,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
*

View file

@ -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 */

View file

@ -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);

View file

@ -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;
}

View file

@ -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:

View file

@ -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;