emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] cairo c744c8a: Handle specified bg in images. Use generic


From: Jan D.
Subject: [Emacs-diffs] cairo c744c8a: Handle specified bg in images. Use generic libpng code for PNG:s.
Date: Sun, 12 Apr 2015 11:43:02 +0000

branch: cairo
commit c744c8a8fc2ddea0f3e7d510f1a3c98876c51c05
Author: Jan D <address@hidden>
Commit: Jan D <address@hidden>

    Handle specified bg in images.  Use generic libpng code for PNG:s.
    
    * src/image.c (get_spec_bg_or_alpha_as_argb)
    (create_cairo_image_surface): New functions when USE_CAIRO.
    (xpm_load): Call the above functions.  Handle XPM without mask
    when USE_CAIRO.
    (png_load_body): Handle USE_CAIRO case.
    (png_load): Remove USE_CAIRO specific fuction, modify png_load_body
    instead.
    (jpeg_load_body): Call create_cairo_image_surface.
    (gif_load, svg_load_image): Handle specified background, call
    create_cairo_image_surface.
    
    * src/xterm.c (x_draw_image_glyph_string): Added missing USE_CAIRO.
---
 src/ChangeLog |   15 ++++
 src/image.c   |  226 ++++++++++++++++++++++++++-------------------------------
 src/xterm.c   |    5 +-
 3 files changed, 123 insertions(+), 123 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index e5a8442..cc9ffa8 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,18 @@
+2015-04-12  Jan Djärv  <address@hidden>
+
+       * xterm.c (x_draw_image_glyph_string): Added missing USE_CAIRO.
+
+       * image.c (get_spec_bg_or_alpha_as_argb)
+       (create_cairo_image_surface): New functions when USE_CAIRO.
+       (xpm_load): Call the above functions.  Handle XPM without mask
+       when USE_CAIRO.
+       (png_load_body): Handle USE_CAIRO case.
+       (png_load): Remove USE_CAIRO specific fuction, modify png_load_body
+       instead.
+       (jpeg_load_body): Call create_cairo_image_surface.
+       (gif_load, svg_load_image): Handle specified background, call
+       create_cairo_image_surface.
+
 2015-04-11  Jan Djärv  <address@hidden>
 
        * image.c (jpeg_load_body): Create cairo image surface if USE_CAIRO.
diff --git a/src/image.c b/src/image.c
index 8b78157..fd4ae1e 100644
--- a/src/image.c
+++ b/src/image.c
@@ -518,7 +518,6 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
 
 #endif /* HAVE_X_WINDOWS */
 
-
 /***********************************************************************
                            Image types
  ***********************************************************************/
@@ -1084,6 +1083,47 @@ image_ascent (struct image *img, struct face *face, 
struct glyph_slice *slice)
   return ascent;
 }
 
+#ifdef USE_CAIRO
+static uint32_t
+get_spec_bg_or_alpha_as_argb (struct image *img,
+                              struct frame *f)
+{
+  uint32_t bgcolor = 0;
+  XColor xbgcolor;
+  Lisp_Object bg = image_spec_value (img->spec, QCbackground, NULL);
+
+  if (STRINGP (bg) && XParseColor (FRAME_X_DISPLAY (f),
+                                   FRAME_X_COLORMAP (f),
+                                   SSDATA (bg),
+                                   &xbgcolor))
+    bgcolor = (0xff << 24) | ((xbgcolor.red / 256) << 16)
+      | ((xbgcolor.green / 256) << 8) | (xbgcolor.blue / 256);
+  return bgcolor;
+}
+
+static void
+create_cairo_image_surface (struct image *img,
+                            unsigned char *data,
+                            int width,
+                            int height)
+{
+  cairo_surface_t *surface;
+  cairo_format_t format = CAIRO_FORMAT_ARGB32;
+  int stride = cairo_format_stride_for_width (format, width);
+  surface = cairo_image_surface_create_for_data (data,
+                                                 format,
+                                                 width,
+                                                 height,
+                                                 stride);
+  img->width = width;
+  img->height = height;
+  img->cr_data = surface;
+  img->cr_data2 = data;
+  img->pixmap = 0;
+}
+#endif
+
+
 
 /* Image background colors.  */
 
