config: Add support for font slant and weight

This commit is contained in:
John Lindgren 2022-09-15 10:53:49 -04:00 committed by Johan Malm
parent 1fafb89cba
commit 07a83c19f0
12 changed files with 126 additions and 98 deletions

View file

@ -11,6 +11,21 @@
#include "labwc.h"
#include "buffer.h"
PangoFontDescription *
font_to_pango_desc(struct font *font)
{
PangoFontDescription *desc = pango_font_description_new();
pango_font_description_set_family(desc, font->name);
pango_font_description_set_size(desc, font->size * PANGO_SCALE);
if (font->slant == FONT_SLANT_ITALIC) {
pango_font_description_set_style(desc, PANGO_STYLE_ITALIC);
}
if (font->weight == FONT_WEIGHT_BOLD) {
pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
}
return desc;
}
static PangoRectangle
font_extents(struct font *font, const char *string)
{
@ -25,9 +40,7 @@ font_extents(struct font *font, const char *string)
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
c = cairo_create(surface);
layout = pango_cairo_create_layout(c);
PangoFontDescription *desc = pango_font_description_new();
pango_font_description_set_family(desc, font->name);
pango_font_description_set_size(desc, font->size * PANGO_SCALE);
PangoFontDescription *desc = font_to_pango_desc(font);
pango_layout_set_font_description(layout, desc);
pango_layout_set_text(layout, string, -1);
@ -108,9 +121,7 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width,
pango_layout_set_text(layout, text, -1);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
PangoFontDescription *desc = pango_font_description_new();
pango_font_description_set_family(desc, font->name);
pango_font_description_set_size(desc, font->size * PANGO_SCALE);
PangoFontDescription *desc = font_to_pango_desc(font);
pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc);
pango_cairo_update_layout(cairo, layout);

View file

@ -86,6 +86,8 @@ scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text,
self->font.name = strdup(font->name);
}
self->font.size = font->size;
self->font.slant = font->slant;
self->font.weight = font->weight;
memcpy(self->color, color, sizeof(self->color));
self->arrow = arrow ? strdup(arrow) : NULL;

View file

