<> <> <> <> DIRECTORY ImagerColorDefs, ImagerDevice, ImagerColorPrivate, ImagerPDDevice USING [], ImagerPixelArray, ImagerPixelMap USING [Create, DeviceRectangle, PixelMap], <> <> ImagerTransformation, PDFileWriter, PrincOps USING [zBNDCK, zINC]; ImagerPDDeviceImpl: CEDAR PROGRAM IMPORTS ImagerPixelMap, ImagerTransformation, PDFileWriter EXPORTS ImagerPDDevice, ImagerColorDefs ~ BEGIN Device: TYPE ~ ImagerDevice.Device; RunProc: TYPE ~ ImagerDevice.RunProc; HalftoneParameters: TYPE ~ ImagerDevice.HalftoneParameters; DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle; PixelMap: TYPE ~ ImagerPixelMap.PixelMap; Transformation: TYPE ~ ImagerTransformation.Transformation; Color: TYPE ~ ImagerColorDefs.Color; ConstantColor: TYPE ~ ImagerColorDefs.ConstantColor; SampledColor: TYPE ~ ImagerColorDefs.SampledColor; ColorOperator: TYPE ~ ImagerColorDefs.ColorOperator; ColorOperatorRep: TYPE ~ ImagerColorDefs.ColorOperatorRep; ConstantColorImpl: TYPE ~ REF ConstantColorImplRep; ConstantColorImplRep: PUBLIC TYPE ~ ImagerColorPrivate.ConstantColorImplRep; -- export to ImagerColorDefs.ConstantColorImplRep PDState: TYPE ~ PDFileWriter.PDState; Toner: TYPE ~ PDFileWriter.Toner; LoadReference: TYPE ~ PDFileWriter.LoadReference; dummyLoadReference: LoadReference ~ LAST[LoadReference]; GrayTileArray: TYPE ~ ARRAY Toner OF ARRAY [0..64) OF LoadReference; StippleRep: TYPE ~ RECORD[loadReference: LoadReference, stipple: PixelMap]; Case: TYPE ~ {nil, constant, gray, sampled}; defaultHalftone: HalftoneParameters _ [dotsPerInch: 50, angle: 30, shape: 0.5]; Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD [ pdState: PDState _ NIL, sSize, fSize: CARDINAL, case: Case _ nil, -- what type of color grayTileRef: GrayTileArray _ ALL[ALL[dummyLoadReference]], stipples: LIST OF StippleRep _ NIL, dot: ImagerPixelMap.PixelMap, -- a halftone dot halftone: HalftoneParameters _ defaultHalftone, -- halftone screen parameters pa: ImagerPixelArray.PixelArray _ NIL, -- pixel array from sampled color transparent: BOOL _ FALSE, -- transparent flag from sampled color multiplier: CARDINAL _ 1, lgScale: INTEGER _ 0, -- scale pa samples to match dot samples paToDevice: Transformation _ NIL, -- transformation from pa coords to display dotToDevice: Transformation _ NIL, -- transformation from dot coords to display <> <> <> <> <> kjhg: NAT _ 0 ]; class: ImagerDevice.Class ~ NEW[ImagerDevice.ClassRep _ [ type: $PD, SetColor: SetColor, SetPriority: SetPriority, SetHalftone: SetHalftone, MaskRuns: MaskRuns ]]; defaultDot: ImagerPixelMap.PixelMap _ ImagerPixelMap.Create[3, [0,0,16,16]]; <> <<>> Create: PUBLIC PROC[pdState: PDState, sSize, fSize, sPixelsPerInch, fPixelsPerInch: CARDINAL] RETURNS[Device] ~ { data: Data ~ NEW[DataRep _ [pdState: pdState, sSize: sSize, fSize: fSize, dot: defaultDot]]; sInches: REAL ~ REAL[sSize]/REAL[sPixelsPerInch]; fInches: REAL ~ REAL[fSize]/REAL[fPixelsPerInch]; surfaceToDevice: Transformation ~ ImagerTransformation.Scale[1]; xPixelsPerInch: CARDINAL _ sPixelsPerInch; yPixelsPerInch: CARDINAL _ fPixelsPerInch; <> IF sInches>fInches THEN { -- s (y) is top-to-bottom, f (x) is left-to-right surfaceToDevice.ApplyPreTranslate[[sSize, 0]]; surfaceToDevice.ApplyPreRotate[90]; xPixelsPerInch _ fPixelsPerInch; yPixelsPerInch _ sPixelsPerInch; } ELSE NULL; -- s (x) is left-to-right, f (y) is bottom-to-top <> <> RETURN[NEW[ImagerDevice.DeviceRep _ [class: class, box: [smin: 0, fmin: 0, smax: sSize, fmax: fSize], surfaceToDevice: surfaceToDevice, surfaceUnitsPerInch: [xPixelsPerInch, yPixelsPerInch], surfaceUnitsPerPixel: 1, data: data]]]; }; Val: TYPE ~ CARDINAL; Table: TYPE ~ REF TableRep; TableRep: TYPE ~ RECORD[SEQUENCE size: NAT OF CARDINAL]; <> <> <> <> <> <> <> <> <> <<};>> <<>> SetColor: PROC[device: Device, color: Color, viewToDevice: Transformation] ~ { data: Data ~ NARROW[device.data]; WITH color SELECT FROM color: ConstantColor => { impl: ConstantColorImpl ~ color.impl; SELECT impl.f FROM > 0.99 => { -- black SetInk: PROC[toner: Toner] ~ {data.pdState.SetColorInk[toner]}; data.pdState.DoForEachToner[SetInk]; }; < 0.001 => { -- white SetClear: PROC[toner: Toner] ~ {data.pdState.SetColorClear[toner]}; data.pdState.DoForEachToner[SetClear]; }; ENDCASE => ERROR; -- not yet implemented data.case _ constant; }; < {>> <> <> <> <> <> <> <> <> <> <> <> <> <> < {>> <> <> <> <> <> <> <> <> <> <<};>> < {>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> < ERROR; -- unknown ColorOperator>> <> <> <> <> <> <<};>> ENDCASE => ERROR; -- unknown color variant }; SetPriority: PROC[device: Device, priorityImportant: BOOL] ~ { data: Data ~ NARROW[device.data]; [] _ data.pdState.SetPriorityImportant[priorityImportant]; }; SetHalftone: PROC[device: Device, halftone: HalftoneParameters] ~ { data: Data ~ NARROW[device.data]; data.halftone _ halftone; }; Check: PROC[x: INTEGER, max: NAT] RETURNS[NAT] ~ TRUSTED MACHINE CODE { PrincOps.zINC; PrincOps.zBNDCK }; <> MaskRuns: PROC[device: Device, bounds: ImagerDevice.DeviceBox, runs: PROC[RunProc]] ~ { data: Data ~ NARROW[device.data]; SELECT data.case FROM nil => ERROR; -- color not initialized constant => { deliverRuns: PROC[captureRun: PROC[sMin, fMin, fSize: CARDINAL]] ~ { run: PROC[sMin, fMin: INTEGER, fSize: NAT] ~ { captureRun[sMin, fMin, fSize] }; runs[run]; }; PDFileWriter.MaskRunGroup[data.pdState, deliverRuns]; }; sampled => { <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> <> <> }; ENDCASE => ERROR; -- illegal case }; END.