IPBitmapOutputImpl.mesa
Last changed by:
Doug Wyatt, July 7, 1983 11:56 am
DIRECTORY
BitBlt USING [AlignedBBTable, BBTableSpace, BITBLT, BitBltTablePtr],
Inline USING [LongMult],
IPBitmapOutput USING [], -- exports only
IPImagerBasic USING [Color, ConstantColor, Transformation],
IPOutput USING [Procs, Ref, Rep, Size];
IPBitmapOutputImpl: CEDAR PROGRAM
IMPORTS BitBlt, Inline
EXPORTS IPBitmapOutput
= BEGIN OPEN IPImagerBasic, IPOutput;
Data: TYPE = REF DataRep;
DataRep: TYPE = RECORD [
base: LONG POINTER, -- base address of bitmap
rast: NAT, -- bitmap words per line
size: Size,
m: Transformation -- base transformation matrix
];
procs: REF READONLY Procs = NEW[Procs =
[GetTransformation: GetTransformation, GetSize: GetSize, Show: Show]];
New: PUBLIC PROC[base: LONG POINTER, raster: NAT, size: Size] RETURNS[Ref] = {
data: Data ← NEW[DataRep ← [base: base, rast: raster, size: size, m: NIL]];
RETURN[NEW[Rep ← [procs, data]]];
};
GetTransformation: PROC[self: Ref] RETURNS[Transformation] = {
data: Data = NARROW[self.data];
RETURN[data.m];
};
GetSize: PROC[self: Ref] RETURNS[Size] = {
data: Data = NARROW[self.data];
RETURN[data.size];
};
GrayArray: TYPE = ARRAY [0..4) OF CARDINAL;
grayTable: ARRAY[0..16) OF CARDINAL ← [
000000B, 010421B, 021042B, 031463B, 042104B, 052525B, 063146B, 073567B,
104210B, 114631B, 125252B, 135673B, 146314B, 156735B, 167356B, 177777B
];
MakeGray: PROC[color: ConstantColor] RETURNS[GrayArray] = {
i: [0..16) = color.g/4096;
table: ARRAY [0..15] OF CARDINAL = [
177777B, 32767, 32735, 24543, 24415, 23391, 23390, 23134,
23130, 6746, 6730, 2634, 2570, 2058, 2050, 0
];
gray: GrayArray ← ALL[177777B];
IF i#0 THEN {
temp: CARDINAL ← table[i];
FOR k: CARDINAL DECREASING IN[0..4) DO
gray[k] ← grayTable[temp MOD 16]; temp ← temp/16;
ENDLOOP;
};
RETURN[gray];
};
Show: PROC[self: Ref, color: Color, gen: PROC[PROC[x, y, w, h: INTEGER]]] = {
data: Data = NARROW[self.data];
base: LONG POINTER = data.base;
rast: NAT = data.rast;
size: Size = data.size;
WITH color SELECT FROM
color: ConstantColor => TRUSTED {
bbspace: BitBlt.BBTableSpace;
bb: BitBlt.BitBltTablePtr = BitBlt.AlignedBBTable[@bbspace];
line: LONG POINTER ← base;
liney: NAT ← 0;
gray: ARRAY [0..4) OF CARDINAL ← MakeGray[color];
rect: SAFE PROC[x, y, w, h: INTEGER] = TRUSTED {
dx: [0..16) = x MOD 16;
dy: [0..4) = y MOD 4;
IF x<0 OR w<0 OR y<0 OR h<0 THEN ERROR;
IF x>size.x OR w>(size.x-x) THEN ERROR;
IF y>size.y OR h>(size.y-y) THEN ERROR;
IF y=liney THEN NULL
ELSE IF y=liney+1 THEN line ← line+rast
ELSE line ← base+Inline.LongMult[y, rast];
liney ← y;
bb.dst ← [word: line+x/16, bit: dx];
bb.src ← [word: @gray+dy, bit: dx];
bb.srcDesc.gray.yOffset ← dy;
bb.width ← w; bb.height ← h;
BitBlt.BITBLT[bb];
};
bb^ ← [
dst: [word: NIL, bit: 0],
dstBpl: 0,
src: [word: NIL, bit: 0],
srcDesc: [gray[[yOffset: 0, widthMinusOne: 0, heightMinusOne: 3]]],
width: 0, height: 0,
flags: [disjoint: TRUE, gray: TRUE, srcFunc: null, dstFunc: null]
];
bb.dstBpl ← rast*16;
gen[rect];
};
ENDCASE => ERROR; -- not implemented
};
END.