aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2008-07-09 00:29:03 +0000
committerKenichi Handa2008-07-09 00:29:03 +0000
commit41ad6003ce046bfeacc1813ab87c6202a7d3f855 (patch)
treec11d93790d14b784fb9278488859567dbe1ccced /src
parent45cebfd9b4a33d69c2bd7108059c728ef6507c75 (diff)
downloademacs-41ad6003ce046bfeacc1813ab87c6202a7d3f855.tar.gz
emacs-41ad6003ce046bfeacc1813ab87c6202a7d3f855.zip
(fontset_compare_rfontdef): Fix plus/minus.
(reorder_font_vector): Change the arg preferred_family to font. Prefer the spec matching with font. (fontset_get_font_group): New function. (fontset_find_font): Change the format of an element of a realized fontset. Use fontset_get_font_group. (fontset_font): Try the current fontset, the default fontset, the fallbacks of the current fonset, and the fallbacks of the default fontset in this order. (face_for_char): Delete the shortcut to use the current font. (fontset_from_font): Don't set fonts for Latin in the fontset.
Diffstat (limited to 'src')
-rw-r--r--src/fontset.c318
1 files changed, 150 insertions, 168 deletions
diff --git a/src/fontset.c b/src/fontset.c
index 2809fdfb5eb..5dbbadbe042 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -208,7 +208,7 @@ static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
208 Lisp_Object)); 208 Lisp_Object));
209static Lisp_Object fontset_find_font P_ ((Lisp_Object, int, struct face *, 209static Lisp_Object fontset_find_font P_ ((Lisp_Object, int, struct face *,
210 int, int)); 210 int, int));
211static void reorder_font_vector P_ ((Lisp_Object, Lisp_Object)); 211static void reorder_font_vector P_ ((Lisp_Object, struct font *));
212static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int)); 212static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int));
213static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); 213static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
214static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); 214static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
@@ -377,8 +377,8 @@ static int
377fontset_compare_rfontdef (val1, val2) 377fontset_compare_rfontdef (val1, val2)
378 const void *val1, *val2; 378 const void *val1, *val2;
379{ 379{
380 return (RFONT_DEF_SCORE (*(Lisp_Object *) val2) 380 return (RFONT_DEF_SCORE (*(Lisp_Object *) val1)
381 - RFONT_DEF_SCORE (*(Lisp_Object *) val1)); 381 - RFONT_DEF_SCORE (*(Lisp_Object *) val2));
382} 382}
383 383
384/* Update FONT-GROUP which has this form: 384/* Update FONT-GROUP which has this form:
@@ -393,54 +393,57 @@ fontset_compare_rfontdef (val1, val2)
393extern Lisp_Object Fassoc_string (); 393extern Lisp_Object Fassoc_string ();
394 394
395static void 395static void
396reorder_font_vector (font_group, preferred_family) 396reorder_font_vector (font_group, font)
397 Lisp_Object font_group; 397 Lisp_Object font_group;
398 Lisp_Object preferred_family; 398 struct font *font;
399{ 399{
400 Lisp_Object vec, font_object;
400 int size; 401 int size;
401 int i; 402 int i;
402 int score_changed = 0; 403 int score_changed = 0;
403 404
404 size = ASIZE (font_group); 405 if (font)
405 /* Exclude the tailing nil elements from the reordering. */ 406 XSETFONT (font_object, font);
406 while (NILP (AREF (font_group, size - 1))) size--; 407 else
407 size -= 2; 408 font_object = Qnil;
409
410 vec = XCDR (font_group);
411 size = ASIZE (vec);
412 /* Exclude the tailing nil element from the reordering. */
413 if (NILP (AREF (vec, size - 1)))
414 size--;
408 415
409 for (i = 0; i < size; i++) 416 for (i = 0; i < size; i++)
410 { 417 {
411 Lisp_Object rfont_def = AREF (font_group, i + 2); 418 Lisp_Object rfont_def = AREF (vec, i);
412 Lisp_Object font_def = RFONT_DEF_FONT_DEF (rfont_def); 419 Lisp_Object font_def = RFONT_DEF_FONT_DEF (rfont_def);
413 Lisp_Object font_spec = FONT_DEF_SPEC (font_def); 420 Lisp_Object font_spec = FONT_DEF_SPEC (font_def);
414 Lisp_Object lang = Ffont_get (font_spec, QClang); 421 int score = RFONT_DEF_SCORE (rfont_def) & 0xFF;
415 Lisp_Object family = AREF (font_spec, FONT_FAMILY_INDEX);
416 Lisp_Object repertory = FONT_DEF_REPERTORY (font_def);
417 int score = 0;
418 422
419 if (! NILP (repertory)) 423 if (! font_match_p (font_spec, font_object))
420 { 424 {
421 Lisp_Object tail; 425 Lisp_Object repertory = FONT_DEF_REPERTORY (font_def);
422 426
423 for (score = 0xFFFF, tail = Vcharset_ordered_list; 427 if (! NILP (repertory))
424 ! EQ (tail, Vcharset_non_preferred_head) && CONSP (tail); 428 {
425 score--, tail = XCDR (tail)) 429 Lisp_Object tail;
426 if (EQ (repertory, XCAR (tail)))
427 break;
428 if (EQ (tail, Vcharset_non_preferred_head))
429 score = 0;
430 }
431 else if (! NILP (lang))
432 {
433 if (EQ (lang, Vcurrent_iso639_language))
434 score = 0xFFFF;
435 else if (CONSP (Vcurrent_iso639_language))
436 score = ! NILP (Fmemq (lang, Vcurrent_iso639_language));
437 }
438 430
439 if (! NILP (preferred_family) && ! NILP (family)) 431 for (tail = Vcharset_ordered_list;
440 { 432 ! EQ (tail, Vcharset_non_preferred_head) && CONSP (tail);
441 if (fast_string_match_ignore_case (preferred_family, 433 score += 0x100, tail = XCDR (tail))
442 SYMBOL_NAME (family)) < 0) 434 if (EQ (repertory, XCAR (tail)))
443 score |= 0x10000; 435 break;
436 }
437 else
438 {
439 Lisp_Object lang = Ffont_get (font_spec, QClang);
440
441 if (! NILP (lang)
442 && ! EQ (lang, Vcurrent_iso639_language)
443 && (! CONSP (Vcurrent_iso639_language)
444 || NILP (Fmemq (lang, Vcurrent_iso639_language))))
445 score |= 0x100;
446 }
444 } 447 }
445 if (RFONT_DEF_SCORE (rfont_def) != score) 448 if (RFONT_DEF_SCORE (rfont_def) != score)
446 { 449 {
@@ -450,10 +453,49 @@ reorder_font_vector (font_group, preferred_family)
450 } 453 }
451 454
452 if (score_changed) 455 if (score_changed)
453 qsort (XVECTOR (font_group)->contents + 2, size, sizeof (Lisp_Object), 456 qsort (XVECTOR (vec)->contents, size, sizeof (Lisp_Object),
454 fontset_compare_rfontdef); 457 fontset_compare_rfontdef);
458 XSETCAR (font_group, make_number (charset_ordered_list_tick));
459}
460
461static Lisp_Object
462fontset_get_font_group (fontset, c)
463{
464 Lisp_Object font_group;
465 Lisp_Object base_fontset;
466 int from, to, i;
455 467
456 ASET (font_group, 0, make_number (charset_ordered_list_tick)); 468 xassert (! BASE_FONTSET_P (fontset));
469 if (c >= 0)
470 font_group = CHAR_TABLE_REF (fontset, c);
471 else
472 font_group = FONTSET_FALLBACK (fontset);
473 if (! NILP (font_group))
474 return font_group;
475 base_fontset = FONTSET_BASE (fontset);
476 if (c >= 0)
477 font_group = char_table_ref_and_range (base_fontset, c, &from, &to);
478 else
479 font_group = FONTSET_FALLBACK (base_fontset);
480 if (NILP (font_group))
481 return Qnil;
482 font_group = Fcopy_sequence (font_group);
483 for (i = 0; i < ASIZE (font_group); i++)
484 if (! NILP (AREF (font_group, i)))
485 {
486 Lisp_Object rfont_def;
487
488 RFONT_DEF_NEW (rfont_def, AREF (font_group, i));
489 /* Remember the original order. */
490 RFONT_DEF_SET_SCORE (rfont_def, i);
491 ASET (font_group, i, rfont_def);
492 }
493 font_group = Fcons (make_number (-1), font_group);
494 if (c >= 0)
495 char_table_set_range (fontset, from, to, font_group);
496 else
497 FONTSET_FALLBACK (fontset) = font_group;
498 return font_group;
457} 499}
458 500
459/* Return RFONT-DEF (vector) in the realized fontset FONTSET for the 501/* Return RFONT-DEF (vector) in the realized fontset FONTSET for the
@@ -476,117 +518,61 @@ fontset_find_font (fontset, c, face, id, fallback)
476 struct face *face; 518 struct face *face;
477 int id, fallback; 519 int id, fallback;
478{ 520{
479 Lisp_Object base_fontset, elt, vec; 521 Lisp_Object elt, vec, font_group;
480 int i, from, to; 522 int i;
481 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset)); 523 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
524 int charset_matched = -1;
482 525
483 base_fontset = FONTSET_BASE (fontset); 526 font_group = fontset_get_font_group (fontset, fallback ? -1 : c);
484 if (! fallback) 527 if (! CONSP (font_group))
485 vec = CHAR_TABLE_REF (fontset, c); 528 return Qnil;
486 else 529 vec = XCDR (font_group);
487 vec = FONTSET_FALLBACK (fontset); 530 if (ASIZE (vec) == 0)
531 return Qnil;
488 532
489 if (NILP (vec)) 533 if (ASIZE (vec) > 1)
490 { 534 {
491 Lisp_Object range; 535 if (XINT (XCAR (font_group)) != charset_ordered_list_tick)
492 536 /* We have just created the font-group,
493 /* We have not yet decided a font for C. */ 537 or the charset priorities were changed. */
494 if (! face) 538 reorder_font_vector (font_group, face->ascii_face->font);
495 return Qnil; 539 if (id >= 0)
496 if (! fallback) 540 /* Find a spec matching with the charset ID to try at
497 { 541 first. */
498 elt = char_table_ref_and_range (base_fontset, c, &from, &to); 542 for (i = 0; i < ASIZE (vec); i++)
499 range = Fcons (make_number (from), make_number (to)); 543 {
500 } 544 Lisp_Object rfont_def = AREF (vec, i);
501 else 545 Lisp_Object repertory
502 { 546 = FONT_DEF_REPERTORY (RFONT_DEF_FONT_DEF (rfont_def));
503 elt = FONTSET_FALLBACK (base_fontset); 547
504 } 548 if (XINT (repertory) == id)
505 if (NILP (elt))
506 {
507 /* This fontset doesn't specify any font for C. */
508 vec = make_number (0);
509 }
510 else if (ASIZE (elt) == 1 && NILP (AREF (elt, 0)))
511 {
512 /* Explicitly specified no font. */
513 vec = Qt;
514 }
515 else
516 {
517 /* Build a font-group vector [ -1 nil RFONT-DEF0 RFONT-DEF1 ... ],
518 where the first -1 is to force reordering of RFONT-DEFs. */
519 int size = ASIZE (elt);
520 int j;
521
522 vec = Fmake_vector (make_number (size + 2), Qnil);
523 ASET (vec, 0, make_number (-1));
524 for (i = j = 0; i < size; i++)
525 if (! NILP (AREF (elt, i)))
526 { 549 {
527 Lisp_Object rfont_def; 550 charset_matched = i;
528
529 RFONT_DEF_NEW (rfont_def, AREF (elt, i));
530 ASET (vec, j + 2, rfont_def);
531 j++;
532 }
533 }
534 /* Then store it in the fontset. */
535 if (! fallback)
536 FONTSET_SET (fontset, range, vec);
537 else
538 FONTSET_FALLBACK (fontset) = vec;
539
540 }
541 if (! VECTORP (vec))
542 return (EQ (vec, Qt) ? Qt : Qnil);
543
544 if (ASIZE (vec) > 4 /* multiple RFONT-DEFs */
545 && XINT (AREF (vec, 0)) != charset_ordered_list_tick)
546 /* We have just created VEC,
547 or the charset priorities were changed. */
548 reorder_font_vector (vec, face->lface[LFACE_FAMILY_INDEX]);
549 i = 2;
550 if (id >= 0)
551 {
552 elt = AREF (vec, 1);
553 if (! NILP (elt)
554 && EQ (make_number (id), RFONT_DEF_REPERTORY (elt)))
555 i = 1;
556 else
557 {
558 for (; i < ASIZE (vec); i++)
559 {
560 elt = AREF (vec, i);
561 if (! NILP (elt)
562 && EQ (make_number (id), RFONT_DEF_REPERTORY (elt)))
563 break; 551 break;
564 } 552 }
565 if (i < ASIZE (vec)) 553 }
566 {
567 ASET (vec, 1, elt);
568 i = 1;
569 }
570 else
571 {
572 ASET (vec, 1, Qnil);
573 i = 2;
574 }
575 }
576 } 554 }
577 555
578 /* Find the first available font in the vector of RFONT-DEF. */ 556 /* Find the first available font in the vector of RFONT-DEF. */
579 for (; i < ASIZE (vec); i++) 557 for (i = 0; i < ASIZE (vec); i++)
580 { 558 {
581 Lisp_Object font_entity, font_object; 559 Lisp_Object font_entity, font_object;
582 560
583 elt = AREF (vec, i); 561 if (i == 0 && charset_matched >= 0)
562 {
563 /* Try the element matching with the charset ID at first. */
564 elt = AREF (vec, charset_matched);
565 charset_matched = -1;
566 i--;
567 }
568 else if (i != charset_matched)
569 elt = AREF (vec, i);
570 else
571 continue;
572
584 if (NILP (elt)) 573 if (NILP (elt))
585 /* This is the sign of not to try fallback fonts. */ 574 /* This is a sign of not to try the other fonts. */
586 return Qt; 575 return Qt;
587 if (id >= 0 && i > 1 && EQ (AREF (vec, 1), elt))
588 /* This is already checked. */
589 continue;
590 if (INTEGERP (RFONT_DEF_FACE (elt)) 576 if (INTEGERP (RFONT_DEF_FACE (elt))
591 && XINT (AREF (elt, 1)) < 0) 577 && XINT (AREF (elt, 1)) < 0)
592 /* We couldn't open this font last time. */ 578 /* We couldn't open this font last time. */
@@ -678,37 +664,46 @@ fontset_font (fontset, c, face, id)
678 Lisp_Object rfont_def; 664 Lisp_Object rfont_def;
679 Lisp_Object base_fontset; 665 Lisp_Object base_fontset;
680 666
681 /* Try a font-group for C. */ 667 /* Try a font-group of FONTSET. */
682 rfont_def = fontset_find_font (fontset, c, face, id, 0); 668 rfont_def = fontset_find_font (fontset, c, face, id, 0);
683 if (VECTORP (rfont_def)) 669 if (VECTORP (rfont_def))
684 return rfont_def; 670 return rfont_def;
685 if (EQ (rfont_def, Qt)) 671 if (EQ (rfont_def, Qt))
686 return Qnil; 672 return Qnil;
687 /* Try a fallback font-group. */ 673
674 /* Try a font-group of the default fontset. */
675 base_fontset = FONTSET_BASE (fontset);
676 if (! EQ (base_fontset, Vdefault_fontset))
677 {
678 if (NILP (FONTSET_DEFAULT (fontset)))
679 FONTSET_DEFAULT (fontset)
680 = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
681 rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
682 if (VECTORP (rfont_def))
683 return rfont_def;
684 if (EQ (rfont_def, Qt))
685 return Qnil;
686 }
687
688 /* Try a fallback font-group of FONTSET. */
688 rfont_def = fontset_find_font (fontset, c, face, id, 1); 689 rfont_def = fontset_find_font (fontset, c, face, id, 1);
689 if (VECTORP (rfont_def)) 690 if (VECTORP (rfont_def))
690 return rfont_def; 691 return rfont_def;
691 if (EQ (rfont_def, Qt)) 692 if (EQ (rfont_def, Qt))
692 return Qnil; 693 return Qnil;
693 694
694 base_fontset = FONTSET_BASE (fontset);
695 if (EQ (base_fontset, Vdefault_fontset))
696 return Qnil;
697
698 /* Try a font-group for C of the default fontset. */
699 if (NILP (FONTSET_DEFAULT (fontset)))
700 FONTSET_DEFAULT (fontset)
701 = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
702 rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
703 if (VECTORP (rfont_def))
704 return rfont_def;
705 /* Try a fallback font-group of the default fontset . */ 695 /* Try a fallback font-group of the default fontset . */
706 rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 1); 696 if (! EQ (base_fontset, Vdefault_fontset))
707 if (! VECTORP (rfont_def)) 697 {
708 /* Remeber that we have no font for C. */ 698 rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 1);
709 FONTSET_SET (fontset, make_number (c), Qt); 699 if (VECTORP (rfont_def))
700 return rfont_def;
701 }
702
703 /* Remeber that we have no font for C. */
704 FONTSET_SET (fontset, make_number (c), Qt);
710 705
711 return rfont_def; 706 return Qnil;
712} 707}
713 708
714/* Return a newly created fontset with NAME. If BASE is nil, make a 709/* Return a newly created fontset with NAME. If BASE is nil, make a
@@ -890,6 +885,7 @@ face_for_char (f, face, c, pos, object)
890 xassert (fontset_id_valid_p (face->fontset)); 885 xassert (fontset_id_valid_p (face->fontset));
891 fontset = FONTSET_FROM_ID (face->fontset); 886 fontset = FONTSET_FROM_ID (face->fontset);
892 xassert (!BASE_FONTSET_P (fontset)); 887 xassert (!BASE_FONTSET_P (fontset));
888
893 if (pos < 0) 889 if (pos < 0)
894 id = -1; 890 id = -1;
895 else 891 else
@@ -909,16 +905,6 @@ face_for_char (f, face, c, pos, object)
909 id = XINT (CHARSET_SYMBOL_ID (charset)); 905 id = XINT (CHARSET_SYMBOL_ID (charset));
910 } 906 }
911 } 907 }
912 if (id < 0)
913 {
914 struct font *font = face->ascii_face->font;
915
916 if (font && font->driver->encode_char (font, c) != FONT_INVALID_CODE)
917 return face->ascii_face->id;
918 font = face->font;
919 if (font && font->driver->encode_char (font, c) != FONT_INVALID_CODE)
920 return face->id;
921 }
922 908
923 rfont_def = fontset_font (fontset, c, face, id); 909 rfont_def = fontset_font (fontset, c, face, id);
924 if (VECTORP (rfont_def)) 910 if (VECTORP (rfont_def))
@@ -1634,13 +1620,9 @@ fontset_from_font (font_object)
1634 auto_fontset_alist = Fcons (Fcons (font_spec, fontset), auto_fontset_alist); 1620 auto_fontset_alist = Fcons (Fcons (font_spec, fontset), auto_fontset_alist);
1635 FONTSET_ASCII (fontset) = font_name; 1621 FONTSET_ASCII (fontset) = font_name;
1636 font_spec = Fcopy_font_spec (font_spec); 1622 font_spec = Fcopy_font_spec (font_spec);
1637 ASET (font_spec, FONT_FOUNDRY_INDEX, Qnil); 1623 ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
1638 ASET (font_spec, FONT_ADSTYLE_INDEX, Qnil);
1639 for (i = FONT_WEIGHT_INDEX; i < FONT_EXTRA_INDEX; i++) 1624 for (i = FONT_WEIGHT_INDEX; i < FONT_EXTRA_INDEX; i++)
1640 ASET (font_spec, i, Qnil); 1625 ASET (font_spec, i, Qnil);
1641 Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qnil);
1642 font_spec = Fcopy_font_spec (font_spec);
1643 ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
1644 Fset_fontset_font (name, Qnil, font_spec, Qnil, Qnil); 1626 Fset_fontset_font (name, Qnil, font_spec, Qnil, Qnil);
1645 return XINT (FONTSET_ID (fontset)); 1627 return XINT (FONTSET_ID (fontset));
1646} 1628}