ImagerDevice.mesa
Copyright Ó 1984, 1985, 1986, 1987, 1989, 1991, 1992 by Xerox Corporation. All rights reserved.
Michael Plass, January 21, 1992 10:39 am PST
Doug Wyatt, January 19, 1987 7:55:35 pm PST
DIRECTORY
ImagerBox USING [Rectangle],
ImagerBrick USING [HalftoneProperties],
ImagerClipper USING [Clipper],
ImagerColor USING [Color, ColorOperator],
ImagerDeviceVector USING [DVec],
ImagerFont USING [Font, XCharProc, XStringProc],
ImagerManhattan USING [Polygon],
ImagerMaskCache USING [CharFlags, CharMask, MaskCache, Parameters],
ImagerPath USING [PathProc],
ImagerPen USING [Pen],
ImagerPixel USING [PixelMap],
ImagerPixelArray USING [PixelArray],
ImagerSample USING [EdgeAction, RawDescriptor, SampleMap],
ImagerTransformation USING [ScanMode, Transformation],
Prop USING [PropList],
SF USING [Box, BoxGenerator, Vec],
Vector2 USING [VEC];
ImagerDevice: CEDAR DEFINITIONS
~ BEGIN OPEN ImagerBox, ImagerPath, ImagerPen, ImagerPixelArray, ImagerSample, ImagerTransformation, Vector2;
Device
MakeDevice: PUBLIC PROC [class: DeviceClass, parm: DeviceParm, state: DeviceState ¬ NIL, data: REF] RETURNS [Device]; -- provides standard works class
Device: TYPE ~ REF DeviceRepr; -- NOTE: Use MakeDevice to allocate this
DeviceRepr: TYPE ~ RECORD [
works: WorksClass, -- higher-level masking operations
worksState: WorksState, -- state information for the works level
class: DeviceClass, -- class operations
parm: DeviceParm, -- static data
state: DeviceState, -- dynamic, non-class-specific data
data: REF  -- class-specific data
];
DeviceState: TYPE ~ REF DeviceStateRep;
DeviceStateRep: TYPE ~ RECORD [
allow: AllowedMasks, -- allowed mask operations for current color
bounds: SF.Box, -- works level allows no masking outside of these bounds
scratchRawBitmapList: LIST OF ImagerSample.RawDescriptor
];
Device Class
The common raster implementation calls these to do the device-dependent work. At this level, clipping has been done; the masking procedures do not need to take the clipper into account.
AllowedMasks: TYPE ~ PACKED RECORD [
unorderedBoxes: BOOL ¬ FALSE,
If TRUE, boxes sent to MaskBoxes may come in any order; otherwise the boxes will be disjoint, nonempty, and for any two consecutive boxes a and b, b.min.s >= a.max.s-1. This invariant is needed, for instance, by certain anti-aliasing implementations.
multipleCoverage: BOOL ¬ FALSE,
If TRUE, portions of the mask may be covered multiple times
regionFill: BOOL ¬ FALSE,
If TRUE, may use MaskRegion
bitmap: BOOL ¬ FALSE,
If TRUE, MaskBitmap may be called.
rawBitmaps: BOOL ¬ FALSE,
If TRUE, MaskRawBitmaps may be called.
runGroupChar: BOOL ¬ FALSE,
If TRUE, MaskChar may be called with a run-group character; otherwise runs are generated.
rasterChar: BOOL ¬ FALSE,
If TRUE, MaskChar may be called with a raster character; otherwise MaskBitmap is called, or runs are generated.
pixelArray: BOOL ¬ FALSE
If TRUE, MaskPixelArray may be called.
];
DeviceClass: TYPE ~ REF DeviceClassRep;
DeviceClassRep: TYPE ~ RECORD [
SetColor: PROC [device: Device, color: ImagerColor.Color, viewToDevice: ImagerTransformation.Transformation] ¬,
Notifies device of a color change. Sets device.state.allow to indicate the kinds of masks that the device is willing to accept.
SetPriority: PROC [device: Device, priorityImportant: BOOL] ¬ NIL,
Notifies device of a change to priorityImportant.
SetHalftoneProperties: PROC [device: Device, halftoneProperties: ImagerBrick.HalftoneProperties] ¬ NIL,
Notifies device of a change to halftoneProperties.
MaskBoxes: PROC [device: Device, bounds: SF.Box, boxes: SF.BoxGenerator] ¬ ,
The basic means of communicating masks; this is the only mask proc that is required.
No guarantees about order if device.allow.unorderedBoxes is TRUE. All boxes will fall within bounds.
MaskRegion: PROC [device: Device, bounds: SF.Box, edgeGenerator: PROC [ImagerSample.EdgeAction]] ¬ NIL,
Masks a monotone region designated by the edges. The edgeGenerator must specify the edges in nondecreasing sMin order.
MaskBitmap: PROC [device: Device, bitmap: ImagerSample.SampleMap, delta: SF.Vec, bounds: SF.Box, boxes: SF.BoxGenerator] ¬ NIL,
Optional proc for masking a bitmap.
MaskPixelArray: PROC [device: Device, bitmap: PixelArray, clientToDevice: Transformation, bounds: SF.Box, boxes: SF.BoxGenerator] ¬ NIL,
Optional proc for masking a bitmap expressed as a PixelArray.
MaskRawBitmaps: PROC [device: Device, list: LIST OF ImagerSample.RawDescriptor] ¬ NIL,
Optional proc for masking multiple bitmaps
DrawBitmap: PROC [device: Device, bitmap: ImagerSample.SampleMap, delta: SF.Vec, bounds: SF.Box, boxes: SF.BoxGenerator] ¬ NIL,
Optional proc for drawing a bitmap.
MaskChar: PROC [device: Device, delta: SF.Vec, mask: ImagerMaskCache.CharMask] ¬ NIL,
Optional proc for masking a character from a font cache.
MoveBox: PROC [device: Device, dstMin, srcMin, size: SF.Vec] ¬ NIL,
Optional proc for moving a rectangular region of the raster. If not supplied, ImagerBackdoor.MoveViewRectangle will raise an error when called.
SwitchBuffer: PROC [device: Device, bounds: SF.Box, copy: BOOL, alt: BOOL] ¬ NIL,
If supplied, allows full implementation of DoWithBuffer.
If copy=TRUE, device should copy from the old buffer to the new buffer; otherwise garbage in the new buffer is OK, since the first thing that will happen is to fill it with a color.
alt=TRUE if switching to a temp buffer, and FALSE if switching back to the main buffer. These calls will always be paired (no nesting).
GetBufferColorOperator: PROC [device: Device] RETURNS [ImagerColor.ColorOperator] ¬ NIL,
If supplied, allows full implementation of ImagerBackdoor.GetBufferColorOperator.
AccessBuffer: PROC [device: Device, box: SF.Box, action: PROC [pixelMap: ImagerPixel.PixelMap]] ¬ NIL,
If supplied, allows full implementation of AccessBuffer.
propList: Prop.PropList ¬ NIL
];
Device Parameter Record
Static instance data that the common raster implementation needs to know.
MakeDeviceParm: PROC [class: DeviceClass, sSize, fSize: NAT, scanMode: ImagerTransformation.ScanMode, surfaceUnitsPerInch: Vector2.VEC, surfaceUnitsPerPixel: NAT ¬ 1, fontCache: ImagerMaskCache.MaskCache ¬ NIL, parameters: ImagerMaskCache.Parameters ¬ NIL, propList: Prop.PropList ¬ NIL] RETURNS [DeviceParm];
ClassOption: TYPE = { SetPriority, DrawBitmap, MoveBox, SwitchBuffer, AccessBuffer };
ClassHas: TYPE = PACKED ARRAY ClassOption OF BOOL;
DeviceParm: TYPE ~ REF DeviceParmRepr; -- Note: Use MakeDeviceParm to allocate this
DeviceParmRepr: TYPE ~ RECORD [
classHas: ClassHas, -- class operations
sSize, fSize: NAT, -- size of device coordinate system
scanMode: ImagerTransformation.ScanMode, -- orientation of device coordinate system
surfaceUnitsPerInch: Vector2.VEC, -- x and y scale factors
surfaceUnitsPerPixel: NAT, -- surface resolution may be a multiple of pixel resolution
fontCache: ImagerMaskCache.MaskCache ¬ NIL, -- cache for device-dependent character masks
parameters: ImagerMaskCache.Parameters ¬ NIL, -- Parameters for non-font applications (i.e., stroke thickening)
propList: Prop.PropList ¬ NIL
];
Higher-level Masking Operations
These operations are the same for most devices, but are done in an object-oriented fashion. See ImagerDeviceWorks for the standard, default implementations. These masking procedures are responsible for turning the resolution-independent masks into resolution-dependent masks for the device-class procedures, taking into account the clipper.
WorksState: TYPE = RECORD [
clipper: DeviceClipper, -- the composite clipper, in device coordinates
clipperToDevice: Transformation, -- coordinate system for client clipper
clientClipper: ImagerClipper.Clipper -- The client clipping region
];
DeviceClipper: TYPE = REF DeviceClipperRep;
DeviceClipperRep: TYPE = RECORD [clipBox: SF.Box, clipMask: ImagerManhattan.Polygon];
ordinaryMetrics: ImagerMaskCache.CharFlags ~ [amplified: FALSE, correction: mask, missing: FALSE];
EasyMetrics: TYPE = {all, ordinary, none};
ClipWorksProc: TYPE ~ PROC [
device: Device,
viewClipper: DeviceClipper, -- clipping region for the view
clipperToDevice: Transformation, -- coordinate system for client clipper
clientClipper: ImagerClipper.Clipper -- client clipping region
];
MaskFillWorksProc: TYPE ~ PROC [
device: Device,
path: PathProc, oddWrap: BOOL,
pathToDevice: Transformation
];
MaskRectangleWorksProc: TYPE ~ PROC [
device: Device,
rectangle: Rectangle,
rectangleToDevice: Transformation
];
MaskStrokeWorksProc: TYPE ~ PROC [
device: Device,
path: PathProc, closed: BOOL,
pathToDevice: Transformation, end: INT, joint: INT, miterLimit: REAL,
pen: Pen
];
MaskVectorWorksProc: TYPE ~ PROC [
device: Device,
p1, p2: VEC,
pointsToDevice: Transformation, end: INT,
pen: Pen
];
MaskDashedStrokeWorksProc: TYPE ~ PROC [
device: Device,
path: PathProc,
patternLen: NAT,
pattern: PROC [NAT] RETURNS [REAL],
offset: REAL,
length: REAL,
closed: BOOL,
pathToDevice: Transformation,
end: INT,
joint: INT,
miterLimit: REAL,
pen: Pen
];
MaskBitmapWorksProc: TYPE ~ PROC [
device: Device,
bitmap: SampleMap,
bitsToDevice: Transformation
];
MaskPixelArrayWorksProc: TYPE ~ PROC [
device: Device,
bitmap: PixelArray,
clientToDevice: Transformation
];
MaskBoxesWorksProc: TYPE ~ PROC [
device: Device,
bounds: SF.Box, boxes: SF.BoxGenerator
];
MaskCharMaskWorksProc: TYPE ~ PROC [
device: Device,
charMask: ImagerMaskCache.CharMask,
cp: ImagerDeviceVector.DVec
] RETURNS [ok: BOOL ¬ TRUE];
ShowWorksProc: TYPE ~ PROC [
device: Device,
fontAtom: ImagerFont.Font,
string: ImagerFont.XStringProc,
cp: ImagerDeviceVector.DVec, -- Gets side-effected
hardChar: ImagerFont.XCharProc, -- side-effects cp
hardMetrics: PROC [charMask: ImagerMaskCache.CharMask], -- side-effects cp
easyMetrics: EasyMetrics, -- says when we should call hardMetrics
noImage: BOOL -- says whether to skip masking
];
WorksClass: TYPE ~ REF WorksClassRep;
WorksClassRep: TYPE ~ RECORD [
Clip: ClipWorksProc,
MaskFill: MaskFillWorksProc,
MaskRectangle: MaskRectangleWorksProc,
MaskStroke: MaskStrokeWorksProc,
MaskVector: MaskVectorWorksProc,
MaskDashedStroke: MaskDashedStrokeWorksProc,
MaskBitmap: MaskBitmapWorksProc,
MaskPixelArray: MaskPixelArrayWorksProc,
MaskBoxes: MaskBoxesWorksProc,
MaskCharMask: MaskCharMaskWorksProc,
Show: ShowWorksProc
];
END.