Bug 689647

Summary: vertical text rendered by external CIDFontType0 wanders on x11alpha
Product: Ghostscript Reporter: mpsuzuki <mpsuzuki>
Component: TextAssignee: mpsuzuki <mpsuzuki>
Status: NOTIFIED FIXED    
Severity: normal CC: mpsuzuki
Priority: P4    
Version: master   
Hardware: PC   
OS: All   
Customer: Word Size: ---
Bug Depends on:    
Bug Blocks: 689464    
Attachments: x11alpha screenshot by SVN revision 7992
x11alpha screenshot by SVN revision 7993
x11alpha screenshot by SVN revision 7993 + "-dNOCACHE"
improved Alex's patch which does not cause regression on Bug687846.ps

Description mpsuzuki 2008-01-09 20:40:19 UTC
By Alex's change on SVN revision 7993, vertical text rendered by
external CIDFontType0 wanders (not horizontal or vertical) on x11alpha.
This bug may be related with glyph cache. The result by -dNOCACHE
looks same with the bug for common raster device (bug 689646).
Comment 1 mpsuzuki 2008-01-09 20:46:12 UTC
Created attachment 3688 [details]
x11alpha screenshot by SVN revision 7992

screenshot of result on x11alpha, the sample PS file is same with bug 689646.
This is expected result.
Comment 2 mpsuzuki 2008-01-09 20:48:39 UTC
Created attachment 3689 [details]
x11alpha screenshot by SVN revision 7993

screenshot of result on x11alpha, this is not expected result.
Comment 3 mpsuzuki 2008-01-09 20:49:58 UTC
Created attachment 3690 [details]
x11alpha screenshot by SVN revision 7993 + "-dNOCACHE"

screenshot of result on x11alpha with "-dNOCACHE".
The result looks same with bug 689646.
Comment 4 Ray Johnston 2008-01-15 09:43:45 UTC
Request Alex to look at this change to see how it could cause this.

If it is actually a font processing bug, please assign to mpsuzuki
Comment 5 Alex Cherepanov 2008-01-19 21:27:48 UTC
My patch fixed an uninitialized variable, but the initialization value
was chosen to keep the existing code working. The following patch
assigns a correct value (IMHO) but it breaks out test file: Bug687846.ps .
It looks like the implementation has several bugs that partly compensate
each other. So we need to review the whole vertical writing code.

Index: gs/src/zchar1.c
===================================================================
--- gs/src/zchar1.c	(revision 8482)
+++ gs/src/zchar1.c	(working copy)
@@ -230,7 +230,7 @@
 	cxs.sbw[2] = 0;
 	cxs.sbw[3] = -penum->FontBBox_as_Metrics2.x; /* Sic! */
 	cxs.use_FontBBox_as_Metrics2 = true;
-	cxs.present = metricsNone;
+	cxs.present = metricsSideBearingAndWidth;
     }
     /* Establish a current point. */
     code = gs_moveto(igs, 0.0, 0.0);
Comment 6 mpsuzuki 2008-01-23 21:03:41 UTC
Created attachment 3734 [details]
improved Alex's patch which does not cause regression on Bug687846.ps

Fix: fix side effect from Alex's patch for bug 689647 to Bug687846.ps.

DETAILS:

This is Alex's patch to fix bug 689647 (vertical text wandering on
x11alpha device).

Index: src/zchar1.c
===================================================================
--- src/zchar1.c	(revision 8482)
+++ src/zchar1.c	(working copy)
@@ -230,7 +239,7 @@
	cxs.sbw[2] = 0;
	cxs.sbw[3] = -penum->FontBBox_as_Metrics2.x; /* Sic! */
	cxs.use_FontBBox_as_Metrics2 = true;
-	cxs.present = metricsNone;
+	cxs.present = metricsSideBearingAndWidth;
     }
     /* Establish a current point. */
     code = gs_moveto(igs, 0.0, 0.0);

===================================================================

By Alex's patch for bug 689647, the initalization of cxs is changed
	original
		cxs.use_FontBBox_as_Metrics2 = true;
		cxs.present = metricsNone;
	patched
		cxs.use_FontBBox_as_Metrics2 = true;
		cxs.present = metricsSideBearingAndWidth;
when current font is CIDFontType 0 and WMode is 1 (vertical).

A few functions should be changed to synchronize it, because
they changes their behaviours by checking cxs.use_FontBBox_as_Metrics2
and cxs.present.

