Mercurial > mplayer.hg
annotate libass/ass_fontconfig.c @ 33263:5f527a9a9521
Add an exit function.
This function will allow performing clean-up operations.
(MPlayer calls guiDone() before exiting, but only if the GUI has been
initialized, i.e. if guiInit() has been called successfully. Any
exit_player()/exit_player_with_rc() after GUI's cfg_read() until
guiInit(), or any exit_player() during guiInit() itself will end the GUI
without calling guiDone(). This exit function will at least handle
abortions during guiInit() itself. It will be called twice in case of an
guiExit() after GUI initialization - first directly, next by guiDone()
via MPlayer's exit_player_with_rc().)
author | ib |
---|---|
date | Tue, 03 May 2011 12:19:22 +0000 |
parents | ac6e48baa03d |
children | 88eebbbbd6a0 |
rev | line source |
---|---|
20008
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19902
diff
changeset
|
1 /* |
26723 | 2 * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> |
3 * | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
4 * This file is part of libass. |
26723 | 5 * |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
6 * libass is free software; you can redistribute it and/or modify |
26723 | 7 * it under the terms of the GNU General Public License as published by |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
11 * libass is distributed in the hope that it will be useful, |
26723 | 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 along | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
17 * with libass; if not, write to the Free Software Foundation, Inc., |
26723 | 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 */ | |
20008
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19902
diff
changeset
|
20 |
18937 | 21 #include "config.h" |
22 | |
23 #include <stdlib.h> | |
24 #include <stdio.h> | |
25 #include <assert.h> | |
26 #include <string.h> | |
31875 | 27 #include <strings.h> |
18937 | 28 #include <sys/types.h> |
29 #include <sys/stat.h> | |
22292 | 30 #include <inttypes.h> |
31 #include <ft2build.h> | |
32 #include FT_FREETYPE_H | |
18937 | 33 |
30200 | 34 #include "ass_utils.h" |
21458
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
35 #include "ass.h" |
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
36 #include "ass_library.h" |
18937 | 37 #include "ass_fontconfig.h" |
38 | |
27393 | 39 #ifdef CONFIG_FONTCONFIG |
18937 | 40 #include <fontconfig/fontconfig.h> |
21460 | 41 #include <fontconfig/fcfreetype.h> |
18937 | 42 #endif |
43 | |
30200 | 44 struct fc_instance { |
27393 | 45 #ifdef CONFIG_FONTCONFIG |
30200 | 46 FcConfig *config; |
18937 | 47 #endif |
30200 | 48 char *family_default; |
49 char *path_default; | |
50 int index_default; | |
18937 | 51 }; |
52 | |
27393 | 53 #ifdef CONFIG_FONTCONFIG |
26660
ab5729095d68
Define FC_FULLNAME and FC_EMBOLDEN to fix compilation with ancient fontconfig.
eugeni
parents:
26659
diff
changeset
|
54 |
18937 | 55 /** |
31853 | 56 * \brief Case-insensitive match ASS/SSA font family against full name. (also |
57 * known as "name for humans") | |
58 * | |
59 * \param lib library instance | |
60 * \param priv fontconfig instance | |
61 * \param family font fullname | |
62 * \param bold weight attribute | |
63 * \param italic italic attribute | |
64 * \return font set | |
65 */ | |
66 static FcFontSet * | |
67 match_fullname(ASS_Library *lib, FCInstance *priv, const char *family, | |
68 unsigned bold, unsigned italic) | |
69 { | |
70 FcFontSet *sets[2]; | |
71 FcFontSet *result = FcFontSetCreate(); | |
72 int nsets = 0; | |
73 int i, fi; | |
74 | |
75 if ((sets[nsets] = FcConfigGetFonts(priv->config, FcSetSystem))) | |
76 nsets++; | |
77 if ((sets[nsets] = FcConfigGetFonts(priv->config, FcSetApplication))) | |
78 nsets++; | |
79 | |
80 // Run over font sets and patterns and try to match against full name | |
81 for (i = 0; i < nsets; i++) { | |
82 FcFontSet *set = sets[i]; | |
83 for (fi = 0; fi < set->nfont; fi++) { | |
84 FcPattern *pat = set->fonts[fi]; | |
85 char *fullname; | |
86 int pi = 0, at; | |
87 FcBool ol; | |
88 while (FcPatternGetString(pat, FC_FULLNAME, pi++, | |
89 (FcChar8 **) &fullname) == FcResultMatch) { | |
90 if (FcPatternGetBool(pat, FC_OUTLINE, 0, &ol) != FcResultMatch | |
91 || ol != FcTrue) | |
92 continue; | |
93 if (FcPatternGetInteger(pat, FC_SLANT, 0, &at) != FcResultMatch | |
94 || at < italic) | |
95 continue; | |
96 if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &at) != FcResultMatch | |
97 || at < bold) | |
98 continue; | |
99 if (strcasecmp(fullname, family) == 0) { | |
100 FcFontSetAdd(result, FcPatternDuplicate(pat)); | |
101 break; | |
102 } | |
103 } | |
104 } | |
105 } | |
106 | |
107 return result; | |
108 } | |
109 | |
110 /** | |
18937 | 111 * \brief Low-level font selection. |
112 * \param priv private data | |
113 * \param family font family | |
28860
7fcc0bf5b27a
Treat -font/-subfont as Fontconfig pattern in libass.
eugeni
parents:
27842
diff
changeset
|
114 * \param treat_family_as_pattern treat family as fontconfig pattern |
18937 | 115 * \param bold font weight value |
116 * \param italic font slant value | |
117 * \param index out: font index inside a file | |
23980 | 118 * \param code: the character that should be present in the font, can be 0 |
18937 | 119 * \return font file path |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
120 */ |
31853 | 121 static char *select_font(ASS_Library *library, FCInstance *priv, |
30200 | 122 const char *family, int treat_family_as_pattern, |
123 unsigned bold, unsigned italic, int *index, | |
124 uint32_t code) | |
18937 | 125 { |
30200 | 126 FcBool rc; |
127 FcResult result; | |
128 FcPattern *pat = NULL, *rpat = NULL; | |
129 int r_index, r_slant, r_weight; | |
130 FcChar8 *r_family, *r_style, *r_file, *r_fullname; | |
131 FcBool r_outline, r_embolden; | |
132 FcCharSet *r_charset; | |
31853 | 133 FcFontSet *ffullname = NULL, *fsorted = NULL, *fset = NULL; |
30200 | 134 int curf; |
135 char *retval = NULL; | |
136 int family_cnt = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
137 |
30200 | 138 *index = 0; |
18937 | 139 |
30200 | 140 if (treat_family_as_pattern) |
141 pat = FcNameParse((const FcChar8 *) family); | |
142 else | |
143 pat = FcPatternCreate(); | |
28860
7fcc0bf5b27a
Treat -font/-subfont as Fontconfig pattern in libass.
eugeni
parents:
27842
diff
changeset
|
144 |
30200 | 145 if (!pat) |
146 goto error; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
147 |
30200 | 148 if (!treat_family_as_pattern) { |
149 FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *) family); | |
26591 | 150 |
30200 | 151 // In SSA/ASS fonts are sometimes referenced by their "full name", |
152 // which is usually a concatenation of family name and font | |
153 // style (ex. Ottawa Bold). Full name is available from | |
154 // FontConfig pattern element FC_FULLNAME, but it is never | |
155 // used for font matching. | |
156 // Therefore, I'm removing words from the end of the name one | |
157 // by one, and adding shortened names to the pattern. It seems | |
158 // that the first value (full name in this case) has | |
159 // precedence in matching. | |
160 // An alternative approach could be to reimplement FcFontSort | |
161 // using FC_FULLNAME instead of FC_FAMILY. | |
162 family_cnt = 1; | |
163 { | |
164 char *s = strdup(family); | |
165 char *p = s + strlen(s); | |
166 while (--p > s) | |
167 if (*p == ' ' || *p == '-') { | |
168 *p = '\0'; | |
169 FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *) s); | |
170 ++family_cnt; | |
171 } | |
172 free(s); | |
173 } | |
174 } | |
175 FcPatternAddBool(pat, FC_OUTLINE, FcTrue); | |
176 FcPatternAddInteger(pat, FC_SLANT, italic); | |
177 FcPatternAddInteger(pat, FC_WEIGHT, bold); | |
19063
5525af2ee4c7
Use FcPatternAdd-Type instead of FcNameParse. The latter, as it turns out, requires escaping of some characters ('-', maybe more).
eugeni
parents:
19001
diff
changeset
|
178 |
30200 | 179 FcDefaultSubstitute(pat); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
180 |
30200 | 181 rc = FcConfigSubstitute(priv->config, pat, FcMatchPattern); |
182 if (!rc) | |
183 goto error; | |
21351
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21279
diff
changeset
|
184 |
31853 | 185 fsorted = FcFontSort(priv->config, pat, FcTrue, NULL, &result); |
186 ffullname = match_fullname(library, priv, family, bold, italic); | |
187 if (!fsorted || !ffullname) | |
30200 | 188 goto error; |
21351
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21279
diff
changeset
|
189 |
31853 | 190 fset = FcFontSetCreate(); |
191 for (curf = 0; curf < ffullname->nfont; ++curf) { | |
192 FcPattern *curp = ffullname->fonts[curf]; | |
193 FcPatternReference(curp); | |
194 FcFontSetAdd(fset, curp); | |
195 } | |
196 for (curf = 0; curf < fsorted->nfont; ++curf) { | |
197 FcPattern *curp = fsorted->fonts[curf]; | |
198 FcPatternReference(curp); | |
199 FcFontSetAdd(fset, curp); | |
200 } | |
201 | |
30200 | 202 for (curf = 0; curf < fset->nfont; ++curf) { |
203 FcPattern *curp = fset->fonts[curf]; | |
26658
1e1ebebc8f5b
Remove extra family names from the search pattern after FcFontSort and
eugeni
parents:
26620
diff
changeset
|
204 |
30200 | 205 result = FcPatternGetBool(curp, FC_OUTLINE, 0, &r_outline); |
206 if (result != FcResultMatch) | |
207 continue; | |
208 if (r_outline != FcTrue) | |
209 continue; | |
210 if (!code) | |
211 break; | |
212 result = FcPatternGetCharSet(curp, FC_CHARSET, 0, &r_charset); | |
213 if (result != FcResultMatch) | |
214 continue; | |
215 if (FcCharSetHasChar(r_charset, code)) | |
216 break; | |
217 } | |
21351
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21279
diff
changeset
|
218 |
30200 | 219 if (curf >= fset->nfont) |
220 goto error; | |
21351
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21279
diff
changeset
|
221 |
30200 | 222 if (!treat_family_as_pattern) { |
223 // Remove all extra family names from original pattern. | |
224 // After this, FcFontRenderPrepare will select the most relevant family | |
225 // name in case there are more than one of them. | |
226 for (; family_cnt > 1; --family_cnt) | |
227 FcPatternRemove(pat, FC_FAMILY, family_cnt - 1); | |
228 } | |
229 | |
230 rpat = FcFontRenderPrepare(priv->config, pat, fset->fonts[curf]); | |
231 if (!rpat) | |
232 goto error; | |
26658
1e1ebebc8f5b
Remove extra family names from the search pattern after FcFontSort and
eugeni
parents:
26620
diff
changeset
|
233 |
30200 | 234 result = FcPatternGetInteger(rpat, FC_INDEX, 0, &r_index); |
235 if (result != FcResultMatch) | |
236 goto error; | |
237 *index = r_index; | |
26658
1e1ebebc8f5b
Remove extra family names from the search pattern after FcFontSort and
eugeni
parents:
26620
diff
changeset
|
238 |
30200 | 239 result = FcPatternGetString(rpat, FC_FILE, 0, &r_file); |
240 if (result != FcResultMatch) | |
241 goto error; | |
242 retval = strdup((const char *) r_file); | |
18937 | 243 |
30200 | 244 result = FcPatternGetString(rpat, FC_FAMILY, 0, &r_family); |
245 if (result != FcResultMatch) | |
246 r_family = NULL; | |
26614 | 247 |
30200 | 248 result = FcPatternGetString(rpat, FC_FULLNAME, 0, &r_fullname); |
249 if (result != FcResultMatch) | |
250 r_fullname = NULL; | |
18937 | 251 |
30200 | 252 if (!treat_family_as_pattern && |
253 !(r_family && strcasecmp((const char *) r_family, family) == 0) && | |
254 !(r_fullname && strcasecmp((const char *) r_fullname, family) == 0)) | |
255 ass_msg(library, MSGL_WARN, | |
256 "fontconfig: Selected font is not the requested one: " | |
257 "'%s' != '%s'", | |
258 (const char *) (r_fullname ? r_fullname : r_family), family); | |
26616 | 259 |
30200 | 260 result = FcPatternGetString(rpat, FC_STYLE, 0, &r_style); |
261 if (result != FcResultMatch) | |
262 r_style = NULL; | |
263 | |
264 result = FcPatternGetInteger(rpat, FC_SLANT, 0, &r_slant); | |
265 if (result != FcResultMatch) | |
266 r_slant = 0; | |
26616 | 267 |
30200 | 268 result = FcPatternGetInteger(rpat, FC_WEIGHT, 0, &r_weight); |
269 if (result != FcResultMatch) | |
270 r_weight = 0; | |
26616 | 271 |
30200 | 272 result = FcPatternGetBool(rpat, FC_EMBOLDEN, 0, &r_embolden); |
273 if (result != FcResultMatch) | |
274 r_embolden = 0; | |
26616 | 275 |
30200 | 276 ass_msg(library, MSGL_V, |
277 "Font info: family '%s', style '%s', fullname '%s'," | |
278 " slant %d, weight %d%s", (const char *) r_family, | |
279 (const char *) r_style, (const char *) r_fullname, r_slant, | |
280 r_weight, r_embolden ? ", embolden" : ""); | |
26616 | 281 |
30200 | 282 error: |
283 if (pat) | |
284 FcPatternDestroy(pat); | |
285 if (rpat) | |
286 FcPatternDestroy(rpat); | |
31853 | 287 if (fsorted) |
288 FcFontSetDestroy(fsorted); | |
289 if (ffullname) | |
290 FcFontSetDestroy(ffullname); | |
30200 | 291 if (fset) |
292 FcFontSetDestroy(fset); | |
293 return retval; | |
18937 | 294 } |
295 | |
296 /** | |
297 * \brief Find a font. Use default family or path if necessary. | |
298 * \param priv_ private data | |
299 * \param family font family | |
28860
7fcc0bf5b27a
Treat -font/-subfont as Fontconfig pattern in libass.
eugeni
parents:
27842
diff
changeset
|
300 * \param treat_family_as_pattern treat family as fontconfig pattern |
18937 | 301 * \param bold font weight value |
302 * \param italic font slant value | |
303 * \param index out: font index inside a file | |
23980 | 304 * \param code: the character that should be present in the font, can be 0 |
18937 | 305 * \return font file path |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
306 */ |
30200 | 307 char *fontconfig_select(ASS_Library *library, FCInstance *priv, |
308 const char *family, int treat_family_as_pattern, | |
309 unsigned bold, unsigned italic, int *index, | |
310 uint32_t code) | |
18937 | 311 { |
30200 | 312 char *res = 0; |
313 if (!priv->config) { | |
314 *index = priv->index_default; | |
315 res = priv->path_default ? strdup(priv->path_default) : 0; | |
316 return res; | |
317 } | |
318 if (family && *family) | |
319 res = | |
31853 | 320 select_font(library, priv, family, treat_family_as_pattern, |
30200 | 321 bold, italic, index, code); |
322 if (!res && priv->family_default) { | |
323 res = | |
31853 | 324 select_font(library, priv, priv->family_default, 0, bold, |
30200 | 325 italic, index, code); |
326 if (res) | |
327 ass_msg(library, MSGL_WARN, "fontconfig_select: Using default " | |
328 "font family: (%s, %d, %d) -> %s, %d", | |
329 family, bold, italic, res, *index); | |
330 } | |
331 if (!res && priv->path_default) { | |
332 res = strdup(priv->path_default); | |
333 *index = priv->index_default; | |
334 ass_msg(library, MSGL_WARN, "fontconfig_select: Using default font: " | |
335 "(%s, %d, %d) -> %s, %d", family, bold, italic, | |
336 res, *index); | |
337 } | |
338 if (!res) { | |
31853 | 339 res = select_font(library, priv, "Arial", 0, bold, italic, |
30200 | 340 index, code); |
341 if (res) | |
342 ass_msg(library, MSGL_WARN, "fontconfig_select: Using 'Arial' " | |
343 "font family: (%s, %d, %d) -> %s, %d", family, bold, | |
344 italic, res, *index); | |
345 } | |
346 if (res) | |
347 ass_msg(library, MSGL_V, | |
348 "fontconfig_select: (%s, %d, %d) -> %s, %d", family, bold, | |
349 italic, res, *index); | |
350 return res; | |
18937 | 351 } |
352 | |
21458
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
353 /** |
21630 | 354 * \brief Process memory font. |
355 * \param priv private data | |
356 * \param library library object | |
357 * \param ftlibrary freetype library object | |
358 * \param idx index of the processed font in library->fontdata | |
31853 | 359 * |
360 * Builds a font pattern in memory via FT_New_Memory_Face/FcFreeTypeQueryFace. | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
361 */ |
30200 | 362 static void process_fontdata(FCInstance *priv, ASS_Library *library, |
363 FT_Library ftlibrary, int idx) | |
21458
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
364 { |
30200 | 365 int rc; |
366 const char *name = library->fontdata[idx].name; | |
367 const char *data = library->fontdata[idx].data; | |
368 int data_size = library->fontdata[idx].size; | |
23216
b863ed752149
Move variables and a function under #ifdef FC_VERSION to avoid warnings.
eugeni
parents:
23215
diff
changeset
|
369 |
30200 | 370 FT_Face face; |
371 FcPattern *pattern; | |
372 FcFontSet *fset; | |
373 FcBool res; | |
374 int face_index, num_faces = 1; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
375 |
30200 | 376 for (face_index = 0; face_index < num_faces; ++face_index) { |
377 rc = FT_New_Memory_Face(ftlibrary, (unsigned char *) data, | |
378 data_size, face_index, &face); | |
379 if (rc) { | |
380 ass_msg(library, MSGL_WARN, "Error opening memory font: %s", | |
381 name); | |
382 return; | |
383 } | |
384 num_faces = face->num_faces; | |
21458
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
385 |
30200 | 386 pattern = |
31853 | 387 FcFreeTypeQueryFace(face, (unsigned char *) name, face_index, |
30200 | 388 FcConfigGetBlanks(priv->config)); |
389 if (!pattern) { | |
390 ass_msg(library, MSGL_WARN, "%s failed", "FcFreeTypeQueryFace"); | |
391 FT_Done_Face(face); | |
392 return; | |
393 } | |
21460 | 394 |
30200 | 395 fset = FcConfigGetFonts(priv->config, FcSetSystem); // somehow it failes when asked for FcSetApplication |
396 if (!fset) { | |
397 ass_msg(library, MSGL_WARN, "%s failed", "FcConfigGetFonts"); | |
398 FT_Done_Face(face); | |
399 return; | |
400 } | |
21460 | 401 |
30200 | 402 res = FcFontSetAdd(fset, pattern); |
403 if (!res) { | |
404 ass_msg(library, MSGL_WARN, "%s failed", "FcFontSetAdd"); | |
405 FT_Done_Face(face); | |
406 return; | |
407 } | |
21460 | 408 |
30200 | 409 FT_Done_Face(face); |
410 } | |
21458
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
411 } |
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
412 |
18937 | 413 /** |
414 * \brief Init fontconfig. | |
21630 | 415 * \param library libass library object |
416 * \param ftlibrary freetype library object | |
18937 | 417 * \param family default font family |
418 * \param path default font path | |
30200 | 419 * \param fc whether fontconfig should be used |
420 * \param config path to a fontconfig configuration file, or NULL | |
421 * \param update whether the fontconfig cache should be built/updated | |
18937 | 422 * \return pointer to fontconfig private data |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
423 */ |
30200 | 424 FCInstance *fontconfig_init(ASS_Library *library, |
425 FT_Library ftlibrary, const char *family, | |
426 const char *path, int fc, const char *config, | |
427 int update) | |
18937 | 428 { |
30200 | 429 int rc; |
430 FCInstance *priv = calloc(1, sizeof(FCInstance)); | |
431 const char *dir = library->fonts_dir; | |
432 int i; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
433 |
30200 | 434 if (!fc) { |
435 ass_msg(library, MSGL_WARN, | |
436 "Fontconfig disabled, only default font will be used."); | |
437 goto exit; | |
438 } | |
21458
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
439 |
30200 | 440 priv->config = FcConfigCreate(); |
441 rc = FcConfigParseAndLoad(priv->config, (unsigned char *) config, FcTrue); | |
442 if (!rc) { | |
443 ass_msg(library, MSGL_WARN, "No usable fontconfig configuration " | |
444 "file found, using fallback."); | |
445 FcConfigDestroy(priv->config); | |
446 priv->config = FcInitLoadConfig(); | |
447 rc++; | |
448 } | |
449 if (rc && update) { | |
450 FcConfigBuildFonts(priv->config); | |
451 } | |
27095 | 452 |
30200 | 453 if (!rc || !priv->config) { |
454 ass_msg(library, MSGL_FATAL, | |
455 "No valid fontconfig configuration found!"); | |
456 FcConfigDestroy(priv->config); | |
457 goto exit; | |
458 } | |
459 | |
460 for (i = 0; i < library->num_fontdata; ++i) | |
461 process_fontdata(priv, library, ftlibrary, i); | |
462 | |
463 if (dir) { | |
31853 | 464 ass_msg(library, MSGL_V, "Updating font cache"); |
27095 | 465 |
30200 | 466 rc = FcConfigAppFontAddDir(priv->config, (const FcChar8 *) dir); |
467 if (!rc) { | |
468 ass_msg(library, MSGL_WARN, "%s failed", "FcConfigAppFontAddDir"); | |
469 } | |
470 } | |
19340 | 471 |
30200 | 472 priv->family_default = family ? strdup(family) : NULL; |
473 exit: | |
474 priv->path_default = path ? strdup(path) : NULL; | |
475 priv->index_default = 0; | |
19340 | 476 |
30200 | 477 return priv; |
18937 | 478 } |
479 | |
30200 | 480 int fontconfig_update(FCInstance *priv) |
481 { | |
482 return FcConfigBuildFonts(priv->config); | |
483 } | |
484 | |
485 #else /* CONFIG_FONTCONFIG */ | |
18937 | 486 |
30200 | 487 char *fontconfig_select(ASS_Library *library, FCInstance *priv, |
488 const char *family, int treat_family_as_pattern, | |
489 unsigned bold, unsigned italic, int *index, | |
490 uint32_t code) | |
18937 | 491 { |
30200 | 492 *index = priv->index_default; |
493 char* res = priv->path_default ? strdup(priv->path_default) : 0; | |
494 return res; | |
18937 | 495 } |
496 | |
30200 | 497 FCInstance *fontconfig_init(ASS_Library *library, |
498 FT_Library ftlibrary, const char *family, | |
499 const char *path, int fc, const char *config, | |
500 int update) | |
18937 | 501 { |
30200 | 502 FCInstance *priv; |
19481 | 503 |
30200 | 504 ass_msg(library, MSGL_WARN, |
505 "Fontconfig disabled, only default font will be used."); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
506 |
30200 | 507 priv = calloc(1, sizeof(FCInstance)); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28942
diff
changeset
|
508 |
30200 | 509 priv->path_default = path ? strdup(path) : 0; |
510 priv->index_default = 0; | |
511 return priv; | |
512 } | |
513 | |
514 int fontconfig_update(FCInstance *priv) | |
515 { | |
516 // Do nothing | |
517 return 1; | |
18937 | 518 } |
519 | |
520 #endif | |
521 | |
30200 | 522 void fontconfig_done(FCInstance *priv) |
18937 | 523 { |
31875 | 524 |
525 if (priv) { | |
30200 | 526 #ifdef CONFIG_FONTCONFIG |
527 FcConfigDestroy(priv->config); | |
528 #endif | |
529 free(priv->path_default); | |
530 free(priv->family_default); | |
31875 | 531 } |
532 free(priv); | |
18937 | 533 } |