diff options
| author | Jan D | 2015-02-11 16:14:35 +0100 |
|---|---|---|
| committer | Jan D | 2015-02-11 16:14:35 +0100 |
| commit | dddcc0e78452f2186c132823a33a174d2596ba33 (patch) | |
| tree | 8369d54925d9ea4b60ecf6a53c6a321dffd194f9 /src/xfns.c | |
| parent | 061c7e2b5a5a5854b2b85f2ace5b1d9222dd7f11 (diff) | |
| download | emacs-dddcc0e78452f2186c132823a33a174d2596ba33.tar.gz emacs-dddcc0e78452f2186c132823a33a174d2596ba33.zip | |
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.
Diffstat (limited to 'src/xfns.c')
| -rw-r--r-- | src/xfns.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/src/xfns.c b/src/xfns.c index 629ac4b26ff..23af4388e5f 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -3052,6 +3052,9 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3052 | specbind (Qx_resource_name, name); | 3052 | specbind (Qx_resource_name, name); |
| 3053 | } | 3053 | } |
| 3054 | 3054 | ||
| 3055 | #ifdef USE_CAIRO | ||
| 3056 | register_font_driver (&ftcrfont_driver, f); | ||
| 3057 | #else | ||
| 3055 | #ifdef HAVE_FREETYPE | 3058 | #ifdef HAVE_FREETYPE |
| 3056 | #ifdef HAVE_XFT | 3059 | #ifdef HAVE_XFT |
| 3057 | register_font_driver (&xftfont_driver, f); | 3060 | register_font_driver (&xftfont_driver, f); |
| @@ -3060,6 +3063,7 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3060 | #endif /* not HAVE_XFT */ | 3063 | #endif /* not HAVE_XFT */ |
| 3061 | #endif /* HAVE_FREETYPE */ | 3064 | #endif /* HAVE_FREETYPE */ |
| 3062 | register_font_driver (&xfont_driver, f); | 3065 | register_font_driver (&xfont_driver, f); |
| 3066 | #endif /* not USE_CAIRO */ | ||
| 3063 | 3067 | ||
| 3064 | x_default_parameter (f, parms, Qfont_backend, Qnil, | 3068 | x_default_parameter (f, parms, Qfont_backend, Qnil, |
| 3065 | "fontBackend", "FontBackend", RES_TYPE_STRING); | 3069 | "fontBackend", "FontBackend", RES_TYPE_STRING); |
| @@ -5049,6 +5053,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo, | |||
| 5049 | specbind (Qx_resource_name, name); | 5053 | specbind (Qx_resource_name, name); |
| 5050 | } | 5054 | } |
| 5051 | 5055 | ||
| 5056 | #ifdef USE_CAIRO | ||
| 5057 | register_font_driver (&ftcrfont_driver, f); | ||
| 5058 | #else | ||
| 5052 | register_font_driver (&xfont_driver, f); | 5059 | register_font_driver (&xfont_driver, f); |
| 5053 | #ifdef HAVE_FREETYPE | 5060 | #ifdef HAVE_FREETYPE |
| 5054 | #ifdef HAVE_XFT | 5061 | #ifdef HAVE_XFT |
| @@ -5057,6 +5064,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, | |||
| 5057 | register_font_driver (&ftxfont_driver, f); | 5064 | register_font_driver (&ftxfont_driver, f); |
| 5058 | #endif /* not HAVE_XFT */ | 5065 | #endif /* not HAVE_XFT */ |
| 5059 | #endif /* HAVE_FREETYPE */ | 5066 | #endif /* HAVE_FREETYPE */ |
| 5067 | #endif /* not USE_CAIRO */ | ||
| 5060 | 5068 | ||
| 5061 | x_default_parameter (f, parms, Qfont_backend, Qnil, | 5069 | x_default_parameter (f, parms, Qfont_backend, Qnil, |
| 5062 | "fontBackend", "FontBackend", RES_TYPE_STRING); | 5070 | "fontBackend", "FontBackend", RES_TYPE_STRING); |
| @@ -6140,6 +6148,160 @@ present and mapped to the usual X keysyms. */) | |||
| 6140 | 6148 | ||
| 6141 | 6149 | ||
| 6142 | /*********************************************************************** | 6150 | /*********************************************************************** |
| 6151 | Printing | ||
| 6152 | ***********************************************************************/ | ||
| 6153 | |||
| 6154 | #ifdef USE_CAIRO | ||
| 6155 | DEFUN ("x-export-frames", Fx_export_frames, Sx_export_frames, 0, 2, 0, | ||
| 6156 | doc: /* XXX Experimental. Return image data of FRAMES in TYPE format. | ||
| 6157 | FRAMES should be nil (the selected frame), a frame, or a list of | ||
| 6158 | frames (each of which corresponds to one page). Optional arg TYPE | ||
| 6159 | should be either `pdf' (default), `png', `ps', or `svg'. Supported | ||
| 6160 | types are determined by the compile-time configuration of cairo. */) | ||
| 6161 | (frames, type) | ||
| 6162 | Lisp_Object frames, type; | ||
| 6163 | { | ||
| 6164 | Lisp_Object result, rest, tmp; | ||
| 6165 | cairo_surface_type_t surface_type; | ||
| 6166 | |||
| 6167 | if (NILP (frames)) | ||
| 6168 | frames = selected_frame; | ||
| 6169 | if (!CONSP (frames)) | ||
| 6170 | frames = list1 (frames); | ||
| 6171 | |||
| 6172 | tmp = Qnil; | ||
| 6173 | for (rest = frames; CONSP (rest); rest = XCDR (rest)) | ||
| 6174 | { | ||
| 6175 | struct frame *f = XFRAME (XCAR (rest)); | ||
| 6176 | |||
| 6177 | if (! FRAME_LIVE_P (f) || ! FRAME_X_P (f) || ! FRAME_LIVE_P (f)) | ||
| 6178 | error ("Invalid frame"); | ||
| 6179 | |||
| 6180 | Lisp_Object frame; | ||
| 6181 | |||
| 6182 | XSETFRAME (frame, f); | ||
| 6183 | tmp = Fcons (frame, tmp); | ||
| 6184 | } | ||
| 6185 | frames = Fnreverse (tmp); | ||
| 6186 | |||
| 6187 | #ifdef CAIRO_HAS_PDF_SURFACE | ||
| 6188 | if (NILP (type) || EQ (type, intern ("pdf"))) /* XXX: Qpdf */ | ||
| 6189 | surface_type = CAIRO_SURFACE_TYPE_PDF; | ||
| 6190 | else | ||
| 6191 | #endif | ||
| 6192 | #ifdef CAIRO_HAS_PNG_FUNCTIONS | ||
| 6193 | if (EQ (type, intern ("png"))) | ||
| 6194 | { | ||
| 6195 | if (!NILP (XCDR (frames))) | ||
| 6196 | error ("PNG export cannot handle multiple frames."); | ||
| 6197 | surface_type = CAIRO_SURFACE_TYPE_IMAGE; | ||
| 6198 | } | ||
| 6199 | else | ||
| 6200 | #endif | ||
| 6201 | #ifdef CAIRO_HAS_PS_SURFACE | ||
| 6202 | if (EQ (type, intern ("ps"))) | ||
| 6203 | surface_type = CAIRO_SURFACE_TYPE_PS; | ||
| 6204 | else | ||
| 6205 | #endif | ||
| 6206 | #ifdef CAIRO_HAS_SVG_SURFACE | ||
| 6207 | if (EQ (type, intern ("svg"))) | ||
| 6208 | { | ||
| 6209 | /* For now, we stick to SVG 1.1. */ | ||
| 6210 | if (!NILP (XCDR (frames))) | ||
| 6211 | error ("SVG export cannot handle multiple frames."); | ||
| 6212 | surface_type = CAIRO_SURFACE_TYPE_SVG; | ||
| 6213 | } | ||
| 6214 | else | ||
| 6215 | #endif | ||
| 6216 | error ("Unsupported export type"); | ||
| 6217 | |||
| 6218 | result = x_cr_export_frames (frames, surface_type); | ||
| 6219 | |||
| 6220 | return result; | ||
| 6221 | } | ||
| 6222 | |||
| 6223 | #ifdef USE_GTK | ||
| 6224 | DEFUN ("x-page-setup-dialog", Fx_page_setup_dialog, Sx_page_setup_dialog, 0, 0, 0, | ||
| 6225 | doc: /* Pop up a page setup dialog. | ||
| 6226 | The current page setup can be obtained using `x-get-page-setup'. */) | ||
| 6227 | () | ||
| 6228 | { | ||
| 6229 | block_input (); | ||
| 6230 | xg_page_setup_dialog (); | ||
| 6231 | unblock_input (); | ||
| 6232 | |||
| 6233 | return Qnil; | ||
| 6234 | } | ||
| 6235 | |||
| 6236 | DEFUN ("x-get-page-setup", Fx_get_page_setup, Sx_get_page_setup, 0, 0, 0, | ||
| 6237 | doc: /* Return the value of the current page setup. | ||
| 6238 | The return value is an alist containing the following keys: | ||
| 6239 | |||
| 6240 | orientation: page orientation (symbol `portrait', `landscape', | ||
| 6241 | `reverse-portrait', or `reverse-landscape'). | ||
| 6242 | width, height: page width/height in points not including margins. | ||
| 6243 | left-margin, right-margin, top-margin, bottom-margin: print margins, | ||
| 6244 | which is the parts of the page that the printer cannot print | ||
| 6245 | on, in points. | ||
| 6246 | |||
| 6247 | The paper width can be obtained as the sum of width, left-margin, and | ||
| 6248 | right-margin values. Likewise, the paper height is the sum of height, | ||
| 6249 | top-margin, and bottom-margin values. */) | ||
| 6250 | () | ||
| 6251 | { | ||
| 6252 | Lisp_Object result; | ||
| 6253 | |||
| 6254 | block_input (); | ||
| 6255 | result = xg_get_page_setup (); | ||
| 6256 | unblock_input (); | ||
| 6257 | |||
| 6258 | return result; | ||
| 6259 | } | ||
| 6260 | |||
| 6261 | DEFUN ("x-print-frames-dialog", Fx_print_frames_dialog, Sx_print_frames_dialog, 0, 1, "", | ||
| 6262 | doc: /* Pop up a print dialog to print the current contents of FRAMES. | ||
| 6263 | FRAMES should be nil (the selected frame), a frame, or a list of | ||
| 6264 | frames (each of which corresponds to one page). Each frame should be | ||
| 6265 | visible. */) | ||
| 6266 | (frames) | ||
| 6267 | Lisp_Object frames; | ||
| 6268 | { | ||
| 6269 | Lisp_Object rest, tmp; | ||
| 6270 | |||
| 6271 | if (NILP (frames)) | ||
| 6272 | frames = selected_frame; | ||
| 6273 | if (!CONSP (frames)) | ||
| 6274 | frames = list1 (frames); | ||
| 6275 | |||
| 6276 | tmp = Qnil; | ||
| 6277 | for (rest = frames; CONSP (rest); rest = XCDR (rest)) | ||
| 6278 | { | ||
| 6279 | struct frame *f = XFRAME (XCAR (rest)); | ||
| 6280 | if (! FRAME_LIVE_P (f) || ! FRAME_X_P (f) || ! FRAME_LIVE_P (f)) | ||
| 6281 | error ("Invalid frame"); | ||
| 6282 | Lisp_Object frame; | ||
| 6283 | |||
| 6284 | XSETFRAME (frame, f); | ||
| 6285 | if (!EQ (Fframe_visible_p (frame), Qt)) | ||
| 6286 | error ("Frames to be printed must be visible."); | ||
| 6287 | tmp = Fcons (frame, tmp); | ||
| 6288 | } | ||
| 6289 | frames = Fnreverse (tmp); | ||
| 6290 | |||
| 6291 | /* Make sure the current matrices are up-to-date. */ | ||
| 6292 | Fredisplay (Qt); | ||
| 6293 | |||
| 6294 | block_input (); | ||
| 6295 | xg_print_frames_dialog (frames); | ||
| 6296 | unblock_input (); | ||
| 6297 | |||
| 6298 | return Qnil; | ||
| 6299 | } | ||
| 6300 | #endif /* USE_GTK */ | ||
| 6301 | #endif /* USE_CAIRO */ | ||
| 6302 | |||
| 6303 | |||
| 6304 | /*********************************************************************** | ||
| 6143 | Initialization | 6305 | Initialization |
| 6144 | ***********************************************************************/ | 6306 | ***********************************************************************/ |
| 6145 | 6307 | ||
| @@ -6195,6 +6357,16 @@ syms_of_xfns (void) | |||
| 6195 | DEFSYM (Qcancel_timer, "cancel-timer"); | 6357 | DEFSYM (Qcancel_timer, "cancel-timer"); |
| 6196 | DEFSYM (Qfont_param, "font-parameter"); | 6358 | DEFSYM (Qfont_param, "font-parameter"); |
| 6197 | 6359 | ||
| 6360 | #ifdef USE_CAIRO | ||
| 6361 | DEFSYM (Qorientation, "orientation"); | ||
| 6362 | DEFSYM (Qtop_margin, "top-margin"); | ||
| 6363 | DEFSYM (Qbottom_margin, "bottom-margin"); | ||
| 6364 | DEFSYM (Qportrait, "portrait"); | ||
| 6365 | DEFSYM (Qlandscape, "landscape"); | ||
| 6366 | DEFSYM (Qreverse_portrait, "reverse-portrait"); | ||
| 6367 | DEFSYM (Qreverse_landscape, "reverse-landscape"); | ||
| 6368 | #endif | ||
| 6369 | |||
| 6198 | Fput (Qundefined_color, Qerror_conditions, | 6370 | Fput (Qundefined_color, Qerror_conditions, |
| 6199 | listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror)); | 6371 | listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror)); |
| 6200 | Fput (Qundefined_color, Qerror_message, | 6372 | Fput (Qundefined_color, Qerror_message, |
| @@ -6335,6 +6507,20 @@ When using Gtk+ tooltips, the tooltip face is not used. */); | |||
| 6335 | } | 6507 | } |
| 6336 | #endif /* USE_GTK */ | 6508 | #endif /* USE_GTK */ |
| 6337 | 6509 | ||
| 6510 | #ifdef USE_CAIRO | ||
| 6511 | Fprovide (intern_c_string ("cairo"), Qnil); | ||
| 6512 | |||
| 6513 | DEFVAR_LISP ("cairo-version-string", Vcairo_version_string, | ||
| 6514 | doc: /* Version info for cairo. */); | ||
| 6515 | { | ||
| 6516 | char cairo_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)]; | ||
| 6517 | int len = sprintf (cairo_version, "%d.%d.%d", | ||
| 6518 | CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR, | ||
| 6519 | CAIRO_VERSION_MICRO); | ||
| 6520 | Vcairo_version_string = make_pure_string (cairo_version, len, len, false); | ||
| 6521 | } | ||
| 6522 | #endif | ||
| 6523 | |||
| 6338 | /* X window properties. */ | 6524 | /* X window properties. */ |
| 6339 | defsubr (&Sx_change_window_property); | 6525 | defsubr (&Sx_change_window_property); |
| 6340 | defsubr (&Sx_delete_window_property); | 6526 | defsubr (&Sx_delete_window_property); |
| @@ -6385,4 +6571,13 @@ When using Gtk+ tooltips, the tooltip face is not used. */); | |||
| 6385 | #if defined (USE_GTK) && defined (HAVE_FREETYPE) | 6571 | #if defined (USE_GTK) && defined (HAVE_FREETYPE) |
| 6386 | defsubr (&Sx_select_font); | 6572 | defsubr (&Sx_select_font); |
| 6387 | #endif | 6573 | #endif |
| 6574 | |||
| 6575 | #ifdef USE_CAIRO | ||
| 6576 | defsubr (&Sx_export_frames); | ||
| 6577 | #ifdef USE_GTK | ||
| 6578 | defsubr (&Sx_page_setup_dialog); | ||
| 6579 | defsubr (&Sx_get_page_setup); | ||
| 6580 | defsubr (&Sx_print_frames_dialog); | ||
| 6581 | #endif | ||
| 6582 | #endif | ||
| 6388 | } | 6583 | } |