xref: /plan9/sys/src/cmd/unix/drawterm/libmemlayer/line.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include <u.h>
2*8ccd4a63SDavid du Colombier #include <libc.h>
3*8ccd4a63SDavid du Colombier #include <draw.h>
4*8ccd4a63SDavid du Colombier #include <memdraw.h>
5*8ccd4a63SDavid du Colombier #include <memlayer.h>
67dd7cddfSDavid du Colombier 
77dd7cddfSDavid du Colombier struct Lline
87dd7cddfSDavid du Colombier {
97dd7cddfSDavid du Colombier 	Point			p0;
107dd7cddfSDavid du Colombier 	Point			p1;
117dd7cddfSDavid du Colombier 	Point			delta;
127dd7cddfSDavid du Colombier 	int			end0;
137dd7cddfSDavid du Colombier 	int			end1;
147dd7cddfSDavid du Colombier 	int			radius;
157dd7cddfSDavid du Colombier 	Point			sp;
167dd7cddfSDavid du Colombier 	Memlayer		*dstlayer;
177dd7cddfSDavid du Colombier 	Memimage	*src;
18*8ccd4a63SDavid du Colombier 	int			op;
197dd7cddfSDavid du Colombier };
207dd7cddfSDavid du Colombier 
217dd7cddfSDavid du Colombier static void llineop(Memimage*, Rectangle, Rectangle, void*, int);
227dd7cddfSDavid du Colombier 
237dd7cddfSDavid du Colombier static
247dd7cddfSDavid du Colombier void
_memline(Memimage * dst,Point p0,Point p1,int end0,int end1,int radius,Memimage * src,Point sp,Rectangle clipr,int op)25*8ccd4a63SDavid du Colombier _memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op)
267dd7cddfSDavid du Colombier {
277dd7cddfSDavid du Colombier 	Rectangle r;
287dd7cddfSDavid du Colombier 	struct Lline ll;
297dd7cddfSDavid du Colombier 	Point d;
307dd7cddfSDavid du Colombier 	int srcclipped;
317dd7cddfSDavid du Colombier 	Memlayer *dl;
327dd7cddfSDavid du Colombier 
337dd7cddfSDavid du Colombier 	if(radius < 0)
347dd7cddfSDavid du Colombier 		return;
357dd7cddfSDavid du Colombier 	if(src->layer)	/* can't draw line with layered source */
367dd7cddfSDavid du Colombier 		return;
377dd7cddfSDavid du Colombier 	srcclipped = 0;
387dd7cddfSDavid du Colombier 
397dd7cddfSDavid du Colombier    Top:
407dd7cddfSDavid du Colombier 	dl = dst->layer;
417dd7cddfSDavid du Colombier 	if(dl == nil){
42*8ccd4a63SDavid du Colombier 		_memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr, op);
437dd7cddfSDavid du Colombier 		return;
447dd7cddfSDavid du Colombier 	}
457dd7cddfSDavid du Colombier 	if(!srcclipped){
467dd7cddfSDavid du Colombier 		d = subpt(sp, p0);
477dd7cddfSDavid du Colombier 		if(rectclip(&clipr, rectsubpt(src->clipr, d)) == 0)
487dd7cddfSDavid du Colombier 			return;
497dd7cddfSDavid du Colombier 		if((src->flags&Frepl)==0 && rectclip(&clipr, rectsubpt(src->r, d))==0)
507dd7cddfSDavid du Colombier 			return;
517dd7cddfSDavid du Colombier 		srcclipped = 1;
527dd7cddfSDavid du Colombier 	}
537dd7cddfSDavid du Colombier 
547dd7cddfSDavid du Colombier 	/* dst is known to be a layer */
557dd7cddfSDavid du Colombier 	p0.x += dl->delta.x;
567dd7cddfSDavid du Colombier 	p0.y += dl->delta.y;
577dd7cddfSDavid du Colombier 	p1.x += dl->delta.x;
587dd7cddfSDavid du Colombier 	p1.y += dl->delta.y;
597dd7cddfSDavid du Colombier 	clipr.min.x += dl->delta.x;
607dd7cddfSDavid du Colombier 	clipr.min.y += dl->delta.y;
617dd7cddfSDavid du Colombier 	clipr.max.x += dl->delta.x;
627dd7cddfSDavid du Colombier 	clipr.max.y += dl->delta.y;
637dd7cddfSDavid du Colombier 	if(dl->clear){
647dd7cddfSDavid du Colombier 		dst = dst->layer->screen->image;
657dd7cddfSDavid du Colombier 		goto Top;
667dd7cddfSDavid du Colombier 	}
677dd7cddfSDavid du Colombier 
687dd7cddfSDavid du Colombier 	/* XXX */
697dd7cddfSDavid du Colombier 	/* this is not the correct set of tests */
70*8ccd4a63SDavid du Colombier //	if(log2[dst->depth] != log2[src->depth] || log2[dst->depth]!=3)
71*8ccd4a63SDavid du Colombier //		return;
727dd7cddfSDavid du Colombier 
737dd7cddfSDavid du Colombier 	/* can't use sutherland-cohen clipping because lines are wide */
747dd7cddfSDavid du Colombier 	r = memlinebbox(p0, p1, end0, end1, radius);
757dd7cddfSDavid du Colombier 	/*
767dd7cddfSDavid du Colombier 	 * r is now a bounding box for the line;
777dd7cddfSDavid du Colombier 	 * use it as a clipping rectangle for subdivision
787dd7cddfSDavid du Colombier 	 */
797dd7cddfSDavid du Colombier 	if(rectclip(&r, clipr) == 0)
807dd7cddfSDavid du Colombier 		return;
817dd7cddfSDavid du Colombier 	ll.p0 = p0;
827dd7cddfSDavid du Colombier 	ll.p1 = p1;
837dd7cddfSDavid du Colombier 	ll.end0 = end0;
847dd7cddfSDavid du Colombier 	ll.end1 = end1;
857dd7cddfSDavid du Colombier 	ll.sp = sp;
867dd7cddfSDavid du Colombier 	ll.dstlayer = dst->layer;
877dd7cddfSDavid du Colombier 	ll.src = src;
887dd7cddfSDavid du Colombier 	ll.radius = radius;
897dd7cddfSDavid du Colombier 	ll.delta = dl->delta;
90*8ccd4a63SDavid du Colombier 	ll.op = op;
91*8ccd4a63SDavid du Colombier 	_memlayerop(llineop, dst, r, r, &ll);
927dd7cddfSDavid du Colombier }
937dd7cddfSDavid du Colombier 
947dd7cddfSDavid du Colombier static
957dd7cddfSDavid du Colombier void
llineop(Memimage * dst,Rectangle screenr,Rectangle clipr,void * etc,int insave)967dd7cddfSDavid du Colombier llineop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave)
977dd7cddfSDavid du Colombier {
987dd7cddfSDavid du Colombier 	struct Lline *ll;
997dd7cddfSDavid du Colombier 	Point p0, p1;
1007dd7cddfSDavid du Colombier 
1017dd7cddfSDavid du Colombier 	USED(screenr.min.x);
1027dd7cddfSDavid du Colombier 	ll = etc;
1037dd7cddfSDavid du Colombier 	if(insave && ll->dstlayer->save==nil)
1047dd7cddfSDavid du Colombier 		return;
1057dd7cddfSDavid du Colombier 	if(!rectclip(&clipr, screenr))
1067dd7cddfSDavid du Colombier 		return;
1077dd7cddfSDavid du Colombier 	if(insave){
1087dd7cddfSDavid du Colombier 		p0 = subpt(ll->p0, ll->delta);
1097dd7cddfSDavid du Colombier 		p1 = subpt(ll->p1, ll->delta);
1107dd7cddfSDavid du Colombier 		clipr = rectsubpt(clipr, ll->delta);
1117dd7cddfSDavid du Colombier 	}else{
1127dd7cddfSDavid du Colombier 		p0 = ll->p0;
1137dd7cddfSDavid du Colombier 		p1 = ll->p1;
1147dd7cddfSDavid du Colombier 	}
115*8ccd4a63SDavid du Colombier 	_memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr, ll->op);
1167dd7cddfSDavid du Colombier }
1177dd7cddfSDavid du Colombier 
1187dd7cddfSDavid du Colombier void
memline(Memimage * dst,Point p0,Point p1,int end0,int end1,int radius,Memimage * src,Point sp,int op)119*8ccd4a63SDavid du Colombier memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op)
1207dd7cddfSDavid du Colombier {
121*8ccd4a63SDavid du Colombier 	_memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op);
1227dd7cddfSDavid du Colombier }
123