Bug 689464 - Japanese font writing direction (vertical ?)
Summary: Japanese font writing direction (vertical ?)
Status: NOTIFIED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: Text (show other bugs)
Version: master
Hardware: All All
: P1 normal
Assignee: mpsuzuki
URL:
Keywords:
Depends on: 689646 689647
Blocks:
  Show dependency tree
 
Reported: 2007-09-18 15:28 UTC by Ray Johnston
Modified: 2008-12-19 08:31 UTC (History)
1 user (show)

See Also:
Customer: 951
Word Size: ---


Attachments
Fix for glyph cache bug after bug 689646 and bug 689647 (3.56 KB, patch)
2008-01-24 09:13 UTC, mpsuzuki
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ray Johnston 2007-09-18 15:28:44 UTC
The glyphs wander up and to the right instead on remaining in the orange box
as they are supposed to.

This may be an example of a vertical writing problem.

I will attempt to extract a reduced test case, but the problem can be seen on
page 7 of casper:/home/sen/incoming/Atsif_8_31/PS3_98_Jap/PTCAB_C5.prn
Comment 1 Ray Johnston 2007-09-18 15:35:57 UTC
Also seen on page one of
casper:/home/sen/incoming/Atsif_8_31/PS3_98_Jap/PTCAB_M3.prn
where the "17" and "18" are written over by an Asian glyph (lower left of screen)
Comment 2 mpsuzuki 2007-09-19 06:18:18 UTC
Yet I've not investigated in detail, PTCAB_M3.prn is appropriate
to start, because all CJK fonts are embedded in the document.

The sample file demonstrate 2 different bugs.

One bug is related to glyph cache. For example,
check the most right text of vertical 4 texts in PTCAB_M3.prn.
If rasterize on x11alpha with glyph cache (enabled by default),
the centerline of 1st and 2nd character is different from
the centerline of 3rd and following characters.
If rasterize on x11alpha without glyph cache (-dNOCACHE),
the centerline of 1-3rd and 5th-later is consistent.
However, the 4th character (dot in center) is shifted
as if its left side bearing is removed. If glyph cache
is enabled, the dot is correctly centerlined.

Another bug is gap between numericals ("17" & "18") and
CJK ideographs. The numericals are drawn in horizontal
writing mode, but other CJK ideographs are drawn in
vertical writing mode. This bug reminds another bug 688058,
but this bug is introduced in later version. If rasterize
by SVN r5429 on x11alpha without glyph cache, no problem
found.

I will continue the investigation.
Comment 3 mpsuzuki 2007-09-20 21:55:08 UTC
The bug of glyph cache had been introduced since SVN revision 4887 by Igor.
The changeset is huge and designed to fix bug 687359, not specific to
glyph cache, but the regression found in SVN revision 4887 disappears
if "-dNOCACHE" is added.
More decomposition of the problem is required to discuss the solution.
Comment 4 mpsuzuki 2007-09-21 05:06:22 UTC
The bug unrelated with glyph cache had been introduced since SVN revision 5607.
The changeset (changing a few line in src/zchar1.c) was designed to fix
similar problem bug 687846.
Comment 5 mpsuzuki 2008-01-09 20:28:53 UTC
The sample PS file is converted from PDF, by Adobe Reader (or Acrobat).
The original PDF refers Jun101-Light which is not embedded in the PDF,
so Adobe Reader inserts KozMin as substituted font instead of Jun101-Light.
This situation is different from other embedded TrueType fonts which
were already embedded in PDF. The bug since SVN revision 5607 can be
reproduced by very simple test. See bug 689646.
Comment 6 Ray Johnston 2008-01-15 10:04:56 UTC
This is the highest priority PS bug for this customer.
Comment 7 mpsuzuki 2008-01-24 08:47:46 UTC
For basic (no anti-aliasing) device, my fix for bug 689646
http://bugs.ghostscript.com/attachment.cgi?id=3738&action=view
fixes this issue.
Comment 8 mpsuzuki 2008-01-24 08:56:29 UTC
For anti-aliasing device (x11alpha), the combination of 2 patches
http://bugs.ghostscript.com/attachment.cgi?id=3738&action=view (fix for bug 689646)
http://bugs.ghostscript.com/attachment.cgi?id=3734&action=view (fix for bug 689647)
can fix the wandering of vertical text, if "-dNOCACHE" is given.
There are more glyph cache bugs.
Comment 9 mpsuzuki 2008-01-24 09:13:17 UTC
Created attachment 3739 [details]
Fix for glyph cache bug after bug 689646 and bug 689647

The glyph cache bug is caused by 2 reasons.

1. the wrong calculation of glyph width and height.
   If cxs.sbw[] is calculated for vertical writing mode,
   they should not be used, because zchar_set_cache()
   expects the horizontal glyph size. When current font
   is WMode == 1, horizontal glyph size should be recalculated.

2. When horizontal glyph size is calculated, the values
   in cxs.sbw[] should not be changed, especially for
   vertical writing mode. They are used by setcachedevice2
   in later. Using temporal variables to pass the horizontal
   glyph size to zchar_set_cache() is better.

