[Oberon] System-V - Frame Clipping
Andreas Pirklbauer
andreas_pirklbauer at yahoo.com
Mon Mar 4 11:28:31 CET 2019
> I will experiment with `Clip(F)', `Clip(NIL)' inside `Display1.Mod’. It actually
> consolidates graph primitives, some based on input from the list here,
> simplified for PO2013, currently does not support brush idea, vectors, etc.
Not 100% sure what problem you are trying to solve. But at least for *patterns*
that are copied "as is” into the frame buffer using SYSTEM.PUT, one can do
the clipping by applying appropriate masks, as shown in the example below.
-ap
Display.CopyPattern with left, right, top, and bottom margins:
PROCEDURE CopyPattern*(col, patadr, x, y, left, right, top, bot, mode: INTEGER); (*only for modes = paint, invert*)
VAR a, a0, pwd: INTEGER;
w, h, pbt: BYTE; pix, mask, ml, mr: SET;
BEGIN (*0 <= top < h, 0 <= bot < h, top + bot < h, 0 <= right < w, 0 <= left < w, left + right < w*)
SYSTEM.GET(patadr, w); SYSTEM.GET(patadr+1, h); INC(patadr, 2 + bot*((w + 7) DIV 8)); h := h - top - bot;
a := base + (x DIV 32)*4 + (y+bot)*128; x := x MOD 32; mask := SYSTEM.VAL(SET, ASR(7FFFFFFFH, 31-x));
FOR a0 := a TO a + (h-1)*128 BY 128 DO
(*build pattern line; w < 32*)
SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt;
IF w > 8 THEN SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt*100H + pwd;
IF w > 16 THEN SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt*10000H + pwd;
IF w > 24 THEN SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt*1000000H + pwd END
END
END ;
IF left + right > 0 THEN (*clip*)
ml := {0 .. w-right-1}; mr := {left .. w-1}; pwd := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET, pwd) * ml * mr)
END ;
SYSTEM.GET(a0, pix);
IF mode = invert THEN SYSTEM.PUT(a0, SYSTEM.VAL(SET, LSL(pwd, x)) / pix)
ELSE SYSTEM.PUT(a0, SYSTEM.VAL(SET, LSL(pwd, x)) + pix)
END ;
IF x + w > 32 THEN (*spill over*)
SYSTEM.GET(a0+4, pix);
IF mode = invert THEN SYSTEM.PUT(a0+4, SYSTEM.VAL(SET, ASR(pwd, -x)) * mask/ pix)
ELSE SYSTEM.PUT(a0+4, SYSTEM.VAL(SET, ASR(pwd, -x)) * mask+ pix)
END
END
END
END CopyPattern;
TextFrames.DisplayLine which uses the above procedure to implement fractional text rendering:
PROCEDURE DisplayLine (F: Frame; L: Line;
VAR R: Texts.Reader; X, Y, topY, botY: INTEGER; len: LONGINT);
VAR patadr, NX, dx, x, y, w, h, left, right, top, bot: INTEGER;
BEGIN NX := F.X + F.W - F.right; left := 0;
WHILE (nextCh # CR) & (R.fnt # NIL) DO
Fonts.GetPat(R.fnt, nextCh, dx, x, y, w, h, patadr);
IF (X + x < NX) & (h # 0) THEN y := Y + y;
IF y + h <= topY THEN top := 0 ELSIF y >= topY THEN top := h ELSE (*clip*) top := y + h - topY END;
IF y >= botY THEN bot := 0 ELSIF y + h <= botY THEN bot := h ELSE (*clip*) bot := botY - y END;
IF x + X + w <= NX THEN right := 0 ELSE (*clip*) right := x + X + w - NX END;
IF top + bot < h THEN Display.CopyPattern(R.col, patadr, X + x, y, left, right, top, bot, Display.invert) END
END;
X := X + dx; INC(len); Texts.Read(R, nextCh)
END;
L.len := len + 1; L.wid := X + eolW - (F.X + F.left);
L.eot := R.fnt = NIL; Texts.Read(R, nextCh)
END DisplayLine;
More information about the Oberon
mailing list