[Fontconfig] fontconfig: Branch 'master'

Behdad Esfahbod behdad at behdad.org
Tue Feb 5 08:36:34 PST 2013


Oh yeah, I think it should be even higher priority than FC_FILE.  It's a
binary match.

On 02/05/2013 03:27 AM, Akira TAGOH wrote:
> I didn't update the matcher for this. so even if one adds the hash value in
> FcPattern, it doesn't affect the score of the best match. guess it may be not
> something one expects? should we allow it to have a score? then what is the
> expected order? it's supposed to be an unique so adding it after FC_FILE would
> be ideal?
> 
> 
> On Tue, Feb 5, 2013 at 3:35 PM, Akira TAGOH <tagoh at kemper.freedesktop.org
> <mailto:tagoh at kemper.freedesktop.org>> wrote:
> 
>      fontconfig/fontconfig.h |    1
>      src/Makefile.am         |    1
>      src/fcfreetype.c        |    9 +
>      src/fchash.c            |  265
>     ++++++++++++++++++++++++++++++++++++++++++++++++
>      src/fcint.h             |    7 +
>      src/fcobjs.h            |    1
>      6 files changed, 284 insertions(+)
> 
>     New commits:
>     commit 95af7447dba7c54ed162b667c0bb2ea6500e8f32
>     Author: Akira TAGOH <akira at tagoh.org <mailto:akira at tagoh.org>>
>     Date:   Mon Feb 4 16:03:29 2013 +0900
> 
>         Bug 50733 - Add font-file hash?
> 
>         Add "hash" object which contains SHA256 hash value (so far) computed
>     from the font file.
> 
>     diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
>     index dc2532f..ff52a61 100644
>     --- a/fontconfig/fontconfig.h
>     +++ b/fontconfig/fontconfig.h
>     @@ -115,6 +115,7 @@ typedef int         FcBool;
>      #define FC_FONT_FEATURES    "fontfeatures"     /* String */
>      #define FC_NAMELANG        "namelang"          /* String RFC 3866 langs */
>      #define FC_PRGNAME         "prgname"           /* String */
>     +#define FC_HASH                    "hash"              /* String */
> 
>      #define FC_CACHE_SUFFIX                    ".cache-" FC_CACHE_VERSION
>      #define FC_DIR_CACHE_FILE          "fonts.cache-" FC_CACHE_VERSION
>     diff --git a/src/Makefile.am b/src/Makefile.am
>     index 8fb8b64..9fd7dd8 100644
>     --- a/src/Makefile.am
>     +++ b/src/Makefile.am
>     @@ -139,6 +139,7 @@ libfontconfig_la_SOURCES = \
>             fcformat.c \
>             fcfreetype.c \
>             fcfs.c \
>     +       fchash.c \
>             fcinit.c \
>             fclang.c \
>             fclist.c \
>     diff --git a/src/fcfreetype.c b/src/fcfreetype.c
>     index faf3c35..111f784 100644
>     --- a/src/fcfreetype.c
>     +++ b/src/fcfreetype.c
>     @@ -1123,6 +1123,8 @@ FcFreeTypeQueryFace (const FT_Face  face,
>          FcChar8        *style = 0;
>          int                    st;
> 
>     +    FcChar8        *hashstr;
>     +
>          pat = FcPatternCreate ();
>          if (!pat)
>             goto bail0;
>     @@ -1634,6 +1636,13 @@ FcFreeTypeQueryFace (const FT_Face  face,
>          if (!FcPatternAddBool (pat, FC_DECORATIVE, decorative))
>             goto bail1;
> 
>     +    hashstr = FcHashGetSHA256DigestFromFile (file);
>     +    if (!hashstr)
>     +       goto bail1;
>     +    if (!FcPatternAddString (pat, FC_HASH, hashstr))
>     +       goto bail1;
>     +    free (hashstr);
>     +
>          /*
>           * Compute the unicode coverage for the font
>           */
>     diff --git a/src/fchash.c b/src/fchash.c
>     new file mode 100644
>     index 0000000..827b20f
>     --- /dev/null
>     +++ b/src/fchash.c
>     @@ -0,0 +1,265 @@
>     +/*
>     + * fontconfig/src/fchash.c
>     + *
>     + * Copyright © 2003 Keith Packard
>     + * Copyright © 2013 Red Hat, Inc.
>     + * Red Hat Author(s): Akira TAGOH
>     + *
>     + * Permission to use, copy, modify, distribute, and sell this software
>     and its
>     + * documentation for any purpose is hereby granted without fee, provided that
>     + * the above copyright notice appear in all copies and that both that
>     + * copyright notice and this permission notice appear in supporting
>     + * documentation, and that the name of the author(s) not be used in
>     + * advertising or publicity pertaining to distribution of the software
>     without
>     + * specific, written prior permission.  The authors make no
>     + * representations about the suitability of this software for any
>     purpose.  It
>     + * is provided "as is" without express or implied warranty.
>     + *
>     + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
>     + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
>     + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
>     + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
>     USE,
>     + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
>     + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
>     + * PERFORMANCE OF THIS SOFTWARE.
>     + */
>     +#ifdef HAVE_CONFIG_H
>     +#include "config.h"
>     +#endif
>     +#include "fcint.h"
>     +#include <stdio.h>
>     +#include <string.h>
>     +
>     +#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)
>     +#define Ch(x, y, z)    ((x & y) ^ (~x & z))
>     +#define Maj(x, y, z)   ((x & y) ^ (x & z) ^ (y & z))
>     +#define SS0(x)         (ROTR32(x, 2) ^ ROTR32(x, 13) ^ ROTR32(x, 22))
>     +#define SS1(x)         (ROTR32(x, 6) ^ ROTR32(x, 11) ^ ROTR32(x, 25))
>     +#define ss0(x)         (ROTR32(x, 7) ^ ROTR32(x, 18) ^ SHR(x, 3))
>     +#define ss1(x)         (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10))
>     +
>     +
>     +static FcChar32 *
>     +FcHashInitSHA256Digest (void)
>     +{
>     +    int i;
>     +    static const FcChar32 h[] = {
>     +       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;
>     +}
>     +
>     +static void
>     +FcHashComputeSHA256Digest (FcChar32   *hash,
>     +                          const char *block)
>     +{
>     +    static const FcChar32 k[] = {
>     +       0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
>     +       0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
>     +       0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
>     +       0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
>     +       0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
>     +       0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
>     +       0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
>     +       0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
>     +       0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
>     +       0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
>     +       0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
>     +       0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
>     +       0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
>     +       0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
>     +       0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
>     +       0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
>     +    };
>     +    FcChar32 w[64], i, j, t1, t2;
>     +    FcChar32 a, b, c, d, e, f, g, h;
>     +
>     +#define H(n)   (hash[n])
>     +
>     +    a = H(0);
>     +    b = H(1);
>     +    c = H(2);
>     +    d = H(3);
>     +    e = H(4);
>     +    f = H(5);
>     +    g = H(6);
>     +    h = H(7);
>     +
>     +    for (i = 0; i < 16; i++)
>     +    {
>     +       j =  (block[(i * 4) + 0] & 0xff) << (8 * 3);
>     +       j |= (block[(i * 4) + 1] & 0xff) << (8 * 2);
>     +       j |= (block[(i * 4) + 2] & 0xff) << (8 * 1);
>     +       j |= (block[(i * 4) + 3] & 0xff);
>     +       w[i] = j;
>     +    }
>     +    for (i = 16; i < 64; i++)
>     +       w[i] = ss1(w[i - 2]) + w[i - 7] + ss0(w[i - 15]) + w[i - 16];
>     +
>     +    for (i = 0; i < 64; i++)
>     +    {
>     +       t1 = h + SS1(e) + Ch(e, f, g) + k[i] + w[i];
>     +       t2 = SS0(a) + Maj(a, b, c);
>     +       h = g;
>     +       g = f;
>     +       f = e;
>     +       e = d + t1;
>     +       d = c;
>     +       c = b;
>     +       b = a;
>     +       a = t1 + t2;
>     +    }
>     +
>     +    H(0) += a;
>     +    H(1) += b;
>     +    H(2) += c;
>     +    H(3) += d;
>     +    H(4) += e;
>     +    H(5) += f;
>     +    H(6) += g;
>     +    H(7) += h;
>     +
>     +#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] =  len        & 0xff;
>     +    block[63 - 1] = (len >>  8) & 0xff;
>     +    block[63 - 2] = (len >> 16) & 0xff;
>     +    block[63 - 3] = (len >> 24) & 0xff;
>     +    block[63 - 4] = (len >> 32) & 0xff;
>     +    block[63 - 5] = (len >> 40) & 0xff;
>     +    block[63 - 6] = (len >> 48) & 0xff;
>     +    block[63 - 7] = (len >> 56) & 0xff;
>     +    FcHashComputeSHA256Digest (ret, block);
>     +
>     +    return FcHashSHA256ToString (ret);
>     +}
>     +
>     +FcChar8 *
>     +FcHashGetSHA256DigestFromFile (const FcChar8 *filename)
>     +{
>     +    FILE *fp = fopen ((const char *)filename, "rb");
>     +    char ibuf[64];
>     +    FcChar32 *ret;
>     +    size_t len;
>     +    struct stat st;
>     +
>     +    if (!fp)
>     +       return NULL;
>     +
>     +    if (FcStat (filename, &st))
>     +       goto bail0;
>     +
>     +    ret = FcHashInitSHA256Digest ();
>     +    if (!ret)
>     +       return NULL;
>     +
>     +    while (!feof (fp))
>     +    {
>     +       if ((len = fread (ibuf, sizeof (char), 64, fp)) < 64)
>     +       {
>     +           long 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);
>     +       }
>     +    }
>     +    fclose (fp);
>     +
>     +    return FcHashSHA256ToString (ret);
>     +
>     +bail0:
>     +    fclose (fp);
>     +    return NULL;
>     +}
>     diff --git a/src/fcint.h b/src/fcint.h
>     index fceb8cc..b5ff382 100644
>     --- a/src/fcint.h
>     +++ b/src/fcint.h
>     @@ -812,6 +812,13 @@ FcFontSetSerializeAlloc (FcSerialize *serialize,
>     const FcFontSet *s);
>      FcPrivate FcFontSet *
>      FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s);
> 
>     +/* fchash.c */
>     +FcPrivate FcChar8 *
>     +FcHashGetSHA256Digest (const FcChar8 *input_strings,
>     +                      size_t         len);
>     +FcPrivate FcChar8 *
>     +FcHashGetSHA256DigestFromFile (const FcChar8 *filename);
>     +
>      /* fcxml.c */
>      FcPrivate void
>      FcTestDestroy (FcTest *test);
>     diff --git a/src/fcobjs.h b/src/fcobjs.h
>     index ad803eb..3cb2349 100644
>     --- a/src/fcobjs.h
>     +++ b/src/fcobjs.h
>     @@ -43,4 +43,5 @@ FC_OBJECT (LCD_FILTER,                FcTypeInteger)
>      FC_OBJECT (NAMELANG,           FcTypeString)
>      FC_OBJECT (FONT_FEATURES,      FcTypeString)
>      FC_OBJECT (PRGNAME,            FcTypeString)
>     +FC_OBJECT (HASH,               FcTypeString)
>      /* ^-------------- Add new objects here. */
> 
>     _______________________________________________
>     Fontconfig mailing list
>     Fontconfig at lists.freedesktop.org <mailto:Fontconfig at lists.freedesktop.org>
>     http://lists.freedesktop.org/mailman/listinfo/fontconfig
> 
> 
> 
> 
> -- 
> Akira TAGOH
> 
> 
> _______________________________________________
> Fontconfig mailing list
> Fontconfig at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/fontconfig
> 

-- 
behdad
http://behdad.org/


More information about the Fontconfig mailing list