DIRECTORY
Ascii, BrineIO, 
Imager, ImagerColor, ImagerFont, ImagerInterpress, ImagerMaskCapture, ImagerTransformation, ImagerTypeface, Interpress,
IO,
Pipal, PipalInt, PipalIO, PipalMos, PipalOps, PipalPaint, PipalReal, 
Real, RefTab, Rope, RopeHash, SF;

PipalMosImpl: CEDAR PROGRAM
IMPORTS Ascii, BrineIO, Imager, ImagerColor, ImagerFont, ImagerInterpress, ImagerMaskCapture, ImagerTransformation, ImagerTypeface, Interpress, IO, Pipal, PipalInt, PipalIO, PipalOps, PipalPaint, PipalReal, Real, RefTab, Rope, RopeHash
EXPORTS PipalMos =
BEGIN OPEN PipalMos;
ROPE: TYPE = Pipal.ROPE;
Object: TYPE = Pipal.Object;
Objects: TYPE = Pipal.Objects;
Transformation: TYPE = PipalInt.Transformation;
Rectangle: TYPE = PipalInt.Rectangle;
colorTable: RefTab.Ref _ RefTab.Create[];

errorLayer: PUBLIC Layer _ $Error;
commentLayer: PUBLIC Layer _ $Comment;
blueCommentLayer: PUBLIC Layer _ $BlueComment;

RopeToLayer: PUBLIC PROC [rope: ROPE] RETURNS [layer: Layer _ NIL] = {
EachPair: RefTab.EachPairAction = {
ll: Layer _ NARROW [key];
quit _ Rope.Equal[IO.PutR1[IO.atom[ll]], rope, FALSE];
IF quit THEN layer _ ll;
};
[] _ RefTab.Pairs[colorTable, EachPair];
};
LayerToRope: PUBLIC PROC [layer: Layer] RETURNS [rope: ROPE] = {
rope _ IO.PutR1[IO.atom[layer]];
};
RegisterLayerColor: PUBLIC PROC [layer: Layer, color: ImagerColor.ConstantColor] = {
[] _ RefTab.Store[colorTable, layer, color];
};
FetchLayerColor: PUBLIC PROC [layer: Layer] RETURNS [color: ImagerColor.ConstantColor] = {
color _ NARROW [RefTab.Fetch[colorTable, layer].val];
};
IsDifLayer: PUBLIC PROC [layer: Layer] RETURNS [BOOL] = {
RETURN [layer=$Pdif OR layer=$Ndif];
};
IsWellLayer: PUBLIC PROC [layer: Layer] RETURNS [BOOL] = {
RETURN [layer=$Pwell OR layer=$Nwell];
};
IsSchematicLayer: PUBLIC PROC [layer: Layer] RETURNS [BOOL] = {
RETURN [layer=$Comment OR layer=$BlueComment];
};
boxClass: PUBLIC Pipal.Class _ Pipal.RegisterClass[name: "Box", type: CODE [BoxRec]];

SizeBox: PipalInt.SizeProc = {size _ NARROW [object, Box].size};

PaintBox: PipalPaint.PaintProc = {
box: Box _ NARROW [object];
color: ImagerColor.ConstantColor _ FetchLayerColor[box.layer];
PipalPaint.SetColor[context, color];
Imager.MaskRectangle[context, [0.0, 0.0, box.size.x, box.size.y]];
};

DescribeBox: Pipal.DescribeProc = {
box: Box _ NARROW [object];
Pipal.PutIndent[out, indent, cr];
IO.PutF[out, "Box %g %g", IO.atom[box.layer], IO.rope[PipalInt.VectorToRope[box.size]]]; 
};

HashBox: Pipal.HashProc = {
box: Box _ NARROW [object];
hash _ RopeHash.FromRope[IO.PutR1[IO.atom[box.layer]]] + PipalInt.HashVector[box.size];
};

EqualBox: Pipal.EqualProc = {
box1: Box _ NARROW [object1];
box2: Box _ NARROW [object2];
equal _ box1^=box2^;
};

CreateBox: PUBLIC PROC [size: PipalInt.Size, layer: Layer] RETURNS [box: Box] = {
IF size.x<=0 OR size.y<=0 THEN ERROR;
IF FetchLayerColor[layer]=NIL THEN ERROR;
box _ NEW [BoxRec _ [size: size, layer: layer]];
};

WriteBox: PipalIO.ClassWriteProc = {
box: Box = NARROW [object];
PipalIO.WriteIntVector[stream, box.size];
BrineIO.WriteAtom[stream, box.layer];
};

ReadBox: PipalIO.ClassReadProc = {
size: PipalInt.Size = PipalIO.ReadIntVector[stream];
layer: Layer = BrineIO.ReadAtom[stream];
RETURN [CreateBox[size, layer]]
};
starClass: PUBLIC Pipal.Class _ Pipal.RegisterClass[name: "Star", type: CODE [StarRec]];

DescribeStar: Pipal.DescribeProc = {
star: Star _ NARROW [object];
Pipal.PutIndent[out, indent, cr];
IO.PutF[out, "%g [%g satellites] of ", IO.rope[IF star.overlayStar THEN "Overlay Star" ELSE "Star"], IO.int[star.size]];
Pipal.Describe[out, star.master, indent+1, level-1, cr];
};

EnumerateStar: PipalInt.EnumerateProc = {
star: Star _ NARROW [object];
IF each[transformation, star.master] THEN RETURN [TRUE];
FOR i: NAT IN [0 .. star.size) DO
quit _ each[transformation, star[i]];
IF quit THEN RETURN;
ENDLOOP;
};

GetSatelliteText: PUBLIC PROC [satellite: Object] RETURNS [text: Text _ NIL] = {
IF ISTYPE [satellite, Text] THEN RETURN [NARROW [satellite]];
IF PipalInt.CountChildren[satellite]#1 THEN ERROR;
text _ GetSatelliteText[PipalInt.NthChild[satellite].nthChild];
};

CreateStar: PUBLIC PROC [master: Object, satellites: Objects, overlayStar: BOOL _ FALSE] RETURNS [star: Star] = {
size: NAT _ 0;
FOR list: Objects _ satellites, list.rest WHILE list#NIL DO
size _ size+1;
[] _ GetSatelliteText[list.first];
ENDLOOP;
star _ NEW [StarRec[size]];
star.overlayStar _ overlayStar;
star.master _ master;
FOR i: NAT IN [0 .. size) DO star[i] _ satellites.first; satellites _ satellites.rest ENDLOOP;
};

GetStarTexts: PUBLIC PROC [star: Star] RETURNS [texts: LIST OF Text _ NIL] = {
FOR i: NAT IN [0 .. star.size) DO
texts _ CONS [GetSatelliteText[star[i]], texts];
ENDLOOP;
};

GetNonItalicRopes: PUBLIC PROC [star: Star] RETURNS [satellites: LIST OF Pipal.ROPE _ NIL] = {
FOR i: NAT IN [0 .. star.size) DO
text: Text _ GetSatelliteText[star[i]];
IF NOT IsItalic[GetTextFontName[text]] 
THEN satellites _ CONS [text.contents, satellites];
ENDLOOP;
};

ReplaceStar: PipalOps.ReplaceProc = {
star: Star _ NARROW [parent];
master: Pipal.Object _ map[star.master];
satellites: Pipal.Objects _ NIL;
FOR i: NAT DECREASING IN [0 .. star.size) DO
satellites _ CONS [map[star[i]], satellites]; 
ENDLOOP;
newParent _ CreateStar[master, satellites, star.overlayStar];
};

WriteStar: PipalIO.ClassWriteProc = {
star: Star _ NARROW [object];
BrineIO.WriteBool[stream, star.overlayStar];
PipalIO.WriteObject[stream, star.master];
BrineIO.WriteInt[stream, star.size];
FOR i: NAT IN [0 .. star.size) DO PipalIO.WriteObject[stream, star[i]] ENDLOOP;
};

ReadStar: PipalIO.ClassReadProc = {
overlayStar: BOOL _ BrineIO.ReadBool[stream];
master: Pipal.Object _ PipalIO.ReadObject[stream];
object _ CreateStar[master, PipalIO.ReadObjects[stream], overlayStar];
};
routingClass: PUBLIC Pipal.Class _ Pipal.RegisterClass[name: "Routing", type: CODE [RoutingRec]];

DescribeRouting: Pipal.DescribeProc = {
routing: Routing _ NARROW [object];
Pipal.PutIndent[out, indent, cr];
IO.PutF[out, "Routing: %g nodes", IO.int[routing.size]];
};

EnumerateRouting: PipalInt.EnumerateProc = {
routing: Routing _ NARROW [object];
FOR i: NAT IN [0 .. routing.size) DO
quit _ each[transformation, routing[i]];
IF quit THEN RETURN;
ENDLOOP;
};

