summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-04-17 18:08:39 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-04-17 18:08:39 +0000
commita5d69f54d9b9a7225010bcf8be7244e8a0e1898a (patch)
treef1ac61eef984db054835bbf56c3cdae7060d14ca
parent618da379b8b9505fc3a4112cb62c3458d1495b4c (diff)
downloadnuttx-a5d69f54d9b9a7225010bcf8be7244e8a0e1898a.tar.gz
nuttx-a5d69f54d9b9a7225010bcf8be7244e8a0e1898a.tar.bz2
nuttx-a5d69f54d9b9a7225010bcf8be7244e8a0e1898a.zip
Fill trapezoid for LCD
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2606 42af7a65-404d-4744-a932-0658087f49c3
-rwxr-xr-xnuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c199
1 files changed, 88 insertions, 111 deletions
diff --git a/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c b/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c
index 6bb9da77e..fd57b17f5 100755
--- a/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c
+++ b/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c
@@ -46,6 +46,7 @@
#include <nuttx/nxglib.h>
#include "nxglib_bitblit.h"
+#include "nxglib_fillrun.h"
/****************************************************************************
* Pre-Processor Definitions
@@ -91,161 +92,137 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX)(
FAR const struct nxgl_rect_s *bounds,
nxgl_mxpixel_t color)
{
- unsigned int stride;
- unsigned int width;
- FAR uint8_t *line;
- int nrows;
- b16_t x1;
- b16_t x2;
- nxgl_coord_t y1;
- nxgl_coord_t y2;
- b16_t dx1dy;
- b16_t dx2dy;
-
-#if NXGLIB_BITSPERPIXEL < 8
- FAR uint8_t *dest;
- uint8_t mpixel = NXGL_MULTIPIXEL(color);
- uint8_t mask;
- int lnlen;
-#endif
-
- /* Get the width of the framebuffer in bytes */
-
- stride = pinfo->stride;
+ unsigned int ncols;
+ unsigned int dy;
+ unsigned int topy;
+ unsigned int boty;
+ unsigned int row;
+ unsigned int botw;
+ b16_t topx1;
+ b16_t topx2;
+ b16_t botx1;
+ b16_t botx2;
+ b16_t dx1dy;
+ b16_t dx2dy;
+ int ix1;
+ int ix2;
+
+ /* Get the top run endpoints */
+
+ topx1 = trap->top.x1;
+ topx2 = trap->top.x2;
- /* Get the top run position and the number of rows to draw */
+ /* Calculate the number of rows to render */
- x1 = trap->top.x1;
- x2 = trap->top.x2;
+ topy = trap->top.y;
+ boty = trap->bot.y;
- /* Calculate the number of rows to render */
+ /* Get the bottom run endpoints */
- y1 = trap->top.y;
- y2 = trap->bot.y;
- nrows = y2 - y1 + 1;
+ botx1 = trap->bot.x1;
+ botx2 = trap->bot.x2;
/* Calculate the slope of the left and right side of the trapezoid */
- dx1dy = b16divi((trap->bot.x1 - x1), nrows - 1);
- dx2dy = b16divi((trap->bot.x2 - x2), nrows - 1);
+ dy = boty - topy;
+ dx1dy = b16divi((botx1 - topx1), dy);
+ dx2dy = b16divi((botx2 - topx2), dy);
/* Perform vertical clipping */
- if (y1 < bounds->pt1.y)
+ if (topy < bounds->pt1.y)
{
/* Calculate the x values for the new top run */
- int dy = bounds->pt1.y - y1;
- x1 += dy * dx1dy;
- x2 += dy * dx2dy;
+ dy = bounds->pt1.y - topy;
+ topx1 += dy * dx1dy;
+ topx2 += dy * dx2dy;
- /* Clip and re-calculate the number of rows to render */
+ /* Clip the top row to render */
- y1 = bounds->pt1.y;
- nrows = y2 - y1 + 1;
+ topy = bounds->pt1.y;
}
- if (y2 > bounds->pt2.y)
+ if (boty > bounds->pt2.y)
{
- /* Clip and re-calculate the number of rows to render */
+ /* Calculate the x values for the new bottom run */
- y2 = bounds->pt2.y;
- nrows = y2 - y1 + 1;
+ dy = boty - bounds->pt2.y;
+ botx1 -= dy * dx1dy;
+ botx2 -= dy * dx2dy;
+
+ /* Clip the bottom row to render */
+
+ boty = bounds->pt2.y;
}
- /* Get the address of the first byte on the first line */
+ /* Break out now if it was completely clipped */
- line = pinfo->fbmem + y1 * stride ;
+ if (topy > boty)
+ {
+ return;
+ }
- /* Then fill the trapezoid line-by-line */
+ /* Handle the special case where the sides cross (as in an hourglass) */
+
+ if (botx1 > botx2)
+ {
+ b16_t tmp;
+ ngl_swap(botx1, botx2, tmp);
+ }
- while (nrows--)
+ /* 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);
+ ncols = ix2 - ix1 + 1;
+
+ ix1 = ngl_clipl(b16toi(botx1), bounds->pt1.x);
+ ix2 = ngl_clipl(b16toi(botx2), bounds->pt2.x);
+ botw = ix2 - ix1 + 1;
+
+ if (ncols < botw)
{
- int ix1;
- int ix2;
+ ncols = botw;
+ }
+ NXGL_FUNCNAME(nxgl_fillrun,NXGLIB_SUFFIX)((NXGLIB_RUNTYPE*)pinfo->buffer, color, ncols);
+
+ /* Then fill the trapezoid line-by-line */
+
+ for (row = topy; row <= boty; row++)
+ {
/* Handle the special case where the sides cross (as in an hourglass) */
- if (x1 > x2)
+ if (topx1 > topx2)
{
b16_t tmp;
- ngl_swap(x1, x2, tmp);
+ ngl_swap(topx1, topx2, tmp);
ngl_swap(dx1dy, dx2dy, tmp);
}
- /* Convert the positions to integer and get the run width */
+ /* Convert the positions to integer and get the run width,
+ * clipping to fit within the bounding box.
+ */
- ix1 = b16toi(x1);
- ix2 = b16toi(x2);
- width = ix2 - ix1 + 1;
+ ix1 = ngl_clipl(b16toi(topx1), bounds->pt1.x);
+ ix2 = ngl_clipl(b16toi(topx2), bounds->pt2.x);
/* Handle some corner cases where we draw nothing. Otherwise, we will
* always draw at least one pixel.
*/
- if (x1 > x2 || ix2 < bounds->pt1.x || ix1 > bounds->pt2.x)
+ if (ix1 <= ix2)
{
- /* Get a clipped copies of the starting and ending X positions. This
- * clipped truncates "down" and gives the quantized pixel holding the
- * fractional X position
- */
-
- ix1 = ngl_clipl(ix1, bounds->pt1.x);
- ix2 = ngl_clipr(ix2, bounds->pt2.x);
-
-#if NXGLIB_BITSPERPIXEL < 8
- /* Handle masking of the fractional initial byte */
-
-#ifdef CONFIG_NX_PACKEDMSFIRST
- mask = (uint8_t)(0xff >> (8 - NXGL_REMAINDERX(ix1));
-#else
- mask = (uint8_t)(0xff << (8 - NXGL_REMAINDERX(ix1)));
-#endif
- dest = line;
- lnlen = width;
-
- if (lnlen > 1 && mask)
- {
- dest[0] = (dest[0] & ~mask) | (mpixel & mask);
- mask = 0xff;
- dest++;
- lnlen--;
- }
-
- /* Handle masking of the fractional final byte */
-
-#ifdef CONFIG_NX_PACKEDMSFIRST
- mask &= (uint8_t)(0xff << (8 - NXGL_REMAINDERX(ix2)));
-#else
- mask &= (uint8_t)(0xff >> (8 - NXGL_REMAINDERX(ix2)));
-#endif
- if (lnlen > 0 && mask)
- {
- dest[lnlen-1] = (dest[lnlen-1] & ~mask) | (mpixel & mask);
- lnlen--;
- }
-
- /* Handle all of the unmasked bytes in-between */
-
- if (lnlen > 0)
- {
- NXGL_MEMSET(dest, (NXGL_PIXEL_T)color, lnlen);
- }
+ /* Then draw the run from ix1 to ix2 at row */
-#else
- /* Then draw the run from (line + ix1) to (line + ix2) */
-
- NXGL_MEMSET(line + NXGL_SCALEX(ix1), (NXGL_PIXEL_T)color, width);
-#endif
+ ncols = ix2 - ix1 + 1;
+ (void)pinfo->putrun(row, ix1, pinfo->buffer, ncols);
}
- /* Move to the start of the next line */
-
- line += stride;
-
/* Add the dx/dy value to get the run positions on the next row */
- x1 += dx1dy;
- x2 += dx2dy;
+ topx1 += dx1dy;
+ topx2 += dx2dy;
}
}