CDUtilImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
by Ch. Jacobi, June 10, 1985 12:06:12 pm PDT
last edited Ch. Jacobi, March 25, 1986 5:23:22 pm PST
DIRECTORY
CD,
CDCells,
CDDirectory,
CDCommandOps,
CDInstances,
CDOrient,
CDProperties,
Rope,
CDUtil;
CDUtilImpl: CEDAR PROGRAM
IMPORTS CD, CDCells, CDCommandOps, CDDirectory, CDInstances, CDOrient, CDProperties, Rope
EXPORTS CDUtil =
BEGIN
InstRec: TYPE = CDUtil.InstRec;
Direction: TYPE = CDUtil.Direction;
CreateSimpleCell: PUBLIC PROC [design: CD.Design, contents: LIST OF InstRec, cellName: Rope.ROPENIL, direction: Direction ← right, alignHigh: BOOLFALSE] RETURNS [CD.Object] =
BEGIN
r: CD.Rect ← [0, 0, 0, 0];
c: CD.Object = CDCells.CreateEmptyCell[];
inst: CD.Instance;
pos: CD.Position ← [0, 0];
IF Rope.IsEmpty[cellName] THEN cellName ← "-SimpleCell";
NARROW[c.specificRef, CD.CellPtr].name ← cellName;
FOR list: LIST OF InstRec ← contents, list.rest WHILE list#NIL DO
sz: CD.Position;
IF list.first.ob=NIL THEN LOOP;
sz ← CDOrient.OrientedSize[CD.InterestSize[list.first.ob], list.first.orient];
SELECT direction FROM
right => {pos.x ← r.x2};
left => {pos.x ← r.x1-sz.x};
up  => {pos.y ← r.y2};
down => {pos.y ← r.y1-sz.y};
none => {pos ← [0, 0]};
ENDCASE => ERROR;
IF alignHigh THEN
SELECT direction FROM
right, left => {pos.y ← -sz.y};
up, down => {pos.x ← -sz.x};
none  => {pos ← [-sz.x, -sz.y]};
ENDCASE => ERROR;
inst ← CDCells.IncludeOb[cell: c, ob: list.first.ob,
position: [pos.x+list.first.dX, pos.y+list.first.dY],
orientation: list.first.orient,
cellCSystem: cdCoords,
obCSystem: interrestCoords,
mode: dontPropagate
].newInst;
r ← CDInstances.InstRectI[inst];
IF list.first.properties#NIL THEN CDProperties.AppendProps[inst.properties, list.first.properties, inst];
IF ~Rope.IsEmpty[list.first.name] THEN
CDProperties.PutInstanceProp[inst, $InstanceName, list.first.name];
ENDLOOP;
[] ← CDCells.RepositionCell[c, NIL];
IF design#NIL THEN [] ← CDDirectory.Include[design, c];
RETURN[c]
END;
PartialCopy: PUBLIC PROC [ob: CD.Object, design: CD.Design, instances: LIST OF Rope.ROPENIL, remove: BOOLTRUE, prop: ATOM ← $InstanceName, name: Rope.ROPENIL] RETURNS [copy: CD.Object←NIL] =
--copy the object; creates a cell
--remove TRUE:
--all the instances with property prop are and a value in instances are removed
--remove FALSE:
--only the instances with property prop are and a value in instances are copied
BEGIN
ExpandToCell: PROC [ob: CD.Object, from: CD.Design] RETURNS [cell: CD.Object] = {
--returns cell; however we dont care if cell is in design or not...
tm, cm: CDDirectory.DMode;
cell ← ob;
IF ~CDCells.IsCell[cell] THEN {
[cell, tm, cm] ← CDDirectory.Expand[ob, from, from];
IF cell=NIL OR ~CDCells.IsCell[cell] THEN RETURN [NIL];
IF cm#included THEN
IF ~ CDDirectory.ReplaceChildren[cell, from] THEN RETURN [NIL]
}
};
ShouldCopy: PROC[i: CD.Instance] RETURNS [copy: BOOLTRUE] = {
--accesses parameters of CopyInst
ref: REF = CDProperties.GetInstanceProp[i, prop];
IF ref#NIL THEN {
val: Rope.ROPE = CDCommandOps.ToRope[ref];
FOR rl: LIST OF Rope.ROPE ← instances, rl.rest WHILE rl#NIL DO
IF Rope.Equal[val, rl.first] THEN RETURN [copy ← ~remove];
ENDLOOP
};
copy ← remove
};
cell: CD.Object ← ExpandToCell[ob, design];
--don't care if top level in design; we copy anyway
IF cell#NIL THEN {
newList: CD.InstanceList ← NIL;
cp, newCp: CD.CellPtr;
copy ← CDCells.CreateEmptyCell[];
cp ← NARROW[cell.specificRef];
newCp ← NARROW[copy.specificRef];
copy.size ← cell.size;
CDProperties.CopyProps[cell.properties, copy];
newCp^ ← cp^;
FOR il: CD.InstanceList ← cp.contents, il.rest WHILE il#NIL DO
IF ShouldCopy[il.first] THEN {
i: CD.Instance ← NEW[CD.InstanceRep ← il.first^];
CDProperties.CopyProps[i.properties, i];
newList ← CONS[i, newList];
};
ENDLOOP;
newCp.contents ← newList;
--interest rect: by luck, the right thing happens even without coding
[] ← CDCells.RepositionCell[copy, NIL];
IF design#NIL THEN [] ← CDDirectory.Include[design, copy, name];
};
END;
END.