[gs-cvs] rev 7057 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Tue Sep 19 11:59:11 PDT 2006
Author: leonardo
Date: 2006-09-19 11:59:10 -0700 (Tue, 19 Sep 2006)
New Revision: 7057
Modified:
trunk/gs/src/gdevpdfb.h
trunk/gs/src/gdevpdfx.h
trunk/gs/src/gdevpdtd.c
trunk/gs/src/gdevpdtf.c
trunk/gs/src/gdevpdtf.h
trunk/gs/src/gdevpdtw.c
Log:
Fix (pdfwrite) : Wrinting a PDF/A, convert True Type fonts into CIDFontType2.
DETAILS :
THis is a partial fix the bug 688790
"pdfwrite : The PDF/A conversion needs to re-encode texts".
PDF/A doesn't allow True Type fonts with Encoding Differences.
Therefore we convert such fonts into CIDFontType2.
The main work is done with 2 functions :
pdf_convert_truetype_font_descriptor and
pdf_convert_truetype_font.
See comments in code about the conversion algorithm.
Minor change (gdevpdtw.c) : The old code always compressed CIDToGIDMap.
The new code does dependently on the CompressFonts distiller parameter.
Except that, for a non-PDFA run the code change should be equivalent.
Now the font conversion works, but Adobe preflight tool
reports missed glyphs by unknown reason.
Will need a separate patch for that.
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/src/gdevpdfb.h
===================================================================
--- trunk/gs/src/gdevpdfb.h 2006-09-19 16:08:49 UTC (rev 7056)
+++ trunk/gs/src/gdevpdfb.h 2006-09-19 18:59:10 UTC (rev 7057)
@@ -178,6 +178,8 @@
{0}, /* cs_Patterns */
{0}, /* Identity_ToUnicode_CMaps */
0, /* last_resource */
+ 0, /* OneByteIdentityH */
+ gs_no_id, /* IdentityCIDSystemInfo_id */
{
{
{0}}}, /* outline_levels */
Modified: trunk/gs/src/gdevpdfx.h
===================================================================
--- trunk/gs/src/gdevpdfx.h 2006-09-19 16:08:49 UTC (rev 7056)
+++ trunk/gs/src/gdevpdfx.h 2006-09-19 18:59:10 UTC (rev 7057)
@@ -534,6 +534,8 @@
pdf_resource_t *cs_Patterns[5];
pdf_resource_t *Identity_ToUnicode_CMaps[2]; /* WMode = 0,1 */
pdf_resource_t *last_resource;
+ pdf_resource_t *OneByteIdentityH;
+ gs_id IdentityCIDSystemInfo_id;
pdf_outline_level_t outline_levels[MAX_OUTLINE_DEPTH];
int outline_depth;
int closed_outline_depth;
Modified: trunk/gs/src/gdevpdtd.c
===================================================================
--- trunk/gs/src/gdevpdtd.c 2006-09-19 16:08:49 UTC (rev 7056)
+++ trunk/gs/src/gdevpdtd.c 2006-09-19 18:59:10 UTC (rev 7057)
@@ -681,7 +681,38 @@
* Convert True Type font descriptor into CID font descriptor for PDF/A.
*/
int
-pdf_convert_truetype_font_descriptor(gx_device_pdf *pdev, pdf_font_descriptor_t *pfd)
+pdf_convert_truetype_font_descriptor(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
{
+ pdf_font_descriptor_t *pfd = pdfont->FontDescriptor;
+ int num_CIDs = 256;
+ int length_CIDSet = num_CIDs / 8;
+ int length_CIDToGIDMap = num_CIDs * sizeof(ushort);
+ pdf_base_font_t *pbfont = pfd->base_font;
+ gs_font *pfont = (gs_font *)pbfont->copied;
+ gs_char ch;
+ /* Save the simple font descriptor data because CID font data overlap them. */
+ int FirstChar = pdfont->u.simple.FirstChar, LastChar = pdfont->u.simple.LastChar;
+ pdf_encoding_element_t *Encoding = pdfont->u.simple.Encoding;
+
+ pfd->FontType = ft_CID_TrueType;
+ pdfont->u.simple.Encoding = NULL; /* Drop due to overlapping against a garbager problem. */
+ pbfont->CIDSet = gs_alloc_bytes(pdev->pdf_memory, length_CIDSet,
+ "pdf_convert_truetype_font_descriptor");
+ if (pbfont->CIDSet == NULL)
+ return_error(gs_error_VMerror);
+ memset(pbfont->CIDSet, 0, length_CIDSet);
+ pdfont->u.cidfont.CIDToGIDMap = (ushort *)gs_alloc_bytes(pdev->pdf_memory,
+ length_CIDToGIDMap, "pdf_convert_truetype_font_descriptor");
+ if (pdfont->u.cidfont.CIDToGIDMap == NULL)
+ return_error(gs_error_VMerror);
+ memset(pdfont->u.cidfont.CIDToGIDMap, 0, length_CIDToGIDMap);
+ for (ch = FirstChar; ch <= LastChar; ch++) {
+ if (Encoding[ch].glyph != GS_NO_GLYPH) {
+ gs_glyph glyph = pfont->procs.encode_char(pfont, ch, GLYPH_SPACE_INDEX);
+
+ pbfont->CIDSet[ch / 8] |= 0x80 >> (ch % 8);
+ pdfont->u.cidfont.CIDToGIDMap[ch] = glyph - GS_MIN_GLYPH_INDEX;
+ }
+ }
return 0;
}
Modified: trunk/gs/src/gdevpdtf.c
===================================================================
--- trunk/gs/src/gdevpdtf.c 2006-09-19 16:08:49 UTC (rev 7056)
+++ trunk/gs/src/gdevpdtf.c 2006-09-19 18:59:10 UTC (rev 7057)
@@ -882,6 +882,19 @@
/* ------ CID-keyed ------ */
+/* Write CIDSystemInfo */
+private int
+pdf_write_cid_systemInfo_separate(gx_device_pdf *pdev, const gs_cid_system_info_t *pcidsi, long *id)
+{
+ int code;
+
+ *id = pdf_begin_separate(pdev);
+ code = pdf_write_cid_system_info(pdev, pcidsi, *id);
+ pdf_end_separate(pdev);
+ return code;
+}
+
+
/* Allocate a CIDFont resource. */
int
pdf_font_cidfont_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
@@ -939,15 +952,9 @@
* Write the CIDSystemInfo now, so we don't try to access it after
* the font may no longer be available.
*/
- {
- long cidsi_id = pdf_begin_separate(pdev);
-
- code = pdf_write_cid_system_info(pdev, pcidsi, cidsi_id);
- if (code < 0)
- return code;
- pdf_end_separate(pdev);
- pdfont->u.cidfont.CIDSystemInfo_id = cidsi_id;
- }
+ code = pdf_write_cid_systemInfo_separate(pdev, pcidsi, &pdfont->u.cidfont.CIDSystemInfo_id);
+ if (code < 0)
+ return code;
*ppfres = pdfont;
return pdf_compute_BaseFont(pdev, pdfont, false);
}
@@ -1004,16 +1011,49 @@
int
pdf_convert_truetype_font(gx_device_pdf *pdev, pdf_resource_t *pres)
{
- if (!pdev->PDFA )
+ if (!pdev->PDFA)
return 0;
else {
- pdf_font_resource_t *pdfont = (pdf_font_resource_t *) pres;
+ pdf_font_resource_t *pdfont = (pdf_font_resource_t *)pres;
if (pdfont->FontType != ft_TrueType)
return 0;
+ else if (pdf_resource_id(pres) == -1)
+ return 0; /* An unused font. */
else {
- /* Reserved for future implementation. */
- return 0;
+ int code = pdf_different_encoding_index(pdfont, 0);
+
+ if (code < 0)
+ return code;
+ if (code == 256)
+ return 0;
+ { /* The encoding have a difference - do convert. */
+ pdf_font_resource_t *pdfont0;
+ gs_const_string CMapName = {(const byte *)"OneByteIdentityH", 16};
+
+ code = pdf_convert_truetype_font_descriptor(pdev, pdfont);
+ if (code < 0)
+ return code;
+ code = pdf_font_type0_alloc(pdev, &pdfont0, pres->rid + 1, pdfont, &CMapName);
+ if (code < 0)
+ return code;
+ /* Pass the font object ID to the type 0 font resource. */
+ pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont0, pdf_resource_id(pres));
+ pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont, gs_no_id);
+ /* Set Encoding_name because we won't call attach_cmap_resource for it : */
+ code = pdf_write_OneByteIdentityH(pdev);
+ if (code < 0)
+ return 0;
+ pdfont->u.cidfont.CIDSystemInfo_id = pdev->IdentityCIDSystemInfo_id;
+ sprintf(pdfont0->u.type0.Encoding_name, "%ld 0 R", pdf_resource_id(pdev->OneByteIdentityH));
+ /* Move ToUnicode : */
+ pdfont0->res_ToUnicode = pdfont->res_ToUnicode; pdfont->res_ToUnicode = 0;
+ pdfont0->cmap_ToUnicode = pdfont->cmap_ToUnicode; pdfont->cmap_ToUnicode = 0;
+ /* Change the font type to CID font : */
+ pdfont->FontType = ft_CID_TrueType;
+ pdfont->write_contents = pdf_write_contents_cid2;
+ return 0;
+ }
}
}
}
@@ -1029,3 +1069,78 @@
{
return pdf_write_cmap(pdev, pcmap, ppres, font_index_only);
}
+
+static const char *OneByteIdentityH[] = {
+ "/CIDInit /ProcSet findresource begin",
+ "12 dict begin",
+ "begincmap",
+ "/CIDSystemInfo 3 dict dup begin",
+ "/Registry (Adobe) def",
+ "/Ordering (Identity) def",
+ "/Supplement 0 def",
+ "end def",
+ "/CMapName /OneByteIdentityH def",
+ "/CMapVersion 1.000 def",
+ "/CMapType 1 def",
+ "/UIDOffset 0 def",
+ "/XUID [1 10 25404 9999] def",
+ "/WMode 0 def",
+ "1 begincodespacerange",
+ "<00> <FF>",
+ "endcodespacerange",
+ "1 begincidrange",
+ "<00> <FF> 0",
+ "endcidrange",
+ "endcmap",
+ "CMapName currentdict /CMap defineresource pop",
+ "end",
+ "end",
+NULL};
+
+/*
+ * Write OneByteIdentityH CMap.
+ */
+int
+pdf_write_OneByteIdentityH(gx_device_pdf *pdev)
+{
+ int code, i;
+ pdf_data_writer_t writer;
+ cos_dict_t *pcd;
+ char buf[200];
+ static const gs_cid_system_info_t cidsi = {{(const byte *)"Adobe", 5}, {(const byte *)"Identity", 8}, 0};
+ long id;
+
+ if (pdev->IdentityCIDSystemInfo_id == gs_no_id) {
+ code = pdf_write_cid_systemInfo_separate(pdev, &cidsi, &id);
+ if (code < 0)
+ return code;
+ pdev->IdentityCIDSystemInfo_id = id;
+ }
+ if (pdev->OneByteIdentityH != NULL)
+ return 0;
+ code = pdf_begin_data_stream(pdev, &writer,
+ DATA_STREAM_NOT_BINARY |
+ /* Don't set DATA_STREAM_ENCRYPT since we write to a temporary file.
+ See comment in pdf_begin_encrypt. */
+ (pdev->CompressFonts ?
+ DATA_STREAM_COMPRESS : 0), gs_no_id);
+ if (code < 0)
+ return code;
+ pdev->OneByteIdentityH = writer.pres;
+ pcd = (cos_dict_t *)writer.pres->object;
+ code = cos_dict_put_c_key_string(pcd, "/CMapName", "/OneByteIdentityH", 17);
+ if (code < 0)
+ return code;
+ sprintf(buf, "%ld 0 R", pdev->IdentityCIDSystemInfo_id);
+ code = cos_dict_put_c_key_string(pcd, "/CIDSystemInfo", buf, strlen(buf));
+ if (code < 0)
+ return code;
+ code = cos_dict_put_string_copy(pcd, "/Type", "/CMap");
+ if (code < 0)
+ return code;
+ for (i = 0; OneByteIdentityH[i]; i++) {
+ stream_puts(pdev->strm, OneByteIdentityH[i]);
+ stream_putc(pdev->strm, '\n');
+ }
+ return pdf_end_data(&writer);
+}
Modified: trunk/gs/src/gdevpdtf.h
===================================================================
--- trunk/gs/src/gdevpdtf.h 2006-09-19 16:08:49 UTC (rev 7056)
+++ trunk/gs/src/gdevpdtf.h 2006-09-19 18:59:10 UTC (rev 7057)
@@ -440,7 +440,7 @@
/*
* Convert True Type font descriptor into CID font descriptor for PDF/A.
*/
-int pdf_convert_truetype_font_descriptor(gx_device_pdf *pdev, pdf_font_descriptor_t *pfd);
+int pdf_convert_truetype_font_descriptor(gx_device_pdf *pdev, pdf_font_resource_t *pdfont);
/* ---------------- CMap resources ---------------- */
@@ -450,6 +450,11 @@
int pdf_cmap_alloc(gx_device_pdf *pdev, const gs_cmap_t *pcmap,
pdf_resource_t **ppres /* CMap */, int font_index_only);
+/*
+ * Write OneByteIdentityH CMap.
+ */
+int pdf_write_OneByteIdentityH(gx_device_pdf *pdev);
+
/*
* Add a CID-to-GID mapping to a CIDFontType 2 font resource.
*/
Modified: trunk/gs/src/gdevpdtw.c
===================================================================
--- trunk/gs/src/gdevpdtw.c 2006-09-19 16:08:49 UTC (rev 7056)
+++ trunk/gs/src/gdevpdtw.c 2006-09-19 18:59:10 UTC (rev 7057)
@@ -507,7 +507,7 @@
int i;
pdf_begin_data_stream(pdev, &writer,
- DATA_STREAM_BINARY | DATA_STREAM_COMPRESS,
+ DATA_STREAM_BINARY | (pdev->CompressFonts ? DATA_STREAM_COMPRESS : 0),
/* Don't set DATA_STREAM_ENCRYPT since we write to a temporary file.
See comment in pdf_begin_encrypt. */
map_id);
More information about the gs-cvs
mailing list