CreateRouting: PUBLIC PROC [nodes: Objects] RETURNS [routing: Routing] = {
size: NAT _ Pipal.Length[nodes];
routing _ NEW [RoutingRec[size]];
FOR i: NAT IN [0 .. size) DO routing[i] _ nodes.first; nodes _ nodes.rest ENDLOOP;
};

ReplaceRouting: PipalOps.ReplaceProc = {
routing: Routing _ NARROW [parent];
nodes: Pipal.Objects _ NIL;
FOR i: NAT DECREASING IN [0 .. routing.size) DO
nodes _ CONS [map[routing[i]], nodes]; 
ENDLOOP;
newParent _ CreateRouting[nodes];
};

WriteRouting: PipalIO.ClassWriteProc = {
routing: Routing _ NARROW [object];
BrineIO.WriteInt[stream, routing.size];
FOR i: NAT IN [0 .. routing.size) DO PipalIO.WriteObject[stream, routing[i]] ENDLOOP;
};

ReadRouting: PipalIO.ClassReadProc = {
object _ CreateRouting[PipalIO.ReadObjects[stream]];
};
tilingClass: PUBLIC Pipal.Class _ Pipal.RegisterClass[name: "Tiling", type: CODE [TilingRec]];

DescribeTiling: Pipal.DescribeProc = {
tiling: Tiling _ NARROW [object];
Pipal.PutIndent[out, indent, cr];
IO.PutF[out, "Tiling: [%g, %g]", IO.int[tiling.sizeX], IO.int[tiling.sizeY]];
};

EnumerateTiling: PipalInt.EnumerateProc = {
tiling: Tiling _ NARROW [object];
pos: PipalInt.Position;
pos.y _ 0;
FOR y: NAT IN [0 .. tiling.sizeY) DO
pos.x _ 0;
FOR x: NAT IN [0 .. tiling.sizeX) DO
sub: Object _ tiling.xyTile[x, y, tiling.data];
quit _ each[PipalInt.Compose[transformation, [pos]], sub];
IF quit THEN RETURN;
pos.x _ pos.x + PipalInt.AbutBox[sub].size.x;
ENDLOOP;
pos.y _ pos.y + PipalInt.AbutBox[tiling.xyTile[0, y, tiling.data]].size.y;
ENDLOOP;
};

CreateTiling: PUBLIC PROC [sizeX, sizeY: NAT, xyTile: XYTileProc, data: REF _ NIL] RETURNS [tiling: Tiling] = {
tiling _ NEW [TilingRec _ [sizeX: sizeX, sizeY: sizeY, xyTile: xyTile, data: data]];
IF sizeX=0 OR sizeY=0 THEN ERROR;
FOR y: NAT IN [0 .. sizeY) DO
height: INT _ PipalInt.AbutBox[tiling.xyTile[0, y, tiling.data]].size.y;
FOR x: NAT IN [1 .. sizeX) DO
IF PipalInt.AbutBox[tiling.xyTile[x, y, tiling.data]].size.y#height THEN ERROR; -- constraint of same height within a row not respected!
ENDLOOP;
ENDLOOP;
FOR x: NAT IN [0 .. sizeX) DO
width: INT _ PipalInt.AbutBox[tiling.xyTile[x, 0, tiling.data]].size.x;
FOR y: NAT IN [1 .. sizeY) DO
IF PipalInt.AbutBox[tiling.xyTile[x, y, tiling.data]].size.x#width THEN ERROR; -- constraint of same width within a column not respected!
ENDLOOP;
ENDLOOP;
};

EnumerateTiles: PUBLIC PROC [tiling: Tiling, each: EachTileProc] RETURNS [quit: BOOL _ FALSE] = {
pos: PipalInt.Position _ [0, 0];
FOR y: NAT IN [0 .. tiling.sizeY) DO
pos.x _ 0;
FOR x: NAT IN [0 .. tiling.sizeX) DO
tile: Object _ tiling.xyTile[x, y, tiling.data];
quit _ each[x, y, tile, pos];
IF quit THEN RETURN;
pos.x _ pos.x + PipalInt.AbutBox[tile].size.x;
ENDLOOP;
pos.y _ pos.y + PipalInt.AbutBox[tiling.xyTile[0, y, tiling.data]].size.y;
ENDLOOP;
};

WriteTiling: PipalIO.ClassWriteProc = {
tiling: Tiling _ NARROW [object];
BrineIO.WriteInt[stream, tiling.sizeX];
BrineIO.WriteInt[stream, tiling.sizeY];
FOR y: NAT IN [0 .. tiling.sizeY) DO
FOR x: NAT IN [0 .. tiling.sizeX) DO PipalIO.WriteObject[stream, tiling.xyTile[x, y, tiling.data]] ENDLOOP;
ENDLOOP;
};

TileArrayRec: TYPE = RECORD [SEQUENCE sizeY: NAT OF REF TileLinesRec];
TileLinesRec: TYPE = RECORD [SEQUENCE sizeX: NAT OF Pipal.Object];
TileArrayXY: XYTileProc = {
tileArray: REF TileArrayRec _ NARROW [data];
RETURN [tileArray[y][x]];
};

ReadTiling: PipalIO.ClassReadProc = {
sizeX: NAT _ NAT [BrineIO.ReadInt[stream]];
sizeY: NAT _ NAT [BrineIO.ReadInt[stream]];
tileArray: REF TileArrayRec _ NEW [TileArrayRec[sizeY]];
FOR y: NAT IN [0 .. sizeY) DO
tileArray[y] _ NEW [TileLinesRec[sizeX]];
FOR x: NAT IN [0 .. sizeX) DO tileArray[y][x] _ PipalIO.ReadObject[stream] ENDLOOP;
ENDLOOP;
object _ CreateTiling[sizeX, sizeY, TileArrayXY, tileArray];
};
markerClass: PUBLIC Pipal.Class _ Pipal.RegisterClass[name: "Marker", type: CODE [MarkerRec]];

SizeMarker: PipalInt.SizeProc = {
marker: Marker _ NARROW [object];
size _ marker.size;
};

PaintMarker: PipalPaint.PaintProc = {
marker: Marker _ NARROW [object];
color: ImagerColor.ConstantColor _ FetchLayerColor[marker.layer];
size: PipalInt.Size _ marker.size;
PipalPaint.SetColor[context, color];
Imager.MaskVector[context, [0, 0], [size.x, size.y]];
Imager.MaskVector[context, [0, size.y], [size.x, 0]];
};

DescribeMarker: Pipal.DescribeProc = {
marker: Marker _ NARROW [object];
Pipal.PutIndent[out, indent, cr];
IO.PutF[out, "Marker %g %g", IO.atom[marker.layer], IO.rope[PipalInt.VectorToRope[marker.size]]]; 
};

HashMarker: Pipal.HashProc = {
marker: Marker _ NARROW [object];
hash _ RopeHash.FromRope[IO.PutR1[IO.atom[marker.layer]]] + PipalInt.HashVector[marker.size];
};

EqualMarker: Pipal.EqualProc = {
marker1: Marker _ NARROW [object1];
marker2: Marker _ NARROW [object2];
equal _ marker1^=marker2^;
};

CreateMarker: PUBLIC PROC [size: PipalInt.Size, layer: Layer] RETURNS [marker: Marker] = {
IF FetchLayerColor[layer]=NIL THEN ERROR;
marker _ NEW [MarkerRec _ [size: size, layer: layer]];
};

WriteMarker: PipalIO.ClassWriteProc = {
marker: Marker = NARROW [object];
PipalIO.WriteIntVector[stream, marker.size];
BrineIO.WriteAtom[stream, marker.layer];
};

ReadMarker: PipalIO.ClassReadProc = {
size: PipalInt.Size = PipalIO.ReadIntVector[stream];
layer: Layer = BrineIO.ReadAtom[stream];
RETURN [CreateMarker[size, layer]]
};
schematicIconClass: PUBLIC Pipal.Class _ Pipal.RegisterClass[name: "SchematicIcon", type: CODE [SchematicIconRec]];

DescribeSchematicIcon: Pipal.DescribeProc = {
icon: SchematicIcon _ NARROW [object];
Pipal.PutIndent[out, indent, cr];
IO.PutF[out, "SchematicIcon: [%g, %g, %g]", IO.rope[icon.expression], IO.rope[IF icon.code THEN "code" ELSE "sch"], IO.rope[SELECT icon.type FROM cell => "cell", wire => "wire", unnamedWire => "unnamedWire", ENDCASE => ERROR]];
};

EqualSchematicIcon: Pipal.EqualProc = {
icon1: SchematicIcon _ NARROW [object1];
icon2: SchematicIcon _ NARROW [object2];
equal _ Rope.Equal[icon1.expression, icon2.expression] AND icon1.code=icon2.code AND icon1.type=icon2.type AND Pipal.Equal[icon1.child, icon2.child];
};

EnumerateSchematicIcon: PipalInt.EnumerateProc = {
icon: SchematicIcon _ NARROW [object];
quit _ each[transformation, icon.child];
};

