ImagerDefaultImpl.mesa
Doug Wyatt, November 23, 1983 2:02 pm
Michael Plass, April 12, 1984 3:08:20 pm PST
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.colorcolor};
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] ~ {
Equivalent to {SetXYRel[context, [x, 0]]; CorrectSpace[context, [x, 0]]}
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] ~ {
The interpress document asks that this be the length in meters, but since it is only used for comparisons, view coordinates should work as well. If the view coordinates had non-uniform scaling, this would have to be accounted for here.
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.