DIRECTORY Basics USING [IsBound], Commander USING [CommandProc, Register], Convert USING [RealFromLiteral], FunctionCache USING [Cache, CompareProc, GlobalCache, Insert, Lookup], Imager USING [Box, ConcatT, Context, DoSave, ScaleT, Trans, Transformation, Warning], ImagerMemory USING [GetContextSize, NewMemoryContext, Replay], ImagerTransformation USING [ApplyPreTranslate, Scale], InterpressInterpreter USING [classAppearanceError, classAppearanceWarning, classComment, classMasterError, classMasterWarning, DoPage, FromRope, LogProc, Master], IO USING [PutFR1, PutRope, STREAM], NodeProps USING [DeclarePropertyAttribute, GetProp], NodeStyle USING [GetLineFormatting, GetReal, Ref], ProcessProps USING [GetProp], Real USING [Round], Rope USING [Equal, Fetch, Match, ROPE, Run, Size], RuntimeError USING [UNCAUGHT], Scaled USING [Float, Floor, FromReal], SimpleFeedback USING [Append, Blink], TEditFormat, TextEdit USING [Size], TextNode USING [Ref], ViewerOps USING [PaintEverything]; ArtworkInterpressImpl: CEDAR PROGRAM IMPORTS Basics, Commander, Convert, FunctionCache, Imager, ImagerMemory, ImagerTransformation, InterpressInterpreter, IO, NodeProps, NodeStyle, ProcessProps, Real, Rope, RuntimeError, Scaled, SimpleFeedback, TEditFormat, TextEdit, ViewerOps ~ BEGIN ROPE: TYPE ~ Rope.ROPE; GetBounds: PROC [prop: REF, nodeStyle: NodeStyle.Ref] RETURNS [box: Imager.Box ¬ [0,0,0,0]] ~ { rope: ROPE ~ WITH prop SELECT FROM r: ROPE => r, ENDCASE => NIL; size: INT ~ Rope.Size[rope]; IF size # 0 THEN { i: INT ¬ -1; Getc: PROC RETURNS [CHAR] ~ {i¬i+1; RETURN [IF i r ¬ r*0.001; Match["cm"] => r ¬ r*0.01; Match["in"] => r ¬ r*0.0254; Match["pt"] => r ¬ r*0.0254/72.27; Match["bp"] => r ¬ r*0.0254/72; ENDCASE => ERROR; r ¬ r*pointsPerMeter; GetTok[]; SELECT TRUE FROM Match["xmin"] => box.xmin ¬ r; Match["xmax"] => box.xmax ¬ r; Match["ymin"] => box.ymin ¬ r; Match["ymax"] => box.ymax ¬ r; ENDCASE => ERROR; ENDLOOP; } ELSE { box.ymax ¬ NodeStyle.GetReal[nodeStyle, $topLeading]; box.ymin ¬ -NodeStyle.GetReal[nodeStyle, $bottomLeading]; box.xmax ¬ NodeStyle.GetReal[nodeStyle, $lineLength]; }; }; Floor: PROC [r: REAL] RETURNS [i: INT] ~ { i ¬ Real.Round[r]; IF i > r THEN i ¬ i-1; }; Ceiling: PROC [r: REAL] RETURNS [i: INT] ~ { i ¬ Real.Round[r]; IF i < r THEN i ¬ i+1; }; PositiveMin: PROC [a, b: REAL] RETURNS [REAL] ~ { IF a < 0 THEN RETURN [MAX[b, 0.01]]; IF b < 0 THEN RETURN [a]; RETURN [MIN[a, b]] }; HasFit: PROC [node: TextNode.Ref] RETURNS [BOOL] ~ { WITH NodeProps.GetProp[n: node, name: $Fit] SELECT FROM b: REF BOOL => RETURN [b­]; rope: ROPE => RETURN [Rope.Equal[rope, "TRUE"]]; ENDCASE => RETURN [FALSE]; }; DetermineScaleFactor: PROC [box: Imager.Box, lineWidth: REAL] RETURNS [REAL] ~ { size: REAL ~ MAX[box.xmax-box.xmin, 1]; scaleFactor: REAL ~ lineWidth/size; RETURN [scaleFactor] }; ReportUncaught: PROC [who: Rope.ROPE] ~ { SimpleFeedback.Append[$Artwork, begin, $Error, "Artwork Interpress UNCAUGHT ERROR during "]; SimpleFeedback.Append[$Artwork, end, $Error, who]; SimpleFeedback.Blink[$Artwork, $Error]; }; Format: TEditFormat.FormatProc ~ { inner: PROC ~ { extraIndent: REAL ~ nodeStyle.GetReal[$firstIndent]; leftIndent: REAL ~ nodeStyle.GetReal[$leftIndent] + extraIndent; rightIndent: REAL ~ nodeStyle.GetReal[$rightIndent]; clippedLineWidth: REAL ~ PositiveMin[nodeStyle.GetReal[$lineLength], Scaled.Float[lineWidth]]; trimmedLineWidth: REAL ~ MAX[clippedLineWidth-leftIndent-rightIndent, 0]; box: Imager.Box ¬ GetBounds[NodeProps.GetProp[n: node, name: $Bounds], nodeStyle]; lineInfo.artworkData ¬ NIL; IF HasFit[node] THEN { scaleFactor: REAL ~ DetermineScaleFactor[box, trimmedLineWidth]; m: Imager.Transformation ¬ ImagerTransformation.Scale[scaleFactor]; ImagerTransformation.ApplyPreTranslate[m, [-box.xmin, -box.ymin]]; box.xmax ¬ (box.xmax-box.xmin)*scaleFactor; box.ymax ¬ (box.ymax-box.ymin)*scaleFactor; box.xmin ¬ 0; box.ymin ¬ 0; lineInfo.artworkData ¬ m; }; lineInfo.xmin ¬ Floor[box.xmin]; lineInfo.ymin ¬ Floor[box.ymin]; lineInfo.xmax ¬ Ceiling[box.xmax]; lineInfo.ymax ¬ Ceiling[box.ymax]; SELECT nodeStyle.GetLineFormatting[] FROM FlushLeft => {lineInfo.xOffset ¬ Scaled.FromReal[leftIndent]}; FlushRight => {lineInfo.xOffset ¬ Scaled.FromReal[MAX[Scaled.Float[lineWidth]-leftIndent-box.xmax, 0]]}; Centered, Justified => {lineInfo.xOffset ¬ Scaled.FromReal[leftIndent+(trimmedLineWidth-box.xmax)/2]}; ENDCASE => ERROR; }; lineInfo.startPos ¬ [node, 0]; lineInfo.nextPos ¬ [node, TextEdit.Size[node]]; lineInfo.nChars ¬ TextEdit.Size[node]; inner[ ! RuntimeError.UNCAUGHT => IF NOT debug THEN { ReportUncaught["Format"]; CONTINUE }; ]; }; Resolve: TEditFormat.ResolveProc ~ { loc ¬ lineInfo.startPos; xmin ¬ lineInfo.xmin+Scaled.Floor[lineInfo.xOffset]; width ¬ lineInfo.xmax; rightOfLine ¬ FALSE; }; CharPosition: TEditFormat.CharPositionProc ~ { x ¬ lineInfo.xmin+Scaled.Floor[lineInfo.xOffset]; width ¬ lineInfo.xmax; }; BoundingBox: TEditFormat.BoundingBoxProc ~ { RETURN [[lineInfo.xmin, lineInfo.ymin, lineInfo.xmax, lineInfo.ymax]] }; debug: BOOL ¬ FALSE; useFSRope: BOOL ¬ TRUE; pointsPerMeter: REAL ¬ 72/0.0254; memoryCache: FunctionCache.Cache ¬ FunctionCache.GlobalCache[]; cacheID: ROPE ~ "Art"; GetCachedMemoryContext: PROC [ipRope: ROPE] RETURNS [memory: Imager.Context] ~ { Log: InterpressInterpreter.LogProc = { tag: ROPE ~ SELECT class FROM InterpressInterpreter.classMasterError => "Artwork Interpress Master Error: ", InterpressInterpreter.classMasterWarning => "Artwork Interpress Master Warning: ", InterpressInterpreter.classAppearanceError => "Artwork Interpress Appearance Error: ", InterpressInterpreter.classAppearanceWarning => "Artwork Interpress Appearance Warning: ", InterpressInterpreter.classComment => "Artwork Interpress Comment: ", ENDCASE => IO.PutFR1["Artwork Interpress Error class %g: ", [integer[class]]]; WITH ProcessProps.GetProp[$StdOut] SELECT FROM errout: IO.STREAM => { IO.PutRope[errout, tag]; IO.PutRope[errout, explanation]; IO.PutRope[errout, "\n"]; }; ENDCASE => { msgClass: ATOM ~ SELECT class FROM InterpressInterpreter.classMasterError => $Error, InterpressInterpreter.classMasterWarning => $Warning, InterpressInterpreter.classAppearanceError => $Error, InterpressInterpreter.classAppearanceWarning => $Warning, InterpressInterpreter.classComment => $Comment, ENDCASE => $Error; SimpleFeedback.Append[$Artwork, begin, msgClass, tag]; SimpleFeedback.Append[$Artwork, end, msgClass, explanation]; }; }; compare: FunctionCache.CompareProc ~ {good ¬ argument = ipRope}; memory ¬ NARROW[FunctionCache.Lookup[memoryCache, compare, cacheID].value]; IF memory = NIL THEN { proc: PROC ~ { ipMaster: InterpressInterpreter.Master ~ InterpressInterpreter.FromRope[rope: ipRope, log: Log]; InterpressInterpreter.DoPage[master: ipMaster, page: 1, context: memory, log: Log]; }; memory ¬ ImagerMemory.NewMemoryContext[]; proc[ ! RuntimeError.UNCAUGHT => IF NOT debug THEN { ReportUncaught["GetCachedMemoryContext"]; CONTINUE }; ]; FunctionCache.Insert[memoryCache, ipRope, memory, ImagerMemory.GetContextSize[memory], cacheID]; }; }; Paint: TEditFormat.PaintProc ~ { prevMsg: ROPE ¬ NIL; ipRope: ROPE ¬ NARROW[NodeProps.GetProp[lineInfo.startPos.node, $Interpress]]; compare: FunctionCache.CompareProc ~ {good ¬ argument = ipRope}; memory: Imager.Context ~ GetCachedMemoryContext[ipRope]; proc: PROC ~ { Imager.Trans[context]; WITH lineInfo.artworkData SELECT FROM m: Imager.Transformation => Imager.ConcatT[context, m]; ENDCASE => NULL; Imager.ScaleT[context, pointsPerMeter]; ImagerMemory.Replay[c: memory, into: context ! Imager.Warning => { IF error.explanation # prevMsg THEN { SimpleFeedback.Append[$Artwork, begin, $Warning, "Artwork Interpress Warning: "]; SimpleFeedback.Append[$Artwork, end, $Warning, error.explanation]; prevMsg ¬ error.explanation; }; RESUME; }; ]; }; Imager.DoSave[context, proc ! RuntimeError.UNCAUGHT => IF NOT debug THEN { ReportUncaught["Paint"]; CONTINUE }; ]; }; class: TEditFormat.ArtworkClass ~ NEW[TEditFormat.ArtworkClassRep ¬ [ name: $Interpress, format: Format, paint: Paint, resolve: Resolve, charPosition: CharPosition, boundingBox: BoundingBox ]]; Command: Commander.CommandProc ~ { oldState: BOOL ¬ TEditFormat.ArtworkEnabled[]; newState: BOOL ¬ oldState; SELECT TRUE FROM Rope.Match["*on*", cmd.commandLine, FALSE] => { newState ¬ TRUE; }; Rope.Match["*off*", cmd.commandLine, FALSE] => { newState ¬ FALSE; }; ENDCASE => { cmd.out.PutRope["Please say on or off.\n"]; }; oldState ¬ TEditFormat.SetArtworkEnabled[newState]; IF newState#oldState AND Basics.IsBound[ViewerOps.PaintEverything] THEN ViewerOps.PaintEverything[]; }; NodeProps.DeclarePropertyAttribute[$Interpress, $ClientOnly]; NodeProps.DeclarePropertyAttribute[$Fit, $Visible]; TEditFormat.RegisterArtwork[class]; Commander.Register["Artwork", Command, "Turn Artwork on or off"]; Commander.Register["ArtworkInterpress", Command, "Turn Artwork on or off"]; END. T ArtworkInterpressImpl.mesa Copyright Σ 1985, 1986, 1989, 1990, 1992 by Xerox Corporation. All rights reserved. Michael Plass, March 24, 1992 12:13 pm PST Pier, October 9, 1985 2:39:15 pm PDT Doug Wyatt, October 10, 1990 1:59 pm PDT Invariant: c = (IF iKšœžœ˜6Kšœžœ‡˜’Kšžœžœžœ˜#Kšœ žœ%˜4Kšœ žœ#˜2Kšœ žœ ˜Kšœžœ ˜Kšœžœžœ ˜2Kšœ žœžœ˜Kšœžœ˜&Kšœžœ˜%Kšœ ˜ Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜"—K˜KšΠlnœž ˜$Kšžœožœx˜πšœž˜K˜šžœžœžœ˜K˜—šΟn œžœžœžœ"˜_Kšœžœžœžœžœžœžœžœ˜@Kšœžœ˜šžœ žœ˜Kšœžœ˜ Kš œžœžœžœ žœžœžœžœ˜Sšœžœ ˜Kšœžœžœžœ™5—Kšœ žœ˜Kšœ žœ˜š œžœ˜K˜ Kšžœžœ žœ˜#K˜Kšžœžœžœ žœ˜.Kšœ˜—š  œžœžœžœžœ˜*K•StartOfExpansionO[s1: ROPE, pos1: INT _ 0, s2: ROPE, pos2: INT _ 0, case: BOOL _ TRUE]šœžœ˜Kšžœžœ"žœ˜DKšœ˜—Kšžœžœžœ žœ˜.šžœ ž˜Kšœžœ˜Kšžœžœ˜$Kšœ ˜ K˜.Kšœ ˜ šžœžœž˜K˜K˜K˜K˜"K˜Kšžœžœ˜—K˜Kšœ ˜ šžœžœž˜K˜K˜K˜K˜Kšžœžœ˜—Kšžœ˜—Kšœ˜—šžœ˜Kšœžœ1˜5K˜9Kšœžœ1˜5Kšœ˜—Kšœ˜K˜—š  œžœžœžœžœ˜*K˜Kšžœžœ ˜Kšœ˜K˜—š  œžœžœžœžœ˜,K˜Kšžœžœ ˜Kšœ˜K˜—š   œžœžœžœžœ˜1Kšžœžœžœžœ ˜$Kšžœžœžœ˜Kšžœžœ˜Kšœ˜K˜—š œžœžœžœ˜4šžœ(žœž˜7Kšœžœžœžœ˜Kšœžœžœ˜0Kšžœžœžœ˜—Kšœ˜K˜—š  œžœžœžœžœ˜PKšœžœžœ˜'Kšœ žœ˜#Kšžœ˜Kšœ˜K˜—š œžœ žœ˜)Kšœ]˜]Kšœ2˜2Kšœ'˜'Kšœ˜K˜—š œ˜"šœžœ˜Kšœ žœ#˜4Kšœ žœ0˜@Kšœ žœ#˜4KšœžœH˜^Kšœžœžœ-˜IK˜RKšœžœ˜šžœžœ˜Kšœ žœ/˜@K˜CKšœB˜BK˜+K˜+K˜ K˜ K˜Kšœ˜—K˜ K˜ K˜"K˜"šžœž˜)K˜>Kšœ2žœ3˜hK˜fKšžœžœ˜—Kšœ˜—K˜K˜/K˜&šœžœ˜!Kšžœžœžœžœ˜9Kšœ˜—Kšœ˜K˜—š œ˜$K˜K˜4K˜Kšœžœ˜Kšœ˜K˜—š  œ"˜.K˜1K˜Kšœ˜K˜—š  œ!˜,Kšžœ?˜EKšœ˜K˜—Kšœžœžœ˜Kšœ žœžœ˜Kšœžœ ˜!K–:[maxEntries: INT _ 10, maxTotalSize: INT _ 2147483647]˜?šœ žœ ˜K˜—š œžœ žœžœ˜P–/ -- [class: INT, code: ATOM, explanation: ROPE]š œ#˜&Kšœžœžœžœ™+–-[message: ROPE, clearFirst: BOOL _ FALSE]šœžœžœž˜K˜NK˜RK˜VK˜ZK˜EKšžœžœA˜N—šžœžœž˜.šœžœžœ˜Kšžœ˜Kšžœ˜ Kšžœ˜Kšœ˜—šžœ˜ –-[message: ROPE, clearFirst: BOOL _ FALSE]šœ žœžœž˜"K˜1K˜5K˜5K˜9K˜/Kšžœ ˜—Kšœ6˜6Kšœ<˜