libgnomeprint r2291 - in trunk: . libgnomeprint



Author: kmaraas
Date: Sat Feb  2 19:24:24 2008
New Revision: 2291
URL: http://svn.gnome.org/viewvc/libgnomeprint?rev=2291&view=rev

Log:
2007-02-13  Suresh Chandrasekharan <suresh chandrasekharan sun com>
	
	Fix for bugzilla # 407648 "PDF output does not support searching"

	* libgnomeprint/gnome-print-pdf-private.h: gnome_print_embed_pdf_font
	  added an additional glyph2unicode parameter for passing the 
	  glyph-id to unicode mapping array. A new private function
	  gnome_print_pdf_font_tounicode is also defined, which outputs
	  "ToUnicode" mapping for a subsetted TrueType font.

	* libgnomeprint/gnome-print-pdf-tt.c: 
	  (gnome_print_pdf_ttsubset_low_glyph_bound): New static function for
	  calculating the lower glyph bound in an array is defined.

	  (gnome_print_pdf_tt_subset_embed): Changed to call 
	  gnome_print_pdf_ttsubset_low_glyph_bound

	  (gnome_print_pdf_font_tounicode): New function for output
	  ToUnicode charmap for a subsetted font.

	* libgnomeprint/gnome-print-pdf.c: 
	  (subsetfontname_cmp): New sort function defined for sorting the
	  subsetted fonts based on psnames.

	  (gnome_print_embed_all_pdf_fonts): Changed to define glyph2unicode
	  array, which is created only once for all the subfonts of a 
	  masterfont. The pdf font embedding order is changed based on
	  the masterfont so that we don't have to do the expensive
	  for loop for all subfonts.

	  (gnome_print_embed_pdf_font): Call gnome_print_pdf_font_tounicode
	  is subsetting is happening, use the returned objet_number as the
	  the ToUnicode object number.

Modified:
   trunk/ChangeLog
   trunk/libgnomeprint/gnome-print-pdf-private.h
   trunk/libgnomeprint/gnome-print-pdf-tt.c
   trunk/libgnomeprint/gnome-print-pdf.c

Modified: trunk/libgnomeprint/gnome-print-pdf-private.h
==============================================================================
--- trunk/libgnomeprint/gnome-print-pdf-private.h	(original)
+++ trunk/libgnomeprint/gnome-print-pdf-private.h	Sat Feb  2 19:24:24 2008
@@ -65,11 +65,11 @@
 gint gnome_print_pdf_object_end   (GnomePrintPdf *pdf, gint object_number, gboolean dont_print);
 
 /* Type 1 & TrueType embed */
-void gnome_print_embed_pdf_font  (GnomePrintPdf *pdf, GnomePrintPdfFont *font);
+void gnome_print_embed_pdf_font  (GnomePrintPdf *pdf, GnomePrintPdfFont *font, gint *glyph2unicode);
 gint gnome_print_pdf_t1_embed (GnomePrintPdf *pdf, const guchar *file_name, gint *object_number);
 gint gnome_print_pdf_tt_embed (GnomePrintPdf *pdf, const guchar *file_name, gint *object_number);
 gint gnome_print_pdf_tt_subset_embed (GnomePrintPdf *pdf, GnomePrintPdfFont *font, const guchar *file_name, gint *object_number);
-
+void gnome_print_pdf_font_tounicode (GnomePrintPdf *pdf, GnomePrintPdfFont *font, gint *glyph2unicode, gint *object_number_descriptor_ret);
 
 G_END_DECLS
 

Modified: trunk/libgnomeprint/gnome-print-pdf-tt.c
==============================================================================
--- trunk/libgnomeprint/gnome-print-pdf-tt.c	(original)
+++ trunk/libgnomeprint/gnome-print-pdf-tt.c	Sat Feb  2 19:24:24 2008
@@ -39,6 +39,21 @@
 
 #define PSO_GLYPH_MARKED(pso,g) (pso->glyphs[(g) >> 5] & (1 << ((g) & 0x1f)))
 
