aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2008-05-14 01:28:01 +0000
committerKenichi Handa2008-05-14 01:28:01 +0000
commit42984a746c17fd54c187bcf69f4609d59f1d0f86 (patch)
tree09408423a8636701a7e028d6add8e2e559a921e0 /src
parent38548f605fd5172cf2ac179d16977f2cc536d4c0 (diff)
downloademacs-42984a746c17fd54c187bcf69f4609d59f1d0f86.tar.gz
emacs-42984a746c17fd54c187bcf69f4609d59f1d0f86.zip
(ftfont_pattern_entity): Argument FRAME removed. Make
a font-entity by font_make_entity. Use font_intern_prop instead of intern_downcase. Use FONT_SET_STYLE to set a style-related font property. If a font is scalable, set avgwidth property to 0. Set font-entity property by font_put_extra. (ftfont_list_generic_family): Argument SPEC and REGISTRY removed. (ffont_driver): Adjusted for the change of struct font_driver. (ftfont_spec_pattern): New function. (ftfont_list): Return a list, not vector. (ftfont_match): Use ftfont_spec_pattern to get a pattern. (ftfont_list_family): Don't downcase names. (ftfont_free_entity): Deleted. (ftfont_open): Return a font-ojbect. Adjusted for the change of struct font. Get underline_thickness and underline_position from font property. Don't update dpyinfo->smallest_font_height and dpyinfo->smallest_char_width. (ftfont_close): Don't free `struct font'. (ftfont_has_char): Adjusted for the format change of font-entity. (ftfont_encode_char, ftfont_text_extents): Likewise.
Diffstat (limited to 'src')
-rw-r--r--src/ftfont.c661
1 files changed, 330 insertions, 331 deletions
diff --git a/src/ftfont.c b/src/ftfont.c
index a3ce243f369..7360742231d 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -71,10 +71,8 @@ struct ftfont_info
71}; 71};
72 72
73static int ftfont_build_basic_charsets P_ ((void)); 73static int ftfont_build_basic_charsets P_ ((void));
74static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, 74static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, Lisp_Object));
75 Lisp_Object, Lisp_Object)); 75static Lisp_Object ftfont_list_generic_family P_ ((Lisp_Object));
76static Lisp_Object ftfont_list_generic_family P_ ((Lisp_Object, Lisp_Object,
77 Lisp_Object));
78Lisp_Object ftfont_font_format P_ ((FcPattern *)); 76Lisp_Object ftfont_font_format P_ ((FcPattern *));
79 77
80#define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM)) 78#define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM))
@@ -99,10 +97,12 @@ ftfont_build_basic_charsets ()
99 return 0; 97 return 0;
100} 98}
101 99
100extern Lisp_Object Qc, Qm, Qp, Qd;
101
102static Lisp_Object 102static Lisp_Object
103ftfont_pattern_entity (p, frame, registry) 103ftfont_pattern_entity (p, registry)
104 FcPattern *p; 104 FcPattern *p;
105 Lisp_Object frame, registry; 105 Lisp_Object registry;
106{ 106{
107 Lisp_Object entity; 107 Lisp_Object entity;
108 FcChar8 *file, *fontformat; 108 FcChar8 *file, *fontformat;
@@ -110,6 +110,7 @@ ftfont_pattern_entity (p, frame, registry)
110 FcChar8 *str; 110 FcChar8 *str;
111 int numeric; 111 int numeric;
112 double dbl; 112 double dbl;
113 FcBool b;
113 114
114 if (FcPatternGetString (p, FC_FILE, 0, &file) != FcResultMatch) 115 if (FcPatternGetString (p, FC_FILE, 0, &file) != FcResultMatch)
115 return Qnil; 116 return Qnil;
@@ -120,38 +121,48 @@ ftfont_pattern_entity (p, frame, registry)
120#endif /* FC_FONTFORMAT */ 121#endif /* FC_FONTFORMAT */
121 fontformat = NULL; 122 fontformat = NULL;
122 123
123 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), null_string); 124 entity = font_make_entity ();
124 125
125 ASET (entity, FONT_TYPE_INDEX, Qfreetype); 126 ASET (entity, FONT_TYPE_INDEX, Qfreetype);
126 ASET (entity, FONT_REGISTRY_INDEX, registry); 127 ASET (entity, FONT_REGISTRY_INDEX, registry);
127 ASET (entity, FONT_FRAME_INDEX, frame);
128 ASET (entity, FONT_OBJLIST_INDEX, Qnil);
129 128
130 if (FcPatternGetString (p, FC_FOUNDRY, 0, &str) == FcResultMatch) 129 if (FcPatternGetString (p, FC_FOUNDRY, 0, &str) == FcResultMatch)
131 ASET (entity, FONT_FOUNDRY_INDEX, intern_downcase (str, strlen (str))); 130 ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (str, strlen (str)));
132 if (FcPatternGetString (p, FC_FAMILY, 0, &str) == FcResultMatch) 131 if (FcPatternGetString (p, FC_FAMILY, 0, &str) == FcResultMatch)
133 ASET (entity, FONT_FAMILY_INDEX, intern_downcase (str, strlen (str))); 132 ASET (entity, FONT_FAMILY_INDEX, font_intern_prop (str, strlen (str)));
134 if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) 133 if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch)
135 { 134 {
136 if (numeric == FC_WEIGHT_REGULAR) 135 if (numeric >= FC_WEIGHT_REGULAR && numeric < FC_WEIGHT_MEDIUM)
137 numeric = 100; 136 numeric = FC_WEIGHT_MEDIUM;
138 ASET (entity, FONT_WEIGHT_INDEX, make_number (numeric)); 137 FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, make_number (numeric));
139 } 138 }
140 if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch) 139 if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch)
141 ASET (entity, FONT_SLANT_INDEX, make_number (numeric + 100)); 140 {
141 numeric += 100;
142 FONT_SET_STYLE (entity, FONT_SLANT_INDEX, make_number (numeric));
143 }
142 if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch) 144 if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch)
143 ASET (entity, FONT_WIDTH_INDEX, make_number (numeric)); 145 {
146 FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_number (numeric));
147 }
144 if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch) 148 if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch)
145 ASET (entity, FONT_SIZE_INDEX, make_number (dbl)); 149 ASET (entity, FONT_SIZE_INDEX, make_number (dbl));
146 else 150 else
147 ASET (entity, FONT_SIZE_INDEX, make_number (0)); 151 ASET (entity, FONT_SIZE_INDEX, make_number (0));
152 if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) == FcResultMatch)
153 ASET (entity, FONT_SPACING_INDEX, make_number (numeric));
154 if (FcPatternGetDouble (p, FC_DPI, 0, &dbl) == FcResultMatch)
155 {
156 int dpi = dbl;
157 ASET (entity, FONT_DPI_INDEX, make_number (dpi));
158 }
159 if (FcPatternGetBool (p, FC_SCALABLE, 0, &b) == FcResultMatch
160 && b == FcTrue)
161 ASET (entity, FONT_AVGWIDTH_INDEX, make_number (0));
148 162
149 if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) != FcResultMatch)
150 numeric = -1;
151 file = FcStrCopy (file); 163 file = FcStrCopy (file);
152 if (! file) 164 if (! file)
153 return Qnil; 165 return Qnil;
154
155 p = FcPatternCreate (); 166 p = FcPatternCreate ();
156 if (! p) 167 if (! p)
157 return Qnil; 168 return Qnil;
@@ -163,24 +174,28 @@ ftfont_pattern_entity (p, frame, registry)
163 || (fontformat 174 || (fontformat
164 && FcPatternAddString (p, FC_FONTFORMAT, fontformat) == FcFalse) 175 && FcPatternAddString (p, FC_FONTFORMAT, fontformat) == FcFalse)
165#endif /* FC_FONTFORMAT */ 176#endif /* FC_FONTFORMAT */
166 || (numeric >= 0 177 )
167 && FcPatternAddInteger (p, FC_SPACING, numeric) == FcFalse))
168 { 178 {
169 FcPatternDestroy (p); 179 FcPatternDestroy (p);
170 return Qnil; 180 return Qnil;
171 } 181 }
172 ASET (entity, FONT_EXTRA_INDEX, make_save_value (p, 0)); 182 font_put_extra (entity, QCfont_entity, make_save_value (p, 0));
173 return entity; 183 return entity;
174} 184}
175 185
186
176static Lisp_Object ftfont_generic_family_list; 187static Lisp_Object ftfont_generic_family_list;
177 188
178static Lisp_Object 189static Lisp_Object
179ftfont_list_generic_family (spec, frame, registry) 190ftfont_list_generic_family (family)
180 Lisp_Object spec, frame, registry; 191 Lisp_Object family;
181{ 192{
182 Lisp_Object family = AREF (spec, FONT_FAMILY_INDEX);
183 Lisp_Object slot, list, val; 193 Lisp_Object slot, list, val;
194 FcObjectSet *objset = NULL;
195 FcPattern *pattern = NULL, *pat = NULL;
196 FcFontSet *fontset = NULL;
197 FcChar8 *fam;
198 int i, j;
184 199
185 if (EQ (family, Qmono)) 200 if (EQ (family, Qmono))
186 family = Qmonospace; 201 family = Qmonospace;
@@ -188,86 +203,53 @@ ftfont_list_generic_family (spec, frame, registry)
188 family = Qsans_serif; 203 family = Qsans_serif;
189 slot = assq_no_quit (family, ftfont_generic_family_list); 204 slot = assq_no_quit (family, ftfont_generic_family_list);
190 if (! CONSP (slot)) 205 if (! CONSP (slot))
191 return null_vector; 206 return Qnil;
192 list = XCDR (slot); 207 list = XCDR (slot);
193 if (EQ (list, Qt)) 208 if (! EQ (list, Qt))
209 return list;
210
211 objset = FcObjectSetBuild (FC_FAMILY, NULL);
212 if (! objset)
213 goto err;
214 pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString,
215 SYMBOL_FcChar8 (family), (char *) 0);
216 if (! pattern)
217 goto err;
218 pat = FcPatternCreate ();
219 if (! pat)
220 goto err;
221 FcConfigSubstitute (NULL, pattern, FcMatchPattern);
222 for (i = 0, list = Qnil;
223 FcPatternGetString (pattern, FC_FAMILY, i, &fam) == FcResultMatch;
224 i++)
194 { 225 {
195 /* Not yet listed. */ 226 if (strcmp ((char *) fam, (char *) SYMBOL_FcChar8 (family)) == 0)
196 FcObjectSet *objset = NULL; 227 continue;
197 FcPattern *pattern = NULL, *pat = NULL; 228 if (! FcPatternAddString (pat, FC_FAMILY, fam))
198 FcFontSet *fontset = NULL;
199 FcChar8 *fam;
200 int i, j;
201
202 objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT,
203 FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING,
204 FC_CHARSET, FC_FILE,
205#ifdef FC_FONTFORMAT
206 FC_FONTFORMAT,
207#endif /* FC_FONTFORMAT */
208 NULL);
209 if (! objset)
210 goto err;
211 pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString,
212 SYMBOL_FcChar8 (family), (char *) 0);
213 if (! pattern)
214 goto err; 229 goto err;
215 pat = FcPatternCreate (); 230 fontset = FcFontList (NULL, pat, objset);
216 if (! pat) 231 if (! fontset)
217 goto err; 232 goto err;
218 FcConfigSubstitute (NULL, pattern, FcMatchPattern); 233 if (fontset->nfont > 0)
219 for (i = 0, val = Qnil; 234 list = Fcons (intern ((char *) fam), list);
220 FcPatternGetString (pattern, FC_FAMILY, i, &fam) == FcResultMatch; 235 FcFontSetDestroy (fontset);
221 i++) 236 fontset = NULL;
222 { 237 FcPatternDel (pat, FC_FAMILY);
223 if (strcmp ((char *) fam, (char *) SYMBOL_FcChar8 (family)) == 0)
224 continue;
225 if (! FcPatternAddString (pat, FC_FAMILY, fam))
226 goto err;
227 fontset = FcFontList (NULL, pat, objset);
228 if (! fontset)
229 goto err;
230 /* Here we build the list in reverse order so that the last
231 loop in this function build a list in the correct
232 order. */
233 for (j = 0; j < fontset->nfont; j++)
234 {
235 Lisp_Object entity;
236
237 entity = ftfont_pattern_entity (fontset->fonts[j],
238 frame, registry);
239 if (! NILP (entity))
240 val = Fcons (entity, val);
241 }
242 FcFontSetDestroy (fontset);
243 fontset = NULL;
244 FcPatternDel (pat, FC_FAMILY);
245 }
246 list = val;
247 XSETCDR (slot, list);
248 err:
249 if (pat) FcPatternDestroy (pat);
250 if (pattern) FcPatternDestroy (pattern);
251 if (fontset) FcFontSetDestroy (fontset);
252 if (objset) FcObjectSetDestroy (objset);
253 if (EQ (list, Qt))
254 return Qnil;
255 } 238 }
256 ASET (spec, FONT_FAMILY_INDEX, Qnil); 239 XSETCDR (slot, list);
257 for (val = Qnil; CONSP (list); list = XCDR (list)) 240 err:
258 if (font_match_p (spec, XCAR (list))) 241 if (pat) FcPatternDestroy (pat);
259 val = Fcons (XCAR (list), val); 242 if (pattern) FcPatternDestroy (pattern);
260 ASET (spec, FONT_FAMILY_INDEX, family); 243 if (fontset) FcFontSetDestroy (fontset);
261 return Fvconcat (1, &val); 244 if (objset) FcObjectSetDestroy (objset);
245 return list;
262} 246}
263 247
264
265static Lisp_Object ftfont_get_cache P_ ((FRAME_PTR)); 248static Lisp_Object ftfont_get_cache P_ ((FRAME_PTR));
266static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); 249static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object));
267static Lisp_Object ftfont_match P_ ((Lisp_Object, Lisp_Object)); 250static Lisp_Object ftfont_match P_ ((Lisp_Object, Lisp_Object));
268static Lisp_Object ftfont_list_family P_ ((Lisp_Object)); 251static Lisp_Object ftfont_list_family P_ ((Lisp_Object));
269static void ftfont_free_entity P_ ((Lisp_Object)); 252static Lisp_Object ftfont_open P_ ((FRAME_PTR, Lisp_Object, int));
270static struct font *ftfont_open P_ ((FRAME_PTR, Lisp_Object, int));
271static void ftfont_close P_ ((FRAME_PTR, struct font *)); 253static void ftfont_close P_ ((FRAME_PTR, struct font *));
272static int ftfont_has_char P_ ((Lisp_Object, int)); 254static int ftfont_has_char P_ ((Lisp_Object, int));
273static unsigned ftfont_encode_char P_ ((struct font *, int)); 255static unsigned ftfont_encode_char P_ ((struct font *, int));
@@ -282,11 +264,12 @@ static Lisp_Object ftfont_shape P_ ((Lisp_Object));
282struct font_driver ftfont_driver = 264struct font_driver ftfont_driver =
283 { 265 {
284 0, /* Qfreetype */ 266 0, /* Qfreetype */
267 0, /* case insensitive */
285 ftfont_get_cache, 268 ftfont_get_cache,
286 ftfont_list, 269 ftfont_list,
287 ftfont_match, 270 ftfont_match,
288 ftfont_list_family, 271 ftfont_list_family,
289 ftfont_free_entity, 272 NULL,
290 ftfont_open, 273 ftfont_open,
291 ftfont_close, 274 ftfont_close,
292 /* We can't draw a text without device dependent functions. */ 275 /* We can't draw a text without device dependent functions. */
@@ -409,41 +392,41 @@ ftfont_get_open_type_spec (Lisp_Object otf_spec)
409 return spec; 392 return spec;
410} 393}
411 394
412static Lisp_Object 395static FcPattern *
413ftfont_list (frame, spec) 396ftfont_spec_pattern (spec, otlayout, otspec)
414 Lisp_Object frame, spec; 397 Lisp_Object spec;
398 char *otlayout;
399 struct OpenTypeSpec **otspec;
415{ 400{
416 Lisp_Object val, tmp, extra; 401 Lisp_Object val, tmp, extra;
417 int i; 402 int i;
418 FcPattern *pattern = NULL; 403 FcPattern *pattern = NULL;
419 FcCharSet *charset = NULL; 404 FcCharSet *charset = NULL;
420 FcLangSet *langset = NULL; 405 FcLangSet *langset = NULL;
421 FcFontSet *fontset = NULL; 406 int n;
422 FcObjectSet *objset = NULL; 407 int dpi = -1;
423 Lisp_Object script;
424 Lisp_Object registry = Qunicode_bmp;
425 struct OpenTypeSpec *otspec= NULL;
426 int weight = 0;
427 double dpi = -1;
428 int spacing = -1; 408 int spacing = -1;
429 int scalable = -1; 409 int scalable = -1;
430 char otlayout[15]; /* For "otlayout:XXXX" */ 410 Lisp_Object name = Qnil;
431 411 Lisp_Object script = Qnil;
432 val = null_vector; 412 Lisp_Object registry = Qunicode_bmp;
433
434 if (! fc_initialized)
435 {
436 FcInit ();
437 fc_initialized = 1;
438 }
439 413
440 if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX)) 414 if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX))
441 && ! EQ (AREF (spec, FONT_ADSTYLE_INDEX), null_string)) 415 && SBYTES (SYMBOL_NAME (AREF (spec, FONT_ADSTYLE_INDEX))) > 0)
442 return val; 416 /* Fontconfig doesn't support adstyle property. */
443 if (! NILP (AREF (spec, FONT_SLANT_INDEX)) 417 return NULL;
444 && XINT (AREF (spec, FONT_SLANT_INDEX)) < 100) 418 if ((n = FONT_SLANT_NUMERIC (spec)) >= 0
419 && n < 100)
445 /* Fontconfig doesn't support reverse-italic/obligue. */ 420 /* Fontconfig doesn't support reverse-italic/obligue. */
446 return val; 421 return NULL;
422
423 if (INTEGERP (AREF (spec, FONT_DPI_INDEX)))
424 dpi = XINT (AREF (spec, FONT_DPI_INDEX));
425 if (INTEGERP (AREF (spec, FONT_SPACING_INDEX)))
426 spacing = XINT (AREF (spec, FONT_SPACING_INDEX));
427 if (INTEGERP (AREF (spec, FONT_AVGWIDTH_INDEX))
428 && XINT (AREF (spec, FONT_AVGWIDTH_INDEX)) == 0)
429 scalable = 1;
447 430
448 if (! NILP (AREF (spec, FONT_REGISTRY_INDEX))) 431 if (! NILP (AREF (spec, FONT_REGISTRY_INDEX)))
449 { 432 {
@@ -452,34 +435,27 @@ ftfont_list (frame, spec)
452 { 435 {
453 if (! cs_iso8859_1 436 if (! cs_iso8859_1
454 && ftfont_build_basic_charsets () < 0) 437 && ftfont_build_basic_charsets () < 0)
455 return Qnil; 438 return NULL;
456 charset = cs_iso8859_1; 439 charset = cs_iso8859_1;
457 } 440 }
458 else if (! EQ (registry, Qiso10646_1) 441 else if (! EQ (registry, Qiso10646_1)
459 && ! EQ (registry, Qunicode_bmp) 442 && ! EQ (registry, Qunicode_bmp)
460 && ! EQ (registry, Qunicode_sip)) 443 && ! EQ (registry, Qunicode_sip))
461 return val; 444 return NULL;
462 } 445 }
463 446
464 otlayout[0] = '\0'; 447 otlayout[0] = '\0';
465 script = Qnil;
466 for (extra = AREF (spec, FONT_EXTRA_INDEX); 448 for (extra = AREF (spec, FONT_EXTRA_INDEX);
467 CONSP (extra); extra = XCDR (extra)) 449 CONSP (extra); extra = XCDR (extra))
468 { 450 {
469 Lisp_Object key, val; 451 Lisp_Object key, val;
470 452
471 tmp = XCAR (extra); 453 key = XCAR (XCAR (extra)), val = XCDR (XCAR (extra));
472 key = XCAR (tmp), val = XCDR (tmp); 454 if (EQ (key, QCdpi))
473 if (EQ (key, QCotf)) 455 dpi = XINT (val);
474 { 456 else if (EQ (key, QCfc_unknown_spec))
475 otspec = ftfont_get_open_type_spec (val); 457 name = val;
476 if (! otspec) 458 else if (EQ (key, QClang))
477 return null_vector;
478 strcat (otlayout, "otlayout:");
479 OTF_TAG_STR (otspec->script_tag, otlayout + 9);
480 script = otspec->script;
481 }
482 else if (EQ (key, QClanguage))
483 { 459 {
484 langset = FcLangSetCreate (); 460 langset = FcLangSetCreate ();
485 if (! langset) 461 if (! langset)
@@ -495,12 +471,19 @@ ftfont_list (frame, spec)
495 && ! FcLangSetAdd (langset, SYMBOL_FcChar8 (XCAR (val)))) 471 && ! FcLangSetAdd (langset, SYMBOL_FcChar8 (XCAR (val))))
496 goto err; 472 goto err;
497 } 473 }
474 else if (EQ (key, QCname))
475 name = val;
476 else if (EQ (key, QCotf))
477 {
478 *otspec = ftfont_get_open_type_spec (val);
479 if (! *otspec)
480 return NULL;
481 strcat (otlayout, "otlayout:");
482 OTF_TAG_STR ((*otspec)->script_tag, otlayout + 9);
483 script = (*otspec)->script;
484 }
498 else if (EQ (key, QCscript)) 485 else if (EQ (key, QCscript))
499 script = val; 486 script = val;
500 else if (EQ (key, QCdpi))
501 dpi = XINT (val);
502 else if (EQ (key, QCspacing))
503 spacing = XINT (val);
504 else if (EQ (key, QCscalable)) 487 else if (EQ (key, QCscalable))
505 scalable = ! NILP (val); 488 scalable = ! NILP (val);
506 } 489 }
@@ -521,32 +504,15 @@ ftfont_list (frame, spec)
521 } 504 }
522 } 505 }
523 506
524 pattern = FcPatternCreate (); 507 pattern = NILP (name) ? FcPatternCreate () : FcNameParse (SDATA (name));
525 if (! pattern) 508 if (! pattern)
526 goto err; 509 goto err;
510 FcPatternDel (pattern, FC_SIZE);
511 FcPatternDel (pattern, FC_PIXEL_SIZE);
527 tmp = AREF (spec, FONT_FOUNDRY_INDEX); 512 tmp = AREF (spec, FONT_FOUNDRY_INDEX);
528 if (SYMBOLP (tmp) && ! NILP (tmp) 513 if (! NILP (tmp)
529 && ! FcPatternAddString (pattern, FC_FOUNDRY, SYMBOL_FcChar8 (tmp))) 514 && ! FcPatternAddString (pattern, FC_FOUNDRY, SYMBOL_FcChar8 (tmp)))
530 goto err; 515 goto err;
531 tmp = AREF (spec, FONT_FAMILY_INDEX);
532 if (SYMBOLP (tmp) && ! NILP (tmp)
533 && ! FcPatternAddString (pattern, FC_FAMILY, SYMBOL_FcChar8 (tmp)))
534 goto err;
535 /* Emacs conventionally doesn't distinguish normal, regular, and
536 medium weight, but fontconfig does. So, we can't restrict font
537 listing by weight. We check it after getting a list. */
538 tmp = AREF (spec, FONT_WEIGHT_INDEX);
539 if (INTEGERP (tmp))
540 weight = XINT (tmp);
541 tmp = AREF (spec, FONT_SLANT_INDEX);
542 if (INTEGERP (tmp)
543 && ! FcPatternAddInteger (pattern, FC_SLANT, XINT (tmp) - 100))
544 goto err;
545 tmp = AREF (spec, FONT_WIDTH_INDEX);
546 if (INTEGERP (tmp)
547 && ! FcPatternAddInteger (pattern, FC_WIDTH, XINT (tmp)))
548 goto err;
549
550 if (charset 516 if (charset
551 && ! FcPatternAddCharSet (pattern, FC_CHARSET, charset)) 517 && ! FcPatternAddCharSet (pattern, FC_CHARSET, charset))
552 goto err; 518 goto err;
@@ -562,65 +528,100 @@ ftfont_list (frame, spec)
562 if (scalable >= 0 528 if (scalable >= 0
563 && ! FcPatternAddBool (pattern, FC_SCALABLE, scalable ? FcTrue : FcFalse)) 529 && ! FcPatternAddBool (pattern, FC_SCALABLE, scalable ? FcTrue : FcFalse))
564 goto err; 530 goto err;
531 goto finish;
532
533 err:
534 /* We come here because of unexpected error in fontconfig API call
535 (usually insufficient memory). */
536 if (pattern)
537 {
538 FcPatternDestroy (pattern);
539 pattern = NULL;
540 }
541 if (*otspec)
542 {
543 if ((*otspec)->nfeatures[0] > 0)
544 free ((*otspec)->features[0]);
545 if ((*otspec)->nfeatures[1] > 0)
546 free ((*otspec)->features[1]);
547 free (*otspec);
548 *otspec = NULL;
549 }
565 550
551 finish:
552 if (charset && charset != cs_iso8859_1) FcCharSetDestroy (charset);
553 if (langset) FcLangSetDestroy (langset);
554 return pattern;
555}
556
557static Lisp_Object
558ftfont_list (frame, spec)
559 Lisp_Object frame, spec;
560{
561 Lisp_Object val, tmp, registry, family, family_list;
562 int i;
563 FcPattern *pattern;
564 FcFontSet *fontset = NULL;
565 FcObjectSet *objset = NULL;
566 double pixel_size = 0;
567 int weight = -1, slant = -1, width = -1;
568 double dpi = -1;
569 int spacing = -1;
570 int scalable = -1;
571 char otlayout[15]; /* For "otlayout:XXXX" */
572 struct OpenTypeSpec *otspec = NULL;
573
574 if (! fc_initialized)
575 {
576 FcInit ();
577 fc_initialized = 1;
578 }
579
580 pattern = ftfont_spec_pattern (spec, otlayout, &otspec);
581 if (! pattern)
582 return Qnil;
566 objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, 583 objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT,
567 FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, 584 FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, FC_SCALABLE,
568 FC_CHARSET, FC_FILE, 585 FC_CHARSET, FC_FILE,
586#ifdef FC_CAPABILITY
587 FC_CAPABILITY,
588#endif /* FC_CAPABILITY */
569#ifdef FC_FONTFORMAT 589#ifdef FC_FONTFORMAT
570 FC_FONTFORMAT, 590 FC_FONTFORMAT,
571#endif /* FC_FONTFORMAT */ 591#endif /* FC_FONTFORMAT */
572 NULL); 592 NULL);
573 if (! objset) 593 if (! objset)
574 goto err; 594 goto err;
575 if (otlayout[0]) 595
596 registry = AREF (spec, FONT_REGISTRY_INDEX);
597 family = AREF (spec, FONT_FAMILY_INDEX);
598 if (NILP (family))
599 family_list = Fcons (Qnil, Qnil);
600 else
576 { 601 {
577#ifdef FC_CAPABILITY 602 family_list = ftfont_list_generic_family (family);
578 if (! FcObjectSetAdd (objset, FC_CAPABILITY)) 603 if (NILP (family_list))
579 goto err; 604 family_list = Fcons (family, Qnil);
580#else /* not FC_CAPABILITY */
581 goto finish;
582#endif /* not FC_CAPABILITY */
583 } 605 }
584 606
585 fontset = FcFontList (NULL, pattern, objset); 607 for (val = Qnil; CONSP (family_list); family_list = XCDR (family_list))
586 if (! fontset)
587 goto err;
588
589 if (fontset->nfont > 0)
590 { 608 {
591 double pixel_size; 609 family = XCAR (family_list);
592 610 if (! NILP (family))
593 if (NILP (AREF (spec, FONT_SIZE_INDEX))) 611 {
594 pixel_size = 0; 612 FcPatternDel (pattern, FC_FAMILY);
595 else 613 if (! FcPatternAddString (pattern, FC_FAMILY, SYMBOL_FcChar8 (family)))
596 pixel_size = XINT (AREF (spec, FONT_SIZE_INDEX)); 614 goto err;
597 615 }
598 for (i = 0, val = Qnil; i < fontset->nfont; i++) 616 fontset = FcFontList (NULL, pattern, objset);
617 if (! fontset)
618 goto err;
619 for (i = 0; i < fontset->nfont; i++)
599 { 620 {
600 Lisp_Object entity; 621 Lisp_Object entity;
622 int n;
623 double dbl;
601 624
602 if (pixel_size > 0)
603 {
604 double this;
605
606 if (FcPatternGetDouble (fontset->fonts[i], FC_PIXEL_SIZE, 0,
607 &this) == FcResultMatch
608 && ((this < pixel_size - FONT_PIXEL_SIZE_QUANTUM)
609 || (this > pixel_size + FONT_PIXEL_SIZE_QUANTUM)))
610 continue;
611 }
612 if (weight > 0)
613 {
614 int this;
615
616 if (FcPatternGetInteger (fontset->fonts[i], FC_WEIGHT, 0,
617 &this) != FcResultMatch
618 || (this != weight
619 && (weight != 100
620 || this < FC_WEIGHT_REGULAR
621 || this > FC_WEIGHT_MEDIUM)))
622 continue;
623 }
624#ifdef FC_CAPABILITY 625#ifdef FC_CAPABILITY
625 if (otlayout[0]) 626 if (otlayout[0])
626 { 627 {
@@ -655,14 +656,13 @@ ftfont_list (frame, spec)
655 continue; 656 continue;
656 } 657 }
657#endif /* HAVE_LIBOTF */ 658#endif /* HAVE_LIBOTF */
658 entity = ftfont_pattern_entity (fontset->fonts[i], frame, registry); 659 entity = ftfont_pattern_entity (fontset->fonts[i], registry);
659 if (! NILP (entity)) 660 if (! NILP (entity))
660 val = Fcons (entity, val); 661 val = Fcons (entity, val);
661 } 662 }
662 val = Fvconcat (1, &val); 663 FcFontSetDestroy (fontset);
664 fontset = NULL;
663 } 665 }
664 else if (! NILP (AREF (spec, FONT_FAMILY_INDEX)))
665 val = ftfont_list_generic_family (spec, frame, registry);
666 goto finish; 666 goto finish;
667 667
668 err: 668 err:
@@ -671,19 +671,9 @@ ftfont_list (frame, spec)
671 val = Qnil; 671 val = Qnil;
672 672
673 finish: 673 finish:
674 if (charset && charset != cs_iso8859_1) FcCharSetDestroy (charset);
675 if (objset) FcObjectSetDestroy (objset); 674 if (objset) FcObjectSetDestroy (objset);
676 if (fontset) FcFontSetDestroy (fontset); 675 if (fontset) FcFontSetDestroy (fontset);
677 if (langset) FcLangSetDestroy (langset);
678 if (pattern) FcPatternDestroy (pattern); 676 if (pattern) FcPatternDestroy (pattern);
679 if (otspec)
680 {
681 if (otspec->nfeatures[0] > 0)
682 free (otspec->features[0]);
683 if (otspec->nfeatures[1] > 0)
684 free (otspec->features[1]);
685 free (otspec);
686 }
687 return val; 677 return val;
688} 678}
689 679
@@ -692,8 +682,10 @@ ftfont_match (frame, spec)
692 Lisp_Object frame, spec; 682 Lisp_Object frame, spec;
693{ 683{
694 Lisp_Object extra, val, entity; 684 Lisp_Object extra, val, entity;
695 FcPattern *pattern = NULL, *match = NULL; 685 FcPattern *pattern, *match = NULL;
696 FcResult result; 686 FcResult result;
687 char otlayout[15]; /* For "otlayout:XXXX" */
688 struct OpenTypeSpec *otspec = NULL;
697 689
698 if (! fc_initialized) 690 if (! fc_initialized)
699 { 691 {
@@ -701,35 +693,35 @@ ftfont_match (frame, spec)
701 fc_initialized = 1; 693 fc_initialized = 1;
702 } 694 }
703 695
704 extra = AREF (spec, FONT_EXTRA_INDEX); 696 pattern = ftfont_spec_pattern (spec, otlayout, &otspec);
705 val = assq_no_quit (QCname, extra); 697 if (! pattern)
706 if (! CONSP (val) || ! STRINGP (XCDR (val)))
707 return Qnil; 698 return Qnil;
708 699
709 entity = Qnil; 700 if (INTEGERP (AREF (spec, FONT_SIZE_INDEX)))
710 pattern = FcNameParse (SDATA (XCDR (val)));
711 if (pattern)
712 { 701 {
713 if (INTEGERP (AREF (spec, FONT_SIZE_INDEX))) 702 FcValue value;
714 {
715 FcValue value;
716 703
717 value.type = FcTypeDouble; 704 value.type = FcTypeDouble;
718 value.u.d = XINT (AREF (spec, FONT_SIZE_INDEX)); 705 value.u.d = XINT (AREF (spec, FONT_SIZE_INDEX));
719 FcPatternAdd (pattern, FC_PIXEL_SIZE, value, FcFalse); 706 FcPatternAdd (pattern, FC_PIXEL_SIZE, value, FcFalse);
720 } 707 }
721 if (FcConfigSubstitute (NULL, pattern, FcMatchPattern) == FcTrue) 708 if (FcConfigSubstitute (NULL, pattern, FcMatchPattern) == FcTrue)
709 {
710 FcDefaultSubstitute (pattern);
711 match = FcFontMatch (NULL, pattern, &result);
712 if (match)
722 { 713 {
723 FcDefaultSubstitute (pattern); 714 entity = ftfont_pattern_entity (match, Qunicode_bmp);
724 match = FcFontMatch (NULL, pattern, &result); 715 FcPatternDestroy (match);
725 if (match) 716 if (! NILP (AREF (spec, FONT_FAMILY_INDEX))
726 { 717 && NILP (assq_no_quit (AREF (spec, FONT_FAMILY_INDEX),
727 entity = ftfont_pattern_entity (match, frame, Qunicode_bmp); 718 ftfont_generic_family_list))
728 FcPatternDestroy (match); 719 && NILP (Fstring_equal (AREF (spec, FONT_FAMILY_INDEX),
729 } 720 AREF (entity, FONT_FAMILY_INDEX))))
721 entity = Qnil;
730 } 722 }
731 FcPatternDestroy (pattern);
732 } 723 }
724 FcPatternDestroy (pattern);
733 725
734 return entity; 726 return entity;
735} 727}
@@ -767,8 +759,7 @@ ftfont_list_family (frame)
767 FcChar8 *str; 759 FcChar8 *str;
768 760
769 if (FcPatternGetString (pat, FC_FAMILY, 0, &str) == FcResultMatch) 761 if (FcPatternGetString (pat, FC_FAMILY, 0, &str) == FcResultMatch)
770 list = Fcons (intern_downcase ((char *) str, strlen ((char *) str)), 762 list = Fcons (intern ((char *) str), list);
771 list);
772 } 763 }
773 764
774 finish: 765 finish:
@@ -780,17 +771,7 @@ ftfont_list_family (frame)
780} 771}
781 772
782 773
783static void 774static Lisp_Object
784ftfont_free_entity (entity)
785 Lisp_Object entity;
786{
787 Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX);
788 FcPattern *pattern = XSAVE_VALUE (val)->pointer;
789
790 FcPatternDestroy (pattern);
791}
792
793static struct font *
794ftfont_open (f, entity, pixel_size) 775ftfont_open (f, entity, pixel_size)
795 FRAME_PTR f; 776 FRAME_PTR f;
796 Lisp_Object entity; 777 Lisp_Object entity;
@@ -801,42 +782,45 @@ ftfont_open (f, entity, pixel_size)
801 FT_Face ft_face; 782 FT_Face ft_face;
802 FT_Size ft_size; 783 FT_Size ft_size;
803 FT_UInt size; 784 FT_UInt size;
804 Lisp_Object val; 785 Lisp_Object val, font_object;
805 FcPattern *pattern; 786 FcPattern *pattern;
806 FcChar8 *file; 787 FcChar8 *file = NULL, *fmt = NULL;
788 FcBool scalable;
807 int spacing; 789 int spacing;
808 char *name; 790 char name[256];
809 int len; 791 int i, len;
792 int upEM;
810 793
811 val = AREF (entity, FONT_EXTRA_INDEX); 794 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
812 if (XTYPE (val) != Lisp_Misc 795 if (! CONSP (val))
813 || XMISCTYPE (val) != Lisp_Misc_Save_Value) 796 return Qnil;
814 return NULL; 797 val = XCDR (val);
815 pattern = XSAVE_VALUE (val)->pointer; 798 pattern = XSAVE_VALUE (val)->pointer;
816 if (XSAVE_VALUE (val)->integer == 0) 799 if (XSAVE_VALUE (val)->integer == 0)
817 { 800 {
818 /* We have not yet created FT_Face for this font. */ 801 /* We have not yet created FT_Face for this font. */
819 if (! ft_library 802 if (! ft_library
820 && FT_Init_FreeType (&ft_library) != 0) 803 && FT_Init_FreeType (&ft_library) != 0)
821 return NULL; 804 return Qnil;
822 if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch) 805 if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch)
823 return NULL; 806 return Qnil;
824 if (FT_New_Face (ft_library, (char *) file, 0, &ft_face) != 0) 807 if (FT_New_Face (ft_library, (char *) file, 0, &ft_face) != 0)
825 return NULL; 808 return Qnil;
826 FcPatternAddFTFace (pattern, FC_FT_FACE, ft_face); 809 FcPatternAddFTFace (pattern, FC_FT_FACE, ft_face);
827 ft_size = ft_face->size; 810 ft_size = ft_face->size;
811 XSAVE_VALUE (val)->integer++;
828 } 812 }
829 else 813 else
830 { 814 {
831 if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &ft_face) 815 if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &ft_face)
832 != FcResultMatch) 816 != FcResultMatch)
833 return NULL; 817 return Qnil;
834 if (FT_New_Size (ft_face, &ft_size) != 0) 818 if (FT_New_Size (ft_face, &ft_size) != 0)
835 return NULL; 819 return Qnil;
836 if (FT_Activate_Size (ft_size) != 0) 820 if (FT_Activate_Size (ft_size) != 0)
837 { 821 {
838 FT_Done_Size (ft_size); 822 FT_Done_Size (ft_size);
839 return NULL; 823 return Qnil;
840 } 824 }
841 } 825 }
842 826
@@ -847,84 +831,99 @@ ftfont_open (f, entity, pixel_size)
847 { 831 {
848 if (XSAVE_VALUE (val)->integer == 0) 832 if (XSAVE_VALUE (val)->integer == 0)
849 FT_Done_Face (ft_face); 833 FT_Done_Face (ft_face);
850 return NULL; 834 return Qnil;
851 } 835 }
852 836
853 ftfont_info = malloc (sizeof (struct ftfont_info)); 837 font_object = font_make_object (VECSIZE (struct ftfont_info));
854 if (! ftfont_info) 838 ASET (font_object, FONT_TYPE_INDEX, Qfreetype);
855 return NULL; 839 for (i = 1;i < FONT_ENTITY_MAX; i++)
840 ASET (font_object, i, AREF (entity, i));
841 ASET (font_object, FONT_SIZE_INDEX, make_number (size));
842 len = font_unparse_xlfd (entity, size, name, 256);
843 if (len > 0)
844 ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len));
845 len = font_unparse_fcname (entity, size, name, 256);
846 if (len > 0)
847 ASET (font_object, FONT_FULLNAME_INDEX, make_unibyte_string (name, len));
848 else
849 ASET (font_object, FONT_FULLNAME_INDEX,
850 AREF (font_object, FONT_NAME_INDEX));
851 if (! file
852 && ! FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch)
853 return Qnil;
854 ASET (font_object, FONT_FILE_INDEX,
855 make_unibyte_string ((char *) file, strlen ((char *) file)));
856 ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (pattern));
857 font = XFONT_OBJECT (font_object);
858 ftfont_info = (struct ftfont_info *) font;
856 ftfont_info->ft_size = ft_size; 859 ftfont_info->ft_size = ft_size;
857#ifdef HAVE_LIBOTF 860#ifdef HAVE_LIBOTF
858 ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT; 861 ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT;
859 ftfont_info->otf = NULL; 862 ftfont_info->otf = NULL;
860#endif /* HAVE_LIBOTF */ 863#endif /* HAVE_LIBOTF */
861
862 font = (struct font *) ftfont_info;
863 font->format = ftfont_font_format (pattern);
864 font->entity = entity;
865 font->pixel_size = size; 864 font->pixel_size = size;
866 font->driver = &ftfont_driver; 865 font->driver = &ftfont_driver;
867 len = 96; 866 font->encoding_charset = font->repertory_charset = -1;
868 name = malloc (len);
869 while (name && font_unparse_fcname (entity, pixel_size, name, len) < 0)
870 {
871 char *new = realloc (name, len += 32);
872 867
873 if (! new) 868 upEM = ft_face->units_per_EM;
874 free (name); 869 if (! FcPatternGetBool (pattern, FC_SCALABLE, 0, &scalable) == FcResultMatch)
875 name = new; 870 scalable = FcFalse;
871 if (scalable)
872 {
873 font->ascent = ft_face->ascender * size / upEM;
874 font->descent = - ft_face->descender * size / upEM;
875 font->height = ft_face->height * size / upEM;
876 }
877 else
878 {
879 font->ascent = ft_face->size->metrics.ascender >> 6;
880 font->descent = - ft_face->size->metrics.descender >> 6;
881 font->height = ft_face->size->metrics.height >> 6;
876 } 882 }
877 font->font.full_name = font->font.name = name;
878 font->file_name = (char *) file;
879 font->font.size = ft_face->size->metrics.max_advance >> 6;
880 if (font->font.size <= 0)
881 font->font.size = size;
882 font->font.charset = font->encoding_charset = font->repertory_charset = -1;
883 font->ascent = ft_face->size->metrics.ascender >> 6;
884 font->descent = - ft_face->size->metrics.descender >> 6;
885 font->font.height = font->ascent + font->descent;
886 if (FcPatternGetInteger (pattern, FC_SPACING, 0, &spacing) != FcResultMatch) 883 if (FcPatternGetInteger (pattern, FC_SPACING, 0, &spacing) != FcResultMatch)
887 spacing = FC_PROPORTIONAL; 884 spacing = FC_PROPORTIONAL;
888 if (spacing != FC_PROPORTIONAL) 885 if (spacing != FC_PROPORTIONAL)
889 font->font.average_width = font->font.space_width = font->font.size; 886 font->min_width = font->average_width = font->space_width
887 = (scalable ? ft_face->max_advance_width * size / upEM
888 : ft_face->size->metrics.max_advance >> 6);
890 else 889 else
891 { 890 {
892 int i; 891 int n;
893 892
894 font->font.average_width = font->font.space_width = 0; 893 font->min_width = font->average_width = font->space_width = 0;
895 for (i = 32; i < 127; i++) 894 for (i = 32, n = 0; i < 127; i++)
896 { 895 if (FT_Load_Char (ft_face, i, FT_LOAD_DEFAULT) != 0)
897 if (FT_Load_Char (ft_face, i, FT_LOAD_DEFAULT) != 0) 896 {
898 break; 897 int this_width = ft_face->glyph->metrics.horiAdvance >> 6;
899 if (i == 32) 898
900 font->font.space_width = ft_face->glyph->metrics.horiAdvance >> 6; 899 if (this_width > 0
901 font->font.average_width += ft_face->glyph->metrics.horiAdvance >> 6; 900 && (! font->min_width || font->min_width > this_width))
902 } 901 font->min_width = this_width;
903 if (i == 127) 902 if (i == 32)
904 { 903 font->space_width = this_width;
905 /* The font contains all ASCII printable characters. */ 904 font->average_width += this_width;
906 font->font.average_width /= 95; 905 n++;
907 } 906 }
908 else 907 if (n > 0)
909 { 908 font->average_width /= n;
910 if (i == 32)
911 font->font.space_width = font->font.size;
912 font->font.average_width = font->font.size;
913 }
914 } 909 }
915 910
916 /* Unfortunately FreeType doesn't provide a way to get minimum char 911 font->baseline_offset = 0;
917 width. So, we use space_width instead. */ 912 font->relative_compose = 0;
918 font->min_width = font->font.space_width; 913 font->default_ascent = 0;
919 914 font->vertical_centering = 0;
920 font->font.baseline_offset = 0; 915 if (scalable)
921 font->font.relative_compose = 0; 916 {
922 font->font.default_ascent = 0; 917 font->underline_position = -ft_face->underline_position * size / upEM;
923 font->font.vertical_centering = 0; 918 font->underline_thickness = -ft_face->underline_thickness * size / upEM;
924 919 }
925 (XSAVE_VALUE (val)->integer)++; 920 else
921 {
922 font->underline_position = -1;
923 font->underline_thickness = 0;
924 }
926 925
927 return font; 926 return font_object;
928} 927}
929 928
930static void 929static void
@@ -933,9 +932,10 @@ ftfont_close (f, font)
933 struct font *font; 932 struct font *font;
934{ 933{
935 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; 934 struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
936 Lisp_Object entity = font->entity; 935 Lisp_Object val;
937 Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX);
938 936
937 val = assq_no_quit (QCfont_entity, font->props[FONT_EXTRA_INDEX]);
938 val = XCDR (val);
939 (XSAVE_VALUE (val)->integer)--; 939 (XSAVE_VALUE (val)->integer)--;
940 if (XSAVE_VALUE (val)->integer == 0) 940 if (XSAVE_VALUE (val)->integer == 0)
941 { 941 {
@@ -947,8 +947,6 @@ ftfont_close (f, font)
947 } 947 }
948 else 948 else
949 FT_Done_Size (ftfont_info->ft_size); 949 FT_Done_Size (ftfont_info->ft_size);
950
951 free (font);
952} 950}
953 951
954static int 952static int
@@ -960,7 +958,8 @@ ftfont_has_char (entity, c)
960 FcPattern *pattern; 958 FcPattern *pattern;
961 FcCharSet *charset; 959 FcCharSet *charset;
962 960
963 val = AREF (entity, FONT_EXTRA_INDEX); 961 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
962 val = XCDR (val);
964 pattern = XSAVE_VALUE (val)->pointer; 963 pattern = XSAVE_VALUE (val)->pointer;
965 if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch) 964 if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch)
966 return -1; 965 return -1;
@@ -1019,7 +1018,7 @@ ftfont_text_extents (font, code, nglyphs, metrics)
1019 } 1018 }
1020 else 1019 else
1021 { 1020 {
1022 width += font->font.space_width; 1021 width += font->space_width;
1023 } 1022 }
1024 } 1023 }
1025 if (metrics) 1024 if (metrics)
@@ -1161,7 +1160,7 @@ ftfont_get_metrics (font, gstring, from, to)
1161 else 1160 else
1162 { 1161 {
1163 g->lbearing = 0; 1162 g->lbearing = 0;
1164 g->rbearing = g->xadv = flt_font_ft->font->font.space_width << 6; 1163 g->rbearing = g->xadv = flt_font_ft->font->space_width << 6;
1165 g->ascent = flt_font_ft->font->ascent << 6; 1164 g->ascent = flt_font_ft->font->ascent << 6;
1166 g->descent = flt_font_ft->font->descent << 6; 1165 g->descent = flt_font_ft->font->descent << 6;
1167 } 1166 }