DIRECTORY Ascii, Convert USING [Error, IntFromRope, RealFromRope], CustomBrick, ImagerBrick USING [Brick], ImagerSample USING [NewSampleMap, Put], IO USING [CharClass, EndOfStream, GetTokenRope, PutFR, RIS, STREAM], PrintColor USING [HalftoneProperties, Toner, TonerUniverse], Real USING [Round], Rope USING [Cat, Concat, Equal, ROPE], RuntimeError USING [UNCAUGHT]; CustomBrickImpl: CEDAR PROGRAM IMPORTS Convert, ImagerSample, IO, Real, Rope, RuntimeError EXPORTS CustomBrick ~ BEGIN Bound: TYPE ~ RECORD [first, last: INT]; int: Bound ~ [INT.FIRST, INT.LAST]; nat: Bound ~ [NAT.FIRST, NAT.LAST]; card: Bound ~ [CARD16.FIRST, CARD16.LAST]; ROPE: TYPE ~ Rope.ROPE; HalftoneProperties: TYPE ~ PrintColor.HalftoneProperties; Toner: TYPE ~ PrintColor.Toner; Brick: TYPE ~ ImagerBrick.Brick; Complain: PROC [rope: ROPE] ~ { }; HalftonePropertiesFromRope: PUBLIC PROC [specs: ROPE, tonerUniverse: PrintColor.TonerUniverse] RETURNS [h: HalftoneProperties] ~ { CmdTokenBreak: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = '_ OR char = '[ OR char = '] THEN RETURN [break]; RETURN [ SELECT char FROM Ascii.SP, Ascii.TAB, ',, ';, Ascii.LF, Ascii.CR => sepr ENDCASE => other ] }; GetCmdToken: PROC [stream: IO.STREAM] RETURNS [rope: ROPE] = { rope ¬ NIL; rope ¬ stream.GetTokenRope[CmdTokenBreak ! IO.EndOfStream => CONTINUE].token; }; RealToNum: PROC [real: REAL, bounds: Bound ¬ int, name: ROPE ¬ NIL] RETURNS [number: INT ¬ 0] ~ { IF name=NIL THEN name ¬ "Value"; number ¬ Real.Round[real ! RuntimeError.UNCAUGHT => CONTINUE]; IF real#number THEN Complain[IO.PutFR[format: "%g (%g) should be integral.", v1: [rope [name]], v2: [real [real]]]]; IF number NOT IN [bounds.first .. bounds.last] THEN Complain[IO.PutFR[format: "Value (%g) should be in range [%g .. %g]", v1: [rope [name]], v2: [integer [bounds.first]], v3: [integer [bounds.last]]]]; }; RealFromRope: PROC [rope: ROPE] RETURNS [real: REAL] = { oops: BOOL ¬ FALSE; real ¬ Convert.RealFromRope[rope ! Convert.Error => {oops ¬ TRUE; CONTINUE}]; IF oops THEN {oops ¬ FALSE; real ¬ Convert.IntFromRope[rope ! Convert.Error => {oops ¬ TRUE; CONTINUE}]}; IF oops THEN Complain[Rope.Concat["Number expected: ", rope]]; }; ParseBrick: PROC ~ { a: REF ARRAY [0..1000) OF INT ¬ NEW[ARRAY [0..1000) OF INT]; sSize: NAT ¬ 0; fSize: NAT ¬ 0; phase: NAT ¬ 0; maxSample: CARDINAL ¬ 0; toner: Toner ¬ black; n: NAT ¬ 0; brick: REF Brick ¬ NEW[Brick]; tok ¬ GetCmdToken[cmds]; WHILE Rope.Equal[tok, "["] DO tok ¬ GetCmdToken[cmds]; WHILE tok # NIL AND NOT Rope.Equal[tok, "]"] DO val: INT ~ RealToNum[RealFromRope[tok], nat]; a[n] ¬ val; n ¬ n + 1; IF sSize = 0 THEN fSize ¬ fSize + 1; tok ¬ GetCmdToken[cmds]; ENDLOOP; sSize ¬ sSize + 1; IF n MOD fSize # 0 THEN Complain["Malformed array"]; tok ¬ GetCmdToken[cmds]; ENDLOOP; IF Rope.Equal[tok, "]"] THEN tok ¬ GetCmdToken[cmds] ELSE Complain["Malformed array"]; phase ¬ RealToNum[RealFromRope[tok], card]; tok ¬ GetCmdToken[cmds]; maxSample ¬ RealToNum[RealFromRope[tok], card]; tok ¬ GetCmdToken[cmds]; SELECT TRUE FROM Rope.Equal[tok, "black", FALSE] => toner ¬ black; Rope.Equal[tok, "cyan", FALSE] => toner ¬ cyan; Rope.Equal[tok, "magenta", FALSE] => toner ¬ magenta; Rope.Equal[tok, "yellow", FALSE] => toner ¬ yellow; ENDCASE => Complain[Rope.Cat["Expected toner name, but found \"", tok, "\""]]; tok ¬ GetCmdToken[cmds]; IF NOT Rope.Equal[tok, "brick", FALSE] THEN Complain["Missing \"brick\" Keyword"]; brick.maxSample ¬ maxSample; brick.sampleMap ¬ ImagerSample.NewSampleMap[box: [max: [sSize, fSize]], bitsPerSample: IF maxSample > 255 THEN BITS[CARDINAL] ELSE 8]; brick.phase ¬ phase; FOR s: NAT IN [0..sSize) DO FOR f: NAT IN [0..fSize) DO val: NAT ~ a[s*fSize+f]; IF val NOT IN [0..maxSample] THEN Complain["Brick values should be IN [0..maxSample]"]; ImagerSample.Put[map: brick.sampleMap, index: [s, f], value: val]; ENDLOOP; ENDLOOP; IF tonerUniverse[toner] THEN h ¬ CONS[[type: NIL, toner: toner, brick: brick­], h]; }; cmds: IO.STREAM ¬ IO.RIS[rope: specs]; tok: ROPE ¬ NIL; h ¬ NIL; UNTIL (tok ¬ GetCmdToken[cmds]) = NIL DO IF Rope.Equal["[", tok] THEN ParseBrick[]; ENDLOOP; }; END.  CustomBrickImpl.mesa Copyright Σ 1988, 1991 by Xerox Corporation. All rights reserved. Dave Rumph, August 11, 1988 0:06:06 am PDT Michael Plass, October 26, 1991 10:20 pm PDT Body RETURNS RECORD [type: ATOM, toner: Toner, brick: ImagerBrick.Brick] Κ 9–(cedarcode) style•NewlineDelimiter ™™Icodešœ Οeœ7™BK™*K™,—K˜šΟk ˜ Kšœ˜Kšœžœ$˜1K˜ Kšœ žœ ˜Kšœ žœ˜'Kšžœžœ/žœžœ˜DKšœ žœ,˜K– "cedar" stylešœžœ˜ K– "cedar" stylešœ+žœžœ˜MKšœ˜—code2š  œžœžœžœžœžœ žœ ˜aKšžœžœžœ˜ Kšœ(žœžœ˜>K•StartOfExpansion[format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]šžœ žœ žœU˜tK–[format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]š žœžœžœžœ žœŠ˜ΙK˜—– "cedar" styleš   œžœžœžœžœ˜8K– "cedar" stylešœžœžœ˜K– "cedar" stylešœ<žœžœ˜MK– "cedar" styleš žœžœ žœ=žœžœ˜iK– "cedar" stylešžœžœ2˜>Kšœ˜—š  œžœ˜Kšœžœžœ žœžœžœžœ žœžœ˜