comparison src/glyphs.c @ 272:c5d627a313b1 r21-0b34

Import from CVS: tag r21-0b34
author cvs
date Mon, 13 Aug 2007 10:28:48 +0200
parents b2472a1930f2
children 6330739388db
comparison
equal deleted inserted replaced
271:c7b7086b0a39 272:c5d627a313b1
39 #include "window.h" 39 #include "window.h"
40 40
41 Lisp_Object Qimage_conversion_error; 41 Lisp_Object Qimage_conversion_error;
42 42
43 Lisp_Object Qglyphp, Qcontrib_p, Qbaseline; 43 Lisp_Object Qglyphp, Qcontrib_p, Qbaseline;
44
45 Lisp_Object Qbuffer_glyph_p, Qpointer_glyph_p, Qicon_glyph_p; 44 Lisp_Object Qbuffer_glyph_p, Qpointer_glyph_p, Qicon_glyph_p;
46
47 Lisp_Object Qnothing_image_instance_p, Qtext_image_instance_p; 45 Lisp_Object Qnothing_image_instance_p, Qtext_image_instance_p;
48 Lisp_Object Qmono_pixmap_image_instance_p; 46 Lisp_Object Qmono_pixmap_image_instance_p;
49 Lisp_Object Qcolor_pixmap_image_instance_p; 47 Lisp_Object Qcolor_pixmap_image_instance_p;
50 Lisp_Object Qpointer_image_instance_p; 48 Lisp_Object Qpointer_image_instance_p;
51 Lisp_Object Qsubwindow_image_instance_p; 49 Lisp_Object Qsubwindow_image_instance_p;
52
53 Lisp_Object Qconst_glyph_variable; 50 Lisp_Object Qconst_glyph_variable;
54
55 /* Qtext, Qpointer defined in general.c */
56 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow; 51 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow;
52 Lisp_Object Q_file, Q_data, Q_face;
53 Lisp_Object Qicon;
54 Lisp_Object Qformatted_string;
57 55
58 Lisp_Object Vcurrent_display_table; 56 Lisp_Object Vcurrent_display_table;
59 /* Declared in faces.c */
60 extern Lisp_Object Qdisplay_table;
61
62 Lisp_Object Vtruncation_glyph, Vcontinuation_glyph, Voctal_escape_glyph; 57 Lisp_Object Vtruncation_glyph, Vcontinuation_glyph, Voctal_escape_glyph;
63 Lisp_Object Vcontrol_arrow_glyph, Vinvisible_text_glyph, Vhscroll_glyph; 58 Lisp_Object Vcontrol_arrow_glyph, Vinvisible_text_glyph, Vhscroll_glyph;
64 Lisp_Object Vxemacs_logo; 59 Lisp_Object Vxemacs_logo;
65
66 Lisp_Object Vthe_nothing_vector; 60 Lisp_Object Vthe_nothing_vector;
67 61 Lisp_Object Vimage_instantiator_format_list;
68 Lisp_Object Q_file, Q_data, Q_face; 62 Lisp_Object Vimage_instance_type_list;
69 63 Lisp_Object Vglyph_type_list;
70 Lisp_Object Qicon; 64
71
72 /* Qnothing, Qstring, Qinherit in general.c */
73 DEFINE_IMAGE_INSTANTIATOR_FORMAT (nothing); 65 DEFINE_IMAGE_INSTANTIATOR_FORMAT (nothing);
74 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit); 66 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit);
75 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string); 67 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string);
76 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); 68 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
77 Lisp_Object Qformatted_string;
78
79 MAC_DEFINE (struct image_instantiator_methods *, MTiiformat_meth_or_given)
80 69
81 typedef struct image_instantiator_format_entry image_instantiator_format_entry; 70 typedef struct image_instantiator_format_entry image_instantiator_format_entry;
82 struct image_instantiator_format_entry 71 struct image_instantiator_format_entry
83 { 72 {
84 Lisp_Object symbol; 73 Lisp_Object symbol;
90 Dynarr_declare (struct image_instantiator_format_entry); 79 Dynarr_declare (struct image_instantiator_format_entry);
91 } image_instantiator_format_entry_dynarr; 80 } image_instantiator_format_entry_dynarr;
92 81
93 image_instantiator_format_entry_dynarr * 82 image_instantiator_format_entry_dynarr *
94 the_image_instantiator_format_entry_dynarr; 83 the_image_instantiator_format_entry_dynarr;
95
96 Lisp_Object Vimage_instantiator_format_list;
97
98 Lisp_Object Vimage_instance_type_list;
99
100 Lisp_Object Vglyph_type_list;
101 84
102 static Lisp_Object allocate_image_instance (Lisp_Object device); 85 static Lisp_Object allocate_image_instance (Lisp_Object device);
103 static void image_validate (Lisp_Object instantiator); 86 static void image_validate (Lisp_Object instantiator);
104 static void glyph_property_was_changed (Lisp_Object glyph, 87 static void glyph_property_was_changed (Lisp_Object glyph,
105 Lisp_Object property, 88 Lisp_Object property,
106 Lisp_Object locale); 89 Lisp_Object locale);
90 EXFUN (Fimage_instance_type, 1);
91 EXFUN (Fglyph_type, 1);
107 92
108 93
109 /**************************************************************************** 94 /****************************************************************************
110 * Image Instantiators * 95 * Image Instantiators *
111 ****************************************************************************/ 96 ****************************************************************************/
138 } 123 }
139 124
140 static int 125 static int
141 valid_image_instantiator_format_p (Lisp_Object format) 126 valid_image_instantiator_format_p (Lisp_Object format)
142 { 127 {
143 if (decode_image_instantiator_format (format, ERROR_ME_NOT)) 128 return (decode_image_instantiator_format (format, ERROR_ME_NOT) != 0);
144 return 1;
145 return 0;
146 } 129 }
147 130
148 DEFUN ("valid-image-instantiator-format-p", 131 DEFUN ("valid-image-instantiator-format-p",
149 Fvalid_image_instantiator_format_p, 1, 1, 0, /* 132 Fvalid_image_instantiator_format_p, 1, 1, 0, /*
150 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid. 133 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid.
151 Valid formats are some subset of 'nothing, 'string, 'formatted-string, 134 Valid formats are some subset of 'nothing, 'string, 'formatted-string,
152 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font, 135 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font,
153 'autodetect, and 'subwindow, depending on how XEmacs was 136 'autodetect, and 'subwindow, depending on how XEmacs was compiled.
154 compiled.
155 */ 137 */
156 (image_instantiator_format)) 138 (image_instantiator_format))
157 { 139 {
158 if (valid_image_instantiator_format_p (image_instantiator_format)) 140 return valid_image_instantiator_format_p (image_instantiator_format) ?
159 return Qt; 141 Qt : Qnil;
160 else
161 return Qnil;
162 } 142 }
163 143
164 DEFUN ("image-instantiator-format-list", 144 DEFUN ("image-instantiator-format-list",
165 Fimage_instantiator_format_list, 0, 0, 0, /* 145 Fimage_instantiator_format_list, 0, 0, 0, /*
166 Return a list of valid image-instantiator formats. 146 Return a list of valid image-instantiator formats.
474 filename even though this is a potential memory pig. We have to 454 filename even though this is a potential memory pig. We have to
475 do this because it is quite possible that we will need to 455 do this because it is quite possible that we will need to
476 instantiate a new instance of the pixmap and the file will no 456 instantiate a new instance of the pixmap and the file will no
477 longer exist (e.g. w3 pixmaps are almost always from temporary 457 longer exist (e.g. w3 pixmaps are almost always from temporary
478 files). */ 458 files). */
479 instantiator = IIFORMAT_METH_OR_GIVEN 459 {
480 (decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], 460 struct image_instantiator_methods * meths =
481 ERROR_ME), 461 decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
482 normalize, (instantiator, contype), instantiator); 462 ERROR_ME);
483 463 return IIFORMAT_METH_OR_GIVEN (meths, normalize,
484 return instantiator; 464 (instantiator, contype),
465 instantiator);
466 }
485 } 467 }
486 468
487 static Lisp_Object 469 static Lisp_Object
488 instantiate_image_instantiator (Lisp_Object device, Lisp_Object domain, 470 instantiate_image_instantiator (Lisp_Object device, Lisp_Object domain,
489 Lisp_Object instantiator, 471 Lisp_Object instantiator,
490 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 472 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
491 int dest_mask) 473 int dest_mask)
492 { 474 {
493 Lisp_Object ii; 475 Lisp_Object ii = allocate_image_instance (device);
476 struct image_instantiator_methods *meths;
494 struct gcpro gcpro1; 477 struct gcpro gcpro1;
495 478
496 ii = allocate_image_instance (device);
497
498 GCPRO1 (ii); 479 GCPRO1 (ii);
499 { 480 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
500 struct image_instantiator_methods *meths = 481 ERROR_ME);
501 decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], 482 if (!HAS_IIFORMAT_METH_P (meths, instantiate))
502 ERROR_ME); 483 signal_simple_error
503 484 ("Don't know how to instantiate this image instantiator?",
504 if (!HAS_IIFORMAT_METH_P (meths, instantiate)) 485 instantiator);
505 signal_simple_error 486 IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
506 ("Don't know how to instantiate this image instantiator?", 487 pointer_bg, dest_mask, domain));
507 instantiator);
508 IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
509 pointer_bg, dest_mask, domain));
510 }
511 UNGCPRO; 488 UNGCPRO;
512 489
513 return ii; 490 return ii;
514 } 491 }
515 492
517 /**************************************************************************** 494 /****************************************************************************
518 * Image-Instance Object * 495 * Image-Instance Object *
519 ****************************************************************************/ 496 ****************************************************************************/
520 497
521 Lisp_Object Qimage_instancep; 498 Lisp_Object Qimage_instancep;
522 static Lisp_Object mark_image_instance (Lisp_Object, void (*) (Lisp_Object)); 499
523 static void print_image_instance (Lisp_Object, Lisp_Object, int);
524 static void finalize_image_instance (void *, int);
525 static int image_instance_equal (Lisp_Object o1, Lisp_Object o2, int depth);
526 static unsigned long image_instance_hash (Lisp_Object obj, int depth);
527 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance,
528 mark_image_instance, print_image_instance,
529 finalize_image_instance, image_instance_equal,
530 image_instance_hash,
531 struct Lisp_Image_Instance);
532 static Lisp_Object 500 static Lisp_Object
533 mark_image_instance (Lisp_Object obj, void (*markobj) (Lisp_Object)) 501 mark_image_instance (Lisp_Object obj, void (*markobj) (Lisp_Object))
534 { 502 {
535 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); 503 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj);
536 504
780 748
781 return HASH2 (hash, DEVMETH_OR_GIVEN (d, image_instance_hash, (i, depth), 749 return HASH2 (hash, DEVMETH_OR_GIVEN (d, image_instance_hash, (i, depth),
782 0)); 750 0));
783 } 751 }
784 752
753 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance,
754 mark_image_instance, print_image_instance,
755 finalize_image_instance, image_instance_equal,
756 image_instance_hash,
757 struct Lisp_Image_Instance);
758
785 static Lisp_Object 759 static Lisp_Object
786 allocate_image_instance (Lisp_Object device) 760 allocate_image_instance (Lisp_Object device)
787 { 761 {
788 struct Lisp_Image_Instance *lp = 762 struct Lisp_Image_Instance *lp =
789 alloc_lcrecord_type (struct Lisp_Image_Instance, lrecord_image_instance); 763 alloc_lcrecord_type (struct Lisp_Image_Instance, lrecord_image_instance);
790 Lisp_Object val = Qnil; 764 Lisp_Object val;
791 765
792 zero_lcrecord (lp); 766 zero_lcrecord (lp);
793 lp->device = device; 767 lp->device = device;
794 lp->type = IMAGE_NOTHING; 768 lp->type = IMAGE_NOTHING;
795 lp->name = Qnil; 769 lp->name = Qnil;
974 Qnil, Qnil, dest_mask); 948 Qnil, Qnil, dest_mask);
975 RETURN_UNGCPRO (ii); 949 RETURN_UNGCPRO (ii);
976 } 950 }
977 951
978 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /* 952 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /*
979 Create a new `image-instance' object. 953 Return a new `image-instance' object.
980 954
981 Image-instance objects encapsulate the way a particular image (pixmap, 955 Image-instance objects encapsulate the way a particular image (pixmap,
982 etc.) is displayed on a particular device. In most circumstances, you 956 etc.) is displayed on a particular device. In most circumstances, you
983 do not need to directly create image instances; use a glyph instead. 957 do not need to directly create image instances; use a glyph instead.
984 However, it may occasionally be useful to explicitly create image 958 However, it may occasionally be useful to explicitly create image
1466 } 1440 }
1467 1441
1468 static Lisp_Object 1442 static Lisp_Object
1469 image_instantiate_cache_result (Lisp_Object locative) 1443 image_instantiate_cache_result (Lisp_Object locative)
1470 { 1444 {
1471 Lisp_Object instance = Fcar (locative); 1445 /* locative = (instance instantiator . subtable) */
1472 Lisp_Object instantiator = Fcar (Fcdr (locative)); 1446 Fputhash (XCAR (XCDR (locative)), XCAR (locative), XCDR (XCDR (locative)));
1473 Lisp_Object subtable = Fcdr (Fcdr (locative));
1474 Fputhash (instantiator, instance, subtable);
1475 free_cons (XCONS (XCDR (locative))); 1447 free_cons (XCONS (XCDR (locative)));
1476 free_cons (XCONS (locative)); 1448 free_cons (XCONS (locative));
1477 return Qnil; 1449 return Qnil;
1478 } 1450 }
1479 1451
1716 1688
1717 GCPRO2 (retlist, possible_console_types); 1689 GCPRO2 (retlist, possible_console_types);
1718 1690
1719 LIST_LOOP (rest, possible_console_types) 1691 LIST_LOOP (rest, possible_console_types)
1720 { 1692 {
1721 Lisp_Object newinst;
1722 Lisp_Object contype = XCAR (rest); 1693 Lisp_Object contype = XCAR (rest);
1723 1694 Lisp_Object newinst = call_with_suspended_errors
1724 newinst = call_with_suspended_errors
1725 ((lisp_fn_t) normalize_image_instantiator, 1695 ((lisp_fn_t) normalize_image_instantiator,
1726 Qnil, Qimage, ERROR_ME_NOT, 3, instantiator, contype, 1696 Qnil, Qimage, ERROR_ME_NOT, 3, instantiator, contype,
1727 make_int (XIMAGE_SPECIFIER_ALLOWED (specifier))); 1697 make_int (XIMAGE_SPECIFIER_ALLOWED (specifier)));
1728 1698
1729 if (!NILP (newinst)) 1699 if (!NILP (newinst))
1911 1881
1912 /**************************************************************************** 1882 /****************************************************************************
1913 * Glyph Object * 1883 * Glyph Object *
1914 ****************************************************************************/ 1884 ****************************************************************************/
1915 1885
1916 static Lisp_Object mark_glyph (Lisp_Object, void (*) (Lisp_Object)); 1886 static Lisp_Object
1917 static void print_glyph (Lisp_Object, Lisp_Object, int); 1887 mark_glyph (Lisp_Object obj, void (*markobj) (Lisp_Object))
1918 static int glyph_equal (Lisp_Object, Lisp_Object, int depth); 1888 {
1919 static unsigned long glyph_hash (Lisp_Object obj, int depth); 1889 struct Lisp_Glyph *glyph = XGLYPH (obj);
1920 static Lisp_Object glyph_getprop (Lisp_Object obj, Lisp_Object prop); 1890
1921 static int glyph_putprop (Lisp_Object obj, Lisp_Object prop, 1891 ((markobj) (glyph->image));
1922 Lisp_Object value); 1892 ((markobj) (glyph->contrib_p));
1923 static int glyph_remprop (Lisp_Object obj, Lisp_Object prop); 1893 ((markobj) (glyph->baseline));
1924 static Lisp_Object glyph_plist (Lisp_Object obj); 1894 ((markobj) (glyph->face));
1895
1896 return glyph->plist;
1897 }
1898
1899 static void
1900 print_glyph (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1901 {
1902 struct Lisp_Glyph *glyph = XGLYPH (obj);
1903 char buf[20];
1904
1905 if (print_readably)
1906 error ("printing unreadable object #<glyph 0x%x>", glyph->header.uid);
1907
1908 write_c_string ("#<glyph (", printcharfun);
1909 print_internal (Fglyph_type (obj), printcharfun, 0);
1910 write_c_string (") ", printcharfun);
1911 print_internal (glyph->image, printcharfun, 1);
1912 sprintf (buf, "0x%x>", glyph->header.uid);
1913 write_c_string (buf, printcharfun);
1914 }
1915
1916 /* Glyphs are equal if all of their display attributes are equal. We
1917 don't compare names or doc-strings, because that would make equal
1918 be eq.
1919
1920 This isn't concerned with "unspecified" attributes, that's what
1921 #'glyph-differs-from-default-p is for. */
1922 static int
1923 glyph_equal (Lisp_Object o1, Lisp_Object o2, int depth)
1924 {
1925 struct Lisp_Glyph *g1 = XGLYPH (o1);
1926 struct Lisp_Glyph *g2 = XGLYPH (o2);
1927
1928 depth++;
1929
1930 return (internal_equal (g1->image, g2->image, depth) &&
1931 internal_equal (g1->contrib_p, g2->contrib_p, depth) &&
1932 internal_equal (g1->baseline, g2->baseline, depth) &&
1933 internal_equal (g1->face, g2->face, depth) &&
1934 !plists_differ (g1->plist, g2->plist, 0, 0, depth + 1));
1935 }
1936
1937 static unsigned long
1938 glyph_hash (Lisp_Object obj, int depth)
1939 {
1940 depth++;
1941
1942 /* No need to hash all of the elements; that would take too long.
1943 Just hash the most common ones. */
1944 return HASH2 (internal_hash (XGLYPH (obj)->image, depth),
1945 internal_hash (XGLYPH (obj)->face, depth));
1946 }
1947
1948 static Lisp_Object
1949 glyph_getprop (Lisp_Object obj, Lisp_Object prop)
1950 {
1951 struct Lisp_Glyph *g = XGLYPH (obj);
1952
1953 if (EQ (prop, Qimage)) return g->image;
1954 if (EQ (prop, Qcontrib_p)) return g->contrib_p;
1955 if (EQ (prop, Qbaseline)) return g->baseline;
1956 if (EQ (prop, Qface)) return g->face;
1957
1958 return external_plist_get (&g->plist, prop, 0, ERROR_ME);
1959 }
1960
1961 static int
1962 glyph_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value)
1963 {
1964 if ((EQ (prop, Qimage)) ||
1965 (EQ (prop, Qcontrib_p)) ||
1966 (EQ (prop, Qbaseline)))
1967 return 0;
1968
1969 if (EQ (prop, Qface))
1970 {
1971 XGLYPH (obj)->face = Fget_face (value);
1972 return 1;
1973 }
1974
1975 external_plist_put (&XGLYPH (obj)->plist, prop, value, 0, ERROR_ME);
1976 return 1;
1977 }
1978
1979 static int
1980 glyph_remprop (Lisp_Object obj, Lisp_Object prop)
1981 {
1982 if ((EQ (prop, Qimage)) ||
1983 (EQ (prop, Qcontrib_p)) ||
1984 (EQ (prop, Qbaseline)))
1985 return -1;
1986
1987 if (EQ (prop, Qface))
1988 {
1989 XGLYPH (obj)->face = Qnil;
1990 return 1;
1991 }
1992
1993 return external_remprop (&XGLYPH (obj)->plist, prop, 0, ERROR_ME);
1994 }
1995
1996 static Lisp_Object
1997 glyph_plist (Lisp_Object obj)
1998 {
1999 struct Lisp_Glyph *glyph = XGLYPH (obj);
2000 Lisp_Object result = glyph->plist;
2001
2002 result = cons3 (Qface, glyph->face, result);
2003 result = cons3 (Qbaseline, glyph->baseline, result);
2004 result = cons3 (Qcontrib_p, glyph->contrib_p, result);
2005 result = cons3 (Qimage, glyph->image, result);
2006
2007 return result;
2008 }
2009
1925 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("glyph", glyph, 2010 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("glyph", glyph,
1926 mark_glyph, print_glyph, 0, 2011 mark_glyph, print_glyph, 0,
1927 glyph_equal, glyph_hash, 2012 glyph_equal, glyph_hash,
1928 glyph_getprop, glyph_putprop, 2013 glyph_getprop, glyph_putprop,
1929 glyph_remprop, glyph_plist, 2014 glyph_remprop, glyph_plist,
1930 struct Lisp_Glyph); 2015 struct Lisp_Glyph);
1931 2016
1932 static Lisp_Object
1933 mark_glyph (Lisp_Object obj, void (*markobj) (Lisp_Object))
1934 {
1935 struct Lisp_Glyph *glyph = XGLYPH (obj);
1936
1937 ((markobj) (glyph->image));
1938 ((markobj) (glyph->contrib_p));
1939 ((markobj) (glyph->baseline));
1940 ((markobj) (glyph->face));
1941
1942 return glyph->plist;
1943 }
1944
1945 static void
1946 print_glyph (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1947 {
1948 struct Lisp_Glyph *glyph = XGLYPH (obj);
1949 char buf[20];
1950
1951 if (print_readably)
1952 error ("printing unreadable object #<glyph 0x%x>", glyph->header.uid);
1953
1954 write_c_string ("#<glyph (", printcharfun);
1955 print_internal (Fglyph_type (obj), printcharfun, 0);
1956 write_c_string (") ", printcharfun);
1957 print_internal (glyph->image, printcharfun, 1);
1958 sprintf (buf, "0x%x>", glyph->header.uid);
1959 write_c_string (buf, printcharfun);
1960 }
1961
1962 /* Glyphs are equal if all of their display attributes are equal. We
1963 don't compare names or doc-strings, because that would make equal
1964 be eq.
1965
1966 This isn't concerned with "unspecified" attributes, that's what
1967 #'glyph-differs-from-default-p is for. */
1968 static int
1969 glyph_equal (Lisp_Object o1, Lisp_Object o2, int depth)
1970 {
1971 struct Lisp_Glyph *g1 = XGLYPH (o1);
1972 struct Lisp_Glyph *g2 = XGLYPH (o2);
1973
1974 depth++;
1975
1976 return (internal_equal (g1->image, g2->image, depth) &&
1977 internal_equal (g1->contrib_p, g2->contrib_p, depth) &&
1978 internal_equal (g1->baseline, g2->baseline, depth) &&
1979 internal_equal (g1->face, g2->face, depth) &&
1980 !plists_differ (g1->plist, g2->plist, 0, 0, depth + 1));
1981 }
1982
1983 static unsigned long
1984 glyph_hash (Lisp_Object obj, int depth)
1985 {
1986 depth++;
1987
1988 /* No need to hash all of the elements; that would take too long.
1989 Just hash the most common ones. */
1990 return HASH2 (internal_hash (XGLYPH (obj)->image, depth),
1991 internal_hash (XGLYPH (obj)->face, depth));
1992 }
1993
1994 static Lisp_Object
1995 glyph_getprop (Lisp_Object obj, Lisp_Object prop)
1996 {
1997 struct Lisp_Glyph *g = XGLYPH (obj);
1998
1999 if (EQ (prop, Qimage)) return g->image;
2000 if (EQ (prop, Qcontrib_p)) return g->contrib_p;
2001 if (EQ (prop, Qbaseline)) return g->baseline;
2002 if (EQ (prop, Qface)) return g->face;
2003
2004 return external_plist_get (&g->plist, prop, 0, ERROR_ME);
2005 }
2006
2007 static int
2008 glyph_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value)
2009 {
2010 if ((EQ (prop, Qimage)) ||
2011 (EQ (prop, Qcontrib_p)) ||
2012 (EQ (prop, Qbaseline)))
2013 return 0;
2014
2015 if (EQ (prop, Qface))
2016 {
2017 XGLYPH (obj)->face = Fget_face (value);
2018 return 1;
2019 }
2020
2021 external_plist_put (&XGLYPH (obj)->plist, prop, value, 0, ERROR_ME);
2022 return 1;
2023 }
2024
2025 static int
2026 glyph_remprop (Lisp_Object obj, Lisp_Object prop)
2027 {
2028 if ((EQ (prop, Qimage)) ||
2029 (EQ (prop, Qcontrib_p)) ||
2030 (EQ (prop, Qbaseline)))
2031 return -1;
2032
2033 if (EQ (prop, Qface))
2034 {
2035 XGLYPH (obj)->face = Qnil;
2036 return 1;
2037 }
2038
2039 return external_remprop (&XGLYPH (obj)->plist, prop, 0, ERROR_ME);
2040 }
2041
2042 static Lisp_Object
2043 glyph_plist (Lisp_Object obj)
2044 {
2045 struct Lisp_Glyph *g = XGLYPH (obj);
2046 Lisp_Object result = Qnil;
2047
2048 /* backwards order; we reverse it below */
2049 result = Fcons (g->image, Fcons (Qimage, result));
2050 result = Fcons (g->contrib_p, Fcons (Qcontrib_p, result));
2051 result = Fcons (g->baseline, Fcons (Qbaseline, result));
2052 result = Fcons (g->face, Fcons (Qface, result));
2053
2054 return nconc2 (Fnreverse (result), g->plist);
2055 }
2056
2057 Lisp_Object 2017 Lisp_Object
2058 allocate_glyph (enum glyph_type type, 2018 allocate_glyph (enum glyph_type type,
2059 void (*after_change) (Lisp_Object glyph, Lisp_Object property, 2019 void (*after_change) (Lisp_Object glyph, Lisp_Object property,
2060 Lisp_Object locale)) 2020 Lisp_Object locale))
2061 { 2021 {
2154 { 2114 {
2155 return Fcopy_sequence (Vglyph_type_list); 2115 return Fcopy_sequence (Vglyph_type_list);
2156 } 2116 }
2157 2117
2158 DEFUN ("make-glyph-internal", Fmake_glyph_internal, 0, 1, 0, /* 2118 DEFUN ("make-glyph-internal", Fmake_glyph_internal, 0, 1, 0, /*
2159 Create a new, uninitialized glyph. 2119 Create and return a new uninitialized glyph or type TYPE.
2160 2120
2161 TYPE specifies the type of the glyph; this should be one of `buffer', 2121 TYPE specifies the type of the glyph; this should be one of `buffer',
2162 `pointer', or `icon', and defaults to `buffer'. The type of the glyph 2122 `pointer', or `icon', and defaults to `buffer'. The type of the glyph
2163 specifies in which contexts the glyph can be used, and controls the 2123 specifies in which contexts the glyph can be used, and controls the
2164 allowable image types into which the glyph's image can be 2124 allowable image types into which the glyph's image can be
2537 struct glyph_cachel *cachel) 2497 struct glyph_cachel *cachel)
2538 { 2498 {
2539 /* #### This should be || !cachel->updated */ 2499 /* #### This should be || !cachel->updated */
2540 if (NILP (cachel->glyph) || !EQ (cachel->glyph, glyph)) 2500 if (NILP (cachel->glyph) || !EQ (cachel->glyph, glyph))
2541 { 2501 {
2542 Lisp_Object window = Qnil; 2502 Lisp_Object window;
2543 2503
2544 XSETWINDOW (window, w); 2504 XSETWINDOW (window, w);
2545 2505
2546 /* #### This could be sped up if we redid things to grab the glyph 2506 /* #### This could be sped up if we redid things to grab the glyph
2547 instantiation and passed it to the size functions. */ 2507 instantiation and passed it to the size functions. */
2557 static void 2517 static void
2558 add_glyph_cachel (struct window *w, Lisp_Object glyph) 2518 add_glyph_cachel (struct window *w, Lisp_Object glyph)
2559 { 2519 {
2560 struct glyph_cachel new_cachel; 2520 struct glyph_cachel new_cachel;
2561 2521
2562 memset (&new_cachel, 0, sizeof (struct glyph_cachel)); 2522 xzero (new_cachel);
2563 new_cachel.glyph = Qnil; 2523 new_cachel.glyph = Qnil;
2564 2524
2565 update_glyph_cachel_data (w, glyph, &new_cachel); 2525 update_glyph_cachel_data (w, glyph, &new_cachel);
2566 Dynarr_add (w->glyph_cachels, new_cachel); 2526 Dynarr_add (w->glyph_cachels, new_cachel);
2567 } 2527 }
2659 if no valid table is specified, return 0. */ 2619 if no valid table is specified, return 0. */
2660 2620
2661 struct Lisp_Vector * 2621 struct Lisp_Vector *
2662 get_display_table (struct window *w, face_index findex) 2622 get_display_table (struct window *w, face_index findex)
2663 { 2623 {
2664 Lisp_Object tem = Qnil; 2624 Lisp_Object tem;
2665 2625
2666 tem = WINDOW_FACE_CACHEL_DISPLAY_TABLE (w, findex); 2626 tem = WINDOW_FACE_CACHEL_DISPLAY_TABLE (w, findex);
2667 if (VECTORP (tem) && XVECTOR_LENGTH (tem) == DISP_TABLE_SIZE) 2627 if (VECTORP (tem) && XVECTOR_LENGTH (tem) == DISP_TABLE_SIZE)
2668 return XVECTOR (tem); 2628 return XVECTOR (tem);
2669 2629