diff options
| author | Kenichi Handa | 2009-05-08 06:05:38 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2009-05-08 06:05:38 +0000 |
| commit | 92f192809352574cac652b437c0d4467aa06fb6c (patch) | |
| tree | 61134010bf837eadca09386abde7364e4082913b /src | |
| parent | 3909e3a33227a144215e29ab3b64c63cac290aac (diff) | |
| download | emacs-92f192809352574cac652b437c0d4467aa06fb6c.tar.gz emacs-92f192809352574cac652b437c0d4467aa06fb6c.zip | |
(xfont_check_char_support)
(xfont_check_registry_char_support): New functions.
(xfont_list_pattern): Delete unused arg FRAME, add arg CHARS.
Callers adjusted.
(xfont_list): Handle :script property.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/xfont.c | 174 |
2 files changed, 164 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 779f0d99645..61e3420cb32 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2009-05-08 Kenichi Handa <handa@m17n.org> | ||
| 2 | |||
| 3 | * xfont.c (xfont_check_char_support) | ||
| 4 | (xfont_check_registry_char_support): New functions. | ||
| 5 | (xfont_list_pattern): Delete unused arg FRAME, add arg CHARS. | ||
| 6 | Callers adjusted. | ||
| 7 | (xfont_list): Handle :script property. | ||
| 8 | |||
| 1 | 2009-05-07 David Reitter <david.reitter@gmail.com> | 9 | 2009-05-07 David Reitter <david.reitter@gmail.com> |
| 2 | 10 | ||
| 3 | * nsterm.m (ns_dumpglyphs_stretch,ns_dumpglyphs_image): | 11 | * nsterm.m (ns_dumpglyphs_stretch,ns_dumpglyphs_image): |
diff --git a/src/xfont.c b/src/xfont.c index afafca89c24..987c2ddc210 100644 --- a/src/xfont.c +++ b/src/xfont.c | |||
| @@ -256,13 +256,129 @@ xfont_encode_coding_xlfd (char *xlfd) | |||
| 256 | return len; | 256 | return len; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | static Lisp_Object xfont_list_pattern P_ ((Lisp_Object, Display *, char *)); | 259 | /* Check if XFONT supports CHARS (cons or vector of characters). If |
| 260 | yes, return 1. If no, return 0. */ | ||
| 261 | |||
| 262 | static int xfont_check_char_support P_ ((XFontStruct *, Lisp_Object)); | ||
| 263 | |||
| 264 | static int | ||
| 265 | xfont_check_char_support (xfont, chars) | ||
| 266 | XFontStruct *xfont; | ||
| 267 | Lisp_Object chars; | ||
| 268 | { | ||
| 269 | if (CONSP (chars)) | ||
| 270 | { | ||
| 271 | Lisp_Object tail = chars; | ||
| 272 | |||
| 273 | while (CONSP (tail)) | ||
| 274 | { | ||
| 275 | int c = XINT (XCAR (chars)); | ||
| 276 | XChar2b char2b; | ||
| 277 | char2b.byte1 = c >> 16; | ||
| 278 | char2b.byte2 = c & 0xFF; | ||
| 279 | if (! xfont_get_pcm (xfont, &char2b)) | ||
| 280 | return 0; | ||
| 281 | } | ||
| 282 | return 1; | ||
| 283 | } | ||
| 284 | if (VECTORP (chars)) | ||
| 285 | { | ||
| 286 | int i; | ||
| 287 | |||
| 288 | for (i = ASIZE (chars) - 1; i >= 0; i--) | ||
| 289 | { | ||
| 290 | int c = XINT (AREF (chars, i)); | ||
| 291 | XChar2b char2b; | ||
| 292 | char2b.byte1 = c >> 16; | ||
| 293 | char2b.byte2 = c & 0xFF; | ||
| 294 | if (xfont_get_pcm (xfont, &char2b)) | ||
| 295 | return 1; | ||
| 296 | } | ||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | return 0; | ||
| 300 | } | ||
| 301 | |||
| 302 | |||
| 303 | /* Check if a repertory charset correponding to REGISTRY supports | ||
| 304 | CHARS (cons or vector of characters). If yes, return Qt. If no, | ||
| 305 | return Qnil. If not decidable by REGISTRY, return a copy of CHARS | ||
| 306 | but with elements changed to glyph codes. */ | ||
| 307 | |||
| 308 | static Lisp_Object xfont_check_registry_char_support P_ ((Lisp_Object, | ||
| 309 | Lisp_Object)); | ||
| 260 | 310 | ||
| 261 | static Lisp_Object | 311 | static Lisp_Object |
| 262 | xfont_list_pattern (frame, display, pattern) | 312 | xfont_check_registry_char_support (registry, chars) |
| 263 | Lisp_Object frame; | 313 | Lisp_Object registry, chars; |
| 314 | { | ||
| 315 | struct charset *encoding, *repertory, *charset; | ||
| 316 | |||
| 317 | if (font_registry_charsets (registry, &encoding, &repertory) < 0) | ||
| 318 | return Qnil; | ||
| 319 | if (! repertory) | ||
| 320 | chars = Fcopy_sequence (chars); | ||
| 321 | charset = repertory ? repertory : encoding; | ||
| 322 | if (CONSP (chars)) | ||
| 323 | { | ||
| 324 | Lisp_Object tail = chars; | ||
| 325 | |||
| 326 | while (CONSP (tail)) | ||
| 327 | { | ||
| 328 | int c, code; | ||
| 329 | |||
| 330 | if (! INTEGERP (XCAR (tail))) | ||
| 331 | return Qnil; | ||
| 332 | c = XINT (XCAR (tail)); | ||
| 333 | code = ENCODE_CHAR (charset, c); | ||
| 334 | if (code == CHARSET_INVALID_CODE (charset)) | ||
| 335 | return Qnil; | ||
| 336 | if (! repertory) | ||
| 337 | XSETCAR (tail, make_number (code)); | ||
| 338 | } | ||
| 339 | return repertory ? Qt : chars; | ||
| 340 | } | ||
| 341 | if (VECTORP (chars)) | ||
| 342 | { | ||
| 343 | int i; | ||
| 344 | |||
| 345 | for (i = ASIZE (chars) - 1; i >= 0; i--) | ||
| 346 | { | ||
| 347 | int c, code; | ||
| 348 | |||
| 349 | if (! INTEGERP (AREF (chars, i))) | ||
| 350 | return Qnil; | ||
| 351 | c = XINT (AREF (chars, i)); | ||
| 352 | code = ENCODE_CHAR (charset, c); | ||
| 353 | |||
| 354 | if (code == CHARSET_INVALID_CODE (charset)) | ||
| 355 | { | ||
| 356 | if (! repertory) | ||
| 357 | return Qnil; | ||
| 358 | } | ||
| 359 | else | ||
| 360 | { | ||
| 361 | if (repertory) | ||
| 362 | return Qt; | ||
| 363 | ASET (chars, i, make_number (code)); | ||
| 364 | } | ||
| 365 | } | ||
| 366 | return repertory ? Qnil : chars; | ||
| 367 | } | ||
| 368 | return Qnil; | ||
| 369 | } | ||
| 370 | |||
| 371 | static Lisp_Object xfont_list_pattern P_ ((Display *, char *, Lisp_Object)); | ||
| 372 | |||
| 373 | /* Return a list of font-entities matching with PATTERN available on | ||
| 374 | DISPLAY. If CHARS is non-nil, exclude fonts not supporting | ||
| 375 | CHARS. */ | ||
| 376 | |||
| 377 | static Lisp_Object | ||
| 378 | xfont_list_pattern (display, pattern, chars) | ||
| 264 | Display *display; | 379 | Display *display; |
| 265 | char *pattern; | 380 | char *pattern; |
| 381 | Lisp_Object chars; | ||
| 266 | { | 382 | { |
| 267 | Lisp_Object list = Qnil; | 383 | Lisp_Object list = Qnil; |
| 268 | int i, limit, num_fonts; | 384 | int i, limit, num_fonts; |
| @@ -301,11 +417,21 @@ xfont_list_pattern (frame, display, pattern) | |||
| 301 | { | 417 | { |
| 302 | Lisp_Object entity; | 418 | Lisp_Object entity; |
| 303 | int result; | 419 | int result; |
| 304 | char *p; | 420 | XFontStruct *font = NULL; |
| 305 | 421 | ||
| 306 | if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0) | 422 | if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0) |
| 307 | continue; | 423 | continue; |
| 308 | 424 | if (! NILP (chars)) | |
| 425 | { | ||
| 426 | font = XLoadQueryFont (display, indices[i]); | ||
| 427 | if (! font) | ||
| 428 | continue; | ||
| 429 | if (! xfont_check_char_support (font, chars)) | ||
| 430 | { | ||
| 431 | XFreeFont (display, font); | ||
| 432 | continue; | ||
| 433 | } | ||
| 434 | } | ||
| 309 | entity = font_make_entity (); | 435 | entity = font_make_entity (); |
| 310 | ASET (entity, FONT_TYPE_INDEX, Qx); | 436 | ASET (entity, FONT_TYPE_INDEX, Qx); |
| 311 | xfont_decode_coding_xlfd (indices[i], -1, buf); | 437 | xfont_decode_coding_xlfd (indices[i], -1, buf); |
| @@ -314,10 +440,11 @@ xfont_list_pattern (frame, display, pattern) | |||
| 314 | { | 440 | { |
| 315 | /* This may be an alias name. Try to get the full XLFD name | 441 | /* This may be an alias name. Try to get the full XLFD name |
| 316 | from XA_FONT property of the font. */ | 442 | from XA_FONT property of the font. */ |
| 317 | XFontStruct *font = XLoadQueryFont (display, indices[i]); | ||
| 318 | unsigned long value; | 443 | unsigned long value; |
| 319 | 444 | ||
| 320 | if (! font) | 445 | if (! font) |
| 446 | font = XLoadQueryFont (display, indices[i]); | ||
| 447 | if (! font) | ||
| 321 | continue; | 448 | continue; |
| 322 | if (XGetFontProperty (font, XA_FONT, &value)) | 449 | if (XGetFontProperty (font, XA_FONT, &value)) |
| 323 | { | 450 | { |
| @@ -334,9 +461,10 @@ xfont_list_pattern (frame, display, pattern) | |||
| 334 | } | 461 | } |
| 335 | XFree (name); | 462 | XFree (name); |
| 336 | } | 463 | } |
| 337 | XFreeFont (display, font); | ||
| 338 | } | 464 | } |
| 339 | 465 | ||
| 466 | if (font) | ||
| 467 | XFreeFont (display, font); | ||
| 340 | if (result == 0 | 468 | if (result == 0 |
| 341 | /* Avoid auto-scaled fonts. */ | 469 | /* Avoid auto-scaled fonts. */ |
| 342 | && (XINT (AREF (entity, FONT_DPI_INDEX)) == 0 | 470 | && (XINT (AREF (entity, FONT_DPI_INDEX)) == 0 |
| @@ -359,7 +487,7 @@ xfont_list (frame, spec) | |||
| 359 | { | 487 | { |
| 360 | FRAME_PTR f = XFRAME (frame); | 488 | FRAME_PTR f = XFRAME (frame); |
| 361 | Display *display = FRAME_X_DISPLAY_INFO (f)->display; | 489 | Display *display = FRAME_X_DISPLAY_INFO (f)->display; |
| 362 | Lisp_Object registry, list, val, extra; | 490 | Lisp_Object registry, list, val, extra, chars; |
| 363 | int len; | 491 | int len; |
| 364 | /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */ | 492 | /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */ |
| 365 | char name[512]; | 493 | char name[512]; |
| @@ -370,20 +498,32 @@ xfont_list (frame, spec) | |||
| 370 | val = assq_no_quit (QCotf, extra); | 498 | val = assq_no_quit (QCotf, extra); |
| 371 | if (! NILP (val)) | 499 | if (! NILP (val)) |
| 372 | return Qnil; | 500 | return Qnil; |
| 373 | val = assq_no_quit (QCscript, extra); | ||
| 374 | if (! NILP (val)) | ||
| 375 | return Qnil; | ||
| 376 | val = assq_no_quit (QClang, extra); | 501 | val = assq_no_quit (QClang, extra); |
| 377 | if (! NILP (val)) | 502 | if (! NILP (val)) |
| 378 | return Qnil; | 503 | return Qnil; |
| 379 | } | 504 | } |
| 380 | |||
| 381 | registry = AREF (spec, FONT_REGISTRY_INDEX); | 505 | registry = AREF (spec, FONT_REGISTRY_INDEX); |
| 382 | len = font_unparse_xlfd (spec, 0, name, 512); | 506 | len = font_unparse_xlfd (spec, 0, name, 512); |
| 383 | if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0) | 507 | if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0) |
| 384 | return Qnil; | 508 | return Qnil; |
| 509 | val = assq_no_quit (QCscript, extra); | ||
| 510 | if (NILP (val)) | ||
| 511 | chars = Qnil; | ||
| 512 | else | ||
| 513 | { | ||
| 514 | chars = assq_no_quit (XCDR (val), Vscript_representative_chars); | ||
| 515 | if (! NILP (chars) && ! NILP (registry)) | ||
| 516 | { | ||
| 517 | chars = xfont_check_registry_char_support (registry, XCDR (chars)); | ||
| 518 | if (NILP (chars)) | ||
| 519 | return Qnil; | ||
| 520 | if (EQ (chars, Qt)) | ||
| 521 | chars = Qnil; | ||
| 522 | } | ||
| 523 | } | ||
| 524 | |||
| 385 | ASET (spec, FONT_REGISTRY_INDEX, registry); | 525 | ASET (spec, FONT_REGISTRY_INDEX, registry); |
| 386 | list = xfont_list_pattern (frame, display, name); | 526 | list = xfont_list_pattern (display, name, chars); |
| 387 | if (NILP (list) && NILP (registry)) | 527 | if (NILP (list) && NILP (registry)) |
| 388 | { | 528 | { |
| 389 | /* Try iso10646-1 */ | 529 | /* Try iso10646-1 */ |
| @@ -392,7 +532,7 @@ xfont_list (frame, spec) | |||
| 392 | if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */ | 532 | if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */ |
| 393 | { | 533 | { |
| 394 | strcpy (r, "iso10646-1"); | 534 | strcpy (r, "iso10646-1"); |
| 395 | list = xfont_list_pattern (frame, display, name); | 535 | list = xfont_list_pattern (display, name, chars); |
| 396 | } | 536 | } |
| 397 | } | 537 | } |
| 398 | if (NILP (list) && ! NILP (registry)) | 538 | if (NILP (list) && ! NILP (registry)) |
| @@ -412,7 +552,7 @@ xfont_list (frame, spec) | |||
| 412 | && ((r - name) + SBYTES (XCAR (alter))) < 256) | 552 | && ((r - name) + SBYTES (XCAR (alter))) < 256) |
| 413 | { | 553 | { |
| 414 | strcpy (r, (char *) SDATA (XCAR (alter))); | 554 | strcpy (r, (char *) SDATA (XCAR (alter))); |
| 415 | list = xfont_list_pattern (frame, display, name); | 555 | list = xfont_list_pattern (display, name, chars); |
| 416 | if (! NILP (list)) | 556 | if (! NILP (list)) |
| 417 | break; | 557 | break; |
| 418 | } | 558 | } |
| @@ -427,10 +567,9 @@ xfont_list (frame, spec) | |||
| 427 | bcopy (SDATA (XCDR (val)), name, SBYTES (XCDR (val)) + 1); | 567 | bcopy (SDATA (XCDR (val)), name, SBYTES (XCDR (val)) + 1); |
| 428 | if (xfont_encode_coding_xlfd (name) < 0) | 568 | if (xfont_encode_coding_xlfd (name) < 0) |
| 429 | return Qnil; | 569 | return Qnil; |
| 430 | list = xfont_list_pattern (frame, display, name); | 570 | list = xfont_list_pattern (display, name, chars); |
| 431 | } | 571 | } |
| 432 | } | 572 | } |
| 433 | |||
| 434 | return list; | 573 | return list; |
| 435 | } | 574 | } |
| 436 | 575 | ||
| @@ -569,7 +708,6 @@ xfont_open (f, entity, pixel_size) | |||
| 569 | Lisp_Object font_object, fullname; | 708 | Lisp_Object font_object, fullname; |
| 570 | struct font *font; | 709 | struct font *font; |
| 571 | XFontStruct *xfont; | 710 | XFontStruct *xfont; |
| 572 | int i; | ||
| 573 | 711 | ||
| 574 | /* At first, check if we know how to encode characters for this | 712 | /* At first, check if we know how to encode characters for this |
| 575 | font. */ | 713 | font. */ |