Author: ken
Date: 2008-03-20 03:20:17 -0700 (Thu, 20 Mar 2008)
New Revision: 8603

Modified:
   trunk/gs/src/gdevpdtf.c
   trunk/gs/src/gdevpdtt.c
   trunk/gs/src/gdevpsft.c
   trunk/gs/src/gstype42.c
   trunk/gs/src/gxfont.h
   trunk/gs/src/gxfont42.h
   trunk/gs/src/zfont.c
Log:
Fix (pdfwrite): pdfwrite embedded TrueType/Type 42 fonts which
specifically forbid embedding.

Details:
Bug #689693 "GS embeds licensed fonts when generating PDF".

For Type 42 fonts, in order to prevent embedding fonts with license
restrictions we need to retrieve and honour the /FSType key if present
in the FontInfo dictionary of the font.

We also need to check the embedding status of TrueType fonts read from disk
in a similar fashion to Type 42 fonts downloaded in the course of the job.

Finally, when writing a TrueType font to a PDF file, we need to preserve any
existing embedding rights by setting fstype appropriately in the OS/2 table.
It is possible to permit font embedding even when the embedding rights
are non zero and we should preserve these.

(gxfont.h) Add a new parameter, EmbeddingRights, and a new flag
	     FONT_INFO_EMBEDDING_RIGHTS, to the gs_font_info structure.

(zfont.c) In zfont_info, if we request the EmbeddingRights, and the font has
          a FontInfo dictionary, retrieve the FSType if present.

(gdevdtf.c) When determining whether a font may be embedded, retrieve the
          font info, check the 'members' structure member after retrieving font info
          to see if the EmbeddingRights member has been updated. Assume embedding
          allowed if the member has not been updated.

(gxfont42.h) Add a new member os2_offset to the gs_type42_data structure, to allow
           us to read from the OS/2 table later.

(gstype42.c) In gs_type42_font_init, when reading the TrueType Table directory, store
           the offset to the OS/2 table.

           In gs_truetype_font_info, if the caller has requested the embedding rights
           and they haven't already been retrieved from an FSType entry in the
           FontInfo dictionary, get the OS/2 table and pull the fstype value from there.

(gdevpsft.c) When writing a TrueType font, and we don't have an OS/2 table to
             copy (appears to always be the case), check to see if we have any
             embedding rights information in the original font, and preserve it if so
             by setting the fstype entry in the OS/2 table.

EXPECTED DIFFERENCES:
None.


Modified: trunk/gs/src/gdevpdtf.c
===================================================================
--- trunk/gs/src/gdevpdtf.c	2008-03-19 10:09:21 UTC (rev 8602)
+++ trunk/gs/src/gdevpdtf.c	2008-03-20 10:20:17 UTC (rev 8603)
@@ -662,7 +662,33 @@
     int index = pdf_find_standard_font_name(chars, size);
     bool embed_as_standard_called = false;
     bool do_embed_as_standard = false; /* Quiet compiler. */
+    int code;
+    gs_font_info_t info;
 
+    memset(&info, 0x00, sizeof(gs_font_info_t));
+    code = font->procs.font_info(font, NULL, FONT_INFO_EMBEDDING_RIGHTS, &info);
+    if (code == 0 && (info.members & FONT_INFO_EMBEDDING_RIGHTS)) {
+	if ((info.EmbeddingRights == 0x0002) || (info.EmbeddingRights & 0x0200)) {
+	    /* See the OpenType specification, "The 'OS/2' and Windows Metrics Table" for details
+	       of the fstype parameter. This is a bitfield, currently we forbid embedding of fonts
+	       with these bits set:
+	       bit 1	0x0002	Fonts that have only this bit set must not be modified, embedded or
+				exchanged in any manner.
+	       bit 9	0x0200	Bitmap embedding only.
+
+	       Note for Restricted License embedding (bit 1), this must be the only level of embedding 
+	       selected (see the OpenType spec).
+             */
+	    char name[gs_font_name_max + 1];
+	    int len;
+
+	    len = min(gs_font_name_max, font->font_name.size);
+	    memcpy(name, font->font_name.chars, len);
+	    name[len] = 0;
+	    eprintf1("\nWarning: %s cannot be embedded because of licensing restrictions\n", name);
+	    return FONT_EMBED_NO;
+	}
+    }
     /*
      * The behavior of Acrobat Distiller changed between 3.0 (PDF 1.2),
      * which will never embed the base 14 fonts, and 4.0 (PDF 1.3), which

Modified: trunk/gs/src/gdevpdtt.c
===================================================================
--- trunk/gs/src/gdevpdtt.c	2008-03-19 10:09:21 UTC (rev 8602)
+++ trunk/gs/src/gdevpdtt.c	2008-03-20 10:20:17 UTC (rev 8603)
@@ -2443,7 +2443,7 @@
 		len = min(gs_font_name_max, gnstr.size);
 		memcpy(glyph, gnstr.data, len);
 		glyph[len] = 0x00;
-		len = min(255, penum->current_font->font_name.size);
+		len = min(gs_font_name_max, penum->current_font->font_name.size);
 		memcpy(FontName, penum->current_font->font_name.chars, len);
 		FontName[len] = 0x00;
 		len = min(255, penum->current_font->key_name.size);

Modified: trunk/gs/src/gdevpsft.c
===================================================================
--- trunk/gs/src/gdevpsft.c	2008-03-19 10:09:21 UTC (rev 8602)
+++ trunk/gs/src/gdevpsft.c	2008-03-20 10:20:17 UTC (rev 8603)
@@ -494,6 +494,8 @@
 write_OS_2(stream *s, gs_font *font, uint first_glyph, int num_glyphs)
 {
     ttf_OS_2_t os2;
+    gs_font_info_t info;
+    int code;
 
     /*
      * We don't bother to set most of the fields.  The really important
@@ -507,6 +509,17 @@
     put_u16(os2.usWeightClass, 400); /* Normal */
     put_u16(os2.usWidthClass, 5); /* Normal */
     update_OS_2(&os2, first_glyph, num_glyphs);
