(mfont_list): New function.
[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     "r",
388     "ri",
389     "ro" };
390 static char *common_stretch[] =
391   { "condensed",
392     "narrow",
393     "semicondensed",
394     "normal",
395     "semiexpanded",
396     "expanded" };
397 static char *common_adstyle[] =
398   { "serif",
399     "",
400     "sans" };
401 static char *common_registry[] =
402   { "iso8859-1" };
403
404 /* Table containing all the data above.  */
405
406 struct MFontCommonNames
407 {
408   int num;
409   char **names;
410 };
411
412 static struct MFontCommonNames font_common_names[] =
413   {
414     { sizeof (common_foundry) / sizeof (char *), common_foundry},
415     { sizeof (common_family) / sizeof (char *), common_family},
416     { sizeof (common_weight) / sizeof (char *), common_weight},
417     { sizeof (common_style) / sizeof (char *), common_style},
418     { sizeof (common_stretch) / sizeof (char *), common_stretch},
419     { sizeof (common_adstyle) / sizeof (char *), common_adstyle},
420     { sizeof (common_registry) / sizeof (char *), common_registry}
421   };
422
423
424 /** Table of available font property names.  */
425
426 MFontPropertyTable mfont__property_table[MFONT_REGISTRY + 1];
427
428
429 /** Return the numeric value of SYMBOL as the Nth font property.  */
430
431 #define FONT_PROPERTY_NUMERIC(symbol, n)        \
432   ((symbol) == Mnil                             \
433    ? 0                                          \
434    : ((int) msymbol_get ((symbol), mfont__property_table[(n)].property)))
435
436
437 /** Set the numeric value of SYMBOL as the Nth font property to NUMERIC.  */
438
439 #define SET_FONT_PROPERTY_NUMERIC(symbol, n, numeric)           \
440   msymbol_put((symbol), mfont__property_table[(n)].property,    \
441               (void *) (numeric))
442
443 static char *
444 gen_font_name (char *buf, MFont *font)
445 {
446   char size[16];
447   int i;
448
449   buf[0] = '\0';
450   for (i = 0; i <= MFONT_REGISTRY; i++)
451     if (FONT_PROPERTY (font, i) != Mnil)
452       {
453         char *name = msymbol_name (FONT_PROPERTY (font, i));
454
455         if (name[0])
456           {
457             if (i > 0)
458               strcat (buf, ",");
459             strcat (buf, name);
460           }
461       }
462   sprintf (size, ",%d", font->property[MFONT_SIZE] / 10);
463   strcat (buf, size);
464   return buf;
465 }
466
467
468 \f
469 /* Font selector.  */
470
471 struct MFontEncoding {
472   MFont spec;
473   MSymbol encoding_name;
474   MCharset *encoding_charset;
475   MSymbol repertory_name;
476   MCharset *repertory_charset;
477 };
478
479 static MPlist *font_encoding_list;
480 static MFontEncoding default_encoding;
481
482 /** Load font encoding table from the data <font encoding>.
483     The data has this form:
484         (FONT-SPEC ENCODING) ...
485     where FONT-SPEC has this form:
486         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
487     All elements are symbols.  */
488
489 static int
490 load_font_encoding_table ()
491 {
492   MDatabase *mdb;
493   MPlist *encoding_list, *plist, *pl, *elt;
494
495   font_encoding_list = pl = mplist ();
496
497   mdb = mdatabase_find (Mfont, msymbol ("encoding"), Mnil, Mnil);
498   if (! mdb
499       || ! (encoding_list = (MPlist *) mdatabase_load (mdb)))
500     MERROR (MERROR_FONT, -1);
501
502   MPLIST_DO (plist, encoding_list)
503     {
504       MFontEncoding *encoding;
505       MSymbol registry;
506
507       MSTRUCT_CALLOC (encoding, MERROR_FONT);
508
509       if (! MPLIST_PLIST_P (plist)
510           || (elt = MPLIST_PLIST (plist), mplist_length (elt) < 2)
511           || ! MPLIST_PLIST_P (elt))
512         MWARNING (MERROR_FONT);
513       registry = mfont__set_spec_from_plist (&encoding->spec,
514                                              MPLIST_PLIST (elt));
515       elt = MPLIST_NEXT (elt);
516       if (! MPLIST_SYMBOL_P (elt))
517         MWARNING (MERROR_FONT);
518       encoding->encoding_name = MPLIST_SYMBOL (elt);
519       elt = MPLIST_NEXT (elt);
520       if (MPLIST_TAIL_P (elt))
521         encoding->repertory_name = encoding->encoding_name;
522       else if (! MPLIST_SYMBOL_P (elt))
523         MWARNING (MERROR_FONT);
524       else
525         encoding->repertory_name = MPLIST_SYMBOL (elt);
526
527       if (registry == Mnil)
528         registry = Mt;
529       pl = mplist_add (pl, registry, encoding);
530       continue;
531
532     warning:
533       free (encoding);
534     }
535
536   M17N_OBJECT_UNREF (encoding_list);
537   return 0;
538 }
539
540 typedef struct {
541   MFont spec;
542   int resize;
543 } MFontResize;
544
545 static MPlist *font_resize_list;
546
547 /** Load font size table from the data <font size>.
548     The data has this form:
549         (FONT-SPEC RESIZE-FACTOR) ...
550     where FONT-SPEC has this form:
551         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
552     All elements of FONT-SPEC are symbols.  */
553
554 static int
555 load_font_resize_table ()
556 {
557   MDatabase *mdb;
558   MPlist *size_adjust_list, *plist, *pl, *elt;
559
560   font_resize_list = pl = mplist ();
561
562   mdb = mdatabase_find (Mfont, msymbol ("resize"), Mnil, Mnil);
563   if (! mdb)
564     return -1;
565   if (! (size_adjust_list = (MPlist *) mdatabase_load (mdb)))
566     MERROR (MERROR_FONT, -1);
567
568   MPLIST_DO (plist, size_adjust_list)
569     {
570       MFontResize *resize;
571       MSymbol registry;
572
573       MSTRUCT_CALLOC (resize, MERROR_FONT);
574
575       if (! MPLIST_PLIST_P (plist)
576           || (elt = MPLIST_PLIST (plist), mplist_length (elt) != 2)
577           || ! MPLIST_PLIST_P (elt))
578         MWARNING (MERROR_FONT);
579       registry = mfont__set_spec_from_plist (&resize->spec,
580                                              MPLIST_PLIST (elt));
581       elt = MPLIST_NEXT (elt);
582       if (! MPLIST_INTEGER_P (elt))
583         MWARNING (MERROR_FONT);
584       resize->resize = MPLIST_INTEGER (elt);
585
586       if (registry == Mnil)
587         registry = Mt;
588       pl = mplist_add (pl, registry, resize);
589       continue;
590
591     warning:
592       free (resize);
593     }
594
595   M17N_OBJECT_UNREF (size_adjust_list);
596   return 0;
597 }
598
599 /** Return a font encoding (and repertory) of FONT.  */
600
601 static MFontEncoding *
602 find_encoding (MFont *font)
603 {
604   MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
605   MFontEncoding *encoding = NULL;
606   MPlist *plist;
607
608   if (! font_encoding_list)
609     load_font_encoding_table ();
610   if (! MPLIST_TAIL_P (font_encoding_list))
611     while (1)
612       {
613         plist = font_encoding_list;
614         while (registry ? (plist = mplist_find_by_key (plist, registry))
615                : plist)
616           {
617             encoding = (MFontEncoding *) MPLIST_VAL (plist);
618             if (mfont__match_p (font, &encoding->spec, MFONT_ADSTYLE))
619               {
620                 if (! encoding->encoding_charset)
621                   encoding->encoding_charset
622                     = MCHARSET (encoding->encoding_name);
623                 if (! encoding->encoding_charset)
624                   {
625                     mplist_pop (plist);
626                     continue;
627                   }
628                 if (encoding->repertory_name == encoding->encoding_name)
629                   encoding->repertory_charset = encoding->encoding_charset;
630                 else if (encoding->repertory_name != Mnil)
631                   {
632                     encoding->repertory_charset
633                       = MCHARSET (encoding->repertory_name);
634                     if (! encoding->repertory_charset)
635                       {
636                         mplist_pop (plist);
637                         continue;
638                       }
639                   }
640                 return encoding;
641               }
642             else
643               plist = MPLIST_NEXT (plist);
644           }
645         if (registry == Mnil || registry == Mt)
646           break;
647         registry = Mt;
648       }
649   return &default_encoding;
650 }
651
652 /* XLFD parser/generator */
653
654 /** Indices to each field of split font name.  */
655
656 enum xlfd_field_idx
657   {
658     XLFD_FOUNDRY,
659     XLFD_FAMILY,
660     XLFD_WEIGHT,
661     XLFD_SLANT,
662     XLFD_SWIDTH,
663     XLFD_ADSTYLE,
664     XLFD_PIXEL,
665     XLFD_POINT,
666     XLFD_RESX,
667     XLFD_RESY,
668     XLFD_SPACING,
669     XLFD_AVGWIDTH,
670     XLFD_REGISTRY,              /* This contains ENCODING.  */
671     /* anchor */
672     XLFD_FIELD_MAX
673   };
674
675 static int
676 xlfd_parse_name (char *name, MFont *font)
677 {
678   char *field[XLFD_FIELD_MAX];
679   unsigned short size, resy;
680   MSymbol attrs[MFONT_PROPERTY_MAX];
681   char copy[513];
682   int i;
683   char *p;
684
685   if (name[0] != '-')
686     return -1;
687
688   field[0] = copy;
689   for (i = 1, p = copy, name++; *name; p++, name++)
690     {
691       if (p - copy > 512)
692         return -1;
693       if (*name == '-'
694           && i < XLFD_FIELD_MAX)
695         {
696           *p = '\0';
697           if (field[i - 1][0] == '*')
698             field[i - 1] = NULL;
699           field[i++] = p + 1;
700         }
701       else
702         *p = tolower (*name);
703     }
704   *p = '\0';
705   if (field[i - 1][0] == '*')
706     field[i - 1] = NULL;
707   while (i < XLFD_FIELD_MAX)
708     field[i++] = NULL;
709
710   resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0;
711   if (! field[XLFD_PIXEL])
712     size = field[XLFD_POINT] ? atoi (field[XLFD_POINT]) * resy / 72 : 0;
713   else if (field[XLFD_PIXEL][0] == '[')
714     {
715       /* The pixel size field specifies a transformation matrix of the
716          form "[A B C D]".  The XLFD spec says that the scalar value N
717          for the pixel size is equivalent to D.  */
718       char *p0 = field[XLFD_PIXEL] + 1, *p1;
719       double d;
720
721       for (i = 0; i < 4; i++, p0 = p1)
722         d = strtod (p0, &p1);
723       size = d * 10;
724     }
725   else
726     size = atoi (field[XLFD_PIXEL]) * 10;
727
728   attrs[MFONT_FOUNDRY]
729     = field[XLFD_FOUNDRY] ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
730   attrs[MFONT_FAMILY]
731     = field[XLFD_FAMILY] ? msymbol (field[XLFD_FAMILY]) : Mnil;
732   attrs[MFONT_WEIGHT]
733     = field[XLFD_WEIGHT] ? msymbol (field[XLFD_WEIGHT]) : Mnil;
734   attrs[MFONT_STYLE]
735     = field[XLFD_SLANT] ? msymbol (field[XLFD_SLANT]) : Mnil;
736   attrs[MFONT_STRETCH]
737     = field[XLFD_SWIDTH] ? msymbol (field[XLFD_SWIDTH]) : Mnil;
738   attrs[MFONT_ADSTYLE]
739     = field[XLFD_ADSTYLE] ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
740   attrs[MFONT_REGISTRY]
741     = field[XLFD_REGISTRY] ? msymbol (field[XLFD_REGISTRY]) : Mnil;
742   mfont__set_spec (font, attrs, size, resy);
743   return 0;
744 }
745
746 static char *
747 xlfd_unparse_name (MFont *font)
748 {
749   MSymbol prop[7];
750   char name[513];
751   char *str[7];
752   int len, i;
753   unsigned short size, resy;
754
755   prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
756   prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
757   prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
758   prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
759   prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
760   prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
761   prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
762   for (len = 0, i = 0; i < 7; i++)
763     {
764       if (prop[i] != Mnil)
765         {
766           str[i] = msymbol_name (prop[i]);
767           len += strlen (str[i]);
768         }
769       else
770         {
771           str[i] = "*";
772           len++;
773         }
774     }
775   if ((len
776        + 12                     /* 12 dashes */
777        + 3                      /* 3 asterisks */
778        + 30                     /* 3 integers (each 10 digits) */
779        + 1)                     /* '\0' terminal */
780       > 513)
781     return NULL;
782
783   size = (int) mfont_get_prop (font, Msize);
784   if ((size % 10) < 5)
785     size /= 10;
786   else
787     size = size / 10 + 1;
788   resy = (int) mfont_get_prop (font, Mresolution);
789
790   sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s",
791            str[0], str[1], str[2], str[3], str[4], str[5],
792            size, resy, resy,  str[6]);
793   return strdup (name);
794 }
795
796 \f
797 /* Internal API */
798
799 int
800 mfont__init ()
801 {
802   int i, shift;
803
804   Mfoundry = msymbol ("foundry");
805   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
806   Mfamily = msymbol ("family");
807   mfont__property_table[MFONT_FAMILY].property = Mfamily;
808   Mweight = msymbol ("weight");
809   mfont__property_table[MFONT_WEIGHT].property = Mweight;
810   Mstyle = msymbol ("style");
811   mfont__property_table[MFONT_STYLE].property = Mstyle;
812   Mstretch = msymbol ("stretch");
813   mfont__property_table[MFONT_STRETCH].property = Mstretch;
814   Madstyle = msymbol ("adstyle");
815   mfont__property_table[MFONT_ADSTYLE].property = Madstyle;
816   Mregistry = msymbol ("registry");
817   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
818
819   Msize = msymbol ("size");
820   Mresolution = msymbol ("resolution");
821
822   Mfontconfig = msymbol ("fontconfig");
823
824   Mx = msymbol ("x");
825   Mfreetype = msymbol ("freetype");
826   Mxft = msymbol ("xft");
827
828   /* The first entry of each mfont__property_table must be Mnil so
829      that actual properties get positive numeric numbers.  */
830   for (i = 0; i <= MFONT_REGISTRY; i++)
831     {
832       MLIST_INIT1 (&mfont__property_table[i], names, 8);
833       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
834     }
835
836   /* Register predefined font property names.  */
837   for (i = 0; i <= MFONT_REGISTRY; i++)
838     {
839       int j;
840
841       for (j = 0; j < font_common_names[i].num; j++)
842         {
843           MSymbol sym = msymbol (font_common_names[i].names[j]);
844
845           if (sym == Mnil)
846             return -1;
847           if (msymbol_put (sym, mfont__property_table[i].property,
848                            (void *) (j + 1)) < 0)
849             return -1;
850           MLIST_APPEND1 (&mfont__property_table[i], names, sym, MERROR_FONT);
851         }
852     }
853
854   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
855      of a score is a flag for a scalable font (see the documentation
856      of mfont_score).  */
857   i = FONT_SCORE_PRIORITY_SIZE - 1;
858   for (shift = 1; i >= 0; i--)
859     {
860       font_score_shift_bits[font_score_priority[i]] = shift;
861       if (font_score_priority[i] == MFONT_SIZE)
862         shift += 16;
863       else
864         shift += 2;
865     }
866
867   MFONT_INIT (&default_encoding.spec);
868   default_encoding.encoding_name = Mnil;
869   default_encoding.encoding_charset = NULL;
870   default_encoding.repertory_name = Mnil;
871   default_encoding.repertory_charset = NULL;
872   {
873     char *path, *buf;
874     int bufsize;
875
876     mfont_freetype_path = mplist ();
877     bufsize = strlen (M17NDIR) + 7;
878     buf = alloca (bufsize);
879     sprintf (buf, "%s/fonts", M17NDIR);
880     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
881     path = getenv ("M17NDIR");
882     if (path)
883       {
884         i = strlen (path) + 7;
885         if (i > bufsize)
886           buf = alloca (i);
887         sprintf (buf, "%s/fonts", path);
888         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
889       }
890   }
891
892 #ifdef HAVE_FREETYPE
893   if (mfont__ft_init () < 0)
894     return -1;
895 #endif /* HAVE_FREETYPE */
896   if (mfont__flt_init () < 0)
897     return -1;
898
899   return 0;
900 }
901
902 void
903 mfont__fini ()
904 {
905   MPlist *plist;
906   int i;
907
908   mfont__flt_fini ();
909 #ifdef HAVE_FREETYPE
910   mfont__ft_fini ();
911 #endif /* HAVE_FREETYPE */
912
913   MPLIST_DO (plist, mfont_freetype_path)
914     free (MPLIST_VAL (plist));
915   M17N_OBJECT_UNREF (mfont_freetype_path);
916
917   if (font_resize_list)
918     {
919       MPLIST_DO (plist, font_resize_list)
920         free (MPLIST_VAL (plist));
921       M17N_OBJECT_UNREF (font_resize_list);
922       font_resize_list = NULL;
923     }
924   if (font_encoding_list)
925     {
926       MPLIST_DO (plist, font_encoding_list)
927         free (MPLIST_VAL (plist));
928       M17N_OBJECT_UNREF (font_encoding_list);
929       font_encoding_list = NULL;
930     }
931   for (i = 0; i <= MFONT_REGISTRY; i++)
932     MLIST_FREE1 (&mfont__property_table[i], names);
933 }
934
935 void
936 mfont__free_realized (MRealizedFont *rfont)
937 {
938   M17N_OBJECT_UNREF (rfont->info);
939   free (rfont);
940 }
941
942
943 /* Compare FONT with REQUEST and return how much they differs.  If
944    FONT does not match with SPEC, return -1.  */
945
946 int
947 mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size)
948 {
949   int score = 0;
950   int i = FONT_SCORE_PRIORITY_SIZE;
951
952   while (--i >= 0)
953     {
954       enum MFontProperty prop = font_score_priority[i];
955
956       if (request->property[prop] != 0)
957         {
958           int val = 0;
959
960           if (spec->property[prop] && font->property[prop]
961               && font->property[prop] != spec->property[prop])
962             return -1;
963           if (font->property[prop])
964             val = abs (font->property[prop] - request->property[prop]);
965           if (val && prop <= MFONT_FAMILY)
966             val = 1;
967           if (prop == MFONT_SIZE)
968             {
969               if (font->property[MFONT_RESY] == 0)
970                 /* This is a scalable font.  We prefer a bitmap font
971                    if the size matches exactly.  */
972                 score |= 1;
973               else
974                 score |= (val << font_score_shift_bits[MFONT_SIZE]
975                           | ((limited_size && val > 0) ? 0x400000 : 0));
976             }
977           else
978             score |= (val > 3 ? 3 : val) << font_score_shift_bits[prop];
979         }
980     }
981   return score;
982 }
983
984
985 /** Return 1 iff FONT matches SPEC.  */
986
987 int
988 mfont__match_p (MFont *font, MFont *spec, int prop)
989 {
990   for (; prop >= 0; prop--)
991     if (spec->property[prop] && font->property[prop]
992         && font->property[prop] != spec->property[prop])
993       return 0;
994   return 1;
995 }
996
997
998 void
999 mfont__set_spec_from_face (MFont *spec, MFace *face)
1000 {
1001   int i;
1002
1003   for (i = 0; i <= MFONT_ADSTYLE; i++)
1004     mfont__set_property (spec, i, face->property[i]);
1005   /* The value 1 is "iso8859-1".  */
1006   spec->property[MFONT_REGISTRY] = 1;
1007   spec->property[MFONT_SIZE] = (int) (face->property[MFACE_SIZE]);
1008   spec->property[MFONT_RESY] = 0;
1009 }
1010
1011
1012 extern MSymbol
1013 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
1014 {
1015   int i;
1016   MSymbol spec_list[MFONT_REGISTRY + 1];
1017   MSymbol registry;
1018
1019   MFONT_INIT (spec);
1020   memset (spec_list, 0, sizeof spec_list);
1021   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
1022     {
1023       if (! MPLIST_SYMBOL_P (plist))
1024         MERROR (MERROR_FONT, Mnil);     
1025       spec_list[i] = MPLIST_SYMBOL (plist);
1026     }
1027   registry = spec_list[i - 1];
1028   mfont__set_property (spec, MFONT_REGISTRY, registry);
1029   for (i -= 2; i >= 0; i--)
1030     mfont__set_property (spec, i, spec_list[i]);
1031   return registry;
1032 }
1033
1034 MRealizedFont *
1035 mfont__select (MFrame *frame, MFont *spec, MFont *request, int limited_size,
1036                MSymbol layouter)
1037 {
1038   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1039   MPlist *plist;
1040   MRealizedFont *best;
1041   int i;
1042   int mdebug_mask = MDEBUG_FONT;
1043
1044   if (registry == Mnil)
1045     registry = Mt;
1046
1047   MPLIST_DO (plist, frame->realized_font_list)
1048     {
1049       best = MPLIST_VAL (plist);
1050       if (MPLIST_KEY (plist) == registry
1051           && ! memcmp (&best->spec, spec, sizeof (MFont))
1052           && ! memcmp (&best->request, request, sizeof (MFont)))
1053         {
1054           if (best->layouter != layouter)
1055             {
1056               MRealizedFont *copy;
1057
1058               MSTRUCT_MALLOC (copy, MERROR_FONT);
1059               *copy = *best;
1060               copy->layouter = layouter;
1061               mplist_add (frame->realized_font_list, registry, copy);
1062               if (copy->info)
1063                 M17N_OBJECT_REF (copy->info);
1064               best = copy;
1065             }
1066           return best;
1067         }
1068     }
1069
1070   MDEBUG_PUSH_TIME ();
1071   best = NULL;
1072   MPLIST_DO (plist, frame->font_driver_list)
1073     {
1074       MFontDriver *driver = MPLIST_VAL (plist);
1075       MRealizedFont *this
1076         = (driver->select) (frame, spec, request, limited_size);
1077
1078       if (this)
1079         {
1080           this->driver = driver;
1081           if (! best
1082               || this->score < best->score)
1083             {
1084               if (best)
1085                 mfont__free_realized (best);
1086               best = this;
1087               if (this->score == 0)
1088                 break;
1089             }
1090           else
1091             mfont__free_realized (this);
1092         }
1093     }
1094
1095   if (mdebug__flag & mdebug_mask)
1096     {
1097       char buf1[256], buf2[256];
1098       MFont font = *spec;
1099
1100       for (i = 0; i < MFONT_PROPERTY_MAX; i++)
1101         if (! font.property[i])
1102           font.property[i] = request->property[i];
1103       gen_font_name (buf2, &font);
1104
1105       if (best)
1106         MDEBUG_PRINT_TIME ("FONT", 
1107                            (stderr, " to select <%s> (%x)from <%s>.",
1108                             gen_font_name (buf1, &best->font),
1109                             best->score,
1110                             buf2));
1111       else
1112         MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
1113       MDEBUG_POP_TIME ();
1114     }
1115
1116   if (! best)
1117     return NULL;
1118   best->layouter = layouter;
1119   mplist_add (frame->realized_font_list, registry, best);
1120   return best;
1121 }
1122
1123
1124 /** Open a font specified in RFONT.  Return 0 if successfully
1125     opened, otherwise return -1.  */
1126
1127 int
1128 mfont__open (MRealizedFont *rfont)
1129 {
1130   return (rfont->driver->open) (rfont);
1131 }
1132
1133 void
1134 mfont__resize (MFont *spec, MFont *request)
1135 {
1136   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1137   MFontResize *resize;
1138   MPlist *plist;
1139
1140   if (! font_resize_list)
1141     load_font_resize_table ();
1142   if (! MPLIST_TAIL_P (font_resize_list))
1143     while (1)
1144       {
1145         plist = font_resize_list;
1146         while (registry ? (plist = mplist_find_by_key (plist, registry))
1147                : plist)
1148           {
1149             resize = (MFontResize *) MPLIST_VAL (plist);
1150             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1151               {
1152                 request->property[MFONT_SIZE]
1153                   = request->property[MFONT_SIZE] * resize->resize / 100;
1154                 return;
1155               }
1156             plist = MPLIST_NEXT (plist);
1157           }
1158         if (registry == Mt)
1159           break;
1160         registry = Mt;
1161       }
1162 }
1163
1164
1165 unsigned
1166 mfont__encode_char (MRealizedFont *rfont, int c)
1167 {
1168   MFontEncoding *encoding;
1169   unsigned code;
1170
1171   if (rfont->layouter != Mnil)
1172     return mfont__flt_encode_char (rfont->layouter, c);
1173   if (! rfont->encoding)
1174     rfont->encoding = find_encoding (&rfont->font);
1175   encoding = rfont->encoding;
1176   if (! encoding->encoding_charset)
1177     return MCHAR_INVALID_CODE;
1178   if (encoding->repertory_charset
1179       && ENCODE_CHAR (encoding->repertory_charset, c) == MCHAR_INVALID_CODE)
1180     return MCHAR_INVALID_CODE;
1181   code = ENCODE_CHAR (encoding->encoding_charset, c);
1182   if (code == MCHAR_INVALID_CODE)
1183     return MCHAR_INVALID_CODE;
1184   return (rfont->driver->encode_char) (rfont, code);
1185 }
1186
1187 void
1188 mfont__get_metric (MGlyphString *gstring, int from, int to)
1189 {
1190   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1191   MRealizedFont *rfont = from_g->rface->rfont;
1192
1193   for (g = from_g; g != to_g; g++)
1194     if (g->rface->rfont != rfont)
1195       {
1196         int idx = GLYPH_INDEX (g);
1197
1198         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1199         from_g = g;
1200         rfont = g->rface->rfont;
1201         from = idx;
1202       }
1203   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1204 }
1205
1206
1207 void
1208 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1209 {
1210   int numeric;
1211
1212   if (val == Mnil)
1213     numeric = 0;
1214   else
1215     {
1216       numeric = FONT_PROPERTY_NUMERIC (val, key);
1217       if (! numeric)
1218         {
1219           numeric = mfont__property_table[key].used;
1220           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1221           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1222         }
1223     }
1224   font->property[key] = numeric;
1225 }
1226
1227 void
1228 mfont__set_spec (MFont *font, MSymbol *attrs,
1229                  unsigned short size, unsigned short resy)
1230 {
1231   int i;
1232
1233   for (i = 0; i <= MFONT_REGISTRY; i++)
1234     mfont__set_property (font, i, attrs[i]);
1235   font->property[MFONT_SIZE] = size;
1236   font->property[MFONT_RESY] = resy;
1237 }
1238
1239 int
1240 mfont__parse_name_into_font (char *name, MSymbol format, MFont *font)
1241 {
1242   int result = -1;
1243
1244   if (format == Mx || format == Mnil)
1245     result = xlfd_parse_name (name, font);
1246 #ifdef HAVE_FONTCONFIG
1247   if (format == Mfontconfig || (! result && format == Mnil))
1248     result = mfont__ft_parse_name (name, font);
1249 #endif
1250   return result;
1251 }
1252
1253 /*** @} */
1254 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1255
1256 \f
1257
1258 /* External API */
1259
1260 /*** @addtogroup m17nFont */
1261 /*** @{ */
1262 /*=*/
1263
1264 /***en @name Variables: Keys of font property.  */
1265 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1266 /*** @{ */
1267 /*=*/
1268
1269 /***en
1270     @brief Key of font property specifying foundry.
1271
1272     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1273     is used as a key of font property and face property.  The property
1274     value must be a symbol whose name is a foundry name of a font.  */
1275 /***ja
1276     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1277     
1278     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1279     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1280     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1281     */
1282
1283 MSymbol Mfoundry;
1284
1285 /***en
1286     @brief Key of font property specifying family.
1287
1288     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1289     used as a key of font property and face property.  The property
1290     value must be a symbol whose name is a family name of a font.  */ 
1291 /***ja
1292     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1293     
1294     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1295     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1296     ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1297     */
1298
1299 MSymbol Mfamily;
1300
1301 /***en
1302     @brief Key of font property specifying weight.
1303
1304     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1305     used as a key of font property and face property.  The property
1306     value must be a symbol whose name is a weight name of a font (e.g
1307     "medium", "bold").  */ 
1308 /***ja
1309     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1310     
1311     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1312     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1313     ¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1314     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1315     */
1316
1317 MSymbol Mweight;
1318
1319 /***en
1320     @brief Key of font property specifying style.
1321
1322     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1323     used as a key of font property and face property.  The property
1324     value must be a symbol whose name is a style name of a font (e.g
1325     "r", "i", "o").  */ 
1326 /***ja
1327     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1328     
1329     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1330     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1331     ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1332     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1333     */
1334
1335 MSymbol Mstyle;
1336
1337 /***en
1338     @brief Key of font property specifying stretch.
1339
1340     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1341     is used as a key of font property and face property.  The property
1342     value must be a symbol whose name is a stretch name of a font (e.g
1343     "normal", "condensed").  */ 
1344 /***ja
1345     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1346     
1347     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1348     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1349     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1350     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1351     */
1352
1353 MSymbol Mstretch;
1354
1355 /***en
1356     @brief Key of font property specifying additional style.
1357
1358     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1359     is used as a key of font property and face property.  The property
1360     value must be a symbol whose name is an additional style name of a
1361     font (e.g "serif", "", "sans").  */ 
1362 /***ja
1363     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1364     
1365     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1366     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1367     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1368     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1369     */
1370
1371 MSymbol Madstyle;
1372
1373 /***en
1374     @brief Key of font property specifying registry.
1375
1376     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1377     and is used as a key of font property.  The property value must be
1378     a symbol whose name is a registry name a font registry
1379     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1380 /***ja
1381     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1382     
1383     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
1384     ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
1385     ¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" Åù) ¤ò̾Á°¤È¤·
1386     ¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
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     */
1424
1425 MSymbol Mresolution;
1426
1427 /***en
1428     @brief Symobl of name "fontconfig".
1429
1430     The variable #Mfontconfig is to be used as an argument of the
1431     functions mfont_parse_name () and mfont_unparse_name ().  */
1432
1433 MSymbol Mfontconfig;
1434
1435 /***en
1436     @brief Symbol of name "x".
1437
1438     The variable #Mx is to be used for a value of <type> member of the
1439     structure #MDrawGlyph to specify the type of <fontp> member is
1440     actually (XFontStruct *).  */
1441
1442 MSymbol Mx;
1443
1444 /***en
1445     @brief Symbol of name "freetype".
1446
1447     The variable #Mfreetype is to be used for a value of <type> member
1448     of the structure #MDrawGlyph to specify the type of <fontp> member
1449     is actually FT_Face.  */
1450
1451 MSymbol Mfreetype;
1452
1453 /***en
1454     @brief Symbol of name "xft".
1455
1456     The variable #Mxft is to be used for a value of <type> member of the
1457     structure #MDrawGlyph to specify the type of <fontp> member
1458     is actually (XftFont *).  */
1459
1460 MSymbol Mxft;
1461
1462 /*=*/
1463 /*** @} */
1464 /*=*/
1465
1466 /***en
1467     @brief List of font files and directories that contain font files.
1468
1469     The variable @c mfont_freetype_path is a plist of FreeType font
1470     files and directories that contain FreeType font files.  Key of
1471     the element is @c Mstring, and the value is a string that
1472     represents a font file or a directory.
1473
1474     The macro M17N_INIT () sets up this variable to contain the
1475     sub-directory "fonts" of the m17n database and the environment
1476     variable "M17NDIR".  The first call of mframe () creates the
1477     internal list of the actually available fonts from this variable.
1478     Thus, an application program, if necessary, must modify the
1479     variable before calling mframe ().  If it is going to add a new
1480     element, value must be a string that can be safely freed.
1481
1482     If the m17n library is not configured to use the FreeType library,
1483     this variable is not used.  */
1484 /***ja
1485     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
1486
1487     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë
1488     ¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring ¤Ç¤¢
1489     ¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
1490
1491     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ
1492      ¿ô "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
1493      mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©
1494      ¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢
1495      mframe () ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê
1496      ¤¤¡£¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó
1497      ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1498
1499     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì
1500     ¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
1501
1502 MPlist *mfont_freetype_path;
1503
1504 /*=*/
1505
1506 /***en
1507     @brief Create a new font.
1508
1509     The mfont () function creates a new font object that has no
1510     property.
1511
1512     @return
1513     This function returns a pointer to the created font object.  */
1514 /***ja
1515     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
1516
1517     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯
1518     ¥È¤òºî¤ë¡£
1519
1520     @return
1521     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
1522
1523 MFont *
1524 mfont ()
1525 {
1526   MFont *font;
1527
1528   MSTRUCT_CALLOC (font, MERROR_FONT);
1529   return font;
1530 }
1531
1532 /*=*/
1533
1534 /***en
1535     @brief Create a font by parsing a fontname.
1536
1537     The mfont_parse_name () function creates a new font object.  The
1538     properties are extracted fontname $NAME.
1539
1540     $FORMAT specifies the format of $NAME.  If $FORMAT is #Mx, $NAME
1541     is parsed as XLFD (X Logical Font Description).  If $FORMAT is
1542     #Mfontconfig, $NAME is parsed as Fontconfig's textual
1543     representation of font.  If $FORMAT is #Mnil, $NAME is at first
1544     parsed as XLFD, and it it fails, parsed as Fontconfig's
1545     representation.
1546
1547     @return
1548     If the operation was successful, this function returns a pointer
1549     to the created font.  Otherwise it returns @c NULL.  */
1550
1551 /***ja
1552     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1553
1554     ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
1555     ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
1556
1557     $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
1558     $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1559     $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­
1560     ¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD ¤Ë
1561     ½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1562
1563     @return
1564     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
1565     ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
1566
1567 MFont *
1568 mfont_parse_name (char *name, MSymbol format)
1569 {
1570   MFont template, *font;
1571   
1572   MFONT_INIT (&template);
1573   if (mfont__parse_name_into_font (name, format, &template) < 0)
1574     MERROR (MERROR_FONT, NULL);
1575   MSTRUCT_CALLOC (font, MERROR_FONT);
1576   *font = template;
1577   return font;
1578 }
1579
1580 /*=*/
1581
1582 /***en
1583     @brief Create a fontname from a font.
1584
1585     The mfont_unparse_name () function creates a fontname string
1586     from font $FONT according to $FORMAT.
1587
1588     $FORMAT must be #Mx or #Mfontconfig.  If it is #Mx, the fontname
1589     is in XLFD (X Logical Font Description) format.  If it is
1590     #Mfontconfig, the fontname is in the style of Fontconfig's text
1591     representation.
1592
1593     @return
1594     This function returns a newly allocated fontname string, which is
1595     not freed unless the user explicitly does so by free ().  */
1596
1597 /***ja
1598     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1599
1600     ´Ø¿ô mfont_unparse_name () ¤Ï $FORMAT ¤Ë¤·¤¿¤¬¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»ú
1601     Îó¤ò¥Õ¥©¥ó¥È$FONT ¤ò¸µ¤Ëºî¤ë¡£
1602
1603     $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£#Mx ¤Ê¤é¤Ð¥Õ¥©
1604     ¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£#Mfontconfig ¤Ê
1605     ¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
1606
1607     @return 
1608     ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢
1609     ¥æ¡¼¥¶¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
1610
1611 char *
1612 mfont_unparse_name (MFont *font, MSymbol format)
1613 {
1614   char *name;
1615
1616   if (format == Mx)
1617     name = xlfd_unparse_name (font);
1618 #ifdef HAVE_FONTCONFIG
1619   else if (format == Mfontconfig)
1620     name = mfont__ft_unparse_name (font);
1621 #endif
1622   else
1623     MERROR (MERROR_FONT, NULL);
1624   return name;
1625 }
1626
1627 /*=*/
1628
1629 /***en
1630     @brief Make a copy of a font.
1631
1632     The mfont_copy () function returns a new copy of font $FONT.  */
1633 /***ja
1634     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
1635
1636     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
1637
1638 MFont *
1639 mfont_copy (MFont *font)
1640 {
1641   MFont *copy;
1642
1643   MSTRUCT_MALLOC (copy, MERROR_FONT);
1644   *copy = *font;
1645   return copy;
1646 }
1647
1648 /*=*/
1649
1650 /***en
1651     @brief Get a property value of a font.
1652
1653     The mfont_get_prop () function gets the value of $KEY property of
1654     font $FONT.  $KEY must be one of the following symbols:
1655
1656         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1657         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1658
1659     @return
1660     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1661     Madstyle, or @c Mregistry, this function returns the
1662     corresponding value as a symbol.  If the font does not have $KEY
1663     property, it returns @c Mnil.
1664     If $KEY is @c Msize or @c Mresolution, this function returns the
1665     corresponding value as an integer.  If the font does not have $KEY
1666     property, it returns 0.
1667     If $KEY is something else, it returns @c NULL and assigns an error
1668     code to the external variable #merror_code.  */
1669
1670 /***ja
1671     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1672
1673     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
1674     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
1675     ¤Ð¤Ê¤é¤Ê¤¤¡£
1676
1677         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1678         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1679
1680     @return 
1681     $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1682     Madstyle, @c Mregistry ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È
1683     ¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c Mnil ¤òÊÖ¤¹¡£
1684     $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò
1685     ¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤ò
1686     ÊÖ¤¹¡£
1687     $KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
1688     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1689
1690 void *
1691 mfont_get_prop (MFont *font, MSymbol key)
1692 {
1693   if (key == Mfoundry)
1694     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
1695   if (key == Mfamily)
1696     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
1697   if (key == Mweight)
1698     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
1699   if (key == Mstyle)
1700     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
1701   if (key == Mstretch)
1702     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
1703   if (key == Madstyle)
1704     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
1705   if (key == Mregistry)
1706     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
1707   if (key == Msize)
1708     {
1709       int size = font->property[MFONT_SIZE];
1710       return (void *) size;
1711     }
1712   if (key == Mresolution)
1713     {
1714       int resy = font->property[MFONT_RESY];
1715       return (void *) resy;
1716     }
1717
1718   MERROR (MERROR_FONT, NULL);
1719 }
1720
1721
1722 /*=*/
1723 /***en
1724     @brief Put a property value to a font.
1725
1726     The mfont_put_prop () function puts a font property whose key is
1727     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
1728     following symbols:
1729
1730         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1731         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1732
1733     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
1734     Otherwise, $VAL must be a symbol.  */
1735 /***ja
1736     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
1737
1738     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY ¤Ç¤¢¤ë¥×¥í
1739     ¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢
1740     ¤ë¡£
1741
1742         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1743         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1744
1745     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ
1746     ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
1747
1748 int
1749 mfont_put_prop (MFont *font, MSymbol key, void *val)
1750 {
1751   if (key == Mfoundry)
1752     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
1753   else if (key == Mfamily)
1754     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
1755   else if (key == Mweight)
1756     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
1757   else if (key == Mstyle)
1758     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
1759   else if (key == Mstretch)
1760     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
1761   else if (key == Madstyle)
1762     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
1763   else if (key == Mregistry)
1764     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
1765   else if (key == Msize)
1766     {
1767       unsigned size = (unsigned) val;
1768       font->property[MFONT_SIZE] = size;
1769     }
1770   else if (key == Mresolution)
1771     {
1772       unsigned resy = (unsigned) val;
1773       font->property[MFONT_RESY] =  resy;
1774     }
1775   else
1776     MERROR (MERROR_FONT, -1);
1777   return 0;
1778 }
1779
1780 /*=*/
1781
1782 /***en
1783     @brief Return the font selection priority.
1784
1785     The mfont_selection_priority () function returns a newly created
1786     array of six symbols.  The elements are the following
1787     keys of font properties ordered by priority.
1788
1789         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1790         @c Madstyle, @c Msize.
1791
1792    The m17n library selects the best matching font according to the
1793    order of this array.  A font that has a different value for a
1794    property of lower priority is preferred to a font that has a
1795    different value for a property of higher priority.  */
1796 /***ja
1797     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÊÖ¤¹.
1798
1799     ´Ø¿ô mfont_selection_priority () ¤Ï6¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã
1800     ¤ÆÊÖ¤¹¡£ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤ËÊÂ
1801     ¤Ù¤¿¤â¤Î¤Ç¤¢¤ë¡£
1802
1803         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1804         @c Madstyle, @c Msize.
1805
1806    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
1807    Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬°ã¤¦¥Õ¥©¥ó¥È¤ÈÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤Î
1808    Ãͤ¬°ã¤¦¥Õ¥©¥ó¥È¤¬¤¢¤ë¾ì¹ç¡¢Á°¼Ô¤¬ÁªÂò¤µ¤ì¤ë¡£
1809    */
1810
1811 MSymbol *
1812 mfont_selection_priority ()
1813 {
1814   MSymbol *keys;
1815   int i;
1816
1817   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
1818   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1819     {
1820       enum MFontProperty prop = font_score_priority[i];
1821
1822       if (prop == MFONT_SIZE)
1823         keys[i] = Msize;
1824       else if (prop == MFONT_ADSTYLE)
1825         keys[i] = Madstyle;
1826       else if (prop == MFONT_FAMILY)
1827         keys[i] = Mfamily;
1828       else if (prop == MFONT_WEIGHT)
1829         keys[i] = Mweight;
1830       else if (prop == MFONT_STYLE)
1831         keys[i] = Mstyle;
1832       else if (prop == MFONT_STRETCH)
1833         keys[i] = Mstretch;
1834       else
1835         keys[i] = Mfoundry;
1836     }
1837   return keys;
1838 }
1839
1840 /*=*/
1841
1842 /***en
1843     @brief Set the font selection priority.
1844
1845     The mfont_set_selection_priority () function sets font selection
1846     priority according to $KEYS, which is an array of six symbols.
1847     Each element must be one of the below.  No two elements must be
1848     the same.
1849
1850         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1851         @c Madstyle, @c Msize.
1852
1853     See the documentation of the function mfont_selection_priority ()
1854     for details.  */
1855 /***ja
1856     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
1857
1858     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
1859     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£³ÆÍ×ÁǤϰʲ¼¤Î¤¦¤Á¤Î¤É¤ì
1860     ¤«¤Ç¤¢¤ê¡¢Á´¤Æ°Û¤Ê¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1861
1862         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1863         @c Madstyle, @c Msize.
1864
1865     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
1866      */
1867
1868 int
1869 mfont_set_selection_priority (MSymbol *keys)
1870 {
1871   int priority[FONT_SCORE_PRIORITY_SIZE];
1872   int i, j;
1873
1874   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
1875     {
1876       enum MFontProperty prop;
1877
1878       if (*keys == Msize)
1879         prop = MFONT_SIZE;
1880       else if (*keys == Madstyle)
1881         prop = MFONT_ADSTYLE;
1882       else if (*keys == Mfamily)
1883         prop = MFONT_FAMILY;
1884       else if (*keys == Mweight)
1885         prop = MFONT_WEIGHT;
1886       else if (*keys == Mstyle)
1887         prop = MFONT_STYLE;
1888       else if (*keys == Mstretch)
1889         prop = MFONT_STRETCH;
1890       else if (*keys == Mfoundry)
1891         prop = MFONT_FOUNDRY;
1892       else
1893         /* Invalid element.  */
1894         return -1;
1895       for (j = 0; j < i; j++)
1896         if (priority[j] == prop)
1897           /* Duplicated element.  */
1898           return -1;
1899       priority[i] = prop;
1900     }
1901   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1902     font_score_priority[i] = priority[i];
1903   return 0;
1904 }
1905
1906 /*=*/
1907
1908 /***en
1909     @brief Find a font.
1910
1911     The mfont_find () function returns a pointer to the available font
1912     that matches best the specification $SPEC on frame $FRAME.
1913
1914     $SCORE, if not NULL, must point to a place to store the score
1915     value that indicates how well the found font matches to $SPEC.  The
1916     smaller score means a better match.  */
1917 /***ja
1918     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
1919
1920     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC ¤Ë¤â¤Ã
1921     ¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
1922
1923     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC ¤Ë¤É¤ì¤Û¤É¹ç¤Ã
1924     ¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥¹¥³¥¢¤¬¾®¤µ
1925     ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1926     */
1927
1928 MFont *
1929 mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
1930 {
1931   MFont spec_copy;
1932   MRealizedFont *rfont;
1933
1934   MFONT_INIT (&spec_copy);
1935   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
1936
1937   rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
1938   if (!rfont)
1939     return NULL;
1940   if (score)
1941     *score = rfont->score;
1942   return &rfont->font;
1943 }
1944
1945 /*=*/
1946 /***en
1947     @brief Set encoding of a font.
1948
1949     The mfont_set_encoding () function sets the encoding information
1950     of font $FONT.
1951
1952     $ENCODING_NAME is a symbol representing a charset that has the
1953     same encoding as the font.
1954
1955     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
1956     has the same repertory as the font.  If it is @c Mnil, whether a
1957     specific character is supported by the font is asked to each font
1958     driver.
1959
1960     @return
1961     If the operation was successful, this function returns 0.
1962     Otherwise it returns -1 and assigns an error code to the external
1963     variable #merror_code.  */
1964 /***ja
1965     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
1966
1967     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó
1968     ¤òÀßÄꤹ¤ë¡£
1969
1970     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò
1971     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1972
1973     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó
1974     ¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ
1975     »ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤Ë
1976     Ì䤤¹ç¤ï¤»¤ë¡£
1977
1978     @return
1979     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°
1980     ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1981
1982
1983 int
1984 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
1985 {
1986   MCharset *encoding_charset = MCHARSET (encoding_name);
1987   MCharset *repertory_charset;
1988   MSymbol registry;
1989   MFontEncoding *encoding;
1990   MPlist *plist;
1991
1992   if (! encoding_charset)
1993     MERROR (MERROR_FONT, -1);
1994   if (repertory_name != Mnil)
1995     {
1996       repertory_charset = MCHARSET (repertory_name);
1997       if (! repertory_charset)
1998         MERROR (MERROR_FONT, -1);
1999     }
2000   else
2001     repertory_charset = NULL;
2002
2003   MSTRUCT_CALLOC (encoding, MERROR_FONT);
2004   encoding->spec = *font;
2005   encoding->encoding_name = encoding_name;
2006   encoding->encoding_charset = encoding_charset;
2007   encoding->repertory_name = repertory_name;
2008   encoding->repertory_charset = repertory_charset;
2009   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
2010   if (registry == Mnil)
2011     registry = Mt;
2012   if (! font_encoding_list)
2013     load_font_encoding_table ();
2014   mplist_push (font_encoding_list, registry, encoding);
2015   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
2016     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
2017                   sizeof (MFont)))
2018       {
2019         mplist_pop (plist);
2020         break;
2021       }
2022   return 0;
2023 }
2024
2025 /*=*/
2026
2027 /***en
2028     @brief Create a fontname from a font.
2029
2030     This function is obsolete.   Use mfont_unparse_name instead. */
2031 /***ja
2032     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2033
2034     ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
2035
2036 char *
2037 mfont_name (MFont *font)
2038 {
2039   return mfont_unparse_name (font, Mx);
2040 }
2041
2042 /*=*/
2043
2044 /***en
2045     @brief Create a new font from fontname.
2046
2047     This function is obsolete.  Use mfont_parse_name () instead.  */
2048
2049 /***ja
2050     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2051
2052     ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
2053
2054 MFont *
2055 mfont_from_name (char *name)
2056 {
2057   return mfont_parse_name (name, Mx);
2058 }
2059
2060 /*=*/
2061
2062 /***en
2063     @brief Get resize information of a font.
2064
2065     The mfont_resize_ratio () function lookups the m17n database
2066     \<font, reisize\> and returns a resizing ratio (in percentage) of
2067     FONT.  For instance, if the return value is 150, that means that
2068     the m17n library uses an 1.5 time bigger font than a specified
2069     size.  */
2070
2071 /***ja
2072     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥µ¥¤¥º¾ðÊó¤òÆÀ¤ë
2073
2074     ´Ø¿ô mfont_resize_ratio ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹ \<font, reisize\> ¤ò¸¡
2075     º÷¤·¡¢¥Õ¥©¥ó¥È FONT ¤Î¥ê¥µ¥¤¥º¤ÎÈæΨ¡Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¡Ë¤òÊÖ¤¹¡£Î㤨
2076     ¤ÐÊÖÃͤ¬ 150 ¤Ç¤¢¤ì¤Ð¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ï»ØÄꤵ¤ì¤¿¥µ¥¤¥º¤Î 1.5 ÇܤÎ
2077     ¥Õ¥©¥ó¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ */
2078
2079 int
2080 mfont_resize_ratio (MFont *font)
2081 {
2082   MFont request = *font;
2083
2084   mfont__resize (font, &request);
2085   return (font->property[MFONT_SIZE] * 100 / request.property[MFONT_SIZE]);
2086 }
2087
2088 /*=*/
2089
2090 /***en
2091     @brief Get a list fonts.
2092
2093     The mfont_list () functions returns a list of fonts available on
2094     frame $FRAME.  If $FONT is not nil, it limits fonts to ones that
2095     matchq with $FONT.  If $LANGUAGE is not @c Mnil, it limits fonts
2096     to ones that support $LANGUAGE.
2097
2098     @return
2099     This function returns a plist whose keys are family name and
2100     values are pointers to the object MFont.  The plist must be freed
2101     by m17n_object_unref ().  */
2102
2103 MPlist *
2104 mfont_list (MFrame *frame, MFont *font, MSymbol language)
2105 {
2106   MPlist *plist = mplist (), *p;
2107   
2108   MPLIST_DO (p, frame->font_driver_list)
2109     {
2110       MFontDriver *driver = MPLIST_VAL (p);
2111
2112       (driver->list) (frame, plist, font, language);
2113     }
2114   return plist;
2115 }
2116
2117 /*** @} */
2118
2119 /*** @addtogroup m17nDebug */
2120 /*=*/
2121 /*** @{ */
2122
2123 /***en
2124     @brief Dump a font.
2125
2126     The mdebug_dump_font () function prints font $FONT in a human readable
2127     way to the stderr.
2128
2129     @return
2130     This function returns $FONT.  */
2131 /***ja
2132     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
2133
2134     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr ¤Ë¿Í´Ö¤Ë²ÄÆɤÊ
2135     ·Á¤Ç°õºþ¤¹¤ë¡£
2136
2137     @return
2138     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
2139
2140 MFont *
2141 mdebug_dump_font (MFont *font)
2142 {
2143   char *name;
2144   
2145   name = mfont_unparse_name (font, Mx);
2146   if (name)
2147     {
2148       fprintf (stderr, "%s", name);
2149       free (name);
2150     }
2151   return font;
2152 }
2153
2154 /*** @} */
2155
2156 /*
2157   Local Variables:
2158   coding: euc-japan
2159   End:
2160 */