8 #include "mf_rlefont.h"
16 #define REF_FILLZEROS 16
19 #define RLE_CODEMASK 0xC0
20 #define RLE_VALMASK 0x3F
21 #define RLE_ZEROS 0x00
22 #define RLE_64ZEROS 0x40
24 #define RLE_SHADE 0xC0
27 #define DICT_START7BIT 4
28 #define DICT_START6BIT 132
29 #define DICT_START5BIT 196
30 #define DICT_START4BIT 228
31 #define DICT_START3BIT 244
32 #define DICT_START2BIT 252
38 static const gU8 *find_glyph(
const struct mf_rlefont_s *font,
42 const struct mf_rlefont_char_range_s *range;
43 for (i = 0; i < font->char_range_count; i++)
45 range = &font->char_ranges[i];
46 index = character - range->first_char;
47 if (character >= range->first_char && index < range->char_count)
49 unsigned offset = range->glyph_offsets[index];
50 return &range->glyph_data[offset];
66 mf_pixel_callback_t callback;
72 static void write_pixels(
struct renderstate_r *rstate, gU16 count,
78 while (rstate->x + count >= rstate->x_end)
80 rowlen = rstate->x_end - rstate->x;
81 rstate->callback(rstate->x, rstate->y, rowlen, alpha, rstate->state);
83 rstate->x = rstate->x_begin;
90 rstate->callback(rstate->x, rstate->y, count, alpha, rstate->state);
96 static void skip_pixels(
struct renderstate_r *rstate, gU16 count)
99 while (rstate->x >= rstate->x_end)
101 rstate->x -= rstate->x_end - rstate->x_begin;
107 static void write_rle_dictentry(
const struct mf_rlefont_s *font,
108 struct renderstate_r *rstate,
111 gU16 offset = font->dictionary_offsets[index];
112 gU16 length = font->dictionary_offsets[index + 1] - offset;
115 for (i = 0; i < length; i++)
117 gU8 code = font->dictionary_data[offset + i];
118 if ((code & RLE_CODEMASK) == RLE_ZEROS)
120 skip_pixels(rstate, code & RLE_VALMASK);
122 else if ((code & RLE_CODEMASK) == RLE_64ZEROS)
124 skip_pixels(rstate, ((code & RLE_VALMASK) + 1) * 64);
126 else if ((code & RLE_CODEMASK) == RLE_ONES)
128 write_pixels(rstate, (code & RLE_VALMASK) + 1, 255);
130 else if ((code & RLE_CODEMASK) == RLE_SHADE)
133 count = ((code & RLE_VALMASK) >> 4) + 1;
134 alpha = ((code & RLE_VALMASK) & 0xF) * 0x11;
135 write_pixels(rstate, count, alpha);
141 static gU8 fillentry_bitcount(gU8 index)
143 if (index >= DICT_START2BIT)
145 else if (index >= DICT_START3BIT)
147 else if (index >= DICT_START4BIT)
149 else if (index >= DICT_START5BIT)
151 else if (index >= DICT_START6BIT)
158 static void write_bin_codeword(
const struct mf_rlefont_s *font,
159 struct renderstate_r *rstate,
162 gU8 bitcount = fillentry_bitcount(code);
163 gU8
byte = code - DICT_START7BIT;
177 write_pixels(rstate, runlen, 255);
181 skip_pixels(rstate, 1);
188 write_pixels(rstate, runlen, 255);
192 static void write_ref_codeword(
const struct mf_rlefont_s *font,
193 struct renderstate_r *rstate,
198 write_pixels(rstate, 1, 0x11 * code);
200 else if (code == REF_FILLZEROS)
203 rstate->y = rstate->y_end;
205 else if (code < DICT_START)
209 else if (code < DICT_START + font->rle_entry_count)
211 write_rle_dictentry(font, rstate, code - DICT_START);
215 write_bin_codeword(font, rstate, code);
220 static void write_ref_dictentry(
const struct mf_rlefont_s *font,
221 struct renderstate_r *rstate,
224 gU16 offset = font->dictionary_offsets[index];
225 gU16 length = font->dictionary_offsets[index + 1] - offset;
228 for (i = 0; i < length; i++)
230 gU8 code = font->dictionary_data[offset + i];
231 write_ref_codeword(font, rstate, code);
236 static void write_glyph_codeword(
const struct mf_rlefont_s *font,
237 struct renderstate_r *rstate,
240 if (code >= DICT_START + font->rle_entry_count &&
241 code < DICT_START + font->dict_entry_count)
243 write_ref_dictentry(font, rstate, code - DICT_START);
247 write_ref_codeword(font, rstate, code);
252 gU8 mf_rlefont_render_character(
const struct mf_font_s *font,
255 mf_pixel_callback_t callback,
261 struct renderstate_r rstate;
263 rstate.x_end = x0 + font->width;
266 rstate.y_end = y0 + font->height;
267 rstate.callback = callback;
268 rstate.state = state;
270 p = find_glyph((
struct mf_rlefont_s*)font, character);
275 while (rstate.y < rstate.y_end)
277 write_glyph_codeword((
struct mf_rlefont_s*)font, &rstate, *p++);
283 gU8 mf_rlefont_character_width(
const struct mf_font_s *font,
287 p = find_glyph((
struct mf_rlefont_s*)font, character);