Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: apk update && apk add meson wayland-dev musl-dev wayland-protocols gcc inih-dev cmocka-dev
run: apk update && apk add meson wayland-dev musl-dev wayland-protocols gcc inih-dev cmocka-dev freetype-dev
- name: Run tests
run: meson setup test && ninja -C test test

Expand All @@ -23,7 +23,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: apk update && apk add meson wayland-dev musl-dev wayland-protocols gcc inih-dev cmocka-dev clang19 clang19-extra-tools clang19-analyzer
run: apk update && apk add meson wayland-dev musl-dev wayland-protocols gcc inih-dev cmocka-dev freetype-dev clang19 clang19-extra-tools clang19-analyzer
- name: Run clang-analyzer
if: success() || failure()
run: scan-build meson setup clang-analyzer && scan-build --status-bugs ninja -C clang-analyzer
Expand Down
24 changes: 19 additions & 5 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ rt = cc.find_library('rt')
libm = cc.find_library('m')
seccomp = dependency('libseccomp', required: get_option('seccomp'))
inih = dependency('inih')
freetype2 = dependency('freetype2', required: get_option('text'))

sysconfdir = get_option('sysconfdir')
if not fs.is_absolute(sysconfdir)
sysconfdir = prefix / sysconfdir
endif

global_configuration_h = configuration_data({
'WOB_VERSION': '"@0@"'.format(meson.project_version()),
'WOB_ETC_CONFIG_FOLDER_PATH': '"@0@"'.format(sysconfdir),
})
configure_file(output: 'global_configuration.h', configuration: global_configuration_h)
global_configuration_h = configuration_data()

global_configuration_h.set_quoted('WOB_VERSION', meson.project_version())
global_configuration_h.set_quoted('WOB_ETC_CONFIG_FOLDER_PATH', sysconfdir)

wayland_scanner_code = generator(
wayland_scanner,
Expand Down Expand Up @@ -87,11 +87,23 @@ endforeach

wob_sources = ['src/main.c', 'src/image.c', 'src/log.c', 'src/color.c', 'src/config.c', 'src/wob.c', 'src/shm.c', wl_proto_src, wl_proto_headers]
wob_dependencies = [wayland_client, rt, inih, libm]

if seccomp.found()
wob_dependencies += seccomp
wob_sources += 'src/pledge_seccomp.c'
global_configuration_h.set('WOB_PLEDGE_ENABLED', 'true')
else
wob_sources += 'src/pledge.c'
global_configuration_h.set('WOB_PLEDGE_ENABLED', 'false')
endif

if freetype2.found()
wob_dependencies += freetype2
wob_sources += 'src/font_freetype.c'
global_configuration_h.set('WOB_TEXT_ENABLED', 'true')
else
wob_sources += 'src/font_stub.c'
global_configuration_h.set('WOB_TEXT_ENABLED', 'false')
endif

executable(
Expand Down Expand Up @@ -146,3 +158,5 @@ if get_option('systemd-unit-files').enabled()
)
install_data('etc/systemd/wob.socket', install_dir: systemd_unit_dir)
endif

configure_file(output: 'global_configuration.h', configuration: global_configuration_h)
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ option('man-pages', type: 'feature', value: 'auto', description: 'Generate and i
option('seccomp', type: 'feature', value: 'auto', description: 'Use seccomp on Linux')
option('tests', type: 'feature', value: 'auto', description: 'Build tests')
option('systemd-unit-files', type: 'feature', value: 'enabled', description: 'Install systemd unit files')
option('text', type: 'feature', value: 'auto', description: 'Build with freetype2 text rendering')
58 changes: 49 additions & 9 deletions src/color.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,32 @@

#include "color.h"

struct wob_color
wob_color_from_argb8888(uint32_t argb)
{
struct wob_color result = {
.a = (float) (argb >> 24 & 0xFF) / 255.0f,
.r = (float) (argb >> 16 & 0xFF) / 255.0f,
.g = (float) (argb >> 8 & 0xFF) / 255.0f,
.b = (float) (argb & 0xFF) / 255.0f,
};

return result;
}

struct wob_color
wob_color_blend_premultiplied(struct wob_color foreground, struct wob_color background)
{
struct wob_color result = {
.a = foreground.a + background.a * (1 - foreground.a),
.r = foreground.r + background.r * (1 - foreground.a),
.b = foreground.b + background.b * (1 - foreground.a),
.g = foreground.g + background.g * (1 - foreground.a),
};

return result;
}

uint32_t
wob_color_to_argb(const struct wob_color color)
{
Expand Down Expand Up @@ -63,22 +89,36 @@ bool
wob_color_from_rgba_string(const char *str, struct wob_color *color)
{
unsigned long length = strlen(str);
for (const char *c = str; *c != '\0'; ++c) {
if (!isxdigit(*c)) {
return false;
}
}

uint8_t parts[4];
parts[3] = 0xFF;
switch (length) {
case 8:
parts[3] = hex_to_int(str[6]) * 16 + hex_to_int(str[7]);
int p6 = hex_to_int(str[6]);
int p7 = hex_to_int(str[7]);

if (p6 < 0 || p7 < 0) {
return false;
}

parts[3] = p6 * 16 + p7;
// fallthrough
case 6:
parts[0] = hex_to_int(str[0]) * 16 + hex_to_int(str[1]);
parts[1] = hex_to_int(str[2]) * 16 + hex_to_int(str[3]);
parts[2] = hex_to_int(str[4]) * 16 + hex_to_int(str[5]);
int p0 = hex_to_int(str[0]);
int p1 = hex_to_int(str[1]);
int p2 = hex_to_int(str[2]);
int p3 = hex_to_int(str[3]);
int p4 = hex_to_int(str[4]);
int p5 = hex_to_int(str[5]);

if (p0 < 0 || p1 < 0 || p2 < 0 || p3 < 0 || p4 < 0 || p5 < 0) {
return false;
}

parts[0] = p0 * 16 + p1;
parts[1] = p2 * 16 + p3;
parts[2] = p4 * 16 + p5;

break;
default:
return false;
Expand Down
4 changes: 4 additions & 0 deletions src/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ struct wob_color {
float b;
};

struct wob_color wob_color_from_argb8888(uint32_t argb);

struct wob_color wob_color_blend_premultiplied(struct wob_color foreground, struct wob_color background);

uint32_t wob_color_to_argb(struct wob_color color);

uint32_t wob_color_to_rgba(struct wob_color color);
Expand Down
32 changes: 31 additions & 1 deletion src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,18 @@ handler(void *user, const char *section, const char *name, const char *value)
}
return 1;
}
if (strcmp(name, "font") == 0) {
config->font_path = strdup(value);
return 1;
}
if (strcmp(name, "font_size") == 0) {
if (parse_number(value, &ul) == false) {
wob_log_error("Font size must be a positive value.");
return 0;
}
config->font_size = ul;
return 1;
}

wob_log_warn("Unknown config key %s", name);
return 1;
Expand Down Expand Up @@ -389,6 +401,14 @@ handler(void *user, const char *section, const char *name, const char *value)
output_config->dimensions.bar_padding = ul;
return 1;
}
if (strcmp(name, "font_size") == 0) {
if (parse_number(value, &ul) == false) {
wob_log_error("Font size must be a positive value.");
return 0;
}
output_config->font_size = ul;
return 1;
}

wob_log_warn("Unknown config key %s", name);
return 1;
Expand Down Expand Up @@ -512,6 +532,8 @@ wob_config_create()
config->margin = (struct wob_margin) {.top = 0, .left = 0, .bottom = 0, .right = 0};
config->anchor = WOB_ANCHOR_CENTER;
config->overflow_mode = WOB_OVERFLOW_MODE_WRAP;
config->font_path = NULL;
config->font_size = 16;
config->default_style.colors.background = (struct wob_color) {.a = 1.0f, .r = 0.0f, .g = 0.0f, .b = 0.0f};
config->default_style.colors.value = (struct wob_color) {.a = 1.0f, .r = 1.0f, .g = 1.0f, .b = 1.0f};
config->default_style.colors.border = (struct wob_color) {.a = 1.0f, .r = 1.0f, .g = 1.0f, .b = 1.0f};
Expand Down Expand Up @@ -585,6 +607,8 @@ wob_config_debug(struct wob_config *config)
wob_log_debug("config.overflow_colors.background = " WOB_COLOR_PRINTF_FORMAT, WOB_COLOR_PRINTF_RGBA(config->default_style.overflow_colors.background));
wob_log_debug("config.overflow_colors.value = " WOB_COLOR_PRINTF_FORMAT, WOB_COLOR_PRINTF_RGBA(config->default_style.overflow_colors.value));
wob_log_debug("config.overflow_colors.border = " WOB_COLOR_PRINTF_FORMAT, WOB_COLOR_PRINTF_RGBA(config->default_style.overflow_colors.border));
wob_log_debug("config.font = %s", config->font_path != NULL ? config->font_path : "<empty>");
wob_log_debug("config.font_size = %d", config->font_size);

struct wob_style *style;
wl_list_for_each (style, &config->styles, link) {
Expand Down Expand Up @@ -615,6 +639,7 @@ wob_config_debug(struct wob_config *config)
WOB_ORIENTATION_HORIZONTAL,
WOB_ORIENTATION_VERTICAL
);
wob_log_debug("config.output.%s.font_size = %d", output_config->id, output_config->font_size);
}
}

