240
ft_gen_font (FT_Face ft_face)
250
if (FT_IS_SCALABLE (ft_face))
251
size = ft_face->size->metrics.y_ppem;
252
else if (ft_face->num_fixed_sizes == 0)
255
size = ft_face->available_sizes[0].height;
257
MSTRUCT_CALLOC (ft_info, MERROR_FONT_FT);
258
font = &ft_info->font;
259
STRDUP_LOWER (buf, bufsize, ft_face->family_name);
260
family = msymbol (buf);
261
mfont__set_property (font, MFONT_FAMILY, family);
262
mfont__set_property (font, MFONT_WEIGHT, Mmedium);
263
mfont__set_property (font, MFONT_STYLE, Mr);
264
mfont__set_property (font, MFONT_STRETCH, Mnormal);
265
mfont__set_property (font, MFONT_ADSTYLE, Mnull);
266
mfont__set_property (font, MFONT_REGISTRY, Municode_bmp);
267
font->size = size * 10;
268
font->type = MFONT_TYPE_OBJECT;
269
font->source = MFONT_SOURCE_FT;
272
stylename = ft_face->style_name;
277
for (i = 0; i < ft_to_prop_size; i++)
278
if (! strncasecmp (ft_to_prop[i].ft_style, stylename,
281
mfont__set_property (font, ft_to_prop[i].prop,
282
msymbol (ft_to_prop[i].val));
283
stylename += ft_to_prop[i].len;
286
if (i == ft_to_prop_size)
288
char *p1 = stylename + 1;
291
while (*p1 >= 'a' && *p1 <= 'z') p1++;
292
sym = msymbol__with_len (stylename, p1 - stylename);
293
for (i = MFONT_WEIGHT; i <= MFONT_STRETCH; i++)
294
if (msymbol_get (sym, mfont__property_table[i].property))
296
mfont__set_property (font, i, sym);
301
while (*stylename && ! isalpha (*stylename))
227
307
#ifdef HAVE_FONTCONFIG
406
491
MFontFT *ft_info;
408
493
MSTRUCT_CALLOC (ft_info, MERROR_FONT_FT);
409
fc_parse_pattern (pat, family, &ft_info->font);
494
fc_parse_pattern (pat, family, ft_info);
410
495
ft_info->font.type = MFONT_TYPE_OBJECT;
500
fc_init_font_list (void)
502
FcPattern *pattern = FcPatternCreate ();
503
FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, NULL);
504
FcFontSet *fs = FcFontList (fc_config, pattern, os);
505
MPlist *plist = mplist ();
510
ft_font_list = plist;
511
for (i = 0; i < fs->nfont; i++)
515
if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0,
516
(FcChar8 **) &fam) != FcResultMatch)
518
STRDUP_LOWER (buf, bufsize, fam);
519
plist = mplist_add (plist, msymbol (buf), NULL);
521
FcFontSetDestroy (fs);
522
FcObjectSetDestroy (os);
523
FcPatternDestroy (pattern);
527
fc_list_pattern (FcPattern *pattern)
529
FcObjectSet *os = NULL;
530
FcFontSet *fs = NULL;
531
MSymbol last_family = Mnil;
532
MPlist *plist = NULL, *pl = NULL;
537
if (! (os = FcObjectSetBuild (FC_FAMILY, FC_FILE, NULL)))
539
if (! (fs = FcFontList (fc_config, pattern, os)))
542
for (i = 0; i < fs->nfont; i++)
544
MSymbol family, file;
545
char *fam, *filename;
548
if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0,
549
(FcChar8 **) &fam) != FcResultMatch)
551
if (FcPatternGetString (fs->fonts[i], FC_FILE, 0,
552
(FcChar8 **) &filename) != FcResultMatch)
554
STRDUP_LOWER (buf, bufsize, fam);
555
family = msymbol (buf);
556
file = msymbol (filename);
557
if (family != last_family)
559
pl = MPLIST_PLIST (ft_list_family (family, 0));
560
last_family = family;
562
ft_info = mplist_get (pl, file);
567
mplist_add (plist, family, ft_info);
572
if (fs) FcFontSetDestroy (fs);
573
if (os) FcObjectSetDestroy (os);
577
/* Return FcCharSet object built from CHAR_LIST or MT. In the latter
578
case, it is assured that the M-text contains at least one
582
fc_build_charset (MPlist *char_list, MText *mt)
584
FcCharSet *cs = FcCharSetCreate ();
590
for (; ! MPLIST_TAIL_P (char_list); char_list = MPLIST_NEXT (char_list))
591
if (! FcCharSetAddChar (cs, (FcChar32) MPLIST_INTEGER (char_list)))
593
FcCharSetDestroy (cs);
601
for (i = mtext_nchars (mt) - 1; i >= 0; i--)
602
if (! FcCharSetAddChar (cs, (FcChar32) mtext_ref_char (mt, i)))
604
FcCharSetDestroy (cs);
607
if (mtext_nchars (mt) > 0
608
&& (mt = mtext_get_prop (mt, 0, Mtext)))
609
for (i = mtext_nchars (mt) - 1; i >= 0; i--)
610
if (! FcCharSetAddChar (cs, (FcChar32) mtext_ref_char (mt, i)))
612
FcCharSetDestroy (cs);
414
619
#else /* not HAVE_FONTCONFIG */
430
635
if (FT_New_Face (ft_library, filename, 0, &ft_face) != 0)
432
if (! FT_IS_SCALABLE (ft_face))
436
BDF_PropertyRec prop;
438
reject = FT_Get_BDF_Property (ft_face, "PIXEL_SIZE", &prop) == 0;
439
size = prop.u.integer * 10;
440
#else /* not HAVE_FTBDF_H */
442
#endif /* not HAVE_FTBDF_H */
445
FT_Done_Face (ft_face);
450
MSTRUCT_CALLOC (ft_info, MERROR_FONT_FT);
637
ft_info = ft_gen_font (ft_face);
638
FT_Done_Face (ft_face);
451
642
font = &ft_info->font;
452
STRDUP_LOWER (buf, bufsize, ft_face->family_name);
453
family = msymbol (buf);
454
mfont__set_property (font, MFONT_FAMILY, family);
455
mfont__set_property (font, MFONT_WEIGHT, Mmedium);
456
mfont__set_property (font, MFONT_STYLE, Mr);
457
mfont__set_property (font, MFONT_STRETCH, Mnormal);
458
mfont__set_property (font, MFONT_ADSTYLE, Mnull);
459
mfont__set_property (font, MFONT_REGISTRY, Municode_bmp);
460
font->type = MFONT_TYPE_OBJECT;
461
font->source = MFONT_SOURCE_FT;
463
643
font->file = msymbol (filename);
465
stylename = ft_face->style_name;
468
for (i = 0; i < ft_to_prop_size; i++)
469
if (! strncasecmp (ft_to_prop[i].ft_style, stylename,
472
mfont__set_property (font, ft_to_prop[i].prop,
473
msymbol (ft_to_prop[i].val));
474
stylename += ft_to_prop[i].len;
477
if (i == ft_to_prop_size)
479
char *p1 = stylename + 1;
482
while (*p1 >= 'a' && *p1 <= 'z') p1++;
483
sym = msymbol__with_len (stylename, p1 - stylename);
484
for (i = MFONT_WEIGHT; i <= MFONT_STRETCH; i++)
485
if (msymbol_get (sym, mfont__property_table[i].property))
487
mfont__set_property (font, i, sym);
492
while (*stylename && ! isalpha (*stylename))
496
FT_Done_Face (ft_face);
498
645
plist = mplist_find_by_key (ft_font_list, family);
500
647
mplist_push (MPLIST_PLIST (plist), font->file, ft_info);
658
ft_init_font_list (void)
666
ft_font_list = mplist ();
667
MPLIST_DO (plist, mfont_freetype_path)
668
if (MPLIST_STRING_P (plist)
669
&& (pathname = MPLIST_STRING (plist))
670
&& stat (pathname, &buf) == 0)
672
if (S_ISREG (buf.st_mode))
673
ft_add_font (pathname);
674
else if (S_ISDIR (buf.st_mode))
676
DIR *dir = opendir (pathname);
680
int len = strlen (pathname);
683
while ((dp = readdir (dir)) != NULL)
685
SAFE_ALLOCA (path, len + strlen (dp->d_name) + 2);
686
strcpy (path, pathname);
688
strcpy (path + len + 1, dp->d_name);
698
/* Return 1 iff the font pointed by FT_INFO has all characters in
702
ft_has_char_list_p (MFontFT *ft_info, MPlist *char_list)
707
if (FT_New_Face (ft_library, MSYMBOL_NAME (ft_info->font.file), 0, &ft_face))
709
MPLIST_DO (cl, char_list)
710
if (FT_Get_Char_Index (ft_face, (FT_ULong) MPLIST_INTEGER (cl)) == 0)
712
FT_Done_Face (ft_face);
713
return MPLIST_TAIL_P (cl);
716
/* Return ((FAMILY . FONT) ...) where FONT is a pointer to MFontFT
717
that supports characters in CHAR_LIST or MT. One of CHAR_LIST or
721
ft_list_char_list (MPlist *char_list, MText *mt)
723
MPlist *plist = NULL, *pl, *p;
726
ft_list_family (Mnil, 0);
730
int len = mtext_nchars (mt);
731
MText *extra = mtext_get_prop (mt, 0, Mtext);
732
int total_len = len + (extra ? mtext_nchars (extra) : 0);
735
char_list = mplist ();
736
for (i = 0; i < total_len; i++)
738
int c = (i < len ? mtext_ref_char (mt, i)
739
: mtext_ref_char (extra, i - len));
741
if (! mplist_find_by_value (char_list, (void *) c))
742
mplist_push (char_list, Minteger, (void *) c);
746
MPLIST_DO (pl, ft_font_list)
748
MPLIST_DO (p, MPLIST_PLIST (pl))
750
MFontFT *ft_info = MPLIST_VAL (p);
752
if (ft_has_char_list_p (ft_info, char_list))
754
MSymbol family = mfont_get_prop (&ft_info->font, Mfamily);
758
mplist_push (plist, family, ft_info);
763
M17N_OBJECT_UNREF (char_list);
510
766
#endif /* not HAVE_FONTCONFIG */
726
948
MPlist *plist = NULL;
730
951
if (! ft_language_list)
731
952
ft_language_list = mplist ();
732
953
else if ((plist = mplist_find_by_key (ft_language_list, language)))
733
954
return (MPLIST_VAL (plist) ? MPLIST_PLIST (plist) : NULL);
956
mt = mlanguage_text (language);
735
958
#ifdef HAVE_FONTCONFIG
736
for (step = 0; step < 2; step++)
738
FcPattern *pattern = NULL;
739
FcObjectSet *os = NULL;
740
FcFontSet *fs = NULL;
745
if (! (pattern = FcPatternCreate ())
746
|| ! (os = FcObjectSetBuild (FC_FAMILY, FC_FILE, NULL)))
750
FcLangSet *ls = FcLangSetCreate ();
754
if (FcLangSetAdd (ls, (FcChar8 *) MSYMBOL_NAME (language))
755
&& FcPatternAddLangSet (pattern, FC_LANG, ls))
756
fs = FcFontList (fc_config, pattern, os);
757
FcLangSetDestroy (ls);
765
if (! (mt = msymbol_get (language, Mtext)))
767
if (! (cs = FcCharSetCreate ()))
769
for (i = mtext_nchars (mt) - 1; i >= 0; i--)
770
if (! FcCharSetAddChar (cs, (FcChar32) mtext_ref_char (mt, i)))
773
&& (mt = mtext_get_prop (mt, 0, Mtext)))
774
for (i = mtext_nchars (mt) - 1; i >= 0; i--)
775
if (! FcCharSetAddChar (cs, (FcChar32) mtext_ref_char (mt, i)))
779
if (FcPatternAddCharSet (pattern, FC_CHARSET, cs))
780
fs = FcFontList (fc_config, pattern, os);
782
FcCharSetDestroy (cs);
787
for (i = 0; i < fs->nfont; i++)
789
MSymbol family, file;
790
char *fam, *filename;
794
if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0,
795
(FcChar8 **) &fam) != FcResultMatch)
797
if (FcPatternGetString (fs->fonts[i], FC_FILE, 0,
798
(FcChar8 **) &filename) != FcResultMatch)
800
STRDUP_LOWER (buf, bufsize, fam);
801
family = msymbol (buf);
802
file = msymbol (filename);
803
pl = MPLIST_PLIST (ft_list_family (family, 0));
804
ft_info = mplist_get (pl, file);
809
mplist_add (plist, family, ft_info);
812
FcFontSetDestroy (fs);
813
FcObjectSetDestroy (os);
814
FcPatternDestroy (pattern);
815
if (language == msymbol ("en"))
821
FcObjectSetDestroy (os);
823
FcPatternDestroy (pattern);
824
MEMORY_FULL (MERROR_FONT_FT);
960
FcPattern *pattern = NULL;
961
FcCharSet *cs = NULL;
962
FcLangSet *ls = NULL;
964
if (! (pattern = FcPatternCreate ()))
967
if (mt && mtext_nchars (mt) > 0)
969
cs = fc_build_charset (NULL, mt);
970
if (cs && ! FcPatternAddCharSet (pattern, FC_CHARSET, cs))
975
if (! (ls = FcLangSetCreate ()))
977
if (! FcLangSetAdd (ls, (FcChar8 *) MSYMBOL_NAME (language))
978
|| ! FcPatternAddLangSet (pattern, FC_LANG, ls))
982
plist = fc_list_pattern (pattern);
984
if (cs) FcCharSetDestroy (cs);
985
if (ls) FcLangSetDestroy (ls);
986
if (pattern) FcPatternDestroy (pattern);
988
#else /* not HAVE_FONTCONFIG */
989
if (mt && mtext_nchars (mt) > 0)
990
plist = ft_list_char_list (NULL, mt);
991
#endif /* not HAVE_FONTCONFIG */
828
993
mplist_push (ft_language_list, language, plist);
831
#else /* not HAVE_FONTCONFIG */
833
if ((mt = msymbol_get (language, Mtext)))
835
MText *extra = mtext_get_prop (mt, 0, Mtext);
837
int len = mtext_nchars (mt);
838
int extra_len = extra ? mtext_nchars (extra) : 0;
842
ft_list_family (Mnil, 0);
843
MPLIST_DO (pl, ft_font_list)
845
MPLIST_DO (p, MPLIST_PLIST (pl))
847
MFontFT *ft_info = MPLIST_VAL (p);
851
if (FT_New_Face (ft_library, MSYMBOL_NAME (ft_info->font.file),
854
for (i = len - 1; i >= 0; i--)
855
if (FT_Get_Char_Index (ft_face,
856
(FT_ULong) mtext_ref_char (mt, i)) == 0)
858
if (i < 0 && extra_len > 0)
859
for (i = extra_len - 1; i >= 0; i--)
860
if (FT_Get_Char_Index (ft_face,
861
(FT_ULong) mtext_ref_char (extra, i)) == 0)
863
FT_Done_Face (ft_face);
868
family = mfont_get_prop (&ft_info->font, Mfamily);
869
mplist_push (plist, family, ft_info);
874
#endif /* not HAVE_FONTCONFIG */
878
998
ft_list_script (MSymbol script)
880
1000
MPlist *plist = NULL;
881
MPlist *language_list, *pl;
883
1003
if (! ft_script_list)
884
1004
ft_script_list = mplist ();
885
1005
else if ((plist = mplist_find_by_key (ft_script_list, script)))
886
1006
return (MPLIST_VAL (plist) ? MPLIST_PLIST (plist) : NULL);
888
language_list = mlanguage__list (script);
889
MPLIST_DO (pl, language_list)
1008
char_list = mscript__char_list (script);
1010
#ifdef HAVE_FONTCONFIG
891
MSymbol language = MPLIST_VAL (pl) ? MPLIST_SYMBOL (pl) : MPLIST_KEY (pl);
892
MPlist *p = ft_list_language (language);
1013
FcPattern *pattern = NULL;
901
family = MPLIST_KEY (p);
902
if (! mplist_find_by_value (plist, MPLIST_VAL (p)))
903
mplist_add (plist, family, MPLIST_VAL (p));
1016
if (! (pattern = FcPatternCreate ()))
1018
cs = fc_build_charset (char_list, NULL);
1019
if (cs && ! FcPatternAddCharSet (pattern, FC_CHARSET, cs))
1021
plist = fc_list_pattern (pattern);
1023
if (cs) FcCharSetDestroy (cs);
1024
if (pattern) FcPatternDestroy (pattern);
1026
#else /* not HAVE_FONTCONFIG */
1028
plist = ft_list_char_list (char_list, NULL);
1029
#endif /* not HAVE_FONTCONFIG */
906
1031
mplist_push (ft_script_list, script, plist);
907
M17N_OBJECT_UNREF (language_list);
912
ft_check_otf (MFontFT *ft_info, MFontCapability *cap)
1036
ft_check_otf (MFontFT *ft_info, MFontCapability *cap, FT_Face ft_face)
915
1039
if (ft_info->otf == invalid_otf)
917
1041
if (! ft_info->otf)
919
ft_info->otf = OTF_open (MSYMBOL_NAME (ft_info->font.file));
1043
#if (LIBOTF_MAJOR_VERSION > 0 || LIBOTF_MINOR_VERSION > 9 || LIBOTF_RELEASE_NUMBER > 4)
1045
ft_info->otf = OTF_open_ft_face (ft_face);
1048
ft_info->otf = OTF_open (MSYMBOL_NAME (ft_info->font.file));
920
1049
if (! ft_info->otf)
922
1051
ft_info->otf = invalid_otf;
949
ft_check_lang (MFontFT *ft_info, MFontCapability *cap)
1078
ft_check_language (MFontFT *ft_info, MSymbol language, FT_Face ft_face)
951
#ifdef HAVE_FONTCONFIG
956
for (i = 0; cap->lang[i] != Mnil; i++)
959
&& (plist = mplist_find_by_key (ft_info->lang, cap->lang[i])))
961
if (MPLIST_VAL (plist))
966
if (! ft_info->langset)
968
FcPattern *pat = FcPatternBuild (NULL, FC_FILE, FcTypeString,
969
MSYMBOL_NAME (ft_info->font.file),
971
FcObjectSet *os = FcObjectSetBuild (FC_LANG, FC_CHARSET, NULL);
972
FcFontSet *fs = FcFontList (fc_config, pat, os);
1082
int ft_face_allocaed = 0;
1086
#ifdef HAVE_FONTCONFIG
1087
if (ft_info->langset
1088
&& (FcLangSetHasLang (ft_info->langset,
1089
(FcChar8 *) MSYMBOL_NAME (language))
1090
!= FcLangDifferentLang))
1092
#endif /* HAVE_FONTCONFIG */
1094
mt = mlanguage_text (language);
1095
if (! mt || mtext_nchars (mt) == 0)
1100
char *filename = MSYMBOL_NAME (ft_info->font.file);
1102
if (FT_New_Face (ft_library, filename, 0, &ft_face))
1104
ft_face_allocaed = 1;
1107
len = mtext_nchars (mt);
1108
extra = mtext_get_prop (mt, 0, Mtext);
1109
total_len = len + (extra ? mtext_nchars (extra) : 0);
1111
for (i = 0; i < total_len; i++)
1113
int c = (i < len ? mtext_ref_char (mt, i)
1114
: mtext_ref_char (extra, i - len));
1116
#ifdef HAVE_FONTCONFIG
1117
if (ft_info->charset
1118
&& FcCharSetHasChar (ft_info->charset, (FcChar32) c) == FcFalse)
1120
#endif /* HAVE_FONTCONFIG */
1121
if (FT_Get_Char_Index (ft_face, (FT_ULong) c) == 0)
1125
if (ft_face_allocaed)
1126
FT_Done_Face (ft_face);
1128
return (i == total_len ? 0 : -1);
1132
ft_check_script (MFontFT *ft_info, MSymbol script, FT_Face ft_face)
1134
MPlist *char_list = mscript__char_list (script);
1138
#ifdef HAVE_FONTCONFIG
1139
if (ft_info->charset)
1141
MPLIST_DO (char_list, char_list)
1142
if (FcCharSetHasChar (ft_info->charset,
1143
(FcChar32) MPLIST_INTEGER (char_list)) == FcFalse)
1147
#endif /* HAVE_FONTCONFIG */
1149
int ft_face_allocaed = 0;
1153
char *filename = MSYMBOL_NAME (ft_info->font.file);
1155
if (FT_New_Face (ft_library, filename, 0, &ft_face))
976
if (FcPatternGetLangSet (fs->fonts[0], FC_LANG, 0, &ft_info->langset)
978
ft_info->langset = FcLangSetCopy (ft_info->langset);
980
ft_info->langset = FcLangSetCreate ();
981
FcPatternGetCharSet (fs->fonts[0], FC_CHARSET, 0, &ft_info->charset);
982
FcFontSetDestroy (fs);
983
FcObjectSetDestroy (os);
984
FcPatternDestroy (pat);
987
ft_info->lang = mplist ();
988
if (FcLangSetHasLang (ft_info->langset,
989
(FcChar8 *) MSYMBOL_NAME (cap->lang[i]))
990
!= FcLangDifferentLang)
992
mplist_push (ft_info->lang, cap->lang[i], Mt);
996
mt = msymbol_get (cap->lang[i], Mtext);
999
mplist_push (ft_info->lang, cap->lang[i], Mnil);
1003
for (j = mtext_nchars (mt) - 1; j >= 0; j--)
1004
if (! FcCharSetAddChar (ft_info->charset,
1005
(FcChar32) mtext_ref_char (mt, j)))
1157
ft_face_allocaed = 1;
1160
MPLIST_DO (char_list, char_list)
1161
if (FT_Get_Char_Index (ft_face, (FT_ULong) MPLIST_INTEGER (char_list))
1008
&& (mt = mtext_get_prop (mt, 0, Mtext)))
1009
for (j = mtext_nchars (mt) - 1; j >= 0; j--)
1010
if (! FcCharSetAddChar (ft_info->charset,
1011
(FcChar32) mtext_ref_char (mt, j)))
1013
mplist_push (ft_info->lang, cap->lang[i], (j < 0 ? Mt : Mnil));
1164
if (ft_face_allocaed)
1165
FT_Done_Face (ft_face);
1017
#endif /* HAVE_FONTCONFIG */
1168
return (MPLIST_TAIL_P (char_list) ? 0 : -1);
1021
1171
static MPlist *ft_default_list;
1069
1219
static MPlist *ft_capability_list;
1071
1221
static MPlist *
1072
ft_list_capability (MSymbol sym)
1222
ft_list_capability (MSymbol capability)
1074
MPlist *plist, *pl, *p;
1075
MFontCapability *cap = mfont__get_capability (sym);
1079
if (ft_capability_list)
1081
plist = mplist_find_by_key (ft_capability_list, sym);
1083
return (MPLIST_VAL (plist) ? MPLIST_VAL (plist) : NULL);
1088
ft_capability_list = mplist ();
1091
if (cap->script != Mnil)
1093
pl = ft_list_script (cap->script);
1097
if (cap->script_tag && ft_check_otf (MPLIST_VAL (pl), cap) < 0)
1099
if (cap->lang && ft_check_lang (MPLIST_VAL (pl), cap) < 0)
1103
mplist_add (plist, MPLIST_KEY (pl), MPLIST_VAL (pl));
1105
mplist_push (ft_capability_list, sym, plist);
1113
for (i = 0; cap->lang[i] != Mnil; i++)
1115
p = ft_list_language (cap->lang[i]);
1121
mplist_add (plist, MPLIST_KEY (p), MPLIST_VAL (p));
1125
mplist_push (ft_capability_list, sym, plist);
1224
MFontCapability *cap;
1225
MPlist *plist = NULL, *pl;
1227
if (! ft_capability_list)
1228
ft_capability_list = mplist ();
1229
else if ((plist = mplist_find_by_key (ft_capability_list, capability)))
1230
return (MPLIST_VAL (plist) ? MPLIST_VAL (plist) : NULL);
1232
cap = mfont__get_capability (capability);
1234
if (cap && cap->language != Mnil)
1236
plist = ft_list_language (cap->language);
1239
plist = mplist_copy (plist);
1242
if (cap && cap->script != Mnil)
1246
plist = ft_list_script (cap->script);
1249
plist = mplist_copy (plist);
1253
for (pl = plist; ! MPLIST_TAIL_P (pl);)
1255
if (ft_check_script (MPLIST_VAL (pl), cap->script, NULL) < 0)
1258
pl = MPLIST_NEXT (pl);
1262
if (cap->script_tag)
1264
for (pl = plist; ! MPLIST_TAIL_P (pl);)
1266
if (ft_check_otf (MPLIST_VAL (pl), cap, NULL) < 0)
1269
pl = MPLIST_NEXT (pl);
1273
if (MPLIST_TAIL_P (plist))
1275
M17N_OBJECT_UNREF (plist);
1280
mplist_push (ft_capability_list, capability, plist);
1995
ft_list_family_names (MFrame *frame, MPlist *plist)
2001
#ifdef HAVE_FONTCONFIG
2002
fc_init_font_list ();
2003
#else /* not HAVE_FONTCONFIG */
2004
ft_init_font_list ();
2005
#endif /* not HAVE_FONTCONFIG */
2008
MPLIST_DO (pl, ft_font_list)
2010
MSymbol family = MPLIST_KEY (pl);
2013
#ifdef HAVE_FONTCONFIG
2014
if (msymbol_get (family, Mgeneric_family) != Mnil)
2016
#endif /* HAVE_FONTCONFIG */
2017
MPLIST_DO (p, plist)
2019
MSymbol sym = MPLIST_SYMBOL (p);
2023
if (strcmp (MSYMBOL_NAME (sym), MSYMBOL_NAME (family)) > 0)
2025
mplist_push (p, Msymbol, family);
2029
if (MPLIST_TAIL_P (p))
2030
mplist_push (p, Msymbol, family);
1839
2035
ft_check_capability (MRealizedFont *rfont, MSymbol capability)
1841
2037
MFontFT *ft_info = (MFontFT *) rfont->font;
2038
MRealizedFontFT *ft_rfont = rfont->info;
1842
2039
MFontCapability *cap = mfont__get_capability (capability);
1844
if (cap->script_tag && ft_check_otf (ft_info, cap) < 0)
1846
if (cap->lang && ft_check_lang (ft_info, cap) < 0)
2041
if (cap->script != Mnil
2042
&& ft_check_script (ft_info, cap->script, ft_rfont->ft_face) < 0)
2044
if (cap->language != Mnil
2045
&& ft_check_language (ft_info, cap->language, ft_rfont->ft_face) < 0)
2047
if (cap->script_tag && ft_check_otf (ft_info, cap, ft_rfont->ft_face) < 0)
2052
static MRealizedFont *
2053
ft_encapsulate (MFrame *frame, MSymbol data_type, void *data)
2056
MRealizedFont *rfont;
2057
MRealizedFontFT *ft_rfont;
2060
if (data_type == Mfontconfig)
2062
#ifdef HAVE_FONTCONFIG
2063
FcPattern *pattern = data;
2065
if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &ft_face)
2068
ft_info = fc_gen_font (pattern, NULL);
2069
#else /* not HAVE_FONTCONFIG */
2071
#endif /* not HAVE_FONTCONFIG */
2073
else if (data_type == Mfreetype)
2076
ft_info = ft_gen_font (ft_face);
2081
M17N_OBJECT (ft_rfont, free_ft_rfont, MERROR_FONT_FT);
2082
ft_rfont->ft_face = ft_face;
2083
ft_rfont->face_encapsulated = 1;
2085
MDEBUG_DUMP (" [FONT-FT] encapsulating ", (char *) ft_face->family_name,);
2087
MSTRUCT_CALLOC (rfont, MERROR_FONT_FT);
2088
rfont->font = (MFont *) ft_info;
2089
rfont->info = ft_rfont;
2090
rfont->fontp = ft_face;
2091
rfont->driver = &mfont__ft_driver;
2092
rfont->spec = ft_info->font;
2093
rfont->spec.type = MFONT_TYPE_REALIZED;
2094
rfont->frame = frame;
2095
rfont->ascent = ft_face->size->metrics.ascender >> 6;
2096
rfont->descent = - ft_face->size->metrics.descender >> 6;
2097
rfont->max_advance = ft_face->size->metrics.max_advance >> 6;
2098
rfont->baseline_offset = 0;
2101
BDF_PropertyRec prop;
2103
if (! FT_IS_SCALABLE (ft_face)
2104
&& FT_Get_BDF_Property (ft_face, "_MULE_BASELINE_OFFSET", &prop) == 0)
2106
rfont->baseline_offset = prop.u.integer;
2107
rfont->ascent += prop.u.integer;
2108
rfont->descent -= prop.u.integer;
2111
#endif /* HAVE_FTBDF_H */
2112
if (FT_IS_SCALABLE (ft_face))
2113
rfont->average_width = 0;
2115
rfont->average_width = ft_face->available_sizes->width;
2116
rfont->next = MPLIST_VAL (frame->realized_font_list);
2117
MPLIST_VAL (frame->realized_font_list) = rfont;
2123
ft_close (MRealizedFont *rfont)
2125
if (! rfont->encapsulating)
2128
M17N_OBJECT_UNREF (rfont->info);
1853
2134
/* Internal API */
1855
2136
MFontDriver mfont__ft_driver =
1856
2137
{ ft_select, ft_open, ft_find_metric, ft_has_char, ft_encode_char,
1857
ft_render, ft_list , ft_check_capability};
2138
ft_render, ft_list, ft_list_family_names, ft_check_capability,
2139
ft_encapsulate, ft_close };
1860
2142
mfont__ft_init ()