<> <> <> <<>> 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> 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.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.