diff options
Diffstat (limited to 'fontconfig')
-rw-r--r-- | fontconfig/src/fccfg.c | 10 | ||||
-rw-r--r-- | fontconfig/src/fccharset.c | 15 | ||||
-rw-r--r-- | fontconfig/src/fcfreetype.c | 82 | ||||
-rw-r--r-- | fontconfig/src/fchash.c | 234 | ||||
-rw-r--r-- | fontconfig/src/fcint.h | 24 | ||||
-rw-r--r-- | fontconfig/src/fclang.c | 27 |
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; } |