aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/render.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/render.c')
-rw-r--r--swaybar/render.c134
1 files changed, 98 insertions, 36 deletions
diff --git a/swaybar/render.c b/swaybar/render.c
index df066622..fcc8be1d 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -5,7 +5,7 @@
5#include <stdlib.h> 5#include <stdlib.h>
6#include <stdint.h> 6#include <stdint.h>
7#include <string.h> 7#include <string.h>
8#include "cairo.h" 8#include "cairo_util.h"
9#include "pango.h" 9#include "pango.h"
10#include "pool-buffer.h" 10#include "pool-buffer.h"
11#include "swaybar/bar.h" 11#include "swaybar/bar.h"
@@ -23,8 +23,31 @@ static const int WS_HORIZONTAL_PADDING = 5;
23static const double WS_VERTICAL_PADDING = 1.5; 23static const double WS_VERTICAL_PADDING = 1.5;
24static const double BORDER_WIDTH = 1; 24static const double BORDER_WIDTH = 1;
25 25
26static uint32_t render_status_line_error(cairo_t *cairo, 26struct render_context {
27 struct swaybar_output *output, double *x) { 27 cairo_t *cairo;
28 struct swaybar_output *output;
29 cairo_font_options_t *textaa_sharp;
30 cairo_font_options_t *textaa_safe;
31 uint32_t background_color;
32};
33
34static void choose_text_aa_mode(struct render_context *ctx, uint32_t fontcolor) {
35 uint32_t salpha = fontcolor & 0xFF;
36 uint32_t balpha = ctx->background_color & 0xFF;
37
38 // Subpixel antialiasing requires blend be done in cairo, not compositor
39 cairo_font_options_t *fo = salpha == balpha ?
40 ctx->textaa_sharp : ctx->textaa_safe;
41 cairo_set_font_options(ctx->cairo, fo);
42
43 // Color emojis, being semitransparent bitmaps, are leaky with 'SOURCE'
44 cairo_operator_t op = salpha == 0xFF ?
45 CAIRO_OPERATOR_OVER : CAIRO_OPERATOR_SOURCE;
46 cairo_set_operator(ctx->cairo, op);
47}
48
49static uint32_t render_status_line_error(struct render_context *ctx, double *x) {
50 struct swaybar_output *output = ctx->output;
28 const char *error = output->bar->status->text; 51 const char *error = output->bar->status->text;
29 if (!error) { 52 if (!error) {
30 return 0; 53 return 0;
@@ -32,6 +55,7 @@ static uint32_t render_status_line_error(cairo_t *cairo,
32 55
33 uint32_t height = output->height * output->scale; 56 uint32_t height = output->height * output->scale;
34 57
58 cairo_t *cairo = ctx->cairo;
35 cairo_set_source_u32(cairo, 0xFF0000FF); 59 cairo_set_source_u32(cairo, 0xFF0000FF);
36 60
37 int margin = 3 * output->scale; 61 int margin = 3 * output->scale;
@@ -53,21 +77,24 @@ static uint32_t render_status_line_error(cairo_t *cairo,
53 77
54 double text_y = height / 2.0 - text_height / 2.0; 78 double text_y = height / 2.0 - text_height / 2.0;
55 cairo_move_to(cairo, *x, (int)floor(text_y)); 79 cairo_move_to(cairo, *x, (int)floor(text_y));
80 choose_text_aa_mode(ctx, 0xFF0000FF);
56 pango_printf(cairo, font, output->scale, false, "%s", error); 81 pango_printf(cairo, font, output->scale, false, "%s", error);
57 *x -= margin; 82 *x -= margin;
58 return output->height; 83 return output->height;
59} 84}
60 85
61static uint32_t render_status_line_text(cairo_t *cairo, 86static uint32_t render_status_line_text(struct render_context *ctx, double *x) {
62 struct swaybar_output *output, double *x) { 87 struct swaybar_output *output = ctx->output;
63 const char *text = output->bar->status->text; 88 const char *text = output->bar->status->text;
64 if (!text) { 89 if (!text) {
65 return 0; 90 return 0;
66 } 91 }
67 92
93 cairo_t *cairo = ctx->cairo;
68 struct swaybar_config *config = output->bar->config; 94 struct swaybar_config *config = output->bar->config;
69 cairo_set_source_u32(cairo, output->focused ? 95 uint32_t fontcolor = output->focused ?
70 config->colors.focused_statusline : config->colors.statusline); 96 config->colors.focused_statusline : config->colors.statusline;
97 cairo_set_source_u32(cairo, fontcolor);
71 98
72 int text_width, text_height; 99 int text_width, text_height;
73 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 100 get_text_size(cairo, config->font, &text_width, &text_height, NULL,
@@ -87,6 +114,7 @@ static uint32_t render_status_line_text(cairo_t *cairo,
87 uint32_t height = output->height * output->scale; 114 uint32_t height = output->height * output->scale;
88 double text_y = height / 2.0 - text_height / 2.0; 115 double text_y = height / 2.0 - text_height / 2.0;
89 cairo_move_to(cairo, *x, (int)floor(text_y)); 116 cairo_move_to(cairo, *x, (int)floor(text_y));
117 choose_text_aa_mode(ctx, fontcolor);
90 pango_printf(cairo, config->font, output->scale, 118 pango_printf(cairo, config->font, output->scale,
91 config->pango_markup, "%s", text); 119 config->pango_markup, "%s", text);
92 *x -= margin; 120 *x -= margin;
@@ -96,6 +124,7 @@ static uint32_t render_status_line_text(cairo_t *cairo,
96static void render_sharp_rectangle(cairo_t *cairo, uint32_t color, 124static void render_sharp_rectangle(cairo_t *cairo, uint32_t color,
97 double x, double y, double width, double height) { 125 double x, double y, double width, double height) {
98 cairo_save(cairo); 126 cairo_save(cairo);
127 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
99 cairo_set_source_u32(cairo, color); 128 cairo_set_source_u32(cairo, color);
100 cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); 129 cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE);
101 cairo_rectangle(cairo, x, y, width, height); 130 cairo_rectangle(cairo, x, y, width, height);
@@ -109,6 +138,7 @@ static void render_sharp_line(cairo_t *cairo, uint32_t color,
109 render_sharp_rectangle(cairo, color, x, y, width, height); 138 render_sharp_rectangle(cairo, color, x, y, width, height);
110 } else { 139 } else {
111 cairo_save(cairo); 140 cairo_save(cairo);
141 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
112 cairo_set_source_u32(cairo, color); 142 cairo_set_source_u32(cairo, color);
113 cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); 143 cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE);
114 if (width == 1) { 144 if (width == 1) {
@@ -146,9 +176,8 @@ static void i3bar_block_unref_callback(void *data) {
146 i3bar_block_unref(data); 176 i3bar_block_unref(data);
147} 177}
148 178
149static uint32_t render_status_block(cairo_t *cairo, 179static uint32_t render_status_block(struct render_context *ctx,
150 struct swaybar_output *output, struct i3bar_block *block, double *x, 180 struct i3bar_block *block, double *x, bool edge, bool use_short_text) {
151 bool edge, bool use_short_text) {
152 if (!block->full_text || !*block->full_text) { 181 if (!block->full_text || !*block->full_text) {
153 return 0; 182 return 0;
154 } 183 }
@@ -158,8 +187,9 @@ static uint32_t render_status_block(cairo_t *cairo,
158 text = block->short_text; 187 text = block->short_text;
159 } 188 }
160 189
190 cairo_t *cairo = ctx->cairo;
191 struct swaybar_output *output = ctx->output;
161 struct swaybar_config *config = output->bar->config; 192 struct swaybar_config *config = output->bar->config;
162
163 int text_width, text_height; 193 int text_width, text_height;
164 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 194 get_text_size(cairo, config->font, &text_width, &text_height, NULL,
165 output->scale, block->markup, "%s", text); 195 output->scale, block->markup, "%s", text);
@@ -240,6 +270,7 @@ static uint32_t render_status_block(cairo_t *cairo,
240 if (bg_color) { 270 if (bg_color) {
241 render_sharp_rectangle(cairo, bg_color, x_pos, y_pos, 271 render_sharp_rectangle(cairo, bg_color, x_pos, y_pos,
242 block_width, render_height); 272 block_width, render_height);
273 ctx->background_color = bg_color;
243 } 274 }
244 275
245 uint32_t border_color = block->urgent 276 uint32_t border_color = block->urgent
@@ -274,6 +305,7 @@ static uint32_t render_status_block(cairo_t *cairo,
274 color = block->color_set ? block->color : color; 305 color = block->color_set ? block->color : color;
275 color = block->urgent ? config->colors.urgent_workspace.text : color; 306 color = block->urgent ? config->colors.urgent_workspace.text : color;
276 cairo_set_source_u32(cairo, color); 307 cairo_set_source_u32(cairo, color);
308 choose_text_aa_mode(ctx, color);
277 pango_printf(cairo, config->font, output->scale, 309 pango_printf(cairo, config->font, output->scale,
278 block->markup, "%s", text); 310 block->markup, "%s", text);
279 x_pos += width; 311 x_pos += width;
@@ -287,17 +319,20 @@ static uint32_t render_status_block(cairo_t *cairo,
287 319
288 if (!edge && block->separator) { 320 if (!edge && block->separator) {
289 if (output->focused) { 321 if (output->focused) {
290 cairo_set_source_u32(cairo, config->colors.focused_separator); 322 color = config->colors.focused_separator;
291 } else { 323 } else {
292 cairo_set_source_u32(cairo, config->colors.separator); 324 color = config->colors.separator;
293 } 325 }
326 cairo_set_source_u32(cairo, color);
294 if (config->sep_symbol) { 327 if (config->sep_symbol) {
295 offset = x_pos + (sep_block_width - sep_width) / 2; 328 offset = x_pos + (sep_block_width - sep_width) / 2;
296 double sep_y = height / 2.0 - sep_height / 2.0; 329 double sep_y = height / 2.0 - sep_height / 2.0;
297 cairo_move_to(cairo, offset, (int)floor(sep_y)); 330 cairo_move_to(cairo, offset, (int)floor(sep_y));
331 choose_text_aa_mode(ctx, color);
298 pango_printf(cairo, config->font, output->scale, false, 332 pango_printf(cairo, config->font, output->scale, false,
299 "%s", config->sep_symbol); 333 "%s", config->sep_symbol);
300 } else { 334 } else {
335 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
301 cairo_set_line_width(cairo, 1); 336 cairo_set_line_width(cairo, 1);
302 cairo_move_to(cairo, x_pos + sep_block_width / 2, margin); 337 cairo_move_to(cairo, x_pos + sep_block_width / 2, margin);
303 cairo_line_to(cairo, x_pos + sep_block_width / 2, height - margin); 338 cairo_line_to(cairo, x_pos + sep_block_width / 2, height - margin);
@@ -459,13 +494,14 @@ static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo,
459 return width; 494 return width;
460} 495}
461 496
462static uint32_t render_status_line_i3bar(cairo_t *cairo, 497static uint32_t render_status_line_i3bar(struct render_context *ctx, double *x) {
463 struct swaybar_output *output, double *x) { 498 struct swaybar_output *output = ctx->output;
464 uint32_t max_height = 0; 499 uint32_t max_height = 0;
465 bool edge = *x == output->width * output->scale; 500 bool edge = *x == output->width * output->scale;
466 struct i3bar_block *block; 501 struct i3bar_block *block;
467 bool use_short_text = false; 502 bool use_short_text = false;
468 503
504 cairo_t *cairo = ctx->cairo;
469 double reserved_width = 505 double reserved_width =
470 predict_workspace_buttons_length(cairo, output) + 506 predict_workspace_buttons_length(cairo, output) +
471 predict_binding_mode_indicator_length(cairo, output) + 507 predict_binding_mode_indicator_length(cairo, output) +
@@ -479,7 +515,7 @@ static uint32_t render_status_line_i3bar(cairo_t *cairo,
479 } 515 }
480 516
481 wl_list_for_each(block, &output->bar->status->blocks, link) { 517 wl_list_for_each(block, &output->bar->status->blocks, link) {
482 uint32_t h = render_status_block(cairo, output, block, x, edge, 518 uint32_t h = render_status_block(ctx, block, x, edge,
483 use_short_text); 519 use_short_text);
484 max_height = h > max_height ? h : max_height; 520 max_height = h > max_height ? h : max_height;
485 edge = false; 521 edge = false;
@@ -487,29 +523,30 @@ static uint32_t render_status_line_i3bar(cairo_t *cairo,
487 return max_height; 523 return max_height;
488} 524}
489 525
490static uint32_t render_status_line(cairo_t *cairo, 526static uint32_t render_status_line(struct render_context *ctx, double *x) {
491 struct swaybar_output *output, double *x) { 527 struct status_line *status = ctx->output->bar->status;
492 struct status_line *status = output->bar->status;
493 switch (status->protocol) { 528 switch (status->protocol) {
494 case PROTOCOL_ERROR: 529 case PROTOCOL_ERROR:
495 return render_status_line_error(cairo, output, x); 530 return render_status_line_error(ctx, x);
496 case PROTOCOL_TEXT: 531 case PROTOCOL_TEXT:
497 return render_status_line_text(cairo, output, x); 532 return render_status_line_text(ctx, x);
498 case PROTOCOL_I3BAR: 533 case PROTOCOL_I3BAR:
499 return render_status_line_i3bar(cairo, output, x); 534 return render_status_line_i3bar(ctx, x);
500 case PROTOCOL_UNDEF: 535 case PROTOCOL_UNDEF:
501 return 0; 536 return 0;
502 } 537 }
503 return 0; 538 return 0;
504} 539}
505 540
506static uint32_t render_binding_mode_indicator(cairo_t *cairo, 541static uint32_t render_binding_mode_indicator(struct render_context *ctx,
507 struct swaybar_output *output, double x) { 542 double x) {
543 struct swaybar_output *output = ctx->output;
508 const char *mode = output->bar->mode; 544 const char *mode = output->bar->mode;
509 if (!mode) { 545 if (!mode) {
510 return 0; 546 return 0;
511 } 547 }
512 548
549 cairo_t *cairo = ctx->cairo;
513 struct swaybar_config *config = output->bar->config; 550 struct swaybar_config *config = output->bar->config;
514 int text_width, text_height; 551 int text_width, text_height;
515 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 552 get_text_size(cairo, config->font, &text_width, &text_height, NULL,
@@ -533,7 +570,9 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo,
533 } 570 }
534 571
535 uint32_t height = output->height * output->scale; 572 uint32_t height = output->height * output->scale;
573 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
536 cairo_set_source_u32(cairo, config->colors.binding_mode.background); 574 cairo_set_source_u32(cairo, config->colors.binding_mode.background);
575 ctx->background_color = config->colors.binding_mode.background;
537 cairo_rectangle(cairo, x, 0, width, height); 576 cairo_rectangle(cairo, x, 0, width, height);
538 cairo_fill(cairo); 577 cairo_fill(cairo);
539 578
@@ -550,6 +589,7 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo,
550 double text_y = height / 2.0 - text_height / 2.0; 589 double text_y = height / 2.0 - text_height / 2.0;
551 cairo_set_source_u32(cairo, config->colors.binding_mode.text); 590 cairo_set_source_u32(cairo, config->colors.binding_mode.text);
552 cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); 591 cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y));
592 choose_text_aa_mode(ctx, config->colors.binding_mode.text);
553 pango_printf(cairo, config->font, output->scale, 593 pango_printf(cairo, config->font, output->scale,
554 output->bar->mode_pango_markup, "%s", mode); 594 output->bar->mode_pango_markup, "%s", mode);
555 return output->height; 595 return output->height;
@@ -565,9 +605,9 @@ static enum hotspot_event_handling workspace_hotspot_callback(
565 return HOTSPOT_IGNORE; 605 return HOTSPOT_IGNORE;
566} 606}
567 607
568static uint32_t render_workspace_button(cairo_t *cairo, 608static uint32_t render_workspace_button(struct render_context *ctx,
569 struct swaybar_output *output,
570 struct swaybar_workspace *ws, double *x) { 609 struct swaybar_workspace *ws, double *x) {
610 struct swaybar_output *output = ctx->output;
571 struct swaybar_config *config = output->bar->config; 611 struct swaybar_config *config = output->bar->config;
572 struct box_colors box_colors; 612 struct box_colors box_colors;
573 if (ws->urgent) { 613 if (ws->urgent) {
@@ -582,6 +622,7 @@ static uint32_t render_workspace_button(cairo_t *cairo,
582 622
583 uint32_t height = output->height * output->scale; 623 uint32_t height = output->height * output->scale;
584 624
625 cairo_t *cairo = ctx->cairo;
585 int text_width, text_height; 626 int text_width, text_height;
586 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 627 get_text_size(cairo, config->font, &text_width, &text_height, NULL,
587 output->scale, config->pango_markup, "%s", ws->label); 628 output->scale, config->pango_markup, "%s", ws->label);
@@ -603,7 +644,9 @@ static uint32_t render_workspace_button(cairo_t *cairo,
603 width = config->workspace_min_width * output->scale; 644 width = config->workspace_min_width * output->scale;
604 } 645 }
605 646
647 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
606 cairo_set_source_u32(cairo, box_colors.background); 648 cairo_set_source_u32(cairo, box_colors.background);
649 ctx->background_color = box_colors.background;
607 cairo_rectangle(cairo, *x, 0, width, height); 650 cairo_rectangle(cairo, *x, 0, width, height);
608 cairo_fill(cairo); 651 cairo_fill(cairo);
609 652
@@ -620,6 +663,7 @@ static uint32_t render_workspace_button(cairo_t *cairo,
620 double text_y = height / 2.0 - text_height / 2.0; 663 double text_y = height / 2.0 - text_height / 2.0;
621 cairo_set_source_u32(cairo, box_colors.text); 664 cairo_set_source_u32(cairo, box_colors.text);
622 cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); 665 cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y));
666 choose_text_aa_mode(ctx, box_colors.text);
623 pango_printf(cairo, config->font, output->scale, config->pango_markup, 667 pango_printf(cairo, config->font, output->scale, config->pango_markup,
624 "%s", ws->label); 668 "%s", ws->label);
625 669
@@ -637,15 +681,19 @@ static uint32_t render_workspace_button(cairo_t *cairo,
637 return output->height; 681 return output->height;
638} 682}
639 683
640static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { 684static uint32_t render_to_cairo(struct render_context *ctx) {
685 cairo_t *cairo = ctx->cairo;
686 struct swaybar_output *output = ctx->output;
641 struct swaybar *bar = output->bar; 687 struct swaybar *bar = output->bar;
642 struct swaybar_config *config = bar->config; 688 struct swaybar_config *config = bar->config;
643 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); 689 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
644 if (output->focused) { 690 if (output->focused) {
645 cairo_set_source_u32(cairo, config->colors.focused_background); 691 ctx->background_color = config->colors.focused_background;
646 } else { 692 } else {
647 cairo_set_source_u32(cairo, config->colors.background); 693 ctx->background_color = config->colors.background;
648 } 694 }
695
696 cairo_set_source_u32(cairo, ctx->background_color);
649 cairo_paint(cairo); 697 cairo_paint(cairo);
650 698
651 int th; 699 int th;
@@ -666,19 +714,19 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) {
666 } 714 }
667#endif 715#endif
668 if (bar->status) { 716 if (bar->status) {
669 uint32_t h = render_status_line(cairo, output, &x); 717 uint32_t h = render_status_line(ctx, &x);
670 max_height = h > max_height ? h : max_height; 718 max_height = h > max_height ? h : max_height;
671 } 719 }
672 x = 0; 720 x = 0;
673 if (config->workspace_buttons) { 721 if (config->workspace_buttons) {
674 struct swaybar_workspace *ws; 722 struct swaybar_workspace *ws;
675 wl_list_for_each(ws, &output->workspaces, link) { 723 wl_list_for_each(ws, &output->workspaces, link) {
676 uint32_t h = render_workspace_button(cairo, output, ws, &x); 724 uint32_t h = render_workspace_button(ctx, ws, &x);
677 max_height = h > max_height ? h : max_height; 725 max_height = h > max_height ? h : max_height;
678 } 726 }
679 } 727 }
680 if (config->binding_mode_indicator) { 728 if (config->binding_mode_indicator) {
681 uint32_t h = render_binding_mode_indicator(cairo, output, x); 729 uint32_t h = render_binding_mode_indicator(ctx, x);
682 max_height = h > max_height ? h : max_height; 730 max_height = h > max_height ? h : max_height;
683 } 731 }
684 732
@@ -708,26 +756,35 @@ void render_frame(struct swaybar_output *output) {
708 756
709 free_hotspots(&output->hotspots); 757 free_hotspots(&output->hotspots);
710 758
759 struct render_context ctx = { 0 };
760 ctx.output = output;
761
711 cairo_surface_t *recorder = cairo_recording_surface_create( 762 cairo_surface_t *recorder = cairo_recording_surface_create(
712 CAIRO_CONTENT_COLOR_ALPHA, NULL); 763 CAIRO_CONTENT_COLOR_ALPHA, NULL);
713 cairo_t *cairo = cairo_create(recorder); 764 cairo_t *cairo = cairo_create(recorder);
714 cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); 765 cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST);
766 ctx.cairo = cairo;
767
715 cairo_font_options_t *fo = cairo_font_options_create(); 768 cairo_font_options_t *fo = cairo_font_options_create();
716 cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); 769 cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
770 cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY);
771 ctx.textaa_safe = fo;
717 if (output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) { 772 if (output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) {
718 cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY); 773 ctx.textaa_sharp = ctx.textaa_safe;
719 } else { 774 } else {
775 fo = cairo_font_options_create();
776 cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
720 cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); 777 cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL);
721 cairo_font_options_set_subpixel_order(fo, 778 cairo_font_options_set_subpixel_order(fo,
722 to_cairo_subpixel_order(output->subpixel)); 779 to_cairo_subpixel_order(output->subpixel));
780 ctx.textaa_sharp = fo;
723 } 781 }
724 cairo_set_font_options(cairo, fo); 782
725 cairo_font_options_destroy(fo);
726 cairo_save(cairo); 783 cairo_save(cairo);
727 cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); 784 cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
728 cairo_paint(cairo); 785 cairo_paint(cairo);
729 cairo_restore(cairo); 786 cairo_restore(cairo);
730 uint32_t height = render_to_cairo(cairo, output); 787 uint32_t height = render_to_cairo(&ctx);
731 int config_height = output->bar->config->height; 788 int config_height = output->bar->config->height;
732 if (config_height > 0) { 789 if (config_height > 0) {
733 height = config_height; 790 height = config_height;
@@ -779,6 +836,11 @@ void render_frame(struct swaybar_output *output) {
779 836
780 wl_surface_commit(output->surface); 837 wl_surface_commit(output->surface);
781 } 838 }
839
840 if (ctx.textaa_sharp != ctx.textaa_safe) {
841 cairo_font_options_destroy(ctx.textaa_sharp);
842 }
843 cairo_font_options_destroy(ctx.textaa_safe);
782 cairo_surface_destroy(recorder); 844 cairo_surface_destroy(recorder);
783 cairo_destroy(cairo); 845 cairo_destroy(cairo);
784} 846}