|
|
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.