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