ImagerDoc.tioga
Doug Wyatt, May 26, 1985 12:23:50 pm PDT
Michael Plass, June 26, 1985 2:37:49 pm PDT
THE CEDAR IMAGER
CEDAR 6.0 — FOR INTERNAL XEROX USE ONLY
The Cedar Imager
Device-independent image generation in Cedar
Doug Wyatt
© Copyright 1985 Xerox Corporation. All rights reserved.
Abstract: Package for device-independent image generation in Cedar.
Created by: Michael Plass and Doug Wyatt
Maintained by: The Imager Implementors <ImagerImplementors^.pa>
Keywords: image, graphics, font, display, printing, device independence, Interpress
XEROX  Xerox Corporation
   Palo Alto Research Center
   3333 Coyote Hill Road
   Palo Alto, California 94304

For Internal Xerox Use Only
Introduction
The Imager is patterned strongly after the imaging facilities available in Interpress, so refer to these internal publications for a description of the semantics of the various Imager operations:
Interpress Electronic Printing Standard (Version 2.1, XSIS 048404, April 1984) (Chapter 4)
Full Interpress (Interpress Extension Strategy) (DRAFT June 1983) (Chapter 4)
Introduction to Interpress (Sproull & Reid, XSIG 038306, June 1983)
For examples of how to use the Imager, refer to ImagerExamples.df on CedarChest. CedarChest also contains packages for creating Imager contexts for different kinds of output.
Refer to Viewers for obtaining Contexts that output to the displays.
History
Imager is a successor to the Cedar Graphics package that was developed by John Warnock and Doug Wyatt. The design of Imager benefited from advice offered by Frank Crow, Butler Lampson, Scott McGregor, Ken Pier, Lyle Ramshaw, Bob Sproull, and Maureen Stone. The main designers and implementors of Imager were Michael Plass and Doug Wyatt.
Transformations
Device coordinates
The Device coordinate system is in whatever units are most convenient for the implementation, and is normally inaccessible to the client.
Surface coordinates
The Surface coordinate system covers the entire output medium, one unit per pixel, with the origin at the lower-left corner and x to the right, y up.
View coordinates
The View coordinate system is normally just a translation from the Surface coordinates. This is normally maintained by the window package, not by random clients. When reading Interpress documentation, read "View coordinates" wherever you see "Device Coordinates". The View has a clipping area associated with it, which is often (but not always) just a rectangle. The View clipping area, as well as the View transformation, are not affected by DoSave, or DoSaveAll.
Client coordinates
The Client coordinate system is the one the client thinks in terms of. Initially in meters, it may be changed by the client at any time to whatever is most convenient. The client-to-view transformation is accessible as context.state.T.
Public Interfaces
Imager
The main one; see below.
Vector2, ImagerTransformation, ImagerPath, ImagerFont, ImagerPixelArray, ImagerColor, ImagerColorOperator
For dealing with particular data types that are used by Imager.
ImagerBackdoor
Operations that are not applicable to every kind of context.
ImagerOps
Extra handy operations.
The Imager interface
Contexts and Imager State
Context: TYPE ~ REF ContextRep;
Error: ERROR [error: ErrorDesc];
ErrorDesc: TYPE ~ RECORD [code: ATOM, explanation: ROPE];
GetClass: PROC [context: Context] RETURNS [ATOM];
Returns an ATOM that identifies the context class.
PutProp: PROC [context: Context, key: REF, val: REF];
GetProp: PROC [context: Context, key: REF] RETURNS [val: REF];
Operations on context.propList; propList is saved and restored by DoSave and DoSaveAll.
DoSave: PROC [context: Context, action: PROC];
DoSaveAll: PROC [context: Context, action: PROC];
These save imager variables, call the action procedure, then restore imager variables.
DoSave restores all but the current position and correctMeasure.
DoSaveAll restores everything.
Transformations and Current Position
Two important parts of the Imager state help clients to position the objects that make up an image; these are the current transformation and the current position. The basic procedure for changing the current transformation is:
ConcatT: PROC [context: Context, m: Transformation];
ConcatT premultiplies the current transformation by an arbitrary transformation. Procedures for building general transformations are in the ImagerTransformation interface. If you just want to do something simple, the following convenience procedures may be handy.
ScaleT: PROC [context: Context, s: REAL];
Scale2T: PROC [context: Context, s: VEC];
RotateT: PROC [context: Context, a: REAL];
TranslateT: PROC [context: Context, t: VEC];
ScaleT applies a uniform scaling factor; Scale2T scales independently in x and y; RotateT applies a counterclockwise rotation (measured in degrees); and TranslateT translates the origin.
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.
SetXY: PROC [context: Context, p: VEC];
SetXYI: PROC [context: Context, x, y: INTEGER];
Sets the current position.
SetXYRel: PROC [context: Context, v: VEC];
SetXYRelI: PROC [context: Context, x, y: INTEGER];
Adds a relative displacement to the current position.
SetXRel: PROC [context: Context, x: REAL];
SetXRelI: PROC [context: Context, x: INTEGER];
Equivalent to SetXYRel[context, x, 0]
SetYRel: PROC [context: Context, y: REAL];
SetYRelI: PROC [context: Context, y: INTEGER];
Equivalent to SetXYRel[context, 0, y]
Text and Spacing Correction
SetFont: PROC [context: Context, font: Font];
Sets the font for subsequent Show operations.
SetAmplifySpace: PROC [context: Context, amplifySpace: REAL];
Sets the scale factor for widths of `amplified' characters.
Show: PROC [context: Context, string: XStringProc, xrel: BOOLFALSE];
Shows a string of characters in the current font, starting at the current position.
If xrel~TRUE, every other char means SetXRel[context, char.code-128].
ShowChar: PROC [context: Context, char: CHAR];
Shows an 8-bit character (in Character Set 0).
ShowXChar: PROC [context: Context, char: XChar];
Shows a 16-bit Xerox Character Code.
ShowRope: PROC [context: Context, rope: ROPE,
start: INT ← 0, len: INTINT.LAST, xrel: BOOLFALSE];
Shows characters from a ROPE, using the Xerox String Encoding.
ShowText: PROC [context: Context, text: REF READONLY TEXT,
start: NAT ← 0, len: NATNAT.LAST, xrel: BOOLFALSE];
Shows characters from a REF TEXT, using the Xerox String Encoding.
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];
Draws an 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, 3, 1];
CorrectMask: PROC [context: Context];
CorrectSpace: PROC [context: Context, v: VEC];
Note "correction space" opportunities for Correct; see Correct, below.
Usually, font characters call these implicitly within Show.
Space: PROC [context: Context, x: REAL];
SpaceI: PROC [context: Context, x: INTEGER];
Use Space rather than SetXRel to make correctable spaces inside Correct.
Equivalent to { SetXRel[ctx, x]; CorrectSpace[ctx, [x, 0]] }.
SetCorrectMeasure: PROC [context: Context, v: VEC];
Sets the expected line measure for subsequent Correct operations.
SetCorrectTolerance: PROC [context: Context, v: VEC];
Sets the line measure tolerance for subsequent Correct operations.
SetCorrectShrink: PROC [context: Context, correctShrink: REAL];
Sets the allowable fraction of space shrink for subsequent Correct operations.
Correct: PROC [context: Context, action: PROC];
Ensures reasonable spacing of text (or other masks) even if the imager approximates fonts.
Like DoSave[context, action], but adjusts "correction space" if necessary to ensure that the net change in current position is within correctTolerance of correctMeasure.
Note that Correct may (or may not) invoke action twice.
See the Interpress Standard, section 4.10, and the Introduction to Interpress, section 10.
DontCorrect: PROC [context: Context, action: PROC, saveCP: BOOLFALSE];
Disables correction, calls action, then restores correction state.
If saveCP~TRUE, also saves and restores current position.
For relevant examples, see the Introduction to Interpress, section 10.6.
Color and Pixel Arrays
SetColor: PROC [context: Context, color: Color];
Sets the current color.
MakeGray: PROC [f: REAL] RETURNS [ConstantColor];
Returns a constant gray; f is the fraction of absorptance, from 0 (white) to 1 (black).
black: READONLY ConstantColor; -- MakeGray[1]
white: READONLY ConstantColor; -- MakeGray[0]
SetGray: PROC [context: Context, f: REAL];
Equivalent to SetColor[context, MakeGray[f]]
SetSampledColor: PROC [context: Context, pa: PixelArray,
m: Transformation ← NIL, colorOperator: ColorOperator];
Equivalent to SetColor[context, MakeSampledColor[pa, Concat[m, T], colorOperator].
Better than direct use of MakeSampledColor, since you don't need to know T.
SetSampledBlack: PROC [context: Context, pa: PixelArray,
m: Transformation ← NIL, clear: BOOLFALSE];
Equivalent to SetColor[context, MakeSampledBlack[pa, Concat[m, T], clear].
Better than direct use of MakeSampledBlack, since you don't need to know T.
Masks and Clipping
MaskFill: PROC [context: Context, path: PathProc, parity: BOOLFALSE];
Fills with the current color the interior of the region outlined by the specified path.
Closes each trajectory in the path with a straight line, if necessary.
If parity~FALSE, the mask includes all points with nonzero winding number.
If parity~TRUE, the mask includes all points with odd winding number.
MaskFillTrajectory: PROC [context: Context, trajectory: Trajectory, parity: BOOLFALSE];
Fills the region described by a Trajectory.
MaskFillOutline: PROC [context: Context, outline: Outline, parity: BOOLFALSE];
Fills the region described by an Outline.
MaskRectangle: PROC [context: Context, r: Rectangle];
MaskRectangleI: PROC [context: Context, x, y, w, h: INTEGER];
Fills the rectangle [x, y], [x+w, y], [x+w, y+h], [x, y+h].
Box: TYPE ~ RECORD [xmin, ymin, xmax, ymax: REAL];
MaskBox: PROC [context: Context, box: Box];
Fills the rectangle [xmin, ymin], [xmax, ymin], [xmax, ymax], [xmin, ymax].
A convenience for former users of Graphics.DrawBox.
SetStrokeWidth: PROC [context: Context, strokeWidth: REAL];
Establishes the width for subsequent strokes.
StrokeEnd: TYPE ~ {square, butt, round};
square: square off each end after extending the stroke by half strokeWidth
butt: square off each end flush with the endpoint
round: round each end with a semicircular cap of strokeWidth diameter
SetStrokeEnd: PROC [context: Context, strokeEnd: StrokeEnd];
Establishes the endpoint style for subsequent strokes.
StrokeJoint: TYPE ~ {mitered, round};
mitered: extend segment sides until they meet (acute angles make long, sharp corners)
round: join segments in a circle of strokeWidth diameter
SetStrokeJoint: PROC [context: Context, strokeJoint: StrokeJoint];
Establishes the joint style for subsequent strokes.
MaskStroke: PROC [context: Context, path: PathProc, closed: BOOLFALSE];
Fills with the current color a stroke whose centerline is the specified path.
The current strokeWidth and strokeJoint determine the stroke's width and joint style.
If closed~FALSE, the current strokeEnd determines the stroke's endpoint style.
If closed~TRUE, each trajectory is closed, if necessary, with a straight line.
MaskStrokeTrajectory: PROC [context: Context, trajectory: Trajectory, closed: BOOLFALSE];
Fills a stroke along a trajectory.
MaskVector: PROC [context: Context, p1, p2: VEC];
MaskVectorI: PROC [context: Context, x1, y1, x2, y2: INTEGER];
Fills a stroke along the line joining p1 and p2.
MaskPixel: PROC [context: Context, pa: PixelArray];
Uses a pixel array as a mask; pa must have one bit per pixel.
MaskBits: PROC [context: Context, base: LONG POINTER, wordsPerLine: NAT,
sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER ← 0];
SetPriorityImportant: PROC [context: Context, priorityImportant: BOOL];
If priorityImportant~TRUE, subsequent Mask operations will retain correct priority order.
SetNoImage: PROC [context: Context, noImage: BOOL];
If noImage~TRUE, subsequent Mask operations will not change the output.
Clip: PROC [context: Context, path: PathProc, parity, exclude: BOOLFALSE];
Clips subsequent masks to the interior of a region described (as for MaskFill) by a path.
If exclude~TRUE, clips to the exterior of the region instead of the interior.
This region is itself clipped by any clipping region previously in force.
ClipOutline: PROC [context: Context, outline: Outline, parity, exclude: BOOLFALSE];
Clips to an outline.
ClipRectangle: PROC [context: Context, r: Rectangle, exclude: BOOLFALSE];
ClipRectangleI: PROC [context: Context, x, y, w, h: INTEGER, exclude: BOOLFALSE];
Clips to the rectangle [x, y], [x+w, y], [x+w, y+h], [x, y+h].