<<>> <> <> <> <> <> <<>> DIRECTORY Convert USING [RealFromLiteral], Imager USING [Box, DoSave, MaskBox, SetColor, Trans], NodeProps USING [], NodeStyle USING [GetColor, GetReal, GetLineFormatting, Ref], Real USING [Round], Rope USING [Fetch, ROPE, Run, Size], RuntimeError USING [UNCAUGHT], Scaled USING [Float, Floor, FromReal], TEditFormat USING [ArtworkClass, ArtworkClassRep, BoundingBoxProc, CharPositionProc, FormatProc, PaintProc, RegisterArtwork, ResolveProc], TextEditBogus USING [GetRope], TextEdit USING [RefTextNode, Size]; ArtworkRuleImpl: CEDAR PROGRAM IMPORTS Convert, Imager, NodeStyle, Real, Rope, RuntimeError, Scaled, TEditFormat, TextEditBogus, TextEdit ~ BEGIN ROPE: TYPE ~ Rope.ROPE; debug: BOOLEAN ¬ FALSE; Format: TEditFormat.FormatProc ~ { inner: PROC ~ { extraIndent: REAL ¬ nodeStyle.GetReal[$firstIndent]; leftIndent: REAL ¬ nodeStyle.GetReal[$leftIndent] + extraIndent; rightIndent: REAL ¬ nodeStyle.GetReal[$rightIndent]; lineLength: REAL ~ nodeStyle.GetReal[$lineLength]; trimmedLineWidth: REAL ~ (IF lineLength > 0.0 AND lineLength < Scaled.Float[lineWidth] THEN lineLength ELSE Scaled.Float[lineWidth]) - leftIndent - rightIndent; ruleThickness: REAL ¬ 0.0; ruleLength: REAL ¬ 0.0; [ruleThickness, ruleLength] ¬ GetRule[node, nodeStyle ! RuntimeError.UNCAUGHT => {<> CONTINUE}]; IF ruleLength = 0 THEN ruleLength ¬ trimmedLineWidth; lineInfo.xmin ¬ 0; lineInfo.ymin ¬ 0; lineInfo.xmax ¬ Ceiling[ruleLength]; lineInfo.ymax ¬ Ceiling[ruleThickness]; SELECT nodeStyle.GetLineFormatting[] FROM FlushLeft, Justified => {lineInfo.xOffset ¬ Scaled.FromReal[leftIndent]}; FlushRight => {lineInfo.xOffset ¬ Scaled.FromReal[MAX[Scaled.Float[lineWidth]-leftIndent-ruleLength, 0]]}; Centered => {lineInfo.xOffset ¬ Scaled.FromReal[leftIndent+(trimmedLineWidth-ruleLength)/2]}; ENDCASE => ERROR; }; lineInfo.startPos ¬ [node, 0]; lineInfo.nextPos ¬ [node, TextEdit.Size[node]]; lineInfo.nChars ¬ TextEdit.Size[node]; IF lineInfo.formatInfo.length = 0 THEN { <> lineInfo.formatInfo[lineInfo.formatInfo.length].color ¬ NodeStyle.GetColor[nodeStyle, text]; lineInfo.formatInfo.length ¬ lineInfo.formatInfo.length + 1; }; inner[ ! RuntimeError.UNCAUGHT => {IF NOT debug THEN {<> 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]] }; Paint: TEditFormat.PaintProc ~ { inner: PROC ~ { IF lineInfo.formatInfo.length > 0 AND lineInfo.formatInfo[0].color # NIL THEN { Imager.SetColor[context, lineInfo.formatInfo[0].color]; }; Imager.Trans[context]; Imager.MaskBox[context, box]; }; box: Imager.Box ~ BoundingBox[lineInfo, lineInfo.startPos.where, lineInfo.nChars]; Imager.DoSave[context, inner]; }; pointsPerMeter: REAL ¬ 72/0.0254; GetRule: PROC [node: TextEdit.RefTextNode, nodeStyle: NodeStyle.Ref] RETURNS [thickness, length: REAL ¬ 0.0] ~ { <> rope: ROPE ~ TextEditBogus.GetRope[node]; size: INT ~ Rope.Size[rope]; IF size # 0 THEN { i: INT ¬ -1; Getc: PROC RETURNS [CHAR] ~ {i¬i+1; RETURN [IF i> startTok: INT ¬ 0; sizeTok: INT ¬ 0; GetTok: PROC ~ { startTok ¬ i; UNTIL c = ' DO c ¬ Getc[] ENDLOOP; sizeTok ¬ i-startTok; WHILE c = ' AND i=size DO GetTok[]; SELECT rope.Fetch[startTok] FROM '- => thickness ¬ 0.4; ' => thickness ¬ 0.4; '= => thickness ¬ 1.0; '~ => thickness ¬ 0.8*nodeStyle.GetReal[$fontSize]; '# => thickness ¬ 0.8*nodeStyle.GetReal[$fontSize]; ENDCASE => { SELECT TRUE FROM Match["thickness:"] => thickness ¬ GetReal[]; Match["length:"] => length ¬ GetReal[]; ENDCASE => ERROR; }; ENDLOOP; } ELSE { thickness ¬ 1.0; length ¬ nodeStyle.GetReal[$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; }; class: TEditFormat.ArtworkClass ~ NEW[TEditFormat.ArtworkClassRep ¬ [ name: $Rule, format: Format, paint: Paint, resolve: Resolve, charPosition: CharPosition, boundingBox: BoundingBox ]]; TEditFormat.RegisterArtwork[class]; <> END.