~
BEGIN
smallestBitmap:
NAT ← 10;
All bitmaps will be at least this big, in an attempt to improve locality.
permanentThreshold:
NAT ← 0;
Bitmaps smaller than this will be allocated from the permanent zone.
PixelMap: TYPE ~ ImagerPixelMap.PixelMap;
Manhattan: TYPE ~ ImagerManhattan.Polygon;
DeviceBox: TYPE ~ ImagerDevice.DeviceBox;
DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle;
Class: TYPE ~ REF ClassRep;
ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; -- export to Imager.ClassRep
Context: TYPE ~ Imager.Context;
Color: TYPE ~ Imager.Color;
ColorOperator: TYPE ~ Imager.ColorOperator;
Device: TYPE ~ ImagerDevice.Device;
Font: TYPE ~ ImagerFont.Font;
PathProc: TYPE ~ Imager.PathProc;
PixelArray: TYPE ~ Imager.PixelArray;
Rectangle: TYPE ~ ImagerTransformation.Rectangle;
Transformation: TYPE ~ ImagerTransformation.Transformation;
VEC: TYPE ~ Vector2.VEC;
Clipper: TYPE ~ ImagerBackdoor.Clipper;
IntKey: TYPE ~ ImagerBackdoor.IntKey;
RealKey: TYPE ~ ImagerBackdoor.RealKey;
XChar: TYPE ~ ImagerFont.XChar;
CorrectionType: TYPE ~ ImagerFont.CorrectionType;
CharMask: TYPE ~ ImagerDevice.CharMask;
RunProc: TYPE ~ ImagerDevice.RunProc;
BoxProc:
TYPE ~ ImagerDevice
.BoxProc;
surfaceOrigin:
NAT ~ 10000;
The surface origin away from the origin of device coords, since DeviceBox uses cardinals.
Smaller than 16K to hit integerTrans often.
DeviceData: TYPE ~ REF DeviceDataRep;
DeviceDataRep:
TYPE ~
RECORD [
rectangles: Manhattan
];
CreateDevice:
PROC
RETURNS [Device] ~ {
deviceData: DeviceData ~
NEW[DeviceDataRep ← [
rectangles: NIL
]];
device: Device ~
NEW[ImagerDevice.DeviceRep ← [
class: deviceClass,
data: deviceData,
box: [smin: 0, fmin: 0, smax: 2*surfaceOrigin-1, fmax: 2*surfaceOrigin-1],
surfaceToDevice: ImagerTransformation.Translate[[surfaceOrigin, surfaceOrigin]],
surfaceUnitsPerInch: [1,1], -- doesn't really matter
surfaceUnitsPerPixel: 1
]];
RETURN [device];
};
deviceClass: ImagerDevice.Class ~
NEW[ImagerDevice.ClassRep ← [
type: $RasterCapture,
SetColor: NullSetColor,
SetPriority: NullSetPriority,
SetHalftone: NullSetHalftone,
MaskRuns: MaskRuns,
MaskBoxes: MaskBoxes,
MaskBits: MaskBits
]];
NullSetColor: PROC[device: Device, color: Color, viewToDevice: Transformation] ~ {};
NullSetPriority: PROC[device: Device, priorityImportant: BOOL] ~ {};
NullSetHalftone:
PROC[device: Device, halftone: ImagerDevice.HalftoneParameters] ~ {};
MaskManhattan:
PROC[device: Device, addition: Manhattan] ~ {
deviceData: DeviceData ~ NARROW[device.data];
new: Manhattan ~ ImagerManhattan.Union[addition, deviceData.rectangles];
ImagerManhattan.Destroy[addition];
ImagerManhattan.Destroy[deviceData.rectangles];
deviceData.rectangles ← new;
};
MaskRuns:
PROC[device: Device, bounds: DeviceBox, runs:
PROC[RunProc]] ~ {
Runs: PROC[run: RunProc, repeat: PROC[NAT]] ~ {runs[run]};
MaskManhattan[device, ImagerManhattan.CreateFromRuns[Runs]];
};
MaskBoxes:
PROC[device: Device, bounds: DeviceBox, boxes:
PROC[BoxProc]] ~ {
Box:
PROC[b: DeviceBox] ~ {
MaskManhattan[device, ImagerManhattan.CreateFromBox[[b.smin, b.fmin, b.smax-b.smin, b.fmax-b.fmin]]];
};
boxes[Box];
};
MaskBits:
PROC[device: Device, srcBase:
LONG
POINTER, srcWordsPerLine:
NAT,
ts, tf:
INTEGER, boxes:
PROC[BoxProc]] ~ {
Box:
PROC[b: DeviceBox] ~ {
ManhattanRuns:
PROC[run: RunProc, repeat:
PROC[
NAT]] ~ {
ImagerMask.RunsFromBits[
base: srcBase,
wordsPerLine: srcWordsPerLine,
sBits: b.smin-ts,
fBits: b.fmin-tf,
sSize: b.smax-b.smin,
fSize: b.fmax-b.fmin,
sRuns: b.smin,
fRuns: b.fmin,
run: run
];
};
MaskManhattan[device, ImagerManhattan.CreateFromRuns[ManhattanRuns]];
};
boxes[Box];
};
CreateContext:
PROC
RETURNS [Context] ~ {
ctxData: CtxData ~ NEW[CtxDataRep];
device: Device ~ CreateDevice[];
ctxData.rasterContext ← ImagerRaster.Create[device: device, pixelUnits: TRUE, fontCache: NIL];
ctxData.deviceData ← NARROW[device.data];
ctxData.smin ← ctxData.fmin ← Real.LargestNumber;
ctxData.smax ← ctxData.smax ← -Real.LargestNumber;
RETURN [NEW[Imager.ContextRep ← [class: captureClass, state: NIL, data: ctxData]]];
};
c1: Context ← NIL;
c2: Context ← NIL;
GetContext:
ENTRY
PROC
RETURNS [context: Context] ~ {
IF c1#NIL THEN {context ← c1; c1 ← NIL}
ELSE IF c2#NIL THEN {context ← c2; c2 ← NIL}
ELSE context ← CreateContext[];
};
FreeContext:
ENTRY
PROC [context: Context] ~ {
ctxData: CtxData ~ NARROW[context.data];
rasterContext: Context ~ ctxData.rasterContext;
deviceData: DeviceData ~ ctxData.deviceData;
ctxData^ ← [rasterContext: rasterContext, deviceData: deviceData, firstFont: NIL, firstChar: [0,0], smin: Real.LargestNumber, fmin: Real.LargestNumber, smax: Real.LargestNumber, fmax: -Real.LargestNumber];
deviceData.rectangles ← NIL;
IF c1=NIL THEN {c1 ← context} ELSE c2 ← context;
};
GetRectangles:
PROC [context: Context]
RETURNS [p: Manhattan] ~ {
ctxData: CtxData ~ NARROW[context.data];
p ← ctxData.deviceData.rectangles;
ctxData.deviceData.rectangles ← NIL;
};
RasterCharMaskFromManhattan:
PROC [p: Manhattan, bb: DeviceRectangle]
RETURNS [mask:
REF ImagerDevice.CharMaskRep.raster] ~
TRUSTED {
rast: NAT ~ (bb.fSize+(Basics.bitsPerWord-1))/Basics.bitsPerWord;
bitmapWords: LONG CARDINAL ~ Basics.LongMult[bb.sSize, rast];
pixelMap: PixelMap;
zone: ZONE ~ IF bitmapWords < permanentThreshold THEN SafeStorage.GetPermanentZone[] ELSE SafeStorage.GetSystemZone[];
IF bitmapWords > NAT.LAST THEN RETURN [NIL];
mask ← NEW[ImagerDevice.CharMaskRep.raster[MAX[NAT[bitmapWords], smallestBitmap]]];
mask.flag ← ALL[0];
IF bb.sSize = 0
OR bb.fSize = 0
THEN {
mask.sMinBB ← mask.fMinBB ← mask.sSizeBB ← mask.fSizeBB ← 0;
}
ELSE {
mask.sMinBB ← INTEGER[bb.sMin]-surfaceOrigin;
mask.fMinBB ← INTEGER[bb.fMin]-surfaceOrigin;
mask.sSizeBB ← bb.sSize;
mask.fSizeBB ← bb.fSize;
};
pixelMap ← ImagerPixelMap.CreateFrameBuffer[pointer: @mask[0], words: bitmapWords, lgBitsPerPixel: 0, rast: rast, lines: bb.sSize, ref: mask];
pixelMap ← pixelMap.ShiftMap[bb.sMin, bb.fMin];
pixelMap.Clear[];
WHILE p #
NIL
DO
pixelMap.Fill[p.first, 1];
p ← p.rest;
ENDLOOP;
};
RunsCharMaskFromManhattan:
PROC [p: Manhattan, bb: DeviceRectangle, nRuns:
INT]
RETURNS [mask:
REF ImagerDevice.CharMaskRep.runs] ~ {
i: NAT ← 0;
s: NAT ← 0;
sMinBB: INTEGER ~ INTEGER[bb.sMin]-surfaceOrigin;
fMinBB: INTEGER ~ INTEGER[bb.fMin]-surfaceOrigin;
Run:
PROC [sMin, fMin:
INTEGER, fSize:
NAT] ~ {
smin: NAT ~ sMin-sMinBB-surfaceOrigin;
fmin: NAT ~ fMin-fMinBB-surfaceOrigin;
IF smin # s
THEN {
mask[i-1].lastRun ← TRUE;
s ← s + 1;
WHILE smin > s
DO
mask[i] ← [fMin: 0, lastRun: TRUE, fSize: 0];
i ← i + 1;
s ← s + 1;
ENDLOOP;
};
mask[i] ← [fMin: fmin, lastRun: FALSE, fSize: fSize];
i ← i + 1;
};
IF nRuns = 0 OR nRuns > NAT.LAST/2 THEN RETURN [NIL];
mask ← NEW[ImagerDevice.CharMaskRep.runs[nRuns]];
mask.flag ← ALL[0];
mask.sMinBB ← sMinBB;
mask.fMinBB ← fMinBB;
mask.sSizeBB ← bb.sSize;
mask.fSizeBB ← bb.fSize;
ImagerManhattan.MapRuns[p, Run];
IF i#nRuns THEN ERROR;
IF s+1 # bb.sSize THEN ERROR;
mask[i-1].lastRun ← TRUE;
};
CountRuns:
PROC [p: Manhattan]
RETURNS [runs:
INT ← 0] ~ {
This version includes zero-length runs needed to get the PD run representation to work.
s: INTEGER ← IF p # NIL THEN p.first.sMin ELSE 0;
WHILE p #
NIL
DO
sMin: INTEGER ~ p.first.sMin;
sSize: INTEGER ~ p.first.sSize;
IF sMin > s THEN {runs ← runs + (sMin - s)};
s ← sMin+sSize;
runs ← runs + sSize;
p ← p.rest;
ENDLOOP;
};
Capture:
PUBLIC
PROC [operator:
PROC[Context], m: Transformation, r:
REAL]
RETURNS [charMask: CharMask ←
NIL] ~ {
context: Context ~ GetContext[];
ctxData: CtxData ~ NARROW[context.data];
complete: BOOL ← TRUE;
proc:
PROC ~ {
Imager.ConcatT[context, m];
operator[context ! Cant => {complete ← FALSE; CONTINUE}];
};
Imager.SetXY[context, [0,0]];
Imager.DoSave[context, proc];
IF
NOT complete
THEN {
ImagerManhattan.Destroy[GetRectangles[context]];
}
ELSE {
width: VEC ← ImagerBackdoor.GetCP[ctxData.rasterContext];
p: Manhattan ~ GetRectangles[context];
IF
ABS[width.x] <= 16383.0
AND
ABS[width.y] <= 16383.0
THEN {
bb: DeviceRectangle ~ ImagerManhattan.BoundingBox[p];
bitmapWords: REAL ~ REAL[bb.sSize]*REAL[(bb.fSize+15)/16];
nRuns: INT ~ CountRuns[p];
charMask ← (
IF nRuns*2*r >= bitmapWords THEN RasterCharMaskFromManhattan[p, bb]
ELSE RunsCharMaskFromManhattan[p, bb, nRuns]);
IF charMask#
NIL
THEN {
charMask.amplified ← ctxData.amplified;
charMask.correction ← ctxData.correction;
charMask.metricsValid ← TRUE;
charMask.sWidth ← Scaled.FromReal[width.x];
charMask.fWidth ← Scaled.FromReal[width.y];
};
};
ImagerManhattan.Destroy[p];
};
FreeContext[context];
};
CaptureBounds:
PUBLIC
PROC [operator:
PROC[Context], m: Transformation]
RETURNS [Rectangle] ~ {
p: Manhattan ← CaptureManhattan[operator, m ! Cant => {
SELECT why
FROM
$GetT, $GetColor, $GetClipper, $GetBoundingRectangle => REJECT;
ENDCASE => RESUME;
}];
d: DeviceRectangle ~ ImagerManhattan.BoundingBox[p];
ImagerManhattan.Destroy[p];
RETURN [[x: d.sMin, y: d.fMin, w: d.sSize, h: d.fSize]]
};
CaptureManhattan:
PUBLIC
PROC [operator:
PROC[Context], m: Transformation]
RETURNS [p: Manhattan ←
NIL] ~ {
context: Context ~ GetContext[];
ctxData: CtxData ~ NARROW[context.data];
complete: BOOL ← TRUE;
proc:
PROC ~ {
Imager.ConcatT[context, m];
operator[context];
};
Imager.SetXY[context, [0,0]];
Imager.DoSave[context, proc];
p ← GetRectangles[context];
ImagerManhattan.Shift[p, -surfaceOrigin, -surfaceOrigin];
FreeContext[context];
};
CaptureRuns:
PUBLIC
PROC [operator:
PROC[Context], m: Transformation, run: RunProc] ~ {
p: Manhattan ← CaptureManhattan[operator, m];
ImagerManhattan.MapRuns[p, run];
ImagerManhattan.Destroy[p];
};
CaptureBitmap:
PUBLIC
PROC [operator:
PROC[Context], m: Transformation]
RETURNS [pixelMap: PixelMap] ~ {
p: Manhattan ← CaptureManhattan[operator, m];
pixelMap ← ImagerPixelMap.Create[0, p.BoundingBox];
pixelMap.Clear;
FOR t: Manhattan ← p, t.rest
UNTIL t =
NIL
DO
pixelMap.Fill[t.first, 1];
ENDLOOP;
ImagerManhattan.Destroy[p];
};
OK:
TYPE ~
RECORD [
int: PACKED ARRAY IntKey OF BOOL ← ALL[FALSE],
real: PACKED ARRAY RealKey OF BOOL ← ALL[FALSE],
font: BOOL ← FALSE
];
CtxData: TYPE ~ REF CtxDataRep;
CtxDataRep:
TYPE ~
RECORD [
rasterContext: Context,
deviceData: DeviceData,
ok: OK,
amplified: BOOLEAN ← FALSE,
correction: CorrectionType ← none,
nChars: INT ← 0,
firstFont: REF,
firstChar: XChar,
smin, fmin, smax, fmax: REAL
];
Cant: PUBLIC SIGNAL [why: ATOM] ~ CODE;
MyDoSave:
PROC[context: Context, action:
PROC, all:
BOOL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
ok: OK ~ ctxData.ok;
class.DoSave[ctxData.rasterContext, action, all ! UNWIND => {ctxData.ok ← ok}];
ctxData.ok ← ok;
};
MySetInt:
PROC[context: Context, key: IntKey, val:
INT] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
ctxData.ok.int[key] ← TRUE;
class.SetInt[context: ctxData.rasterContext, key: key, val: val];
};
MySetReal:
PROC[context: Context, key: RealKey, val:
REAL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
ctxData.ok.real[key] ← TRUE;
class.SetReal[context: ctxData.rasterContext, key: key, val: val];
};
MySetT: PROC[context: Context, m: Transformation] ~ {SIGNAL Cant[$SetT]};
MySetFont:
PROC[context: Context, font: Font] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
ctxData.ok.font ← TRUE;
class.SetFont[ctxData.rasterContext, font];
};
MySetColor: PROC[context: Context, color: Color] ~ {SIGNAL Cant[$SetColor]};
MySetClipper: PROC[context: Context, clipper: Clipper] ~ {SIGNAL Cant[$SetClipper]};
MyGetInt:
PROC[context: Context, key: IntKey]
RETURNS[
INT] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
IF NOT ctxData.ok.int[key] THEN SIGNAL Cant[$UninitializedState];
RETURN [class.GetInt[ctxData.rasterContext, key]];
};
MyGetReal:
PROC[context: Context, key: RealKey]
RETURNS[
REAL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
IF key=amplifySpace
AND
NOT ctxData.ok.real[key]
THEN {
ctxData.amplified ←
TRUE;
Assume the operator is a good guy and will use this to amplify the width vector.
RETURN [1.0];
};
IF NOT ctxData.ok.real[key] THEN SIGNAL Cant[$UninitializedState];
RETURN [class.GetReal[ctxData.rasterContext, key]];
};
MyGetT:
PROC[context: Context]
RETURNS[Transformation] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
RETURN [class.GetT[ctxData.rasterContext]];
};
MyGetFont:
PROC[context: Context]
RETURNS[Font] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
IF NOT ctxData.ok.font THEN SIGNAL Cant[$UninitializedState];
RETURN [class.GetFont[ctxData.rasterContext]];
};
MyGetColor: PROC[context: Context] RETURNS[Color] ~ {ERROR Cant[$GetColor]};
MyGetClipper: PROC[context: Context] RETURNS[Clipper] ~ {ERROR Cant[$GetClipper]};
MyConcatT:
PROC[context: Context, m: Transformation] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.ConcatT[ctxData.rasterContext, m];
};
MyScale2T:
PROC[context: Context, s:
VEC] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.Scale2T[ctxData.rasterContext, s];
};
MyRotateT:
PROC[context: Context, a:
REAL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.RotateT[ctxData.rasterContext, a];
};
MyTranslateT:
PROC[context: Context, t:
VEC] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.TranslateT[ctxData.rasterContext, t];
};
MyMove:
PROC[context: Context, rounded:
BOOL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.Move[ctxData.rasterContext, rounded];
};
MySetXY:
PROC[context: Context, p:
VEC] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.SetXY[ctxData.rasterContext, p];
};
MySetXYRel:
PROC[context: Context, v:
VEC] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.SetXYRel[ctxData.rasterContext, v];
};
MyShow:
PROC[context: Context, string: ImagerFont.XStringProc, xrel:
BOOL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.Show[ctxData.rasterContext, string, xrel];
};
MyShowText:
PROC[context: Context, text:
REF
READONLY
TEXT, start, len:
NAT, xrel:
BOOL]~{
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.ShowText[ctxData.rasterContext, text, start, len, xrel];
};
MyGetCP:
PROC[context: Context, rounded:
BOOL]
RETURNS[
VEC] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
RETURN [class.GetCP[ctxData.rasterContext, rounded]];
};
MyGetBoundingRectangle: PROC[context: Context] RETURNS [Rectangle] ~ {ERROR Cant[$GetBoundingRectangle]};
MyStartUnderline:
PROC[context: Context] ~ {
ctxData: CtxData ~ NARROW[context.data];
ctxData.ok.real[underlineStart] ← TRUE;
Imager.StartUnderline[ctxData.rasterContext];
};
MyMaskUnderline:
PROC[context: Context, dy, h:
REAL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
IF NOT ctxData.ok.real[underlineStart] THEN SIGNAL Cant[$UninitializedState];
Imager.MaskUnderline[ctxData.rasterContext, dy, h];
};
MyCorrectMask:
PROC[context: Context] ~ {
ctxData: CtxData ~ NARROW[context.data];
IF ctxData.correction#none THEN SIGNAL Cant[$CorrectMask];
ctxData.correction ← mask;
};
MyCorrectSpace:
PROC[context: Context, v:
VEC] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
IF ctxData.correction#none THEN SIGNAL Cant[$CorrectSpace];
ctxData.correction ← space;
class.CorrectSpace[ctxData.rasterContext, v];
};
MySpace:
PROC[context: Context, x:
REAL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
IF ctxData.correction#none THEN SIGNAL Cant[$CorrectSpace];
ctxData.correction ← space;
class.Space[ctxData.rasterContext, x];
};
MySetCorrectMeasure: PROC[context: Context, v: VEC] ~ {};
MySetCorrectTolerance: PROC[context: Context, v: VEC] ~ {};
MyCorrect: PROC[context: Context, action: PROC] ~ {SIGNAL Cant[$Correct]; MyDoSave[context, action, TRUE]};
MyDontCorrect: PROC[context: Context, action: PROC, saveCP: BOOL] ~ {SIGNAL Cant[$Correct]; MyDoSave[context, action, saveCP]};
MySetGray: PROC[context: Context, f: REAL] ~ {SIGNAL Cant[$SetColor]};
MySetSampledColor: PROC[context: Context, pa: PixelArray,
m: Transformation, colorOperator: ColorOperator] ~ {SIGNAL Cant[$SetColor]};
MySetSampledBlack: PROC[context: Context, pa: PixelArray,
m: Transformation, clear: BOOL] ~ {SIGNAL Cant[$SetColor]};
MyMaskFill:
PROC[context: Context, path: PathProc, oddWrap:
BOOL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.MaskFill[ctxData.rasterContext, path, oddWrap];
};
MyMaskRectangle:
PROC[context: Context, r: Rectangle] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.MaskRectangle[ctxData.rasterContext, r];
};
MyMaskRectangleI:
PROC[context: Context, x, y, w, h:
INTEGER] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.MaskRectangleI[ctxData.rasterContext, x, y, w, h];
};
MyMaskStroke:
PROC[context: Context, path: PathProc, closed:
BOOL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
IF NOT (ctxData.ok.real[strokeWidth] AND ctxData.ok.int[strokeEnd] AND ctxData.ok.int[strokeJoint]) THEN SIGNAL Cant[$UninitializedState];
class.MaskStroke[ctxData.rasterContext, path, closed];
};
MyMaskVector:
PROC[context: Context, p1, p2:
VEC] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
IF NOT (ctxData.ok.real[strokeWidth] AND ctxData.ok.int[strokeEnd]) THEN SIGNAL Cant[$UninitializedState];
class.MaskVector[ctxData.rasterContext, p1, p2];
};
MyMaskDashedStroke:
PROC[context: Context, path: PathProc,
patternLen:
NAT, pattern:
PROC [
NAT]
RETURNS [
REAL], offset, length:
REAL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
IF NOT (ctxData.ok.real[strokeWidth] AND ctxData.ok.int[strokeEnd] AND ctxData.ok.int[strokeJoint]) THEN SIGNAL Cant[$UninitializedState];
class.MaskDashedStroke[ctxData.rasterContext, path, patternLen, pattern, offset, length];
};
MyMaskPixel:
PROC[context: Context, pa: PixelArray] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.MaskPixel[ctxData.rasterContext, pa];
};
MyMaskBits:
PROC[context: Context, base:
LONG
POINTER, wordsPerLine:
NAT,
sMin, fMin, sSize, fSize:
NAT, tx, ty:
INTEGER] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.MaskBits[ctxData.rasterContext, base, wordsPerLine, sMin, fMin, sSize, fSize, tx, ty];
};
MyClip:
PROC[context: Context, path: PathProc, oddWrap:
BOOL, exclude:
BOOL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.Clip[ctxData.rasterContext, path, oddWrap, exclude];
};
MyClipRectangle:
PROC[context: Context, r: Rectangle, exclude:
BOOL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.ClipRectangle[ctxData.rasterContext, r, exclude];
};
MyClipRectangleI:
PROC[context: Context, x, y, w, h:
INTEGER, exclude:
BOOL] ~ {
ctxData: CtxData ~ NARROW[context.data];
class: Class ~ ctxData.rasterContext.class;
class.ClipRectangleI[ctxData.rasterContext, x, y, w, h, exclude];
};
captureClass: Class ~
NEW[ClassRep ← [
type: $Capture,
DoSave: MyDoSave,
SetInt: MySetInt,
SetReal: MySetReal,
SetT: MySetT,
SetFont: MySetFont,
SetColor: MySetColor,
SetClipper: MySetClipper,
GetInt: MyGetInt,
GetReal: MyGetReal,
GetT: MyGetT,
GetFont: MyGetFont,
GetColor: MyGetColor,
GetClipper: MyGetClipper,
ConcatT: MyConcatT,
Scale2T: MyScale2T,
RotateT: MyRotateT,
TranslateT: MyTranslateT,
Move: MyMove,
SetXY: MySetXY,
SetXYRel: MySetXYRel,
Show: MyShow,
ShowText: MyShowText,
StartUnderline: MyStartUnderline,
MaskUnderline: MyMaskUnderline,
CorrectMask: MyCorrectMask,
CorrectSpace: MyCorrectSpace,
Space: MySpace,
SetCorrectMeasure: MySetCorrectMeasure,
SetCorrectTolerance: MySetCorrectTolerance,
Correct: MyCorrect,
DontCorrect: MyDontCorrect,
SetGray: MySetGray,
SetSampledColor: MySetSampledColor,
SetSampledBlack: MySetSampledBlack,
MaskFill: MyMaskFill,
MaskStroke: MyMaskStroke,
MaskVector: MyMaskVector,
MaskDashedStroke: MyMaskDashedStroke,
MaskRectangle: MyMaskRectangle,
MaskRectangleI: MyMaskRectangleI,
MaskPixel: MyMaskPixel,
MaskBits: MyMaskBits,
Clip: MyClip,
ClipRectangle: MyClipRectangle,
ClipRectangleI: MyClipRectangleI,
GetCP: MyGetCP,
GetBoundingRectangle: MyGetBoundingRectangle,
propList: NIL
]];