diff --git a/common/cairo.c b/common/cairo.c index c267c77ca..e8231484d 100644 --- a/common/cairo.c +++ b/common/cairo.c @@ -13,6 +13,22 @@ void cairo_set_source_u32(cairo_t *cairo, uint32_t color) { (color >> (0*8) & 0xFF) / 255.0); } +cairo_subpixel_order_t to_cairo_subpixel_order(enum wl_output_subpixel subpixel) { + switch (subpixel) { + case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB: + return CAIRO_SUBPIXEL_ORDER_RGB; + case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR: + return CAIRO_SUBPIXEL_ORDER_BGR; + case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB: + return CAIRO_SUBPIXEL_ORDER_VRGB; + case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR: + return CAIRO_SUBPIXEL_ORDER_VBGR; + default: + return CAIRO_SUBPIXEL_ORDER_DEFAULT; + } + return CAIRO_SUBPIXEL_ORDER_DEFAULT; +} + cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image, int width, int height) { int image_width = cairo_image_surface_get_width(image); diff --git a/include/cairo.h b/include/cairo.h index 316727059..86530b605 100644 --- a/include/cairo.h +++ b/include/cairo.h @@ -2,8 +2,10 @@ #define _SWAY_CAIRO_H #include #include +#include void cairo_set_source_u32(cairo_t *cairo, uint32_t color); +cairo_subpixel_order_t to_cairo_subpixel_order(enum wl_output_subpixel subpixel); cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image, int width, int height); diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h index 4065fb8bd..29e961592 100644 --- a/include/swaybar/bar.h +++ b/include/swaybar/bar.h @@ -81,6 +81,7 @@ struct swaybar_output { uint32_t width, height; int32_t scale; + enum wl_output_subpixel subpixel; struct pool_buffer buffers[2]; struct pool_buffer *current_buffer; }; diff --git a/include/swaylock/swaylock.h b/include/swaylock/swaylock.h index 950cfaafa..2f0cd34db 100644 --- a/include/swaylock/swaylock.h +++ b/include/swaylock/swaylock.h @@ -82,6 +82,7 @@ struct swaylock_surface { bool frame_pending, dirty; uint32_t width, height; int32_t scale; + enum wl_output_subpixel subpixel; char *output_name; struct wl_list link; }; diff --git a/sway/tree/container.c b/sway/tree/container.c index 476877449..8dc22410c 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -465,11 +465,17 @@ static void update_title_texture(struct sway_container *con, cairo_surface_t *surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height); cairo_t *cairo = cairo_create(surface); + cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); + cairo_font_options_t *fo = cairo_font_options_create(); + cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); + cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); + cairo_font_options_set_subpixel_order(fo, to_cairo_subpixel_order(output->wlr_output->subpixel)); + cairo_set_font_options(cairo, fo); + cairo_font_options_destroy(fo); cairo_set_source_rgba(cairo, class->background[0], class->background[1], class->background[2], class->background[3]); cairo_paint(cairo); PangoContext *pango = pango_cairo_create_context(cairo); - cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); cairo_set_source_rgba(cairo, class->text[0], class->text[1], class->text[2], class->text[3]); cairo_move_to(cairo, 0, 0); diff --git a/swaybar/bar.c b/swaybar/bar.c index 69069f408..ab307fd41 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -319,10 +319,14 @@ static bool bar_uses_output(struct swaybar *bar, const char *name) { return false; } -static void output_geometry(void *data, struct wl_output *output, int32_t x, +static void output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char *make, const char *model, int32_t transform) { - // Who cares + struct swaybar_output *output = data; + output->subpixel = subpixel; + if (output->surface) { + render_frame(output->bar, output); + } } static void output_mode(void *data, struct wl_output *output, uint32_t flags, diff --git a/swaybar/render.c b/swaybar/render.c index 26db80cbe..9413dc57b 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -495,6 +495,13 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) { cairo_surface_t *recorder = cairo_recording_surface_create( CAIRO_CONTENT_COLOR_ALPHA, NULL); cairo_t *cairo = cairo_create(recorder); + cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); + cairo_font_options_t *fo = cairo_font_options_create(); + cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); + cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); + cairo_font_options_set_subpixel_order(fo, to_cairo_subpixel_order(output->subpixel)); + cairo_set_font_options(cairo, fo); + cairo_font_options_destroy(fo); cairo_save(cairo); cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); cairo_paint(cairo); diff --git a/swaylock/main.c b/swaylock/main.c index 668a87427..c25c8eec8 100644 --- a/swaylock/main.c +++ b/swaylock/main.c @@ -195,11 +195,15 @@ void damage_state(struct swaylock_state *state) { } } -static void handle_wl_output_geometry(void *data, struct wl_output *output, +static void handle_wl_output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char *make, const char *model, int32_t transform) { - // Who cares + struct swaylock_surface *surface = data; + surface->subpixel = subpixel; + if (surface->state->run_display) { + damage_surface(surface); + } } static void handle_wl_output_mode(void *data, struct wl_output *output, diff --git a/swaylock/render.c b/swaylock/render.c index 66c55965d..fa8832bd1 100644 --- a/swaylock/render.c +++ b/swaylock/render.c @@ -39,6 +39,13 @@ void render_frame(struct swaylock_surface *surface) { } cairo_t *cairo = surface->current_buffer->cairo; + cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); + cairo_font_options_t *fo = cairo_font_options_create(); + cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); + cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); + cairo_font_options_set_subpixel_order(fo, to_cairo_subpixel_order(surface->subpixel)); + cairo_set_font_options(cairo, fo); + cairo_font_options_destroy(fo); cairo_identity_matrix(cairo); cairo_save(cairo);