Nikolay Sivov : gdiplus: Implement unfilled mode for arrow caps.
Alexandre Julliard
julliard at winehq.org
Mon May 14 17:20:10 CDT 2018
Module: wine
Branch: master
Commit: 39c8ebddcc302dac896dcd594a43b16e52d723c4
URL: https://source.winehq.org/git/wine.git/?a=commit;h=39c8ebddcc302dac896dcd594a43b16e52d723c4
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon May 14 07:59:36 2018 +0300
gdiplus: Implement unfilled mode for arrow caps.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/gdiplus/customlinecap.c | 75 +++++++++++++++++++++++---------------
dlls/gdiplus/tests/customlinecap.c | 5 +--
2 files changed, 46 insertions(+), 34 deletions(-)
diff --git a/dlls/gdiplus/customlinecap.c b/dlls/gdiplus/customlinecap.c
index 7fbe8b6..c74928e 100644
--- a/dlls/gdiplus/customlinecap.c
+++ b/dlls/gdiplus/customlinecap.c
@@ -282,19 +282,43 @@ GpStatus WINGDIPAPI GdipGetCustomLineCapType(GpCustomLineCap *customCap, CustomL
static void arrowcap_update_path(GpAdjustableArrowCap *cap)
{
+ static const BYTE types_filled[] =
+ {
+ PathPointTypeStart, PathPointTypeLine, PathPointTypeLine, PathPointTypeLine | PathPointTypeCloseSubpath
+ };
+ static const BYTE types_unfilled[] =
+ {
+ PathPointTypeStart, PathPointTypeLine, PathPointTypeLine
+ };
GpPointF *points;
- assert(cap->cap.pathdata.Count == 4);
+ assert(cap->cap.pathdata.Count == 3 || cap->cap.pathdata.Count == 4);
points = cap->cap.pathdata.Points;
- points[0].X = 0.0;
- points[0].Y = 0.0;
- points[1].X = -cap->width / 2.0;
- points[1].Y = -cap->height;
- points[2].X = 0.0;
- points[2].Y = -cap->height - cap->middle_inset;
- points[3].X = cap->width / 2.0;
- points[3].Y = -cap->height;
+ if (cap->cap.fill)
+ {
+ memcpy(cap->cap.pathdata.Types, types_filled, sizeof(types_filled));
+ cap->cap.pathdata.Count = 4;
+ points[0].X = -cap->width / 2.0;
+ points[0].Y = -cap->height;
+ points[1].X = 0.0;
+ points[1].Y = 0.0;
+ points[2].X = cap->width / 2.0;
+ points[2].Y = -cap->height;
+ points[3].X = 0.0;
+ points[3].Y = -cap->height - cap->middle_inset;
+ }
+ else
+ {
+ memcpy(cap->cap.pathdata.Types, types_unfilled, sizeof(types_unfilled));
+ cap->cap.pathdata.Count = 3;
+ points[0].X = -cap->width / 4.0;
+ points[0].Y = -cap->height / 2.0;
+ points[1].X = 0.0;
+ points[1].Y = 0.0;
+ points[2].X = cap->width / 4.0;
+ points[2].Y = -cap->height / 2.0;
+ }
if (cap->width == 0.0)
cap->cap.inset = 0.0;
@@ -306,7 +330,6 @@ GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL f
GpAdjustableArrowCap **cap)
{
GpPathData pathdata;
- BYTE types[4];
GpStatus stat;
TRACE("(%0.2f,%0.2f,%i,%p)\n", height, width, fill, cap);
@@ -314,22 +337,15 @@ GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL f
if (!cap)
return InvalidParameter;
- if (!fill)
- FIXME("Arrows without fills are not supported.\n");
-
*cap = heap_alloc_zero(sizeof(**cap));
if (!*cap)
return OutOfMemory;
- types[0] = PathPointTypeStart;
- types[1] = PathPointTypeLine;
- types[2] = PathPointTypeLine;
- types[3] = PathPointTypeLine | PathPointTypeCloseSubpath;
-
+ /* We'll need 4 points at most. */
pathdata.Count = 4;
pathdata.Points = NULL;
- pathdata.Types = types;
- stat = init_custom_linecap(&(*cap)->cap, &pathdata, TRUE, LineCapTriangle, width != 0.0 ? height / width : 0.0);
+ pathdata.Types = NULL;
+ stat = init_custom_linecap(&(*cap)->cap, &pathdata, fill, LineCapTriangle, width != 0.0 ? height / width : 0.0);
if (stat != Ok)
{
heap_free(*cap);
@@ -347,14 +363,13 @@ GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL f
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL* fill)
{
- static int calls;
-
TRACE("(%p,%p)\n", cap, fill);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap || !fill)
+ return InvalidParameter;
- return NotImplemented;
+ *fill = cap->cap.fill;
+ return Ok;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL* height)
@@ -392,14 +407,14 @@ GpStatus WINGDIPAPI GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, RE
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL fill)
{
- static int calls;
-
TRACE("(%p,%i)\n", cap, fill);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap)
+ return InvalidParameter;
- return NotImplemented;
+ cap->cap.fill = fill;
+ arrowcap_update_path(cap);
+ return Ok;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL height)
diff --git a/dlls/gdiplus/tests/customlinecap.c b/dlls/gdiplus/tests/customlinecap.c
index 6a22c26..e4ec329 100644
--- a/dlls/gdiplus/tests/customlinecap.c
+++ b/dlls/gdiplus/tests/customlinecap.c
@@ -250,16 +250,13 @@ static void test_create_adjustable_cap(void)
ok(stat == Ok, "Failed to create adjustable cap, %d\n", stat);
stat = GdipGetAdjustableArrowCapFillState(cap, NULL);
-todo_wine
ok(stat == InvalidParameter, "Unexpected return code, %d\n", stat);
ret = FALSE;
stat = GdipGetAdjustableArrowCapFillState(cap, &ret);
-todo_wine
-{
ok(stat == Ok, "Unexpected return code, %d\n", stat);
ok(ret, "Unexpected fill state %d\n", ret);
-}
+
stat = GdipGetAdjustableArrowCapHeight(cap, NULL);
ok(stat == InvalidParameter, "Unexpected return code, %d\n", stat);
More information about the wine-cvs
mailing list