nxterm_scroll.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /****************************************************************************
  2. * nuttx/graphics/nxterm/nxterm_scroll.c
  3. *
  4. * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <stdint.h>
  40. #include <stdbool.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <semaphore.h>
  45. #include <errno.h>
  46. #include <debug.h>
  47. #include <nuttx/nx/nx.h>
  48. #include <nuttx/nx/nxfonts.h>
  49. #include "nxterm.h"
  50. /****************************************************************************
  51. * Private Functions
  52. ****************************************************************************/
  53. /****************************************************************************
  54. * Name: nxterm_movedisplay
  55. *
  56. * Description:
  57. * This function implements the data movement for the scroll operation. If
  58. * we can read the displays framebuffer memory, then the job is pretty
  59. * easy. However, many displays (such as SPI-based LCDs) are often read-
  60. * only.
  61. *
  62. ****************************************************************************/
  63. #ifdef CONFIG_NX_WRITEONLY
  64. static inline void nxterm_movedisplay(FAR struct nxterm_state_s *priv,
  65. int bottom, int scrollheight)
  66. {
  67. FAR struct nxterm_bitmap_s *bm;
  68. struct nxgl_rect_s rect;
  69. nxgl_coord_t row;
  70. int ret;
  71. int i;
  72. /* Move each row, one at a time. They could all be moved at once (by calling
  73. * nxterm_redraw), but the since the region is cleared, then re-written, the
  74. * effect would not be good. Below the region is also cleared and re-written,
  75. * however, in much smaller chunks.
  76. */
  77. rect.pt1.x = 0;
  78. rect.pt2.x = priv->wndo.wsize.w - 1;
  79. for (row = CONFIG_NXTERM_LINESEPARATION; row < bottom; row += scrollheight)
  80. {
  81. /* Create a bounding box the size of one row of characters */
  82. rect.pt1.y = row;
  83. rect.pt2.y = row + scrollheight - 1;
  84. /* Clear the region */
  85. ret = priv->ops->fill(priv, &rect, priv->wndo.wcolor);
  86. if (ret < 0)
  87. {
  88. gerr("ERROR: Fill failed: %d\n", errno);
  89. }
  90. /* Fill each character that might lie within in the bounding box */
  91. for (i = 0; i < priv->nchars; i++)
  92. {
  93. bm = &priv->bm[i];
  94. if (bm->pos.y <= rect.pt2.y &&
  95. bm->pos.y + priv->fheight >= rect.pt1.y)
  96. {
  97. nxterm_fillchar(priv, &rect, bm);
  98. }
  99. }
  100. }
  101. /* Finally, clear the vacated part of the display */
  102. rect.pt1.y = bottom;
  103. rect.pt2.y = priv->wndo.wsize.h - 1;
  104. ret = priv->ops->fill(priv, &rect, priv->wndo.wcolor);
  105. if (ret < 0)
  106. {
  107. gerr("ERROR: Fill failed: %d\n", errno);
  108. }
  109. }
  110. #else
  111. static inline void nxterm_movedisplay(FAR struct nxterm_state_s *priv,
  112. int bottom, int scrollheight)
  113. {
  114. struct nxgl_rect_s rect;
  115. struct nxgl_point_s offset;
  116. int ret;
  117. /* Add the line separation value to the scroll height */
  118. scrollheight += CONFIG_NXTERM_LINESEPARATION;
  119. /* Move the display in the range of 0-height up one scrollheight. The
  120. * line at the bottom will be reset to the background color automatically.
  121. *
  122. * The source rectangle to be moved.
  123. */
  124. rect.pt1.x = 0;
  125. rect.pt1.y = scrollheight;
  126. rect.pt2.x = priv->wndo.wsize.w - 1;
  127. rect.pt2.y = priv->wndo.wsize.h - 1;
  128. /* The offset that determines how far to move the source rectangle */
  129. offset.x = 0;
  130. offset.y = -scrollheight;
  131. /* Move the source rectangle upward by the scrollheight */
  132. ret = priv->ops->move(priv, &rect, &offset);
  133. if (ret < 0)
  134. {
  135. gerr("ERROR: Move failed: %d\n", errno);
  136. }
  137. /* Finally, clear the vacated bottom part of the display */
  138. rect.pt1.y = priv->wndo.wsize.h - scrollheight;
  139. ret = priv->ops->fill(priv, &rect, priv->wndo.wcolor);
  140. if (ret < 0)
  141. {
  142. gerr("ERROR: Fill failed: %d\n", errno);
  143. }
  144. }
  145. #endif
  146. /****************************************************************************
  147. * Public Functions
  148. ****************************************************************************/
  149. /****************************************************************************
  150. * Name: nxterm_scroll
  151. ****************************************************************************/
  152. void nxterm_scroll(FAR struct nxterm_state_s *priv, int scrollheight)
  153. {
  154. int i;
  155. int j;
  156. /* Adjust the vertical position of each character */
  157. for (i = 0; i < priv->nchars; )
  158. {
  159. FAR struct nxterm_bitmap_s *bm = &priv->bm[i];
  160. /* Has any part of this character scrolled off the screen? */
  161. if (bm->pos.y < scrollheight + CONFIG_NXTERM_LINESEPARATION)
  162. {
  163. /* Yes... Delete the character by moving all of the data */
  164. for (j = i; j < priv->nchars - 1; j++)
  165. {
  166. memcpy(&priv->bm[j], &priv->bm[j + 1],
  167. sizeof(struct nxterm_bitmap_s));
  168. }
  169. /* Decrement the number of cached characters ('i' is not incremented
  170. * in this case because it already points to the next character)
  171. */
  172. priv->nchars--;
  173. }
  174. /* No.. just decrement its vertical position (moving it "up" the
  175. * display by one line).
  176. */
  177. else
  178. {
  179. bm->pos.y -= scrollheight;
  180. /* We are keeping this one so increment to the next character */
  181. i++;
  182. }
  183. }
  184. /* And move the next display position up by one line as well */
  185. priv->fpos.y -= scrollheight;
  186. /* Move the display in the range of 0-height up one scrollheight. */
  187. nxterm_movedisplay(priv, priv->fpos.y, scrollheight);
  188. }