Ejemplo n.º 1
0
void
memldelete(Memimage *i)
{
	Memscreen *s;
	Memlayer *l;

	l = i->layer;
	/* free backing store and disconnect refresh, to make pushback fast */
	freememimage(l->save);
	l->save = nil;
	l->refreshptr = nil;
	memltorear(i);

	/* window is now the rearmost;  clean up screen structures and deallocate */
	s = i->layer->screen;
	if(s->fill){
		i->clipr = i->r;
		memdraw(i, i->r, s->fill, i->r.min, nil, i->r.min, S);
	}
	if(l->front){
		l->front->layer->rear = nil;
		s->rearmost = l->front;
	}else{
		s->frontmost = nil;
		s->rearmost = nil;
	}
	free(l);
	freememimage(i);
}
Ejemplo n.º 2
0
Point
memimagestring(Memimage *b, Point p, Memimage *color, Point cp, Memsubfont *f, char *cs)
{
	int w, width;
	uchar *s;
	Rune c;
	Fontchar *i;

	s = (uchar*)cs;
	for(; (c=*s); p.x+=width, cp.x+=width){
		width = 0;
		if(c < Runeself)
			s++;
		else{
			w = chartorune(&c, (char*)s);
			if(w == 0){
				s++;
				continue;
			}
			s += w;
		}
		if(c >= f->n)
			continue;
//		i = f->info+c;
		i = &(f->info[c]);
		width = i->width;
		memdraw(b, Rect(p.x+i->left, p.y+i->top, p.x+i->left+(i[1].x-i[0].x), p.y+i->bottom),
			color, cp, f->bits, Pt(i->x, i->top), SoverD);
	}
	return p;
}
Ejemplo n.º 3
0
Archivo: draw.c Proyecto: 0intro/vx32
static
void
ldrawop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave)
{
	struct Draw *d;
	Point p0, p1;
	Rectangle oclipr, srcr, r, mr;
	int ok;

	d = etc;
	if(insave && d->dstlayer->save==nil)
		return;

	p0 = addpt(screenr.min, d->deltas);
	p1 = addpt(screenr.min, d->deltam);

	if(insave){
		r = rectsubpt(screenr, d->dstlayer->delta);
		clipr = rectsubpt(clipr, d->dstlayer->delta);
	}else
		r = screenr;

	/* now in logical coordinates */

	/* clipr may have narrowed what we should draw on, so clip if necessary */
	if(!rectinrect(r, clipr)){
		oclipr = dst->clipr;
		dst->clipr = clipr;
		ok = drawclip(dst, &r, d->src, &p0, d->mask, &p1, &srcr, &mr);
		dst->clipr = oclipr;
		if(!ok)
			return;
	}
	memdraw(dst, r, d->src, p0, d->mask, p1, d->op);
}
Ejemplo n.º 4
0
static void
fillpoint(Memimage *dst, int x, int y, Memimage *src, Point p, int op)
{
	Rectangle r;

	r.min.x = x;
	r.min.y = y;
	r.max.x = x+1;
	r.max.y = y+1;
	p.x += x;
	p.y += y;
	memdraw(dst, r, src, p, memopaque, p, op);
}
Ejemplo n.º 5
0
static void
fillline(Memimage *dst, int left, int right, int y, Memimage *src, Point p, int op)
{
	Rectangle r;

	r.min.x = left;
	r.min.y = y;
	r.max.x = right;
	r.max.y = y+1;
	p.x += left;
	p.y += y;
	memdraw(dst, r, src, p, memopaque, p, op);
}
Ejemplo n.º 6
0
static
void
lhideop(Memimage *src, Rectangle screenr, Rectangle clipr, void *etc, int insave)
{
	Rectangle r;
	Memlayer *l;

	USED(clipr.min.x);
	USED(insave);
	l = etc;
	if(src != l->save){	/* do nothing if src is already in save area */
		r = rectsubpt(screenr, l->delta);
		memdraw(l->save, r, src, screenr.min, nil, screenr.min, S);
	}
}
Ejemplo n.º 7
0
static
void
lexposeop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave)
{
	Memlayer *l;
	Rectangle r;

	USED(clipr.min.x);
	if(insave)	/* if dst is save area, don't bother */
		return;
	l = etc;
	r = rectsubpt(screenr, l->delta);
	if(l->save)
		memdraw(dst, screenr, l->save, r.min, nil, r.min, S);
	else
		l->refreshfn(dst, r, l->refreshptr);
}
Ejemplo n.º 8
0
int
memunload(Memimage *src, Rectangle r, uint8_t *data, int n)
{
	Memimage *tmp;
	Memlayer *dl;
	Rectangle lr;
	int dx;

    Top:
	dl = src->layer;
	if(dl == nil)
		return unloadmemimage(src, r, data, n);

	/*
 	 * Convert to screen coordinates.
	 */
	lr = r;
	r.min.x += dl->delta.x;
	r.min.y += dl->delta.y;
	r.max.x += dl->delta.x;
	r.max.y += dl->delta.y;
	dx = dl->delta.x&(7/src->depth);
	if(dl->clear && dx==0){
		src = dl->screen->image;
		goto Top;
	}

	/*
	 * src is an obscured layer or data is unaligned
	 */
	if(dl->save && dx==0){
		if(dl->refreshfn != nil)
			return -1;	/* can't unload window if it's not Refbackup */
		if(n > 0)
			memlhide(src, r);
		n = unloadmemimage(dl->save, lr, data, n);
		return n;
	}
	tmp = allocmemimage(lr, src->chan);
	if(tmp == nil)
		return -1;
	memdraw(tmp, lr, src, lr.min, nil, lr.min, S);
	n = unloadmemimage(tmp, lr, data, n);
	freememimage(tmp);
	return n;
}
Ejemplo n.º 9
0
/*
 * Place i so i->r.min = log, i->layer->screenr.min == scr.
*/
int
memlorigin(Memimage *i, Point log, Point scr)
{
	Memlayer *l;
	Memscreen *s;
	Memimage *t, *shad, *nsave;
	Rectangle x, newr, oldr;
	Point delta;
	int overlap, eqlog, eqscr, wasclear;

	l = i->layer;
	s = l->screen;
	oldr = l->screenr;
	newr = Rect(scr.x, scr.y, scr.x+Dx(oldr), scr.y+Dy(oldr));
	eqscr = eqpt(scr, oldr.min);
	eqlog = eqpt(log, i->r.min);
	if(eqscr && eqlog)
		return 0;
	nsave = nil;
	if(eqlog==0 && l->save!=nil){
		nsave = allocmemimage(Rect(log.x, log.y, log.x+Dx(oldr), log.y+Dy(oldr)), i->chan);
		if(nsave == nil)
			return -1;
	}

	/*
	 * Bring it to front and move logical coordinate system.
	 */
	memltofront(i);
	wasclear = l->clear;
	if(nsave){
		if(!wasclear)
			memimagedraw(nsave, nsave->r, l->save, l->save->r.min, nil, Pt(0,0), S);
		freememimage(l->save);
		l->save = nsave;
	}
	delta = subpt(log, i->r.min);
	i->r = rectaddpt(i->r, delta);
	i->clipr = rectaddpt(i->clipr, delta);
	l->delta = subpt(l->screenr.min, i->r.min);
	if(eqscr)
		return 0;

	/*
	 * To clean up old position, make a shadow window there, don't paint it,
	 * push it behind this one, and (later) delete it.  Because the refresh function
	 * for this fake window is a no-op, this will cause no graphics action except
	 * to restore the background and expose the windows previously hidden.
	 */
	shad = memlalloc(s, oldr, memlnorefresh, nil, DNofill);
	if(shad == nil)
		return -1;
	s->frontmost = i;
	if(s->rearmost == i)
		s->rearmost = shad;
	else
		l->rear->layer->front = shad;
	shad->layer->front = i;
	shad->layer->rear = l->rear;
	l->rear = shad;
	l->front = nil;
	shad->layer->clear = 0;

	/*
	 * Shadow is now holding down the fort at the old position.
	 * Move the window and hide things obscured by new position.
	 */
	for(t=l->rear->layer->rear; t!=nil; t=t->layer->rear){
		x = newr;
		overlap = rectclip(&x, t->layer->screenr);
		if(overlap){
			memlhide(t, x);
			t->layer->clear = 0;
		}
	}
	l->screenr = newr;
	l->delta = subpt(scr, i->r.min);
	l->clear = rectinrect(newr, l->screen->image->clipr);

	/*
	 * Everything's covered.  Copy to new position and delete shadow window.
	 */
	if(wasclear)
		memdraw(s->image, newr, s->image, oldr.min, nil, Pt(0,0), S);
	else
		memlexpose(i, newr);
	memldelete(shad);

	return 1;
}
Ejemplo n.º 10
0
Memimage*
memlalloc(Memscreen *s, Rectangle screenr, Refreshfn refreshfn, void *refreshptr, ulong val)
{
	Memlayer *l;
	Memimage *n;
	static Memimage *paint;

	if(paint == nil){
		paint = allocmemimage(Rect(0,0,1,1), RGBA32);
		if(paint == nil)
			return nil;
		paint->flags |= Frepl;
		paint->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
	}

	n = allocmemimaged(screenr, s->image->chan, s->image->data);
	if(n == nil)
		return nil;
	l = malloc(sizeof(Memlayer));
	if(l == nil){
		free(n);
		return nil;
	}

	l->screen = s;
	if(refreshfn)
		l->save = nil;
	else{
		l->save = allocmemimage(screenr, s->image->chan);
		if(l->save == nil){
			free(l);
			free(n);
			return nil;
		}
		/* allocmemimage doesn't initialize memory; this paints save area */
		if(val != DNofill)
			memfillcolor(l->save, val);
	}
	l->refreshfn = refreshfn;
	l->refreshptr = nil;	/* don't set it until we're done */
	l->screenr = screenr;
	l->delta = Pt(0,0);

	n->data->ref++;
	n->zero = s->image->zero;
	n->width = s->image->width;
	n->layer = l;

	/* start with new window behind all existing ones */
	l->front = s->rearmost;
	l->rear = nil;
	if(s->rearmost)
		s->rearmost->layer->rear = n;
	s->rearmost = n;
	if(s->frontmost == nil)
		s->frontmost = n;
	l->clear = 0;

	/* now pull new window to front */
	_memltofrontfill(n, val != DNofill);
	l->refreshptr = refreshptr;

	/*
	 * paint with requested color; previously exposed areas are already right
	 * if this window has backing store, but just painting the whole thing is simplest.
	 */
	if(val != DNofill){
		memsetchan(paint, n->chan);
		memfillcolor(paint, val);
		memdraw(n, n->r, paint, n->r.min, nil, n->r.min, S);
	}
	return n;
}
Ejemplo n.º 11
0
Archivo: arc.c Proyecto: 0intro/vx32
/*
 * make a "wedge" mask covering the desired angle and contained in
 * a surrounding square; draw a full ellipse; intersect that with the
 * wedge to make a mask through which to copy src to dst.
 */
