ImagerImpl.mesa
Michael Plass, October 27, 1983 3:33 pm
Doug Wyatt, October 11, 1983 3:59 pm
Last Edited by: Stone, December 20, 1983 3:18 pm
DIRECTORY
Atom USING [GetProp, PutProp],
Font USING [CreateScaled],
Imager USING [Context, ContextRep, defaultStrokeEnd, defaultStrokeWidth, Error, ErrorCode, FONT, Outline, OutlineRep, Polygon, RopeOrRefText, Trajectory, TrajectoryRep],
ImagerBasic USING [Color, ColorRep, ConstantColor, IntPair, IntRectangle, Pair, PathMapType, PixelArray, StrokeEnd, Transformation, Visibility],
ImagerConic,
ImagerPrivate USING [Class],
ImagerTransform USING [Scale],
Real USING [RoundLI],
Rope USING [ROPE]
;
ImagerImpl: CEDAR PROGRAM
IMPORTS Atom, Font, Imager, ImagerConic, ImagerTransform, Real
EXPORTS Imager, ImagerPrivate
= BEGIN OPEN Imager, ImagerBasic;
Types
Class: TYPE = ImagerPrivate.Class;
Errors
Error: PUBLIC ERROR [errorCode: ErrorCode] ~ CODE;
Creation
imagerRegistrationKey: ATOM ~ $ImagerDeviceClass;
RegisterDevice: PUBLIC PROC [class: ImagerPrivate.Class] ~ {
Atom.PutProp[class.deviceType, imagerRegistrationKey, class];
};
Create: PUBLIC PROC[deviceType: ATOM, data: REF] RETURNS [context: Context] ~ {
WITH Atom.GetProp[deviceType, imagerRegistrationKey] SELECT FROM
class: Class => {
context ← NEW[ContextRep ← [class: class, data: NIL]];
class.Init[context, data];
};
ENDCASE => ERROR UnimplementedDevice;
};
UnimplementedDevice: PUBLIC ERROR = CODE;
Imager state
Here are all the imager variables, with their types and initial values:
Persistent:
cpx, cpy: REAL ← 0
correctMX, correctMY: REAL ← 0
Non-persistent:
T: Transformation ← identityTransformation
priorityImportant: BOOLFALSE
mediumXSize, mediumYSize: REAL ← 0
fieldXMin, fieldYMin: REAL ← 0
fieldXMax, fieldYMax: REAL ← 0
showVec: Vector ← emptyVector
color: Color ← black
noImage: BOOLFALSE
strokeWidth: REAL ← 0
strokeEnd: StrokeEnd ← square
underlineStart: REAL ← 0
amplifySpace: REAL ← 1
correctPass: [0..2] ← 0
correctShrink: REAL ← 0.5
correctTX, correctTY: REAL ← 0
clipOutline: Outline ← FullField[]
DoSave: PUBLIC PROC[context: Context, body: PROC] = {
class: Class = NARROW[context.class];
class.DoSave[context, body];
};
DoSaveAll: PUBLIC PROC[context: Context, body: PROC] = {
class: Class = NARROW[context.class];
class.DoSaveAll[context, body];
};
SetPriorityImportant: PUBLIC PROC[context: Context, priorityImportant: BOOL] = {
class: Class = NARROW[context.class];
class.ISetInt[context, $priorityImportant, IF priorityImportant THEN 1 ELSE 0];
};
Transformations
Scale: PROC[s: REAL] RETURNS[Transformation] = { RETURN[ImagerTransform.Scale[s, s]] };
pointsToMeters: PUBLIC Transformation ← Scale[0.0254/72.27];
micasToMeters: PUBLIC Transformation ← Scale[0.00001];
ConcatT: PUBLIC PROC[context: Context, m: Transformation] = {
class: Class = NARROW[context.class];
class.ConcatT[context, m];
};
TranslateT: PUBLIC PROC[context: Context, x, y: REAL] = {
class: Class = NARROW[context.class];
class.TranslateT[context, x, y];
};
RotateT: PUBLIC PROC[context: Context, a: REAL] = {
class: Class = NARROW[context.class];
class.RotateT[context, a];
};
ScaleT: PUBLIC PROC[context: Context, s: REAL] = {
class: Class = NARROW[context.class];
class.ScaleT[context, s];
};
Scale2T: PUBLIC PROC[context: Context, sx, sy: REAL] = {
class: Class = NARROW[context.class];
class.Scale2T[context, sx, sy];
};
Move: PUBLIC PROC[context: Context] = {
class: Class = NARROW[context.class];
class.Move[context];
};
Trans: PUBLIC PROC[context: Context] = {
class: Class = NARROW[context.class];
class.Trans[context];
};
Current position operators
SetXY: PUBLIC PROC[context: Context, p: Pair] = {
class: Class = NARROW[context.class];
class.SetXY[context, p];
};
IntegerSetXY: PUBLIC PROC[context: Context, x, y: INTEGER] = {
class: Class = NARROW[context.class];
class.IntegerSetXY[context, x, y];
};
SetXYRel: PUBLIC PROC[context: Context, v: Pair] = {
class: Class = NARROW[context.class];
class.SetXYRel[context, v];
};
IntegerSetXYRel: PUBLIC PROC[context: Context, x, y: INTEGER] = {
class: Class = NARROW[context.class];
class.IntegerSetXYRel[context, x, y];
};
SetXRel: PUBLIC PROC[context: Context, x: REAL] = {
class: Class = NARROW[context.class];
class.SetXYRel[context, [x, 0]];
};
IntegerSetXRel: PUBLIC PROC[context: Context, x: INTEGER] = {
class: Class = NARROW[context.class];
class.IntegerSetXYRel[context, x, 0];
};
SetYRel: PUBLIC PROC[context: Context, y: REAL] = {
class: Class = NARROW[context.class];
class.SetXYRel[context, [0, y]];
};
IntegerSetYRel: PUBLIC PROC[context: Context, y: INTEGER] = {
class: Class = NARROW[context.class];
class.IntegerSetXYRel[context, 0, y];
};
Color
Card: PROC [real: REAL] RETURNS [card: CARDINAL] ~ {
int: INT ← Real.RoundLI[real*LAST[CARDINAL]];
card ← MAX[MIN[int, LAST[CARDINAL]], 0];
};
MakeGray: PUBLIC PROC[f: REAL] RETURNS[ConstantColor] = {
IF f<0 OR f>1 THEN ERROR;
RETURN[NEW[ColorRep[constant] ←
[constant[x: Card[0.3101], y: Card[0.3163], Y: Card[1-f]]]]];
};
black: PUBLIC ConstantColor ← MakeGray[1];
white: PUBLIC ConstantColor ← MakeGray[0];
SetColor: PUBLIC PROC[context: Context, color: Color] = {
class: Class = NARROW[context.class];
class.ISet[context, $color, color];
};
Mask operators
TrajectoryRep: TYPE = PRIVATE RECORD[
prev: Trajectory, -- trajectory preceding this segment
lp: Pair, -- the last point
variant: SELECT tag: * FROM
move => [], -- begin new trajectory at lp
line => [], -- straight line segment, endpoints [prev.lp, lp]
curve => [p1, p2: Pair], -- cubic curve segment, Bezier control points [prev.lp, p1, p2, lp]
conic => [p1: Pair, r: REAL], -- conic section segment; see Full Interpress
ENDCASE
];
LastPoint: PUBLIC PROC[t: Trajectory] RETURNS[Pair] = {
RETURN[t.lp];
};
MoveTo: PUBLIC PROC[p: Pair] RETURNS[Trajectory] = {
RETURN[NEW[TrajectoryRep[move] ← [prev: NIL, lp: p, variant: move[]]]];
};
LineTo: PUBLIC PROC[t: Trajectory, p: Pair] RETURNS[Trajectory] = {
RETURN[NEW[TrajectoryRep[line] ← [prev: t, lp: p, variant: line[]]]];
};
LineToX: PUBLIC PROC[t: Trajectory, x: REAL] RETURNS[Trajectory] = {
RETURN[NEW[TrajectoryRep[line] ← [prev: t, lp: [x, t.lp.y], variant: line[]]]];
};
LineToY: PUBLIC PROC[t: Trajectory, y: REAL] RETURNS[Trajectory] = {
RETURN[NEW[TrajectoryRep[line] ← [prev: t, lp: [t.lp.x, y], variant: line[]]]];
};
CurveTo: PUBLIC PROC[t: Trajectory, p1, p2, p3: Pair] RETURNS[Trajectory] = {
RETURN[NEW[TrajectoryRep[curve] ← [prev: t, lp: p3, variant: curve[p1, p2]]]];
};
ConicTo: PUBLIC PROC[t: Trajectory, p1, p2: Pair, r: REAL] RETURNS[Trajectory] = {
RETURN[NEW[TrajectoryRep[conic] ← [prev: t, lp: p2, variant: conic[p1, r]]]];
};
ArcTo: PUBLIC PROC[t: Trajectory, p1, p2: Pair] RETURNS[Trajectory] = {
conic: PROC[p1, p2: Pair, r: REAL] ~ {t ← ConicTo[t, p1, p2, r]};
ImagerConic.FromArc[LastPoint[t], p1, p2, conic];
RETURN [t]
};
MakeOutline: PUBLIC PROC[list: LIST OF Trajectory] RETURNS[Outline] = {
RETURN[NEW[OutlineRep ← [list]]];
};
MapTrajectory: PathMapType = {
t: Trajectory = NARROW[data];
move[t.lp];
FOR x: Trajectory ← t, x.prev UNTIL x.prev=NIL DO
p0: Pair = x.prev.lp;
WITH x SELECT FROM
x: REF TrajectoryRep[line] => line[p0];
x: REF TrajectoryRep[curve] => curve[x.p2, x.p1, p0];
x: REF TrajectoryRep[conic] => conic[x.p1, p0, x.r];
x: REF TrajectoryRep[move] => ERROR;
ENDCASE => ERROR;
ENDLOOP;
};
MapTrajectoryList: PathMapType = {
FOR x: LIST OF Trajectory ← NARROW[data], x.rest UNTIL x=NIL DO
MapTrajectory[x.first, move, line, curve, conic]
ENDLOOP;
};
MapPolygon: PathMapType = {
p: Polygon = NARROW[data];
IF p.length>0 THEN {
move[p[0]];
FOR i: NAT IN[1..MIN[p.length, p.maxLength]) DO line[p[i]] ENDLOOP;
};
};
MaskFill: PUBLIC PROC[context: Context, outline: REF] = {
class: Class = NARROW[context.class];
WITH outline SELECT FROM
o: Outline => class.MaskFill[context, MapTrajectoryList, o.list];
list: LIST OF Trajectory => class.MaskFill[context, MapTrajectoryList, list];
t: Trajectory => class.MaskFill[context, MapTrajectory, t];
p: Polygon => class.MaskFill[context, MapPolygon, p];
ENDCASE => ERROR;
};
SetStrokeWidth: PUBLIC PROC[context: Context, strokeWidth: REAL] = {
class: Class = NARROW[context.class];
class.ISetReal[context, $strokeWidth, strokeWidth];
};
SetStrokeEnd: PUBLIC PROC[context: Context, strokeEnd: StrokeEnd] = {
class: Class = NARROW[context.class];
class.ISetInt[context, $strokeEnd, SELECT strokeEnd FROM
square => 0, butt => 1, round => 2, ENDCASE => ERROR];
};
MaskStroke: PUBLIC PROC[context: Context, t: Trajectory,
strokeWidth: REAL ← defaultStrokeWidth, strokeEnd: StrokeEnd ← defaultStrokeEnd] = {
class: Class = NARROW[context.class];
class.MaskStroke[context, MapTrajectory, t, strokeWidth, strokeEnd];
};
MaskStrokeClosed: PUBLIC PROC[context: Context, t: Trajectory,
strokeWidth: REAL ← defaultStrokeWidth] = {
class: Class = NARROW[context.class];
class.MaskStrokeClosed[context, MapTrajectory, t, strokeWidth];
};
MaskVector: PUBLIC PROC[context: Context, p1, p2: Pair,
strokeWidth: REAL ← defaultStrokeWidth, strokeEnd: StrokeEnd ← defaultStrokeEnd] = {
class: Class = NARROW[context.class];
IF strokeWidth=defaultStrokeWidth AND strokeEnd=defaultStrokeEnd THEN
class.MaskVector[context, p1.x, p1.y, p2.x, p2.y]
ELSE {
MapVector: PathMapType = { move[p1]; line[p2] };
class.MaskStroke[context, MapVector, NIL, strokeWidth, strokeEnd];
};
};
MaskRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] = {
class: Class = NARROW[context.class];
class.MaskRectangle[context, x, y, w, h];
};
IntegerMaskRectangle: PUBLIC PROC[context: Context, x, y, w, h: INTEGER] = {
class: Class = NARROW[context.class];
class.IntegerMaskRectangle[context, x, y, w, h];
};
StartUnderline: PUBLIC PROC[context: Context] = {
class: Class = NARROW[context.class];
class.StartUnderline[context];
};
MaskUnderline: PUBLIC PROC[context: Context, dy, h: REAL] = {
class: Class = NARROW[context.class];
class.MaskUnderline[context, dy, h];
};
IntegerMaskUnderline: PUBLIC PROC[context: Context, dy, h: INTEGER] = {
class: Class = NARROW[context.class];
class.IntegerMaskUnderline[context, dy, h];
};
MaskPixel: PUBLIC PROC[context: Context, pa: PixelArray] = {
class: Class = NARROW[context.class];
class.MaskPixel[context, pa];
};
ClipOutline: PUBLIC PROC[context: Context, outline: REF] = {
class: Class = NARROW[context.class];
WITH outline SELECT FROM
o: Outline => class.ClipOutline[context, MapTrajectoryList, o.list];
list: LIST OF Trajectory => class.ClipOutline[context, MapTrajectoryList, list];
t: Trajectory => class.ClipOutline[context, MapTrajectory, t];
p: Polygon => class.ClipOutline[context, MapPolygon, p];
ENDCASE => ERROR Imager.Error[$UnknownType];
};
ExcludeOutline: PUBLIC PROC[context: Context, outline: REF] = {
class: Class = NARROW[context.class];
WITH outline SELECT FROM
o: Outline => class.ExcludeOutline[context, MapTrajectoryList, o.list];
list: LIST OF Trajectory => class.ExcludeOutline[context, MapTrajectoryList, list];
t: Trajectory => class.ExcludeOutline[context, MapTrajectory, t];
p: Polygon => class.ExcludeOutline[context, MapPolygon, p];
ENDCASE => ERROR Imager.Error[$UnknownType];
};
ClipRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] = {
class: Class = NARROW[context.class];
class.ClipRectangle[context, x, y, w, h];
};
ExcludeRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] = {
class: Class = NARROW[context.class];
class.ExcludeRectangle[context, x, y, w, h];
};
IntegerClipRectangle: PUBLIC PROC[context: Context, x, y, w, h: INTEGER] = {
class: Class = NARROW[context.class];
class.IntegerClipRectangle[context, x, y, w, h];
};
IntegerExcludeRectangle: PUBLIC PROC[context: Context, x, y, w, h: INTEGER] = {
class: Class = NARROW[context.class];
class.IntegerExcludeRectangle[context, x, y, w, h];
};
Character operators
MakeFont: PUBLIC PROC[name: Rope.ROPE, size: REAL] RETURNS[FONT] = {
RETURN[Font.CreateScaled[name, size]];
};
SetFont: PUBLIC PROC[context: Context, font: FONT] = {
class: Class = NARROW[context.class];
class.ISet[context, $showVec, font];
};
ShowChar: PUBLIC PROC[context: Context, char: CHAR, font: FONTNIL] = {
class: Class = NARROW[context.class];
class.ShowChar[context, char, font];
};
ShowCharacters: PUBLIC PROC[context: Context, characters: RopeOrRefText, font: FONTNIL,
start: INT ← 0, length: INTLAST[INT]] = {
class: Class = NARROW[context.class];
class.ShowCharacters[context, characters, font, start, length];
};
SetAmplifySpace: PUBLIC PROC[context: Context, amplifySpace: REAL] = {
class: Class = NARROW[context.class];
class.ISetReal[context, $amplifySpace, amplifySpace];
};
Spacing correction
CorrectMask: PUBLIC PROC[context: Context] = {
class: Class = NARROW[context.class];
class.CorrectMask[context];
};
CorrectSpace: PUBLIC PROC[context: Context, v: Pair] = {
class: Class = NARROW[context.class];
class.CorrectSpace[context, v];
};
Correct: PUBLIC PROC[context: Context, body: PROC] = {
class: Class = NARROW[context.class];
class.Correct[context, body];
};
SetCorrectMeasure: PUBLIC PROC[context: Context, v: Pair] = {
class: Class = NARROW[context.class];
class.SetCorrectMeasure[context, v];
};
SetCorrectTolerance: PUBLIC PROC[context: Context, v: Pair] = {
class: Class = NARROW[context.class];
class.SetCorrectTolerance[context, v];
};
SetCorrectShrink: PUBLIC PROC[context: Context, correctShrink: REAL] = {
class: Class = NARROW[context.class];
class.ISetReal[context, $correctShrink, correctShrink];
};
Space: PUBLIC PROC[context: Context, x: REAL] = {
class: Class = NARROW[context.class];
class.Space[context, x];
};
IntegerSpace: PUBLIC PROC[context: Context, x: INTEGER] = {
class: Class = NARROW[context.class];
class.IntegerSpace[context, x];
};
*** Remaining warts ***
Reset: PUBLIC PROC[context: Context] = {
class: Class = NARROW[context.class];
class.Reset[context];
};
SetView: PUBLIC PROC[context: Context, box: IntRectangle, halftoneOrigin: IntPair] = {
class: Class = NARROW[context.class];
class.SetView[context, box, halftoneOrigin];
};
ClipView: PUBLIC PROC[context: Context, box: IntRectangle, exclude: BOOL] = {
class: Class = NARROW[context.class];
class.ClipView[context, box, exclude];
};
DrawBitmap: PUBLIC PROC[context: Context, base: LONG POINTER, raster: CARDINAL, area: IntRectangle] = {
class: Class = NARROW[context.class];
class.DrawBitmap[context, base, raster, area];
};
MaskBits: PUBLIC PROC[context: Context, base: LONG POINTER, raster: CARDINAL, tile: IntRectangle, area: IntRectangle] = {
class: Class = NARROW[context.class];
class.MaskBits[context, base, raster, tile, area];
};
MoveSurfaceRectangle: PUBLIC PROC[context: Context, source: IntRectangle, dest: IntPair] = {
class: Class = NARROW[context.class];
class.MoveSurfaceRectangle[context, source, dest];
};
XOR: PUBLIC Color ← NEW[ImagerBasic.ColorRep[special] ← [special[$XOR]]];
MakeStipple: PUBLIC PROC[stipple: CARDINAL] RETURNS[Color] = {
ref: REF CARDINAL = NEW[CARDINAL ← stipple];
RETURN[NEW[ImagerBasic.ColorRep[special] ← [special[ref]]]]
};
TestRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] RETURNS[Visibility] = {
class: Class = NARROW[context.class];
RETURN[class.TestRectangle[context, x, y, w, h]];
};
GetSurfaceBounds: PUBLIC PROC[context: Context] RETURNS[IntRectangle] = {
class: Class = NARROW[context.class];
RETURN[class.GetSurfaceBounds[context]];
};
GetViewBounds: PUBLIC PROC[context: Context] RETURNS[IntRectangle] = {
class: Class = NARROW[context.class];
RETURN[class.GetViewBounds[context]];
};
SpecialOp: PUBLIC PROC[context: Context, op: ATOM, data: REF] RETURNS[REF] = {
class: Class = NARROW[context.class];
RETURN[class.SpecialOp[context, op, data]];
};
END.