(mfont__encoding_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 MPlist *
1254 mfont__encoding_list (void)
1255 {
1256   if (! font_encoding_list)
1257     load_font_encoding_table ();
1258   return font_encoding_list;
1259 }
1260
1261 /*** @} */
1262 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1263
1264 \f
1265
1266 /* External API */
1267
1268 /*** @addtogroup m17nFont */
1269 /*** @{ */
1270 /*=*/
1271
1272 /***en @name Variables: Keys of font property.  */
1273 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1274 /*** @{ */
1275 /*=*/
1276
1277 /***en
1278     @brief Key of font property specifying foundry.
1279
1280     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1281     is used as a key of font property and face property.  The property
1282     value must be a symbol whose name is a foundry name of a font.  */
1283 /***ja
1284     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1285     
1286     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1287     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1288     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1289     */
1290
1291 MSymbol Mfoundry;
1292
1293 /***en
1294     @brief Key of font property specifying family.
1295
1296     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1297     used as a key of font property and face property.  The property
1298     value must be a symbol whose name is a family name of a font.  */ 
1299 /***ja
1300     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1301     
1302     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1303     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1304     ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1305     */
1306
1307 MSymbol Mfamily;
1308
1309 /***en
1310     @brief Key of font property specifying weight.
1311
1312     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1313     used as a key of font property and face property.  The property
1314     value must be a symbol whose name is a weight name of a font (e.g
1315     "medium", "bold").  */ 
1316 /***ja
1317     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1318     
1319     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1320     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1321     ¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1322     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1323     */
1324
1325 MSymbol Mweight;
1326
1327 /***en
1328     @brief Key of font property specifying style.
1329
1330     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1331     used as a key of font property and face property.  The property
1332     value must be a symbol whose name is a style name of a font (e.g
1333     "r", "i", "o").  */ 
1334 /***ja
1335     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1336     
1337     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1338     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1339     ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1340     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1341     */
1342
1343 MSymbol Mstyle;
1344
1345 /***en
1346     @brief Key of font property specifying stretch.
1347
1348     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1349     is used as a key of font property and face property.  The property
1350     value must be a symbol whose name is a stretch name of a font (e.g
1351     "normal", "condensed").  */ 
1352 /***ja
1353     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1354     
1355     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1356     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1357     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1358     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1359     */
1360
1361 MSymbol Mstretch;
1362
1363 /***en
1364     @brief Key of font property specifying additional style.
1365
1366     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1367     is used as a key of font property and face property.  The property
1368     value must be a symbol whose name is an additional style name of a
1369     font (e.g "serif", "", "sans").  */ 
1370 /***ja
1371     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1372     
1373     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1374     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1375     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1376     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1377     */
1378
1379 MSymbol Madstyle;
1380
1381 /***en
1382     @brief Key of font property specifying registry.
1383
1384     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1385     and is used as a key of font property.  The property value must be
1386     a symbol whose name is a registry name a font registry
1387     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1388 /***ja
1389     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1390     
1391     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
1392     ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
1393     ¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" Åù) ¤ò̾Á°¤È¤·
1394     ¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1395     */
1396
1397 MSymbol Mregistry;
1398
1399 /***en
1400     @brief Key of font property specifying size.
1401
1402     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1403     used as a key of font property and face property.  The property
1404     value must be an integer specifying a font design size in the unit
1405     of 1/10 point (on 100 dpi display).  */ 
1406 /***ja
1407     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1408     
1409     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©
1410     ¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1411     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó
1412     ¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1413     */
1414
1415 MSymbol Msize;
1416
1417 /***en
1418     @brief Key of font property specifying resolution.
1419
1420     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1421     is used as a key of font property and face property.  The property
1422     value must be an integer to specifying a font resolution in the
1423     unit of dots per inch (dpi).  */ 
1424 /***ja
1425     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1426     
1427     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü
1428     ¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é
1429     ¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ô
1430     ÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1431     */
1432
1433 MSymbol Mresolution;
1434
1435 /***en
1436     @brief Symobl of name "fontconfig".
1437
1438     The variable #Mfontconfig is to be used as an argument of the
1439     functions mfont_parse_name () and mfont_unparse_name ().  */
1440
1441 MSymbol Mfontconfig;
1442
1443 /***en
1444     @brief Symbol of name "x".
1445
1446     The variable #Mx is to be used for a value of <type> member of the
1447     structure #MDrawGlyph to specify the type of <fontp> member is
1448     actually (XFontStruct *).  */
1449
1450 MSymbol Mx;
1451
1452 /***en
1453     @brief Symbol of name "freetype".
1454
1455     The variable #Mfreetype is to be used for a value of <type> member
1456     of the structure #MDrawGlyph to specify the type of <fontp> member
1457     is actually FT_Face.  */
1458
1459 MSymbol Mfreetype;
1460
1461 /***en
1462     @brief Symbol of name "xft".
1463
1464     The variable #Mxft is to be used for a value of <type> member of the
1465     structure #MDrawGlyph to specify the type of <fontp> member
1466     is actually (XftFont *).  */
1467
1468 MSymbol Mxft;
1469
1470 /*=*/
1471 /*** @} */
1472 /*=*/
1473
1474 /***en
1475     @brief List of font files and directories that contain font files.
1476
1477     The variable @c mfont_freetype_path is a plist of FreeType font
1478     files and directories that contain FreeType font files.  Key of
1479     the element is @c Mstring, and the value is a string that
1480     represents a font file or a directory.
1481
1482     The macro M17N_INIT () sets up this variable to contain the
1483     sub-directory "fonts" of the m17n database and the environment
1484     variable "M17NDIR".  The first call of mframe () creates the
1485     internal list of the actually available fonts from this variable.
1486     Thus, an application program, if necessary, must modify the
1487     variable before calling mframe ().  If it is going to add a new
1488     element, value must be a string that can be safely freed.
1489
1490     If the m17n library is not configured to use the FreeType library,
1491     this variable is not used.  */
1492 /***ja
1493     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
1494
1495     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë
1496     ¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring ¤Ç¤¢
1497     ¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
1498
1499     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ
1500      ¿ô "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
1501      mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©
1502      ¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢
1503      mframe () ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê
1504      ¤¤¡£¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó
1505      ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1506
1507     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì
1508     ¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
1509
1510 MPlist *mfont_freetype_path;
1511
1512 /*=*/
1513
1514 /***en
1515     @brief Create a new font.
1516
1517     The mfont () function creates a new font object that has no
1518     property.
1519
1520     @return
1521     This function returns a pointer to the created font object.  */
1522 /***ja
1523     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
1524
1525     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯
1526     ¥È¤òºî¤ë¡£
1527
1528     @return
1529     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
1530
1531 MFont *
1532 mfont ()
1533 {
1534   MFont *font;
1535
1536   MSTRUCT_CALLOC (font, MERROR_FONT);
1537   return font;
1538 }
1539
1540 /*=*/
1541
1542 /***en
1543     @brief Create a font by parsing a fontname.
1544
1545     The mfont_parse_name () function creates a new font object.  The
1546     properties are extracted fontname $NAME.
1547
1548     $FORMAT specifies the format of $NAME.  If $FORMAT is #Mx, $NAME
1549     is parsed as XLFD (X Logical Font Description).  If $FORMAT is
1550     #Mfontconfig, $NAME is parsed as Fontconfig's textual
1551     representation of font.  If $FORMAT is #Mnil, $NAME is at first
1552     parsed as XLFD, and it it fails, parsed as Fontconfig's
1553     representation.
1554
1555     @return
1556     If the operation was successful, this function returns a pointer
1557     to the created font.  Otherwise it returns @c NULL.  */
1558
1559 /***ja
1560     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1561
1562     ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
1563     ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
1564
1565     $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
1566     $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1567     $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­
1568     ¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD ¤Ë
1569     ½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1570
1571     @return
1572     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
1573     ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
1574
1575 MFont *
1576 mfont_parse_name (char *name, MSymbol format)
1577 {
1578   MFont template, *font;
1579   
1580   MFONT_INIT (&template);
1581   if (mfont__parse_name_into_font (name, format, &template) < 0)
1582     MERROR (MERROR_FONT, NULL);
1583   MSTRUCT_CALLOC (font, MERROR_FONT);
1584   *font = template;
1585   return font;
1586 }
1587
1588 /*=*/
1589
1590 /***en
1591     @brief Create a fontname from a font.
1592
1593     The mfont_unparse_name () function creates a fontname string
1594     from font $FONT according to $FORMAT.
1595
1596     $FORMAT must be #Mx or #Mfontconfig.  If it is #Mx, the fontname
1597     is in XLFD (X Logical Font Description) format.  If it is
1598     #Mfontconfig, the fontname is in the style of Fontconfig's text
1599     representation.
1600
1601     @return
1602     This function returns a newly allocated fontname string, which is
1603     not freed unless the user explicitly does so by free ().  */
1604
1605 /***ja
1606     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1607
1608     ´Ø¿ô mfont_unparse_name () ¤Ï $FORMAT ¤Ë¤·¤¿¤¬¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»ú
1609     Îó¤ò¥Õ¥©¥ó¥È$FONT ¤ò¸µ¤Ëºî¤ë¡£
1610
1611     $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£#Mx ¤Ê¤é¤Ð¥Õ¥©
1612     ¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£#Mfontconfig ¤Ê
1613     ¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
1614
1615     @return 
1616     ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢
1617     ¥æ¡¼¥¶¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
1618
1619 char *
1620 mfont_unparse_name (MFont *font, MSymbol format)
1621 {
1622   char *name;
1623
1624   if (format == Mx)
1625     name = xlfd_unparse_name (font);
1626 #ifdef HAVE_FONTCONFIG
1627   else if (format == Mfontconfig)
1628     name = mfont__ft_unparse_name (font);
1629 #endif
1630   else
1631     MERROR (MERROR_FONT, NULL);
1632   return name;
1633 }
1634
1635 /*=*/
1636
1637 /***en
1638     @brief Make a copy of a font.
1639
1640     The mfont_copy () function returns a new copy of font $FONT.  */
1641 /***ja
1642     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
1643
1644     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
1645
1646 MFont *
1647 mfont_copy (MFont *font)
1648 {
1649   MFont *copy;
1650
1651   MSTRUCT_MALLOC (copy, MERROR_FONT);
1652   *copy = *font;
1653   return copy;
1654 }
1655
1656 /*=*/
1657
1658 /***en
1659     @brief Get a property value of a font.
1660
1661     The mfont_get_prop () function gets the value of $KEY property of
1662     font $FONT.  $KEY must be one of the following symbols:
1663
1664         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1665         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1666
1667     @return
1668     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1669     Madstyle, or @c Mregistry, this function returns the
1670     corresponding value as a symbol.  If the font does not have $KEY
1671     property, it returns @c Mnil.
1672     If $KEY is @c Msize or @c Mresolution, this function returns the
1673     corresponding value as an integer.  If the font does not have $KEY
1674     property, it returns 0.
1675     If $KEY is something else, it returns @c NULL and assigns an error
1676     code to the external variable #merror_code.  */
1677
1678 /***ja
1679     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1680
1681     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
1682     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
1683     ¤Ð¤Ê¤é¤Ê¤¤¡£
1684
1685         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1686         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1687
1688     @return 
1689     $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1690     Madstyle, @c Mregistry ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È
1691     ¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c Mnil ¤òÊÖ¤¹¡£
1692     $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò
1693     ¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤ò
1694     ÊÖ¤¹¡£
1695     $KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
1696     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1697
1698 void *
1699 mfont_get_prop (MFont *font, MSymbol key)
1700 {
1701   if (key == Mfoundry)
1702     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
1703   if (key == Mfamily)
1704     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
1705   if (key == Mweight)
1706     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
1707   if (key == Mstyle)
1708     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
1709   if (key == Mstretch)
1710     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
1711   if (key == Madstyle)
1712     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
1713   if (key == Mregistry)
1714     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
1715   if (key == Msize)
1716     {
1717       int size = font->property[MFONT_SIZE];
1718       return (void *) size;
1719     }
1720   if (key == Mresolution)
1721     {
1722       int resy = font->property[MFONT_RESY];
1723       return (void *) resy;
1724     }
1725
1726   MERROR (MERROR_FONT, NULL);
1727 }
1728
1729
1730 /*=*/
1731 /***en
1732     @brief Put a property value to a font.
1733
1734     The mfont_put_prop () function puts a font property whose key is
1735     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
1736     following symbols:
1737
1738         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1739         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1740
1741     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
1742     Otherwise, $VAL must be a symbol.  */
1743 /***ja
1744     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
1745
1746     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY ¤Ç¤¢¤ë¥×¥í
1747     ¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢
1748     ¤ë¡£
1749
1750         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1751         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1752
1753     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ
1754     ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
1755
1756 int
1757 mfont_put_prop (MFont *font, MSymbol key, void *val)
1758 {
1759   if (key == Mfoundry)
1760     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
1761   else if (key == Mfamily)
1762     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
1763   else if (key == Mweight)
1764     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
1765   else if (key == Mstyle)
1766     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
1767   else if (key == Mstretch)
1768     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
1769   else if (key == Madstyle)
1770     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
1771   else if (key == Mregistry)
1772     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
1773   else if (key == Msize)
1774     {
1775       unsigned size = (unsigned) val;
1776       font->property[MFONT_SIZE] = size;
1777     }
1778   else if (key == Mresolution)
1779     {
1780       unsigned resy = (unsigned) val;
1781       font->property[MFONT_RESY] =  resy;
1782     }
1783   else
1784     MERROR (MERROR_FONT, -1);
1785   return 0;
1786 }
1787
1788 /*=*/
1789
1790 /***en
1791     @brief Return the font selection priority.
1792
1793     The mfont_selection_priority () function returns a newly created
1794     array of six symbols.  The elements are the following
1795     keys of font properties ordered by priority.
1796
1797         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1798         @c Madstyle, @c Msize.
1799
1800    The m17n library selects the best matching font according to the
1801    order of this array.  A font that has a different value for a
1802    property of lower priority is preferred to a font that has a
1803    different value for a property of higher priority.  */
1804 /***ja
1805     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÊÖ¤¹.
1806
1807     ´Ø¿ô mfont_selection_priority () ¤Ï6¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã
1808     ¤ÆÊÖ¤¹¡£ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤ËÊÂ
1809     ¤Ù¤¿¤â¤Î¤Ç¤¢¤ë¡£
1810
1811         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1812         @c Madstyle, @c Msize.
1813
1814    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
1815    Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬°ã¤¦¥Õ¥©¥ó¥È¤ÈÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤Î
1816    Ãͤ¬°ã¤¦¥Õ¥©¥ó¥È¤¬¤¢¤ë¾ì¹ç¡¢Á°¼Ô¤¬ÁªÂò¤µ¤ì¤ë¡£
1817    */
1818
1819 MSymbol *
1820 mfont_selection_priority ()
1821 {
1822   MSymbol *keys;
1823   int i;
1824
1825   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
1826   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1827     {
1828       enum MFontProperty prop = font_score_priority[i];
1829
1830       if (prop == MFONT_SIZE)
1831         keys[i] = Msize;
1832       else if (prop == MFONT_ADSTYLE)
1833         keys[i] = Madstyle;
1834       else if (prop == MFONT_FAMILY)
1835         keys[i] = Mfamily;
1836       else if (prop == MFONT_WEIGHT)
1837         keys[i] = Mweight;
1838       else if (prop == MFONT_STYLE)
1839         keys[i] = Mstyle;
1840       else if (prop == MFONT_STRETCH)
1841         keys[i] = Mstretch;
1842       else
1843         keys[i] = Mfoundry;
1844     }
1845   return keys;
1846 }
1847
1848 /*=*/
1849
1850 /***en
1851     @brief Set the font selection priority.
1852
1853     The mfont_set_selection_priority () function sets font selection
1854     priority according to $KEYS, which is an array of six symbols.
1855     Each element must be one of the below.  No two elements must be
1856     the same.
1857
1858         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1859         @c Madstyle, @c Msize.
1860
1861     See the documentation of the function mfont_selection_priority ()
1862     for details.  */
1863 /***ja
1864     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
1865
1866     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
1867     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£³ÆÍ×ÁǤϰʲ¼¤Î¤¦¤Á¤Î¤É¤ì
1868     ¤«¤Ç¤¢¤ê¡¢Á´¤Æ°Û¤Ê¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1869
1870         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1871         @c Madstyle, @c Msize.
1872
1873     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
1874      */
1875
1876 int
1877 mfont_set_selection_priority (MSymbol *keys)
1878 {
1879   int priority[FONT_SCORE_PRIORITY_SIZE];
1880   int i, j;
1881
1882   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
1883     {
1884       enum MFontProperty prop;
1885
1886       if (*keys == Msize)
1887         prop = MFONT_SIZE;
1888       else if (*keys == Madstyle)
1889         prop = MFONT_ADSTYLE;
1890       else if (*keys == Mfamily)
1891         prop = MFONT_FAMILY;
1892       else if (*keys == Mweight)
1893         prop = MFONT_WEIGHT;
1894       else if (*keys == Mstyle)
1895         prop = MFONT_STYLE;
1896       else if (*keys == Mstretch)
1897         prop = MFONT_STRETCH;
1898       else if (*keys == Mfoundry)
1899         prop = MFONT_FOUNDRY;
1900       else
1901         /* Invalid element.  */
1902         return -1;
1903       for (j = 0; j < i; j++)
1904         if (priority[j] == prop)
1905           /* Duplicated element.  */
1906           return -1;
1907       priority[i] = prop;
1908     }
1909   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1910     font_score_priority[i] = priority[i];
1911   return 0;
1912 }
1913
1914 /*=*/
1915
1916 /***en
1917     @brief Find a font.
1918
1919     The mfont_find () function returns a pointer to the available font
1920     that matches best the specification $SPEC on frame $FRAME.
1921
1922     $SCORE, if not NULL, must point to a place to store the score
1923     value that indicates how well the found font matches to $SPEC.  The
1924     smaller score means a better match.  */
1925 /***ja
1926     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
1927
1928     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC ¤Ë¤â¤Ã
1929     ¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
1930
1931     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC ¤Ë¤É¤ì¤Û¤É¹ç¤Ã
1932     ¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥¹¥³¥¢¤¬¾®¤µ
1933     ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1934     */
1935
1936 MFont *
1937 mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
1938 {
1939   MFont spec_copy;
1940   MRealizedFont *rfont;
1941
1942   MFONT_INIT (&spec_copy);
1943   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
1944
1945   rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
1946   if (!rfont)
1947     return NULL;
1948   if (score)
1949     *score = rfont->score;
1950   return &rfont->font;
1951 }
1952
1953 /*=*/
1954 /***en
1955     @brief Set encoding of a font.
1956
1957     The mfont_set_encoding () function sets the encoding information
1958     of font $FONT.
1959
1960     $ENCODING_NAME is a symbol representing a charset that has the
1961     same encoding as the font.
1962
1963     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
1964     has the same repertory as the font.  If it is @c Mnil, whether a
1965     specific character is supported by the font is asked to each font
1966     driver.
1967
1968     @return
1969     If the operation was successful, this function returns 0.
1970     Otherwise it returns -1 and assigns an error code to the external
1971     variable #merror_code.  */
1972 /***ja
1973     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
1974
1975     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó
1976     ¤òÀßÄꤹ¤ë¡£
1977
1978     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò
1979     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1980
1981     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó
1982     ¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ
1983     »ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤Ë
1984     Ì䤤¹ç¤ï¤»¤ë¡£
1985
1986     @return
1987     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°
1988     ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1989
1990
1991 int
1992 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
1993 {
1994   MCharset *encoding_charset = MCHARSET (encoding_name);
1995   MCharset *repertory_charset;
1996   MSymbol registry;
1997   MFontEncoding *encoding;
1998   MPlist *plist;
1999
2000   if (! encoding_charset)
2001     MERROR (MERROR_FONT, -1);
2002   if (repertory_name != Mnil)
2003     {
2004       repertory_charset = MCHARSET (repertory_name);
2005       if (! repertory_charset)
2006         MERROR (MERROR_FONT, -1);
2007     }
2008   else
2009     repertory_charset = NULL;
2010
2011   MSTRUCT_CALLOC (encoding, MERROR_FONT);
2012   encoding->spec = *font;
2013   encoding->encoding_name = encoding_name;
2014   encoding->encoding_charset = encoding_charset;
2015   encoding->repertory_name = repertory_name;
2016   encoding->repertory_charset = repertory_charset;
2017   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
2018   if (registry == Mnil)
2019     registry = Mt;
2020   if (! font_encoding_list)
2021     load_font_encoding_table ();
2022   mplist_push (font_encoding_list, registry, encoding);
2023   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
2024     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
2025                   sizeof (MFont)))
2026       {
2027         mplist_pop (plist);
2028         break;
2029       }
2030   return 0;
2031 }
2032
2033 /*=*/
2034
2035 /***en
2036     @brief Create a fontname from a font.
2037
2038     This function is obsolete.   Use mfont_unparse_name instead. */
2039 /***ja
2040     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2041
2042     ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
2043
2044 char *
2045 mfont_name (MFont *font)
2046 {
2047   return mfont_unparse_name (font, Mx);
2048 }
2049
2050 /*=*/
2051
2052 /***en
2053     @brief Create a new font from fontname.
2054
2055     This function is obsolete.  Use mfont_parse_name () instead.  */
2056
2057 /***ja
2058     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2059
2060     ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
2061
2062 MFont *
2063 mfont_from_name (char *name)
2064 {
2065   return mfont_parse_name (name, Mx);
2066 }
2067
2068 /*=*/
2069
2070 /***en
2071     @brief Get resize information of a font.
2072
2073     The mfont_resize_ratio () function lookups the m17n database
2074     \<font, reisize\> and returns a resizing ratio (in percentage) of
2075     FONT.  For instance, if the return value is 150, that means that
2076     the m17n library uses an 1.5 time bigger font than a specified
2077     size.  */
2078
2079 /***ja
2080     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥µ¥¤¥º¾ðÊó¤òÆÀ¤ë
2081
2082     ´Ø¿ô mfont_resize_ratio ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹ \<font, reisize\> ¤ò¸¡
2083     º÷¤·¡¢¥Õ¥©¥ó¥È FONT ¤Î¥ê¥µ¥¤¥º¤ÎÈæΨ¡Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¡Ë¤òÊÖ¤¹¡£Î㤨
2084     ¤ÐÊÖÃͤ¬ 150 ¤Ç¤¢¤ì¤Ð¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ï»ØÄꤵ¤ì¤¿¥µ¥¤¥º¤Î 1.5 ÇܤÎ
2085     ¥Õ¥©¥ó¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ */
2086
2087 int
2088 mfont_resize_ratio (MFont *font)
2089 {
2090   MFont request = *font;
2091
2092   mfont__resize (font, &request);
2093   return (font->property[MFONT_SIZE] * 100 / request.property[MFONT_SIZE]);
2094 }
2095
2096 /*=*/
2097
2098 /***en
2099     @brief Get a list fonts.
2100
2101     The mfont_list () functions returns a list of fonts available on
2102     frame $FRAME.  If $FONT is not nil, it limits fonts to ones that
2103     matchq with $FONT.  If $LANGUAGE is not @c Mnil, it limits fonts
2104     to ones that support $LANGUAGE.
2105
2106     @return
2107     This function returns a plist whose keys are family name and
2108     values are pointers to the object MFont.  The plist must be freed
2109     by m17n_object_unref ().  */
2110
2111 MPlist *
2112 mfont_list (MFrame *frame, MFont *font, MSymbol language)
2113 {
2114   MPlist *plist = mplist (), *p;
2115   
2116   MPLIST_DO (p, frame->font_driver_list)
2117     {
2118       MFontDriver *driver = MPLIST_VAL (p);
2119
2120       (driver->list) (frame, plist, font, language);
2121     }
2122   return plist;
2123 }
2124
2125 /*** @} */
2126
2127 /*** @addtogroup m17nDebug */
2128 /*=*/
2129 /*** @{ */
2130
2131 /***en
2132     @brief Dump a font.
2133
2134     The mdebug_dump_font () function prints font $FONT in a human readable
2135     way to the stderr.
2136
2137     @return
2138     This function returns $FONT.  */
2139 /***ja
2140     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
2141
2142     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr ¤Ë¿Í´Ö¤Ë²ÄÆɤÊ
2143     ·Á¤Ç°õºþ¤¹¤ë¡£
2144
2145     @return
2146     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
2147
2148 MFont *
2149 mdebug_dump_font (MFont *font)
2150 {
2151   char *name;
2152   
2153   name = mfont_unparse_name (font, Mx);
2154   if (name)
2155     {
2156       fprintf (stderr, "%s", name);
2157       free (name);
2158     }
2159   return font;
2160 }
2161
2162 void
2163 mdebug_dump_font_list (MFrame *frame, MSymbol family)
2164 {
2165   MPlist *plist, *p;
2166
2167   if (family == Mnil)
2168     plist = mfont_list (frame, NULL, Mnil);
2169   else
2170     {
2171       MFont font;
2172
2173       MFONT_INIT (&font);
2174       mfont__set_property (&font, MFONT_FAMILY, family);
2175       plist = mfont_list (frame, &font, Mnil);
2176     }
2177   MPLIST_DO (p, plist)
2178     {
2179       mdebug_dump_font (MPLIST_VAL (p));
2180       fprintf (stderr, "\n");
2181     }
2182   M17N_OBJECT_UNREF (plist);
2183 }
2184
2185 /*** @} */
2186
2187 /*
2188   Local Variables:
2189   coding: euc-japan
2190   End:
2191 */