From 2297e43cc0d6a6d85523ea897825ee2052fe1df2 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 5 Aug 2020 20:14:17 +0100 Subject: [PATCH] Base rc.title_height on font vertical extents --- include/common/font.h | 10 ++++++++++ include/config/rcxml.h | 1 + meson.build | 12 +++++++----- src/common/font.c | 41 +++++++++++++++++++++++++++++++++++++++ src/common/meson.build | 1 + src/config/rcxml.c | 11 +++++++++++ src/deco.c | 38 ++++++++++++++++++------------------ tests/meson.build | 5 +++-- tools/pango/.gitignore | 2 ++ tools/pango/Makefile | 15 ++++++++++++++ tools/pango/font-height.c | 13 +++++++++++++ 11 files changed, 123 insertions(+), 26 deletions(-) create mode 100644 include/common/font.h create mode 100644 src/common/font.c create mode 100644 tools/pango/.gitignore create mode 100644 tools/pango/Makefile create mode 100644 tools/pango/font-height.c diff --git a/include/common/font.h b/include/common/font.h new file mode 100644 index 00000000..04f99f09 --- /dev/null +++ b/include/common/font.h @@ -0,0 +1,10 @@ +#ifndef __LABWC_FONT_H +#define __LABWC_FONT_H + +/* + * font_height - get font vertical extents + * @font_description: string describing font, for example 'sans 10' + */ +int font_height(const char *font_description); + +#endif /* __LABWC_FONT_H */ diff --git a/include/config/rcxml.h b/include/config/rcxml.h index 0b5484a5..45a7caf3 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -13,6 +13,7 @@ struct rcxml { char *font_name_activewindow; int font_size_activewindow; struct wl_list keybinds; + int title_height; /* not set in rc.xml, but derived from font, etc */ }; extern struct rcxml rc; diff --git a/meson.build b/meson.build index 49ee4ef2..a4db297a 100644 --- a/meson.build +++ b/meson.build @@ -43,19 +43,21 @@ xkbcommon = dependency('xkbcommon') xml2 = dependency('libxml-2.0') glib = dependency('glib-2.0') cairo = dependency('cairo') -pango = dependency('pango') +pangocairo = dependency('pangocairo') labwc_inc = include_directories('include') subdir('protocols') + +labwc_deps = [ + server_protos, wayland_server, wlroots, xkbcommon, xml2, glib, + cairo, pangocairo +] + subdir('src') subdir('tests') subdir('docs') -labwc_deps = [ - server_protos, wayland_server, wlroots, xkbcommon, xml2, glib, cairo, pango -] - executable( meson.project_name(), labwc_sources, diff --git a/src/common/font.c b/src/common/font.c new file mode 100644 index 00000000..acf49752 --- /dev/null +++ b/src/common/font.c @@ -0,0 +1,41 @@ +#include +#include + +#include "common/font.h" + +static PangoRectangle font_extents(const char *font_description, + const char *string) +{ + PangoRectangle rect; + cairo_surface_t *surface; + cairo_t *c; + PangoLayout *layout; + PangoFontDescription *font; + + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); + c = cairo_create(surface); + layout = pango_cairo_create_layout(c); + font = pango_font_description_from_string(font_description); + + pango_layout_set_font_description(layout, font); + pango_layout_set_text(layout, string, -1); + pango_layout_set_single_paragraph_mode(layout, TRUE); + pango_layout_set_width(layout, -1); + pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_MIDDLE); + pango_layout_get_extents(layout, NULL, &rect); + pango_extents_to_pixels(&rect, NULL); + + /* we put a 2 px edge on each side - because Openbox does it :) */ + rect.width += 4; + + g_object_unref(layout); + pango_font_description_free(font); + return rect; +} + +int font_height(const char *font_description) +{ + PangoRectangle rectangle; + rectangle = font_extents(font_description, "abcdefg"); + return rectangle.height; +} diff --git a/src/common/meson.build b/src/common/meson.build index 36446b59..fe8e710d 100644 --- a/src/common/meson.build +++ b/src/common/meson.build @@ -1,4 +1,5 @@ labwc_sources += files( 'buf.c', + 'font.c', 'spawn.c', ) diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 8f25bf3c..b5c86842 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -14,6 +14,7 @@ #include "config/keybind.h" #include "config/config-dir.h" #include "common/bug-on.h" +#include "common/font.h" static bool in_keybind = false; static bool is_attribute = false; @@ -232,6 +233,14 @@ static void bind(const char *binding, const char *action) fprintf(stderr, "binding: %s: %s\n", binding, action); } +static void set_title_height(void) +{ + char buf[256]; + snprintf(buf, sizeof(buf), "%s %d", rc.font_name_activewindow, + rc.font_size_activewindow); + rc.title_height = font_height(buf); +} + static void post_processing(void) { if (!wl_list_length(&rc.keybinds)) { @@ -241,6 +250,8 @@ static void post_processing(void) bind("A-F3", "Execute"); } /* TODO: Set all char* variables if NULL */ + + set_title_height(); } static void rcxml_path(char *buf, size_t len, const char *filename) diff --git a/src/deco.c b/src/deco.c index d5a64ad6..50a4c332 100644 --- a/src/deco.c +++ b/src/deco.c @@ -6,18 +6,18 @@ #include "labwc.h" #include "theme/theme.h" +#include "config/rcxml.h" /* Based on expected font height of Sans 8 */ -#define TITLE_HEIGHT (14) #define BORDER_WIDTH (1) struct wlr_box deco_max_extents(struct view *view) { struct wlr_box box = { .x = view->x - BORDER_WIDTH, - .y = view->y - TITLE_HEIGHT - BORDER_WIDTH, + .y = view->y - rc.title_height - BORDER_WIDTH, .width = view->surface->current.width + 2 * BORDER_WIDTH, - .height = view->surface->current.height + TITLE_HEIGHT + + .height = view->surface->current.height + rc.title_height + 2 * BORDER_WIDTH, }; return box; @@ -33,44 +33,44 @@ struct wlr_box deco_box(struct view *view, enum deco_part deco_part) switch (deco_part) { case LAB_DECO_BUTTON_CLOSE: wlr_texture_get_size(theme.xbm_close, &box.width, &box.height); - margin = (TITLE_HEIGHT - box.height) / 2; + margin = (rc.title_height - box.height) / 2; box.x = view->x + view->surface->current.width + margin - - TITLE_HEIGHT; - box.y = view->y - TITLE_HEIGHT + margin; + rc.title_height; + box.y = view->y - rc.title_height + margin; break; case LAB_DECO_BUTTON_MAXIMIZE: wlr_texture_get_size(theme.xbm_maximize, &box.width, &box.height); - margin = (TITLE_HEIGHT - box.height) / 2; + margin = (rc.title_height - box.height) / 2; box.x = view->x + view->surface->current.width + margin - - TITLE_HEIGHT * 2; - box.y = view->y - TITLE_HEIGHT + margin; + rc.title_height * 2; + box.y = view->y - rc.title_height + margin; break; case LAB_DECO_BUTTON_ICONIFY: wlr_texture_get_size(theme.xbm_iconify, &box.width, &box.height); - margin = (TITLE_HEIGHT - box.height) / 2; + margin = (rc.title_height - box.height) / 2; box.x = view->x + view->surface->current.width + margin - - TITLE_HEIGHT * 3; - box.y = view->y - TITLE_HEIGHT + margin; + rc.title_height * 3; + box.y = view->y - rc.title_height + margin; break; case LAB_DECO_PART_TITLE: box.x = view->x; - box.y = view->y - TITLE_HEIGHT; + box.y = view->y - rc.title_height; box.width = view->surface->current.width; - box.height = TITLE_HEIGHT; + box.height = rc.title_height; break; case LAB_DECO_PART_TOP: box.x = view->x - BORDER_WIDTH; - box.y = view->y - TITLE_HEIGHT - BORDER_WIDTH; + box.y = view->y - rc.title_height - BORDER_WIDTH; box.width = view->surface->current.width + 2 * BORDER_WIDTH; box.height = BORDER_WIDTH; break; case LAB_DECO_PART_RIGHT: box.x = view->x + view->surface->current.width; - box.y = view->y - TITLE_HEIGHT; + box.y = view->y - rc.title_height; box.width = BORDER_WIDTH; - box.height = view->surface->current.height + TITLE_HEIGHT; + box.height = view->surface->current.height + rc.title_height; break; case LAB_DECO_PART_BOTTOM: box.x = view->x - BORDER_WIDTH; @@ -80,9 +80,9 @@ struct wlr_box deco_box(struct view *view, enum deco_part deco_part) break; case LAB_DECO_PART_LEFT: box.x = view->x - BORDER_WIDTH; - box.y = view->y - TITLE_HEIGHT; + box.y = view->y - rc.title_height; box.width = BORDER_WIDTH; - box.height = view->surface->current.height + TITLE_HEIGHT; + box.height = view->surface->current.height + rc.title_height; break; default: break; diff --git a/tests/meson.build b/tests/meson.build index de7d3087..eedb43a9 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -4,9 +4,10 @@ rcxml_lib = static_library( '../src/config/rcxml.c', '../src/config/keybind.c', '../src/config/config-dir.c', - '../src/common/buf.c' + '../src/common/buf.c', + '../src/common/font.c', ), - dependencies: [xml2, wayland_server, xkbcommon, glib, wlroots], + dependencies: labwc_deps, include_directories: [labwc_inc], ) diff --git a/tools/pango/.gitignore b/tools/pango/.gitignore new file mode 100644 index 00000000..583e383c --- /dev/null +++ b/tools/pango/.gitignore @@ -0,0 +1,2 @@ +*.o +font-height diff --git a/tools/pango/Makefile b/tools/pango/Makefile new file mode 100644 index 00000000..88ab215f --- /dev/null +++ b/tools/pango/Makefile @@ -0,0 +1,15 @@ +CFLAGS += -g -Wall -O0 -std=c11 +CFLAGS += `pkg-config cairo pango pangocairo --cflags` +CFLAGS += -I../../include +LIBS += `pkg-config cairo pango pangocairo --libs` +LDFLAGS += $(LIBS) + +PROGS = font-height + +all: $(PROGS) + +font-height: font-height.c ../../src/common/font.c + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +clean: + rm -f $(PROGS) *.o diff --git a/tools/pango/font-height.c b/tools/pango/font-height.c new file mode 100644 index 00000000..24690f53 --- /dev/null +++ b/tools/pango/font-height.c @@ -0,0 +1,13 @@ +#include +#include + +#include "common/font.h" + +int main(int argc, char **argv) +{ + if (argc < 2) { + printf("Usage: %s (e.g. 'sans 10')\n", argv[0]); + exit(1); + } + printf("height=%d\n", font_height(argv[1])); +}