aboutsummaryrefslogtreecommitdiffstats
path: root/src/pgtkterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pgtkterm.c')
-rw-r--r--src/pgtkterm.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 544436e6e44..6d8b1ece877 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -7045,6 +7045,17 @@ pgtk_cr_draw_frame (cairo_t * cr, struct frame *f)
7045 cairo_paint (cr); 7045 cairo_paint (cr);
7046} 7046}
7047 7047
7048static cairo_status_t
7049pgtk_cr_accumulate_data (void *closure, const unsigned char *data,
7050 unsigned int length)
7051{
7052 Lisp_Object *acc = (Lisp_Object *) closure;
7053
7054 *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
7055
7056 return CAIRO_STATUS_SUCCESS;
7057}
7058
7048void 7059void
7049pgtk_cr_destroy_frame_context (struct frame *f) 7060pgtk_cr_destroy_frame_context (struct frame *f)
7050{ 7061{
@@ -7056,6 +7067,110 @@ pgtk_cr_destroy_frame_context (struct frame *f)
7056 } 7067 }
7057} 7068}
7058 7069
7070static void
7071pgtk_cr_destroy (void *cr)
7072{
7073 block_input ();
7074 cairo_destroy (cr);
7075 unblock_input ();
7076}
7077
7078
7079
7080Lisp_Object
7081pgtk_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
7082{
7083 struct frame *f;
7084 cairo_surface_t *surface;
7085 cairo_t *cr;
7086 int width, height;
7087 void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
7088 Lisp_Object acc = Qnil;
7089 ptrdiff_t count = SPECPDL_INDEX ();
7090
7091 specbind (Qredisplay_dont_pause, Qt);
7092 redisplay_preserve_echo_area (31);
7093
7094 f = XFRAME (XCAR (frames));
7095 frames = XCDR (frames);
7096 width = FRAME_PIXEL_WIDTH (f);
7097 height = FRAME_PIXEL_HEIGHT (f);
7098
7099 block_input ();
7100#ifdef CAIRO_HAS_PDF_SURFACE
7101 if (surface_type == CAIRO_SURFACE_TYPE_PDF)
7102 {
7103 surface = cairo_pdf_surface_create_for_stream (pgtk_cr_accumulate_data, &acc,
7104 width, height);
7105 surface_set_size_func = cairo_pdf_surface_set_size;
7106 }
7107 else
7108#endif
7109#ifdef CAIRO_HAS_PNG_FUNCTIONS
7110 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
7111 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
7112 else
7113#endif
7114#ifdef CAIRO_HAS_PS_SURFACE
7115 if (surface_type == CAIRO_SURFACE_TYPE_PS)
7116 {
7117 surface = cairo_ps_surface_create_for_stream (pgtk_cr_accumulate_data, &acc,
7118 width, height);
7119 surface_set_size_func = cairo_ps_surface_set_size;
7120 }
7121 else
7122#endif
7123#ifdef CAIRO_HAS_SVG_SURFACE
7124 if (surface_type == CAIRO_SURFACE_TYPE_SVG)
7125 surface = cairo_svg_surface_create_for_stream (pgtk_cr_accumulate_data, &acc,
7126 width, height);
7127 else
7128#endif
7129 abort ();
7130
7131 cr = cairo_create (surface);
7132 cairo_surface_destroy (surface);
7133 record_unwind_protect_ptr (pgtk_cr_destroy, cr);
7134
7135 while (1)
7136 {
7137 cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
7138 FRAME_CR_CONTEXT (f) = cr;
7139 pgtk_clear_area (f, 0, 0, width, height);
7140 expose_frame (f, 0, 0, width, height);
7141 FRAME_CR_CONTEXT (f) = saved_cr;
7142
7143 if (NILP (frames))
7144 break;
7145
7146 cairo_surface_show_page (surface);
7147 f = XFRAME (XCAR (frames));
7148 frames = XCDR (frames);
7149 width = FRAME_PIXEL_WIDTH (f);
7150 height = FRAME_PIXEL_HEIGHT (f);
7151 if (surface_set_size_func)
7152 (*surface_set_size_func) (surface, width, height);
7153
7154 unblock_input ();
7155 maybe_quit ();
7156 block_input ();
7157 }
7158
7159#ifdef CAIRO_HAS_PNG_FUNCTIONS
7160 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
7161 {
7162 cairo_surface_flush (surface);
7163 cairo_surface_write_to_png_stream (surface, pgtk_cr_accumulate_data, &acc);
7164 }
7165#endif
7166 unblock_input ();
7167
7168 unbind_to (count, Qnil);
7169
7170 return CALLN (Fapply, intern ("concat"), Fnreverse (acc));
7171}
7172
7173
7059void 7174void
7060init_pgtkterm (void) 7175init_pgtkterm (void)
7061{ 7176{