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