nxterm_scroll.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /****************************************************************************
  2. * graphics/nxterm/nxterm_scroll.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /****************************************************************************
  21. * Included Files
  22. ****************************************************************************/
  23. #include <nuttx/config.h>
  24. #include <stdint.h>
  25. #include <stdbool.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <errno.h>
  30. #include <debug.h>
  31. #include <nuttx/nx/nx.h>
  32. #include <nuttx/nx/nxfonts.h>
  33. #include "nxterm.h"
  34. /****************************************************************************
  35. * Private Functions
  36. ****************************************************************************/
  37. /****************************************************************************
  38. * Name: nxterm_movedisplay
  39. *
  40. * Description:
  41. * This function implements the data movement for the scroll operation. If
  42. * we can read the displays framebuffer memory, then the job is pretty
  43. * easy. However, many displays (such as SPI-based LCDs) are often read-
  44. * only.
  45. *
  46. ****************************************************************************/
  47. #ifdef CONFIG_NX_WRITEONLY
  48. static inline void nxterm_movedisplay(FAR struct nxterm_state_s *priv,
  49. int bottom, int scrollheight)
  50. {
  51. FAR struct nxterm_bitmap_s *bm;
  52. struct nxgl_rect_s rect;
  53. nxgl_coord_t row;
  54. int ret;
  55. int i;
  56. /* Move each row, one at a time. They could all be moved at once (by
  57. * calling nxterm_redraw), but the since the region is cleared, then
  58. * re-written, the effect would not be good. Below the region is also
  59. * cleared and re-written, however, in much smaller chunks.
  60. */
  61. rect.pt1.x = 0;
  62. rect.pt2.x = priv->wndo.wsize.w - 1;
  63. for (row = CONFIG_NXTERM_LINESEPARATION; row < bottom; row += scrollheight)
  64. {
  65. /* Create a bounding box the size of one row of characters */
  66. rect.pt1.y = row;
  67. rect.pt2.y = row + scrollheight - 1;
  68. /* Clear the region */
  69. ret = priv->ops->fill(priv, &rect, priv->wndo.wcolor);
  70. if (ret < 0)
  71. {
  72. gerr("ERROR: Fill failed: %d\n", get_errno());
  73. }
  74. /* Fill each character that might lie within in the bounding box */
  75. for (i = 0; i < priv->nchars; i++)
  76. {
  77. bm = &priv->bm[i];
  78. if (bm->pos.y <= rect.pt2.y &&
  79. bm->pos.y + priv->fheight >= rect.pt1.y)
  80. {
  81. nxterm_fillchar(priv, &rect, bm);
  82. }
  83. }
  84. }
  85. /* Finally, clear the vacated part of the display */
  86. rect.pt1.y = bottom;
  87. rect.pt2.y = priv->wndo.wsize.h - 1;
  88. ret = priv->ops->fill(priv, &rect, priv->wndo.wcolor);
  89. if (ret < 0)
  90. {
  91. gerr("ERROR: Fill failed: %d\n", get_errno());
  92. }
  93. }
  94. #else
  95. static inline void nxterm_movedisplay(FAR struct nxterm_state_s *priv,
  96. int bottom, int scrollheight)
  97. {
  98. struct nxgl_rect_s rect;
  99. struct nxgl_point_s offset;
  100. int ret;
  101. /* Add the line separation value to the scroll height */
  102. scrollheight += CONFIG_NXTERM_LINESEPARATION;
  103. /* Move the display in the range of 0-height up one scrollheight. The
  104. * line at the bottom will be reset to the background color automatically.
  105. *
  106. * The source rectangle to be moved.
  107. */
  108. rect.pt1.x = 0;
  109. rect.pt1.y = scrollheight;
  110. rect.pt2.x = priv->wndo.wsize.w - 1;
  111. rect.pt2.y = priv->wndo.wsize.h - 1;
  112. /* The offset that determines how far to move the source rectangle */
  113. offset.x = 0;
  114. offset.y = -scrollheight;
  115. /* Move the source rectangle upward by the scrollheight */
  116. ret = priv->ops->move(priv, &rect, &offset);
  117. if (ret < 0)
  118. {
  119. gerr("ERROR: Move failed: %d\n", get_errno());
  120. }
  121. /* Finally, clear the vacated bottom part of the display */
  122. rect.pt1.y = priv->wndo.wsize.h - scrollheight;
  123. ret = priv->ops->fill(priv, &rect, priv->wndo.wcolor);
  124. if (ret < 0)
  125. {
  126. gerr("ERROR: Fill failed: %d\n", get_errno());
  127. }
  128. }
  129. #endif
  130. /****************************************************************************
  131. * Public Functions
  132. ****************************************************************************/
  133. /****************************************************************************
  134. * Name: nxterm_scroll
  135. ****************************************************************************/
  136. void nxterm_scroll(FAR struct nxterm_state_s *priv, int scrollheight)
  137. {
  138. int i;
  139. int j;
  140. /* Adjust the vertical position of each character */
  141. for (i = 0; i < priv->nchars; )
  142. {
  143. FAR struct nxterm_bitmap_s *bm = &priv->bm[i];
  144. /* Has any part of this character scrolled off the screen? */
  145. if (bm->pos.y < scrollheight + CONFIG_NXTERM_LINESEPARATION)
  146. {
  147. /* Yes... Delete the character by moving all of the data */
  148. for (j = i; j < priv->nchars - 1; j++)
  149. {
  150. memcpy(&priv->bm[j], &priv->bm[j + 1],
  151. sizeof(struct nxterm_bitmap_s));
  152. }
  153. /* Decrement the number of cached characters ('i' is not
  154. * incremented in this case because it already points to the next
  155. * character)
  156. */
  157. priv->nchars--;
  158. }
  159. /* No.. just decrement its vertical position (moving it "up" the
  160. * display by one line).
  161. */
  162. else
  163. {
  164. bm->pos.y -= scrollheight;
  165. /* We are keeping this one so increment to the next character */
  166. i++;
  167. }
  168. }
  169. /* And move the next display position up by one line as well */
  170. priv->fpos.y -= scrollheight;
  171. /* Move the display in the range of 0-height up one scrollheight. */
  172. nxterm_movedisplay(priv, priv->fpos.y, scrollheight);
  173. }