Mercurial > mplayer.hg
annotate libass/ass_fontconfig.c @ 32254:70cdc0575aff
Drop obsolete CONFIG_IPV6 #definition for FFmpeg from config.h.
author | diego |
---|---|
date | Tue, 21 Sep 2010 14:16:57 +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 } |