diff --git a/graphics/nxglib/fb/nxglib_moverectangle.c b/graphics/nxglib/fb/nxglib_moverectangle.c
index 228bc3bb9bb5cdffbd21d47406bb9950df875ace..4403c6f6d02a21b1a213ca0270d38bb6b8a6ab54 100644
--- a/graphics/nxglib/fb/nxglib_moverectangle.c
+++ b/graphics/nxglib/fb/nxglib_moverectangle.c
@@ -123,7 +123,9 @@ static inline void nxgl_lowresmemcpy(FAR uint8_t *dline, FAR const uint8_t *slin
  *
  * Descripton:
  *   Move a rectangular region from location to another in the
- *   framebuffer memory.
+ *   framebuffer memory.  The source is expressed as a rectangle; the
+ *   destination position is expressed as a point corresponding to the
+ *   translation of the upper, left-hand corner.
  *
  ****************************************************************************/
 
@@ -172,12 +174,16 @@ void NXGL_FUNCNAME(nxgl_moverectangle,NXGLIB_SUFFIX)
 # endif
 #endif
 
-  /* Case 1:  The starting position is above the display */
+  /* Case 1:  The destination position (offset) is above the displayed
+   * position (rect)
+   */
 
-  if (offset->y < 0)
+  if (offset->y < rect->pt1.y)
     {
-      dline = pinfo->fbmem + rect->pt1.y * stride + NXGL_SCALEX(rect->pt1.x);
-      sline = dline - offset->y * stride - NXGL_SCALEX(offset->x);
+      /* Copy the rectangle from top down. */
+
+      sline = pinfo->fbmem + rect->pt1.y * stride + NXGL_SCALEX(rect->pt1.x);
+      dline = dline - offset->y * stride - NXGL_SCALEX(offset->x);
 
       while (rows--)
         {
@@ -191,12 +197,16 @@ void NXGL_FUNCNAME(nxgl_moverectangle,NXGLIB_SUFFIX)
         }
     }
 
-  /* Case 2: It's not */
+  /* Case 2: The destination position (offset) is below the displayed
+   * position (rect)
+   */
 
   else
     {
-      dline = pinfo->fbmem + rect->pt2.y * stride + NXGL_SCALEX(rect->pt1.x);
-      sline = dline - offset->y * stride - NXGL_SCALEX(offset->x);
+      /* Copy the rectangle from the bottom up */
+
+      sline = pinfo->fbmem + rect->pt2.y * stride + NXGL_SCALEX(rect->pt1.x);
+      dline = dline - offset->y * stride - NXGL_SCALEX(offset->x);
 
       while (rows--)
         {
diff --git a/graphics/nxglib/lcd/nxglib_fillrectangle.c b/graphics/nxglib/lcd/nxglib_fillrectangle.c
index 33d62d720654d44f503491432bee45117579bd6c..9bb7606b6100c4eedb29ef9c0bbd2d8d9a23b36f 100755
--- a/graphics/nxglib/lcd/nxglib_fillrectangle.c
+++ b/graphics/nxglib/lcd/nxglib_fillrectangle.c
@@ -80,7 +80,7 @@
  * Name: nxgl_fillrectangle_*bpp
  *
  * Descripton:
- *   Fill a rectangle region in the framebuffer memory with a fixed color
+ *   Fill a rectangle region in the LCD memory with a fixed color
  *
  ****************************************************************************/
 
diff --git a/graphics/nxglib/lcd/nxglib_filltrapezoid.c b/graphics/nxglib/lcd/nxglib_filltrapezoid.c
index fd57b17f5c068c667824260ebe14146dba45d6b5..e940d5e1ad120a650c9d730ee8e2a6b1cadf9f8b 100755
--- a/graphics/nxglib/lcd/nxglib_filltrapezoid.c
+++ b/graphics/nxglib/lcd/nxglib_filltrapezoid.c
@@ -80,7 +80,7 @@
  * Name: nxglib_filltrapezoid_*bpp
  *
  * Descripton:
- *   Fill a trapezoidal region in the framebuffer memory with a fixed color.
+ *   Fill a trapezoidal region in the LCD memory with a fixed color.
  *   Clip the trapezoid to lie within a boundng box.  This is useful for
  *   drawing complex shapes that can be broken into a set of trapezoids.
  *
diff --git a/graphics/nxglib/lcd/nxglib_moverectangle.c b/graphics/nxglib/lcd/nxglib_moverectangle.c
index 035f052bcfab198b18ead6d69f50acd65fb6dd24..c6ceb845c8879626b06d2cd122cdf07742413083 100755
--- a/graphics/nxglib/lcd/nxglib_moverectangle.c
+++ b/graphics/nxglib/lcd/nxglib_moverectangle.c
@@ -66,54 +66,6 @@
  * Private Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: nxgl_lowresmemcpy
- ****************************************************************************/
-
-#if NXGLIB_BITSPERPIXEL < 8
-static inline void nxgl_lowresmemcpy(FAR uint8_t *dline, FAR const uint8_t *sline,
-                                     unsigned int width,
-                                     uint8_t leadmask, uint8_t tailmask)
-{
-  FAR const uint8_t *sptr;
-  FAR uint8_t *dptr;
-  uint8_t mask;
-  int lnlen;
-
-  /* Handle masking of the fractional initial byte */
-
-  mask  = leadmask;
-  sptr  = sline;
-  dptr  = dline;
-  lnlen = width;
-
-  if (lnlen > 1 && mask)
-     {
-       dptr[0] = (dptr[0] & ~mask) | (sptr[0] & mask);
-       mask = 0xff;
-       dptr++;
-       sptr++;
-       lnlen--;
-     }
-
-   /* Handle masking of the fractional final byte */
-
-   mask &= tailmask;
-   if (lnlen > 0 && mask)
-     {
-       dptr[lnlen-1] = (dptr[lnlen-1] & ~mask) | (sptr[lnlen-1] & mask);
-       lnlen--;
-     }
-
-   /* Handle all of the unmasked bytes in-between */
-
-   if (lnlen > 0)
-     {
-       NXGL_MEMCPY(dptr, sptr, lnlen);
-     }
-}
-#endif
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -123,7 +75,9 @@ static inline void nxgl_lowresmemcpy(FAR uint8_t *dline, FAR const uint8_t *slin
  *
  * Descripton:
  *   Move a rectangular region from location to another in the
- *   framebuffer memory.
+ *   LCD memory.  The source is expressed as a rectangle; the
+ *   destination position is expressed as a point corresponding to the
+ *   translation of the upper, left-hand corner.
  *
  ****************************************************************************/
 
@@ -131,82 +85,47 @@ void NXGL_FUNCNAME(nxgl_moverectangle,NXGLIB_SUFFIX)
 (FAR struct lcd_planeinfo_s *pinfo, FAR const struct nxgl_rect_s *rect,
  FAR struct nxgl_point_s *offset)
 {
-  FAR const uint8_t *sline;
-  FAR uint8_t *dline;
-  unsigned int width;
-  unsigned int stride;
-  unsigned int rows;
-
-#if NXGLIB_BITSPERPIXEL < 8
-  uint8_t leadmask;
-  uint8_t tailmask;
-#endif
+  unsigned int ncols;
+  unsigned int srcrow;
+  unsigned int destrow;
 
-  /* Get the width of the framebuffer in bytes */
+  /* Get the width of the rectange to move in pixels. */
 
-  stride = pinfo->stride;
+  ncols = rect->pt2.x - rect->pt1.x + 1;
 
-  /* Get the dimensions of the rectange to fill: width in pixels, height
-   * in rows
+  /* Case 1:  The destination position (offset) is above the displayed
+   * position (rect)
    */
 
-  width = rect->pt2.x - rect->pt1.x + 1;
-  rows  = rect->pt2.y - rect->pt1.y + 1;
-
-#if NXGLIB_BITSPERPIXEL < 8
-# ifdef CONFIG_NX_PACKEDMSFIRST
-
-  /* Get the mask for pixels that are ordered so that they pack from the
-   * MS byte down.
-   */
-
-  leadmask = (uint8_t)(0xff >> (8 - NXGL_REMAINDERX(rect->pt1.x)));
-  tailmask = (uint8_t)(0xff << (8 - NXGL_REMAINDERX(rect->pt2.x-1)));
-# else
-  /* Get the mask for pixels that are ordered so that they pack from the
-   * LS byte up.
-   */
-
-  leadmask = (uint8_t)(0xff << (8 - NXGL_REMAINDERX(rect->pt1.x)));
-  tailmask = (uint8_t)(0xff >> (8 - NXGL_REMAINDERX(rect->pt1.x-1)));
-# endif
-#endif
-
-  /* Case 1:  The starting position is above the display */
-
-  if (offset->y < 0)
+  if (offset->y < rect->pt1.y)
     {
-      dline = pinfo->fbmem + rect->pt1.y * stride + NXGL_SCALEX(rect->pt1.x);
-      sline = dline - offset->y * stride - NXGL_SCALEX(offset->x);
+      /* Copy the rectangle from top down */
 
-      while (rows--)
+      for (srcrow = rect->pt1.y, destrow = offset->y;
+           srcrow <= rect->pt2.y;
+           srcrow++, destrow++)
         {
-#if NXGLIB_BITSPERPIXEL < 8
-          nxgl_lowresmemcpy(dline, sline, width, leadmask, tailmask);
-#else
-          NXGL_MEMCPY(dline, sline, width);
-#endif
-          dline += stride;
-          sline += stride;
+          (void)pinfo->getrun(srcrow, rect->pt1.x, pinfo->buffer, ncols);
+          (void)pinfo->putrun(destrow, offset->x, pinfo->buffer, ncols);
         }
     }
 
-  /* Case 2: It's not */
+  /* Case 2: The destination position (offset) is below the displayed
+   * position (rect)
+   */
 
   else
     {
-      dline = pinfo->fbmem + rect->pt2.y * stride + NXGL_SCALEX(rect->pt1.x);
-      sline = dline - offset->y * stride - NXGL_SCALEX(offset->x);
+      unsigned int dy = rect->pt2.y - rect->pt1.y;
+
+      /* Copy the rectangle from the bottom up */
 
-      while (rows--)
+      for (srcrow = rect->pt2.y, destrow = offset->y + dy;
+           srcrow >= rect->pt1.y;
+           srcrow--, destrow--)
         {
-          dline -= stride;
-          sline -= stride;
-#if NXGLIB_BITSPERPIXEL < 8
-          nxgl_lowresmemcpy(dline, sline, width, leadmask, tailmask);
-#else
-          NXGL_MEMCPY(dline, sline, width);
-#endif
+          (void)pinfo->getrun(srcrow, rect->pt1.x, pinfo->buffer, ncols);
+          (void)pinfo->putrun(destrow, offset->x, pinfo->buffer, ncols);
         }
     }
 }
diff --git a/include/nuttx/nxglib.h b/include/nuttx/nxglib.h
index cf9f40133a377399168305c05c188ec7bc0c071e..ffd3d0ca7ebf24f9deb97af403d153c00a8776da 100644
--- a/include/nuttx/nxglib.h
+++ b/include/nuttx/nxglib.h
@@ -284,7 +284,9 @@ EXTERN void nxgl_filltrapezoid_32bpp(FAR NX_PLANEINFOTYPE *pinfo,
  *
  * Descripton:
  *   Move a rectangular region from location to another in the
- *   framebuffer memory.
+ *   framebuffer/LCD memory.  The source is expressed as a rectangle; the
+ *   destination position is expressed as a point corresponding to the
+ *   translation of the upper, left-hand corner.
  *
  ****************************************************************************/