DIRECTORY CD, CDBasics, CDCallSpecific, CDDirectory, CDIO, CDOrient, CDProperties, CDRepetitions, CDInterestRects, TokenIO; CDRepetitionsImpl: CEDAR PROGRAM IMPORTS CD, CDRepetitions, CDBasics, CDCallSpecific, CDDirectory, CDIO, CDOrient, CDProperties, TokenIO, CDInterestRects EXPORTS CDRepetitions SHARES CDDirectory = BEGIN OldSetInterest: PROC [ob: CD.Object, r: CD.Rect] = BEGIN cptr: RepPtr = NARROW[ob.specificRef]; cptr.ir _ r; END; RepPtr: TYPE = CDRepetitions.RepPtr; RepRec: TYPE = CDRepetitions.RepRec; pForRepetitions: REF CD.ObjectClass = CD.RegisterObjectClass[$Repetitions]; ComputeBoundsR: PROC [ob: CD.Object] RETURNS [CD.Rect] = BEGIN rp: RepPtr = NARROW[ob.specificRef]; sz: CD.Position = CDOrient.OrientedSize[rp.ob.size, rp.orientation]; toffset: CD.Position = [(rp.count-1)*rp.offset.x, (rp.count-1)*rp.offset.y]; r1: CD.Rect = CDBasics.RectAt[rp.offsetOfFirst, sz]; r2: CD.Rect = CDBasics.RectAt[CDBasics.AddPoints[rp.offsetOfFirst, toffset], sz]; RETURN CDBasics.Surround[r1, r2]; END; InternalCreateRepetition: PROC [ob: CD.Object, count: NAT, offset: CD.Position, orientation: CD.Orientation] RETURNS [CD.Object] = BEGIN repOb: CD.Object = NEW[CD.ObjectRep]; rp: RepPtr = NEW[RepRec]; sz: CD.Position = CDOrient.OrientedSize[ob.size, orientation]; repOb.class _ pForRepetitions; count _ MAX[1, MIN[count, 512]]; repOb.size.x _ sz.x+(count-1)*ABS[offset.x]; repOb.size.y _ sz.y+(count-1)*ABS[offset.y]; repOb.layer _ ob.layer; rp.ob _ ob; rp.offsetOfFirst _ [0, 0]; IF offset.x<0 THEN rp.offsetOfFirst.x_ -(count-1)*offset.x; IF offset.y<0 THEN rp.offsetOfFirst.y_ -(count-1)*offset.y; rp.orientation _ orientation; rp.offset _ offset; rp.count _ count; repOb.specificRef _ rp; BEGIN iR: CD.Rect _ CDOrient.DeMapRect[ itemInWorld: iR, cellSize: ob.size, cellInstOrient: orientation ]; iR.x2 _ iR.x2+(count-1)*ABS[offset.x]; iR.y2 _ iR.y2+(count-1)*ABS[offset.y]; rp.ir _ iR END; RETURN [repOb]; END; CreateRepetition: PUBLIC PROC [design: CD.Design, ob: CD.Object, count: NAT, offset: CD.Position, orientation: CD.Orientation_0] RETURNS [CD.Object] = BEGIN repOb: CD.Object = InternalCreateRepetition[ob, count, offset, orientation]; [] _ CDDirectory.Include[design, repOb]; RETURN [repOb]; END; DrawMeForRepetitions: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN rptr: RepPtr _ NARROW[inst.ob.specificRef]; rel, sz: CD.Position; o: CD.Orientation _ CDOrient.ComposeOrient[rptr.orientation, orient]; dummyApp: CD.Instance _ NEW[CD.InstanceRep]; xi: REF INT; dummyApp.ob _ rptr.ob; rel _ rptr.offsetOfFirst; sz _ CDOrient.OrientedSize[rptr.ob.size, rptr.orientation]; WITH CDProperties.GetPropFromInstance[inst, $CDxIndex] SELECT FROM intP: REF INT => xi _ intP; ENDCASE => { xi _ NEW[INT]; CDProperties.PutPropOnInstance[inst, $CDxIndex, xi]; WITH CDProperties.GetPropFromInstance[inst, $CDxIndexProperty] SELECT FROM ixP: ATOM => { CDProperties.PutPropOnInstance[inst, ixP, xi]; }; ENDCASE => NULL }; FOR i: INT IN [0..rptr.count) DO r: CD.Rect _ CDOrient.MapRect[ itemInCell: CDBasics.RectAt[rel, sz], cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos ]; IF pr.stopFlag^ THEN EXIT; xi^ _ i; pr.drawChild[dummyApp, CDBasics.BaseOfRect[r], o, pr]; rel _ CDBasics.AddPoints[rel, rptr.offset]; ENDLOOP; END; QuickDrawMeForRepetitions: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN rptr: RepPtr _ NARROW[inst.ob.specificRef]; rel, sz: CD.Position; o: CD.Orientation _ CDOrient.ComposeOrient[rptr.orientation, orient]; dummyApp: CD.Instance _ NEW[CD.InstanceRep]; xi: REF INT; dummyApp.ob _ rptr.ob; rel _ rptr.offsetOfFirst; sz _ CDOrient.OrientedSize[rptr.ob.size, rptr.orientation]; WITH CDProperties.GetPropFromInstance[inst, $CDxIndex] SELECT FROM intP: REF INT => xi _ intP; ENDCASE => { xi _ NEW[INT]; CDProperties.PutPropOnInstance[inst, $CDxIndex, xi]; WITH CDProperties.GetPropFromInstance[inst, $CDxIndexProperty] SELECT FROM ixP: ATOM => { CDProperties.PutPropOnInstance[inst, ixP, xi]; }; ENDCASE => NULL }; FOR i: INT IN [0..rptr.count) DO r: CD.Rect _ CDOrient.MapRect[ itemInCell: CDBasics.RectAt[rel, sz], cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos ]; IF pr.stopFlag^ THEN EXIT; xi^ _ i; rptr.ob.class.quickDrawMe[dummyApp, CDBasics.BaseOfRect[r], o, pr]; rel _ CDBasics.AddPoints[rel, rptr.offset]; ENDLOOP; END; Another: PROC [me: CD.Object, from, to: CD.Design] RETURNS [CD.Object] = BEGIN rp: RepPtr = NARROW[me.specificRef]; RETURN [CreateRepetition[to, rp.ob, rp.count, rp.offset, rp.orientation]] END; IncCount: CDCallSpecific.CallProc -- PROC [design: CD.Design, inst: CD.Instance, x: REF] RETURNS [done: BOOL_TRUE, removeMe: BOOL_FALSE, include: CD.InstanceList_NIL, repaintMe: BOOL_FALSE, repaintInclude: BOOL_FALSE] -- = BEGIN sz: CD.Position _ inst.ob.size; ap: CD.Instance _ NEW[CD.InstanceRep_inst^]; rptr: RepPtr _ NARROW[inst.ob.specificRef]; newOb: CD.Object = CreateRepetition[design, rptr.ob, rptr.count+1, rptr.offset, rptr.orientation]; IF ap.ob.size#newOb.size THEN { relativeNewBound: CD.Rect _ [x1: 0, y1: 0, x2: inst.ob.size.x, y2: inst.ob.size.y]; IF rptr.offset.x>=0 THEN relativeNewBound.x2 _ inst.ob.size.x+rptr.offset.x ELSE relativeNewBound.x1 _ rptr.offset.x; IF rptr.offset.y>=0 THEN relativeNewBound.y2 _ inst.ob.size.y+rptr.offset.y ELSE relativeNewBound.y1 _ rptr.offset.y; ap.location _ CDBasics.BaseOfRect[ CDOrient.MapRect[ itemInCell: relativeNewBound, cellSize: inst.ob.size, cellInstOrient: inst.orientation, cellInstPos: inst.location]]; }; ap.ob _ newOb; include _ LIST[ap]; repaintMe _ TRUE; removeMe _ TRUE; repaintInclude _ TRUE; END; DecCount: CDCallSpecific.CallProc -- PROC [design: CD.Design, inst: CD.Instance, x: REF] RETURNS [done: BOOL_TRUE, removeMe: BOOL_FALSE, include: CD.InstanceList_NIL, repaintMe: BOOL_FALSE, repaintInclude: BOOL_FALSE] -- = BEGIN sz: CD.Position _ inst.ob.size; ap: CD.Instance _ NEW[CD.InstanceRep_inst^]; rptr: RepPtr _ NARROW[inst.ob.specificRef]; newOb: CD.Object = CreateRepetition[design, rptr.ob, rptr.count-1, rptr.offset, rptr.orientation]; IF ap.ob.size#newOb.size THEN { relativeNewBound: CD.Rect _ [x1: 0, y1: 0, x2: inst.ob.size.x, y2: inst.ob.size.y]; IF rptr.offset.x>=0 THEN relativeNewBound.x2 _ inst.ob.size.x-rptr.offset.x ELSE relativeNewBound.x1 _ -rptr.offset.x; IF rptr.offset.y>=0 THEN relativeNewBound.y2 _ inst.ob.size.y-rptr.offset.y ELSE relativeNewBound.y1 _ -rptr.offset.y; ap.location _ CDBasics.BaseOfRect[ CDOrient.MapRect[ itemInCell: relativeNewBound, cellSize: inst.ob.size, cellInstOrient: inst.orientation, cellInstPos: inst.location]]; }; ap.ob _ newOb; include _ LIST[ap]; repaintMe _ TRUE; removeMe _ TRUE; repaintInclude _ TRUE; END; Expand: PROC [me: CD.Object, from, to: CD.Design] RETURNS [CD.Object] = BEGIN RETURN [CDDirectory.ExpandByDraw[me, from, to]]; END; TransformToCell: CDCallSpecific.CallProc -- PROC [design: CD.Design, inst: CD.Instance, x: REF] RETURNS [done: BOOL_TRUE, removeMe: BOOL_FALSE, include: CD.InstanceList_NIL, repaintMe: BOOL_FALSE, repaintInclude: BOOL_FALSE] -- = BEGIN cob: CD.Object _ NIL; IF CDRepetitions.IsRepetition[inst.ob] THEN cob _ Expand[inst.ob, design, design]; done _ cob#NIL; IF done THEN { removeMe _ TRUE; repaintMe _ TRUE; include _ LIST[NEW[CD.InstanceRep _ [ ob: cob, location: inst.location, orientation: inst.orientation, selected: inst.selected, properties: CDProperties.CopyProps[inst.properties] ]]]; repaintInclude _ TRUE; } END; EnumerateRepeatedObjects: PROC [me: CD.Object, p: CDDirectory.EnumerateObjectsProc, x: REF] = BEGIN rptr: RepPtr = NARROW[me.specificRef]; p[rptr.ob, x]; END; ReadRepetition: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN ob: CD.Object = CDIO.ReadObject[]; count: NAT = TokenIO.ReadInt[]; offsetx: INT = TokenIO.ReadInt[]; offsety: INT = TokenIO.ReadInt[]; orientation: CD.Orientation = CDIO.ReadOrientation[]; RETURN [ InternalCreateRepetition[ ob: ob, count: count, offset: [offsetx, offsety], orientation: orientation ]]; END; WriteRepetition: CD.InternalWriteProc -- PROC [me: Object] -- = BEGIN specific: RepPtr = NARROW[me.specificRef]; CDIO.WriteObject[specific.ob]; TokenIO.WriteInt[specific.count]; TokenIO.WriteInt[specific.offset.x]; TokenIO.WriteInt[specific.offset.y]; CDIO.WriteOrientation[specific.orientation]; END; ReplaceDirectChildForReps: CDDirectory.ReplaceDChildsProc = BEGIN AdjustItself: PROC [me: CD.Object] = BEGIN rp: RepPtr = NARROW[me.specificRef]; rp.offsetOfFirst _ [0, 0]; IF rp.offset.x<0 THEN rp.offsetOfFirst.x_ -(rp.count-1)*rp.offset.x; IF rp.offset.y<0 THEN rp.offsetOfFirst.y_ -(rp.count-1)*rp.offset.y; END; found: BOOL _ FALSE; rp: CDRepetitions.RepPtr = NARROW[me.specificRef]; FOR replaceList: CDDirectory.ReplaceList _ replace, replaceList.rest WHILE replaceList#NIL DO rep: REF CDDirectory.ReplaceRec = replaceList.first; IF rep.old=rp.ob THEN { IF rep.newSize#rep.oldSize OR rep.off#[0, 0] THEN { rp.offsetOfFirst _ CDBasics.BaseOfRect[ CDOrient.MapRect[ itemInCell: CDBasics.MoveRect[ [x1: 0, y1: 0, x2: rep.newSize.x, y2: rep.newSize.y], rep.off], cellSize: rep.oldSize, cellInstOrient: rp.orientation, cellInstPos: rp.offsetOfFirst]]; rp.ob _ rep.new; found _ TRUE; EXIT } }; ENDLOOP; IF found THEN { newR: CD.Rect _ ComputeBoundsR[me]; IF newR#CDBasics.RectAt[[0, 0], me.size] THEN { newSize: CD.Position _ CDBasics.SizeOfRect[newR]; oldSize: CD.Position _ me.size; newBase: CD.Position = CDBasics.BaseOfRect[newR]; AdjustItself[me]; me.size _ newSize; IF design#NIL THEN CDDirectory.RepositionObject[ design: design, ob: me, oldSize: oldSize, baseOff: newBase ] } } END; InitRepetitions: PROC [] = BEGIN rp: REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[pForRepetitions]; rp.enumerateChildObjects _ EnumerateRepeatedObjects; rp.replaceDirectChilds _ ReplaceDirectChildForReps; rp.expand _ Expand; rp.another _ Another; pForRepetitions.drawMe _ DrawMeForRepetitions; pForRepetitions.quickDrawMe _ QuickDrawMeForRepetitions; pForRepetitions.internalRead _ ReadRepetition; pForRepetitions.internalWrite _ WriteRepetition; CDInterestRects.InstallOldSetInterest[pForRepetitions, OldSetInterest]; CDCallSpecific.Register[$TransformToCell, pForRepetitions, TransformToCell]; CDCallSpecific.Register[$IncCount, pForRepetitions, IncCount]; CDCallSpecific.Register[$DecCount, pForRepetitions, DecCount]; END; InitRepetitions[]; END. ÆCDRepetitionsImpl.mesa (part of ChipNDale) Copyright c 1983, 1985 by Xerox Corporation. All rights reserved. by Christian Jacobi, October 27, 1983 3:36 pm last edited Christian Jacobi, June 3, 1985 2:51:50 pm PDT --hang two properties on the application; both pointing to the same int containing the --repetition number; --the first property has the name $CDxIndex --the second property name is the value of the property $CDxIndexProperty --do drawing --hang two properties on the application; both pointing to the same int containing the --repetition number; --the first property has the name $CDxIndex --the second property name is the value of the property $CDxIndexProperty --do drawing Ê =˜šœ1™1Jšœ Ïmœ7™BJšœ.™.Jšœ9™9—J˜šÏk ˜ Jšžœ˜Jšœ ˜ Jšœ˜Jšœ ˜ Jšžœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜J˜—šÏbœžœžœ˜!Jšžœžœ8žœ2˜xJšžœ˜Jšžœ˜—Jšž˜J˜šÏnœžœžœ žœ˜2Jšž˜Jšœžœ˜&Jšœ ˜ Jšžœ˜J˜—Jšœžœ˜$Jšœžœ˜$J˜Jšœžœžœžœ#˜KJ˜š Ðbnœžœžœ žœžœ˜8Jšž˜Jšœ žœ˜$Jšœžœ>˜DJšœ žœA˜LJšœžœ.˜4JšœžœK˜QJšžœ˜!Jšžœ˜—J˜š œžœžœžœ žœžœžœžœ ˜‚Jšž˜Jšœžœ žœžœ ˜%Jšœ žœ ˜Jšœžœ8˜>Jšœ˜Jšœžœžœ˜ Jšœžœ ˜,Jšœžœ ˜,Jšœ˜Jšœ ˜ Jšœ˜Jšžœ žœ)˜;Jšžœ žœ)˜;Jšœ˜Jšœ˜Jšœ˜Jšœ˜šž˜šœžœ˜!Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœžœ ˜&Jšœžœ ˜&Jšœ ˜ Jšžœ˜—Jšžœ ˜Jšžœ˜—J˜š œžœžœ žœ žœžœ žœžœžœžœ ˜–Jšž˜JšœžœC˜LJšœ(˜(Jšžœ ˜Jšžœ˜—J˜š  œžœžœžœžœ ˜XJšœžœ ˜Jšž˜Jšœžœ˜+Jšœ žœ ˜Jšœžœ@˜EJšœ žœ žœžœ˜,Jšœžœžœ˜ Jšœ˜Jšœ˜Jšœ;˜;JšœW™WJšœ™Jšœ+™+JšœJ™Jšžœ3žœž˜BJšœžœžœ˜šžœ˜ Jšœžœžœ˜Jšœ4˜4šžœ;žœž˜Jšœžœ˜Jšœ.˜.Jšœ˜—Jšžœž˜—J˜——Jšœ ™ šžœžœžœž˜ šœžœ˜Jšœ'˜'Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšžœžœžœ˜Jšœ˜Jšœ6˜6Jšœ+˜+Jšžœ˜—Jšžœ˜—J˜š  œžœžœžœžœ ˜]Jšœžœ ˜Jšž˜Jšœžœ˜+Jšœ žœ ˜Jšœžœ@˜EJšœ žœ žœžœ˜,Jšœžœžœ˜ Jšœ˜Jšœ˜Jšœ;˜;JšœW™WJšœ™Jšœ+™+JšœJ™Jšžœ3žœž˜BJšœžœžœ˜šžœ˜ Jšœžœžœ˜Jšœ4˜4šžœ;žœž˜Jšœžœ˜Jšœ.˜.Jšœ˜—Jšžœž˜—J˜——Jšœ ™ šžœžœžœž˜ šœžœ˜Jšœ'˜'Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšžœžœžœ˜Jšœ˜JšœC˜CJšœ+˜+Jšžœ˜—Jšžœ˜—J˜š  œžœžœžœ žœžœ ˜HJšž˜Jšœ žœ˜$JšžœC˜IJšžœ˜—J˜šŸœ˜!JšÏcºœ˜½Jšž˜Jšœžœ˜Jšœžœ žœžœ˜,Jšœžœ˜+JšœžœY˜bšžœžœ˜Jšœžœ?˜SJšžœžœ4˜LJšžœ%˜)Jšžœžœ4˜LJšžœ%˜)šœ"˜"šœ˜Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜——Jšœ˜—Jšœ˜Jšœ žœ˜Jšœ žœ˜Jšœ žœ˜Jšœžœ˜Jšžœ˜—J˜šŸœ˜!Jš¢ºœ˜½Jšž˜Jšœžœ˜Jšœžœ žœžœ˜,Jšœžœ˜+JšœžœY˜bšžœžœ˜Jšœžœ?˜SJšžœžœ4˜LJšžœ&˜*Jšžœžœ4˜LJšžœ'˜+šœ"˜"šœ˜Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜——Jšœ˜—Jšœ˜Jšœ žœ˜Jšœ žœ˜Jšœ žœ˜Jšœžœ˜Jšžœ˜—J˜š  œžœžœžœ žœžœ ˜GJšž˜Jšžœ*˜0Jšžœ˜—J˜šŸœ˜)Jš¢ºœ˜¼Jšž˜Jšœžœ žœ˜Jšžœ%žœ'˜RJšœ žœ˜šžœžœ˜Jšœ žœ˜Jšœ žœ˜šœ žœžœžœ˜&Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ3˜3Jšœ˜—Jšœžœ˜J˜—Jšžœ˜—J˜š œžœžœ1žœ˜^Jšž˜Jšœžœ˜&Jšœ˜Jšžœ˜—J˜šŸœžœ¢œ˜BJšž˜Jšœžœ žœ˜"Jšœžœ˜Jšœ žœ˜!Jšœ žœ˜!Jšœ žœžœ˜5šžœ˜"Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜—Jšžœ˜—J˜šŸœžœ¢œ˜?Jšž˜Jšœžœ˜*Jšžœ˜Jšœ!˜!Jšœ$˜$Jšœ$˜$Jšžœ(˜,Jšžœ˜—J˜šŸœ"˜;Jšž˜J˜š¡ œžœžœ ˜%Jšž˜Jšœ žœ˜$Jšœ˜Jšžœžœ/˜DJšžœžœ/˜DJšžœ˜—J˜Jšœžœžœ˜Jšœžœ˜2šžœBžœ žœž˜]Jšœžœ,˜4šžœžœ˜šžœžœžœ˜3šœ'˜'šœ˜šœ˜Jšœ?˜?—Jšœ˜Jšœ˜Jšœ ˜ ——Jšœ˜Jšœž˜ Jšž˜J˜—Jšœ˜—Jšžœ˜—šžœžœ˜Jšœ#˜#šžœ'žœ˜/Jšœ žœ&˜1Jšœ žœ˜Jšœ žœ&˜1Jšœ˜Jšœ˜šžœžœž˜šœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜——J˜—J˜—Jšžœ˜—J˜š œžœ˜Jšž˜JšœžœQ˜XJšœ4˜4Jšœ3˜3Jšœ˜Jšœ˜Jšœ.˜.Jšœ8˜8Jšœ.˜.Jšœ0˜0JšœG˜GJšœL˜LJšœ>˜>Jšœ>˜>Jšžœ˜—J˜Jšœ˜Jšžœ˜J˜J˜—…—(Ê8Í