]> cvs.zerfleddert.de Git - micropolis/blob - src/tk/tkcvpoly.c
Fixes for compilation with gcc 15
[micropolis] / src / tk / tkcvpoly.c
1 /*
2 * tkCanvPoly.c --
3 *
4 * This file implements polygon items for canvas widgets.
5 *
6 * Copyright 1991-1992 Regents of the University of California.
7 * Permission to use, copy, modify, and distribute this
8 * software and its documentation for any purpose and without
9 * fee is hereby granted, provided that the above copyright
10 * notice appear in all copies. The University of California
11 * makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without
13 * express or implied warranty.
14 */
15
16 #ifndef lint
17 static char rcsid[] = "$Header: /user6/ouster/wish/RCS/tkCanvPoly.c,v 1.6 92/07/28 15:40:10 ouster Exp $ SPRITE (Berkeley)";
18 #endif
19
20 #include <stdio.h>
21 #include <math.h>
22 #include "tkint.h"
23 #include "tkcanvas.h"
24 #include "tkconfig.h"
25
26 /*
27 * The structure below defines the record for each polygon item.
28 */
29
30 typedef struct PolygonItem {
31 Tk_Item header; /* Generic stuff that's the same for all
32 * types. MUST BE FIRST IN STRUCTURE. */
33 int numPoints; /* Number of points in polygon (always >= 3).
34 * Polygon is always closed. */
35 double *coordPtr; /* Pointer to malloc-ed array containing
36 * x- and y-coords of all points in polygon.
37 * X-coords are even-valued indices, y-coords
38 * are corresponding odd-valued indices. */
39 XColor *fg; /* Foreground color for polygon. */
40 Pixmap fillStipple; /* Stipple bitmap for filling polygon. */
41 GC gc; /* Graphics context for filling polygon. */
42 int smooth; /* Non-zero means draw shape smoothed (i.e.
43 * with Bezier splines). */
44 int splineSteps; /* Number of steps in each spline segment. */
45 } PolygonItem;
46
47 /*
48 * Information used for parsing configuration specs:
49 */
50
51 static Tk_ConfigSpec configSpecs[] = {
52 {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,
53 "black", Tk_Offset(PolygonItem, fg), TK_CONFIG_NULL_OK},
54 {TK_CONFIG_BOOLEAN, "-smooth", (char *) NULL, (char *) NULL,
55 "no", Tk_Offset(PolygonItem, smooth), TK_CONFIG_DONT_SET_DEFAULT},
56 {TK_CONFIG_INT, "-splinesteps", (char *) NULL, (char *) NULL,
57 "12", Tk_Offset(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT},
58 {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,
59 (char *) NULL, Tk_Offset(PolygonItem, fillStipple), TK_CONFIG_NULL_OK},
60 {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
61 (char *) NULL, 0, TK_CONFIG_NULL_OK, &tkCanvasTagsOption},
62 {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
63 (char *) NULL, 0, 0}
64 };
65
66 /*
67 * Prototypes for procedures defined in this file:
68 */
69
70 static void ComputePolygonBbox _ANSI_ARGS_((Tk_Canvas *canvasPtr,
71 PolygonItem *polyPtr));
72 static int ConfigurePolygon _ANSI_ARGS_((
73 Tk_Canvas *canvasPtr, Tk_Item *itemPtr, int argc,
74 char **argv, int flags));
75 static int CreatePolygon _ANSI_ARGS_((Tk_Canvas *canvasPtr,
76 struct Tk_Item *itemPtr, int argc, char **argv));
77 static void DeletePolygon _ANSI_ARGS_((Tk_Item *itemPtr));
78 static void DisplayPolygon _ANSI_ARGS_((Tk_Canvas *canvasPtr,
79 Tk_Item *itemPtr, Drawable dst));
80 static int PolygonCoords _ANSI_ARGS_((Tk_Canvas *canvasPtr,
81 Tk_Item *itemPtr, int argc, char **argv));
82 static int PolygonToArea _ANSI_ARGS_((Tk_Canvas *canvasPtr,
83 Tk_Item *itemPtr, double *rectPtr));
84 static double PolygonToPoint _ANSI_ARGS_((Tk_Canvas *canvasPtr,
85 Tk_Item *itemPtr, double *pointPtr));
86 static void ScalePolygon _ANSI_ARGS_((Tk_Canvas *canvasPtr,
87 Tk_Item *itemPtr, double originX, double originY,
88 double scaleX, double scaleY));
89 static void TranslatePolygon _ANSI_ARGS_((Tk_Canvas *canvasPtr,
90 Tk_Item *itemPtr, double deltaX, double deltaY));
91
92 /*
93 * The structures below defines the polygon item type by means
94 * of procedures that can be invoked by generic item code.
95 */
96
97 Tk_ItemType TkPolygonType = {
98 "polygon", /* name */
99 sizeof(PolygonItem), /* itemSize */
100 CreatePolygon, /* createProc */
101 configSpecs, /* configSpecs */
102 ConfigurePolygon, /* configureProc */
103 PolygonCoords, /* coordProc */
104 DeletePolygon, /* deleteProc */
105 DisplayPolygon, /* displayProc */
106 0, /* alwaysRedraw */
107 PolygonToPoint, /* pointProc */
108 PolygonToArea, /* areaProc */
109 (Tk_ItemPostscriptProc *) NULL, /* postscriptProc */
110 ScalePolygon, /* scaleProc */
111 TranslatePolygon, /* translateProc */
112 (Tk_ItemIndexProc *) NULL, /* indexProc */
113 (Tk_ItemCursorProc *) NULL, /* cursorProc */
114 (Tk_ItemSelectionProc *) NULL, /* selectionProc */
115 (Tk_ItemInsertProc *) NULL, /* insertProc */
116 (Tk_ItemDCharsProc *) NULL, /* dTextProc */
117 (Tk_ItemType *) NULL /* nextPtr */
118 };
119
120 /*
121 * The definition below determines how large are static arrays
122 * used to hold spline points (splines larger than this have to
123 * have their arrays malloc-ed).
124 */
125
126 #define MAX_STATIC_POINTS 200
127 \f
128 /*
129 *--------------------------------------------------------------
130 *
131 * CreatePolygon --
132 *
133 * This procedure is invoked to create a new polygon item in
134 * a canvas.
135 *
136 * Results:
137 * A standard Tcl return value. If an error occurred in
138 * creating the item, then an error message is left in
139 * canvasPtr->interp->result; in this case itemPtr is
140 * left uninitialized, so it can be safely freed by the
141 * caller.
142 *
143 * Side effects:
144 * A new polygon item is created.
145 *
146 *--------------------------------------------------------------
147 */
148
149 static int
150 CreatePolygon (
151 register Tk_Canvas *canvasPtr, /* Canvas to hold new item. */
152 Tk_Item *itemPtr, /* Record to hold new item; header
153 * has been initialized by caller. */
154 int argc, /* Number of arguments in argv. */
155 char **argv /* Arguments describing polygon. */
156 )
157 {
158 register PolygonItem *polyPtr = (PolygonItem *) itemPtr;
159 int i;
160
161 if (argc < 6) {
162 Tcl_AppendResult(canvasPtr->interp, "wrong # args: should be \"",
163 Tk_PathName(canvasPtr->tkwin),
164 "\" create x1 y1 x2 y2 x3 y3 ?x4 y4 ...? ?options?",
165 (char *) NULL);
166 return TCL_ERROR;
167 }
168
169 /*
170 * Carry out initialization that is needed in order to clean
171 * up after errors during the the remainder of this procedure.
172 */
173
174 polyPtr->numPoints = 0;
175 polyPtr->coordPtr = NULL;
176 polyPtr->fg = None;
177 polyPtr->fillStipple = None;
178 polyPtr->gc = None;
179 polyPtr->smooth = 0;
180 polyPtr->splineSteps = 12;
181
182 /*
183 * Count the number of points and then parse them into a point
184 * array. Leading arguments are assumed to be points if they
185 * start with a digit or a minus sign followed by a digit.
186 */
187
188 for (i = 4; i < (argc-1); i+=2) {
189 if ((!isdigit(argv[i][0])) &&
190 ((argv[i][0] != '-') || (!isdigit(argv[i][1])))) {
191 break;
192 }
193 }
194 if (PolygonCoords(canvasPtr, itemPtr, i, argv) != TCL_OK) {
195 goto error;
196 }
197
198 if (ConfigurePolygon(canvasPtr, itemPtr, argc-i, argv+i, 0) == TCL_OK) {
199 return TCL_OK;
200 }
201
202 error:
203 DeletePolygon(itemPtr);
204 return TCL_ERROR;
205 }
206 \f
207 /*
208 *--------------------------------------------------------------
209 *
210 * PolygonCoords --
211 *
212 * This procedure is invoked to process the "coords" widget
213 * command on polygons. See the user documentation for details
214 * on what it does.
215 *
216 * Results:
217 * Returns TCL_OK or TCL_ERROR, and sets canvasPtr->interp->result.
218 *
219 * Side effects:
220 * The coordinates for the given item may be changed.
221 *
222 *--------------------------------------------------------------
223 */
224
225 static int
226 PolygonCoords (
227 register Tk_Canvas *canvasPtr, /* Canvas containing item. */
228 Tk_Item *itemPtr, /* Item whose coordinates are to be
229 * read or modified. */
230 int argc, /* Number of coordinates supplied in
231 * argv. */
232 char **argv /* Array of coordinates: x1, y1,
233 * x2, y2, ... */
234 )
235 {
236 register PolygonItem *polyPtr = (PolygonItem *) itemPtr;
237 char buffer[300];
238 int i, numPoints;
239
240 if (argc == 0) {
241 for (i = 0; i < 2*polyPtr->numPoints; i++) {
242 sprintf(buffer, "%g", polyPtr->coordPtr[i]);
243 Tcl_AppendElement(canvasPtr->interp, buffer, 0);
244 }
245 } else if (argc < 6) {
246 Tcl_AppendResult(canvasPtr->interp,
247 "too few coordinates for polygon: must have at least 6",
248 (char *) NULL);
249 return TCL_ERROR;
250 } else if (argc & 1) {
251 Tcl_AppendResult(canvasPtr->interp,
252 "odd number of coordinates specified for polygon",
253 (char *) NULL);
254 return TCL_ERROR;
255 } else {
256 numPoints = argc/2;
257 if (polyPtr->numPoints != numPoints) {
258 if (polyPtr->coordPtr != NULL) {
259 ckfree((char *) polyPtr->coordPtr);
260 }
261
262 /*
263 * One extra point gets allocated here, just in case we have
264 * to add another point to close the polygon.
265 */
266
267 polyPtr->coordPtr = (double *) ckalloc((unsigned)
268 (sizeof(double) * (argc+2)));
269 polyPtr->numPoints = numPoints;
270 }
271 for (i = argc-1; i >= 0; i--) {
272 if (TkGetCanvasCoord(canvasPtr, argv[i], &polyPtr->coordPtr[i])
273 != TCL_OK) {
274 return TCL_ERROR;
275 }
276 }
277
278 /*
279 * Close the polygon if it isn't already closed.
280 */
281
282 if ((polyPtr->coordPtr[argc-2] != polyPtr->coordPtr[0])
283 || (polyPtr->coordPtr[argc-1] != polyPtr->coordPtr[1])) {
284 polyPtr->numPoints++;
285 polyPtr->coordPtr[argc] = polyPtr->coordPtr[0];
286 polyPtr->coordPtr[argc+1] = polyPtr->coordPtr[1];
287 }
288 ComputePolygonBbox(canvasPtr, polyPtr);
289 }
290 return TCL_OK;
291 }
292 \f
293 /*
294 *--------------------------------------------------------------
295 *
296 * ConfigurePolygon --
297 *
298 * This procedure is invoked to configure various aspects
299 * of a polygon item such as its background color.
300 *
301 * Results:
302 * A standard Tcl result code. If an error occurs, then
303 * an error message is left in canvasPtr->interp->result.
304 *
305 * Side effects:
306 * Configuration information, such as colors and stipple
307 * patterns, may be set for itemPtr.
308 *
309 *--------------------------------------------------------------
310 */
311
312 static int
313 ConfigurePolygon (
314 Tk_Canvas *canvasPtr, /* Canvas containing itemPtr. */
315 Tk_Item *itemPtr, /* Polygon item to reconfigure. */
316 int argc, /* Number of elements in argv. */
317 char **argv, /* Arguments describing things to configure. */
318 int flags /* Flags to pass to Tk_ConfigureWidget. */
319 )
320 {
321 register PolygonItem *polyPtr = (PolygonItem *) itemPtr;
322 XGCValues gcValues;
323 GC newGC;
324 unsigned long mask;
325
326 if (Tk_ConfigureWidget(canvasPtr->interp, canvasPtr->tkwin,
327 configSpecs, argc, argv, (char *) polyPtr, flags) != TCL_OK) {
328 return TCL_ERROR;
329 }
330
331 /*
332 * A few of the options require additional processing, such as
333 * graphics contexts.
334 */
335
336 if (polyPtr->fg == NULL) {
337 newGC = None;
338 } else {
339 gcValues.foreground = polyPtr->fg->pixel;
340 mask = GCForeground;
341 if (polyPtr->fillStipple != None) {
342 gcValues.stipple = polyPtr->fillStipple;
343 gcValues.fill_style = FillStippled;
344 mask |= GCStipple|GCFillStyle;
345 }
346 newGC = Tk_GetGC(canvasPtr->tkwin, mask, &gcValues);
347 }
348 if (polyPtr->gc != None) {
349 Tk_FreeGC(polyPtr->gc);
350 }
351 polyPtr->gc = newGC;
352
353 /*
354 * Keep spline parameters within reasonable limits.
355 */
356
357 if (polyPtr->splineSteps < 1) {
358 polyPtr->splineSteps = 1;
359 } else if (polyPtr->splineSteps > 100) {
360 polyPtr->splineSteps = 100;
361 }
362
363 ComputePolygonBbox(canvasPtr, polyPtr);
364 return TCL_OK;
365 }
366 \f
367 /*
368 *--------------------------------------------------------------
369 *
370 * DeletePolygon --
371 *
372 * This procedure is called to clean up the data structure
373 * associated with a polygon item.
374 *
375 * Results:
376 * None.
377 *
378 * Side effects:
379 * Resources associated with itemPtr are released.
380 *
381 *--------------------------------------------------------------
382 */
383
384 static void
385 DeletePolygon (
386 Tk_Item *itemPtr /* Item that is being deleted. */
387 )
388 {
389 register PolygonItem *polyPtr = (PolygonItem *) itemPtr;
390
391 if (polyPtr->coordPtr != NULL) {
392 ckfree((char *) polyPtr->coordPtr);
393 }
394 if (polyPtr->fg != NULL) {
395 Tk_FreeColor(polyPtr->fg);
396 }
397 if (polyPtr->fillStipple != None) {
398 Tk_FreeBitmap(polyPtr->fillStipple);
399 }
400 if (polyPtr->gc != None) {
401 Tk_FreeGC(polyPtr->gc);
402 }
403 }
404 \f
405 /*
406 *--------------------------------------------------------------
407 *
408 * ComputePolygonBbox --
409 *
410 * This procedure is invoked to compute the bounding box of
411 * all the pixels that may be drawn as part of a polygon.
412 *
413 * Results:
414 * None.
415 *
416 * Side effects:
417 * The fields x1, y1, x2, and y2 are updated in the header
418 * for itemPtr.
419 *
420 *--------------------------------------------------------------
421 */
422
423 static void
424 ComputePolygonBbox (
425 register Tk_Canvas *canvasPtr, /* Canvas that contains item. */
426 PolygonItem *polyPtr /* Item whose bbox is to be
427 * recomputed. */
428 )
429 {
430 register double *coordPtr;
431 int i;
432
433 coordPtr = polyPtr->coordPtr;
434 polyPtr->header.x1 = polyPtr->header.x2 = *coordPtr;
435 polyPtr->header.y1 = polyPtr->header.y2 = coordPtr[1];
436
437 for (i = 1, coordPtr = polyPtr->coordPtr+2; i < polyPtr->numPoints;
438 i++, coordPtr += 2) {
439 TkIncludePoint(canvasPtr, (Tk_Item *) polyPtr, coordPtr);
440 }
441
442 /*
443 * Add one more pixel of fudge factor just to be safe (e.g.
444 * X may round differently than we do).
445 */
446
447 polyPtr->header.x1 -= 1;
448 polyPtr->header.x2 += 1;
449 polyPtr->header.y1 -= 1;
450 polyPtr->header.y2 += 1;
451 }
452 \f
453 /*
454 *--------------------------------------------------------------
455 *
456 * TkFillPolygon --
457 *
458 * This procedure is invoked to convert a polygon to screen
459 * coordinates and display it using a particular GC.
460 *
461 * Results:
462 * None.
463 *
464 * Side effects:
465 * ItemPtr is drawn in drawable using the transformation
466 * information in canvasPtr.
467 *
468 *--------------------------------------------------------------
469 */
470
471 void
472 TkFillPolygon (
473 register Tk_Canvas *canvasPtr, /* Canvas whose coordinate system
474 * is to be used for drawing. */
475 double *coordPtr, /* Array of coordinates for polygon:
476 * x1, y1, x2, y2, .... */
477 int numPoints, /* Twice this many coordinates are
478 * present at *coordPtr. */
479 Drawable drawable, /* Pixmap or window in which to draw
480 * polygon. */
481 GC gc /* Graphics context for drawing. */
482 )
483 {
484 XPoint staticPoints[MAX_STATIC_POINTS];
485 XPoint *pointPtr;
486 register XPoint *pPtr;
487 int i;
488
489 /*
490 * Build up an array of points in screen coordinates. Use a
491 * static array unless the polygon has an enormous number of points;
492 * in this case, dynamically allocate an array.
493 */
494
495 if (numPoints <= MAX_STATIC_POINTS) {
496 pointPtr = staticPoints;
497 } else {
498 pointPtr = (XPoint *) ckalloc((unsigned) (numPoints * sizeof(XPoint)));
499 }
500
501 for (i = 0, pPtr = pointPtr; i < numPoints; i += 1, coordPtr += 2, pPtr++) {
502 pPtr->x = SCREEN_X(canvasPtr, coordPtr[0]);
503 pPtr->y = SCREEN_Y(canvasPtr, coordPtr[1]);
504 }
505
506 /*
507 * Display polygon, then free up polygon storage if it was dynamically
508 * allocated.
509 */
510
511 XFillPolygon(Tk_Display(canvasPtr->tkwin), drawable, gc, pointPtr,
512 numPoints, Complex, CoordModeOrigin);
513 if (pointPtr != staticPoints) {
514 ckfree((char *) pointPtr);
515 }
516
517 }
518 \f
519 /*
520 *--------------------------------------------------------------
521 *
522 * DisplayPolygon --
523 *
524 * This procedure is invoked to draw a polygon item in a given
525 * drawable.
526 *
527 * Results:
528 * None.
529 *
530 * Side effects:
531 * ItemPtr is drawn in drawable using the transformation
532 * information in canvasPtr.
533 *
534 *--------------------------------------------------------------
535 */
536
537 static void
538 DisplayPolygon (
539 register Tk_Canvas *canvasPtr, /* Canvas that contains item. */
540 Tk_Item *itemPtr, /* Item to be displayed. */
541 Drawable drawable /* Pixmap or window in which to draw
542 * item. */
543 )
544 {
545 register PolygonItem *polyPtr = (PolygonItem *) itemPtr;
546
547 if (polyPtr->gc == None) {
548 return;
549 }
550
551 if (!polyPtr->smooth) {
552 TkFillPolygon(canvasPtr, polyPtr->coordPtr, polyPtr->numPoints,
553 drawable, polyPtr->gc);
554 } else {
555 int numPoints;
556 XPoint staticPoints[MAX_STATIC_POINTS];
557 XPoint *pointPtr;
558
559 /*
560 * This is a smoothed polygon. Display using a set of generated
561 * spline points rather than the original points.
562 */
563
564 numPoints = 1 + polyPtr->numPoints*polyPtr->splineSteps;
565 if (numPoints <= MAX_STATIC_POINTS) {
566 pointPtr = staticPoints;
567 } else {
568 pointPtr = (XPoint *) ckalloc((unsigned)
569 (numPoints * sizeof(XPoint)));
570 }
571 numPoints = TkMakeBezierCurve(canvasPtr, polyPtr->coordPtr,
572 polyPtr->numPoints, polyPtr->splineSteps, pointPtr,
573 (double *) NULL);
574 XFillPolygon(Tk_Display(canvasPtr->tkwin), drawable, polyPtr->gc,
575 pointPtr, numPoints, Complex, CoordModeOrigin);
576 if (pointPtr != staticPoints) {
577 ckfree((char *) pointPtr);
578 }
579 }
580 }
581 \f
582 /*
583 *--------------------------------------------------------------
584 *
585 * PolygonToPoint --
586 *
587 * Computes the distance from a given point to a given
588 * polygon, in canvas units.
589 *
590 * Results:
591 * The return value is 0 if the point whose x and y coordinates
592 * are pointPtr[0] and pointPtr[1] is inside the polygon. If the
593 * point isn't inside the polygon then the return value is the
594 * distance from the point to the polygon.
595 *
596 * Side effects:
597 * None.
598 *
599 *--------------------------------------------------------------
600 */
601
602 /* ARGSUSED */
603 static double
604 PolygonToPoint (
605 Tk_Canvas *canvasPtr, /* Canvas containing item. */
606 Tk_Item *itemPtr, /* Item to check against point. */
607 double *pointPtr /* Pointer to x and y coordinates. */
608 )
609 {
610 PolygonItem *polyPtr = (PolygonItem *) itemPtr;
611 double *coordPtr, distance;
612 double staticSpace[2*MAX_STATIC_POINTS];
613 int numPoints;
614
615 if (!polyPtr->smooth) {
616 return TkPolygonToPoint(polyPtr->coordPtr, polyPtr->numPoints,
617 pointPtr);
618 }
619
620 /*
621 * Smoothed polygon. Generate a new set of points and use them
622 * for comparison.
623 */
624
625 numPoints = 1 + polyPtr->numPoints*polyPtr->splineSteps;
626 if (numPoints <= MAX_STATIC_POINTS) {
627 coordPtr = staticSpace;
628 } else {
629 coordPtr = (double *) ckalloc((unsigned)
630 (2*numPoints*sizeof(double)));
631 }
632 numPoints = TkMakeBezierCurve(canvasPtr, polyPtr->coordPtr,
633 polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
634 coordPtr);
635 distance = TkPolygonToPoint(coordPtr, numPoints, pointPtr);
636 if (coordPtr != staticSpace) {
637 ckfree((char *) coordPtr);
638 }
639 return distance;
640 }
641 \f
642 /*
643 *--------------------------------------------------------------
644 *
645 * PolygonToArea --
646 *
647 * This procedure is called to determine whether an item
648 * lies entirely inside, entirely outside, or overlapping
649 * a given rectangular area.
650 *
651 * Results:
652 * -1 is returned if the item is entirely outside the area
653 * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
654 * inside the given area.
655 *
656 * Side effects:
657 * None.
658 *
659 *--------------------------------------------------------------
660 */
661
662 /* ARGSUSED */
663 static int
664 PolygonToArea (
665 Tk_Canvas *canvasPtr, /* Canvas containing item. */
666 Tk_Item *itemPtr, /* Item to check against polygon. */
667 double *rectPtr /* Pointer to array of four coordinates
668 * (x1, y1, x2, y2) describing rectangular
669 * area. */
670 )
671 {
672 PolygonItem *polyPtr = (PolygonItem *) itemPtr;
673 double *coordPtr;
674 double staticSpace[2*MAX_STATIC_POINTS];
675 int numPoints, result;
676
677 if (!polyPtr->smooth) {
678 return TkPolygonToArea(polyPtr->coordPtr, polyPtr->numPoints, rectPtr);
679 }
680
681 /*
682 * Smoothed polygon. Generate a new set of points and use them
683 * for comparison.
684 */
685
686 numPoints = 1 + polyPtr->numPoints*polyPtr->splineSteps;
687 if (numPoints <= MAX_STATIC_POINTS) {
688 coordPtr = staticSpace;
689 } else {
690 coordPtr = (double *) ckalloc((unsigned)
691 (2*numPoints*sizeof(double)));
692 }
693 numPoints = TkMakeBezierCurve(canvasPtr, polyPtr->coordPtr,
694 polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
695 coordPtr);
696 result = TkPolygonToArea(coordPtr, numPoints, rectPtr);
697 if (coordPtr != staticSpace) {
698 ckfree((char *) coordPtr);
699 }
700 return result;
701 }
702 \f
703 /*
704 *--------------------------------------------------------------
705 *
706 * ScalePolygon --
707 *
708 * This procedure is invoked to rescale a polygon item.
709 *
710 * Results:
711 * None.
712 *
713 * Side effects:
714 * The polygon referred to by itemPtr is rescaled so that the
715 * following transformation is applied to all point
716 * coordinates:
717 * x' = originX + scaleX*(x-originX)
718 * y' = originY + scaleY*(y-originY)
719 *
720 *--------------------------------------------------------------
721 */
722
723 static void
724 ScalePolygon (
725 Tk_Canvas *canvasPtr, /* Canvas containing polygon. */
726 Tk_Item *itemPtr, /* Polygon to be scaled. */
727 double originX,
728 double originY, /* Origin about which to scale rect. */
729 double scaleX, /* Amount to scale in X direction. */
730 double scaleY /* Amount to scale in Y direction. */
731 )
732 {
733 PolygonItem *polyPtr = (PolygonItem *) itemPtr;
734 register double *coordPtr;
735 int i;
736
737 for (i = 0, coordPtr = polyPtr->coordPtr; i < polyPtr->numPoints;
738 i++, coordPtr += 2) {
739 *coordPtr = originX + scaleX*(*coordPtr - originX);
740 coordPtr[1] = originY + scaleY*(coordPtr[1] - originY);
741 }
742 ComputePolygonBbox(canvasPtr, polyPtr);
743 }
744 \f
745 /*
746 *--------------------------------------------------------------
747 *
748 * TranslatePolygon --
749 *
750 * This procedure is called to move a polygon by a given
751 * amount.
752 *
753 * Results:
754 * None.
755 *
756 * Side effects:
757 * The position of the polygon is offset by (xDelta, yDelta),
758 * and the bounding box is updated in the generic part of the
759 * item structure.
760 *
761 *--------------------------------------------------------------
762 */
763
764 static void
765 TranslatePolygon (
766 Tk_Canvas *canvasPtr, /* Canvas containing item. */
767 Tk_Item *itemPtr, /* Item that is being moved. */
768 double deltaX,
769 double deltaY /* Amount by which item is to be
770 * moved. */
771 )
772 {
773 PolygonItem *polyPtr = (PolygonItem *) itemPtr;
774 register double *coordPtr;
775 int i;
776
777 for (i = 0, coordPtr = polyPtr->coordPtr; i < polyPtr->numPoints;
778 i++, coordPtr += 2) {
779 *coordPtr += deltaX;
780 coordPtr[1] += deltaY;
781 }
782 ComputePolygonBbox(canvasPtr, polyPtr);
783 }
Impressum, Datenschutz