Fix: Wrong centerline of vertical text drawn by CJK TrueType fonts.

DETAILS:
In vertical writing mode, when zchar_get_metrics() returns
successfully but returned value is "metricsNone", the vertical
metric obtained by gs_type42_default_get_metrics() with a flag
gs_type42_metrics_options_WMODE1_AND_BBOX is not reliable.

The metric for vertical writing mode is synthesized from
per-glyph bounding box (pbbox) obtained by new function
gs_type42_glyph_fbbox() and horizontal metric obtained by
gs_type42_default_get_metrics() with a flag
gs_type42_metrics_options_WMODE0_AND_BBOX.

"pbbox" is filled by calling gs_type42_glyph_fbbox() which
parses the entry of glyf table for given glyph index and
updates both of per-glyph and per-font bounding box.
If per-glyph bounding box is unavailable, per-font bounding
box is used.

EXPECTED DIFFERENCES:
None.
Index: src/zchar42.c
===================================================================
--- src/zchar42.c	(revision 8357)
+++ src/zchar42.c	(working copy)
@@ -10,6 +10,16 @@
    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 Masatake Yamato and 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 42 character display operator */
@@ -42,11 +52,19 @@
     double w[2];
     int present;
     gs_font_type42 *pfont42 = (gs_font_type42 *)pbfont;
-    int code = zchar_get_metrics(pbfont, cnref, sbw);
-    gs_rect bbox;
+    gs_rect bbox,*pbbox;
+    int code;
     int vertical = gs_rootfont(igs)->WMode;
     float sbw_bbox[8];
 
+    if (vertical &&
+        0 == gs_type42_glyph_fbbox((gs_font *)pbfont, glyph_index, &bbox)
+       ) 
+        pbbox = &bbox;
+    else
+        pbbox = &pbfont->FontBBox;
+
+    code = zchar_get_metrics(pbfont, cnref, sbw);
     if (code < 0)
 	return code;
     present = code;
@@ -75,9 +93,16 @@
 		present = metricsSideBearingAndWidth;
 	    }
 	} else {
+	    float sbw_hbbox[8];
+
+	    code = pfont42->data.get_metrics(pfont42, glyph_index, 
+		    gs_type42_metrics_options_WMODE0_AND_BBOX, sbw_hbbox);
+	    if (code < 0)
+		return code;
+
 	    if (present == metricsNone) {
-		sbw[0] = sbw_bbox[2] / 2;
-		sbw[1] = (pbfont->FontBBox.q.y + pbfont->FontBBox.p.y - sbw_bbox[3]) / 2;
+		sbw[0] = sbw_hbbox[2] / 2;
+		sbw[1] = pbbox->q.y - sbw_bbox[1];
 		sbw[2] = sbw_bbox[2];
 		sbw[3] = sbw_bbox[3];
 		present = metricsSideBearingAndWidth;
@@ -113,7 +138,7 @@
     return zchar_set_cache(i_ctx_p, pbfont, cnref,
 			   (put_lsb && present == metricsSideBearingAndWidth ?
 			    sbw : NULL),
-			   w, &bbox,
+			   w, pbbox,
 			   cont, exec_cont,
 			   gs_rootfont(igs)->WMode ? sbw : NULL);
 }
Index: src/gxfont42.h
===================================================================
--- src/gxfont42.h	(revision 8357)
+++ src/gxfont42.h	(working copy)
@@ -10,6 +10,14 @@
    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)
+ * For questions, please send mail to espgs8-cjk@printing-japan.org
+ *
+ * (C) Copyright 2006 Center of the International Cooperation for
+ *     Computerization
+ */
 
 /* $Id$ */
 /* Type 42 font data definition */
@@ -155,6 +163,9 @@
 int gs_type42_get_outline_from_TT_file(gs_font_type42 * pfont, stream *s, uint glyph_index,
 		gs_glyph_data_t *pgd);
 
+/* Export the function get glypf bounding box from font data */
+int gs_type42_glyph_fbbox(gs_font *font, uint glyph_index, gs_rect *pbbox);
+
 /* Export the font procedures so they can be called from the interpreter. */
 font_proc_enumerate_glyph(gs_type42_enumerate_glyph);
 font_proc_glyph_info(gs_type42_glyph_info);
Index: src/gstype42.c
===================================================================
--- src/gstype42.c	(revision 8357)
+++ src/gstype42.c	(working copy)
@@ -10,6 +10,14 @@
    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)
+ * For questions, please send mail to espgs8-cjk@printing-japan.org
+ *
+ * (C) Copyright 2006 Center of the International Cooperation for
+ *     Computerization
+ */
 
 /* $Id$ */
 /* Type 42 (TrueType) font library routines */
@@ -667,6 +675,50 @@
 			     origin.y + float2fixed(info.width[WMode].y));
 }
 
+/* Get glyph bounding box from font file */
+int
+gs_type42_glyph_fbbox(gs_font *font, uint glyph_index, gs_rect *pbbox)
+{
+    gs_font_type42 *const pfont = (gs_font_type42 *)font;
+    gs_glyph_data_t glyph_data;
+    double factor = 1.0 / pfont->data.unitsPerEm;
+    int code = 0;
+    const byte *gdata;
+
+    if ((code = pfont->data.get_outline(pfont, glyph_index, &glyph_data)) < 0) {
+	return code;		/* non-existent glyph */
+    }
+    if (glyph_data.bits.size == 0) {
+	code = 1; /* notdef */
+	goto done;
+    }
+    if (glyph_data.bits.size != 0 && S16(glyph_data.bits.data) == -1) {
+	/* This is a composite glyph. */
+	uint flags;
+	gs_matrix_fixed mat;
+
+	gdata = glyph_data.bits.data + 10;
+	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) {
+		code = gs_type42_glyph_fbbox(font, comp_index, pbbox);
+		goto done;
+	    }
+	}
+	while (flags & TT_CG_MORE_COMPONENTS);
+    }
+    gdata = glyph_data.bits.data;
+    pbbox->p.x = S16(gdata+2)*factor;
+    pbbox->p.y = S16(gdata+4)*factor;
+    pbbox->q.x = S16(gdata+6)*factor;
+    pbbox->q.y = S16(gdata+8)*factor;
+done:
+    gs_glyph_data_free(&glyph_data, "gs_type42_glyph_fbbox");
+    return code;
+}
 /* Get glyph info by glyph index. */
 int
 gs_type42_glyph_info_by_gid(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
