|
|
1.1 ! root 1: #include <u.h> ! 2: #include <libg.h> ! 3: #include <gnot.h> ! 4: ! 5: #define PSHIFT(x, y) {if(LENDIAN) x <<= y; else x >>= y;} ! 6: ! 7: int ! 8: _setdda(int x, int y, Linedesc *l) ! 9: { ! 10: int e; ! 11: ! 12: /* ! 13: * Unfold all the symmetry folded out in gsetline() ! 14: */ ! 15: if(l->slopeneg == 0) ! 16: e = ((2*(x-l->x0)+2)*l->dminor ! 17: -(2*(y-l->y0)+1)*l->dmajor); ! 18: else{ ! 19: if(l->xmajor) ! 20: e = ((2*(x-l->x0)+2)*l->dminor ! 21: +(2*(l->y0+y)-1)*l->dmajor); ! 22: else ! 23: e = ((2*(l->x0-x)+2)*l->dminor ! 24: -(2*(l->y0+y)+1)*l->dmajor)-1; ! 25: } ! 26: return e; ! 27: } ! 28: ! 29: /* ! 30: * Strange, usually fast line code. ! 31: * Based on the observation that given src and f, src is constant ! 32: * for the call, so we can reduce f by that symmetry. Then we can ! 33: * reduce it again by choosing the src we actually run with; thus ! 34: * src, f -> src', f' ! 35: * In the code, src is replicated through the register m. ! 36: * The f's we choose (they are somewhat arbitrary) are ! 37: * f(0) = S & D ! 38: * and ! 39: * f(1) = S | ~D, ! 40: * chosen by the bits of the incoming f. In particular, if ! 41: * src == 0 ! 42: * we select ! 43: * f' = f&1, src' = (f&2) >> 1 ! 44: * else ! 45: * f' = (f>>2)&1, src' = ((f>>2)&2) >> 1 ! 46: * If src is all 1's or all 0's (guaranteed true on a 1-bit display), ! 47: * this is all we need; otherwise (the slower case) we insert into the dest ! 48: * twice: once for the 1 bits in src, once for the 0 bits, using f' and src' ! 49: * each computed as above. ! 50: */ ! 51: ! 52: void ! 53: gsegment(GBitmap *b, Point p, Point q, int src, Fcode f) ! 54: { ! 55: int i, dw, dx, dy; ! 56: int e, e1, e2; ! 57: uchar m, m1, k, k0, k1, f0, f1, lom, him, him0, him1, t, *dest; ! 58: int ld, bpp, xshift; ! 59: int m0, lo, lo0, lo1, kk, kk0, kk1; ! 60: Linedesc l; ! 61: ! 62: if(!_clipline(b->clipr, &p, &q, &l)) ! 63: return; ! 64: /* line is now clipped and closed */ ! 65: dx = q.x - p.x; ! 66: dy = q.y - p.y; ! 67: if(dx < 0) /* can't happen, but breaks code if it does */ ! 68: return; ! 69: ! 70: ld = b->ldepth; ! 71: bpp = 8>>(3-ld); ! 72: lom = ((1<<bpp)-1); ! 73: him = lom<<(8-bpp); ! 74: xshift = (p.x&(7>>ld))<<ld; ! 75: if(LENDIAN) ! 76: xshift = 8-bpp - xshift; ! 77: k = him>>xshift; /* mask */ ! 78: lo = src&lom; ! 79: ! 80: if(lo==lom || lo==0){ ! 81: /* ! 82: * set new f, new src ! 83: */ ! 84: if(lo) ! 85: f >>= 2; ! 86: f &= 3; ! 87: if(f & 2) ! 88: lo = lom; ! 89: else ! 90: lo = 0; ! 91: f &= 1; ! 92: /* ! 93: * develop m as a register full of pixels containing 'lo1' ! 94: */ ! 95: m = lo; ! 96: for(i=1<<ld; i<8; i+=i) ! 97: m |= m<<i; ! 98: }else{ ! 99: /* ! 100: * set *1 for 1 bits; *0 for 0 bits ! 101: */ ! 102: f1 = (f>>2)&3; ! 103: if(f1 & 2) ! 104: lo1 = lom & lo; ! 105: else ! 106: lo1 = 0; ! 107: f1 &= 1; ! 108: him1 = (lom&lo)<<(8-bpp); ! 109: k1 = him1>>xshift; /* mask */ ! 110: f0 = f&3; ! 111: if(f0 & 2) ! 112: lo0 = lom & ~lo; ! 113: else ! 114: lo0 = 0; ! 115: f0 &= 1; ! 116: him0 = (lom&~lo)<<(8-bpp); ! 117: k0 = him0>>xshift; /* mask */ ! 118: /* ! 119: * develop m0, m1 as a register full of pixels containing 'lo1' ! 120: */ ! 121: m0 = lo0; ! 122: m1 = lo1; ! 123: for(i=1<<ld; i<8; i+=i){ ! 124: m0 |= m0<<i; ! 125: m1 |= m1<<i; ! 126: } ! 127: f = 2; ! 128: } ! 129: ! 130: if(LENDIAN){ ! 131: him >>= 8-bpp; ! 132: him0 >>= 8-bpp; ! 133: him1 >>= 8-bpp; ! 134: } ! 135: ! 136: dw = b->width*sizeof(ulong); ! 137: if(dy < 0){ ! 138: dw = -dw; ! 139: dy = -dy; ! 140: } ! 141: dest = (uchar*)gaddr(b, p) + ((p.x&(31>>ld))>>(3-ld)); ! 142: e1 = 2*l.dminor; ! 143: e2 = e1 - 2*l.dmajor; ! 144: if(l.xmajor == 0) ! 145: goto majory; ! 146: ! 147: majorx: ! 148: e = _setdda(p.x, p.y, &l); ! 149: switch(f){ ! 150: case 0: ! 151: kk = 0; ! 152: for(i=dx; i>=0; i--){ ! 153: kk |= k; ! 154: PSHIFT(k, bpp); ! 155: if(e >= 0){ ! 156: *dest &= m|~kk; ! 157: dest += dw; ! 158: e += e2; ! 159: kk = 0; ! 160: if(k == 0){ ! 161: k = him; ! 162: dest++; ! 163: } ! 164: continue; ! 165: } ! 166: e += e1; ! 167: if(k == 0){ ! 168: k = him; ! 169: *dest &= m|~kk; ! 170: dest++; ! 171: kk = 0; ! 172: } ! 173: } ! 174: if(kk) ! 175: *dest &= m|~kk; ! 176: return; ! 177: ! 178: case 1: ! 179: kk = 0; ! 180: for(i=dx; i>=0; i--){ ! 181: kk |= k; ! 182: PSHIFT(k, bpp); ! 183: if(e >= 0){ ! 184: t = *dest; ! 185: *dest = (kk ^ t) | (t & m); ! 186: dest += dw; ! 187: e += e2; ! 188: kk = 0; ! 189: if(k == 0){ ! 190: k = him; ! 191: dest++; ! 192: } ! 193: continue; ! 194: } ! 195: e += e1; ! 196: if(k == 0){ ! 197: t = *dest; ! 198: *dest = (kk ^ t) | (t & m); ! 199: dest++; ! 200: k = him; ! 201: kk = 0; ! 202: } ! 203: } ! 204: if(kk){ ! 205: t = *dest; ! 206: *dest = (kk ^ t) | (t & m); ! 207: } ! 208: return; ! 209: ! 210: case 2: ! 211: kk = 0; ! 212: kk0 = 0; ! 213: kk1 = 0; ! 214: for(i=dx; i>=0; i--){ ! 215: kk |= k; ! 216: kk0 |= k0; ! 217: kk1 |= k1; ! 218: PSHIFT(k, bpp); ! 219: PSHIFT(k0, bpp); ! 220: PSHIFT(k1, bpp); ! 221: if(e >= 0){ ! 222: t = *dest; ! 223: if(f0 == 0) ! 224: t &= m0|~kk0; ! 225: else ! 226: t = (kk0 ^ t) | (t & m0); ! 227: if(f1 == 0) ! 228: *dest = t & (m1|~kk1); ! 229: else ! 230: *dest = (kk1 ^ t) | (t & m1); ! 231: dest += dw; ! 232: e += e2; ! 233: kk = 0; ! 234: kk0 = 0; ! 235: kk1 = 0; ! 236: if(k == 0){ ! 237: k = him; ! 238: k0 = him0; ! 239: k1 = him1; ! 240: dest++; ! 241: } ! 242: continue; ! 243: } ! 244: e += e1; ! 245: if(k == 0){ ! 246: t = *dest; ! 247: if(f0 == 0) ! 248: t &= m0|~kk0; ! 249: else ! 250: t = (kk0 ^ t) | (t & m0); ! 251: if(f1 == 0) ! 252: *dest = t & (m1|~kk1); ! 253: else ! 254: *dest = (kk1 ^ t) | (t & m1); ! 255: dest++; ! 256: k = him; ! 257: k0 = him0; ! 258: k1 = him1; ! 259: kk = 0; ! 260: kk0 = 0; ! 261: kk1 = 0; ! 262: } ! 263: } ! 264: if(kk){ ! 265: t = *dest; ! 266: if(f0 == 0) ! 267: t &= m0|~kk0; ! 268: else ! 269: t = (kk0 ^ t) | (t & m0); ! 270: if(f1 == 0) ! 271: *dest = t & (m1|~kk1); ! 272: else ! 273: *dest = (kk1 ^ t) | (t & m1); ! 274: } ! 275: return; ! 276: } ! 277: return; ! 278: ! 279: majory: ! 280: e = _setdda(p.y, p.x, &l); ! 281: switch (f){ ! 282: case 0: ! 283: for(i=dy; i>=0; --i){ ! 284: *dest &= m|~k; ! 285: dest += dw; ! 286: if(e >= 0){ ! 287: PSHIFT(k, bpp); ! 288: if(k == 0){ ! 289: dest++; ! 290: k = him; ! 291: } ! 292: e += e2; ! 293: }else ! 294: e += e1; ! 295: } ! 296: return; ! 297: ! 298: case 1: ! 299: for(i=dy; i>=0; --i){ ! 300: t = *dest; ! 301: *dest = (k ^ t) | (t & m); ! 302: dest += dw; ! 303: if(e >= 0){ ! 304: PSHIFT(k, bpp); ! 305: if(k == 0){ ! 306: dest++; ! 307: k = him; ! 308: } ! 309: e += e2; ! 310: }else ! 311: e += e1; ! 312: } ! 313: return; ! 314: ! 315: case 2: ! 316: for(i=dy; i>=0; --i){ ! 317: t = *dest; ! 318: if(f0 == 0) ! 319: t &= m0|~k0; ! 320: else ! 321: t = (k0 ^ t) | (t & m0); ! 322: if(f1 == 0) ! 323: *dest = t & (m1|~k1); ! 324: else ! 325: *dest = (k1 ^ t) | (t & m1); ! 326: dest += dw; ! 327: if(e >= 0){ ! 328: PSHIFT(k, bpp); ! 329: PSHIFT(k0, bpp); ! 330: PSHIFT(k1, bpp); ! 331: if(k == 0){ ! 332: dest++; ! 333: k = him; ! 334: k0 = him0; ! 335: k1 = him1; ! 336: } ! 337: e += e2; ! 338: }else ! 339: e += e1; ! 340: } ! 341: } ! 342: return; ! 343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.