9fans.net/go@v0.0.5/draw/poly.go (about) 1 package draw 2 3 func addcoord(p []byte, oldx, newx int) int { 4 dx := newx - oldx 5 if uint(dx - -0x40) <= 0x7F { 6 p[0] = byte(dx & 0x7F) 7 return 1 8 } 9 p[0] = 0x80 | byte(newx&0x7F) 10 p[1] = byte(newx >> 7) 11 p[2] = byte(newx >> 15) 12 return 3 13 } 14 15 func dopoly(cmd byte, dst *Image, pp []Point, end0, end1 End, radius int, src *Image, sp Point, op Op) { 16 if len(pp) == 0 { 17 return 18 } 19 20 setdrawop(dst.Display, op) 21 m := 1 + 4 + 2 + 4 + 4 + 4 + 4 + 2*4 + len(pp)*2*3 // too much 22 a := dst.Display.bufimage(m) // too much 23 a[0] = cmd 24 bplong(a[1:], uint32(dst.id)) 25 bpshort(a[5:], uint16(len(pp)-1)) 26 bplong(a[7:], uint32(end0)) 27 bplong(a[11:], uint32(end1)) 28 bplong(a[15:], uint32(radius)) 29 bplong(a[19:], uint32(src.id)) 30 bplong(a[23:], uint32(sp.X)) 31 bplong(a[27:], uint32(sp.Y)) 32 o := 31 33 ox, oy := 0, 0 34 for _, p := range pp { 35 o += addcoord(a[o:], ox, p.X) 36 o += addcoord(a[o:], oy, p.Y) 37 ox, oy = p.X, p.Y 38 } 39 d := dst.Display 40 d.buf = d.buf[:len(d.buf)-m+o] 41 } 42 43 // Poly draws a general open polygon; it is conceptually equivalent to a series of 44 // calls to Line joining adjacent points in the array of points p. 45 // The ends end0 and end1 of the polygon are specified as in the Line method; 46 // see the EndSquare and Arrow documentation. 47 // Interior lines are terminated with EndDisc to make smooth joins. 48 // The source is aligned so that sp corresponds to p[0]. 49 func (dst *Image) Poly(p []Point, end0, end1 End, radius int, src *Image, sp Point) { 50 dst.Display.mu.Lock() 51 defer dst.Display.mu.Unlock() 52 dopoly('p', dst, p, end0, end1, radius, src, sp, SoverD) 53 } 54 55 // PolyOp is like Poly but specifies an explicit Porter-Duff operator. 56 func (dst *Image) PolyOp(p []Point, end0, end1 End, radius int, src *Image, sp Point, op Op) { 57 dst.Display.mu.Lock() 58 defer dst.Display.mu.Unlock() 59 dopoly('p', dst, p, end0, end1, radius, src, sp, op) 60 } 61 62 // FillPoly is like Poly but fills in the resulting polygon rather than outlining it. 63 // The source is aligned so sp corresponds to p[0]. 64 // The winding rule parameter wind resolves ambiguities about what to fill if the 65 // polygon is self-intersecting. If wind is ^0, a pixel is inside the polygon 66 // if the polygon's winding number about the point is non-zero. 67 // If wind is 1, a pixel is inside if the winding number is odd. 68 // Complementary values (0 or ^1) cause outside pixels to be filled. 69 // The meaning of other values is undefined. 70 // The polygon is closed with a line if necessary. 71 func (dst *Image) FillPoly(p []Point, wind int, src *Image, sp Point) { 72 dst.Display.mu.Lock() 73 defer dst.Display.mu.Unlock() 74 dopoly('P', dst, p, End(wind), 0, 0, src, sp, SoverD) 75 } 76 77 // FillPolyOp is like FillPoly but specifies an explicit Porter-Duff operator. 78 func (dst *Image) FillPolyOp(p []Point, wind int, src *Image, sp Point, op Op) { 79 dst.Display.mu.Lock() 80 defer dst.Display.mu.Unlock() 81 dopoly('P', dst, p, End(wind), 0, 0, src, sp, op) 82 }