1 /*
2 This file is part of LilyPond, the GNU music typesetter.
3
4 Copyright (C) 2005--2020 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "lily-guile.hh"
21 #include "international.hh"
22 #include "main.hh"
23 #include "string-convert.hh"
24 #include "warn.hh"
25
26 #include <fontconfig/fontconfig.h>
27
28 using std::string;
29
30 string
display_fontset(FcFontSet * fs)31 display_fontset (FcFontSet *fs)
32 {
33 string retval;
34
35 int j;
36 for (j = 0; j < fs->nfont; j++)
37 {
38 FcChar8 *font;
39 FcChar8 *str;
40
41 font = FcNameUnparse (fs->fonts[j]);
42 if (FcPatternGetString (fs->fonts[j], FC_FILE, 0, &str) == FcResultMatch)
43 retval += String_convert::form_string ("FILE %s\n", str);
44 if (FcPatternGetString (fs->fonts[j], FC_INDEX, 0, &str) == FcResultMatch)
45 retval += String_convert::form_string ("INDEX %s\n", str);
46 if (FcPatternGetString (fs->fonts[j], FC_FAMILY, 0, &str) == FcResultMatch)
47 retval += String_convert::form_string ("family %s\n ", str);
48 if (FcPatternGetString (fs->fonts[j],
49 "designsize", 0, &str) == FcResultMatch)
50 retval += String_convert::form_string ("designsize %s\n ", str);
51
52 retval += String_convert::form_string ("%s\n", (const char *)font);
53 free (font);
54 }
55
56 return retval;
57 }
58
59 string
display_strlist(char const * what,FcStrList * slist)60 display_strlist (char const *what, FcStrList *slist)
61 {
62 string retval;
63 while (FcChar8 *dir = FcStrListNext (slist))
64 {
65 retval += String_convert::form_string ("%s: %s\n", what, dir);
66 }
67 return retval;
68 }
69
70 string
display_config(FcConfig * fcc)71 display_config (FcConfig *fcc)
72 {
73 string retval;
74 retval += display_strlist ("Config files", FcConfigGetConfigFiles (fcc));
75 retval += display_strlist ("Config dir", FcConfigGetConfigDirs (fcc));
76 retval += display_strlist ("Font dir", FcConfigGetFontDirs (fcc));
77 return retval;
78 }
79
80 string
display_list(FcConfig * fcc)81 display_list (FcConfig *fcc)
82 {
83 FcPattern *pat = FcPatternCreate ();
84
85 FcObjectSet *os = 0;
86 if (!os)
87 os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, (char *)0);
88
89 FcFontSet *fs = FcFontList (fcc, pat, os);
90 FcObjectSetDestroy (os);
91 if (pat)
92 FcPatternDestroy (pat);
93
94 string retval;
95 if (fs)
96 {
97 retval = display_fontset (fs);
98 FcFontSetDestroy (fs);
99 }
100 return retval;
101 }
102
103 LY_DEFINE (ly_font_config_get_font_file, "ly:font-config-get-font-file", 1, 0, 0,
104 (SCM name),
105 "Get the file for font @var{name}.")
106 {
107 LY_ASSERT_TYPE (scm_is_string, name, 1);
108
109 FcPattern *pat = FcPatternCreate ();
110 FcValue val;
111
112 val.type = FcTypeString;
113 val.u.s = (const FcChar8 *)ly_scm2string (name).c_str (); // FC_SLANT_ITALIC;
114 FcPatternAdd (pat, FC_FAMILY, val, FcFalse);
115
116 FcResult result;
117 SCM scm_result = SCM_BOOL_F;
118
119 FcConfigSubstitute (NULL, pat, FcMatchFont);
120 FcDefaultSubstitute (pat);
121
122 pat = FcFontMatch (NULL, pat, &result);
123 FcChar8 *str = 0;
124 if (FcPatternGetString (pat, FC_FILE, 0, &str) == FcResultMatch)
125 scm_result = scm_from_utf8_string ((char const *)str);
126
127 FcPatternDestroy (pat);
128
129 return scm_result;
130 }
131
132 LY_DEFINE (ly_font_config_display_fonts, "ly:font-config-display-fonts", 0, 0, 0,
133 (),
134 "Dump a list of all fonts visible to FontConfig.")
135 {
136 string str = display_list (NULL);
137 str += display_config (NULL);
138
139 progress_indication (str);
140
141 return SCM_UNSPECIFIED;
142 }
143
144 LY_DEFINE (ly_font_config_add_directory, "ly:font-config-add-directory", 1, 0, 0,
145 (SCM dir),
146 "Add directory @var{dir} to FontConfig.")
147 {
148 LY_ASSERT_TYPE (scm_is_string, dir, 1);
149
150 string d = ly_scm2string (dir);
151
152 if (!FcConfigAppFontAddDir (0, (const FcChar8 *)d.c_str ()))
153 error (_f ("failed adding font directory: %s", d.c_str ()));
154 else
155 debug_output (_f ("Adding font directory: %s", d.c_str ()));
156
157 return SCM_UNSPECIFIED;
158 }
159
160 LY_DEFINE (ly_font_config_add_font, "ly:font-config-add-font", 1, 0, 0,
161 (SCM font),
162 "Add font @var{font} to FontConfig.")
163 {
164 LY_ASSERT_TYPE (scm_is_string, font, 1);
165
166 string f = ly_scm2string (font);
167
168 if (!FcConfigAppFontAddFile (0, (const FcChar8 *)f.c_str ()))
169 error (_f ("failed adding font file: %s", f.c_str ()));
170 else
171 debug_output (_f ("Adding font file: %s", f.c_str ()));
172
173 return SCM_UNSPECIFIED;
174 }
175