aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c109
1 files changed, 86 insertions, 23 deletions
diff --git a/src/image.c b/src/image.c
index 576956d4dbb..18126a804f3 100644
--- a/src/image.c
+++ b/src/image.c
@@ -135,14 +135,6 @@ typedef struct ns_bitmap_record Bitmap_Record;
135# define COLOR_TABLE_SUPPORT 1 135# define COLOR_TABLE_SUPPORT 1
136#endif 136#endif
137 137
138#ifdef HAVE_RSVG
139#if defined HAVE_NS
140# define FRAME_SCALE_FACTOR(f) ns_frame_scale_factor (f)
141#else
142# define FRAME_SCALE_FACTOR(f) 1;
143#endif
144#endif
145
146static void image_disable_image (struct frame *, struct image *); 138static void image_disable_image (struct frame *, struct image *);
147static void image_edge_detection (struct frame *, struct image *, Lisp_Object, 139static void image_edge_detection (struct frame *, struct image *, Lisp_Object,
148 Lisp_Object); 140 Lisp_Object);
@@ -1207,6 +1199,7 @@ free_image (struct frame *f, struct image *img)
1207 1199
1208 /* Free resources, then free IMG. */ 1200 /* Free resources, then free IMG. */
1209 img->type->free_img (f, img); 1201 img->type->free_img (f, img);
1202 xfree (img->face_font_family);
1210 xfree (img); 1203 xfree (img);
1211 } 1204 }
1212} 1205}
@@ -1605,7 +1598,7 @@ make_image_cache (void)
1605static struct image * 1598static struct image *
1606search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash, 1599search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash,
1607 unsigned long foreground, unsigned long background, 1600 unsigned long foreground, unsigned long background,
1608 bool ignore_colors) 1601 int font_size, char *font_family, bool ignore_colors)
1609{ 1602{
1610 struct image *img; 1603 struct image *img;
1611 struct image_cache *c = FRAME_IMAGE_CACHE (f); 1604 struct image_cache *c = FRAME_IMAGE_CACHE (f);
@@ -1629,7 +1622,10 @@ search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash,
1629 if (img->hash == hash 1622 if (img->hash == hash
1630 && !NILP (Fequal (img->spec, spec)) 1623 && !NILP (Fequal (img->spec, spec))
1631 && (ignore_colors || (img->face_foreground == foreground 1624 && (ignore_colors || (img->face_foreground == foreground
1632 && img->face_background == background))) 1625 && img->face_background == background
1626 && img->face_font_size == font_size
1627 && (font_family
1628 &&!strcmp (font_family, img->face_font_family)))))
1633 break; 1629 break;
1634 return img; 1630 return img;
1635} 1631}
@@ -1647,7 +1643,7 @@ uncache_image (struct frame *f, Lisp_Object spec)
1647 can have multiple copies of an image with the same spec. We want 1643 can have multiple copies of an image with the same spec. We want
1648 to remove them all to ensure the user doesn't see an old version 1644 to remove them all to ensure the user doesn't see an old version
1649 of the image when the face changes. */ 1645 of the image when the face changes. */
1650 while ((img = search_image_cache (f, spec, hash, 0, 0, true))) 1646 while ((img = search_image_cache (f, spec, hash, 0, 0, 0, NULL, true)))
1651 { 1647 {
1652 free_image (f, img); 1648 free_image (f, img);
1653 /* As display glyphs may still be referring to the image ID, we 1649 /* As display glyphs may still be referring to the image ID, we
@@ -2419,6 +2415,8 @@ lookup_image (struct frame *f, Lisp_Object spec, int face_id)
2419 struct face *face = FACE_FROM_ID (f, face_id); 2415 struct face *face = FACE_FROM_ID (f, face_id);
2420 unsigned long foreground = FACE_COLOR_TO_PIXEL (face->foreground, f); 2416 unsigned long foreground = FACE_COLOR_TO_PIXEL (face->foreground, f);
2421 unsigned long background = FACE_COLOR_TO_PIXEL (face->background, f); 2417 unsigned long background = FACE_COLOR_TO_PIXEL (face->background, f);
2418 int font_size = face->font->pixel_size;
2419 char *font_family = SSDATA (face->lface[LFACE_FAMILY_INDEX]);
2422 2420
2423 /* F must be a window-system frame, and SPEC must be a valid image 2421 /* F must be a window-system frame, and SPEC must be a valid image
2424 specification. */ 2422 specification. */
@@ -2427,7 +2425,8 @@ lookup_image (struct frame *f, Lisp_Object spec, int face_id)
2427 2425
2428 /* Look up SPEC in the hash table of the image cache. */ 2426 /* Look up SPEC in the hash table of the image cache. */
2429 hash = sxhash (spec); 2427 hash = sxhash (spec);
2430 img = search_image_cache (f, spec, hash, foreground, background, false); 2428 img = search_image_cache (f, spec, hash, foreground, background,
2429 font_size, font_family, false);
2431 if (img && img->load_failed_p) 2430 if (img && img->load_failed_p)
2432 { 2431 {
2433 free_image (f, img); 2432 free_image (f, img);
@@ -2442,6 +2441,9 @@ lookup_image (struct frame *f, Lisp_Object spec, int face_id)
2442 cache_image (f, img); 2441 cache_image (f, img);
2443 img->face_foreground = foreground; 2442 img->face_foreground = foreground;
2444 img->face_background = background; 2443 img->face_background = background;
2444 img->face_font_size = font_size;
2445 img->face_font_family = xmalloc (strlen (font_family) + 1);
2446 strcpy (img->face_font_family, font_family);
2445 img->load_failed_p = ! img->type->load_img (f, img); 2447 img->load_failed_p = ! img->type->load_img (f, img);
2446 2448
2447 /* If we can't load the image, and we don't have a width and 2449 /* If we can't load the image, and we don't have a width and
@@ -9540,6 +9542,7 @@ enum svg_keyword_index
9540 SVG_DATA, 9542 SVG_DATA,
9541 SVG_FILE, 9543 SVG_FILE,
9542 SVG_BASE_URI, 9544 SVG_BASE_URI,
9545 SVG_CSS,
9543 SVG_ASCENT, 9546 SVG_ASCENT,
9544 SVG_MARGIN, 9547 SVG_MARGIN,
9545 SVG_RELIEF, 9548 SVG_RELIEF,
@@ -9560,6 +9563,7 @@ static const struct image_keyword svg_format[SVG_LAST] =
9560 {":data", IMAGE_STRING_VALUE, 0}, 9563 {":data", IMAGE_STRING_VALUE, 0},
9561 {":file", IMAGE_STRING_VALUE, 0}, 9564 {":file", IMAGE_STRING_VALUE, 0},
9562 {":base-uri", IMAGE_STRING_VALUE, 0}, 9565 {":base-uri", IMAGE_STRING_VALUE, 0},
9566 {":css", IMAGE_STRING_VALUE, 0},
9563 {":ascent", IMAGE_ASCENT_VALUE, 0}, 9567 {":ascent", IMAGE_ASCENT_VALUE, 0},
9564 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, 9568 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
9565 {":relief", IMAGE_INTEGER_VALUE, 0}, 9569 {":relief", IMAGE_INTEGER_VALUE, 0},
@@ -9643,6 +9647,11 @@ DEF_DLL_FN (gboolean, rsvg_handle_get_geometry_for_layer,
9643 (RsvgHandle *, const char *, const RsvgRectangle *, 9647 (RsvgHandle *, const char *, const RsvgRectangle *,
9644 RsvgRectangle *, RsvgRectangle *, GError **)); 9648 RsvgRectangle *, RsvgRectangle *, GError **));
9645# endif 9649# endif
9650
9651# if LIBRSVG_CHECK_VERSION (2, 48, 0)
9652DEF_DLL_FN (gboolean, rsvg_handle_set_stylesheet,
9653 (RsvgHandle *, const guint8 *, gsize, GError **));
9654# endif
9646DEF_DLL_FN (void, rsvg_handle_get_dimensions, 9655DEF_DLL_FN (void, rsvg_handle_get_dimensions,
9647 (RsvgHandle *, RsvgDimensionData *)); 9656 (RsvgHandle *, RsvgDimensionData *));
9648DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *)); 9657DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
@@ -9696,6 +9705,9 @@ init_svg_functions (void)
9696 LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_dimensions); 9705 LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_dimensions);
9697 LOAD_DLL_FN (library, rsvg_handle_get_geometry_for_layer); 9706 LOAD_DLL_FN (library, rsvg_handle_get_geometry_for_layer);
9698#endif 9707#endif
9708#if LIBRSVG_CHECK_VERSION (2, 48, 0)
9709 LOAD_DLL_FN (library, rsvg_handle_set_stylesheet);
9710#endif
9699 LOAD_DLL_FN (library, rsvg_handle_get_dimensions); 9711 LOAD_DLL_FN (library, rsvg_handle_get_dimensions);
9700 LOAD_DLL_FN (library, rsvg_handle_get_pixbuf); 9712 LOAD_DLL_FN (library, rsvg_handle_get_pixbuf);
9701 9713
@@ -9736,6 +9748,9 @@ init_svg_functions (void)
9736# undef rsvg_handle_get_geometry_for_layer 9748# undef rsvg_handle_get_geometry_for_layer
9737# endif 9749# endif
9738# undef rsvg_handle_get_dimensions 9750# undef rsvg_handle_get_dimensions
9751# if LIBRSVG_CHECK_VERSION (2, 48, 0)
9752# undef rsvg_handle_set_stylesheet
9753# endif
9739# undef rsvg_handle_get_pixbuf 9754# undef rsvg_handle_get_pixbuf
9740# if LIBRSVG_CHECK_VERSION (2, 32, 0) 9755# if LIBRSVG_CHECK_VERSION (2, 32, 0)
9741# undef g_file_new_for_path 9756# undef g_file_new_for_path
@@ -9769,6 +9784,9 @@ init_svg_functions (void)
9769 fn_rsvg_handle_get_geometry_for_layer 9784 fn_rsvg_handle_get_geometry_for_layer
9770# endif 9785# endif
9771# define rsvg_handle_get_dimensions fn_rsvg_handle_get_dimensions 9786# define rsvg_handle_get_dimensions fn_rsvg_handle_get_dimensions
9787# if LIBRSVG_CHECK_VERSION (2, 48, 0)
9788# define rsvg_handle_set_stylesheet fn_rsvg_handle_set_stylesheet
9789# endif
9772# define rsvg_handle_get_pixbuf fn_rsvg_handle_get_pixbuf 9790# define rsvg_handle_get_pixbuf fn_rsvg_handle_get_pixbuf
9773# if LIBRSVG_CHECK_VERSION (2, 32, 0) 9791# if LIBRSVG_CHECK_VERSION (2, 32, 0)
9774# define g_file_new_for_path fn_g_file_new_for_path 9792# define g_file_new_for_path fn_g_file_new_for_path
@@ -9846,7 +9864,7 @@ svg_load (struct frame *f, struct image *img)
9846 9864
9847#if LIBRSVG_CHECK_VERSION (2, 46, 0) 9865#if LIBRSVG_CHECK_VERSION (2, 46, 0)
9848static double 9866static double
9849svg_css_length_to_pixels (RsvgLength length, double dpi) 9867svg_css_length_to_pixels (RsvgLength length, double dpi, int font_size)
9850{ 9868{
9851 double value = length.length; 9869 double value = length.length;
9852 9870
@@ -9874,9 +9892,16 @@ svg_css_length_to_pixels (RsvgLength length, double dpi)
9874 case RSVG_UNIT_IN: 9892 case RSVG_UNIT_IN:
9875 value *= dpi; 9893 value *= dpi;
9876 break; 9894 break;
9895#if LIBRSVG_CHECK_VERSION (2, 48, 0)
9896 /* We don't know exactly what font size is used on older librsvg
9897 versions. */
9898 case RSVG_UNIT_EM:
9899 value *= font_size;
9900 break;
9901#endif
9877 default: 9902 default:
9878 /* Probably one of em, ex, or %. We can't know what the pixel 9903 /* Probably ex or %. We can't know what the pixel value is
9879 value is without more information. */ 9904 without more information. */
9880 value = 0; 9905 value = 0;
9881 } 9906 }
9882 9907
@@ -9906,6 +9931,10 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9906 char *wrapped_contents = NULL; 9931 char *wrapped_contents = NULL;
9907 ptrdiff_t wrapped_size; 9932 ptrdiff_t wrapped_size;
9908 9933
9934#if LIBRSVG_CHECK_VERSION (2, 48, 0)
9935 char *css = NULL;
9936#endif
9937
9909#if ! GLIB_CHECK_VERSION (2, 36, 0) 9938#if ! GLIB_CHECK_VERSION (2, 36, 0)
9910 /* g_type_init is a glib function that must be called prior to 9939 /* g_type_init is a glib function that must be called prior to
9911 using gnome type library functions (obsolete since 2.36.0). */ 9940 using gnome type library functions (obsolete since 2.36.0). */
@@ -9931,6 +9960,26 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9931 9960
9932 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx, 9961 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
9933 FRAME_DISPLAY_INFO (f)->resy); 9962 FRAME_DISPLAY_INFO (f)->resy);
9963
9964#if LIBRSVG_CHECK_VERSION (2, 48, 0)
9965 Lisp_Object lcss = image_spec_value (img->spec, QCcss, NULL);
9966 if (!STRINGP (lcss))
9967 {
9968 /* Generate the CSS for the SVG image. */
9969 const char *css_spec = "svg{font-family:\"%s\";font-size:%4dpx}";
9970 int css_len = strlen (css_spec) + strlen (img->face_font_family);
9971 css = xmalloc (css_len);
9972 snprintf (css, css_len, css_spec, img->face_font_family, img->face_font_size);
9973 rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *)css, strlen (css), NULL);
9974 }
9975 else
9976 {
9977 css = xmalloc (SBYTES (lcss) + 1);
9978 strncpy (css, SSDATA (lcss), SBYTES (lcss));
9979 *(css + SBYTES (lcss) + 1) = 0;
9980 }
9981#endif
9982
9934#else 9983#else
9935 /* Make a handle to a new rsvg object. */ 9984 /* Make a handle to a new rsvg object. */
9936 rsvg_handle = rsvg_handle_new (); 9985 rsvg_handle = rsvg_handle_new ();
@@ -9973,20 +10022,20 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9973 if (has_width && has_height) 10022 if (has_width && has_height)
9974 { 10023 {
9975 /* Success! We can use these values directly. */ 10024 /* Success! We can use these values directly. */
9976 viewbox_width = svg_css_length_to_pixels (iwidth, dpi); 10025 viewbox_width = svg_css_length_to_pixels (iwidth, dpi, img->face_font_size);
9977 viewbox_height = svg_css_length_to_pixels (iheight, dpi); 10026 viewbox_height = svg_css_length_to_pixels (iheight, dpi, img->face_font_size);
9978 } 10027 }
9979 else if (has_width && has_viewbox) 10028 else if (has_width && has_viewbox)
9980 { 10029 {
9981 viewbox_width = svg_css_length_to_pixels (iwidth, dpi); 10030 viewbox_width = svg_css_length_to_pixels (iwidth, dpi, img->face_font_size);
9982 viewbox_height = svg_css_length_to_pixels (iwidth, dpi) 10031 viewbox_height = svg_css_length_to_pixels (iwidth, dpi, img->face_font_size)
9983 * viewbox.width / viewbox.height; 10032 * viewbox.height / viewbox.width;
9984 } 10033 }
9985 else if (has_height && has_viewbox) 10034 else if (has_height && has_viewbox)
9986 { 10035 {
9987 viewbox_height = svg_css_length_to_pixels (iheight, dpi); 10036 viewbox_height = svg_css_length_to_pixels (iheight, dpi, img->face_font_size);
9988 viewbox_width = svg_css_length_to_pixels (iheight, dpi) 10037 viewbox_width = svg_css_length_to_pixels (iheight, dpi, img->face_font_size)
9989 * viewbox.height / viewbox.width; 10038 * viewbox.width / viewbox.height;
9990 } 10039 }
9991 else if (has_viewbox) 10040 else if (has_viewbox)
9992 { 10041 {
@@ -10107,6 +10156,10 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
10107 10156
10108 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx, 10157 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10109 FRAME_DISPLAY_INFO (f)->resy); 10158 FRAME_DISPLAY_INFO (f)->resy);
10159
10160#if LIBRSVG_CHECK_VERSION (2, 48, 0)
10161 rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *)css, strlen (css), NULL);
10162#endif
10110#else 10163#else
10111 /* Make a handle to a new rsvg object. */ 10164 /* Make a handle to a new rsvg object. */
10112 rsvg_handle = rsvg_handle_new (); 10165 rsvg_handle = rsvg_handle_new ();
@@ -10140,6 +10193,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
10140 g_object_unref (rsvg_handle); 10193 g_object_unref (rsvg_handle);
10141 xfree (wrapped_contents); 10194 xfree (wrapped_contents);
10142 10195
10196#if LIBRSVG_CHECK_VERSION (2, 48, 0)
10197 if (!STRINGP (lcss))
10198 xfree (css);
10199#endif
10200
10143 /* Extract some meta data from the svg handle. */ 10201 /* Extract some meta data from the svg handle. */
10144 width = gdk_pixbuf_get_width (pixbuf); 10202 width = gdk_pixbuf_get_width (pixbuf);
10145 height = gdk_pixbuf_get_height (pixbuf); 10203 height = gdk_pixbuf_get_height (pixbuf);
@@ -10210,6 +10268,10 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
10210 g_object_unref (rsvg_handle); 10268 g_object_unref (rsvg_handle);
10211 if (wrapped_contents) 10269 if (wrapped_contents)
10212 xfree (wrapped_contents); 10270 xfree (wrapped_contents);
10271#if LIBRSVG_CHECK_VERSION (2, 48, 0)
10272 if (css && !STRINGP (lcss))
10273 xfree (css);
10274#endif
10213 /* FIXME: Use error->message so the user knows what is the actual 10275 /* FIXME: Use error->message so the user knows what is the actual
10214 problem with the image. */ 10276 problem with the image. */
10215 image_error ("Error parsing SVG image `%s'", img->spec); 10277 image_error ("Error parsing SVG image `%s'", img->spec);
@@ -10801,6 +10863,7 @@ non-numeric, there is no explicit limit on the size of images. */);
10801#if defined (HAVE_RSVG) 10863#if defined (HAVE_RSVG)
10802 DEFSYM (Qsvg, "svg"); 10864 DEFSYM (Qsvg, "svg");
10803 DEFSYM (QCbase_uri, ":base-uri"); 10865 DEFSYM (QCbase_uri, ":base-uri");
10866 DEFSYM (QCcss, ":css");
10804 add_image_type (Qsvg); 10867 add_image_type (Qsvg);
10805#ifdef HAVE_NTGUI 10868#ifdef HAVE_NTGUI
10806 /* Other libraries used directly by svg code. */ 10869 /* Other libraries used directly by svg code. */