/* 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,
FT_Library library;
FT_Face face;
+ FT_Face bold_face;
char *font;
char *text;
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)
{
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)
{
free (label->text);
free (label->font);
FT_Done_Face (label->face);
+ FT_Done_Face (label->bold_face);
FT_Done_FreeType (label->library);
free (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);
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
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;
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;
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,
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;
}
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;
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)
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;
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);
}