DIRECTORY CD, CDInstances, CDBasics, CDLayers USING [MakeAbstract, AbstractToPaint], CDImports, CDIO, CDOps, CDOrient, CDSymbolicObjects, CDPrivate, CDProperties, CDRects, Imager, ImagerPath, LRUCache, Rope; CDSymbolicObjectsImpl: CEDAR MONITOR IMPORTS CD, CDInstances, CDBasics, CDLayers, CDIO, CDOps, CDOrient, CDPrivate, CDProperties, CDRects, Imager, ImagerPath, LRUCache, Rope EXPORTS CDSymbolicObjects SHARES CDLayers = BEGIN symNameProp: ATOM = $SignalName; symLayerProp: ATOM = $layerOfPin; symOwnerProp: ATOM = $ownerOfPin; markObject: CD.Object; markObjectPath: ImagerPath.Trajectory = CreateMarkObjectPath[]; dummySpecific: REF SymRec = NEW[SymRec]; SymRec: TYPE = RECORD [dummy: INT _ 17]; pinLayer: PUBLIC CD.Layer _ CD.NewLayer[NIL, $pinRepresentation]; segmentLayer: PUBLIC CD.Layer _ CD.NewLayer[NIL, $segmentRepresentation]; markLayer: CD.Layer _ CD.undefLayer; lruQueue: LRUCache.Handle _ LRUCache.Create[87, CDPrivate.Hash, Equal]; freePin: CD.Object _ NIL; --reduces the allocators work freeSegment: CD.Object _ NIL; GivePin: ENTRY PROC [] RETURNS [ob: CD.Object] = INLINE { ob _ freePin; freePin _ NIL; IF ob=NIL THEN ob _ NEW[CD.ObjectRep_[class: pinClass, specificRef: dummySpecific, layer: pinLayer]]; }; GiveSegment: ENTRY PROC [] RETURNS [ob: CD.Object] = INLINE { ob _ freeSegment; freeSegment _ NIL; IF ob=NIL THEN ob _ NEW[CD.ObjectRep_[class: segmentClass, specificRef: dummySpecific, layer: segmentLayer]]; }; Equal: PROC[x, y: REF] RETURNS [BOOL] = { ob1: CD.Object = NARROW[x]; ob2: CD.Object = NARROW[y]; RETURN [ob1.class=ob2.class AND ob1.size=ob2.size AND ob1.layer=ob2.layer] }; pinClass: PUBLIC CD.ObjectClass _ CD.RegisterObjectClass[$PinOb0, [ drawMe: DrawPin, quickDrawMe: DrawPin, showMeSelected: ShowSelectedSymRL, internalRead: ReadPin, internalWrite: WritePinOrSegment, wireTyped: TRUE, symbolic: TRUE, description: "pin", describeInst: DescribeInstance ]]; segmentClass: PUBLIC CD.ObjectClass _ CD.RegisterObjectClass[$SymbolicSegment, [ drawMe: DrawSegment, quickDrawMe: DrawSegment, showMeSelected: ShowSelectedSymRL, internalRead: ReadSegment, internalWrite: WritePinOrSegment, wireTyped: TRUE, symbolic: TRUE, description: "segment", describeInst: DescribeInstance ]]; markClass: PUBLIC CD.ObjectClass _ CD.RegisterObjectClass[$AlignmentMarkOb, [ drawMe: DrawMark, quickDrawMe: DrawMark, internalRead: ReadMark, internalWrite: WriteMark, symbolic: TRUE, description: "mark" ]]; CreateMarkObjectPath: PROC [] RETURNS [markObjectPath: ImagerPath.Trajectory] = { markObjectPath _ ImagerPath.MoveTo[[0, 0]]; markObjectPath _ ImagerPath.LineTo[markObjectPath, [0, 3]]; markObjectPath _ ImagerPath.LineTo[markObjectPath, [1, 2]]; markObjectPath _ ImagerPath.LineTo[markObjectPath, [3, 4]]; markObjectPath _ ImagerPath.LineTo[markObjectPath, [4, 3]]; markObjectPath _ ImagerPath.LineTo[markObjectPath, [2, 1]]; markObjectPath _ ImagerPath.LineTo[markObjectPath, [3, 0]]; markObjectPath _ ImagerPath.LineTo[markObjectPath, [0, 0]]; }; Init: PROC [] = { CDLayers.MakeAbstract[pinLayer]; CDRects.UseAsCreateRect[pinLayer, RCreatePin, pinClass]; CDLayers.MakeAbstract[segmentLayer]; CDRects.UseAsCreateRect[segmentLayer, RCreateSegment, segmentClass]; markObject _ NEW[CD.ObjectRep _ [ class: markClass, size: [4, 4], layer: markLayer, specificRef: $AlignmentMarkOb ]]; [] _ CDProperties.RegisterProperty[symLayerProp, $layer]; [] _ CDProperties.RegisterProperty[symOwnerProp, $atom]; CDProperties.InstallProcs[prop: symOwnerProp, new: [makeCopy: CDProperties.CopyVal]]; CDProperties.InstallProcs[prop: symLayerProp, new: [makeCopy: CDProperties.CopyVal]]; }; CreateMark: PUBLIC PROC [dummySize: CD.Number_0] RETURNS [CD.Object] = { RETURN [markObject] }; CreateSegment: PUBLIC PROC [length: CD.Number, dummyWidth: CD.Number_0] RETURNS [ob: CD.Object] = { used: REF; insert: BOOL; ob _ GiveSegment[]; IF dummyWidth<=0 THEN dummyWidth _ 8; ob.size _ CDBasics.MaxPoint[[dummyWidth, length], [1, 1]]; [insert: insert, used: used] _ LRUCache.Include[lruQueue, ob]; IF ~insert THEN { freeSegment _ ob; ob _ NARROW[used]; }; }; RCreateSegment: PROC [size: CD.Position, l: CD.Layer] RETURNS [CD.Object] = { RETURN [CreateSegment[size.y, size.x]] }; CreatePin: PUBLIC PROC [size: CD.Position] RETURNS [ob: CD.Object] = { used: REF; insert: BOOL; ob _ GivePin[]; ob.size _ CDBasics.MaxPoint[size, [1, 1]]; [insert: insert, used: used] _ LRUCache.Include[lruQueue, ob]; IF ~insert THEN { freePin _ ob; ob _ NARROW[used]; }; }; RCreatePin: PROC [size: CD.Position, l: CD.Layer] RETURNS [CD.Object] = { RETURN [CreatePin[size]] }; IsSymbolicOb: PUBLIC PROC [ob: CD.Object] RETURNS [BOOL] = { RETURN [ob.class=markClass OR ob.class=segmentClass OR ob.class=pinClass] }; IsMark: PUBLIC PROC [ob: CD.Object] RETURNS [BOOL] = { RETURN [ob.class=markClass] }; IsSegment: PUBLIC PROC [ob: CD.Object] RETURNS [BOOL] = { RETURN [ob.class=segmentClass] }; IsPin: PUBLIC PROC [ob: CD.Object] RETURNS [BOOL] = { RETURN [ob.class=pinClass] }; SymbolicKind: PUBLIC PROC [ob: CD.Object] RETURNS [k: CDSymbolicObjects.Kind] = { SELECT TRUE FROM ob.class=pinClass => k _ pin; ob.class=segmentClass => k _ segment; ob.class=markClass => k _ mark; ENDCASE => k _ notSymbolic }; SetOwner: PUBLIC PROC [symInst: CD.Instance, owner: ATOM_NIL] = { IF IsSymbolicOb[symInst.ob] THEN CDProperties.PutInstanceProp[symInst, symOwnerProp, owner] }; GetOwner: PUBLIC PROC [symInst: CD.Instance] RETURNS [at: ATOM] = { WITH CDProperties.GetInstanceProp[symInst, symOwnerProp] SELECT FROM a: ATOM => at _ a ENDCASE => at _ NIL }; SetName: PUBLIC PROC [symInst: CD.Instance, name: Rope.ROPE] = { IF IsSymbolicOb[symInst.ob] THEN CDProperties.PutInstanceProp[symInst, symNameProp, name] }; GetName: PUBLIC PROC [symInst: CD.Instance] RETURNS [r: Rope.ROPE _ NIL] = { IF IsSymbolicOb[symInst.ob] THEN { WITH CDProperties.GetInstanceProp[symInst, symNameProp] SELECT FROM n: Rope.ROPE => r _ n; rt: REF READONLY TEXT => r _ Rope.FromRefText[rt]; ENDCASE => NULL; } }; SetLayer: PUBLIC PROC [symInst: CD.Instance, layer: CD.Layer] = { IF IsSymbolicOb[symInst.ob] THEN CDProperties.PutInstanceProp[symInst, symLayerProp, CDPrivate.layers[layer]] }; GetLayer: PUBLIC PROC [symInst: CD.Instance] RETURNS [layer: CD.Layer] = { WITH CDProperties.GetInstanceProp[symInst, symLayerProp] SELECT FROM lp: CDPrivate.LayerRef => layer _ lp^.number ENDCASE => layer _ CD.undefLayer }; DirectionFromOrient: PUBLIC PROC [o: CD.Orientation] RETURNS [dir: CDSymbolicObjects.Direction] = { SELECT o FROM CDOrient.original, CDOrient.rotate180X => dir _ west; CDOrient.rotate90, CDOrient.rotate90X => dir _ south; CDOrient.rotate180, CDOrient.mirrorX => dir _ east; CDOrient.rotate270, CDOrient.rotate270X => dir _ north; ENDCASE => ERROR; }; OrientFromDirection: PUBLIC PROC [dir: CDSymbolicObjects.Direction] RETURNS [o: CD.Orientation] = { SELECT dir FROM west => o _ CDOrient.original; south => o _ CDOrient.rotate90; east => o _ CDOrient.rotate180; north => o _ CDOrient.rotate270; ENDCASE => ERROR; }; CreateSymInst: PUBLIC PROC [name: Rope.ROPE, denotes: CD.Rect, dummySize: CD.Number, layer: CD.Layer, owner: ATOM, approachFrom: CDSymbolicObjects.Direction] RETURNS [symInst: CD.Instance] = { symOb: CD.Object; orient: CD.Orientation _ OrientFromDirection[approachFrom]; loc: CD.Position; denotes _ CDBasics.NormalizeRect[denotes]; IF denotes.x1#denotes.x2 AND denotes.y1#denotes.y2 THEN { loc _ CDBasics.BaseOfRect[denotes]; symOb _ CreatePin[CDOrient.OrientedSize[CDBasics.SizeOfRect[denotes], orient]]; } ELSE IF denotes.x1=denotes.x2 AND denotes.y1=denotes.y2 THEN { p: CD.Position; symOb _ CreateMark[dummySize]; p _ CDOrient.MapPoint[ pointInCell: [0, 0], cellSize: symOb.size, cellInstOrient: orient, cellInstPos: [0, 0] ]; loc _ [x: denotes.x1-p.x, y: denotes.y1-p.y]; } ELSE { l: CD.Number; IF denotes.x1=denotes.x2 THEN { l _ denotes.y2-denotes.y1; IF approachFrom=south OR approachFrom=north THEN { approachFrom _ west; orient _ OrientFromDirection[approachFrom]; } } ELSE { l _ denotes.x2-denotes.x1; IF approachFrom=west OR approachFrom=east THEN { approachFrom _ south; orient _ OrientFromDirection[approachFrom]; } }; symOb _ CreateSegment[length: l, dummyWidth: dummySize]; loc _ CDBasics.BaseOfRect[denotes]; SELECT approachFrom FROM west, south => NULL; east => loc.x _ loc.x-symOb.size.x; north => loc.y _ loc.y-symOb.size.x; ENDCASE => ERROR; }; layer _ CDLayers.AbstractToPaint[layer]; symInst _ CDInstances.NewInst[ob: symOb, location: loc, orientation: orient]; IF name#NIL THEN SetName[symInst, name]; IF layer#CD.undefLayer THEN SetLayer[symInst, layer]; IF owner#NIL THEN SetOwner[symInst, owner]; }; Denotes: PUBLIC PROC [symInst: CD.Instance] RETURNS [CD.Rect] = { itemInCell: CD.Rect; SELECT TRUE FROM symInst.ob.class=pinClass => itemInCell _ [x1: 0, y1: 0, x2: symInst.ob.size.x, y2: symInst.ob.size.y]; symInst.ob.class=segmentClass => itemInCell _ [x1: 0, y1: 0, x2: 0, y2: symInst.ob.size.y]; symInst.ob.class=markClass => itemInCell _ [0, 0, 0, 0]; ENDCASE => ERROR; RETURN [CDOrient.MapRect[ itemInCell: itemInCell, cellInstPos: symInst.location, cellSize: symInst.ob.size, cellInstOrient: symInst.orientation ]] }; EnumerateSymbolicObs: PUBLIC PROC [cellOb: CD.Object_NIL, eachInst: CDSymbolicObjects.InstEnumerator] RETURNS [quit: BOOL_FALSE] = { cp: CD.CellPtr; WITH cellOb.specificRef SELECT FROM c: CD.CellPtr => cp _ c; ip: CDImports.ImportPtr => { -- HACK? until imports handle symbolic objects more reasonably IF ip.boundInstance=NIL THEN RETURN [TRUE]; quit _ EnumerateSymbolicObs[ip.boundInstance.ob, eachInst]; RETURN }; ENDCASE => RETURN [TRUE]; FOR list: CD.InstanceList _ cp.contents, list.rest WHILE (list#NIL AND ~quit) DO IF IsSymbolicOb[list.first.ob] THEN { quit _ eachInst[list.first]; -- do NOT catch errors }; ENDLOOP; }; FindSymbolicObs: PUBLIC PROC [cellOb: CD.Object_NIL, name: Rope.ROPE] RETURNS [il: CD.InstanceList_NIL] = { Enumerate: CDSymbolicObjects.InstEnumerator = { IF Rope.Equal[GetName[inst], name] THEN il _ CONS[inst, il]; }; [] _ EnumerateSymbolicObs[cellOb, Enumerate]; }; WritePinOrSegment: CD.InternalWriteProc -- PROC [me: Object] -- = { CDIO.WritePos[me.size]; }; WriteMark: CD.InternalWriteProc --PROC [me: Object]-- = { }; ReadPin: CD.InternalReadProc --PROC [] RETURNS [Object]-- = { RETURN [CreatePin[CDIO.ReadPos[]]] }; ReadSegment: CD.InternalReadProc --PROC [] RETURNS [Object]-- = { p: CD.Position _ CDIO.ReadPos[]; RETURN [CreateSegment[p.y, p.x]] }; ReadMark: CD.InternalReadProc --PROC [] RETURNS [Object]-- = { RETURN [markObject] }; DescribeInstance: PROC[i: CD.Instance] RETURNS [Rope.ROPE] = { RETURN [Rope.Cat[CDOps.LayerName[GetLayer[i]], " ", i.ob.class.description]]; }; ShowSelectedSymRL: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = { pr.drawRect[CDOrient.RectAt[pos, inst.ob.size, orient], CD.shadeLayer, pr] }; DrawPin: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = { DrawPinInContext: PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer] = { Imager.MaskVector[context, [0, 0], [ob.size.x, ob.size.y]]; Imager.MaskVector[context, [0, ob.size.y], [ob.size.x, 0]]; }; IF pr.symbolics AND (pr.scaleHint*MIN[inst.ob.size.y, inst.ob.size.x]>3 OR pr.scaleHint<=0) THEN { pr.drawContext[pr, DrawPinInContext, inst.ob, pos, orient, pinLayer]; pr.drawComment[r: CDOrient.RectAt[pos, inst.ob.size, orient], comment: GetName[inst], pr: pr] }; }; DrawSegment: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = { DrawSegmentInContext: PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer] = { Imager.MaskVector[context, [0, 0], [0, ob.size.y]]; Imager.MaskVector[context, [0, 0], [ob.size.x, ob.size.y/2]]; Imager.MaskVector[context, [0, ob.size.y], [ob.size.x, ob.size.y/2]]; }; IF pr.symbolics AND (pr.scaleHint*inst.ob.size.y>3 OR pr.scaleHint<=0) THEN { pr.drawContext[pr, DrawSegmentInContext, inst.ob, pos, orient, segmentLayer]; pr.drawComment[r: CDOrient.RectAt[pos, inst.ob.size, orient], comment: GetName[inst], pr: pr] } }; DrawMark: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = { DrawPath: PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer] = { Imager.MaskFillTrajectory[context, markObjectPath]; }; IF pr.symbolics AND (pr.scaleHint*inst.ob.size.y>2 OR pr.scaleHint<=0) THEN { pr.drawContext[pr, DrawPath, markObject, pos, orient, markLayer] } }; Init[]; END. ŽCDSymbolicObjectsImpl.mesa (part of ChipNDale) Copyright c 1984, 1986 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, August 8, 1984 12:41:50 pm PDT Last Edited by: Christian Jacobi, August 16, 1986 6:32:13 pm PDT --rects --lines --points --common --has the right form for CDRects type --pin --mark --segment -- erroneous parameters.. -- erroneous parameters.. Κ;˜codešœ/™/Kšœ Οmœ7™BKšœ=™=K™@—K˜šΟk ˜ Kšžœ˜K˜ K˜ Kšœ žœ!˜/Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜K˜ K˜ K˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜—K˜šΠblœžœžœ˜(Kšžœžœ~˜ˆKšžœ˜Kšžœ˜—Kšž˜K˜Kšœ žœ˜ Kšœžœ˜"Kšœžœ˜"K˜šœ žœ˜Kšœ?˜?—K˜šœžœ žœ ˜(Kšœžœžœ žœ˜(K˜—Kšœ ž œ žœ žœ˜AKšœž œ žœ žœ˜IKšœ žœ žœ ˜$K˜KšœG˜GK˜Kšœ žœ žœΟc˜7Kšœ žœ žœ˜K˜š Οnœžœžœžœžœ žœ˜9Kšœžœ˜šžœžœžœ˜KšœžœžœK˜V—K˜—K˜š ‘ œžœžœžœžœ žœ˜=Kšœ žœ˜$šžœžœžœ˜KšœžœžœS˜^—K˜—K˜š ‘œžœžœžœžœ˜)Kšœžœ žœ˜Kšœžœ žœ˜Kšžœžœžœ˜JKšœ˜—K˜šœ žœžœžœ˜CKšœ˜Kšœ˜Kšœ"˜"Kšœ˜Kšœ!˜!Kšœ žœ˜Kšœ žœ˜Kšœ˜Kšœ˜Kšœ˜—šœžœžœžœ(˜PKšœ˜Kšœ˜Kšœ"˜"Kšœ˜Kšœ!˜!Kšœ žœ˜Kšœ žœ˜Kšœ˜Kšœ˜Kšœ˜—šœ žœžœžœ(˜MKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ žœ˜Kšœ˜Kšœ˜K˜—š‘œžœžœ,˜QKšœ+˜+Kšœ;˜;Kšœ;˜;Kšœ;˜;Kšœ;˜;Kšœ;˜;Kšœ;˜;Kšœ;˜;Kšœ˜—K˜š‘œžœ˜Kšœ™Kšœ ˜ Kšœ8˜8Kšœ™Kšœ$˜$KšœD˜DKšœ™šœ žœžœ˜!Kšœ˜K˜ Kšœ˜Kšœ˜Kšœ˜—Kšœ™Kšœ9˜9Kšœ8˜8KšœU˜UKšœU˜UKšœ˜—K˜š ‘ œžœžœ žœ žœžœ ˜HJšžœ ˜Kšœ˜—K˜š‘ œžœžœ žœžœ žœžœ ˜cKšœžœ žœ˜Kšœ˜Kšžœžœ˜%Kšœ:˜:Kšœ>˜>šžœ žœ˜Kšœ˜Kšœžœ˜K˜—Kšœ˜K˜—š ‘œžœžœžœžœžœ ˜MKšžœ ˜&Kšžœ˜—K˜š ‘ œžœžœžœ žœžœ ˜FKšœžœ žœ˜Kšœ˜Kšœ*˜*Kšœ>˜>šžœ žœ˜Kšœ ˜ Kšœžœ˜K˜—Kšœ˜K˜—š ‘ œžœžœžœžœžœ ˜IK™%Kšžœ˜Kšœ˜—K˜š ‘ œžœžœžœ žœžœ˜Jšœ™Jšœ˜Jšœ˜šœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜J˜—Jšœ-˜-J˜—šžœ˜Jšœ ™ Jšœžœ˜ šžœžœ˜Jšœ˜šžœžœžœ˜2J™Jšœ˜Jšœ+˜+J˜—Jšœ˜—šžœ˜Jšœ˜šžœžœžœ˜0J™Jšœ˜Jšœ+˜+J˜—J˜—Jšœ9˜9Jšœ#˜#šžœž˜Jšœžœ˜Jšœ$˜$Jšœ$˜$Jšžœžœ˜—J˜—Kšœ(˜(KšœM˜MKšžœžœžœ˜(Kšžœžœ žœ˜5Kšžœžœžœ˜+Kšœ˜—K˜š ‘œžœžœ žœ žœžœ ˜AKšœ žœ˜šžœžœž˜Kšœg˜gKšœ[˜[Kšœ8˜8Kšžœžœ˜—šžœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ#˜#Kšœ˜—Kšœ˜—K™š‘œžœžœ žœžœ.žœžœžœ˜„Kšœžœ ˜šžœžœž˜#Kšœžœ˜šœ >˜[Kš žœžœžœžœžœ˜+Kšœ;˜;Kšž˜Kšœ˜—Kšžœžœžœ˜—š žœžœ'žœžœžœž˜Pšžœžœ˜%Kšœ ˜3K˜—Kšžœ˜—Kšœ˜—K˜š‘œžœžœ žœžœ žœžœžœžœ˜kšΠbn œ&˜/Kšžœ!žœžœ ˜Kšžœ ˜Kšœ˜K˜—š ‘œžœžœ žœžœ˜>KšžœG˜MKšœ˜—K˜š ‘œžœžœžœžœžœ ˜iKšœ8žœ˜JKšœ˜—K˜š ‘œžœžœžœžœ ˜KKšœžœ ˜š‘œžœžœžœ ˜TKšœ;˜;Kšœ;˜;Kšœ˜—š žœžœžœ#žœžœ˜bKšœE˜EKšœ]˜]K˜—Kšœ˜—K˜š ‘ œžœžœžœžœ ˜OKšœžœ ˜š‘œžœžœžœ ˜XKšœ3˜3Kšœ=˜=KšœE˜EKšœ˜—šžœžœ žœžœ˜MKšœM˜MKšœ]˜]K˜—Kšœ˜—K˜š ’œžœžœžœžœ ˜LKšœžœ ˜š‘œžœžœžœ ˜LKšœ3˜3Kšœ˜—šžœžœ žœžœ˜NKšœ@˜@K˜—Kšœ˜—K˜Kšœ˜Kšžœ˜K˜—…—0άB₯