Example #1
0
static
void
doellipse(int cmd, Image *dst, Point *c, int xr, int yr, int thick, Image *src, Point *sp, int alpha, int phi, Drawop op)
{
    uchar *a;

    _setdrawop(dst->display, op);

    a = bufimage(dst->display, 1+4+4+2*4+4+4+4+2*4+2*4);
    if(a == 0) {
        fprint(2, "image ellipse: %r\n");
        return;
    }
    a[0] = cmd;
    BPLONG(a+1, dst->id);
    BPLONG(a+5, src->id);
    BPLONG(a+9, c->x);
    BPLONG(a+13, c->y);
    BPLONG(a+17, xr);
    BPLONG(a+21, yr);
    BPLONG(a+25, thick);
    BPLONG(a+29, sp->x);
    BPLONG(a+33, sp->y);
    BPLONG(a+37, alpha);
    BPLONG(a+41, phi);
}
Example #2
0
static void
draw1(Image *dst, Rectangle *r, Image *src, Point *p0, Image *mask, Point *p1, Drawop op)
{
	uchar *a;

	_setdrawop(dst->display, op);

	a = bufimage(dst->display, 1+4+4+4+4*4+2*4+2*4);
	if(a == nil)
		return;
	if(src == nil)
		src = dst->display->black;
	if(mask == nil)
		mask = dst->display->opaque;
	a[0] = 'd';
	BPLONG(a+1, dst->id);
	BPLONG(a+5, src->id);
	BPLONG(a+9, mask->id);
	BPLONG(a+13, r->min.x);
	BPLONG(a+17, r->min.y);
	BPLONG(a+21, r->max.x);
	BPLONG(a+25, r->max.y);
	BPLONG(a+29, p0->x);
	BPLONG(a+33, p0->y);
	BPLONG(a+37, p1->x);
	BPLONG(a+41, p1->y);
}
Example #3
0
void
lineop(Image *dst, Point p0, Point p1, int end0, int end1, int radius, Image *src, Point sp, Drawop op)
{
	uchar *a;

	_setdrawop(dst->display, op);

	a = bufimage(dst->display, 1+4+2*4+2*4+4+4+4+4+2*4);
	if(a == 0){
		fprint(2, "image line: %r\n");
		return;
	}
	a[0] = 'L';
	BPLONG(a+1, dst->id);
	BPLONG(a+5, p0.x);
	BPLONG(a+9, p0.y);
	BPLONG(a+13, p1.x);
	BPLONG(a+17, p1.y);
	BPLONG(a+21, end0);
	BPLONG(a+25, end1);
	BPLONG(a+29, radius);
	BPLONG(a+33, src->id);
	BPLONG(a+37, sp.x);
	BPLONG(a+41, sp.y);
}
Example #4
0
int
unloadimage(Image *i, Rectangle r, uchar *data, int ndata)
{
    int bpl, n, chunk, dx, dy;
    uchar *a, *start;
    Display *d;

    if(!rectinrect(r, i->r)) {
        werrstr("unloadimage: bad rectangle");
        return -1;
    }
    bpl = bytesperline(r, i->depth);
    if(ndata < bpl*Dy(r)) {
        werrstr("unloadimage: buffer too small");
        return -1;
    }
    start = data;
    d = i->display;
    chunk = d->bufsize;
    flushimage(d, 0);	/* make sure subsequent flush is for us only */
    while(r.min.y < r.max.y) {
        dx = Dx(r);
        dy = chunk/bpl;
        if(dy <= 0) {
            dy = 1;
            dx = ((chunk*dx)/bpl) & ~7;
            n = bytesperline(Rect(r.min.x, r.min.y, r.min.x+dx, r.min.y+dy), i->depth);
            if(unloadimage(i, Rect(r.min.x+dx, r.min.y, r.max.x, r.min.y+dy), data+n, bpl-n) < 0)
                return -1;
        } else {
            if(dy > Dy(r))
                dy = Dy(r);
            n = bpl*dy;
        }
        a = bufimage(d, 1+4+4*4);
        if(a == nil) {
            werrstr("unloadimage: %r");
            return -1;
        }
        a[0] = 'r';
        BPLONG(a+1, i->id);
        BPLONG(a+5, r.min.x);
        BPLONG(a+9, r.min.y);
        BPLONG(a+13, r.min.x+dx);
        BPLONG(a+17, r.min.y+dy);
        if(flushimage(d, 0) < 0)
            return -1;
        if(read(d->fd, data, n) < 0)
            return -1;
        data += bpl*dy;
        r.min.y += dy;
    }
    return data - start;
}
Example #5
0
void
drawsetdebug(int v)
{
	uchar *a;
	a = bufimage(display, 1+1);
	if(a == 0){
		fprint(2, "drawsetdebug: %r\n");
		return;
	}
	a[0] = 'D';
	a[1] = v;
}
Example #6
0
void
_setdrawop(Display *d, Drawop op)
{
	uchar *a;

	if(op != SoverD){
		a = bufimage(d, 1+1);
		if(a == nil)
			return;
		a[0] = 'O';
		a[1] = op;
	}
}
Example #7
0
int
loadimage(Image *i, Rectangle r, uchar *data, int ndata)
{
	long dy;
	int n, bpl;
	uchar *a;
	int chunk;

	chunk = i->display->bufsize - 64;

	if(!rectinrect(r, i->r)){
		werrstr("loadimage: bad rectangle");
		return -1;
	}
	bpl = bytesperline(r, i->depth);
	n = bpl*Dy(r);
	if(n > ndata){
		werrstr("loadimage: insufficient data");
		return -1;
	}
	ndata = 0;
	while(r.max.y > r.min.y){
		dy = r.max.y - r.min.y;
		if(dy*bpl > chunk)
			dy = chunk/bpl;
		if(dy <= 0){
			werrstr("loadimage: image too wide for buffer");
			return -1;
		}
		n = dy*bpl;
		a = bufimage(i->display, 21+n);
		if(a == nil){
			werrstr("bufimage failed");
			return -1;
		}
		a[0] = 'y';
		BPLONG(a+1, i->id);
		BPLONG(a+5, r.min.x);
		BPLONG(a+9, r.min.y);
		BPLONG(a+13, r.max.x);
		BPLONG(a+17, r.min.y+dy);
		memmove(a+21, data, n);
		ndata += n;
		data += n;
		r.min.y += dy;
	}
	if(flushimage(i->display, 0) < 0)
		return -1;
	return ndata;
}
Example #8
0
int
unloadimage(Image *i, Rectangle r, uchar *data, int ndata)
{
	int bpl, n, ntot, dy;
	uchar *a;
	Display *d;

	if(!rectinrect(r, i->r)){
		werrstr("unloadimage: bad rectangle");
		return -1;
	}
	bpl = bytesperline(r, i->depth);
	if(ndata < bpl*Dy(r)){
		werrstr("unloadimage: buffer too small");
		return -1;
	}

	d = i->display;
	flushimage(d, 0);	/* make sure subsequent flush is for us only */
	ntot = 0;
	while(r.min.y < r.max.y){
		a = bufimage(d, 1+4+4*4);
		if(a == 0){
			werrstr("unloadimage: %r");
			return -1;
		}
		dy = 8000/bpl;
		if(dy <= 0){
			werrstr("unloadimage: image too wide");
			return -1;
		}
		if(dy > Dy(r))
			dy = Dy(r);
		a[0] = 'r';
		BPLONG(a+1, i->id);
		BPLONG(a+5, r.min.x);
		BPLONG(a+9, r.min.y);
		BPLONG(a+13, r.max.x);
		BPLONG(a+17, r.min.y+dy);
		if(flushimage(d, 0) < 0)
			return -1;
		n = read(d->fd, data+ntot, ndata-ntot);
		if(n < 0)
			return n;
		ntot += n;
		r.min.y += dy;
	}
	return ntot;
}
Example #9
0
int
cloadimage(Image *i, Rectangle r, uchar *data, int ndata)
{
	int m, nb, miny, maxy, ncblock;
	uchar *a;

	if(!rectinrect(r, i->r)){
		werrstr("cloadimage: bad rectangle");
		return -1;
	}

	miny = r.min.y;
	m = 0;
	ncblock = _compblocksize(r, i->depth);
	while(miny != r.max.y){
		maxy = atoi((char*)data+0*12);
		nb = atoi((char*)data+1*12);
		if(maxy<=miny || r.max.y<maxy){
			werrstr("creadimage: bad maxy %d", maxy);
			return -1;
		}
		data += 2*12;
		ndata -= 2*12;
		m += 2*12;
		if(nb<=0 || ncblock<nb || nb>ndata){
			werrstr("creadimage: bad count %d", nb);
			return -1;
		}
		a = bufimage(i->display, 21+nb);
		if(a == nil)
			return -1;
		a[0] = 'Y';
		BPLONG(a+1, i->id);
		BPLONG(a+5, r.min.x);
		BPLONG(a+9, miny);
		BPLONG(a+13, r.max.x);
		BPLONG(a+17, maxy);
		memmove(a+21, data, nb);
		miny = maxy;
		data += nb;
		ndata += nb;
		m += nb;
	}
	return m;
}
Example #10
0
int
nameimage(Image *i, char *name, int in)
{
	uchar *a;
	int n;

	n = strlen(name);
	a = bufimage(i->display, 1+4+1+1+n);
	if(a == 0)
		return 0;
	a[0] = 'N';
	BPLONG(a+1, i->id);
	a[5] = in;
	a[6] = n;
	memmove(a+7, name, n);
	if(flushimage(i->display, 0) < 0)
		return 0;
	return 1;
}
Example #11
0
static
void
dopoly(int cmd, Image *dst, Point *pp, int np, int end0, int end1, int radius, Image *src, Point *sp, Drawop op)
{
	uchar *a, *t, *u;
	int i, ox, oy;

	if(np == 0)
		return;
	t = malloc(np*2*3);
	if(t == nil)
		return;
	u = t;
	ox = oy = 0;
	for(i=0; i<np; i++){
		u = addcoord(u, ox, pp[i].x);
		ox = pp[i].x;
		u = addcoord(u, oy, pp[i].y);
		oy = pp[i].y;
	}

	_setdrawop(dst->display, op);

	a = bufimage(dst->display, 1+4+2+4+4+4+4+2*4+(u-t));
	if(a == 0){
		free(t);
		fprint(2, "image poly: %r\n");
		return;
	}
	a[0] = cmd;
	BPLONG(a+1, dst->id);
	BPSHORT(a+5, np-1);
	BPLONG(a+7, end0);
	BPLONG(a+11, end1);
	BPLONG(a+15, radius);
	BPLONG(a+19, src->id);
	BPLONG(a+23, sp->x);
	BPLONG(a+27, sp->y);
	memmove(a+31, t, u-t);
	free(t);
}
Example #12
0
int
_freeimage1(Image *i)
{
	uchar *a;
	Display *d;
	Image *w;

	if(i == 0)
		return 0;
	/* make sure no refresh events occur on this if we block in the write */
	d = i->display;
	/* flush pending data so we don't get error deleting the image */
	flushimage(d, 0);
	a = bufimage(d, 1+4);
	if(a == 0)
		return -1;
	a[0] = 'f';
	BPLONG(a+1, i->id);
	if(i->screen){
		w = d->windows;
		if(w == i)
			d->windows = i->next;
		else
			while(w){
				if(w->next == i){
					w->next = i->next;
					break;
				}
				w = w->next;
			}
	}
	if(flushimage(d, i->screen!=0) < 0)
		return -1;

	return 0;
}
Example #13
0
Image*
_allocimage(Image *ai, Display *d, Rectangle r, ulong chan, int repl, ulong val, int screenid, int refresh)
{
	uchar *a;
	char *err;
	Image *i;
	Rectangle clipr;
	int id;
	int depth;

	err = 0;
	i = 0;

	if(chan == 0){
		werrstr("bad channel descriptor");
		return nil;
	}

	depth = chantodepth(chan);
	if(depth == 0){
		err = "bad channel descriptor";
    Error:
		if(err)
			werrstr("allocimage: %s", err);
		else
			werrstr("allocimage: %r");
		free(i);
		return 0;
	}

	/* flush pending data so we don't get error allocating the image */
	flushimage(d, 0);
	a = bufimage(d, 1+4+4+1+4+1+4*4+4*4+4);
	if(a == 0)
		goto Error;
	d->imageid++;
	id = d->imageid;
	a[0] = 'b';
	BPLONG(a+1, id);
	BPLONG(a+5, screenid);
	a[9] = refresh;
	BPLONG(a+10, chan);
	a[14] = repl;
	BPLONG(a+15, r.min.x);
	BPLONG(a+19, r.min.y);
	BPLONG(a+23, r.max.x);
	BPLONG(a+27, r.max.y);
	if(repl)
		/* huge but not infinite, so various offsets will leave it huge, not overflow */
		clipr = Rect(-0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF);
	else
		clipr = r;
	BPLONG(a+31, clipr.min.x);
	BPLONG(a+35, clipr.min.y);
	BPLONG(a+39, clipr.max.x);
	BPLONG(a+43, clipr.max.y);
	BPLONG(a+47, val);
	if(flushimage(d, 0) < 0)
		goto Error;

	if(ai)
		i = ai;
	else{
		i = malloc(sizeof(Image));
		if(i == nil){
			a = bufimage(d, 1+4);
			if(a){
				a[0] = 'f';
				BPLONG(a+1, id);
				flushimage(d, 0);
			}
			goto Error;
		}
	}
	i->display = d;
	i->id = id;
	i->depth = depth;
	i->chan = chan;
	i->r = r;
	i->clipr = clipr;
	i->repl = repl;
	i->screen = 0;
	i->next = 0;
	return i;
}
Example #14
0
Image*
namedimage(Display *d, char *name)
{
	uchar *a;
	char *err, buf[12*12+1];
	Image *i;
	int id, n;
	ulong chan;

	err = 0;
	i = 0;

	n = strlen(name);
	if(n >= 256){
		err = "name too long";
    Error:
		if(err)
			werrstr("namedimage: %s", err);
		else
			werrstr("namedimage: %r");
		if(i)
			free(i);
		return 0;
	}
	/* flush pending data so we don't get error allocating the image */
	flushimage(d, 0);
	a = bufimage(d, 1+4+1+n);
	if(a == 0)
		goto Error;
	d->imageid++;
	id = d->imageid;
	a[0] = 'n';
	BPLONG(a+1, id);
	a[5] = n;
	memmove(a+6, name, n);
	if(flushimage(d, 0) < 0)
		goto Error;

	if(pread(d->ctlfd, buf, sizeof buf, 0) < 12*12)
		goto Error;
	buf[12*12] = '\0';

	i = malloc(sizeof(Image));
	if(i == nil){
	Error1:
		a = bufimage(d, 1+4);
		if(a){
			a[0] = 'f';
			BPLONG(a+1, id);
			flushimage(d, 0);
		}
		goto Error;
	}
	i->display = d;
	i->id = id;
	if((chan=strtochan(buf+2*12))==0){
		werrstr("bad channel '%.12s' from devdraw", buf+2*12);
		goto Error1;
	}
	i->chan = chan;
	i->depth = chantodepth(chan);
	i->repl = atoi(buf+3*12);
	i->r.min.x = atoi(buf+4*12);
	i->r.min.y = atoi(buf+5*12);
	i->r.max.x = atoi(buf+6*12);
	i->r.max.y = atoi(buf+7*12);
	i->clipr.min.x = atoi(buf+8*12);
	i->clipr.min.y = atoi(buf+9*12);
	i->clipr.max.x = atoi(buf+10*12);
	i->clipr.max.y = atoi(buf+11*12);
	i->screen = 0;
	i->next = 0;
	return i;
}
Example #15
0
Point
_string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, int len, Rectangle clipr, Image *bg, Point bgp, Drawop op)
{
	int m, n, wid, max;
	ushort cbuf[Max], *c, *ec;
	uchar *b;
	char *subfontname;
	char **sptr;
	Rune **rptr;
	Font *def;
	Subfont *sf;

	if(s == nil){
		s = "";
		sptr = nil;
	}else
		sptr = &s;
	if(r == nil){
		r = (Rune*) L"";
		rptr = nil;
	}else
		rptr = &r;
	sf = nil;
	while((*s || *r) && len > 0){
		max = Max;
		if(len < max)
			max = len;
		n = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname);
		if(n > 0){
			_setdrawop(dst->display, op);

			m = 47+2*n;
			if(bg)
				m += 4+2*4;
			b = bufimage(dst->display, m);
			if(b == 0){
				fprint(2, "string: %r\n");
				break;
			}
			if(bg)
				b[0] = 'x';
			else
				b[0] = 's';
			BPLONG(b+1, dst->id);
			BPLONG(b+5, src->id);
			BPLONG(b+9, f->cacheimage->id);
			BPLONG(b+13, pt.x);
			BPLONG(b+17, pt.y+f->ascent);
			BPLONG(b+21, clipr.min.x);
			BPLONG(b+25, clipr.min.y);
			BPLONG(b+29, clipr.max.x);
			BPLONG(b+33, clipr.max.y);
			BPLONG(b+37, sp.x);
			BPLONG(b+41, sp.y);
			BPSHORT(b+45, n);
			b += 47;
			if(bg){
				BPLONG(b, bg->id);
				BPLONG(b+4, bgp.x);
				BPLONG(b+8, bgp.y);
				b += 12;
			}
			ec = &cbuf[n];
			for(c=cbuf; c<ec; c++, b+=2)
				BPSHORT(b, *c);
			pt.x += wid;
			bgp.x += wid;
			agefont(f);
			len -= n;
		}
		if(subfontname){
			freesubfont(sf);
			if((sf=_getsubfont(f->display, subfontname)) == 0){
				def = f->display ? f->display->defaultfont : nil;
				if(def && f!=def)
					f = def;
				else
					break;
			}
			/* 
			 * must not free sf until cachechars has found it in the cache
			 * and picked up its own reference.
			 */
		}
	}
	return pt;
}