ImagerMemoryImpl.mesa
Copyright © 1984, 1985, 1986 Xerox Corporation. All rights reserved.
Eric Nickell, July 17, 1985 5:03:14 pm PDT
Michael Plass, September 24, 1985 4:09:33 pm PDT
Pier, October 8, 1985 2:28:23 pm PDT
Doug Wyatt, May 30, 1986 7:16:30 pm PDT
DIRECTORY
Basics, CountedVM, Imager, ImagerBackdoor, ImagerColorOperator, ImagerExtras, ImagerFont, ImagerMemory, ImagerPath, ImagerPrivate, ImagerTransformation, PrincOpsUtils, Rope;
ImagerMemoryImpl: CEDAR PROGRAM
IMPORTS Basics, CountedVM, Imager, ImagerBackdoor, ImagerColorOperator, ImagerExtras, ImagerFont, ImagerTransformation, PrincOpsUtils, Rope
EXPORTS Imager, ImagerMemory
SHARES Rope -- For QFetch
~ BEGIN
OPEN Imager;
IntKey: TYPE ~ ImagerBackdoor.IntKey;
RealKey: TYPE ~ ImagerBackdoor.RealKey;
Clipper: TYPE ~ ImagerBackdoor.Clipper;
firstMemForm: NAT ~ 1000;
endMemForm: NAT ~ 2000;
Data: TYPE ~ REF DataRep;
DataRep: TYPE ~ RECORD[head, tail: CommandList, getTDone: BOOLFALSE, getTForm: NAT ← firstMemForm];
Class: TYPE ~ ImagerPrivate.Class;
ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; --export to Imager
CommandList: TYPE ~ LIST OF CommandRep;
checkSize: [0..5] ~ SIZE[CommandRep]; -- want to keep the size of CommandRep small.
CommandRep: TYPE ~ RECORD[SELECT type: * FROM
DoSave => [body: CommandList, all: BOOL],
SetInt => [key: IntKey, val: INT],
SetReal => [key: RealKey, val: REAL],
SetT => [m: Transformation],
SetFont => [font: Font],
SetColor => [color: Color],
SetClipper => [clipper: Clipper],
ConcatT => [m: Transformation],
Scale2T => [s: VEC],
RotateT => [a: REAL],
TranslateT => [t: VEC],
Move => [rounded: BOOL],
SetXY => [p: VEC],
SetXYRel => [v: VEC],
Show => [string: XStringSeq, xrel: BOOL],
ShowShort => [text: Rope.Text, xrel: BOOL],
StartUnderline => [],
MaskUnderline => [dy, h: REAL],
CorrectMask => [],
CorrectSpace => [v: VEC],
Space => [x: REAL],
SetCorrectMeasure => [v: VEC],
SetCorrectTolerance => [v: VEC],
Correct => [body: CommandList],
DontCorrect => [body: CommandList, saveCP: BOOL],
SetGray => [f: REAL],
SetSampledColor => [d: REF SetSampledColorData],
SetSampledBlack => [d: REF SetSampledBlackData],
MaskFill => [path: Path, oddWrap: BOOL],
MaskRectangle => [r: REF Rectangle],
MaskRectangleI => [x, y, w, h: INTEGER],
MaskStroke => [path: Path, closed: BOOL],
MaskVector => [p: REF ARRAY [0..2) OF VEC],
MaskDashedStroke => [d: REF MaskDashedStrokeData],
MaskPixel => [pa: PixelArray],
MaskBits => [bits: Bits],
DrawBits => [bits: Bits],
Clip => [path: Path, oddWrap: BOOL, exclude: BOOL],
ClipRectangle => [r: REF Rectangle, exclude: BOOL]
ENDCASE
];
SetSampledColorData: TYPE ~ RECORD [
pa: PixelArray,
m: Transformation,
colorOperator: ColorOperator
];
SetSampledBlackData: TYPE ~ RECORD [
pa: PixelArray,
m: Transformation,
clear: BOOL
];
MaskDashedStrokeData: TYPE ~ RECORD [
path: Path,
pattern: REF PatternSequence,
offset: REAL,
length: REAL
];
PatternSequence: TYPE ~ RECORD [SEQUENCE patternLen: NAT OF REAL];
XStringSeq: TYPE ~ REF XStringSeqRec;
XStringSeqRec: TYPE ~ RECORD [
SEQUENCE n: CARDINAL OF XChar
];
Path: TYPE ~ REF PointSequence;
PointSequence: TYPE ~ RECORD [
rest: REF PointSequence ← NIL,
seq: SEQUENCE k: NAT OF PointRec
];
PointRec: TYPE ~ RECORD [SELECT type: * FROM
move => [p0: VEC],
line => [p1: VEC],
push => [p: VEC],
curve => [p3: VEC], -- preceeded by two pushes
conic => [r: REAL], -- preceeded by two pushes
arc => [p2: VEC] -- preceeded by one push
ENDCASE
];
Utility Procedures
DoPath: PROC [path: Path, moveTo: ImagerPath.MoveToProc, lineTo: ImagerPath.LineToProc, curveTo: ImagerPath.CurveToProc, conicTo: ImagerPath.ConicToProc, arcTo: ImagerPath.ArcToProc] ~ {
stack: ARRAY [0..2) OF VEC;
s: [0..2] ← 0;
UNTIL path = NIL DO
FOR i: NAT IN [0..path.k) DO
pointRec: PointRec ~ path[i];
WITH x: pointRec SELECT FROM
move => {check: [0..0] ~ s; moveTo[x.p0]};
line => {check: [0..0] ~ s; lineTo[x.p1]};
push => {stack[s] ← x.p; s ← s+1};
curve => {check: [2..2] ~ s; curveTo[stack[0], stack[1], x.p3]; s ← 0};
conic => {check: [2..2] ~ s; conicTo[stack[0], stack[1], x.r]; s ← 0};
arc => {check: [1..1] ~ s; arcTo[stack[0], x.p2]; s ← 0};
ENDCASE => ERROR;
ENDLOOP;
path ← path.rest;
ENDLOOP;
};
GetPath: PROC [pathProc: PathProc] RETURNS [path: Path] ~ {
bufSize: NAT ~ 40;
buf: ARRAY [0..bufSize) OF PointRec;
k: NAT ← 0;
Flush: PROC ~ {
rest: REF PointSequence ← NEW[PointSequence[k]];
FOR i: NAT IN [0..k) DO
TRUSTED {rest[i] ← buf[i]};
ENDLOOP;
IF pathTail = NIL THEN path ← rest ELSE pathTail.rest ← rest;
pathTail ← rest;
k ← 0;
};
AppendToPath: PROC [pointRec: PointRec] ~ {
IF k = bufSize THEN Flush[];
TRUSTED {buf[k] ← pointRec};
k ← k + 1;
};
MoveTo: ImagerPath.MoveToProc ~ {
AppendToPath[[move [p]]]
};
LineTo: ImagerPath.LineToProc ~ {
AppendToPath[[line [p1]]]
};
CurveTo: ImagerPath.CurveToProc ~ {
AppendToPath[[push [p1]]];
AppendToPath[[push [p2]]];
AppendToPath[[curve [p3]]]
};
ConicTo: ImagerPath.ConicToProc ~ {
AppendToPath[[push [p1]]];
AppendToPath[[push [p2]]];
AppendToPath[[conic [r]]]
};
ArcTo: ImagerPath.ArcToProc ~ {
AppendToPath[[push [p1]]];
AppendToPath[[arc [p2]]]
};
pathTail: Path ← path ← NIL;
pathProc[MoveTo, LineTo, CurveTo, ConicTo, ArcTo];
Flush[];
};
GetPattern: PROC [patternLen: NAT, pattern: PROC [NAT] RETURNS [REAL]]
RETURNS [patternRef: REF PatternSequence] ~ {
patternRef ← NEW[PatternSequence[patternLen]];
FOR i: NAT IN[0..patternLen) DO patternRef[i] ← pattern[i] ENDLOOP;
};
GetBody: PROC [context: Context, action: PROC] RETURNS [body: CommandList] ~ {
savedData: Data ~ NARROW[context.data];
data: Data;
context.data ← NEW[DataRep ← [NIL, NIL]]; --Start with a fresh trail
action[];    --Perform the action
data ← NARROW[context.data];
context.data ← savedData; 
RETURN [data.head]
};
Append: PROC[context: Context, command: CommandRep] ~ {
WITH context.data SELECT FROM
data: Data => {
tail: CommandList ~ LIST[command];
IF data.tail=NIL THEN data.head ← tail ELSE data.tail.rest ← tail;
data.tail ← tail;
};
ENDCASE => ERROR;
};
ReplayList: PROC [cList: CommandList, into: Context] ~ TRUSTED {
FOR each: CommandList ← cList, each.rest UNTIL each=NIL DO
We use this form of discrimination because it generates a jump table rather than a series of sequential tests. Unfortunately, it needs to be trusted. . .
WITH cmd: each.first SELECT FROM
DoSave => CHECKED {
Action: PROC ~ {
ReplayList[cmd.body, into];
};
IF cmd.all THEN Imager.DoSaveAll[into, Action] ELSE Imager.DoSave[into, Action];
};
SetInt => ImagerBackdoor.SetInt[into, cmd.key, cmd.val];
SetReal => ImagerBackdoor.SetReal[into, cmd.key, cmd.val];
SetT => ImagerBackdoor.SetT[into, cmd.m];
SetFont => Imager.SetFont[into, cmd.font];
SetColor => Imager.SetColor[into, cmd.color];
SetClipper => ImagerBackdoor.SetClipper[into, cmd.clipper];
ConcatT => Imager.ConcatT[into, cmd.m];
Scale2T => Imager.Scale2T[into, cmd.s];
RotateT => Imager.RotateT[into, cmd.a];
TranslateT => Imager.TranslateT[into, cmd.t];
Move => {
IF cmd.rounded THEN Imager.Trans[into] ELSE Imager.Move[into];
};
SetXY => Imager.SetXY[into, cmd.p];
SetXYRel => Imager.SetXYRel[into, cmd.v];
Show => CHECKED {
FeedChar: Imager.XStringProc ~ {
~ PROC [charAction: XCharProc]
XCharProc: TYPE ~ PROC [char: XChar];
FOR i: CARDINAL IN [0..cmd.string.n) DO
charAction[cmd.string[i]];
ENDLOOP;
};
Imager.Show[into, FeedChar, cmd.xrel];
};
ShowShort => CHECKED {
FeedChar: Imager.XStringProc ~ {
~ PROC [charAction: XCharProc]
XCharProc: TYPE ~ PROC [char: XChar];
text: Rope.Text ~ cmd.text;
FOR i: CARDINAL IN [0..text.length) DO
charAction[[0, Rope.QFetch[text, i]-'\000]];
ENDLOOP;
};
Imager.Show[into, FeedChar, cmd.xrel];
};
StartUnderline => Imager.StartUnderline[into];
MaskUnderline => Imager.MaskUnderline[into, cmd.dy, cmd.h];
CorrectMask => Imager.CorrectMask[into];
CorrectSpace => Imager.CorrectSpace[into, cmd.v];
Space => Imager.Space[into, cmd.x];
SetCorrectMeasure => Imager.SetCorrectMeasure[into, cmd.v];
SetCorrectTolerance => Imager.SetCorrectTolerance[into, cmd.v];
Correct => CHECKED {
Action: PROC ~ {
ReplayList[cmd.body, into];
};
Imager.Correct[into, Action];
};
DontCorrect => CHECKED {
Action: PROC ~ {
ReplayList[cmd.body, into];
};
Imager.DontCorrect[into, Action, cmd.saveCP];
};
SetGray => Imager.SetGray[into, cmd.f];
SetSampledColor => Imager.SetSampledColor[into, cmd.d.pa, cmd.d.m, cmd.d.colorOperator];
SetSampledBlack => Imager.SetSampledBlack[into, cmd.d.pa, cmd.d.m, cmd.d.clear];
MaskFill => CHECKED {
PathProc: Imager.PathProc ~ {
DoPath[cmd.path, moveTo, lineTo, curveTo, conicTo, arcTo];
};
Imager.MaskFill[into, PathProc, cmd.oddWrap];
};
MaskRectangle => Imager.MaskRectangle[into, cmd.r^];
MaskRectangleI => Imager.MaskRectangleI[into, cmd.x, cmd.y, cmd.w, cmd.h];
MaskStroke => CHECKED {
PathProc: Imager.PathProc ~ {
DoPath[cmd.path, moveTo, lineTo, curveTo, conicTo, arcTo];
};
Imager.MaskStroke[into, PathProc, cmd.closed];
};
MaskVector => Imager.MaskVector[into, cmd.p^[0], cmd.p^[1]];
MaskDashedStroke => CHECKED {
path: Imager.PathProc ~ {
DoPath[cmd.d.path, moveTo, lineTo, curveTo, conicTo, arcTo];
};
pattern: PROC [i: NAT] RETURNS [REAL] ~ { RETURN[cmd.d.pattern[i]] };
ImagerExtras.MaskDashedStroke[context: into, path: path,
patternLen: cmd.d.pattern.patternLen, pattern: pattern,
offset: cmd.d.offset, length: cmd.d.length];
};
MaskPixel => Imager.MaskPixel[into, cmd.pa];
MaskBits => Imager.MaskBits[into, cmd.bits.vm.pointer, cmd.bits.wordsPerLine, cmd.bits.sMin, cmd.bits.fMin, cmd.bits.sSize, cmd.bits.fSize, cmd.bits.tx, cmd.bits.ty];
DrawBits => ImagerBackdoor.DrawBits[into, cmd.bits.vm.pointer, cmd.bits.wordsPerLine, cmd.bits.sMin, cmd.bits.fMin, cmd.bits.sSize, cmd.bits.fSize, cmd.bits.tx, cmd.bits.ty];
Clip => CHECKED {
PathProc: Imager.PathProc ~ {
DoPath[cmd.path, moveTo, lineTo, curveTo, conicTo, arcTo];
};
Imager.Clip[into, PathProc, cmd.oddWrap, cmd.exclude];
};
ClipRectangle => Imager.ClipRectangle[into, cmd.r^, cmd.exclude];
ENDCASE => ERROR;
ENDLOOP;
};
ReplayListSize: PROC [cList: CommandList] RETURNS [size: INT] ~ TRUSTED {
size ← 0;
FOR each: CommandList ← cList, each.rest UNTIL each=NIL DO
We use this form of discrimination because it generates a jump table rather than a series of sequential tests. Unfortunately, it needs to be trusted. . .
WITH cmd: each.first SELECT FROM
DoSave => CHECKED {size ← size+ReplayListSize[cmd.body];};
SetInt => size ← size+SIZE[CommandRep[SetInt]];
SetReal => size ← size+SIZE[CommandRep[SetReal]];
SetT => size ← size+SIZE[CommandRep[SetT]];
SetFont => size ← size+SIZE[CommandRep[SetFont]];
SetColor => size ← size+SIZE[CommandRep[SetColor]];
SetClipper => size ← size+SIZE[CommandRep[SetClipper]];
ConcatT => size ← size+SIZE[CommandRep[ConcatT]];
Scale2T => size ← size+SIZE[CommandRep[Scale2T]];
RotateT => size ← size+SIZE[CommandRep[RotateT]];
TranslateT => size ← size+SIZE[CommandRep[TranslateT]];
Move => size ← size+SIZE[CommandRep[Move]];
SetXY => size ← size+SIZE[CommandRep[SetXY]];
SetXYRel => size ← size+SIZE[CommandRep[SetXYRel]];
Show => size ← size+SIZE[XStringSeq]+1;
ShowShort => size ← size+SIZE[Rope.Text]+1;
StartUnderline => size ← size+SIZE[CommandRep[StartUnderline]];
MaskUnderline => size ← size+SIZE[CommandRep[MaskUnderline]];
CorrectMask => size ← size+SIZE[CommandRep[CorrectMask]];
CorrectSpace => size ← size+SIZE[CommandRep[CorrectSpace]];
Space => size ← size+SIZE[CommandRep[Space]];
SetCorrectMeasure => size ← size+SIZE[CommandRep[SetCorrectMeasure]];
SetCorrectTolerance => size ← size+SIZE[CommandRep[SetCorrectTolerance]];
Correct => CHECKED {size ← size+ReplayListSize[cmd.body];};
DontCorrect => CHECKED {size ← size+ReplayListSize[cmd.body];};
SetGray => size ← size+SIZE[CommandRep[SetGray]];
SetSampledColor => size ← size+SIZE[CommandRep[SetSampledColor]];
SetSampledBlack => size ← size+SIZE[CommandRep[SetSampledBlack]];
MaskFill => size ← size+SIZE[CommandRep[MaskFill]];
MaskRectangle => size ← size+SIZE[CommandRep[MaskRectangle]];
MaskRectangleI => size ← size+SIZE[CommandRep[MaskRectangleI]];
MaskStroke => size ← size+SIZE[CommandRep[MaskStroke]];
MaskVector => size ← size+SIZE[CommandRep[MaskVector]];
MaskDashedStroke => size ← size+SIZE[CommandRep[MaskDashedStroke]];
MaskPixel => size ← size+SIZE[CommandRep[MaskPixel]];
MaskBits => size ← size+SIZE[CommandRep[MaskBits]];
DrawBits => size ← size+SIZE[CommandRep[DrawBits]];
Clip => size ← size+SIZE[CommandRep[Clip]];
ClipRectangle => size ← size+SIZE[CommandRep[ClipRectangle]];
ENDCASE => ERROR;
ENDLOOP;
};
Public Procs
NewMemoryContext: PUBLIC PROC RETURNS [c: Context] ~ {
c ← NEW[Imager.ContextRep ← [class: memoryClass, data: NEW[DataRep ← [NIL, NIL]]]];
};
Replay: PUBLIC PROC [c, into: Context] ~ {
cList: CommandList ~ NARROW[c.data, Data].head;
ReplayList[cList, into];
};
GetContextSize: PUBLIC PROC [c: Context] RETURNS [size: INT] ~ {
cList: CommandList ~ NARROW[c.data, Data].head;
RETURN[ReplayListSize[cList]];
};
Memory Context Procs
Bits: TYPE ~ REF BitsRep;
BitsRep: TYPE ~ RECORD [
wordsPerLine, sMin, fMin, sSize, fSize: NAT,
tx, ty: INTEGER,
vm: CountedVM.Handle
];
MakeBits: PROC [base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] RETURNS [bits: Bits] ~ {
nwords: INT ← Basics.LongMult[wordsPerLine, sSize];
vm: CountedVM.Handle ← CountedVM.SimpleAllocate[nwords];
bits ← NEW[BitsRep ← [wordsPerLine, sMin, fMin, sSize, fSize, tx, ty, vm]];
TRUSTED {PrincOpsUtils.LongCopy[from: base, to: vm.pointer, nwords: nwords]}
};
MemoryDoSave: PROC[context: Context, action: PROC, all: BOOL] ~ {
body: CommandList ~ GetBody[context, action];
Append[context, [DoSave [body, all]]];
};
MemorySetInt: PROC[context: Context, key: IntKey, val: INT] ~ {
Append[context, [SetInt [key, val]]];
};
MemorySetReal: PROC[context: Context, key: RealKey, val: REAL] ~ {
Append[context, [SetReal [key, val]]];
};
MemoryGetT: PROC[context: Context] RETURNS[Transformation] ~ {
m: Transformation ← ImagerTransformation.Scale[1.0];
data: Data ~ NARROW[context.data];
IF NOT data.getTDone THEN {
data.getTDone ← TRUE;
IF (data.getTForm ← data.getTForm + 1) = endMemForm THEN data.getTForm ← firstMemForm;
};
m.form ← data.getTForm;
RETURN [m];
};
MemorySetT: PROC[context: Context, m: Transformation] ~ {
Append[context, [SetT [m]]];
};
MemorySetFont: PROC[context: Context, font: Font] ~ {
Append[context, [SetFont [font]]];
};
MemorySetColor: PROC[context: Context, color: Color] ~ {
WITH color SELECT FROM
sampledColor: SampledColor => {
data: Data ~ NARROW[context.data];
IF data.getTDone AND sampledColor.um.form = data.getTForm THEN {
opClass: ATOM ~ ImagerColorOperator.GetColorOperatorClass[sampledColor.colorOperator];
um: Transformation ← ImagerTransformation.Copy[sampledColor.um];
um.form ← 0;
ImagerTransformation.ApplyPreScale[um, 1];
IF opClass = $SampledBlack OR opClass = $SampledBlackClear THEN
MemorySetSampledBlack[context, sampledColor.pa, um, opClass=$SampledBlackClear]
ELSE MemorySetSampledColor[context, sampledColor.pa, um, sampledColor.colorOperator];
RETURN;
};
};
ENDCASE => NULL;
Append[context, [SetColor [color]]];
};
MemorySetClipper: PROC[context: Context, clipper: Clipper] ~ {
Append[context, [SetClipper [clipper]]];
};
MemoryGetInt: PROC[context: Context, key: IntKey] RETURNS[INT] ~ {
Imager.Error[[$unimplemented, "Not implemented"]]};
MemoryGetReal: PROC[context: Context, key: RealKey] RETURNS[REAL] ~ {
Imager.Error[[$unimplemented, "Not implemented"]]};
MemoryGetFont: PROC[context: Context] RETURNS[Font] ~ {
Imager.Error[[$unimplemented, "Not implemented"]]};
MemoryGetColor: PROC[context: Context] RETURNS[Color] ~ {
Imager.Error[[$unimplemented, "Not implemented"]]};
MemoryGetClipper: PROC[context: Context] RETURNS[Clipper] ~ {
Imager.Error[[$unimplemented, "Not implemented"]]};
MemoryConcatT: PROC[context: Context, m: Transformation] ~ {
Append[context, [ConcatT [m]]];
};
MemoryScale2T: PROC[context: Context, s: VEC] ~ {
Append[context, [Scale2T [s]]];
};
MemoryRotateT: PROC[context: Context, a: REAL] ~ {
Append[context, [RotateT [a]]];
};
MemoryTranslateT: PROC[context: Context, t: VEC] ~ {
Append[context, [TranslateT [t]]];
};
MemoryMove: PROC[context: Context, rounded: BOOL] ~ {
Append[context, [Move [rounded]]];
};
MemorySetXY: PROC[context: Context, p: VEC] ~ {
Append[context, [SetXY [p]]];
};
MemorySetXYRel: PROC[context: Context, v: VEC] ~ {
Append[context, [SetXYRel [v]]];
};
MemoryShow: PROC[context: Context, string: XStringProc, xrel: BOOL] ~ {
eightbit: BOOLTRUE;
n: INT ← 0;
CountXChars: ImagerFont.XCharProc ~ {
IF char.set # 0 THEN eightbit ← FALSE;
n ← n+1;
};
InstallXChar: ImagerFont.XCharProc ~ {
xString[n] ← char;
n ← n+1;
};
xString: XStringSeq;
string[CountXChars];  -- Count number of chars fed back, set eightbit
IF eightbit THEN {
text: Rope.Text ~ Rope.NewText[n];
i: NAT ← 0;
InstallChar: ImagerFont.XCharProc ~ {
text[i] ← VAL[char.code];
i ← i+1;
};
text.length ← n;
string[InstallChar];  -- Install each character
Append[context, [ShowShort [text: text, xrel: xrel]]];
}
ELSE {
xString: XStringSeq ~ NEW[XStringSeqRec[n]];
i: INT ← 0;
InstallXChar: ImagerFont.XCharProc ~ {
xString[i] ← char;
i ← i+1;
};
string[InstallXChar];  -- Install each character
Append[context, [Show [string: xString, xrel: xrel]]];
};
};
MemoryShowText: PROC[context: Context, text: REF READONLY TEXT, start, len: NAT, xrel: BOOL] ~ {
class: Class ~ context.class;
string: XStringProc ~ { ImagerFont.MapText[text, start, len, charAction] };
class.Show[context, string, xrel];
};
MemoryStartUnderline: PROC[context: Context] ~ {
Append[context, [StartUnderline []]]};
MemoryMaskUnderline: PROC[context: Context, dy, h: REAL] ~ {
Append[context, [MaskUnderline [dy, h]]];
};
MemoryCorrectMask: PROC[context: Context] ~ {
Append[context, [CorrectMask []]]};
MemoryCorrectSpace: PROC[context: Context, v: VEC] ~ {
Append[context, [CorrectSpace [v]]];
};
MemorySpace: PROC[context: Context, x: REAL] ~ {
Append[context, [Space [x]]];
};
MemorySetCorrectMeasure: PROC[context: Context, v: VEC] ~ {
Append[context, [SetCorrectMeasure [v]]];
};
MemorySetCorrectTolerance: PROC[context: Context, v: VEC] ~ {
Append[context, [SetCorrectTolerance [v]]];
};
MemoryCorrect: PROC[context: Context, action: PROC] ~ {
body: CommandList ~ GetBody[context, action];
Append[context, [Correct [body]]];
};
MemoryDontCorrect: PROC[context: Context, action: PROC, saveCP: BOOL] ~ {
body: CommandList ~ GetBody[context, action];
Append[context, [DontCorrect [body, saveCP]]];
};
MemorySetGray: PROC[context: Context, f: REAL] ~ {
Append[context, [SetGray [f]]];
};
MemorySetSampledColor: PROC[context: Context, pa: PixelArray, m: Transformation, colorOperator: ColorOperator] ~ {
Append[context, [SetSampledColor [NEW[SetSampledColorData ← [pa, m, colorOperator]]]]];
};
MemorySetSampledBlack: PROC[context: Context, pa: PixelArray, m: Transformation, clear: BOOL] ~ {
Append[context, [SetSampledBlack [NEW[SetSampledBlackData ← [pa, m, clear]]]]];
};
MemoryMaskFill: PROC[context: Context, path: PathProc, oddWrap: BOOL] ~ {
pathList: Path ~ GetPath[path];
Append[context, [MaskFill [pathList, oddWrap]]];
};
MemoryMaskRectangle: PROC[context: Context, r: Rectangle] ~ {
Append[context, [MaskRectangle [NEW[Rectangle ← r]]]];
};
MemoryMaskRectangleI: PROC[context: Context, x, y, w, h: INTEGER] ~ {
Append[context, [MaskRectangleI [x, y, w, h]]];
};
MemoryMaskStroke: PROC[context: Context, path: PathProc, closed: BOOL] ~ {
pathList: Path ~ GetPath[path];
Append[context, [MaskStroke [pathList, closed]]];
};
MemoryMaskVector: PROC[context: Context, p1, p2: VEC] ~ {
Append[context, [MaskVector [NEW[ARRAY [0..2) OF VEC ← [p1, p2]]]]];
};
MemoryMaskDashedStroke: PROC[context: Context, path: PathProc,
patternLen: NAT, pattern: PROC [NAT] RETURNS [REAL], offset, length: REAL] ~ {
pathRef: Path ~ GetPath[path];
patternRef: REF PatternSequence ~ GetPattern[patternLen, pattern];
Append[context, [MaskDashedStroke [NEW[MaskDashedStrokeData ← [
path: pathRef, pattern: patternRef, offset: offset, length: length]]]]];
};
MemoryMaskPixel: PROC[context: Context, pa: PixelArray] ~ {
Append[context, [MaskPixel [pa]]];
};
MemoryMaskBits: PROC[context: Context, base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] ~ {
bits: Bits ~ MakeBits[base, wordsPerLine, sMin, fMin, sSize, fSize, tx, ty];
Append[context, [MaskBits [bits]]];
};
MemoryDrawBits: PROC[context: Context, base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] ~ {
bits: Bits ~ MakeBits[base, wordsPerLine, sMin, fMin, sSize, fSize, tx, ty];
Append[context, [DrawBits [bits]]];
};
MemoryClip: PROC[context: Context, path: PathProc, oddWrap: BOOL, exclude: BOOL] ~ {
pathList: Path ~ GetPath[path];
Append[context, [Clip [pathList, oddWrap, exclude]]];
};
MemoryClipRectangle: PROC[context: Context, r: Rectangle, exclude: BOOL] ~ {
Append[context, [ClipRectangle [NEW[Rectangle ← r], exclude]]];
};
MemoryClipRectangleI: PROC[context: Context, x, y, w, h: INTEGER, exclude: BOOL] ~ {
Append[context, [ClipRectangle [NEW[Rectangle ← [x, y, w, h]], exclude]]];
};
MemoryGetCP: PROC[context: Context, rounded: BOOL] RETURNS[VEC] ~ {
Imager.Error[[$unimplemented, "Not implemented"]]};
MemoryGetBoundingRectangle: PROC[context: Context] RETURNS[Rectangle] ~ {
Imager.Error[[$unimplemented, "Not implemented"]]};
memoryClass: Class ~ NEW[ClassRep ← [
type: $Memory,
DoSave: MemoryDoSave,
SetInt: MemorySetInt,
SetReal: MemorySetReal,
SetT: MemorySetT,
SetFont: MemorySetFont,
SetColor: MemorySetColor,
SetClipper: MemorySetClipper,
GetInt: MemoryGetInt,
GetReal: MemoryGetReal,
GetT: MemoryGetT,
GetFont: MemoryGetFont,
GetColor: MemoryGetColor,
GetClipper: MemoryGetClipper,
ConcatT: MemoryConcatT,
Scale2T: MemoryScale2T,
RotateT: MemoryRotateT,
TranslateT: MemoryTranslateT,
Move: MemoryMove,
SetXY: MemorySetXY,
SetXYRel: MemorySetXYRel,
Show: MemoryShow,
ShowText: MemoryShowText,
StartUnderline: MemoryStartUnderline,
MaskUnderline: MemoryMaskUnderline,
CorrectMask: MemoryCorrectMask,
CorrectSpace: MemoryCorrectSpace,
Space: MemorySpace,
SetCorrectMeasure: MemorySetCorrectMeasure,
SetCorrectTolerance: MemorySetCorrectTolerance,
Correct: MemoryCorrect,
DontCorrect: MemoryDontCorrect,
SetGray: MemorySetGray,
SetSampledColor: MemorySetSampledColor,
SetSampledBlack: MemorySetSampledBlack,
MaskFill: MemoryMaskFill,
MaskRectangle: MemoryMaskRectangle,
MaskRectangleI: MemoryMaskRectangleI,
MaskStroke: MemoryMaskStroke,
MaskVector: MemoryMaskVector,
MaskDashedStroke: MemoryMaskDashedStroke,
MaskPixel: MemoryMaskPixel,
MaskBits: MemoryMaskBits,
DrawBits: MemoryDrawBits,
Clip: MemoryClip,
ClipRectangle: MemoryClipRectangle,
ClipRectangleI: MemoryClipRectangleI,
GetCP: MemoryGetCP,
GetBoundingRectangle: MemoryGetBoundingRectangle
]];
END.