DIRECTORY Convert, Feedback, GGBoundBox, GGColorOps, GGCoreOps, GGCoreTypes, GGParseIn, GGParseOut, Imager, ImagerColor, ImagerColorES, ImagerColorFns, ImagerColorPrivate, ImagerDeviceVector, ImagerInterpress, ImagerPrivate, ImagerState, ImagerTransformation, Interpress, IO, PutGet, RefText, Rope, SimpleFeedback, SymTab, TextNode; GGParseImpl: CEDAR PROGRAM IMPORTS Convert, Feedback, GGBoundBox, GGColorOps, GGCoreOps, Imager, ImagerColor, ImagerColorES, ImagerColorFns, ImagerColorPrivate, ImagerInterpress, ImagerState, ImagerTransformation, Interpress, IO, PutGet, RefText, Rope, SimpleFeedback, SymTab EXPORTS GGParseOut, GGParseIn, Imager, ImagerColor, GGColorOps = BEGIN BoundBox: TYPE = GGCoreTypes.BoundBox; Color: TYPE = Imager.Color; Point: TYPE = Imager.VEC; RopeListt: TYPE = GGCoreTypes.RopeListt; SequenceOfReal: TYPE = REF SequenceOfRealObj; SequenceOfRealObj: TYPE = GGCoreTypes.SequenceOfRealObj; StrokeEnd: TYPE = Imager.StrokeEnd; StrokeJoint: TYPE = Imager.StrokeJoint; Class: TYPE ~ REF ClassRep; ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; -- export to Imager.ClassRep PixelProc: TYPE ~ ImagerColorPrivate.PixelProc; State: TYPE ~ REF StateRep; StateRep: PUBLIC TYPE ~ ImagerState.StateRep; TupleProc: TYPE ~ ImagerColorPrivate.TupleProc; Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = Feedback.Problem; ColorType: TYPE = GGColorOps.ColorType; OperatorType: TYPE = GGColorOps.OperatorType; ColorOperator: TYPE = ImagerColor.ColorOperator; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; CMYK: TYPE = ImagerColorFns.CMYK; ColorOperatorClassRep: PUBLIC TYPE ~ ImagerColorPrivate.ColorOperatorClassRep; WriteColor: PUBLIC PROC [f: IO.STREAM, color: Color] = { gray: ImagerColor.OpConstantColor _ ImagerColor.ColorFromGray[1]; IF color=NIL THEN f.PutRope["[]"] ELSE { f.PutChar['[]; WITH color SELECT FROM op: ImagerColor.OpConstantColor => { SELECT GetOperatorType[GetColorType[op].op] FROM grayLinear, grayDensity, grayVisual => { --put out "MakeGray" val: REAL; WriteNAT[f, 1]; val _ ImagerColorPrivate.IntensityFromColor[op]; f.PutF[" %g]", [real[1.0 - val]]]; }; map, buildMap, rgbLinear, xeroxRgbLinear, colorMap => { -- put out an RGB r, g, b: REAL; WriteNAT[f, 0]; [r,g,b] _ GGCoreOps.ExtractRGB[op]; f.PutF[" %g %g %g]", [real[r]], [real[g]], [real[b]]]; }; cmyk => { cmyk: CMYK; WriteNAT[f, 5]; cmyk _ CMYKFromColor[op]; f.PutF[" %g %g %g %g]", [real[cmyk.C]], [real[cmyk.M]], [real[cmyk.Y]], [real[cmyk.K]] ]; }; yesLinear => { yes: ImagerColorES.YES; WriteNAT[f, 6]; yes _ ImagerColorES.YESFromColor[op]; f.PutF[" %g %g %g]", [real[yes.Y]], [real[yes.E]], [real[yes.S]] ]; }; ENDCASE => ERROR; }; special: ImagerColor.SpecialColor => { WriteNAT[f, 2]; f.PutF[" %g]", [rope[special.name]]]; }; sampledBlack: ImagerColor.SampledBlack => { WriteNAT[f, 3]; f.PutChar[IO.SP]; WriteSampledColor[f, sampledBlack]; f.PutChar[']]; }; sampledColor: ImagerColor.SampledColor => { WriteNAT[f, 4]; f.PutChar[IO.SP]; WriteSampledColor[f, sampledColor]; f.PutChar[']]; }; ENDCASE => { --black rectangles for sampled colors WriteNAT[f, 1]; f.PutF[" %g]", [real[0]]]; }; }; }; ExtractCMYK: PUBLIC PROC [color: ImagerColor.ConstantColor] RETURNS [c,m,y,k: REAL] = { cmyk: ImagerColorFns.CMYK; op: ImagerColor.OpConstantColor; IF color=NIL THEN ERROR Problem["NIL color for ExtractCMYK"]; op _ NARROW[color]; cmyk _ GGColorOps.CMYKFromColor[op]; c _ cmyk.C; m _ cmyk.M; y _ cmyk.Y; k _ cmyk.K; }; ExtractIntensity: PUBLIC PROC [color: ImagerColor.ConstantColor] RETURNS [intensity: REAL] = { IF color=NIL THEN ERROR Problem["NIL color for ExtractIntensity"]; intensity _ ImagerColorPrivate.IntensityFromColor[color]; }; RopeFromOpType: ARRAY OperatorType OF ROPE _ [ grayLinear: "Xerox/GrayLinear", grayDensity: "Xerox/GrayDensity", grayVisual: "Xerox/GrayVisual", map: "Xerox/Map", buildMap: "Xerox/BuildMap", rgbLinear: "Xerox/Research/RGBLinear", xeroxRgbLinear: "Xerox/RGBLinear", colorMap: "Xerox/Research/ColorMap", cmyk: "Xerox/Research/CMYK", yesLinear: "Xerox/YESLinear", cielab: "Xerox/CIELAB", highlightLinear: "Xerox/HighlightLinear", process: "Xerox/Process", highlight: "Xerox/Highlight" ]; GetColorType: PUBLIC PROC [color: ImagerColor.Color] RETURNS [type: ColorType, op: ColorOperator] ~ { WITH color SELECT FROM color: ImagerColor.OpConstantColor => {type _ constantOp; op _ color.colorOperator}; color: ImagerColor.SpecialColor => {type _ constantSpecial; op _ NIL}; color: ImagerColor.SampledColor => {type _ sampled; op _ color.colorOperator}; color: ImagerColor.SampledBlack => {type _ sampledBlack; op _ NIL}; ENDCASE => ERROR; }; GetOperatorType: PUBLIC PROC [op: ColorOperator] RETURNS [OperatorType] ~ { class: REF ColorOperatorClassRep _ op.class; type: OperatorType _ SELECT TRUE FROM Rope.Equal[class.name, "Xerox/GrayLinear"] => grayLinear, Rope.Equal[class.name, "Xerox/GrayDensity"] => grayDensity, Rope.Equal[class.name, "Xerox/GrayVisual"] => grayVisual, Rope.Equal[class.name, "Xerox/Map"] => map, Rope.Equal[class.name, "Xerox/BuildMap"] => buildMap, Rope.Equal[class.name, "Xerox/Research/RGBLinear"] => rgbLinear, Rope.Equal[class.name, "Xerox/RGBLinear"] => xeroxRgbLinear, Rope.Equal[class.name, "Xerox/Research/ColorMap"] => colorMap, Rope.Equal[class.name, "Xerox/Research/CMYK"] => cmyk, Rope.Equal[class.name, "Xerox/YESLinear"] => yesLinear, Rope.Equal[class.name, "Xerox/CIELAB"] => cielab, Rope.Equal[class.name, "Xerox/HighlightLinear"] => highlightLinear, Rope.Equal[class.name, "Xerox/Process"] => process, Rope.Equal[class.name, "Xerox/Highlight"] => highlight ENDCASE => ERROR; RETURN[type]; }; CMYKFromColor: PUBLIC PROC [color: ImagerColor.OpConstantColor] RETURNS [cmyk: CMYK] = { IF ImagerColorPrivate.SupportsOutput[color.colorOperator, $CMYK] THEN { pixelIn: PixelProc ~ { RETURN[color.pixel[i]] }; tupleAction: PROC [tupleOut: TupleProc] ~ { cmyk _ [C: tupleOut[0], M: tupleOut[1], Y: tupleOut[2], K: tupleOut[3]]; }; ImagerColorPrivate.TupleFromPixel[color.colorOperator, [type: $CMYK, samplesPerPixelOut: 4], pixelIn, tupleAction]; } ELSE ERROR Problem["CMYKFromColor called with non-CMYK color"]; }; WritePixelArray: PUBLIC PROC [f: IO.STREAM, pa: Imager.PixelArray] = { ipRef: ImagerInterpress.Ref; masterStream: IO.STREAM; masterSize: CARD; masterRope: Rope.ROPE; IF pa = NIL THEN f.PutRope["0"] ELSE { MaskPixelArray: PROC [dc: Imager.Context] = { Imager.MaskPixel[dc, pa]; }; masterStream _ IO.ROS[]; ipRef _ ImagerInterpress.CreateFromStream[masterStream, "Interpress/Xerox/3.0 "]; ImagerInterpress.DoPage[ipRef, MaskPixelArray]; ImagerInterpress.Finish[ipRef]; masterRope _ masterStream.RopeFromROS[]; masterSize _ Rope.Length[masterRope]; f.PutF["%g\n", [integer[masterSize]]]; f.PutRope[masterRope]; }; }; WriteSampledColor: PROC [f: IO.STREAM, sColor: Imager.Color] = { ipRef: ImagerInterpress.Ref; masterStream: IO.STREAM; masterSize: CARD; masterRope: Rope.ROPE; SetTheColor: PROC [dc: Imager.Context] = { Imager.SetColor[dc, sColor]; }; masterStream _ IO.ROS[]; ipRef _ ImagerInterpress.CreateFromStream[masterStream, "Interpress/Xerox/3.0 "]; ImagerInterpress.DoPage[ipRef, SetTheColor]; ImagerInterpress.Finish[ipRef]; masterRope _ masterStream.RopeFromROS[]; masterSize _ Rope.Length[masterRope]; f.PutF["%g\n", [integer[masterSize]]]; f.PutRope[masterRope]; }; WriteNAT: PROC [f: IO.STREAM, val: NAT] = { f.PutF["%g", [integer[val]]]; }; WriteStrokeEnd: PUBLIC PROC [f: IO.STREAM, strokeEnd: StrokeEnd] = { rope: Rope.ROPE; SELECT strokeEnd FROM round => rope _ "round"; square => rope _ "square"; butt => rope _ "butt"; ENDCASE => ERROR; f.PutRope[rope]; }; WriteStrokeJoint: PUBLIC PROC [f: IO.STREAM, strokeJoint: StrokeJoint] = { rope: Rope.ROPE; SELECT strokeJoint FROM round => rope _ "round"; miter => rope _ "miter"; bevel => rope _ "bevel"; ENDCASE => ERROR; f.PutRope[rope]; }; WritePoint: PUBLIC PROC [f: IO.STREAM, point: Point] = { f.PutF["[%g,%g]", [real[point.x]], [real[point.y]]]; }; WriteTransformation: PUBLIC PROC [f: IO.STREAM, transform: ImagerTransformation.Transformation] = { f.PutF["[%g %g %g ", [real[transform.a]], [real[transform.b]], [real[transform.c]]]; f.PutF["%g %g %g]", [real[transform.d]], [real[transform.e]], [real[transform.f]]]; }; WriteFactoredTransformation: PUBLIC PROC [f: IO.STREAM, transform: ImagerTransformation.Transformation] = { factored: ImagerTransformation.FactoredTransformation _ ImagerTransformation.Factor[transform]; f.PutF["[r1: %g s: [%g %g] ", [real[factored.r1]], [real[factored.s.x]], [real[factored.s.y]] ]; f.PutF["r2: %g t: [%g %g]]", [real[factored.r2]], [real[factored.t.x]], [real[factored.t.y]]]; }; WriteFactoredTransformationVEC: PUBLIC PROC [f: IO.STREAM, transform: ImagerTransformation.Transformation] = { factored: ImagerTransformation.FactoredTransformation _ ImagerTransformation.Factor[transform]; f.PutF["[r1: %g s: [%g %g] r2: %g]", [real[factored.r1]], [real[factored.s.x]], [real[factored.s.y]], [real[factored.r2]] ]; }; WriteBox: PUBLIC PROC [f: IO.STREAM, box: BoundBox] = { IF box.null THEN { f.PutRope["[0 0 -1 0]"]; RETURN}; IF box.infinite THEN { f.PutRope["[0 0 0 -1]"]; RETURN}; f.PutF["[%g %g %g %g]", [real[box.loX]], [real[box.loY]], [real[box.hiX]], [real[box.hiY]]]; }; WriteBool: PUBLIC PROC [f: IO.STREAM, bool: BOOL] = { IF bool THEN f.PutRope["T"] ELSE f.PutRope["F"]; }; WriteListOfRope: PUBLIC PROC [f: IO.STREAM, ropes: LIST OF Rope.ROPE] = { IF ropes = NIL THEN RETURN; f.PutRope[ropes.first]; FOR list: LIST OF Rope.ROPE _ ropes.rest, list.rest UNTIL list = NIL DO f.PutRope[", "]; f.PutRope[list.first]; ENDLOOP; }; WriteProps: PUBLIC PROC [f: IO.STREAM, props: LIST OF REF ANY] = { f.PutChar[IO.SP]; FOR name: LIST OF REF ANY _ props, name.rest UNTIL name=NIL DO f.PutRope[NARROW[name.first]]; f.PutChar[IO.SP]; ENDLOOP; }; WriteArrayOfReal: PUBLIC PROC [f: IO.STREAM, reals: SequenceOfReal] = { f.PutChar['[]; IF reals.len > 0 THEN f.PutF["%g", [real[reals[0]]]]; FOR i: NAT IN [1..reals.len) DO f.PutF[" %g", [real[reals[i]]]]; ENDLOOP; f.PutChar[']]; }; WriteScalarButtonValues: PUBLIC PROC [f: IO.STREAM, names: LIST OF Rope.ROPE, values: LIST OF REAL, on: LIST OF BOOL] = { IF values # NIL THEN { f.PutF["[%g %g", IF on.first THEN [character['T]] ELSE [character['F]], [real[values.first]] ]; IF names#NIL AND names.first#NIL THEN f.PutF[" %g", [rope[names.first]] ]; f.PutChar[']]; FOR thisValue: LIST OF REAL _ values.rest, thisValue.rest UNTIL thisValue = NIL DO on _ on.rest; -- move down list of BOOLs IF names#NIL THEN names _ names.rest; -- move down list of names f.PutF[" [%g %g", IF on.first THEN [character['T]] ELSE [character['F]], [real[thisValue.first]] ]; IF names#NIL AND names.first#NIL THEN f.PutF[" %g", [rope[names.first]] ]; f.PutChar[']]; ENDLOOP; }; }; WriteText: PUBLIC PROC [f: IO.STREAM, text: TextNode.Ref, screenStyle: BOOL] = { f.PutF["%g ", [rope[IF screenStyle THEN "T" ELSE "F"]] ]; IF text=NIL THEN f.PutF["%g ", [integer[0]] ] -- byte count of 0 => no text ELSE { r: Rope.ROPE _ PutGet.ToRope[text].output; f.PutF["%g ", [integer[Rope.Length[r]]] ]; f.PutRope[r]; -- for fast, big ropes }; }; SyntaxError: PUBLIC SIGNAL [position: NAT, wasThere: Rope.ROPE, notThere: Rope.ROPE] = CODE; ReadText: PUBLIC PROC [f: IO.STREAM, version: REAL] RETURNS [text: TextNode.Ref, screenStyle: BOOL] = { fillText: Rope.ROPE; nodeSize: CARD _ 0; [screenStyle, ----] _ ReadBool[f, version]; -- read screenStyle. Better be good. nodeSize _ ReadWCARD[f]; -- read number of chars in node IF nodeSize=0 THEN RETURN[NIL, screenStyle]; IF f.PeekChar[]= ' THEN []_ f.GetChar[]; -- don't ask. Leave this in. fillText _ f.GetRope[nodeSize, TRUE]; text _ PutGet.FromRope[fillText]; }; ReadBlank: PUBLIC PROC [f: IO.STREAM] = { [] _ IO.SkipWhitespace[f, TRUE]; }; ReadWhiteSpace: PUBLIC PROC [f: IO.STREAM] = { WhiteSpaceProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM IO.TAB => RETURN [other]; IO.LF =>RETURN [other]; IO.CR =>RETURN [other]; IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; whiteSpace: Rope.ROPE; end: BOOL _ FALSE; [whiteSpace, ----] _ IO.GetTokenRope[f, WhiteSpaceProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR Rope.Size[whiteSpace] = 0 THEN SIGNAL SyntaxError[IO.GetIndex[f], "null", ""]; }; ReadHorizontalBlank: PUBLIC PROC [f: IO.STREAM] RETURNS [good: BOOL] = { HorizontalBlankProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM IO.TAB, IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; whiteSpace: Rope.ROPE; c: CHAR; end: BOOL _ FALSE; good _ TRUE; [whiteSpace, ----] _ IO.GetTokenRope[f, HorizontalBlankProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; c _ Rope.Fetch[whiteSpace, 0]; SELECT c FROM IO.CR, IO.LF => {good _ FALSE; RETURN}; IO.TAB, IO.SP => {good _ TRUE; RETURN}; ENDCASE => {good _ TRUE; IO.Backup[f, c]; RETURN}; }; ReadWord: PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { WordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.TAB => RETURN [break]; IO.LF =>RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ', => RETURN [break]; '] => RETURN [break]; ') => RETURN [break]; ENDCASE => RETURN [other]; }; [word, ----] _ IO.GetTokenRope[f, WordBreakProc !IO.EndOfStream => {word _ NIL; CONTINUE}]; }; ReadWWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { [] _ IO.SkipWhitespace[f, TRUE]; word _ ReadWord[f]; }; ReadRope: PROC [f: STREAM, rope: Rope.ROPE] = { got: ROPE; endofstream: BOOL _ FALSE; got _ f.GetRope[len: Rope.Length[rope], demand: TRUE ! IO.EndOfStream => {endofstream _ TRUE; CONTINUE}]; IF endofstream THEN SIGNAL SyntaxError [IO.GetIndex[f], NIL, rope]; IF NOT Rope.Equal[rope, got, TRUE] THEN SIGNAL SyntaxError [IO.GetIndex[f], got, rope]; }; ReadWRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { [] _ IO.SkipWhitespace[f, TRUE]; ReadRope[f, rope]; }; ReadLine: PUBLIC PROC [f: IO.STREAM] RETURNS [line: Rope.ROPE] = { LineBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR, IO.LF =>RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; [line, ----] _ IO.GetTokenRope[f, LineBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {line _ NIL; RETURN}; IF Rope.Equal[line, "\r"] OR Rope.Equal[line, "\l"] THEN {line _ NIL; RETURN} -- nothing on this line ELSE [----, ----] _ IO.GetTokenRope[f, LineBreakProc]; -- remove trailing }; ReadChar: PUBLIC PROC [f: IO.STREAM, c: CHAR] = { streamC: CHAR; [] _ IO.SkipWhitespace[f, TRUE]; streamC _ IO.GetChar[f]; IF NOT c = streamC THEN SIGNAL SyntaxError[IO.GetIndex[f], Rope.FromChar[streamC], Rope.FromChar[c]]; }; ReadKeyWord: PUBLIC PROC [f: IO.STREAM] RETURNS [keyWord: Rope.ROPE, good: BOOL] = { KeyWordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR, IO.LF =>RETURN [break]; ': => RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; nextChar: Rope.ROPE; [keyWord, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; keyWord _ NIL; RETURN}; [nextChar, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; good _ Rope.Equal[nextChar, ":", TRUE]; }; ReadNAT: PROC [f: IO.STREAM] RETURNS [n: NAT] = { end: BOOL _ FALSE; intRope: Rope.ROPE; [intRope, ----] _ IO.GetTokenRope[f, NATBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {n _ 1; RETURN}; n _ Convert.IntFromRope[intRope ! Convert.Error => {ERROR SyntaxError[position: IO.GetIndex[f], wasThere: IO.PutFR["Couldn't convert %g to an INT", [rope[intRope]]], notThere: NIL]};]; }; NATBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], IO.CR, IO.LF, IO.SP, IO.TAB, '., ',, ': => RETURN [break]; ENDCASE => RETURN [other]; }; ReadCARD: PROC [f: IO.STREAM] RETURNS [n: CARD] = { end: BOOL _ FALSE; cardRope: Rope.ROPE; [cardRope, ----] _ IO.GetTokenRope[f, NATBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {n _ 1; RETURN}; n _ Convert.CardFromRope[cardRope !Convert.Error => {ERROR SyntaxError[position: IO.GetIndex[f], wasThere: IO.PutFR["Couldn't convert %g to a CARD", [rope[cardRope]]], notThere: NIL]};]; }; ReadWNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { [] _ IO.SkipWhitespace[f, TRUE]; n _ ReadNAT[f]; }; ReadWCARD: PUBLIC PROC [f: IO.STREAM] RETURNS [n: CARD] = { [] _ IO.SkipWhitespace[f, TRUE]; n _ ReadCARD[f]; }; ReadReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { RealBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '), '], ', => RETURN [break]; IO.CR, IO.LF, IO.SP, IO.TAB => RETURN [break]; ENDCASE => RETURN [other]; }; realText, buffer: REF TEXT; end: BOOL _ FALSE; buffer _ RefText.ObtainScratch[50]; [realText, ----] _ IO.GetToken[f, RealBreakProc, buffer !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {r _ 0.0; RETURN}; r _ Convert.RealFromRope[RefText.TrustTextAsRope[realText] ! Convert.Error => {ERROR SyntaxError[position: IO.GetIndex[f], wasThere: IO.PutFR["Couldn't convert %g to a REAL", [rope[RefText.TrustTextAsRope[realText]]]], notThere: NIL]}; ]; RefText.ReleaseScratch[buffer]; }; ReadWReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { [] _ IO.SkipWhitespace[f, TRUE]; r _ ReadReal[f]; }; ReadWUpToEndBracket: PROC [f: IO.STREAM] RETURNS [expr: Rope.ROPE] = { CloseBracketProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = { SELECT char FROM '] =>RETURN [break]; ENDCASE => RETURN [other]; }; [] _ IO.SkipWhitespace[f, TRUE]; [expr, ----] _ IO.GetTokenRope[f, CloseBracketProc]; RETURN[IF Rope.Equal[expr, "]"] THEN NIL ELSE expr]; }; OpConstantColor: TYPE ~ ImagerColor.OpConstantColor; ReadColor: PUBLIC PROC [f: IO.STREAM, version: REAL] RETURNS [color: Color] = { s: IO.STREAM; word: Rope.ROPE; ReadBlack: PROC [stream: IO.STREAM] = { found: BOOL _ FALSE; val: SymTab.Val; grayRope: Rope.ROPE _ ReadWUpToEndBracket[stream]; [found, val] _ SymTab.Fetch[colorTab, grayRope]; IF found THEN color _ NARROW[val] ELSE { grayStream: IO.STREAM _ IO.RIS[rope: grayRope]; level: REAL _ ReadWReal[grayStream]; color _ IF level=0.0 THEN Imager.white ELSE IF level=1.0 THEN Imager.black ELSE ImagerColor.ColorFromGray[level]; [] _ SymTab.Insert[colorTab, grayRope, color]; }; }; ReadRGB: PROC [stream: IO.STREAM] = { found: BOOL _ FALSE; val: SymTab.Val; rgbRope: Rope.ROPE _ ReadWUpToEndBracket[stream]; [found, val] _ SymTab.Fetch[colorTab, rgbRope]; IF found THEN color _ NARROW[val] ELSE { r, g, b: REAL; rgbStream: IO.STREAM _ IO.RIS[rope: rgbRope]; r _ ReadWReal[rgbStream]; IF version < 8701.26 THEN ReadChar[rgbStream, ',]; g _ ReadWReal[rgbStream]; IF version < 8701.26 THEN ReadChar[rgbStream, ',]; b _ ReadWReal[rgbStream]; color _ ImagerColor.ColorFromRGB[[r, g, b]]; [] _ SymTab.Insert[colorTab, rgbRope, color]; }; }; ReadCMYK: PROC [stream: IO.STREAM] = { found: BOOL _ FALSE; val: SymTab.Val; cmykRope: Rope.ROPE _ ReadWUpToEndBracket[stream]; [found, val] _ SymTab.Fetch[colorTab, cmykRope]; IF found THEN color _ NARROW[val] ELSE { c, m, y, k: REAL; cmykStream: IO.STREAM _ IO.RIS[rope: cmykRope]; c _ ReadWReal[cmykStream]; m _ ReadWReal[cmykStream]; y _ ReadWReal[cmykStream]; k _ ReadWReal[cmykStream]; color _ ImagerColorFns.ColorFromCMYK[[c, m, y, k]]; [] _ SymTab.Insert[colorTab, cmykRope, color]; }; }; ReadYESLinear: PROC [stream: IO.STREAM] = { found: BOOL _ FALSE; val: SymTab.Val; yesRope: Rope.ROPE _ ReadWUpToEndBracket[stream]; [found, val] _ SymTab.Fetch[colorTab, yesRope]; IF found THEN color _ NARROW[val] ELSE { y, e, s: REAL; yesStream: IO.STREAM _ IO.RIS[rope: yesRope]; y _ ReadWReal[yesStream]; e _ ReadWReal[yesStream]; s _ ReadWReal[yesStream]; color _ ImagerColorES.ColorFromYES[[y, e, s]]; [] _ SymTab.Insert[colorTab, yesRope, color]; }; }; SELECT TRUE FROM version >= 8706.24 => { key: NAT; ReadWRope[f, "["]; word _ ReadWWord[f]; IF Rope.Equal[word, "]"] THEN RETURN[NIL]; key _ Convert.IntFromRope[word ! Convert.Error => {ERROR SyntaxError[position: IO.GetIndex[f], wasThere: IO.PutFR["Couldn't convert %g to an INT", [rope[word]]], notThere: NIL]};]; SELECT key FROM 0 => ReadRGB[f]; 1 => ReadBlack[f]; 2 => color _ ImagerColor.Find[ReadColorToken[f]]; 3, 4 => color _ ReadSampledColor[f]; 5 => ReadCMYK[f]; 6 => ReadYESLinear[f]; ENDCASE => ERROR; ReadWRope[f, "]"]; }; version < 8701.26 => { word _ ReadColorToken[f]; IF Rope.Equal[word, "none"] THEN RETURN[NIL]; IF f.PeekChar[]='] THEN ReadWRope[f, "]"]; s _ IO.RIS[word, colorStream]; ReadChar[s, '[]; ReadRGB[s]; IF ImagerColorPrivate.GrayFromColor[NARROW[color]] = 1.0 THEN color _ Imager.black; -- the default used to be "black toner" }; ENDCASE => { --8701.26 < version < 8706.24 isBlackToner, good: BOOL; word _ ReadBracketedExpression[f]; IF word = NIL THEN RETURN[NIL]; s _ IO.RIS[word, colorStream]; [isBlackToner, good] _ ReadBool[s, version]; IF NOT good THEN ERROR; IF isBlackToner THEN ReadBlack[s] ELSE ReadRGB[s]; }; }; -- end of ReadColor ReadColorToken: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { ColorBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM '], IO.SP, IO.CR, IO.LF, IO.TAB => RETURN [break]; ENDCASE => RETURN [other]; }; [] _ IO.SkipWhitespace[f, TRUE]; [word, ----] _ IO.GetTokenRope[f, ColorBreakProc ! IO.EndOfStream => {word _ NIL; CONTINUE}]; }; ReadPixelArray: PUBLIC PROC [f: IO.STREAM] RETURNS [pa: Imager.PixelArray] = { ipMaster: Interpress.Master _ NIL; masterText: Rope.ROPE; masterSize: CARD; masterSize _ ReadWCARD[f]; ReadBlank[f]; IF masterSize = 0 THEN pa _ NIL ELSE { masterText _ IO.GetRope[f, masterSize, TRUE]; ipMaster _ Interpress.FromRope[masterText, NIL]; pa _ ReadPixelArrayFromIP[ipMaster]; }; }; ReadSampledColor: PROC [f: IO.STREAM] RETURNS [sColor: Imager.Color] = { ipMaster: Interpress.Master _ NIL; masterText: Rope.ROPE; masterSize: CARD; masterSize _ ReadWCARD[f]; ReadBlank[f]; masterText _ IO.GetRope[f, masterSize, TRUE]; ipMaster _ Interpress.FromRope[masterText, NIL]; sColor _ ReadColorFromIP[ipMaster]; }; ReadPixelArrayFromIP: PROC [ipMaster: Interpress.Master] RETURNS [pa: Imager.PixelArray] = { ShowWarnings: Interpress.LogProc = { SimpleFeedback.Append[$MessageWindow, oneLiner, $Warning, explanation]; }; ReadMaster: PROC [context: Imager.Context] = { Interpress.DoPage[master: ipMaster, page: 1, context: context, log: ShowWarnings]; }; pa _ CapturePixelArray[action: ReadMaster]; }; ReadColorFromIP: PROC [ipMaster: Interpress.Master] RETURNS [sColor: Imager.Color] = { ShowWarnings: Interpress.LogProc = { SimpleFeedback.Append[$MessageWindow, oneLiner, $Warning, explanation]; }; ReadMaster: PROC [context: Imager.Context] = { Interpress.DoPage[master: ipMaster, page: 1, context: context, log: ShowWarnings]; }; sColor _ CaptureColor[action: ReadMaster]; }; CaptureColorData: TYPE ~ REF CaptureColorDataRep; CaptureColorDataRep: TYPE ~ RECORD [ color: Imager.Color, pa: Imager.PixelArray ]; CreateColorContext: PROC [] RETURNS [Imager.Context] ~ { data: CaptureColorData ~ NEW[CaptureColorDataRep _ [color: NIL, pa: NIL]]; state: State ~ ImagerState.CreateState[]; state.color _ Imager.black; RETURN[NEW[Imager.ContextRep _ [class: captureColorClass, state: state, data: data]]]; }; CaptureColor: PROC [action: PROC [Imager.Context]] RETURNS [Imager.Color] = { context: Imager.Context ~ CreateColorContext[]; action[context]; WITH context.data SELECT FROM data: CaptureColorData => RETURN [data.color]; ENDCASE => ERROR; }; CapturePixelArray: PROC [action: PROC [Imager.Context]] RETURNS [Imager.PixelArray] = { context: Imager.Context ~ CreateColorContext[]; action[context]; WITH context.data SELECT FROM data: CaptureColorData => RETURN [data.pa]; ENDCASE => ERROR; }; MySetSampledColor: PUBLIC PROC [context: Imager.Context, pa: Imager.PixelArray, m: Imager.Transformation, colorOperator: Imager.ColorOperator] = { data: CaptureColorData ~ NARROW[context.data]; state: State ~ context.state; ImagerState.StateSetSampledColor[context, pa, m, colorOperator]; data.color _ state.color; }; MySetSampledBlack: PUBLIC PROC [context: Imager.Context, pa: Imager.PixelArray, m: Imager.Transformation, clear: BOOL] = { data: CaptureColorData ~ NARROW[context.data]; state: State ~ context.state; ImagerState.StateSetSampledBlack[context, pa, m, clear]; data.color _ state.color; }; MyMaskPixel: PUBLIC PROC [context: Imager.Context, pa: Imager.PixelArray] = { data: CaptureColorData ~ NARROW[context.data]; state: State ~ context.state; data.pa _ pa; }; MySetColor: PUBLIC PROC [context: Imager.Context, color: Imager.Color] = { data: CaptureColorData ~ NARROW[context.data]; data.color _ color; }; ReadStrokeEnd: PUBLIC PROC [f: IO.STREAM] RETURNS [strokeEnd: Imager.StrokeEnd] = { endName: Rope.ROPE; [] _ IO.SkipWhitespace[f, TRUE]; endName _ ReadWWord[f]; SELECT TRUE FROM Rope.Equal[endName, "square", TRUE] => strokeEnd _ square; Rope.Equal[endName, "butt", TRUE] => strokeEnd _ butt; Rope.Equal[endName, "round", TRUE] => strokeEnd _ round; ENDCASE => ERROR; }; ReadStrokeJoint: PUBLIC PROC [f: IO.STREAM] RETURNS [strokeJoint: Imager.StrokeJoint] = { endName: Rope.ROPE; [] _ IO.SkipWhitespace[f, TRUE]; endName _ ReadWWord[f]; SELECT TRUE FROM Rope.Equal[endName, "round", TRUE] => strokeJoint _ round; Rope.Equal[endName, "miter", TRUE] => strokeJoint _ miter; Rope.Equal[endName, "bevel", TRUE] => strokeJoint _ bevel; ENDCASE => ERROR; }; ReadPoint: PUBLIC PROC [f: IO.STREAM] RETURNS [point: Point] = { [] _ IO.SkipWhitespace[f, TRUE]; ReadRope[f, "["]; point.x _ ReadWReal[f]; ReadRope[f, ","]; point.y _ ReadWReal[f]; ReadRope[f, "]"]; }; ReadTransformation: PUBLIC PROC [f: IO.STREAM] RETURNS [transform: ImagerTransformation.Transformation] = { a, b, c, d, e, g: REAL; ReadWRope[f, "["]; a _ ReadWReal[f]; b _ ReadWReal[f]; c _ ReadWReal[f]; d _ ReadWReal[f]; e _ ReadWReal[f]; g _ ReadWReal[f]; ReadWRope[f, "]"]; transform _ ImagerTransformation.Create[a, b, c, d, e, g]; }; ReadFactoredTransformationVEC: PUBLIC PROC [f: IO.STREAM] RETURNS [transform: ImagerTransformation.Transformation] = { r1, sx, sy, r2 : REAL; ReadWRope[f, "[r1:"]; r1 _ ReadWReal[f]; ReadWRope[f, "s:"]; ReadWRope[f, "["]; sx _ ReadWReal[f]; sy _ ReadWReal[f]; ReadWRope[f, "]"]; ReadWRope[f, "r2:"]; r2 _ ReadWReal[f]; ReadWRope[f, "]"]; { OPEN ImagerTransformation; transform _ Cat[Rotate[r1], Scale2[[sx, sy]], Rotate[r2]]; }; }; ReadFactoredTransformation: PUBLIC PROC [f: IO.STREAM] RETURNS [transform: ImagerTransformation.Transformation] = { r1, sx, sy, r2, tx, ty: REAL; ReadWRope[f, "[r1:"]; r1 _ ReadWReal[f]; ReadWRope[f, "s:"]; ReadWRope[f, "["]; sx _ ReadWReal[f]; sy _ ReadWReal[f]; ReadWRope[f, "]"]; ReadWRope[f, "r2:"]; r2 _ ReadWReal[f]; ReadWRope[f, "t:"]; ReadWRope[f, "["]; tx _ ReadWReal[f]; ty _ ReadWReal[f]; ReadWRope[f, "]" ]; ReadWRope[f, "]" ]; { OPEN ImagerTransformation; transform _ Cat[Rotate[r1], Scale2[[sx, sy]], Rotate[r2], Translate[[tx, ty]] ]; }; }; ReadBox: PUBLIC PROC [f: IO.STREAM] RETURNS [box: BoundBox] = { loX, loY, hiX, hiY: REAL; ReadWRope[f, "["]; loX _ ReadWReal[f]; loY _ ReadWReal[f]; hiX _ ReadWReal[f]; hiY _ ReadWReal[f]; ReadWRope[f, "]"]; IF loX = 0.0 AND hiX = -1.0 THEN RETURN[GGBoundBox.NullBoundBox[]]; IF loY = 0.0 AND hiY = -1.0 THEN RETURN[GGBoundBox.CreateBoundBox[0,0,0,0,FALSE,TRUE]]; box _ GGBoundBox.CreateBoundBox[loX, loY, hiX, hiY]; }; ReadBool: PUBLIC PROC [f: IO.STREAM, version: REAL] RETURNS [truth: BOOL, good: BOOL] = { BoolBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], IO.CR, IO.LF, IO.SP, '., ', => RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; boolRope: Rope.ROPE; [] _ IO.SkipWhitespace[f, TRUE]; [boolRope, ----] _ IO.GetTokenRope[f, BoolBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; truth _ FALSE; RETURN}; good _ TRUE; IF version >= 8701.26 THEN { IF Rope.Equal[boolRope, "T", TRUE] THEN truth _ TRUE ELSE IF Rope.Equal[boolRope, "F", TRUE] THEN truth _ FALSE ELSE {truth _ FALSE; good _ FALSE}; } ELSE { IF Rope.Equal[boolRope, "TRUE", TRUE] THEN truth _ TRUE ELSE IF Rope.Equal[boolRope, "FALSE", TRUE] THEN truth _ FALSE ELSE {truth _ FALSE; good _ FALSE}; }; }; ReadListOfRope: PUBLIC PROC [f: IO.STREAM] RETURNS [ropeList: LIST OF Rope.ROPE] = { cr: Rope.ROPE = Rope.FromChar[IO.CR]; lf: Rope.ROPE = Rope.FromChar[IO.LF]; rightParen: Rope.ROPE = Rope.FromChar[')]; rightBracket: Rope.ROPE = Rope.FromChar[']]; RopesOnOneLineOrParenProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = { SELECT char FROM IO.CR, IO.LF, '), '] =>RETURN [break]; IO.SP, IO.TAB, ', , '; => RETURN [sepr]; ENDCASE => RETURN [other]; }; rope: Rope.ROPE; end: BOOL _ FALSE; [] _ IO.SkipWhitespace[f, TRUE]; ropeList _ NIL; WHILE TRUE DO [rope, ----] _ IO.GetTokenRope[f, RopesOnOneLineOrParenProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR rope = NIL THEN RETURN; IF Rope.Equal[rope, cr] OR Rope.Equal[rope, lf] THEN RETURN; IF Rope.Equal[rope, rightParen] THEN { f.Backup[')]; RETURN; }; IF Rope.Equal[rope, rightBracket] THEN { f.Backup[']]; RETURN; }; ropeList _ AppendRopeToRopeList[rope, ropeList]; ENDLOOP; }; ReadScalarButtonValues: PUBLIC PROC [f: IO.STREAM, version: REAL] RETURNS [names: LIST OF Rope.ROPE, values: LIST OF REAL, on: LIST OF BOOL] = { valuePtr: LIST OF REAL; boolPtr: LIST OF BOOL; ropeListt: RopeListt; expr: Rope.ROPE; stream: IO.STREAM; end, nextOn, good: BOOL _ FALSE; nextVal: REAL; nextName: Rope.ROPE _ NIL; [] _ IO.SkipWhitespace[f, TRUE]; [values, valuePtr] _ GGCoreOps.StartRealList[]; [on, boolPtr] _ GGCoreOps.StartBoolList[]; ropeListt _ GGCoreOps.NewRopeListt[]; WHILE TRUE DO expr _ ReadBracketedExpression[f ! IO.EndOfStream, SyntaxError => {end _ TRUE; CONTINUE}]; IF end OR expr = NIL THEN GOTO Done; stream _ IO.RIS[expr, stream]; [nextOn, good] _ ReadBool[stream, version]; IF NOT good THEN ERROR; -- for now nextVal _ ReadWReal[stream]; nextName _ IF IO.EndOf[stream] THEN NIL ELSE ReadWWord[stream]; -- read optional rope [values, valuePtr] _ GGCoreOps.AddReal[nextVal, values, valuePtr]; [on, boolPtr] _ GGCoreOps.AddBool[nextOn, on, boolPtr]; GGCoreOps.AppendRope[nextName, ropeListt]; REPEAT Done => names _ ropeListt.list; ENDLOOP; }; ReadBracketedExpression: PROC [f: IO.STREAM] RETURNS [expr: Rope.ROPE] = { CloseBracketProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = { SELECT char FROM '] =>RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; ReadChar[f, '[ ! SyntaxError => {end _ TRUE; CONTINUE;}; ]; IF end THEN RETURN[NIL]; [expr, ----] _ IO.GetTokenRope[f, CloseBracketProc]; IF Rope.Equal[expr, "]"] THEN RETURN[NIL] ELSE ReadChar[f, ']]; }; RealLength: PROC [list: LIST OF Rope.ROPE] RETURNS [n: INT _ 0] = { UNTIL list = NIL DO n _ n+1; list _ list.rest; ENDLOOP; }; ReadArrayOfReal: PUBLIC PROC [f: IO.STREAM] RETURNS [reals: SequenceOfReal] = { ropeList: LIST OF Rope.ROPE; real: REAL; len, index: NAT; ReadWRope[f, "["]; ropeList _ ReadListOfRope[f]; ReadWRope[f, "]"]; len _ RealLength[ropeList]; reals _ NEW[SequenceOfRealObj[len]]; index _ 0; FOR list: LIST OF Rope.ROPE _ ropeList, list.rest UNTIL list = NIL DO real _ Convert.RealFromRope[list.first ! Convert.Error => {ERROR SyntaxError[position: IO.GetIndex[f], wasThere: IO.PutFR["Couldn't convert %g to a REAL", [rope[list.first]]], notThere: NIL]}]; reals[index] _ real; index _ index + 1; ENDLOOP; }; AppendRopeToRopeList: PROC [rope: Rope.ROPE, list: LIST OF Rope.ROPE] RETURNS [LIST OF Rope.ROPE] = { z: LIST OF Rope.ROPE _ list; IF z = NIL THEN RETURN[CONS[rope,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[rope,NIL]; RETURN[list]; }; colorStream: IO.STREAM; captureColorClass: Class; colorTab: SymTab.Ref; Init: PROC [] = { colorStream _ IO.RIS["This string is longer than any color is likely to be."]; captureColorClass _ NEW[ClassRep _ [ type: $CaptureColor, Save: ImagerState.StateSave, Restore: ImagerState.StateRestore, SetInt: ImagerState.StateSetInt, SetReal: ImagerState.StateSetReal, SetT: ImagerState.StateSetT, SetFont: ImagerState.StateSetFont, SetColor: MySetColor, SetClipper: ImagerState.StateSetClipper, GetInt: ImagerState.StateGetInt, GetReal: ImagerState.StateGetReal, GetT: ImagerState.StateGetT, GetFont: ImagerState.StateGetFont, GetColor: ImagerState.StateGetColor, GetClipper: ImagerState.StateGetClipper, ConcatT: ImagerState.StateConcatT, Scale2T: ImagerState.StateScale2T, RotateT: ImagerState.StateRotateT, TranslateT: ImagerState.StateTranslateT, Move: ImagerState.StateMove, SetXY: ImagerState.StateSetXY, SetXYRel: ImagerState.StateSetXYRel, Show: NIL, ShowText: NIL, StartUnderline: ImagerState.StateStartUnderline, MaskUnderline: ImagerState.StateMaskUnderline, CorrectMask: ImagerState.StateCorrectMask, CorrectSpace: ImagerState.StateCorrectSpace, Space: ImagerState.StateSpace, SetCorrectMeasure: ImagerState.StateSetCorrectMeasure, SetCorrectTolerance: ImagerState.StateSetCorrectTolerance, Correct: ImagerState.StateCorrect, DontCorrect: ImagerState.StateDontCorrect, SetGray: ImagerState.StateSetGray, SetSampledColor: MySetSampledColor, SetSampledBlack: MySetSampledBlack, ShowBackward: NIL, MaskFill: NIL, MaskStroke: NIL, ShowAndFixedXRel: NIL, MaskDashedStroke: NIL, MaskRectangle: NIL, MaskRectangleI: NIL, MaskVector: NIL, MaskPixel: MyMaskPixel, MaskBitmap: NIL, DrawBitmap: NIL, DrawPixels: NIL, DoIfVisible: NIL, DoWithBuffer: NIL, DrawObject: NIL, Clip: ImagerState.StateClip, ClipRectangle: ImagerState.StateClipRectangle, ClipRectangleI: ImagerState.StateClipRectangleI, GetCP: ImagerState.StateGetCP, GetBounds: NIL, ViewReset: NIL, ViewTranslateI: NIL, ViewClip: NIL, ViewClipRectangleI: NIL, GetTransformation: NIL, Transform: NIL, MoveViewRectangle: NIL, TestViewRectangle: NIL, propList: NIL ]]; colorTab _ SymTab.Create[]; }; Init[]; END. ˆGGParseImpl.mesa Last edited by Bier, January 22, 1992 11:00 am PST Copyright ำ 1986, 1989 by Xerox Corporation. All rights reserved. Contents: Routines which turn various Gargoyle data structures into Rope.ROPEs and write them onto a file stream. Pier, November 20, 1990 3:52 pm PST Maureen Stone, June 25, 1987 2:56:07 pm PDT Doug Wyatt, September 14, 1989 4:03:00 pm PDT Michael Plass, September 18, 1989 11:15:32 am PDT Output Encoding: 0: Red, Green, Blue triple 1: Grey value 2: Special Color 3: Sampled Black (?) 4: Sampled Color (?) cc: ImagerColor.ConstantColor _ NARROW[color]; ColorOperator will be NIL for specialColor and sampledBlack The names are defined in the implementation of the class. All but CMYK are defined in ImagerColorImpl. CMYK is defined in ImagerColorFnsImpl A color operator includes a list of atoms that define the type of color values it can produce. Conventionally, all color operators can produce intensity ($Y) and rgb ($RGB) ImagerColorPrivate IntensityFromColor and RGBFromColor will produce these values. Only the CMYK color model understands the $CMYK atom, so only colors whose color operators are type cmyk should be asked to produce it (the printing software, rather than the color operator, does the RGB to CMYK transformation when printing) Only works for the CMYK color model so check the type first set primaries directly, no color correction YESFromColor: PROC [c: Color] RETURNS [yes: ImagerColorES.YES] ~ BEGIN Exerpted from ImagerColorESImpl. WITH c SELECT FROM sc: ImagerColor.SpecialColor => IF (sc.substitute # NIL) THEN yes _ YESFromColor [sc.substitute] ELSE ERROR Imager.Error [[$noSubstituteColor, "No substitute for SpecialColor"]]; cc: ImagerColor.OpConstantColor => BEGIN PixelIn: PixelProc ~ { RETURN [cc.pixel[i]] }; YesAction: PROC [tupleOut: TupleProc] ~ { yes _ [Y: tupleOut[0], E: tupleOut[1], S: tupleOut[2]] }; IF ImagerColorPrivate.SupportsOutput[cc.colorOperator, $YES] THEN ImagerColorPrivate.TupleFromPixel [cc.colorOperator, [type: $YES, samplesPerPixelOut: 3], PixelIn, YesAction] ELSE ERROR Problem["YESFromColor called with non-YES color"]; END; ENDCASE => ERROR Imager.Error [[$wrongType, "Wrong type (expected ConstantColor)"]] END; -- YESFromColor Write a description of yourself onto stream f. Write the interpress into a Rope.ROPE. Send the rope to stream f. Write a description of yourself onto stream f. Write the interpress into a Rope.ROPE. Send the rope to stream f. Represents Cat[Rotate[r1], Scale2[s], Rotate[r2], Translate[t]]. Gargoyle file format "[r1: REAL s: [REAL REAL] r2: REAL t: [REAL REAL] ]" Like WriteFactoredTransformation but suppresses the translation component Writes out a list of button values in the form: [F 4.0 4] [F 2.0 2] [F 1.0 1] [F 0.75 3/4] ... Input Routines for reading gargoyle data structures from a stream. Reads, 's, 's, and 's until something else is encountered. Doesn't mind if no white space characters are found. Treats comments as white space. Reads, 's, 's, and 's until something else is encountered. Signals SyntaxError if no white space characters are found. Reads 's, and 's until something else is encountered. Returns good = FALSE if a CR is encountered before anything else Used to read in a rope which is data. Removes the given rope from the top of the stream. Used to remove formatting phrases from files. We are not interested in these strings but only in the data in between them. Signals SyntaxError if some other rope is on top. Reads a rope UNTIL is encountered. IF Rope.Equal[line, "\n"] THEN {line _ NIL; RETURN} -- nothing on this line Reads a rope until a ':' or are encountered. If CR is encountered first, then good is FALSE since ":" is expected after a keyword. Reads digits up to the next ], , . Leaves these terminators on the stream. Reads digits up to the next ], , . Leaves these terminators on the stream. A convenience function. A convenience function. Reads digits up to the next ), ], , or . Leaves these terminators on the stream. IF RefText.Find[realText, ".", 0, FALSE] = -1 THEN realText _ RefText.Append[realText, ".0"]; A convenience function. Equivalent to ReadBlank[f]; r _ ReadReal[f]; Reads a rope until , or are encountered. Read a description of yourself from stream f. Read a description of yourself from stream f. Assumes the next rope on the stream will be of the form "[,]". FactoredTransformation: TYPE ~ RECORD[r1: REAL, s: VEC, r2: REAL, t: VEC]; Represents Cat[Rotate[r1], Scale2[s], Rotate[r2], Translate[t]]. Expects "[r1: REAL s: [REAL REAL] r2: REAL ]. No translation" FactoredTransformation: TYPE ~ RECORD[r1: REAL, s: VEC, r2: REAL, t: VEC]; Represents Cat[Rotate[r1], Scale2[s], Rotate[r2], Translate[t]]. Gargoyle file format "[r1: REAL s: [REAL REAL] r2: REAL t: [REAL REAL] ]" Tries to read T or F from the stream. If it encounters another word, good = FALSE; Reads a list of REALs enclosed in square brackets, separated by spaces, tabs, commas, or semi-colons. For instance [3.5, 2.6, 1, 4. 3.0 ] returns a list of 5 real numbers. A copy of List.Nconc1 for LIST OF Rope.ROPE instead of LIST OF REF ANY ส6\˜codešœ™Kšœ2™2KšœB™BKšฯnœj™rKšœ#™#K™+K™-K™1—K™šฯk ˜ Jšœ†žœ:˜ย—K˜š œžœž˜Jšžœภžœ/˜๘Kšžœ9˜@—Kšž˜˜Iprocšœ žœ˜&Lšœžœ˜Lšœžœ žœ˜Kšœ žœ˜(Lšœžœžœ˜-Lšœžœ!˜8Lšœ žœ˜#Lšœ žœ˜'Kšœžœžœ ˜Kšœ žœžœฯc˜LKšœ žœ ˜/Kšœžœžœ ˜Kšœ žœžœ˜-Kšœ žœ ˜/Kšœžœžœ žœ˜;K˜Kšœ žœ˜'Kšœžœ˜-Kšœžœ˜0Kšžœžœžœ˜Kšžœžœžœžœ˜Kšžœžœžœ˜!Kšœžœžœ,˜N—Ihead™š  œžœžœžœžœ˜8K™ K™K™K™K™K™KšœA˜AKšžœžœžœ˜!šžœ˜Lšœ žœ™.L˜šžœžœž˜˜$šžœ&ž˜0šœ)Ÿ˜=Lšœžœ˜ Lšœ˜Lšœ0˜0Lšœ"˜"L˜—šœ8Ÿ˜ILšœ žœ˜Lšœ˜Lšœ#˜#Lšœ6˜6L˜—šœ ˜ Lšœžœ˜ Lšœ˜Lšœ˜LšœY˜YL˜—šœ˜Lšœžœ˜Lšœ˜Lšœ%˜%LšœC˜CL˜—Lšžœžœ˜—L˜—˜'Lšœ˜Lšœ%˜%L˜—šœ+˜+Lšœ˜Lšœ žœžœ˜Lšœ#˜#Lšœ˜L˜—šœ+˜+Lšœ˜Lšœ žœžœ˜Lšœ#˜#Lšœ˜Lšœ˜—šžœŸ%˜2Lšœ˜Lšœ˜L˜——L˜—K˜K˜—š  œžœžœ$žœ žœ˜WKšœžœ˜K˜ Kšžœžœžœžœ&˜=Kšœžœ˜Kšœ$˜$Kšœ1˜1K˜K˜—š œžœžœ$žœ žœ˜^Kšžœžœžœžœ+˜BKšœ9˜9K˜K˜—šœžœžœžœ˜.Kšœ ˜ Kšœ!˜!Kšœ ˜ Kšœ˜Kšœ˜Kšœ&˜&Kšœ"˜"Kšœ$˜$Kšœ˜Kšœ˜Kšœ˜Kšœ)˜)Kšœ˜Kšœ˜K˜—š œž œžœ)˜eKšœžœ"™;šžœžœž˜KšœT˜TKšœAžœ˜FKšœN˜NKšœ>žœ˜CKšžœžœ˜—K˜—šœž œžœ˜KK™ŽKšœžœ"˜,šœžœžœž˜%Kšœ9˜9Kšœ;˜;Kšœ9˜9Kšœ+˜+Kšœ5˜5Kšœ@˜@Kšœ<˜˜>Kšœ6˜6Kšœ7˜7Kšœ1˜1KšœC˜CKšœ3˜3Kšœ6˜6Kšžœžœ˜—Kšžœ˜ K˜—K™^KšœM™MKšœœ œ™QJ™ZJ™YJ™=š œž œ&žœžœ˜XKšœžœ$™;šžœ?žœ˜GKšœ+™+Kšœžœ˜0šœ žœ˜+KšœH˜HKšœ˜—Kšœs˜sK˜—Kšžœžœ5˜?K˜K˜—code2š  œžœ žœžœž™FK™ šžœžœž™šœ™Kšžœžœžœ#™@KšžœžœG™Q—šœ#ž™(Kšœžœ™.š œžœ™'Kšœ;™;—šžœ;ž™AKšœm™m—Kšžœžœ3™=Kšžœ™—KšžœžœC™S—KšžœŸ™K™—šœž œžœžœ˜FK™.Kšœ˜Kšœžœžœ˜Kšœ žœ˜Kšœžœ˜K˜Kšžœžœžœ˜šžœ˜šœžœ˜-Kšœ˜K˜—Kšฯb!ะbk ™&Kšœžœžœ˜KšœQ˜QKšœ/˜/Kšœ˜Kšœ(˜(K•StartOfExpansion[base: ROPE]šœ%˜%K˜Kš ™Kšœ&˜&Kšœ˜K˜—K˜K˜—šœžœžœžœ˜@K™.Kšœ˜Kšœžœžœ˜Kšœ žœ˜Kšœžœ˜š œžœ˜*Kšœ˜K˜—K˜Kš !ก ™&Kšœžœžœ˜KšœQ˜QKšœ,˜,Kšœ˜Kšœ(˜(K–[base: ROPE]šœ%˜%K˜Kš ™Kšœ&˜&Kšœ˜K˜K˜—š œžœžœžœžœ˜+Lšœ˜K˜K˜—š œžœžœžœžœ˜DKšœ žœ˜šžœ ž˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—K˜K˜K˜—š œžœžœžœžœ˜JKšœ žœ˜šžœ ž˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—K˜K˜K˜—š  œžœžœžœžœ˜8Lšœ4˜4K˜K˜—š œžœžœžœžœ5˜cLšœT˜TLšœS˜SL˜K˜—š œžœžœžœžœ5˜kKšœ@™@K™ILšœ_˜_Lšœ`˜`Lšœ^˜^L˜K˜—š œžœžœžœžœ5˜nKšœI™ILšœ_˜_Lšœ|˜|L˜K˜—š œžœžœžœžœ˜7Kšžœ žœžœ˜4Kšžœžœžœ˜8Kšœ\˜\K˜K˜—š  œžœžœžœžœžœ˜5Lšžœžœžœ˜0L˜L˜—šœžœžœžœžœ žœžœžœ˜ILšžœ žœžœžœ˜Lšœ˜š žœžœžœžœžœžœž˜GL˜Lšœ˜Lšžœ˜—L˜L˜—š œžœžœžœžœ žœžœžœžœ˜BKšœ žœžœ˜šžœžœžœžœžœžœžœž˜>Kšœ žœžœžœ˜0Kšžœ˜—K˜K˜—š œžœžœžœžœ˜GK˜Kšžœžœ ˜5šžœžœžœž˜Kšœ ˜ Kšžœ˜—K˜K˜K˜—šœž œžœžœ žœžœžœ žœžœžœžœžœžœ˜yL™/L™.šžœ žœžœ˜Kšœžœ žœžœ)˜_Kš žœžœžœ žœžœ%˜JKšœ˜š žœ žœžœžœžœ žœž˜RKšœŸ˜(KšžœžœžœŸ˜@Kšœžœ žœžœ,˜cKš žœžœžœ žœžœ%˜JKšœ˜Kšžœ˜—K˜—K˜L˜—š  œžœžœžœžœ#žœ˜PKšœžœ žœžœ ˜9KšžœžœžœŸ˜Kšžœ˜Kšœžœ˜*Kšœ*˜*KšœŸ˜$K˜—K˜—Mšœ™Kšœ<™Lšžœžœ ˜—Lšœ˜L˜—š œžœžœžœžœžœ˜3Lšœ žœžœ+™VLšœžœžœ˜Lšœžœ˜šœ Ÿœžœ˜2Lšœžœžœžœ˜+—Lšžœžœ žœ˜šœ!˜!Lš œžœžœžœEžœ˜™—Lšœ˜L˜—šœžœžœžœžœžœžœ˜9Lšœ™Lšœžœžœ˜ Lšœ˜Lšœ˜L˜—š œžœžœžœžœžœžœ˜;Lšœ™Lšœžœžœ˜ Lšœ˜Lšœ˜L˜—šœžœžœžœžœžœžœ˜:Lšœ#žœžœžœ+™dš œžœžœžœžœžœžœ˜Hšžœž˜Lšœžœ ˜Lšžœžœžœžœžœžœžœžœžœ ˜.Lšžœžœ ˜—Lšœ˜—Lšœžœžœ˜Lšœžœžœ˜Lšœ#˜#šœ Ÿœžœ"˜7Lšœžœžœžœ˜+—Lšžœžœ žœ˜Lšžœ žœžœ+™]šœ<˜™>—Lšœžœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜šœ˜L–ฤ[m1: ImagerTransformation.Transformation _ NIL, m2: ImagerTransformation.Transformation _ NIL, m3: ImagerTransformation.Transformation _ NIL, m4: ImagerTransformation.Transformation _ NIL]šžœ˜K–ฤ[m1: ImagerTransformation.Transformation _ NIL, m2: ImagerTransformation.Transformation _ NIL, m3: ImagerTransformation.Transformation _ NIL, m4: ImagerTransformation.Transformation _ NIL]šœ:˜:Lšœ˜—L˜L˜—š œžœžœžœžœžœ5˜sš œžœžœžœžœžœžœ™JKšœ@™@KšœI™I—Lšœžœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜šœ˜L–ฤ[m1: ImagerTransformation.Transformation _ NIL, m2: ImagerTransformation.Transformation _ NIL, m3: ImagerTransformation.Transformation _ NIL, m4: ImagerTransformation.Transformation _ NIL]šžœ˜K–ฤ[m1: ImagerTransformation.Transformation _ NIL, m2: ImagerTransformation.Transformation _ NIL, m3: ImagerTransformation.Transformation _ NIL, m4: ImagerTransformation.Transformation _ NIL]šœP˜PLšœ˜—Lšœ˜L˜—š œžœžœžœžœžœ˜?Lšœžœ˜L˜L˜L˜L˜L˜L˜Lšžœ žœ žœžœ˜CLš žœ žœ žœžœ#žœžœ˜WLšœ4˜4L˜L˜—šœžœžœžœžœ žœžœ žœžœ˜YLšœMžœ™Sš œžœžœžœžœžœžœ˜Hšžœž˜Lšœžœžœžœžœžœžœ žœ ˜2Lšžœžœ ˜—Lšœ˜—Lšœžœžœ˜Lšœžœ˜Lšœžœžœ˜ šœ Ÿœžœ˜3Lšœžœžœžœ˜+—Lš žœžœ žœ žœžœ˜2Lšœžœ˜ šžœžœ˜Lšžœžœžœ ž˜4š žœžœžœžœ ž˜:Lšžœ žœ žœ˜#—L˜—šžœ˜Lšžœžœžœ ž˜7š žœžœžœžœ ž˜>Lšžœ žœ žœ˜#—L˜—Lšœ˜L˜—šœžœžœžœžœžœ žœžœžœ˜TLšœ žœžœžœ˜%Lšœ žœžœžœ˜%Lšœžœ˜*Lšœžœ˜,š œžœžœžœžœžœ˜Lšžœž˜Lš žœžœžœžœ žœ ˜&Lš žœžœžœžœ žœ˜(Lšžœžœ ˜—Lšœ˜—Lšœ žœ˜Lšœžœžœ˜Lšœžœžœ˜ Lšœ žœ˜šžœžœž˜ šœŸœžœ*˜;Lšœžœžœžœ˜+—Lš žœžœžœžœžœ˜!Lšžœžœžœžœ˜<šžœžœ˜&Lšœ ˜ Lšžœ˜L˜—šžœ žœ˜(Lšœ ˜ Lšžœ˜L˜—Lšœ0˜0Lšžœ˜—L˜L˜—š œžœžœžœžœ žœžœ žœžœžœ žœžœžœžœžœžœ˜Lšœ žœžœžœ˜Lšœ žœžœžœ˜Lšœ˜Lšœ žœ˜Lšœžœžœ˜Lšœžœžœ˜ Lšœ žœ˜Lšœžœžœ˜Lšœžœžœ˜ Lšœ/˜/Lšœ*˜*Lšœ%˜%šžœžœž˜ Lšœ#žœ$žœžœ˜ZLš žœžœžœžœžœ˜$Kšœ žœžœ˜Kšœ+˜+Kš žœžœžœžœŸ ˜"Kšœ˜K–[self: STREAM]š œ žœžœžœžœžœŸ˜UKšœB˜BKšœ7˜7Kšœ*˜*šž˜Kšœ˜—Lšžœ˜—L˜L˜—š œžœžœžœžœ žœ˜Jš œžœžœžœžœžœ˜Cšžœž˜Lšœžœ ˜Lšžœžœ ˜—Lšœ˜—Lšœžœžœ˜Lšœ'žœžœ˜;Kšžœžœžœžœ˜LšœŸœžœ#˜4Lšžœžœžœžœ˜)Lšžœ˜L˜L˜—š œžœžœžœžœžœžœ ˜Cšžœžœž˜Kšœ˜Kšœ˜Kšžœ˜—L˜L˜—š œžœžœžœžœžœ˜OL™ฌLšœ žœžœžœ˜Lšœžœ˜ Lšœ žœ˜L˜Lšœ˜L˜Lšœ˜Lšœžœ˜$L˜ š žœžœžœžœžœžœž˜Ešœ&˜&Lš œžœžœžœGžœ˜›—Lšœ˜Lšœ˜Lšžœ˜—L˜L˜—šœžœ žœžœžœžœžœžœžœžœ˜eJšœžœžœžœ žœžœžœž™FJšœžœžœžœ˜Jš žœžœžœžœžœžœ˜'Jšžœ žœžœ žœ˜*Jšœ žœžœ˜Jšžœ˜ Jšœ˜—J˜Jšœ žœžœ˜Jšœ˜Jšœ˜J˜šœžœ˜Jšœžœžœ:˜Nšœžœ ˜$Kšœ˜Kšœ˜Kšœ˜"Kšœ˜ Kšœ˜"Kšœ˜Kšœ˜"Kšœ ˜Kš œ˜(Kšœ˜ Kšœ˜"Kšœ˜Kšœ˜"Kšœ˜$Kš œ˜(Kšœ˜"Kšœ˜"Kšœ˜"Kš œ˜(Kšœ˜Kšœ˜Kšœ˜$Kšœžœ˜ Kšœžœ˜Kšœ"˜0Kš œ!˜.Kš œ˜*Kš œ ˜,Kšœ˜Kšœ%˜6Kšœ'˜:Kšœ˜"Kš œ˜*Kšœ˜"Kšœ˜#Kšœ˜#Kš œžœ˜Kšœžœ˜Kš œžœ˜Kšœžœ˜Kšœžœ˜Kš œžœ˜Kšœžœ˜Kš œžœ˜Kš œ˜Kš œžœ˜Kš œžœ˜Kš œžœ˜Kš œžœ˜Kš œžœ˜Kš œžœ˜Kšœ˜Kš œ!˜.Kšœ"˜0Kšœ˜Kš œžœ˜Kš œžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kš œžœ˜Kšœžœ˜Kšœžœ˜Kšœ ž˜ K˜K˜—J˜J˜J˜—J˜J˜L˜Kšžœ˜—…—„Zฯ>