PWPinsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet, June 4, 1985 11:27:01 am PDT
Last Edited by: Serlet, July 6, 1985 12:32:54 pm PDT
Last Edited by: Monier, June 6, 1985 0:05:34 am PDT
PWPinsImpl:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDCells, CDDirectory, CDImports, CDOrient, CDPinObjects, CDProperties, Convert, Rope
EXPORTS PWPins =
BEGIN
OPEN PWPins;
GetSide:
PUBLIC
PROC [ob:
CD.ObPtr, pin:
CD.ApplicationPtr]
RETURNS [isOnBorder:
BOOL, side: Side] = {
LargerSide:
PROC [hSide, vSide: Side]
RETURNS [side: Side] = {
side ← IF pinRect.x2-pinRect.x1>pinRect.y2-pinRect.y1 THEN hSide ELSE vSide;
};
rect: CD.Rect ← CD.InterestRect[ob]; -- the border
pinRect: CD.Rect ← CDOrient.RectAt[pin.location, pin.ob.size, pin.orientation]; -- bbox of the pin
isOnBorder ← TRUE;
SELECT
TRUE
FROM
rect.y2 = pinRect.y2 AND rect.x1 = pinRect.x1 => side ← LargerSide[top, left];
rect.y2 = pinRect.y2 AND rect.x2 = pinRect.x2 => side ← LargerSide[top, right];
rect.y1 = pinRect.y1 AND rect.x1 = pinRect.x1 => side ← LargerSide[bottom, left];
rect.y1 = pinRect.y1 AND rect.x2 = pinRect.x2 => side ← LargerSide[bottom, right];
rect.y2 = pinRect.y2 => side ← top;
rect.y1 = pinRect.y1 => side ← bottom;
rect.x1 = pinRect.x1 => side ← left;
rect.x2 = pinRect.x2 => side ← right;
ENDCASE => isOnBorder ← FALSE;
};
FilterProc: TYPE = PROC [subRect: CD.Rect] RETURNS [isSubInteresting: BOOL ← TRUE];
DefaultFilter: FilterProc = {};
Because we must finally get applications, this one has in its parameters all necessary information for reconstructing the application.
EnumerateDeepPinsInContext:
PRIVATE
PROC [ob:
CD.ObPtr, location:
CD.Position ← [0, 0], orientation:
CD.Orientation ← 0, properties:
CD.Properties ←
NIL, eachPin: AppEnumerator, stopEnumerateDeepPins:
BOOL, filter: FilterProc]
RETURNS [quit:
BOOL ←
FALSE] = {
IF ~filter[CDOrient.MapRect[
itemInCell: CD.InterestRect[ob],
cellSize: ob.size,
cellInstOrient: orientation,
cellInstPos: location]] THEN RETURN;
SELECT
TRUE
FROM
CDPinObjects.IsPinOb[ob] => {
quit ← eachPin[NEW[CD.Application ← [ob: ob, location: location, orientation: orientation, properties: CDProperties.CopyProps[properties]]]];
};
CDCells.IsCell[ob] => {
cellPtr: CD.CellPtr ← NARROW[ob.specificRef];
FOR list:
CD.ApplicationList ← cellPtr.contents, list.rest
WHILE (list#
NIL
AND ~quit)
DO
IF ~stopEnumerateDeepPins
OR CDProperties.GetPropFromApplication[list.first, $StopEnumerateDeepPins]=
NIL
THEN
quit ← EnumerateDeepPinsInContext[
list.first.ob,
CDBasics.BaseOfRect[
CDOrient.MapRect[
itemInCell:
CDOrient.RectAt[list.first.location, list.first.ob.size, list.first.orientation],
cellSize: ob.size,
cellInstOrient: orientation,
cellInstPos: location]],
CDOrient.ComposeOrient[list.first.orientation, orientation],
list.first.properties,
eachPin, stopEnumerateDeepPins, filter];
IF quit THEN EXIT;
ENDLOOP;
};
CDImports.IsImport[ob] => {
HACKK until imports handle pins reasonably
ip: CDImports.ReferencePtr ← NARROW[ob.specificRef];
IF ip.boundApp=NIL THEN RETURN;
quit ← EnumerateDeepPinsInContext[ip.boundApp.ob, location, orientation, NIL, eachPin, stopEnumerateDeepPins, filter];
};
ENDCASE => {
newOb: CD.ObPtr ← CDDirectory.Expand[ob, NIL, NIL];
quit ← newOb#NIL AND EnumerateDeepPinsInContext[newOb, location, orientation, NIL, eachPin, stopEnumerateDeepPins, filter];
};
};
EnumerateDeepPins:
PUBLIC PROC [ob:
CD.ObPtr, eachPin: AppEnumerator, stopEnumerateDeepPins:
BOOL ←
TRUE]
RETURNS [quit:
BOOL] = {
quit ← EnumerateDeepPinsInContext[ob: ob, eachPin: eachPin, stopEnumerateDeepPins: stopEnumerateDeepPins, filter: DefaultFilter];
};
EnumerateEdgePins:
PUBLIC
PROC [ob:
CD.ObPtr, eachPin: AppEnumerator, stopEnumerateDeepPins:
BOOL ←
TRUE]
RETURNS [quit:
BOOL] = {
iRectShrank: CD.Rect ← CDBasics.Extend[CD.InterestRect[ob], -1];
EdgeFilter: FilterProc = {isSubInteresting ← ~CDBasics.Inside[subRect, iRectShrank]};
EachPinFilter: AppEnumerator
-- [app: CD.ApplicationPtr] RETURNS [quit: BOOL ← FALSE] -- = {
IF GetSide[ob, app].isOnBorder THEN quit ← eachPin[app];
};
quit ← EnumerateDeepPinsInContext[ob: ob, eachPin: EachPinFilter, stopEnumerateDeepPins: stopEnumerateDeepPins, filter: EdgeFilter];
};
RenamePins:
PUBLIC
PROC [design:
CD.Design, ob:
CD.ObPtr, renameProc: RenameProc ← DefaultRenameProc, stopEnumerateDeepPins:
BOOL ←
TRUE]
RETURNS [cell:
CD.ObPtr] =
BEGIN
cellPtr: CD.CellPtr;
KeepPinOnEdge: AppEnumerator
-- [app: CD.ApplicationPtr] RETURNS [quit: BOOL ← FALSE] -- = {
newApp: CD.ApplicationPtr;
newRope: ROPE ← renameProc[CDPinObjects.GetName[app]];
IF Rope.IsEmpty[newRope] THEN RETURN;
newApp ←
NEW[
CD.Application ← [
ob: CDPinObjects.CreatePinOb[app.ob.size],
location: app.location, orientation: app.orientation,
properties: CDProperties.CopyProps[app.properties]]];
CDPinObjects.SetName[newApp, newRope];
cellPtr.contents ← CONS[newApp, cellPtr.contents];
};
app: CD.ApplicationPtr ← NEW[CD.Application ← [ob: ob]];
IF stopEnumerateDeepPins THEN CDProperties.PutPropOnApplication[app, $StopEnumerateDeepPins, $StopEnumerateDeepPins];
cell ← CDCells.CreateEmptyCell[]; cellPtr ← NARROW[cell.specificRef];
[] ← EnumerateEdgePins[ob, KeepPinOnEdge];
cellPtr.contents ← CONS[app, cellPtr.contents];
CDCells.SetInterestRect[cell, CD.InterestRect[ob]];
[] ← CDCells.RepositionCell[cell, NIL];
[] ← CDDirectory.Include[design, cell, "RenamedPins"];
END;
DefaultRenameProc: PUBLIC RenameProc = {newRope ← oldRope};
Useful in many RenameProcs for indexing names. e.g. Index["foo", 4]="foo[4]"
Index:
PUBLIC PROC [rope:
ROPE, index:
INT]
RETURNS [indexedRope:
ROPE] = {
indexedRope ← Rope.Cat[rope, "[", Convert.RopeFromInt[index], "]"];
};
[] ← CDProperties.RegisterProperty[$StopEnumerateDeepPins, $CDPinExtras];
CDProperties.FetchProcs[$StopEnumerateDeepPins].makeCopy ← CDProperties.CopyVal;
END.