From c059c056e55ab968ac7c513bbd96720655e06da3 Mon Sep 17 00:00:00 2001 From: fvogel Date: Mon, 31 Dec 2018 13:27:01 +0000 Subject: Fix proposal by Simon Geard for [6ce6e74635]: TIP415 implementation does not handle small arcs correctly --- generic/tkCanvArc.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/generic/tkCanvArc.c b/generic/tkCanvArc.c index 8bc1781..02deebe 100644 --- a/generic/tkCanvArc.c +++ b/generic/tkCanvArc.c @@ -13,6 +13,8 @@ #include "tkInt.h" #include "tkCanvas.h" +#include "float.h" + /* * The structure below defines the record for each arc item. */ @@ -183,7 +185,7 @@ static void ComputeArcBbox(Tk_Canvas canvas, ArcItem *arcPtr); static int ConfigureArc(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[], int flags); -static void ComputeArcFromHeight(ArcItem *arcPtr); +static int ComputeArcFromHeight(ArcItem *arcPtr); static int CreateArc(Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]); @@ -473,7 +475,14 @@ ConfigureArc( * overridden. */ if (arcPtr->height != 0) { - ComputeArcFromHeight(arcPtr); + int ret = ComputeArcFromHeight(arcPtr); + if (ret != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "coordinates too close to define a chord")); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC", + NULL); + return ret; + } ComputeArcBbox(canvas, arcPtr); } @@ -593,7 +602,7 @@ ConfigureArc( * end-point and height (!= 0). * * Results: - * None. + * TCL_ERROR if the chord length is zero, TCL_OK otherwise. * * Side effects: * The height parameter is set to 0 on exit. @@ -601,7 +610,7 @@ ConfigureArc( *-------------------------------------------------------------- */ -static void +static int ComputeArcFromHeight( ArcItem* arcPtr) { @@ -613,6 +622,10 @@ ComputeArcFromHeight( chordLen = hypot(arcPtr->endPoint[1] - arcPtr->startPoint[1], arcPtr->startPoint[0] - arcPtr->endPoint[0]); + + if (chordLen < DBL_EPSILON) + return TCL_ERROR; + chordDir[0] = (arcPtr->endPoint[0] - arcPtr->startPoint[0]) / chordLen; chordDir[1] = (arcPtr->endPoint[1] - arcPtr->startPoint[1]) / chordLen; chordCen[0] = (arcPtr->startPoint[0] + arcPtr->endPoint[0]) / 2; @@ -666,6 +679,8 @@ ComputeArcFromHeight( */ arcPtr->height = 0; + + return TCL_OK; } /* -- cgit v0.12