/* NMshowpoint.c - * * This file provides procedures that use the highlight layer * to display information about particular points. Currently, * this is used to highlight selected terminals in nets. * * ********************************************************************* * * Copyright (C) 1985, 1990 Regents of the University of California. * * * Permission to use, copy, modify, and distribute this * * * software and its documentation for any purpose and without * * * fee is hereby granted, provided that the above copyright * * * notice appear in all copies. The University of California * * * makes no representations about the suitability of this * * * software for any purpose. It is provided "as is" without * * * express or implied warranty. Export of this software outside * * * of the United States of America may require an export license. * * ********************************************************************* */ #ifndef lint static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/netmenu/NMshowpt.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "windows/windows.h" #include "graphics/graphics.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "utils/main.h" #include "utils/malloc.h" /* The net highlight information consists of an array of points. * Around each point, this file redisplays a box with a hollow * center. Each box is displayed on the screen either MAXLAMBDAS * across, or MAXPIXELS across, whichever is less. This means * that a) the boxes don't get too large at large view magnifications, * and b) when erasing a box, we have an upper limit on how much area * (in lambda coordinates) will have to be redisplayed. */ static Point * nmspPoints = NULL; /* Pointer to array of points. */ static int nmspArraySize = 0; /* Size of array. */ static int nmspArrayUsed = 0; /* Number of entries actually used. */ #define MAXLAMBDAS 30 #define MAXPIXELS 14 #define THICKNESS 3 /* * ---------------------------------------------------------------------------- * * NMRedrawPoints -- * * This procedure is called by the highlight package to redisplay * our highlights. A lock has already been made on the window by the * highlight code. * * Results: * None. * * Side effects: * Information gets redisplayed on the screen. * * ---------------------------------------------------------------------------- */ int NMRedrawPoints(window, plane) MagWindow *window; /* Window in which to redisplay. */ Plane *plane; /* Non-space tiles on this plane indicate * the areas where highlights must be redrawn. */ { int i; Rect dbArea, screen; extern int nmspAlways1(); /* Forward reference. */ /* Make sure that we have something to display, and that the * root definition for this window is the edit's root definition. */ if (nmspArrayUsed == 0) return 0; if (((CellUse *)(window->w_surfaceID))->cu_def != EditRootDef) return 0; for (i = 0; i < nmspArrayUsed; i += 1) { /* Make a rectangle around the point that is either MAXLAMBAS * across in database coordinates or MAXPIXELS across in screen * coordinates, whichever is smaller. */ dbArea.r_xbot = nmspPoints[i].p_x - MAXLAMBDAS/2; dbArea.r_ybot = nmspPoints[i].p_y - MAXLAMBDAS/2; dbArea.r_xtop = dbArea.r_xbot + MAXLAMBDAS; dbArea.r_ytop = dbArea.r_ybot + MAXLAMBDAS; if (!DBSrPaintArea((Tile *) NULL, plane, &dbArea, &DBAllButSpaceBits, nmspAlways1, (ClientData) NULL)) continue; WindSurfaceToScreen(window, &dbArea, &screen); if (((screen.r_xtop - screen.r_xbot) > MAXPIXELS) || ((screen.r_ytop - screen.r_ybot) > MAXPIXELS)) { dbArea.r_ur = dbArea.r_ll = nmspPoints[i]; WindSurfaceToScreen(window, &dbArea, &screen); screen.r_xbot -= MAXPIXELS/2; screen.r_xtop += MAXPIXELS/2; screen.r_ybot -= MAXPIXELS/2; screen.r_ytop += MAXPIXELS/2; } /* If the rectangle is less than 2*THICKNESS across, draw it * solid. Otherwise, draw it with a hollow center (i.e. as * four boxes). */ if (((screen.r_xtop - screen.r_xbot) < 2*THICKNESS) || ((screen.r_ytop - screen.r_ybot) < 2*THICKNESS)) { GrClipBox(&screen, STYLE_SOLIDHIGHLIGHTS); } else { Rect screen2; screen2 = screen; screen2.r_ytop = screen2.r_ybot + THICKNESS - 1; GrClipBox(&screen2, STYLE_SOLIDHIGHLIGHTS); screen2.r_ytop = screen.r_ytop; screen2.r_ybot = screen2.r_ytop - THICKNESS + 1; GrClipBox(&screen2, STYLE_SOLIDHIGHLIGHTS); screen2.r_ybot = screen.r_ybot + THICKNESS - 1; screen2.r_xtop = screen2.r_xbot + THICKNESS - 1; GrClipBox(&screen2, STYLE_SOLIDHIGHLIGHTS); screen2.r_xtop = screen.r_xtop; screen2.r_xbot = screen2.r_xtop - THICKNESS + 1; GrClipBox(&screen2, STYLE_SOLIDHIGHLIGHTS); } } return 0; } int nmspAlways1() { return 1; } /* * ---------------------------------------------------------------------------- * * NMAddPoint -- * * This procedure adds a point to the list of those being * highlighted. * * Results: * None. * * Side effects: * The point is added to our internal list of those to be * highlighted. It will also be displayed on the screen * after the next call to WindUpdate. * * ---------------------------------------------------------------------------- */ void NMAddPoint(point) Point *point; /* Point to be highlighted, in coordinates * of EditRootDef. */ { int i; Point *newArray; Rect area; /* Make sure this point isn't already on the list. */ for (i = 0; i < nmspArrayUsed; i += 1) { if ((nmspPoints[i].p_x == point->p_x) && (nmspPoints[i].p_y == point->p_y)) return; } /* Make sure there's enough space in the array. Make it * bigger if necessary. */ if (nmspArrayUsed == nmspArraySize) { nmspArraySize *= 2; if (nmspArraySize < 10) nmspArraySize = 10; newArray = (Point *) mallocMagic((unsigned)nmspArraySize*sizeof(Point)); for (i = 0; i < nmspArrayUsed; i += 1) newArray[i] = nmspPoints[i]; if (nmspPoints != NULL) freeMagic((char *) nmspPoints); nmspPoints = newArray; } /* Add in the new point at the end of the array. */ nmspPoints[nmspArrayUsed] = *point; nmspArrayUsed += 1; /* Remember the area to be redisplayed. */ area.r_xbot = point->p_x - MAXLAMBDAS/2; area.r_xtop = point->p_x + MAXLAMBDAS/2; area.r_ybot = point->p_y - MAXLAMBDAS/2; area.r_ytop = point->p_y + MAXLAMBDAS/2; DBWHLRedraw(EditRootDef, &area, FALSE); } /* * ---------------------------------------------------------------------------- * * NMDeletePoint -- * * This procedure removes a point from the list of those * being highlighted. * * Results: * None. * * Side effects: * The highlight information is removed from our internal list. * The screen will not be updated until the next WindUpdate * call. * * ---------------------------------------------------------------------------- */ void NMDeletePoint(point) Point *point; /* Point to be un-highlighted, in coords * of EditRootDef. */ { int i; Rect area; /* Remove from list (smash list down to cover hole. */ for (i = 0; i < nmspArrayUsed; i += 1) { if ((nmspPoints[i].p_x != point->p_x) || (nmspPoints[i].p_y != point->p_y)) continue; for (i += 1; i < nmspArrayUsed; i += 1) nmspPoints[i-1] = nmspPoints[i]; nmspArrayUsed -= 1; break; } /* Redisplay on screen. */ area.r_xbot = point->p_x - MAXLAMBDAS/2; area.r_xtop = area.r_xbot + MAXLAMBDAS; area.r_ybot = point->p_y - MAXLAMBDAS/2; area.r_ytop = area.r_ybot + MAXLAMBDAS; DBWHLRedraw(EditRootDef, &area, TRUE); } /* * ---------------------------------------------------------------------------- * * NMClearPoints -- * * This procedure clears the list of points being highlighted. * * Results: * None. * * Side effects: * All points are removed from the list. The screen won't be * updated until the next call to WindUpdate. * * ---------------------------------------------------------------------------- */ void NMClearPoints() { int i; Rect area; for (i = 0; i < nmspArrayUsed; i += 1) { area.r_xbot = nmspPoints[i].p_x - MAXLAMBDAS/2; area.r_xtop = area.r_xbot + MAXLAMBDAS; area.r_ybot = nmspPoints[i].p_y - MAXLAMBDAS/2; area.r_ytop = area.r_ybot + MAXLAMBDAS; DBWHLRedraw(EditRootDef, &area, TRUE); } nmspArrayUsed = 0; }