Merge branch 'cairo'.
Main work done by YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>. Small fixes and image work by Jan D. <jan.h.d@swipnet.se>.
This commit is contained in:
commit
c03c730481
21 changed files with 2321 additions and 141 deletions
21
ChangeLog.1
21
ChangeLog.1
|
@ -1,9 +1,23 @@
|
|||
2015-04-11 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* configure.ac: Allow jpeg with cairo.
|
||||
Allow tiff and gif with cairo.
|
||||
|
||||
2015-04-07 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Merge from gnulib
|
||||
* lib/stddef.in.h: Update from gnulib, incorporating:
|
||||
2015-04-02 stddef: port to pre-C11 GCC on x86
|
||||
|
||||
2015-04-05 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* configure.ac: Allow rsvg with cairo. Move back HAVE_RSVG.
|
||||
|
||||
2015-04-03 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* configure.ac (HAVE_RSVG): Move after cairo.
|
||||
(USE_CAIRO): Disable rsvg, don't disable Xpm.
|
||||
|
||||
2015-04-03 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Port 'configure' to clang 3.5
|
||||
|
@ -108,6 +122,13 @@
|
|||
* configure.ac: Set locallisppath to empty for NS self contained,
|
||||
unless --enable-loadllisppath was given (Bug#19850).
|
||||
|
||||
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.
|
||||
|
|
30
configure.ac
30
configure.ac
|
@ -330,6 +330,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])
|
||||
|
||||
|
@ -2407,6 +2408,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],
|
||||
|
@ -3075,6 +3077,25 @@ 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
|
||||
|
||||
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
|
||||
|
@ -4009,8 +4030,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>
|
||||
|
@ -4776,7 +4797,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"
|
||||
|
@ -5142,6 +5165,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}"
|
||||
|
|
|
@ -1748,6 +1748,12 @@
|
|||
(package-menu--print-info, package-menu--status-predicate):
|
||||
Account for the "incompat" status.
|
||||
|
||||
2015-02-11 Martin Rudalics <rudalics@gmx.at>
|
||||
|
||||
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"
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
2015-04-03 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* Makefile.in (CAIRO_CFLAGS): Add.
|
||||
2015-03-18 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* xlwmenu.c (pop_up_menu): Remove debugging code.
|
||||
|
|
|
@ -33,6 +33,7 @@ C_SWITCH_MACHINE=@C_SWITCH_MACHINE@
|
|||
PROFILING_CFLAGS = @PROFILING_CFLAGS@
|
||||
WARN_CFLAGS = `echo @WARN_CFLAGS@ | sed 's/ -Wwrite-strings//'`
|
||||
WERROR_CFLAGS = @WERROR_CFLAGS@
|
||||
CAIRO_CFLAGS= @CAIRO_CFLAGS@
|
||||
|
||||
CC=@CC@
|
||||
CFLAGS=@CFLAGS@
|
||||
|
@ -88,6 +89,7 @@ endif
|
|||
ALL_CFLAGS= $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \
|
||||
$(C_SWITCH_MACHINE) $(DEPFLAGS) \
|
||||
$(WARN_CFLAGS) $(WERROR_CFLAGS) $(PROFILING_CFLAGS) $(CFLAGS) \
|
||||
$(CAIRO_CFLAGS) \
|
||||
-Demacs -I../src \
|
||||
-I$(srcdir) -I$(srcdir)/../src -I../lib -I$(srcdir)/../lib
|
||||
|
||||
|
|
236
src/ChangeLog.13
236
src/ChangeLog.13
|
@ -1,9 +1,51 @@
|
|||
2015-04-26 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* image.c (xcolor_to_argb32): New function.
|
||||
(get_spec_bg_or_alpha_as_argb): Call xcolor_to_argb32.
|
||||
(pbm_load, png_load_body, jpeg_load_body, gif_load): Only use
|
||||
XImagePtr if ! USE_CAIRO.
|
||||
(pbm_load): Add cairo support.
|
||||
|
||||
2015-04-12 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* xterm.c (x_draw_image_glyph_string): Added missing USE_CAIRO.
|
||||
(x_free_cr_resources): Renamed from x_prepare_for_xlibdraw.
|
||||
(x_cr_draw_frame, x_cr_export_frames, x_shift_glyphs_for_insert)
|
||||
(x_free_frame_resources): Rename x_prepare_for_xlibdraw to
|
||||
x_free_cr_resources.
|
||||
|
||||
* image.c (get_spec_bg_or_alpha_as_argb)
|
||||
(create_cairo_image_surface): New functions when USE_CAIRO.
|
||||
(xpm_load): Call the above functions. Handle XPM without mask
|
||||
when USE_CAIRO.
|
||||
(png_load_body): Handle USE_CAIRO case.
|
||||
(png_load): Remove USE_CAIRO specific fuction, modify png_load_body
|
||||
instead.
|
||||
(jpeg_load_body): Call create_cairo_image_surface.
|
||||
(gif_load, svg_load_image): Handle specified background, call
|
||||
create_cairo_image_surface.
|
||||
|
||||
2015-04-11 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* image.c (jpeg_load_body): Create cairo image surface if USE_CAIRO.
|
||||
(tiff_load): Create cairo image surface if USE_CAIRO.
|
||||
(gif_load): Ditto.
|
||||
|
||||
2015-04-06 Koichi Arakawa <arakawa@pp.iij4u.or.jp> (tiny change)
|
||||
|
||||
* w32proc.c (w32_executable_type): Look for the DLL name in the
|
||||
correct section. This avoids segfaults with some executables.
|
||||
(Bug#20264)
|
||||
|
||||
2015-04-05 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* image.c: #undef COLOR_TABLE_SUPPORT when USE_CAIRO.
|
||||
(x_clear_image): Free cr_data and cr_data2 if set.
|
||||
(xpm_load): Assign data to cr_data2.
|
||||
(svg_load_image): Convert from GdkPixbuf to CAIRO_FORMAT_ARGB32.
|
||||
|
||||
* dispextern.h (struct image): add cr_data2 if cairo.
|
||||
|
||||
2015-04-04 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* xselect.c (x_reply_selection_request)
|
||||
|
@ -15,8 +57,17 @@
|
|||
|
||||
2015-04-03 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* image.c (prepare_image_for_display): Don't load if USE_CAIRO.
|
||||
(x_clear_image): If USE_CAIRO, also free possible img->ximg->obdata and
|
||||
don't return early.
|
||||
(ALLOC_XPM_COLORS): Don't define when USE_CAIRO.
|
||||
(xpm_load): Convert simple Xpms (32 bit ZPixmap) to CAIRO_FORMAT_ARGB32
|
||||
and create a surface.
|
||||
|
||||
* xterm.c (handle_one_xevent): Always redraw tool tips on
|
||||
MapNotify. Update tool tip frame sizes on ConfigureNotify.
|
||||
(x_update_begin): Don't create any surface for non-visible
|
||||
tip frames, the geometry may be wrong.
|
||||
|
||||
2015-03-31 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
|
@ -559,6 +610,191 @@
|
|||
DEFINE_LISP_SYMBOL_BEGIN / DEFINE_LISP_SYMBOL_END. All uses changed.
|
||||
(DEFINE_NONNIL_Q_SYMBOL_MACROS): New macro, defaulting to true.
|
||||
|
||||
2015-02-19 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
|
||||
|
||||
* ftcrfont.c (ftcrfont_draw): Don't flush when drawing to screen.
|
||||
|
||||
2015-02-17 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
|
||||
|
||||
* xterm.c [USE_CAIRO]: Include math.h.
|
||||
(enum corners) [USE_CAIRO]: New enum.
|
||||
(x_erase_corners_for_relief) [USE_CAIRO]: New function.
|
||||
(x_draw_relief_rect) [USE_CAIRO]: Use it. If box width is larger
|
||||
than 1, draw the outermost line using the black relief.
|
||||
|
||||
2015-02-16 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
|
||||
|
||||
* gtkutil.c (xg_page_setup_dialog, xg_get_page_setup, draw_page)
|
||||
(xg_print_frames_dialog): Modernize k&r declarations.
|
||||
|
||||
* xfns.c (Fx_export_frames, Fx_page_setup_dialog, Fx_get_page_setup)
|
||||
(Fx_print_frames_dialog): Modernize k&r declarations.
|
||||
|
||||
* xterm.c (x_draw_window_divider): Use x_fill_rectangle instead of
|
||||
XFillRectangle.
|
||||
(x_draw_horizontal_wave) [USE_CAIRO]: New function.
|
||||
(x_draw_underwave) [USE_CAIRO]: Use it.
|
||||
(x_gc_get_ext_data, x_extension_initialize, 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_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)
|
||||
(x_clear_area): Modernize k&r declarations.
|
||||
(x_cr_draw_image, x_fill_rectangle, x_draw_rectangle)
|
||||
(x_fill_trapezoid_for_relief): Use int instead of unsigned int for
|
||||
width and height args.
|
||||
(x_draw_stretch_glyph_string): Call x_reset_clip_rectangles instead
|
||||
of XSetClipMask.
|
||||
(x_draw_relief_rect) [USE_CAIRO]: Reset clipping.
|
||||
(x_fill_trapezoid_for_relief): Remove unnecessary cairo_close_path.
|
||||
|
||||
2015-02-14 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
|
||||
|
||||
* fringe.c (init_fringe_bitmap) [USE_CAIRO]: Adjust bitmap data for
|
||||
cairo image surface.
|
||||
|
||||
* xterm.c (x_cr_define_fringe_bitmap): Call cairo_surface_mark_dirty.
|
||||
|
||||
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@
|
||||
|
||||
|
@ -350,7 +354,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)
|
||||
|
||||
|
@ -456,7 +460,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) \
|
||||
|
|
|
@ -2941,6 +2941,10 @@ struct image
|
|||
/* Pixmaps of the image. */
|
||||
Pixmap pixmap, mask;
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
void *cr_data;
|
||||
void *cr_data2;
|
||||
#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
|
||||
|
@ -3302,6 +3306,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
|
||||
|
|
24
src/fringe.c
24
src/fringe.c
|
@ -1405,6 +1405,21 @@ init_fringe_bitmap (int which, struct fringe_bitmap *fb, int once_p)
|
|||
unsigned short *bits = fb->bits;
|
||||
int j;
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
for (j = 0; j < fb->height; j++)
|
||||
{
|
||||
unsigned short b = *bits;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
*bits++ = (b << (16 - fb->width));
|
||||
#else
|
||||
b = (unsigned short)((swap_nibble[b & 0xf] << 12)
|
||||
| (swap_nibble[(b>>4) & 0xf] << 8)
|
||||
| (swap_nibble[(b>>8) & 0xf] << 4)
|
||||
| (swap_nibble[(b>>12) & 0xf]));
|
||||
*bits++ = (b >> (16 - fb->width));
|
||||
#endif
|
||||
}
|
||||
#else /* not USE_CAIRO */
|
||||
if (fb->width <= 8)
|
||||
{
|
||||
unsigned char *cbits = (unsigned char *)fb->bits;
|
||||
|
@ -1433,6 +1448,7 @@ init_fringe_bitmap (int which, struct fringe_bitmap *fb, int once_p)
|
|||
*bits++ = b;
|
||||
}
|
||||
}
|
||||
#endif /* not USE_CAIRO */
|
||||
#endif /* HAVE_X_WINDOWS */
|
||||
|
||||
}
|
||||
|
@ -1731,10 +1747,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 +1767,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)
|
||||
{
|
||||
|
|
320
src/ftcrfont.c
Normal file
320
src/ftcrfont.c
Normal file
|
@ -0,0 +1,320 @@
|
|||
/* 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;
|
||||
cairo_surface_type_t surface_type;
|
||||
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);
|
||||
/* XXX: It used to be necessary to flush when exporting. It might
|
||||
be the case that this is no longer necessary. */
|
||||
surface_type = cairo_surface_get_type (surface);
|
||||
if (surface_type != CAIRO_SURFACE_TYPE_XLIB
|
||||
&& (surface_type != CAIRO_SURFACE_TYPE_IMAGE
|
||||
|| cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32))
|
||||
cairo_surface_flush (surface);
|
||||
|
||||
x_end_cr_clip (f);
|
||||
|
||||
unblock_input ();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
syms_of_ftcrfont (void)
|
||||
{
|
||||
if (ftfont_info_size != offsetof (struct ftcrfont_info, cr_font_face))
|
||||
abort ();
|
||||
|
||||
DEFSYM (Qftcr, "ftcr");
|
||||
|
||||
ftcrfont_driver = ftfont_driver;
|
||||
ftcrfont_driver.type = Qftcr;
|
||||
ftcrfont_driver.list = ftcrfont_list;
|
||||
ftcrfont_driver.match = ftcrfont_match;
|
||||
ftcrfont_driver.open = ftcrfont_open;
|
||||
ftcrfont_driver.close = ftcrfont_close;
|
||||
ftcrfont_driver.text_extents = ftcrfont_text_extents;
|
||||
ftcrfont_driver.draw = ftcrfont_draw;
|
||||
register_font_driver (&ftcrfont_driver, NULL);
|
||||
}
|
26
src/ftfont.c
26
src/ftfont.c
|
@ -67,6 +67,8 @@ struct ftfont_info
|
|||
FT_Matrix matrix;
|
||||
};
|
||||
|
||||
size_t ftfont_info_size = sizeof (struct ftfont_info);
|
||||
|
||||
enum ftfont_cache_for
|
||||
{
|
||||
FTFONT_CACHE_FOR_FACE,
|
||||
|
@ -1161,8 +1163,11 @@ ftfont_list_family (struct frame *f)
|
|||
}
|
||||
|
||||
|
||||
static Lisp_Object
|
||||
ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
|
||||
Lisp_Object
|
||||
ftfont_open2 (struct frame *f,
|
||||
Lisp_Object entity,
|
||||
int pixel_size,
|
||||
Lisp_Object font_object)
|
||||
{
|
||||
struct ftfont_info *ftfont_info;
|
||||
struct font *font;
|
||||
|
@ -1170,7 +1175,7 @@ ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
|
|||
FT_Face ft_face;
|
||||
FT_Size ft_size;
|
||||
FT_UInt size;
|
||||
Lisp_Object val, filename, idx, cache, font_object;
|
||||
Lisp_Object val, filename, idx, cache;
|
||||
bool scalable;
|
||||
int spacing;
|
||||
int i;
|
||||
|
@ -1210,8 +1215,6 @@ ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
font_object = font_build_object (VECSIZE (struct ftfont_info),
|
||||
Qfreetype, entity, size);
|
||||
ASET (font_object, FONT_FILE_INDEX, filename);
|
||||
font = XFONT_OBJECT (font_object);
|
||||
ftfont_info = (struct ftfont_info *) font;
|
||||
|
@ -1294,6 +1297,19 @@ ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
|
|||
return font_object;
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
|
||||
{
|
||||
Lisp_Object font_object;
|
||||
FT_UInt size;
|
||||
size = XINT (AREF (entity, FONT_SIZE_INDEX));
|
||||
if (size == 0)
|
||||
size = pixel_size;
|
||||
font_object = font_build_object (VECSIZE (struct ftfont_info),
|
||||
Qfreetype, entity, size);
|
||||
return ftfont_open2 (f, entity, pixel_size, font_object);
|
||||
}
|
||||
|
||||
static void
|
||||
ftfont_close (struct font *font)
|
||||
{
|
||||
|
|
|
@ -37,6 +37,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#endif /* HAVE_LIBOTF */
|
||||
|
||||
extern FcCharSet *ftfont_get_fc_charset (Lisp_Object);
|
||||
extern Lisp_Object ftfont_open2 (struct frame *f,
|
||||
Lisp_Object entity,
|
||||
int pixel_size,
|
||||
Lisp_Object font_object);
|
||||
extern size_t ftfont_info_size;
|
||||
|
||||
#endif /* EMACS_FTFONT_H */
|
||||
|
||||
|
|
128
src/gtkutil.c
128
src/gtkutil.c
|
@ -847,22 +847,23 @@ xg_clear_under_internal_border (struct frame *f)
|
|||
{
|
||||
if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
|
||||
{
|
||||
#ifndef USE_CAIRO
|
||||
GtkWidget *wfixed = f->output_data.x->edit_widget;
|
||||
|
||||
gtk_widget_queue_draw (wfixed);
|
||||
gdk_window_process_all_updates ();
|
||||
|
||||
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0, 0,
|
||||
#endif
|
||||
x_clear_area (f, 0, 0,
|
||||
FRAME_PIXEL_WIDTH (f), FRAME_INTERNAL_BORDER_WIDTH (f));
|
||||
|
||||
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0, 0,
|
||||
x_clear_area (f, 0, 0,
|
||||
FRAME_INTERNAL_BORDER_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
|
||||
|
||||
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0,
|
||||
x_clear_area (f, 0,
|
||||
FRAME_PIXEL_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f),
|
||||
FRAME_PIXEL_WIDTH (f), FRAME_INTERNAL_BORDER_WIDTH (f));
|
||||
|
||||
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
|
||||
x_clear_area (f,
|
||||
FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f),
|
||||
0, FRAME_INTERNAL_BORDER_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
|
||||
}
|
||||
|
@ -2141,12 +2142,18 @@ xg_get_font (struct frame *f, const char *default_name)
|
|||
PangoWeight weight = pango_font_description_get_weight (desc);
|
||||
PangoStyle style = pango_font_description_get_style (desc);
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
#define FONT_TYPE_WANTED (Qftcr)
|
||||
#else
|
||||
#define FONT_TYPE_WANTED (Qxft)
|
||||
#endif
|
||||
font = CALLN (Ffont_spec,
|
||||
QCname, build_string (name),
|
||||
QCsize, make_float (pango_units_to_double (size)),
|
||||
QCweight, XG_WEIGHT_TO_SYMBOL (weight),
|
||||
QCslant, XG_STYLE_TO_SYMBOL (style),
|
||||
QCtype, Qxft);
|
||||
QCtype,
|
||||
FONT_TYPE_WANTED);
|
||||
|
||||
pango_font_description_free (desc);
|
||||
dupstring (&x_last_font_name, name);
|
||||
|
@ -3806,8 +3813,10 @@ xg_update_scrollbar_pos (struct frame *f,
|
|||
gtk_widget_show_all (wparent);
|
||||
gtk_widget_set_size_request (wscroll, width, height);
|
||||
}
|
||||
#ifndef USE_CAIRO
|
||||
gtk_widget_queue_draw (wfixed);
|
||||
gdk_window_process_all_updates ();
|
||||
#endif
|
||||
if (oldx != -1 && oldw > 0 && oldh > 0)
|
||||
{
|
||||
/* Clear under old scroll bar position. This must be done after
|
||||
|
@ -3815,8 +3824,7 @@ xg_update_scrollbar_pos (struct frame *f,
|
|||
above. */
|
||||
oldw += (scale - 1) * oldw;
|
||||
oldx -= (scale - 1) * oldw;
|
||||
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
|
||||
oldx, oldy, oldw, oldh);
|
||||
x_clear_area (f, oldx, oldy, oldw, oldh);
|
||||
}
|
||||
|
||||
/* GTK does not redraw until the main loop is entered again, but
|
||||
|
@ -3882,7 +3890,7 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
|
|||
/* Clear under old scroll bar position. This must be done after
|
||||
the gtk_widget_queue_draw and gdk_window_process_all_updates
|
||||
above. */
|
||||
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
|
||||
x_clear_area (f,
|
||||
oldx, oldy, oldw, oldh);
|
||||
|
||||
/* GTK does not redraw until the main loop is entered again, but
|
||||
|
@ -4059,6 +4067,108 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Printing
|
||||
***********************************************************************/
|
||||
#ifdef USE_CAIRO
|
||||
static GtkPrintSettings *print_settings = NULL;
|
||||
static GtkPageSetup *page_setup = NULL;
|
||||
|
||||
void
|
||||
xg_page_setup_dialog (void)
|
||||
{
|
||||
GtkPageSetup *new_page_setup = NULL;
|
||||
|
||||
if (print_settings == NULL)
|
||||
print_settings = gtk_print_settings_new ();
|
||||
new_page_setup = gtk_print_run_page_setup_dialog (NULL, page_setup,
|
||||
print_settings);
|
||||
if (page_setup)
|
||||
g_object_unref (page_setup);
|
||||
page_setup = new_page_setup;
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
xg_get_page_setup (void)
|
||||
{
|
||||
Lisp_Object result, orientation_symbol;
|
||||
GtkPageOrientation orientation;
|
||||
|
||||
if (page_setup == NULL)
|
||||
page_setup = gtk_page_setup_new ();
|
||||
result = list4 (Fcons (Qleft_margin,
|
||||
make_float (gtk_page_setup_get_left_margin (page_setup,
|
||||
GTK_UNIT_POINTS))),
|
||||
Fcons (Qright_margin,
|
||||
make_float (gtk_page_setup_get_right_margin (page_setup,
|
||||
GTK_UNIT_POINTS))),
|
||||
Fcons (Qtop_margin,
|
||||
make_float (gtk_page_setup_get_top_margin (page_setup,
|
||||
GTK_UNIT_POINTS))),
|
||||
Fcons (Qbottom_margin,
|
||||
make_float (gtk_page_setup_get_bottom_margin (page_setup,
|
||||
GTK_UNIT_POINTS))));
|
||||
result = Fcons (Fcons (Qheight,
|
||||
make_float (gtk_page_setup_get_page_height (page_setup,
|
||||
GTK_UNIT_POINTS))),
|
||||
result);
|
||||
result = Fcons (Fcons (Qwidth,
|
||||
make_float (gtk_page_setup_get_page_width (page_setup,
|
||||
GTK_UNIT_POINTS))),
|
||||
result);
|
||||
orientation = gtk_page_setup_get_orientation (page_setup);
|
||||
if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT)
|
||||
orientation_symbol = Qportrait;
|
||||
else if (orientation == GTK_PAGE_ORIENTATION_LANDSCAPE)
|
||||
orientation_symbol = Qlandscape;
|
||||
else if (orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
|
||||
orientation_symbol = Qreverse_portrait;
|
||||
else if (orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)
|
||||
orientation_symbol = Qreverse_landscape;
|
||||
result = Fcons (Fcons (Qorientation, orientation_symbol), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_page (GtkPrintOperation *operation, GtkPrintContext *context,
|
||||
gint page_nr, gpointer user_data)
|
||||
{
|
||||
Lisp_Object frames = *((Lisp_Object *) user_data);
|
||||
struct frame *f = XFRAME (Fnth (make_number (page_nr), frames));
|
||||
cairo_t *cr = gtk_print_context_get_cairo_context (context);
|
||||
|
||||
x_cr_draw_frame (cr, f);
|
||||
}
|
||||
|
||||
void
|
||||
xg_print_frames_dialog (Lisp_Object frames)
|
||||
{
|
||||
GtkPrintOperation *print;
|
||||
GtkPrintOperationResult res;
|
||||
|
||||
print = gtk_print_operation_new ();
|
||||
if (print_settings != NULL)
|
||||
gtk_print_operation_set_print_settings (print, print_settings);
|
||||
if (page_setup != NULL)
|
||||
gtk_print_operation_set_default_page_setup (print, page_setup);
|
||||
gtk_print_operation_set_n_pages (print, XINT (Flength (frames)));
|
||||
g_signal_connect (print, "draw-page", G_CALLBACK (draw_page), &frames);
|
||||
res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
|
||||
NULL, NULL);
|
||||
if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
|
||||
{
|
||||
if (print_settings != NULL)
|
||||
g_object_unref (print_settings);
|
||||
print_settings =
|
||||
g_object_ref (gtk_print_operation_get_print_settings (print));
|
||||
}
|
||||
g_object_unref (print);
|
||||
}
|
||||
|
||||
#endif /* USE_CAIRO */
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -180,6 +180,12 @@ extern bool xg_prepare_tooltip (struct frame *f,
|
|||
extern void xg_show_tooltip (struct frame *f, int root_x, int root_y);
|
||||
extern bool xg_hide_tooltip (struct frame *f);
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
extern void xg_page_setup_dialog (void);
|
||||
extern Lisp_Object xg_get_page_setup (void);
|
||||
extern void xg_print_frames_dialog (Lisp_Object);
|
||||
#endif
|
||||
|
||||
/* Mark all callback data that are Lisp_object:s during GC. */
|
||||
extern void xg_mark_data (void);
|
||||
|
||||
|
|
379
src/image.c
379
src/image.c
|
@ -88,6 +88,10 @@ typedef struct w32_bitmap_record Bitmap_Record;
|
|||
|
||||
#endif /* HAVE_NTGUI */
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
#undef COLOR_TABLE_SUPPORT
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NS
|
||||
#undef COLOR_TABLE_SUPPORT
|
||||
|
||||
|
@ -514,7 +518,6 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
|
|||
|
||||
#endif /* HAVE_X_WINDOWS */
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Image types
|
||||
***********************************************************************/
|
||||
|
@ -1019,6 +1022,7 @@ prepare_image_for_display (struct frame *f, struct image *img)
|
|||
/* We're about to display IMG, so set its timestamp to `now'. */
|
||||
img->timestamp = current_timespec ();
|
||||
|
||||
#ifndef USE_CAIRO
|
||||
/* If IMG doesn't have a pixmap yet, load it now, using the image
|
||||
type dependent loader function. */
|
||||
if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
|
||||
|
@ -1032,6 +1036,7 @@ prepare_image_for_display (struct frame *f, struct image *img)
|
|||
unblock_input ();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1078,6 +1083,54 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
|
|||
return ascent;
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
static uint32_t
|
||||
xcolor_to_argb32 (XColor xc)
|
||||
{
|
||||
return (0xff << 24) | ((xc.red / 256) << 16)
|
||||
| ((xc.green / 256) << 8) | (xc.blue / 256);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_spec_bg_or_alpha_as_argb (struct image *img,
|
||||
struct frame *f)
|
||||
{
|
||||
uint32_t bgcolor = 0;
|
||||
XColor xbgcolor;
|
||||
Lisp_Object bg = image_spec_value (img->spec, QCbackground, NULL);
|
||||
|
||||
if (STRINGP (bg) && XParseColor (FRAME_X_DISPLAY (f),
|
||||
FRAME_X_COLORMAP (f),
|
||||
SSDATA (bg),
|
||||
&xbgcolor))
|
||||
bgcolor = xcolor_to_argb32 (xbgcolor);
|
||||
|
||||
return bgcolor;
|
||||
}
|
||||
|
||||
static void
|
||||
create_cairo_image_surface (struct image *img,
|
||||
unsigned char *data,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_format_t format = CAIRO_FORMAT_ARGB32;
|
||||
int stride = cairo_format_stride_for_width (format, width);
|
||||
surface = cairo_image_surface_create_for_data (data,
|
||||
format,
|
||||
width,
|
||||
height,
|
||||
stride);
|
||||
img->width = width;
|
||||
img->height = height;
|
||||
img->cr_data = surface;
|
||||
img->cr_data2 = data;
|
||||
img->pixmap = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Image background colors. */
|
||||
|
||||
|
@ -1299,6 +1352,11 @@ static void
|
|||
x_clear_image (struct frame *f, struct image *img)
|
||||
{
|
||||
block_input ();
|
||||
#ifdef USE_CAIRO
|
||||
if (img->cr_data)
|
||||
cairo_surface_destroy ((cairo_surface_t *)img->cr_data);
|
||||
if (img->cr_data2) xfree (img->cr_data2);
|
||||
#endif
|
||||
x_clear_image_1 (f, img,
|
||||
CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS);
|
||||
unblock_input ();
|
||||
|
@ -3154,9 +3212,11 @@ static struct image_type xpm_type =
|
|||
color allocation failures more gracefully than the ones on the XPM
|
||||
lib. */
|
||||
|
||||
#ifndef USE_CAIRO
|
||||
#if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
|
||||
#define ALLOC_XPM_COLORS
|
||||
#endif
|
||||
#endif /* USE_CAIRO */
|
||||
#endif /* HAVE_X_WINDOWS */
|
||||
|
||||
#ifdef ALLOC_XPM_COLORS
|
||||
|
@ -3617,6 +3677,44 @@ xpm_load (struct frame *f, struct image *img)
|
|||
#endif /* HAVE_NTGUI */
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
// Load very specific Xpm:s.
|
||||
if (rc == XpmSuccess
|
||||
&& img->ximg->format == ZPixmap
|
||||
&& img->ximg->bits_per_pixel == 32
|
||||
&& (! img->mask_img || img->mask_img->bits_per_pixel == 1))
|
||||
{
|
||||
int width = img->ximg->width;
|
||||
int height = img->ximg->height;
|
||||
unsigned char *data = (unsigned char *) xmalloc (width*height*4);
|
||||
int i;
|
||||
uint32_t *od = (uint32_t *)data;
|
||||
uint32_t *id = (uint32_t *)img->ximg->data;
|
||||
unsigned char *mid = img->mask_img ? img->mask_img->data : 0;
|
||||
uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
|
||||
|
||||
for (i = 0; i < height; ++i)
|
||||
{
|
||||
int k;
|
||||
for (k = 0; k < width; ++k)
|
||||
{
|
||||
int idx = i * img->ximg->bytes_per_line/4 + k;
|
||||
int maskidx = mid ? i * img->mask_img->bytes_per_line + k/8 : 0;
|
||||
int mask = mid ? mid[maskidx] & (1 << (k % 8)) : 1;
|
||||
|
||||
if (mask) od[idx] = id[idx] + 0xff000000; // ff => full alpha
|
||||
else od[idx] = bgcolor;
|
||||
}
|
||||
}
|
||||
|
||||
create_cairo_image_surface (img, data, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = XpmFileInvalid;
|
||||
x_clear_image (f, img);
|
||||
}
|
||||
#else
|
||||
#ifdef HAVE_X_WINDOWS
|
||||
if (rc == XpmSuccess)
|
||||
{
|
||||
|
@ -3642,6 +3740,7 @@ xpm_load (struct frame *f, struct image *img)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* ! USE_CAIRO */
|
||||
|
||||
if (rc == XpmSuccess)
|
||||
{
|
||||
|
@ -5148,12 +5247,17 @@ pbm_load (struct frame *f, struct image *img)
|
|||
bool raw_p;
|
||||
int x, y;
|
||||
int width, height, max_color_idx = 0;
|
||||
XImagePtr ximg;
|
||||
Lisp_Object file, specified_file;
|
||||
enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
|
||||
unsigned char *contents = NULL;
|
||||
unsigned char *end, *p;
|
||||
ptrdiff_t size;
|
||||
#ifdef USE_CAIRO
|
||||
unsigned char *data = 0;
|
||||
uint32_t *dataptr;
|
||||
#else
|
||||
XImagePtr ximg;
|
||||
#endif
|
||||
|
||||
specified_file = image_spec_value (img->spec, QCfile, NULL);
|
||||
|
||||
|
@ -5235,6 +5339,11 @@ pbm_load (struct frame *f, struct image *img)
|
|||
width = pbm_scan_number (&p, end);
|
||||
height = pbm_scan_number (&p, end);
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
data = (unsigned char *) xmalloc (width * height * 4);
|
||||
dataptr = (uint32_t *) data;
|
||||
#endif
|
||||
|
||||
if (type != PBM_MONO)
|
||||
{
|
||||
max_color_idx = pbm_scan_number (&p, end);
|
||||
|
@ -5251,8 +5360,10 @@ pbm_load (struct frame *f, struct image *img)
|
|||
goto error;
|
||||
}
|
||||
|
||||
#ifndef USE_CAIRO
|
||||
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
/* Initialize the color hash table. */
|
||||
init_color_table ();
|
||||
|
@ -5263,12 +5374,34 @@ pbm_load (struct frame *f, struct image *img)
|
|||
struct image_keyword fmt[PBM_LAST];
|
||||
unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
|
||||
unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
XColor xfg, xbg;
|
||||
int fga32, bga32;
|
||||
#endif
|
||||
/* Parse the image specification. */
|
||||
memcpy (fmt, pbm_format, sizeof fmt);
|
||||
parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
|
||||
|
||||
/* Get foreground and background colors, maybe allocate colors. */
|
||||
#ifdef USE_CAIRO
|
||||
if (! fmt[PBM_FOREGROUND].count
|
||||
|| ! STRINGP (fmt[PBM_FOREGROUND].value)
|
||||
|| ! x_defined_color (f, SSDATA (fmt[PBM_FOREGROUND].value), &xfg, 0))
|
||||
{
|
||||
xfg.pixel = fg;
|
||||
x_query_color (f, &xfg);
|
||||
}
|
||||
fga32 = xcolor_to_argb32 (xfg);
|
||||
|
||||
if (! fmt[PBM_BACKGROUND].count
|
||||
|| ! STRINGP (fmt[PBM_BACKGROUND].value)
|
||||
|| ! x_defined_color (f, SSDATA (fmt[PBM_BACKGROUND].value), &xbg, 0))
|
||||
{
|
||||
xbg.pixel = bg;
|
||||
x_query_color (f, &xbg);
|
||||
}
|
||||
bga32 = xcolor_to_argb32 (xbg);
|
||||
#else
|
||||
if (fmt[PBM_FOREGROUND].count
|
||||
&& STRINGP (fmt[PBM_FOREGROUND].value))
|
||||
fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
|
||||
|
@ -5279,6 +5412,7 @@ pbm_load (struct frame *f, struct image *img)
|
|||
img->background = bg;
|
||||
img->background_valid = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (y = 0; y < height; ++y)
|
||||
for (x = 0; x < width; ++x)
|
||||
|
@ -5289,7 +5423,11 @@ pbm_load (struct frame *f, struct image *img)
|
|||
{
|
||||
if (p >= end)
|
||||
{
|
||||
#ifdef USE_CAIRO
|
||||
xfree (data);
|
||||
#else
|
||||
x_destroy_x_image (ximg);
|
||||
#endif
|
||||
x_clear_image (f, img);
|
||||
image_error ("Invalid image size in image `%s'",
|
||||
img->spec, Qnil);
|
||||
|
@ -5303,7 +5441,11 @@ pbm_load (struct frame *f, struct image *img)
|
|||
else
|
||||
g = pbm_scan_number (&p, end);
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
*dataptr++ = g ? fga32 : bga32;
|
||||
#else
|
||||
XPutPixel (ximg, x, y, g ? fg : bg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5316,7 +5458,11 @@ pbm_load (struct frame *f, struct image *img)
|
|||
|
||||
if (raw_p && p + expected_size > end)
|
||||
{
|
||||
#ifdef USE_CAIRO
|
||||
xfree (data);
|
||||
#else
|
||||
x_destroy_x_image (ximg);
|
||||
#endif
|
||||
x_clear_image (f, img);
|
||||
image_error ("Invalid image size in image `%s'",
|
||||
img->spec, Qnil);
|
||||
|
@ -5357,18 +5503,29 @@ pbm_load (struct frame *f, struct image *img)
|
|||
|
||||
if (r < 0 || g < 0 || b < 0)
|
||||
{
|
||||
#ifdef USE_CAIRO
|
||||
xfree (data);
|
||||
#else
|
||||
x_destroy_x_image (ximg);
|
||||
#endif
|
||||
image_error ("Invalid pixel value in image `%s'",
|
||||
img->spec, Qnil);
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
r = (double) r * 255 / max_color_idx;
|
||||
g = (double) g * 255 / max_color_idx;
|
||||
b = (double) b * 255 / max_color_idx;
|
||||
*dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
|
||||
#else
|
||||
/* RGB values are now in the range 0..max_color_idx.
|
||||
Scale this to the range 0..0xffff supported by X. */
|
||||
r = (double) r * 65535 / max_color_idx;
|
||||
g = (double) g * 65535 / max_color_idx;
|
||||
b = (double) b * 65535 / max_color_idx;
|
||||
XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5384,12 +5541,16 @@ pbm_load (struct frame *f, struct image *img)
|
|||
|
||||
/* Maybe fill in the background field while we have ximg handy. */
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
create_cairo_image_surface (img, data, width, height);
|
||||
#else
|
||||
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
|
||||
/* Casting avoids a GCC warning. */
|
||||
IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
|
||||
|
||||
/* Put ximg into the image. */
|
||||
image_put_x_image (f, img, ximg, 0);
|
||||
#endif
|
||||
|
||||
/* X and W32 versions did it here, MAC version above. ++kfs
|
||||
img->width = width;
|
||||
|
@ -5404,7 +5565,7 @@ pbm_load (struct frame *f, struct image *img)
|
|||
PNG
|
||||
***********************************************************************/
|
||||
|
||||
#if defined (HAVE_PNG) || defined (HAVE_NS)
|
||||
#if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO)
|
||||
|
||||
/* Function prototypes. */
|
||||
|
||||
|
@ -5478,7 +5639,7 @@ png_image_p (Lisp_Object object)
|
|||
return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PNG || HAVE_NS */
|
||||
#endif /* HAVE_PNG || HAVE_NS || USE_CAIRO */
|
||||
|
||||
|
||||
#if defined HAVE_PNG && !defined HAVE_NS
|
||||
|
@ -5713,7 +5874,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
Lisp_Object specified_data;
|
||||
int x, y;
|
||||
ptrdiff_t i;
|
||||
XImagePtr ximg, mask_img = NULL;
|
||||
png_struct *png_ptr;
|
||||
png_info *info_ptr = NULL, *end_info = NULL;
|
||||
FILE *fp = NULL;
|
||||
|
@ -5727,6 +5887,13 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
bool transparent_p;
|
||||
struct png_memory_storage tbr; /* Data to be read */
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
unsigned char *data = 0;
|
||||
uint32_t *dataptr;
|
||||
#else
|
||||
XImagePtr ximg, mask_img = NULL;
|
||||
#endif
|
||||
|
||||
/* Find out what file to load. */
|
||||
specified_file = image_spec_value (img->spec, QCfile, NULL);
|
||||
specified_data = image_spec_value (img->spec, QCdata, NULL);
|
||||
|
@ -5847,10 +6014,12 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
goto error;
|
||||
}
|
||||
|
||||
#ifndef USE_CAIRO
|
||||
/* Create the X image and pixmap now, so that the work below can be
|
||||
omitted if the image is too large for X. */
|
||||
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
/* If image contains simply transparency data, we prefer to
|
||||
construct a clipping mask. */
|
||||
|
@ -5937,6 +6106,10 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
c->fp = NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
data = (unsigned char *) xmalloc (width * height * 4);
|
||||
dataptr = (uint32_t *) data;
|
||||
#else
|
||||
/* Create an image and pixmap serving as mask if the PNG image
|
||||
contains an alpha channel. */
|
||||
if (channels == 4
|
||||
|
@ -5948,6 +6121,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fill the X image and mask from PNG data. */
|
||||
init_color_table ();
|
||||
|
@ -5960,6 +6134,14 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
{
|
||||
int r, g, b;
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
int a = 0xff;
|
||||
r = *p++;
|
||||
g = *p++;
|
||||
b = *p++;
|
||||
if (channels == 4) a = *p++;
|
||||
*dataptr++ = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
#else
|
||||
r = *p++ << 8;
|
||||
g = *p++ << 8;
|
||||
b = *p++ << 8;
|
||||
|
@ -5986,6 +6168,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
|
||||
++p;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6015,6 +6198,9 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
img->width = width;
|
||||
img->height = height;
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
create_cairo_image_surface (img, data, width, height);
|
||||
#else
|
||||
/* Maybe fill in the background field while we have ximg handy.
|
||||
Casting avoids a GCC warning. */
|
||||
IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
|
||||
|
@ -6031,6 +6217,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
|
||||
image_put_x_image (f, img, mask_img, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -6052,6 +6239,7 @@ png_load (struct frame *f, struct image *img)
|
|||
image_spec_value (img->spec, QCdata, NULL));
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_NS */
|
||||
|
||||
|
||||
|
@ -6463,9 +6651,12 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
FILE * IF_LINT (volatile) fp = NULL;
|
||||
JSAMPARRAY buffer;
|
||||
int row_stride, x, y;
|
||||
XImagePtr ximg = NULL;
|
||||
unsigned long *colors;
|
||||
int width, height;
|
||||
int i, ir, ig, ib;
|
||||
#ifndef USE_CAIRO
|
||||
XImagePtr ximg = NULL;
|
||||
#endif
|
||||
|
||||
/* Open the JPEG file. */
|
||||
specified_file = image_spec_value (img->spec, QCfile, NULL);
|
||||
|
@ -6525,8 +6716,9 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
jpeg_destroy_decompress (&mgr->cinfo);
|
||||
|
||||
/* If we already have an XImage, free that. */
|
||||
#ifndef USE_CAIRO
|
||||
x_destroy_x_image (ximg);
|
||||
|
||||
#endif
|
||||
/* Free pixmap and colors. */
|
||||
x_clear_image (f, img);
|
||||
return 0;
|
||||
|
@ -6560,12 +6752,14 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
sys_longjmp (mgr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
#ifndef USE_CAIRO
|
||||
/* Create X image and pixmap. */
|
||||
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
|
||||
{
|
||||
mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
|
||||
sys_longjmp (mgr->setjmp_buffer, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate colors. When color quantization is used,
|
||||
mgr->cinfo.actual_number_of_colors has been set with the number of
|
||||
|
@ -6574,8 +6768,6 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
No more than 255 colors will be generated. */
|
||||
USE_SAFE_ALLOCA;
|
||||
{
|
||||
int i, ir, ig, ib;
|
||||
|
||||
if (mgr->cinfo.out_color_components > 2)
|
||||
ir = 0, ig = 1, ib = 2;
|
||||
else if (mgr->cinfo.out_color_components > 1)
|
||||
|
@ -6583,6 +6775,7 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
else
|
||||
ir = 0, ig = 0, ib = 0;
|
||||
|
||||
#ifndef CAIRO
|
||||
/* Use the color table mechanism because it handles colors that
|
||||
cannot be allocated nicely. Such colors will be replaced with
|
||||
a default color, and we don't have to care about which colors
|
||||
|
@ -6599,6 +6792,7 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
int b = mgr->cinfo.colormap[ib][i] << 8;
|
||||
colors[i] = lookup_rgb_color (f, r, g, b);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COLOR_TABLE_SUPPORT
|
||||
/* Remember those colors actually allocated. */
|
||||
|
@ -6611,12 +6805,36 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
row_stride = width * mgr->cinfo.output_components;
|
||||
buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo,
|
||||
JPOOL_IMAGE, row_stride, 1);
|
||||
#ifdef USE_CAIRO
|
||||
{
|
||||
unsigned char *data = (unsigned char *) xmalloc (width*height*4);
|
||||
uint32_t *dataptr = (uint32_t *) data;
|
||||
int r, g, b;
|
||||
|
||||
for (y = 0; y < height; ++y)
|
||||
{
|
||||
jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
|
||||
|
||||
for (x = 0; x < width; ++x)
|
||||
{
|
||||
i = buffer[0][x];
|
||||
r = mgr->cinfo.colormap[ir][i];
|
||||
g = mgr->cinfo.colormap[ig][i];
|
||||
b = mgr->cinfo.colormap[ib][i];
|
||||
*dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
|
||||
create_cairo_image_surface (img, data, width, height);
|
||||
}
|
||||
#else
|
||||
for (y = 0; y < height; ++y)
|
||||
{
|
||||
jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
|
||||
for (x = 0; x < mgr->cinfo.output_width; ++x)
|
||||
XPutPixel (ximg, x, y, colors[buffer[0][x]]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clean up. */
|
||||
jpeg_finish_decompress (&mgr->cinfo);
|
||||
|
@ -6624,6 +6842,7 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
if (fp)
|
||||
fclose (fp);
|
||||
|
||||
#ifndef USE_CAIRO
|
||||
/* Maybe fill in the background field while we have ximg handy. */
|
||||
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
|
||||
/* Casting avoids a GCC warning. */
|
||||
|
@ -6631,6 +6850,7 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
|
||||
/* Put ximg into the image. */
|
||||
image_put_x_image (f, img, ximg, 0);
|
||||
#endif
|
||||
SAFE_FREE ();
|
||||
return 1;
|
||||
}
|
||||
|
@ -7063,6 +7283,29 @@ tiff_load (struct frame *f, struct image *img)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
{
|
||||
unsigned char *data = (unsigned char *) xmalloc (width*height*4);
|
||||
uint32_t *dataptr = (uint32_t *) data;
|
||||
int r, g, b, a;
|
||||
|
||||
for (y = 0; y < height; ++y)
|
||||
{
|
||||
uint32 *row = buf + (height - 1 - y) * width;
|
||||
for (x = 0; x < width; ++x)
|
||||
{
|
||||
uint32 abgr = row[x];
|
||||
int r = TIFFGetR (abgr);
|
||||
int g = TIFFGetG (abgr);
|
||||
int b = TIFFGetB (abgr);
|
||||
int a = TIFFGetA (abgr);
|
||||
*dataptr++ = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
|
||||
create_cairo_image_surface (img, data, width, height);
|
||||
}
|
||||
#else
|
||||
/* Initialize the color table. */
|
||||
init_color_table ();
|
||||
|
||||
|
@ -7097,8 +7340,10 @@ tiff_load (struct frame *f, struct image *img)
|
|||
|
||||
/* Put ximg into the image. */
|
||||
image_put_x_image (f, img, ximg, 0);
|
||||
xfree (buf);
|
||||
|
||||
#endif /* ! USE_CAIRO */
|
||||
|
||||
xfree (buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -7348,7 +7593,6 @@ gif_load (struct frame *f, struct image *img)
|
|||
{
|
||||
Lisp_Object file;
|
||||
int rc, width, height, x, y, i, j;
|
||||
XImagePtr ximg;
|
||||
ColorMapObject *gif_color_map;
|
||||
unsigned long pixel_colors[256];
|
||||
GifFileType *gif;
|
||||
|
@ -7360,6 +7604,12 @@ gif_load (struct frame *f, struct image *img)
|
|||
EMACS_INT idx;
|
||||
int gif_err;
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
unsigned char *data = 0;
|
||||
#else
|
||||
XImagePtr ximg;
|
||||
#endif
|
||||
|
||||
if (NILP (specified_data))
|
||||
{
|
||||
file = x_find_image_file (specified_file);
|
||||
|
@ -7488,6 +7738,25 @@ gif_load (struct frame *f, struct image *img)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
/* xzalloc so data is zero => transparent */
|
||||
data = (unsigned char *) xzalloc (width * height * 4);
|
||||
if (STRINGP (specified_bg))
|
||||
{
|
||||
XColor color;
|
||||
if (x_defined_color (f, SSDATA (specified_bg), &color, 0))
|
||||
{
|
||||
uint32_t *dataptr = (uint32_t *)data;
|
||||
int r = color.red/256;
|
||||
int g = color.green/256;
|
||||
int b = color.blue/256;
|
||||
|
||||
for (y = 0; y < height; ++y)
|
||||
for (x = 0; x < width; ++x)
|
||||
*dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Create the X image and pixmap. */
|
||||
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
|
||||
{
|
||||
|
@ -7514,6 +7783,7 @@ gif_load (struct frame *f, struct image *img)
|
|||
for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
|
||||
XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read the GIF image into the X image. */
|
||||
|
||||
|
@ -7568,12 +7838,14 @@ gif_load (struct frame *f, struct image *img)
|
|||
if (disposal == 0)
|
||||
disposal = 1;
|
||||
|
||||
/* Allocate subimage colors. */
|
||||
memset (pixel_colors, 0, sizeof pixel_colors);
|
||||
gif_color_map = subimage->ImageDesc.ColorMap;
|
||||
if (!gif_color_map)
|
||||
gif_color_map = gif->SColorMap;
|
||||
|
||||
#ifndef USE_CAIRO
|
||||
/* Allocate subimage colors. */
|
||||
memset (pixel_colors, 0, sizeof pixel_colors);
|
||||
|
||||
if (gif_color_map)
|
||||
for (i = 0; i < gif_color_map->ColorCount; ++i)
|
||||
{
|
||||
|
@ -7588,6 +7860,7 @@ gif_load (struct frame *f, struct image *img)
|
|||
pixel_colors[i] = lookup_rgb_color (f, r, g, b);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Apply the pixel values. */
|
||||
if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace)
|
||||
|
@ -7605,20 +7878,47 @@ gif_load (struct frame *f, struct image *img)
|
|||
{
|
||||
int c = raster[y * subimg_width + x];
|
||||
if (transparency_color_index != c || disposal != 1)
|
||||
XPutPixel (ximg, x + subimg_left, row + subimg_top,
|
||||
pixel_colors[c]);
|
||||
{
|
||||
#ifdef USE_CAIRO
|
||||
uint32_t *dataptr =
|
||||
((uint32_t*)data + ((row + subimg_top) * subimg_width
|
||||
+ x + subimg_left));
|
||||
int r = gif_color_map->Colors[c].Red;
|
||||
int g = gif_color_map->Colors[c].Green;
|
||||
int b = gif_color_map->Colors[c].Blue;
|
||||
|
||||
if (transparency_color_index != c)
|
||||
*dataptr = (0xff << 24) | (r << 16) | (g << 8) | b;
|
||||
#else
|
||||
XPutPixel (ximg, x + subimg_left, row + subimg_top,
|
||||
pixel_colors[c]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < subimg_height; ++y)
|
||||
for (y = 0; y < subimg_height; ++y)
|
||||
for (x = 0; x < subimg_width; ++x)
|
||||
{
|
||||
int c = raster[y * subimg_width + x];
|
||||
if (transparency_color_index != c || disposal != 1)
|
||||
XPutPixel (ximg, x + subimg_left, y + subimg_top,
|
||||
pixel_colors[c]);
|
||||
{
|
||||
#ifdef USE_CAIRO
|
||||
uint32_t *dataptr =
|
||||
((uint32_t*)data + ((y + subimg_top) * subimg_width
|
||||
+ x + subimg_left));
|
||||
int r = gif_color_map->Colors[c].Red;
|
||||
int g = gif_color_map->Colors[c].Green;
|
||||
int b = gif_color_map->Colors[c].Blue;
|
||||
if (transparency_color_index != c)
|
||||
*dataptr = (0xff << 24) | (r << 16) | (g << 8) | b;
|
||||
#else
|
||||
XPutPixel (ximg, x + subimg_left, y + subimg_top,
|
||||
pixel_colors[c]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7675,6 +7975,9 @@ gif_load (struct frame *f, struct image *img)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
create_cairo_image_surface (img, data, width, height);
|
||||
#else
|
||||
/* Maybe fill in the background field while we have ximg handy. */
|
||||
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
|
||||
/* Casting avoids a GCC warning. */
|
||||
|
@ -7682,6 +7985,7 @@ gif_load (struct frame *f, struct image *img)
|
|||
|
||||
/* Put ximg into the image. */
|
||||
image_put_x_image (f, img, ximg, 0);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -8901,6 +9205,37 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. *
|
|||
eassert (gdk_pixbuf_get_has_alpha (pixbuf));
|
||||
eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
{
|
||||
unsigned char *data = (unsigned char *) xmalloc (width*height*4);
|
||||
int y;
|
||||
uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
|
||||
|
||||
for (y = 0; y < height; ++y)
|
||||
{
|
||||
const guchar *iconptr = pixels + y * rowstride;
|
||||
uint32_t *dataptr = (uint32_t *) (data + y * rowstride);
|
||||
int x;
|
||||
|
||||
for (x = 0; x < width; ++x)
|
||||
{
|
||||
if (iconptr[3] == 0)
|
||||
*dataptr = bgcolor;
|
||||
else
|
||||
*dataptr = (iconptr[0] << 16)
|
||||
| (iconptr[1] << 8)
|
||||
| iconptr[2]
|
||||
| (iconptr[3] << 24);
|
||||
|
||||
iconptr += 4;
|
||||
++dataptr;
|
||||
}
|
||||
}
|
||||
|
||||
create_cairo_image_surface (img, data, width, height);
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
#else
|
||||
/* Try to create a x pixmap to hold the svg pixmap. */
|
||||
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
|
||||
{
|
||||
|
@ -8972,6 +9307,7 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. *
|
|||
|
||||
/* Put ximg into the image. */
|
||||
image_put_x_image (f, img, ximg, 0);
|
||||
#endif /* ! USE_CAIRO */
|
||||
|
||||
return 1;
|
||||
|
||||
|
@ -9239,15 +9575,16 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
|
|||
/* For each pixel of the image, look its color up in the
|
||||
color table. After having done so, the color table will
|
||||
contain an entry for each color used by the image. */
|
||||
#ifdef COLOR_TABLE_SUPPORT
|
||||
for (y = 0; y < img->height; ++y)
|
||||
for (x = 0; x < img->width; ++x)
|
||||
{
|
||||
unsigned long pixel = XGetPixel (ximg, x, y);
|
||||
|
||||
lookup_pixel_color (f, pixel);
|
||||
}
|
||||
|
||||
/* Record colors in the image. Free color table and XImage. */
|
||||
#ifdef COLOR_TABLE_SUPPORT
|
||||
img->colors = colors_in_color_table (&img->ncolors);
|
||||
free_color_table ();
|
||||
#endif
|
||||
|
@ -9360,7 +9697,7 @@ lookup_image_type (Lisp_Object type)
|
|||
return define_image_type (&gif_type);
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_PNG) || defined (HAVE_NS)
|
||||
#if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO)
|
||||
if (EQ (type, Qpng))
|
||||
return define_image_type (&png_type);
|
||||
#endif
|
||||
|
|
193
src/xfns.c
193
src/xfns.c
|
@ -3116,6 +3116,9 @@ This function is an internal primitive--use `make-frame' instead. */)
|
|||
specbind (Qx_resource_name, name);
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
register_font_driver (&ftcrfont_driver, f);
|
||||
#else
|
||||
#ifdef HAVE_FREETYPE
|
||||
#ifdef HAVE_XFT
|
||||
register_font_driver (&xftfont_driver, f);
|
||||
|
@ -3124,6 +3127,7 @@ This function is an internal primitive--use `make-frame' instead. */)
|
|||
#endif /* not HAVE_XFT */
|
||||
#endif /* HAVE_FREETYPE */
|
||||
register_font_driver (&xfont_driver, f);
|
||||
#endif /* not USE_CAIRO */
|
||||
|
||||
x_default_parameter (f, parms, Qfont_backend, Qnil,
|
||||
"fontBackend", "FontBackend", RES_TYPE_STRING);
|
||||
|
@ -5118,6 +5122,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
|
|||
specbind (Qx_resource_name, name);
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
register_font_driver (&ftcrfont_driver, f);
|
||||
#else
|
||||
register_font_driver (&xfont_driver, f);
|
||||
#ifdef HAVE_FREETYPE
|
||||
#ifdef HAVE_XFT
|
||||
|
@ -5126,6 +5133,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
|
|||
register_font_driver (&ftxfont_driver, f);
|
||||
#endif /* not HAVE_XFT */
|
||||
#endif /* HAVE_FREETYPE */
|
||||
#endif /* not USE_CAIRO */
|
||||
|
||||
x_default_parameter (f, parms, Qfont_backend, Qnil,
|
||||
"fontBackend", "FontBackend", RES_TYPE_STRING);
|
||||
|
@ -6207,6 +6215,158 @@ present and mapped to the usual X keysyms. */)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Printing
|
||||
***********************************************************************/
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
DEFUN ("x-export-frames", Fx_export_frames, Sx_export_frames, 0, 2, 0,
|
||||
doc: /* XXX Experimental. Return image data of FRAMES in TYPE format.
|
||||
FRAMES should be nil (the selected frame), a frame, or a list of
|
||||
frames (each of which corresponds to one page). Optional arg TYPE
|
||||
should be either `pdf' (default), `png', `ps', or `svg'. Supported
|
||||
types are determined by the compile-time configuration of cairo. */)
|
||||
(Lisp_Object frames, Lisp_Object type)
|
||||
{
|
||||
Lisp_Object result, rest, tmp;
|
||||
cairo_surface_type_t surface_type;
|
||||
|
||||
if (NILP (frames))
|
||||
frames = selected_frame;
|
||||
if (!CONSP (frames))
|
||||
frames = list1 (frames);
|
||||
|
||||
tmp = Qnil;
|
||||
for (rest = frames; CONSP (rest); rest = XCDR (rest))
|
||||
{
|
||||
struct frame *f = XFRAME (XCAR (rest));
|
||||
|
||||
if (! FRAME_LIVE_P (f) || ! FRAME_X_P (f) || ! FRAME_LIVE_P (f))
|
||||
error ("Invalid frame");
|
||||
|
||||
Lisp_Object frame;
|
||||
|
||||
XSETFRAME (frame, f);
|
||||
tmp = Fcons (frame, tmp);
|
||||
}
|
||||
frames = Fnreverse (tmp);
|
||||
|
||||
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||
if (NILP (type) || EQ (type, intern ("pdf"))) /* XXX: Qpdf */
|
||||
surface_type = CAIRO_SURFACE_TYPE_PDF;
|
||||
else
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_PNG_FUNCTIONS
|
||||
if (EQ (type, intern ("png")))
|
||||
{
|
||||
if (!NILP (XCDR (frames)))
|
||||
error ("PNG export cannot handle multiple frames.");
|
||||
surface_type = CAIRO_SURFACE_TYPE_IMAGE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_PS_SURFACE
|
||||
if (EQ (type, intern ("ps")))
|
||||
surface_type = CAIRO_SURFACE_TYPE_PS;
|
||||
else
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
if (EQ (type, intern ("svg")))
|
||||
{
|
||||
/* For now, we stick to SVG 1.1. */
|
||||
if (!NILP (XCDR (frames)))
|
||||
error ("SVG export cannot handle multiple frames.");
|
||||
surface_type = CAIRO_SURFACE_TYPE_SVG;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
error ("Unsupported export type");
|
||||
|
||||
result = x_cr_export_frames (frames, surface_type);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef USE_GTK
|
||||
DEFUN ("x-page-setup-dialog", Fx_page_setup_dialog, Sx_page_setup_dialog, 0, 0, 0,
|
||||
doc: /* Pop up a page setup dialog.
|
||||
The current page setup can be obtained using `x-get-page-setup'. */)
|
||||
(void)
|
||||
{
|
||||
block_input ();
|
||||
xg_page_setup_dialog ();
|
||||
unblock_input ();
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("x-get-page-setup", Fx_get_page_setup, Sx_get_page_setup, 0, 0, 0,
|
||||
doc: /* Return the value of the current page setup.
|
||||
The return value is an alist containing the following keys:
|
||||
|
||||
orientation: page orientation (symbol `portrait', `landscape',
|
||||
`reverse-portrait', or `reverse-landscape').
|
||||
width, height: page width/height in points not including margins.
|
||||
left-margin, right-margin, top-margin, bottom-margin: print margins,
|
||||
which is the parts of the page that the printer cannot print
|
||||
on, in points.
|
||||
|
||||
The paper width can be obtained as the sum of width, left-margin, and
|
||||
right-margin values. Likewise, the paper height is the sum of height,
|
||||
top-margin, and bottom-margin values. */)
|
||||
(void)
|
||||
{
|
||||
Lisp_Object result;
|
||||
|
||||
block_input ();
|
||||
result = xg_get_page_setup ();
|
||||
unblock_input ();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DEFUN ("x-print-frames-dialog", Fx_print_frames_dialog, Sx_print_frames_dialog, 0, 1, "",
|
||||
doc: /* Pop up a print dialog to print the current contents of FRAMES.
|
||||
FRAMES should be nil (the selected frame), a frame, or a list of
|
||||
frames (each of which corresponds to one page). Each frame should be
|
||||
visible. */)
|
||||
(Lisp_Object frames)
|
||||
{
|
||||
Lisp_Object rest, tmp;
|
||||
|
||||
if (NILP (frames))
|
||||
frames = selected_frame;
|
||||
if (!CONSP (frames))
|
||||
frames = list1 (frames);
|
||||
|
||||
tmp = Qnil;
|
||||
for (rest = frames; CONSP (rest); rest = XCDR (rest))
|
||||
{
|
||||
struct frame *f = XFRAME (XCAR (rest));
|
||||
if (! FRAME_LIVE_P (f) || ! FRAME_X_P (f) || ! FRAME_LIVE_P (f))
|
||||
error ("Invalid frame");
|
||||
Lisp_Object frame;
|
||||
|
||||
XSETFRAME (frame, f);
|
||||
if (!EQ (Fframe_visible_p (frame), Qt))
|
||||
error ("Frames to be printed must be visible.");
|
||||
tmp = Fcons (frame, tmp);
|
||||
}
|
||||
frames = Fnreverse (tmp);
|
||||
|
||||
/* Make sure the current matrices are up-to-date. */
|
||||
Fredisplay (Qt);
|
||||
|
||||
block_input ();
|
||||
xg_print_frames_dialog (frames);
|
||||
unblock_input ();
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
#endif /* USE_GTK */
|
||||
#endif /* USE_CAIRO */
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Initialization
|
||||
|
@ -6265,6 +6425,16 @@ syms_of_xfns (void)
|
|||
DEFSYM (Qfont_param, "font-parameter");
|
||||
DEFSYM (Qmono, "mono");
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
DEFSYM (Qorientation, "orientation");
|
||||
DEFSYM (Qtop_margin, "top-margin");
|
||||
DEFSYM (Qbottom_margin, "bottom-margin");
|
||||
DEFSYM (Qportrait, "portrait");
|
||||
DEFSYM (Qlandscape, "landscape");
|
||||
DEFSYM (Qreverse_portrait, "reverse-portrait");
|
||||
DEFSYM (Qreverse_landscape, "reverse-landscape");
|
||||
#endif
|
||||
|
||||
Fput (Qundefined_color, Qerror_conditions,
|
||||
listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));
|
||||
Fput (Qundefined_color, Qerror_message,
|
||||
|
@ -6405,6 +6575,20 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
|
|||
}
|
||||
#endif /* USE_GTK */
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
Fprovide (intern_c_string ("cairo"), Qnil);
|
||||
|
||||
DEFVAR_LISP ("cairo-version-string", Vcairo_version_string,
|
||||
doc: /* Version info for cairo. */);
|
||||
{
|
||||
char cairo_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
|
||||
int len = sprintf (cairo_version, "%d.%d.%d",
|
||||
CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR,
|
||||
CAIRO_VERSION_MICRO);
|
||||
Vcairo_version_string = make_pure_string (cairo_version, len, len, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* X window properties. */
|
||||
defsubr (&Sx_change_window_property);
|
||||
defsubr (&Sx_delete_window_property);
|
||||
|
@ -6455,4 +6639,13 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
|
|||
#if defined (USE_GTK) && defined (HAVE_FREETYPE)
|
||||
defsubr (&Sx_select_font);
|
||||
#endif
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
defsubr (&Sx_export_frames);
|
||||
#ifdef USE_GTK
|
||||
defsubr (&Sx_page_setup_dialog);
|
||||
defsubr (&Sx_get_page_setup);
|
||||
defsubr (&Sx_print_frames_dialog);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
1000
src/xterm.c
1000
src/xterm.c
File diff suppressed because it is too large
Load diff
53
src/xterm.h
53
src/xterm.h
|
@ -70,6 +70,19 @@ typedef GtkWidget *xt_or_gtk_widget;
|
|||
#define USE_GTK_TOOLTIP
|
||||
#endif
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
#include <cairo-xlib.h>
|
||||
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||
#include <cairo-pdf.h>
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_PS_SURFACE
|
||||
#include <cairo-ps.h>
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
#include <cairo-svg.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_X_I18N
|
||||
#include <X11/Xlocale.h>
|
||||
#endif
|
||||
|
@ -115,6 +128,9 @@ struct xim_inst_t
|
|||
|
||||
struct x_bitmap_record
|
||||
{
|
||||
#ifdef USE_CAIRO
|
||||
void *img;
|
||||
#endif
|
||||
Pixmap pixmap;
|
||||
bool have_mask;
|
||||
Pixmap mask;
|
||||
|
@ -123,6 +139,19 @@ struct x_bitmap_record
|
|||
/* Record some info about this pixmap. */
|
||||
int height, width, depth;
|
||||
};
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
struct x_gc_ext_data
|
||||
{
|
||||
#define MAX_CLIP_RECTS 2
|
||||
/* Number of clipping rectangles. */
|
||||
int n_clip_rects;
|
||||
|
||||
/* Clipping rectangles. */
|
||||
XRectangle clip_rects[MAX_CLIP_RECTS];
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* For each X display, we have a structure that records
|
||||
information about it. */
|
||||
|
@ -411,6 +440,10 @@ struct x_display_info
|
|||
|
||||
/* SM */
|
||||
Atom Xatom_SM_CLIENT_ID;
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
XExtCodes *ext_codes;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef HAVE_X_I18N
|
||||
|
@ -636,7 +669,6 @@ struct x_output
|
|||
/* The offset we need to add to compensate for type A WMs. */
|
||||
int move_offset_top;
|
||||
int move_offset_left;
|
||||
};
|
||||
|
||||
/* Extreme 'short' and 'long' values suitable for libX11. */
|
||||
#define X_SHRT_MAX 0x7fff
|
||||
|
@ -645,6 +677,14 @@ struct x_output
|
|||
#define X_LONG_MIN (-1 - X_LONG_MAX)
|
||||
#define X_ULONG_MAX 0xffffffffUL
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
/* Cairo drawing context. */
|
||||
cairo_t *cr_context;
|
||||
/* Cairo surface for double buffering */
|
||||
cairo_surface_t *cr_surface;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define No_Cursor (None)
|
||||
|
||||
enum
|
||||
|
@ -991,7 +1031,8 @@ extern bool x_alloc_lighter_color_for_widget (Widget, Display *, Colormap,
|
|||
double, int);
|
||||
#endif
|
||||
extern bool x_alloc_nearest_color (struct frame *, Colormap, XColor *);
|
||||
extern void x_clear_area (Display *, Window, int, int, int, int);
|
||||
extern void x_query_color (struct frame *f, XColor *);
|
||||
extern void x_clear_area (struct frame *f, int, int, int, int);
|
||||
#if !defined USE_X_TOOLKIT && !defined USE_GTK
|
||||
extern void x_mouse_leave (struct x_display_info *);
|
||||
#endif
|
||||
|
@ -1000,6 +1041,14 @@ extern void x_mouse_leave (struct x_display_info *);
|
|||
extern int x_dispatch_event (XEvent *, Display *);
|
||||
#endif
|
||||
extern int x_x_to_emacs_modifiers (struct x_display_info *, int);
|
||||
#ifdef USE_CAIRO
|
||||
extern cairo_t *x_begin_cr_clip (struct frame *, GC);
|
||||
extern void x_end_cr_clip (struct frame *);
|
||||
extern void x_set_cr_source_with_gc_foreground (struct frame *, GC);
|
||||
extern void x_set_cr_source_with_gc_background (struct frame *, GC);
|
||||
extern void x_cr_draw_frame (cairo_t *, struct frame *);
|
||||
extern Lisp_Object x_cr_export_frames (Lisp_Object, cairo_surface_type_t);
|
||||
#endif
|
||||
|
||||
INLINE int
|
||||
x_display_pixel_height (struct x_display_info *dpyinfo)
|
||||
|
|
Loading…
Add table
Reference in a new issue