aboutsummaryrefslogtreecommitdiff
path: root/generic/Rectangle.c
diff options
context:
space:
mode:
authorlecoanet2000-01-13 09:45:59 +0000
committerlecoanet2000-01-13 09:45:59 +0000
commita776aef900eca7ec13d72e84e59294f37277d727 (patch)
tree7b6fc0a83e68530f92b38cc2f72ac943386a680c /generic/Rectangle.c
parent48fcc19f26d053b1b4a0f94f986a9bcc37eb9aa9 (diff)
downloadtkzinc-a776aef900eca7ec13d72e84e59294f37277d727.zip
tkzinc-a776aef900eca7ec13d72e84e59294f37277d727.tar.gz
tkzinc-a776aef900eca7ec13d72e84e59294f37277d727.tar.bz2
tkzinc-a776aef900eca7ec13d72e84e59294f37277d727.tar.xz
Adaptation des ent�tes.
Utilisation du module de couleur interne. Implementation du relief en rotation. Arrondi des coordonn�es transform�es. Am�nagement de la m�thode Coords.
Diffstat (limited to 'generic/Rectangle.c')
-rw-r--r--generic/Rectangle.c832
1 files changed, 832 insertions, 0 deletions
diff --git a/generic/Rectangle.c b/generic/Rectangle.c
new file mode 100644
index 0000000..f573f3f
--- /dev/null
+++ b/generic/Rectangle.c
@@ -0,0 +1,832 @@
+/*
+ * Rectangle.c -- Implementation of rectangle item.
+ *
+ * Authors : Patrick Lecoanet.
+ * Creation date : Fri Dec 2 14:47:42 1994
+ *
+ * $Id$
+ */
+
+/*
+ * Copyright (c) 1993 - 1999 CENA, Patrick Lecoanet --
+ *
+ * This code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this code; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include <malloc.h>
+
+#include "Item.h"
+#include "Geo.h"
+#include "Draw.h"
+#include "Types.h"
+#include "Image.h"
+#include "Color.h"
+#include "WidgetInfo.h"
+
+
+static const char rcsid[] = "$Id$";
+static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $";
+
+/*
+ * Bit offset of flags.
+ */
+#define FILLED_BIT 1 /* If the rectangle is filled with color/pattern */
+
+
+/*
+ **********************************************************************************
+ *
+ * Specific Rectangle item record
+ *
+ **********************************************************************************
+ */
+
+typedef struct _RectangleItemStruct {
+ ItemStruct header;
+
+ /* Public data */
+ RadarPoint coords[2];
+ unsigned char flags;
+ ReliefStyle relief;
+ LineStyle line_style;
+ int line_width;
+ RadarColor line_color;
+ Pixmap fill_pattern;
+ Pixmap line_pattern;
+ RadarColor fill_color;
+ char *tile_name;
+
+ /* Private data */
+ RadarPoint dev[4];
+ RadarImage tile;
+ RadarColorGradient gradient;
+} RectangleItemStruct, *RectangleItem;
+
+
+static RadarAttrConfig rect_attrs[] = {
+ { RADAR_CONFIG_BOOL, "-composerotation", NULL,
+ Tk_Offset(RectangleItemStruct, header.flags), COMPOSE_ROTATION_BIT,
+ RADAR_COORDS_FLAG, False },
+ { RADAR_CONFIG_BOOL, "-composescale", NULL,
+ Tk_Offset(RectangleItemStruct, header.flags), COMPOSE_SCALE_BIT,
+ RADAR_COORDS_FLAG, False },
+ { RADAR_CONFIG_COLOR, "-fillcolor", NULL,
+ Tk_Offset(RectangleItemStruct, fill_color), 0,
+ RADAR_DRAW_FLAG|RADAR_BORDER_FLAG, False },
+ { RADAR_CONFIG_BOOL, "-filled", NULL,
+ Tk_Offset(RectangleItemStruct, flags), FILLED_BIT, RADAR_COORDS_FLAG, False },
+ { RADAR_CONFIG_PATTERN, "-fillpattern", NULL,
+ Tk_Offset(RectangleItemStruct, fill_pattern), 0, RADAR_DRAW_FLAG, False },
+ { RADAR_CONFIG_COLOR, "-linecolor", NULL,
+ Tk_Offset(RectangleItemStruct, line_color), 0,
+ RADAR_DRAW_FLAG, False },
+ { RADAR_CONFIG_PATTERN, "-linepattern", NULL,
+ Tk_Offset(RectangleItemStruct, line_pattern), 0, RADAR_DRAW_FLAG, False },
+ { RADAR_CONFIG_LINE_STYLE, "-linestyle", NULL,
+ Tk_Offset(RectangleItemStruct, line_style), 0, RADAR_DRAW_FLAG, False },
+ { RADAR_CONFIG_DIM, "-linewidth", NULL,
+ Tk_Offset(RectangleItemStruct, line_width), 0, RADAR_COORDS_FLAG, False },
+ { RADAR_CONFIG_PRI, "-priority", NULL,
+ Tk_Offset(RectangleItemStruct, header.priority), 0,
+ RADAR_DRAW_FLAG|RADAR_REPICK_FLAG, False },
+ { RADAR_CONFIG_RELIEF, "-relief", NULL, Tk_Offset(RectangleItemStruct, relief), 0,
+ RADAR_DRAW_FLAG, False },
+ { RADAR_CONFIG_BOOL, "-sensitive", NULL,
+ Tk_Offset(RectangleItemStruct, header.flags), SENSITIVE_BIT,
+ RADAR_REPICK_FLAG, False },
+ { RADAR_CONFIG_TAGS, "-tags", NULL,
+ Tk_Offset(RectangleItemStruct, header.tags), 0, 0, False },
+ { RADAR_CONFIG_IMAGE, "-tile", NULL,
+ Tk_Offset(RectangleItemStruct, tile_name), 0,
+ RADAR_DRAW_FLAG|RADAR_TILE_FLAG, False },
+ { RADAR_CONFIG_BOOL, "-visible", NULL,
+ Tk_Offset(RectangleItemStruct, header.flags), VISIBLE_BIT,
+ RADAR_DRAW_FLAG|RADAR_REPICK_FLAG|RADAR_VIS_FLAG, False },
+
+ { RADAR_CONFIG_END, NULL, NULL, 0, 0, 0 }
+};
+
+
+/*
+ **********************************************************************************
+ *
+ * RectTileChange --
+ *
+ **********************************************************************************
+ */
+static void
+RectTileChange(ClientData client_data,
+ int x,
+ int y,
+ int width,
+ int height,
+ int image_width,
+ int image_height)
+{
+ RectangleItem rect = (RectangleItem) client_data;
+
+ InvalidateImage(rect->tile);
+ ITEM.Invalidate((Item) rect, RADAR_COORDS_FLAG);
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Init --
+ *
+ **********************************************************************************
+ */
+static int
+Init(Item item,
+ int *argc,
+ Arg **args)
+{
+ WidgetInfo *wi = item->wi;
+ RectangleItem rect = (RectangleItem) item;
+ Arg *elems;
+ int result, num_elems;
+#ifdef PTK
+ LangFreeProc *freeProc = NULL;
+#endif
+
+ rect->gradient = NULL;
+
+ /* Init attributes */
+ SET(item->flags, VISIBLE_BIT);
+ SET(item->flags, SENSITIVE_BIT);
+ SET(item->flags, COMPOSE_ROTATION_BIT);
+ SET(item->flags, COMPOSE_SCALE_BIT);
+ item->priority = DEFAULT_RECTANGLE_PRIORITY;
+
+ if (*argc < 1) {
+ Tcl_AppendResult(wi->interp, " rectangle coords expected", NULL);
+ return RADAR_ERROR;
+ }
+ result = Lang_SplitList(wi->interp, (*args)[0], &num_elems, &elems, &freeProc);
+ if ((result == RADAR_ERROR) || (num_elems != 4)) {
+ rect_error:
+#ifdef PTK
+ if (elems != NULL && freeProc) {
+ (*freeProc)(num_elems, elems);
+ }
+#endif
+ Tcl_AppendResult(wi->interp, " malformed rectangle coords", NULL);
+ return RADAR_ERROR;
+ }
+ if (Tcl_GetDouble(wi->interp, elems[0], &rect->coords[0].x) == RADAR_ERROR) {
+ rect_error2:
+#ifndef PTK
+ Tcl_Free((char *) elems);
+#endif
+ goto rect_error;
+ };
+ if (Tcl_GetDouble(wi->interp, elems[1], &rect->coords[0].y) == RADAR_ERROR) {
+ goto rect_error2;
+ };
+ if (Tcl_GetDouble(wi->interp, elems[2], &rect->coords[1].x) == RADAR_ERROR) {
+ goto rect_error2;
+ };
+ if (Tcl_GetDouble(wi->interp, elems[3], &rect->coords[1].y) == RADAR_ERROR) {
+ goto rect_error2;
+ };
+ (*args)++;
+ (*argc)--;
+#ifndef PTK
+ Tcl_Free((char *) elems);
+#else
+ if (freeProc) {
+ (*freeProc)(num_elems, elems);
+ }
+#endif
+
+ CLEAR(rect->flags, FILLED_BIT);
+ rect->relief = RELIEF_FLAT;
+ rect->line_style = LINE_SIMPLE;
+ rect->line_width = 1;
+ rect->line_pattern = RadarUnspecifiedPattern;
+ rect->tile_name = "";
+ rect->tile = RadarUnspecifiedImage;
+ rect->fill_pattern = RadarUnspecifiedPattern;
+ rect->line_color = RadarGetColorByValue(wi->win, wi->fore_color);
+ rect->fill_color = RadarGetColorByValue(wi->win, wi->fore_color);
+
+ return RADAR_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Clone --
+ *
+ **********************************************************************************
+ */
+static void
+Clone(Item item)
+{
+ RectangleItem rect = (RectangleItem) item;
+ WidgetInfo *wi = item->wi;
+ char *text;
+
+ if (rect->gradient) {
+ rect->gradient = RadarGetColorGradientByValue(rect->gradient);
+ }
+ if (strlen(rect->tile_name) != 0) {
+ text = RadarMalloc((strlen(rect->tile_name) + 1) * sizeof(char));
+ strcpy(text, rect->tile_name);
+ rect->tile_name = text;
+ rect->tile = Tk_GetImage(wi->interp, wi->win, rect->tile_name,
+ RectTileChange, (ClientData) rect);
+ }
+ if (rect->line_pattern != RadarUnspecifiedPattern) {
+ rect->line_pattern = Tk_GetBitmap(wi->interp, wi->win,
+ Tk_NameOfBitmap(wi->dpy, rect->line_pattern));
+ }
+ if (rect->fill_pattern != RadarUnspecifiedPattern) {
+ rect->fill_pattern = Tk_GetBitmap(wi->interp, wi->win,
+ Tk_NameOfBitmap(wi->dpy, rect->fill_pattern));
+ }
+ rect->line_color = RadarGetColorByValue(wi->win, rect->line_color);
+ rect->fill_color = RadarGetColorByValue(wi->win, rect->fill_color);
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Destroy --
+ *
+ **********************************************************************************
+ */
+static void
+Destroy(Item item)
+{
+ WidgetInfo *wi = item->wi;
+ RectangleItem rect = (RectangleItem) item;
+
+ if (strlen(rect->tile_name) != 0) {
+ RadarFree(rect->tile_name);
+ }
+ if (rect->tile != RadarUnspecifiedImage) {
+ Tk_FreeImage(rect->tile);
+ rect->tile = RadarUnspecifiedImage;
+ }
+ if (rect->gradient) {
+ RadarFreeColorGradient(rect->gradient);
+ }
+ if (rect->line_pattern != RadarUnspecifiedPattern) {
+ Tk_FreeBitmap(wi->dpy, rect->line_pattern);
+ }
+ if (rect->fill_pattern != RadarUnspecifiedPattern) {
+ Tk_FreeBitmap(wi->dpy, rect->fill_pattern);
+ }
+ RadarFreeColor(rect->fill_color);
+ RadarFreeColor(rect->line_color);
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Configure --
+ *
+ **********************************************************************************
+ */
+static int
+Configure(Item item,
+ int argc,
+ RadarAttrList argv,
+ int *flags)
+{
+ WidgetInfo *wi = item->wi;
+ RectangleItem rect = (RectangleItem) item;
+
+ if (ITEM_P.ConfigureAttributes((char *) item, -1, argc, argv, flags) == RADAR_ERROR) {
+ return RADAR_ERROR;
+ }
+
+ if (rect->gradient &&
+ (ISSET(*flags, RADAR_BORDER_FLAG) || (rect->relief == RELIEF_FLAT))) {
+ RadarFreeColorGradient(rect->gradient);
+ rect->gradient = NULL;
+ }
+ if ((rect->relief != RELIEF_FLAT) && !rect->gradient) {
+ rect->gradient = RadarGetReliefGradient(wi->interp, wi->win,
+ RadarNameOfColor(rect->fill_color));
+ }
+ if (ISSET(*flags, RADAR_TILE_FLAG)) {
+ Tk_Image tile;
+
+ if (strcmp(rect->tile_name, "") != 0) {
+ tile = Tk_GetImage(wi->interp, wi->win, rect->tile_name,
+ RectTileChange, (ClientData) rect);
+ if (tile == NULL) {
+ /*
+ * The name will not be in sync with the image in
+ * this case.
+ */
+ return RADAR_ERROR;
+ }
+ }
+ else {
+ tile = RadarUnspecifiedImage;
+ }
+ if (rect->tile != RadarUnspecifiedImage) {
+ Tk_FreeImage(rect->tile);
+ }
+ rect->tile = tile;
+ }
+
+ return RADAR_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Query --
+ *
+ **********************************************************************************
+ */
+static int
+Query(Item item,
+ int argc,
+ RadarAttrList argv)
+{
+ if (ITEM_P.QueryAttribute((char *) item, -1, argv[0]) == RADAR_ERROR) {
+ return RADAR_ERROR;
+ }
+
+ return RADAR_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * ComputeCoordinates --
+ *
+ **********************************************************************************
+ */
+static void
+ComputeCoordinates(Item item,
+ RadarBool force)
+{
+ WidgetInfo *wi = item->wi;
+ RectangleItem rect = (RectangleItem) item;
+ RadarPoint p[4];
+
+ ResetBBox(&item->item_bounding_box);
+ if (!rect->line_width && ISCLEAR(rect->flags, FILLED_BIT)) {
+ return;
+ }
+
+ p[0] = rect->coords[0];
+ p[2] = rect->coords[1];
+ p[1].x = p[2].x;
+ p[1].y = p[0].y;
+ p[3].x = p[0].x;
+ p[3].y = p[2].y;
+ RadarTransformPoints(wi->current_transfo, p, rect->dev, 4);
+
+ /*
+ * Add all points to the bounding box. Then expand by the line
+ * width to account for mitered corners. This is an overestimate.
+ */
+ AddPointsToBBox(&item->item_bounding_box, rect->dev, 4);
+ if (rect->line_width > 0) {
+ item->item_bounding_box.orig.x -= rect->line_width;
+ item->item_bounding_box.orig.y -= rect->line_width;
+ item->item_bounding_box.corner.x += rect->line_width;
+ item->item_bounding_box.corner.y += rect->line_width;
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * ToArea --
+ * Tell if the object is entirely outside (-1),
+ * entirely inside (1) or in between (0).
+ *
+ **********************************************************************************
+ */
+static int
+ToArea(Item item,
+ RadarBBox *area,
+ Tk_Uid tag_uid,
+ int enclosed,
+ RadarBool report)
+{
+ RectangleItem rect = (RectangleItem) item;
+ int result;
+
+ result = -1;
+
+ if (ISSET(rect->flags, FILLED_BIT)) {
+ result = PolygonInBBox(rect->dev, 4, area);
+ }
+ else if (rect->line_width > 0) {
+ int i;
+ RadarPoint pts[5];
+
+ for (i = 0; i < 4; i++) {
+ pts[i] = rect->dev[i];
+ }
+ pts[4] = pts[0];
+ result = PolylineInBBox(pts, 5, rect->line_width,
+ CapProjecting, JoinMiter, area);
+ }
+
+ return result;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Draw --
+ *
+ **********************************************************************************
+ */
+static void
+Draw(Item item)
+{
+ WidgetInfo *wi = item->wi;
+ RectangleItem rect = (RectangleItem) item;
+ XGCValues values;
+ int i, gc_mask;
+ RadarBool aligned;
+ RadarDim delta;
+ XRectangle r;
+ XPoint xp[5];
+
+ delta = rect->dev[0].y - rect->dev[1].y;
+ delta = ABS(delta);
+ aligned = delta < X_PRECISION_LIMIT;
+ delta = rect->dev[0].x - rect->dev[1].x;
+ delta = ABS(delta);
+ aligned |= delta < X_PRECISION_LIMIT;
+
+ if (aligned) {
+ if (rect->dev[0].x < rect->dev[2].x) {
+ r.x = REAL_TO_INT(rect->dev[0].x);
+ r.width = REAL_TO_INT(rect->dev[2].x) - r.x;
+ }
+ else {
+ r.x = REAL_TO_INT(rect->dev[2].x);
+ r.width = REAL_TO_INT(rect->dev[0].x) - r.x;
+ }
+ if (rect->dev[0].y < rect->dev[2].y) {
+ r.y = REAL_TO_INT(rect->dev[0].y);
+ r.height = REAL_TO_INT(rect->dev[2].y) - r.y;
+ }
+ else {
+ r.y = REAL_TO_INT(rect->dev[2].y);
+ r.height = REAL_TO_INT(rect->dev[0].y) - r.y;
+ }
+ }
+ else {
+ for (i = 0; i < 4; i++) {
+ xp[i].x = REAL_TO_INT(rect->dev[i].x);
+ xp[i].y = REAL_TO_INT(rect->dev[i].y);
+ }
+ xp[i] = xp[0];
+ }
+
+ /*
+ * Fill if requested.
+ */
+ if (ISSET(rect->flags, FILLED_BIT)) {
+ values.foreground = RadarPixel(rect->fill_color);
+ if (rect->tile != RadarUnspecifiedImage) { /* Fill tiled */
+ Pixmap pmap = GetImagePixmap(wi->win, rect->tile);
+ values.fill_style = FillTiled;
+ values.tile = pmap;
+ values.ts_x_origin = (int) item->item_bounding_box.orig.x;
+ values.ts_y_origin = (int) item->item_bounding_box.orig.y;
+ XChangeGC(wi->dpy, wi->gc,
+ GCTileStipXOrigin|GCTileStipYOrigin|GCFillStyle|GCTile, &values);
+ }
+ else if (rect->fill_pattern != RadarUnspecifiedPattern) { /* Fill stippled */
+ values.fill_style = FillStippled;
+ values.stipple = rect->fill_pattern;
+ values.ts_x_origin = (int) item->item_bounding_box.orig.x;
+ values.ts_y_origin = (int) item->item_bounding_box.orig.y;
+ XChangeGC(wi->dpy, wi->gc,
+ GCTileStipXOrigin|GCTileStipYOrigin|GCFillStyle|GCStipple|GCForeground,
+ &values);
+ }
+ else { /* Fill solid */
+ values.fill_style = FillSolid;
+ XChangeGC(wi->dpy, wi->gc, GCForeground | GCFillStyle, &values);
+ }
+ if (aligned) {
+ XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y,
+ r.width, r.height);
+ }
+ else {
+ XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, xp, 4, Convex, CoordModeOrigin);
+ }
+ }
+
+ /* Draw the outline */
+ if (rect->line_width) {
+ if (rect->relief != RELIEF_FLAT) {
+ if (aligned) {
+ DrawRectangleRelief(wi, rect->relief, rect->gradient,
+ &r, rect->line_width);
+ }
+ else {
+ RadarPoint p[5];
+ for (i = 0; i < 4; i++) {
+ p[4-i].x = rect->dev[i].x;
+ p[4-i].y = rect->dev[i].y;
+ }
+ p[0] = p[4];
+ DrawPolygonRelief(wi, rect->relief, rect->gradient,
+ p, 5, rect->line_width);
+ }
+ }
+ else {
+ SetLineStyle(wi->dpy, wi->gc, rect->line_style);
+ gc_mask = GCFillStyle|GCLineWidth|GCForeground|GCJoinStyle;
+ values.foreground = RadarPixel(rect->line_color);
+ values.line_width = (rect->line_width == 1) ? 0 : rect->line_width;
+ values.join_style = JoinMiter;
+ if (!aligned) {
+ gc_mask |= GCCapStyle;
+ values.cap_style = CapProjecting;
+ }
+ if (rect->line_pattern == RadarUnspecifiedPattern) {
+ values.fill_style = FillSolid;
+ XChangeGC(wi->dpy, wi->gc, gc_mask, &values);
+ }
+ else {
+ values.fill_style = FillStippled;
+ values.stipple = rect->line_pattern;
+ gc_mask |= GCStipple;
+ XChangeGC(wi->dpy, wi->gc, gc_mask, &values);
+ }
+ if (aligned) {
+ XDrawRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y,
+ r.width, r.height);
+ }
+ else {
+ XDrawLines(wi->dpy, wi->draw_buffer, wi->gc, xp, 5, CoordModeOrigin);
+ }
+ }
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * IsSensitive --
+ *
+ **********************************************************************************
+ */
+static RadarBool
+IsSensitive(Item item,
+ int item_part)
+{
+ return (ISSET(item->flags, SENSITIVE_BIT) &&
+ item->parent->class->IsSensitive(item->parent, RADAR_NO_PART));
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Pick --
+ *
+ **********************************************************************************
+ */
+static double
+Pick(Item item,
+ RadarPoint *p,
+ Item start_item,
+ int aperture,
+ Item *a_item,
+ int *part)
+{
+ RectangleItem rect = (RectangleItem) item;
+ double best_dist;
+
+ best_dist = PolygonToPointDist(rect->dev, 4, p);
+
+ if (ISSET(rect->flags, FILLED_BIT)) {
+ if (best_dist <= 0.0) {
+ return 0.0;
+ }
+ }
+ best_dist = ABS(best_dist);
+
+ if (rect->line_width > 1) {
+ double dist;
+ int i;
+ RadarPoint pts[5];
+
+ for (i = 0; i < 4; i++) {
+ pts[i] = rect->dev[i];
+ }
+ pts[4] = pts[0];
+ dist = PolylineToPointDist(pts, 5, rect->line_width,
+ CapProjecting, JoinMiter, p);
+ if (dist <= 0.0) {
+ return 0.0;
+ }
+ best_dist = MIN(dist, best_dist);
+ }
+
+ return best_dist;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * PostScript --
+ *
+ **********************************************************************************
+ */
+static void
+PostScript(Item item,
+ PostScriptInfo ps_info)
+{
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * GetClipVertices --
+ * Get the clipping shape.
+ *
+ **********************************************************************************
+ */
+static RadarBool
+GetClipVertices(Item item,
+ RadarPoint **points,
+ int *num_points)
+{
+ RectangleItem rect = (RectangleItem) item;
+ double delta;
+ RadarBool aligned;
+
+ delta = rect->dev[0].y - rect->dev[1].y;
+ delta = ABS(delta);
+ aligned = delta < PRECISION_LIMIT;
+ delta = rect->dev[0].x - rect->dev[1].x;
+ delta = ABS(delta);
+ aligned |= delta < PRECISION_LIMIT;
+
+ if (aligned) {
+ RadarListAssertSize(item->wi->work_pts, 2);
+ *points = (RadarPoint *) RadarListArray(item->wi->work_pts);
+ *num_points = 2;
+
+ if (rect->dev[0].x < rect->dev[2].x) {
+ (*points)[0].x = rect->dev[0].x;
+ (*points)[1].x = rect->dev[2].x+1.0;
+ }
+ else {
+ (*points)[0].x = rect->dev[2].x;
+ (*points)[1].x = rect->dev[0].x+1.0;
+ }
+ if (rect->dev[0].y < rect->dev[2].y) {
+ (*points)[0].y = rect->dev[0].y;
+ (*points)[1].y = rect->dev[2].y+1.0;
+ }
+ else {
+ (*points)[0].y = rect->dev[2].y;
+ (*points)[1].y = rect->dev[0].y+1.0;
+ }
+ }
+ else {
+ *points = rect->dev;
+ *num_points = 4;
+ }
+
+ return aligned;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Coords --
+ * Return or edit the item vertices.
+ *
+ **********************************************************************************
+ */
+static int
+Coords(Item item,
+ int index,
+ int cmd,
+ RadarPoint **pts,
+ int *num_pts)
+{
+ RectangleItem rect = (RectangleItem) item;
+
+ if ((cmd == COORDS_ADD) || (cmd == COORDS_ADD_LAST) || (cmd == COORDS_REMOVE)) {
+ Tcl_AppendResult(item->wi->interp,
+ " rectangles can't add or remove vertices", NULL);
+ return RADAR_ERROR;
+ }
+ else if (cmd == COORDS_REPLACE_ALL) {
+ if (*num_pts != 2) {
+ Tcl_AppendResult(item->wi->interp,
+ " coords command need 2 points on rectangles", NULL);
+ return RADAR_ERROR;
+ }
+ rect->coords[0] = (*pts)[0];
+ rect->coords[1] = (*pts)[1];
+ ITEM.Invalidate(item, RADAR_COORDS_FLAG);
+ }
+ else if (cmd == COORDS_REPLACE) {
+ if (*num_pts < 1) {
+ Tcl_AppendResult(item->wi->interp,
+ " coords command need at least 1 point", NULL);
+ return RADAR_ERROR;
+ }
+ if (index < 0) {
+ index += 2;
+ }
+ if ((index < 0) || (index > 1)) {
+ range_err:
+ Tcl_AppendResult(item->wi->interp,
+ " incorrect coord index, should be between -2 and 1", NULL);
+ return RADAR_ERROR;
+ }
+ rect->coords[index] = (*pts)[0];
+ ITEM.Invalidate(item, RADAR_COORDS_FLAG);
+ }
+ else if (cmd == COORDS_READ_ALL) {
+ *num_pts = 2;
+ *pts = rect->coords;
+ }
+ else if (cmd == COORDS_READ) {
+ if (index < 0) {
+ index += 2;
+ }
+ if ((index < 0) || (index > 1)) {
+ goto range_err;
+ }
+ *num_pts = 1;
+ *pts = &rect->coords[index];
+ }
+
+ return RADAR_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Exported functions struct --
+ *
+ **********************************************************************************
+ */
+static ItemClassStruct RECTANGLE_ITEM_CLASS = {
+ sizeof(RectangleItemStruct),
+ False,
+ False,
+ False,
+ "rectangle",
+ rect_attrs,
+ Init,
+ Clone,
+ Destroy,
+ Configure,
+ Query,
+ NULL,
+ NULL,
+ GetClipVertices,
+ Coords,
+ ComputeCoordinates,
+ ToArea,
+ Draw,
+ IsSensitive,
+ Pick,
+ PostScript
+};
+
+RadarItemClassId RadarRectangle = (RadarItemClassId) &RECTANGLE_ITEM_CLASS;