line.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) 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 }