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