diff options
| author | Kenichi Handa | 2006-06-19 12:43:59 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2006-06-19 12:43:59 +0000 |
| commit | 9331887d8d56a6a40f4a8fcc19f66b0ccb307e9d (patch) | |
| tree | 962a764d1350ccc247b4841fa9c12306004d99d6 /src | |
| parent | 63565713ad24051f6a1d4422863a7921cedc8f27 (diff) | |
| download | emacs-9331887d8d56a6a40f4a8fcc19f66b0ccb307e9d.tar.gz emacs-9331887d8d56a6a40f4a8fcc19f66b0ccb307e9d.zip | |
(POINT_TO_PIXEL): Don't divice POINT by 10.
(QCspacing, QCdpi): New variables.
(syms_of_font): Initialize them.
(font_pixel_size): New function.
(font_put_extra): New function.
(font_parse_xlfd): Fix handling of font size. Add QCdpi property
in FONT_EXTRA.
(font_parse_fcname): Handle enumenrated values (e.g. bold). Fix
handling font size. Add QCname property that contains only
unknown properties.
(font_score): Change argument. Caller changed. Pay attention to
FONT_PIXEL_SIZE_QUANTUM.
(font_sort_entites): Fix handling of font size.
(font_list_entities): Likewise.
(font_find_for_lface): Likewise.
(font_open_for_lface): Likewise.
(font_open_by_name): Likewise.
(Ffont_spec): Add QCname property that contains only unknown
properties.
Diffstat (limited to 'src')
| -rw-r--r-- | src/font.c | 341 |
1 files changed, 230 insertions, 111 deletions
diff --git a/src/font.c b/src/font.c index 0ec174393ae..15b3947d5fc 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -64,10 +64,12 @@ Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp; | |||
| 64 | /* Number of pt per inch (from the TeXbook). */ | 64 | /* Number of pt per inch (from the TeXbook). */ |
| 65 | #define PT_PER_INCH 72.27 | 65 | #define PT_PER_INCH 72.27 |
| 66 | 66 | ||
| 67 | /* Return a pixel size corresponding to POINT size (1/10 pt unit) on | 67 | /* Return a pixel size (integer) corresponding to POINT size (double) |
| 68 | resolution RESY. */ | 68 | on resolution RESY. */ |
| 69 | #define POINT_TO_PIXEL(POINT, RESY) ((POINT) * (RESY) / PT_PER_INCH / 10 + 0.5) | 69 | #define POINT_TO_PIXEL(POINT, RESY) ((POINT) * (RESY) / PT_PER_INCH + 0.5) |
| 70 | 70 | ||
| 71 | /* Return a point size (double) corresponding to POINT size (integer) | ||
| 72 | on resolution RESY. */ | ||
| 71 | #define PIXEL_TO_POINT(PIXEL, RESY) ((PIXEL) * PT_PER_INCH * 10 / (RESY) + 0.5) | 73 | #define PIXEL_TO_POINT(PIXEL, RESY) ((PIXEL) * PT_PER_INCH * 10 / (RESY) + 0.5) |
| 72 | 74 | ||
| 73 | /* Special string of zero length. It is used to specify a NULL name | 75 | /* Special string of zero length. It is used to specify a NULL name |
| @@ -99,7 +101,7 @@ static Lisp_Object font_family_alist; | |||
| 99 | extern Lisp_Object QCtype, QCfamily, QCweight, QCslant, QCwidth, QCsize, QCname; | 101 | extern Lisp_Object QCtype, QCfamily, QCweight, QCslant, QCwidth, QCsize, QCname; |
| 100 | Lisp_Object QCfoundry, QCadstyle, QCregistry, QCextra; | 102 | Lisp_Object QCfoundry, QCadstyle, QCregistry, QCextra; |
| 101 | /* Symbols representing keys of font extra info. */ | 103 | /* Symbols representing keys of font extra info. */ |
| 102 | Lisp_Object QCotf, QClanguage, QCscript; | 104 | Lisp_Object QCspacing, QCdpi, QCotf, QClanguage, QCscript; |
| 103 | 105 | ||
| 104 | /* List of all font drivers. All font-backends (XXXfont.c) call | 106 | /* List of all font drivers. All font-backends (XXXfont.c) call |
| 105 | add_font_driver in syms_of_XXXfont to register the font-driver | 107 | add_font_driver in syms_of_XXXfont to register the font-driver |
| @@ -114,6 +116,33 @@ static Lisp_Object font_open_entity P_ ((FRAME_PTR, Lisp_Object, int)); | |||
| 114 | /* Number of registered font drivers. */ | 116 | /* Number of registered font drivers. */ |
| 115 | static int num_font_drivers; | 117 | static int num_font_drivers; |
| 116 | 118 | ||
| 119 | /* Return a pixel size of font-spec SPEC on frame F. */ | ||
| 120 | static int | ||
| 121 | font_pixel_size (f, spec) | ||
| 122 | FRAME_PTR f; | ||
| 123 | Lisp_Object spec; | ||
| 124 | { | ||
| 125 | Lisp_Object size = AREF (spec, FONT_SIZE_INDEX); | ||
| 126 | double point_size; | ||
| 127 | int pixel_size, dpi; | ||
| 128 | Lisp_Object extra, val; | ||
| 129 | |||
| 130 | if (INTEGERP (size)) | ||
| 131 | return XINT (size); | ||
| 132 | if (NILP (size)) | ||
| 133 | return 0; | ||
| 134 | point_size = XFLOAT_DATA (size); | ||
| 135 | extra = AREF (spec, FONT_EXTRA_INDEX); | ||
| 136 | val = assq_no_quit (extra, QCdpi); | ||
| 137 | |||
| 138 | if (CONSP (val) && INTEGERP (XCDR (val))) | ||
| 139 | dpi = XINT (XCDR (val)); | ||
| 140 | else | ||
| 141 | dpi = f->resy; | ||
| 142 | pixel_size = POINT_TO_PIXEL (point_size, dpi); | ||
| 143 | return pixel_size; | ||
| 144 | } | ||
| 145 | |||
| 117 | /* Return a numeric value corresponding to PROP's NAME (symbol). If | 146 | /* Return a numeric value corresponding to PROP's NAME (symbol). If |
| 118 | NAME is not registered in font_style_table, return Qnil. PROP must | 147 | NAME is not registered in font_style_table, return Qnil. PROP must |
| 119 | be one of FONT_{WEIGHT|SLANT|SWIDTH}_INDEX. */ | 148 | be one of FONT_{WEIGHT|SLANT|SWIDTH}_INDEX. */ |
| @@ -345,6 +374,26 @@ font_prop_validate (spec) | |||
| 345 | return spec; | 374 | return spec; |
| 346 | } | 375 | } |
| 347 | 376 | ||
| 377 | static void | ||
| 378 | font_put_extra (font, prop, val, force) | ||
| 379 | Lisp_Object font, prop, val; | ||
| 380 | int force; | ||
| 381 | { | ||
| 382 | Lisp_Object extra = AREF (font, FONT_EXTRA_INDEX); | ||
| 383 | Lisp_Object slot = (NILP (extra) ? Qnil : Fassq (prop, extra)); | ||
| 384 | |||
| 385 | if (NILP (slot)) | ||
| 386 | { | ||
| 387 | extra = Fcons (Fcons (prop, val), extra); | ||
| 388 | ASET (font, FONT_EXTRA_INDEX, extra); | ||
| 389 | return; | ||
| 390 | } | ||
| 391 | if (! NILP (XCDR (slot)) && ! force) | ||
| 392 | return; | ||
| 393 | XSETCDR (slot, val); | ||
| 394 | return; | ||
| 395 | } | ||
| 396 | |||
| 348 | 397 | ||
| 349 | /* Font name parser and unparser */ | 398 | /* Font name parser and unparser */ |
| 350 | 399 | ||
| @@ -635,8 +684,19 @@ font_expand_wildcards (field, n) | |||
| 635 | } | 684 | } |
| 636 | 685 | ||
| 637 | /* Parse NAME (null terminated) as XLFD and store information in FONT | 686 | /* Parse NAME (null terminated) as XLFD and store information in FONT |
| 638 | (font-spec or font-entity). See font_parse_name for more | 687 | (font-spec or font-entity). Size property of FONT is set as |
| 639 | detail. */ | 688 | follows: |
| 689 | specified XLFD fields FONT property | ||
| 690 | --------------------- ------------- | ||
| 691 | PIXEL_SIZE PIXEL_SIZE (Lisp integer) | ||
| 692 | POINT_SIZE and RESY calculated pixel size (Lisp integer) | ||
| 693 | POINT_SIZE POINT_SIZE/10 (Lisp float) | ||
| 694 | |||
| 695 | If NAME is successfully parsed, return 2 (size is specified), 1 | ||
| 696 | (size is not specified), or 0 (size is not specified but resolution | ||
| 697 | is specified). Otherwise return -1. | ||
| 698 | |||
| 699 | See font_parse_name for more detail. */ | ||
| 640 | 700 | ||
| 641 | int | 701 | int |
| 642 | font_parse_xlfd (name, font, merge) | 702 | font_parse_xlfd (name, font, merge) |
| @@ -690,6 +750,8 @@ font_parse_xlfd (name, font, merge) | |||
| 690 | } | 750 | } |
| 691 | else if (i == XLFD_POINT_INDEX) | 751 | else if (i == XLFD_POINT_INDEX) |
| 692 | { | 752 | { |
| 753 | /* If PIXEL_SIZE is specified, we don't have to | ||
| 754 | calculate POINT_SIZE. */ | ||
| 693 | if (pixel_size < 0) | 755 | if (pixel_size < 0) |
| 694 | { | 756 | { |
| 695 | if (isdigit (*name)) | 757 | if (isdigit (*name)) |
| @@ -707,6 +769,8 @@ font_parse_xlfd (name, font, merge) | |||
| 707 | else if (i == XLFD_RESY_INDEX) | 769 | else if (i == XLFD_RESY_INDEX) |
| 708 | { | 770 | { |
| 709 | /* Stuff RESY, SPACING, and AVGWIDTH. */ | 771 | /* Stuff RESY, SPACING, and AVGWIDTH. */ |
| 772 | /* If PIXEL_SIZE is specified, we don't have to | ||
| 773 | calculate RESY. */ | ||
| 710 | if (pixel_size < 0 && isdigit (*name)) | 774 | if (pixel_size < 0 && isdigit (*name)) |
| 711 | resy = atoi (name); | 775 | resy = atoi (name); |
| 712 | for (p++; *p != '-'; p++); | 776 | for (p++; *p != '-'; p++); |
| @@ -776,10 +840,15 @@ font_parse_xlfd (name, font, merge) | |||
| 776 | return -1; | 840 | return -1; |
| 777 | if (! NILP (f[XLFD_PIXEL_INDEX])) | 841 | if (! NILP (f[XLFD_PIXEL_INDEX])) |
| 778 | pixel_size = XINT (f[XLFD_PIXEL_INDEX]); | 842 | pixel_size = XINT (f[XLFD_PIXEL_INDEX]); |
| 779 | if (! NILP (f[XLFD_POINT_INDEX])) | 843 | /* If PIXEL_SIZE is specified, we don't have to |
| 780 | point_size = XINT (f[XLFD_POINT_INDEX]); | 844 | calculate POINT_SIZE and RESY. */ |
| 781 | if (! NILP (f[XLFD_RESY_INDEX])) | 845 | if (pixel_size < 0) |
| 782 | resy = XINT (f[XLFD_RESY_INDEX]); | 846 | { |
| 847 | if (! NILP (f[XLFD_POINT_INDEX])) | ||
| 848 | point_size = XINT (f[XLFD_POINT_INDEX]); | ||
| 849 | if (! NILP (f[XLFD_RESY_INDEX])) | ||
| 850 | resy = XINT (f[XLFD_RESY_INDEX]); | ||
| 851 | } | ||
| 783 | if (! NILP (f[XLFD_AVGWIDTH_INDEX])) | 852 | if (! NILP (f[XLFD_AVGWIDTH_INDEX])) |
| 784 | avgwidth = XINT (f[XLFD_AVGWIDTH_INDEX]); | 853 | avgwidth = XINT (f[XLFD_AVGWIDTH_INDEX]); |
| 785 | if (NILP (f[XLFD_REGISTRY_INDEX])) | 854 | if (NILP (f[XLFD_REGISTRY_INDEX])) |
| @@ -828,22 +897,16 @@ font_parse_xlfd (name, font, merge) | |||
| 828 | if (pixel_size >= 0) | 897 | if (pixel_size >= 0) |
| 829 | ASET (font, FONT_SIZE_INDEX, make_number (pixel_size)); | 898 | ASET (font, FONT_SIZE_INDEX, make_number (pixel_size)); |
| 830 | else if (point_size >= 0) | 899 | else if (point_size >= 0) |
| 831 | { | 900 | ASET (font, FONT_SIZE_INDEX, make_float (point_size / 10)); |
| 832 | if (resy > 0) | ||
| 833 | { | ||
| 834 | pixel_size = POINT_TO_PIXEL (point_size, resy); | ||
| 835 | ASET (font, FONT_SIZE_INDEX, make_number (pixel_size)); | ||
| 836 | } | ||
| 837 | else | ||
| 838 | { | ||
| 839 | ASET (font, FONT_SIZE_INDEX, make_float (point_size / 10)); | ||
| 840 | } | ||
| 841 | } | ||
| 842 | } | 901 | } |
| 843 | 902 | ||
| 844 | if (FONT_ENTITY_P (font) | 903 | if (FONT_ENTITY_P (font)) |
| 845 | && EQ (AREF (font, FONT_TYPE_INDEX), Qx)) | 904 | { |
| 846 | ASET (font, FONT_EXTRA_INDEX, f[XLFD_RESY_INDEX]); | 905 | if (EQ (AREF (font, FONT_TYPE_INDEX), Qx)) |
| 906 | ASET (font, FONT_EXTRA_INDEX, f[XLFD_RESY_INDEX]); | ||
| 907 | } | ||
| 908 | else if (resy >= 0) | ||
| 909 | font_put_extra (font, QCdpi, make_number (resy), merge); | ||
| 847 | 910 | ||
| 848 | return (avgwidth > 0 ? 2 : resy == 0); | 911 | return (avgwidth > 0 ? 2 : resy == 0); |
| 849 | } | 912 | } |
| @@ -930,7 +993,7 @@ font_unparse_xlfd (font, pixel_size, name, nbytes) | |||
| 930 | { | 993 | { |
| 931 | i = XINT (val); | 994 | i = XINT (val); |
| 932 | if (i > 0) | 995 | if (i > 0) |
| 933 | len += sprintf (work, "%d", i) + 1; | 996 | len += sprintf (work, "%d-*", i) + 1; |
| 934 | else /* i == 0 */ | 997 | else /* i == 0 */ |
| 935 | len += sprintf (work, "%d-*", pixel_size) + 1; | 998 | len += sprintf (work, "%d-*", pixel_size) + 1; |
| 936 | pixel_point = work; | 999 | pixel_point = work; |
| @@ -972,8 +1035,8 @@ font_unparse_xlfd (font, pixel_size, name, nbytes) | |||
| 972 | } | 1035 | } |
| 973 | 1036 | ||
| 974 | /* Parse NAME (null terminated) as Fonconfig's name format and store | 1037 | /* Parse NAME (null terminated) as Fonconfig's name format and store |
| 975 | information in FONT (font-spec or font-entity). See | 1038 | information in FONT (font-spec or font-entity). If NAME is |
| 976 | font_parse_name for more detail. */ | 1039 | successfully parsed, return 0. Otherwise return -1. */ |
| 977 | 1040 | ||
| 978 | int | 1041 | int |
| 979 | font_parse_fcname (name, font, merge) | 1042 | font_parse_fcname (name, font, merge) |
| @@ -986,6 +1049,8 @@ font_parse_fcname (name, font, merge) | |||
| 986 | double point_size = 0; | 1049 | double point_size = 0; |
| 987 | int pixel_size = 0; | 1050 | int pixel_size = 0; |
| 988 | Lisp_Object extra = AREF (font, FONT_EXTRA_INDEX); | 1051 | Lisp_Object extra = AREF (font, FONT_EXTRA_INDEX); |
| 1052 | int len = strlen (name); | ||
| 1053 | char *copy; | ||
| 989 | 1054 | ||
| 990 | /* It is assured that (name[0] && name[0] != '-'). */ | 1055 | /* It is assured that (name[0] && name[0] != '-'). */ |
| 991 | if (name[0] == ':') | 1056 | if (name[0] == ':') |
| @@ -1009,57 +1074,114 @@ font_parse_fcname (name, font, merge) | |||
| 1009 | if (! merge || NILP (AREF (font, FONT_FAMILY_INDEX))) | 1074 | if (! merge || NILP (AREF (font, FONT_FAMILY_INDEX))) |
| 1010 | ASET (font, FONT_FAMILY_INDEX, family); | 1075 | ASET (font, FONT_FAMILY_INDEX, family); |
| 1011 | } | 1076 | } |
| 1077 | |||
| 1078 | len -= p0 - name; | ||
| 1079 | copy = alloca (len + 1); | ||
| 1080 | if (! copy) | ||
| 1081 | return -1; | ||
| 1082 | name = copy; | ||
| 1083 | |||
| 1084 | /* Now parse ":KEY=VAL" patterns. Store known keys and values in | ||
| 1085 | extra, copy unknown ones to COPY. */ | ||
| 1012 | while (*p0) | 1086 | while (*p0) |
| 1013 | { | 1087 | { |
| 1014 | Lisp_Object key, val; | 1088 | Lisp_Object key, val; |
| 1015 | enum font_property_index prop; | 1089 | enum font_property_index prop; |
| 1016 | 1090 | ||
| 1017 | p1 = index (name, '='); | 1091 | for (p1 = p0 + 1; islower (*p1); p1++); |
| 1018 | if (! p1) | 1092 | if (*p1 != '=') |
| 1019 | return -1; | ||
| 1020 | if (memcmp (p0 + 1, "pixelsize=", 10) == 0) | ||
| 1021 | prop = FONT_SIZE_INDEX; | ||
| 1022 | else | ||
| 1023 | { | ||
| 1024 | key = intern_font_field (p0, p1 - p0); | ||
| 1025 | prop = check_font_prop_name (key); | ||
| 1026 | } | ||
| 1027 | p0 = p1 + 1; | ||
| 1028 | for (p1 = p0; *p1 && *p1 != ':'; p1++); | ||
| 1029 | if (prop == FONT_SIZE_INDEX) | ||
| 1030 | { | 1093 | { |
| 1031 | pixel_size = atoi (p0); | 1094 | /* Must be an enumerated value. */ |
| 1095 | val = intern_font_field (p0 + 1, p1 - p0 - 1); | ||
| 1096 | |||
| 1097 | if (memcmp (p0 + 1, "light", 5) == 0 | ||
| 1098 | || memcmp (p0 + 1, "medium", 6) == 0 | ||
| 1099 | || memcmp (p0 + 1, "demibold", 8) == 0 | ||
| 1100 | || memcmp (p0 + 1, "bold", 4) == 0 | ||
| 1101 | || memcmp (p0 + 1, "black", 5) == 0) | ||
| 1102 | { | ||
| 1103 | if (! merge || NILP (AREF (font, FONT_WEIGHT_INDEX))) | ||
| 1104 | ASET (font, FONT_WEIGHT_INDEX, | ||
| 1105 | prop_name_to_numeric (FONT_WEIGHT_INDEX, val)); | ||
| 1106 | } | ||
| 1107 | else if (memcmp (p0 + 1, "roman", 5) == 0 | ||
| 1108 | || memcmp (p0 + 1, "italic", 6) == 0 | ||
| 1109 | || memcmp (p0 + 1, "oblique", 7) == 0) | ||
| 1110 | { | ||
| 1111 | if (! merge || NILP (AREF (font, FONT_SLANT_INDEX))) | ||
| 1112 | ASET (font, FONT_SLANT_INDEX, | ||
| 1113 | prop_name_to_numeric (FONT_SLANT_INDEX, val)); | ||
| 1114 | } | ||
| 1115 | else if (memcmp (p0 + 1, "charcell", 8) == 0 | ||
| 1116 | || memcmp (p0 + 1, "mono", 4) == 0 | ||
| 1117 | || memcmp (p0 + 1, "proportional", 12) == 0) | ||
| 1118 | { | ||
| 1119 | font_put_extra (font, QCspacing, | ||
| 1120 | p0[1] == 'c' ? make_number (FONT_SPACING_CHARCELL) | ||
| 1121 | : p0[1] == 'm' ? make_number (FONT_SPACING_MONO) | ||
| 1122 | : make_number (FONT_SPACING_PROPORTIONAL), | ||
| 1123 | merge); | ||
| 1124 | } | ||
| 1125 | else | ||
| 1126 | { | ||
| 1127 | /* unknown key */ | ||
| 1128 | bcopy (p0, copy, p1 - p0); | ||
| 1129 | copy += p1 - p0; | ||
| 1130 | } | ||
| 1032 | } | 1131 | } |
| 1033 | else | 1132 | else |
| 1034 | { | 1133 | { |
| 1035 | val = intern_font_field (p0, p1 - p0); | 1134 | if (memcmp (p0 + 1, "pixelsize=", 10) == 0) |
| 1036 | if (prop < FONT_EXTRA_INDEX) | 1135 | prop = FONT_SIZE_INDEX; |
| 1136 | else | ||
| 1137 | { | ||
| 1138 | key = intern_font_field (p0, p1 - p0); | ||
| 1139 | prop = check_font_prop_name (key); | ||
| 1140 | } | ||
| 1141 | p0 = p1 + 1; | ||
| 1142 | for (p1 = p0; *p1 && *p1 != ':'; p1++); | ||
| 1143 | if (prop == FONT_SIZE_INDEX) | ||
| 1144 | { | ||
| 1145 | pixel_size = atoi (p0); | ||
| 1146 | } | ||
| 1147 | else if (prop < FONT_EXTRA_INDEX) | ||
| 1037 | { | 1148 | { |
| 1038 | if (! merge || NILP (AREF (font, prop))) | 1149 | if (! merge || NILP (AREF (font, prop))) |
| 1039 | { | 1150 | { |
| 1040 | val = font_property_table[prop].validater (prop, val); | 1151 | val = intern_font_field (p0, p1 - p0); |
| 1152 | if (prop >= FONT_WEIGHT_INDEX && prop <= FONT_WIDTH_INDEX) | ||
| 1153 | val = font_property_table[prop].validater (prop, val); | ||
| 1041 | if (! EQ (val, Qerror)) | 1154 | if (! EQ (val, Qerror)) |
| 1042 | ASET (font, prop, val); | 1155 | ASET (font, prop, val); |
| 1043 | } | 1156 | } |
| 1044 | } | 1157 | } |
| 1158 | else if (EQ (key, QCdpi)) | ||
| 1159 | { | ||
| 1160 | if (INTEGERP (val)) | ||
| 1161 | font_put_extra (font, key, val, merge); | ||
| 1162 | } | ||
| 1045 | else | 1163 | else |
| 1046 | { | 1164 | { |
| 1047 | if (! merge || NILP (Fplist_get (extra, key))) | 1165 | /* unknown key */ |
| 1048 | extra = Fplist_put (extra, key, val); | 1166 | bcopy (p0, copy, p1 - p0); |
| 1167 | copy += p1 - p0; | ||
| 1049 | } | 1168 | } |
| 1050 | } | 1169 | } |
| 1051 | p0 = p1; | 1170 | p0 = p1; |
| 1052 | } | 1171 | } |
| 1053 | ASET (font, FONT_EXTRA_INDEX, extra); | 1172 | |
| 1054 | if (! merge || NILP (AREF (font, FONT_SIZE_INDEX))) | 1173 | if (! merge || NILP (AREF (font, FONT_SIZE_INDEX))) |
| 1055 | { | 1174 | { |
| 1056 | if (point_size > 0) | 1175 | if (pixel_size > 0) |
| 1057 | ASET (font, FONT_SIZE_INDEX, make_float (point_size)); | ||
| 1058 | else if (pixel_size > 0) | ||
| 1059 | ASET (font, FONT_SIZE_INDEX, make_number (pixel_size)); | 1176 | ASET (font, FONT_SIZE_INDEX, make_number (pixel_size)); |
| 1177 | else if (point_size > 0) | ||
| 1178 | ASET (font, FONT_SIZE_INDEX, make_float (point_size)); | ||
| 1060 | } | 1179 | } |
| 1180 | if (name < copy) | ||
| 1181 | font_put_extra (font, QCname, make_unibyte_string (name, copy - name), | ||
| 1182 | merge); | ||
| 1061 | 1183 | ||
| 1062 | return (NILP (AREF (font, FONT_SIZE_INDEX)) ? 1 : 2); | 1184 | return 0; |
| 1063 | } | 1185 | } |
| 1064 | 1186 | ||
| 1065 | /* Store fontconfig's font name of FONT (font-spec or font-entity) in | 1187 | /* Store fontconfig's font name of FONT (font-spec or font-entity) in |
| @@ -1135,8 +1257,7 @@ font_unparse_fcname (font, pixel_size, name, nbytes) | |||
| 1135 | 1257 | ||
| 1136 | /* Parse NAME (null terminated) and store information in FONT | 1258 | /* Parse NAME (null terminated) and store information in FONT |
| 1137 | (font-spec or font-entity). If NAME is successfully parsed, return | 1259 | (font-spec or font-entity). If NAME is successfully parsed, return |
| 1138 | 2 (size is specified), 1 (size is not specified), or 0 (size is not | 1260 | a non-negative value. Otherwise return -1. |
| 1139 | specified but resolution is specified). Otherwise return -1. | ||
| 1140 | 1261 | ||
| 1141 | If NAME is XLFD and FONT is a font-entity, store | 1262 | If NAME is XLFD and FONT is a font-entity, store |
| 1142 | RESY-SPACING-AVWIDTH information as a symbol in FONT_EXTRA_INDEX. | 1263 | RESY-SPACING-AVWIDTH information as a symbol in FONT_EXTRA_INDEX. |
| @@ -1734,7 +1855,7 @@ font_gstring_produce (old, from, to, new, idx, code, n) | |||
| 1734 | 1855 | ||
| 1735 | /* Font sorting */ | 1856 | /* Font sorting */ |
| 1736 | 1857 | ||
| 1737 | static unsigned font_score P_ ((Lisp_Object, Lisp_Object)); | 1858 | static unsigned font_score P_ ((Lisp_Object, Lisp_Object *)); |
| 1738 | static int font_compare P_ ((const void *, const void *)); | 1859 | static int font_compare P_ ((const void *, const void *)); |
| 1739 | static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object, | 1860 | static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object, |
| 1740 | Lisp_Object, Lisp_Object)); | 1861 | Lisp_Object, Lisp_Object)); |
| @@ -1753,43 +1874,45 @@ static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object, | |||
| 1753 | property in a score. */ | 1874 | property in a score. */ |
| 1754 | static int sort_shift_bits[FONT_SIZE_INDEX + 1]; | 1875 | static int sort_shift_bits[FONT_SIZE_INDEX + 1]; |
| 1755 | 1876 | ||
| 1756 | /* Score font-entity ENTITY against font-spec SPEC. The return value | 1877 | /* Score font-entity ENTITY against properties of font-spec SPEC_PROP. |
| 1757 | indicates how different ENTITY is compared with SPEC. */ | 1878 | The return value indicates how different ENTITY is compared with |
| 1879 | SPEC_PROP. */ | ||
| 1758 | 1880 | ||
| 1759 | static unsigned | 1881 | static unsigned |
| 1760 | font_score (entity, spec) | 1882 | font_score (entity, spec_prop) |
| 1761 | Lisp_Object entity, spec; | 1883 | Lisp_Object entity, *spec_prop; |
| 1762 | { | 1884 | { |
| 1763 | unsigned score = 0; | 1885 | unsigned score = 0; |
| 1764 | int i; | 1886 | int i; |
| 1765 | /* Score atomic fields. Maximum difference is 1. */ | 1887 | /* Score four atomic fields. Maximum difference is 1. */ |
| 1766 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++) | 1888 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++) |
| 1767 | { | 1889 | if (! NILP (spec_prop[i]) |
| 1768 | Lisp_Object val = AREF (spec, i); | 1890 | && ! EQ (spec_prop[i], AREF (entity, i))) |
| 1769 | 1891 | score |= 1 << sort_shift_bits[i]; | |
| 1770 | if (! NILP (val) | ||
| 1771 | && ! EQ (val, AREF (entity, i))) | ||
| 1772 | score |= 1 << sort_shift_bits[i]; | ||
| 1773 | } | ||
| 1774 | 1892 | ||
| 1775 | /* Score numeric fields. Maximum difference is 127. */ | 1893 | /* Score four numeric fields. Maximum difference is 127. */ |
| 1776 | for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++) | 1894 | for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++) |
| 1777 | { | 1895 | { |
| 1778 | Lisp_Object spec_val = AREF (spec, i); | ||
| 1779 | Lisp_Object entity_val = AREF (entity, i); | 1896 | Lisp_Object entity_val = AREF (entity, i); |
| 1780 | 1897 | ||
| 1781 | if (! NILP (spec_val) && ! EQ (spec_val, entity_val)) | 1898 | if (! NILP (spec_prop[i]) && ! EQ (spec_prop[i], entity_val)) |
| 1782 | { | 1899 | { |
| 1783 | if (! INTEGERP (entity_val)) | 1900 | if (! INTEGERP (entity_val)) |
| 1784 | score |= 127 << sort_shift_bits[i]; | 1901 | score |= 127 << sort_shift_bits[i]; |
| 1785 | else if (i < FONT_SIZE_INDEX | 1902 | else |
| 1786 | || XINT (entity_val) != 0) | ||
| 1787 | { | 1903 | { |
| 1788 | int diff = XINT (entity_val) - XINT (spec_val); | 1904 | int diff = XINT (entity_val) - XINT (spec_prop[i]); |
| 1789 | 1905 | ||
| 1790 | if (diff < 0) | 1906 | if (diff < 0) |
| 1791 | diff = - diff; | 1907 | diff = - diff; |
| 1792 | score |= min (diff, 127) << sort_shift_bits[i]; | 1908 | if (i == FONT_SIZE_INDEX) |
| 1909 | { | ||
| 1910 | if (XINT (entity_val) > 0 | ||
| 1911 | && diff > FONT_PIXEL_SIZE_QUANTUM) | ||
| 1912 | score |= min (diff, 127) << sort_shift_bits[i]; | ||
| 1913 | } | ||
| 1914 | else | ||
| 1915 | score |= min (diff, 127) << sort_shift_bits[i]; | ||
| 1793 | } | 1916 | } |
| 1794 | } | 1917 | } |
| 1795 | } | 1918 | } |
| @@ -1819,58 +1942,46 @@ struct font_sort_data | |||
| 1819 | 1942 | ||
| 1820 | /* Sort font-entities in vector VEC by closeness to font-spec PREFER. | 1943 | /* Sort font-entities in vector VEC by closeness to font-spec PREFER. |
| 1821 | If PREFER specifies a point-size, calculate the corresponding | 1944 | If PREFER specifies a point-size, calculate the corresponding |
| 1822 | pixel-size from the Y-resolution of FRAME before sorting. If SPEC | 1945 | pixel-size from QCdpi property of PREFER or from the Y-resolution |
| 1823 | is not nil, it is a font-spec to get the font-entities in VEC. */ | 1946 | of FRAME before sorting. If SPEC is not nil, it is a font-spec to |
| 1947 | get the font-entities in VEC. */ | ||
| 1824 | 1948 | ||
| 1825 | static Lisp_Object | 1949 | static Lisp_Object |
| 1826 | font_sort_entites (vec, prefer, frame, spec) | 1950 | font_sort_entites (vec, prefer, frame, spec) |
| 1827 | Lisp_Object vec, prefer, frame, spec; | 1951 | Lisp_Object vec, prefer, frame, spec; |
| 1828 | { | 1952 | { |
| 1829 | Lisp_Object size; | 1953 | Lisp_Object prefer_prop[FONT_SPEC_MAX]; |
| 1830 | int len, i; | 1954 | int len, i; |
| 1831 | struct font_sort_data *data; | 1955 | struct font_sort_data *data; |
| 1832 | int prefer_is_copy = 0; | ||
| 1833 | USE_SAFE_ALLOCA; | 1956 | USE_SAFE_ALLOCA; |
| 1834 | 1957 | ||
| 1835 | len = ASIZE (vec); | 1958 | len = ASIZE (vec); |
| 1836 | if (len <= 1) | 1959 | if (len <= 1) |
| 1837 | return vec; | 1960 | return vec; |
| 1838 | 1961 | ||
| 1839 | size = AREF (spec, FONT_SIZE_INDEX); | 1962 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++) |
| 1840 | if (FLOATP (size)) | 1963 | prefer_prop[i] = AREF (prefer, i); |
| 1841 | { | ||
| 1842 | double point_size = XFLOAT_DATA (size) * 10; | ||
| 1843 | int pixel_size = POINT_TO_PIXEL (point_size, XFRAME (frame)->resy); | ||
| 1844 | |||
| 1845 | prefer = Fcopy_sequence (prefer); | ||
| 1846 | ASET (prefer, FONT_SIZE_INDEX, make_number (pixel_size)); | ||
| 1847 | prefer_is_copy = 1; | ||
| 1848 | } | ||
| 1849 | 1964 | ||
| 1850 | if (! NILP (spec)) | 1965 | if (! NILP (spec)) |
| 1851 | { | 1966 | { |
| 1852 | /* As it is assured that all fonts in VEC match with SPEC, we | 1967 | /* As it is assured that all fonts in VEC match with SPEC, we |
| 1853 | should ignore properties specified in SPEC. So, set the | 1968 | should ignore properties specified in SPEC. So, set the |
| 1854 | corresponding properties in PREFER nil. */ | 1969 | corresponding properties in PREFER_PROP to nil. */ |
| 1855 | for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++) | 1970 | for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++) |
| 1856 | if (! NILP (AREF (spec, i)) && ! NILP (AREF (prefer, i))) | 1971 | if (! NILP (AREF (spec, i))) |
| 1857 | break; | 1972 | prefer_prop[i++] = Qnil; |
| 1858 | if (i <= FONT_SIZE_INDEX) | ||
| 1859 | { | ||
| 1860 | if (! prefer_is_copy) | ||
| 1861 | prefer = Fcopy_sequence (prefer); | ||
| 1862 | for (; i <= FONT_SIZE_INDEX; i++) | ||
| 1863 | if (! NILP (AREF (spec, i)) && ! NILP (AREF (prefer, i))) | ||
| 1864 | ASET (prefer, i, Qnil); | ||
| 1865 | } | ||
| 1866 | } | 1973 | } |
| 1867 | 1974 | ||
| 1975 | if (FLOATP (prefer_prop[FONT_SIZE_INDEX])) | ||
| 1976 | prefer_prop[FONT_SIZE_INDEX] | ||
| 1977 | = make_number (font_pixel_size (XFRAME (frame), prefer)); | ||
| 1978 | |||
| 1868 | /* Scoring and sorting. */ | 1979 | /* Scoring and sorting. */ |
| 1869 | SAFE_ALLOCA (data, struct font_sort_data *, (sizeof *data) * len); | 1980 | SAFE_ALLOCA (data, struct font_sort_data *, (sizeof *data) * len); |
| 1870 | for (i = 0; i < len; i++) | 1981 | for (i = 0; i < len; i++) |
| 1871 | { | 1982 | { |
| 1872 | data[i].entity = AREF (vec, i); | 1983 | data[i].entity = AREF (vec, i); |
| 1873 | data[i].score = font_score (data[i].entity, prefer); | 1984 | data[i].score = font_score (data[i].entity, prefer_prop); |
| 1874 | } | 1985 | } |
| 1875 | qsort (data, len, sizeof *data, font_compare); | 1986 | qsort (data, len, sizeof *data, font_compare); |
| 1876 | for (i = 0; i < len; i++) | 1987 | for (i = 0; i < len; i++) |
| @@ -2004,7 +2115,7 @@ font_list_entities (frame, spec) | |||
| 2004 | } | 2115 | } |
| 2005 | size = AREF (spec, FONT_SIZE_INDEX); | 2116 | size = AREF (spec, FONT_SIZE_INDEX); |
| 2006 | if (FLOATP (size)) | 2117 | if (FLOATP (size)) |
| 2007 | ASET (spec, FONT_SIZE_INDEX, POINT_TO_PIXEL (size * 10, f->resy)); | 2118 | ASET (spec, FONT_SIZE_INDEX, make_number (font_pixel_size (f, spec))); |
| 2008 | 2119 | ||
| 2009 | xassert (ASIZE (spec) == FONT_SPEC_MAX); | 2120 | xassert (ASIZE (spec) == FONT_SPEC_MAX); |
| 2010 | ftype = AREF (spec, FONT_TYPE_INDEX); | 2121 | ftype = AREF (spec, FONT_TYPE_INDEX); |
| @@ -2238,7 +2349,7 @@ font_find_for_lface (f, lface, spec) | |||
| 2238 | if (ASIZE (entities) > 1) | 2349 | if (ASIZE (entities) > 1) |
| 2239 | { | 2350 | { |
| 2240 | Lisp_Object prefer = scratch_font_prefer, val; | 2351 | Lisp_Object prefer = scratch_font_prefer, val; |
| 2241 | int size; | 2352 | double pt; |
| 2242 | 2353 | ||
| 2243 | ASET (prefer, FONT_WEIGHT_INDEX, | 2354 | ASET (prefer, FONT_WEIGHT_INDEX, |
| 2244 | font_prop_validate_style (FONT_WEIGHT_INDEX, | 2355 | font_prop_validate_style (FONT_WEIGHT_INDEX, |
| @@ -2249,9 +2360,8 @@ font_find_for_lface (f, lface, spec) | |||
| 2249 | ASET (prefer, FONT_WIDTH_INDEX, | 2360 | ASET (prefer, FONT_WIDTH_INDEX, |
| 2250 | font_prop_validate_style (FONT_WIDTH_INDEX, | 2361 | font_prop_validate_style (FONT_WIDTH_INDEX, |
| 2251 | lface[LFACE_SWIDTH_INDEX])); | 2362 | lface[LFACE_SWIDTH_INDEX])); |
| 2252 | val = lface[LFACE_HEIGHT_INDEX]; | 2363 | pt = XINT (lface[LFACE_HEIGHT_INDEX]); |
| 2253 | size = POINT_TO_PIXEL (XINT (val), f->resy); | 2364 | ASET (prefer, FONT_SIZE_INDEX, make_float (pt / 10)); |
| 2254 | ASET (prefer, FONT_SIZE_INDEX, make_number (size)); | ||
| 2255 | 2365 | ||
| 2256 | font_sort_entites (entities, prefer, frame, spec); | 2366 | font_sort_entites (entities, prefer, frame, spec); |
| 2257 | } | 2367 | } |
| @@ -2265,9 +2375,11 @@ font_open_for_lface (f, lface, entity) | |||
| 2265 | Lisp_Object *lface; | 2375 | Lisp_Object *lface; |
| 2266 | Lisp_Object entity; | 2376 | Lisp_Object entity; |
| 2267 | { | 2377 | { |
| 2268 | int pt = XINT (lface[LFACE_HEIGHT_INDEX]); | 2378 | double pt = XINT (lface[LFACE_HEIGHT_INDEX]); |
| 2269 | int size = POINT_TO_PIXEL (pt, f->resy); | 2379 | int size; |
| 2270 | 2380 | ||
| 2381 | pt /= 10; | ||
| 2382 | size = POINT_TO_PIXEL (pt, f->resy); | ||
| 2271 | return font_open_entity (f, entity, size); | 2383 | return font_open_entity (f, entity, size); |
| 2272 | } | 2384 | } |
| 2273 | 2385 | ||
| @@ -2356,7 +2468,7 @@ font_open_by_name (f, name) | |||
| 2356 | pixel_size = XINT (size); | 2468 | pixel_size = XINT (size); |
| 2357 | else /* FLOATP (size) */ | 2469 | else /* FLOATP (size) */ |
| 2358 | { | 2470 | { |
| 2359 | double pt = XFLOAT_DATA (size) * 10; | 2471 | double pt = XFLOAT_DATA (size); |
| 2360 | 2472 | ||
| 2361 | pixel_size = POINT_TO_PIXEL (pt, f->resy); | 2473 | pixel_size = POINT_TO_PIXEL (pt, f->resy); |
| 2362 | size = make_number (pixel_size); | 2474 | size = make_number (pixel_size); |
| @@ -2364,10 +2476,12 @@ font_open_by_name (f, name) | |||
| 2364 | } | 2476 | } |
| 2365 | if (pixel_size == 0) | 2477 | if (pixel_size == 0) |
| 2366 | { | 2478 | { |
| 2367 | pixel_size = POINT_TO_PIXEL (120.0, f->resy); | 2479 | pixel_size = POINT_TO_PIXEL (12.0, f->resy); |
| 2368 | size = make_number (pixel_size); | 2480 | size = make_number (pixel_size); |
| 2369 | } | 2481 | } |
| 2370 | ASET (prefer, FONT_SIZE_INDEX, size); | 2482 | ASET (prefer, FONT_SIZE_INDEX, size); |
| 2483 | if (NILP (AREF (spec, FONT_REGISTRY_INDEX))) | ||
| 2484 | ASET (spec, FONT_REGISTRY_INDEX, Qiso8859_1); | ||
| 2371 | 2485 | ||
| 2372 | entities = Flist_fonts (spec, frame, make_number (1), prefer); | 2486 | entities = Flist_fonts (spec, frame, make_number (1), prefer); |
| 2373 | return (NILP (entities) | 2487 | return (NILP (entities) |
| @@ -2451,7 +2565,7 @@ usage: (font-spec &rest properties) */) | |||
| 2451 | Lisp_Object *args; | 2565 | Lisp_Object *args; |
| 2452 | { | 2566 | { |
| 2453 | Lisp_Object spec = Fmake_vector (make_number (FONT_SPEC_MAX), Qnil); | 2567 | Lisp_Object spec = Fmake_vector (make_number (FONT_SPEC_MAX), Qnil); |
| 2454 | Lisp_Object extra = Qnil; | 2568 | Lisp_Object extra = Qnil, name = Qnil; |
| 2455 | int i; | 2569 | int i; |
| 2456 | 2570 | ||
| 2457 | for (i = 0; i < nargs; i += 2) | 2571 | for (i = 0; i < nargs; i += 2) |
| @@ -2465,11 +2579,14 @@ usage: (font-spec &rest properties) */) | |||
| 2465 | else | 2579 | else |
| 2466 | { | 2580 | { |
| 2467 | if (EQ (key, QCname)) | 2581 | if (EQ (key, QCname)) |
| 2468 | font_parse_name ((char *) SDATA (val), spec, 0); | 2582 | name = val; |
| 2469 | extra = Fcons (Fcons (key, val), extra); | 2583 | else |
| 2584 | extra = Fcons (Fcons (key, val), extra); | ||
| 2470 | } | 2585 | } |
| 2471 | } | 2586 | } |
| 2472 | ASET (spec, FONT_EXTRA_INDEX, extra); | 2587 | ASET (spec, FONT_EXTRA_INDEX, extra); |
| 2588 | if (STRINGP (name)) | ||
| 2589 | font_parse_name (SDATA (name), spec, 0); | ||
| 2473 | return spec; | 2590 | return spec; |
| 2474 | } | 2591 | } |
| 2475 | 2592 | ||
| @@ -3020,6 +3137,8 @@ syms_of_font () | |||
| 3020 | DEFSYM (QCfoundry, ":foundry"); | 3137 | DEFSYM (QCfoundry, ":foundry"); |
| 3021 | DEFSYM (QCadstyle, ":adstyle"); | 3138 | DEFSYM (QCadstyle, ":adstyle"); |
| 3022 | DEFSYM (QCregistry, ":registry"); | 3139 | DEFSYM (QCregistry, ":registry"); |
| 3140 | DEFSYM (QCspacing, ":spacing"); | ||
| 3141 | DEFSYM (QCdpi, ":dpi"); | ||
| 3023 | DEFSYM (QCextra, ":extra"); | 3142 | DEFSYM (QCextra, ":extra"); |
| 3024 | 3143 | ||
| 3025 | staticpro (&null_string); | 3144 | staticpro (&null_string); |