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

Submitted by Ryo Munakata on Oct. 4, 2014, 11:37 a.m.

Details

Message ID 1412422633-3728-2-git-send-email-ryomnktml@gmail.com
State Changes Requested
Headers show

Not browsing as part of any series.

Commit Message

Ryo Munakata Oct. 4, 2014, 11:37 a.m.
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@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(-)

Patch hide | download patch | download mbox

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
+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;

Comments

On Oct 4, 2014 4:37 AM, "Ryo Munakata" <ryomnktml@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@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
On 10/04/2014 04:37 AM, Ryo Munakata 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.

As far as I can tell Pango does this fallback without any setup, not 
sure why you have all this code for turning on fallback. The following 
seems to produce all the assigned glyphs in just about every block I 
tried, and certainly produces glyphs that are not in sans:

   PangoFontDescription *font_description = pango_font_description_new ();
   pango_font_description_set_family (font_description, "sans");
   pango_font_description_set_weight (font_description, 
PANGO_WEIGHT_NORMAL);
   pango_font_description_set_absolute_size (font_description, 32 * 
PANGO_SCALE);
   PangoLayout *layout = pango_cairo_create_layout (cr);
   pango_layout_set_font_description (layout, font_description);
   pango_layout_set_markup (layout, text, -1);
   pango_layout_set_width(layout, (W-20) * PANGO_SCALE);
   pango_layout_set_height(layout, (H-100) * PANGO_SCALE);
   cairo_move_to (cr, 10.0, 100.0);
   pango_cairo_show_layout (cr, layout);
   g_object_unref (layout);
   pango_font_description_free (font_description);
On Sat, 04 Oct 2014 15:08:12 -0700
Bill Spitzak <spitzak@gmail.com> wrote:

> On 10/04/2014 04:37 AM, Ryo Munakata 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.
> 
> As far as I can tell Pango does this fallback without any setup, not 
> sure why you have all this code for turning on fallback. The following 
> seems to produce all the assigned glyphs in just about every block I 
> tried, and certainly produces glyphs that are not in sans:
> 
>    PangoFontDescription *font_description = pango_font_description_new ();
>    pango_font_description_set_family (font_description, "sans");
>    pango_font_description_set_weight (font_description, 
> PANGO_WEIGHT_NORMAL);
>    pango_font_description_set_absolute_size (font_description, 32 * 
> PANGO_SCALE);
>    PangoLayout *layout = pango_cairo_create_layout (cr);
>    pango_layout_set_font_description (layout, font_description);
>    pango_layout_set_markup (layout, text, -1);
>    pango_layout_set_width(layout, (W-20) * PANGO_SCALE);
>    pango_layout_set_height(layout, (H-100) * PANGO_SCALE);
>    cairo_move_to (cr, 10.0, 100.0);
>    pango_cairo_show_layout (cr, layout);
>    g_object_unref (layout);
>    pango_font_description_free (font_description);

Hi, Bill.
Thank you for reviewing!

Yeah, pango does fallback without any setup but that isn't what I want.

What I want to do with 'fonts' entry is: if *every single* font in the list
doesn't have *all the needed* glyphs, then, we set the first font in the list
and use pango fallback mode.

The code you wrote is something like:
sans doesn't seem to have some glyphs. Let's use pango fallback mode.

pango_layout_set_best_font() does the followings:
 1. Oops, sans doesn't have all the needed glyphs.
 2. So then, try the next font in the list.
 3. It also doen't contain some glyphs. Let's try the third one.
 4. Finally, it contains all the needed glyphs. Let's use the third one.
or:
 4. It also doesn't. Set the first font and let's use pango fallback mode. 
    (This is the case you showed me)

The point is pango_layout_set_best_font() respects the fonts list users specified as much as possible.

Maybe the commit message I wrote is unclear or broken.
Sorry about that.
I don't think that's a great idea. The rest of my system uses Pango's
algorithms for doing font fallback and font shaping, and I don't see a
reason to differ from it.

Not to mention that it's very unlikely that I want my window title to
suddenly switch completely to a fullwidth font because it had one Japanese
character in it.

On Sat, Oct 4, 2014 at 5:50 PM, Ryo Munakata <ryomnktml@gmail.com> wrote:

> On Sat, 04 Oct 2014 15:08:12 -0700
> Bill Spitzak <spitzak@gmail.com> wrote:
>
> > On 10/04/2014 04:37 AM, Ryo Munakata 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.
> >
> > As far as I can tell Pango does this fallback without any setup, not
> > sure why you have all this code for turning on fallback. The following
> > seems to produce all the assigned glyphs in just about every block I
> > tried, and certainly produces glyphs that are not in sans:
> >
> >    PangoFontDescription *font_description = pango_font_description_new
> ();
> >    pango_font_description_set_family (font_description, "sans");
> >    pango_font_description_set_weight (font_description,
> > PANGO_WEIGHT_NORMAL);
> >    pango_font_description_set_absolute_size (font_description, 32 *
> > PANGO_SCALE);
> >    PangoLayout *layout = pango_cairo_create_layout (cr);
> >    pango_layout_set_font_description (layout, font_description);
> >    pango_layout_set_markup (layout, text, -1);
> >    pango_layout_set_width(layout, (W-20) * PANGO_SCALE);
> >    pango_layout_set_height(layout, (H-100) * PANGO_SCALE);
> >    cairo_move_to (cr, 10.0, 100.0);
> >    pango_cairo_show_layout (cr, layout);
> >    g_object_unref (layout);
> >    pango_font_description_free (font_description);
>
> Hi, Bill.
> Thank you for reviewing!
>
> Yeah, pango does fallback without any setup but that isn't what I want.
>
> What I want to do with 'fonts' entry is: if *every single* font in the list
> doesn't have *all the needed* glyphs, then, we set the first font in the
> list
> and use pango fallback mode.
>
> The code you wrote is something like:
> sans doesn't seem to have some glyphs. Let's use pango fallback mode.
>
> pango_layout_set_best_font() does the followings:
>  1. Oops, sans doesn't have all the needed glyphs.
>  2. So then, try the next font in the list.
>  3. It also doen't contain some glyphs. Let's try the third one.
>  4. Finally, it contains all the needed glyphs. Let's use the third one.
> or:
>  4. It also doesn't. Set the first font and let's use pango fallback mode.
>     (This is the case you showed me)
>
> The point is pango_layout_set_best_font() respects the fonts list users
> specified as much as possible.
>
> Maybe the commit message I wrote is unclear or broken.
> Sorry about that.
>
> --
> Ryo Munakata <ryomnktml@gmail.com>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
Hi, Jasper.
Thank you for reviewing!