@@ -3635,19 +3675,16 @@ xpm_load (struct frame *f, struct image *img)
   if (rc == XpmSuccess
       && img->ximg->format == ZPixmap
       && img->ximg->bits_per_pixel == 32
-      && img->mask_img->bits_per_pixel == 1)
+      && (! img->mask_img || img->mask_img->bits_per_pixel == 1))
     {
-      cairo_surface_t *surface;
       int width = img->ximg->width;
       int height = img->ximg->height;
-      cairo_format_t format = CAIRO_FORMAT_ARGB32;
-      int stride = cairo_format_stride_for_width (format, width);
-      unsigned char *data = (unsigned char *)
-        xmalloc (width*height*4);
+      unsigned char *data = (unsigned char *) xmalloc (width*height*4);
       int i;
       uint32_t *od = (uint32_t *)data;
       uint32_t *id = (uint32_t *)img->ximg->data;
-      unsigned char *mid = img->mask_img->data;
+      unsigned char *mid = img->mask_img ? img->mask_img->data : 0;
+      uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
 
       for (i = 0; i < height; ++i)
         {
@@ -3655,24 +3692,15 @@ xpm_load (struct frame *f, struct image *img)
           for (k = 0; k < width; ++k)
             {
               int idx = i * img->ximg->bytes_per_line/4 + k;
-              int maskidx = i * img->mask_img->bytes_per_line + k/8;
-              int mask = mid[maskidx] & (1 << (k % 8));
+              int maskidx = mid ? i * img->mask_img->bytes_per_line + k/8 : 0;
+              int mask = mid ? mid[maskidx] & (1 << (k % 8)) : 1;
 
               if (mask) od[idx] = id[idx] + 0xff000000; // ff => full alpha
-              else od[idx] = 0;
+              else od[idx] = bgcolor;
             }
         }
 
-      surface = cairo_image_surface_create_for_data (data,
-                                                     format,
-                                                     width,
-                                                     height,
-                                                     stride);
-      img->width = cairo_image_surface_get_width (surface);
-      img->height = cairo_image_surface_get_height (surface);
-      img->cr_data = surface;
-      img->pixmap = 0;
-      img->cr_data2 = data;
+      create_cairo_image_surface (img, data, width, height);
     }
   else
     {
@@ -5544,7 +5572,7 @@ png_image_p (Lisp_Object object)
 #endif /* HAVE_PNG || HAVE_NS || USE_CAIRO */
 
 
-#if defined HAVE_PNG && !defined HAVE_NS && !defined USE_CAIRO
+#if defined HAVE_PNG && !defined HAVE_NS
 
 # ifdef WINDOWSNT
 /* PNG library details.  */
@@ -5790,6 +5818,11 @@ png_load_body (struct frame *f, struct image *img, 
struct png_load_context *c)
   bool transparent_p;
   struct png_memory_storage tbr;  /* Data to be read */
 
+#ifdef USE_CAIRO
+  unsigned char *data = 0;
+  uint32_t *dataptr;
+#endif
+
   /* Find out what file to load.  */
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
@@ -5908,10 +5941,12 @@ png_load_body (struct frame *f, struct image *img, 
struct png_load_context *c)
       goto error;
     }
 
+#ifndef USE_CAIRO
   /* Create the X image and pixmap now, so that the work below can be
      omitted if the image is too large for X.  */
   if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
     goto error;
+#endif
 
   /* If image contains simply transparency data, we prefer to
      construct a clipping mask.  */
@@ -5998,6 +6033,10 @@ png_load_body (struct frame *f, struct image *img, 
struct png_load_context *c)
       c->fp = NULL;
     }
 
+#ifdef USE_CAIRO
+  data = (unsigned char *) xmalloc (width * height * 4);
+  dataptr = (uint32_t *) data;
+#else
   /* Create an image and pixmap serving as mask if the PNG image
      contains an alpha channel.  */
   if (channels == 4
@@ -6009,6 +6048,7 @@ png_load_body (struct frame *f, struct image *img, struct 
png_load_context *c)
       x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
       goto error;
     }
+#endif
 
   /* Fill the X image and mask from PNG data.  */
   init_color_table ();
