summaryrefslogtreecommitdiff
path: root/nuttx/graphics/nxglib
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-08-03 21:49:31 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-08-03 21:49:31 +0000
commit2dbf43396ef13cf1f6870631edbe399b12d5d07a (patch)
tree5adc239ba2ea9d6b8cbaa46aedc732c3e95a51a0 /nuttx/graphics/nxglib
parent4a934b34d9f91e136d417551111a2c06b1f5c327 (diff)
downloadnuttx-2dbf43396ef13cf1f6870631edbe399b12d5d07a.tar.gz
nuttx-2dbf43396ef13cf1f6870631edbe399b12d5d07a.tar.bz2
nuttx-2dbf43396ef13cf1f6870631edbe399b12d5d07a.zip
Fix numerous errors in trapezoid rendering and wide line drawing algorithms
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3841 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/graphics/nxglib')
-rw-r--r--nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c24
-rw-r--r--nuttx/graphics/nxglib/nxglib_splitline.c42
2 files changed, 43 insertions, 23 deletions
diff --git a/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c b/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c
index 970bbf829..faeebbec7 100644
--- a/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c
+++ b/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c
@@ -191,12 +191,16 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX)
/* Fill the run buffer for the maximum run that we will need */
- ix1 = ngl_clipl(b16toi(topx1), bounds->pt1.x);
- ix2 = ngl_clipl(b16toi(topx2), bounds->pt2.x);
+ ix1 = b16toi(topx1);
+ ix1 = ngl_clipl(ix1, bounds->pt1.x);
+ ix2 = b16toi(topx2);
+ ix2 = ngl_clipr(ix2, bounds->pt2.x);
ncols = ix2 - ix1 + 1;
- ix1 = ngl_clipl(b16toi(botx1), bounds->pt1.x);
- ix2 = ngl_clipl(b16toi(botx2), bounds->pt2.x);
+ ix1 = b16toi(botx1);
+ ix1 = ngl_clipl(ix1, bounds->pt1.x);
+ ix2 = b16toi(botx2);
+ ix2 = ngl_clipr(ix2, bounds->pt2.x);
botw = ix2 - ix1 + 1;
if (ncols < botw)
@@ -206,7 +210,7 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX)
NXGL_FUNCNAME(nxgl_fillrun,NXGLIB_SUFFIX)((NXGLIB_RUNTYPE*)pinfo->buffer, color, ncols);
- /* Then fill the trapezoid line-by-line */
+ /* Then fill the trapezoid row-by-row */
for (row = topy; row <= boty; row++)
{
@@ -219,12 +223,14 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX)
ngl_swap(dx1dy, dx2dy, tmp);
}
- /* Convert the positions to integer and get the run width,
- * clipping to fit within the bounding box.
+ /* Convert the positions to integer and get the run width, clipping to
+ * fit within the bounding box.
*/
- ix1 = ngl_clipl(b16toi(topx1), bounds->pt1.x);
- ix2 = ngl_clipl(b16toi(topx2), bounds->pt2.x);
+ ix1 = b16toi(topx1);
+ ix1 = ngl_clipl(ix1, bounds->pt1.x);
+ ix2 = b16toi(topx2);
+ ix2 = ngl_clipr(ix2, bounds->pt2.x);
/* Handle some corner cases where we draw nothing. Otherwise, we will
* always draw at least one pixel.
diff --git a/nuttx/graphics/nxglib/nxglib_splitline.c b/nuttx/graphics/nxglib/nxglib_splitline.c
index eb2906e3f..31d6949ad 100644
--- a/nuttx/graphics/nxglib/nxglib_splitline.c
+++ b/nuttx/graphics/nxglib/nxglib_splitline.c
@@ -121,6 +121,7 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector,
b16_t xoffset;
b16_t halfoffset;
b16_t angle;
+ b16_t sinangle;
b16_t b16x;
/* First, check the linewidth */
@@ -193,12 +194,12 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector,
{
/* A line of width 1 is basically a single parallelogram of width 1 */
- traps[1].top.x1 = line.pt1.x;
- traps[1].top.x2 = line.pt1.x;
+ traps[1].top.x1 = itob16(line.pt1.x);
+ traps[1].top.x2 = traps[1].top.x1;
traps[1].top.y = line.pt1.y;
- traps[1].bot.x1 = line.pt2.x;
- traps[1].bot.x2 = line.pt2.x;
+ traps[1].bot.x1 = itob16(line.pt2.x);
+ traps[1].bot.x2 = traps[1].bot.x1;
traps[1].bot.y = line.pt2.y;
return 1;
}
@@ -219,21 +220,34 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector,
iwidth = line.pt1.x - line.pt2.x + 1;
}
- /*
- * Triangle height: linewidth * cosA
+ /* Triangle height: linewidth * cosA
* Adjusted width: triheight / sinA
* X offset : linewidth * linewidth / adjusted line width
*/
angle = b16atan2(itob16(iheight), itob16(iwidth));
triheight = b16toi(linewidth * b16cos(angle));
- adjwidth = b16divb16(itob16(linewidth), b16sin(angle));
- xoffset = itob16(linewidth * linewidth);
- xoffset = b16divb16(xoffset, adjwidth);
-
- halfoffset = (xoffset >> 1);
halfheight = (triheight >> 1);
+ /* If the sine of the angle is tiny (i.e., the line is nearly horizontal),
+ * then we cannot compute the adjusted width. In this case, just use
+ * the width of the line (not very good estimate -- need to revisit).
+ */
+
+ sinangle = b16sin(angle);
+ if (sinangle == 0)
+ {
+ adjwidth = itob16(iwidth);
+ xoffset = adjwidth;
+ }
+ else
+ {
+ adjwidth = b16divb16(itob16(linewidth), sinangle);
+ xoffset = itob16(linewidth * linewidth);
+ xoffset = b16divb16(xoffset, adjwidth);
+ }
+ halfoffset = (xoffset >> 1);
+
/* Return the top triangle (if there is one). NOTE that the horizontal
* (z) positions are represented with 16 bits of fraction. The vertical
* (y) positions, on the other hand, are integer.
@@ -256,7 +270,7 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector,
traps[0].bot.y = iy;
b16x = itob16(line.pt2.x) + halfoffset;
- iy = itob16(line.pt2.y) - halfheight;
+ iy = line.pt2.y - halfheight;
traps[2].top.x1 = b16x - adjwidth + b16ONE;
traps[2].top.x2 = b16x;
@@ -270,7 +284,7 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector,
/* Line is going "south west" */
b16x = itob16(line.pt1.x) + halfoffset;
- iy = itob16(line.pt1.y) + halfheight;
+ iy = line.pt1.y + halfheight;
traps[0].top.x1 = b16x - xoffset;
traps[0].top.x2 = traps[0].top.x1;
@@ -280,7 +294,7 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector,
traps[0].bot.y = iy;
b16x = itob16(line.pt2.x) - halfoffset;
- iy = itob16(line.pt2.y) - halfheight;
+ iy = line.pt2.y - halfheight;
traps[2].top.x1 = b16x;
traps[2].top.x2 = b16x + adjwidth - b16ONE;