4c022ed9c725f8ccc4e4a89a6baa161b0f13f288
[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, @c Mspacing.
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.  
37
38     "The font property that belongs to font F and whose key is @c
39     Mxxx" may be shortened to "the xxx property of F".
40
41     The value of a foundry property is a symbol representing font
42     foundry information, e.g. adobe, misc, etc.
43
44     The value of a family property is a symbol representing font family
45     information, e.g. times, helvetica, etc.
46
47     The value of a weight property is a symbol representing weight
48     information, e.g. normal, bold, etc.
49
50     The value of a style property is a symbol representing slant
51     information, e.g. normal, italic, etc.
52
53     The value of a stretch property is a symbol representing width
54     information, e.g. normal, semicondensed, etc.
55
56     The value of an adstyle property is a symbol representing abstract
57     font family information, e.g. serif, sans-serif, etc.
58
59     The value of a registry property is a symbol representing registry
60     information, e.g. iso10646-1, iso8895-1, etc.
61
62     The value of a size property is an integer representing design
63     size in the unit of 1/10 point.
64
65     The value of a resolution property is an integer representing
66     assumed device resolution in the unit of dots per inch (dpi).
67
68     The value of a type property is a symbol indicating a font driver;
69     currently Mx or Mfreetype.
70
71     The m17n library uses font objects for two purposes: to receive
72     font specification from an application program, and to present
73     available fonts to an application program.  When the m17n library
74     presents an available font to an application program, all font
75     properties have a concrete value.
76
77     The m17n library supports three kinds of fonts: Window system fonts,
78     FreeType fonts, and OpenType fonts.
79
80     <ul>
81
82     <li> Window system fonts
83
84     The m17n-X library supports all fonts handled by an X server and
85     an X font server.  The correspondence between XLFD fields and font
86     properties are shown below.
87
88 @verbatim
89     XLFD field                                  property
90     ---------------                             --------
91     FOUNDRY                                     foundry
92     FAMILY_NAME                                 family
93     WEIGHT_NAME                                 weight
94     SLANT                                       style
95     SETWIDTH_NAME                               stretch
96     ADD_STYLE_NAME                              adstyle
97     PIXEL_SIZE                                  size
98     RESOLUTION_Y                                resolution
99     CHARSET_REGISTRY-CHARSET_ENCODING           registry
100 @endverbatim
101
102     XLFD fields not listed in the above table are ignored.
103
104     <li> FreeType fonts
105
106     The m17n library, if configured to use the FreeType library,
107     supports all fonts that can be handled by the FreeType library.
108     The variable #mfont_freetype_path is initialized properly according
109     to the configuration of the m17n library and the environment
110     variable @c M17NDIR.  See the documentation of the variable for
111     details.
112
113     If the m17n library is configured to use the fontconfig library,
114     in addition to #mfont_freetype_path, all fonts available via
115     fontconfig are supported.
116
117     The family name of a FreeType font corresponds to the family
118     property.  Style names of FreeType fonts correspond to the weight,
119     style, and stretch properties as below.
120
121 @verbatim
122     style name          weight  style   stretch
123     ----------          ------  -----   -------
124     Regular             medium  r       normal
125     Italic              medium  i       normal
126     Bold                bold    r       normal
127     Bold Italic         bold    i       normal
128     Narrow              medium  r       condensed
129     Narrow Italic       medium  i       condensed
130     Narrow Bold         bold    r       condensed
131     Narrow Bold Italic  bold    i       condensed
132     Black               black   r       normal
133     Black Italic        black   i       normal
134     Oblique             medium  o       normal
135     BoldOblique         bold    o       normal
136 @endverbatim
137
138     Style names not listed in the above table are treated as
139     "Regular".
140
141     Combination of a platform ID and an encoding ID corresponds to the
142     registry property.  For example, if a font has the combination (1
143     1), the registry property is 1-1.  Some frequent combinations have
144     a predefined registry property as below.
145
146 @verbatim
147     platform ID         encoding ID     registry property
148     -----------         -----------     -----------------
149     0                   3               unicode-bmp
150     0                   4               unicode-full
151     1                   0               apple-roman
152     3                   1               unicode-bmp
153     3                   1               unicode-full
154 @endverbatim
155
156     Thus, a font that has two combinations (1 0) and (3 1) corresponds
157     to four font objects whose registries are 1-0, apple-roman, 3-1,
158     and unicode-bmp.
159
160     <li> OpenType fonts 
161
162     The m17n library, if configured to use both the FreeType library
163     and the OTF library, supports any OpenType fonts.  The list of
164     actually available fonts is created in the same way as in the case
165     of FreeType fonts.  If a fontset instructs to use an OpenType font
166     via an FLT (Font Layout Table), and the FLT has an OTF-related
167     command (e.g. otf:deva), the OTF library converts a character
168     sequence to a glyph code sequence according to the OpenType layout
169     tables of the font, and the FreeType library gives a bitmap image
170     for each glyph.
171
172     </ul>
173
174   */
175
176 /***ja
177     @addtogroup m17nFont
178     @brief ¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È.
179
180     m17n GUI API ¤Ï¥Õ¥©¥ó¥È¤ò @c MFont ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æɽ¸½¤¹¤ë¡£
181     ¥Õ¥©¥ó¥È¤Ï @e ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£Â¾¤Î¥¿¥¤¥×¤Î¥×
182     ¥í¥Ñ¥Æ¥£Æ±ÍÍ¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¥­¡¼¤ÈÃͤ«¤é¤Ê¤ê¡¢¥­¡¼¤Ï°Ê²¼¤Î¥·
183     ¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
184
185     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
186     @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing
187
188     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution 
189     ¤Î¾ì¹ç¡¢ÃͤÏÀ°¿ôÃͤǤ¢¤ê¡¢¥­¡¼¤¬¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Ãͤϥ·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
190
191     ¡Ö¥Õ¥©¥ó¥È F ¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ @c Mxxx 
192     ¤Ç¤¢¤ë¤â¤Î¡×¤Î¤³¤È¤ò´Êñ¤Ë¡ÖF ¤Î xxx ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
193
194     foundry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢adobe, misc 
195     Åù¤Î¥Õ¥©¥ó¥È¤Î³«È¯¸µ¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
196
197     family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢times, helvetica 
198     Åù¤Î¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
199
200     weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, bold Åù¤ÎÂÀ¤µ¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
201
202     style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, italic 
203     Åù¤Î¥¹¥¿¥¤¥ë¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
204
205     stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, semicondensed 
206     Åù¤Îʸ»úÉý¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
207
208     adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢serif, sans-serif
209     Åù¤ÎÃê¾ÝŪ¤Ê¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
210
211     registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢iso10646, iso8895-1
212     Åù¤Î¥ì¥¸¥¹¥È¥ê¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
213
214     size ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤òɽ¤ï¤¹À°¿ôÃͤǤ¢¤ê¡¢
215     Ã±°Ì¤Ï1/10 ¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£
216
217     resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ÁÛÄꤵ¤ì¤Æ¤¤¤ë¥Ç¥Ð¥¤¥¹¤Î²òÁüÅÙ¤òɽ¤ï¤¹
218     À°¿ôÃͤǤ¢¤ê¡¢Ã±°Ì¤Ïdots per inch (dpi) ¤Ç¤¢¤ë¡£
219
220     type ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ò»Ø¼¨¤·¡¢¸½ºß Mx ¤â¤·¤¯¤Ï
221     Mfreetype ¤Ç¤¢¤ë¡£
222
223     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤Ä¤ÎÌÜŪ¤ÇÍѤ¤¤Æ¤¤¤ë¡£¥¢¥×
224     ¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¥Õ¥©¥ó¥È¤Î»ØÄê¤ò¼õ¤±¼è¤ëÌÜŪ¤È¡¢¥¢¥×¥ê¥±¡¼
225     ¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤òÄ󼨤¹¤ëÌÜŪ¤Ç¤¢¤ë¡£¥¢¥×¥ê¥±¡¼
226     ¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÂФ·¤ÆÄ󼨤ò¹Ô¤¦ºÝ¤Ë¤Ï¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù
227     ¤Æ¶ñÂÎŪ¤ÊÃͤò»ý¤Ä¡£
228
229     m17n ¥é¥¤¥Ö¥é¥ê¤Ï Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¡¢FreeType¥Õ¥©¥ó¥È¡¢
230     OpenType¥Õ¥©¥ó¥È¤Î£³¼ïÎà¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£
231
232     <ul>
233
234     <li> Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È
235
236     m17n X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢X ¥µ¡¼¥Ð¤È X ¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤¬¼è¤ê°·¤¦Á´¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£
237     XLFD ¤Î³Æ¥Õ¥£¡¼¥ë¥É¤È¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ÎÂбþ¤Ï°Ê²¼¤ÎÄ̤ꡣ¤³¤Îɽ¤Ë¤Ê¤¤¥Õ¥£¡¼¥ë¥É¤Ï̵»ë¤µ¤ì¤ë¡£
238
239 @verbatim
240     XLFD ¥Õ¥£¡¼¥ë¥É                             ¥×¥í¥Ñ¥Æ¥£
241     ---------------                             --------
242     FOUNDRY                                     foundry
243     FAMILY_NAME                                 family
244     WEIGHT_NAME                                 weight
245     SLANT                                       style
246     SETWIDTH_NAME                               stretch
247     ADD_STYLE_NAME                              adstyle
248     PIXEL_SIZE                                  size
249     RESOLUTION_Y                                resolution
250     CHARSET_REGISTRY-CHARSET_ENCODING           registry
251 @endverbatim
252
253     <li> FreeType fonts
254
255     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
256     FreeType ¤¬°·¤¦¤¹¤Ù¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ÊÑ¿ô 
257     #mfont_freetype_path ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤ÎÀßÄê¤È´Ä¶­ÊÑ¿ô @c M17NDIR 
258     ¤Ë±þ¤¸¤Æ½é´ü²½¤µ¤ì¤ë¡£¾ÜºÙ¤ÏÊÑ¿ô¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
259
260     ¤â¤· m17n ¥é¥¤¥Ö¥é¥ê¤¬ fontconfig ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
261     #mfont_freetype_path ¤Ë²Ã¤¨¤Æ¡¢ fontconfig ¤Ç»ÈÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤â¤¹¤Ù¤Æ¥µ¥Ý¡¼¥È¤µ¤ì¤ë¡£
262
263     FreeType ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤Ï family ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
264     FreeType ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾¤Ï¡¢²¼¤Îɽ¤Î¤è¤¦¤Ë weight, style,
265     stretch ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
266
267 @verbatim
268     ¥¹¥¿¥¤¥ë̾          weight  style   stretch
269     ----------          ------  -----   -------
270     Regular             medium  r       normal
271     Italic              medium  i       normal
272     Bold                bold    r       normal
273     Bold Italic         bold    i       normal
274     Narrow              medium  r       condensed
275     Narrow Italic       medium  i       condensed
276     Narrow Bold         bold    r       condensed
277     Narrow Bold Italic  bold    i       condensed
278     Black               black   r       normal
279     Black Italic        black   i       normal
280     Oblique             medium  o       normal
281     BoldOblique         bold    o       normal
282 @endverbatim
283
284     ¾å¤Îɽ¤Ë¸½¤ï¤ì¤Ê¤¤¥¹¥¿¥¤¥ë̾¤Ï "Regular" ¤È¤·¤Æ°·¤ï¤ì¤ë¡£
285
286     platform ID ¤È encoding ID ¤ÎÁȤ߹ç¤ï¤»¤¬ registry 
287     ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£¤¿¤È¤¨¤Ð¤¢¤ë¥Õ¥©¥ó¥È¤¬ (1 1) ¤È¤¤¤¦ ID ¤ÎÁȹ礻¤ò»ý¤Æ¤Ð¡¢
288     registry ¥×¥í¥Ñ¥Æ¥£¤Ï 1-1 ¤È¤Ê¤ë¡£ÉÑÈˤˤ¢¤é¤ï¤ì¤ëÁȹ礻¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤ÊÄêµÁºÑ¤ß
289     registry ¥×¥í¥Ñ¥Æ¥£ ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤ë¡£
290
291 @verbatim
292     platform ID         encoding ID     registry ¥×¥í¥Ñ¥Æ¥£
293     -----------         -----------     -----------------
294     0                   3               unicode-bmp
295     0                   4               unicode-full
296     1                   0               apple-roman
297     3                   1               unicode-bmp
298     3                   1               unicode-full
299 @endverbatim
300
301     ¤·¤¿¤¬¤Ã¤Æ¡¢Æó¤Ä¤ÎÁȹ礻 (1 0) ¡¢(3 1) ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤Ï¡¢¤½¤ì¤¾¤ì
302     registry ¥×¥í¥Ñ¥Æ¥£¤¬ 1-0, apple-roman, 3-1, unicode-bmp
303     ¤Ç¤¢¤ë£´¤Ä¤Î¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ËÂбþ¤¹¤ë¡£
304
305     <li> OpenType ¥Õ¥©¥ó¥È
306
307     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤È OTF 
308     ¥é¥¤¥Ö¥é¥ê¤ò»ÈÍѤ¹¤ë¤è¤¦¤ËÀßÄꤹ¤ì¤Ð¡¢¤¹¤Ù¤Æ¤Î OpenType 
309     ¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£¼ÂºÝ¤ËÍøÍѤǤ­¤ë¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤Ï FreeType
310     ¥Õ¥©¥ó¥È¤Î¾ì¹ç¤ÈƱÍͤ˺î¤é¤ì¤ë¡£OpenType ¥Õ¥©¥ó¥È¤ò FLT (Font Layout Table)
311     ·Ðͳ¤Ç»ÈÍѤ¹¤ë¤è¤¦¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ë»ØÄꤵ¤ì¤Æ¤ª¤ê¡¢FLT ¤Ë OTF 
312     ´ØÏ¢¤Î¥³¥Þ¥ó¥É (¤¿¤È¤¨¤Ð otf:deva) ¤¬¤¢¤ì¤Ð¡¢OTF ¥é¥¤¥Ö¥é¥ê¤¬¥Õ¥©¥ó¥È¤Î OpenType
313     ¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¤Ë½¾¤Ã¤Æʸ»úÎó¤ò¥°¥ê¥Õ¥³¡¼¥ÉÎó¤ËÊÑ´¹¤·¡¢FreeType
314     ¥é¥¤¥Ö¥é¥ê¤¬³Æ¥°¥ê¥Õ¤Î¥Ó¥Ã¥È¥Þ¥Ã¥×¥¤¥á¡¼¥¸¤òÄ󶡤¹¤ë¡£
315
316     </ul>
317
318 */
319
320 /*=*/
321
322 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
323 /*** @addtogroup m17nInternal
324      @{ */
325
326 #include "config.h"
327
328 #include <stdio.h>
329 #include <stdlib.h>
330 #include <string.h>
331
332 #include "m17n-gui.h"
333 #include "m17n-misc.h"
334 #include "internal.h"
335 #include "mtext.h"
336 #include "symbol.h"
337 #include "plist.h"
338 #include "charset.h"
339 #include "internal-gui.h"
340 #include "font.h"
341 #include "face.h"
342 #include "fontset.h"
343
344 MPlist *mfont__driver_list;
345
346 static MSymbol M_font_capability, M_font_list, M_font_list_len;
347
348 /** Indices to font properties sorted by their priority.  */
349 static int font_score_priority[] =
350   { MFONT_SIZE,
351     MFONT_WEIGHT,
352     MFONT_STYLE,
353     MFONT_STRETCH,
354     MFONT_FAMILY,
355     MFONT_ADSTYLE,
356     MFONT_FOUNDRY
357   };
358
359 #define FONT_SCORE_PRIORITY_SIZE        \
360   (sizeof font_score_priority / sizeof font_score_priority[0])
361
362 /* Indexed by a font property MFONT_XXX, and the value is how many
363    bits to shift the difference of property values.  */
364 static int font_score_shift_bits[MFONT_SIZE + 1];
365
366 /** Predefined symbols for each font property.  The order is important
367     because the function font_score () decides how well a font matches
368     with a spec by checking how close the index is.  */
369
370 static char *common_foundry[] =
371   { "misc",
372     "adobe" };
373 static char *common_family[] =
374   { "fixed",
375     "courier",
376     "helvetica",
377     "times" };
378 static char *common_weight[] =
379   { "thin"
380     "ultralight",
381     "extralight",
382     "light",
383     "demilight",
384     "book",
385     "regular",
386     "normal",
387     "medium",
388     "demibold",
389     "semibold",
390     "bold",
391     "extrabold",
392     "ultrabold",
393     "black",
394     "heavy" };
395 static char *common_style[] =
396   { "o",
397     "i",
398     "slanted",
399     "r",
400     "rslanted",
401     "ri",
402     "ro" };
403 static char *common_stretch[] =
404   { "ultracondensed",
405     "extracondensed",
406     "condensed",
407     "narrow",
408     "semicondensed",
409     "normal",
410     "semiexpanded",
411     "expanded",
412     "extraexpanded",
413     "ultraexpanded" };
414 static char *common_adstyle[] =
415   { "serif",
416     "",
417     "sans" };
418 static char *common_registry[] =
419   { "iso8859-1" };
420
421 static unsigned short font_weight_regular;
422 static unsigned short font_weight_normal;
423 static unsigned short font_weight_medium;
424
425 /* Table containing all the data above.  */
426
427 struct MFontCommonNames
428 {
429   int num;
430   char **names;
431 };
432
433 static struct MFontCommonNames font_common_names[] =
434   {
435     { sizeof (common_foundry) / sizeof (char *), common_foundry},
436     { sizeof (common_family) / sizeof (char *), common_family},
437     { sizeof (common_weight) / sizeof (char *), common_weight},
438     { sizeof (common_style) / sizeof (char *), common_style},
439     { sizeof (common_stretch) / sizeof (char *), common_stretch},
440     { sizeof (common_adstyle) / sizeof (char *), common_adstyle},
441     { sizeof (common_registry) / sizeof (char *), common_registry}
442   };
443
444
445 /** Table of available font property names.  */
446
447 MFontPropertyTable mfont__property_table[MFONT_REGISTRY + 1];
448
449
450 /** Return the numeric value of SYMBOL as the Nth font property.  */
451
452 #define FONT_PROPERTY_NUMERIC(symbol, n)        \
453   ((symbol) == Mnil                             \
454    ? 0                                          \
455    : ((int) msymbol_get ((symbol), mfont__property_table[(n)].property)))
456
457
458 /** Set the numeric value of SYMBOL as the Nth font property to NUMERIC.  */
459
460 #define SET_FONT_PROPERTY_NUMERIC(symbol, n, numeric)           \
461   msymbol_put((symbol), mfont__property_table[(n)].property,    \
462               (void *) (numeric))
463
464 \f
465 /* Font selector.  */
466
467 struct MFontEncoding {
468   MFont spec;
469   MSymbol encoding_name;
470   MCharset *encoding_charset;
471   MSymbol repertory_name;
472   MCharset *repertory_charset;
473 };
474
475 static MPlist *font_encoding_list;
476 static MFontEncoding default_encoding;
477
478 /** Load font encoding table from the data <font encoding>.
479     The data has this form:
480         (FONT-SPEC ENCODING) ...
481     where FONT-SPEC has this form:
482         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
483     All elements are symbols.  */
484
485 static int
486 load_font_encoding_table ()
487 {
488   MDatabase *mdb;
489   MPlist *encoding_list, *plist, *pl, *elt;
490
491   font_encoding_list = pl = mplist ();
492
493   mdb = mdatabase_find (Mfont, msymbol ("encoding"), Mnil, Mnil);
494   if (! mdb
495       || ! (encoding_list = (MPlist *) mdatabase_load (mdb)))
496     MERROR (MERROR_FONT, -1);
497
498   MPLIST_DO (plist, encoding_list)
499     {
500       MFontEncoding *encoding;
501       MSymbol registry;
502
503       MSTRUCT_CALLOC (encoding, MERROR_FONT);
504
505       if (! MPLIST_PLIST_P (plist)
506           || (elt = MPLIST_PLIST (plist), mplist_length (elt) < 2)
507           || ! MPLIST_PLIST_P (elt))
508         MWARNING (MERROR_FONT);
509       registry = mfont__set_spec_from_plist (&encoding->spec,
510                                              MPLIST_PLIST (elt));
511       elt = MPLIST_NEXT (elt);
512       if (! MPLIST_SYMBOL_P (elt))
513         MWARNING (MERROR_FONT);
514       encoding->encoding_name = MPLIST_SYMBOL (elt);
515       elt = MPLIST_NEXT (elt);
516       if (MPLIST_TAIL_P (elt))
517         encoding->repertory_name = encoding->encoding_name;
518       else if (! MPLIST_SYMBOL_P (elt))
519         MWARNING (MERROR_FONT);
520       else
521         encoding->repertory_name = MPLIST_SYMBOL (elt);
522
523       if (registry == Mnil)
524         mplist_push (font_encoding_list, Mt, encoding);
525       else
526         pl = mplist_add (pl, registry, encoding);
527       continue;
528
529     warning:
530       free (encoding);
531     }
532
533   M17N_OBJECT_UNREF (encoding_list);
534   return 0;
535 }
536
537 typedef struct {
538   MFont spec;
539   int resize;
540 } MFontResize;
541
542 static MPlist *font_resize_list;
543
544 /** Load font size table from the data <font size>.
545     The data has this form:
546         (FONT-SPEC RESIZE-FACTOR) ...
547     where FONT-SPEC has this form:
548         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
549     All elements of FONT-SPEC are symbols.  */
550
551 static int
552 load_font_resize_table ()
553 {
554   MDatabase *mdb;
555   MPlist *size_adjust_list, *plist, *pl, *elt;
556
557   font_resize_list = pl = mplist ();
558
559   mdb = mdatabase_find (Mfont, msymbol ("resize"), Mnil, Mnil);
560   if (! mdb)
561     return -1;
562   if (! (size_adjust_list = (MPlist *) mdatabase_load (mdb)))
563     MERROR (MERROR_FONT, -1);
564
565   MPLIST_DO (plist, size_adjust_list)
566     {
567       MFontResize *resize;
568       MSymbol registry;
569
570       MSTRUCT_CALLOC (resize, MERROR_FONT);
571
572       if (! MPLIST_PLIST_P (plist)
573           || (elt = MPLIST_PLIST (plist), mplist_length (elt) != 2)
574           || ! MPLIST_PLIST_P (elt))
575         MWARNING (MERROR_FONT);
576       registry = mfont__set_spec_from_plist (&resize->spec,
577                                              MPLIST_PLIST (elt));
578       elt = MPLIST_NEXT (elt);
579       if (! MPLIST_INTEGER_P (elt))
580         MWARNING (MERROR_FONT);
581       resize->resize = MPLIST_INTEGER (elt);
582
583       if (registry == Mnil)
584         registry = Mt;
585       pl = mplist_add (pl, registry, resize);
586       continue;
587
588     warning:
589       free (resize);
590     }
591
592   M17N_OBJECT_UNREF (size_adjust_list);
593   return 0;
594 }
595
596 /** Return a font encoding (and repertory) of FONT.  */
597
598 static MFontEncoding *
599 find_encoding (MFont *font)
600 {
601   MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
602   MFontEncoding *encoding = NULL;
603   MPlist *plist;
604
605   if (! font_encoding_list)
606     load_font_encoding_table ();
607   plist = font_encoding_list;
608   while (! MPLIST_TAIL_P (plist))
609     {
610       encoding = (MFontEncoding *) MPLIST_VAL (plist);
611       if (mfont__match_p (font, &encoding->spec, MFONT_REGISTRY))
612         {
613           if (encoding->encoding_name != Mnil
614               && ! encoding->encoding_charset)
615             {
616               encoding->encoding_charset = MCHARSET (encoding->encoding_name);
617               if (! encoding->encoding_charset)
618                 {
619                   mplist_pop (plist);
620                   continue;
621                 }
622             }
623           if (encoding->repertory_name == encoding->encoding_name)
624             encoding->repertory_charset = encoding->encoding_charset;
625           else if (encoding->repertory_name != Mnil)
626             {
627               encoding->repertory_charset
628                 = MCHARSET (encoding->repertory_name);
629               if (! encoding->repertory_charset)
630                 {
631                   mplist_pop (plist);
632                   continue;
633                 }
634             }
635           font->encoding = encoding;
636           return encoding;
637         }
638
639       if (registry && MPLIST_KEY (plist) != Mt)
640         {
641           plist = mplist_find_by_key (plist, registry);
642           if (! plist)
643             break;
644         }
645       else
646         plist = MPLIST_NEXT (plist);
647     }
648   font->encoding = &default_encoding;
649   return &default_encoding;
650 }
651
652 #ifndef HAVE_OTF
653 static OTF_Tag
654 OTF_tag (char *name)
655 {
656   unsigned char *p = (unsigned char *) name;
657
658   if (! name)
659     return (OTF_Tag) 0;
660   return (OTF_Tag) ((p[0] << 24)
661                     | (! p[1] ? 0
662                        : ((p[1] << 16)
663                           | (! p[2] ? 0
664                              : (p[2] << 8) | p[3]))));
665 }
666 #endif /* not HAVE_OTF */
667
668 static MPlist *otf_script_list;
669
670 static int
671 load_otf_script_list ()
672 {
673   MDatabase *mdb;
674   MPlist *plist, *pl;
675
676   otf_script_list = mplist ();
677   mdb = mdatabase_find (msymbol ("standard"), Mscript, msymbol ("otf"), Mnil);
678   if (! mdb
679       || ! (plist = mdatabase_load (mdb)))
680     MERROR (MERROR_FONT, -1);
681   MPLIST_DO (pl, plist)
682     {
683       MPlist *p;
684       MSymbol script, otf_script;
685       OTF_Tag tag;
686
687       if (! MPLIST_PLIST_P (pl))
688         continue;
689       p = MPLIST_PLIST (pl);
690       if (! MPLIST_SYMBOL_P (p))
691         continue;
692       script = MPLIST_SYMBOL (p);
693       p = MPLIST_NEXT (p);
694       if (! MPLIST_SYMBOL_P (p))
695         continue;
696       otf_script = MPLIST_SYMBOL (p);
697       tag = OTF_tag (MSYMBOL_NAME (otf_script));
698       mplist_push (otf_script_list, script, (void *) tag);
699     }
700   M17N_OBJECT_UNREF (plist);
701   return 0;
702 }
703
704 static MSymbol
705 find_script_from_otf_tag (OTF_Tag tag)
706 {
707   MPlist *plist;
708
709   if (! otf_script_list)
710     load_otf_script_list ();
711   plist = mplist_find_by_value (otf_script_list, (void *) tag);
712   return (plist ? MPLIST_KEY (plist) : Mnil);
713 }
714
715
716 /* XLFD parser/generator */
717
718 /** Indices to each field of split font name.  */
719
720 enum xlfd_field_idx
721   {
722     XLFD_FOUNDRY,
723     XLFD_FAMILY,
724     XLFD_WEIGHT,
725     XLFD_SLANT,
726     XLFD_SWIDTH,
727     XLFD_ADSTYLE,
728     XLFD_PIXEL,
729     XLFD_POINT,
730     XLFD_RESX,
731     XLFD_RESY,
732     XLFD_SPACING,
733     XLFD_AVGWIDTH,
734     XLFD_REGISTRY,              /* This contains ENCODING.  */
735     /* anchor */
736     XLFD_FIELD_MAX
737   };
738
739 static int
740 xlfd_parse_name (const char *name, MFont *font)
741 {
742   char *field[XLFD_FIELD_MAX];
743   unsigned short resy, avgwidth;
744   unsigned size;
745   char copy[513];
746   int i;
747   char *p;
748
749   if (name[0] != '-')
750     return -1;
751
752   field[0] = copy;
753   for (i = 1, p = copy, name++; *name; p++, name++)
754     {
755       if (p - copy > 512)
756         return -1;
757       if (*name == '-'
758           && i < XLFD_FIELD_MAX)
759         {
760           *p = '\0';
761           if (field[i - 1][0] == '*')
762             field[i - 1] = NULL;
763           field[i++] = p + 1;
764         }
765       else
766         *p = tolower (*name);
767     }
768   *p = '\0';
769   if (field[i - 1][0] == '*')
770     field[i - 1] = NULL;
771   while (i < XLFD_FIELD_MAX)
772     field[i++] = NULL;
773
774   resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0;
775   avgwidth = ((field[XLFD_AVGWIDTH] && isdigit (field[XLFD_AVGWIDTH][0]))
776               ? atoi (field[XLFD_AVGWIDTH]) : 1);
777   if (! avgwidth)
778     size = 0;
779   else if (! field[XLFD_PIXEL])
780     size = field[XLFD_POINT] ? atoi (field[XLFD_POINT]) * resy / 72 : 0;
781   else if (field[XLFD_PIXEL][0] == '[')
782     {
783       /* The pixel size field specifies a transformation matrix of the
784          form "[A B C D]".  The XLFD spec says that the scalar value N
785          for the pixel size is equivalent to D.  */
786       char *p0 = field[XLFD_PIXEL] + 1, *p1;
787       double d;
788
789       for (i = 0; i < 4; i++, p0 = p1)
790         d = strtod (p0, &p1);
791       size = d * 10;
792     }
793   else
794     size = atoi (field[XLFD_PIXEL]) * 10;
795
796   if (field[XLFD_FOUNDRY])
797     mfont__set_property (font, MFONT_FOUNDRY, msymbol (field[XLFD_FOUNDRY]));
798   if (field[XLFD_FAMILY])
799     mfont__set_property (font, MFONT_FAMILY, msymbol (field[XLFD_FAMILY]));
800   if (field[XLFD_WEIGHT])
801     mfont__set_property (font, MFONT_WEIGHT, msymbol (field[XLFD_WEIGHT]));
802   if (field[XLFD_SLANT])
803     mfont__set_property (font, MFONT_STYLE, msymbol (field[XLFD_SLANT]));
804   if (field[XLFD_SWIDTH])
805     mfont__set_property (font, MFONT_STRETCH, msymbol (field[XLFD_SWIDTH]));
806   if (field[XLFD_ADSTYLE])
807     mfont__set_property (font, MFONT_ADSTYLE, msymbol (field[XLFD_ADSTYLE]));
808   font->property[MFONT_RESY] = resy;
809   font->size = size;
810   if (field[XLFD_SPACING])
811     font->spacing
812       = ((field[XLFD_SPACING][0] == 'p' || field[XLFD_SPACING][0] == 'P')
813          ? MFONT_SPACING_PROPORTIONAL
814          : (field[XLFD_SPACING][0] == 'm' || field[XLFD_SPACING][0] == 'M')
815          ? MFONT_SPACING_MONO : MFONT_SPACING_CHARCELL);
816   if (field[XLFD_REGISTRY])
817     mfont__set_property (font, MFONT_REGISTRY, msymbol (field[XLFD_REGISTRY]));
818   font->type = MFONT_TYPE_SPEC;
819   font->source = MFONT_SOURCE_X;
820   return 0;
821 }
822
823 static char *
824 xlfd_unparse_name (MFont *font)
825 {
826   MSymbol prop[7];
827   char name[513];
828   char *str[7];
829   int len, i;
830   char spacing;
831   unsigned short size, resy;
832
833   prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
834   prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
835   prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
836   prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
837   prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
838   prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
839   prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
840   for (len = 0, i = 0; i < 7; i++)
841     {
842       if (prop[i] != Mnil)
843         {
844           str[i] = msymbol_name (prop[i]);
845           len += strlen (str[i]);
846         }
847       else
848         {
849           str[i] = "*";
850           len++;
851         }
852     }
853   spacing = (font->spacing == MFONT_SPACING_UNDECIDED ? '*'
854              : font->spacing == MFONT_SPACING_PROPORTIONAL ? 'p'
855              : font->spacing == MFONT_SPACING_MONO ? 'm'
856              : 'c');
857
858   if ((len
859        + 13                     /* 13 dashes */
860        + 2                      /* 2 asterisks */
861        + 30                     /* 3 integers (each 10 digits) */
862        + 1                      /* 1 spacing char */
863        + 1)                     /* '\0' terminal */
864       > 513)
865     return NULL;
866
867   resy = (int) mfont_get_prop (font, Mresolution);
868   size = font->size;
869   if ((size % 10) < 5)
870     size /= 10;
871   else
872     size = size / 10 + 1;
873
874   sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-%c-*-%s",
875            str[0], str[1], str[2], str[3], str[4], str[5],
876            size, resy, resy, spacing, str[6]);
877   return strdup (name);
878 }
879
880 /* Compare FONT with REQUEST and return how much they differs.  */
881
882 static int
883 font_score (MFont *font, MFont *request)
884 {
885   int score = 0;
886   int i = FONT_SCORE_PRIORITY_SIZE;
887
888   while (--i >= 0)
889     {
890       enum MFontProperty prop = font_score_priority[i];
891       int val;
892
893       if (prop == MFONT_SIZE)
894         {
895           if (font->size && request->size)
896             {
897               val = font->size - request->size;
898               if (val)
899                 {
900                   if (val < 0)
901                     val = - val;
902                   if (val >= 0x10000)
903                     val = 0xFFFF;
904                   score |= (val << font_score_shift_bits[MFONT_SIZE]);
905                 }
906             }
907         }
908       else if (font->property[prop] && request->property[prop]
909                && font->property[prop] != request->property[prop])
910         {
911           if (prop <= MFONT_FAMILY)
912             val = 1;
913           else if (prop == MFONT_WEIGHT)
914             {
915               unsigned short v1 = font->property[prop];
916               unsigned short v2 = request->property[prop];
917
918               if (v1 == font_weight_regular || v1 == font_weight_normal)
919                 v1 = font_weight_medium;
920               if (v2 == font_weight_regular || v2 == font_weight_normal)
921                 v2 = font_weight_medium;
922               val = v1 > v2 ? v1 - v2 : v2 - v1;
923             }
924           else
925             {
926               val = font->property[prop] - request->property[prop];
927               if (val < 0)
928                 val = - val;
929               if (val > 3)
930                 val = 3;
931             }
932           score |= val << font_score_shift_bits[prop];
933         }
934     }
935   if (request->file != Mnil && request->file != font->file)
936     score |= 40000000;
937   return score;
938 }
939
940 \f
941 /* Internal API */
942
943 MSymbol Miso8859_1, Miso10646_1, Municode_bmp, Municode_full, Mapple_roman;
944
945 int
946 mfont__init ()
947 {
948   int i, shift;
949   MSymbol regular = msymbol ("regular");
950   MSymbol normal = msymbol ("normal");
951   MSymbol medium = msymbol ("medium");
952
953   M_font_capability = msymbol_as_managing_key ("  font-capability");
954   M_font_list = msymbol_as_managing_key ("  font-list");
955   M_font_list_len = msymbol ("  font-list-len");
956
957   Mfoundry = msymbol ("foundry");
958   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
959   Mfamily = msymbol ("family");
960   mfont__property_table[MFONT_FAMILY].property = Mfamily;
961   Mweight = msymbol ("weight");
962   mfont__property_table[MFONT_WEIGHT].property = Mweight;
963   Mstyle = msymbol ("style");
964   mfont__property_table[MFONT_STYLE].property = Mstyle;
965   Mstretch = msymbol ("stretch");
966   mfont__property_table[MFONT_STRETCH].property = Mstretch;
967   Madstyle = msymbol ("adstyle");
968   mfont__property_table[MFONT_ADSTYLE].property = Madstyle;
969   Mregistry = msymbol ("registry");
970   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
971
972   Mspacing = msymbol ("spacing");
973   Msize = msymbol ("size");
974   Mresolution = msymbol ("resolution");
975   Mascent = msymbol ("ascent");
976   Mdescent = msymbol ("descent");
977   Mmax_advance = msymbol ("max-advance");
978   Mfontfile = msymbol ("fontfile");
979
980   Mfontconfig = msymbol ("fontconfig");
981
982   Mx = msymbol ("x");
983   Mfreetype = msymbol ("freetype");
984   Mxft = msymbol ("xft");
985
986   Miso8859_1 = msymbol ("iso8859-1");
987   Miso10646_1 = msymbol ("iso10646-1");
988   Municode_bmp = msymbol ("unicode-bmp");
989   Municode_full = msymbol ("unicode-full");
990   Mapple_roman = msymbol ("apple-roman");
991
992   /* The first entry of each mfont__property_table must be Mnil so
993      that actual properties get positive numeric numbers.  */
994   for (i = 0; i <= MFONT_REGISTRY; i++)
995     {
996       MLIST_INIT1 (&mfont__property_table[i], names, 8);
997       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
998     }
999
1000   /* Register predefined font property names.  */
1001   for (i = 0; i <= MFONT_REGISTRY; i++)
1002     {
1003       int j;
1004
1005       for (j = 0; j < font_common_names[i].num; j++)
1006         {
1007           MSymbol sym = msymbol (font_common_names[i].names[j]);
1008
1009           if (sym == Mnil)
1010             return -1;
1011           if (msymbol_put (sym, mfont__property_table[i].property,
1012                            (void *) (j + 1)) < 0)
1013             return -1;
1014           MLIST_APPEND1 (&mfont__property_table[i], names, sym,
1015                          MERROR_FONT);
1016           if (i == MFONT_WEIGHT)
1017             {
1018               if (sym == regular)
1019                 font_weight_regular = j + 1;
1020               else if (sym == normal)
1021                 font_weight_normal = j + 1;
1022               else if (sym == medium)
1023                 font_weight_medium = j + 1;
1024             }
1025         }
1026     }
1027
1028   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
1029      of a score is a flag for a scalable font (see the documentation
1030      of font_score).  */
1031   i = FONT_SCORE_PRIORITY_SIZE - 1;
1032   for (shift = 1; i >= 0; i--)
1033     {
1034       font_score_shift_bits[font_score_priority[i]] = shift;
1035       if (font_score_priority[i] == MFONT_SIZE)
1036         shift += 16;
1037       else if (font_score_priority[i] <= MFONT_FAMILY)
1038         shift++;
1039       else
1040         shift += 2;
1041     }
1042
1043   MFONT_INIT (&default_encoding.spec);
1044   default_encoding.encoding_name = Municode_full;
1045   default_encoding.encoding_charset = mcharset__unicode;
1046   default_encoding.repertory_name = Mnil;
1047   default_encoding.repertory_charset = NULL;
1048   {
1049     char *path, *buf;
1050     int bufsize;
1051     USE_SAFE_ALLOCA;
1052
1053     mfont_freetype_path = mplist ();
1054     bufsize = strlen (M17NDIR) + 7;
1055     SAFE_ALLOCA (buf, bufsize);
1056     sprintf (buf, "%s/fonts", M17NDIR);
1057     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
1058     path = getenv ("M17NDIR");
1059     if (path)
1060       {
1061         bufsize = strlen (path) + 7;
1062         SAFE_ALLOCA (buf, bufsize);
1063         sprintf (buf, "%s/fonts", path);
1064         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
1065       }
1066     SAFE_FREE (buf);
1067   }
1068
1069 #ifdef HAVE_FREETYPE
1070   if (mfont__ft_init () < 0)
1071     return -1;
1072 #endif /* HAVE_FREETYPE */
1073   if (mfont__flt_init () < 0)
1074     return -1;
1075
1076   return 0;
1077 }
1078
1079 void
1080 mfont__fini ()
1081 {
1082   MPlist *plist;
1083   int i;
1084
1085   mfont__flt_fini ();
1086 #ifdef HAVE_FREETYPE
1087   mfont__ft_fini ();
1088 #endif /* HAVE_FREETYPE */
1089
1090   MPLIST_DO (plist, mfont_freetype_path)
1091     free (MPLIST_VAL (plist));
1092   M17N_OBJECT_UNREF (mfont_freetype_path);
1093
1094   if (font_resize_list)
1095     {
1096       MPLIST_DO (plist, font_resize_list)
1097         free (MPLIST_VAL (plist));
1098       M17N_OBJECT_UNREF (font_resize_list);
1099       font_resize_list = NULL;
1100     }
1101   if (font_encoding_list)
1102     {
1103       MPLIST_DO (plist, font_encoding_list)
1104         free (MPLIST_VAL (plist));
1105       M17N_OBJECT_UNREF (font_encoding_list);
1106       font_encoding_list = NULL;
1107     }
1108   if (otf_script_list)
1109     {
1110       M17N_OBJECT_UNREF (otf_script_list);
1111       otf_script_list = NULL;
1112     }
1113
1114   for (i = 0; i <= MFONT_REGISTRY; i++)
1115     MLIST_FREE1 (&mfont__property_table[i], names);
1116 }
1117
1118
1119 MSymbol
1120 mfont__id (MFont *font)
1121 {
1122   char *buf, *p;
1123   int i;
1124   int file_len = (font->file == Mnil ? 0 : MSYMBOL_NAMELEN (font->file));
1125   int capability_len  = (font->capability == Mnil ? 0
1126                          : MSYMBOL_NAMELEN (font->capability));
1127   int total_len = MFONT_PROPERTY_MAX * 5 + 9 + file_len + capability_len;
1128   MSymbol id;
1129   USE_SAFE_ALLOCA;
1130
1131   SAFE_ALLOCA (buf, total_len);
1132   p = buf;
1133   if (font->property[0])
1134     p += sprintf (p, "%X", font->property[0]);
1135   for (i = 1; i < MFONT_PROPERTY_MAX; i++)
1136     {
1137       if (font->property[i])
1138         p += sprintf (p, "-%X", font->property[i]);
1139       else
1140         *p++ = '-';
1141     }
1142   if (font->size)
1143     p += sprintf (p, "-%X", font->size);
1144   if (font->spacing)
1145     p += sprintf (p, "-%X", font->spacing);
1146   if (capability_len > 0)
1147     {
1148       *p++ = '-';
1149       memcpy (p, MSYMBOL_NAME (font->capability), capability_len);
1150       p += capability_len;
1151     }
1152   if (file_len > 0)
1153     {
1154       *p++ = '-';
1155       memcpy (p, MSYMBOL_NAME (font->file), file_len);
1156       p += file_len;
1157     }      
1158   id = msymbol__with_len (buf, p - buf);
1159   SAFE_FREE (buf);
1160   return id;
1161 }
1162
1163 /** Return 1 iff FONT matches SPEC.  */
1164
1165 int
1166 mfont__match_p (MFont *font, MFont *spec, int prop)
1167 {
1168   if (spec->capability != font->capability
1169       && spec->capability != Mnil && font->capability != Mnil)
1170     return 0;
1171   if (spec->file != font->file
1172       && spec->file != Mnil && font->file != Mnil)
1173     return 0;
1174   for (; prop >= 0; prop--)
1175     if (spec->property[prop] && font->property[prop]
1176         && font->property[prop] != spec->property[prop])
1177       return 0;
1178   return 1;
1179 }
1180
1181 /* Merge SRC into DST.  If error_on_conflict is nonzero and a font
1182    property differs in SRC and DST, return -1.  */
1183
1184 int
1185 mfont__merge (MFont *dst, MFont *src, int error_on_conflict)
1186 {
1187   int i;
1188
1189   for (i = 0; i < MFONT_PROPERTY_MAX; i++)
1190     {
1191       if (! dst->property[i])
1192         dst->property[i] = src->property[i];
1193       else if (error_on_conflict
1194                && src->property[i]
1195                && dst->property[i] != src->property[i])
1196         return -1;
1197     }
1198   if (! dst->spacing)
1199     dst->spacing = src->spacing;
1200   else if (error_on_conflict
1201            && src->spacing
1202            && dst->spacing != src->spacing)
1203     return -1;
1204   if (! dst->size)
1205     dst->size = src->size;
1206   else if (error_on_conflict
1207            && src->size
1208            && dst->size != src->size)
1209     return -1;
1210   if (dst->capability == Mnil)
1211     dst->capability = src->capability;
1212   else if (error_on_conflict
1213            && src->capability
1214            && dst->capability != src->capability)
1215     return -1;
1216   if (dst->file == Mnil)
1217     dst->file = src->file;
1218   else if (error_on_conflict
1219            && src->file
1220            && dst->file != src->file)
1221     return -1;
1222   return 0;
1223 }
1224
1225 void
1226 mfont__set_spec_from_face (MFont *spec, MFace *face)
1227 {
1228   int i;
1229
1230   for (i = 0; i <= MFONT_ADSTYLE; i++)
1231     mfont__set_property (spec, i, face->property[i]);
1232   spec->property[MFONT_REGISTRY] = 0;
1233   spec->property[MFONT_RESY] = 0;
1234   spec->size = (int) (face->property[MFACE_SIZE]);
1235   spec->type = MFONT_TYPE_SPEC;
1236   spec->source = MFONT_SOURCE_UNDECIDED;
1237   spec->file = spec->capability = Mnil;
1238   spec->encoding = NULL;
1239 }
1240
1241
1242 extern MSymbol
1243 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
1244 {
1245   int i;
1246   MSymbol spec_list[MFONT_REGISTRY + 1];
1247   MSymbol registry;
1248   char *reg;
1249
1250   MFONT_INIT (spec);
1251   memset (spec_list, 0, sizeof spec_list);
1252   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
1253     {
1254       if (! MPLIST_SYMBOL_P (plist))
1255         MERROR (MERROR_FONT, Mnil);     
1256       spec_list[i] = MPLIST_SYMBOL (plist);
1257     }
1258   registry = spec_list[i - 1];
1259   if (i > 1 && registry != Mnil)
1260     {
1261       reg = MSYMBOL_NAME (registry);
1262       if (reg[0] == ':')
1263         {
1264           mfont__get_capability (registry);
1265           spec->capability = registry;
1266           registry = spec_list[i - 2];
1267           i--;
1268         }
1269     }
1270   mfont__set_property (spec, MFONT_REGISTRY, registry);
1271   for (i -= 2; i >= 0; i--)
1272     mfont__set_property (spec, i, spec_list[i]);
1273   spec->type = MFONT_TYPE_SPEC;
1274
1275   return registry;
1276 }
1277
1278
1279 MFont *
1280 mfont__select (MFrame *frame, MFont *font, int max_size)
1281 {
1282   MFontDriver *driver;
1283
1284   if (font->type == MFONT_TYPE_FAILURE)
1285     return NULL;
1286   if (font->type != MFONT_TYPE_SPEC)
1287     return font;
1288   if (font->source == MFONT_SOURCE_UNDECIDED)
1289     {
1290       if (font->file != Mnil || font->capability != Mnil)
1291         font->source = MFONT_SOURCE_FT;
1292       else if (font->property[MFONT_REGISTRY])
1293         {
1294           MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
1295           char *reg = MSYMBOL_NAME (registry);
1296
1297           if (strncmp (reg, "unicode-", 8) == 0
1298               || strncmp (reg, "apple-roman", 11) == 0
1299               || (reg[0] >= '0' && reg[0] <= '9' && reg[1] == '-'))
1300             font->source = MFONT_SOURCE_FT;
1301         }
1302     }
1303   if (font->source != MFONT_SOURCE_FT)
1304     {
1305       driver = mplist_get (frame->font_driver_list, Mx);
1306       if (driver)
1307         return (driver->select) (frame, font, max_size);
1308     }
1309   driver = mplist_get (frame->font_driver_list, Mfreetype);
1310   if (! driver)
1311     return NULL;
1312   return (driver->select) (frame, font, max_size);
1313 }
1314
1315
1316 int
1317 mfont__available (MFrame *frame, MFont *font)
1318 {
1319   return -1;
1320 }
1321
1322 static int
1323 compare_font_score (const void *e1, const void *e2)
1324 {
1325   return (((MFontScore *) e1)->score > ((MFontScore *) e2)->score);
1326 }
1327
1328 void
1329 mdebug_dump_font_list (MFontList *font_list)
1330 {
1331   int i;
1332
1333   for (i = 0; i < font_list->nfonts; i++)
1334     {
1335       fprintf (stderr, "%04X - ", font_list->fonts[i].score);
1336       mdebug_dump_font (font_list->fonts[i].font);
1337       fprintf (stderr, "\n");
1338     }
1339 }
1340
1341 void
1342 mfont__free_realized (MRealizedFont *rfont)
1343 {
1344   MRealizedFont *next;
1345
1346   for (; rfont; rfont = next)
1347     {
1348       next = rfont->next;
1349       M17N_OBJECT_UNREF (rfont->info);
1350       free (rfont);
1351       rfont = next;
1352     }
1353 }
1354
1355 MFontList *
1356 mfont__list (MFrame *frame, MFont *spec, MFont *request, int max_size)
1357 {
1358   MFontList *list;
1359   MSymbol id = mfont__id (spec);
1360   MPlist *pl, *p;
1361   int num, i;
1362
1363   pl = msymbol_get (id, M_font_list);
1364   if (pl)
1365     num = (int) msymbol_get (id, M_font_list_len);
1366   else
1367     {
1368       pl = mplist ();
1369       num = 0;
1370       MPLIST_DO (p, frame->font_driver_list)
1371         {
1372           if (spec->source == MFONT_SOURCE_X ? MPLIST_KEY (p) == Mx
1373               : spec->source == MFONT_SOURCE_FT ? MPLIST_KEY (p) == Mfreetype
1374               : 1)
1375             {
1376               MFontDriver *driver = MPLIST_VAL (p);
1377               num += (driver->list) (frame, pl, spec, 0);
1378             }
1379         }
1380       msymbol_put (id, M_font_list, pl);
1381       M17N_OBJECT_UNREF (pl);
1382       msymbol_put (id, M_font_list_len, (void *) num);
1383     }
1384   
1385   if (num == 0)
1386     return NULL;
1387
1388   MSTRUCT_MALLOC (list, MERROR_FONT);
1389   MTABLE_MALLOC (list->fonts, num, MERROR_FONT);
1390   for (i = 0; num > 0; num--, pl = MPLIST_NEXT (pl))
1391     {
1392       MFont *font = MPLIST_VAL (pl);
1393
1394       if (max_size == 0
1395           || font->size == 0
1396           || font->size < max_size)
1397         {
1398           list->fonts[i].font = font;
1399           list->fonts[i].score
1400             = spec == request ? 0 : font_score (font, request);
1401           i++;
1402         }
1403     }
1404   if (i == 0)
1405     {
1406       free (list->fonts);
1407       free (list);
1408       return NULL;
1409     }
1410   list->nfonts = i;
1411   if (spec != request)
1412     qsort (list->fonts, i, sizeof (MFontScore), compare_font_score);
1413   list->object = *spec;
1414   mfont__merge (&list->object, request, 0);
1415   list->object.type = MFONT_TYPE_OBJECT;
1416   return list;
1417 }
1418
1419 /** Open a font specified in FONT.  */
1420
1421 MRealizedFont *
1422 mfont__open (MFrame *frame, MFont *font, MFont *spec)
1423 {
1424   MFontDriver *driver;
1425   MRealizedFont *rfont;
1426
1427   if (font->source == MFONT_SOURCE_UNDECIDED)
1428     MFATAL (MERROR_FONT);
1429   if (font->type != MFONT_TYPE_OBJECT)
1430     MFATAL (MERROR_FONT);
1431   for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
1432        rfont = rfont->next)
1433     {
1434       driver = rfont->driver;
1435       if (rfont->font == font
1436           && mplist_find_by_value (frame->font_driver_list, driver))
1437         break;
1438     }
1439
1440   if (! rfont)
1441     {
1442       driver = mplist_get (frame->font_driver_list,
1443                            font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
1444       if (! driver)
1445         MFATAL (MERROR_FONT);
1446     }
1447   return (driver->open) (frame, font, spec, rfont);
1448 }
1449
1450 void
1451 mfont__resize (MFont *spec, MFont *request)
1452 {
1453   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1454   MFontResize *resize;
1455   MPlist *plist;
1456
1457   if (! font_resize_list)
1458     load_font_resize_table ();
1459   if (! MPLIST_TAIL_P (font_resize_list))
1460     while (1)
1461       {
1462         plist = font_resize_list;
1463         while (registry ? (plist = mplist_find_by_key (plist, registry))
1464                : plist)
1465           {
1466             resize = (MFontResize *) MPLIST_VAL (plist);
1467             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1468               {
1469                 request->size = request->size * resize->resize / 100;
1470                 return;
1471               }
1472             plist = MPLIST_NEXT (plist);
1473           }
1474         if (registry == Mt)
1475           break;
1476         registry = Mt;
1477       }
1478 }
1479
1480
1481 int
1482 mfont__has_char (MFrame *frame, MFont *font, MFont *spec, int c)
1483 {
1484   MFontEncoding *encoding;
1485   unsigned code;
1486   MFontDriver *driver;
1487
1488   if (font->source == MFONT_SOURCE_UNDECIDED)
1489     MFATAL (MERROR_FONT);
1490   encoding = (font->encoding ? font->encoding : find_encoding (font));
1491   if (! encoding->encoding_charset)
1492     return 0;
1493   if (encoding->repertory_charset)
1494     {
1495       code = ENCODE_CHAR (encoding->repertory_charset, c);
1496       return (code != MCHAR_INVALID_CODE);
1497     }
1498   code = ENCODE_CHAR (encoding->encoding_charset, c);
1499   if (code == MCHAR_INVALID_CODE)
1500     return 0;
1501   if (font->type == MFONT_TYPE_REALIZED)
1502     driver = ((MRealizedFont *) font)->driver;
1503   else
1504     {
1505       driver = mplist_get (frame->font_driver_list,
1506                            font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
1507       if (! driver)
1508         MFATAL (MERROR_FONT);
1509     }
1510   return (driver->has_char) (frame, font, spec, c, code);
1511 }
1512
1513 unsigned
1514 mfont__encode_char (MFrame *frame, MFont *font, MFont *spec, int c)
1515 {
1516   MFontEncoding *encoding;
1517   unsigned code;
1518   MFontDriver *driver;
1519
1520   if (font->source == MFONT_SOURCE_UNDECIDED)
1521     MFATAL (MERROR_FONT);
1522   encoding = (font->encoding ? font->encoding : find_encoding (font));
1523   if (! encoding->encoding_charset)
1524     return MCHAR_INVALID_CODE;
1525   if (encoding->repertory_charset)
1526     return (ENCODE_CHAR (encoding->repertory_charset, c));
1527   code = ENCODE_CHAR (encoding->encoding_charset, c);
1528   if (code == MCHAR_INVALID_CODE)
1529     return MCHAR_INVALID_CODE;
1530   if (font->type == MFONT_TYPE_REALIZED)
1531     driver = ((MRealizedFont *) font)->driver;
1532   else
1533     {
1534       driver = mplist_get (frame->font_driver_list,
1535                            font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
1536       if (! driver)
1537         MFATAL (MERROR_FONT);
1538     }
1539   return (driver->encode_char) (frame, font, spec, code);
1540 }
1541
1542 void
1543 mfont__get_metric (MGlyphString *gstring, int from, int to)
1544 {
1545   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1546   MRealizedFont *rfont = from_g->rface->rfont;
1547
1548   for (g = from_g; g != to_g; g++)
1549     if (g->rface->rfont != rfont)
1550       {
1551         int idx = GLYPH_INDEX (g);
1552
1553         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1554         from_g = g;
1555         rfont = g->rface->rfont;
1556         from = idx;
1557       }
1558   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1559 }
1560
1561
1562 /* KEY <= MFONT_REGISTRY */
1563
1564 void
1565 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1566 {
1567   int numeric;
1568
1569   if (val == Mnil)
1570     numeric = 0;
1571   else
1572     {
1573       numeric = FONT_PROPERTY_NUMERIC (val, key);
1574       if (! numeric)
1575         {
1576           numeric = mfont__property_table[key].used;
1577           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1578           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1579         }
1580     }
1581   font->property[key] = numeric;
1582 }
1583
1584 int
1585 mfont__parse_name_into_font (const char *name, MSymbol format, MFont *font)
1586 {
1587   int result = -1;
1588
1589   if (format == Mx || format == Mnil)
1590     result = xlfd_parse_name (name, font);
1591 #ifdef HAVE_FONTCONFIG
1592   if (format == Mfontconfig || (result < 0 && format == Mnil))
1593     result = mfont__ft_parse_name (name, font);
1594 #endif /* HAVE_FONTCONFIG */
1595   return result;
1596 }
1597
1598 MPlist *
1599 mfont__encoding_list (void)
1600 {
1601   if (! font_encoding_list)
1602     load_font_encoding_table ();
1603   return font_encoding_list;
1604 }
1605
1606 static void
1607 free_font_capability (void *object)
1608 {
1609   MFontCapability *cap = object;
1610   int i;
1611   
1612   if (cap->lang)
1613     free (cap->lang);
1614 #ifdef HAVE_OTF
1615   if (cap->script)
1616     for (i = 0; i < MFONT_OTT_MAX; i++)
1617       {
1618         if (cap->features[i].str)
1619           free (cap->features[i].str);
1620         if (cap->features[i].tags)
1621           free (cap->features[i].tags);
1622       }
1623 #endif /* HAVE_OTF */
1624   free (cap);
1625 }
1626
1627 MFontCapability *
1628 mfont__get_capability (MSymbol sym)
1629 {
1630   MFontCapability *cap = msymbol_get (sym, M_font_capability);
1631   char *str, *p, *endp;
1632   int i;
1633
1634   if (cap)
1635     return cap;
1636   str = MSYMBOL_NAME (sym);
1637   if (str[0] != ':')
1638     return NULL;
1639   M17N_OBJECT (cap, free_font_capability, MERROR_FONT);
1640   msymbol_put (sym, M_font_capability, cap);
1641   M17N_OBJECT_UNREF (cap);
1642   endp = str + MSYMBOL_NAMELEN (sym);
1643   while (str < endp)
1644     {
1645       if (*str++ != ':')
1646         continue;
1647 #ifdef HAVE_OTF
1648       if (str[0] == 'o' && str[1] == 't' && str[2] == 'f' && str[3] == '=')
1649         {
1650           str += 4;
1651           for (i = 0, p = str; i < 4 && p < endp; i++, p++);
1652           if (i < 4)
1653             break;
1654           cap->script_tag = OTF_tag (str);
1655           cap->script = find_script_from_otf_tag (cap->script_tag);
1656           if (*p == '/')
1657             {
1658               for (i = 0, str = ++p; i < 4 && p < endp; i++, p++);
1659               if (i < 4)
1660                 {
1661                   cap->script = Mnil;
1662                   break;
1663                 }
1664               cap->langsys_tag = OTF_tag (str);
1665             }
1666           else
1667             cap->langsys_tag = 0;
1668
1669           for (i = 0; i < MFONT_OTT_MAX; i++)
1670             cap->features[i].nfeatures = -1;
1671
1672           while (*p == '=' || *p == '+')
1673             {
1674               int idx = *p == '=' ? MFONT_OTT_GSUB : MFONT_OTT_GPOS;
1675
1676               str = ++p;
1677               while (p < endp && *p != '+') p++;
1678               if (str < p)
1679                 {
1680                   int n;
1681                   /* We never have more than (p - str) tags.  */
1682                   OTF_Tag *tags = alloca (sizeof (OTF_Tag) * (p - str));
1683                   char *p0;
1684
1685                   cap->features[idx].str = malloc (p - str + 1);
1686                   for (i = n = 0, p0 = str; str + i < p; i++)
1687                     {
1688                       cap->features[idx].str[i] = str[i];
1689                       if (str[i] == ',' || str + i + 1 == p)
1690                         {
1691                           if (*p0 == '*')
1692                             tags[n] = 0;
1693                           else if (*p0 == '~')
1694                             tags[n] = OTF_tag (p0 + 1) | 0x80000000;
1695                           else
1696                             tags[n] = OTF_tag (p0);
1697                           n++;
1698                           p0 = str + i + 1;
1699                         }
1700                     }
1701                   cap->features[idx].str[i] = '\0';
1702                   cap->features[idx].nfeatures = n;
1703                   if (n > 0)
1704                     {
1705                       int size = sizeof (OTF_Tag) * n;
1706
1707                       cap->features[idx].tags = malloc (size);
1708                       memcpy (cap->features[idx].tags, tags, size);
1709                     }
1710                 }
1711               else
1712                 {
1713                   cap->features[idx].str = NULL;
1714                   cap->features[idx].nfeatures = 0;
1715                 }
1716             }
1717
1718           for (i = 0; i < MFONT_OTT_MAX; i++)
1719             if (cap->features[i].nfeatures < 0)
1720               {
1721                 cap->features[i].str = strdup ("*");
1722                 cap->features[i].nfeatures = 1;
1723                 cap->features[i].tags = malloc (sizeof (OTF_Tag));
1724                 cap->features[i].tags[0] = 0;
1725               }
1726           str = p;
1727           continue;
1728         }
1729 #endif /* HAVE_OTF */
1730       if (str[0] == 'l' && str[1] == 'a' && str[2] == 'n' && str[3] == 'g'
1731           && str[4] == '=')
1732         {
1733           int count;
1734
1735           str += 5;
1736           for (p = str, count = 2; p < endp && *p != ':'; p++)
1737             if (*p == ',')
1738               count++;
1739           MTABLE_MALLOC (cap->lang, count, MERROR_FONT);
1740           for (p = str, count = 0; p < endp && *p != ':'; p++)
1741             if (*p == ',')
1742               {
1743                 MSymbol lang = msymbol__with_len (str, p - str), sym;
1744
1745                 if (msymbol_get (lang, Miso639_2))
1746                   cap->lang[count++] = lang;
1747                 else if ((sym = msymbol_get (lang, Miso639_1)) != Mnil)
1748                   cap->lang[count++] = sym;
1749                 else if (msymbol_get (lang, Mlanguage))
1750                   cap->lang[count++] = lang;
1751                 str = p + 1;
1752               }
1753           if (str < p)
1754             cap->lang[count++] = msymbol__with_len (str, p - str);
1755           cap->lang[count] = Mnil;
1756           str = p;
1757         }
1758       else if (str[0] == 's' && str[1] == 'c' && str[2] == 'r' && str[3] == 'i'
1759                && str[4] == 'p' && str[5] == 't' && str[6] == '=')
1760         {
1761           str += 7;
1762           for (p = str; p < endp && *p != ':'; p++);
1763           if (str < p)
1764             cap->script = msymbol__with_len (str, p - str);
1765           str = p;
1766         }
1767     }
1768   return cap;
1769 }
1770
1771 /*** @} */
1772 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1773
1774 \f
1775
1776 /* External API */
1777
1778 /*** @addtogroup m17nFont */
1779 /*** @{ */
1780 /*=*/
1781
1782 /***en @name Variables: Keys of font property.  */
1783 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1784 /*** @{ */
1785 /*=*/
1786
1787 /***en
1788     @brief Key of font property specifying foundry.
1789
1790     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1791     is used as a key of font property and face property.  The property
1792     value must be a symbol whose name is a foundry name of a font.  */
1793 /***ja
1794     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1795     
1796     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> 
1797     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1798     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1799
1800 MSymbol Mfoundry;
1801
1802 /***en
1803     @brief Key of font property specifying family.
1804
1805     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1806     used as a key of font property and face property.  The property
1807     value must be a symbol whose name is a family name of a font.  */ 
1808 /***ja
1809     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1810     
1811     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> 
1812     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1813     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1814
1815 MSymbol Mfamily;
1816
1817 /***en
1818     @brief Key of font property specifying weight.
1819
1820     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1821     used as a key of font property and face property.  The property
1822     value must be a symbol whose name is a weight name of a font (e.g
1823     "medium", "bold").  */ 
1824 /***ja
1825     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1826     
1827     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> 
1828     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1829     Ãͤϡ¢¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1830
1831 MSymbol Mweight;
1832
1833 /***en
1834     @brief Key of font property specifying style.
1835
1836     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1837     used as a key of font property and face property.  The property
1838     value must be a symbol whose name is a style name of a font (e.g
1839     "r", "i", "o").  */ 
1840 /***ja
1841     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1842     
1843     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> 
1844     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1845     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1846
1847 MSymbol Mstyle;
1848
1849 /***en
1850     @brief Key of font property specifying stretch.
1851
1852     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1853     is used as a key of font property and face property.  The property
1854     value must be a symbol whose name is a stretch name of a font (e.g
1855     "normal", "condensed").  */ 
1856 /***ja
1857     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1858     
1859     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> 
1860     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1861     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1862
1863 MSymbol Mstretch;
1864
1865 /***en
1866     @brief Key of font property specifying additional style.
1867
1868     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1869     is used as a key of font property and face property.  The property
1870     value must be a symbol whose name is an additional style name of a
1871     font (e.g "serif", "", "sans").  */ 
1872 /***ja
1873     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1874     
1875     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> 
1876     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1877     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1878
1879 MSymbol Madstyle;
1880
1881 /***en
1882     @brief Key of font property specifying spacing.
1883
1884     The variable #Madstyle is a symbol of name <tt>"spacing"</tt> and
1885     is used as a key of font property.  The property value must be a
1886     symbol whose name specifies the spacing of a font (e.g "p" for
1887     proportional, "m" for monospaced).  */ 
1888 /***ja
1889     @brief spacing ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1890     
1891     ÊÑ¿ô #Mspacing ¤Ï <tt>"spacing"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1892     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î spacing
1893     ÆÃÀ­¤ò¼¨¤¹Ì¾Á° ("p", "m" Åù)¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£  */
1894
1895 MSymbol Mspacing;
1896
1897 /***en
1898     @brief Key of font property specifying registry.
1899
1900     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1901     and is used as a key of font property.  The property value must be
1902     a symbol whose name is a registry name a font registry
1903     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1904 /***ja
1905     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1906     
1907     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> 
1908     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1909     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" 
1910     Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1911
1912 MSymbol Mregistry;
1913
1914 /***en
1915     @brief Key of font property specifying size.
1916
1917     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1918     used as a key of font property and face property.  The property
1919     value must be an integer specifying a font design size in the unit
1920     of 1/10 point (on 100 dpi display).  */ 
1921 /***ja
1922     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1923     
1924     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> 
1925     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1926     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 
1927     ¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
1928     */
1929
1930 MSymbol Msize;
1931
1932 /***en
1933     @brief Key of font property specifying file name.
1934
1935     The variable #Mfontfile is a symbol of name <tt>"fontfile"</tt>
1936     and is used as a key of font property.  The property value must be
1937     a symbol whose name is a font file name.  */ 
1938 /***ja
1939     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1940     
1941     ÊÑ¿ô #Mfontfile ¤Ï <tt>"fontfile"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1942     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤
1943     ¥ë̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¤È¤¹¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */
1944
1945 MSymbol Mfontfile;
1946
1947 /***en
1948     @brief Key of font property specifying resolution.
1949
1950     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1951     is used as a key of font property and face property.  The property
1952     value must be an integer to specifying a font resolution in the
1953     unit of dots per inch (dpi).  */ 
1954 /***ja
1955     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1956     
1957     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> 
1958     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1959     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£    */
1960
1961 MSymbol Mresolution;
1962
1963 /***en
1964     @brief Key of font property specifying ascent.
1965
1966     The variable #Mascent is a symbol of name <tt>"ascent"</tt> and is
1967     used as a key of font property.  The property value must be an
1968     integer specifying a font ascent value by pixels.  */ 
1969
1970 MSymbol Mascent;
1971
1972 /***en
1973     @brief Key of font property specifying descent.
1974
1975     The variable #Mdescent is a symbol of name <tt>"descent"</tt> and
1976     is used as a key of font property.  The property value must be an
1977     integer specifying a font's descent value by pixels.  */ 
1978
1979 MSymbol Mdescent;
1980
1981 /***en
1982     @brief Key of font property specifying max advance width.
1983
1984     The variable #Mmax_advance is a symbol of name
1985     <tt>"max-advance"</tt> and is used as a key of font property.  The
1986     property value must be an integer specifying a font's max advance
1987     value by pixels.  */ 
1988
1989 MSymbol Mmax_advance;
1990
1991
1992 /***en
1993     @brief Symbol of name "fontconfig".
1994
1995     The variable #Mfontconfig is to be used as an argument of the
1996     functions mfont_parse_name () and mfont_unparse_name ().  */
1997 /***ja
1998     @brief "fontconfig" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
1999
2000     ÊÑ¿ô #Mfontconfig ¤Ï´Ø¿ô mfont_parse_name () ¤È mfont_unparse_name ()
2001     ¤Î°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£  */
2002
2003 MSymbol Mfontconfig;
2004
2005 /***en
2006     @brief Symbol of name "x".
2007
2008     The variable #Mx is to be used for a value of <type> member of the
2009     structure #MDrawGlyph to specify the type of <fontp> member is
2010     actually (XFontStruct *).  */
2011 /***ja
2012     @brief "x" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
2013
2014     ÊÑ¿ô #Mx ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
2015     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XFontStruct *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹.  */
2016
2017 MSymbol Mx;
2018
2019 /***en
2020     @brief Symbol of name "freetype".
2021
2022     The variable #Mfreetype is to be used for a value of <type> member
2023     of the structure #MDrawGlyph to specify the type of <fontp> member
2024     is actually FT_Face.  */
2025 /***ja
2026     @brief "freetype" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
2027
2028     ÊÑ¿ô #Mfreetype ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
2029     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï FT_Face ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£  */
2030
2031 MSymbol Mfreetype;
2032
2033 /***en
2034     @brief Symbol of name "xft".
2035
2036     The variable #Mxft is to be used for a value of <type> member of the
2037     structure #MDrawGlyph to specify the type of <fontp> member
2038     is actually (XftFont *).  */
2039 /***ja
2040     @brief  "xft" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
2041
2042     ÊÑ¿ô #Mxft ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
2043     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XftFont *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£  */
2044
2045 MSymbol Mxft;
2046
2047 /*=*/
2048 /*** @} */
2049 /*=*/
2050
2051 /***en
2052     @brief List of font files and directories that contain font files.
2053
2054     The variable @c mfont_freetype_path is a plist of FreeType font
2055     files and directories that contain FreeType font files.  Key of
2056     the element is @c Mstring, and the value is a string that
2057     represents a font file or a directory.
2058
2059     The macro M17N_INIT () sets up this variable to contain the
2060     sub-directory "fonts" of the m17n database and the environment
2061     variable "M17NDIR".  The first call of mframe () creates the
2062     internal list of the actually available fonts from this variable.
2063     Thus, an application program, if necessary, must modify the
2064     variable before calling mframe ().  If it is going to add a new
2065     element, value must be a string that can be safely freed.
2066
2067     If the m17n library is not configured to use the FreeType library,
2068     this variable is not used.  */
2069 /***ja
2070     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
2071
2072     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î 
2073     plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring 
2074     ¤Ç¤¢¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
2075
2076     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ¿ô 
2077     "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
2078     mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£
2079     ¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢mframe () 
2080     ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2081     ¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2082
2083     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
2084
2085 MPlist *mfont_freetype_path;
2086
2087 /*=*/
2088
2089 /***en
2090     @brief Create a new font.
2091
2092     The mfont () function creates a new font object that has no
2093     property.
2094
2095     @return
2096     This function returns a pointer to the created font object.  */
2097 /***ja
2098     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
2099
2100     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
2101
2102     @return
2103     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
2104
2105 MFont *
2106 mfont ()
2107 {
2108   MFont *font;
2109
2110   MSTRUCT_CALLOC (font, MERROR_FONT);
2111   return font;
2112 }
2113
2114 /*=*/
2115
2116 /***en
2117     @brief Create a font by parsing a fontname.
2118
2119     The mfont_parse_name () function creates a new font object.  The
2120     properties are extracted fontname $NAME.
2121
2122     $FORMAT specifies the format of $NAME.  If $FORMAT is #Mx, $NAME
2123     is parsed as XLFD (X Logical Font Description).  If $FORMAT is
2124     #Mfontconfig, $NAME is parsed as Fontconfig's textual
2125     representation of font.  If $FORMAT is #Mnil, $NAME is at first
2126     parsed as XLFD, and it it fails, parsed as Fontconfig's
2127     representation.
2128
2129     @return
2130     If the operation was successful, this function returns a pointer
2131     to the created font.  Otherwise it returns @c NULL.  */
2132
2133 /***ja
2134     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2135
2136     ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ 
2137     $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
2138
2139     $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
2140     $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
2141     $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig 
2142     ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD 
2143     ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
2144
2145     @return
2146     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () 
2147     ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
2148
2149 MFont *
2150 mfont_parse_name (const char *name, MSymbol format)
2151 {
2152   MFont template, *font;
2153   
2154   MFONT_INIT (&template);
2155   if (mfont__parse_name_into_font (name, format, &template) < 0)
2156     MERROR (MERROR_FONT, NULL);
2157   MSTRUCT_CALLOC (font, MERROR_FONT);
2158   *font = template;
2159   return font;
2160 }
2161
2162 /*=*/
2163
2164 /***en
2165     @brief Create a fontname from a font.
2166
2167     The mfont_unparse_name () function creates a fontname string
2168     from font $FONT according to $FORMAT.
2169
2170     $FORMAT must be #Mx or #Mfontconfig.  If it is #Mx, the fontname
2171     is in XLFD (X Logical Font Description) format.  If it is
2172     #Mfontconfig, the fontname is in the style of Fontconfig's text
2173     representation.
2174
2175     @return
2176     This function returns a newly allocated fontname string, which is
2177     not freed unless the user explicitly does so by free ().  */
2178
2179 /***ja
2180     @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
2181
2182     ´Ø¿ô mfont_unparse_name () ¤Ï ¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È $FONT 
2183     ¤ò¸µ¤Ë$FORMAT ¤Ë½¾¤Ã¤Æºî¤ë¡£
2184
2185     $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤¢¤ë¡£
2186     #Mx ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£
2187     #Mfontconfig ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
2188
2189     @return 
2190     ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶¤¬
2191     free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
2192
2193 char *
2194 mfont_unparse_name (MFont *font, MSymbol format)
2195 {
2196   char *name;
2197
2198   if (format == Mx)
2199     name = xlfd_unparse_name (font);
2200 #ifdef HAVE_FONTCONFIG
2201   else if (format == Mfontconfig)
2202     name = mfont__ft_unparse_name (font);
2203
2204 #endif /* HAVE_FONTCONFIG */
2205   else
2206     MERROR (MERROR_FONT, NULL);
2207   return name;
2208 }
2209
2210 /*=*/
2211
2212 /***en
2213     @brief Make a copy of a font.
2214
2215     The mfont_copy () function returns a new copy of font $FONT.  */
2216 /***ja
2217     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
2218
2219     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
2220
2221 MFont *
2222 mfont_copy (MFont *font)
2223 {
2224   MFont *copy;
2225
2226   MSTRUCT_MALLOC (copy, MERROR_FONT);
2227   *copy = *font;
2228   return copy;
2229 }
2230
2231 /*=*/
2232
2233 /***en
2234     @brief Get a property value of a font.
2235
2236     The mfont_get_prop () function gets the value of $KEY property of
2237     font $FONT.  $KEY must be one of the following symbols:
2238
2239         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2240         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
2241
2242     @return
2243     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
2244     Madstyle, @c Mregistry, or @c Mspacing, this function returns the
2245     corresponding value as a symbol.  If the font does not have $KEY
2246     property, it returns @c Mnil.
2247     If $KEY is @c Msize or @c Mresolution, this function returns the
2248     corresponding value as an integer.  If the font does not have $KEY
2249     property, it returns 0.
2250     If $KEY is something else, it returns @c NULL and assigns an error
2251     code to the external variable #merror_code.  */
2252  
2253 /***ja
2254     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
2255
2256     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬
2257     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
2258     ¤Ð¤Ê¤é¤Ê¤¤¡£
2259
2260         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2261         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
2262
2263     @return $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
2264     Madstyle, @c Mregistry, @c Mspacing ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃÍ
2265     ¤ò¥·¥ó¥Ü¥ë¤È¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï
2266     @c Mnil ¤òÊÖ¤¹¡£$KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢
2267     ÁêÅö¤¹¤ëÃͤò¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤
2268     ¾ì¹ç¤Ë¤Ï 0 ¤òÊÖ¤¹¡£$KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢
2269     ³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
2270
2271 void *
2272 mfont_get_prop (MFont *font, MSymbol key)
2273 {
2274   MRealizedFont *rfont = NULL;
2275
2276   if (font->type == MFONT_TYPE_REALIZED)
2277     rfont = (MRealizedFont *) font, font = rfont->font;
2278
2279   if (key == Mfoundry)
2280     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
2281   if (key == Mfamily)
2282     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
2283   if (key == Mweight)
2284     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
2285   if (key == Mstyle)
2286     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
2287   if (key == Mstretch)
2288     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
2289   if (key == Madstyle)
2290     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
2291   if (key == Mregistry)
2292     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
2293   if (key == Msize)
2294     {
2295       int size = font->size;
2296       return (void *) size;
2297     }
2298   if (key == Mresolution)
2299     {
2300       int resy = font->property[MFONT_RESY];
2301       return (void *) resy;
2302     }
2303   if (key == Mfontfile)
2304     return (void *) font->file;
2305   if (key == Mspacing)
2306     return (font->spacing == MFONT_SPACING_UNDECIDED ? Mnil
2307             : msymbol (font->spacing == MFONT_SPACING_PROPORTIONAL ? "p"
2308                        : font->spacing == MFONT_SPACING_MONO ? "m" : "c"));
2309   if (rfont)
2310     {
2311       if (key == Mascent)
2312         return (void *) rfont->ascent;
2313       if (key == Mdescent)
2314         return (void *) rfont->descent;
2315       if (key == Mmax_advance)
2316         return (void *) rfont->max_advance;
2317     }
2318   MERROR (MERROR_FONT, NULL);
2319 }
2320
2321
2322 /*=*/
2323 /***en
2324     @brief Put a property value to a font.
2325
2326     The mfont_put_prop () function puts a font property whose key is
2327     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
2328     following symbols:
2329
2330         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2331         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
2332
2333     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
2334     Otherwise, $VAL must be a symbol.  */
2335  /***ja
2336     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
2337
2338     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY 
2339     ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
2340
2341         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2342         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
2343
2344     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL 
2345     ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
2346
2347 int
2348 mfont_put_prop (MFont *font, MSymbol key, void *val)
2349 {
2350   if (key == Mfoundry)
2351     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
2352   else if (key == Mfamily)
2353     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
2354   else if (key == Mweight)
2355     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
2356   else if (key == Mstyle)
2357     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
2358   else if (key == Mstretch)
2359     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
2360   else if (key == Madstyle)
2361     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
2362   else if (key == Mregistry)
2363     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
2364   else if (key == Msize)
2365     {
2366       unsigned size = (unsigned) val;
2367       font->size = size;
2368     }
2369   else if (key == Mresolution)
2370     {
2371       unsigned resy = (unsigned) val;
2372       font->property[MFONT_RESY] = resy;
2373     }
2374   else if (key == Mfontfile)
2375     {
2376       font->file = (MSymbol) val;
2377     }
2378   else
2379     MERROR (MERROR_FONT, -1);
2380   return 0;
2381 }
2382
2383 /*=*/
2384
2385 /***en
2386     @brief Return the font selection priority.
2387
2388     The mfont_selection_priority () function returns a newly created
2389     array of six symbols.  The elements are the following
2390     keys of font properties ordered by priority.
2391
2392         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2393         @c Madstyle, @c Msize.
2394
2395    The m17n library selects the best matching font according to the
2396    order of this array.  A font that has a different value for a
2397    property of lower priority is preferred to a font that has a
2398    different value for a property of higher priority.  */
2399 /***ja
2400     @brief ¥Õ¥©¥ó¥ÈÁªÂò¤ÎÍ¥ÀèÅÙ¤òÊÖ¤¹.
2401
2402     ´Ø¿ô mfont_selection_priority () ¤Ï 6 ¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã¤ÆÊÖ¤¹¡£
2403     ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤Ëʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
2404
2405         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2406         @c Madstyle, @c Msize.
2407
2408    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
2409    ÌÜŪ¤Î¥Õ¥©¥ó¥È¤È¡¢¤½¤ì¤¾¤ì°ã¤¦¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¤¬¤¢¤Ã¤¿¾ì¹ç¡¢Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¡ÊÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Æ¤¤¤ë¥Õ¥©¥ó¥È¡Ë¤¬ÁªÂò¤µ¤ì¤ë¡£
2410
2411    */
2412
2413 MSymbol *
2414 mfont_selection_priority ()
2415 {
2416   MSymbol *keys;
2417   int i;
2418
2419   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
2420   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
2421     {
2422       enum MFontProperty prop = font_score_priority[i];
2423
2424       if (prop == MFONT_SIZE)
2425         keys[i] = Msize;
2426       else if (prop == MFONT_ADSTYLE)
2427         keys[i] = Madstyle;
2428       else if (prop == MFONT_FAMILY)
2429         keys[i] = Mfamily;
2430       else if (prop == MFONT_WEIGHT)
2431         keys[i] = Mweight;
2432       else if (prop == MFONT_STYLE)
2433         keys[i] = Mstyle;
2434       else if (prop == MFONT_STRETCH)
2435         keys[i] = Mstretch;
2436       else
2437         keys[i] = Mfoundry;
2438     }
2439   return keys;
2440 }
2441
2442 /*=*/
2443
2444 /***en
2445     @brief Set the font selection priority.
2446
2447     The mfont_set_selection_priority () function sets font selection
2448     priority according to $KEYS, which is an array of six symbols.
2449     Each element must be one of the below.  No two elements must be
2450     the same.
2451
2452         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2453         @c Madstyle, @c Msize.
2454
2455     See the documentation of the function mfont_selection_priority ()
2456     for details.  */
2457 /***ja
2458     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
2459
2460     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
2461     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£ÇÛÎó¤Ï°Ê²¼¤Î³ÆÍ×ÁǤòŬÀÚ
2462     ¤Ê½çÈÖ¤Çʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
2463
2464         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2465         @c Madstyle, @c Msize.
2466
2467     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
2468      */
2469
2470 int
2471 mfont_set_selection_priority (MSymbol *keys)
2472 {
2473   int priority[FONT_SCORE_PRIORITY_SIZE];
2474   int i, j, shift;
2475
2476   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
2477     {
2478       enum MFontProperty prop;
2479
2480       if (*keys == Msize)
2481         prop = MFONT_SIZE;
2482       else if (*keys == Madstyle)
2483         prop = MFONT_ADSTYLE;
2484       else if (*keys == Mfamily)
2485         prop = MFONT_FAMILY;
2486       else if (*keys == Mweight)
2487         prop = MFONT_WEIGHT;
2488       else if (*keys == Mstyle)
2489         prop = MFONT_STYLE;
2490       else if (*keys == Mstretch)
2491         prop = MFONT_STRETCH;
2492       else if (*keys == Mfoundry)
2493         prop = MFONT_FOUNDRY;
2494       else
2495         /* Invalid element.  */
2496         return -1;
2497       for (j = 0; j < i; j++)
2498         if (priority[j] == prop)
2499           /* Duplicated element.  */
2500           return -1;
2501       priority[i] = prop;
2502     }
2503   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
2504     font_score_priority[i] = priority[i];
2505   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
2506      of a score is a flag for a scalable font (see the documentation
2507      of font_score).  */
2508   i = FONT_SCORE_PRIORITY_SIZE - 1;
2509   for (shift = 1; i >= 0; i--)
2510     {
2511       font_score_shift_bits[font_score_priority[i]] = shift;
2512       if (font_score_priority[i] == MFONT_SIZE)
2513         shift += 16;
2514       else if (font_score_priority[i] <= MFONT_FAMILY)
2515         shift++;
2516       else
2517         shift += 2;
2518     }
2519   return 0;
2520 }
2521
2522 /*=*/
2523
2524 /***en
2525     @brief Find a font.
2526
2527     The mfont_find () function returns a pointer to the available font
2528     that matches best the specification $SPEC on frame $FRAME.
2529
2530     $SCORE, if not NULL, must point to a place to store the score
2531     value that indicates how well the found font matches to $SPEC.  The
2532     smaller score means a better match.  */
2533 /***ja
2534     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
2535
2536     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC 
2537     ¤Ë¤â¤Ã¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
2538
2539     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC 
2540     ¤Ë¤É¤ì¤Û¤É¹ç¤Ã¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£
2541     ¥¹¥³¥¢¤¬¾®¤µ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
2542     */
2543
2544 MFont *
2545 mfont_find (MFrame *frame, MFont *spec, int *score, int max_size)
2546 {
2547   MFont spec_copy;
2548   MFont *best;
2549   MFontList *list;
2550   MRealizedFont *rfont;
2551
2552   MFONT_INIT (&spec_copy);
2553   spec_copy.property[MFONT_FAMILY] = spec->property[MFONT_FAMILY];
2554   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
2555   spec_copy.capability = spec->capability;
2556   spec_copy.file = spec->file;
2557
2558   list = mfont__list (frame, &spec_copy, spec, max_size);
2559   if (! list)
2560     return NULL;
2561
2562   best = list->fonts[0].font;
2563   if (score)
2564     *score = list->fonts[0].score;
2565   free (list->fonts);
2566   free (list);
2567   rfont = mfont__open (frame, best, best);
2568   if (! rfont)
2569     return NULL;
2570   return (MFont *) rfont;
2571 }
2572
2573 /*=*/
2574 /***en
2575     @brief Set encoding of a font.
2576
2577     The mfont_set_encoding () function sets the encoding information
2578     of font $FONT.
2579
2580     $ENCODING_NAME is a symbol representing a charset that has the
2581     same encoding as the font.
2582
2583     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
2584     has the same repertory as the font.  If it is @c Mnil, whether a
2585     specific character is supported by the font is asked to each font
2586     driver.
2587
2588     @return
2589     If the operation was successful, this function returns 0.
2590     Otherwise it returns -1 and assigns an error code to the external
2591     variable #merror_code.  */
2592 /***ja
2593     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
2594
2595     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó¤òÀßÄꤹ¤ë¡£
2596
2597     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
2598
2599     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
2600     @c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ»ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢³Æ¡¹¤Î¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ËÌ䤤¹ç¤ï¤»¤ë¡£
2601
2602     @return
2603     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô
2604     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
2605
2606
2607 int
2608 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
2609 {
2610   MCharset *encoding_charset = MCHARSET (encoding_name);
2611   MCharset *repertory_charset;
2612   MSymbol registry;
2613   MFontEncoding *encoding;
2614   MPlist *plist;
2615
2616   if (! encoding_charset)
2617     MERROR (MERROR_FONT, -1);
2618   if (repertory_name != Mnil)
2619     {
2620       repertory_charset = MCHARSET (repertory_name);
2621       if (! repertory_charset)
2622         MERROR (MERROR_FONT, -1);
2623     }
2624   else
2625     repertory_charset = NULL;
2626
2627   MSTRUCT_CALLOC (encoding, MERROR_FONT);
2628   encoding->spec = *font;
2629   encoding->encoding_name = encoding_name;
2630   encoding->encoding_charset = encoding_charset;
2631   encoding->repertory_name = repertory_name;
2632   encoding->repertory_charset = repertory_charset;
2633   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
2634   if (registry == Mnil)
2635     registry = Mt;
2636   if (! font_encoding_list)
2637     load_font_encoding_table ();
2638   mplist_push (font_encoding_list, registry, encoding);
2639   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
2640     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
2641                   sizeof (MFont)))
2642       {
2643         mplist_pop (plist);
2644         break;
2645       }
2646   return 0;
2647 }
2648
2649 /*=*/
2650
2651 /***en
2652     @brief Create a fontname from a font.
2653
2654     This function is obsolete.   Use mfont_unparse_name instead. */
2655 /***ja
2656     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2657
2658     ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
2659
2660 char *
2661 mfont_name (MFont *font)
2662 {
2663   return mfont_unparse_name (font, Mx);
2664 }
2665
2666 /*=*/
2667
2668 /***en
2669     @brief Create a new font from fontname.
2670
2671     This function is obsolete.  Use mfont_parse_name () instead.  */
2672
2673 /***ja
2674     @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
2675
2676     ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
2677
2678 MFont *
2679 mfont_from_name (const char *name)
2680 {
2681   return mfont_parse_name (name, Mx);
2682 }
2683
2684 /*=*/
2685
2686 /***en
2687     @brief Get resize information of a font.
2688
2689     The mfont_resize_ratio () function lookups the m17n database
2690     \<font, reisize\> and returns a resizing ratio (in percentage) of
2691     FONT.  For instance, if the return value is 150, that means that
2692     the m17n library uses an 1.5 time bigger font than a specified
2693     size.  */
2694
2695 /***ja
2696     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥µ¥¤¥º¾ðÊó¤òÆÀ¤ë
2697
2698     ´Ø¿ô mfont_resize_ratio ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹ \<font, reisize\> 
2699     ¤ò¸¡º÷¤·¡¢¥Õ¥©¥ó¥È FONT ¤Î¥ê¥µ¥¤¥º¤ÎÈæΨ¡Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¡Ë
2700     ¤òÊÖ¤¹¡£¤¿¤È¤¨¤ÐÊÖ¤¹Ãͤ¬ 150 ¤Ç¤¢¤ì¤Ð¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ï»ØÄꤵ¤ì¤¿¥µ¥¤¥º¤Î 1.5 
2701     ÇܤΥե©¥ó¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ */
2702
2703 int
2704 mfont_resize_ratio (MFont *font)
2705 {
2706   MFont request = *font;
2707
2708   mfont__resize (font, &request);
2709   return (font->size * 100 / request.size);
2710 }
2711
2712 /*=*/
2713
2714 /***en
2715     @brief Get a list of fonts.
2716
2717     The mfont_list () functions returns a list of fonts available on
2718     frame $FRAME.  $FONT, if not NULL, limits fonts to ones
2719     that match with $FONT.  $LANGUAGE, if not @c Mnil, limits fonts to
2720     ones that support $LANGUAGE.  $MAXNUM, if greater than 0, limits
2721     the number of fonts.
2722
2723     @return
2724     This function returns a plist whose keys are family names and
2725     values are pointers to the object MFont.  The plist must be freed
2726     by m17n_object_unref ().  If no font is found, it returns
2727     NULL.  */
2728
2729 /***ja
2730     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë
2731
2732     ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2733     $FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2734     $LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2735     $MAXNUM ¤Ï¡¢0 ¤è¤êÂ礭¤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
2736
2737     @return 
2738     ¤³¤Î´Ø¿ô¤Ï¥­¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê
2739     plist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref () 
2740     ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£  */
2741
2742 MPlist *
2743 mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum)
2744 {
2745   MPlist *plist, *pl;
2746   MFontList *font_list;
2747   int i;
2748   MFont *work = NULL;
2749   
2750   if (language != Mnil)
2751     {
2752       /* ":lang=XXX" */
2753       char *buf = alloca (MSYMBOL_NAMELEN (language) + 7);
2754
2755       sprintf (buf, ":lang=%s", MSYMBOL_NAME (language));
2756       if (! font)
2757         font = work = mfont ();
2758       font->capability = msymbol (buf);
2759     }
2760
2761   font_list = mfont__list (frame, font, font, 0);
2762   if (work)
2763     free (work);
2764   if (! font_list)
2765     return NULL;
2766   if (font_list->nfonts == 0)
2767     {
2768       free (font_list);
2769       return NULL;
2770     }
2771
2772   plist = pl = mplist ();
2773   for (i = 0; i < font_list->nfonts; i++)
2774     {
2775       MSymbol family = FONT_PROPERTY (font_list->fonts[i].font, MFONT_FAMILY);
2776
2777       if (family != Mnil)
2778         pl = mplist_add (pl, family, font_list->fonts[i].font);
2779     }
2780   free (font_list);
2781   return plist;
2782 }
2783
2784
2785 /*=*/
2786
2787 /***en
2788     @brief Check the usability of a font.
2789
2790     The function mfont_check () checkes if $FONT can be used for
2791     $SCRIPT and RLANGUAGE in $FONTSET on $FRAME.
2792
2793     @return If the font is usable, return 1.  Otherwise return 0.
2794  */
2795
2796 int
2797 mfont_check (MFrame *frame, MFontset *fontset, MFont *font,
2798              MSymbol script, MSymbol language)
2799 {
2800   MFont spec;
2801   MPlist *plist, *pl;
2802   int result = 0;
2803
2804   if (! fontset)
2805     fontset = frame->face->property[MFACE_FONTSET];
2806
2807   plist = mfontset_lookup (fontset, script, Mt, Mnil);
2808   if (script != Mnil)
2809     {
2810       if (language == Mnil)
2811         {
2812           if (! mplist_find_by_key (plist, Mt))
2813             /* No fallback fonts.  */
2814             language = MPLIST_KEY (plist);
2815         }
2816       else if (! mplist_find_by_key (plist, language))
2817         {
2818           /* Try fallback fonts. */
2819           if (mplist_find_by_key (plist, Mt))
2820             language = Mnil;
2821           else
2822             /* No fallback fonts.  */
2823             language = MPLIST_KEY (plist);
2824         }
2825
2826       M17N_OBJECT_UNREF (plist);
2827       plist = mfontset_lookup (fontset, script, language, Mnil);
2828     }
2829   MPLIST_DO (pl, plist)
2830     {
2831       spec = *(MFont *) MPLIST_VAL (pl);          
2832       if (mfont__merge (&spec, font, 1) >= 0
2833           && mfont__select (frame, &spec, 0))
2834         {
2835           result = 1;
2836           break;
2837         }
2838     }
2839   M17N_OBJECT_UNREF (plist);
2840   return result;
2841 }
2842
2843 /*** @} */
2844
2845 /*** @addtogroup m17nDebug */
2846 /*=*/
2847 /*** @{ */
2848
2849 /***en
2850     @brief Dump a font.
2851
2852     The mdebug_dump_font () function prints font $FONT in a human readable
2853     way to the stderr.
2854
2855     @return
2856     This function returns $FONT.  */
2857 /***ja
2858     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
2859
2860     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr 
2861     ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£
2862
2863     @return
2864     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
2865
2866 MFont *
2867 mdebug_dump_font (MFont *font)
2868 {
2869   char *name;
2870   
2871   name = mfont_unparse_name (font, Mx);
2872   if (name)
2873     {
2874       fprintf (stderr, "%s", name);
2875       free (name);
2876     }
2877   return font;
2878 }
2879
2880 /*** @} */
2881
2882 /*
2883   Local Variables:
2884   coding: euc-japan
2885   End:
2886 */