From: David Kahurani k.kahurani@gmail.com
Signed-off-by: David Kahurani k.kahurani@gmail.com --- dlls/gdiplus/graphics.c | 103 ++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 58 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 3845ce376ca..5e027e29631 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -50,6 +50,7 @@ static GpStatus draw_driver_string(GpGraphics *graphics, GDIPCONST UINT16 *text, GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix);
+static GpStatus SOFTWARE_GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *path); /* Converts from gdiplus path point type to gdi path point type. */ static BYTE convert_path_point_type(BYTE type) { @@ -1921,28 +1922,28 @@ static void shorten_bezier_amt(GpPointF * pt, REAL amt, BOOL rev) }
/* Draws a combination of bezier curves and lines between points. */ -static GpStatus draw_poly(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF * pt, - GDIPCONST BYTE * types, INT count, BOOL caps) +static GpStatus draw_path(GpGraphics *graphics, GpPen *pen, GpPath *path, BOOL caps) { - POINT *pti = heap_alloc_zero(count * sizeof(POINT)); - BYTE *tp = heap_alloc_zero(count); - GpPointF *ptcopy = heap_alloc_zero(count * sizeof(GpPointF)); - INT i, j; + GpPath *clonedpath; + INT i, count = path->pathdata.Count; GpStatus status = GenericError;
- if(!count){ + if(!path->pathdata.Count){ status = Ok; goto end; } - if(!pti || !tp || !ptcopy){ + + GdipClonePath(path, &clonedpath); + + if(!clonedpath){ status = OutOfMemory; goto end; }
- for(i = 1; i < count; i++){ - if((types[i] & PathPointTypePathTypeMask) == PathPointTypeBezier){ - if((i + 2 >= count) || !(types[i + 1] & PathPointTypeBezier) - || !(types[i + 2] & PathPointTypeBezier)){ + for(i = 1; i < clonedpath->pathdata.Count; i++){ + if((clonedpath->pathdata.Types[i] & PathPointTypePathTypeMask) == PathPointTypeBezier){ + if((i + 2 >= count) || !(clonedpath->pathdata.Types[i + 1] & PathPointTypeBezier) + || !(clonedpath->pathdata.Types[i + 2] & PathPointTypeBezier)){ ERR("Bad bezier points\n"); goto end; } @@ -1950,38 +1951,36 @@ static GpStatus draw_poly(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF * } }
- memcpy(ptcopy, pt, count * sizeof(GpPointF)); - /* If we are drawing caps, go through the points and adjust them accordingly, * and draw the caps. */ if(caps){ - switch(types[count - 1] & PathPointTypePathTypeMask){ + switch(clonedpath->pathdata.Types[count - 1] & PathPointTypePathTypeMask){ case PathPointTypeBezier: if(pen->endcap == LineCapArrowAnchor) - shorten_bezier_amt(&ptcopy[count - 4], pen->width, FALSE); + shorten_bezier_amt(&clonedpath->pathdata.Points[count - 4], pen->width, FALSE); else if((pen->endcap == LineCapCustom) && pen->customend) - shorten_bezier_amt(&ptcopy[count - 4], + shorten_bezier_amt(&clonedpath->pathdata.Points[count - 4], pen->width * pen->customend->inset, FALSE);
draw_cap(graphics, get_gdi_brush_color(pen->brush), pen->endcap, pen->width, pen->customend, - pt[count - 1].X - (ptcopy[count - 1].X - ptcopy[count - 2].X), - pt[count - 1].Y - (ptcopy[count - 1].Y - ptcopy[count - 2].Y), - pt[count - 1].X, pt[count - 1].Y); + path->pathdata.Points[count - 1].X - (clonedpath->pathdata.Points[count - 1].X - clonedpath->pathdata.Points[count - 2].X), + path->pathdata.Points[count - 1].Y - (clonedpath->pathdata.Points[count - 1].Y - clonedpath->pathdata.Points[count - 2].Y), + path->pathdata.Points[count - 1].X, path->pathdata.Points[count - 1].Y);
break; case PathPointTypeLine: if(pen->endcap == LineCapArrowAnchor) - shorten_line_amt(ptcopy[count - 2].X, ptcopy[count - 2].Y, - &ptcopy[count - 1].X, &ptcopy[count - 1].Y, + shorten_line_amt(clonedpath->pathdata.Points[count - 2].X, clonedpath->pathdata.Points[count - 2].Y, + &clonedpath->pathdata.Points[count - 1].X, &clonedpath->pathdata.Points[count - 1].Y, pen->width); else if((pen->endcap == LineCapCustom) && pen->customend) - shorten_line_amt(ptcopy[count - 2].X, ptcopy[count - 2].Y, - &ptcopy[count - 1].X, &ptcopy[count - 1].Y, + shorten_line_amt(clonedpath->pathdata.Points[count - 2].X, clonedpath->pathdata.Points[count - 2].Y, + &clonedpath->pathdata.Points[count - 1].X, &clonedpath->pathdata.Points[count - 1].Y, pen->customend->inset * pen->width);
draw_cap(graphics, get_gdi_brush_color(pen->brush), pen->endcap, pen->width, pen->customend, - pt[count - 2].X, pt[count - 2].Y, pt[count - 1].X, - pt[count - 1].Y); + path->pathdata.Points[count - 2].X, path->pathdata.Points[count - 2].Y, path->pathdata.Points[count - 1].X, + path->pathdata.Points[count - 1].Y);
break; default: @@ -1990,36 +1989,36 @@ static GpStatus draw_poly(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF * }
/* Find start of points */ - for(j = 1; j < count && ((types[j] & PathPointTypePathTypeMask) - == PathPointTypeStart); j++); + for(i = 1; i < count && ((clonedpath->pathdata.Types[i] & PathPointTypePathTypeMask) + == PathPointTypeStart); i++);
- switch(types[j] & PathPointTypePathTypeMask){ + switch(clonedpath->pathdata.Types[i] & PathPointTypePathTypeMask){ case PathPointTypeBezier: if(pen->startcap == LineCapArrowAnchor) - shorten_bezier_amt(&ptcopy[j - 1], pen->width, TRUE); + shorten_bezier_amt(&clonedpath->pathdata.Points[i - 1], pen->width, TRUE); else if((pen->startcap == LineCapCustom) && pen->customstart) - shorten_bezier_amt(&ptcopy[j - 1], + shorten_bezier_amt(&clonedpath->pathdata.Points[i - 1], pen->width * pen->customstart->inset, TRUE);
draw_cap(graphics, get_gdi_brush_color(pen->brush), pen->startcap, pen->width, pen->customstart, - pt[j - 1].X - (ptcopy[j - 1].X - ptcopy[j].X), - pt[j - 1].Y - (ptcopy[j - 1].Y - ptcopy[j].Y), - pt[j - 1].X, pt[j - 1].Y); + path->pathdata.Points[i - 1].X - (clonedpath->pathdata.Points[i - 1].X - clonedpath->pathdata.Points[i].X), + path->pathdata.Points[i - 1].Y - (clonedpath->pathdata.Points[i - 1].Y - clonedpath->pathdata.Points[i].Y), + path->pathdata.Points[i - 1].X, path->pathdata.Points[i - 1].Y);
break; case PathPointTypeLine: if(pen->startcap == LineCapArrowAnchor) - shorten_line_amt(ptcopy[j].X, ptcopy[j].Y, - &ptcopy[j - 1].X, &ptcopy[j - 1].Y, + shorten_line_amt(clonedpath->pathdata.Points[i].X, clonedpath->pathdata.Points[i].Y, + &clonedpath->pathdata.Points[i - 1].X, &clonedpath->pathdata.Points[i - 1].Y, pen->width); else if((pen->startcap == LineCapCustom) && pen->customstart) - shorten_line_amt(ptcopy[j].X, ptcopy[j].Y, - &ptcopy[j - 1].X, &ptcopy[j - 1].Y, + shorten_line_amt(clonedpath->pathdata.Points[i].X, clonedpath->pathdata.Points[i].Y, + &clonedpath->pathdata.Points[i - 1].X, &clonedpath->pathdata.Points[i - 1].Y, pen->customstart->inset * pen->width);
draw_cap(graphics, get_gdi_brush_color(pen->brush), pen->startcap, pen->width, pen->customstart, - pt[j].X, pt[j].Y, pt[j - 1].X, - pt[j - 1].Y); + path->pathdata.Points[i].X, path->pathdata.Points[i].Y, path->pathdata.Points[i - 1].X, + path->pathdata.Points[i - 1].Y);
break; default: @@ -2028,23 +2027,13 @@ static GpStatus draw_poly(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF * } }
- gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, ptcopy, count); - - round_points(pti, ptcopy, count); - - for(i = 0; i < count; i++){ - tp[i] = convert_path_point_type(types[i]); - } - - PolyDraw(graphics->hdc, pti, tp, count); + GdipCreatePath(FillModeAlternate, &path); + SOFTWARE_GdipFillPath(graphics, pen->brush, clonedpath);
status = Ok;
end: - heap_free(pti); - heap_free(ptcopy); - heap_free(tp); - + GdipDeletePath(clonedpath); return status; }
@@ -3659,8 +3648,7 @@ static GpStatus GDI32_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *pat
gdi_transform_acquire(graphics);
- retval = draw_poly(graphics, pen, path->pathdata.Points, - path->pathdata.Types, path->pathdata.Count, TRUE); + retval = draw_path(graphics, pen, path, TRUE);
gdi_transform_release(graphics);
@@ -4340,8 +4328,7 @@ static GpStatus GDI32_GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath gdi_transform_acquire(graphics);
BeginPath(graphics->hdc); - retval = draw_poly(graphics, NULL, path->pathdata.Points, - path->pathdata.Types, path->pathdata.Count, FALSE); + retval = draw_path(graphics, NULL, path, FALSE);
if(retval == Ok) { @@ -4634,7 +4621,7 @@ static GpStatus GDI32_GdipFillRegion(GpGraphics* graphics, GpBrush* brush, ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY); DeleteObject(hrgn);
- status = GdipGetRegionHRgn(region, graphics, &hrgn); + status = get_region_hrgn(®ion->node, graphics, FALSE, &hrgn); if (status != Ok) { RestoreDC(graphics->hdc, save_state);