summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/code.google.com/p/draw2d/draw2d/raster/polygon.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/code.google.com/p/draw2d/draw2d/raster/polygon.go')
-rw-r--r--Godeps/_workspace/src/code.google.com/p/draw2d/draw2d/raster/polygon.go581
1 files changed, 0 insertions, 581 deletions
diff --git a/Godeps/_workspace/src/code.google.com/p/draw2d/draw2d/raster/polygon.go b/Godeps/_workspace/src/code.google.com/p/draw2d/draw2d/raster/polygon.go
deleted file mode 100644
index 2a19e7355..000000000
--- a/Godeps/_workspace/src/code.google.com/p/draw2d/draw2d/raster/polygon.go
+++ /dev/null
@@ -1,581 +0,0 @@
-// Copyright 2011 The draw2d Authors. All rights reserved.
-// created: 27/05/2011 by Laurent Le Goff
-package raster
-
-const (
- POLYGON_CLIP_NONE = iota
- POLYGON_CLIP_LEFT
- POLYGON_CLIP_RIGHT
- POLYGON_CLIP_TOP
- POLYGON_CLIP_BOTTOM
-)
-
-type Polygon []float64
-
-type PolygonEdge struct {
- X, Slope float64
- FirstLine, LastLine int
- Winding int16
-}
-
-//! A more optimized representation of a polygon edge.
-type PolygonScanEdge struct {
- FirstLine, LastLine int
- Winding int16
- X Fix
- Slope Fix
- SlopeFix Fix
- NextEdge *PolygonScanEdge
-}
-
-//! Calculates the edges of the polygon with transformation and clipping to edges array.
-/*! \param startIndex the index for the first vertex.
- * \param vertexCount the amount of vertices to convert.
- * \param edges the array for result edges. This should be able to contain 2*aVertexCount edges.
- * \param tr the transformation matrix for the polygon.
- * \param aClipRectangle the clip rectangle.
- * \return the amount of edges in the result.
- */
-func (p Polygon) getEdges(startIndex, vertexCount int, edges []PolygonEdge, tr [6]float64, clipBound [4]float64) int {
- startIndex = startIndex * 2
- endIndex := startIndex + vertexCount*2
- if endIndex > len(p) {
- endIndex = len(p)
- }
-
- x := p[startIndex]
- y := p[startIndex+1]
- // inline transformation
- prevX := x*tr[0] + y*tr[2] + tr[4]
- prevY := x*tr[1] + y*tr[3] + tr[5]
-
- //! Calculates the clip flags for a point.
- prevClipFlags := POLYGON_CLIP_NONE
- if prevX < clipBound[0] {
- prevClipFlags |= POLYGON_CLIP_LEFT
- } else if prevX >= clipBound[2] {
- prevClipFlags |= POLYGON_CLIP_RIGHT
- }
-
- if prevY < clipBound[1] {
- prevClipFlags |= POLYGON_CLIP_TOP
- } else if prevY >= clipBound[3] {
- prevClipFlags |= POLYGON_CLIP_BOTTOM
- }
-
- edgeCount := 0
- var k, clipFlags, clipSum, clipUnion int
- var xleft, yleft, xright, yright, oldY, maxX, minX float64
- var swapWinding int16
- for n := startIndex; n < endIndex; n = n + 2 {
- k = (n + 2) % len(p)
- x = p[k]*tr[0] + p[k+1]*tr[2] + tr[4]
- y = p[k]*tr[1] + p[k+1]*tr[3] + tr[5]
-
- //! Calculates the clip flags for a point.
- clipFlags = POLYGON_CLIP_NONE
- if prevX < clipBound[0] {
- clipFlags |= POLYGON_CLIP_LEFT
- } else if prevX >= clipBound[2] {
- clipFlags |= POLYGON_CLIP_RIGHT
- }
- if prevY < clipBound[1] {
- clipFlags |= POLYGON_CLIP_TOP
- } else if prevY >= clipBound[3] {
- clipFlags |= POLYGON_CLIP_BOTTOM
- }
-
- clipSum = prevClipFlags | clipFlags
- clipUnion = prevClipFlags & clipFlags
-
- // Skip all edges that are either completely outside at the top or at the bottom.
- if clipUnion&(POLYGON_CLIP_TOP|POLYGON_CLIP_BOTTOM) == 0 {
- if clipUnion&POLYGON_CLIP_RIGHT != 0 {
- // Both clip to right, edge is a vertical line on the right side
- if getVerticalEdge(prevY, y, clipBound[2], &edges[edgeCount], clipBound) {
- edgeCount++
- }
- } else if clipUnion&POLYGON_CLIP_LEFT != 0 {
- // Both clip to left, edge is a vertical line on the left side
- if getVerticalEdge(prevY, y, clipBound[0], &edges[edgeCount], clipBound) {
- edgeCount++
- }
- } else if clipSum&(POLYGON_CLIP_RIGHT|POLYGON_CLIP_LEFT) == 0 {
- // No clipping in the horizontal direction
- if getEdge(prevX, prevY, x, y, &edges[edgeCount], clipBound) {
- edgeCount++
- }
- } else {
- // Clips to left or right or both.
-
- if x < prevX {
- xleft, yleft = x, y
- xright, yright = prevX, prevY
- swapWinding = -1
- } else {
- xleft, yleft = prevX, prevY
- xright, yright = x, y
- swapWinding = 1
- }
-
- slope := (yright - yleft) / (xright - xleft)
-
- if clipSum&POLYGON_CLIP_RIGHT != 0 {
- // calculate new position for the right vertex
- oldY = yright
- maxX = clipBound[2]
-
- yright = yleft + (maxX-xleft)*slope
- xright = maxX
-
- // add vertical edge for the overflowing part
- if getVerticalEdge(yright, oldY, maxX, &edges[edgeCount], clipBound) {
- edges[edgeCount].Winding *= swapWinding
- edgeCount++
- }
- }
-
- if clipSum&POLYGON_CLIP_LEFT != 0 {
- // calculate new position for the left vertex
- oldY = yleft
- minX = clipBound[0]
-
- yleft = yleft + (minX-xleft)*slope
- xleft = minX
-
- // add vertical edge for the overflowing part
- if getVerticalEdge(oldY, yleft, minX, &edges[edgeCount], clipBound) {
- edges[edgeCount].Winding *= swapWinding
- edgeCount++
- }
- }
-
- if getEdge(xleft, yleft, xright, yright, &edges[edgeCount], clipBound) {
- edges[edgeCount].Winding *= swapWinding
- edgeCount++
- }
- }
- }
-
- prevClipFlags = clipFlags
- prevX = x
- prevY = y
- }
-
- return edgeCount
-}
-
-//! Creates a polygon edge between two vectors.
-/*! Clips the edge vertically to the clip rectangle. Returns true for edges that
- * should be rendered, false for others.
- */
-func getEdge(x0, y0, x1, y1 float64, edge *PolygonEdge, clipBound [4]float64) bool {
- var startX, startY, endX, endY float64
- var winding int16
-
- if y0 <= y1 {
- startX = x0
- startY = y0
- endX = x1
- endY = y1
- winding = 1
- } else {
- startX = x1
- startY = y1
- endX = x0
- endY = y0
- winding = -1
- }
-
- // Essentially, firstLine is floor(startY + 1) and lastLine is floor(endY).
- // These are refactored to integer casts in order to avoid function
- // calls. The difference with integer cast is that numbers are always
- // rounded towards zero. Since values smaller than zero get clipped away,
- // only coordinates between 0 and -1 require greater attention as they
- // also round to zero. The problems in this range can be avoided by
- // adding one to the values before conversion and subtracting after it.
-
- firstLine := int(startY + 1)
- lastLine := int(endY+1) - 1
-
- minClip := int(clipBound[1])
- maxClip := int(clipBound[3])
-
- // If start and end are on the same line, the edge doesn't cross
- // any lines and thus can be ignored.
- // If the end is smaller than the first line, edge is out.
- // If the start is larger than the last line, edge is out.
- if firstLine > lastLine || lastLine < minClip || firstLine >= maxClip {
- return false
- }
-
- // Adjust the start based on the target.
- if firstLine < minClip {
- firstLine = minClip
- }
-
- if lastLine >= maxClip {
- lastLine = maxClip - 1
- }
- edge.Slope = (endX - startX) / (endY - startY)
- edge.X = startX + (float64(firstLine)-startY)*edge.Slope
- edge.Winding = winding
- edge.FirstLine = firstLine
- edge.LastLine = lastLine
-
- return true
-}
-
-//! Creates a vertical polygon edge between two y values.
-/*! Clips the edge vertically to the clip rectangle. Returns true for edges that
- * should be rendered, false for others.
- */
-func getVerticalEdge(startY, endY, x float64, edge *PolygonEdge, clipBound [4]float64) bool {
- var start, end float64
- var winding int16
- if startY < endY {
- start = startY
- end = endY
- winding = 1
- } else {
- start = endY
- end = startY
- winding = -1
- }
-
- firstLine := int(start + 1)
- lastLine := int(end+1) - 1
-
- minClip := int(clipBound[1])
- maxClip := int(clipBound[3])
-
- // If start and end are on the same line, the edge doesn't cross
- // any lines and thus can be ignored.
- // If the end is smaller than the first line, edge is out.
- // If the start is larger than the last line, edge is out.
- if firstLine > lastLine || lastLine < minClip || firstLine >= maxClip {
- return false
- }
-
- // Adjust the start based on the clip rect.
- if firstLine < minClip {
- firstLine = minClip
- }
- if lastLine >= maxClip {
- lastLine = maxClip - 1
- }
-
- edge.Slope = 0
- edge.X = x
- edge.Winding = winding
- edge.FirstLine = firstLine
- edge.LastLine = lastLine
-
- return true
-}
-
-type VertexData struct {
- X, Y float64
- ClipFlags int
- Line int
-}
-
-//! Calculates the edges of the polygon with transformation and clipping to edges array.
-/*! Note that this may return upto three times the amount of edges that the polygon has vertices,
- * in the unlucky case where both left and right side get clipped for all edges.
- * \param edges the array for result edges. This should be able to contain 2*aVertexCount edges.
- * \param aTransformation the transformation matrix for the polygon.
- * \param aClipRectangle the clip rectangle.
- * \return the amount of edges in the result.
- */
-func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound [4]float64) int {
- var n int
- vertexData := make([]VertexData, len(p)/2+1)
- for n = 0; n < len(vertexData)-1; n = n + 1 {
- k := n * 2
- vertexData[n].X = p[k]*tr[0] + p[k+1]*tr[2] + tr[4]
- vertexData[n].Y = p[k]*tr[1] + p[k+1]*tr[3] + tr[5]
- // Calculate clip flags for all vertices.
- vertexData[n].ClipFlags = POLYGON_CLIP_NONE
- if vertexData[n].X < clipBound[0] {
- vertexData[n].ClipFlags |= POLYGON_CLIP_LEFT
- } else if vertexData[n].X >= clipBound[2] {
- vertexData[n].ClipFlags |= POLYGON_CLIP_RIGHT
- }
- if vertexData[n].Y < clipBound[1] {
- vertexData[n].ClipFlags |= POLYGON_CLIP_TOP
- } else if vertexData[n].Y >= clipBound[3] {
- vertexData[n].ClipFlags |= POLYGON_CLIP_BOTTOM
- }
-
- // Calculate line of the vertex. If the vertex is clipped by top or bottom, the line
- // is determined by the clip rectangle.
- if vertexData[n].ClipFlags&POLYGON_CLIP_TOP != 0 {
- vertexData[n].Line = int(clipBound[1])
- } else if vertexData[n].ClipFlags&POLYGON_CLIP_BOTTOM != 0 {
- vertexData[n].Line = int(clipBound[3] - 1)
- } else {
- vertexData[n].Line = int(vertexData[n].Y+1) - 1
- }
- }
-
- // Copy the data from 0 to the last entry to make the data to loop.
- vertexData[len(vertexData)-1] = vertexData[0]
-
- // Transform the first vertex; store.
- // Process mVertexCount - 1 times, next is n+1
- // copy the first vertex to
- // Process 1 time, next is n
-
- edgeCount := 0
- for n = 0; n < len(vertexData)-1; n++ {
- clipSum := vertexData[n].ClipFlags | vertexData[n+1].ClipFlags
- clipUnion := vertexData[n].ClipFlags & vertexData[n+1].ClipFlags
-
- if clipUnion&(POLYGON_CLIP_TOP|POLYGON_CLIP_BOTTOM) == 0 &&
- vertexData[n].Line != vertexData[n+1].Line {
- var startIndex, endIndex int
- var winding int16
- if vertexData[n].Y < vertexData[n+1].Y {
- startIndex = n
- endIndex = n + 1
- winding = 1
- } else {
- startIndex = n + 1
- endIndex = n
- winding = -1
- }
-
- firstLine := vertexData[startIndex].Line + 1
- lastLine := vertexData[endIndex].Line
-
- if clipUnion&POLYGON_CLIP_RIGHT != 0 {
- // Both clip to right, edge is a vertical line on the right side
- edges[edgeCount].FirstLine = firstLine
- edges[edgeCount].LastLine = lastLine
- edges[edgeCount].Winding = winding
- edges[edgeCount].X = Fix(clipBound[2] * FIXED_FLOAT_COEF)
- edges[edgeCount].Slope = 0
- edges[edgeCount].SlopeFix = 0
-
- edgeCount++
- } else if clipUnion&POLYGON_CLIP_LEFT != 0 {
- // Both clip to left, edge is a vertical line on the left side
- edges[edgeCount].FirstLine = firstLine
- edges[edgeCount].LastLine = lastLine
- edges[edgeCount].Winding = winding
- edges[edgeCount].X = Fix(clipBound[0] * FIXED_FLOAT_COEF)
- edges[edgeCount].Slope = 0
- edges[edgeCount].SlopeFix = 0
-
- edgeCount++
- } else if clipSum&(POLYGON_CLIP_RIGHT|POLYGON_CLIP_LEFT) == 0 {
- // No clipping in the horizontal direction
- slope := (vertexData[endIndex].X -
- vertexData[startIndex].X) /
- (vertexData[endIndex].Y -
- vertexData[startIndex].Y)
-
- // If there is vertical clip (for the top) it will be processed here. The calculation
- // should be done for all non-clipping edges as well to determine the accurate position
- // where the edge crosses the first scanline.
- startx := vertexData[startIndex].X +
- (float64(firstLine)-vertexData[startIndex].Y)*slope
-
- edges[edgeCount].FirstLine = firstLine
- edges[edgeCount].LastLine = lastLine
- edges[edgeCount].Winding = winding
- edges[edgeCount].X = Fix(startx * FIXED_FLOAT_COEF)
- edges[edgeCount].Slope = Fix(slope * FIXED_FLOAT_COEF)
-
- if lastLine-firstLine >= SLOPE_FIX_STEP {
- edges[edgeCount].SlopeFix = Fix(slope*SLOPE_FIX_STEP*FIXED_FLOAT_COEF) -
- edges[edgeCount].Slope<<SLOPE_FIX_SHIFT
- } else {
- edges[edgeCount].SlopeFix = 0
- }
-
- edgeCount++
- } else {
- // Clips to left or right or both.
- slope := (vertexData[endIndex].X -
- vertexData[startIndex].X) /
- (vertexData[endIndex].Y -
- vertexData[startIndex].Y)
-
- // The edge may clip to both left and right.
- // The clip results in one or two new vertices, and one to three segments.
- // The rounding for scanlines may produce a result where any of the segments is
- // ignored.
-
- // The start is always above the end. Calculate the clip positions to clipVertices.
- // It is possible that only one of the vertices exist. This will be detected from the
- // clip flags of the vertex later, so they are initialized here.
- var clipVertices [2]VertexData
-
- if vertexData[startIndex].X <
- vertexData[endIndex].X {
- clipVertices[0].X = clipBound[0]
- clipVertices[1].X = clipBound[2]
- clipVertices[0].ClipFlags = POLYGON_CLIP_LEFT
- clipVertices[1].ClipFlags = POLYGON_CLIP_RIGHT
- } else {
- clipVertices[0].X = clipBound[2]
- clipVertices[1].X = clipBound[0]
- clipVertices[0].ClipFlags = POLYGON_CLIP_RIGHT
- clipVertices[1].ClipFlags = POLYGON_CLIP_LEFT
- }
-
- var p int
- for p = 0; p < 2; p++ {
- // Check if either of the vertices crosses the edge marked for the clip vertex
- if clipSum&clipVertices[p].ClipFlags != 0 {
- // The the vertex is required, calculate it.
- clipVertices[p].Y = vertexData[startIndex].Y +
- (clipVertices[p].X-
- vertexData[startIndex].X)/slope
-
- // If there is clipping in the vertical direction, the new vertex may be clipped.
- if clipSum&(POLYGON_CLIP_TOP|POLYGON_CLIP_BOTTOM) != 0 {
- if clipVertices[p].Y < clipBound[1] {
- clipVertices[p].ClipFlags = POLYGON_CLIP_TOP
- clipVertices[p].Line = int(clipBound[1])
- } else if clipVertices[p].Y > clipBound[3] {
- clipVertices[p].ClipFlags = POLYGON_CLIP_BOTTOM
- clipVertices[p].Line = int(clipBound[3] - 1)
- } else {
- clipVertices[p].ClipFlags = 0
- clipVertices[p].Line = int(clipVertices[p].Y+1) - 1
- }
- } else {
- clipVertices[p].ClipFlags = 0
- clipVertices[p].Line = int(clipVertices[p].Y+1) - 1
- }
- }
- }
-
- // Now there are three or four vertices, in the top-to-bottom order of start, clip0, clip1,
- // end. What kind of edges are required for connecting these can be determined from the
- // clip flags.
- // -if clip vertex has horizontal clip flags, it doesn't exist. No edge is generated.
- // -if start vertex or end vertex has horizontal clip flag, the edge to/from the clip vertex is vertical
- // -if the line of two vertices is the same, the edge is not generated, since the edge doesn't
- // cross any scanlines.
-
- // The alternative patterns are:
- // start - clip0 - clip1 - end
- // start - clip0 - end
- // start - clip1 - end
-
- var topClipIndex, bottomClipIndex int
- if (clipVertices[0].ClipFlags|clipVertices[1].ClipFlags)&
- (POLYGON_CLIP_LEFT|POLYGON_CLIP_RIGHT) == 0 {
- // Both sides are clipped, the order is start-clip0-clip1-end
- topClipIndex = 0
- bottomClipIndex = 1
-
- // Add the edge from clip0 to clip1
- // Check that the line is different for the vertices.
- if clipVertices[0].Line != clipVertices[1].Line {
- firstClipLine := clipVertices[0].Line + 1
-
- startx := vertexData[startIndex].X +
- (float64(firstClipLine)-vertexData[startIndex].Y)*slope
-
- edges[edgeCount].X = Fix(startx * FIXED_FLOAT_COEF)
- edges[edgeCount].Slope = Fix(slope * FIXED_FLOAT_COEF)
- edges[edgeCount].FirstLine = firstClipLine
- edges[edgeCount].LastLine = clipVertices[1].Line
- edges[edgeCount].Winding = winding
-
- if edges[edgeCount].LastLine-edges[edgeCount].FirstLine >= SLOPE_FIX_STEP {
- edges[edgeCount].SlopeFix = Fix(slope*SLOPE_FIX_STEP*FIXED_FLOAT_COEF) -
- edges[edgeCount].Slope<<SLOPE_FIX_SHIFT
- } else {
- edges[edgeCount].SlopeFix = 0
- }
-
- edgeCount++
- }
- } else {
- // Clip at either side, check which side. The clip flag is on for the vertex
- // that doesn't exist, i.e. has not been clipped to be inside the rect.
- if clipVertices[0].ClipFlags&(POLYGON_CLIP_LEFT|POLYGON_CLIP_RIGHT) != 0 {
- topClipIndex = 1
- bottomClipIndex = 1
- } else {
- topClipIndex = 0
- bottomClipIndex = 0
- }
- }
-
- // Generate the edges from start - clip top and clip bottom - end
- // Clip top and clip bottom may be the same vertex if there is only one
- // clipped vertex.
-
- // Check that the line is different for the vertices.
- if vertexData[startIndex].Line != clipVertices[topClipIndex].Line {
- edges[edgeCount].FirstLine = firstLine
- edges[edgeCount].LastLine = clipVertices[topClipIndex].Line
- edges[edgeCount].Winding = winding
-
- // If startIndex is clipped, the edge is a vertical one.
- if vertexData[startIndex].ClipFlags&(POLYGON_CLIP_LEFT|POLYGON_CLIP_RIGHT) != 0 {
- edges[edgeCount].X = Fix(clipVertices[topClipIndex].X * FIXED_FLOAT_COEF)
- edges[edgeCount].Slope = 0
- edges[edgeCount].SlopeFix = 0
- } else {
- startx := vertexData[startIndex].X +
- (float64(firstLine)-vertexData[startIndex].Y)*slope
-
- edges[edgeCount].X = Fix(startx * FIXED_FLOAT_COEF)
- edges[edgeCount].Slope = Fix(slope * FIXED_FLOAT_COEF)
-
- if edges[edgeCount].LastLine-edges[edgeCount].FirstLine >= SLOPE_FIX_STEP {
- edges[edgeCount].SlopeFix = Fix(slope*SLOPE_FIX_STEP*FIXED_FLOAT_COEF) -
- edges[edgeCount].Slope<<SLOPE_FIX_SHIFT
- } else {
- edges[edgeCount].SlopeFix = 0
- }
- }
-
- edgeCount++
- }
-
- // Check that the line is different for the vertices.
- if clipVertices[bottomClipIndex].Line != vertexData[endIndex].Line {
- firstClipLine := clipVertices[bottomClipIndex].Line + 1
-
- edges[edgeCount].FirstLine = firstClipLine
- edges[edgeCount].LastLine = lastLine
- edges[edgeCount].Winding = winding
-
- // If endIndex is clipped, the edge is a vertical one.
- if vertexData[endIndex].ClipFlags&(POLYGON_CLIP_LEFT|POLYGON_CLIP_RIGHT) != 0 {
- edges[edgeCount].X = Fix(clipVertices[bottomClipIndex].X * FIXED_FLOAT_COEF)
- edges[edgeCount].Slope = 0
- edges[edgeCount].SlopeFix = 0
- } else {
- startx := vertexData[startIndex].X +
- (float64(firstClipLine)-vertexData[startIndex].Y)*slope
-
- edges[edgeCount].X = Fix(startx * FIXED_FLOAT_COEF)
- edges[edgeCount].Slope = Fix(slope * FIXED_FLOAT_COEF)
-
- if edges[edgeCount].LastLine-edges[edgeCount].FirstLine >= SLOPE_FIX_STEP {
- edges[edgeCount].SlopeFix = Fix(slope*SLOPE_FIX_STEP*FIXED_FLOAT_COEF) -
- edges[edgeCount].Slope<<SLOPE_FIX_SHIFT
- } else {
- edges[edgeCount].SlopeFix = 0
- }
- }
-
- edgeCount++
- }
-
- }
- }
- }
-
- return edgeCount
-}