[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