Expand All @@ -634,6 +659,10 @@ wob_config_destroy(struct wob_config *config)
free(style);
}

if (config->font_path != NULL) {
free(config->font_path);
}

free(config);
}

Expand Down Expand Up @@ -683,7 +712,8 @@ wob_config_match_output(struct wob_config *config, const char *match)
struct wob_output_config *output_config = NULL;
bool output_found = false;
wl_list_for_each (output_config, &config->outputs, link) {
if (strstr(output_config->match, match) == 0) {
wob_log_debug("%s = %s?", output_config->match, match);
if (strstr(match, output_config->match) != NULL) {
output_found = true;
break;
}
Expand Down
3 changes: 3 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct wob_output_config {
struct wob_dimensions dimensions;
struct wob_margin margin;
unsigned long anchor;
unsigned long font_size;
};

struct wob_colors {
Expand All @@ -79,6 +80,8 @@ struct wob_config {
struct wl_list styles;
struct wl_list outputs;
bool sandbox;
char *font_path;
unsigned long font_size;
};

struct wob_config *wob_config_create();
Expand Down
32 changes: 32 additions & 0 deletions src/font.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef FONT_H
#define FONT_H

#include <stddef.h>

#include "color.h"
#include "config.h"

struct wob_font_manager;

struct wob_font;

struct wob_font_text_dimensions {
int w;
int h;
};

struct wob_font_manager *wob_font_manager_create();

void wob_font_manager_destroy(struct wob_font_manager *);

void wob_font_manager_load_font(struct wob_font_manager *, const char *fpath);

void wob_font_manager_load_fonts_from_config(struct wob_font_manager *, struct wob_config *);

struct wob_font *wob_font_manager_get(struct wob_font_manager *, const char *fpath);

void wob_font_render_text(struct wob_font *font, char *text, int font_size, struct wob_color font_color, uint32_t *argb8888_buffer, size_t argb8888_buffer_size);

struct wob_font_text_dimensions wob_font_render_text_dimensions(struct wob_font *font, char *text, int font_size);

#endif
Loading