Commit dddcc0e7 authored by Jan D's avatar Jan D

Add cairo drawing.

* configure.ac (with-cairo): New option.
(USE_CAIRO): Default to yes for Gtk+ 3.  Add code to test for cairo,
set CAIRO_CFLAGS, CAIRO_LIBS.  Add ftcrfonto to FONT_OBJ if cairo.
Output "Does Emacs use cairo?".

* lisp/version.el (emacs-version): Add cairo version.

* src/Makefile.in (CAIRO_CFLAGS, CAIRO_LIBS): New variables.
(FONT_OBJ): Add comment about ftcrfont.
(ALL_CFLAGS): Add CAIRO_CFLAGS.
(LIBES): Add CAIRO_LIBS.

* src/dispextern.h (struct image): Add cr_data for cairo.
(x_cr_init_fringe): Declare.

* src/font.c (syms_of_font): Call syms_of_ftcrfont for cairo.

* src/font.h (ftcrfont_driver, syms_of_ftcrfont): Declare

* src/fringe.c (x_cr_init_fringe): New function name that shares code
with w32_init_fringe.

* src/ftcrfont.c: New font driver for cairo, based on the ftfont driver.

* src/ftfont.c (ftfont_info_size); New global variable.
(ftfont_open2): New extern function almost the same as old ftfont_open,
but takes the font_object as argument.
(ftfont_open): Build font object and call ftfont_open2.

* src/ftfont.h (ftfont_open2, ftfont_info_size): Declare.

* src/gtkutil.c (xg_clear_under_internal_border)
(xg_update_scrollbar_pos, xg_update_horizontal_scrollbar_pos): Only
queue_draw if not cairo.  Change args to x_clear_area.
(xg_get_font): Use Qftcr when using cairo, Qxft otherwise.
(xg_page_setup_dialog, xg_get_page_setup, draw_page)
(xg_print_frames_dialog): New functions for printing.

* src/gtkutil.h (xg_page_setup_dialog, xg_get_page_setup)
(xg_print_frames_dialog): Declare.

* src/image.c: Add defined (USE_CAIRO) for PNG.
Add !defined USE_CAIRO for W32 PNG code.
(x_clear_image): If cairo, destroy the surface in cr_data.
(png_load): Add new cairo compatible implementation.
(lookup_image_type): Add defined (USE_CAIRO) for define png_type.

* src/xfns.c: New section Printing.
(x-export-frames, x-page-setup-dialog, x-get-page-setup)
(x-print-frames-dialog): New printing functions.
(Fx_create_frame, x_create_tip_frame): Register ftcrfont if
cairo.
(syms_of_xfns): Defsym Qorientation, Qtop_margin, Qbottom_margin,
Qportrait, Qlandscape, Qreverse_portrait, Qreverse_landscape).
(syms_of_xfns): Provide cairo and defvar cairo-version-string.
defsubr Sx_page_setup_dialog, Sx_get_page_setup, Sx_print_frames_dialog.

