Clean up cairo printing code

* src/gtkutil.c (xg_get_page_setup): Use listn.
* src/xfns.c (Fx_export_frames, Fx_print_frames_dialog): Doc fix.  Use
decode_window_system_frame and FRAME_VISIBLE_P.
(Fx_print_frames_dialog): Use redisplay_preserve_echo_area instead
of Fdisplay.
* src/xterm.c (x_cr_export_frames): Use redisplay_preserve_echo_area
instead of Fdisplay.  Temporarily unblock_input around QUIT.
This commit is contained in:
YAMAMOTO Mitsuharu 2015-12-31 14:18:09 +09:00
parent 30f4a892ec
commit ce5ad125ef
3 changed files with 47 additions and 56 deletions

View file

@ -4084,31 +4084,11 @@ xg_page_setup_dialog (void)
Lisp_Object Lisp_Object
xg_get_page_setup (void) xg_get_page_setup (void)
{ {
Lisp_Object result, orientation_symbol;
GtkPageOrientation orientation; GtkPageOrientation orientation;
Lisp_Object orientation_symbol;
if (page_setup == NULL) if (page_setup == NULL)
page_setup = gtk_page_setup_new (); 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); orientation = gtk_page_setup_get_orientation (page_setup);
if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT) if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT)
orientation_symbol = Qportrait; orientation_symbol = Qportrait;
@ -4118,9 +4098,24 @@ xg_get_page_setup (void)
orientation_symbol = Qreverse_portrait; orientation_symbol = Qreverse_portrait;
else if (orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE) else if (orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)
orientation_symbol = Qreverse_landscape; orientation_symbol = Qreverse_landscape;
result = Fcons (Fcons (Qorientation, orientation_symbol), result);
return result; return listn (CONSTYPE_HEAP, 7,
Fcons (Qorientation, orientation_symbol),
#define MAKE_FLOAT_PAGE_SETUP(f) make_float (f (page_setup, GTK_UNIT_POINTS))
Fcons (Qwidth,
MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_page_width)),
Fcons (Qheight,
MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_page_height)),
Fcons (Qleft_margin,
MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_left_margin)),
Fcons (Qright_margin,
MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_right_margin)),
Fcons (Qtop_margin,
MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_top_margin)),
Fcons (Qbottom_margin,
MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_bottom_margin))
#undef MAKE_FLOAT_PAGE_SETUP
);
} }
static void static void

View file

