90e9db6027f06d24f250ac2438133b5a18e53478
[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     "normal",
377     "medium",
378     "regular",
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   /* The first entry of each mfont__property_table must be Mnil so
825      that actual properties get positive numeric numbers.  */
826   for (i = 0; i <= MFONT_REGISTRY; i++)
827     {
828       MLIST_INIT1 (&mfont__property_table[i], names, 8);
829       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
830     }
831
832   /* Register predefined font property names.  */
833   for (i = 0; i <= MFONT_REGISTRY; i++)
834     {
835       int j;
836
837       for (j = 0; j < font_common_names[i].num; j++)
838         {
839           MSymbol sym = msymbol (font_common_names[i].names[j]);
840
841           if (sym == Mnil)
842             return -1;
843           if (msymbol_put(sym, mfont__property_table[i].property,
844                           (void *) (j + 1)) < 0)
845             return -1;
846           MLIST_APPEND1 (&mfont__property_table[i], names, sym, MERROR_FONT);
847         }
848     }
849
850   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
851      of a score is a flag for a scalable font (see the documentation
852      of mfont_score).  */
853   i = FONT_SCORE_PRIORITY_SIZE - 1;
854   for (shift = 1; i >= 0; i--)
855     {
856       font_score_shift_bits[font_score_priority[i]] = shift;
857       if (font_score_priority[i] == MFONT_SIZE)
858         shift += 16;
859       else
860         shift += 2;
861     }
862
863   MFONT_INIT (&default_encoding.spec);
864   default_encoding.encoding_name = Mnil;
865   default_encoding.encoding_charset = NULL;
866   default_encoding.repertory_name = Mnil;
867   default_encoding.repertory_charset = NULL;
868   {
869     char *path, *buf;
870     int bufsize;
871
872     mfont_freetype_path = mplist ();
873     bufsize = strlen (M17NDIR) + 7;
874     buf = alloca (bufsize);
875     sprintf (buf, "%s/fonts", M17NDIR);
876     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
877     path = getenv ("M17NDIR");
878     if (path)
879       {
880         i = strlen (path) + 7;
881         if (i > bufsize)
882           buf = alloca (i);
883         sprintf (buf, "%s/fonts", path);
884         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
885       }
886   }
887
888 #ifdef HAVE_FREETYPE
889   if (mfont__ft_init () < 0)
890     return -1;
891 #endif /* HAVE_FREETYPE */
892   if (mfont__flt_init () < 0)
893     return -1;
894
895   return 0;
896 }
897
898 void
899 mfont__fini ()
900 {
901   MPlist *plist;
902   int i;
903
904   mfont__flt_fini ();
905 #ifdef HAVE_FREETYPE
906   mfont__ft_fini ();
907 #endif /* HAVE_FREETYPE */
908
909   MPLIST_DO (plist, mfont_freetype_path)
910     free (MPLIST_VAL (plist));
911   M17N_OBJECT_UNREF (mfont_freetype_path);
912
913   if (font_resize_list)
914     {
915       MPLIST_DO (plist, font_resize_list)
916         free (MPLIST_VAL (plist));
917       M17N_OBJECT_UNREF (font_resize_list);
918       font_resize_list = NULL;
919     }
920   if (font_encoding_list)
921     {
922       MPLIST_DO (plist, font_encoding_list)
923         free (MPLIST_VAL (plist));
924       M17N_OBJECT_UNREF (font_encoding_list);
925       font_encoding_list = NULL;
926     }
927   for (i = 0; i <= MFONT_REGISTRY; i++)
928     MLIST_FREE1 (&mfont__property_table[i], names);
929 }
930
931 void
932 mfont__free_realized (MRealizedFont *rfont)
933 {
934   M17N_OBJECT_UNREF (rfont->info);
935   free (rfont);
936 }
937
938
939 /* Compare FONT with REQUEST and return how much they differs.  If
940    FONT does not match with SPEC, return -1.  */
941
942 int
943 mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size)
944 {
945   int score = 0;
946   int i = FONT_SCORE_PRIORITY_SIZE;
947
948   while (--i >= 0)
949     {
950       enum MFontProperty prop = font_score_priority[i];
951
952       if (request->property[prop] != 0)
953         {
954           int val = 0;
955
956           if (spec->property[prop] && font->property[prop]
957               && font->property[prop] != spec->property[prop])
958             return -1;
959           if (font->property[prop])
960             val = abs (font->property[prop] - request->property[prop]);
961           if (prop == MFONT_SIZE)
962             {
963               if (font->property[MFONT_RESY] == 0)
964                 /* This is a scalable font.  We prefer a bitmap font
965                    if the size matches exactly.  */
966                 score |= 1;
967               else
968                 score |= (val << font_score_shift_bits[MFONT_SIZE]
969                           | ((limited_size && val > 0) ? 0x400000 : 0));
970             }
971           else
972             score |= (val > 3 ? 3 : val) << font_score_shift_bits[prop];
973         }
974     }
975   return score;
976 }
977
978
979 /** Return 1 iff FONT matches SPEC.  */
980
981 int
982 mfont__match_p (MFont *font, MFont *spec, int prop)
983 {
984   for (; prop >= 0; prop--)
985     if (spec->property[prop] && font->property[prop]
986         && font->property[prop] != spec->property[prop])
987       return 0;
988   return 1;
989 }
990
991
992 void
993 mfont__set_spec_from_face (MFont *spec, MFace *face)
994 {
995   int i;
996
997   for (i = 0; i <= MFONT_ADSTYLE; i++)
998     mfont__set_property (spec, i, face->property[i]);
999   /* The value 1 is "iso8859-1".  */
1000   spec->property[MFONT_REGISTRY] = 1;
1001   spec->property[MFONT_SIZE] = (int) (face->property[MFACE_SIZE]);
1002   spec->property[MFONT_RESY] = 0;
1003 }
1004
1005
1006 extern MSymbol
1007 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
1008 {
1009   int i;
1010   MSymbol spec_list[MFONT_REGISTRY + 1];
1011   MSymbol registry;
1012
1013   MFONT_INIT (spec);
1014   memset (spec_list, 0, sizeof spec_list);
1015   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
1016     {
1017       if (! MPLIST_SYMBOL_P (plist))
1018         MERROR (MERROR_FONT, Mnil);     
1019       spec_list[i] = MPLIST_SYMBOL (plist);
1020     }
1021   registry = spec_list[i - 1];
1022   mfont__set_property (spec, MFONT_REGISTRY, registry);
1023   for (i -= 2; i >= 0; i--)
1024     mfont__set_property (spec, i, spec_list[i]);
1025   return registry;
1026 }
1027
1028 MRealizedFont *
1029 mfont__select (MFrame *frame, MFont *spec, MFont *request, int limited_size,
1030                MSymbol layouter)
1031 {
1032   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1033   MPlist *plist;
1034   MRealizedFont *best;
1035   int i;
1036   int mdebug_mask = MDEBUG_FONT;
1037
1038   if (registry == Mnil)
1039     registry = Mt;
1040
1041   MPLIST_DO (plist, frame->realized_font_list)
1042     {
1043       best = MPLIST_VAL (plist);
1044       if (MPLIST_KEY (plist) == registry
1045           && ! memcmp (&best->spec, spec, sizeof (MFont))
1046           && ! memcmp (&best->request, request, sizeof (MFont)))
1047         {
1048           if (best->layouter != layouter)
1049             {
1050               MRealizedFont *copy;
1051
1052               MSTRUCT_MALLOC (copy, MERROR_FONT);
1053               *copy = *best;
1054               copy->layouter = layouter;
1055               mplist_add (frame->realized_font_list, registry, copy);
1056               if (copy->info)
1057                 M17N_OBJECT_REF (copy->info);
1058               best = copy;
1059             }
1060           return best;
1061         }
1062     }
1063
1064   MDEBUG_PUSH_TIME ();
1065   best = NULL;
1066   MPLIST_DO (plist, frame->font_driver_list)
1067     {
1068       MFontDriver *driver = MPLIST_VAL (plist);
1069       MRealizedFont *this
1070         = (driver->select) (frame, spec, request, limited_size);
1071
1072       if (this)
1073         {
1074           this->driver = driver;
1075           if (! best
1076               || this->score < best->score)
1077             {
1078               if (best)
1079                 mfont__free_realized (best);
1080               best = this;
1081               if (this->score == 0)
1082                 break;
1083             }
1084           else
1085             mfont__free_realized (this);
1086         }
1087     }
1088
1089   if (mdebug__flag & mdebug_mask)
1090     {
1091       char buf1[256], buf2[256];
1092       MFont font = *spec;
1093
1094       for (i = 0; i < MFONT_PROPERTY_MAX; i++)
1095         if (! font.property[i])
1096           font.property[i] = request->property[i];
1097       gen_font_name (buf2, &font);
1098
1099       if (best)
1100         MDEBUG_PRINT_TIME ("FONT", 
1101                            (stderr, " to select <%s> (%x)from <%s>.",
1102                             gen_font_name (buf1, &best->font),
1103                             best->score,
1104                             buf2));
1105       else
1106         MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
1107       MDEBUG_POP_TIME ();
1108     }
1109
1110   if (! best)
1111     return NULL;
1112   best->layouter = layouter;
1113   mplist_add (frame->realized_font_list, registry, best);
1114   return best;
1115 }
1116
1117
1118 /** Open a font specified in RFONT.  Return 0 if successfully
1119     opened, otherwise return -1.  */
1120
1121 int
1122 mfont__open (MRealizedFont *rfont)
1123 {
1124   return (rfont->driver->open) (rfont);
1125 }
1126
1127 void
1128 mfont__resize (MFont *spec, MFont *request)
1129 {
1130   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1131   MFontResize *resize;
1132   MPlist *plist;
1133
1134   if (! font_resize_list)
1135     load_font_resize_table ();
1136   if (! MPLIST_TAIL_P (font_resize_list))
1137     while (1)
1138       {
1139         plist = font_resize_list;
1140         while (registry ? (plist = mplist_find_by_key (plist, registry))
1141                : plist)
1142           {
1143             resize = (MFontResize *) MPLIST_VAL (plist);
1144             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1145               {
1146                 request->property[MFONT_SIZE]
1147                   = request->property[MFONT_SIZE] * resize->resize / 100;
1148                 return;
1149               }
1150             plist = MPLIST_NEXT (plist);
1151           }
1152         if (registry == Mt)
1153           break;
1154         registry = Mt;
1155       }
1156 }
1157
1158
1159 unsigned
1160 mfont__encode_char (MRealizedFont *rfont, int c)
1161 {
1162   MFontEncoding *encoding;
1163   unsigned code;
1164
1165   if (rfont->layouter != Mnil)
1166     return mfont__flt_encode_char (rfont->layouter, c);
1167   if (! rfont->encoding)
1168     rfont->encoding = find_encoding (&rfont->font);
1169   encoding = rfont->encoding;
1170   if (! encoding->encoding_charset)
1171     return MCHAR_INVALID_CODE;
1172   if (encoding->repertory_charset
1173       && ENCODE_CHAR (encoding->repertory_charset, c) == MCHAR_INVALID_CODE)
1174     return MCHAR_INVALID_CODE;
1175   code = ENCODE_CHAR (encoding->encoding_charset, c);
1176   if (code == MCHAR_INVALID_CODE)
1177     return MCHAR_INVALID_CODE;
1178   return (rfont->driver->encode_char) (rfont, code);
1179 }
1180
1181 void
1182 mfont__get_metric (MGlyphString *gstring, int from, int to)
1183 {
1184   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1185   MRealizedFont *rfont = from_g->rface->rfont;
1186
1187   for (g = from_g; g != to_g; g++)
1188     if (g->rface->rfont != rfont)
1189       {
1190         int idx = GLYPH_INDEX (g);
1191
1192         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1193         from_g = g;
1194         rfont = g->rface->rfont;
1195         from = idx;
1196       }
1197   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1198 }
1199
1200
1201 void
1202 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1203 {
1204   int numeric;
1205
1206   if (val == Mnil)
1207     numeric = 0;
1208   else
1209     {
1210       numeric = FONT_PROPERTY_NUMERIC (val, key);
1211       if (! numeric)
1212         {
1213           numeric = mfont__property_table[key].used;
1214           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1215           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1216         }
1217     }
1218   font->property[key] = numeric;
1219 }
1220
1221 void
1222 mfont__set_spec (MFont *font, MSymbol *attrs,
1223                  unsigned short size, unsigned short resy)
1224 {
1225   int i;
1226
1227   for (i = 0; i <= MFONT_REGISTRY; i++)
1228     mfont__set_property (font, i, attrs[i]);
1229   font->property[MFONT_SIZE] = size;
1230   font->property[MFONT_RESY] = resy;
1231 }
1232
1233 int
1234 mfont__parse_name_into_font (char *name, MSymbol format, MFont *font)
1235 {
1236   int result = -1;
1237
1238   if (format == Mx || format == Mnil)
1239     result = xlfd_parse_name (name, font);
1240 #ifdef HAVE_FONTCONFIG
1241   if (format == Mfontconfig || (! result && format == Mnil))
1242     result = mfont__ft_parse_name (name, font);
1243 #endif
1244   return result;
1245 }
1246
1247 /*** @} */
1248 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1249
1250 \f
1251
1252 /* External API */
1253
1254 /*** @addtogroup m17nFont */
1255 /*** @{ */
1256 /*=*/
1257
1258 /***en @name Variables: Keys of font property.  */
1259 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1260 /*** @{ */
1261 /*=*/
1262
1263 /***en
1264     @brief Key of font property specifying foundry.
1265
1266     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1267     is used as a key of font property and face property.  The property
1268     value must be a symbol whose name is a foundry name of a font.  */
1269 /***ja
1270     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1271     
1272     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1273     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1274     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1275     */
1276
1277 MSymbol Mfoundry;
1278
1279 /***en
1280     @brief Key of font property specifying family.
1281
1282     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1283     used as a key of font property and face property.  The property
1284     value must be a symbol whose name is a family name of a font.  */ 
1285 /***ja
1286     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1287     
1288     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1289     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1290     ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1291     */
1292
1293 MSymbol Mfamily;
1294
1295 /***en
1296     @brief Key of font property specifying weight.
1297
1298     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1299     used as a key of font property and face property.  The property
1300     value must be a symbol whose name is a weight name of a font (e.g
1301     "medium", "bold").  */ 
1302 /***ja
1303     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1304     
1305     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1306     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1307     ¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1308     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1309     */
1310
1311 MSymbol Mweight;
1312
1313 /***en
1314     @brief Key of font property specifying style.
1315
1316     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1317     used as a key of font property and face property.  The property
1318     value must be a symbol whose name is a style name of a font (e.g
1319     "r", "i", "o").  */ 
1320 /***ja
1321     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1322     
1323     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1324     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1325     ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1326     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1327     */
1328
1329 MSymbol Mstyle;
1330
1331 /***en
1332     @brief Key of font property specifying stretch.
1333
1334     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1335     is used as a key of font property and face property.  The property
1336     value must be a symbol whose name is a stretch name of a font (e.g
1337     "normal", "condensed").  */ 
1338 /***ja
1339     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1340     
1341     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1342     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1343     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1344     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1345     */
1346
1347 MSymbol Mstretch;
1348
1349 /***en
1350     @brief Key of font property specifying additional style.
1351
1352     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1353     is used as a key of font property and face property.  The property
1354     value must be a symbol whose name is an additional style name of a
1355     font (e.g "serif", "", "sans").  */ 
1356 /***ja
1357     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1358     
1359     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1360     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1361     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1362     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1363     */
1364
1365 MSymbol Madstyle;
1366
1367 /***en
1368     @brief Key of font property specifying registry.
1369
1370     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1371     and is used as a key of font property.  The property value must be
1372     a symbol whose name is a registry name a font registry
1373     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1374 /***ja
1375     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1376     
1377     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
1378     ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
1379     ¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" Åù) ¤ò̾Á°¤È¤·
1380     ¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1381     */
1382
1383 MSymbol Mregistry;
1384
1385 /***en
1386     @brief Key of font property specifying size.
1387
1388     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1389     used as a key of font property and face property.  The property
1390     value must be an integer specifying a font design size in the unit
1391     of 1/10 point (on 100 dpi display).  */ 
1392 /***ja
1393     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1394     
1395     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©
1396     ¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1397     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó
1398     ¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1399     */
1400
1401 MSymbol Msize;
1402
1403 /***en
1404     @brief Key of font property specifying resolution.
1405
1406     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1407     is used as a key of font property and face property.  The property
1408     value must be an integer to specifying a font resolution in the
1409     unit of dots per inch (dpi).  */ 
1410 /***ja
1411     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1412     
1413     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü
1414     ¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é
1415     ¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ô
1416     ÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1417     */
1418
1419 MSymbol Mresolution;
1420
1421 /***en
1422     @brief Symobl of name "fontconfig".
1423
1424     The variable #Mfontconfig is to be used as an argument of the
1425     functions mfont_parse_name () and mfont_unparse_name ().  */
1426
1427 MSymbol Mfontconfig;
1428
1429 /*=*/
1430 /*** @} */
1431 /*=*/
1432
1433 /***en
1434     @brief List of font files and directories that contain font files.
1435
1436     The variable @c mfont_freetype_path is a plist of FreeType font
1437     files and directories that contain FreeType font files.  Key of
1438     the element is @c Mstring, and the value is a string that
1439     represents a font file or a directory.
1440
1441     The macro M17N_INIT () sets up this variable to contain the
1442     sub-directory "fonts" of the m17n database and the environment
1443     variable "M17NDIR".  The first call of mframe () creates the
1444     internal list of the actually available fonts from this variable.
1445     Thus, an application program, if necessary, must modify the
1446     variable before calling mframe ().  If it is going to add a new
1447     element, value must be a string that can be safely freed.
1448
1449     If the m17n library is not configured to use the FreeType library,
1450     this variable is not used.  */
1451 /***ja
1452     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
1453
1454     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë
1455     ¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring ¤Ç¤¢
1456     ¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
1457
1458     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ
1459      ¿ô "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
1460      mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©
1461      ¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢
1462      mframe () ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê
1463      ¤¤¡£¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó
1464      ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1465
1466     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì
1467     ¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
1468
1469 MPlist *mfont_freetype_path;
1470
1471 /*=*/
1472
1473 /***en
1474     @brief Create a new font.
1475
1476     The mfont () function creates a new font object that has no
1477     property.
1478
1479     @return
1480     This function returns a pointer to the created font object.  */
1481 /***ja
1482     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
1483
1484     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯
1485     ¥È¤òºî¤ë¡£
1486
1487     @return
1488     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
1489
1490 MFont *
1491 mfont ()
1492 {
1493   MFont *font;
1494
1495   MSTRUCT_CALLOC (font, MERROR_FONT);
1496   return font;
1497 }
1498
1499 /*=*/
1500
1501 /***en
1502     @brief Create a font by parsing a fontname.
1503
1504     The mfont_parse_name () function creates a new font object.  The
1505     properties are extracted fontname $NAME.
1506
1507     $FORMAT specifies the format of $NAME.  If $FORMAT is #Mx, $NAME
1508     is parsed as XLFD (X Logical Font Description).  If $FORMAT is
1509     #Mfontconfig, $NAME is parsed as Fontconfig's textual
1510     representation of font.  If $FORMAT is #Mnil, $NAME is at first
1511     parsed as XLFD, and it it fails, parsed as Fontconfig's
1512     representation.
1513
1514     @return
1515     If the operation was successful, this function returns a pointer
1516     to the created font.  Otherwise it returns @c NULL.  */
1517
1518 /***ja
1519     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1520
1521     ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
1522     ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
1523
1524     $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
1525     $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1526     $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­
1527     ¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD ¤Ë
1528     ½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1529
1530     @return
1531     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
1532     ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
1533
1534 MFont *
1535 mfont_parse_name (char *name, MSymbol format)
1536 {
1537   MFont template, *font;
1538   
1539   MFONT_INIT (&template);
1540   if (mfont__parse_name_into_font (name, format, &template) < 0)
1541     MERROR (MERROR_FONT, NULL);
1542   MSTRUCT_CALLOC (font, MERROR_FONT);
1543   *font = template;
1544   return font;
1545 }
1546
1547 /*=*/
1548
1549 /***en
1550     @brief Create a fontname from a font.
1551
1552     The mfont_unparse_name () function creates a fontname string
1553     from font $FONT according to $FORMAT.
1554
1555     $FORMAT must be #Mx or #Mfontconfig.  If it is #Mx, the fontname
1556     is in XLFD (X Logical Font Description) format.  If it is
1557     #Mfontconfig, the fontname is in the style of Fontconfig's text
1558     representation.
1559
1560     @return
1561     This function returns a newly allocated fontname string, which is
1562     not freed unless the user explicitly does so by free ().  */
1563
1564 /***ja
1565     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1566
1567     ´Ø¿ô mfont_unparse_name () ¤Ï $FORMAT ¤Ë¤·¤¿¤¬¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»ú
1568     Îó¤ò¥Õ¥©¥ó¥È$FONT ¤ò¸µ¤Ëºî¤ë¡£
1569
1570     $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£#Mx ¤Ê¤é¤Ð¥Õ¥©
1571     ¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£#Mfontconfig ¤Ê
1572     ¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
1573
1574     @return 
1575     ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢
1576     ¥æ¡¼¥¶¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
1577
1578 char *
1579 mfont_unparse_name (MFont *font, MSymbol format)
1580 {
1581   char *name;
1582
1583   if (format == Mx)
1584     name = xlfd_unparse_name (font);
1585 #ifdef HAVE_FONTCONFIG
1586   else if (format == Mfontconfig)
1587     name = mfont__ft_unparse_name (font);
1588 #endif
1589   else
1590     MERROR (MERROR_FONT, NULL);
1591   return name;
1592 }
1593
1594 /*=*/
1595
1596 /***en
1597     @brief Make a copy of a font.
1598
1599     The mfont_copy () function returns a new copy of font $FONT.  */
1600 /***ja
1601     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
1602
1603     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
1604
1605 MFont *
1606 mfont_copy (MFont *font)
1607 {
1608   MFont *copy;
1609
1610   MSTRUCT_MALLOC (copy, MERROR_FONT);
1611   *copy = *font;
1612   return copy;
1613 }
1614
1615 /*=*/
1616
1617 /***en
1618     @brief Get a property value of a font.
1619
1620     The mfont_get_prop () function gets the value of $KEY property of
1621     font $FONT.  $KEY must be one of the following symbols:
1622
1623         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1624         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1625
1626     @return
1627     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1628     Madstyle, or @c Mregistry, this function returns the
1629     corresponding value as a symbol.  If the font does not have $KEY
1630     property, it returns @c Mnil.
1631     If $KEY is @c Msize or @c Mresolution, this function returns the
1632     corresponding value as an integer.  If the font does not have $KEY
1633     property, it returns 0.
1634     If $KEY is something else, it returns @c NULL and assigns an error
1635     code to the external variable #merror_code.  */
1636
1637 /***ja
1638     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1639
1640     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
1641     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
1642     ¤Ð¤Ê¤é¤Ê¤¤¡£
1643
1644         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1645         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1646
1647     @return 
1648     $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1649     Madstyle, @c Mregistry ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È
1650     ¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c Mnil ¤òÊÖ¤¹¡£
1651     $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò
1652     ¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤ò
1653     ÊÖ¤¹¡£
1654     $KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
1655     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1656
1657 void *
1658 mfont_get_prop (MFont *font, MSymbol key)
1659 {
1660   if (key == Mfoundry)
1661     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
1662   if (key == Mfamily)
1663     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
1664   if (key == Mweight)
1665     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
1666   if (key == Mstyle)
1667     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
1668   if (key == Mstretch)
1669     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
1670   if (key == Madstyle)
1671     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
1672   if (key == Mregistry)
1673     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
1674   if (key == Msize)
1675     {
1676       int size = font->property[MFONT_SIZE];
1677       return (void *) size;
1678     }
1679   if (key == Mresolution)
1680     {
1681       int resy = font->property[MFONT_RESY];
1682       return (void *) resy;
1683     }
1684
1685   MERROR (MERROR_FONT, NULL);
1686 }
1687
1688
1689 /*=*/
1690 /***en
1691     @brief Put a property value to a font.
1692
1693     The mfont_put_prop () function puts a font property whose key is
1694     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
1695     following symbols:
1696
1697         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1698         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1699
1700     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
1701     Otherwise, $VAL must be a symbol.  */
1702 /***ja
1703     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
1704
1705     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY ¤Ç¤¢¤ë¥×¥í
1706     ¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢
1707     ¤ë¡£
1708
1709         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1710         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1711
1712     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ
1713     ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
1714
1715 int
1716 mfont_put_prop (MFont *font, MSymbol key, void *val)
1717 {
1718   if (key == Mfoundry)
1719     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
1720   else if (key == Mfamily)
1721     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
1722   else if (key == Mweight)
1723     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
1724   else if (key == Mstyle)
1725     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
1726   else if (key == Mstretch)
1727     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
1728   else if (key == Madstyle)
1729     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
1730   else if (key == Mregistry)
1731     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
1732   else if (key == Msize)
1733     {
1734       unsigned size = (unsigned) val;
1735       font->property[MFONT_SIZE] = size;
1736     }
1737   else if (key == Mresolution)
1738     {
1739       unsigned resy = (unsigned) val;
1740       font->property[MFONT_RESY] =  resy;
1741     }
1742   else
1743     MERROR (MERROR_FONT, -1);
1744   return 0;
1745 }
1746
1747 /*=*/
1748
1749 /***en
1750     @brief Return the font selection priority.
1751
1752     The mfont_selection_priority () function returns a newly created
1753     array of six symbols.  The elements are the following
1754     keys of font properties ordered by priority.
1755
1756         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1757         @c Madstyle, @c Msize.
1758
1759    The m17n library selects the best matching font according to the
1760    order of this array.  A font that has a different value for a
1761    property of lower priority is preferred to a font that has a
1762    different value for a property of higher priority.  */
1763 /***ja
1764     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÊÖ¤¹.
1765
1766     ´Ø¿ô mfont_selection_priority () ¤Ï6¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã
1767     ¤ÆÊÖ¤¹¡£ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤ËÊÂ
1768     ¤Ù¤¿¤â¤Î¤Ç¤¢¤ë¡£
1769
1770         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1771         @c Madstyle, @c Msize.
1772
1773    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
1774    Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬°ã¤¦¥Õ¥©¥ó¥È¤ÈÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤Î
1775    Ãͤ¬°ã¤¦¥Õ¥©¥ó¥È¤¬¤¢¤ë¾ì¹ç¡¢Á°¼Ô¤¬ÁªÂò¤µ¤ì¤ë¡£
1776    */
1777
1778 MSymbol *
1779 mfont_selection_priority ()
1780 {
1781   MSymbol *keys;
1782   int i;
1783
1784   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
1785   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1786     {
1787       enum MFontProperty prop = font_score_priority[i];
1788
1789       if (prop == MFONT_SIZE)
1790         keys[i] = Msize;
1791       else if (prop == MFONT_ADSTYLE)
1792         keys[i] = Madstyle;
1793       else if (prop == MFONT_FAMILY)
1794         keys[i] = Mfamily;
1795       else if (prop == MFONT_WEIGHT)
1796         keys[i] = Mweight;
1797       else if (prop == MFONT_STYLE)
1798         keys[i] = Mstyle;
1799       else if (prop == MFONT_STRETCH)
1800         keys[i] = Mstretch;
1801       else
1802         keys[i] = Mfoundry;
1803     }
1804   return keys;
1805 }
1806
1807 /*=*/
1808
1809 /***en
1810     @brief Set the font selection priority.
1811
1812     The mfont_set_selection_priority () function sets font selection
1813     priority according to $KEYS, which is an array of six symbols.
1814     Each element must be one of the below.  No two elements must be
1815     the same.
1816
1817         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1818         @c Madstyle, @c Msize.
1819
1820     See the documentation of the function mfont_selection_priority ()
1821     for details.  */
1822 /***ja
1823     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
1824
1825     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
1826     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£³ÆÍ×ÁǤϰʲ¼¤Î¤¦¤Á¤Î¤É¤ì
1827     ¤«¤Ç¤¢¤ê¡¢Á´¤Æ°Û¤Ê¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1828
1829         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1830         @c Madstyle, @c Msize.
1831
1832     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
1833      */
1834
1835 int
1836 mfont_set_selection_priority (MSymbol *keys)
1837 {
1838   int priority[FONT_SCORE_PRIORITY_SIZE];
1839   int i, j;
1840
1841   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
1842     {
1843       enum MFontProperty prop;
1844
1845       if (*keys == Msize)
1846         prop = MFONT_SIZE;
1847       else if (*keys == Madstyle)
1848         prop = MFONT_ADSTYLE;
1849       else if (*keys == Mfamily)
1850         prop = MFONT_FAMILY;
1851       else if (*keys == Mweight)
1852         prop = MFONT_WEIGHT;
1853       else if (*keys == Mstyle)
1854         prop = MFONT_STYLE;
1855       else if (*keys == Mstretch)
1856         prop = MFONT_STRETCH;
1857       else if (*keys == Mfoundry)
1858         prop = MFONT_FOUNDRY;
1859       else
1860         /* Invalid element.  */
1861         return -1;
1862       for (j = 0; j < i; j++)
1863         if (priority[j] == prop)
1864           /* Duplicated element.  */
1865           return -1;
1866       priority[i] = prop;
1867     }
1868   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1869     font_score_priority[i] = priority[i];
1870   return 0;
1871 }
1872
1873 /*=*/
1874
1875 /***en
1876     @brief Find a font.
1877
1878     The mfont_find () function returns a pointer to the available font
1879     that matches best the specification $SPEC on frame $FRAME.
1880
1881     $SCORE, if not NULL, must point to a place to store the score
1882     value that indicates how well the found font matches to $SPEC.  The
1883     smaller score means a better match.  */
1884 /***ja
1885     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
1886
1887     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC ¤Ë¤â¤Ã
1888     ¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
1889
1890     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC ¤Ë¤É¤ì¤Û¤É¹ç¤Ã
1891     ¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥¹¥³¥¢¤¬¾®¤µ
1892     ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1893     */
1894
1895 MFont *
1896 mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
1897 {
1898   MFont spec_copy;
1899   MRealizedFont *rfont;
1900
1901   MFONT_INIT (&spec_copy);
1902   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
1903
1904   rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
1905   if (!rfont)
1906     return NULL;
1907   if (score)
1908     *score = rfont->score;
1909   return &rfont->font;
1910 }
1911
1912 /*=*/
1913 /***en
1914     @brief Set encoding of a font.
1915
1916     The mfont_set_encoding () function sets the encoding information
1917     of font $FONT.
1918
1919     $ENCODING_NAME is a symbol representing a charset that has the
1920     same encoding as the font.
1921
1922     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
1923     has the same repertory as the font.  If it is @c Mnil, whether a
1924     specific character is supported by the font is asked to each font
1925     driver.
1926
1927     @return
1928     If the operation was successful, this function returns 0.
1929     Otherwise it returns -1 and assigns an error code to the external
1930     variable #merror_code.  */
1931 /***ja
1932     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
1933
1934     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó
1935     ¤òÀßÄꤹ¤ë¡£
1936
1937     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò
1938     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1939
1940     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó
1941     ¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ
1942     »ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤Ë
1943     Ì䤤¹ç¤ï¤»¤ë¡£
1944
1945     @return
1946     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°
1947     ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1948
1949
1950 int
1951 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
1952 {
1953   MCharset *encoding_charset = MCHARSET (encoding_name);
1954   MCharset *repertory_charset;
1955   MSymbol registry;
1956   MFontEncoding *encoding;
1957   MPlist *plist;
1958
1959   if (! encoding_charset)
1960     MERROR (MERROR_FONT, -1);
1961   if (repertory_name != Mnil)
1962     {
1963       repertory_charset = MCHARSET (repertory_name);
1964       if (! repertory_charset)
1965         MERROR (MERROR_FONT, -1);
1966     }
1967   else
1968     repertory_charset = NULL;
1969
1970   MSTRUCT_CALLOC (encoding, MERROR_FONT);
1971   encoding->spec = *font;
1972   encoding->encoding_name = encoding_name;
1973   encoding->encoding_charset = encoding_charset;
1974   encoding->repertory_name = repertory_name;
1975   encoding->repertory_charset = repertory_charset;
1976   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
1977   if (registry == Mnil)
1978     registry = Mt;
1979   if (! font_encoding_list)
1980     load_font_encoding_table ();
1981   mplist_push (font_encoding_list, registry, encoding);
1982   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
1983     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
1984                   sizeof (MFont)))
1985       {
1986         mplist_pop (plist);
1987         break;
1988       }
1989   return 0;
1990 }
1991
1992 /*=*/
1993
1994 /***en
1995     @brief Create a fontname from a font.
1996
1997     This function is obsolete.   Use mfont_unparse_name instead. */
1998 /***ja
1999     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2000
2001     ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
2002
2003 char *
2004 mfont_name (MFont *font)
2005 {
2006   return mfont_unparse_name (font, Mx);
2007 }
2008
2009 /*=*/
2010
2011 /***en
2012     @brief Create a new font from fontname.
2013
2014     This function is obsolete.  Use mfont_parse_name () instead.  */
2015
2016 /***ja
2017     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2018
2019     ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
2020
2021 MFont *
2022 mfont_from_name (char *name)
2023 {
2024   return mfont_parse_name (name, Mx);
2025 }
2026
2027 /*** @} */
2028
2029 /*** @addtogroup m17nDebug */
2030 /*=*/
2031 /*** @{ */
2032
2033 /***en
2034     @brief Dump a font.
2035
2036     The mdebug_dump_font () function prints font $FONT in a human readable
2037     way to the stderr.
2038
2039     @return
2040     This function returns $FONT.  */
2041 /***ja
2042     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
2043
2044     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr ¤Ë¿Í´Ö¤Ë²ÄÆɤÊ
2045     ·Á¤Ç°õºþ¤¹¤ë¡£
2046
2047     @return
2048     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
2049
2050 MFont *
2051 mdebug_dump_font (MFont *font)
2052 {
2053   char *name;
2054   
2055   name = mfont_unparse_name (font, Mx);
2056   if (name)
2057     {
2058       fprintf (stderr, "%s", name);
2059       free (name);
2060     }
2061   return font;
2062 }
2063
2064 /*** @} */
2065
2066 /*
2067   Local Variables:
2068   coding: euc-japan
2069   End:
2070 */