diff --git a/commands/CmdRS.c b/commands/CmdRS.c index 7bdb5b0f..370380d9 100644 --- a/commands/CmdRS.c +++ b/commands/CmdRS.c @@ -633,12 +633,72 @@ cmdSelectArea(layers, less, option) TTMaskClearType(&mask, i); } } - if (option == SEL_INTERSECT) - SelectIntersect(&scx, &mask, crec->dbw_bitmask); else SelectArea(&scx, &mask, crec->dbw_bitmask); } +/* + * ---------------------------------------------------------------------------- + * + * cmdIntersectArea -- + * + * This is a utility procedure used by CmdSelect to do area + * selection itersect. + * + * Results: + * None. + * + * Side effects: + * The selection is pared down to contain only the part of the + * original selection that intersects with the type "layer". + * + * ---------------------------------------------------------------------------- + */ + +void +cmdIntersectArea(layer) + char *layer; /* The layer to intersect with */ +{ + TileType ttype; + SearchContext scx; + int windowMask, xMask; + DBWclientRec *crec; + MagWindow *window; + + bzero(&scx, sizeof(SearchContext)); + window = ToolGetBoxWindow(&scx.scx_area, &windowMask); + if (window == NULL) + { + TxPrintf("The box isn't in a window.\n"); + return; + } + + /* Since the box may actually be in multiple windows, we have to + * be a bit careful. If the box is only in one window, then there's + * no problem. If it's in more than window, the cursor must + * disambiguate the windows. + */ + + xMask = ((DBWclientRec *) window->w_clientData)->dbw_bitmask; + if ((windowMask & ~xMask) != 0) + { + window = CmdGetRootPoint((Point *) NULL, (Rect *) NULL); + xMask = ((DBWclientRec *) window->w_clientData)->dbw_bitmask; + if ((windowMask & xMask) == 0) + { + TxPrintf("The box is in more than one window; use the cursor\n"); + TxPrintf("to select the one you want to select from.\n"); + return; + } + } + + scx.scx_use = (CellUse *) window->w_surfaceID; + scx.scx_trans = GeoIdentityTransform; + crec = (DBWclientRec *) window->w_clientData; + ttype = DBTechNoisyNameType(layer); + SelectIntersect(&scx, ttype, crec->dbw_bitmask); +} + /* * ---------------------------------------------------------------------------- * @@ -935,10 +995,7 @@ CmdSelect(w, cmd) case SEL_INTERSECT: if (cmd->tx_argc > 3) goto usageError; - if (!(more || less)) SelectClear(); - if (cmd->tx_argc == 3) - cmdSelectArea(optionArgs[1], less, option); - else cmdSelectArea("*,label,subcell", less, option); + cmdIntersectArea(optionArgs[1]); return; /*-------------------------------------------------------------------- diff --git a/commands/CmdTZ.c b/commands/CmdTZ.c index aa0b378e..26b8fb50 100644 --- a/commands/CmdTZ.c +++ b/commands/CmdTZ.c @@ -1040,12 +1040,13 @@ CmdWhat(w, cmd) { Tcl_ListObjAppendElement(magicinterp, paintobj, Tcl_NewStringObj(DBTypeLongName(i), -1)); - Tcl_ListObjAppendElement(magicinterp, paintobj, - paintcellobj); for (lidp = lid; lidp; lidp = lidp->lid_next) Tcl_ListObjAppendElement(magicinterp, paintcellobj, Tcl_NewStringObj(lidp->lid_name, -1)); + + Tcl_ListObjAppendElement(magicinterp, paintobj, + paintcellobj); } while (lid != NULL) diff --git a/select/selCreate.c b/select/selCreate.c index 7968dc61..ebb92793 100644 --- a/select/selCreate.c +++ b/select/selCreate.c @@ -253,37 +253,6 @@ selClearFunc(scx) else return 2; } -/* Structure used by selIntersectPaintFunc() */ - -struct selIntersectData { - Rect *sid_rect; - TileType sid_type; -}; - -/* - * ---------------------------------------------------------------------------- - * - * selDupPaintFunc -- - * - * Copy paint from tile area in Select2Def into SelectDef as all types - * in rMask. - * - * ---------------------------------------------------------------------------- - */ - -int -selDupPaintFunc(tile, rMask) - Tile *tile; /* The tile to get the area to copy paint. */ - TileTypeBitMask *rMask; /* Paint types to copy to. */ -{ - Rect r; - - TiToRect(tile, &r); - DBPaintMask(SelectDef, &r, rMask); - - return 0; /* Keep the search going. */ -} - /* * ---------------------------------------------------------------------------- * @@ -293,18 +262,15 @@ selDupPaintFunc(tile, rMask) */ int -selIntersectPaintFunc2(tile, sid) +selIntersectPaintFunc2(tile, rect) Tile *tile; /* The tile to copy paint from. */ - struct selIntersectData *sid; + Rect *rect; /* Area to clip to */ { Rect r; - int p; TiToRect(tile, &r); - GEOCLIP(&r, sid->sid_rect); /* Clip out the intersection area */ - - DBPaint(Select2Def, &r, sid->sid_type); /* Paint back into Select2Def */ - + GEOCLIP(&r, rect); /* Clip out the intersection area */ + DBPaint(SelectDef, &r, TiGetTypeExact(tile)); /* Paint back into SelectDef */ return 0; /* Keep the search going. */ } @@ -319,26 +285,21 @@ selIntersectPaintFunc2(tile, sid) */ int -selIntersectPaintFunc(tile, type) +selIntersectPaintFunc(tile) Tile *tile; /* The tile to copy paint from. */ - TileType type; /* The type of tile to keep */ { TileTypeBitMask tMask; Rect r; - int plane; - struct selIntersectData sid; + int pNum; TiToRect(tile, &r); - TTMaskSetOnlyType(&tMask, type); - plane = DBPlane(type); - - sid.sid_type = TiGetTypeExact(tile); - sid.sid_rect = &r; - - DBSrPaintArea((Tile *)NULL, Select2Def->cd_planes[plane], &r, - &tMask, selIntersectPaintFunc2, (ClientData)&sid); - + for (pNum = 0; pNum < DBNumPlanes; pNum++) + { + DBSrPaintArea((Tile *)NULL, Select2Def->cd_planes[pNum], &r, + &DBAllButSpaceAndDRCBits, selIntersectPaintFunc2, + (ClientData)&r); + } return 0; /* Keep the search going. */ } @@ -363,15 +324,15 @@ selIntersectPaintFunc(tile, type) */ void -SelectIntersect(scx, types, xMask) +SelectIntersect(scx, type, xMask) SearchContext *scx; /* Describes the area in which material * is to be selected. The resulting * coordinates should map to the coordinates * of EditRootDef. The cell use should be * the root of a window. */ - TileTypeBitMask *types; /* Indicates which intersecting layers to - * select. May not include labels or cells. + TileType type; /* Indicates which layer to intersect with + * the current selection. */ int xMask; /* Indicates window (or windows) where cells * must be expanded for their contents to be @@ -382,67 +343,36 @@ SelectIntersect(scx, types, xMask) TileTypeBitMask tMask, rMask; TileType s, t; int plane; + SearchContext scx2; - /* If the source definition is changing, clear the old selection. */ - - if (SelectRootDef != scx->scx_use->cu_def) - { - if (SelectRootDef != NULL) - SelectClear(); - SelectRootDef = scx->scx_use->cu_def; - SelSetDisplay(SelectUse, SelectRootDef); - } + /* The source definition may not change */ + if (SelectRootDef != scx->scx_use->cu_def) return; SelRememberForUndo(TRUE, (CellDef *) NULL, (Rect *) NULL); - /* Select all paint of types in "types" mask and copy into Select2Def */ - + /* Copy SelectDef contents (paint only) into Select2Def */ DBCellClearDef(Select2Def); - (void) DBCellCopyAllPaint(scx, types, xMask, Select2Use); + scx2.scx_use = SelectUse; + scx2.scx_area = SelectUse->cu_bbox; + GeoTransTrans(&GeoIdentityTransform, &SelectUse->cu_transform, &scx2.scx_trans); + DBCellCopyAllPaint(&scx2, &DBAllButSpaceAndDRCBits, CU_DESCEND_NO_LOCK, + Select2Use); - /* Find the first type in the list. This will be used as the reference */ + /* Clear the original selection */ + DBCellClearDef(SelectDef); - for (t = 0; t < DBNumUserLayers; t++) - if (TTMaskHasType(types, t)) - break; - - if (t == DBNumUserLayers) return; - - /* Compute the type mask of the reference type */ - TTMaskSetOnlyType(&tMask, t); + /* Select all paint of type "type" and copy into SelectDef */ + TTMaskSetOnlyType(&tMask, type); plane = DBPlane(t); + (void) DBCellCopyAllPaint(scx, &tMask, xMask, SelectUse); - /* For each other type in "types", do the following */ + /* Scan Select2Def for all geometry inside the area of "type", and */ + /* copy back to SelectDef as "type" */ - for (s = t + 1; s < DBNumUserLayers; s++) - { - if (TTMaskHasType(types, s)) - { - /* Copy the reference paint type from Select2Def into SelectDef */ - DBSrPaintArea((Tile *)NULL, Select2Def->cd_planes[plane], &scx->scx_area, - &tMask, selDupPaintFunc, (ClientData)&tMask); + DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[plane], + &scx->scx_area, &tMask, selIntersectPaintFunc, (ClientData)NULL); - /* Erase the reference paint type from Select2Def */ - DBEraseMask(Select2Def, &TiPlaneRect, &tMask); - - /* Scan Select2Def for all geometry of type s inside the areas of */ - /* the reference type, and copy back to Select2Def as the reference */ - /* type */ - DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[plane], - &scx->scx_area, &tMask, selIntersectPaintFunc, (ClientData)s); - - /* Erase the reference paint type from SelectDef */ - DBEraseMask(SelectDef, &TiPlaneRect, &tMask); - } - } - - /* Copy any remaining paint in the reference layer in Select2Def to */ - /* SelectDef as all the intersection types. */ - - DBSrPaintArea((Tile *)NULL, Select2Def->cd_planes[plane], &scx->scx_area, - &tMask, selDupPaintFunc, (ClientData)types); - - SelectDef->cd_types = *types; /* Remember what types were requested */ + DBEraseMask(SelectDef, &TiPlaneRect, &tMask); /* Display the new selection. */