@ -236,6 +236,23 @@ fill_libinput_category(char *nodename, char *content)
}
}
static void
set_font_attr(struct font *font, const char *nodename, const char *content)
{
if (!strcmp(nodename, "name")) {
zfree(font->name);
font->name = strdup(content);
} else if (!strcmp(nodename, "size")) {
font->size = atoi(content);
} else if (!strcmp(nodename, "slant")) {
font->slant = !strcasecmp(content, "italic") ?
FONT_SLANT_ITALIC : FONT_SLANT_NORMAL;
} else if (!strcmp(nodename, "weight")) {
font->weight = !strcasecmp(content, "bold") ?
FONT_WEIGHT_BOLD : FONT_WEIGHT_NORMAL;
}
}
static void
fill_font(char *nodename, char *content, enum font_place place)
{
@ -250,36 +267,18 @@ fill_font(char *nodename, char *content, enum font_place place)
* If <theme><font></font></theme> is used without a place=""
* attribute, we set all font variables
*/
if (!strcmp(nodename, "name")) {
rc.font_name_activewindow = strdup(content);
rc.font_name_menuitem = strdup(content);
rc.font_name_osd = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_activewindow = atoi(content);
rc.font_size_menuitem = atoi(content);
rc.font_size_osd = atoi(content);
}
set_font_attr(&rc.font_activewindow, nodename, content);
set_font_attr(&rc.font_menuitem, nodename, content);
set_font_attr(&rc.font_osd, nodename, content);
break;
case FONT_PLACE_ACTIVEWINDOW:
if (!strcmp(nodename, "name")) {
rc.font_name_activewindow = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_activewindow = atoi(content);
}
set_font_attr(&rc.font_activewindow, nodename, content);
break;
case FONT_PLACE_MENUITEM:
if (!strcmp(nodename, "name")) {
rc.font_name_menuitem = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_menuitem = atoi(content);
}
set_font_attr(&rc.font_menuitem, nodename, content);
break;
case FONT_PLACE_OSD:
if (!strcmp(nodename, "name")) {
rc.font_name_osd = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_osd = atoi(content);
}
set_font_attr(&rc.font_osd, nodename, content);
break;
/* TODO: implement for all font places */
@ -368,6 +367,10 @@ entry(xmlNode *node, char *nodename, char *content)
fill_font(nodename, content, font_place);
} else if (!strcmp(nodename, "size.font.theme")) {
fill_font(nodename, content, font_place);
} else if (!strcmp(nodename, "slant.font.theme")) {
fill_font(nodename, content, font_place);
} else if (!strcmp(nodename, "weight.font.theme")) {
fill_font(nodename, content, font_place);
} else if (!strcasecmp(nodename, "followMouse.focus")) {
rc.focus_follow_mouse = get_bool(content);
} else if (!strcasecmp(nodename, "raiseOnFocus.focus")) {
@ -491,9 +494,9 @@ rcxml_init()
wl_list_init(&rc.libinput_categories);
rc.xdg_shell_server_side_deco = true;
rc.corner_radius = 8;
rc.font_size_activewindow = 10;
rc.font_size_menuitem = 10;
rc.font_size_osd = 10;
rc.font_activewindow.size = 10;
rc.font_menuitem.size = 10;
rc.font_osd.size = 10;
rc.doubleclick_time = 500;
rc.repeat_rate = 25;
rc.repeat_delay = 600;
@ -666,14 +669,14 @@ post_processing(void)
/* Replace all earlier mousebindings by later ones */
merge_mouse_bindings();
if (!rc.font_name_activewindow) {
rc.font_name_activewindow = strdup("sans");
if (!rc.font_activewindow.name) {
rc.font_activewindow.name = strdup("sans");
}
if (!rc.font_name_menuitem) {
rc.font_name_menuitem = strdup("sans");
if (!rc.font_menuitem.name) {
rc.font_menuitem.name = strdup("sans");
}
if (!rc.font_name_osd) {
rc.font_name_osd = strdup("sans");
if (!rc.font_osd.name) {
rc.font_osd.name = strdup("sans");
}
if (!wl_list_length(&rc.libinput_categories)) {
/* So we still allow tap to click by default */
@ -759,9 +762,9 @@ no_config:
void
rcxml_finish(void)
{
zfree(rc.font_name_activewindow);
zfree(rc.font_name_menuitem);
zfree(rc.font_name_osd);
zfree(rc.font_activewindow.name);
zfree(rc.font_menuitem.name);
zfree(rc.font_osd.name);
zfree(rc.theme_name);
struct keybind *k, *k_tmp;

View file

@ -88,13 +88,10 @@ item_create(struct menu *menu, const char *text, bool show_arrow)
menuitem->selectable = true;
struct server *server = menu->server;
struct theme *theme = server->theme;
struct font font = {
.name = rc.font_name_menuitem,
.size = rc.font_size_menuitem,
};
if (!menu->item_height) {
menu->item_height = font_height(&font) + 2 * MENU_ITEM_PADDING_Y;
menu->item_height = font_height(&rc.font_menuitem)
+ 2 * MENU_ITEM_PADDING_Y;
}
menuitem->height = menu->item_height;
@ -139,9 +136,9 @@ item_create(struct menu *menu, const char *text, bool show_arrow)
/* Font buffers */
const char *arrow = show_arrow ? "" : NULL;
scaled_font_buffer_update(menuitem->normal.buffer, text, item_max_width,
&font, theme->menu_items_text_color, arrow);
&rc.font_menuitem, theme->menu_items_text_color, arrow);
scaled_font_buffer_update(menuitem->selected.buffer, text, item_max_width,
&font, theme->menu_items_active_text_color, arrow);
&rc.font_menuitem, theme->menu_items_active_text_color, arrow);
/* Center font nodes */
x = MENU_ITEM_PADDING_X;

View file

@ -304,13 +304,7 @@ osd_update(struct server *server)
(OSD_ITEM_WIDTH - 2 * OSD_ITEM_PADDING) * PANGO_SCALE);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
struct font font = {
.name = rc.font_name_osd,
.size = rc.font_size_osd,
};
PangoFontDescription *desc = pango_font_description_new();
pango_font_description_set_family(desc, font.name);
pango_font_description_set_size(desc, font.size * PANGO_SCALE);
PangoFontDescription *desc = font_to_pango_desc(&rc.font_osd);
pango_layout_set_font_description(layout, desc);
PangoTabArray *tabs = pango_tab_array_new_with_positions(2, TRUE,
@ -323,19 +317,20 @@ osd_update(struct server *server)
y = OSD_BORDER_WIDTH;
/* Center text entries on the y axis */
int y_offset = (OSD_ITEM_HEIGHT - font_height(&font)) / 2;
int y_offset = (OSD_ITEM_HEIGHT - font_height(&rc.font_osd)) / 2;
y += y_offset;
if (show_workspace) {
/* Center workspace indicator on the x axis */
int x = font_width(&font, server->workspace_current->name);
int x = font_width(&rc.font_osd, server->workspace_current->name);
x = (OSD_ITEM_WIDTH - x) / 2;
cairo_move_to(cairo, x, y);
PangoWeight weight = pango_font_description_get_weight(desc);
pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
pango_layout_set_font_description(layout, desc);
pango_layout_set_text(layout, server->workspace_current->name, -1);
pango_cairo_show_layout(cairo, layout);
pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL);
pango_font_description_set_weight(desc, weight);
pango_layout_set_font_description(layout, desc);
y += OSD_ITEM_HEIGHT;
}

View file

@ -216,12 +216,6 @@ ssd_update_title(struct view *view)
struct ssd_state_title *state = &view->ssd.state.title;
bool title_unchanged = state->text && !strcmp(title, state->text);
/* TODO: Do we only have active window fonts? */
struct font font = {
.name = rc.font_name_activewindow,
.size = rc.font_size_activewindow,
};
float *text_color;
struct ssd_part *part;
struct ssd_sub_tree *subtree;
@ -261,8 +255,10 @@ ssd_update_title(struct view *view)
}
if (part->buffer) {
/* TODO: Do we only have active window fonts? */
scaled_font_buffer_update(part->buffer, title,
title_bg_width, &font, text_color, NULL);
title_bg_width, &rc.font_activewindow,
text_color, NULL);
}
/* And finally update the cache */

View file

@ -473,11 +473,8 @@ create_corners(struct theme *theme)
static void
post_processing(struct theme *theme)
{
struct font font = {
.name = rc.font_name_activewindow,
.size = rc.font_size_activewindow,
};
theme->title_height = font_height(&font) + 2 * theme->padding_height;
theme->title_height = font_height(&rc.font_activewindow)
+ 2 * theme->padding_height;
if (rc.corner_radius >= theme->title_height) {
theme->title_height = rc.corner_radius + 1;

View file

@ -57,16 +57,12 @@ _osd_update(struct server *server)
uint16_t padding = 2;
uint16_t rect_height = 20;
uint16_t rect_width = 20;
struct font font = {
.name = rc.font_name_osd,
.size = rc.font_size_osd,
};
/* Dimensions */
size_t workspace_count = wl_list_length(&server->workspaces);
uint16_t marker_width = workspace_count * (rect_width + padding) - padding;
uint16_t width = margin * 2 + (marker_width < 200 ? 200 : marker_width);
uint16_t height = margin * 3 + rect_height + font_height(&font);
uint16_t height = margin * 3 + rect_height + font_height(&rc.font_osd);
cairo_t *cairo;
cairo_surface_t *surface;
@ -113,13 +109,11 @@ _osd_update(struct server *server)
pango_layout_set_width(layout, (width - 2 * margin) * PANGO_SCALE);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
PangoFontDescription *desc = pango_font_description_new();
pango_font_description_set_family(desc, font.name);
pango_font_description_set_size(desc, font.size * PANGO_SCALE);
PangoFontDescription *desc = font_to_pango_desc(&rc.font_osd);
pango_layout_set_font_description(layout, desc);
/* Center workspace indicator on the x axis */
x = font_width(&font, server->workspace_current->name);
x = font_width(&rc.font_osd, server->workspace_current->name);
x = (width - x) / 2;
cairo_move_to(cairo, x, margin * 2 + rect_height);
//pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);