I'm not sure if this is the appropriate place for this question but
I'll ask anyway. Please re-direct me if I'm in the wrong place.
I was thinking of using ghostscript from a Perl program to calculate
the length of strings (for determining text justification, wrapping,
etc). However, it seems that the length is dependent on the output
device I choose. For example :
stbaldwin@au-stb-mobile:~/dev$ gs -sDEVICE=nullpage
GPL Ghostscript SVN PRE-RELEASE 8.61 (2007-08-02)
Copyright (C) 2007 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>/F { findfont exch scalefont setfont } bind def
GS>32 /Myriad F
Loading Myriad font from /usr/share/ghostscript/fonts/MyriadPro-
SemiCn.otf... 2609680 1150401 2092096 801688 1 done.
Using MyriadPro-SemiCn font for Myriad.
GS>(AWAY) stringwidth == ==
-0.0
76.890625
GS>stbaldwin@au-stb-mobile:~/dev$ gs -sDEVICE=x11
GPL Ghostscript SVN PRE-RELEASE 8.61 (2007-08-02)
Copyright (C) 2007 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>/F { findfont exch scalefont setfont } bind def
GS>32 /Myriad F
Loading Myriad font from /usr/share/ghostscript/fonts/MyriadPro-
SemiCn.otf... 2852000 1227522 2317688 1015991 1 done.
Using MyriadPro-SemiCn font for Myriad.
GS>(AWAY) stringwidth == ==
-0.0
76.8841095
GS>stbaldwin@au-stb-mobile:~/dev$ gs -sDEVICE=pswrite -sOutputFile=/
dev/null
GPL Ghostscript SVN PRE-RELEASE 8.61 (2007-08-02)
Copyright (C) 2007 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>/F { findfont exch scalefont setfont } bind def
GS>/F { findfont exch scalefont setfont } bind def
GS>32 /Myriad F
Loading Myriad font from /usr/share/ghostscript/fonts/MyriadPro-
SemiCn.otf... 2857588 1231589 2383880 1084299 1 done.
Using MyriadPro-SemiCn font for Myriad.
GS>(AWAY) stringwidth == ==
0.0
76.8953094
I realise the difference is small, but I don't understand why there is
any difference. Can someone please enlighten me?
Thanks,
Steve
> I realise the difference is small, but I don't understand why there is
> any difference. Can someone please enlighten me?
Looks like rounding errors to me. The different devices probably set up
different matrices to map to the output device. While its true that
stringwidth operates in user space, hinting of glyphs can result in very
small differences in the shape of glyphs depending on the precise
location of the pixels representing the glyphs.
GS, like all the PostScript interpreters I know enough about to be sure
of, uses a fixed-point representation for performance reasons. Rounding
errors are not uncommon, though they should be small.
Ken
Thanks for the reply Ken. I thought that may have been the reason.
I have also been looking at calculating the width of a string myself by
extracting the appropriate bits out of the (opentype) font file. I think
I've worked out how to obtain the glyph widths (from the hmtx->advance
structure), but these are in "font design units". How do I convert from
these into real world units (e.g. points like postscript). I realise the
point size of the font has something to do with it, but I'm missing a key
piece of the puzzle. Can anyone point me in the right direction?
Thanks,
Steve
> I have also been looking at calculating the width of a string myself by
> extracting the appropriate bits out of the (opentype) font file.
Yes, I saw your post in comp.fonts.
> I think
> I've worked out how to obtain the glyph widths (from the hmtx->advance
> structure), but these are in "font design units". How do I convert from
> these into real world units (e.g. points like postscript). I realise the
> point size of the font has something to do with it, but I'm missing a key
> piece of the puzzle. Can anyone point me in the right direction?
In PostScript fonts exist in their own space, a bit like user space.
This space is scaled so that the font design space (typically 1000x1000
for type 1 fonts) is 1 unit in user space. When you create an instance
of a font, using setfont or similar, you create a font whose FontMatrix
incorporates the scale from 1-unit user space to the desired size.
So 12 scalefont will rsult in a FontMatrix [12 0 0 12 0 0].
So what you really need is the mapping from design space, which is given
somewhere in the TrueType spec. Hmm, the OpenType spec, page 74 onwards
discusses this in some depth. However what I think you need is the
'unitsPerEm' field in the 'head' table.
Say that you have a typical font with unitsPerEm = 2048. You have a
glyph whose advance value is 512. When scaled to user space the glyph
will occupy one quarter of a unit in user space. If the font is then
scaled to 12 point, the glyph will occupy 3 points horizontally.
Of course there is a further calculation when it comes to output,
because we need to take the resolution of the device into account. So at
300 dpi, the glyph will occupy (300 / 72) * 3 = 12.5 pixels. We can't
really have half pixels, so normally this would be promoted to 13.
However, with glyphs this becomes more complicated, because of hinting
and (in the case of TrueType) grid fitting.
I would have guessed you wouldn't want to worry about that, but an error
in the second decimal place of GS's stringwidth does seem to cause you
concern, so perhaps I'm wrong.
Ken
I tried this with a Type3 font (they do not support hinting) and still
saw a difference of of about .004 points with different output devices
and gs.
Sending the same file to an Adobe RIP with 2 different HWResolutions
produced a difference from gs but identical numbers at 600 and 1200
dpi.
As it's in user space wouldn't this be a "bug" in gs?
Ed
% font omitted
<<
/HWResolution [ 600 600 ]
>> setpagedevice
/F { findfont exch scalefont setfont } bind def
12 /CourierC F
72 72 moveto
(AWAY) stringwidth dup == ( ) cvs show ( ) show
dup ( ) cvs show ==
showpage
> I tried this with a Type3 font (they do not support hinting) and still
> saw a difference of of about .004 points with different output devices
> and gs.
GS has a grid fitting algorithm which (I believe) applies to all font
types. You may need to turn this off. There is a way to do it, I just
can't remember off-hand how and its getting late.
> Sending the same file to an Adobe RIP with 2 different HWResolutions
> produced a difference from gs but identical numbers at 600 and 1200
> dpi.
> As it's in user space wouldn't this be a "bug" in gs?
Like I said, fotns are a bit different, grid-fitting and hinting can
make the actual shape of the glyph slightly different depending on the
resolution. This is unlikely to make any difference at 600 dpi and above
though, so you could always try runnning at high resolution and see what
happens.
If you still think its a bug then by all means report it as such.
Ken
> Like I said, fotns are a bit different, grid-fitting and hinting can
> make the actual shape of the glyph slightly different depending on the
> resolution. This is unlikely to make any difference at 600 dpi and above
> though, so you could always try runnning at high resolution and see what
> happens.
I sent PS above with the setpagedevice back to gs and then got the
same
values from stringwidth with diffent gs devices. Setting the gs flag
-r600x600 may do the same. This may be a solution for the original
poster's problem.
Ed