* src/xterm.c (x_clear_area1, x_prepare_for_xlibdraw)
(x_set_clip_rectangles, x_reset_clip_rectangles, x_fill_rectangle)
(x_draw_rectangle, x_fill_trapezoid_for_relief, x_clear_window)
(x_gc_get_ext_data, x_extension_initialize, x_cr_accumulate_data):
Declare.
(FRAME_CR_CONTEXT, FRAME_CR_SURFACE): New macros.
(max_fringe_bmp, fringe_bmp): New variables.
(x_gc_get_ext_data, x_extension_initialize)
(x_cr_destroy_surface, x_begin_cr_clip, x_end_cr_clip)
(x_set_cr_source_with_gc_foreground)
(x_set_cr_source_with_gc_background, x_cr_define_fringe_bitmap)
(x_cr_destroy_fringe_bitmap, x_cr_draw_image, x_cr_draw_frame)
(x_cr_accumulate_data, x_cr_destroy, x_cr_export_frames)
(x_prepare_for_xlibdraw, x_set_clip_rectangles)
(x_reset_clip_rectangles, x_fill_rectangle, x_draw_rectangle)
(x_clear_window, x_fill_trapezoid_for_relief): New functions.
(x_update_begin): Create cairo surface if needed.
(x_draw_vertical_window_border): Call x_fill_rectangle for cairo.
(x_update_end): Paint cairo drawing surface to xlib surface.
(x_clear_under_internal_border, x_after_update_window_line): Adjust
arguments to x_clear_area.
(x_draw_fringe_bitmap): Call x_fill_rectangle.  Get GC values and
call x_cr_draw_image for cairo.  Call x_reset_clip_rectangles instead
of XSetClipMask.
(x_set_glyph_string_clipping)
(x_set_glyph_string_clipping_exactly): Use x_set_clip_rectangles
instead of XSetClipRectangles.
(x_clear_glyph_string_rect, x_draw_glyph_string_background): Use
x_fill_rectangle instead of XFillRectangle.
(x_draw_glyph_string_foreground)
(x_draw_composite_glyph_string_foreground)
(x_draw_glyphless_glyph_string_foreground): Use x_draw_rectangle instead
of XDrawRectangle.
(x_draw_relief_rect): Add code for USE_CAIRO.
Call x_reset_clip_rectangles instead of XSetClipMask.
(x_draw_box_rect): x_set_clip_rectangles instead of XSetClipRectangles,
x_fill_rectangle instead of XFillRectangle, x_reset_clip_rectangles
instead of XSetClipMask.
(x_draw_image_foreground, x_draw_image_foreground_1):
x_draw_rectangle instead of XDrawRectangle.
(x_draw_glyph_string_bg_rect): x_fill_rectangle instead of
XFillRectangle.
(x_draw_image_glyph_string): If img has cr_data, use it as
a cairo surface.
(x_draw_stretch_glyph_string): x_set_clip_rectangles instead of
XSetClipRectangles, x_fill_rectangle instead of XFillRectangle.
(x_draw_glyph_string): x_fill_rectangle instead of XFillRectangle.,
x_reset_clip_rectangles instead of XSetClipMask.
(x_shift_glyphs_for_insert): Call x_prepare_for_xlibdraw.
(x_clear_area1): New function that calls XClearArea.
(x_clear_area): Takes frame as parameter, calls x_clear_area1 for
non-cairo.
(x_clear_frame): x_clear_window instead of XClearWindow.
(x_scroll_run): Set frame garbaged if cairo.
(XTmouse_position): Initialize *part to 0.
(x_scroll_bar_create): Adjust arguments to x_clear_area.
(x_scroll_bar_set_handle): x_clear_area1 instead of x_clear_area,
x_fill_rectangle instead of XFillRectangle.
(XTset_vertical_scroll_bar, XTset_horizontal_scroll_bar): Adjust
arguments to x_clear_area.
(x_scroll_bar_expose): x_draw_rectangle instead of XDrawRectangle.
(handle_one_xevent): Adjust arguments to x_clear_area.
Destroy cairo surface for frame if ConfigureNotify.
(x_clip_to_row): x_set_clip_rectangles instead of XSetClipRectangles.
(x_draw_hollow_cursor): x_draw_rectangle instead of XDrawRectangle,
x_reset_clip_rectangles instead of XSetClipMask.
(x_draw_bar_cursor): x_fill_rectangle instead of XFillRectangle,
x_reset_clip_rectangles instead of XSetClipMask.
(x_clear_frame_area): Adjust arguments to x_clear_area.
(x_free_frame_resources): Call x_prepare_for_xlibdraw.
(x_term_init): Call x_extension_initialize if cairo.
(x_redisplay_interface): Add x_cr_define_fringe_bitmap,
x_cr_destroy_fringe_bitmap for cairo.
(x_initialize): Call x_cr_init_fringe for cairo.