@@ -6021,6 +6061,14 @@ png_load_body (struct frame *f, struct image *img, 
struct png_load_context *c)
        {
          int r, g, b;
 
+#ifdef USE_CAIRO
+          int a = 0xff;
+         r = *p++;
+         g = *p++;
+         b = *p++;
+          if (channels == 4) a = *p++;
+          *dataptr++ = (a << 24) | (r << 16) | (g << 8) | b;
+#else
          r = *p++ << 8;
          g = *p++ << 8;
          b = *p++ << 8;
@@ -6047,6 +6095,7 @@ png_load_body (struct frame *f, struct image *img, struct 
png_load_context *c)
                XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : 
PIX_MASK_RETAIN);
              ++p;
            }
+#endif
        }
     }
 
@@ -6076,6 +6125,9 @@ png_load_body (struct frame *f, struct image *img, struct 
png_load_context *c)
   img->width = width;
   img->height = height;
 
+#ifdef USE_CAIRO
+  create_cairo_image_surface (img, data, width, height);
+#else
   /* Maybe fill in the background field while we have ximg handy.
      Casting avoids a GCC warning.  */
   IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
@@ -6092,6 +6144,7 @@ png_load_body (struct frame *f, struct image *img, struct 
png_load_context *c)
 
       image_put_x_image (f, img, mask_img, 1);
     }
+#endif
 
   return 1;
 }
@@ -6113,44 +6166,8 @@ png_load (struct frame *f, struct image *img)
                         image_spec_value (img->spec, QCdata, NULL));
 }
 
-#elif defined USE_CAIRO
 
-static bool
-png_load (struct frame *f, struct image *img)
-{
-  Lisp_Object file;
-  Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
-  cairo_surface_t *surface;
-
-  if (! STRINGP (specified_file))
-    {
-      image_error ("Invalid image spec, file missing `%s'", img->spec, Qnil);
-      return false;
-    }
-
-  file = x_find_image_file (specified_file);
-  if (! STRINGP (file))
-    {
-      image_error ("Cannot find image file `%s'", specified_file, Qnil);
-      return false;
-    }
-
-  surface = cairo_image_surface_create_from_png (SSDATA (file));
-  if (! surface)
-    {
-      image_error ("Error creating surface from file `%s'",
-                   specified_file, Qnil);
-      return false;
-    }
-  img->width = cairo_image_surface_get_width (surface);
-  img->height = cairo_image_surface_get_height (surface);
-  img->cr_data = surface;
-  img->pixmap = 0;
-
-  return true;
-}
-
-#endif /* USE_CAIRO */
+#endif /* HAVE_NS */
 
 
 
@@ -6708,9 +6725,6 @@ jpeg_load_body (struct frame *f, struct image *img,
                                         JPOOL_IMAGE, row_stride, 1);
 #ifdef USE_CAIRO
   {
-    cairo_surface_t *surface;
-    cairo_format_t format = CAIRO_FORMAT_ARGB32;
-    int stride = cairo_format_stride_for_width (format, width);
     unsigned char *data = (unsigned char *) xmalloc (width*height*4);
     uint32_t *dataptr = (uint32_t *) data;
     int r, g, b;
@@ -6729,17 +6743,7 @@ jpeg_load_body (struct frame *f, struct image *img,
           }
       }
 
-    surface = cairo_image_surface_create_for_data (data,
-                                                   format,
-                                                   width,
-                                                   height,
-                                                   stride);
-
-    img->width  = width;
-    img->height = height;
-    img->cr_data = surface;
-    img->cr_data2 = data;
-    img->pixmap = 0;
+    create_cairo_image_surface (img, data, width, height);
   }
 #else
   for (y = 0; y < height; ++y)
@@ -7199,9 +7203,6 @@ tiff_load (struct frame *f, struct image *img)
 
 #ifdef USE_CAIRO
   {
-    cairo_surface_t *surface;
-    cairo_format_t format = CAIRO_FORMAT_ARGB32;
-    int stride = cairo_format_stride_for_width (format, width);
     unsigned char *data = (unsigned char *) xmalloc (width*height*4);
     uint32_t *dataptr = (uint32_t *) data;
     int r, g, b, a;
@@ -7220,17 +7221,7 @@ tiff_load (struct frame *f, struct image *img)
           }
       }
 
