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
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)
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.
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.
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.
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.
This is the highest priority PS bug for this customer.
For basic (no anti-aliasing) device, my fix for bug 689646 http://bugs.ghostscript.com/attachment.cgi?id=3738&action=view fixes this issue.
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.
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));
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.