diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-08-03 16:04:48 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-08-03 16:04:48 +0000 |
commit | 4a934b34d9f91e136d417551111a2c06b1f5c327 (patch) | |
tree | 63babfcb60345875f3ae20b676c94761eb47b30a /nuttx/graphics/nxglib | |
parent | 0597a9446b75ebcbd07d1503f5b70c50f8e36967 (diff) | |
download | nuttx-4a934b34d9f91e136d417551111a2c06b1f5c327.tar.gz nuttx-4a934b34d9f91e136d417551111a2c06b1f5c327.tar.bz2 nuttx-4a934b34d9f91e136d417551111a2c06b1f5c327.zip |
Fix numerous errors in trapezoid rendering and wide line drawing algorithms
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3840 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/graphics/nxglib')
-rw-r--r-- | nuttx/graphics/nxglib/fb/nxglib_filltrapezoid.c | 22 | ||||
-rw-r--r-- | nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c | 24 | ||||
-rw-r--r-- | nuttx/graphics/nxglib/nxglib_runoffset.c | 8 | ||||
-rw-r--r-- | nuttx/graphics/nxglib/nxglib_splitline.c | 89 |
4 files changed, 92 insertions, 51 deletions
diff --git a/nuttx/graphics/nxglib/fb/nxglib_filltrapezoid.c b/nuttx/graphics/nxglib/fb/nxglib_filltrapezoid.c index 2f16b58ed..4f0c2f072 100644 --- a/nuttx/graphics/nxglib/fb/nxglib_filltrapezoid.c +++ b/nuttx/graphics/nxglib/fb/nxglib_filltrapezoid.c @@ -115,8 +115,8 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX)( /* Get the top run position and the number of rows to draw */ - x1 = trap->top.x1; - x2 = trap->top.x2; + x1 = trap->top.x1; + x2 = trap->top.x2; /* Calculate the number of rows to render */ @@ -133,6 +133,15 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX)( if (y1 < bounds->pt1.y) { + /* Is the entire trapezoid "above" the clipping window? */ + + if (y2 < bounds->pt1.y) + { + /* Yes.. then do nothing */ + + return; + } + /* Calculate the x values for the new top run */ int dy = bounds->pt1.y - y1; @@ -147,6 +156,15 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX)( if (y2 > bounds->pt2.y) { + /* Is the entire trapezoid "below" the clipping window? */ + + if (y1 > bounds->pt2.y) + { + /* Yes.. then do nothing */ + + return; + } + /* Clip and re-calculate the number of rows to render */ y2 = bounds->pt2.y; diff --git a/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c b/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c index 0c8611088..970bbf829 100644 --- a/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c +++ b/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c @@ -124,14 +124,23 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX) /* Calculate the slope of the left and right side of the trapezoid */ - dy = boty - topy; - dx1dy = b16divi((botx1 - topx1), dy); - dx2dy = b16divi((botx2 - topx2), dy); + dy = boty - topy; + dx1dy = b16divi((botx1 - topx1), dy); + dx2dy = b16divi((botx2 - topx2), dy); /* Perform vertical clipping */ if (topy < bounds->pt1.y) { + /* Is the entire trapezoid "above" the clipping window? */ + + if (boty < bounds->pt1.y) + { + /* Yes.. then do nothing */ + + return; + } + /* Calculate the x values for the new top run */ dy = bounds->pt1.y - topy; @@ -145,6 +154,15 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX) if (boty > bounds->pt2.y) { + /* Is the entire trapezoid "below" the clipping window? */ + + if (topy > bounds->pt2.y) + { + /* Yes.. then do nothing */ + + return; + } + /* Calculate the x values for the new bottom run */ dy = boty - bounds->pt2.y; diff --git a/nuttx/graphics/nxglib/nxglib_runoffset.c b/nuttx/graphics/nxglib/nxglib_runoffset.c index 31d0dd163..f66d73674 100644 --- a/nuttx/graphics/nxglib/nxglib_runoffset.c +++ b/nuttx/graphics/nxglib/nxglib_runoffset.c @@ -70,7 +70,7 @@ * Name: nxgl_runoffset * * Description: - * Offset the run position by the specified dx, dy values. + * Offset the run position by the specified (integer) dx, dy values. * ****************************************************************************/ @@ -79,7 +79,7 @@ void nxgl_runoffset(FAR struct nxgl_run_s *dest, nxgl_coord_t dx, nxgl_coord_t dy) { b16_t b16dx = itob16(dx); - dest->x1 += b16dx; - dest->x2 += b16dx; - dest->y += dy; + dest->x1 = src->x1 + b16dx; + dest->x2 = src->x2 + b16dx; + dest->y = src->y + dy; } diff --git a/nuttx/graphics/nxglib/nxglib_splitline.c b/nuttx/graphics/nxglib/nxglib_splitline.c index 7be9cc115..eb2906e3f 100644 --- a/nuttx/graphics/nxglib/nxglib_splitline.c +++ b/nuttx/graphics/nxglib/nxglib_splitline.c @@ -112,15 +112,16 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, nxgl_coord_t linewidth) { struct nxgl_vector_s line; - struct nxgl_point_s pt; nxgl_coord_t iheight; nxgl_coord_t iwidth; + nxgl_coord_t iy; nxgl_coord_t triheight; - nxgl_coord_t adjwidth; - nxgl_coord_t xoffset; - nxgl_coord_t halfoffset; nxgl_coord_t halfheight; + b16_t adjwidth; + b16_t xoffset; + b16_t halfoffset; b16_t angle; + b16_t b16x; /* First, check the linewidth */ @@ -226,13 +227,17 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, angle = b16atan2(itob16(iheight), itob16(iwidth)); triheight = b16toi(linewidth * b16cos(angle)); - adjwidth = b16toi(b16divb16(itob16(linewidth), b16sin(angle))); - xoffset = (linewidth * linewidth + (adjwidth >> 1)) / adjwidth; + adjwidth = b16divb16(itob16(linewidth), b16sin(angle)); + xoffset = itob16(linewidth * linewidth); + xoffset = b16divb16(xoffset, adjwidth); halfoffset = (xoffset >> 1); halfheight = (triheight >> 1); - /* Return the top triangle (if there is one) */ + /* 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. + */ if (triheight > 0) { @@ -240,53 +245,53 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, { /* Line is going "south east" */ - pt.x = line.pt1.x - halfoffset; - pt.y = line.pt1.y + halfheight; + b16x = itob16(line.pt1.x) - halfoffset; + iy = line.pt1.y + halfheight; - traps[0].top.x1 = pt.x + xoffset; + traps[0].top.x1 = b16x + xoffset; traps[0].top.x2 = traps[0].top.x1; - traps[0].top.y = pt.y - triheight + 1; - traps[0].bot.x1 = pt.x; - traps[0].bot.x2 = pt.x + adjwidth - 1; - traps[0].bot.y = pt.y; - - pt.x = line.pt2.x + halfoffset; - pt.y = line.pt2.y - halfheight; - - traps[2].top.x1 = pt.x - adjwidth + 1; - traps[2].top.x2 = pt.x; - traps[2].top.y = pt.y; - traps[2].bot.x1 = pt.x - xoffset; + traps[0].top.y = iy - triheight + 1; + traps[0].bot.x1 = b16x; + traps[0].bot.x2 = b16x + adjwidth - b16ONE; + traps[0].bot.y = iy; + + b16x = itob16(line.pt2.x) + halfoffset; + iy = itob16(line.pt2.y) - halfheight; + + traps[2].top.x1 = b16x - adjwidth + b16ONE; + traps[2].top.x2 = b16x; + traps[2].top.y = iy; + traps[2].bot.x1 = b16x - xoffset; traps[2].bot.x2 = traps[2].bot.x1; - traps[2].bot.y = pt.y + triheight - 1; + traps[2].bot.y = iy + triheight - 1; } else { /* Line is going "south west" */ - pt.x = line.pt1.x + halfoffset; - pt.y = line.pt1.y + halfheight; + b16x = itob16(line.pt1.x) + halfoffset; + iy = itob16(line.pt1.y) + halfheight; - traps[0].top.x1 = pt.x - xoffset; + traps[0].top.x1 = b16x - xoffset; traps[0].top.x2 = traps[0].top.x1; - traps[0].top.y = pt.y - triheight + 1; - traps[0].bot.x1 = pt.x - adjwidth + 1; - traps[0].bot.x2 = pt.x; - traps[0].bot.y = pt.y; - - pt.x = line.pt2.x - halfoffset; - pt.y = line.pt2.y - halfheight; - - traps[2].top.x1 = pt.x; - traps[2].top.x2 = pt.x + adjwidth - 1; - traps[2].top.y = pt.y; - traps[2].bot.x1 = pt.x + xoffset; + traps[0].top.y = iy - triheight + 1; + traps[0].bot.x1 = b16x - adjwidth + b16ONE; + traps[0].bot.x2 = b16x; + traps[0].bot.y = iy; + + b16x = itob16(line.pt2.x) - halfoffset; + iy = itob16(line.pt2.y) - halfheight; + + traps[2].top.x1 = b16x; + traps[2].top.x2 = b16x + adjwidth - b16ONE; + traps[2].top.y = iy; + traps[2].bot.x1 = b16x + xoffset; traps[2].bot.x2 = traps[2].bot.x1; - traps[2].bot.y = pt.y + triheight - 1; + traps[2].bot.y = iy + triheight - 1; } /* The center parallelogram is the horizontal edge of each triangle. - * Note the minor inefficency: that horizontal edge is drawn twice. + * Note the minor inefficency: that horizontal edges are drawn twice. */ traps[1].top.x1 = traps[0].bot.x1; @@ -304,11 +309,11 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, * bottom. Just return the center parallelogram. */ - traps[1].top.x1 = line.pt1.x - halfoffset; + traps[1].top.x1 = itob16(line.pt1.x) - halfoffset; traps[1].top.x2 = traps[1].top.x1 + adjwidth - 1; traps[1].top.y = line.pt1.y; - traps[1].bot.x1 = line.pt2.x - halfoffset; + traps[1].bot.x1 = itob16(line.pt2.x) - halfoffset; traps[1].bot.x2 = traps[1].bot.x1 + adjwidth - 1; traps[1].bot.y = line.pt2.y; return 1; |