From a776aef900eca7ec13d72e84e59294f37277d727 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Thu, 13 Jan 2000 09:45:59 +0000 Subject: 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. --- generic/Rectangle.c | 832 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 832 insertions(+) create mode 100644 generic/Rectangle.c (limited to 'generic') 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 + +#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; -- cgit v1.1