void
memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int alpha, int phi, int op)
{
	int i, w, beta, tmp, c1, c2, m, m1;
	Rectangle rect;
	Point p,	bnd[8];
	Memimage *wedge, *figure, *mask;

	if(a < 0)
		a = -a;
	if(b < 0)
		b = -b;
	w = t;
	if(w < 0)
		w = 0;
	alpha = -alpha;		/* compensate for upside-down coords */
	phi = -phi;
	beta = alpha + phi;
	if(phi < 0){
		tmp = alpha;
		alpha = beta;
		beta = tmp;
		phi = -phi;
	}
	if(phi >= 360){
		memellipse(dst, c, a, b, t, src, sp, op);
		return;
	}
	while(alpha < 0)
		alpha += 360;
	while(beta < 0)
		beta += 360;
	c1 = alpha/90 & 3;	/* number of nearest corner */
	c2 = beta/90 & 3;
		/*
		 * icossin returns point at radius ICOSSCALE.
		 * multiplying by m1 moves it outside the ellipse
		*/
	rect = Rect(-a-w, -b-w, a+w+1, b+w+1);
	m = rect.max.x;	/* inradius of bounding square */
	if(m < rect.max.y)
		m = rect.max.y;
	m1 = (m+ICOSSCALE-1) >> 10;
	m = m1 << 10;		/* assure m1*cossin is inside */
	i = 0;
	bnd[i++] = Pt(0,0);
	icossin(alpha, &p.x, &p.y);
	bnd[i++] = mulpt(p, m1);
	for(;;) {
		bnd[i++] = mulpt(corners[c1], m);
		if(c1==c2 && phi<180)
			break;
		c1 = (c1+1) & 3;
		phi -= 90;
	}
	icossin(beta, &p.x, &p.y);
	bnd[i++] = mulpt(p, m1);

	figure = nil;
	mask = nil;
	wedge = allocmemimage(rect, GREY1);
	if(wedge == nil)
		goto Return;
	memfillcolor(wedge, DTransparent);
	memfillpoly(wedge, bnd, i, ~0, memopaque, p00, S);
	figure = allocmemimage(rect, GREY1);
	if(figure == nil)
		goto Return;
	memfillcolor(figure, DTransparent);
	memellipse(figure, p00, a, b, t, memopaque, p00, S);
	mask = allocmemimage(rect, GREY1);
	if(mask == nil)
		goto Return;
	memfillcolor(mask, DTransparent);
	memimagedraw(mask, rect, figure, rect.min, wedge, rect.min, S);
	c = subpt(c, dst->r.min);
	memdraw(dst, dst->r, src, subpt(sp, c), mask, subpt(p00, c), op);

    Return:
	freememimage(wedge);
	freememimage(figure);
	freememimage(mask);
}
Ejemplo n.º 12
0
Archivo: draw.c Proyecto: 0intro/vx32
void
memdraw(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1, int op)
{
	struct Draw d;
	Rectangle srcr, tr, mr;
	Memlayer *dl, *sl;

	if(drawdebug)
		iprint("memdraw %p %R %p %P %p %P\n", dst, r, src, p0, mask, p1);

	if(mask == nil)
		mask = memopaque;

	if(mask->layer){
if(drawdebug)	iprint("mask->layer != nil\n");
		return;	/* too hard, at least for now */
	}

    Top:
	if(dst->layer==nil && src->layer==nil){
		memimagedraw(dst, r, src, p0, mask, p1, op);
		return;
	}

	if(drawclip(dst, &r, src, &p0, mask, &p1, &srcr, &mr) == 0){
if(drawdebug)	iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->clipr, mask->clipr);
		return;
	}

	/*
 	 * Convert to screen coordinates.
	 */
	dl = dst->layer;
	if(dl != nil){
		r.min.x += dl->delta.x;
		r.min.y += dl->delta.y;
		r.max.x += dl->delta.x;
		r.max.y += dl->delta.y;
	}
    Clearlayer:
	if(dl!=nil && dl->clear){
		if(src == dst){
			p0.x += dl->delta.x;
			p0.y += dl->delta.y;
			src = dl->screen->image;
		}
		dst = dl->screen->image;
		goto Top;
	}

	sl = src->layer;
	if(sl != nil){
		p0.x += sl->delta.x;
		p0.y += sl->delta.y;
		srcr.min.x += sl->delta.x;
		srcr.min.y += sl->delta.y;
		srcr.max.x += sl->delta.x;
		srcr.max.y += sl->delta.y;
	}

	/*
	 * Now everything is in screen coordinates.
	 * mask is an image.  dst and src are images or obscured layers.
	 */

	/*
	 * if dst and src are the same layer, just draw in save area and expose.
	 */
	if(dl!=nil && dst==src){
		if(dl->save == nil)
			return;	/* refresh function makes this case unworkable */
		if(rectXrect(r, srcr)){
			tr = r;
			if(srcr.min.x < tr.min.x){
				p1.x += tr.min.x - srcr.min.x;
				tr.min.x = srcr.min.x;
			}
			if(srcr.min.y < tr.min.y){
				p1.y += tr.min.x - srcr.min.x;
				tr.min.y = srcr.min.y;
			}
			if(srcr.max.x > tr.max.x)
				tr.max.x = srcr.max.x;
			if(srcr.max.y > tr.max.y)
				tr.max.y = srcr.max.y;
			memlhide(dst, tr);
		}else{
			memlhide(dst, r);
			memlhide(dst, srcr);
		}
		memdraw(dl->save, rectsubpt(r, dl->delta), dl->save,
			subpt(srcr.min, src->layer->delta), mask, p1, op);
		memlexpose(dst, r);
		return;
	}

	if(sl){
		if(sl->clear){
			src = sl->screen->image;
			if(dl != nil){
				r.min.x -= dl->delta.x;
				r.min.y -= dl->delta.y;
				r.max.x -= dl->delta.x;
				r.max.y -= dl->delta.y;
			}
			goto Top;
		}
		/* relatively rare case; use save area */
		if(sl->save == nil)
			return;	/* refresh function makes this case unworkable */
		memlhide(src, srcr);
		/* convert back to logical coordinates */
		p0.x -= sl->delta.x;
		p0.y -= sl->delta.y;
		srcr.min.x -= sl->delta.x;
		srcr.min.y -= sl->delta.y;
		srcr.max.x -= sl->delta.x;
		srcr.max.y -= sl->delta.y;
		src = src->layer->save;
	}

	/*
	 * src is now an image.  dst may be an image or a clear layer
	 */
	if(dst->layer==nil)
		goto Top;
	if(dst->layer->clear)
		goto Clearlayer;

	/*
	 * dst is an obscured layer
	 */
	d.deltas = subpt(p0, r.min);
	d.deltam = subpt(p1, r.min);
	d.dstlayer = dl;
	d.src = src;
	d.op = op;
	d.mask = mask;
	_memlayerop(ldrawop, dst, r, r, &d);
}