winex11: Directly use win32u for GDI functions in graphics.c.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-04-12 13:09:50 +02:00 committed by Alexandre Julliard
parent df4ddc30b3
commit 4631b007c1
2 changed files with 79 additions and 48 deletions

View File

@ -75,20 +75,23 @@ static const int X11DRV_XROPfunction[16] =
/* get the rectangle in device coordinates, with optional mirroring */
static RECT get_device_rect( HDC hdc, int left, int top, int right, int bottom )
{
DWORD layout;
RECT rect;
NtGdiGetDCDword( hdc, NtGdiGetLayout, &layout );
rect.left = left;
rect.top = top;
rect.right = right;
rect.bottom = bottom;
if (GetLayout( hdc ) & LAYOUT_RTL)
if (layout & LAYOUT_RTL)
{
/* shift the rectangle so that the right border is included after mirroring */
/* it would be more correct to do this after LPtoDP but that's not what Windows does */
rect.left--;
rect.right--;
}
LPtoDP( hdc, (POINT *)&rect, 2 );
lp_to_dp( hdc, (POINT *)&rect, 2 );
if (rect.left > rect.right)
{
int tmp = rect.left;
@ -157,7 +160,7 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp )
RECT *rect, tmp;
XRectangle *xrect;
if (!(size = GetRegionData( hrgn, 0, NULL ))) return NULL;
if (!(size = NtGdiGetRegionData( hrgn, 0, NULL ))) return NULL;
if (sizeof(XRectangle) > sizeof(RECT))
{
/* add extra size for XRectangle array */
@ -165,7 +168,7 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp )
size += count * (sizeof(XRectangle) - sizeof(RECT));
}
if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL;
if (!GetRegionData( hrgn, size, data ))
if (!NtGdiGetRegionData( hrgn, size, data ))
{
HeapFree( GetProcessHeap(), 0, data );
return NULL;
@ -175,7 +178,7 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp )
xrect = (XRectangle *)data->Buffer;
if (hdc_lptodp) /* map to device coordinates */
{
LPtoDP( hdc_lptodp, (POINT *)rect, data->rdh.nCount * 2 );
lp_to_dp( hdc_lptodp, (POINT *)rect, data->rdh.nCount * 2 );
for (i = 0; i < data->rdh.nCount; i++)
{
if (rect[i].right < rect[i].left)
@ -271,10 +274,10 @@ BOOL add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn )
if (!rgn) return FALSE;
if (dev->region)
{
if (!(clip = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE;
CombineRgn( clip, dev->region, rgn, RGN_AND );
if (!(clip = NtGdiCreateRectRgn( 0, 0, 0, 0 ))) return FALSE;
NtGdiCombineRgn( clip, dev->region, rgn, RGN_AND );
update_x11_clipping( dev, clip );
DeleteObject( clip );
NtGdiDeleteObjectApp( clip );
}
else update_x11_clipping( dev, rgn );
return TRUE;
@ -311,25 +314,31 @@ void CDECL X11DRV_SetDeviceClipping( PHYSDEV dev, HRGN rgn )
*/
BOOL X11DRV_SetupGCForPatBlt( X11DRV_PDEVICE *physDev, GC gc, BOOL fMapColors )
{
DWORD bk_color, text_color, rop_mode, bk_mode, poly_fill_mode;
XGCValues val;
unsigned long mask;
Pixmap pixmap = 0;
POINT pt;
if (physDev->brush.style == BS_NULL) return FALSE;
NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetBkColor, &bk_color );
NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetROP2, &rop_mode );
if (physDev->brush.pixel == -1)
{
/* Special case used for monochrome pattern brushes.
* We need to swap foreground and background because
* Windows does it the wrong way...
*/
val.foreground = X11DRV_PALETTE_ToPhysical( physDev, GetBkColor(physDev->dev.hdc) );
val.background = X11DRV_PALETTE_ToPhysical( physDev, GetTextColor(physDev->dev.hdc) );
NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetTextColor, &text_color );
val.foreground = X11DRV_PALETTE_ToPhysical( physDev, bk_color );
val.background = X11DRV_PALETTE_ToPhysical( physDev, text_color );
}
else
{
val.foreground = physDev->brush.pixel;
val.background = X11DRV_PALETTE_ToPhysical( physDev, GetBkColor(physDev->dev.hdc) );
val.background = X11DRV_PALETTE_ToPhysical( physDev, bk_color );
}
if (fMapColors && X11DRV_PALETTE_XPixelToPalette)
{
@ -337,7 +346,7 @@ BOOL X11DRV_SetupGCForPatBlt( X11DRV_PDEVICE *physDev, GC gc, BOOL fMapColors )
val.background = X11DRV_PALETTE_XPixelToPalette[val.background];
}
val.function = X11DRV_XROPfunction[GetROP2(physDev->dev.hdc)-1];
val.function = X11DRV_XROPfunction[rop_mode - 1];
/*
** Let's replace GXinvert by GXxor with (black xor white)
** This solves the selection color and leak problems in excel
@ -354,7 +363,8 @@ BOOL X11DRV_SetupGCForPatBlt( X11DRV_PDEVICE *physDev, GC gc, BOOL fMapColors )
{
case FillStippled:
case FillOpaqueStippled:
if (GetBkMode(physDev->dev.hdc)==OPAQUE) val.fill_style = FillOpaqueStippled;
NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetBkMode, &bk_mode );
if (bk_mode == OPAQUE) val.fill_style = FillOpaqueStippled;
val.stipple = physDev->brush.pixmap;
mask = GCStipple;
break;
@ -383,10 +393,13 @@ BOOL X11DRV_SetupGCForPatBlt( X11DRV_PDEVICE *physDev, GC gc, BOOL fMapColors )
mask = 0;
break;
}
GetBrushOrgEx( physDev->dev.hdc, &pt );
NtGdiGetDCPoint( physDev->dev.hdc, NtGdiGetBrushOrgEx, &pt );
NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetPolyFillMode, &poly_fill_mode );
val.ts_x_origin = physDev->dc_rect.left + pt.x;
val.ts_y_origin = physDev->dc_rect.top + pt.y;
val.fill_rule = (GetPolyFillMode(physDev->dev.hdc) == WINDING) ? WindingRule : EvenOddRule;
val.fill_rule = poly_fill_mode == WINDING ? WindingRule : EvenOddRule;
XChangeGC( gdi_display, gc,
GCFunction | GCForeground | GCBackground | GCFillStyle |
GCFillRule | GCTileStipXOrigin | GCTileStipYOrigin | mask,
@ -416,8 +429,10 @@ BOOL X11DRV_SetupGCForBrush( X11DRV_PDEVICE *physDev )
*/
static BOOL X11DRV_SetupGCForPen( X11DRV_PDEVICE *physDev )
{
DWORD rop2, bk_color, bk_mode;
XGCValues val;
UINT rop2 = GetROP2(physDev->dev.hdc);
NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetROP2, &rop2 );
if (physDev->pen.style == PS_NULL) return FALSE;
@ -444,7 +459,8 @@ static BOOL X11DRV_SetupGCForPen( X11DRV_PDEVICE *physDev )
val.foreground = physDev->pen.pixel;
val.function = X11DRV_XROPfunction[rop2-1];
}
val.background = X11DRV_PALETTE_ToPhysical( physDev, GetBkColor(physDev->dev.hdc) );
NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetBkColor, &bk_color );
val.background = X11DRV_PALETTE_ToPhysical( physDev, bk_color );
val.fill_style = FillSolid;
val.line_width = physDev->pen.width;
if (val.line_width <= 1) {
@ -477,7 +493,8 @@ static BOOL X11DRV_SetupGCForPen( X11DRV_PDEVICE *physDev )
}
if (physDev->pen.dash_len)
val.line_style = ((GetBkMode(physDev->dev.hdc) == OPAQUE) && (!physDev->pen.ext))
val.line_style = (NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetBkMode, &bk_mode) &&
bk_mode == OPAQUE && !physDev->pen.ext)
? LineDoubleDash : LineOnOffDash;
else
val.line_style = LineSolid;
@ -504,7 +521,7 @@ INT X11DRV_XWStoDS( HDC hdc, INT width )
pt[0].y = 0;
pt[1].x = width;
pt[1].y = 0;
LPtoDP( hdc, pt, 2 );
lp_to_dp( hdc, pt, 2 );
return pt[1].x - pt[0].x;
}
@ -521,7 +538,7 @@ INT X11DRV_YWStoDS( HDC hdc, INT height )
pt[0].y = 0;
pt[1].x = 0;
pt[1].y = height;
LPtoDP( hdc, pt, 2 );
lp_to_dp( hdc, pt, 2 );
return pt[1].y - pt[0].y;
}
@ -533,10 +550,10 @@ BOOL CDECL X11DRV_LineTo( PHYSDEV dev, INT x, INT y )
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
POINT pt[2];
GetCurrentPositionEx( dev->hdc, &pt[0] );
NtGdiGetDCPoint( dev->hdc, NtGdiGetCurrentPosition, &pt[0] );
pt[1].x = x;
pt[1].y = y;
LPtoDP( dev->hdc, pt, 2 );
lp_to_dp( dev->hdc, pt, 2 );
add_pen_device_bounds( physDev, pt, 2 );
if (X11DRV_SetupGCForPen( physDev ))
@ -561,6 +578,7 @@ static BOOL X11DRV_DrawArc( PHYSDEV dev, INT left, INT top, INT right, INT botto
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
INT xcenter, ycenter, istart_angle, idiff_angle;
INT width, oldwidth;
DWORD arc_dir;
double start_angle, end_angle;
XPoint points[4];
POINT start, end;
@ -570,13 +588,13 @@ static BOOL X11DRV_DrawArc( PHYSDEV dev, INT left, INT top, INT right, INT botto
start.y = ystart;
end.x = xend;
end.y = yend;
LPtoDP(dev->hdc, &start, 1);
LPtoDP(dev->hdc, &end, 1);
lp_to_dp(dev->hdc, &start, 1);
lp_to_dp(dev->hdc, &end, 1);
if ((rc.left == rc.right) || (rc.top == rc.bottom)
||(lines && ((rc.right-rc.left==1)||(rc.bottom-rc.top==1)))) return TRUE;
if (GetArcDirection( dev->hdc ) == AD_CLOCKWISE)
if (NtGdiGetDCDword( dev->hdc, NtGdiGetArcDirection, &arc_dir ) && arc_dir == AD_CLOCKWISE)
{ POINT tmp = start; start = end; end = tmp; }
oldwidth = width = physDev->pen.width;
@ -843,7 +861,7 @@ BOOL CDECL X11DRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bott
pts[0].x = pts[0].y = 0;
pts[1].x = ell_width;
pts[1].y = ell_height;
LPtoDP(dev->hdc, pts, 2);
lp_to_dp(dev->hdc, pts, 2);
ell_width = max(abs( pts[1].x - pts[0].x ), 1);
ell_height = max(abs( pts[1].y - pts[0].y ), 1);
@ -1024,7 +1042,7 @@ COLORREF CDECL X11DRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
pt.x = x;
pt.y = y;
LPtoDP( dev->hdc, &pt, 1 );
lp_to_dp( dev->hdc, &pt, 1 );
pixel = X11DRV_PALETTE_ToPhysical( physDev, color );
XSetForeground( gdi_display, physDev->gc, pixel );
@ -1063,9 +1081,9 @@ BOOL CDECL X11DRV_PaintRgn( PHYSDEV dev, HRGN hrgn )
XFillRectangles( gdi_display, physDev->drawable, physDev->gc, rect, data->rdh.nCount );
HeapFree( GetProcessHeap(), 0, data );
}
if (GetRgnBox( hrgn, &rc ))
if (NtGdiGetRgnBox( hrgn, &rc ))
{
LPtoDP( dev->hdc, (POINT *)&rc, 2 );
lp_to_dp( dev->hdc, (POINT *)&rc, 2 );
add_device_bounds( physDev, &rc );
}
return TRUE;
@ -1084,7 +1102,7 @@ static BOOL X11DRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
points = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*pt) );
if (!points) return FALSE;
memcpy( points, pt, count * sizeof(*pt) );
LPtoDP( dev->hdc, points, count );
lp_to_dp( dev->hdc, points, count );
add_pen_device_bounds( physDev, points, count );
if (!(xpoints = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (count+1) )))
@ -1135,16 +1153,22 @@ BOOL CDECL X11DRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts,
points = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*pt) );
if (!points) return FALSE;
memcpy( points, pt, total * sizeof(*pt) );
LPtoDP( dev->hdc, points, total );
lp_to_dp( dev->hdc, points, total );
add_pen_device_bounds( physDev, points, total );
if (X11DRV_SetupGCForBrush( physDev ))
{
DWORD poly_fill_mode;
XRectangle *rect;
HRGN hrgn = CreatePolyPolygonRgn( points, counts, polygons, GetPolyFillMode( dev->hdc ) );
RGNDATA *data = X11DRV_GetRegionData( hrgn, 0 );
HRGN hrgn;
RGNDATA *data;
DeleteObject( hrgn );
NtGdiGetDCDword( dev->hdc, NtGdiGetPolyFillMode, &poly_fill_mode );
hrgn = UlongToHandle( NtGdiPolyPolyDraw( UlongToHandle(poly_fill_mode), points,
(const ULONG *)counts, polygons,
NtGdiPolyPolygonRgn ));
data = X11DRV_GetRegionData( hrgn, 0 );
NtGdiDeleteObjectApp( hrgn );
if (!data) goto done;
rect = (XRectangle *)data->Buffer;
for (i = 0; i < data->rdh.nCount; i++)
@ -1202,7 +1226,7 @@ BOOL CDECL X11DRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* count
points = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*pt) );
if (!points) return FALSE;
memcpy( points, pt, total * sizeof(*pt) );
LPtoDP( dev->hdc, points, total );
lp_to_dp( dev->hdc, points, total );
add_pen_device_bounds( physDev, points, total );
if (X11DRV_SetupGCForPen ( physDev ))
@ -1239,27 +1263,27 @@ static BOOL x11drv_stroke_and_fill_path( PHYSDEV dev, BOOL stroke, BOOL fill )
XPoint *xpoints;
int i, j, size;
FlattenPath( dev->hdc );
if ((size = GetPath( dev->hdc, NULL, NULL, 0 )) == -1) return FALSE;
NtGdiFlattenPath( dev->hdc );
if ((size = NtGdiGetPath( dev->hdc, NULL, NULL, 0 )) == -1) return FALSE;
if (!size)
{
AbortPath( dev->hdc );
NtGdiAbortPath( dev->hdc );
return TRUE;
}
xpoints = HeapAlloc( GetProcessHeap(), 0, (size + 1) * sizeof(*xpoints) );
points = HeapAlloc( GetProcessHeap(), 0, size * sizeof(*points) );
flags = HeapAlloc( GetProcessHeap(), 0, size * sizeof(*flags) );
if (!points || !flags || !xpoints) goto done;
if (GetPath( dev->hdc, points, flags, size ) == -1) goto done;
LPtoDP( dev->hdc, points, size );
if (NtGdiGetPath( dev->hdc, points, flags, size ) == -1) goto done;
lp_to_dp( dev->hdc, points, size );
if (fill && X11DRV_SetupGCForBrush( physDev ))
{
XRectangle *rect;
HRGN hrgn = PathToRegion( dev->hdc );
HRGN hrgn = NtGdiPathToRegion( dev->hdc );
RGNDATA *data = X11DRV_GetRegionData( hrgn, 0 );
DeleteObject( hrgn );
NtGdiDeleteObjectApp( hrgn );
if (!data) goto done;
rect = (XRectangle *)data->Buffer;
for (i = 0; i < data->rdh.nCount; i++)
@ -1296,7 +1320,7 @@ static BOOL x11drv_stroke_and_fill_path( PHYSDEV dev, BOOL stroke, BOOL fill )
}
add_pen_device_bounds( physDev, points, size );
AbortPath( dev->hdc );
NtGdiAbortPath( dev->hdc );
ret = TRUE;
done:
@ -1423,7 +1447,7 @@ BOOL CDECL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT
pt.x = x;
pt.y = y;
LPtoDP( dev->hdc, &pt, 1 );
lp_to_dp( dev->hdc, &pt, 1 );
if (!physDev->region)
{
@ -1434,8 +1458,8 @@ BOOL CDECL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT
}
else
{
if (!PtInRegion( physDev->region, pt.x, pt.y )) return FALSE;
GetRgnBox( physDev->region, &rect );
if (!NtGdiPtInRegion( physDev->region, pt.x, pt.y )) return FALSE;
NtGdiGetRgnBox( physDev->region, &rect );
rect.left = max( rect.left, 0 );
rect.top = max( rect.top, 0 );
rect.right = min( rect.right, physDev->dc_rect.right - physDev->dc_rect.left );
@ -1511,7 +1535,7 @@ BOOL CDECL X11DRV_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
pt[0].y = v[0].y;
pt[1].x = v[1].x;
pt[1].y = v[1].y;
LPtoDP( dev->hdc, pt, 2 );
lp_to_dp( dev->hdc, pt, 2 );
dx = pt[1].x - pt[0].x;
if (!dx) continue;
if (dx < 0) /* swap the colors */
@ -1561,7 +1585,7 @@ BOOL CDECL X11DRV_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
pt[0].y = v[0].y;
pt[1].x = v[1].x;
pt[1].y = v[1].y;
LPtoDP( dev->hdc, pt, 2 );
lp_to_dp( dev->hdc, pt, 2 );
dy = pt[1].y - pt[0].y;
if (!dy) continue;
if (dy < 0) /* swap the colors */

View File

@ -840,6 +840,13 @@ static inline BOOL is_window_rect_mapped( const RECT *rect )
max( rect->bottom, rect->top + 1 ) > virtual_rect.top);
}
/* GDI helpers */
static inline BOOL lp_to_dp( HDC hdc, POINT *points, INT count )
{
return NtGdiTransformPoints( hdc, points, points, count, NtGdiLPtoDP );
}
/* registry helpers */
extern HKEY open_hkcu_key( const char *name ) DECLSPEC_HIDDEN;