Added a smoothing and strikethrough option to font loading. (#1087)
* Added a smoothing option to font loading. * Added a font strikethrough option to font loading. * Fixed underline applying incorrectly in cases of non-underlined fallback fonts being used. Co-authored-by: Guldoman <giulio.lettieri@gmail.com>
This commit is contained in:
parent
f07b62f852
commit
9b1bfeacac
|
@ -4,6 +4,7 @@ lhelper/
|
||||||
submodules/
|
submodules/
|
||||||
subprojects/*/
|
subprojects/*/
|
||||||
/appimage*
|
/appimage*
|
||||||
|
.vscode
|
||||||
.cache
|
.cache
|
||||||
.ccls-cache
|
.ccls-cache
|
||||||
.lite-debug.log
|
.lite-debug.log
|
||||||
|
|
|
@ -497,7 +497,7 @@ local style = require "core.style"
|
||||||
--
|
--
|
||||||
-- the function to load the font accept a 3rd optional argument like:
|
-- the function to load the font accept a 3rd optional argument like:
|
||||||
--
|
--
|
||||||
-- {antialiasing="grayscale", hinting="full", bold=true, italic=true, underline=true}
|
-- {antialiasing="grayscale", hinting="full", bold=true, italic=true, underline=true, smoothing=true, strikethrough=true}
|
||||||
--
|
--
|
||||||
-- possible values are:
|
-- possible values are:
|
||||||
-- antialiasing: grayscale, subpixel
|
-- antialiasing: grayscale, subpixel
|
||||||
|
@ -505,6 +505,8 @@ local style = require "core.style"
|
||||||
-- bold: true, false
|
-- bold: true, false
|
||||||
-- italic: true, false
|
-- italic: true, false
|
||||||
-- underline: true, false
|
-- underline: true, false
|
||||||
|
-- smoothing: true, false
|
||||||
|
-- strikethrough: true, false
|
||||||
|
|
||||||
------------------------------ Plugins ----------------------------------------
|
------------------------------ Plugins ----------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ renderer.color = {}
|
||||||
-- @field public bold boolean
|
-- @field public bold boolean
|
||||||
-- @field public italic boolean
|
-- @field public italic boolean
|
||||||
-- @field public underline boolean
|
-- @field public underline boolean
|
||||||
|
-- @field public smoothing boolean
|
||||||
|
-- @field public strikethrough boolean
|
||||||
renderer.fontoptions = {}
|
renderer.fontoptions = {}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
@ -58,6 +58,13 @@ static int font_get_options(
|
||||||
lua_getfield(L, 3, "underline");
|
lua_getfield(L, 3, "underline");
|
||||||
if (lua_toboolean(L, -1))
|
if (lua_toboolean(L, -1))
|
||||||
style_local |= FONT_STYLE_UNDERLINE;
|
style_local |= FONT_STYLE_UNDERLINE;
|
||||||
|
lua_getfield(L, 3, "smoothing");
|
||||||
|
if (lua_toboolean(L, -1))
|
||||||
|
style_local |= FONT_STYLE_SMOOTH;
|
||||||
|
lua_getfield(L, 3, "strikethrough");
|
||||||
|
if (lua_toboolean(L, -1))
|
||||||
|
style_local |= FONT_STYLE_STRIKETHROUGH;
|
||||||
|
|
||||||
lua_pop(L, 5);
|
lua_pop(L, 5);
|
||||||
|
|
||||||
if (style_local != 0)
|
if (style_local != 0)
|
||||||
|
|
|
@ -50,6 +50,7 @@ typedef struct RenFont {
|
||||||
ERenFontAntialiasing antialiasing;
|
ERenFontAntialiasing antialiasing;
|
||||||
ERenFontHinting hinting;
|
ERenFontHinting hinting;
|
||||||
unsigned char style;
|
unsigned char style;
|
||||||
|
unsigned short underline_thickness;
|
||||||
char path[1];
|
char path[1];
|
||||||
} RenFont;
|
} RenFont;
|
||||||
|
|
||||||
|
@ -100,6 +101,8 @@ static int font_set_render_options(RenFont* font) {
|
||||||
|
|
||||||
static int font_set_style(FT_Outline* outline, int x_translation, unsigned char style) {
|
static int font_set_style(FT_Outline* outline, int x_translation, unsigned char style) {
|
||||||
FT_Outline_Translate(outline, x_translation, 0 );
|
FT_Outline_Translate(outline, x_translation, 0 );
|
||||||
|
if (style & FONT_STYLE_SMOOTH)
|
||||||
|
FT_Outline_Embolden(outline, 1 << 5);
|
||||||
if (style & FONT_STYLE_BOLD)
|
if (style & FONT_STYLE_BOLD)
|
||||||
FT_Outline_EmboldenXY(outline, 1 << 5, 0);
|
FT_Outline_EmboldenXY(outline, 1 << 5, 0);
|
||||||
if (style & FONT_STYLE_ITALIC) {
|
if (style & FONT_STYLE_ITALIC) {
|
||||||
|
@ -220,6 +223,10 @@ RenFont* ren_font_load(const char* path, float size, ERenFontAntialiasing antial
|
||||||
font->hinting = hinting;
|
font->hinting = hinting;
|
||||||
font->style = style;
|
font->style = style;
|
||||||
|
|
||||||
|
if(FT_IS_SCALABLE(face))
|
||||||
|
font->underline_thickness = (unsigned short)((face->underline_thickness / (float)face->units_per_EM) * font->size);
|
||||||
|
if(!font->underline_thickness) font->underline_thickness = ceil((double) font->height / 14.0);
|
||||||
|
|
||||||
if (FT_Load_Char(face, ' ', font_set_load_options(font)))
|
if (FT_Load_Char(face, ' ', font_set_load_options(font)))
|
||||||
goto failure;
|
goto failure;
|
||||||
font->space_advance = face->glyph->advance.x / 64.0f;
|
font->space_advance = face->glyph->advance.x / 64.0f;
|
||||||
|
@ -314,6 +321,11 @@ float ren_draw_text(RenFont **fonts, const char *text, float x, int y, RenColor
|
||||||
uint8_t* destination_pixels = surface->pixels;
|
uint8_t* destination_pixels = surface->pixels;
|
||||||
int clip_end_x = clip.x + clip.width, clip_end_y = clip.y + clip.height;
|
int clip_end_x = clip.x + clip.width, clip_end_y = clip.y + clip.height;
|
||||||
|
|
||||||
|
RenFont* last;
|
||||||
|
float last_pen_x = x;
|
||||||
|
bool underline = fonts[0]->style & FONT_STYLE_UNDERLINE;
|
||||||
|
bool strikethrough = fonts[0]->style & FONT_STYLE_STRIKETHROUGH;
|
||||||
|
|
||||||
while (text < end) {
|
while (text < end) {
|
||||||
unsigned int codepoint, r, g, b;
|
unsigned int codepoint, r, g, b;
|
||||||
text = utf8_to_codepoint(text, &codepoint);
|
text = utf8_to_codepoint(text, &codepoint);
|
||||||
|
@ -369,10 +381,22 @@ float ren_draw_text(RenFont **fonts, const char *text, float x, int y, RenColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pen_x += metric->xadvance ? metric->xadvance : font->space_advance;
|
|
||||||
|
float adv = metric->xadvance ? metric->xadvance : font->space_advance;
|
||||||
|
|
||||||
|
if(!last) last = font;
|
||||||
|
else if(font != last || text == end) {
|
||||||
|
float local_pen_x = text == end ? pen_x + adv : pen_x;
|
||||||
|
if (underline)
|
||||||
|
ren_draw_rect((RenRect){last_pen_x, y / surface_scale + last->height - 1, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color);
|
||||||
|
if (strikethrough)
|
||||||
|
ren_draw_rect((RenRect){last_pen_x, y / surface_scale + last->height / 2, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color);
|
||||||
|
last = font;
|
||||||
|
last_pen_x = pen_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
pen_x += adv;
|
||||||
}
|
}
|
||||||
if (fonts[0]->style & FONT_STYLE_UNDERLINE)
|
|
||||||
ren_draw_rect((RenRect){ x, y / surface_scale + ren_font_group_get_height(fonts) - 1, (pen_x - x) / surface_scale, 1 }, color);
|
|
||||||
return pen_x / surface_scale;
|
return pen_x / surface_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,4 +488,3 @@ void ren_get_size(int *x, int *y) {
|
||||||
*x = surface->w / scale;
|
*x = surface->w / scale;
|
||||||
*y = surface->h / scale;
|
*y = surface->h / scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
typedef struct RenFont RenFont;
|
typedef struct RenFont RenFont;
|
||||||
typedef enum { FONT_HINTING_NONE, FONT_HINTING_SLIGHT, FONT_HINTING_FULL } ERenFontHinting;
|
typedef enum { FONT_HINTING_NONE, FONT_HINTING_SLIGHT, FONT_HINTING_FULL } ERenFontHinting;
|
||||||
typedef enum { FONT_ANTIALIASING_NONE, FONT_ANTIALIASING_GRAYSCALE, FONT_ANTIALIASING_SUBPIXEL } ERenFontAntialiasing;
|
typedef enum { FONT_ANTIALIASING_NONE, FONT_ANTIALIASING_GRAYSCALE, FONT_ANTIALIASING_SUBPIXEL } ERenFontAntialiasing;
|
||||||
typedef enum { FONT_STYLE_BOLD = 1, FONT_STYLE_ITALIC = 2, FONT_STYLE_UNDERLINE = 4 } ERenFontStyle;
|
typedef enum { FONT_STYLE_BOLD = 1, FONT_STYLE_ITALIC = 2, FONT_STYLE_UNDERLINE = 4, FONT_STYLE_SMOOTH = 8, FONT_STYLE_STRIKETHROUGH = 16 } ERenFontStyle;
|
||||||
typedef struct { uint8_t b, g, r, a; } RenColor;
|
typedef struct { uint8_t b, g, r, a; } RenColor;
|
||||||
typedef struct { int x, y, width, height; } RenRect;
|
typedef struct { int x, y, width, height; } RenRect;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue