diff options
| author | Ari Roponen | 2018-04-27 15:13:12 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2018-06-02 12:33:13 +0300 |
| commit | aac541e75e2c22d05752025c2087ae2eea4cb525 (patch) | |
| tree | 24357a6045713312196d8faeb62100441ad130c8 /src | |
| parent | e96245a5497ecbc6c58740a6b6bd1f848a44b26c (diff) | |
| download | emacs-aac541e75e2c22d05752025c2087ae2eea4cb525.tar.gz emacs-aac541e75e2c22d05752025c2087ae2eea4cb525.zip | |
Fix some problems in the Cairo build
* src/xterm.c (x_begin_cr_clip): Create image surface.
(x_update_end) [USE_CAIRO]: Remove GTK3-specific code.
(x_scroll_run) [USE_CAIRO]: Implement scrolling.
* src/image.c (lookup_rgb_color) [USE_CAIRO]: Support Cairo.
(jpeg_load_body) [USE_CAIRO]: Support Cairo. Use USE_CAIRO
instead of CAIRO for #ifdef's.
(imagemagick_load_image) [USE_CAIRO]: Support Cairo.
(Bug#31288)
(cherry picked from commit 2d0eff42b8f1122e00f948759ed01a3be1a8c3fc)
Diffstat (limited to 'src')
| -rw-r--r-- | src/image.c | 41 | ||||
| -rw-r--r-- | src/xterm.c | 84 |
2 files changed, 83 insertions, 42 deletions
diff --git a/src/image.c b/src/image.c index 37416c16168..4d5a1bf5e66 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -4629,6 +4629,8 @@ lookup_rgb_color (struct frame *f, int r, int g, int b) | |||
| 4629 | return PALETTERGB (r >> 8, g >> 8, b >> 8); | 4629 | return PALETTERGB (r >> 8, g >> 8, b >> 8); |
| 4630 | #elif defined HAVE_NS | 4630 | #elif defined HAVE_NS |
| 4631 | return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8); | 4631 | return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8); |
| 4632 | #elif defined USE_CAIRO | ||
| 4633 | return (0xffu << 24) | (r << 16) | (g << 8) | b; | ||
| 4632 | #else | 4634 | #else |
| 4633 | xsignal1 (Qfile_error, | 4635 | xsignal1 (Qfile_error, |
| 4634 | build_string ("This Emacs mishandles this image file type")); | 4636 | build_string ("This Emacs mishandles this image file type")); |
| @@ -6702,10 +6704,10 @@ jpeg_load_body (struct frame *f, struct image *img, | |||
| 6702 | FILE *volatile fp = NULL; | 6704 | FILE *volatile fp = NULL; |
| 6703 | JSAMPARRAY buffer; | 6705 | JSAMPARRAY buffer; |
| 6704 | int row_stride, x, y; | 6706 | int row_stride, x, y; |
| 6705 | unsigned long *colors; | ||
| 6706 | int width, height; | 6707 | int width, height; |
| 6707 | int i, ir, ig, ib; | 6708 | int i, ir, ig, ib; |
| 6708 | #ifndef USE_CAIRO | 6709 | #ifndef USE_CAIRO |
| 6710 | unsigned long *colors; | ||
| 6709 | XImagePtr ximg = NULL; | 6711 | XImagePtr ximg = NULL; |
| 6710 | #endif | 6712 | #endif |
| 6711 | 6713 | ||
| @@ -6823,7 +6825,7 @@ jpeg_load_body (struct frame *f, struct image *img, | |||
| 6823 | else | 6825 | else |
| 6824 | ir = 0, ig = 0, ib = 0; | 6826 | ir = 0, ig = 0, ib = 0; |
| 6825 | 6827 | ||
| 6826 | #ifndef CAIRO | 6828 | #ifndef USE_CAIRO |
| 6827 | /* Use the color table mechanism because it handles colors that | 6829 | /* Use the color table mechanism because it handles colors that |
| 6828 | cannot be allocated nicely. Such colors will be replaced with | 6830 | cannot be allocated nicely. Such colors will be replaced with |
| 6829 | a default color, and we don't have to care about which colors | 6831 | a default color, and we don't have to care about which colors |
| @@ -8537,7 +8539,9 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8537 | int width, height; | 8539 | int width, height; |
| 8538 | size_t image_width, image_height; | 8540 | size_t image_width, image_height; |
| 8539 | MagickBooleanType status; | 8541 | MagickBooleanType status; |
| 8542 | #ifndef USE_CAIRO | ||
| 8540 | XImagePtr ximg; | 8543 | XImagePtr ximg; |
| 8544 | #endif | ||
| 8541 | int x, y; | 8545 | int x, y; |
| 8542 | MagickWand *image_wand; | 8546 | MagickWand *image_wand; |
| 8543 | PixelIterator *iterator; | 8547 | PixelIterator *iterator; |
| @@ -8551,6 +8555,9 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8551 | double rotation; | 8555 | double rotation; |
| 8552 | char hint_buffer[MaxTextExtent]; | 8556 | char hint_buffer[MaxTextExtent]; |
| 8553 | char *filename_hint = NULL; | 8557 | char *filename_hint = NULL; |
| 8558 | #ifdef USE_CAIRO | ||
| 8559 | void *data = NULL; | ||
| 8560 | #endif | ||
| 8554 | 8561 | ||
| 8555 | /* Initialize the ImageMagick environment. */ | 8562 | /* Initialize the ImageMagick environment. */ |
| 8556 | static bool imagemagick_initialized; | 8563 | static bool imagemagick_initialized; |
| @@ -8759,6 +8766,12 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8759 | /* Magicexportimage is normally faster than pixelpushing. This | 8766 | /* Magicexportimage is normally faster than pixelpushing. This |
| 8760 | method is also well tested. Some aspects of this method are | 8767 | method is also well tested. Some aspects of this method are |
| 8761 | ad-hoc and needs to be more researched. */ | 8768 | ad-hoc and needs to be more researched. */ |
| 8769 | void *dataptr; | ||
| 8770 | #ifdef USE_CAIRO | ||
| 8771 | data = xmalloc (width * height * 4); | ||
| 8772 | const char *exportdepth = "BGRA"; | ||
| 8773 | dataptr = data; | ||
| 8774 | #else | ||
| 8762 | int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/ | 8775 | int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/ |
| 8763 | const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/ | 8776 | const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/ |
| 8764 | /* Try to create a x pixmap to hold the imagemagick pixmap. */ | 8777 | /* Try to create a x pixmap to hold the imagemagick pixmap. */ |
| @@ -8771,6 +8784,8 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8771 | image_error ("Imagemagick X bitmap allocation failure"); | 8784 | image_error ("Imagemagick X bitmap allocation failure"); |
| 8772 | goto imagemagick_error; | 8785 | goto imagemagick_error; |
| 8773 | } | 8786 | } |
| 8787 | dataptr = ximg->data; | ||
| 8788 | #endif /* not USE_CAIRO */ | ||
| 8774 | 8789 | ||
| 8775 | /* Oddly, the below code doesn't seem to work:*/ | 8790 | /* Oddly, the below code doesn't seem to work:*/ |
| 8776 | /* switch(ximg->bitmap_unit){ */ | 8791 | /* switch(ximg->bitmap_unit){ */ |
| @@ -8793,14 +8808,17 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8793 | */ | 8808 | */ |
| 8794 | int pixelwidth = CharPixel; /*??? TODO figure out*/ | 8809 | int pixelwidth = CharPixel; /*??? TODO figure out*/ |
| 8795 | MagickExportImagePixels (image_wand, 0, 0, width, height, | 8810 | MagickExportImagePixels (image_wand, 0, 0, width, height, |
| 8796 | exportdepth, pixelwidth, ximg->data); | 8811 | exportdepth, pixelwidth, dataptr); |
| 8797 | } | 8812 | } |
| 8798 | else | 8813 | else |
| 8799 | #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */ | 8814 | #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */ |
| 8800 | { | 8815 | { |
| 8801 | size_t image_height; | 8816 | size_t image_height; |
| 8802 | MagickRealType color_scale = 65535.0 / QuantumRange; | 8817 | MagickRealType color_scale = 65535.0 / QuantumRange; |
| 8803 | 8818 | #ifdef USE_CAIRO | |
| 8819 | data = xmalloc (width * height * 4); | ||
| 8820 | color_scale /= 256; | ||
| 8821 | #else | ||
| 8804 | /* Try to create a x pixmap to hold the imagemagick pixmap. */ | 8822 | /* Try to create a x pixmap to hold the imagemagick pixmap. */ |
| 8805 | if (!image_create_x_image_and_pixmap (f, img, width, height, 0, | 8823 | if (!image_create_x_image_and_pixmap (f, img, width, height, 0, |
| 8806 | &ximg, 0)) | 8824 | &ximg, 0)) |
| @@ -8811,6 +8829,7 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8811 | image_error ("Imagemagick X bitmap allocation failure"); | 8829 | image_error ("Imagemagick X bitmap allocation failure"); |
| 8812 | goto imagemagick_error; | 8830 | goto imagemagick_error; |
| 8813 | } | 8831 | } |
| 8832 | #endif | ||
| 8814 | 8833 | ||
| 8815 | /* Copy imagemagick image to x with primitive yet robust pixel | 8834 | /* Copy imagemagick image to x with primitive yet robust pixel |
| 8816 | pusher loop. This has been tested a lot with many different | 8835 | pusher loop. This has been tested a lot with many different |
| @@ -8823,7 +8842,9 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8823 | #ifdef COLOR_TABLE_SUPPORT | 8842 | #ifdef COLOR_TABLE_SUPPORT |
| 8824 | free_color_table (); | 8843 | free_color_table (); |
| 8825 | #endif | 8844 | #endif |
| 8845 | #ifndef USE_CAIRO | ||
| 8826 | x_destroy_x_image (ximg); | 8846 | x_destroy_x_image (ximg); |
| 8847 | #endif | ||
| 8827 | image_error ("Imagemagick pixel iterator creation failed"); | 8848 | image_error ("Imagemagick pixel iterator creation failed"); |
| 8828 | goto imagemagick_error; | 8849 | goto imagemagick_error; |
| 8829 | } | 8850 | } |
| @@ -8839,16 +8860,27 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8839 | for (x = 0; x < xlim; x++) | 8860 | for (x = 0; x < xlim; x++) |
| 8840 | { | 8861 | { |
| 8841 | PixelGetMagickColor (pixels[x], &pixel); | 8862 | PixelGetMagickColor (pixels[x], &pixel); |
| 8863 | #ifdef USE_CAIRO | ||
| 8864 | ((uint32_t *)data)[width * y + x] = | ||
| 8865 | lookup_rgb_color (f, | ||
| 8866 | color_scale * pixel.red, | ||
| 8867 | color_scale * pixel.green, | ||
| 8868 | color_scale * pixel.blue); | ||
| 8869 | #else | ||
| 8842 | XPutPixel (ximg, x, y, | 8870 | XPutPixel (ximg, x, y, |
| 8843 | lookup_rgb_color (f, | 8871 | lookup_rgb_color (f, |
| 8844 | color_scale * pixel.red, | 8872 | color_scale * pixel.red, |
| 8845 | color_scale * pixel.green, | 8873 | color_scale * pixel.green, |
| 8846 | color_scale * pixel.blue)); | 8874 | color_scale * pixel.blue)); |
| 8875 | #endif | ||
| 8847 | } | 8876 | } |
| 8848 | } | 8877 | } |
| 8849 | DestroyPixelIterator (iterator); | 8878 | DestroyPixelIterator (iterator); |
| 8850 | } | 8879 | } |
| 8851 | 8880 | ||
| 8881 | #ifdef USE_CAIRO | ||
| 8882 | create_cairo_image_surface (img, data, width, height); | ||
| 8883 | #else | ||
| 8852 | #ifdef COLOR_TABLE_SUPPORT | 8884 | #ifdef COLOR_TABLE_SUPPORT |
| 8853 | /* Remember colors allocated for this image. */ | 8885 | /* Remember colors allocated for this image. */ |
| 8854 | img->colors = colors_in_color_table (&img->ncolors); | 8886 | img->colors = colors_in_color_table (&img->ncolors); |
| @@ -8860,6 +8892,7 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8860 | 8892 | ||
| 8861 | /* Put ximg into the image. */ | 8893 | /* Put ximg into the image. */ |
| 8862 | image_put_x_image (f, img, ximg, 0); | 8894 | image_put_x_image (f, img, ximg, 0); |
| 8895 | #endif | ||
| 8863 | 8896 | ||
| 8864 | /* Final cleanup. image_wand should be the only resource left. */ | 8897 | /* Final cleanup. image_wand should be the only resource left. */ |
| 8865 | DestroyMagickWand (image_wand); | 8898 | DestroyMagickWand (image_wand); |
diff --git a/src/xterm.c b/src/xterm.c index 7b445e5f46c..f6f2079ec69 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -360,17 +360,12 @@ x_begin_cr_clip (struct frame *f, GC gc) | |||
| 360 | 360 | ||
| 361 | if (! FRAME_CR_SURFACE (f)) | 361 | if (! FRAME_CR_SURFACE (f)) |
| 362 | { | 362 | { |
| 363 | cairo_surface_t *surface; | 363 | FRAME_CR_SURFACE (f) = |
| 364 | surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f), | 364 | cairo_image_surface_create (CAIRO_FORMAT_ARGB32, |
| 365 | FRAME_X_DRAWABLE (f), | 365 | FRAME_PIXEL_WIDTH (f), |
| 366 | FRAME_DISPLAY_INFO (f)->visual, | 366 | FRAME_PIXEL_HEIGHT (f)); |
| 367 | FRAME_PIXEL_WIDTH (f), | 367 | } |
| 368 | FRAME_PIXEL_HEIGHT (f)); | 368 | cr = cairo_create (FRAME_CR_SURFACE (f)); |
| 369 | cr = cairo_create (surface); | ||
| 370 | cairo_surface_destroy (surface); | ||
| 371 | } | ||
| 372 | else | ||
| 373 | cr = cairo_create (FRAME_CR_SURFACE (f)); | ||
| 374 | FRAME_CR_CONTEXT (f) = cr; | 369 | FRAME_CR_CONTEXT (f) = cr; |
| 375 | } | 370 | } |
| 376 | cairo_save (cr); | 371 | cairo_save (cr); |
| @@ -1239,32 +1234,24 @@ x_update_end (struct frame *f) | |||
| 1239 | #ifdef USE_CAIRO | 1234 | #ifdef USE_CAIRO |
| 1240 | if (FRAME_CR_SURFACE (f)) | 1235 | if (FRAME_CR_SURFACE (f)) |
| 1241 | { | 1236 | { |
| 1242 | cairo_t *cr = 0; | 1237 | cairo_t *cr; |
| 1243 | block_input(); | 1238 | cairo_surface_t *surface; |
| 1244 | #if defined (USE_GTK) && defined (HAVE_GTK3) | 1239 | int width, height; |
| 1245 | if (FRAME_GTK_WIDGET (f)) | 1240 | |
| 1246 | { | 1241 | block_input (); |
| 1247 | GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f)); | 1242 | width = FRAME_PIXEL_WIDTH (f); |
| 1248 | cr = gdk_cairo_create (w); | 1243 | height = FRAME_PIXEL_HEIGHT (f); |
| 1249 | } | 1244 | if (! FRAME_EXTERNAL_TOOL_BAR (f)) |
| 1250 | else | 1245 | height += FRAME_TOOL_BAR_HEIGHT (f); |
| 1251 | #endif | 1246 | if (! FRAME_EXTERNAL_MENU_BAR (f)) |
| 1252 | { | 1247 | height += FRAME_MENU_BAR_HEIGHT (f); |
| 1253 | cairo_surface_t *surface; | 1248 | surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f), |
| 1254 | int width = FRAME_PIXEL_WIDTH (f); | 1249 | FRAME_X_DRAWABLE (f), |
| 1255 | int height = FRAME_PIXEL_HEIGHT (f); | 1250 | FRAME_DISPLAY_INFO (f)->visual, |
| 1256 | if (! FRAME_EXTERNAL_TOOL_BAR (f)) | 1251 | width, |
| 1257 | height += FRAME_TOOL_BAR_HEIGHT (f); | 1252 | height); |
| 1258 | if (! FRAME_EXTERNAL_MENU_BAR (f)) | 1253 | cr = cairo_create (surface); |
| 1259 | height += FRAME_MENU_BAR_HEIGHT (f); | 1254 | cairo_surface_destroy (surface); |
| 1260 | surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f), | ||
| 1261 | FRAME_X_DRAWABLE (f), | ||
| 1262 | FRAME_DISPLAY_INFO (f)->visual, | ||
| 1263 | width, | ||
| 1264 | height); | ||
| 1265 | cr = cairo_create (surface); | ||
| 1266 | cairo_surface_destroy (surface); | ||
| 1267 | } | ||
| 1268 | 1255 | ||
| 1269 | cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0); | 1256 | cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0); |
| 1270 | cairo_paint (cr); | 1257 | cairo_paint (cr); |
| @@ -4256,7 +4243,28 @@ x_scroll_run (struct window *w, struct run *run) | |||
| 4256 | x_clear_cursor (w); | 4243 | x_clear_cursor (w); |
| 4257 | 4244 | ||
| 4258 | #ifdef USE_CAIRO | 4245 | #ifdef USE_CAIRO |
| 4259 | SET_FRAME_GARBAGED (f); | 4246 | if (FRAME_CR_CONTEXT (f)) |
| 4247 | { | ||
| 4248 | cairo_surface_t *s = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, | ||
| 4249 | width, height); | ||
| 4250 | cairo_t *cr = cairo_create (s); | ||
| 4251 | cairo_set_source_surface (cr, cairo_get_target (FRAME_CR_CONTEXT (f)), | ||
| 4252 | -x, -from_y); | ||
| 4253 | cairo_paint (cr); | ||
| 4254 | cairo_destroy (cr); | ||
| 4255 | |||
| 4256 | cr = FRAME_CR_CONTEXT (f); | ||
| 4257 | cairo_save (cr); | ||
| 4258 | cairo_set_source_surface (cr, s, 0, to_y); | ||
| 4259 | cairo_rectangle (cr, x, to_y, width, height); | ||
| 4260 | cairo_fill (cr); | ||
| 4261 | cairo_restore (cr); | ||
| 4262 | cairo_surface_destroy (s); | ||
| 4263 | } | ||
| 4264 | else | ||
| 4265 | { | ||
| 4266 | SET_FRAME_GARBAGED (f); | ||
| 4267 | } | ||
| 4260 | #else | 4268 | #else |
| 4261 | XCopyArea (FRAME_X_DISPLAY (f), | 4269 | XCopyArea (FRAME_X_DISPLAY (f), |
| 4262 | FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f), | 4270 | FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f), |