CreateSchematicIcon: PUBLIC PROC [child: Pipal.Object, expression: Pipal.ROPE, code: BOOL, type: SchematicIconType] RETURNS [icon: SchematicIcon] = {
icon _ NEW [SchematicIconRec _ [child: child, expression: expression, code: code, type: type]];
};

ReplaceSchematicIcon: PipalOps.ReplaceProc = {
icon: SchematicIcon _ NARROW [parent];
child: Pipal.Object _ map[icon.child];
newParent _ CreateSchematicIcon[child, icon.expression, icon.code, icon.type];
};

WriteSchematicIcon: PipalIO.ClassWriteProc = {
icon: SchematicIcon = NARROW [object];
PipalIO.WriteObject[stream, icon.child];
BrineIO.WriteRope[stream, icon.expression];
BrineIO.WriteBool[stream, icon.code];
BrineIO.WriteInt[stream, ORD [icon.type]];
};

ReadSchematicIcon: PipalIO.ClassReadProc = {
child: Pipal.Object _ PipalIO.ReadObject[stream];
expression: Pipal.ROPE _ BrineIO.ReadRope[stream];
code: BOOL _ BrineIO.ReadBool[stream];
ord: NAT _ BrineIO.ReadInt[stream];
type: SchematicIconType _ VAL [ord];
RETURN [CreateSchematicIcon[child, expression, code, type]]
};
schematicSequenceClass: PUBLIC Pipal.Class _ Pipal.RegisterClass[name: "SchematicSequence", type: CODE [SchematicSequenceRec]];

DescribeSchematicSequence: Pipal.DescribeProc = {
seq: SchematicSequence _ NARROW [object];
Pipal.PutIndent[out, indent, cr];
IO.PutF[out, "SchematicSequence: [%g]", IO.rope[seq.repetition]];
};

EqualSchematicSequence: Pipal.EqualProc = {
seq1: SchematicSequence _ NARROW [object1];
seq2: SchematicSequence _ NARROW [object2];
equal _ Rope.Equal[seq1.repetition, seq2.repetition] AND Pipal.Equal[seq1.child, seq2.child];
};

EnumerateSchematicSequence: PipalInt.EnumerateProc = {
seq: SchematicSequence _ NARROW [object];
quit _ each[transformation, seq.child];
};

CreateSchematicSequence: PUBLIC PROC [child: Pipal.Object, repetition: Pipal.ROPE] RETURNS [seq: SchematicSequence] = {
seq _ NEW [SchematicSequenceRec _ [child: child, repetition: repetition]];
};

ReplaceSchematicSequence: PipalOps.ReplaceProc = {
seq: SchematicSequence _ NARROW [parent];
child: Pipal.Object _ map[seq.child];
newParent _ CreateSchematicSequence[child, seq.repetition];
};

WriteSchematicSequence: PipalIO.ClassWriteProc = {
seq: SchematicSequence = NARROW [object];
PipalIO.WriteObject[stream, seq.child];
BrineIO.WriteRope[stream, seq.repetition];
};

ReadSchematicSequence: PipalIO.ClassReadProc = {
child: Pipal.Object _ PipalIO.ReadObject[stream];
repetition: Pipal.ROPE _ BrineIO.ReadRope[stream];
RETURN [CreateSchematicSequence[child, repetition]]
};
textClass: PUBLIC Pipal.Class _ Pipal.RegisterClass[name: "Text", type: CODE [TextRec]];

ComputeBBoxText: PROC [text: Text] RETURNS [bbox: Rectangle] = {
fontExt: ImagerFont.Extents _ ImagerFont.FontBoundingBox[text.font];
ropeExt: ImagerFont.Extents _ ImagerFont.RopeBoundingBox[text.font, text.contents];
originX: INT _ Real.Ceiling[fontExt.leftExtent]; 
originY: INT _ Real.Ceiling[fontExt.descent];
endX: INT _ Real.Ceiling[ropeExt.rightExtent]; 
endY: INT _ Real.Ceiling[fontExt.ascent];
bbox _ [[-originX, -originY], [endX+originX, endY+originY]];
};

SizeText: PipalInt.SizeProc = {size _ ComputeBBoxText[NARROW [object]].size};
AbutBoxText: PipalInt.AbutBoxProc = {abutBox _ ComputeBBoxText[NARROW [object]]};
BBoxText: PipalInt.BBoxProc = {
bbox _ PipalInt.TransformRectangle[transformation, ComputeBBoxText[NARROW [object]]];
};

PaintText: PipalPaint.PaintProc = {
text: Text _ NARROW [object];
bbox: Rectangle _ ComputeBBoxText[text];
PipalPaint.PaintFlippedText[context, text.contents, text.font, bbox];
};

DescribeText: Pipal.DescribeProc = {
text: Text _ NARROW [object];
Pipal.PutIndent[out, indent, cr];
IO.PutF[out, "Text %g", IO.rope[text.contents]]; 
};

HashText: Pipal.HashProc = {
text: Text _ NARROW [object];
hash _ RopeHash.FromRope[text.contents] + PipalInt.HashObjectSize[object];
};

EqualText: Pipal.EqualProc = {
text1: Text _ NARROW [object1];
text2: Text _ NARROW [object2];
equal _ Rope.Equal[text1.contents, text2.contents] AND text1.font=text2.font;
};

CreateText: PUBLIC PROC [contents: ROPE, font: Imager.Font] RETURNS [text: Text] = {
IF font=NIL THEN ERROR;
text _ NEW [TextRec _ [contents: contents, font: font]];
};

GetTextFontName: PUBLIC PROC [text: Text] RETURNS [fontName: ROPE] = {
font: Imager.Font _ text.font;
typeface: REF _ font.typeface;
typeface2: ImagerTypeface.Typeface _ NARROW [typeface];
fontName _ typeface2.name;
};

