<> <> <> <> DIRECTORY CD, CDAtomicObjects, CDBasics, CDCells, CDCellsInteractions, CDCommandOps, CDDirectory, CDDirectoryOps, CDImports, CDOps, CDCurves, CDProperties, CDRects, CDSequencer, CDSymbolicObjects, CDTexts, CDViewer, RefTab, Rope, TerminalIO; CDConvertTechnologies: CEDAR PROGRAM IMPORTS CD, CDBasics, CDAtomicObjects, CDCellsInteractions, CDCells, CDCommandOps, CDDirectory, CDDirectoryOps, CDImports, CDOps, CDCurves, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CDViewer, RefTab, TerminalIO = BEGIN <<>> <<--MUST BE SETUP USING INTERPRETER>> fromTechnologyKey: ATOM_NIL; toTechnologyKey: ATOM_NIL; layerConversion: RefTab.Ref; -- layerkey => layerkey classConversion: RefTab.Ref; -- object class key => key for atomic objects classPosOffsets: RefTab.Ref; -- old object class key => CD.Position [offset in old coord system] classSizeOffsets: RefTab.Ref; -- old object class key => CD.Position [offset in old coord system] <<--must be protected>> correspondKey: REF INT; design: CD.Design; newDesign: CD.Design; lambda: CD.Number; newLambda: CD.Number; oldTech: CD.Technology; newTech: CD.Technology; TRect: PROC [rect: CD.Rect] RETURNS [r: CD.Rect] = { r _ [x1: rect.x1*newLambda/lambda, x2: rect.x2*newLambda/lambda, y1: rect.y1*newLambda/lambda, y2: rect.y2*newLambda/lambda] }; TPos: PROC [pos: CD.Position] RETURNS [p: CD.Position] = { p _ [pos.x*newLambda/lambda, pos.y*newLambda/lambda] }; TNum: PROC [n: CD.Number] RETURNS [CD.Number] = { RETURN [n*newLambda/lambda] }; SizeOffset: PROC [oldOb: CD.Object] RETURNS [s: CD.Position_[0, 0]] = { IF classSizeOffsets#NIL THEN WITH RefTab.Fetch[classSizeOffsets, oldOb.class.objectType].val SELECT FROM p: REF CD.Position => s _ p^; ENDCASE => NULL; }; MustOffsetOrigin: PROC [oldOb: CD.Object] RETURNS [off: CD.Position _ [0, 0]] = { <<--off in old coord system >> IF classPosOffsets#NIL THEN WITH RefTab.Fetch[classPosOffsets, oldOb.class.objectType].val SELECT FROM p: REF CD.Position => off _ p^; ENDCASE => NULL; }; OriginPos: PROC [i: CD.Instance, point: CD.Position _ [0, 0]] RETURNS [p: CD.Position] = { <<--point in origin coordinates of object i.ob is returned in world coordinates >> RETURN [CDBasics.MapPoint[ pointInCell: point, cellInWorld: i.trans ]] }; CorrespondingLayer: PROC [layer: CD.Layer] RETURNS [l: CD.Layer] = { key: ATOM _ CD.LayerKey[layer]; WITH RefTab.Fetch[layerConversion, key].val SELECT FROM a: ATOM => l _ CD.FetchLayer[newTech, a]; ENDCASE => { IF CD.LayerTechnology[layer]=NIL THEN RETURN [layer]; l _ CD.FetchLayer[newTech, CD.LayerKey[layer]] } }; TransferAny: PROC [ob: CD.Object] RETURNS [new: CD.Object_NIL] = { WITH CDProperties.GetProp[ob, correspondKey] SELECT FROM ob1: CD.Object => RETURN [ob1]; ENDCASE => NULL; IF CDAtomicObjects.IsAtomicOb[ob] THEN new _ TransferAtomicObject[ob] ELSE IF CDCells.IsCell[ob] THEN new _ TransferCell[ob] ELSE IF ob.class.wireTyped THEN new _ TransferWire[ob] ELSE IF CDSymbolicObjects.IsMark[ob] THEN new _ CDSymbolicObjects.CreateMark[] ELSE IF CDTexts.IsText[ob] THEN new _ TransferText[ob] ELSE IF CDImports.IsImport[ob] THEN new _ TransferImport[ob] ELSE IF CDCurves.IsPolygon[ob] THEN new _ TransferPolygon[ob] ELSE IF CDCurves.IsLine[ob] THEN new _ TransferLine[ob] ELSE IF CDCurves.IsSpline[ob] THEN new _ TransferSpline[ob] ELSE IF CDCurves.IsFilledCurve[ob] THEN new _ TransferFilledCurve[ob]; IF new=NIL THEN new _ TransferHard[ob]; IF new=NIL THEN TerminalIO.PutRope["unknown object type\n"] ELSE { name: Rope.ROPE _ CDDirectory.Name[ob, design]; IF name#NIL THEN [] _ CDDirectory.Include[newDesign, new, name] } }; GetAtomKey: PROC [a: ATOM] RETURNS [ATOM] = { WITH RefTab.Fetch[classConversion, a].val SELECT FROM aa: ATOM => RETURN [aa]; ENDCASE => RETURN [NIL]; }; TransferAtomicObject: PROC [ob: CD.Object] RETURNS [new: CD.Object_NIL] = { newKey: ATOM _ GetAtomKey[ob.class.objectType]; sz: CD.Position _ CD.InterestSize[ob]; sz _ TPos[CDBasics.AddPoints[sz, SizeOffset[ob]]]; IF newKey#NIL THEN { new _ CDAtomicObjects.CreateAtomicOb[newKey, sz, newTech, CorrespondingLayer[ob.layer]]; } }; TransferHard: PROC [ob: CD.Object] RETURNS [new: CD.Object_NIL] = { ob1: CD.Object _ CDDirectory.Expand1[ob, NIL, design].new; IF ob1=NIL OR ob1=ob THEN ob1 _ CDDirectory.Expand1ByDraw[ob]; IF ob1#NIL THEN { new _ TransferWithChildrenCheck[ob1]; CDProperties.PutProp[ob, correspondKey, CDProperties.GetProp[ob1, correspondKey]]; } }; TransferWire: PROC [ob: CD.Object] RETURNS [new: CD.Object] = { new _ CDRects.CreateRect[TPos[CD.InterestSize[ob]], CorrespondingLayer[ob.layer]] }; TransferText: PROC [ob: CD.Object] RETURNS [new: CD.Object] = { tp: CDTexts.TextSpecific _ NARROW[ob.specific]; font: CDTexts.CDFont; font _ CDTexts.MakeFont[name: tp.cdFont.supposedName, scale: TNum[tp.cdFont.scaleI]]; new _ CDTexts.Create[text: tp.text, font: font, layer: CorrespondingLayer[ob.layer], flip: CDTexts.IsFlipText[ob]]; }; TransferImport: PROC [ob: CD.Object] RETURNS [new: CD.Object] = { <<--dirty>> ip: CDImports.ImportSpecific _ NARROW[ob.specific]; newIp: CDImports.ImportSpecific _ NEW[CDImports.ImportRep_[ir: TRect[ip.ir], objectName: ip.objectName, designName: ip.designName]]; new _ NEW[CD.ObjectRep_ob^]; new.properties _ NIL; new.specific _ newIp; new.bbox _ TRect[new.bbox]; }; TransferPosList: PROC [ob: CD.Object] RETURNS [newPl: LIST OF CD.Position_NIL, w: CD.Number] = { pp: CDCurves.CurveSpecific _ NARROW[ob.specific]; FOR pl: LIST OF CD.Position _ pp.points, pl.rest WHILE pl#NIL DO newPl _ CONS[TPos[pl.first], newPl]; ENDLOOP; w _ pp.w }; TransferPolygon: PROC [ob: CD.Object] RETURNS [new: CD.Object] = { newPl: LIST OF CD.Position; w: CD.Number; [newPl, w] _ TransferPosList[ob]; new _ CDCurves.CreatePolygon[newPl, CorrespondingLayer[ob.layer]].ob; }; TransferLine: PROC [ob: CD.Object] RETURNS [new: CD.Object] = { newPl: LIST OF CD.Position; w: CD.Number; [newPl, w] _ TransferPosList[ob]; new _ CDCurves.CreateLine[newPl, w, CorrespondingLayer[ob.layer]].ob; }; TransferSpline: PROC [ob: CD.Object] RETURNS [new: CD.Object] = { newPl: LIST OF CD.Position; w: CD.Number; [newPl, w] _ TransferPosList[ob]; new _ CDCurves.CreateSpline[newPl, w, CorrespondingLayer[ob.layer]].ob; }; TransferFilledCurve: PROC [ob: CD.Object] RETURNS [new: CD.Object] = { newPl: LIST OF CD.Position; w: CD.Number; [newPl, w] _ TransferPosList[ob]; new _ CDCurves.CreateFilledCurve[newPl, CorrespondingLayer[ob.layer]].ob; }; TransferCell: PROC [ob: CD.Object] RETURNS [new: CD.Object] = { EachInst: CDCells.InstEnumerator = { newChild: CD.Object; copy: CD.Instance; position: CD.Position _ TPos[OriginPos[inst, MustOffsetOrigin[inst.ob]]]; newChild _ TransferAny[inst.ob]; IF newChild#NIL THEN { copy _ CDCells.IncludeOb[design: NIL, cell: new, ob: newChild, trans: [position, inst.trans.orient], mode: dontResize].newInst; CDProperties.AppendProps[winner: copy.properties, looser: inst.properties, putOnto: copy]; } }; cp: CD.CellSpecific _ NARROW[ob.specific]; new _ CDCells.CreateEmptyCell[]; [] _ CDCells.EnumerateInstances[ob, EachInst]; IF cp.specifiedIr THEN CDCells.SetInterestRect[NIL, new, TRect[cp.ir]]; [] _ CDCells.ResizeCell[NIL, new]; CDProperties.AppendProps[winner: new.properties, looser: ob.properties, putOnto: new]; [] _ CDCells.SetSimplificationTreshhold[new]; }; ReallyTransfer: PROC [ob: CD.Object] RETURNS [ob1: CD.Object] = { <<--all children of ob are already transfereed>> ob1 _ TransferAny[ob] }; TransferWithChildrenCheck: PROC [ob: CD.Object] RETURNS [ob1: CD.Object] = { EachChild: PROC [me: CD.Object, data: REF] RETURNS [quit: BOOL_FALSE] = { [] _ TransferWithChildrenCheck[me]; }; WITH CDProperties.GetProp[ob, correspondKey] SELECT FROM obx: CD.Object => ob1 _ obx; ENDCASE => { [] _ CDDirectory.EnumerateChildObjects[ob, EachChild, NIL]; ob1 _ ReallyTransfer[ob]; CDProperties.PutProp[ob, correspondKey, ob1] }; }; Transfer: PROC [from: CD.Design, tech: CD.Technology] RETURNS [nD: CD.Design] = { EachDirEl: PROC [name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOL_FALSE] = { [] _ TransferWithChildrenCheck[ob]; }; dummyOb, newDummyOb: CD.Object; design _ from; correspondKey _ NEW[INT]; oldTech _ from.technology; newTech _ tech; newDesign _ nD _ CDOps.CreateDesign[tech]; dummyOb _ CDCellsInteractions.MakeTopInstance[from].ob; lambda _ oldTech.lambda; newLambda _ newTech.lambda; [] _ CDDirectory.Enumerate[design: from, action: EachDirEl]; newDummyOb _ TransferWithChildrenCheck[dummyOb]; [] _ CDCells.IncludeOb[design: newDesign, ob: newDummyOb]; CDDirectoryOps.RemoveProperties[from, correspondKey]; }; ProtectedTransferComm: PROC [comm: CDSequencer.Command] = { t: CD.Technology; d: CD.Design; TerminalIO.PutRope["transfer technology\n"]; IF comm.design.technology.key#fromTechnologyKey THEN { TerminalIO.PutRope["not right ""from"" technology set up\n"]; ERROR ABORTED }; t _ CD.FetchTechnology[toTechnologyKey]; IF t=NIL THEN { TerminalIO.PutRope["the ""to"" technology is not loaded\n"]; ERROR ABORTED }; [] _ CDDirectoryOps.CleanUp[comm.design]; d _ Transfer[comm.design, t]; [] _ CDViewer.CreateViewer[d]; }; TransferComm: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["transfer technology\n"]; TerminalIO.PutRope["Has not been checked for this release\n"]; [] _ CDCommandOps.DoWithResource[ proc: ProtectedTransferComm, comm: comm, resource: $CDTransferTecnology ]; }; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "convert technology", proc: TransferComm, key: $CDConvertTechnologiesX, doc: "MUST set up technologies with command file first"]; END.