PressImageImpl.mesa
Last edited by Shore; December 4, 1982 12:25 am
DIRECTORY
CGArea USING [Empty, Ref],
CGContext USING [GenBox, Rep],
CGDevice USING [Ref],
CGMatrix USING [Assign, Concat, ConcatTransformation, Make, New, Ref, SetTrans],
CGSource USING [Ref, Rep],
CGStorage USING [qZone],
Environment USING [bitsPerWord],
File USING [Capability],
FileIO USING [CapabilityFromStream, STREAM],
Graphics USING [Context, Scale],
GraphicsBasic USING [black],
PressImage,
PressReader USING [Dots],
Space USING [Create, CreateUniformSwapUnits, Delete, Handle, LongPointer, Map, virtualMemory]; -- GetAttributes Unmap nullHandle
PressImageImpl:
PROGRAM
-- MONITOR
IMPORTS CGArea, CGContext, CGMatrix, CGStorage, FileIO, Graphics, Space
EXPORTS PressImage
SHARES Graphics = BEGIN
Context: TYPE = Graphics.Context;
ContextData: TYPE = REF ContextDataRep;
ContextDataRep: PUBLIC TYPE = CGContext.Rep;
PressImage: PUBLIC TYPE = REF PressImageData;
PressImageData:
PUBLIC
TYPE =
RECORD [
file: FileIO.STREAM,
numberPages: NAT,
pageNumber: NAT,
byteOffset: INT,
length: INT,
scanDirection: CARDINAL,
scanCount: CARDINAL, -- lines
scanLength: CARDINAL, -- dots
wordsPerLine: CARDINAL, -- words per scan line
imageHeight: REAL,
imageWidth: REAL,
miv: CGMatrix.Ref, -- image-to-virtual matrix
matrix: CGMatrix.Ref, -- image-to-device matrix
src: CGSource.Ref -- source info for image
];
dataZone: ZONE = CGStorage.qZone;
srcZone: ZONE = CGStorage.qZone;
PressImageError: PUBLIC ERROR = CODE;
MakePressImage:
PUBLIC
PROCEDURE [sampleType, dots, lines, mode, pd, dd, pl, dl:
INT, width, height:
REAL, bits: PressReader.Dots]
RETURNS [self: PressImage ←
NIL] = {
scanlines, pixels, wpl, bps: CARDINAL;
scanlines ← lines;
pixels ← dots;
wpl ← (dots+Environment.bitsPerWord-1)/Environment.bitsPerWord;
IF dots MOD Environment.bitsPerWord # 0 THEN ERROR PressImageError;
bps ← sampleType;
self ← dataZone.
NEW[PressImageData ← [
file: bits.file,
numberPages: bits.numberPages,
pageNumber: bits.pageNumber,
byteOffset: bits.byteOffset,
length: bits.length,
scanDirection: mode,
scanCount: scanlines,
scanLength: pixels,
wordsPerLine: wpl,
imageHeight: height,
imageWidth: width,
miv:
SELECT mode
FROM
2 => CGMatrix.Make[[1,0,0,1,0,0]],
3 => CGMatrix.Make[[1,0,0,-1,0,lines]],
8 => CGMatrix.Make[[0,1,1,0,0,0]],
ENDCASE => ERROR, -- unexpected scanDirection
matrix: CGMatrix.New[], -- placeholder for image-to-device mapping
src: srcZone.NEW[CGSource.Rep ← [type: array, mode: opaque, fat: FALSE, raw: FALSE, bps: bps, color: GraphicsBasic.black, xbase: NIL, xrast: wpl, Get: NIL]]]];
RETURN [self];
};
DrawPressImage:
PUBLIC
PROCEDURE [self: Context, image: PressImage] = {
ctx: ContextData;
data: PressImage ← image;
T: CGMatrix.Ref; -- virtual to destination mapping
M: CGMatrix.Ref ← data.matrix; -- image to destination mapping
src: CGSource.Ref ← data.src;
wpl: CARDINAL ← data.wordsPerLine;
device: CGDevice.Ref;
file: File.Capability ← FileIO.CapabilityFromStream[data.file];
space: Space.Handle;
area: CGArea.Ref;
basePtr, dotPtr: LONG POINTER;
Graphics.Scale[self, data.imageWidth/REAL[data.scanLength], data.imageHeight/REAL[data.scanCount]];
ctx ← NARROW[self.data];
T ← ctx.matrix;
device ← ctx.device;
CGMatrix.Assign[M,T];
CGMatrix.SetTrans[M, ctx.cp]; -- translate to current position
IF NOT ctx.yUp THEN CGMatrix.Concat[M,1,0,0,-1];
CGMatrix.ConcatTransformation[M, data.miv.m]; -- M ← miv * T
src.color ← ctx.src.color; src.mode ← ctx.src.mode;
space ← Space.Create[size: data.numberPages, parent: Space.virtualMemory];
Space.CreateUniformSwapUnits[size: 10, parent: space];
Space.Map[space, [file, data.pageNumber+1]];
basePtr ← Space.LongPointer[space];
dotPtr ← basePtr+data.byteOffset/2;
src.xbase ← dotPtr;
area ← CGContext.GenBox[ctx,
[xmin: 0, ymin: 0, xmax: data.scanLength-1, ymax: data.scanCount-1], M];
IF NOT CGArea.Empty[area] THEN device.Show[device, area, src, M];
Space.Delete[space];
};
END.