[gs-devel] Re: [gs-cvs] rev 7815 - trunk/gs/src
SaGS
sags5495 at hotmail.com
Mon Apr 2 01:31:02 PDT 2007
----- Original Message -----
From: <leonardo at ghostscript.com>
To: <gs-cvs at ghostscript.com>
Sent: Monday, 02 April 2007 00:46
Subject: [gs-cvs] rev 7815 - trunk/gs/src
> Author: leonardo
> Date: 2007-04-01 14:46:50 -0700 (Sun, 01 Apr 2007)
> New Revision: 7815
>
> Modified:
> trunk/gs/src/gdevpdtc.c
> Log:
> Fix (pdfwrite) : a composite font with a Type 3 descendent and FMapType 2
> ...
> Modified: trunk/gs/src/gdevpdtc.c
> ===================================================================
> --- trunk/gs/src/gdevpdtc.c 2007-04-01 19:14:49 UTC (rev 7814)
> +++ trunk/gs/src/gdevpdtc.c 2007-04-01 21:46:50 UTC (rev 7815)
> ...
> code = pdf_process_string_aux(&out, &str, NULL, &fmat, &text_state);
> if (code < 0)
> return code;
> curr.xy_index = out.xy_index; /* pdf_encode_process_string advanced
> it. */
> - gs_text_enum_copy_dynamic(pte, (gs_text_enum_t *)&prev, true);
> + pte->xy_index = out.xy_index;
> + if (out.index < str.size) {
> ...
> + } else
> + /* advance *pte past the current substring */
> + gs_text_enum_copy_dynamic(pte, (gs_text_enum_t *)&prev, true);
> if (return_width) {
> ...
Dear Leonardo,
You moved the "pte->xy_index = out.xy_index", but it's not correct. The call
to "gs_text_enum_copy_dynamic()" will overwrite the value with an incorrect
one. That's why in my patch the assignement to "pte->xy_index" is done after
the "if".
I don't think you can see the adverse effect in any of the samples attached
to the bug reports, because most create Type 0 fonts with a single
descendent. IIRC only the ones for bug #689041 "Japanese Font Display
Problem is ps2pdf" have more than one descendent, but those don't use xshow.
Case that doesn't work with the commited patch:
- Type 0 font with 2 Type 3 descendents;
- xshow operation;
- the xshow string contains same chars from 1st descendent, then some from
2nd descendent;
- all chars in the 1st substring are already accumulated, but the 1st one
from the 2nd substring is not.
[Cannot test this right now, but I'll do if you'll consider necessary.]
Then here's what happens:
- 1st substring is processed, "pte->xy_index = out.xy_index" advances
".xy_index" OK;
- the code takes the "/* advance *pte past the current substring */" branch
and "gs_text_enum_copy_dynamic()" overwrites "pte->xy_index" with an
incorrect value (moves it back to the beginning of the whole string);
- the 2nd substring is copied into the buffer;
- the call to "pdf_process_string_aux()" returns -21 because the 1st char
[in the substring it received] is not accumulated; the return code is
different from the case when it processes at least one character;
- "process_composite_text()" returns immediately because of "if (code < 0)
return code;", with the wrong "pte->xy_index";
- the char in question is accumulated;
- "process_composite_text()" is called again, and it will reuse widths from
the beginning of the widths array for chars in the 2nd substring.
To test, I would insert some "xshow" in the sample from bug #689041, like
"(LATIN) show % force them to be accumulated
(LATINjapanese) ... xshow"
More information about the gs-devel
mailing list