gdisp: Update font decoder
This commit is contained in:
parent
bfc28ae986
commit
44ef4ac25b
@ -27,7 +27,7 @@ static const struct mf_bwfont_char_range_s *find_char_range(
|
|||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ static gU8 render_char(const struct mf_bwfont_char_range_s *r,
|
|||||||
gU8 x, y, height, num_cols;
|
gU8 x, y, height, num_cols;
|
||||||
gU8 bit, byte, mask;
|
gU8 bit, byte, mask;
|
||||||
bool oldstate, newstate;
|
bool oldstate, newstate;
|
||||||
|
|
||||||
if (r->width)
|
if (r->width)
|
||||||
{
|
{
|
||||||
data = r->glyph_data + r->width * index * r->height_bytes;
|
data = r->glyph_data + r->width * index * r->height_bytes;
|
||||||
@ -64,18 +64,18 @@ static gU8 render_char(const struct mf_bwfont_char_range_s *r,
|
|||||||
data = r->glyph_data + r->glyph_offsets[index] * r->height_bytes;
|
data = r->glyph_data + r->glyph_offsets[index] * r->height_bytes;
|
||||||
num_cols = r->glyph_offsets[index + 1] - r->glyph_offsets[index];
|
num_cols = r->glyph_offsets[index + 1] - r->glyph_offsets[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
stride = r->height_bytes;
|
stride = r->height_bytes;
|
||||||
height = r->height_pixels;
|
height = r->height_pixels;
|
||||||
y0 += r->offset_y;
|
y0 += r->offset_y;
|
||||||
x0 += r->offset_x;
|
x0 += r->offset_x;
|
||||||
bit = 0;
|
bit = 0;
|
||||||
byte = 0;
|
byte = 0;
|
||||||
|
|
||||||
for (y = 0; y < height; y++)
|
for (y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
mask = (1 << bit);
|
mask = (1 << bit);
|
||||||
|
|
||||||
oldstate = false;
|
oldstate = false;
|
||||||
runlen = 0;
|
runlen = 0;
|
||||||
p = data + byte;
|
p = data + byte;
|
||||||
@ -88,19 +88,19 @@ static gU8 render_char(const struct mf_bwfont_char_range_s *r,
|
|||||||
{
|
{
|
||||||
callback(x0 + x - runlen, y0 + y, runlen, 255, state);
|
callback(x0 + x - runlen, y0 + y, runlen, 255, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
oldstate = newstate;
|
oldstate = newstate;
|
||||||
runlen = 0;
|
runlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
runlen++;
|
runlen++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldstate && runlen)
|
if (oldstate && runlen)
|
||||||
{
|
{
|
||||||
callback(x0 + x - runlen, y0 + y, runlen, 255, state);
|
callback(x0 + x - runlen, y0 + y, runlen, 255, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
bit++;
|
bit++;
|
||||||
if (bit > 7)
|
if (bit > 7)
|
||||||
{
|
{
|
||||||
@ -108,7 +108,7 @@ static gU8 render_char(const struct mf_bwfont_char_range_s *r,
|
|||||||
byte++;
|
byte++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_width(r, index);
|
return get_width(r, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ gU8 mf_bwfont_render_character(const struct mf_font_s *font,
|
|||||||
range = find_char_range(bwfont, character, &index);
|
range = find_char_range(bwfont, character, &index);
|
||||||
if (!range)
|
if (!range)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return render_char(range, x0, y0, index, callback, state);
|
return render_char(range, x0, y0, index, callback, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ gU8 mf_bwfont_character_width(const struct mf_font_s *font,
|
|||||||
range = find_char_range(bwfont, character, &index);
|
range = find_char_range(bwfont, character, &index);
|
||||||
if (!range)
|
if (!range)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return get_width(range, index);
|
return get_width(range, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,9 @@
|
|||||||
#define MF_USE_KERNING GDISP_NEED_TEXT_KERNING
|
#define MF_USE_KERNING GDISP_NEED_TEXT_KERNING
|
||||||
#define MF_FONT_FILE_NAME "src/gdisp/fonts/fonts.h"
|
#define MF_FONT_FILE_NAME "src/gdisp/fonts/fonts.h"
|
||||||
|
|
||||||
/* These are not used for now */
|
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
||||||
#define MF_USE_JUSTIFY 0
|
#define pgm_read_word(addr) (*(const uint16_t *)(addr))
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************
|
/*******************************************************
|
||||||
* Configuration settings related to build environment *
|
* Configuration settings related to build environment *
|
||||||
@ -168,7 +169,7 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define MF_EXTERN extern "C"
|
#define MF_EXTERN extern "C"
|
||||||
#else
|
#else
|
||||||
#define MF_EXTERN
|
#define MF_EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,9 +20,9 @@ mf_char mf_getchar(mf_str *str)
|
|||||||
c = **str;
|
c = **str;
|
||||||
if (!c)
|
if (!c)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
(*str)++;
|
(*str)++;
|
||||||
|
|
||||||
if ((c & 0x80) == 0)
|
if ((c & 0x80) == 0)
|
||||||
{
|
{
|
||||||
/* Just normal ASCII character. */
|
/* Just normal ASCII character. */
|
||||||
@ -54,14 +54,14 @@ mf_char mf_getchar(mf_str *str)
|
|||||||
{
|
{
|
||||||
seqlen++;
|
seqlen++;
|
||||||
tmp >>= 1;
|
tmp >>= 1;
|
||||||
|
|
||||||
result = (result << 6) | (**str & 0x3F);
|
result = (result << 6) | (**str & 0x3F);
|
||||||
(*str)++;
|
(*str)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = (result << 6) | (**str & 0x3F);
|
result = (result << 6) | (**str & 0x3F);
|
||||||
(*str)++;
|
(*str)++;
|
||||||
|
|
||||||
result |= (c & (tmp - 1)) << ((seqlen - 1) * 6);
|
result |= (c & (tmp - 1)) << ((seqlen - 1) * 6);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ mf_char mf_getchar(mf_str *str)
|
|||||||
void mf_rewind(mf_str *str)
|
void mf_rewind(mf_str *str)
|
||||||
{
|
{
|
||||||
(*str)--;
|
(*str)--;
|
||||||
|
|
||||||
while ((**str & 0x80) != 0x00 && (**str & 0xC0) != 0xC0)
|
while ((**str & 0x80) != 0x00 && (**str & 0xC0) != 0xC0)
|
||||||
(*str)--;
|
(*str)--;
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ mf_char mf_getchar(mf_str *str)
|
|||||||
|
|
||||||
void mf_rewind(mf_str *str)
|
void mf_rewind(mf_str *str)
|
||||||
{
|
{
|
||||||
(*str)--;
|
(*str)--;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,10 +40,10 @@ typedef const wchar_t * mf_str;
|
|||||||
|
|
||||||
/* Returns the next character in the string and advances the pointer.
|
/* Returns the next character in the string and advances the pointer.
|
||||||
* When the string ends, returns 0 and leaves the pointer at the 0 byte.
|
* When the string ends, returns 0 and leaves the pointer at the 0 byte.
|
||||||
*
|
*
|
||||||
* str: Pointer to variable holding current location in string.
|
* str: Pointer to variable holding current location in string.
|
||||||
* Initialize it to the start of the string.
|
* Initialize it to the start of the string.
|
||||||
*
|
*
|
||||||
* Returns: The next character, as unicode codepoint.
|
* Returns: The next character, as unicode codepoint.
|
||||||
*/
|
*/
|
||||||
MF_EXTERN mf_char mf_getchar(mf_str *str);
|
MF_EXTERN mf_char mf_getchar(mf_str *str);
|
||||||
|
@ -5,18 +5,9 @@
|
|||||||
* http://ugfx.io/license.html
|
* http://ugfx.io/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mf_config.h"
|
|
||||||
|
|
||||||
#ifndef MF_NO_COMPILE
|
#ifndef MF_NO_COMPILE
|
||||||
|
|
||||||
#define MF_BWFONT_INTERNALS
|
|
||||||
#define MF_RLEFONT_INTERNALS
|
|
||||||
#define MF_SCALEDFONT_INTERNALS
|
|
||||||
#include "mf_font.h"
|
#include "mf_font.h"
|
||||||
#include "mf_rlefont.h"
|
|
||||||
#include "mf_bwfont.h"
|
|
||||||
#include "mf_scaledfont.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
/* This will be made into a list of included fonts using macro magic. */
|
/* This will be made into a list of included fonts using macro magic. */
|
||||||
@ -32,32 +23,77 @@ gU8 mf_render_character(const struct mf_font_s *font,
|
|||||||
mf_pixel_callback_t callback,
|
mf_pixel_callback_t callback,
|
||||||
void *state)
|
void *state)
|
||||||
{
|
{
|
||||||
gU8 width;
|
uint8_t width;
|
||||||
width = font->render_character(font, x0, y0, MFCHAR2UINT16(character), callback, state);
|
width = font->render_character(font, x0, y0, character, callback, state);
|
||||||
|
|
||||||
if (!width)
|
if (!width)
|
||||||
{
|
{
|
||||||
width = font->render_character(font, x0, y0, font->fallback_character,
|
width = font->render_character(font, x0, y0, font->fallback_character,
|
||||||
callback, state);
|
callback, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
gU8 mf_character_width(const struct mf_font_s *font,
|
uint8_t mf_character_width(const struct mf_font_s *font,
|
||||||
mf_char character)
|
mf_char character)
|
||||||
{
|
{
|
||||||
gU8 width;
|
uint8_t width;
|
||||||
width = font->character_width(font, MFCHAR2UINT16(character));
|
width = font->character_width(font, character);
|
||||||
|
|
||||||
if (!width)
|
if (!width)
|
||||||
{
|
{
|
||||||
width = font->character_width(font, font->fallback_character);
|
width = font->character_width(font, font->fallback_character);
|
||||||
}
|
}
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct whitespace_state
|
||||||
|
{
|
||||||
|
uint8_t min_x, min_y;
|
||||||
|
uint8_t max_x, max_y;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void whitespace_callback(int16_t x, int16_t y, uint8_t count,
|
||||||
|
uint8_t alpha, void *state)
|
||||||
|
{
|
||||||
|
struct whitespace_state *s = state;
|
||||||
|
if (alpha > 7)
|
||||||
|
{
|
||||||
|
if (s->min_x > x) s->min_x = x;
|
||||||
|
if (s->min_y > y) s->min_y = y;
|
||||||
|
x += count - 1;
|
||||||
|
if (s->max_x < x) s->max_x = x;
|
||||||
|
if (s->max_y < y) s->max_y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MF_EXTERN void mf_character_whitespace(const struct mf_font_s *font,
|
||||||
|
mf_char character,
|
||||||
|
uint8_t *left, uint8_t *top,
|
||||||
|
uint8_t *right, uint8_t *bottom)
|
||||||
|
{
|
||||||
|
struct whitespace_state state = {255, 255, 0, 0};
|
||||||
|
mf_render_character(font, 0, 0, character, whitespace_callback, &state);
|
||||||
|
|
||||||
|
if (state.min_x == 255 && state.min_y == 255)
|
||||||
|
{
|
||||||
|
/* Character is whitespace */
|
||||||
|
if (left) *left = font->width;
|
||||||
|
if (top) *top = font->height;
|
||||||
|
if (right) *right = 0;
|
||||||
|
if (bottom) *bottom = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (left) *left = state.min_x;
|
||||||
|
if (top) *top = state.min_y;
|
||||||
|
if (right) *right = font->width - state.max_x - 1;
|
||||||
|
if (bottom) *bottom = font->height - state.max_y - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Avoids a dependency on libc */
|
/* Avoids a dependency on libc */
|
||||||
static bool strequals(const char *a, const char *b)
|
static bool strequals(const char *a, const char *b)
|
||||||
{
|
{
|
||||||
@ -73,7 +109,7 @@ const struct mf_font_s *mf_find_font(const char *name)
|
|||||||
{
|
{
|
||||||
const struct mf_font_list_s *f;
|
const struct mf_font_list_s *f;
|
||||||
f = MF_INCLUDED_FONTS;
|
f = MF_INCLUDED_FONTS;
|
||||||
|
|
||||||
while (f)
|
while (f)
|
||||||
{
|
{
|
||||||
if (strequals(f->font->full_name, name) ||
|
if (strequals(f->font->full_name, name) ||
|
||||||
@ -81,14 +117,14 @@ const struct mf_font_s *mf_find_font(const char *name)
|
|||||||
{
|
{
|
||||||
return f->font;
|
return f->font;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = f->next;
|
f = f->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct mf_font_list_s *mf_get_font_list()
|
const struct mf_font_list_s *mf_get_font_list(void)
|
||||||
{
|
{
|
||||||
return MF_INCLUDED_FONTS;
|
return MF_INCLUDED_FONTS;
|
||||||
}
|
}
|
||||||
|
@ -57,13 +57,13 @@ struct mf_font_s
|
|||||||
|
|
||||||
/* Function to get character width. Should return 0 if character is
|
/* Function to get character width. Should return 0 if character is
|
||||||
* not found. */
|
* not found. */
|
||||||
gU8 (*character_width)(const struct mf_font_s *font, gU16 character);
|
gU8 (*character_width)(const struct mf_font_s *font, mf_char character);
|
||||||
|
|
||||||
/* Function to render a character. Returns the character width or 0 if
|
/* Function to render a character. Returns the character width or 0 if
|
||||||
* character is not found. */
|
* character is not found. */
|
||||||
gU8 (*render_character)(const struct mf_font_s *font,
|
gU8 (*render_character)(const struct mf_font_s *font,
|
||||||
gI16 x0, gI16 y0,
|
gI16 x0, gI16 y0,
|
||||||
gU16 character,
|
mf_char character,
|
||||||
mf_pixel_callback_t callback,
|
mf_pixel_callback_t callback,
|
||||||
void *state);
|
void *state);
|
||||||
};
|
};
|
||||||
@ -101,13 +101,32 @@ MF_EXTERN gU8 mf_render_character(const struct mf_font_s *font,
|
|||||||
* data, but rather the tracking width.
|
* data, but rather the tracking width.
|
||||||
*
|
*
|
||||||
* font: Pointer to the font definition.
|
* font: Pointer to the font definition.
|
||||||
* character: The character code (unicode) to render.
|
* character: The character code (unicode) to check width of.
|
||||||
*
|
*
|
||||||
* Returns width of the character in pixels.
|
* Returns width of the character in pixels.
|
||||||
*/
|
*/
|
||||||
MF_EXTERN gU8 mf_character_width(const struct mf_font_s *font,
|
MF_EXTERN uint8_t mf_character_width(const struct mf_font_s *font,
|
||||||
mf_char character);
|
mf_char character);
|
||||||
|
|
||||||
|
/* Count the amount of white space at the borders of a character.
|
||||||
|
*
|
||||||
|
* E.g. if the font->width and font->height are 10x20, but the character
|
||||||
|
* is only a thin line at the very left edge, this function will return
|
||||||
|
* (0, 0, 9, 0). If the character is fully whitespace, the function will
|
||||||
|
* return (10, 20, 0, 0).
|
||||||
|
*
|
||||||
|
* font: Pointer to the font definition.
|
||||||
|
* character: The character code (unicode) to check white space of.
|
||||||
|
* left: Number of empty rows at left edge. Can be NULL.
|
||||||
|
* top: Number of empty rows at top edge. Can be NULL.
|
||||||
|
* right: Number of empty rows at right edge. Can be NULL.
|
||||||
|
* bottom: Number of empty rows at bottom edge. Can be NULL.
|
||||||
|
*/
|
||||||
|
MF_EXTERN void mf_character_whitespace(const struct mf_font_s *font,
|
||||||
|
mf_char character,
|
||||||
|
uint8_t *left, uint8_t *top,
|
||||||
|
uint8_t *right, uint8_t *bottom);
|
||||||
|
|
||||||
/* Find a font based on name. The name can be either short name or full name.
|
/* Find a font based on name. The name can be either short name or full name.
|
||||||
* Note: You can pass MF_INCLUDED_FONTS to search among all the included .h
|
* Note: You can pass MF_INCLUDED_FONTS to search among all the included .h
|
||||||
* files.
|
* files.
|
||||||
|
@ -18,14 +18,14 @@ static gI16 mf_round_to_tab(const struct mf_font_s *font,
|
|||||||
gI16 tabw, dx;
|
gI16 tabw, dx;
|
||||||
|
|
||||||
tabw = mf_character_width(font, 'm') * MF_TABSIZE;
|
tabw = mf_character_width(font, 'm') * MF_TABSIZE;
|
||||||
|
|
||||||
/* Always atleast 1 space */
|
/* Always atleast 1 space */
|
||||||
x += mf_character_width(font, ' ');
|
x += mf_character_width(font, ' ');
|
||||||
|
|
||||||
/* Round to next tab stop */
|
/* Round to next tab stop */
|
||||||
dx = x - x0 + font->baseline_x;
|
dx = x - x0 + font->baseline_x;
|
||||||
x += tabw - (dx % tabw);
|
x += tabw - (dx % tabw);
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,14 +36,14 @@ static gI16 mf_round_to_prev_tab(const struct mf_font_s *font,
|
|||||||
gI16 tabw, dx;
|
gI16 tabw, dx;
|
||||||
|
|
||||||
tabw = mf_character_width(font, 'm') * MF_TABSIZE;
|
tabw = mf_character_width(font, 'm') * MF_TABSIZE;
|
||||||
|
|
||||||
/* Always atleast 1 space */
|
/* Always atleast 1 space */
|
||||||
x -= mf_character_width(font, ' ');
|
x -= mf_character_width(font, ' ');
|
||||||
|
|
||||||
/* Round to previous tab stop */
|
/* Round to previous tab stop */
|
||||||
dx = x0 - x + font->baseline_x;
|
dx = x0 - x + font->baseline_x;
|
||||||
x -= tabw - (dx % tabw);
|
x -= tabw - (dx % tabw);
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -56,7 +56,7 @@ gI16 mf_get_string_width(const struct mf_font_s *font, mf_str text,
|
|||||||
|
|
||||||
if (!count)
|
if (!count)
|
||||||
count = 0xFFFF;
|
count = 0xFFFF;
|
||||||
|
|
||||||
while (count-- && *text)
|
while (count-- && *text)
|
||||||
{
|
{
|
||||||
c2 = mf_getchar(&text);
|
c2 = mf_getchar(&text);
|
||||||
@ -71,14 +71,14 @@ gI16 mf_get_string_width(const struct mf_font_s *font, mf_str text,
|
|||||||
c2 = ' ';
|
c2 = ' ';
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kern && c1 != 0)
|
if (kern && c1 != 0)
|
||||||
result += mf_compute_kerning(font, c1, c2);
|
result += mf_compute_kerning(font, c1, c2);
|
||||||
|
|
||||||
result += mf_character_width(font, c2);
|
result += mf_character_width(font, c2);
|
||||||
c1 = c2;
|
c1 = c2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,10 +87,10 @@ static gU16 strip_spaces(mf_str text, gU16 count, mf_char *last_char)
|
|||||||
{
|
{
|
||||||
gU16 i = 0, result = 0;
|
gU16 i = 0, result = 0;
|
||||||
mf_char tmp = 0;
|
mf_char tmp = 0;
|
||||||
|
|
||||||
if (!count)
|
if (!count)
|
||||||
count = 0xFFFF;
|
count = 0xFFFF;
|
||||||
|
|
||||||
while (count-- && *text)
|
while (count-- && *text)
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
@ -101,7 +101,7 @@ static gU16 strip_spaces(mf_str text, gU16 count, mf_char *last_char)
|
|||||||
result = i;
|
result = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_char)
|
if (last_char)
|
||||||
{
|
{
|
||||||
if (!*text)
|
if (!*text)
|
||||||
@ -109,7 +109,7 @@ static gU16 strip_spaces(mf_str text, gU16 count, mf_char *last_char)
|
|||||||
else
|
else
|
||||||
*last_char = tmp;
|
*last_char = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,12 +122,12 @@ static void render_left(const struct mf_font_s *font,
|
|||||||
{
|
{
|
||||||
gI16 x;
|
gI16 x;
|
||||||
mf_char c1 = 0, c2;
|
mf_char c1 = 0, c2;
|
||||||
|
|
||||||
x = x0 - font->baseline_x;
|
x = x0 - font->baseline_x;
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
c2 = mf_getchar(&text);
|
c2 = mf_getchar(&text);
|
||||||
|
|
||||||
if (c2 == '\t')
|
if (c2 == '\t')
|
||||||
{
|
{
|
||||||
#if MF_USE_TABS
|
#if MF_USE_TABS
|
||||||
@ -138,7 +138,7 @@ static void render_left(const struct mf_font_s *font,
|
|||||||
c2 = ' ';
|
c2 = ' ';
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c1 != 0)
|
if (c1 != 0)
|
||||||
x += mf_compute_kerning(font, c1, c2);
|
x += mf_compute_kerning(font, c1, c2);
|
||||||
|
|
||||||
@ -174,18 +174,18 @@ static void render_right(const struct mf_font_s *font,
|
|||||||
gU16 i;
|
gU16 i;
|
||||||
mf_char c1, c2 = 0;
|
mf_char c1, c2 = 0;
|
||||||
mf_str tmp;
|
mf_str tmp;
|
||||||
|
|
||||||
/* Go to the end of the line. */
|
/* Go to the end of the line. */
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
mf_getchar(&text);
|
mf_getchar(&text);
|
||||||
|
|
||||||
x = x0 - font->baseline_x;
|
x = x0 - font->baseline_x;
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
mf_rewind(&text);
|
mf_rewind(&text);
|
||||||
tmp = text;
|
tmp = text;
|
||||||
c1 = mf_getchar(&tmp);
|
c1 = mf_getchar(&tmp);
|
||||||
|
|
||||||
/* Perform tab alignment */
|
/* Perform tab alignment */
|
||||||
if (c1 == '\t')
|
if (c1 == '\t')
|
||||||
{
|
{
|
||||||
@ -197,14 +197,14 @@ static void render_right(const struct mf_font_s *font,
|
|||||||
c1 = ' ';
|
c1 = ' ';
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply the nominal character width */
|
/* Apply the nominal character width */
|
||||||
x -= mf_character_width(font, c1);
|
x -= mf_character_width(font, c1);
|
||||||
|
|
||||||
/* Apply kerning */
|
/* Apply kerning */
|
||||||
if (c2 != 0)
|
if (c2 != 0)
|
||||||
x -= mf_compute_kerning(font, c1, c2);
|
x -= mf_compute_kerning(font, c1, c2);
|
||||||
|
|
||||||
callback(x, y0, c1, state);
|
callback(x, y0, c1, state);
|
||||||
c2 = c1;
|
c2 = c1;
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ void mf_render_aligned(const struct mf_font_s *font,
|
|||||||
{
|
{
|
||||||
gI16 string_width;
|
gI16 string_width;
|
||||||
count = strip_spaces(text, count, 0);
|
count = strip_spaces(text, count, 0);
|
||||||
|
|
||||||
if (align == MF_ALIGN_LEFT)
|
if (align == MF_ALIGN_LEFT)
|
||||||
{
|
{
|
||||||
render_left(font, x0, y0, text, count, callback, state);
|
render_left(font, x0, y0, text, count, callback, state);
|
||||||
@ -247,7 +247,6 @@ void mf_render_justified(const struct mf_font_s *font,
|
|||||||
mf_character_callback_t callback,
|
mf_character_callback_t callback,
|
||||||
void *state)
|
void *state)
|
||||||
{
|
{
|
||||||
(void) width;
|
|
||||||
mf_render_aligned(font, x0, y0, MF_ALIGN_LEFT, text, count, callback, state);
|
mf_render_aligned(font, x0, y0, MF_ALIGN_LEFT, text, count, callback, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,20 +280,20 @@ void mf_render_justified(const struct mf_font_s *font,
|
|||||||
gI16 string_width, adjustment;
|
gI16 string_width, adjustment;
|
||||||
gU16 num_spaces;
|
gU16 num_spaces;
|
||||||
mf_char last_char;
|
mf_char last_char;
|
||||||
|
|
||||||
count = strip_spaces(text, count, &last_char);
|
count = strip_spaces(text, count, &last_char);
|
||||||
|
|
||||||
if (last_char == '\n' || last_char == 0)
|
if (last_char == '\n' || last_char == 0)
|
||||||
{
|
{
|
||||||
/* Line ends in linefeed, do not justify. */
|
/* Line ends in linefeed, do not justify. */
|
||||||
render_left(font, x0, y0, text, count, callback, state);
|
render_left(font, x0, y0, text, count, callback, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string_width = mf_get_string_width(font, text, count, false);
|
string_width = mf_get_string_width(font, text, count, false);
|
||||||
adjustment = width - string_width;
|
adjustment = width - string_width;
|
||||||
num_spaces = count_spaces(text, count);
|
num_spaces = count_spaces(text, count);
|
||||||
|
|
||||||
{
|
{
|
||||||
gI16 x, tmp;
|
gI16 x, tmp;
|
||||||
mf_char c1 = 0, c2;
|
mf_char c1 = 0, c2;
|
||||||
@ -303,7 +302,7 @@ void mf_render_justified(const struct mf_font_s *font,
|
|||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
c2 = mf_getchar(&text);
|
c2 = mf_getchar(&text);
|
||||||
|
|
||||||
if (c2 == '\t')
|
if (c2 == '\t')
|
||||||
{
|
{
|
||||||
#if MF_USE_TABS
|
#if MF_USE_TABS
|
||||||
@ -316,7 +315,7 @@ void mf_render_justified(const struct mf_font_s *font,
|
|||||||
c2 = ' ';
|
c2 = ' ';
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_justify_space(c2))
|
if (is_justify_space(c2))
|
||||||
{
|
{
|
||||||
tmp = (adjustment + num_spaces / 2) / num_spaces;
|
tmp = (adjustment + num_spaces / 2) / num_spaces;
|
||||||
@ -324,7 +323,7 @@ void mf_render_justified(const struct mf_font_s *font,
|
|||||||
num_spaces--;
|
num_spaces--;
|
||||||
x += tmp;
|
x += tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c1 != 0)
|
if (c1 != 0)
|
||||||
{
|
{
|
||||||
tmp = mf_compute_kerning(font, c1, c2);
|
tmp = mf_compute_kerning(font, c1, c2);
|
||||||
|
@ -40,7 +40,7 @@ static void fit_rightedge(gI16 x, gI16 y, gU8 count, gU8 alpha,
|
|||||||
void *state)
|
void *state)
|
||||||
{
|
{
|
||||||
struct kerning_state_s *s = state;
|
struct kerning_state_s *s = state;
|
||||||
|
|
||||||
if (alpha > 7)
|
if (alpha > 7)
|
||||||
{
|
{
|
||||||
gU8 zone = y / s->zoneheight;
|
gU8 zone = y / s->zoneheight;
|
||||||
@ -56,12 +56,12 @@ static bool do_kerning(mf_char c)
|
|||||||
/* Just a speed optimization, spaces would be ignored anyway. */
|
/* Just a speed optimization, spaces would be ignored anyway. */
|
||||||
if (c == ' ' || c == '\n' || c == '\r' || c == '\t')
|
if (c == ' ' || c == '\n' || c == '\r' || c == '\t')
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Do not kern against digits, in order to keep values in tables nicely
|
/* Do not kern against digits, in order to keep values in tables nicely
|
||||||
* aligned. Most fonts have constant width for digits. */
|
* aligned. Most fonts have constant width for digits. */
|
||||||
if (c >= '0' && c <= '9')
|
if (c >= '0' && c <= '9')
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,14 +78,14 @@ gI8 mf_compute_kerning(const struct mf_font_s *font,
|
|||||||
|
|
||||||
if (font->flags & MF_FONT_FLAG_MONOSPACE)
|
if (font->flags & MF_FONT_FLAG_MONOSPACE)
|
||||||
return 0; /* No kerning for monospace fonts */
|
return 0; /* No kerning for monospace fonts */
|
||||||
|
|
||||||
if (!do_kerning(c1) || !do_kerning(c2))
|
if (!do_kerning(c1) || !do_kerning(c2))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Compute the height of one kerning zone in pixels */
|
/* Compute the height of one kerning zone in pixels */
|
||||||
i = (font->height + MF_KERNING_ZONES - 1) / MF_KERNING_ZONES;
|
i = (font->height + MF_KERNING_ZONES - 1) / MF_KERNING_ZONES;
|
||||||
if (i < 1) i = 1;
|
if (i < 1) i = 1;
|
||||||
|
|
||||||
/* Initialize structures */
|
/* Initialize structures */
|
||||||
leftedge.zoneheight = rightedge.zoneheight = i;
|
leftedge.zoneheight = rightedge.zoneheight = i;
|
||||||
for (i = 0; i < MF_KERNING_ZONES; i++)
|
for (i = 0; i < MF_KERNING_ZONES; i++)
|
||||||
@ -93,11 +93,11 @@ gI8 mf_compute_kerning(const struct mf_font_s *font,
|
|||||||
leftedge.edgepos[i] = 255;
|
leftedge.edgepos[i] = 255;
|
||||||
rightedge.edgepos[i] = 0;
|
rightedge.edgepos[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Analyze the edges of both glyphs. */
|
/* Analyze the edges of both glyphs. */
|
||||||
w1 = mf_render_character(font, 0, 0, c1, fit_rightedge, &rightedge);
|
w1 = mf_render_character(font, 0, 0, c1, fit_rightedge, &rightedge);
|
||||||
w2 = mf_render_character(font, 0, 0, c2, fit_leftedge, &leftedge);
|
w2 = mf_render_character(font, 0, 0, c2, fit_leftedge, &leftedge);
|
||||||
|
|
||||||
/* Find the minimum horizontal space between the glyphs. */
|
/* Find the minimum horizontal space between the glyphs. */
|
||||||
min_space = 255;
|
min_space = 255;
|
||||||
for (i = 0; i < MF_KERNING_ZONES; i++)
|
for (i = 0; i < MF_KERNING_ZONES; i++)
|
||||||
@ -105,24 +105,24 @@ gI8 mf_compute_kerning(const struct mf_font_s *font,
|
|||||||
gU8 space;
|
gU8 space;
|
||||||
if (leftedge.edgepos[i] == 255 || rightedge.edgepos[i] == 0)
|
if (leftedge.edgepos[i] == 255 || rightedge.edgepos[i] == 0)
|
||||||
continue; /* Outside glyph area. */
|
continue; /* Outside glyph area. */
|
||||||
|
|
||||||
space = w1 - rightedge.edgepos[i] + leftedge.edgepos[i];
|
space = w1 - rightedge.edgepos[i] + leftedge.edgepos[i];
|
||||||
if (space < min_space)
|
if (space < min_space)
|
||||||
min_space = space;
|
min_space = space;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min_space == 255)
|
if (min_space == 255)
|
||||||
return 0; /* One of the characters is space, or both are punctuation. */
|
return 0; /* One of the characters is space, or both are punctuation. */
|
||||||
|
|
||||||
/* Compute the adjustment of the glyph position. */
|
/* Compute the adjustment of the glyph position. */
|
||||||
normal_space = avg16(w1, w2) * MF_KERNING_SPACE_PERCENT / 100;
|
normal_space = avg16(w1, w2) * MF_KERNING_SPACE_PERCENT / 100;
|
||||||
normal_space += MF_KERNING_SPACE_PIXELS;
|
normal_space += MF_KERNING_SPACE_PIXELS;
|
||||||
adjust = normal_space - min_space;
|
adjust = normal_space - min_space;
|
||||||
max_adjust = -max16(w1, w2) * MF_KERNING_LIMIT / 100;
|
max_adjust = -max16(w1, w2) * MF_KERNING_LIMIT / 100;
|
||||||
|
|
||||||
if (adjust > 0) adjust = 0;
|
if (adjust > 0) adjust = 0;
|
||||||
if (adjust < max_adjust) adjust = max_adjust;
|
if (adjust < max_adjust) adjust = max_adjust;
|
||||||
|
|
||||||
return adjust;
|
return adjust;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,18 +17,18 @@
|
|||||||
#include "mf_rlefont.h"
|
#include "mf_rlefont.h"
|
||||||
|
|
||||||
/* Compute the kerning adjustment when c1 is followed by c2.
|
/* Compute the kerning adjustment when c1 is followed by c2.
|
||||||
*
|
*
|
||||||
* font: Pointer to the font definition.
|
* font: Pointer to the font definition.
|
||||||
* c1: The previous character.
|
* c1: The previous character.
|
||||||
* c2: The next character to render.
|
* c2: The next character to render.
|
||||||
*
|
*
|
||||||
* Returns the offset to add to the x position for c2.
|
* Returns the offset to add to the x position for c2.
|
||||||
*/
|
*/
|
||||||
#if MF_USE_KERNING
|
#if MF_USE_KERNING
|
||||||
MF_EXTERN gI8 mf_compute_kerning(const struct mf_font_s *font,
|
MF_EXTERN gI8 mf_compute_kerning(const struct mf_font_s *font,
|
||||||
mf_char c1, mf_char c2);
|
mf_char c1, mf_char c2);
|
||||||
#else
|
#else
|
||||||
#define mf_compute_kerning(font, c1, c2) 0
|
#define mf_compute_kerning(f,c1,c2) (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,7 +46,7 @@ static const gU8 *find_glyph(const struct mf_rlefont_s *font,
|
|||||||
index = character - range->first_char;
|
index = character - range->first_char;
|
||||||
if (character >= range->first_char && index < range->char_count)
|
if (character >= range->first_char && index < range->char_count)
|
||||||
{
|
{
|
||||||
unsigned offset = range->glyph_offsets[index];
|
uint16_t offset = pgm_read_word(range->glyph_offsets + index);
|
||||||
return &range->glyph_data[offset];
|
return &range->glyph_data[offset];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ static void write_pixels(struct renderstate_r *rstate, gU16 count,
|
|||||||
gU8 rowlen;
|
gU8 rowlen;
|
||||||
|
|
||||||
/* Write row-by-row if the run spans multiple rows. */
|
/* Write row-by-row if the run spans multiple rows. */
|
||||||
while (rstate->x + count >= rstate->x_end)
|
while ((int32_t)rstate->x + count >= rstate->x_end)
|
||||||
{
|
{
|
||||||
rowlen = rstate->x_end - rstate->x;
|
rowlen = rstate->x_end - rstate->x;
|
||||||
rstate->callback(rstate->x, rstate->y, rowlen, alpha, rstate->state);
|
rstate->callback(rstate->x, rstate->y, rowlen, alpha, rstate->state);
|
||||||
@ -83,7 +83,7 @@ static void write_pixels(struct renderstate_r *rstate, gU16 count,
|
|||||||
rstate->x = rstate->x_begin;
|
rstate->x = rstate->x_begin;
|
||||||
rstate->y++;
|
rstate->y++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the remaining part */
|
/* Write the remaining part */
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
@ -108,13 +108,13 @@ static void write_rle_dictentry(const struct mf_rlefont_s *font,
|
|||||||
struct renderstate_r *rstate,
|
struct renderstate_r *rstate,
|
||||||
gU8 index)
|
gU8 index)
|
||||||
{
|
{
|
||||||
gU16 offset = font->dictionary_offsets[index];
|
uint16_t offset = pgm_read_word(font->dictionary_offsets + index);
|
||||||
gU16 length = font->dictionary_offsets[index + 1] - offset;
|
uint16_t length = pgm_read_word(font->dictionary_offsets + index + 1) - offset;
|
||||||
gU16 i;
|
uint16_t i;
|
||||||
|
|
||||||
for (i = 0; i < length; i++)
|
for (i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
gU8 code = font->dictionary_data[offset + i];
|
uint8_t code = pgm_read_byte(font->dictionary_data + offset + i);
|
||||||
if ((code & RLE_CODEMASK) == RLE_ZEROS)
|
if ((code & RLE_CODEMASK) == RLE_ZEROS)
|
||||||
{
|
{
|
||||||
skip_pixels(rstate, code & RLE_VALMASK);
|
skip_pixels(rstate, code & RLE_VALMASK);
|
||||||
@ -159,31 +159,31 @@ static void write_bin_codeword(const struct mf_rlefont_s *font,
|
|||||||
struct renderstate_r *rstate,
|
struct renderstate_r *rstate,
|
||||||
gU8 code)
|
gU8 code)
|
||||||
{
|
{
|
||||||
gU8 bitcount = fillentry_bitcount(code);
|
(void)font;
|
||||||
gU8 byte = code - DICT_START7BIT;
|
uint8_t bitcount = fillentry_bitcount(code);
|
||||||
gU8 runlen = 0;
|
uint8_t byte = code - DICT_START7BIT;
|
||||||
(void) font;
|
uint8_t runlen = 0;
|
||||||
|
|
||||||
while (bitcount--)
|
while (bitcount--)
|
||||||
{
|
{
|
||||||
if (byte & 1)
|
if (byte & 1)
|
||||||
{
|
{
|
||||||
runlen++;
|
runlen++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (runlen)
|
if (runlen)
|
||||||
{
|
{
|
||||||
write_pixels(rstate, runlen, 255);
|
write_pixels(rstate, runlen, 255);
|
||||||
runlen = 0;
|
runlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_pixels(rstate, 1);
|
skip_pixels(rstate, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte >>= 1;
|
byte >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runlen)
|
if (runlen)
|
||||||
write_pixels(rstate, runlen, 255);
|
write_pixels(rstate, runlen, 255);
|
||||||
}
|
}
|
||||||
@ -191,9 +191,13 @@ static void write_bin_codeword(const struct mf_rlefont_s *font,
|
|||||||
/* Decode and write out a reference codeword */
|
/* Decode and write out a reference codeword */
|
||||||
static void write_ref_codeword(const struct mf_rlefont_s *font,
|
static void write_ref_codeword(const struct mf_rlefont_s *font,
|
||||||
struct renderstate_r *rstate,
|
struct renderstate_r *rstate,
|
||||||
gU8 code)
|
uint8_t code)
|
||||||
{
|
{
|
||||||
if (code <= 15)
|
if (code == 0)
|
||||||
|
{
|
||||||
|
skip_pixels(rstate, 1);
|
||||||
|
}
|
||||||
|
else if (code <= 15)
|
||||||
{
|
{
|
||||||
write_pixels(rstate, 1, 0x11 * code);
|
write_pixels(rstate, 1, 0x11 * code);
|
||||||
}
|
}
|
||||||
@ -219,15 +223,15 @@ static void write_ref_codeword(const struct mf_rlefont_s *font,
|
|||||||
/* Decode and write out a reference encoded dictionary entry. */
|
/* Decode and write out a reference encoded dictionary entry. */
|
||||||
static void write_ref_dictentry(const struct mf_rlefont_s *font,
|
static void write_ref_dictentry(const struct mf_rlefont_s *font,
|
||||||
struct renderstate_r *rstate,
|
struct renderstate_r *rstate,
|
||||||
gU8 index)
|
uint8_t index)
|
||||||
{
|
{
|
||||||
gU16 offset = font->dictionary_offsets[index];
|
uint16_t offset = pgm_read_word(font->dictionary_offsets + index);
|
||||||
gU16 length = font->dictionary_offsets[index + 1] - offset;
|
uint16_t length = pgm_read_word(font->dictionary_offsets + index + 1) - offset;
|
||||||
gU16 i;
|
uint16_t i;
|
||||||
|
|
||||||
for (i = 0; i < length; i++)
|
for (i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
gU8 code = font->dictionary_data[offset + i];
|
uint8_t code = pgm_read_byte(font->dictionary_data + offset + i);
|
||||||
write_ref_codeword(font, rstate, code);
|
write_ref_codeword(font, rstate, code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -235,7 +239,7 @@ static void write_ref_dictentry(const struct mf_rlefont_s *font,
|
|||||||
/* Decode and write out an arbitrary glyph codeword */
|
/* Decode and write out an arbitrary glyph codeword */
|
||||||
static void write_glyph_codeword(const struct mf_rlefont_s *font,
|
static void write_glyph_codeword(const struct mf_rlefont_s *font,
|
||||||
struct renderstate_r *rstate,
|
struct renderstate_r *rstate,
|
||||||
gU8 code)
|
uint8_t code)
|
||||||
{
|
{
|
||||||
if (code >= DICT_START + font->rle_entry_count &&
|
if (code >= DICT_START + font->rle_entry_count &&
|
||||||
code < DICT_START + font->dict_entry_count)
|
code < DICT_START + font->dict_entry_count)
|
||||||
@ -249,15 +253,15 @@ static void write_glyph_codeword(const struct mf_rlefont_s *font,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gU8 mf_rlefont_render_character(const struct mf_font_s *font,
|
uint8_t mf_rlefont_render_character(const struct mf_font_s *font,
|
||||||
gI16 x0, gI16 y0,
|
int16_t x0, int16_t y0,
|
||||||
gU16 character,
|
uint16_t character,
|
||||||
mf_pixel_callback_t callback,
|
mf_pixel_callback_t callback,
|
||||||
void *state)
|
void *state)
|
||||||
{
|
{
|
||||||
const gU8 *p;
|
const uint8_t *p;
|
||||||
gU8 width;
|
uint8_t width;
|
||||||
|
|
||||||
struct renderstate_r rstate;
|
struct renderstate_r rstate;
|
||||||
rstate.x_begin = x0;
|
rstate.x_begin = x0;
|
||||||
rstate.x_end = x0 + font->width;
|
rstate.x_end = x0 + font->width;
|
||||||
@ -266,29 +270,28 @@ gU8 mf_rlefont_render_character(const struct mf_font_s *font,
|
|||||||
rstate.y_end = y0 + font->height;
|
rstate.y_end = y0 + font->height;
|
||||||
rstate.callback = callback;
|
rstate.callback = callback;
|
||||||
rstate.state = state;
|
rstate.state = state;
|
||||||
|
|
||||||
p = find_glyph((struct mf_rlefont_s*)font, character);
|
|
||||||
if (!p)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
width = *p++;
|
|
||||||
while (rstate.y < rstate.y_end)
|
|
||||||
{
|
|
||||||
write_glyph_codeword((struct mf_rlefont_s*)font, &rstate, *p++);
|
|
||||||
}
|
|
||||||
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
gU8 mf_rlefont_character_width(const struct mf_font_s *font,
|
|
||||||
gU16 character)
|
|
||||||
{
|
|
||||||
const gU8 *p;
|
|
||||||
p = find_glyph((struct mf_rlefont_s*)font, character);
|
p = find_glyph((struct mf_rlefont_s*)font, character);
|
||||||
if (!p)
|
if (!p)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return *p;
|
width = pgm_read_byte(p++);
|
||||||
|
while (rstate.y < rstate.y_end)
|
||||||
|
{
|
||||||
|
write_glyph_codeword((struct mf_rlefont_s*)font, &rstate, pgm_read_byte(p++));
|
||||||
|
}
|
||||||
|
|
||||||
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t mf_rlefont_character_width(const struct mf_font_s *font,
|
||||||
|
uint16_t character)
|
||||||
|
{
|
||||||
|
const uint8_t *p;
|
||||||
|
p = find_glyph((struct mf_rlefont_s*)font, character);
|
||||||
|
if (!p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
#endif //MF_NO_COMPILE
|
#endif //MF_NO_COMPILE
|
||||||
|
return pgm_read_byte(p);
|
||||||
|
}
|
||||||
|
@ -39,7 +39,7 @@ struct mf_rlefont_char_range_s
|
|||||||
struct mf_rlefont_s
|
struct mf_rlefont_s
|
||||||
{
|
{
|
||||||
struct mf_font_s font;
|
struct mf_font_s font;
|
||||||
|
|
||||||
/* Version of the font definition used. */
|
/* Version of the font definition used. */
|
||||||
const gU8 version;
|
const gU8 version;
|
||||||
|
|
||||||
|
@ -28,27 +28,27 @@ static void scaled_pixel_callback(gI16 x, gI16 y, gU8 count,
|
|||||||
count *= rstate->x_scale;
|
count *= rstate->x_scale;
|
||||||
x = rstate->x0 + x * rstate->x_scale;
|
x = rstate->x0 + x * rstate->x_scale;
|
||||||
y = rstate->y0 + y * rstate->y_scale;
|
y = rstate->y0 + y * rstate->y_scale;
|
||||||
|
|
||||||
for (dy = 0; dy < rstate->y_scale; dy++)
|
for (dy = 0; dy < rstate->y_scale; dy++)
|
||||||
{
|
{
|
||||||
rstate->orig_callback(x, y + dy, count, alpha, rstate->orig_state);
|
rstate->orig_callback(x, y + dy, count, alpha, rstate->orig_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gU8 mf_scaled_character_width(const struct mf_font_s *font,
|
static gU8 scaled_character_width(const struct mf_font_s *font,
|
||||||
gU16 character)
|
mf_char character)
|
||||||
{
|
{
|
||||||
struct mf_scaledfont_s *sfont = (struct mf_scaledfont_s*)font;
|
struct mf_scaledfont_s *sfont = (struct mf_scaledfont_s*)font;
|
||||||
gU8 basewidth;
|
gU8 basewidth;
|
||||||
|
|
||||||
basewidth = sfont->basefont->character_width(sfont->basefont, character);
|
basewidth = sfont->basefont->character_width(sfont->basefont, character);
|
||||||
|
|
||||||
return sfont->x_scale * basewidth;
|
return sfont->x_scale * basewidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
gU8 mf_scaled_render_character(const struct mf_font_s *font,
|
static gU8 scaled_render_character(const struct mf_font_s *font,
|
||||||
gI16 x0, gI16 y0,
|
int16_t x0, int16_t y0,
|
||||||
gU16 character,
|
mf_char character,
|
||||||
mf_pixel_callback_t callback,
|
mf_pixel_callback_t callback,
|
||||||
void *state)
|
void *state)
|
||||||
{
|
{
|
||||||
@ -62,10 +62,10 @@ gU8 mf_scaled_render_character(const struct mf_font_s *font,
|
|||||||
rstate.y_scale = sfont->y_scale;
|
rstate.y_scale = sfont->y_scale;
|
||||||
rstate.x0 = x0;
|
rstate.x0 = x0;
|
||||||
rstate.y0 = y0;
|
rstate.y0 = y0;
|
||||||
|
|
||||||
basewidth = sfont->basefont->render_character(sfont->basefont, 0, 0,
|
basewidth = sfont->basefont->render_character(sfont->basefont, 0, 0,
|
||||||
character, scaled_pixel_callback, &rstate);
|
character, scaled_pixel_callback, &rstate);
|
||||||
|
|
||||||
return sfont->x_scale * basewidth;
|
return sfont->x_scale * basewidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ void mf_scale_font(struct mf_scaledfont_s *newfont,
|
|||||||
{
|
{
|
||||||
newfont->font = *basefont;
|
newfont->font = *basefont;
|
||||||
newfont->basefont = basefont;
|
newfont->basefont = basefont;
|
||||||
|
|
||||||
newfont->font.width *= x_scale;
|
newfont->font.width *= x_scale;
|
||||||
newfont->font.height *= y_scale;
|
newfont->font.height *= y_scale;
|
||||||
newfont->font.baseline_x *= x_scale;
|
newfont->font.baseline_x *= x_scale;
|
||||||
@ -83,9 +83,9 @@ void mf_scale_font(struct mf_scaledfont_s *newfont,
|
|||||||
newfont->font.min_x_advance *= x_scale;
|
newfont->font.min_x_advance *= x_scale;
|
||||||
newfont->font.max_x_advance *= x_scale;
|
newfont->font.max_x_advance *= x_scale;
|
||||||
newfont->font.line_height *= y_scale;
|
newfont->font.line_height *= y_scale;
|
||||||
newfont->font.character_width = &mf_scaled_character_width;
|
newfont->font.character_width = &scaled_character_width;
|
||||||
newfont->font.render_character = &mf_scaled_render_character;
|
newfont->font.render_character = &scaled_render_character;
|
||||||
|
|
||||||
newfont->x_scale = x_scale;
|
newfont->x_scale = x_scale;
|
||||||
newfont->y_scale = y_scale;
|
newfont->y_scale = y_scale;
|
||||||
}
|
}
|
||||||
|
@ -17,26 +17,14 @@
|
|||||||
struct mf_scaledfont_s
|
struct mf_scaledfont_s
|
||||||
{
|
{
|
||||||
struct mf_font_s font;
|
struct mf_font_s font;
|
||||||
|
|
||||||
const struct mf_font_s *basefont;
|
const struct mf_font_s *basefont;
|
||||||
gU8 x_scale;
|
uint8_t x_scale;
|
||||||
gU8 y_scale;
|
uint8_t y_scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
MF_EXTERN void mf_scale_font(struct mf_scaledfont_s *newfont,
|
MF_EXTERN void mf_scale_font(struct mf_scaledfont_s *newfont,
|
||||||
const struct mf_font_s *basefont,
|
const struct mf_font_s *basefont,
|
||||||
gU8 x_scale, gU8 y_scale);
|
gU8 x_scale, gU8 y_scale);
|
||||||
|
|
||||||
#ifdef MF_SCALEDFONT_INTERNALS
|
|
||||||
/* Internal functions, don't use these directly. */
|
|
||||||
MF_EXTERN gU8 mf_scaled_render_character(const struct mf_font_s *font,
|
|
||||||
gI16 x0, gI16 y0,
|
|
||||||
gU16 character,
|
|
||||||
mf_pixel_callback_t callback,
|
|
||||||
void *state);
|
|
||||||
|
|
||||||
MF_EXTERN gU8 mf_scaled_character_width(const struct mf_font_s *font,
|
|
||||||
gU16 character);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,7 +43,7 @@ static bool get_wordlen(const struct mf_font_s *font, mf_str *text,
|
|||||||
result->chars++;
|
result->chars++;
|
||||||
result->word += mf_character_width(font, c);
|
result->word += mf_character_width(font, c);
|
||||||
|
|
||||||
prev = *text;
|
prev = *text;
|
||||||
c = mf_getchar(text);
|
c = mf_getchar(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,10 +56,10 @@ static bool get_wordlen(const struct mf_font_s *font, mf_str *text,
|
|||||||
else if (c == '\t')
|
else if (c == '\t')
|
||||||
result->space += mf_character_width(font, 'm') * MF_TABSIZE;
|
result->space += mf_character_width(font, 'm') * MF_TABSIZE;
|
||||||
else if (c == '\n') {
|
else if (c == '\n') {
|
||||||
/* Special case for newlines, skip the character then break. */
|
/* Special case for newlines, skip the character then break. */
|
||||||
prev = *text;
|
prev = *text;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = *text;
|
prev = *text;
|
||||||
c = mf_getchar(text);
|
c = mf_getchar(text);
|
||||||
@ -239,6 +239,7 @@ void mf_wordwrap(const struct mf_font_s *font, gI16 width,
|
|||||||
void mf_wordwrap(const struct mf_font_s *font, gI16 width,
|
void mf_wordwrap(const struct mf_font_s *font, gI16 width,
|
||||||
mf_str text, mf_line_callback_t callback, void *state)
|
mf_str text, mf_line_callback_t callback, void *state)
|
||||||
{
|
{
|
||||||
|
mf_str orig = text;
|
||||||
mf_str linestart;
|
mf_str linestart;
|
||||||
|
|
||||||
/* Current line width and character count */
|
/* Current line width and character count */
|
||||||
|
@ -20,14 +20,14 @@
|
|||||||
* line: Pointer to the beginning of the string for this line.
|
* line: Pointer to the beginning of the string for this line.
|
||||||
* count: Number of characters on the line.
|
* count: Number of characters on the line.
|
||||||
* state: Free variable that was passed to wordwrap().
|
* state: Free variable that was passed to wordwrap().
|
||||||
*
|
*
|
||||||
* Returns: true to continue, false to stop after this line.
|
* Returns: true to continue, false to stop after this line.
|
||||||
*/
|
*/
|
||||||
typedef bool (*mf_line_callback_t) (mf_str line, gU16 count,
|
typedef bool (*mf_line_callback_t) (mf_str line, gU16 count,
|
||||||
void *state);
|
void *state);
|
||||||
|
|
||||||
/* Word wrap a piece of text. Calls the callback function for each line.
|
/* Word wrap a piece of text. Calls the callback function for each line.
|
||||||
*
|
*
|
||||||
* font: Font to use for metrics.
|
* font: Font to use for metrics.
|
||||||
* width: Maximum line width in pixels.
|
* width: Maximum line width in pixels.
|
||||||
* text: Pointer to the start of the text to process.
|
* text: Pointer to the start of the text to process.
|
||||||
@ -35,5 +35,5 @@ typedef bool (*mf_line_callback_t) (mf_str line, gU16 count,
|
|||||||
*/
|
*/
|
||||||
MF_EXTERN void mf_wordwrap(const struct mf_font_s *font, gI16 width,
|
MF_EXTERN void mf_wordwrap(const struct mf_font_s *font, gI16 width,
|
||||||
mf_str text, mf_line_callback_t callback, void *state);
|
mf_str text, mf_line_callback_t callback, void *state);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user