DIRECTORY Ascii, BrineIO, Imager, ImagerBackdoor, ImagerColor, ImagerFont, ImagerInterpress, ImagerTransformation, ImagerTypeface, Interpress, IO, Pipal, PipalInt, PipalIO, PipalMos, PipalOps, PipalPaint, PipalReal, Real, RefTab, Rope, RopeHash; PipalMosImpl: CEDAR PROGRAM IMPORTS Ascii, BrineIO, Imager, ImagerBackdoor, ImagerColor, ImagerFont, ImagerInterpress, 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]]]; }; 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]]; }; 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.ScaleT[context, pointsPerMeter]; PipalPaint.SetColor[context, Imager.black]; Interpress.DoPage[master: ipMaster, page: 1, context: context, log: Log]; }; ipMaster: Interpress.Master _ NARROW [self.data]; 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: [-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.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 19, 1988 7:04:08 pm PDT Short Cuts Layers Box Star Routing Tiling Checking all right Marker Schematic Icons Schematic Sequences Text Picture Imager.Trans[context]; Interpress.DoPage[master: ipMaster, page: 1, context: context, log: Log]; 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]] ImagerInterpress.DoPage[ipMaster, DrawPicture]; 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šœ$˜$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šœ<˜˜eK˜K˜—šž œœœœ˜Ešž œœ˜/Jšœ9˜9J˜—Jš œœœœœ˜Jšœd˜dJš ?˜?Jš /™/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šœ<˜˜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šœ<˜˜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˜—…—”ฺผา