]>
Commit | Line | Data |
---|---|---|
3ea8a859 AM |
1 | diff --git a/conf.d/30-metric-aliases.conf b/conf.d/30-metric-aliases.conf |
2 | index f25052a..0fd0b8a 100644 | |
3 | --- a/conf.d/30-metric-aliases.conf | |
4 | +++ b/conf.d/30-metric-aliases.conf | |
5 | @@ -230,6 +230,7 @@ | |
6 | <alias binding="same"> | |
7 | <family>Helvetica</family> | |
8 | <accept> | |
9 | + <family>TeX Gyre Heros</family> | |
10 | <family>Nimbus Sans L</family> | |
11 | </accept> | |
12 | </alias> | |
13 | @@ -237,6 +238,7 @@ | |
14 | <alias binding="same"> | |
15 | <family>Times</family> | |
16 | <accept> | |
17 | + <family>TeX Gyre Termes</family> | |
18 | <family>Nimbus Roman No9 L</family> | |
19 | </accept> | |
20 | </alias> | |
21 | @@ -253,6 +255,7 @@ | |
22 | <alias binding="same"> | |
23 | <family>Arial</family> | |
24 | <accept> | |
25 | + <family>TeX Gyre Heros</family> | |
26 | <family>Arimo</family> | |
27 | <family>Liberation Sans</family> | |
28 | <family>Albany</family> | |
29 | @@ -270,6 +273,7 @@ | |
30 | <alias binding="same"> | |
31 | <family>Times New Roman</family> | |
32 | <accept> | |
33 | + <family>TeX Gyre Termes</family> | |
34 | <family>Tinos</family> | |
35 | <family>Liberation Serif</family> | |
36 | <family>Thorndale</family> | |
37 | @@ -278,6 +282,13 @@ | |
38 | </alias> | |
39 | ||
40 | <alias binding="same"> | |
41 | + <family>Georgia</family> | |
42 | + <accept> | |
43 | + <family>Gelasio</family> | |
44 | + </accept> | |
45 | + </alias> | |
46 | + | |
47 | + <alias binding="same"> | |
48 | <family>Courier New</family> | |
49 | <accept> | |
50 | <family>Cousine</family> | |
51 | diff --git a/conf.d/45-latin.conf b/conf.d/45-latin.conf | |
52 | index 09fd526..aa62ed4 100644 | |
53 | --- a/conf.d/45-latin.conf | |
54 | +++ b/conf.d/45-latin.conf | |
55 | @@ -45,6 +45,22 @@ | |
56 | <family>Thorndale</family> | |
57 | <default><family>serif</family></default> | |
58 | </alias> | |
59 | + <alias> | |
60 | + <family>Georgia</family> | |
61 | + <default><family>serif</family></default> | |
62 | + </alias> | |
63 | + <alias> | |
64 | + <family>Garamond</family> | |
65 | + <default><family>serif</family></default> | |
66 | + </alias> | |
67 | + <alias> | |
68 | + <family>Palatino Linotype</family> | |
69 | + <default><family>serif</family></default> | |
70 | + </alias> | |
71 | + <alias> | |
72 | + <family>Trebuchet MS</family> | |
73 | + <default><family>serif</family></default> | |
74 | + </alias> | |
75 | <!-- | |
76 | Sans-serif faces | |
77 | --> | |
78 | diff --git a/configure.ac b/configure.ac | |
79 | index 0f129db..321fece 100644 | |
80 | --- a/configure.ac | |
81 | +++ b/configure.ac | |
82 | @@ -54,6 +54,9 @@ AC_SUBST(LIBT_VERSION_INFO) | |
83 | LIBT_CURRENT_MINUS_AGE=`expr $LIBT_CURRENT - $LIBT_AGE` | |
84 | AC_SUBST(LIBT_CURRENT_MINUS_AGE) | |
85 | ||
86 | +PKGCONFIG_REQUIRES= | |
87 | +PKGCONFIG_REQUIRES_PRIVATELY= | |
88 | + | |
89 | dnl ========================================================================== | |
90 | ||
91 | AC_CONFIG_HEADERS(config.h) | |
92 | @@ -161,6 +164,37 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([[ | |
93 | AC_MSG_RESULT([yes]) | |
94 | AC_DEFINE([HAVE_POSIX_FADVISE], [1], [Define to 1 if you have the 'posix_fadvise' function.]) | |
95 | ],[AC_MSG_RESULT([no])]) | |
96 | +if test "$os_win32" = "no"; then | |
97 | + AC_MSG_CHECKING([for scandir]) | |
98 | + AC_LINK_IFELSE([AC_LANG_SOURCE([[ | |
99 | + #include <dirent.h> | |
100 | + int comp(const struct dirent **, const struct dirent **); | |
101 | + int comp(const struct dirent **a, const struct dirent **b) { return 0; } | |
102 | + int main(void) { | |
103 | + struct dirent **d; | |
104 | + return scandir(".", &d, 0, &comp) >= 0; | |
105 | + } | |
106 | + ]])],[ | |
107 | + AC_MSG_RESULT([yes]) | |
108 | + AC_DEFINE([HAVE_SCANDIR], [1], [Define to 1 if you have the 'scandir' function.]) | |
109 | + ],[ | |
110 | + AC_LINK_IFELSE([AC_LANG_SOURCE([[ | |
111 | + #include <dirent.h> | |
112 | + int comp(const void *, const void *); | |
113 | + int comp(const void *a, const void *b) { return 0; } | |
114 | + int main(void) { | |
115 | + struct dirent **d; | |
116 | + return scandir(".", &d, 0, &comp) >= 0; | |
117 | + } | |
118 | + ]])],[ | |
119 | + AC_MSG_RESULT([yes]) | |
120 | + AC_DEFINE([HAVE_SCANDIR_VOID_P], [1], [Define to 1 if you have the 'scandir' function with int (* compar)(const void *, const void *)]) | |
121 | + ],[ | |
122 | + AC_MSG_ERROR([ | |
123 | +*** No scandir function available.]) | |
124 | + ]) | |
125 | + ]) | |
126 | +fi | |
127 | CFLAGS="$fc_saved_CFLAGS" | |
128 | ||
129 | # | |
130 | @@ -251,13 +285,14 @@ if test "x$enable_iconv" != "xno"; then | |
131 | AC_TRY_LINK([#include <iconv.h>], | |
132 | [iconv_open ("from", "to");], | |
133 | [iconv_type="libiconv" | |
134 | - use_iconv=1], | |
135 | + use_iconv=1 | |
136 | + ICONV_CFLAGS="$libiconv_cflags" | |
137 | + ICONV_LIBS="$libiconv_libs" | |
138 | + ], | |
139 | [use_iconv=0]) | |
140 | ||
141 | CFLAGS="$iconvsaved_CFLAGS" | |
142 | LIBS="$iconvsaved_LIBS" | |
143 | - ICONV_CFLAGS="$libiconv_cflags" | |
144 | - ICONV_LIBS="$libiconv_libs" | |
145 | fi | |
146 | if test "x$use_iconv" = "x0"; then | |
147 | AC_TRY_LINK([#include <iconv.h>], | |
148 | @@ -277,6 +312,7 @@ AC_DEFINE_UNQUOTED(USE_ICONV,$use_iconv,[Use iconv.]) | |
149 | # Checks for FreeType | |
150 | # | |
151 | PKG_CHECK_MODULES(FREETYPE, freetype2) | |
152 | +PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES freetype2" | |
153 | ||
154 | AC_SUBST(FREETYPE_LIBS) | |
155 | AC_SUBST(FREETYPE_CFLAGS) | |
156 | @@ -336,6 +372,8 @@ if test "$enable_libxml2" != "yes"; then | |
157 | else | |
158 | EXPAT_LIBS="-lexpat" | |
159 | fi | |
160 | + else | |
161 | + PKGCONFIG_REQUIRES_PRIVATELY="$PKGCONFIG_REQUIRES_PRIVATELY expat" | |
162 | fi | |
163 | ||
164 | expatsaved_CPPFLAGS="$CPPFLAGS" | |
165 | @@ -377,6 +415,7 @@ AC_ARG_ENABLE(libxml2, | |
166 | ||
167 | if test "$enable_libxml2" = "yes"; then | |
168 | PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.6]) | |
169 | + PKGCONFIG_REQUIRES_PRIVATELY="$PKGCONFIG_REQUIRES_PRIVATELY libxml-2.0" | |
170 | AC_DEFINE_UNQUOTED(ENABLE_LIBXML2,1,[Use libxml2 instead of Expat]) | |
171 | ||
172 | AC_SUBST(LIBXML2_CFLAGS) | |
173 | @@ -684,6 +723,12 @@ dnl include the header file for workaround of miscalculating size on autoconf | |
174 | dnl particularly for fat binaries | |
175 | AH_BOTTOM([#include "config-fixups.h"]) | |
176 | ||
177 | +dnl | |
178 | +dnl | |
179 | +AC_SUBST(PKGCONFIG_REQUIRES) | |
180 | +AC_SUBST(PKGCONFIG_REQUIRES_PRIVATELY) | |
181 | + | |
182 | +dnl | |
183 | AC_CONFIG_FILES([ | |
184 | Makefile | |
185 | fontconfig/Makefile | |
186 | diff --git a/fontconfig.pc.in b/fontconfig.pc.in | |
187 | index 9ef2c27..6e112bb 100644 | |
188 | --- a/fontconfig.pc.in | |
189 | +++ b/fontconfig.pc.in | |
190 | @@ -11,6 +11,8 @@ cachedir=@fc_cachedir@ | |
191 | Name: Fontconfig | |
192 | Description: Font configuration and customization library | |
193 | Version: @VERSION@ | |
194 | +Requires: @PKGCONFIG_REQUIRES@ | |
195 | +Requires.private: @PKGCONFIG_REQUIRES_PRIVATELY@ | |
196 | Libs: -L${libdir} -lfontconfig | |
197 | -Libs.private: @LIBXML2_LIBS@ @EXPAT_LIBS@ @FREETYPE_LIBS@ @ICONV_LIBS@ | |
198 | -Cflags: -I${includedir} | |
199 | +Libs.private: @EXPAT_LIBS@ @FREETYPE_LIBS@ @ICONV_LIBS@ @LIBXML2_LIBS@ | |
200 | +Cflags: -I${includedir} @EXPAT_CFLAGS@ @FREETYPE_CFLAGS@ @ICONV_CFLAGS@ @LIBXML2_CFLAGS@ | |
201 | diff --git a/fontconfig/fcprivate.h b/fontconfig/fcprivate.h | |
202 | index 18b8c08..210c1d8 100644 | |
203 | --- a/fontconfig/fcprivate.h | |
204 | +++ b/fontconfig/fcprivate.h | |
205 | @@ -48,8 +48,9 @@ | |
206 | __o__ = va_arg (va, const char *); \ | |
207 | if (!__o__) \ | |
208 | break; \ | |
209 | - __v__.type = va_arg (va, FcType); \ | |
210 | + __v__.type = va_arg (va, int); \ | |
211 | switch (__v__.type) { \ | |
212 | + case FcTypeUnknown: \ | |
213 | case FcTypeVoid: \ | |
214 | goto _FcPatternVapBuild_bail1; \ | |
215 | case FcTypeInteger: \ | |
216 | diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h | |
217 | index 422187b..39d1b1b 100644 | |
218 | --- a/fontconfig/fontconfig.h | |
219 | +++ b/fontconfig/fontconfig.h | |
220 | @@ -185,6 +185,7 @@ typedef int FcBool; | |
221 | #define FC_LCD_LEGACY 3 | |
222 | ||
223 | typedef enum _FcType { | |
224 | + FcTypeUnknown = -1, | |
225 | FcTypeVoid, | |
226 | FcTypeInteger, | |
227 | FcTypeDouble, | |
228 | diff --git a/src/fccache.c b/src/fccache.c | |
229 | index 9f1c298..e02d49e 100644 | |
230 | --- a/src/fccache.c | |
231 | +++ b/src/fccache.c | |
232 | @@ -830,34 +830,6 @@ bail1: | |
233 | return NULL; | |
234 | } | |
235 | ||
236 | - | |
237 | -#ifdef _WIN32 | |
238 | -#include <direct.h> | |
239 | -#define mkdir(path,mode) _mkdir(path) | |
240 | -#endif | |
241 | - | |
242 | -static FcBool | |
243 | -FcMakeDirectory (const FcChar8 *dir) | |
244 | -{ | |
245 | - FcChar8 *parent; | |
246 | - FcBool ret; | |
247 | - | |
248 | - if (strlen ((char *) dir) == 0) | |
249 | - return FcFalse; | |
250 | - | |
251 | - parent = FcStrDirname (dir); | |
252 | - if (!parent) | |
253 | - return FcFalse; | |
254 | - if (access ((char *) parent, F_OK) == 0) | |
255 | - ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0; | |
256 | - else if (access ((char *) parent, F_OK) == -1) | |
257 | - ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0; | |
258 | - else | |
259 | - ret = FcFalse; | |
260 | - FcStrFree (parent); | |
261 | - return ret; | |
262 | -} | |
263 | - | |
264 | /* write serialized state to the cache file */ | |
265 | FcBool | |
266 | FcDirCacheWrite (FcCache *cache, FcConfig *config) | |
267 | diff --git a/src/fccfg.c b/src/fccfg.c | |
268 | index fcdf73e..be738d5 100644 | |
269 | --- a/src/fccfg.c | |
270 | +++ b/src/fccfg.c | |
271 | @@ -214,10 +214,8 @@ FcSubstDestroy (FcSubst *s) | |
272 | while (s) | |
273 | { | |
274 | n = s->next; | |
275 | - if (s->test) | |
276 | - FcTestDestroy (s->test); | |
277 | - if (s->edit) | |
278 | - FcEditDestroy (s->edit); | |
279 | + if (s->rule) | |
280 | + FcRuleDestroy (s->rule); | |
281 | free (s); | |
282 | s = n; | |
283 | } | |
284 | @@ -226,20 +224,20 @@ FcSubstDestroy (FcSubst *s) | |
285 | FcExpr * | |
286 | FcConfigAllocExpr (FcConfig *config) | |
287 | { | |
288 | - if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end) | |
289 | - { | |
290 | - FcExprPage *new_page; | |
291 | + if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end) | |
292 | + { | |
293 | + FcExprPage *new_page; | |
294 | ||
295 | - new_page = malloc (sizeof (FcExprPage)); | |
296 | - if (!new_page) | |
297 | - return 0; | |
298 | + new_page = malloc (sizeof (FcExprPage)); | |
299 | + if (!new_page) | |
300 | + return 0; | |
301 | ||
302 | - new_page->next_page = config->expr_pool; | |
303 | - new_page->next = new_page->exprs; | |
304 | - config->expr_pool = new_page; | |
305 | - } | |
306 | + new_page->next_page = config->expr_pool; | |
307 | + new_page->next = new_page->exprs; | |
308 | + config->expr_pool = new_page; | |
309 | + } | |
310 | ||
311 | - return config->expr_pool->next++; | |
312 | + return config->expr_pool->next++; | |
313 | } | |
314 | ||
315 | FcConfig * | |
316 | @@ -644,15 +642,13 @@ FcConfigSetRescanInverval (FcConfig *config, int rescanInterval) | |
317 | return FcConfigSetRescanInterval (config, rescanInterval); | |
318 | } | |
319 | ||
320 | - | |
321 | FcBool | |
322 | -FcConfigAddEdit (FcConfig *config, | |
323 | - FcTest *test, | |
324 | - FcEdit *edit, | |
325 | +FcConfigAddRule (FcConfig *config, | |
326 | + FcRule *rule, | |
327 | FcMatchKind kind) | |
328 | { | |
329 | FcSubst *subst, **prev; | |
330 | - FcTest *t; | |
331 | + FcRule *r; | |
332 | int num; | |
333 | ||
334 | switch (kind) { | |
335 | @@ -673,15 +669,27 @@ FcConfigAddEdit (FcConfig *config, | |
336 | return FcFalse; | |
337 | for (; *prev; prev = &(*prev)->next); | |
338 | *prev = subst; | |
339 | - subst->next = 0; | |
340 | - subst->test = test; | |
341 | - subst->edit = edit; | |
342 | + subst->next = NULL; | |
343 | + subst->rule = rule; | |
344 | num = 0; | |
345 | - for (t = test; t; t = t->next) | |
346 | + for (r = rule; r; r = r->next) | |
347 | { | |
348 | - if (t->kind == FcMatchDefault) | |
349 | - t->kind = kind; | |
350 | - num++; | |
351 | + switch (r->type) | |
352 | + { | |
353 | + case FcRuleTest: | |
354 | + if (r->u.test && | |
355 | + r->u.test->kind == FcMatchDefault) | |
356 | + r->u.test->kind = kind; | |
357 | + if (r->u.test->object > FC_MAX_BASE_OBJECT) | |
358 | + num++; | |
359 | + break; | |
360 | + case FcRuleEdit: | |
361 | + if (r->u.edit->object > FC_MAX_BASE_OBJECT) | |
362 | + num++; | |
363 | + break; | |
364 | + default: | |
365 | + break; | |
366 | + } | |
367 | } | |
368 | if (config->maxObjects < num) | |
369 | config->maxObjects = num; | |
370 | @@ -721,7 +729,7 @@ FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf) | |
371 | ||
372 | FcBool | |
373 | FcConfigCompareValue (const FcValue *left_o, | |
374 | - FcOp op_, | |
375 | + unsigned int op_, | |
376 | const FcValue *right_o) | |
377 | { | |
378 | FcValue left = FcValueCanonicalize(left_o); | |
379 | @@ -736,6 +744,8 @@ FcConfigCompareValue (const FcValue *left_o, | |
380 | if (left.type == right.type) | |
381 | { | |
382 | switch (left.type) { | |
383 | + case FcTypeUnknown: | |
384 | + break; /* No way to guess how to compare for this object */ | |
385 | case FcTypeInteger: | |
386 | break; /* FcConfigPromote prevents this from happening */ | |
387 | case FcTypeDouble: | |
388 | @@ -1484,13 +1494,16 @@ FcConfigSubstituteWithPat (FcConfig *config, | |
389 | { | |
390 | FcValue v; | |
391 | FcSubst *s; | |
392 | - FcSubState *st; | |
393 | - int i; | |
394 | - FcTest *t; | |
395 | - FcEdit *e; | |
396 | - FcValueList *l; | |
397 | + FcRule *r; | |
398 | + FcValueList *l, **value = NULL; | |
399 | FcPattern *m; | |
400 | FcStrSet *strs; | |
401 | + FcObject object = FC_INVALID_OBJECT; | |
402 | + FcPatternElt **elt = NULL; | |
403 | + int i, nobjs; | |
404 | + FcBool retval = FcTrue; | |
405 | + | |
406 | +#define FC_OBJ_ID(_n_) ((_n_) > FC_MAX_BASE_OBJECT ? ((_n_) - FC_EXT_OBJ_INDEX) : (_n_)) | |
407 | ||
408 | if (!config) | |
409 | { | |
410 | @@ -1535,9 +1548,19 @@ FcConfigSubstituteWithPat (FcConfig *config, | |
411 | return FcFalse; | |
412 | } | |
413 | ||
414 | - st = (FcSubState *) malloc (config->maxObjects * sizeof (FcSubState)); | |
415 | - if (!st && config->maxObjects) | |
416 | - return FcFalse; | |
417 | + nobjs = FC_MAX_BASE_OBJECT + config->maxObjects + 2; | |
418 | + value = (FcValueList **) malloc (SIZEOF_VOID_P * nobjs); | |
419 | + if (!value) | |
420 | + { | |
421 | + retval = FcFalse; | |
422 | + goto bail1; | |
423 | + } | |
424 | + elt = (FcPatternElt **) malloc (SIZEOF_VOID_P * nobjs); | |
425 | + if (!elt) | |
426 | + { | |
427 | + retval = FcFalse; | |
428 | + goto bail1; | |
429 | + } | |
430 | ||
431 | if (FcDebug () & FC_DBG_EDIT) | |
432 | { | |
433 | @@ -1546,200 +1569,185 @@ FcConfigSubstituteWithPat (FcConfig *config, | |
434 | } | |
435 | for (; s; s = s->next) | |
436 | { | |
437 | - /* | |
438 | - * Check the tests to see if | |
439 | - * they all match the pattern | |
440 | - */ | |
441 | - for (t = s->test, i = 0; t; t = t->next, i++) | |
442 | + r = s->rule; | |
443 | + for (i = 0; i < nobjs; i++) | |
444 | { | |
445 | - if (FcDebug () & FC_DBG_EDIT) | |
446 | - { | |
447 | - printf ("FcConfigSubstitute test "); | |
448 | - FcTestPrint (t); | |
449 | - } | |
450 | - st[i].elt = 0; | |
451 | - if (kind == FcMatchFont && t->kind == FcMatchPattern) | |
452 | - m = p_pat; | |
453 | - else | |
454 | - m = p; | |
455 | - if (m) | |
456 | - st[i].elt = FcPatternObjectFindElt (m, t->object); | |
457 | - else | |
458 | - st[i].elt = 0; | |
459 | - /* | |
460 | - * If there's no such field in the font, | |
461 | - * then FcQualAll matches while FcQualAny does not | |
462 | - */ | |
463 | - if (!st[i].elt) | |
464 | - { | |
465 | - if (t->qual == FcQualAll) | |
466 | + elt[i] = NULL; | |
467 | + value[i] = NULL; | |
468 | + } | |
469 | + for (; r; r = r->next) | |
470 | + { | |
471 | + switch (r->type) { | |
472 | + case FcRuleUnknown: | |
473 | + /* shouldn't be reached */ | |
474 | + break; | |
475 | + case FcRuleTest: | |
476 | + object = FC_OBJ_ID (r->u.test->object); | |
477 | + /* | |
478 | + * Check the tests to see if | |
479 | + * they all match the pattern | |
480 | + */ | |
481 | + if (FcDebug () & FC_DBG_EDIT) | |
482 | { | |
483 | - st[i].value = 0; | |
484 | - continue; | |
485 | + printf ("FcConfigSubstitute test "); | |
486 | + FcTestPrint (r->u.test); | |
487 | } | |
488 | + if (kind == FcMatchFont && r->u.test->kind == FcMatchPattern) | |
489 | + m = p_pat; | |
490 | else | |
491 | - break; | |
492 | - } | |
493 | - /* | |
494 | - * Check to see if there is a match, mark the location | |
495 | - * to apply match-relative edits | |
496 | - */ | |
497 | - st[i].value = FcConfigMatchValueList (m, p_pat, kind, t, st[i].elt->values); | |
498 | - if (!st[i].value) | |
499 | - break; | |
500 | - if (t->qual == FcQualFirst && st[i].value != st[i].elt->values) | |
501 | - break; | |
502 | - if (t->qual == FcQualNotFirst && st[i].value == st[i].elt->values) | |
503 | - break; | |
504 | - } | |
505 | - if (t) | |
506 | - { | |
507 | - if (FcDebug () & FC_DBG_EDIT) | |
508 | - printf ("No match\n"); | |
509 | - continue; | |
510 | - } | |
511 | - if (FcDebug () & FC_DBG_EDIT) | |
512 | - { | |
513 | - printf ("Substitute "); | |
514 | - FcSubstPrint (s); | |
515 | - } | |
516 | - for (e = s->edit; e; e = e->next) | |
517 | - { | |
518 | - /* | |
519 | - * Evaluate the list of expressions | |
520 | - */ | |
521 | - l = FcConfigValues (p, p_pat,kind, e->expr, e->binding); | |
522 | - /* | |
523 | - * Locate any test associated with this field, skipping | |
524 | - * tests associated with the pattern when substituting in | |
525 | - * the font | |
526 | - */ | |
527 | - for (t = s->test, i = 0; t; t = t->next, i++) | |
528 | - { | |
529 | - if ((t->kind == FcMatchFont || kind == FcMatchPattern) && | |
530 | - t->object == e->object) | |
531 | + m = p; | |
532 | + if (m) | |
533 | + elt[object] = FcPatternObjectFindElt (m, r->u.test->object); | |
534 | + /* | |
535 | + * If there's no such field in the font, | |
536 | + * then FcQualAll matches while FcQualAny does not | |
537 | + */ | |
538 | + if (!elt[object]) | |
539 | { | |
540 | - /* | |
541 | - * KLUDGE - the pattern may have been reallocated or | |
542 | - * things may have been inserted or deleted above | |
543 | - * this element by other edits. Go back and find | |
544 | - * the element again | |
545 | - */ | |
546 | - if (e != s->edit && st[i].elt) | |
547 | - st[i].elt = FcPatternObjectFindElt (p, t->object); | |
548 | - if (!st[i].elt) | |
549 | - t = 0; | |
550 | - break; | |
551 | + if (r->u.test->qual == FcQualAll) | |
552 | + { | |
553 | + value[object] = NULL; | |
554 | + continue; | |
555 | + } | |
556 | + else | |
557 | + { | |
558 | + if (FcDebug () & FC_DBG_EDIT) | |
559 | + printf ("No match\n"); | |
560 | + goto bail; | |
561 | + } | |
562 | } | |
563 | - } | |
564 | - switch (FC_OP_GET_OP (e->op)) { | |
565 | - case FcOpAssign: | |
566 | /* | |
567 | - * If there was a test, then replace the matched | |
568 | - * value with the new list of values | |
569 | + * Check to see if there is a match, mark the location | |
570 | + * to apply match-relative edits | |
571 | */ | |
572 | - if (t) | |
573 | + value[object] = FcConfigMatchValueList (m, p_pat, kind, r->u.test, elt[object]->values); | |
574 | + if (!value[object] || | |
575 | + (r->u.test->qual == FcQualFirst && value[object] != elt[object]->values) || | |
576 | + (r->u.test->qual == FcQualNotFirst && value[object] == elt[object]->values)) | |
577 | { | |
578 | - FcValueList *thisValue = st[i].value; | |
579 | - FcValueList *nextValue = thisValue; | |
580 | - | |
581 | + if (FcDebug () & FC_DBG_EDIT) | |
582 | + printf ("No match\n"); | |
583 | + goto bail; | |
584 | + } | |
585 | + break; | |
586 | + case FcRuleEdit: | |
587 | + object = FC_OBJ_ID (r->u.edit->object); | |
588 | + if (FcDebug () & FC_DBG_EDIT) | |
589 | + { | |
590 | + printf ("Substitute "); | |
591 | + FcEditPrint (r->u.edit); | |
592 | + printf ("\n\n"); | |
593 | + } | |
594 | + /* | |
595 | + * Evaluate the list of expressions | |
596 | + */ | |
597 | + l = FcConfigValues (p, p_pat,kind, r->u.edit->expr, r->u.edit->binding); | |
598 | + | |
599 | + switch (FC_OP_GET_OP (r->u.edit->op)) { | |
600 | + case FcOpAssign: | |
601 | /* | |
602 | - * Append the new list of values after the current value | |
603 | + * If there was a test, then replace the matched | |
604 | + * value with the new list of values | |
605 | */ | |
606 | - FcConfigAdd (&st[i].elt->values, thisValue, FcTrue, l, e->object); | |
607 | + if (value[object]) | |
608 | + { | |
609 | + FcValueList *thisValue = value[object]; | |
610 | + FcValueList *nextValue = l; | |
611 | + | |
612 | + /* | |
613 | + * Append the new list of values after the current value | |
614 | + */ | |
615 | + FcConfigAdd (&elt[object]->values, thisValue, FcTrue, l, r->u.edit->object); | |
616 | + /* | |
617 | + * Delete the marked value | |
618 | + */ | |
619 | + if (thisValue) | |
620 | + FcConfigDel (&elt[object]->values, thisValue); | |
621 | + /* | |
622 | + * Adjust a pointer into the value list to ensure | |
623 | + * future edits occur at the same place | |
624 | + */ | |
625 | + value[object] = nextValue; | |
626 | + break; | |
627 | + } | |
628 | + /* fall through ... */ | |
629 | + case FcOpAssignReplace: | |
630 | /* | |
631 | - * Delete the marked value | |
632 | + * Delete all of the values and insert | |
633 | + * the new set | |
634 | */ | |
635 | - if (thisValue) | |
636 | - FcConfigDel (&st[i].elt->values, thisValue); | |
637 | + FcConfigPatternDel (p, r->u.edit->object); | |
638 | + FcConfigPatternAdd (p, r->u.edit->object, l, FcTrue); | |
639 | /* | |
640 | - * Adjust any pointers into the value list to ensure | |
641 | - * future edits occur at the same place | |
642 | + * Adjust a pointer into the value list as they no | |
643 | + * longer point to anything valid | |
644 | */ | |
645 | - for (t = s->test, i = 0; t; t = t->next, i++) | |
646 | + value[object] = NULL; | |
647 | + break; | |
648 | + case FcOpPrepend: | |
649 | + if (value[object]) | |
650 | { | |
651 | - if (st[i].value == thisValue) | |
652 | - st[i].value = nextValue; | |
653 | + FcConfigAdd (&elt[object]->values, value[object], FcFalse, l, r->u.edit->object); | |
654 | + break; | |
655 | } | |
656 | + /* fall through ... */ | |
657 | + case FcOpPrependFirst: | |
658 | + FcConfigPatternAdd (p, r->u.edit->object, l, FcFalse); | |
659 | break; | |
660 | - } | |
661 | - /* fall through ... */ | |
662 | - case FcOpAssignReplace: | |
663 | - /* | |
664 | - * Delete all of the values and insert | |
665 | - * the new set | |
666 | - */ | |
667 | - FcConfigPatternDel (p, e->object); | |
668 | - FcConfigPatternAdd (p, e->object, l, FcTrue); | |
669 | - /* | |
670 | - * Adjust any pointers into the value list as they no | |
671 | - * longer point to anything valid | |
672 | - */ | |
673 | - if (t) | |
674 | - { | |
675 | - FcPatternElt *thisElt = st[i].elt; | |
676 | - for (t = s->test, i = 0; t; t = t->next, i++) | |
677 | + case FcOpAppend: | |
678 | + if (value[object]) | |
679 | { | |
680 | - if (st[i].elt == thisElt) | |
681 | - st[i].value = 0; | |
682 | + FcConfigAdd (&elt[object]->values, value[object], FcTrue, l, r->u.edit->object); | |
683 | + break; | |
684 | } | |
685 | - } | |
686 | - break; | |
687 | - case FcOpPrepend: | |
688 | - if (t) | |
689 | - { | |
690 | - FcConfigAdd (&st[i].elt->values, st[i].value, FcFalse, l, e->object); | |
691 | + /* fall through ... */ | |
692 | + case FcOpAppendLast: | |
693 | + FcConfigPatternAdd (p, r->u.edit->object, l, FcTrue); | |
694 | break; | |
695 | - } | |
696 | - /* fall through ... */ | |
697 | - case FcOpPrependFirst: | |
698 | - FcConfigPatternAdd (p, e->object, l, FcFalse); | |
699 | - break; | |
700 | - case FcOpAppend: | |
701 | - if (t) | |
702 | - { | |
703 | - FcConfigAdd (&st[i].elt->values, st[i].value, FcTrue, l, e->object); | |
704 | + case FcOpDelete: | |
705 | + if (value[object]) | |
706 | + { | |
707 | + FcConfigDel (&elt[object]->values, value[object]); | |
708 | + break; | |
709 | + } | |
710 | + /* fall through ... */ | |
711 | + case FcOpDeleteAll: | |
712 | + FcConfigPatternDel (p, r->u.edit->object); | |
713 | + break; | |
714 | + default: | |
715 | + FcValueListDestroy (l); | |
716 | break; | |
717 | } | |
718 | - /* fall through ... */ | |
719 | - case FcOpAppendLast: | |
720 | - FcConfigPatternAdd (p, e->object, l, FcTrue); | |
721 | - break; | |
722 | - case FcOpDelete: | |
723 | - if (t) | |
724 | + /* | |
725 | + * Now go through the pattern and eliminate | |
726 | + * any properties without data | |
727 | + */ | |
728 | + FcConfigPatternCanon (p, r->u.edit->object); | |
729 | + | |
730 | + if (FcDebug () & FC_DBG_EDIT) | |
731 | { | |
732 | - FcConfigDel (&st[i].elt->values, st[i].value); | |
733 | - break; | |
734 | + printf ("FcConfigSubstitute edit"); | |
735 | + FcPatternPrint (p); | |
736 | } | |
737 | - /* fall through ... */ | |
738 | - case FcOpDeleteAll: | |
739 | - FcConfigPatternDel (p, e->object); | |
740 | - break; | |
741 | - default: | |
742 | - FcValueListDestroy (l); | |
743 | break; | |
744 | } | |
745 | } | |
746 | - /* | |
747 | - * Now go through the pattern and eliminate | |
748 | - * any properties without data | |
749 | - */ | |
750 | - for (e = s->edit; e; e = e->next) | |
751 | - FcConfigPatternCanon (p, e->object); | |
752 | - | |
753 | - if (FcDebug () & FC_DBG_EDIT) | |
754 | - { | |
755 | - printf ("FcConfigSubstitute edit"); | |
756 | - FcPatternPrint (p); | |
757 | - } | |
758 | + bail:; | |
759 | } | |
760 | - free (st); | |
761 | if (FcDebug () & FC_DBG_EDIT) | |
762 | { | |
763 | printf ("FcConfigSubstitute done"); | |
764 | FcPatternPrint (p); | |
765 | } | |
766 | - return FcTrue; | |
767 | +bail1: | |
768 | + if (elt) | |
769 | + free (elt); | |
770 | + if (value) | |
771 | + free (value); | |
772 | + | |
773 | +#undef FC_OBJ_ID | |
774 | + | |
775 | + return retval; | |
776 | } | |
777 | ||
778 | FcBool | |
779 | diff --git a/src/fccompat.c b/src/fccompat.c | |
780 | index a217160..d4f88c8 100644 | |
781 | --- a/src/fccompat.c | |
782 | +++ b/src/fccompat.c | |
783 | @@ -219,3 +219,30 @@ FcRandom(void) | |
784 | ||
785 | return result; | |
786 | } | |
787 | + | |
788 | +#ifdef _WIN32 | |
789 | +#include <direct.h> | |
790 | +#define mkdir(path,mode) _mkdir(path) | |
791 | +#endif | |
792 | + | |
793 | +FcBool | |
794 | +FcMakeDirectory (const FcChar8 *dir) | |
795 | +{ | |
796 | + FcChar8 *parent; | |
797 | + FcBool ret; | |
798 | + | |
799 | + if (strlen ((char *) dir) == 0) | |
800 | + return FcFalse; | |
801 | + | |
802 | + parent = FcStrDirname (dir); | |
803 | + if (!parent) | |
804 | + return FcFalse; | |
805 | + if (access ((char *) parent, F_OK) == 0) | |
806 | + ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0; | |
807 | + else if (access ((char *) parent, F_OK) == -1) | |
808 | + ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0; | |
809 | + else | |
810 | + ret = FcFalse; | |
811 | + FcStrFree (parent); | |
812 | + return ret; | |
813 | +} | |
814 | diff --git a/src/fcdbg.c b/src/fcdbg.c | |
815 | index 9d02f5a..d74bc27 100644 | |
816 | --- a/src/fcdbg.c | |
817 | +++ b/src/fcdbg.c | |
818 | @@ -30,6 +30,9 @@ static void | |
819 | _FcValuePrintFile (FILE *f, const FcValue v) | |
820 | { | |
821 | switch (v.type) { | |
822 | + case FcTypeUnknown: | |
823 | + fprintf (f, "<unknown>"); | |
824 | + break; | |
825 | case FcTypeVoid: | |
826 | fprintf (f, "<void>"); | |
827 | break; | |
828 | @@ -98,6 +101,10 @@ FcValueBindingPrint (const FcValueListPtr l) | |
829 | case FcValueBindingSame: | |
830 | printf ("(=)"); | |
831 | break; | |
832 | + default: | |
833 | + /* shouldn't be reached */ | |
834 | + printf ("(?)"); | |
835 | + break; | |
836 | } | |
837 | } | |
838 | ||
839 | @@ -420,21 +427,38 @@ FcEditPrint (const FcEdit *edit) | |
840 | void | |
841 | FcSubstPrint (const FcSubst *subst) | |
842 | { | |
843 | - FcEdit *e; | |
844 | - FcTest *t; | |
845 | + FcRule *r; | |
846 | + FcRuleType last_type = FcRuleUnknown; | |
847 | ||
848 | printf ("match\n"); | |
849 | - for (t = subst->test; t; t = t->next) | |
850 | - { | |
851 | - printf ("\t"); | |
852 | - FcTestPrint (t); | |
853 | - } | |
854 | - printf ("edit\n"); | |
855 | - for (e = subst->edit; e; e = e->next) | |
856 | + for (r = subst->rule; r; r = r->next) | |
857 | { | |
858 | + if (last_type != r->type) | |
859 | + { | |
860 | + switch (r->type) { | |
861 | + case FcRuleTest: | |
862 | + printf ("[test]\n"); | |
863 | + break; | |
864 | + case FcRuleEdit: | |
865 | + printf ("[edit]\n"); | |
866 | + break; | |
867 | + default: | |
868 | + break; | |
869 | + } | |
870 | + last_type = r->type; | |
871 | + } | |
872 | printf ("\t"); | |
873 | - FcEditPrint (e); | |
874 | - printf (";\n"); | |
875 | + switch (r->type) { | |
876 | + case FcRuleTest: | |
877 | + FcTestPrint (r->u.test); | |
878 | + break; | |
879 | + case FcRuleEdit: | |
880 | + FcEditPrint (r->u.edit); | |
881 | + printf (";\n"); | |
882 | + break; | |
883 | + default: | |
884 | + break; | |
885 | + } | |
886 | } | |
887 | printf ("\n"); | |
888 | } | |
889 | diff --git a/src/fcdir.c b/src/fcdir.c | |
890 | index dc580bb..b040a28 100644 | |
891 | --- a/src/fcdir.c | |
892 | +++ b/src/fcdir.c | |
893 | @@ -49,6 +49,16 @@ FcFileIsLink (const FcChar8 *file) | |
894 | #endif | |
895 | } | |
896 | ||
897 | +FcBool | |
898 | +FcFileIsFile (const FcChar8 *file) | |
899 | +{ | |
900 | + struct stat statb; | |
901 | + | |
902 | + if (FcStat (file, &statb) != 0) | |
903 | + return FcFalse; | |
904 | + return S_ISREG (statb.st_mode); | |
905 | +} | |
906 | + | |
907 | static FcBool | |
908 | FcFileScanFontConfig (FcFontSet *set, | |
909 | FcBlanks *blanks, | |
910 | diff --git a/src/fchash.c b/src/fchash.c | |
911 | index 92585a6..7216bee 100644 | |
912 | --- a/src/fchash.c | |
913 | +++ b/src/fchash.c | |
914 | @@ -190,14 +190,14 @@ FcHashGetSHA256Digest (const FcChar8 *input_strings, | |
915 | } | |
916 | /* set input size at the end */ | |
917 | len *= 8; | |
918 | - block[63 - 0] = len & 0xff; | |
919 | - block[63 - 1] = (len >> 8) & 0xff; | |
920 | - block[63 - 2] = (len >> 16) & 0xff; | |
921 | - block[63 - 3] = (len >> 24) & 0xff; | |
922 | - block[63 - 4] = (len >> 32) & 0xff; | |
923 | - block[63 - 5] = (len >> 40) & 0xff; | |
924 | - block[63 - 6] = (len >> 48) & 0xff; | |
925 | - block[63 - 7] = (len >> 56) & 0xff; | |
926 | + block[63 - 0] = (uint64_t)len & 0xff; | |
927 | + block[63 - 1] = ((uint64_t)len >> 8) & 0xff; | |
928 | + block[63 - 2] = ((uint64_t)len >> 16) & 0xff; | |
929 | + block[63 - 3] = ((uint64_t)len >> 24) & 0xff; | |
930 | + block[63 - 4] = ((uint64_t)len >> 32) & 0xff; | |
931 | + block[63 - 5] = ((uint64_t)len >> 40) & 0xff; | |
932 | + block[63 - 6] = ((uint64_t)len >> 48) & 0xff; | |
933 | + block[63 - 7] = ((uint64_t)len >> 56) & 0xff; | |
934 | FcHashComputeSHA256Digest (ret, block); | |
935 | ||
936 | return FcHashSHA256ToString (ret); | |
937 | @@ -226,7 +226,7 @@ FcHashGetSHA256DigestFromFile (const FcChar8 *filename) | |
938 | { | |
939 | if ((len = fread (ibuf, sizeof (char), 64, fp)) < 64) | |
940 | { | |
941 | - long v; | |
942 | + uint64_t v; | |
943 | ||
944 | /* add a padding */ | |
945 | memset (&ibuf[len], 0, 64 - len); | |
946 | @@ -281,7 +281,7 @@ FcHashGetSHA256DigestFromMemory (const char *fontdata, | |
947 | { | |
948 | if ((length - i) < 64) | |
949 | { | |
950 | - long v; | |
951 | + uint64_t v; | |
952 | size_t n; | |
953 | ||
954 | /* add a padding */ | |
955 | diff --git a/src/fcint.h b/src/fcint.h | |
956 | index 65bf333..ec0c674 100644 | |
957 | --- a/src/fcint.h | |
958 | +++ b/src/fcint.h | |
959 | @@ -37,6 +37,7 @@ | |
960 | #include <ctype.h> | |
961 | #include <assert.h> | |
962 | #include <errno.h> | |
963 | +#include <limits.h> | |
964 | #include <unistd.h> | |
965 | #include <stddef.h> | |
966 | #include <sys/types.h> | |
967 | @@ -85,7 +86,7 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA; | |
968 | #define FC_DBG_CONFIG 1024 | |
969 | #define FC_DBG_LANGSET 2048 | |
970 | ||
971 | -#define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] | |
972 | +#define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] FC_UNUSED | |
973 | #define _FC_ASSERT_STATIC0(_line, _cond) _FC_ASSERT_STATIC1 (_line, (_cond)) | |
974 | #define FC_ASSERT_STATIC(_cond) _FC_ASSERT_STATIC0 (__LINE__, (_cond)) | |
975 | ||
976 | @@ -107,7 +108,9 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA; | |
977 | FC_ASSERT_STATIC (sizeof (FcRef) == sizeof (int)); | |
978 | ||
979 | typedef enum _FcValueBinding { | |
980 | - FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame | |
981 | + FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame, | |
982 | + /* to make sure sizeof (FcValueBinding) == 4 even with -fshort-enums */ | |
983 | + FcValueBindingEnd = INT_MAX | |
984 | } FcValueBinding; | |
985 | ||
986 | #define FcStrdup(s) ((FcChar8 *) strdup ((const char *) (s))) | |
987 | @@ -171,6 +174,11 @@ typedef struct _FcValueList { | |
988 | ||
989 | typedef int FcObject; | |
990 | ||
991 | +/* The 1000 is to leave some room for future added internal objects, such | |
992 | + * that caches from newer fontconfig can still be used with older fontconfig | |
993 | + * without getting confused. */ | |
994 | +#define FC_EXT_OBJ_INDEX 1000 | |
995 | + | |
996 | typedef struct _FcPatternElt *FcPatternEltPtr; | |
997 | ||
998 | /* | |
999 | @@ -271,7 +279,6 @@ typedef enum _FcQual { | |
1000 | #define FcMatchDefault ((FcMatchKind) -1) | |
1001 | ||
1002 | typedef struct _FcTest { | |
1003 | - struct _FcTest *next; | |
1004 | FcMatchKind kind; | |
1005 | FcQual qual; | |
1006 | FcObject object; | |
1007 | @@ -280,17 +287,28 @@ typedef struct _FcTest { | |
1008 | } FcTest; | |
1009 | ||
1010 | typedef struct _FcEdit { | |
1011 | - struct _FcEdit *next; | |
1012 | FcObject object; | |
1013 | FcOp op; | |
1014 | FcExpr *expr; | |
1015 | FcValueBinding binding; | |
1016 | } FcEdit; | |
1017 | ||
1018 | +typedef enum _FcRuleType { | |
1019 | + FcRuleUnknown, FcRuleTest, FcRuleEdit | |
1020 | +} FcRuleType; | |
1021 | + | |
1022 | +typedef struct _FcRule { | |
1023 | + struct _FcRule *next; | |
1024 | + FcRuleType type; | |
1025 | + union { | |
1026 | + FcTest *test; | |
1027 | + FcEdit *edit; | |
1028 | + } u; | |
1029 | +} FcRule; | |
1030 | + | |
1031 | typedef struct _FcSubst { | |
1032 | struct _FcSubst *next; | |
1033 | - FcTest *test; | |
1034 | - FcEdit *edit; | |
1035 | + FcRule *rule; | |
1036 | } FcSubst; | |
1037 | ||
1038 | typedef struct _FcCharLeaf { | |
1039 | @@ -610,10 +628,9 @@ FcPrivate FcBool | |
1040 | FcConfigAddBlank (FcConfig *config, | |
1041 | FcChar32 blank); | |
1042 | ||
1043 | -FcPrivate FcBool | |
1044 | -FcConfigAddEdit (FcConfig *config, | |
1045 | - FcTest *test, | |
1046 | - FcEdit *edit, | |
1047 | +FcBool | |
1048 | +FcConfigAddRule (FcConfig *config, | |
1049 | + FcRule *rule, | |
1050 | FcMatchKind kind); | |
1051 | ||
1052 | FcPrivate void | |
1053 | @@ -623,7 +640,7 @@ FcConfigSetFonts (FcConfig *config, | |
1054 | ||
1055 | FcPrivate FcBool | |
1056 | FcConfigCompareValue (const FcValue *m, | |
1057 | - FcOp op, | |
1058 | + unsigned int op_, | |
1059 | const FcValue *v); | |
1060 | ||
1061 | FcPrivate FcBool | |
1062 | @@ -730,6 +747,9 @@ FcMakeTempfile (char *template); | |
1063 | FcPrivate int32_t | |
1064 | FcRandom (void); | |
1065 | ||
1066 | +FcPrivate FcBool | |
1067 | +FcMakeDirectory (const FcChar8 *dir); | |
1068 | + | |
1069 | /* fcdbg.c */ | |
1070 | ||
1071 | FcPrivate void | |
1072 | @@ -788,6 +808,9 @@ FcPrivate FcBool | |
1073 | FcFileIsLink (const FcChar8 *file); | |
1074 | ||
1075 | FcPrivate FcBool | |
1076 | +FcFileIsFile (const FcChar8 *file); | |
1077 | + | |
1078 | +FcPrivate FcBool | |
1079 | FcFileScanConfig (FcFontSet *set, | |
1080 | FcStrSet *dirs, | |
1081 | FcBlanks *blanks, | |
1082 | @@ -840,6 +863,9 @@ FcTestDestroy (FcTest *test); | |
1083 | FcPrivate void | |
1084 | FcEditDestroy (FcEdit *e); | |
1085 | ||
1086 | +void | |
1087 | +FcRuleDestroy (FcRule *rule); | |
1088 | + | |
1089 | /* fclang.c */ | |
1090 | FcPrivate FcLangSet * | |
1091 | FcFreeTypeLangSet (const FcCharSet *charset, | |
1092 | diff --git a/src/fclist.c b/src/fclist.c | |
1093 | index b7ae899..c56e24c 100644 | |
1094 | --- a/src/fclist.c | |
1095 | +++ b/src/fclist.c | |
1096 | @@ -252,6 +252,7 @@ FcListValueHash (FcValue *value) | |
1097 | { | |
1098 | FcValue v = FcValueCanonicalize(value); | |
1099 | switch (v.type) { | |
1100 | + case FcTypeUnknown: | |
1101 | case FcTypeVoid: | |
1102 | return 0; | |
1103 | case FcTypeInteger: | |
1104 | diff --git a/src/fcmatch.c b/src/fcmatch.c | |
1105 | index 10976d6..dec92b9 100644 | |
1106 | --- a/src/fcmatch.c | |
1107 | +++ b/src/fcmatch.c | |
1108 | @@ -245,6 +245,8 @@ typedef enum _FcMatcherPriorityDummy { | |
1109 | typedef enum _FcMatcherPriority { | |
1110 | PRI1(HASH), | |
1111 | PRI1(FILE), | |
1112 | + PRI1(FONTFORMAT), | |
1113 | + PRI1(SCALABLE), | |
1114 | PRI1(FOUNDRY), | |
1115 | PRI1(CHARSET), | |
1116 | PRI_FAMILY_STRONG, | |
1117 | diff --git a/src/fcname.c b/src/fcname.c | |
1118 | index 6dd4d49..712b2fa 100644 | |
1119 | --- a/src/fcname.c | |
1120 | +++ b/src/fcname.c | |
1121 | @@ -76,6 +76,8 @@ FcObjectValidType (FcObject object, FcType type) | |
1122 | ||
1123 | if (t) { | |
1124 | switch ((int) t->type) { | |
1125 | + case FcTypeUnknown: | |
1126 | + return FcTrue; | |
1127 | case FcTypeDouble: | |
1128 | case FcTypeInteger: | |
1129 | if (type == FcTypeDouble || type == FcTypeInteger) | |
1130 | @@ -86,7 +88,7 @@ FcObjectValidType (FcObject object, FcType type) | |
1131 | return FcTrue; | |
1132 | break; | |
1133 | default: | |
1134 | - if (t->type == (unsigned int) -1 || type == t->type) | |
1135 | + if (type == t->type) | |
1136 | return FcTrue; | |
1137 | break; | |
1138 | } | |
1139 | @@ -318,6 +320,12 @@ FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *l | |
1140 | ||
1141 | while ((c = *cur)) | |
1142 | { | |
1143 | + if (!isspace (c)) | |
1144 | + break; | |
1145 | + ++cur; | |
1146 | + } | |
1147 | + while ((c = *cur)) | |
1148 | + { | |
1149 | if (c == '\\') | |
1150 | { | |
1151 | ++cur; | |
1152 | @@ -468,6 +476,7 @@ FcNameUnparseValue (FcStrBuf *buf, | |
1153 | FcValue v = FcValueCanonicalize(v0); | |
1154 | ||
1155 | switch (v.type) { | |
1156 | + case FcTypeUnknown: | |
1157 | case FcTypeVoid: | |
1158 | return FcTrue; | |
1159 | case FcTypeInteger: | |
1160 | diff --git a/src/fcobjs.c b/src/fcobjs.c | |
1161 | index 146ca70..bad9824 100644 | |
1162 | --- a/src/fcobjs.c | |
1163 | +++ b/src/fcobjs.c | |
1164 | @@ -37,7 +37,7 @@ FcObjectTypeLookup (register const char *str, register unsigned int len); | |
1165 | /* The 1000 is to leave some room for future added internal objects, such | |
1166 | * that caches from newer fontconfig can still be used with older fontconfig | |
1167 | * without getting confused. */ | |
1168 | -static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + 1000; | |
1169 | +static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX; | |
1170 | struct FcObjectOtherTypeInfo { | |
1171 | struct FcObjectOtherTypeInfo *next; | |
1172 | FcObjectType object; | |
1173 | @@ -63,7 +63,7 @@ retry: | |
1174 | return NULL; | |
1175 | ||
1176 | ot->object.object = (const char *) FcStrdup (str); | |
1177 | - ot->object.type = -1; | |
1178 | + ot->object.type = FcTypeUnknown; | |
1179 | ot->id = fc_atomic_int_add (next_id, +1); | |
1180 | ot->next = ots; | |
1181 | ||
1182 | diff --git a/src/fcobjs.h b/src/fcobjs.h | |
1183 | index 682fe6a..87c7319 100644 | |
1184 | --- a/src/fcobjs.h | |
1185 | +++ b/src/fcobjs.h | |
1186 | @@ -23,7 +23,7 @@ FC_OBJECT (FILE, FcTypeString, FcCompareFilename) | |
1187 | FC_OBJECT (INDEX, FcTypeInteger, NULL) | |
1188 | FC_OBJECT (RASTERIZER, FcTypeString, FcCompareString) | |
1189 | FC_OBJECT (OUTLINE, FcTypeBool, FcCompareBool) | |
1190 | -FC_OBJECT (SCALABLE, FcTypeBool, NULL) | |
1191 | +FC_OBJECT (SCALABLE, FcTypeBool, FcCompareBool) | |
1192 | FC_OBJECT (DPI, FcTypeDouble, NULL) | |
1193 | FC_OBJECT (RGBA, FcTypeInteger, NULL) | |
1194 | FC_OBJECT (SCALE, FcTypeDouble, NULL) | |
1195 | @@ -35,7 +35,7 @@ FC_OBJECT (CHARSET, FcTypeCharSet, FcCompareCharSet) | |
1196 | FC_OBJECT (LANG, FcTypeLangSet, FcCompareLang) | |
1197 | FC_OBJECT (FONTVERSION, FcTypeInteger, FcCompareNumber) | |
1198 | FC_OBJECT (CAPABILITY, FcTypeString, NULL) | |
1199 | -FC_OBJECT (FONTFORMAT, FcTypeString, NULL) | |
1200 | +FC_OBJECT (FONTFORMAT, FcTypeString, FcCompareString) | |
1201 | FC_OBJECT (EMBOLDEN, FcTypeBool, NULL) | |
1202 | FC_OBJECT (EMBEDDED_BITMAP, FcTypeBool, NULL) | |
1203 | FC_OBJECT (DECORATIVE, FcTypeBool, FcCompareBool) | |
1204 | diff --git a/src/fcpat.c b/src/fcpat.c | |
1205 | index 25bff64..0614ac2 100644 | |
1206 | --- a/src/fcpat.c | |
1207 | +++ b/src/fcpat.c | |
1208 | @@ -246,6 +246,8 @@ FcValueEqual (FcValue va, FcValue vb) | |
1209 | return FcFalse; | |
1210 | } | |
1211 | switch (va.type) { | |
1212 | + case FcTypeUnknown: | |
1213 | + return FcFalse; /* don't know how to compare this object */ | |
1214 | case FcTypeVoid: | |
1215 | return FcTrue; | |
1216 | case FcTypeInteger: | |
1217 | @@ -294,6 +296,7 @@ static FcChar32 | |
1218 | FcValueHash (const FcValue *v) | |
1219 | { | |
1220 | switch (v->type) { | |
1221 | + case FcTypeUnknown: | |
1222 | case FcTypeVoid: | |
1223 | return 0; | |
1224 | case FcTypeInteger: | |
1225 | @@ -317,7 +320,7 @@ FcValueHash (const FcValue *v) | |
1226 | case FcTypeLangSet: | |
1227 | return FcLangSetHash (FcValueLangSet(v)); | |
1228 | } | |
1229 | - return FcFalse; | |
1230 | + return 0; | |
1231 | } | |
1232 | ||
1233 | static FcBool | |
1234 | diff --git a/src/fcstat.c b/src/fcstat.c | |
1235 | index 390f45c..ab56aca 100644 | |
1236 | --- a/src/fcstat.c | |
1237 | +++ b/src/fcstat.c | |
1238 | @@ -164,11 +164,21 @@ FcDirChecksumScandirFilter(const struct dirent *entry) | |
1239 | } | |
1240 | #endif | |
1241 | ||
1242 | +#ifdef HAVE_SCANDIR | |
1243 | static int | |
1244 | FcDirChecksumScandirSorter(const struct dirent **lhs, const struct dirent **rhs) | |
1245 | { | |
1246 | return strcmp((*lhs)->d_name, (*rhs)->d_name); | |
1247 | } | |
1248 | +#elif HAVE_SCANDIR_VOID_P | |
1249 | +static int | |
1250 | +FcDirChecksumScandirSorter(const void *a, const void *b) | |
1251 | +{ | |
1252 | + const struct dirent *lhs = a, *rhs = b; | |
1253 | + | |
1254 | + return strcmp(lhs->d_name, rhs->d_name); | |
1255 | +} | |
1256 | +#endif | |
1257 | ||
1258 | static int | |
1259 | FcDirChecksum (const FcChar8 *dir, time_t *checksum) | |
1260 | diff --git a/src/fcxml.c b/src/fcxml.c | |
1261 | index 470e44f..2cdf0ad 100644 | |
1262 | --- a/src/fcxml.c | |
1263 | +++ b/src/fcxml.c | |
1264 | @@ -62,12 +62,30 @@ FcExprDestroy (FcExpr *e); | |
1265 | void | |
1266 | FcTestDestroy (FcTest *test) | |
1267 | { | |
1268 | - if (test->next) | |
1269 | - FcTestDestroy (test->next); | |
1270 | FcExprDestroy (test->expr); | |
1271 | free (test); | |
1272 | } | |
1273 | ||
1274 | +void | |
1275 | +FcRuleDestroy (FcRule *rule) | |
1276 | +{ | |
1277 | + FcRule *n = rule->next; | |
1278 | + | |
1279 | + switch (rule->type) { | |
1280 | + case FcRuleTest: | |
1281 | + FcTestDestroy (rule->u.test); | |
1282 | + break; | |
1283 | + case FcRuleEdit: | |
1284 | + FcEditDestroy (rule->u.edit); | |
1285 | + break; | |
1286 | + default: | |
1287 | + break; | |
1288 | + } | |
1289 | + free (rule); | |
1290 | + if (n) | |
1291 | + FcRuleDestroy (n); | |
1292 | +} | |
1293 | + | |
1294 | static FcExpr * | |
1295 | FcExprCreateInteger (FcConfig *config, int i) | |
1296 | { | |
1297 | @@ -300,8 +318,6 @@ FcExprDestroy (FcExpr *e) | |
1298 | void | |
1299 | FcEditDestroy (FcEdit *e) | |
1300 | { | |
1301 | - if (e->next) | |
1302 | - FcEditDestroy (e->next); | |
1303 | if (e->expr) | |
1304 | FcExprDestroy (e->expr); | |
1305 | free (e); | |
1306 | @@ -705,7 +721,7 @@ FcTestCreate (FcConfigParse *parse, | |
1307 | FcMatchKind kind, | |
1308 | FcQual qual, | |
1309 | const FcChar8 *field, | |
1310 | - FcOp compare, | |
1311 | + unsigned int compare, | |
1312 | FcExpr *expr) | |
1313 | { | |
1314 | FcTest *test = (FcTest *) malloc (sizeof (FcTest)); | |
1315 | @@ -714,7 +730,6 @@ FcTestCreate (FcConfigParse *parse, | |
1316 | { | |
1317 | const FcObjectType *o; | |
1318 | ||
1319 | - test->next = 0; | |
1320 | test->kind = kind; | |
1321 | test->qual = qual; | |
1322 | test->object = FcObjectFromName ((const char *) field); | |
1323 | @@ -740,7 +755,6 @@ FcEditCreate (FcConfigParse *parse, | |
1324 | { | |
1325 | const FcObjectType *o; | |
1326 | ||
1327 | - e->next = 0; | |
1328 | e->object = object; | |
1329 | e->op = op; | |
1330 | e->expr = expr; | |
1331 | @@ -752,6 +766,34 @@ FcEditCreate (FcConfigParse *parse, | |
1332 | return e; | |
1333 | } | |
1334 | ||
1335 | +static FcRule * | |
1336 | +FcRuleCreate (FcRuleType type, | |
1337 | + void *p) | |
1338 | +{ | |
1339 | + FcRule *r = (FcRule *) malloc (sizeof (FcRule)); | |
1340 | + | |
1341 | + if (!r) | |
1342 | + return NULL; | |
1343 | + | |
1344 | + r->next = NULL; | |
1345 | + r->type = type; | |
1346 | + switch (type) | |
1347 | + { | |
1348 | + case FcRuleTest: | |
1349 | + r->u.test = (FcTest *) p; | |
1350 | + break; | |
1351 | + case FcRuleEdit: | |
1352 | + r->u.edit = (FcEdit *) p; | |
1353 | + break; | |
1354 | + default: | |
1355 | + free (r); | |
1356 | + r = NULL; | |
1357 | + break; | |
1358 | + } | |
1359 | + | |
1360 | + return r; | |
1361 | +} | |
1362 | + | |
1363 | static FcVStack * | |
1364 | FcVStackCreateAndPush (FcConfigParse *parse) | |
1365 | { | |
1366 | @@ -1657,9 +1699,9 @@ static void | |
1367 | FcParseAlias (FcConfigParse *parse) | |
1368 | { | |
1369 | FcExpr *family = 0, *accept = 0, *prefer = 0, *def = 0, *new = 0; | |
1370 | - FcEdit *edit = 0, *next; | |
1371 | + FcEdit *edit = 0; | |
1372 | FcVStack *vstack; | |
1373 | - FcTest *test = NULL; | |
1374 | + FcRule *rule = NULL, *r; | |
1375 | FcValueBinding binding; | |
1376 | ||
1377 | if (!FcConfigLexBinding (parse, FcConfigGetAttribute (parse, "binding"), &binding)) | |
1378 | @@ -1704,8 +1746,14 @@ FcParseAlias (FcConfigParse *parse) | |
1379 | vstack->tag = FcVStackNone; | |
1380 | break; | |
1381 | case FcVStackTest: | |
1382 | - vstack->u.test->next = test; | |
1383 | - test = vstack->u.test; | |
1384 | + if (rule) | |
1385 | + { | |
1386 | + r = FcRuleCreate (FcRuleTest, vstack->u.test); | |
1387 | + r->next = rule; | |
1388 | + rule = r; | |
1389 | + } | |
1390 | + else | |
1391 | + rule = FcRuleCreate (FcRuleTest, vstack->u.test); | |
1392 | vstack->tag = FcVStackNone; | |
1393 | break; | |
1394 | default: | |
1395 | @@ -1723,8 +1771,35 @@ FcParseAlias (FcConfigParse *parse) | |
1396 | FcExprDestroy (accept); | |
1397 | if (def) | |
1398 | FcExprDestroy (def); | |
1399 | + if (rule) | |
1400 | + FcRuleDestroy (rule); | |
1401 | return; | |
1402 | } | |
1403 | + if (!prefer && | |
1404 | + !accept && | |
1405 | + !def) | |
1406 | + { | |
1407 | + FcExprDestroy (family); | |
1408 | + return; | |
1409 | + } | |
1410 | + else | |
1411 | + { | |
1412 | + FcTest *t = FcTestCreate (parse, FcMatchPattern, | |
1413 | + FcQualAny, | |
1414 | + (FcChar8 *) FC_FAMILY, | |
1415 | + FC_OP (FcOpEqual, FcOpFlagIgnoreBlanks), | |
1416 | + family); | |
1417 | + if (rule) | |
1418 | + { | |
1419 | + for (r = rule; r->next; r = r->next); | |
1420 | + r->next = FcRuleCreate (FcRuleTest, t); | |
1421 | + r = r->next; | |
1422 | + } | |
1423 | + else | |
1424 | + { | |
1425 | + r = rule = FcRuleCreate (FcRuleTest, t); | |
1426 | + } | |
1427 | + } | |
1428 | if (prefer) | |
1429 | { | |
1430 | edit = FcEditCreate (parse, | |
1431 | @@ -1732,60 +1807,46 @@ FcParseAlias (FcConfigParse *parse) | |
1432 | FcOpPrepend, | |
1433 | prefer, | |
1434 | binding); | |
1435 | - if (edit) | |
1436 | - edit->next = 0; | |
1437 | - else | |
1438 | + if (!edit) | |
1439 | FcExprDestroy (prefer); | |
1440 | + else | |
1441 | + { | |
1442 | + r->next = FcRuleCreate (FcRuleEdit, edit); | |
1443 | + r = r->next; | |
1444 | + } | |
1445 | } | |
1446 | if (accept) | |
1447 | { | |
1448 | - next = edit; | |
1449 | edit = FcEditCreate (parse, | |
1450 | FC_FAMILY_OBJECT, | |
1451 | FcOpAppend, | |
1452 | accept, | |
1453 | binding); | |
1454 | - if (edit) | |
1455 | - edit->next = next; | |
1456 | - else | |
1457 | + if (!edit) | |
1458 | FcExprDestroy (accept); | |
1459 | + else | |
1460 | + { | |
1461 | + r->next = FcRuleCreate (FcRuleEdit, edit); | |
1462 | + r = r->next; | |
1463 | + } | |
1464 | } | |
1465 | if (def) | |
1466 | { | |
1467 | - next = edit; | |
1468 | edit = FcEditCreate (parse, | |
1469 | FC_FAMILY_OBJECT, | |
1470 | FcOpAppendLast, | |
1471 | def, | |
1472 | binding); | |
1473 | - if (edit) | |
1474 | - edit->next = next; | |
1475 | - else | |
1476 | + if (!edit) | |
1477 | FcExprDestroy (def); | |
1478 | - } | |
1479 | - if (edit) | |
1480 | - { | |
1481 | - FcTest *t = FcTestCreate (parse, FcMatchPattern, | |
1482 | - FcQualAny, | |
1483 | - (FcChar8 *) FC_FAMILY, | |
1484 | - FC_OP (FcOpEqual, FcOpFlagIgnoreBlanks), | |
1485 | - family); | |
1486 | - if (test) | |
1487 | + else | |
1488 | { | |
1489 | - FcTest *p = test; | |
1490 | - | |
1491 | - while (p->next) | |
1492 | - p = p->next; | |
1493 | - p->next = t; | |
1494 | + r->next = FcRuleCreate (FcRuleEdit, edit); | |
1495 | + r = r->next; | |
1496 | } | |
1497 | - else | |
1498 | - test = t; | |
1499 | - if (test) | |
1500 | - if (!FcConfigAddEdit (parse->config, test, edit, FcMatchPattern)) | |
1501 | - FcTestDestroy (test); | |
1502 | } | |
1503 | - else | |
1504 | - FcExprDestroy (family); | |
1505 | + if (!FcConfigAddRule (parse->config, rule, FcMatchPattern)) | |
1506 | + FcRuleDestroy (rule); | |
1507 | } | |
1508 | ||
1509 | static FcExpr * | |
1510 | @@ -2121,6 +2182,8 @@ FcParseInclude (FcConfigParse *parse) | |
1511 | FcBool ignore_missing = FcFalse; | |
1512 | FcBool deprecated = FcFalse; | |
1513 | FcChar8 *prefix = NULL, *p; | |
1514 | + static FcChar8 *userdir = NULL; | |
1515 | + static FcChar8 *userconf = NULL; | |
1516 | ||
1517 | s = FcStrBufDoneStatic (&parse->pstack->str); | |
1518 | if (!s) | |
1519 | @@ -2153,23 +2216,78 @@ FcParseInclude (FcConfigParse *parse) | |
1520 | memcpy (&prefix[plen + 1], s, dlen); | |
1521 | prefix[plen + 1 + dlen] = 0; | |
1522 | s = prefix; | |
1523 | + if (FcFileIsDir (s)) | |
1524 | + { | |
1525 | + userdir: | |
1526 | + if (!userdir) | |
1527 | + userdir = FcStrdup (s); | |
1528 | + } | |
1529 | + else if (FcFileIsFile (s)) | |
1530 | + { | |
1531 | + userconf: | |
1532 | + if (!userconf) | |
1533 | + userconf = FcStrdup (s); | |
1534 | + } | |
1535 | + else | |
1536 | + { | |
1537 | + /* No config dir nor file on the XDG directory spec compliant place | |
1538 | + * so need to guess what it is supposed to be. | |
1539 | + */ | |
1540 | + FcChar8 *parent = FcStrDirname (s); | |
1541 | + | |
1542 | + if (!FcFileIsDir (parent)) | |
1543 | + FcMakeDirectory (parent); | |
1544 | + FcStrFree (parent); | |
1545 | + if (FcStrStr (s, (const FcChar8 *)"conf.d") != NULL) | |
1546 | + goto userdir; | |
1547 | + else | |
1548 | + goto userconf; | |
1549 | + } | |
1550 | } | |
1551 | if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing)) | |
1552 | parse->error = FcTrue; | |
1553 | +#ifndef _WIN32 | |
1554 | else | |
1555 | { | |
1556 | FcChar8 *filename; | |
1557 | + static FcBool warn_conf = FcFalse, warn_confd = FcFalse; | |
1558 | ||
1559 | filename = FcConfigFilename(s); | |
1560 | if (deprecated == FcTrue && | |
1561 | filename != NULL && | |
1562 | !FcFileIsLink (filename)) | |
1563 | { | |
1564 | - FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated.", s); | |
1565 | + if (FcFileIsDir (filename)) | |
1566 | + { | |
1567 | + if (FcFileIsDir (userdir) || | |
1568 | + rename ((const char *)filename, (const char *)userdir) != 0 || | |
1569 | + symlink ((const char *)userdir, (const char *)filename) != 0) | |
1570 | + { | |
1571 | + if (!warn_confd) | |
1572 | + { | |
1573 | + FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userdir); | |
1574 | + warn_confd = FcTrue; | |
1575 | + } | |
1576 | + } | |
1577 | + } | |
1578 | + else | |
1579 | + { | |
1580 | + if (FcFileIsFile (userconf) || | |
1581 | + rename ((const char *)filename, (const char *)userconf) != 0 || | |
1582 | + symlink ((const char *)userconf, (const char *)filename) != 0) | |
1583 | + { | |
1584 | + if (!warn_conf) | |
1585 | + { | |
1586 | + FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userconf); | |
1587 | + warn_conf = FcTrue; | |
1588 | + } | |
1589 | + } | |
1590 | + } | |
1591 | } | |
1592 | if(filename) | |
1593 | FcStrFree(filename); | |
1594 | } | |
1595 | +#endif | |
1596 | FcStrBufDestroy (&parse->pstack->str); | |
1597 | ||
1598 | bail: | |
1599 | @@ -2386,22 +2504,14 @@ FcParseEdit (FcConfigParse *parse) | |
1600 | FcEditDestroy (edit); | |
1601 | } | |
1602 | ||
1603 | -typedef struct FcSubstStack { | |
1604 | - FcTest *test; | |
1605 | - FcEdit *edit; | |
1606 | -} FcSubstStack; | |
1607 | - | |
1608 | static void | |
1609 | FcParseMatch (FcConfigParse *parse) | |
1610 | { | |
1611 | const FcChar8 *kind_name; | |
1612 | FcMatchKind kind; | |
1613 | - FcTest *test = 0; | |
1614 | FcEdit *edit = 0; | |
1615 | FcVStack *vstack; | |
1616 | - FcBool tested = FcFalse; | |
1617 | - FcSubstStack *sstack = NULL; | |
1618 | - int len, pos = 0; | |
1619 | + FcRule *rule = NULL, *r; | |
1620 | ||
1621 | kind_name = FcConfigGetAttribute (parse, "target"); | |
1622 | if (!kind_name) | |
1623 | @@ -2420,48 +2530,29 @@ FcParseMatch (FcConfigParse *parse) | |
1624 | return; | |
1625 | } | |
1626 | } | |
1627 | - len = FcVStackElements(parse); | |
1628 | - if (len > 0) | |
1629 | - { | |
1630 | - sstack = malloc (sizeof (FcSubstStack) * (len + 1)); | |
1631 | - if (!sstack) | |
1632 | - { | |
1633 | - FcConfigMessage (parse, FcSevereError, "out of memory"); | |
1634 | - return; | |
1635 | - } | |
1636 | - } | |
1637 | while ((vstack = FcVStackPeek (parse))) | |
1638 | { | |
1639 | switch ((int) vstack->tag) { | |
1640 | case FcVStackTest: | |
1641 | - vstack->u.test->next = test; | |
1642 | - test = vstack->u.test; | |
1643 | + r = FcRuleCreate (FcRuleTest, vstack->u.test); | |
1644 | + if (rule) | |
1645 | + r->next = rule; | |
1646 | + rule = r; | |
1647 | vstack->tag = FcVStackNone; | |
1648 | - tested = FcTrue; | |
1649 | break; | |
1650 | case FcVStackEdit: | |
1651 | - /* due to the reverse traversal, <edit> node appears faster than | |
1652 | - * <test> node if any. so we have to deal with it here rather than | |
1653 | - * the above in FcVStackTest, and put recipes in reverse order. | |
1654 | - */ | |
1655 | - if (tested) | |
1656 | - { | |
1657 | - sstack[pos].test = test; | |
1658 | - sstack[pos].edit = edit; | |
1659 | - pos++; | |
1660 | - test = NULL; | |
1661 | - edit = NULL; | |
1662 | - tested = FcFalse; | |
1663 | - } | |
1664 | - vstack->u.edit->next = edit; | |
1665 | - edit = vstack->u.edit; | |
1666 | - vstack->tag = FcVStackNone; | |
1667 | - if (kind == FcMatchScan && edit->object > FC_MAX_BASE_OBJECT) | |
1668 | + if (kind == FcMatchScan && vstack->u.edit->object > FC_MAX_BASE_OBJECT) | |
1669 | { | |
1670 | FcConfigMessage (parse, FcSevereError, | |
1671 | "<match target=\"scan\"> cannot edit user-defined object \"%s\"", | |
1672 | FcObjectName(edit->object)); | |
1673 | + break; | |
1674 | } | |
1675 | + r = FcRuleCreate (FcRuleEdit, vstack->u.edit); | |
1676 | + if (rule) | |
1677 | + r->next = rule; | |
1678 | + rule = r; | |
1679 | + vstack->tag = FcVStackNone; | |
1680 | break; | |
1681 | default: | |
1682 | FcConfigMessage (parse, FcSevereWarning, "invalid match element"); | |
1683 | @@ -2469,22 +2560,8 @@ FcParseMatch (FcConfigParse *parse) | |
1684 | } | |
1685 | FcVStackPopAndDestroy (parse); | |
1686 | } | |
1687 | - if (!FcConfigAddEdit (parse->config, test, edit, kind)) | |
1688 | + if (!FcConfigAddRule (parse->config, rule, kind)) | |
1689 | FcConfigMessage (parse, FcSevereError, "out of memory"); | |
1690 | - if (sstack) | |
1691 | - { | |
1692 | - int i; | |
1693 | - | |
1694 | - for (i = 0; i < pos; i++) | |
1695 | - { | |
1696 | - if (!FcConfigAddEdit (parse->config, sstack[pos - i - 1].test, sstack[pos - i - 1].edit, kind)) | |
1697 | - { | |
1698 | - FcConfigMessage (parse, FcSevereError, "out of memory"); | |
1699 | - return; | |
1700 | - } | |
1701 | - } | |
1702 | - free (sstack); | |
1703 | - } | |
1704 | } | |
1705 | ||
1706 | static void |