Mercurial > hg > xemacs-beta
comparison src/glyphs-x.c @ 221:6c0ae1f9357f r20-4b9
Import from CVS: tag r20-4b9
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:10:02 +0200 |
parents | 262b8bb4a523 |
children | 2c611d1463a6 |
comparison
equal
deleted
inserted
replaced
220:04f4bca7b601 | 221:6c0ae1f9357f |
---|---|
58 | 58 |
59 #ifdef HAVE_IMAGEMAGICK | 59 #ifdef HAVE_IMAGEMAGICK |
60 #include <magick/magick.h> | 60 #include <magick/magick.h> |
61 /*#include <image.h>*/ | 61 /*#include <image.h>*/ |
62 #include <assert.h> | 62 #include <assert.h> |
63 | |
64 #define OLDCOMPAT /* allow lisp code using the old names to still function */ | |
63 #endif | 65 #endif |
64 | 66 |
65 #define LISP_DEVICE_TO_X_SCREEN(dev) \ | 67 #define LISP_DEVICE_TO_X_SCREEN(dev) \ |
66 XDefaultScreenOfDisplay (DEVICE_X_DISPLAY (XDEVICE (dev))) | 68 XDefaultScreenOfDisplay (DEVICE_X_DISPLAY (XDEVICE (dev))) |
67 | 69 |
83 #endif | 85 #endif |
84 | 86 |
85 #ifdef HAVE_IMAGEMAGICK | 87 #ifdef HAVE_IMAGEMAGICK |
86 DEFINE_IMAGE_INSTANTIATOR_FORMAT (imagick); | 88 DEFINE_IMAGE_INSTANTIATOR_FORMAT (imagick); |
87 Lisp_Object Qimagick; | 89 Lisp_Object Qimagick; |
90 | |
91 #ifdef OLDCOMPAT /* old compatibility */ | |
92 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff); | |
93 DEFINE_IMAGE_INSTANTIATOR_FORMAT (png); | |
94 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif); | |
95 DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg); | |
96 Lisp_Object Qtiff; | |
97 Lisp_Object Qpng; | |
98 Lisp_Object Qgif; | |
99 Lisp_Object Qjpeg; | |
100 #endif | |
88 #endif | 101 #endif |
89 | 102 |
90 DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font); | 103 DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font); |
91 Lisp_Object Qcursor_font; | 104 Lisp_Object Qcursor_font; |
92 | 105 |
1678 return IMAGE_COLOR_PIXMAP_MASK; | 1691 return IMAGE_COLOR_PIXMAP_MASK; |
1679 } | 1692 } |
1680 | 1693 |
1681 struct imagick_unwind_data | 1694 struct imagick_unwind_data |
1682 { | 1695 { |
1683 /* FIXME - what goes here...*/ | |
1684 Display *dpy; | 1696 Display *dpy; |
1697 Colormap cmap; | |
1685 FILE *instream; | 1698 FILE *instream; |
1686 Image *image; | 1699 Image *image; |
1687 XImage *ximage; | 1700 XImage *ximage; |
1688 unsigned long *pixels; | 1701 unsigned long *pixels; |
1689 unsigned long npixels; | 1702 unsigned long npixels; |
1705 | 1718 |
1706 if (data->image) { | 1719 if (data->image) { |
1707 DestroyImage(data->image); | 1720 DestroyImage(data->image); |
1708 } | 1721 } |
1709 | 1722 |
1710 if (data->ximage) | 1723 if (data->ximage) { |
1711 { | 1724 if (data->ximage->data) { |
1712 if (data->ximage->data) | |
1713 { | |
1714 xfree (data->ximage->data); | 1725 xfree (data->ximage->data); |
1715 data->ximage->data = NULL; | 1726 data->ximage->data = NULL; |
1716 } | 1727 } |
1717 XDestroyImage (data->ximage); | 1728 XDestroyImage (data->ximage); |
1718 } | 1729 } |
1730 | |
1731 if (data->npixels > 0) { | |
1732 XFreeColors(data->dpy, data->cmap, data->pixels, data->npixels, 0L); | |
1733 xfree (data->pixels); | |
1734 } | |
1719 | 1735 |
1720 return Qnil; | 1736 return Qnil; |
1721 } | 1737 } |
1722 | 1738 |
1723 static void | 1739 static void |
1724 imagick_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 1740 imagick_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
1725 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 1741 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1726 int dest_mask, Lisp_Object domain) | 1742 int dest_mask, Lisp_Object domain) |
1727 { | 1743 { |
1728 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 1744 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
1729 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | 1745 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
1730 Display *dpy; | 1746 Display *dpy; |
1731 Screen *scr; | 1747 Screen *scr; |
1732 Visual *visual; | 1748 Visual *visual; |
1733 Dimension depth; | 1749 Colormap cmap; |
1734 struct imagick_unwind_data unwind; | 1750 Dimension depth; |
1735 int speccount = specpdl_depth (); | 1751 struct imagick_unwind_data unwind; |
1736 ImageInfo image_info; | 1752 int speccount = specpdl_depth (); |
1737 | 1753 ImageInfo image_info; |
1738 /* ImageMagick variables */ | 1754 |
1739 | 1755 /* ImageMagick variables */ |
1740 /* Basic error checking */ | 1756 |
1741 if (!DEVICE_X_P (XDEVICE (device))) | 1757 /* Basic error checking */ |
1742 signal_simple_error ("Not an X device", device); | 1758 if (!DEVICE_X_P (XDEVICE (device))) |
1743 | 1759 signal_simple_error ("Not an X device", device); |
1744 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | 1760 |
1745 scr = DefaultScreenOfDisplay (dpy); | 1761 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); |
1746 depth = DEVICE_X_DEPTH (XDEVICE (device)); | 1762 scr = DefaultScreenOfDisplay (dpy); |
1747 visual = DEVICE_X_VISUAL (XDEVICE (device)); | 1763 depth = DEVICE_X_DEPTH (XDEVICE (device)); |
1748 | 1764 visual = DEVICE_X_VISUAL (XDEVICE (device)); |
1749 /* Set up the unwind */ | 1765 cmap = DEVICE_X_COLORMAP (XDEVICE(device)); |
1750 memset (&unwind, 0, sizeof (unwind)); | 1766 |
1751 unwind.dpy = dpy; | 1767 /* Set up the unwind */ |
1752 record_unwind_protect(imagick_instantiate_unwind,make_opaque_ptr(&unwind)); | 1768 memset (&unwind, 0, sizeof (unwind)); |
1753 | 1769 unwind.dpy = dpy; |
1754 /* Write out to a temp file - not sure if ImageMagick supports the | 1770 unwind.cmap = cmap; |
1755 ** notion of an abstrat 'data source' right now. | 1771 record_unwind_protect(imagick_instantiate_unwind,make_opaque_ptr(&unwind)); |
1756 */ | 1772 |
1773 /* Write out to a temp file - not sure if ImageMagick supports the | |
1774 ** notion of an abstract 'data source' right now. | |
1775 ** JH: It doesn't as of 3.9.3 | |
1776 */ | |
1777 { | |
1778 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1779 | |
1780 assert (!NILP (data)); | |
1781 | |
1782 write_lisp_string_to_temp_file (data, unwind.tempfile); | |
1783 unwind.tempfile_needs_to_be_removed = 1; | |
1784 | |
1785 if ((unwind.instream = fopen (unwind.tempfile, "rb")) == NULL) | |
1786 report_file_error ("Opening ImageMagick temp file", | |
1787 list1 (build_string (unwind.tempfile))); | |
1788 } | |
1789 | |
1790 /* Initialize structures and read in the image */ | |
1791 GetImageInfo(&image_info); | |
1792 strcpy(image_info.filename,unwind.tempfile); | |
1793 unwind.image = ReadImage(&image_info); | |
1794 | |
1795 if (unwind.image == (Image *) NULL) { | |
1796 signal_simple_error ("Unable to read image.",instantiator); | |
1797 } | |
1798 | |
1799 #if 1 | |
1800 /* | |
1801 * For now, force dithering everything, and deal with all images as if they | |
1802 * were PseudoClass images | |
1803 */ | |
1804 if (unwind.image->class != PseudoClass) { | |
1805 QuantizeInfo quantize_info; | |
1806 GetQuantizeInfo(&quantize_info); | |
1807 quantize_info.number_colors=256; | |
1808 quantize_info.tree_depth=8; | |
1809 quantize_info.dither=True; | |
1810 quantize_info.colorspace=RGBColorspace; | |
1811 QuantizeImage(&quantize_info, unwind.image); | |
1812 SyncImage(unwind.image); | |
1813 /* #### It would probably be a good idea to sort the colormap by popularity, | |
1814 * so that in case we run out of entries in the map, it will likely be on | |
1815 * the less used colors | |
1816 */ | |
1817 } else { | |
1818 CompressColormap(unwind.image); | |
1819 SyncImage(unwind.image); | |
1820 } | |
1821 | |
1822 #endif | |
1823 | |
1824 #if 0 | |
1825 DescribeImage(unwind.image,stderr,1); | |
1826 #endif | |
1827 | |
1828 unwind.ximage = XCreateImage(dpy, visual, depth, | |
1829 (depth == 1) ? XYPixmap : ZPixmap, | |
1830 0, 0, | |
1831 unwind.image->columns, | |
1832 unwind.image->rows, | |
1833 XBitmapPad(dpy), 0); | |
1834 | |
1835 if (!unwind.ximage) { | |
1836 signal_simple_error("Unable to allocate XImage structure", | |
1837 instantiator); | |
1838 } | |
1839 | |
1840 unwind.ximage->data = (char *) xmalloc(unwind.ximage->bytes_per_line * | |
1841 unwind.ximage->height); | |
1842 | |
1843 if (unwind.ximage->data == (char *)NULL) { | |
1844 signal_simple_error("Unable to allocate XImage data information", | |
1845 instantiator); | |
1846 } | |
1847 | |
1848 | |
1849 /* | |
1850 ** First pull out all of the colors used, and create a lookup for them | |
1851 */ | |
1852 | |
1853 if (unwind.image->class == PseudoClass) { | |
1854 int i; | |
1855 | |
1856 unwind.npixels = unwind.image->colors; | |
1857 unwind.pixels = xmalloc(unwind.npixels * sizeof(unsigned long)); | |
1858 for (i = 0; i < unwind.npixels; i++) { | |
1859 XColor color; | |
1860 /* ImageMagic uses 8bit values for colors, whilst X expects 16bits */ | |
1861 color.red = unwind.image->colormap[i].red << 8; | |
1862 color.green = unwind.image->colormap[i].green << 8; | |
1863 color.blue = unwind.image->colormap[i].blue << 8; | |
1864 color.flags = DoRed | DoGreen | DoBlue; | |
1865 allocate_nearest_color (dpy, cmap, visual, &color); | |
1866 unwind.pixels[i] = color.pixel; | |
1867 } | |
1868 } | |
1869 | |
1870 /* | |
1871 ** Need to pull the data from the 'Image' structure in | |
1872 ** unwind.image and convert it to an 'XImage' in unwind.ximage | |
1873 */ | |
1874 { | |
1875 int i,j,x,b; | |
1876 unsigned int bytes_per_pixel, scanline_pad; | |
1877 unsigned long pixval; | |
1878 unsigned char *q; | |
1879 RunlengthPacket *p; | |
1880 | |
1881 q = (unsigned char *) unwind.ximage->data; | |
1882 x = 0; | |
1883 p = unwind.image->pixels; | |
1884 scanline_pad = unwind.ximage->bytes_per_line - | |
1885 ((unwind.ximage->width * unwind.ximage->bits_per_pixel) >> 3); | |
1886 | |
1887 /* Convert to multi-byte color-mapped X image. */ | |
1888 bytes_per_pixel=unwind.ximage->bits_per_pixel >> 3; | |
1889 | |
1890 for (i=0; i < unwind.image->packets; i++) { | |
1891 if (unwind.image->class == PseudoClass) | |
1892 pixval = unwind.pixels[p->index]; | |
1893 else | |
1757 { | 1894 { |
1758 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | 1895 /* ### NOW what? */ |
1759 | 1896 pixval = 0; |
1760 assert (!NILP (data)); | |
1761 | |
1762 write_lisp_string_to_temp_file (data, unwind.tempfile); | |
1763 unwind.tempfile_needs_to_be_removed = 1; | |
1764 | |
1765 if ((unwind.instream = fopen (unwind.tempfile, "rb")) == NULL) | |
1766 report_file_error ("Opening ImageMagick temp file", | |
1767 list1 (build_string (unwind.tempfile))); | |
1768 } | 1897 } |
1769 | 1898 |
1770 /* Initialize structures and read in the image */ | 1899 for (j=0; j <= ((int) p->length); j++) { |
1771 GetImageInfo(&image_info); | 1900 for (b=0; b < bytes_per_pixel; b++) |
1772 strcpy(image_info.filename,unwind.tempfile); | 1901 *q++=(unsigned char) (pixval >> (8*b)); |
1773 unwind.image = ReadImage(&image_info); | 1902 x++; |
1774 if (unwind.image == (Image *) NULL) { | 1903 if (x == unwind.ximage->width) { |
1775 signal_simple_error ("Unable to read image.",instantiator); | 1904 x=0; |
1905 q+=scanline_pad; | |
1776 } | 1906 } |
1777 | 1907 } |
1778 #if 1 | 1908 p++; |
1779 DescribeImage(unwind.image,stderr,1); | 1909 } |
1780 #endif | 1910 } |
1781 | 1911 |
1782 unwind.ximage = XCreateImage(dpy, visual, depth, | 1912 init_image_instance_from_x_image (ii, unwind.ximage, dest_mask, |
1783 (depth == 1) ? XYPixmap : ZPixmap, | 1913 unwind.pixels, unwind.npixels, |
1784 0, 0, | 1914 instantiator); |
1785 unwind.image->columns, | 1915 |
1786 unwind.image->rows, | 1916 /* And we are done! |
1787 XBitmapPad(dpy), 0); | 1917 ** Now that we've succeeded, we don't want the pixels |
1788 | 1918 ** freed right now. They're kept around in the image instance |
1789 if (!unwind.ximage) { | 1919 ** structure until it's destroyed. |
1790 signal_simple_error("Unable to allocate XImage structure", | 1920 */ |
1791 instantiator); | 1921 unwind.npixels = 0; |
1792 } | 1922 unbind_to (speccount, Qnil); |
1793 | |
1794 unwind.ximage->data = (char *) xmalloc(unwind.ximage->bytes_per_line * | |
1795 unwind.ximage->height * | |
1796 unwind.ximage->depth); | |
1797 | |
1798 if (unwind.ximage->data == (char *)NULL) { | |
1799 signal_simple_error("Unable to allocate pixel information", | |
1800 instantiator); | |
1801 } | |
1802 | |
1803 /* Need to pull the data from the 'Image' structure in | |
1804 ** unwind.image and convert it to an 'XImage' in unwind.ximage | |
1805 ** | |
1806 ** FIXME IM FUCKED | |
1807 ** | |
1808 ** WMP 10/30/97 | |
1809 */ | |
1810 | |
1811 { | |
1812 int i,j,x; | |
1813 unsigned int bytes_per_pixel, scanline_pad; | |
1814 unsigned char *q; | |
1815 RunlengthPacket *p; | |
1816 XColor color; | |
1817 | |
1818 unwind.npixels = unwind.image->total_colors; | |
1819 unwind.pixels = xmalloc(unwind.npixels * sizeof(unsigned long)); | |
1820 q = (unsigned char *) unwind.ximage->data; | |
1821 x = 0; | |
1822 memset(unwind.pixels,0,unwind.npixels * sizeof(unsigned long)); | |
1823 p = unwind.image->pixels; | |
1824 scanline_pad = unwind.ximage->bytes_per_line - | |
1825 ((unwind.ximage->width * unwind.ximage->bits_per_pixel) >> 3); | |
1826 | |
1827 /* Convert to multi-byte color-mapped X image. */ | |
1828 bytes_per_pixel=unwind.ximage->bits_per_pixel >> 3; | |
1829 | |
1830 #if 1 | |
1831 for (i=0; i < unwind.image->packets; i++) | |
1832 { | |
1833 color.red = p->red; | |
1834 color.green = p->green; | |
1835 color.blue = p->blue; | |
1836 color.flags = DoRed | DoGreen | DoBlue; | |
1837 allocate_nearest_color (dpy, DefaultColormapOfScreen (scr), visual, &color); | |
1838 unwind.pixels[i] = color.pixel; | |
1839 | |
1840 for (j=0; j <= ((int) p->length); j++) | |
1841 { | |
1842 *q++=(unsigned char) color.pixel; | |
1843 x++; | |
1844 if (x == unwind.ximage->width) | |
1845 { | |
1846 x=0; | |
1847 q+=scanline_pad; | |
1848 } | |
1849 } | |
1850 p++; | |
1851 } | |
1852 #else | |
1853 for (i=0; i < unwind.image->packets; i++) | |
1854 { | |
1855 pixel = unwind.pixels[p->index]; | |
1856 for (k=0; k < bytes_per_pixel; k++) | |
1857 { | |
1858 channel[k]=(unsigned char) pixel; | |
1859 pixel>>=8; | |
1860 } | |
1861 for (j=0; j <= ((int) p->length); j++) | |
1862 { | |
1863 for (k=0; k < bytes_per_pixel; k++) | |
1864 *q++=channel[k]; | |
1865 x++; | |
1866 if (x == unwind.ximage->width) | |
1867 { | |
1868 x=0; | |
1869 q+=scanline_pad; | |
1870 } | |
1871 } | |
1872 p++; | |
1873 } | |
1874 #endif | |
1875 } | |
1876 | |
1877 init_image_instance_from_x_image (ii, unwind.ximage, dest_mask, | |
1878 unwind.pixels, unwind.npixels, | |
1879 instantiator); | |
1880 | |
1881 /* And we are done! | |
1882 ** Now that we've succeeded, we don't want the pixels | |
1883 ** freed right now. They're kept around in the image instance | |
1884 ** structure until it's destroyed. | |
1885 */ | |
1886 unwind.npixels = 0; | |
1887 unbind_to (speccount, Qnil); | |
1888 } | 1923 } |
1889 | 1924 |
1890 #endif /* HAVE_IMAGEMAGICK */ | 1925 #endif /* HAVE_IMAGEMAGICK */ |
1891 | 1926 |
1892 | 1927 |
2802 IIFORMAT_HAS_METHOD (imagick, possible_dest_types); | 2837 IIFORMAT_HAS_METHOD (imagick, possible_dest_types); |
2803 IIFORMAT_HAS_METHOD (imagick, instantiate); | 2838 IIFORMAT_HAS_METHOD (imagick, instantiate); |
2804 | 2839 |
2805 IIFORMAT_VALID_KEYWORD (imagick, Q_data, check_valid_string); | 2840 IIFORMAT_VALID_KEYWORD (imagick, Q_data, check_valid_string); |
2806 IIFORMAT_VALID_KEYWORD (imagick, Q_file, check_valid_string); | 2841 IIFORMAT_VALID_KEYWORD (imagick, Q_file, check_valid_string); |
2842 | |
2843 #ifdef OLDCOMPAT /* old graphics compatibility */ | |
2844 #define IIFORMAT_USES_METHOD(format, source, m) \ | |
2845 (format##_image_instantiator_methods->m##_method = source##_##m) | |
2846 | |
2847 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff"); | |
2848 IIFORMAT_USES_METHOD (tiff, imagick, validate); | |
2849 IIFORMAT_USES_METHOD (tiff, imagick, normalize); | |
2850 IIFORMAT_USES_METHOD (tiff, imagick, possible_dest_types); | |
2851 IIFORMAT_USES_METHOD (tiff, imagick, instantiate); | |
2852 IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string); | |
2853 IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string); | |
2854 | |
2855 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png"); | |
2856 IIFORMAT_USES_METHOD (png, imagick, validate); | |
2857 IIFORMAT_USES_METHOD (png, imagick, normalize); | |
2858 IIFORMAT_USES_METHOD (png, imagick, possible_dest_types); | |
2859 IIFORMAT_USES_METHOD (png, imagick, instantiate); | |
2860 IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string); | |
2861 IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string); | |
2862 | |
2863 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif"); | |
2864 IIFORMAT_USES_METHOD (gif, imagick, validate); | |
2865 IIFORMAT_USES_METHOD (gif, imagick, normalize); | |
2866 IIFORMAT_USES_METHOD (gif, imagick, possible_dest_types); | |
2867 IIFORMAT_USES_METHOD (gif, imagick, instantiate); | |
2868 IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string); | |
2869 IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string); | |
2870 | |
2871 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg"); | |
2872 IIFORMAT_USES_METHOD (jpeg, imagick, validate); | |
2873 IIFORMAT_USES_METHOD (jpeg, imagick, normalize); | |
2874 IIFORMAT_USES_METHOD (jpeg, imagick, possible_dest_types); | |
2875 IIFORMAT_USES_METHOD (jpeg, imagick, instantiate); | |
2876 IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string); | |
2877 IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string); | |
2878 | |
2879 #endif /* old compat */ | |
2880 | |
2807 #endif | 2881 #endif |
2808 | 2882 |
2809 #ifdef HAVE_XPM | 2883 #ifdef HAVE_XPM |
2810 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xpm, "xpm"); | 2884 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xpm, "xpm"); |
2811 | 2885 |
2866 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */ | 2940 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */ |
2867 #endif | 2941 #endif |
2868 | 2942 |
2869 #ifdef HAVE_IMAGEMAGICK | 2943 #ifdef HAVE_IMAGEMAGICK |
2870 Fprovide (Qimagick); | 2944 Fprovide (Qimagick); |
2945 | |
2946 #ifdef OLDCOMPAT | |
2947 Fprovide (Qtiff); | |
2948 Fprovide (Qpng); | |
2949 Fprovide (Qgif); | |
2950 Fprovide (Qjpeg); | |
2951 #endif | |
2871 #endif | 2952 #endif |
2872 | 2953 |
2873 #ifdef HAVE_XFACE | 2954 #ifdef HAVE_XFACE |
2874 Fprovide (Qxface); | 2955 Fprovide (Qxface); |
2875 #endif | 2956 #endif |