On Sat, 4 Oct 2014 07:09:54 -0700
"Jasper St. Pierre" <jstpierre@mecheye.net> wrote:

> On Oct 4, 2014 4:37 AM, "Ryo Munakata" <ryomnktml@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@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?

I think you are right. We dislike redudancy.
So if you think only pango_font_description_create() is the rewriting of Pango,
I will remove it, add the code like below and resend the new patches.
If you think others also contain some redudancy please tell me.

I think other pango helpers in the patch are needed.
I don't like writing same code twice.

#define CAIRO_UTIL_XSTR(x) #x
#define CAIRO_UTIL_STR(s) CAIRO_UTIL_XSTR(s)
/* We need these above to share the below between pango and cairo rendering code */
#define DEFAULT_FONT_FAMILY "sans"
#define DEFAULT_FONT_SIZE 14
#define DEFAULT_FONT_DESC DEFAULT_FONT_FAMILY " " \
    CAIRO_UTIL_STR(DEFAULT_FONT_SIZE)

PangoFontDescription *fontdesc =
    pango_font_description_from_string(DEFAULT_FONT_DESC);
pango_font_description_set_weight(fontdesc, DEFAULT_FONT_WEIGHT);

Thanks.
On Sat, 4 Oct 2014 18:01:51 -0700
"Jasper St. Pierre" <jstpierre@mecheye.net> wrote:

> I don't think that's a great idea. The rest of my system uses Pango's
> algorithms for doing font fallback and font shaping, and I don't see a
> reason to differ from it.
> 
> Not to mention that it's very unlikely that I want my window title to
> suddenly switch completely to a fullwidth font because it had one Japanese
> character in it.
> 

Hi, Jasper.

So do you think that the fonts list isn't needed?
If users want the behavior Bill showed, they just need to set fonts=sans.
That doesn't suddenly switch completely to a fullwidth font.

I want to know what you need.
Please tell me the way you want to solve the problem which is why I wrote this series.

Thanks.
Set a font description like "Sans" and then let Pango do the glyph
selection with fallback fonts. It hooks together with fontconfig -- it
knows well enough what font options are available.

On Sat, Oct 4, 2014 at 6:47 PM, Ryo Munakata <ryomnktml@gmail.com> wrote:

> On Sat, 4 Oct 2014 18:01:51 -0700
> "Jasper St. Pierre" <jstpierre@mecheye.net> wrote:
>
> > I don't think that's a great idea. The rest of my system uses Pango's
> > algorithms for doing font fallback and font shaping, and I don't see a
> > reason to differ from it.
> >
> > Not to mention that it's very unlikely that I want my window title to
> > suddenly switch completely to a fullwidth font because it had one
> Japanese
> > character in it.
> >
>
> Hi, Jasper.
>
> So do you think that the fonts list isn't needed?
> If users want the behavior Bill showed, they just need to set fonts=sans.
> That doesn't suddenly switch completely to a fullwidth font.
>
> I want to know what you need.
> Please tell me the way you want to solve the problem which is why I wrote
> this series.
>
> Thanks.
> --
> Ryo Munakata <ryomnktml@gmail.com>
>
On Sat, 4 Oct 2014 18:53:30 -0700
"Jasper St. Pierre" <jstpierre@mecheye.net> wrote:

> Set a font description like "Sans" and then let Pango do the glyph
> selection with fallback fonts. It hooks together with fontconfig -- it
> knows well enough what font options are available.

I agree with that.

Ryo, will you be sending another patch then?


Thanks,
pq

> On Sat, Oct 4, 2014 at 6:47 PM, Ryo Munakata <ryomnktml@gmail.com> wrote:
> 
> > On Sat, 4 Oct 2014 18:01:51 -0700
> > "Jasper St. Pierre" <jstpierre@mecheye.net> wrote:
> >
> > > I don't think that's a great idea. The rest of my system uses Pango's
> > > algorithms for doing font fallback and font shaping, and I don't see a
> > > reason to differ from it.
> > >
> > > Not to mention that it's very unlikely that I want my window title to
> > > suddenly switch completely to a fullwidth font because it had one
> > Japanese
> > > character in it.
> > >
> >
> > Hi, Jasper.
> >
> > So do you think that the fonts list isn't needed?
> > If users want the behavior Bill showed, they just need to set fonts=sans.
> > That doesn't suddenly switch completely to a fullwidth font.
> >
> > I want to know what you need.
> > Please tell me the way you want to solve the problem which is why I wrote
> > this series.
> >
> > Thanks.
> > --
> > Ryo Munakata <ryomnktml@gmail.com>