* src/xterm.h: Add include of cairo header files.
(x_bitmap_record): Add img if cairo.
(x_gc_ext_data): New struct for cairo.
(x_display_info): Add ext_codes for cairo.
(x_output): Add cr_context and cr_surface for cairo.
(x_clear_area): Change arguments from Display*/Window to frame pointer.
(x_query_color, x_begin_cr_clip, x_end_cr_clip)
(x_set_cr_source_with_gc_foreground, x_set_cr_source_with_gc_background)
(x_cr_draw_frame, x_cr_export_frames): Declare.
parent 061c7e2b
2015-02-11 Jan Djärv <jan.h.d@swipnet.se>
* configure.ac (with-cairo): New option.
(USE_CAIRO): Default to yes for Gtk+ 3. Add code to test for cairo,
set CAIRO_CFLAGS, CAIRO_LIBS. Add ftcrfonto to FONT_OBJ if cairo.
Output "Does Emacs use cairo?".
2015-02-09 Paul Eggert <eggert@cs.ucla.edu>
* configure.ac (HAVE_LIBXML2): Add missing comma.
......
......@@ -335,6 +335,7 @@ OPTION_DEFAULT_ON([tiff],[don't compile with TIFF image support])
OPTION_DEFAULT_ON([gif],[don't compile with GIF image support])
OPTION_DEFAULT_ON([png],[don't compile with PNG image support])
OPTION_DEFAULT_ON([rsvg],[don't compile with SVG image support])
OPTION_DEFAULT_OFF([cairo],[compile with Cairo drawing])
OPTION_DEFAULT_ON([xml2],[don't compile with XML parsing support])
OPTION_DEFAULT_ON([imagemagick],[don't compile with ImageMagick image support])
......@@ -2386,6 +2387,7 @@ if test "${opsys}" != "mingw32"; then
AC_DEFINE(HAVE_GTK3, 1, [Define to 1 if using GTK 3 or later.])
GTK_OBJ=emacsgtkfixed.o
gtk_term_header=gtkutil.h
USE_CAIRO=yes
USE_GTK_TOOLKIT="GTK3"
if test "x$ac_enable_gtk_deprecation_warnings" = x; then
AC_DEFINE([GDK_DISABLE_DEPRECATION_WARNINGS], [1],
......@@ -3052,6 +3054,30 @@ AC_SUBST(LIBOTF_LIBS)
AC_SUBST(M17N_FLT_CFLAGS)
AC_SUBST(M17N_FLT_LIBS)
USE_CAIRO=no
if test "${HAVE_X11}" = "yes"; then
if test "${with_cairo}" != "no"; then
CAIRO_REQUIRED=1.12.0
CAIRO_MODULE="cairo >= $CAIRO_REQUIRED"
PKG_CHECK_MODULES(CAIRO, $CAIRO_MODULE, USE_CAIRO=yes, :)
if test $USE_CAIRO = yes; then
AC_DEFINE(USE_CAIRO, 1, [Define to 1 if using cairo.])
else
AC_MSG_ERROR([cairo requested but not found.])
fi
with_xpm=no
with_jpeg=no
with_gif=no
with_tiff=no
CFLAGS="$CFLAGS $CAIRO_CFLAGS"
LIBS="$LIBS $CAIRO_LIBS"
AC_SUBST(CAIRO_CFLAGS)
AC_SUBST(CAIRO_LIBS)
fi
fi
### Use -lXpm if available, unless `--with-xpm=no'.
### mingw32 doesn't use -lXpm, since it loads the library dynamically.
### In the Cygwin-w32 build, we need to use /usr/include/noX/X11/xpm.h
......@@ -3987,8 +4013,8 @@ OLDCFLAGS="$CFLAGS"
OLDLIBS="$LIBS"
CFLAGS="$CFLAGS $GTK_CFLAGS $RSVG_CFLAGS $DBUS_CFLAGS $SETTINGS_CFLAGS"
LIBS="$LIBS $GTK_LIBS $RSVG_LIBS $DBUS_LIBS $SETTINGS_LIBS"
CFLAGS="$CFLAGS $GFILENOTIFY_CFLAGS"
LIBS="$LIBS $GFILENOTIFY_LIBS"
CFLAGS="$CFLAGS $GFILENOTIFY_CFLAGS $CAIRO_CFLAGS"
LIBS="$LIBS $GFILENOTIFY_LIBS $CAIRO_LIBS"
AC_MSG_CHECKING([whether GLib is linked in])
AC_LINK_IFELSE([AC_LANG_PROGRAM(
[[#include <glib.h>
......@@ -4754,7 +4780,9 @@ if test "${HAVE_X_WINDOWS}" = "yes" ; then
XMENU_OBJ=xmenu.o
XOBJ="xterm.o xfns.o xselect.o xrdb.o xsmfns.o xsettings.o"
FONT_OBJ=xfont.o
if test "$HAVE_XFT" = "yes"; then
if test "$USE_CAIRO" = "yes"; then
FONT_OBJ="ftfont.o ftcrfont.o"
elif test "$HAVE_XFT" = "yes"; then
FONT_OBJ="$FONT_OBJ ftfont.o xftfont.o ftxfont.o"
elif test "$HAVE_FREETYPE" = "yes"; then
FONT_OBJ="$FONT_OBJ ftfont.o ftxfont.o"
......@@ -5101,6 +5129,7 @@ echo " Does Emacs use -ltiff? ${HAVE_TIFF}"
echo " Does Emacs use a gif library? ${HAVE_GIF} $LIBGIF"
echo " Does Emacs use a png library? ${HAVE_PNG} $LIBPNG"
echo " Does Emacs use -lrsvg-2? ${HAVE_RSVG}"
echo " Does Emacs use cairo? ${USE_CAIRO}"
echo " Does Emacs use imagemagick? ${HAVE_IMAGEMAGICK}"
echo " Does Emacs support sound? ${HAVE_SOUND}"
......
2015-02-11 Jan Djärv <jan.h.d@swipnet.se>
* version.el (emacs-version): Add cairo version.
2015-02-11 Martin Rudalics <rudalics@gmx.at>
* frame.el (toggle-frame-maximized, toggle-frame-fullscreen):
......
......@@ -56,8 +56,8 @@ to the system configuration; look at `system-configuration' instead."
(interactive "P")
(let ((version-string
(format (if (not (called-interactively-p 'interactive))
"GNU Emacs %s (%s%s%s)\n of %s on %s"
"GNU Emacs %s (%s%s%s) of %s on %s")
"GNU Emacs %s (%s%s%s%s)\n of %s on %s"
"GNU Emacs %s (%s%s%s%s) of %s on %s")
emacs-version
system-configuration
(cond ((featurep 'motif)
......@@ -68,6 +68,9 @@ to the system configuration; look at `system-configuration' instead."
((featurep 'ns)
(format ", NS %s" ns-version-string))
(t ""))
(if (featurep 'cairo)
(format ", cairo version %s" cairo-version-string)
"")
(if (and (boundp 'x-toolkit-scroll-bars)
(memq x-toolkit-scroll-bars '(xaw xaw3d)))
(format ", %s scroll bars"
......
2015-02-11 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
Jan Djärv <jan.h.d@swipnet.se>
* xterm.h: Add include of cairo header files.
(x_bitmap_record): Add img if cairo.
(x_gc_ext_data): New struct for cairo.
(x_display_info): Add ext_codes for cairo.
(x_output): Add cr_context and cr_surface for cairo.
(x_clear_area): Change arguments from Display*/Window to frame pointer.
(x_query_color, x_begin_cr_clip, x_end_cr_clip)
(x_set_cr_source_with_gc_foreground, x_set_cr_source_with_gc_background)
(x_cr_draw_frame, x_cr_export_frames): Declare.
* xterm.c (x_clear_area1, x_prepare_for_xlibdraw)
(x_set_clip_rectangles, x_reset_clip_rectangles, x_fill_rectangle)
(x_draw_rectangle, x_fill_trapezoid_for_relief, x_clear_window)
(x_gc_get_ext_data, x_extension_initialize, x_cr_accumulate_data):
Declare.
(FRAME_CR_CONTEXT, FRAME_CR_SURFACE): New macros.
(max_fringe_bmp, fringe_bmp): New variables.
(x_gc_get_ext_data, x_extension_initialize)
(x_cr_destroy_surface, x_begin_cr_clip, x_end_cr_clip)
(x_set_cr_source_with_gc_foreground)
(x_set_cr_source_with_gc_background, x_cr_define_fringe_bitmap)
(x_cr_destroy_fringe_bitmap, x_cr_draw_image, x_cr_draw_frame)
(x_cr_accumulate_data, x_cr_destroy, x_cr_export_frames)
(x_prepare_for_xlibdraw, x_set_clip_rectangles)
(x_reset_clip_rectangles, x_fill_rectangle, x_draw_rectangle)
(x_clear_window, x_fill_trapezoid_for_relief): New functions.
(x_update_begin): Create cairo surface if needed.
(x_draw_vertical_window_border): Call x_fill_rectangle for cairo.
(x_update_end): Paint cairo drawing surface to xlib surface.
(x_clear_under_internal_border, x_after_update_window_line): Adjust
arguments to x_clear_area.
(x_draw_fringe_bitmap): Call x_fill_rectangle. Get GC values and
call x_cr_draw_image for cairo. Call x_reset_clip_rectangles instead
of XSetClipMask.
(x_set_glyph_string_clipping)
(x_set_glyph_string_clipping_exactly): Use x_set_clip_rectangles
instead of XSetClipRectangles.
(x_clear_glyph_string_rect, x_draw_glyph_string_background): Use
x_fill_rectangle instead of XFillRectangle.
(x_draw_glyph_string_foreground)
(x_draw_composite_glyph_string_foreground)
(x_draw_glyphless_glyph_string_foreground): Use x_draw_rectangle instead
of XDrawRectangle.
(x_draw_relief_rect): Add code for USE_CAIRO.
Call x_reset_clip_rectangles instead of XSetClipMask.
(x_draw_box_rect): x_set_clip_rectangles instead of XSetClipRectangles,
x_fill_rectangle instead of XFillRectangle, x_reset_clip_rectangles
instead of XSetClipMask.
(x_draw_image_foreground, x_draw_image_foreground_1):
x_draw_rectangle instead of XDrawRectangle.
(x_draw_glyph_string_bg_rect): x_fill_rectangle instead of
XFillRectangle.
(x_draw_image_glyph_string): If img has cr_data, use it as
a cairo surface.
(x_draw_stretch_glyph_string): x_set_clip_rectangles instead of
XSetClipRectangles, x_fill_rectangle instead of XFillRectangle.
(x_draw_glyph_string): x_fill_rectangle instead of XFillRectangle.,
x_reset_clip_rectangles instead of XSetClipMask.
(x_shift_glyphs_for_insert): Call x_prepare_for_xlibdraw.
(x_clear_area1): New function that calls XClearArea.
(x_clear_area): Takes frame as parameter, calls x_clear_area1 for
non-cairo.
(x_clear_frame): x_clear_window instead of XClearWindow.
(x_scroll_run): Set frame garbaged if cairo.
(XTmouse_position): Initialize *part to 0.
(x_scroll_bar_create): Adjust arguments to x_clear_area.
(x_scroll_bar_set_handle): x_clear_area1 instead of x_clear_area,
x_fill_rectangle instead of XFillRectangle.
(XTset_vertical_scroll_bar, XTset_horizontal_scroll_bar): Adjust
arguments to x_clear_area.
(x_scroll_bar_expose): x_draw_rectangle instead of XDrawRectangle.
(handle_one_xevent): Adjust arguments to x_clear_area.
Destroy cairo surface for frame if ConfigureNotify.
(x_clip_to_row): x_set_clip_rectangles instead of XSetClipRectangles.
(x_draw_hollow_cursor): x_draw_rectangle instead of XDrawRectangle,
x_reset_clip_rectangles instead of XSetClipMask.
(x_draw_bar_cursor): x_fill_rectangle instead of XFillRectangle,
x_reset_clip_rectangles instead of XSetClipMask.
(x_clear_frame_area): Adjust arguments to x_clear_area.
(x_free_frame_resources): Call x_prepare_for_xlibdraw.
(x_term_init): Call x_extension_initialize if cairo.
(x_redisplay_interface): Add x_cr_define_fringe_bitmap,
x_cr_destroy_fringe_bitmap for cairo.
(x_initialize): Call x_cr_init_fringe for cairo.
* xfns.c: New section Printing.
(x-export-frames, x-page-setup-dialog, x-get-page-setup)
(x-print-frames-dialog): New printing functions.
(Fx_create_frame, x_create_tip_frame): Register ftcrfont if
cairo.
(syms_of_xfns): Defsym Qorientation, Qtop_margin, Qbottom_margin,
Qportrait, Qlandscape, Qreverse_portrait, Qreverse_landscape).
(syms_of_xfns): Provide cairo and defvar cairo-version-string.
defsubr Sx_page_setup_dialog, Sx_get_page_setup, Sx_print_frames_dialog.
* image.c: Add defined (USE_CAIRO) for PNG.
Add !defined USE_CAIRO for W32 PNG code.
(x_clear_image): If cairo, destroy the surface in cr_data.
(png_load): Add new cairo compatible implementation.
(lookup_image_type): Add defined (USE_CAIRO) for define png_type.
* gtkutil.h (xg_page_setup_dialog, xg_get_page_setup)
(xg_print_frames_dialog): Declare.
* gtkutil.c (xg_clear_under_internal_border)
(xg_update_scrollbar_pos, xg_update_horizontal_scrollbar_pos): Only
queue_draw if not cairo. Change args to x_clear_area.
(xg_get_font): Use Qftcr when using cairo, Qxft otherwise.
(xg_page_setup_dialog, xg_get_page_setup, draw_page)
(xg_print_frames_dialog): New functions for printing.
* ftfont.h (ftfont_open2, ftfont_info_size): Declare.
* ftfont.c (ftfont_info_size); New global variable.
(ftfont_open2): New extern function almost the same as old ftfont_open,
but takes the font_object as argument.
(ftfont_open): Build font object and call ftfont_open2.
* ftcrfont.c: New font driver for cairo, based on the ftfont driver.
* fringe.c (x_cr_init_fringe): New function name that shares code
with w32_init_fringe.
* font.h (ftcrfont_driver, syms_of_ftcrfont): Declare
* font.c (syms_of_font): Call syms_of_ftcrfont for cairo.
* dispextern.h (struct image): Add cr_data for cairo.
(x_cr_init_fringe): Declare.
* Makefile.in (CAIRO_CFLAGS, CAIRO_LIBS): New variables.
(FONT_OBJ): Add comment about ftcrfont.
(ALL_CFLAGS): Add CAIRO_CFLAGS.
(LIBES): Add CAIRO_LIBS.
2015-02-11 Martin Rudalics <rudalics@gmx.at>
* w32term.c (w32_read_socket): In SIZE_MAXIMIZED and
......
......@@ -218,6 +218,9 @@ CFLAGS_SOUND= @CFLAGS_SOUND@
RSVG_LIBS= @RSVG_LIBS@
RSVG_CFLAGS= @RSVG_CFLAGS@
CAIRO_LIBS= @CAIRO_LIBS@
CAIRO_CFLAGS= @CAIRO_CFLAGS@
IMAGEMAGICK_LIBS= @IMAGEMAGICK_LIBS@
IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@
......@@ -273,6 +276,7 @@ W32_RES_LINK=@W32_RES_LINK@
## Empty if !HAVE_X_WINDOWS
## xfont.o ftfont.o xftfont.o ftxfont.o if HAVE_XFT
## xfont.o ftfont.o ftxfont.o if HAVE_FREETYPE
## ftfont.o ftcrfont.o if USE_CAIRO
## else xfont.o
FONT_OBJ=@FONT_OBJ@
......@@ -345,7 +349,7 @@ ALL_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
$(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) \
$(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
$(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
$(LIBGNUTLS_CFLAGS) $(GFILENOTIFY_CFLAGS) \
$(LIBGNUTLS_CFLAGS) $(GFILENOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
$(WARN_CFLAGS) $(WERROR_CFLAGS) $(CFLAGS)
ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS)
......@@ -423,7 +427,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
$(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_ACL) $(LIB_CLOCK_GETTIME) \
$(LIB_EACCESS) $(LIB_FDATASYNC) $(LIB_TIMER_TIME) $(DBUS_LIBS) \
$(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) $(XFIXES_LIBS) \
$(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
$(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) $(CAIRO_LIBS) \
$(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
$(LIBGNUTLS_LIBS) $(LIB_PTHREAD) \
......
......@@ -2939,6 +2939,9 @@ struct image
/* Pixmaps of the image. */
Pixmap pixmap, mask;
#ifdef USE_CAIRO
void *cr_data;
#endif
#ifdef HAVE_X_WINDOWS
/* X images of the image, corresponding to the above Pixmaps.
Non-NULL means it and its Pixmap counterpart may be out of sync
......@@ -3300,6 +3303,9 @@ bool update_window_fringes (struct window *, bool);
void w32_init_fringe (struct redisplay_interface *);
void w32_reset_fringes (void);
#endif
#ifdef USE_CAIRO
void x_cr_init_fringe (struct redisplay_interface *);
#endif
extern unsigned row_hash (struct glyph_row *);
......
......@@ -5280,11 +5280,15 @@ EMACS_FONT_LOG is set. Otherwise, it is set to t. */);
#ifdef HAVE_FREETYPE
syms_of_ftfont ();
#ifdef HAVE_X_WINDOWS
#ifdef USE_CAIRO
syms_of_ftcrfont ();
#else
syms_of_xfont ();
syms_of_ftxfont ();
#ifdef HAVE_XFT
syms_of_xftfont ();
#endif /* HAVE_XFT */
#endif /* not USE_CAIRO */
#endif /* HAVE_X_WINDOWS */
#else /* not HAVE_FREETYPE */
#ifdef HAVE_X_WINDOWS
......
......@@ -844,6 +844,10 @@ extern struct font_driver nsfont_driver;
extern void syms_of_nsfont (void);
extern void syms_of_macfont (void);
#endif /* HAVE_NS */
#ifdef USE_CAIRO
extern struct font_driver ftcrfont_driver;
extern void syms_of_ftcrfont (void);
#endif
#ifndef FONT_DEBUG
#define FONT_DEBUG
......
......@@ -1731,10 +1731,14 @@ init_fringe (void)
fringe_faces = xzalloc (max_fringe_bitmaps * sizeof *fringe_faces);
}
#ifdef HAVE_NTGUI
#if defined (HAVE_NTGUI) || defined (USE_CAIRO)
void
#ifdef HAVE_NTGUI
w32_init_fringe (struct redisplay_interface *rif)
#else
x_cr_init_fringe (struct redisplay_interface *rif)
#endif
{
int bt;
......@@ -1747,7 +1751,9 @@ w32_init_fringe (struct redisplay_interface *rif)
rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
}
}
#endif
#ifdef HAVE_NTGUI
void
w32_reset_fringes (void)
{
......
/* ftcrfont.c -- FreeType font driver on cairo.
Copyright (C) 2015 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdio.h>
#include <cairo-ft.h>
#include "lisp.h"
#include "dispextern.h"
#include "xterm.h"
#include "frame.h"
#include "blockinput.h"
#include "character.h"
#include "charset.h"
#include "fontset.h"
#include "font.h"
#include "ftfont.h"
/* FTCR font driver. */
/* The actual structure for ftcr font that can be casted to struct
font. */
struct ftcrfont_info
{
struct font font;
/* The following six members must be here in this order to be
compatible with struct ftfont_info (in ftfont.c). */
#ifdef HAVE_LIBOTF
bool maybe_otf; /* Flag to tell if this may be OTF or not. */
OTF *otf;
#endif /* HAVE_LIBOTF */
FT_Size ft_size;
int index;
FT_Matrix matrix;
cairo_font_face_t *cr_font_face;
/* To prevent cairo from cluttering the activated FT_Size maintained
in ftfont.c, we activate this special FT_Size before drawing. */
FT_Size ft_size_draw;
/* Font metrics cache. */
struct font_metrics **metrics;
short metrics_nrows;
};
#define METRICS_NCOLS_PER_ROW (128)
enum metrics_status
{
METRICS_INVALID = -1, /* metrics entry is invalid */
};
#define METRICS_STATUS(metrics) ((metrics)->ascent + (metrics)->descent)
#define METRICS_SET_STATUS(metrics, status) \
((metrics)->ascent = 0, (metrics)->descent = (status))
/* Prototypes for helper function. */
static int ftcrfont_glyph_extents (struct font *, unsigned,
struct font_metrics *);
/* Prototypes for font-driver methods. */
static Lisp_Object ftcrfont_list (struct frame*, Lisp_Object);
static Lisp_Object ftcrfont_match (struct frame*, Lisp_Object);
static Lisp_Object ftcrfont_open (struct frame*, Lisp_Object, int);
static void ftcrfont_close (struct font *);
static void ftcrfont_text_extents (struct font *, unsigned *, int,
struct font_metrics *);
static int ftcrfont_draw (struct glyph_string *, int, int, int, int, bool);
struct font_driver ftcrfont_driver;
static int
ftcrfont_glyph_extents (struct font *font,
unsigned glyph,
struct font_metrics *metrics)
{
struct ftcrfont_info *ftcrfont_info = (struct ftcrfont_info *) font;
int row, col;
struct font_metrics *cache;
row = glyph / METRICS_NCOLS_PER_ROW;
col = glyph % METRICS_NCOLS_PER_ROW;
if (row >= ftcrfont_info->metrics_nrows)
{
ftcrfont_info->metrics =
xrealloc (ftcrfont_info->metrics,
sizeof (struct font_metrics *) * (row + 1));
bzero (ftcrfont_info->metrics + ftcrfont_info->metrics_nrows,
(sizeof (struct font_metrics *)
* (row + 1 - ftcrfont_info->metrics_nrows)));
ftcrfont_info->metrics_nrows = row + 1;
}
if (ftcrfont_info->metrics[row] == NULL)
{
struct font_metrics *new;
int i;
new = xmalloc (sizeof (struct font_metrics) * METRICS_NCOLS_PER_ROW);
for (i = 0; i < METRICS_NCOLS_PER_ROW; i++)
METRICS_SET_STATUS (new + i, METRICS_INVALID);
ftcrfont_info->metrics[row] = new;
}
cache = ftcrfont_info->metrics[row] + col;
if (METRICS_STATUS (cache) == METRICS_INVALID)
ftfont_driver.text_extents (font, &glyph, 1, cache);
if (metrics)
*metrics = *cache;
return cache->width;
}
static Lisp_Object
ftcrfont_list (struct frame *f, Lisp_Object spec)
{
Lisp_Object list = ftfont_driver.list (f, spec), tail;
for (tail = list; CONSP (tail); tail = XCDR (tail))
ASET (XCAR (tail), FONT_TYPE_INDEX, Qftcr);
return list;
}
static Lisp_Object
ftcrfont_match (struct frame *f, Lisp_Object spec)
{
Lisp_Object entity = ftfont_driver.match (f, spec);
if (VECTORP (entity))
ASET (entity, FONT_TYPE_INDEX, Qftcr);
return entity;
}
extern FT_Face ftfont_get_ft_face (Lisp_Object);
static Lisp_Object
ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
Lisp_Object font_object;
struct font *font;
struct ftcrfont_info *ftcrfont_info;
FT_Face ft_face;
FT_UInt size;
block_input ();
size = XINT (AREF (entity, FONT_SIZE_INDEX));
if (size == 0)
size = pixel_size;
font_object = font_build_object (VECSIZE (struct ftcrfont_info),
Qftcr, entity, size);
font_object = ftfont_open2 (f, entity, pixel_size, font_object);
if (NILP (font_object)) return Qnil;
font = XFONT_OBJECT (font_object);
font->driver = &ftcrfont_driver;
ftcrfont_info = (struct ftcrfont_info *) font;
ft_face = ftcrfont_info->ft_size->face;
FT_New_Size (ft_face, &ftcrfont_info->ft_size_draw);
FT_Activate_Size (ftcrfont_info->ft_size_draw);
FT_Set_Pixel_Sizes (ft_face, 0, font->pixel_size);
ftcrfont_info->cr_font_face =
cairo_ft_font_face_create_for_ft_face (ft_face, 0);
ftcrfont_info->metrics = NULL;
ftcrfont_info->metrics_nrows = 0;
unblock_input ();
return font_object;
}
static void
ftcrfont_close (struct font *font)
{
struct ftcrfont_info *ftcrfont_info = (struct ftcrfont_info *) font;
int i;
block_input ();
for (i = 0; i < ftcrfont_info->metrics_nrows; i++)
if (ftcrfont_info->metrics[i])
xfree (ftcrfont_info->metrics[i]);
if (ftcrfont_info->metrics)
xfree (ftcrfont_info->metrics);
FT_Done_Size (ftcrfont_info->ft_size_draw);
cairo_font_face_destroy (ftcrfont_info->cr_font_face);
unblock_input ();
ftfont_driver.close (font);
}
static void
ftcrfont_text_extents (struct font *font,
unsigned *code,
int nglyphs,
struct font_metrics *metrics)
{
int width, i;
block_input ();
width = ftcrfont_glyph_extents (font, code[0], metrics);
for (i = 1; i < nglyphs; i++)
{
struct font_metrics m;
int w = ftcrfont_glyph_extents (font, code[i], metrics ? &m : NULL);
if (metrics)
{
if (width + m.lbearing < metrics->lbearing)
metrics->lbearing = width + m.lbearing;
if (width + m.rbearing > metrics->rbearing)
metrics->rbearing = width + m.rbearing;
if (m.ascent > metrics->ascent)
metrics->ascent = m.ascent;
if (m.descent > metrics->descent)
metrics->descent = m.descent;
}
width += w;
}
unblock_input ();
if (metrics)
metrics->width = width;
}
static int
ftcrfont_draw (struct glyph_string *s,
int from, int to, int x, int y, bool with_background)
{
struct frame *f = s->f;
struct face *face = s->face;
struct ftcrfont_info *ftcrfont_info = (struct ftcrfont_info *) s->font;
cairo_t *cr;
cairo_glyph_t *glyphs;
cairo_surface_t *surface;
int len = to - from;
int i;
block_input ();
cr = x_begin_cr_clip (f, s->gc);
if (with_background)
{
x_set_cr_source_with_gc_background (f, s->gc);
cairo_rectangle (cr, x, y - FONT_BASE (face->font),
s->width, FONT_HEIGHT (face->font));
cairo_fill (cr);
}
glyphs = alloca (sizeof (cairo_glyph_t) * len);
for (i = 0; i < len; i++)
{
unsigned code = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
| XCHAR2B_BYTE2 (s->char2b + from + i));
glyphs[i].index = code;
glyphs[i].x = x;
glyphs[i].y = y;
x += (s->padding_p ? 1 : ftcrfont_glyph_extents (s->font, code, NULL));
}
x_set_cr_source_with_gc_foreground (f, s->gc);
cairo_set_font_face (cr, ftcrfont_info->cr_font_face);
cairo_set_font_size (cr, s->font->pixel_size);
/* cairo_set_font_matrix */
/* cairo_set_font_options */
FT_Activate_Size (ftcrfont_info->ft_size_draw);
cairo_show_glyphs (cr, glyphs, len);
surface = cairo_get_target (cr);
if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
cairo_surface_flush (surface);
x_end_cr_clip (f);
unblock_input ();
return len;
}