* charstring_execchar_aux()

When current font is CIDFontType 0 and WMode is 1, originally
cxs.present was set to metricsNone, thus the twice creation of
the path by gs_type1_set_lsb() was not executed.

To avoid unwanted gs_type1_set_lsb() execution, the condition
is fixed
	original
		if (cxs.present == metricsSideBearingAndWidth)
	patched
		if (cxs.present == metricsSideBearingAndWidth
			&& !cxs.use_FontBBox_as_Metrics2)

* nobbox_finish() 

When current font is CIDFontType 0 and WMode is 1, originally
cxs.present was set to metricsNone, thus the calculation of
side bearing and width from the constructed path was executed.

	if (pcxs->present == metricsNone) {
		gs_point endpt;

		if ((code = gs_currentpoint(igs, &endpt)) < 0)
			return code;
		pcxs->sbw[2] = endpt.x, pcxs->sbw[3] = endpt.y;
		pcxs->present = metricsSideBearingAndWidth;
	}
 
After Alex's patch, cxs.present is set to metricsSideBearingAndWidth,
thus this part is not executed. To synchronize nobbox_finish(),
the condition should be fixed as 
	original
		if (pcxs->present == metricsNone)
	patched
		if (pcxs->present == metricsNone
			|| pcxs->use_FontBBox_as_Metrics2)

These are extracted from Koji Otani's patch for src/zchar1.c
(bug 689405) to fix Bug687846.ps issue.

Index: src/zchar1.c
===================================================================
--- src/zchar1.c	(revision 8482)
+++ src/zchar1.c	(working copy)
@@ -10,6 +10,15 @@
    or contact Artifex Software, Inc.,	7 Mt. Lassen Drive - Suite A-134,
    San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
 */
+/*
+ * Modified by AXE,Inc., BBR Inc. and Turbolinux Inc.
+ *   under the technical advice by suzuki toshiya (Hiroshima University)
+ * Based on bugfix by Hideo Saito, 2001.
+ * For questions, please send mail to espgs8-cjk@printing-japan.org
+ *
+ * (C) Copyright 2006 Center of the International Cooperation for
+ *	Computerization
+ */
 
 /* $Id$ */
 /* Type 1 character display operator */
@@ -279,7 +288,7 @@
	 * create the path twice, since we can't know the
	 * oversampling factor until after setcachedevice.
	 */
-	if (cxs.present == metricsSideBearingAndWidth) {
+	if (cxs.present == metricsSideBearingAndWidth &&
!cxs.use_FontBBox_as_Metrics2) {
	    gs_point sbpt;
 
	    sbpt.x = cxs.sbw[0], sbpt.y = cxs.sbw[1];
@@ -837,7 +846,7 @@
	gs_font_type1 *const pfont1 = (gs_font_type1 *) pfont;
	op_proc_t cont, exec_cont = 0;
 
-	if (pcxs->present == metricsNone) {
+	if (pcxs->present == metricsNone || pcxs->use_FontBBox_as_Metrics2) {
	    gs_point endpt;
 
	    if ((code = gs_currentpoint(igs, &endpt)) < 0)
Comment 7 leonardo 2008-01-25 00:34:28 UTC
A test case is not attached.

With revision 8504 this command line works fine :

..\..\gs-hd\bin\gswin32c.exe -IF:\AFPL\gs-hd\lib;f:\afpl\fonts -r144 -dBATCH -
d/DEBUG -d/NOCACHE -dTextAlphaBits=4 -sDEVICE=ppmraw -o out.ppm attachment.ps

where attachment.ps is the test file of the bug 689646.

Closing as invalid since no test case and it appears working for me.
Comment 8 mpsuzuki 2008-01-25 01:17:01 UTC
This bug occurs on x11alpha and without "-dNOCACHE".
As initial comment, adding "-dNOCACHE" hides this bug.

>..\..\gs-hd\bin\gswin32c.exe -IF:\AFPL\gs-hd\lib;f:\afpl\fonts -r144 -dBATCH -
>d/DEBUG -d/NOCACHE -dTextAlphaBits=4 -sDEVICE=ppmraw -o out.ppm attachment.ps

I'm unfamiliar with Win32-specific syntax, the option
"-d/NOCACHE" enables glyph cache?
Comment 9 mpsuzuki 2008-01-25 01:49:24 UTC
Fortunately, the sample does not reproduce the bug
after SVN revision 8504, that was designed to fix
bug 689464.