[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