gdi32: Add a DC driver entry point for GdiGradientFill.
This commit is contained in:
parent
afd962121b
commit
95cba0c0f4
|
@ -586,6 +586,7 @@ const struct gdi_dc_funcs dib_driver =
|
|||
NULL, /* pGetTextExtentExPointI */
|
||||
NULL, /* pGetTextFace */
|
||||
NULL, /* pGetTextMetrics */
|
||||
NULL, /* pGradientFill */
|
||||
NULL, /* pIntersectClipRect */
|
||||
NULL, /* pInvertRgn */
|
||||
dibdrv_LineTo, /* pLineTo */
|
||||
|
|
|
@ -796,6 +796,7 @@ const struct gdi_dc_funcs null_driver =
|
|||
nulldrv_GetTextExtentExPointI, /* pGetTextExtentExPointI */
|
||||
nulldrv_GetTextFace, /* pGetTextFace */
|
||||
nulldrv_GetTextMetrics, /* pGetTextMetrics */
|
||||
nulldrv_GradientFill, /* pGradientFill */
|
||||
nulldrv_IntersectClipRect, /* pIntersectClipRect */
|
||||
nulldrv_InvertRgn, /* pInvertRgn */
|
||||
nulldrv_LineTo, /* pLineTo */
|
||||
|
|
|
@ -97,6 +97,7 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
|
|||
NULL, /* pGetTextExtentExPointI */
|
||||
NULL, /* pGetTextFace */
|
||||
NULL, /* pGetTextMetrics */
|
||||
NULL, /* pGradientFill */
|
||||
EMFDRV_IntersectClipRect, /* pIntersectClipRect */
|
||||
EMFDRV_InvertRgn, /* pInvertRgn */
|
||||
EMFDRV_LineTo, /* pLineTo */
|
||||
|
|
|
@ -7183,6 +7183,7 @@ static const struct gdi_dc_funcs freetype_funcs =
|
|||
freetype_GetTextExtentExPointI, /* pGetTextExtentExPointI */
|
||||
freetype_GetTextFace, /* pGetTextFace */
|
||||
freetype_GetTextMetrics, /* pGetTextMetrics */
|
||||
NULL, /* pGradientFill */
|
||||
NULL, /* pIntersectClipRect */
|
||||
NULL, /* pInvertRgn */
|
||||
NULL, /* pLineTo */
|
||||
|
|
|
@ -364,6 +364,8 @@ extern BOOL nulldrv_FrameRgn( PHYSDEV dev, HRGN rgn, HBRUSH brush, INT width, IN
|
|||
extern LONG nulldrv_GetBitmapBits( HBITMAP bitmap, void *bits, LONG size ) DECLSPEC_HIDDEN;
|
||||
extern DWORD nulldrv_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, struct gdi_image_bits *bits, struct bitblt_coords *src ) DECLSPEC_HIDDEN;
|
||||
extern COLORREF nulldrv_GetNearestColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
|
||||
extern BOOL nulldrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
|
||||
void * grad_array, ULONG ngrad, ULONG mode ) DECLSPEC_HIDDEN;
|
||||
extern INT nulldrv_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
|
||||
extern BOOL nulldrv_InvertRgn( PHYSDEV dev, HRGN rgn ) DECLSPEC_HIDDEN;
|
||||
extern BOOL nulldrv_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -142,6 +142,7 @@ static const struct gdi_dc_funcs MFDRV_Funcs =
|
|||
NULL, /* pGetTextExtentExPointI */
|
||||
NULL, /* pGetTextFace */
|
||||
NULL, /* pGetTextMetrics */
|
||||
NULL, /* pGradientFill */
|
||||
MFDRV_IntersectClipRect, /* pIntersectClipRect */
|
||||
MFDRV_InvertRgn, /* pInvertRgn */
|
||||
MFDRV_LineTo, /* pLineTo */
|
||||
|
|
|
@ -226,6 +226,149 @@ BOOL nulldrv_PolylineTo( PHYSDEV dev, const POINT *points, INT count )
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL nulldrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
|
||||
void * grad_array, ULONG ngrad, ULONG mode )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case GRADIENT_FILL_RECT_H:
|
||||
for(i = 0; i < ngrad; i++)
|
||||
{
|
||||
GRADIENT_RECT *rect = ((GRADIENT_RECT *)grad_array) + i;
|
||||
TRIVERTEX *v1 = vert_array + rect->UpperLeft;
|
||||
TRIVERTEX *v2 = vert_array + rect->LowerRight;
|
||||
int y1 = v1->y < v2->y ? v1->y : v2->y;
|
||||
int y2 = v2->y > v1->y ? v2->y : v1->y;
|
||||
int x, dx;
|
||||
if (v1->x > v2->x)
|
||||
{
|
||||
TRIVERTEX *t = v2;
|
||||
v2 = v1;
|
||||
v1 = t;
|
||||
}
|
||||
dx = v2->x - v1->x;
|
||||
for (x = 0; x < dx; x++)
|
||||
{
|
||||
POINT pts[2];
|
||||
HPEN hPen, hOldPen;
|
||||
|
||||
hPen = CreatePen( PS_SOLID, 1, RGB(
|
||||
(v1->Red * (dx - x) + v2->Red * x) / dx >> 8,
|
||||
(v1->Green * (dx - x) + v2->Green * x) / dx >> 8,
|
||||
(v1->Blue * (dx - x) + v2->Blue * x) / dx >> 8));
|
||||
hOldPen = SelectObject( dev->hdc, hPen );
|
||||
pts[0].x = v1->x + x;
|
||||
pts[0].y = y1;
|
||||
pts[1].x = v1->x + x;
|
||||
pts[1].y = y2;
|
||||
Polyline( dev->hdc, &pts[0], 2 );
|
||||
DeleteObject( SelectObject(dev->hdc, hOldPen ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRADIENT_FILL_RECT_V:
|
||||
for(i = 0; i < ngrad; i++)
|
||||
{
|
||||
GRADIENT_RECT *rect = ((GRADIENT_RECT *)grad_array) + i;
|
||||
TRIVERTEX *v1 = vert_array + rect->UpperLeft;
|
||||
TRIVERTEX *v2 = vert_array + rect->LowerRight;
|
||||
int x1 = v1->x < v2->x ? v1->x : v2->x;
|
||||
int x2 = v2->x > v1->x ? v2->x : v1->x;
|
||||
int y, dy;
|
||||
if (v1->y > v2->y)
|
||||
{
|
||||
TRIVERTEX *t = v2;
|
||||
v2 = v1;
|
||||
v1 = t;
|
||||
}
|
||||
dy = v2->y - v1->y;
|
||||
for (y = 0; y < dy; y++)
|
||||
{
|
||||
POINT pts[2];
|
||||
HPEN hPen, hOldPen;
|
||||
|
||||
hPen = CreatePen( PS_SOLID, 1, RGB(
|
||||
(v1->Red * (dy - y) + v2->Red * y) / dy >> 8,
|
||||
(v1->Green * (dy - y) + v2->Green * y) / dy >> 8,
|
||||
(v1->Blue * (dy - y) + v2->Blue * y) / dy >> 8));
|
||||
hOldPen = SelectObject( dev->hdc, hPen );
|
||||
pts[0].x = x1;
|
||||
pts[0].y = v1->y + y;
|
||||
pts[1].x = x2;
|
||||
pts[1].y = v1->y + y;
|
||||
Polyline( dev->hdc, &pts[0], 2 );
|
||||
DeleteObject( SelectObject(dev->hdc, hOldPen ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRADIENT_FILL_TRIANGLE:
|
||||
for (i = 0; i < ngrad; i++)
|
||||
{
|
||||
GRADIENT_TRIANGLE *tri = ((GRADIENT_TRIANGLE *)grad_array) + i;
|
||||
TRIVERTEX *v1 = vert_array + tri->Vertex1;
|
||||
TRIVERTEX *v2 = vert_array + tri->Vertex2;
|
||||
TRIVERTEX *v3 = vert_array + tri->Vertex3;
|
||||
int y, dy;
|
||||
|
||||
if (v1->y > v2->y)
|
||||
{ TRIVERTEX *t = v1; v1 = v2; v2 = t; }
|
||||
if (v2->y > v3->y)
|
||||
{
|
||||
TRIVERTEX *t = v2; v2 = v3; v3 = t;
|
||||
if (v1->y > v2->y)
|
||||
{ t = v1; v1 = v2; v2 = t; }
|
||||
}
|
||||
/* v1->y <= v2->y <= v3->y */
|
||||
|
||||
dy = v3->y - v1->y;
|
||||
for (y = 0; y < dy; y++)
|
||||
{
|
||||
/* v1->y <= y < v3->y */
|
||||
TRIVERTEX *v = y < (v2->y - v1->y) ? v1 : v3;
|
||||
/* (v->y <= y < v2->y) || (v2->y <= y < v->y) */
|
||||
int dy2 = v2->y - v->y;
|
||||
int y2 = y + v1->y - v->y;
|
||||
|
||||
int x1 = (v3->x * y + v1->x * (dy - y )) / dy;
|
||||
int x2 = (v2->x * y2 + v-> x * (dy2 - y2)) / dy2;
|
||||
int r1 = (v3->Red * y + v1->Red * (dy - y )) / dy;
|
||||
int r2 = (v2->Red * y2 + v-> Red * (dy2 - y2)) / dy2;
|
||||
int g1 = (v3->Green * y + v1->Green * (dy - y )) / dy;
|
||||
int g2 = (v2->Green * y2 + v-> Green * (dy2 - y2)) / dy2;
|
||||
int b1 = (v3->Blue * y + v1->Blue * (dy - y )) / dy;
|
||||
int b2 = (v2->Blue * y2 + v-> Blue * (dy2 - y2)) / dy2;
|
||||
|
||||
int x;
|
||||
if (x1 < x2)
|
||||
{
|
||||
int dx = x2 - x1;
|
||||
for (x = 0; x < dx; x++)
|
||||
SetPixel (dev->hdc, x + x1, y + v1->y, RGB(
|
||||
(r1 * (dx - x) + r2 * x) / dx >> 8,
|
||||
(g1 * (dx - x) + g2 * x) / dx >> 8,
|
||||
(b1 * (dx - x) + b2 * x) / dx >> 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
int dx = x1 - x2;
|
||||
for (x = 0; x < dx; x++)
|
||||
SetPixel (dev->hdc, x + x2, y + v1->y, RGB(
|
||||
(r2 * (dx - x) + r1 * x) / dx >> 8,
|
||||
(g2 * (dx - x) + g1 * x) / dx >> 8,
|
||||
(b2 * (dx - x) + b1 * x) / dx >> 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LineTo (GDI32.@)
|
||||
*/
|
||||
|
@ -1223,147 +1366,19 @@ POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut )
|
|||
BOOL WINAPI GdiGradientFill( HDC hdc, TRIVERTEX *vert_array, ULONG nvert,
|
||||
void * grad_array, ULONG ngrad, ULONG mode )
|
||||
{
|
||||
unsigned int i;
|
||||
DC *dc = get_dc_ptr( hdc );
|
||||
PHYSDEV physdev;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("vert_array:%p nvert:%d grad_array:%p ngrad:%d\n",
|
||||
vert_array, nvert, grad_array, ngrad);
|
||||
TRACE("%p vert_array:%p nvert:%d grad_array:%p ngrad:%d\n", hdc, vert_array, nvert, grad_array, ngrad);
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case GRADIENT_FILL_RECT_H:
|
||||
for(i = 0; i < ngrad; i++)
|
||||
{
|
||||
GRADIENT_RECT *rect = ((GRADIENT_RECT *)grad_array) + i;
|
||||
TRIVERTEX *v1 = vert_array + rect->UpperLeft;
|
||||
TRIVERTEX *v2 = vert_array + rect->LowerRight;
|
||||
int y1 = v1->y < v2->y ? v1->y : v2->y;
|
||||
int y2 = v2->y > v1->y ? v2->y : v1->y;
|
||||
int x, dx;
|
||||
if (v1->x > v2->x)
|
||||
{
|
||||
TRIVERTEX *t = v2;
|
||||
v2 = v1;
|
||||
v1 = t;
|
||||
}
|
||||
dx = v2->x - v1->x;
|
||||
for (x = 0; x < dx; x++)
|
||||
{
|
||||
POINT pts[2];
|
||||
HPEN hPen, hOldPen;
|
||||
|
||||
hPen = CreatePen( PS_SOLID, 1, RGB(
|
||||
(v1->Red * (dx - x) + v2->Red * x) / dx >> 8,
|
||||
(v1->Green * (dx - x) + v2->Green * x) / dx >> 8,
|
||||
(v1->Blue * (dx - x) + v2->Blue * x) / dx >> 8));
|
||||
hOldPen = SelectObject( hdc, hPen );
|
||||
pts[0].x = v1->x + x;
|
||||
pts[0].y = y1;
|
||||
pts[1].x = v1->x + x;
|
||||
pts[1].y = y2;
|
||||
Polyline( hdc, &pts[0], 2 );
|
||||
DeleteObject( SelectObject(hdc, hOldPen ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRADIENT_FILL_RECT_V:
|
||||
for(i = 0; i < ngrad; i++)
|
||||
{
|
||||
GRADIENT_RECT *rect = ((GRADIENT_RECT *)grad_array) + i;
|
||||
TRIVERTEX *v1 = vert_array + rect->UpperLeft;
|
||||
TRIVERTEX *v2 = vert_array + rect->LowerRight;
|
||||
int x1 = v1->x < v2->x ? v1->x : v2->x;
|
||||
int x2 = v2->x > v1->x ? v2->x : v1->x;
|
||||
int y, dy;
|
||||
if (v1->y > v2->y)
|
||||
{
|
||||
TRIVERTEX *t = v2;
|
||||
v2 = v1;
|
||||
v1 = t;
|
||||
}
|
||||
dy = v2->y - v1->y;
|
||||
for (y = 0; y < dy; y++)
|
||||
{
|
||||
POINT pts[2];
|
||||
HPEN hPen, hOldPen;
|
||||
|
||||
hPen = CreatePen( PS_SOLID, 1, RGB(
|
||||
(v1->Red * (dy - y) + v2->Red * y) / dy >> 8,
|
||||
(v1->Green * (dy - y) + v2->Green * y) / dy >> 8,
|
||||
(v1->Blue * (dy - y) + v2->Blue * y) / dy >> 8));
|
||||
hOldPen = SelectObject( hdc, hPen );
|
||||
pts[0].x = x1;
|
||||
pts[0].y = v1->y + y;
|
||||
pts[1].x = x2;
|
||||
pts[1].y = v1->y + y;
|
||||
Polyline( hdc, &pts[0], 2 );
|
||||
DeleteObject( SelectObject(hdc, hOldPen ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRADIENT_FILL_TRIANGLE:
|
||||
for (i = 0; i < ngrad; i++)
|
||||
{
|
||||
GRADIENT_TRIANGLE *tri = ((GRADIENT_TRIANGLE *)grad_array) + i;
|
||||
TRIVERTEX *v1 = vert_array + tri->Vertex1;
|
||||
TRIVERTEX *v2 = vert_array + tri->Vertex2;
|
||||
TRIVERTEX *v3 = vert_array + tri->Vertex3;
|
||||
int y, dy;
|
||||
|
||||
if (v1->y > v2->y)
|
||||
{ TRIVERTEX *t = v1; v1 = v2; v2 = t; }
|
||||
if (v2->y > v3->y)
|
||||
{
|
||||
TRIVERTEX *t = v2; v2 = v3; v3 = t;
|
||||
if (v1->y > v2->y)
|
||||
{ t = v1; v1 = v2; v2 = t; }
|
||||
}
|
||||
/* v1->y <= v2->y <= v3->y */
|
||||
if (!dc) return FALSE;
|
||||
|
||||
dy = v3->y - v1->y;
|
||||
for (y = 0; y < dy; y++)
|
||||
{
|
||||
/* v1->y <= y < v3->y */
|
||||
TRIVERTEX *v = y < (v2->y - v1->y) ? v1 : v3;
|
||||
/* (v->y <= y < v2->y) || (v2->y <= y < v->y) */
|
||||
int dy2 = v2->y - v->y;
|
||||
int y2 = y + v1->y - v->y;
|
||||
|
||||
int x1 = (v3->x * y + v1->x * (dy - y )) / dy;
|
||||
int x2 = (v2->x * y2 + v-> x * (dy2 - y2)) / dy2;
|
||||
int r1 = (v3->Red * y + v1->Red * (dy - y )) / dy;
|
||||
int r2 = (v2->Red * y2 + v-> Red * (dy2 - y2)) / dy2;
|
||||
int g1 = (v3->Green * y + v1->Green * (dy - y )) / dy;
|
||||
int g2 = (v2->Green * y2 + v-> Green * (dy2 - y2)) / dy2;
|
||||
int b1 = (v3->Blue * y + v1->Blue * (dy - y )) / dy;
|
||||
int b2 = (v2->Blue * y2 + v-> Blue * (dy2 - y2)) / dy2;
|
||||
|
||||
int x;
|
||||
if (x1 < x2)
|
||||
{
|
||||
int dx = x2 - x1;
|
||||
for (x = 0; x < dx; x++)
|
||||
SetPixel (hdc, x + x1, y + v1->y, RGB(
|
||||
(r1 * (dx - x) + r2 * x) / dx >> 8,
|
||||
(g1 * (dx - x) + g2 * x) / dx >> 8,
|
||||
(b1 * (dx - x) + b2 * x) / dx >> 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
int dx = x1 - x2;
|
||||
for (x = 0; x < dx; x++)
|
||||
SetPixel (hdc, x + x2, y + v1->y, RGB(
|
||||
(r2 * (dx - x) + r1 * x) / dx >> 8,
|
||||
(g2 * (dx - x) + g1 * x) / dx >> 8,
|
||||
(b2 * (dx - x) + b1 * x) / dx >> 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
update_dc( dc );
|
||||
physdev = GET_DC_PHYSDEV( dc, pGradientFill );
|
||||
ret = physdev->funcs->pGradientFill( physdev, vert_array, nvert, grad_array, ngrad, mode );
|
||||
release_dc_ptr( dc );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -2315,6 +2315,7 @@ const struct gdi_dc_funcs path_driver =
|
|||
NULL, /* pGetTextExtentExPointI */
|
||||
NULL, /* pGetTextFace */
|
||||
NULL, /* pGetTextMetrics */
|
||||
NULL, /* pGradientFill */
|
||||
NULL, /* pIntersectClipRect */
|
||||
NULL, /* pInvertRgn */
|
||||
pathdrv_LineTo, /* pLineTo */
|
||||
|
|
|
@ -879,6 +879,7 @@ static const struct gdi_dc_funcs psdrv_funcs =
|
|||
NULL, /* pGetTextExtentExPointI */
|
||||
NULL, /* pGetTextFace */
|
||||
PSDRV_GetTextMetrics, /* pGetTextMetrics */
|
||||
NULL, /* pGradientFill */
|
||||
NULL, /* pIntersectClipRect */
|
||||
NULL, /* pInvertRgn */
|
||||
PSDRV_LineTo, /* pLineTo */
|
||||
|
|
|
@ -526,6 +526,7 @@ static const struct gdi_dc_funcs x11drv_funcs =
|
|||
NULL, /* pGetTextExtentExPointI */
|
||||
NULL, /* pGetTextFace */
|
||||
X11DRV_GetTextMetrics, /* pGetTextMetrics */
|
||||
NULL, /* pGradientFill */
|
||||
NULL, /* pIntersectClipRect */
|
||||
NULL, /* pInvertRgn */
|
||||
X11DRV_LineTo, /* pLineTo */
|
||||
|
|
|
@ -3071,6 +3071,7 @@ static const struct gdi_dc_funcs xrender_funcs =
|
|||
NULL, /* pGetTextExtentExPointI */
|
||||
NULL, /* pGetTextFace */
|
||||
NULL, /* pGetTextMetrics */
|
||||
NULL, /* pGradientFill */
|
||||
NULL, /* pIntersectClipRect */
|
||||
NULL, /* pInvertRgn */
|
||||
NULL, /* pLineTo */
|
||||
|
|
|
@ -115,6 +115,7 @@ struct gdi_dc_funcs
|
|||
BOOL (*pGetTextExtentExPointI)(PHYSDEV,const WORD*,INT,INT,LPINT,LPINT,LPSIZE);
|
||||
INT (*pGetTextFace)(PHYSDEV,INT,LPWSTR);
|
||||
BOOL (*pGetTextMetrics)(PHYSDEV,TEXTMETRICW*);
|
||||
BOOL (*pGradientFill)(PHYSDEV,TRIVERTEX*,ULONG,void*,ULONG,ULONG);
|
||||
INT (*pIntersectClipRect)(PHYSDEV,INT,INT,INT,INT);
|
||||
BOOL (*pInvertRgn)(PHYSDEV,HRGN);
|
||||
BOOL (*pLineTo)(PHYSDEV,INT,INT);
|
||||
|
@ -203,7 +204,7 @@ struct gdi_dc_funcs
|
|||
};
|
||||
|
||||
/* increment this when you change the DC function table */
|
||||
#define WINE_GDI_DRIVER_VERSION 16
|
||||
#define WINE_GDI_DRIVER_VERSION 17
|
||||
|
||||
static inline PHYSDEV get_physdev_entry_point( PHYSDEV dev, size_t offset )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue