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