<> <> <> <<>> DIRECTORY Atom USING [DottedPair, DottedPairNode, PropList], Basics USING [bitsPerWord], Font USING [CreateScaled], Imager USING [Box, Color, ConstantColor, Context, ErrorCode, FONT, Matrix, Pair, PathProc, StrokeEnd, Trajectory, TrajectoryList, TrajectoryRep, Transformation], ImagerBasic USING [ColorRep, PixelArray], ImagerConic USING [FromArc], ImagerMasks USING [PixelArrayFromPixelMap], ImagerPixelMaps USING [Create, PixelMap], ImagerTransform USING [Concat, Contents, FromRec, InverseTransform, InverseTransformVec, Invert, Rotate, Scale, Scale2, Transform, TransformVec, Translate], PrincOps USING [BBTableSpace, BBptr], PrincOpsUtils USING [AlignedBBTable, BITBLT], Real USING [RoundLI], Rope USING [ROPE]; ImagerImpl: CEDAR PROGRAM IMPORTS Font, ImagerConic, ImagerMasks, ImagerPixelMaps, ImagerTransform, PrincOpsUtils, Real EXPORTS Imager ~ BEGIN OPEN Imager; ROPE: TYPE ~ Rope.ROPE; <> <> Create: PUBLIC PROC[deviceType: ATOM, data: REF _ NIL] RETURNS [Context] ~ { <> <> ERROR; }; <> Error: PUBLIC ERROR[errorCode: ErrorCode] ~ CODE; <> <> <<>> <> <<>> DoSave: PUBLIC PROC[context: Context, body: PROC] ~ { context.class.DoSave[context, body]; }; DoSaveAll: PUBLIC PROC[context: Context, body: PROC] ~ { context.class.DoSaveAll[context, body]; }; <> SetPriorityImportant: PUBLIC PROC[context: Context, priorityImportant: BOOL] ~ { context.class.SetPriorityImportant[context, priorityImportant]; }; <> PropList: TYPE ~ Atom.PropList; DottedPair: TYPE ~ Atom.DottedPair; DottedPairNode: TYPE ~ Atom.DottedPairNode; <> << >> RemPropFromList: PROC[p: PropList, key: REF] RETURNS[PropList] ~ { IF p=NIL THEN RETURN[NIL] ELSE IF p.first.key=key THEN RETURN[p.rest] ELSE { rest: PropList ~ RemPropFromList[p.rest, key]; IF rest=p.rest THEN RETURN[p] ELSE RETURN[CONS[p.first, rest]]; }; }; PutPropOnList: PROC[p: PropList, key: REF, value: REF] RETURNS[PropList] ~ { rest: PropList ~ RemPropFromList[p, key]; IF value=NIL THEN RETURN[rest] ELSE { pair: DottedPair ~ NEW[DottedPairNode _ [key, value]]; RETURN[CONS[pair, rest]]; }; }; GetPropFromList: PROC[p: PropList, key: REF] RETURNS[value: REF] ~ { FOR list: PropList _ p, list.rest UNTIL list=NIL DO pair: DottedPair ~ list.first; IF pair.key=key THEN RETURN[pair.val]; ENDLOOP; RETURN[NIL]; }; GetProp: PUBLIC PROC[context: Context, key: REF] RETURNS[value: REF] ~ { RETURN[GetPropFromList[context.propList, key]]; }; PutProp: PUBLIC PROC[context: Context, key: REF, value: REF] ~ { context.propList _ PutPropOnList[context.propList, key, value]; }; RemProp: PUBLIC PROC[context: Context, key: REF] ~ { context.propList _ RemPropFromList[context.propList, key]; }; <> <> MakeT: PUBLIC PROC[m: Matrix] RETURNS[Transformation] ~ { RETURN[ImagerTransform.FromRec[m]] }; OpenT: PUBLIC PROC[m: Transformation] RETURNS[Matrix] ~ { RETURN[ImagerTransform.Contents[m]]; }; Scale: PUBLIC PROC[s: REAL] RETURNS[Transformation] ~ { RETURN[ImagerTransform.Scale[s]]; }; Scale2: PUBLIC PROC[sx, sy: REAL] RETURNS[Transformation] ~ { RETURN[ImagerTransform.Scale2[sx, sy]]; }; Rotate: PUBLIC PROC[a: REAL] RETURNS[Transformation] ~ { RETURN[ImagerTransform.Rotate[a]]; }; Translate: PUBLIC PROC[x, y: REAL] RETURNS[Transformation] ~ { RETURN[ImagerTransform.Translate[x, y]]; }; Concat: PUBLIC PROC[m, n: Transformation] RETURNS[Transformation] ~ { RETURN[ImagerTransform.Concat[m, n]]; }; Invert: PUBLIC PROC[m: Transformation] RETURNS[Transformation] ~ { RETURN [ImagerTransform.Invert[m]] }; <> Transform: PUBLIC PROC[m: Transformation, p: Pair] RETURNS[Pair] ~ { RETURN[ImagerTransform.Transform[p, m]] }; TransformVec: PUBLIC PROC[m: Transformation, p: Pair] RETURNS[Pair] ~ { RETURN[ImagerTransform.TransformVec[p, m]] }; InverseTransform: PUBLIC PROC[m: Transformation, p: Pair] RETURNS[Pair] ~ { RETURN[ImagerTransform.InverseTransform[p, m]] }; InverseTransformVec: PUBLIC PROC[m: Transformation, p: Pair] RETURNS[Pair] ~ { RETURN[ImagerTransform.InverseTransformVec[p, m]] }; <<>> <> ConcatT: PUBLIC PROC[context: Context, m: Transformation] ~ { context.class.ConcatT[context, m]; }; ScaleT: PUBLIC PROC[context: Context, s: REAL] ~ { context.class.ScaleT[context, s]; }; <<>> Scale2T: PUBLIC PROC[context: Context, sx, sy: REAL] ~ { context.class.Scale2T[context, sx, sy]; }; RotateT: PUBLIC PROC[context: Context, a: REAL] ~ { context.class.RotateT[context, a]; }; TranslateT: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.TranslateT[context, x, y]; }; <<>> <<>> Move: PUBLIC PROC[context: Context] ~ { context.class.Move[context]; }; <<>> Trans: PUBLIC PROC[context: Context] ~ { context.class.Trans[context]; }; <> <> <<>> LastPoint: PUBLIC PROC[t: Trajectory] RETURNS[x, y: REAL] ~ { RETURN[t.lp.x, t.lp.y]; }; <<>> LastPointP: PUBLIC PROC[t: Trajectory] RETURNS[Pair] ~ { RETURN[t.lp]; }; <<>> MoveTo: PUBLIC PROC[x, y: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[move] _ [prev: NIL, lp: [x, y], variant: move[]]]]; }; <<>> MoveToP: PUBLIC PROC[p: Pair] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[move] _ [prev: NIL, lp: p, variant: move[]]]]; }; <<>> LineTo: PUBLIC PROC[t: Trajectory, x, y: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [prev: t, lp: [x, y], variant: line[]]]]; }; <<>> LineToP: PUBLIC PROC[t: Trajectory, p: Pair] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [prev: t, lp: p, variant: line[]]]]; }; <<>> LineToX: PUBLIC PROC[t: Trajectory, x: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [prev: t, lp: [x, t.lp.y], variant: line[]]]]; }; <<>> LineToY: PUBLIC PROC[t: Trajectory, y: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [prev: t, lp: [t.lp.x, y], variant: line[]]]]; }; <<>> CurveTo: PUBLIC PROC[t: Trajectory, x1, y1, x2, y2, x3, y3: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[curve] _ [prev: t, lp: [x3, y3], variant: curve[[x1, y1], [x2, y2]]]]]; }; CurveToP: PUBLIC PROC[t: Trajectory, p1, p2, p3: Pair] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[curve] _ [prev: t, lp: p3, variant: curve[p1, p2]]]]; }; ConicTo: PUBLIC PROC[t: Trajectory, x1, y1, x2, y2: REAL, r: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[conic] _ [prev: t, lp: [x2, y2], variant: conic[[x1, y1], r]]]]; }; ConicToP: PUBLIC PROC[t: Trajectory, p1, p2: Pair, r: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[conic] _ [prev: t, lp: p2, variant: conic[p1, r]]]]; }; ArcTo: PUBLIC PROC[t: Trajectory, x1, y1, x2, y2: REAL] RETURNS[Trajectory] ~ { conic: PROC[p1, p2: Pair, r: REAL] ~ {t _ ConicToP[t, p1, p2, r]}; ImagerConic.FromArc[t.lp, [x1, y1], [x2, y2], conic]; RETURN[t]; }; ArcToP: PUBLIC PROC[t: Trajectory, p1, p2: Pair] RETURNS[Trajectory] ~ { conic: PROC[p1, p2: Pair, r: REAL] ~ {t _ ConicToP[t, p1, p2, r]}; ImagerConic.FromArc[t.lp, p1, p2, conic]; RETURN[t]; }; <> <> <> <> <> <> <> <<];>> <<>> MapTrajectory: PUBLIC PathProc ~ { WITH data SELECT FROM end: Trajectory => { move[end.lp]; FOR t: Trajectory _ end, t.prev UNTIL t.prev=NIL DO p0: Pair ~ t.prev.lp; WITH t SELECT FROM t: REF TrajectoryRep[move] => ERROR; -- should have had t.prev=NIL t: REF TrajectoryRep[line] => line[p0]; t: REF TrajectoryRep[curve] => curve[t.p2, t.p1, p0]; t: REF TrajectoryRep[conic] => conic[t.p1, p0, t.r]; < arc[t.p1, p0];>> ENDCASE => ERROR; -- unknown variant ENDLOOP; }; ENDCASE => ERROR; -- data is wrong type or NIL }; MapTrajectoryList: PUBLIC PathProc ~ { WITH data SELECT FROM head: TrajectoryList => { FOR list: TrajectoryList _ head, list.rest UNTIL list=NIL DO t: Trajectory ~ list.first; MapTrajectory[t, move, line, curve, conic]; ENDLOOP; }; ENDCASE => ERROR; -- data is wrong type or NIL }; <> MaskFill: PUBLIC PROC[context: Context, outline: REF] ~ { WITH outline SELECT FROM t: Trajectory => context.class.MaskFill[context, MapTrajectory, t]; tlist: TrajectoryList => context.class.MaskFill[context, MapTrajectoryList, tlist]; < context.class.MaskFill[context, MapPath, path];>> ENDCASE => ERROR Error[$InvalidOutline]; -- outline is wrong type or NIL }; MaskFillPath: PUBLIC PROC[context: Context, pathProc: PathProc, pathData: REF _ NIL] ~ { context.class.MaskFill[context, pathProc, pathData]; }; <> SetStrokeWidth: PUBLIC PROC[context: Context, strokeWidth: REAL] ~ { context.class.SetStrokeWidth[context, strokeWidth]; }; SetStrokeEnd: PUBLIC PROC[context: Context, strokeEnd: StrokeEnd] ~ { context.class.SetStrokeEnd[context, strokeEnd]; }; MaskStroke: PUBLIC PROC[context: Context, stroke: REF] ~ { WITH stroke SELECT FROM t: Trajectory => context.class.MaskStroke[context, MapTrajectory, t]; tlist: TrajectoryList => context.class.MaskStroke[context, MapTrajectoryList, tlist]; < context.class.MaskStroke[context, MapPath, path];>> ENDCASE => ERROR Error[$InvalidStroke]; -- stroke is wrong type or NIL }; <<>> MaskStrokeClosed: PUBLIC PROC[context: Context, stroke: REF] ~ { WITH stroke SELECT FROM t: Trajectory => context.class.MaskStrokeClosed[context, MapTrajectory, t]; tlist: TrajectoryList => context.class.MaskStrokeClosed[context, MapTrajectoryList, tlist]; < context.class.MaskStrokeClosed[context, MapPath, path];>> ENDCASE => ERROR Error[$InvalidStroke]; -- stroke is wrong type or NIL }; <<>> MaskStrokePath: PUBLIC PROC[ context: Context, pathProc: PathProc, pathData: REF _ NIL] ~ { context.class.MaskStroke[context, pathProc, pathData]; }; MaskStrokeClosedPath: PUBLIC PROC[ context: Context, pathProc: PathProc, pathData: REF _ NIL] ~ { context.class.MaskStrokeClosed[context, pathProc, pathData]; }; <<>> <> MaskRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] ~ { context.class.MaskRectangle[context: context, x: x, y: y, w: w, h: h]; }; <<>> MaskBox: PUBLIC PROC[context: Context, box: Box] ~ { context.class.MaskRectangle[context: context, x: box.xmin, y: box.ymin, w: box.xmax-box.xmin, h: box.ymax-box.ymin]; }; <<>> MaskVector: PUBLIC PROC[context: Context, x1, y1, x2, y2: REAL] ~ { context.class.MaskVector[context: context, x1: x1, y1: y1, x2: x2, y2: y2]; }; MaskVectorP: PUBLIC PROC[context: Context, p1, p2: Pair] ~ { context.class.MaskVector[context: context, x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y]; }; <> <> <> <<>> SetXY: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.SetXY[context, x, y]; }; SetXYP: PUBLIC PROC[context: Context, p: Pair] ~ { context.class.SetXY[context, p.x, p.y]; }; SetXYRel: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.SetXYRel[context, x, y]; }; SetXYRelP: PUBLIC PROC[context: Context, p: Pair] ~ { context.class.SetXYRel[context, p.x, p.y]; }; SetXRel: PUBLIC PROC[context: Context, x: REAL] ~ { context.class.SetXYRel[context, x, 0]; }; SetYRel: PUBLIC PROC[context: Context, y: REAL] ~ { context.class.SetXYRel[context, 0, y]; }; <> <<>> FindFont: PUBLIC PROC[name: ROPE] RETURNS[FONT] ~ { RETURN[NIL]; }; ModifyFont: PUBLIC PROC[font: FONT, m: Transformation] RETURNS[FONT] ~ { RETURN[NIL]; }; MakeFont: PUBLIC PROC[name: ROPE, size: REAL] RETURNS[FONT] ~ { RETURN[Font.CreateScaled[name, size]]; }; SetFont: PUBLIC PROC[context: Context, font: FONT] ~ { context.class.SetFont[context, font]; }; ShowRope: PUBLIC PROC[context: Context, rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] ~ { context.class.ShowRope[context, rope, start, len]; }; ShowText: PUBLIC PROC[context: Context, text: REF READONLY TEXT, start: NAT _ 0, len: NAT _ NAT.LAST] ~ { context.class.ShowText[context, text, start, len]; }; ShowChar: PUBLIC PROC[context: Context, char: CHAR] ~ { context.class.ShowChar[context, char]; }; SetAmplifySpace: PUBLIC PROC[context: Context, amplifySpace: REAL] ~ { context.class.SetAmplifySpace[context, amplifySpace]; }; <> <> <<>> StartUnderline: PUBLIC PROC[context: Context] ~ { context.class.StartUnderline[context]; }; <<>> MaskUnderline: PUBLIC PROC[context: Context, dy, h: REAL] ~ { context.class.MaskUnderline[context, dy, h]; }; <> CorrectMask: PUBLIC PROC[context: Context] ~ { context.class.CorrectMask[context]; }; CorrectSpace: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.CorrectSpace[context, x, y]; }; CorrectSpaceP: PUBLIC PROC[context: Context, p: Pair] ~ { context.class.CorrectSpace[context, p.x, p.y]; }; Correct: PUBLIC PROC[context: Context, body: PROC] ~ { context.class.Correct[context, body]; }; SetCorrectMeasure: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.SetCorrectMeasure[context, x, y]; }; SetCorrectMeasureP: PUBLIC PROC[context: Context, p: Pair] ~ { context.class.SetCorrectMeasure[context, p.x, p.y]; }; SetCorrectTolerance: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.SetCorrectTolerance[context, x, y]; }; SetCorrectToleranceP: PUBLIC PROC[context: Context, p: Pair] ~ { context.class.SetCorrectTolerance[context, p.x, p.y]; }; SetCorrectShrink: PUBLIC PROC[context: Context, correctShrink: REAL] ~ { context.class.SetCorrectShrink[context, correctShrink]; }; Space: PUBLIC PROC[context: Context, x: REAL] ~ { context.class.Space[context, x]; }; <> PixelArray: TYPE ~ ImagerBasic.PixelArray; MakePixelArrayFromBits: PUBLIC PROC[ bitPointer: LONG POINTER TO PACKED ARRAY [0..0) OF [0..1], bitsPerLine, samplesPerLine, numberOfLines: NAT] RETURNS [pixelArray: PixelArray] ~ TRUSTED { pixelMap: ImagerPixelMaps.PixelMap _ ImagerPixelMaps.Create[0, [0, 0, numberOfLines, samplesPerLine]]; bbTableSpace: PrincOps.BBTableSpace; bb: PrincOps.BBptr ~ PrincOpsUtils.AlignedBBTable[@bbTableSpace]; bb^ _ [ dst: [word: pixelMap.refRep.pointer, bit: 0], dstBpl: pixelMap.refRep.rast*Basics.bitsPerWord, src: [word: bitPointer, bit: 0], srcDesc: [srcBpl[bitsPerLine]], height: numberOfLines, width: samplesPerLine, flags: [direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: FALSE, srcFunc: null, dstFunc: null] ]; PrincOpsUtils.BITBLT[bb]; pixelArray _ ImagerMasks.PixelArrayFromPixelMap[pixelMap]; pixelArray.m _ pixelArray.m.Concat[ImagerTransform.Rotate[-90]].Concat[ImagerTransform.Translate[0, numberOfLines]]; }; MaskPixel: PUBLIC PROC[context: Context, pa: PixelArray] ~ { context.class.MaskPixel[context, pa]; }; <> <> <<>> <> Card: PROC[real: REAL] RETURNS[card: CARDINAL] ~ { int: INT _ Real.RoundLI[real*LAST[CARDINAL]]; card _ MAX[MIN[int, LAST[CARDINAL]], 0]; }; MakeGray: PUBLIC PROC[f: REAL] RETURNS[ConstantColor] ~ { IF f<0 OR f>1 THEN ERROR Error[$GrayParameterOutOfRange]; RETURN[NEW[ImagerBasic.ColorRep[constant] _ [constant[x: Card[0.3101], y: Card[0.3163], Y: Card[1-f]]]]]; }; <<>> black: PUBLIC ConstantColor _ MakeGray[1]; white: PUBLIC ConstantColor _ MakeGray[0]; <> Color: TYPE ~ REF ImagerBasic.ColorRep; SetSampledColor: PUBLIC PROC[context: Context, pa: PixelArray, pixelT: Transformation, colorOperator: ATOM _ $Intensity] ~ { context.class.SetSampledColor[context, pa, pixelT, colorOperator]; }; SetSampledBlack: PUBLIC PROC[context: Context, pa: PixelArray, pixelT: Transformation, transparent: BOOL _ FALSE] ~ { context.class.SetSampledBlack[context, pa, pixelT, transparent]; }; <<>> <> SetColor: PUBLIC PROC[context: Context, color: Color] ~ { context.class.SetColor[context, color]; }; SetGray: PUBLIC PROC[context: Context, f: REAL] ~ { context.class.SetGray[context, f]; }; <<>> <> <<>> ClipOutline: PUBLIC PROC[context: Context, outline: REF] ~ { WITH outline SELECT FROM t: Trajectory => context.class.ClipOutline[context, MapTrajectory, t]; tlist: TrajectoryList => context.class.ClipOutline[context, MapTrajectoryList, tlist]; < context.class.MaskFill[context, MapPath, path];>> ENDCASE => ERROR Error[$InvalidOutline]; -- outline is wrong type or NIL }; ClipOutlinePath: PUBLIC PROC[context: Context, pathProc: PathProc, pathData: REF _ NIL] ~ { context.class.ClipOutline[context, pathProc, pathData]; }; ExcludeOutline: PUBLIC PROC[context: Context, outline: REF] ~ { WITH outline SELECT FROM t: Trajectory => context.class.ExcludeOutline[context, MapTrajectory, t]; tlist: TrajectoryList => context.class.ExcludeOutline[context, MapTrajectoryList, tlist]; < context.class.MaskFill[context, MapPath, path];>> ENDCASE => ERROR Error[$InvalidOutline]; -- outline is wrong type or NIL }; ExcludeOutlinePath: PUBLIC PROC[context: Context, pathProc: PathProc, pathData: REF _ NIL] ~ { context.class.ExcludeOutline[context, pathProc, pathData]; }; ClipRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] ~ { context.class.ClipRectangle[context, x, y, w, h]; }; ExcludeRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] ~ { context.class.ExcludeRectangle[context, x, y, w, h]; }; END.