diff options
Diffstat (limited to 'src/pgtkterm.c')
| -rw-r--r-- | src/pgtkterm.c | 115 |
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 | ||
| 7048 | static cairo_status_t | ||
| 7049 | pgtk_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 | |||
| 7048 | void | 7059 | void |
| 7049 | pgtk_cr_destroy_frame_context (struct frame *f) | 7060 | pgtk_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 | ||
| 7070 | static void | ||
| 7071 | pgtk_cr_destroy (void *cr) | ||
| 7072 | { | ||
| 7073 | block_input (); | ||
| 7074 | cairo_destroy (cr); | ||
| 7075 | unblock_input (); | ||
| 7076 | } | ||
| 7077 | |||
| 7078 | |||
| 7079 | |||
| 7080 | Lisp_Object | ||
| 7081 | pgtk_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 | |||
| 7059 | void | 7174 | void |
| 7060 | init_pgtkterm (void) | 7175 | init_pgtkterm (void) |
| 7061 | { | 7176 | { |