aboutsummaryrefslogtreecommitdiff
path: root/fontconfig
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig')
-rw-r--r--fontconfig/src/fccfg.c10
-rw-r--r--fontconfig/src/fccharset.c15
-rw-r--r--fontconfig/src/fcfreetype.c82
-rw-r--r--fontconfig/src/fchash.c234
-rw-r--r--fontconfig/src/fcint.h24
-rw-r--r--fontconfig/src/fclang.c27
6 files changed, 154 insertions, 238 deletions
diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c
index cdb8c0f25..fe69eecd7 100644
--- a/fontconfig/src/fccfg.c
+++ b/fontconfig/src/fccfg.c
@@ -722,6 +722,16 @@ FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf)
v.u.l = FcLangSetPromote (v.u.s, buf);
v.type = FcTypeLangSet;
}
+ else if (v.type == FcTypeVoid && u.type == FcTypeLangSet)
+ {
+ v.u.l = FcLangSetPromote (NULL, buf);
+ v.type = FcTypeLangSet;
+ }
+ else if (v.type == FcTypeVoid && u.type == FcTypeCharSet)
+ {
+ v.u.c = FcCharSetPromote (buf);
+ v.type = FcTypeCharSet;
+ }
if (buf && v.type == FcTypeDouble && u.type == FcTypeRange)
{
v.u.r = FcRangePromote (v.u.d, buf);
diff --git a/fontconfig/src/fccharset.c b/fontconfig/src/fccharset.c
index c9f928cd4..43a3cc00a 100644
--- a/fontconfig/src/fccharset.c
+++ b/fontconfig/src/fccharset.c
@@ -43,6 +43,21 @@ FcCharSetCreate (void)
}
FcCharSet *
+FcCharSetPromote (FcValuePromotionBuffer *vbuf)
+{
+ FcCharSet *fcs = (FcCharSet *) vbuf;
+
+ FC_ASSERT_STATIC (sizeof (FcCharSet) <= sizeof (FcValuePromotionBuffer));
+
+ FcRefSetConst (&fcs->ref);
+ fcs->num = 0;
+ fcs->leaves_offset = 0;
+ fcs->numbers_offset = 0;
+
+ return fcs;
+}
+
+FcCharSet *
FcCharSetNew (void)
{
return FcCharSetCreate ();
diff --git a/fontconfig/src/fcfreetype.c b/fontconfig/src/fcfreetype.c
index d0932b31b..3dd865a83 100644
--- a/fontconfig/src/fcfreetype.c
+++ b/fontconfig/src/fcfreetype.c
@@ -1104,9 +1104,6 @@ FcFreeTypeQueryFace (const FT_Face face,
char psname[256];
const char *tmp;
- FcChar8 *hashstr = NULL;
- FT_Error err;
- FT_ULong len = 0, alen;
FcRange *r = NULL;
double lower_size = 0.0L, upper_size = DBL_MAX;
@@ -1324,7 +1321,7 @@ FcFreeTypeQueryFace (const FT_Face face,
++nstyle;
}
- if (!nfamily)
+ if (!nfamily && file && *file)
{
FcChar8 *start, *end;
FcChar8 *family;
@@ -1398,7 +1395,7 @@ FcFreeTypeQueryFace (const FT_Face face,
if (!FcPatternAddString (pat, FC_POSTSCRIPT_NAME, (const FcChar8 *)psname))
goto bail1;
- if (!FcPatternAddString (pat, FC_FILE, file))
+ if (file && *file && !FcPatternAddString (pat, FC_FILE, file))
goto bail1;
if (!FcPatternAddInteger (pat, FC_INDEX, id))
@@ -1699,46 +1696,55 @@ FcFreeTypeQueryFace (const FT_Face face,
if (!FcPatternAddBool (pat, FC_DECORATIVE, decorative))
goto bail1;
- err = FT_Load_Sfnt_Table (face, 0, 0, NULL, &len);
- if (err == FT_Err_Ok)
+
+ /*
+ * Compute hash digest for the font
+ */
{
- char *fontdata;
-
- alen = (len + 63) & ~63;
- fontdata = malloc (alen);
- if (!fontdata)
- goto bail3;
- err = FT_Load_Sfnt_Table (face, 0, 0, (FT_Byte *)fontdata, &len);
- if (err != FT_Err_Ok)
+ FcChar8 *hashstr = NULL;
+ FcHashDigest digest;
+
+ FcHashInitDigest (digest);
+
+ if (face->stream->read == NULL)
{
- free (fontdata);
- goto bail3;
+ const char *data = (const char *) face->stream->base;
+ size_t total_len = face->stream->size;
+ size_t len = total_len;
+
+ while (len >= 64)
+ {
+ FcHashDigestAddBlock (digest, data);
+ data += 64;
+ len -= 64;
+ }
+ FcHashDigestFinish (digest, data, total_len);
+ } else {
+ char data[64];
+ size_t total_len = 0;
+ size_t len = 0;
+
+ while ((len = face->stream->read (face->stream, total_len, (unsigned char *) data, sizeof(data))) == 64)
+ {
+ FcHashDigestAddBlock (digest, data);
+ total_len += 64;
+ }
+ total_len += len;
+ FcHashDigestFinish (digest, data, total_len);
}
- memset (&fontdata[len], 0, alen - len);
- hashstr = FcHashGetSHA256DigestFromMemory (fontdata, len);
- free (fontdata);
- }
- else if (err == FT_Err_Invalid_Face_Handle)
- {
- /* font may not support SFNT. falling back to
- * read the font data from file directly
- */
- hashstr = FcHashGetSHA256DigestFromFile (file);
- }
- else
- {
- goto bail3;
- }
- if (hashstr)
- {
- if (!FcPatternAddString (pat, FC_HASH, hashstr))
+
+ hashstr = FcHashToString (digest);
+ if (hashstr)
{
+ if (!FcPatternAddString (pat, FC_HASH, hashstr))
+ {
+ free (hashstr);
+ goto bail1;
+ }
free (hashstr);
- goto bail1;
}
- free (hashstr);
}
-bail3:
+
/*
* Compute the unicode coverage for the font
diff --git a/fontconfig/src/fchash.c b/fontconfig/src/fchash.c
index 38300028c..1526cfd2b 100644
--- a/fontconfig/src/fchash.c
+++ b/fontconfig/src/fchash.c
@@ -3,7 +3,9 @@
*
* Copyright © 2003 Keith Packard
* Copyright © 2013 Red Hat, Inc.
+ * Copyright © 2014 Google, Inc.
* Red Hat Author(s): Akira TAGOH
+ * Google Author(s): Behdad Esfahbod
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -27,6 +29,9 @@
#include <stdio.h>
#include <string.h>
+/* SHA256 */
+
+
#define ROTRN(w, v, n) ((((FcChar32)v) >> n) | (((FcChar32)v) << (w - n)))
#define ROTR32(v, n) ROTRN(32, v, n)
#define SHR(v, n) (v >> n)
@@ -38,28 +43,21 @@
#define ss1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10))
-static FcChar32 *
-FcHashInitSHA256Digest (void)
+
+void
+FcHashInitDigest (FcHashDigest digest)
{
- int i;
- static const FcChar32 h[] = {
+ static const FcHashDigest init = {
0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL
};
- FcChar32 *ret = malloc (sizeof (FcChar32) * 8);
- if (!ret)
- return NULL;
-
- for (i = 0; i < 8; i++)
- ret[i] = h[i];
-
- return ret;
+ memcpy (digest, init, sizeof (FcHashDigest));
}
-static void
-FcHashComputeSHA256Digest (FcChar32 *hash,
- const char *block)
+void
+FcHashDigestAddBlock (FcHashDigest digest,
+ const char block[64])
{
static const FcChar32 k[] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
@@ -82,7 +80,7 @@ FcHashComputeSHA256Digest (FcChar32 *hash,
FcChar32 w[64], i, j, t1, t2;
FcChar32 a, b, c, d, e, f, g, h;
-#define H(n) (hash[n])
+#define H(n) (digest[n])
a = H(0);
b = H(1);
@@ -130,188 +128,62 @@ FcHashComputeSHA256Digest (FcChar32 *hash,
#undef H
}
-static FcChar8 *
-FcHashSHA256ToString (FcChar32 *hash)
-{
- FcChar8 *ret = NULL;
- static const char hex[] = "0123456789abcdef";
- int i, j;
-
- if (hash)
- {
- ret = malloc (sizeof (FcChar8) * (8 * 8 + 7 + 1));
- if (!ret)
- return NULL;
- memcpy (ret, "sha256:", 7);
-#define H(n) hash[n]
- for (i = 0; i < 8; i++)
- {
- FcChar32 v = H(i);
-
- for (j = 0; j < 8; j++)
- ret[7 + (i * 8) + j] = hex[(v >> (28 - j * 4)) & 0xf];
- }
- ret[7 + i * 8] = 0;
-#undef H
- free (hash);
- }
-
- return ret;
-}
-
-FcChar8 *
-FcHashGetSHA256Digest (const FcChar8 *input_strings,
- size_t len)
-{
- size_t i, round_len = len / 64;
- char block[64];
- FcChar32 *ret = FcHashInitSHA256Digest ();
-
- if (!ret)
- return NULL;
-
- for (i = 0; i < round_len; i++)
- {
- FcHashComputeSHA256Digest (ret, (const char *)&input_strings[i * 64]);
- }
- /* padding */
- if ((len % 64) != 0)
- memcpy (block, &input_strings[len / 64], len % 64);
- memset (&block[len % 64], 0, 64 - (len % 64));
- block[len % 64] = 0x80;
- if ((64 - (len % 64)) < 9)
- {
- /* process a block once */
- FcHashComputeSHA256Digest (ret, block);
- memset (block, 0, 64);
- }
- /* set input size at the end */
- len *= 8;
- block[63 - 0] = (uint64_t)len & 0xff;
- block[63 - 1] = ((uint64_t)len >> 8) & 0xff;
- block[63 - 2] = ((uint64_t)len >> 16) & 0xff;
- block[63 - 3] = ((uint64_t)len >> 24) & 0xff;
- block[63 - 4] = ((uint64_t)len >> 32) & 0xff;
- block[63 - 5] = ((uint64_t)len >> 40) & 0xff;
- block[63 - 6] = ((uint64_t)len >> 48) & 0xff;
- block[63 - 7] = ((uint64_t)len >> 56) & 0xff;
- FcHashComputeSHA256Digest (ret, block);
-
- return FcHashSHA256ToString (ret);
-}
-
-FcChar8 *
-FcHashGetSHA256DigestFromFile (const FcChar8 *filename)
+void
+FcHashDigestFinish (FcHashDigest digest,
+ const char *residual, /* < 64 bytes */
+ size_t total_len)
{
- FILE *fp = fopen ((const char *)filename, "rb");
char ibuf[64];
- FcChar32 *ret;
- size_t len;
- struct stat st;
-
- if (!fp)
- return NULL;
+ unsigned int len = total_len % 64;
+ uint64_t v;
- if (FcStat (filename, &st))
- goto bail0;
+ if (!len)
+ return;
- ret = FcHashInitSHA256Digest ();
- if (!ret)
- goto bail0;
+ memcpy (ibuf, residual, len);
+ memset (ibuf + len, 0, 64 - len);
+ ibuf[len] = 0x80;
- while (!feof (fp))
+ if ((64 - len) < 9)
{
- if ((len = fread (ibuf, sizeof (char), 64, fp)) < 64)
- {
- uint64_t v;
-
- /* add a padding */
- memset (&ibuf[len], 0, 64 - len);
- ibuf[len] = 0x80;
- if ((64 - len) < 9)
- {
- /* process a block once */
- FcHashComputeSHA256Digest (ret, ibuf);
- memset (ibuf, 0, 64);
- }
- /* set input size at the end */
- v = (long)st.st_size * 8;
- ibuf[63 - 0] = v & 0xff;
- ibuf[63 - 1] = (v >> 8) & 0xff;
- ibuf[63 - 2] = (v >> 16) & 0xff;
- ibuf[63 - 3] = (v >> 24) & 0xff;
- ibuf[63 - 4] = (v >> 32) & 0xff;
- ibuf[63 - 5] = (v >> 40) & 0xff;
- ibuf[63 - 6] = (v >> 48) & 0xff;
- ibuf[63 - 7] = (v >> 56) & 0xff;
- FcHashComputeSHA256Digest (ret, ibuf);
- break;
- }
- else
- {
- FcHashComputeSHA256Digest (ret, ibuf);
- }
+ FcHashDigestAddBlock (digest, ibuf);
+ memset (ibuf, 0, 64);
}
- fclose (fp);
-
- return FcHashSHA256ToString (ret);
-
-bail0:
- fclose (fp);
- return NULL;
+ /* set input size at the end */
+ v = (uint64_t) total_len * 8;
+ ibuf[63 - 0] = v & 0xff;
+ ibuf[63 - 1] = (v >> 8) & 0xff;
+ ibuf[63 - 2] = (v >> 16) & 0xff;
+ ibuf[63 - 3] = (v >> 24) & 0xff;
+ ibuf[63 - 4] = (v >> 32) & 0xff;
+ ibuf[63 - 5] = (v >> 40) & 0xff;
+ ibuf[63 - 6] = (v >> 48) & 0xff;
+ ibuf[63 - 7] = (v >> 56) & 0xff;
+ FcHashDigestAddBlock (digest, ibuf);
}
FcChar8 *
-FcHashGetSHA256DigestFromMemory (const char *fontdata,
- size_t length)
+FcHashToString (const FcHashDigest digest)
{
- char ibuf[64];
- FcChar32 *ret;
- size_t i = 0;
+ FcChar8 *ret = NULL;
+ static const char hex[] = "0123456789abcdef";
+ int i, j;
- ret = FcHashInitSHA256Digest ();
+ ret = malloc (sizeof (FcChar8) * (8 * 8 + 7 + 1));
if (!ret)
return NULL;
-
- while (i <= length)
+ memcpy (ret, "sha256:", 7);
+#define H(n) digest[n]
+ for (i = 0; i < 8; i++)
{
- if ((length - i) < 64)
- {
- uint64_t v;
- size_t n;
+ FcChar32 v = H(i);
- /* add a padding */
- n = length - i;
- if (n > 0)
- memcpy (ibuf, &fontdata[i], n);
- memset (&ibuf[n], 0, 64 - n);
- ibuf[n] = 0x80;
- if ((64 - n) < 9)
- {
- /* process a block once */
- FcHashComputeSHA256Digest (ret, ibuf);
- memset (ibuf, 0, 64);
- }
- /* set input size at the end */
- v = length * 8;
- ibuf[63 - 0] = v & 0xff;
- ibuf[63 - 1] = (v >> 8) & 0xff;
- ibuf[63 - 2] = (v >> 16) & 0xff;
- ibuf[63 - 3] = (v >> 24) & 0xff;
- ibuf[63 - 4] = (v >> 32) & 0xff;
- ibuf[63 - 5] = (v >> 40) & 0xff;
- ibuf[63 - 6] = (v >> 48) & 0xff;
- ibuf[63 - 7] = (v >> 56) & 0xff;
- FcHashComputeSHA256Digest (ret, ibuf);
- break;
- }
- else
- {
- FcHashComputeSHA256Digest (ret, &fontdata[i]);
- }
- i += 64;
+ for (j = 0; j < 8; j++)
+ ret[7 + (i * 8) + j] = hex[(v >> (28 - j * 4)) & 0xf];
}
+ ret[7 + i * 8] = 0;
+#undef H
- return FcHashSHA256ToString (ret);
+ return ret;
}
diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h
index dd26fd89a..3d41b0cb2 100644
--- a/fontconfig/src/fcint.h
+++ b/fontconfig/src/fcint.h
@@ -720,6 +720,9 @@ FcPrivate FcLangSet *
FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l);
/* fccharset.c */
+FcPrivate FcCharSet *
+FcCharSetPromote (FcValuePromotionBuffer *vbuf);
+
FcPrivate void
FcLangCharSetPopulate (void);
@@ -864,16 +867,23 @@ FcPrivate FcFontSet *
FcFontSetDeserialize (const FcFontSet *set);
/* fchash.c */
-FcPrivate FcChar8 *
-FcHashGetSHA256Digest (const FcChar8 *input_strings,
- size_t len);
-FcPrivate FcChar8 *
-FcHashGetSHA256DigestFromFile (const FcChar8 *filename);
+typedef FcChar32 FcHashDigest[8];
+
+FcPrivate void
+FcHashInitDigest (FcHashDigest digest);
+
+FcPrivate void
+FcHashDigestAddBlock (FcHashDigest digest,
+ const char block[64]);
+
+FcPrivate void
+FcHashDigestFinish (FcHashDigest digest,
+ const char *residual, /* < 64 bytes */
+ size_t total_len);
FcPrivate FcChar8 *
-FcHashGetSHA256DigestFromMemory (const char *fontdata,
- size_t length);
+FcHashToString (const FcHashDigest digest);
/* fcinit.c */
FcPrivate FcConfig *
diff --git a/fontconfig/src/fclang.c b/fontconfig/src/fclang.c
index 9f685f6fd..b1fd1bcae 100644
--- a/fontconfig/src/fclang.c
+++ b/fontconfig/src/fclang.c
@@ -720,19 +720,22 @@ FcLangSetPromote (const FcChar8 *lang, FcValuePromotionBuffer *vbuf)
memset (buf->ls.map, '\0', sizeof (buf->ls.map));
buf->ls.map_size = NUM_LANG_SET_MAP;
buf->ls.extra = 0;
- id = FcLangSetIndex (lang);
- if (id > 0)
+ if (lang)
{
- FcLangSetBitSet (&buf->ls, id);
- }
- else
- {
- buf->ls.extra = &buf->strs;
- buf->strs.num = 1;
- buf->strs.size = 1;
- buf->strs.strs = &buf->str;
- FcRefInit (&buf->strs.ref, 1);
- buf->str = (FcChar8 *) lang;
+ id = FcLangSetIndex (lang);
+ if (id > 0)
+ {
+ FcLangSetBitSet (&buf->ls, id);
+ }
+ else
+ {
+ buf->ls.extra = &buf->strs;
+ buf->strs.num = 1;
+ buf->strs.size = 1;
+ buf->strs.strs = &buf->str;
+ FcRefInit (&buf->strs.ref, 1);
+ buf->str = (FcChar8 *) lang;
+ }
}
return &buf->ls;
}