You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
5.4 KiB

3 years ago
  1. // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "stdint.h"
  15. #include "stdarg.h"
  16. #include "string.h"
  17. #include "stdio.h"
  18. #include "stdlib.h"
  19. #include "fb_gfx.h"
  20. typedef struct
  21. { // Data stored PER GLYPH
  22. uint16_t bitmapOffset; // Pointer into GFXfont->bitmap
  23. uint8_t width, height; // Bitmap dimensions in pixels
  24. uint8_t xAdvance; // Distance to advance cursor (x axis)
  25. int8_t xOffset, yOffset; // Dist from cursor pos to UL corner
  26. } GFXglyph;
  27. typedef struct
  28. { // Data stored for FONT AS A WHOLE:
  29. uint8_t *bitmap; // Glyph bitmaps, concatenated
  30. GFXglyph *glyph; // Glyph array
  31. uint8_t first, last; // ASCII extents
  32. uint8_t yAdvance; // Newline distance (y axis)
  33. uint8_t yOffset; // Y offset of the font zero line (y axis)
  34. } GFXfont;
  35. #include "FreeMonoBold12pt7b.h" //14x24
  36. #define gfxFont ((GFXfont *)(&FreeMonoBold12pt7b))
  37. void fb_gfx_fillRect(camera_fb_t *fb, int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color)
  38. {
  39. int bytes_per_pixel = 0;
  40. switch (fb->format)
  41. {
  42. case PIXFORMAT_GRAYSCALE:
  43. bytes_per_pixel = 1;
  44. break;
  45. case PIXFORMAT_RGB565:
  46. bytes_per_pixel = 2;
  47. break;
  48. case PIXFORMAT_RGB888:
  49. bytes_per_pixel = 3;
  50. default:
  51. break;
  52. }
  53. int32_t line_step = (fb->width - w) * 3;
  54. uint8_t *data = fb->buf + ((x + (y * fb->width)) * bytes_per_pixel);
  55. uint8_t c0 = color >> 16;
  56. uint8_t c1 = color >> 8;
  57. uint8_t c2 = color;
  58. for (int i = 0; i < h; i++)
  59. {
  60. for (int j = 0; j < w; j++)
  61. {
  62. switch (bytes_per_pixel)
  63. {
  64. case 1:
  65. data[0] = c2;
  66. data++;
  67. break;
  68. case 2:
  69. data[0] = c1;
  70. data[1] = c2;
  71. data += 2;
  72. break;
  73. case 3:
  74. data[0] = c0;
  75. data[1] = c1;
  76. data[2] = c2;
  77. data += 3;
  78. default:
  79. break;
  80. }
  81. }
  82. data += line_step;
  83. }
  84. }
  85. void fb_gfx_drawFastHLine(camera_fb_t *fb, int32_t x, int32_t y, int32_t w, uint32_t color)
  86. {
  87. fb_gfx_fillRect(fb, x, y, w, 1, color);
  88. }
  89. void fb_gfx_drawFastVLine(camera_fb_t *fb, int32_t x, int32_t y, int32_t h, uint32_t color)
  90. {
  91. fb_gfx_fillRect(fb, x, y, 1, h, color);
  92. }
  93. uint8_t fb_gfx_putc(camera_fb_t *fb, int32_t x, int32_t y, uint32_t color, unsigned char c)
  94. {
  95. uint16_t line_width;
  96. uint8_t xa = 0, bit = 0, bits = 0, xx, yy;
  97. uint8_t *bitmap;
  98. GFXglyph *glyph;
  99. if ((c < 32) || (c < gfxFont->first) || (c > gfxFont->last))
  100. {
  101. return xa;
  102. }
  103. c -= gfxFont->first;
  104. glyph = &(gfxFont->glyph[c]);
  105. bitmap = gfxFont->bitmap + glyph->bitmapOffset;
  106. xa = glyph->xAdvance;
  107. x += glyph->xOffset;
  108. y += glyph->yOffset;
  109. y += gfxFont->yOffset;
  110. line_width = 0;
  111. for (yy = 0; yy < glyph->height; yy++)
  112. {
  113. for (xx = 0; xx < glyph->width; xx++)
  114. {
  115. if (bit == 0)
  116. {
  117. bits = *bitmap++;
  118. bit = 0x80;
  119. }
  120. if (bits & bit)
  121. {
  122. line_width++;
  123. }
  124. else if (line_width)
  125. {
  126. fb_gfx_drawFastHLine(fb, x + xx - line_width, y + yy, line_width, color);
  127. line_width = 0;
  128. }
  129. bit >>= 1;
  130. }
  131. if (line_width)
  132. {
  133. fb_gfx_drawFastHLine(fb, x + xx - line_width, y + yy, line_width, color);
  134. line_width = 0;
  135. }
  136. }
  137. return xa;
  138. }
  139. uint32_t fb_gfx_print(camera_fb_t *fb, int x, int y, uint32_t color, const char *str)
  140. {
  141. uint32_t l = 0;
  142. int xc = x, yc = y, lc = fb->width - gfxFont->glyph[0].xAdvance;
  143. uint8_t fh = gfxFont->yAdvance;
  144. char c = *str++;
  145. while (c)
  146. {
  147. if (c != '\r')
  148. {
  149. if (c == '\n')
  150. {
  151. yc += fh;
  152. xc = x;
  153. }
  154. else
  155. {
  156. if (xc > lc)
  157. {
  158. yc += fh;
  159. xc = x;
  160. }
  161. xc += fb_gfx_putc(fb, xc, yc, color, c);
  162. }
  163. }
  164. l++;
  165. c = *str++;
  166. }
  167. return l;
  168. }
  169. uint32_t fb_gfx_printf(camera_fb_t *fb, int32_t x, int32_t y, uint32_t color, const char *format, ...)
  170. {
  171. char loc_buf[64];
  172. char *temp = loc_buf;
  173. int len;
  174. va_list arg;
  175. va_list copy;
  176. va_start(arg, format);
  177. va_copy(copy, arg);
  178. len = vsnprintf(loc_buf, sizeof(loc_buf), format, arg);
  179. va_end(copy);
  180. if (len >= sizeof(loc_buf))
  181. {
  182. temp = (char *)malloc(len + 1);
  183. if (temp == NULL)
  184. {
  185. return 0;
  186. }
  187. }
  188. vsnprintf(temp, len + 1, format, arg);
  189. va_end(arg);
  190. fb_gfx_print(fb, x, y, color, temp);
  191. if (len > 64)
  192. {
  193. free(temp);
  194. }
  195. return len;
  196. }