From 74dc60da74c62e07f0d63179da9724d705794a6d Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 25 Jun 2006 18:59:29 +0000 Subject: bye --- src/libdraw/md-draw.c | 2489 ------------------------------------------------- 1 file changed, 2489 deletions(-) delete mode 100644 src/libdraw/md-draw.c (limited to 'src/libdraw/md-draw.c') diff --git a/src/libdraw/md-draw.c b/src/libdraw/md-draw.c deleted file mode 100644 index 2d8681e5..00000000 --- a/src/libdraw/md-draw.c +++ /dev/null @@ -1,2489 +0,0 @@ -#include -#include -#include -#include - -int drawdebug; -static int tablesbuilt; - -/* perfect approximation to NTSC = .299r+.587g+.114b when 0 ≤ r,g,b < 256 */ -#define RGB2K(r,g,b) ((156763*(r)+307758*(g)+59769*(b))>>19) - -/* - * for 0 ≤ x ≤ 255*255, (x*0x0101+0x100)>>16 is a perfect approximation. - * for 0 ≤ x < (1<<16), x/255 = ((x+1)*0x0101)>>16 is a perfect approximation. - * the last one is perfect for all up to 1<<16, avoids a multiply, but requires a rathole. - */ -/* #define DIV255(x) (((x)*257+256)>>16) */ -#define DIV255(x) ((((x)+1)*257)>>16) -/* #define DIV255(x) (tmp=(x)+1, (tmp+(tmp>>8))>>8) */ - -#define MUL(x, y, t) (t = (x)*(y)+128, (t+(t>>8))>>8) -#define MASK13 0xFF00FF00 -#define MASK02 0x00FF00FF -#define MUL13(a, x, t) (t = (a)*(((x)&MASK13)>>8)+128, ((t+((t>>8)&MASK02))>>8)&MASK02) -#define MUL02(a, x, t) (t = (a)*(((x)&MASK02)>>0)+128, ((t+((t>>8)&MASK02))>>8)&MASK02) -#define MUL0123(a, x, s, t) ((MUL13(a, x, s)<<8)|MUL02(a, x, t)) - -#define MUL2(u, v, x, y) (t = (u)*(v)+(x)*(y)+256, (t+(t>>8))>>8) - -static void mktables(void); -typedef int Subdraw(Memdrawparam*); -static Subdraw chardraw, alphadraw, memoptdraw; - -static Memimage* memones; -static Memimage* memzeros; -Memimage *memwhite; -Memimage *memblack; -Memimage *memtransparent; -Memimage *memopaque; - -int __ifmt(Fmt*); - -void -memimageinit(void) -{ - static int didinit = 0; - - if(didinit) - return; - - didinit = 1; - - mktables(); - _memmkcmap(); - - fmtinstall('R', Rfmt); - fmtinstall('P', Pfmt); - fmtinstall('b', __ifmt); - - memones = allocmemimage(Rect(0,0,1,1), GREY1); - memones->flags |= Frepl; - memones->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); - *byteaddr(memones, ZP) = ~0; - - memzeros = allocmemimage(Rect(0,0,1,1), GREY1); - memzeros->flags |= Frepl; - memzeros->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); - *byteaddr(memzeros, ZP) = 0; - - if(memones == nil || memzeros == nil) - assert(0 /*cannot initialize memimage library */); /* RSC BUG */ - - memwhite = memones; - memblack = memzeros; - memopaque = memones; - memtransparent = memzeros; -} - -u32int _imgtorgba(Memimage*, u32int); -u32int _rgbatoimg(Memimage*, u32int); -u32int _pixelbits(Memimage*, Point); - -#define DBG if(drawdebug) -static Memdrawparam par; - -Memdrawparam* -_memimagedrawsetup(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1, int op) -{ - if(mask == nil) - mask = memopaque; - -DBG print("memimagedraw %p/%luX %R @ %p %p/%luX %P %p/%luX %P... ", dst, dst->chan, r, dst->data->bdata, src, src->chan, p0, mask, mask->chan, p1); - - if(drawclip(dst, &r, src, &p0, mask, &p1, &par.sr, &par.mr) == 0){ -/* if(drawdebug) */ -/* iprint("empty clipped rectangle\n"); */ - return nil; - } - - if(op < Clear || op > SoverD){ -/* if(drawdebug) */ -/* iprint("op out of range: %d\n", op); */ - return nil; - } - - par.op = op; - par.dst = dst; - par.r = r; - par.src = src; - /* par.sr set by drawclip */ - par.mask = mask; - /* par.mr set by drawclip */ - - par.state = 0; - if(src->flags&Frepl){ - par.state |= Replsrc; - if(Dx(src->r)==1 && Dy(src->r)==1){ - par.sval = pixelbits(src, src->r.min); - par.state |= Simplesrc; - par.srgba = _imgtorgba(src, par.sval); - par.sdval = _rgbatoimg(dst, par.srgba); - if((par.srgba&0xFF) == 0 && (op&DoutS)){ -/* if (drawdebug) iprint("fill with transparent source\n"); */ - return nil; /* no-op successfully handled */ - } - if((par.srgba&0xFF) == 0xFF) - par.state |= Fullsrc; - } - } - - if(mask->flags & Frepl){ - par.state |= Replmask; - if(Dx(mask->r)==1 && Dy(mask->r)==1){ - par.mval = pixelbits(mask, mask->r.min); - if(par.mval == 0 && (op&DoutS)){ -/* if(drawdebug) iprint("fill with zero mask\n"); */ - return nil; /* no-op successfully handled */ - } - par.state |= Simplemask; - if(par.mval == ~0) - par.state |= Fullmask; - par.mrgba = _imgtorgba(mask, par.mval); - } - } - -/* if(drawdebug) */ -/* iprint("dr %R sr %R mr %R...", r, par.sr, par.mr); */ -DBG print("draw dr %R sr %R mr %R %lux\n", r, par.sr, par.mr, par.state); - - return ∥ -} - -void -_memimagedraw(Memdrawparam *par) -{ - /* - * Now that we've clipped the parameters down to be consistent, we - * simply try sub-drawing routines in order until we find one that was able - * to handle us. If the sub-drawing routine returns zero, it means it was - * unable to satisfy the request, so we do not return. - */ - - /* - * Hardware support. Each video driver provides this function, - * which checks to see if there is anything it can help with. - * There could be an if around this checking to see if dst is in video memory. - */ -DBG print("test hwdraw\n"); - if(hwdraw(par)){ -/*if(drawdebug) iprint("hw handled\n"); */ -DBG print("hwdraw handled\n"); - return; - } - /* - * Optimizations using memmove and memset. - */ -DBG print("test memoptdraw\n"); - if(memoptdraw(par)){ -/*if(drawdebug) iprint("memopt handled\n"); */ -DBG print("memopt handled\n"); - return; - } - - /* - * Character drawing. - * Solid source color being painted through a boolean mask onto a high res image. - */ -DBG print("test chardraw\n"); - if(chardraw(par)){ -/*if(drawdebug) iprint("chardraw handled\n"); */ -DBG print("chardraw handled\n"); - return; - } - - /* - * General calculation-laden case that does alpha for each pixel. - */ -DBG print("do alphadraw\n"); - alphadraw(par); -/*if(drawdebug) iprint("alphadraw handled\n"); */ -DBG print("alphadraw handled\n"); -} -#undef DBG - -/* - * Clip the destination rectangle further based on the properties of the - * source and mask rectangles. Once the destination rectangle is properly - * clipped, adjust the source and mask rectangles to be the same size. - * Then if source or mask is replicated, move its clipped rectangle - * so that its minimum point falls within the repl rectangle. - * - * Return zero if the final rectangle is null. - */ -int -drawclip(Memimage *dst, Rectangle *r, Memimage *src, Point *p0, Memimage *mask, Point *p1, Rectangle *sr, Rectangle *mr) -{ - Point rmin, delta; - int splitcoords; - Rectangle omr; - - if(r->min.x>=r->max.x || r->min.y>=r->max.y) - return 0; - splitcoords = (p0->x!=p1->x) || (p0->y!=p1->y); - /* clip to destination */ - rmin = r->min; - if(!rectclip(r, dst->r) || !rectclip(r, dst->clipr)) - return 0; - /* move mask point */ - p1->x += r->min.x-rmin.x; - p1->y += r->min.y-rmin.y; - /* move source point */ - p0->x += r->min.x-rmin.x; - p0->y += r->min.y-rmin.y; - /* map destination rectangle into source */ - sr->min = *p0; - sr->max.x = p0->x+Dx(*r); - sr->max.y = p0->y+Dy(*r); - /* sr is r in source coordinates; clip to source */ - if(!(src->flags&Frepl) && !rectclip(sr, src->r)) - return 0; - if(!rectclip(sr, src->clipr)) - return 0; - /* compute and clip rectangle in mask */ - if(splitcoords){ - /* move mask point with source */ - p1->x += sr->min.x-p0->x; - p1->y += sr->min.y-p0->y; - mr->min = *p1; - mr->max.x = p1->x+Dx(*sr); - mr->max.y = p1->y+Dy(*sr); - omr = *mr; - /* mr is now rectangle in mask; clip it */ - if(!(mask->flags&Frepl) && !rectclip(mr, mask->r)) - return 0; - if(!rectclip(mr, mask->clipr)) - return 0; - /* reflect any clips back to source */ - sr->min.x += mr->min.x-omr.min.x; - sr->min.y += mr->min.y-omr.min.y; - sr->max.x += mr->max.x-omr.max.x; - sr->max.y += mr->max.y-omr.max.y; - *p1 = mr->min; - }else{ - if(!(mask->flags&Frepl) && !rectclip(sr, mask->r)) - return 0; - if(!rectclip(sr, mask->clipr)) - return 0; - *p1 = sr->min; - } - - /* move source clipping back to destination */ - delta.x = r->min.x - p0->x; - delta.y = r->min.y - p0->y; - r->min.x = sr->min.x + delta.x; - r->min.y = sr->min.y + delta.y; - r->max.x = sr->max.x + delta.x; - r->max.y = sr->max.y + delta.y; - - /* move source rectangle so sr->min is in src->r */ - if(src->flags&Frepl) { - delta.x = drawreplxy(src->r.min.x, src->r.max.x, sr->min.x) - sr->min.x; - delta.y = drawreplxy(src->r.min.y, src->r.max.y, sr->min.y) - sr->min.y; - sr->min.x += delta.x; - sr->min.y += delta.y; - sr->max.x += delta.x; - sr->max.y += delta.y; - } - *p0 = sr->min; - - /* move mask point so it is in mask->r */ - *p1 = drawrepl(mask->r, *p1); - mr->min = *p1; - mr->max.x = p1->x+Dx(*sr); - mr->max.y = p1->y+Dy(*sr); - - assert(Dx(*sr) == Dx(*mr) && Dx(*mr) == Dx(*r)); - assert(Dy(*sr) == Dy(*mr) && Dy(*mr) == Dy(*r)); - assert(ptinrect(*p0, src->r)); - assert(ptinrect(*p1, mask->r)); - assert(ptinrect(r->min, dst->r)); - - return 1; -} - -/* - * Conversion tables. - */ -static uchar replbit[1+8][256]; /* replbit[x][y] is the replication of the x-bit quantity y to 8-bit depth */ -static uchar conv18[256][8]; /* conv18[x][y] is the yth pixel in the depth-1 pixel x */ -static uchar conv28[256][4]; /* ... */ -static uchar conv48[256][2]; - -/* - * bitmap of how to replicate n bits to fill 8, for 1 ≤ n ≤ 8. - * the X's are where to put the bottom (ones) bit of the n-bit pattern. - * only the top 8 bits of the result are actually used. - * (the lower 8 bits are needed to get bits in the right place - * when n is not a divisor of 8.) - * - * Should check to see if its easier to just refer to replmul than - * use the precomputed values in replbit. On PCs it may well - * be; on machines with slow multiply instructions it probably isn't. - */ -#define a ((((((((((((((((0 -#define X *2+1) -#define _ *2) -static int replmul[1+8] = { - 0, - a X X X X X X X X X X X X X X X X, - a _ X _ X _ X _ X _ X _ X _ X _ X, - a _ _ X _ _ X _ _ X _ _ X _ _ X _, - a _ _ _ X _ _ _ X _ _ _ X _ _ _ X, - a _ _ _ _ X _ _ _ _ X _ _ _ _ X _, - a _ _ _ _ _ X _ _ _ _ _ X _ _ _ _, - a _ _ _ _ _ _ X _ _ _ _ _ _ X _ _, - a _ _ _ _ _ _ _ X _ _ _ _ _ _ _ X, -}; -#undef a -#undef X -#undef _ - -static void -mktables(void) -{ - int i, j, mask, sh, small; - - if(tablesbuilt) - return; - - fmtinstall('R', Rfmt); - fmtinstall('P', Pfmt); - tablesbuilt = 1; - - /* bit replication up to 8 bits */ - for(i=0; i<256; i++){ - for(j=0; j<=8; j++){ /* j <= 8 [sic] */ - small = i & ((1<>8; - } - } - - /* bit unpacking up to 8 bits, only powers of 2 */ - for(i=0; i<256; i++){ - for(j=0, sh=7, mask=1; j<8; j++, sh--) - conv18[i][j] = replbit[1][(i>>sh)&mask]; - - for(j=0, sh=6, mask=3; j<4; j++, sh-=2) - conv28[i][j] = replbit[2][(i>>sh)&mask]; - - for(j=0, sh=4, mask=15; j<2; j++, sh-=4) - conv48[i][j] = replbit[4][(i>>sh)&mask]; - } -} - -static uchar ones = 0xff; - -/* - * General alpha drawing case. Can handle anything. - */ -typedef struct Buffer Buffer; -struct Buffer { - /* used by most routines */ - uchar *red; - uchar *grn; - uchar *blu; - uchar *alpha; - uchar *grey; - u32int *rgba; - int delta; /* number of bytes to add to pointer to get next pixel to the right */ - - /* used by boolcalc* for mask data */ - uchar *m; /* ptr to mask data r.min byte; like p->bytermin */ - int mskip; /* no. of left bits to skip in *m */ - uchar *bm; /* ptr to mask data img->r.min byte; like p->bytey0s */ - int bmskip; /* no. of left bits to skip in *bm */ - uchar *em; /* ptr to mask data img->r.max.x byte; like p->bytey0e */ - int emskip; /* no. of right bits to skip in *em */ -}; - -typedef struct Param Param; -typedef Buffer Readfn(Param*, uchar*, int); -typedef void Writefn(Param*, uchar*, Buffer); -typedef Buffer Calcfn(Buffer, Buffer, Buffer, int, int, int); - -enum { - MAXBCACHE = 16 -}; - -/* giant rathole to customize functions with */ -struct Param { - Readfn *replcall; - Readfn *greymaskcall; - Readfn *convreadcall; - Writefn *convwritecall; - - Memimage *img; - Rectangle r; - int dx; /* of r */ - int needbuf; - int convgrey; - int alphaonly; - - uchar *bytey0s; /* byteaddr(Pt(img->r.min.x, img->r.min.y)) */ - uchar *bytermin; /* byteaddr(Pt(r.min.x, img->r.min.y)) */ - uchar *bytey0e; /* byteaddr(Pt(img->r.max.x, img->r.min.y)) */ - int bwidth; - - int replcache; /* if set, cache buffers */ - Buffer bcache[MAXBCACHE]; - u32int bfilled; - uchar *bufbase; - int bufoff; - int bufdelta; - - int dir; - - int convbufoff; - uchar *convbuf; - Param *convdpar; - int convdx; -}; - -static uchar *drawbuf; -static int ndrawbuf; -static int mdrawbuf; -static Param spar, mpar, dpar; /* easier on the stacks */ -static Readfn greymaskread, replread, readptr; -static Writefn nullwrite; -static Calcfn alphacalc0, alphacalc14, alphacalc2810, alphacalc3679, alphacalc5, alphacalc11, alphacalcS; -static Calcfn boolcalc14, boolcalc236789, boolcalc1011; - -static Readfn* readfn(Memimage*); -static Readfn* readalphafn(Memimage*); -static Writefn* writefn(Memimage*); - -static Calcfn* boolcopyfn(Memimage*, Memimage*); -static Readfn* convfn(Memimage*, Param*, Memimage*, Param*); - -static Calcfn *alphacalc[Ncomp] = -{ - alphacalc0, /* Clear */ - alphacalc14, /* DoutS */ - alphacalc2810, /* SoutD */ - alphacalc3679, /* DxorS */ - alphacalc14, /* DinS */ - alphacalc5, /* D */ - alphacalc3679, /* DatopS */ - alphacalc3679, /* DoverS */ - alphacalc2810, /* SinD */ - alphacalc3679, /* SatopD */ - alphacalc2810, /* S */ - alphacalc11, /* SoverD */ -}; - -static Calcfn *boolcalc[Ncomp] = -{ - alphacalc0, /* Clear */ - boolcalc14, /* DoutS */ - boolcalc236789, /* SoutD */ - boolcalc236789, /* DxorS */ - boolcalc14, /* DinS */ - alphacalc5, /* D */ - boolcalc236789, /* DatopS */ - boolcalc236789, /* DoverS */ - boolcalc236789, /* SinD */ - boolcalc236789, /* SatopD */ - boolcalc1011, /* S */ - boolcalc1011, /* SoverD */ -}; - -static int -allocdrawbuf(void) -{ - uchar *p; - - if(ndrawbuf > mdrawbuf){ - p = realloc(drawbuf, ndrawbuf); - if(p == nil){ - werrstr("memimagedraw out of memory"); - return -1; - } - drawbuf = p; - mdrawbuf = ndrawbuf; - } - return 0; -} - -static void -getparam(Param *p, Memimage *img, Rectangle r, int convgrey, int needbuf) -{ - int nbuf; - - memset(p, 0, sizeof *p); - - p->img = img; - p->r = r; - p->dx = Dx(r); - p->needbuf = needbuf; - p->convgrey = convgrey; - - assert(img->r.min.x <= r.min.x && r.min.x < img->r.max.x); - - p->bytey0s = byteaddr(img, Pt(img->r.min.x, img->r.min.y)); - p->bytermin = byteaddr(img, Pt(r.min.x, img->r.min.y)); - p->bytey0e = byteaddr(img, Pt(img->r.max.x, img->r.min.y)); - p->bwidth = sizeof(u32int)*img->width; - - assert(p->bytey0s <= p->bytermin && p->bytermin <= p->bytey0e); - - if(p->r.min.x == p->img->r.min.x) - assert(p->bytermin == p->bytey0s); - - nbuf = 1; - if((img->flags&Frepl) && Dy(img->r) <= MAXBCACHE && Dy(img->r) < Dy(r)){ - p->replcache = 1; - nbuf = Dy(img->r); - } - p->bufdelta = 4*p->dx; - p->bufoff = ndrawbuf; - ndrawbuf += p->bufdelta*nbuf; -} - -static void -clipy(Memimage *img, int *y) -{ - int dy; - - dy = Dy(img->r); - if(*y == dy) - *y = 0; - else if(*y == -1) - *y = dy-1; - assert(0 <= *y && *y < dy); -} - -static void -dumpbuf(char *s, Buffer b, int n) -{ - int i; - uchar *p; - - print("%s", s); - for(i=0; ir); - r = par->r; - dx = Dx(r); - dy = Dy(r); - - ndrawbuf = 0; - - src = par->src; - mask = par->mask; - dst = par->dst; - sr = par->sr; - mr = par->mr; - op = par->op; - - isgrey = dst->flags&Fgrey; - - /* - * Buffering when src and dst are the same bitmap is sufficient but not - * necessary. There are stronger conditions we could use. We could - * check to see if the rectangles intersect, and if simply moving in the - * correct y direction can avoid the need to buffer. - */ - needbuf = (src->data == dst->data); - - getparam(&spar, src, sr, isgrey, needbuf); - getparam(&dpar, dst, r, isgrey, needbuf); - getparam(&mpar, mask, mr, 0, needbuf); - - dir = (needbuf && byteaddr(dst, r.min) > byteaddr(src, sr.min)) ? -1 : 1; - spar.dir = mpar.dir = dpar.dir = dir; - - /* - * If the mask is purely boolean, we can convert from src to dst format - * when we read src, and then just copy it to dst where the mask tells us to. - * This requires a boolean (1-bit grey) mask and lack of a source alpha channel. - * - * The computation is accomplished by assigning the function pointers as follows: - * rdsrc - read and convert source into dst format in a buffer - * rdmask - convert mask to bytes, set pointer to it - * rddst - fill with pointer to real dst data, but do no reads - * calc - copy src onto dst when mask says to. - * wrdst - do nothing - * This is slightly sleazy, since things aren't doing exactly what their names say, - * but it avoids a fair amount of code duplication to make this a case here - * rather than have a separate booldraw. - */ -/*if(drawdebug) iprint("flag %lud mchan %lux=?%x dd %d\n", src->flags&Falpha, mask->chan, GREY1, dst->depth); */ - if(!(src->flags&Falpha) && mask->chan == GREY1 && dst->depth >= 8 && op == SoverD){ -/*if(drawdebug) iprint("boolcopy..."); */ - rdsrc = convfn(dst, &dpar, src, &spar); - rddst = readptr; - rdmask = readfn(mask); - calc = boolcopyfn(dst, mask); - wrdst = nullwrite; - }else{ - /* usual alphadraw parameter fetching */ - rdsrc = readfn(src); - rddst = readfn(dst); - wrdst = writefn(dst); - calc = alphacalc[op]; - - /* - * If there is no alpha channel, we'll ask for a grey channel - * and pretend it is the alpha. - */ - if(mask->flags&Falpha){ - rdmask = readalphafn(mask); - mpar.alphaonly = 1; - }else{ - mpar.greymaskcall = readfn(mask); - mpar.convgrey = 1; - rdmask = greymaskread; - - /* - * Should really be above, but then boolcopyfns would have - * to deal with bit alignment, and I haven't written that. - * - * This is a common case for things like ellipse drawing. - * When there's no alpha involved and the mask is boolean, - * we can avoid all the division and multiplication. - */ - if(mask->chan == GREY1 && !(src->flags&Falpha)) - calc = boolcalc[op]; - else if(op == SoverD && !(src->flags&Falpha)) - calc = alphacalcS; - } - } - - /* - * If the image has a small enough repl rectangle, - * we can just read each line once and cache them. - */ - if(spar.replcache){ - spar.replcall = rdsrc; - rdsrc = replread; - } - if(mpar.replcache){ - mpar.replcall = rdmask; - rdmask = replread; - } - - if(allocdrawbuf() < 0) - return 0; - - /* - * Before we were saving only offsets from drawbuf in the parameter - * structures; now that drawbuf has been grown to accomodate us, - * we can fill in the pointers. - */ - spar.bufbase = drawbuf+spar.bufoff; - mpar.bufbase = drawbuf+mpar.bufoff; - dpar.bufbase = drawbuf+dpar.bufoff; - spar.convbuf = drawbuf+spar.convbufoff; - - if(dir == 1){ - starty = 0; - endy = dy; - }else{ - starty = dy-1; - endy = -1; - } - - /* - * srcy, masky, and dsty are offsets from the top of their - * respective Rectangles. they need to be contained within - * the rectangles, so clipy can keep them there without division. - */ - srcy = (starty + sr.min.y - src->r.min.y)%Dy(src->r); - masky = (starty + mr.min.y - mask->r.min.y)%Dy(mask->r); - dsty = starty + r.min.y - dst->r.min.y; - - assert(0 <= srcy && srcy < Dy(src->r)); - assert(0 <= masky && masky < Dy(mask->r)); - assert(0 <= dsty && dsty < Dy(dst->r)); - - if(drawdebug) - print("alphadraw: rdsrc=%p rdmask=%p rddst=%p calc=%p wrdst=%p\n", - rdsrc, rdmask, rddst, calc, wrdst); - for(y=starty; y!=endy; y+=dir, srcy+=dir, masky+=dir, dsty+=dir){ - clipy(src, &srcy); - clipy(dst, &dsty); - clipy(mask, &masky); - - bsrc = rdsrc(&spar, spar.bufbase, srcy); -DBG print("["); - bmask = rdmask(&mpar, mpar.bufbase, masky); -DBG print("]\n"); - bdst = rddst(&dpar, dpar.bufbase, dsty); -DBG dumpbuf("src", bsrc, dx); -DBG dumpbuf("mask", bmask, dx); -DBG dumpbuf("dst", bdst, dx); - bdst = calc(bdst, bsrc, bmask, dx, isgrey, op); -DBG dumpbuf("bdst", bdst, dx); - wrdst(&dpar, dpar.bytermin+dsty*dpar.bwidth, bdst); - } - - return 1; -} -#undef DBG - -static Buffer -alphacalc0(Buffer bdst, Buffer b1, Buffer b2, int dx, int grey, int op) -{ - USED(grey); - USED(op); - memset(bdst.rgba, 0, dx*bdst.delta); - return bdst; -} - -static Buffer -alphacalc14(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op) -{ - Buffer obdst; - int fd, sadelta; - int i, sa, ma, q; - u32int s, t; - - obdst = bdst; - sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta; - q = bsrc.delta == 4 && bdst.delta == 4; - - for(i=0; ibcache[y]; - if((p->bfilled & (1<bfilled |= 1<replcall(p, p->bufbase+y*p->bufdelta, y); - } - return *b; -} - -/* - * Alpha reading function that simply relabels the grey pointer. - */ -static Buffer -greymaskread(Param *p, uchar *buf, int y) -{ - Buffer b; - - b = p->greymaskcall(p, buf, y); - b.alpha = b.grey; - return b; -} - -#define DBG if(0) -static Buffer -readnbit(Param *p, uchar *buf, int y) -{ - Buffer b; - Memimage *img; - uchar *repl, *r, *w, *ow, bits; - int i, n, sh, depth, x, dx, npack, nbits; - - memset(&b, 0, sizeof b); - b.rgba = (u32int*)buf; - b.grey = w = buf; - b.red = b.blu = b.grn = w; - b.alpha = &ones; - b.delta = 1; - - dx = p->dx; - img = p->img; - depth = img->depth; - repl = &replbit[depth][0]; - npack = 8/depth; - sh = 8-depth; - - /* copy from p->r.min.x until end of repl rectangle */ - x = p->r.min.x; - n = dx; - if(n > p->img->r.max.x - x) - n = p->img->r.max.x - x; - - r = p->bytermin + y*p->bwidth; -DBG print("readnbit dx %d %p=%p+%d*%d, *r=%d fetch %d ", dx, r, p->bytermin, y, p->bwidth, *r, n); - bits = *r++; - nbits = 8; - if(i=x&(npack-1)){ -DBG print("throwaway %d...", i); - bits <<= depth*i; - nbits -= depth*i; - } - for(i=0; i>sh]; -DBG print("bit %x...", repl[bits>>sh]); - bits <<= depth; - nbits -= depth; - } - dx -= n; - if(dx == 0) - return b; - - assert(x+i == p->img->r.max.x); - - /* copy from beginning of repl rectangle until where we were before. */ - x = p->img->r.min.x; - n = dx; - if(n > p->r.min.x - x) - n = p->r.min.x - x; - - r = p->bytey0s + y*p->bwidth; -DBG print("x=%d r=%p...", x, r); - bits = *r++; - nbits = 8; - if(i=x&(npack-1)){ - bits <<= depth*i; - nbits -= depth*i; - } -DBG print("nbits=%d...", nbits); - for(i=0; i>sh]; -DBG print("bit %x...", repl[bits>>sh]); - bits <<= depth; - nbits -= depth; -DBG print("bits %x nbits %d...", bits, nbits); - } - dx -= n; - if(dx == 0) - return b; - - assert(dx > 0); - /* now we have exactly one full scan line: just replicate the buffer itself until we are done */ - ow = buf; - while(dx--) - *w++ = *ow++; - - return b; -} -#undef DBG - -#define DBG if(0) -static void -writenbit(Param *p, uchar *w, Buffer src) -{ - uchar *r; - u32int bits; - int i, sh, depth, npack, nbits, x, ex; - - assert(src.grey != nil && src.delta == 1); - - x = p->r.min.x; - ex = x+p->dx; - depth = p->img->depth; - npack = 8/depth; - - i=x&(npack-1); - bits = i ? (*w >> (8-depth*i)) : 0; - nbits = depth*i; - sh = 8-depth; - r = src.grey; - - for(; x> sh); - nbits += depth; - if(nbits == 8){ - *w++ = bits; - nbits = 0; - } - } - - if(nbits){ - sh = 8-nbits; - bits <<= sh; - bits |= *w & ((1<bytey0s + y*p->bwidth; - r = p->bytermin + y*p->bwidth; - end = p->bytey0e + y*p->bwidth; - cmap = p->img->cmap->cmap2rgb; - convgrey = p->convgrey; - copyalpha = (p->img->flags&Falpha) ? 1 : 0; - - w = buf; - dx = p->dx; - if(copyalpha){ - b.alpha = buf++; - a = p->img->shift[CAlpha]/8; - m = p->img->shift[CMap]/8; - for(i=0; iimg->cmap->rgb2cmap; - - delta = src.delta; - red= src.red; - grn = src.grn; - blu = src.blu; - - dx = p->dx; - for(i=0; i>4)*256+(*grn>>4)*16+(*blu>>4)]; -} - -#define DBG if(drawdebug) -static Buffer -readbyte(Param *p, uchar *buf, int y) -{ - Buffer b; - Memimage *img; - int dx, isgrey, convgrey, alphaonly, copyalpha, i, nb; - uchar *begin, *end, *r, *w, *rrepl, *grepl, *brepl, *arepl, *krepl; - uchar ured, ugrn, ublu; - u32int u; - - img = p->img; - begin = p->bytey0s + y*p->bwidth; - r = p->bytermin + y*p->bwidth; - end = p->bytey0e + y*p->bwidth; - - w = buf; - dx = p->dx; - nb = img->depth/8; - - convgrey = p->convgrey; /* convert rgb to grey */ - isgrey = img->flags&Fgrey; - alphaonly = p->alphaonly; - copyalpha = (img->flags&Falpha) ? 1 : 0; - - /* if we can, avoid processing everything */ - if(!(img->flags&Frepl) && !convgrey && (img->flags&Fbytes)){ - memset(&b, 0, sizeof b); - if(p->needbuf){ - memmove(buf, r, dx*nb); - r = buf; - } - b.rgba = (u32int*)r; - if(copyalpha) - b.alpha = r+img->shift[CAlpha]/8; - else - b.alpha = &ones; - if(isgrey){ - b.grey = r+img->shift[CGrey]/8; - b.red = b.grn = b.blu = b.grey; - }else{ - b.red = r+img->shift[CRed]/8; - b.grn = r+img->shift[CGreen]/8; - b.blu = r+img->shift[CBlue]/8; - } - b.delta = nb; - return b; - } - - rrepl = replbit[img->nbits[CRed]]; - grepl = replbit[img->nbits[CGreen]]; - brepl = replbit[img->nbits[CBlue]]; - arepl = replbit[img->nbits[CAlpha]]; - krepl = replbit[img->nbits[CGrey]]; - - for(i=0; i>img->shift[CAlpha]) & img->mask[CAlpha]]; - - if(isgrey) - *w++ = krepl[(u >> img->shift[CGrey]) & img->mask[CGrey]]; - else if(!alphaonly){ - ured = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]]; - ugrn = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]]; - ublu = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]]; - if(convgrey){ - *w++ = RGB2K(ured, ugrn, ublu); - }else{ - *w++ = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]]; - *w++ = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]]; - *w++ = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]]; - } - } - r += nb; - if(r == end) - r = begin; - } - - b.alpha = copyalpha ? buf : &ones; - b.rgba = (u32int*)buf; - if(alphaonly){ - b.red = b.grn = b.blu = b.grey = nil; - if(!copyalpha) - b.rgba = nil; - b.delta = 1; - }else if(isgrey || convgrey){ - b.grey = buf+copyalpha; - b.red = b.grn = b.blu = buf+copyalpha; - b.delta = copyalpha+1; - }else{ - b.blu = buf+copyalpha; - b.grn = buf+copyalpha+1; - b.grey = nil; - b.red = buf+copyalpha+2; - b.delta = copyalpha+3; - } - return b; -} -#undef DBG - -#define DBG if(drawdebug) -static void -writebyte(Param *p, uchar *w, Buffer src) -{ - Memimage *img; - int i, isalpha, isgrey, nb, delta, dx, adelta; - uchar ff, *red, *grn, *blu, *grey, *alpha; - u32int u, mask; - - img = p->img; - - red = src.red; - grn = src.grn; - blu = src.blu; - alpha = src.alpha; - delta = src.delta; - grey = src.grey; - dx = p->dx; - - nb = img->depth/8; - mask = (nb==4) ? 0 : ~((1<depth)-1); - - isalpha = img->flags&Falpha; - isgrey = img->flags&Fgrey; - adelta = src.delta; - - if(isalpha && (alpha == nil || alpha == &ones)){ - ff = 0xFF; - alpha = &ff; - adelta = 0; - } - - for(i=0; i> (8-img->nbits[CGrey])) & img->mask[CGrey]) << img->shift[CGrey]; -DBG print("|grey %.8lux...", u); - grey += delta; - }else{ - u |= ((*red >> (8-img->nbits[CRed])) & img->mask[CRed]) << img->shift[CRed]; - u |= ((*grn >> (8-img->nbits[CGreen])) & img->mask[CGreen]) << img->shift[CGreen]; - u |= ((*blu >> (8-img->nbits[CBlue])) & img->mask[CBlue]) << img->shift[CBlue]; - red += delta; - grn += delta; - blu += delta; -DBG print("|rgb %.8lux...", u); - } - - if(isalpha){ - u |= ((*alpha >> (8-img->nbits[CAlpha])) & img->mask[CAlpha]) << img->shift[CAlpha]; - alpha += adelta; -DBG print("|alpha %.8lux...", u); - } - - w[0] = u; - w[1] = u>>8; - w[2] = u>>16; - w[3] = u>>24; -DBG print("write back %.8lux...", u); - w += nb; - } -} -#undef DBG - -static Readfn* -readfn(Memimage *img) -{ - if(img->depth < 8) - return readnbit; - if(img->nbits[CMap] == 8) - return readcmap; - return readbyte; -} - -static Readfn* -readalphafn(Memimage *m) -{ - USED(m); - return readbyte; -} - -static Writefn* -writefn(Memimage *img) -{ - if(img->depth < 8) - return writenbit; - if(img->chan == CMAP8) - return writecmap; - return writebyte; -} - -static void -nullwrite(Param *p, uchar *s, Buffer b) -{ - USED(p); - USED(s); -} - -static Buffer -readptr(Param *p, uchar *s, int y) -{ - Buffer b; - uchar *q; - - USED(s); - memset(&b, 0, sizeof b); - q = p->bytermin + y*p->bwidth; - b.red = q; /* ptr to data */ - b.grn = b.blu = b.grey = b.alpha = nil; - b.rgba = (u32int*)q; - b.delta = p->img->depth/8; - return b; -} - -static Buffer -boolmemmove(Buffer bdst, Buffer bsrc, Buffer b1, int dx, int i, int o) -{ - USED(i); - USED(o); - memmove(bdst.red, bsrc.red, dx*bdst.delta); - return bdst; -} - -static Buffer -boolcopy8(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o) -{ - uchar *m, *r, *w, *ew; - - USED(i); - USED(o); - m = bmask.grey; - w = bdst.red; - r = bsrc.red; - ew = w+dx; - for(; w < ew; w++,r++) - if(*m++) - *w = *r; - return bdst; /* not used */ -} - -static Buffer -boolcopy16(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o) -{ - uchar *m; - ushort *r, *w, *ew; - - USED(i); - USED(o); - m = bmask.grey; - w = (ushort*)bdst.red; - r = (ushort*)bsrc.red; - ew = w+dx; - for(; w < ew; w++,r++) - if(*m++) - *w = *r; - return bdst; /* not used */ -} - -static Buffer -boolcopy24(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o) -{ - uchar *m; - uchar *r, *w, *ew; - - USED(i); - USED(o); - m = bmask.grey; - w = bdst.red; - r = bsrc.red; - ew = w+dx*3; - while(w < ew){ - if(*m++){ - *w++ = *r++; - *w++ = *r++; - *w++ = *r++; - }else{ - w += 3; - r += 3; - } - } - return bdst; /* not used */ -} - -static Buffer -boolcopy32(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o) -{ - uchar *m; - u32int *r, *w, *ew; - - USED(i); - USED(o); - m = bmask.grey; - w = (u32int*)bdst.red; - r = (u32int*)bsrc.red; - ew = w+dx; - for(; w < ew; w++,r++) - if(*m++) - *w = *r; - return bdst; /* not used */ -} - -static Buffer -genconv(Param *p, uchar *buf, int y) -{ - Buffer b; - int nb; - uchar *r, *w, *ew; - - /* read from source into RGB format in convbuf */ - b = p->convreadcall(p, p->convbuf, y); - - /* write RGB format into dst format in buf */ - p->convwritecall(p->convdpar, buf, b); - - if(p->convdx){ - nb = p->convdpar->img->depth/8; - r = buf; - w = buf+nb*p->dx; - ew = buf+nb*p->convdx; - while(wchan == src->chan && !(src->flags&Frepl)){ -/*if(drawdebug) iprint("readptr..."); */ - return readptr; - } - - if(dst->chan==CMAP8 && (src->chan==GREY1||src->chan==GREY2||src->chan==GREY4)){ - /* cheat because we know the replicated value is exactly the color map entry. */ -/*if(drawdebug) iprint("Readnbit..."); */ - return readnbit; - } - - spar->convreadcall = readfn(src); - spar->convwritecall = writefn(dst); - spar->convdpar = dpar; - - /* allocate a conversion buffer */ - spar->convbufoff = ndrawbuf; - ndrawbuf += spar->dx*4; - - if(spar->dx > Dx(spar->img->r)){ - spar->convdx = spar->dx; - spar->dx = Dx(spar->img->r); - } - -/*if(drawdebug) iprint("genconv..."); */ - return genconv; -} - -/* - * Do NOT call this directly. pixelbits is a wrapper - * around this that fetches the bits from the X server - * when necessary. - */ -u32int -_pixelbits(Memimage *i, Point pt) -{ - uchar *p; - u32int val; - int off, bpp, npack; - - val = 0; - p = byteaddr(i, pt); - switch(bpp=i->depth){ - case 1: - case 2: - case 4: - npack = 8/bpp; - off = pt.x%npack; - val = p[0] >> bpp*(npack-1-off); - val &= (1<flags&Frepl && Dx(mask->r)==1 && Dy(mask->r)==1 && pixelbits(mask, mask->r.min)==~0) - return boolmemmove; - - switch(img->depth){ - case 8: - return boolcopy8; - case 16: - return boolcopy16; - case 24: - return boolcopy24; - case 32: - return boolcopy32; - default: - assert(0 /* boolcopyfn */); - } - return 0; -} - -/* - * Optimized draw for filling and scrolling; uses memset and memmove. - */ -static void -memsets(void *vp, ushort val, int n) -{ - ushort *p, *ep; - - p = vp; - ep = p+n; - while(p>8; - c = val>>16; - while(pchan; chan; chan>>=8){ - nb = NBITS(chan); - ov = v = val&((1<>= nb; - - while(nb < 8){ - v |= v<>= (nb-8); - - switch(TYPE(chan)){ - case CRed: - r = v; - break; - case CGreen: - g = v; - break; - case CBlue: - b = v; - break; - case CAlpha: - a = v; - break; - case CGrey: - r = g = b = v; - break; - case CMap: - p = img->cmap->cmap2rgb+3*ov; - r = *p++; - g = *p++; - b = *p; - break; - } - } - return (r<<24)|(g<<16)|(b<<8)|a; -} - -u32int -_rgbatoimg(Memimage *img, u32int rgba) -{ - u32int chan; - int d, nb; - u32int v; - uchar *p, r, g, b, a, m; - - v = 0; - r = rgba>>24; - g = rgba>>16; - b = rgba>>8; - a = rgba; - d = 0; - for(chan=img->chan; chan; chan>>=8){ - nb = NBITS(chan); - switch(TYPE(chan)){ - case CRed: - v |= (r>>(8-nb))<>(8-nb))<>(8-nb))<>(8-nb))<cmap->rgb2cmap; - m = p[(r>>4)*256+(g>>4)*16+(b>>4)]; - v |= (m>>(8-nb))<>(8-nb))<r); - dy = Dy(par->r); - src = par->src; - dst = par->dst; - op = par->op; - -DBG print("state %lux mval %lux dd %d\n", par->state, par->mval, dst->depth); - /* - * If we have an opaque mask and source is one opaque pixel we can convert to the - * destination format and just replicate with memset. - */ - m = Simplesrc|Simplemask|Fullmask; - if((par->state&m)==m && (par->srgba&0xFF) == 0xFF && (op ==S || op == SoverD)){ - uchar *dp, p[4]; - int d, dwid, ppb, np, nb; - uchar lm, rm; - -DBG print("memopt, dst %p, dst->data->bdata %p\n", dst, dst->data->bdata); - dwid = dst->width*sizeof(u32int); - dp = byteaddr(dst, par->r.min); - v = par->sdval; -DBG print("sdval %lud, depth %d\n", v, dst->depth); - switch(dst->depth){ - case 1: - case 2: - case 4: - for(d=dst->depth; d<8; d*=2) - v |= (v<depth; /* pixels per byte */ - m = ppb-1; - /* left edge */ - np = par->r.min.x&m; /* no. pixels unused on left side of word */ - dx -= (ppb-np); - nb = 8 - np * dst->depth; /* no. bits used on right side of word */ - lm = (1<r.min.x, nb, lm, ppb, m); - - /* right edge */ - np = par->r.max.x&m; /* no. pixels used on left side of word */ - dx -= np; - nb = 8 - np * dst->depth; /* no. bits unused on right side of word */ - rm = ~((1<r.max.x, nb, rm, ppb, m); - -DBG print("dx %d Dx %d\n", dx, Dx(par->r)); - /* lm, rm are masks that are 1 where we should touch the bits */ - if(dx < 0){ /* just one byte */ - lm &= rm; - for(y=0; y>8; - v = *(ushort*)p; -DBG print("dp=%p; dx=%d; for(y=0; y<%d; y++, dp+=%d)\nmemsets(dp, v, dx);\n", - dp, dx, dy, dwid); - for(y=0; y>8; - p[2] = v>>16; - p[3] = v>>24; - v = *(u32int*)p; - for(y=0; ystate&(m|Replsrc))==m && src->depth >= 8 - && src->chan == dst->chan && !(src->flags&Falpha) && (op == S || op == SoverD)){ - uchar *sp, *dp; - long swid, dwid, nb; - int dir; - - if(src->data == dst->data && byteaddr(dst, par->r.min) > byteaddr(src, par->sr.min)) - dir = -1; - else - dir = 1; - - swid = src->width*sizeof(u32int); - dwid = dst->width*sizeof(u32int); - sp = byteaddr(src, par->sr.min); - dp = byteaddr(dst, par->r.min); - if(dir == -1){ - sp += (dy-1)*swid; - dp += (dy-1)*dwid; - swid = -swid; - dwid = -dwid; - } - nb = (dx*src->depth)/8; - for(y=0; ystate&(Simplemask|Simplesrc|Replmask|Replsrc))==0 - && dst->chan==GREY1 && src->chan==GREY1 && par->mask->chan==GREY1 - && (par->r.min.x&7)==(par->sr.min.x&7) && (par->r.min.x&7)==(par->mr.min.x&7)){ - uchar *sp, *dp, *mp; - uchar lm, rm; - long swid, dwid, mwid; - int i, x, dir; - - sp = byteaddr(src, par->sr.min); - dp = byteaddr(dst, par->r.min); - mp = byteaddr(par->mask, par->mr.min); - swid = src->width*sizeof(u32int); - dwid = dst->width*sizeof(u32int); - mwid = par->mask->width*sizeof(u32int); - - if(src->data == dst->data && byteaddr(dst, par->r.min) > byteaddr(src, par->sr.min)){ - dir = -1; - }else - dir = 1; - - lm = 0xFF>>(par->r.min.x&7); - rm = 0xFF<<(8-(par->r.max.x&7)); - dx -= (8-(par->r.min.x&7)) + (par->r.max.x&7); - - if(dx < 0){ /* one byte wide */ - lm &= rm; - if(dir == -1){ - dp += dwid*(dy-1); - sp += swid*(dy-1); - mp += mwid*(dy-1); - dwid = -dwid; - swid = -swid; - mwid = -mwid; - } - for(y=0; ymask->flags, par->mask->depth, par->src->flags, - Dx(par->src->r), Dy(par->src->r), par->dst->depth, par->dst->data, par->src->data); - - mask = par->mask; - src = par->src; - dst = par->dst; - r = par->r; - mr = par->mr; - op = par->op; - - if((par->state&(Replsrc|Simplesrc|Fullsrc|Replmask)) != (Replsrc|Simplesrc|Fullsrc) - || mask->depth != 1 || dst->depth<8 || dst->data==src->data - || op != SoverD) - return 0; - -/*if(drawdebug) iprint("chardraw..."); */ - - depth = mask->depth; - maskwid = mask->width*sizeof(u32int); - rp = byteaddr(mask, mr.min); - npack = 8/depth; - bsh = (mr.min.x % npack) * depth; - - wp = byteaddr(dst, r.min); - dstwid = dst->width*sizeof(u32int); -DBG print("bsh %d\n", bsh); - dy = Dy(r); - dx = Dx(r); - - ddepth = dst->depth; - - /* - * for loop counts from bsh to bsh+dx - * - * we want the bottom bits to be the amount - * to shift the pixels down, so for n≡0 (mod 8) we want - * bottom bits 7. for n≡1, 6, etc. - * the bits come from -n-1. - */ - - bx = -bsh-1; - ex = -bsh-1-dx; - SET(bits); - v = par->sdval; - - /* make little endian */ - sp[0] = v; - sp[1] = v>>8; - sp[2] = v>>16; - sp[3] = v>>24; - -/*print("sp %x %x %x %x\n", sp[0], sp[1], sp[2], sp[3]); */ - for(y=0; yex; x--, wc++){ - i = x&7; - if(i == 8-1) - bits = *q++; -DBG print("bits %lux sh %d...", bits, i); - if((bits>>i)&1) - *wc = v; - } - break; - case 16: - ws = (ushort*)wp; - v = *(ushort*)sp; - for(x=bx; x>ex; x--, ws++){ - i = x&7; - if(i == 8-1) - bits = *q++; -DBG print("bits %lux sh %d...", bits, i); - if((bits>>i)&1) - *ws = v; - } - break; - case 24: - wc = wp; - for(x=bx; x>ex; x--, wc+=3){ - i = x&7; - if(i == 8-1) - bits = *q++; -DBG print("bits %lux sh %d...", bits, i); - if((bits>>i)&1){ - wc[0] = sp[0]; - wc[1] = sp[1]; - wc[2] = sp[2]; - } - } - break; - case 32: - wl = (u32int*)wp; - v = *(u32int*)sp; - for(x=bx; x>ex; x--, wl++){ - i = x&7; - if(i == 8-1) - bits = *q++; -DBG iprint("bits %lux sh %d...", bits, i); - if((bits>>i)&1) - *wl = v; - } - break; - } - } - -DBG print("\n"); - return 1; -} -#undef DBG - - -/* - * Fill entire byte with replicated (if necessary) copy of source pixel, - * assuming destination ldepth is >= source ldepth. - * - * This code is just plain wrong for >8bpp. - * -u32int -membyteval(Memimage *src) -{ - int i, val, bpp; - uchar uc; - - unloadmemimage(src, src->r, &uc, 1); - bpp = src->depth; - uc <<= (src->r.min.x&(7/src->depth))*src->depth; - uc &= ~(0xFF>>bpp); - * pixel value is now in high part of byte. repeat throughout byte - val = uc; - for(i=bpp; i<8; i<<=1) - val |= val>>i; - return val; -} - * - */ - -void -_memfillcolor(Memimage *i, u32int val) -{ - u32int bits; - int d, y; - uchar p[4]; - - if(val == DNofill) - return; - - bits = _rgbatoimg(i, val); - switch(i->depth){ - case 24: /* 24-bit images suck */ - for(y=i->r.min.y; yr.max.y; y++) - memset24(byteaddr(i, Pt(i->r.min.x, y)), bits, Dx(i->r)); - break; - default: /* 1, 2, 4, 8, 16, 32 */ - for(d=i->depth; d<32; d*=2) - bits = (bits << d) | bits; - p[0] = bits; /* make little endian */ - p[1] = bits>>8; - p[2] = bits>>16; - p[3] = bits>>24; - bits = *(u32int*)p; - memsetl(wordaddr(i, i->r.min), bits, i->width*Dy(i->r)); - break; - } -} - -- cgit v1.2.3