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))