Box
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]]
};
Star
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];
};
Tiling
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]];
Checking all right
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];
};
Marker
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]]
};
Schematic Icons
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]]
};
Schematic Sequences
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]]
};
Text
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]]];
};
debugFlipText:
BOOL ←
FALSE;
-- will be true if the flipping did not work!
PaintText: PipalPaint.PaintProc = {
text: Text ← NARROW [object];
bbox: Rectangle ← ComputeBBoxText[text];
vec: Imager.VEC ← ImagerBackdoor.TransformVec[context, [1, 1], client, surface];
tt: Imager.Transformation ← PipalReal.IntToRealTransformation[[
[IF vec.x<0 THEN bbox.size.x+bbox.base.x+bbox.base.x ELSE 0, IF vec.y<0 THEN bbox.size.y+bbox.base.y+bbox.base.y ELSE 0],
SELECT
TRUE
FROM
vec.y<0 AND vec.x<0 => rotate180,
vec.y<0 => rotate180X,
vec.x<0 => mirrorX,
ENDCASE => identity
]];
IF ImagerBackdoor.GetFont[context]#text.font THEN Imager.SetFont[context, text.font];
PipalPaint.SetColor[context, Imager.black];
Imager.ConcatT[context, tt];
vec ← ImagerBackdoor.TransformVec[context, [1, 1], client, surface];
debugFlipText ← debugFlipText OR vec.x<0 OR vec.y<0;
Imager.SetXY[context, [0, 0]];
Imager.ShowRope[context, text.contents];
Imager.ConcatT[context, ImagerTransformation.Invert[tt]];
PipalReal.DestroyTransformation[tt];
};
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]];
};
Picture
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];
};
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[];
};
pointsPerMeter: REAL = Imager.pointsPerInch / Imager.metersPerInch;
metersPerPoint:
REAL = Imager.metersPerInch / Imager.pointsPerInch;
InterpressDraw:
PROC [self: Imager.Object, context: Imager.Context] = {
Scale:
PROC = {
Imager.Trans[context];
Imager.ScaleT[context, pointsPerMeter];
PipalPaint.SetColor[context, Imager.black];
Interpress.DoPage[master: ipMaster, page: 1, context: context, log: Log];
};
ipMaster: Interpress.Master ← NARROW [self.data];
Interpress.DoPage[master: ipMaster, page: 1, context: context, log: Log];
Imager.DoSave[context, Scale];
};
CreatePictureFromInterpress:
PUBLIC
PROC [size: PipalInt.Size, master: Pipal.
ROPE]
RETURNS [picture: Picture] = {
ipMaster: Interpress.Master ← Interpress.FromRope[rope: master, log: Log];
picture ← CreatePicture[
size,
NEW [Imager.ObjectRep ← [draw: InterpressDraw, clip: [0, 0, size.x, size.y], data: ipMaster]]
NEW [Imager.ObjectRep ← [draw: InterpressDraw, clip: [-9E30, -9E30, 9E31, 9E31], data: ipMaster]]
NEW [Imager.ObjectRep ← [draw: InterpressDraw, clip: [-2000, -2000, 2000, 2000], data: 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.DoPage[ipMaster, DrawPicture];
ImagerInterpress.Finish[ipMaster];
rope ← IO.RopeFromROS[master];
};
Could be made denser!
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]];
};
Atomicity
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;
This function does not create a ClippedEnumeration, but rather creates the most appropriate representation. This is the key to space/time trade-offs.
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]];
};
Initialization
Layers
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"];
Box
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];
Star
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];
Routing
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];
Tiling
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];
Marker
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];
Schematic Icons
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];
Schematic Sequence
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];
Text
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];
Picture
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];
Atomicity
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]];