+static gint
+gnome_print_pdf_ttsubset_low_glyph_bound (guchar *subsetfontname)
+{
+	gint len, lower;
+
+	len = subsetfontname ? strlen (subsetfontname) : 0;
+
+	if (len > 4)
+		lower = *(subsetfontname + len - 4) == '_' ? atoi (subsetfontname + len - 3) : 0;
+	else
+		lower = 0;
+
+	return (lower*255);
+}
+
 gint
 gnome_print_pdf_tt_subset_embed (GnomePrintPdf *pdf,
 			  GnomePrintPdfFont *font,
@@ -47,26 +62,17 @@
 	GnomePrintBuffer b;
 	GnomePrintReturnCode retval = GNOME_PRINT_ERROR_UNKNOWN;
 	GnomeFontPsObject *pso = font->pso;
-	gint i, j, k, lower, upper, nglyphs, len, code_glyph;
+	gint i, j, k, lower, upper, nglyphs, code_glyph;
 	guchar *subfont_file = NULL;
 	gushort glyphArray[256];
         guchar encoding[256];
 
 	nglyphs = pso->face->num_glyphs;
 
-	len = pso->encodedname ? strlen (pso->encodedname) : 0;
-
-	if (len > 4)
-		lower = *(pso->encodedname + len - 4) == '_' ? atoi (pso->encodedname + len - 3) : 0;
-	else
-		lower = 0;
-
-	upper = lower + 1;
+	lower = gnome_print_pdf_ttsubset_low_glyph_bound (pso->encodedname);
+	upper = lower + 255;
 
 	k = 1;
-	lower *= 255;
-	upper *= 255;
-
 	font->code_to_glyph [0] = 0;
 	glyphArray[0] = encoding[0] = 0;
 
@@ -126,3 +132,102 @@
 
 	return retval;
 }	
+
+void
+gnome_print_pdf_font_tounicode (GnomePrintPdf *pdf, GnomePrintPdfFont *font,
+				        gint *glyph2unicode,
+					gint *object_number_descriptor_ret)
+{
+	GnomeFontPsObject *pso = font->pso;
+	gint length_object_num, object_number_descriptor;
+	gint nglyphs, len = 0, lower, upper, mapped_nos = 0;
+	gint i, j, k, uni;
+	gchar buf[48];
+
+	nglyphs = pso->face->num_glyphs;
+	memset(buf, 0, sizeof(buf)/sizeof(buf[0]));
+
+	object_number_descriptor = gnome_print_pdf_object_new (pdf);
+	*object_number_descriptor_ret = object_number_descriptor;
+
+	gnome_print_pdf_object_start (pdf, object_number_descriptor, TRUE);
+	gnome_print_pdf_fprintf (pdf,
+				 "%d 0 obj" EOL,
+				 object_number_descriptor);
+
+        length_object_num = gnome_print_pdf_object_new (pdf);
+        gnome_print_pdf_fprintf (pdf, "<<" EOL);
+        gnome_print_pdf_fprintf (pdf, "/Length %d 0 R" EOL, length_object_num);
+        gnome_print_pdf_fprintf (pdf, ">>" EOL);
+        gnome_print_pdf_fprintf (pdf, "stream" EOL);
+
+	len += gnome_print_pdf_fprintf (pdf,
+			     "/CIDInit /ProcSet findresource begin" EOL
+			     "12 dict begin" EOL
+			     "begincmap" EOL
+			     "/CIDSystemInfo" EOL
+			     "<< /Registry (Adobe)" EOL
+			     "/Ordering (UCS)" EOL
+			     "/Supplement 0" EOL
+			     ">> def" EOL
+			     "/CMapName /Adobe-Identity-UCS def" EOL
+			     "/CMapType 2 def" EOL
+			     "1 begincodespacerange" EOL
+			     "<00> <FFFF>" EOL
+			     "endcodespacerange" EOL
+			     );
+
+	lower = gnome_print_pdf_ttsubset_low_glyph_bound (pso->encodedname);
+	upper = lower + 255;
+
+	for ( j = lower; j < upper && j < nglyphs; j++) {
+		if (PSO_GLYPH_MARKED(pso, j)) {
+			mapped_nos++;
+		}
+	}
+
+	i = k = 0;
+
+	for ( j = lower; j < upper && j < nglyphs; j++) {
+		if (PSO_GLYPH_MARKED(pso, j)) {
+			if ((i % 100) == 0) {
+				if (i)
+					len += gnome_print_pdf_fprintf (pdf,
+						"endbfchar" EOL
+						);
+				len += gnome_print_pdf_fprintf (pdf,"%d", (mapped_nos-i > 100) ? 100 : mapped_nos-i);
+				len += gnome_print_pdf_fprintf (pdf," beginbfchar" EOL);
+			}
+
+			uni = glyph2unicode[j];
+			if (uni) {
+				sprintf(buf,  "<%02x>  <%02x%02x>", k+1, uni/256, uni&255);
+			} else {
+				sprintf(buf,  "<%02x>  <fffd>", k+1);
+			}
+			len += gnome_print_pdf_fprintf (pdf, "%s" EOL, buf);
+			i++;
+		}
+		k++;
+	}
+	len += gnome_print_pdf_fprintf (pdf,
+    			"endbfchar" EOL
+                      	"endcmap" EOL
+                      	"CMapName currentdict /CMap defineresource pop" EOL
+                      	"end" EOL
+                      	"end" EOL 
+			);
+
+
+	gnome_print_pdf_fprintf (pdf,  "endstream" EOL);
+	gnome_print_pdf_object_end   (pdf, object_number_descriptor, TRUE);
+	gnome_print_pdf_fprintf (pdf,  "endobj" EOL);
+
+	gnome_print_pdf_object_start (pdf, length_object_num, TRUE);
+	gnome_print_pdf_fprintf (pdf,
+				 "%d 0 obj" EOL
+				 "%d" EOL
+				 "endobj" EOL,
+				 length_object_num, len);
+	gnome_print_pdf_object_end (pdf, length_object_num, TRUE);
+}

