[gs-devel] Fix for gs_ttf.ps to handle fonts with overlapping CMap 4 ranges

Anthony Fok anthony at thizlinux.com
Wed Sep 11 20:52:59 PDT 2002


On Wed, Sep 11, 2002 at 05:01:01PM +0400, Igor V. Melichev wrote:
> Dear Anthony Fok,
> 
> Thank you for your contribution to Ghostscript.
> For accommodating your patch I'd like to know which fonts
> require it. Could you please sent me a font example and a test document ?
> 
> Igor.

Dear Igor,

The font in question is Arphic's latest HKSCS-2001 TrueType font
BMIN00L.TTF.  However, note that overlapping CMap 4 ranges is found in
quite a few other CJK fonts too, as FreeType noted that fact specifically
in a comment, and skipped one of the stricter validation test because
of that.  The following is my earlier analysis of the problem:

	http://www.freetype.org/pipermail/freetype/2002-July/002428.html

Back then, I didn't know enough about PostScript programming to
actually debug gs_ttf.ps myself.  Also, I was rightly adviced that I
shouldn't have distributed the font at all especially without prior
permission from Arphic.  My action could have compromised the Free
Software community and Artifex's integrity too.  So, I pulled the font
from the web, and offered a public apology:

	http://www.freetype.org/pipermail/freetype/2002-July/002432.html

So, for all parties' interest, I'd rather not give you the font unless
explicit permission is obtained from Arphic.  Instead, I'll provide you
with pre-rendered PostScript files (i.e. the output from ps2ps), log
files, debug files, and my analysis.  :-)  You may find these files
here:

	http://anthony.homelinux.net/~foka/gs/

Source PostScript file: all_ac1.ps (with the font and range changed)

Pre-rendered PS files:
   all_ac1_minguni-good.ps.gz  (Good output using MING_UNI.TTF)
   all_ac1_bmin00l-bad.ps.gz   (with BMIN00L.TTF, before patching gs_ttf.ps)
   all_ac1_bmin00l-good.ps.gz  (after patching gs_ttf.ps)

Logs (from running "gs -sDEBUG all_ac1.ps"):
   all_ac1_bmin00l-bad.log.gz
   all_ac1_bmin00l-good.log.gz

Comparing the two files, you'll notice that the resulting CMap 4
array (the very long line at the end: [0 0 0 .... 0 533]) differ.
To compare, I used fonttools to generate bmin00l.ttx.gz and extracted
the resulting CMap 4 array, and did the same with
all_ac1_bmin00l-{bad,good}.log.  This results in:

	cmap4-bmin00l-from-fonttools.txt
	cmap4-bmin00l-from-gs-bad.txt	(before my patch)
	cmap4-bmin00l-from-gs-good.txt	(after my patch)

I feel more confident that my patch works when I checked today that
cmap4-bmin00l-from-fonttools.txt and cmap4-bmin00l-from-gs-good.txt are
identical.  :-)

In the unpatched gs_ttf.ps, it was implicitly assumed that
scode[i] will never be less than or equal to ecode[i-1]:

    /putglyph {
      glyphs code 3 -1 roll put /code code 1 add def
    } bind def

and

    numcodes scode firstcode sub
    exch sub 0 .max dup { 0 putglyph } repeat

Here, "code" is always incremented.  So, for example:

scode=62211 ecode=62842 delta=21241 droff=0
scode=62842 ecode=62884 delta=21241 droff=0

Here, both ecode[i-1] and scode[i] are 62842 (U+F57A), i.e. an overlap.
Unfortunately, "code" is already incremented, resulting in incorrect
array:

	        Wrong	Right
	U+F57A: 18547	18547
	U+F57B: 18547	18548
	U+F57C: 18548	18549
	U+F57D: 18549	18550
	U+F57E: 18550	18551
	U+F57F: 18551	18552
	.....

So, intead of throwing away negative results of "numcodes scode
firstcode sub exch sub", we should instead keep the negative number and
use it to decrement "code":

      numcodes scode firstcode sub
      exch sub dup dup 0 ge { %ifelse
        { 0 putglyph } repeat
      } { %else
        code add /code exch def
      } ifelse

And yes, of course, my patch is under the same license as the original
gs_ttf.ps .  :-)

Cheers,

Anthony

-- 
Anthony Fok Tung-Ling
ThizLinux Laboratory   <anthony at thizlinux.com> http://www.thizlinux.com/
Debian Chinese Project <foka at debian.org>       http://www.debian.org/intl/zh/
Come visit Our Lady of Victory Camp!           http://www.olvc.ab.ca/



More information about the gs-devel mailing list