+
+    /*
+     * We should also preserve the licensed embedding rights, to prevent
+     * 'laundering' a TrueType font. These can be non-zero even when embedding is permitted.
+     */
+    memset(&info, 0x00, sizeof(gs_font_info_t));
+    code = font->procs.font_info(font, NULL, FONT_INFO_EMBEDDING_RIGHTS, &info);
+    if (code == 0 && (info.members & FONT_INFO_EMBEDDING_RIGHTS)) {
+	put_u16(os2.fsType, info.EmbeddingRights);
+    }
+
     stream_write(s, &os2, offset_of(ttf_OS_2_t, sxHeight[0]));
     put_pad(s, offset_of(ttf_OS_2_t, sxHeight[0]));
 }

Modified: trunk/gs/src/gstype42.c
===================================================================
--- trunk/gs/src/gstype42.c	2008-03-19 10:09:21 UTC (rev 8602)
+++ trunk/gs/src/gstype42.c	2008-03-20 10:20:17 UTC (rev 8603)
@@ -223,6 +223,8 @@
 	} else if (!memcmp(tab, "vmtx", 4)) {
 	    pfont->data.metrics[1].offset = offset;
 	    pfont->data.metrics[1].length = (uint)u32(tab + 12);
+	} else if (!memcmp(tab, "OS/2", 4)) {
+	    pfont->data.os2_offset = offset;
 	}
     }
     loca_size >>= pfont->data.indexToLocFormat + 1;
@@ -1294,6 +1296,16 @@
     gs_font_type42 *pfont = (gs_font_type42 *)font;
     int code;
 
+    if (!(info->members & FONT_INFO_EMBEDDING_RIGHTS) && (members & FONT_INFO_EMBEDDING_RIGHTS)) {
+	if(pfont->data.os2_offset != 0) {
+	    int (*string_proc)(gs_font_type42 *, ulong, uint, const byte **) = pfont->data.string_proc;
+	    unsigned char fstype[2];
+
+	    READ_SFNTS(pfont, pfont->data.os2_offset + 8, 2, fstype);
+    	    info->EmbeddingRights = U16(fstype);
+    	    info->members |= FONT_INFO_EMBEDDING_RIGHTS;
+	}
+    }
     if (pfont->data.name_offset == 0)
 	return 0;
     if (!(info->members & FONT_INFO_COPYRIGHT) && (members & FONT_INFO_COPYRIGHT)) {
@@ -1311,6 +1323,7 @@
 	if (code < 0)
 	    return code;
     }
+
     return 0;
 }
 

Modified: trunk/gs/src/gxfont.h
===================================================================
--- trunk/gs/src/gxfont.h	2008-03-19 10:09:21 UTC (rev 8602)
+++ trunk/gs/src/gxfont.h	2008-03-20 10:20:17 UTC (rev 8603)
@@ -108,7 +108,8 @@
     gs_const_string FamilyName;
 #define FONT_INFO_FULL_NAME 0x2000
     gs_const_string FullName;
-
+#define FONT_INFO_EMBEDDING_RIGHTS 0x4000
+    int EmbeddingRights;
 } gs_font_info_t;
 
 #define public_st_gs_font_info() /* in gsfont.c */\

Modified: trunk/gs/src/gxfont42.h
===================================================================
--- trunk/gs/src/gxfont42.h	2008-03-19 10:09:21 UTC (rev 8602)
+++ trunk/gs/src/gxfont42.h	2008-03-20 10:20:17 UTC (rev 8603)
@@ -85,6 +85,7 @@
     gs_type42_mtx_t metrics[2];	/* hhea/hmtx, vhea/vmtx (indexed by WMode) */
     ulong loca;			/* offset to loca table */
     ulong name_offset;		/* offset to name table */		
+    ulong os2_offset;		/* offset to OS/2 table */		
     /*
      * TrueType fonts specify the number of glyphs in two different ways:
      * the size of the loca table, and an explicit value in maxp.  Currently

Modified: trunk/gs/src/zfont.c
===================================================================
--- trunk/gs/src/zfont.c	2008-03-19 10:09:21 UTC (rev 8602)
+++ trunk/gs/src/zfont.c	2008-03-20 10:20:17 UTC (rev 8603)
@@ -589,7 +589,7 @@
 		      FONT_INFO_FAMILY_NAME | FONT_INFO_FULL_NAME),
 				    info);
     const ref *pfdict;
-    ref *pfontinfo;
+    ref *pfontinfo, *pvalue;
 
     if (code < 0)
 	return code;
@@ -609,6 +609,11 @@
     if ((members & FONT_INFO_FULL_NAME) &&
 	zfont_info_has(pfontinfo, "FullName", &info->FullName))
 	info->members |= FONT_INFO_FULL_NAME;
+    if ((members & FONT_INFO_EMBEDDING_RIGHTS) 
+	&& (dict_find_string(pfontinfo, "FSType", &pvalue) > 0)) {
+	info->EmbeddingRights = pvalue->value.intval;
+	info->members |= FONT_INFO_EMBEDDING_RIGHTS;
+    }
     return code;
 }
 

_______________________________________________
gs-cvs mailing list
gs-cvs@ghostscript.com
http://www.ghostscript.com/mailman/listinfo/gs-cvs
