aboutsummaryrefslogtreecommitdiff
path: root/fontconfig/src
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig/src')
-rw-r--r--fontconfig/src/fccache.c6
-rw-r--r--fontconfig/src/fcdbg.c88
-rw-r--r--fontconfig/src/fcdefault.c1
-rw-r--r--fontconfig/src/fcfreetype.c80
-rw-r--r--fontconfig/src/fcinit.c28
-rw-r--r--fontconfig/src/fcint.h41
-rw-r--r--fontconfig/src/fcmatch.c44
-rw-r--r--fontconfig/src/fcname.c20
-rw-r--r--fontconfig/src/fcobjs.c31
-rw-r--r--fontconfig/src/fcobjs.h1
-rw-r--r--fontconfig/src/fcpat.c6
-rw-r--r--fontconfig/src/fcrange.c109
-rw-r--r--fontconfig/src/fcxml.c63
13 files changed, 333 insertions, 185 deletions
diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c
index 25538bd70..fc3ed410a 100644
--- a/fontconfig/src/fccache.c
+++ b/fontconfig/src/fccache.c
@@ -655,7 +655,7 @@ FcDirCacheMapFd (FcConfig *config, int fd, struct stat *fd_stat, struct stat *di
allocated = FcTrue;
}
if (cache->magic != FC_CACHE_MAGIC_MMAP ||
- cache->version < FC_CACHE_CONTENT_VERSION ||
+ cache->version < FC_CACHE_VERSION_NUMBER ||
cache->size != (intptr_t) fd_stat->st_size ||
!FcCacheTimeValid (config, cache, dir_stat) ||
!FcCacheDirsValid (config, cache) ||
@@ -751,7 +751,7 @@ FcDirCacheValidateHelper (FcConfig *config, int fd, struct stat *fd_stat, struct
ret = FcFalse;
else if (c.magic != FC_CACHE_MAGIC_MMAP)
ret = FcFalse;
- else if (c.version < FC_CACHE_CONTENT_VERSION)
+ else if (c.version < FC_CACHE_VERSION_NUMBER)
ret = FcFalse;
else if (fd_stat->st_size != c.size)
ret = FcFalse;
@@ -828,7 +828,7 @@ FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcSt
serialize->linear = cache;
cache->magic = FC_CACHE_MAGIC_ALLOC;
- cache->version = FC_CACHE_CONTENT_VERSION;
+ cache->version = FC_CACHE_VERSION_NUMBER;
cache->size = serialize->size;
cache->checksum = (int) dir_stat->st_mtime;
diff --git a/fontconfig/src/fcdbg.c b/fontconfig/src/fcdbg.c
index ef038f017..c2853fff3 100644
--- a/fontconfig/src/fcdbg.c
+++ b/fontconfig/src/fcdbg.c
@@ -29,8 +29,6 @@
static void
_FcValuePrintFile (FILE *f, const FcValue v)
{
- FcRange r;
-
switch (v.type) {
case FcTypeUnknown:
fprintf (f, "<unknown>");
@@ -64,8 +62,7 @@ _FcValuePrintFile (FILE *f, const FcValue v)
fprintf (f, "face");
break;
case FcTypeRange:
- r = FcRangeCanonicalize (v.u.r);
- fprintf (f, "(%g, %g)", r.u.d.begin, r.u.d.end);
+ fprintf (f, "[%g %g)", v.u.r->begin, v.u.r->end);
break;
}
}
@@ -214,6 +211,84 @@ FcPatternPrint (const FcPattern *p)
}
void
+FcPatternPrint2 (FcPattern *pp1,
+ FcPattern *pp2,
+ const FcObjectSet *os)
+{
+ int i, j, k, pos;
+ FcPatternElt *e1, *e2;
+ FcPattern *p1, *p2;
+
+ if (os)
+ {
+ p1 = FcPatternFilter (pp1, os);
+ p2 = FcPatternFilter (pp2, os);
+ }
+ else
+ {
+ p1 = pp1;
+ p2 = pp2;
+ }
+ printf ("Pattern has %d elts (size %d), %d elts (size %d)\n",
+ p1->num, p1->size, p2->num, p2->size);
+ for (i = 0, j = 0; i < p1->num; i++)
+ {
+ e1 = &FcPatternElts(p1)[i];
+ e2 = &FcPatternElts(p2)[j];
+ if (!e2 || e1->object != e2->object)
+ {
+ pos = FcPatternPosition (p2, FcObjectName (e1->object));
+ if (pos >= 0)
+ {
+ for (k = j; k < pos; k++)
+ {
+ e2 = &FcPatternElts(p2)[k];
+ printf ("\t%s: (None) -> ", FcObjectName (e2->object));
+ FcValueListPrint (FcPatternEltValues (e2));
+ printf ("\n");
+ }
+ j = pos;
+ goto cont;
+ }
+ else
+ {
+ printf ("\t%s:", FcObjectName (e1->object));
+ FcValueListPrint (FcPatternEltValues (e1));
+ printf (" -> (None)\n");
+ }
+ }
+ else
+ {
+ cont:
+ printf ("\t%s:", FcObjectName (e1->object));
+ FcValueListPrint (FcPatternEltValues (e1));
+ printf (" -> ");
+ e2 = &FcPatternElts(p2)[j];
+ FcValueListPrint (FcPatternEltValues (e2));
+ printf ("\n");
+ j++;
+ }
+ }
+ if (j < p2->num)
+ {
+ for (k = j; k < p2->num; k++)
+ {
+ e2 = &FcPatternElts(p2)[k];
+ if (FcObjectName (e2->object))
+ {
+ printf ("\t%s: (None) -> ", FcObjectName (e2->object));
+ FcValueListPrint (FcPatternEltValues (e2));
+ printf ("\n");
+ }
+ }
+ }
+ if (p1 != pp1)
+ FcPatternDestroy (p1);
+ if (p2 != pp2)
+ FcPatternDestroy (p2);
+}
+
+void
FcOpPrint (FcOp op_)
{
FcOp op = FC_OP_GET_OP (op_);
@@ -267,8 +342,6 @@ FcOpPrint (FcOp op_)
void
FcExprPrint (const FcExpr *expr)
{
- FcRange r;
-
if (!expr) printf ("none");
else switch (FC_OP_GET_OP (expr->op)) {
case FcOpInteger: printf ("%d", expr->u.ival); break;
@@ -286,8 +359,7 @@ FcExprPrint (const FcExpr *expr)
printf ("]");
break;
case FcOpRange:
- r = FcRangeCanonicalize (expr->u.rval);
- printf ("(%g, %g)", r.u.d.begin, r.u.d.end);
+ printf ("(%g, %g)", expr->u.rval->begin, expr->u.rval->end);
break;
case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
case FcOpCharSet: printf ("charset\n"); break;
diff --git a/fontconfig/src/fcdefault.c b/fontconfig/src/fcdefault.c
index 7c16f4841..4643e46dc 100644
--- a/fontconfig/src/fcdefault.c
+++ b/fontconfig/src/fcdefault.c
@@ -38,6 +38,7 @@ static const struct {
{ FC_GLOBAL_ADVANCE_OBJECT, FcTrue }, /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */
{ FC_EMBEDDED_BITMAP_OBJECT, FcTrue }, /* !FC_LOAD_NO_BITMAP */
{ FC_DECORATIVE_OBJECT, FcFalse },
+ { FC_SYMBOL_OBJECT, FcFalse },
};
#define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0])
diff --git a/fontconfig/src/fcfreetype.c b/fontconfig/src/fcfreetype.c
index afbd9ac1e..809ff2992 100644
--- a/fontconfig/src/fcfreetype.c
+++ b/fontconfig/src/fcfreetype.c
@@ -1199,7 +1199,8 @@ FcFreeTypeQueryFace (const FT_Face face,
const char *tmp;
FcRange *r = NULL;
- double lower_size = 0.0L, upper_size = DBL_MAX;
+
+ FcBool symbol = FcFalse;
FcInitDebug (); /* We might be called with no initizalization whatsoever. */
@@ -1615,13 +1616,12 @@ FcFreeTypeQueryFace (const FT_Face face,
#if defined (HAVE_TT_OS2_USUPPEROPTICALPOINTSIZE) && defined (HAVE_TT_OS2_USLOWEROPTICALPOINTSIZE)
if (os2 && os2->version >= 0x0005 && os2->version != 0xffff)
{
+ double lower_size, upper_size;
+
/* usLowerPointSize and usUpperPointSize is actually twips */
lower_size = os2->usLowerOpticalPointSize / 20.0L;
upper_size = os2->usUpperOpticalPointSize / 20.0L;
- }
-#endif
- if (os2)
- {
+
r = FcRangeCreateDouble (lower_size, upper_size);
if (!FcPatternAddRange (pat, FC_SIZE, r))
{
@@ -1630,20 +1630,7 @@ FcFreeTypeQueryFace (const FT_Face face,
}
FcRangeDestroy (r);
}
- else
- {
- for (i = 0; i < face->num_fixed_sizes; i++)
- {
- double d = FcGetPixelSize (face, i);
- r = FcRangeCreateDouble (d, d);
- if (!FcPatternAddRange (pat, FC_SIZE, r))
- {
- FcRangeDestroy (r);
- goto bail1;
- }
- FcRangeDestroy (r);
- }
- }
+#endif
/*
* Type 1: Check for FontInfo dictionary information
@@ -1803,6 +1790,11 @@ FcFreeTypeQueryFace (const FT_Face face,
if (!cs)
goto bail1;
+ /* The FcFreeTypeCharSetAndSpacing() chose the encoding; test it for symbol. */
+ symbol = face->charmap && face->charmap->encoding == FT_ENCODING_MS_SYMBOL;
+ if (!FcPatternAddBool (pat, FC_SYMBOL, symbol))
+ goto bail1;
+
#if HAVE_FT_GET_BDF_PROPERTY
/* For PCF fonts, override the computed spacing with the one from
the property */
@@ -1835,9 +1827,18 @@ FcFreeTypeQueryFace (const FT_Face face,
if (!FcPatternAddCharSet (pat, FC_CHARSET, cs))
goto bail2;
- ls = FcFreeTypeLangSet (cs, exclusiveLang);
- if (!ls)
- goto bail2;
+ if (!symbol)
+ {
+ ls = FcFreeTypeLangSet (cs, exclusiveLang);
+ if (!ls)
+ goto bail2;
+ }
+ else
+ {
+ /* Symbol fonts don't cover any language, even though they
+ * claim to support Latin1 range. */
+ ls = FcLangSetCreate ();
+ }
if (!FcPatternAddLangSet (pat, FC_LANG, ls))
{
@@ -2093,6 +2094,22 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
glyphindex = FT_Get_Char_Index (face, (FT_ULong) ucs4);
if (glyphindex)
return glyphindex;
+ if (ucs4 < 0x100 && face->charmap &&
+ face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
+ {
+ /* For symbol-encoded OpenType fonts, we duplicate the
+ * U+F000..F0FF range at U+0000..U+00FF. That's what
+ * Windows seems to do, and that's hinted about at:
+ * http://www.microsoft.com/typography/otspec/recom.htm
+ * under "Non-Standard (Symbol) Fonts".
+ *
+ * See thread with subject "Webdings and other MS symbol
+ * fonts don't display" on mailing list from May 2015.
+ */
+ glyphindex = FT_Get_Char_Index (face, (FT_ULong) ucs4 + 0xF000);
+ if (glyphindex)
+ return glyphindex;
+ }
}
#if HAVE_FT_HAS_PS_GLYPH_NAMES
/*
@@ -2253,6 +2270,23 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing
}
ucs4 = FT_Get_Next_Char (face, ucs4, &glyph);
}
+ if (fcFontEncodings[o] == FT_ENCODING_MS_SYMBOL)
+ {
+ /* For symbol-encoded OpenType fonts, we duplicate the
+ * U+F000..F0FF range at U+0000..U+00FF. That's what
+ * Windows seems to do, and that's hinted about at:
+ * http://www.microsoft.com/typography/otspec/recom.htm
+ * under "Non-Standard (Symbol) Fonts".
+ *
+ * See thread with subject "Webdings and other MS symbol
+ * fonts don't display" on mailing list from May 2015.
+ */
+ for (ucs4 = 0xF000; ucs4 < 0xF100; ucs4++)
+ {
+ if (FcCharSetHasChar (fcs, ucs4))
+ FcCharSetAddChar (fcs, ucs4 - 0xF000);
+ }
+ }
#ifdef CHECK
for (ucs4 = 0; ucs4 < 0x10000; ucs4++)
{
@@ -2267,6 +2301,8 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing
}
#endif
}
+
+ break;
}
#if HAVE_FT_HAS_PS_GLYPH_NAMES
/*
diff --git a/fontconfig/src/fcinit.c b/fontconfig/src/fcinit.c
index 6134ed40d..5e7c2f156 100644
--- a/fontconfig/src/fcinit.c
+++ b/fontconfig/src/fcinit.c
@@ -91,12 +91,23 @@ FcInitLoadOwnConfig (FcConfig *config)
{
FcChar8 *prefix, *p;
size_t plen;
+ FcBool have_own = FcFalse;
+ char *env_file, *env_path;
- fprintf (stderr,
- "Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
- fprintf (stderr,
- "Fontconfig warning: adding <cachedir>%s</cachedir>\n",
- FC_CACHEDIR);
+ env_file = getenv ("FONTCONFIG_FILE");
+ env_path = getenv ("FONTCONFIG_PATH");
+ if ((env_file != NULL && env_file[0] != 0) ||
+ (env_path != NULL && env_path[0] != 0))
+ have_own = FcTrue;
+
+ if (!have_own)
+ {
+ fprintf (stderr,
+ "Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
+ fprintf (stderr,
+ "Fontconfig warning: adding <cachedir>%s</cachedir>\n",
+ FC_CACHEDIR);
+ }
prefix = FcConfigXdgCacheHome ();
if (!prefix)
goto bail;
@@ -107,8 +118,9 @@ FcInitLoadOwnConfig (FcConfig *config)
prefix = p;
memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11);
prefix[plen + 11] = 0;
- fprintf (stderr,
- "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n");
+ if (!have_own)
+ fprintf (stderr,
+ "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n");
if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) ||
!FcConfigAddCacheDir (config, (FcChar8 *) prefix))
@@ -180,6 +192,8 @@ FcFini (void)
FcConfigFini ();
FcCacheFini ();
FcDefaultFini ();
+ FcObjectFini ();
+ FcConfigPathFini ();
}
/*
diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h
index 80205c950..15e22fdbc 100644
--- a/fontconfig/src/fcint.h
+++ b/fontconfig/src/fcint.h
@@ -87,6 +87,7 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA;
#define FC_DBG_SCANV 256
#define FC_DBG_CONFIG 1024
#define FC_DBG_LANGSET 2048
+#define FC_DBG_MATCH2 4096
#define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] FC_UNUSED
#define _FC_ASSERT_STATIC0(_line, _cond) _FC_ASSERT_STATIC1 (_line, (_cond))
@@ -96,11 +97,6 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA;
#define FC_MAX(a,b) ((a) > (b) ? (a) : (b))
#define FC_ABS(a) ((a) < 0 ? -(a) : (a))
-#define FcDoubleIsZero(a) (fabs ((a)) <= DBL_EPSILON)
-#define FcDoubleCmpEQ(a,b) (fabs ((a) - (b)) <= DBL_EPSILON)
-#define FcDoubleCmpGE(a,b) (FcDoubleCmpEQ (a, b) || (a) > (b))
-#define FcDoubleCmpLE(a,b) (FcDoubleCmpEQ (a, b) || (a) < (b))
-
/* slim_internal.h */
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
#define FcPrivate __attribute__((__visibility__("hidden")))
@@ -252,21 +248,9 @@ typedef struct _FcExprName {
FcMatchKind kind;
} FcExprName;
-typedef struct _FcRangeInt {
- FcChar32 begin;
- FcChar32 end;
-} FcRangeInt;
-typedef struct _FcRangeDouble {
+struct _FcRange {
double begin;
double end;
-} FcRangeDouble;
-struct _FcRange {
- FcBool is_double;
- FcBool is_inclusive;
- union {
- FcRangeInt i;
- FcRangeDouble d;
- } u;
};
@@ -378,7 +362,7 @@ typedef struct _FcStrBuf {
struct _FcCache {
unsigned int magic; /* FC_CACHE_MAGIC_MMAP or FC_CACHE_ALLOC */
- int version; /* FC_CACHE_CONTENT_VERSION */
+ int version; /* FC_CACHE_VERSION_NUMBER */
intptr_t size; /* size of file */
intptr_t dir; /* offset to dir name */
intptr_t dirs; /* offset to subdirs */
@@ -470,7 +454,6 @@ typedef struct _FcCaseFold {
#define FC_CACHE_MAGIC_MMAP 0xFC02FC04
#define FC_CACHE_MAGIC_ALLOC 0xFC02FC05
-#define FC_CACHE_CONTENT_VERSION 5
struct _FcAtomic {
FcChar8 *file; /* original file name */
@@ -811,6 +794,9 @@ FcSubstPrint (const FcSubst *subst);
FcPrivate void
FcCharSetPrint (const FcCharSet *c);
+FcPrivate void
+FcPatternPrint2 (FcPattern *p1, FcPattern *p2, const FcObjectSet *os);
+
extern FcPrivate int FcDebugVal;
#define FcDebug() (FcDebugVal)
@@ -881,6 +867,9 @@ FcInitLoadOwnConfigAndFonts (FcConfig *config);
/* fcxml.c */
FcPrivate void
+FcConfigPathFini (void);
+
+FcPrivate void
FcTestDestroy (FcTest *test);
FcPrivate void
@@ -1054,6 +1043,9 @@ FcPatternObjectGetRange (const FcPattern *p, FcObject object, int id, FcRange **
FcPrivate FcBool
FcPatternAppend (FcPattern *p, FcPattern *s);
+FcPrivate int
+FcPatternPosition (const FcPattern *p, const char *object);
+
FcPrivate FcChar32
FcStringHash (const FcChar8 *s);
@@ -1080,16 +1072,10 @@ FcMatrixFree (FcMatrix *mat);
/* fcrange.c */
-FcPrivate FcRange
-FcRangeCanonicalize (const FcRange *range);
-
FcPrivate FcRange *
FcRangePromote (double v, FcValuePromotionBuffer *vbuf);
FcPrivate FcBool
-FcRangeIsZero (const FcRange *r);
-
-FcPrivate FcBool
FcRangeIsInRange (const FcRange *a, const FcRange *b);
FcPrivate FcBool
@@ -1192,6 +1178,9 @@ FcStrSerialize (FcSerialize *serialize, const FcChar8 *str);
/* fcobjs.c */
+FcPrivate void
+FcObjectFini (void);
+
FcPrivate FcObject
FcObjectLookupIdByName (const char *str);
diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c
index 46d08bcc7..40efbd3f6 100644
--- a/fontconfig/src/fcmatch.c
+++ b/fontconfig/src/fcmatch.c
@@ -220,7 +220,7 @@ FcCompareSizeRange (FcValue *v1, FcValue *v2)
if (FcRangeIsInRange (r1, r2))
ret = 0.0;
else
- ret = FC_MIN (fabs (r1->u.d.end - r2->u.d.begin), fabs (r1->u.d.begin - r2->u.d.end));
+ ret = FC_MIN (fabs (r1->end - r2->begin), fabs (r1->begin - r2->end));
bail:
if (r1)
@@ -292,6 +292,7 @@ typedef enum _FcMatcherPriority {
PRI1(LANG),
PRI_FAMILY_WEAK,
PRI_POSTSCRIPT_NAME_WEAK,
+ PRI1(SYMBOL),
PRI1(SPACING),
PRI1(SIZE),
PRI1(PIXEL_SIZE),
@@ -688,6 +689,47 @@ FcFontSetMatchInternal (FcFontSet **sets,
printf ("\n");
FcPatternPrint (best);
}
+ if (FcDebug () & FC_DBG_MATCH2)
+ {
+ char *env = getenv ("FC_DBG_MATCH_FILTER");
+ FcObjectSet *os = NULL;
+
+ if (env)
+ {
+ char *ss, *s;
+ char *p;
+ FcBool f = FcTrue;
+
+ ss = s = strdup (env);
+ os = FcObjectSetCreate ();
+ while (f)
+ {
+ size_t len;
+ char *x;
+
+ if (!(p = strchr (s, ',')))
+ {
+ f = FcFalse;
+ len = strlen (s) + 1;
+ }
+ else
+ {
+ len = (p - s) + 1;
+ }
+ x = malloc (sizeof (char) * len);
+ strncpy (x, s, len - 1);
+ x[len - 1] = 0;
+ if (FcObjectFromName (x) > 0)
+ FcObjectSetAdd (os, x);
+ s = p + 1;
+ free (x);
+ }
+ free (ss);
+ }
+ FcPatternPrint2 (p, best, os);
+ if (os)
+ FcObjectSetDestroy (os);
+ }
/* assuming that 'result' is initialized with FcResultNoMatch
* outside this function */
if (best)
diff --git a/fontconfig/src/fcname.c b/fontconfig/src/fcname.c
index 1d8fe757c..8be36c70c 100644
--- a/fontconfig/src/fcname.c
+++ b/fontconfig/src/fcname.c
@@ -88,7 +88,9 @@ FcObjectValidType (FcObject object, FcType type)
return FcTrue;
break;
case FcTypeRange:
- if (type == FcTypeRange || type == FcTypeDouble)
+ if (type == FcTypeRange ||
+ type == FcTypeDouble ||
+ type == FcTypeInteger)
return FcTrue;
break;
default:
@@ -316,7 +318,7 @@ FcNameConvert (FcType type, FcChar8 *string)
v.type = FcTypeVoid;
break;
case FcTypeRange:
- if (sscanf ((char *) string, "(%lg %lg)", &b, &e) != 2)
+ if (sscanf ((char *) string, "[%lg %lg)", &b, &e) != 2)
{
v.u.d = strtod ((char *) string, &p);
if (p != NULL && p[0] != 0)
@@ -498,7 +500,6 @@ FcNameUnparseValue (FcStrBuf *buf,
{
FcChar8 temp[1024];
FcValue v = FcValueCanonicalize(v0);
- FcRange r;
switch (v.type) {
case FcTypeUnknown:
@@ -525,17 +526,8 @@ FcNameUnparseValue (FcStrBuf *buf,
case FcTypeFTFace:
return FcTrue;
case FcTypeRange:
- r = FcRangeCanonicalize (v.u.r);
- if (!FcDoubleIsZero (r.u.d.begin) || !FcDoubleIsZero (r.u.d.end))
- {
- if (FcDoubleCmpEQ (r.u.d.begin, r.u.d.end))
- sprintf ((char *) temp, "%g", r.u.d.begin);
- else
- sprintf ((char *) temp, "(%g %g)", r.u.d.begin, r.u.d.end);
- return FcNameUnparseString (buf, temp, 0);
- }
- else
- return FcTrue;
+ sprintf ((char *) temp, "[%g %g)", v.u.r->begin, v.u.r->end);
+ return FcNameUnparseString (buf, temp, 0);
}
return FcFalse;
}
diff --git a/fontconfig/src/fcobjs.c b/fontconfig/src/fcobjs.c
index bad9824d4..16ff31c47 100644
--- a/fontconfig/src/fcobjs.c
+++ b/fontconfig/src/fcobjs.c
@@ -44,6 +44,28 @@ struct FcObjectOtherTypeInfo {
FcObject id;
} *other_types;
+void
+FcObjectFini (void)
+{
+ struct FcObjectOtherTypeInfo *ots, *ot;
+
+retry:
+ ots = fc_atomic_ptr_get (&other_types);
+ if (!ots)
+ return;
+ if (!fc_atomic_ptr_cmpexch (&other_types, ots, NULL))
+ goto retry;
+
+ while (ots)
+ {
+ ot = ots->next;
+ if (ots->object.object)
+ free (ots->object.object);
+ free (ots);
+ ots = ot;
+ }
+}
+
static FcObjectType *
_FcObjectLookupOtherTypeByName (const char *str, FcObject *id)
{
@@ -62,12 +84,19 @@ retry:
if (!ot)
return NULL;
- ot->object.object = (const char *) FcStrdup (str);
+ ot->object.object = (char *) FcStrdup (str);
ot->object.type = FcTypeUnknown;
ot->id = fc_atomic_int_add (next_id, +1);
+ if (ot->id < (FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX))
+ {
+ fprintf (stderr, "Fontconfig error: No object ID to assign\n");
+ abort ();
+ }
ot->next = ots;
if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) {
+ if (ot->object.object)
+ free (ot->object.object);
free (ot);
goto retry;
}
diff --git a/fontconfig/src/fcobjs.h b/fontconfig/src/fcobjs.h
index 573fa610d..1fc4f656b 100644
--- a/fontconfig/src/fcobjs.h
+++ b/fontconfig/src/fcobjs.h
@@ -69,4 +69,5 @@ FC_OBJECT (PRGNAME, FcTypeString, NULL)
FC_OBJECT (HASH, FcTypeString, NULL) /* deprecated */
FC_OBJECT (POSTSCRIPT_NAME, FcTypeString, FcComparePostScript)
FC_OBJECT (COLOR, FcTypeBool, FcCompareBool)
+FC_OBJECT (SYMBOL, FcTypeBool, FcCompareBool)
/* ^-------------- Add new objects here. */
diff --git a/fontconfig/src/fcpat.c b/fontconfig/src/fcpat.c
index 7e7d54a4e..3ef1ed212 100644
--- a/fontconfig/src/fcpat.c
+++ b/fontconfig/src/fcpat.c
@@ -425,6 +425,12 @@ FcPatternObjectPosition (const FcPattern *p, FcObject object)
return -(mid + 1);
}
+int
+FcPatternPosition (const FcPattern *p, const char *object)
+{
+ return FcPatternObjectPosition (p, FcObjectFromName (object));
+}
+
FcPatternElt *
FcPatternObjectFindElt (const FcPattern *p, FcObject object)
{
diff --git a/fontconfig/src/fcrange.c b/fontconfig/src/fcrange.c
index 9b1b67b82..f70226c55 100644
--- a/fontconfig/src/fcrange.c
+++ b/fontconfig/src/fcrange.c
@@ -32,10 +32,8 @@ FcRangeCreateDouble (double begin, double end)
if (ret)
{
- ret->is_double = FcTrue;
- ret->is_inclusive = FcDoubleCmpEQ (begin, end);
- ret->u.d.begin = begin;
- ret->u.d.end = end;
+ ret->begin = begin;
+ ret->end = end;
}
return ret;
@@ -48,10 +46,8 @@ FcRangeCreateInteger (FcChar32 begin, FcChar32 end)
if (ret)
{
- ret->is_double = FcFalse;
- ret->is_inclusive = (begin == end);
- ret->u.i.begin = begin;
- ret->u.i.end = end;
+ ret->begin = begin;
+ ret->end = end;
}
return ret;
@@ -66,14 +62,7 @@ FcRangeDestroy (FcRange *range)
FcRange *
FcRangeCopy (const FcRange *range)
{
- FcRange *ret;
-
- if (range->is_double)
- ret = FcRangeCreateDouble (range->u.d.begin, range->u.d.end);
- else
- ret = FcRangeCreateInteger (range->u.i.begin, range->u.i.end);
-
- return ret;
+ return FcRangeCreateDouble (range->begin, range->end);
}
FcBool
@@ -81,41 +70,14 @@ FcRangeGetDouble(const FcRange *range, double *begin, double *end)
{
if (!range)
return FcFalse;
- if (range->is_double)
- {
- if (begin)
- *begin = range->u.d.begin;
- if (end)
- *end = range->u.d.end;
- }
- else
- {
- if (begin)
- *begin = (double)range->u.i.begin;
- if (end)
- *end = (double)range->u.i.end;
- }
+ if (begin)
+ *begin = range->begin;
+ if (end)
+ *end = range->end;
return FcTrue;
}
-FcRange
-FcRangeCanonicalize (const FcRange *range)
-{
- FcRange new;
-
- if (range->is_double)
- new = *range;
- else
- {
- new.is_double = FcTrue;
- new.is_inclusive = range->is_inclusive;
- new.u.d.begin = (double)range->u.i.begin;
- new.u.d.end = (double)range->u.i.end;
- }
- return new;
-}
-
FcRange *
FcRangePromote (double v, FcValuePromotionBuffer *vbuf)
{
@@ -125,50 +87,24 @@ FcRangePromote (double v, FcValuePromotionBuffer *vbuf)
FcRangePromotionBuffer *buf = (FcRangePromotionBuffer *) vbuf;
FC_ASSERT_STATIC (sizeof (FcRangePromotionBuffer) <= sizeof (FcValuePromotionBuffer));
- buf->r.is_double = FcTrue;
- buf->r.is_inclusive = FcTrue;
- buf->r.u.d.begin = v;
- buf->r.u.d.end = v;
+ buf->r.begin = v;
+ buf->r.end = v;
return &buf->r;
}
FcBool
-FcRangeIsZero (const FcRange *r)
-{
- FcRange c;
-
- if (!r)
- return FcFalse;
- c = FcRangeCanonicalize (r);
-
- return FcDoubleIsZero (c.u.d.begin) && FcDoubleIsZero (c.u.d.end);
-}
-
-FcBool
FcRangeIsInRange (const FcRange *a, const FcRange *b)
{
- FcRange ca, cb;
- FcBool f;
-
if (!a || !b)
return FcFalse;
- ca = FcRangeCanonicalize (a);
- cb = FcRangeCanonicalize (b);
- if (ca.is_inclusive & cb.is_inclusive)
- f = ca.u.d.end <= cb.u.d.end;
- else
- f = ca.u.d.end < cb.u.d.end;
-
- return FcDoubleCmpGE (ca.u.d.begin, cb.u.d.begin) && f;
+ return a->begin >= b->begin && a->end <= b->end;
}
FcBool
FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b)
{
- FcRange ca, cb;
-
switch ((int) op) {
case FcOpEqual:
case FcOpContains:
@@ -178,21 +114,13 @@ FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b)
case FcOpNotContains:
return !FcRangeIsInRange (a, b);
case FcOpLess:
- ca = FcRangeCanonicalize (a);
- cb = FcRangeCanonicalize (b);
- return ca.u.d.begin < cb.u.d.begin;
+ return a->begin < b->begin;
case FcOpLessEqual:
- ca = FcRangeCanonicalize (a);
- cb = FcRangeCanonicalize (b);
- return FcDoubleCmpLE (ca.u.d.begin, cb.u.d.begin);
+ return a->begin <= b->begin;
case FcOpMore:
- ca = FcRangeCanonicalize (a);
- cb = FcRangeCanonicalize (b);
- return ca.u.d.end > cb.u.d.end;
+ return a->end > b->end;
case FcOpMoreEqual:
- ca = FcRangeCanonicalize (a);
- cb = FcRangeCanonicalize (b);
- return FcDoubleCmpGE (ca.u.d.end, cb.u.d.end);
+ return a->end >= b->end;
default:
break;
}
@@ -202,9 +130,8 @@ FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b)
FcChar32
FcRangeHash (const FcRange *r)
{
- FcRange c = FcRangeCanonicalize (r);
- int b = (int) (c.u.d.begin * 100);
- int e = FcDoubleCmpEQ (c.u.d.end, DBL_MAX) ? INT_MAX : (int) (c.u.d.end * 100);
+ int b = (int) (r->begin * 100);
+ int e = (int) (r->end * 100);
return b ^ (b << 1) ^ (e << 9);
}
diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c
index 9a6f08d27..bad6b8193 100644
--- a/fontconfig/src/fcxml.c
+++ b/fontconfig/src/fcxml.c
@@ -57,6 +57,9 @@
extern FcChar8 fontconfig_instprefix[];
#endif
+static FcChar8 *__fc_userdir = NULL;
+static FcChar8 *__fc_userconf = NULL;
+
static void
FcExprDestroy (FcExpr *e);
@@ -79,6 +82,7 @@ FcRuleDestroy (FcRule *rule)
case FcRuleEdit:
FcEditDestroy (rule->u.edit);
break;
+ case FcRuleUnknown:
default:
break;
}
@@ -609,6 +613,7 @@ FcTypeName (FcType type)
return "langset";
case FcTypeRange:
return "range";
+ case FcTypeUnknown:
default:
return "unknown";
}
@@ -806,6 +811,7 @@ FcRuleCreate (FcRuleType type,
case FcRuleEdit:
r->u.edit = (FcEdit *) p;
break;
+ case FcRuleUnknown:
default:
free (r);
r = NULL;
@@ -1255,7 +1261,6 @@ FcParseBlank (FcConfigParse *parse)
{
int n = FcVStackElements (parse);
FcChar32 i, begin, end;
- FcRange r;
while (n-- > 0)
{
@@ -1272,9 +1277,8 @@ FcParseBlank (FcConfigParse *parse)
goto bail;
break;
case FcVStackRange:
- r = FcRangeCanonicalize (v->u.range);
- begin = (FcChar32)r.u.d.begin;
- end = (FcChar32)r.u.d.end;
+ begin = (FcChar32) v->u.range->begin;
+ end = (FcChar32) v->u.range->end;
if (begin <= end)
{
for (i = begin; i <= end; i++)
@@ -1587,7 +1591,6 @@ FcParseCharSet (FcConfigParse *parse)
FcVStack *vstack;
FcCharSet *charset = FcCharSetCreate ();
FcChar32 i, begin, end;
- FcRange r;
int n = 0;
while ((vstack = FcVStackPeek (parse)))
@@ -1602,9 +1605,8 @@ FcParseCharSet (FcConfigParse *parse)
n++;
break;
case FcVStackRange:
- r = FcRangeCanonicalize (vstack->u.range);
- begin = (FcChar32)r.u.d.begin;
- end = (FcChar32)r.u.d.end;
+ begin = (FcChar32) vstack->u.range->begin;
+ end = (FcChar32) vstack->u.range->end;
if (begin <= end)
{
@@ -2262,6 +2264,24 @@ FcParseCacheDir (FcConfigParse *parse)
FcStrFree (data);
}
+void
+FcConfigPathFini (void)
+{
+ FcChar8 *s;
+
+retry_dir:
+ s = fc_atomic_ptr_get (&__fc_userdir);
+ if (!fc_atomic_ptr_cmpexch (&__fc_userdir, s, NULL))
+ goto retry_dir;
+ free (s);
+
+retry_conf:
+ s = fc_atomic_ptr_get (&__fc_userconf);
+ if (!fc_atomic_ptr_cmpexch (&__fc_userconf, s, NULL))
+ goto retry_conf;
+ free (s);
+}
+
static void
FcParseInclude (FcConfigParse *parse)
{
@@ -2272,8 +2292,7 @@ FcParseInclude (FcConfigParse *parse)
FcBool deprecated = FcFalse;
#endif
FcChar8 *prefix = NULL, *p;
- static FcChar8 *userdir = NULL;
- static FcChar8 *userconf = NULL;
+ FcChar8 *userdir = NULL, *userconf = NULL;
s = FcStrBufDoneStatic (&parse->pstack->str);
if (!s)
@@ -2303,6 +2322,7 @@ FcParseInclude (FcConfigParse *parse)
{
size_t plen = strlen ((const char *)prefix);
size_t dlen = strlen ((const char *)s);
+ FcChar8 *u;
p = realloc (prefix, plen + 1 + dlen + 1);
if (!p)
@@ -2318,14 +2338,32 @@ FcParseInclude (FcConfigParse *parse)
if (FcFileIsDir (s))
{
userdir:
+ userdir = fc_atomic_ptr_get (&__fc_userdir);
if (!userdir)
- userdir = FcStrdup (s);
+ {
+ u = FcStrdup (s);
+ if (!fc_atomic_ptr_cmpexch (&__fc_userdir, userdir, u))
+ {
+ free (u);
+ goto userdir;
+ }
+ userdir = u;
+ }
}
else if (FcFileIsFile (s))
{
userconf:
+ userconf = fc_atomic_ptr_get (&__fc_userconf);
if (!userconf)
- userconf = FcStrdup (s);
+ {
+ u = FcStrdup (s);
+ if (!fc_atomic_ptr_cmpexch (&__fc_userconf, userconf, u))
+ {
+ free (u);
+ goto userconf;
+ }
+ userconf = u;
+ }
}
else
{
@@ -2349,6 +2387,7 @@ FcParseInclude (FcConfigParse *parse)
filename = FcConfigFilename(s);
if (deprecated == FcTrue &&
filename != NULL &&
+ userdir != NULL &&
!FcFileIsLink (filename))
{
if (FcFileIsDir (filename))