[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ft] Reading KERN subtables
From: |
Alex Taylor |
Subject: |
[ft] Reading KERN subtables |
Date: |
Wed, 21 Aug 2013 19:46:19 -0400 (EDT) |
User-agent: |
PMMail/3.08 (os/2; U; Warp 4.5; en-CA; i386; ver 3.08.70.1660) |
Three dumb (?) questions related to parsing the TrueType KERN table...
For a couple of my projects, I need to retrieve a list of all kerning pairs
defined in the KERN table (subtable format 0). (I'm populating
externally-defined API data structures which require it.)
Since this information doesn't seem to be directly provided by FreeType,
I've been working on some functions to get the information out of the KERN
table. I got some hints from the old FreeType v1 'ftxkern' extension
source, but it wasn't feasible to adapt it directly.
I've written a routine which seems to work in the (usual) case that the
format 0 subtable is the first (or only) kerning subtable present.
However, I'm not at all sure if the logic to read subtables other than the
first is watertight. I need to test this logic; unfortunately, I can't
find any fonts which have multiple kerning subtables. If anyone knows
where I can find a sample of such a (TrueType) font, I'd appreciate it.
(That's question #1.)
My logic for seeking a format 0 subtable is:
FX_Kerning *pKern; // These structures are basically
FX_Kerning_Subtable *pKST; // taken from the old 'ftxkern'
FX_Kern_0 *pKD; // extension & renamed
...
pKST = (FX_Kerning_Subtable *)(pKern->tables);
pKST->version = SWAP_SHORT( pKST->version ); // fix the byte order
pKST->length = SWAP_SHORT( pKST->length );
while ( pKST->format != 0 ) {
pKST = (PVOID)(pKST + pKST->length);
pKST->version = SWAP_SHORT( pKST->version );
pKST->length = SWAP_SHORT( pKST->length );
sub_index++;
}
However, I found something odd when examining the font 'Constantia Regular'
(CONSTAN.TTF) v5.90. It shows a single kerning subtable, format 0, with
36740 kerning pairs. But each pair occupies 6 bytes, meaning the total
subtable size is over 200KB -- much too large for the unsigned short
'length' field in the subtable header. Indeed, the 'length' field shows a
value of around 23KB, which is obviously bogus. So my second question is,
what is the correct way of coping with this scenario? (And is this a buggy
font, or have I made a mistake somewhere?)
Finally, looking at how the old ftxkern extension did this, it appears very
strange to me. It defines
TT_Kern_Subtable* tables;
in the kerning directory. It then seemingly treats 'tables' as an array of
fixed-size elements, e.g.:
TT_Kern_Subtable* sub;
...
sub = kern->tables + kern_index;
where kern_index is the desired subtable number. How can this possibly
work? If I read the OTF spec correctly, each subtable may be a different
length - containing not only a variable-format header, but the kerning data
itself, which is of arbitrary size. Am I just obtuse, or missing
something?
If someone(s) could shed some light on these questions, I'd appreciate
it...
Thanks
--
Alex Taylor <address@hidden>
http://www.altsan.org
- [ft] Reading KERN subtables,
Alex Taylor <=