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  }