]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libdraw/poly.c
acme: fix border size, autoindent undo: imported from plan9port (thanks jxy)
[plan9front.git] / sys / src / libdraw / poly.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4
5 static
6 uchar*
7 addcoord(uchar *p, int oldx, int newx)
8 {
9         int dx;
10
11         dx = newx-oldx;
12         /* does dx fit in 7 signed bits? */
13         if((unsigned)(dx - -0x40) <= 0x7F)
14                 *p++ = dx&0x7F;
15         else{
16                 *p++ = 0x80 | (newx&0x7F);
17                 *p++ = newx>>7;
18                 *p++ = newx>>15;
19         }
20         return p;
21 }
22
23 static
24 void
25 dopoly(int cmd, Image *dst, Point *pp, int np, int end0, int end1, int radius, Image *src, Point *sp, Drawop op)
26 {
27         uchar *a, *t, *u;
28         int i, ox, oy;
29
30         if(np == 0)
31                 return;
32         t = malloc(np*2*3);
33         if(t == nil)
34                 return;
35         u = t;
36         ox = oy = 0;
37         for(i=0; i<np; i++){
38                 u = addcoord(u, ox, pp[i].x);
39                 ox = pp[i].x;
40                 u = addcoord(u, oy, pp[i].y);
41                 oy = pp[i].y;
42         }
43
44         _setdrawop(dst->display, op);
45
46         a = bufimage(dst->display, 1+4+2+4+4+4+4+2*4+(u-t));
47         if(a == nil){
48                 free(t);
49                 fprint(2, "image poly: %r\n");
50                 return;
51         }
52         a[0] = cmd;
53         BPLONG(a+1, dst->id);
54         BPSHORT(a+5, np-1);
55         BPLONG(a+7, end0);
56         BPLONG(a+11, end1);
57         BPLONG(a+15, radius);
58         BPLONG(a+19, src->id);
59         BPLONG(a+23, sp->x);
60         BPLONG(a+27, sp->y);
61         memmove(a+31, t, u-t);
62         free(t);
63 }
64
65 void
66 poly(Image *dst, Point *p, int np, int end0, int end1, int radius, Image *src, Point sp)
67 {
68         dopoly('p', dst, p, np, end0, end1, radius, src, &sp, SoverD);
69 }
70
71 void
72 polyop(Image *dst, Point *p, int np, int end0, int end1, int radius, Image *src, Point sp, Drawop op)
73 {
74         dopoly('p', dst, p, np, end0, end1, radius, src, &sp, op);
75 }
76
77 void
78 fillpoly(Image *dst, Point *p, int np, int wind, Image *src, Point sp)
79 {
80         dopoly('P', dst, p, np, wind, 0, 0, src, &sp, SoverD);
81 }
82
83 void
84 fillpolyop(Image *dst, Point *p, int np, int wind, Image *src, Point sp, Drawop op)
85 {
86         dopoly('P', dst, p, np, wind, 0, 0, src, &sp, op);
87 }