diff --git a/VERSION b/VERSION index 25f64810..7e9025c1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.288 +8.3.289 diff --git a/commands/CmdCD.c b/commands/CmdCD.c index f873e43b..85ce06fe 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -2238,11 +2238,13 @@ CmdContact(w, cmd) MagWindow *w; TxCommand *cmd; { - TileType type, rtype; + TileType type, rtype, ctype; TileTypeBitMask *rmask, smask; CCStruct ccs; Rect area; + LinkedRect *lr = NULL; int cmdContactFunc(); /* Forward declaration */ + int cmdContactEraseFunc(); /* Forward declaration */ windCheckOnlyWindow(&w, DBWclientID); if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID)) @@ -2251,13 +2253,78 @@ CmdContact(w, cmd) return; } - if (cmd->tx_argc != 2) + if ((cmd->tx_argc != 2) && (cmd->tx_argc != 3)) { TxError("Usage: %s \n", cmd->tx_argv[0]); return; } if (!ToolGetEditBox(&area)) return; + if (EditCellUse == NULL) + { + TxError("The cell in the window is not editable.\n"); + return; + } + + if (cmd->tx_argc == 3) + { + if (!strcmp(cmd->tx_argv[1], "erase")) + { + /* Erase a contact from the area of the box. This acts */ + /* differently from the "erase" command. "erase" will */ + /* remove the contact and leave nothing behind. "contact */ + /* erase" will remove the contact and leave the residues */ + /* behind. The main difference is that this action cannot */ + /* be done on a whole area; the individual contacts need */ + /* to be enumerated and the erase/paint done on each one. */ + + type = DBTechNoisyNameType(cmd->tx_argv[2]); + + if (!DBIsContact(type)) + { + TxError("Error: tile type \"%s\" is not a contact.\n", + cmd->tx_argv[2]); + return; + } + TTMaskSetOnlyType(&smask, type); + + /* Add all stacked contact types containing "type" */ + for (ctype = DBNumUserLayers; ctype < DBNumTypes; ctype++) + { + rmask = DBResidueMask(ctype); + if (TTMaskHasType(rmask, ctype)) + TTMaskSetMask(&smask, rmask); + } + + /* Enumerate all tiles inside the box area containing contact "type" */ + DBSrPaintArea((Tile *) NULL, EditCellUse->cu_def->cd_planes[DBPlane(type)], + &area, &smask, cmdContactEraseFunc, (ClientData)&lr); + + rmask = DBResidueMask(type); + + while (lr != NULL) + { + GeoClip(&lr->r_r, &area); + + /* Erase contact type "type" and repaint with the residues */ + DBErase(EditCellUse->cu_def, &lr->r_r, type); + for (rtype = 0; rtype < DBNumUserLayers; rtype++) + if (TTMaskHasType(rmask, rtype)) + DBPaint(EditCellUse->cu_def, &lr->r_r, rtype); + + freeMagic(lr); + lr = lr->r_next; + } + + /* Refresh the layout drawing */ + DBWAreaChanged(EditCellUse->cu_def, &area, DBW_ALLWINDOWS, &smask); + DRCCheckThis (EditCellUse->cu_def, TT_CHECKPAINT, &area); + } + else + TxError("Usage: %s erase \n", cmd->tx_argv[0]); + return; + } + type = DBTechNoisyNameType(cmd->tx_argv[1]); if (type >= 0) { @@ -2345,6 +2412,27 @@ cmdContactFunc2(tile, ccs) return 0; } +/* For each contact tile found, attach the area to a LinkedRect structure + */ + +int +cmdContactEraseFunc(tile, lr) + Tile *tile; + LinkedRect **lr; +{ + LinkedRect *newlr; + Rect area; + + newlr = (LinkedRect *)mallocMagic(sizeof(LinkedRect)); + + newlr->r_type = TiGetType(tile); + TiToRect(tile, &newlr->r_r); + newlr->r_next = *lr; + *lr = newlr; + + return 0; +} + /* * ---------------------------------------------------------------------------- * diff --git a/doc/html/contact.html b/doc/html/contact.html index 96e47faa..7d3ca7f9 100644 --- a/doc/html/contact.html +++ b/doc/html/contact.html @@ -25,7 +25,7 @@ Paint a contact at the intersection of two layers.

Usage:

- contact type

+ contact [erase] type

Summary:

@@ -33,20 +33,24 @@ Paint a contact at the intersection of two layers. The contact command computes the intersection area (inside the cursor box) of the two (or more) residue types that make up the contact type type, and paints the contact type type on top of the - area of intersection. + area of intersection.

+ + Option contact erase erases contacts from the area of the cursor + box without affecting the metal layers (or stacked contacts) surrounding + the contact being erased. (Note that the erase command will + remove both the contact type and the surrounding metal layers.) +

Implementation Notes:

contact is implemented as a built-in layout command in magic. - As of magic version 7.3.115 this command does not correctly translate the - cursor box for edit cells and may paint outside of the cursor box, with - random results.

See Also:

paint
+ erase

diff --git a/doc/html/erase.html b/doc/html/erase.html index df0af7f6..32a9c2a2 100644 --- a/doc/html/erase.html +++ b/doc/html/erase.html @@ -60,7 +60,12 @@ Erase paint from the layout inside the bounds of the cursor box. The option "erase cursor" picks the layers at the position of the (X11) cursor and erases these from the area of the cursor - box. + box.

+ + Note that when applied to contact types, "erase" will erase + the entire contact, including the top and bottom metal types + comprising the contact. To remove the contact cuts without affecting + the surrounding material, use the "contact erase" command.

Implementation Notes:

@@ -71,6 +76,7 @@ Erase paint from the layout inside the bounds of the cursor box.

See Also:

paint
+ contact