|
|
1.1 root 1: #include <jerq.h>
2: #include "layer.h"
3:
4: /*
5: * Magic
6: *
7: * Intersect a rectangle to a layer, doing all subdivision into rectangles.
8: * layerop() clips rectangle to outer edge of layer, then calls mRlayerop
9: * which recursively chains along the layer list, doing op's (specified
10: * by a pointer to a function) whenever there is an intersection. Differs
11: * from rob's by taking a direction of evaluation, so that the subrectangles
12: * produced are properly sorted for bitblt from a layer to itself.
13: *
14: */
15:
16: /* For the portion outside the current layer, we use recursion */
17: #define out(or,co) mRlayerop(l, fn, Rpt(or,co), fp, o->back)
18:
19: /* For the portion inside, we perform the function */
20: #define in(r) (*fn)(l, r, (l?l->obs:0), fp, o)
21:
22: #define C_DONE 0
23: #define C_UP 1
24: #define C_LEFT 2
25: #define C_MID 3
26: #define C_RIGHT 4
27: #define C_DOWN 5
28:
29: int blitdir = 0; /* direction from source to destination */
30:
31: /*
32: * directions: 0 = up and left,
33: * 1 = up and right,
34: * 2 = down and left,
35: * 3 = down and right
36: */
37:
38: static short nextcase[4][6] = {
39: C_UP, C_LEFT, C_MID, C_RIGHT, C_DOWN, C_DONE,
40: C_UP, C_RIGHT, C_MID, C_LEFT, C_DOWN, C_DONE,
41: C_DOWN, C_LEFT, C_MID, C_RIGHT, C_UP, C_DONE,
42: C_DOWN, C_RIGHT, C_MID, C_LEFT, C_UP, C_DONE,
43: };
44:
45: mRlayerop(l, fn, r, fp, o)
46: register Layer *l;
47: void (*fn)();
48: Rectangle r; /* Screen coords */
49: int *fp;
50: register Layer *o;
51: {
52: Rectangle clipr;
53: register Rectangle *rp= &r, *cp= &clipr, *bp;
54: register short *next;
55:
56: *cp = *rp;
57: Top:
58: bp= &o->rect;
59: if((o==l) || (o==0)) /* We have a piece that wasn't obscured */
60: (*fn)(l, r, l, fp, o);
61: else if (rectclip(cp, *bp)==0) { /* note side-effect to clipr */
62: o=o->back; /* efficiency hack */
63: goto Top;
64: } else {
65: /* They must overlap */
66: for (next=&nextcase[blitdir][0]; *next != C_DONE; )
67: switch(*next++) {
68: case C_UP:
69: if (rp->origin.y<bp->origin.y)
70: out(rp->origin,
71: Pt(rp->corner.x, bp->origin.y));
72: break;
73: case C_DOWN:
74: if (rp->corner.y>bp->corner.y)
75: out(Pt(rp->origin.x, bp->corner.y),
76: rp->corner);
77: break;
78: case C_LEFT:
79: if (rp->origin.x<bp->origin.x)
80: out(Pt(rp->origin.x, cp->origin.y),
81: Pt(bp->origin.x, cp->corner.y));
82: break;
83: case C_RIGHT:
84: if (rp->corner.x>bp->corner.x)
85: out(Pt(bp->corner.x, cp->origin.y),
86: Pt(rp->corner.x, cp->corner.y));
87: break;
88: case C_MID:
89: in(*cp);
90: break;
91: }
92: }
93: }
94:
95: /*
96: * Clip to outer rectangle of layer, then call layerop
97: */
98: /*VARARGS3*/
99: layerop(l, fn, r, f)
100: register Layer *l;
101: void (*fn)();
102: Rectangle r; /* Screen coords */
103: int f;
104: {
105: if(l && (rectclip(&r, l->rect)==0))
106: return;
107: if (l && (l->someobs == l->nonevis))
108: (*fn)(l, r, l->nonevis?l->obs:(Bitmap *)l, &f,
109: (l->nonevis?lfront:l));
110: else
111: mRlayerop(l, fn, r, &f, lfront);
112: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.