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>*
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><keybind key="">*

View file

@ -19,9 +19,24 @@
<theme>
<name></name>
<cornerRadius>8</cornerRadius>
<font place="ActiveWindow"><name>sans</name><size>10</size></font>
<font place="MenuItem"><name>sans</name><size>10</size></font>
<font place="OSD"><name>sans</name><size>10</size></font>
<font place="ActiveWindow">
<name>sans</name>
<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>
<!-- edge strength is in pixels -->

View file

@ -4,11 +4,25 @@
struct lab_data_buffer;
enum font_slant {
FONT_SLANT_NORMAL,
FONT_SLANT_ITALIC
};
enum font_weight {
FONT_WEIGHT_NORMAL,
FONT_WEIGHT_BOLD
};
struct font {
char *name;
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: description of font including family name and size

View file

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

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);