Koji Otani's patch inserts these hook (horizontal glyph size
calculation and pass it by temporal variable) to type1exec_bbox()
and nobbox_finish().

diff -u src/zchar1.c src/zchar1.c
--- src/zchar1.c	(3734+3738)
+++ src/zchar1.c	(more Koji Otani bits)
@@ -397,11 +397,48 @@
     } else {
	/* We have the width and bounding box: */
	/* set up the cache device now. */
+	 double w[2];
+	 w[0] = pcxs->sbw[2], w[1] = pcxs->sbw[3];
+      
+	if (pcxs->use_FontBBox_as_Metrics2) {
+	   /* In this case, we have to calculate width for WMode=0. 
+	      pcxs->sbw[2, 3] is width for WMode=1.
+	      Normally, the width for WMode=0 is not used in WMode=1 
+	      rendering. However, if CDevProc is defined, 
+	      the width for WMode=0 is used. 
+	      Do the same as the case pcxs->present == metricsNone */
+	     double sbw[4];
+	     ref cnref;
+	     ref other_subr;
+	     int code;
+	     
+	    /* Since an OtherSubr callout might change osp, */
+	    /* save the character name now. */
+	    ref_assign(&cnref, op - 1);
+	    code = type1_continue_dispatch(i_ctx_p, pcxs, op, &other_subr, 4);
+	    op = osp;		/* OtherSubrs might change it */
+	    switch (code) {
+	     default:		/* code < 0 or done, error */
+		 return ((code < 0 ? code :
+			 gs_note_error(e_invalidfont)));
+	    case type1_result_callothersubr:	/* unknown OtherSubr */
+		return type1_call_OtherSubr(i_ctx_p, pcxs,
+					    bbox_getsbw_continue,
+					    &other_subr);
+	    case type1_result_sbw:	/* [h]sbw, done */
+		break;
+	    }
+	    type1_cis_get_metrics(pcis, sbw);
+	    w[0] = sbw[2], w[1] = sbw[3];
+	    /* Now actual width is available, I can calculate much 
+	       better side bearing for WMode 1 from the width. */
+	    pcxs->sbw[0] = w[0] / 2;
+	}
	return zchar_set_cache(i_ctx_p, pbfont, op - 1,
			       (pcxs->present == metricsSideBearingAndWidth
				&& !pcxs->use_FontBBox_as_Metrics2 ?
				pcxs->sbw : NULL),
-			       pcxs->sbw + 2,
+			       w,
			       &pcxs->char_bbox,
			       cont, exec_cont, 
			       (pcxs->use_FontBBox_as_Metrics2 ? pcxs->sbw :
NULL));
@@ -834,6 +871,7 @@
     int code;
     gs_text_enum_t *penum = op_show_find(i_ctx_p);
     gs_font *pfont;
+    double w[2] = { pcxs->sbw[2], pcxs->sbw[3] };
 
     if ((code = gs_pathbbox(igs, &pcxs->char_bbox)) < 0 ||
	(code = font_param(op - 3, &pfont)) < 0
@@ -851,8 +889,18 @@
 
	    if ((code = gs_currentpoint(igs, &endpt)) < 0)
		return code;
-	    pcxs->sbw[2] = endpt.x, pcxs->sbw[3] = endpt.y;
+	    /* We will not use sbw[3, 4]. 
+	       If pcxs->use_FontBBox_as_Metrics2 is true,
+	       sbw[3, 4] are used as arguments(W1x, W1y) of setcachedevice2. 
+	       We will use w[0, 1] as W0x and W0y of setcachedevice2.
+	       W0 and W1 is differrent parameters. Don't confuse. */
+	    w[0] = endpt.x, w[1] = endpt.y;
	    pcxs->present = metricsSideBearingAndWidth;
+	    if (pcxs->use_FontBBox_as_Metrics2) {
+	      /* Now actual width is available, I can calculate much 
+		 better side bearing for WMode 1 from the width. */
+	      pcxs->sbw[0] = w[0] / 2;
+	    }
	}
	/*
	 * We only need to rebuild the path from scratch if we might
@@ -871,7 +919,7 @@
			? nobbox_fill : nobbox_stroke);
	    exec_cont = 0;
	    code = zchar_set_cache(i_ctx_p, pbfont, op - 1, NULL,
-				   pcxs->sbw + 2,
+				    w,
				   &pcxs->char_bbox,
				   cont, &exec_cont,
				   (pcxs->use_FontBBox_as_Metrics2 ? pcxs->sbw
: NULL));
Comment 10 leonardo 2008-01-25 00:26:45 UTC
We decided to go with a different fix, which has been committed as 
http://ghostscript.com/pipermail/gs-cvs/2008-January/008087.html
It replaces comments #7,8,9.

This patch doesn't try to fix the antialiased rendering problem, which is 
described in Bug 689647. Not sure why this bug set depending on that - it looks 
as an independent problem.

Closing this bug now.