|
|
1.1 root 1: #include <u.h>
2: #include <libg.h>
3: #include <gnot.h>
4: #include "tabs.h"
5:
6: #define swizbytes(a) (a)
7:
8: /* a = s (func(f)) d, where f involves d */
9: #define fcodefun(a,s,d,f) switch(f) {\
10: case DnorS: a = ~((d)|(s)); break; \
11: case DandnotS: a = (d)&~(s); break; \
12: case notDandS: a = ~(d)&(s); break; \
13: case notD: a = ~(d); break; \
14: case DxorS: a = (d)^(s); break; \
15: case DnandS: a = ~((d)&(s)); break; \
16: case DandS: a = (d)&(s); break; \
17: case DxnorS: a = ~((d)^(s)); break; \
18: case D: a = d; break; \
19: case DornotS: a = (d)|~(s); break; \
20: case notDorS: a = ~(d)|(s); break; \
21: case DorS: a = (d)|(s); break; \
22: default: a = d; break; \
23: }
24: /*
25: * texture - uses bitblt, logarithmically if f doesn't involve D
26: * but special case some textures whose rows can be packed in 32 bits
27: */
28:
29: void
30: gtexture(GBitmap *dm, Rectangle r, GBitmap *sm, Fcode f)
31: {
32: Point p, dp;
33: int x, y, d, w, hm, wneed, sld, dld, dunused, sunused, fconst;
34: ulong a, b, c, lmask, rmask, *ps, *pe, *pp, s[32];
35: Rectangle savdr;
36:
37: if(rectclip(&r, dm->clipr) == 0)
38: return;
39: dp = sub(sm->clipr.max, sm->clipr.min);
40: if(dp.x==0 || dp.y==0 || Dx(r)==0 || Dy(r)==0)
41: return;
42: p.x = r.min.x - (r.min.x % dp.x);
43: p.y = r.min.y - (r.min.y % dp.y);
44: f &= 0xF;
45: sld = sm->ldepth;
46: dld = dm->ldepth;
47: w = dp.x << sld;
48: wneed = (dld == sld) ? 32 : 32 >> dld;
49: fconst = (f==F || f==Zero);
50: sunused = (f==D || f==notD || fconst);
51: dunused = (f==S || f==notS || fconst);
52: if(sunused ||
53: ((sld == 0 && !LENDIAN || sld == dld) &&
54: sm->clipr.min.x == 0 && sm->r.min.x == 0 &&
55: sm->clipr.min.y == 0 && sm->r.min.y == 0 &&
56: w <= wneed && wneed%w == 0 &&
57: dp.y <= 32 && (dp.y&(dp.y-1))==0)) {
58: /* 32-bit word tiling; replicate/convert rows into s[] */
59: if (sunused) {
60: dp.y = 1;
61: s[0] = (f==F)? ~0 : 0;
62: } else for(y = 0; y < dp.y; y++) {
63: /* we know sm rows fit in a word */
64: a = swizbytes(sm->base[y]);
65: if(w < wneed) {
66: if(LENDIAN){
67: b = a;
68: for(x = w; x < 32; x += w)
69: a |= b << x;
70: }else{
71: b = a >> (32-w);
72: for(x = w; x < 32; x += w)
73: a |= b << (32-x-w);
74: }
75: }
76: if(sld != dld)
77: switch(dld) {
78: case 1:
79: a = (tab01[a>>24]<<16) |
80: tab01[(a>>16)&0xFF];
81: break;
82: case 2:
83: a = tab02[a>>24];
84: break;
85: case 3:
86: a = tab03[a>>28];
87: break;
88: default:
89: /* don't do ldepth > 3 yet */
90: return;
91: }
92: if(f == notS)
93: a = ~a;
94: if(!dunused) {
95: /* rotate right to get aligned */
96: b = (p.x << dld) % 32;
97: if(b)
98: a = (a >> b) | (a << (32-b));
99: }
100: s[y] = swizbytes(a);
101: }
102: a = (r.min.x<<dld)&31;
103: if(LENDIAN){
104: lmask = ~0UL << a;
105: rmask = ~0UL >> (32-((r.max.x<<dld))&31);
106: }else{
107: lmask = ~0UL >> a;
108: rmask = ~0UL << (32-((r.max.x<<dld))&31);
109: }
110: if(!rmask)
111: rmask = ~0;
112: ps = gaddr(dm, r.min);
113: pe = gaddr(dm, Pt(r.max.x-1, r.min.y));
114: lmask = swizbytes(lmask);
115: rmask = swizbytes(rmask);
116: if(pe == ps)
117: lmask &= rmask;
118: w = dm->width;
119: hm = dp.y-1; /* we know dp.y is a power of 2 */
120: if (dunused) {
121: for(y = r.min.y; y < r.max.y; y++) {
122: a = s[y&hm];
123: b = *ps;
124: *ps = ((a^b)&lmask)^b;
125: if(ps < pe) {
126: for(pp = ps+1; pp<pe; )
127: *pp++ = a;
128: b = *pe;
129: *pe = ((a^b)&rmask)^b;
130: }
131: ps += w;
132: pe += w;
133: }
134: } else {
135: for(y = r.min.y; y < r.max.y; y++) {
136: a = s[y&hm];
137: b = *ps;
138: fcodefun(c,a,b,f)
139: *ps = ((c^b)&lmask)^b;
140: if(ps < pe) {
141: for(pp = ps+1; pp<pe; ) {
142: b = *pp;
143: fcodefun(c,a,b,f)
144: *pp++ = c;
145: }
146: b = *pe;
147: fcodefun(c,a,b,f)
148: *pe = ((c^b)&rmask)^b;
149: }
150: ps += w;
151: pe += w;
152: }
153: }
154: } else if(dunused){
155: /* logarithmic tiling */
156: savdr = dm->clipr;
157: rectclip(&dm->clipr, r);
158: if(!eqpt(p, r.min)){
159: gbitblt(dm, p, sm, sm->clipr, f);
160: d = dp.x;
161: x = p.x+d;
162: if(x<r.max.x){
163: gbitblt(dm, Pt(x, p.y), sm, sm->clipr, f);
164: for(; x+d<r.max.x; d+=d)
165: gbitblt(dm, Pt(x+d, p.y), dm,
166: Rect(x, p.y, x+d, p.y+dp.y), S);
167: }
168: d = dp.y;
169: y = p.y+d;
170: if(y<r.max.y){
171: gbitblt(dm, Pt(p.x,y), sm, sm->clipr, f);
172: for(; y+d<r.max.y; d+=d)
173: gbitblt(dm, Pt(p.x, y+d), dm,
174: Rect(p.x, y, p.x+dp.x, y+d), S);
175: }
176: p = add(p, dp);
177: }
178: if(p.x<r.max.x && p.y<r.max.y){
179: gbitblt(dm, p, sm, sm->clipr, f);
180: for(d=dp.x; p.x+d<r.max.x; d+=d)
181: gbitblt(dm, Pt(p.x+d, p.y), dm,
182: Rect(p.x, p.y, p.x+d, p.y+dp.y), S);
183: for(d=dp.y; p.y+d<r.max.y; d+=d)
184: gbitblt(dm, Pt(p.x, p.y+d), dm,
185: Rect(p.x, p.y, r.max.x, p.y+d), S);
186: }
187: dm->clipr = savdr;
188: }else{
189: savdr = dm->clipr;
190: rectclip(&dm->clipr, r);
191: for(y=p.y; y<r.max.y; y+=dp.y)
192: for(x=p.x; x<r.max.x; x+=dp.x)
193: gbitblt(dm, Pt(x, y), sm, sm->clipr, f);
194: dm->clipr = savdr;
195: }
196: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.