Mercurial > hg > xemacs-beta
comparison src/glyphs.c @ 450:98528da0b7fc r21-2-40
Import from CVS: tag r21-2-40
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:39:20 +0200 |
parents | 3078fd1074e8 |
children | 3d3049ae1304 |
comparison
equal
deleted
inserted
replaced
449:c83749d23eb5 | 450:98528da0b7fc |
---|---|
380 /* if the result is of a type that can't be instantiated | 380 /* if the result is of a type that can't be instantiated |
381 (e.g. a string when we're dealing with a pointer glyph), | 381 (e.g. a string when we're dealing with a pointer glyph), |
382 skip it. */ | 382 skip it. */ |
383 if (!(dest_mask & | 383 if (!(dest_mask & |
384 IIFORMAT_METH (decode_image_instantiator_format | 384 IIFORMAT_METH (decode_image_instantiator_format |
385 (XVECTOR_DATA (typevec)[0], ERROR_ME), | 385 (INSTANTIATOR_TYPE (typevec), ERROR_ME), |
386 possible_dest_types, ()))) | 386 possible_dest_types, ()))) |
387 continue; | 387 continue; |
388 if (fast_string_match (exp, 0, data, 0, -1, 0, ERROR_ME, 0) >= 0) | 388 if (fast_string_match (exp, 0, data, 0, -1, 0, ERROR_ME, 0) >= 0) |
389 { | 389 { |
390 if (!NILP (XCDR (XCDR (mapping)))) | 390 if (!NILP (XCDR (XCDR (mapping)))) |
687 Lisp_Object domain) | 687 Lisp_Object domain) |
688 { | 688 { |
689 int governing_domain; | 689 int governing_domain; |
690 | 690 |
691 struct image_instantiator_methods *meths = | 691 struct image_instantiator_methods *meths = |
692 decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], | 692 decode_image_instantiator_format (INSTANTIATOR_TYPE (instantiator), |
693 ERROR_ME); | 693 ERROR_ME); |
694 governing_domain = IIFORMAT_METH_OR_GIVEN (meths, governing_domain, (), | 694 governing_domain = IIFORMAT_METH_OR_GIVEN (meths, governing_domain, (), |
695 GOVERNING_DOMAIN_DEVICE); | 695 GOVERNING_DOMAIN_DEVICE); |
696 | 696 |
697 if (governing_domain == GOVERNING_DOMAIN_WINDOW | 697 if (governing_domain == GOVERNING_DOMAIN_WINDOW |
740 struct gcpro gcpro1; | 740 struct gcpro gcpro1; |
741 struct image_instantiator_methods *meths; | 741 struct image_instantiator_methods *meths; |
742 | 742 |
743 GCPRO1 (instantiator); | 743 GCPRO1 (instantiator); |
744 | 744 |
745 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], | 745 meths = decode_image_instantiator_format (INSTANTIATOR_TYPE (instantiator), |
746 ERROR_ME); | 746 ERROR_ME); |
747 RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize, | 747 RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize, |
748 (instantiator, contype, dest_mask), | 748 (instantiator, contype, dest_mask), |
749 instantiator)); | 749 instantiator)); |
750 } | 750 } |
763 Lisp_Image_Instance* p = XIMAGE_INSTANCE (ii); | 763 Lisp_Image_Instance* p = XIMAGE_INSTANCE (ii); |
764 struct image_instantiator_methods *meths, *device_meths; | 764 struct image_instantiator_methods *meths, *device_meths; |
765 struct gcpro gcpro1; | 765 struct gcpro gcpro1; |
766 | 766 |
767 GCPRO1 (ii); | 767 GCPRO1 (ii); |
768 if (!valid_image_instantiator_format_p (XVECTOR_DATA (instantiator)[0], | 768 if (!valid_image_instantiator_format_p (INSTANTIATOR_TYPE (instantiator), |
769 DOMAIN_DEVICE (governing_domain))) | 769 DOMAIN_DEVICE (governing_domain))) |
770 signal_simple_error | 770 signal_simple_error |
771 ("Image instantiator format is invalid in this locale.", | 771 ("Image instantiator format is invalid in this locale.", |
772 instantiator); | 772 instantiator); |
773 | 773 |
774 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], | 774 meths = decode_image_instantiator_format (INSTANTIATOR_TYPE (instantiator), |
775 ERROR_ME); | 775 ERROR_ME); |
776 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, | 776 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, |
777 pointer_bg, dest_mask, domain)); | 777 pointer_bg, dest_mask, domain)); |
778 | 778 |
779 /* Now do device specific instantiation. */ | 779 /* Now do device specific instantiation. */ |
780 device_meths = decode_device_ii_format (DOMAIN_DEVICE (governing_domain), | 780 device_meths = decode_device_ii_format (DOMAIN_DEVICE (governing_domain), |
781 XVECTOR_DATA (instantiator)[0], | 781 INSTANTIATOR_TYPE (instantiator), |
782 ERROR_ME_NOT); | 782 ERROR_ME_NOT); |
783 | 783 |
784 if (!HAS_IIFORMAT_METH_P (meths, instantiate) | 784 if (!HAS_IIFORMAT_METH_P (meths, instantiate) |
785 && (!device_meths || !HAS_IIFORMAT_METH_P (device_meths, instantiate))) | 785 && (!device_meths || !HAS_IIFORMAT_METH_P (device_meths, instantiate))) |
786 signal_simple_error | 786 signal_simple_error |
1467 DEVICE_TYPE (DOMAIN_XDEVICE (domain)), | 1467 DEVICE_TYPE (DOMAIN_XDEVICE (domain)), |
1468 make_int (dest_mask)); | 1468 make_int (dest_mask)); |
1469 GCPRO1 (data); | 1469 GCPRO1 (data); |
1470 /* After normalizing the data, it's always either an image instance (which | 1470 /* After normalizing the data, it's always either an image instance (which |
1471 we filtered out above) or a vector. */ | 1471 we filtered out above) or a vector. */ |
1472 if (EQ (XVECTOR_DATA (data)[0], Qinherit)) | 1472 if (EQ (INSTANTIATOR_TYPE (data), Qinherit)) |
1473 signal_simple_error ("Inheritance not allowed here", data); | 1473 signal_simple_error ("Inheritance not allowed here", data); |
1474 governing_domain = | 1474 governing_domain = |
1475 get_image_instantiator_governing_domain (data, domain); | 1475 get_image_instantiator_governing_domain (data, domain); |
1476 ii = instantiate_image_instantiator (governing_domain, domain, data, | 1476 ii = instantiate_image_instantiator (governing_domain, domain, data, |
1477 Qnil, Qnil, dest_mask, Qnil); | 1477 Qnil, Qnil, dest_mask, Qnil); |
1990 XIMAGE_INSTANCE_YOFFSET (image_instance) = yoffset; | 1990 XIMAGE_INSTANCE_YOFFSET (image_instance) = yoffset; |
1991 | 1991 |
1992 assert (XIMAGE_INSTANCE_YOFFSET (image_instance) >= 0 | 1992 assert (XIMAGE_INSTANCE_YOFFSET (image_instance) >= 0 |
1993 && XIMAGE_INSTANCE_XOFFSET (image_instance) >= 0); | 1993 && XIMAGE_INSTANCE_XOFFSET (image_instance) >= 0); |
1994 | 1994 |
1995 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); | |
1996 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); | |
1997 | |
1998 /* If geometry is unspecified then get some reasonable values for it. */ | 1995 /* If geometry is unspecified then get some reasonable values for it. */ |
1999 if (width == IMAGE_UNSPECIFIED_GEOMETRY | 1996 if (width == IMAGE_UNSPECIFIED_GEOMETRY |
2000 || | 1997 || |
2001 height == IMAGE_UNSPECIFIED_GEOMETRY) | 1998 height == IMAGE_UNSPECIFIED_GEOMETRY) |
2002 { | 1999 { |
2003 int dwidth = IMAGE_UNSPECIFIED_GEOMETRY; | 2000 int dwidth = IMAGE_UNSPECIFIED_GEOMETRY; |
2004 int dheight = IMAGE_UNSPECIFIED_GEOMETRY; | 2001 int dheight = IMAGE_UNSPECIFIED_GEOMETRY; |
2005 | |
2006 /* Get the desired geometry. */ | 2002 /* Get the desired geometry. */ |
2007 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | 2003 image_instance_query_geometry (image_instance, |
2008 { | 2004 &dwidth, &dheight, |
2009 IIFORMAT_METH (meths, query_geometry, (image_instance, &dwidth, &dheight, | 2005 IMAGE_DESIRED_GEOMETRY, |
2010 IMAGE_DESIRED_GEOMETRY, | 2006 domain); |
2011 domain)); | |
2012 } | |
2013 else | |
2014 { | |
2015 dwidth = IMAGE_INSTANCE_WIDTH (ii); | |
2016 dheight = IMAGE_INSTANCE_HEIGHT (ii); | |
2017 } | |
2018 | |
2019 /* Compare with allowed geometry. */ | 2007 /* Compare with allowed geometry. */ |
2020 if (width == IMAGE_UNSPECIFIED_GEOMETRY) | 2008 if (width == IMAGE_UNSPECIFIED_GEOMETRY) |
2021 width = dwidth; | 2009 width = dwidth; |
2022 if (height == IMAGE_UNSPECIFIED_GEOMETRY) | 2010 if (height == IMAGE_UNSPECIFIED_GEOMETRY) |
2023 height = dheight; | 2011 height = dheight; |
2040 } | 2028 } |
2041 | 2029 |
2042 IMAGE_INSTANCE_WIDTH (ii) = width; | 2030 IMAGE_INSTANCE_WIDTH (ii) = width; |
2043 IMAGE_INSTANCE_HEIGHT (ii) = height; | 2031 IMAGE_INSTANCE_HEIGHT (ii) = height; |
2044 | 2032 |
2045 if (IIFORMAT_METH_OR_GIVEN (meths, layout, | 2033 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); |
2046 (image_instance, width, height, xoffset, yoffset, | 2034 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); |
2047 domain), 1)) | 2035 |
2048 /* Do not clear the dirty flag here - redisplay will do this for | 2036 MAYBE_IIFORMAT_METH (meths, layout, |
2049 us at the end. */ | 2037 (image_instance, width, height, xoffset, yoffset, |
2050 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0; | 2038 domain)); |
2039 /* Do not clear the dirty flag here - redisplay will do this for | |
2040 us at the end. */ | |
2041 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0; | |
2051 } | 2042 } |
2052 | 2043 |
2053 /* Update an image instance from its changed instantiator. */ | 2044 /* Update an image instance from its changed instantiator. */ |
2054 static void | 2045 static void |
2055 update_image_instance (Lisp_Object image_instance, | 2046 update_image_instance (Lisp_Object image_instance, |
3052 | 3043 |
3053 mark_object (IMAGE_SPECIFIER_ATTACHEE (image)); | 3044 mark_object (IMAGE_SPECIFIER_ATTACHEE (image)); |
3054 mark_object (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image)); | 3045 mark_object (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image)); |
3055 } | 3046 } |
3056 | 3047 |
3048 static int | |
3049 instantiator_eq_equal (Lisp_Object obj1, Lisp_Object obj2) | |
3050 { | |
3051 if (EQ (obj1, obj2)) | |
3052 return 1; | |
3053 | |
3054 else if (CONSP (obj1) && CONSP (obj2)) | |
3055 { | |
3056 return instantiator_eq_equal (XCAR (obj1), XCAR (obj2)) | |
3057 && | |
3058 instantiator_eq_equal (XCDR (obj1), XCDR (obj2)); | |
3059 } | |
3060 return 0; | |
3061 } | |
3062 | |
3063 static hashcode_t | |
3064 instantiator_eq_hash (Lisp_Object obj) | |
3065 { | |
3066 if (CONSP (obj)) | |
3067 { | |
3068 /* no point in worrying about tail recursion, since we're not | |
3069 going very deep */ | |
3070 return HASH2 (instantiator_eq_hash (XCAR (obj)), | |
3071 instantiator_eq_hash (XCDR (obj))); | |
3072 } | |
3073 return LISP_HASH (obj); | |
3074 } | |
3075 | |
3076 /* We need a special hash table for storing image instances. */ | |
3077 Lisp_Object | |
3078 make_image_instance_cache_hash_table (void) | |
3079 { | |
3080 return make_general_lisp_hash_table | |
3081 (instantiator_eq_hash, instantiator_eq_equal, | |
3082 30, -1.0, -1.0, | |
3083 HASH_TABLE_KEY_CAR_VALUE_WEAK); | |
3084 } | |
3085 | |
3057 static Lisp_Object | 3086 static Lisp_Object |
3058 image_instantiate_cache_result (Lisp_Object locative) | 3087 image_instantiate_cache_result (Lisp_Object locative) |
3059 { | 3088 { |
3060 /* locative = (instance instantiator . subtable) | 3089 /* locative = (instance instantiator . subtable) |
3061 | 3090 |
3108 else | 3137 else |
3109 signal_simple_error_2 ("Wrong domain for image instance", | 3138 signal_simple_error_2 ("Wrong domain for image instance", |
3110 instantiator, domain); | 3139 instantiator, domain); |
3111 } | 3140 } |
3112 else if (VECTORP (instantiator) | 3141 else if (VECTORP (instantiator) |
3113 && EQ (XVECTOR_DATA (instantiator)[0], Qinherit)) | 3142 && EQ (INSTANTIATOR_TYPE (instantiator), Qinherit)) |
3114 { | 3143 { |
3115 assert (XVECTOR_LENGTH (instantiator) == 3); | 3144 assert (XVECTOR_LENGTH (instantiator) == 3); |
3116 return (FACE_PROPERTY_INSTANCE | 3145 return (FACE_PROPERTY_INSTANCE |
3117 (Fget_face (XVECTOR_DATA (instantiator)[2]), | 3146 (Fget_face (XVECTOR_DATA (instantiator)[2]), |
3118 Qbackground_pixmap, domain, 0, depth)); | 3147 Qbackground_pixmap, domain, 0, depth)); |
3119 } | 3148 } |
3120 else | 3149 else |
3121 { | 3150 { |
3122 Lisp_Object instance = Qnil; | 3151 Lisp_Object instance = Qnil; |
3123 Lisp_Object subtable = Qnil; | 3152 Lisp_Object subtable = Qnil; |
3124 Lisp_Object ls3 = Qnil; | 3153 /* #### Should this be GCPRO'd? */ |
3154 Lisp_Object hash_key = Qnil; | |
3125 Lisp_Object pointer_fg = Qnil; | 3155 Lisp_Object pointer_fg = Qnil; |
3126 Lisp_Object pointer_bg = Qnil; | 3156 Lisp_Object pointer_bg = Qnil; |
3127 Lisp_Object governing_domain = | 3157 Lisp_Object governing_domain = |
3128 get_image_instantiator_governing_domain (instantiator, domain); | 3158 get_image_instantiator_governing_domain (instantiator, domain); |
3129 struct gcpro gcpro1; | 3159 struct gcpro gcpro1; |
3137 | 3167 |
3138 if (pointerp) | 3168 if (pointerp) |
3139 { | 3169 { |
3140 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain); | 3170 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain); |
3141 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain); | 3171 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain); |
3142 ls3 = list3 (glyph, pointer_fg, pointer_bg); | 3172 hash_key = list4 (glyph, INSTANTIATOR_TYPE (instantiator), |
3173 pointer_fg, pointer_bg); | |
3143 } | 3174 } |
3175 else | |
3176 /* We cannot simply key on the glyph since fallbacks could use | |
3177 the same glyph but have a totally different instantiator | |
3178 type. Thus we key on the glyph and the type (but not any | |
3179 other parts of the instantiator. */ | |
3180 hash_key = list2 (glyph, INSTANTIATOR_TYPE (instantiator)); | |
3144 | 3181 |
3145 /* First look in the device cache. */ | 3182 /* First look in the device cache. */ |
3146 if (DEVICEP (governing_domain)) | 3183 if (DEVICEP (governing_domain)) |
3147 { | 3184 { |
3148 subtable = Fgethash (make_int (dest_mask), | 3185 subtable = Fgethash (make_int (dest_mask), |
3165 | 3202 |
3166 However, if the image-instance could be a pointer, we | 3203 However, if the image-instance could be a pointer, we |
3167 have to use EQUAL because we massaged the | 3204 have to use EQUAL because we massaged the |
3168 instantiator into a cons3 also containing the | 3205 instantiator into a cons3 also containing the |
3169 foreground and background of the pointer face. */ | 3206 foreground and background of the pointer face. */ |
3170 | 3207 subtable = make_image_instance_cache_hash_table (); |
3171 subtable = make_lisp_hash_table | 3208 |
3172 (20, pointerp ? HASH_TABLE_KEY_CAR_WEAK | |
3173 : HASH_TABLE_KEY_WEAK, | |
3174 pointerp ? HASH_TABLE_EQUAL | |
3175 : HASH_TABLE_EQ); | |
3176 Fputhash (make_int (dest_mask), subtable, | 3209 Fputhash (make_int (dest_mask), subtable, |
3177 XDEVICE (governing_domain)->image_instance_cache); | 3210 XDEVICE (governing_domain)->image_instance_cache); |
3178 instance = Qunbound; | 3211 instance = Qunbound; |
3179 } | 3212 } |
3180 else | 3213 else |
3181 { | 3214 { |
3182 instance = Fgethash (pointerp ? ls3 : glyph, | 3215 instance = Fgethash (hash_key, subtable, Qunbound); |
3183 subtable, Qunbound); | |
3184 } | 3216 } |
3185 } | 3217 } |
3186 else if (WINDOWP (governing_domain)) | 3218 else if (WINDOWP (governing_domain)) |
3187 { | 3219 { |
3188 /* Subwindows have a per-window cache and have to be treated | 3220 /* Subwindows have a per-window cache and have to be treated |
3189 differently. */ | 3221 differently. */ |
3190 instance = | 3222 instance = |
3191 Fgethash (pointerp ? ls3 : glyph, | 3223 Fgethash (hash_key, |
3192 XWINDOW (governing_domain)->subwindow_instance_cache, | 3224 XWINDOW (governing_domain)->subwindow_instance_cache, |
3193 Qunbound); | 3225 Qunbound); |
3194 } | 3226 } |
3195 else | 3227 else |
3196 abort (); /* We're not allowed anything else currently. */ | 3228 abort (); /* We're not allowed anything else currently. */ |
3199 one. */ | 3231 one. */ |
3200 if (UNBOUNDP (instance)) | 3232 if (UNBOUNDP (instance)) |
3201 { | 3233 { |
3202 Lisp_Object locative = | 3234 Lisp_Object locative = |
3203 noseeum_cons (Qnil, | 3235 noseeum_cons (Qnil, |
3204 noseeum_cons (pointerp ? ls3 : glyph, | 3236 noseeum_cons (hash_key, |
3205 DEVICEP (governing_domain) ? subtable | 3237 DEVICEP (governing_domain) ? subtable |
3206 : XWINDOW (governing_domain) | 3238 : XWINDOW (governing_domain) |
3207 ->subwindow_instance_cache)); | 3239 ->subwindow_instance_cache)); |
3208 int speccount = specpdl_depth (); | 3240 int speccount = specpdl_depth (); |
3209 | 3241 |
3232 #endif | 3264 #endif |
3233 unbind_to (speccount, Qnil); | 3265 unbind_to (speccount, Qnil); |
3234 #ifdef ERROR_CHECK_GLYPHS | 3266 #ifdef ERROR_CHECK_GLYPHS |
3235 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) | 3267 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) |
3236 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) | 3268 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) |
3237 assert (EQ (Fgethash ((pointerp ? ls3 : glyph), | 3269 assert (EQ (Fgethash (hash_key, |
3238 XWINDOW (governing_domain) | 3270 XWINDOW (governing_domain) |
3239 ->subwindow_instance_cache, | 3271 ->subwindow_instance_cache, |
3240 Qunbound), instance)); | 3272 Qunbound), instance)); |
3241 #endif | 3273 #endif |
3242 } | 3274 } |
3256 changes to the instantiator, but currently only copes | 3288 changes to the instantiator, but currently only copes |
3257 with the most used properties. This means that it is | 3289 with the most used properties. This means that it is |
3258 possible to make changes that don't get reflected in the | 3290 possible to make changes that don't get reflected in the |
3259 display. */ | 3291 display. */ |
3260 update_image_instance (instance, instantiator); | 3292 update_image_instance (instance, instantiator); |
3261 free_list (ls3); | 3293 free_list (hash_key); |
3262 } | 3294 } |
3263 | 3295 |
3264 #ifdef ERROR_CHECK_GLYPHS | 3296 #ifdef ERROR_CHECK_GLYPHS |
3265 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) | 3297 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance)) |
3266 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) | 3298 & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) |