[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