IsItalic: PUBLIC PROC [fontName: ROPE] RETURNS [BOOL _ FALSE] = {
pressFontLeng: INT = 17; pressFontName: ROPE = "Xerox/PressFonts/";
tiogaFontLeng: INT = 17; tiogaFontName: ROPE = "Xerox/TiogaFonts/";
leng: INT _ Rope.Length[fontName];
IF leng>tiogaFontLeng THEN
IF Rope.Equal[Rope.Substr[fontName, 0, tiogaFontLeng], tiogaFontName, FALSE] THEN
RETURN [Ascii.Upper[Rope.Fetch[fontName, leng-1]]='I];
IF leng>pressFontLeng THEN
IF Rope.Equal[Rope.Substr[fontName, 0, pressFontLeng], pressFontName, FALSE] THEN 
RETURN [Ascii.Upper[Rope.Fetch[fontName, leng-2]]='I]
};

WriteText: PipalIO.ClassWriteProc = {
text: Text = NARROW [object];
typeface: REF _ text.font.typeface;
BrineIO.WriteRope[stream, text.contents];
PipalIO.WriteRealTransformation[stream, text.font.charToClient];
BrineIO.WriteRope[stream, NARROW [typeface, ImagerTypeface.Typeface].name];
};

ReadText: PipalIO.ClassReadProc = {
contents: Pipal.ROPE _ BrineIO.ReadRope[stream];
transformation: PipalReal.Transformation _ PipalIO.ReadRealTransformation[stream];
name: Pipal.ROPE _ BrineIO.ReadRope[stream];
typeface: ImagerTypeface.Typeface _ ImagerTypeface.FindTypeface[name, noSubstitute];
font: Imager.Font _ ImagerTypeface.MakeFont[typeface, transformation];
RETURN [CreateText[contents, font]];
};
pictureClass: PUBLIC Pipal.Class _ Pipal.RegisterClass[name: "Picture", type: CODE [PictureRec]];

SizePicture: PipalInt.SizeProc = {
picture: Picture _ NARROW [object];
size _ picture.size;
};

PaintPicture: PipalPaint.PaintProc = {
picture: Picture _ NARROW [object];
Imager.DrawObject[context, picture.imagerObject, Imager.zeroVEC, TRUE];
};

CreatePicture: PUBLIC PROC [size: PipalInt.Size, imagerObject: Imager.Object] RETURNS [picture: Picture] = {
IF imagerObject=NIL THEN ERROR;
picture _ NEW [PictureRec _ [size: size, imagerObject: imagerObject]];
};

LogSignal: SIGNAL = CODE;
Log: Interpress.LogProc = {
SIGNAL LogSignal[];
};

metersPerPoint: REAL = Imager.metersPerInch / Imager.pointsPerInch;

MasterBounds: PROC [ipMaster: Interpress.Master] RETURNS [rect: PipalReal.Rectangle] = {
scale: REAL _ 150.0/0.0254; -- ~150 pixels/inch
m: Imager.Transformation _ ImagerTransformation.Scale[scale];
Operator: PROC [context: Imager.Context] ~ {
Imager.SetColor[context, Imager.black];
Imager.SetStrokeEnd[context, square];
Imager.SetStrokeWidth[context, 0.0];
Imager.SetAmplifySpace[context, 1.0];
Interpress.DoPage[ipMaster, 1, context, NIL];
};
box: SF.Box _ ImagerMaskCapture.CaptureBounds[Operator, m];
rect.base.x _ box.min.s/scale; rect.base.y _ box.min.f/scale;
rect.size.x _ (box.max.s-box.min.s)/scale; rect.size.y _ (box.max.f-box.min.f)/scale; 
};

ScaleIP: TYPE = REF ScaleIPRec;
ScaleIPRec: TYPE = RECORD [trans: Imager.Transformation, ipMaster: Interpress.Master];

InterpressDraw: PROC [self: Imager.Object, context: Imager.Context] = {
scaleIP: ScaleIP _ NARROW [self.data];
ipMaster: Interpress.Master _ scaleIP.ipMaster;
Imager.ConcatT[context, scaleIP.trans];
Interpress.DoPage[master: ipMaster, page: 1, context: context, log: Log];
};

CreatePictureFromInterpress: PUBLIC PROC [size: PipalInt.Size, master: Pipal.ROPE] RETURNS [picture: Picture] = {
ipMaster: Interpress.Master _ Interpress.FromRope[rope: master, log: Log];
rect: PipalReal.Rectangle _ MasterBounds[ipMaster];
trans: Imager.Transformation _ ImagerTransformation.Concat[
ImagerTransformation.Translate[[-rect.base.x, -rect.base.y]], 
ImagerTransformation.Scale2[[IF rect.size.x=0 THEN 1 ELSE size.x / rect.size.x, IF rect.size.y=0 THEN 1 ELSE size.y / rect.size.y]]
];
picture _ CreatePicture[
size, 
NEW [Imager.ObjectRep _ [draw: InterpressDraw, clip: [0, 0, size.x, size.y], data: NEW [ScaleIPRec _ [trans: trans, ipMaster: ipMaster]]]]
];
};

HashPicture: Pipal.HashProc = {
picture: Picture = NARROW [object];
hash _ Pipal.HashObjectClass[object] + PipalInt.HashVector[picture.size];
};

EqualPicture: Pipal.EqualProc = {
picture1: Picture _ NARROW [object1];
picture2: Picture _ NARROW [object2];
equal _ picture1.size=picture2.size AND Rope.Equal[PictureToRope[picture1], PictureToRope[picture2]];
};

PictureToRope: PROC [picture: Picture] RETURNS [rope: Pipal.ROPE] = {
DrawPicture: PROC [context: Imager.Context] = {
picture.imagerObject.draw[picture.imagerObject, context];
};
master: IO.STREAM _ IO.ROS[];
ipMaster: ImagerInterpress.Ref _ ImagerInterpress.CreateFromStream[master, "Interpress/Xerox/3.0 "];
ImagerInterpress.DoPage[ipMaster, DrawPicture, metersPerPoint];
ImagerInterpress.Finish[ipMaster];
rope _ IO.RopeFromROS[master];
};

WritePicture: PipalIO.ClassWriteProc = {
CodeChar: Rope.ActionType = {BrineIO.WriteInt[stream, ORD [c]]};
picture: Picture = NARROW [object];
rope: Pipal.ROPE _ PictureToRope[picture];
PipalIO.WriteIntVector[stream, picture.size];
BrineIO.WriteInt[stream, Rope.Length[rope]];
[] _ Rope.Map[base: rope, action: CodeChar];
};

ReadPicture: PipalIO.ClassReadProc = {
DecodeChar: PROC RETURNS [CHAR] = {
nat: NAT _ BrineIO.ReadInt[stream];
RETURN [VAL [nat]];
};
size: PipalInt.Size _ PipalIO.ReadIntVector[stream];
length: INT _ BrineIO.ReadInt[stream];
master: Pipal.ROPE _ Rope.FromProc[length, DecodeChar];
RETURN [CreatePictureFromInterpress[size, master]];
};
indirectProp: PUBLIC ATOM _ $MosIndirect;
atomicProp: PUBLIC ATOM _ $MosAtomic;

biAtomicProp: PUBLIC ATOM _ $MosBiAtomic;

transistorProp: PUBLIC ATOM _ $MosTransistor;

IsAnnotationAtomic: IsAtomicProc = {
annotation: Pipal.Annotation _ NARROW [object];
RETURN [annotation.key=atomicProp OR annotation.key=biAtomicProp OR annotation.key=transistorProp];
};
isAtomicMethod: PUBLIC Pipal.Method _ Pipal.RegisterMethod["MosIsAtomic"];

IsAtomic: PUBLIC IsAtomicProc = {
refProc: REF IsAtomicProc = NARROW [Pipal.ObjectMethod[object, isAtomicMethod]];
RETURN [IF refProc=NIL THEN NOT PipalInt.HasEnumerate[object] ELSE refProc^[object]];
};

EnumerateAtomic: PUBLIC PipalInt.EnumerateProc = {
FilterAtomic: PipalInt.EachChildProc = {
quit _ IF IsAtomic[child] 
THEN each[transformation, child] 
ELSE PipalInt.Enumerate[child, FilterAtomic, transformation];
};
quit _ FilterAtomic[transformation, object];
};

clippedEnumerationClass: PUBLIC Pipal.Class _ Pipal.RegisterClass[name: "ClippedEnumeration", type: CODE [ClippedEnumerationRec]];

CreateClippedEnumeration: PUBLIC PROC [clipRect: Rectangle, child: Object] RETURNS [clippedEnumeration: ClippedEnumeration] = {
clippedEnumeration _ NEW [ClippedEnumerationRec _ [clipRect: clipRect, child: child]];
};

EnumerateClippedEnumeration: PipalInt.EnumerateProc = {
ClipEach: PipalInt.EachChildProc = {
IF PipalInt.AtEdge[ce.clipRect, transformation, child] THEN quit _ each[transformation, child];
};
ce: ClippedEnumeration _ NARROW [object];
quit _ EnumerateAtomic[ce.child, ClipEach, transformation];
};

CountAtomicChildren: PUBLIC PROC [object: Object] RETURNS [count: INT _ 0] = {
CountEach: PipalInt.EachChildProc = {count _ count + 1};
[] _ EnumerateAtomic[object, CountEach, []];
};
expandPortsCount: INT _ 5;
CreateClipEnum: PUBLIC PROC [clipRect: Rectangle, child: Object] RETURNS [Object] = {
clippedEnumeration: ClippedEnumeration _ CreateClippedEnumeration[clipRect, child];
count: INT _ CountAtomicChildren[clippedEnumeration];
children: Objects _ NIL;
ConsEachChild: PipalInt.EachChildProc = {
IF child=Pipal.void THEN ERROR;
children _ CONS [PipalInt.TransformObject[transformation, child], children];
};
IF count>expandPortsCount THEN RETURN [clippedEnumeration];
IF EnumerateAtomic[clippedEnumeration, ConsEachChild] THEN ERROR;
RETURN [Pipal.CreateOv[children]];
};

EnumerateRectangleLayers: PUBLIC PROC [object: Object, each: EachRectangleLayerProc, transformation: Transformation _ [], includeMarkers, includeSchematicLayer: BOOL _ TRUE] RETURNS [quit: BOOL _ FALSE] = {
InternalEach: PipalInt.EachChildProc = {
SELECT Pipal.ObjectClass[child] FROM
boxClass	=> {
box: Box _ NARROW [child];
IF includeSchematicLayer OR NOT IsSchematicLayer[box.layer] THEN quit _ each[PipalInt.TransformBBox[transformation, box.size], box.layer, FALSE];
};
markerClass	=> {
marker: Marker _ NARROW [child];
IF includeMarkers AND (includeSchematicLayer OR NOT IsSchematicLayer[marker.layer]) THEN quit _ each[PipalInt.TransformBBox[transformation, marker.size], marker.layer, TRUE];
};
pictureClass, textClass	=> {};
ENDCASE		=> quit _ PipalInt.Enumerate[child, InternalEach, transformation];
};
quit _ InternalEach[transformation, object];
};

ContainsWell: PUBLIC PROC [object: Object] RETURNS [BOOL] = {
Each: EachRectangleLayerProc = {quit _ IsWellLayer[layer]};
RETURN [EnumerateRectangleLayers[object: object, each: Each, includeSchematicLayer: FALSE]];
};

Touch: PUBLIC TouchProc = {
GenericTouchInstance1: PipalInt.EachChildProc = {
quit _ touch[touch, transformation, child, trans1, object1];
};
GenericTouchInstance2: PipalInt.EachChildProc = {
quit _ touch[touch, trans2, object2, transformation, child];
};
RectTouchInstance2: EachRectangleLayerProc = {
RectTouchInstance12: EachRectangleLayerProc = {
quit _ PipalInt.DoRectanglesIntersect[rect, rect1] AND layer=layer1;
};
rect1: Rectangle _ rect;
layer1: Layer _ layer;
quit _ EnumerateRectangleLayers[object2, RectTouchInstance12, trans2];
};
IF NOT PipalInt.DoRectanglesIntersect[PipalInt.BBox[object1, trans1], PipalInt.BBox[object2, trans2]] THEN RETURN;
IF PipalInt.HasEnumerate[object1] THEN RETURN [PipalInt.Enumerate[object1, GenericTouchInstance2, trans1]];
IF PipalInt.HasEnumerate[object2] THEN RETURN [PipalInt.Enumerate[object2, GenericTouchInstance1, trans2]];
RETURN [EnumerateRectangleLayers[object1, RectTouchInstance2, trans1]];
};

LayoutTouch: PUBLIC TouchProc = {
IsRect: PROC [object: Object, layer: Layer] RETURNS [BOOL] = INLINE {
IF NOT ISTYPE [object, Box] THEN RETURN [FALSE];
RETURN [NARROW [object, Box].layer=layer];
};
ChangeRect: PROC [object: Object, layer: Layer] RETURNS [Object] = {
box: Box = NARROW [object];
RETURN [CreateBox[box.size, layer]];
};
IF IsRect[object1, $PwellCont] THEN RETURN [
touch[touch, trans1, ChangeRect[object1, $Pwell], trans2, object2] OR 
touch[touch, trans1, ChangeRect[object1, $Pdif], trans2, object2]
];
IF IsRect[object1, $NwellCont] THEN RETURN [
touch[touch, trans1, ChangeRect[object1, $Nwell], trans2, object2] OR 
touch[touch, trans1, ChangeRect[object1, $Ndif], trans2, object2]
];
IF IsRect[object2, $PwellCont] THEN RETURN [
touch[touch, trans2, ChangeRect[object2, $Pwell], trans1, object1] OR 
touch[touch, trans2, ChangeRect[object2, $Pdif], trans1, object1]
];
IF IsRect[object2, $NwellCont] THEN RETURN [
touch[touch, trans2, ChangeRect[object2, $Nwell], trans1, object1] OR 
touch[touch, trans2, ChangeRect[object2, $Ndif], trans1, object1]
];
IF IsRect[object1, $Met2] AND IsRect[object2, $Ovg] THEN RETURN [
PipalInt.IsInsideRectangle[PipalInt.BBox[object1, trans1], PipalInt.BBox[object2, trans2]]
];
IF IsRect[object1, $Ovg] AND IsRect[object2, $Met2] THEN RETURN [
PipalInt.IsInsideRectangle[PipalInt.BBox[object2, trans2], PipalInt.BBox[object1, trans1]]
];
RETURN Touch[touch, trans1, object1, trans2, object2];
};

SchematicTouch: PUBLIC TouchProc = {
GenericTouchInstance1: PipalInt.EachChildProc = {
quit _ touch[touch, transformation, child, trans1, object1];
};
GenericTouchInstance2: PipalInt.EachChildProc = {
quit _ touch[touch, trans2, object2, transformation, child];
};
IF NOT PipalInt.DoRectanglesIntersect[PipalInt.BBox[object1, trans1], PipalInt.BBox[object2, trans2]] THEN RETURN;
IF PipalInt.HasEnumerate[object1] THEN RETURN [PipalInt.Enumerate[object1, GenericTouchInstance2, trans1]];
IF PipalInt.HasEnumerate[object2] THEN RETURN [PipalInt.Enumerate[object2, GenericTouchInstance1, trans2]];
IF Pipal.ObjectClass[object1]#boxClass OR Pipal.ObjectClass[object2]#boxClass THEN ERROR; -- the only thing we know is Rectangles!
IF ~SilTouchRect[PipalInt.BBox[object1, trans1], PipalInt.BBox[object2, trans2]] THEN RETURN;
RETURN [NARROW [object1, Box].layer=NARROW [object2, Box].layer];
};

SilTouchRect: PROC [r1, r2: Rectangle] RETURNS [BOOL] = INLINE {
Intersect: PROC [i1min, i1max, i2min, i2max: PipalInt.Number] RETURNS [BOOL] = INLINE {
RETURN [(i1max >= i2min) AND (i2max >= i1min)];
};
Adjoin: PROC [i1min, i1max, i2min, i2max: PipalInt.Number] RETURNS [BOOL] = INLINE {
RETURN [(i2min >= i1min AND i2min <= i1max AND i2max >= i1max) OR
 (i1min >= i2min AND i1min <= i2max AND i1max >= i2max)];
};
RETURN [
(Intersect[r1.base.x, r1.base.x+r1.size.x, r2.base.x, r2.base.x+r2.size.x] AND Adjoin[r1.base.y, r1.base.y+r1.size.y, r2.base.y, r2.base.y+r2.size.y]) 
OR 
(Intersect[r1.base.y, r1.base.y+r1.size.y, r2.base.y, r2.base.y+r2.size.y] AND Adjoin[r1.base.x, r1.base.x+r1.size.x, r2.base.x, r2.base.x+r2.size.x]) 
OR PipalInt.IsInsideRectangle[r1, r2] OR PipalInt.IsInsideRectangle[r2, r1]
]
};
extractTransistorMethod: PUBLIC Pipal.Method _ Pipal.RegisterMethod["MosExtractTransistor"];
ExtractTransistor: PUBLIC ExtractTransistorProc = {
RETURN (NARROW [Pipal.ObjectMethod[object, extractTransistorMethod], REF ExtractTransistorProc]^)[object];
};
ShortRegisterLayerColor: PROC [layer: Layer, colorName: ROPE] = {
RegisterLayerColor[layer, ImagerColor.Find[Rope.Cat["Xerox/Research/ChipNDale/CMosB/", colorName]]];
};
RegisterLayerColor[$Error, Imager.white];
RegisterLayerColor[$Comment, Imager.black];
RegisterLayerColor[$Bond, Imager.white];
ShortRegisterLayerColor[$Pdif, "PDif"];
ShortRegisterLayerColor[$Ndif, "NDif"];
ShortRegisterLayerColor[$PwellCont, "PWelCont"];
ShortRegisterLayerColor[$NwellCont, "NWelCont"];
ShortRegisterLayerColor[$Pwell, "PWel"];
ShortRegisterLayerColor[$Nwell, "NWel"];
ShortRegisterLayerColor[$Pol, "Pol"];
ShortRegisterLayerColor[$Met, "Met"];
ShortRegisterLayerColor[$Met2, "Met2"];
ShortRegisterLayerColor[$Ovg, "Ovg"];
ShortRegisterLayerColor[$Cut, "Cut"];
ShortRegisterLayerColor[$Cut2, "Cut2"];
ShortRegisterLayerColor[$BlueComment, "Met"];
Pipal.PutClassMethod[boxClass, PipalInt.sizeMethod, NEW [PipalInt.SizeProc _ SizeBox]];
Pipal.PutClassMethod[boxClass, PipalReal.sizeMethod, NEW [PipalReal.SizeProc _ PipalReal.UseIntSize]];
Pipal.PutClassMethod[boxClass, PipalInt.abutBoxMethod, NEW [PipalInt.AbutBoxProc _ PipalInt.AbutBoxFromSize]];
Pipal.PutClassMethod[boxClass, PipalPaint.paintMethod, NEW [PipalPaint.PaintProc _ PaintBox]];
Pipal.PutClassMethod[boxClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeBox]];
Pipal.PutClassMethod[boxClass, Pipal.hashMethod, NEW [Pipal.HashProc _ HashBox]];
Pipal.PutClassMethod[boxClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualBox]];
PipalIO.RegisterClass[boxClass, ReadBox, WriteBox];
Pipal.PutClassMethod[starClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeStar]];
Pipal.PutClassMethod[starClass, Pipal.hashMethod, NEW [Pipal.HashProc _ PipalOps.HashByEnumeration]];
Pipal.PutClassMethod[starClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ PipalOps.EqualByEnumeration]];
Pipal.PutClassMethod[starClass, PipalInt.sizeMethod, NEW [PipalInt.SizeProc _ PipalInt.CachedSizeFromEnumerate]];
Pipal.PutClassMethod[starClass, PipalInt.bboxMethod, NEW [PipalInt.BBoxProc _ PipalInt.CachedBBoxFromEnumerate]];
Pipal.PutClassMethod[starClass, PipalInt.abutBoxMethod, NEW [PipalInt.AbutBoxProc _ PipalInt.CachedAbutBoxFromEnumerate]];
Pipal.PutClassMethod[starClass, PipalInt.enumerateMethod, NEW [PipalInt.EnumerateProc _ EnumerateStar]];
Pipal.PutClassMethod[starClass, PipalOps.replaceMethod, NEW [PipalOps.ReplaceProc _ ReplaceStar]];
PipalIO.RegisterClass[starClass, ReadStar, WriteStar];
Pipal.PutClassMethod[routingClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeRouting]];
Pipal.PutClassMethod[routingClass, Pipal.hashMethod, NEW [Pipal.HashProc _ PipalOps.CachedHashByEnumeration]];
Pipal.PutClassMethod[routingClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ PipalOps.EqualByEnumeration]];
Pipal.PutClassMethod[routingClass, PipalInt.sizeMethod, NEW [PipalInt.SizeProc _ PipalInt.CachedSizeFromEnumerate]];
Pipal.PutClassMethod[routingClass, PipalInt.bboxMethod, NEW [PipalInt.BBoxProc _ PipalInt.CachedBBoxFromEnumerate]];
Pipal.PutClassMethod[routingClass, PipalInt.abutBoxMethod, NEW [PipalInt.AbutBoxProc _ PipalInt.CachedAbutBoxFromEnumerate]];
Pipal.PutClassMethod[routingClass, PipalInt.enumerateMethod, NEW [PipalInt.EnumerateProc _ EnumerateRouting]];
Pipal.PutClassMethod[routingClass, PipalOps.replaceMethod, NEW [PipalOps.ReplaceProc _ ReplaceRouting]];
PipalIO.RegisterClass[routingClass, ReadRouting, WriteRouting];
Pipal.PutClassMethod[tilingClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeTiling]];
Pipal.PutClassMethod[tilingClass, Pipal.hashMethod, NEW [Pipal.HashProc _ PipalOps.CachedHashByEnumeration]];
Pipal.PutClassMethod[tilingClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ PipalOps.EqualByEnumeration]];
Pipal.PutClassMethod[tilingClass, PipalInt.sizeMethod, NEW [PipalInt.SizeProc _ PipalInt.CachedSizeFromEnumerate]];
Pipal.PutClassMethod[tilingClass, PipalInt.bboxMethod, NEW [PipalInt.BBoxProc _ PipalInt.CachedBBoxFromEnumerate]];
Pipal.PutClassMethod[tilingClass, PipalInt.abutBoxMethod, NEW [PipalInt.AbutBoxProc _ PipalInt.CachedAbutBoxFromEnumerate]];
Pipal.PutClassMethod[tilingClass, PipalInt.enumerateMethod, NEW [PipalInt.EnumerateProc _ EnumerateTiling]];
Pipal.PutClassMethod[tilingClass, PipalOps.replaceMethod, NEW [PipalOps.ReplaceProc _ PipalOps.ReplaceFromRecast]];
PipalIO.RegisterClass[tilingClass, ReadTiling, WriteTiling];
Pipal.PutClassMethod[markerClass, PipalInt.sizeMethod, NEW [PipalInt.SizeProc _ SizeMarker]];
Pipal.PutClassMethod[markerClass, PipalReal.sizeMethod, NEW [PipalReal.SizeProc _ PipalReal.UseIntSize]];
Pipal.PutClassMethod[markerClass, PipalInt.abutBoxMethod, NEW [PipalInt.AbutBoxProc _ PipalInt.AbutBoxFromSize]];
Pipal.PutClassMethod[markerClass, PipalPaint.paintMethod, NEW [PipalPaint.PaintProc _ PaintMarker]];
Pipal.PutClassMethod[markerClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeMarker]];
Pipal.PutClassMethod[markerClass, Pipal.hashMethod, NEW [Pipal.HashProc _ HashMarker]];
Pipal.PutClassMethod[markerClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualMarker]];
PipalIO.RegisterClass[markerClass, ReadMarker, WriteMarker];
Pipal.PutClassMethod[schematicIconClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeSchematicIcon]];
Pipal.PutClassMethod[schematicIconClass, Pipal.hashMethod, NEW [Pipal.HashProc _ PipalOps.HashByEnumeration]];
Pipal.PutClassMethod[schematicIconClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualSchematicIcon]];
Pipal.PutClassMethod[schematicIconClass, PipalInt.sizeMethod, NEW [PipalInt.SizeProc _ PipalInt.CachedSizeFromEnumerate]];
Pipal.PutClassMethod[schematicIconClass, PipalInt.enumerateMethod, NEW [PipalInt.EnumerateProc _ EnumerateSchematicIcon]];
Pipal.PutClassMethod[schematicIconClass, PipalOps.replaceMethod, NEW [PipalOps.ReplaceProc _ ReplaceSchematicIcon]];
PipalIO.RegisterClass[schematicIconClass, ReadSchematicIcon, WriteSchematicIcon];
Pipal.PutClassMethod[schematicSequenceClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeSchematicSequence]];
Pipal.PutClassMethod[schematicSequenceClass, Pipal.hashMethod, NEW [Pipal.HashProc _ PipalOps.HashByEnumeration]];
Pipal.PutClassMethod[schematicSequenceClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualSchematicSequence]];
Pipal.PutClassMethod[schematicSequenceClass, PipalInt.sizeMethod, NEW [PipalInt.SizeProc _ PipalInt.CachedSizeFromEnumerate]];
Pipal.PutClassMethod[schematicSequenceClass, PipalInt.enumerateMethod, NEW [PipalInt.EnumerateProc _ EnumerateSchematicSequence]];
Pipal.PutClassMethod[schematicSequenceClass, PipalOps.replaceMethod, NEW [PipalOps.ReplaceProc _ ReplaceSchematicSequence]];
PipalIO.RegisterClass[schematicSequenceClass, ReadSchematicSequence, WriteSchematicSequence];
Pipal.PutClassMethod[textClass, PipalInt.sizeMethod, NEW [PipalInt.SizeProc _ SizeText]];
Pipal.PutClassMethod[textClass, PipalInt.bboxMethod, NEW [PipalInt.BBoxProc _ BBoxText]];
Pipal.PutClassMethod[textClass, PipalReal.sizeMethod, NEW [PipalReal.SizeProc _ PipalReal.UseIntSize]];
Pipal.PutClassMethod[textClass, PipalInt.abutBoxMethod, NEW [PipalInt.AbutBoxProc _ AbutBoxText]];
Pipal.PutClassMethod[textClass, PipalPaint.paintMethod, NEW [PipalPaint.PaintProc _ PaintText]];
Pipal.PutClassMethod[textClass, Pipal.describeMethod, NEW [Pipal.DescribeProc _ DescribeText]];
Pipal.PutClassMethod[textClass, Pipal.hashMethod, NEW [Pipal.HashProc _ HashText]];
Pipal.PutClassMethod[textClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualText]];
PipalIO.RegisterClass[textClass, ReadText, WriteText];
Pipal.PutClassMethod[pictureClass, PipalInt.sizeMethod, NEW [PipalInt.SizeProc _ SizePicture]];
Pipal.PutClassMethod[pictureClass, PipalReal.sizeMethod, NEW [PipalReal.SizeProc _ PipalReal.UseIntSize]];
Pipal.PutClassMethod[pictureClass, PipalInt.abutBoxMethod, NEW [PipalInt.AbutBoxProc _ PipalInt.AbutBoxFromSize]];
Pipal.PutClassMethod[pictureClass, PipalPaint.paintMethod, NEW [PipalPaint.PaintProc _ PaintPicture]];
Pipal.PutClassMethod[pictureClass, Pipal.hashMethod, NEW [Pipal.HashProc _ HashPicture]];
Pipal.PutClassMethod[pictureClass, Pipal.equalMethod, NEW [Pipal.EqualProc _ EqualPicture]];
PipalIO.RegisterClass[pictureClass, ReadPicture, WritePicture];
Pipal.PutClassMethod[starClass, isAtomicMethod, NEW [IsAtomicProc _ Pipal.AlwaysTrue]];
Pipal.PutClassMethod[Pipal.annotationClass, isAtomicMethod, NEW [IsAtomicProc _ IsAnnotationAtomic]];
Pipal.PutClassMethod[clippedEnumerationClass, PipalInt.enumerateMethod, NEW [PipalInt.EnumerateProc _ EnumerateClippedEnumeration]];
END.

