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