summaryrefslogtreecommitdiff
path: root/lwlib/lwlib-utils.c
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>2019-04-24 12:31:37 +0900
committerYAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>2019-04-24 12:31:37 +0900
commit5f4e8e2e088de9fb76cb631077c6eddd3219f594 (patch)
treeabb80bc8ec36c28d4eef08b92db90a142f641be6 /lwlib/lwlib-utils.c
parent1828e9a9b7481572448284a8e5925bf97f2145f7 (diff)
downloademacs-5f4e8e2e088de9fb76cb631077c6eddd3219f594.tar.gz
Don't link libXft when using cairo
* configure.ac: Check cairo early. Don't try Xft if cairo is used. * lwlib/lwlib-utils.h [USE_CAIRO]: Include cairo.h and fontconfig.h. (XftFont, XftDraw, XftColor, XGlyphInfo) [USE_CAIRO]: New typedefs. (XftFontOpenName, XftFontClose, XftDrawCreate, XftDrawDestroy) (XftDrawRect, XftDrawStringUtf8, XftTextExtentsUtf8) [USE_CAIRO]: New macros. (crxft_font_open_name, crxft_font_close, crxft_draw_create) (crxft_draw_rect, crxft_draw_string, crxft_text_extents) [USE_CAIRO]: New externs. * lwlib/lwlib-utils.c [USE_CAIRO]: Include math.h, cairo-ft.h, and cairo-xlib.h. (crxft_font_open_name, crxft_font_close, crxft_draw_create) (crxft_set_source_color, crxft_draw_rect, crxft_draw_string) (crxft_text_extents) [USE_CAIRO]: New Xft compatibility functions. * lwlib/xlwmenuP.h [USE_CAIRO]: Include lwlib-utils.h. * lwlib/xlwmenu.c (display_menu_item) [USE_CAIRO]: Call cairo_surface_mark_dirty and cairo_surface_flush. * lwlib/lwlib-Xaw.c [USE_CAIRO]: Include stdlib.h and lwlib-utils.h. (draw_text) [USE_CAIRO]: Call cairo_surface_flush. * src/xsettings.c [USE_CAIRO]: Include fontconfig.h (apply_xft_settings) [!HAVE_XFT]: Don't call XftDefaultSubstitute or XftDefaultSet. * lwlib/lwlib-Xaw.c: * lwlib/lwlib-int.h: * lwlib/xlwmenu.c: * lwlib/xlwmenuP.h: * src/xrdb.c: * src/xsettings.c: * src/xterm.c: Replace all #ifdef HAVE_XFT with #if defined USE_CAIRO || defined HAVE_XFT. * src/xfns.c (x_default_font_parameter): Replace #ifdef HAVE_XFT with #if defined USE_CAIRO || defined HAVE_XFT.
Diffstat (limited to 'lwlib/lwlib-utils.c')
-rw-r--r--lwlib/lwlib-utils.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/lwlib/lwlib-utils.c b/lwlib/lwlib-utils.c
index 7c60bdb056d..2c0a931f9cb 100644
--- a/lwlib/lwlib-utils.c
+++ b/lwlib/lwlib-utils.c
@@ -137,3 +137,143 @@ XtWidgetBeingDestroyedP (Widget widget)
{
return widget->core.being_destroyed;
}
+
+#ifdef USE_CAIRO
+/* Xft emulation on cairo. */
+#include <math.h>
+#include <cairo-ft.h>
+#include <cairo-xlib.h>
+
+XftFont *
+crxft_font_open_name (Display *dpy, int screen, const char *name)
+{
+ XftFont *pub = NULL;
+ FcPattern *pattern = FcNameParse ((FcChar8 *) name);
+ if (pattern)
+ {
+ FcConfigSubstitute (NULL, pattern, FcMatchPattern);
+ double dpi;
+ if (FcPatternGetDouble (pattern, FC_DPI, 0, &dpi) == FcResultNoMatch)
+ {
+ char *v = XGetDefault (dpy, "Xft", FC_DPI);
+ if (v == NULL || sscanf (v, "%lf", &dpi) != 1)
+ dpi = ((DisplayHeight (dpy, screen) * 25.4)
+ / DisplayHeightMM (dpy, screen));
+ FcPatternAddDouble (pattern, FC_DPI, dpi);
+ }
+ FcDefaultSubstitute (pattern);
+ cairo_font_face_t *font_face
+ = cairo_ft_font_face_create_for_pattern (pattern);
+ if (font_face)
+ {
+ double pixel_size;
+ if ((FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &pixel_size)
+ != FcResultMatch)
+ || pixel_size < 1)
+ pixel_size = 10;
+
+ pub = xmalloc (sizeof (*pub));
+ cairo_matrix_t font_matrix, ctm;
+ cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size);
+ cairo_matrix_init_identity (&ctm);
+ cairo_font_options_t *options = cairo_font_options_create ();
+ cairo_ft_font_options_substitute (options, pattern);
+ pub->scaled_font = cairo_scaled_font_create (font_face, &font_matrix,
+ &ctm, options);
+ cairo_font_face_destroy (font_face);
+ cairo_font_options_destroy (options);
+
+ cairo_font_extents_t extents;
+ cairo_scaled_font_extents (pub->scaled_font, &extents);
+ pub->ascent = lround (extents.ascent);
+ pub->descent = lround (extents.descent);
+ pub->height = lround (extents.height);
+ pub->max_advance_width = lround (extents.max_x_advance);
+ }
+ FcPatternDestroy (pattern);
+ }
+ return pub;
+}
+
+void
+crxft_font_close (XftFont *pub)
+{
+ cairo_scaled_font_destroy (pub->scaled_font);
+ xfree (pub);
+}
+
+cairo_t *
+crxft_draw_create (Display *dpy, Drawable drawable, Visual *visual)
+{
+ cairo_t *cr = NULL;
+ Window root;
+ int x, y;
+ unsigned int width, height, border_width, depth;
+
+ if (!XGetGeometry (dpy, drawable, &root, &x, &y, &width, &height,
+ &border_width, &depth))
+ return NULL;
+
+ cairo_surface_t *surface = cairo_xlib_surface_create (dpy, drawable, visual,
+ width, height);
+ if (surface)
+ {
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+ }
+
+ return cr;
+}
+
+static void
+crxft_set_source_color (cairo_t *cr, const XftColor *color)
+{
+ cairo_set_source_rgba (cr, color->color.red / 65535.0,
+ color->color.green / 65535.0,
+ color->color.blue / 65535.0,
+ color->color.alpha / 65535.0);
+}
+
+void
+crxft_draw_rect (cairo_t *cr, const XftColor *color, int x, int y,
+ unsigned int width, unsigned int height)
+{
+ crxft_set_source_color (cr, color);
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_fill (cr);
+}
+
+void
+crxft_draw_string (cairo_t *cr, const XftColor *color, XftFont *pub,
+ int x, int y, const FcChar8 *string, int len)
+{
+ char *buf = xmalloc (len + 1);
+ memcpy (buf, string, len);
+ buf[len] = '\0';
+ crxft_set_source_color (cr, color);
+ cairo_set_scaled_font (cr, pub->scaled_font);
+ cairo_move_to (cr, x, y);
+ cairo_show_text (cr, buf);
+ xfree (buf);
+}
+
+void
+crxft_text_extents (XftFont *pub, const FcChar8 *string, int len,
+ XGlyphInfo *extents)
+{
+ char *buf = xmalloc (len + 1);
+ memcpy (buf, string, len);
+ buf[len] = '\0';
+ cairo_text_extents_t text_extents;
+ cairo_scaled_font_text_extents (pub->scaled_font, buf, &text_extents);
+ xfree (buf);
+ extents->x = ceil (- text_extents.x_bearing);
+ extents->y = ceil (- text_extents.y_bearing);
+ extents->width = (ceil (text_extents.x_bearing + text_extents.width)
+ + extents->x);
+ extents->height = (ceil (text_extents.y_bearing + text_extents.height)
+ + extents->y);
+ extents->xOff = lround (text_extents.x_advance);
+ extents->yOff = lround (text_extents.y_advance);
+}
+#endif /* USE_CAIRO */