Hanna
Sourcecode Batteriemanagementsystem
gfx_text.c
gehe zur Dokumentation dieser Datei
1 
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 #include "compiler.h"
47 #include "stddef.h"
48 #include "assert.h"
49 #ifdef CONFIG_HUGEMEM
50 # include "hugemem.h"
51 #endif
52 #if XMEGA
53 //# include "progmem.h"
54 #endif
55 
56 #include "gfx.h"
57 #include "gfx_text.h"
58 
59 #ifndef CONFIG_FONT_PIXELS_PER_BYTE
60 # define CONFIG_FONT_PIXELS_PER_BYTE 8
61 #endif
62 
63 #define EXTMEM_BUF_SIZE 20
64 
65 #if defined(CONFIG_HUGEMEM) || defined(__DOXYGEN__)
66 
86 static void gfx_draw_char_hugemem(const char ch, const gfx_coord_t x,
87  const gfx_coord_t y, const struct font *font,
88  const gfx_color_t color)
89 {
90  uint8_t i;
91  uint8_t char_row_size;
92  uint8_t glyph_size;
93  uint16_t glyph_data_offset;
94  uint8_t char_buff[EXTMEM_BUF_SIZE];
95  uint8_t buffer_pos;
96  uint8_t rows_left;
97 
98  /* Sanity check on parameters, assert if font is NULL. */
99  Assert(font != NULL);
100 
101  gfx_coord_t inc_x = x;
102  gfx_coord_t inc_y = y;
103 
104  char_row_size = font->width / CONFIG_FONT_PIXELS_PER_BYTE;
105  if (font->width % CONFIG_FONT_PIXELS_PER_BYTE) {
106  char_row_size++;
107  }
108 
109  glyph_size = char_row_size * font->height;
110  glyph_data_offset = glyph_size * ((uint8_t)ch - font->first_char);
111  buffer_pos = EXTMEM_BUF_SIZE;
112  rows_left = font->height;
113 
114  do {
115  static uint8_t glyph_byte = 0;
116  uint8_t pixelsToDraw = font->width;
117 
118  for (i = 0; i < pixelsToDraw; i++) {
119  if (i % CONFIG_FONT_PIXELS_PER_BYTE == 0) {
120  /* Read another byte from hugemem */
121  if (buffer_pos >= EXTMEM_BUF_SIZE) {
122  hugemem_ptr_t source
123  = font->data.hugemem;
124  source = (hugemem_ptr_t)
125  ((uint32_t)source +
126  glyph_data_offset);
127 
128  hugemem_read_block(char_buff, source,
129  EXTMEM_BUF_SIZE);
130 
131  glyph_data_offset += EXTMEM_BUF_SIZE;
132  buffer_pos = 0;
133  }
134 
135  glyph_byte = char_buff[buffer_pos];
136  buffer_pos++;
137  }
138 
139  /* Draw bit of glyph to screen */
140  if ((glyph_byte & 0x80)) {
141  gfx_draw_pixel(inc_x, inc_y, color);
142  }
143 
144  inc_x += 1;
145  glyph_byte <<= 1;
146  }
147 
148  inc_y += 1;
149  inc_x = x;
150  } while (--rows_left > 0);
151 }
152 
153 #endif
154 
174 static void gfx_draw_char_progmem(const char ch, const gfx_coord_t x,
175  const gfx_coord_t y, const struct font *font,
176  const gfx_color_t color)
177 {
178  uint8_t PROGMEM_PTR_T glyph_data;
179  uint16_t glyph_data_offset;
180  uint8_t char_row_size;
181  uint8_t rows_left;
182  uint8_t i;
183 
184  /* Sanity check on parameters, assert if font is NULL. */
185  Assert(font != NULL);
186 
187  gfx_coord_t inc_x = x;
188  gfx_coord_t inc_y = y;
189 
190  char_row_size = font->width / CONFIG_FONT_PIXELS_PER_BYTE;
191  if (font->width % CONFIG_FONT_PIXELS_PER_BYTE) {
192  char_row_size++;
193  }
194 
195  glyph_data_offset = char_row_size * font->height *
196  ((uint8_t)ch - font->first_char);
197  glyph_data = font->data.progmem + glyph_data_offset;
198  rows_left = font->height;
199 
200  do {
201  uint8_t glyph_byte = 0;
202  uint8_t pixelsToDraw = font->width;
203 
204  for (i = 0; i < pixelsToDraw; i++) {
205  if (i % CONFIG_FONT_PIXELS_PER_BYTE == 0) {
206  glyph_byte = PROGMEM_READ_BYTE(glyph_data);
207  glyph_data++;
208  }
209 
210  if ((glyph_byte & 0x80)) {
211  gfx_draw_pixel(inc_x, inc_y, color);
212  }
213 
214  inc_x += 1;
215  glyph_byte <<= 1;
216  }
217 
218  inc_y += 1;
219  inc_x = x;
220  rows_left--;
221  } while (rows_left > 0);
222 }
223 
234 void gfx_draw_char(const char c, const gfx_coord_t x, const gfx_coord_t y,
235  const struct font *font, const gfx_color_t bg_color,
236  const gfx_color_t text_color)
237 {
238  if (bg_color != GFX_COLOR_TRANSPARENT) {
239  gfx_draw_filled_rect(x, y, font->width, font->height, bg_color);
240  }
241 
242  switch (font->type) {
243  case FONT_LOC_PROGMEM:
244  gfx_draw_char_progmem(c, x, y, font, text_color);
245  break;
246 
247 #ifdef CONFIG_HUGEMEM
248  case FONT_LOC_HUGEMEM:
249  gfx_draw_char_hugemem(c, x, y, font, text_color);
250  break;
251 
252 #endif
253  default:
254  /* Unsupported mode, call assert */
255  Assert(false);
256  break;
257  }
258 }
259 
272 void gfx_draw_string(const char *str, gfx_coord_t x, gfx_coord_t y,
273  const struct font *font, const gfx_color_t bg_color,
274  const gfx_color_t text_color)
275 {
276  gfx_draw_string_aligned(str, x, y, font, bg_color, text_color,
278 }
279 
296  const struct font *font, const gfx_color_t bg_color,
297  const gfx_color_t text_color, enum gfx_text_position text_pos,
298  enum gfx_text_alignment text_align)
299 {
300  gfx_coord_t bounding_x, bounding_y;
301 
302  /* Sanity check on parameters, assert if str or font is NULL. */
303  Assert(str != NULL);
304  Assert(font != NULL);
305 
306  /* Retrieve the bounding box of the overall text paragraph */
307  gfx_get_string_bounding_box(str, font, &bounding_x, &bounding_y);
308 
309  /* Move the Y coordinate according to the Y positional setting given */
310  if (text_pos & TEXT_POS_CENTER_Y) {
311  y -= bounding_y / 2;
312  } else if (text_pos & TEXT_POS_BOTTOM) {
313  y -= bounding_y;
314  }
315 
316  /* Move the X coordinate according to the X positional setting given */
317  if (text_pos & TEXT_POS_CENTER_X) {
318  x -= bounding_x / 2;
319  } else if (text_pos & TEXT_POS_RIGHT) {
320  x -= bounding_x;
321  }
322 
323  /* Need to draw each line of the text paragraph individually */
324  while (*str != '\0') {
325  const char *curr_line_text = str;
326  gfx_coord_t curr_line_x = x;
327  gfx_coord_t curr_line_width = 0;
328 
329  /* Determine width of current line in the the paragraph */
330  do {
331  if (*str == '\n') {
332  str++;
333  break;
334  } else if (*str != '\r') {
335  curr_line_width += font->width;
336  }
337  } while (*(++str) != '\0');
338 
339  /* Move the line starting X coordinate on the display according
340  * to the line width and the specified text alignment parameter
341  */
342  if (text_align == TEXT_ALIGN_CENTER) {
343  curr_line_x += (bounding_x / 2) - (curr_line_width / 2);
344  } else if (text_align == TEXT_ALIGN_RIGHT) {
345  curr_line_x += bounding_x - curr_line_width;
346  }
347 
348  /* Draw current line to the display with the calculated
349  * coordinates
350  */
351  do {
352  if (*curr_line_text == '\n') {
353  break;
354  } else if (*curr_line_text != '\r') {
355  gfx_draw_char(*curr_line_text, curr_line_x, y,
356  font, bg_color, text_color);
357 
358  /* Step to the next character display X
359  * coordinate
360  */
361  curr_line_x += font->width;
362  }
363  } while (*(++curr_line_text) != '\0');
364 
365  /* Step to the next Y line coordinate for the next line in
366  * paragraph
367  */
368  y += font->height + 1;
369  }
370 }
371 
389 void gfx_draw_progmem_string(char PROGMEM_PTR_T str, gfx_coord_t x,
390  gfx_coord_t y, const struct font *font,
391  const gfx_color_t bg_color, const gfx_color_t text_color)
392 {
393  gfx_draw_progmem_string_aligned(str, x, y, font, bg_color, text_color,
395 }
396 
414 void gfx_draw_progmem_string_aligned(char PROGMEM_PTR_T str,
415  gfx_coord_t x, gfx_coord_t y, const struct font *font,
416  const gfx_color_t bg_color, const gfx_color_t text_color,
417  enum gfx_text_position text_pos,
418  enum gfx_text_alignment text_align)
419 {
420  gfx_coord_t bounding_x, bounding_y;
421  char curr_str_char;
422 
423  /* Sanity check on parameters, assert if str or font is NULL. */
424  Assert(str != NULL);
425  Assert(font != NULL);
426 
427  /* Retrieve the bounding box of the overall text paragraph */
429  &bounding_x, &bounding_y);
430 
431  /* Move the Y coordinate according to the Y positional setting given */
432  if (text_pos & TEXT_POS_CENTER_Y) {
433  y -= bounding_y / 2;
434  } else if (text_pos & TEXT_POS_BOTTOM) {
435  y -= bounding_y;
436  }
437 
438  /* Move the X coordinate according to the X positional setting given */
439  if (text_pos & TEXT_POS_CENTER_X) {
440  x -= bounding_x / 2;
441  } else if (text_pos & TEXT_POS_RIGHT) {
442  x -= bounding_x;
443  }
444 
445  curr_str_char = PROGMEM_READ_BYTE((uint8_t PROGMEM_PTR_T)str);
446 
447  /* Need to draw each line of the text paragraph individually */
448  while (curr_str_char != '\0') {
449  char PROGMEM_PTR_T curr_line_text = str;
450  char curr_line_char;
451  gfx_coord_t curr_line_x = x;
452  gfx_coord_t curr_line_width = 0;
453 
454  /* Determine width of current line in the the paragraph */
455  do {
456  if (curr_str_char == '\n') {
457  curr_str_char
458  = PROGMEM_READ_BYTE(
459  (uint8_t PROGMEM_PTR_T)(++str));
460  break;
461  } else if (curr_str_char != '\r') {
462  curr_line_width += font->width;
463  }
464 
465  curr_str_char = PROGMEM_READ_BYTE(
466  (uint8_t PROGMEM_PTR_T)(++str));
467  } while (curr_str_char != '\0');
468 
469  /* Move the line starting X coordinate on the display according
470  * to the line width and the specified text alignment parameter
471  */
472  if (text_align == TEXT_ALIGN_CENTER) {
473  curr_line_x += (bounding_x / 2) - (curr_line_width / 2);
474  } else if (text_align == TEXT_ALIGN_RIGHT) {
475  curr_line_x += bounding_x - curr_line_width;
476  }
477 
478  curr_line_char = PROGMEM_READ_BYTE(
479  (uint8_t PROGMEM_PTR_T)curr_line_text);
480 
481  /* Draw current line to the display with the calculated
482  * coordinates
483  */
484  do {
485  if (*curr_line_text == '\n') {
486  break;
487  } else if (*curr_line_text != '\r') {
488  gfx_draw_char(*curr_line_text, curr_line_x, y,
489  font, bg_color, text_color);
490 
491  /* Step to the next character display X
492  *coordinate
493  */
494  curr_line_x += font->width;
495  }
496 
497  curr_line_char = PROGMEM_READ_BYTE(
498  (uint8_t PROGMEM_PTR_T)(++curr_line_text));
499  } while (curr_line_char != '\0');
500 
501  /* Step to the next Y line coordinate for the next line in
502  * paragraph
503  */
504  y += font->height + 1;
505  }
506 }
507 
519 void gfx_get_string_bounding_box(const char *str, const struct font *font,
521 {
522  gfx_coord_t font_width = font->width;
523  gfx_coord_t font_height = font->height;
524 
525  gfx_coord_t max_width = 1;
526  gfx_coord_t max_height = font_height;
527  gfx_coord_t x = 0;
528 
529  /* Sanity check on parameters, assert if str or font is NULL. */
530  Assert(str != NULL);
531  Assert(font != NULL);
532 
533  /* Handle each character until trailing null byte */
534  do {
535  /* Handle '\n' as newline, draw normal characters. */
536  if (*str == '\n') {
537  x = 0;
538  max_height += font_height;
539  } else if (*str == '\r') {
540  /* Skip '\r' characters. */
541  } else {
542  x += font_width;
543  if (x > max_width) {
544  max_width = x;
545  }
546  }
547  } while (*(++str));
548 
549  /* Return values through references */
550  *width = max_width;
551  *height = max_height;
552 }
553 
565 void gfx_get_progmem_string_bounding_box(char PROGMEM_PTR_T str,
566  const struct font *font, gfx_coord_t *width,
568 {
569  gfx_coord_t font_width = font->width;
570  gfx_coord_t font_height = font->height;
571 
572  char temp_char;
573  gfx_coord_t max_width = 1;
574  gfx_coord_t max_height = font_height;
575  gfx_coord_t x = 0;
576 
577  /* Sanity check on parameters, assert if str or font is NULL. */
578  Assert(str != NULL);
579  Assert(font != NULL);
580 
581  /* Handle each character until trailing null byte */
582  temp_char = PROGMEM_READ_BYTE((uint8_t PROGMEM_PTR_T)str);
583 
584  while (temp_char) {
585  /* Handle '\n' as newline, draw normal characters. */
586  if (temp_char == '\n') {
587  x = 0;
588  max_height += font_height;
589  } else if (*str == '\r') {
590  /* Skip '\r' characters. */
591  } else {
592  x += font_width;
593  if (x > max_width) {
594  max_width = x;
595  }
596  }
597 
598  temp_char = PROGMEM_READ_BYTE((uint8_t PROGMEM_PTR_T)(++str));
599  }
600 
601  /* Return values through references */
602  *width = max_width;
603  *height = max_height;
604 }
uint8_t height
Definition: gfx_text.h:127
void gfx_draw_string(const char *str, gfx_coord_t x, gfx_coord_t y, const struct font *font, const gfx_color_t bg_color, const gfx_color_t text_color)
Draws a string to the display.
Definition: gfx_text.c:272
void gfx_get_progmem_string_bounding_box(char PROGMEM_PTR_T str, const struct font *font, gfx_coord_t *width, gfx_coord_t *height)
Computes the bounding box of a string located in program memory.
Definition: gfx_text.c:565
void gfx_draw_progmem_string(char PROGMEM_PTR_T str, gfx_coord_t x, gfx_coord_t y, const struct font *font, const gfx_color_t bg_color, const gfx_color_t text_color)
Draws a string located in program memory to the display.
Definition: gfx_text.c:389
Commonly used includes, types and macros.
#define Assert(expr)
This macro is used to test fatal errors.
Definition: compiler.h:46
void gfx_get_string_bounding_box(const char *str, const struct font *font, gfx_coord_t *width, gfx_coord_t *height)
Computes the bounding box of a string.
Definition: gfx_text.c:519
#define gfx_draw_pixel(x, y, color)
Definition: gfx_ili9341.h:257
#define GFX_COLOR_TRANSPARENT
Value used as input to font functions to give a transparent background region.
Definition: gfx_ili9341.h:73
Definition: gfx_text.h:109
gfx_color_t color
Definition: gfx_generic.h:94
enum font_data_type type
Definition: gfx_text.h:111
gfx_coord_t height
Definition: gfx_generic.h:87
uint8_t first_char
Definition: gfx_text.h:129
ili9341_coord_t gfx_coord_t
Data type representing a coordinate on the screen.
Definition: gfx_ili9341.h:58
Graphical library API header file.
static void gfx_draw_char_progmem(const char ch, const gfx_coord_t x, const gfx_coord_t y, const struct font *font, const gfx_color_t color)
Helper function that draws a character from a font in progmem to the display.
Definition: gfx_text.c:174
void gfx_draw_progmem_string_aligned(char PROGMEM_PTR_T str, gfx_coord_t x, gfx_coord_t y, const struct font *font, const gfx_color_t bg_color, const gfx_color_t text_color, enum gfx_text_position text_pos, enum gfx_text_alignment text_align)
Draws an aligned string located in program memory to the display.
Definition: gfx_text.c:414
Graphic library API header file.
gfx_text_alignment
Definition: gfx_text.h:73
#define gfx_draw_filled_rect(x, y, width, height, color)
Definition: gfx_ili9341.h:178
gfx_coord_t width
Definition: gfx_generic.h:85
void gfx_draw_string_aligned(const char *str, gfx_coord_t x, gfx_coord_t y, const struct font *font, const gfx_color_t bg_color, const gfx_color_t text_color, enum gfx_text_position text_pos, enum gfx_text_alignment text_align)
Draws an aligned string to the display.
Definition: gfx_text.c:295
uint8_t width
Definition: gfx_text.h:125
ili9341_color_t gfx_color_t
Data type for color values native to the display.
Definition: gfx_ili9341.h:57
void gfx_draw_char(const char c, const gfx_coord_t x, const gfx_coord_t y, const struct font *font, const gfx_color_t bg_color, const gfx_color_t text_color)
Draws a character to the display.
Definition: gfx_text.c:234
uint8_t PROGMEM_PTR_T progmem
Definition: gfx_text.h:121
gfx_text_position
Definition: gfx_text.h:83