Imager.mesa
Copyright © 1984 Xerox Corporation. All rights reserved.
Michael Plass, February 20, 1984 9:15:15 am PST
Doug Wyatt, November 29, 1984 2:48:07 pm PST
The Imager provides a rich set of facilities for creating two-dimensional images on a variety of devices; images can be specified in a way that is independent of any particular imaging device.
DIRECTORY
ImagerColor USING [Color, ColorOperator],
ImagerFont USING [Char, CharSet, Font],
ImagerPath USING [Clipper, PathProc],
ImagerPixelArray USING [PixelArray],
ImagerTransformation USING [Transformation],
Prop USING [PropList],
Rope USING [ROPE],
Vector2 USING [VEC];
Imager: CEDAR DEFINITIONS
~ BEGIN
Types
Context: TYPE ~ REF ContextRep;
ContextRep: TYPE ~ RECORD[
class: Class, -- procedures for the context class
data: REF, -- instance data (class-dependent)
props: Prop.PropList -- instance property list
];
VEC: TYPE ~ Vector2.VEC;
Transformation: TYPE ~ ImagerTransformation.Transformation;
PathProc: TYPE ~ ImagerPath.PathProc;
Clipper: TYPE ~ ImagerPath.Clipper;
PixelArray: TYPE ~ ImagerPixelArray.PixelArray;
Color: TYPE ~ ImagerColor.Color;
ColorOperator: TYPE ~ ImagerColor.ColorOperator;
Char: TYPE ~ ImagerFont.Char;
CharSet: TYPE ~ ImagerFont.CharSet;
Font: TYPE ~ ImagerFont.Font;
ROPE: TYPE ~ Rope.ROPE;
Imager variables
DoSave: PROC[context: Context, action: PROC];
DoSaveAll: PROC[context: Context, action: PROC];
Call the "action" procedure, then restore imager variables to their state prior to the call.
DoSave preserves changes to the "persistent" imager variables, cp and correctMeasure.
DoSaveAll saves and restores all imager variables.
PutProp: PROC[context: Context, key: REF, value: REF];
Puts a key-value pair on the context's property list.
GetProp: PROC[context: Context, key: REF] RETURNS[value: REF];
Looks for key on the context's property list and returns the corresponding value.
Uses REF equality to compare keys. Returns NIL if key is not found.
RemProp: PROC[context: Context, key: REF];
Looks for key on the context's property list and removes the key-value pair.
Uses REF equality to compare keys. No effect if key is not found.
Errors
Error: ERROR[errorCode: ErrorCode];
ErrorCode: TYPE ~ {
Bug, -- detected an internal inconsistency
Unimplemented, -- operation not provided for this context
NotYetImplemented, -- part of the Imager implementation is incomplete
UnknownSpecialColor, -- unrecognized atom for a special Color
GrayParameterOutOfRange -- for SetGray or MakeGray, f<0 or f>1
};
Transformations
ConcatT: PROC[context: Context, m: Transformation];
Premultiplies the current transformation by m.
metersPerInch: REAL ~ 0.0254;
metersPerPoint: REAL ~ 0.00035146;
metersPerMica: REAL ~ 0.00001;
These are common scale factors for ScaleT.
ScaleT: PROC[context: Context, s: REAL];
Scales the current transformation by s.
Equivalent to ConcatT[context, ImagerTransformation.Scale[s]].
Scale2T: PROC[context: Context, s: VEC];
Equivalent to ConcatT[context, ImagerTransformation.Scale2[s]].
RotateT: PROC[context: Context, a: REAL];
Equivalent to ConcatT[context, ImagerTransformation.Rotate[a]].
Angle a is in degrees counterclockwise.
TranslateT: PROC[context: Context, t: VEC];
Equivalent to ConcatT[context, ImagerTransformation.Translate[t]].
Move: PROC[context: Context];
Translates the origin to the current position.
Trans: PROC[context: Context];
Translates the origin to the grid point nearest the current position.
Masks
MaskFill: PROC[context: Context, pathProc: PathProc, pathData: REFNIL];
Fills the region outlined by the path with the current color.
Points with nonzero winding number are "inside" the path.
MaskFillParity: PROC[context: Context, pathProc: PathProc, pathData: REFNIL];
Like MaskFill, but only points with odd winding number are "inside" the path.
MaskRectangle: PROC[context: Context, x, y, w, h: REAL];
MaskRectangleI: PROC[context: Context, x, y, w, h: INTEGER]
~ INLINE { context.class.MaskRectangleI[context, x, y, w, h] };
Fills a rectangular area with the given origin, width and height.
Box: TYPE ~ RECORD[xmin, ymin, xmax, ymax: REAL];
MaskBox: PROC[context: Context, box: Box];
Fills a rectangular area with the given boundaries.
A convenience for former users of Graphics.DrawBox.
StrokeEnd: TYPE ~ {square, butt, round};
square: Square off the end after extending the stroke by half its width
butt: Square off the end flush with the endpoint
round: Round the end with a semicircular cap
StrokeJoint: TYPE ~ {miter, round};
miter: Extend sides until they meet (acute angles make long, sharp corners)
round: Put a circle at each joint
StrokeStyle: TYPE ~ RECORD[end: StrokeEnd, joint: StrokeJoint];
StrokeDashes: TYPE ~ REF StrokeDashesRep;
StrokeDashesRep: TYPE ~ RECORD[begin, repeat, end: DashPattern ← NIL];
DashPattern: TYPE ~ LIST OF DashSpec;
DashSpec: TYPE ~ RECORD[style: StrokeStyle, width, length, stretch: REAL];
SetStrokeWidth: PROC[context: Context, width: REAL];
Establishes the width for following strokes.
SetStrokeStyle: PROC[context: Context, style: StrokeStyle];
Establishes endpoint and joint treatment for following strokes.
SetStrokeDashes: PROC[context: Context, dashes: StrokeDashes ← NIL];
Establishes a dash pattern for following strokes.
MaskStroke: PROC[context: Context, pathProc: PathProc, pathData: REFNIL];
The stroke is first broadened to have uniform width strokeWidth, fitted with the endpoints specified by strokeStyle, then transformed by the current transformation T, and used as a mask to alter the image.
MaskStrokeClosed: PROC[context: Context, pathProc: PathProc, pathData: REFNIL];
Like MaskStroke, except that each trajectory is closed if necessary with a straight line back to its starting point.
MaskVector: PROC[context: Context, p1, p2: VEC];
MaskVectorI: PROC[context: Context, x1, y1, x2, y2: INTEGER]
~ INLINE { context.class.MaskVectorI[context, x1, y1, x2, y2] };
MaskStroke for a single straight line segment.
MaskPixel: PROC[context: Context, pa: PixelArray];
Uses a pixel array as a mask; must have one bit per pixel.
MaskBits: PROC[context: Context,
base: LONG POINTER, wordsPerLine: NAT,
sMin, fMin, sSize, fSize: NAT, sOffset, fOffset: INTEGER ← 0];
SetPriorityImportant: PROC[context: Context, priorityImportant: BOOL];
While priorityImportant=TRUE, the order of mask operations is preserved.
SetNoImage: PROC[context: Context, noImage: BOOL];
While noImage=TRUE, mask operations do not affect the output.
Text
SetXY: PROC[context: Context, p: VEC];
SetXYI: PROC[context: Context, x, y: INTEGER]
~ INLINE { context.class.SetXYI[context, x, y] };
Sets the current position.
SetXYRel: PROC[context: Context, v: VEC];
SetXYRelI: PROC[context: Context, x, y: INTEGER]
~ INLINE { context.class.SetXYRelI[context, x, y] };
Adds a relative displacement to the current position.
SetXRel: PROC[context: Context, x: REAL];
SetXRelI: PROC[context: Context, x: INTEGER]
~ INLINE { context.class.SetXYRelI[context, x, 0] };
Equivalent to SetXYRel[context, x, 0]
SetYRel: PROC[context: Context, y: REAL];
SetYRelI: PROC[context: Context, y: INTEGER]
~ INLINE { context.class.SetXYRelI[context, 0, y] };
Equivalent to SetXYRel[context, 0, y]
SetFont: PROC[context: Context, font: Font];
Establishes the font for following Shows.
Show: PROC[context: Context, chars: PROC[PROC[Char]], xrel: BOOLFALSE];
ShowChar: PROC[context: Context, char: CHAR,
set: CharSet ← 0];
ShowRope: PROC[context: Context, rope: ROPE,
start: INT ← 0, len: INTINT.LAST,
set: CharSet ← 0];
ShowText: PROC[context: Context, text: REF READONLY TEXT,
start: NAT ← 0, len: NATNAT.LAST,
set: CharSet ← 0];
SetAmplifySpace: PROC[context: Context, amplifySpace: REAL];
StartUnderline: PROC[context: Context];
Remembers the starting x position for an underline.
MaskUnderline: PROC[context: Context, dy, h: REAL];
MaskUnderlineI: PROC[context: Context, dy, h: INTEGER]
~ INLINE { context.class.MaskUnderlineI[context, dy, h] };
Masks a rectangular underline from the StartUnderline point to the current position.
The underline's top is dy below the current position; its height is h.
Example: StartUnderline[ctx]; ShowRope[ctx, "underlined"]; MaskUnderline[ctx, 4, 1];
CorrectMask: PROC[context: Context];
CorrectSpace: PROC[context: Context, v: VEC];
Space: PROC[context: Context, x: REAL];
SpaceI: PROC[context: Context, x: INTEGER]
~ INLINE { context.class.SpaceI[context, x] };
Equivalent to { SetXRel[ctx, x]; CorrectSpace[ctx, [x, 0]] }.
SetCorrectMeasure: PROC[context: Context, v: VEC];
SetCorrectTolerance: PROC[context: Context, v: VEC];
SetCorrectShrink: PROC[context: Context, correctShrink: REAL];
Correct: PROC[context: Context, action: PROC];
Color
black, white: READONLY Color;
SetColor: PROC[context: Context, color: Color];
Sets the current color.
SetGray: PROC[context: Context, f: REAL];
Equivalent to SetColor[context, ImagerColor.MakeGray[f]]
SetSampledColor: PROC[context: Context, pa: PixelArray,
m: Transformation ← NIL, colorOperator: ColorOperator];
SetSampledBlack: PROC[context: Context, pa: PixelArray,
m: Transformation ← NIL, clear: BOOLFALSE];
These operations set a sampled color with a transformation of Concat[m, T].
Clipping
ClipOutline: PROC[context: Context, pathProc: PathProc, pathData: REFNIL];
ExcludeOutline: PROC[context: Context, pathProc: PathProc, pathData: REFNIL];
ClipRectangle: PROC[context: Context, x, y, w, h: REAL];
ClipRectangleI: PROC[context: Context, x, y, w, h: INTEGER]
~ INLINE { context.class.ClipRectangleI[context, x, y, w, h, FALSE] };
ExcludeRectangle: PROC[context: Context, x, y, w, h: REAL];
ExcludeRectangleI: PROC[context: Context, x, y, w, h: INTEGER]
~ INLINE { context.class.ClipRectangleI[context, x, y, w, h, TRUE] };
Private details
RealKey: TYPE ~ { -- for SetReal, GetReal
DCScpx, DCScpy,
correctMX, correctMY,
mediumXSize, mediumYSize,
fieldXMin, fieldYMin, fieldXMax, fieldYMax,
strokeWidth,
underlineStart,
amplifySpace,
correctShrink, correctExpand,
correctTX, correctTY
};
IntKey: TYPE ~ { -- for SetInt, GetInt
priorityImportant,
noImage,
strokeStyle,
correctPass
};
SetT: PROC[context: Context, m: Transformation];
SetFont: PROC[context: Context, font: Font]; -- declared above
SetColor: PROC[context: Context, color: Color]; -- declared above
SetClipper: PROC[context: Context, clipper: Clipper];
SetReal: PROC[context: Context, key: RealKey, value: REAL];
SetInt: PROC[context: Context, key: IntKey, value: INT];
GetT: PROC[context: Context] RETURNS[Transformation];
GetFont: PROC[context: Context] RETURNS[Font];
GetColor: PROC[context: Context] RETURNS[Color];
GetClipper: PROC[context: Context] RETURNS[Clipper];
GetReal: PROC[context: Context, key: RealKey] RETURNS[REAL];
GetInt: PROC[context: Context, key: IntKey] RETURNS[INT];
GetCP: PROC[context: Context] RETURNS[VEC];
GetCPRounded: PROC[context: Context] RETURNS[VEC];
Class: TYPE ~ REF ClassRep;
ClassRep: TYPE ~ RECORD[
type: ATOM,
SetT: PROC[context: Context, m: Transformation],
SetFont: PROC[context: Context, font: Font],
SetColor: PROC[context: Context, color: Color],
SetClipper: PROC[context: Context, clipper: Clipper],
SetReal: PROC[context: Context, key: RealKey, value: REAL],
SetInt: PROC[context: Context, key: IntKey, value: INT],
GetT: PROC[context: Context] RETURNS[Transformation],
GetFont: PROC[context: Context] RETURNS[Font],
GetColor: PROC[context: Context] RETURNS[Color],
GetClipper: PROC[context: Context] RETURNS[Clipper],
GetReal: PROC[context: Context, key: RealKey] RETURNS[REAL],
GetInt: PROC[context: Context, key: IntKey] RETURNS[INT],
DoSave: PROC[context: Context, action: PROC],
DoSaveAll: PROC[context: Context, action: PROC],
ConcatT: PROC[context: Context, m: Transformation],
Scale2T: PROC[context: Context, s: VEC],
RotateT: PROC[context: Context, a: REAL],
TranslateT: PROC[context: Context, t: VEC],
Move: PROC[context: Context],
Trans: PROC[context: Context],
SetGray: PROC[context: Context, f: REAL],
SetSampledColor: PROC[context: Context, pa: PixelArray,
m: Transformation, colorOperator: ColorOperator],
MaskFill: PROC[context: Context, pathProc: PathProc, pathData: REF, parity: BOOL],
MaskStroke: PROC[context: Context, pathProc: PathProc, pathData: REF, closed: BOOL],
MaskRectangle: PROC[context: Context, x, y, w, h: REAL],
MaskRectangleI: PROC[context: Context, x, y, w, h: INTEGER],
MaskVector: PROC[context: Context, p1, p2: VEC],
MaskVectorI: PROC[context: Context, x1, y1, x2, y2: INTEGER],
StartUnderline: PROC[context: Context],
MaskUnderline: PROC[context: Context, dy, h: REAL],
MaskUnderlineI: PROC[context: Context, dy, h: INTEGER],
MaskPixel: PROC[context: Context, pa: PixelArray],
MaskBits: PROC[context: Context, base: LONG POINTER, wordsPerLine: NAT,
sMin, fMin, sSize, fSize: NAT, sOffset, fOffset: INTEGER],
ClipOutline: PROC[context: Context, pathProc: PathProc, pathData: REF, exclude: BOOL],
ClipRectangle: PROC[context: Context, x, y, w, h: REAL, exclude: BOOL],
ClipRectangleI: PROC[context: Context, x, y, w, h: INTEGER, exclude: BOOL],
SetXY: PROC[context: Context, p: VEC],
SetXYI: PROC[context: Context, x, y: INTEGER],
SetXYRel: PROC[context: Context, v: VEC],
SetXYRelI: PROC[context: Context, x, y: INTEGER],
GetCP: PROC[context: Context, round: BOOL] RETURNS[VEC],
Show: PROC[context: Context, chars: PROC[PROC[Char]], xrel: BOOL],
CorrectMask: PROC[context: Context],
CorrectSpace: PROC[context: Context, v: VEC],
Space: PROC[context: Context, x: REAL],
SpaceI: PROC[context: Context, x: INTEGER],
SetCorrectMeasure: PROC[context: Context, v: VEC],
SetCorrectTolerance: PROC[context: Context, v: VEC],
Correct: PROC[context: Context, action: PROC],
props: Prop.PropList ← NIL
];
END.