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

@ -136,6 +136,12 @@ The rest of this man page describes configuration options.
*<theme><font place=""><size>* *<theme><font place=""><size>*
Font size in pixels. Default is 10. Font size in pixels. Default is 10.
*<theme><font place=""><slant>*
Font slant (normal or italic). Default is normal.
*<theme><font place=""><weight>*
Font weight (normal or bold). Default is normal.
## KEYBOARD ## KEYBOARD
*<keyboard><keybind key="">* *<keyboard><keybind key="">*

View file

@ -19,9 +19,24 @@
<theme> <theme>
<name></name> <name></name>
<cornerRadius>8</cornerRadius> <cornerRadius>8</cornerRadius>
<font place="ActiveWindow"><name>sans</name><size>10</size></font> <font place="ActiveWindow">
<font place="MenuItem"><name>sans</name><size>10</size></font> <name>sans</name>
<font place="OSD"><name>sans</name><size>10</size></font> <size>10</size>
<slant>normal</slant>
<weight>normal</weight>
</font>
<font place="MenuItem">
<name>sans</name>
<size>10</size>
<slant>normal</slant>
<weight>normal</weight>
</font>
<font place="OSD">
<name>sans</name>
<size>10</size>
<slant>normal</slant>
<weight>normal</weight>
</font>
</theme> </theme>
<!-- edge strength is in pixels --> <!-- edge strength is in pixels -->

View file

@ -4,11 +4,25 @@
struct lab_data_buffer; struct lab_data_buffer;
enum font_slant {
FONT_SLANT_NORMAL,
FONT_SLANT_ITALIC
};
enum font_weight {
FONT_WEIGHT_NORMAL,
FONT_WEIGHT_BOLD
};
struct font { struct font {
char *name; char *name;
int size; int size;
enum font_slant slant;
enum font_weight weight;
}; };
struct _PangoFontDescription *font_to_pango_desc(struct font *font);
/** /**
* font_height - get font vertical extents * font_height - get font vertical extents
* @font: description of font including family name and size * @font: description of font including family name and size

View file

@ -7,6 +7,7 @@
#include <wayland-server-core.h> #include <wayland-server-core.h>
#include "common/buf.h" #include "common/buf.h"
#include "common/font.h"
#include "config/libinput.h" #include "config/libinput.h"
#include "theme.h" #include "theme.h"
@ -25,12 +26,9 @@ struct rcxml {
/* theme */ /* theme */
char *theme_name; char *theme_name;
int corner_radius; int corner_radius;
char *font_name_activewindow; struct font font_activewindow;
char *font_name_menuitem; struct font font_menuitem;
char *font_name_osd; struct font font_osd;
int font_size_activewindow;
int font_size_menuitem;
int font_size_osd;
/* Pointer to current theme */ /* Pointer to current theme */
struct theme *theme; struct theme *theme;

View file

