I got original ttf2fft source from ming web site. this original ttf2fft version is 1.0. The original ttf2fft require under Freetype 2.0.9. so I wrote this patch to compile with Freetype2.2.1.
But I don't test kerning table conversion. Please use this patch at your own risk.
http://reddog.s35.xrea.com/software/ttf2fft.zip
diff -uNr ttf2fft_old/ttf2fft.cxx ttf2fft/ttf2fft.cxx --- ttf2fft_old/ttf2fft.cxx Sun Jan 11 03:49:11 2004 +++ ttf2fft/ttf2fft.cxx Wed Feb 28 20:54:12 2007 @@ -57,7 +57,7 @@ #include FT_CACHE_CHARMAP_H #include <freetype/ftoutln.h> #include <freetype/ftbbox.h> -#include <freetype/internal/tttypes.h> +//#include <freetype/internal/tttypes.h> #include <freetype/ttnameid.h> #include <stdio.h> @@ -477,21 +477,21 @@ static double ratio_EM; -int Outline_MoveTo_Func( FT_Vector * to, void * user ) { +int Outline_MoveTo_Func(const FT_Vector * to, void * user ) { Shape* shape = (Shape*) user; //printf(" moveTo(%d, %d)\n", to->x, to->y); shape->movePenTo((int)(to->x*ratio_EM), -(int)(to->y*ratio_EM)); return 0; } -static int Outline_LineTo_Func( FT_Vector * to, void * user ) { +static int Outline_LineTo_Func(const FT_Vector * to, void * user ) { Shape* shape = (Shape*) user; //printf(" lineTo(%d, %d)\n", to->x, to->y); shape->drawLineTo((int)(to->x*ratio_EM), -(int)(to->y*ratio_EM)); return 0; } -static int Outline_ConicTo_Func( FT_Vector* ctrl, FT_Vector * to, void * user ) { +static int Outline_ConicTo_Func(const FT_Vector* ctrl,const FT_Vector * to, void * user ) { Shape* shape = (Shape*) user; //printf(" conicTo(%d, %d, %d, %d)\n",ctrl->x, ctrl->y, to->x, to->y); shape->drawCurveTo((int)(ctrl->x*ratio_EM), -(int)(ctrl->y*ratio_EM), @@ -499,7 +499,7 @@ return 0; } -static int Outline_CubicTo_Func( FT_Vector* ctrl1, FT_Vector* ctrl2, FT_Vector * to, void * user ) { +static int Outline_CubicTo_Func(const FT_Vector* ctrl1,const FT_Vector* ctrl2,const FT_Vector * to, void * user ) { Shape* shape = (Shape*) user; //printf(" CUBICTo(%d, %d, %d, %d)\n",ctrl1->x, ctrl1->y, to->x, to->y); return 1; @@ -721,45 +721,42 @@ // probably we need to restrict writing only to codes from codetable if( FT_HAS_KERNING(face) && FT_IS_SFNT(face) ) { - printf(" writing kerning table\n"); - TT_Face ttface = (TT_Face) face; - int nKern = ttface->num_kern_pairs; - - int* kern_table = new int[nKern*3]; + Vector<int> ktable; - int sz = 0; - for( int i=0; i<nKern; i++ ) { - TT_Kern0_Pair pair = ttface->kern_pairs + i; - int left_idx = pair->left; - int right_idx = pair->right; - int value = (int) (pair->value*ratio_EM); - if( value == 0 ) continue; - //printf( "left: %d, right: %d, value: %d\n", left_idx, right_idx, value); - - int left_code = -1; - for( int k=0; k<indexes.size(); k++ ) { - if( indexes.elementAt(k) == left_idx ) { - left_code = codetable.elementAt(k); - break; - } - } - if( left_code < 0 ) continue; - - int right_code = -1; - for( int k=0; k<indexes.size(); k++ ) { - if( indexes.elementAt(k) == right_idx ) { - right_code = codetable.elementAt(k); - break; - } - } - if( right_code < 0 ) continue; - - kern_table[sz++] = left_code; - kern_table[sz++] = right_code; - kern_table[sz++] = value; - } - - nKern = sz/3; + printf(" writing kerning table\n"); + for( int n=0; n<indexes.size(); n++ ) { + int left = indexes.elementAt(n); + int right; + FT_Vector delta; + + if (left < 0) continue; + + for( int m=0; m<indexes.size(); m++ ) { + right = indexes.elementAt(m); + + if (right < 0) continue; + + if (FT_Get_Kerning(face, left, right, 0, &delta) == 0) { + if (delta.x != 0) break; + } else { + break; + } + } + if (delta.x == 0 || !error) continue; + + ktable.addElement(left); + ktable.addElement(right); + ktable.addElement((int)(delta.x * ratio_EM)); + } + + int sz = ktable.size(); + int nKern = sz/3; + int* kern_table = new int[sz]; + for (int j=0; j<ktable.size();) { + kern_table[j] = ktable.elementAt(j); j++; + kern_table[j] = ktable.elementAt(j); j++; + kern_table[j] = ktable.elementAt(j); j++; + } fob->writeWord( nKern ); for( int j=0; j<nKern; j++ ) {