Implement optional font rendering options

The user can now choose antialiasing grayscale and subpixel and hinting
non, slight or full.
This commit is contained in:
Francesco Abbate 2020-12-04 16:15:54 +01:00
parent 549ac806e9
commit afda299fe4
4 changed files with 73 additions and 5 deletions

View File

@ -7,9 +7,23 @@ style.scrollbar_size = common.round(4 * SCALE)
style.caret_width = common.round(2 * SCALE)
style.tab_width = common.round(170 * SCALE)
-- The function renderer.font.load can accept an option table as a second optional argument.
-- It shoud be like the following:
--
-- {antialiasing= "grayscale", hinting = "full"}
--
-- The possible values for each option are:
-- - for antialiang: grayscale, subpixel
-- - for hinting: none, slight, full
--
-- The defaults values are antialiang subpixel and hinting slight for optimal visualization
-- on ordinary LCD monitor with RGB patterns.
--
-- On High DPI monitor or non RGB monitor you may consider using antialiang grayscale instead.
-- The antialising grayscale with full hinting is interesting for crisp font rendering.
style.font = renderer.font.load(DATADIR .. "/fonts/font.ttf", 14 * SCALE)
style.big_font = renderer.font.load(DATADIR .. "/fonts/font.ttf", 34 * SCALE)
style.icon_font = renderer.font.load(DATADIR .. "/fonts/icons.ttf", 14 * SCALE)
style.icon_font = renderer.font.load(DATADIR .. "/fonts/icons.ttf", 14 * SCALE, {antialiasing="grayscale", hinting="full"})
style.code_font = renderer.font.load(DATADIR .. "/fonts/monospace.ttf", 13.5 * SCALE)
style.background = { common.color "#2e2e32" }

View File

@ -6,9 +6,43 @@
static int f_load(lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
float size = luaL_checknumber(L, 2);
unsigned int font_options = 0;
if (lua_gettop(L) > 2 && lua_istable(L, 3)) {
lua_getfield(L, 3, "antialiasing");
if (lua_isstring(L, -1)) {
const char *antialiasing = lua_tostring(L, -1);
if (antialiasing) {
if (strcmp(antialiasing, "grayscale") == 0) {
font_options |= RenFontGrayscale;
} else if (strcmp(antialiasing, "subpixel") == 0) {
font_options |= RenFontSubpixel;
} else {
return luaL_error(L, "error in renderer.font.load, unknown antialiasing option: \"%s\"", antialiasing);
}
}
}
lua_pop(L, 1);
lua_getfield(L, 3, "hinting");
if (lua_isstring(L, -1)) {
const char *hinting = lua_tostring(L, -1);
if (hinting) {
if (strcmp(hinting, "slight") == 0) {
font_options |= RenFontHintingSlight;
} else if (strcmp(hinting, "none") == 0) {
font_options |= RenFontHintingNone;
} else if (strcmp(hinting, "full") == 0) {
font_options |= RenFontHintingFull;
} else {
return luaL_error(L, "error in renderer.font.load, unknown hinting option: \"%s\"", hinting);
}
}
}
lua_pop(L, 1);
}
RenFont **self = lua_newuserdata(L, sizeof(*self));
luaL_setmetatable(L, API_TYPE_FONT);
*self = ren_load_font(filename, size);
*self = ren_load_font(filename, size, font_options);
if (!*self) { luaL_error(L, "failed to load font"); }
return 1;
}

View File

@ -141,14 +141,23 @@ static GlyphSet* get_glyphset(RenFont *font, int codepoint) {
}
RenFont* ren_load_font(const char *filename, float size) {
RenFont* ren_load_font(const char *filename, float size, unsigned int renderer_flags) {
RenFont *font = NULL;
/* init font */
font = check_alloc(calloc(1, sizeof(RenFont)));
font->size = size;
font->renderer = FR_Renderer_New(FR_HINTING | FR_SUBPIXEL | FR_PRESCALE_X);
unsigned int fr_renderer_flags = 0;
if ((renderer_flags & RenFontAntialiasingMask) == RenFontSubpixel) {
fr_renderer_flags |= FR_SUBPIXEL;
}
if ((renderer_flags & RenFontHintingMask) == RenFontHintingSlight) {
fr_renderer_flags |= (FR_HINTING | FR_PRESCALE_X);
} else if ((renderer_flags & RenFontHintingMask) == RenFontHintingFull) {
fr_renderer_flags |= FR_HINTING;
}
font->renderer = FR_Renderer_New(fr_renderer_flags);
if (FR_Load_Font(font->renderer, filename)) {
free(font);
return NULL;

View File

@ -7,6 +7,17 @@
typedef struct RenImage RenImage;
typedef struct RenFont RenFont;
enum {
RenFontAntialiasingMask = 1,
RenFontGrayscale = 1,
RenFontSubpixel = 0,
RenFontHintingMask = 3 << 1,
RenFontHintingSlight = 0 << 1,
RenFontHintingNone = 1 << 1,
RenFontHintingFull = 2 << 1,
};
typedef struct { uint8_t b, g, r, a; } RenColor;
typedef struct { int x, y, width, height; } RenRect;
@ -19,7 +30,7 @@ void ren_get_size(int *x, int *y);
RenImage* ren_new_image(int width, int height);
void ren_free_image(RenImage *image);
RenFont* ren_load_font(const char *filename, float size);
RenFont* ren_load_font(const char *filename, float size, unsigned int renderer_flags);
void ren_free_font(RenFont *font);
void ren_set_font_tab_width(RenFont *font, int n);
int ren_get_font_tab_width(RenFont *font);