<> <> <> DIRECTORY Imager, ImagerBasic, ImagerDefault, ImagerPrivate, ImagerTransform, Real; ImagerDefaultImpl: CEDAR PROGRAM IMPORTS Imager, ImagerTransform, Real EXPORTS ImagerDefault SHARES Imager ~ BEGIN OPEN ImagerDefault; Trajectory: TYPE ~ Imager.Trajectory; TrajectoryRep: TYPE ~ Imager.TrajectoryRep; InitialStateRep: ImagerBasic.StateRep ~ [ cpx: 0.0, cpy: 0.0, correctMX: 0.0, correctMY: 0.0, correctMaskCount: 0, correctMaskX: 0.0, correctMaskY: 0.0, correctSumX: 0.0, correctSumY: 0.0, correctSpaceX: 0.0, correctSpaceY: 0.0, correctcpx: 0.0, correctcpy: 0.0, correctTargetX: 0.0, correctTargetY: 0.0, T: ImagerTransform.Create[1,0,0,0,1,0], priorityImportant: 0, mediumXSize: 0, mediumYSize: 0, fieldXMin: 0, fieldYMin: 0, fieldXMax: 0, fieldYMax: 0, showVec: NIL, color: NIL, noImage: 0, strokeWidth: 0.0, strokeEnd: 0, underlineStart: 0.0, amplifySpace: 1.0, correctPass: 0, correctShrink: 0.5, correctTX: 0.0, correctTY: 0.0, clipper: NIL, propertyList: NIL ]; InitState: PUBLIC PROC [context: Context] ~ { state: State _ NEW[ImagerBasic.StateRep _ InitialStateRep]; state.color _ Imager.black; context.state _ state; }; ISet: PUBLIC PROC [context: Context, n: Name, x: REF] ~ { WITH context.state SELECT FROM state: State => { SELECT n FROM T => WITH x SELECT FROM t: REF ImagerBasic.Transformation => {state.T _ t^}; ENDCASE => ERROR Imager.Error[$WrongType]; showVec => state.showVec _ x; color => WITH x SELECT FROM color: ImagerBasic.Color => {state.color _ color}; ENDCASE => ERROR Imager.Error[$WrongType]; clipOutline => state.clipper _ NARROW[x]; ENDCASE => ERROR Imager.Error[$BadSelector]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; ISetReal: PUBLIC PROC [context: Context, n: Name, x: REAL] ~ { WITH context.state SELECT FROM state: State => { SELECT n FROM DCScpx => state.cpx _ x; DCScpy => state.cpy _ x; correctMX => state.correctMX _ x; correctMY => state.correctMY _ x; mediumXSize => state.mediumXSize _ x; mediumYSize => state.mediumYSize _ x; fieldXMin => state.fieldXMin _ x; fieldYMin => state.fieldYMin _ x; fieldXMax => state.fieldXMax _ x; fieldYMax => state.fieldYMax _ x; strokeWidth => state.strokeWidth _ x; underlineStart => state.underlineStart _ x; amplifySpace => state.amplifySpace _ x; correctShrink => state.correctShrink _ x; correctTX => state.correctTX _ x; correctTY => state.correctTY _ x; ENDCASE => ERROR Imager.Error[$BadSelector]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; ISetInt: PUBLIC PROC [context: Context, n: Name, x: INT] ~ { WITH context.state SELECT FROM state: State => { SELECT n FROM priorityImportant => state.priorityImportant _ x; noImage => state.noImage _ x; strokeEnd => state.strokeEnd _ x; correctPass => state.correctPass _ x; ENDCASE => ERROR Imager.Error[$BadSelector]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; SetSampledColor: PUBLIC PROC[context: Context, pa: PixelArray, pixelT: Transformation, colorOperator: ATOM] ~ { state: State _ NARROW[context.state]; color: ImagerBasic.SampledColor ~ NEW[ImagerBasic.ColorRep.sampled _ [sampled[ transparent: FALSE, pa: pa, m: pixelT.Concat[state.T], colorOperator: colorOperator ]]]; state.color _ color; }; SetSampledBlack: PUBLIC PROC[context: Context, pa: PixelArray, pixelT: Transformation, transparent: BOOLEAN] ~ { state: State _ NARROW[context.state]; color: ImagerBasic.SampledColor ~ NEW[ImagerBasic.ColorRep.sampled _ [sampled[ transparent: transparent, pa: pa, m: pixelT.Concat[state.T], colorOperator: $SampledBlack ]]]; state.color _ color; }; DoSave: PUBLIC PROC [context: Context, body: PROC] ~ { state: State _ NARROW[context.state]; T: Transformation _ state.T; priorityImportant: INT _ state.priorityImportant; mediumXSize: REAL _ state.mediumXSize; mediumYSize: REAL _ state.mediumYSize; fieldXMin: REAL _ state.fieldXMin; fieldYMin: REAL _ state.fieldYMin; fieldXMax: REAL _ state.fieldXMax; fieldYMax: REAL _ state.fieldYMax; showVec: REF _ state.showVec; color: Color _ state.color; noImage: INT _ state.noImage; strokeWidth: REAL _ state.strokeWidth; strokeEnd: INT _ state.strokeEnd; underlineStart: REAL _ state.underlineStart; amplifySpace: REAL _ state.amplifySpace; correctPass: INT _ state.correctPass; correctShrink: REAL _ state.correctShrink; correctTX: REAL _ state.correctTX; correctTY: REAL _ state.correctTY; clipper: ClientClipper _ state.clipper; propertyList: REF _ state.propertyList; Restore: PROC ~ { state.T _ T; state.priorityImportant _ priorityImportant; state.mediumXSize _ mediumXSize; state.mediumYSize _ mediumYSize; state.fieldXMin _ fieldXMin; state.fieldYMin _ fieldYMin; state.fieldXMax _ fieldXMax; state.fieldYMax _ fieldYMax; state.showVec _ showVec; state.color _ color; state.noImage _ noImage; state.strokeWidth _ strokeWidth; state.strokeEnd _ strokeEnd; state.underlineStart _ underlineStart; state.amplifySpace _ amplifySpace; state.correctPass _ correctPass; state.correctShrink _ correctShrink; state.correctTX _ correctTX; state.correctTY _ correctTY; state.clipper _ clipper; state.propertyList _ propertyList; }; body[! UNWIND => Restore[]]; Restore[]; }; DoSaveAll: PUBLIC PROC [context: Context, body: PROC] ~ { state: State _ NARROW[context.state]; stateRep: ImagerBasic.StateRep _ state^; Restore: PROC ~ { state^ _ stateRep; }; body[! UNWIND => Restore[]]; Restore[]; }; ConcatT: PUBLIC PROC [context: Context, m: Transformation] ~ { WITH context.state SELECT FROM state: State => { state.T _ ImagerTransform.Concat[m, state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; TranslateT: PUBLIC PROC [context: Context, x, y: REAL] ~ { WITH context.state SELECT FROM state: State => { state.T _ ImagerTransform.PreTranslate[x, y, state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; RotateT: PUBLIC PROC [context: Context, a: REAL] ~ { WITH context.state SELECT FROM state: State => { state.T _ ImagerTransform.PreRotate[a, state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; ScaleT: PUBLIC PROC [context: Context, s: REAL] ~ { WITH context.state SELECT FROM state: State => { state.T _ ImagerTransform.PreScale[s, state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Scale2T: PUBLIC PROC [context: Context, sx, sy: REAL] ~ { WITH context.state SELECT FROM state: State => { state.T _ ImagerTransform.PreScale2[sx, sy, state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Move: PUBLIC PROC [context: Context] ~ { WITH context.state SELECT FROM state: State => { new: Pair _ [state.cpx, state.cpy]; t: ImagerTransform.TransformationRec _ state.T.Contents; state.T _ ImagerTransform.Create[t.a, t.b, new.x, t.d, t.e, new.y]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Trans: PUBLIC PROC [context: Context] ~ { WITH context.state SELECT FROM state: State => { new: Pair _ Imager.DRound[[state.cpx, state.cpy]]; t: ImagerTransform.TransformationRec _ state.T.Contents; state.T _ ImagerTransform.Create[t.a, t.b, new.x, t.d, t.e, new.y]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; SetXY: PUBLIC PROC [context: Context, p: Pair] ~ { WITH context.state SELECT FROM state: State => { [[state.cpx, state.cpy]] _ ImagerTransform.Transform[p, state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; IntegerSetXY: PUBLIC PROC [context: Context, x, y: INTEGER] ~ { WITH context.state SELECT FROM state: State => { [[state.cpx, state.cpy]] _ ImagerTransform.Transform[[x, y], state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; SetXYRel: PUBLIC PROC [context: Context, v: Pair] ~ { WITH context.state SELECT FROM state: State => { delta: Pair ~ ImagerTransform.TransformVec[v, state.T]; state.cpx _ state.cpx + delta.x; state.cpy _ state.cpy + delta.y; }; ENDCASE => ERROR Imager.Error[$Bug]; }; IntegerSetXYRel: PUBLIC PROC [context: Context, x, y: INTEGER] ~ { WITH context.state SELECT FROM state: State => { delta: Pair ~ ImagerTransform.TransformVec[[x, y], state.T]; state.cpx _ state.cpx + delta.x; state.cpy _ state.cpy + delta.y; }; ENDCASE => ERROR Imager.Error[$Bug]; }; GetCP: PUBLIC PROC [context: Context] RETURNS [cp: Pair] ~ { WITH context.state SELECT FROM state: State => { cp _ ImagerTransform.InverseTransform[[state.cpx, state.cpy], state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; GetCPRounded: PUBLIC PROC [context: Context] RETURNS [cp: Pair] ~ { WITH context.state SELECT FROM state: State => { cp _ ImagerTransform.InverseTransform[[Real.RoundLI[state.cpx], Real.RoundLI[state.cpy]], state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; MaskVector: PUBLIC PROC [context: Context, x1, y1, x2, y2: REAL] ~ { WITH context.state SELECT FROM state: State => { class: ImagerPrivate.Class ~ NARROW[context.class]; strokeEnd: StrokeEnd ~ SELECT state.strokeEnd FROM 0 => square, 1 => butt, 2 => round, ENDCASE => ERROR Imager.Error[$InvalidStrokeEnd]; MapVector: PathMapType = { move[[x1, y1]]; line[[x2, y2]] }; class.MaskStroke[context, MapVector, NIL, state.strokeWidth, strokeEnd]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; IntegerMaskVector: PUBLIC PROC [context: Context, x1, y1, x2, y2: INTEGER] ~ { MaskVector[context, x1, y1, x2, y2]; }; StartUnderline: PUBLIC PROC [context: Context] ~ { WITH context.state SELECT FROM state: State => { cp: Pair ~ ImagerTransform.InverseTransform[[state.cpx, state.cpy], state.T]; state.underlineStart _ cp.x; }; ENDCASE => ERROR Imager.Error[$Bug]; }; MaskUnderline: PUBLIC PROC [context: Context, dy, h: REAL] ~ { SimpleCO: PROC ~ { WITH context.state SELECT FROM state: State => { cp: Pair ~ ImagerTransform.InverseTransform[[state.cpx, state.cpy], state.T]; Imager.SetXY[context, [state.underlineStart, cp.y-dy-h]]; Imager.Trans[context]; Imager.MaskRectangle[context, 0, 0, cp.x-state.underlineStart, h]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Imager.DoSaveAll[context, SimpleCO]; }; IntegerMaskUnderline: PUBLIC PROC [context: Context, dy, h: INTEGER] ~ { MaskUnderline[context, dy, h]; }; ClipOutline: PUBLIC PROC [context: Context, pathMap: PathMapType, pathData: REF] ~ { WITH context.state SELECT FROM state: State => { trans: ImagerTransform.TransformationRec ~ state.T.Contents; XForm: PROC [p: Pair] RETURNS [Pair] ~ { RETURN [[trans.a*p.x+trans.b*p.y+trans.c, trans.d*p.x+trans.e*p.y+trans.f]] }; tList: LIST OF Trajectory _ NIL; Move: PROC [p: Pair] ~ {tList _ CONS[Imager.MoveTo[XForm[p]], tList]}; Line: PROC [p: Pair] ~ {tList.first _ tList.first.LineTo[XForm[p]]}; Curve: PROC [p1, p2, p3: Pair] ~ { tList.first _ tList.first.CurveTo[XForm[p1], XForm[p2], XForm[p3]] }; Conic: PROC [p1, p2: Pair, r: REAL] ~ { tList.first _ tList.first.ConicTo[XForm[p1], XForm[p2], r] }; pathMap[pathData, Move, Line, Curve, Conic]; state.clipper _ CONS[[exclude: FALSE, easyRectangle: FALSE, pathMap: MapTrajectoryList, pathData: tList], state.clipper]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; 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; }; ExcludeOutline: PUBLIC PROC [context: Context, pathMap: PathMapType, pathData: REF] ~ { WITH context.state SELECT FROM state: State => { ClipOutline[context, pathMap, pathData]; state.clipper.first.exclude _ TRUE; }; ENDCASE => ERROR Imager.Error[$Bug]; }; ClipRectangle: PUBLIC PROC [context: Context, x, y, w, h: REAL] ~ { WITH context.state SELECT FROM state: State => { pathMap: PathMapType ~ { move[[x, y]]; line[[x+w, y]]; line[[x+w, y+h]]; line[[x, y+h]]; }; t: ImagerTransform.TransformationRec ~ state.T.Contents; ClipOutline[context, pathMap, NIL]; state.clipper.first.easyRectangle _ (t.a = 0 AND t.e = 0) OR (t.b = 0 AND t.d = 0); }; ENDCASE => ERROR Imager.Error[$Bug]; }; ExcludeRectangle: PUBLIC PROC [context: Context, x, y, w, h: REAL] ~ { WITH context.state SELECT FROM state: State => { ClipRectangle[context, x, y, w, h]; state.clipper.first.exclude _ TRUE; }; ENDCASE => ERROR Imager.Error[$Bug]; }; IntegerClipRectangle: PUBLIC PROC [context: Context, x, y, w, h: INTEGER] ~ { ClipRectangle[context, x, y, w, h]; }; IntegerExcludeRectangle: PUBLIC PROC [context: Context, x, y, w, h: INTEGER] ~ { ExcludeRectangle[context, x, y, w, h]; }; CorrectMask: PUBLIC PROC [context: Context] ~ { WITH context.state SELECT FROM state: State => { SELECT state.correctPass FROM 1 => state.correctMaskCount _ state.correctMaskCount + 1; 2 => IF state.correctMaskCount > 0 THEN { spx: REAL ~ state.correctMaskX/state.correctMaskCount; spy: REAL ~ state.correctMaskY/state.correctMaskCount; state.correctMaskX _ state.correctMaskX - spx; state.correctMaskY _ state.correctMaskY - spy; state.correctMaskCount _ state.correctMaskCount - 1; state.cpx _ state.cpx + spx; state.cpy _ state.cpy + spy; }; ENDCASE => NULL; }; ENDCASE => ERROR Imager.Error[$Bug]; }; CorrectSpace: PUBLIC PROC [context: Context, v: Pair] ~ { WITH context.state SELECT FROM state: State => CorrectSpaceView[context, ImagerTransform.TransformVec[v, state.T]]; ENDCASE => ERROR Imager.Error[$Bug]; }; CorrectSpaceView: PUBLIC PROC [context: Context, v: Pair] ~ { WITH context.state SELECT FROM state: State => { SELECT state.correctPass FROM 1 => { state.correctSumX _ state.correctSumX + v.x; state.correctSumY _ state.correctSumY + v.y; }; 2 => { Div: PROC [num, denom: REAL] RETURNS [REAL] ~ { IF denom = 0.0 THEN { IF num = 0.0 THEN RETURN [0.0] ELSE ERROR Imager.Error[$ZeroDivideInCorrectSpace] } ELSE RETURN [num/denom] }; spx: REAL ~ Div[v.x*state.correctSpaceX, state.correctSumX]; spy: REAL ~ Div[v.y*state.correctSpaceY, state.correctSumY]; state.correctSumX _ state.correctSumX - v.x; state.correctSumY _ state.correctSumY - v.y; state.correctSpaceX _ state.correctSpaceX - spx; state.correctSpaceY _ state.correctSpaceY - spy; state.cpx _ state.cpx + spx; state.cpy _ state.cpy + spy; }; ENDCASE => NULL; }; ENDCASE => ERROR Imager.Error[$Bug]; }; SetCorrectMeasure: PUBLIC PROC [context: Context, v: Pair] ~ { WITH context.state SELECT FROM state: State => { [[state.correctMX, state.correctMY]] _ ImagerTransform.TransformVec[v, state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; SetCorrectTolerance: PUBLIC PROC [context: Context, v: Pair] ~ { WITH context.state SELECT FROM state: State => { [[state.correctTX, state.correctTY]] _ ImagerTransform.TransformVec[v, state.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Space: PUBLIC PROC [context: Context, x: REAL] ~ { <> WITH context.state SELECT FROM state: State => { v: Pair ~ ImagerTransform.TransformVec[[x, 0], state.T]; state.cpx _ state.cpx + v.x; state.cpy _ state.cpy + v.y; SELECT state.correctPass FROM 1 => { state.correctSumX _ state.correctSumX + v.x; state.correctSumY _ state.correctSumY + v.y; }; 2 => IF state.correctMaskCount > 0 THEN { Div: PROC [num, denom: REAL] RETURNS [REAL] ~ { IF denom = 0.0 THEN { IF num = 0.0 THEN RETURN [0.0] ELSE ERROR Imager.Error[$ZeroDivideInCorrectSpace] } ELSE RETURN [num/denom] }; spx: REAL ~ Div[v.x*state.correctSpaceX, state.correctSumX]; spy: REAL ~ Div[v.y*state.correctSpaceY, state.correctSumY]; state.correctSumX _ state.correctSumX - v.x; state.correctSumY _ state.correctSumY - v.y; state.correctSpaceX _ state.correctSpaceX - spx; state.correctSpaceY _ state.correctSpaceY - spy; state.cpx _ state.cpx + spx; state.cpy _ state.cpy + spy; }; ENDCASE => NULL; }; ENDCASE => ERROR Imager.Error[$Bug]; }; IntegerSpace: PUBLIC PROC [context: Context, x: INTEGER] ~ { Imager.Space[context, x]; }; Correct: PUBLIC PROC [context: Context, body: PUBLIC PROC] ~ { WITH context.state SELECT FROM state: State => { Length: PROC [x, y: REAL] RETURNS [REAL] ~ { <> RETURN [Real.SqRt[x*x + y*y]]; }; state.correctcpx _ state.cpx; state.correctcpy _ state.cpy; state.noImage _ 1; state.correctMaskCount _ 0; state.correctSumX _ state.correctSpaceY _ 0; state.correctPass _ 1; Imager.DoSave[context, body]; state.correctTargetX _ state.correctcpx + state.correctMX; state.correctTargetY _ state.correctcpy + state.correctMY; state.correctMaskX _ state.correctMaskY _ 0; state.correctMaskCount _ state.correctMaskCount - 1; state.correctSpaceX _ state.correctTargetX - state.cpx; state.correctSpaceY _ state.correctTargetY - state.cpy; CHECKED { IF ( Length[state.correctSpaceX, state.correctSpaceY] > state.correctShrink*Length[state.correctSumX, state.correctSumY] AND Length[state.correctcpx - state.correctTargetX, state.correctcpy - state.correctTargetY] < Length[state.correctcpx - state.cpx, state.correctcpy - state.cpy] ) THEN { state.correctMaskX _ state.correctSpaceX + state.correctShrink*state.correctSumX; state.correctMaskY _ state.correctSpaceY + state.correctShrink*state.correctSumY; state.correctSpaceX _ state.correctSpaceX - state.correctMaskX; state.correctSpaceY _ state.correctSpaceY - state.correctMaskY; }; IF state.correctSumX = 0 AND state.correctSpaceX # 0 THEN { state.correctMaskX _ state.correctSpaceX; state.correctSpaceX _ 0; }; IF state.correctSumY = 0 AND state.correctSpaceY # 0 THEN { state.correctMaskY _ state.correctSpaceY; state.correctSpaceY _ 0; }; }; state.cpx _ state.correctcpx; state.cpy _ state.correctcpy; state.noImage _ 0; state.correctPass _ 2; Imager.DoSave[context, body]; state.correctPass _ 0; IF Length[state.correctTargetX - state.cpx, state.correctTargetY - state.cpy] > Length[state.correctTX, state.correctTY] THEN ERROR Imager.Error[$UnableToProperlyAdjustMaskPositions]; state.cpx _ state.correctTargetX; state.cpy _ state.correctTargetY; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Reset: PUBLIC PROC [context: Context] ~ { WITH context.state SELECT FROM state: State => { propertyList: REF _ state.propertyList; state^ _ InitialStateRep; state.color _ Imager.black; state.propertyList _ propertyList; }; ENDCASE => ERROR Imager.Error[$Bug]; }; DrawBitmap: PUBLIC PROC [context: Context, base: LONG POINTER, raster: CARDINAL, area: IntRectangle] ~ { ERROR Imager.Error[$NotYetImplemented]; }; MaskBits: PUBLIC PROC [context: Context, base: LONG POINTER, raster: CARDINAL, tile: IntRectangle, area: IntRectangle] ~ { ERROR Imager.Error[$NotYetImplemented]; }; GetSurfaceBounds: PUBLIC PROC [context: Context] RETURNS [IntRectangle] ~ { WITH context.state SELECT FROM state: State => { ERROR Imager.Error[$NotYetImplemented]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; END.