@ -6564,31 +6564,27 @@ present and mapped to the usual X keysyms. */)
DEFUN ("x-export-frames", Fx_export_frames, Sx_export_frames, 0, 2, 0, DEFUN ("x-export-frames", Fx_export_frames, Sx_export_frames, 0, 2, 0,
doc: /* Return image data of FRAMES in TYPE format. doc: /* Return image data of FRAMES in TYPE format.
FRAMES should be nil (the selected frame), a frame, or a list of FRAMES should be nil (the selected frame), a frame, or a list of
frames (each of which corresponds to one page). Optional arg TYPE frames (each of which corresponds to one page). Each frame should be
should be either `pdf' (default), `png', `postscript', or `svg'. visible. Optional arg TYPE should be either `pdf' (default), `png',
Supported types are determined by the compile-time configuration of `postscript', or `svg'. Supported types are determined by the
cairo. */) compile-time configuration of cairo. */)
(Lisp_Object frames, Lisp_Object type) (Lisp_Object frames, Lisp_Object type)
{ {
Lisp_Object result, rest, tmp; Lisp_Object rest, tmp;
cairo_surface_type_t surface_type; cairo_surface_type_t surface_type;
if (NILP (frames))
frames = selected_frame;
if (!CONSP (frames)) if (!CONSP (frames))
frames = list1 (frames); frames = list1 (frames);
tmp = Qnil; tmp = Qnil;
for (rest = frames; CONSP (rest); rest = XCDR (rest)) for (rest = frames; CONSP (rest); rest = XCDR (rest))
{ {
struct frame *f = XFRAME (XCAR (rest)); struct frame *f = decode_window_system_frame (XCAR (rest));
if (! FRAME_LIVE_P (f) || ! FRAME_X_P (f) || ! FRAME_LIVE_P (f))
error ("Invalid frame");
Lisp_Object frame; Lisp_Object frame;
XSETFRAME (frame, f); XSETFRAME (frame, f);
if (!FRAME_VISIBLE_P (f))
error ("Frames to be exported must be visible.");
tmp = Fcons (frame, tmp); tmp = Fcons (frame, tmp);
} }
frames = Fnreverse (tmp); frames = Fnreverse (tmp);
@ -6624,9 +6620,7 @@ cairo. */)
#endif #endif
error ("Unsupported export type"); error ("Unsupported export type");
result = x_cr_export_frames (frames, surface_type); return x_cr_export_frames (frames, surface_type);
return result;
} }
#ifdef USE_GTK #ifdef USE_GTK
@ -6654,8 +6648,12 @@ The return value is an alist containing the following keys:
on, in points. on, in points.
The paper width can be obtained as the sum of width, left-margin, and 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, right-margin values if the page orientation is `portrait' or
top-margin, and bottom-margin values. */) `reverse-portrait'. Otherwise, it is the sum of width, top-margin,
and bottom-margin values. Likewise, the paper height is the sum of
height, top-margin, and bottom-margin values if the page orientation
is `portrait' or `reverse-portrait'. Otherwise, it is the sum of
height, left-margin, and right-margin values. */)
(void) (void)
{ {
Lisp_Object result; Lisp_Object result;
@ -6675,29 +6673,29 @@ visible. */)
(Lisp_Object frames) (Lisp_Object frames)
{ {
Lisp_Object rest, tmp; Lisp_Object rest, tmp;
int count;
if (NILP (frames))
frames = selected_frame;
if (!CONSP (frames)) if (!CONSP (frames))
frames = list1 (frames); frames = list1 (frames);
tmp = Qnil; tmp = Qnil;
for (rest = frames; CONSP (rest); rest = XCDR (rest)) for (rest = frames; CONSP (rest); rest = XCDR (rest))
{ {
struct frame *f = XFRAME (XCAR (rest)); struct frame *f = decode_window_system_frame (XCAR (rest));
if (! FRAME_LIVE_P (f) || ! FRAME_X_P (f) || ! FRAME_LIVE_P (f))
error ("Invalid frame");
Lisp_Object frame; Lisp_Object frame;
XSETFRAME (frame, f); XSETFRAME (frame, f);
if (!EQ (Fframe_visible_p (frame), Qt)) if (!FRAME_VISIBLE_P (f))
error ("Frames to be printed must be visible."); error ("Frames to be printed must be visible.");
tmp = Fcons (frame, tmp); tmp = Fcons (frame, tmp);
} }
frames = Fnreverse (tmp); frames = Fnreverse (tmp);
/* Make sure the current matrices are up-to-date. */ /* Make sure the current matrices are up-to-date. */
Fredisplay (Qt); count = SPECPDL_INDEX ();
specbind (Qredisplay_dont_pause, Qt);
redisplay_preserve_echo_area (32);
unbind_to (count, Qnil);
block_input (); block_input ();
xg_print_frames_dialog (frames); xg_print_frames_dialog (frames);

View file

@ -569,7 +569,8 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
Lisp_Object acc = Qnil; Lisp_Object acc = Qnil;
int count = SPECPDL_INDEX (); int count = SPECPDL_INDEX ();
Fredisplay (Qt); specbind (Qredisplay_dont_pause, Qt);
redisplay_preserve_echo_area (31);
f = XFRAME (XCAR (frames)); f = XFRAME (XCAR (frames));
frames = XCDR (frames); frames = XCDR (frames);
@ -611,24 +612,18 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
cr = cairo_create (surface); cr = cairo_create (surface);
cairo_surface_destroy (surface); cairo_surface_destroy (surface);
record_unwind_protect (x_cr_destroy, make_save_ptr (cr)); record_unwind_protect (x_cr_destroy, make_save_ptr (cr));
unblock_input ();
while (1) while (1)
{ {
QUIT;
block_input ();
x_free_cr_resources (f); x_free_cr_resources (f);
FRAME_CR_CONTEXT (f) = cr; FRAME_CR_CONTEXT (f) = cr;
x_clear_area (f, 0, 0, width, height); x_clear_area (f, 0, 0, width, height);
expose_frame (f, 0, 0, width, height); expose_frame (f, 0, 0, width, height);
FRAME_CR_CONTEXT (f) = NULL; FRAME_CR_CONTEXT (f) = NULL;
unblock_input ();
if (NILP (frames)) if (NILP (frames))
break; break;
block_input ();
cairo_surface_show_page (surface); cairo_surface_show_page (surface);
f = XFRAME (XCAR (frames)); f = XFRAME (XCAR (frames));
frames = XCDR (frames); frames = XCDR (frames);
@ -636,18 +631,21 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
height = FRAME_PIXEL_HEIGHT (f); height = FRAME_PIXEL_HEIGHT (f);
if (surface_set_size_func) if (surface_set_size_func)
(*surface_set_size_func) (surface, width, height); (*surface_set_size_func) (surface, width, height);
unblock_input (); unblock_input ();
QUIT;
block_input ();
} }
#ifdef CAIRO_HAS_PNG_FUNCTIONS #ifdef CAIRO_HAS_PNG_FUNCTIONS
if (surface_type == CAIRO_SURFACE_TYPE_IMAGE) if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
{ {
block_input ();
cairo_surface_flush (surface); cairo_surface_flush (surface);
cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc); cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
unblock_input ();
} }
#endif #endif
unblock_input ();
unbind_to (count, Qnil); unbind_to (count, Qnil);
return CALLN (Fapply, intern ("concat"), Fnreverse (acc)); return CALLN (Fapply, intern ("concat"), Fnreverse (acc));