[PATCH weston v2 1/2] Add font entry to shell section for title fonts

Jasper St. Pierre jstpierre at mecheye.net
Sat Oct 4 07:09:54 PDT 2014


On Oct 4, 2014 4:37 AM, "Ryo Munakata" <ryomnktml at 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 <ryomnktml at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20141004/c9330f83/attachment-0001.html>


More information about the wayland-devel mailing list