Rewrite hashing to use FT_Stream directly

This is more robust but introduces a small change in behavior:
For .pcf.gz fonts, the new code calculates the hash of the uncompressed
font data whereas the original code was calculating the hash of the
compressed data.

No big deal IMO.
This commit is contained in:
Behdad Esfahbod 2014-05-16 15:02:58 -06:00
parent 8284df49ef
commit 3f992254f2
3 changed files with 61 additions and 111 deletions

View File

@ -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;
@ -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)
{
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)
/*
* Compute hash digest for the font
*/
{
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 = FcHashGetDigestFromMemory (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 = FcHashGetDigestFromFile (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

View File

@ -43,9 +43,8 @@
#define ss1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10))
typedef FcChar32 FcHashDigest[8];
static void
void
FcHashInitDigest (FcHashDigest digest)
{
static const FcHashDigest init = {
@ -56,7 +55,7 @@ FcHashInitDigest (FcHashDigest digest)
memcpy (digest, init, sizeof (FcHashDigest));
}
static void
void
FcHashDigestAddBlock (FcHashDigest digest,
const char block[64])
{
@ -129,7 +128,7 @@ FcHashDigestAddBlock (FcHashDigest digest,
#undef H
}
static void
void
FcHashDigestFinish (FcHashDigest digest,
const char *residual, /* < 64 bytes */
size_t total_len)
@ -164,7 +163,7 @@ FcHashDigestFinish (FcHashDigest digest,
FcHashDigestAddBlock (digest, ibuf);
}
static FcChar8 *
FcChar8 *
FcHashToString (const FcHashDigest digest)
{
FcChar8 *ret = NULL;
@ -188,69 +187,3 @@ FcHashToString (const FcHashDigest digest)
return ret;
}
FcChar8 *
FcHashGetDigestFromFile (const FcChar8 *filename)
{
FcHashDigest digest;
FILE *fp;
char ibuf[64];
size_t len;
struct stat st;
fp = fopen ((const char *)filename, "rb");
if (!fp)
return NULL;
FcHashInitDigest (digest);
if (FcStat (filename, &st))
goto bail0;
while (!feof (fp))
{
if ((len = fread (ibuf, sizeof (char), 64, fp)) < 64)
{
FcHashDigestFinish (digest, ibuf, st.st_size);
break;
}
else
{
FcHashDigestAddBlock (digest, ibuf);
}
}
fclose (fp);
return FcHashToString (digest);
bail0:
fclose (fp);
return NULL;
}
FcChar8 *
FcHashGetDigestFromMemory (const char *fontdata,
size_t length)
{
FcHashDigest digest;
size_t i = 0;
FcHashInitDigest (digest);
while (i <= length)
{
if ((length - i) < 64)
{
FcHashDigestFinish (digest, fontdata+i, length);
break;
}
else
{
FcHashDigestAddBlock (digest, &fontdata[i]);
}
i += 64;
}
return FcHashToString (digest);
}

View File

@ -867,12 +867,23 @@ FcPrivate FcFontSet *
FcFontSetDeserialize (const FcFontSet *set);
/* fchash.c */
FcPrivate FcChar8 *
FcHashGetDigestFromFile (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 *
FcHashGetDigestFromMemory (const char *fontdata,
size_t length);
FcHashToString (const FcHashDigest digest);
/* fcinit.c */
FcPrivate FcConfig *