[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