diff --git a/ChangeLog b/ChangeLog index fd2a234..f680dcf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ -2018-12-26 master +2018-12-31 master - Fix spacing around icons in executor without text in vertical panels (issue #716) - Fix Bug: Clock Only Updates Every Minute With Format %s (issue #724) +- Fix markup drawing when font shadow enabled (issue #709) 2018-08-05 16.6.1 - Fix packaging regression for debian (issue #715) diff --git a/src/button/button.c b/src/button/button.c index 7e1dc59..bf41c67 100644 --- a/src/button/button.c +++ b/src/button/button.c @@ -478,7 +478,7 @@ void draw_button(void *obj, cairo_t *c) button->frontend->textx, button->frontend->texty, &button->backend->font_color, - panel_config.font_shadow); + panel_config.font_shadow ? layout : NULL); g_object_unref(layout); g_object_unref(context); diff --git a/src/execplugin/execplugin.c b/src/execplugin/execplugin.c index 1b02d9b..2181e6e 100644 --- a/src/execplugin/execplugin.c +++ b/src/execplugin/execplugin.c @@ -491,6 +491,18 @@ gboolean resize_execp(void *obj) return resized; } +PangoLayout *create_execp_text_layout(Execp *execp, PangoContext *context) +{ + PangoLayout *layout = pango_layout_new(context); + pango_layout_set_font_description(layout, execp->backend->font_desc); + pango_layout_set_width(layout, (execp->frontend->textw + TINT2_PANGO_SLACK) * PANGO_SCALE); + pango_layout_set_height(layout, (execp->frontend->texth + TINT2_PANGO_SLACK) * PANGO_SCALE); + pango_layout_set_alignment(layout, execp->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT); + pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); + pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); + return layout; +} + void draw_execp(void *obj, cairo_t *c) { Execp *execp = (Execp *)obj; @@ -498,7 +510,8 @@ void draw_execp(void *obj, cairo_t *c) PangoContext *context = pango_cairo_create_context(c); pango_cairo_context_set_resolution(context, 96 * panel->scale); - PangoLayout *layout = pango_layout_new(context); + PangoLayout *layout = create_execp_text_layout(execp, context); + PangoLayout *shadow_layout = NULL; if (execp->backend->has_icon && execp->backend->icon) { imlib_context_set_image(execp->backend->icon); @@ -507,16 +520,18 @@ void draw_execp(void *obj, cairo_t *c) } // draw layout - pango_layout_set_font_description(layout, execp->backend->font_desc); - pango_layout_set_width(layout, (execp->frontend->textw + TINT2_PANGO_SLACK) * PANGO_SCALE); - pango_layout_set_height(layout, (execp->frontend->texth + TINT2_PANGO_SLACK) * PANGO_SCALE); - pango_layout_set_alignment(layout, execp->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT); - pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); - pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); - if (!execp->backend->has_markup) + if (!execp->backend->has_markup) { pango_layout_set_text(layout, execp->backend->text, strlen(execp->backend->text)); - else + } else { pango_layout_set_markup(layout, execp->backend->text, strlen(execp->backend->text)); + if (panel_config.font_shadow) { + shadow_layout = create_execp_text_layout(execp, context); + if (!layout_set_markup_strip_colors(shadow_layout, execp->backend->text)) { + g_object_unref(shadow_layout); + shadow_layout = NULL; + } + } + } pango_cairo_update_layout(c, layout); draw_text(layout, @@ -524,7 +539,7 @@ void draw_execp(void *obj, cairo_t *c) execp->frontend->textx, execp->frontend->texty, &execp->backend->font_color, - panel_config.font_shadow); + shadow_layout); g_object_unref(layout); g_object_unref(context); diff --git a/src/taskbar/task.c b/src/taskbar/task.c index 4d279be..41a878d 100644 --- a/src/taskbar/task.c +++ b/src/taskbar/task.c @@ -497,7 +497,7 @@ void draw_task(void *obj, cairo_t *c) task->_text_posy = (panel->g_task.area.height - task->_text_height) / 2.0; Color *config_text = &panel->g_task.font[task->current_state]; - draw_text(layout, c, panel->g_task.text_posx, task->_text_posy, config_text, panel->font_shadow); + draw_text(layout, c, panel->g_task.text_posx, task->_text_posy, config_text, panel->font_shadow ? layout : NULL); g_object_unref(layout); g_object_unref(context); diff --git a/src/taskbar/taskbarname.c b/src/taskbar/taskbarname.c index dc95d85..5dd153c 100644 --- a/src/taskbar/taskbarname.c +++ b/src/taskbar/taskbarname.c @@ -215,7 +215,7 @@ void draw_taskbarname(void *obj, cairo_t *c) cairo_set_source_rgba(c, config_text->rgb[0], config_text->rgb[1], config_text->rgb[2], config_text->alpha); pango_cairo_update_layout(c, layout); - draw_text(layout, c, 0, taskbar_name->posy, config_text, ((Panel *)taskbar_name->area.panel)->font_shadow); + draw_text(layout, c, 0, taskbar_name->posy, config_text, ((Panel *)taskbar_name->area.panel)->font_shadow ? layout : NULL); g_object_unref(layout); g_object_unref(context); diff --git a/src/util/area.c b/src/util/area.c index 61dc4c8..c1cc949 100644 --- a/src/util/area.c +++ b/src/util/area.c @@ -1084,7 +1084,7 @@ void draw_text_area(Area *area, pango_layout_set_font_description(layout, line1_font_desc); pango_layout_set_text(layout, line1, strlen(line1)); pango_cairo_update_layout(c, layout); - draw_text(layout, c, (area->width - inner_w) / 2, line1_posy, color, ((Panel *)area->panel)->font_shadow); + draw_text(layout, c, (area->width - inner_w) / 2, line1_posy, color, ((Panel *)area->panel)->font_shadow ? layout : NULL); } if (line2 && line2[0]) { @@ -1092,7 +1092,7 @@ void draw_text_area(Area *area, pango_layout_set_indent(layout, 0); pango_layout_set_text(layout, line2, strlen(line2)); pango_cairo_update_layout(c, layout); - draw_text(layout, c, (area->width - inner_w) / 2, line2_posy, color, ((Panel *)area->panel)->font_shadow); + draw_text(layout, c, (area->width - inner_w) / 2, line2_posy, color, ((Panel *)area->panel)->font_shadow ? layout : NULL); } g_object_unref(layout); diff --git a/src/util/common.c b/src/util/common.c index 032b433..cb4928e 100644 --- a/src/util/common.c +++ b/src/util/common.c @@ -724,27 +724,60 @@ void render_image(Drawable d, int x, int y) XFreePixmap(server.display, pixmap); } -void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, int font_shadow) +gboolean is_color_attribute(PangoAttribute *attr, gpointer user_data) { - if (font_shadow) { - const int shadow_size = 3; - const double shadow_edge_alpha = 0.0; - int i, j; - for (i = -shadow_size; i <= shadow_size; i++) { - for (j = -shadow_size; j <= shadow_size; j++) { - cairo_set_source_rgba(c, - 0.0, - 0.0, - 0.0, - 1.0 - - (1.0 - shadow_edge_alpha) * - sqrt((i * i + j * j) / (double)(shadow_size * shadow_size))); - pango_cairo_update_layout(c, layout); - cairo_move_to(c, posx + i, posy + j); - pango_cairo_show_layout(c, layout); - } + return attr->klass->type == PANGO_ATTR_FOREGROUND || + attr->klass->type == PANGO_ATTR_BACKGROUND || + attr->klass->type == PANGO_ATTR_UNDERLINE_COLOR || + attr->klass->type == PANGO_ATTR_STRIKETHROUGH_COLOR || + attr->klass->type == PANGO_ATTR_FOREGROUND_ALPHA || + attr->klass->type == PANGO_ATTR_BACKGROUND_ALPHA; +} + +gboolean layout_set_markup_strip_colors(PangoLayout *layout, const char *markup) +{ + PangoAttrList *attrs = NULL; + char *text = NULL; + GError *error = NULL; + if (!pango_parse_markup(markup, -1, 0, &attrs, &text, NULL, &error)) { + g_error_free(error); + return FALSE; + } + + pango_layout_set_text(layout, text, -1); + g_free(text); + + pango_attr_list_filter(attrs, is_color_attribute, NULL); + pango_layout_set_attributes(layout, attrs); + pango_attr_list_unref(attrs); + return TRUE; +} + +void draw_shadow(cairo_t *c, int posx, int posy, PangoLayout *shadow_layout) +{ + const int shadow_size = 3; + const double shadow_edge_alpha = 0.0; + int i, j; + for (i = -shadow_size; i <= shadow_size; i++) { + for (j = -shadow_size; j <= shadow_size; j++) { + cairo_set_source_rgba(c, + 0.0, + 0.0, + 0.0, + 1.0 - + (1.0 - shadow_edge_alpha) * + sqrt((i * i + j * j) / (double)(shadow_size * shadow_size))); + pango_cairo_update_layout(c, shadow_layout); + cairo_move_to(c, posx + i, posy + j); + pango_cairo_show_layout(c, shadow_layout); } } +} + +void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, PangoLayout *shadow_layout) +{ + if (shadow_layout) + draw_shadow(c, posx, posy, shadow_layout); cairo_set_source_rgba(c, color->rgb[0], color->rgb[1], color->rgb[2], color->alpha); pango_cairo_update_layout(c, layout); cairo_move_to(c, posx, posy); diff --git a/src/util/common.h b/src/util/common.h index a9454b6..8eb2729 100644 --- a/src/util/common.h +++ b/src/util/common.h @@ -126,7 +126,8 @@ void get_text_size2(const PangoFontDescription *font, gboolean markup, double scale); -void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, int font_shadow); +gboolean layout_set_markup_strip_colors(PangoLayout *layout, const char *markup); +void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, PangoLayout *shadow_layout); // Draws a rounded rectangle void draw_rect(cairo_t *c, double x, double y, double w, double h, double r);