@ -11,6 +11,21 @@
#include "labwc.h" #include "labwc.h"
#include "buffer.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 static PangoRectangle
font_extents(struct font *font, const char *string) 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); surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
c = cairo_create(surface); c = cairo_create(surface);
layout = pango_cairo_create_layout(c); layout = pango_cairo_create_layout(c);
PangoFontDescription *desc = pango_font_description_new(); PangoFontDescription *desc = font_to_pango_desc(font);
pango_font_description_set_family(desc, font->name);
pango_font_description_set_size(desc, font->size * PANGO_SCALE);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
pango_layout_set_text(layout, string, -1); 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_text(layout, text, -1);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
PangoFontDescription *desc = pango_font_description_new(); PangoFontDescription *desc = font_to_pango_desc(font);
pango_font_description_set_family(desc, font->name);
pango_font_description_set_size(desc, font->size * PANGO_SCALE);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc); pango_font_description_free(desc);
pango_cairo_update_layout(cairo, layout); 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.name = strdup(font->name);
} }
self->font.size = font->size; self->font.size = font->size;
self->font.slant = font->slant;
self->font.weight = font->weight;
memcpy(self->color, color, sizeof(self->color)); memcpy(self->color, color, sizeof(self->color));
self->arrow = arrow ? strdup(arrow) : NULL; 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 static void
fill_font(char *nodename, char *content, enum font_place place) 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="" * If <theme><font></font></theme> is used without a place=""
* attribute, we set all font variables * attribute, we set all font variables
*/ */
if (!strcmp(nodename, "name")) { set_font_attr(&rc.font_activewindow, nodename, content);
rc.font_name_activewindow = strdup(content); set_font_attr(&rc.font_menuitem, nodename, content);
rc.font_name_menuitem = strdup(content); set_font_attr(&rc.font_osd, nodename, 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);
}
break; break;
case FONT_PLACE_ACTIVEWINDOW: case FONT_PLACE_ACTIVEWINDOW:
if (!strcmp(nodename, "name")) { set_font_attr(&rc.font_activewindow, nodename, content);
rc.font_name_activewindow = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_activewindow = atoi(content);
}
break; break;
case FONT_PLACE_MENUITEM: case FONT_PLACE_MENUITEM:
if (!strcmp(nodename, "name")) { set_font_attr(&rc.font_menuitem, nodename, content);
rc.font_name_menuitem = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_menuitem = atoi(content);
}
break; break;
case FONT_PLACE_OSD: case FONT_PLACE_OSD:
if (!strcmp(nodename, "name")) { set_font_attr(&rc.font_osd, nodename, content);
rc.font_name_osd = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_osd = atoi(content);
}
break; break;
/* TODO: implement for all font places */ /* TODO: implement for all font places */
@ -368,6 +367,10 @@ entry(xmlNode *node, char *nodename, char *content)
fill_font(nodename, content, font_place); fill_font(nodename, content, font_place);
} else if (!strcmp(nodename, "size.font.theme")) { } else if (!strcmp(nodename, "size.font.theme")) {
fill_font(nodename, content, font_place); 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")) { } else if (!strcasecmp(nodename, "followMouse.focus")) {
rc.focus_follow_mouse = get_bool(content); rc.focus_follow_mouse = get_bool(content);
} else if (!strcasecmp(nodename, "raiseOnFocus.focus")) { } else if (!strcasecmp(nodename, "raiseOnFocus.focus")) {
@ -491,9 +494,9 @@ rcxml_init()
wl_list_init(&rc.libinput_categories); wl_list_init(&rc.libinput_categories);
rc.xdg_shell_server_side_deco = true; rc.xdg_shell_server_side_deco = true;
rc.corner_radius = 8; rc.corner_radius = 8;
rc.font_size_activewindow = 10; rc.font_activewindow.size = 10;
rc.font_size_menuitem = 10; rc.font_menuitem.size = 10;
rc.font_size_osd = 10; rc.font_osd.size = 10;
rc.doubleclick_time = 500; rc.doubleclick_time = 500;
rc.repeat_rate = 25; rc.repeat_rate = 25;
rc.repeat_delay = 600; rc.repeat_delay = 600;
@ -666,14 +669,14 @@ post_processing(void)
/* Replace all earlier mousebindings by later ones */ /* Replace all earlier mousebindings by later ones */
merge_mouse_bindings(); merge_mouse_bindings();
if (!rc.font_name_activewindow) { if (!rc.font_activewindow.name) {
rc.font_name_activewindow = strdup("sans"); rc.font_activewindow.name = strdup("sans");
} }
if (!rc.font_name_menuitem) { if (!rc.font_menuitem.name) {
rc.font_name_menuitem = strdup("sans"); rc.font_menuitem.name = strdup("sans");
} }
if (!rc.font_name_osd) { if (!rc.font_osd.name) {
rc.font_name_osd = strdup("sans"); rc.font_osd.name = strdup("sans");
} }
if (!wl_list_length(&rc.libinput_categories)) { if (!wl_list_length(&rc.libinput_categories)) {
/* So we still allow tap to click by default */ /* So we still allow tap to click by default */
@ -759,9 +762,9 @@ no_config:
void void
rcxml_finish(void) rcxml_finish(void)
{ {
zfree(rc.font_name_activewindow); zfree(rc.font_activewindow.name);
zfree(rc.font_name_menuitem); zfree(rc.font_menuitem.name);
zfree(rc.font_name_osd); zfree(rc.font_osd.name);
zfree(rc.theme_name); zfree(rc.theme_name);
struct keybind *k, *k_tmp; 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; menuitem->selectable = true;
struct server *server = menu->server; struct server *server = menu->server;
struct theme *theme = server->theme; struct theme *theme = server->theme;
struct font font = {
.name = rc.font_name_menuitem,
.size = rc.font_size_menuitem,
};
if (!menu->item_height) { 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; menuitem->height = menu->item_height;
@ -139,9 +136,9 @@ item_create(struct menu *menu, const char *text, bool show_arrow)
/* Font buffers */ /* Font buffers */
const char *arrow = show_arrow ? "" : NULL; const char *arrow = show_arrow ? "" : NULL;
scaled_font_buffer_update(menuitem->normal.buffer, text, item_max_width, 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, 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 */ /* Center font nodes */
x = MENU_ITEM_PADDING_X; 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); (OSD_ITEM_WIDTH - 2 * OSD_ITEM_PADDING) * PANGO_SCALE);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
struct font font = { PangoFontDescription *desc = font_to_pango_desc(&rc.font_osd);
.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);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
PangoTabArray *tabs = pango_tab_array_new_with_positions(2, TRUE, PangoTabArray *tabs = pango_tab_array_new_with_positions(2, TRUE,
@ -323,19 +317,20 @@ osd_update(struct server *server)
y = OSD_BORDER_WIDTH; y = OSD_BORDER_WIDTH;
/* Center text entries on the y axis */ /* 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; y += y_offset;
if (show_workspace) { if (show_workspace) {
/* Center workspace indicator on the x axis */ /* 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; x = (OSD_ITEM_WIDTH - x) / 2;
cairo_move_to(cairo, x, y); cairo_move_to(cairo, x, y);
PangoWeight weight = pango_font_description_get_weight(desc);
pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
pango_layout_set_text(layout, server->workspace_current->name, -1); pango_layout_set_text(layout, server->workspace_current->name, -1);
pango_cairo_show_layout(cairo, layout); 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); pango_layout_set_font_description(layout, desc);
y += OSD_ITEM_HEIGHT; 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; struct ssd_state_title *state = &view->ssd.state.title;
bool title_unchanged = state->text && !strcmp(title, state->text); 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; float *text_color;
struct ssd_part *part; struct ssd_part *part;
struct ssd_sub_tree *subtree; struct ssd_sub_tree *subtree;
@ -261,8 +255,10 @@ ssd_update_title(struct view *view)
} }
if (part->buffer) { if (part->buffer) {
/* TODO: Do we only have active window fonts? */
scaled_font_buffer_update(part->buffer, title, 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 */ /* And finally update the cache */

View file

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

View file

@ -57,16 +57,12 @@ _osd_update(struct server *server)
uint16_t padding = 2; uint16_t padding = 2;
uint16_t rect_height = 20; uint16_t rect_height = 20;
uint16_t rect_width = 20; uint16_t rect_width = 20;
struct font font = {
.name = rc.font_name_osd,
.size = rc.font_size_osd,
};
/* Dimensions */ /* Dimensions */
size_t workspace_count = wl_list_length(&server->workspaces); size_t workspace_count = wl_list_length(&server->workspaces);
uint16_t marker_width = workspace_count * (rect_width + padding) - padding; uint16_t marker_width = workspace_count * (rect_width + padding) - padding;
uint16_t width = margin * 2 + (marker_width < 200 ? 200 : marker_width); 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_t *cairo;
cairo_surface_t *surface; 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_width(layout, (width - 2 * margin) * PANGO_SCALE);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
PangoFontDescription *desc = pango_font_description_new(); PangoFontDescription *desc = font_to_pango_desc(&rc.font_osd);
pango_font_description_set_family(desc, font.name);
pango_font_description_set_size(desc, font.size * PANGO_SCALE);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
/* Center workspace indicator on the x axis */ /* 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; x = (width - x) / 2;
cairo_move_to(cairo, x, margin * 2 + rect_height); cairo_move_to(cairo, x, margin * 2 + rect_height);
//pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); //pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);