Evan Stade : gdi32: Improved PolyDraw in path closed case.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Jul 19 07:59:54 CDT 2007
Module: wine
Branch: master
Commit: 099bfbe1a4e0cd53fc6d22326740eb2356c3953e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=099bfbe1a4e0cd53fc6d22326740eb2356c3953e
Author: Evan Stade <estade at gmail.com>
Date: Wed Jul 18 19:41:13 2007 -0700
gdi32: Improved PolyDraw in path closed case.
---
dlls/gdi32/painting.c | 107 +++++++++++++++++++++++++++++++------------------
1 files changed, 68 insertions(+), 39 deletions(-)
diff --git a/dlls/gdi32/painting.c b/dlls/gdi32/painting.c
index ed3f9b0..6276e8c 100644
--- a/dlls/gdi32/painting.c
+++ b/dlls/gdi32/painting.c
@@ -824,8 +824,8 @@ BOOL WINAPI PolyDraw(HDC hdc, const POINT *lppt, const BYTE *lpbTypes,
{
DC *dc;
BOOL result = FALSE;
- POINT lastmove;
- unsigned int i;
+ POINT * line_pts = NULL, * bzr_pts = NULL, bzr[4];
+ INT i, num_pts, num_bzr_pts, space, size;
dc = DC_GetDCUpdate( hdc );
if(!dc) return FALSE;
@@ -835,47 +835,76 @@ BOOL WINAPI PolyDraw(HDC hdc, const POINT *lppt, const BYTE *lpbTypes,
else if(dc->funcs->pPolyDraw)
result = dc->funcs->pPolyDraw( dc->physDev, lppt, lpbTypes, cCount );
else {
- /* check for each bezierto if there are two more points */
- for( i = 0; i < cCount; i++ )
- if( lpbTypes[i] != PT_MOVETO &&
- lpbTypes[i] & PT_BEZIERTO )
- {
- if( cCount < i+3 )
- goto end;
- else
- i += 2;
- }
+ /* check for valid point types */
+ for(i = 0; i < cCount; i++) {
+ switch(lpbTypes[i]) {
+ case PT_MOVETO:
+ case PT_LINETO | PT_CLOSEFIGURE:
+ case PT_LINETO:
+ break;
+ case PT_BEZIERTO:
+ if((i + 2 < cCount) && (lpbTypes[i + 1] == PT_BEZIERTO) &&
+ ((lpbTypes[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)){
+ i += 2;
+ break;
+ }
+ default:
+ goto end;
+ }
+ }
- /* if no moveto occurs, we will close the figure here */
- lastmove.x = dc->CursPosX;
- lastmove.y = dc->CursPosY;
+ space = cCount + 300;
+ line_pts = HeapAlloc(GetProcessHeap(), 0, space * sizeof(POINT));
+ num_pts = 1;
+
+ line_pts[0].x = dc->CursPosX;
+ line_pts[0].y = dc->CursPosY;
+
+ for(i = 0; i < cCount; i++) {
+ switch(lpbTypes[i]) {
+ case PT_MOVETO:
+ if(num_pts >= 2)
+ Polyline(dc->hSelf, line_pts, num_pts);
+ num_pts = 0;
+ line_pts[num_pts++] = lppt[i];
+ break;
+ case PT_LINETO:
+ case (PT_LINETO | PT_CLOSEFIGURE):
+ line_pts[num_pts++] = lppt[i];
+ break;
+ case PT_BEZIERTO:
+ bzr[0].x = line_pts[num_pts - 1].x;
+ bzr[0].y = line_pts[num_pts - 1].y;
+ memcpy(&bzr[1], &lppt[i], 3 * sizeof(POINT));
+
+ bzr_pts = GDI_Bezier(bzr, 4, &num_bzr_pts);
+
+ size = num_pts + (cCount - i) + num_bzr_pts;
+ if(space < size){
+ space = size * 2;
+ line_pts = HeapReAlloc(GetProcessHeap(), 0, line_pts,
+ space * sizeof(POINT));
+ }
+ memcpy(&line_pts[num_pts], &bzr_pts[1],
+ (num_bzr_pts - 1) * sizeof(POINT));
+ num_pts += num_bzr_pts - 1;
+ HeapFree(GetProcessHeap(), 0, bzr_pts);
+ i += 2;
+ break;
+ default:
+ goto end;
+ }
- /* now let's draw */
- for( i = 0; i < cCount; i++ )
- {
- if( lpbTypes[i] == PT_MOVETO )
- {
- MoveToEx( hdc, lppt[i].x, lppt[i].y, NULL );
- lastmove.x = dc->CursPosX;
- lastmove.y = dc->CursPosY;
- }
- else if( lpbTypes[i] & PT_LINETO )
- LineTo( hdc, lppt[i].x, lppt[i].y );
- else if( lpbTypes[i] & PT_BEZIERTO )
- {
- PolyBezierTo( hdc, &lppt[i], 3 );
- i += 2;
- }
- else
- goto end;
+ if(lpbTypes[i] & PT_CLOSEFIGURE)
+ line_pts[num_pts++] = line_pts[0];
+ }
- if( lpbTypes[i] & PT_CLOSEFIGURE )
- {
- LineTo( hdc, lastmove.x, lastmove.y );
- }
- }
+ if(num_pts >= 2)
+ Polyline(dc->hSelf, line_pts, num_pts);
+
+ MoveToEx(dc->hSelf, line_pts[num_pts - 1].x, line_pts[num_pts - 1].y, NULL);
- result = TRUE;
+ result = TRUE;
}
end:
More information about the wine-cvs
mailing list