Imager.mesa
This interface is the public expression of the client view of the procedures, structures, etc.
for making images on all devices.
Last edited by:
Crow, August 1, 1983 4:02 pm
Plass, August 3, 1983 10:01 am
Wyatt, Plass, & Crow, September 20, 1983 4:59 pm
Wyatt, September 21, 1983 10:13 am
DIRECTORY
ImagerBasic USING [Color, IntPair, IntRectangle, Pair, PathClosure, PixelArray, Rectangle, StrokeEnds, Transformation, Visibility],
Rope USING [ROPE],
UnifiedFonts USING [FONT];
Types
FONT:
TYPE = UnifiedFonts.
FONT;
Pair:
TYPE = ImagerBasic.Pair;
IntPair:
TYPE = ImagerBasic.IntPair;
Rectangle:
TYPE = ImagerBasic.Rectangle;
IntRectangle:
TYPE = ImagerBasic.IntRectangle;
Color:
TYPE = ImagerBasic.Color;
PixelArray:
TYPE = ImagerBasic.PixelArray;
Transformation:
TYPE = ImagerBasic.Transformation;
Path: TYPE = REF PathRep;
PathRep:
TYPE =
PRIVATE
RECORD[
prev: Path, -- the preceding path, NIL if path begins at lp
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, e: REAL], -- conic section segment; see Full Interpress
ENDCASE
];
Polygon: TYPE = REF PolygonRep;
PolygonRep:
TYPE =
RECORD[length:
NAT, vertices:
SEQUENCE max:
NAT
OF Pair];
Context
Context: TYPE = REF ContextRep; -- Holds the imager state
ContextRep: TYPE = RECORD[class: REF, data: REF];
Create:
PROC [deviceType:
ATOM, data:
REF]
RETURNS [Context];
For making a new context.
The data field is optional; its type is dependent on the deviceType.
May raise ERROR UnimplementedDevice
UnimplementedDevice: ERROR;
DeviceType:
PROC [context: Context]
RETURNS [
ATOM];
Clear:
PROC [context: Context];
If display, clear the entire view to white.
NewPage:
PROC [context: Context];
If printer or InterPress, start new page.
Close:
PROC [context: Context];
If printer or InterPress, close output file.
Saving and restoring imager variables.
See also GetT/SetT, GetColor/SetColor, GetClipper/SetClipper, GetViewCP/SetViewCP
DoSaveAll:
PROC [context: Context, action:
PROC];
Save the imager variables, execute the action, and restore the variables to their old values.
DoSave:
PROC [context: Context, action:
PROC];
Like DoSaveAll, but CP is not restored
Transformations
These calls concatenate to the current client transform.
ConcatT:
PROC [context: Context, m: Transformation];
equivalent to SetT[context, Concat[m, GetT[context]]]
TranslateT: PROC [context: Context, dx, dy: REAL];
RotateT: PROC [context: Context, degrees: REAL];
ScaleT:
PROC [context: Context, sx, sy:
REAL];
various special cases of ConcatT
Move:
PROC[context: Context];
Translate so that the origin maps to the current position.
Trans:
PROC[context: Context];
Translate so that the origin maps to the (view) grid point nearest the current position.
Current position
The imaging operators make it easy to locate a graphical object such as a character at the current position, a location on the view. Several operators are available for changing the current position. It is by altering the current position that an operator displaying a character specifies where the next character in the text line should usually lie.
SetXY: PROC [context: Context, p: Pair];
SetXYRel: PROC [context: Context, v: Pair];
SetXRel: PROC [context: Context, x: REAL];
SetYRel:
PROC [context: Context, y:
REAL];
Paths
MoveTo:
PROC[path: Path, p: Pair]
RETURNS[Path];
Start a new trajectory at p.
StartAt:
PROC[p: Pair]
RETURNS[Path] =
INLINE {
RETURN[MoveTo[
NIL, p]] };
Create a new path starting at p.
LineTo:
PROC[path: Path, p: Pair]
RETURNS[Path];
Extend a straight line segment from path.lp to p.
CurveTo:
PROC[path: Path, p1, p2, p3: Pair]
RETURNS[Path];
Extend a cubic curve segment from path.lp to p3.
The curve is defined by four Bezier control points: [path.lp, p1, p2, p3]
ConicTo:
PROC[path: Path, p1, p2: Pair, e:
REAL]
RETURNS[Path];
Extend a conic section segment from path.lp to p2.
The segment starts at path.lp, tangent to and pointed in the direction of the line from path.lp to p1. The segment ends at p2, tangent to and pointed in the direction of the line from p1 to p2. The eccentricity of the conic section is e, e IN[0..1].
LastPoint:
PROC[path: Path]
RETURNS[Pair] =
INLINE {
RETURN[path.lp] };
The following constructs a path describing the triangle a-b-c:
path: Path ← StartAt[a]; path ← LineTo[path, b]; path ← LineTo[path, c];
or, equivalently...
path: Path = StartAt[a].LineTo[b].LineTo[c];
Masks
These procedures take the current color and apply it to those pixels which lie inside an area defined by the mask parameter (stroke, area, or pixelmask). The defined area is treated as a stencil which is conceptually superposed over the page while the color or image is applied.
MaskFill:
PROC [context: Context, path: Path];
Use the path to outline an area to be filled with the current color
StrokeEnd: TYPE = {default, butt, square, round};
MaskStroke:
PROC [context: Context, path: Path, width:
REAL ← defaultWidth,
strokeEnd: StrokeEnd ← default, closed: BOOL ← FALSE];
Form a stencil of "width" thickness around a spine defined by "path", and fill it with the current color. Connected path segments will be mitered together.
"butt" ends are squared off at the endpoint coordinate.
"square" ends are extended by half the stroke width before squaring.
"round" ends have semicircular caps at the ends.
MaskPixel:
PROC [context: Context, pixelArray: PixelArray];
Use the supplied pixel array as the stencil. The origin of the pixel array will be placed at the origin of the client space. The samples will be placed at one unit intervals in the client space.
MaskRectangle:
PROC [context: Context, area: Rectangle];
Fill rectangular area with the current color
MaskIntRectangle:
PROC [context: Context, area: IntRectangle];
StartUnderline: PROC[context: Context];
MaskUnderline: PROC[context: Context, dy, h: REAL];
In the following, the width of lines is device dependent, approximately .1% page height.
MaskThinStroke:
PROC [context: Context, path: Path, closed:
BOOL ←
FALSE];
Draw whole path using the current color
MaskVector:
PROC [context: Context, p1, p2: Pair];
Draw a thin stroke which is a single line segment from p1 to p2.
MaskBits:
PROC [context: Context, base:
LONG
POINTER, raster:
CARDINAL, tile: IntRectangle, area: IntRectangle];
Use a set of bits beginning at "base" to form a single-bit per pixel tile with dimensions given by "tile". The tile will be used (repetitively if necessary) to color the "area". The tile is filled with bits from "base" as follows:
line: LONG POINTER ← base;
FOR y DECREASING IN [0..tile.h) DO
FOR x IN [0..tile.w) DO
tile[x, y] ← GetBit[line, x];
ENDLOOP;
line ← line+raster;
ENDLOOP;
where GetBit[line, i] gets the ith bit after line.
Clipping
These routines allow the definition and testing of client clipping paths. Clipping paths are assumed to be glued to the view once defined. Subsequent changes in the client transform do not affect previously defined clipping paths.
Clipper:
TYPE =
REF;
-- for use in GetClipper and SetClipper only.
Direct control of the client-to-view clipper.
GetClipper: PROC [context: Context] RETURNS [Clipper];
SetClipper:
PROC [context: Context, clipper: Clipper];
Note: the clipper is represented in the view coordinate system!
ClipOutline:
PROC [context: Context, outline: Path, exclude:
BOOL ←
FALSE];
Modifies old clipping region by supplied outline. Exclude sets clipping outside path rather than inside.
ClipRectangle:
PROC [context: Context, outline: Rectangle, exclude:
BOOL ←
FALSE];
Modifies old clipping region by supplied outline. Exclude sets clipping outside path rather than inside.
TestRectangle:
PROC [context: Context, area: Rectangle]
RETURNS [Visibility];
ClipIntRectangle:
PROC [context: Context, outline: IntRectangle, exclude:
BOOL ←
FALSE];
Modifies old clipping region by supplied outline. Exclude sets clipping outside path rather than inside.
TestIntRectangle:
PROC [context: Context, area: IntRectangle]
RETURNS [Visibility];
DoWithoutClipping:
PROC [context: Context, bounds: IntRectangle, action:
PROC[Context]];
Uses TestIntRectangle with "bounds" to verify that no clipping is needed. In cases of inaccurate bounding rectangles, the client assumes liability for garbaged displays, but not for garbaged worlds.
Characters
Use the Font interface to obtain FONTs and their metrics.
MaskChar: PROC [context: Context, font: FONT, char: CHAR];
MaskCharacters:
PROC [context: Context, font:
FONT, characters:
REF,
--
ROPE
or
REF
TEXT
start: INT ← 0, length: INT ← LAST[INT]];
Uses the DeviceWidth of each character for positioning.
Affects current position.
Window managers only below here, please.
Not all devices support these operations. To determine whether or not a given operation is supported, clients should inspect the appropriate field of the class record, e. g.,
IF context.class.MoveSurfaceRectangle = NIL
THEN RedrawRectangle[]
ELSE context.MoveSurfaceRectangle[. . .];
Reset:
PROC [context: Context];
Reset a context to its initial state (same as when it was created).
Procedures for manipulating View-to-Surface transformation and clipper
SetView:
PROC [context: Context, box: IntRectangle, halftoneOrigin: IntPair ← [0, 0]];
Sets the View-to-Surface transformation to map the origin in View coordinates to (box.x and box.y) in Surface coordinates, and the View-to-Surface clipper to show the specified box. The halftoneOrigin parameter is for controlling the phase of halftones, and is also expressed in terms of Surface coordinates.
ClipView:
PROC [context: Context, box: IntRectangle, exclude:
BOOL];
For setting up fancier clippers; the box is in Surface coordinates.
GetSurfaceBounds:
PROC [context: Context]
RETURNS [IntRectangle];
For finding out where the usable parts of the Surface are. The results are in Surface coordinates.
GetViewBounds:
PROC [context: Context]
RETURNS [IntRectangle];
Yields the bounding box of the View clipper, in Surface coordinates.
MoveSurfaceRectangle:
PROC [context: Context, source: IntRectangle, dest: IntPair]
RETURNS [
BOOL];
Moves the source rectangle so that its new origin is at dest. Both source and dest are in Surface coordinates. Returns FALSE if the device does not support the operation. Overlapping source and dest are allowed. Clippers are ignored. Beware of moving images containing halftones, because this may cause misaligned halftone screens. The halftone screens are aligned by SetView, so the window package may move viewers around without problems.
SetColorInvert: PROC [context: Context];
DrawBitmap: PROC [context: Context, base: LONG POINTER, raster: CARDINAL, area: IntRectangle];
SpecialOp:
PROC [context: Context, op:
ATOM, data:
REF]
RETURNS [
BOOL];