diff options
Diffstat (limited to 'generic/tkCanvUtil.c')
-rw-r--r-- | generic/tkCanvUtil.c | 1136 |
1 files changed, 596 insertions, 540 deletions
diff --git a/generic/tkCanvUtil.c b/generic/tkCanvUtil.c index ff0d720..c249243 100644 --- a/generic/tkCanvUtil.c +++ b/generic/tkCanvUtil.c @@ -1,16 +1,15 @@ -/* +/* * tkCanvUtil.c -- * - * This procedure contains a collection of utility procedures - * used by the implementations of various canvas item types. + * This procedure contains a collection of utility procedures used by the + * implementations of various canvas item types. * * Copyright (c) 1994 Sun Microsystems, Inc. - * Copyright (c) 1994 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvUtil.c,v 1.12 2004/08/19 14:41:52 dkf Exp $ + * RCS: @(#) $Id: tkCanvUtil.c,v 1.13 2005/10/17 20:23:29 dkf Exp $ */ #include "tkInt.h" @@ -23,38 +22,36 @@ */ typedef struct SmoothAssocData { - struct SmoothAssocData *nextPtr; /* pointer to next SmoothAssocData */ - Tk_SmoothMethod smooth; /* name and functions associated with - * this option */ + struct SmoothAssocData *nextPtr; + /* Pointer to next SmoothAssocData. */ + Tk_SmoothMethod smooth; /* Name and functions associated with this + * option. */ } SmoothAssocData; Tk_SmoothMethod tkBezierSmoothMethod = { "true", TkMakeBezierCurve, - (void (*) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, - double *coordPtr, int numPoints, int numSteps))) - TkMakeBezierPostscript, + (void (*) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, + int numPoints, int numSteps)) TkMakeBezierPostscript, }; static Tk_SmoothMethod tkRawSmoothMethod = { "raw", TkMakeRawCurve, - (void (*) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, - double *coordPtr, int numPoints, int numSteps))) - TkMakeRawCurvePostscript, + (void (*) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, + int numPoints, int numSteps)) TkMakeRawCurvePostscript, }; /* * Function forward-declarations. */ -static void SmoothMethodCleanupProc _ANSI_ARGS_(( - ClientData clientData, Tcl_Interp *interp)); -static SmoothAssocData *InitSmoothMethods _ANSI_ARGS_((Tcl_Interp *interp)); -static int DashConvert _ANSI_ARGS_((char *l, CONST char *p, - int n, double width)); -static void translateAndAppendCoords _ANSI_ARGS_(( - TkCanvas *canvPtr, double x, double y, - XPoint *outArr, int numOut)); +static void SmoothMethodCleanupProc(ClientData clientData, + Tcl_Interp *interp); +static SmoothAssocData *InitSmoothMethods(Tcl_Interp *interp); +static int DashConvert(char *l, CONST char *p, int n, + double width); +static void TranslateAndAppendCoords(TkCanvas *canvPtr, + double x, double y, XPoint *outArr, int numOut); #define ABS(a) ((a>=0)?(a):(-(a))) @@ -63,8 +60,8 @@ static void translateAndAppendCoords _ANSI_ARGS_(( * * Tk_CanvasTkwin -- * - * Given a token for a canvas, this procedure returns the - * widget that represents the canvas. + * Given a token for a canvas, this procedure returns the widget that + * represents the canvas. * * Results: * The return value is a handle for the widget. @@ -76,8 +73,8 @@ static void translateAndAppendCoords _ANSI_ARGS_(( */ Tk_Window -Tk_CanvasTkwin(canvas) - Tk_Canvas canvas; /* Token for the canvas. */ +Tk_CanvasTkwin( + Tk_Canvas canvas) /* Token for the canvas. */ { TkCanvas *canvasPtr = (TkCanvas *) canvas; return canvasPtr->tkwin; @@ -93,11 +90,10 @@ Tk_CanvasTkwin(canvas) * be drawn in the drawable used for display. * * Results: - * There is no return value. The values at *drawableXPtr and - * *drawableYPtr are filled in with the coordinates at which - * x and y should be drawn. These coordinates are clipped - * to fit within a "short", since this is what X uses in - * most cases for drawing. + * There is no return value. The values at *drawableXPtr and + * *drawableYPtr are filled in with the coordinates at which x and y + * should be drawn. These coordinates are clipped to fit within a + * "short", since this is what X uses in most cases for drawing. * * Side effects: * None. @@ -106,11 +102,12 @@ Tk_CanvasTkwin(canvas) */ void -Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr) - Tk_Canvas canvas; /* Token for the canvas. */ - double x, y; /* Coordinates in canvas space. */ - short *drawableXPtr, *drawableYPtr; /* Screen coordinates are stored - * here. */ +Tk_CanvasDrawableCoords( + Tk_Canvas canvas, /* Token for the canvas. */ + double x, /* Coordinates in canvas space. */ + double y, + short *drawableXPtr, /* Screen coordinates are stored here. */ + short *drawableYPtr) { TkCanvas *canvasPtr = (TkCanvas *) canvas; double tmp; @@ -129,7 +126,7 @@ Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr) *drawableXPtr = (short) tmp; } - tmp = y - canvasPtr->drawableYOrigin; + tmp = y - canvasPtr->drawableYOrigin; if (tmp > 0) { tmp += 0.5; } else { @@ -149,15 +146,14 @@ Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr) * * Tk_CanvasWindowCoords -- * - * Given an (x,y) coordinate pair within a canvas, this procedure - * returns the corresponding coordinates in the canvas's window. + * Given an (x,y) coordinate pair within a canvas, this procedure returns + * the corresponding coordinates in the canvas's window. * * Results: - * There is no return value. The values at *screenXPtr and - * *screenYPtr are filled in with the coordinates at which - * (x,y) appears in the canvas's window. These coordinates - * are clipped to fit within a "short", since this is what X - * uses in most cases for drawing. + * There is no return value. The values at *screenXPtr and *screenYPtr + * are filled in with the coordinates at which (x,y) appears in the + * canvas's window. These coordinates are clipped to fit within a + * "short", since this is what X uses in most cases for drawing. * * Side effects: * None. @@ -166,11 +162,12 @@ Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr) */ void -Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr) - Tk_Canvas canvas; /* Token for the canvas. */ - double x, y; /* Coordinates in canvas space. */ - short *screenXPtr, *screenYPtr; /* Screen coordinates are stored - * here. */ +Tk_CanvasWindowCoords( + Tk_Canvas canvas, /* Token for the canvas. */ + double x, /* Coordinates in canvas space. */ + double y, + short *screenXPtr, /* Screen coordinates are stored here. */ + short *screenYPtr) { TkCanvas *canvasPtr = (TkCanvas *) canvas; double tmp; @@ -189,7 +186,7 @@ Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr) *screenXPtr = (short) tmp; } - tmp = y - canvasPtr->yOrigin; + tmp = y - canvasPtr->yOrigin; if (tmp > 0) { tmp += 0.5; } else { @@ -213,11 +210,10 @@ Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr) * corresponding to that string. * * Results: - * The return value is a standard Tcl return result. If - * TCL_OK is returned, then everything went well and the - * canvas coordinate is stored at *doublePtr; otherwise - * TCL_ERROR is returned and an error message is left in - * the interp's result. + * The return value is a standard Tcl return result. If TCL_OK is + * returned, then everything went well and the canvas coordinate is + * stored at *doublePtr; otherwise TCL_ERROR is returned and an error + * message is left in the interp's result. * * Side effects: * None. @@ -226,14 +222,15 @@ Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr) */ int -Tk_CanvasGetCoord(interp, canvas, string, doublePtr) - Tcl_Interp *interp; /* Interpreter for error reporting. */ - Tk_Canvas canvas; /* Canvas to which coordinate applies. */ - CONST char *string; /* Describes coordinate (any screen - * coordinate form may be used here). */ - double *doublePtr; /* Place to store converted coordinate. */ +Tk_CanvasGetCoord( + Tcl_Interp *interp, /* Interpreter for error reporting. */ + Tk_Canvas canvas, /* Canvas to which coordinate applies. */ + CONST char *string, /* Describes coordinate (any screen coordinate + * form may be used here). */ + double *doublePtr) /* Place to store converted coordinate. */ { TkCanvas *canvasPtr = (TkCanvas *) canvas; + if (Tk_GetScreenMM(canvasPtr->interp, canvasPtr->tkwin, string, doublePtr) != TCL_OK) { return TCL_ERROR; @@ -251,11 +248,10 @@ Tk_CanvasGetCoord(interp, canvas, string, doublePtr) * corresponding to that string. * * Results: - * The return value is a standard Tcl return result. If - * TCL_OK is returned, then everything went well and the - * canvas coordinate is stored at *doublePtr; otherwise - * TCL_ERROR is returned and an error message is left in - * interp->result. + * The return value is a standard Tcl return result. If TCL_OK is + * returned, then everything went well and the canvas coordinate is + * stored at *doublePtr; otherwise TCL_ERROR is returned and an error + * message is left in interp->result. * * Side effects: * None. @@ -264,14 +260,15 @@ Tk_CanvasGetCoord(interp, canvas, string, doublePtr) */ int -Tk_CanvasGetCoordFromObj(interp, canvas, obj, doublePtr) - Tcl_Interp *interp; /* Interpreter for error reporting. */ - Tk_Canvas canvas; /* Canvas to which coordinate applies. */ - Tcl_Obj *obj; /* Describes coordinate (any screen - * coordinate form may be used here). */ - double *doublePtr; /* Place to store converted coordinate. */ +Tk_CanvasGetCoordFromObj( + Tcl_Interp *interp, /* Interpreter for error reporting. */ + Tk_Canvas canvas, /* Canvas to which coordinate applies. */ + Tcl_Obj *obj, /* Describes coordinate (any screen coordinate + * form may be used here). */ + double *doublePtr) /* Place to store converted coordinate. */ { TkCanvas *canvasPtr = (TkCanvas *) canvas; + if (Tk_GetMMFromObj(canvasPtr->interp, canvasPtr->tkwin, obj, doublePtr) != TCL_OK) { return TCL_ERROR; @@ -285,9 +282,9 @@ Tk_CanvasGetCoordFromObj(interp, canvas, obj, doublePtr) * * Tk_CanvasSetStippleOrigin -- * - * This procedure sets the stipple origin in a graphics context - * so that stipples drawn with the GC will line up with other - * stipples previously drawn in the canvas. + * This procedure sets the stipple origin in a graphics context so that + * stipples drawn with the GC will line up with other stipples previously + * drawn in the canvas. * * Results: * None. @@ -299,12 +296,11 @@ Tk_CanvasGetCoordFromObj(interp, canvas, obj, doublePtr) */ void -Tk_CanvasSetStippleOrigin(canvas, gc) - Tk_Canvas canvas; /* Token for a canvas. */ - GC gc; /* Graphics context that is about to be - * used to draw a stippled pattern as - * part of redisplaying the canvas. */ - +Tk_CanvasSetStippleOrigin( + Tk_Canvas canvas, /* Token for a canvas. */ + GC gc) /* Graphics context that is about to be used + * to draw a stippled pattern as part of + * redisplaying the canvas. */ { TkCanvas *canvasPtr = (TkCanvas *) canvas; @@ -317,9 +313,9 @@ Tk_CanvasSetStippleOrigin(canvas, gc) * * Tk_CanvasSetOffset-- * - * This procedure sets the stipple offset in a graphics - * context so that stipples drawn with the GC will - * line up with other stipples with the same offset. + * This procedure sets the stipple offset in a graphics context so that + * stipples drawn with the GC will line up with other stipples with the + * same offset. * * Results: * None. @@ -331,12 +327,12 @@ Tk_CanvasSetStippleOrigin(canvas, gc) */ void -Tk_CanvasSetOffset(canvas, gc, offset) - Tk_Canvas canvas; /* Token for a canvas. */ - GC gc; /* Graphics context that is about to be - * used to draw a stippled pattern as - * part of redisplaying the canvas. */ - Tk_TSOffset *offset; /* offset (may be NULL pointer)*/ +Tk_CanvasSetOffset( + Tk_Canvas canvas, /* Token for a canvas. */ + GC gc, /* Graphics context that is about to be used + * to draw a stippled pattern as part of + * redisplaying the canvas. */ + Tk_TSOffset *offset) /* Offset (may be NULL pointer)*/ { TkCanvas *canvasPtr = (TkCanvas *) canvas; int flags = 0; @@ -361,17 +357,16 @@ Tk_CanvasSetOffset(canvas, gc, offset) * * Tk_CanvasGetTextInfo -- * - * This procedure returns a pointer to a structure containing - * information about the selection and insertion cursor for - * a canvas widget. Items such as text items save the pointer - * and use it to share access to the information with the generic - * canvas code. + * This procedure returns a pointer to a structure containing information + * about the selection and insertion cursor for a canvas widget. Items + * such as text items save the pointer and use it to share access to the + * information with the generic canvas code. * * Results: * The return value is a pointer to the structure holding text - * information for the canvas. Most of the fields should not - * be modified outside the generic canvas code; see the user - * documentation for details. + * information for the canvas. Most of the fields should not be modified + * outside the generic canvas code; see the user documentation for + * details. * * Side effects: * None. @@ -380,8 +375,8 @@ Tk_CanvasSetOffset(canvas, gc, offset) */ Tk_CanvasTextInfo * -Tk_CanvasGetTextInfo(canvas) - Tk_Canvas canvas; /* Token for the canvas widget. */ +Tk_CanvasGetTextInfo( + Tk_Canvas canvas) /* Token for the canvas widget. */ { return &((TkCanvas *) canvas)->textInfo; } @@ -391,28 +386,27 @@ Tk_CanvasGetTextInfo(canvas) * * Tk_CanvasTagsParseProc -- * - * This procedure is invoked during option processing to handle - * "-tags" options for canvas items. + * This procedure is invoked during option processing to handle "-tags" + * options for canvas items. * * Results: * A standard Tcl return value. * * Side effects: - * The tags for a given item get replaced by those indicated - * in the value argument. + * The tags for a given item get replaced by those indicated in the value + * argument. * *-------------------------------------------------------------- */ int -Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset) - ClientData clientData; /* Not used.*/ - Tcl_Interp *interp; /* Used for reporting errors. */ - Tk_Window tkwin; /* Window containing canvas widget. */ - CONST char *value; /* Value of option (list of tag - * names). */ - char *widgRec; /* Pointer to record for item. */ - int offset; /* Offset into item (ignored). */ +Tk_CanvasTagsParseProc( + ClientData clientData, /* Not used.*/ + Tcl_Interp *interp, /* Used for reporting errors. */ + Tk_Window tkwin, /* Window containing canvas widget. */ + CONST char *value, /* Value of option (list of tag names). */ + char *widgRec, /* Pointer to record for item. */ + int offset) /* Offset into item (ignored). */ { register Tk_Item *itemPtr = (Tk_Item *) widgRec; int argc, i; @@ -428,8 +422,7 @@ Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset) } /* - * Make sure that there's enough space in the item to hold the - * tag names. + * Make sure that there's enough space in the item to hold the tag names. */ if (itemPtr->tagSpace < argc) { @@ -456,16 +449,16 @@ Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset) * * Tk_CanvasTagsPrintProc -- * - * This procedure is invoked by the Tk configuration code - * to produce a printable string for the "-tags" configuration - * option for canvas items. + * This procedure is invoked by the Tk configuration code to produce a + * printable string for the "-tags" configuration option for canvas + * items. * * Results: - * The return value is a string describing all the tags for - * the item referred to by "widgRec". In addition, *freeProcPtr - * is filled in with the address of a procedure to call to free - * the result string when it's no longer needed (or NULL to - * indicate that the string doesn't need to be freed). + * The return value is a string describing all the tags for the item + * referred to by "widgRec". In addition, *freeProcPtr is filled in with + * the address of a procedure to call to free the result string when it's + * no longer needed (or NULL to indicate that the string doesn't need to + * be freed). * * Side effects: * None. @@ -474,14 +467,14 @@ Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset) */ char * -Tk_CanvasTagsPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) - ClientData clientData; /* Ignored. */ - Tk_Window tkwin; /* Window containing canvas widget. */ - char *widgRec; /* Pointer to record for item. */ - int offset; /* Ignored. */ - Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with - * information about how to reclaim - * storage for return string. */ +Tk_CanvasTagsPrintProc( + ClientData clientData, /* Ignored. */ + Tk_Window tkwin, /* Window containing canvas widget. */ + char *widgRec, /* Pointer to record for item. */ + int offset, /* Ignored. */ + Tcl_FreeProc **freeProcPtr) /* Pointer to variable to fill in with + * information about how to reclaim storage + * for return string. */ { register Tk_Item *itemPtr = (Tk_Item *) widgRec; @@ -502,28 +495,27 @@ Tk_CanvasTagsPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) * * TkCanvasDashParseProc -- * - * This procedure is invoked during option processing to handle - * "-dash", "-activedash" and "-disableddash" options for canvas - * objects. + * This procedure is invoked during option processing to handle "-dash", + * "-activedash" and "-disableddash" options for canvas objects. * * Results: * A standard Tcl return value. * * Side effects: - * The dash list for a given canvas object gets replaced by - * those indicated in the value argument. + * The dash list for a given canvas object gets replaced by those + * indicated in the value argument. * *-------------------------------------------------------------- */ int -TkCanvasDashParseProc(clientData, interp, tkwin, value, widgRec, offset) - ClientData clientData; /* Not used.*/ - Tcl_Interp *interp; /* Used for reporting errors. */ - Tk_Window tkwin; /* Window containing canvas widget. */ - CONST char *value; /* Value of option. */ - char *widgRec; /* Pointer to record for item. */ - int offset; /* Offset into item. */ +TkCanvasDashParseProc( + ClientData clientData, /* Not used.*/ + Tcl_Interp *interp, /* Used for reporting errors. */ + Tk_Window tkwin, /* Window containing canvas widget. */ + CONST char *value, /* Value of option. */ + char *widgRec, /* Pointer to record for item. */ + int offset) /* Offset into item. */ { return Tk_GetDash(interp, value, (Tk_Dash *)(widgRec+offset)); } @@ -533,16 +525,16 @@ TkCanvasDashParseProc(clientData, interp, tkwin, value, widgRec, offset) * * TkCanvasDashPrintProc -- * - * This procedure is invoked by the Tk configuration code - * to produce a printable string for the "-dash", "-activedash" - * and "-disableddash" configuration options for canvas items. + * This procedure is invoked by the Tk configuration code to produce a + * printable string for the "-dash", "-activedash" and "-disableddash" + * configuration options for canvas items. * * Results: - * The return value is a string describing all the dash list for - * the item referred to by "widgRec"and "offset". In addition, - * *freeProcPtr is filled in with the address of a procedure to - * call to free the result string when it's no longer needed (or - * NULL to indicate that the string doesn't need to be freed). + * The return value is a string describing all the dash list for the item + * referred to by "widgRec"and "offset". In addition, *freeProcPtr is + * filled in with the address of a procedure to call to free the result + * string when it's no longer needed (or NULL to indicate that the string + * doesn't need to be freed). * * Side effects: * None. @@ -551,14 +543,14 @@ TkCanvasDashParseProc(clientData, interp, tkwin, value, widgRec, offset) */ char * -TkCanvasDashPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) - ClientData clientData; /* Ignored. */ - Tk_Window tkwin; /* Window containing canvas widget. */ - char *widgRec; /* Pointer to record for item. */ - int offset; /* Offset in record for item. */ - Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with - * information about how to reclaim - * storage for return string. */ +TkCanvasDashPrintProc( + ClientData clientData, /* Ignored. */ + Tk_Window tkwin, /* Window containing canvas widget. */ + char *widgRec, /* Pointer to record for item. */ + int offset, /* Offset in record for item. */ + Tcl_FreeProc **freeProcPtr) /* Pointer to variable to fill in with + * information about how to reclaim storage + * for return string. */ { Tk_Dash *dash = (Tk_Dash *) (widgRec+offset); char *buffer; @@ -593,9 +585,9 @@ TkCanvasDashPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) * * InitSmoothMethods -- * - * This procedure is invoked to set up the initial state of the - * list of "-smooth" methods. It should only be called when the - * list installed in the interpreter is NULL. + * This procedure is invoked to set up the initial state of the list of + * "-smooth" methods. It should only be called when the list installed + * in the interpreter is NULL. * * Results: * Pointer to the start of the list of default smooth methods. @@ -608,8 +600,8 @@ TkCanvasDashPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) */ static SmoothAssocData * -InitSmoothMethods(interp) - Tcl_Interp *interp; +InitSmoothMethods( + Tcl_Interp *interp) { SmoothAssocData *methods, *ptr; @@ -627,7 +619,7 @@ InitSmoothMethods(interp) ptr->nextPtr = NULL; Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc, - (ClientData) methods); + (ClientData) methods); return methods; } @@ -636,23 +628,23 @@ InitSmoothMethods(interp) * * Tk_CreateSmoothMethod -- * - * This procedure is invoked to add additional values - * for the "-smooth" option to the list. + * This procedure is invoked to add additional values for the "-smooth" + * option to the list. * * Results: * A standard Tcl return value. * * Side effects: - * In the future "-smooth <name>" will be accepted as - * smooth method for the line and polygon. + * In the future "-smooth <name>" will be accepted as smooth method for + * the line and polygon. * *-------------------------------------------------------------- */ void -Tk_CreateSmoothMethod(interp, smooth) - Tcl_Interp *interp; - Tk_SmoothMethod *smooth; +Tk_CreateSmoothMethod( + Tcl_Interp *interp, + Tk_SmoothMethod *smooth) { SmoothAssocData *methods, *typePtr2, *prevPtr, *ptr; methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod", @@ -688,15 +680,15 @@ Tk_CreateSmoothMethod(interp, smooth) ptr->smooth.postscriptProc = smooth->postscriptProc; ptr->nextPtr = methods; Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc, - (ClientData) ptr); + (ClientData) ptr); } /* *---------------------------------------------------------------------- * * SmoothMethodCleanupProc -- * - * This procedure is invoked whenever an interpreter is deleted - * to cleanup the smooth methods. + * This procedure is invoked whenever an interpreter is deleted to + * cleanup the smooth methods. * * Results: * None. @@ -708,10 +700,10 @@ Tk_CreateSmoothMethod(interp, smooth) */ static void -SmoothMethodCleanupProc(clientData, interp) - ClientData clientData; /* Points to "smoothMethod" AssocData - * for the interpreter. */ - Tcl_Interp *interp; /* Interpreter that is being deleted. */ +SmoothMethodCleanupProc( + ClientData clientData, /* Points to "smoothMethod" AssocData for the + * interpreter. */ + Tcl_Interp *interp) /* Interpreter that is being deleted. */ { SmoothAssocData *ptr, *methods = (SmoothAssocData *) clientData; @@ -725,8 +717,8 @@ SmoothMethodCleanupProc(clientData, interp) * * TkSmoothParseProc -- * - * This procedure is invoked during option processing to handle - * the "-smooth" option. + * This procedure is invoked during option processing to handle the + * "-smooth" option. * * Results: * A standard Tcl return value. @@ -739,13 +731,13 @@ SmoothMethodCleanupProc(clientData, interp) */ int -TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset) - ClientData clientData; /* some flags.*/ - Tcl_Interp *interp; /* Used for reporting errors. */ - Tk_Window tkwin; /* Window containing canvas widget. */ - CONST char *value; /* Value of option. */ - char *widgRec; /* Pointer to record for item. */ - int offset; /* Offset into item. */ +TkSmoothParseProc( + ClientData clientData, /* some flags.*/ + Tcl_Interp *interp, /* Used for reporting errors. */ + Tk_Window tkwin, /* Window containing canvas widget. */ + CONST char *value, /* Value of option. */ + char *widgRec, /* Pointer to record for item. */ + int offset) /* Offset into item. */ { register Tk_SmoothMethod **smoothPtr = (Tk_SmoothMethod **) (widgRec + offset); @@ -761,18 +753,27 @@ TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset) length = strlen(value); methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod", (Tcl_InterpDeleteProc **) NULL); + /* * Not initialized yet; fix that now. */ + if (methods == NULL) { methods = InitSmoothMethods(interp); } + /* - * Backward compatability hack + * Backward compatability hack. */ + if (strncmp(value, "bezier", length) == 0) { smooth = &tkBezierSmoothMethod; } + + /* + * Search the list of installed smooth methods. + */ + while (methods != (SmoothAssocData *) NULL) { if (strncmp(value, methods->smooth.name, length) == 0) { if (smooth != (Tk_SmoothMethod *) NULL) { @@ -789,6 +790,10 @@ TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset) return TCL_OK; } + /* + * Did not find it. Try parsing as a boolean instead. + */ + if (Tcl_GetBoolean(interp, (char *) value, &b) != TCL_OK) { return TCL_ERROR; } @@ -800,16 +805,15 @@ TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset) * * TkSmoothPrintProc -- * - * This procedure is invoked by the Tk configuration code - * to produce a printable string for the "-smooth" - * configuration option. + * This procedure is invoked by the Tk configuration code to produce a + * printable string for the "-smooth" configuration option. * * Results: - * The return value is a string describing the smooth option for - * the item referred to by "widgRec". In addition, *freeProcPtr - * is filled in with the address of a procedure to call to free - * the result string when it's no longer needed (or NULL to - * indicate that the string doesn't need to be freed). + * The return value is a string describing the smooth option for the item + * referred to by "widgRec". In addition, *freeProcPtr is filled in with + * the address of a procedure to call to free the result string when it's + * no longer needed (or NULL to indicate that the string doesn't need to + * be freed). * * Side effects: * None. @@ -818,16 +822,17 @@ TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset) */ char * -TkSmoothPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) - ClientData clientData; /* Ignored. */ - Tk_Window tkwin; /* Window containing canvas widget. */ - char *widgRec; /* Pointer to record for item. */ - int offset; /* Offset into item. */ - Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with - * information about how to reclaim - * storage for return string. */ +TkSmoothPrintProc( + ClientData clientData, /* Ignored. */ + Tk_Window tkwin, /* Window containing canvas widget. */ + char *widgRec, /* Pointer to record for item. */ + int offset, /* Offset into item. */ + Tcl_FreeProc **freeProcPtr) /* Pointer to variable to fill in with + * information about how to reclaim storage + * for return string. */ { - register Tk_SmoothMethod **smoothPtr = (Tk_SmoothMethod **) (widgRec + offset); + register Tk_SmoothMethod **smoothPtr = + (Tk_SmoothMethod **) (widgRec + offset); return (*smoothPtr) ? (*smoothPtr)->name : "0"; } @@ -836,13 +841,12 @@ TkSmoothPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) * * Tk_GetDash * - * This procedure is used to parse a string, assuming - * it is dash information. + * This procedure is used to parse a string, assuming it is dash + * information. * * Results: - * The return value is a standard Tcl result: TCL_OK means - * that the dash information was parsed ok, and - * TCL_ERROR means it couldn't be parsed. + * The return value is a standard Tcl result: TCL_OK means that the dash + * information was parsed ok, and TCL_ERROR means it couldn't be parsed. * * Side effects: * Dash information in the dash structure is updated. @@ -851,11 +855,11 @@ TkSmoothPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) */ int -Tk_GetDash(interp, value, dash) - Tcl_Interp *interp; /* Used for error reporting. */ - CONST char *value; /* Textual specification of dash list. */ - Tk_Dash *dash; /* Pointer to record in which to - * store dash information. */ +Tk_GetDash( + Tcl_Interp *interp, /* Used for error reporting. */ + CONST char *value, /* Textual specification of dash list. */ + Tk_Dash *dash) /* Pointer to record in which to store dash + * information. */ { int argc, i; CONST char **largv, **argv = NULL; @@ -865,8 +869,13 @@ Tk_GetDash(interp, value, dash) dash->number = 0; return TCL_OK; } - if ((*value == '.') || (*value == ',') || - (*value == '-') || (*value == '_')) { + + /* + * switch is usually compiled more efficiently than a chain of conditions. + */ + + switch (*value) { + case '.': case ',': case '-': case '_': i = DashConvert((char *) NULL, value, -1, 0.0); if (i>0) { i = strlen(value); @@ -882,20 +891,10 @@ Tk_GetDash(interp, value, dash) dash->number = -i; return TCL_OK; } + if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) { Tcl_ResetResult(interp); - badDashList: - Tcl_AppendResult(interp, "bad dash list \"", value, - "\": must be a list of integers or a format like \"-..\"", - (char *) NULL); - syntaxError: - if (argv != NULL) { - ckfree((char *) argv); - } - if (ABS(dash->number) > sizeof(char *)) - ckfree((char *) dash->pattern.pt); - dash->number = 0; - return TCL_ERROR; + goto badDashList; } if (ABS(dash->number) > sizeof(char *)) { @@ -909,23 +908,41 @@ Tk_GetDash(interp, value, dash) dash->number = argc; largv = argv; - while(argc>0) { - if (Tcl_GetInt(interp, *largv, &i) != TCL_OK || - i < 1 || i>255) { + while (argc>0) { + if (Tcl_GetInt(interp, *largv, &i) != TCL_OK || i < 1 || i>255) { Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "expected integer in the range 1..255 but got \"", - *largv, "\"", (char *) NULL); + Tcl_AppendResult(interp, + "expected integer in the range 1..255 but got \"", + *largv, "\"", (char *) NULL); goto syntaxError; } *pt++ = i; - argc--; largv++; + argc--; + largv++; } - + if (argv != NULL) { ckfree((char *) argv); } - return TCL_OK; + + /* + * Something went wrong. Generate error message, clean up and return. + */ + + badDashList: + Tcl_AppendResult(interp, "bad dash list \"", value, + "\": must be a list of integers or a format like \"-..\"", + (char *) NULL); + syntaxError: + if (argv != NULL) { + ckfree((char *) argv); + } + if (ABS(dash->number) > sizeof(char *)) { + ckfree((char *) dash->pattern.pt); + } + dash->number = 0; + return TCL_ERROR; } /* @@ -933,8 +950,8 @@ Tk_GetDash(interp, value, dash) * * Tk_CreateOutline * - * This procedure initializes the Tk_Outline structure - * with default values. + * This procedure initializes the Tk_Outline structure with default + * values. * * Results: * None @@ -945,8 +962,9 @@ Tk_GetDash(interp, value, dash) *-------------------------------------------------------------- */ -void Tk_CreateOutline(outline) - Tk_Outline *outline; +void +Tk_CreateOutline( + Tk_Outline *outline) /* Outline structure to be filled in. */ { outline->gc = None; outline->width = 1.0; @@ -972,8 +990,8 @@ void Tk_CreateOutline(outline) * * Tk_DeleteOutline * - * This procedure frees all memory that might be - * allocated and referenced in the Tk_Outline structure. + * This procedure frees all memory that might be allocated and referenced + * in the Tk_Outline structure. * * Results: * None @@ -984,9 +1002,10 @@ void Tk_CreateOutline(outline) *-------------------------------------------------------------- */ -void Tk_DeleteOutline(display, outline) - Display *display; /* Display containing window */ - Tk_Outline *outline; +void +Tk_DeleteOutline( + Display *display, /* Display containing window. */ + Tk_Outline *outline) { if (outline->gc != None) { Tk_FreeGC(display, outline->gc); @@ -1025,15 +1044,14 @@ void Tk_DeleteOutline(display, outline) * * Tk_ConfigOutlineGC * - * This procedure should be called in the canvas object - * during the configure command. The graphics context - * description in gcValues is updated according to the - * information in the dash structure, as far as possible. + * This procedure should be called in the canvas object during the + * configure command. The graphics context description in gcValues is + * updated according to the information in the dash structure, as far as + * possible. * * Results: - * The return-value is a mask, indicating which - * elements of gcValues have been updated. - * 0 means there is no outline. + * The return-value is a mask, indicating which elements of gcValues have + * been updated. 0 means there is no outline. * * Side effects: * GC information in gcValues is updated. @@ -1041,11 +1059,12 @@ void Tk_DeleteOutline(display, outline) *-------------------------------------------------------------- */ -int Tk_ConfigOutlineGC(gcValues, canvas, item, outline) - XGCValues *gcValues; - Tk_Canvas canvas; - Tk_Item *item; - Tk_Outline *outline; +int +Tk_ConfigOutlineGC( + XGCValues *gcValues, + Tk_Canvas canvas, + Tk_Item *item, + Tk_Outline *outline) { int mask = 0; double width; @@ -1090,7 +1109,7 @@ int Tk_ConfigOutlineGC(gcValues, canvas, item, outline) if (outline->activeStipple!=None) { stipple = outline->activeStipple; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (outline->disabledWidth>0) { width = outline->disabledWidth; } @@ -1139,15 +1158,12 @@ int Tk_ConfigOutlineGC(gcValues, canvas, item, outline) * * Tk_ChangeOutlineGC * - * Updates the GC to represent the full information of - * the dash structure. Partly this is already done in - * Tk_ConfigOutlineGC(). - * This function should be called just before drawing - * the dashed item. + * Updates the GC to represent the full information of the dash + * structure. Partly this is already done in Tk_ConfigOutlineGC(). This + * function should be called just before drawing the dashed item. * * Results: - * 1 if there is a stipple pattern. - * 0 otherwise. + * 1 if there is a stipple pattern, and 0 otherwise. * * Side effects: * GC is updated. @@ -1156,10 +1172,10 @@ int Tk_ConfigOutlineGC(gcValues, canvas, item, outline) */ int -Tk_ChangeOutlineGC(canvas, item, outline) - Tk_Canvas canvas; - Tk_Item *item; - Tk_Outline *outline; +Tk_ChangeOutlineGC( + Tk_Canvas canvas, + Tk_Item *item, + Tk_Outline *outline) { CONST char *p; double width; @@ -1209,25 +1225,30 @@ Tk_ChangeOutlineGC(canvas, item, outline) return 0; } - if ((dash->number<-1) || ((dash->number == -1) && (dash->pattern.array[1]!=','))) { + if ((dash->number<-1) || + ((dash->number == -1) && (dash->pattern.array[1] != ','))) { char *q; int i = -dash->number; - p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array; + p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array; q = (char *) ckalloc(2*(unsigned int)i); i = DashConvert(q, p, i, width); - XSetDashes(((TkCanvas *)canvas)->display, outline->gc, outline->offset, q, i); + XSetDashes(((TkCanvas *)canvas)->display, outline->gc, + outline->offset, q, i); ckfree(q); - } else if ( dash->number>2 || (dash->number==2 && - (dash->pattern.array[0]!=dash->pattern.array[1]))) { - p = (char *) (dash->number > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array; - XSetDashes(((TkCanvas *)canvas)->display, outline->gc, outline->offset, p, dash->number); + } else if (dash->number>2 || (dash->number==2 && + (dash->pattern.array[0]!=dash->pattern.array[1]))) { + p = (char *) (dash->number > (int)sizeof(char *)) + ? dash->pattern.pt : dash->pattern.array; + XSetDashes(((TkCanvas *)canvas)->display, outline->gc, + outline->offset, p, dash->number); } if (stipple!=None) { int w=0; int h=0; Tk_TSOffset *tsoffset = &outline->tsoffset; int flags = tsoffset->flags; - if (!(flags & TK_OFFSET_INDEX) && (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) { + if (!(flags & TK_OFFSET_INDEX) && + (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) { Tk_SizeOfBitmap(((TkCanvas *)canvas)->display, stipple, &w, &h); if (flags & TK_OFFSET_CENTER) { w /= 2; @@ -1256,26 +1277,24 @@ Tk_ChangeOutlineGC(canvas, item, outline) * * Tk_ResetOutlineGC * - * Restores the GC to the situation before - * Tk_ChangeDashGC() was called. - * This function should be called just after the dashed - * item is drawn, because the GC is supposed to be - * read-only. + * Restores the GC to the situation before Tk_ChangeDashGC() was called. + * This function should be called just after the dashed item is drawn, + * because the GC is supposed to be read-only. * * Results: - * 1 if there is a stipple pattern. - * 0 otherwise. + * 1 if there is a stipple pattern, and 0 otherwise. * * Side effects: * GC is updated. * *-------------------------------------------------------------- */ + int -Tk_ResetOutlineGC(canvas, item, outline) - Tk_Canvas canvas; - Tk_Item *item; - Tk_Outline *outline; +Tk_ResetOutlineGC( + Tk_Canvas canvas, + Tk_Item *item, + Tk_Outline *outline) { char dashList; double width; @@ -1307,7 +1326,7 @@ Tk_ResetOutlineGC(canvas, item, outline) if (outline->activeStipple!=None) { stipple = outline->activeStipple; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (outline->disabledWidth>width) { width = outline->disabledWidth; } @@ -1326,8 +1345,8 @@ Tk_ResetOutlineGC(canvas, item, outline) } if ((dash->number > 2) || (dash->number < -1) || (dash->number==2 && - (dash->pattern.array[0] != dash->pattern.array[1])) || - ((dash->number == -1) && (dash->pattern.array[1] != ','))) { + (dash->pattern.array[0] != dash->pattern.array[1])) || + ((dash->number == -1) && (dash->pattern.array[1] != ','))) { if (dash->number < 0) { dashList = (int) (4 * width + 0.5); } else if (dash->number<3) { @@ -1344,30 +1363,30 @@ Tk_ResetOutlineGC(canvas, item, outline) } return 0; } - /* *-------------------------------------------------------------- * * Tk_CanvasPsOutline * - * Creates the postscript command for the correct - * Outline-information (width, dash, color and stipple). + * Creates the postscript command for the correct Outline-information + * (width, dash, color and stipple). * * Results: * TCL_OK if succeeded, otherwise TCL_ERROR. * * Side effects: - * canvas->interp->result contains the postscript string, - * or an error message if the result was TCL_ERROR. + * canvas->interp->result contains the postscript string, or an error + * message if the result was TCL_ERROR. * *-------------------------------------------------------------- */ + int -Tk_CanvasPsOutline(canvas, item, outline) - Tk_Canvas canvas; - Tk_Item *item; - Tk_Outline *outline; +Tk_CanvasPsOutline( + Tk_Canvas canvas, + Tk_Item *item, + Tk_Outline *outline) { char string[41]; char pattern[11]; @@ -1389,6 +1408,7 @@ Tk_CanvasPsOutline(canvas, item, outline) if (state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } + if (((TkCanvas *)canvas)->currentItemPtr == item) { if (outline->activeWidth > width) { width = outline->activeWidth; @@ -1426,9 +1446,10 @@ Tk_CanvasPsOutline(canvas, item, outline) lptr = (char *)ckalloc((unsigned int) (1 - 2*dash->number)); } ptr = (char *) ((ABS(dash->number) > sizeof(char *)) ) ? - dash->pattern.pt : dash->pattern.array; + dash->pattern.pt : dash->pattern.array; if (dash->number > 0) { char *ptr0 = ptr; + sprintf(str, "[%d", *ptr++ & 0xff); i = dash->number-1; while (i--) { @@ -1444,6 +1465,7 @@ Tk_CanvasPsOutline(canvas, item, outline) } else if (dash->number < 0) { if ((i = DashConvert(lptr, ptr, -dash->number, width)) != 0) { char *lptr0 = lptr; + sprintf(str, "[%d", *lptr++ & 0xff); while (--i) { sprintf(str+strlen(str), " %d", *lptr++ & 0xff); @@ -1478,22 +1500,18 @@ Tk_CanvasPsOutline(canvas, item, outline) return TCL_OK; } - /* *-------------------------------------------------------------- * * DashConvert * - * Converts a character-like dash-list (e.g. "-..") - * into an X11-style. l must point to a string that - * holds room to at least 2*n characters. if - * l == NULL, this function can be used for - * syntax checking only. + * Converts a character-like dash-list (e.g. "-..") into an X11-style. l + * must point to a string that holds room to at least 2*n characters. If + * l == NULL, this function can be used for syntax checking only. * * Results: - * The length of the resulting X11 compatible - * dash-list. -1 if failed. + * The length of the resulting X11 compatible dash-list. -1 if failed. * * Side effects: * None @@ -1502,11 +1520,13 @@ Tk_CanvasPsOutline(canvas, item, outline) */ static int -DashConvert (l, p, n, width) - char *l; - CONST char *p; - int n; - double width; +DashConvert( + char *l, /* Must be at least 2*n chars long, or NULL to + * indicate "just check syntax". */ + CONST char *p, /* String to parse. */ + int n, /* Length of string to parse, or -1 to + * indicate that strlen() should be used. */ + double width) /* Width of line. */ { int result = 0; int size, intWidth; @@ -1520,30 +1540,28 @@ DashConvert (l, p, n, width) } while (n-- && *p) { switch (*p++) { - case ' ': - if (result) { - if (l) { - l[-1] += intWidth + 1; - } - continue; - } else { - return 0; + case ' ': + if (result) { + if (l) { + l[-1] += intWidth + 1; } - break; - case '_': - size = 8; - break; - case '-': - size = 6; - break; - case ',': - size = 4; - break; - case '.': - size = 2; - break; - default: - return -1; + continue; + } + return 0; + case '_': + size = 8; + break; + case '-': + size = 6; + break; + case ',': + size = 4; + break; + case '.': + size = 2; + break; + default: + return -1; } if (l) { *l++ = size * intWidth; @@ -1557,14 +1575,14 @@ DashConvert (l, p, n, width) /* *---------------------------------------------------------------------- * - * translateAndAppendCoords -- + * TranslateAndAppendCoords -- * * This is a helper routine for TkCanvTranslatePath() below. * * Given an (x,y) coordinate pair within a canvas, this procedure - * computes the corresponding coordinates at which the point should - * be drawn in the drawable used for display. Those coordinates are - * then written into outArr[numOut*2] and outArr[numOut*2+1]. + * computes the corresponding coordinates at which the point should be + * drawn in the drawable used for display. Those coordinates are then + * written into outArr[numOut*2] and outArr[numOut*2+1]. * * Results: * There is no return value. @@ -1576,11 +1594,12 @@ DashConvert (l, p, n, width) */ static void -translateAndAppendCoords(canvPtr, x, y, outArr, numOut) - TkCanvas *canvPtr; /* The canvas. */ - double x, y; /* Coordinates in canvas space. */ - XPoint *outArr; /* Write results into this array */ - int numOut; /* Num of prior entries in outArr[] */ +TranslateAndAppendCoords( + TkCanvas *canvPtr, /* The canvas. */ + double x, /* Coordinates in canvas space. */ + double y, + XPoint *outArr, /* Write results into this array */ + int numOut) /* Num of prior entries in outArr[] */ { double tmp; @@ -1592,7 +1611,7 @@ translateAndAppendCoords(canvPtr, x, y, outArr, numOut) } outArr[numOut].x = (short) tmp; - tmp = y - canvPtr->drawableYOrigin; + tmp = y - canvPtr->drawableYOrigin; if (tmp > 0) { tmp += 0.5; } else { @@ -1606,225 +1625,262 @@ translateAndAppendCoords(canvPtr, x, y, outArr, numOut) * * TkCanvTranslatePath * - * Translate a line or polygon path so that all vertices are - * within a rectangle that is 1000 pixels larger than the total - * size of the canvas window. This will prevent pixel coordinates - * from overflowing the 16-bit integer size limitation imposed by - * most windowing systems. - * - * coordPtr must point to an array of doubles, two doubles per - * vertex. There are a total of numVertex vertices, or 2*numVertex - * entries in coordPtr. The result vertices written into outArr - * have their coordinate origin shifted to canvPtr->drawableXOrigin - * by canvPtr->drawableYOrigin. There might be as many as 3 times - * more output vertices than there are input vertices. The calling - * function should allocate space accordingly. - * - * This routine limits the width and height of a canvas window - * to 31767 pixels. At the highest resolution display devices - * available today (210 ppi in Jan 2003) that's a window that is - * over 13 feet wide and tall. Should be enough for the near - * future. + * Translate a line or polygon path so that all vertices are within a + * rectangle that is 1000 pixels larger than the total size of the canvas + * window. This will prevent pixel coordinates from overflowing the + * 16-bit integer size limitation imposed by most windowing systems. + * + * coordPtr must point to an array of doubles, two doubles per vertex. + * There are a total of numVertex vertices, or 2*numVertex entries in + * coordPtr. The result vertices written into outArr have their + * coordinate origin shifted to canvPtr->drawableXOrigin by + * canvPtr->drawableYOrigin. There might be as many as 3 times more + * output vertices than there are input vertices. The calling function + * should allocate space accordingly. + * + * This routine limits the width and height of a canvas window to 31767 + * pixels. At the highest resolution display devices available today (210 + * ppi in Jan 2003) that's a window that is over 13 feet wide and tall. + * Should be enough for the near future. * * Results: - * Clipped and translated path vertices are written into outArr[]. - * There might be as many as twice the vertices in outArr[] as there - * are in coordPtr[]. The return value is the number of vertices - * actually written into outArr[]. + * Clipped and translated path vertices are written into outArr[]. There + * might be as many as twice the vertices in outArr[] as there are in + * coordPtr[]. The return value is the number of vertices actually + * written into outArr[]. * * Side effects: * None * *-------------------------------------------------------------- */ + int -TkCanvTranslatePath (canvPtr, numVertex, coordArr, closedPath, outArr) - TkCanvas *canvPtr; /* The canvas */ - int numVertex; /* Number of vertices specified by coordArr[] */ - double *coordArr; /* X and Y coordinates for each vertex */ - int closedPath; /* True if this is a closed polygon */ - XPoint *outArr; /* Write results here, if not NULL */ +TkCanvTranslatePath( + TkCanvas *canvPtr, /* The canvas */ + int numVertex, /* Number of vertices specified by + * coordArr[] */ + double *coordArr, /* X and Y coordinates for each vertex */ + int closedPath, /* True if this is a closed polygon */ + XPoint *outArr) /* Write results here, if not NULL */ { - int numOutput = 0; /* Number of output coordinates */ - double lft, rgh; /* Left and right sides of the bounding box */ - double top, btm; /* Top and bottom sizes of the bounding box */ - double *tempArr; /* Temporary storage used by the clipper */ - double *a, *b, *t; /* Pointers to parts of the temporary storage */ - int i, j; /* Loop counters */ - int maxOutput; /* Maximum number of outputs that we will allow */ - double limit[4]; /* Boundries at which clipping occurs */ - double staticSpace[480]; /* Temp space from the stack */ + int numOutput = 0; /* Number of output coordinates */ + double lft, rgh; /* Left and right sides of the bounding box */ + double top, btm; /* Top and bottom sizes of the bounding box */ + double *tempArr; /* Temporary storage used by the clipper */ + double *a, *b, *t; /* Pointers to parts of the temporary + * storage */ + int i, j; /* Loop counters */ + int maxOutput; /* Maximum number of outputs that we will + * allow */ + double limit[4]; /* Boundries at which clipping occurs */ + double staticSpace[480]; /* Temp space from the stack */ /* - ** Constrain all vertices of the path to be within a box that is no - ** larger than 32000 pixels wide or height. The top-left corner of - ** this clipping box is 1000 pixels above and to the left of the top - ** left corner of the window on which the canvas is displayed. - ** - ** This means that a canvas will not display properly on a canvas - ** window that is larger than 31000 pixels wide or high. That is not - ** a problem today, but might someday become a factor for ultra-high - ** resolutions displays. - ** - ** The X11 protocol allows us (in theory) to expand the size of the - ** clipping box to 32767 pixels. But we have found experimentally that - ** XFree86 sometimes fails to draw lines correctly if they are longer - ** than about 32500 pixels. So we have left a little margin in the - ** size to mask that bug. - */ + * Constrain all vertices of the path to be within a box that is no larger + * than 32000 pixels wide or height. The top-left corner of this clipping + * box is 1000 pixels above and to the left of the top left corner of the + * window on which the canvas is displayed. + * + * This means that a canvas will not display properly on a canvas window + * that is larger than 31000 pixels wide or high. That is not a problem + * today, but might someday become a factor for ultra-high resolutions + * displays. + * + * The X11 protocol allows us (in theory) to expand the size of the + * clipping box to 32767 pixels. But we have found experimentally that + * XFree86 sometimes fails to draw lines correctly if they are longer than + * about 32500 pixels. So we have left a little margin in the size to mask + * that bug. + */ + lft = canvPtr->xOrigin - 1000.0; top = canvPtr->yOrigin - 1000.0; rgh = lft + 32000.0; btm = top + 32000.0; - /* Try the common case first - no clipping. Loop over the input - ** coordinates and translate them into appropriate output coordinates. - ** But if a vertex outside of the bounding box is seen, break out of - ** the loop. - ** - ** Most of the time, no clipping is needed, so this one loop is - ** sufficient to do the translation. - */ - for(i=0; i<numVertex; i++){ - double x, y; - x = coordArr[i*2]; - y = coordArr[i*2+1]; - if( x<lft || x>rgh || y<top || y>btm ) break; - translateAndAppendCoords(canvPtr, x, y, outArr, numOutput++); - } - if( i==numVertex ){ - assert( numOutput==numVertex ); - return numOutput; - } - - /* If we reach this point, it means that some clipping is required. - ** Begin by allocating some working storage - at least 6 times as much space - ** as coordArr[] requires. Divide this space into two separate arrays - ** a[] and b[]. Initialize a[] to be equal to coordArr[]. - */ - if( numVertex*12 <= (int)(sizeof(staticSpace)/sizeof(staticSpace[0])) ){ - tempArr = staticSpace; + /* + * Try the common case first - no clipping. Loop over the input + * coordinates and translate them into appropriate output coordinates. + * But if a vertex outside of the bounding box is seen, break out of the + * loop. + * + * Most of the time, no clipping is needed, so this one loop is sufficient + * to do the translation. + */ + + for (i=0; i<numVertex; i++){ + double x, y; + + x = coordArr[i*2]; + y = coordArr[i*2+1]; + if (x<lft || x>rgh || y<top || y>btm) { + break; + } + TranslateAndAppendCoords(canvPtr, x, y, outArr, numOutput++); + } + if (i == numVertex){ + assert(numOutput == numVertex); + return numOutput; + } + + /* + * If we reach this point, it means that some clipping is required. Begin + * by allocating some working storage - at least 6 times as much space as + * coordArr[] requires. Divide this space into two separate arrays a[] and + * b[]. Initialize a[] to be equal to coordArr[]. + */ + + if (numVertex*12 <= (int)(sizeof(staticSpace)/sizeof(staticSpace[0]))) { + tempArr = staticSpace; } else { - tempArr = (double*)ckalloc( numVertex*12*sizeof(tempArr[0]) ); + tempArr = (double *)ckalloc(numVertex*12*sizeof(tempArr[0])); } - for(i=0; i<numVertex*2; i++){ - tempArr[i] = coordArr[i]; + for (i=0; i<numVertex*2; i++){ + tempArr[i] = coordArr[i]; } a = tempArr; b = &tempArr[numVertex*6]; - /* We will make four passes through the input data. On each pass, - ** we copy the contents of a[] over into b[]. As we copy, we clip - ** any line segments that extend to the right past xClip then we - ** rotate the coordinate system 90 degrees clockwise. After each - ** pass is complete, we interchange a[] and b[] in preparation for - ** the next pass. - ** - ** Each pass clips line segments that extend beyond a single side - ** of the bounding box, and four passes rotate the coordinate system - ** back to its original value. I'm not an expert on graphics - ** algorithms, but I think this is called Cohen-Sutherland polygon - ** clipping. - ** - ** The limit[] array contains the xClip value used for each of the - ** four passes. - */ + /* + * We will make four passes through the input data. On each pass, we copy + * the contents of a[] over into b[]. As we copy, we clip any line + * segments that extend to the right past xClip then we rotate the + * coordinate system 90 degrees clockwise. After each pass is complete, we + * interchange a[] and b[] in preparation for the next pass. + * + * Each pass clips line segments that extend beyond a single side of the + * bounding box, and four passes rotate the coordinate system back to its + * original value. I'm not an expert on graphics algorithms, but I think + * this is called Cohen-Sutherland polygon clipping. + * + * The limit[] array contains the xClip value used for each of the four + * passes. + */ + limit[0] = rgh; limit[1] = -top; limit[2] = -lft; limit[3] = btm; - /* This is the loop that makes the four passes through the data. - */ + /* + * This is the loop that makes the four passes through the data. + */ + maxOutput = numVertex*3; - for(j=0; j<4; j++){ - double xClip = limit[j]; - int inside = a[0]<xClip; - double priorY = a[1]; - numOutput = 0; - - /* Clip everything to the right of xClip. Store the results in - ** b[] rotated by 90 degrees clockwise. - */ - for(i=0; i<numVertex; i++){ - double x = a[i*2]; - double y = a[i*2+1]; - if( x>=xClip ){ - /* The current vertex is to the right of xClip. - */ - if( inside ){ - /* If the current vertex is to the right of xClip but - ** the previous vertex was left of xClip, then draw a - ** line segment from the previous vertex to until it - ** intersects the vertical at xClip. - */ - double x0, y0, yN; - assert( i>0 ); - x0 = a[i*2-2]; - y0 = a[i*2-1]; - yN = y0 + (y - y0)*(xClip-x0)/(x-x0); - b[numOutput*2] = -yN; - b[numOutput*2+1] = xClip; - numOutput++; - assert( numOutput<=maxOutput ); - priorY = yN; - inside = 0; - }else if( i==0 ){ - /* If the first vertex is to the right of xClip, add - ** a vertex that is the projection of the first vertex - ** onto the vertical xClip line. - */ - b[0] = -y; - b[1] = xClip; - numOutput = 1; - priorY = y; - } - }else{ - /* The current vertex is to the left of xClip - */ - if( !inside ){ - /* If the current vertex is on the left of xClip and - ** one or more prior vertices where to the right, then - ** we have to draw a line segment along xClip that extends - ** from the spot where we first crossed from left to right - ** to the spot where we cross back from right to left. - */ - double x0, y0, yN; - assert( i>0 ); - x0 = a[i*2-2]; - y0 = a[i*2-1]; - yN = y0 + (y - y0)*(xClip-x0)/(x-x0); - if( yN!=priorY ){ - b[numOutput*2] = -yN; - b[numOutput*2+1] = xClip; - numOutput++; - assert( numOutput<=maxOutput ); - } - inside = 1; - } - b[numOutput*2] = -y; - b[numOutput*2+1] = x; - numOutput++; - assert( numOutput<=maxOutput ); - } - } - - /* Interchange a[] and b[] in preparation for the next pass. - */ - t = a; - a = b; - b = t; - numVertex = numOutput; - } - - /* All clipping is now finished. Convert the coordinates from doubles - ** into XPoints and translate the origin for the drawable. - */ - for(i=0; i<numVertex; i++){ - translateAndAppendCoords(canvPtr, a[i*2], a[i*2+1], outArr, i); - } - if( tempArr!=staticSpace ){ - ckfree((char *) tempArr); + for (j=0; j<4; j++){ + double xClip = limit[j]; + int inside = a[0]<xClip; + double priorY = a[1]; + numOutput = 0; + + /* + * Clip everything to the right of xClip. Store the results in b[] + * rotated by 90 degrees clockwise. + */ + + for (i=0; i<numVertex; i++){ + double x = a[i*2]; + double y = a[i*2+1]; + + if (x >= xClip) { + /* + * The current vertex is to the right of xClip. + */ + + if (inside) { + /* + * If the current vertex is to the right of xClip but the + * previous vertex was left of xClip, then draw a line + * segment from the previous vertex to until it intersects + * the vertical at xClip. + */ + + double x0, y0, yN; + + assert(i > 0); + x0 = a[i*2-2]; + y0 = a[i*2-1]; + yN = y0 + (y - y0)*(xClip-x0)/(x-x0); + b[numOutput*2] = -yN; + b[numOutput*2+1] = xClip; + numOutput++; + assert(numOutput <= maxOutput); + priorY = yN; + inside = 0; + } else if (i == 0) { + /* + * If the first vertex is to the right of xClip, add a + * vertex that is the projection of the first vertex onto + * the vertical xClip line. + */ + + b[0] = -y; + b[1] = xClip; + numOutput = 1; + priorY = y; + } + } else { + /* + * The current vertex is to the left of xClip + */ + if (!inside) { + /* If the current vertex is on the left of xClip and one + * or more prior vertices where to the right, then we have + * to draw a line segment along xClip that extends from + * the spot where we first crossed from left to right to + * the spot where we cross back from right to left. + */ + + double x0, y0, yN; + + assert(i > 0); + x0 = a[i*2-2]; + y0 = a[i*2-1]; + yN = y0 + (y - y0)*(xClip-x0)/(x-x0); + if (yN != priorY) { + b[numOutput*2] = -yN; + b[numOutput*2+1] = xClip; + numOutput++; + assert(numOutput <= maxOutput); + } + inside = 1; + } + b[numOutput*2] = -y; + b[numOutput*2+1] = x; + numOutput++; + assert(numOutput <= maxOutput); + } + } + + /* + * Interchange a[] and b[] in preparation for the next pass. + */ + + t = a; + a = b; + b = t; + numVertex = numOutput; + } + + /* + * All clipping is now finished. Convert the coordinates from doubles into + * XPoints and translate the origin for the drawable. + */ + + for (i=0; i<numVertex; i++){ + TranslateAndAppendCoords(canvPtr, a[i*2], a[i*2+1], outArr, i); + } + if (tempArr != staticSpace) { + ckfree((char *) tempArr); } return numOutput; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |