Copyright (C) 1994, Digital Equipment Corp.
by Steve Glassman, Mark Manasse and Greg Nelson
<*PRAGMA LL*> INTERFACEAScrnPaintOp ; IMPORT TrestleComm, PaintOp;
ScrnPaintOp.T is a painting operation that is valid for
some particular screentype.
If op is a ScrnPaintOp.T valid for screentype st, then op
maps a source pixel s and destination pixel d to a result pixel
op(d, s). It will be used in a painting operation that sets d
:= op(d, s). Both d and op(d, s) have type st, and s either
has type st or st.bits. (The type st.bits is the screentype
for one-bit deep sources that can be used with st.) For example,
in a copy operation, s has type st, while in painting a bitmap,
s has type st.bits.
A ScrnPaintOp.Oracle is meaningful only as the op field of some
screentype st. It provides methods to generate ScreenPaintOp.Ts
that are valid for st.
A {\it tint} is a paintop that is independent of s. If op is
a tint, we write op(d) instead of op(d, s). (Even in the case
of a tint, the type of s must be st.bits; otherwise the result
of applying the tint is undefined.)
\subsubsection{Obtaining handles from the oracle}
TYPE
Pixel = INTEGER;
Oracle = Private OBJECT
METHODS
<* LL.sup <= VBT.mu *>
opaque(pix: Pixel): T
RAISES {Failure, TrestleComm.Failure};
bgfg(bg, fg: T): T
RAISES {Failure, TrestleComm.Failure};
swap(p,q: Pixel): T
RAISES {Failure, TrestleComm.Failure};
transparent(): T
RAISES {Failure, TrestleComm.Failure};
copy(): T
RAISES {Failure, TrestleComm.Failure};
builtIn(op: PaintOp.Predefined): T;
END;
Private <: ROOT;
EXCEPTION Failure;
For a screentype st, the field st.op is an Oracle whose methods
satisfy the following specifications:
The method call
op := st.op.opaque(pix)
sets op to a tint such that op(p) = pix for any p. The method call
op := st.op.bgfg(bg, fg)
sets op to a tint such that op(p, 0) = bg(p) and op(p, 1)
= fg(p), for any p, if bg and fg are tints. The method call
op := st.op.swap(p, q)
sets op to a tint such that op(p)=q, op(q)=p, and for any
x, op(op(x))=x. The method call
op := st.op.transparent()
sets op to a tint such that op(p) = p for any p. The method call
op := st.op.copy()
sets op to a painting operation such that op(p, q) = q for any
p and q. The method call
st.op.builtIn(op)
returns the operation valid for st that corresponds to the
predefined screen-independent operation PaintOp.T{op}.
The exception Failure is raised if the screentype cannot provide the
requested painting operation. For all the methods, LL.sup <= VBT.mu.
TYPE
PlaneWiseOracle = Oracle OBJECT
METHODS <* LL.sup <= VBT.mu *>
planewise(
READONLY mask: ARRAY OF BOOLEAN;
op1, op2: T): T
RAISES {Failure, TrestleComm.Failure};
END;
If a screentype's op oracle is a PlaneWiseOracle (which you can
test with TYPECASE), then you can use its planewise method to
define painting operations by their effects on each bit position
of the destination pixel. Let p[i] denote bit i of pixel p.
Assuming NUMBER(mask) = st.depth, the method call
op := st.op.planewise(mask, bitOps)
sets op so that for d and s of screentype st and i in
[0..st.depth-1],
IF mask[i] THEN
op(d, s)[i] = op1(d[i], s[i])
ELSE
op(d, s)[i] = op2(d[i], s[i])
END
The method may raise Failure if it does not support a particular
combination of op1, op2, and mask.
The convenience procedure ConstructPlanewiseOp can be used to construct a painting operation from an array of boolean functions represented by the
enumeration by BitOp:
TYPE
BitOp = {
Zero, (* 0 *)
And, (* dest AND src *)
NotAnd, (* (NOT dest) AND src *)
Src, (* src *)
AndNot, (* dest and (NOT src) *)
Dest, (* dest *)
Xor, (* dest XOR src *)
Or, (* dest OR src *)
Nor, (* (NOT dest) AND (NOT src) *)
Equal, (* dest XOR (NOT src) *)
Invert, (* NOT dest *)
NotOr, (* (NOT dest) OR src *)
NotSrc, (* NOT src *)
OrNot, (* dest OR (NOT src) *)
Nand, (* (NOT dest) OR (NOT src) *)
One}; (* 1 *)
PROCEDURE ConstructPlanewiseOp(
pwo: PlaneWiseOracle;
READONLY bitOps: ARRAY OF BitOp): T
RAISES {Failure, TrestleComm.Failure};
<* LL.sup <= VBT.mu *>
Return the painting operation that appliesbitOp[i]to planeiof the source and destination.
If
NUMBER(bitOps) = st.depth then ConstructPlanewiseOp uses pwo to
construct and return an operation op such that for s and
d of screentype st and i in [0 .. st.depth-1],
op(d, s)[i] = bitOps[i](d[i], s[i])
The procedure may raise Failure if the screentype does not support
a particular array bitOps.
\subsubsection{The handle object}
TYPE T <: Public; Public = OBJECT id: INTEGER; pix: Pixel := -1 END;If
p is a T, then p.id is an identifier whose interpretation
depends on the screentype. If p was created by a call
st.op.opaque(pix), then p.pix = pix; otherwise p.pix = -1.
END ScrnPaintOp.