Move Bezier code out of x11drv into commmon GDI code; if any driver
does not implement PolyBezier[To] the curve is approximated to lines and drawn with Polyline. Implement many GDI-Path recording functions (at least the win9x subset). Implement FlattenPath and FillPath.
This commit is contained in:
parent
de73965d67
commit
b8e94b6119
|
@ -379,3 +379,25 @@ MFDRV_SetTextColor( DC *dc, COLORREF color )
|
|||
LOWORD(color));
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* MFDRV_PolyBezier
|
||||
* Since MetaFiles don't record Beziers and they don't even record
|
||||
* approximations to them using lines, we need this stub function.
|
||||
*/
|
||||
BOOL
|
||||
MFDRV_PolyBezier( DC *dc, const POINT *pts, DWORD count )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* MFDRV_PolyBezierTo
|
||||
* Since MetaFiles don't record Beziers and they don't even record
|
||||
* approximations to them using lines, we need this stub function.
|
||||
*/
|
||||
BOOL
|
||||
MFDRV_PolyBezierTo( DC *dc, const POINT *pts, DWORD count )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -65,8 +65,8 @@ static const DC_FUNCTIONS MFDRV_Funcs =
|
|||
MFDRV_PaintRgn, /* pPaintRgn */
|
||||
MFDRV_PatBlt, /* pPatBlt */
|
||||
MFDRV_Pie, /* pPie */
|
||||
NULL, /* pPolyBezier */
|
||||
NULL, /* pPolyBezierTo */
|
||||
MFDRV_PolyBezier, /* pPolyBezier */
|
||||
MFDRV_PolyBezierTo, /* pPolyBezierTo */
|
||||
NULL, /* pPolyDraw */
|
||||
MFDRV_PolyPolygon, /* pPolyPolygon */
|
||||
NULL, /* pPolyPolyline */
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/*
|
||||
* Misc. graphics operations
|
||||
* GDI drawing functions.
|
||||
*
|
||||
* Copyright 1993, 1994 Alexandre Julliard
|
||||
* Copyright 1997 Bertho A. Stultiens
|
||||
* 1999 Huw D M Davies
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
@ -100,7 +101,7 @@ BOOL WINAPI MoveToEx( HDC hdc, INT x, INT y, LPPOINT pt )
|
|||
|
||||
if(dc->funcs->pMoveToEx)
|
||||
return dc->funcs->pMoveToEx(dc,x,y,pt);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -125,12 +126,13 @@ BOOL WINAPI Arc( HDC hdc, INT left, INT top, INT right,
|
|||
INT xend, INT yend )
|
||||
{
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(dc && PATH_IsPathOpen(dc->w.path))
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_Arc(hdc, left, top, right, bottom, xstart, ystart, xend,
|
||||
yend);
|
||||
|
||||
return dc && dc->funcs->pArc &&
|
||||
return dc->funcs->pArc &&
|
||||
dc->funcs->pArc(dc,left,top,right,bottom,xstart,ystart,xend,yend);
|
||||
}
|
||||
|
||||
|
@ -145,7 +147,6 @@ BOOL WINAPI ArcTo( HDC hdc,
|
|||
{
|
||||
BOOL result;
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(dc->funcs->pArcTo)
|
||||
|
@ -200,8 +201,14 @@ BOOL WINAPI Pie( HDC hdc, INT left, INT top,
|
|||
INT xend, INT yend )
|
||||
{
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
return dc && dc->funcs->pPie &&
|
||||
if(PATH_IsPathOpen(dc->w.path)) {
|
||||
FIXME("-> Path: stub\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return dc->funcs->pPie &&
|
||||
dc->funcs->pPie(dc,left,top,right,bottom,xstart,ystart,xend,yend);
|
||||
}
|
||||
|
||||
|
@ -225,8 +232,14 @@ BOOL WINAPI Chord( HDC hdc, INT left, INT top,
|
|||
INT xend, INT yend )
|
||||
{
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
return dc && dc->funcs->pChord &&
|
||||
if(PATH_IsPathOpen(dc->w.path)) {
|
||||
FIXME("-> Path: stub\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return dc->funcs->pChord &&
|
||||
dc->funcs->pChord(dc,left,top,right,bottom,xstart,ystart,xend,yend);
|
||||
}
|
||||
|
||||
|
@ -248,8 +261,14 @@ BOOL WINAPI Ellipse( HDC hdc, INT left, INT top,
|
|||
INT right, INT bottom )
|
||||
{
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
return dc && dc->funcs->pEllipse &&
|
||||
if(PATH_IsPathOpen(dc->w.path)) {
|
||||
FIXME("-> Path: stub\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return dc->funcs->pEllipse &&
|
||||
dc->funcs->pEllipse(dc,left,top,right,bottom);
|
||||
}
|
||||
|
||||
|
@ -271,11 +290,12 @@ BOOL WINAPI Rectangle( HDC hdc, INT left, INT top,
|
|||
INT right, INT bottom )
|
||||
{
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(dc && PATH_IsPathOpen(dc->w.path))
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_Rectangle(hdc, left, top, right, bottom);
|
||||
|
||||
return dc && dc->funcs->pRectangle &&
|
||||
return dc->funcs->pRectangle &&
|
||||
dc->funcs->pRectangle(dc,left,top,right,bottom);
|
||||
}
|
||||
|
||||
|
@ -296,16 +316,16 @@ BOOL16 WINAPI RoundRect16( HDC16 hdc, INT16 left, INT16 top, INT16 right,
|
|||
BOOL WINAPI RoundRect( HDC hdc, INT left, INT top, INT right,
|
||||
INT bottom, INT ell_width, INT ell_height )
|
||||
{
|
||||
|
||||
if(ell_width == 0 || ell_height == 0) /* Just an optimization */
|
||||
return Rectangle(hdc, left, top, right, bottom);
|
||||
|
||||
else {
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
return dc && dc->funcs->pRoundRect &&
|
||||
dc->funcs->pRoundRect(dc,left,top,right,bottom,ell_width,ell_height);
|
||||
if(PATH_IsPathOpen(dc->w.path)) {
|
||||
FIXME("-> Path: stub\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return dc->funcs->pRoundRect &&
|
||||
dc->funcs->pRoundRect(dc,left,top,right,bottom,ell_width,ell_height);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -599,8 +619,12 @@ BOOL16 WINAPI Polyline16( HDC16 hdc, const POINT16* pt, INT16 count )
|
|||
BOOL WINAPI Polyline( HDC hdc, const POINT* pt, INT count )
|
||||
{
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
return dc && dc->funcs->pPolyline &&
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_Polyline(hdc, pt, count);
|
||||
|
||||
return dc->funcs->pPolyline &&
|
||||
dc->funcs->pPolyline(dc,pt,count);
|
||||
}
|
||||
|
||||
|
@ -614,7 +638,10 @@ BOOL WINAPI PolylineTo( HDC hdc, const POINT* pt, DWORD cCount )
|
|||
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(dc->funcs->pPolylineTo)
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
ret = PATH_PolylineTo(hdc, pt, cCount);
|
||||
|
||||
else if(dc->funcs->pPolylineTo)
|
||||
ret = dc->funcs->pPolylineTo(dc, pt, cCount);
|
||||
|
||||
else { /* do it using Polyline */
|
||||
|
@ -659,8 +686,12 @@ BOOL16 WINAPI Polygon16( HDC16 hdc, const POINT16* pt, INT16 count )
|
|||
BOOL WINAPI Polygon( HDC hdc, const POINT* pt, INT count )
|
||||
{
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
return dc && dc->funcs->pPolygon &&
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_Polygon(hdc, pt, count);
|
||||
|
||||
return dc->funcs->pPolygon &&
|
||||
dc->funcs->pPolygon(dc,pt,count);
|
||||
}
|
||||
|
||||
|
@ -699,8 +730,12 @@ BOOL WINAPI PolyPolygon( HDC hdc, const POINT* pt, const INT* counts,
|
|||
UINT polygons )
|
||||
{
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
return dc && dc->funcs->pPolyPolygon &&
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_PolyPolygon(hdc, pt, counts, polygons);
|
||||
|
||||
return dc->funcs->pPolyPolygon &&
|
||||
dc->funcs->pPolyPolygon(dc,pt,counts,polygons);
|
||||
}
|
||||
|
||||
|
@ -711,8 +746,12 @@ BOOL WINAPI PolyPolyline( HDC hdc, const POINT* pt, const DWORD* counts,
|
|||
DWORD polylines )
|
||||
{
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
return dc && dc->funcs->pPolyPolyline &&
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_PolyPolyline(hdc, pt, counts, polylines);
|
||||
|
||||
return dc->funcs->pPolyPolyline &&
|
||||
dc->funcs->pPolyPolyline(dc,pt,counts,polylines);
|
||||
}
|
||||
|
||||
|
@ -803,9 +842,27 @@ BOOL16 WINAPI PolyBezierTo16( HDC16 hDc, const POINT16* lppt, INT16 cPoints )
|
|||
BOOL WINAPI PolyBezier( HDC hdc, const POINT* lppt, DWORD cPoints )
|
||||
{
|
||||
DC * dc = DC_GetDCPtr( hdc );
|
||||
if(!dc) return FALSE;
|
||||
|
||||
return dc && dc->funcs->pPolyBezier &&
|
||||
dc->funcs->pPolyBezier(dc, lppt, cPoints);
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_PolyBezier(hdc, lppt, cPoints);
|
||||
|
||||
if(dc->funcs->pPolyBezier)
|
||||
return dc->funcs->pPolyBezier(dc, lppt, cPoints);
|
||||
|
||||
/* We'll convert it into line segments and draw them using Polyline */
|
||||
{
|
||||
POINT *Pts;
|
||||
INT nOut;
|
||||
BOOL ret;
|
||||
|
||||
Pts = GDI_Bezier( lppt, cPoints, &nOut );
|
||||
if(!Pts) return FALSE;
|
||||
TRACE("Pts = %p, no = %d\n", Pts, nOut);
|
||||
ret = Polyline( dc->hSelf, Pts, nOut );
|
||||
HeapFree( GetProcessHeap(), 0, Pts );
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -828,10 +885,18 @@ BOOL WINAPI PolyBezierTo( HDC hdc, const POINT* lppt, DWORD cPoints )
|
|||
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
ret = PATH_PolyBezierTo(hdc, lppt, cPoints);
|
||||
else
|
||||
ret = dc->funcs->pPolyBezierTo &&
|
||||
dc->funcs->pPolyBezierTo(dc, lppt, cPoints);
|
||||
|
||||
else if(dc->funcs->pPolyBezierTo)
|
||||
ret = dc->funcs->pPolyBezierTo(dc, lppt, cPoints);
|
||||
else { /* We'll do it using PolyBezier */
|
||||
POINT *pt;
|
||||
pt = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT) * (cPoints + 1) );
|
||||
if(!pt) return FALSE;
|
||||
pt[0].x = dc->w.CursPosX;
|
||||
pt[0].y = dc->w.CursPosY;
|
||||
memcpy(pt + 1, lppt, sizeof(POINT) * cPoints);
|
||||
ret = PolyBezier(dc->hSelf, pt, cPoints+1);
|
||||
HeapFree( GetProcessHeap(), 0, pt );
|
||||
}
|
||||
if(ret) {
|
||||
dc->w.CursPosX = lppt[cPoints-1].x;
|
||||
dc->w.CursPosY = lppt[cPoints-1].y;
|
||||
|
@ -860,3 +925,198 @@ BOOL WINAPI PolyDraw(HDC hdc, const POINT *lppt, const BYTE *lpbTypes,
|
|||
FIXME("PolyDraw, stub\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* *Very* simple bezier drawing code,
|
||||
*
|
||||
* It uses a recursive algorithm to divide the curve in a series
|
||||
* of straight line segements. Not ideal but for me sufficient.
|
||||
* If you are in need for something better look for some incremental
|
||||
* algorithm.
|
||||
*
|
||||
* 7 July 1998 Rein Klazes
|
||||
*/
|
||||
|
||||
/*
|
||||
* some macro definitions for bezier drawing
|
||||
*
|
||||
* to avoid trucation errors the coordinates are
|
||||
* shifted upwards. When used in drawing they are
|
||||
* shifted down again, including correct rounding
|
||||
* and avoiding floating point arithmatic
|
||||
* 4 bits should allow 27 bits coordinates which I saw
|
||||
* somewere in the win32 doc's
|
||||
*
|
||||
*/
|
||||
|
||||
#define BEZIERSHIFTBITS 4
|
||||
#define BEZIERSHIFTUP(x) ((x)<<BEZIERSHIFTBITS)
|
||||
#define BEZIERPIXEL BEZIERSHIFTUP(1)
|
||||
#define BEZIERSHIFTDOWN(x) (((x)+(1<<(BEZIERSHIFTBITS-1)))>>BEZIERSHIFTBITS)
|
||||
/* maximum depth of recursion */
|
||||
#define BEZIERMAXDEPTH 8
|
||||
|
||||
/* size of array to store points on */
|
||||
/* enough for one curve */
|
||||
#define BEZIER_INITBUFSIZE (150)
|
||||
|
||||
/* calculate Bezier average, in this case the middle
|
||||
* correctly rounded...
|
||||
* */
|
||||
|
||||
#define BEZIERMIDDLE(Mid, P1, P2) \
|
||||
(Mid).x=((P1).x+(P2).x + 1)/2;\
|
||||
(Mid).y=((P1).y+(P2).y + 1)/2;
|
||||
|
||||
/**********************************************************
|
||||
* BezierCheck helper function to check
|
||||
* that recursion can be terminated
|
||||
* Points[0] and Points[3] are begin and endpoint
|
||||
* Points[1] and Points[2] are control points
|
||||
* level is the recursion depth
|
||||
* returns true if the recusion can be terminated
|
||||
*/
|
||||
static BOOL BezierCheck( int level, POINT *Points)
|
||||
{
|
||||
INT dx, dy;
|
||||
dx=Points[3].x-Points[0].x;
|
||||
dy=Points[3].y-Points[0].y;
|
||||
if(abs(dy)<=abs(dx)){/* shallow line */
|
||||
/* check that control points are between begin and end */
|
||||
if(Points[1].x < Points[0].x){
|
||||
if(Points[1].x < Points[3].x)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[1].x > Points[3].x)
|
||||
return FALSE;
|
||||
if(Points[2].x < Points[0].x){
|
||||
if(Points[2].x < Points[3].x)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[2].x > Points[3].x)
|
||||
return FALSE;
|
||||
dx=BEZIERSHIFTDOWN(dx);
|
||||
if(!dx) return TRUE;
|
||||
if(abs(Points[1].y-Points[0].y-(dy/dx)*
|
||||
BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
|
||||
abs(Points[2].y-Points[0].y-(dy/dx)*
|
||||
BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL )
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}else{ /* steep line */
|
||||
/* check that control points are between begin and end */
|
||||
if(Points[1].y < Points[0].y){
|
||||
if(Points[1].y < Points[3].y)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[1].y > Points[3].y)
|
||||
return FALSE;
|
||||
if(Points[2].y < Points[0].y){
|
||||
if(Points[2].y < Points[3].y)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[2].y > Points[3].y)
|
||||
return FALSE;
|
||||
dy=BEZIERSHIFTDOWN(dy);
|
||||
if(!dy) return TRUE;
|
||||
if(abs(Points[1].x-Points[0].x-(dx/dy)*
|
||||
BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
|
||||
abs(Points[2].x-Points[0].x-(dx/dy)*
|
||||
BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL )
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for GDI_Bezier.
|
||||
* Just handles one Bezier, so Points should point to four POINTs
|
||||
*/
|
||||
static void GDI_InternalBezier( POINT *Points, POINT **PtsOut, INT *dwOut,
|
||||
INT *nPtsOut, INT level )
|
||||
{
|
||||
if(*nPtsOut == *dwOut) {
|
||||
*dwOut *= 2;
|
||||
*PtsOut = HeapReAlloc( GetProcessHeap(), 0, *PtsOut,
|
||||
*dwOut * sizeof(POINT) );
|
||||
}
|
||||
|
||||
if(!level || BezierCheck(level, Points)) {
|
||||
if(*nPtsOut == 0) {
|
||||
(*PtsOut)[0].x = BEZIERSHIFTDOWN(Points[0].x);
|
||||
(*PtsOut)[0].y = BEZIERSHIFTDOWN(Points[0].y);
|
||||
*nPtsOut = 1;
|
||||
}
|
||||
(*PtsOut)[*nPtsOut].x = BEZIERSHIFTDOWN(Points[3].x);
|
||||
(*PtsOut)[*nPtsOut].y = BEZIERSHIFTDOWN(Points[3].y);
|
||||
(*nPtsOut) ++;
|
||||
} else {
|
||||
POINT Points2[4]; /* for the second recursive call */
|
||||
Points2[3]=Points[3];
|
||||
BEZIERMIDDLE(Points2[2], Points[2], Points[3]);
|
||||
BEZIERMIDDLE(Points2[0], Points[1], Points[2]);
|
||||
BEZIERMIDDLE(Points2[1],Points2[0],Points2[2]);
|
||||
|
||||
BEZIERMIDDLE(Points[1], Points[0], Points[1]);
|
||||
BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
|
||||
BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
|
||||
|
||||
Points2[0]=Points[3];
|
||||
|
||||
/* do the two halves */
|
||||
GDI_InternalBezier(Points, PtsOut, dwOut, nPtsOut, level-1);
|
||||
GDI_InternalBezier(Points2, PtsOut, dwOut, nPtsOut, level-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GDI_Bezier [INTERNAL]
|
||||
* Calculate line segments that approximate -what microsoft calls- a bezier
|
||||
* curve.
|
||||
* The routine recursively divides the curve in two parts until a straight
|
||||
* line can be drawn
|
||||
*
|
||||
* PARAMS
|
||||
*
|
||||
* Points [I] Ptr to count POINTs which are the end and control points
|
||||
* of the set of Bezier curves to flatten.
|
||||
* count [I] Number of Points. Must be 3n+1.
|
||||
* nPtsOut [O] Will contain no of points that have been produced (i.e. no. of
|
||||
* lines+1).
|
||||
*
|
||||
* RETURNS
|
||||
*
|
||||
* Ptr to an array of POINTs that contain the lines that approximinate the
|
||||
* Beziers. The array is allocated on the process heap and it is the caller's
|
||||
* responsibility to HeapFree it. [this is not a particularly nice interface
|
||||
* but since we can't know in advance how many points will generate, the
|
||||
* alternative would be to call the function twice, once to determine the size
|
||||
* and a second time to do the work - I decided this was too much of a pain].
|
||||
*/
|
||||
POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut )
|
||||
{
|
||||
POINT *out;
|
||||
INT Bezier, dwOut = BEZIER_INITBUFSIZE, i;
|
||||
|
||||
if((count - 1) % 3 != 0) {
|
||||
ERR("Invalid no. of points\n");
|
||||
return NULL;
|
||||
}
|
||||
*nPtsOut = 0;
|
||||
out = HeapAlloc( GetProcessHeap(), 0, dwOut * sizeof(POINT));
|
||||
for(Bezier = 0; Bezier < (count-1)/3; Bezier++) {
|
||||
POINT ptBuf[4];
|
||||
memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4);
|
||||
for(i = 0; i < 4; i++) {
|
||||
ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x);
|
||||
ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y);
|
||||
}
|
||||
GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
|
||||
}
|
||||
TRACE("Produced %d points\n", *nPtsOut);
|
||||
return out;
|
||||
}
|
||||
|
|
220
graphics/path.c
220
graphics/path.c
|
@ -2,6 +2,7 @@
|
|||
* Graphics paths (BeginPath, EndPath etc.)
|
||||
*
|
||||
* Copyright 1997, 1998 Martin Boehme
|
||||
* 1999 Huw D M Davies
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -903,6 +904,7 @@ BOOL PATH_PolyBezierTo(HDC hdc, const POINT *pts, DWORD cbPoints)
|
|||
if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for(i = 0; i < cbPoints; i++) {
|
||||
pt = pts[i];
|
||||
if(!LPtoDP(hdc, &pt, 1))
|
||||
|
@ -912,10 +914,217 @@ BOOL PATH_PolyBezierTo(HDC hdc, const POINT *pts, DWORD cbPoints)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL PATH_PolyBezier(HDC hdc, const POINT *pts, DWORD cbPoints)
|
||||
{
|
||||
GdiPath *pPath;
|
||||
POINT pt;
|
||||
INT i;
|
||||
|
||||
if(!PATH_GetPathFromHDC(hdc, &pPath))
|
||||
return FALSE;
|
||||
|
||||
/* Check that path is open */
|
||||
if(pPath->state!=PATH_Open)
|
||||
return FALSE;
|
||||
|
||||
for(i = 0; i < cbPoints; i++) {
|
||||
pt = pts[i];
|
||||
if(!LPtoDP(hdc, &pt, 1))
|
||||
return FALSE;
|
||||
PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL PATH_Polyline(HDC hdc, const POINT *pts, DWORD cbPoints)
|
||||
{
|
||||
GdiPath *pPath;
|
||||
POINT pt;
|
||||
INT i;
|
||||
|
||||
if(!PATH_GetPathFromHDC(hdc, &pPath))
|
||||
return FALSE;
|
||||
|
||||
/* Check that path is open */
|
||||
if(pPath->state!=PATH_Open)
|
||||
return FALSE;
|
||||
|
||||
for(i = 0; i < cbPoints; i++) {
|
||||
pt = pts[i];
|
||||
if(!LPtoDP(hdc, &pt, 1))
|
||||
return FALSE;
|
||||
PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL PATH_PolylineTo(HDC hdc, const POINT *pts, DWORD cbPoints)
|
||||
{
|
||||
GdiPath *pPath;
|
||||
POINT pt;
|
||||
INT i;
|
||||
|
||||
if(!PATH_GetPathFromHDC(hdc, &pPath))
|
||||
return FALSE;
|
||||
|
||||
/* Check that path is open */
|
||||
if(pPath->state!=PATH_Open)
|
||||
return FALSE;
|
||||
|
||||
/* Add a PT_MOVETO if necessary */
|
||||
if(pPath->newStroke)
|
||||
{
|
||||
pPath->newStroke=FALSE;
|
||||
if(!GetCurrentPositionEx(hdc, &pt) ||
|
||||
!LPtoDP(hdc, &pt, 1))
|
||||
return FALSE;
|
||||
if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for(i = 0; i < cbPoints; i++) {
|
||||
pt = pts[i];
|
||||
if(!LPtoDP(hdc, &pt, 1))
|
||||
return FALSE;
|
||||
PATH_AddEntry(pPath, &pt, PT_LINETO);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL PATH_Polygon(HDC hdc, const POINT *pts, DWORD cbPoints)
|
||||
{
|
||||
GdiPath *pPath;
|
||||
POINT pt;
|
||||
INT i;
|
||||
|
||||
if(!PATH_GetPathFromHDC(hdc, &pPath))
|
||||
return FALSE;
|
||||
|
||||
/* Check that path is open */
|
||||
if(pPath->state!=PATH_Open)
|
||||
return FALSE;
|
||||
|
||||
for(i = 0; i < cbPoints; i++) {
|
||||
pt = pts[i];
|
||||
if(!LPtoDP(hdc, &pt, 1))
|
||||
return FALSE;
|
||||
PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO :
|
||||
((i == cbPoints-1) ? PT_LINETO | PT_CLOSEFIGURE :
|
||||
PT_LINETO));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL PATH_PolyPolygon( HDC hdc, const POINT* pts, const INT* counts,
|
||||
UINT polygons )
|
||||
{
|
||||
GdiPath *pPath;
|
||||
POINT pt, startpt;
|
||||
INT poly, point, i;
|
||||
|
||||
if(!PATH_GetPathFromHDC(hdc, &pPath))
|
||||
return FALSE;
|
||||
|
||||
/* Check that path is open */
|
||||
if(pPath->state!=PATH_Open)
|
||||
return FALSE;
|
||||
|
||||
for(i = 0, poly = 0; poly < polygons; poly++) {
|
||||
for(point = 0; point < counts[poly]; point++, i++) {
|
||||
pt = pts[i];
|
||||
if(!LPtoDP(hdc, &pt, 1))
|
||||
return FALSE;
|
||||
if(point == 0) startpt = pt;
|
||||
PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
|
||||
}
|
||||
/* win98 adds an extra line to close the figure for some reason */
|
||||
PATH_AddEntry(pPath, &startpt, PT_LINETO | PT_CLOSEFIGURE);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL PATH_PolyPolyline( HDC hdc, const POINT* pts, const DWORD* counts,
|
||||
DWORD polylines )
|
||||
{
|
||||
GdiPath *pPath;
|
||||
POINT pt;
|
||||
INT poly, point, i;
|
||||
|
||||
if(!PATH_GetPathFromHDC(hdc, &pPath))
|
||||
return FALSE;
|
||||
|
||||
/* Check that path is open */
|
||||
if(pPath->state!=PATH_Open)
|
||||
return FALSE;
|
||||
|
||||
for(i = 0, poly = 0; poly < polylines; poly++) {
|
||||
for(point = 0; point < counts[poly]; point++, i++) {
|
||||
pt = pts[i];
|
||||
if(!LPtoDP(hdc, &pt, 1))
|
||||
return FALSE;
|
||||
PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Internal functions
|
||||
*/
|
||||
|
||||
|
||||
/* PATH_AddFlatBezier
|
||||
*
|
||||
*/
|
||||
static BOOL PATH_AddFlatBezier(GdiPath *pPath, POINT *pt, BOOL closed)
|
||||
{
|
||||
POINT *pts;
|
||||
INT no, i;
|
||||
|
||||
pts = GDI_Bezier( pt, 4, &no );
|
||||
if(!pts) return FALSE;
|
||||
|
||||
for(i = 1; i < no; i++)
|
||||
PATH_AddEntry(pPath, &pts[i],
|
||||
(i == no-1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO);
|
||||
HeapFree( GetProcessHeap(), 0, pts );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* PATH_FlattenPath
|
||||
*
|
||||
* Replaces Beziers with line segments
|
||||
*
|
||||
*/
|
||||
static BOOL PATH_FlattenPath(GdiPath *pPath)
|
||||
{
|
||||
GdiPath newPath;
|
||||
INT srcpt;
|
||||
|
||||
memset(&newPath, 0, sizeof(newPath));
|
||||
newPath.state = PATH_Open;
|
||||
for(srcpt = 0; srcpt < pPath->numEntriesUsed; srcpt++) {
|
||||
switch(pPath->pFlags[srcpt] & ~PT_CLOSEFIGURE) {
|
||||
case PT_MOVETO:
|
||||
case PT_LINETO:
|
||||
PATH_AddEntry(&newPath, &pPath->pPoints[srcpt],
|
||||
pPath->pFlags[srcpt]);
|
||||
break;
|
||||
case PT_BEZIERTO:
|
||||
PATH_AddFlatBezier(&newPath, &pPath->pPoints[srcpt-1],
|
||||
pPath->pFlags[srcpt+2] & PT_CLOSEFIGURE);
|
||||
srcpt += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
newPath.state = PATH_Closed;
|
||||
PATH_AssignGdiPath(pPath, &newPath);
|
||||
PATH_EmptyPath(&newPath);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* PATH_PathToRegion
|
||||
*
|
||||
* Creates a region from the specified path using the specified polygon
|
||||
|
@ -934,6 +1143,8 @@ static BOOL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode,
|
|||
assert(pPath!=NULL);
|
||||
assert(pHrgn!=NULL);
|
||||
|
||||
PATH_FlattenPath(pPath);
|
||||
|
||||
/* FIXME: What happens when number of points is zero? */
|
||||
|
||||
/* First pass: Find out how many strokes there are in the path */
|
||||
|
@ -1008,6 +1219,7 @@ BOOL PATH_AddEntry(GdiPath *pPath, const POINT *pPoint, BYTE flags)
|
|||
/* FIXME: If newStroke is true, perhaps we want to check that we're
|
||||
* getting a PT_MOVETO
|
||||
*/
|
||||
TRACE("(%ld,%ld) - %d\n", pPoint->x, pPoint->y, flags);
|
||||
|
||||
/* Check that path is open */
|
||||
if(pPath->state!=PATH_Open)
|
||||
|
@ -1225,6 +1437,8 @@ BOOL16 WINAPI FlattenPath16(HDC16 hdc)
|
|||
BOOL WINAPI FlattenPath(HDC hdc)
|
||||
{
|
||||
DC *dc = DC_GetDCPtr( hdc );
|
||||
GdiPath *pPath;
|
||||
TRACE("%08x\n", hdc);
|
||||
|
||||
if(!dc) {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
|
@ -1234,8 +1448,10 @@ BOOL WINAPI FlattenPath(HDC hdc)
|
|||
if(dc->funcs->pFlattenPath)
|
||||
return dc->funcs->pFlattenPath(dc);
|
||||
|
||||
FIXME("stub\n");
|
||||
return 0;
|
||||
pPath = &dc->w.path;
|
||||
if(pPath->state != PATH_Closed)
|
||||
return FALSE;
|
||||
return PATH_FlattenPath(pPath);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
|
|
@ -139,16 +139,6 @@ BOOL TTYDRV_DC_Pie(DC *dc, INT left, INT top, INT right, INT bottom,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_DC_PolyBezier
|
||||
*/
|
||||
BOOL TTYDRV_DC_PolyBezier(DC *dc, const POINT* BezierPoints, DWORD count)
|
||||
{
|
||||
FIXME("(%p, %p, %lu): stub\n", dc, BezierPoints, count);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_DC_Polygon
|
||||
*/
|
||||
|
|
|
@ -63,7 +63,7 @@ static const DC_FUNCTIONS TTYDRV_DC_Driver =
|
|||
TTYDRV_DC_PaintRgn, /* pPaintRgn */
|
||||
TTYDRV_DC_PatBlt, /* pPatBlt */
|
||||
TTYDRV_DC_Pie, /* pPie */
|
||||
TTYDRV_DC_PolyBezier, /* pPolyBezier */
|
||||
NULL, /* pPolyBezier */
|
||||
NULL, /* pPolyBezierTo */
|
||||
NULL, /* pPolyDraw */
|
||||
TTYDRV_DC_PolyPolygon, /* pPolyPolygon */
|
||||
|
|
|
@ -1189,239 +1189,6 @@ X11DRV_ExtFloodFill( DC *dc, INT x, INT y, COLORREF color,
|
|||
return result;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* *Very* simple bezier drawing code,
|
||||
*
|
||||
* It uses a recursive algorithm to divide the curve in a series
|
||||
* of straight line segements. Not ideal but for me sufficient.
|
||||
* If you are in need for something better look for some incremental
|
||||
* algorithm.
|
||||
*
|
||||
* 7 July 1998 Rein Klazes
|
||||
*/
|
||||
|
||||
/*
|
||||
* some macro definitions for bezier drawing
|
||||
*
|
||||
* to avoid trucation errors the coordinates are
|
||||
* shifted upwards. When used in drawing they are
|
||||
* shifted down again, including correct rounding
|
||||
* and avoiding floating point arithmatic
|
||||
* 4 bits should allow 27 bits coordinates which I saw
|
||||
* somewere in the win32 doc's
|
||||
*
|
||||
*/
|
||||
|
||||
#define BEZIERSHIFTBITS 4
|
||||
#define BEZIERSHIFTUP(x) ((x)<<BEZIERSHIFTBITS)
|
||||
#define BEZIERPIXEL BEZIERSHIFTUP(1)
|
||||
#define BEZIERSHIFTDOWN(x) (((x)+(1<<(BEZIERSHIFTBITS-1)))>>BEZIERSHIFTBITS)
|
||||
/* maximum depth of recursion */
|
||||
#define BEZIERMAXDEPTH 8
|
||||
|
||||
/* size of array to store points on */
|
||||
/* enough for one curve */
|
||||
#define BEZMAXPOINTS (150)
|
||||
|
||||
/* calculate Bezier average, in this case the middle
|
||||
* correctly rounded...
|
||||
* */
|
||||
|
||||
#define BEZIERMIDDLE(Mid, P1, P2) \
|
||||
(Mid).x=((P1).x+(P2).x + 1)/2;\
|
||||
(Mid).y=((P1).y+(P2).y + 1)/2;
|
||||
|
||||
/**********************************************************
|
||||
* BezierCheck helper function to check
|
||||
* that recursion can be terminated
|
||||
* Points[0] and Points[3] are begin and endpoint
|
||||
* Points[1] and Points[2] are control points
|
||||
* level is the recursion depth
|
||||
* returns true if the recusion can be terminated
|
||||
*/
|
||||
static BOOL BezierCheck( int level, POINT *Points)
|
||||
{
|
||||
INT dx, dy;
|
||||
dx=Points[3].x-Points[0].x;
|
||||
dy=Points[3].y-Points[0].y;
|
||||
if(ABS(dy)<=ABS(dx)){/* shallow line */
|
||||
/* check that control points are between begin and end */
|
||||
if(Points[1].x < Points[0].x){
|
||||
if(Points[1].x < Points[3].x)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[1].x > Points[3].x)
|
||||
return FALSE;
|
||||
if(Points[2].x < Points[0].x){
|
||||
if(Points[2].x < Points[3].x)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[2].x > Points[3].x)
|
||||
return FALSE;
|
||||
dx=BEZIERSHIFTDOWN(dx);
|
||||
if(!dx) return TRUE;
|
||||
if(abs(Points[1].y-Points[0].y-(dy/dx)*
|
||||
BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
|
||||
abs(Points[2].y-Points[0].y-(dy/dx)*
|
||||
BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL )
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}else{ /* steep line */
|
||||
/* check that control points are between begin and end */
|
||||
if(Points[1].y < Points[0].y){
|
||||
if(Points[1].y < Points[3].y)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[1].y > Points[3].y)
|
||||
return FALSE;
|
||||
if(Points[2].y < Points[0].y){
|
||||
if(Points[2].y < Points[3].y)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[2].y > Points[3].y)
|
||||
return FALSE;
|
||||
dy=BEZIERSHIFTDOWN(dy);
|
||||
if(!dy) return TRUE;
|
||||
if(abs(Points[1].x-Points[0].x-(dx/dy)*
|
||||
BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
|
||||
abs(Points[2].x-Points[0].x-(dx/dy)*
|
||||
BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL )
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_Bezier
|
||||
* Draw a -what microsoft calls- bezier curve
|
||||
* The routine recursively devides the curve
|
||||
* in two parts until a straight line can be drawn
|
||||
*
|
||||
* level recusion depth counted backwards
|
||||
* dc device context
|
||||
* Points array of begin(0), end(3) and control points(1 and 2)
|
||||
* XPoints array with points calculated sofar
|
||||
* *pIx nr points calculated sofar
|
||||
*
|
||||
*/
|
||||
static void X11DRV_Bezier(int level, DC * dc, POINT *Points,
|
||||
XPoint* xpoints, unsigned int* pIx)
|
||||
{
|
||||
X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
|
||||
|
||||
if(*pIx == BEZMAXPOINTS){
|
||||
if (X11DRV_SetupGCForPen( dc ))
|
||||
TSXDrawLines( display, physDev->drawable, physDev->gc,
|
||||
xpoints, *pIx, CoordModeOrigin );
|
||||
*pIx=0;
|
||||
}
|
||||
if(!level || BezierCheck(level, Points)) {
|
||||
if(*pIx == 0){
|
||||
xpoints[*pIx].x= dc->w.DCOrgX + BEZIERSHIFTDOWN(Points[0].x);
|
||||
xpoints[*pIx].y= dc->w.DCOrgY + BEZIERSHIFTDOWN(Points[0].y);
|
||||
*pIx=1;
|
||||
}
|
||||
xpoints[*pIx].x= dc->w.DCOrgX + BEZIERSHIFTDOWN(Points[3].x);
|
||||
xpoints[*pIx].y= dc->w.DCOrgY + BEZIERSHIFTDOWN(Points[3].y);
|
||||
(*pIx) ++;
|
||||
} else {
|
||||
POINT Points2[4]; /* for the second recursive call */
|
||||
Points2[3]=Points[3];
|
||||
BEZIERMIDDLE(Points2[2], Points[2], Points[3]);
|
||||
BEZIERMIDDLE(Points2[0], Points[1], Points[2]);
|
||||
BEZIERMIDDLE(Points2[1],Points2[0],Points2[2]);
|
||||
|
||||
BEZIERMIDDLE(Points[1], Points[0], Points[1]);
|
||||
BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
|
||||
BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
|
||||
|
||||
Points2[0]=Points[3];
|
||||
|
||||
/* do the two halves */
|
||||
X11DRV_Bezier(level-1, dc, Points, xpoints, pIx);
|
||||
X11DRV_Bezier(level-1, dc, Points2, xpoints, pIx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_InternalPolyBezier
|
||||
* Implement functionality for PolyBezier and PolyBezierTo
|
||||
* calls.
|
||||
* [i] dc pointer to device context
|
||||
* [i] start, first point in curve
|
||||
* [i] BezierPoints , array of point filled with rest of the points
|
||||
* [i] count, number of points in BezierPoints, must be a
|
||||
* multiple of 3.
|
||||
*/
|
||||
static BOOL
|
||||
X11DRV_InternalPolyBezier(DC *dc, POINT start, const POINT* BezierPoints,
|
||||
DWORD count)
|
||||
{
|
||||
POINT Points[4];
|
||||
int i;
|
||||
unsigned int ix=0;
|
||||
XPoint* xpoints;
|
||||
X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
|
||||
|
||||
TRACE("dc=%p count=%ld %ld,%ld - %ld,%ld - %ld,%ld - %ld,%ld\n",
|
||||
dc, count,
|
||||
start.x, start.y,
|
||||
(BezierPoints+0)->x, (BezierPoints+0)->y,
|
||||
(BezierPoints+1)->x, (BezierPoints+1)->y,
|
||||
(BezierPoints+2)->x, (BezierPoints+2)->y);
|
||||
if(!count || count % 3){/* paranoid */
|
||||
WARN(" bad value for count : %ld\n", count);
|
||||
return FALSE;
|
||||
}
|
||||
xpoints=(XPoint*) xmalloc( sizeof(XPoint)*BEZMAXPOINTS);
|
||||
start.x=BEZIERSHIFTUP(XLPTODP(dc,start.x));
|
||||
start.y=BEZIERSHIFTUP(YLPTODP(dc,start.y));
|
||||
while(count){
|
||||
Points[0]=start;
|
||||
for(i=1;i<4;i++) {
|
||||
Points[i].x= BEZIERSHIFTUP(XLPTODP(dc,BezierPoints->x));
|
||||
Points[i].y= BEZIERSHIFTUP(YLPTODP(dc,BezierPoints->y));
|
||||
BezierPoints++;
|
||||
}
|
||||
start=Points[3];
|
||||
X11DRV_Bezier(BEZIERMAXDEPTH , dc, Points, xpoints, &ix );
|
||||
count -=3;
|
||||
}
|
||||
if (ix && X11DRV_SetupGCForPen( dc ))
|
||||
TSXDrawLines( display, physDev->drawable, physDev->gc,
|
||||
xpoints, ix, CoordModeOrigin );
|
||||
free(xpoints);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* X11DRV_PolyBezier
|
||||
*/
|
||||
BOOL
|
||||
X11DRV_PolyBezier(DC *dc, const POINT *Points, DWORD count)
|
||||
{
|
||||
return X11DRV_InternalPolyBezier(dc, Points[0], Points+1, count-1);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* X11DRV_PolyBezierTo
|
||||
*/
|
||||
BOOL
|
||||
X11DRV_PolyBezierTo(DC *dc, const POINT *Points, DWORD count)
|
||||
{
|
||||
POINT pt;
|
||||
|
||||
pt.x = dc->w.CursPosX;
|
||||
pt.y = dc->w.CursPosY;
|
||||
return X11DRV_InternalPolyBezier(dc, pt, Points, count);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* X11DRV_SetBkColor
|
||||
*/
|
||||
|
|
|
@ -78,8 +78,8 @@ static const DC_FUNCTIONS X11DRV_Funcs =
|
|||
X11DRV_PaintRgn, /* pPaintRgn */
|
||||
X11DRV_PatBlt, /* pPatBlt */
|
||||
X11DRV_Pie, /* pPie */
|
||||
X11DRV_PolyBezier, /* pPolyBezier */
|
||||
X11DRV_PolyBezierTo, /* pPolyBezierTo */
|
||||
NULL, /* pPolyBezier */
|
||||
NULL, /* pPolyBezierTo */
|
||||
NULL, /* pPolyDraw */
|
||||
X11DRV_PolyPolygon, /* pPolyPolygon */
|
||||
X11DRV_PolyPolyline, /* pPolyPolyline */
|
||||
|
|
|
@ -467,4 +467,8 @@ extern BOOL DRIVER_RegisterDriver( LPCSTR name, const DC_FUNCTIONS *funcs );
|
|||
extern const DC_FUNCTIONS *DRIVER_FindDriver( LPCSTR name );
|
||||
extern BOOL DRIVER_UnregisterDriver( LPCSTR name );
|
||||
extern BOOL DRIVER_GetDriverName( LPCSTR device, LPSTR driver, DWORD size );
|
||||
|
||||
extern POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut );
|
||||
|
||||
|
||||
#endif /* __WINE_GDI_H */
|
||||
|
|
|
@ -74,6 +74,8 @@ extern BOOL MFDRV_PatBlt( DC *dc, INT left, INT top, INT width, INT height,
|
|||
extern BOOL MFDRV_Pie( DC *dc, INT left, INT top, INT right,
|
||||
INT bottom, INT xstart, INT ystart, INT xend,
|
||||
INT yend );
|
||||
extern BOOL MFDRV_PolyBezier( DC *dc, const POINT* pt, DWORD count );
|
||||
extern BOOL MFDRV_PolyBezierTo( DC *dc, const POINT* pt, DWORD count );
|
||||
extern BOOL MFDRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts,
|
||||
UINT polygons);
|
||||
extern BOOL MFDRV_Polygon( DC *dc, const POINT* pt, INT count );
|
||||
|
|
|
@ -51,6 +51,14 @@ extern BOOL PATH_Ellipse(HDC hdc, INT x1, INT y1,
|
|||
extern BOOL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2,
|
||||
INT xStart, INT yStart, INT xEnd, INT yEnd);
|
||||
extern BOOL PATH_PolyBezierTo(HDC hdc, const POINT *pt, DWORD cbCount);
|
||||
extern BOOL PATH_PolyBezier(HDC hdc, const POINT *pt, DWORD cbCount);
|
||||
extern BOOL PATH_PolylineTo(HDC hdc, const POINT *pt, DWORD cbCount);
|
||||
extern BOOL PATH_Polyline(HDC hdc, const POINT *pt, DWORD cbCount);
|
||||
extern BOOL PATH_Polygon(HDC hdc, const POINT *pt, DWORD cbCount);
|
||||
extern BOOL PATH_PolyPolyline(HDC hdc, const POINT *pt, const DWORD *counts,
|
||||
DWORD polylines);
|
||||
extern BOOL PATH_PolyPolygon(HDC hdc, const POINT *pt, const INT *counts,
|
||||
UINT polygons);
|
||||
#endif /* __WINE_PATH_H */
|
||||
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ extern HANDLE TTYDRV_DC_LoadOEMResource(WORD resid, WORD type);
|
|||
extern BOOL TTYDRV_DC_PaintRgn(struct tagDC *dc, HRGN hrgn);
|
||||
extern BOOL TTYDRV_DC_PatBlt(struct tagDC *dc, INT left, INT top, INT width, INT height, DWORD rop);
|
||||
extern BOOL TTYDRV_DC_Pie(struct tagDC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
|
||||
extern BOOL TTYDRV_DC_PolyBezier(struct tagDC *dc, const POINT* BezierPoints, DWORD count);
|
||||
extern BOOL TTYDRV_DC_Polygon(struct tagDC *dc, const POINT* pt, INT count);
|
||||
extern BOOL TTYDRV_DC_Polyline(struct tagDC *dc, const POINT* pt, INT count);
|
||||
extern BOOL TTYDRV_DC_PolyPolygon(struct tagDC *dc, const POINT* pt, const INT* counts, UINT polygons);
|
||||
|
|
|
@ -125,10 +125,6 @@ extern COLORREF X11DRV_SetPixel( struct tagDC *dc, INT x, INT y,
|
|||
extern COLORREF X11DRV_GetPixel( struct tagDC *dc, INT x, INT y);
|
||||
extern BOOL X11DRV_PaintRgn( struct tagDC *dc, HRGN hrgn );
|
||||
extern BOOL X11DRV_Polyline( struct tagDC *dc,const POINT* pt,INT count);
|
||||
extern BOOL X11DRV_PolyBezier( struct tagDC *dc, const POINT* lppt,
|
||||
DWORD cPoints);
|
||||
extern BOOL X11DRV_PolyBezierTo( struct tagDC *dc, const POINT* lppt,
|
||||
DWORD cPoints);
|
||||
extern BOOL X11DRV_Polygon( struct tagDC *dc, const POINT* pt, INT count );
|
||||
extern BOOL X11DRV_PolyPolygon( struct tagDC *dc, const POINT* pt,
|
||||
const INT* counts, UINT polygons);
|
||||
|
|
Loading…
Reference in New Issue