Mercurial > emacs
annotate src/ftfont.c @ 90500:60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
scalable.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Wed, 28 Jun 2006 05:40:15 +0000 |
parents | 908d27653432 |
children | 69dc5ab6d693 |
rev | line source |
---|---|
90400 | 1 /* ftfont.c -- FreeType font driver. |
2 Copyright (C) 2006 Free Software Foundation, Inc. | |
3 Copyright (C) 2006 | |
4 National Institute of Advanced Industrial Science and Technology (AIST) | |
5 Registration Number H13PRO009 | |
6 | |
7 This file is part of GNU Emacs. | |
8 | |
9 GNU Emacs is free software; you can redistribute it and/or modify | |
10 it under the terms of the GNU General Public License as published by | |
11 the Free Software Foundation; either version 2, or (at your option) | |
12 any later version. | |
13 | |
14 GNU Emacs is distributed in the hope that it will be useful, | |
15 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 GNU General Public License for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with GNU Emacs; see the file COPYING. If not, write to | |
21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
22 Boston, MA 02110-1301, USA. */ | |
23 | |
24 #include <config.h> | |
25 #include <stdio.h> | |
26 | |
27 #include <ft2build.h> | |
28 #include FT_FREETYPE_H | |
29 #include FT_SIZES_H | |
30 #include <fontconfig/fontconfig.h> | |
31 #include <fontconfig/fcfreetype.h> | |
32 | |
33 #include "lisp.h" | |
34 #include "dispextern.h" | |
35 #include "frame.h" | |
36 #include "blockinput.h" | |
37 #include "character.h" | |
38 #include "charset.h" | |
39 #include "coding.h" | |
40 #include "fontset.h" | |
41 #include "font.h" | |
42 | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
43 /* Symbolic type of this font-driver. */ |
90400 | 44 Lisp_Object Qfreetype; |
45 | |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
46 /* Fontconfig's generic families and their aliases. */ |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
47 static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
48 |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
49 /* Flag to tell if FcInit is areadly called or not. */ |
90400 | 50 static int fc_initialized; |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
51 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
52 /* Handle to a FreeType library instance. */ |
90400 | 53 static FT_Library ft_library; |
54 | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
55 /* Cache for FreeType fonts. */ |
90400 | 56 static Lisp_Object freetype_font_cache; |
57 | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
58 /* Fontconfig's charset used for finding fonts of registry |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
59 "iso8859-1". */ |
90400 | 60 static FcCharSet *cs_iso8859_1; |
61 | |
62 /* The actual structure for FreeType font that can be casted to struct | |
63 font. */ | |
64 | |
65 struct ftfont_info | |
66 { | |
67 struct font font; | |
68 FT_Size ft_size; | |
69 }; | |
70 | |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
71 static int ftfont_build_basic_charsets P_ ((void)); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
72 static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
73 Lisp_Object, Lisp_Object)); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
74 static Lisp_Object ftfont_list_generic_family P_ ((Lisp_Object, Lisp_Object, |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
75 Lisp_Object)); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
76 |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
77 #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM)) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
78 |
90400 | 79 static int |
80 ftfont_build_basic_charsets () | |
81 { | |
82 FcChar32 c; | |
83 | |
84 cs_iso8859_1 = FcCharSetCreate (); | |
85 if (! cs_iso8859_1) | |
86 return -1; | |
87 for (c = ' '; c < 127; c++) | |
88 if (! FcCharSetAddChar (cs_iso8859_1, c)) | |
89 return -1; | |
90 for (c = 192; c < 256; c++) | |
91 if (! FcCharSetAddChar (cs_iso8859_1, c)) | |
92 return -1; | |
93 return 0; | |
94 } | |
95 | |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
96 static Lisp_Object |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
97 ftfont_pattern_entity (p, frame, registry) |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
98 FcPattern *p; |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
99 Lisp_Object frame, registry; |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
100 { |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
101 Lisp_Object entity; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
102 FcChar8 *file; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
103 FcCharSet *charset; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
104 char *str; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
105 int numeric; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
106 double dbl; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
107 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
108 if (FcPatternGetString (p, FC_FILE, 0, &file) != FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
109 return Qnil; |
90450
5c96354daf9e
(ftfont_pattern_entity): Fix typo.
Kenichi Handa <handa@m17n.org>
parents:
90441
diff
changeset
|
110 if (FcPatternGetCharSet (p, FC_CHARSET, 0, &charset) != FcResultMatch) |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
111 charset = NULL; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
112 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
113 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), null_string); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
114 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
115 ASET (entity, FONT_TYPE_INDEX, Qfreetype); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
116 ASET (entity, FONT_REGISTRY_INDEX, registry); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
117 ASET (entity, FONT_FRAME_INDEX, frame); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
118 ASET (entity, FONT_OBJLIST_INDEX, Qnil); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
119 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
120 if (FcPatternGetString (p, FC_FOUNDRY, 0, (FcChar8 **) &str) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
121 ASET (entity, FONT_FOUNDRY_INDEX, intern_downcase (str, strlen (str))); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
122 if (FcPatternGetString (p, FC_FAMILY, 0, (FcChar8 **) &str) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
123 ASET (entity, FONT_FAMILY_INDEX, intern_downcase (str, strlen (str))); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
124 if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) |
90474
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
125 { |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
126 if (numeric == FC_WEIGHT_REGULAR) |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
127 numeric = 100; |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
128 ASET (entity, FONT_WEIGHT_INDEX, make_number (numeric)); |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
129 } |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
130 if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
131 ASET (entity, FONT_SLANT_INDEX, make_number (numeric + 100)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
132 if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
133 ASET (entity, FONT_WIDTH_INDEX, make_number (numeric)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
134 if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
135 ASET (entity, FONT_SIZE_INDEX, make_number (dbl)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
136 else |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
137 ASET (entity, FONT_SIZE_INDEX, make_number (0)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
138 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
139 if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) != FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
140 numeric = FC_MONO; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
141 file = FcStrCopy (file); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
142 if (! file) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
143 return Qnil; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
144 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
145 p = FcPatternCreate (); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
146 if (! p) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
147 return Qnil; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
148 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
149 if (FcPatternAddString (p, FC_FILE, file) == FcFalse |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
150 || (charset && FcPatternAddCharSet (p, FC_CHARSET, charset) == FcFalse) |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
151 || FcPatternAddInteger (p, FC_SPACING, numeric) == FcFalse) |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
152 { |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
153 FcPatternDestroy (p); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
154 return Qnil; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
155 } |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
156 ASET (entity, FONT_EXTRA_INDEX, make_save_value (p, 0)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
157 return entity; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
158 } |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
159 |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
160 static Lisp_Object ftfont_generic_family_list; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
161 |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
162 static Lisp_Object |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
163 ftfont_list_generic_family (spec, frame, registry) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
164 Lisp_Object spec, frame, registry; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
165 { |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
166 Lisp_Object family = AREF (spec, FONT_FAMILY_INDEX); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
167 Lisp_Object slot, list, val; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
168 |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
169 if (EQ (family, Qmono)) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
170 family = Qmonospace; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
171 else if (EQ (family, Qsans) || EQ (family, Qsans__serif)) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
172 family = Qsans_serif; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
173 slot = assq_no_quit (family, ftfont_generic_family_list); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
174 if (! CONSP (slot)) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
175 return null_vector; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
176 list = XCDR (slot); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
177 if (EQ (list, Qt)) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
178 { |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
179 /* Not yet listed. */ |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
180 FcObjectSet *objset = NULL; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
181 FcPattern *pattern = NULL, *pat = NULL; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
182 FcFontSet *fontset = NULL; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
183 FcChar8 *fam; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
184 int i, j; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
185 |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
186 objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
187 FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
188 FC_CHARSET, FC_FILE, NULL); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
189 if (! objset) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
190 goto err; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
191 pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
192 SYMBOL_FcChar8 (family), (char *) 0); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
193 if (! pattern) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
194 goto err; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
195 pat = FcPatternCreate (); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
196 if (! pat) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
197 goto err; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
198 FcConfigSubstitute (NULL, pattern, FcMatchPattern); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
199 for (i = 0, val = Qnil; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
200 FcPatternGetString (pattern, FC_FAMILY, i, &fam) == FcResultMatch; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
201 i++) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
202 { |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
203 if (strcmp ((char *) fam, (char *) SYMBOL_FcChar8 (family)) == 0) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
204 continue; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
205 if (! FcPatternAddString (pat, FC_FAMILY, fam)) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
206 goto err; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
207 fontset = FcFontList (NULL, pat, objset); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
208 if (! fontset) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
209 goto err; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
210 /* Here we build the list in reverse order so that the last |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
211 loop in this function build a list in the correct |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
212 order. */ |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
213 for (j = 0; j < fontset->nfont; j++) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
214 { |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
215 Lisp_Object entity; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
216 |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
217 entity = ftfont_pattern_entity (fontset->fonts[j], |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
218 frame, registry); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
219 if (! NILP (entity)) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
220 val = Fcons (entity, val); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
221 } |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
222 FcFontSetDestroy (fontset); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
223 fontset = NULL; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
224 FcPatternDel (pat, FC_FAMILY); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
225 } |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
226 list = val; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
227 XSETCDR (slot, list); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
228 err: |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
229 if (pat) FcPatternDestroy (pat); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
230 if (pattern) FcPatternDestroy (pattern); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
231 if (fontset) FcFontSetDestroy (fontset); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
232 if (objset) FcObjectSetDestroy (objset); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
233 if (EQ (list, Qt)) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
234 return Qnil; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
235 } |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
236 ASET (spec, FONT_FAMILY_INDEX, Qnil); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
237 for (val = Qnil; CONSP (list); list = XCDR (list)) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
238 if (font_match_p (spec, XCAR (list))) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
239 val = Fcons (XCAR (list), val); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
240 ASET (spec, FONT_FAMILY_INDEX, family); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
241 return Fvconcat (1, &val); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
242 } |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
243 |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
244 |
90400 | 245 static Lisp_Object ftfont_get_cache P_ ((Lisp_Object)); |
246 static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); | |
247 static Lisp_Object ftfont_list_family P_ ((Lisp_Object)); | |
248 static void ftfont_free_entity P_ ((Lisp_Object)); | |
249 static struct font *ftfont_open P_ ((FRAME_PTR, Lisp_Object, int)); | |
250 static void ftfont_close P_ ((FRAME_PTR, struct font *)); | |
251 static int ftfont_has_char P_ ((Lisp_Object, int)); | |
252 static unsigned ftfont_encode_char P_ ((struct font *, int)); | |
253 static int ftfont_text_extents P_ ((struct font *, unsigned *, int, | |
254 struct font_metrics *)); | |
255 static int ftfont_get_bitmap P_ ((struct font *, unsigned, | |
256 struct font_bitmap *, int)); | |
257 static int ftfont_anchor_point P_ ((struct font *, unsigned, int, | |
258 int *, int *)); | |
259 | |
260 struct font_driver ftfont_driver = | |
261 { | |
262 (Lisp_Object) NULL, /* Qfreetype */ | |
263 ftfont_get_cache, | |
264 ftfont_list, | |
265 ftfont_list_family, | |
266 ftfont_free_entity, | |
267 ftfont_open, | |
268 ftfont_close, | |
269 /* We can't draw a text without device dependent functions. */ | |
270 NULL, | |
271 NULL, | |
272 ftfont_has_char, | |
273 ftfont_encode_char, | |
274 ftfont_text_extents, | |
275 /* We can't draw a text without device dependent functions. */ | |
276 NULL, | |
277 ftfont_get_bitmap, | |
278 NULL, | |
279 NULL, | |
280 NULL, | |
281 ftfont_anchor_point, | |
282 #ifdef HAVE_LIBOTF | |
283 font_otf_capability, | |
284 font_otf_gsub, | |
285 font_otf_gpos | |
286 #else | |
287 NULL, | |
288 NULL, | |
289 NULL | |
290 #endif /* HAVE_LIBOTF */ | |
291 }; | |
292 | |
293 extern Lisp_Object QCname; | |
294 | |
295 static Lisp_Object | |
296 ftfont_get_cache (frame) | |
297 Lisp_Object frame; | |
298 { | |
299 return freetype_font_cache; | |
300 } | |
301 | |
302 static Lisp_Object | |
303 ftfont_list (frame, spec) | |
304 Lisp_Object frame, spec; | |
305 { | |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
306 Lisp_Object val, tmp, extra, font_name; |
90400 | 307 int i; |
308 FcPattern *pattern = NULL; | |
309 FcCharSet *charset = NULL; | |
310 FcLangSet *langset = NULL; | |
311 FcFontSet *fontset = NULL; | |
312 FcObjectSet *objset = NULL; | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
313 Lisp_Object registry = Qunicode_bmp; |
90480
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
314 int weight = 0; |
90500
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
315 double dpi = -1; |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
316 int spacing = -1; |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
317 int scalable = -1; |
90400 | 318 |
319 val = null_vector; | |
320 | |
321 if (! fc_initialized) | |
322 { | |
323 FcInit (); | |
324 fc_initialized = 1; | |
325 } | |
326 | |
90480
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
327 if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX)) |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
328 && ! EQ (AREF (spec, FONT_ADSTYLE_INDEX), null_string)) |
90400 | 329 return val; |
90480
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
330 if (! NILP (AREF (spec, FONT_SLANT_INDEX)) |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
331 && XINT (AREF (spec, FONT_SLANT_INDEX)) < 100) |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
332 /* Fontconfig doesn't support reverse-italic/obligue. */ |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
333 return val; |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
334 |
90400 | 335 if (! NILP (AREF (spec, FONT_REGISTRY_INDEX))) |
336 { | |
337 registry = AREF (spec, FONT_REGISTRY_INDEX); | |
338 if (EQ (registry, Qiso8859_1)) | |
339 { | |
340 if (! cs_iso8859_1 | |
341 && ftfont_build_basic_charsets () < 0) | |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
342 return Qnil; |
90400 | 343 charset = cs_iso8859_1; |
344 } | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
345 else if (! EQ (registry, Qiso10646_1) && ! EQ (registry, Qunicode_bmp)) |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
346 return val; |
90400 | 347 } |
348 | |
349 extra = AREF (spec, FONT_EXTRA_INDEX); | |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
350 font_name = Qnil; |
90400 | 351 if (CONSP (extra)) |
352 { | |
90500
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
353 tmp = assq_no_quit (QCname, extra); |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
354 if (CONSP (tmp)) |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
355 { |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
356 font_name = XCDR (tmp); |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
357 if (SDATA (font_name)[0] != ':') |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
358 return val; |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
359 } |
90480
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
360 tmp = assq_no_quit (QCotf, extra); |
90400 | 361 if (! NILP (tmp)) |
362 return val; | |
90480
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
363 tmp = assq_no_quit (QClanguage, extra); |
90400 | 364 if (CONSP (tmp)) |
365 { | |
366 langset = FcLangSetCreate (); | |
367 if (! langset) | |
368 goto err; | |
369 tmp = XCDR (tmp); | |
370 if (SYMBOLP (tmp)) | |
371 { | |
372 if (! FcLangSetAdd (langset, SYMBOL_FcChar8 (tmp))) | |
373 goto err; | |
374 } | |
375 else | |
376 while (CONSP (tmp)) | |
377 { | |
378 if (SYMBOLP (XCAR (tmp)) | |
379 && ! FcLangSetAdd (langset, SYMBOL_FcChar8 (XCAR (tmp)))) | |
380 goto err; | |
381 tmp = XCDR (tmp); | |
382 } | |
383 } | |
90480
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
384 tmp = assq_no_quit (QCscript, extra); |
90400 | 385 if (CONSP (tmp) && ! charset) |
386 { | |
387 Lisp_Object script = XCDR (tmp); | |
388 Lisp_Object chars = assq_no_quit (script, | |
389 Vscript_representative_chars); | |
390 | |
391 if (CONSP (chars)) | |
392 { | |
393 charset = FcCharSetCreate (); | |
394 if (! charset) | |
395 goto err; | |
396 for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars)) | |
397 if (CHARACTERP (XCAR (chars)) | |
398 && ! FcCharSetAddChar (charset, XUINT (XCAR (chars)))) | |
399 goto err; | |
400 } | |
401 } | |
90500
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
402 tmp = assq_no_quit (QCdpi, extra); |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
403 if (CONSP (tmp)) |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
404 dpi = XINT (XCDR (tmp)); |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
405 tmp = assq_no_quit (QCspacing, extra); |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
406 if (CONSP (tmp)) |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
407 spacing = XINT (XCDR (tmp)); |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
408 tmp = assq_no_quit (QCscalable, extra); |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
409 if (CONSP (tmp)) |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
410 spacing = ! NILP (XCDR (tmp)); |
90400 | 411 } |
412 | |
413 if (STRINGP (font_name)) | |
90480
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
414 pattern = FcNameParse (SDATA (font_name)); |
90400 | 415 else |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
416 pattern = FcPatternCreate (); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
417 if (! pattern) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
418 goto err; |
90400 | 419 |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
420 tmp = AREF (spec, FONT_FOUNDRY_INDEX); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
421 if (SYMBOLP (tmp) && ! NILP (tmp) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
422 && ! FcPatternAddString (pattern, FC_FOUNDRY, SYMBOL_FcChar8 (tmp))) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
423 goto err; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
424 tmp = AREF (spec, FONT_FAMILY_INDEX); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
425 if (SYMBOLP (tmp) && ! NILP (tmp) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
426 && ! FcPatternAddString (pattern, FC_FAMILY, SYMBOL_FcChar8 (tmp))) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
427 goto err; |
90480
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
428 /* Emacs conventionally doesn't distinguish normal, regular, and |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
429 medium weight, but fontconfig does. So, we can't restrict font |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
430 listing by weight. We check it after getting a list. */ |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
431 tmp = AREF (spec, FONT_WEIGHT_INDEX); |
90480
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
432 if (INTEGERP (tmp)) |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
433 weight = XINT (tmp); |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
434 tmp = AREF (spec, FONT_SLANT_INDEX); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
435 if (INTEGERP (tmp) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
436 && ! FcPatternAddInteger (pattern, FC_SLANT, XINT (tmp) - 100)) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
437 goto err; |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
438 tmp = AREF (spec, FONT_WIDTH_INDEX); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
439 if (INTEGERP (tmp) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
440 && ! FcPatternAddInteger (pattern, FC_WIDTH, XINT (tmp))) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
441 goto err; |
90400 | 442 |
443 if (charset | |
444 && ! FcPatternAddCharSet (pattern, FC_CHARSET, charset)) | |
445 goto err; | |
446 if (langset | |
447 && ! FcPatternAddLangSet (pattern, FC_LANG, langset)) | |
448 goto err; | |
90500
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
449 if (dpi >= 0 |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
450 && ! FcPatternAddDouble (pattern, FC_DPI, dpi)) |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
451 goto err; |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
452 if (spacing >= 0 |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
453 && ! FcPatternAddInteger (pattern, FC_SPACING, spacing)) |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
454 goto err; |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
455 if (scalable >= 0 |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
456 && ! FcPatternAddBool (pattern, FC_SPACING, spacing ? FcTrue : FcFalse)) |
60e0667ab709
(ftfont_list): Handle properties dpi, spacing, and
Kenichi Handa <handa@m17n.org>
parents:
90480
diff
changeset
|
457 goto err; |
90400 | 458 |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
459 objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
460 FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
461 FC_CHARSET, FC_FILE, NULL); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
462 if (! objset) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
463 goto err; |
90474
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
464 |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
465 fontset = FcFontList (NULL, pattern, objset); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
466 if (! fontset) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
467 goto err; |
90400 | 468 |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
469 if (fontset->nfont > 0) |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
470 { |
90474
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
471 double pixel_size; |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
472 |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
473 if (NILP (AREF (spec, FONT_SIZE_INDEX))) |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
474 pixel_size = 0; |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
475 else |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
476 pixel_size = XINT (AREF (spec, FONT_SIZE_INDEX)); |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
477 |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
478 for (i = 0, val = Qnil; i < fontset->nfont; i++) |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
479 { |
90474
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
480 Lisp_Object entity; |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
481 |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
482 if (pixel_size > 0) |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
483 { |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
484 double this; |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
485 |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
486 if (FcPatternGetDouble (fontset->fonts[i], FC_PIXEL_SIZE, 0, |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
487 &this) == FcResultMatch |
90480
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
488 && ((this < pixel_size - FONT_PIXEL_SIZE_QUANTUM) |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
489 || (this > pixel_size + FONT_PIXEL_SIZE_QUANTUM))) |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
490 continue; |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
491 } |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
492 if (weight > 0) |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
493 { |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
494 int this; |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
495 |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
496 if (FcPatternGetInteger (fontset->fonts[i], FC_WEIGHT, 0, |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
497 &this) != FcResultMatch |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
498 || (this != weight |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
499 && (weight != 100 |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
500 || this < FC_WEIGHT_REGULAR |
908d27653432
(ftfont_list): Use assq_no_quit, not Fassq. Don't
Kenichi Handa <handa@m17n.org>
parents:
90474
diff
changeset
|
501 || this > FC_WEIGHT_MEDIUM))) |
90474
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
502 continue; |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
503 } |
8627c9321afb
(ftfont_pattern_entity): Use the numeric value 100 for
Kenichi Handa <handa@m17n.org>
parents:
90464
diff
changeset
|
504 entity = ftfont_pattern_entity (fontset->fonts[i], frame, registry); |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
505 if (! NILP (entity)) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
506 val = Fcons (entity, val); |
90400 | 507 } |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
508 val = Fvconcat (1, &val); |
90400 | 509 } |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
510 else if (! NILP (AREF (spec, FONT_FAMILY_INDEX))) |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
511 val = ftfont_list_generic_family (spec, frame, registry); |
90400 | 512 goto finish; |
513 | |
514 err: | |
515 /* We come here because of unexpected error in fontconfig API call | |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
516 (usually insufficient memory). */ |
90400 | 517 val = Qnil; |
518 | |
519 finish: | |
520 if (charset && charset != cs_iso8859_1) FcCharSetDestroy (charset); | |
521 if (objset) FcObjectSetDestroy (objset); | |
522 if (fontset) FcFontSetDestroy (fontset); | |
523 if (langset) FcLangSetDestroy (langset); | |
524 if (pattern) FcPatternDestroy (pattern); | |
525 | |
526 return val; | |
527 } | |
528 | |
529 static Lisp_Object | |
530 ftfont_list_family (frame) | |
531 Lisp_Object frame; | |
532 { | |
533 Lisp_Object list; | |
534 FcPattern *pattern = NULL; | |
535 FcFontSet *fontset = NULL; | |
536 FcObjectSet *objset = NULL; | |
537 int i; | |
538 | |
539 if (! fc_initialized) | |
540 { | |
541 FcInit (); | |
542 fc_initialized = 1; | |
543 } | |
544 | |
545 pattern = FcPatternCreate (); | |
546 if (! pattern) | |
547 goto finish; | |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
548 objset = FcObjectSetBuild (FC_FAMILY, NULL); |
90400 | 549 if (! objset) |
550 goto finish; | |
551 fontset = FcFontList (NULL, pattern, objset); | |
552 if (! fontset) | |
553 goto finish; | |
554 | |
555 list = Qnil; | |
556 for (i = 0; i < fontset->nfont; i++) | |
557 { | |
558 FcPattern *pat = fontset->fonts[i]; | |
559 FcChar8 *str; | |
560 | |
561 if (FcPatternGetString (pat, FC_FAMILY, 0, &str) == FcResultMatch) | |
562 list = Fcons (intern_downcase ((char *) str, strlen ((char *) str)), | |
563 list); | |
564 } | |
565 | |
566 finish: | |
567 if (objset) FcObjectSetDestroy (objset); | |
568 if (fontset) FcFontSetDestroy (fontset); | |
569 if (pattern) FcPatternDestroy (pattern); | |
570 | |
571 return list; | |
572 } | |
573 | |
574 | |
575 static void | |
576 ftfont_free_entity (entity) | |
577 Lisp_Object entity; | |
578 { | |
579 Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX); | |
580 FcPattern *pattern = XSAVE_VALUE (val)->pointer; | |
581 | |
582 FcPatternDestroy (pattern); | |
583 } | |
584 | |
585 static struct font * | |
586 ftfont_open (f, entity, pixel_size) | |
587 FRAME_PTR f; | |
588 Lisp_Object entity; | |
589 int pixel_size; | |
590 { | |
591 struct ftfont_info *ftfont_info; | |
592 struct font *font; | |
593 FT_Face ft_face; | |
594 FT_Size ft_size; | |
595 FT_UInt size; | |
596 Lisp_Object val; | |
597 FcPattern *pattern; | |
598 FcChar8 *file; | |
599 int spacing; | |
600 | |
601 val = AREF (entity, FONT_EXTRA_INDEX); | |
602 if (XTYPE (val) != Lisp_Misc | |
603 || XMISCTYPE (val) != Lisp_Misc_Save_Value) | |
604 return NULL; | |
605 pattern = XSAVE_VALUE (val)->pointer; | |
606 if (XSAVE_VALUE (val)->integer == 0) | |
607 { | |
608 /* We have not yet created FT_Face for this font. */ | |
609 if (! ft_library | |
610 && FT_Init_FreeType (&ft_library) != 0) | |
611 return NULL; | |
612 if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch) | |
613 return NULL; | |
614 if (FT_New_Face (ft_library, (char *) file, 0, &ft_face) != 0) | |
615 return NULL; | |
616 FcPatternAddFTFace (pattern, FC_FT_FACE, ft_face); | |
617 ft_size = ft_face->size; | |
618 } | |
619 else | |
620 { | |
621 if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &ft_face) | |
622 != FcResultMatch) | |
623 return NULL; | |
624 if (FT_New_Size (ft_face, &ft_size) != 0) | |
625 return NULL; | |
626 if (FT_Activate_Size (ft_size) != 0) | |
627 { | |
628 FT_Done_Size (ft_size); | |
629 return NULL; | |
630 } | |
631 } | |
632 | |
633 size = XINT (AREF (entity, FONT_SIZE_INDEX)); | |
634 if (size == 0) | |
635 size = pixel_size; | |
636 if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0) | |
637 { | |
638 if (XSAVE_VALUE (val)->integer == 0) | |
639 FT_Done_Face (ft_face); | |
640 return NULL; | |
641 } | |
642 | |
643 ftfont_info = malloc (sizeof (struct ftfont_info)); | |
644 if (! ftfont_info) | |
645 return NULL; | |
646 ftfont_info->ft_size = ft_size; | |
647 | |
648 font = (struct font *) ftfont_info; | |
649 font->entity = entity; | |
650 font->pixel_size = size; | |
651 font->driver = &ftfont_driver; | |
652 font->font.name = font->font.full_name = NULL; | |
653 font->file_name = (char *) file; | |
654 font->font.size = ft_face->size->metrics.max_advance >> 6; | |
655 font->ascent = ft_face->size->metrics.ascender >> 6; | |
656 font->descent = - ft_face->size->metrics.descender >> 6; | |
657 font->font.height = ft_face->size->metrics.height >> 6; | |
658 if (FcPatternGetInteger (pattern, FC_SPACING, 0, &spacing) != FcResultMatch | |
659 || spacing != FC_PROPORTIONAL) | |
660 font->font.average_width = font->font.space_width = font->font.size; | |
661 else | |
662 { | |
663 int i; | |
664 | |
665 for (i = 32; i < 127; i++) | |
666 { | |
667 if (FT_Load_Char (ft_face, i, FT_LOAD_DEFAULT) != 0) | |
668 break; | |
669 if (i == 32) | |
670 font->font.space_width = ft_face->glyph->metrics.horiAdvance >> 6; | |
671 font->font.average_width += ft_face->glyph->metrics.horiAdvance >> 6; | |
672 } | |
673 if (i == 127) | |
674 { | |
675 /* The font contains all ASCII printable characters. */ | |
676 font->font.average_width /= 95; | |
677 } | |
678 else | |
679 { | |
680 if (i == 32) | |
681 font->font.space_width = font->font.size; | |
682 font->font.average_width = font->font.size; | |
683 } | |
684 } | |
685 | |
686 font->font.baseline_offset = 0; | |
687 font->font.relative_compose = 0; | |
688 font->font.default_ascent = 0; | |
689 font->font.vertical_centering = 0; | |
690 | |
691 (XSAVE_VALUE (val)->integer)++; | |
692 | |
693 return font; | |
694 } | |
695 | |
696 static void | |
697 ftfont_close (f, font) | |
698 FRAME_PTR f; | |
699 struct font *font; | |
700 { | |
701 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | |
702 Lisp_Object entity = font->entity; | |
703 Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX); | |
704 | |
705 (XSAVE_VALUE (val)->integer)--; | |
706 if (XSAVE_VALUE (val)->integer == 0) | |
707 FT_Done_Face (ftfont_info->ft_size->face); | |
708 else | |
709 FT_Done_Size (ftfont_info->ft_size); | |
710 | |
711 free (font); | |
712 } | |
713 | |
714 static int | |
715 ftfont_has_char (entity, c) | |
716 Lisp_Object entity; | |
717 int c; | |
718 { | |
719 Lisp_Object val; | |
720 FcPattern *pattern; | |
721 FcCharSet *charset; | |
722 | |
723 val = AREF (entity, FONT_EXTRA_INDEX); | |
724 pattern = XSAVE_VALUE (val)->pointer; | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
725 if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
726 return -1; |
90400 | 727 return (FcCharSetHasChar (charset, (FcChar32) c) == FcTrue); |
728 } | |
729 | |
730 static unsigned | |
731 ftfont_encode_char (font, c) | |
732 struct font *font; | |
733 int c; | |
734 { | |
735 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | |
736 FT_Face ft_face = ftfont_info->ft_size->face; | |
737 FT_ULong charcode = c; | |
738 FT_UInt code = FT_Get_Char_Index (ft_face, charcode); | |
739 | |
740 return (code > 0 ? code : 0xFFFFFFFF); | |
741 } | |
742 | |
743 static int | |
744 ftfont_text_extents (font, code, nglyphs, metrics) | |
745 struct font *font; | |
746 unsigned *code; | |
747 int nglyphs; | |
748 struct font_metrics *metrics; | |
749 { | |
750 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | |
751 FT_Face ft_face = ftfont_info->ft_size->face; | |
752 int width = 0; | |
753 int i; | |
754 | |
755 if (ftfont_info->ft_size != ft_face->size) | |
756 FT_Activate_Size (ftfont_info->ft_size); | |
757 if (metrics) | |
758 bzero (metrics, sizeof (struct font_metrics)); | |
759 for (i = 0; i < nglyphs; i++) | |
760 { | |
761 if (FT_Load_Glyph (ft_face, code[i], FT_LOAD_DEFAULT) == 0) | |
762 { | |
763 FT_Glyph_Metrics *m = &ft_face->glyph->metrics; | |
764 | |
765 if (metrics) | |
766 { | |
767 if (metrics->lbearing > width + (m->horiBearingX >> 6)) | |
768 metrics->lbearing = width + (m->horiBearingX >> 6); | |
769 if (metrics->rbearing | |
770 < width + ((m->horiBearingX + m->width) >> 6)) | |
771 metrics->rbearing | |
772 = width + ((m->horiBearingX + m->width) >> 6); | |
773 if (metrics->ascent < (m->horiBearingY >> 6)) | |
774 metrics->ascent = m->horiBearingY >> 6; | |
775 if (metrics->descent > ((m->horiBearingY + m->height) >> 6)) | |
776 metrics->descent = (m->horiBearingY + m->height) >> 6; | |
777 } | |
778 width += m->horiAdvance >> 6; | |
779 } | |
780 else | |
781 { | |
782 width += font->font.space_width; | |
783 } | |
784 } | |
785 if (metrics) | |
786 metrics->width = width; | |
787 | |
788 return width; | |
789 } | |
790 | |
791 static int | |
792 ftfont_get_bitmap (font, code, bitmap, bits_per_pixel) | |
793 struct font *font; | |
794 unsigned code; | |
795 struct font_bitmap *bitmap; | |
796 int bits_per_pixel; | |
797 { | |
798 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | |
799 FT_Face ft_face = ftfont_info->ft_size->face; | |
800 FT_Int32 load_flags = FT_LOAD_RENDER; | |
801 | |
802 if (ftfont_info->ft_size != ft_face->size) | |
803 FT_Activate_Size (ftfont_info->ft_size); | |
804 if (bits_per_pixel == 1) | |
805 { | |
806 #ifdef FT_LOAD_TARGET_MONO | |
807 load_flags |= FT_LOAD_TARGET_MONO; | |
808 #else | |
809 load_flags |= FT_LOAD_MONOCHROME; | |
810 #endif | |
811 } | |
812 else if (bits_per_pixel != 8) | |
813 /* We don't support such a rendering. */ | |
814 return -1; | |
815 | |
816 if (FT_Load_Glyph (ft_face, code, load_flags) != 0) | |
817 return -1; | |
818 bitmap->rows = ft_face->glyph->bitmap.rows; | |
819 bitmap->width = ft_face->glyph->bitmap.width; | |
820 bitmap->pitch = ft_face->glyph->bitmap.pitch; | |
821 bitmap->buffer = ft_face->glyph->bitmap.buffer; | |
822 bitmap->left = ft_face->glyph->bitmap_left; | |
823 bitmap->top = ft_face->glyph->bitmap_top; | |
824 bitmap->advance = ft_face->glyph->metrics.horiAdvance >> 6; | |
825 bitmap->extra = NULL; | |
826 | |
827 return 0; | |
828 } | |
829 | |
830 static int | |
831 ftfont_anchor_point (font, code, index, x, y) | |
832 struct font *font; | |
833 unsigned code; | |
834 int index; | |
835 int *x, *y; | |
836 { | |
837 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | |
838 FT_Face ft_face = ftfont_info->ft_size->face; | |
839 | |
840 if (ftfont_info->ft_size != ft_face->size) | |
841 FT_Activate_Size (ftfont_info->ft_size); | |
842 if (FT_Load_Glyph (ft_face, code, FT_LOAD_DEFAULT) != 0) | |
843 return -1; | |
844 if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) | |
845 return -1; | |
846 if (index >= ft_face->glyph->outline.n_points) | |
847 return -1; | |
848 *x = ft_face->glyph->outline.points[index].x; | |
849 *y = ft_face->glyph->outline.points[index].y; | |
850 return 0; | |
851 } | |
852 | |
853 | |
854 void | |
855 syms_of_ftfont () | |
856 { | |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
857 DEFSYM (Qfreetype, "freetype"); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
858 DEFSYM (Qmonospace, "monospace"); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
859 DEFSYM (Qsans_serif, "sans-serif"); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
860 DEFSYM (Qserif, "serif"); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
861 DEFSYM (Qmono, "mono"); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
862 DEFSYM (Qsans, "sans"); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
863 DEFSYM (Qsans__serif, "sans serif"); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
864 |
90400 | 865 staticpro (&freetype_font_cache); |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
866 freetype_font_cache = Fcons (Qt, Qnil); |
90400 | 867 |
90464
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
868 staticpro (&ftfont_generic_family_list); |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
869 ftfont_generic_family_list |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
870 = Fcons (Fcons (Qmonospace, Qt), |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
871 Fcons (Fcons (Qsans_serif, Qt), |
4702b592db4c
(Qmonospace, Qsans_serif, Qserif, Qmono, Qsans)
Kenichi Handa <handa@m17n.org>
parents:
90450
diff
changeset
|
872 Fcons (Fcons (Qsans, Qt), Qnil))); |
90400 | 873 |
874 ftfont_driver.type = Qfreetype; | |
875 register_font_driver (&ftfont_driver, NULL); | |
876 } | |
90427 | 877 |
878 /* arch-tag: 7cfa432c-33a6-4988-83d2-a82ed8604aca | |
879 (do not change this comment) */ |