summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2012-09-13 14:53:15 +0100
committerKen Sharp <ken.sharp@artifex.com>2012-09-13 14:53:15 +0100
commit44d00dd1bd34e2fb735d4682b73d880e208f92bd (patch)
tree36a68a99cfbcfb6c506fec5e5fddb872352d10e8
parente8cfe956fe45fa949d22b10e2af665506e49fde4 (diff)
downloadghostpdl-44d00dd1bd34e2fb735d4682b73d880e208f92bd.tar.gz
pdfwrite - improve subset font prefix generation
We generate the prefix for a subset font by creating a hash from the usage pattern of glyphs in a font. If the font was already subset, and 'compact' (ie glyphs are used in order from 1 to n), then it was possible to generate the same prefix for two differetn subsets of the same font. In fact this is always possible, but here we add a heuristic which uses the MD5 hash we create for stream objects as an additional hash when generating the subset prefix. This does not guarantee that name collisions won't occur but should reduce the incidence still further. No differences expected.
-rw-r--r--gs/base/gdevpdtb.c8
-rw-r--r--gs/base/gdevpdtb.h2
-rw-r--r--gs/base/gdevpdtd.c15
-rw-r--r--gs/base/gdevpdtd.h2
-rw-r--r--gs/base/gdevpdtf.c7
5 files changed, 31 insertions, 3 deletions
diff --git a/gs/base/gdevpdtb.c b/gs/base/gdevpdtb.c
index 45381780a..d123cea30 100644
--- a/gs/base/gdevpdtb.c
+++ b/gs/base/gdevpdtb.c
@@ -146,7 +146,7 @@ hash(ulong v, int index, ushort w)
* Add the XXXXXX+ prefix for a subset font.
*/
int
-pdf_add_subset_prefix(const gx_device_pdf *pdev, gs_string *pstr, byte *used, int count)
+pdf_add_subset_prefix(const gx_device_pdf *pdev, gs_string *pstr, byte *used, int count, char *md5_hash)
{
uint size = pstr->size;
byte *data = gs_resize_string(pdev->pdf_memory, pstr->data, size,
@@ -160,6 +160,12 @@ pdf_add_subset_prefix(const gx_device_pdf *pdev, gs_string *pstr, byte *used, in
if (data == 0)
return_error(gs_error_VMerror);
+ if (md5_hash) {
+ for (i = 0; i < 8; i++) {
+ v = hash(v, i, *(ushort *)(md5_hash + i));
+ }
+ }
+
/* Hash the 'used' array. */
for (i = 0; i < len0; i += sizeof(ushort))
v = hash(v, i, *(ushort *)(used + i));
diff --git a/gs/base/gdevpdtb.h b/gs/base/gdevpdtb.h
index a44da9bac..200c02193 100644
--- a/gs/base/gdevpdtb.h
+++ b/gs/base/gdevpdtb.h
@@ -117,7 +117,7 @@ bool pdf_has_subset_prefix(const byte *str, uint size);
* Add the XXXXXX+ prefix for a subset font.
*/
int pdf_add_subset_prefix(const gx_device_pdf *pdev, gs_string *pstr,
- byte *used, int count);
+ byte *used, int count, char *md5_hash);
/*
* Determine whether a copied font should be subsetted.
diff --git a/gs/base/gdevpdtd.c b/gs/base/gdevpdtd.c
index 19a9c028a..e2359a3ac 100644
--- a/gs/base/gdevpdtd.c
+++ b/gs/base/gdevpdtd.c
@@ -334,6 +334,21 @@ gs_string *pdf_font_descriptor_name(pdf_font_descriptor_t *pfd)
return &pfd->common.values.FontName;
}
+char *pdf_fontfile_hash(void *pfd)
+{
+ pdf_font_descriptor_t *fd = (pdf_font_descriptor_t *)pfd;
+ cos_dict_t *pcd;
+
+ if (fd->base_font && fd->base_font->FontFile) {
+ pcd = (cos_dict_t *)fd->base_font->FontFile;
+ if (pcd->stream_md5_valid)
+ return ((char *)pcd->stream_hash);
+ else
+ return 0;
+ } else
+ return 0;
+}
+
/*
* Return the (copied, subset or complete) font associated with a FontDescriptor.
* This procedure probably shouldn't exist....
diff --git a/gs/base/gdevpdtd.h b/gs/base/gdevpdtd.h
index b48089142..0ad885f3f 100644
--- a/gs/base/gdevpdtd.h
+++ b/gs/base/gdevpdtd.h
@@ -104,6 +104,8 @@ bool pdf_font_descriptor_is_subset(const pdf_font_descriptor_t *pfd);
*/
gs_string *pdf_font_descriptor_name(pdf_font_descriptor_t *pfd);
+char *pdf_fontfile_hash(void *pfd);
+
/*
* Return the (copied, subset or complete) font associated with a FontDescriptor.
* This procedure probably shouldn't exist....
diff --git a/gs/base/gdevpdtf.c b/gs/base/gdevpdtf.c
index c6e8e1553..bbdfa025b 100644
--- a/gs/base/gdevpdtf.c
+++ b/gs/base/gdevpdtf.c
@@ -891,7 +891,12 @@ pdf_compute_BaseFont(gx_device_pdf *pdev, pdf_font_resource_t *pdfont, bool fini
!pdf_has_subset_prefix(fname.data, fname.size) &&
pdf_font_descriptor_embedding(pdfont->FontDescriptor)
) {
- int code = pdf_add_subset_prefix(pdev, &fname, pdfont->used, pdfont->count);
+ int code;
+
+ if (pdfont->FontDescriptor)
+ code = pdf_add_subset_prefix(pdev, &fname, pdfont->used, pdfont->count, pdf_fontfile_hash(pdfont->FontDescriptor));
+ else
+ code = pdf_add_subset_prefix(pdev, &fname, pdfont->used, pdfont->count, 0);
if (code < 0)
return code;