DisplayAsPrinterImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Michael Plass, July 13, 1987 5:20:30 pm PDT
DIRECTORY Imager, ImagerBackdoor, HBrick, ImagerColor, ImagerDevice, ImagerMaskCache, ImagerPrintColor, ImagerPrivate, ImagerRaster, ImagerSample, ImagerTransformation, PrintColor, SF, Vector2, Terminal, ImagerPixel;
DisplayAsPrinterImpl: CEDAR PROGRAM
IMPORTS ImagerBackdoor, HBrick, ImagerMaskCache, ImagerPrintColor, ImagerRaster, ImagerPixel, ImagerSample, ImagerTransformation, Terminal
EXPORTS ExportsList
~ BEGIN
Data: TYPE ~ REF DataRep;
DataRep: TYPE ~ RECORD [
bitmaps: ImagerPixel.PixelMap ← NIL,
viewToDevice: ImagerTransformation.Transformation,
deviceColorData: ImagerPrintColor.DeviceColorData
];
fontCacheName: ATOM ~ $Print;
fontCacheMaxSize: INT ← 8000;
defaultDotShape: REAL ← 0.48;
defaultScreenAngle: ARRAY PrintColor.Toner[black..yellow] OF REAL ← [
black: 90,
cyan: 75,
magenta: 105,
yellow: 45
];
MakeHalftoneProperties: PROC [logicalDevice: PrintColor.LogicalDevice, pixelsPerHalftoneDot: REAL] RETURNS [h: PrintColor.HalftoneProperties ← NIL] ~ {
FOR t: PrintColor.Toner IN PrintColor.Toner[black..yellow] DO
angle: REAL ~ defaultScreenAngle[t];
brick: HBrick.Brick ~ HBrick.BrickFromDotScreen[pixelsPerDot: pixelsPerHalftoneDot, degrees: angle, shape: defaultDotShape];
h ← CONS[[type: NIL, toner: t, brick: brick], h];
ENDLOOP;
};
Create: PUBLIC PROC [deviceSpaceSize: SF.Vec, scanMode: ImagerTransformation.ScanMode, surfaceUnitsPerInch: Vector2.VEC, logicalDevice: PrintColor.LogicalDevice, pixelsPerHalftoneDot: REAL] RETURNS [Imager.Context] ~ {
halftoneProperties: PrintColor.HalftoneProperties ~ MakeHalftoneProperties[logicalDevice, pixelsPerHalftoneDot];
data: Data ~ NEW[DataRep ← [bitmaps: NIL, deviceColorData: ImagerPrintColor.NewDeviceColorData[logicalDevice: logicalDevice, halftoneProperties: halftoneProperties, correction: NIL, interpolate: FALSE]]];
deviceParm: ImagerDevice.DeviceParm ← NEW[ImagerDevice.DeviceParmRep ← [
class: deviceClass,
sSize: deviceSpaceSize.s,
fSize: deviceSpaceSize.f,
scanMode: scanMode,
surfaceUnitsPerInch: surfaceUnitsPerInch,
surfaceUnitsPerPixel: 1,
fontTuner: NIL,
fontCache: ImagerMaskCache.GetNamedCache[fontCacheName, fontCacheMaxSize],
rastWeight: 2.0
]];
context: Imager.Context ~ ImagerRaster.Create[class: contextClass, deviceParm: deviceParm, data: data, pixelUnits: FALSE];
ImagerRaster.SetDeviceClipBox[context, [[0,0], [0,0]]];
RETURN [context]
};
InterleavedRep: TYPE ~ RECORD [mapInterleaved: ImagerSample.SampleMap, offset: NAT, samplesPerPixel: NAT];
InterleavedGetSamples: ImagerSample.ObjectGetProc ~ {
data: REF InterleavedRep ~ NARROW[ImagerSample.GetData[self]];
ImagerSample.GetSamples[map: data.mapInterleaved, initIndex: [initIndex.s, initIndex.f*data.samplesPerPixel+data.offset], delta: [0, data.samplesPerPixel], buffer: buffer, start: start, count: count];
};
InterleavedPutSamples: ImagerSample.ObjectPutProc ~ {
data: REF InterleavedRep ~ NARROW[ImagerSample.GetData[self]];
ImagerSample.PutSamples[map: data.mapInterleaved, initIndex: [initIndex.s, initIndex.f*data.samplesPerPixel+data.offset], delta: [0, data.samplesPerPixel], buffer: buffer, start: start, count: count, function: function];
};
InitColorMap: PUBLIC PROC [vt: Terminal.Virtual] ~ {
FOR k: NAT IN [0..1] DO
FOR y: NAT IN [0..1] DO
FOR m: NAT IN [0..1] DO
FOR c: NAT IN [0..1] DO
channel: CARDINAL ~ (((c*2+m)*2+y)*2+k);
red: CARDINAL ~ (1-c)*255*(1-k);
green: CARDINAL ~ (1-m)*255*(1-k);
blue: CARDINAL ~ (1-y)*255*(1-k);
Terminal.SetColor[vt: vt, aChannelValue: channel, bChannelValue: 0, red: red, green: green, blue: blue];
ENDLOOP;
ENDLOOP;
ENDLOOP;
ENDLOOP;
};
PixelMapFromFrameBuffers: PUBLIC PROC [frameA: Terminal.FrameBuffer] RETURNS [ImagerPixel.PixelMap] ~ {
sampleA: ImagerSample.SampleMap ~ ImagerSample.MapFromFrameBuffer[frameA];
box: SF.Box ~ ImagerSample.GetBox[sampleA];
frameAInterleaved: Terminal.FrameBuffer ~ NEW[Terminal.FrameBufferRep ← [vm: frameA.vm, base: frameA.base, wordsPerLine: frameA.wordsPerLine, bitsPerPixel: 1, width: frameA.width*frameA.bitsPerPixel, height: frameA.height]];
sampleInterleaved: ImagerSample.SampleMap ~ ImagerSample.MapFromFrameBuffer[frameAInterleaved];
sampleC: ImagerSample.SampleMap ~ ImagerSample.NewObjectSampleMap[box: box, bitsPerSample: 1, getSamples: InterleavedGetSamples, putSamples: InterleavedPutSamples, data: NEW[InterleavedRep ← [sampleInterleaved, frameA.bitsPerPixel-4, frameA.bitsPerPixel]]];
sampleM: ImagerSample.SampleMap ~ ImagerSample.NewObjectSampleMap[box: box, bitsPerSample: 1, getSamples: InterleavedGetSamples, putSamples: InterleavedPutSamples, data: NEW[InterleavedRep ← [sampleInterleaved, frameA.bitsPerPixel-3, frameA.bitsPerPixel]]];
sampleY: ImagerSample.SampleMap ~ ImagerSample.NewObjectSampleMap[box: box, bitsPerSample: 1, getSamples: InterleavedGetSamples, putSamples: InterleavedPutSamples, data: NEW[InterleavedRep ← [sampleInterleaved, frameA.bitsPerPixel-2, frameA.bitsPerPixel]]];
sampleK: ImagerSample.SampleMap ~ ImagerSample.NewObjectSampleMap[box: box, bitsPerSample: 1, getSamples: InterleavedGetSamples, putSamples: InterleavedPutSamples, data: NEW[InterleavedRep ← [sampleInterleaved, frameA.bitsPerPixel-1, frameA.bitsPerPixel]]];
pixelMap: ImagerPixel.PixelMap ~ ImagerPixel.MakePixelMap[sampleK, sampleC, sampleM, sampleY];
RETURN [pixelMap];
};
frameA should be at least 4 bps.
SetBitmaps: PUBLIC PROC [context: Imager.Context, bitmaps: ImagerPixel.PixelMap] ~ {
data: Data ~ NARROW[context.data];
data.bitmaps ← bitmaps;
ImagerRaster.SetDeviceClipBox[context, IF bitmaps = NIL THEN [] ELSE bitmaps.box];
};
SetSeparation: PUBLIC PROC [context: Imager.Context, toner: PrintColor.Toner] ~ {
data: Data ~ NARROW[context.data];
ImagerPrintColor.SetSeparation[data.deviceColorData, toner];
};
MySetColor: PROC [context: Imager.Context, color: ImagerColor.Color, viewToDevice: ImagerTransformation.Transformation] RETURNS [ImagerDevice.AllowedMasks] ~ {
data: Data ~ NARROW[context.data];
data.viewToDevice ← ImagerTransformation.Copy[viewToDevice];
ImagerPrintColor.SetDeviceColorData[data.deviceColorData, color, viewToDevice];
RETURN [[
unorderedBoxes: FALSE,
multipleCoverage: FALSE,
regionFill: FALSE,
bitmap: FALSE,
rawBitmaps: FALSE,
runGroupChar: FALSE,
rasterChar: FALSE
]];
};
MyMaskBoxes: PROC [context: Imager.Context, bounds: SF.Box, boxes: SF.BoxGenerator] ~ {
data: Data ~ NARROW[context.data];
FOR t: PrintColor.Toner IN [black..yellow] DO
ImagerPrintColor.SetSeparation[data.deviceColorData, t];
ImagerPrintColor.SetDeviceColorData[data.deviceColorData, ImagerBackdoor.GetColor[context], data.viewToDevice];
ImagerPrintColor.MaskBoxes[data.bitmaps[ORD[t]], data.deviceColorData, bounds, boxes];
ENDLOOP;
};
deviceClass: ImagerDevice.DeviceClass ~ NEW[ImagerDevice.DeviceClassRep ← [
SetColor: MySetColor,
SetPriority: NIL,
MaskBoxes: MyMaskBoxes,
MaskRegion: NIL,
MaskBitmap: NIL,
MaskRawBitmaps: NIL,
DrawBitmap: NIL,
MaskChar: NIL,
MoveBox: NIL,
DoBuffered: NIL,
AccessBuffer: NIL
]];
contextClass: ImagerPrivate.Class ~ CreateClass[];
CreateClass: PROC RETURNS [class: ImagerPrivate.Class] ~ INLINE {
class ← ImagerRaster.CreateClass[type: $Print, deviceClass: deviceClass];
class.Show ← ...;
};
END.