diff options
| author | Kenichi Handa | 2008-05-14 01:25:55 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2008-05-14 01:25:55 +0000 |
| commit | 35027d0ca6108382edc5598d933f555808d43dfb (patch) | |
| tree | 4eb6d888f8e02158f2d1db7ce1ebacf84155ff3c /src | |
| parent | 875003e5bce60bfda5b853f8512099cf16e8b169 (diff) | |
| download | emacs-35027d0ca6108382edc5598d933f555808d43dfb.tar.gz emacs-35027d0ca6108382edc5598d933f555808d43dfb.zip | |
Include <strings.h>.
(enable_font_backend): Delete it.
(Qfont_spec, Qfont_entity, Qfont_object): New variables.
(CHECK_VALIDATE_FONT_SPEC): Delete it.
(PT_PER_INCH, POINT_TO_PIXEL, PIXEL_TO_POINT): Moved to font.h.
(null_string): Delete it.
(null_vector): Make it static.
(font_family_alist): Delete it.
(Qnormal): Extern it.
(QCextra, QClanguage): Delete it.
(QClang, QCavgwidth, QCfont_entity, QCfc_unknown_spec): New
variables.
(font_make_spec, font_make_entity, font_make_object)
(font_intern_prop): Renamed from intern_downcase. Don't downcase
the string. Callers changed.
(font_pixel_size): Adjusted for the format change of font-related
objects.
(prop_name_to_numeric, prop_numeric_to_name): Delete them.
(font_style_to_value, font_style_symbolic): New function.
(build_font_family_alist): Delete it.
(font_registry_charsets): Use Fassoc_string instead of
assq_no_quit.
(font_prop_validate_symbol): Don't return null_string.
(font_prop_validate_style): Adjusted for the change of
style-related values in a font vector.
(font_property_table): Delete entries for QClangauge and
QCantialias, add entries for QCavgwidth.
(get_font_prop_index): Delete the 2nd argument FROM.
(font_prop_validate): Arguments changed.
(font_put_extra): Adjusted for the change of font-related objects.
(font_expand_wildcards, font_parse_xlfd, font_unparse_xlfd)
(font_parse_fcname, font_unparse_fcname)
(font_prepare_composition): Likewise.
(font_parse_family_registry): Renamed from font_merge_old_spec.
(otf_open): Delete the 1st arg entity.
(font_otf_capability): Adjusted for the above change.
(font_score): New arg alternate_families. Adjusted for the change
of font-related objects.
(font_sort_entites): New arg best_only.
(font_symbolic_weight, font_symbolic_slant, font_symbolic_width):
Delete them.
(font_match_p): Check alternate families.
(font_find_object): Delete it.
(font_check_object): New function.
(font_clear_cache): Adjusted for the change of font-related
objects.
(font_delete_unmatched): New arg.
(font_list_entities): Call font_driver->list with a spec that
doesn't specify style-related properties.
(font_matching_entity): Arguments changed. Caller changed.
(font_open_entity): Adjusted for the change of font-related
objects.
(font_close_object, font_has_char, font_encode_char)
(font_get_name, font_get_spec): Likewise.
(font_spec_from_name, font_clear_prop, font_update_lface): New
functions.
(font_find_for_lface, font_open_for_lface, font_load_for_lface):
(font_prepare_for_face, font_done_for_face, font_open_by_name)
(font_at): Adjusted for the change of font-related objects.
(font_range): New function.
(Ffontp, Ffont_spec, Ffont_get, Ffont_put, Flist_fonts)
(Ffont_xlfd_name): Adjusted for the change of font-related
objects.
(Fcopy_font_spec, Fmerge_font_spec): New function.
(Ffont_family_list): Renamed from list-families.
(Finternal_set_font_style_table): Arguments changed.
(Ffont_fill_gstring, Ffont_shape_text, Fopen_font)
(Ffont_drive_otf, Fquery_font, Ffont_match_p): Adjusted for the
change of font-related objects.
(syms_of_font): Delete "ifdef USE_FONT_BACKEND". DEFSYM new
symboles.
Diffstat (limited to 'src')
| -rw-r--r-- | src/font.c | 2354 |
1 files changed, 1265 insertions, 1089 deletions
diff --git a/src/font.c b/src/font.c index 5ed33fcf4b4..c3a4af928a5 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -24,6 +24,7 @@ Boston, MA 02110-1301, USA. */ | |||
| 24 | #include <config.h> | 24 | #include <config.h> |
| 25 | #include <stdio.h> | 25 | #include <stdio.h> |
| 26 | #include <stdlib.h> | 26 | #include <stdlib.h> |
| 27 | #include <strings.h> | ||
| 27 | #include <ctype.h> | 28 | #include <ctype.h> |
| 28 | #ifdef HAVE_M17N_FLT | 29 | #ifdef HAVE_M17N_FLT |
| 29 | #include <m17n-flt.h> | 30 | #include <m17n-flt.h> |
| @@ -63,64 +64,34 @@ Boston, MA 02110-1301, USA. */ | |||
| 63 | #define xassert(X) (void) 0 | 64 | #define xassert(X) (void) 0 |
| 64 | #endif | 65 | #endif |
| 65 | 66 | ||
| 66 | int enable_font_backend; | 67 | Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; |
| 67 | 68 | ||
| 68 | Lisp_Object Qopentype; | 69 | Lisp_Object Qopentype; |
| 69 | 70 | ||
| 70 | /* Important character set symbols. */ | 71 | /* Important character set strings. */ |
| 71 | Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip; | 72 | Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip; |
| 72 | 73 | ||
| 73 | /* Like CHECK_FONT_SPEC but also validate properties of the font-spec, | ||
| 74 | and set X to the validated result. */ | ||
| 75 | |||
| 76 | #define CHECK_VALIDATE_FONT_SPEC(x) \ | ||
| 77 | do { \ | ||
| 78 | if (! FONT_SPEC_P (x)) wrong_type_argument (Qfont, x); \ | ||
| 79 | x = font_prop_validate (x); \ | ||
| 80 | } while (0) | ||
| 81 | |||
| 82 | /* Number of pt per inch (from the TeXbook). */ | ||
| 83 | #define PT_PER_INCH 72.27 | ||
| 84 | |||
| 85 | /* Return a pixel size (integer) corresponding to POINT size (double) | ||
| 86 | on resolution DPI. */ | ||
| 87 | #define POINT_TO_PIXEL(POINT, DPI) ((POINT) * (DPI) / PT_PER_INCH + 0.5) | ||
| 88 | |||
| 89 | /* Return a point size (double) corresponding to POINT size (integer) | ||
| 90 | on resolution DPI. */ | ||
| 91 | #define PIXEL_TO_POINT(PIXEL, DPI) ((PIXEL) * PT_PER_INCH * 10 / (DPI) + 0.5) | ||
| 92 | |||
| 93 | /* Special string of zero length. It is used to specify a NULL name | ||
| 94 | in a font properties (e.g. adstyle). We don't use the symbol of | ||
| 95 | NULL name because it's confusing (Lisp printer prints nothing for | ||
| 96 | it). */ | ||
| 97 | Lisp_Object null_string; | ||
| 98 | |||
| 99 | /* Special vector of zero length. This is repeatedly used by (struct | 74 | /* Special vector of zero length. This is repeatedly used by (struct |
| 100 | font_driver *)->list when a specified font is not found. */ | 75 | font_driver *)->list when a specified font is not found. */ |
| 101 | Lisp_Object null_vector; | 76 | static Lisp_Object null_vector; |
| 102 | 77 | ||
| 103 | /* Vector of 3 elements. Each element is an alist for one of font | 78 | /* Vector of 3 elements. Each element is a vector for one of font |
| 104 | style properties (weight, slant, width). Each alist contains a | 79 | style properties (weight, slant, width). The vector contains a |
| 105 | mapping between symbolic property values (e.g. `medium' for weight) | 80 | mapping between symbolic property values (e.g. `medium' for weight) |
| 106 | and numeric property values (e.g. 100). So, it looks like this: | 81 | and numeric property values (e.g. 100). So, it looks like this: |
| 107 | [((thin . 0) ... (heavy . 210)) | 82 | [[(ultra-light . 20) ... (black . 210)] |
| 108 | ((ro . 0) ... (ot . 210)) | 83 | [(reverse-oblique . 0) ... (oblique . 210)] |
| 109 | ((ultracondensed . 50) ... (wide . 200))] */ | 84 | [(ultra-contains . 50) ... (wide . 200)]] */ |
| 110 | static Lisp_Object font_style_table; | 85 | static Lisp_Object font_style_table; |
| 111 | 86 | ||
| 112 | /* Alist of font family vs the corresponding aliases. | 87 | extern Lisp_Object Qnormal; |
| 113 | Each element has this form: | ||
| 114 | (FAMILY ALIAS1 ALIAS2 ...) */ | ||
| 115 | |||
| 116 | static Lisp_Object font_family_alist; | ||
| 117 | 88 | ||
| 118 | /* Symbols representing keys of normal font properties. */ | 89 | /* Symbols representing keys of normal font properties. */ |
| 119 | extern Lisp_Object QCtype, QCfamily, QCweight, QCslant, QCwidth, QCsize, QCname; | 90 | extern Lisp_Object QCtype, QCfamily, QCweight, QCslant, QCwidth, QCsize, QCname; |
| 120 | Lisp_Object QCfoundry, QCadstyle, QCregistry, QCextra; | 91 | Lisp_Object QCfoundry, QCadstyle, QCregistry; |
| 121 | /* Symbols representing keys of font extra info. */ | 92 | /* Symbols representing keys of font extra info. */ |
| 122 | Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClanguage, QCscript; | 93 | Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript, QCavgwidth; |
| 123 | Lisp_Object QCantialias; | 94 | Lisp_Object QCantialias, QCfont_entity, QCfc_unknown_spec; |
| 124 | /* Symbols representing values of font spacing property. */ | 95 | /* Symbols representing values of font spacing property. */ |
| 125 | Lisp_Object Qc, Qm, Qp, Qd; | 96 | Lisp_Object Qc, Qm, Qp, Qd; |
| 126 | 97 | ||
| @@ -147,16 +118,92 @@ static Lisp_Object font_charset_alist; | |||
| 147 | here. */ | 118 | here. */ |
| 148 | static struct font_driver_list *font_driver_list; | 119 | static struct font_driver_list *font_driver_list; |
| 149 | 120 | ||
| 121 | |||
| 122 | |||
| 123 | /* Creaters of font-related Lisp object. */ | ||
| 124 | |||
| 125 | Lisp_Object | ||
| 126 | font_make_spec () | ||
| 127 | { | ||
| 128 | Lisp_Object font_spec; | ||
| 129 | struct font_spec *spec | ||
| 130 | = ((struct font_spec *) | ||
| 131 | allocate_pseudovector (VECSIZE (struct font_spec), | ||
| 132 | FONT_SPEC_MAX, PVEC_FONT)); | ||
| 133 | XSETFONT (font_spec, spec); | ||
| 134 | return font_spec; | ||
| 135 | } | ||
| 136 | |||
| 137 | Lisp_Object | ||
| 138 | font_make_entity () | ||
| 139 | { | ||
| 140 | Lisp_Object font_entity; | ||
| 141 | struct font_entity *entity | ||
| 142 | = ((struct font_entity *) | ||
| 143 | allocate_pseudovector (VECSIZE (struct font_entity), | ||
| 144 | FONT_ENTITY_MAX, PVEC_FONT)); | ||
| 145 | XSETFONT (font_entity, entity); | ||
| 146 | return font_entity; | ||
| 147 | } | ||
| 148 | |||
| 149 | Lisp_Object | ||
| 150 | font_make_object (size) | ||
| 151 | int size; | ||
| 152 | { | ||
| 153 | Lisp_Object font_object; | ||
| 154 | struct font *font | ||
| 155 | = (struct font *) allocate_pseudovector (size, FONT_OBJECT_MAX, PVEC_FONT); | ||
| 156 | XSETFONT (font_object, font); | ||
| 157 | |||
| 158 | return font_object; | ||
| 159 | } | ||
| 160 | |||
| 161 | |||
| 162 | |||
| 150 | static int font_pixel_size P_ ((FRAME_PTR f, Lisp_Object)); | 163 | static int font_pixel_size P_ ((FRAME_PTR f, Lisp_Object)); |
| 151 | static Lisp_Object prop_name_to_numeric P_ ((enum font_property_index, | ||
| 152 | Lisp_Object)); | ||
| 153 | static Lisp_Object prop_numeric_to_name P_ ((enum font_property_index, int)); | ||
| 154 | static Lisp_Object font_open_entity P_ ((FRAME_PTR, Lisp_Object, int)); | 164 | static Lisp_Object font_open_entity P_ ((FRAME_PTR, Lisp_Object, int)); |
| 155 | static void build_font_family_alist P_ ((void)); | 165 | static Lisp_Object font_matching_entity P_ ((FRAME_PTR, Lisp_Object *, |
| 166 | Lisp_Object)); | ||
| 156 | 167 | ||
| 157 | /* Number of registered font drivers. */ | 168 | /* Number of registered font drivers. */ |
| 158 | static int num_font_drivers; | 169 | static int num_font_drivers; |
| 159 | 170 | ||
| 171 | |||
| 172 | /* Return a Lispy value of a font property value at STR and LEN bytes. | ||
| 173 | If STR is "*", it returns nil. | ||
| 174 | If all characters in STR are digits, it returns an integer. | ||
| 175 | Otherwise, it returns a symbol interned from STR. */ | ||
| 176 | |||
| 177 | Lisp_Object | ||
| 178 | font_intern_prop (str, len) | ||
| 179 | char *str; | ||
| 180 | int len; | ||
| 181 | { | ||
| 182 | int i; | ||
| 183 | Lisp_Object tem, string; | ||
| 184 | Lisp_Object obarray; | ||
| 185 | |||
| 186 | if (len == 1 && *str == '*') | ||
| 187 | return Qnil; | ||
| 188 | if (len >=1 && isdigit (*str)) | ||
| 189 | { | ||
| 190 | for (i = 1; i < len; i++) | ||
| 191 | if (! isdigit (str[i])) | ||
| 192 | break; | ||
| 193 | if (i == len) | ||
| 194 | return make_number (atoi (str)); | ||
| 195 | } | ||
| 196 | |||
| 197 | /* The following code is copied from the function intern (in lread.c). */ | ||
| 198 | obarray = Vobarray; | ||
| 199 | if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0) | ||
| 200 | obarray = check_obarray (obarray); | ||
| 201 | tem = oblookup (obarray, str, len, len); | ||
| 202 | if (SYMBOLP (tem)) | ||
| 203 | return tem; | ||
| 204 | return Fintern (make_unibyte_string (str, len), obarray); | ||
| 205 | } | ||
| 206 | |||
| 160 | /* Return a pixel size of font-spec SPEC on frame F. */ | 207 | /* Return a pixel size of font-spec SPEC on frame F. */ |
| 161 | 208 | ||
| 162 | static int | 209 | static int |
| @@ -166,126 +213,123 @@ font_pixel_size (f, spec) | |||
| 166 | { | 213 | { |
| 167 | Lisp_Object size = AREF (spec, FONT_SIZE_INDEX); | 214 | Lisp_Object size = AREF (spec, FONT_SIZE_INDEX); |
| 168 | double point_size; | 215 | double point_size; |
| 169 | int pixel_size, dpi; | 216 | int dpi, pixel_size; |
| 170 | Lisp_Object extra, val; | 217 | Lisp_Object extra, val; |
| 171 | 218 | ||
| 172 | if (INTEGERP (size)) | 219 | if (INTEGERP (size)) |
| 173 | return XINT (size); | 220 | return XINT (size); |
| 174 | if (NILP (size)) | 221 | if (NILP (size)) |
| 175 | return 0; | 222 | return 0; xassert (FLOATP (size)); |
| 176 | point_size = XFLOAT_DATA (size); | 223 | point_size = XFLOAT_DATA (size); |
| 177 | extra = AREF (spec, FONT_EXTRA_INDEX); | 224 | val = AREF (spec, FONT_DPI_INDEX); |
| 178 | val = assq_no_quit (QCdpi, extra); | 225 | if (INTEGERP (val)) |
| 179 | if (CONSP (val)) | 226 | dpi = XINT (XCDR (val)); |
| 180 | { | ||
| 181 | if (INTEGERP (XCDR (val))) | ||
| 182 | dpi = XINT (XCDR (val)); | ||
| 183 | else | ||
| 184 | dpi = XFLOAT_DATA (XCDR (val)) + 0.5; | ||
| 185 | } | ||
| 186 | else | 227 | else |
| 187 | dpi = f->resy; | 228 | dpi = f->resy; |
| 188 | pixel_size = POINT_TO_PIXEL (point_size, dpi); | 229 | pixel_size = POINT_TO_PIXEL (point_size, dpi); |
| 189 | return pixel_size; | 230 | return pixel_size; |
| 190 | } | 231 | } |
| 191 | 232 | ||
| 192 | /* Return a numeric value corresponding to PROP's NAME (symbol). If | ||
| 193 | NAME is not registered in font_style_table, return Qnil. PROP must | ||
| 194 | be one of FONT_{WEIGHT|SLANT|SWIDTH}_INDEX. */ | ||
| 195 | |||
| 196 | static Lisp_Object | ||
| 197 | prop_name_to_numeric (prop, name) | ||
| 198 | enum font_property_index prop; | ||
| 199 | Lisp_Object name; | ||
| 200 | { | ||
| 201 | int table_index = prop - FONT_WEIGHT_INDEX; | ||
| 202 | Lisp_Object val; | ||
| 203 | 233 | ||
| 204 | val = assq_no_quit (name, AREF (font_style_table, table_index)); | 234 | /* Return a value of PROP's VAL (symbol or integer) to be stored in a |
| 205 | return (NILP (val) ? Qnil : XCDR (val)); | 235 | font vector. If VAL is not valid (i.e. not registered in |
| 206 | } | 236 | font_style_table), return -1 if NOERROR is zero, and return a |
| 237 | proper index if NOERROR is nonzero. In that case, register VAL in | ||
| 238 | font_style_table if VAL is a symbol, and return a closest index if | ||
| 239 | VAL is an integer. */ | ||
| 207 | 240 | ||
| 208 | 241 | int | |
| 209 | /* Return a name (symbol) corresponding to PROP's NUMERIC value. If | 242 | font_style_to_value (prop, val, noerror) |
| 210 | no name is registered for NUMERIC in font_style_table, return a | ||
| 211 | symbol of integer name (e.g. `123'). PROP must be one of | ||
| 212 | FONT_{WEIGHT|SLANT|SWIDTH}_INDEX. */ | ||
| 213 | |||
| 214 | static Lisp_Object | ||
| 215 | prop_numeric_to_name (prop, numeric) | ||
| 216 | enum font_property_index prop; | 243 | enum font_property_index prop; |
| 217 | int numeric; | 244 | Lisp_Object val; |
| 245 | int noerror; | ||
| 218 | { | 246 | { |
| 219 | int table_index = prop - FONT_WEIGHT_INDEX; | 247 | Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX); |
| 220 | Lisp_Object table = AREF (font_style_table, table_index); | 248 | int len = ASIZE (table); |
| 221 | char buf[10]; | 249 | int i; |
| 222 | 250 | ||
| 223 | while (! NILP (table)) | 251 | if (SYMBOLP (val)) |
| 224 | { | 252 | { |
| 225 | if (XINT (XCDR (XCAR (table))) >= numeric) | 253 | char *s; |
| 254 | Lisp_Object args[2], elt; | ||
| 255 | |||
| 256 | /* At first try exact match. */ | ||
| 257 | for (i = 0; i < len; i++) | ||
| 258 | if (EQ (val, XCAR (AREF (table, i)))) | ||
| 259 | return (XINT (XCDR (AREF (table, i))) << 8) | i; | ||
| 260 | /* Try also with case-folding match. */ | ||
| 261 | s = SDATA (SYMBOL_NAME (val)); | ||
| 262 | for (i = 0; i < len; i++) | ||
| 226 | { | 263 | { |
| 227 | if (XINT (XCDR (XCAR (table))) == numeric) | 264 | elt = XCAR (AREF (table, i)); |
| 228 | return XCAR (XCAR (table)); | 265 | if (strcasecmp (s, (char *) SDATA (SYMBOL_NAME (elt))) == 0) |
| 229 | else | 266 | return i; |
| 230 | break; | ||
| 231 | } | 267 | } |
| 232 | table = XCDR (table); | 268 | if (! noerror) |
| 269 | return -1; | ||
| 270 | if (len == 255) | ||
| 271 | abort (); | ||
| 272 | args[0] = table; | ||
| 273 | args[1] = Fmake_vector (make_number (1), Fcons (val, make_number (255))); | ||
| 274 | ASET (font_style_table, prop - FONT_WEIGHT_INDEX, Fvconcat (2, args)); | ||
| 275 | return (255 << 8) | i; | ||
| 233 | } | 276 | } |
| 234 | sprintf (buf, "%d", numeric); | 277 | else |
| 235 | return intern (buf); | 278 | { |
| 236 | } | 279 | int last_i, i, last_n; |
| 280 | int numeric = XINT (val); | ||
| 237 | 281 | ||
| 282 | for (i = 1, last_i = last_n = -1; i < len;) | ||
| 283 | { | ||
| 284 | int n = XINT (XCDR (AREF (table, i))); | ||
| 238 | 285 | ||
| 239 | /* Return a symbol whose name is STR (length LEN). If STR contains | 286 | if (numeric == n) |
| 240 | uppercase letters, downcase them in advance. */ | 287 | return (n << 8) | i; |
| 288 | if (numeric < n) | ||
| 289 | { | ||
| 290 | if (! noerror) | ||
| 291 | return -1; | ||
| 292 | return ((last_i < 0 || n - numeric < numeric - last_n) | ||
| 293 | ? (n << 8) | i : (last_n << 8 | last_i)); | ||
| 294 | } | ||
| 295 | last_i = i; | ||
| 296 | last_n = n; | ||
| 297 | for (i++; i < len && n == XINT (XCDR (AREF (table, i + 1))); i++); | ||
| 298 | } | ||
| 299 | if (! noerror) | ||
| 300 | return -1; | ||
| 301 | return (last_n << 8) | last_i; | ||
| 302 | } | ||
| 303 | } | ||
| 241 | 304 | ||
| 242 | Lisp_Object | 305 | Lisp_Object |
| 243 | intern_downcase (str, len) | 306 | font_style_symbolic (font, prop, for_face) |
| 244 | char *str; | 307 | Lisp_Object font; |
| 245 | int len; | 308 | enum font_property_index prop; |
| 309 | int for_face; | ||
| 246 | { | 310 | { |
| 247 | char *buf; | 311 | Lisp_Object val = AREF (font, prop); |
| 248 | int i; | 312 | Lisp_Object table; |
| 313 | int i, numeric; | ||
| 249 | 314 | ||
| 250 | for (i = 0; i < len; i++) | 315 | if (NILP (val)) |
| 251 | if (isupper (str[i])) | 316 | return Qnil; |
| 252 | break; | 317 | table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX); |
| 253 | if (i == len) | 318 | if (! for_face) |
| 254 | return Fintern (make_unibyte_string (str, len), Qnil); | 319 | return XCAR (AREF (table, XINT (val) & 0xFF)); |
| 255 | buf = alloca (len); | 320 | numeric = XINT (val) >> 8; |
| 256 | if (! buf) | 321 | for (i = 0; i < ASIZE (table); i++) |
| 257 | return Fintern (null_string, Qnil); | 322 | if (XINT (XCDR (AREF (table, i))) == numeric) |
| 258 | bcopy (str, buf, len); | 323 | return XCAR (AREF (table, i)); |
| 259 | for (; i < len; i++) | 324 | abort (); |
| 260 | if (isascii (buf[i])) | 325 | return Qnil; |
| 261 | buf[i] = tolower (buf[i]); | ||
| 262 | return Fintern (make_unibyte_string (buf, len), Qnil); | ||
| 263 | } | 326 | } |
| 264 | 327 | ||
| 265 | extern Lisp_Object Vface_alternative_font_family_alist; | 328 | extern Lisp_Object Vface_alternative_font_family_alist; |
| 266 | 329 | ||
| 267 | /* Setup font_family_alist of the form: | ||
| 268 | ((FAMILY-SYMBOL ALIAS-SYMBOL ...) ...) | ||
| 269 | from Vface_alternative_font_family_alist of the form: | ||
| 270 | ((FAMILY-STRING ALIAS-STRING ...) ...) */ | ||
| 271 | |||
| 272 | static void | ||
| 273 | build_font_family_alist () | ||
| 274 | { | ||
| 275 | Lisp_Object alist = Vface_alternative_font_family_alist; | ||
| 276 | |||
| 277 | for (; CONSP (alist); alist = XCDR (alist)) | ||
| 278 | { | ||
| 279 | Lisp_Object tail, elt; | ||
| 280 | |||
| 281 | for (tail = XCAR (alist), elt = Qnil ; CONSP (tail); tail = XCDR (tail)) | ||
| 282 | elt = nconc2 (elt, Fcons (Fintern (XCAR (tail), Qnil), Qnil)); | ||
| 283 | font_family_alist = Fcons (elt, font_family_alist); | ||
| 284 | } | ||
| 285 | } | ||
| 286 | |||
| 287 | extern Lisp_Object find_font_encoding P_ ((Lisp_Object)); | 330 | extern Lisp_Object find_font_encoding P_ ((Lisp_Object)); |
| 288 | 331 | ||
| 332 | |||
| 289 | /* Return encoding charset and repertory charset for REGISTRY in | 333 | /* Return encoding charset and repertory charset for REGISTRY in |
| 290 | ENCODING and REPERTORY correspondingly. If correct information for | 334 | ENCODING and REPERTORY correspondingly. If correct information for |
| 291 | REGISTRY is available, return 0. Otherwise return -1. */ | 335 | REGISTRY is available, return 0. Otherwise return -1. */ |
| @@ -298,7 +342,7 @@ font_registry_charsets (registry, encoding, repertory) | |||
| 298 | Lisp_Object val; | 342 | Lisp_Object val; |
| 299 | int encoding_id, repertory_id; | 343 | int encoding_id, repertory_id; |
| 300 | 344 | ||
| 301 | val = assq_no_quit (registry, font_charset_alist); | 345 | val = Fassoc_string (registry, font_charset_alist, Qt); |
| 302 | if (! NILP (val)) | 346 | if (! NILP (val)) |
| 303 | { | 347 | { |
| 304 | val = XCDR (val); | 348 | val = XCDR (val); |
| @@ -351,54 +395,56 @@ font_registry_charsets (registry, encoding, repertory) | |||
| 351 | /* Font property value validaters. See the comment of | 395 | /* Font property value validaters. See the comment of |
| 352 | font_property_table for the meaning of the arguments. */ | 396 | font_property_table for the meaning of the arguments. */ |
| 353 | 397 | ||
| 398 | static Lisp_Object font_prop_validate P_ ((int, Lisp_Object, Lisp_Object)); | ||
| 354 | static Lisp_Object font_prop_validate_symbol P_ ((Lisp_Object, Lisp_Object)); | 399 | static Lisp_Object font_prop_validate_symbol P_ ((Lisp_Object, Lisp_Object)); |
| 355 | static Lisp_Object font_prop_validate_style P_ ((Lisp_Object, Lisp_Object)); | 400 | static Lisp_Object font_prop_validate_style P_ ((Lisp_Object, Lisp_Object)); |
| 356 | static Lisp_Object font_prop_validate_non_neg P_ ((Lisp_Object, Lisp_Object)); | 401 | static Lisp_Object font_prop_validate_non_neg P_ ((Lisp_Object, Lisp_Object)); |
| 357 | static Lisp_Object font_prop_validate_spacing P_ ((Lisp_Object, Lisp_Object)); | 402 | static Lisp_Object font_prop_validate_spacing P_ ((Lisp_Object, Lisp_Object)); |
| 358 | static int get_font_prop_index P_ ((Lisp_Object, int)); | 403 | static int get_font_prop_index P_ ((Lisp_Object)); |
| 359 | static Lisp_Object font_prop_validate P_ ((Lisp_Object)); | ||
| 360 | 404 | ||
| 361 | static Lisp_Object | 405 | static Lisp_Object |
| 362 | font_prop_validate_symbol (prop, val) | 406 | font_prop_validate_symbol (prop, val) |
| 363 | Lisp_Object prop, val; | 407 | Lisp_Object prop, val; |
| 364 | { | 408 | { |
| 365 | if (EQ (prop, QCotf)) | ||
| 366 | return (SYMBOLP (val) ? val : Qerror); | ||
| 367 | if (STRINGP (val)) | 409 | if (STRINGP (val)) |
| 368 | val = (SCHARS (val) == 0 ? null_string | 410 | val = Fintern (val, Qnil); |
| 369 | : intern_downcase ((char *) SDATA (val), SBYTES (val))); | 411 | if (! SYMBOLP (val)) |
| 370 | else if (SYMBOLP (val)) | ||
| 371 | { | ||
| 372 | if (SCHARS (SYMBOL_NAME (val)) == 0) | ||
| 373 | val = null_string; | ||
| 374 | } | ||
| 375 | else | ||
| 376 | val = Qerror; | 412 | val = Qerror; |
| 413 | else if (EQ (prop, QCregistry)) | ||
| 414 | val = Fintern (Fdowncase (SYMBOL_NAME (val)), Qnil); | ||
| 377 | return val; | 415 | return val; |
| 378 | } | 416 | } |
| 379 | 417 | ||
| 418 | |||
| 380 | static Lisp_Object | 419 | static Lisp_Object |
| 381 | font_prop_validate_style (prop, val) | 420 | font_prop_validate_style (style, val) |
| 382 | Lisp_Object prop, val; | 421 | Lisp_Object style, val; |
| 383 | { | 422 | { |
| 384 | if (! INTEGERP (val)) | 423 | enum font_property_index prop = (EQ (style, QCweight) ? FONT_WEIGHT_INDEX |
| 424 | : EQ (style, QCslant) ? FONT_SLANT_INDEX | ||
| 425 | : FONT_WIDTH_INDEX); | ||
| 426 | int n; | ||
| 427 | if (INTEGERP (val)) | ||
| 385 | { | 428 | { |
| 386 | if (STRINGP (val)) | 429 | n = XINT (val); |
| 387 | val = intern_downcase ((char *) SDATA (val), SBYTES (val)); | 430 | if ((n & 0xFF) |
| 388 | if (! SYMBOLP (val)) | 431 | >= ASIZE (AREF (font_style_table, prop - FONT_WEIGHT_INDEX))) |
| 389 | val = Qerror; | 432 | val = Qerror; |
| 390 | else | 433 | else |
| 391 | { | 434 | { |
| 392 | enum font_property_index prop_index | 435 | Lisp_Object elt = AREF (AREF (font_style_table, prop - FONT_WEIGHT_INDEX), n & 0xFF); |
| 393 | = (EQ (prop, QCweight) ? FONT_WEIGHT_INDEX | 436 | if (XINT (XCDR (elt)) != (n >> 8)) |
| 394 | : EQ (prop, QCslant) ? FONT_SLANT_INDEX | ||
| 395 | : FONT_WIDTH_INDEX); | ||
| 396 | |||
| 397 | val = prop_name_to_numeric (prop_index, val); | ||
| 398 | if (NILP (val)) | ||
| 399 | val = Qerror; | 437 | val = Qerror; |
| 400 | } | 438 | } |
| 401 | } | 439 | } |
| 440 | else if (SYMBOLP (val)) | ||
| 441 | { | ||
| 442 | int n = font_style_to_value (prop, val, 0); | ||
| 443 | |||
| 444 | val = n >= 0 ? make_number (n) : Qerror; | ||
| 445 | } | ||
| 446 | else | ||
| 447 | val = Qerror; | ||
| 402 | return val; | 448 | return val; |
| 403 | } | 449 | } |
| 404 | 450 | ||
| @@ -422,6 +468,8 @@ font_prop_validate_spacing (prop, val) | |||
| 422 | return make_number (FONT_SPACING_MONO); | 468 | return make_number (FONT_SPACING_MONO); |
| 423 | if (EQ (val, Qp)) | 469 | if (EQ (val, Qp)) |
| 424 | return make_number (FONT_SPACING_PROPORTIONAL); | 470 | return make_number (FONT_SPACING_PROPORTIONAL); |
| 471 | if (EQ (val, Qd)) | ||
| 472 | return make_number (FONT_SPACING_DUAL); | ||
| 425 | return Qerror; | 473 | return Qerror; |
| 426 | } | 474 | } |
| 427 | 475 | ||
| @@ -480,13 +528,14 @@ struct | |||
| 480 | { &QCslant, font_prop_validate_style }, | 528 | { &QCslant, font_prop_validate_style }, |
| 481 | { &QCwidth, font_prop_validate_style }, | 529 | { &QCwidth, font_prop_validate_style }, |
| 482 | { &QCsize, font_prop_validate_non_neg }, | 530 | { &QCsize, font_prop_validate_non_neg }, |
| 483 | { &QClanguage, font_prop_validate_symbol }, | ||
| 484 | { &QCscript, font_prop_validate_symbol }, | ||
| 485 | { &QCdpi, font_prop_validate_non_neg }, | 531 | { &QCdpi, font_prop_validate_non_neg }, |
| 486 | { &QCspacing, font_prop_validate_spacing }, | 532 | { &QCspacing, font_prop_validate_spacing }, |
| 487 | { &QCscalable, NULL }, | 533 | { &QCavgwidth, font_prop_validate_non_neg }, |
| 488 | { &QCotf, font_prop_validate_otf }, | 534 | /* The order of the above entries must match with enum |
| 489 | { &QCantialias, font_prop_validate_symbol } | 535 | font_property_index. */ |
| 536 | { &QClang, font_prop_validate_symbol }, | ||
| 537 | { &QCscript, font_prop_validate_symbol }, | ||
| 538 | { &QCotf, font_prop_validate_otf } | ||
| 490 | }; | 539 | }; |
| 491 | 540 | ||
| 492 | /* Size (number of elements) of the above table. */ | 541 | /* Size (number of elements) of the above table. */ |
| @@ -494,63 +543,48 @@ struct | |||
| 494 | ((sizeof font_property_table) / (sizeof *font_property_table)) | 543 | ((sizeof font_property_table) / (sizeof *font_property_table)) |
| 495 | 544 | ||
| 496 | /* Return an index number of font property KEY or -1 if KEY is not an | 545 | /* Return an index number of font property KEY or -1 if KEY is not an |
| 497 | already known property. Start searching font_property_table from | 546 | already known property. */ |
| 498 | index FROM (which is 0 or FONT_EXTRA_INDEX). */ | ||
| 499 | 547 | ||
| 500 | static int | 548 | static int |
| 501 | get_font_prop_index (key, from) | 549 | get_font_prop_index (key) |
| 502 | Lisp_Object key; | 550 | Lisp_Object key; |
| 503 | int from; | ||
| 504 | { | 551 | { |
| 505 | for (; from < FONT_PROPERTY_TABLE_SIZE; from++) | 552 | int i; |
| 506 | if (EQ (key, *font_property_table[from].key)) | 553 | |
| 507 | return from; | 554 | for (i = 0; i < FONT_PROPERTY_TABLE_SIZE; i++) |
| 555 | if (EQ (key, *font_property_table[i].key)) | ||
| 556 | return i; | ||
| 508 | return -1; | 557 | return -1; |
| 509 | } | 558 | } |
| 510 | 559 | ||
| 511 | /* Validate font properties in SPEC (vector) while updating elements | 560 | /* Validate the font property. The property key is specified by the |
| 512 | to regularized values. Signal an error if an invalid property is | 561 | symbol PROP, or the index IDX (if PROP is nil). If VAL is invalid, |
| 513 | found. */ | 562 | signal an error. The value is VAL or the regularized one. */ |
| 514 | 563 | ||
| 515 | static Lisp_Object | 564 | static Lisp_Object |
| 516 | font_prop_validate (spec) | 565 | font_prop_validate (idx, prop, val) |
| 517 | Lisp_Object spec; | 566 | int idx; |
| 567 | Lisp_Object prop, val; | ||
| 518 | { | 568 | { |
| 519 | int i; | 569 | Lisp_Object validated; |
| 520 | Lisp_Object prop, val, extra; | ||
| 521 | 570 | ||
| 522 | for (i = FONT_TYPE_INDEX; i < FONT_EXTRA_INDEX; i++) | 571 | if (NILP (prop)) |
| 523 | { | 572 | prop = *font_property_table[idx].key; |
| 524 | if (! NILP (AREF (spec, i))) | 573 | else |
| 525 | { | ||
| 526 | prop = *font_property_table[i].key; | ||
| 527 | val = (font_property_table[i].validater) (prop, AREF (spec, i)); | ||
| 528 | if (EQ (val, Qerror)) | ||
| 529 | Fsignal (Qfont, list2 (build_string ("invalid font property"), | ||
| 530 | Fcons (prop, AREF (spec, i)))); | ||
| 531 | ASET (spec, i, val); | ||
| 532 | } | ||
| 533 | } | ||
| 534 | for (extra = AREF (spec, FONT_EXTRA_INDEX); | ||
| 535 | CONSP (extra); extra = XCDR (extra)) | ||
| 536 | { | 574 | { |
| 537 | Lisp_Object elt = XCAR (extra); | 575 | idx = get_font_prop_index (prop); |
| 538 | 576 | if (idx < 0) | |
| 539 | prop = XCAR (elt); | 577 | return val; |
| 540 | i = get_font_prop_index (prop, FONT_EXTRA_INDEX); | ||
| 541 | if (i >= 0 | ||
| 542 | && font_property_table[i].validater) | ||
| 543 | { | ||
| 544 | val = (font_property_table[i].validater) (prop, XCDR (elt)); | ||
| 545 | if (EQ (val, Qerror)) | ||
| 546 | signal_error ("invalid font property", elt); | ||
| 547 | XSETCDR (elt, val); | ||
| 548 | } | ||
| 549 | } | 578 | } |
| 550 | return spec; | 579 | validated = (font_property_table[idx].validater) (prop, val); |
| 580 | if (EQ (validated, Qerror)) | ||
| 581 | signal_error ("invalid font property", Fcons (prop, val)); | ||
| 582 | return validated; | ||
| 551 | } | 583 | } |
| 552 | 584 | ||
| 553 | /* Store VAL as a value of extra font property PROP in FONT. */ | 585 | |
| 586 | /* Store VAL as a value of extra font property PROP in FONT while | ||
| 587 | keeping the sorting order. Don't check the validity of VAL. */ | ||
| 554 | 588 | ||
| 555 | Lisp_Object | 589 | Lisp_Object |
| 556 | font_put_extra (font, prop, val) | 590 | font_put_extra (font, prop, val) |
| @@ -561,8 +595,15 @@ font_put_extra (font, prop, val) | |||
| 561 | 595 | ||
| 562 | if (NILP (slot)) | 596 | if (NILP (slot)) |
| 563 | { | 597 | { |
| 564 | extra = Fcons (Fcons (prop, val), extra); | 598 | Lisp_Object prev = Qnil; |
| 565 | ASET (font, FONT_EXTRA_INDEX, extra); | 599 | |
| 600 | while (CONSP (extra) | ||
| 601 | && NILP (Fstring_lessp (prop, XCAR (XCAR (extra))))) | ||
| 602 | prev = extra, extra = XCDR (extra); | ||
| 603 | if (NILP (prev)) | ||
| 604 | ASET (font, FONT_EXTRA_INDEX, Fcons (Fcons (prop, val), extra)); | ||
| 605 | else | ||
| 606 | XSETCDR (prev, Fcons (Fcons (prop, val), extra)); | ||
| 566 | return val; | 607 | return val; |
| 567 | } | 608 | } |
| 568 | XSETCDR (slot, val); | 609 | XSETCDR (slot, val); |
| @@ -572,7 +613,6 @@ font_put_extra (font, prop, val) | |||
| 572 | 613 | ||
| 573 | /* Font name parser and unparser */ | 614 | /* Font name parser and unparser */ |
| 574 | 615 | ||
| 575 | static Lisp_Object intern_font_field P_ ((char *, int)); | ||
| 576 | static int parse_matrix P_ ((char *)); | 616 | static int parse_matrix P_ ((char *)); |
| 577 | static int font_expand_wildcards P_ ((Lisp_Object *, int)); | 617 | static int font_expand_wildcards P_ ((Lisp_Object *, int)); |
| 578 | static int font_parse_name P_ ((char *, Lisp_Object)); | 618 | static int font_parse_name P_ ((char *, Lisp_Object)); |
| @@ -617,34 +657,6 @@ enum xlfd_field_mask | |||
| 617 | }; | 657 | }; |
| 618 | 658 | ||
| 619 | 659 | ||
| 620 | /* Return a Lispy value of a XLFD font field at STR and LEN bytes. | ||
| 621 | If LEN is zero, it returns `null_string'. | ||
| 622 | If STR is "*", it returns nil. | ||
| 623 | If all characters in STR are digits, it returns an integer. | ||
| 624 | Otherwise, it returns a symbol interned from downcased STR. */ | ||
| 625 | |||
| 626 | static Lisp_Object | ||
| 627 | intern_font_field (str, len) | ||
| 628 | char *str; | ||
| 629 | int len; | ||
| 630 | { | ||
| 631 | int i; | ||
| 632 | |||
| 633 | if (len == 0) | ||
| 634 | return null_string; | ||
| 635 | if (*str == '*' && len == 1) | ||
| 636 | return Qnil; | ||
| 637 | if (isdigit (*str)) | ||
| 638 | { | ||
| 639 | for (i = 1; i < len; i++) | ||
| 640 | if (! isdigit (str[i])) | ||
| 641 | break; | ||
| 642 | if (i == len) | ||
| 643 | return make_number (atoi (str)); | ||
| 644 | } | ||
| 645 | return intern_downcase (str, len); | ||
| 646 | } | ||
| 647 | |||
| 648 | /* Parse P pointing the pixel/point size field of the form | 660 | /* Parse P pointing the pixel/point size field of the form |
| 649 | `[A B C D]' which specifies a transformation matrix: | 661 | `[A B C D]' which specifies a transformation matrix: |
| 650 | 662 | ||
| @@ -755,7 +767,7 @@ font_expand_wildcards (field, n) | |||
| 755 | from = XLFD_POINT_INDEX, to = XLFD_AVGWIDTH_INDEX, | 767 | from = XLFD_POINT_INDEX, to = XLFD_AVGWIDTH_INDEX, |
| 756 | mask = XLFD_LARGENUM_MASK; | 768 | mask = XLFD_LARGENUM_MASK; |
| 757 | } | 769 | } |
| 758 | else if (EQ (val, null_string)) | 770 | else if (SBYTES (SYMBOL_NAME (val)) == 0) |
| 759 | from = XLFD_FOUNDRY_INDEX, to = XLFD_ADSTYLE_INDEX, | 771 | from = XLFD_FOUNDRY_INDEX, to = XLFD_ADSTYLE_INDEX, |
| 760 | mask = XLFD_NULL_MASK; | 772 | mask = XLFD_NULL_MASK; |
| 761 | else if (i == 0) | 773 | else if (i == 0) |
| @@ -773,15 +785,15 @@ font_expand_wildcards (field, n) | |||
| 773 | } | 785 | } |
| 774 | else if (range_from <= XLFD_WEIGHT_INDEX | 786 | else if (range_from <= XLFD_WEIGHT_INDEX |
| 775 | && range_to >= XLFD_WEIGHT_INDEX | 787 | && range_to >= XLFD_WEIGHT_INDEX |
| 776 | && !NILP (prop_name_to_numeric (FONT_WEIGHT_INDEX, val))) | 788 | && FONT_WEIGHT_NAME_NUMERIC (val) >= 0) |
| 777 | from = to = XLFD_WEIGHT_INDEX, mask = XLFD_WEIGHT_MASK; | 789 | from = to = XLFD_WEIGHT_INDEX, mask = XLFD_WEIGHT_MASK; |
| 778 | else if (range_from <= XLFD_SLANT_INDEX | 790 | else if (range_from <= XLFD_SLANT_INDEX |
| 779 | && range_to >= XLFD_SLANT_INDEX | 791 | && range_to >= XLFD_SLANT_INDEX |
| 780 | && !NILP (prop_name_to_numeric (FONT_SLANT_INDEX, val))) | 792 | && FONT_SLANT_NAME_NUMERIC (val) >= 0) |
| 781 | from = to = XLFD_SLANT_INDEX, mask = XLFD_SLANT_MASK; | 793 | from = to = XLFD_SLANT_INDEX, mask = XLFD_SLANT_MASK; |
| 782 | else if (range_from <= XLFD_SWIDTH_INDEX | 794 | else if (range_from <= XLFD_SWIDTH_INDEX |
| 783 | && range_to >= XLFD_SWIDTH_INDEX | 795 | && range_to >= XLFD_SWIDTH_INDEX |
| 784 | && !NILP (prop_name_to_numeric (FONT_WIDTH_INDEX, val))) | 796 | && FONT_WIDTH_NAME_NUMERIC (val) >= 0) |
| 785 | from = to = XLFD_SWIDTH_INDEX, mask = XLFD_SWIDTH_MASK; | 797 | from = to = XLFD_SWIDTH_INDEX, mask = XLFD_SWIDTH_MASK; |
| 786 | else | 798 | else |
| 787 | { | 799 | { |
| @@ -902,6 +914,7 @@ font_check_xlfd_parse (Lisp_Object font, char *name) | |||
| 902 | 914 | ||
| 903 | #endif | 915 | #endif |
| 904 | 916 | ||
| 917 | |||
| 905 | /* Parse NAME (null terminated) as XLFD and store information in FONT | 918 | /* Parse NAME (null terminated) as XLFD and store information in FONT |
| 906 | (font-spec or font-entity). Size property of FONT is set as | 919 | (font-spec or font-entity). Size property of FONT is set as |
| 907 | follows: | 920 | follows: |
| @@ -915,9 +928,7 @@ font_check_xlfd_parse (Lisp_Object font, char *name) | |||
| 915 | 928 | ||
| 916 | FONT is usually a font-spec, but when this function is called from | 929 | FONT is usually a font-spec, but when this function is called from |
| 917 | X font backend driver, it is a font-entity. In that case, NAME is | 930 | X font backend driver, it is a font-entity. In that case, NAME is |
| 918 | a fully specified XLFD, and we set FONT_EXTRA_INDEX of FONT to a | 931 | a fully specified XLFD. */ |
| 919 | symbol RESX-RESY-SPACING-AVGWIDTH. | ||
| 920 | */ | ||
| 921 | 932 | ||
| 922 | int | 933 | int |
| 923 | font_parse_xlfd (name, font) | 934 | font_parse_xlfd (name, font) |
| @@ -925,9 +936,7 @@ font_parse_xlfd (name, font) | |||
| 925 | Lisp_Object font; | 936 | Lisp_Object font; |
| 926 | { | 937 | { |
| 927 | int len = strlen (name); | 938 | int len = strlen (name); |
| 928 | int i, j; | 939 | int i, j, n; |
| 929 | Lisp_Object dpi, spacing; | ||
| 930 | int avgwidth; | ||
| 931 | char *f[XLFD_LAST_INDEX + 1]; | 940 | char *f[XLFD_LAST_INDEX + 1]; |
| 932 | Lisp_Object val; | 941 | Lisp_Object val; |
| 933 | char *p; | 942 | char *p; |
| @@ -941,52 +950,49 @@ font_parse_xlfd (name, font) | |||
| 941 | else | 950 | else |
| 942 | i = 0; | 951 | i = 0; |
| 943 | for (p = name + i; *p; p++) | 952 | for (p = name + i; *p; p++) |
| 944 | if (*p == '-' && i < XLFD_LAST_INDEX) | 953 | if (*p == '-') |
| 945 | f[i++] = p + 1; | 954 | { |
| 946 | f[i] = p; | 955 | f[i++] = p + 1; |
| 956 | if (i == XLFD_LAST_INDEX) | ||
| 957 | break; | ||
| 958 | } | ||
| 959 | f[i] = name + len; | ||
| 947 | 960 | ||
| 948 | dpi = spacing = Qnil; | 961 | #define INTERN_FIELD(N) font_intern_prop (f[N], f[(N) + 1] - 1 - f[N]) |
| 949 | avgwidth = -1; | ||
| 950 | 962 | ||
| 951 | if (i == XLFD_LAST_INDEX) | 963 | if (i == XLFD_LAST_INDEX) |
| 952 | { | 964 | { |
| 965 | /* Fully specified XLFD. */ | ||
| 953 | int pixel_size; | 966 | int pixel_size; |
| 967 | int spacing_char; | ||
| 954 | 968 | ||
| 955 | /* Fully specified XLFD. */ | 969 | ASET (font, FONT_FOUNDRY_INDEX, INTERN_FIELD (XLFD_FOUNDRY_INDEX)); |
| 956 | for (i = 0, j = FONT_FOUNDRY_INDEX; i < XLFD_WEIGHT_INDEX; i++, j++) | 970 | ASET (font, FONT_FAMILY_INDEX, INTERN_FIELD (XLFD_FAMILY_INDEX)); |
| 957 | { | 971 | for (i = XLFD_WEIGHT_INDEX, j = FONT_WEIGHT_INDEX; |
| 958 | val = intern_font_field (f[i], f[i + 1] - 1 - f[i]); | 972 | i <= XLFD_SWIDTH_INDEX; i++, j++) |
| 959 | if (! NILP (val)) | ||
| 960 | ASET (font, j, val); | ||
| 961 | } | ||
| 962 | for (j = FONT_WEIGHT_INDEX; i < XLFD_ADSTYLE_INDEX; i++, j++) | ||
| 963 | { | 973 | { |
| 964 | val = intern_font_field (f[i], f[i + 1] - 1 - f[i]); | 974 | val = INTERN_FIELD (i); |
| 965 | if (! NILP (val)) | 975 | if (! NILP (val)) |
| 966 | { | 976 | { |
| 967 | Lisp_Object numeric = prop_name_to_numeric (j, val); | 977 | if ((n = font_style_to_value (j, INTERN_FIELD (i), 0)) < 0) |
| 968 | 978 | return -1; | |
| 969 | if (INTEGERP (numeric)) | 979 | ASET (font, j, make_number (n)); |
| 970 | val = numeric; | ||
| 971 | ASET (font, j, val); | ||
| 972 | } | 980 | } |
| 973 | } | 981 | } |
| 974 | val = intern_font_field (f[i], f[i + 1] - 1 - f[i]); | 982 | ASET (font, FONT_ADSTYLE_INDEX, INTERN_FIELD (XLFD_ADSTYLE_INDEX)); |
| 975 | if (! NILP (val)) | 983 | if (strcmp (f[XLFD_REGISTRY_INDEX], "*-*") == 0) |
| 976 | ASET (font, FONT_ADSTYLE_INDEX, val); | 984 | ASET (font, FONT_REGISTRY_INDEX, Qnil); |
| 977 | i = XLFD_REGISTRY_INDEX; | 985 | else |
| 978 | val = intern_font_field (f[i], f[i + 2] - f[i]); | 986 | ASET (font, FONT_REGISTRY_INDEX, |
| 979 | if (! NILP (val)) | 987 | font_intern_prop (f[XLFD_REGISTRY_INDEX], |
| 980 | ASET (font, FONT_REGISTRY_INDEX, val); | 988 | f[XLFD_LAST_INDEX] - f[XLFD_REGISTRY_INDEX])); |
| 981 | |||
| 982 | p = f[XLFD_PIXEL_INDEX]; | 989 | p = f[XLFD_PIXEL_INDEX]; |
| 983 | if (*p == '[' && (pixel_size = parse_matrix (p)) >= 0) | 990 | if (*p == '[' && (pixel_size = parse_matrix (p)) >= 0) |
| 984 | ASET (font, FONT_SIZE_INDEX, make_number (pixel_size)); | 991 | ASET (font, FONT_SIZE_INDEX, make_number (pixel_size)); |
| 985 | else | 992 | else |
| 986 | { | 993 | { |
| 987 | i = XLFD_PIXEL_INDEX; | 994 | val = INTERN_FIELD (XLFD_PIXEL_INDEX); |
| 988 | val = intern_font_field (f[i], f[i + 1] - 1 - f[i]); | 995 | if (INTEGERP (val)) |
| 989 | if (! NILP (val)) | ||
| 990 | ASET (font, FONT_SIZE_INDEX, val); | 996 | ASET (font, FONT_SIZE_INDEX, val); |
| 991 | else | 997 | else |
| 992 | { | 998 | { |
| @@ -1000,43 +1006,31 @@ font_parse_xlfd (name, font) | |||
| 1000 | point_size = atoi (p), point_size /= 10; | 1006 | point_size = atoi (p), point_size /= 10; |
| 1001 | if (point_size >= 0) | 1007 | if (point_size >= 0) |
| 1002 | ASET (font, FONT_SIZE_INDEX, make_float (point_size)); | 1008 | ASET (font, FONT_SIZE_INDEX, make_float (point_size)); |
| 1003 | else | ||
| 1004 | { | ||
| 1005 | i = XLFD_PIXEL_INDEX; | ||
| 1006 | val = intern_font_field (f[i], f[i + 1] - 1 - f[i]); | ||
| 1007 | if (! NILP (val)) | ||
| 1008 | ASET (font, FONT_SIZE_INDEX, val); | ||
| 1009 | } | ||
| 1010 | } | 1009 | } |
| 1011 | } | 1010 | } |
| 1012 | 1011 | ||
| 1013 | /* Parse RESX, RESY, SPACING, and AVGWIDTH. */ | 1012 | ASET (font, FONT_DPI_INDEX, INTERN_FIELD (XLFD_RESY_INDEX)); |
| 1014 | if (FONT_ENTITY_P (font)) | 1013 | val = INTERN_FIELD (XLFD_SPACING_INDEX); |
| 1014 | if (! NILP (val)) | ||
| 1015 | { | 1015 | { |
| 1016 | i = XLFD_RESX_INDEX; | 1016 | val = font_prop_validate_spacing (QCspacing, val); |
| 1017 | ASET (font, FONT_EXTRA_INDEX, | 1017 | if (! INTEGERP (val)) |
| 1018 | intern_font_field (f[i], f[XLFD_REGISTRY_INDEX] - 1 - f[i])); | 1018 | return -1; |
| 1019 | eassert (font_check_xlfd_parse (font, name)); | 1019 | ASET (font, FONT_SPACING_INDEX, val); |
| 1020 | return 0; | ||
| 1021 | } | 1020 | } |
| 1022 | |||
| 1023 | /* Here we just setup DPI, SPACING, and AVGWIDTH. They are set | ||
| 1024 | in FONT_EXTRA_INDEX later. */ | ||
| 1025 | i = XLFD_RESX_INDEX; | ||
| 1026 | dpi = intern_font_field (f[i], f[i + 1] - 1 - f[i]); | ||
| 1027 | i = XLFD_SPACING_INDEX; | ||
| 1028 | spacing = intern_font_field (f[i], f[i + 1] - 1 - f[i]); | ||
| 1029 | p = f[XLFD_AVGWIDTH_INDEX]; | 1021 | p = f[XLFD_AVGWIDTH_INDEX]; |
| 1030 | if (*p == '~') | 1022 | if (*p == '~') |
| 1031 | p++; | 1023 | p++; |
| 1032 | if (isdigit (*p)) | 1024 | ASET (font, FONT_AVGWIDTH_INDEX, |
| 1033 | avgwidth = atoi (p); | 1025 | font_intern_prop (p, f[XLFD_REGISTRY_INDEX] - 1 - p)); |
| 1034 | } | 1026 | } |
| 1035 | else | 1027 | else |
| 1036 | { | 1028 | { |
| 1037 | int wild_card_found = 0; | 1029 | int wild_card_found = 0; |
| 1038 | Lisp_Object prop[XLFD_LAST_INDEX]; | 1030 | Lisp_Object prop[XLFD_LAST_INDEX]; |
| 1039 | 1031 | ||
| 1032 | if (FONT_ENTITY_P (font)) | ||
| 1033 | return -1; | ||
| 1040 | for (j = 0; j < i; j++) | 1034 | for (j = 0; j < i; j++) |
| 1041 | { | 1035 | { |
| 1042 | if (*f[j] == '*') | 1036 | if (*f[j] == '*') |
| @@ -1046,49 +1040,41 @@ font_parse_xlfd (name, font) | |||
| 1046 | prop[j] = Qnil; | 1040 | prop[j] = Qnil; |
| 1047 | wild_card_found = 1; | 1041 | wild_card_found = 1; |
| 1048 | } | 1042 | } |
| 1049 | else if (isdigit (*f[j])) | ||
| 1050 | { | ||
| 1051 | for (p = f[j] + 1; isdigit (*p); p++); | ||
| 1052 | if (*p && *p != '-') | ||
| 1053 | prop[j] = intern_downcase (f[j], p - f[j]); | ||
| 1054 | else | ||
| 1055 | prop[j] = make_number (atoi (f[j])); | ||
| 1056 | } | ||
| 1057 | else if (j + 1 < i) | 1043 | else if (j + 1 < i) |
| 1058 | prop[j] = intern_font_field (f[j], f[j + 1] - 1 - f[j]); | 1044 | prop[j] = INTERN_FIELD (j); |
| 1059 | else | 1045 | else |
| 1060 | prop[j] = intern_font_field (f[j], f[i] - f[j]); | 1046 | prop[j] = font_intern_prop (f[j], f[i] - f[j]); |
| 1061 | } | 1047 | } |
| 1062 | if (! wild_card_found) | 1048 | if (! wild_card_found) |
| 1063 | return -1; | 1049 | return -1; |
| 1064 | if (font_expand_wildcards (prop, i) < 0) | 1050 | if (font_expand_wildcards (prop, i) < 0) |
| 1065 | return -1; | 1051 | return -1; |
| 1066 | 1052 | ||
| 1067 | for (i = 0, j = FONT_FOUNDRY_INDEX; i < XLFD_WEIGHT_INDEX; i++, j++) | 1053 | ASET (font, FONT_FOUNDRY_INDEX, prop[XLFD_FOUNDRY_INDEX]); |
| 1068 | if (! NILP (prop[i])) | 1054 | ASET (font, FONT_FAMILY_INDEX, prop[XLFD_FAMILY_INDEX]); |
| 1069 | ASET (font, j, prop[i]); | 1055 | for (i = XLFD_WEIGHT_INDEX, j = FONT_WEIGHT_INDEX; |
| 1070 | for (j = FONT_WEIGHT_INDEX; i < XLFD_ADSTYLE_INDEX; i++, j++) | 1056 | i <= XLFD_SWIDTH_INDEX; i++, j++) |
| 1071 | if (! NILP (prop[i])) | 1057 | if (! NILP (prop[i])) |
| 1072 | ASET (font, j, prop[i]); | 1058 | { |
| 1073 | if (! NILP (prop[XLFD_ADSTYLE_INDEX])) | 1059 | if ((n = font_style_to_value (j, prop[i], 1)) < 0) |
| 1074 | ASET (font, FONT_ADSTYLE_INDEX, prop[XLFD_ADSTYLE_INDEX]); | 1060 | return -1; |
| 1061 | ASET (font, j, make_number (n)); | ||
| 1062 | } | ||
| 1063 | ASET (font, FONT_ADSTYLE_INDEX, prop[XLFD_ADSTYLE_INDEX]); | ||
| 1075 | val = prop[XLFD_REGISTRY_INDEX]; | 1064 | val = prop[XLFD_REGISTRY_INDEX]; |
| 1076 | if (NILP (val)) | 1065 | if (NILP (val)) |
| 1077 | { | 1066 | { |
| 1078 | val = prop[XLFD_ENCODING_INDEX]; | 1067 | val = prop[XLFD_ENCODING_INDEX]; |
| 1079 | if (! NILP (val)) | 1068 | if (! NILP (val)) |
| 1080 | val = Fintern (concat2 (build_string ("*-"), SYMBOL_NAME (val)), | 1069 | val = concat2 (build_string ("*-"), SYMBOL_NAME (val)); |
| 1081 | Qnil); | ||
| 1082 | } | 1070 | } |
| 1083 | else if (NILP (prop[XLFD_ENCODING_INDEX])) | 1071 | else if (NILP (prop[XLFD_ENCODING_INDEX])) |
| 1084 | val = Fintern (concat2 (SYMBOL_NAME (val), build_string ("-*")), | 1072 | val = concat2 (SYMBOL_NAME (val), build_string ("-*")); |
| 1085 | Qnil); | ||
| 1086 | else | 1073 | else |
| 1087 | val = Fintern (concat3 (SYMBOL_NAME (val), build_string ("-"), | 1074 | val = concat3 (SYMBOL_NAME (val), build_string ("-"), |
| 1088 | SYMBOL_NAME (prop[XLFD_ENCODING_INDEX])), | 1075 | SYMBOL_NAME (prop[XLFD_ENCODING_INDEX])); |
| 1089 | Qnil); | ||
| 1090 | if (! NILP (val)) | 1076 | if (! NILP (val)) |
| 1091 | ASET (font, FONT_REGISTRY_INDEX, val); | 1077 | ASET (font, FONT_REGISTRY_INDEX, Fintern (val, Qnil)); |
| 1092 | 1078 | ||
| 1093 | if (INTEGERP (prop[XLFD_PIXEL_INDEX])) | 1079 | if (INTEGERP (prop[XLFD_PIXEL_INDEX])) |
| 1094 | ASET (font, FONT_SIZE_INDEX, prop[XLFD_PIXEL_INDEX]); | 1080 | ASET (font, FONT_SIZE_INDEX, prop[XLFD_PIXEL_INDEX]); |
| @@ -1099,19 +1085,20 @@ font_parse_xlfd (name, font) | |||
| 1099 | ASET (font, FONT_SIZE_INDEX, make_float (point_size / 10)); | 1085 | ASET (font, FONT_SIZE_INDEX, make_float (point_size / 10)); |
| 1100 | } | 1086 | } |
| 1101 | 1087 | ||
| 1102 | dpi = prop[XLFD_RESX_INDEX]; | 1088 | if (INTEGERP (prop[XLFD_RESX_INDEX])) |
| 1103 | spacing = prop[XLFD_SPACING_INDEX]; | 1089 | ASET (font, FONT_DPI_INDEX, prop[XLFD_RESY_INDEX]); |
| 1090 | if (! NILP (prop[XLFD_SPACING_INDEX])) | ||
| 1091 | { | ||
| 1092 | val = font_prop_validate_spacing (QCspacing, | ||
| 1093 | prop[XLFD_SPACING_INDEX]); | ||
| 1094 | if (! INTEGERP (val)) | ||
| 1095 | return -1; | ||
| 1096 | ASET (font, FONT_SPACING_INDEX, val); | ||
| 1097 | } | ||
| 1104 | if (INTEGERP (prop[XLFD_AVGWIDTH_INDEX])) | 1098 | if (INTEGERP (prop[XLFD_AVGWIDTH_INDEX])) |
| 1105 | avgwidth = XINT (prop[XLFD_AVGWIDTH_INDEX]); | 1099 | ASET (font, FONT_AVGWIDTH_INDEX, prop[XLFD_AVGWIDTH_INDEX]); |
| 1106 | } | 1100 | } |
| 1107 | 1101 | ||
| 1108 | if (! NILP (dpi)) | ||
| 1109 | font_put_extra (font, QCdpi, dpi); | ||
| 1110 | if (! NILP (spacing)) | ||
| 1111 | font_put_extra (font, QCspacing, spacing); | ||
| 1112 | if (avgwidth >= 0) | ||
| 1113 | font_put_extra (font, QCscalable, avgwidth == 0 ? Qt : Qnil); | ||
| 1114 | |||
| 1115 | return 0; | 1102 | return 0; |
| 1116 | } | 1103 | } |
| 1117 | 1104 | ||
| @@ -1176,16 +1163,12 @@ font_unparse_xlfd (font, pixel_size, name, nbytes) | |||
| 1176 | for (i = FONT_WEIGHT_INDEX, j = XLFD_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX; | 1163 | for (i = FONT_WEIGHT_INDEX, j = XLFD_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX; |
| 1177 | i++, j++) | 1164 | i++, j++) |
| 1178 | { | 1165 | { |
| 1179 | val = AREF (font, i); | 1166 | val = font_style_symbolic (font, i, 0); |
| 1180 | if (NILP (val)) | 1167 | if (NILP (val)) |
| 1181 | f[j] = "*", len += 2; | 1168 | f[j] = "*", len += 2; |
| 1182 | else | 1169 | else |
| 1183 | { | 1170 | { |
| 1184 | if (INTEGERP (val)) | 1171 | val = SYMBOL_NAME (val); |
| 1185 | val = prop_numeric_to_name (i, XINT (val)); | ||
| 1186 | if (SYMBOLP (val)) | ||
| 1187 | val = SYMBOL_NAME (val); | ||
| 1188 | xassert (STRINGP (val)); | ||
| 1189 | f[j] = (char *) SDATA (val), len += SBYTES (val) + 1; | 1172 | f[j] = (char *) SDATA (val), len += SBYTES (val) + 1; |
| 1190 | } | 1173 | } |
| 1191 | } | 1174 | } |
| @@ -1194,7 +1177,7 @@ font_unparse_xlfd (font, pixel_size, name, nbytes) | |||
| 1194 | xassert (NUMBERP (val) || NILP (val)); | 1177 | xassert (NUMBERP (val) || NILP (val)); |
| 1195 | if (INTEGERP (val)) | 1178 | if (INTEGERP (val)) |
| 1196 | { | 1179 | { |
| 1197 | int i = XINT (val); | 1180 | i = XINT (val); |
| 1198 | if (i <= 0) | 1181 | if (i <= 0) |
| 1199 | i = pixel_size; | 1182 | i = pixel_size; |
| 1200 | if (i > 0) | 1183 | if (i > 0) |
| @@ -1207,81 +1190,52 @@ font_unparse_xlfd (font, pixel_size, name, nbytes) | |||
| 1207 | } | 1190 | } |
| 1208 | else if (FLOATP (val)) | 1191 | else if (FLOATP (val)) |
| 1209 | { | 1192 | { |
| 1210 | int i = XFLOAT_DATA (val) * 10; | 1193 | i = XFLOAT_DATA (val) * 10; |
| 1211 | f[XLFD_PIXEL_INDEX] = alloca (12); | 1194 | f[XLFD_PIXEL_INDEX] = alloca (12); |
| 1212 | len += sprintf (f[XLFD_PIXEL_INDEX], "*-%d", i) + 1; | 1195 | len += sprintf (f[XLFD_PIXEL_INDEX], "*-%d", i) + 1; |
| 1213 | } | 1196 | } |
| 1214 | else | 1197 | else |
| 1215 | f[XLFD_PIXEL_INDEX] = "*-*", len += 4; | 1198 | f[XLFD_PIXEL_INDEX] = "*-*", len += 4; |
| 1216 | 1199 | ||
| 1217 | val = AREF (font, FONT_EXTRA_INDEX); | 1200 | if (INTEGERP (AREF (font, FONT_DPI_INDEX))) |
| 1218 | |||
| 1219 | if (FONT_ENTITY_P (font) | ||
| 1220 | && EQ (AREF (font, FONT_TYPE_INDEX), Qx)) | ||
| 1221 | { | 1201 | { |
| 1222 | /* Setup names for RESX-RESY-SPACING-AVWIDTH. */ | 1202 | i = XINT (AREF (font, FONT_DPI_INDEX)); |
| 1223 | if (SYMBOLP (val) && ! NILP (val)) | 1203 | f[XLFD_RESX_INDEX] = alloca (22); |
| 1224 | { | 1204 | len += sprintf (f[XLFD_RESX_INDEX], |
| 1225 | val = SYMBOL_NAME (val); | 1205 | "%d-%d", i, i) + 1; |
| 1226 | f[XLFD_RESX_INDEX] = (char *) SDATA (val), len += SBYTES (val) + 1; | ||
| 1227 | } | ||
| 1228 | else | ||
| 1229 | f[XLFD_RESX_INDEX] = "*-*-*-*", len += 6; | ||
| 1230 | } | 1206 | } |
| 1231 | else | 1207 | else |
| 1208 | f[XLFD_RESX_INDEX] = "*-*", len += 4; | ||
| 1209 | if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) | ||
| 1232 | { | 1210 | { |
| 1233 | Lisp_Object dpi = assq_no_quit (QCdpi, val); | 1211 | int spacing = XINT (AREF (font, FONT_SPACING_INDEX)); |
| 1234 | Lisp_Object spacing = assq_no_quit (QCspacing, val); | ||
| 1235 | Lisp_Object scalable = assq_no_quit (QCscalable, val); | ||
| 1236 | |||
| 1237 | if (CONSP (dpi) || CONSP (spacing) || CONSP (scalable)) | ||
| 1238 | { | ||
| 1239 | char *str = alloca (24); | ||
| 1240 | int this_len; | ||
| 1241 | 1212 | ||
| 1242 | if (CONSP (dpi) && INTEGERP (XCDR (dpi))) | 1213 | f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p" |
| 1243 | this_len = sprintf (str, "%d-%d", | 1214 | : spacing <= FONT_SPACING_DUAL ? "d" |
| 1244 | XINT (XCDR (dpi)), XINT (XCDR (dpi))); | 1215 | : spacing <= FONT_SPACING_MONO ? "m" |
| 1245 | else | 1216 | : "c"); |
| 1246 | this_len = sprintf (str, "*-*"); | 1217 | len += 2; |
| 1247 | if (CONSP (spacing) && ! NILP (XCDR (spacing))) | ||
| 1248 | { | ||
| 1249 | val = XCDR (spacing); | ||
| 1250 | if (INTEGERP (val)) | ||
| 1251 | { | ||
| 1252 | if (XINT (val) < FONT_SPACING_MONO) | ||
| 1253 | val = Qp; | ||
| 1254 | else if (XINT (val) < FONT_SPACING_CHARCELL) | ||
| 1255 | val = Qm; | ||
| 1256 | else | ||
| 1257 | val = Qc; | ||
| 1258 | } | ||
| 1259 | xassert (SYMBOLP (val)); | ||
| 1260 | this_len += sprintf (str + this_len, "-%c", | ||
| 1261 | SDATA (SYMBOL_NAME (val))[0]); | ||
| 1262 | } | ||
| 1263 | else | ||
| 1264 | this_len += sprintf (str + this_len, "-*"); | ||
| 1265 | if (CONSP (scalable) && ! NILP (XCDR (spacing))) | ||
| 1266 | this_len += sprintf (str + this_len, "-0"); | ||
| 1267 | else | ||
| 1268 | this_len += sprintf (str + this_len, "-*"); | ||
| 1269 | f[XLFD_RESX_INDEX] = str; | ||
| 1270 | len += this_len; | ||
| 1271 | } | ||
| 1272 | else | ||
| 1273 | f[XLFD_RESX_INDEX] = "*-*-*-*", len += 8; | ||
| 1274 | } | 1218 | } |
| 1275 | 1219 | else | |
| 1220 | f[XLFD_SPACING_INDEX] = "*", len += 2; | ||
| 1221 | if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) | ||
| 1222 | { | ||
| 1223 | f[XLFD_AVGWIDTH_INDEX] = alloca (11); | ||
| 1224 | len += sprintf (f[XLFD_AVGWIDTH_INDEX], | ||
| 1225 | "%d", XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1; | ||
| 1226 | } | ||
| 1227 | else | ||
| 1228 | f[XLFD_AVGWIDTH_INDEX] = "*", len += 2; | ||
| 1276 | len++; /* for terminating '\0'. */ | 1229 | len++; /* for terminating '\0'. */ |
| 1277 | if (len >= nbytes) | 1230 | if (len >= nbytes) |
| 1278 | return -1; | 1231 | return -1; |
| 1279 | return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s", | 1232 | return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", |
| 1280 | f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX], | 1233 | f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX], |
| 1281 | f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX], | 1234 | f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX], |
| 1282 | f[XLFD_SWIDTH_INDEX], | 1235 | f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX], |
| 1283 | f[XLFD_ADSTYLE_INDEX], f[XLFD_PIXEL_INDEX], | 1236 | f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX], |
| 1284 | f[XLFD_RESX_INDEX], f[XLFD_REGISTRY_INDEX]); | 1237 | f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX], |
| 1238 | f[XLFD_REGISTRY_INDEX]); | ||
| 1285 | } | 1239 | } |
| 1286 | 1240 | ||
| 1287 | /* Parse NAME (null terminated) as Fonconfig's name format and store | 1241 | /* Parse NAME (null terminated) as Fonconfig's name format and store |
| @@ -1296,8 +1250,6 @@ font_parse_fcname (name, font) | |||
| 1296 | char *p0, *p1; | 1250 | char *p0, *p1; |
| 1297 | int len = strlen (name); | 1251 | int len = strlen (name); |
| 1298 | char *copy; | 1252 | char *copy; |
| 1299 | int weight_set = 0; | ||
| 1300 | int slant_set = 0; | ||
| 1301 | 1253 | ||
| 1302 | if (len == 0) | 1254 | if (len == 0) |
| 1303 | return -1; | 1255 | return -1; |
| @@ -1312,7 +1264,7 @@ font_parse_fcname (name, font) | |||
| 1312 | for (p0 = name + 1; *p0 && (*p0 != '-' && *p0 != ':'); p0++) | 1264 | for (p0 = name + 1; *p0 && (*p0 != '-' && *p0 != ':'); p0++) |
| 1313 | if (*p0 == '\\' && p0[1]) | 1265 | if (*p0 == '\\' && p0[1]) |
| 1314 | p0++; | 1266 | p0++; |
| 1315 | family = intern_font_field (name, p0 - name); | 1267 | family = font_intern_prop (name, p0 - name); |
| 1316 | if (*p0 == '-') | 1268 | if (*p0 == '-') |
| 1317 | { | 1269 | { |
| 1318 | if (! isdigit (p0[1])) | 1270 | if (! isdigit (p0[1])) |
| @@ -1333,7 +1285,8 @@ font_parse_fcname (name, font) | |||
| 1333 | name = copy; | 1285 | name = copy; |
| 1334 | 1286 | ||
| 1335 | /* Now parse ":KEY=VAL" patterns. Store known keys and values in | 1287 | /* Now parse ":KEY=VAL" patterns. Store known keys and values in |
| 1336 | extra, copy unknown ones to COPY. */ | 1288 | extra, copy unknown ones to COPY. It is stored in extra slot by |
| 1289 | the key QCfc_unknown_spec. */ | ||
| 1337 | while (*p0) | 1290 | while (*p0) |
| 1338 | { | 1291 | { |
| 1339 | Lisp_Object key, val; | 1292 | Lisp_Object key, val; |
| @@ -1343,30 +1296,26 @@ font_parse_fcname (name, font) | |||
| 1343 | if (*p1 != '=') | 1296 | if (*p1 != '=') |
| 1344 | { | 1297 | { |
| 1345 | /* Must be an enumerated value. */ | 1298 | /* Must be an enumerated value. */ |
| 1346 | val = intern_font_field (p0 + 1, p1 - p0 - 1); | 1299 | val = font_intern_prop (p0 + 1, p1 - p0 - 1); |
| 1347 | if (memcmp (p0 + 1, "light", 5) == 0 | 1300 | if (memcmp (p0 + 1, "light", 5) == 0 |
| 1348 | || memcmp (p0 + 1, "medium", 6) == 0 | 1301 | || memcmp (p0 + 1, "medium", 6) == 0 |
| 1349 | || memcmp (p0 + 1, "demibold", 8) == 0 | 1302 | || memcmp (p0 + 1, "demibold", 8) == 0 |
| 1350 | || memcmp (p0 + 1, "bold", 4) == 0 | 1303 | || memcmp (p0 + 1, "bold", 4) == 0 |
| 1351 | || memcmp (p0 + 1, "black", 5) == 0) | 1304 | || memcmp (p0 + 1, "black", 5) == 0) |
| 1352 | { | 1305 | FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, val); |
| 1353 | ASET (font, FONT_WEIGHT_INDEX, val); | ||
| 1354 | weight_set = 1; | ||
| 1355 | } | ||
| 1356 | else if (memcmp (p0 + 1, "roman", 5) == 0 | 1306 | else if (memcmp (p0 + 1, "roman", 5) == 0 |
| 1357 | || memcmp (p0 + 1, "italic", 6) == 0 | 1307 | || memcmp (p0 + 1, "italic", 6) == 0 |
| 1358 | || memcmp (p0 + 1, "oblique", 7) == 0) | 1308 | || memcmp (p0 + 1, "oblique", 7) == 0) |
| 1359 | { | 1309 | FONT_SET_STYLE (font, FONT_SLANT_INDEX, val); |
| 1360 | ASET (font, FONT_SLANT_INDEX, val); | ||
| 1361 | slant_set = 1; | ||
| 1362 | } | ||
| 1363 | else if (memcmp (p0 + 1, "charcell", 8) == 0 | 1310 | else if (memcmp (p0 + 1, "charcell", 8) == 0 |
| 1364 | || memcmp (p0 + 1, "mono", 4) == 0 | 1311 | || memcmp (p0 + 1, "mono", 4) == 0 |
| 1365 | || memcmp (p0 + 1, "proportional", 12) == 0) | 1312 | || memcmp (p0 + 1, "proportional", 12) == 0) |
| 1366 | { | 1313 | { |
| 1367 | font_put_extra (font, QCspacing, | 1314 | int spacing = (p0[1] == 'c' ? FONT_SPACING_CHARCELL |
| 1368 | (p0[1] == 'c' ? Qc : p0[1] == 'm' ? Qm : Qp)); | 1315 | : p0[1] == 'm' ? FONT_SPACING_MONO |
| 1369 | } | 1316 | : FONT_SPACING_PROPORTIONAL); |
| 1317 | ASET (font, FONT_SPACING_INDEX, make_number (spacing)); | ||
| 1318 | } | ||
| 1370 | else | 1319 | else |
| 1371 | { | 1320 | { |
| 1372 | /* unknown key */ | 1321 | /* unknown key */ |
| @@ -1380,34 +1329,28 @@ font_parse_fcname (name, font) | |||
| 1380 | prop = FONT_SIZE_INDEX; | 1329 | prop = FONT_SIZE_INDEX; |
| 1381 | else | 1330 | else |
| 1382 | { | 1331 | { |
| 1383 | key = intern_font_field (p0, p1 - p0); | 1332 | key = font_intern_prop (p0, p1 - p0); |
| 1384 | prop = get_font_prop_index (key, 0); | 1333 | prop = get_font_prop_index (key); |
| 1385 | } | 1334 | } |
| 1386 | p0 = p1 + 1; | 1335 | p0 = p1 + 1; |
| 1387 | for (p1 = p0; *p1 && *p1 != ':'; p1++); | 1336 | for (p1 = p0; *p1 && *p1 != ':'; p1++); |
| 1388 | val = intern_font_field (p0, p1 - p0); | 1337 | val = font_intern_prop (p0, p1 - p0); |
| 1389 | if (! NILP (val)) | 1338 | if (! NILP (val)) |
| 1390 | { | 1339 | { |
| 1391 | if (prop >= 0 && prop < FONT_EXTRA_INDEX) | 1340 | if (prop >= FONT_FOUNDRY_INDEX && prop < FONT_EXTRA_INDEX) |
| 1392 | { | 1341 | ASET (font, prop, font_prop_validate (prop, Qnil, val)); |
| 1393 | if (prop == FONT_WEIGHT_INDEX) | 1342 | else if (prop >= 0) |
| 1394 | weight_set = 1; | 1343 | Ffont_put (font, key, val); |
| 1395 | else if (prop == FONT_SLANT_INDEX) | ||
| 1396 | slant_set = 1; | ||
| 1397 | |||
| 1398 | ASET (font, prop, val); | ||
| 1399 | } | ||
| 1400 | else | 1344 | else |
| 1401 | font_put_extra (font, key, val); | 1345 | bcopy (p0 - 1, copy, p1 - p0 + 1); |
| 1346 | copy += p1 - p0 + 1; | ||
| 1402 | } | 1347 | } |
| 1403 | } | 1348 | } |
| 1404 | p0 = p1; | 1349 | p0 = p1; |
| 1405 | } | 1350 | } |
| 1406 | 1351 | if (name != copy) | |
| 1407 | if (!weight_set) | 1352 | font_put_extra (font, QCfc_unknown_spec, |
| 1408 | ASET (font, FONT_WEIGHT_INDEX, build_string ("normal")); | 1353 | make_unibyte_string (name, copy - name)); |
| 1409 | if (!slant_set) | ||
| 1410 | ASET (font, FONT_SLANT_INDEX, build_string ("normal")); | ||
| 1411 | 1354 | ||
| 1412 | return 0; | 1355 | return 0; |
| 1413 | } | 1356 | } |
| @@ -1423,17 +1366,18 @@ font_unparse_fcname (font, pixel_size, name, nbytes) | |||
| 1423 | char *name; | 1366 | char *name; |
| 1424 | int nbytes; | 1367 | int nbytes; |
| 1425 | { | 1368 | { |
| 1426 | Lisp_Object val; | 1369 | Lisp_Object tail, val; |
| 1427 | int point_size; | 1370 | int point_size; |
| 1428 | int dpi, spacing, scalable; | 1371 | int dpi, spacing, avgwidth; |
| 1429 | int i, len = 1; | 1372 | int i, len = 1; |
| 1430 | char *p; | 1373 | char *p; |
| 1431 | Lisp_Object styles[3]; | 1374 | Lisp_Object styles[3]; |
| 1432 | char *style_names[3] = { "weight", "slant", "width" }; | 1375 | char *style_names[3] = { "weight", "slant", "width" }; |
| 1376 | char work[256]; | ||
| 1433 | 1377 | ||
| 1434 | val = AREF (font, FONT_FAMILY_INDEX); | 1378 | val = AREF (font, FONT_FAMILY_INDEX); |
| 1435 | if (SYMBOLP (val) && ! NILP (val)) | 1379 | if (STRINGP (val)) |
| 1436 | len += SBYTES (SYMBOL_NAME (val)); | 1380 | len += SBYTES (val); |
| 1437 | 1381 | ||
| 1438 | val = AREF (font, FONT_SIZE_INDEX); | 1382 | val = AREF (font, FONT_SIZE_INDEX); |
| 1439 | if (INTEGERP (val)) | 1383 | if (INTEGERP (val)) |
| @@ -1451,64 +1395,44 @@ font_unparse_fcname (font, pixel_size, name, nbytes) | |||
| 1451 | } | 1395 | } |
| 1452 | 1396 | ||
| 1453 | val = AREF (font, FONT_FOUNDRY_INDEX); | 1397 | val = AREF (font, FONT_FOUNDRY_INDEX); |
| 1454 | if (SYMBOLP (val) && ! NILP (val)) | 1398 | if (STRINGP (val)) |
| 1455 | /* ":foundry=NAME" */ | 1399 | /* ":foundry=NAME" */ |
| 1456 | len += 9 + SBYTES (SYMBOL_NAME (val)); | 1400 | len += 9 + SBYTES (val); |
| 1457 | 1401 | ||
| 1458 | for (i = FONT_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX; i++) | 1402 | for (i = 0; i < 3; i++) |
| 1459 | { | 1403 | { |
| 1460 | val = AREF (font, i); | 1404 | int this_len; |
| 1461 | if (INTEGERP (val)) | ||
| 1462 | { | ||
| 1463 | val = prop_numeric_to_name (i, XINT (val)); | ||
| 1464 | } | ||
| 1465 | if (SYMBOLP (val) && ! NILP (val)) | ||
| 1466 | len += (strlen (style_names[i - FONT_WEIGHT_INDEX]) | ||
| 1467 | + 2 + SBYTES (SYMBOL_NAME (val))); /* :xxx=NAME */ | ||
| 1468 | styles[i - FONT_WEIGHT_INDEX] = val; | ||
| 1469 | } | ||
| 1470 | 1405 | ||
| 1471 | val = AREF (font, FONT_EXTRA_INDEX); | 1406 | styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0); |
| 1472 | if (FONT_ENTITY_P (font) | 1407 | if (! NILP (styles[i])) |
| 1473 | && EQ (AREF (font, FONT_TYPE_INDEX), Qx)) | 1408 | len += sprintf (work, ":%s=%s", style_names[i], |
| 1474 | { | 1409 | SDATA (SYMBOL_NAME (styles[i]))); |
| 1475 | char *p; | ||
| 1476 | |||
| 1477 | /* VAL is a symbol of name `RESX-RESY-SPACING-AVWIDTH'. */ | ||
| 1478 | p = (char *) SDATA (SYMBOL_NAME (val)); | ||
| 1479 | dpi = atoi (p); | ||
| 1480 | for (p++; *p != '-'; p++); /* skip RESX */ | ||
| 1481 | for (p++; *p != '-'; p++); /* skip RESY */ | ||
| 1482 | spacing = (*p == 'c' ? FONT_SPACING_CHARCELL | ||
| 1483 | : *p == 'm' ? FONT_SPACING_MONO | ||
| 1484 | : FONT_SPACING_PROPORTIONAL); | ||
| 1485 | for (p++; *p != '-'; p++); /* skip SPACING */ | ||
| 1486 | scalable = (atoi (p) == 0); | ||
| 1487 | /* The longest pattern is ":dpi=NUM:scalable=False:spacing=100" */ | ||
| 1488 | len += 42; | ||
| 1489 | } | 1410 | } |
| 1490 | else | 1411 | |
| 1412 | if (INTEGERP (AREF (font, FONT_DPI_INDEX))) | ||
| 1413 | len += sprintf (work, ":dpi=%d", dpi); | ||
| 1414 | if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) | ||
| 1415 | len += strlen (":spacing=100"); | ||
| 1416 | if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) | ||
| 1417 | len += strlen (":scalable=false"); /* or ":scalable=true" */ | ||
| 1418 | for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) | ||
| 1491 | { | 1419 | { |
| 1492 | Lisp_Object elt; | 1420 | Lisp_Object key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail)); |
| 1493 | 1421 | ||
| 1494 | dpi = spacing = scalable = -1; | 1422 | len += SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY= */ |
| 1495 | elt = assq_no_quit (QCdpi, val); | 1423 | if (STRINGP (val)) |
| 1496 | if (CONSP (elt)) | 1424 | len += SBYTES (val); |
| 1497 | dpi = XINT (XCDR (elt)), len += 15; /* for ":dpi=NUM" */ | 1425 | else if (INTEGERP (val)) |
| 1498 | elt = assq_no_quit (QCspacing, val); | 1426 | len += sprintf (work, "%d", XINT (val)); |
| 1499 | if (CONSP (elt)) | 1427 | else if (SYMBOLP (val)) |
| 1500 | spacing = XINT (XCDR (elt)), len += 12; /* for ":spacing=100" */ | 1428 | len += (NILP (val) ? 5 : 4); /* for "false" or "true" */ |
| 1501 | elt = assq_no_quit (QCscalable, val); | ||
| 1502 | if (CONSP (elt)) | ||
| 1503 | scalable = ! NILP (XCDR (elt)), len += 15; /* for ":scalable=False" */ | ||
| 1504 | } | 1429 | } |
| 1505 | 1430 | ||
| 1506 | if (len > nbytes) | 1431 | if (len > nbytes) |
| 1507 | return -1; | 1432 | return -1; |
| 1508 | p = name; | 1433 | p = name; |
| 1509 | if (! NILP (AREF (font, FONT_FAMILY_INDEX))) | 1434 | if (! NILP (AREF (font, FONT_FAMILY_INDEX))) |
| 1510 | p += sprintf(p, "%s", | 1435 | p += sprintf(p, "%s", SDATA (SYMBOL_NAME (AREF (font, FONT_FAMILY_INDEX)))); |
| 1511 | SDATA (SYMBOL_NAME (AREF (font, FONT_FAMILY_INDEX)))); | ||
| 1512 | if (point_size > 0) | 1436 | if (point_size > 0) |
| 1513 | { | 1437 | { |
| 1514 | if (p == name) | 1438 | if (p == name) |
| @@ -1518,32 +1442,30 @@ font_unparse_fcname (font, pixel_size, name, nbytes) | |||
| 1518 | } | 1442 | } |
| 1519 | else if (pixel_size > 0) | 1443 | else if (pixel_size > 0) |
| 1520 | p += sprintf (p, ":pixelsize=%d", pixel_size); | 1444 | p += sprintf (p, ":pixelsize=%d", pixel_size); |
| 1521 | if (SYMBOLP (AREF (font, FONT_FOUNDRY_INDEX)) | 1445 | if (! NILP (AREF (font, FONT_FOUNDRY_INDEX))) |
| 1522 | && ! NILP (AREF (font, FONT_FOUNDRY_INDEX))) | ||
| 1523 | p += sprintf (p, ":foundry=%s", | 1446 | p += sprintf (p, ":foundry=%s", |
| 1524 | SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX)))); | 1447 | SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX)))); |
| 1525 | for (i = 0; i < 3; i++) | 1448 | for (i = 0; i < 3; i++) |
| 1526 | if (SYMBOLP (styles[i]) && ! NILP (styles [i])) | 1449 | if (! NILP (styles[i])) |
| 1527 | p += sprintf (p, ":%s=%s", style_names[i], | 1450 | p += sprintf (p, ":%s=%s", style_names[i], |
| 1528 | SDATA (SYMBOL_NAME (styles [i]))); | 1451 | SDATA (SYMBOL_NAME (styles[i]))); |
| 1529 | if (dpi >= 0) | 1452 | if (INTEGERP (AREF (font, FONT_DPI_INDEX))) |
| 1530 | p += sprintf (p, ":dpi=%d", dpi); | 1453 | p += sprintf (p, ":dpi=%d", XINT (AREF (font, FONT_DPI_INDEX))); |
| 1531 | if (spacing >= 0) | 1454 | if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) |
| 1532 | p += sprintf (p, ":spacing=%d", spacing); | 1455 | p += sprintf (p, ":spacing=%d", XINT (AREF (font, FONT_SPACING_INDEX))); |
| 1533 | if (scalable > 0) | 1456 | if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) |
| 1534 | p += sprintf (p, ":scalable=True"); | 1457 | { |
| 1535 | else if (scalable == 0) | 1458 | if (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0) |
| 1536 | p += sprintf (p, ":scalable=False"); | 1459 | p += sprintf (p, ":scalable=true"); |
| 1460 | else | ||
| 1461 | p += sprintf (p, ":scalable=false"); | ||
| 1462 | } | ||
| 1537 | return (p - name); | 1463 | return (p - name); |
| 1538 | } | 1464 | } |
| 1539 | 1465 | ||
| 1540 | /* Parse NAME (null terminated) and store information in FONT | 1466 | /* Parse NAME (null terminated) and store information in FONT |
| 1541 | (font-spec or font-entity). If NAME is successfully parsed, return | 1467 | (font-spec or font-entity). If NAME is successfully parsed, return |
| 1542 | 0. Otherwise return -1. | 1468 | 0. Otherwise return -1. */ |
| 1543 | |||
| 1544 | If NAME is XLFD and FONT is a font-entity, store | ||
| 1545 | RESX-RESY-SPACING-AVWIDTH information as a symbol in | ||
| 1546 | FONT_EXTRA_INDEX. */ | ||
| 1547 | 1469 | ||
| 1548 | static int | 1470 | static int |
| 1549 | font_parse_name (name, font) | 1471 | font_parse_name (name, font) |
| @@ -1555,57 +1477,58 @@ font_parse_name (name, font) | |||
| 1555 | return font_parse_fcname (name, font); | 1477 | return font_parse_fcname (name, font); |
| 1556 | } | 1478 | } |
| 1557 | 1479 | ||
| 1558 | /* Merge old style font specification (either a font name NAME or a | 1480 | |
| 1559 | combination of a family name FAMILY and a registry name REGISTRY | 1481 | /* Merge FAMILY and REGISTRY into FONT_SPEC. FAMILY may have the form |
| 1560 | into the font specification SPEC. */ | 1482 | "FAMILY-FOUNDRY". REGISTRY may not contain charset-encoding |
| 1483 | part. */ | ||
| 1561 | 1484 | ||
| 1562 | void | 1485 | void |
| 1563 | font_merge_old_spec (name, family, registry, spec) | 1486 | font_parse_family_registry (family, registry, font_spec) |
| 1564 | Lisp_Object name, family, registry, spec; | 1487 | Lisp_Object family, registry, font_spec; |
| 1565 | { | 1488 | { |
| 1566 | if (STRINGP (name)) | 1489 | int len; |
| 1490 | char *p0, *p1; | ||
| 1491 | |||
| 1492 | if (! NILP (family)) | ||
| 1567 | { | 1493 | { |
| 1568 | if (font_parse_xlfd ((char *) SDATA (name), spec) < 0) | 1494 | CHECK_STRING (family); |
| 1495 | len = SBYTES (family); | ||
| 1496 | p0 = (char *) SDATA (family); | ||
| 1497 | p1 = index (p0, '-'); | ||
| 1498 | if (p1) | ||
| 1569 | { | 1499 | { |
| 1570 | Lisp_Object extra = Fcons (Fcons (QCname, name), Qnil); | 1500 | if (*p0 != '*' || p1 - p0 > 1) |
| 1571 | 1501 | ASET (font_spec, FONT_FOUNDRY_INDEX, | |
| 1572 | ASET (spec, FONT_EXTRA_INDEX, extra); | 1502 | font_intern_prop (p0, p1 - p0)); |
| 1503 | p1++; | ||
| 1504 | len -= p1 - p0; | ||
| 1505 | ASET (font_spec, FONT_FAMILY_INDEX, font_intern_prop (p1, len)); | ||
| 1573 | } | 1506 | } |
| 1507 | else | ||
| 1508 | ASET (font_spec, FONT_FAMILY_INDEX, Fintern (family, Qnil)); | ||
| 1574 | } | 1509 | } |
| 1575 | else | 1510 | if (! NILP (registry)) |
| 1576 | { | 1511 | { |
| 1577 | if (! NILP (family)) | 1512 | /* Convert "XXX" and "XXX*" to "XXX*-*". */ |
| 1513 | CHECK_STRING (registry); | ||
| 1514 | len = SBYTES (registry); | ||
| 1515 | p0 = (char *) SDATA (registry); | ||
| 1516 | p1 = index (p0, '-'); | ||
| 1517 | if (! p1) | ||
| 1578 | { | 1518 | { |
| 1579 | int len; | 1519 | if (SDATA (registry)[len - 1] == '*') |
| 1580 | char *p0, *p1; | 1520 | registry = concat2 (registry, build_string ("-*")); |
| 1581 | 1521 | else | |
| 1582 | xassert (STRINGP (family)); | 1522 | registry = concat2 (registry, build_string ("*-*")); |
| 1583 | len = SBYTES (family); | ||
| 1584 | p0 = (char *) SDATA (family); | ||
| 1585 | p1 = index (p0, '-'); | ||
| 1586 | if (p1) | ||
| 1587 | { | ||
| 1588 | if ((*p0 != '*' || p1 - p0 > 1) | ||
| 1589 | && NILP (AREF (spec, FONT_FOUNDRY_INDEX))) | ||
| 1590 | ASET (spec, FONT_FOUNDRY_INDEX, | ||
| 1591 | intern_downcase (p0, p1 - p0)); | ||
| 1592 | if (NILP (AREF (spec, FONT_FAMILY_INDEX))) | ||
| 1593 | ASET (spec, FONT_FAMILY_INDEX, | ||
| 1594 | intern_downcase (p1 + 1, len - (p1 + 1 - p0))); | ||
| 1595 | } | ||
| 1596 | else if (NILP (AREF (spec, FONT_FAMILY_INDEX))) | ||
| 1597 | ASET (spec, FONT_FAMILY_INDEX, intern_downcase (p0, len)); | ||
| 1598 | } | 1523 | } |
| 1599 | if (! NILP (registry) | 1524 | registry = Fdowncase (registry); |
| 1600 | && NILP (AREF (spec, FONT_REGISTRY_INDEX))) | 1525 | ASET (font_spec, FONT_REGISTRY_INDEX, Fintern (registry, Qnil)); |
| 1601 | ASET (spec, FONT_REGISTRY_INDEX, | ||
| 1602 | intern_downcase ((char *) SDATA (registry), SBYTES (registry))); | ||
| 1603 | } | 1526 | } |
| 1604 | } | 1527 | } |
| 1605 | 1528 | ||
| 1606 | 1529 | ||
| 1607 | /* This part (through the next ^L) is still experimental and never | 1530 | /* This part (through the next ^L) is still experimental and not |
| 1608 | tested. We may drastically change codes. */ | 1531 | tested much. We may drastically change codes. */ |
| 1609 | 1532 | ||
| 1610 | /* OTF handler */ | 1533 | /* OTF handler */ |
| 1611 | 1534 | ||
| @@ -1671,7 +1594,7 @@ static void | |||
| 1671 | check_otf_features (otf_features) | 1594 | check_otf_features (otf_features) |
| 1672 | Lisp_Object otf_features; | 1595 | Lisp_Object otf_features; |
| 1673 | { | 1596 | { |
| 1674 | Lisp_Object val, elt; | 1597 | Lisp_Object val; |
| 1675 | 1598 | ||
| 1676 | CHECK_CONS (otf_features); | 1599 | CHECK_CONS (otf_features); |
| 1677 | CHECK_SYMBOL (XCAR (otf_features)); | 1600 | CHECK_SYMBOL (XCAR (otf_features)); |
| @@ -1710,20 +1633,19 @@ otf_tag_symbol (tag) | |||
| 1710 | } | 1633 | } |
| 1711 | 1634 | ||
| 1712 | static OTF * | 1635 | static OTF * |
| 1713 | otf_open (entity, file) | 1636 | otf_open (file) |
| 1714 | Lisp_Object entity; | 1637 | Lisp_Object file; |
| 1715 | char *file; | ||
| 1716 | { | 1638 | { |
| 1717 | Lisp_Object val = Fassoc (entity, otf_list); | 1639 | Lisp_Object val = Fassoc (file, otf_list); |
| 1718 | OTF *otf; | 1640 | OTF *otf; |
| 1719 | 1641 | ||
| 1720 | if (! NILP (val)) | 1642 | if (! NILP (val)) |
| 1721 | otf = XSAVE_VALUE (XCDR (val))->pointer; | 1643 | otf = XSAVE_VALUE (XCDR (val))->pointer; |
| 1722 | else | 1644 | else |
| 1723 | { | 1645 | { |
| 1724 | otf = file ? OTF_open (file) : NULL; | 1646 | otf = STRINGP (file) ? OTF_open ((char *) SDATA (file)) : NULL; |
| 1725 | val = make_save_value (otf, 0); | 1647 | val = make_save_value (otf, 0); |
| 1726 | otf_list = Fcons (Fcons (entity, val), otf_list); | 1648 | otf_list = Fcons (Fcons (file, val), otf_list); |
| 1727 | } | 1649 | } |
| 1728 | return otf; | 1650 | return otf; |
| 1729 | } | 1651 | } |
| @@ -1741,7 +1663,7 @@ font_otf_capability (font) | |||
| 1741 | Lisp_Object capability = Fcons (Qnil, Qnil); | 1663 | Lisp_Object capability = Fcons (Qnil, Qnil); |
| 1742 | int i; | 1664 | int i; |
| 1743 | 1665 | ||
| 1744 | otf = otf_open (font->entity, font->file_name); | 1666 | otf = otf_open (font->props[FONT_FILE_INDEX]); |
| 1745 | if (! otf) | 1667 | if (! otf) |
| 1746 | return Qnil; | 1668 | return Qnil; |
| 1747 | for (i = 0; i < 2; i++) | 1669 | for (i = 0; i < 2; i++) |
| @@ -1814,7 +1736,7 @@ generate_otf_features (spec, features) | |||
| 1814 | char *features; | 1736 | char *features; |
| 1815 | { | 1737 | { |
| 1816 | Lisp_Object val; | 1738 | Lisp_Object val; |
| 1817 | char *p, *pend; | 1739 | char *p; |
| 1818 | int asterisk; | 1740 | int asterisk; |
| 1819 | 1741 | ||
| 1820 | p = features; | 1742 | p = features; |
| @@ -1917,7 +1839,7 @@ font_prepare_composition (cmp, f) | |||
| 1917 | = AREF (XHASH_TABLE (composition_hash_table)->key_and_value, | 1839 | = AREF (XHASH_TABLE (composition_hash_table)->key_and_value, |
| 1918 | cmp->hash_index * 2); | 1840 | cmp->hash_index * 2); |
| 1919 | 1841 | ||
| 1920 | cmp->font = XSAVE_VALUE (LGSTRING_FONT (gstring))->pointer; | 1842 | cmp->font = XFONT_OBJECT (LGSTRING_FONT (gstring)); |
| 1921 | cmp->glyph_len = LGSTRING_LENGTH (gstring); | 1843 | cmp->glyph_len = LGSTRING_LENGTH (gstring); |
| 1922 | cmp->pixel_width = LGSTRING_WIDTH (gstring); | 1844 | cmp->pixel_width = LGSTRING_WIDTH (gstring); |
| 1923 | cmp->lbearing = LGSTRING_LBEARING (gstring); | 1845 | cmp->lbearing = LGSTRING_LBEARING (gstring); |
| @@ -1934,87 +1856,106 @@ font_prepare_composition (cmp, f) | |||
| 1934 | 1856 | ||
| 1935 | /* Font sorting */ | 1857 | /* Font sorting */ |
| 1936 | 1858 | ||
| 1937 | static unsigned font_score P_ ((Lisp_Object, Lisp_Object *)); | 1859 | static unsigned font_score P_ ((Lisp_Object, Lisp_Object *, Lisp_Object)); |
| 1938 | static int font_compare P_ ((const void *, const void *)); | 1860 | static int font_compare P_ ((const void *, const void *)); |
| 1939 | static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object, | 1861 | static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object, |
| 1940 | Lisp_Object, Lisp_Object)); | 1862 | Lisp_Object, Lisp_Object, |
| 1863 | int)); | ||
| 1941 | 1864 | ||
| 1942 | /* We sort fonts by scoring each of them against a specified | 1865 | /* We sort fonts by scoring each of them against a specified |
| 1943 | font-spec. The score value is 32 bit (`unsigned'), and the smaller | 1866 | font-spec. The score value is 32 bit (`unsigned'), and the smaller |
| 1944 | the value is, the closer the font is to the font-spec. | 1867 | the value is, the closer the font is to the font-spec. |
| 1945 | 1868 | ||
| 1946 | Each 1-bit of the highest 4 bits of the score is used for atomic | 1869 | The highest 2 bits of the score is used for FAMILY. The exact |
| 1947 | properties FOUNDRY, FAMILY, ADSTYLE, and REGISTRY. | 1870 | match is 0, match with one of face-font-family-alternatives is |
| 1871 | nonzero. | ||
| 1872 | |||
| 1873 | The next 2 bits of the score is used for the atomic properties | ||
| 1874 | FOUNDRY and ADSTYLE respectively. | ||
| 1948 | 1875 | ||
| 1949 | Each 7-bit in the lowest 28 bits are used for numeric properties | 1876 | Each 7-bit in the lower 28 bits are used for numeric properties |
| 1950 | WEIGHT, SLANT, WIDTH, and SIZE. */ | 1877 | WEIGHT, SLANT, WIDTH, and SIZE. */ |
| 1951 | 1878 | ||
| 1952 | /* How many bits to shift to store the difference value of each font | 1879 | /* How many bits to shift to store the difference value of each font |
| 1953 | property in a score. */ | 1880 | property in a score. Note that flots for FONT_TYPE_INDEX and |
| 1881 | FONT_REGISTRY_INDEX are not used. */ | ||
| 1954 | static int sort_shift_bits[FONT_SIZE_INDEX + 1]; | 1882 | static int sort_shift_bits[FONT_SIZE_INDEX + 1]; |
| 1955 | 1883 | ||
| 1956 | /* Score font-entity ENTITY against properties of font-spec SPEC_PROP. | 1884 | /* Score font-entity ENTITY against properties of font-spec SPEC_PROP. |
| 1957 | The return value indicates how different ENTITY is compared with | 1885 | The return value indicates how different ENTITY is compared with |
| 1958 | SPEC_PROP. */ | 1886 | SPEC_PROP. |
| 1887 | |||
| 1888 | ALTERNATE_FAMILIES, if non-nil, is a pre-calculated list of | ||
| 1889 | alternate family names for AREF (SPEC_PROP, FONT_FAMILY_INDEX). */ | ||
| 1959 | 1890 | ||
| 1960 | static unsigned | 1891 | static unsigned |
| 1961 | font_score (entity, spec_prop) | 1892 | font_score (entity, spec_prop, alternate_families) |
| 1962 | Lisp_Object entity, *spec_prop; | 1893 | Lisp_Object entity, *spec_prop; |
| 1894 | Lisp_Object alternate_families; | ||
| 1963 | { | 1895 | { |
| 1964 | unsigned score = 0; | 1896 | unsigned score = 0; |
| 1965 | int i; | 1897 | int i; |
| 1966 | /* Score four atomic fields. Maximum difference is 1. */ | ||
| 1967 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++) | ||
| 1968 | if (! NILP (spec_prop[i]) | ||
| 1969 | && ! EQ (spec_prop[i], AREF (entity, i))) | ||
| 1970 | score |= 1 << sort_shift_bits[i]; | ||
| 1971 | |||
| 1972 | /* Score four numeric fields. Maximum difference is 127. */ | ||
| 1973 | for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++) | ||
| 1974 | { | ||
| 1975 | Lisp_Object entity_val = AREF (entity, i); | ||
| 1976 | Lisp_Object spec_val = spec_prop[i]; | ||
| 1977 | 1898 | ||
| 1978 | /* If weight and slant are unspecified, score normal lower (low wins). */ | 1899 | /* Score three atomic fields. Maximum difference is 1 (family is 3). */ |
| 1979 | if (NILP (spec_val)) | 1900 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_ADSTYLE_INDEX; i++) |
| 1980 | { | 1901 | if (i != FONT_REGISTRY_INDEX |
| 1981 | if (i == FONT_WEIGHT_INDEX || i == FONT_SLANT_INDEX) | 1902 | && ! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i])) |
| 1982 | spec_val = prop_name_to_numeric (i, build_string ("normal")); | 1903 | { |
| 1983 | } | 1904 | Lisp_Object entity_str = SYMBOL_NAME (AREF (entity, i)); |
| 1905 | Lisp_Object spec_str = SYMBOL_NAME (spec_prop[i]); | ||
| 1984 | 1906 | ||
| 1985 | if (! NILP (spec_val) && ! EQ (spec_val, entity_val)) | 1907 | if (strcasecmp (SDATA (spec_str), SDATA (entity_str))) |
| 1986 | { | 1908 | { |
| 1987 | if (! INTEGERP (entity_val)) | 1909 | if (i == FONT_FAMILY_INDEX && CONSP (alternate_families)) |
| 1988 | score |= 127 << sort_shift_bits[i]; | 1910 | { |
| 1989 | else | 1911 | int j; |
| 1990 | { | 1912 | |
| 1991 | int diff = XINT (entity_val) - XINT (spec_val); | 1913 | for (j = 1; CONSP (alternate_families); |
| 1914 | j++, alternate_families = XCDR (alternate_families)) | ||
| 1915 | { | ||
| 1916 | spec_str = XCAR (alternate_families); | ||
| 1917 | if (strcasecmp (SDATA (spec_str), SDATA (entity_str)) == 0) | ||
| 1918 | break; | ||
| 1919 | |||
| 1920 | } | ||
| 1921 | if (j > 3) | ||
| 1922 | j = 3; | ||
| 1923 | score |= j << sort_shift_bits[i]; | ||
| 1924 | } | ||
| 1925 | else | ||
| 1926 | score |= 1 << sort_shift_bits[i]; | ||
| 1927 | } | ||
| 1928 | } | ||
| 1992 | 1929 | ||
| 1993 | if (diff < 0) | 1930 | /* Score three style numeric fields. Maximum difference is 127. */ |
| 1994 | diff = - diff; | 1931 | for (i = FONT_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX; i++) |
| 1995 | if (i == FONT_SIZE_INDEX) | 1932 | if (! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i])) |
| 1996 | { | 1933 | { |
| 1997 | if (XINT (entity_val) > 0 | 1934 | int diff = (XINT (AREF (entity, i)) >> 8) - (XINT (spec_prop[i]) >> 8); |
| 1998 | && diff > FONT_PIXEL_SIZE_QUANTUM) | 1935 | |
| 1999 | score |= min (diff, 127) << sort_shift_bits[i]; | 1936 | if (diff < 0) |
| 2000 | } | 1937 | diff = - diff; |
| 2001 | #ifdef WINDOWSNT | 1938 | /* This is to prefer the exact symbol style. */ |
| 2002 | else if (i == FONT_WEIGHT_INDEX) | 1939 | diff++; |
| 2003 | { | 1940 | score |= min (diff, 127) << sort_shift_bits[i]; |
| 2004 | /* Windows uses a much wider range for weight (100-900) | 1941 | } |
| 2005 | compared with freetype (0-210), so scale down the | 1942 | |
| 2006 | difference. A more general way of doing this | 1943 | /* Score the size. Maximum difference is 127. */ |
| 2007 | would be to look up the values of regular and bold | 1944 | i = FONT_SIZE_INDEX; |
| 2008 | and/or light and calculate the scale factor from them, | 1945 | if (! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i]) |
| 2009 | but the lookup would be expensive, and if only Windows | 1946 | && XINT (AREF (entity, i)) > 0) |
| 2010 | needs it, not worth the effort. */ | 1947 | { |
| 2011 | score |= min (diff / 4, 127) << sort_shift_bits[i]; | 1948 | /* We use the higher 6-bit for the actual size difference. The |
| 2012 | } | 1949 | lowest bit is set if the DPI is different. */ |
| 2013 | #endif | 1950 | int diff = XINT (spec_prop[i]) - XINT (AREF (entity, i)); |
| 2014 | else | 1951 | |
| 2015 | score |= min (diff, 127) << sort_shift_bits[i]; | 1952 | if (diff < 0) |
| 2016 | } | 1953 | diff = - diff; |
| 2017 | } | 1954 | diff << 1; |
| 1955 | if (! NILP (spec_prop[FONT_DPI_INDEX]) | ||
| 1956 | && ! EQ (spec_prop[FONT_DPI_INDEX], AREF (entity, FONT_DPI_INDEX))) | ||
| 1957 | diff |= 1; | ||
| 1958 | score |= min (diff, 127) << sort_shift_bits[FONT_SIZE_INDEX]; | ||
| 2018 | } | 1959 | } |
| 2019 | 1960 | ||
| 2020 | return score; | 1961 | return score; |
| @@ -2027,8 +1968,7 @@ static int | |||
| 2027 | font_compare (d1, d2) | 1968 | font_compare (d1, d2) |
| 2028 | const void *d1, *d2; | 1969 | const void *d1, *d2; |
| 2029 | { | 1970 | { |
| 2030 | return (*(unsigned *) d1 < *(unsigned *) d2 | 1971 | return (*(unsigned *) d1 - *(unsigned *) d2); |
| 2031 | ? -1 : *(unsigned *) d1 > *(unsigned *) d2); | ||
| 2032 | } | 1972 | } |
| 2033 | 1973 | ||
| 2034 | 1974 | ||
| @@ -2044,48 +1984,81 @@ struct font_sort_data | |||
| 2044 | If PREFER specifies a point-size, calculate the corresponding | 1984 | If PREFER specifies a point-size, calculate the corresponding |
| 2045 | pixel-size from QCdpi property of PREFER or from the Y-resolution | 1985 | pixel-size from QCdpi property of PREFER or from the Y-resolution |
| 2046 | of FRAME before sorting. If SPEC is not nil, it is a font-spec to | 1986 | of FRAME before sorting. If SPEC is not nil, it is a font-spec to |
| 2047 | get the font-entities in VEC. */ | 1987 | get the font-entities in VEC. |
| 1988 | |||
| 1989 | If BEST-ONLY is nonzero, return the best matching entity. Otherwise, | ||
| 1990 | return the sorted VEC. */ | ||
| 2048 | 1991 | ||
| 2049 | static Lisp_Object | 1992 | static Lisp_Object |
| 2050 | font_sort_entites (vec, prefer, frame, spec) | 1993 | font_sort_entites (vec, prefer, frame, spec, best_only) |
| 2051 | Lisp_Object vec, prefer, frame, spec; | 1994 | Lisp_Object vec, prefer, frame, spec; |
| 1995 | int best_only; | ||
| 2052 | { | 1996 | { |
| 2053 | Lisp_Object prefer_prop[FONT_SPEC_MAX]; | 1997 | Lisp_Object prefer_prop[FONT_SPEC_MAX]; |
| 2054 | int len, i; | 1998 | int len, i; |
| 2055 | struct font_sort_data *data; | 1999 | struct font_sort_data *data; |
| 2000 | Lisp_Object alternate_families = Qnil; | ||
| 2001 | unsigned best_score; | ||
| 2002 | Lisp_Object best_entity; | ||
| 2056 | USE_SAFE_ALLOCA; | 2003 | USE_SAFE_ALLOCA; |
| 2057 | 2004 | ||
| 2058 | len = ASIZE (vec); | 2005 | len = ASIZE (vec); |
| 2059 | if (len <= 1) | 2006 | if (len <= 1) |
| 2060 | return vec; | 2007 | return best_only ? AREF (vec, 0) : vec; |
| 2061 | 2008 | ||
| 2062 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++) | 2009 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_DPI_INDEX; i++) |
| 2063 | prefer_prop[i] = AREF (prefer, i); | 2010 | prefer_prop[i] = AREF (prefer, i); |
| 2064 | 2011 | ||
| 2065 | if (! NILP (spec)) | 2012 | if (! NILP (spec)) |
| 2066 | { | 2013 | { |
| 2067 | /* As it is assured that all fonts in VEC match with SPEC, we | 2014 | /* A font driver may return a font that has a property value |
| 2068 | should ignore properties specified in SPEC. So, set the | 2015 | different from the value specified in SPEC if the driver |
| 2069 | corresponding properties in PREFER_PROP to nil. */ | 2016 | thinks they are the same. That happens, for instance, such a |
| 2070 | for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++) | 2017 | generic family name as "serif" is specified. So, to ignore |
| 2018 | such a difference, for all properties specified in SPEC, set | ||
| 2019 | the corresponding properties in PREFER_PROP to nil. */ | ||
| 2020 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++) | ||
| 2071 | if (! NILP (AREF (spec, i))) | 2021 | if (! NILP (AREF (spec, i))) |
| 2072 | prefer_prop[i++] = Qnil; | 2022 | prefer_prop[i] = Qnil; |
| 2073 | } | 2023 | } |
| 2074 | 2024 | ||
| 2075 | if (FLOATP (prefer_prop[FONT_SIZE_INDEX])) | 2025 | if (FLOATP (prefer_prop[FONT_SIZE_INDEX])) |
| 2076 | prefer_prop[FONT_SIZE_INDEX] | 2026 | prefer_prop[FONT_SIZE_INDEX] |
| 2077 | = make_number (font_pixel_size (XFRAME (frame), prefer)); | 2027 | = make_number (font_pixel_size (XFRAME (frame), prefer)); |
| 2028 | if (! NILP (prefer_prop[FONT_FAMILY_INDEX])) | ||
| 2029 | { | ||
| 2030 | alternate_families | ||
| 2031 | = Fassoc_string (prefer_prop[FONT_FAMILY_INDEX], | ||
| 2032 | Vface_alternative_font_family_alist, Qt); | ||
| 2033 | if (CONSP (alternate_families)) | ||
| 2034 | alternate_families = XCDR (alternate_families); | ||
| 2035 | } | ||
| 2078 | 2036 | ||
| 2079 | /* Scoring and sorting. */ | 2037 | /* Scoring and sorting. */ |
| 2080 | SAFE_ALLOCA (data, struct font_sort_data *, (sizeof *data) * len); | 2038 | SAFE_ALLOCA (data, struct font_sort_data *, (sizeof *data) * len); |
| 2039 | best_score = 0xFFFFFFFF; | ||
| 2040 | best_entity = Qnil; | ||
| 2081 | for (i = 0; i < len; i++) | 2041 | for (i = 0; i < len; i++) |
| 2082 | { | 2042 | { |
| 2083 | data[i].entity = AREF (vec, i); | 2043 | data[i].entity = AREF (vec, i); |
| 2084 | data[i].score = font_score (data[i].entity, prefer_prop); | 2044 | data[i].score = font_score (data[i].entity, prefer_prop, |
| 2045 | alternate_families); | ||
| 2046 | if (best_only && best_score > data[i].score) | ||
| 2047 | { | ||
| 2048 | best_score = data[i].score; | ||
| 2049 | best_entity = data[i].entity; | ||
| 2050 | if (best_score == 0) | ||
| 2051 | break; | ||
| 2052 | } | ||
| 2085 | } | 2053 | } |
| 2086 | qsort (data, len, sizeof *data, font_compare); | 2054 | if (NILP (best_entity)) |
| 2087 | for (i = 0; i < len; i++) | 2055 | { |
| 2088 | ASET (vec, i, data[i].entity); | 2056 | qsort (data, len, sizeof *data, font_compare); |
| 2057 | for (i = 0; i < len; i++) | ||
| 2058 | ASET (vec, i, data[i].entity); | ||
| 2059 | } | ||
| 2060 | else | ||
| 2061 | vec = best_entity; | ||
| 2089 | SAFE_FREE (); | 2062 | SAFE_FREE (); |
| 2090 | 2063 | ||
| 2091 | return vec; | 2064 | return vec; |
| @@ -2102,9 +2075,9 @@ void | |||
| 2102 | font_update_sort_order (order) | 2075 | font_update_sort_order (order) |
| 2103 | int *order; | 2076 | int *order; |
| 2104 | { | 2077 | { |
| 2105 | int i, shift_bits = 21; | 2078 | int i, shift_bits; |
| 2106 | 2079 | ||
| 2107 | for (i = 0; i < 4; i++, shift_bits -= 7) | 2080 | for (i = 0, shift_bits = 21; i < 4; i++, shift_bits -= 7) |
| 2108 | { | 2081 | { |
| 2109 | int xlfd_idx = order[i]; | 2082 | int xlfd_idx = order[i]; |
| 2110 | 2083 | ||
| @@ -2120,87 +2093,51 @@ font_update_sort_order (order) | |||
| 2120 | } | 2093 | } |
| 2121 | 2094 | ||
| 2122 | 2095 | ||
| 2123 | /* Return weight property of FONT as symbol. */ | ||
| 2124 | |||
| 2125 | Lisp_Object | ||
| 2126 | font_symbolic_weight (font) | ||
| 2127 | Lisp_Object font; | ||
| 2128 | { | ||
| 2129 | Lisp_Object weight = AREF (font, FONT_WEIGHT_INDEX); | ||
| 2130 | |||
| 2131 | if (INTEGERP (weight)) | ||
| 2132 | weight = prop_numeric_to_name (FONT_WEIGHT_INDEX, XINT (weight)); | ||
| 2133 | return weight; | ||
| 2134 | } | ||
| 2135 | |||
| 2136 | |||
| 2137 | /* Return slant property of FONT as symbol. */ | ||
| 2138 | |||
| 2139 | Lisp_Object | ||
| 2140 | font_symbolic_slant (font) | ||
| 2141 | Lisp_Object font; | ||
| 2142 | { | ||
| 2143 | Lisp_Object slant = AREF (font, FONT_SLANT_INDEX); | ||
| 2144 | |||
| 2145 | if (INTEGERP (slant)) | ||
| 2146 | slant = prop_numeric_to_name (FONT_SLANT_INDEX, XINT (slant)); | ||
| 2147 | return slant; | ||
| 2148 | } | ||
| 2149 | |||
| 2150 | |||
| 2151 | /* Return width property of FONT as symbol. */ | ||
| 2152 | |||
| 2153 | Lisp_Object | ||
| 2154 | font_symbolic_width (font) | ||
| 2155 | Lisp_Object font; | ||
| 2156 | { | ||
| 2157 | Lisp_Object width = AREF (font, FONT_WIDTH_INDEX); | ||
| 2158 | |||
| 2159 | if (INTEGERP (width)) | ||
| 2160 | width = prop_numeric_to_name (FONT_WIDTH_INDEX, XINT (width)); | ||
| 2161 | return width; | ||
| 2162 | } | ||
| 2163 | |||
| 2164 | |||
| 2165 | /* Check if ENTITY matches with the font specification SPEC. */ | 2096 | /* Check if ENTITY matches with the font specification SPEC. */ |
| 2166 | 2097 | ||
| 2167 | int | 2098 | int |
| 2168 | font_match_p (spec, entity) | 2099 | font_match_p (spec, entity) |
| 2169 | Lisp_Object spec, entity; | 2100 | Lisp_Object spec, entity; |
| 2170 | { | 2101 | { |
| 2102 | Lisp_Object prefer_prop[FONT_SPEC_MAX]; | ||
| 2103 | Lisp_Object alternate_families = Qnil; | ||
| 2104 | int prefer_style[3]; | ||
| 2171 | int i; | 2105 | int i; |
| 2172 | 2106 | ||
| 2173 | for (i = FONT_FOUNDRY_INDEX; i < FONT_SIZE_INDEX; i++) | 2107 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++) |
| 2174 | if (! NILP (AREF (spec, i)) | 2108 | prefer_prop[i] = AREF (spec, i); |
| 2175 | && ! EQ (AREF (spec, i), AREF (entity, i))) | 2109 | if (FLOATP (prefer_prop[FONT_SIZE_INDEX])) |
| 2176 | return 0; | 2110 | prefer_prop[FONT_SIZE_INDEX] |
| 2177 | if (INTEGERP (AREF (spec, FONT_SIZE_INDEX)) | 2111 | = make_number (font_pixel_size (XFRAME (selected_frame), spec)); |
| 2178 | && XINT (AREF (entity, FONT_SIZE_INDEX)) > 0 | 2112 | if (! NILP (prefer_prop[FONT_FAMILY_INDEX])) |
| 2179 | && (XINT (AREF (spec, FONT_SIZE_INDEX)) | 2113 | { |
| 2180 | != XINT (AREF (entity, FONT_SIZE_INDEX)))) | 2114 | alternate_families |
| 2181 | return 0; | 2115 | = Fassoc_string (prefer_prop[FONT_FAMILY_INDEX], |
| 2182 | return 1; | 2116 | Vface_alternative_font_family_alist, Qt); |
| 2117 | if (CONSP (alternate_families)) | ||
| 2118 | alternate_families = XCDR (alternate_families); | ||
| 2119 | } | ||
| 2120 | |||
| 2121 | return (font_score (entity, prefer_prop, alternate_families) == 0); | ||
| 2183 | } | 2122 | } |
| 2184 | 2123 | ||
| 2185 | 2124 | ||
| 2186 | /* Return a lispy font object corresponding to FONT. */ | 2125 | /* CHeck a lispy font object corresponding to FONT. */ |
| 2187 | 2126 | ||
| 2188 | Lisp_Object | 2127 | int |
| 2189 | font_find_object (font) | 2128 | font_check_object (font) |
| 2190 | struct font *font; | 2129 | struct font *font; |
| 2191 | { | 2130 | { |
| 2192 | Lisp_Object tail, elt; | 2131 | Lisp_Object tail, elt; |
| 2193 | 2132 | ||
| 2194 | for (tail = AREF (font->entity, FONT_OBJLIST_INDEX); CONSP (tail); | 2133 | for (tail = font->props[FONT_OBJLIST_INDEX]; CONSP (tail); |
| 2195 | tail = XCDR (tail)) | 2134 | tail = XCDR (tail)) |
| 2196 | { | 2135 | { |
| 2197 | elt = XCAR (tail); | 2136 | elt = XCAR (tail); |
| 2198 | if (font == XSAVE_VALUE (elt)->pointer | 2137 | if (font == XFONT_OBJECT (elt)) |
| 2199 | && XSAVE_VALUE (elt)->integer > 0) | 2138 | return 1; |
| 2200 | return elt; | ||
| 2201 | } | 2139 | } |
| 2202 | abort (); | 2140 | return 0; |
| 2203 | return Qnil; | ||
| 2204 | } | 2141 | } |
| 2205 | 2142 | ||
| 2206 | 2143 | ||
| @@ -2316,13 +2253,10 @@ font_clear_cache (f, cache, driver) | |||
| 2316 | for (; CONSP (objlist); objlist = XCDR (objlist)) | 2253 | for (; CONSP (objlist); objlist = XCDR (objlist)) |
| 2317 | { | 2254 | { |
| 2318 | Lisp_Object val = XCAR (objlist); | 2255 | Lisp_Object val = XCAR (objlist); |
| 2319 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); | 2256 | struct font *font = XFONT_OBJECT (val); |
| 2320 | struct font *font = p->pointer; | ||
| 2321 | 2257 | ||
| 2322 | xassert (font && driver == font->driver); | 2258 | xassert (font && driver == font->driver); |
| 2323 | driver->close (f, font); | 2259 | driver->close (f, font); |
| 2324 | p->pointer = NULL; | ||
| 2325 | p->integer = 0; | ||
| 2326 | num_fonts--; | 2260 | num_fonts--; |
| 2327 | } | 2261 | } |
| 2328 | if (driver->free_entity) | 2262 | if (driver->free_entity) |
| @@ -2337,40 +2271,100 @@ font_clear_cache (f, cache, driver) | |||
| 2337 | 2271 | ||
| 2338 | static Lisp_Object scratch_font_spec, scratch_font_prefer; | 2272 | static Lisp_Object scratch_font_spec, scratch_font_prefer; |
| 2339 | 2273 | ||
| 2274 | Lisp_Object | ||
| 2275 | font_delete_unmatched (list, spec, size) | ||
| 2276 | Lisp_Object list, spec; | ||
| 2277 | int size; | ||
| 2278 | { | ||
| 2279 | Lisp_Object entity, prev, tail; | ||
| 2280 | enum font_property_index prop; | ||
| 2340 | 2281 | ||
| 2341 | /* Return a vector of font-entities matching with SPEC on frame F. */ | 2282 | for (tail = list, prev = Qnil; CONSP (tail); ) |
| 2283 | { | ||
| 2284 | entity = XCAR (tail); | ||
| 2285 | for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++) | ||
| 2286 | if (INTEGERP (AREF (spec, prop)) | ||
| 2287 | && ((XINT (AREF (spec, prop)) >> 8) | ||
| 2288 | != (XINT (AREF (entity, prop)) >> 8))) | ||
| 2289 | prop = FONT_SPEC_MAX; | ||
| 2290 | if (prop++ <= FONT_SIZE_INDEX | ||
| 2291 | && size | ||
| 2292 | && XINT (AREF (entity, FONT_SIZE_INDEX)) > 0) | ||
| 2293 | { | ||
| 2294 | int diff = XINT (AREF (entity, FONT_SIZE_INDEX)) - size; | ||
| 2342 | 2295 | ||
| 2343 | static Lisp_Object | 2296 | if (diff != 0 |
| 2297 | && (diff < 0 ? -diff > FONT_PIXEL_SIZE_QUANTUM | ||
| 2298 | : diff > FONT_PIXEL_SIZE_QUANTUM)) | ||
| 2299 | prop = FONT_SPEC_MAX; | ||
| 2300 | } | ||
| 2301 | if (prop < FONT_SPEC_MAX | ||
| 2302 | && INTEGERP (AREF (spec, FONT_SPACING_INDEX)) | ||
| 2303 | && ! EQ (AREF (spec, FONT_SPACING_INDEX), | ||
| 2304 | AREF (entity, FONT_SPACING_INDEX))) | ||
| 2305 | prop = FONT_SPEC_MAX; | ||
| 2306 | if (prop < FONT_SPEC_MAX) | ||
| 2307 | prev = tail, tail = XCDR (tail); | ||
| 2308 | else if (NILP (prev)) | ||
| 2309 | list = tail = XCDR (tail); | ||
| 2310 | else | ||
| 2311 | tail = XCDR (tail), XSETCDR (prev, tail); | ||
| 2312 | } | ||
| 2313 | return list; | ||
| 2314 | } | ||
| 2315 | |||
| 2316 | |||
| 2317 | /* Return a vector of font-entities matching with SPEC on FRAME. */ | ||
| 2318 | |||
| 2319 | Lisp_Object | ||
| 2344 | font_list_entities (frame, spec) | 2320 | font_list_entities (frame, spec) |
| 2345 | Lisp_Object frame, spec; | 2321 | Lisp_Object frame, spec; |
| 2346 | { | 2322 | { |
| 2347 | FRAME_PTR f = XFRAME (frame); | 2323 | FRAME_PTR f = XFRAME (frame); |
| 2348 | struct font_driver_list *driver_list = f->font_driver_list; | 2324 | struct font_driver_list *driver_list = f->font_driver_list; |
| 2349 | Lisp_Object ftype, family, size, alternate_familes; | 2325 | Lisp_Object ftype, family, alternate_familes; |
| 2350 | Lisp_Object *vec = alloca (sizeof (Lisp_Object) * num_font_drivers); | 2326 | Lisp_Object *vec; |
| 2327 | int size; | ||
| 2328 | int need_filtering = 0; | ||
| 2329 | int n_family = 1; | ||
| 2351 | int i; | 2330 | int i; |
| 2352 | 2331 | ||
| 2353 | if (! vec) | 2332 | xassert (FONT_SPEC_P (spec)); |
| 2354 | return null_vector; | ||
| 2355 | 2333 | ||
| 2356 | family = AREF (spec, FONT_FAMILY_INDEX); | 2334 | family = AREF (spec, FONT_FAMILY_INDEX); |
| 2357 | if (NILP (family)) | 2335 | if (NILP (family)) |
| 2358 | alternate_familes = Qnil; | 2336 | alternate_familes = Qnil; |
| 2359 | else | 2337 | else |
| 2360 | { | 2338 | { |
| 2361 | if (NILP (font_family_alist) | 2339 | alternate_familes = Fassoc_string (family, |
| 2362 | && !NILP (Vface_alternative_font_family_alist)) | 2340 | Vface_alternative_font_family_alist, |
| 2363 | build_font_family_alist (); | 2341 | Qt); |
| 2364 | alternate_familes = assq_no_quit (family, font_family_alist); | ||
| 2365 | if (! NILP (alternate_familes)) | 2342 | if (! NILP (alternate_familes)) |
| 2366 | alternate_familes = XCDR (alternate_familes); | 2343 | alternate_familes = XCDR (alternate_familes); |
| 2344 | n_family += XINT (Flength (alternate_familes)); | ||
| 2367 | } | 2345 | } |
| 2368 | size = AREF (spec, FONT_SIZE_INDEX); | ||
| 2369 | if (FLOATP (size)) | ||
| 2370 | ASET (spec, FONT_SIZE_INDEX, make_number (font_pixel_size (f, spec))); | ||
| 2371 | 2346 | ||
| 2372 | xassert (ASIZE (spec) == FONT_SPEC_MAX); | 2347 | if (INTEGERP (AREF (spec, FONT_SIZE_INDEX))) |
| 2348 | size = XINT (AREF (spec, FONT_SIZE_INDEX)); | ||
| 2349 | else if (FLOATP (AREF (spec, FONT_SIZE_INDEX))) | ||
| 2350 | size = font_pixel_size (f, spec); | ||
| 2351 | else | ||
| 2352 | size = 0; | ||
| 2353 | |||
| 2373 | ftype = AREF (spec, FONT_TYPE_INDEX); | 2354 | ftype = AREF (spec, FONT_TYPE_INDEX); |
| 2355 | for (i = 0; i <= FONT_REGISTRY_INDEX; i++) | ||
| 2356 | ASET (scratch_font_spec, i, AREF (spec, i)); | ||
| 2357 | for (; i < FONT_EXTRA_INDEX; i++) | ||
| 2358 | { | ||
| 2359 | ASET (scratch_font_spec, i, Qnil); | ||
| 2360 | if (! NILP (AREF (spec, i))) | ||
| 2361 | need_filtering = 1; | ||
| 2362 | } | ||
| 2363 | ASET (scratch_font_spec, FONT_EXTRA_INDEX, AREF (spec, FONT_EXTRA_INDEX)); | ||
| 2364 | |||
| 2365 | vec = alloca (sizeof (Lisp_Object) * num_font_drivers * n_family); | ||
| 2366 | if (! vec) | ||
| 2367 | return null_vector; | ||
| 2374 | 2368 | ||
| 2375 | for (i = 0; driver_list; driver_list = driver_list->next) | 2369 | for (i = 0; driver_list; driver_list = driver_list->next) |
| 2376 | if (driver_list->on | 2370 | if (driver_list->on |
| @@ -2379,50 +2373,53 @@ font_list_entities (frame, spec) | |||
| 2379 | Lisp_Object cache = font_get_cache (f, driver_list->driver); | 2373 | Lisp_Object cache = font_get_cache (f, driver_list->driver); |
| 2380 | Lisp_Object tail = alternate_familes; | 2374 | Lisp_Object tail = alternate_familes; |
| 2381 | 2375 | ||
| 2382 | ASET (spec, FONT_TYPE_INDEX, driver_list->driver->type); | ||
| 2383 | ASET (spec, FONT_FAMILY_INDEX, family); | ||
| 2384 | |||
| 2385 | while (1) | 2376 | while (1) |
| 2386 | { | 2377 | { |
| 2387 | Lisp_Object val = assoc_no_quit (spec, XCDR (cache)); | 2378 | Lisp_Object val = assoc_no_quit (scratch_font_spec, XCDR (cache)); |
| 2388 | 2379 | ||
| 2389 | if (CONSP (val)) | 2380 | if (CONSP (val) && VECTORP (XCDR (val))) |
| 2390 | val = XCDR (val); | 2381 | val = XCDR (val); |
| 2391 | else | 2382 | else |
| 2392 | { | 2383 | { |
| 2393 | val = driver_list->driver->list (frame, spec); | 2384 | Lisp_Object copy; |
| 2394 | if (VECTORP (val)) | 2385 | |
| 2395 | XSETCDR (cache, Fcons (Fcons (Fcopy_sequence (spec), val), | 2386 | val = driver_list->driver->list (frame, scratch_font_spec); |
| 2396 | XCDR (cache))); | 2387 | if (! NILP (val) && need_filtering) |
| 2388 | val = font_delete_unmatched (val, spec, size); | ||
| 2389 | copy = Fcopy_font_spec (scratch_font_spec); | ||
| 2390 | XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache))); | ||
| 2397 | } | 2391 | } |
| 2398 | if (VECTORP (val) && ASIZE (val) > 0) | 2392 | if (! NILP (val)) |
| 2399 | { | 2393 | { |
| 2400 | vec[i++] = val; | 2394 | vec[i++] = val; |
| 2401 | break; | 2395 | break; |
| 2402 | } | 2396 | } |
| 2403 | if (NILP (tail)) | 2397 | if (NILP (tail)) |
| 2404 | break; | 2398 | break; |
| 2405 | ASET (spec, FONT_FAMILY_INDEX, XCAR (tail)); | 2399 | ASET (scratch_font_spec, FONT_FAMILY_INDEX, |
| 2400 | Fintern (XCAR (tail), Qnil)); | ||
| 2406 | tail = XCDR (tail); | 2401 | tail = XCDR (tail); |
| 2407 | } | 2402 | } |
| 2408 | } | 2403 | } |
| 2409 | ASET (spec, FONT_TYPE_INDEX, ftype); | 2404 | |
| 2410 | ASET (spec, FONT_FAMILY_INDEX, family); | ||
| 2411 | ASET (spec, FONT_SIZE_INDEX, size); | ||
| 2412 | return (i > 0 ? Fvconcat (i, vec) : null_vector); | 2405 | return (i > 0 ? Fvconcat (i, vec) : null_vector); |
| 2413 | } | 2406 | } |
| 2414 | 2407 | ||
| 2415 | 2408 | ||
| 2416 | /* Return a font entity matching with SPEC on FRAME. */ | 2409 | /* Return a font entity matching with SPEC on FRAME. ATTRS, if non |
| 2410 | nil, is an array of face's attributes, which specifies preferred | ||
| 2411 | font-related attributes. */ | ||
| 2417 | 2412 | ||
| 2418 | static Lisp_Object | 2413 | static Lisp_Object |
| 2419 | font_matching_entity (frame, spec) | 2414 | font_matching_entity (f, attrs, spec) |
| 2420 | Lisp_Object frame, spec; | 2415 | FRAME_PTR f; |
| 2416 | Lisp_Object *attrs, spec; | ||
| 2421 | { | 2417 | { |
| 2422 | FRAME_PTR f = XFRAME (frame); | ||
| 2423 | struct font_driver_list *driver_list = f->font_driver_list; | 2418 | struct font_driver_list *driver_list = f->font_driver_list; |
| 2424 | Lisp_Object ftype, size, entity; | 2419 | Lisp_Object ftype, size, entity; |
| 2420 | Lisp_Object frame; | ||
| 2425 | 2421 | ||
| 2422 | XSETFRAME (frame, f); | ||
| 2426 | ftype = AREF (spec, FONT_TYPE_INDEX); | 2423 | ftype = AREF (spec, FONT_TYPE_INDEX); |
| 2427 | size = AREF (spec, FONT_SIZE_INDEX); | 2424 | size = AREF (spec, FONT_SIZE_INDEX); |
| 2428 | if (FLOATP (size)) | 2425 | if (FLOATP (size)) |
| @@ -2433,21 +2430,16 @@ font_matching_entity (frame, spec) | |||
| 2433 | && (NILP (ftype) || EQ (driver_list->driver->type, ftype))) | 2430 | && (NILP (ftype) || EQ (driver_list->driver->type, ftype))) |
| 2434 | { | 2431 | { |
| 2435 | Lisp_Object cache = font_get_cache (f, driver_list->driver); | 2432 | Lisp_Object cache = font_get_cache (f, driver_list->driver); |
| 2436 | Lisp_Object key; | ||
| 2437 | 2433 | ||
| 2438 | ASET (spec, FONT_TYPE_INDEX, driver_list->driver->type); | 2434 | ASET (spec, FONT_TYPE_INDEX, driver_list->driver->type); |
| 2439 | key = Fcons (spec, Qnil); | 2435 | entity = assoc_no_quit (spec, XCDR (cache)); |
| 2440 | entity = assoc_no_quit (key, XCDR (cache)); | 2436 | if (CONSP (entity) && ! VECTORP (XCDR (entity))) |
| 2441 | if (CONSP (entity)) | ||
| 2442 | entity = XCDR (entity); | 2437 | entity = XCDR (entity); |
| 2443 | else | 2438 | else |
| 2444 | { | 2439 | { |
| 2445 | entity = driver_list->driver->match (frame, spec); | 2440 | entity = driver_list->driver->match (frame, spec); |
| 2446 | if (! NILP (entity)) | 2441 | XSETCDR (cache, Fcons (Fcons (Fcopy_font_spec (spec), entity), |
| 2447 | { | 2442 | XCDR (cache))); |
| 2448 | XSETCAR (key, Fcopy_sequence (spec)); | ||
| 2449 | XSETCDR (cache, Fcons (Fcons (key, entity), XCDR (cache))); | ||
| 2450 | } | ||
| 2451 | } | 2443 | } |
| 2452 | if (! NILP (entity)) | 2444 | if (! NILP (entity)) |
| 2453 | break; | 2445 | break; |
| @@ -2470,53 +2462,52 @@ font_open_entity (f, entity, pixel_size) | |||
| 2470 | struct font_driver_list *driver_list; | 2462 | struct font_driver_list *driver_list; |
| 2471 | Lisp_Object objlist, size, val, font_object; | 2463 | Lisp_Object objlist, size, val, font_object; |
| 2472 | struct font *font; | 2464 | struct font *font; |
| 2465 | int min_width; | ||
| 2473 | 2466 | ||
| 2467 | xassert (FONT_ENTITY_P (entity)); | ||
| 2474 | size = AREF (entity, FONT_SIZE_INDEX); | 2468 | size = AREF (entity, FONT_SIZE_INDEX); |
| 2475 | xassert (NATNUMP (size)); | ||
| 2476 | if (XINT (size) != 0) | 2469 | if (XINT (size) != 0) |
| 2477 | pixel_size = XINT (size); | 2470 | pixel_size = XINT (size); |
| 2478 | 2471 | ||
| 2479 | font_object = Qnil; | ||
| 2480 | for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist); | 2472 | for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist); |
| 2481 | objlist = XCDR (objlist)) | 2473 | objlist = XCDR (objlist)) |
| 2482 | { | 2474 | if (XFONT_OBJECT (XCAR (objlist))->pixel_size == pixel_size) |
| 2483 | font = XSAVE_VALUE (XCAR (objlist))->pointer; | 2475 | return XCAR (objlist); |
| 2484 | if (font->pixel_size == pixel_size) | 2476 | |
| 2485 | { | 2477 | val = AREF (entity, FONT_TYPE_INDEX); |
| 2486 | font_object = XCAR (objlist); | 2478 | for (driver_list = f->font_driver_list; |
| 2487 | XSAVE_VALUE (font_object)->integer++; | 2479 | driver_list && ! EQ (driver_list->driver->type, val); |
| 2488 | break; | 2480 | driver_list = driver_list->next); |
| 2489 | } | 2481 | if (! driver_list) |
| 2490 | } | 2482 | return Qnil; |
| 2491 | 2483 | ||
| 2484 | font_object = driver_list->driver->open (f, entity, pixel_size); | ||
| 2492 | if (NILP (font_object)) | 2485 | if (NILP (font_object)) |
| 2486 | return Qnil; | ||
| 2487 | ASET (entity, FONT_OBJLIST_INDEX, | ||
| 2488 | Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX))); | ||
| 2489 | ASET (font_object, FONT_OBJLIST_INDEX, AREF (entity, FONT_OBJLIST_INDEX)); | ||
| 2490 | num_fonts++; | ||
| 2491 | |||
| 2492 | font = XFONT_OBJECT (font_object); | ||
| 2493 | min_width = (font->min_width ? font->min_width | ||
| 2494 | : font->average_width ? font->average_width | ||
| 2495 | : font->space_width ? font->space_width | ||
| 2496 | : 1); | ||
| 2497 | FRAME_X_DISPLAY_INFO (f)->n_fonts++; | ||
| 2498 | if (FRAME_X_DISPLAY_INFO (f)->n_fonts == 1) | ||
| 2493 | { | 2499 | { |
| 2494 | val = AREF (entity, FONT_TYPE_INDEX); | 2500 | FRAME_SMALLEST_CHAR_WIDTH (f) = min_width; |
| 2495 | for (driver_list = f->font_driver_list; | 2501 | FRAME_SMALLEST_FONT_HEIGHT (f) = font->height; |
| 2496 | driver_list && ! EQ (driver_list->driver->type, val); | 2502 | fonts_changed_p = 1; |
| 2497 | driver_list = driver_list->next); | 2503 | } |
| 2498 | if (! driver_list) | 2504 | else |
| 2499 | return Qnil; | 2505 | { |
| 2500 | 2506 | if (FRAME_SMALLEST_CHAR_WIDTH (f) > min_width) | |
| 2501 | font = driver_list->driver->open (f, entity, pixel_size); | 2507 | FRAME_SMALLEST_CHAR_WIDTH (f) = min_width, fonts_changed_p = 1; |
| 2502 | if (! font) | 2508 | if (FRAME_SMALLEST_FONT_HEIGHT (f) > font->height) |
| 2503 | return Qnil; | 2509 | FRAME_SMALLEST_FONT_HEIGHT (f) = font->height, fonts_changed_p = 1; |
| 2504 | font->scalable = XINT (size) == 0; | ||
| 2505 | |||
| 2506 | font_object = make_save_value (font, 1); | ||
| 2507 | ASET (entity, FONT_OBJLIST_INDEX, | ||
| 2508 | Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX))); | ||
| 2509 | num_fonts++; | ||
| 2510 | } | 2510 | } |
| 2511 | |||
| 2512 | if (FRAME_SMALLEST_CHAR_WIDTH (f) > font->min_width) | ||
| 2513 | FRAME_SMALLEST_CHAR_WIDTH (f) = font->min_width; | ||
| 2514 | if (FRAME_SMALLEST_CHAR_WIDTH (f) <= 0) | ||
| 2515 | FRAME_SMALLEST_CHAR_WIDTH (f) = 1; | ||
| 2516 | if (FRAME_SMALLEST_FONT_HEIGHT (f) > font->font.height) | ||
| 2517 | FRAME_SMALLEST_FONT_HEIGHT (f) = font->font.height; | ||
| 2518 | if (FRAME_SMALLEST_FONT_HEIGHT (f) <= 0) | ||
| 2519 | FRAME_SMALLEST_FONT_HEIGHT (f) = 1; | ||
| 2520 | 2511 | ||
| 2521 | return font_object; | 2512 | return font_object; |
| 2522 | } | 2513 | } |
| @@ -2529,25 +2520,20 @@ font_close_object (f, font_object) | |||
| 2529 | FRAME_PTR f; | 2520 | FRAME_PTR f; |
| 2530 | Lisp_Object font_object; | 2521 | Lisp_Object font_object; |
| 2531 | { | 2522 | { |
| 2532 | struct font *font = XSAVE_VALUE (font_object)->pointer; | 2523 | struct font *font = XFONT_OBJECT (font_object); |
| 2533 | Lisp_Object objlist; | 2524 | Lisp_Object objlist; |
| 2534 | Lisp_Object tail, prev = Qnil; | 2525 | Lisp_Object tail, prev = Qnil; |
| 2535 | 2526 | ||
| 2536 | xassert (XSAVE_VALUE (font_object)->integer > 0); | 2527 | objlist = AREF (font_object, FONT_OBJLIST_INDEX); |
| 2537 | XSAVE_VALUE (font_object)->integer--; | ||
| 2538 | if (XSAVE_VALUE (font_object)->integer > 0) | ||
| 2539 | return; | ||
| 2540 | |||
| 2541 | objlist = AREF (font->entity, FONT_OBJLIST_INDEX); | ||
| 2542 | for (prev = Qnil, tail = objlist; CONSP (tail); | 2528 | for (prev = Qnil, tail = objlist; CONSP (tail); |
| 2543 | prev = tail, tail = XCDR (tail)) | 2529 | prev = tail, tail = XCDR (tail)) |
| 2544 | if (EQ (font_object, XCAR (tail))) | 2530 | if (EQ (font_object, XCAR (tail))) |
| 2545 | { | 2531 | { |
| 2546 | if (font->driver->close) | 2532 | xassert (FRAME_X_DISPLAY_INFO (f)->n_fonts); |
| 2547 | font->driver->close (f, font); | 2533 | font->driver->close (f, font); |
| 2548 | XSAVE_VALUE (font_object)->pointer = NULL; | 2534 | FRAME_X_DISPLAY_INFO (f)->n_fonts--; |
| 2549 | if (NILP (prev)) | 2535 | if (NILP (prev)) |
| 2550 | ASET (font->entity, FONT_OBJLIST_INDEX, XCDR (objlist)); | 2536 | ASET (font_object, FONT_OBJLIST_INDEX, XCDR (objlist)); |
| 2551 | else | 2537 | else |
| 2552 | XSETCDR (prev, XCDR (objlist)); | 2538 | XSETCDR (prev, XCDR (objlist)); |
| 2553 | num_fonts--; | 2539 | num_fonts--; |
| @@ -2584,11 +2570,10 @@ font_has_char (f, font, c) | |||
| 2584 | } | 2570 | } |
| 2585 | 2571 | ||
| 2586 | xassert (FONT_OBJECT_P (font)); | 2572 | xassert (FONT_OBJECT_P (font)); |
| 2587 | fontp = XSAVE_VALUE (font)->pointer; | 2573 | fontp = XFONT_OBJECT (font); |
| 2588 | |||
| 2589 | if (fontp->driver->has_char) | 2574 | if (fontp->driver->has_char) |
| 2590 | { | 2575 | { |
| 2591 | int result = fontp->driver->has_char (fontp->entity, c); | 2576 | int result = fontp->driver->has_char (font, c); |
| 2592 | 2577 | ||
| 2593 | if (result >= 0) | 2578 | if (result >= 0) |
| 2594 | return result; | 2579 | return result; |
| @@ -2604,8 +2589,10 @@ font_encode_char (font_object, c) | |||
| 2604 | Lisp_Object font_object; | 2589 | Lisp_Object font_object; |
| 2605 | int c; | 2590 | int c; |
| 2606 | { | 2591 | { |
| 2607 | struct font *font = XSAVE_VALUE (font_object)->pointer; | 2592 | struct font *font; |
| 2608 | 2593 | ||
| 2594 | xassert (FONT_OBJECT_P (font_object)); | ||
| 2595 | font = XFONT_OBJECT (font_object); | ||
| 2609 | return font->driver->encode_char (font, c); | 2596 | return font->driver->encode_char (font, c); |
| 2610 | } | 2597 | } |
| 2611 | 2598 | ||
| @@ -2616,12 +2603,10 @@ Lisp_Object | |||
| 2616 | font_get_name (font_object) | 2603 | font_get_name (font_object) |
| 2617 | Lisp_Object font_object; | 2604 | Lisp_Object font_object; |
| 2618 | { | 2605 | { |
| 2619 | struct font *font = XSAVE_VALUE (font_object)->pointer; | 2606 | Lisp_Object name; |
| 2620 | char *name = (font->font.full_name ? font->font.full_name | ||
| 2621 | : font->font.name ? font->font.name | ||
| 2622 | : NULL); | ||
| 2623 | 2607 | ||
| 2624 | return (name ? make_unibyte_string (name, strlen (name)) : null_string); | 2608 | xassert (FONT_OBJECT_P (font_object)); |
| 2609 | return AREF (font_object, FONT_NAME_INDEX); | ||
| 2625 | } | 2610 | } |
| 2626 | 2611 | ||
| 2627 | 2612 | ||
| @@ -2631,154 +2616,232 @@ Lisp_Object | |||
| 2631 | font_get_spec (font_object) | 2616 | font_get_spec (font_object) |
| 2632 | Lisp_Object font_object; | 2617 | Lisp_Object font_object; |
| 2633 | { | 2618 | { |
| 2634 | struct font *font = XSAVE_VALUE (font_object)->pointer; | 2619 | Lisp_Object spec = font_make_spec (); |
| 2635 | Lisp_Object spec = Ffont_spec (0, NULL); | ||
| 2636 | int i; | 2620 | int i; |
| 2637 | 2621 | ||
| 2638 | for (i = 0; i < FONT_SIZE_INDEX; i++) | 2622 | for (i = 0; i < FONT_SIZE_INDEX; i++) |
| 2639 | ASET (spec, i, AREF (font->entity, i)); | 2623 | ASET (spec, i, AREF (font_object, i)); |
| 2640 | ASET (spec, FONT_SIZE_INDEX, make_number (font->pixel_size)); | 2624 | ASET (spec, FONT_SIZE_INDEX, |
| 2625 | make_number (XFONT_OBJECT (font_object)->pixel_size)); | ||
| 2641 | return spec; | 2626 | return spec; |
| 2642 | } | 2627 | } |
| 2643 | 2628 | ||
| 2629 | Lisp_Object | ||
| 2630 | font_spec_from_name (font_name) | ||
| 2631 | Lisp_Object font_name; | ||
| 2632 | { | ||
| 2633 | Lisp_Object args[2]; | ||
| 2634 | |||
| 2635 | args[0] = QCname; | ||
| 2636 | args[1] = font_name; | ||
| 2637 | return Ffont_spec (2, args); | ||
| 2638 | } | ||
| 2644 | 2639 | ||
| 2645 | /* Return the frame on which FONT exists. FONT is a font object or a | ||
| 2646 | font entity. */ | ||
| 2647 | 2640 | ||
| 2648 | Lisp_Object | 2641 | void |
| 2649 | font_get_frame (font) | 2642 | font_clear_prop (attrs, prop) |
| 2650 | Lisp_Object font; | 2643 | Lisp_Object *attrs; |
| 2644 | enum font_property_index prop; | ||
| 2651 | { | 2645 | { |
| 2652 | if (FONT_OBJECT_P (font)) | 2646 | Lisp_Object font = attrs[LFACE_FONT_INDEX]; |
| 2653 | font = ((struct font *) XSAVE_VALUE (font)->pointer)->entity; | 2647 | Lisp_Object extra, prev; |
| 2654 | xassert (FONT_ENTITY_P (font)); | 2648 | |
| 2655 | return AREF (font, FONT_FRAME_INDEX); | 2649 | if (! FONTP (font)) |
| 2650 | return; | ||
| 2651 | if (NILP (AREF (font, prop)) | ||
| 2652 | && prop != FONT_FAMILY_INDEX && prop != FONT_FAMILY_INDEX) | ||
| 2653 | return; | ||
| 2654 | font = Fcopy_font_spec (font); | ||
| 2655 | ASET (font, prop, Qnil); | ||
| 2656 | if (prop == FONT_FAMILY_INDEX) | ||
| 2657 | { | ||
| 2658 | ASET (font, FONT_FOUNDRY_INDEX, Qnil); | ||
| 2659 | ASET (font, FONT_ADSTYLE_INDEX, Qnil); | ||
| 2660 | ASET (font, FONT_SIZE_INDEX, Qnil); | ||
| 2661 | ASET (font, FONT_DPI_INDEX, Qnil); | ||
| 2662 | ASET (font, FONT_SPACING_INDEX, Qnil); | ||
| 2663 | ASET (font, FONT_AVGWIDTH_INDEX, Qnil); | ||
| 2664 | } | ||
| 2665 | else if (prop == FONT_SIZE_INDEX) | ||
| 2666 | { | ||
| 2667 | ASET (font, FONT_DPI_INDEX, Qnil); | ||
| 2668 | ASET (font, FONT_SPACING_INDEX, Qnil); | ||
| 2669 | ASET (font, FONT_AVGWIDTH_INDEX, Qnil); | ||
| 2670 | } | ||
| 2671 | attrs[LFACE_FONT_INDEX] = font; | ||
| 2656 | } | 2672 | } |
| 2657 | 2673 | ||
| 2674 | void | ||
| 2675 | font_update_lface (f, attrs) | ||
| 2676 | FRAME_PTR f; | ||
| 2677 | Lisp_Object *attrs; | ||
| 2678 | { | ||
| 2679 | Lisp_Object spec, val; | ||
| 2680 | int n; | ||
| 2681 | |||
| 2682 | spec = attrs[LFACE_FONT_INDEX]; | ||
| 2683 | if (! FONT_SPEC_P (spec)) | ||
| 2684 | return; | ||
| 2685 | |||
| 2686 | if (! NILP (AREF (spec, FONT_FOUNDRY_INDEX)) | ||
| 2687 | || ! NILP (AREF (spec, FONT_FAMILY_INDEX))) | ||
| 2688 | { | ||
| 2689 | Lisp_Object family; | ||
| 2690 | |||
| 2691 | if (NILP (AREF (spec, FONT_FOUNDRY_INDEX))) | ||
| 2692 | family = AREF (spec, FONT_FAMILY_INDEX); | ||
| 2693 | else if (NILP (AREF (spec, FONT_FAMILY_INDEX))) | ||
| 2694 | family = concat2 (SYMBOL_NAME (AREF (spec, FONT_FOUNDRY_INDEX)), | ||
| 2695 | build_string ("-*")); | ||
| 2696 | else | ||
| 2697 | family = concat3 (SYMBOL_NAME (AREF (spec, FONT_FOUNDRY_INDEX)), | ||
| 2698 | build_string ("-"), | ||
| 2699 | SYMBOL_NAME (AREF (spec, FONT_FAMILY_INDEX))); | ||
| 2700 | attrs[LFACE_FAMILY_INDEX] = family; | ||
| 2701 | } | ||
| 2702 | if (! NILP (AREF (spec, FONT_WEIGHT_INDEX))) | ||
| 2703 | attrs[LFACE_WEIGHT_INDEX] = FONT_WEIGHT_FOR_FACE (spec); | ||
| 2704 | if (! NILP (AREF (spec, FONT_SLANT_INDEX))) | ||
| 2705 | attrs[LFACE_SLANT_INDEX] = FONT_SLANT_FOR_FACE (spec);; | ||
| 2706 | if (! NILP (AREF (spec, FONT_WIDTH_INDEX))) | ||
| 2707 | attrs[LFACE_SWIDTH_INDEX] = FONT_WIDTH_FOR_FACE (spec); | ||
| 2708 | if (! NILP (AREF (spec, FONT_SIZE_INDEX))) | ||
| 2709 | { | ||
| 2710 | int point; | ||
| 2658 | 2711 | ||
| 2659 | /* Find a font entity best matching with LFACE. If SPEC is non-nil, | 2712 | if (INTEGERP (AREF (spec, FONT_SIZE_INDEX))) |
| 2660 | the font must exactly match with it. C, if not negative, is a | 2713 | { |
| 2714 | Lisp_Object val; | ||
| 2715 | int dpi = f->resy; | ||
| 2716 | |||
| 2717 | val = Ffont_get (spec, QCdpi); | ||
| 2718 | if (! NILP (val)) | ||
| 2719 | dpi = XINT (val); | ||
| 2720 | point = PIXEL_TO_POINT (XINT (AREF (spec, FONT_SIZE_INDEX)) * 10, | ||
| 2721 | dpi); | ||
| 2722 | } | ||
| 2723 | else if (FLOATP (AREF (spec, FONT_SIZE_INDEX))) | ||
| 2724 | point = XFLOAT_DATA (AREF (spec, FONT_SIZE_INDEX)) * 10; | ||
| 2725 | attrs[LFACE_HEIGHT_INDEX] = make_number (point); | ||
| 2726 | } | ||
| 2727 | } | ||
| 2728 | |||
| 2729 | |||
| 2730 | /* Return a font-entity satisfying SPEC and best matching with face's | ||
| 2731 | font related attributes in ATTRS. C, if not negative, is a | ||
| 2661 | character that the entity must support. */ | 2732 | character that the entity must support. */ |
| 2662 | 2733 | ||
| 2663 | Lisp_Object | 2734 | Lisp_Object |
| 2664 | font_find_for_lface (f, lface, spec, c) | 2735 | font_find_for_lface (f, attrs, spec, c) |
| 2665 | FRAME_PTR f; | 2736 | FRAME_PTR f; |
| 2666 | Lisp_Object *lface; | 2737 | Lisp_Object *attrs; |
| 2667 | Lisp_Object spec; | 2738 | Lisp_Object spec; |
| 2668 | int c; | 2739 | int c; |
| 2669 | { | 2740 | { |
| 2670 | Lisp_Object frame, entities, val; | 2741 | Lisp_Object frame, entities, val, props[FONT_REGISTRY_INDEX + 1] ; |
| 2742 | Lisp_Object size; | ||
| 2671 | int i, result; | 2743 | int i, result; |
| 2672 | 2744 | ||
| 2673 | XSETFRAME (frame, f); | 2745 | if (c >= 0) |
| 2674 | |||
| 2675 | if (NILP (spec)) | ||
| 2676 | { | ||
| 2677 | if (c >= 0x100) | ||
| 2678 | return Qnil; | ||
| 2679 | for (i = 0; i < FONT_SPEC_MAX; i++) | ||
| 2680 | ASET (scratch_font_spec, i, Qnil); | ||
| 2681 | ASET (scratch_font_spec, FONT_REGISTRY_INDEX, Qiso8859_1); | ||
| 2682 | |||
| 2683 | if (! NILP (lface[LFACE_FAMILY_INDEX])) | ||
| 2684 | font_merge_old_spec (Qnil, lface[LFACE_FAMILY_INDEX], Qnil, | ||
| 2685 | scratch_font_spec); | ||
| 2686 | entities = font_list_entities (frame, scratch_font_spec); | ||
| 2687 | while (ASIZE (entities) == 0) | ||
| 2688 | { | ||
| 2689 | /* Try without FOUNDRY or FAMILY. */ | ||
| 2690 | if (! NILP (AREF (scratch_font_spec, FONT_FOUNDRY_INDEX))) | ||
| 2691 | { | ||
| 2692 | ASET (scratch_font_spec, FONT_FOUNDRY_INDEX, Qnil); | ||
| 2693 | entities = font_list_entities (frame, scratch_font_spec); | ||
| 2694 | } | ||
| 2695 | else if (! NILP (AREF (scratch_font_spec, FONT_FAMILY_INDEX))) | ||
| 2696 | { | ||
| 2697 | ASET (scratch_font_spec, FONT_FAMILY_INDEX, Qnil); | ||
| 2698 | entities = font_list_entities (frame, scratch_font_spec); | ||
| 2699 | } | ||
| 2700 | else | ||
| 2701 | break; | ||
| 2702 | } | ||
| 2703 | } | ||
| 2704 | else | ||
| 2705 | { | 2746 | { |
| 2706 | Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX); | 2747 | Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX); |
| 2748 | struct charset *encoding, *repertory; | ||
| 2707 | 2749 | ||
| 2708 | if (NILP (registry)) | 2750 | if (font_registry_charsets (registry, &encoding, &repertory) < 0) |
| 2709 | registry = Qiso8859_1; | 2751 | return Qnil; |
| 2710 | 2752 | if (repertory) | |
| 2711 | if (c >= 0) | ||
| 2712 | { | 2753 | { |
| 2713 | struct charset *encoding, *repertory; | 2754 | if (ENCODE_CHAR (repertory, c) == CHARSET_INVALID_CODE (repertory)) |
| 2714 | |||
| 2715 | if (font_registry_charsets (registry, &encoding, &repertory) < 0) | ||
| 2716 | return Qnil; | ||
| 2717 | if (repertory) | ||
| 2718 | { | ||
| 2719 | if (ENCODE_CHAR (repertory, c) | ||
| 2720 | == CHARSET_INVALID_CODE (repertory)) | ||
| 2721 | return Qnil; | ||
| 2722 | /* Any font of this registry support C. So, let's | ||
| 2723 | suppress the further checking. */ | ||
| 2724 | c = -1; | ||
| 2725 | } | ||
| 2726 | else if (c > encoding->max_char) | ||
| 2727 | return Qnil; | 2755 | return Qnil; |
| 2756 | /* Any font of this registry support C. So, let's | ||
| 2757 | suppress the further checking. */ | ||
| 2758 | c = -1; | ||
| 2728 | } | 2759 | } |
| 2729 | for (i = 0; i < FONT_SPEC_MAX; i++) | 2760 | else if (c > encoding->max_char) |
| 2730 | ASET (scratch_font_spec, i, AREF (spec, i)); | 2761 | return Qnil; |
| 2731 | ASET (scratch_font_spec, FONT_REGISTRY_INDEX, registry); | ||
| 2732 | entities = font_list_entities (frame, scratch_font_spec); | ||
| 2733 | } | 2762 | } |
| 2734 | 2763 | ||
| 2764 | XSETFRAME (frame, f); | ||
| 2765 | size = AREF (spec, FONT_SIZE_INDEX); | ||
| 2766 | ASET (spec, FONT_SIZE_INDEX, Qnil); | ||
| 2767 | entities = font_list_entities (frame, spec); | ||
| 2768 | ASET (spec, FONT_SIZE_INDEX, size); | ||
| 2735 | if (ASIZE (entities) == 0) | 2769 | if (ASIZE (entities) == 0) |
| 2736 | return Qnil; | 2770 | return Qnil; |
| 2737 | if (ASIZE (entities) > 1) | 2771 | if (ASIZE (entities) == 1) |
| 2772 | { | ||
| 2773 | if (c < 0) | ||
| 2774 | return AREF (entities, 0); | ||
| 2775 | } | ||
| 2776 | else | ||
| 2738 | { | 2777 | { |
| 2739 | /* Sort fonts by properties specified in LFACE. */ | 2778 | /* Sort fonts by properties specified in LFACE. */ |
| 2740 | Lisp_Object prefer = scratch_font_prefer; | 2779 | Lisp_Object prefer = scratch_font_prefer; |
| 2741 | double pt; | 2780 | double pt; |
| 2742 | 2781 | for (i = 0; i < FONT_EXTRA_INDEX; i++) | |
| 2743 | if (! NILP (lface[LFACE_FAMILY_INDEX])) | 2782 | ASET (prefer, i, AREF (spec, i)); |
| 2744 | font_merge_old_spec (Qnil, lface[LFACE_FAMILY_INDEX], Qnil, prefer); | 2783 | if (NILP (AREF (prefer, FONT_FAMILY_INDEX))) |
| 2745 | ASET (prefer, FONT_WEIGHT_INDEX, | 2784 | font_parse_family_registry (attrs[LFACE_FAMILY_INDEX], Qnil, prefer); |
| 2746 | font_prop_validate_style (QCweight, lface[LFACE_WEIGHT_INDEX])); | 2785 | if (NILP (AREF (prefer, FONT_WEIGHT_INDEX))) |
| 2747 | ASET (prefer, FONT_SLANT_INDEX, | 2786 | FONT_SET_STYLE (prefer, FONT_WEIGHT_INDEX, attrs[LFACE_WEIGHT_INDEX]); |
| 2748 | font_prop_validate_style (QCslant, lface[LFACE_SLANT_INDEX])); | 2787 | if (NILP (AREF (prefer, FONT_SLANT_INDEX))) |
| 2749 | ASET (prefer, FONT_WIDTH_INDEX, | 2788 | FONT_SET_STYLE (prefer, FONT_SLANT_INDEX, attrs[LFACE_SLANT_INDEX]); |
| 2750 | font_prop_validate_style (QCwidth, lface[LFACE_SWIDTH_INDEX])); | 2789 | if (NILP (AREF (prefer, FONT_WIDTH_INDEX))) |
| 2751 | pt = XINT (lface[LFACE_HEIGHT_INDEX]); | 2790 | FONT_SET_STYLE (prefer, FONT_WIDTH_INDEX, attrs[LFACE_SWIDTH_INDEX]); |
| 2752 | ASET (prefer, FONT_SIZE_INDEX, make_float (pt / 10)); | 2791 | if (INTEGERP (size)) |
| 2753 | 2792 | ASET (prefer, FONT_SIZE_INDEX, size); | |
| 2754 | font_sort_entites (entities, prefer, frame, spec); | 2793 | else if (FLOATP (size)) |
| 2794 | ASET (prefer, FONT_SIZE_INDEX, make_number (font_pixel_size (f, spec))); | ||
| 2795 | else | ||
| 2796 | { | ||
| 2797 | double pt = XINT (attrs[LFACE_HEIGHT_INDEX]); | ||
| 2798 | int pixel_size = POINT_TO_PIXEL (pt / 10, f->resy); | ||
| 2799 | ASET (prefer, FONT_SIZE_INDEX, make_number (pixel_size)); | ||
| 2800 | } | ||
| 2801 | ASET (spec, FONT_SIZE_INDEX, Qnil); | ||
| 2802 | entities = font_sort_entites (entities, prefer, frame, spec, c < 0); | ||
| 2803 | ASET (spec, FONT_SIZE_INDEX, size); | ||
| 2755 | } | 2804 | } |
| 2756 | |||
| 2757 | if (c < 0) | 2805 | if (c < 0) |
| 2758 | return AREF (entities, 0); | 2806 | return entities; |
| 2759 | 2807 | ||
| 2760 | val = AREF (entities, 0); | 2808 | for (i = 0; i < ASIZE (entities); i++) |
| 2761 | result = font_has_char (f, val, c); | 2809 | { |
| 2762 | if (result > 0) | 2810 | int j; |
| 2763 | return val; | 2811 | |
| 2764 | if (result == 0) | 2812 | val = AREF (entities, i); |
| 2765 | return Qnil; | 2813 | if (i > 0) |
| 2766 | val = font_open_for_lface (f, val, lface, spec); | 2814 | { |
| 2767 | if (NILP (val)) | 2815 | for (j = FONT_FOUNDRY_INDEX; j <= FONT_REGISTRY_INDEX; j++) |
| 2768 | return Qnil; | 2816 | if (! EQ (AREF (val, j), props[j])) |
| 2769 | result = font_has_char (f, val, c); | 2817 | break; |
| 2770 | font_close_object (f, val); | 2818 | if (j > FONT_REGISTRY_INDEX) |
| 2771 | if (result > 0) | 2819 | continue; |
| 2772 | return val; | 2820 | } |
| 2821 | for (j = FONT_FOUNDRY_INDEX; j <= FONT_REGISTRY_INDEX; j++) | ||
| 2822 | props[j] = AREF (val, j); | ||
| 2823 | result = font_has_char (f, val, c); | ||
| 2824 | if (result > 0) | ||
| 2825 | return val; | ||
| 2826 | if (result == 0) | ||
| 2827 | return Qnil; | ||
| 2828 | val = font_open_for_lface (f, val, attrs, spec); | ||
| 2829 | if (NILP (val)) | ||
| 2830 | continue; | ||
| 2831 | result = font_has_char (f, val, c); | ||
| 2832 | font_close_object (f, val); | ||
| 2833 | if (result > 0) | ||
| 2834 | return AREF (entities, i); | ||
| 2835 | } | ||
| 2773 | return Qnil; | 2836 | return Qnil; |
| 2774 | } | 2837 | } |
| 2775 | 2838 | ||
| 2776 | 2839 | ||
| 2777 | Lisp_Object | 2840 | Lisp_Object |
| 2778 | font_open_for_lface (f, entity, lface, spec) | 2841 | font_open_for_lface (f, entity, attrs, spec) |
| 2779 | FRAME_PTR f; | 2842 | FRAME_PTR f; |
| 2780 | Lisp_Object entity; | 2843 | Lisp_Object entity; |
| 2781 | Lisp_Object *lface; | 2844 | Lisp_Object *attrs; |
| 2782 | Lisp_Object spec; | 2845 | Lisp_Object spec; |
| 2783 | { | 2846 | { |
| 2784 | int size; | 2847 | int size; |
| @@ -2787,7 +2850,7 @@ font_open_for_lface (f, entity, lface, spec) | |||
| 2787 | size = XINT (AREF (spec, FONT_SIZE_INDEX)); | 2850 | size = XINT (AREF (spec, FONT_SIZE_INDEX)); |
| 2788 | else | 2851 | else |
| 2789 | { | 2852 | { |
| 2790 | double pt = XINT (lface[LFACE_HEIGHT_INDEX]); | 2853 | double pt = XINT (attrs[LFACE_HEIGHT_INDEX]); |
| 2791 | 2854 | ||
| 2792 | pt /= 10; | 2855 | pt /= 10; |
| 2793 | size = POINT_TO_PIXEL (pt, f->resy); | 2856 | size = POINT_TO_PIXEL (pt, f->resy); |
| @@ -2796,46 +2859,28 @@ font_open_for_lface (f, entity, lface, spec) | |||
| 2796 | } | 2859 | } |
| 2797 | 2860 | ||
| 2798 | 2861 | ||
| 2799 | /* Load a font best matching with FACE's font-related properties into | 2862 | /* Find a font satisfying SPEC and best matching with face's |
| 2800 | FACE on frame F. If no proper font is found, record that FACE has | 2863 | attributes in ATTRS on FRAME, and return the opened |
| 2801 | no font. */ | 2864 | font-object. */ |
| 2802 | 2865 | ||
| 2803 | void | 2866 | Lisp_Object |
| 2804 | font_load_for_face (f, face) | 2867 | font_load_for_lface (f, attrs, spec) |
| 2805 | FRAME_PTR f; | 2868 | FRAME_PTR f; |
| 2806 | struct face *face; | 2869 | Lisp_Object *attrs, spec; |
| 2807 | { | 2870 | { |
| 2808 | Lisp_Object font_object = face->lface[LFACE_FONT_INDEX]; | 2871 | Lisp_Object entity; |
| 2809 | |||
| 2810 | if (NILP (font_object)) | ||
| 2811 | { | ||
| 2812 | Lisp_Object entity = font_find_for_lface (f, face->lface, Qnil, -1); | ||
| 2813 | |||
| 2814 | if (! NILP (entity)) | ||
| 2815 | font_object = font_open_for_lface (f, entity, face->lface, Qnil); | ||
| 2816 | } | ||
| 2817 | else if (STRINGP (font_object)) | ||
| 2818 | { | ||
| 2819 | font_object = font_open_by_name (f, SDATA (font_object)); | ||
| 2820 | } | ||
| 2821 | |||
| 2822 | if (! NILP (font_object)) | ||
| 2823 | { | ||
| 2824 | struct font *font = XSAVE_VALUE (font_object)->pointer; | ||
| 2825 | 2872 | ||
| 2826 | face->font = font->font.font; | 2873 | entity = font_find_for_lface (f, attrs, spec, -1); |
| 2827 | face->font_info = (struct font_info *) font; | 2874 | if (NILP (entity)) |
| 2828 | face->font_info_id = 0; | ||
| 2829 | face->font_name = font->font.full_name; | ||
| 2830 | } | ||
| 2831 | else | ||
| 2832 | { | 2875 | { |
| 2833 | face->font = NULL; | 2876 | /* No font is listed for SPEC, but each font-backend may have |
| 2834 | face->font_info = NULL; | 2877 | the different criteria about "font matching". So, try |
| 2835 | face->font_info_id = -1; | 2878 | it. */ |
| 2836 | face->font_name = NULL; | 2879 | entity = font_matching_entity (f, attrs, spec); |
| 2837 | add_to_log ("Unable to load font for a face%s", null_string, Qnil); | 2880 | if (NILP (entity)) |
| 2881 | return Qnil; | ||
| 2838 | } | 2882 | } |
| 2883 | return font_open_for_lface (f, entity, attrs, spec); | ||
| 2839 | } | 2884 | } |
| 2840 | 2885 | ||
| 2841 | 2886 | ||
| @@ -2846,10 +2891,8 @@ font_prepare_for_face (f, face) | |||
| 2846 | FRAME_PTR f; | 2891 | FRAME_PTR f; |
| 2847 | struct face *face; | 2892 | struct face *face; |
| 2848 | { | 2893 | { |
| 2849 | struct font *font = (struct font *) face->font_info; | 2894 | if (face->font->driver->prepare_face) |
| 2850 | 2895 | face->font->driver->prepare_face (f, face); | |
| 2851 | if (font->driver->prepare_face) | ||
| 2852 | font->driver->prepare_face (f, face); | ||
| 2853 | } | 2896 | } |
| 2854 | 2897 | ||
| 2855 | 2898 | ||
| @@ -2860,10 +2903,8 @@ font_done_for_face (f, face) | |||
| 2860 | FRAME_PTR f; | 2903 | FRAME_PTR f; |
| 2861 | struct face *face; | 2904 | struct face *face; |
| 2862 | { | 2905 | { |
| 2863 | struct font *font = (struct font *) face->font_info; | 2906 | if (face->font->driver->done_face) |
| 2864 | 2907 | face->font->driver->done_face (f, face); | |
| 2865 | if (font->driver->done_face) | ||
| 2866 | font->driver->done_face (f, face); | ||
| 2867 | face->extra = NULL; | 2908 | face->extra = NULL; |
| 2868 | } | 2909 | } |
| 2869 | 2910 | ||
| @@ -2888,34 +2929,41 @@ font_open_by_name (f, name) | |||
| 2888 | args[1] = make_unibyte_string (name, strlen (name)); | 2929 | args[1] = make_unibyte_string (name, strlen (name)); |
| 2889 | spec = Ffont_spec (2, args); | 2930 | spec = Ffont_spec (2, args); |
| 2890 | prefer = scratch_font_prefer; | 2931 | prefer = scratch_font_prefer; |
| 2891 | for (i = FONT_WEIGHT_INDEX; i < FONT_SIZE_INDEX; i++) | 2932 | for (i = 0; i < FONT_SPEC_MAX; i++) |
| 2892 | if (NILP (AREF (spec, i))) | 2933 | { |
| 2893 | ASET (prefer, i, make_number (100)); | 2934 | ASET (prefer, i, AREF (spec, i)); |
| 2935 | if (NILP (AREF (prefer, i)) | ||
| 2936 | && i >= FONT_WEIGHT_INDEX && i <= FONT_WIDTH_INDEX) | ||
| 2937 | FONT_SET_STYLE (prefer, i, make_number (100)); | ||
| 2938 | } | ||
| 2894 | size = AREF (spec, FONT_SIZE_INDEX); | 2939 | size = AREF (spec, FONT_SIZE_INDEX); |
| 2895 | if (NILP (size)) | 2940 | if (NILP (size)) |
| 2896 | pixel_size = 0; | 2941 | pixel_size = 0; |
| 2897 | else if (INTEGERP (size)) | 2942 | else |
| 2898 | pixel_size = XINT (size); | ||
| 2899 | else /* FLOATP (size) */ | ||
| 2900 | { | 2943 | { |
| 2901 | double pt = XFLOAT_DATA (size); | 2944 | if (INTEGERP (size)) |
| 2945 | pixel_size = XINT (size); | ||
| 2946 | else /* FLOATP (size) */ | ||
| 2947 | { | ||
| 2948 | double pt = XFLOAT_DATA (size); | ||
| 2902 | 2949 | ||
| 2903 | pixel_size = POINT_TO_PIXEL (pt, f->resy); | 2950 | pixel_size = POINT_TO_PIXEL (pt, f->resy); |
| 2904 | size = make_number (pixel_size); | 2951 | } |
| 2905 | ASET (spec, FONT_SIZE_INDEX, size); | 2952 | if (pixel_size == 0) |
| 2953 | ASET (spec, FONT_SIZE_INDEX, Qnil); | ||
| 2906 | } | 2954 | } |
| 2907 | if (pixel_size == 0) | 2955 | if (pixel_size == 0) |
| 2908 | { | 2956 | { |
| 2909 | pixel_size = POINT_TO_PIXEL (12.0, f->resy); | 2957 | pixel_size = POINT_TO_PIXEL (12.0, f->resy); |
| 2910 | size = make_number (pixel_size); | 2958 | size = make_number (pixel_size); |
| 2959 | ASET (prefer, FONT_SIZE_INDEX, size); | ||
| 2911 | } | 2960 | } |
| 2912 | ASET (prefer, FONT_SIZE_INDEX, size); | ||
| 2913 | if (NILP (AREF (spec, FONT_REGISTRY_INDEX))) | 2961 | if (NILP (AREF (spec, FONT_REGISTRY_INDEX))) |
| 2914 | ASET (spec, FONT_REGISTRY_INDEX, Qiso8859_1); | 2962 | ASET (spec, FONT_REGISTRY_INDEX, Qiso8859_1); |
| 2915 | 2963 | ||
| 2916 | entity_list = Flist_fonts (spec, frame, make_number (1), prefer); | 2964 | entity_list = Flist_fonts (spec, frame, make_number (1), prefer); |
| 2917 | if (NILP (entity_list)) | 2965 | if (NILP (entity_list)) |
| 2918 | entity = font_matching_entity (frame, spec); | 2966 | entity = font_matching_entity (f, NULL, spec); |
| 2919 | else | 2967 | else |
| 2920 | entity = XCAR (entity_list); | 2968 | entity = XCAR (entity_list); |
| 2921 | return (NILP (entity) | 2969 | return (NILP (entity) |
| @@ -3100,6 +3148,7 @@ font_at (c, pos, face, w, string) | |||
| 3100 | { | 3148 | { |
| 3101 | FRAME_PTR f; | 3149 | FRAME_PTR f; |
| 3102 | int multibyte; | 3150 | int multibyte; |
| 3151 | Lisp_Object font_object; | ||
| 3103 | 3152 | ||
| 3104 | if (c < 0) | 3153 | if (c < 0) |
| 3105 | { | 3154 | { |
| @@ -3153,21 +3202,97 @@ font_at (c, pos, face, w, string) | |||
| 3153 | int face_id = FACE_FOR_CHAR (f, face, c, pos, string); | 3202 | int face_id = FACE_FOR_CHAR (f, face, c, pos, string); |
| 3154 | face = FACE_FROM_ID (f, face_id); | 3203 | face = FACE_FROM_ID (f, face_id); |
| 3155 | } | 3204 | } |
| 3156 | if (! face->font_info) | 3205 | if (! face->font) |
| 3157 | return Qnil; | 3206 | return Qnil; |
| 3158 | return font_find_object ((struct font *) face->font_info); | 3207 | |
| 3208 | xassert (font_check_object ((struct font *) face->font)); | ||
| 3209 | XSETFONT (font_object, face->font); | ||
| 3210 | return font_object; | ||
| 3211 | } | ||
| 3212 | |||
| 3213 | |||
| 3214 | /* Check how many characters after POS (at most to LIMIT) can be | ||
| 3215 | displayed by the same font. FACE is the face selected for the | ||
| 3216 | character as POS on frame F. STRING, if not nil, is the string to | ||
| 3217 | check instead of the current buffer. | ||
| 3218 | |||
| 3219 | The return value is the position of the character that is displayed | ||
| 3220 | by the differnt font than that of the character as POS. */ | ||
| 3221 | |||
| 3222 | EMACS_INT | ||
| 3223 | font_range (pos, limit, face, f, string) | ||
| 3224 | EMACS_INT pos, limit; | ||
| 3225 | struct face *face; | ||
| 3226 | FRAME_PTR f; | ||
| 3227 | Lisp_Object string; | ||
| 3228 | { | ||
| 3229 | int multibyte; | ||
| 3230 | EMACS_INT pos_byte; | ||
| 3231 | int c; | ||
| 3232 | struct font *font; | ||
| 3233 | int first = 1; | ||
| 3234 | |||
| 3235 | if (NILP (string)) | ||
| 3236 | { | ||
| 3237 | multibyte = ! NILP (current_buffer->enable_multibyte_characters); | ||
| 3238 | pos_byte = CHAR_TO_BYTE (pos); | ||
| 3239 | } | ||
| 3240 | else | ||
| 3241 | { | ||
| 3242 | multibyte = STRING_MULTIBYTE (string); | ||
| 3243 | pos_byte = string_char_to_byte (string, pos); | ||
| 3244 | } | ||
| 3245 | |||
| 3246 | if (! multibyte) | ||
| 3247 | /* All unibyte character are displayed by the same font. */ | ||
| 3248 | return limit; | ||
| 3249 | |||
| 3250 | while (pos < limit) | ||
| 3251 | { | ||
| 3252 | int face_id; | ||
| 3253 | |||
| 3254 | if (NILP (string)) | ||
| 3255 | FETCH_CHAR_ADVANCE_NO_CHECK (c, pos, pos_byte); | ||
| 3256 | else | ||
| 3257 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte); | ||
| 3258 | face_id = FACE_FOR_CHAR (f, face, c, pos, string); | ||
| 3259 | face = FACE_FROM_ID (f, face_id); | ||
| 3260 | if (first) | ||
| 3261 | { | ||
| 3262 | font = face->font; | ||
| 3263 | first = 0; | ||
| 3264 | continue; | ||
| 3265 | } | ||
| 3266 | else if (font != face->font) | ||
| 3267 | { | ||
| 3268 | pos--; | ||
| 3269 | break; | ||
| 3270 | } | ||
| 3271 | } | ||
| 3272 | return pos; | ||
| 3159 | } | 3273 | } |
| 3160 | 3274 | ||
| 3161 | 3275 | ||
| 3162 | /* Lisp API */ | 3276 | /* Lisp API */ |
| 3163 | 3277 | ||
| 3164 | DEFUN ("fontp", Ffontp, Sfontp, 1, 1, 0, | 3278 | DEFUN ("fontp", Ffontp, Sfontp, 1, 2, 0, |
| 3165 | doc: /* Return t if OBJECT is a font-spec, font-entity, or font-object. | 3279 | doc: /* Return t if OBJECT is a font-spec, font-entity, or font-object. |
| 3166 | Return nil otherwise. */) | 3280 | Return nil otherwise. |
| 3167 | (object) | 3281 | Optional 2nd argument EXTRA-TYPE, if non-nil, specifies to check |
| 3168 | Lisp_Object object; | 3282 | which kind of font it is. It must be one of `font-spec', `font-entity' |
| 3283 | `font-object'. */) | ||
| 3284 | (object, extra_type) | ||
| 3285 | Lisp_Object object, extra_type; | ||
| 3169 | { | 3286 | { |
| 3170 | return (FONTP (object) ? Qt : Qnil); | 3287 | if (NILP (extra_type)) |
| 3288 | return (FONTP (object) ? Qt : Qnil); | ||
| 3289 | if (EQ (extra_type, Qfont_spec)) | ||
| 3290 | return (FONT_SPEC_P (object) ? Qt : Qnil); | ||
| 3291 | if (EQ (extra_type, Qfont_entity)) | ||
| 3292 | return (FONT_ENTITY_P (object) ? Qt : Qnil); | ||
| 3293 | if (EQ (extra_type, Qfont_object)) | ||
| 3294 | return (FONT_OBJECT_P (object) ? Qt : Qnil); | ||
| 3295 | wrong_type_argument (intern ("font-extra-type"), extra_type); | ||
| 3171 | } | 3296 | } |
| 3172 | 3297 | ||
| 3173 | DEFUN ("font-spec", Ffont_spec, Sfont_spec, 0, MANY, 0, | 3298 | DEFUN ("font-spec", Ffont_spec, Sfont_spec, 0, MANY, 0, |
| @@ -3188,7 +3313,7 @@ VALUE must be a string or a symbol specifying the font foundry, e.g. ``misc''. | |||
| 3188 | `:adstyle' | 3313 | `:adstyle' |
| 3189 | 3314 | ||
| 3190 | VALUE must be a string or a symbol specifying the additional | 3315 | VALUE must be a string or a symbol specifying the additional |
| 3191 | typographic style information of a font, e.g. ``sans''. Usually null. | 3316 | typographic style information of a font, e.g. ``sans''. |
| 3192 | 3317 | ||
| 3193 | `:registry' | 3318 | `:registry' |
| 3194 | 3319 | ||
| @@ -3198,38 +3323,101 @@ encoding of a font, e.g. ``iso8859-1''. | |||
| 3198 | `:size' | 3323 | `:size' |
| 3199 | 3324 | ||
| 3200 | VALUE must be a non-negative integer or a floating point number | 3325 | VALUE must be a non-negative integer or a floating point number |
| 3201 | specifying the font size. It specifies the font size in 1/10 pixels | 3326 | specifying the font size. It specifies the font size in pixels |
| 3202 | (if VALUE is an integer), or in points (if VALUE is a float). | 3327 | (if VALUE is an integer), or in points (if VALUE is a float). |
| 3203 | usage: (font-spec ARGS ...) */) | 3328 | usage: (font-spec ARGS ...) */) |
| 3204 | (nargs, args) | 3329 | (nargs, args) |
| 3205 | int nargs; | 3330 | int nargs; |
| 3206 | Lisp_Object *args; | 3331 | Lisp_Object *args; |
| 3207 | { | 3332 | { |
| 3208 | Lisp_Object spec = Fmake_vector (make_number (FONT_SPEC_MAX), Qnil); | 3333 | Lisp_Object spec = font_make_spec (); |
| 3209 | int i; | 3334 | int i; |
| 3210 | 3335 | ||
| 3211 | for (i = 0; i < nargs; i += 2) | 3336 | for (i = 0; i < nargs; i += 2) |
| 3212 | { | 3337 | { |
| 3213 | enum font_property_index prop; | ||
| 3214 | Lisp_Object key = args[i], val = args[i + 1]; | 3338 | Lisp_Object key = args[i], val = args[i + 1]; |
| 3215 | 3339 | ||
| 3216 | prop = get_font_prop_index (key, 0); | 3340 | if (EQ (key, QCname)) |
| 3217 | if (prop < FONT_EXTRA_INDEX) | 3341 | { |
| 3218 | ASET (spec, prop, val); | 3342 | CHECK_STRING (val); |
| 3343 | font_parse_name ((char *) SDATA (val), spec); | ||
| 3344 | font_put_extra (spec, key, val); | ||
| 3345 | } | ||
| 3346 | else if (EQ (key, QCfamily)) | ||
| 3347 | { | ||
| 3348 | CHECK_STRING (val); | ||
| 3349 | font_parse_family_registry (val, Qnil, spec); | ||
| 3350 | } | ||
| 3219 | else | 3351 | else |
| 3220 | { | 3352 | { |
| 3221 | if (EQ (key, QCname)) | 3353 | int idx = get_font_prop_index (key); |
| 3354 | |||
| 3355 | if (idx >= 0) | ||
| 3222 | { | 3356 | { |
| 3223 | CHECK_STRING (val); | 3357 | val = font_prop_validate (idx, Qnil, val); |
| 3224 | font_parse_name ((char *) SDATA (val), spec); | 3358 | if (idx < FONT_EXTRA_INDEX) |
| 3359 | ASET (spec, idx, val); | ||
| 3360 | else | ||
| 3361 | font_put_extra (spec, key, val); | ||
| 3225 | } | 3362 | } |
| 3226 | font_put_extra (spec, key, val); | 3363 | else |
| 3364 | font_put_extra (spec, key, font_prop_validate (0, key, val)); | ||
| 3227 | } | 3365 | } |
| 3228 | } | 3366 | } |
| 3229 | CHECK_VALIDATE_FONT_SPEC (spec); | ||
| 3230 | return spec; | 3367 | return spec; |
| 3231 | } | 3368 | } |
| 3232 | 3369 | ||
| 3370 | DEFUN ("copy-font-spec", Fcopy_font_spec, Scopy_font_spec, 1, 1, 0, | ||
| 3371 | doc: /* Return a copy of FONT as a font-spec. */) | ||
| 3372 | (font) | ||
| 3373 | Lisp_Object font; | ||
| 3374 | { | ||
| 3375 | Lisp_Object new_spec, tail, extra; | ||
| 3376 | int i; | ||
| 3377 | |||
| 3378 | CHECK_FONT (font); | ||
| 3379 | new_spec = font_make_spec (); | ||
| 3380 | for (i = 1; i < FONT_EXTRA_INDEX; i++) | ||
| 3381 | ASET (new_spec, i, AREF (font, i)); | ||
| 3382 | extra = Qnil; | ||
| 3383 | for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) | ||
| 3384 | { | ||
| 3385 | if (! EQ (XCAR (XCAR (tail)), QCfont_entity)) | ||
| 3386 | extra = Fcons (Fcons (XCAR (XCAR (tail)), XCDR (XCAR (tail))), extra); | ||
| 3387 | } | ||
| 3388 | ASET (new_spec, FONT_EXTRA_INDEX, extra); | ||
| 3389 | return new_spec; | ||
| 3390 | } | ||
| 3391 | |||
| 3392 | DEFUN ("merge-font-spec", Fmerge_font_spec, Smerge_font_spec, 2, 2, 0, | ||
| 3393 | doc: /* Merge font-specs FROM and TO, and return a new font-spec. | ||
| 3394 | Every specified properties in FROM override the corresponding | ||
| 3395 | properties in TO. */) | ||
| 3396 | (from, to) | ||
| 3397 | Lisp_Object from, to; | ||
| 3398 | { | ||
| 3399 | Lisp_Object extra, tail; | ||
| 3400 | int i; | ||
| 3401 | |||
| 3402 | CHECK_FONT (from); | ||
| 3403 | CHECK_FONT (to); | ||
| 3404 | to = Fcopy_font_spec (to); | ||
| 3405 | for (i = 0; i < FONT_EXTRA_INDEX; i++) | ||
| 3406 | ASET (to, i, AREF (from, i)); | ||
| 3407 | extra = AREF (to, FONT_EXTRA_INDEX); | ||
| 3408 | for (tail = AREF (from, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) | ||
| 3409 | if (! EQ (XCAR (XCAR (tail)), Qfont_entity)) | ||
| 3410 | { | ||
| 3411 | Lisp_Object slot = assq_no_quit (XCAR (XCAR (tail)), extra); | ||
| 3412 | |||
| 3413 | if (! NILP (slot)) | ||
| 3414 | XSETCDR (slot, XCDR (XCAR (tail))); | ||
| 3415 | else | ||
| 3416 | extra = Fcons (Fcons (XCAR (XCAR (tail)), XCDR (XCAR (tail))), extra); | ||
| 3417 | } | ||
| 3418 | ASET (to, FONT_EXTRA_INDEX, extra); | ||
| 3419 | return to; | ||
| 3420 | } | ||
| 3233 | 3421 | ||
| 3234 | DEFUN ("font-get", Ffont_get, Sfont_get, 2, 2, 0, | 3422 | DEFUN ("font-get", Ffont_get, Sfont_get, 2, 2, 0, |
| 3235 | doc: /* Return the value of FONT's property KEY. | 3423 | doc: /* Return the value of FONT's property KEY. |
| @@ -3237,29 +3425,15 @@ FONT is a font-spec, a font-entity, or a font-object. */) | |||
| 3237 | (font, key) | 3425 | (font, key) |
| 3238 | Lisp_Object font, key; | 3426 | Lisp_Object font, key; |
| 3239 | { | 3427 | { |
| 3240 | enum font_property_index idx; | 3428 | int idx; |
| 3241 | 3429 | ||
| 3242 | if (FONT_OBJECT_P (font)) | 3430 | CHECK_FONT (font); |
| 3243 | { | 3431 | CHECK_SYMBOL (key); |
| 3244 | struct font *fontp = XSAVE_VALUE (font)->pointer; | ||
| 3245 | 3432 | ||
| 3246 | if (EQ (key, QCotf)) | 3433 | idx = get_font_prop_index (key); |
| 3247 | { | 3434 | if (idx >= 0 && idx < FONT_EXTRA_INDEX) |
| 3248 | if (fontp->driver->otf_capability) | ||
| 3249 | return fontp->driver->otf_capability (fontp); | ||
| 3250 | else | ||
| 3251 | return Qnil; | ||
| 3252 | } | ||
| 3253 | font = fontp->entity; | ||
| 3254 | } | ||
| 3255 | else | ||
| 3256 | CHECK_FONT (font); | ||
| 3257 | idx = get_font_prop_index (key, 0); | ||
| 3258 | if (idx < FONT_EXTRA_INDEX) | ||
| 3259 | return AREF (font, idx); | 3435 | return AREF (font, idx); |
| 3260 | if (FONT_ENTITY_P (font)) | 3436 | return Fcdr (Fassq (key, AREF (font, FONT_EXTRA_INDEX))); |
| 3261 | return Qnil; | ||
| 3262 | return Fcdr (Fassoc (key, AREF (font, FONT_EXTRA_INDEX))); | ||
| 3263 | } | 3437 | } |
| 3264 | 3438 | ||
| 3265 | 3439 | ||
| @@ -3268,19 +3442,21 @@ DEFUN ("font-put", Ffont_put, Sfont_put, 3, 3, 0, | |||
| 3268 | (font_spec, prop, val) | 3442 | (font_spec, prop, val) |
| 3269 | Lisp_Object font_spec, prop, val; | 3443 | Lisp_Object font_spec, prop, val; |
| 3270 | { | 3444 | { |
| 3271 | enum font_property_index idx; | 3445 | int idx; |
| 3272 | Lisp_Object extra, slot; | 3446 | Lisp_Object extra, slot; |
| 3273 | 3447 | ||
| 3274 | CHECK_FONT_SPEC (font_spec); | 3448 | CHECK_FONT_SPEC (font_spec); |
| 3275 | idx = get_font_prop_index (prop, 0); | 3449 | idx = get_font_prop_index (prop); |
| 3276 | if (idx < FONT_EXTRA_INDEX) | 3450 | if (idx >= 0 && idx < FONT_EXTRA_INDEX) |
| 3277 | return ASET (font_spec, idx, val); | 3451 | { |
| 3278 | extra = AREF (font_spec, FONT_EXTRA_INDEX); | 3452 | if (idx == FONT_FAMILY_INDEX |
| 3279 | slot = Fassoc (extra, prop); | 3453 | && STRINGP (val)) |
| 3280 | if (NILP (slot)) | 3454 | font_parse_family_registry (val, Qnil, font_spec); |
| 3281 | extra = Fcons (Fcons (prop, val), extra); | 3455 | else |
| 3456 | ASET (font_spec, idx, font_prop_validate (idx, Qnil, val)); | ||
| 3457 | } | ||
| 3282 | else | 3458 | else |
| 3283 | Fsetcdr (slot, val); | 3459 | font_put_extra (font_spec, prop, font_prop_validate (0, prop, val)); |
| 3284 | return val; | 3460 | return val; |
| 3285 | } | 3461 | } |
| 3286 | 3462 | ||
| @@ -3300,7 +3476,7 @@ how they are close to PREFER. */) | |||
| 3300 | if (NILP (frame)) | 3476 | if (NILP (frame)) |
| 3301 | frame = selected_frame; | 3477 | frame = selected_frame; |
| 3302 | CHECK_LIVE_FRAME (frame); | 3478 | CHECK_LIVE_FRAME (frame); |
| 3303 | CHECK_VALIDATE_FONT_SPEC (font_spec); | 3479 | CHECK_FONT_SPEC (font_spec); |
| 3304 | if (! NILP (num)) | 3480 | if (! NILP (num)) |
| 3305 | { | 3481 | { |
| 3306 | CHECK_NUMBER (num); | 3482 | CHECK_NUMBER (num); |
| @@ -3309,7 +3485,7 @@ how they are close to PREFER. */) | |||
| 3309 | return Qnil; | 3485 | return Qnil; |
| 3310 | } | 3486 | } |
| 3311 | if (! NILP (prefer)) | 3487 | if (! NILP (prefer)) |
| 3312 | CHECK_FONT (prefer); | 3488 | CHECK_FONT_SPEC (prefer); |
| 3313 | 3489 | ||
| 3314 | vec = font_list_entities (frame, font_spec); | 3490 | vec = font_list_entities (frame, font_spec); |
| 3315 | len = ASIZE (vec); | 3491 | len = ASIZE (vec); |
| @@ -3319,7 +3495,7 @@ how they are close to PREFER. */) | |||
| 3319 | return Fcons (AREF (vec, 0), Qnil); | 3495 | return Fcons (AREF (vec, 0), Qnil); |
| 3320 | 3496 | ||
| 3321 | if (! NILP (prefer)) | 3497 | if (! NILP (prefer)) |
| 3322 | vec = font_sort_entites (vec, prefer, frame, font_spec); | 3498 | vec = font_sort_entites (vec, prefer, frame, font_spec, 0); |
| 3323 | 3499 | ||
| 3324 | list = tail = Fcons (AREF (vec, 0), Qnil); | 3500 | list = tail = Fcons (AREF (vec, 0), Qnil); |
| 3325 | if (n == 0 || n > len) | 3501 | if (n == 0 || n > len) |
| @@ -3334,7 +3510,7 @@ how they are close to PREFER. */) | |||
| 3334 | return list; | 3510 | return list; |
| 3335 | } | 3511 | } |
| 3336 | 3512 | ||
| 3337 | DEFUN ("list-families", Flist_families, Slist_families, 0, 1, 0, | 3513 | DEFUN ("font-family-list", Ffont_family_list, Sfont_family_list, 0, 1, 0, |
| 3338 | doc: /* List available font families on the current frame. | 3514 | doc: /* List available font families on the current frame. |
| 3339 | Optional argument FRAME specifies the target frame. */) | 3515 | Optional argument FRAME specifies the target frame. */) |
| 3340 | (frame) | 3516 | (frame) |
| @@ -3392,19 +3568,17 @@ If the name is too long for XLFD (maximum 255 chars), return nil. */) | |||
| 3392 | char name[256]; | 3568 | char name[256]; |
| 3393 | int pixel_size = 0; | 3569 | int pixel_size = 0; |
| 3394 | 3570 | ||
| 3395 | if (FONT_SPEC_P (font)) | 3571 | CHECK_FONT (font); |
| 3396 | CHECK_VALIDATE_FONT_SPEC (font); | 3572 | |
| 3397 | else if (FONT_ENTITY_P (font)) | 3573 | if (FONT_OBJECT_P (font)) |
| 3398 | CHECK_FONT (font); | ||
| 3399 | else | ||
| 3400 | { | 3574 | { |
| 3401 | struct font *fontp; | 3575 | Lisp_Object font_name = AREF (font, FONT_NAME_INDEX); |
| 3402 | 3576 | ||
| 3403 | CHECK_FONT_GET_OBJECT (font, fontp); | 3577 | if (STRINGP (font_name) |
| 3404 | font = fontp->entity; | 3578 | && SDATA (font_name)[0] == '-') |
| 3405 | pixel_size = fontp->pixel_size; | 3579 | return font_name; |
| 3580 | pixel_size = XFONT_OBJECT (font)->pixel_size; | ||
| 3406 | } | 3581 | } |
| 3407 | |||
| 3408 | if (font_unparse_xlfd (font, pixel_size, name, 256) < 0) | 3582 | if (font_unparse_xlfd (font, pixel_size, name, 256) < 0) |
| 3409 | return Qnil; | 3583 | return Qnil; |
| 3410 | return build_string (name); | 3584 | return build_string (name); |
| @@ -3445,41 +3619,55 @@ DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0, | |||
| 3445 | } | 3619 | } |
| 3446 | 3620 | ||
| 3447 | DEFUN ("internal-set-font-style-table", Finternal_set_font_style_table, | 3621 | DEFUN ("internal-set-font-style-table", Finternal_set_font_style_table, |
| 3448 | Sinternal_set_font_style_table, 2, 2, 0, | 3622 | Sinternal_set_font_style_table, 3, 3, 0, |
| 3449 | doc: /* Set font style table for PROP to TABLE. | 3623 | doc: /* Setup font style table from WEIGHT, SLANT, and WIDTH tables. |
| 3450 | PROP must be `:weight', `:slant', or `:width'. | 3624 | WEIGHT, SLANT, WIDTH must be `font-weight-table', `font-slant-table', |
| 3451 | TABLE must be an alist of symbols vs the corresponding numeric values | 3625 | `font-width-table' respectivly. |
| 3452 | sorted by numeric values. */) | 3626 | This function is called after those tables are initialized. */) |
| 3453 | (prop, table) | 3627 | (weight, slant, width) |
| 3454 | Lisp_Object prop, table; | 3628 | Lisp_Object weight, slant, width; |
| 3455 | { | 3629 | { |
| 3456 | int table_index; | 3630 | Lisp_Object tables[3]; |
| 3457 | int numeric; | 3631 | int i; |
| 3458 | Lisp_Object tail, val; | 3632 | |
| 3633 | tables[0] = weight, tables[1] = slant, tables[2] = width; | ||
| 3459 | 3634 | ||
| 3460 | CHECK_SYMBOL (prop); | 3635 | font_style_table = Fmake_vector (make_number (3), Qnil); |
| 3461 | table_index = (EQ (prop, QCweight) ? 0 | 3636 | /* In the following loop, we don't use XCAR and XCDR until assuring |
| 3462 | : EQ (prop, QCslant) ? 1 | 3637 | the argument is a cons cell so that the error in the tables can |
| 3463 | : EQ (prop, QCwidth) ? 2 | 3638 | be detected. */ |
| 3464 | : 3); | 3639 | for (i = 0; i < 3; i++) |
| 3465 | if (table_index >= ASIZE (font_style_table)) | ||
| 3466 | error ("Invalid font style property: %s", SDATA (SYMBOL_NAME (prop))); | ||
| 3467 | table = Fcopy_sequence (table); | ||
| 3468 | numeric = -1; | ||
| 3469 | for (tail = table; CONSP (tail); tail = XCDR (tail)) | ||
| 3470 | { | 3640 | { |
| 3471 | prop = Fcar (XCAR (tail)); | 3641 | Lisp_Object tail, elt, list, val; |
| 3472 | val = Fcdr (XCAR (tail)); | 3642 | |
| 3473 | CHECK_SYMBOL (prop); | 3643 | for (tail = tables[i], list = Qnil; CONSP (tail); tail = XCDR (tail)) |
| 3474 | CHECK_NATNUM (val); | 3644 | { |
| 3475 | if (numeric > XINT (val)) | 3645 | int numeric = -1; |
| 3476 | error ("Numeric values not sorted for %s", SDATA (SYMBOL_NAME (prop))); | 3646 | |
| 3477 | else if (numeric == XINT (val)) | 3647 | elt = Fcar (tail); |
| 3478 | error ("Duplicate numeric values for %s", SDATA (SYMBOL_NAME (prop))); | 3648 | CHECK_SYMBOL (Fcar (elt)); |
| 3479 | numeric = XINT (val); | 3649 | val = Fcons (XCAR (elt), Qnil); |
| 3480 | XSETCAR (tail, Fcons (prop, val)); | 3650 | elt = XCDR (elt); |
| 3651 | CHECK_NATNUM (Fcar (elt)); | ||
| 3652 | if (numeric >= XINT (XCAR (elt))) | ||
| 3653 | error ("Numeric values not unique nor sorted in %s", | ||
| 3654 | (i == 0 ? "font-weight-table" | ||
| 3655 | : i == 1 ? "font-slant-table" | ||
| 3656 | : "font-width-table")); | ||
| 3657 | numeric = XINT (XCAR (elt)); | ||
| 3658 | XSETCDR (val, XCAR (elt)); | ||
| 3659 | list = Fcons (val, list); | ||
| 3660 | for (elt = XCDR (elt); CONSP (elt); elt = XCDR (elt)) | ||
| 3661 | { | ||
| 3662 | val = XCAR (elt); | ||
| 3663 | CHECK_SYMBOL (val); | ||
| 3664 | list = Fcons (Fcons (XCAR (elt), make_number (numeric)), list); | ||
| 3665 | } | ||
| 3666 | } | ||
| 3667 | list = Fnreverse (list); | ||
| 3668 | ASET (font_style_table, i, Fvconcat (1, &list)); | ||
| 3481 | } | 3669 | } |
| 3482 | ASET (font_style_table, table_index, table); | 3670 | |
| 3483 | return Qnil; | 3671 | return Qnil; |
| 3484 | } | 3672 | } |
| 3485 | 3673 | ||
| @@ -3544,7 +3732,7 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */) | |||
| 3544 | CHECK_VECTOR (gstring); | 3732 | CHECK_VECTOR (gstring); |
| 3545 | if (NILP (font_object)) | 3733 | if (NILP (font_object)) |
| 3546 | font_object = LGSTRING_FONT (gstring); | 3734 | font_object = LGSTRING_FONT (gstring); |
| 3547 | CHECK_FONT_GET_OBJECT (font_object, font); | 3735 | font = XFONT_OBJECT (font_object); |
| 3548 | 3736 | ||
| 3549 | if (STRINGP (object)) | 3737 | if (STRINGP (object)) |
| 3550 | { | 3738 | { |
| @@ -3623,11 +3811,11 @@ FONT-OBJECT. */) | |||
| 3623 | struct font_metrics metrics; | 3811 | struct font_metrics metrics; |
| 3624 | EMACS_INT start, end; | 3812 | EMACS_INT start, end; |
| 3625 | Lisp_Object gstring, n; | 3813 | Lisp_Object gstring, n; |
| 3626 | int len, i, j; | 3814 | int len, i; |
| 3627 | 3815 | ||
| 3628 | if (! FONT_OBJECT_P (font_object)) | 3816 | if (! FONT_OBJECT_P (font_object)) |
| 3629 | return Qnil; | 3817 | return Qnil; |
| 3630 | CHECK_FONT_GET_OBJECT (font_object, font); | 3818 | font = XFONT_OBJECT (font_object); |
| 3631 | if (! font->driver->shape) | 3819 | if (! font->driver->shape) |
| 3632 | return Qnil; | 3820 | return Qnil; |
| 3633 | 3821 | ||
| @@ -3792,7 +3980,8 @@ glyph-string. */) | |||
| 3792 | int len, num; | 3980 | int len, num; |
| 3793 | 3981 | ||
| 3794 | check_otf_features (otf_features); | 3982 | check_otf_features (otf_features); |
| 3795 | CHECK_FONT_GET_OBJECT (font_object, font); | 3983 | CHECK_FONT_OBJECT (font_object); |
| 3984 | font = XFONT_OBJECT (font_object); | ||
| 3796 | if (! font->driver->otf_drive) | 3985 | if (! font->driver->otf_drive) |
| 3797 | error ("Font backend %s can't drive OpenType GSUB table", | 3986 | error ("Font backend %s can't drive OpenType GSUB table", |
| 3798 | SDATA (SYMBOL_NAME (font->driver->type))); | 3987 | SDATA (SYMBOL_NAME (font->driver->type))); |
| @@ -3883,19 +4072,22 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0, | |||
| 3883 | int isize; | 4072 | int isize; |
| 3884 | 4073 | ||
| 3885 | CHECK_FONT_ENTITY (font_entity); | 4074 | CHECK_FONT_ENTITY (font_entity); |
| 3886 | if (NILP (size)) | ||
| 3887 | size = AREF (font_entity, FONT_SIZE_INDEX); | ||
| 3888 | CHECK_NUMBER (size); | ||
| 3889 | if (NILP (frame)) | 4075 | if (NILP (frame)) |
| 3890 | frame = selected_frame; | 4076 | frame = selected_frame; |
| 3891 | CHECK_LIVE_FRAME (frame); | 4077 | CHECK_LIVE_FRAME (frame); |
| 3892 | 4078 | ||
| 3893 | isize = XINT (size); | 4079 | if (NILP (size)) |
| 3894 | if (isize == 0) | 4080 | isize = XINT (AREF (font_entity, FONT_SIZE_INDEX)); |
| 3895 | isize = 120; | 4081 | else |
| 3896 | if (isize < 0) | 4082 | { |
| 3897 | isize = POINT_TO_PIXEL (- isize, XFRAME (frame)->resy); | 4083 | CHECK_NUMBER_OR_FLOAT (size); |
| 3898 | 4084 | if (FLOATP (size)) | |
| 4085 | isize = POINT_TO_PIXEL (- isize, XFRAME (frame)->resy); | ||
| 4086 | else | ||
| 4087 | isize = XINT (size); | ||
| 4088 | if (isize == 0) | ||
| 4089 | isize = 120; | ||
| 4090 | } | ||
| 3899 | return font_open_entity (XFRAME (frame), font_entity, isize); | 4091 | return font_open_entity (XFRAME (frame), font_entity, isize); |
| 3900 | } | 4092 | } |
| 3901 | 4093 | ||
| @@ -3962,22 +4154,16 @@ If the font is not OpenType font, CAPABILITY is nil. */) | |||
| 3962 | CHECK_FONT_GET_OBJECT (font_object, font); | 4154 | CHECK_FONT_GET_OBJECT (font_object, font); |
| 3963 | 4155 | ||
| 3964 | val = Fmake_vector (make_number (9), Qnil); | 4156 | val = Fmake_vector (make_number (9), Qnil); |
| 3965 | if (font->font.full_name) | 4157 | ASET (val, 0, AREF (font_object, FONT_NAME_INDEX)); |
| 3966 | ASET (val, 0, make_unibyte_string (font->font.full_name, | 4158 | ASET (val, 1, AREF (font_object, FONT_FILE_INDEX)); |
| 3967 | strlen (font->font.full_name))); | ||
| 3968 | if (font->file_name) | ||
| 3969 | ASET (val, 1, make_unibyte_string (font->file_name, | ||
| 3970 | strlen (font->file_name))); | ||
| 3971 | ASET (val, 2, make_number (font->pixel_size)); | 4159 | ASET (val, 2, make_number (font->pixel_size)); |
| 3972 | ASET (val, 3, make_number (font->font.size)); | 4160 | ASET (val, 3, make_number (font->max_width)); |
| 3973 | ASET (val, 4, make_number (font->ascent)); | 4161 | ASET (val, 4, make_number (font->ascent)); |
| 3974 | ASET (val, 5, make_number (font->descent)); | 4162 | ASET (val, 5, make_number (font->descent)); |
| 3975 | ASET (val, 6, make_number (font->font.space_width)); | 4163 | ASET (val, 6, make_number (font->space_width)); |
| 3976 | ASET (val, 7, make_number (font->font.average_width)); | 4164 | ASET (val, 7, make_number (font->average_width)); |
| 3977 | if (font->driver->otf_capability) | 4165 | if (font->driver->otf_capability) |
| 3978 | ASET (val, 8, Fcons (Qopentype, font->driver->otf_capability (font))); | 4166 | ASET (val, 8, Fcons (Qopentype, font->driver->otf_capability (font))); |
| 3979 | else | ||
| 3980 | ASET (val, 8, Fcons (font->format, Qnil)); | ||
| 3981 | return val; | 4167 | return val; |
| 3982 | } | 4168 | } |
| 3983 | 4169 | ||
| @@ -4031,10 +4217,7 @@ FONT is a font-spec, font-entity, or font-object. */) | |||
| 4031 | Lisp_Object spec, font; | 4217 | Lisp_Object spec, font; |
| 4032 | { | 4218 | { |
| 4033 | CHECK_FONT_SPEC (spec); | 4219 | CHECK_FONT_SPEC (spec); |
| 4034 | if (FONT_OBJECT_P (font)) | 4220 | CHECK_FONT (font); |
| 4035 | font = ((struct font *) XSAVE_VALUE (font)->pointer)->entity; | ||
| 4036 | else if (! FONT_ENTITY_P (font)) | ||
| 4037 | CHECK_FONT_SPEC (font); | ||
| 4038 | 4221 | ||
| 4039 | return (font_match_p (spec, font) ? Qt : Qnil); | 4222 | return (font_match_p (spec, font) ? Qt : Qnil); |
| 4040 | } | 4223 | } |
| @@ -4058,9 +4241,6 @@ the current buffer. It defaults to the currently selected window. */) | |||
| 4058 | } | 4241 | } |
| 4059 | else | 4242 | else |
| 4060 | { | 4243 | { |
| 4061 | EMACS_INT len; | ||
| 4062 | unsigned char *str; | ||
| 4063 | |||
| 4064 | CHECK_NUMBER (position); | 4244 | CHECK_NUMBER (position); |
| 4065 | CHECK_STRING (string); | 4245 | CHECK_STRING (string); |
| 4066 | pos = XINT (position); | 4246 | pos = XINT (position); |
| @@ -4138,18 +4318,19 @@ syms_of_font () | |||
| 4138 | sort_shift_bits[FONT_ADSTYLE_INDEX] = 28; | 4318 | sort_shift_bits[FONT_ADSTYLE_INDEX] = 28; |
| 4139 | sort_shift_bits[FONT_FOUNDRY_INDEX] = 29; | 4319 | sort_shift_bits[FONT_FOUNDRY_INDEX] = 29; |
| 4140 | sort_shift_bits[FONT_FAMILY_INDEX] = 30; | 4320 | sort_shift_bits[FONT_FAMILY_INDEX] = 30; |
| 4141 | sort_shift_bits[FONT_REGISTRY_INDEX] = 31; | 4321 | /* Note that sort_shift_bits[FONT_SORT_TYPE] and |
| 4142 | /* Note that sort_shift_bits[FONT_TYPE_INDEX] is never used. */ | 4322 | sort_shift_bits[FONT_SORT_REGISTRY] are never used. */ |
| 4143 | 4323 | ||
| 4144 | staticpro (&font_style_table); | 4324 | staticpro (&font_style_table); |
| 4145 | font_style_table = Fmake_vector (make_number (3), Qnil); | 4325 | font_style_table = Fmake_vector (make_number (3), Qnil); |
| 4146 | 4326 | ||
| 4147 | staticpro (&font_family_alist); | ||
| 4148 | font_family_alist = Qnil; | ||
| 4149 | |||
| 4150 | staticpro (&font_charset_alist); | 4327 | staticpro (&font_charset_alist); |
| 4151 | font_charset_alist = Qnil; | 4328 | font_charset_alist = Qnil; |
| 4152 | 4329 | ||
| 4330 | DEFSYM (Qfont_spec, "font-spec"); | ||
| 4331 | DEFSYM (Qfont_entity, "font-entity"); | ||
| 4332 | DEFSYM (Qfont_object, "font-object"); | ||
| 4333 | |||
| 4153 | DEFSYM (Qopentype, "opentype"); | 4334 | DEFSYM (Qopentype, "opentype"); |
| 4154 | 4335 | ||
| 4155 | DEFSYM (Qiso8859_1, "iso8859-1"); | 4336 | DEFSYM (Qiso8859_1, "iso8859-1"); |
| @@ -4158,7 +4339,7 @@ syms_of_font () | |||
| 4158 | DEFSYM (Qunicode_sip, "unicode-sip"); | 4339 | DEFSYM (Qunicode_sip, "unicode-sip"); |
| 4159 | 4340 | ||
| 4160 | DEFSYM (QCotf, ":otf"); | 4341 | DEFSYM (QCotf, ":otf"); |
| 4161 | DEFSYM (QClanguage, ":language"); | 4342 | DEFSYM (QClang, ":lang"); |
| 4162 | DEFSYM (QCscript, ":script"); | 4343 | DEFSYM (QCscript, ":script"); |
| 4163 | DEFSYM (QCantialias, ":antialias"); | 4344 | DEFSYM (QCantialias, ":antialias"); |
| 4164 | 4345 | ||
| @@ -4168,15 +4349,15 @@ syms_of_font () | |||
| 4168 | DEFSYM (QCspacing, ":spacing"); | 4349 | DEFSYM (QCspacing, ":spacing"); |
| 4169 | DEFSYM (QCdpi, ":dpi"); | 4350 | DEFSYM (QCdpi, ":dpi"); |
| 4170 | DEFSYM (QCscalable, ":scalable"); | 4351 | DEFSYM (QCscalable, ":scalable"); |
| 4171 | DEFSYM (QCextra, ":extra"); | 4352 | DEFSYM (QCavgwidth, ":avgwidth"); |
| 4353 | DEFSYM (QCfont_entity, ":font-entity"); | ||
| 4354 | DEFSYM (QCfc_unknown_spec, ":fc-unknown-spec"); | ||
| 4172 | 4355 | ||
| 4173 | DEFSYM (Qc, "c"); | 4356 | DEFSYM (Qc, "c"); |
| 4174 | DEFSYM (Qm, "m"); | 4357 | DEFSYM (Qm, "m"); |
| 4175 | DEFSYM (Qp, "p"); | 4358 | DEFSYM (Qp, "p"); |
| 4176 | DEFSYM (Qd, "d"); | 4359 | DEFSYM (Qd, "d"); |
| 4177 | 4360 | ||
| 4178 | staticpro (&null_string); | ||
| 4179 | null_string = build_string (""); | ||
| 4180 | staticpro (&null_vector); | 4361 | staticpro (&null_vector); |
| 4181 | null_vector = Fmake_vector (make_number (0), Qnil); | 4362 | null_vector = Fmake_vector (make_number (0), Qnil); |
| 4182 | 4363 | ||
| @@ -4195,7 +4376,7 @@ syms_of_font () | |||
| 4195 | defsubr (&Sfont_get); | 4376 | defsubr (&Sfont_get); |
| 4196 | defsubr (&Sfont_put); | 4377 | defsubr (&Sfont_put); |
| 4197 | defsubr (&Slist_fonts); | 4378 | defsubr (&Slist_fonts); |
| 4198 | defsubr (&Slist_families); | 4379 | defsubr (&Sfont_family_list); |
| 4199 | defsubr (&Sfind_font); | 4380 | defsubr (&Sfind_font); |
| 4200 | defsubr (&Sfont_xlfd_name); | 4381 | defsubr (&Sfont_xlfd_name); |
| 4201 | defsubr (&Sclear_font_cache); | 4382 | defsubr (&Sclear_font_cache); |
| @@ -4218,34 +4399,29 @@ syms_of_font () | |||
| 4218 | #endif | 4399 | #endif |
| 4219 | #endif /* FONT_DEBUG */ | 4400 | #endif /* FONT_DEBUG */ |
| 4220 | 4401 | ||
| 4221 | #ifdef USE_FONT_BACKEND | ||
| 4222 | if (enable_font_backend) | ||
| 4223 | { | ||
| 4224 | #ifdef HAVE_FREETYPE | 4402 | #ifdef HAVE_FREETYPE |
| 4225 | syms_of_ftfont (); | 4403 | syms_of_ftfont (); |
| 4226 | #ifdef HAVE_X_WINDOWS | 4404 | #ifdef HAVE_X_WINDOWS |
| 4227 | syms_of_xfont (); | 4405 | syms_of_xfont (); |
| 4228 | syms_of_ftxfont (); | 4406 | syms_of_ftxfont (); |
| 4229 | #ifdef HAVE_XFT | 4407 | #ifdef HAVE_XFT |
| 4230 | syms_of_xftfont (); | 4408 | syms_of_xftfont (); |
| 4231 | #endif /* HAVE_XFT */ | 4409 | #endif /* HAVE_XFT */ |
| 4232 | #endif /* HAVE_X_WINDOWS */ | 4410 | #endif /* HAVE_X_WINDOWS */ |
| 4233 | #else /* not HAVE_FREETYPE */ | 4411 | #else /* not HAVE_FREETYPE */ |
| 4234 | #ifdef HAVE_X_WINDOWS | 4412 | #ifdef HAVE_X_WINDOWS |
| 4235 | syms_of_xfont (); | 4413 | syms_of_xfont (); |
| 4236 | #endif /* HAVE_X_WINDOWS */ | 4414 | #endif /* HAVE_X_WINDOWS */ |
| 4237 | #endif /* not HAVE_FREETYPE */ | 4415 | #endif /* not HAVE_FREETYPE */ |
| 4238 | #ifdef HAVE_BDFFONT | 4416 | #ifdef HAVE_BDFFONT |
| 4239 | syms_of_bdffont (); | 4417 | syms_of_bdffont (); |
| 4240 | #endif /* HAVE_BDFFONT */ | 4418 | #endif /* HAVE_BDFFONT */ |
| 4241 | #ifdef WINDOWSNT | 4419 | #ifdef WINDOWSNT |
| 4242 | syms_of_w32font (); | 4420 | syms_of_w32font (); |
| 4243 | #endif /* WINDOWSNT */ | 4421 | #endif /* WINDOWSNT */ |
| 4244 | #ifdef MAC_OS | 4422 | #ifdef MAC_OS |
| 4245 | syms_of_atmfont (); | 4423 | syms_of_atmfont (); |
| 4246 | #endif /* MAC_OS */ | 4424 | #endif /* MAC_OS */ |
| 4247 | } | ||
| 4248 | #endif /* USE_FONT_BACKEND */ | ||
| 4249 | } | 4425 | } |
| 4250 | 4426 | ||
| 4251 | /* arch-tag: 74c9475d-5976-4c93-a327-942ae3072846 | 4427 | /* arch-tag: 74c9475d-5976-4c93-a327-942ae3072846 |