[gs-cvs] rev 7567 - in trunk/gs: doc src

leonardo at ghostscript.com leonardo at ghostscript.com
Fri Jan 5 12:44:22 PST 2007


Author: leonardo
Date: 2007-01-05 12:44:21 -0800 (Fri, 05 Jan 2007)
New Revision: 7567

Modified:
   trunk/gs/doc/pscet_status.txt
   trunk/gs/src/gstype42.c
   trunk/gs/src/gxfcid.h
   trunk/gs/src/gxfont42.h
   trunk/gs/src/zchar42.c
Log:
Fix (True Type renderer) : Account glyph bbox when setting up the cache device.

DETAILS :

Debugged with CET 34_all.PS page 4.
An embedded True Type font has an incorrect FontBBox :
parts of glyphs appear outside it. Uniting it with
glyph bbox helps. However using glyph bbox only
doesn't work for Dynalab fonts, so this change includes
a voluntary solution which unites FontBBox and glyph bbox.

This patch slightly change the prototypes of 
gs_type42_data_s::get_outline and gs_font_cid2_data_s::get_outline,
and their implementations. We believe that this change
must be compatible, except a case of a wrong walue was passed 
to 'wmode' argument. The PCL group must check that 
it never pass other values than 0 or 1.
In the new code the 'wmode' argument is replaced
with options enum, and other values require a bigger
array for the last argument. See commenmts in code
and the extended implementation in gs_type42_default_get_metrics.

The function zchar42_set_cache has been re4written 
to simplify its understanding. Now it accounts
the glyph bbox. We noticed that the old code 
with WMode 1 set 'w' equal to horizontal width,
which looks incorrect. The new code sets the vertical width.
Also the old code did an unuseful call to get_metrics
when WMode=1 and the vertical metric presents in the font.

The function gs_type42_default_get_metrics has been removed
due to low use. The new code replaces it with pfont->data.get_metrics.
We didn't find calls to it from the PCL code.

EXPECTED DIFFERENCES :

"Bug687698.ps" - proigression (A glyph was truncated).


Modified: trunk/gs/doc/pscet_status.txt
===================================================================
--- trunk/gs/doc/pscet_status.txt	2007-01-05 05:19:34 UTC (rev 7566)
+++ trunk/gs/doc/pscet_status.txt	2007-01-05 20:44:21 UTC (rev 7567)
@@ -5327,38 +5327,13 @@
 
 34_all-3  OK	Minor differences visually reviewed by RJJ
 
-34_all-4  DIFF	Truncated glyphs. 
-		Analyzed by Igor.
-		A simplified test case is placed to 
-		peeves:/home/igor/pscet/mytests/34_all-4-Igor01.PS 
-		- it paints a single glyph.
-		The embedded TrueType CID font named CID_TTF
-		has an incorrect FontBBox [ 0 0 1 1 ].
-		Some glyphs are defined with negative coordinated.
-		PLRM defines an undefined result for this case.
-		A right rendering may be obtained with -dNOCACHE .
-		.
-		Rather improving Ghostscript for this case would be useful,
-		the improvement is pretty hard. One idea is to delay the cache
-		device bitmap bufer allocation until the 
-		outline is generated and its bbox is known.
-		I mean to install the cache device as usual
-		(because the outliner needs its parameters such as alpha),
-		and delay the bitmap allocation.
-		It would also simplify the type 1,2 
-		rendering due to dropping nobbox_finish.
-		By another hand, we never meet such case
-		with Type 42 in practice,
-		so CET test looks far-fetched.
-		.
-		Passing to Ray to decide what to do with it.
-		Assign: Ray.
+34_all-4  OK
 		                                               	
 34_all-5  DIFF	Same as 33_all-6. Assign: Alex.
 
 34_all-6  AOK	GS has more CMap resources. Not important. Analyzed by Igor.
 
-34_all-7  DIFF	Same as 34_all-4 Assign: Ray.
+34_all-7  OK
 
 35_all-1  DIFF	Same as 34_all-1. Assign: Ray
 

