<> <> <> <> <> <> <> <> <<>> 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] = { <> <<0: Red, Green, Blue triple>> <<1: Grey value>> <<2: Special Color>> <<3: Sampled Black (?)>> <<4: Sampled 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"]; }; <> <> <> <>> <> <> < BEGIN>> <> <> <<{ yes _ [Y: tupleOut[0], E: tupleOut[1], S: tupleOut[2]] };>> <> <> <> <> < ERROR Imager.Error [[$wrongType, "Wrong type (expected ConstantColor)"]]>> <> <<>> 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] = { <> <<[F 4.0 4] [F 2.0 2] [F 1.0 1] [F 0.75 3/4] ...>> 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] = { <'s, 's, and 's until something else is encountered. Doesn't mind if no white space characters are found. Treats comments as white space.>> [] _ IO.SkipWhitespace[f, TRUE]; }; ReadWhiteSpace: PUBLIC PROC [f: IO.STREAM] = { <'s, 's, and 's until something else is encountered. Signals SyntaxError if no white space characters are found.>> 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] = { <'s, and 's until something else is encountered. Returns good = FALSE if a CR is encountered before anything else>> 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] = { < is encountered.>> 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] = { < are encountered. If CR is encountered first, then good is FALSE since ":" is expected after a keyword.>> 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] = { <, . Leaves these terminators on the stream.>> 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] = { <, . Leaves these terminators on the stream.>> 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] = { <, or . Leaves these terminators on the stream.>> 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] = { <, or are encountered.>> 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.