URI:
       tarc.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tarc.c (2586B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <memdraw.h>
            5 
            6 /*
            7  * elarc(dst,c,a,b,t,src,sp,alpha,phi)
            8  *   draws the part of an ellipse between rays at angles alpha and alpha+phi
            9  *   measured counterclockwise from the positive x axis. other
           10  *   arguments are as for ellipse(dst,c,a,b,t,src,sp)
           11  */
           12 
           13 enum
           14 {
           15         R, T, L, B        /* right, top, left, bottom */
           16 };
           17 
           18 static
           19 Point corners[] = {
           20         {1,1},
           21         {-1,1},
           22         {-1,-1},
           23         {1,-1}
           24 };
           25 
           26 static
           27 Point p00;
           28 
           29 /*
           30  * make a "wedge" mask covering the desired angle and contained in
           31  * a surrounding square; draw a full ellipse; intersect that with the
           32  * wedge to make a mask through which to copy src to dst.
           33  */
           34 void
           35 memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int alpha, int phi, int op)
           36 {
           37         int i, w, beta, tmp, c1, c2, m, m1;
           38         Rectangle rect;
           39         Point p,        bnd[8];
           40         Memimage *wedge, *figure, *mask;
           41 
           42         if(a < 0)
           43                 a = -a;
           44         if(b < 0)
           45                 b = -b;
           46         w = t;
           47         if(w < 0)
           48                 w = 0;
           49         alpha = -alpha;                /* compensate for upside-down coords */
           50         phi = -phi;
           51         beta = alpha + phi;
           52         if(phi < 0){
           53                 tmp = alpha;
           54                 alpha = beta;
           55                 beta = tmp;
           56                 phi = -phi;
           57         }
           58         if(phi >= 360){
           59                 memellipse(dst, c, a, b, t, src, sp, op);
           60                 return;
           61         }
           62         while(alpha < 0)
           63                 alpha += 360;
           64         while(beta < 0)
           65                 beta += 360;
           66         c1 = alpha/90 & 3;        /* number of nearest corner */
           67         c2 = beta/90 & 3;
           68                 /*
           69                  * icossin returns point at radius ICOSSCALE.
           70                  * multiplying by m1 moves it outside the ellipse
           71                 */
           72         rect = Rect(-a-w, -b-w, a+w+1, b+w+1);
           73         m = rect.max.x;        /* inradius of bounding square */
           74         if(m < rect.max.y)
           75                 m = rect.max.y;
           76         m1 = (m+ICOSSCALE-1) >> 10;
           77         m = m1 << 10;                /* assure m1*cossin is inside */
           78         i = 0;
           79         bnd[i++] = Pt(0,0);
           80         icossin(alpha, &p.x, &p.y);
           81         bnd[i++] = mulpt(p, m1);
           82         for(;;) {
           83                 bnd[i++] = mulpt(corners[c1], m);
           84                 if(c1==c2 && phi<180)
           85                         break;
           86                 c1 = (c1+1) & 3;
           87                 phi -= 90;
           88         }
           89         icossin(beta, &p.x, &p.y);
           90         bnd[i++] = mulpt(p, m1);
           91 
           92         figure = nil;
           93         mask = nil;
           94         wedge = allocmemimage(rect, GREY1);
           95         if(wedge == nil)
           96                 goto Return;
           97         memfillcolor(wedge, DTransparent);
           98         memfillpoly(wedge, bnd, i, ~0, memopaque, p00, S);
           99         figure = allocmemimage(rect, GREY1);
          100         if(figure == nil)
          101                 goto Return;
          102         memfillcolor(figure, DTransparent);
          103         memellipse(figure, p00, a, b, t, memopaque, p00, S);
          104         mask = allocmemimage(rect, GREY1);
          105         if(mask == nil)
          106                 goto Return;
          107         memfillcolor(mask, DTransparent);
          108         memimagedraw(mask, rect, figure, rect.min, wedge, rect.min, S);
          109         c = subpt(c, dst->r.min);
          110         memdraw(dst, dst->r, src, subpt(sp, c), mask, subpt(p00, c), op);
          111 
          112     Return:
          113         freememimage(wedge);
          114         freememimage(figure);
          115         freememimage(mask);
          116 }