2 * DGen's font renderer.
9 #include "font.h" /* The interface functions */
12 #define FONT_VISIBLE 24
15 extern const short *dgen_font_8x13
[0x80];
16 extern const short *dgen_font_16x26
[0x80];
17 extern const short *dgen_font_7x5
[0x80];
19 const struct dgen_font dgen_font
[] = {
20 { 16, 26, &dgen_font_16x26
},
21 { 8, 13, &dgen_font_8x13
},
22 { 7, 5, &dgen_font_7x5
},
26 const struct dgen_font
*font_select(unsigned int max_width
,
27 unsigned int max_height
,
30 const struct dgen_font
*font
= dgen_font
;
32 assert(type
<= FONT_TYPE_AUTO
);
33 if (type
!= FONT_TYPE_AUTO
) {
34 // Make sure we're able to display at least one character.
36 if ((max_width
< font
->w
) || (max_height
< font
->h
))
40 // Chose a font able to display at least FONT_VISIBLE characters.
41 while ((font
->data
!= NULL
) &&
42 ((font
->h
> max_height
) ||
43 ((max_width
/ font
->w
) < FONT_VISIBLE
))) {
47 if (font
->data
== NULL
)
52 static void font_mark(uint8_t *buf
,
53 unsigned int max_width
, unsigned int max_height
,
54 unsigned int bytes_per_pixel
, unsigned int pitch
,
56 unsigned int font_w
, unsigned int font_h
)
60 if (((mark_x
+ font_w
) > max_width
) || (max_height
< font_h
))
62 buf
+= (mark_x
* bytes_per_pixel
);
63 for (y
= 0; (y
!= font_h
); ++y
) {
65 unsigned int len
= (bytes_per_pixel
* font_w
);
67 for (x
= 0; (x
< len
); ++x
)
73 size_t font_text_width(const char *msg
, size_t len
,
74 unsigned int max_width
, unsigned int max_height
,
77 const struct dgen_font
*font
=
78 font_select(max_width
, max_height
, type
);
83 while ((*msg
!= '\0') && (len
)) {
91 size_t font_text_max_len(unsigned int max_width
, unsigned int max_height
,
94 const struct dgen_font
*font
=
95 font_select(max_width
, max_height
, type
);
99 return (max_width
/ font
->w
);
102 size_t font_text(uint8_t *buf
,
103 unsigned int max_width
, unsigned int max_height
,
104 unsigned int bytes_per_pixel
, unsigned int pitch
,
105 const char *msg
, size_t len
, unsigned int mark
,
108 const struct dgen_font
*font
;
115 if ((font
= font_select(max_width
, max_height
, type
)) == NULL
) {
116 printf("info: %.*s\n", (unsigned int)len
, msg
);
119 for (x
= 0; (x
!= mark
); ++x
)
125 p_max
= (buf
+ (pitch
* max_height
));
127 ((msg
[r
] != '\0') && (r
!= len
) && ((x
+ font
->w
) <= max_width
));
129 const short *glyph
= (*font
->data
)[(msg
[r
] & 0x7f)];
130 uint8_t *p
= (buf
+ (x
* bytes_per_pixel
));
136 while ((g
= *glyph
) != -1) {
139 p
+= (((n
+= g
) / font
->w
) * pitch
);
141 for (i
= 0; (i
< bytes_per_pixel
); ++i
) {
142 uint8_t *tmp
= &p
[((n
* bytes_per_pixel
) + i
)];
150 font_mark(buf
, max_width
, max_height
, bytes_per_pixel
,
151 pitch
, x
, font
->w
, font
->h
);
154 font_mark(buf
, max_width
, max_height
, bytes_per_pixel
, pitch
,
155 x
, font
->w
, font
->h
);