📄 tkcanvarc.c
字号:
/* * tkCanvArc.c -- * * This file implements arc items for canvas widgets. * * Copyright (c) 1992-1994 The Regents of the University of California. * Copyright (c) 1994-1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkCanvArc.c 1.34 97/04/25 16:50:56 */#include <stdio.h>#include "tkPort.h"#include "tkInt.h"/* * The structure below defines the record for each arc item. */typedef struct ArcItem { Tk_Item header; /* Generic stuff that's the same for all * types. MUST BE FIRST IN STRUCTURE. */ double bbox[4]; /* Coordinates (x1, y1, x2, y2) of bounding * box for oval of which arc is a piece. */ double start; /* Angle at which arc begins, in degrees * between 0 and 360. */ double extent; /* Extent of arc (angular distance from * start to end of arc) in degrees between * -360 and 360. */ double *outlinePtr; /* Points to (x,y) coordinates for points * that define one or two closed polygons * representing the portion of the outline * that isn't part of the arc (the V-shape * for a pie slice or a line-like segment * for a chord). Malloc'ed. */ int numOutlinePoints; /* Number of points at outlinePtr. Zero * means no space allocated. */ int width; /* Width of outline (in pixels). */ XColor *outlineColor; /* Color for outline. NULL means don't * draw outline. */ XColor *fillColor; /* Color for filling arc (used for drawing * outline too when style is "arc"). NULL * means don't fill arc. */ Pixmap fillStipple; /* Stipple bitmap for filling item. */ Pixmap outlineStipple; /* Stipple bitmap for outline. */ Tk_Uid style; /* How to draw arc: arc, chord, or pieslice. */ GC outlineGC; /* Graphics context for outline. */ GC fillGC; /* Graphics context for filling item. */ double center1[2]; /* Coordinates of center of arc outline at * start (see ComputeArcOutline). */ double center2[2]; /* Coordinates of center of arc outline at * start+extent (see ComputeArcOutline). */} ArcItem;/* * The definitions below define the sizes of the polygons used to * display outline information for various styles of arcs: */#define CHORD_OUTLINE_PTS 7#define PIE_OUTLINE1_PTS 6#define PIE_OUTLINE2_PTS 7/* * Information used for parsing configuration specs: */static Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, (ClientData) NULL};static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_DOUBLE, "-extent", (char *) NULL, (char *) NULL, "90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL, (char *) NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK}, {TK_CONFIG_COLOR, "-outline", (char *) NULL, (char *) NULL, "black", Tk_Offset(ArcItem, outlineColor), TK_CONFIG_NULL_OK}, {TK_CONFIG_BITMAP, "-outlinestipple", (char *) NULL, (char *) NULL, (char *) NULL, Tk_Offset(ArcItem, outlineStipple), TK_CONFIG_NULL_OK}, {TK_CONFIG_DOUBLE, "-start", (char *) NULL, (char *) NULL, "0", Tk_Offset(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL, (char *) NULL, Tk_Offset(ArcItem, fillStipple), TK_CONFIG_NULL_OK}, {TK_CONFIG_UID, "-style", (char *) NULL, (char *) NULL, "pieslice", Tk_Offset(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL, (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL, "1", Tk_Offset(ArcItem, width), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, 0, 0}};/* * Prototypes for procedures defined in this file: */static void ComputeArcBbox _ANSI_ARGS_((Tk_Canvas canvas, ArcItem *arcPtr));static int ConfigureArc _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int argc, char **argv, int flags));static int CreateArc _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, int argc, char **argv));static void DeleteArc _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, Display *display));static void DisplayArc _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, Display *display, Drawable dst, int x, int y, int width, int height));static int ArcCoords _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int argc, char **argv));static int ArcToArea _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, double *rectPtr));static double ArcToPoint _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, double *coordPtr));static int ArcToPostscript _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));static void ScaleArc _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, double originX, double originY, double scaleX, double scaleY));static void TranslateArc _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, double deltaX, double deltaY));static int AngleInRange _ANSI_ARGS_((double x, double y, double start, double extent));static void ComputeArcOutline _ANSI_ARGS_((ArcItem *arcPtr));static int HorizLineToArc _ANSI_ARGS_((double x1, double x2, double y, double rx, double ry, double start, double extent));static int VertLineToArc _ANSI_ARGS_((double x, double y1, double y2, double rx, double ry, double start, double extent));/* * The structures below defines the arc item types by means of procedures * that can be invoked by generic item code. */Tk_ItemType tkArcType = { "arc", /* name */ sizeof(ArcItem), /* itemSize */ CreateArc, /* createProc */ configSpecs, /* configSpecs */ ConfigureArc, /* configureProc */ ArcCoords, /* coordProc */ DeleteArc, /* deleteProc */ DisplayArc, /* displayProc */ 0, /* alwaysRedraw */ ArcToPoint, /* pointProc */ ArcToArea, /* areaProc */ ArcToPostscript, /* postscriptProc */ ScaleArc, /* scaleProc */ TranslateArc, /* translateProc */ (Tk_ItemIndexProc *) NULL, /* indexProc */ (Tk_ItemCursorProc *) NULL, /* icursorProc */ (Tk_ItemSelectionProc *) NULL, /* selectionProc */ (Tk_ItemInsertProc *) NULL, /* insertProc */ (Tk_ItemDCharsProc *) NULL, /* dTextProc */ (Tk_ItemType *) NULL /* nextPtr */};#ifndef PI# define PI 3.14159265358979323846#endif/* * The uid's below comprise the legal values for the "-style" * option for arcs. */static Tk_Uid arcUid = NULL;static Tk_Uid chordUid = NULL;static Tk_Uid pieSliceUid = NULL;/* *-------------------------------------------------------------- * * CreateArc -- * * This procedure is invoked to create a new arc item in * a canvas. * * Results: * A standard Tcl return value. If an error occurred in * creating the item, then an error message is left in * interp->result; in this case itemPtr is * left uninitialized, so it can be safely freed by the * caller. * * Side effects: * A new arc item is created. * *-------------------------------------------------------------- */static intCreateArc(interp, canvas, itemPtr, argc, argv) Tcl_Interp *interp; /* Interpreter for error reporting. */ Tk_Canvas canvas; /* Canvas to hold new item. */ Tk_Item *itemPtr; /* Record to hold new item; header * has been initialized by caller. */ int argc; /* Number of arguments in argv. */ char **argv; /* Arguments describing arc. */{ ArcItem *arcPtr = (ArcItem *) itemPtr; if (argc < 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tk_PathName(Tk_CanvasTkwin(canvas)), " create ", itemPtr->typePtr->name, " x1 y1 x2 y2 ?options?\"", (char *) NULL); return TCL_ERROR; } /* * Carry out once-only initialization. */ if (arcUid == NULL) { arcUid = Tk_GetUid("arc"); chordUid = Tk_GetUid("chord"); pieSliceUid = Tk_GetUid("pieslice"); } /* * Carry out initialization that is needed in order to clean * up after errors during the the remainder of this procedure. */ arcPtr->start = 0; arcPtr->extent = 90; arcPtr->outlinePtr = NULL; arcPtr->numOutlinePoints = 0; arcPtr->width = 1; arcPtr->outlineColor = NULL; arcPtr->fillColor = NULL; arcPtr->fillStipple = None; arcPtr->outlineStipple = None; arcPtr->style = pieSliceUid; arcPtr->outlineGC = None; arcPtr->fillGC = None; /* * Process the arguments to fill in the item record. */ if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &arcPtr->bbox[0]) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[1], &arcPtr->bbox[1]) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[2], &arcPtr->bbox[2]) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[3], &arcPtr->bbox[3]) != TCL_OK)) { return TCL_ERROR; } if (ConfigureArc(interp, canvas, itemPtr, argc-4, argv+4, 0) != TCL_OK) { DeleteArc(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas))); return TCL_ERROR; } return TCL_OK;}/* *-------------------------------------------------------------- * * ArcCoords -- * * This procedure is invoked to process the "coords" widget * command on arcs. See the user documentation for details * on what it does. * * Results: * Returns TCL_OK or TCL_ERROR, and sets interp->result. * * Side effects: * The coordinates for the given item may be changed. * *-------------------------------------------------------------- */static intArcCoords(interp, canvas, itemPtr, argc, argv) Tcl_Interp *interp; /* Used for error reporting. */ Tk_Canvas canvas; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item whose coordinates are to be * read or modified. */ int argc; /* Number of coordinates supplied in * argv. */ char **argv; /* Array of coordinates: x1, y1, * x2, y2, ... */{ ArcItem *arcPtr = (ArcItem *) itemPtr; char c0[TCL_DOUBLE_SPACE], c1[TCL_DOUBLE_SPACE]; char c2[TCL_DOUBLE_SPACE], c3[TCL_DOUBLE_SPACE]; if (argc == 0) { Tcl_PrintDouble(interp, arcPtr->bbox[0], c0); Tcl_PrintDouble(interp, arcPtr->bbox[1], c1); Tcl_PrintDouble(interp, arcPtr->bbox[2], c2); Tcl_PrintDouble(interp, arcPtr->bbox[3], c3); Tcl_AppendResult(interp, c0, " ", c1, " ", c2, " ", c3, (char *) NULL); } else if (argc == 4) { if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &arcPtr->bbox[0]) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[1], &arcPtr->bbox[1]) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[2], &arcPtr->bbox[2]) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[3], &arcPtr->bbox[3]) != TCL_OK)) { return TCL_ERROR; } ComputeArcBbox(canvas, arcPtr); } else { sprintf(interp->result, "wrong # coordinates: expected 0 or 4, got %d", argc); return TCL_ERROR; } return TCL_OK;}/* *-------------------------------------------------------------- * * ConfigureArc -- * * This procedure is invoked to configure various aspects * of a arc item, such as its outline and fill colors. * * Results: * A standard Tcl result code. If an error occurs, then * an error message is left in interp->result. * * Side effects: * Configuration information, such as colors and stipple * patterns, may be set for itemPtr. * *-------------------------------------------------------------- */static intConfigureArc(interp, canvas, itemPtr, argc, argv, flags) Tcl_Interp *interp; /* Used for error reporting. */ Tk_Canvas canvas; /* Canvas containing itemPtr. */ Tk_Item *itemPtr; /* Arc item to reconfigure. */ int argc; /* Number of elements in argv. */ char **argv; /* Arguments describing things to configure. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */{ ArcItem *arcPtr = (ArcItem *) itemPtr; XGCValues gcValues; GC newGC; unsigned long mask; int i; Tk_Window tkwin; tkwin = Tk_CanvasTkwin(canvas); if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, argv, (char *) arcPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * A few of the options require additional processing, such as * style and graphics contexts. */ i = (int) (arcPtr->start/360.0); arcPtr->start -= i*360.0; if (arcPtr->start < 0) { arcPtr->start += 360.0; } i = (int) (arcPtr->extent/360.0); arcPtr->extent -= i*360.0; if ((arcPtr->style != arcUid) && (arcPtr->style != chordUid) && (arcPtr->style != pieSliceUid)) { Tcl_AppendResult(interp, "bad -style option \"", arcPtr->style, "\": must be arc, chord, or pieslice", (char *) NULL); arcPtr->style = pieSliceUid; return TCL_ERROR; } if (arcPtr->width < 0) { arcPtr->width = 1; } if (arcPtr->outlineColor == NULL) { newGC = None; } else { gcValues.foreground = arcPtr->outlineColor->pixel; gcValues.cap_style = CapButt; gcValues.line_width = arcPtr->width; mask = GCForeground|GCCapStyle|GCLineWidth; if (arcPtr->outlineStipple != None) { gcValues.stipple = arcPtr->outlineStipple; gcValues.fill_style = FillStippled; mask |= GCStipple|GCFillStyle; } newGC = Tk_GetGC(tkwin, mask, &gcValues); } if (arcPtr->outlineGC != None) { Tk_FreeGC(Tk_Display(tkwin), arcPtr->outlineGC); } arcPtr->outlineGC = newGC; if ((arcPtr->fillColor == NULL) || (arcPtr->style == arcUid)) { newGC = None; } else { gcValues.foreground = arcPtr->fillColor->pixel; if (arcPtr->style == chordUid) { gcValues.arc_mode = ArcChord; } else { gcValues.arc_mode = ArcPieSlice; } mask = GCForeground|GCArcMode; if (arcPtr->fillStipple != None) { gcValues.stipple = arcPtr->fillStipple; gcValues.fill_style = FillStippled; mask |= GCStipple|GCFillStyle; } newGC = Tk_GetGC(tkwin, mask, &gcValues);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -