winex11: Convert all points to device coordinates at once for polylines and polygons.

This commit is contained in:
Alexandre Julliard 2012-04-17 14:38:24 +02:00
parent b2f3144e0c
commit dedd9fe23e
3 changed files with 90 additions and 92 deletions

View File

@ -1090,41 +1090,6 @@ BOOL X11DRV_PaintRgn( PHYSDEV dev, HRGN hrgn )
return TRUE; return TRUE;
} }
/**********************************************************************
* X11DRV_Polyline
*/
BOOL X11DRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
{
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
int i;
XPoint *points;
if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * count )))
{
WARN("No memory to convert POINTs to XPoints!\n");
return FALSE;
}
for (i = 0; i < count; i++)
{
POINT tmp = pt[i];
LPtoDP(dev->hdc, &tmp, 1);
points[i].x = physDev->dc_rect.left + tmp.x;
points[i].y = physDev->dc_rect.top + tmp.y;
}
if (X11DRV_SetupGCForPen ( physDev ))
{
wine_tsx11_lock();
XDrawLines( gdi_display, physDev->drawable, physDev->gc,
points, count, CoordModeOrigin );
wine_tsx11_unlock();
}
HeapFree( GetProcessHeap(), 0, points );
return TRUE;
}
/********************************************************************** /**********************************************************************
* X11DRV_Polygon * X11DRV_Polygon
*/ */
@ -1132,37 +1097,42 @@ BOOL X11DRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
{ {
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev ); X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
int i; int i;
XPoint *points; POINT *points;
XPoint *xpoints;
if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (count+1) ))) points = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*pt) );
if (!points) return FALSE;
memcpy( points, pt, count * sizeof(*pt) );
LPtoDP( dev->hdc, points, count );
if (!(xpoints = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (count+1) )))
{ {
WARN("No memory to convert POINTs to XPoints!\n"); HeapFree( GetProcessHeap(), 0, points );
return FALSE; return FALSE;
} }
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
POINT tmp = pt[i]; xpoints[i].x = physDev->dc_rect.left + points[i].x;
LPtoDP(dev->hdc, &tmp, 1); xpoints[i].y = physDev->dc_rect.top + points[i].y;
points[i].x = physDev->dc_rect.left + tmp.x;
points[i].y = physDev->dc_rect.top + tmp.y;
} }
points[count] = points[0]; xpoints[count] = xpoints[0];
if (X11DRV_SetupGCForBrush( physDev )) if (X11DRV_SetupGCForBrush( physDev ))
{ {
wine_tsx11_lock(); wine_tsx11_lock();
XFillPolygon( gdi_display, physDev->drawable, physDev->gc, XFillPolygon( gdi_display, physDev->drawable, physDev->gc,
points, count+1, Complex, CoordModeOrigin); xpoints, count+1, Complex, CoordModeOrigin);
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
if (X11DRV_SetupGCForPen ( physDev )) if (X11DRV_SetupGCForPen ( physDev ))
{ {
wine_tsx11_lock(); wine_tsx11_lock();
XDrawLines( gdi_display, physDev->drawable, physDev->gc, XDrawLines( gdi_display, physDev->drawable, physDev->gc,
points, count+1, CoordModeOrigin ); xpoints, count+1, CoordModeOrigin );
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
HeapFree( GetProcessHeap(), 0, xpoints );
HeapFree( GetProcessHeap(), 0, points ); HeapFree( GetProcessHeap(), 0, points );
return TRUE; return TRUE;
} }
@ -1174,48 +1144,68 @@ BOOL X11DRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
BOOL X11DRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons ) BOOL X11DRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons )
{ {
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev ); X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
HRGN hrgn; DWORD total = 0, max = 0, pos, i;
POINT *points;
BOOL ret = FALSE;
/* FIXME: The points should be converted to device coords before */ for (i = 0; i < polygons; i++)
/* creating the region. */ {
if (counts[i] < 2) return FALSE;
if (counts[i] > max) max = counts[i];
total += counts[i];
}
hrgn = CreatePolyPolygonRgn( pt, counts, polygons, GetPolyFillMode( dev->hdc ) ); points = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*pt) );
X11DRV_PaintRgn( dev, hrgn ); if (!points) return FALSE;
DeleteObject( hrgn ); memcpy( points, pt, total * sizeof(*pt) );
LPtoDP( dev->hdc, points, total );
/* Draw the outline of the polygons */ if (X11DRV_SetupGCForBrush( physDev ))
{
XRectangle *rect;
HRGN hrgn = CreatePolyPolygonRgn( points, counts, polygons, GetPolyFillMode( dev->hdc ) );
RGNDATA *data = X11DRV_GetRegionData( hrgn, 0 );
DeleteObject( hrgn );
if (!data) goto done;
rect = (XRectangle *)data->Buffer;
for (i = 0; i < data->rdh.nCount; i++)
{
rect[i].x += physDev->dc_rect.left;
rect[i].y += physDev->dc_rect.top;
}
wine_tsx11_lock();
XFillRectangles( gdi_display, physDev->drawable, physDev->gc, rect, data->rdh.nCount );
wine_tsx11_unlock();
HeapFree( GetProcessHeap(), 0, data );
}
if (X11DRV_SetupGCForPen ( physDev )) if (X11DRV_SetupGCForPen ( physDev ))
{ {
unsigned int i; XPoint *xpoints;
int j, max = 0; int j;
XPoint *points;
for (i = 0; i < polygons; i++) if (counts[i] > max) max = counts[i]; if (!(xpoints = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (max + 1) ))) goto done;
if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (max+1) ))) for (i = pos = 0; i < polygons; pos += counts[i++])
{ {
WARN("No memory to convert POINTs to XPoints!\n"); for (j = 0; j < counts[i]; j++)
return FALSE; {
} xpoints[j].x = physDev->dc_rect.left + points[pos + j].x;
for (i = 0; i < polygons; i++) xpoints[j].y = physDev->dc_rect.top + points[pos + j].y;
{ }
for (j = 0; j < counts[i]; j++) xpoints[j] = xpoints[0];
{
POINT tmp = *pt;
LPtoDP(dev->hdc, &tmp, 1);
points[j].x = physDev->dc_rect.left + tmp.x;
points[j].y = physDev->dc_rect.top + tmp.y;
pt++;
}
points[j] = points[0];
wine_tsx11_lock(); wine_tsx11_lock();
XDrawLines( gdi_display, physDev->drawable, physDev->gc, XDrawLines( gdi_display, physDev->drawable, physDev->gc, xpoints, j + 1, CoordModeOrigin );
points, j + 1, CoordModeOrigin );
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
HeapFree( GetProcessHeap(), 0, points ); HeapFree( GetProcessHeap(), 0, xpoints );
} }
return TRUE; ret = TRUE;
done:
HeapFree( GetProcessHeap(), 0, points );
return ret;
} }
@ -1225,35 +1215,44 @@ BOOL X11DRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT p
BOOL X11DRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polylines ) BOOL X11DRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polylines )
{ {
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev ); X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
DWORD total = 0, max = 0, pos, i, j;
POINT *points;
for (i = 0; i < polylines; i++)
{
if (counts[i] < 2) return FALSE;
if (counts[i] > max) max = counts[i];
total += counts[i];
}
points = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*pt) );
if (!points) return FALSE;
memcpy( points, pt, total * sizeof(*pt) );
LPtoDP( dev->hdc, points, total );
if (X11DRV_SetupGCForPen ( physDev )) if (X11DRV_SetupGCForPen ( physDev ))
{ {
unsigned int i, j, max = 0; XPoint *xpoints;
XPoint *points;
for (i = 0; i < polylines; i++) if (counts[i] > max) max = counts[i]; if (!(xpoints = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * max )))
if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * max )))
{ {
WARN("No memory to convert POINTs to XPoints!\n"); HeapFree( GetProcessHeap(), 0, points );
return FALSE; return FALSE;
} }
for (i = 0; i < polylines; i++) for (i = pos = 0; i < polylines; pos += counts[i++])
{ {
for (j = 0; j < counts[i]; j++) for (j = 0; j < counts[i]; j++)
{ {
POINT tmp = *pt; xpoints[j].x = physDev->dc_rect.left + points[pos + j].x;
LPtoDP(dev->hdc, &tmp, 1); xpoints[j].y = physDev->dc_rect.top + points[pos + j].y;
points[j].x = physDev->dc_rect.left + tmp.x;
points[j].y = physDev->dc_rect.top + tmp.y;
pt++;
} }
wine_tsx11_lock(); wine_tsx11_lock();
XDrawLines( gdi_display, physDev->drawable, physDev->gc, XDrawLines( gdi_display, physDev->drawable, physDev->gc, xpoints, j, CoordModeOrigin );
points, j, CoordModeOrigin );
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
HeapFree( GetProcessHeap(), 0, points ); HeapFree( GetProcessHeap(), 0, xpoints );
} }
HeapFree( GetProcessHeap(), 0, points );
return TRUE; return TRUE;
} }

View File

@ -532,7 +532,7 @@ static const struct gdi_dc_funcs x11drv_funcs =
X11DRV_PolyPolygon, /* pPolyPolygon */ X11DRV_PolyPolygon, /* pPolyPolygon */
X11DRV_PolyPolyline, /* pPolyPolyline */ X11DRV_PolyPolyline, /* pPolyPolyline */
X11DRV_Polygon, /* pPolygon */ X11DRV_Polygon, /* pPolygon */
X11DRV_Polyline, /* pPolyline */ NULL, /* pPolyline */
NULL, /* pPolylineTo */ NULL, /* pPolylineTo */
X11DRV_PutImage, /* pPutImage */ X11DRV_PutImage, /* pPutImage */
X11DRV_RealizeDefaultPalette, /* pRealizeDefaultPalette */ X11DRV_RealizeDefaultPalette, /* pRealizeDefaultPalette */

View File

@ -182,7 +182,6 @@ extern BOOL X11DRV_PaintRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop ) DECLSPEC_HIDDEN; extern BOOL X11DRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_Pie( PHYSDEV dev, INT left, INT top, INT right, extern BOOL X11DRV_Pie( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN; INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_Polyline( PHYSDEV dev,const POINT* pt,INT count) DECLSPEC_HIDDEN;
extern BOOL X11DRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN; extern BOOL X11DRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons) DECLSPEC_HIDDEN; extern BOOL X11DRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons) DECLSPEC_HIDDEN;
extern BOOL X11DRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polylines) DECLSPEC_HIDDEN; extern BOOL X11DRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polylines) DECLSPEC_HIDDEN;