Modified: trunk/libgnomeprint/gnome-print-pdf.c
==============================================================================
--- trunk/libgnomeprint/gnome-print-pdf.c	(original)
+++ trunk/libgnomeprint/gnome-print-pdf.c	Sat Feb  2 19:24:24 2008
@@ -1345,22 +1345,57 @@
 	return ret;
 }
 
+static int 
+subsetfontname_cmp (gconstpointer a, gconstpointer b)
+{
+	GnomeFontFace *face_a = ((GnomePrintPdfFont *) a)->face;
+	GnomeFontFace *face_b = ((GnomePrintPdfFont *) b)->face;
+
+	return strcmp((const char *)face_a->psname, (const char *)face_b->psname);
+}
+
+#define UCS2_UPPER_BOUND 0xFFFF
+ 
 static void
 gnome_print_embed_all_pdf_fonts (GnomePrintPdf *pdf)
 {
-	GList *list;
+	GList *list, *prev_list = NULL, *copy_list;
+	gint *glyph2unicode;
 
 	g_return_if_fail (pdf != NULL);
+	
+	glyph2unicode = (gint *) calloc (UCS2_UPPER_BOUND, sizeof(gint));
+
+	copy_list = list = g_list_copy ((GList *)pdf->fonts);
+
+	list = g_list_sort (list, subsetfontname_cmp);
 
-	list = pdf->fonts;
 	while (list) {
+		gint font_change = 1;
 		GnomePrintPdfFont *font;
+
 		font = list->data;
-		gnome_print_embed_pdf_font (pdf, font);
+
+		if (prev_list)
+			font_change = subsetfontname_cmp (prev_list->data, list->data);
+		if (font_change && font && font->face && font->face->ft_face) {
+			int i;
+			for(i = 0; i < UCS2_UPPER_BOUND; i++) {
+				int glyph = FT_Get_Char_Index (font->face->ft_face, i);
+				glyph2unicode[glyph] = i;
+			}
+		}
+		gnome_print_embed_pdf_font (pdf, font, glyph2unicode);
+		prev_list = list;
 		list = list->next;
 	}
+
+	g_list_free (copy_list);
+
+	free (glyph2unicode);
 }
 
+#undef UCS2_UPPER_BOUND
 
 static gint
 gnome_print_pdf_close (GnomePrintContext *pc)
@@ -1778,9 +1813,10 @@
 }
 
 void
-gnome_print_embed_pdf_font (GnomePrintPdf *pdf, GnomePrintPdfFont *font)
+gnome_print_embed_pdf_font (GnomePrintPdf *pdf, GnomePrintPdfFont *font, gint *glyph2unicode)
 {
 	gint object_number_descriptor = 0;
+	gint object_number_tounicode = 0;
 	guchar *basefont_name;
 	gboolean plan_b = FALSE; /* TRUE if we could not embed the font */
 
@@ -1793,7 +1829,11 @@
 				   gnome_font_face_get_ps_name (font->face));
 			plan_b = TRUE;
 			font->is_type_1 = TRUE; /* It isn't, but the substitute is */
-		}
+		} 
+
+		if (NEEDED_SUBSETTING(font))
+			gnome_print_pdf_font_tounicode (pdf, font, glyph2unicode, &object_number_tounicode);
+		
 	}
 
 	basefont_name = gnome_print_pdf_get_subfont_name ((guchar *)gnome_font_face_get_ps_name (font->face), font->object_number);
@@ -1828,6 +1868,12 @@
 					  object_number_descriptor);
 	}
 
+	if (NEEDED_SUBSETTING(font)) {
+		gnome_print_pdf_fprintf (pdf, 
+					"/ToUnicode %d 0 R" EOL, 
+					object_number_tounicode);
+	}
+
 	gnome_print_pdf_object_end   (pdf, font->object_number, FALSE);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]