DIRECTORY CD USING [CreateDrawRef, Design, DrawProc, DrawRectProc, DrawRef, shadeLayer, Instance, InstanceList, Layer, Orientation, original, Position, Rect], CDBasics USING [BaseOfRect, Extend, SizeOfRect, ToRect, universe], CDDirectory USING [Name], CDInstances USING [NewInst], CDOps USING [LayerName], CDOrient USING [ComposeOrient, DecomposeOrient, DeMapRect, MapRect, RectAt], CDProperties USING [GetProp], CDRects USING [CreateBareRect], CDViewer USING [ViewerList, ViewersOf], CDViewHighlight USING [ShowInstance], CStitching, PropertyLists USING [GetProp], RefTab USING [EachPairAction, Pairs], Rope USING [Cat], SX, SXAccessInternal, SXAtoms USING [SignalName, spinifex], SXHighlightNode, SXQuadTree USING [Dimension, Enumerate, PerRectProc], TerminalIO USING [WriteRope]; SXHighlightNodeImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDDirectory, CDInstances, CDOps, CDOrient, CDProperties, CDRects, CDViewer, CDViewHighlight, CStitching, PropertyLists, RefTab, Rope, SX, SXAccessInternal, SXAtoms, SXQuadTree, TerminalIO EXPORTS SXHighlightNode = BEGIN RemoveHighlightNode: PUBLIC PROC [design: CD.Design] = BEGIN vl: CDViewer.ViewerList _ CDViewer.ViewersOf[design]; FOR list: CDViewer.ViewerList _ vl, list.rest WHILE list#NIL DO CDViewHighlight.ShowInstance [list.first, NIL, TRUE, $SX]; ENDLOOP; END; -- RemoveHighlightNode IncludeHighLight: PROC [design: CD.Design, rect: CD.Rect] = BEGIN vl: CDViewer.ViewerList _ CDViewer.ViewersOf[design]; app: CD.Instance = CDInstances.NewInst [ ob: CDRects.CreateBareRect [CDBasics.SizeOfRect[rect], CD.shadeLayer], location: CDBasics.BaseOfRect [rect]]; FOR list: CDViewer.ViewerList _ vl, list.rest WHILE list#NIL DO CDViewHighlight.ShowInstance [list.first, app, FALSE, $SX]; ENDLOOP; END; -- IncludeHighLight HighlightNode: PUBLIC PROC [design: CD.Design, pos: CD.Position, lev: CD.Layer] = BEGIN WITH CDProperties.GetProp[design.technology, SXAtoms.spinifex] SELECT FROM tpOK: REF SX.TechHandle => { FOR mapList: LIST OF SX.MapRec _ tpOK.cdLayerMapping[lev], mapList.rest WHILE mapList#NIL DO IF mapList.first.value = NIL THEN { rootCir: REF SX.Circuit = SXAccessInternal.GetLogicalCell[design.actual.first.dummyCell.ob].circuit; data: REF SearchData _ NEW [SearchData _ [layer: lev, nodeLayer: mapList.first.spinifexLayer, tech: tpOK, rootCir: rootCir, cir: rootCir]]; GoForIt [data, design, pos]; RETURN }; REPEAT FINISHED => { TerminalIO.WriteRope [Rope.Cat[" ", CDOps.LayerName[lev], " is not conducting\n"]]; RETURN } ENDLOOP; }; ENDCASE => TerminalIO.WriteRope ["technology does not support Spinifex\n"]; END; -- HighlightNode GoForIt: PROC [sd: REF SearchData, design: CD.Design, pos: CD.Position] = BEGIN AddSplodge: CStitching.TileProc = BEGIN rect: CD.Rect = CDOrient.MapRect [tile.Area, sd.rootSize, sd.rootOrient, sd.rootPos]; IncludeHighLight [design, rect]; END; dr: CD.DrawRef = CD.CreateDrawRef [[]]; nodeGeom: CStitching.Tesselation; RemoveHighlightNode [design]; dr.drawChild _ CompensateDummyCell; -- Used for outermost cell only, dr.drawChild set to SearchChild for recursive calls inside CompensateDummyCell. dr.drawRect _ 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.interestClip _ CDBasics.Extend [CDBasics.ToRect[pos, pos], 1]; design.actual.first.dummyCell.ob.class.drawMe[design.actual.first.dummyCell, [0,0], CD.original, dr]; IF sd.node = NIL THEN { TerminalIO.WriteRope [Rope.Cat[ " Failed to find geometry on layer \"", CDOps.LayerName[sd.layer], "\" at indicated point.\n"]]; RETURN }; [sd.node, sd.applChain] _ sd.rootCir.FindRootNode[sd.node, sd.applChain]; WITH PropertyLists.GetProp [sd.node.properties, SXAtoms.SignalName] SELECT FROM sig: REF SX.SignalName => { TerminalIO.WriteRope [Rope.Cat [" Highlighting: ", sig.name,".\n"]] }; ENDCASE => { TerminalIO.WriteRope [" Highlighting node.\n"] }; IF sd.applChain#NIL THEN -- Node appeared on some subcircuit, rather than root. sd.cir _ SXAccessInternal.GetLogicalCell[sd.applChain.first.ob].circuit ELSE sd.cir _ sd.rootCir; nodeGeom _ CStitching.NewTesselation []; Paint [sd, nodeGeom]; [] _ nodeGeom.EnumerateArea [CDBasics.universe, AddSplodge]; END; -- GoForIt SearchData: TYPE = RECORD [layer: CD.Layer, nodeLayer: SX.SpinifexLayerIndex, tech: REF SX.TechHandle, rootCir: REF SX.Circuit, -- Highest Spinifex SX.Circuit found in application chain. cir: REF SX.Circuit, node: REF SX.CircuitNode _ NIL, applChain: LIST OF CD.Instance _ NIL, pushSize: CD.Position _ [0,0], pushPos: CD.Position _ [0,0], pushOrient: CD.Orientation _ CD.original, rootSize: CD.Position _ [0,0], rootPos: CD.Position _ [0,0], rootOrient: CD.Orientation _ CD.original]; CompensateDummyCell: CD.DrawProc = BEGIN data: REF SearchData = NARROW [pr.devicePrivate]; oldClip: CD.Rect = pr.interestClip; pr.drawChild _ SearchChild; pr.interestClip _ CDOrient.DeMapRect[itemInWorld: oldClip, cellSize: data.pushSize, cellInstOrient: data.pushOrient, cellInstPos: data.pushPos]; pos _ CDBasics.BaseOfRect [CDOrient.DeMapRect [ CDOrient.RectAt [pos: pos, size: inst.ob.size, orient: orient], data.pushSize, data.pushOrient, data.pushPos]]; orient _ CDOrient.DecomposeOrient [orient, data.pushOrient]; SearchChild [inst, pos, orient, pr]; pr.interestClip _ oldClip; pr.drawChild _ CompensateDummyCell END; -- CompensateDummyCell SearchChild: CD.DrawProc = BEGIN sx: REF SX.LogicalCell = SXAccessInternal.GetLogicalCell[inst.ob]; IF sx#NIL AND sx.circuit#NIL AND sx.analysisState=useCircuit THEN { subcircuit: REF SX.Circuit _ sx.circuit; data: REF SearchData = NARROW [pr.devicePrivate]; oldClip: CD.Rect = pr.interestClip; cir: REF SX.Circuit = data.cir; root: REF SX.Circuit = data.rootCir; appl: CD.Instance; oldChain: LIST OF CD.Instance = data.applChain; data.cir _ subcircuit; IF data.rootCir = NIL THEN { data.rootCir _ subcircuit; data.rootSize _ inst.ob.size; data.rootPos _ CDBasics.BaseOfRect [CDOrient.MapRect [ CDOrient.RectAt [pos: pos, size: data.rootSize, orient: orient], data.pushSize, data.pushOrient, data.pushPos]]; data.rootOrient _ CDOrient.ComposeOrient [orient, data.pushOrient] }; pr.interestClip _ CDOrient.DeMapRect [ itemInWorld: oldClip, cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos]; IF cir # NIL THEN { FOR aList: CD.InstanceList _ cir.subcircuits, aList.rest WHILE aList # NIL DO appl _ aList.first; IF appl.location=pos AND appl.orientation=orient AND appl.ob=inst.ob THEN EXIT; REPEAT FINISHED => {ERROR}; ENDLOOP; data.applChain _ CONS [appl, data.applChain]; }; inst.ob.class.drawMe [inst, [0,0], CD.original, pr]; IF cir # NIL THEN data.cir _ cir; IF pr.stopFlag^ = FALSE THEN {data.applChain _ oldChain; data.rootCir _ root}; pr.interestClip _ oldClip } ELSE { data: REF SearchData = NARROW [pr.devicePrivate]; sx: REF SX.LogicalCell = SXAccessInternal.GetLogicalCell [inst.ob]; IF sx#NIL AND sx.analysisState=notYetDone AND data.cir#NIL THEN { TerminalIO.WriteRope [Rope.Cat[" ", CDDirectory.Name[inst.ob], " has not been extracted\n"]]; ERROR ABORTED }; inst.ob.class.drawMe [inst, pos, orient, pr] } END; -- SearchChild CheckRect: CD.DrawRectProc = BEGIN IF l = NARROW[pr.devicePrivate, REF SearchData].layer THEN { SearchNode: SXQuadTree.PerRectProc = BEGIN WITH r.nodeInformation SELECT FROM n: REF SX.CircuitNode => sData.node _ n; -- XXX FIX HERE, pr.stopFlag should be set only if node is found. ENDCASE; pr.stopFlag^ _ TRUE END; -- SearchNode sData: REF SearchData = NARROW [pr.devicePrivate]; IF sData.cir = NIL THEN { TerminalIO.WriteRope [" design has not been analyzed.\n"]; ERROR ABORTED }; SXQuadTree.Enumerate [quadTree: sData.cir.spinifexLayers[sData.nodeLayer], clipRect: pr.interestClip, PerRect: SearchNode] } END; -- CheckRect Paint: PROC [data: REF SearchData, protoPaint: CStitching.Tesselation] = BEGIN Compose: PROC [pos: CD.Position, orient: CD.Orientation, size: CD.Position, applChain: LIST OF CD.Instance] RETURNS [combPos: CD.Position, combOrient: CD.Orientation] = BEGIN IF applChain.rest # NIL THEN { [pos, orient] _ Compose [pos, orient, applChain.rest.first.ob.size, applChain.rest]; combPos _ CDBasics.BaseOfRect [CDOrient.MapRect [ CDOrient.RectAt [applChain.first.location, applChain.first.ob.size, applChain.first.orientation], applChain.rest.first.ob.size, orient, pos]]; combOrient _ CDOrient.ComposeOrient [applChain.first.orientation, orient] } ELSE { combPos _ CDBasics.BaseOfRect [CDOrient.MapRect [ 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] } END; -- Compose PerCell: PROC [circuit: REF SX.Circuit, node: REF SX.CircuitNode, pos: CD.Position, orient: CD.Orientation, size: CD.Position] = BEGIN PaintNode: SXQuadTree.PerRectProc = BEGIN IF r.nodeInformation=data THEN { newR: CD.Rect = CDOrient.MapRect [ itemInCell: SXQuadTree.Dimension [r], cellSize: size, cellInstOrient: orient, cellInstPos: pos]; protoPaint.ChangeRect [newR, SXAtoms.spinifex] } END; -- PaintNode SearchForPortConnection: RefTab.EachPairAction = BEGIN FOR ml: SX.MergeRecList _ NARROW[val], ml.rest WHILE ml # NIL DO IF ml.first.becomes = node THEN { applChain: LIST OF CD.Instance = ml.first.applChain; subCircuit: REF SX.Circuit = SXAccessInternal.GetLogicalCell[applChain.first.ob].circuit; subnode: REF SX.CircuitNode = NARROW [key]; subPos: CD.Position; subOrient: CD.Orientation; [subPos, subOrient] _ Compose [pos, orient, size, applChain]; PerCell [subCircuit, subnode, subPos, subOrient, applChain.first.ob.size]; } ENDLOOP; RETURN [FALSE] END; -- SearchForPortConnection FOR layer: SX.SpinifexLayerIndex IN [0..data.tech.numSpinifexLayers) DO SXQuadTree.Enumerate [quadTree: circuit.spinifexLayers[layer], clipRect: CDBasics.universe, PerRect: PaintNode, data: node] ENDLOOP; IF circuit.mergeDirectory#NIL THEN [] _ circuit.mergeDirectory.Pairs [SearchForPortConnection] END; -- PerCell pos: CD.Position _ [0,0]; orient: CD.Orientation _ CD.original; ac: LIST OF CD.Instance = data.applChain; -- list of cells down to the node. 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; -- Paint END. "SXHighlightNodeImpl.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Written by: Mark Shand, August 8, 1984 11:39:46 am PDT Last Edited by: Shand, September 3, 1984 5:51:16 am PDT Last Edited by: Jacobi, July 25, 1985 3:22:38 pm PDT Last edited by: gbb June 6, 1986 2:41:28 pm PDT OK if NIL! [tile: TilePtr, data: REF ANY] find the node we wish to highlight. find the highest layer node to which the node we wish to highlight is merged. find all rectangles connected to the high-layer node. add rectangles to the currently pushed ChipNDale cell which cover all the rectangles in the highlighted node. PROC [aptr: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: REF CD.DrawInformation] For outermost cell transforms must be precompensated for transform compositions which occur in DrawMe. In subcells such precompensation is not required. Now really start searching. PROC [aptr: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: REF CD.DrawInformation] This object is a logical subcircuit. PROC[r: Rect, l: Layer, pr: DrawRef] PROC[r: REF Rectangle, data: REF ANY] PROC [r: REF Rectangle, data: REF ANY] PROC[key: RefTab.Key, val: RefTab.Val] RETURNS [quit: BOOLEAN] Edited on March 4, 1985 4:23:17 pm PST, by Jacobi removing errors reprogrammed, without using drawprocs Edited on March 5, 1985 8:59:52 am PST, by Jacobi made readable Edited on April 8, 1985 2:51:21 pm PST, by Jacobi use of SXAccessInternal instead of properties; SpinifexCellPredicate removed Edited on May 6, 1985 11:26:55 am PDT, by Beretta Converted to ChipNDale CD20 Edited on July 25, 1985 3:20:45 pm PDT, by Jacobi Use of CDViewHighlight instead of changing the design I don't like the loop over all viewers, but I don't want to change the interface and can't know which is the right viewer... ส ห˜code™Kšœ ฯmœ7™BK™6K™7K™4K™/—šฯk ˜ KšžœŒ˜”Jšœ žœ4˜BJšœ žœ˜Kšœ žœ ˜Kšœžœ ˜Jšœ žœ>˜LKšœ žœ ˜Jšœžœ˜Jšœ žœ˜'Jšœ%˜%Jšœ ˜ Kšœžœ ˜Jšœžœ˜&Jšœžœ˜Jšœ˜J˜Jšœžœ˜%Jšœ˜Kšœ žœ%˜5Jšœ žœ ˜—code2šะlnœžœž˜"Iunitšžœžœ’žœ3˜ัMšžœž˜—š ฯnœžœžœ žœ ž˜