From 38fabb6b1bbc83f1053f037260b5bfa796a23ba1 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Mon, 28 Dec 2015 11:24:25 +0100 Subject: [PATCH] Issue #303: Create one pango context from xlib surface - Create one pango context and set font options from main xlib surface - Set font type on global pango context. - Use CAIRO_OPERATOR_OVER for drawing text (otherwise subpixel rendering is not done). --- Changelog | 3 ++- include/textbox.h | 2 ++ source/rofi.c | 22 ++++++++++++++++++++++ source/textbox.c | 44 ++++++++++++++++---------------------------- test/textbox-test.c | 2 +- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/Changelog b/Changelog index cf7da78c..f2d82447 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,6 @@ 1.0.0 (unreleased): - + Bug fixes: + - Fix subpixel rendering. (#303) 0.15.12: New features: - Initial `-dump` command for dmenu mode. (#216) diff --git a/include/textbox.h b/include/textbox.h index ce0dc1d2..e7aef209 100644 --- a/include/textbox.h +++ b/include/textbox.h @@ -4,6 +4,7 @@ #include #include #include +#include #include typedef struct @@ -231,4 +232,5 @@ void textbox_delete ( textbox *tb, int pos, int dlen ); void textbox_moveresize ( textbox *tb, int x, int y, int w, int h ); int textbox_get_estimated_char_height ( void ); +void textbox_set_pango_context ( PangoContext *p ); #endif //ROFI_TEXTBOX_H diff --git a/source/rofi.c b/source/rofi.c index b1bdbe28..2ab6e751 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -268,6 +268,28 @@ static Window create_window ( Display *display ) draw = cairo_create ( surface ); cairo_set_operator ( draw, CAIRO_OPERATOR_SOURCE ); + // Set up pango context. + cairo_font_options_t *fo = cairo_font_options_create (); + // Take font description from xlib surface + cairo_surface_get_font_options ( surface, fo ); + PangoContext *p = pango_cairo_create_context ( draw ); + // Set the font options from the xlib surface + pango_cairo_context_set_font_options ( p, fo ); + // Setup dpi + if ( config.dpi > 0 ) { + PangoFontMap *font_map = pango_cairo_font_map_get_default (); + pango_cairo_font_map_set_resolution ( (PangoCairoFontMap *) font_map, (double) config.dpi ); + } + // Setup font. + PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font ); + pango_context_set_font_description ( p, pfd ); + pango_font_description_free ( pfd ); + // Tell textbox to use this context. + textbox_set_pango_context ( p ); + // cleanup + g_object_unref ( p ); + cairo_font_options_destroy ( fo ); + // // make it an unmanaged window if ( !normal_window_mode && !config.fullscreen ) { window_set_atom_prop ( display, box, netatoms[_NET_WM_STATE], &netatoms[_NET_WM_STATE_ABOVE], 1 ); diff --git a/source/textbox.c b/source/textbox.c index 250935d5..754f2fa0 100644 --- a/source/textbox.c +++ b/source/textbox.c @@ -34,7 +34,6 @@ #include #include #include -#include #include "rofi.h" #include "textbox.h" #include "keyb.h" @@ -76,10 +75,7 @@ textbox* textbox_create ( TextboxFlags flags, short x, short y, short w, short h tb->main_surface = cairo_image_surface_create ( get_format (), tb->w, tb->h ); tb->main_draw = cairo_create ( tb->main_surface ); - tb->layout = pango_cairo_create_layout ( tb->main_draw ); - PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font ); - pango_layout_set_font_description ( tb->layout, pfd ); - pango_font_description_free ( pfd ); + tb->layout = pango_layout_new ( p_context ); textbox_font ( tb, tbft ); if ( ( flags & TB_WRAP ) == TB_WRAP ) { @@ -239,8 +235,6 @@ static void texbox_update ( textbox *tb ) } tb->main_surface = cairo_image_surface_create ( get_format (), tb->w, tb->h ); tb->main_draw = cairo_create ( tb->main_surface ); - PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font ); - pango_font_description_free ( pfd ); cairo_set_operator ( tb->main_draw, CAIRO_OPERATOR_SOURCE ); pango_cairo_update_layout ( tb->main_draw, tb->layout ); @@ -300,19 +294,20 @@ static void texbox_update ( textbox *tb ) cairo_set_source_rgba ( tb->main_draw, col.red, col.green, col.blue, col.alpha * scale ); cairo_paint ( tb->main_draw ); - // Set ARGB col = tb->color_fg; cairo_set_source_rgba ( tb->main_draw, col.red, col.green, col.blue, col.alpha * scale ); - cairo_move_to ( tb->main_draw, x, y ); - pango_cairo_show_layout ( tb->main_draw, tb->layout ); - - //cairo_fill(tb->draw); // draw the cursor if ( tb->flags & TB_EDITABLE ) { cairo_rectangle ( tb->main_draw, x + cursor_x, y, cursor_width, font_height ); cairo_fill ( tb->main_draw ); } + // Set ARGB + // We need to set over, otherwise subpixel hinting wont work. + cairo_set_operator ( tb->main_draw, CAIRO_OPERATOR_OVER ); + cairo_move_to ( tb->main_draw, x, y ); + pango_cairo_show_layout ( tb->main_draw, tb->layout ); + tb->update = FALSE; } } @@ -658,11 +653,12 @@ void textbox_setup ( Display *display ) parse_color ( display, config.menu_hlfg_active, &( colors[ACTIVE].hlfg ) ); parse_color ( display, config.menu_hlbg_active, &( colors[ACTIVE].hlbg ) ); } - PangoFontMap *font_map = pango_cairo_font_map_get_default (); - if ( config.dpi > 0 ) { - pango_cairo_font_map_set_resolution ( (PangoCairoFontMap *) font_map, (double) config.dpi ); - } - p_context = pango_font_map_create_context ( font_map ); +} + +void textbox_set_pango_context ( PangoContext *p ) +{ + textbox_cleanup (); + p_context = g_object_ref ( p ); } void textbox_cleanup ( void ) @@ -699,26 +695,18 @@ int textbox_get_font_width ( textbox *tb ) double textbox_get_estimated_char_width ( void ) { - PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font ); // Get width - PangoFontMetrics *metric = pango_context_get_metrics ( p_context, pfd, NULL ); - int width = pango_font_metrics_get_approximate_char_width ( metric ); + PangoFontMetrics *metric = pango_context_get_metrics ( p_context, NULL, NULL ); + int width = pango_font_metrics_get_approximate_char_width ( metric ); pango_font_metrics_unref ( metric ); - - pango_font_description_free ( pfd ); return ( width ) / (double) PANGO_SCALE; } int textbox_get_estimated_char_height ( void ) { - // Set font. - PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font ); - // Get width - PangoFontMetrics *metric = pango_context_get_metrics ( p_context, pfd, NULL ); + PangoFontMetrics *metric = pango_context_get_metrics ( p_context, NULL, NULL ); int height = pango_font_metrics_get_ascent ( metric ) + pango_font_metrics_get_descent ( metric ); pango_font_metrics_unref ( metric ); - - pango_font_description_free ( pfd ); return ( height ) / PANGO_SCALE + 2 * SIDE_MARGIN; } diff --git a/test/textbox-test.c b/test/textbox-test.c index f1a993ee..a57a767e 100644 --- a/test/textbox-test.c +++ b/test/textbox-test.c @@ -92,7 +92,7 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv ) config.menu_bg_alt = config.menu_bg; textbox_setup ( display ); textbox *box = textbox_create ( TB_EDITABLE | TB_AUTOWIDTH | TB_AUTOHEIGHT, 0, 0, -1, -1, - NORMAL, "test" ); + NORMAL, "test" ); TASSERT ( box != NULL ); textbox_cursor_end ( box );