DIRECTORY CD, CDInstances, CDCells, CDCellsBackdoor, CDDirectory, CDBasics, CDBasicsInline, CDIO, CDOps, CDProperties, CDRects, Process USING [Yield, Detach], PropertyLists, Real, RefTab, Rope, TerminalIO, TokenIO; CDCellsImpl: CEDAR MONITOR IMPORTS CD, CDCells, CDInstances, CDIO, CDDirectory, CDBasics, CDBasicsInline, CDOps, CDProperties, CDRects, Process, PropertyLists, Real, RefTab, Rope, TerminalIO, TokenIO EXPORTS CDCells, CDCellsBackdoor SHARES CD, CDRects, CDDirectory = BEGIN cellClass: PUBLIC CD.ObjectClass = CD.RegisterObjectClass[$Cell, [ drawMe: DrawMeForCells, quickDrawMe: QuickDrawMeForCells, showMeSelected: DrawCellSelection, internalRead: ReadCell, internalWrite: WriteCell, describe: Describe, interestRect: InterestRectCells ]]; pCellClass: PUBLIC CD.ObjectClass = cellClass; Init: PROC [] = { dp: REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[cellClass, [ enumerateChildObjects: EnumerateChildObjects, name: Name, directoryOp: DirectoryOp, another: Another, replaceDirectChilds: ReplaceDirectChildForCell ]]; [] _ CDProperties.RegisterProperty[$InsideRect]; CDProperties.InstallProcs[prop: $InsideRect, procs: CDProperties.PropertyProcsRec[ makeCopy: CDProperties.DontCopy, internalWrite: NIL, internalRead: InternalReadProperty, exclusive: TRUE ] ]; }; IsDummyCell: PUBLIC PROC [cell: CD.Object] RETURNS [BOOL_FALSE] = { WITH cell.specific SELECT FROM cp: CD.CellSpecific => RETURN [cp.dummyCell]; ENDCASE => NULL; }; InternalReadProperty: PROC [h: TokenIO.Handle, prop: ATOM] RETURNS [val: REF] = { val _ NEW[CD.Rect _ CDIO.ReadRect[h]] }; InterestRectCells: PROC [ob: CD.Object] RETURNS [CD.Rect] = { RETURN [NARROW[ob.specific, CD.CellSpecific].ir] }; DirectoryOp: PROC [me: CD.Object, design: CD.Design, name: Rope.ROPE, function: CDDirectory.DirectoryFunction] RETURNS [proceed: BOOL_TRUE] = { IF function#remove THEN NARROW[me.specific, CD.CellSpecific].name _ name }; Name: PROC [me: CD.Object] RETURNS [Rope.ROPE] = { RETURN [NARROW[me.specific, CD.CellSpecific].name] }; EnumerateChildObjects: PROC [me: CD.Object, p: CDDirectory.EnumerateObjectsProc, x: REF] = { cp: CD.CellSpecific _ NARROW[me.specific]; FOR list: CD.InstanceList _ cp.contents, list.rest WHILE list#NIL DO p[list.first.ob, x] ENDLOOP; IF cp.sequence#NIL THEN FOR n: NAT IN [0..cp.sequence.length) DO p[cp.sequence[n].ob, x] ENDLOOP; }; Another: PROC [me: CD.Object, fromOrNil: CD.Design, into: CD.Design, friendly: BOOL] RETURNS [ new: CD.Object _ CreateEmptyCell[], topMode: CDDirectory.InclOrReady _ ready, childMode: CDDirectory.ImmOrIncl _ immutable] = { oldCp: CD.CellSpecific _ NARROW[me.specific]; newCp: CD.CellSpecific _ NARROW[new.specific]; new.bbox _ me.bbox; newCp^ _ oldCp^; newCp.dummyCell _ FALSE; [newCp.contents, newCp.sequence] _ CopyInsts[oldCp.contents, oldCp.sequence]; CDProperties.AppendProps[winner: new.properties, looser: me.properties, putOnto: new]; IF fromOrNil=into AND into#NIL THEN childMode _ included }; CopyInsts: PUBLIC PROC [list: CD.InstanceList, seq: CD.InstanceSequence, inPlace: BOOL_FALSE] RETURNS [lCopy: CD.InstanceList_NIL, sCopy: CD.InstanceSequence] = { maxSSize: NAT = 10000; i: CD.Instance; from, to: INT _ 0; oldSLeng: INT _ IF seq=NIL THEN 0 ELSE MIN[seq.length, seq.size]; newSLeng: INT _ MIN[maxSSize, CDInstances.Length[list]+oldSLeng]; sCopy _ NEW[CD.InstanceSequenceRep[newSLeng]]; DO IF from0 THEN { pr.drawOutLine[CDBasics.MapRect[cp.ir, trans], CD.outlineLayer,pr]; IF pr.scaleHint*(inst.ob.bbox.y2-inst.ob.bbox.y1)>9 THEN pr.drawComment[CDBasics.MapRect[cp.ir, trans], cp.name, pr]; } ELSE { mapClip: CD.Rect _ CDBasicsInline.DeMapRect[pr.interestClip, trans]; --clipping boundary in cell coordinates IF pr.borders AND cp.drawBorder THEN pr.drawOutLine[CDBasicsInline.MapRect[cp.ir, trans], CD.outlineLayer, pr]; FOR w: CD.InstanceList _ cp.contents, w.rest WHILE w#NIL DO IF CDBasicsInline.IntersectRI[mapClip, w.first] THEN { IF pr.stopFlag^ THEN RETURN; w.first.ob.class.quickDrawMe[w.first, CDBasics.ComposeTransform[w.first.trans, trans], pr]; } ENDLOOP; IF cp.sequence#NIL THEN FOR n: NAT IN [0..cp.sequence.length) DO IF CDBasicsInline.IntersectRI[mapClip, cp.sequence[n]] THEN { IF pr.stopFlag^ THEN RETURN; IF cp.sequence[n].ob.class=CDRects.bareRectClass THEN pr.drawRect[CDBasicsInline.MapRect[cp.sequence[n].ob.bbox, CDBasicsInline.ComposeTransform[cp.sequence[n].trans, trans]], cp.sequence[n].ob.layer, pr] ELSE cp.sequence[n].ob.class.quickDrawMe[cp.sequence[n], CDBasicsInline.ComposeTransform[cp.sequence[n].trans, trans], pr]; } ENDLOOP; Yield[]; IF pr.checkPriority THEN pr.priorityChecker[pr]; } }; DrawCellSelection: PROC [inst: CD.Instance, trans: CD.Transformation, pr: CD.DrawRef] = { cp: CD.CellSpecific ~ NARROW[inst.ob.specific]; IF pr.scaleHint0 THEN pr.drawRect[CDBasicsInline.MapRect[cp.ir, trans], CD.shadeLayer, pr] ELSE pr.drawOutLine[CDBasicsInline.MapRect[cp.ir, trans], CD.selectionLayer, pr] }; CreateEmptyCell: PUBLIC PROC [] RETURNS [ob: CD.Object] = { ob _ NEW[CD.ObjectRep_[ class: cellClass, bbox: [0, 0, 1, 1], specific: NEW[CD.CellRep_[simplifyOn: -1]] ]]; }; CreateCell: PUBLIC PROC [il: CD.InstanceList_NIL, sq: CD.InstanceSequence_NIL, ir: CD.Rect_[0,0,-1,-1]] RETURNS [CD.Object] = { ob: CD.Object = CreateEmptyCell[]; cp: CD.CellSpecific = NARROW[ob.specific]; cp.contents _ il; cp.sequence _ sq; SetInterestRect[NIL, ob, ir, dontResize]; [] _ ResizeCell[NIL, ob]; SetSimplificationTreshhold[ob, -1]; RETURN [ob] }; CreateCellXTransformed: PUBLIC PROC [il: CD.InstanceList_NIL, sq: CD.InstanceSequence_NIL, ir: CD.Rect_[0,0,-1,-1], cTrans: CD.Transformation_[]] RETURNS [ob: CD.Object] = { [il, sq] _ CopyInsts[il, sq, FALSE]; FOR l: CD.InstanceList _ il, l.rest WHILE l#NIL DO l.first.trans _ CDBasics.DecomposeTransform[l.first.trans, cTrans]; ENDLOOP; IF sq#NIL THEN FOR n: NAT IN [0..sq.length) DO sq[n].trans _ CDBasics.DecomposeTransform[sq[n].trans, cTrans]; ENDLOOP; RETURN [ CreateCell[il, sq, CDBasics.DeMapRect[ir, cTrans]]]; }; ReadCell: CD.InternalReadProc = { i: INT; ob: CD.Object = CreateEmptyCell[]; specific: CD.CellSpecific = NARROW[ob.specific]; IF h.oldVersion AND CDIO.VersionKey[h]<=15 THEN { ReadCell23[ob, h]; RETURN [ob] }; specific.ir _ CDIO.ReadRect[h]; specific.simplifyOn _ TokenIO.ReadInt[h]; i _ TokenIO.ReadInt[h]; specific.specifiedIr _ (i MOD 2)#0; specific.drawBorder _ (i/2)#0; [specific.sequence, specific.contents] _ ReadInstances[h]; [] _ ResizeCell[NIL, ob]; IF ob.bbox.y2>ob.bbox.y1 THEN specific.simplifyOn _ specific.simplifyOn/(ob.bbox.y2-ob.bbox.y1); RETURN [ob]; }; ReadInstances: PUBLIC PROC [h: TokenIO.Handle] RETURNS [seq: CD.InstanceSequence, list: CD.InstanceList_NIL] = { maxSSize: NAT = 10000; num: INT = TokenIO.ReadInt[h]; newSLeng: INT _ MIN[maxSSize, num]; natNewSLeng: NAT _ newSLeng; seq _ NEW[CD.InstanceSequenceRep[natNewSLeng]]; FOR n: NAT IN [0..natNewSLeng) DO seq[n] _ CDIO.ReadInstance[h]; ENDLOOP; seq.length _ natNewSLeng; THROUGH [natNewSLeng..num) DO list _ CONS[CDIO.ReadInstance[h], list]; ENDLOOP; }; CountInstances: PUBLIC PROC [cell: CD.Object] RETURNS [n: INT_0] = { specific: CD.CellSpecific = NARROW[cell.specific]; n _ CDInstances.Length[specific.contents]; IF specific.sequence#NIL THEN n _ n+specific.sequence.length }; WriteCell: CD.InternalWriteProc = { specific: CD.CellSpecific = NARROW[ob.specific]; sLeng: NAT _ IF specific.sequence=NIL THEN 0 ELSE specific.sequence.length; i: INT _ IF specific.drawBorder THEN 2 ELSE 0; IF specific.specifiedIr THEN i _ i+1; CDIO.WriteRect[h, specific.ir]; TokenIO.WriteInt[h, Real.Round[ MAX[MIN[specific.simplifyOn, 500.0], 0.0] * MAX[MIN[(ob.bbox.y2-ob.bbox.y1), 100000], 0] ]]; TokenIO.WriteInt[h, i]; TokenIO.WriteInt[h, CountInstances[ob]]; FOR l: CD.InstanceList _ specific.contents, l.rest WHILE l#NIL DO CDIO.WriteInstance[h, l.first]; ENDLOOP; IF specific.sequence#NIL THEN FOR n: NAT IN [0..specific.sequence.length) DO CDIO.WriteInstance[h, specific.sequence[n]]; ENDLOOP; }; Describe: PROC[ob: CD.Object] RETURNS [Rope.ROPE] = { RETURN [Rope.Concat["cell ", NARROW[ob.specific, CD.CellSpecific].name]] }; ReplaceDirectChildForCell: PUBLIC PROC [me: CD.Object, design: CD.Design, replace: CDDirectory.ReplaceList] RETURNS [changed: BOOL_FALSE] = { cp: CD.CellSpecific = NARROW[me.specific]; FOR replaceList: CDDirectory.ReplaceList _ replace, replaceList.rest WHILE replaceList#NIL DO rep: REF CDDirectory.ReplaceRec = replaceList.first; PerInst: PROC [i: CD.Instance] = --INLINE-- { IF i.ob=rep.old THEN { changed _ TRUE; IF rep.trans#[] THEN i.trans _ CDBasics.ComposeTransform[itemInCell: rep.trans, cellInWorld: i.trans].itemInWorld; i.ob _ rep.new }; }; IF rep.old=me THEN LOOP; FOR l: CD.InstanceList _ cp.contents, l.rest WHILE l#NIL DO PerInst[l.first] ENDLOOP; IF cp.sequence#NIL THEN FOR n: NAT IN [0..cp.sequence.length) DO PerInst[cp.sequence[n]] ENDLOOP; ENDLOOP; IF changed AND ~cp.dummyCell THEN [] _ ResizeCell[design, me]; }; Bounds: PUBLIC PROC [list: CD.InstanceList_NIL, seq: CD.InstanceSequence_NIL, doIr: BOOL_TRUE, doBb: BOOL_TRUE] RETURNS [ir, bbox: CD.Rect _ CDBasics.empty] = { FOR l: LIST OF CD.Instance _ list, l.rest WHILE l#NIL DO IF doBb THEN bbox _ CDBasics.Surround[bbox, CDInstances.InstRectO[l.first]]; IF doIr THEN ir _ CDBasics.Surround[ir, CDInstances.InstRectI[l.first]]; ENDLOOP; IF seq#NIL THEN FOR n: NAT IN [0..seq.length) DO IF doBb THEN bbox _ CDBasics.Surround[bbox, CDInstances.InstRectO[seq[n]]]; IF doIr THEN ir _ CDBasics.Surround[ir, CDInstances.InstRectI[seq[n]]]; ENDLOOP; }; EnumerateInstances: PUBLIC PROC [cell: CD.Object, proc: CDCells.InstEnumerator] RETURNS [quit: BOOL] = { cp: CD.CellSpecific _ NARROW[cell.specific]; quit _ EnumInsts[cp.contents, cp.sequence, proc]; }; EnumInsts: PUBLIC PROC [list: CD.InstanceList, seq: CD.InstanceSequence, proc: CDCells.InstEnumerator] RETURNS [quit: BOOL_FALSE] = { FOR l: LIST OF CD.Instance _ list, l.rest WHILE l#NIL DO IF quit THEN RETURN; quit _ proc[l.first] ENDLOOP; IF seq#NIL THEN FOR n: NAT IN [0..seq.length) DO IF quit THEN RETURN; quit _ proc[seq[n]] ENDLOOP; }; ResizeCell: PUBLIC PROC [design: CD.Design, cell: CD.Object] RETURNS [didResize: BOOL] = { max: CD.Number = 536870910; -- LAST[CD.Number]/4-1 cp: CD.CellSpecific = NARROW[cell.specific]; IF cp.dummyCell THEN RETURN [didResize_FALSE] ELSE { oldBb: CD.Rect _ cell.bbox; oldIr: CD.Rect _ cp.ir; bb, ir: CD.Rect; [ir, bb] _ Bounds[cp.contents, cp.sequence, ~cp.specifiedIr, TRUE]; IF cp.specifiedIr THEN ir _ cp.ir; bb _ CDBasics.Surround[bb, ir]; IF ~CDBasics.NonEmpty[bb] THEN ir _ bb _ [0, 0, 1, 1]; IF didResize _ (ir#oldIr OR bb#oldBb) THEN { cp.ir _ ir; cell.bbox _ bb; CDDirectory.PropagateResize[design, cell] }; IF bb.x1<=-max OR bb.x2>=max OR bb.y1<=-max OR bb.y2>=max THEN TerminalIO.PutRopes["**WARNING: cell ", cp.name, " too large, it might generate arithmetic overflow\n"]; IF cp.simplifyOn<0 THEN SetSimplificationTreshhold[cell, -1]; } }; IsPushedIn: PUBLIC PROC [design: CD.Design] RETURNS [yes: BOOL] = { RETURN [ design^.actual.rest#NIL ] }; IsEmpty: PUBLIC PROC [cell: CD.Object] RETURNS [BOOL_FALSE] = { cp: CD.CellSpecific _ NARROW[cell.specific]; IF cp.contents=NIL THEN RETURN [ cp.sequence=NIL OR cp.sequence.length=0 ] }; PushedCellName: PUBLIC PROC [design: CD.Design] RETURNS [Rope.ROPE] = { RETURN [SELECT TRUE FROM design=NIL => "no design", design.actual.rest=NIL => "top level", ENDCASE => design.actual.first.specific.name ] }; SetInterestRect: PUBLIC PROC [design: CD.Design, cell: CD.Object, r: CD.Rect _ [0, 0, -1, -1], mode: CDCells.IncludeMode] = { cp: CD.CellSpecific _ NARROW[cell.specific]; old: CD.Rect _ cp.ir; cp.specifiedIr _ CDBasics.NonEmpty[r]; IF ~cp.specifiedIr THEN r _ Bounds[cp.contents, cp.sequence, TRUE, FALSE].ir; cp.ir _ r; SELECT mode FROM doit, dontNotify => [] _ ResizeCell[design, cell]; ENDCASE => NULL; IF mode=doit THEN CDDirectory.PropagateChange[cell, design]; }; SetBorderMode: PUBLIC PROC [cell: CD.Object, draw: BOOL] = { WITH cell.specific SELECT FROM cp: CD.CellSpecific => cp.drawBorder _ draw ENDCASE => NULL; }; SetSimplificationTreshhold: PUBLIC PROC [cell: CD.Object, val: REAL, inPixels: BOOL_TRUE] = { WITH cell.specific SELECT FROM cp: CD.CellSpecific => cp.simplifyOn _ IF val<0 THEN 50.0/MAX[(cell.bbox.y2-cell.bbox.y1), 1] ELSE IF inPixels THEN val/MAX[(cell.bbox.y2-cell.bbox.y1), 1] ELSE val; ENDCASE => NULL; }; ToSequenceMode: PUBLIC PROC [cell: CD.Object] = { IF CDCells.IsCell[cell] AND ~IsDummyCell[cell] THEN { cp: CD.CellSpecific _ NARROW[cell.specific]; [cp.contents, cp.sequence] _ CopyInsts[cp.contents, cp.sequence, TRUE] } }; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- IncludeInstance: PUBLIC PROC [design: CD.Design _ NIL, cell: CD.Object _ NIL, inst: CD.Instance, mode: CDCells.IncludeMode] RETURNS [resize: BOOL] = { cp: CD.CellSpecific; IF inst=NIL OR inst.ob=NIL THEN ERROR CD.Error[callingError, "Include NIL inst"]; IF cell#NIL THEN cp _ NARROW[cell.specific] ELSE IF design#NIL THEN cp _ design^.actual.first.specific ELSE ERROR; cp.contents _ CONS[inst, cp.contents]; --does not yet change insideRect !! IF cell#NIL THEN { resize _ ~CDBasics.Inside[CDInstances.InstRectO[inst], cell.bbox]; IF ~resize AND ~cp.specifiedIr THEN resize _ ~CDBasics.Inside[CDInstances.InstRectI[inst], cp.ir]; IF resize THEN SELECT mode FROM doit, dontNotify => [] _ ResizeCell[design, cell]; ENDCASE => NULL; IF mode=doit THEN CDDirectory.PropagateChange[cell, design]; }; IF design#NIL AND mode=doit THEN { IF cell=NIL THEN CDOps.RedrawInstance[design, inst, FALSE] ELSE CDOps.Redraw[design] }; }; IncludeOb: PUBLIC PROC [design: CD.Design, cell: CD.Object, ob: CD.Object, trans: CD.Transformation, mode: CDCells.IncludeMode] RETURNS [newInst: CD.Instance_NIL, resize: BOOL_FALSE] = { newInst _ NEW[CD.InstanceRep _ [ob: ob, trans: trans]]; resize _ IncludeInstance[design, cell, newInst, mode]; }; RemoveN: ENTRY PROC [seq: CD.InstanceSequence, n: INT] = { ENABLE UNWIND => NULL; IF seq#NIL THEN { leng: NAT _ seq.length; IF leng>seq.size THEN { leng _ seq.length _ seq.size; TRUSTED {Process.Detach[FORK TerminalIO.PutRope["**unconsistant instance sequence found/n"]]}; }; IF n>=leng OR leng=0 THEN RETURN; seq[n] _ seq[leng-1]; seq.length _ leng-1; seq[leng-1] _ NIL; } }; RemoveInstance: PUBLIC PROC [design: CD.Design _ NIL, cell: CD.Object, inst: CD.Instance, mode: CDCells.IncludeMode] RETURNS [resize: BOOL] = { cp: CD.CellSpecific; done: BOOL _ FALSE; IF cell=NIL THEN { IF design=NIL THEN ERROR CD.Error[callingError, "Remove from NIL cell"]; cp _ design^.actual.first.specific; } ELSE cp _ NARROW[cell.specific]; IF cp.contents#NIL THEN { IF cp.contents.first=inst THEN {cp.contents _ cp.contents.rest; done _ TRUE} ELSE FOR list: CD.InstanceList _ cp.contents, list.rest WHILE list.rest#NIL DO IF list.rest.first=inst THEN {list.rest _ list.rest.rest; done _ TRUE; EXIT} ENDLOOP; }; IF ~done AND cp.sequence#NIL THEN FOR n: NAT IN [0..cp.sequence.length) DO IF cp.sequence[n]=inst THEN { RemoveN[cp.sequence, n]; done _ TRUE; EXIT } ENDLOOP; IF cell#NIL THEN { oldr: CD.Rect _ CDBasics.Surround[cell.bbox, cp.ir]; r: CD.Rect = CDInstances.InstRectO[inst]; resize _ r.x1<=oldr.x1 OR r.y1<=oldr.y1 OR r.x2>=oldr.x2 OR r.y2>=oldr.y2; IF ~resize AND ~cp.specifiedIr THEN { r: CD.Rect = CDInstances.InstRectI[inst]; resize _ r.x1<=cp.ir.x1 OR r.y1<=cp.ir.y1 OR r.x2>=cp.ir.x2 OR r.y2>=cp.ir.y2; }; IF resize THEN SELECT mode FROM doit, dontNotify => [] _ ResizeCell[design, cell]; ENDCASE => NULL; IF mode=doit THEN CDDirectory.PropagateChange[cell, design]; }; IF design#NIL AND mode=doit THEN { IF cell=NIL THEN CDOps.RedrawInstance[design, inst] ELSE CDOps.Redraw[design] }; }; Get23Table: PROC [h: TokenIO.Handle] RETURNS [RefTab.Ref_NIL] = { rt: RefTab.Ref; WITH PropertyLists.GetProp[h.properties^, $convert23] SELECT FROM tab: RefTab.Ref => rt _ tab; ENDCASE => { rt _ RefTab.Create[201]; h.properties^ _ PropertyLists.PutProp[h.properties^, $convert23, rt] }; RETURN [rt]; }; ReadCell23: PROC [ob: CD.Object, h: TokenIO.Handle] = { i: INT; origin: CD.Position; oldBbox: CD.Rect; specific: CD.CellSpecific = NARROW[ob.specific]; size: CD.Position _ CDIO.ReadPos[h]; IF CDIO.VersionKey[h]>=8 THEN { --not that old specific.simplifyOn _ TokenIO.ReadInt[h]; i _ TokenIO.ReadInt[h]; specific.specifiedIr _ (i MOD 2)#0; specific.drawBorder _ (i/2)#0; IF specific.specifiedIr THEN specific.ir _ CDIO.ReadRect[h]; origin _ CDIO.ReadPos[h]; } ELSE { -- very old versions IF CDIO.VersionKey[h]<1 THEN { specific.name _ TokenIO.ReadRope[h]; } ELSE { specific.simplifyOn _ TokenIO.ReadInt[h]; }; }; [specific.sequence, specific.contents] _ ReadInstances[h]; oldBbox _ BoundsSL23[specific.sequence, specific.contents, h]; [] _ ResizeCell[NIL, ob]; IF oldBbox#ob.bbox THEN PutBox23[ob, h, oldBbox]; IF ob.bbox.y2>ob.bbox.y1 THEN specific.simplifyOn _ specific.simplifyOn/(ob.bbox.y2-ob.bbox.y1); }; PutBox23: PROC [ob: CD.Object, h: TokenIO.Handle, bbox: CD.Rect] = { tab: RefTab.Ref _ Get23Table[h]; [] _ RefTab.Insert[tab, ob, NEW[CD.Rect_bbox]] }; BBox23: PROC [ob: CD.Object, h: TokenIO.Handle] RETURNS [bbox: CD.Rect] = { bbox_ob.bbox; IF ob.class.inDirectory THEN WITH RefTab.Fetch[Get23Table[h], ob].val SELECT FROM rr: REF CD.Rect => RETURN [rr^] ENDCASE => NULL; }; InstRectOBound23: PROC [inst: CD.Instance, h: TokenIO.Handle] RETURNS [CD.Rect] = { RETURN [CDBasics.MapRect[BBox23[inst.ob, h], inst.trans]] }; BoundsSL23: PROC [seq: CD.InstanceSequence_NIL, list: CD.InstanceList_NIL, h: TokenIO.Handle] RETURNS [bbox: CD.Rect_CDBasics.empty] = { Proc: CDCells.InstEnumerator = { bbox _ CDBasics.Surround[bbox, InstRectOBound23[inst, h]]; }; [] _ EnumInsts[list, seq, Proc]; }; Init[]; END. CDCellsImpl.mesa (part of ChipNDale) Copyright c 1983, 1986 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, June 24, 1983 5:00 pm Last Edited by: Christian Jacobi, January 10, 1987 11:49:00 am PST --old stuff for io format version 4 --makes a copy of the list and the sequence, but tries to make the sequence as long as possible --inPlace TRUE: just reuse old Instances; FALSE: copy the Instances IF trans#[] THEN i.trans _ CDBasicsInline.ComposeTransform[i.trans, trans]; --draw border --draw inside --we do want to yield, but not too often --draw border --draw inside --speed up rects... RETURN [ CreateCell[CDInstances.DeComposedList[il, cTrans], CDBasics.DeMapRect[ir, cTrans]] ] [il, sq] _ CopyInsts[il, sq, FALSE, CDBasics.InverseTransform[cTrans]]; --be conservative; make sure no nil instances are introduced by bad client concurrency --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --old file format versions --it doesn't work with properties, they aren't yet initialized ΚΕ˜codešœ&™&Kšœ Οmœ7™BKšœ5™5K™BK˜—šΟk ˜ Kšžœ˜K˜ K˜K˜K˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœžœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜—K˜šΟn œžœžœ˜Kšžœžœžœ†˜¬Kšžœ˜ Kšžœžœ˜"—Kšž˜K˜šœ ž œžœ˜BKšœ˜Kšœ!˜!Kšœ"˜"Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ žœžœ˜.K˜šŸœžœ˜šœžœL˜SKšœ-˜-Kšœ ˜ Kšœ˜Kšœ˜Kšœ.˜.Kšœ˜—Kšœ0˜0šœ-˜-šœ%˜%Kšœ!˜!Kšœžœ˜Kšœ#˜#Kšœ ž˜Kšœ˜—Kšœ˜—Kšœ˜—K˜šŸ œžœžœžœ žœžœžœ˜Cšžœžœž˜Kšœžœžœ˜-Kšžœžœ˜—K˜K˜—š Ÿœžœžœžœžœ˜QKšœ#™#Kšœžœžœžœ ˜%Kšœ˜—K˜š Ÿœžœžœ žœžœ ˜=Kšžœžœžœ˜0Kšœ˜K˜—šŸ œžœžœžœžœ+žœ žœžœ˜šžœžœ˜Kšžœžœ˜0—Kšœ˜—K˜š Ÿœžœžœ žœžœ˜2Kšžœžœžœ˜2Kšœ˜—K˜šŸœžœžœ1žœ˜\Kšœžœžœ˜*š žœžœ'žœžœž˜DKšœ˜Kšžœ˜—šžœ žœžœ˜Kš žœžœžœžœžœ˜I—Kšœ˜—K˜šŸœžœžœžœžœžœžœžœz˜ΰKšœžœžœ˜-Kšœžœžœ˜.Kšœ˜Kšœ˜Kšœžœ˜KšœM˜MKšœV˜VKšžœžœžœžœ˜8Kšœ˜—K˜šŸ œž œžœžœžœžœžœ žœžœ žœ˜’KšΟc_™_Kš C™CKšœ žœ ˜Kšœžœ ˜Kšœ žœ˜Kš œ žœžœžœžœžœžœ˜AKšœ žœžœ.˜AKšœžœžœ ˜.šž˜Kšžœžœ˜4Kšžœžœžœžœ$˜9Kšžœžœ˜ š žœžœžœžœžœ˜Kšžœ žœ˜)Kšžœ žœ<™LKšžœ žœ˜.Kš žœžœ žœ žœ žœ˜2Kšžœ žœ ˜K˜—Kšžœ˜—Kšœ˜K˜—K˜š Ÿœžœžœžœžœ ˜VKšœžœžœ˜@Kšœ žœ? '˜qK™ šžœ žœ žœ˜%Kšœ&žœ5˜]—K™ š žœžœ$žœžœž˜;šžœ.žœ˜6Kšžœžœžœ˜KšœK˜KK˜—Kšžœ˜—šžœ žœž˜šžœžœžœž˜(šžœ5žœ˜=Kšžœžœžœ˜Kšœ_˜_K˜—Kšžœ˜——Kšœ˜Kšœ˜—J˜Jšœžœ˜šŸœžœžœ˜J™(Jšžœ žœ˜(J˜—K˜šŸœžœžœ)žœ ˜[Kšœžœžœ˜/šžœžœžœ˜8Kšœ/žœ˜Cšžœ2žœ˜9Kšœ<˜<—K˜—šžœ˜Kšœ žœ: '˜lK™ šžœ žœ žœ˜%KšœJ˜J—K™ š žœžœ$žœžœž˜;šžœ.žœ˜6Kšžœžœžœ˜Kšœ[˜[K˜—Kšžœ˜—šžœ žœž˜šžœžœžœž˜(šžœ5žœ˜=K™Kšžœžœžœ˜šžœ/žœ˜6Kšœ–˜–—šžœ˜Kšœv˜v—K˜—Kšžœ˜——Kšœ˜Kšžœžœ˜0Kšœ˜—Kšœ˜—K˜šŸœžœžœ)žœ ˜YKšœžœ˜/šžœžœžœ˜6Kšœ2žœ˜D—šžœ˜Kšœ4žœ˜K—Kšœ˜—K˜š Ÿœžœžœžœžœ ˜;šœžœžœ ˜Kšœ˜Kšœ˜Kšœ žœžœ˜*Kšœ˜—Kšœ˜—K˜šŸ œžœžœžœžœžœžœžœžœžœ ˜Kšœžœ˜"Kšœžœžœ˜*Kšœ˜Kšœ˜Kšœžœ˜)Kšœžœ˜Kšœ#˜#Kšžœ˜ Kšœ˜—K˜šŸœžœžœžœžœžœžœžœžœžœžœ ˜­KšžœW™]Kšœžœ%™GKšœžœ˜$š žœžœžœžœž˜2KšœC˜CKšžœ˜—šžœžœž˜šžœžœžœž˜Kšœ?˜?Kšžœ˜——Kšžœ7˜=K˜—K˜šΠbnœžœ˜!Kšœžœ˜Kšœžœ˜"Kšœ žœžœ˜0šžœžœžœžœ˜1Kšœžœ˜K˜—Kšœžœ˜ Kšœ)˜)Kšœ˜Kšœžœ˜#Kšœ˜Kšœ:˜:Kšœžœ˜šžœžœ˜KšœB˜B—Kšžœ˜ K˜K˜—š Ÿ œžœžœžœ"žœžœ˜pKšœ žœ ˜Kšœžœ˜Kšœ žœžœžœ ˜@Kšœžœžœ#˜/šžœžœžœž˜!Kšœ žœ˜Kšžœ˜—Kšœ˜šžœž˜Kšœžœžœ˜(Kšžœ˜—Kšœ˜—K˜š Ÿœž œžœ žœžœ˜DKšœ žœžœ˜2Kšœ*˜*Kšžœžœžœ˜Kšœ˜K˜—šŸœž œžœžœžœžœžœžœžœžœžœ žœ˜ š žœžœžœžœžœžœž˜8Kšžœžœ@˜LKšžœžœ<˜HKšžœ˜—šžœžœž˜šžœžœžœž˜ Kšžœžœ?˜KKšžœžœ;˜GKšžœ˜——K˜—K˜š Ÿœžœžœžœ'žœžœ˜hKšœžœžœ˜,Kšœ1˜1Kšœ˜—K˜šŸ œž œžœžœ1žœžœžœ˜…š žœžœžœžœžœžœž˜8Kšžœžœžœ˜Kšœ˜Kšžœ˜—šžœžœž˜šžœžœžœž˜ Kšžœžœžœ˜Kšœ˜Kšžœ˜——K˜—K˜šŸ œžœžœ žœžœ žœ žœ˜ZKšœžœ ˜2Kšœžœžœ˜,Kšžœžœžœ žœ˜-šžœ˜Kšœžœžœ˜3Kšœžœ˜Kšœ=žœ˜CKšžœžœ ˜"Kšœ˜Kšžœžœ˜6šžœžœ žœ˜,Kšœ˜Kšœ)˜)Kšœ˜—š žœ žœ žœ žœ ž˜>Kšœh˜h—Kšžœžœ&˜=K˜—Kšœ˜—K˜š Ÿ œž œ žœ žœžœ˜CKšžœžœ˜"Kšœ˜K™—šŸœžœžœžœ žœžœžœ˜?Kšœžœžœ˜,šžœ žœž˜Kšžœžœžœ˜2—K˜K˜—š Ÿœžœžœ žœ žœžœ˜Gšžœžœžœž˜Kšœžœ˜Kšœžœ˜&Kšžœ&˜-Kšœ˜—Kšœ˜—K˜š Ÿœžœžœ žœžœ žœ6˜}Kšœžœžœ˜,Kšœ˜Kšœ&˜&Kšžœžœ&žœžœ˜MKšœ ˜ šžœž˜Kšœ2˜2Kšžœžœ˜—Kšžœ žœ+˜Kšžœ˜ —Kšžœžœ˜—Kšœ˜—K˜šŸœžœžœžœ ˜1šžœžœžœ˜5Jšœžœžœ˜,JšœAžœ˜FJ˜—J˜—K˜K˜0K˜šŸœžœžœ žœ žœžœ žœžœ&žœ žœ˜–Kšœžœ˜Kšžœžœžœ žœžœžœžœ)˜QKšžœžœžœžœ˜+Kšžœžœžœžœ#˜:Kšžœžœ˜ Kšœžœ #˜Jšžœžœžœ˜KšœB˜Bšžœ žœžœ˜%Kšœ>˜>—šžœžœ˜šžœž˜Kšœ2˜2Kšžœžœ˜——Kšžœ žœ+˜˜>Kšœžœ˜Kšžœžœ˜1šžœžœ˜KšœB˜B—K˜K˜—šŸœžœžœ.˜DKšœ ˜ Kšœžœžœ ˜.Kšœ˜K˜—š Ÿœžœžœžœžœ ˜KKšœ ˜ šžœž˜Kš >™>šžœ%žœž˜4Kšœžœžœ žœ˜Kšžœžœ˜——Kšœ˜K˜—š Ÿœžœžœžœžœ ˜SKšžœ3˜9Kšœ˜K˜—šŸ œžœžœžœžœžœžœžœ˜ˆšŸœ˜ Kšœ:˜:K˜—Kšœ ˜ K˜—K˜K˜Kšžœ˜K˜—…—KVj!