Mercurial > hg > xemacs-beta
comparison src/glyphs.c @ 438:84b14dcb0985 r21-2-27
Import from CVS: tag r21-2-27
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:32:25 +0200 |
parents | 9d177e8d4150 |
children | 8de8e3f6228a |
comparison
equal
deleted
inserted
replaced
437:e2a4e8b94b82 | 438:84b14dcb0985 |
---|---|
1 /* Generic glyph/image implementation + display tables | 1 /* Generic glyph/image implementation + display tables |
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. | 2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. |
3 Copyright (C) 1995 Tinker Systems | 3 Copyright (C) 1995 Tinker Systems |
4 Copyright (C) 1995, 1996 Ben Wing | 4 Copyright (C) 1995, 1996 Ben Wing |
5 Copyright (C) 1995 Sun Microsystems | 5 Copyright (C) 1995 Sun Microsystems |
6 Copyright (C) 1998, 1999 Andy Piper | 6 Copyright (C) 1998, 1999, 2000 Andy Piper |
7 | 7 |
8 This file is part of XEmacs. | 8 This file is part of XEmacs. |
9 | 9 |
10 XEmacs is free software; you can redistribute it and/or modify it | 10 XEmacs is free software; you can redistribute it and/or modify it |
11 under the terms of the GNU General Public License as published by the | 11 under the terms of the GNU General Public License as published by the |
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
23 Boston, MA 02111-1307, USA. */ | 23 Boston, MA 02111-1307, USA. */ |
24 | 24 |
25 /* Synched up with: Not in FSF. */ | 25 /* Synched up with: Not in FSF. */ |
26 | 26 |
27 /* Written by Ben Wing and Chuck Thompson. */ | 27 /* Written by Ben Wing and Chuck Thompson. Heavily modified / |
28 rewritten by Andy Piper. */ | |
28 | 29 |
29 #include <config.h> | 30 #include <config.h> |
30 #include "lisp.h" | 31 #include "lisp.h" |
31 | 32 |
32 #include "buffer.h" | 33 #include "buffer.h" |
120 } image_instantiator_format_entry_dynarr; | 121 } image_instantiator_format_entry_dynarr; |
121 | 122 |
122 image_instantiator_format_entry_dynarr * | 123 image_instantiator_format_entry_dynarr * |
123 the_image_instantiator_format_entry_dynarr; | 124 the_image_instantiator_format_entry_dynarr; |
124 | 125 |
125 static Lisp_Object allocate_image_instance (Lisp_Object device); | 126 static Lisp_Object allocate_image_instance (Lisp_Object device, Lisp_Object glyph); |
126 static void image_validate (Lisp_Object instantiator); | 127 static void image_validate (Lisp_Object instantiator); |
127 static void glyph_property_was_changed (Lisp_Object glyph, | 128 static void glyph_property_was_changed (Lisp_Object glyph, |
128 Lisp_Object property, | 129 Lisp_Object property, |
129 Lisp_Object locale); | 130 Lisp_Object locale); |
130 static void register_ignored_expose (struct frame* f, int x, int y, int width, int height); | 131 static void register_ignored_expose (struct frame* f, int x, int y, int width, int height); |
573 | 574 |
574 static Lisp_Object | 575 static Lisp_Object |
575 instantiate_image_instantiator (Lisp_Object device, Lisp_Object domain, | 576 instantiate_image_instantiator (Lisp_Object device, Lisp_Object domain, |
576 Lisp_Object instantiator, | 577 Lisp_Object instantiator, |
577 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 578 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
578 int dest_mask) | 579 int dest_mask, Lisp_Object glyph) |
579 { | 580 { |
580 Lisp_Object ii = allocate_image_instance (device); | 581 Lisp_Object ii = allocate_image_instance (device, glyph); |
581 struct image_instantiator_methods *meths; | 582 struct image_instantiator_methods *meths; |
582 struct gcpro gcpro1; | 583 struct gcpro gcpro1; |
583 int methp = 0; | 584 int methp = 0; |
584 | 585 |
585 GCPRO1 (ii); | 586 GCPRO1 (ii); |
620 mark_image_instance (Lisp_Object obj) | 621 mark_image_instance (Lisp_Object obj) |
621 { | 622 { |
622 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); | 623 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); |
623 | 624 |
624 mark_object (i->name); | 625 mark_object (i->name); |
626 /* We don't mark the glyph reference since that would create a | |
627 circularity preventing GC. */ | |
625 switch (IMAGE_INSTANCE_TYPE (i)) | 628 switch (IMAGE_INSTANCE_TYPE (i)) |
626 { | 629 { |
627 case IMAGE_TEXT: | 630 case IMAGE_TEXT: |
628 mark_object (IMAGE_INSTANCE_TEXT_STRING (i)); | 631 mark_object (IMAGE_INSTANCE_TEXT_STRING (i)); |
629 break; | 632 break; |
752 write_c_string (")", printcharfun); | 755 write_c_string (")", printcharfun); |
753 } | 756 } |
754 break; | 757 break; |
755 | 758 |
756 case IMAGE_WIDGET: | 759 case IMAGE_WIDGET: |
757 /* | |
758 if (!NILP (IMAGE_INSTANCE_WIDGET_CALLBACK (ii))) | |
759 { | |
760 print_internal (IMAGE_INSTANCE_WIDGET_CALLBACK (ii), printcharfun, 0); | |
761 write_c_string (", ", printcharfun); | |
762 } | |
763 */ | |
764 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii))) | 760 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii))) |
765 { | 761 { |
766 write_c_string (" (", printcharfun); | 762 write_c_string (" (", printcharfun); |
767 print_internal | 763 print_internal |
768 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0); | 764 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0); |
840 struct device *d1 = XDEVICE (i1->device); | 836 struct device *d1 = XDEVICE (i1->device); |
841 struct device *d2 = XDEVICE (i2->device); | 837 struct device *d2 = XDEVICE (i2->device); |
842 | 838 |
843 if (d1 != d2) | 839 if (d1 != d2) |
844 return 0; | 840 return 0; |
845 if (IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2)) | 841 if (IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2) |
842 || IMAGE_INSTANCE_WIDTH (i1) != IMAGE_INSTANCE_WIDTH (i2) | |
843 || IMAGE_INSTANCE_HEIGHT (i1) != IMAGE_INSTANCE_HEIGHT (i2) | |
844 || IMAGE_INSTANCE_XOFFSET (i1) != IMAGE_INSTANCE_XOFFSET (i2) | |
845 || IMAGE_INSTANCE_YOFFSET (i1) != IMAGE_INSTANCE_YOFFSET (i2)) | |
846 return 0; | 846 return 0; |
847 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2), | 847 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2), |
848 depth + 1)) | 848 depth + 1)) |
849 return 0; | 849 return 0; |
850 | 850 |
861 break; | 861 break; |
862 | 862 |
863 case IMAGE_MONO_PIXMAP: | 863 case IMAGE_MONO_PIXMAP: |
864 case IMAGE_COLOR_PIXMAP: | 864 case IMAGE_COLOR_PIXMAP: |
865 case IMAGE_POINTER: | 865 case IMAGE_POINTER: |
866 if (!(IMAGE_INSTANCE_PIXMAP_WIDTH (i1) == | 866 if (!(IMAGE_INSTANCE_PIXMAP_DEPTH (i1) == |
867 IMAGE_INSTANCE_PIXMAP_WIDTH (i2) && | |
868 IMAGE_INSTANCE_PIXMAP_HEIGHT (i1) == | |
869 IMAGE_INSTANCE_PIXMAP_HEIGHT (i2) && | |
870 IMAGE_INSTANCE_PIXMAP_DEPTH (i1) == | |
871 IMAGE_INSTANCE_PIXMAP_DEPTH (i2) && | 867 IMAGE_INSTANCE_PIXMAP_DEPTH (i2) && |
872 IMAGE_INSTANCE_PIXMAP_SLICE (i1) == | 868 IMAGE_INSTANCE_PIXMAP_SLICE (i1) == |
873 IMAGE_INSTANCE_PIXMAP_SLICE (i2) && | 869 IMAGE_INSTANCE_PIXMAP_SLICE (i2) && |
874 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i1), | 870 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i1), |
875 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i2)) && | 871 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i2)) && |
885 break; | 881 break; |
886 | 882 |
887 case IMAGE_WIDGET: | 883 case IMAGE_WIDGET: |
888 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), | 884 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1), |
889 IMAGE_INSTANCE_WIDGET_TYPE (i2)) | 885 IMAGE_INSTANCE_WIDGET_TYPE (i2)) |
886 && IMAGE_INSTANCE_SUBWINDOW_ID (i1) == | |
887 IMAGE_INSTANCE_SUBWINDOW_ID (i2) | |
890 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1), | 888 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1), |
891 IMAGE_INSTANCE_WIDGET_ITEMS (i2), | 889 IMAGE_INSTANCE_WIDGET_ITEMS (i2), |
892 depth + 1) | 890 depth + 1) |
893 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), | 891 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1), |
894 IMAGE_INSTANCE_WIDGET_PROPS (i2), | 892 IMAGE_INSTANCE_WIDGET_PROPS (i2), |
895 depth + 1) | 893 depth + 1) |
896 )) | 894 )) |
897 return 0; | 895 return 0; |
896 break; | |
897 | |
898 case IMAGE_LAYOUT: | 898 case IMAGE_LAYOUT: |
899 if (IMAGE_INSTANCE_TYPE (i1) == IMAGE_LAYOUT | 899 if (IMAGE_INSTANCE_TYPE (i1) == IMAGE_LAYOUT |
900 && | 900 && |
901 !(EQ (IMAGE_INSTANCE_LAYOUT_BORDER (i1), | 901 !(EQ (IMAGE_INSTANCE_LAYOUT_BORDER (i1), |
902 IMAGE_INSTANCE_LAYOUT_BORDER (i2)) | 902 IMAGE_INSTANCE_LAYOUT_BORDER (i2)) |
903 && | 903 && |
904 internal_equal (IMAGE_INSTANCE_LAYOUT_CHILDREN (i1), | 904 internal_equal (IMAGE_INSTANCE_LAYOUT_CHILDREN (i1), |
905 IMAGE_INSTANCE_LAYOUT_CHILDREN (i2), | 905 IMAGE_INSTANCE_LAYOUT_CHILDREN (i2), |
906 depth + 1))) | 906 depth + 1))) |
907 return 0; | 907 return 0; |
908 break; | |
909 | |
908 case IMAGE_SUBWINDOW: | 910 case IMAGE_SUBWINDOW: |
909 if (!(IMAGE_INSTANCE_SUBWINDOW_WIDTH (i1) == | 911 if (!(IMAGE_INSTANCE_SUBWINDOW_ID (i1) == |
910 IMAGE_INSTANCE_SUBWINDOW_WIDTH (i2) && | |
911 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i1) == | |
912 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i2) && | |
913 IMAGE_INSTANCE_SUBWINDOW_ID (i1) == | |
914 IMAGE_INSTANCE_SUBWINDOW_ID (i2))) | 912 IMAGE_INSTANCE_SUBWINDOW_ID (i2))) |
915 return 0; | 913 return 0; |
916 break; | 914 break; |
917 | 915 |
918 default: | 916 default: |
925 static unsigned long | 923 static unsigned long |
926 image_instance_hash (Lisp_Object obj, int depth) | 924 image_instance_hash (Lisp_Object obj, int depth) |
927 { | 925 { |
928 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); | 926 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj); |
929 struct device *d = XDEVICE (i->device); | 927 struct device *d = XDEVICE (i->device); |
930 unsigned long hash = (unsigned long) d; | 928 unsigned long hash = HASH3 ((unsigned long) d, |
929 IMAGE_INSTANCE_WIDTH (i), | |
930 IMAGE_INSTANCE_HEIGHT (i)); | |
931 | 931 |
932 switch (IMAGE_INSTANCE_TYPE (i)) | 932 switch (IMAGE_INSTANCE_TYPE (i)) |
933 { | 933 { |
934 case IMAGE_NOTHING: | 934 case IMAGE_NOTHING: |
935 break; | 935 break; |
940 break; | 940 break; |
941 | 941 |
942 case IMAGE_MONO_PIXMAP: | 942 case IMAGE_MONO_PIXMAP: |
943 case IMAGE_COLOR_PIXMAP: | 943 case IMAGE_COLOR_PIXMAP: |
944 case IMAGE_POINTER: | 944 case IMAGE_POINTER: |
945 hash = HASH6 (hash, IMAGE_INSTANCE_PIXMAP_WIDTH (i), | 945 hash = HASH4 (hash, IMAGE_INSTANCE_PIXMAP_DEPTH (i), |
946 IMAGE_INSTANCE_PIXMAP_HEIGHT (i), | |
947 IMAGE_INSTANCE_PIXMAP_DEPTH (i), | |
948 IMAGE_INSTANCE_PIXMAP_SLICE (i), | 946 IMAGE_INSTANCE_PIXMAP_SLICE (i), |
949 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i), | 947 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i), |
950 depth + 1)); | 948 depth + 1)); |
951 break; | 949 break; |
952 | 950 |
953 case IMAGE_WIDGET: | 951 case IMAGE_WIDGET: |
954 hash = HASH4 (hash, | 952 hash = HASH4 (hash, |
955 internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1), | 953 internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1), |
956 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), | 954 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), |
957 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1)); | 955 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1)); |
956 case IMAGE_SUBWINDOW: | |
957 hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); | |
958 break; | |
959 | |
958 case IMAGE_LAYOUT: | 960 case IMAGE_LAYOUT: |
959 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_LAYOUT) | 961 hash = HASH3 (hash, |
960 hash = HASH3 (hash, | 962 internal_hash (IMAGE_INSTANCE_LAYOUT_BORDER (i), depth + 1), |
961 internal_hash (IMAGE_INSTANCE_LAYOUT_BORDER (i), depth + 1), | 963 internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i), |
962 internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i), | 964 depth + 1)); |
963 depth + 1)); | |
964 case IMAGE_SUBWINDOW: | |
965 hash = HASH4 (hash, IMAGE_INSTANCE_SUBWINDOW_WIDTH (i), | |
966 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i), | |
967 (int) IMAGE_INSTANCE_SUBWINDOW_ID (i)); | |
968 break; | 965 break; |
969 | 966 |
970 default: | 967 default: |
971 abort (); | 968 abort (); |
972 } | 969 } |
980 finalize_image_instance, image_instance_equal, | 977 finalize_image_instance, image_instance_equal, |
981 image_instance_hash, 0, | 978 image_instance_hash, 0, |
982 struct Lisp_Image_Instance); | 979 struct Lisp_Image_Instance); |
983 | 980 |
984 static Lisp_Object | 981 static Lisp_Object |
985 allocate_image_instance (Lisp_Object device) | 982 allocate_image_instance (Lisp_Object device, Lisp_Object glyph) |
986 { | 983 { |
987 struct Lisp_Image_Instance *lp = | 984 struct Lisp_Image_Instance *lp = |
988 alloc_lcrecord_type (struct Lisp_Image_Instance, &lrecord_image_instance); | 985 alloc_lcrecord_type (struct Lisp_Image_Instance, &lrecord_image_instance); |
989 Lisp_Object val; | 986 Lisp_Object val; |
990 | 987 |
992 lp->device = device; | 989 lp->device = device; |
993 lp->type = IMAGE_NOTHING; | 990 lp->type = IMAGE_NOTHING; |
994 lp->name = Qnil; | 991 lp->name = Qnil; |
995 lp->x_offset = 0; | 992 lp->x_offset = 0; |
996 lp->y_offset = 0; | 993 lp->y_offset = 0; |
994 lp->width = 0; | |
995 lp->height = 0; | |
996 lp->glyph = glyph; | |
997 MARK_IMAGE_INSTANCE_CHANGED (lp); /* So that layouts get done. */ | |
997 XSETIMAGE_INSTANCE (val, lp); | 998 XSETIMAGE_INSTANCE (val, lp); |
999 MARK_GLYPHS_CHANGED; /* So that the dirty flag gets reset. */ | |
998 return val; | 1000 return val; |
999 } | 1001 } |
1000 | 1002 |
1001 static enum image_instance_type | 1003 static enum image_instance_type |
1002 decode_image_instance_type (Lisp_Object type, Error_behavior errb) | 1004 decode_image_instance_type (Lisp_Object type, Error_behavior errb) |
1174 make_int (dest_mask)); | 1176 make_int (dest_mask)); |
1175 GCPRO1 (data); | 1177 GCPRO1 (data); |
1176 if (VECTORP (data) && EQ (XVECTOR_DATA (data)[0], Qinherit)) | 1178 if (VECTORP (data) && EQ (XVECTOR_DATA (data)[0], Qinherit)) |
1177 signal_simple_error ("Inheritance not allowed here", data); | 1179 signal_simple_error ("Inheritance not allowed here", data); |
1178 ii = instantiate_image_instantiator (device, device, data, | 1180 ii = instantiate_image_instantiator (device, device, data, |
1179 Qnil, Qnil, dest_mask); | 1181 Qnil, Qnil, dest_mask, Qnil); |
1180 RETURN_UNGCPRO (ii); | 1182 RETURN_UNGCPRO (ii); |
1181 } | 1183 } |
1182 | 1184 |
1183 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /* | 1185 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /* |
1184 Return a new `image-instance' object. | 1186 Return a new `image-instance' object. |
1448 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1450 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1449 { | 1451 { |
1450 case IMAGE_MONO_PIXMAP: | 1452 case IMAGE_MONO_PIXMAP: |
1451 case IMAGE_COLOR_PIXMAP: | 1453 case IMAGE_COLOR_PIXMAP: |
1452 case IMAGE_POINTER: | 1454 case IMAGE_POINTER: |
1453 return make_int (XIMAGE_INSTANCE_PIXMAP_HEIGHT (image_instance)); | |
1454 | |
1455 case IMAGE_SUBWINDOW: | 1455 case IMAGE_SUBWINDOW: |
1456 case IMAGE_WIDGET: | 1456 case IMAGE_WIDGET: |
1457 case IMAGE_LAYOUT: | 1457 case IMAGE_LAYOUT: |
1458 return make_int (XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (image_instance)); | 1458 return make_int (XIMAGE_INSTANCE_HEIGHT (image_instance)); |
1459 | 1459 |
1460 default: | 1460 default: |
1461 return Qnil; | 1461 return Qnil; |
1462 } | 1462 } |
1463 } | 1463 } |
1472 switch (XIMAGE_INSTANCE_TYPE (image_instance)) | 1472 switch (XIMAGE_INSTANCE_TYPE (image_instance)) |
1473 { | 1473 { |
1474 case IMAGE_MONO_PIXMAP: | 1474 case IMAGE_MONO_PIXMAP: |
1475 case IMAGE_COLOR_PIXMAP: | 1475 case IMAGE_COLOR_PIXMAP: |
1476 case IMAGE_POINTER: | 1476 case IMAGE_POINTER: |
1477 return make_int (XIMAGE_INSTANCE_PIXMAP_WIDTH (image_instance)); | |
1478 | |
1479 case IMAGE_SUBWINDOW: | 1477 case IMAGE_SUBWINDOW: |
1480 case IMAGE_WIDGET: | 1478 case IMAGE_WIDGET: |
1481 case IMAGE_LAYOUT: | 1479 case IMAGE_LAYOUT: |
1482 return make_int (XIMAGE_INSTANCE_SUBWINDOW_WIDTH (image_instance)); | 1480 return make_int (XIMAGE_INSTANCE_WIDTH (image_instance)); |
1483 | 1481 |
1484 default: | 1482 default: |
1485 return Qnil; | 1483 return Qnil; |
1486 } | 1484 } |
1487 } | 1485 } |
1609 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance)) | 1607 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance)) |
1610 return image_instance; | 1608 return image_instance; |
1611 | 1609 |
1612 /* #### There should be a copy_image_instance(), which calls a | 1610 /* #### There should be a copy_image_instance(), which calls a |
1613 device-specific method to copy the window-system subobject. */ | 1611 device-specific method to copy the window-system subobject. */ |
1614 new = allocate_image_instance (device); | 1612 new = allocate_image_instance (device, Qnil); |
1615 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance)); | 1613 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance)); |
1616 /* note that if this method returns non-zero, this method MUST | 1614 /* note that if this method returns non-zero, this method MUST |
1617 copy any window-system resources, so that when one image instance is | 1615 copy any window-system resources, so that when one image instance is |
1618 freed, the other one is not hosed. */ | 1616 freed, the other one is not hosed. */ |
1619 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground, | 1617 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground, |
1620 background))) | 1618 background))) |
1621 return image_instance; | 1619 return image_instance; |
1622 return new; | 1620 return new; |
1623 } | 1621 } |
1624 | 1622 |
1623 | |
1624 /************************************************************************/ | |
1625 /* Geometry calculations */ | |
1626 /************************************************************************/ | |
1627 | |
1628 /* Find out desired geometry of the image instance. If there is no | |
1629 special function then just return the width and / or height. */ | |
1630 void | |
1631 image_instance_query_geometry (Lisp_Object image_instance, | |
1632 unsigned int* width, unsigned int* height, | |
1633 enum image_instance_geometry disp, | |
1634 Lisp_Object domain) | |
1635 { | |
1636 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | |
1637 Lisp_Object type; | |
1638 struct image_instantiator_methods* meths; | |
1639 | |
1640 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | |
1641 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); | |
1642 | |
1643 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | |
1644 { | |
1645 IIFORMAT_METH (meths, query_geometry, (image_instance, width, height, | |
1646 disp, domain)); | |
1647 } | |
1648 else | |
1649 { | |
1650 if (width) | |
1651 *width = IMAGE_INSTANCE_WIDTH (ii); | |
1652 if (height) | |
1653 *height = IMAGE_INSTANCE_HEIGHT (ii); | |
1654 } | |
1655 } | |
1656 | |
1657 /* Layout the image instance using the provided dimensions. Layout | |
1658 widgets are going to do different kinds of calculations to | |
1659 determine what size to give things so we could make the layout | |
1660 function relatively simple to take account of that. An alternative | |
1661 approach is to consider separately the two cases, one where you | |
1662 don't mind what size you have (normal widgets) and one where you | |
1663 want to specifiy something (layout widgets). */ | |
1664 void | |
1665 image_instance_layout (Lisp_Object image_instance, | |
1666 unsigned int width, unsigned int height, | |
1667 Lisp_Object domain) | |
1668 { | |
1669 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | |
1670 Lisp_Object type; | |
1671 struct image_instantiator_methods* meths; | |
1672 | |
1673 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | |
1674 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); | |
1675 | |
1676 /* If geometry is unspecified then get some reasonable values for it. */ | |
1677 if (width == IMAGE_UNSPECIFIED_GEOMETRY | |
1678 || | |
1679 height == IMAGE_UNSPECIFIED_GEOMETRY) | |
1680 { | |
1681 unsigned int dwidth, dheight; | |
1682 | |
1683 /* Get the desired geometry. */ | |
1684 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | |
1685 { | |
1686 IIFORMAT_METH (meths, query_geometry, (image_instance, &dwidth, &dheight, | |
1687 IMAGE_DESIRED_GEOMETRY, | |
1688 domain)); | |
1689 } | |
1690 else | |
1691 { | |
1692 dwidth = IMAGE_INSTANCE_WIDTH (ii); | |
1693 dheight = IMAGE_INSTANCE_HEIGHT (ii); | |
1694 } | |
1695 | |
1696 /* Compare with allowed geometry. */ | |
1697 if (width == IMAGE_UNSPECIFIED_GEOMETRY) | |
1698 width = dwidth; | |
1699 if (height == IMAGE_UNSPECIFIED_GEOMETRY) | |
1700 height = dheight; | |
1701 } | |
1702 | |
1703 /* At this point width and height should contain sane values. Thus | |
1704 we set the glyph geometry and lay it out. */ | |
1705 IMAGE_INSTANCE_WIDTH (ii) = width; | |
1706 IMAGE_INSTANCE_HEIGHT (ii) = height; | |
1707 | |
1708 if (meths && HAS_IIFORMAT_METH_P (meths, layout)) | |
1709 { | |
1710 IIFORMAT_METH (meths, layout, (image_instance, width, height, domain)); | |
1711 } | |
1712 /* else no change to the geometry. */ | |
1713 } | |
1714 | |
1625 | 1715 |
1626 /************************************************************************/ | 1716 /************************************************************************/ |
1627 /* error helpers */ | 1717 /* error helpers */ |
1628 /************************************************************************/ | 1718 /************************************************************************/ |
1629 DOESNT_RETURN | 1719 DOESNT_RETURN |
1716 string_possible_dest_types (void) | 1806 string_possible_dest_types (void) |
1717 { | 1807 { |
1718 return IMAGE_TEXT_MASK; | 1808 return IMAGE_TEXT_MASK; |
1719 } | 1809 } |
1720 | 1810 |
1721 /* called from autodetect_instantiate() */ | 1811 /* Called from autodetect_instantiate() */ |
1722 void | 1812 void |
1723 string_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 1813 string_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
1724 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 1814 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1725 int dest_mask, Lisp_Object domain) | 1815 int dest_mask, Lisp_Object domain) |
1726 { | 1816 { |
1727 Lisp_Object string = find_keyword_in_vector (instantiator, Q_data); | 1817 Lisp_Object string = find_keyword_in_vector (instantiator, Q_data); |
1728 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 1818 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
1729 | 1819 |
1730 assert (!NILP (string)); | 1820 /* Should never get here with a domain other than a window. */ |
1821 assert (!NILP (string) && WINDOWP (domain)); | |
1731 if (dest_mask & IMAGE_TEXT_MASK) | 1822 if (dest_mask & IMAGE_TEXT_MASK) |
1732 { | 1823 { |
1733 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; | 1824 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; |
1734 IMAGE_INSTANCE_TEXT_STRING (ii) = string; | 1825 IMAGE_INSTANCE_TEXT_STRING (ii) = string; |
1735 } | 1826 } |
1736 else | 1827 else |
1737 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK); | 1828 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK); |
1829 } | |
1830 | |
1831 /* Sort out the size of the text that is being displayed. Calculating | |
1832 it dynamically allows us to change the text and still see | |
1833 everything. Note that the following methods are for text not string | |
1834 since that is what the instantiated type is. The first method is a | |
1835 helper that is used elsewhere for calculating text geometry. */ | |
1836 void | |
1837 query_string_geometry (Lisp_Object string, Lisp_Object face, | |
1838 unsigned int* width, unsigned int* height, | |
1839 unsigned int* descent, Lisp_Object domain) | |
1840 { | |
1841 struct font_metric_info fm; | |
1842 unsigned char charsets[NUM_LEADING_BYTES]; | |
1843 struct face_cachel frame_cachel; | |
1844 struct face_cachel *cachel; | |
1845 Lisp_Object frame = FW_FRAME (domain); | |
1846 | |
1847 /* Compute height */ | |
1848 if (height) | |
1849 { | |
1850 /* Compute string metric info */ | |
1851 find_charsets_in_bufbyte_string (charsets, | |
1852 XSTRING_DATA (string), | |
1853 XSTRING_LENGTH (string)); | |
1854 | |
1855 /* Fallback to the default face if none was provided. */ | |
1856 if (!NILP (face)) | |
1857 { | |
1858 reset_face_cachel (&frame_cachel); | |
1859 update_face_cachel_data (&frame_cachel, frame, face); | |
1860 cachel = &frame_cachel; | |
1861 } | |
1862 else | |
1863 { | |
1864 cachel = WINDOW_FACE_CACHEL (XWINDOW (domain), DEFAULT_INDEX); | |
1865 } | |
1866 | |
1867 ensure_face_cachel_complete (cachel, domain, charsets); | |
1868 face_cachel_charset_font_metric_info (cachel, charsets, &fm); | |
1869 | |
1870 *height = fm.ascent + fm.descent; | |
1871 /* #### descent only gets set if we query the height as well. */ | |
1872 if (descent) | |
1873 *descent = fm.descent; | |
1874 } | |
1875 | |
1876 /* Compute width */ | |
1877 if (width) | |
1878 { | |
1879 if (!NILP (face)) | |
1880 *width = redisplay_frame_text_width_string (XFRAME (frame), | |
1881 face, | |
1882 0, string, 0, -1); | |
1883 else | |
1884 *width = redisplay_frame_text_width_string (XFRAME (frame), | |
1885 Vdefault_face, | |
1886 0, string, 0, -1); | |
1887 } | |
1888 } | |
1889 | |
1890 Lisp_Object | |
1891 query_string_font (Lisp_Object string, Lisp_Object face, Lisp_Object domain) | |
1892 { | |
1893 unsigned char charsets[NUM_LEADING_BYTES]; | |
1894 struct face_cachel frame_cachel; | |
1895 struct face_cachel *cachel; | |
1896 int i; | |
1897 Lisp_Object frame = FW_FRAME (domain); | |
1898 | |
1899 /* Compute string font info */ | |
1900 find_charsets_in_bufbyte_string (charsets, | |
1901 XSTRING_DATA (string), | |
1902 XSTRING_LENGTH (string)); | |
1903 | |
1904 reset_face_cachel (&frame_cachel); | |
1905 update_face_cachel_data (&frame_cachel, frame, face); | |
1906 cachel = &frame_cachel; | |
1907 | |
1908 ensure_face_cachel_complete (cachel, domain, charsets); | |
1909 | |
1910 for (i = 0; i < NUM_LEADING_BYTES; i++) | |
1911 { | |
1912 if (charsets[i]) | |
1913 { | |
1914 return FACE_CACHEL_FONT (cachel, | |
1915 CHARSET_BY_LEADING_BYTE (i + | |
1916 MIN_LEADING_BYTE)); | |
1917 | |
1918 } | |
1919 } | |
1920 | |
1921 return Qnil; /* NOT REACHED */ | |
1922 } | |
1923 | |
1924 static void | |
1925 text_query_geometry (Lisp_Object image_instance, | |
1926 unsigned int* width, unsigned int* height, | |
1927 enum image_instance_geometry disp, Lisp_Object domain) | |
1928 { | |
1929 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1930 unsigned int descent = 0; | |
1931 | |
1932 query_string_geometry (IMAGE_INSTANCE_TEXT_STRING (ii), | |
1933 IMAGE_INSTANCE_FACE (ii), | |
1934 width, height, &descent, domain); | |
1935 | |
1936 /* The descent gets set as a side effect of querying the | |
1937 geometry. */ | |
1938 IMAGE_INSTANCE_TEXT_DESCENT (ii) = descent; | |
1738 } | 1939 } |
1739 | 1940 |
1740 /* set the properties of a string */ | 1941 /* set the properties of a string */ |
1741 static Lisp_Object | 1942 static Lisp_Object |
1742 text_set_property (Lisp_Object image_instance, Lisp_Object prop, | 1943 text_set_property (Lisp_Object image_instance, Lisp_Object prop, |
1775 formatted_string_instantiate (Lisp_Object image_instance, | 1976 formatted_string_instantiate (Lisp_Object image_instance, |
1776 Lisp_Object instantiator, | 1977 Lisp_Object instantiator, |
1777 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 1978 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1778 int dest_mask, Lisp_Object domain) | 1979 int dest_mask, Lisp_Object domain) |
1779 { | 1980 { |
1780 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1781 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1782 | |
1783 assert (!NILP (data)); | |
1784 /* #### implement this */ | 1981 /* #### implement this */ |
1785 warn_when_safe (Qunimplemented, Qnotice, | 1982 warn_when_safe (Qunimplemented, Qnotice, |
1786 "`formatted-string' not yet implemented; assuming `string'"); | 1983 "`formatted-string' not yet implemented; assuming `string'"); |
1787 if (dest_mask & IMAGE_TEXT_MASK) | 1984 |
1788 { | 1985 string_instantiate (image_instance, instantiator, |
1789 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; | 1986 pointer_fg, pointer_bg, dest_mask, domain); |
1790 IMAGE_INSTANCE_TEXT_STRING (ii) = data; | |
1791 } | |
1792 else | |
1793 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK); | |
1794 } | 1987 } |
1795 | 1988 |
1796 | 1989 |
1797 /************************************************************************/ | 1990 /************************************************************************/ |
1798 /* pixmap file functions */ | 1991 /* pixmap file functions */ |
2445 Lisp_Object domain, Lisp_Object instantiator, | 2638 Lisp_Object domain, Lisp_Object instantiator, |
2446 Lisp_Object depth) | 2639 Lisp_Object depth) |
2447 { | 2640 { |
2448 Lisp_Object device = DFW_DEVICE (domain); | 2641 Lisp_Object device = DFW_DEVICE (domain); |
2449 struct device *d = XDEVICE (device); | 2642 struct device *d = XDEVICE (device); |
2643 Lisp_Object glyph = IMAGE_SPECIFIER_ATTACHEE (XIMAGE_SPECIFIER (specifier)); | |
2450 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier); | 2644 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier); |
2451 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER); | 2645 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER); |
2452 | 2646 |
2453 if (IMAGE_INSTANCEP (instantiator)) | 2647 if (IMAGE_INSTANCEP (instantiator)) |
2454 { | 2648 { |
2567 locative); | 2761 locative); |
2568 instance = instantiate_image_instantiator (device, | 2762 instance = instantiate_image_instantiator (device, |
2569 domain, | 2763 domain, |
2570 instantiator, | 2764 instantiator, |
2571 pointer_fg, pointer_bg, | 2765 pointer_fg, pointer_bg, |
2572 dest_mask); | 2766 dest_mask, |
2767 glyph); | |
2573 | 2768 |
2574 Fsetcar (locative, instance); | 2769 Fsetcar (locative, instance); |
2575 /* only after the image has been instantiated do we know | 2770 /* only after the image has been instantiated do we know |
2576 whether we need to put it in the per-window image instance | 2771 whether we need to put it in the per-window image instance |
2577 cache. */ | 2772 cache. */ |
3161 XIMAGE_SPECIFIER_ALLOWED (g->image) = | 3356 XIMAGE_SPECIFIER_ALLOWED (g->image) = |
3162 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK; | 3357 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK; |
3163 break; | 3358 break; |
3164 case GLYPH_ICON: | 3359 case GLYPH_ICON: |
3165 XIMAGE_SPECIFIER_ALLOWED (g->image) = | 3360 XIMAGE_SPECIFIER_ALLOWED (g->image) = |
3166 IMAGE_NOTHING_MASK | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK; | 3361 IMAGE_NOTHING_MASK | IMAGE_MONO_PIXMAP_MASK |
3362 | IMAGE_COLOR_PIXMAP_MASK; | |
3167 break; | 3363 break; |
3168 default: | 3364 default: |
3169 abort (); | 3365 abort (); |
3170 } | 3366 } |
3171 | 3367 |
3294 case GLYPH_POINTER: return Qpointer; | 3490 case GLYPH_POINTER: return Qpointer; |
3295 case GLYPH_ICON: return Qicon; | 3491 case GLYPH_ICON: return Qicon; |
3296 } | 3492 } |
3297 } | 3493 } |
3298 | 3494 |
3495 Lisp_Object | |
3496 glyph_image_instance (Lisp_Object glyph, Lisp_Object domain, | |
3497 Error_behavior errb, int no_quit) | |
3498 { | |
3499 Lisp_Object specifier = GLYPH_IMAGE (XGLYPH (glyph)); | |
3500 | |
3501 /* This can never return Qunbound. All glyphs have 'nothing as | |
3502 a fallback. */ | |
3503 Lisp_Object image_instance = specifier_instance (specifier, Qunbound, | |
3504 domain, errb, no_quit, 0, | |
3505 Qzero); | |
3506 | |
3507 return image_instance; | |
3508 } | |
3509 | |
3510 static Lisp_Object | |
3511 glyph_image_instance_maybe (Lisp_Object glyph_or_image, Lisp_Object window) | |
3512 { | |
3513 Lisp_Object instance = glyph_or_image; | |
3514 | |
3515 if (GLYPHP (glyph_or_image)) | |
3516 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); | |
3517 | |
3518 return instance; | |
3519 } | |
3520 | |
3299 /***************************************************************************** | 3521 /***************************************************************************** |
3300 glyph_width | 3522 glyph_width |
3301 | 3523 |
3302 Return the width of the given GLYPH on the given WINDOW. If the | 3524 Return the width of the given GLYPH on the given WINDOW. |
3303 instance is a string then the width is calculated using the font of | 3525 Calculations are done based on recursively querying the geometry of |
3304 the given FACE, unless a face is defined by the glyph itself. | 3526 the associated image instances. |
3305 ****************************************************************************/ | 3527 ****************************************************************************/ |
3306 unsigned short | 3528 unsigned short |
3307 glyph_width (Lisp_Object glyph_or_image, Lisp_Object frame_face, | 3529 glyph_width (Lisp_Object glyph_or_image, Lisp_Object domain) |
3308 face_index window_findex, Lisp_Object window) | 3530 { |
3309 { | 3531 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, |
3310 Lisp_Object instance = glyph_or_image; | 3532 domain); |
3311 Lisp_Object frame = XWINDOW (window)->frame; | |
3312 | |
3313 /* #### We somehow need to distinguish between the user causing this | |
3314 error condition and a bug causing it. */ | |
3315 if (GLYPHP (glyph_or_image)) | |
3316 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); | |
3317 | |
3318 if (!IMAGE_INSTANCEP (instance)) | 3533 if (!IMAGE_INSTANCEP (instance)) |
3319 return 0; | 3534 return 0; |
3320 | 3535 |
3321 switch (XIMAGE_INSTANCE_TYPE (instance)) | 3536 if (XIMAGE_INSTANCE_DIRTYP (instance)) |
3322 { | 3537 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, |
3323 case IMAGE_TEXT: | 3538 IMAGE_UNSPECIFIED_GEOMETRY, domain); |
3324 { | 3539 |
3325 Lisp_Object str = XIMAGE_INSTANCE_TEXT_STRING (instance); | 3540 return XIMAGE_INSTANCE_WIDTH (instance); |
3326 Lisp_Object private_face = Qnil; | |
3327 | |
3328 if (GLYPHP (glyph_or_image)) | |
3329 private_face = XGLYPH_FACE(glyph_or_image); | |
3330 | |
3331 if (!NILP (private_face)) | |
3332 return redisplay_frame_text_width_string (XFRAME (frame), | |
3333 private_face, | |
3334 0, str, 0, -1); | |
3335 else | |
3336 if (!NILP (frame_face)) | |
3337 return redisplay_frame_text_width_string (XFRAME (frame), | |
3338 frame_face, | |
3339 0, str, 0, -1); | |
3340 else | |
3341 return redisplay_text_width_string (XWINDOW (window), | |
3342 window_findex, | |
3343 0, str, 0, -1); | |
3344 } | |
3345 | |
3346 case IMAGE_MONO_PIXMAP: | |
3347 case IMAGE_COLOR_PIXMAP: | |
3348 case IMAGE_POINTER: | |
3349 return XIMAGE_INSTANCE_PIXMAP_WIDTH (instance); | |
3350 | |
3351 case IMAGE_NOTHING: | |
3352 return 0; | |
3353 | |
3354 case IMAGE_SUBWINDOW: | |
3355 case IMAGE_WIDGET: | |
3356 case IMAGE_LAYOUT: | |
3357 return XIMAGE_INSTANCE_SUBWINDOW_WIDTH (instance); | |
3358 | |
3359 default: | |
3360 abort (); | |
3361 return 0; | |
3362 } | |
3363 } | 3541 } |
3364 | 3542 |
3365 DEFUN ("glyph-width", Fglyph_width, 1, 2, 0, /* | 3543 DEFUN ("glyph-width", Fglyph_width, 1, 2, 0, /* |
3366 Return the width of GLYPH on WINDOW. | 3544 Return the width of GLYPH on WINDOW. |
3367 This may not be exact as it does not take into account all of the context | 3545 This may not be exact as it does not take into account all of the context |
3370 (glyph, window)) | 3548 (glyph, window)) |
3371 { | 3549 { |
3372 XSETWINDOW (window, decode_window (window)); | 3550 XSETWINDOW (window, decode_window (window)); |
3373 CHECK_GLYPH (glyph); | 3551 CHECK_GLYPH (glyph); |
3374 | 3552 |
3375 return make_int (glyph_width (glyph, Qnil, DEFAULT_INDEX, window)); | 3553 return make_int (glyph_width (glyph, window)); |
3376 } | 3554 } |
3377 | 3555 |
3378 #define RETURN_ASCENT 0 | 3556 unsigned short |
3379 #define RETURN_DESCENT 1 | 3557 glyph_ascent (Lisp_Object glyph_or_image, Lisp_Object domain) |
3380 #define RETURN_HEIGHT 2 | 3558 { |
3381 | 3559 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, |
3382 Lisp_Object | 3560 domain); |
3383 glyph_image_instance (Lisp_Object glyph, Lisp_Object domain, | |
3384 Error_behavior errb, int no_quit) | |
3385 { | |
3386 Lisp_Object specifier = GLYPH_IMAGE (XGLYPH (glyph)); | |
3387 | |
3388 /* This can never return Qunbound. All glyphs have 'nothing as | |
3389 a fallback. */ | |
3390 return specifier_instance (specifier, Qunbound, domain, errb, no_quit, 0, | |
3391 Qzero); | |
3392 } | |
3393 | |
3394 static unsigned short | |
3395 glyph_height_internal (Lisp_Object glyph_or_image, Lisp_Object frame_face, | |
3396 face_index window_findex, Lisp_Object window, | |
3397 int function) | |
3398 { | |
3399 Lisp_Object instance = glyph_or_image; | |
3400 Lisp_Object frame = XWINDOW (window)->frame; | |
3401 | |
3402 if (GLYPHP (glyph_or_image)) | |
3403 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); | |
3404 | |
3405 if (!IMAGE_INSTANCEP (instance)) | 3561 if (!IMAGE_INSTANCEP (instance)) |
3406 return 0; | 3562 return 0; |
3407 | 3563 |
3408 switch (XIMAGE_INSTANCE_TYPE (instance)) | 3564 if (XIMAGE_INSTANCE_DIRTYP (instance)) |
3409 { | 3565 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, |
3410 case IMAGE_TEXT: | 3566 IMAGE_UNSPECIFIED_GEOMETRY, domain); |
3411 { | 3567 |
3412 struct font_metric_info fm; | 3568 if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT) |
3413 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance); | 3569 return XIMAGE_INSTANCE_TEXT_ASCENT (instance); |
3414 unsigned char charsets[NUM_LEADING_BYTES]; | 3570 else |
3415 struct face_cachel frame_cachel; | 3571 return XIMAGE_INSTANCE_HEIGHT (instance); |
3416 struct face_cachel *cachel; | |
3417 | |
3418 find_charsets_in_bufbyte_string (charsets, | |
3419 XSTRING_DATA (string), | |
3420 XSTRING_LENGTH (string)); | |
3421 | |
3422 if (!NILP (frame_face)) | |
3423 { | |
3424 reset_face_cachel (&frame_cachel); | |
3425 update_face_cachel_data (&frame_cachel, frame, frame_face); | |
3426 cachel = &frame_cachel; | |
3427 } | |
3428 else | |
3429 cachel = WINDOW_FACE_CACHEL (XWINDOW (window), window_findex); | |
3430 ensure_face_cachel_complete (cachel, window, charsets); | |
3431 | |
3432 face_cachel_charset_font_metric_info (cachel, charsets, &fm); | |
3433 | |
3434 switch (function) | |
3435 { | |
3436 case RETURN_ASCENT: return fm.ascent; | |
3437 case RETURN_DESCENT: return fm.descent; | |
3438 case RETURN_HEIGHT: return fm.ascent + fm.descent; | |
3439 default: | |
3440 abort (); | |
3441 return 0; /* not reached */ | |
3442 } | |
3443 } | |
3444 | |
3445 case IMAGE_MONO_PIXMAP: | |
3446 case IMAGE_COLOR_PIXMAP: | |
3447 case IMAGE_POINTER: | |
3448 /* #### Ugh ugh ugh -- temporary crap */ | |
3449 if (function == RETURN_ASCENT || function == RETURN_HEIGHT) | |
3450 return XIMAGE_INSTANCE_PIXMAP_HEIGHT (instance); | |
3451 else | |
3452 return 0; | |
3453 | |
3454 case IMAGE_NOTHING: | |
3455 return 0; | |
3456 | |
3457 case IMAGE_SUBWINDOW: | |
3458 case IMAGE_WIDGET: | |
3459 case IMAGE_LAYOUT: | |
3460 /* #### Ugh ugh ugh -- temporary crap */ | |
3461 if (function == RETURN_ASCENT || function == RETURN_HEIGHT) | |
3462 return XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (instance); | |
3463 else | |
3464 return 0; | |
3465 | |
3466 default: | |
3467 abort (); | |
3468 return 0; | |
3469 } | |
3470 } | 3572 } |
3471 | 3573 |
3472 unsigned short | 3574 unsigned short |
3473 glyph_ascent (Lisp_Object glyph, Lisp_Object frame_face, | 3575 glyph_descent (Lisp_Object glyph_or_image, Lisp_Object domain) |
3474 face_index window_findex, Lisp_Object window) | 3576 { |
3475 { | 3577 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, |
3476 return glyph_height_internal (glyph, frame_face, window_findex, window, | 3578 domain); |
3477 RETURN_ASCENT); | 3579 if (!IMAGE_INSTANCEP (instance)) |
3478 } | 3580 return 0; |
3479 | 3581 |
3480 unsigned short | 3582 if (XIMAGE_INSTANCE_DIRTYP (instance)) |
3481 glyph_descent (Lisp_Object glyph, Lisp_Object frame_face, | 3583 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, |
3482 face_index window_findex, Lisp_Object window) | 3584 IMAGE_UNSPECIFIED_GEOMETRY, domain); |
3483 { | 3585 |
3484 return glyph_height_internal (glyph, frame_face, window_findex, window, | 3586 if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT) |
3485 RETURN_DESCENT); | 3587 return XIMAGE_INSTANCE_TEXT_DESCENT (instance); |
3588 else | |
3589 return 0; | |
3486 } | 3590 } |
3487 | 3591 |
3488 /* strictly a convenience function. */ | 3592 /* strictly a convenience function. */ |
3489 unsigned short | 3593 unsigned short |
3490 glyph_height (Lisp_Object glyph, Lisp_Object frame_face, | 3594 glyph_height (Lisp_Object glyph_or_image, Lisp_Object domain) |
3491 face_index window_findex, Lisp_Object window) | 3595 { |
3492 { | 3596 Lisp_Object instance = glyph_image_instance_maybe (glyph_or_image, |
3493 return glyph_height_internal (glyph, frame_face, window_findex, window, | 3597 domain); |
3494 RETURN_HEIGHT); | 3598 |
3599 if (!IMAGE_INSTANCEP (instance)) | |
3600 return 0; | |
3601 | |
3602 if (XIMAGE_INSTANCE_DIRTYP (instance)) | |
3603 image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY, | |
3604 IMAGE_UNSPECIFIED_GEOMETRY, domain); | |
3605 | |
3606 return XIMAGE_INSTANCE_HEIGHT (instance); | |
3495 } | 3607 } |
3496 | 3608 |
3497 DEFUN ("glyph-ascent", Fglyph_ascent, 1, 2, 0, /* | 3609 DEFUN ("glyph-ascent", Fglyph_ascent, 1, 2, 0, /* |
3498 Return the ascent value of GLYPH on WINDOW. | 3610 Return the ascent value of GLYPH on WINDOW. |
3499 This may not be exact as it does not take into account all of the context | 3611 This may not be exact as it does not take into account all of the context |
3502 (glyph, window)) | 3614 (glyph, window)) |
3503 { | 3615 { |
3504 XSETWINDOW (window, decode_window (window)); | 3616 XSETWINDOW (window, decode_window (window)); |
3505 CHECK_GLYPH (glyph); | 3617 CHECK_GLYPH (glyph); |
3506 | 3618 |
3507 return make_int (glyph_ascent (glyph, Qnil, DEFAULT_INDEX, window)); | 3619 return make_int (glyph_ascent (glyph, window)); |
3508 } | 3620 } |
3509 | 3621 |
3510 DEFUN ("glyph-descent", Fglyph_descent, 1, 2, 0, /* | 3622 DEFUN ("glyph-descent", Fglyph_descent, 1, 2, 0, /* |
3511 Return the descent value of GLYPH on WINDOW. | 3623 Return the descent value of GLYPH on WINDOW. |
3512 This may not be exact as it does not take into account all of the context | 3624 This may not be exact as it does not take into account all of the context |
3515 (glyph, window)) | 3627 (glyph, window)) |
3516 { | 3628 { |
3517 XSETWINDOW (window, decode_window (window)); | 3629 XSETWINDOW (window, decode_window (window)); |
3518 CHECK_GLYPH (glyph); | 3630 CHECK_GLYPH (glyph); |
3519 | 3631 |
3520 return make_int (glyph_descent (glyph, Qnil, DEFAULT_INDEX, window)); | 3632 return make_int (glyph_descent (glyph, window)); |
3521 } | 3633 } |
3522 | 3634 |
3523 /* This is redundant but I bet a lot of people expect it to exist. */ | 3635 /* This is redundant but I bet a lot of people expect it to exist. */ |
3524 DEFUN ("glyph-height", Fglyph_height, 1, 2, 0, /* | 3636 DEFUN ("glyph-height", Fglyph_height, 1, 2, 0, /* |
3525 Return the height of GLYPH on WINDOW. | 3637 Return the height of GLYPH on WINDOW. |
3529 (glyph, window)) | 3641 (glyph, window)) |
3530 { | 3642 { |
3531 XSETWINDOW (window, decode_window (window)); | 3643 XSETWINDOW (window, decode_window (window)); |
3532 CHECK_GLYPH (glyph); | 3644 CHECK_GLYPH (glyph); |
3533 | 3645 |
3534 return make_int (glyph_height (glyph, Qnil, DEFAULT_INDEX, window)); | 3646 return make_int (glyph_height (glyph, window)); |
3535 } | 3647 } |
3536 | |
3537 #undef RETURN_ASCENT | |
3538 #undef RETURN_DESCENT | |
3539 #undef RETURN_HEIGHT | |
3540 | 3648 |
3541 static unsigned int | 3649 static unsigned int |
3542 glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window) | 3650 glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window) |
3543 { | 3651 { |
3544 Lisp_Object instance = glyph_or_image; | 3652 return XIMAGE_INSTANCE_DIRTYP (glyph_image_instance_maybe |
3545 | 3653 (glyph_or_image, window)); |
3546 if (GLYPHP (glyph_or_image)) | |
3547 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); | |
3548 | |
3549 return XIMAGE_INSTANCE_DIRTYP (instance); | |
3550 } | 3654 } |
3551 | 3655 |
3552 static void | 3656 static void |
3553 set_glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window, int dirty) | 3657 set_glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window, int dirty) |
3554 { | 3658 { |
3619 { | 3723 { |
3620 if (XGLYPH (glyph)->after_change) | 3724 if (XGLYPH (glyph)->after_change) |
3621 (XGLYPH (glyph)->after_change) (glyph, property, locale); | 3725 (XGLYPH (glyph)->after_change) (glyph, property, locale); |
3622 } | 3726 } |
3623 | 3727 |
3728 #if 0 /* Not used for now */ | |
3729 static void | |
3730 glyph_query_geometry (Lisp_Object glyph_or_image, Lisp_Object window, | |
3731 unsigned int* width, unsigned int* height, | |
3732 enum image_instance_geometry disp, Lisp_Object domain) | |
3733 { | |
3734 Lisp_Object instance = glyph_or_image; | |
3735 | |
3736 if (GLYPHP (glyph_or_image)) | |
3737 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); | |
3738 | |
3739 image_instance_query_geometry (instance, width, height, disp, domain); | |
3740 } | |
3741 | |
3742 static void | |
3743 glyph_layout (Lisp_Object glyph_or_image, Lisp_Object window, | |
3744 unsigned int width, unsigned int height, Lisp_Object domain) | |
3745 { | |
3746 Lisp_Object instance = glyph_or_image; | |
3747 | |
3748 if (GLYPHP (glyph_or_image)) | |
3749 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1); | |
3750 | |
3751 image_instance_layout (instance, width, height, domain); | |
3752 } | |
3753 #endif | |
3754 | |
3624 | 3755 |
3625 /***************************************************************************** | 3756 /***************************************************************************** |
3626 * glyph cachel functions * | 3757 * glyph cachel functions * |
3627 *****************************************************************************/ | 3758 *****************************************************************************/ |
3628 | 3759 |
3660 cachel->glyph = glyph; | 3791 cachel->glyph = glyph; |
3661 /* Speed things up slightly by grabbing the glyph instantiation | 3792 /* Speed things up slightly by grabbing the glyph instantiation |
3662 and passing it to the size functions. */ | 3793 and passing it to the size functions. */ |
3663 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); | 3794 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); |
3664 cachel->dirty = XGLYPH_DIRTYP (glyph) = glyph_dirty_p (glyph, window); | 3795 cachel->dirty = XGLYPH_DIRTYP (glyph) = glyph_dirty_p (glyph, window); |
3665 cachel->width = glyph_width (instance, Qnil, DEFAULT_INDEX, window); | 3796 cachel->width = glyph_width (instance, window); |
3666 cachel->ascent = glyph_ascent (instance, Qnil, DEFAULT_INDEX, window); | 3797 cachel->ascent = glyph_ascent (instance, window); |
3667 cachel->descent = glyph_descent (instance, Qnil, DEFAULT_INDEX, window); | 3798 cachel->descent = glyph_descent (instance, window); |
3668 } | 3799 } |
3669 | 3800 |
3670 cachel->updated = 1; | 3801 cachel->updated = 1; |
3671 } | 3802 } |
3672 | 3803 |
3779 | 3910 |
3780 | 3911 |
3781 /***************************************************************************** | 3912 /***************************************************************************** |
3782 * subwindow cachel functions * | 3913 * subwindow cachel functions * |
3783 *****************************************************************************/ | 3914 *****************************************************************************/ |
3784 /* subwindows are curious in that you have to physically unmap them to | 3915 /* Subwindows are curious in that you have to physically unmap them to |
3785 not display them. It is problematic deciding what to do in | 3916 not display them. It is problematic deciding what to do in |
3786 redisplay. We have two caches - a per-window instance cache that | 3917 redisplay. We have two caches - a per-window instance cache that |
3787 keeps track of subwindows on a window, these are linked to their | 3918 keeps track of subwindows on a window, these are linked to their |
3788 instantiator in the hashtable and when the instantiator goes away | 3919 instantiator in the hashtable and when the instantiator goes away |
3789 we want the instance to go away also. However we also have a | 3920 we want the instance to go away also. However we also have a |
4049 || | 4180 || |
4050 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) | 4181 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) |
4051 return; | 4182 return; |
4052 | 4183 |
4053 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii)); | 4184 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii)); |
4054 } | 4185 /* We must update the window's size as it may have been changed by |
4055 | 4186 the the layout routines. We also do this here so that explicit resizing |
4187 from lisp does not result in synchronous updates. */ | |
4188 MAYBE_DEVMETH (XDEVICE (ii->device), resize_subwindow, (ii, | |
4189 IMAGE_INSTANCE_WIDTH (ii), | |
4190 IMAGE_INSTANCE_HEIGHT (ii))); | |
4191 } | |
4192 | |
4193 /* Update all the subwindows on a frame. */ | |
4056 void | 4194 void |
4057 update_frame_subwindows (struct frame *f) | 4195 update_frame_subwindows (struct frame *f) |
4058 { | 4196 { |
4059 int elt; | 4197 int elt; |
4060 | 4198 |
4092 elt = get_subwindow_cachel_index (f, subwindow); | 4230 elt = get_subwindow_cachel_index (f, subwindow); |
4093 cachel = Dynarr_atp (f->subwindow_cachels, elt); | 4231 cachel = Dynarr_atp (f->subwindow_cachels, elt); |
4094 | 4232 |
4095 /* make sure we don't get expose events */ | 4233 /* make sure we don't get expose events */ |
4096 register_ignored_expose (f, cachel->x, cachel->y, cachel->width, cachel->height); | 4234 register_ignored_expose (f, cachel->x, cachel->y, cachel->width, cachel->height); |
4097 cachel->x = -1; | 4235 cachel->x = ~0; |
4098 cachel->y = -1; | 4236 cachel->y = ~0; |
4099 cachel->being_displayed = 0; | 4237 cachel->being_displayed = 0; |
4100 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; | 4238 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; |
4101 | 4239 |
4102 MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii)); | 4240 MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii)); |
4103 } | 4241 } |
4131 cachel->y = y; | 4269 cachel->y = y; |
4132 cachel->width = dga->width; | 4270 cachel->width = dga->width; |
4133 cachel->height = dga->height; | 4271 cachel->height = dga->height; |
4134 cachel->being_displayed = 1; | 4272 cachel->being_displayed = 1; |
4135 | 4273 |
4274 /* This forces any pending display changes to happen to the image | |
4275 before we show it. I'm not sure whether or not we need mark as | |
4276 clean here, but for now we will. */ | |
4277 if (IMAGE_INSTANCE_DIRTYP (ii)) | |
4278 { | |
4279 update_subwindow (subwindow); | |
4280 IMAGE_INSTANCE_DIRTYP (ii) = 0; | |
4281 } | |
4282 | |
4136 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga)); | 4283 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga)); |
4137 } | 4284 } |
4138 | 4285 |
4139 static int | 4286 static int |
4140 subwindow_possible_dest_types (void) | 4287 subwindow_possible_dest_types (void) |
4163 ii->data = 0; | 4310 ii->data = 0; |
4164 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; | 4311 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; |
4165 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; | 4312 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; |
4166 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame; | 4313 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame; |
4167 | 4314 |
4168 /* this stuff may get overidden by the widget code */ | 4315 /* #### This stuff may get overidden by the widget code and is |
4316 actually really dumb now that we have dynamic geometry | |
4317 calculations. What should really happen is that the subwindow | |
4318 should query its child for and appropriate geometry. */ | |
4169 if (NILP (width)) | 4319 if (NILP (width)) |
4170 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20; | 4320 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20; |
4171 else | 4321 else |
4172 { | 4322 { |
4173 int w = 1; | 4323 int w = 1; |
4215 int neww, newh; | 4365 int neww, newh; |
4216 | 4366 |
4217 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); | 4367 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow); |
4218 | 4368 |
4219 if (NILP (width)) | 4369 if (NILP (width)) |
4220 neww = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow); | 4370 neww = XIMAGE_INSTANCE_WIDTH (subwindow); |
4221 else | 4371 else |
4222 neww = XINT (width); | 4372 neww = XINT (width); |
4223 | 4373 |
4224 if (NILP (height)) | 4374 if (NILP (height)) |
4225 newh = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow); | 4375 newh = XIMAGE_INSTANCE_HEIGHT (subwindow); |
4226 else | 4376 else |
4227 newh = XINT (height); | 4377 newh = XINT (height); |
4228 | 4378 |
4229 | 4379 /* The actual resizing gets done asychronously by |
4230 MAYBE_DEVMETH (XDEVICE (XIMAGE_INSTANCE_DEVICE (subwindow)), | 4380 update_subwindow. */ |
4231 resize_subwindow, (XIMAGE_INSTANCE (subwindow), neww, newh)); | 4381 XIMAGE_INSTANCE_HEIGHT (subwindow) = newh; |
4232 | 4382 XIMAGE_INSTANCE_WIDTH (subwindow) = neww; |
4233 XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow) = newh; | |
4234 XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow) = neww; | |
4235 | 4383 |
4236 /* need to update the cachels as redisplay will not do this */ | 4384 /* need to update the cachels as redisplay will not do this */ |
4237 update_subwindow_cachel (subwindow); | 4385 update_subwindow_cachel (subwindow); |
4238 | 4386 |
4239 return subwindow; | 4387 return subwindow; |
4368 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii); | 4516 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii); |
4369 /* We might need to kick redisplay at this point - but we | 4517 /* We might need to kick redisplay at this point - but we |
4370 also might not. */ | 4518 also might not. */ |
4371 MARK_DEVICE_FRAMES_GLYPHS_CHANGED | 4519 MARK_DEVICE_FRAMES_GLYPHS_CHANGED |
4372 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))); | 4520 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))); |
4373 IMAGE_INSTANCE_DIRTYP (ii) = 1; | 4521 MARK_IMAGE_INSTANCE_CHANGED (ii); |
4374 } | 4522 } |
4375 } | 4523 } |
4376 } | 4524 } |
4377 return Qnil; | 4525 return Qnil; |
4378 } | 4526 } |
4643 | 4791 |
4644 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string); | 4792 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string); |
4645 /* Do this so we can set strings. */ | 4793 /* Do this so we can set strings. */ |
4646 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text"); | 4794 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text"); |
4647 IIFORMAT_HAS_METHOD (text, set_property); | 4795 IIFORMAT_HAS_METHOD (text, set_property); |
4796 IIFORMAT_HAS_METHOD (text, query_geometry); | |
4648 | 4797 |
4649 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string"); | 4798 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string"); |
4650 | 4799 |
4651 IIFORMAT_HAS_METHOD (formatted_string, validate); | 4800 IIFORMAT_HAS_METHOD (formatted_string, validate); |
4652 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types); | 4801 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types); |
4812 */ ); | 4961 */ ); |
4813 Vcurrent_display_table = Fmake_specifier (Qdisplay_table); | 4962 Vcurrent_display_table = Fmake_specifier (Qdisplay_table); |
4814 set_specifier_fallback (Vcurrent_display_table, | 4963 set_specifier_fallback (Vcurrent_display_table, |
4815 list1 (Fcons (Qnil, Qnil))); | 4964 list1 (Fcons (Qnil, Qnil))); |
4816 set_specifier_caching (Vcurrent_display_table, | 4965 set_specifier_caching (Vcurrent_display_table, |
4817 slot_offset (struct window, | 4966 offsetof (struct window, display_table), |
4818 display_table), | |
4819 some_window_value_changed, | 4967 some_window_value_changed, |
4820 0, 0); | 4968 0, 0); |
4821 } | 4969 } |
4822 | 4970 |
4823 void | 4971 void |