vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

line.c (2586B)


      1 #include "u.h"
      2 #include "lib.h"
      3 #include "draw.h"
      4 #include "memdraw.h"
      5 #include "memlayer.h"
      6 
      7 struct Lline
      8 {
      9 	Point			p0;
     10 	Point			p1;
     11 	Point			delta;
     12 	int			end0;
     13 	int			end1;
     14 	int			radius;
     15 	Point			sp;
     16 	Memlayer		*dstlayer;
     17 	Memimage	*src;
     18 	int			op;
     19 };
     20 
     21 static void llineop(Memimage*, Rectangle, Rectangle, void*, int);
     22 
     23 static
     24 void
     25 _memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op)
     26 {
     27 	Rectangle r;
     28 	struct Lline ll;
     29 	Point d;
     30 	int srcclipped;
     31 	Memlayer *dl;
     32 
     33 	if(radius < 0)
     34 		return;
     35 	if(src->layer)	/* can't draw line with layered source */
     36 		return;
     37 	srcclipped = 0;
     38 
     39    Top:
     40 	dl = dst->layer;
     41 	if(dl == nil){
     42 		_memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr, op);
     43 		return;
     44 	}
     45 	if(!srcclipped){
     46 		d = subpt(sp, p0);
     47 		if(rectclip(&clipr, rectsubpt(src->clipr, d)) == 0)
     48 			return;
     49 		if((src->flags&Frepl)==0 && rectclip(&clipr, rectsubpt(src->r, d))==0)
     50 			return;
     51 		srcclipped = 1;
     52 	}
     53 
     54 	/* dst is known to be a layer */
     55 	p0.x += dl->delta.x;
     56 	p0.y += dl->delta.y;
     57 	p1.x += dl->delta.x;
     58 	p1.y += dl->delta.y;
     59 	clipr.min.x += dl->delta.x;
     60 	clipr.min.y += dl->delta.y;
     61 	clipr.max.x += dl->delta.x;
     62 	clipr.max.y += dl->delta.y;
     63 	if(dl->clear){
     64 		dst = dst->layer->screen->image;
     65 		goto Top;
     66 	}
     67 
     68 	/* XXX */
     69 	/* this is not the correct set of tests */
     70 //	if(log2[dst->depth] != log2[src->depth] || log2[dst->depth]!=3)
     71 //		return;
     72 
     73 	/* can't use sutherland-cohen clipping because lines are wide */
     74 	r = memlinebbox(p0, p1, end0, end1, radius);
     75 	/*
     76 	 * r is now a bounding box for the line;
     77 	 * use it as a clipping rectangle for subdivision
     78 	 */
     79 	if(rectclip(&r, clipr) == 0)
     80 		return;
     81 	ll.p0 = p0;
     82 	ll.p1 = p1;
     83 	ll.end0 = end0;
     84 	ll.end1 = end1;
     85 	ll.sp = sp;
     86 	ll.dstlayer = dst->layer;
     87 	ll.src = src;
     88 	ll.radius = radius;
     89 	ll.delta = dl->delta;
     90 	ll.op = op;
     91 	_memlayerop(llineop, dst, r, r, &ll);
     92 }
     93 
     94 static
     95 void
     96 llineop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave)
     97 {
     98 	struct Lline *ll;
     99 	Point p0, p1;
    100 
    101 	USED(screenr.min.x);
    102 	ll = etc;
    103 	if(insave && ll->dstlayer->save==nil)
    104 		return;
    105 	if(!rectclip(&clipr, screenr))
    106 		return;
    107 	if(insave){
    108 		p0 = subpt(ll->p0, ll->delta);
    109 		p1 = subpt(ll->p1, ll->delta);
    110 		clipr = rectsubpt(clipr, ll->delta);
    111 	}else{
    112 		p0 = ll->p0;
    113 		p1 = ll->p1;
    114 	}
    115 	_memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr, ll->op);
    116 }
    117 
    118 void
    119 memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op)
    120 {
    121 	_memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op);
    122 }