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