DIRECTORY Atom, CD, CDBasics, CDCells, CDDirectory, CDEnvironment, CDInstances, CDIO, CDOps, CDProperties, Commander, Core, CoreClasses, CoreFlat, CoreIO, CoreOps, CoreProperties, CoreGeometry, GList, InstanceTable, IO, PW, PWCore, RefTab, Rope, Sinix, SinixOps, Sisyph, TerminalIO; PWCoreImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDCells, CDDirectory, CDEnvironment, CDInstances, CDIO, CDOps, CDProperties, CoreClasses, CoreIO, CoreOps, CoreProperties, CoreGeometry, GList, RefTab, InstanceTable, IO, PW, PWCore, Rope, Sinix, SinixOps, Sisyph, TerminalIO EXPORTS PWCore SHARES CDCells, CDDirectory = BEGIN OPEN PWCore; Signal: PUBLIC SIGNAL [cellType: CellType] = CODE; Error: PUBLIC ERROR [type: ATOM, message: ROPE, cellType: CellType] = CODE; PinsCorrespondingToSeveralPublics: PUBLIC SIGNAL [cellType: CellType, obj: Object, publics: Wires, geometry: CoreGeometry.Instances] = CODE; NoPinsOnAtomicPublic: PUBLIC SIGNAL [cellType: CellType, obj: Object, public: Wire, message: ROPE _ NIL] = CODE; layoutAtomsTable: RefTab.Ref _ RefTab.Create[]; LayoutAtomData: TYPE = REF LayoutAtomDataRec; LayoutAtomDataRec: TYPE = RECORD [layoutProc: LayoutProc, decorateProc: DecorateProc, attributesProc: AttributesProc _ NIL]; RegisterLayoutAtom: PUBLIC PROC [layoutAtom: ATOM, layoutProc: LayoutProc, decorateProc: DecorateProc _ NIL, attributesProc: AttributesProc _ NIL] RETURNS [sameAtom: ATOM] = { sameAtom _ layoutAtom; IF ~RefTab.Store[layoutAtomsTable, layoutAtom, NEW [LayoutAtomDataRec _ [layoutProc: layoutProc, decorateProc: decorateProc, attributesProc: attributesProc]]] THEN TerminalIO.PutF["LayoutProc and DecorateProc for %g overwritten\n", IO.atom[layoutAtom]]; }; GetLayoutAtomData: PROC [layoutAtom: ATOM] RETURNS [layoutAtomData: LayoutAtomData] = { layoutAtomData _ NARROW [RefTab.Fetch[layoutAtomsTable, layoutAtom].val]; IF layoutAtomData#NIL THEN RETURN; CDEnvironment.ExecFileEntry[Atom.GetPName[layoutAtom], NIL, "PWCore"]; layoutAtomData _ NARROW [RefTab.Fetch[layoutAtomsTable, layoutAtom].val]; }; GetLayoutAtomRegistration: PUBLIC PROC [layoutAtom: ATOM] RETURNS [layoutProc: LayoutProc _ NIL, decorateProc: DecorateProc _ NIL, attributesProc: AttributesProc _ NIL] = { layoutAtomData: LayoutAtomData _ GetLayoutAtomData[layoutAtom]; IF layoutAtomData=NIL THEN RETURN; layoutProc _ layoutAtomData.layoutProc; decorateProc _ layoutAtomData.decorateProc; attributesProc _ layoutAtomData.attributesProc; }; layoutAtomProp: PUBLIC ATOM _ CoreProperties.RegisterProperty[$Layout]; GetLayoutAtom: PUBLIC PROC [cellType: CellType] RETURNS [layoutAtom: ATOM _ NIL] = { layoutAtom _ NARROW [CoreProperties.InheritCellTypeProp[cellType, layoutAtomProp]]; }; CopyDecorations: PROC [to, from: CellType, obj: Object] = { CopyPins: PROC [toWire, fromWire: Wire] = { IF NOT CoreGeometry.HasPins[extractMode.decoration, fromWire] THEN SIGNAL NoPinsOnAtomicPublic[from, obj, fromWire, CoreOps.GetFullWireName[from.public, fromWire]]; CoreGeometry.AddIndirectLazyPins[extractMode.decoration, toWire, fromWire]; }; CoreOps.VisitAtomicPairs[to.public, from.public, CopyPins]; }; CheckDecorations: PROC [ct: CellType, obj: Object] = { CheckPins: PROC [wire: Wire] = { IF NOT CoreGeometry.HasPins[extractMode.decoration, wire] THEN SIGNAL NoPinsOnAtomicPublic[ct, obj, wire, CoreOps.GetFullWireName[ct.public, wire]]; }; CoreOps.VisitRootAtomics[ct.public, CheckPins]; }; fromPWCoreProp: PRIVATE ATOM _ $FromPWCoreLayout; -- on CD.Objects FromPWCoreRecord: TYPE = RECORD [int: INT]; SetFromPWCore: PRIVATE PROC [cellType: CellType] = { obj: CD.Object _ CoreGeometry.GetObject[extractMode.decoration, cellType]; int: INT _ LOOPHOLE [cellType]; IF CDProperties.GetObjectProp[obj, fromPWCoreProp]#NIL THEN Signal[cellType]; -- same object is stuffed on two different cells! That breaks the invariants, and Lichen will not work! CDProperties.PutObjectProp[obj, fromPWCoreProp, NEW [FromPWCoreRecord _ [int]]]; }; Layout: PUBLIC PROC [cellType: CellType] RETURNS [obj: Object] = { layoutAtom: ATOM; layoutAtomData: LayoutAtomData; obj _ CoreGeometry.GetObject[extractMode.decoration, cellType]; IF obj#NIL THEN RETURN; layoutAtom _ NARROW [CoreProperties.GetCellTypeProp[cellType, layoutAtomProp]]; IF layoutAtom=NIL THEN layoutAtom _ NARROW [CoreProperties.GetCellClassProp[cellType.class, layoutAtomProp]]; IF layoutAtom=NIL AND cellType.class.recast=NIL THEN ERROR Error[$NoLayoutAtom, "Impossible to find a layoutAtom for this cellType", cellType]; layoutAtomData _ GetLayoutAtomData[IF layoutAtom=NIL THEN $Recast ELSE layoutAtom]; IF layoutAtomData=NIL THEN ERROR Error[$NoRegistration, IO.PutFR["LayoutAtom %g has not been registered", IO.atom[layoutAtom]], cellType]; IF layoutAtomData.attributesProc#NIL THEN layoutAtomData.attributesProc[cellType]; obj _ layoutAtomData.layoutProc[cellType]; PW.SetName[obj, CoreOps.GetCellTypeName[cellType]]; CoreGeometry.PutObject[extractMode.decoration, cellType, obj]; IF layoutAtomData.decorateProc#NIL THEN layoutAtomData.decorateProc[cellType, obj]; CheckDecorations[cellType, obj]; SetFromPWCore[cellType]; }; GetPWCoreExtractedCTKey: PUBLIC PROC [extractedCT: CellType] RETURNS [key: INT _ 0] = { obj: CD.Object _ CoreGeometry.GetObject[extractMode.decoration, extractedCT]; ref: REF FromPWCoreRecord _ NARROW [CDProperties.GetObjectProp[obj, fromPWCoreProp]]; IF ref#NIL THEN key _ ref.int; }; IsPWCoreGenerated: PUBLIC PROC [obj: Object] RETURNS [BOOL] = { RETURN [CDProperties.GetObjectProp[obj, fromPWCoreProp]#NIL]; }; FromLayoutWithoutPublic: PUBLIC PROC [obj: Object] RETURNS [cellType: CellType] = { cellType _ NARROW [Sinix.Extract[obj, extractMode].result]; IF IsPWCoreGenerated[obj] THEN RETURN; -- done twice! SetLayoutAndDecoration[cellType, obj]; CheckDecorations[cellType, obj]; SetFromPWCore[cellType]; }; extractMode: PUBLIC Sinix.Mode _ SinixOps.GetExtractMode[$cmosB]; maskSuffix: PUBLIC ROPE _ ".mask"; GetAndAddSuffix: PROC [cellType: CellType] RETURNS [obj: Object] = { source: CD.Design _ NARROW [CoreProperties.GetCellTypeProp[cellType, $PWCoreSourceDesign]]; obj _ PW.Get[source, IO.PutR[IO.rope[CoreOps.GetCellTypeName[cellType]], IO.rope[maskSuffix]]]; }; Get: LayoutProc = { obj _ PW.CreateIndirect[GetAndAddSuffix[cellType]]; }; GetAndFlatten: LayoutProc = { obj _ PW.Flatten[GetAndAddSuffix[cellType]]; }; Value: LayoutProc = { obj _ NARROW [CoreProperties.GetCellTypeProp[cellType, $PWCoreValue]]; }; DecorateValue: PUBLIC DecorateProc = { extractedCT: CellType _ NARROW [Sinix.Extract[obj, extractMode].result]; extractedToSource: RefTab.Ref _ RefTab.Create[extractedCT.public.size]; FindInExtractedPublic: CoreOps.EachWireProc = { FOR names: LIST OF ROPE _ CoreOps.GetFullWireNames[cellType.public, wire], names.rest WHILE names#NIL DO name: ROPE _ names.first; extractedWire: Wire _ CoreOps.FindWire[extractedCT.public, name]; previousSourceWire: Wire _ NARROW [RefTab.Fetch[extractedToSource, extractedWire].val]; IF extractedWire=NIL OR extractedWire.size#0 THEN LOOP; IF previousSourceWire#NIL AND previousSourceWire#wire THEN SIGNAL PinsCorrespondingToSeveralPublics[cellType, obj, LIST [previousSourceWire, wire], CoreGeometry.GetPins[extractMode.decoration, extractedWire]]; IF NOT CoreGeometry.HasPins[extractMode.decoration, extractedWire] THEN SIGNAL NoPinsOnAtomicPublic[cellType, obj, extractedWire, name]; CoreGeometry.AddIndirectLazyPins[extractMode.decoration, wire, extractedWire]; [] _ RefTab.Store[extractedToSource, extractedWire, wire]; ENDLOOP; }; [] _ CoreOps.VisitWire[cellType.public, FindInExtractedPublic]; }; sisyphFudge: INT _ CD.FetchTechnology[$cmosB].lambda/2; -- Not very clean here! AttributeAbutXorY: AttributesProc = { ambiguous, inX: BOOL; [ambiguous, inX] _ InstancesInXOrY[Sisyph.mode.decoration, cellType, sisyphFudge]; IF ambiguous THEN ERROR Error[$CallerBug, "*** Ambiguity for deciding between AbutX and AbutY.\n", cellType]; SortInstances[Sisyph.mode.decoration, cellType, IF inX THEN SortInX ELSE SortInY]; }; LayoutAbutXorY: LayoutProc = { obj _ (IF InstancesInXOrY[Sisyph.mode.decoration, cellType, sisyphFudge].inX THEN AbutX ELSE AbutY)[cellType]; }; DecorateAbutXorY: DecorateProc = { (IF InstancesInXOrY[Sisyph.mode.decoration, cellType, sisyphFudge].inX THEN DecorateAbutX ELSE DecorateAbutY)[cellType, obj]; }; AttributeX: AttributesProc = {SortInstances[Sisyph.mode.decoration, cellType, SortInX]}; AttributeY: AttributesProc = {SortInstances[Sisyph.mode.decoration, cellType, SortInY]}; AbutX: LayoutProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; subObjects: LIST OF Object _ NIL; FOR i: NAT DECREASING IN [0 .. data.size) DO subObjects _ CONS [Layout[data[i].type], subObjects]; ENDLOOP; obj _ PW.AbutListX[subObjects]; }; AbutY: LayoutProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; subObjects: LIST OF Object _ NIL; FOR i: NAT DECREASING IN [0 .. data.size) DO subObjects _ CONS [Layout[data[i].type], subObjects]; ENDLOOP; obj _ PW.AbutListY[subObjects]; }; AbutFlipXAndDecorate: LayoutProc = {obj _ AbutFlipAndDecorate[cellType, TRUE]}; AbutFlipYAndDecorate: LayoutProc = {obj _ AbutFlipAndDecorate[cellType, FALSE]}; AbutFlipAndDecorate: PROC [cellType: CellType, inX: BOOL] RETURNS [obj: Object] = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; flip: BOOL _ FALSE; -- indicates polarity of the coming flip instances: CD.InstanceList _ NIL; -- instances for constructing the cell layout0: CD.Object _ Layout[data[0].type]; isize0: CD.Position _ CD.InterestSize[layout0]; pos: CD.Position _ [0, 0]; -- position (in ir coordonnates) of the coming cell FOR i: NAT IN [0 .. data.size) DO orientation: CD.Orientation _ IF flip THEN IF inX THEN mirrorX ELSE rotate180X ELSE original; layout: CD.Object _ Layout[data[i].type]; ir: CD.Rect = CDBasics.MapRect[CD.InterestRect[layout], [[0, 0], orientation]]; isize: CD.Position _ CDBasics.SizeOfRect[ir]; trans: CD.Transformation = [CDBasics.SubPoints[pos, CDBasics.BaseOfRect[ir]], orientation]; -- translation, in the CD coordonnate system IF NOT (IF inX THEN isize.y=isize0.y ELSE isize.x=isize0.x) THEN ERROR; -- incompatible y dimension for an abutX instances _ CONS [CDInstances.NewInst[layout, trans], instances]; CoreGeometry.PutTrans[extractMode.decoration, data[i], trans]; IF inX THEN pos.x _ pos.x + isize.x ELSE pos.y _ pos.y + isize.y; flip _ NOT flip; ENDLOOP; obj _ PW.CreateCell[instances: instances]; CoreGeometry.PutRecordLazyPins[extractMode.decoration, cellType, CD.InterestRect[obj]]; }; ReverseAbutX: LayoutProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; subObjects: LIST OF Object _ NIL; FOR i: NAT IN [0 .. data.size) DO subObjects _ CONS [Layout[data[i].type], subObjects]; ENDLOOP; obj _ PW.AbutListX[subObjects]; }; ReverseAbutY: LayoutProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; subObjects: LIST OF Object _ NIL; FOR i: NAT IN [0 .. data.size) DO subObjects _ CONS [Layout[data[i].type], subObjects]; ENDLOOP; obj _ PW.AbutListY[subObjects]; }; ArrayX: LayoutProc = { recasted: CellType _ CoreOps.Recast[cellType]; SetLayout[recasted, $RawAbutX]; obj _ PW.CreateIndirect[Layout[recasted]]; }; ArrayY: LayoutProc = { recasted: CellType _ CoreOps.Recast[cellType]; SetLayout[recasted, $RawAbutY]; obj _ PW.CreateIndirect[Layout[recasted]]; }; ArrayFlipX: LayoutProc = { recasted: CellType _ CoreOps.Recast[cellType]; SetLayout[recasted, $RawAbutFlipX]; obj _ PW.CreateIndirect[Layout[recasted]]; }; ArrayFlipY: LayoutProc = { recasted: CellType _ CoreOps.Recast[cellType]; SetLayout[recasted, $RawAbutFlipY]; obj _ PW.CreateIndirect[Layout[recasted]]; }; ReverseArrayX: LayoutProc = { recasted: CellType _ CoreOps.Recast[cellType]; SetLayout[recasted, $RawReverseAbutX]; obj _ PW.CreateIndirect[Layout[recasted]]; }; ReverseArrayY: LayoutProc = { recasted: CellType _ CoreOps.Recast[cellType]; SetLayout[recasted, $RawReverseAbutY]; obj _ PW.CreateIndirect[Layout[recasted]]; }; Recast: LayoutProc = { obj _ PW.CreateIndirect[Layout[CoreOps.Recast[cellType]]]; }; DecorateAbut: PUBLIC PROC [cellType: CellType, obj: Object, sort: SortProc] = { InsertInst: CDCells.InstEnumerator = { IF inst.trans.orient#original THEN ERROR Error[$CallerBug, "DecorateAbut is only applicable to objects expanding into cells without rotation", cellType]; sorted _ CONS [inst, sorted]; }; CompareInst: GList.CompareProc = { inst1: CD.Instance = NARROW [ref1]; inst2: CD.Instance = NARROW [ref2]; RETURN [IF sort[ObjectBase[inst1.ob, inst1.trans], ObjectBase[inst2.ob, inst2.trans]] THEN less ELSE greater]; }; sorted: LIST OF CD.Instance; recordData: CoreClasses.RecordCellType _ NARROW [cellType.data]; WHILE obj.class#CDCells.pCellClass DO obj _ CDDirectory.Expand1[obj].new ENDLOOP; [] _ CDCells.EnumerateInstances[obj, InsertInst]; sorted _ NARROW [GList.Sort[sorted, CompareInst]]; FOR i: NAT IN [0 .. recordData.size) DO CoreGeometry.PutTrans[extractMode.decoration, recordData[i], sorted.first.trans]; sorted _ sorted.rest; ENDLOOP; IF sorted#NIL THEN ERROR Error[$CallerBug, "DecorateAbut assumption not valid: CD cell has more instances than record CellType", cellType]; CoreGeometry.PutRecordLazyPins[extractMode.decoration, cellType, CD.InterestRect[obj]]; }; DecorateAbutX: PUBLIC DecorateProc = { DecorateAbut[cellType, obj, SortInX]; }; DecorateAbutY: PUBLIC DecorateProc = { DecorateAbut[cellType, obj, SortInY]; }; DecorateReverseAbutX: PUBLIC DecorateProc = { DecorateAbut[cellType, obj, ReverseSortInX]; }; DecorateReverseAbutY: PUBLIC DecorateProc = { DecorateAbut[cellType, obj, ReverseSortInY]; }; DecorateRecasted: PUBLIC DecorateProc = { CopyDecorations[cellType, CoreOps.Recast[cellType], obj]; }; Rotated: PROC [cellType: CellType] RETURNS [rotatedCT: CellType] = { rct: CoreClasses.RecordCellType; IF cellType.class#CoreClasses.recordCellClass THEN ERROR Error[$CallerBug, "Rotation CellType expected [RecordCell with one instance]", cellType]; rct _ NARROW [cellType.data]; IF rct.size#1 THEN ERROR Error[$CallerBug, "Rotation CellType expected [RecordCell with one instance]", cellType]; rotatedCT _ rct[0].type; }; FlipX: LayoutProc = {obj _ PW.FlipX[Layout[Rotated[cellType]]]}; FlipY: LayoutProc = {obj _ PW.FlipY[Layout[Rotated[cellType]]]}; Rot90: LayoutProc = {obj _ PW.Rot90[Layout[Rotated[cellType]]]}; Rot180: LayoutProc = {obj _ PW.Rot180[Layout[Rotated[cellType]]]}; Rot270: LayoutProc = {obj _ PW.Rot270[Layout[Rotated[cellType]]]}; DecorateRotated: PUBLIC DecorateProc = { rotatedCT: CellType = Rotated[cellType]; trans: CoreGeometry.Transformation; DecorateUniqueInst: CDCells.InstEnumerator = {trans _ inst.trans}; WHILE obj.class#CDCells.pCellClass DO obj _ CDDirectory.Expand1[obj].new ENDLOOP; IF CDCells.CountInstances[obj]#1 THEN ERROR Error[$CallerBug, "DecorateRotated is not supposed to be called with an obj that does not expand into a one instance cell", cellType]; [] _ CDCells.EnumerateInstances[obj, DecorateUniqueInst]; CoreGeometry.PutTrans[extractMode.decoration, NARROW [cellType.data, CoreClasses.RecordCellType][0], trans]; CoreGeometry.PutRecordLazyPins[extractMode.decoration, cellType, CD.InterestRect[obj]]; }; SortInX: PUBLIC PROC [pos1, pos2: CD.Position] RETURNS [BOOL] = {RETURN [pos1.xpos2.x]}; ReverseSortInY: PUBLIC PROC [pos1, pos2: CD.Position] RETURNS [BOOL] = {RETURN [pos1.y>pos2.y]}; ObjectBase: PROC [obj: CD.Object, trans: CoreGeometry.Transformation] RETURNS [pos: CD.Position] = { pos _ CDBasics.BaseOfRect[CDBasics.MapRect[CD.InterestRect[obj], trans]]; }; InstanceBase: PROC [decoration: CoreGeometry.Decoration, cellType: CellType, trans: CoreGeometry.Transformation] RETURNS [pos: CD.Position] = { pos _ ObjectBase[CoreGeometry.GetObject[decoration, cellType], trans]; }; InstancesInXOrY: PUBLIC PROC [decoration: CoreGeometry.Decoration, record: CellType, fudge: INT _ 0] RETURNS [ambiguous, inX: BOOL] = { data: CoreClasses.RecordCellType _ NARROW [record.data]; overlappingInX, overlappingInY: BOOL _ FALSE; FOR i: NAT IN [0 .. data.size-1) DO rect1: CD.Rect _ CDBasics.MapRect[ CD.InterestRect[CoreGeometry.GetObject[decoration, data[i].type]], CoreGeometry.GetTrans[decoration, data[i]] ]; FOR j: NAT IN (i .. data.size) DO rect2: CD.Rect _ CDBasics.MapRect[ CD.InterestRect[CoreGeometry.GetObject[decoration, data[j].type]], CoreGeometry.GetTrans[decoration, data[j]] ]; IF rect1.x1+fudge extractedPublic layout _ PWCore.Layout[sourceCT]; extractedCT _ NARROW [Sinix.Extract[layout, extractMode].result]; extractedToSource _ RefTab.Create[]; -- maps extractedWire to source extractedInstances _ InstanceTableFromPublic[extractMode.decoration, layout.bbox, extractedCT.public]; key _ GetPWCoreExtractedCTKey[extractedCT]; CoreOps.VisitRootAtomics[sourceCT.public, FillTable]; }; InstanceTableFromPublic: PROC [decoration: CoreGeometry.Decoration, bbox: CD.Rect, public: WireSeq] RETURNS [table: InstanceTable.Table] = { FillInstanceTable: PROC [wire: Wire] = { AddPinInTable: CoreGeometry.EachInstanceProc = { InstanceTable.Insert[table, instance, wire]; }; [] _ CoreGeometry.EnumeratePins[decoration, wire, AddPinInTable]; }; table _ InstanceTable.Create[bbox]; CoreOps.VisitRootAtomics[public, FillInstanceTable]; }; [] _ RegisterLayoutAtom[$Get, Get, DecorateValue]; [] _ RegisterLayoutAtom[$GetAndFlatten, GetAndFlatten, DecorateValue]; [] _ RegisterLayoutAtom[$Value, Value, DecorateValue]; [] _ RegisterLayoutAtom[$ValueNoDecorate, Value]; [] _ RegisterLayoutAtom[$AbutListXNoDecorate, AbutX]; [] _ RegisterLayoutAtom[$AbutListYNoDecorate, AbutY]; [] _ RegisterLayoutAtom[$RawAbutX, AbutX, DecorateAbutX]; [] _ RegisterLayoutAtom[$RawAbutY, AbutY, DecorateAbutY]; [] _ RegisterLayoutAtom[$RawAbutFlipX, AbutFlipXAndDecorate]; [] _ RegisterLayoutAtom[$RawAbutFlipY, AbutFlipYAndDecorate]; [] _ RegisterLayoutAtom[$AbutFlipX, AbutFlipXAndDecorate, NIL, AttributeX]; [] _ RegisterLayoutAtom[$AbutFlipY, AbutFlipYAndDecorate, NIL, AttributeY]; [] _ RegisterLayoutAtom[$RawReverseAbutX, ReverseAbutX, DecorateReverseAbutX]; [] _ RegisterLayoutAtom[$RawReverseAbutY, ReverseAbutY, DecorateReverseAbutY]; [] _ RegisterLayoutAtom[$AbutX, AbutX, DecorateAbutX, AttributeX]; [] _ RegisterLayoutAtom[$AbutY, AbutY, DecorateAbutY, AttributeY]; [] _ RegisterLayoutAtom[$Abut, LayoutAbutXorY, DecorateAbutXorY, AttributeAbutXorY]; [] _ RegisterLayoutAtom[$ReverseAbutX, ReverseAbutX, DecorateReverseAbutX, AttributeX]; [] _ RegisterLayoutAtom[$ReverseAbutY, ReverseAbutY, DecorateReverseAbutY, AttributeY]; [] _ RegisterLayoutAtom[$ArrayX, ArrayX, DecorateRecasted]; [] _ RegisterLayoutAtom[$ArrayY, ArrayY, DecorateRecasted]; [] _ RegisterLayoutAtom[$ArrayFlipX, ArrayFlipX, DecorateRecasted]; [] _ RegisterLayoutAtom[$ArrayFlipY, ArrayFlipY, DecorateRecasted]; [] _ RegisterLayoutAtom[$ReverseArrayX, ReverseArrayX, DecorateRecasted]; [] _ RegisterLayoutAtom[$ReverseArrayY, ReverseArrayY, DecorateRecasted]; [] _ RegisterLayoutAtom[$Recast, Recast, DecorateRecasted]; [] _ RegisterLayoutAtom[$FlipX, FlipX, DecorateRotated]; [] _ RegisterLayoutAtom[$FlipY, FlipY, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot90, Rot90, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot180, Rot180, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot270, Rot270, DecorateRotated]; END. PWCoreImpl.mesa Copyright Σ 1985, 1987 by Xerox Corporation. All rights reserved. Louis Monier May 17, 1986 1:35:25 pm PDT Bertrand Serlet April 28, 1988 1:48:55 pm PDT Barth, April 22, 1986 7:30:28 pm PST Spreitzer, April 11, 1986 10:52:25 am PST Last Edited by: Louis Monier July 26, 1988 7:14:55 pm PDT Jean-Marc Frailong December 28, 1987 10:00:21 am PST Last edited by: Christian Jacobi, January 9, 1987 12:16:44 pm PST Exceptions LayoutAtomsTable Primitives Copies decorations from from to to We check that the public of the source and the public of the recasted layout are similar, and we copy properties from one to the other Checks that's ct is properly decorated. We compute the attributes (if any) Now the layout We decorate for lazy decorations Now we decorate the source cellType We check those decorations, and we decorate layoutCellType. We need to do that in order to be able to return layoutCellType as the result of the extraction. We mark obj as coming from Layout Global Variable $Get, $GetAndFlatten, $Value and $ValueNoDecorate Here could be added the code for searching in a "Design" property if source=NIL? Question for the reader: Why are we making an indirect here??? Answer: because two different cellTypes can have the exact same name, Layout: $Get and $PWCoreSourceDesign: design. For example two icons extracted in different Sisyph contexts will yield two different (but identical!) cellTypes. Abuts, Arrays and Recast We decorate each instance with the appropriate trans, so that the Lazy GetPins can find the location We decorate each instance with the appropriate trans, so that the Lazy GetPins can find the location Rotations This line is important since obj can be of the class "Rotation" itself. Help for writing DecorateProcs Short cut Saving "Checkpoints" Slight modification of CDDirectoryOps.IncludeDescribedObjects to avoid problems when dealing with objects inclkuded in 2 designs. Hack, of course! Backdoor for clients such as PWCoreLichen Creates a table instance -> public Initialization and various registrations Κ°˜™IcodešœB™BKšœ%Οk™(Kšœ*™-Kšœ!™$Kšœ&™)Kšœ9™9Kšœ1™4Kšœ>™A—J˜š ˜ Kšœ˜Kšœ>œ˜[K˜ Kšœ>˜>K˜Kšœœ˜Kšœ ˜ Kšœ˜Kšœ$˜$—K˜šΠbn œœ˜Kš œœ>œqœœ3˜όKšœ˜Kšœ˜Kšœœ˜—head™ šΟnœœœœ˜2J˜—š Ÿœœœœ œœ˜KJ˜—šŸ!œœœWœ˜ŒJ˜—Jš Ÿœœœ:œœœ˜p—šœ™Jšœ/˜/J˜Kšœœœ˜-KšœœœWœ˜|K˜šŸœœœœ7œ#œœ œ˜―Kšœ˜šœ-œm˜ŸKšœEœ˜^—K˜K˜—šŸœœœœ%˜WKšœœ2˜IKšœœœœ˜"Kšœ7œ ˜FKšœœ2˜IK˜K˜—šŸœœœœœœœ#œ˜¬Kšœ?˜?Kšœœœœ˜"Kšœ(˜(Kšœ,˜,Kšœ/˜/K˜——šœ ™ šœœœ,˜GJ˜—š Ÿ œœœœœœ˜TKšœ œ@˜SK˜K˜—Kšœ"™"šŸœœ&˜;šŸœœ˜+šœœ8˜>Jšœœ[˜f—JšœK˜KK˜—Kšœ†™†Kšœ;˜;K˜K˜—Kšœ'™'šŸœœ ˜6šŸ œœ˜ šœœ4œ˜?JšœO˜U—K˜—Kšœ/˜/K˜K˜—JšœΠbkœœΟc˜BJšœœœœ˜+šŸ œœœ˜4KšœœC˜JKšœœœ ˜Kšœ1œœ‘h˜ΆKšœ0œ˜PK˜J˜—šŸœœœœ˜BKšœ œ˜Kšœ˜Kšœ?˜?Kšœœœœ˜Kšœ œ<˜Ošœ œœ˜Kšœ œC˜V—š œ œœœœ˜5KšœV˜[—Kš œ#œ œœ œ ˜Sšœœœ˜Kšœœ0œ˜o—K™"Kšœœœ)˜RK™Kšœ*˜*Kšœ1˜3K™ Kšœ>˜>Kšœ#™#Kšœœœ,˜SKšœ™Kšœ ˜ Kšœ!™!Kšœ˜Kšœ˜—K˜š Ÿœœœœœ ˜WKšœœF˜MKšœœœ3˜UKšœœœ˜J˜J˜—š Ÿœœœœœ˜?Jšœ2œ˜=J˜J˜—šŸœœœœ˜SJšœ œ*˜;Kšœœœ‘˜5Kšœ&˜&Kšœ ˜ Kšœ˜K˜——™Jšœ œ.˜A—šœ1™1šœ œœ ˜"J˜—šŸœœœ˜DKšœœ œA˜[JšœLœ™PJš œœ œœ*œ˜_J˜J˜—K™>K™ζšžœ˜Jšœœ+˜3K˜K˜—šŸ œ˜Jšœœ$˜,K˜K˜—šŸœ˜Kšœœ:˜FK˜K˜—šŸ œœ˜&Jšœœ*˜HJšœG˜Gšžœ˜/š œœœœ?œœ˜hKšœœ˜KšœA˜AKšœœ6˜WKš œœœœœ˜7Kš œœœœœ2œZ˜Ρšœœ=˜CJšœœ:˜E—JšœN˜NKšœ:˜:Kšœ˜—J˜—Jšœ?˜?Kšœ˜——™šœ œœ#‘˜OK˜—šŸœ˜%Kšœœ˜KšœR˜RKšœ œœV˜mKšœ0œœ œ ˜RKšœ˜K˜—šŸœ˜KšœœDœœ˜nK˜K˜—šŸœ˜"KšœœDœœ˜}K˜K˜—šŸ œN˜XK˜—šŸ œN˜XK˜—šŸœ˜Kšœ#œ˜:Kšœ œœ œ˜!š œœ œœ˜,Kšœ œ$˜5Kšœ˜—Jšœœ˜K˜K˜—šŸœ˜Kšœ#œ˜:Kšœ œœ œ˜!š œœ œœ˜,Kšœ œ$˜5Kšœ˜—Jšœœ˜K˜K˜—šŸœ4œ˜OK˜—šŸœ4œ˜PK˜—šŸœœœœ˜SKšœ#œ˜:Kšœœœ‘(˜˜>Jšœœœ˜AKšœœ˜Kšœ˜—Jšœœ#˜+JšœAœ˜WK˜K˜—šŸ œ˜Kšœ#œ˜:Kšœ œœ œ˜!šœœœ˜!Kšœ œ$˜5Kšœ˜—Jšœœ˜K˜K˜—šŸ œ˜Kšœ#œ˜:Kšœ œœ œ˜!šœœœ˜!Kšœ œ$˜5Kšœ˜—Jšœœ˜K˜K˜—šžœ˜Kšœ.˜.Kšœ&œ"˜JK˜K˜—šžœ˜Kšœ.˜.Kšœ&œ"˜JK˜K˜—šž œ˜Kšœ.˜.Kšœ*œ"˜NK˜K˜—šž œ˜Kšœ.˜.Kšœ*œ"˜NK˜K˜—šž œ˜Kšœ.˜.Kšœ-œ"˜QK˜K˜—šž œ˜Kšœ.˜.Kšœ-œ"˜QK˜K˜—šžœ˜Kšœœ2˜:K˜K˜—šŸ œœœ6˜OšŸ œ˜&Kšœœœq˜™Kšœ œ˜K˜—šŸ œ˜"Jšœœ œ˜#Jšœœ œ˜#šœœL˜VJšœœ ˜—J˜—Kšœœœœ ˜Jšœ)œ˜@Kšœœ$œ˜QKšœ1˜1Kšœ œ#˜2Jšœd™dšœœœ˜'JšœQ˜QJšœ˜Jšœ˜—Jšœœœœs˜‹JšœAœ˜WK˜K˜—šŸ œœ˜&Kšœ%˜%Kšœ˜K˜—šŸ œœ˜&Kšœ%˜%Kšœ˜K˜—šŸœœ˜-Kšœ,˜,Kšœ˜K˜—šŸœœ˜-Kšœ,˜,Kšœ˜K˜—šžœœ˜)Kšœ9˜9Kšœ˜——™ šŸœœœ˜DJšœ ˜ Jšœ,œœZ˜’Jšœœ˜Jšœ œœZ˜rJšœ˜J˜K˜—šžœœ#˜@K˜—šžœœ#˜@K˜—šžœœ#˜@K˜—šžœœ$˜BK˜—šžœœ$˜BK˜—šžœœ˜(Jšœ(˜(Kšœ#˜#KšŸœ0˜BKšœG™GKšœœ$œ˜QKšœœœ‡˜²Kšœ9˜9Kšœ.œ8˜lKšœAœ˜WK˜——™KšŸœœœœ œœœ˜YKšŸœœœœ œœœ˜YKšŸœœœœ œœœ˜`šŸœœœœ œœœ˜`K˜—š Ÿ œœœ-œœ˜dKšœ+œ˜IK˜K˜—šŸ œœ_œœ˜KšœF˜FK˜K˜—š Ÿœœœ@œœœ˜‡Kšœ#œ˜8Kšœ œœ˜-šœœœ˜#šœœ˜"JšœA˜CJšœ*˜*J˜—šœœœ˜!šœœ˜"JšœA˜CJšœ*˜*J˜—Kšœœœœ˜RKšœœœœ˜RKšœ˜—Kšœ˜—Kšœ*˜*Kšœ˜K˜K˜—šŸ œœœN˜hKšœ#œ˜:šœœœ˜#šœœœ˜!šœ˜ KšœT˜TKšœR˜RKšœœ˜Kšœ'˜'Kšœ˜Kšœ˜—Kšœ˜—Kšœ˜—K˜——™ šŸ œœœ"œœœ œœ˜pKšœE˜EKšœœœB˜ZKšœ˜K˜—š Ÿœœœ*œœ˜kKšœF˜FKšœH˜Hšœœœ$˜3Kšœ8˜8Kšœ˜Kšœ˜—K•StartOfExpansion`[actual: Core.Wire, type: Core.CellType, name: ROPE _ NIL, props: Core.Properties _ NIL]šœWœH˜£Kšœ!˜!K˜——™Kšœ™šŸœœ œ œ ˜DšŸ œ ˜*šœœ˜Kšœ œ ˜/Kšœœœœ˜Kšœœ-˜:Kšœœœœ˜Kšœ™Kš œ.œœœœœ˜UKšœ+œ˜1K˜—K˜—Jšœ:˜:Jšœ˜J˜—š Ÿœœœ%œœ˜HJšœ œ'˜4Jšœ5œ ˜DJšœ)˜)Jšœ$˜$Jšœ˜šœU˜UJšœ œ œ˜.——J˜š Ÿ œœœ%œœ˜MJšœ œ'˜4Jšœœ˜0Jšœœœ˜IJšœ œ˜Jšœ6œ ˜EJšœR˜RJšœ!˜!Jšœ3˜3Jšœ.˜.Jšœœ)˜2Jšœ1‘˜PJ˜—šŸ œœœ˜1Jšœ œ'˜4Jšœœ˜2Jšœœœ˜IJšœ œ˜(Jšœ7œ ˜FJšœ#˜#šœ œ ˜Jšœœ œ*˜Q—JšœB˜BJšœ0˜0Jšœ.˜.Jšœœ+˜4Jšœ2‘˜QJ˜—š Ÿœœœœœ˜CJšœœ˜Kšœ(œ ˜7Jšœ(˜(Jšœ?˜?Kšœ˜Kšœ'œ˜7——™)š Ÿ œœœœMœ˜‰šŸ œœ˜(šŸ œ#˜0šŸœœK˜WJšœœ ˜%Jšœœ6˜OJšœœœ‘˜=šœœK˜QJšœœ˜ —Jš œ œœœ5œœ ˜—JšœB˜BJ˜—JšœQ˜QJ˜—JšœU˜UJ˜—Jšœ)‘$˜MJšœ!˜!Jšœœ-˜AJšœ%‘˜DJšœf˜fJšœ+˜+Jšœ5˜5J˜J˜—Jšœ"™"šŸœœ-œœ!˜ŒšŸœœ˜(šŸ œ#˜0Jšœ,˜,J˜—JšœA˜AJ˜—Jšœ#˜#Jšœ4˜4J˜——™(Jšœ2˜2JšœF˜FJšœ6˜6Jšœ1˜1Jšœ5˜5Jšœ5˜5Jšœ9˜9Jšœ9˜9Jšœ=˜=Jšœ=˜=Jšœ:œ˜KJšœ:œ˜KJšœN˜NJšœN˜NJšœB˜BJšœB˜BJšœT˜TJšœW˜WJšœW˜WJšœ;˜;Jšœ;˜;JšœC˜CJšœC˜CJšœI˜IJšœI˜IJšœ;˜;Jšœ8˜8Jšœ8˜8Jšœ8˜8Jšœ:˜:Jšœ:˜:—J˜Kšœ˜K™—…—`ώ€Δ