On Oct 4, 2014 4:37 AM, "Ryo Munakata" <ryomnk...@gmail.com> wrote: > > cairo-util has used sans font family for title fonts so far. > But sans doesn't support glyphs of some non-ascii characters. > So now let users choose a font family for titles. > > To show texts correctly now using pangocairo for redering fonts. > If any single font in 'fonts' entry doesn't contain all the needed glyphs, > we use the fallback mode of pango. > > This pangocairo support is enabled if configure finds pangocairo > on the build environment. > Otherwise fall back to plain cairo rendering. > > The entry name is generic, 'fonts' so that other places > where draw texts can use this entry too. > > Signed-off-by: Ryo Munakata <ryomnk...@gmail.com> > --- > Makefile.am | 4 ++ > clients/window.c | 18 +++-- > configure.ac | 5 +- > man/weston.ini.man | 3 + > shared/cairo-util.c | 180 ++++++++++++++++++++++++++++++++++++++++++++-- > shared/cairo-util.h | 5 ++ > src/compositor-wayland.c | 9 ++- > weston.ini.in | 1 + > xwayland/window-manager.c | 7 +- > 9 files changed, 216 insertions(+), 16 deletions(-) > > diff --git a/Makefile.am b/Makefile.am > index 10be920..db3f423 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -829,6 +829,10 @@ libshared_cairo_la_SOURCES = \ > shared/frame.c \ > shared/cairo-util.h > > +if HAVE_PANGO > +libshared_cairo_la_CFLAGS += $(PANGO_CFLAGS) > +libshared_cairo_la_LIBADD += $(PANGO_LIBS) > +endif > > # > # tests subdirectory > diff --git a/clients/window.c b/clients/window.c > index 139c7f9..d9cbb9e 100644 > --- a/clients/window.c > +++ b/clients/window.c > @@ -113,6 +113,8 @@ struct display { > > struct theme *theme; > > + struct weston_config *config; > + > struct wl_cursor_theme *cursor_theme; > struct wl_cursor **cursors; > > @@ -1279,18 +1281,15 @@ static const struct cursor_alternatives cursors[] = { > static void > create_cursors(struct display *display) > { > - struct weston_config *config; > struct weston_config_section *s; > int size; > char *theme = NULL; > unsigned int i, j; > struct wl_cursor *cursor; > > - config = weston_config_parse("weston.ini"); > - s = weston_config_get_section(config, "shell", NULL, NULL); > + s = weston_config_get_section(display->config, "shell", NULL, NULL); > weston_config_section_get_string(s, "cursor-theme", &theme, NULL); > weston_config_section_get_int(s, "cursor-size", &size, 32); > - weston_config_destroy(config); > > display->cursor_theme = wl_cursor_theme_load(theme, size, display->shm); > if (!display->cursor_theme) { > @@ -5439,6 +5438,8 @@ struct display * > display_create(int *argc, char *argv[]) > { > struct display *d; > + char *fonts; > + struct weston_config_section *s; > > wl_log_set_handler_client(log_handler); > > @@ -5488,9 +5489,14 @@ display_create(int *argc, char *argv[]) > "falling back to software rendering and wl_shm.\n"); > #endif > > + d->config = weston_config_parse("weston.ini"); > + > create_cursors(d); > > - d->theme = theme_create(); > + s = weston_config_get_section(d->config, "shell", NULL, NULL); > + weston_config_section_get_string(s, "fonts", &fonts, NULL); > + d->theme = theme_create_with_fonts(fonts); > + free(fonts); > > wl_list_init(&d->window_list); > > @@ -5566,6 +5572,8 @@ display_destroy(struct display *display) > !(display->display_fd_events & EPOLLHUP)) > wl_display_flush(display->display); > > + weston_config_destroy(display->config); > + > wl_display_disconnect(display->display); > free(display); > } > diff --git a/configure.ac b/configure.ac > index 1c133bd..8b703bd 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -272,6 +272,9 @@ PKG_CHECK_MODULES(PNG, [libpng]) > PKG_CHECK_MODULES(WEBP, [libwebp], [have_webp=yes], [have_webp=no]) > AS_IF([test "x$have_webp" = "xyes"], > [AC_DEFINE([HAVE_WEBP], [1], [Have webp])]) > +PKG_CHECK_MODULES(PANGO, [pangocairo], [have_pango=yes], [have_pango=no]) > +AS_IF([test "x$have_pango" = "xyes"], > + [AC_DEFINE([HAVE_PANGO], [1], [Have pango support])]) > > AC_ARG_ENABLE(vaapi-recorder, [ --enable-vaapi-recorder],, > enable_vaapi_recorder=auto) > @@ -335,8 +338,6 @@ if test x$enable_clients = xyes; then > [AC_DEFINE([HAVE_CAIRO_EGL], [1], [Have cairo-egl])], > [AC_ERROR([cairo-egl not used because $CAIRO_EGL_PKG_ERRORS])])], > [have_cairo_egl=no]) > - > - PKG_CHECK_MODULES(PANGO, [pangocairo], [have_pango=yes], [have_pango=no]) > fi > > AC_ARG_ENABLE(resize-optimization, > diff --git a/man/weston.ini.man b/man/weston.ini.man > index c05a221..73e32d7 100644 > --- a/man/weston.ini.man > +++ b/man/weston.ini.man > @@ -260,6 +260,9 @@ sets the path to lock screen background image (string). (tablet shell only) > .TP 7 > .BI "homescreen=" path > sets the path to home screen background image (string). (tablet shell only) > +.TP 7 > +.BI "fonts=" font-families > +sets the font family nams separated by commas (string). (title fonts only for now) > .RE > .SH "LAUNCHER SECTION" > There can be multiple launcher sections, one for each launcher. > diff --git a/shared/cairo-util.c b/shared/cairo-util.c > index 26286c5..9c9957a 100644 > --- a/shared/cairo-util.c > +++ b/shared/cairo-util.c > @@ -33,9 +33,42 @@ > #include "cairo-util.h" > > #include "image-loader.h" > -#include "config-parser.h" > +#include "zalloc.h" > > #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) > +#define DEFAULT_FONT_FAMILY "sans" > +#define DEFAULT_FONT_SIZE 14 > + > +struct font_entry { > + struct wl_list link; > + char *name; > +}; > + > +static struct font_entry * > +font_entry_create(char *fontname) > +{ > + struct font_entry *font = zalloc(sizeof *font); > + > + if (!font) > + return NULL; > + > + font->name = strdup(fontname); > + return font; > +} > + > +static void > +font_entry_destroy(struct font_entry *font) > +{ > + free(font->name); > + free(font); > +} > + > +static struct font_entry * > +font_entry_list_front(struct wl_list *list) > +{ > + struct font_entry *font; > + return wl_container_of(list, font, link); > +} > > void > surface_flush_device(cairo_surface_t *surface) > @@ -337,8 +370,29 @@ theme_set_background_source(struct theme *t, cairo_t *cr, uint32_t flags) > } > } > > +static void > +insert_font_family_list(struct wl_list *title_fonts, const char *fonts) > +{ > + char *fontlist, *str, *token, *saveptr; > + struct wl_list *current = title_fonts; > + > + if (!fonts || !(fontlist = strdup(fonts))) > + return; > + > + for (str = fontlist; (token = strtok_r(str, ",", &saveptr)) != NULL;) { > + struct font_entry *font = font_entry_create(token); > + > + if (font) { > + wl_list_insert(current, &font->link); > + current = &font->link; > + } > + str = NULL; > + } > + free(fontlist); > +} > + > struct theme * > -theme_create(void) > +theme_create_with_fonts(const char *fonts) > { > struct theme *t; > cairo_t *cr; > @@ -347,6 +401,10 @@ theme_create(void) > if (t == NULL) > return NULL; > > + wl_list_init(&t->title_fonts); > + insert_font_family_list(&t->title_fonts, > + fonts ? fonts : DEFAULT_FONT_FAMILY); > + > t->margin = 32; > t->width = 6; > t->titlebar_height = 27; > @@ -402,25 +460,113 @@ theme_create(void) > return NULL; > } > > +struct theme * > +theme_create(void) > +{ > + return theme_create_with_fonts(NULL); > +} > + > void > theme_destroy(struct theme *t) > { > + struct font_entry *font, *next; > + > + wl_list_for_each_safe(font, next, &t->title_fonts, link) > + font_entry_destroy(font); > cairo_surface_destroy(t->active_frame); > cairo_surface_destroy(t->inactive_frame); > cairo_surface_destroy(t->shadow); > free(t); > } > > +#ifdef HAVE_PANGO > +#include <pango/pangocairo.h> > + > +#define DEFAULT_FONT_WEIGHT PANGO_WEIGHT_BOLD > + > +static void > +pango_layout_set_fallback(PangoLayout *layout, gboolean fallback) > +{ > + PangoAttrList *list = pango_layout_get_attributes(layout); > + PangoAttrList *attr_list = list ? list : pango_attr_list_new(); > + > + if (!attr_list) > + return; > + > + PangoAttribute *fb_attr = pango_attr_fallback_new(fallback); > + pango_attr_list_change(attr_list, fb_attr); > + pango_layout_set_attributes(layout, attr_list); > + > + if (!list) > + pango_attr_list_unref(attr_list); > +} > + > +static PangoFontDescription * > +pango_font_description_create(const char *font, > + double size, PangoWeight weight) > +{ > + PangoFontDescription *fontdesc = > + pango_font_description_from_string(font); > + > + pango_font_description_set_weight(fontdesc, weight); > + pango_font_description_set_absolute_size(fontdesc, size * PANGO_SCALE); > + return fontdesc; > +} > + > +static void
Why not just make the default font description be something like "12 Sans"? This seems like a lot of infrastructure that's basically rewriting Pango. I assume that desktop-shell can't hard-depend on Pango? +pango_layout_set_best_font(PangoLayout *layout, > + struct wl_list *fonts, const char *text) > +{ > + struct font_entry *font, *first_font = NULL, *best_font = NULL; > + > + pango_layout_set_text(layout, text, -1); > + pango_layout_set_fallback(layout, FALSE); > + > + wl_list_for_each(font, fonts, link) { > + PangoFontDescription *fontdesc = > + pango_font_description_create(font->name, > + DEFAULT_FONT_SIZE, DEFAULT_FONT_WEIGHT); > + > + pango_layout_set_font_description(layout, fontdesc); > + pango_font_description_free(fontdesc); > + if (!pango_layout_get_unknown_glyphs_count(layout)) { > + best_font = font; > + break; > + } > + > + if (!first_font) > + first_font = font; > + } > + > + if (!best_font && first_font) { > + PangoFontDescription *fontdesc = > + pango_font_description_create(first_font->name, > + DEFAULT_FONT_SIZE, DEFAULT_FONT_WEIGHT); > + > + pango_layout_set_font_description(layout, fontdesc); > + pango_font_description_free(fontdesc); > + } > + > + pango_layout_set_fallback(layout, TRUE); > +} > +#endif > + > void > theme_render_frame(struct theme *t, > cairo_t *cr, int width, int height, > const char *title, struct wl_list *buttons, > uint32_t flags) > { > + cairo_surface_t *source; > +#ifdef HAVE_PANGO > + PangoLayout *layout = pango_cairo_create_layout(cr); > + PangoRectangle extents; > + int x, y, margin, top_margin; > +#else > cairo_text_extents_t extents; > cairo_font_extents_t font_extents; > - cairo_surface_t *source; > int x, y, margin, top_margin; > +#endif > > cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); > cairo_set_source_rgba(cr, 0, 0, 0, 0); > @@ -458,31 +604,53 @@ theme_render_frame(struct theme *t, > cairo_clip(cr); > > cairo_set_operator(cr, CAIRO_OPERATOR_OVER); > - cairo_select_font_face(cr, "sans", > +#ifdef HAVE_PANGO > + pango_layout_set_best_font(layout, &t->title_fonts, title); > + pango_layout_get_pixel_extents(layout, NULL, &extents); > + x = (width - extents.width) / 2; > + y = margin + (t->titlebar_height - extents.height) / 2; > +#else > + cairo_select_font_face(cr, > + font_entry_list_front(&t->title_fonts)->name, > CAIRO_FONT_SLANT_NORMAL, > CAIRO_FONT_WEIGHT_BOLD); > - cairo_set_font_size(cr, 14); > + cairo_set_font_size(cr, DEFAULT_FONT_SIZE); > cairo_text_extents(cr, title, &extents); > cairo_font_extents (cr, &font_extents); > x = (width - extents.width) / 2; > y = margin + > (t->titlebar_height - > - font_extents.ascent - font_extents.descent) / 2 + > + font_extents.ascent - font_extents.descent) / 2 + > font_extents.ascent; > +#endif > > if (flags & THEME_FRAME_ACTIVE) { > cairo_move_to(cr, x + 1, y + 1); > cairo_set_source_rgb(cr, 1, 1, 1); > +#ifdef HAVE_PANGO > + pango_cairo_show_layout(cr, layout); > + cairo_move_to(cr, x, y); > + cairo_set_source_rgb(cr, 0, 0, 0); > + pango_cairo_show_layout(cr, layout); > +#else > cairo_show_text(cr, title); > cairo_move_to(cr, x, y); > cairo_set_source_rgb(cr, 0, 0, 0); > cairo_show_text(cr, title); > +#endif > } else { > cairo_move_to(cr, x, y); > cairo_set_source_rgb(cr, 0.4, 0.4, 0.4); > +#ifdef HAVE_PANGO > + pango_cairo_show_layout(cr, layout); > +#else > cairo_show_text(cr, title); > +#endif > } > } > +#ifdef HAVE_PANGO > + g_object_unref(layout); > +#endif > } > > enum theme_location > diff --git a/shared/cairo-util.h b/shared/cairo-util.h > index 11d11d1..db10140 100644 > --- a/shared/cairo-util.h > +++ b/shared/cairo-util.h > @@ -53,10 +53,15 @@ struct theme { > int margin; > int width; > int titlebar_height; > + struct wl_list title_fonts; > }; > > struct theme * > theme_create(void); > + > +struct theme * > +theme_create_with_fonts(const char *fonts); > + > void > theme_destroy(struct theme *t); > > diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c > index bf71a76..7cf002c 100644 > --- a/src/compositor-wayland.c > +++ b/src/compositor-wayland.c > @@ -738,7 +738,8 @@ wayland_output_set_windowed(struct wayland_output *output) > struct wayland_compositor *c = > (struct wayland_compositor *)output->base.compositor; > int tlen; > - char *title; > + char *title, *fonts; > + struct weston_config_section *s; > > if (output->frame) > return 0; > @@ -755,7 +756,11 @@ wayland_output_set_windowed(struct wayland_output *output) > } > > if (!c->theme) { > - c->theme = theme_create(); > + s = weston_config_get_section(c->base.config, "shell", NULL, NULL); > + weston_config_section_get_string(s, "fonts", &fonts, ""); > + c->theme = theme_create_with_fonts(fonts); > + free(fonts); > + > if (!c->theme) { > free(title); > return -1; > diff --git a/weston.ini.in b/weston.ini.in > index 4fca0bb..26192da 100644 > --- a/weston.ini.in > +++ b/weston.ini.in > @@ -15,6 +15,7 @@ startup-animation=fade > #num-workspaces=6 > #cursor-theme=whiteglass > #cursor-size=24 > +#fonts=sans > > #lockscreen-icon=/usr/share/icons/gnome/256x256/actions/lock.png > #lockscreen=/usr/share/backgrounds/gnome/Garden.jpg > diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c > index 4e91f9d..a1b3094 100644 > --- a/xwayland/window-manager.c > +++ b/xwayland/window-manager.c > @@ -2031,6 +2031,8 @@ weston_wm_create(struct weston_xserver *wxs, int fd) > xcb_screen_iterator_t s; > uint32_t values[1]; > xcb_atom_t supported[3]; > + char *fonts; > + struct weston_config_section *section; > > wm = zalloc(sizeof *wm); > if (wm == NULL) > @@ -2076,7 +2078,10 @@ weston_wm_create(struct weston_xserver *wxs, int fd) > xcb_composite_redirect_subwindows(wm->conn, wm->screen->root, > XCB_COMPOSITE_REDIRECT_MANUAL); > > - wm->theme = theme_create(); > + section = weston_config_get_section(wxs->compositor->config, "shell", NULL, NULL); > + weston_config_section_get_string(section, "fonts", &fonts, NULL); > + wm->theme = theme_create_with_fonts(fonts); > + free(fonts); > > supported[0] = wm->atom.net_wm_moveresize; > supported[1] = wm->atom.net_wm_state; > -- > 2.1.2 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel
_______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel