Copyright (C) 1994, Digital Equipment Corp.
Digital Internal Use Only
Created on Tue Jan 17 16:48:42 PST 1995 by najork
MODULE; IMPORT PaintOp, ScreenType, ScrnPaintOp, TrestleClass, VBTClass, WinDef, WinGDI, WinScreenType, WinScreenTypePrivate, Word; PROCEDURE WinScrnPaintOp NewOracle (st: WinScreenType.T): ScrnPaintOp.Oracle = BEGIN RETURN NEW(Oracle, st := st) END NewOracle; TYPE Oracle = ScrnPaintOp.Oracle BRANDED OBJECT st: WinScreenType.T; OVERRIDES opaque := Opaque; bgfg := BgFg; swap := Swap; transparent := Transparent; copy := Copy; builtIn := BuiltIn; END; PROCEDUREOpaque (self: Oracle; pix: ScrnPaintOp.Pixel): ScrnPaintOp.T = BEGIN RETURN NewPaintOp (self.st, Op {Mode.Opaq, pix}, Op {Mode.Opaq, pix}, pix); END Opaque; PROCEDURETransparent (self: Oracle): ScrnPaintOp.T = BEGIN RETURN NewPaintOp (self.st, Op {Mode.Tran, 0}, Op {Mode.Tran, 0}); END Transparent; PROCEDURECopy (self: Oracle): ScrnPaintOp.T = BEGIN RETURN NewPaintOp (self.st, Op {Mode.Copy, 0}, Op {Mode.Copy, 0}); END Copy; PROCEDURESwap (self: Oracle; p, q: ScrnPaintOp.Pixel): ScrnPaintOp.T = VAR pix := Word.Xor(p, q);
pix := 16_00000000;
(* expected behavior - no-op *)
pix := 16_00FFFFFF;
(* white to black, red to green (but not cyan) *)
pix := 16_02FFFFFF;
(* white turns green; red turns blue *) BEGIN (* "p = q" is a special case, which can be handled much more efficiently by calling "Transparent". *) IF p = q THEN RETURN Transparent(self); END; RETURN NewPaintOp (self.st, Op {Mode.Swap, pix}, Op {Mode.Swap, pix}); END Swap; PROCEDURE***** CONST R3_NOOP = 16_00AA0029; ****BgFg (self: Oracle; bg, fg: ScrnPaintOp.T): ScrnPaintOp.T RAISES {ScrnPaintOp.Failure} = PROCEDURE IsTint (rec: OpRecord): BOOLEAN = BEGIN RETURN rec.bop = rec.fop AND NOT rec.bop.mode = Mode.Copy; END IsTint; VAR st := self.st; BEGIN LOCK st.trsl DO IF bg.id < 0 OR bg.id >= st.opcount OR NOT IsTint(st.optable[bg.id]) OR fg.id < 0 OR fg.id >= st.opcount OR NOT IsTint(st.optable[fg.id]) THEN RAISE ScrnPaintOp.Failure; END; END; RETURN NewPaintOp(st, st.optable[bg.id].bop, st.optable[fg.id].fop); END BgFg; PROCEDUREBuiltIn (self: Oracle; op: PaintOp.Predefined): ScrnPaintOp.T = VAR b := self.st.bg; f := self.st.fg; back := Op {Mode.Opaq, b}; fore := Op {Mode.Opaq, f}; swap := Op {Mode.Swap, Word.Xor (b, f)}; tran := Op {Mode.Tran, 0}; BEGIN CASE op OF | PaintOp.Bg.op => RETURN NewPaintOp (self.st, back, back, b); | PaintOp.BgFg.op => RETURN NewPaintOp (self.st, back, fore); | PaintOp.BgTransparent.op => RETURN NewPaintOp (self.st, back, tran); | PaintOp.BgSwap.op => RETURN NewPaintOp (self.st, back, swap); | PaintOp.FgBg.op => RETURN NewPaintOp (self.st, fore, back); | PaintOp.Fg.op => RETURN NewPaintOp (self.st, fore, fore, f); | PaintOp.FgTransparent.op => RETURN NewPaintOp (self.st, fore, tran); | PaintOp.FgSwap.op => RETURN NewPaintOp (self.st, fore, swap); | PaintOp.TransparentBg.op => RETURN NewPaintOp (self.st, tran, back); | PaintOp.TransparentFg.op => RETURN NewPaintOp (self.st, tran, fore); | PaintOp.Transparent.op => RETURN NewPaintOp (self.st, tran, tran); | PaintOp.TransparentSwap.op => RETURN NewPaintOp (self.st, tran, swap); | PaintOp.SwapBg.op => RETURN NewPaintOp (self.st, swap, back); | PaintOp.SwapFg.op => RETURN NewPaintOp (self.st, swap, fore); | PaintOp.SwapTransparent.op => RETURN NewPaintOp (self.st, swap, tran); | PaintOp.Swap.op => RETURN NewPaintOp (self.st, swap, swap); | PaintOp.Copy.op => RETURN Copy(self); END; END BuiltIn; PROCEDUREToBinaryRasterOp (bop, fop: Op): INTEGER = BEGIN CASE bop.mode OF | Mode.Copy => CASE fop.mode OF | Mode.Copy => RETURN WinGDI.R2_COPYPEN; | Mode.Tran => RETURN WinGDI.R2_NOP; (* illegal combination *) | Mode.Opaq => RETURN WinGDI.R2_NOP; (* illegal combination *) | Mode.Swap => RETURN WinGDI.R2_NOP; (* illegal combination *) END; | Mode.Tran => CASE fop.mode OF | Mode.Copy => RETURN WinGDI.R2_NOP; (* illegal combination *) | Mode.Tran => RETURN WinGDI.R2_NOP; | Mode.Opaq => RETURN WinGDI.R2_COPYPEN; | Mode.Swap => RETURN WinGDI.R2_XORPEN; END; | Mode.Opaq => CASE fop.mode OF | Mode.Copy => RETURN WinGDI.R2_NOP; (* illegal combination *) | Mode.Tran => RETURN WinGDI.R2_NOP; | Mode.Opaq => RETURN WinGDI.R2_COPYPEN; | Mode.Swap => RETURN WinGDI.R2_XORPEN; END; | Mode.Swap => CASE fop.mode OF | Mode.Copy => RETURN WinGDI.R2_NOP; (* illegal combination *) | Mode.Tran => RETURN WinGDI.R2_NOP; | Mode.Opaq => RETURN WinGDI.R2_COPYPEN; | Mode.Swap => RETURN WinGDI.R2_XORPEN; END; END; END ToBinaryRasterOp;
PROCEDUREToBgTernaryRasterOp (op: Op): WinDef.DWORD = BEGIN CASE op.mode OF | Mode.Opaq => RETURN 16_00B8074A; | Mode.Tran => RETURN 0; | Mode.Swap => RETURN 16_009A0709; | Mode.Copy => RETURN WinGDI.SRCCOPY; END; END ToBgTernaryRasterOp; PROCEDUREToFgTernaryRasterOp (op: Op): WinDef.DWORD = BEGIN CASE op.mode OF | Mode.Opaq => RETURN 16_00E20746; | Mode.Tran => RETURN 0; | Mode.Swap => RETURN 16_006A01E9; | Mode.Copy => RETURN 0; END; END ToFgTernaryRasterOp; PROCEDURENewPaintOp (VAR st : WinScreenType.T; READONLY bop : Op; READONLY fop : Op; pix := -1): ScrnPaintOp.T = VAR res := NEW(ScrnPaintOp.T, pix := pix); rec : OpRecord; BEGIN rec.bop := bop; rec.fop := fop; rec.rop2 := ToBinaryRasterOp (bop, fop); rec.brop3 := ToBgTernaryRasterOp (bop); rec.frop3 := ToFgTernaryRasterOp (fop); LOCK st.trsl DO WITH n = NUMBER(st.optable^) DO IF n = st.opcount THEN WITH new = NEW(REF ARRAY OF OpRecord, 2 * n) DO SUBARRAY (new^, 0, n) := st.optable^; st.optable := new; END; END; END; res.id := st.opcount; st.optable[res.id] := rec; INC(st.opcount); END; RETURN res END NewPaintOp; BEGIN END WinScrnPaintOp.