9464327fbd8d0b8936bd9c86534f538cbf33d50e
[m17n/m17n-lib.git] / src / font.c
1 /* font.c -- font module.
2    Copyright (C) 2003, 2004
3      National Institute of Advanced Industrial Science and Technology (AIST)
4      Registration Number H15PRO112
5
6    This file is part of the m17n library.
7
8    The m17n library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Lesser General Public License
10    as published by the Free Software Foundation; either version 2.1 of
11    the License, or (at your option) any later version.
12
13    The m17n library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Lesser General Public
19    License along with the m17n library; if not, write to the Free
20    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21    02111-1307, USA.  */
22
23 /***en
24     @addtogroup m17nFont
25     @brief Font object.
26
27     The m17n GUI API represents a font by an object of the type @c
28     MFont.  A font can have @e font @e properties.  Like other types
29     of properties, a font property consists of a key and a value.  The
30     key of a font property must be one of the following symbols:
31
32     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
33     @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
34
35     When the key of a font property is @c Msize or @c Mresolution, its
36     value is an integer.  Otherwise the value is a symbol.  "The font
37     property that belongs to font F and whose key is @c Mxxx" may be
38     shortened to "the xxx property of F".
39
40     The value of a foundry property is a symbol representing font
41     foundry information, e.g. adobe, misc, etc.
42
43     The value of a family property is a symbol representing font family
44     information, e.g. times, helvetica, etc.
45
46     The value of a weight property is a symbol representing weight
47     information, e.g. normal, bold, etc.
48
49     The value of a style property is a symbol representing slant
50     information, e.g. normal, italic, etc.
51
52     The value of a stretch property is a symbol representing width
53     information, e.g. normal, semicondensed, etc.
54
55     The value of an adstyle property is a symbol representing abstract
56     font family information, e.g. serif, sans-serif, etc.
57
58     The value of a registry property is a symbol representing registry
59     information, e.g. iso10646-1, iso8895-1, etc.
60
61     The value of a size property is an integer representing design
62     size in the unit of 1/10 point.
63
64     The value of a resolution property is an integer representing
65     assumed device resolution in the unit of dots per inch (dpi)
66
67     The m17n library uses font objects for two purposes: to receive
68     font specification from an application program, and to present
69     available fonts to an application program.  When the m17n library
70     presents an available font to an application program, all font
71     properties have a concrete value.
72
73     The m17n library supports three kinds of fonts: Window system fonts,
74     FreeType fonts, and OpenType fonts.
75
76     <ul>
77
78     <li> Window system fonts
79
80     The m17n-X library supports all fonts handled by an X server and
81     an X font server.  The correspondence between XLFD fields and font
82     properties are shown below.
83
84 @verbatim
85     XLFD field                                  property
86     ---------------                             --------
87     FOUNDRY                                     foundry
88     FAMILY_NAME                                 family
89     WEIGHT_NAME                                 weight
90     SLANT                                       style
91     SETWIDTH_NAME                               stretch
92     ADD_STYLE_NAME                              adstyle
93     POINT_SIZE                                  size
94     RESOLUTION_Y                                resolution
95     CHARSET_REGISTRY-CHARSET_ENCODING           registry
96 @endverbatim
97
98     XLFD fields not listed in the above table are ignored.
99
100     <li> FreeType fonts
101
102     The m17n library, if configured to use the FreeType library,
103     supports all fonts that can be handled by the FreeType library.
104     The variable #mfont_freetype_path is initialized properly according
105     to the configuration of the m17n library and the environment
106     variable @c M17NDIR.  See the documentation of the variable for
107     details.
108
109     If the m17n library is configured to use the fontconfig librray,
110     in addition to #mfont_freetype_path, all fonts available via
111     fontconfig are supported.
112
113     The family name of a FreeType font corresponds to the family
114     property.  Style names of FreeType fonts correspond to the weight,
115     style, and stretch properties as below.
116
117 @verbatim
118     style name          weight  style   stretch
119     ----------          ------  -----   -------
120     Regular             medium  r       normal
121     Italic              medium  i       normal
122     Bold                bold    r       normal
123     Bold Italic         bold    i       normal
124     Narrow              medium  r       condensed
125     Narrow Italic       medium  i       condensed
126     Narrow Bold         bold    r       condensed
127     Narrow Bold Italic  bold    i       condensed
128     Black               black   r       normal
129     Black Italic        black   i       normal
130     Oblique             medium  o       normal
131     BoldOblique         bold    o       normal
132 @endverbatim
133
134     Style names not listed in the above table are treated as
135     "Regular".
136
137     Combination of a platform ID and an encoding ID corresponds to the
138     registry property.  For example, if a font has the combination (1
139     1), the registry property is 1-1.  Some frequent combinations have
140     a predefined registry property as below.
141
142 @verbatim
143     platform ID         encoding ID     registry property
144     -----------         -----------     -----------------
145     0                   3               unicode-bmp
146     0                   4               unicode-full
147     1                   0               apple-roman
148     3                   1               unicode-bmp
149     3                   1               unicode-full
150 @endverbatim
151
152     Thus, a font that has two combinations (1 0) and (3 1) corresponds
153     to four font objects whose registries are 1-0, apple-roman, 3-1,
154     and unicode-bmp.
155
156     <li> OpenType fonts 
157
158     The m17n library, if configured to use both the FreeType library
159     and the OTF library, supports any OpenType fonts.  The list of
160     actually available fonts is created in the same way as in the case
161     of FreeType fonts.  If a fontset instructs to use an OpenType font
162     via an FLT (Font Layout Table), and the FLT has an OTF-related
163     command (e.g. otf:deva), the OTF library converts a character
164     sequence to a glyph code sequence according to the OpenType layout
165     tables of the font, and the FreeType library gives a bitmap image
166     for each glyph.
167
168     </ul>
169
170   */
171
172 /***ja
173     @addtogroup m17nFont
174     @brief ¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È.
175
176     m17n GUI API ¤Ï¥Õ¥©¥ó¥È¤ò @c MFont ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æɽ¸½¤¹¤ë¡£
177     ¥Õ¥©¥ó¥È¤Ï @e ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£Â¾¤Î¥¿¥¤¥×¤Î
178     ¥×¥í¥Ñ¥Æ¥£Æ±ÍÍ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¥­¡¼¤ÈÃͤ«¤é¤Ê¤ë¡£¥­¡¼¤Ï°Ê²¼¤Î¥·
179     ¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
180
181     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
182     @c Madstyle, @c Mregistry, @c Msize, @c Mresolution
183
184     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¡¢
185     ÃͤÏÀ°¿ôÃͤǤ¢¤ê¡¢¥­¡¼¤¬¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Ãͤϥ·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£¡Ö¥Õ¥©
186     ¥ó¥È F ¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ @c Mxxx ¤Ç¤¢¤ë¤â¤Î¡×¤Î¤³¤È
187     ¤ò´Êñ¤Ë¡ÖF ¤Î xxx ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
188
189     foundry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢adobe, misc Åù¤Î¥Õ¥©¥ó¥È¤Î³«È¯¸µ¾ðÊó¤ò¼¨
190     ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
191
192     family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢times, helvetica Åù¤Î¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤ò
193     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
194
195     weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, bold Åù¤ÎÂÀ¤µ¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·
196     ¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
197
198     style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, italic Åù¤Î¥¹¥¿¥¤¥ë¤Ë´Ø¤¹¤ë¾ðÊó¤ò
199     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
200
201     stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, semicondensed Åù¤Îʸ»úÉý¤Ë´Ø¤¹¤ë
202     ¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
203
204     adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢serif, sans-serif Åù¤ÎÃê¾ÝŪ¤Ê¥Õ¥©¥ó¥È¥Õ¥¡
205     ¥ß¥ê¡¼¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
206
207     registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢iso10646, iso8895-1 Åù¤Î¥ì¥¸¥¹¥È¥ê¾ðÊó¤ò
208     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
209
210     size ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤òɽ¤ï¤¹À°¿ôÃͤǤ¢
211     ¤ê¡¢Ã±°Ì¤Ï 1/10 ¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£
212
213     resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ÁÛÄꤵ¤ì¤Æ¤¤¤ë¥Ç¥Ð¥¤¥¹¤Î²òÁüÅÙ¤òɽ¤ï
214     ¤¹À°¿ôÃͤǤ¢¤ê¡¢Ã±°Ì¤Ï dots per inch (dpi) ¤Ç¤¢¤ë¡£  
215
216     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤Ä¤ÎÌÜŪ¤ÇÍѤ¤¤Æ¤¤¤ë¡£¥¢
217     ¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¥Õ¥©¥ó¥È¤Î»ØÄê¤ò¼õ¤±¼è¤ëÌÜŪ¤È¡¢¥¢¥×¥ê
218     ¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤òÄ󼨤¹¤ëÌÜŪ¤Ç¤¢¤ë¡£¥¢¥×
219     ¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÂФ·¤ÆÄ󼨤ò¹Ô¤¦ºÝ¤Ë¤Ï¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£
220     ¤Ï¤¹¤Ù¤Æ¶ñÂÎŪ¤ÊÃͤò»ý¤Ä¡£
221
222     m17n ¥é¥¤¥Ö¥é¥ê¤Ï Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¡¢FreeType¥Õ¥©¥ó¥È¡¢
223     OpenType¥Õ¥©¥ó¥È¤Î£³¼ïÎà¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£
224
225     <ul>
226
227     <li> Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È
228
229     m17n X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢X ¥µ¡¼¥Ð¤È X ¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤¬¼è¤ê°·¤¦Á´¤Æ¤Î¥Õ¥©
230     ¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£XLFD ¤Î³Æ¥Õ¥£¡¼¥ë¥É¤È¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ÎÂбþ
231     ¤Ï°Ê²¼¤ÎÄ̤ꡣ¤³¤Îɽ¤Ë¤Ê¤¤¥Õ¥£¡¼¥ë¥É¤Ï̵»ë¤µ¤ì¤ë¡£
232
233 @verbatim
234     XLFD ¥Õ¥£¡¼¥ë¥É                             ¥×¥í¥Ñ¥Æ¥£
235     ---------------                             --------
236     FOUNDRY                                     foundry
237     FAMILY_NAME                                 family
238     WEIGHT_NAME                                 weight
239     SLANT                                       style
240     SETWIDTH_NAME                               stretch
241     ADD_STYLE_NAME                              adstyle
242     POINT_SIZE                                  size
243     RESOLUTION_Y                                resolution
244     CHARSET_REGISTRY-CHARSET_ENCODING           registry
245 @endverbatim
246
247     <li> FreeType fonts
248
249     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë
250     ¤Ï¡¢FreeType ¤¬°·¤¦¤¹¤Ù¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ÊÑ¿ô 
251     #mfont_freetype_path ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤ÎÀßÄê¤È´Ä¶­ÊÑ¿ô @c M17NDIR 
252     ¤Ë±þ¤¸¤Æ½é´ü²½¤µ¤ì¤ë¡£¾ÜºÙ¤ÏÊÑ¿ô¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
253
254     ¤â¤· m17n ¥é¥¤¥Ö¥é¥ê¤¬ fontconfig ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿
255     ¾ì¹ç¤Ë¤Ï¡¢#mfont_freetype_path ¤Ë²Ã¤¨¤Æ¡¢ fontconfig ¤Ç»ÈÍѲÄǽ¤Ê¥Õ¥©
256     ¥ó¥È¤â¤¹¤Ù¤Æ¥µ¥Ý¡¼¥È¤µ¤ì¤ë¡£
257
258     FreeType ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤Ï family ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
259     FreeType ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾¤Ï¡¢²¼¤Îɽ¤Î¤è¤¦¤Ë weight, style,
260     stretch ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
261
262 @verbatim
263     ¥¹¥¿¥¤¥ë̾          weight  style   stretch
264     ----------          ------  -----   -------
265     Regular             medium  r       normal
266     Italic              medium  i       normal
267     Bold                bold    r       normal
268     Bold Italic         bold    i       normal
269     Narrow              medium  r       condensed
270     Narrow Italic       medium  i       condensed
271     Narrow Bold         bold    r       condensed
272     Narrow Bold Italic  bold    i       condensed
273     Black               black   r       normal
274     Black Italic        black   i       normal
275     Oblique             medium  o       normal
276     BoldOblique         bold    o       normal
277 @endverbatim
278
279     ¾å¤Îɽ¤Ë¸½¤ï¤ì¤Ê¤¤¥¹¥¿¥¤¥ë̾¤Ï "Regular" ¤È¤·¤Æ°·¤ï¤ì¤ë¡£
280
281     platform ID ¤È encoding ID ¤ÎÁȤ߹ç¤ï¤»¤Ï registry ¥×¥í¥Ñ¥Æ¥£¤ËÂÐ
282     ±þ¤¹¤ë¡£¤¿¤È¤¨¤Ð¤¢¤ë¥Õ¥©¥ó¥È¤¬ (1 1) ¤È¤¤¤¦ ID ¤ÎÁȹ礻¤ò»ý¤Æ¤Ð¡¢
283     registry ¥×¥í¥Ñ¥Æ¥£¤Ï 1-1 ¤È¤Ê¤ë¡£ÉÑÈˤˤ¢¤é¤ï¤ì¤ëÁȹ礻¤Ë¤Ï°Ê²¼¤Î
284     ¤è¤¦¤ÊÄêµÁºÑ¤ß registry ¥×¥í¥Ñ¥Æ¥£ ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤ë¡£
285
286 @verbatim
287     platform ID         encoding ID     registry ¥×¥í¥Ñ¥Æ¥£
288     -----------         -----------     -----------------
289     0                   3               unicode-bmp
290     0                   4               unicode-full
291     1                   0               apple-roman
292     3                   1               unicode-bmp
293     3                   1               unicode-full
294 @endverbatim
295
296     ¤·¤¿¤¬¤Ã¤Æ¡¢Æó¤Ä¤ÎÁȹ礻 (1 0) ¡¢(3 1) ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤Ï¡¢¤½¤ì¤¾¤ì
297     registry ¥×¥í¥Ñ¥Æ¥£¤¬ 1-0, apple-roman, 3-1, unicode-bmp ¤Ç¤¢¤ë£´¤Ä
298     ¤Î¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ËÂбþ¤¹¤ë¡£
299
300     <li> OpenType ¥Õ¥©¥ó¥È
301
302     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤È OTF ¥é¥¤¥Ö¥é¥ê¤ò»ÈÍѤ¹¤ë¤è
303     ¤¦¤ËÀßÄꤹ¤ì¤Ð¡¢¤¹¤Ù¤Æ¤Î OpenType ¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£¼ÂºÝ¤ËÍø
304     ÍѤǤ­¤ë¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤Ï FreeType ¥Õ¥©¥ó¥È¤Î¾ì¹ç¤ÈƱÍͤ˺î¤é¤ì¤ë¡£
305     OpenType ¥Õ¥©¥ó¥È¤ò FLT (Font Layout Table) ·Ðͳ¤Ç»ÈÍѤ¹¤ë¤è¤¦¥Õ¥©
306     ¥ó¥È¥»¥Ã¥È¤Ë»ØÄꤵ¤ì¤Æ¤ª¤ê¡¢FLT ¤Ë OTF ´ØÏ¢¤Î¥³¥Þ¥ó¥É (¤¿¤È¤¨¤Ð
307     otf:deva) ¤¬¤¢¤ì¤Ð¡¢OTF ¥é¥¤¥Ö¥é¥ê¤¬¥Õ¥©¥ó¥È¤Î OpenType ¥ì¥¤¥¢¥¦¥È
308     ¥Æ¡¼¥Ö¥ë¤Ë½¾¤Ã¤Æʸ»úÎó¤ò¥°¥ê¥Õ¥³¡¼¥ÉÎó¤ËÊÑ´¹¤·¡¢FreeType ¥é¥¤¥Ö¥é¥ê
309     ¤¬³Æ¥°¥ê¥Õ¤Î¥Ó¥Ã¥È¥Þ¥Ã¥×¥¤¥á¡¼¥¸¤òÄ󶡤¹¤ë¡£
310
311     </ul>
312
313 */
314
315 /*=*/
316
317 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
318 /*** @addtogroup m17nInternal
319      @{ */
320
321 #include "config.h"
322
323 #include <stdio.h>
324 #include <stdlib.h>
325 #include <string.h>
326
327 #include "m17n-gui.h"
328 #include "m17n-misc.h"
329 #include "internal.h"
330 #include "mtext.h"
331 #include "symbol.h"
332 #include "plist.h"
333 #include "charset.h"
334 #include "internal-gui.h"
335 #include "font.h"
336 #include "face.h"
337
338 MPlist *mfont__driver_list;
339
340 /** Indices to font properties sorted by their priority.  */
341 static int font_score_priority[] =
342   { MFONT_SIZE,
343     MFONT_ADSTYLE,
344     MFONT_FAMILY,
345     MFONT_WEIGHT,
346     MFONT_STYLE,
347     MFONT_STRETCH,
348     MFONT_FOUNDRY
349   };
350
351 #define FONT_SCORE_PRIORITY_SIZE        \
352   (sizeof font_score_priority / sizeof font_score_priority[0])
353
354 /* Indexed by a font property MFONT_XXX, and the value is how many
355    bits to shift the difference of property values.  */
356 static int font_score_shift_bits[MFONT_PROPERTY_MAX];
357
358 /** Predefined symbols for each font property.  The order is important
359     because the function score_font () decides how well a font matches
360     with a spec by checking how close the index is.  */
361
362 static char *common_foundry[] =
363   { "misc",
364     "adobe" };
365 static char *common_family[] =
366   { "fixed",
367     "courier",
368     "helvetica",
369     "times" };
370 static char *common_weight[] =
371   { "ultralight",
372     "extralight",
373     "light",
374     "demilight",
375     "book",
376     "normal",
377     "medium",
378     "regular",
379     "demibold",
380     "bold",
381     "extrabold",
382     "ultrabold",
383     "black" };
384 static char *common_style[] =
385   { "o",
386     "i",
387     "r",
388     "ri",
389     "ro" };
390 static char *common_stretch[] =
391   { "condensed",
392     "narrow",
393     "semicondensed",
394     "normal",
395     "semiexpanded",
396     "expanded" };
397 static char *common_adstyle[] =
398   { "serif",
399     "",
400     "sans" };
401 static char *common_registry[] =
402   { "iso8859-1" };
403
404 /* Table containing all the data above.  */
405
406 struct MFontCommonNames
407 {
408   int num;
409   char **names;
410 };
411
412 static struct MFontCommonNames font_common_names[] =
413   {
414     { sizeof (common_foundry) / sizeof (char *), common_foundry},
415     { sizeof (common_family) / sizeof (char *), common_family},
416     { sizeof (common_weight) / sizeof (char *), common_weight},
417     { sizeof (common_style) / sizeof (char *), common_style},
418     { sizeof (common_stretch) / sizeof (char *), common_stretch},
419     { sizeof (common_adstyle) / sizeof (char *), common_adstyle},
420     { sizeof (common_registry) / sizeof (char *), common_registry}
421   };
422
423
424 /** Table of available font property names.  */
425
426 MFontPropertyTable mfont__property_table[MFONT_REGISTRY + 1];
427
428
429 /** Return the numeric value of SYMBOL as the Nth font property.  */
430
431 #define FONT_PROPERTY_NUMERIC(symbol, n)        \
432   ((symbol) == Mnil                             \
433    ? 0                                          \
434    : ((int) msymbol_get ((symbol), mfont__property_table[(n)].property)))
435
436
437 /** Set the numeric value of SYMBOL as the Nth font property to NUMERIC.  */
438
439 #define SET_FONT_PROPERTY_NUMERIC(symbol, n, numeric)           \
440   msymbol_put((symbol), mfont__property_table[(n)].property,    \
441               (void *) (numeric))
442
443 static char *
444 gen_font_name (char *buf, MFont *font)
445 {
446   char size[16];
447   int i;
448
449   buf[0] = '\0';
450   for (i = 0; i <= MFONT_REGISTRY; i++)
451     if (FONT_PROPERTY (font, i) != Mnil)
452       {
453         char *name = msymbol_name (FONT_PROPERTY (font, i));
454
455         if (name[0])
456           {
457             if (i > 0)
458               strcat (buf, ",");
459             strcat (buf, name);
460           }
461       }
462   sprintf (size, ",%d", font->property[MFONT_SIZE] / 10);
463   strcat (buf, size);
464   return buf;
465 }
466
467
468 \f
469 /* Font selector.  */
470
471 struct MFontEncoding {
472   MFont spec;
473   MSymbol encoding_name;
474   MCharset *encoding_charset;
475   MSymbol repertory_name;
476   MCharset *repertory_charset;
477 };
478
479 static MPlist *font_encoding_list;
480 static MFontEncoding default_encoding;
481
482 /** Load font encoding table from the data <font encoding>.
483     The data has this form:
484         (FONT-SPEC ENCODING) ...
485     where FONT-SPEC has this form:
486         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
487     All elements are symbols.  */
488
489 static int
490 load_font_encoding_table ()
491 {
492   MDatabase *mdb;
493   MPlist *encoding_list, *plist, *pl, *elt;
494
495   font_encoding_list = pl = mplist ();
496
497   mdb = mdatabase_find (Mfont, msymbol ("encoding"), Mnil, Mnil);
498   if (! mdb
499       || ! (encoding_list = (MPlist *) mdatabase_load (mdb)))
500     MERROR (MERROR_FONT, -1);
501
502   MPLIST_DO (plist, encoding_list)
503     {
504       MFontEncoding *encoding;
505       MSymbol registry;
506
507       MSTRUCT_CALLOC (encoding, MERROR_FONT);
508
509       if (! MPLIST_PLIST_P (plist)
510           || (elt = MPLIST_PLIST (plist), mplist_length (elt) < 2)
511           || ! MPLIST_PLIST_P (elt))
512         MWARNING (MERROR_FONT);
513       registry = mfont__set_spec_from_plist (&encoding->spec,
514                                              MPLIST_PLIST (elt));
515       elt = MPLIST_NEXT (elt);
516       if (! MPLIST_SYMBOL_P (elt))
517         MWARNING (MERROR_FONT);
518       encoding->encoding_name = MPLIST_SYMBOL (elt);
519       elt = MPLIST_NEXT (elt);
520       if (MPLIST_TAIL_P (elt))
521         encoding->repertory_name = encoding->encoding_name;
522       else if (! MPLIST_SYMBOL_P (elt))
523         MWARNING (MERROR_FONT);
524       else
525         encoding->repertory_name = MPLIST_SYMBOL (elt);
526
527       if (registry == Mnil)
528         registry = Mt;
529       pl = mplist_add (pl, registry, encoding);
530       continue;
531
532     warning:
533       free (encoding);
534     }
535
536   M17N_OBJECT_UNREF (encoding_list);
537   return 0;
538 }
539
540 typedef struct {
541   MFont spec;
542   int resize;
543 } MFontResize;
544
545 static MPlist *font_resize_list;
546
547 /** Load font size table from the data <font size>.
548     The data has this form:
549         (FONT-SPEC RESIZE-FACTOR) ...
550     where FONT-SPEC has this form:
551         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
552     All elements of FONT-SPEC are symbols.  */
553
554 static int
555 load_font_resize_table ()
556 {
557   MDatabase *mdb;
558   MPlist *size_adjust_list, *plist, *pl, *elt;
559
560   font_resize_list = pl = mplist ();
561
562   mdb = mdatabase_find (Mfont, msymbol ("resize"), Mnil, Mnil);
563   if (! mdb)
564     return -1;
565   if (! (size_adjust_list = (MPlist *) mdatabase_load (mdb)))
566     MERROR (MERROR_FONT, -1);
567
568   MPLIST_DO (plist, size_adjust_list)
569     {
570       MFontResize *resize;
571       MSymbol registry;
572
573       MSTRUCT_CALLOC (resize, MERROR_FONT);
574
575       if (! MPLIST_PLIST_P (plist)
576           || (elt = MPLIST_PLIST (plist), mplist_length (elt) != 2)
577           || ! MPLIST_PLIST_P (elt))
578         MWARNING (MERROR_FONT);
579       registry = mfont__set_spec_from_plist (&resize->spec,
580                                              MPLIST_PLIST (elt));
581       elt = MPLIST_NEXT (elt);
582       if (! MPLIST_INTEGER_P (elt))
583         MWARNING (MERROR_FONT);
584       resize->resize = MPLIST_INTEGER (elt);
585
586       if (registry == Mnil)
587         registry = Mt;
588       pl = mplist_add (pl, registry, resize);
589       continue;
590
591     warning:
592       free (resize);
593     }
594
595   M17N_OBJECT_UNREF (size_adjust_list);
596   return 0;
597 }
598
599 /** Return a font encoding (and repertory) of FONT.  */
600
601 static MFontEncoding *
602 find_encoding (MFont *font)
603 {
604   MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
605   MFontEncoding *encoding = NULL;
606   MPlist *plist;
607
608   if (! font_encoding_list)
609     load_font_encoding_table ();
610   if (! MPLIST_TAIL_P (font_encoding_list))
611     while (1)
612       {
613         plist = font_encoding_list;
614         while (registry ? (plist = mplist_find_by_key (plist, registry))
615                : plist)
616           {
617             encoding = (MFontEncoding *) MPLIST_VAL (plist);
618             if (mfont__match_p (font, &encoding->spec, MFONT_ADSTYLE))
619               {
620                 if (! encoding->encoding_charset)
621                   encoding->encoding_charset
622                     = MCHARSET (encoding->encoding_name);
623                 if (! encoding->encoding_charset)
624                   {
625                     mplist_pop (plist);
626                     continue;
627                   }
628                 if (encoding->repertory_name == encoding->encoding_name)
629                   encoding->repertory_charset = encoding->encoding_charset;
630                 else if (encoding->repertory_name != Mnil)
631                   {
632                     encoding->repertory_charset
633                       = MCHARSET (encoding->repertory_name);
634                     if (! encoding->repertory_charset)
635                       {
636                         mplist_pop (plist);
637                         continue;
638                       }
639                   }
640                 return encoding;
641               }
642             else
643               plist = MPLIST_NEXT (plist);
644           }
645         if (registry == Mnil || registry == Mt)
646           break;
647         registry = Mt;
648       }
649   return &default_encoding;
650 }
651
652 /* XLFD parser/generator */
653
654 /** Indices to each field of split font name.  */
655
656 enum xlfd_field_idx
657   {
658     XLFD_FOUNDRY,
659     XLFD_FAMILY,
660     XLFD_WEIGHT,
661     XLFD_SLANT,
662     XLFD_SWIDTH,
663     XLFD_ADSTYLE,
664     XLFD_PIXEL,
665     XLFD_POINT,
666     XLFD_RESX,
667     XLFD_RESY,
668     XLFD_SPACING,
669     XLFD_AVGWIDTH,
670     XLFD_REGISTRY,              /* This contains ENCODING.  */
671     /* anchor */
672     XLFD_FIELD_MAX
673   };
674
675 static int
676 xlfd_parse_name (char *name, MFont *font)
677 {
678   char *field[XLFD_FIELD_MAX];
679   unsigned short size, resy;
680   MSymbol attrs[MFONT_PROPERTY_MAX];
681   char copy[513];
682   int i;
683   char *p;
684
685   if (name[0] != '-')
686     return -1;
687
688   field[0] = copy;
689   for (i = 1, p = copy, name++; *name; p++, name++)
690     {
691       if (p - copy > 512)
692         return -1;
693       if (*name == '-'
694           && i < XLFD_FIELD_MAX)
695         {
696           *p = '\0';
697           if (field[i - 1][0] == '*')
698             field[i - 1] = NULL;
699           field[i++] = p + 1;
700         }
701       else
702         *p = tolower (*name);
703     }
704   *p = '\0';
705   if (field[i - 1][0] == '*')
706     field[i - 1] = NULL;
707   while (i < XLFD_FIELD_MAX)
708     field[i++] = NULL;
709
710   resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0;
711   if (! field[XLFD_PIXEL])
712     size = field[XLFD_POINT] ? atoi (field[XLFD_POINT]) * resy / 72 : 0;
713   else if (field[XLFD_PIXEL][0] == '[')
714     {
715       /* The pixel size field specifies a transformation matrix of the
716          form "[A B C D]".  The XLFD spec says that the scalar value N
717          for the pixel size is equivalent to D.  */
718       char *p0 = field[XLFD_PIXEL] + 1, *p1;
719       double d;
720
721       for (i = 0; i < 4; i++, p0 = p1)
722         d = strtod (p0, &p1);
723       size = d * 10;
724     }
725   else
726     size = atoi (field[XLFD_PIXEL]) * 10;
727
728   attrs[MFONT_FOUNDRY]
729     = field[XLFD_FOUNDRY] ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
730   attrs[MFONT_FAMILY]
731     = field[XLFD_FAMILY] ? msymbol (field[XLFD_FAMILY]) : Mnil;
732   attrs[MFONT_WEIGHT]
733     = field[XLFD_WEIGHT] ? msymbol (field[XLFD_WEIGHT]) : Mnil;
734   attrs[MFONT_STYLE]
735     = field[XLFD_SLANT] ? msymbol (field[XLFD_SLANT]) : Mnil;
736   attrs[MFONT_STRETCH]
737     = field[XLFD_SWIDTH] ? msymbol (field[XLFD_SWIDTH]) : Mnil;
738   attrs[MFONT_ADSTYLE]
739     = field[XLFD_ADSTYLE] ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
740   attrs[MFONT_REGISTRY]
741     = field[XLFD_REGISTRY] ? msymbol (field[XLFD_REGISTRY]) : Mnil;
742   mfont__set_spec (font, attrs, size, resy);
743   return 0;
744 }
745
746 static char *
747 xlfd_unparse_name (MFont *font)
748 {
749   MSymbol prop[7];
750   char name[513];
751   char *str[7];
752   int len, i;
753   unsigned short size, resy;
754
755   prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
756   prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
757   prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
758   prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
759   prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
760   prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
761   prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
762   for (len = 0, i = 0; i < 7; i++)
763     {
764       if (prop[i] != Mnil)
765         {
766           str[i] = msymbol_name (prop[i]);
767           len += strlen (str[i]);
768         }
769       else
770         {
771           str[i] = "*";
772           len++;
773         }
774     }
775   if ((len
776        + 12                     /* 12 dashes */
777        + 3                      /* 3 asterisks */
778        + 30                     /* 3 integers (each 10 digits) */
779        + 1)                     /* '\0' terminal */
780       > 513)
781     return NULL;
782
783   size = (int) mfont_get_prop (font, Msize);
784   if ((size % 10) < 5)
785     size /= 10;
786   else
787     size = size / 10 + 1;
788   resy = (int) mfont_get_prop (font, Mresolution);
789
790   sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s",
791            str[0], str[1], str[2], str[3], str[4], str[5],
792            size, resy, resy,  str[6]);
793   return strdup (name);
794 }
795
796 \f
797 /* Internal API */
798
799 int
800 mfont__init ()
801 {
802   int i, shift;
803
804   Mfoundry = msymbol ("foundry");
805   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
806   Mfamily = msymbol ("family");
807   mfont__property_table[MFONT_FAMILY].property = Mfamily;
808   Mweight = msymbol ("weight");
809   mfont__property_table[MFONT_WEIGHT].property = Mweight;
810   Mstyle = msymbol ("style");
811   mfont__property_table[MFONT_STYLE].property = Mstyle;
812   Mstretch = msymbol ("stretch");
813   mfont__property_table[MFONT_STRETCH].property = Mstretch;
814   Madstyle = msymbol ("adstyle");
815   mfont__property_table[MFONT_ADSTYLE].property = Madstyle;
816   Mregistry = msymbol ("registry");
817   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
818
819   Msize = msymbol ("size");
820   Mresolution = msymbol ("resolution");
821
822   Mfontconfig = msymbol ("fontconfig");
823
824   /* The first entry of each mfont__property_table must be Mnil so
825      that actual properties get positive numeric numbers.  */
826   for (i = 0; i <= MFONT_REGISTRY; i++)
827     {
828       MLIST_INIT1 (&mfont__property_table[i], names, 8);
829       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
830     }
831
832   /* Register predefined font property names.  */
833   for (i = 0; i <= MFONT_REGISTRY; i++)
834     {
835       int j;
836
837       for (j = 0; j < font_common_names[i].num; j++)
838         {
839           MSymbol sym = msymbol (font_common_names[i].names[j]);
840
841           if (sym == Mnil)
842             return -1;
843           if (msymbol_put(sym, mfont__property_table[i].property,
844                           (void *) (j + 1)) < 0)
845             return -1;
846           MLIST_APPEND1 (&mfont__property_table[i], names, sym, MERROR_FONT);
847         }
848     }
849
850   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
851      of a score is a flag for a scalable font (see the documentation
852      of mfont_score).  */
853   i = FONT_SCORE_PRIORITY_SIZE - 1;
854   for (shift = 1; i >= 0; i--)
855     {
856       font_score_shift_bits[font_score_priority[i]] = shift;
857       if (font_score_priority[i] == MFONT_SIZE)
858         shift += 16;
859       else
860         shift += 2;
861     }
862
863   MFONT_INIT (&default_encoding.spec);
864   default_encoding.encoding_name = Mnil;
865   default_encoding.encoding_charset = NULL;
866   default_encoding.repertory_name = Mnil;
867   default_encoding.repertory_charset = NULL;
868   {
869     char *path, *buf;
870     int bufsize;
871
872     mfont_freetype_path = mplist ();
873     bufsize = strlen (M17NDIR) + 7;
874     buf = alloca (bufsize);
875     sprintf (buf, "%s/fonts", M17NDIR);
876     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
877     path = getenv ("M17NDIR");
878     if (path)
879       {
880         i = strlen (path) + 7;
881         if (i > bufsize)
882           buf = alloca (i);
883         sprintf (buf, "%s/fonts", path);
884         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
885       }
886   }
887
888 #ifdef HAVE_FREETYPE
889   if (mfont__ft_init () < 0)
890     return -1;
891 #endif /* HAVE_FREETYPE */
892   if (mfont__flt_init () < 0)
893     return -1;
894
895   return 0;
896 }
897
898 void
899 mfont__fini ()
900 {
901   MPlist *plist;
902   int i;
903
904   mfont__flt_fini ();
905 #ifdef HAVE_FREETYPE
906   mfont__ft_fini ();
907 #endif /* HAVE_FREETYPE */
908
909   MPLIST_DO (plist, mfont_freetype_path)
910     free (MPLIST_VAL (plist));
911   M17N_OBJECT_UNREF (mfont_freetype_path);
912
913   if (font_resize_list)
914     {
915       MPLIST_DO (plist, font_resize_list)
916         free (MPLIST_VAL (plist));
917       M17N_OBJECT_UNREF (font_resize_list);
918       font_resize_list = NULL;
919     }
920   if (font_encoding_list)
921     {
922       MPLIST_DO (plist, font_encoding_list)
923         free (MPLIST_VAL (plist));
924       M17N_OBJECT_UNREF (font_encoding_list);
925       font_encoding_list = NULL;
926     }
927   for (i = 0; i <= MFONT_REGISTRY; i++)
928     MLIST_FREE1 (&mfont__property_table[i], names);
929 }
930
931 void
932 mfont__free_realized (MRealizedFont *rfont)
933 {
934   M17N_OBJECT_UNREF (rfont->info);
935   free (rfont);
936 }
937
938
939 /* Compare FONT with REQUEST and return how much they differs.  If
940    FONT does not match with SPEC, return -1.  */
941
942 int
943 mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size)
944 {
945   int score = 0;
946   int i = FONT_SCORE_PRIORITY_SIZE;
947
948   while (--i >= 0)
949     {
950       enum MFontProperty prop = font_score_priority[i];
951
952       if (request->property[prop] != 0)
953         {
954           int val = 0;
955
956           if (spec->property[prop] && font->property[prop]
957               && font->property[prop] != spec->property[prop])
958             return -1;
959           if (font->property[prop])
960             val = abs (font->property[prop] - request->property[prop]);
961           if (prop == MFONT_SIZE)
962             {
963               if (font->property[MFONT_RESY] == 0)
964                 /* This is a scalable font.  We prefer a bitmap font
965                    if the size matches exactly.  */
966                 score |= 1;
967               else
968                 score |= (val << font_score_shift_bits[MFONT_SIZE]
969                           | ((limited_size && val > 0) ? 0x400000 : 0));
970             }
971           else
972             score |= (val > 3 ? 3 : val) << font_score_shift_bits[prop];
973         }
974     }
975   return score;
976 }
977
978
979 /** Return 1 iff FONT matches SPEC.  */
980
981 int
982 mfont__match_p (MFont *font, MFont *spec, int prop)
983 {
984   for (; prop >= 0; prop--)
985     if (spec->property[prop] && font->property[prop]
986         && font->property[prop] != spec->property[prop])
987       return 0;
988   return 1;
989 }
990
991
992 void
993 mfont__set_spec_from_face (MFont *spec, MFace *face)
994 {
995   int i;
996
997   for (i = 0; i <= MFONT_ADSTYLE; i++)
998     mfont__set_property (spec, i, face->property[i]);
999   /* The value 1 is "iso8859-1".  */
1000   spec->property[MFONT_REGISTRY] = 1;
1001   spec->property[MFONT_SIZE] = (int) (face->property[MFACE_SIZE]);
1002   spec->property[MFONT_RESY] = 0;
1003 }
1004
1005
1006 extern MSymbol
1007 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
1008 {
1009   int i;
1010   MSymbol spec_list[MFONT_REGISTRY + 1];
1011   MSymbol registry;
1012
1013   MFONT_INIT (spec);
1014   memset (spec_list, 0, sizeof spec_list);
1015   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
1016     {
1017       if (! MPLIST_SYMBOL_P (plist))
1018         MERROR (MERROR_FONT, Mnil);     
1019       spec_list[i] = MPLIST_SYMBOL (plist);
1020     }
1021   registry = spec_list[i - 1];
1022   mfont__set_property (spec, MFONT_REGISTRY, registry);
1023   for (i -= 2; i >= 0; i--)
1024     mfont__set_property (spec, i, spec_list[i]);
1025   return registry;
1026 }
1027
1028 MRealizedFont *
1029 mfont__select (MFrame *frame, MFont *spec, MFont *request, int limited_size,
1030                MSymbol layouter)
1031 {
1032   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1033   MPlist *plist;
1034   MRealizedFont *best;
1035   int i;
1036   int mdebug_mask = MDEBUG_FONT;
1037
1038   if (registry == Mnil)
1039     registry = Mt;
1040
1041   MPLIST_DO (plist, frame->realized_font_list)
1042     {
1043       best = MPLIST_VAL (plist);
1044       if (MPLIST_KEY (plist) == registry
1045           && ! memcmp (&best->spec, spec, sizeof (MFont))
1046           && ! memcmp (&best->request, request, sizeof (MFont)))
1047         {
1048           if (best->layouter != layouter)
1049             {
1050               MRealizedFont *copy;
1051
1052               MSTRUCT_MALLOC (copy, MERROR_FONT);
1053               *copy = *best;
1054               copy->layouter = layouter;
1055               mplist_add (frame->realized_font_list, registry, copy);
1056               if (copy->info)
1057                 M17N_OBJECT_REF (copy->info);
1058               best = copy;
1059             }
1060           return best;
1061         }
1062     }
1063
1064   MDEBUG_PUSH_TIME ();
1065   best = NULL;
1066   MPLIST_DO (plist, frame->font_driver_list)
1067     {
1068       MFontDriver *driver = MPLIST_VAL (plist);
1069       MRealizedFont *this
1070         = (driver->select) (frame, spec, request, limited_size);
1071
1072       if (this)
1073         {
1074           this->driver = driver;
1075           if (! best
1076               || this->score < best->score)
1077             {
1078               if (best)
1079                 mfont__free_realized (best);
1080               best = this;
1081               if (this->score == 0)
1082                 break;
1083             }
1084           else
1085             mfont__free_realized (this);
1086         }
1087     }
1088
1089   if (mdebug__flag & mdebug_mask)
1090     {
1091       char buf1[256], buf2[256];
1092       MFont font = *spec;
1093
1094       for (i = 0; i < MFONT_PROPERTY_MAX; i++)
1095         if (! font.property[i])
1096           font.property[i] = request->property[i];
1097       gen_font_name (buf2, &font);
1098
1099       if (best)
1100         MDEBUG_PRINT_TIME ("FONT", 
1101                            (stderr, " to select <%s> (%x)from <%s>.",
1102                             gen_font_name (buf1, &best->font),
1103                             best->score,
1104                             buf2));
1105       else
1106         MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
1107       MDEBUG_POP_TIME ();
1108     }
1109
1110   if (! best)
1111     return NULL;
1112   best->layouter = layouter;
1113   mplist_add (frame->realized_font_list, registry, best);
1114   return best;
1115 }
1116
1117
1118 /** Open a font specified in RFONT.  Return 0 if successfully
1119     opened, otherwise return -1.  */
1120
1121 int
1122 mfont__open (MRealizedFont *rfont)
1123 {
1124   return (rfont->driver->open) (rfont);
1125 }
1126
1127 void
1128 mfont__resize (MFont *spec, MFont *request)
1129 {
1130   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1131   MFontResize *resize;
1132   MPlist *plist;
1133
1134   if (! font_resize_list)
1135     load_font_resize_table ();
1136   if (! MPLIST_TAIL_P (font_resize_list))
1137     while (1)
1138       {
1139         plist = font_resize_list;
1140         while (registry ? (plist = mplist_find_by_key (plist, registry))
1141                : plist)
1142           {
1143             resize = (MFontResize *) MPLIST_VAL (plist);
1144             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1145               {
1146                 request->property[MFONT_SIZE]
1147                   = request->property[MFONT_SIZE] * resize->resize / 100;
1148                 return;
1149               }
1150             plist = MPLIST_NEXT (plist);
1151           }
1152         if (registry == Mt)
1153           break;
1154         registry = Mt;
1155       }
1156 }
1157
1158 /* Return 1 if C is encodable, 0, if C is not encodable, -1 if it
1159    can't be decided now.  */
1160
1161 int
1162 mfont__encodable_p (MRealizedFont *rfont, MSymbol layouter_name, int c)
1163 {
1164   MFontEncoding *encoding;
1165
1166   if (layouter_name != Mnil)
1167     return (mfont__flt_encode_char (layouter_name, c)
1168             != MCHAR_INVALID_CODE);
1169   if (! rfont->encoding)
1170     rfont->encoding = find_encoding (&rfont->spec);
1171   encoding = rfont->encoding;
1172   if (! encoding->repertory_charset)
1173     return -1;
1174   return (ENCODE_CHAR (encoding->repertory_charset, c) != MCHAR_INVALID_CODE);
1175 }
1176
1177 unsigned
1178 mfont__encode_char (MRealizedFont *rfont, int c)
1179 {
1180   MFontEncoding *encoding;
1181   unsigned code;
1182
1183   if (rfont->layouter != Mnil)
1184     return mfont__flt_encode_char (rfont->layouter, c);
1185   if (! rfont->encoding)
1186     rfont->encoding = find_encoding (&rfont->font);
1187   encoding = rfont->encoding;
1188   if (! encoding->encoding_charset)
1189     return MCHAR_INVALID_CODE;
1190   code = ENCODE_CHAR (encoding->encoding_charset, c);
1191   if (code == MCHAR_INVALID_CODE)
1192     return MCHAR_INVALID_CODE;
1193   if (! encoding->repertory_charset)
1194     return (rfont->driver->encode_char) (rfont, c, code);
1195   if (ENCODE_CHAR (encoding->repertory_charset, c) == MCHAR_INVALID_CODE)
1196     return MCHAR_INVALID_CODE;
1197   return code;
1198 }
1199
1200 void
1201 mfont__get_metric (MGlyphString *gstring, int from, int to)
1202 {
1203   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1204   MRealizedFont *rfont = from_g->rface->rfont;
1205
1206   for (g = from_g; g != to_g; g++)
1207     if (g->rface->rfont != rfont)
1208       {
1209         int idx = GLYPH_INDEX (g);
1210
1211         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1212         from_g = g;
1213         rfont = g->rface->rfont;
1214         from = idx;
1215       }
1216   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1217 }
1218
1219
1220 void
1221 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1222 {
1223   int numeric;
1224
1225   if (val == Mnil)
1226     numeric = 0;
1227   else
1228     {
1229       numeric = FONT_PROPERTY_NUMERIC (val, key);
1230       if (! numeric)
1231         {
1232           numeric = mfont__property_table[key].used;
1233           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1234           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1235         }
1236     }
1237   font->property[key] = numeric;
1238 }
1239
1240 void
1241 mfont__set_spec (MFont *font, MSymbol *attrs,
1242                  unsigned short size, unsigned short resy)
1243 {
1244   int i;
1245
1246   for (i = 0; i <= MFONT_REGISTRY; i++)
1247     mfont__set_property (font, i, attrs[i]);
1248   font->property[MFONT_SIZE] = size;
1249   font->property[MFONT_RESY] = resy;
1250 }
1251
1252 int
1253 mfont__parse_name_into_font (char *name, MSymbol format, MFont *font)
1254 {
1255   int result = -1;
1256
1257   if (format == Mx || format == Mnil)
1258     result = xlfd_parse_name (name, font);
1259 #ifdef HAVE_FONTCONFIG
1260   if (format == Mfontconfig || (! result && format == Mnil))
1261     result = mfont__ft_parse_name (name, font);
1262 #endif
1263   return result;
1264 }
1265
1266 /*** @} */
1267 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1268
1269 \f
1270
1271 /* External API */
1272
1273 /*** @addtogroup m17nFont */
1274 /*** @{ */
1275 /*=*/
1276
1277 /***en @name Variables: Keys of font property.  */
1278 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1279 /*** @{ */
1280 /*=*/
1281
1282 /***en
1283     @brief Key of font property specifying foundry.
1284
1285     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1286     is used as a key of font property and face property.  The property
1287     value must be a symbol whose name is a foundry name of a font.  */
1288 /***ja
1289     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1290     
1291     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1292     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1293     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1294     */
1295
1296 MSymbol Mfoundry;
1297
1298 /***en
1299     @brief Key of font property specifying family.
1300
1301     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1302     used as a key of font property and face property.  The property
1303     value must be a symbol whose name is a family name of a font.  */ 
1304 /***ja
1305     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1306     
1307     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1308     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1309     ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1310     */
1311
1312 MSymbol Mfamily;
1313
1314 /***en
1315     @brief Key of font property specifying weight.
1316
1317     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1318     used as a key of font property and face property.  The property
1319     value must be a symbol whose name is a weight name of a font (e.g
1320     "medium", "bold").  */ 
1321 /***ja
1322     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1323     
1324     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1325     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1326     ¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1327     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1328     */
1329
1330 MSymbol Mweight;
1331
1332 /***en
1333     @brief Key of font property specifying style.
1334
1335     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1336     used as a key of font property and face property.  The property
1337     value must be a symbol whose name is a style name of a font (e.g
1338     "r", "i", "o").  */ 
1339 /***ja
1340     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1341     
1342     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1343     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1344     ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1345     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1346     */
1347
1348 MSymbol Mstyle;
1349
1350 /***en
1351     @brief Key of font property specifying stretch.
1352
1353     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1354     is used as a key of font property and face property.  The property
1355     value must be a symbol whose name is a stretch name of a font (e.g
1356     "normal", "condensed").  */ 
1357 /***ja
1358     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1359     
1360     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1361     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1362     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1363     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1364     */
1365
1366 MSymbol Mstretch;
1367
1368 /***en
1369     @brief Key of font property specifying additional style.
1370
1371     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1372     is used as a key of font property and face property.  The property
1373     value must be a symbol whose name is an additional style name of a
1374     font (e.g "serif", "", "sans").  */ 
1375 /***ja
1376     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1377     
1378     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1379     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1380     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1381     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1382     */
1383
1384 MSymbol Madstyle;
1385
1386 /***en
1387     @brief Key of font property specifying registry.
1388
1389     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1390     and is used as a key of font property.  The property value must be
1391     a symbol whose name is a registry name a font registry
1392     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1393 /***ja
1394     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1395     
1396     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
1397     ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
1398     ¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" Åù) ¤ò̾Á°¤È¤·
1399     ¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1400     */
1401
1402 MSymbol Mregistry;
1403
1404 /***en
1405     @brief Key of font property specifying size.
1406
1407     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1408     used as a key of font property and face property.  The property
1409     value must be an integer specifying a font design size in the unit
1410     of 1/10 point (on 100 dpi display).  */ 
1411 /***ja
1412     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1413     
1414     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©
1415     ¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1416     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó
1417     ¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1418     */
1419
1420 MSymbol Msize;
1421
1422 /***en
1423     @brief Key of font property specifying resolution.
1424
1425     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1426     is used as a key of font property and face property.  The property
1427     value must be an integer to specifying a font resolution in the
1428     unit of dots per inch (dpi).  */ 
1429 /***ja
1430     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1431     
1432     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü
1433     ¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é
1434     ¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ô
1435     ÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1436     */
1437
1438 MSymbol Mresolution;
1439
1440 /***en
1441     @brief Symobl of name "fontconfig".
1442
1443     The variable #Mfontconfig is to be used as an argument of the
1444     functions mfont_parse_name () and mfont_unparse_name ().  */
1445
1446 MSymbol Mfontconfig;
1447
1448 /*=*/
1449 /*** @} */
1450 /*=*/
1451
1452 /***en
1453     @brief List of font files and directories that contain font files.
1454
1455     The variable @c mfont_freetype_path is a plist of FreeType font
1456     files and directories that contain FreeType font files.  Key of
1457     the element is @c Mstring, and the value is a string that
1458     represents a font file or a directory.
1459
1460     The macro M17N_INIT () sets up this variable to contain the
1461     sub-directory "fonts" of the m17n database and the environment
1462     variable "M17NDIR".  The first call of mframe () creates the
1463     internal list of the actually available fonts from this variable.
1464     Thus, an application program, if necessary, must modify the
1465     variable before calling mframe ().  If it is going to add a new
1466     element, value must be a string that can be safely freed.
1467
1468     If the m17n library is not configured to use the FreeType library,
1469     this variable is not used.  */
1470 /***ja
1471     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
1472
1473     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë
1474     ¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring ¤Ç¤¢
1475     ¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
1476
1477     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ
1478      ¿ô "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
1479      mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©
1480      ¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢
1481      mframe () ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê
1482      ¤¤¡£¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó
1483      ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1484
1485     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì
1486     ¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
1487
1488 MPlist *mfont_freetype_path;
1489
1490 /*=*/
1491
1492 /***en
1493     @brief Create a new font.
1494
1495     The mfont () function creates a new font object that has no
1496     property.
1497
1498     @return
1499     This function returns a pointer to the created font object.  */
1500 /***ja
1501     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
1502
1503     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯
1504     ¥È¤òºî¤ë¡£
1505
1506     @return
1507     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
1508
1509 MFont *
1510 mfont ()
1511 {
1512   MFont *font;
1513
1514   MSTRUCT_CALLOC (font, MERROR_FONT);
1515   return font;
1516 }
1517
1518 /*=*/
1519
1520 /***en
1521     @brief Create a font by parsing a fontname.
1522
1523     The mfont_parse_name () function creates a new font object.  The
1524     properties are extracted fontname $NAME.
1525
1526     $FORMAT specifies the format of $NAME.  If $FORMAT is #Mx, $NAME
1527     is parsed as XLFD (X Logical Font Description).  If $FORMAT is
1528     #Mfontconfig, $NAME is parsed as Fontconfig's textual
1529     representation of font.  If $FORMAT is #Mnil, $NAME is at first
1530     parsed as XLFD, and it it fails, parsed as Fontconfig's
1531     representation.
1532
1533     @return
1534     If the operation was successful, this function returns a pointer
1535     to the created font.  Otherwise it returns @c NULL.  */
1536
1537 /***ja
1538     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1539
1540     ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
1541     ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
1542
1543     $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
1544     $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1545     $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­
1546     ¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD ¤Ë
1547     ½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1548
1549     @return
1550     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
1551     ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
1552
1553 MFont *
1554 mfont_parse_name (char *name, MSymbol format)
1555 {
1556   MFont template, *font;
1557   
1558   MFONT_INIT (&template);
1559   if (mfont__parse_name_into_font (name, format, &template) < 0)
1560     MERROR (MERROR_FONT, NULL);
1561   MSTRUCT_CALLOC (font, MERROR_FONT);
1562   *font = template;
1563   return font;
1564 }
1565
1566 /*=*/
1567
1568 /***en
1569     @brief Create a fontname from a font.
1570
1571     The mfont_unparse_name () function creates a fontname string
1572     from font $FONT according to $FORMAT.
1573
1574     $FORMAT must be #Mx or #Mfontconfig.  If it is #Mx, the fontname
1575     is in XLFD (X Logical Font Description) format.  If it is
1576     #Mfontconfig, the fontname is in the style of Fontconfig's text
1577     representation.
1578
1579     @return
1580     This function returns a newly allocated fontname string, which is
1581     not freed unless the user explicitly does so by free ().  */
1582
1583 /***ja
1584     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1585
1586     ´Ø¿ô mfont_unparse_name () ¤Ï $FORMAT ¤Ë¤·¤¿¤¬¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»ú
1587     Îó¤ò¥Õ¥©¥ó¥È$FONT ¤ò¸µ¤Ëºî¤ë¡£
1588
1589     $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£#Mx ¤Ê¤é¤Ð¥Õ¥©
1590     ¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£#Mfontconfig ¤Ê
1591     ¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
1592
1593     @return 
1594     ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢
1595     ¥æ¡¼¥¶¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
1596
1597 char *
1598 mfont_unparse_name (MFont *font, MSymbol format)
1599 {
1600   char *name;
1601
1602   if (format == Mx)
1603     name = xlfd_unparse_name (font);
1604 #ifdef HAVE_FONTCONFIG
1605   else if (format == Mfontconfig)
1606     name = mfont__ft_unparse_name (font);
1607 #endif
1608   else
1609     MERROR (MERROR_FONT, NULL);
1610   return name;
1611 }
1612
1613 /*=*/
1614
1615 /***en
1616     @brief Make a copy of a font.
1617
1618     The mfont_copy () function returns a new copy of font $FONT.  */
1619 /***ja
1620     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
1621
1622     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
1623
1624 MFont *
1625 mfont_copy (MFont *font)
1626 {
1627   MFont *copy;
1628
1629   MSTRUCT_MALLOC (copy, MERROR_FONT);
1630   *copy = *font;
1631   return copy;
1632 }
1633
1634 /*=*/
1635
1636 /***en
1637     @brief Get a property value of a font.
1638
1639     The mfont_get_prop () function gets the value of $KEY property of
1640     font $FONT.  $KEY must be one of the following symbols:
1641
1642         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1643         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1644
1645     @return
1646     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1647     Madstyle, or @c Mregistry, this function returns the
1648     corresponding value as a symbol.  If the font does not have $KEY
1649     property, it returns @c Mnil.
1650     If $KEY is @c Msize or @c Mresolution, this function returns the
1651     corresponding value as an integer.  If the font does not have $KEY
1652     property, it returns 0.
1653     If $KEY is something else, it returns @c NULL and assigns an error
1654     code to the external variable #merror_code.  */
1655
1656 /***ja
1657     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1658
1659     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
1660     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
1661     ¤Ð¤Ê¤é¤Ê¤¤¡£
1662
1663         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1664         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1665
1666     @return 
1667     $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1668     Madstyle, @c Mregistry ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È
1669     ¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c Mnil ¤òÊÖ¤¹¡£
1670     $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò
1671     ¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤ò
1672     ÊÖ¤¹¡£
1673     $KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
1674     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1675
1676 void *
1677 mfont_get_prop (MFont *font, MSymbol key)
1678 {
1679   if (key == Mfoundry)
1680     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
1681   if (key == Mfamily)
1682     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
1683   if (key == Mweight)
1684     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
1685   if (key == Mstyle)
1686     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
1687   if (key == Mstretch)
1688     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
1689   if (key == Madstyle)
1690     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
1691   if (key == Mregistry)
1692     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
1693   if (key == Msize)
1694     {
1695       int size = font->property[MFONT_SIZE];
1696       return (void *) size;
1697     }
1698   if (key == Mresolution)
1699     {
1700       int resy = font->property[MFONT_RESY];
1701       return (void *) resy;
1702     }
1703
1704   MERROR (MERROR_FONT, NULL);
1705 }
1706
1707
1708 /*=*/
1709 /***en
1710     @brief Put a property value to a font.
1711
1712     The mfont_put_prop () function puts a font property whose key is
1713     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
1714     following symbols:
1715
1716         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1717         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1718
1719     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
1720     Otherwise, $VAL must be a symbol.  */
1721 /***ja
1722     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
1723
1724     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY ¤Ç¤¢¤ë¥×¥í
1725     ¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢
1726     ¤ë¡£
1727
1728         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1729         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1730
1731     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ
1732     ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
1733
1734 int
1735 mfont_put_prop (MFont *font, MSymbol key, void *val)
1736 {
1737   if (key == Mfoundry)
1738     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
1739   else if (key == Mfamily)
1740     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
1741   else if (key == Mweight)
1742     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
1743   else if (key == Mstyle)
1744     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
1745   else if (key == Mstretch)
1746     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
1747   else if (key == Madstyle)
1748     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
1749   else if (key == Mregistry)
1750     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
1751   else if (key == Msize)
1752     {
1753       unsigned size = (unsigned) val;
1754       font->property[MFONT_SIZE] = size;
1755     }
1756   else if (key == Mresolution)
1757     {
1758       unsigned resy = (unsigned) val;
1759       font->property[MFONT_RESY] =  resy;
1760     }
1761   else
1762     MERROR (MERROR_FONT, -1);
1763   return 0;
1764 }
1765
1766 /*=*/
1767
1768 /***en
1769     @brief Return the font selection priority.
1770
1771     The mfont_selection_priority () function returns a newly created
1772     array of six symbols.  The elements are the following
1773     keys of font properties ordered by priority.
1774
1775         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1776         @c Madstyle, @c Msize.
1777
1778    The m17n library selects the best matching font according to the
1779    order of this array.  A font that has a different value for a
1780    property of lower priority is preferred to a font that has a
1781    different value for a property of higher priority.  */
1782 /***ja
1783     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÊÖ¤¹.
1784
1785     ´Ø¿ô mfont_selection_priority () ¤Ï6¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã
1786     ¤ÆÊÖ¤¹¡£ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤ËÊÂ
1787     ¤Ù¤¿¤â¤Î¤Ç¤¢¤ë¡£
1788
1789         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1790         @c Madstyle, @c Msize.
1791
1792    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
1793    Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬°ã¤¦¥Õ¥©¥ó¥È¤ÈÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤Î
1794    Ãͤ¬°ã¤¦¥Õ¥©¥ó¥È¤¬¤¢¤ë¾ì¹ç¡¢Á°¼Ô¤¬ÁªÂò¤µ¤ì¤ë¡£
1795    */
1796
1797 MSymbol *
1798 mfont_selection_priority ()
1799 {
1800   MSymbol *keys;
1801   int i;
1802
1803   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
1804   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1805     {
1806       enum MFontProperty prop = font_score_priority[i];
1807
1808       if (prop == MFONT_SIZE)
1809         keys[i] = Msize;
1810       else if (prop == MFONT_ADSTYLE)
1811         keys[i] = Madstyle;
1812       else if (prop == MFONT_FAMILY)
1813         keys[i] = Mfamily;
1814       else if (prop == MFONT_WEIGHT)
1815         keys[i] = Mweight;
1816       else if (prop == MFONT_STYLE)
1817         keys[i] = Mstyle;
1818       else if (prop == MFONT_STRETCH)
1819         keys[i] = Mstretch;
1820       else
1821         keys[i] = Mfoundry;
1822     }
1823   return keys;
1824 }
1825
1826 /*=*/
1827
1828 /***en
1829     @brief Set the font selection priority.
1830
1831     The mfont_set_selection_priority () function sets font selection
1832     priority according to $KEYS, which is an array of six symbols.
1833     Each element must be one of the below.  No two elements must be
1834     the same.
1835
1836         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1837         @c Madstyle, @c Msize.
1838
1839     See the documentation of the function mfont_selection_priority ()
1840     for details.  */
1841 /***ja
1842     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
1843
1844     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
1845     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£³ÆÍ×ÁǤϰʲ¼¤Î¤¦¤Á¤Î¤É¤ì
1846     ¤«¤Ç¤¢¤ê¡¢Á´¤Æ°Û¤Ê¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1847
1848         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1849         @c Madstyle, @c Msize.
1850
1851     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
1852      */
1853
1854 int
1855 mfont_set_selection_priority (MSymbol *keys)
1856 {
1857   int priority[FONT_SCORE_PRIORITY_SIZE];
1858   int i, j;
1859
1860   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
1861     {
1862       enum MFontProperty prop;
1863
1864       if (*keys == Msize)
1865         prop = MFONT_SIZE;
1866       else if (*keys == Madstyle)
1867         prop = MFONT_ADSTYLE;
1868       else if (*keys == Mfamily)
1869         prop = MFONT_FAMILY;
1870       else if (*keys == Mweight)
1871         prop = MFONT_WEIGHT;
1872       else if (*keys == Mstyle)
1873         prop = MFONT_STYLE;
1874       else if (*keys == Mstretch)
1875         prop = MFONT_STRETCH;
1876       else if (*keys == Mfoundry)
1877         prop = MFONT_FOUNDRY;
1878       else
1879         /* Invalid element.  */
1880         return -1;
1881       for (j = 0; j < i; j++)
1882         if (priority[j] == prop)
1883           /* Duplicated element.  */
1884           return -1;
1885       priority[i] = prop;
1886     }
1887   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1888     font_score_priority[i] = priority[i];
1889   return 0;
1890 }
1891
1892 /*=*/
1893
1894 /***en
1895     @brief Find a font.
1896
1897     The mfont_find () function returns a pointer to the available font
1898     that matches best the specification $SPEC on frame $FRAME.
1899
1900     $SCORE, if not NULL, must point to a place to store the score
1901     value that indicates how well the found font matches to $SPEC.  The
1902     smaller score means a better match.  */
1903 /***ja
1904     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
1905
1906     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC ¤Ë¤â¤Ã
1907     ¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
1908
1909     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC ¤Ë¤É¤ì¤Û¤É¹ç¤Ã
1910     ¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥¹¥³¥¢¤¬¾®¤µ
1911     ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1912     */
1913
1914 MFont *
1915 mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
1916 {
1917   MFont spec_copy;
1918   MRealizedFont *rfont;
1919
1920   MFONT_INIT (&spec_copy);
1921   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
1922
1923   rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
1924   if (!rfont)
1925     return NULL;
1926   if (score)
1927     *score = rfont->score;
1928   return &rfont->font;
1929 }
1930
1931 /*=*/
1932 /***en
1933     @brief Set encoding of a font.
1934
1935     The mfont_set_encoding () function sets the encoding information
1936     of font $FONT.
1937
1938     $ENCODING_NAME is a symbol representing a charset that has the
1939     same encoding as the font.
1940
1941     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
1942     has the same repertory as the font.  If it is @c Mnil, whether a
1943     specific character is supported by the font is asked to each font
1944     driver.
1945
1946     @return
1947     If the operation was successful, this function returns 0.
1948     Otherwise it returns -1 and assigns an error code to the external
1949     variable #merror_code.  */
1950 /***ja
1951     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
1952
1953     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó
1954     ¤òÀßÄꤹ¤ë¡£
1955
1956     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò
1957     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1958
1959     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó
1960     ¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ
1961     »ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤Ë
1962     Ì䤤¹ç¤ï¤»¤ë¡£
1963
1964     @return
1965     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°
1966     ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1967
1968
1969 int
1970 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
1971 {
1972   MCharset *encoding_charset = MCHARSET (encoding_name);
1973   MCharset *repertory_charset;
1974   MSymbol registry;
1975   MFontEncoding *encoding;
1976   MPlist *plist;
1977
1978   if (! encoding_charset)
1979     MERROR (MERROR_FONT, -1);
1980   if (repertory_name != Mnil)
1981     {
1982       repertory_charset = MCHARSET (repertory_name);
1983       if (! repertory_charset)
1984         MERROR (MERROR_FONT, -1);
1985     }
1986   else
1987     repertory_charset = NULL;
1988
1989   MSTRUCT_CALLOC (encoding, MERROR_FONT);
1990   encoding->spec = *font;
1991   encoding->encoding_name = encoding_name;
1992   encoding->encoding_charset = encoding_charset;
1993   encoding->repertory_name = repertory_name;
1994   encoding->repertory_charset = repertory_charset;
1995   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
1996   if (registry == Mnil)
1997     registry = Mt;
1998   if (! font_encoding_list)
1999     load_font_encoding_table ();
2000   mplist_push (font_encoding_list, registry, encoding);
2001   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
2002     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
2003                   sizeof (MFont)))
2004       {
2005         mplist_pop (plist);
2006         break;
2007       }
2008   return 0;
2009 }
2010
2011 /*=*/
2012
2013 /***en
2014     @brief Create a fontname from a font.
2015
2016     This function is obsolete.   Use mfont_unparse_name instead. */
2017 /***ja
2018     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2019
2020     ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
2021
2022 char *
2023 mfont_name (MFont *font)
2024 {
2025   return mfont_unparse_name (font, Mx);
2026 }
2027
2028 /*=*/
2029
2030 /***en
2031     @brief Create a new font from fontname.
2032
2033     This function is obsolete.  Use mfont_parse_name () instead.  */
2034
2035 /***ja
2036     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2037
2038     ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
2039
2040 MFont *
2041 mfont_from_name (char *name)
2042 {
2043   return mfont_parse_name (name, Mx);
2044 }
2045
2046 /*** @} */
2047
2048 /*** @addtogroup m17nDebug */
2049 /*=*/
2050 /*** @{ */
2051
2052 /***en
2053     @brief Dump a font.
2054
2055     The mdebug_dump_font () function prints font $FONT in a human readable
2056     way to the stderr.
2057
2058     @return
2059     This function returns $FONT.  */
2060 /***ja
2061     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
2062
2063     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr ¤Ë¿Í´Ö¤Ë²ÄÆɤÊ
2064     ·Á¤Ç°õºþ¤¹¤ë¡£
2065
2066     @return
2067     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
2068
2069 MFont *
2070 mdebug_dump_font (MFont *font)
2071 {
2072   char *name;
2073   
2074   name = mfont_unparse_name (font, Mx);
2075   if (name)
2076     {
2077       fprintf (stderr, "%s", name);
2078       free (name);
2079     }
2080   return font;
2081 }
2082
2083 /*** @} */
2084
2085 /*
2086   Local Variables:
2087   coding: euc-japan
2088   End:
2089 */