diff options
| author | Po Lu | 2022-12-11 09:32:20 +0800 |
|---|---|---|
| committer | Po Lu | 2022-12-11 09:32:47 +0800 |
| commit | 05ece1eb8b7ce28d366d02df89449d453be8d37e (patch) | |
| tree | d754b2d292ce8f9bc157cb508fdf6e93b939fb68 /src | |
| parent | 7013b0179cbe5cce19e114d7673770d1425d3005 (diff) | |
| download | emacs-05ece1eb8b7ce28d366d02df89449d453be8d37e.tar.gz emacs-05ece1eb8b7ce28d366d02df89449d453be8d37e.zip | |
Improve last change to xfaces.c
* src/xfaces.c (font_unset_attribute): New function.
(realize_gui_face): Improve commentary and use list instead of
bitmask.
(syms_of_xfaces): Get rid of bitmask. Replace it by a list,
there is no reason any user should have to think about bitmasks
in Emacs lisp.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfaces.c | 115 |
1 files changed, 61 insertions, 54 deletions
diff --git a/src/xfaces.c b/src/xfaces.c index 643f4365896..88d3a79f8c0 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -6014,6 +6014,23 @@ realize_non_ascii_face (struct frame *f, Lisp_Object font_object, | |||
| 6014 | } | 6014 | } |
| 6015 | #endif /* HAVE_WINDOW_SYSTEM */ | 6015 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 6016 | 6016 | ||
| 6017 | /* Remove the attribute at INDEX from the font object if SYMBOL | ||
| 6018 | appears in `font-fallback-ignored-attributes'. */ | ||
| 6019 | |||
| 6020 | static void | ||
| 6021 | font_unset_attribute (Lisp_Object font_object, enum font_property_index index, | ||
| 6022 | Lisp_Object symbol) | ||
| 6023 | { | ||
| 6024 | Lisp_Object tail; | ||
| 6025 | |||
| 6026 | tail = Vfont_fallback_ignored_attributes; | ||
| 6027 | |||
| 6028 | FOR_EACH_TAIL_SAFE (tail) | ||
| 6029 | { | ||
| 6030 | if (EQ (XCAR (tail), symbol)) | ||
| 6031 | ASET (font_object, index, Qnil); | ||
| 6032 | } | ||
| 6033 | } | ||
| 6017 | 6034 | ||
| 6018 | /* Realize the fully-specified face with attributes ATTRS in face | 6035 | /* Realize the fully-specified face with attributes ATTRS in face |
| 6019 | cache CACHE for ASCII characters. Do it for GUI frame CACHE->f. | 6036 | cache CACHE for ASCII characters. Do it for GUI frame CACHE->f. |
| @@ -6029,7 +6046,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] | |||
| 6029 | #ifdef HAVE_WINDOW_SYSTEM | 6046 | #ifdef HAVE_WINDOW_SYSTEM |
| 6030 | struct face *default_face; | 6047 | struct face *default_face; |
| 6031 | struct frame *f; | 6048 | struct frame *f; |
| 6032 | Lisp_Object stipple, underline, overline, strike_through, box; | 6049 | Lisp_Object stipple, underline, overline, strike_through, box, spec; |
| 6033 | 6050 | ||
| 6034 | eassert (FRAME_WINDOW_P (cache->f)); | 6051 | eassert (FRAME_WINDOW_P (cache->f)); |
| 6035 | 6052 | ||
| @@ -6072,39 +6089,34 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] | |||
| 6072 | } | 6089 | } |
| 6073 | if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) | 6090 | if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) |
| 6074 | { | 6091 | { |
| 6075 | Lisp_Object spec = copy_font_spec (attrs[LFACE_FONT_INDEX]); | 6092 | spec = copy_font_spec (attrs[LFACE_FONT_INDEX]); |
| 6076 | #define MAYBE_UNSET_ATTRIBUTE(ATTR) \ | 6093 | |
| 6077 | if (realize_gui_face_ignored_spec_attributes \ | 6094 | /* Unset several values in SPEC, usually the width, slant, |
| 6078 | & (1 << FONT_##ATTR##_INDEX)) \ | 6095 | and weight. The best possible values for these |
| 6079 | ASET (spec, FONT_##ATTR##_INDEX, Qnil); | 6096 | attributes is determined in font_find_for_lface, called |
| 6080 | /* The default value of | 6097 | by font_load_for_lface, when the candidate list returned |
| 6081 | realize_gui_face_ignored_spec_attributes unsets the | 6098 | by font_list_entities is sorted by font_select_entity |
| 6082 | weight, slant and width in spec. The best possible | 6099 | (which calls font_sort_entities, which calls font_score). |
| 6083 | values for these attributes is determined in | 6100 | If these attributes are not unset here, the candidate |
| 6084 | font_find_for_lface, called by font_load_for_lface, when | 6101 | font list returned by font_list_entities only contains |
| 6085 | the candidate list returned by font_list_entities is | 6102 | fonts that are exact matches for these weight, slant and |
| 6086 | sorted by font_select_entity (which calls | 6103 | width attributes, which leads to suboptimal or wrong font |
| 6087 | font_sort_entities, which calls font_score). If these | 6104 | choices. (bug#5934) */ |
| 6088 | attributes are not unset here, the candidate font list | 6105 | font_unset_attribute (spec, FONT_WEIGHT_INDEX, QCwidth); |
| 6089 | returned by font_list_entities only contains fonts that | 6106 | font_unset_attribute (spec, FONT_SLANT_INDEX, QCslant); |
| 6090 | are exact matches for these weight, slant and width | 6107 | font_unset_attribute (spec, FONT_WIDTH_INDEX, QCwidth); |
| 6091 | attributes, which leads to suboptimal or wrong font | ||
| 6092 | choices. See bug#59347. */ | ||
| 6093 | MAYBE_UNSET_ATTRIBUTE (WEIGHT); | ||
| 6094 | MAYBE_UNSET_ATTRIBUTE (SLANT); | ||
| 6095 | MAYBE_UNSET_ATTRIBUTE (WIDTH); | ||
| 6096 | /* Also allow unsetting other attributes for debugging | 6108 | /* Also allow unsetting other attributes for debugging |
| 6097 | purposes. */ | 6109 | purposes. But not FONT_EXTRA_INDEX; that is not safe to |
| 6098 | MAYBE_UNSET_ATTRIBUTE (FAMILY); | 6110 | touch in the Haiku font backend. */ |
| 6099 | MAYBE_UNSET_ATTRIBUTE (FOUNDRY); | 6111 | font_unset_attribute (spec, FONT_FAMILY_INDEX, QCfamily); |
| 6100 | MAYBE_UNSET_ATTRIBUTE (REGISTRY); | 6112 | font_unset_attribute (spec, FONT_FOUNDRY_INDEX, QCfoundry); |
| 6101 | MAYBE_UNSET_ATTRIBUTE (ADSTYLE); | 6113 | font_unset_attribute (spec, FONT_REGISTRY_INDEX, QCregistry); |
| 6102 | MAYBE_UNSET_ATTRIBUTE (SIZE); | 6114 | font_unset_attribute (spec, FONT_ADSTYLE_INDEX, QCadstyle); |
| 6103 | MAYBE_UNSET_ATTRIBUTE (DPI); | 6115 | font_unset_attribute (spec, FONT_SIZE_INDEX, QCsize); |
| 6104 | MAYBE_UNSET_ATTRIBUTE (SPACING); | 6116 | font_unset_attribute (spec, FONT_DPI_INDEX, QCdpi); |
| 6105 | MAYBE_UNSET_ATTRIBUTE (AVGWIDTH); | 6117 | font_unset_attribute (spec, FONT_SPACING_INDEX, QCspacing); |
| 6106 | MAYBE_UNSET_ATTRIBUTE (EXTRA); | 6118 | font_unset_attribute (spec, FONT_AVGWIDTH_INDEX, QCavgwidth); |
| 6107 | #undef MAYBE_UNSET_ATTRIBUTE | 6119 | |
| 6108 | attrs[LFACE_FONT_INDEX] = font_load_for_lface (f, attrs, spec); | 6120 | attrs[LFACE_FONT_INDEX] = font_load_for_lface (f, attrs, spec); |
| 6109 | } | 6121 | } |
| 6110 | if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) | 6122 | if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) |
| @@ -7394,27 +7406,22 @@ Lisp programs that change the value of this variable should also | |||
| 7394 | clear the face cache, see `clear-face-cache'. */); | 7406 | clear the face cache, see `clear-face-cache'. */); |
| 7395 | face_near_same_color_threshold = 30000; | 7407 | face_near_same_color_threshold = 30000; |
| 7396 | 7408 | ||
| 7397 | DEFVAR_INT ("realize-gui-face-ignored-spec-attributes", | 7409 | DEFVAR_LISP ("font-fallback-ignored-attributes", |
| 7398 | realize_gui_face_ignored_spec_attributes, | 7410 | Vfont_fallback_ignored_attributes, |
| 7399 | doc: /* Ignored font-spec attributes in realize_gui_face. | 7411 | doc: /* A list of face attributes to ignore. |
| 7400 | 7412 | ||
| 7401 | The value is an integer number and represents a bit mask. | 7413 | List of font-related face attributes to ignore when realizing a face. |
| 7402 | The attribute corresponding to each bit that is set is cleared in | 7414 | This is a list of symbols representing face attributes that will be |
| 7403 | realize_gui_face. The bits are: 1 = :foundry, 2 = :family, | 7415 | ignored by Emacs when realizing a face, and an exact match couldn't be |
| 7404 | 3 = :adstyle, 4 = :registry, 5 = :weight, 6 = :slant, 7 = :width, | 7416 | found for its preferred font. For example: |
| 7405 | 8 = :size, 9 = :dpi, 10 = :spacing, 11 = :avgwidth, 12 = extra | 7417 | |
| 7406 | attributes (:name, :script, :lang and :otf). | 7418 | (:weight :slant :width) |
| 7407 | 7419 | ||
| 7408 | Bits 5 to 7 are set in the default value. When these bits are not | 7420 | tells Emacs to ignore the `:weight', `:slant' and `:width' face |
| 7409 | set, and when the font chosen for the default face has a weight, slant | 7421 | attributes when searching for a font and an exact match could not be |
| 7410 | or width that is not supported by other available fonts on the system, | 7422 | found for the font attributes specified in the face being realized. */); |
| 7411 | such as 'medium', Emacs may select suboptimal fonts for other faces. | 7423 | Vfont_fallback_ignored_attributes |
| 7412 | 7424 | = list3 (QCwidth, QCslant, QCwidth); | |
| 7413 | There is no reason to change that value except for debugging purposes. */); | ||
| 7414 | realize_gui_face_ignored_spec_attributes = | ||
| 7415 | (1 << FONT_WEIGHT_INDEX) | | ||
| 7416 | (1 << FONT_SLANT_INDEX) | | ||
| 7417 | (1 << FONT_WIDTH_INDEX); | ||
| 7418 | 7425 | ||
| 7419 | #ifdef HAVE_WINDOW_SYSTEM | 7426 | #ifdef HAVE_WINDOW_SYSTEM |
| 7420 | defsubr (&Sbitmap_spec_p); | 7427 | defsubr (&Sbitmap_spec_p); |