<*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.T
s
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]) ENDThe 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 planei
of 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.