<> <> DIRECTORY Imager, ImagerBasic, ImagerDefault, ImagerPrivate, ImagerTransform, Real; ImagerDefaultImpl: CEDAR PROGRAM IMPORTS Imager, ImagerTransform, Real EXPORTS ImagerDefault ~ BEGIN OPEN ImagerDefault; InitialStateRep: StateRep ~ [ cpx: 0.0, cpy: 0.0, correctMX: 0.0, correctMY: 0.0, nps: [ 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, 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 ] ]; InitState: PUBLIC PROC [context: Context] ~ { state: State _ NEW[StateRep _ InitialStateRep]; state.nps.color _ Imager.black; context.state _ state; }; IGet: PUBLIC PROC [context: Context, n: Name] RETURNS [REF] ~ { WITH context.state SELECT FROM state: State => { SELECT n FROM T => RETURN [NEW[ImagerBasic.Transformation _ state.nps.T]]; showVec => RETURN [state.nps.showVec]; color => RETURN [state.nps.color]; clipOutline => RETURN [state.nps.clipper]; ENDCASE => ERROR Imager.Error[$BadSelector]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; 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.nps.T _ t^}; ENDCASE => ERROR Imager.Error[$WrongType]; showVec => state.nps.showVec _ x; color => WITH x SELECT FROM color: ImagerBasic.Color => {state.nps.color _ color}; ENDCASE => ERROR Imager.Error[$WrongType]; clipOutline => state.nps.clipper _ x; ENDCASE => ERROR Imager.Error[$BadSelector]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; IGetReal: PUBLIC PROC [context: Context, n: Name] RETURNS [x: REAL] ~ { WITH context.state SELECT FROM state: State => { SELECT n FROM DCScpx => x _ state.cpx; DCScpy => x _ state.cpy; correctMX => x _ state.correctMX; correctMY => x _ state.correctMY; mediumXSize => x _ state.nps.mediumXSize; mediumYSize => x _ state.nps.mediumYSize; fieldXMin => x _ state.nps.fieldXMin; fieldYMin => x _ state.nps.fieldYMin; fieldXMax => x _ state.nps.fieldXMax; fieldYMax => x _ state.nps.fieldYMax; strokeWidth => x _ state.nps.strokeWidth; underlineStart => x _ state.nps.underlineStart; amplifySpace => x _ state.nps.amplifySpace; correctShrink => x _ state.nps.correctShrink; correctTX => x _ state.nps.correctTX; correctTY => x _ state.nps.correctTY; 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.nps.mediumXSize _ x; mediumYSize => state.nps.mediumYSize _ x; fieldXMin => state.nps.fieldXMin _ x; fieldYMin => state.nps.fieldYMin _ x; fieldXMax => state.nps.fieldXMax _ x; fieldYMax => state.nps.fieldYMax _ x; strokeWidth => state.nps.strokeWidth _ x; underlineStart => state.nps.underlineStart _ x; amplifySpace => state.nps.amplifySpace _ x; correctShrink => state.nps.correctShrink _ x; correctTX => state.nps.correctTX _ x; correctTY => state.nps.correctTY _ x; ENDCASE => ERROR Imager.Error[$BadSelector]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; IGetInt: PUBLIC PROC [context: Context, n: Name] RETURNS [x: INT] ~ { WITH context.state SELECT FROM state: State => { SELECT n FROM priorityImportant => x _ state.nps.priorityImportant; noImage => x _ state.nps.noImage; strokeEnd => x _ state.nps.strokeEnd; correctPass => x _ state.nps.correctPass; 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.nps.priorityImportant _ x; noImage => state.nps.noImage _ x; strokeEnd => state.nps.strokeEnd _ x; correctPass => state.nps.correctPass _ x; ENDCASE => ERROR Imager.Error[$BadSelector]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; ConcatT: PUBLIC PROC [context: Context, m: Transformation] ~ { WITH context.state SELECT FROM state: State => { state.nps.T _ ImagerTransform.Concat[m, state.nps.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; TranslateT: PUBLIC PROC [context: Context, x, y: REAL] ~ { WITH context.state SELECT FROM state: State => { state.nps.T _ ImagerTransform.PreTranslate[x, y, state.nps.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; RotateT: PUBLIC PROC [context: Context, a: REAL] ~ { WITH context.state SELECT FROM state: State => { state.nps.T _ ImagerTransform.PreRotate[a, state.nps.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; ScaleT: PUBLIC PROC [context: Context, s: REAL] ~ { WITH context.state SELECT FROM state: State => { state.nps.T _ ImagerTransform.PreScale[s, s, state.nps.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Scale2T: PUBLIC PROC [context: Context, sx, sy: REAL] ~ { WITH context.state SELECT FROM state: State => { state.nps.T _ ImagerTransform.PreScale[sx, sy, state.nps.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Move: PUBLIC PROC [context: Context] ~ { WITH context.state SELECT FROM state: State => { state.nps.T.c _ state.cpx; state.nps.T.f _ state.cpy; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Trans: PUBLIC PROC [context: Context] ~ { WITH context.state SELECT FROM state: State => { state.nps.T.c _ Real.RoundLI[state.cpx]; state.nps.T.f _ Real.RoundLI[state.cpy]; }; 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.nps.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.nps.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.nps.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.nps.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.nps.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.nps.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.nps.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.nps.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.nps.T]; state.nps.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.nps.T]; Imager.SetXY[context, [state.nps.underlineStart, cp.y-dy-h]]; Imager.Trans[context]; Imager.MaskRectangle[context, 0, 0, cp.x-state.nps.underlineStart, h]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Imager.DoSaveAll[context, SimpleCO]; }; IntegerMaskUnderline: PUBLIC PROC [context: Context, dy, h: INTEGER] ~ { MaskUnderline[context, dy, h]; }; CorrectMask: PUBLIC PROC [context: Context] ~ { WITH context.state SELECT FROM state: State => { SELECT state.nps.correctPass FROM 1 => state.nps.correctMaskCount _ state.nps.correctMaskCount + 1; 2 => IF state.nps.correctMaskCount > 0 THEN { spx: REAL ~ state.nps.correctMaskX/state.nps.correctMaskCount; spy: REAL ~ state.nps.correctMaskY/state.nps.correctMaskCount; state.nps.correctMaskX _ state.nps.correctMaskX - spx; state.nps.correctMaskY _ state.nps.correctMaskY - spy; state.nps.correctMaskCount _ state.nps.correctMaskCount - 1; }; ENDCASE => NULL; }; ENDCASE => ERROR Imager.Error[$Bug]; }; CorrectSpace: PUBLIC PROC [context: Context, v: Pair] ~ { WITH context.state SELECT FROM state: State => { d: Pair ~ ImagerTransform.InverseTransformVec[v, state.nps.T]; SELECT state.nps.correctPass FROM 1 => { state.nps.correctSumX _ state.nps.correctSumX + d.x; state.nps.correctSumY _ state.nps.correctSumY + d.y; }; 2 => IF state.nps.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[d.x*state.nps.correctSpaceX, state.nps.correctSumX]; spy: REAL ~ Div[d.y*state.nps.correctSpaceY, state.nps.correctSumY]; state.nps.correctSumX _ state.nps.correctSumX - d.x; state.nps.correctSumY _ state.nps.correctSumY - d.y; state.nps.correctSpaceX _ state.nps.correctSpaceX - spx; state.nps.correctSpaceY _ state.nps.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.InverseTransformVec[v, state.nps.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; SetCorrectTolerance: PUBLIC PROC [context: Context, v: Pair] ~ { WITH context.state SELECT FROM state: State => { [[state.nps.correctTX, state.nps.correctTY]] _ ImagerTransform.InverseTransformVec[v, state.nps.T]; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Space: PUBLIC PROC [context: Context, x: REAL] ~ { <> WITH context.state SELECT FROM state: State => { d: Pair ~ ImagerTransform.TransformVec[[x, 0], state.nps.T]; state.cpx _ state.cpx + d.x; state.cpy _ state.cpy + d.y; SELECT state.nps.correctPass FROM 1 => { state.nps.correctSumX _ state.nps.correctSumX + d.x; state.nps.correctSumY _ state.nps.correctSumY + d.y; }; 2 => IF state.nps.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[d.x*state.nps.correctSpaceX, state.nps.correctSumX]; spy: REAL ~ Div[d.y*state.nps.correctSpaceY, state.nps.correctSumY]; state.nps.correctSumX _ state.nps.correctSumX - d.x; state.nps.correctSumY _ state.nps.correctSumY - d.y; state.nps.correctSpaceX _ state.nps.correctSpaceX - spx; state.nps.correctSpaceY _ state.nps.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] ~ { p: Pair _ ImagerTransform.InverseTransformVec[[x, y], state.nps.T]; RETURN [Real.SqRt[x*x + y*y]]; }; state.nps.correctcpx _ state.cpx; state.nps.correctcpy _ state.cpy; state.nps.noImage _ 1; state.nps.correctMaskCount _ 0; state.nps.correctSumX _ state.nps.correctSpaceY _ 0; state.nps.correctPass _ 1; Imager.DoSave[context, body]; state.nps.correctTargetX _ state.nps.correctcpx + state.correctMX; state.nps.correctTargetY _ state.nps.correctcpy + state.correctMY; state.nps.correctMaskX _ state.nps.correctMaskY _ 0; state.nps.correctMaskCount _ state.nps.correctMaskCount - 1; state.nps.correctSpaceX _ state.nps.correctTargetX - state.cpx; state.nps.correctSpaceY _ state.nps.correctTargetY - state.cpy; CHECKED { sumLength: REAL _ Length[state.nps.correctSumX, state.nps.correctSumY]; IF sumLength = 0.0 OR ( Length[state.nps.correctSpaceX, state.nps.correctSpaceY] > state.nps.correctShrink*sumLength AND Length[state.nps.correctcpx - state.nps.correctTargetX, state.nps.correctcpy - state.nps.correctTargetY] < Length[state.nps.correctcpx - state.cpx, state.nps.correctcpy - state.cpy] ) THEN { state.nps.correctMaskX _ state.nps.correctSpaceX + state.nps.correctShrink*state.nps.correctSumX; state.nps.correctMaskY _ state.nps.correctSpaceY + state.nps.correctShrink*state.nps.correctSumY; state.nps.correctSpaceX _ state.nps.correctSpaceX - state.nps.correctMaskX; state.nps.correctSpaceY _ state.nps.correctSpaceY - state.nps.correctMaskY; }; }; state.cpx _ state.nps.correctcpx; state.cpy _ state.nps.correctcpy; state.nps.noImage _ 0; state.nps.correctPass _ 2; Imager.DoSave[context, body]; state.nps.correctPass _ 0; IF Length[state.nps.correctTargetX - state.cpx, state.nps.correctTargetY - state.cpy] > Length[state.nps.correctTargetX, state.nps.correctTargetY] THEN ERROR Imager.Error[$UnableToProperlyAdjustMaskPositions]; state.cpx _ state.nps.correctTargetX; state.cpy _ state.nps.correctTargetY; }; ENDCASE => ERROR Imager.Error[$Bug]; }; Reset: PUBLIC PROC [context: Context] ~ { WITH context.state SELECT FROM state: State => { state^ _ InitialStateRep; state.nps.color _ Imager.black; }; 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.