DIRECTORY Commander USING [CommandProc, Register], Convert USING [RealFromLiteral], FSRope USING [StreamFromRope], FunctionCache USING [Cache, CompareProc, GlobalCache, Insert, Lookup], Imager USING [Box, ConcatT, Context, DoSave, ScaleT, Trans, Transformation], ImagerMemory USING [GetContextSize, NewMemoryContext, Replay], ImagerTransformation USING [ApplyPreTranslate, Scale], Interpress USING [DoPage, FromStream, Master], IO USING [PutRope, RIS, STREAM], NodeProps USING [GetProp], NodePropsExtras USING [DeclarePropertyAttribute], NodeStyle USING [GetBottomLeading, GetFirstIndent, GetLeftIndent, GetLineFormatting, GetLineLength, GetRightIndent, GetTopLeading, Ref], Real USING [Round], Rope USING [Equal, Fetch, Match, ROPE, Run, Size], RuntimeError USING [UNCAUGHT], Scaled USING [Float, FromReal], TEditFormat USING [ArtworkClass, ArtworkClassRep, BoundingBoxProc, CharPositionProc, FormatProc, GetArtworkClass, PaintProc, RegisterArtwork, ResolveProc, UnRegisterArtwork], TextEdit USING [Size], TextNode USING [Ref], ViewerOps USING [BlinkDisplay, PaintEverything]; ArtworkInterpressImpl: CEDAR PROGRAM IMPORTS Commander, Convert, FSRope, FunctionCache, Imager, ImagerMemory, ImagerTransformation, Interpress, IO, NodeProps, NodePropsExtras, NodeStyle, Real, Rope, RuntimeError, Scaled, 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.GetTopLeading[nodeStyle]; box.ymin _ -NodeStyle.GetBottomLeading[nodeStyle]; box.xmax _ NodeStyle.GetLineLength[nodeStyle]; }; }; 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] }; Format: TEditFormat.FormatProc ~ { inner: PROC ~ { extraIndent: REAL ~ nodeStyle.GetFirstIndent; leftIndent: REAL ~ nodeStyle.GetLeftIndent + extraIndent; rightIndent: REAL ~ nodeStyle.GetRightIndent; clippedLineWidth: REAL ~ PositiveMin[nodeStyle.GetLineLength, lineWidth.Float]; 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[lineWidth.Float-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 {ViewerOps.BlinkDisplay[]; CONTINUE}}]; }; Resolve: TEditFormat.ResolveProc ~ { loc _ lineInfo.startPos; xmin _ lineInfo.xmin+lineInfo.xOffset.integerPart; width _ lineInfo.xmax; rightOfLine _ FALSE; }; CharPosition: TEditFormat.CharPositionProc ~ { x _ lineInfo.xmin+lineInfo.xOffset.integerPart; 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] ~ { compare: FunctionCache.CompareProc ~ {good _ argument = ipRope}; memory _ NARROW[FunctionCache.Lookup[memoryCache, compare, cacheID].value]; IF memory = NIL THEN { ipStream: IO.STREAM _ IF useFSRope THEN FSRope.StreamFromRope[ipRope] ELSE IO.RIS[ipRope]; proc: PROC ~ { ipMaster: Interpress.Master ~ Interpress.FromStream[stream: ipStream, log: NIL]; Interpress.DoPage[master: ipMaster, page: 1, context: memory, log: NIL]; }; memory _ ImagerMemory.NewMemoryContext[]; proc[ ! RuntimeError.UNCAUGHT => {IF NOT debug THEN {ViewerOps.BlinkDisplay[]; CONTINUE}}]; FunctionCache.Insert[memoryCache, ipRope, memory, ImagerMemory.GetContextSize[memory], cacheID]; }; }; Paint: TEditFormat.PaintProc ~ { 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.DoSave[context, proc]; }; class: TEditFormat.ArtworkClass ~ NEW[TEditFormat.ArtworkClassRep _ [ name: $Interpress, format: Format, paint: Paint, resolve: Resolve, charPosition: CharPosition, boundingBox: BoundingBox ]]; Command: Commander.CommandProc ~ { old, new: TEditFormat.ArtworkClass _ NIL; old _ TEditFormat.GetArtworkClass[class.name]; SELECT TRUE FROM Rope.Match["*on*", cmd.commandLine, FALSE] => { TEditFormat.RegisterArtwork[class]; new _ class; }; Rope.Match["*off*", cmd.commandLine, FALSE] => { TEditFormat.UnRegisterArtwork[class.name]; new _ NIL; }; ENDCASE => { cmd.out.PutRope["Please say on or off.\n"]; new _ old; }; IF new#old THEN ViewerOps.PaintEverything[]; }; NodePropsExtras.DeclarePropertyAttribute[$Fit, $Visible]; Commander.Register["ArtworkInterpress", Command, "Turn ArtworkInterpress on or off"]; END. ArtworkInterpressImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Michael Plass, August 22, 1986 3:47:04 pm PDT Pier, October 9, 1985 2:39:15 pm PDT Doug Wyatt, July 23, 1986 11:27:11 am PDT Invariant: c = (IF iKšœžœ˜6Kšœ žœ˜.Kšžœžœ žœžœ˜ Kšœ žœ ˜Kšœžœ˜1Kšœ žœy˜ˆKšœžœ ˜Kšœžœžœ ˜2Kšœ žœžœ˜Kšœžœ˜Kšœ žœ˜®Kšœ žœ˜Kšœ žœ˜Kšœ žœ!˜0—K˜KšÐlnœž ˜$Kšžœdžœk˜Øšœž˜K˜šžœžœžœ˜J˜—šÏn œžœžœžœ"˜_Jšœžœžœžœžœžœžœžœ˜@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šœ˜—šžœ˜Jšœžœ*˜.Jšœ2˜2Jšœžœ*˜.Kšœ˜—Jšœ˜J˜—š  œžœžœžœžœ˜*Kšœ˜Kšžœžœ ˜Kšœ˜K˜—š  œžœžœžœžœ˜,Kšœ˜Kšžœžœ ˜Kšœ˜K˜—š   œžœžœžœžœ˜1Kšžœžœžœžœ ˜$Kšžœžœžœ˜Kšžœžœ˜Kšœ˜K˜—š œžœžœžœ˜4šžœ(žœž˜7Kšœžœžœžœ˜Kšœžœžœ˜0Kšžœžœžœ˜—Kšœ˜K˜—š  œžœžœžœžœ˜PKšœžœžœ˜'Kšœ žœ˜#Kšžœ˜Kšœ˜K˜—š œ˜"šœžœ˜Jšœ žœ˜-Jšœ žœ)˜9Jšœ žœ˜-Kšœžœ9˜OKšœžœžœ-˜IJšœR˜RKšœžœ˜šžœžœ˜Kšœ žœ/˜@KšœC˜CKšœB˜BKšœ+˜+Kšœ+˜+Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜—Jšœ ˜ Jšœ ˜ Jšœ"˜"Jšœ"˜"šžœž˜)Kšœ>˜>Kšœ2žœ+˜`Kšœf˜fKšžœžœ˜—Kšœ˜—Jšœ˜Jšœ/˜/Jšœ&˜&Jš œžœžœžœžœžœ˜\Jšœ˜J˜—š œ˜$Jšœ˜Jšœ2˜2Jšœ˜Jšœžœ˜Jšœ˜J˜—š  œ"˜.Jšœ/˜/Jšœ˜Jšœ˜J˜—š  œ!˜,Jšžœ?˜EJšœ˜J˜—Jšœžœžœ˜Jšœ žœžœ˜Jšœžœ ˜!J–:[maxEntries: INT _ 10, maxTotalSize: INT _ 2147483647]šœ?˜?šœ žœ ˜J˜—š œžœ žœžœ˜PJšœ@˜@Kšœ žœ<˜Kšžœ žœžœ˜Jš œ žœžœžœ žœžœžœ ˜Zšœžœ˜JšœKžœ˜PJšœCžœ˜HJšœ˜—Jšœ)˜)Jš œžœžœžœžœžœ˜[Kšœ`˜`Kšœ˜—Kšœ˜K˜—š œ˜ Jšœžœžœ9˜NJšœ@˜@Jšœ8˜8šœžœ˜K˜šžœžœž˜%Kšœ7˜7Kšžœžœ˜—Kšœ'˜'Jšœ.˜.Kšœ˜—Jšœ˜Jšœ˜J˜—šœ"žœ ˜EJšœ˜J˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜J˜—š œ˜"Kšœ%žœ˜)Kšœ.˜.šžœžœž˜šœ$žœ˜/Kšœ#˜#Kšœ ˜ Kšœ˜—šœ%žœ˜0Kšœ*˜*Kšœžœ˜ K˜—šžœ˜ Kšœ+˜+Kšœ ˜ Kšœ˜——Kšžœ žœ˜,Kšœ˜K˜—Kšœ9˜9KšœU˜UJ˜—K˜Kšžœ˜—…—°(Í