diff options
| author | Kenichi Handa | 2006-06-28 05:41:21 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2006-06-28 05:41:21 +0000 |
| commit | 6c4aeab695a87a47ed87b3d9933a9a4634c8f39a (patch) | |
| tree | fffffadc530062003b302c1c86b8e8300eea3edb /src | |
| parent | bc9a2afe6f7306e2240033ad64955d4d560f5b5c (diff) | |
| download | emacs-6c4aeab695a87a47ed87b3d9933a9a4634c8f39a.tar.gz emacs-6c4aeab695a87a47ed87b3d9933a9a4634c8f39a.zip | |
(xfont_query_font): Adjusted for the change of
font_parse_xlfd.
(xfont_list_pattern): New function.
(xfont_list): Use xfont_list_pattern.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfont.c | 233 |
1 files changed, 114 insertions, 119 deletions
diff --git a/src/xfont.c b/src/xfont.c index de27f996a5f..ac60b96bb5f 100644 --- a/src/xfont.c +++ b/src/xfont.c | |||
| @@ -92,7 +92,7 @@ xfont_query_font (display, name, spec) | |||
| 92 | { | 92 | { |
| 93 | char *n = (char *) XGetAtomName (display, (Atom) value); | 93 | char *n = (char *) XGetAtomName (display, (Atom) value); |
| 94 | 94 | ||
| 95 | if (font_parse_xlfd (n, spec, 0) >= 0) | 95 | if (font_parse_xlfd (n, spec) >= 0) |
| 96 | name = n; | 96 | name = n; |
| 97 | else | 97 | else |
| 98 | XFree (n); | 98 | XFree (n); |
| @@ -283,158 +283,153 @@ xfont_get_cache (frame) | |||
| 283 | extern Lisp_Object Vface_alternative_font_registry_alist; | 283 | extern Lisp_Object Vface_alternative_font_registry_alist; |
| 284 | 284 | ||
| 285 | static Lisp_Object | 285 | static Lisp_Object |
| 286 | xfont_list (frame, spec) | 286 | xfont_list_pattern (frame, display, pattern) |
| 287 | Lisp_Object frame, spec; | 287 | Lisp_Object frame; |
| 288 | Display *display; | ||
| 289 | char *pattern; | ||
| 288 | { | 290 | { |
| 289 | FRAME_PTR f = XFRAME (frame); | 291 | Lisp_Object list = Qnil; |
| 290 | Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | 292 | int i, limit, num_fonts; |
| 291 | Lisp_Object *vec, val, extra, font_name, entity; | 293 | char **names; |
| 292 | char name[256], **names; | ||
| 293 | int i, idx, limit, num_fonts; | ||
| 294 | int error_occurred = 0; | ||
| 295 | USE_SAFE_ALLOCA; | ||
| 296 | |||
| 297 | extra = AREF (spec, FONT_EXTRA_INDEX); | ||
| 298 | font_name = Qnil; | ||
| 299 | if (CONSP (extra)) | ||
| 300 | { | ||
| 301 | val = Fassq (QCotf, extra); | ||
| 302 | if (! NILP (val)) | ||
| 303 | return null_vector; | ||
| 304 | val = Fassq (QCscript, extra); | ||
| 305 | if (! NILP (val)) | ||
| 306 | return null_vector; | ||
| 307 | val = Fassq (QCname, extra); | ||
| 308 | if (CONSP (val)) | ||
| 309 | font_name = XCDR (val); | ||
| 310 | } | ||
| 311 | |||
| 312 | if (! STRINGP (font_name) | ||
| 313 | && font_unparse_xlfd (spec, 0, name, 256) < 0) | ||
| 314 | return null_vector; | ||
| 315 | 294 | ||
| 316 | BLOCK_INPUT; | 295 | BLOCK_INPUT; |
| 317 | x_catch_errors (dpyinfo->display); | 296 | x_catch_errors (display); |
| 318 | 297 | ||
| 319 | if (STRINGP (font_name)) | 298 | for (limit = 512; ; limit *= 2) |
| 320 | { | 299 | { |
| 321 | XFontStruct *font = XLoadQueryFont (dpyinfo->display, | 300 | names = XListFonts (display, pattern, limit, &num_fonts); |
| 322 | (char *) SDATA (font_name)); | 301 | if (x_had_errors_p (display)) |
| 323 | unsigned long value; | ||
| 324 | |||
| 325 | num_fonts = 0; | ||
| 326 | if (x_had_errors_p (dpyinfo->display)) | ||
| 327 | { | 302 | { |
| 328 | /* This error is perhaps due to insufficient memory on X | 303 | /* This error is perhaps due to insufficient memory on X |
| 329 | server. Let's just ignore it. */ | 304 | server. Let's just ignore it. */ |
| 330 | font = NULL; | 305 | x_clear_errors (display); |
| 331 | error_occurred = 1; | 306 | num_fonts = 0; |
| 332 | x_clear_errors (dpyinfo->display); | 307 | break; |
| 333 | } | 308 | } |
| 334 | if (font) | 309 | if (num_fonts < limit) |
| 310 | break; | ||
| 311 | XFreeFontNames (names); | ||
| 312 | } | ||
| 313 | |||
| 314 | for (i = 0; i < num_fonts; i++) | ||
| 315 | { | ||
| 316 | Lisp_Object entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil); | ||
| 317 | int result; | ||
| 318 | |||
| 319 | ASET (entity, FONT_TYPE_INDEX, Qx); | ||
| 320 | ASET (entity, FONT_FRAME_INDEX, frame); | ||
| 321 | |||
| 322 | result = font_parse_xlfd (names[i], entity); | ||
| 323 | if (result < 0) | ||
| 335 | { | 324 | { |
| 325 | /* This may be an alias name. Try to get the full XLFD name | ||
| 326 | from XA_FONT property of the font. */ | ||
| 327 | XFontStruct *font = XLoadQueryFont (display, names[i]); | ||
| 328 | unsigned long value; | ||
| 329 | |||
| 330 | if (! font) | ||
| 331 | continue; | ||
| 336 | if (XGetFontProperty (font, XA_FONT, &value)) | 332 | if (XGetFontProperty (font, XA_FONT, &value)) |
| 337 | { | 333 | { |
| 338 | char *n = (char *) XGetAtomName (dpyinfo->display, (Atom) value); | 334 | char *name = (char *) XGetAtomName (display, (Atom) value); |
| 339 | int len = strlen (n); | 335 | int len = strlen (name); |
| 340 | char *tmp; | ||
| 341 | 336 | ||
| 342 | /* If DXPC (a Differential X Protocol Compressor) | 337 | /* If DXPC (a Differential X Protocol Compressor) |
| 343 | Ver.3.7 is running, XGetAtomName will return null | 338 | Ver.3.7 is running, XGetAtomName will return null |
| 344 | string. We must avoid such a name. */ | 339 | string. We must avoid such a name. */ |
| 345 | if (len > 0) | 340 | if (len > 0) |
| 346 | { | 341 | result = font_parse_xlfd (name, entity); |
| 347 | num_fonts = 1; | 342 | XFree (name); |
| 348 | names = (char **) alloca (sizeof (char *)); | ||
| 349 | /* Some systems only allow alloca assigned to a | ||
| 350 | simple var. */ | ||
| 351 | tmp = (char *) alloca (len + 1); names[0] = tmp; | ||
| 352 | bcopy (n, names[0], len + 1); | ||
| 353 | } | ||
| 354 | XFree (n); | ||
| 355 | } | 343 | } |
| 356 | XFreeFont (dpyinfo->display, font); | 344 | XFreeFont (display, font); |
| 357 | } | 345 | } |
| 358 | } | 346 | |
| 359 | else | 347 | if (result == 0) |
| 360 | { | ||
| 361 | Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX); | ||
| 362 | Lisp_Object alter = Qnil; | ||
| 363 | char *r = NULL; | ||
| 364 | |||
| 365 | if (! NILP (registry)) | ||
| 366 | alter = Fassoc_string (SYMBOL_NAME (registry), | ||
| 367 | Vface_alternative_font_registry_alist); | ||
| 368 | while (1) | ||
| 369 | { | 348 | { |
| 370 | for (limit = 512, num_fonts = 0; ; limit *= 2) | 349 | Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX); |
| 371 | { | 350 | char *p = (char *) SDATA (SYMBOL_NAME (val)); |
| 372 | names = XListFonts (dpyinfo->display, name, limit, &num_fonts); | 351 | |
| 373 | if (x_had_errors_p (dpyinfo->display)) | 352 | /* P == "RESX-RESY-SPACING-AVGWIDTH. We rejust this font if |
| 374 | { | 353 | it's an autoscaled one (i.e. RESX > 0 && AVGWIDTH == 0). */ |
| 375 | /* This error is perhaps due to insufficient memory | 354 | if (atoi (p) > 0) |
| 376 | on X server. Let's just ignore it. */ | ||
| 377 | x_clear_errors (dpyinfo->display); | ||
| 378 | error_occurred = 1; | ||
| 379 | num_fonts = 0; | ||
| 380 | break; | ||
| 381 | } | ||
| 382 | if (num_fonts < limit) | ||
| 383 | break; | ||
| 384 | XFreeFontNames (names); | ||
| 385 | } | ||
| 386 | if (num_fonts > 0 | ||
| 387 | || NILP (alter)) | ||
| 388 | break; | ||
| 389 | |||
| 390 | /* Setup for trying alternatives. */ | ||
| 391 | if (! r | ||
| 392 | && ! (r = strstr (name, (char *) SDATA (SYMBOL_NAME (registry))))) | ||
| 393 | abort (); | ||
| 394 | while (1) | ||
| 395 | { | 355 | { |
| 396 | registry = Qnil; | 356 | p += SBYTES (SYMBOL_NAME (val)); |
| 397 | alter = XCDR (alter); | 357 | while (p[-1] != '-') p--; |
| 398 | if (NILP (alter)) | 358 | if (atoi (p) == 0) |
| 399 | break; | 359 | continue; |
| 400 | registry = XCAR (alter); | ||
| 401 | if ((r - name) + SBYTES (registry) < 255) | ||
| 402 | break; | ||
| 403 | } | 360 | } |
| 404 | if (NILP (registry)) | 361 | list = Fcons (entity, list); |
| 405 | break; | ||
| 406 | bcopy (SDATA (registry), r, SBYTES (registry)); | ||
| 407 | } | 362 | } |
| 408 | } | 363 | } |
| 409 | 364 | ||
| 410 | x_uncatch_errors (); | 365 | x_uncatch_errors (); |
| 411 | UNBLOCK_INPUT; | 366 | UNBLOCK_INPUT; |
| 412 | 367 | ||
| 413 | if (error_occurred) | 368 | return list; |
| 414 | return Qnil; | 369 | } |
| 415 | if (num_fonts == 0) | ||
| 416 | return null_vector; | ||
| 417 | |||
| 418 | entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil); | ||
| 419 | ASET (entity, FONT_TYPE_INDEX, Qx); | ||
| 420 | ASET (entity, FONT_FRAME_INDEX, frame); | ||
| 421 | 370 | ||
| 422 | SAFE_ALLOCA_LISP (vec, num_fonts); | 371 | static Lisp_Object |
| 423 | for (i = idx = 0; i < num_fonts; i++) | 372 | xfont_list (frame, spec) |
| 373 | Lisp_Object frame, spec; | ||
| 374 | { | ||
| 375 | FRAME_PTR f = XFRAME (frame); | ||
| 376 | Display *display = FRAME_X_DISPLAY_INFO (f)->display; | ||
| 377 | Lisp_Object list, val, extra, font_name; | ||
| 378 | int len; | ||
| 379 | char name[256]; | ||
| 380 | |||
| 381 | extra = AREF (spec, FONT_EXTRA_INDEX); | ||
| 382 | font_name = Qnil; | ||
| 383 | if (CONSP (extra)) | ||
| 424 | { | 384 | { |
| 425 | if (font_parse_xlfd (names[i], entity, 0) > 0) | 385 | val = assq_no_quit (QCotf, extra); |
| 426 | vec[idx++] = Fcopy_sequence (entity); | 386 | if (! NILP (val)) |
| 387 | return null_vector; | ||
| 388 | val = assq_no_quit (QCscript, extra); | ||
| 389 | if (! NILP (val)) | ||
| 390 | return null_vector; | ||
| 391 | val = assq_no_quit (QClanguage, extra); | ||
| 392 | if (! NILP (val)) | ||
| 393 | return null_vector; | ||
| 394 | val = assq_no_quit (QCname, extra); | ||
| 395 | if (CONSP (val)) | ||
| 396 | font_name = XCDR (val); | ||
| 427 | } | 397 | } |
| 428 | if (! STRINGP (font_name)) | 398 | |
| 399 | if (STRINGP (font_name)) | ||
| 400 | list = xfont_list_pattern (frame, display, (char *) SDATA (font_name)); | ||
| 401 | else if ((len = font_unparse_xlfd (spec, 0, name, 256)) < 0) | ||
| 402 | return null_vector; | ||
| 403 | else | ||
| 429 | { | 404 | { |
| 430 | BLOCK_INPUT; | 405 | list = xfont_list_pattern (frame, display, name); |
| 431 | XFreeFontNames (names); | 406 | if (NILP (list)) |
| 432 | UNBLOCK_INPUT; | 407 | { |
| 408 | Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX); | ||
| 409 | Lisp_Object alter; | ||
| 410 | |||
| 411 | if (! NILP (registry) | ||
| 412 | && (alter = Fassoc (SYMBOL_NAME (registry), | ||
| 413 | Vface_alternative_font_registry_alist)) | ||
| 414 | && CONSP (alter)) | ||
| 415 | { | ||
| 416 | /* Pointer to REGISTRY-ENCODING field. */ | ||
| 417 | char *r = name + len - SBYTES (SYMBOL_NAME (registry)); | ||
| 418 | |||
| 419 | for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter)) | ||
| 420 | if (STRINGP (XCAR (alter)) | ||
| 421 | && ((r - name) + SBYTES (XCAR (alter))) < 255) | ||
| 422 | { | ||
| 423 | strcpy (r, (char *) SDATA (XCAR (alter))); | ||
| 424 | list = xfont_list_pattern (frame, display, name); | ||
| 425 | if (! NILP (list)) | ||
| 426 | break; | ||
| 427 | } | ||
| 428 | } | ||
| 429 | } | ||
| 433 | } | 430 | } |
| 434 | val = Fvector (idx, vec); | ||
| 435 | SAFE_FREE (); | ||
| 436 | 431 | ||
| 437 | return val; | 432 | return (NILP (list) ? null_vector : Fvconcat (1, &list)); |
| 438 | } | 433 | } |
| 439 | 434 | ||
| 440 | static int | 435 | static int |