*** empty log message ***
[m17n/m17n-lib.git] / src / font.c
1 /* font.c -- font module.
2    Copyright (C) 2003, 2004
3      National Institute of Advanced Industrial Science and Technology (AIST)
4      Registration Number H15PRO112
5
6    This file is part of the m17n library.
7
8    The m17n library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Lesser General Public License
10    as published by the Free Software Foundation; either version 2.1 of
11    the License, or (at your option) any later version.
12
13    The m17n library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Lesser General Public
19    License along with the m17n library; if not, write to the Free
20    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21    02111-1307, USA.  */
22
23 /***en
24     @addtogroup m17nFont
25     @brief Font object.
26
27     The m17n GUI API represents a font by an object of the type @c
28     MFont.  A font can have @e font @e properties.  Like other types
29     of properties, a font property consists of a key and a value.  The
30     key of a font property must be one of the following symbols:
31
32     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
33     @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
34
35     When the key of a font property is @c Msize or @c Mresolution, its
36     value is an integer.  Otherwise the value is a symbol.  
37
38     "The font property that belongs to font F and whose key is @c
39     Mxxx" may be shortened to "the xxx property of F".
40
41     The value of a foundry property is a symbol representing font
42     foundry information, e.g. adobe, misc, etc.
43
44     The value of a family property is a symbol representing font family
45     information, e.g. times, helvetica, etc.
46
47     The value of a weight property is a symbol representing weight
48     information, e.g. normal, bold, etc.
49
50     The value of a style property is a symbol representing slant
51     information, e.g. normal, italic, etc.
52
53     The value of a stretch property is a symbol representing width
54     information, e.g. normal, semicondensed, etc.
55
56     The value of an adstyle property is a symbol representing abstract
57     font family information, e.g. serif, sans-serif, etc.
58
59     The value of a registry property is a symbol representing registry
60     information, e.g. iso10646-1, iso8895-1, etc.
61
62     The value of a size property is an integer representing design
63     size in the unit of 1/10 point.
64
65     The value of a resolution property is an integer representing
66     assumed device resolution in the unit of dots per inch (dpi)
67
68     The m17n library uses font objects for two purposes: to receive
69     font specification from an application program, and to present
70     available fonts to an application program.  When the m17n library
71     presents an available font to an application program, all font
72     properties have a concrete value.
73
74     The m17n library supports three kinds of fonts: Window system fonts,
75     FreeType fonts, and OpenType fonts.
76
77     <ul>
78
79     <li> Window system fonts
80
81     The m17n-X library supports all fonts handled by an X server and
82     an X font server.  The correspondence between XLFD fields and font
83     properties are shown below.
84
85 @verbatim
86     XLFD field                                  property
87     ---------------                             --------
88     FOUNDRY                                     foundry
89     FAMILY_NAME                                 family
90     WEIGHT_NAME                                 weight
91     SLANT                                       style
92     SETWIDTH_NAME                               stretch
93     ADD_STYLE_NAME                              adstyle
94     POINT_SIZE                                  size
95     RESOLUTION_Y                                resolution
96     CHARSET_REGISTRY-CHARSET_ENCODING           registry
97 @endverbatim
98
99     XLFD fields not listed in the above table are ignored.
100
101     <li> FreeType fonts
102
103     The m17n library, if configured to use the FreeType library,
104     supports all fonts that can be handled by the FreeType library.
105     The variable #mfont_freetype_path is initialized properly according
106     to the configuration of the m17n library and the environment
107     variable @c M17NDIR.  See the documentation of the variable for
108     details.
109
110     If the m17n library is configured to use the fontconfig librray,
111     in addition to #mfont_freetype_path, all fonts available via
112     fontconfig are supported.
113
114     The family name of a FreeType font corresponds to the family
115     property.  Style names of FreeType fonts correspond to the weight,
116     style, and stretch properties as below.
117
118 @verbatim
119     style name          weight  style   stretch
120     ----------          ------  -----   -------
121     Regular             medium  r       normal
122     Italic              medium  i       normal
123     Bold                bold    r       normal
124     Bold Italic         bold    i       normal
125     Narrow              medium  r       condensed
126     Narrow Italic       medium  i       condensed
127     Narrow Bold         bold    r       condensed
128     Narrow Bold Italic  bold    i       condensed
129     Black               black   r       normal
130     Black Italic        black   i       normal
131     Oblique             medium  o       normal
132     BoldOblique         bold    o       normal
133 @endverbatim
134
135     Style names not listed in the above table are treated as
136     "Regular".
137
138     Combination of a platform ID and an encoding ID corresponds to the
139     registry property.  For example, if a font has the combination (1
140     1), the registry property is 1-1.  Some frequent combinations have
141     a predefined registry property as below.
142
143 @verbatim
144     platform ID         encoding ID     registry property
145     -----------         -----------     -----------------
146     0                   3               unicode-bmp
147     0                   4               unicode-full
148     1                   0               apple-roman
149     3                   1               unicode-bmp
150     3                   1               unicode-full
151 @endverbatim
152
153     Thus, a font that has two combinations (1 0) and (3 1) corresponds
154     to four font objects whose registries are 1-0, apple-roman, 3-1,
155     and unicode-bmp.
156
157     <li> OpenType fonts 
158
159     The m17n library, if configured to use both the FreeType library
160     and the OTF library, supports any OpenType fonts.  The list of
161     actually available fonts is created in the same way as in the case
162     of FreeType fonts.  If a fontset instructs to use an OpenType font
163     via an FLT (Font Layout Table), and the FLT has an OTF-related
164     command (e.g. otf:deva), the OTF library converts a character
165     sequence to a glyph code sequence according to the OpenType layout
166     tables of the font, and the FreeType library gives a bitmap image
167     for each glyph.
168
169     </ul>
170
171   */
172
173 /***ja
174     @addtogroup m17nFont
175     @brief ¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È.
176
177     m17n GUI API ¤Ï¥Õ¥©¥ó¥È¤ò @c MFont ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æɽ¸½¤¹¤ë¡£¥Õ¥©¥ó¥È¤Ï @e 
178     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£Â¾¤Î¥¿¥¤¥×¤Î¥×¥í¥Ñ¥Æ¥£Æ±ÍÍ¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¥­¡¼¤ÈÃͤ«¤é¤Ê¤ê¡¢¥­¡¼¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
179
180     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
181     @c Madstyle, @c Mregistry, @c Msize, @c Mresolution
182
183     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution 
184     ¤Î¾ì¹ç¡¢ÃͤÏÀ°¿ôÃͤǤ¢¤ê¡¢¥­¡¼¤¬¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Ãͤϥ·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
185
186     ¡Ö¥Õ¥©¥ó¥È F ¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ @c Mxxx 
187     ¤Ç¤¢¤ë¤â¤Î¡×¤Î¤³¤È¤ò´Êñ¤Ë¡ÖF ¤Î xxx ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
188
189     foundry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢adobe, misc 
190     Åù¤Î¥Õ¥©¥ó¥È¤Î³«È¯¸µ¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
191
192     family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢times, helvetica 
193     Åù¤Î¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
194
195     weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, bold Åù¤ÎÂÀ¤µ¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
196
197     style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, italic 
198     Åù¤Î¥¹¥¿¥¤¥ë¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
199
200     stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, semicondensed 
201     Åù¤Îʸ»úÉý¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
202
203     adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢serif, sans-serif
204     Åù¤ÎÃê¾ÝŪ¤Ê¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
205
206     registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢iso10646, iso8895-1
207     Åù¤Î¥ì¥¸¥¹¥È¥ê¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
208
209     size ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤òɽ¤ï¤¹À°¿ôÃͤǤ¢¤ê¡¢Ã±°Ì¤Ï
210     1/10 ¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£
211
212     resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ÁÛÄꤵ¤ì¤Æ¤¤¤ë¥Ç¥Ð¥¤¥¹¤Î²òÁüÅÙ¤òɽ¤ï¤¹À°¿ôÃͤǤ¢¤ê¡¢Ã±°Ì¤Ï
213     dots per inch (dpi) ¤Ç¤¢¤ë¡£  
214
215     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤Ä¤ÎÌÜŪ¤ÇÍѤ¤¤Æ¤¤¤ë¡£
216     ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¥Õ¥©¥ó¥È¤Î»ØÄê¤ò¼õ¤±¼è¤ëÌÜŪ¤È¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤òÄ󼨤¹¤ëÌÜŪ¤Ç¤¢¤ë¡£
217     ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÂФ·¤ÆÄ󼨤ò¹Ô¤¦ºÝ¤Ë¤Ï¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù¤Æ¶ñÂÎŪ¤ÊÃͤò»ý¤Ä¡£
218
219     m17n ¥é¥¤¥Ö¥é¥ê¤Ï Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¡¢FreeType¥Õ¥©¥ó¥È¡¢
220     OpenType¥Õ¥©¥ó¥È¤Î£³¼ïÎà¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£
221
222     <ul>
223
224     <li> Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È
225
226     m17n X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢X ¥µ¡¼¥Ð¤È X ¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤¬¼è¤ê°·¤¦Á´¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£
227     XLFD ¤Î³Æ¥Õ¥£¡¼¥ë¥É¤È¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ÎÂбþ¤Ï°Ê²¼¤ÎÄ̤ꡣ¤³¤Îɽ¤Ë¤Ê¤¤¥Õ¥£¡¼¥ë¥É¤Ï̵»ë¤µ¤ì¤ë¡£
228
229 @verbatim
230     XLFD ¥Õ¥£¡¼¥ë¥É                             ¥×¥í¥Ñ¥Æ¥£
231     ---------------                             --------
232     FOUNDRY                                     foundry
233     FAMILY_NAME                                 family
234     WEIGHT_NAME                                 weight
235     SLANT                                       style
236     SETWIDTH_NAME                               stretch
237     ADD_STYLE_NAME                              adstyle
238     POINT_SIZE                                  size
239     RESOLUTION_Y                                resolution
240     CHARSET_REGISTRY-CHARSET_ENCODING           registry
241 @endverbatim
242
243     <li> FreeType fonts
244
245     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
246     FreeType ¤¬°·¤¦¤¹¤Ù¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ÊÑ¿ô 
247     #mfont_freetype_path ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤ÎÀßÄê¤È´Ä¶­ÊÑ¿ô @c M17NDIR 
248     ¤Ë±þ¤¸¤Æ½é´ü²½¤µ¤ì¤ë¡£¾ÜºÙ¤ÏÊÑ¿ô¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
249
250     ¤â¤· m17n ¥é¥¤¥Ö¥é¥ê¤¬ fontconfig ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
251     #mfont_freetype_path ¤Ë²Ã¤¨¤Æ¡¢ fontconfig ¤Ç»ÈÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤â¤¹¤Ù¤Æ¥µ¥Ý¡¼¥È¤µ¤ì¤ë¡£
252
253     FreeType ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤Ï family ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
254     FreeType ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾¤Ï¡¢²¼¤Îɽ¤Î¤è¤¦¤Ë weight, style,
255     stretch ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
256
257 @verbatim
258     ¥¹¥¿¥¤¥ë̾          weight  style   stretch
259     ----------          ------  -----   -------
260     Regular             medium  r       normal
261     Italic              medium  i       normal
262     Bold                bold    r       normal
263     Bold Italic         bold    i       normal
264     Narrow              medium  r       condensed
265     Narrow Italic       medium  i       condensed
266     Narrow Bold         bold    r       condensed
267     Narrow Bold Italic  bold    i       condensed
268     Black               black   r       normal
269     Black Italic        black   i       normal
270     Oblique             medium  o       normal
271     BoldOblique         bold    o       normal
272 @endverbatim
273
274     ¾å¤Îɽ¤Ë¸½¤ï¤ì¤Ê¤¤¥¹¥¿¥¤¥ë̾¤Ï "Regular" ¤È¤·¤Æ°·¤ï¤ì¤ë¡£
275
276     platform ID ¤È encoding ID ¤ÎÁȤ߹ç¤ï¤»¤¬ registry 
277     ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£¤¿¤È¤¨¤Ð¤¢¤ë¥Õ¥©¥ó¥È¤¬ (1 1) ¤È¤¤¤¦ ID ¤ÎÁȹ礻¤ò»ý¤Æ¤Ð¡¢
278     registry ¥×¥í¥Ñ¥Æ¥£¤Ï 1-1 ¤È¤Ê¤ë¡£ÉÑÈˤˤ¢¤é¤ï¤ì¤ëÁȹ礻¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤ÊÄêµÁºÑ¤ß
279     registry ¥×¥í¥Ñ¥Æ¥£ ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤ë¡£
280
281 @verbatim
282     platform ID         encoding ID     registry ¥×¥í¥Ñ¥Æ¥£
283     -----------         -----------     -----------------
284     0                   3               unicode-bmp
285     0                   4               unicode-full
286     1                   0               apple-roman
287     3                   1               unicode-bmp
288     3                   1               unicode-full
289 @endverbatim
290
291     ¤·¤¿¤¬¤Ã¤Æ¡¢Æó¤Ä¤ÎÁȹ礻 (1 0) ¡¢(3 1) ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤Ï¡¢¤½¤ì¤¾¤ì
292     registry ¥×¥í¥Ñ¥Æ¥£¤¬ 1-0, apple-roman, 3-1, unicode-bmp
293     ¤Ç¤¢¤ë£´¤Ä¤Î¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ËÂбþ¤¹¤ë¡£
294
295     <li> OpenType ¥Õ¥©¥ó¥È
296
297     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤È OTF 
298     ¥é¥¤¥Ö¥é¥ê¤ò»ÈÍѤ¹¤ë¤è¤¦¤ËÀßÄꤹ¤ì¤Ð¡¢¤¹¤Ù¤Æ¤Î OpenType 
299     ¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£¼ÂºÝ¤ËÍøÍѤǤ­¤ë¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤Ï FreeType
300     ¥Õ¥©¥ó¥È¤Î¾ì¹ç¤ÈƱÍͤ˺î¤é¤ì¤ë¡£OpenType ¥Õ¥©¥ó¥È¤ò FLT (Font Layout Table)
301     ·Ðͳ¤Ç»ÈÍѤ¹¤ë¤è¤¦¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ë»ØÄꤵ¤ì¤Æ¤ª¤ê¡¢FLT ¤Ë OTF 
302     ´ØÏ¢¤Î¥³¥Þ¥ó¥É (¤¿¤È¤¨¤Ð otf:deva) ¤¬¤¢¤ì¤Ð¡¢OTF ¥é¥¤¥Ö¥é¥ê¤¬¥Õ¥©¥ó¥È¤Î OpenType
303     ¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¤Ë½¾¤Ã¤Æʸ»úÎó¤ò¥°¥ê¥Õ¥³¡¼¥ÉÎó¤ËÊÑ´¹¤·¡¢FreeType
304     ¥é¥¤¥Ö¥é¥ê¤¬³Æ¥°¥ê¥Õ¤Î¥Ó¥Ã¥È¥Þ¥Ã¥×¥¤¥á¡¼¥¸¤òÄ󶡤¹¤ë¡£
305
306     </ul>
307
308 */
309
310 /*=*/
311
312 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
313 /*** @addtogroup m17nInternal
314      @{ */
315
316 #include "config.h"
317
318 #include <stdio.h>
319 #include <stdlib.h>
320 #include <string.h>
321
322 #include "m17n-gui.h"
323 #include "m17n-misc.h"
324 #include "internal.h"
325 #include "mtext.h"
326 #include "symbol.h"
327 #include "plist.h"
328 #include "charset.h"
329 #include "internal-gui.h"
330 #include "font.h"
331 #include "face.h"
332
333 MPlist *mfont__driver_list;
334
335 /** Indices to font properties sorted by their priority.  */
336 static int font_score_priority[] =
337   { MFONT_SIZE,
338     MFONT_ADSTYLE,
339     MFONT_FAMILY,
340     MFONT_WEIGHT,
341     MFONT_STYLE,
342     MFONT_STRETCH,
343     MFONT_FOUNDRY
344   };
345
346 #define FONT_SCORE_PRIORITY_SIZE        \
347   (sizeof font_score_priority / sizeof font_score_priority[0])
348
349 /* Indexed by a font property MFONT_XXX, and the value is how many
350    bits to shift the difference of property values.  */
351 static int font_score_shift_bits[MFONT_PROPERTY_MAX];
352
353 /** Predefined symbols for each font property.  The order is important
354     because the function score_font () decides how well a font matches
355     with a spec by checking how close the index is.  */
356
357 static char *common_foundry[] =
358   { "misc",
359     "adobe" };
360 static char *common_family[] =
361   { "fixed",
362     "courier",
363     "helvetica",
364     "times" };
365 static char *common_weight[] =
366   { "ultralight",
367     "extralight",
368     "light",
369     "demilight",
370     "book",
371     "regular",
372     "normal",
373     "medium",
374     "demibold",
375     "bold",
376     "extrabold",
377     "ultrabold",
378     "black" };
379 static char *common_style[] =
380   { "o",
381     "i",
382     "slanted",
383     "r",
384     "rslanted",
385     "ri",
386     "ro" };
387 static char *common_stretch[] =
388   { "condensed",
389     "narrow",
390     "semicondensed",
391     "normal",
392     "semiexpanded",
393     "expanded" };
394 static char *common_adstyle[] =
395   { "serif",
396     "",
397     "sans" };
398 static char *common_registry[] =
399   { "iso8859-1" };
400
401 /* Table containing all the data above.  */
402
403 struct MFontCommonNames
404 {
405   int num;
406   char **names;
407 };
408
409 static struct MFontCommonNames font_common_names[] =
410   {
411     { sizeof (common_foundry) / sizeof (char *), common_foundry},
412     { sizeof (common_family) / sizeof (char *), common_family},
413     { sizeof (common_weight) / sizeof (char *), common_weight},
414     { sizeof (common_style) / sizeof (char *), common_style},
415     { sizeof (common_stretch) / sizeof (char *), common_stretch},
416     { sizeof (common_adstyle) / sizeof (char *), common_adstyle},
417     { sizeof (common_registry) / sizeof (char *), common_registry}
418   };
419
420
421 /** Table of available font property names.  */
422
423 MFontPropertyTable mfont__property_table[MFONT_REGISTRY + 1];
424
425
426 /** Return the numeric value of SYMBOL as the Nth font property.  */
427
428 #define FONT_PROPERTY_NUMERIC(symbol, n)        \
429   ((symbol) == Mnil                             \
430    ? 0                                          \
431    : ((int) msymbol_get ((symbol), mfont__property_table[(n)].property)))
432
433
434 /** Set the numeric value of SYMBOL as the Nth font property to NUMERIC.  */
435
436 #define SET_FONT_PROPERTY_NUMERIC(symbol, n, numeric)           \
437   msymbol_put((symbol), mfont__property_table[(n)].property,    \
438               (void *) (numeric))
439
440 static char *
441 gen_font_name (char *buf, MFont *font)
442 {
443   char size[16];
444   int i;
445
446   buf[0] = '\0';
447   for (i = 0; i <= MFONT_REGISTRY; i++)
448     if (FONT_PROPERTY (font, i) != Mnil)
449       {
450         char *name = msymbol_name (FONT_PROPERTY (font, i));
451
452         if (name[0])
453           {
454             if (i > 0)
455               strcat (buf, ",");
456             strcat (buf, name);
457           }
458       }
459   sprintf (size, ",%d", font->property[MFONT_SIZE] / 10);
460   strcat (buf, size);
461   return buf;
462 }
463
464
465 \f
466 /* Font selector.  */
467
468 struct MFontEncoding {
469   MFont spec;
470   MSymbol encoding_name;
471   MCharset *encoding_charset;
472   MSymbol repertory_name;
473   MCharset *repertory_charset;
474 };
475
476 static MPlist *font_encoding_list;
477 static MFontEncoding default_encoding;
478
479 /** Load font encoding table from the data <font encoding>.
480     The data has this form:
481         (FONT-SPEC ENCODING) ...
482     where FONT-SPEC has this form:
483         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
484     All elements are symbols.  */
485
486 static int
487 load_font_encoding_table ()
488 {
489   MDatabase *mdb;
490   MPlist *encoding_list, *plist, *pl, *elt;
491
492   font_encoding_list = pl = mplist ();
493
494   mdb = mdatabase_find (Mfont, msymbol ("encoding"), Mnil, Mnil);
495   if (! mdb
496       || ! (encoding_list = (MPlist *) mdatabase_load (mdb)))
497     MERROR (MERROR_FONT, -1);
498
499   MPLIST_DO (plist, encoding_list)
500     {
501       MFontEncoding *encoding;
502       MSymbol registry;
503
504       MSTRUCT_CALLOC (encoding, MERROR_FONT);
505
506       if (! MPLIST_PLIST_P (plist)
507           || (elt = MPLIST_PLIST (plist), mplist_length (elt) < 2)
508           || ! MPLIST_PLIST_P (elt))
509         MWARNING (MERROR_FONT);
510       registry = mfont__set_spec_from_plist (&encoding->spec,
511                                              MPLIST_PLIST (elt));
512       elt = MPLIST_NEXT (elt);
513       if (! MPLIST_SYMBOL_P (elt))
514         MWARNING (MERROR_FONT);
515       encoding->encoding_name = MPLIST_SYMBOL (elt);
516       elt = MPLIST_NEXT (elt);
517       if (MPLIST_TAIL_P (elt))
518         encoding->repertory_name = encoding->encoding_name;
519       else if (! MPLIST_SYMBOL_P (elt))
520         MWARNING (MERROR_FONT);
521       else
522         encoding->repertory_name = MPLIST_SYMBOL (elt);
523
524       if (registry == Mnil)
525         mplist_push (font_encoding_list, Mt, encoding);
526       else
527         pl = mplist_add (pl, registry, encoding);
528       continue;
529
530     warning:
531       free (encoding);
532     }
533
534   M17N_OBJECT_UNREF (encoding_list);
535   return 0;
536 }
537
538 typedef struct {
539   MFont spec;
540   int resize;
541 } MFontResize;
542
543 static MPlist *font_resize_list;
544
545 /** Load font size table from the data <font size>.
546     The data has this form:
547         (FONT-SPEC RESIZE-FACTOR) ...
548     where FONT-SPEC has this form:
549         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
550     All elements of FONT-SPEC are symbols.  */
551
552 static int
553 load_font_resize_table ()
554 {
555   MDatabase *mdb;
556   MPlist *size_adjust_list, *plist, *pl, *elt;
557
558   font_resize_list = pl = mplist ();
559
560   mdb = mdatabase_find (Mfont, msymbol ("resize"), Mnil, Mnil);
561   if (! mdb)
562     return -1;
563   if (! (size_adjust_list = (MPlist *) mdatabase_load (mdb)))
564     MERROR (MERROR_FONT, -1);
565
566   MPLIST_DO (plist, size_adjust_list)
567     {
568       MFontResize *resize;
569       MSymbol registry;
570
571       MSTRUCT_CALLOC (resize, MERROR_FONT);
572
573       if (! MPLIST_PLIST_P (plist)
574           || (elt = MPLIST_PLIST (plist), mplist_length (elt) != 2)
575           || ! MPLIST_PLIST_P (elt))
576         MWARNING (MERROR_FONT);
577       registry = mfont__set_spec_from_plist (&resize->spec,
578                                              MPLIST_PLIST (elt));
579       elt = MPLIST_NEXT (elt);
580       if (! MPLIST_INTEGER_P (elt))
581         MWARNING (MERROR_FONT);
582       resize->resize = MPLIST_INTEGER (elt);
583
584       if (registry == Mnil)
585         registry = Mt;
586       pl = mplist_add (pl, registry, resize);
587       continue;
588
589     warning:
590       free (resize);
591     }
592
593   M17N_OBJECT_UNREF (size_adjust_list);
594   return 0;
595 }
596
597 /** Return a font encoding (and repertory) of FONT.  */
598
599 static MFontEncoding *
600 find_encoding (MFont *font)
601 {
602   MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
603   MFontEncoding *encoding = NULL;
604   MPlist *plist;
605
606   if (! font_encoding_list)
607     load_font_encoding_table ();
608   plist = font_encoding_list;
609   while (! MPLIST_TAIL_P (plist))
610     {
611       encoding = (MFontEncoding *) MPLIST_VAL (plist);
612       if (mfont__match_p (font, &encoding->spec, MFONT_REGISTRY))
613         {
614           if (encoding->encoding_name != Mnil
615               && ! encoding->encoding_charset)
616             {
617               encoding->encoding_charset = MCHARSET (encoding->encoding_name);
618               if (! encoding->encoding_charset)
619                 {
620                   mplist_pop (plist);
621                   continue;
622                 }
623             }
624           if (encoding->repertory_name == encoding->encoding_name)
625             encoding->repertory_charset = encoding->encoding_charset;
626           else if (encoding->repertory_name != Mnil)
627             {
628               encoding->repertory_charset
629                 = MCHARSET (encoding->repertory_name);
630               if (! encoding->repertory_charset)
631                 {
632                   mplist_pop (plist);
633                   continue;
634                 }
635             }
636           return encoding;
637         }
638
639       if (registry && MPLIST_KEY (plist) != Mt)
640         {
641           plist = mplist_find_by_key (plist, registry);
642           if (! plist)
643             break;
644         }
645       else
646         plist = MPLIST_NEXT (plist);
647     }
648   return &default_encoding;
649 }
650
651 /* XLFD parser/generator */
652
653 /** Indices to each field of split font name.  */
654
655 enum xlfd_field_idx
656   {
657     XLFD_FOUNDRY,
658     XLFD_FAMILY,
659     XLFD_WEIGHT,
660     XLFD_SLANT,
661     XLFD_SWIDTH,
662     XLFD_ADSTYLE,
663     XLFD_PIXEL,
664     XLFD_POINT,
665     XLFD_RESX,
666     XLFD_RESY,
667     XLFD_SPACING,
668     XLFD_AVGWIDTH,
669     XLFD_REGISTRY,              /* This contains ENCODING.  */
670     /* anchor */
671     XLFD_FIELD_MAX
672   };
673
674 static int
675 xlfd_parse_name (char *name, MFont *font)
676 {
677   char *field[XLFD_FIELD_MAX];
678   unsigned short size, resy, avgwidth;
679   MSymbol attrs[MFONT_PROPERTY_MAX];
680   char copy[513];
681   int i;
682   char *p;
683
684   if (name[0] != '-')
685     return -1;
686
687   field[0] = copy;
688   for (i = 1, p = copy, name++; *name; p++, name++)
689     {
690       if (p - copy > 512)
691         return -1;
692       if (*name == '-'
693           && i < XLFD_FIELD_MAX)
694         {
695           *p = '\0';
696           if (field[i - 1][0] == '*')
697             field[i - 1] = NULL;
698           field[i++] = p + 1;
699         }
700       else
701         *p = tolower (*name);
702     }
703   *p = '\0';
704   if (field[i - 1][0] == '*')
705     field[i - 1] = NULL;
706   while (i < XLFD_FIELD_MAX)
707     field[i++] = NULL;
708
709   resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0;
710   avgwidth = ((field[XLFD_AVGWIDTH] && isdigit (field[XLFD_AVGWIDTH][0]))
711               ? atoi (field[XLFD_AVGWIDTH]) : 1);
712   if (! avgwidth)
713     size = 0;
714   else if (! field[XLFD_PIXEL])
715     size = field[XLFD_POINT] ? atoi (field[XLFD_POINT]) * resy / 72 : 0;
716   else if (field[XLFD_PIXEL][0] == '[')
717     {
718       /* The pixel size field specifies a transformation matrix of the
719          form "[A B C D]".  The XLFD spec says that the scalar value N
720          for the pixel size is equivalent to D.  */
721       char *p0 = field[XLFD_PIXEL] + 1, *p1;
722       double d;
723
724       for (i = 0; i < 4; i++, p0 = p1)
725         d = strtod (p0, &p1);
726       size = d * 10;
727     }
728   else
729     size = atoi (field[XLFD_PIXEL]) * 10;
730
731   attrs[MFONT_FOUNDRY]
732     = field[XLFD_FOUNDRY] ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
733   attrs[MFONT_FAMILY]
734     = field[XLFD_FAMILY] ? msymbol (field[XLFD_FAMILY]) : Mnil;
735   attrs[MFONT_WEIGHT]
736     = field[XLFD_WEIGHT] ? msymbol (field[XLFD_WEIGHT]) : Mnil;
737   attrs[MFONT_STYLE]
738     = field[XLFD_SLANT] ? msymbol (field[XLFD_SLANT]) : Mnil;
739   attrs[MFONT_STRETCH]
740     = field[XLFD_SWIDTH] ? msymbol (field[XLFD_SWIDTH]) : Mnil;
741   attrs[MFONT_ADSTYLE]
742     = field[XLFD_ADSTYLE] ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
743   attrs[MFONT_REGISTRY]
744     = field[XLFD_REGISTRY] ? msymbol (field[XLFD_REGISTRY]) : Mnil;
745   mfont__set_spec (font, attrs, size, resy);
746   return 0;
747 }
748
749 static char *
750 xlfd_unparse_name (MFont *font)
751 {
752   MSymbol prop[7];
753   char name[513];
754   char *str[7];
755   int len, i;
756   unsigned short size, resy;
757
758   prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
759   prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
760   prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
761   prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
762   prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
763   prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
764   prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
765   for (len = 0, i = 0; i < 7; i++)
766     {
767       if (prop[i] != Mnil)
768         {
769           str[i] = msymbol_name (prop[i]);
770           len += strlen (str[i]);
771         }
772       else
773         {
774           str[i] = "*";
775           len++;
776         }
777     }
778   if ((len
779        + 12                     /* 12 dashes */
780        + 3                      /* 3 asterisks */
781        + 30                     /* 3 integers (each 10 digits) */
782        + 1)                     /* '\0' terminal */
783       > 513)
784     return NULL;
785
786   size = (int) mfont_get_prop (font, Msize);
787   if ((size % 10) < 5)
788     size /= 10;
789   else
790     size = size / 10 + 1;
791   resy = (int) mfont_get_prop (font, Mresolution);
792
793   sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s",
794            str[0], str[1], str[2], str[3], str[4], str[5],
795            size, resy, resy,  str[6]);
796   return strdup (name);
797 }
798
799 \f
800 /* Internal API */
801
802 int
803 mfont__init ()
804 {
805   int i, shift;
806
807   Mfoundry = msymbol ("foundry");
808   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
809   Mfamily = msymbol ("family");
810   mfont__property_table[MFONT_FAMILY].property = Mfamily;
811   Mweight = msymbol ("weight");
812   mfont__property_table[MFONT_WEIGHT].property = Mweight;
813   Mstyle = msymbol ("style");
814   mfont__property_table[MFONT_STYLE].property = Mstyle;
815   Mstretch = msymbol ("stretch");
816   mfont__property_table[MFONT_STRETCH].property = Mstretch;
817   Madstyle = msymbol ("adstyle");
818   mfont__property_table[MFONT_ADSTYLE].property = Madstyle;
819   Mregistry = msymbol ("registry");
820   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
821
822   Msize = msymbol ("size");
823   Mresolution = msymbol ("resolution");
824
825   Mfontconfig = msymbol ("fontconfig");
826
827   Mx = msymbol ("x");
828   Mfreetype = msymbol ("freetype");
829   Mxft = msymbol ("xft");
830
831   /* The first entry of each mfont__property_table must be Mnil so
832      that actual properties get positive numeric numbers.  */
833   for (i = 0; i <= MFONT_REGISTRY; i++)
834     {
835       MLIST_INIT1 (&mfont__property_table[i], names, 8);
836       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
837     }
838
839   /* Register predefined font property names.  */
840   for (i = 0; i <= MFONT_REGISTRY; i++)
841     {
842       int j;
843
844       for (j = 0; j < font_common_names[i].num; j++)
845         {
846           MSymbol sym = msymbol (font_common_names[i].names[j]);
847
848           if (sym == Mnil)
849             return -1;
850           if (msymbol_put (sym, mfont__property_table[i].property,
851                            (void *) (j + 1)) < 0)
852             return -1;
853           MLIST_APPEND1 (&mfont__property_table[i], names, sym, MERROR_FONT);
854         }
855     }
856
857   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
858      of a score is a flag for a scalable font (see the documentation
859      of mfont_score).  */
860   i = FONT_SCORE_PRIORITY_SIZE - 1;
861   for (shift = 1; i >= 0; i--)
862     {
863       font_score_shift_bits[font_score_priority[i]] = shift;
864       if (font_score_priority[i] == MFONT_SIZE)
865         shift += 16;
866       else
867         shift += 2;
868     }
869
870   MFONT_INIT (&default_encoding.spec);
871   default_encoding.encoding_name = Mnil;
872   default_encoding.encoding_charset = NULL;
873   default_encoding.repertory_name = Mnil;
874   default_encoding.repertory_charset = NULL;
875   {
876     char *path, *buf;
877     int bufsize;
878
879     mfont_freetype_path = mplist ();
880     bufsize = strlen (M17NDIR) + 7;
881     buf = alloca (bufsize);
882     sprintf (buf, "%s/fonts", M17NDIR);
883     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
884     path = getenv ("M17NDIR");
885     if (path)
886       {
887         i = strlen (path) + 7;
888         if (i > bufsize)
889           buf = alloca (i);
890         sprintf (buf, "%s/fonts", path);
891         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
892       }
893   }
894
895 #ifdef HAVE_FREETYPE
896   if (mfont__ft_init () < 0)
897     return -1;
898 #endif /* HAVE_FREETYPE */
899   if (mfont__flt_init () < 0)
900     return -1;
901
902   return 0;
903 }
904
905 void
906 mfont__fini ()
907 {
908   MPlist *plist;
909   int i;
910
911   mfont__flt_fini ();
912 #ifdef HAVE_FREETYPE
913   mfont__ft_fini ();
914 #endif /* HAVE_FREETYPE */
915
916   MPLIST_DO (plist, mfont_freetype_path)
917     free (MPLIST_VAL (plist));
918   M17N_OBJECT_UNREF (mfont_freetype_path);
919
920   if (font_resize_list)
921     {
922       MPLIST_DO (plist, font_resize_list)
923         free (MPLIST_VAL (plist));
924       M17N_OBJECT_UNREF (font_resize_list);
925       font_resize_list = NULL;
926     }
927   if (font_encoding_list)
928     {
929       MPLIST_DO (plist, font_encoding_list)
930         free (MPLIST_VAL (plist));
931       M17N_OBJECT_UNREF (font_encoding_list);
932       font_encoding_list = NULL;
933     }
934   for (i = 0; i <= MFONT_REGISTRY; i++)
935     MLIST_FREE1 (&mfont__property_table[i], names);
936 }
937
938 void
939 mfont__free_realized (MRealizedFont *rfont)
940 {
941   M17N_OBJECT_UNREF (rfont->info);
942   free (rfont);
943 }
944
945
946 /* Compare FONT with REQUEST and return how much they differs.  If
947    FONT does not match with SPEC, return -1.  */
948
949 int
950 mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size)
951 {
952   int score = 0;
953   int i = FONT_SCORE_PRIORITY_SIZE;
954
955   while (--i >= 0)
956     {
957       enum MFontProperty prop = font_score_priority[i];
958
959       if (request->property[prop] != 0)
960         {
961           int val = 0;
962
963           if (spec->property[prop] && font->property[prop]
964               && font->property[prop] != spec->property[prop])
965             return -1;
966           if (font->property[prop])
967             val = abs (font->property[prop] - request->property[prop]);
968           if (val && prop <= MFONT_FAMILY)
969             val = 1;
970           if (prop == MFONT_SIZE)
971             {
972               if (font->property[MFONT_RESY] == 0)
973                 /* This is a scalable font.  We prefer a bitmap font
974                    if the size matches exactly.  */
975                 score |= 1;
976               else
977                 score |= (val << font_score_shift_bits[MFONT_SIZE]
978                           | ((limited_size && val > 0) ? 0x400000 : 0));
979             }
980           else
981             score |= (val > 3 ? 3 : val) << font_score_shift_bits[prop];
982         }
983     }
984   return score;
985 }
986
987
988 /** Return 1 iff FONT matches SPEC.  */
989
990 int
991 mfont__match_p (MFont *font, MFont *spec, int prop)
992 {
993   for (; prop >= 0; prop--)
994     if (spec->property[prop] && font->property[prop]
995         && font->property[prop] != spec->property[prop])
996       return 0;
997   return 1;
998 }
999
1000
1001 void
1002 mfont__set_spec_from_face (MFont *spec, MFace *face)
1003 {
1004   int i;
1005
1006   for (i = 0; i <= MFONT_ADSTYLE; i++)
1007     mfont__set_property (spec, i, face->property[i]);
1008   /* The value 1 is "iso8859-1".  */
1009   spec->property[MFONT_REGISTRY] = 1;
1010   spec->property[MFONT_SIZE] = (int) (face->property[MFACE_SIZE]);
1011   spec->property[MFONT_RESY] = 0;
1012 }
1013
1014
1015 extern MSymbol
1016 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
1017 {
1018   int i;
1019   MSymbol spec_list[MFONT_REGISTRY + 1];
1020   MSymbol registry;
1021
1022   MFONT_INIT (spec);
1023   memset (spec_list, 0, sizeof spec_list);
1024   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
1025     {
1026       if (! MPLIST_SYMBOL_P (plist))
1027         MERROR (MERROR_FONT, Mnil);     
1028       spec_list[i] = MPLIST_SYMBOL (plist);
1029     }
1030   registry = spec_list[i - 1];
1031   mfont__set_property (spec, MFONT_REGISTRY, registry);
1032   for (i -= 2; i >= 0; i--)
1033     mfont__set_property (spec, i, spec_list[i]);
1034   return registry;
1035 }
1036
1037 MRealizedFont *
1038 mfont__select (MFrame *frame, MFont *spec, MFont *request, int limited_size,
1039                MSymbol layouter)
1040 {
1041   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1042   MPlist *plist;
1043   MRealizedFont *best;
1044   int i;
1045   int mdebug_mask = MDEBUG_FONT;
1046
1047   if (registry == Mnil)
1048     registry = Mt;
1049
1050   MPLIST_DO (plist, frame->realized_font_list)
1051     {
1052       best = MPLIST_VAL (plist);
1053       if (MPLIST_KEY (plist) == registry
1054           && ! memcmp (&best->spec, spec, sizeof (MFont))
1055           && ! memcmp (&best->request, request, sizeof (MFont)))
1056         {
1057           if (best->layouter != layouter)
1058             {
1059               MRealizedFont *copy;
1060
1061               MSTRUCT_MALLOC (copy, MERROR_FONT);
1062               *copy = *best;
1063               copy->layouter = layouter;
1064               mplist_add (frame->realized_font_list, registry, copy);
1065               if (copy->info)
1066                 M17N_OBJECT_REF (copy->info);
1067               best = copy;
1068             }
1069           return best;
1070         }
1071     }
1072
1073   MDEBUG_PUSH_TIME ();
1074   best = NULL;
1075   MPLIST_DO (plist, frame->font_driver_list)
1076     {
1077       MFontDriver *driver = MPLIST_VAL (plist);
1078       MRealizedFont *this
1079         = (driver->select) (frame, spec, request, limited_size);
1080
1081       if (this)
1082         {
1083           this->driver = driver;
1084           if (! best
1085               || this->score < best->score)
1086             {
1087               if (best)
1088                 mfont__free_realized (best);
1089               best = this;
1090               if (this->score == 0)
1091                 break;
1092             }
1093           else
1094             mfont__free_realized (this);
1095         }
1096     }
1097
1098   if (mdebug__flag & mdebug_mask)
1099     {
1100       char buf1[256], buf2[256];
1101       MFont font = *spec;
1102
1103       for (i = 0; i < MFONT_PROPERTY_MAX; i++)
1104         if (! font.property[i])
1105           font.property[i] = request->property[i];
1106       gen_font_name (buf2, &font);
1107
1108       if (best)
1109         MDEBUG_PRINT_TIME ("FONT", 
1110                            (stderr, " to select <%s> (%x)from <%s>.",
1111                             gen_font_name (buf1, &best->font),
1112                             best->score,
1113                             buf2));
1114       else
1115         MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
1116       MDEBUG_POP_TIME ();
1117     }
1118
1119   if (! best)
1120     return NULL;
1121   best->layouter = layouter;
1122   mplist_add (frame->realized_font_list, registry, best);
1123   return best;
1124 }
1125
1126
1127 /** Open a font specified in RFONT.  Return 0 if successfully
1128     opened, otherwise return -1.  */
1129
1130 int
1131 mfont__open (MRealizedFont *rfont)
1132 {
1133   return (rfont->driver->open) (rfont);
1134 }
1135
1136 void
1137 mfont__resize (MFont *spec, MFont *request)
1138 {
1139   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1140   MFontResize *resize;
1141   MPlist *plist;
1142
1143   if (! font_resize_list)
1144     load_font_resize_table ();
1145   if (! MPLIST_TAIL_P (font_resize_list))
1146     while (1)
1147       {
1148         plist = font_resize_list;
1149         while (registry ? (plist = mplist_find_by_key (plist, registry))
1150                : plist)
1151           {
1152             resize = (MFontResize *) MPLIST_VAL (plist);
1153             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1154               {
1155                 request->property[MFONT_SIZE]
1156                   = request->property[MFONT_SIZE] * resize->resize / 100;
1157                 return;
1158               }
1159             plist = MPLIST_NEXT (plist);
1160           }
1161         if (registry == Mt)
1162           break;
1163         registry = Mt;
1164       }
1165 }
1166
1167
1168 unsigned
1169 mfont__encode_char (MRealizedFont *rfont, int c)
1170 {
1171   MFontEncoding *encoding;
1172   unsigned code;
1173
1174   if (rfont->layouter != Mnil)
1175     return mfont__flt_encode_char (rfont->layouter, c);
1176   if (! rfont->encoding)
1177     rfont->encoding = find_encoding (&rfont->font);
1178   encoding = rfont->encoding;
1179   if (! encoding->encoding_charset)
1180     return MCHAR_INVALID_CODE;
1181   if (encoding->repertory_charset
1182       && ENCODE_CHAR (encoding->repertory_charset, c) == MCHAR_INVALID_CODE)
1183     return MCHAR_INVALID_CODE;
1184   code = ENCODE_CHAR (encoding->encoding_charset, c);
1185   if (code == MCHAR_INVALID_CODE)
1186     return MCHAR_INVALID_CODE;
1187   return (rfont->driver->encode_char) (rfont, code);
1188 }
1189
1190 void
1191 mfont__get_metric (MGlyphString *gstring, int from, int to)
1192 {
1193   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1194   MRealizedFont *rfont = from_g->rface->rfont;
1195
1196   for (g = from_g; g != to_g; g++)
1197     if (g->rface->rfont != rfont)
1198       {
1199         int idx = GLYPH_INDEX (g);
1200
1201         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1202         from_g = g;
1203         rfont = g->rface->rfont;
1204         from = idx;
1205       }
1206   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1207 }
1208
1209
1210 void
1211 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1212 {
1213   int numeric;
1214
1215   if (val == Mnil)
1216     numeric = 0;
1217   else
1218     {
1219       numeric = FONT_PROPERTY_NUMERIC (val, key);
1220       if (! numeric)
1221         {
1222           numeric = mfont__property_table[key].used;
1223           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1224           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1225         }
1226     }
1227   font->property[key] = numeric;
1228 }
1229
1230 void
1231 mfont__set_spec (MFont *font, MSymbol *attrs,
1232                  unsigned short size, unsigned short resy)
1233 {
1234   int i;
1235
1236   for (i = 0; i <= MFONT_REGISTRY; i++)
1237     mfont__set_property (font, i, attrs[i]);
1238   font->property[MFONT_SIZE] = size;
1239   font->property[MFONT_RESY] = resy;
1240 }
1241
1242 int
1243 mfont__parse_name_into_font (char *name, MSymbol format, MFont *font)
1244 {
1245   int result = -1;
1246
1247   if (format == Mx || format == Mnil)
1248     result = xlfd_parse_name (name, font);
1249 #ifdef HAVE_FONTCONFIG
1250   if (format == Mfontconfig || (! result && format == Mnil))
1251     result = mfont__ft_parse_name (name, font);
1252 #endif
1253   return result;
1254 }
1255
1256 MPlist *
1257 mfont__encoding_list (void)
1258 {
1259   if (! font_encoding_list)
1260     load_font_encoding_table ();
1261   return font_encoding_list;
1262 }
1263
1264 /*** @} */
1265 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1266
1267 \f
1268
1269 /* External API */
1270
1271 /*** @addtogroup m17nFont */
1272 /*** @{ */
1273 /*=*/
1274
1275 /***en @name Variables: Keys of font property.  */
1276 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1277 /*** @{ */
1278 /*=*/
1279
1280 /***en
1281     @brief Key of font property specifying foundry.
1282
1283     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1284     is used as a key of font property and face property.  The property
1285     value must be a symbol whose name is a foundry name of a font.  */
1286 /***ja
1287     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1288     
1289     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> 
1290     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1291     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1292
1293 MSymbol Mfoundry;
1294
1295 /***en
1296     @brief Key of font property specifying family.
1297
1298     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1299     used as a key of font property and face property.  The property
1300     value must be a symbol whose name is a family name of a font.  */ 
1301 /***ja
1302     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1303     
1304     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> 
1305     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1306     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1307
1308 MSymbol Mfamily;
1309
1310 /***en
1311     @brief Key of font property specifying weight.
1312
1313     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1314     used as a key of font property and face property.  The property
1315     value must be a symbol whose name is a weight name of a font (e.g
1316     "medium", "bold").  */ 
1317 /***ja
1318     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1319     
1320     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> 
1321     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1322     Ãͤϡ¢¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1323
1324 MSymbol Mweight;
1325
1326 /***en
1327     @brief Key of font property specifying style.
1328
1329     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1330     used as a key of font property and face property.  The property
1331     value must be a symbol whose name is a style name of a font (e.g
1332     "r", "i", "o").  */ 
1333 /***ja
1334     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1335     
1336     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> 
1337     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1338     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1339
1340 MSymbol Mstyle;
1341
1342 /***en
1343     @brief Key of font property specifying stretch.
1344
1345     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1346     is used as a key of font property and face property.  The property
1347     value must be a symbol whose name is a stretch name of a font (e.g
1348     "normal", "condensed").  */ 
1349 /***ja
1350     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1351     
1352     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> 
1353     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1354     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1355
1356 MSymbol Mstretch;
1357
1358 /***en
1359     @brief Key of font property specifying additional style.
1360
1361     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1362     is used as a key of font property and face property.  The property
1363     value must be a symbol whose name is an additional style name of a
1364     font (e.g "serif", "", "sans").  */ 
1365 /***ja
1366     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1367     
1368     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> 
1369     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1370     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1371
1372 MSymbol Madstyle;
1373
1374 /***en
1375     @brief Key of font property specifying registry.
1376
1377     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1378     and is used as a key of font property.  The property value must be
1379     a symbol whose name is a registry name a font registry
1380     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1381 /***ja
1382     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1383     
1384     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> 
1385     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1386     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" 
1387     Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1388
1389 MSymbol Mregistry;
1390
1391 /***en
1392     @brief Key of font property specifying size.
1393
1394     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1395     used as a key of font property and face property.  The property
1396     value must be an integer specifying a font design size in the unit
1397     of 1/10 point (on 100 dpi display).  */ 
1398 /***ja
1399     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1400     
1401     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> 
1402     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1403     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 
1404     ¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
1405     */
1406
1407 MSymbol Msize;
1408
1409 /***en
1410     @brief Key of font property specifying resolution.
1411
1412     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1413     is used as a key of font property and face property.  The property
1414     value must be an integer to specifying a font resolution in the
1415     unit of dots per inch (dpi).  */ 
1416 /***ja
1417     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1418     
1419     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> 
1420     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1421     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£    */
1422
1423 MSymbol Mresolution;
1424
1425 /***en
1426     @brief Symbol of name "fontconfig".
1427
1428     The variable #Mfontconfig is to be used as an argument of the
1429     functions mfont_parse_name () and mfont_unparse_name ().  */
1430 /***ja
1431     @brief "fontconfig" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
1432
1433     ÊÑ¿ô #Mfontconfig ¤Ï´Ø¿ô mfont_parse_name () ¤È mfont_unparse_name ()
1434     ¤Î°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£  */
1435
1436 MSymbol Mfontconfig;
1437
1438 /***en
1439     @brief Symbol of name "x".
1440
1441     The variable #Mx is to be used for a value of <type> member of the
1442     structure #MDrawGlyph to specify the type of <fontp> member is
1443     actually (XFontStruct *).  */
1444 /***ja
1445     @brief "x" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
1446
1447     ÊÑ¿ô #Mx ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
1448     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XFontStruct *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹.  */
1449
1450 MSymbol Mx;
1451
1452 /***en
1453     @brief Symbol of name "freetype".
1454
1455     The variable #Mfreetype is to be used for a value of <type> member
1456     of the structure #MDrawGlyph to specify the type of <fontp> member
1457     is actually FT_Face.  */
1458 /***ja
1459     @brief "freetype" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
1460
1461     ÊÑ¿ô #Mfreetype ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
1462     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï FT_Face ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£  */
1463
1464 MSymbol Mfreetype;
1465
1466 /***en
1467     @brief Symbol of name "xft".
1468
1469     The variable #Mxft is to be used for a value of <type> member of the
1470     structure #MDrawGlyph to specify the type of <fontp> member
1471     is actually (XftFont *).  */
1472 /***ja
1473     @brief  "xft" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
1474
1475     ÊÑ¿ô #Mxft ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
1476     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XftFont *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£  */
1477
1478 MSymbol Mxft;
1479
1480 /*=*/
1481 /*** @} */
1482 /*=*/
1483
1484 /***en
1485     @brief List of font files and directories that contain font files.
1486
1487     The variable @c mfont_freetype_path is a plist of FreeType font
1488     files and directories that contain FreeType font files.  Key of
1489     the element is @c Mstring, and the value is a string that
1490     represents a font file or a directory.
1491
1492     The macro M17N_INIT () sets up this variable to contain the
1493     sub-directory "fonts" of the m17n database and the environment
1494     variable "M17NDIR".  The first call of mframe () creates the
1495     internal list of the actually available fonts from this variable.
1496     Thus, an application program, if necessary, must modify the
1497     variable before calling mframe ().  If it is going to add a new
1498     element, value must be a string that can be safely freed.
1499
1500     If the m17n library is not configured to use the FreeType library,
1501     this variable is not used.  */
1502 /***ja
1503     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
1504
1505     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î 
1506     plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring 
1507     ¤Ç¤¢¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
1508
1509     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ¿ô 
1510     "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
1511     mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£
1512     ¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢mframe () 
1513     ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1514     ¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1515
1516     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
1517
1518 MPlist *mfont_freetype_path;
1519
1520 /*=*/
1521
1522 /***en
1523     @brief Create a new font.
1524
1525     The mfont () function creates a new font object that has no
1526     property.
1527
1528     @return
1529     This function returns a pointer to the created font object.  */
1530 /***ja
1531     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
1532
1533     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
1534
1535     @return
1536     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
1537
1538 MFont *
1539 mfont ()
1540 {
1541   MFont *font;
1542
1543   MSTRUCT_CALLOC (font, MERROR_FONT);
1544   return font;
1545 }
1546
1547 /*=*/
1548
1549 /***en
1550     @brief Create a font by parsing a fontname.
1551
1552     The mfont_parse_name () function creates a new font object.  The
1553     properties are extracted fontname $NAME.
1554
1555     $FORMAT specifies the format of $NAME.  If $FORMAT is #Mx, $NAME
1556     is parsed as XLFD (X Logical Font Description).  If $FORMAT is
1557     #Mfontconfig, $NAME is parsed as Fontconfig's textual
1558     representation of font.  If $FORMAT is #Mnil, $NAME is at first
1559     parsed as XLFD, and it it fails, parsed as Fontconfig's
1560     representation.
1561
1562     @return
1563     If the operation was successful, this function returns a pointer
1564     to the created font.  Otherwise it returns @c NULL.  */
1565
1566 /***ja
1567     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1568
1569     ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ 
1570     $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
1571
1572     $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
1573     $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1574     $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig 
1575     ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD 
1576     ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1577
1578     @return
1579     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () 
1580     ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
1581
1582 MFont *
1583 mfont_parse_name (char *name, MSymbol format)
1584 {
1585   MFont template, *font;
1586   
1587   MFONT_INIT (&template);
1588   if (mfont__parse_name_into_font (name, format, &template) < 0)
1589     MERROR (MERROR_FONT, NULL);
1590   MSTRUCT_CALLOC (font, MERROR_FONT);
1591   *font = template;
1592   return font;
1593 }
1594
1595 /*=*/
1596
1597 /***en
1598     @brief Create a fontname from a font.
1599
1600     The mfont_unparse_name () function creates a fontname string
1601     from font $FONT according to $FORMAT.
1602
1603     $FORMAT must be #Mx or #Mfontconfig.  If it is #Mx, the fontname
1604     is in XLFD (X Logical Font Description) format.  If it is
1605     #Mfontconfig, the fontname is in the style of Fontconfig's text
1606     representation.
1607
1608     @return
1609     This function returns a newly allocated fontname string, which is
1610     not freed unless the user explicitly does so by free ().  */
1611
1612 /***ja
1613     @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
1614
1615     ´Ø¿ô mfont_unparse_name () ¤Ï ¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È $FONT 
1616     ¤ò¸µ¤Ë$FORMAT ¤Ë½¾¤Ã¤Æºî¤ë¡£
1617
1618     $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤¢¤ë¡£
1619     #Mx ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£
1620     #Mfontconfig ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
1621
1622     @return 
1623     ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶¤¬
1624     free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
1625
1626 char *
1627 mfont_unparse_name (MFont *font, MSymbol format)
1628 {
1629   char *name;
1630
1631   if (format == Mx)
1632     name = xlfd_unparse_name (font);
1633 #ifdef HAVE_FONTCONFIG
1634   else if (format == Mfontconfig)
1635     name = mfont__ft_unparse_name (font);
1636 #endif
1637   else
1638     MERROR (MERROR_FONT, NULL);
1639   return name;
1640 }
1641
1642 /*=*/
1643
1644 /***en
1645     @brief Make a copy of a font.
1646
1647     The mfont_copy () function returns a new copy of font $FONT.  */
1648 /***ja
1649     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
1650
1651     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
1652
1653 MFont *
1654 mfont_copy (MFont *font)
1655 {
1656   MFont *copy;
1657
1658   MSTRUCT_MALLOC (copy, MERROR_FONT);
1659   *copy = *font;
1660   return copy;
1661 }
1662
1663 /*=*/
1664
1665 /***en
1666     @brief Get a property value of a font.
1667
1668     The mfont_get_prop () function gets the value of $KEY property of
1669     font $FONT.  $KEY must be one of the following symbols:
1670
1671         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1672         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1673
1674     @return
1675     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1676     Madstyle, or @c Mregistry, this function returns the
1677     corresponding value as a symbol.  If the font does not have $KEY
1678     property, it returns @c Mnil.
1679     If $KEY is @c Msize or @c Mresolution, this function returns the
1680     corresponding value as an integer.  If the font does not have $KEY
1681     property, it returns 0.
1682     If $KEY is something else, it returns @c NULL and assigns an error
1683     code to the external variable #merror_code.  */
1684  
1685 /***ja
1686     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1687
1688     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
1689     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
1690
1691         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1692         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1693
1694     @return 
1695     $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1696     Madstyle, @c Mregistry ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È¤·¤ÆÊÖ¤¹¡£
1697     ¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c Mnil ¤òÊÖ¤¹¡£
1698     $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution 
1699     ¤Î¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 
1700     ¤òÊÖ¤¹¡£$KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
1701     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1702
1703 void *
1704 mfont_get_prop (MFont *font, MSymbol key)
1705 {
1706   if (key == Mfoundry)
1707     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
1708   if (key == Mfamily)
1709     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
1710   if (key == Mweight)
1711     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
1712   if (key == Mstyle)
1713     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
1714   if (key == Mstretch)
1715     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
1716   if (key == Madstyle)
1717     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
1718   if (key == Mregistry)
1719     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
1720   if (key == Msize)
1721     {
1722       int size = font->property[MFONT_SIZE];
1723       return (void *) size;
1724     }
1725   if (key == Mresolution)
1726     {
1727       int resy = font->property[MFONT_RESY];
1728       return (void *) resy;
1729     }
1730
1731   MERROR (MERROR_FONT, NULL);
1732 }
1733
1734
1735 /*=*/
1736 /***en
1737     @brief Put a property value to a font.
1738
1739     The mfont_put_prop () function puts a font property whose key is
1740     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
1741     following symbols:
1742
1743         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1744         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1745
1746     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
1747     Otherwise, $VAL must be a symbol.  */
1748  /***ja
1749     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
1750
1751     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY 
1752     ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
1753
1754         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1755         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1756
1757     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL 
1758     ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
1759
1760 int
1761 mfont_put_prop (MFont *font, MSymbol key, void *val)
1762 {
1763   if (key == Mfoundry)
1764     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
1765   else if (key == Mfamily)
1766     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
1767   else if (key == Mweight)
1768     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
1769   else if (key == Mstyle)
1770     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
1771   else if (key == Mstretch)
1772     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
1773   else if (key == Madstyle)
1774     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
1775   else if (key == Mregistry)
1776     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
1777   else if (key == Msize)
1778     {
1779       unsigned size = (unsigned) val;
1780       font->property[MFONT_SIZE] = size;
1781     }
1782   else if (key == Mresolution)
1783     {
1784       unsigned resy = (unsigned) val;
1785       font->property[MFONT_RESY] =  resy;
1786     }
1787   else
1788     MERROR (MERROR_FONT, -1);
1789   return 0;
1790 }
1791
1792 /*=*/
1793
1794 /***en
1795     @brief Return the font selection priority.
1796
1797     The mfont_selection_priority () function returns a newly created
1798     array of six symbols.  The elements are the following
1799     keys of font properties ordered by priority.
1800
1801         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1802         @c Madstyle, @c Msize.
1803
1804    The m17n library selects the best matching font according to the
1805    order of this array.  A font that has a different value for a
1806    property of lower priority is preferred to a font that has a
1807    different value for a property of higher priority.  */
1808 /***ja
1809     @brief ¥Õ¥©¥ó¥ÈÁªÂò¤ÎÍ¥ÀèÅÙ¤òÊÖ¤¹.
1810
1811     ´Ø¿ô mfont_selection_priority () ¤Ï 6 ¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã¤ÆÊÖ¤¹¡£
1812     ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤Ëʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
1813
1814         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1815         @c Madstyle, @c Msize.
1816
1817    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
1818    ÌÜŪ¤Î¥Õ¥©¥ó¥È¤È¡¢¤½¤ì¤¾¤ì°ã¤¦¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¤¬¤¢¤Ã¤¿¾ì¹ç¡¢Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¡ÊÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Æ¤¤¤ë¥Õ¥©¥ó¥È¡Ë¤¬ÁªÂò¤µ¤ì¤ë¡£
1819
1820    */
1821
1822 MSymbol *
1823 mfont_selection_priority ()
1824 {
1825   MSymbol *keys;
1826   int i;
1827
1828   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
1829   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1830     {
1831       enum MFontProperty prop = font_score_priority[i];
1832
1833       if (prop == MFONT_SIZE)
1834         keys[i] = Msize;
1835       else if (prop == MFONT_ADSTYLE)
1836         keys[i] = Madstyle;
1837       else if (prop == MFONT_FAMILY)
1838         keys[i] = Mfamily;
1839       else if (prop == MFONT_WEIGHT)
1840         keys[i] = Mweight;
1841       else if (prop == MFONT_STYLE)
1842         keys[i] = Mstyle;
1843       else if (prop == MFONT_STRETCH)
1844         keys[i] = Mstretch;
1845       else
1846         keys[i] = Mfoundry;
1847     }
1848   return keys;
1849 }
1850
1851 /*=*/
1852
1853 /***en
1854     @brief Set the font selection priority.
1855
1856     The mfont_set_selection_priority () function sets font selection
1857     priority according to $KEYS, which is an array of six symbols.
1858     Each element must be one of the below.  No two elements must be
1859     the same.
1860
1861         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1862         @c Madstyle, @c Msize.
1863
1864     See the documentation of the function mfont_selection_priority ()
1865     for details.  */
1866 /***ja
1867     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
1868
1869     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
1870     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£ÇÛÎó¤Ï°Ê²¼¤Î³ÆÍ×ÁǤòŬÀÚ
1871     ¤Ê½çÈÖ¤Çʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
1872
1873         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1874         @c Madstyle, @c Msize.
1875
1876     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
1877      */
1878
1879 int
1880 mfont_set_selection_priority (MSymbol *keys)
1881 {
1882   int priority[FONT_SCORE_PRIORITY_SIZE];
1883   int i, j;
1884
1885   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
1886     {
1887       enum MFontProperty prop;
1888
1889       if (*keys == Msize)
1890         prop = MFONT_SIZE;
1891       else if (*keys == Madstyle)
1892         prop = MFONT_ADSTYLE;
1893       else if (*keys == Mfamily)
1894         prop = MFONT_FAMILY;
1895       else if (*keys == Mweight)
1896         prop = MFONT_WEIGHT;
1897       else if (*keys == Mstyle)
1898         prop = MFONT_STYLE;
1899       else if (*keys == Mstretch)
1900         prop = MFONT_STRETCH;
1901       else if (*keys == Mfoundry)
1902         prop = MFONT_FOUNDRY;
1903       else
1904         /* Invalid element.  */
1905         return -1;
1906       for (j = 0; j < i; j++)
1907         if (priority[j] == prop)
1908           /* Duplicated element.  */
1909           return -1;
1910       priority[i] = prop;
1911     }
1912   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1913     font_score_priority[i] = priority[i];
1914   return 0;
1915 }
1916
1917 /*=*/
1918
1919 /***en
1920     @brief Find a font.
1921
1922     The mfont_find () function returns a pointer to the available font
1923     that matches best the specification $SPEC on frame $FRAME.
1924
1925     $SCORE, if not NULL, must point to a place to store the score
1926     value that indicates how well the found font matches to $SPEC.  The
1927     smaller score means a better match.  */
1928 /***ja
1929     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
1930
1931     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC 
1932     ¤Ë¤â¤Ã¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
1933
1934     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC 
1935     ¤Ë¤É¤ì¤Û¤É¹ç¤Ã¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£
1936     ¥¹¥³¥¢¤¬¾®¤µ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1937     */
1938
1939 MFont *
1940 mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
1941 {
1942   MFont spec_copy;
1943   MRealizedFont *rfont;
1944
1945   MFONT_INIT (&spec_copy);
1946   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
1947
1948   rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
1949   if (!rfont)
1950     return NULL;
1951   if (score)
1952     *score = rfont->score;
1953   return &rfont->font;
1954 }
1955
1956 /*=*/
1957 /***en
1958     @brief Set encoding of a font.
1959
1960     The mfont_set_encoding () function sets the encoding information
1961     of font $FONT.
1962
1963     $ENCODING_NAME is a symbol representing a charset that has the
1964     same encoding as the font.
1965
1966     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
1967     has the same repertory as the font.  If it is @c Mnil, whether a
1968     specific character is supported by the font is asked to each font
1969     driver.
1970
1971     @return
1972     If the operation was successful, this function returns 0.
1973     Otherwise it returns -1 and assigns an error code to the external
1974     variable #merror_code.  */
1975 /***ja
1976     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
1977
1978     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó¤òÀßÄꤹ¤ë¡£
1979
1980     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1981
1982     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1983     @c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ»ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢³Æ¡¹¤Î¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ËÌ䤤¹ç¤ï¤»¤ë¡£
1984
1985     @return
1986     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô
1987     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1988
1989
1990 int
1991 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
1992 {
1993   MCharset *encoding_charset = MCHARSET (encoding_name);
1994   MCharset *repertory_charset;
1995   MSymbol registry;
1996   MFontEncoding *encoding;
1997   MPlist *plist;
1998
1999   if (! encoding_charset)
2000     MERROR (MERROR_FONT, -1);
2001   if (repertory_name != Mnil)
2002     {
2003       repertory_charset = MCHARSET (repertory_name);
2004       if (! repertory_charset)
2005         MERROR (MERROR_FONT, -1);
2006     }
2007   else
2008     repertory_charset = NULL;
2009
2010   MSTRUCT_CALLOC (encoding, MERROR_FONT);
2011   encoding->spec = *font;
2012   encoding->encoding_name = encoding_name;
2013   encoding->encoding_charset = encoding_charset;
2014   encoding->repertory_name = repertory_name;
2015   encoding->repertory_charset = repertory_charset;
2016   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
2017   if (registry == Mnil)
2018     registry = Mt;
2019   if (! font_encoding_list)
2020     load_font_encoding_table ();
2021   mplist_push (font_encoding_list, registry, encoding);
2022   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
2023     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
2024                   sizeof (MFont)))
2025       {
2026         mplist_pop (plist);
2027         break;
2028       }
2029   return 0;
2030 }
2031
2032 /*=*/
2033
2034 /***en
2035     @brief Create a fontname from a font.
2036
2037     This function is obsolete.   Use mfont_unparse_name instead. */
2038 /***ja
2039     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2040
2041     ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
2042
2043 char *
2044 mfont_name (MFont *font)
2045 {
2046   return mfont_unparse_name (font, Mx);
2047 }
2048
2049 /*=*/
2050
2051 /***en
2052     @brief Create a new font from fontname.
2053
2054     This function is obsolete.  Use mfont_parse_name () instead.  */
2055
2056 /***ja
2057     @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
2058
2059     ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
2060
2061 MFont *
2062 mfont_from_name (char *name)
2063 {
2064   return mfont_parse_name (name, Mx);
2065 }
2066
2067 /*=*/
2068
2069 /***en
2070     @brief Get resize information of a font.
2071
2072     The mfont_resize_ratio () function lookups the m17n database
2073     \<font, reisize\> and returns a resizing ratio (in percentage) of
2074     FONT.  For instance, if the return value is 150, that means that
2075     the m17n library uses an 1.5 time bigger font than a specified
2076     size.  */
2077
2078 /***ja
2079     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥µ¥¤¥º¾ðÊó¤òÆÀ¤ë
2080
2081     ´Ø¿ô mfont_resize_ratio ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹ \<font, reisize\> 
2082     ¤ò¸¡º÷¤·¡¢¥Õ¥©¥ó¥È FONT ¤Î¥ê¥µ¥¤¥º¤ÎÈæΨ¡Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¡Ë
2083     ¤òÊÖ¤¹¡£¤¿¤È¤¨¤ÐÊÖ¤¹Ãͤ¬ 150 ¤Ç¤¢¤ì¤Ð¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ï»ØÄꤵ¤ì¤¿¥µ¥¤¥º¤Î 1.5 
2084     ÇܤΥե©¥ó¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ */
2085
2086 int
2087 mfont_resize_ratio (MFont *font)
2088 {
2089   MFont request = *font;
2090
2091   mfont__resize (font, &request);
2092   return (font->property[MFONT_SIZE] * 100 / request.property[MFONT_SIZE]);
2093 }
2094
2095 /*=*/
2096
2097 /***en
2098     @brief Get a list of fonts.
2099
2100     The mfont_list () functions returns a list of fonts available on
2101     frame $FRAME.  $FONT, if not @c Mnil, limits fonts to ones
2102     that match with $FONT.  $LANGUAGE, if not @c Mnil, limits fonts to
2103     ones that support $LANGUAGE.  $MAXNUM, if greater than 0, limits
2104     the number of fonts.
2105
2106     @return
2107     This function returns a plist whose keys are family names and
2108     values are pointers to the object MFont.  The plist must be freed
2109     by m17n_object_unref ().  If no font is found, it returns
2110     NULL.  */
2111
2112 /***ja
2113     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë
2114
2115     ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2116     $FONT ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2117     $LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2118     $MAXNUM ¤Ï¡¢0 ¤è¤êÂ礭¤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
2119
2120     @return 
2121     ¤³¤Î´Ø¿ô¤Ï¥­¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê
2122     plist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref () 
2123     ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£  */
2124
2125 MPlist *
2126 mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum)
2127 {
2128   MPlist *plist = mplist (), *p;
2129   int num = 0;
2130   
2131   MPLIST_DO (p, frame->font_driver_list)
2132     {
2133       MFontDriver *driver = MPLIST_VAL (p);
2134
2135       num += (driver->list) (frame, plist, font, language,
2136                              maxnum > 0 ? maxnum - num : 0);
2137       if (maxnum > 0 && num >= maxnum)
2138         break;
2139     }
2140   if (MPLIST_TAIL_P (plist))
2141     {
2142       M17N_OBJECT_UNREF (plist);
2143       plist = NULL;
2144     }
2145   return plist;
2146 }
2147
2148 /*** @} */
2149
2150 /*** @addtogroup m17nDebug */
2151 /*=*/
2152 /*** @{ */
2153
2154 /***en
2155     @brief Dump a font.
2156
2157     The mdebug_dump_font () function prints font $FONT in a human readable
2158     way to the stderr.
2159
2160     @return
2161     This function returns $FONT.  */
2162 /***ja
2163     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
2164
2165     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr 
2166     ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£
2167
2168     @return
2169     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
2170
2171 MFont *
2172 mdebug_dump_font (MFont *font)
2173 {
2174   char *name;
2175   
2176   name = mfont_unparse_name (font, Mx);
2177   if (name)
2178     {
2179       fprintf (stderr, "%s", name);
2180       free (name);
2181     }
2182   return font;
2183 }
2184
2185 void
2186 mdebug_dump_font_list (MFrame *frame, MSymbol family, MSymbol lang)
2187 {
2188   MPlist *plist, *p;
2189
2190   if (family == Mnil)
2191     plist = mfont_list (frame, NULL, lang, 0);
2192   else
2193     {
2194       MFont font;
2195
2196       MFONT_INIT (&font);
2197       mfont__set_property (&font, MFONT_FAMILY, family);
2198       plist = mfont_list (frame, &font, lang, 0);
2199     }
2200   MPLIST_DO (p, plist)
2201     {
2202       mdebug_dump_font (MPLIST_VAL (p));
2203       fprintf (stderr, "\n");
2204     }
2205   M17N_OBJECT_UNREF (plist);
2206 }
2207
2208 /*** @} */
2209
2210 /*
2211   Local Variables:
2212   coding: euc-japan
2213   End:
2214 */