ImagerMemoryImpl.mesa
Copyright © 1984, Xerox Corporation. All rights reserved.
Doug Wyatt, December 4, 1984 9:34:48 am PST
Eric Nickell, July 17, 1985 5:03:14 pm PDT
DIRECTORY
Imager, ImagerBackdoor, ImagerFont, ImagerMemory, ImagerPath, ImagerPrivate, PrincOpsUtils, Rope;
ImagerMemoryImpl: CEDAR PROGRAM
IMPORTS Imager, ImagerBackdoor, ImagerPrivate, PrincOpsUtils, Rope
EXPORTS Imager, ImagerMemory
~ BEGIN
OPEN Imager;
IntKey: TYPE ~ ImagerBackdoor.IntKey;
RealKey: TYPE ~ ImagerBackdoor.RealKey;
Clipper: TYPE ~ ImagerBackdoor.Clipper;
StrokeDashes: TYPE ~ ImagerPrivate.StrokeDashes;
Data: TYPE ~ REF DataRep;
DataRep: TYPE ~ RECORD[head, tail: CommandList];
CommandList: TYPE ~ LIST OF Command;
Class: TYPE ~ ImagerPrivate.Class;
ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; --export to Imager
Command: TYPE ~ REF CommandRep;
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],
SetStrokeDashes => [strokeDashes: StrokeDashes],
GetInt => [key: IntKey] RETURNS[INT],
GetReal => [key: RealKey] RETURNS[REAL],
GetT => [] RETURNS[Transformation],
GetFont => [] RETURNS[Font],
GetColor => [] RETURNS[Color],
GetClipper => [] RETURNS[Clipper],
GetStrokeDashes => [] RETURNS[StrokeDashes],
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],
ShowText => [text: REF READONLY TEXT, start, len: NAT, 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 => [pa: PixelArray,
m: Transformation, colorOperator: ColorOperator],
SetSampledBlack => [pa: PixelArray,
m: Transformation, clear: BOOL],
MaskFill => [path: Path, parity: BOOL],
MaskRectangle => [r: Rectangle],
MaskRectangleI => [x, y, w, h: INTEGER],
MaskStroke => [path: Path, closed: BOOL],
MaskVector => [p1, p2: VEC],
MaskPixel => [pa: PixelArray],
MaskBits => [bits: Bits],
DrawBits => [bits: Bits],
Clip => [path: Path, parity: BOOL, exclude: BOOL],
ClipRectangle => [r: Rectangle, exclude: BOOL],
ClipRectangleI => [x, y, w, h: INTEGER, exclude: BOOL]
GetCP => [rounded: BOOL] RETURNS[VEC],
GetBoundingRectangle => [] RETURNS[Rectangle],
ENDCASE
];
XStringSeq: TYPE ~ REF XStringSeqRec;
XStringSeqRec: TYPE ~ RECORD [
SEQUENCE n: CARDINAL OF XChar
];
Path: TYPE ~ LIST OF PathRec;
PathRec: TYPE ~ RECORD [SELECT type: * FROM
move => [p: VEC],
line => [p1: VEC],
curve => [p1, p2, p3: VEC],
conic => [p1, p2: VEC, r: REAL],
arc => [p1, p2: VEC],
dummy => []  --Should never occur after creation
ENDCASE
];
Utility Procedures
DoPath: PROC [path: Path, moveTo: ImagerPath.MoveToProc, lineTo: ImagerPath.LineToProc, curveTo: ImagerPath.CurveToProc, conicTo: ImagerPath.ConicToProc, arcTo: ImagerPath.ArcToProc] ~ {
FOR each: Path ← path, each.rest UNTIL each=NIL DO
WITH each.first SELECT FROM
m: move PathRec => moveTo[m.p];
l: line PathRec => lineTo[l.p1];
cu: curve PathRec => curveTo[cu.p1, cu.p2, cu.p3];
co: conic PathRec => conicTo[co.p1, co.p2, co.r];
arc: arc PathRec => arcTo[arc.p1, arc.p2];
ENDCASE => ERROR;
ENDLOOP;
};
GetPath: PROC [pathProc: PathProc] RETURNS [path: Path] ~ {
AppendToPath: PROC [pathRec: PathRec] ~ {
pathTail ← pathTail.rest ← LIST[pathRec];
};
MoveTo: ImagerPath.MoveToProc ~ {
AppendToPath[[move [p]]]
};
LineTo: ImagerPath.LineToProc ~ {
AppendToPath[[line [p1]]]
};
CurveTo: ImagerPath.CurveToProc ~ {
AppendToPath[[curve [p1, p2, p3]]]
};
ConicTo: ImagerPath.ConicToProc ~ {
AppendToPath[[conic [p1, p2, r]]]
};
ArcTo: ImagerPath.ArcToProc ~ {
AppendToPath[[arc [p1, p2]]]
};
pathTail: Path ← path ← LIST[[dummy []]];
pathProc[MoveTo, LineTo, CurveTo, ConicTo, ArcTo];
path ← path.rest;  --Drop the dummy record
};
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[data: Data, command: CommandRep] ~ {
tail: CommandList ~ LIST[NEW[CommandRep ← command]];
IF data.tail=NIL THEN data.head ← tail ELSE data.tail.rest ← tail;
data.tail ← tail;
};
ReplayList: PROC [cList: CommandList, into: Context] ~ {
FOR each: CommandList ← cList, each.rest UNTIL each=NIL DO
WITH each.first^ SELECT FROM
cmd: DoSave CommandRep => {
Action: PROC ~ {
ReplayList[cmd.body, into];
};
IF cmd.all THEN Imager.DoSaveAll[into, Action] ELSE Imager.DoSave[into, Action];
};
cmd: SetInt CommandRep => ImagerBackdoor.SetInt[into, cmd.key, cmd.val];
cmd: SetReal CommandRep => ImagerBackdoor.SetReal[into, cmd.key, cmd.val];
cmd: SetT CommandRep => ImagerBackdoor.SetT[into, cmd.m];
cmd: SetFont CommandRep => Imager.SetFont[into, cmd.font];
cmd: SetColor CommandRep => Imager.SetColor[into, cmd.color];
cmd: SetClipper CommandRep => ImagerBackdoor.SetClipper[into, cmd.clipper];
cmd: SetStrokeDashes CommandRep => ImagerPrivate.SetStrokeDashes[into, cmd.strokeDashes];
cmd: ConcatT CommandRep => Imager.ConcatT[into, cmd.m];
cmd: Scale2T CommandRep => Imager.Scale2T[into, cmd.s];
cmd: RotateT CommandRep => Imager.RotateT[into, cmd.a];
cmd: TranslateT CommandRep => Imager.TranslateT[into, cmd.t];
cmd: Move CommandRep => {
IF cmd.rounded THEN Imager.Trans[into] ELSE Imager.Move[into];
};
cmd: SetXY CommandRep => Imager.SetXY[into, cmd.p];
cmd: SetXYRel CommandRep => Imager.SetXYRel[into, cmd.v];
cmd: Show CommandRep => {
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];
};
cmd: ShowText CommandRep => Imager.ShowText[into, cmd.text, cmd.start, cmd.len, cmd.xrel];
cmd: StartUnderline CommandRep => Imager.StartUnderline[into];
cmd: MaskUnderline CommandRep => Imager.MaskUnderline[into, cmd.dy, cmd.h];
cmd: CorrectMask CommandRep => Imager.CorrectMask[into];
cmd: CorrectSpace CommandRep => Imager.CorrectSpace[into, cmd.v];
cmd: Space CommandRep => Imager.Space[into, cmd.x];
cmd: SetCorrectMeasure CommandRep => Imager.SetCorrectMeasure[into, cmd.v];
cmd: SetCorrectTolerance CommandRep => Imager.SetCorrectTolerance[into, cmd.v];
cmd: Correct CommandRep => {
Action: PROC ~ {
ReplayList[cmd.body, into];
};
Imager.Correct[into, Action];
};
cmd: DontCorrect CommandRep => {
Action: PROC ~ {
ReplayList[cmd.body, into];
};
Imager.DontCorrect[into, Action, cmd.saveCP];
};
cmd: SetGray CommandRep => Imager.SetGray[into, cmd.f];
cmd: SetSampledColor CommandRep => Imager.SetSampledColor[into, cmd.pa, cmd.
m, cmd.colorOperator];
cmd: SetSampledBlack CommandRep => Imager.SetSampledBlack[into, cmd.pa, cmd.
m, cmd.clear];
cmd: MaskFill CommandRep => {
PathProc: Imager.PathProc ~ {
DoPath[cmd.path, moveTo, lineTo, curveTo, conicTo, arcTo];
};
Imager.MaskFill[into, PathProc, cmd.parity];
};
cmd: MaskRectangle CommandRep => Imager.MaskRectangle[into, cmd.r];
cmd: MaskRectangleI CommandRep => Imager.MaskRectangleI[into, cmd.x, cmd.y, cmd.w, cmd.h];
cmd: MaskStroke CommandRep => {
PathProc: Imager.PathProc ~ {
DoPath[cmd.path, moveTo, lineTo, curveTo, conicTo, arcTo];
};
Imager.MaskStroke[into, PathProc, cmd.closed];
};
cmd: MaskVector CommandRep => Imager.MaskVector[into, cmd.p1, cmd.p2];
cmd: MaskPixel CommandRep => Imager.MaskPixel[into, cmd.pa];
cmd: MaskBits CommandRep => Imager.MaskBits[into, LOOPHOLE[cmd.bits.data], cmd.bits.wordsPerLine, cmd.bits.sMin, cmd.bits.fMin, cmd.bits.sSize, cmd.bits.fSize, cmd.bits.tx, cmd.bits.ty];
cmd: DrawBits CommandRep => ImagerBackdoor.DrawBits[into, LOOPHOLE[cmd.bits.data], cmd.bits.wordsPerLine, cmd.bits.sMin, cmd.bits.fMin, cmd.bits.sSize, cmd.bits.fSize, cmd.bits.tx, cmd.bits.ty];
cmd: Clip CommandRep => {
PathProc: Imager.PathProc ~ {
DoPath[cmd.path, moveTo, lineTo, curveTo, conicTo, arcTo];
};
Imager.Clip[into, PathProc, cmd.parity, cmd.exclude];
};
cmd: ClipRectangle CommandRep => Imager.ClipRectangle[into, cmd.r, cmd.exclude];
cmd: ClipRectangleI CommandRep => Imager.ClipRectangleI[into, cmd.x, cmd.y, cmd.w, cmd.h, cmd.exclude];
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];
};
Memory Context Procs
Bits: TYPE ~ RECORD [
wordsPerLine, sMin, fMin, sSize, fSize: NAT,
tx, ty: INTEGER,
data: REF BitsData
];
BitsData: TYPE ~ RECORD [SEQUENCE size: CARDINAL OF WORD];
MakeBits: PROC [base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] RETURNS [bits: Bits] ~ {
bits ← [wordsPerLine, sMin, fMin, sSize, fSize, tx, ty, NEW[BitsData[wordsPerLine*sSize]]];
TRUSTED {PrincOpsUtils.LongCopy[from: base, to: LOOPHOLE[bits.data], nwords: wordsPerLine*sSize];}
};
MemoryDoSave: PROC[context: Context, action: PROC, all: BOOL] ~ {
body: CommandList ~ GetBody[context, action];
Append[NARROW[context.data], [DoSave [body, all]]];
};
MemorySetInt: PROC[context: Context, key: IntKey, val: INT] ~ {
Append[NARROW[context.data], [SetInt [key, val]]];
};
MemorySetReal: PROC[context: Context, key: RealKey, val: REAL] ~ {
Append[NARROW[context.data], [SetReal [key, val]]];
};
MemorySetT: PROC[context: Context, m: Transformation] ~ {
Append[NARROW[context.data], [SetT [m]]];
};
MemorySetFont: PROC[context: Context, font: Font] ~ {
Append[NARROW[context.data], [SetFont [font]]];
};
MemorySetColor: PROC[context: Context, color: Color] ~ {
Append[NARROW[context.data], [SetColor [color]]];
};
MemorySetClipper: PROC[context: Context, clipper: Clipper] ~ {
Append[NARROW[context.data], [SetClipper [clipper]]];
};
MemorySetStrokeDashes: PROC[context: Context, strokeDashes: StrokeDashes] ~ {
Append[NARROW[context.data], [SetStrokeDashes [strokeDashes]]];
};
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"]]};
MemoryGetT: PROC[context: Context] RETURNS[Transformation] ~ {
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"]]};
MemoryGetStrokeDashes: PROC[context: Context] RETURNS[StrokeDashes] ~ {
Imager.Error[[$unimplemented, "Not implemented"]]};
MemoryConcatT: PROC[context: Context, m: Transformation] ~ {
Append[NARROW[context.data], [ConcatT [m]]];
};
MemoryScale2T: PROC[context: Context, s: VEC] ~ {
Append[NARROW[context.data], [Scale2T [s]]];
};
MemoryRotateT: PROC[context: Context, a: REAL] ~ {
Append[NARROW[context.data], [RotateT [a]]];
};
MemoryTranslateT: PROC[context: Context, t: VEC] ~ {
Append[NARROW[context.data], [TranslateT [t]]];
};
MemoryMove: PROC[context: Context, rounded: BOOL] ~ {
Append[NARROW[context.data], [Move [rounded]]];
};
MemorySetXY: PROC[context: Context, p: VEC] ~ {
Append[NARROW[context.data], [SetXY [p]]];
};
MemorySetXYRel: PROC[context: Context, v: VEC] ~ {
Append[NARROW[context.data], [SetXYRel [v]]];
};
MemoryShow: PROC[context: Context, string: XStringProc, xrel: BOOL] ~ {
CountXChars: ImagerFont.XCharProc ~ {
n ← n+1;
};
InstallXChar: ImagerFont.XCharProc ~ {
xString[n] ← char;
n ← n+1;
};
xString: XStringSeq;
n: INT ← 0;
string[CountXChars];  --Count number of chars fed back
xString ← NEW[XStringSeqRec[n]];
n ← 0;
string[InstallXChar];  --Install each character
Append[NARROW[context.data], [Show [string: xString, xrel: xrel]]];
};
MemoryShowText: PROC[context: Context, text: REF READONLY TEXT, start, len: NAT, xrel: BOOL] ~ {
newText: REF TEXT ~ Rope.ToRefText[Rope.FromRefText[text]];
Append[NARROW[context.data], [ShowText [newText, start, len, xrel]]];
};
MemoryStartUnderline: PROC[context: Context] ~ {
Append[NARROW[context.data], [StartUnderline []]]};
MemoryMaskUnderline: PROC[context: Context, dy, h: REAL] ~ {
Append[NARROW[context.data], [MaskUnderline [dy, h]]];
};
MemoryCorrectMask: PROC[context: Context] ~ {
Append[NARROW[context.data], [CorrectMask []]]};
MemoryCorrectSpace: PROC[context: Context, v: VEC] ~ {
Append[NARROW[context.data], [CorrectSpace [v]]];
};
MemorySpace: PROC[context: Context, x: REAL] ~ {
Append[NARROW[context.data], [Space [x]]];
};
MemorySetCorrectMeasure: PROC[context: Context, v: VEC] ~ {
Append[NARROW[context.data], [SetCorrectMeasure [v]]];
};
MemorySetCorrectTolerance: PROC[context: Context, v: VEC] ~ {
Append[NARROW[context.data], [SetCorrectTolerance [v]]];
};
MemoryCorrect: PROC[context: Context, action: PROC] ~ {
body: CommandList ~ GetBody[context, action];
Append[NARROW[context.data], [Correct [body]]];
};
MemoryDontCorrect: PROC[context: Context, action: PROC, saveCP: BOOL] ~ {
body: CommandList ~ GetBody[context, action];
Append[NARROW[context.data], [DontCorrect [body, saveCP]]];
};
MemorySetGray: PROC[context: Context, f: REAL] ~ {
Append[NARROW[context.data], [SetGray [f]]];
};
MemorySetSampledColor: PROC[context: Context, pa: PixelArray, m: Transformation, colorOperator: ColorOperator] ~ {
Append[NARROW[context.data], [SetSampledColor [pa, m, colorOperator]]];
};
MemorySetSampledBlack: PROC[context: Context, pa: PixelArray, m: Transformation, clear: BOOL] ~ {
Append[NARROW[context.data], [SetSampledBlack [pa, m, clear]]];
};
MemoryMaskFill: PROC[context: Context, path: PathProc, parity: BOOL] ~ {
pathList: Path ~ GetPath[path];
Append[NARROW[context.data], [MaskFill [pathList, parity]]];
};
MemoryMaskRectangle: PROC[context: Context, r: Rectangle] ~ {
Append[NARROW[context.data], [MaskRectangle [r]]];
};
MemoryMaskRectangleI: PROC[context: Context, x, y, w, h: INTEGER] ~ {
Append[NARROW[context.data], [MaskRectangleI [x, y, w, h]]];
};
MemoryMaskStroke: PROC[context: Context, path: PathProc, closed: BOOL] ~ {
pathList: Path ~ GetPath[path];
Append[NARROW[context.data], [MaskStroke [pathList, closed]]];
};
MemoryMaskVector: PROC[context: Context, p1, p2: VEC] ~ {
Append[NARROW[context.data], [MaskVector [p1, p2]]];
};
MemoryMaskPixel: PROC[context: Context, pa: PixelArray] ~ {
Append[NARROW[context.data], [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[NARROW[context.data], [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[NARROW[context.data], [DrawBits [bits]]];
};
MemoryClip: PROC[context: Context, path: PathProc, parity: BOOL, exclude: BOOL] ~ {
pathList: Path ~ GetPath[path];
Append[NARROW[context.data], [Clip [pathList, parity, exclude]]];
};
MemoryClipRectangle: PROC[context: Context, r: Rectangle, exclude: BOOL] ~ {
Append[NARROW[context.data], [ClipRectangle [r, exclude]]];
};
MemoryClipRectangleI: PROC[context: Context, x, y, w, h: INTEGER, exclude: BOOL] ~ {
Append[NARROW[context.data], [ClipRectangleI [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,
SetStrokeDashes: MemorySetStrokeDashes,
GetInt: MemoryGetInt,
GetReal: MemoryGetReal,
GetT: MemoryGetT,
GetFont: MemoryGetFont,
GetColor: MemoryGetColor,
GetClipper: MemoryGetClipper,
GetStrokeDashes: MemoryGetStrokeDashes,
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,
MaskPixel: MemoryMaskPixel,
MaskBits: MemoryMaskBits,
DrawBits: MemoryDrawBits,
Clip: MemoryClip,
ClipRectangle: MemoryClipRectangle,
ClipRectangleI: MemoryClipRectangleI,
GetCP: MemoryGetCP,
GetBoundingRectangle: MemoryGetBoundingRectangle
]];
ImagerPrivate.RegisterDevice[interpressClass];
END.