Mercurial > mplayer.hg
annotate libass/ass_fontconfig.c @ 36215:4eb27365d0b0
Add hack to fix compilation issues on OSX with broken libiconv.
Such a hack is not really a good solution, but since the
issue is relatively common it seems worth it for the moment.
author | reimar |
---|---|
date | Sun, 09 Jun 2013 13:54:47 +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 } |