ImagerDefaultImpl.mesa
Michael Plass, October 31, 1983 12:38 pm
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.colorcolor};
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] ~ {
Equivalent to {SetXYRel[context, [x, 0]]; CorrectSpace[context, [x, 0]]}
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.