Modified: trunk/gs/src/gstype42.c
===================================================================
--- trunk/gs/src/gstype42.c	2007-01-05 05:19:34 UTC (rev 7566)
+++ trunk/gs/src/gstype42.c	2007-01-05 20:44:21 UTC (rev 7567)
@@ -650,7 +650,7 @@
 	    if (members & (GLYPH_INFO_WIDTH0 << i)) {
 		float sbw[4];
 
-		code = gs_type42_wmode_metrics(pfont, glyph_index, i, sbw);
+		code = pfont->data.get_metrics(pfont, glyph_index, i, sbw);
 		if (code < 0) {
 		    code = 0;
 		    continue;
@@ -772,53 +772,69 @@
     return 0;
 }
 
-/* Get the metrics of a glyph. */
+/* Export the default get_metrics procedure. 
+   The length of sbw is >=4 when bbox in not requested,
+   and 8 otherwise.
+ */
 int
 gs_type42_default_get_metrics(gs_font_type42 * pfont, uint glyph_index,
-			      int wmode, float sbw[4])
+			      gs_type42_metrics_options_t options, float sbw[4])
 {
     gs_glyph_data_t glyph_data;
     int code;
-    int result;
+    int result = 0;
+    int wmode = gs_type42_metrics_options_wmode(options);
+    int sbw_requested  = gs_type42_metrics_options_sbw_requested(options);
+    int bbox_requested = gs_type42_metrics_options_bbox_requested(options);
 
     glyph_data.memory = pfont->memory;
     code = pfont->data.get_outline(pfont, glyph_index, &glyph_data);
     if (code < 0)
 	return code;
-    if (glyph_data.bits.size != 0 && S16(glyph_data.bits.data) == -1) {
-	/* This is a composite glyph. */
-	uint flags;
-	const byte *gdata = glyph_data.bits.data + 10;
-	gs_matrix_fixed mat;
+    if (bbox_requested) {
+	if (glyph_data.bits.size >= 10 && bbox_requested) {
+	    /* Note: The glyph bbox usn't useful for Dynalab fonts,
+	       which stretch subglyphs. Therefore we don't 
+	       process subglyphs here. */
+	    double factor = 1.0 / pfont->data.unitsPerEm;
 
-	memset(&mat, 0, sizeof(mat)); /* arbitrary */
-	do {
-	    uint comp_index = U16(gdata + 2);
+	    sbw[4] = S16(glyph_data.bits.data + 2) * factor;
+	    sbw[5] = S16(glyph_data.bits.data + 4) * factor;
+	    sbw[6] = S16(glyph_data.bits.data + 6) * factor;
+	    sbw[7] = S16(glyph_data.bits.data + 8) * factor;
+	} else
+	    sbw[4] = sbw[5] = sbw[6] = sbw[7] = 0;
+    }
+    if (sbw_requested) {
+	if (glyph_data.bits.size != 0 && S16(glyph_data.bits.data) == -1) {
+	    /* This is a composite glyph. */
+	    uint flags;
+	    const byte *gdata = glyph_data.bits.data + 10;
+	    gs_matrix_fixed mat;
 
-	    parse_component(&gdata, &flags, &mat, NULL, pfont, &mat);
-	    if (flags & TT_CG_USE_MY_METRICS) {
-		result = gs_type42_wmode_metrics(pfont, comp_index, wmode, sbw);
-		goto done;
+	    memset(&mat, 0, sizeof(mat)); /* arbitrary */
+	    do {
+		uint comp_index = U16(gdata + 2);
+
+		parse_component(&gdata, &flags, &mat, NULL, pfont, &mat);
+		if (flags & TT_CG_USE_MY_METRICS) {
+		    result = pfont->data.get_metrics(pfont, comp_index, wmode, sbw);
+		    goto done;
+		}
 	    }
+	    while (flags & TT_CG_MORE_COMPONENTS);
 	}
-	while (flags & TT_CG_MORE_COMPONENTS);
+	result = simple_glyph_metrics(pfont, glyph_index, wmode, sbw);
     }
-    result = simple_glyph_metrics(pfont, glyph_index, wmode, sbw);
  done:
     gs_glyph_data_free(&glyph_data, "gs_type42_default_get_metrics");
     return result;
 }
 int
-gs_type42_wmode_metrics(gs_font_type42 * pfont, uint glyph_index, int wmode,
-			float sbw[4])
-{
-    return pfont->data.get_metrics(pfont, glyph_index, wmode, sbw);
-}
-int
 gs_type42_get_metrics(gs_font_type42 * pfont, uint glyph_index,
 		      float sbw[4])
 {
-    return gs_type42_wmode_metrics(pfont, glyph_index, pfont->WMode, sbw);
+    return pfont->data.get_metrics(pfont, glyph_index, pfont->WMode, sbw);
 }
 
 /* Define the bits in the glyph flags. */

Modified: trunk/gs/src/gxfcid.h
===================================================================
--- trunk/gs/src/gxfcid.h	2007-01-05 05:19:34 UTC (rev 7566)
+++ trunk/gs/src/gxfcid.h	2007-01-05 20:44:21 UTC (rev 7567)
@@ -127,7 +127,8 @@
      */
     struct o_ {
 	int (*get_outline)(gs_font_type42 *, uint, gs_glyph_data_t *);
-	int (*get_metrics)(gs_font_type42 *, uint, int, float [4]);
+	int (*get_metrics)(gs_font_type42 *, uint, gs_type42_metrics_options_t, 
+		float * /* See comment for gs_type42_default_get_metrics. */);
     } orig_procs;
 } gs_font_cid2_data;
 struct gs_font_cid2_s {

Modified: trunk/gs/src/gxfont42.h
===================================================================
--- trunk/gs/src/gxfont42.h	2007-01-05 05:19:34 UTC (rev 7566)
+++ trunk/gs/src/gxfont42.h	2007-01-05 20:44:21 UTC (rev 7567)
@@ -36,6 +36,26 @@
 #  define gs_font_type42_DEFINED
 typedef struct gs_font_type42_s gs_font_type42;
 #endif
+
+
+typedef enum gs_type42_metrics_options_s {
+    gs_type42_metrics_options_WMODE0 = 0,
+    gs_type42_metrics_options_WMODE1 = 1,
+    gs_type42_metrics_options_BBOX = 2,
+    gs_type42_metrics_options_WMODE0_AND_BBOX = 4,
+    gs_type42_metrics_options_WMODE1_AND_BBOX = 5,
+} gs_type42_metrics_options_t;
+#define gs_type42_metrics_options_wmode(a)         ((a)&gs_type42_metrics_options_WMODE1)
+#define gs_type42_metrics_options_sbw_requested(a) (~(a)&gs_type42_metrics_options_BBOX)
+#define gs_type42_metrics_options_bbox_requested(a)((a)&6)
+
+/* Export the default get_metrics procedure. 
+   The length of sbw is >=4 when bbox in not requested,
+   and 8 otherwise.
+ */
+int gs_type42_default_get_metrics(gs_font_type42 *pfont, uint glyph_index,
+				  gs_type42_metrics_options_t options, float *sbw);
+
 typedef struct gs_type42_mtx_s {
     uint numMetrics;		/* num*Metrics from [hv]hea */
     ulong offset;		/* offset to [hv]mtx table */
@@ -52,8 +72,9 @@
     uint (*get_glyph_index)(gs_font_type42 *pfont, gs_glyph glyph);
     int (*get_outline)(gs_font_type42 *pfont, uint glyph_index,
 		       gs_glyph_data_t *pgd);
-    int (*get_metrics)(gs_font_type42 *pfont, uint glyph_index, int wmode,
-		       float sbw[4]);
+    int (*get_metrics)(gs_font_type42 *pfont, uint glyph_index, 
+			gs_type42_metrics_options_t options,
+			float *sbw_bbox/* See comment for gs_type42_default_get_metrics */);
 
     /* The following are cached values. */
     ulong cmap;			/* offset to cmap table (not used by */
@@ -115,11 +136,6 @@
 /* Get the metrics of a TrueType character. */
 int gs_type42_get_metrics(gs_font_type42 * pfont, uint glyph_index,
 			  float psbw[4]);
-int gs_type42_wmode_metrics(gs_font_type42 * pfont, uint glyph_index,
-			    int wmode, float psbw[4]);
-/* Export the default get_metrics procedure. */
-int gs_type42_default_get_metrics(gs_font_type42 *pfont, uint glyph_index,
-				  int wmode, float sbw[4]);
 
 int gs_type42_get_outline_from_TT_file(gs_font_type42 * pfont, stream *s, uint glyph_index,
 		gs_glyph_data_t *pgd);

Modified: trunk/gs/src/zchar42.c
===================================================================
--- trunk/gs/src/zchar42.c	2007-01-05 05:19:34 UTC (rev 7566)
+++ trunk/gs/src/zchar42.c	2007-01-05 20:44:21 UTC (rev 7567)
@@ -41,50 +41,79 @@
 {   double sbw[4];
     double w[2];
     int present;
+    gs_font_type42 *pfont42 = (gs_font_type42 *)pbfont;
     int code = zchar_get_metrics(pbfont, cnref, sbw);
+    gs_rect bbox;
+    int vertical = gs_rootfont(igs)->WMode;
+    float sbw_bbox[8];
 
     if (code < 0)
 	return code;
     present = code;
-    if (present == metricsNone) {
-	float sbw42[4];
-	int i;
-
-	code = gs_type42_wmode_metrics((gs_font_type42 *)pbfont,
-				       glyph_index, false, sbw42);
-	if (code < 0)
-	    return code;
-	present = metricsSideBearingAndWidth;
-	for (i = 0; i < 4; ++i)
-	    sbw[i] = sbw42[i];
-	w[0] = sbw[2];
-	w[1] = sbw[3];
-	if (gs_rootfont(igs)->WMode) { /* for vertically-oriented metrics */
-	    code = gs_type42_wmode_metrics((gs_font_type42 *)pbfont,
-					   glyph_index,
-					   true, sbw42);
-	    if (code < 0) { /* no vertical metrics */
+    if (vertical) { /* for vertically-oriented metrics */
+	code = pfont42->data.get_metrics(pfont42, glyph_index, 
+		gs_type42_metrics_options_WMODE1_AND_BBOX, sbw_bbox);
+	if (code < 0) { 
+	    /* No vertical metrics in the font, compose from horizontal. 
+	       Still need bbox also. */
+	    code = pfont42->data.get_metrics(pfont42, glyph_index, 
+		    gs_type42_metrics_options_WMODE0_AND_BBOX, sbw_bbox);
+	    if (code < 0)
+		return code;
+	    if (present == metricsNone) {
 		if (pbfont->FontType == ft_CID_TrueType) {
-		    sbw[0] = sbw[2] / 2;
+		    sbw[0] = sbw_bbox[2] / 2;
 		    sbw[1] = pbfont->FontBBox.q.y;
 		    sbw[2] = 0;
 		    sbw[3] = pbfont->FontBBox.p.y - pbfont->FontBBox.q.y;
+		} else {
+		    sbw[0] = sbw_bbox[0];
+		    sbw[1] = sbw_bbox[1];
+		    sbw[2] = sbw_bbox[2];
+		    sbw[3] = sbw_bbox[3];
 		}
-	    } else {
-		sbw[0] = sbw[2] / 2;
-		sbw[1] = (pbfont->FontBBox.q.y + pbfont->FontBBox.p.y - sbw42[3]) / 2;
-		sbw[2] = sbw42[2];
-		sbw[3] = sbw42[3];
+		present = metricsSideBearingAndWidth;
 	    }
+	} else {
+	    if (present == metricsNone) {
+		sbw[0] = sbw_bbox[2] / 2;
+		sbw[1] = (pbfont->FontBBox.q.y + pbfont->FontBBox.p.y - sbw_bbox[3]) / 2;
+		sbw[2] = sbw_bbox[2];
+		sbw[3] = sbw_bbox[3];
+		present = metricsSideBearingAndWidth;
+	    }
 	}
     } else {
-        w[0] = sbw[2];
-        w[1] = sbw[3];
+	code = pfont42->data.get_metrics(pfont42, glyph_index, 
+		    gs_type42_metrics_options_WMODE0_AND_BBOX, sbw_bbox);
+	if (code < 0)
+	    return code;
+	if (present == metricsNone) {
+	    sbw[0] = sbw_bbox[0];
+	    sbw[1] = sbw_bbox[1];
+	    sbw[2] = sbw_bbox[2];
+	    sbw[3] = sbw_bbox[3];
+	    present = metricsSideBearingAndWidth;
+	}
     }
+    w[0] = sbw[2];
+    w[1] = sbw[3];
+    if (!vertical) {
+	sbw_bbox[6] = (sbw_bbox[6] - sbw_bbox[4]) + sbw_bbox[0];
+	sbw_bbox[4] = sbw_bbox[0];
+    }
+    /* Note: The glyph bbox usn't useful for Dynalab fonts,
+       which stretch subglyphs. Uniting with FontBBox helps.
+       In same time, FontBBox with no glyph bbox
+       doesn't work for 34_all.PS page 4. */
+    bbox.p.x = min(sbw_bbox[4], pbfont->FontBBox.p.y);
+    bbox.p.y = min(sbw_bbox[5], pbfont->FontBBox.p.y);
+    bbox.q.x = max(sbw_bbox[6], pbfont->FontBBox.q.x);
+    bbox.q.y = max(sbw_bbox[7], pbfont->FontBBox.q.y);
     return zchar_set_cache(i_ctx_p, pbfont, cnref,
 			   (put_lsb && present == metricsSideBearingAndWidth ?
 			    sbw : NULL),
-			   w, &pbfont->FontBBox,
+			   w, &bbox,
 			   cont, exec_cont,
 			   gs_rootfont(igs)->WMode ? sbw : NULL);
 }



More information about the gs-cvs mailing list