���ô��PipalMosImpl.mesa
Copyright Ó 1988 by Xerox Corporation.  All rights reserved.
Created by Bertrand Serlet March 6, 1988 1:20:51 pm PST
Bertrand Serlet May 23, 1988 4:15:23 pm PDT

Short Cuts
Layers
Box
Star
Routing
Tiling
Checking all right
Marker
Schematic Icons
Schematic Sequences
Text
Picture
rect is in meters now!
Could be made denser!
Annotations
The annotation value is NIL

Atomicity

This function does not create a ClippedEnumeration, but rather creates the most appropriate representation.  This is the key to space/time trade-offs.
Mask Layers
Of course, we should have a message here, instead of a type dispatch!
Transistors
Initialization
Layers
Box
Star
Routing
Tiling
Marker
Schematic Icons
Schematic Sequence
Text
Picture
Atomicity
Ê#–��–
"cedar" style˜�codešœ™Kšœ<™<Kšœ4Ïk™7Kšœ+™+K™�—š	˜	Kšœ˜Kšœw˜wKšœ˜KšœE˜EKšœœ˜!K˜�—•StartOfExpansion[]šÏnœœ˜Kšœ‰œY˜ëKšœ˜Kšœœ
˜—head™
Kšœœ	œ˜Kšœœ˜Kšœ	œ˜Kšœœ˜/Kšœœ˜%—™šœ)˜)K˜�—Kšœœ˜"Kšœœ˜&šœœ˜.K˜�—šžœœœœœœ˜Fšžœ˜#Kšœœ˜Kšœœœœ˜6Kšœœ˜K˜—Kšœ(˜(K˜—š
žœœœœœ˜@Kšœœœ˜ K˜—šžœœœ5˜TKšœ,˜,K˜—šžœœœœ'˜ZJšœœ'˜5J˜—š
ž
œœœœœ˜9Jšœœ˜$J˜—š
žœœœœœ˜:Jšœœ˜&J˜—š
žœœœœœ˜?Jšœœ˜.J˜——™šœ
œ6œ˜UK˜�—šžœœ˜@K˜�—šžœ˜"Kšœœ
˜Kšœ>˜>Kšœ$˜$KšœB˜BKšœ˜K˜�—šžœ˜#Kšœœ
˜Kšœ!˜!Kšœœœ)˜YK˜K˜�—šžœ˜Kšœœ
˜Kšœœœ3˜WK˜K˜�—šžœ˜Kšœœ˜Kšœœ˜Kšœ˜K˜K˜�—šž	œœœ%œ˜QKšœœœœ˜%Kšœœœœ˜)Kšœœ'˜0K˜K˜�—šžœ˜$Kšœœ
˜Kšœ)˜)Kšœ%˜%Kšœ˜K˜�—šžœ˜"Kšœ4˜4Kšœ(˜(Kšœ˜Kšœ˜——™šœœ7œ˜XK˜�—šžœ˜$Kšœ
œ
˜Kšœ!˜!Kšœ%œœœœ
œ˜xKšœ8˜8K˜K˜�—šž
œ˜)Kšœ
œ
˜Kšœ#œœœ˜8šœœœ˜!Kšœ%˜%Kšœœœ˜Kšœ˜—K˜K˜�—š
žœœœœœ˜PJš
œœœœœ˜=Jšœ%œœ˜2Jšœ?˜?K˜K˜�—šž
œœœ4œœœ˜qKšœœ˜šœ'œœ˜;Kšœ˜Kšœ"˜"Kšœ˜—Kšœœ˜Kšœ˜Kšœ˜Jš
œœœ
œ:œ˜^K˜K˜�—šžœœœœ	œœœ˜Nšœœœ˜!Jšœœ$˜0Jšœ˜—K˜K˜�—šžœœœœœœœœ˜^šœœœ˜!Jšœ'˜'šœœ!˜'Jšœœ˜3—Jšœ˜—K˜K˜�—šžœ˜%Kšœ
œ
˜Kšœ(˜(Kšœœ˜ š	œœ
œœ˜,Kšœ
œ˜.Kšœ˜—Kšœ=˜=K˜K˜�—šž	œ˜%Kšœ
œ
˜Kšœ,˜,Kšœ)˜)Kšœ$˜$Kš
œœœœ&œ˜OK˜K˜�—šžœ˜#Jšœ
œ˜-Jšœ2˜2KšœF˜FKšœ˜——™šœœ:œ˜aK˜�—šžœ˜'Kšœœ
˜#Kšœ!˜!Kšœ œ˜8K˜K˜�—šžœ˜,Kšœœ
˜#šœœœ˜$Kšœ(˜(Kšœœœ˜Kšœ˜—K˜K˜�—šž
œœœœ˜JKšœœ˜ Kšœ
œ˜!Jš
œœœ
œ.œ˜RK˜K˜�—šžœ˜(Kšœœ
˜#Kšœœ˜š	œœ
œœ˜/Kšœœ˜'Kšœ˜—Kšœ!˜!K˜K˜�—šžœ˜(Kšœœ
˜#Kšœ'˜'Kš
œœœœ)œ˜UK˜K˜�—šžœ˜&Kšœ4˜4Kšœ˜——™šœ
œ9œ˜^K˜�—šžœ˜&Kšœœ
˜!Kšœ!˜!Kšœœœ˜MK˜K˜�—šžœ˜+Kšœœ
˜!Kšœ˜Kšœ
˜
šœœœ˜$Kšœ
˜
šœœœ˜$Kšœ/˜/Kšœ:˜:Jšœœœ˜Jšœ-˜-Kšœ˜—JšœJ˜JKšœ˜—K˜K˜�—šžœœœœœœœ˜oKšœ	œH˜TKšœ™Kšœ	œ	œœ˜!šœœœ˜Jšœœ=˜Hšœœœ˜JšœBœœÏc8˜ˆKšœ˜—Kšœ˜—šœœœ˜Jšœœ=˜Gšœœœ˜JšœAœœŸ:˜‰Kšœ˜—Kšœ˜—K˜K˜�—šžœœœ&œœœ˜aKšœ ˜ šœœœ˜$Kšœ
˜
šœœœ˜$Jšœ0˜0Jšœ˜Jšœœœ˜Jšœ.˜.Kšœ˜—JšœJ˜JKšœ˜—K˜K˜�—šžœ˜'Kšœœ
˜!Jšœ'˜'Jšœ'˜'šœœœ˜$Kš
œœœœ?œ˜kKšœ˜—Kšœ˜K˜�—Kš
œœœœœœœ˜FKšœœœœœœ˜Bšžœ˜Kšœœœ˜,Kšœ˜K˜K˜�—šž
œ˜%Kšœœœ˜+Kšœœœ˜+Kšœœœ˜8šœœœ˜Kšœœ˜)Kš
œœœœ.œ˜SKšœ˜—Kšœ<˜<Kšœ˜——™šœ
œ9œ˜^K˜�—šž
œ˜!Kšœœ
˜!Jšœ˜Kšœ˜K˜�—šžœ˜%Kšœœ
˜!KšœA˜AJšœ"˜"Kšœ$˜$Kšœ5˜5Kšœ5˜5Kšœ˜K˜�—šžœ˜&Kšœœ
˜!Kšœ!˜!Kšœœœ,˜bK˜K˜�—šž
œ˜Kšœœ
˜!Kšœœœ9˜]K˜K˜�—šžœ˜ Kšœœ˜#Kšœœ˜#Kšœ˜K˜K˜�—šžœœœ%œ˜ZKšœœœœ˜)Kšœ	œ*˜6K˜K˜�—šžœ˜'Kšœœ
˜!Kšœ,˜,Kšœ(˜(Kšœ˜K˜�—šž
œ˜%Kšœ4˜4Kšœ(˜(Kšœ˜"Kšœ˜——™šœœ@œ˜sK˜�—šžœ˜-Kšœœ
˜&Kšœ!˜!Kšœ*œœœœœ	œœœ?œœ˜ãK˜K˜�—šžœ˜'Kšœœ˜(Kšœœ˜(Kšœ7œœœ'˜•K˜K˜�—šžœ˜2Kšœœ
˜&Kšœ(˜(K˜K˜�—šžœœœ)œœœ˜•KšœœU˜_K˜K˜�—šžœ˜.Kšœœ
˜&Kšœ&˜&KšœN˜NK˜K˜�—šžœ˜.Kšœœ
˜&Kšœ(˜(Kšœ+˜+Kšœ%˜%Kšœœ˜*Kšœ˜K˜�—šžœ˜,Kšœ1˜1Kšœœ˜2Kšœœ˜&Kšœœ˜#Kšœœ˜$Kšœ5˜;Kšœ˜——™šœœDœ˜K˜�—šžœ˜1Kšœœ
˜)Kšœ!˜!Kšœ&œ˜AK˜K˜�—šžœ˜+Kšœœ˜+Kšœœ˜+Kšœ5œ%˜]K˜K˜�—šžœ˜6Kšœœ
˜)Kšœ'˜'K˜K˜�—š
žœœœ)œœ˜wKšœœA˜JK˜K˜�—šžœ˜2Kšœœ
˜)Kšœ%˜%Kšœ;˜;K˜K˜�—šžœ˜2Kšœœ
˜)Kšœ'˜'Kšœ*˜*Kšœ˜K˜�—šžœ˜0Kšœ1˜1Kšœœ˜2Kšœ-˜3Kšœ˜——™šœœ7œ˜XK˜�—šžœœœ˜@KšœD˜DKšœS˜SKšœ	œ%˜1Kšœ	œ!˜-KšœœÏbœ˜/Kšœœ œ	˜)Kšœ<˜<K˜K˜�—Kšžœ.œ˜MKšžœ4œ˜Qšžœ˜KšœCœ˜UKšœ˜K˜�—šž	œ˜#Kšœ
œ
˜Kšœ(˜(KšœE˜EKšœ˜K˜�—šžœ˜$Kšœ
œ
˜Kšœ!˜!Kšœœ˜1K˜K˜�—šžœ˜Kšœ
œ
˜KšœJ˜JK˜K˜�—šž	œ˜Kšœœ˜Kšœœ˜Kšœ3œ˜MK˜K˜�—š
ž
œœœœœ˜TKšœœœœ˜Kšœœ.˜8K˜K˜�—š
žœœœœœ˜FKšœ˜Kšœ
œ˜Kšœ%œ˜7Kšœ˜K˜K˜�—šžœœœœœœœ˜AKšœœœ˜CKšœœœ˜CKšœœ˜"šœ˜šœDœ˜QKšœ0˜6——šœ˜šœDœœ˜RKšœ/˜5——K˜K˜�—šž	œ˜%Jšœ
œ
˜Kšœ
œ˜#Jšœ)˜)Jšœ@˜@Jšœœ+˜KKšœ˜K˜�—šžœ˜#Kšœœ˜0KšœR˜RKšœœ˜,KšœT˜TKšœF˜FKšœ˜$Kšœ˜——™šœœ:œ˜aK˜�—šžœ˜"Kšœœ
˜#J˜Kšœ˜K˜�—šžœ˜&Kšœœ
˜#JšœAœ˜GKšœ˜K˜�—šž
œœœ4œ˜lKšœœœœ˜Kšœ
œ9˜FK˜K˜�—Kšž	œœœ˜šžœ˜Kšœ
˜Kšœ˜K˜�—šœœ/˜CJ˜�—šžœœœ ˜XJšœœŸ˜/Jšœ=˜=šžœœ˜,J˜'J˜%J˜$J˜%Jšœ(œ˜-Jšœ˜—Jšœœ4˜;Jšœ=˜=JšœV˜VJšœ™K˜K˜�—Kšœ	œœ˜šœœœ=˜VK˜�—šžœœ3˜GJšœœ
˜&Jšœ/˜/Jšœ'˜'JšœI˜IK˜K˜�—š
žœœœ%œœ˜qKšœJ˜JJšœ3˜3šœ;˜;Kšœ>˜>Kš
œœœœœœœ˜ƒKšœ˜—šœ˜Kšœ˜KšœPœ4˜ŠKšœ˜—K˜K˜�—šžœ˜Jšœœ
˜#KšœI˜IK˜K˜�—šžœ˜!Kšœœ˜%Kšœœ˜%Kšœ$œ>˜eK˜K˜�—šž
œœœœ˜Ešžœœ˜/Jšœ9˜9J˜—Jš	œœœœœ˜Jšœd˜dJšœ?˜?Jšœ"˜"Jšœœ˜K˜K˜�—Kšœ™šžœ˜(Jšžœ.œ˜@Jšœœ
˜#Jšœœ˜*Jšœ-˜-Jšœ,˜,Jšœ,˜,Kšœ˜K˜�—šžœ˜&šž
œœœœ˜#Jšœœ˜#Jšœœ˜J˜—Jšœ4˜4Jšœœ˜&Jšœœ%˜7Jšœ-˜3Kšœ˜——™šœœœ˜)Kšœ™K™�—šœœœ˜%K˜�—šœœœ˜)K˜�—šœœœ˜-K˜�—šžœ˜$Kšœœ
˜/Jšœœœ ˜cK˜——™	šœœ4˜JK˜�—šžœœ˜!Kšœ	œœ.˜PKšœœ	œœœœ˜UK˜K˜�—šžœœ˜2šžœ˜(šœœ˜Jšœ˜!Jšœ9˜=—K˜—Kšœ,˜,K˜K˜�—šœœEœ˜‚K˜�—šžœœœ&œ-˜Kšœœ>˜VK˜K˜�—šžœ˜7–_ -- [transformation: PipalInt.Transformation, child: Pipal.Object] RETURNS [quit: BOOL _ FALSE]šžœ˜$Kšœ5œ$˜_Kšœ˜—Kšœœ
˜)Kšœ;˜;K˜K˜�—š
žœœœœ	œ	˜NKšž	œ/˜8Kšœ,˜,K˜K™�—Kšœœ˜Kšœ–™–šžœœœ&œ
˜UKšœS˜SKšœœ+˜5Kšœœ˜šž
œ˜)Kšœœœ˜Kšœœ=˜LKšœ˜—Kšœœœ˜;Kšœ4œœ˜AKšœ˜"K˜—K˜�—™šžœœœ|œœœœœ˜Îšžœ˜(JšœE™Ešœ˜$šœ
˜
Jšœœ	˜Jš
œœœœJœ˜‘J˜—šœ˜Jšœœ	˜ Jšœœœœ!œPœ˜®J˜—Jšœ˜JšœD˜K—J˜—Kšœ,˜,K˜K˜�—š
žœœœœœ˜=Kšžœ7˜;KšœNœ˜\K˜K˜�—šžœœ˜šžœ˜1Jšœ<˜<Jšœ˜—šžœ˜1Jšœ<˜<Jšœ˜—šžœ˜.šžœ˜/Jšœ3œ˜DJ˜—Jšœ˜Jšœ˜JšœF˜FJ˜—Jšœœ`œœ˜rJšœ œœ>˜kJšœ œœ>˜kJšœA˜GJ˜J˜�—šžœœ˜!š
žœœ œœœ˜EJšœœœœœœ˜0Jšœœ˜*J˜—šž
œœ œ
˜DJšœœ
˜Jšœ˜$J˜—šœœœ˜,JšœCœ˜FJšœA˜AJšœ˜—šœœœ˜,JšœCœ˜FJšœA˜AJšœ˜—šœœœ˜,JšœCœ˜FJšœA˜AJšœ˜—šœœœ˜,JšœCœ˜FJšœA˜AJšœ˜—šœœœœ˜AJšœZ˜ZJšœ˜—šœœœœ˜AJšœZ˜ZJšœ˜—Jšœ0˜6J˜J˜�—šžœœ˜$šžœ˜1Jšœ<˜<Jšœ˜—šžœ˜1Jšœ<˜<Jšœ˜—Jšœœ`œœ˜rJšœ œœ>˜kJšœ œœ>˜kJš	œ%œ%œœŸ(˜‚JšœOœœ˜]Jšœœœ˜AJšœ˜J˜�—š
žœœœœœ˜@š
ž	œœ/œœœ˜WJšœœ˜/J˜—š
žœœ/œœœ˜Tšœœœ˜AJšœœœ˜9—J˜—šœ˜JšœKœI˜—Jšœ˜JšœKœI˜—Jšœ$œ#˜KJšœ˜—Jšœ˜——™Kšœœ=˜\šžœœ˜3Kšœœ7œ"˜jK˜——™™šžœœœ˜AKšœd˜dK˜—Kšœ)˜)Kšœ+˜+Kšœ(˜(Kšœ'˜'Kšœ'˜'Kšœ0˜0Kšœ0˜0Kšœ(˜(Kšœ(˜(Kšœ%˜%Kšœ%˜%Kšœ'˜'Kšœ%˜%Kšœ%˜%Kšœ'˜'Kšœ-˜-—™Kšœ4œ ˜WKšœ5œ.˜fKšœ7œ4˜nKšœ7œ$˜^Kšœ5œ%˜]Kšœ1œ˜QKšœ2œ˜TKšœ3˜3—™Kšœ6œ&˜_Kšœ2œ0˜eKšœ3œ2˜hKšœ5œ9˜qKšœ5œ9˜qKšœ8œ?˜zKšœ:œ+˜hKšœ8œ'˜bKšœ6˜6—šœ™Kšœ9œ)˜eKšœ5œ6˜nKšœ6œ2˜kKšœ8œ9˜tKšœ8œ9˜tKšœ;œ?˜}Kšœ=œ.˜nKšœ;œ*˜hKšœ?˜?—šœ™Kšœ8œ(˜cKšœ4œ6˜mKšœ5œ2˜jKšœ7œ9˜sKšœ7œ9˜sKšœ:œ?˜|Kšœ<œ-˜lKšœ:œ6˜sKšœ<˜<—™Kšœ7œ#˜]Kšœ8œ.˜iKšœ:œ4˜qKšœ:œ'˜dKšœ8œ(˜cKšœ4œ ˜WKšœ5œ"˜ZKšœ<˜<—™Kšœ?œ/˜qKšœ;œ0˜nKšœ<œ)˜hKšœ>œ9˜zKšœCœ4˜zKšœAœ0˜tKšœQ˜Q—™KšœCœ3˜yKšœ?œ0˜rKšœ@œ-˜pKšœBœ9˜~KšœGœ8˜‚KšœEœ4˜|Kšœ]˜]—™Kšœ5œ!˜YKšœ5œ!˜YKšœ6œ.˜gKšœ8œ'˜bKšœ8œ%˜`Kšœ6œ&˜_Kšœ2œ˜SKšœ3œ ˜VKšœ6˜6—™Kšœ8œ$˜_Kšœ9œ.˜jKšœ;œ4˜rKšœ;œ(˜fKšœ5œ!˜YKšœ6œ#˜\Kšœ?˜?—™	Jšœ0œ$˜WJšœ<œ&˜eJšœHœ9˜„——Kšœ˜K˜�—�…—����•œ��¼&��