SpinifexHighlightNodeImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Written by: Mark Shand, August 8, 1984 11:39:46 am PDT
Last Edited by: Shand, August 13, 1984 2:00:42 am PDT
DIRECTORY
TerminalIO USING [WriteRope],
CD USING [highLightShade, LevelKey, Design, DesignPosition, ApplicationList, ApplicationPtr, Level, DrawProc, NewNullDeviceDrawRef, DrawRef, DrawRectProc, original, Rect, Orientation],
CDOps USING [IncludeApplication],
CDApplications USING [NewApplicationI],
CDRects USING [CreateBareRect],
CDProperties USING [GetProp, GetPropFromObject],
CDInline USING [Extend, ToRect, SizeOfRect, BaseOfRect, universe],
CDOrient USING [DeMapRect, MapRect, ComposeOrient, DecomposeOrient, MapPosition, RectAt],
CDDirectory USING [Name],
Atom USING [GetPName, GetPropFromList],
Rope USING [Cat],
RefTab USING [Pairs, EachPairAction],
Process USING [Abort, GetCurrent],
SpinifexCircuit USING [Circuit, CircuitNode, TechHandle, MapRec, SpinifexLayerIndex, FindRootNode, EnumerateGeometry, Dimension, PerRectProc, MergeRecList, SignalName],
SpinifexAtoms USING [spinifex, SignalName],
SpinifexCellPredicates USING [IsLogicalCell],
CornerStitching USING [Tesselation, NewTesselation, ChangeRect, EnumerateArea, PerTileProc, Area],
SpinifexHighlightNode
;
SpinifexHighlightNodeImpl: CEDAR PROGRAM
IMPORTS TerminalIO, CD, CDOps, CDApplications, CDRects, CDProperties, CDInline, CDOrient, CDDirectory, Atom, Rope, RefTab, Process, SpinifexCircuit, SpinifexAtoms, SpinifexCellPredicates, CornerStitching
EXPORTS SpinifexHighlightNode
~ BEGIN
Circuit: TYPE ~ SpinifexCircuit.Circuit;
HighlightNode: PUBLIC PROCEDURE [design: CD.Design, pos: CD.DesignPosition, lev: CD.Level] ~ {
techProp: REF ANY;
-- Check that this technology can be analyzed.
IF design.technology = NIL THEN
TerminalIO.WriteRope[" Design does not specify a technology.\n"]
ELSE IF (techProp ← CDProperties.GetProp[from~design.technology, prop~SpinifexAtoms.spinifex]) = NIL THEN
TerminalIO.WriteRope[ Rope.Cat[ " \"", design.technology.name, "\" technology lacks analysis capability.\n"]]
ELSE WITH techProp SELECT FROM
tpOK: REF SpinifexCircuit.TechHandle => {
FOR mapList: LIST OF SpinifexCircuit.MapRec ← tpOK.cdLayerMapping[lev], mapList.rest WHILE mapList # NIL DO
IF mapList.first.value = NIL THEN {
rootCir: REF Circuit ~ NARROW[CDProperties.GetPropFromObject[ from~design.actual.first.dummyCell.ob, prop~SpinifexAtoms.spinifex]]; -- OK if NIL!
data: REF SearchData ← NEW[SearchData ← [level~ lev, nodeLayer~ mapList.first.spinifexLayer, tech~ tpOK, rootCir~ rootCir, cir~ rootCir]];
GoForIt[data, design, pos];
RETURN
};
REPEAT FINISHED => {
TerminalIO.WriteRope[ Rope.Cat[ " \"", Atom.GetPName[CD.LevelKey[lev]], "\" is not a conducting layer.\n"]];
RETURN
}
ENDLOOP;
};
ENDCASE => TerminalIO.WriteRope[ Rope.Cat[ " \"", design.technology.name, "\" technology capability is invalid.\n"]];
TRUSTED { Process.Abort[Process.GetCurrent[]] }
};
GoForIt: PROCEDURE [sd: REF SearchData, design: CD.Design, pos: CD.DesignPosition] ~ {
AddSplodge: CornerStitching.PerTileProc -- [tile: TilePtr, data: REF ANY] -- ~ {
PaintRect: CD.Rect ~ CDOrient.MapRect[tile.Area, sd.rootSize, sd.rootOrient, sd.rootPos];
CDOps.IncludeApplication[design, CDApplications.NewApplicationI[ob~ CDRects.CreateBareRect[CDInline.SizeOfRect[PaintRect], CD.highLightShade], location~ CDInline.BaseOfRect[PaintRect], orientation~ CD.original]];
};
dr: CD.DrawRef ~ CD.NewNullDeviceDrawRef[design];
nodeGeom: REF CornerStitching.Tesselation;
dr.drawChild ← CompensateDummyCell;
dr.drawRect ← dr.saveRect ← CheckRect;
dr.devicePrivate ← sd;
IF design.actual.first.mightReplace # NIL THEN {
sd.rootSize ← sd.pushSize ← design.actual.first.mightReplace.ob.size;
sd.rootPos ← sd.pushPos ← design.actual.first.mightReplace.location;
sd.rootOrient ← sd.pushOrient ← design.actual.first.mightReplace.orientation
};
dr.worldClip ← CDInline.Extend[CDInline.ToRect[pos, pos], 1];
design.actual.first.dummyCell.ob.p.drawMe[design.actual.first.dummyCell, [0,0], CD.original, dr];
IF sd.node = NIL THEN {
TerminalIO.WriteRope[ Rope.Cat[ " Failed to find geometry on level: \"", Atom.GetPName[CD.LevelKey[sd.level]], "\" at indicated point.\n"]];
RETURN
};
[sd.node, sd.applChain] ← sd.rootCir.FindRootNode[sd.node, sd.applChain];
WITH sd.node.properties.GetPropFromList[ SpinifexAtoms.SignalName] SELECT FROM
sig: REF SpinifexCircuit.SignalName => {
TerminalIO.WriteRope[Rope.Cat[" Highlighting: ", sig.name,".\n"]]
};
ENDCASE => {
TerminalIO.WriteRope[" Highlighting node.\n"]
};
IF sd.applChain # NIL THEN
sd.cir ← NARROW[CDProperties.GetPropFromObject[ from~sd.applChain.first.ob, prop~SpinifexAtoms.spinifex]]
ELSE
sd.cir ← sd.rootCir;
nodeGeom ← CornerStitching.NewTesselation[];
Paint[sd, nodeGeom];
[] ← nodeGeom.EnumerateArea[CDInline.universe, AddSplodge];
};
SearchData: TYPE ~ RECORD [
level: CD.Level,
nodeLayer: SpinifexCircuit.SpinifexLayerIndex,
tech: REF SpinifexCircuit.TechHandle,
rootCir: REF Circuit,
cir: REF Circuit,
node: REF SpinifexCircuit.CircuitNode ← NIL,
applChain: LIST OF CD.ApplicationPtr ← NIL,
pushSize: CD.DesignPosition ← [0,0],
pushPos: CD.DesignPosition ← [0,0],
pushOrient: CD.Orientation ← CD.original,
rootSize: CD.DesignPosition ← [0,0],
rootPos: CD.DesignPosition ← [0,0],
rootOrient: CD.Orientation ← CD.original
];
CompensateDummyCell: CD.DrawProc -- [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: REF CD.DrawInformation] -- ~ {
data: REF SearchData ~ NARROW[pr.devicePrivate];
oldClip: CD.Rect ~ pr.worldClip;
pr.drawChild ← SearchChild;
pr.worldClip ← CDOrient.DeMapRect[itemInWorld~ oldClip, cellSize~ data.pushSize, cellInstOrient~ data.pushOrient, cellInstPos~ data.pushPos];
pos ← CDInline.BaseOfRect[CDOrient.DeMapRect[CDOrient.RectAt[pos~ pos, size~ aptr.ob.size, orient~ orient], data.pushSize, data.pushOrient, data.pushPos]];
orient ← CDOrient.DecomposeOrient[orient, data.pushOrient];
SearchChild[aptr, pos, orient, pr];
pr.worldClip ← oldClip;
pr.drawChild ← CompensateDummyCell
};
SearchChild: CD.DrawProc -- [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: REF CD.DrawInformation] -- ~ {
WITH CDProperties.GetPropFromObject[ from~aptr.ob, prop~SpinifexAtoms.spinifex] SELECT FROM
subcircuit: REF Circuit => {
This object is a logical subcircuit.
data: REF SearchData ~ NARROW[pr.devicePrivate];
oldClip: CD.Rect ~ pr.worldClip;
cir: REF Circuit ~ data.cir;
root: REF Circuit ~ data.rootCir;
appl: CD.ApplicationPtr;
oldChain: LIST OF CD.ApplicationPtr ~ data.applChain;
data.cir ← subcircuit;
IF data.rootCir = NIL THEN {
data.rootCir ← subcircuit;
data.rootSize ← aptr.ob.size;
data.rootPos ← CDOrient.MapPosition[CDOrient.RectAt[ pos~ pos, size~ data.rootSize, orient~ orient], data.pushSize, data.pushOrient, data.pushPos];
data.rootOrient ← CDOrient.ComposeOrient[orient, data.pushOrient]
};
pr.worldClip ← CDOrient.DeMapRect[itemInWorld~ oldClip, cellSize~ aptr.ob.size, cellInstOrient~ orient, cellInstPos~ pos];
IF cir # NIL THEN {
FOR aList: CD.ApplicationList ← cir.subcircuits, aList.rest WHILE aList # NIL DO
appl ← aList.first;
IF appl.location = pos AND appl.orientation = orient AND appl.ob = aptr.ob THEN EXIT;
REPEAT FINISHED => {
ERROR
};
ENDLOOP;
data.applChain ← CONS[appl, data.applChain];
};
aptr.ob.p.drawMe[aptr, [0,0], CD.original, pr];
IF cir # NIL THEN data.cir ← cir;
IF pr.stopFlag^ = FALSE THEN {
data.applChain ← oldChain;
data.rootCir ← root
};
pr.worldClip ← oldClip
};
ENDCASE => {
data: REF SearchData ~ NARROW[pr.devicePrivate];
IF SpinifexCellPredicates.IsLogicalCell[aptr.ob] AND data.cir # NIL THEN {
TerminalIO.WriteRope[Rope.Cat[ " Cell \"", CDDirectory.Name[aptr.ob], "\" has not been extracted.\n"]];
TRUSTED { Process.Abort[Process.GetCurrent[]] }
};
aptr.ob.p.drawMe[aptr, pos, orient, pr]
}
};
CheckRect: CD.DrawRectProc -- [r: DesignRect, l: Level, pr: DrawRef] -- ~ {
IF l = NARROW[pr.devicePrivate, REF SearchData].level THEN {
SearchNode: SpinifexCircuit.PerRectProc -- [r: REF Rectangle, data: REF ANY] -- ~ {
WITH r.nodeInformation SELECT FROM
n: REF SpinifexCircuit.CircuitNode => sData.node ← n;
ENDCASE;
pr.stopFlag^ ← TRUE
};
sData: REF SearchData ~ NARROW[pr.devicePrivate];
IF sData.cir = NIL THEN {
TerminalIO.WriteRope[" Design has not been analyzed.\n"];
TRUSTED { Process.Abort[Process.GetCurrent[]] }
};
sData.cir.EnumerateGeometry[sData.nodeLayer, pr.worldClip, SearchNode, NIL]
}
};
Paint: PROCEDURE [data: REF SearchData, protoPaint: REF CornerStitching.Tesselation] ~ {
Compose: PROCEDURE [pos: CD.DesignPosition, orient: CD.Orientation, size: CD.DesignPosition, applChain: LIST OF CD.ApplicationPtr] RETURNS [combPos: CD.DesignPosition, combOrient: CD.Orientation] ~ {
IF applChain.rest # NIL THEN {
[pos, orient] ← Compose[pos, orient, applChain.rest.first.ob.size, applChain.rest];
combPos ← CDOrient.MapPosition[CDOrient.RectAt[ pos~ applChain.first.location, size~ applChain.first.ob.size, orient~ applChain.first.orientation], applChain.rest.first.ob.size, orient, pos];
combOrient ← CDOrient.ComposeOrient[applChain.first.orientation, orient]
}
ELSE {
combPos ← CDOrient.MapPosition[CDOrient.RectAt[ pos~ applChain.first.location, size~ applChain.first.ob.size, orient~ applChain.first.orientation], size, orient, pos];
combOrient ← CDOrient.ComposeOrient[applChain.first.orientation, orient]
}
};
PerCell: PROCEDURE [circuit: REF Circuit, node: REF SpinifexCircuit.CircuitNode, pos: CD.DesignPosition, orient: CD.Orientation, size: CD.DesignPosition] ~ {
PaintNode: SpinifexCircuit.PerRectProc -- [r: REF Rectangle, data: REF ANY] -- ~ {
IF r.nodeInformation = data THEN {
newR: CD.Rect ~ CDOrient.MapRect[ itemInCell~ r.Dimension, cellSize~ size, cellInstOrient~ orient, cellInstPos~ pos];
protoPaint.ChangeRect[newR, SpinifexAtoms.spinifex]
}
};
SearchForPortConnection: RefTab.EachPairAction -- [key: RefTab.Key, val: RefTab.Val] RETURNS [quit: BOOLEAN] -- ~ {
FOR ml: SpinifexCircuit.MergeRecList ← NARROW[val], ml.rest WHILE ml # NIL DO
IF ml.first.becomes = node THEN {
applChain: LIST OF CD.ApplicationPtr ~ ml.first.applChain;
subCircuit: REF Circuit ~ NARROW[CDProperties.GetPropFromObject[ from~ applChain.first.ob, prop~ SpinifexAtoms.spinifex]];
subnode: REF SpinifexCircuit.CircuitNode ~ NARROW[key];
subPos: CD.DesignPosition;
subOrient: CD.Orientation;
[subPos, subOrient] ← Compose[pos, orient, size, applChain];
PerCell[ subCircuit, subnode, subPos, subOrient, applChain.first.ob.size];
}
ENDLOOP;
RETURN [FALSE]
};
FOR layer: SpinifexCircuit.SpinifexLayerIndex IN [0..data.tech.numSpinifexLayers) DO
circuit.EnumerateGeometry[layer, CDInline.universe, PaintNode, node]
ENDLOOP;
IF circuit.mergeDirectory # NIL THEN
[] ← circuit.mergeDirectory.Pairs[SearchForPortConnection]
};
pos: CD.DesignPosition ← [0,0];
orient: CD.Orientation ← CD.original;
ac: LIST OF CD.ApplicationPtr ~ data.applChain;
IF ac # NIL THEN
[pos, orient] ← Compose[pos, orient, [0,0], ac];
PerCell[ data.cir, data.node, pos, orient, IF ac = NIL THEN [0,0] ELSE ac.first.ob.size]
};
END.