DIRECTORY
Imager USING [ConcatT, Context, DoSave, DoSaveAll, PathProc, PixelArray, SetColor, SetFont, SetXY],
ImagerBackdoor USING [Clipper, IntKey, RealKey, SetInt, SetReal, ViewTranslateI],
ImagerBox USING [Rectangle],
ImagerColor USING [Color, ColorOperator, ColorRep, SpecialColor],
ImagerDevice USING [AllowedMasks, DeviceClass, DeviceClassRep, Device, DeviceParm, MakeDeviceParm],
ImagerFont USING [Font, XStringProc],
ImagerManhattan USING [BoundingBox, CreateFromBoxes, Destroy, DestructiveUnion, Polygon, Shift],
ImagerMaskCache USING [Parameters, ParametersRep],
ImagerMaskCapture USING [],
ImagerPrivate USING [Class],
ImagerRaster USING [Create, CreateClass, GetDevice, SetDeviceClipBox],
ImagerSample USING [Clear, Fill, NewSampleMap, SampleMap],
ImagerState USING [StateGetFont, StateGetInt, StateGetReal, StateSpace],
ImagerTransformation USING [Transformation],
Real USING [LargestNumber],
SF USING [Box, BoxAction, BoxGenerator, Displace, Max, maxVec, Min, minVec, Nonempty],
Vector2 USING [VEC];
~
BEGIN
allowMultipleCoverage:
BOOL ¬
FALSE;
Clipper: TYPE ~ ImagerBackdoor.Clipper;
Color: TYPE ~ ImagerColor.Color;
Context: TYPE ~ Imager.Context;
Device: TYPE ~ ImagerDevice.Device;
Font: TYPE ~ ImagerFont.Font;
IntKey: TYPE ~ ImagerBackdoor.IntKey;
Parameters: TYPE ~ ImagerMaskCache.Parameters;
PathProc: TYPE ~ Imager.PathProc;
PixelArray: TYPE ~ Imager.PixelArray;
RealKey: TYPE ~ ImagerBackdoor.RealKey;
Rectangle: TYPE ~ ImagerBox.Rectangle;
SampleMap: TYPE ~ ImagerSample.SampleMap;
Transformation: TYPE ~ ImagerTransformation.Transformation;
viewOrigin:
NAT ~ 10000;
The view origin away from the origin of device coords.
Smaller than 16K to hit integerTrans often.
unsetColor: ImagerColor.SpecialColor ~
NEW[ImagerColor.ColorRep.constant.special ¬ [constant[special[type: $Unset, data:
NIL, substitute:
NIL]]]];
Data: TYPE ~ REF DataRep;
DataRep:
TYPE ~
RECORD [
boundsOnly: BOOL ¬ FALSE,
checkColor: BOOL ¬ FALSE,
bounds: SF.Box ¬ [],
boxes: ImagerManhattan.Polygon ¬ NIL
];
nullReal:
REAL ~ Real.LargestNumber;
Cant:
PUBLIC
SIGNAL [why:
ATOM] ~
CODE;
CreateContext:
PROC
RETURNS [Context] ~ {
data: Data ~ NEW [DataRep ¬ []];
deviceParm: ImagerDevice.DeviceParm ~ ImagerDevice.MakeDeviceParm[
class: deviceClass,
sSize: INTEGER.LAST,
fSize: INTEGER.LAST,
scanMode: [slow: right, fast: up],
surfaceUnitsPerInch: [1, 1]
];
context: Context ~ ImagerRaster.Create[class: contextClass, deviceParm: deviceParm, deviceClass: deviceClass, data: data, pixelUnits: TRUE];
ImagerRaster.SetDeviceClipBox[context, [max: [INTEGER.LAST, INTEGER.LAST]]];
ImagerBackdoor.ViewTranslateI[context, viewOrigin, viewOrigin];
FOR key: IntKey
IN IntKey[strokeEnd..strokeJoint]
DO
ImagerBackdoor.SetInt[context, key, INT.LAST];
ENDLOOP;
FOR key: RealKey
IN RealKey[mediumXSize..correctTY]
DO
ImagerBackdoor.SetReal[context, key, nullReal];
ENDLOOP;
Imager.SetColor[context, unsetColor];
Imager.SetFont[context, NIL];
Imager.SetXY[context, [0, 0]];
RETURN [context]
};
Public Procs
CaptureBounds:
PUBLIC
PROC [operator:
PROC [Context], m: Transformation, parameters: Parameters]
RETURNS [box:
SF.Box] ~ {
context: Context ~ GetContext[parameters];
device: Device ~ ImagerRaster.GetDevice[context: context];
data: Data ~ NARROW[device.data];
proc: PROC ~ { Imager.ConcatT[context, m]; operator[context] };
data.boundsOnly ¬ TRUE;
data.checkColor ¬ FALSE;
data.bounds ¬ [min: SF.maxVec, max: SF.minVec];
Imager.DoSaveAll[context, proc];
box ¬ data.bounds;
IF SF.Nonempty[box] THEN box ¬ SF.Displace[box, [-viewOrigin, -viewOrigin]];
FreeContext[context];
RETURN [box];
};
CaptureBoxes:
PUBLIC
PROC [operator:
PROC [Context], m: Transformation, boxAction:
SF.BoxAction, checkColor:
BOOL, parameters: Parameters] ~ {
p: ImagerManhattan.Polygon ~ CaptureManhattan[operator, m, checkColor, parameters];
FOR each:
LIST
OF
SF.Box ¬ p, each.rest
UNTIL each =
NIL
DO
boxAction[each.first];
ENDLOOP;
ImagerManhattan.Destroy[p];
};
CaptureBitmap:
PUBLIC
PROC [operator:
PROC [Context], m: Transformation, checkColor:
BOOL, parameters: Parameters]
RETURNS [SampleMap] ~ {
p: ImagerManhattan.Polygon ~ CaptureManhattan[operator, m, checkColor, parameters];
bitmap: SampleMap ~ ImagerSample.NewSampleMap[ImagerManhattan.BoundingBox[p]];
ImagerSample.Clear[bitmap];
FOR each:
LIST
OF
SF.Box ¬ p, each.rest
UNTIL each =
NIL
DO
ImagerSample.Fill[map: bitmap, box: each.first, value: 1];
ENDLOOP;
ImagerManhattan.Destroy[p];
RETURN [bitmap]
};
CaptureManhattan:
PUBLIC
PROC [operator:
PROC [Context], m: Transformation, checkColor:
BOOL, parameters: Parameters]
RETURNS [p: ImagerManhattan.Polygon ¬
NIL] ~ {
context: Context ~ GetContext[parameters];
device: Device ~ ImagerRaster.GetDevice[context: context];
data: Data ~ NARROW[device.data];
proc: PROC ~ { Imager.ConcatT[context, m]; operator[context] };
data.boundsOnly ¬ FALSE;
data.checkColor ¬ checkColor;
data.bounds ¬ [min: SF.maxVec, max: SF.minVec];
data.boxes ¬ NIL;
Imager.DoSaveAll[context, proc];
ImagerManhattan.Shift[data.boxes, -viewOrigin, -viewOrigin];
p ¬ data.boxes;
data.boxes ¬ NIL;
FreeContext[context];
};
Context Class Procs
MySetT:
PROC [context: Context, m: Transformation] ~ {
SIGNAL Cant[$SetT]};
MyGetInt:
PROC [context: Context, key: IntKey]
RETURNS [
INT] ~ {
i: INT ~ ImagerState.StateGetInt[context, key];
IF i = INT.LAST THEN SIGNAL Cant[$UninitializedState];
RETURN [i]
};
MyGetReal:
PROC [context: Context, key: RealKey]
RETURNS [
REAL] ~ {
r: REAL ~ ImagerState.StateGetReal[context, key];
IF r = nullReal THEN SIGNAL Cant[$UninitializedState];
IF key = DCScpx OR key = DCScpy THEN SIGNAL Cant[$GetDCScp];
RETURN [r]
};
MyGetFont:
PROC [context: Context]
RETURNS [Font] ~ {
font: Font ~ ImagerState.StateGetFont[context];
IF font = NIL THEN SIGNAL Cant[$UninitializedState];
RETURN [font];
};
MyGetColor:
PROC [context: Context]
RETURNS [Color] ~ {
ERROR Cant[$GetColor]
};
MyGetClipper:
PROC [context: Context]
RETURNS [Clipper] ~ {
ERROR Cant[$GetClipper]
};
MySpace:
PROC [context: Context, x:
REAL] ~ {
IF ImagerState.StateGetReal[context, amplifySpace] = nullReal THEN ERROR Cant[$UninitializedState];
ImagerState.StateSpace[context, x];
};
RasterShow: PROC [context: Context, string: ImagerFont.XStringProc, xrel: BOOL] ¬ NIL;
MyShow:
PROC [context: Context, string: ImagerFont.XStringProc, xrel:
BOOL] ~ {
IF ImagerState.StateGetFont[context] = NIL THEN ERROR Cant[$UninitializedState];
RasterShow[context, string, xrel];
};
RasterMaskUnderline: PROC [context: Context, dy: REAL, h: REAL] ¬ NIL;
MyMaskUnderline:
PROC [context: Context, dy:
REAL, h:
REAL] ~ {
IF ImagerState.StateGetReal[context, underlineStart] = nullReal THEN ERROR Cant[$UninitializedState];
RasterMaskUnderline[context, dy, h];
};
MyCorrect:
PROC [context: Context, action:
PROC] ~ {
SIGNAL Cant[$Correct];
Imager.DoSaveAll[context, action];
};
MyDontCorrect:
PROC [context: Context, action:
PROC, saveCP:
BOOL] ~ {
SIGNAL Cant[$Correct];
IF saveCP THEN Imager.DoSaveAll[context, action] ELSE Imager.DoSave[context, action];
};
RasterMaskStroke: PROC [context: Context, path: PathProc, closed: BOOL] ¬ NIL;
MyMaskStroke:
PROC [context: Context, path: PathProc, closed:
BOOL] ~ {
IF ImagerState.StateGetInt[context, strokeEnd] = INT.LAST OR ImagerState.StateGetInt[context, strokeJoint] = INT.LAST OR ImagerState.StateGetReal[context, strokeWidth] = nullReal THEN ERROR Cant[$UninitializedState];
RasterMaskStroke[context, path, closed];
};
MyGetBounds:
PROC [context: Context]
RETURNS [Rectangle] ~ {
ERROR Cant[$GetBounds]};
deviceClass: ImagerDevice.DeviceClass ~
NEW[ImagerDevice.DeviceClassRep ¬ [
SetColor: CaptureSetColor,
MaskBoxes: CaptureMaskBoxes
]];
contextClass: ImagerPrivate.Class ~ MakeClass[];
MakeClass:
PROC
RETURNS [ImagerPrivate.Class] ~ {
new: ImagerPrivate.Class ~ ImagerRaster.CreateClass[type: $Capture];
new.SetT ¬ MySetT;
new.GetInt ¬ MyGetInt;
new.GetReal ¬ MyGetReal;
new.GetFont ¬ MyGetFont;
new.GetColor ¬ MyGetColor;
new.GetClipper ¬ MyGetClipper;
new.Space ¬ MySpace;
RasterMaskUnderline ¬ new.MaskUnderline;
new.MaskUnderline ¬ MyMaskUnderline;
RasterShow ¬ new.Show;
new.Show ¬ MyShow;
new.Correct ¬ MyCorrect;
new.DontCorrect ¬ MyDontCorrect;
RasterMaskStroke ¬ new.MaskStroke;
new.MaskStroke ¬ MyMaskStroke;
new.GetBounds ¬ MyGetBounds;
RETURN [new]
};