summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Melichev <igor.melichev@artifex.com>2004-09-22 13:52:36 +0000
committerIgor Melichev <igor.melichev@artifex.com>2004-09-22 13:52:36 +0000
commitd7ca222003039c6be6e99503d487197e88c45033 (patch)
tree070df4a522863110e49643301d8f77d53439ff3f
parent61e59ee3259dec408d28596d4ff91a29fa8bbe16 (diff)
downloadghostpdl-d7ca222003039c6be6e99503d487197e88c45033.tar.gz
CDevProc|Metrics|Metrics2 did not work with CIDFontType 0.
DETAILS : Bug 687681 "Character spacing incorrect". The old implementation, which comes from the gs-cjk team, has a bug accessing the replaced metrics of a CIDFontType 0 font, which effectively caused the replaced metric to be ignored with CIDFontType 0 fonts. 1. Bug : With CIDFontType 0, CDevProc|Metrics|Metrics2 was searched in the descendent type 1 or 2 font rather than in the parent type 9 font. 1.1. A Type 9 font needs to be accessed via a descendent Type 1|2 font in pfont->procs.glyph_info. Added a new field gs_type1_data_s::parent, and provided an access through it with a new function gs_font_parent. 1.2. Metrics|Metrics2 is now accessed through gs_font_parent. 1.3. To access CDevProc implemented a new function zchar_get_CDevProc, which also works through gs_font_parent. 1.4. gs_type1_data_s::parent needs to reset while a type 9 font finalization, due to a reason, which we could not understand for sure. Likely descendent fonts appear to have a bigger lifetime than their parent type 9 font. Probably the descendents are pointed from somewhere besides FDArray (maybe the font registry ? or maybe after scaling the type 9 font from a type 9 copy ?), and we think it's not good. We believe that they should be released together with the type 9 font. For now leaving it as it is, working around with a hack notify_remove_font_type9. 1.5. In stable font copies gs_type1_data_s::parent is set to NULL to simplify the finalization. They are not used now. 2. Bug : In some cases the glyph bytecode was used instead the CID as a key for searching a Metrics|Metrics2 element (zchar1.c). 3. Bug : The PDF interpreter wrongly scaled W,W2,DW,DW2 for CIDFontTYpe0 (pdf_font.ps). 4. pdfwrite : Improved the generation of W, W2 for CID fonts, because after implementing (1) re-distilled 401-01.ps rendered incorrectly. 4.1. Prefer a non-zero width when computing DW, DW2 (gdevpdtw.c) (debugged with 401-01.ps). 4.2. Don't skip zero W, W2 elements. The old code recognized zeros as unused glyphs, but must do with the real glyph set in the font copy (debugged with the test file of the bug 687681). 5. zcharstring_outline still ignores CDevProc. We believe that it is correct, because it is used to compute font features with no dependence on the relaced metrics. 6. pdfwrite : Allowed a CDevProc callout for CIDFontType 0, because pdfwrite needs to know replaced widths, as well as it was done a half year ago for CIDFontType2. Actually after implementing (1) pdfwrite stopped to work correctly when re-distilling a PDF file with CIDFontType0, due to now it uses W,W2,DW,DW2. 6.1. A new function z1_set_cache is defined for this purpose similarly to zchar42_set_cache. 6.2. gs_font_procs::glyph_outline now retrieves the side bearing and width. Added a new argument 'sbw' to all implementations. 6.2.1. Currently this function extension is implemented for charstring fonts only, which need to interpret a charstring to retrieve the info : type 1,2,9, because we don't want to run the type 1 interpreter 2 times for getting sbw and bbox. Other font types retrieve zeros, which currently are not used. 6.2.2. type1_cis_get_metrics has been made public. 7. We believe that the implementation of W,W2,DW,DW2 in the PDF interpreter, which was contributed by the gs-cjk team, is unreasonably overcomplicated, because it is based on CDevProc, which needs an interpreter callout, which appears extremily hard from pdfwrite. For now leaving it as it is (except a small improvement in (3)). We would like to generate Metrics, Metrics2 instead that. Note that a small part of this patch (the part (1)) is necessary for generating Metrics, Metrics2 for CIDFontTYpe 0. EXPECTED DIFFERENCES : Almost all differences are a single pixel glyph shift. normal 72dpi : "Altona.Page_3.2002-09-27.pdf" "HeiseiMinStd.pdf" "KozukaB-ILEmbed.pdf" "Openhuis_pdf_zw.pdf" "RodinCIDEmbed.pdf" normal 300dpi : "289-01.ps" "Altona.Page_3.2002-09-27.pdf" "Altona_Technical_1v1_x3.pdf" "CIDembedded.pdf" "HeiseiMinStd.pdf" "KozukaB-ILEmbed.pdf" "Openhuis_pdf_zw.pdf" "RodinCIDEmbed.pdf" pdfwrite 72dpi : "Altona.Page_3.2002-09-27.pdf" "HeiseiMinStd.pdf" "KozukaB-ILEmbed.pdf" "Openhuis_pdf_zw.pdf" "RodinCIDEmbed.pdf" pdfwrite 300dpi : "CIDembedded.pdf" "HeiseiMinStd.pdf" "KozukaB-ILEmbed.pdf" "Openhuis_pdf_zw.pdf" "RodinCIDEmbed.pdf" git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@5365 a1074d23-0009-0410-80fe-cf8c14f379e6
-rw-r--r--gs/lib/pdf_font.ps10
-rw-r--r--gs/src/gdevpdtt.c8
-rw-r--r--gs/src/gdevpdtw.c19
-rw-r--r--gs/src/gsfont.c31
-rw-r--r--gs/src/gstype42.c2
-rw-r--r--gs/src/gxfcopy.c11
-rw-r--r--gs/src/gxfont.h6
-rw-r--r--gs/src/gxfont1.h5
-rw-r--r--gs/src/gxtype1.c13
-rw-r--r--gs/src/gxtype1.h3
-rw-r--r--gs/src/ichar1.h5
-rw-r--r--gs/src/icharout.h2
-rw-r--r--gs/src/zchar.c5
-rw-r--r--gs/src/zchar1.c52
-rw-r--r--gs/src/zcharout.c18
-rw-r--r--gs/src/zfcid0.c42
-rw-r--r--gs/src/zfcid1.c4
-rw-r--r--gs/src/zfont1.c1
-rw-r--r--gs/src/zfont42.c4
19 files changed, 194 insertions, 47 deletions
diff --git a/gs/lib/pdf_font.ps b/gs/lib/pdf_font.ps
index 82db5ca1c..53176e6f9 100644
--- a/gs/lib/pdf_font.ps
+++ b/gs/lib/pdf_font.ps
@@ -947,7 +947,6 @@ readonly def
/CIDWProc { % <w0x> <w0y> <llx> <lly> <urx> <ury>
% <w1x> <w1y> <vx> <vy> <cid> <font> CIDWproc
% <w0x'> ... <vy'>
-
begin % push <font> to currentdict
% <w1x> <w1y> <vx> <vy> won't be used and replaced, discard now
5 1 roll pop pop pop pop
@@ -975,7 +974,9 @@ readonly def
exit
} loop
- 1000 div % <w0x'> (normalized W)
+ FontType 11 eq {
+ 1000 div % <w0x'> (normalized W)
+ } if
0 % <w0y'>
% Stack: <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <w0x'> <w0y'>
@@ -1013,14 +1014,13 @@ readonly def
exch pop % discard <cid>
-
% Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> { [<vy'> <w1y'>] | [<w1y'> <vx'> <vy'>] }
dup length 2 eq { % this is DW2
- {1000 div} forall exch
+ FontType 11 eq {{1000 div}} {{}} ifelse forall exch
4 index 7 index add 2 div % <vx'> = (<urx> + <llx>) / 2
exch
}{ % assume W2
- {1000 div} forall
+ FontType 11 eq {{1000 div}} {{}} ifelse forall
} ifelse
end % recover currentdict
diff --git a/gs/src/gdevpdtt.c b/gs/src/gdevpdtt.c
index a436309d5..02d180df5 100644
--- a/gs/src/gdevpdtt.c
+++ b/gs/src/gdevpdtt.c
@@ -1841,6 +1841,7 @@ pdf_glyph_widths(pdf_font_resource_t *pdfont, int wmode, gs_glyph glyph,
int code, rcode = 0;
gs_point v;
int allow_cdevproc_callout = (orig_font->FontType == ft_CID_TrueType
+ || orig_font->FontType == ft_CID_encrypted
? GLYPH_INFO_CDEVPROC : 0); /* fixme : allow more font types. */
if (ofont->FontType == ft_composite)
@@ -1987,8 +1988,13 @@ pdf_text_process(gs_text_enum_t *pte)
if (code < 0)
return code;
}
- if (!penum->pte_default)
+ if (!penum->pte_default) {
pdev->charproc_just_accumulated = false;
+ if (penum->cdevproc_callout) {
+ /* Restore after TEXT_PROCESS_CDEVPROC in scan_cmap_text. */
+ penum->current_font = penum->orig_font;
+ }
+ }
code = -1; /* to force default implementation */
/*
diff --git a/gs/src/gdevpdtw.c b/gs/src/gdevpdtw.c
index ee97cd30c..6f5e55613 100644
--- a/gs/src/gdevpdtw.c
+++ b/gs/src/gdevpdtw.c
@@ -250,7 +250,7 @@ pdf_compute_CIDFont_default_widths(const pdf_font_resource_t *pdfont, int wmode,
(*(width < 0 ? &neg_count : &pos_count))++;
}
}
- for (i = 0; i < countof(counts); ++i)
+ for (i = 1; i < countof(counts); ++i)
if (counts[i] > dw_count)
dwi = i, dw_count = counts[i];
*pdw = (neg_count > pos_count ? -dwi : dwi);
@@ -270,7 +270,7 @@ pdf_compute_CIDFont_default_widths(const pdf_font_resource_t *pdfont, int wmode,
}
}
}
- return (dw_count > 0);
+ return (dw_count + counts[0] > 0);
}
/*
@@ -310,13 +310,26 @@ pdf_write_CIDFont_widths(gx_device_pdf *pdev,
psf_enumerate_bits_begin(&genum, NULL, pdfont->used, pdfont->count,
GLYPH_SPACE_INDEX);
{
-
while (!psf_enumerate_glyphs_next(&genum, &glyph)) {
int cid = glyph - GS_MIN_CID_GLYPH;
int width = (int)(w[cid] + 0.5);
+#if 0 /* Must write zero widths - see test file of the bug Bug 687681.
+ We don't enumerate unused glyphs here due to pdfont->used. */
if (width == 0)
continue; /* Don't write for unused glyphs. */
+#else
+ { /* Check whether copied font really have this glyph.
+ debugged with 401-01.ps, which uses undefined CIDs. */
+ gs_font_base *pfont = pdf_font_resource_font(pdfont, false);
+ gs_glyph_info_t info;
+
+ if (pdfont != NULL) {
+ if (pfont->procs.glyph_info((gs_font *)pfont, glyph, NULL, 0, &info) < 0)
+ continue;
+ }
+ }
+#endif
if (cid == prev + 1) {
if (wmode) {
int vx = (int)(pdfont->u.cidfont.v[cid * 2 + 0] + 0.5);
diff --git a/gs/src/gsfont.c b/gs/src/gsfont.c
index 7461af2ed..35f2a4a16 100644
--- a/gs/src/gsfont.c
+++ b/gs/src/gsfont.c
@@ -885,12 +885,17 @@ gs_default_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
int returned = 0;
int code;
int wmode = ((members & GLYPH_INFO_WIDTH1) != 0);
+ double sbw[4] = {0, 0, 0, 0};
+ /* Currently glyph_outline retrieves sbw only with type 1,2,9 fonts. */
+ bool charstrings_font = (font->FontType == ft_encrypted ||
+ font->FontType == ft_encrypted2 ||
+ font->FontType == ft_CID_encrypted);
gx_path_init_bbox_accumulator(&path);
code = gx_path_add_point(&path, fixed_0, fixed_0);
if (code < 0)
goto out;
- code = font->procs.glyph_outline(font, wmode, glyph, pmat, &path);
+ code = font->procs.glyph_outline(font, wmode, glyph, pmat, &path, sbw);
if (code < 0)
goto out;
if (members & GLYPH_INFO_WIDTHS) {
@@ -920,6 +925,28 @@ gs_default_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
info->bbox.q.y = fixed2float(bbox.q.y);
returned |= GLYPH_INFO_BBOX;
}
+ if (members & (GLYPH_INFO_WIDTH0 << wmode) && charstrings_font) {
+ if (pmat == 0) {
+ info->width[wmode].x = sbw[2];
+ info->width[wmode].y = sbw[3];
+ } else {
+ code = gs_distance_transform(sbw[2], sbw[3], pmat, &info->width[wmode]);
+ if (code < 0)
+ return code;
+ }
+ returned |= GLYPH_INFO_WIDTH0 << wmode;
+ }
+ if (members & (GLYPH_INFO_VVECTOR0 << wmode) && charstrings_font) {
+ if (pmat == 0) {
+ info->v.x = sbw[0];
+ info->v.y = sbw[1];
+ } else {
+ gs_distance_transform(sbw[0], sbw[1], pmat, &info->v);
+ if (code < 0)
+ return code;
+ }
+ returned |= GLYPH_INFO_VVECTOR0 << wmode;
+ }
if (members & GLYPH_INFO_NUM_PIECES) {
info->num_pieces = 0;
returned |= GLYPH_INFO_NUM_PIECES;
@@ -933,7 +960,7 @@ gs_default_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
/* Dummy glyph outline procedure */
int
gs_no_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,
- gx_path *ppath)
+ gx_path *ppath, double sbw[4])
{
return_error(gs_error_undefined);
}
diff --git a/gs/src/gstype42.c b/gs/src/gstype42.c
index a30ba641d..3bdb48522 100644
--- a/gs/src/gstype42.c
+++ b/gs/src/gstype42.c
@@ -459,7 +459,7 @@ parse_pieces(gs_font_type42 *pfont, gs_glyph glyph, gs_glyph *pieces,
/* Define the font procedures for a Type 42 font. */
int
gs_type42_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,
- gx_path *ppath)
+ gx_path *ppath, double sbw[4])
{
gs_font_type42 *const pfont = (gs_font_type42 *)font;
uint glyph_index = (glyph >= GS_MIN_GLYPH_INDEX
diff --git a/gs/src/gxfcopy.c b/gs/src/gxfcopy.c
index 04ad6aef6..2cfa1968a 100644
--- a/gs/src/gxfcopy.c
+++ b/gs/src/gxfcopy.c
@@ -672,6 +672,7 @@ copied_build_char(gs_text_enum_t *pte, gs_state *pgs, gs_font *font,
int code;
gs_glyph_info_t info;
double wxy[6];
+ double sbw_stub[4]; /* Currently glyph_outline retrieves sbw only with type 1,2,9 fonts. */
if (glyph == GS_NO_GLYPH) {
glyph = font->procs.encode_char(font, chr, GLYPH_SPACE_INDEX);
@@ -699,7 +700,7 @@ copied_build_char(gs_text_enum_t *pte, gs_state *pgs, gs_font *font,
wxy[5] = info.bbox.q.y;
if ((code = gs_text_setcachedevice(pte, wxy)) < 0 ||
(code = font->procs.glyph_outline(font, wmode, glyph, &ctm_only(pgs),
- pgs->path)) < 0
+ pgs->path, sbw_stub)) < 0
)
return code;
if (font->PaintType != 0) {
@@ -982,7 +983,7 @@ copy_glyph_type1(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
private int
copied_type1_glyph_outline(gs_font *font, int WMode, gs_glyph glyph,
- const gs_matrix *pmat, gx_path *ppath)
+ const gs_matrix *pmat, gx_path *ppath, double sbw[4])
{ /*
* 'WMode' may be inherited from an upper font.
* We ignore in because Type 1,2 charstrings do not depend on it.
@@ -1033,6 +1034,7 @@ copied_type1_glyph_outline(gs_font *font, int WMode, gs_glyph glyph,
return_error(gs_error_rangecheck); /* can't handle it */
case type1_result_sbw: /* [h]sbw, just continue */
pgd = 0;
+ type1_cis_get_metrics(&cis, sbw);
}
}
}
@@ -1511,7 +1513,7 @@ copied_cid0_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
private int
copied_cid0_glyph_outline(gs_font *font, int WMode, gs_glyph glyph,
- const gs_matrix *pmat, gx_path *ppath)
+ const gs_matrix *pmat, gx_path *ppath, double sbw[4])
{
gs_font_type1 *subfont1;
int code = cid0_subfont(font, glyph, &subfont1);
@@ -1519,7 +1521,7 @@ copied_cid0_glyph_outline(gs_font *font, int WMode, gs_glyph glyph,
if (code < 0)
return code;
return subfont1->procs.glyph_outline((gs_font *)subfont1, WMode, glyph, pmat,
- ppath);
+ ppath, sbw);
}
private int
@@ -1556,6 +1558,7 @@ copy_font_cid0(gs_font *font, gs_font *copied)
if (code < 0)
goto fail;
subcopy1 = (gs_font_type1 *)subcopy;
+ subcopy1->data.parent = NULL;
subdata = cf_data(subcopy);
subdata->parent = copied0;
gs_free_object(copied->memory, subdata->Encoding,
diff --git a/gs/src/gxfont.h b/gs/src/gxfont.h
index 582feb83d..b4cc0f61e 100644
--- a/gs/src/gxfont.h
+++ b/gs/src/gxfont.h
@@ -279,10 +279,11 @@ typedef struct gs_font_procs_s {
* because for font descendents it is inherited from an upper font.
* This is especially important for Type 42 fonts with hmtx and vmtx.
*/
+ /* Currently glyph_outline retrieves sbw only with type 1,2,9 fonts. */
#define font_proc_glyph_outline(proc)\
int proc(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,\
- gx_path *ppath)
+ gx_path *ppath, double sbw[4])
font_proc_glyph_outline((*glyph_outline));
/*
@@ -479,4 +480,7 @@ gs_font_base *
*/
bool gs_font_glyph_is_notdef(gs_font_base *bfont, gs_glyph glyph);
+/* Get font parent (a Type 9 font). */
+const gs_font_base *gs_font_parent(const gs_font_base *pbfont);
+
#endif /* gxfont_INCLUDED */
diff --git a/gs/src/gxfont1.h b/gs/src/gxfont1.h
index d10fc6825..a02397ea0 100644
--- a/gs/src/gxfont1.h
+++ b/gs/src/gxfont1.h
@@ -104,6 +104,7 @@ struct gs_type1_data_s {
gs_type1_data_procs_t procs;
charstring_interpret_proc((*interpret));
void *proc_data; /* data for procs */
+ gs_font_base *parent; /* the type 9 font, if this font is is a type 9 descendent. */
int lenIV; /* -1 means no encryption */
/* (undocumented feature!) */
uint subroutineNumberBias; /* added to operand of callsubr */
@@ -150,9 +151,9 @@ struct gs_font_type1_s {
extern_st(st_gs_font_type1);
#define public_st_gs_font_type1() /* in gstype1.c */\
- gs_public_st_suffix_add1_final(st_gs_font_type1, gs_font_type1,\
+ gs_public_st_suffix_add2_final(st_gs_font_type1, gs_font_type1,\
"gs_font_type1", font_type1_enum_ptrs, font_type1_reloc_ptrs,\
- gs_font_finalize, st_gs_font_base, data.proc_data)
+ gs_font_finalize, st_gs_font_base, data.parent, data.proc_data)
/* Export font procedures so they can be called from the interpreter. */
font_proc_glyph_info(gs_type1_glyph_info);
diff --git a/gs/src/gxtype1.c b/gs/src/gxtype1.c
index 0a8286ccb..39b99f1fa 100644
--- a/gs/src/gxtype1.c
+++ b/gs/src/gxtype1.c
@@ -569,3 +569,16 @@ gs_type1_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
gs_glyph_data_free(&gdata, "gs_type1_glyph_info");
return code;
}
+
+/* Get font parent (a Type 9 font). */
+const gs_font_base *
+gs_font_parent(const gs_font_base *pbfont)
+{
+ if (pbfont->FontType == ft_encrypted || pbfont->FontType == ft_encrypted2) {
+ const gs_font_type1 *pfont1 = (const gs_font_type1 *)pbfont;
+
+ if (pfont1->data.parent != NULL)
+ return pfont1->data.parent;
+ }
+ return pbfont;
+} \ No newline at end of file
diff --git a/gs/src/gxtype1.h b/gs/src/gxtype1.h
index 18fdc0afd..e0d85fbef 100644
--- a/gs/src/gxtype1.h
+++ b/gs/src/gxtype1.h
@@ -247,4 +247,7 @@ int gs_type1_seac(gs_type1_state * pcis, const fixed * cstack,
int gs_type1_endchar(gs_type1_state * pcis);
+/* Get the metrics (l.s.b. and width) from the Type 1 interpreter. */
+void type1_cis_get_metrics(const gs_type1_state * pcis, double psbw[4]);
+
#endif /* gxtype1_INCLUDED */
diff --git a/gs/src/ichar1.h b/gs/src/ichar1.h
index 7ab81b9ae..add874f43 100644
--- a/gs/src/ichar1.h
+++ b/gs/src/ichar1.h
@@ -40,7 +40,7 @@ font_proc_glyph_outline(zchar1_glyph_outline);
*/
int zcharstring_outline(gs_font_type1 *pfont, int WMode, const ref *pgref,
const gs_glyph_data_t *pgd,
- const gs_matrix *pmat, gx_path *ppath);
+ const gs_matrix *pmat, gx_path *ppath, double sbw[4]);
int
z1_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
@@ -50,4 +50,7 @@ int z1_glyph_info_generic(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
int members, gs_glyph_info_t *info, font_proc_glyph_info((*proc)),
int wmode);
+z1_set_cache(i_ctx_t *i_ctx_p, gs_font_base *pbfont, ref *cnref,
+ gs_glyph glyph, op_proc_t cont, op_proc_t *exec_cont);
+
#endif /* ichar1_INCLUDED */
diff --git a/gs/src/icharout.h b/gs/src/icharout.h
index 52f5aa30f..5a8ef0939 100644
--- a/gs/src/icharout.h
+++ b/gs/src/icharout.h
@@ -41,6 +41,8 @@ int /*metrics_present*/
int /*metrics_present*/
zchar_get_metrics2(const gs_font_base * pbfont, const ref * pcnref,
double pwv[4]);
+/* Get CDevProc. */
+bool zchar_get_CDevProc(const gs_font_base * pbfont, ref **ppcdevproc);
/*
* Consult Metrics2 and CDevProc, and call setcachedevice[2]. Return
diff --git a/gs/src/zchar.c b/gs/src/zchar.c
index 6e006861f..6571ad612 100644
--- a/gs/src/zchar.c
+++ b/gs/src/zchar.c
@@ -592,7 +592,10 @@ op_show_continue_dispatch(i_ctx_t *i_ctx_p, int npop, int code)
code = zchar42_set_cache(i_ctx_p, (gs_font_base *)pfont42,
&cnref, glyph_index, cont, &exec_cont, false);
- } else
+ } else if (pfont->FontType == ft_CID_encrypted)
+ code = z1_set_cache(i_ctx_p, (gs_font_base *)pfont,
+ &cnref, glyph, cont, &exec_cont);
+ else
return_error(e_unregistered); /* Unimplemented. */
if (exec_cont != 0)
return_error(e_unregistered); /* Must not happen. */
diff --git a/gs/src/zchar1.c b/gs/src/zchar1.c
index 2708cdc98..75ed8cf53 100644
--- a/gs/src/zchar1.c
+++ b/gs/src/zchar1.c
@@ -158,8 +158,6 @@ private int type1_continue_dispatch(i_ctx_t *, gs_type1exec_state *,
const ref *, ref *, int);
private int op_type1_cleanup(i_ctx_t *);
private void op_type1_free(i_ctx_t *);
-private void
- type1_cis_get_metrics(const gs_type1_state * pcis, double psbw[4]);
private int bbox_getsbw_continue(i_ctx_t *);
private int type1exec_bbox(i_ctx_t *, gs_type1exec_state *, gs_font *, op_proc_t *exec_cont);
private int bbox_finish_fill(i_ctx_t *);
@@ -396,7 +394,7 @@ bbox_getsbw_continue(i_ctx_t *i_ctx_p)
type1_cis_get_metrics(pcis, sbw);
bbox = pcxs->char_bbox;
op_type1_free(i_ctx_p);
- code = zchar_set_cache(i_ctx_p, pbfont, op, sbw, sbw + 2, &bbox,
+ code = zchar_set_cache(i_ctx_p, pbfont, op - 1, sbw, sbw + 2, &bbox,
cont, &exec_cont, NULL);
if (code >= 0 && exec_cont != 0)
code = (*exec_cont)(i_ctx_p);
@@ -617,7 +615,7 @@ bbox_stroke(i_ctx_t *i_ctx_p)
/* -------- Common code -------- */
/* Get the metrics (l.s.b. and width) from the Type 1 interpreter. */
-private void
+void
type1_cis_get_metrics(const gs_type1_state * pcis, double psbw[4])
{
psbw[0] = fixed2float(pcis->lsb.x);
@@ -834,7 +832,7 @@ nobbox_finish(i_ctx_t *i_ctx_p, gs_type1exec_state * pcxs)
code = type1exec_bbox(i_ctx_p, pcxs, pfont, &exec_cont);
} else {
cont = (pbfont->PaintType == 0 ? nobbox_fill : nobbox_stroke), exec_cont = 0;
- code = zchar_set_cache(i_ctx_p, pbfont, op, NULL,
+ code = zchar_set_cache(i_ctx_p, pbfont, op - 1, NULL,
pcxs->sbw + 2,
&pcxs->char_bbox,
cont, &exec_cont,
@@ -1008,7 +1006,7 @@ const gs_type1_data_procs_t z1_data_procs = {
*/
int
zchar1_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,
- gx_path *ppath)
+ gx_path *ppath, double sbw[4])
{
gs_font_type1 *const pfont1 = (gs_font_type1 *)font;
ref gref;
@@ -1019,7 +1017,7 @@ zchar1_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *
code = zchar_charstring_data(font, &gref, &gdata);
if (code < 0)
return code;
- return zcharstring_outline(pfont1, WMode, &gref, &gdata, pmat, ppath);
+ return zcharstring_outline(pfont1, WMode, &gref, &gdata, pmat, ppath, sbw);
}
/*
* Get a glyph outline given a CharString. The glyph_outline procedure
@@ -1028,26 +1026,26 @@ zchar1_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *
int
zcharstring_outline(gs_font_type1 *pfont1, int WMode, const ref *pgref,
const gs_glyph_data_t *pgd_orig,
- const gs_matrix *pmat, gx_path *ppath)
+ const gs_matrix *pmat, gx_path *ppath, double sbw[4])
{
const gs_glyph_data_t *pgd = pgd_orig;
int code;
gs_type1exec_state cxs;
gs_type1_state *const pcis = &cxs.cis;
const gs_type1_data *pdata;
- const ref *pfdict;
ref *pcdevproc;
int value;
gs_imager_state gis;
- double sbw[4], wv[4];
+ double wv[4];
gs_point mpt;
pdata = &pfont1->data;
if (pgd->bits.size <= max(pdata->lenIV, 0))
return_error(e_invalidfont);
- pfdict = &pfont_data(pfont1)->dict;
- if (dict_find_string(pfdict, "CDevProc", &pcdevproc) > 0)
+#if 0 /* Ignore CDevProc for now. */
+ if (zchar_get_CDevProc((const gs_font_base *)pfont1, &pcdevproc))
return_error(e_rangecheck); /* can't call CDevProc from here */
+#endif
switch (WMode) {
default:
code = zchar_get_metrics2((gs_font_base *)pfont1, pgref, wv);
@@ -1103,6 +1101,7 @@ icont:
return_error(e_rangecheck); /* can't handle it */
case type1_result_sbw: /* [h]sbw, just continue */
type1_cis_get_metrics(pcis, cxs.sbw);
+ type1_cis_get_metrics(pcis, sbw);
pgd = 0;
goto icont;
}
@@ -1120,7 +1119,6 @@ z1_glyph_info_generic(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
ref gref;
ref *pcdevproc;
gs_font_base *const pbfont = (gs_font_base *)font;
- const ref *pfdict = &pfont_data(pbfont)->dict;
int width_members = members & (GLYPH_INFO_WIDTH0 << wmode);
int outline_widths = members & GLYPH_INFO_OUTLINE_WIDTHS;
bool modified_widths = false;
@@ -1132,7 +1130,7 @@ z1_glyph_info_generic(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
if (!width_members)
return (*proc)(font, glyph, pmat, members, info);
- if (!outline_widths && dict_find_string(pfdict, "CDevProc", &pcdevproc) > 0) {
+ if (!outline_widths && zchar_get_CDevProc(pbfont, &pcdevproc)) {
done_members |= GLYPH_INFO_CDEVPROC;
if (members & GLYPH_INFO_CDEVPROC) {
info->members = done_members;
@@ -1176,7 +1174,7 @@ z1_glyph_info_generic(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
}
if (outline_widths) {
- if (modified_widths || dict_find_string(pfdict, "CDevProc", &pcdevproc) > 0) {
+ if (modified_widths || zchar_get_CDevProc(pbfont, &pcdevproc)) {
/* Discard the modified widths, but indicate they exist. */
width_members |= done_members;
done_members = outline_widths;
@@ -1204,3 +1202,27 @@ z1_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
&gs_type1_glyph_info, wmode);
}
+/* Get a Type 1 or Type 9 character metrics and set the cache device. */
+int
+z1_set_cache(i_ctx_t *i_ctx_p, gs_font_base *pbfont, ref *cnref,
+ gs_glyph glyph, op_proc_t cont, op_proc_t *exec_cont)
+{ /* This function is similar to zchar42_set_cache. */
+ double sbw[4];
+ gs_glyph_info_t info;
+ int wmode = gs_rootfont(igs)->WMode;
+ int code;
+
+ code = gs_default_glyph_info((gs_font *)pbfont, glyph, &pbfont->FontMatrix,
+ ((GLYPH_INFO_WIDTH0 | GLYPH_INFO_VVECTOR0) << wmode) | GLYPH_INFO_BBOX,
+ &info);
+ if (code < 0)
+ return code;
+ sbw[0] = info.v.x;
+ sbw[1] = info.v.y;
+ sbw[2] = info.width[wmode].x;
+ sbw[3] = info.width[wmode].y;
+ return zchar_set_cache(i_ctx_p, pbfont, cnref, NULL,
+ sbw + 2, &info.bbox,
+ cont, exec_cont,
+ wmode ? sbw : NULL);
+}
diff --git a/gs/src/zcharout.c b/gs/src/zcharout.c
index 3ecfcb020..55f154ff8 100644
--- a/gs/src/zcharout.c
+++ b/gs/src/zcharout.c
@@ -78,7 +78,7 @@ int /*metrics_present*/
zchar_get_metrics(const gs_font_base * pbfont, const ref * pcnref,
double psbw[4])
{
- const ref *pfdict = &pfont_data(pbfont)->dict;
+ const ref *pfdict = &pfont_data(gs_font_parent(pbfont))->dict;
ref *pmdict;
if (dict_find_string(pfdict, "Metrics", &pmdict) > 0) {
@@ -122,7 +122,7 @@ int
zchar_get_metrics2(const gs_font_base * pbfont, const ref * pcnref,
double pwv[4])
{
- const ref *pfdict = &pfont_data(pbfont)->dict;
+ const ref *pfdict = &pfont_data(gs_font_parent(pbfont))->dict;
ref *pmdict;
if (dict_find_string(pfdict, "Metrics2", &pmdict) > 0) {
@@ -143,6 +143,17 @@ zchar_get_metrics2(const gs_font_base * pbfont, const ref * pcnref,
}
/*
+ * Get CDevProc.
+ */
+bool
+zchar_get_CDevProc(const gs_font_base * pbfont, ref **ppcdevproc)
+{
+ const ref *pfdict = &pfont_data(gs_font_parent(pbfont))->dict;
+
+ return dict_find_string(pfdict, "CDevProc", ppcdevproc) > 0;
+}
+
+/*
* Consult Metrics2 and CDevProc, and call setcachedevice[2]. Return
* o_push_estack if we had to call a CDevProc, or if we are skipping the
* rendering process (only getting the metrics).
@@ -156,7 +167,6 @@ zchar_set_cache(i_ctx_t *i_ctx_p, const gs_font_base * pbfont,
const double Metrics2_sbw_default[4])
{
os_ptr op = osp;
- const ref *pfdict = &pfont_data(pbfont)->dict;
ref *pcdevproc;
int have_cdevproc;
ref rpop;
@@ -204,7 +214,7 @@ zchar_set_cache(i_ctx_t *i_ctx_p, const gs_font_base * pbfont,
/* Check for CDevProc or "short-circuiting". */
- have_cdevproc = dict_find_string(pfdict, "CDevProc", &pcdevproc) > 0;
+ have_cdevproc = zchar_get_CDevProc(pbfont, &pcdevproc);
if (have_cdevproc || zchar_show_width_only(penum)) {
int i;
op_proc_t zsetc;
diff --git a/gs/src/zfcid0.c b/gs/src/zfcid0.c
index 54a35d4b5..bcff72759 100644
--- a/gs/src/zfcid0.c
+++ b/gs/src/zfcid0.c
@@ -249,7 +249,7 @@ z9_glyph_data(gs_font_base *pbfont, gs_glyph glyph, gs_glyph_data_t *pgd,
/* Get the outline of a CIDFontType 0 glyph. */
private int
z9_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,
- gx_path *ppath)
+ gx_path *ppath, double sbw[4])
{
gs_font_cid0 *const pfcid = (gs_font_cid0 *)font;
ref gref;
@@ -262,11 +262,22 @@ z9_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat
return code;
glyph_ref(font->memory, glyph, &gref);
ocode = zcharstring_outline(pfcid->cidata.FDArray[fidx], WMode, &gref, &gdata,
- pmat, ppath);
+ pmat, ppath, sbw);
gs_glyph_data_free(&gdata, "z9_glyph_outline");
return ocode;
}
+private int
+z9_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
+ int members, gs_glyph_info_t *info)
+{ /* fixme : same as z11_glyph_info. */
+ int wmode = (members & GLYPH_INFO_WIDTH0 ? 0 : 1);
+
+ return z1_glyph_info_generic(font, glyph, pmat, members, info,
+ &gs_default_glyph_info, wmode);
+}
+
+
/*
* The "fonts" in the FDArray don't have access to their outlines -- the
* outlines are always provided externally. Replace the accessor procedures
@@ -352,6 +363,26 @@ fd_array_element(i_ctx_t *i_ctx_p, gs_font_type1 **ppfont, ref *prfd)
return 0;
}
+
+
+private int
+notify_remove_font_type9(void *proc_data, void *event_data)
+{ /* Likely type 9 font descendents are never released explicitly.
+ So releaseing a type 9 font we must reset pointers in descendents.
+ */
+ /* gs_font_finalize passes event_data == NULL, so check it here. */
+ if (event_data == NULL) {
+ gs_font_cid0 *pfcid = proc_data;
+ int i;
+
+ for (i = 0; i < pfcid->cidata.FDArray_size; ++i) {
+ if (pfcid->cidata.FDArray[i]->data.parent == (gs_font_base *)pfcid)
+ pfcid->cidata.FDArray[i]->data.parent = NULL;
+ }
+ }
+ return 0;
+}
+
/* <string|name> <font_dict> .buildfont9 <string|name> <font> */
private int
zbuildfont9(i_ctx_t *i_ctx_p)
@@ -437,6 +468,7 @@ zbuildfont9(i_ctx_t *i_ctx_p)
goto fail;
pfont->procs.enumerate_glyph = gs_font_cid0_enumerate_glyph;
pfont->procs.glyph_outline = z9_glyph_outline;
+ pfont->procs.glyph_info = z9_glyph_info;
pfcid = (gs_font_cid0 *)pfont;
pfcid->cidata.common = common;
pfcid->cidata.CIDMapOffset = CIDMapOffset;
@@ -451,9 +483,13 @@ zbuildfont9(i_ctx_t *i_ctx_p)
ref_assign(&pfont_data(pfont)->u.cid0.GlyphData, &GlyphData);
ref_assign(&pfont_data(pfont)->u.cid0.DataSource, &DataSource);
code = define_gs_font((gs_font *)pfont);
+ if (code >= 0)
+ code = gs_notify_register(&pfont->notify_list, notify_remove_font_type9, pfont);
if (code >= 0) {
- for (i = 0; i < FDArray_size; ++i)
+ for (i = 0; i < FDArray_size; ++i) {
FDArray[i]->dir = pfont->dir;
+ FDArray[i]->data.parent = pfont;
+ }
return code;
}
fail:
diff --git a/gs/src/zfcid1.c b/gs/src/zfcid1.c
index 38c3d300b..6e2a12fab 100644
--- a/gs/src/zfcid1.c
+++ b/gs/src/zfcid1.c
@@ -236,11 +236,11 @@ z11_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph)
private int
z11_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,
- gx_path *ppath)
+ gx_path *ppath, double sbw[4])
{
return gs_type42_glyph_outline(font, WMode,
z11_get_glyph_index((gs_font_type42 *)font, glyph) + GS_MIN_GLYPH_INDEX,
- pmat, ppath);
+ pmat, ppath, sbw);
}
/* ------ Defining ------ */
diff --git a/gs/src/zfont1.c b/gs/src/zfont1.c
index 032b80bbf..2542d7f05 100644
--- a/gs/src/zfont1.c
+++ b/gs/src/zfont1.c
@@ -201,6 +201,7 @@ charstring_font_init(gs_font_type1 *pfont, const charstring_font_refs_t *pfr,
pdata = pfont_data(pfont);
pfont->data = *pdata1;
+ pfont->data.parent = NULL;
ref_assign(&pdata->u.type1.OtherSubrs, pfr->OtherSubrs);
ref_assign(&pdata->u.type1.Subrs, pfr->Subrs);
ref_assign(&pdata->u.type1.GlobalSubrs, pfr->GlobalSubrs);
diff --git a/gs/src/zfont42.c b/gs/src/zfont42.c
index fb58bc6b7..efbe844ec 100644
--- a/gs/src/zfont42.c
+++ b/gs/src/zfont42.c
@@ -339,10 +339,10 @@ z42_encode_char(gs_font *font, gs_char chr, gs_glyph_space_t glyph_space)
}
private int
z42_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,
- gx_path *ppath)
+ gx_path *ppath, double sbw[4])
{
return gs_type42_glyph_outline(font, WMode, glyph_to_index(font, glyph),
- pmat, ppath);
+ pmat, ppath, sbw);
}
private int
z42_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,