<> <> <> DIRECTORY Atom USING [GetProp, PutProp, PropList, DottedPairNode], Basics USING [bitsPerWord], Font USING [CreateScaled], Imager USING [Context, ContextRep, defaultStrokeEnd, defaultStrokeWidth, ErrorCode, FONT, Outline, OutlineRep, Polygon, RopeOrRefText, Trajectory, TrajectoryRep], ImagerBasic USING [Color, ColorRep, ConstantColor, IntPair, IntRectangle, Pair, PathMapType, PixelArray, StrokeEnd, Transformation, Visibility], ImagerConic USING [FromArc], ImagerMasks USING [PixelArrayFromPixelMap], ImagerPixelMaps USING [Create, PixelMap], ImagerPrivate USING [Class], ImagerTransform, PrincOps USING [BBTableSpace, BBptr], PrincOpsUtils USING [AlignedBBTable, BITBLT], Real USING [RoundLI], Rope USING [ROPE]; ImagerImpl: CEDAR PROGRAM IMPORTS Atom, Font, ImagerConic, ImagerMasks, ImagerPixelMaps, ImagerTransform, PrincOpsUtils, Real EXPORTS Imager, ImagerPrivate = BEGIN OPEN Imager, ImagerBasic; <> Class: TYPE = ImagerPrivate.Class; <> Error: PUBLIC ERROR [errorCode: ErrorCode] ~ CODE; <> imagerRegistrationKey: ATOM ~ $ImagerDeviceClass; RegisterDevice: PUBLIC PROC [class: ImagerPrivate.Class] ~ { Atom.PutProp[class.deviceType, imagerRegistrationKey, class]; }; Create: PUBLIC PROC[deviceType: ATOM, data: REF] RETURNS [context: Context] ~ { WITH Atom.GetProp[deviceType, imagerRegistrationKey] SELECT FROM class: Class => { context _ NEW[ContextRep _ [class: class, data: NIL]]; class.Init[context, data]; }; ENDCASE => Error[$UnimplementedDevice]; }; <> DoSave: PUBLIC PROC[context: Context, body: PROC] = { class: Class = NARROW[context.class]; class.DoSave[context, body]; }; DoSaveAll: PUBLIC PROC[context: Context, body: PROC] = { class: Class = NARROW[context.class]; class.DoSaveAll[context, body]; }; SetPriorityImportant: PUBLIC PROC[context: Context, priorityImportant: BOOL] = { class: Class = NARROW[context.class]; class.ISetInt[context, $priorityImportant, IF priorityImportant THEN 1 ELSE 0]; }; <> pointsToMeters: PUBLIC Transformation _ ImagerTransform.Scale[0.0254/72.27]; micasToMeters: PUBLIC Transformation _ ImagerTransform.Scale[0.00001]; MakeT: PUBLIC PROC[a, b, c, d, e, f: REAL] RETURNS[Transformation] ~ { RETURN [ImagerTransform.Create[a, b, c, d, e, f]] }; OpenT: PUBLIC PROC[m: Transformation] RETURNS[a, b, c, d, e, f: REAL] ~ { [[a, b, c, d, e, f]] _ ImagerTransform.Contents[m]; }; Translate: PUBLIC PROC[x, y: REAL] RETURNS[Transformation] ~ { RETURN [ImagerTransform.Translate[x, y]] }; 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]] }; 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]] }; RoundXY: PUBLIC PROC[m: Transformation, p: Pair] RETURNS[Pair] ~ { RETURN [ImagerTransform.InverseTransform[DRound[ImagerTransform.Transform[p, m]], m]] }; RoundXYVec: PUBLIC PROC[m: Transformation, p: Pair] RETURNS[Pair] ~ { RETURN [ImagerTransform.InverseTransformVec[DRound[ImagerTransform.TransformVec[p, m]], m]] }; ConcatT: PUBLIC PROC[context: Context, m: Transformation] = { class: Class = NARROW[context.class]; class.ConcatT[context, m]; }; <<>> TranslateT: PUBLIC PROC[context: Context, x, y: REAL] = { class: Class = NARROW[context.class]; class.TranslateT[context, x, y]; }; <<>> RotateT: PUBLIC PROC[context: Context, a: REAL] = { class: Class = NARROW[context.class]; class.RotateT[context, a]; }; ScaleT: PUBLIC PROC[context: Context, s: REAL] = { class: Class = NARROW[context.class]; class.ScaleT[context, s]; }; Scale2T: PUBLIC PROC[context: Context, sx, sy: REAL] = { class: Class = NARROW[context.class]; class.Scale2T[context, sx, sy]; }; <<>> Move: PUBLIC PROC[context: Context] = { class: Class = NARROW[context.class]; class.Move[context]; }; <<>> Trans: PUBLIC PROC[context: Context] = { class: Class = NARROW[context.class]; class.Trans[context]; }; <> SetXY: PUBLIC PROC[context: Context, p: Pair] = { class: Class = NARROW[context.class]; class.SetXY[context, p]; }; IntegerSetXY: PUBLIC PROC[context: Context, x, y: INTEGER] = { class: Class = NARROW[context.class]; class.IntegerSetXY[context, x, y]; }; SetXYRel: PUBLIC PROC[context: Context, v: Pair] = { class: Class = NARROW[context.class]; class.SetXYRel[context, v]; }; IntegerSetXYRel: PUBLIC PROC[context: Context, x, y: INTEGER] = { class: Class = NARROW[context.class]; class.IntegerSetXYRel[context, x, y]; }; SetXRel: PUBLIC PROC[context: Context, x: REAL] = { class: Class = NARROW[context.class]; class.SetXYRel[context, [x, 0]]; }; IntegerSetXRel: PUBLIC PROC[context: Context, x: INTEGER] = { class: Class = NARROW[context.class]; class.IntegerSetXYRel[context, x, 0]; }; <<>> SetYRel: PUBLIC PROC[context: Context, y: REAL] = { class: Class = NARROW[context.class]; class.SetXYRel[context, [0, y]]; }; IntegerSetYRel: PUBLIC PROC[context: Context, y: INTEGER] = { class: Class = NARROW[context.class]; class.IntegerSetXYRel[context, 0, y]; }; GetCP: PUBLIC PROC[context: Context] RETURNS[Pair] = { class: Class = NARROW[context.class]; RETURN [class.GetCP[context]]; }; GetCPRounded: PUBLIC PROC[context: Context] RETURNS[Pair] = { class: Class = NARROW[context.class]; RETURN [class.GetCPRounded[context]]; }; <> 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[$GrayParameterOutOfRange]; RETURN[NEW[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]; SetColor: PUBLIC PROC[context: Context, color: Color] = { class: Class = NARROW[context.class]; class.ISet[context, $color, color]; }; SetSampledColor: PUBLIC PROC[context: Context, pa: PixelArray, pixelT: Transformation, colorOperator: ATOM] = { class: Class = NARROW[context.class]; class.SetSampledColor[context, pa, pixelT, colorOperator]; }; SetSampledBlack: PUBLIC PROC[context: Context, pa: PixelArray, pixelT: Transformation, transparent: BOOLEAN] = { class: Class = NARROW[context.class]; class.SetSampledBlack[context, pa, pixelT, transparent]; }; <> LastPoint: PUBLIC PROC[t: Trajectory] RETURNS[Pair] = { RETURN[t.lp]; }; <<>> MoveTo: PUBLIC PROC[p: Pair] RETURNS[Trajectory] = { RETURN[NEW[TrajectoryRep[move] _ [prev: NIL, lp: p, variant: move[]]]]; }; <<>> LineTo: 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, p1, p2, p3: Pair] RETURNS[Trajectory] = { RETURN[NEW[TrajectoryRep[curve] _ [prev: t, lp: p3, variant: curve[p1, p2]]]]; }; ConicTo: 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, p1, p2: Pair] RETURNS[Trajectory] = { conic: PROC[p1, p2: Pair, r: REAL] ~ {t _ ConicTo[t, p1, p2, r]}; ImagerConic.FromArc[LastPoint[t], p1, p2, conic]; RETURN [t] }; MakeOutline: PUBLIC PROC[list: LIST OF Trajectory] RETURNS[Outline] = { RETURN[NEW[OutlineRep _ [list]]]; }; MapTrajectory: PathMapType = { t: Trajectory = NARROW[data]; move[t.lp]; FOR x: Trajectory _ t, x.prev UNTIL x.prev=NIL DO p0: Pair = x.prev.lp; WITH x SELECT FROM x: REF TrajectoryRep[line] => line[p0]; x: REF TrajectoryRep[curve] => curve[x.p2, x.p1, p0]; x: REF TrajectoryRep[conic] => conic[x.p1, p0, x.r]; x: REF TrajectoryRep[move] => ERROR; ENDCASE => ERROR; ENDLOOP; }; MapTrajectoryList: PathMapType = { FOR x: LIST OF Trajectory _ NARROW[data], x.rest UNTIL x = NIL DO MapTrajectory[x.first, move, line, curve, conic] ENDLOOP; }; MapPolygon: PathMapType = { p: Polygon = NARROW[data]; IF p.length>0 THEN { move[p[0]]; FOR i: NAT IN[1..MIN[p.length, p.maxLength]) DO line[p[i]] ENDLOOP; }; }; MapPolygonList: PathMapType = { FOR plist: LIST OF Polygon _ NARROW[data], plist.rest UNTIL plist = NIL DO MapPolygon[plist.first, move, line, curve, conic]; ENDLOOP; }; 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]]; }; MaskFill: PUBLIC PROC[context: Context, outline: REF] = { class: Class = NARROW[context.class]; WITH outline SELECT FROM o: Outline => class.MaskFill[context, MapTrajectoryList, o.list]; list: LIST OF Trajectory => class.MaskFill[context, MapTrajectoryList, list]; t: Trajectory => class.MaskFill[context, MapTrajectory, t]; p: Polygon => class.MaskFill[context, MapPolygon, p]; plist: LIST OF Polygon => class.MaskFill[context, MapPolygonList, plist]; ENDCASE => Error[$UnknownPathType]; }; SetStrokeWidth: PUBLIC PROC[context: Context, strokeWidth: REAL] = { class: Class = NARROW[context.class]; class.ISetReal[context, $strokeWidth, strokeWidth]; }; SetStrokeEnd: PUBLIC PROC[context: Context, strokeEnd: StrokeEnd] = { class: Class = NARROW[context.class]; class.ISetInt[context, $strokeEnd, SELECT strokeEnd FROM square => 0, butt => 1, round => 2, ENDCASE => ERROR]; }; MaskStroke: PUBLIC PROC[context: Context, t: Trajectory, strokeWidth: REAL _ defaultStrokeWidth, strokeEnd: StrokeEnd _ defaultStrokeEnd] = { class: Class = NARROW[context.class]; class.MaskStroke[context, MapTrajectory, t, strokeWidth, strokeEnd]; }; <<>> MaskStrokeClosed: PUBLIC PROC[context: Context, t: Trajectory, strokeWidth: REAL _ defaultStrokeWidth] = { class: Class = NARROW[context.class]; class.MaskStrokeClosed[context, MapTrajectory, t, strokeWidth]; }; MaskVector: PUBLIC PROC[context: Context, p1, p2: Pair, strokeWidth: REAL _ defaultStrokeWidth, strokeEnd: StrokeEnd _ defaultStrokeEnd] = { class: Class = NARROW[context.class]; IF LOOPHOLE[strokeWidth, LONG CARDINAL] = LOOPHOLE[defaultStrokeWidth, LONG CARDINAL] AND strokeEnd=defaultStrokeEnd THEN class.MaskVector[context, p1.x, p1.y, p2.x, p2.y] ELSE { MapVector: PathMapType = { move[p1]; line[p2] }; class.MaskStroke[context, MapVector, NIL, strokeWidth, strokeEnd]; }; }; <<>> MaskRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] = { class: Class = NARROW[context.class]; class.MaskRectangle[context, x, y, w, h]; }; IntegerMaskRectangle: PUBLIC PROC[context: Context, x, y, w, h: INTEGER] = { class: Class = NARROW[context.class]; class.IntegerMaskRectangle[context, x, y, w, h]; }; <<>> StartUnderline: PUBLIC PROC[context: Context] = { class: Class = NARROW[context.class]; class.StartUnderline[context]; }; <<>> MaskUnderline: PUBLIC PROC[context: Context, dy, h: REAL] = { class: Class = NARROW[context.class]; class.MaskUnderline[context, dy, h]; }; IntegerMaskUnderline: PUBLIC PROC[context: Context, dy, h: INTEGER] = { class: Class = NARROW[context.class]; class.IntegerMaskUnderline[context, dy, h]; }; <<>> MaskPixel: PUBLIC PROC[context: Context, pa: PixelArray] = { class: Class = NARROW[context.class]; class.MaskPixel[context, pa]; }; <<>> ClipOutline: PUBLIC PROC[context: Context, outline: REF] = { class: Class = NARROW[context.class]; WITH outline SELECT FROM o: Outline => class.ClipOutline[context, MapTrajectoryList, o.list]; list: LIST OF Trajectory => class.ClipOutline[context, MapTrajectoryList, list]; t: Trajectory => class.ClipOutline[context, MapTrajectory, t]; p: Polygon => class.ClipOutline[context, MapPolygon, p]; ENDCASE => Error[$UnknownPathType]; }; ExcludeOutline: PUBLIC PROC[context: Context, outline: REF] = { class: Class = NARROW[context.class]; WITH outline SELECT FROM o: Outline => class.ExcludeOutline[context, MapTrajectoryList, o.list]; list: LIST OF Trajectory => class.ExcludeOutline[context, MapTrajectoryList, list]; t: Trajectory => class.ExcludeOutline[context, MapTrajectory, t]; p: Polygon => class.ExcludeOutline[context, MapPolygon, p]; ENDCASE => Error[$UnknownPathType]; }; ClipRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] = { class: Class = NARROW[context.class]; class.ClipRectangle[context, x, y, w, h]; }; ExcludeRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] = { class: Class = NARROW[context.class]; class.ExcludeRectangle[context, x, y, w, h]; }; IntegerClipRectangle: PUBLIC PROC[context: Context, x, y, w, h: INTEGER] = { class: Class = NARROW[context.class]; class.IntegerClipRectangle[context, x, y, w, h]; }; IntegerExcludeRectangle: PUBLIC PROC[context: Context, x, y, w, h: INTEGER] = { class: Class = NARROW[context.class]; class.IntegerExcludeRectangle[context, x, y, w, h]; }; <> MakeFont: PUBLIC PROC[name: Rope.ROPE, size: REAL] RETURNS[FONT] = { RETURN[Font.CreateScaled[name, size]]; }; SetFont: PUBLIC PROC[context: Context, font: FONT] = { class: Class = NARROW[context.class]; class.ISet[context, $showVec, font]; }; ShowChar: PUBLIC PROC[context: Context, char: CHAR, font: FONT _ NIL] = { class: Class = NARROW[context.class]; class.ShowChar[context, char, font]; }; ShowCharacters: PUBLIC PROC[context: Context, characters: RopeOrRefText, font: FONT _ NIL, start: INT _ 0, length: INT _ LAST[INT]] = { class: Class = NARROW[context.class]; class.ShowCharacters[context, characters, font, start, length]; }; SetAmplifySpace: PUBLIC PROC[context: Context, amplifySpace: REAL] = { class: Class = NARROW[context.class]; class.ISetReal[context, $amplifySpace, amplifySpace]; }; <> CorrectMask: PUBLIC PROC[context: Context] = { class: Class = NARROW[context.class]; class.CorrectMask[context]; }; CorrectSpace: PUBLIC PROC[context: Context, v: Pair] = { class: Class = NARROW[context.class]; class.CorrectSpace[context, v]; }; Correct: PUBLIC PROC[context: Context, body: PROC] = { class: Class = NARROW[context.class]; class.Correct[context, body]; }; SetCorrectMeasure: PUBLIC PROC[context: Context, v: Pair] = { class: Class = NARROW[context.class]; class.SetCorrectMeasure[context, v]; }; SetCorrectTolerance: PUBLIC PROC[context: Context, v: Pair] = { class: Class = NARROW[context.class]; class.SetCorrectTolerance[context, v]; }; SetCorrectShrink: PUBLIC PROC[context: Context, correctShrink: REAL] = { class: Class = NARROW[context.class]; class.ISetReal[context, $correctShrink, correctShrink]; }; Space: PUBLIC PROC[context: Context, x: REAL] = { class: Class = NARROW[context.class]; class.Space[context, x]; }; IntegerSpace: PUBLIC PROC[context: Context, x: INTEGER] = { class: Class = NARROW[context.class]; class.IntegerSpace[context, x]; }; Reset: PUBLIC PROC[context: Context] = { class: Class = NARROW[context.class]; class.Reset[context]; }; SetViewOrigin: PUBLIC PROC[context: Context, viewOrigin: IntPair] = { class: Class = NARROW[context.class]; class.SetViewOrigin[context, viewOrigin]; }; GetViewOrigin: PUBLIC PROC[context: Context] RETURNS[viewOrigin: IntPair] = { class: Class = NARROW[context.class]; RETURN[class.GetViewOrigin[context]]; }; SetViewBox: PUBLIC PROC[context: Context, viewBox: IntRectangle] = { class: Class = NARROW[context.class]; class.SetViewBox[context, viewBox]; }; GetViewBox: PUBLIC PROC[context: Context] RETURNS[viewBox: IntRectangle] = { class: Class = NARROW[context.class]; RETURN[class.GetViewBox[context]]; }; ClipView: PUBLIC PROC[context: Context, clipBox: IntRectangle, exclude: BOOL] = { class: Class = NARROW[context.class]; class.ClipView[context, clipBox, exclude]; }; PutProp: PUBLIC PROC[context: Context, key: REF, value: REF] = { pList: Atom.PropList _ NARROW[context.state.propertyList]; RemoveKeyFrom: PROC[p: Atom.PropList] RETURNS [Atom.PropList] = { IF p = NIL THEN RETURN [NIL] ELSE IF p.first.key = key THEN RETURN [p.rest] ELSE { rest: Atom.PropList _ RemoveKeyFrom[p.rest]; IF rest # p.rest THEN RETURN [CONS[p.first, rest]] ELSE RETURN [p] } }; pList _ RemoveKeyFrom[pList]; IF value # NIL THEN pList _ CONS[NEW[Atom.DottedPairNode _ [key, value]], pList]; context.state.propertyList _ pList; }; GetProp: PUBLIC PROC[context: Context, key: REF] RETURNS [value: REF] = { pList: Atom.PropList _ NARROW[context.state.propertyList]; WHILE pList # NIL DO IF pList.first.key = key THEN RETURN [pList.first.val]; pList _ pList.rest; ENDLOOP; RETURN [NIL] }; Round: PROC[r: REAL] RETURNS[REAL] = INLINE { IF ABS[r]>= LAST[INT] THEN RETURN [r] ELSE RETURN [Real.RoundLI[r]] }; DRound: PUBLIC PROC[v: Pair] RETURNS[Pair] = { RETURN [[Round[v.x], Round[v.y]]] }; MoveSurfaceRectangle: PUBLIC PROC[context: Context, source: IntRectangle, dest: IntPair] = { class: Class = NARROW[context.class]; class.MoveSurfaceRectangle[context, source, dest]; }; XOR: PUBLIC Color _ NEW[ImagerBasic.ColorRep[special] _ [special[$XOR]]]; MakeStipple: PUBLIC PROC[stipple: CARDINAL] RETURNS[Color] = { ref: REF CARDINAL = NEW[CARDINAL _ stipple]; RETURN[NEW[ImagerBasic.ColorRep[special] _ [special[ref]]]] }; TestRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] RETURNS[Visibility] = { class: Class = NARROW[context.class]; RETURN[class.TestRectangle[context, x, y, w, h]]; }; GetSurfaceBounds: PUBLIC PROC[context: Context] RETURNS[IntRectangle] = { class: Class = NARROW[context.class]; RETURN[class.GetSurfaceBounds[context]]; }; SpecialOp: PUBLIC PROC[context: Context, op: ATOM, data: REF] RETURNS[REF] = { class: Class = NARROW[context.class]; RETURN[class.SpecialOp[context, op, data]]; }; END.