1 #include "mf_font.h"
2 #include <stdbool.h>
3 
4 /* This will be made into a list of included fonts using macro magic. */
5 #define MF_INCLUDED_FONTS 0
6 
7 /* Included fonts begin here */
8 #include MF_FONT_FILE_NAME
9 /* Include fonts end here */
10 
mf_render_character(const struct mf_font_s * font,int16_t x0,int16_t y0,mf_char character,mf_pixel_callback_t callback,void * state)11 uint8_t mf_render_character(const struct mf_font_s *font,
12                             int16_t x0, int16_t y0,
13                             mf_char character,
14                             mf_pixel_callback_t callback,
15                             void *state)
16 {
17     uint8_t width;
18     width = font->render_character(font, x0, y0, character, callback, state);
19 
20     if (!width)
21     {
22         width = font->render_character(font, x0, y0, font->fallback_character,
23                                        callback, state);
24     }
25 
26     return width;
27 }
28 
mf_character_width(const struct mf_font_s * font,mf_char character)29 uint8_t mf_character_width(const struct mf_font_s *font,
30                            mf_char character)
31 {
32     uint8_t width;
33     width = font->character_width(font, character);
34 
35     if (!width)
36     {
37         width = font->character_width(font, font->fallback_character);
38     }
39 
40     return width;
41 }
42 
43 struct whitespace_state
44 {
45     uint8_t min_x, min_y;
46     uint8_t max_x, max_y;
47 };
48 
whitespace_callback(int16_t x,int16_t y,uint8_t count,uint8_t alpha,void * state)49 static void whitespace_callback(int16_t x, int16_t y, uint8_t count,
50                                 uint8_t alpha, void *state)
51 {
52     struct whitespace_state *s = state;
53     if (alpha > 7)
54     {
55         if (s->min_x > x) s->min_x = x;
56         if (s->min_y > y) s->min_y = y;
57         x += count - 1;
58         if (s->max_x < x) s->max_x = x;
59         if (s->max_y < y) s->max_y = y;
60     }
61 }
62 
mf_character_whitespace(const struct mf_font_s * font,mf_char character,uint8_t * left,uint8_t * top,uint8_t * right,uint8_t * bottom)63 MF_EXTERN void mf_character_whitespace(const struct mf_font_s *font,
64                                        mf_char character,
65                                        uint8_t *left, uint8_t *top,
66                                        uint8_t *right, uint8_t *bottom)
67 {
68     struct whitespace_state state = {255, 255, 0, 0};
69     mf_render_character(font, 0, 0, character, whitespace_callback, &state);
70 
71     if (state.min_x == 255 && state.min_y == 255)
72     {
73         /* Character is whitespace */
74         if (left) *left = font->width;
75         if (top) *top = font->height;
76         if (right) *right = 0;
77         if (bottom) *bottom = 0;
78     }
79     else
80     {
81         if (left) *left = state.min_x;
82         if (top) *top = state.min_y;
83         if (right) *right = font->width - state.max_x - 1;
84         if (bottom) *bottom = font->height - state.max_y - 1;
85     }
86 }
87 
88 /* Avoids a dependency on libc */
strequals(const char * a,const char * b)89 static bool strequals(const char *a, const char *b)
90 {
91     while (*a)
92     {
93         if (*a++ != *b++)
94             return false;
95     }
96     return (!*b);
97 }
98 
mf_find_font(const char * name)99 const struct mf_font_s *mf_find_font(const char *name)
100 {
101     const struct mf_font_list_s *f;
102     f = MF_INCLUDED_FONTS;
103 
104     while (f)
105     {
106         if (strequals(f->font->full_name, name) ||
107             strequals(f->font->short_name, name))
108         {
109             return f->font;
110         }
111 
112         f = f->next;
113     }
114 
115     return 0;
116 }
117 
mf_get_font_list()118 const struct mf_font_list_s *mf_get_font_list()
119 {
120     return MF_INCLUDED_FONTS;
121 }
122 
123