DIRECTORY CD, CDBasics, CDBasicsInline, CDIO, CDLayers, CDPrivate, CDProperties, CDRects, CDOps, CDValue, LRUCache, Rope, SafeStorage, TokenIO; CDRectsAndLayersImpl: CEDAR MONITOR IMPORTS CD, CDBasics, CDBasicsInline, CDIO, CDLayers, CDOps, CDPrivate, CDProperties, CDValue, LRUCache, Rope, SafeStorage EXPORTS CDRects, CDLayers SHARES CD = BEGIN bareRectClass: PUBLIC CD.ObjectClass; wellRectClass: PUBLIC CD.ObjectClass; dummy: CD.RectSpecific = SafeStorage.GetPermanentZone[].NEW[CD.RectRep _ [filler: NIL]]; lruCache: LRUCache.Handle = LRUCache.Create[255, CDPrivate.Hash, CDPrivate.Equal]; freeOb: CD.Object _ NIL; --always rect GiveOb: ENTRY PROC [] RETURNS [ob: CD.Object] = INLINE { ENABLE UNWIND => NULL; ob _ freeOb; freeOb _ NIL; IF ob=NIL THEN ob _ NEW[CD.ObjectRep_[specific: dummy]]; ob.class _ bareRectClass; }; CreateRectProc: TYPE = PROC [size: CD.Position, l: CD.Layer] RETURNS [CD.Object] _ NIL; createRectArray: REF ARRAY CD.Layer OF CreateRectProc = SafeStorage.GetPermanentZone[].NEW[ARRAY CD.Layer OF CreateRectProc]; CreateRect: PUBLIC PROC [size: CD.Position, l: CD.Layer] RETURNS [ob: CD.Object] = { IF createRectArray[l]=NIL THEN { ob _ CreateWellRect[size, l] } ELSE { used: REF; insert: BOOL; ob _ createRectArray[l][size, l]; [insert: insert, used: used] _ LRUCache.Include[lruCache, ob]; IF ~insert THEN ob _ NARROW[used]; ob.immutable _ TRUE; }; }; HangExtensionsOn: PROC[on: CD.ObjectClass] = { IF on.newLayer=NIL THEN on.newLayer _ ChangeLayer }; UseForCreateRect: PUBLIC PROC [layer: CD.Layer, createRect: PROC [size: CD.Position, l: CD.Layer] RETURNS [CD.Object], hangExtensionsOn: CD.ObjectClass ] = { IF createRect=NIL THEN createRect _ IF CDLayers.layerData[layer].well=CD.undefLayer THEN CreateBareRect ELSE CreateWellRect; createRectArray[layer] _ createRect; IF hangExtensionsOn#NIL THEN HangExtensionsOn[hangExtensionsOn]; CDProperties.PutLayerProp[onto: layer, prop: $CDxRectCreation, val: $CDxUser]; }; CreateBareRect: PUBLIC PROC [size: CD.Position, l: CD.Layer] RETURNS [ob: CD.Object] = { used: REF; insert: BOOL; ob _ GiveOb[]; ob.bbox _ CDPrivate.MinBBox[size]; ob.layer _ l; [insert: insert, used: used] _ LRUCache.Include[lruCache, ob]; IF ~insert THEN {freeOb _ ob; ob _ NARROW[used]}; ob.immutable _ TRUE; }; CreateWellRect: PROC [size: CD.Position, l: CD.Layer] RETURNS [ob: CD.Object] = { used: REF; insert: BOOL; wellSurround: INT _ 0; ir: CD.Rect _ CDPrivate.MinBBox[size]; ob _ GiveOb[]; IF CDLayers.layerData[l].well#CD.undefLayer THEN { wellSurround _ CDLayers.layerData[l].wSurr; ob.class _ wellRectClass }; ob.bbox _ CDBasics.Extend[ir, wellSurround]; ob.layer _ l; [insert: insert, used: used] _ LRUCache.Include[lruCache, ob]; IF ~insert THEN {freeOb _ ob; ob _ NARROW[used]}; ob.immutable _ TRUE; }; InitRects: PROC [] = { bareRectClass _ CD.RegisterObjectClass[$Rect, [ drawMe: DrawMeForRects, quickDrawMe: DrawMeForRects, internalRead: ReadRect, internalWrite: WriteRect, newLayer: ChangeLayer, describe: Describe, wireTyped: TRUE ]]; HangExtensionsOn[bareRectClass]; wellRectClass _ CD.RegisterObjectClass[$WellRect, [ drawMe: DrawWellRect, interestRect: InsideWellRect, quickDrawMe: DrawWellRect, internalRead: ReadRect, internalWrite: WriteRect, newLayer: ChangeLayer, describe: Describe, wireTyped: TRUE ]]; HangExtensionsOn[wellRectClass]; [] _ CD.RegisterObjectClass[$SaveRect, [internalRead: ReadRect]];--old stuff }; Describe: CD.DescribeProc = { RETURN [Rope.Concat["rect ", CDOps.LayerRope[ob.layer]]] }; DrawMeForRects: CD.DrawProc = { pr.drawRect[pr, CDBasicsInline.MapRect[ob.bbox, trans], ob.layer] }; DrawWellRect: CD.DrawProc = { r: CD.Rect = CDBasicsInline.MapRect[ob.bbox, trans]; pr.drawRect[pr, CDBasics.Extend[r, -CDLayers.layerData[ob.layer].wSurr], CDLayers.layerData[ob.layer].paint]; pr.drawRect[pr, r, CDLayers.layerData[ob.layer].well]; }; InsideWellRect: PROC [ob: CD.Object] RETURNS [CD.Rect] = { RETURN [CDBasics.Extend[ob.bbox, -CDLayers.layerData[ob.layer].wSurr]] }; ChangeLayer: CD.ChangeLayerProc = { newOb: CD.Object _ CreateRect[CD.InterestSize[inst.ob], layer]; IF newOb#NIL THEN inst.ob _ newOb; RETURN [newOb#NIL]; }; WriteRect: CD.InternalWriteProc = { CDIO.WritePos[h, CD.InterestSize[ob]]; CDIO.WriteLayer[h, ob.layer]; }; ReadRect: CD.InternalReadProc = { sz: CD.Position = CDIO.ReadPos[h]; l: CD.Layer = CDIO.ReadLayer[h]; ob: CD.Object = CreateRect[sz, l]; RETURN [ob] }; LayerData: TYPE = CDLayers.LayerData; DesignNotifyProc: TYPE = CDLayers.DesignNotifyProc; LayerNotifyProc: TYPE = CDLayers.LayerNotifyProc; LayerRec: TYPE = RECORD [w: CD.Number, use: CD.Layer]; GetLayerRec: PROC [design: REF, layer: CD.Layer] RETURNS [REF LayerRec] = { ENABLE UNWIND => NULL; WITH CDValue.Fetch[design, CDPrivate.layers[layer].globalUniqueKey, design] SELECT FROM lr: REF LayerRec => RETURN [lr]; ENDCASE => { lr: REF LayerRec _ NEW[LayerRec]; WITH design SELECT FROM d: CD.Design => lr^ _ GetLayerRec[d.technology, layer]^; t: CD.Technology => lr^ _ GetLayerRec[NIL, layer]^; ENDCASE => lr^ _ [w: 0, use: layer]; [] _ CDValue.StoreConditional[design, CDPrivate.layers[layer].globalUniqueKey, lr]; RETURN [GetLayerRec[design, layer]]; --recursion prevents concurrency problems }; }; CurrentLayer: PUBLIC PROC [design: CD.Design] RETURNS [CD.Layer] = { RETURN [CDValue.FetchInt[design, $CurrentLayer, technology]] }; LayerWidth: PUBLIC PROC [design: CD.Design, layer: CD.Layer] RETURNS [CD.Number] = { RETURN [GetLayerRec[design, layer].w] }; PlaceholderToAbstract: PUBLIC PROC [design: CD.Design, layer: CD.Layer] RETURNS [CD.Layer] = { IF lData[layer].kind=placeholder THEN RETURN [GetLayerRec[design, layer].use]; RETURN [layer]; }; SetCurrentLayer: PUBLIC PROC [design: REF, layer: CD.Layer] = { CDValue.StoreInt[boundTo: design, key: $CurrentLayer, value: layer]; WITH design SELECT FROM d: CD.Design => FOR list: LIST OF DesignNotifyProc _ layerProcList, list.rest WHILE list#NIL DO list.first[d]; ENDLOOP; ENDCASE => NULL; }; SetLayerWidth: PUBLIC PROC [design: REF, layer: CD.Layer, width: CD.Number] = { GetLayerRec[design, layer].w _ width; WITH design SELECT FROM d: CD.Design => FOR list: LIST OF LayerNotifyProc _ widthProcList, list.rest WHILE list#NIL DO list.first[d, layer]; ENDLOOP; ENDCASE => NULL; }; SetPlaceholderToAbstract: PUBLIC PROC [design: REF, placeholder, abstract: CD.Layer] = { IF lData[placeholder].kind#placeholder THEN ERROR; GetLayerRec[design, placeholder].use _ abstract; WITH design SELECT FROM d: CD.Design => FOR list: LIST OF LayerNotifyProc _ placeholderProcList, list.rest WHILE list#NIL DO list.first[d, placeholder]; ENDLOOP; ENDCASE => NULL; }; MakeAbstract: PUBLIC PROC [abstract: CD.Layer, paint: CD.Layer _ CD.undefLayer, well: CD.Layer _ CD.undefLayer, wSurr: BYTE _ 0] = { IF well#CD.undefLayer AND lData[well].kind#paint THEN ERROR; lData[abstract] _ [kind: abstract, paint: paint, well: well, wSurr: wSurr]; }; MakePlaceholder: PUBLIC PROC [placeholder: CD.Layer, defaultsTo: CD.Layer] = { lData[placeholder] _ [kind: placeholder, paint: CD.errorLayer, well: CD.undefLayer, wSurr: 0]; GetLayerRec[NIL, placeholder].use _ defaultsTo; }; MakePaint: PUBLIC PROC [layer: CD.Layer] = { lData[layer] _ [kind: paint, paint: layer, well: CD.undefLayer, wSurr: 0]; GetLayerRec[NIL, layer].use _ layer; }; MakeSuppressIR: PUBLIC PROC [layer: CD.Layer, suppressIR: BOOL _ TRUE] = { lData[layer].suppressIR _ suppressIR; }; RegisterNotifiers: PUBLIC ENTRY PROC [layer: DesignNotifyProc_NIL, width: LayerNotifyProc_NIL, placeholder: LayerNotifyProc_NIL] = { ENABLE UNWIND => NULL; IF layer#NIL THEN layerProcList _ CONS[layer, layerProcList]; IF width#NIL THEN widthProcList _ CONS[width, widthProcList]; IF placeholder#NIL THEN placeholderProcList _ CONS[placeholder, placeholderProcList]; }; lData: REF ARRAY CD.Layer OF LayerData = NEW[ARRAY CD.Layer OF LayerData]; layerData: PUBLIC REF READONLY ARRAY CD.Layer OF LayerData = lData; layerProcList: LIST OF DesignNotifyProc _ NIL; widthProcList: LIST OF LayerNotifyProc _ NIL; placeholderProcList: LIST OF LayerNotifyProc _ NIL; InitLayers: PROC [] = { CDValue.RegisterKey[key: $CurrentLayer]; FOR l: CD.Layer IN CD.Layer DO lData[l] _ [kind: placeholder, paint: CD.commentLayer, well: CD.undefLayer, wSurr: 0]; [] _ CDValue.RegisterKey[CDPrivate.layers[l].globalUniqueKey]; ENDLOOP; }; InitLayers[]; InitRects[]; END. CDRectsAndLayersImpl.mesa (part of ChipNDale) Copyright c 1983, 1987 by Xerox Corporation. All rights reserved. Created by: Christian Jacobi, June 24, 1983 4:58 pm Last edited by: Christian Jacobi, April 1, 1987 5:25:38 pm PST --CDRects --initialized by default --don't cache a second time.. --otherwise do not remember object on freeOb! we don't know its class --CDLayers --design can exceptionally be a technology to set default values --reserve call for CDPanelImpl; otherwise CDPanel gets fooled Κ ˜codešœ/™/Kšœ Οmœ7™BKšœ4™4K™>K˜—šΟk ˜ Kšžœ˜K˜ K˜K˜K˜ K˜ K˜ K˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜—K˜šΟnœžœžœ˜$KšžœžœžœP˜zKšžœ˜Kšžœžœ˜ —Kšž˜K˜KšΠbl ™ K˜Kšœž œ ˜%Kšœž œ ˜%K˜Kš œžœ/žœžœžœ˜XKšœR˜RKšœžœ žœΟc ˜&K˜š Ÿœžœžœžœžœ žœ˜8Kšžœžœžœ˜Kšœžœ˜Kš žœžœžœžœžœ˜8Kšœ˜K˜—K˜Kšœžœžœžœžœžœžœ žœ˜WK˜š œžœžœžœžœ˜8Kš œžœžœžœžœ˜FKšœ™K˜—šŸ œžœžœžœžœžœžœ ˜Tšžœžœžœ˜ Kš‘™Kšœ˜K˜—šžœ˜Kšœžœ žœ˜Kšœ!˜!Kšœ>˜>šžœ žœžœ˜#Kš‘F™F—Kšœžœ˜K˜—Kšœ˜K˜—šŸœžœžœ˜.Kšžœ žœžœ˜1Kšœ˜—K˜šŸœžœžœ žœ˜0Kš œ žœžœžœžœžœ ˜FKšœžœ ˜ Kšœ˜šžœ žœžœ˜Kš œ žœ žœ žœžœ˜e—Kšœ$˜$Kšžœžœžœ$˜@KšœN˜NKšœ˜—K˜šŸœžœžœžœžœžœžœ ˜XKšœžœ žœ˜Kšœ˜Kšœ"˜"Kšœ ˜ Kšœ>˜>Kšžœ žœžœ˜1Kšœžœ˜Kšœ˜K˜—š Ÿœžœžœžœžœžœ ˜QKšœžœ žœžœ˜/Kšœ&˜&Kšœ˜šžœžœ žœ˜2Kšœ+˜+Kšœ˜K˜—Kšœ,˜,Kšœ ˜ Kšœ>˜>Kšžœ žœžœ˜1Kšœžœ˜Kšœ˜K˜—šŸ œžœ˜šœžœ˜/Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ž˜Kšœ˜—Kšœ ˜ šœžœ!˜3Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ž˜Kšœ˜—Kšœ ˜ Kšœžœ:‘ ˜LKšœ˜K˜—šŸœ˜Kšžœ3˜9Kšœ˜—K˜šŸœ˜KšœB˜BKšœ˜K˜—šŸ œ˜Kšœžœ0˜5Kšœm˜mKšœ7˜7Kšœ˜K˜—š Ÿœžœžœ žœžœ ˜:KšžœA˜GKšœ˜K˜—šΠbn œžœ˜#Kšœžœžœ˜?Kšžœžœžœ˜"Kšžœžœ˜Kšœ˜K˜—š’ œžœ˜#Kšžœ žœ˜&Kšžœ˜Kšœ˜—K˜š’œžœ˜!Kšœžœ žœ ˜"Kšœžœ žœ˜ Kšœžœ˜"Kšžœ˜ Kšœ˜—K˜Kš  ™ K˜Kšœ žœ˜%Kšœžœ˜3Kšœžœ˜1K˜Kš œ žœžœžœžœ˜6K˜š Ÿ œžœ žœ žœžœžœ˜KKšžœžœžœ˜šžœHžœž˜WKšœžœ žœ˜ šžœ˜ Kšœžœ žœ ˜!šžœžœž˜Kšœžœ3˜8Kšœžœ!žœ ˜3Kšžœ˜$—KšœS˜SKšžœ‘)˜NK˜——Kšœ˜K˜—š Ÿ œžœžœ žœ žœžœ ˜DKšžœ6˜˜>Kšžœ˜—K˜—K™K˜ K˜ Kšžœ˜K˜K˜—…— Ύ.Χ