DIRECTORY Convert, Imager, ImagerColor, NodeProps, NodeStyle, Real, Rope, RuntimeError, Scaled, TEditFormat, TextEdit, ViewerOps; ArtworkRuleImpl: CEDAR PROGRAM IMPORTS Convert, Imager, ImagerColor, NodeStyle, Real, Rope, RuntimeError, Scaled, TEditFormat, TextEdit, ViewerOps ~ BEGIN ROPE: TYPE ~ Rope.ROPE; debug: BOOLEAN _ FALSE; Format: TEditFormat.FormatProc ~ { inner: PROC ~ { extraIndent: REAL _ nodeStyle.GetFirstIndent; leftIndent: REAL _ nodeStyle.GetLeftIndent + extraIndent; rightIndent: REAL _ nodeStyle.GetRightIndent; lineLength: REAL ~ nodeStyle.GetLineLength; trimmedLineWidth: REAL ~ (IF lineLength > 0.0 AND lineLength < lineWidth.Float THEN lineLength ELSE lineWidth.Float) - leftIndent - rightIndent; ruleThickness: REAL _ 0.0; ruleLength: REAL _ 0.0; [ruleThickness, ruleLength] _ GetRule[node, nodeStyle ! RuntimeError.UNCAUGHT => {ViewerOps.BlinkDisplay[]; 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[lineWidth.Float-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 _ GetColor[nodeStyle]; lineInfo.formatInfo.length _ lineInfo.formatInfo.length + 1; }; 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]] }; 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]; }; GetColor: PROC [style: NodeStyle.Ref] RETURNS [color: Imager.Color] ~ { brightness: REAL ~ NodeStyle.GetReal[style, textBrightness]; IF brightness = 0.0 THEN { color _ Imager.black; } ELSE { saturation: REAL ~ NodeStyle.GetReal[style, textSaturation]; IF saturation = 0.0 THEN { color _ Imager.MakeGray[1.0-brightness]; } ELSE { hue: REAL ~ NodeStyle.GetReal[style, textHue]; color _ ImagerColor.ColorFromRGB[ImagerColor.RGBFromHSV[[H: hue, S: saturation, V: brightness]]]; }; }; }; pointsPerMeter: REAL _ 72/0.0254; GetRule: PROC [node: TextEdit.RefTextNode, nodeStyle: NodeStyle.Ref] RETURNS [thickness, length: REAL _ 0.0] ~ { rope: ROPE ~ TextEdit.GetRope[node]; size: INT ~ Rope.Size[rope]; IF size # 0 THEN { i: INT _ -1; Getc: PROC RETURNS [CHAR] ~ {i_i+1; RETURN [IF i=size DO GetTok[]; SELECT rope.Fetch[startTok] FROM '- => thickness _ 0.4; ' => thickness _ 0.4; '= => thickness _ 1.0; '~ => thickness _ 0.8*NodeStyle.GetFontSize[nodeStyle]; '# => thickness _ 0.8*NodeStyle.GetFontSize[nodeStyle]; ENDCASE => { SELECT TRUE FROM Match["thickness:"] => thickness _ GetReal[]; Match["length:"] => length _ GetReal[]; ENDCASE => ERROR; }; ENDLOOP; } ELSE { thickness _ 1.0; length _ 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; }; class: TEditFormat.ArtworkClass ~ NEW[TEditFormat.ArtworkClassRep _ [ name: $Rule, format: Format, paint: Paint, resolve: Resolve, charPosition: CharPosition, boundingBox: BoundingBox ]]; TEditFormat.RegisterArtwork[class]; END. ArtworkRuleImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Rick Beach, March 11, 1986 10:28:50 am PST we should be the only client for this format entry stolen unashamedly from TEditFormatImpl.mesa because its not exported returns the length and thickness of the typographic rule defined by the content of the node Invariant: c = (IF i