mirror of
https://gitlab.freedesktop.org/plymouth/plymouth.git
synced 2026-05-09 07:08:01 +02:00
Merge branch 'freetype-monospace-bold' into 'main'
label-freetype: implement bold font handling See merge request plymouth/plymouth!338
This commit is contained in:
commit
a0e8b6cf50
1 changed files with 96 additions and 13 deletions
|
|
@ -42,7 +42,9 @@
|
|||
|
||||
/* This is used if fontconfig (fc-match) is not available, like in the initrd. */
|
||||
#define FONT_FALLBACK "/usr/share/fonts/Plymouth.ttf"
|
||||
#define BOLD_FONT_FALLBACK "/usr/share/fonts/Plymouth-bold.ttf"
|
||||
#define MONOSPACE_FONT_FALLBACK "/usr/share/fonts/Plymouth-monospace.ttf"
|
||||
#define MONOSPACE_BOLD_FONT_FALLBACK "/usr/share/fonts/Plymouth-monospace-bold.ttf"
|
||||
|
||||
/* This is a little sketchy... It relies on implementation details of the compiler
|
||||
* but it makes dealing with the fixed point math freetype uses much more pleasant,
|
||||
|
|
@ -85,6 +87,7 @@ struct _ply_label_plugin_control
|
|||
|
||||
FT_Library library;
|
||||
FT_Face face;
|
||||
FT_Face bold_face;
|
||||
char *font;
|
||||
|
||||
char *text;
|
||||
|
|
@ -141,6 +144,26 @@ find_default_font_path (void)
|
|||
return fc_match_out;
|
||||
}
|
||||
|
||||
static const char *
|
||||
find_default_bold_font_path (void)
|
||||
{
|
||||
FILE *fp;
|
||||
static char fc_match_out[PATH_MAX];
|
||||
|
||||
fp = popen ("/usr/bin/fc-match -f %{file} :weight=bold", "r");
|
||||
if (!fp)
|
||||
return BOLD_FONT_FALLBACK;
|
||||
|
||||
fgets (fc_match_out, sizeof(fc_match_out), fp);
|
||||
|
||||
pclose (fp);
|
||||
|
||||
if (strcmp (fc_match_out, "") == 0)
|
||||
return BOLD_FONT_FALLBACK;
|
||||
|
||||
return fc_match_out;
|
||||
}
|
||||
|
||||
static const char *
|
||||
find_default_monospace_font_path (void)
|
||||
{
|
||||
|
|
@ -161,6 +184,26 @@ find_default_monospace_font_path (void)
|
|||
return fc_match_out;
|
||||
}
|
||||
|
||||
static const char *
|
||||
find_default_monospace_bold_font_path (void)
|
||||
{
|
||||
FILE *fp;
|
||||
static char fc_match_out[PATH_MAX];
|
||||
|
||||
fp = popen ("/usr/bin/fc-match -f %{file} monospace:weight=bold", "r");
|
||||
if (!fp)
|
||||
return MONOSPACE_BOLD_FONT_FALLBACK;
|
||||
|
||||
fgets (fc_match_out, sizeof(fc_match_out), fp);
|
||||
|
||||
pclose (fp);
|
||||
|
||||
if (strcmp (fc_match_out, "") == 0)
|
||||
return MONOSPACE_BOLD_FONT_FALLBACK;
|
||||
|
||||
return fc_match_out;
|
||||
}
|
||||
|
||||
static ply_label_plugin_control_t *
|
||||
create_control (void)
|
||||
{
|
||||
|
|
@ -213,6 +256,7 @@ destroy_control (ply_label_plugin_control_t *label)
|
|||
free (label->text);
|
||||
free (label->font);
|
||||
FT_Done_Face (label->face);
|
||||
FT_Done_Face (label->bold_face);
|
||||
FT_Done_FreeType (label->library);
|
||||
|
||||
free (label);
|
||||
|
|
@ -235,14 +279,15 @@ get_height_of_control (ply_label_plugin_control_t *label)
|
|||
static FT_GlyphSlot
|
||||
load_glyph (ply_label_plugin_control_t *label,
|
||||
ply_load_glyph_action_t action,
|
||||
const char *input_text)
|
||||
const char *input_text,
|
||||
FT_Face face)
|
||||
{
|
||||
FT_Error error;
|
||||
size_t character_size;
|
||||
wchar_t character;
|
||||
FT_Int32 load_flags = FT_LOAD_TARGET_LIGHT;
|
||||
|
||||
if (label->face == NULL)
|
||||
if (face == NULL)
|
||||
return NULL;
|
||||
|
||||
character_size = mbrtowc (&character, input_text, PLY_UTF8_CHARACTER_SIZE_MAX, NULL);
|
||||
|
|
@ -255,12 +300,12 @@ load_glyph (ply_label_plugin_control_t *label,
|
|||
if (action == PLY_LOAD_GLYPH_ACTION_RENDER)
|
||||
load_flags |= FT_LOAD_RENDER;
|
||||
|
||||
error = FT_Load_Char (label->face, (FT_ULong) character, load_flags);
|
||||
error = FT_Load_Char (face, (FT_ULong) character, load_flags);
|
||||
|
||||
if (error)
|
||||
return NULL;
|
||||
|
||||
return label->face->glyph;
|
||||
return face->glyph;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -424,16 +469,17 @@ static void
|
|||
finish_measuring_line (ply_label_plugin_control_t *label,
|
||||
ply_freetype_unit_t *glyph_x,
|
||||
ply_freetype_unit_t *glyph_y,
|
||||
ply_rectangle_t *dimensions)
|
||||
ply_rectangle_t *dimensions,
|
||||
FT_Face face)
|
||||
{
|
||||
|
||||
ply_freetype_unit_t line_height;
|
||||
ply_rectangle_t *entry;
|
||||
|
||||
if (label->face == NULL)
|
||||
if (face == NULL)
|
||||
return;
|
||||
|
||||
line_height.as_integer = label->face->size->metrics.ascender + -label->face->size->metrics.descender;
|
||||
line_height.as_integer = face->size->metrics.ascender + -face->size->metrics.descender;
|
||||
|
||||
dimensions->x = label->area.x * label->scale_factor;
|
||||
|
||||
|
|
@ -485,6 +531,7 @@ load_glyphs (ply_label_plugin_control_t *label,
|
|||
ply_pixel_buffer_t *pixel_buffer)
|
||||
{
|
||||
FT_GlyphSlot glyph = NULL;
|
||||
FT_Face glyph_face = label->face;
|
||||
ply_rich_text_iterator_t rich_text_iterator;
|
||||
ply_utf8_string_iterator_t utf8_string_iterator;
|
||||
uint32_t *target = NULL;
|
||||
|
|
@ -570,6 +617,12 @@ load_glyphs (ply_label_plugin_control_t *label,
|
|||
|
||||
current_character = rich_text_character->bytes;
|
||||
|
||||
if (label->bold_face != NULL && rich_text_character->style.bold_enabled) {
|
||||
glyph_face = label->bold_face;
|
||||
} else {
|
||||
glyph_face = label->face;
|
||||
}
|
||||
|
||||
if (action == PLY_LOAD_GLYPH_ACTION_RENDER) {
|
||||
look_up_rgb_color_from_terminal_color (label,
|
||||
rich_text_character->style.foreground_color,
|
||||
|
|
@ -587,26 +640,27 @@ load_glyphs (ply_label_plugin_control_t *label,
|
|||
break;
|
||||
}
|
||||
|
||||
glyph = load_glyph (label, action, current_character);
|
||||
|
||||
glyph = load_glyph (label, action, current_character, glyph_face);
|
||||
|
||||
if (glyph == NULL)
|
||||
continue;
|
||||
|
||||
if (is_first_character) {
|
||||
/* Move pen to the first character's base line */
|
||||
glyph_y.as_integer += label->face->size->metrics.ascender;
|
||||
glyph_y.as_integer += glyph_face->size->metrics.ascender;
|
||||
}
|
||||
|
||||
if (*current_character == '\n') {
|
||||
if (action == PLY_LOAD_GLYPH_ACTION_MEASURE)
|
||||
finish_measuring_line (label, &glyph_x, &glyph_y, line_dimensions);
|
||||
finish_measuring_line (label, &glyph_x, &glyph_y, line_dimensions, glyph_face);
|
||||
else
|
||||
line_dimensions = dimensions_of_lines[line_number++];
|
||||
|
||||
glyph_x.as_pixels_unit.pixels = line_dimensions->x;
|
||||
glyph_y.as_pixels_unit.pixels = line_dimensions->y;
|
||||
|
||||
glyph_y.as_integer += label->face->size->metrics.ascender;
|
||||
glyph_y.as_integer += glyph_face->size->metrics.ascender;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -635,7 +689,7 @@ load_glyphs (ply_label_plugin_control_t *label,
|
|||
if (!is_first_character) {
|
||||
FT_Vector kerning_space;
|
||||
|
||||
error = FT_Get_Kerning (label->face, previous_glyph_index, glyph->glyph_index, FT_KERNING_DEFAULT, &kerning_space);
|
||||
error = FT_Get_Kerning (glyph_face, previous_glyph_index, glyph->glyph_index, FT_KERNING_DEFAULT, &kerning_space);
|
||||
|
||||
if (error == 0)
|
||||
glyph_x.as_integer += kerning_space.x;
|
||||
|
|
@ -650,7 +704,7 @@ load_glyphs (ply_label_plugin_control_t *label,
|
|||
if (!is_first_character) {
|
||||
char *text = NULL;
|
||||
|
||||
finish_measuring_line (label, &glyph_x, &glyph_y, line_dimensions);
|
||||
finish_measuring_line (label, &glyph_x, &glyph_y, line_dimensions, glyph_face);
|
||||
|
||||
if (ply_is_tracing ()) {
|
||||
if (label->rich_text != NULL)
|
||||
|
|
@ -783,29 +837,51 @@ set_font_for_control (ply_label_plugin_control_t *label,
|
|||
if (strstr (font, "Mono") || strstr (font, "mono")) {
|
||||
if (!label->is_monospaced) {
|
||||
FT_Done_Face (label->face);
|
||||
FT_Done_Face (label->bold_face);
|
||||
label->face = NULL;
|
||||
label->bold_face = NULL;
|
||||
|
||||
font_path = find_default_monospace_font_path ();
|
||||
|
||||
if (font_path != NULL)
|
||||
error = FT_New_Face (label->library, font_path, 0, &label->face);
|
||||
|
||||
font_path = find_default_monospace_bold_font_path ();
|
||||
|
||||
/* Ignore errors when loading bold face to allow
|
||||
* fallback to regular face */
|
||||
if (font_path != NULL)
|
||||
FT_New_Face (label->library, font_path, 0, &label->bold_face);
|
||||
|
||||
label->is_monospaced = true;
|
||||
}
|
||||
} else {
|
||||
if (label->is_monospaced || label->face == NULL) {
|
||||
FT_Done_Face (label->face);
|
||||
FT_Done_Face (label->bold_face);
|
||||
label->face = NULL;
|
||||
label->bold_face = NULL;
|
||||
|
||||
font_path = find_default_font_path ();
|
||||
|
||||
if (font_path != NULL)
|
||||
error = FT_New_Face (label->library, font_path, 0, &label->face);
|
||||
|
||||
font_path = find_default_bold_font_path ();
|
||||
|
||||
/* Ignore errors when loading bold face to allow
|
||||
* fallback to regular face */
|
||||
if (font_path != NULL)
|
||||
FT_New_Face (label->library, font_path, 0, &label->bold_face);
|
||||
|
||||
label->is_monospaced = false;
|
||||
}
|
||||
}
|
||||
if (error != 0) {
|
||||
FT_Done_Face (label->face);
|
||||
FT_Done_Face (label->bold_face);
|
||||
label->face = NULL;
|
||||
label->bold_face = NULL;
|
||||
|
||||
ply_trace ("Could not load font, error %d", error);
|
||||
return;
|
||||
|
|
@ -834,6 +910,13 @@ set_font_for_control (ply_label_plugin_control_t *label,
|
|||
else
|
||||
FT_Set_Char_Size (label->face, size.as_integer, 0, dpi * label->scale_factor, 0);
|
||||
|
||||
if (label->bold_face != NULL) {
|
||||
if (size_in_pixels)
|
||||
FT_Set_Pixel_Sizes (label->bold_face, 0, size.as_pixels_unit.pixels * label->scale_factor);
|
||||
else
|
||||
FT_Set_Char_Size (label->bold_face, size.as_integer, 0, dpi * label->scale_factor, 0);
|
||||
}
|
||||
|
||||
/* Ignore errors, to keep the current size. */
|
||||
trigger_redraw (label, true);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue