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; 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 ]; AllowedMasks: TYPE ~ PACKED RECORD [ unorderedBoxes: BOOL ¬ FALSE, multipleCoverage: BOOL ¬ FALSE, regionFill: BOOL ¬ FALSE, bitmap: BOOL ¬ FALSE, rawBitmaps: BOOL ¬ FALSE, runGroupChar: BOOL ¬ FALSE, rasterChar: BOOL ¬ FALSE, pixelArray: BOOL ¬ FALSE ]; DeviceClass: TYPE ~ REF DeviceClassRep; DeviceClassRep: TYPE ~ RECORD [ SetColor: PROC [device: Device, color: ImagerColor.Color, viewToDevice: ImagerTransformation.Transformation] ¬, SetPriority: PROC [device: Device, priorityImportant: BOOL] ¬ NIL, SetHalftoneProperties: PROC [device: Device, halftoneProperties: ImagerBrick.HalftoneProperties] ¬ NIL, MaskBoxes: PROC [device: Device, bounds: SF.Box, boxes: SF.BoxGenerator] ¬ , MaskRegion: PROC [device: Device, bounds: SF.Box, edgeGenerator: PROC [ImagerSample.EdgeAction]] ¬ NIL, MaskBitmap: PROC [device: Device, bitmap: ImagerSample.SampleMap, delta: SF.Vec, bounds: SF.Box, boxes: SF.BoxGenerator] ¬ NIL, MaskPixelArray: PROC [device: Device, bitmap: PixelArray, clientToDevice: Transformation, bounds: SF.Box, boxes: SF.BoxGenerator] ¬ NIL, MaskRawBitmaps: PROC [device: Device, list: LIST OF ImagerSample.RawDescriptor] ¬ NIL, DrawBitmap: PROC [device: Device, bitmap: ImagerSample.SampleMap, delta: SF.Vec, bounds: SF.Box, boxes: SF.BoxGenerator] ¬ NIL, MaskChar: PROC [device: Device, delta: SF.Vec, mask: ImagerMaskCache.CharMask] ¬ NIL, MoveBox: PROC [device: Device, dstMin, srcMin, size: SF.Vec] ¬ NIL, SwitchBuffer: PROC [device: Device, bounds: SF.Box, copy: BOOL, alt: BOOL] ¬ NIL, GetBufferColorOperator: PROC [device: Device] RETURNS [ImagerColor.ColorOperator] ¬ NIL, AccessBuffer: PROC [device: Device, box: SF.Box, action: PROC [pixelMap: ImagerPixel.PixelMap]] ¬ NIL, propList: Prop.PropList ¬ NIL ]; 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 ]; 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. ¦ 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 Device 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. 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. If TRUE, portions of the mask may be covered multiple times If TRUE, may use MaskRegion If TRUE, MaskBitmap may be called. If TRUE, MaskRawBitmaps may be called. If TRUE, MaskChar may be called with a run-group character; otherwise runs are generated. If TRUE, MaskChar may be called with a raster character; otherwise MaskBitmap is called, or runs are generated. If TRUE, MaskPixelArray may be called. Notifies device of a color change. Sets device.state.allow to indicate the kinds of masks that the device is willing to accept. Notifies device of a change to priorityImportant. Notifies device of a change to halftoneProperties. 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. Masks a monotone region designated by the edges. The edgeGenerator must specify the edges in nondecreasing sMin order. Optional proc for masking a bitmap. Optional proc for masking a bitmap expressed as a PixelArray. Optional proc for masking multiple bitmaps Optional proc for drawing a bitmap. Optional proc for masking a character from a font cache. Optional proc for moving a rectangular region of the raster. If not supplied, ImagerBackdoor.MoveViewRectangle will raise an error when called. 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). If supplied, allows full implementation of ImagerBackdoor.GetBufferColorOperator. If supplied, allows full implementation of AccessBuffer. Device Parameter Record Static instance data that the common raster implementation needs to know. 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. Κ Ώ•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ ΟeœU™`K™,šœ+™+K™——šΟk ˜ Kšœ žœ ˜Kšœ žœ˜'Kšœžœ ˜Kšœ žœ˜)Kšœžœ˜ Kšœ žœ ˜0Kšœžœ ˜ Kšœžœ.˜CKšœ žœ ˜Kšœ žœ˜Kšœ žœ ˜Kšœžœ˜$Kšœ žœ(˜:Kšœžœ˜6Kšœžœ ˜Kšžœžœ˜"Kšœžœžœ˜—K˜KšΠbl œžœž ˜Kšœžœžœa˜mhead™Kš Οn œžœžœ=žœžœžœ Οc ˜–K˜Kšœžœžœ ‘(˜Gšœ žœžœ˜Kšœ‘"˜5Kšœ‘(˜@Kšœ‘˜'Kšœ‘˜ Kšœ‘#˜7Kšœžœ‘˜!Kšœ˜K˜—Kšœ žœžœ˜'šœžœžœ˜Kšœ‘,˜AKšœžœ‘8˜HKšœžœžœ˜8Kšœ˜——™ ™ΊK™—šœžœžœžœ˜$šœžœžœ˜Kšœžœτ™ϋ—šœžœžœ˜Kšœžœ4™;—šœ žœžœ˜Kšœžœ™—šœžœžœ˜Kšœžœ™"—šœ žœžœ˜Kšœžœ™&—šœžœžœ˜KšœžœR™Y—šœ žœžœ˜Kšœžœh™o—šœ žœž˜Kšœžœ™&—Kšœ˜K˜—Kšœ žœžœ˜'šœžœžœ˜š œžœa˜oKšœ€™€—š  œžœ%žœžœ˜BK™1—š œžœHžœ˜gK™2—š  œžœžœ žœ˜LK™TKšœ<žœ%™e—š   œžœžœžœžœ˜gKšœw™w—š   œžœ9žœžœ žœžœ˜Kšœ#™#—š  œžœNžœ žœžœ˜ˆKšœ=™=—š  œžœžœžœžœ˜VKšœ*™*—š   œžœ9žœžœ žœžœ˜Kšœ#™#—š œžœžœ(žœ˜UKšœ8™8—š œžœ(žœžœ˜CKšœ™—š   œžœžœ žœžœžœ˜QKšœ8™8Kšœžœ©™΅Kšœžœ$žœW™ˆ—š œžœžœžœ˜XK™Q—š   œžœžœžœ%žœ˜fKšœ8™8—Kšœž˜K˜——™™IK™—š œžœ$žœHžœžœ-žœ+žœžœžœ˜΅K˜—Kšœ žœD˜Uš œ žœžœžœ žœžœ˜2K˜—Kšœ žœžœ‘,˜Sšœžœžœ˜Kšœ‘˜'Kšœžœ‘#˜6Kšœ)‘*˜SKšœžœ‘˜:Kšœžœ‘;˜VKšœ'žœ‘-˜YKšœ)žœ‘A˜oKšœž˜Kšœ˜K˜——šœ™™ΦK™—šœ žœžœ˜Kšœ‘/˜GKšœœ‘'˜HKšœ%‘˜BK˜K˜—Kšœžœžœ˜+šœžœžœ žœ)˜UK˜—Kšœ9žœžœ˜bšœ žœ˜*K˜—šœžœžœ˜K˜Kšœ‘˜;Kšœ!‘'˜HKšœ%‘˜>K˜K˜—šœžœžœ˜ K˜Kšœžœ˜K˜Kšœ˜K˜—šœžœžœ˜%K˜K˜K˜!Kšœ˜K˜—šœžœžœ˜"K˜Kšœžœ˜Kšœ#žœ žœžœ˜EK˜Kšœ˜K˜—šœžœžœ˜"K˜Kšœžœ˜ Kšœ%žœ˜)K˜Kšœ˜K˜—šœžœžœ˜(K˜K˜Kšœ žœ˜Kš œ žœžœžœžœ˜#Kšœžœ˜ Kšœžœ˜ Kšœžœ˜ K˜Kšœžœ˜ Kšœžœ˜ Kšœ žœ˜K˜Kšœ˜K˜—šœžœžœ˜"K˜K˜K˜Kšœ˜K˜—šœžœžœ˜&K˜K˜K˜Kšœ˜K˜—šœžœžœ˜!K˜Kšœžœ žœ ˜&Kšœ˜K˜—šœžœžœ˜$K˜Kšœ#˜#K˜Kšœžœžœžœ˜K˜—šœžœžœ˜Kšœ˜K˜Kšœ˜Kšœ‘˜2Kšœ ‘˜2Kšœ žœ'‘˜JKšœ‘'˜AKšœ žœ‘˜-K˜K˜—Kšœ žœžœ˜%šœžœžœ˜Kš œ˜Kš œ˜Kš  œ˜&Kš  œ˜ Kš  œ˜ Kš œ˜,Kš  œ˜ Kš œ˜(Kš  œ˜Kš  œ˜$Kš œ˜Kšœ˜K˜——Kšžœ˜K˜K˜K˜—…—l1Ρ