maug
Quick and dirty C mini-augmentation library.
retrofnt.h
Go to the documentation of this file.
1
2#ifndef RETROFNT_H
3#define RETROFNT_H
4
17#define RETROFONT_PRESENT 1
18
19#ifndef RETROFONT_LINE_SZ
20# define RETROFONT_LINE_SZ 80
21#endif /* !RETROFONT_LINE_SZ */
22
23#ifndef RETROFONT_TRACE_LVL
24# define RETROFONT_TRACE_LVL 0
25#endif /* !RETROFONT_TRACE_LVL */
26
31#define RETROFONT_FLAG_OUTLINE 0x04
32
40#define RETROFONT_FLAG_OUTLINE_LIGHT 0x0c
41
46#define RETROFONT_FLAG_SZ_MIN 0x10
47
51struct RETROFONT;
52
62 const char* font_name, MAUG_MHANDLE* p_font_h,
63 uint8_t glyph_h, uint16_t first_glyph, uint16_t glyphs_count );
64
75 retroflat_blit_t* target, RETROFLAT_COLOR color,
76 const char* str, size_t str_sz,
77 MAUG_MHANDLE font_h, retroflat_pxxy_t x, retroflat_pxxy_t y,
78 retroflat_pxxy_t max_w, retroflat_pxxy_t max_h, uint8_t flags );
79
80void retrofont_string_indent(
81 retroflat_blit_t* target, RETROFLAT_COLOR color,
82 const char* str, size_t str_sz,
83 MAUG_MHANDLE font_h, retroflat_pxxy_t x, retroflat_pxxy_t y,
85 retroflat_pxxy_t x_iter, uint8_t flags );
86
87MERROR_RETVAL retrofont_string_sz(
88 retroflat_blit_t* target, const char* str, size_t str_sz,
89 MAUG_MHANDLE font_h, retroflat_pxxy_t max_w, retroflat_pxxy_t max_h,
90 retroflat_pxxy_t* p_out_w, retroflat_pxxy_t* p_out_h, uint8_t flags );
91
92void retrofont_free( MAUG_MHANDLE* p_font_h );
93
99 struct RETROFONT* font, const char* sub_name, void* data );
100
101#ifdef RETROFNT_C
102
103/* Provide this utility to all font API internal mechanisms. */
104
105MERROR_RETVAL retrofont_read_line(
106 mfile_t* font_file, char* glyph_idx_str, char** p_glyph_bytes
107) {
108 MERROR_RETVAL retval = MERROR_OK;
109 size_t last_char_idx = 0;
110
111 retval = font_file->read_line(
112 font_file, glyph_idx_str, RETROFONT_LINE_SZ, 0 );
113 maug_cleanup_if_not_ok();
114
115 *p_glyph_bytes = maug_strchr( glyph_idx_str, ':' );
116 if( NULL == *p_glyph_bytes ) { \
117 error_printf( "invalid line: %s", glyph_idx_str );
118 /* The line couldn't parse, so skip it, but don't give up entirely and
119 * keep going to the next line.
120 */
121 retval = MERROR_WAIT;
122 goto cleanup;
123 }
124
125 /* Replace : with NULL to split the string and move pointer to actual bytes.
126 */
127 (*p_glyph_bytes)[0] = '\0'; \
128 (*p_glyph_bytes)++;
129
130 /* Hunt for sub statements. */
131 if( 0 == strncmp( "SUB", glyph_idx_str, 3 ) ) {
132 last_char_idx = maug_strlen( *p_glyph_bytes ) - 1;
133 if(
134 '\n' == (*p_glyph_bytes)[last_char_idx] ||
135 '\r' == (*p_glyph_bytes)[last_char_idx] ||
136 '\t' == (*p_glyph_bytes)[last_char_idx] ||
137 ' ' == (*p_glyph_bytes)[last_char_idx]
138 ) {
139 (*p_glyph_bytes)[last_char_idx] = '\0';
140 }
141 debug_printf( RETROFONT_TRACE_LVL, "found sub: \"%s\"", *p_glyph_bytes );
142 retval = MERROR_PARSE;
143 goto cleanup;
144 }
145
146cleanup:
147 return retval;
148}
149
150/* === */
151
152MERROR_RETVAL retrofont_load_stub(
153 const char* font_name, struct RETROFONT* font,
154 retrofont_try_platform_t try_platform,
155 void* try_platform_data
156) {
157 MERROR_RETVAL retval = MERROR_OK;
158 mfile_t font_file;
159 maug_path font_stub_name;
160 char line[RETROFONT_LINE_SZ];
161 char* line_bytes = NULL;
162
163 /* Load font stub and find substitute. */
164 maug_mzero( font_stub_name, sizeof( maug_path ) );
165 mfile_assign_path( font_stub_name, font_name, 0 );
166 font_stub_name[strlen( font_stub_name ) - 5] = 'x';
167 debug_printf( RETROFONT_TRACE_LVL, "stub font_name: %s", font_stub_name );
168 maug_mzero( &font_file, sizeof( mfile_t ) );
169
170 retval = mfile_open_read( font_stub_name, &font_file );
171 maug_cleanup_if_not_ok();
172
173 /* Figure out font width from file and alloc just enough. */
174 do {
175 retval = retrofont_read_line( &font_file, line, &line_bytes );
176 if( MERROR_WAIT == retval || MERROR_OK == retval ) {
177 /* Not a sub line. */
178 retval = MERROR_PARSE;
179 continue;
180
181 } else if( MERROR_PARSE != retval ) {
182 goto cleanup;
183 }
184 debug_printf( RETROFONT_TRACE_LVL, "attempting substitute: %s",
185 line_bytes );
186 retval = try_platform( font, line_bytes, try_platform_data );
187 } while( MERROR_PARSE == retval );
188
189cleanup:
190
191 mfile_close( &font_file );
192
193 return retval;
194}
195
196/* === */
197
198size_t retrofont_sz_from_filename( const char* font_name ) {
199 const char* p_c = NULL;
200 size_t glyph_h = 0;
201 size_t i = 0;
202 char glyph_h_buf[10];
203
204 maug_mzero( glyph_h_buf, 10 );
205
206 assert( NULL != font_name );
207 assert( ' ' <= font_name[0] );
208
209 p_c = maug_strrchr( font_name, '.' );
210 while( p_c - 1 > font_name ) {
211 /* Start at the char before the '.' and work backwords until a '-'. */
212 p_c--;
213 if( '-' == *p_c || '_' == *p_c ) {
214 break;
215 }
216
217 /* TODO: Break if not a digit! */
218
219 /* Shift existing numbers up by one. */
220 for( i = 9 ; 0 < i ; i-- ) {
221 glyph_h_buf[i] = glyph_h_buf[i - 1];
222 }
223
224 /* Add the most recent number to the beginning. */
225 glyph_h_buf[0] = *p_c;
226 }
227
228 glyph_h = maug_atou32( glyph_h_buf, 9, 10 );
229
230 debug_printf(
231 RETROFONT_TRACE_LVL, "detected glyph height: " SIZE_T_FMT, glyph_h );
232
233 return glyph_h;
234}
235
236/* === */
237
239 retroflat_blit_t* target, RETROFLAT_COLOR color,
240 const char* str, size_t str_sz,
241 MAUG_MHANDLE font_h, retroflat_pxxy_t x, retroflat_pxxy_t y,
242 retroflat_pxxy_t max_w, retroflat_pxxy_t max_h, uint8_t flags
243) {
244 retrofont_string_indent(
245 target, color, str, str_sz, font_h, x, y, max_w, max_h, 0, flags );
246}
247
248#endif /* RETROFNT_C */
249
250#include <mrapifon.h>
251
252/* \} */ /* retrofnt */
253
254#endif /* !RETROFNT_H */
255
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition: merror.h:28
MERROR_RETVAL mfile_open_read(const maug_path filename, mfile_t *p_file)
Open a file and read it into memory or memory-map it.
void mfile_close(mfile_t *p_file)
Close a file opened with mfile_open_read().
MERROR_RETVAL mfile_assign_path(maug_path tgt, const maug_path src, uint8_t flags)
Copy a maug_path from one place to another, safely observing character limits, etc.
char maug_path[MAUG_PATH_SZ_MAX]
Path/name used to load an asset from disk or access other files.
Definition: mfile.h:141
int8_t RETROFLAT_COLOR
Defines an index in the platform-specific color-table.
Definition: retroflt.h:326
int16_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition: retroflt.h:879
MERROR_RETVAL(* retrofont_try_platform_t)(struct RETROFONT *font, const char *sub_name, void *data)
Callback for platform-specific font substitute loader to attempt to use font substitute.
Definition: retrofnt.h:98
MERROR_RETVAL retrofont_load(const char *font_name, MAUG_MHANDLE *p_font_h, uint8_t glyph_h, uint16_t first_glyph, uint16_t glyphs_count)
Load a font for drawing.
void retrofont_string(retroflat_blit_t *target, RETROFLAT_COLOR color, const char *str, size_t str_sz, MAUG_MHANDLE font_h, retroflat_pxxy_t x, retroflat_pxxy_t y, retroflat_pxxy_t max_w, retroflat_pxxy_t max_h, uint8_t flags)
Draw a string with the given font.
Definition: mfile.h:206