[gs-cvs] gs/src

L. Peter Deutsch lpd at casper.ghostscript.com
Tue Apr 9 16:31:47 PDT 2002


Update of /cvs/ghostscript/gs/src
In directory casper:/tmp/cvs-serv14191/src

Modified Files:
	gdevpdff.c gxfont.h zchar1.c 
Log Message:

Restores some performance lost as a result of the fix for SourceForge
#495414, by skipping a request for glyph widths which is redundant if the
font doesn't have Metrics or CDevProc.  Addresses SourceForge #451456 (a
general request for better pdfwrite performance), which will be closed after
this change.


Index: gdevpdff.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevpdff.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- gdevpdff.c	21 Feb 2002 22:24:51 -0000	1.25
+++ gdevpdff.c	9 Apr 2002 23:31:44 -0000	1.26
@@ -1068,24 +1068,11 @@
 }
 
 /*
- * Get the widths (unmodified and possibly modified of a glyph in a (base)
+ * Get the widths (unmodified and possibly modified) of a glyph in a (base)
  * font.  Return 1 if the width was defaulted to MissingWidth.
  */
-private int
-store_glyph_width(int *pwidth, int wmode, double scale,
-		  const gs_glyph_info_t *pinfo)
-{
-    double w, v;
-
-    if (wmode && (w = pinfo->width[wmode].y) != 0)
-	v = pinfo->width[wmode].x;
-    else
-	w = pinfo->width[wmode].x, v = pinfo->width[wmode].y;
-    if (v != 0)
-	return_error(gs_error_rangecheck);
-    *pwidth = (int)(w * scale);
-    return 0;
-}
+private int store_glyph_width(int *pwidth, int wmode, double scale,
+			      const gs_glyph_info_t *pinfo);
 int
 pdf_glyph_widths(pdf_font_t *ppf, gs_glyph glyph, gs_font *font,
 		 pdf_glyph_widths_t *pwidths)
@@ -1104,9 +1091,14 @@
 				       GLYPH_INFO_OUTLINE_WIDTHS,
 				       &info)) >= 0 &&
 	(code = store_glyph_width(&pwidths->Width, wmode, scale, &info)) >= 0 &&
-	(code = font->procs.glyph_info(font, glyph, NULL,
-				       GLYPH_INFO_WIDTH0 << wmode,
-				       &info)) >= 0 &&
+	(/*
+	  * Only ask for modified widths if they are different, i.e.,
+	  * if GLYPH_INFO_OUTLINE_WIDTHS was set in the response.
+	  */
+	 (info.members & GLYPH_INFO_OUTLINE_WIDTHS) == 0 ||
+	 (code = font->procs.glyph_info(font, glyph, NULL,
+					GLYPH_INFO_WIDTH0 << wmode,
+					&info)) >= 0) &&
 	(code = store_glyph_width(&pwidths->real_width, wmode, scale, &info)) >= 0
 	) {
 	/*
@@ -1133,6 +1125,21 @@
 	 */
 	return 1;
     }
+}
+private int
+store_glyph_width(int *pwidth, int wmode, double scale,
+		  const gs_glyph_info_t *pinfo)
+{
+    double w, v;
+
+    if (wmode && (w = pinfo->width[wmode].y) != 0)
+	v = pinfo->width[wmode].x;
+    else
+	w = pinfo->width[wmode].x, v = pinfo->width[wmode].y;
+    if (v != 0)
+	return_error(gs_error_rangecheck);
+    *pwidth = (int)(w * scale);
+    return 0;
 }
 
 /*

Index: gxfont.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxfont.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- gxfont.h	29 Mar 2002 00:41:39 -0000	1.9
+++ gxfont.h	9 Apr 2002 23:31:44 -0000	1.10
@@ -110,15 +110,19 @@
 } gs_font_info_t;
 
 /*
- * Define the structure used to return information about a glyph.  Note that
- * a glyph may have two different sets of widths: those stored in the
- * outline (which includes hmtx for TrueType fonts), and those actually used
- * when rendering the glyph.  Currently, these differ only for Type 1 fonts
- * that use Metrics or CDevProc to change the widths.  The glyph_info
+ * Define the structure used to return information about a glyph.
+ *
+ * Note that a glyph may have two different sets of widths: those stored in
+ * the outline (which includes hmtx for TrueType fonts), and those actually
+ * used when rendering the glyph.  Currently, these differ only for Type 1
+ * fonts that use Metrics or CDevProc to change the widths.  The glyph_info
  * procedure normally returns the rendering widths: to get the outline
- * widths, clients use GLYPH_INFO_OUTLINE_WIDTHS.  (Fonts that don't
- * distinguish the two sets of widths don't need to do anything special, and
- * don't need to test for GLYPH_INFO_OUTLINE_WIDTHS.)
+ * widths, clients use GLYPH_INFO_OUTLINE_WIDTHS.  The glyph_info procedure
+ * should set GLYPH_INFO_OUTLINE_WIDTHS in the response (the `members' in
+ * the gs_glyph_info_t structure) iff it was set in the request *and* the
+ * glyph actually has two different sets of widths.  With this arrangement,
+ * fonts that don't distinguish the two sets of widths don't need to do
+ * anything special, and don't need to test for GLYPH_INFO_OUTLINE_WIDTHS.
  */
 typedef struct gs_glyph_info_s {
     int members;		/* mask of which members are valid */

Index: zchar1.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/zchar1.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- zchar1.c	21 Feb 2002 22:24:54 -0000	1.11
+++ zchar1.c	9 Apr 2002 23:31:44 -0000	1.12
@@ -1016,18 +1016,19 @@
     const ref *pfdict = &pfont_data(pbfont)->dict;
     double sbw[4];
     int width_members = members & (GLYPH_INFO_WIDTH0 << wmode);
-    int default_members = members - width_members;
+    int outline_widths = members & GLYPH_INFO_OUTLINE_WIDTHS;
+    bool modified_widths = false;
+    int default_members = members - (width_members + outline_widths);
     int done_members = 0;
     int code;
 
-    if (!width_members || (members & GLYPH_INFO_OUTLINE_WIDTHS))
+    if (!width_members)
 	return gs_type1_glyph_info(font, glyph, pmat, members, info);
-    if (dict_find_string(pfdict, "CDevProc", &pcdevproc) > 0)
-	return_error(e_rangecheck); /* can't handle it */
     glyph_ref(glyph, &gref);
     if (width_members == GLYPH_INFO_WIDTH1) {
 	code = zchar_get_metrics2(pbfont, &gref, sbw);
 	if (code > 0) {
+	    modified_widths = true;
 	    info->width[1].x = sbw[2];
 	    info->width[1].y = sbw[3];
 	    done_members = width_members;
@@ -1037,11 +1038,23 @@
     if (width_members) {
 	code = zchar_get_metrics(pbfont, &gref, sbw);
 	if (code > 0) {
+	    modified_widths = true;
 	    info->width[wmode].x = sbw[2];
 	    info->width[wmode].y = sbw[3];
 	    done_members = width_members;
 	    width_members = 0;
 	}
+    }
+
+    if (outline_widths) {
+	if (modified_widths || dict_find_string(pfdict, "CDevProc", &pcdevproc) > 0) {
+	    /* Discard the modified widths, but indicate they exist. */
+	    width_members |= done_members;
+	    done_members = outline_widths;
+	}
+    } else {
+	if (dict_find_string(pfdict, "CDevProc", &pcdevproc) > 0)
+	    return_error(e_rangecheck); /* can't handle it */
     }
     default_members |= width_members;
     if (default_members) {




More information about the gs-cvs mailing list