aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2006-06-19 12:43:59 +0000
committerKenichi Handa2006-06-19 12:43:59 +0000
commit9331887d8d56a6a40f4a8fcc19f66b0ccb307e9d (patch)
tree962a764d1350ccc247b4841fa9c12306004d99d6 /src
parent63565713ad24051f6a1d4422863a7921cedc8f27 (diff)
downloademacs-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.c341
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;
99extern Lisp_Object QCtype, QCfamily, QCweight, QCslant, QCwidth, QCsize, QCname; 101extern Lisp_Object QCtype, QCfamily, QCweight, QCslant, QCwidth, QCsize, QCname;
100Lisp_Object QCfoundry, QCadstyle, QCregistry, QCextra; 102Lisp_Object QCfoundry, QCadstyle, QCregistry, QCextra;
101/* Symbols representing keys of font extra info. */ 103/* Symbols representing keys of font extra info. */
102Lisp_Object QCotf, QClanguage, QCscript; 104Lisp_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. */
115static int num_font_drivers; 117static int num_font_drivers;
116 118
119/* Return a pixel size of font-spec SPEC on frame F. */
120static int
121font_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
377static void
378font_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
641int 701int
642font_parse_xlfd (name, font, merge) 702font_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
978int 1041int
979font_parse_fcname (name, font, merge) 1042font_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
1737static unsigned font_score P_ ((Lisp_Object, Lisp_Object)); 1858static unsigned font_score P_ ((Lisp_Object, Lisp_Object *));
1738static int font_compare P_ ((const void *, const void *)); 1859static int font_compare P_ ((const void *, const void *));
1739static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object, 1860static 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. */
1754static int sort_shift_bits[FONT_SIZE_INDEX + 1]; 1875static 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
1759static unsigned 1881static unsigned
1760font_score (entity, spec) 1882font_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
1825static Lisp_Object 1949static Lisp_Object
1826font_sort_entites (vec, prefer, frame, spec) 1950font_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);