nxterm_font.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. /****************************************************************************
  2. * graphics/nxterm/nxterm_font.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 <string.h>
  25. #include <assert.h>
  26. #include <errno.h>
  27. #include <debug.h>
  28. #include <nuttx/kmalloc.h>
  29. #include "nxterm.h"
  30. /****************************************************************************
  31. * Private Functions
  32. ****************************************************************************/
  33. /****************************************************************************
  34. * Name: nxterm_fontsize
  35. ****************************************************************************/
  36. static int nxterm_fontsize(FAR struct nxterm_state_s *priv, uint8_t ch,
  37. FAR struct nxgl_size_s *size)
  38. {
  39. FAR const struct nx_fontbitmap_s *fbm;
  40. NXHANDLE hfont;
  41. /* Get the handle of the font managed by the font cache */
  42. hfont = nxf_cache_getfonthandle(priv->fcache);
  43. DEBUGASSERT(hfont != NULL);
  44. /* Does the character code map to a font? */
  45. fbm = nxf_getbitmap(hfont, ch);
  46. if (fbm)
  47. {
  48. /* Yes.. return the font size */
  49. size->w = fbm->metric.width + fbm->metric.xoffset;
  50. size->h = fbm->metric.height + fbm->metric.yoffset;
  51. return OK;
  52. }
  53. return -ENOENT;
  54. }
  55. /****************************************************************************
  56. * Name: nxterm_fillspace
  57. ****************************************************************************/
  58. static void nxterm_fillspace(FAR struct nxterm_state_s *priv,
  59. FAR const struct nxgl_rect_s *rect,
  60. FAR const struct nxterm_bitmap_s *bm)
  61. {
  62. #if 0 /* Not necessary now, but perhaps in the future with VT100 support. */
  63. struct nxgl_rect_s bounds;
  64. struct nxgl_rect_s intersection;
  65. int ret;
  66. /* Construct a bounding box for the glyph */
  67. bounds.pt1.x = bm->pos.x;
  68. bounds.pt1.y = bm->pos.y;
  69. bounds.pt2.x = bm->pos.x + priv->spwidth - 1;
  70. bounds.pt2.y = bm->pos.y + priv->fheight - 1;
  71. # /* Should this also be clipped to a region in the window? */
  72. if (rect != NULL)
  73. {
  74. /* Get the intersection of the redraw region and the character bitmap */
  75. nxgl_rectintersect(&intersection, rect, &bounds);
  76. }
  77. else
  78. {
  79. /* The intersection is the whole glyph */
  80. nxgl_rectcopy(&intersection, &bounds);
  81. }
  82. /* Check for empty intersections */
  83. if (!nxgl_nullrect(&intersection))
  84. {
  85. /* Fill the bitmap region with the background color, erasing the
  86. * character from the display. NOTE: This region might actually
  87. * be obscured... NX will handle that case.
  88. */
  89. ret = priv->ops->fill(priv, &intersection, priv->wndo.wcolor);
  90. if (ret < 0)
  91. {
  92. gerr("ERROR: fill() method failed: %d\n", ret);
  93. }
  94. }
  95. #endif
  96. }
  97. /****************************************************************************
  98. * Public Functions
  99. ****************************************************************************/
  100. /****************************************************************************
  101. * Name: nxterm_addchar
  102. *
  103. * Description:
  104. * This is part of the nxterm_putc logic. It creates and positions a
  105. * the character and renders (or re-uses) a glyph for font.
  106. *
  107. ****************************************************************************/
  108. FAR const struct nxterm_bitmap_s *
  109. nxterm_addchar(FAR struct nxterm_state_s *priv, uint8_t ch)
  110. {
  111. FAR struct nxterm_bitmap_s *bm = NULL;
  112. FAR const struct nxfonts_glyph_s *glyph;
  113. /* Is there space for another character on the display? */
  114. if (priv->nchars < priv->maxchars)
  115. {
  116. /* Yes, setup the bitmap information */
  117. bm = &priv->bm[priv->nchars];
  118. bm->code = ch;
  119. bm->flags = 0;
  120. bm->pos.x = priv->fpos.x;
  121. bm->pos.y = priv->fpos.y;
  122. /* Find (or create) the matching glyph */
  123. glyph = nxf_cache_getglyph(priv->fcache, ch);
  124. if (!glyph)
  125. {
  126. /* No, there is no font for this code.
  127. * Just mark this as a space.
  128. */
  129. bm->flags |= BMFLAGS_NOGLYPH;
  130. /* Set up the next character position */
  131. priv->fpos.x += priv->spwidth;
  132. }
  133. else
  134. {
  135. /* Set up the next character position */
  136. priv->fpos.x += glyph->width;
  137. }
  138. /* Success.. increment nchars to retain this character */
  139. priv->nchars++;
  140. }
  141. return bm;
  142. }
  143. /****************************************************************************
  144. * Name: nxterm_hidechar
  145. *
  146. * Description:
  147. * Erase a character from the window.
  148. *
  149. ****************************************************************************/
  150. int nxterm_hidechar(FAR struct nxterm_state_s *priv,
  151. FAR const struct nxterm_bitmap_s *bm)
  152. {
  153. struct nxgl_rect_s bounds;
  154. struct nxgl_size_s fsize;
  155. int ret;
  156. /* Get the size of the font glyph. If nxterm_fontsize, then the
  157. * character will have been rendered as a space, and no display
  158. * modification is required (not an error).
  159. */
  160. ret = nxterm_fontsize(priv, bm->code, &fsize);
  161. if (ret < 0)
  162. {
  163. /* It was rendered as a space. */
  164. return OK;
  165. }
  166. /* Construct a bounding box for the glyph */
  167. bounds.pt1.x = bm->pos.x;
  168. bounds.pt1.y = bm->pos.y;
  169. bounds.pt2.x = bm->pos.x + fsize.w - 1;
  170. bounds.pt2.y = bm->pos.y + fsize.h - 1;
  171. /* Fill the bitmap region with the background color, erasing the
  172. * character from the display. NOTE: This region might actually
  173. * be obscured... NX will handle that case.
  174. */
  175. return priv->ops->fill(priv, &bounds, priv->wndo.wcolor);
  176. }
  177. /****************************************************************************
  178. * Name: nxterm_backspace
  179. *
  180. * Description:
  181. * Remove the last character from the window.
  182. *
  183. ****************************************************************************/
  184. int nxterm_backspace(FAR struct nxterm_state_s *priv)
  185. {
  186. FAR struct nxterm_bitmap_s *bm;
  187. int ndx;
  188. int ret = -ENOENT;
  189. /* Is there a character on the display? */
  190. if (priv->nchars > 0)
  191. {
  192. /* Yes.. Get the index to the last bitmap on the display */
  193. ndx = priv->nchars - 1;
  194. bm = &priv->bm[ndx];
  195. /* Erase the character from the display */
  196. ret = nxterm_hidechar(priv, bm);
  197. /* The current position to the location where the last character was */
  198. priv->fpos.x = bm->pos.x;
  199. priv->fpos.y = bm->pos.y;
  200. /* Decrement nchars to discard this character */
  201. priv->nchars = ndx;
  202. }
  203. return ret;
  204. }
  205. /****************************************************************************
  206. * Name: nxterm_home
  207. *
  208. * Description:
  209. * Set the next character position to the top-left corner of the display.
  210. *
  211. ****************************************************************************/
  212. void nxterm_home(FAR struct nxterm_state_s *priv)
  213. {
  214. /* The first character is one space from the left */
  215. priv->fpos.x = priv->spwidth;
  216. /* And CONFIG_NXTERM_LINESEPARATION lines from the top */
  217. priv->fpos.y = CONFIG_NXTERM_LINESEPARATION;
  218. }
  219. /****************************************************************************
  220. * Name: nxterm_newline
  221. *
  222. * Description:
  223. * Set the next character position to the beginning of the next line.
  224. *
  225. ****************************************************************************/
  226. void nxterm_newline(FAR struct nxterm_state_s *priv)
  227. {
  228. /* Carriage return: The first character is one space from the left */
  229. priv->fpos.x = priv->spwidth;
  230. /* Linefeed: Down the max font height + CONFIG_NXTERM_LINESEPARATION */
  231. priv->fpos.y += (priv->fheight + CONFIG_NXTERM_LINESEPARATION);
  232. }
  233. /****************************************************************************
  234. * Name: nxterm_fillchar
  235. *
  236. * Description:
  237. * This implements the character display. It is part of the nxterm_putc
  238. * operation but may also be used when redrawing an existing display.
  239. *
  240. ****************************************************************************/
  241. void nxterm_fillchar(FAR struct nxterm_state_s *priv,
  242. FAR const struct nxgl_rect_s *rect,
  243. FAR const struct nxterm_bitmap_s *bm)
  244. {
  245. FAR const struct nxfonts_glyph_s *glyph;
  246. struct nxgl_rect_s bounds;
  247. struct nxgl_rect_s intersection;
  248. struct nxgl_size_s fsize;
  249. int ret;
  250. /* Handle the special case of spaces which have no glyph bitmap */
  251. if (BM_ISSPACE(bm))
  252. {
  253. nxterm_fillspace(priv, rect, bm);
  254. return;
  255. }
  256. /* Get the size of the font glyph (which may not have been created yet) */
  257. ret = nxterm_fontsize(priv, bm->code, &fsize);
  258. if (ret < 0)
  259. {
  260. /* This would mean that there is no bitmap for the character code and
  261. * that the font would be rendered as a space. But this case should
  262. * never happen here because the BM_ISSPACE() should have already
  263. * found all such cases.
  264. */
  265. return;
  266. }
  267. /* Construct a bounding box for the glyph */
  268. bounds.pt1.x = bm->pos.x;
  269. bounds.pt1.y = bm->pos.y;
  270. bounds.pt2.x = bm->pos.x + fsize.w - 1;
  271. bounds.pt2.y = bm->pos.y + fsize.h - 1;
  272. /* Should this also be clipped to a region in the window? */
  273. if (rect != NULL)
  274. {
  275. /* Get the intersection of the redraw region and the character bitmap */
  276. nxgl_rectintersect(&intersection, rect, &bounds);
  277. }
  278. else
  279. {
  280. /* The intersection is the whole glyph */
  281. nxgl_rectcopy(&intersection, &bounds);
  282. }
  283. /* Check for empty intersections */
  284. if (!nxgl_nullrect(&intersection))
  285. {
  286. FAR const void *src;
  287. /* Find (or create) the glyph that goes with this font */
  288. glyph = nxf_cache_getglyph(priv->fcache, bm->code);
  289. if (!glyph)
  290. {
  291. /* Shouldn't happen */
  292. return;
  293. }
  294. /* Blit the font bitmap into the window */
  295. src = (FAR const void *)glyph->bitmap;
  296. ret = priv->ops->bitmap(priv, &intersection, &src,
  297. &bm->pos, (unsigned int)glyph->stride);
  298. DEBUGASSERT(ret >= 0);
  299. }
  300. }