ImagerMaskCaptureImpl.mesa
Copyright Ó 1986, 1987, 1989, 1990, 1991 by Xerox Corporation. All rights reserved.
Michael Plass, October 11, 1991 1:36 pm PDT
Russ Atkinson (RRA) September 5, 1990 5:43 pm PDT
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];
ImagerMaskCaptureImpl: CEDAR MONITOR
IMPORTS Imager, ImagerBackdoor, ImagerDevice, ImagerManhattan, ImagerRaster, ImagerSample, ImagerState, SF
EXPORTS ImagerMaskCapture
~ 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;
VEC: TYPE ~ Vector2.VEC;
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]
};
Context Cache
defaultParameters: Parameters ¬ NEW[ImagerMaskCache.ParametersRep ¬ []];
GetContext: PROC [parameters: Parameters] RETURNS [context: Context] ~ {
context ¬ TryGetContext[];
IF context = NIL THEN context ¬ CreateContext[];
IF parameters = NIL THEN parameters ¬ defaultParameters;
ImagerRaster.GetDevice[context].parm.parameters ¬ parameters;
};
c1: Context ¬ NIL;
c2: Context ¬ NIL;
TryGetContext: ENTRY PROC RETURNS [context: Context] ~ INLINE {
IF c1#NIL THEN {context ¬ c1; c1 ¬ NIL}
ELSE IF c2#NIL THEN {context ¬ c2; c2 ¬ NIL}
ELSE context ¬ NIL;
};
FreeContext: ENTRY PROC [context: Context] ~ INLINE {
IF c1=NIL THEN {c1 ¬ context} ELSE c2 ¬ 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];
};
Device Class Procs
CaptureSetColor: PROC [device: Device, color: Color, viewToDevice: Transformation] ~ {
data: Data ~ NARROW[device.data];
IF data.checkColor AND color # unsetColor THEN SIGNAL Cant[$SetColor];
device.state.allow ¬ [unorderedBoxes: TRUE, multipleCoverage: allowMultipleCoverage];
};
CaptureMaskBoxes: PROC [device: Device, bounds: SF.Box, boxes: SF.BoxGenerator] ~ {
data: Data ~ NARROW[device.data];
data.bounds ¬ [min: SF.Min[data.bounds.min, bounds.min], max: SF.Max[data.bounds.max, bounds.max]];
IF NOT data.boundsOnly THEN {
new: ImagerManhattan.Polygon ~ ImagerManhattan.DestructiveUnion[ImagerManhattan.CreateFromBoxes[boxes], data.boxes];
ImagerManhattan.Destroy[data.boxes];
data.boxes ¬ new;
};
};
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]
};
END.