-    surface = cairo_image_surface_create_for_data (data,
-                                                   format,
-                                                   width,
-                                                   height,
-                                                   stride);
-
-    img->width  = width;
-    img->height = height;
-    img->cr_data = surface;
-    img->cr_data2 = buf;
-    img->pixmap = 0;
+    create_cairo_image_surface (img, data, width, height);
   }
 #else
   /* Initialize the color table.  */
@@ -7667,6 +7658,21 @@ gif_load (struct frame *f, struct image *img)
 #ifdef USE_CAIRO
   /* xzalloc so data is zero => transparent */
   data = (unsigned char *) xzalloc (width * height * 4);
+  if (STRINGP (specified_bg))
+    {
+      XColor color;
+      if (x_defined_color (f, SSDATA (specified_bg), &color, 0))
+        {
+          uint32_t *dataptr = (uint32_t *)data;
+          int r = color.red/256;
+          int g = color.green/256;
+          int b = color.blue/256;
+
+          for (y = 0; y < height; ++y)
+            for (x = 0; x < width; ++x)
+              *dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
+        }
+    }
 #else
   /* Create the X image and pixmap.  */
   if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
@@ -7887,23 +7893,7 @@ gif_load (struct frame *f, struct image *img)
     }
 
 #ifdef USE_CAIRO
-  {
-    cairo_surface_t *surface;
-    cairo_format_t format = CAIRO_FORMAT_ARGB32;
-    int stride = cairo_format_stride_for_width (format, width);
-
-    surface = cairo_image_surface_create_for_data (data,
-                                                   format,
-                                                   width,
-                                                   height,
-                                                   stride);
-
-    img->width  = width;
-    img->height = height;
-    img->cr_data = surface;
-    img->cr_data2 = data;
-    img->pixmap = 0;
-  }
+  create_cairo_image_surface (img, data, width, height);
 #else
   /* Maybe fill in the background field while we have ximg handy. */
   if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
@@ -9134,11 +9124,9 @@ svg_load_image (struct frame *f,         /* Pointer to 
emacs frame structure.  *
 
 #ifdef USE_CAIRO
   {
-    cairo_surface_t *surface;
-    cairo_format_t format = CAIRO_FORMAT_ARGB32;
-    int stride = cairo_format_stride_for_width (format, width);
     unsigned char *data = (unsigned char *) xmalloc (width*height*4);
     int y;
+    uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
 
     for (y = 0; y < height; ++y)
       {
@@ -9148,27 +9136,21 @@ svg_load_image (struct frame *f,         /* Pointer to 
emacs frame structure.  *
 
         for (x = 0; x < width; ++x)
           {
-            *dataptr = (iconptr[0] << 16)
-              | (iconptr[1] << 8)
-              | iconptr[2]
-              | (iconptr[3] << 24);
+            if (iconptr[3] == 0)
+              *dataptr = bgcolor;
+            else
+              *dataptr = (iconptr[0] << 16)
+                | (iconptr[1] << 8)
+                | iconptr[2]
+                | (iconptr[3] << 24);
+
             iconptr += 4;
             ++dataptr;
           }
       }
 
-    surface = cairo_image_surface_create_for_data (data,
-                                                   format,
-                                                   width,
-                                                   height,
-                                                   stride);
-
+    create_cairo_image_surface (img, data, width, height);
     g_object_unref (pixbuf);
-    img->width  = width;
-    img->height = height;
-    img->cr_data = surface;
-    img->cr_data2 = data;
-    img->pixmap = 0;
   }
 #else
   /* Try to create a x pixmap to hold the svg pixmap.  */
diff --git a/src/xterm.c b/src/xterm.c
index f1632f3..aba700d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3167,6 +3167,7 @@ x_draw_image_glyph_string (struct glyph_string *s)
     }
 
   /* Draw the foreground.  */
+#ifdef USE_CAIRO
   if (s->img->cr_data)
     {
       cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
@@ -3182,7 +3183,9 @@ x_draw_image_glyph_string (struct glyph_string *s)
       cairo_fill (cr);
       x_end_cr_clip (s->f);
     }
-  else if (pixmap != None)
+  else
+#endif
+    if (pixmap != None)
     {
       x_draw_image_foreground_1 (s, pixmap);
       x_set_glyph_string_clipping (s);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]