* src/base/ftpfr.c, src/pfr/pfrtypes.h, src/pfr/pfrload.c,

src/pfr/pfrobjs.c: fixing PFR kerning support. The tables within
        the font file contain (charcode,charcode) kerning pairs, we need
        to convert them to (gindex,gindex) !

        * include/freetype/ftoption.h: commenting out the macro
        TT_CONFIG_OPTION_BYTECODE_INTERPRETER
This commit is contained in:
David Turner 2003-09-09 20:11:56 +00:00
parent 4748730ac6
commit b0b1ea3fea
6 changed files with 175 additions and 151 deletions

View File

@ -1,3 +1,13 @@
2003-09-09 David Turner <david@freetype.org>
* src/base/ftpfr.c, src/pfr/pfrtypes.h, src/pfr/pfrload.c,
src/pfr/pfrobjs.c: fixing PFR kerning support. The tables within
the font file contain (charcode,charcode) kerning pairs, we need
to convert them to (gindex,gindex) !
* include/freetype/ftoption.h: commenting out the macro
TT_CONFIG_OPTION_BYTECODE_INTERPRETER
2003-08-31 Manish Singh <yosh@gimp.org>
* src/bdf/bdflib.c (_bdf_readstream): Don't use FT_MEM_COPY but

View File

@ -399,7 +399,7 @@ FT_BEGIN_HEADER
/* Do not #undef this macro here, since the build system might */
/* define it for certain configurations only. */
/* */
#undef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
/* #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
/*************************************************************************/

View File

@ -37,7 +37,7 @@
if ( name[0] == 'p' &&
name[1] == 'f' &&
name[2] == 'r' &&
name[4] == 0 )
name[3] == 0 )
{
*aservice = (FT_PFR_Service) module->clazz->module_interface;
error = 0;

View File

@ -511,89 +511,6 @@
}
#if 0
/* load kerning pair data */
FT_CALLBACK_DEF( FT_Error )
pfr_extra_item_load_kerning_pairs( FT_Byte* p,
FT_Byte* limit,
PFR_PhyFont phy_font )
{
FT_Int count;
FT_UShort base_adj;
FT_UInt flags;
FT_UInt num_pairs;
PFR_KernPair pairs;
FT_Error error = 0;
FT_Memory memory = phy_font->memory;
/* allocate a new kerning item */
/* XXX: there may be multiple extra items for kerning */
if ( phy_font->kern_pairs != NULL )
goto Exit;
FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" ));
PFR_CHECK( 4 );
num_pairs = PFR_NEXT_BYTE( p );
base_adj = PFR_NEXT_SHORT( p );
flags = PFR_NEXT_BYTE( p );
#ifndef PFR_CONFIG_NO_CHECKS
count = 3;
if ( flags & PFR_KERN_2BYTE_CHAR )
count += 2;
if ( flags & PFR_KERN_2BYTE_ADJ )
count += 1;
PFR_CHECK( num_pairs * count );
#endif
if ( FT_NEW_ARRAY( pairs, num_pairs ) )
goto Exit;
phy_font->num_kern_pairs = num_pairs;
phy_font->kern_pairs = pairs;
for (count = num_pairs ; count > 0; count--, pairs++ )
{
if ( flags & PFR_KERN_2BYTE_CHAR )
{
pairs->glyph1 = PFR_NEXT_USHORT( p );
pairs->glyph2 = PFR_NEXT_USHORT( p );
}
else
{
pairs->glyph1 = PFR_NEXT_BYTE( p );
pairs->glyph2 = PFR_NEXT_BYTE( p );
}
if ( flags & PFR_KERN_2BYTE_ADJ )
pairs->kerning.x = base_adj + PFR_NEXT_SHORT( p );
else
pairs->kerning.x = base_adj + PFR_NEXT_INT8( p );
pairs->kerning.y = 0;
FT_TRACE2(( "kerning %d <-> %d : %ld\n",
pairs->glyph1, pairs->glyph2, pairs->kerning.x ));
}
Exit:
return error;
Too_Short:
error = PFR_Err_Invalid_Table;
FT_ERROR(( "pfr_extra_item_load_kerning_pairs: "
"invalid kerning pairs table\n" ));
goto Exit;
}
#else /* 0 */
/* load kerning pair data */
FT_CALLBACK_DEF( FT_Error )
@ -690,7 +607,139 @@
"invalid kerning pairs table\n" ));
goto Exit;
}
#endif /* 0 */
/* the kerning data embedded in a PFR font are (charcode,charcode)
* pairs, we need to translate them to (gindex,gindex) and sort
* the resulting array
*/
static FT_UInt
pfr_get_gindex( PFR_Char chars,
FT_UInt count,
FT_UInt charcode )
{
FT_UInt min = 0;
FT_UInt max = count;
while ( min < max )
{
FT_UInt mid = (min+max) >> 1;
PFR_Char c = chars + mid;
if ( c->char_code == charcode )
return mid + 1;
if ( c->char_code < charcode )
min = mid + 1;
else
max = mid;
}
return 0;
}
FT_CALLBACK_DEF( int )
pfr_compare_kern_pairs( const void* pair1,
const void* pair2 )
{
FT_UInt32 p1 = PFR_KERN_PAIR_INDEX( (PFR_KernPair)pair1 );
FT_UInt32 p2 = PFR_KERN_PAIR_INDEX( (PFR_KernPair)pair2 );
if ( p1 < p2 )
return -1;
if ( p1 > p2 )
return 1;
return 0;
}
static FT_Error
pfr_sort_kerning_pairs( FT_Stream stream,
PFR_PhyFont phy_font )
{
FT_Error error;
FT_Memory memory = stream->memory;
PFR_KernPair pairs;
PFR_KernItem item;
PFR_Char chars = phy_font->chars;
FT_UInt num_chars = phy_font->num_chars;
FT_UInt count;
/* create kerning pairs array
*/
if ( FT_NEW_ARRAY( phy_font->kern_pairs, phy_font->num_kern_pairs ) )
goto Exit;
/* load all kerning items into the array,
* converting character codes into glyph indices
*/
pairs = phy_font->kern_pairs;
item = phy_font->kern_items;
count = 0;
for ( ; item; item = item->next )
{
FT_UInt limit = count + item->pair_count;
FT_Byte* p;
if ( limit > phy_font->num_kern_pairs )
{
error = PFR_Err_Invalid_Table;
goto Exit;
}
if ( FT_STREAM_SEEK( item->offset ) ||
FT_FRAME_ENTER( item->pair_count * item->pair_size ) )
goto Exit;
p = stream->cursor;
for ( ; count < limit; count++ )
{
PFR_KernPair pair = pairs + count;
FT_UInt char1, char2;
FT_Int kerning;
if ( item->flags & PFR_KERN_2BYTE_CHAR )
{
char1 = FT_NEXT_USHORT( p );
char2 = FT_NEXT_USHORT( p );
}
else
{
char1 = FT_NEXT_BYTE( p );
char2 = FT_NEXT_BYTE( p );
}
if ( item->flags & PFR_KERN_2BYTE_ADJ )
kerning = item->base_adj + FT_NEXT_SHORT( p );
else
kerning = item->base_adj + FT_NEXT_CHAR( p );
pair->glyph1 = pfr_get_gindex( chars, num_chars, char1 );
pair->glyph2 = pfr_get_gindex( chars, num_chars, char2 );
pair->kerning = kerning;
}
FT_FRAME_EXIT();
}
/* sort the resulting array
*/
ft_qsort( pairs, count,
sizeof ( PFR_KernPairRec ),
pfr_compare_kern_pairs );
Exit:
if ( error )
{
/* disable kerning data in case of error
*/
phy_font->num_kern_pairs = 0;
}
return error;
}
static const PFR_ExtraItemRec pfr_phy_font_extra_items[] =
@ -770,6 +819,7 @@
FT_FREE( phy_font->blue_values );
phy_font->num_blue_values = 0;
FT_FREE( phy_font->kern_pairs );
{
PFR_KernItem item, next;
@ -1008,6 +1058,9 @@
phy_font->bct_offset = FT_STREAM_POS();
phy_font->cursor = NULL;
/* now sort kerning pairs */
error = pfr_sort_kerning_pairs( stream, phy_font );
Exit:
return error;

View File

@ -419,77 +419,34 @@
{
FT_Error error = PFR_Err_Ok;
PFR_PhyFont phy_font = &face->phy_font;
PFR_KernItem item = phy_font->kern_items;
PFR_KernPair pairs = phy_font->kern_pairs;
FT_UInt32 idx = PFR_KERN_INDEX( glyph1, glyph2 );
FT_UInt min, max;
FT_UNUSED( error ); /* just needed as syntactical sugar */
kerning->x = 0;
kerning->y = 0;
/* find the kerning item containing our pair */
while ( item )
min = 0;
max = phy_font->num_kern_pairs;
while ( min < max )
{
if ( item->pair1 <= idx && idx <= item->pair2 )
goto Found_Item;
item = item->next;
}
/* not found */
return;
Found_Item:
{
/* perform simply binary search within the item */
FT_UInt min, mid, max;
FT_Stream stream = face->root.stream;
FT_Byte* p;
if ( FT_STREAM_SEEK( item->offset ) ||
FT_FRAME_ENTER( item->pair_count * item->pair_size ) )
return;
min = 0;
max = item->pair_count;
while ( min < max )
FT_UInt mid = (min+max) >> 1;
PFR_KernPair pair = pairs + mid;
FT_UInt32 pidx = PFR_KERN_PAIR_INDEX( pair );
if ( pidx == idx )
{
FT_UInt char1, char2, charcode;
mid = ( min + max ) >> 1;
p = stream->cursor + mid*item->pair_size;
if ( item->flags & PFR_KERN_2BYTE_CHAR )
{
char1 = FT_NEXT_USHORT( p );
char2 = FT_NEXT_USHORT( p );
}
else
{
char1 = FT_NEXT_USHORT( p );
char2 = FT_NEXT_USHORT( p );
}
charcode = PFR_KERN_INDEX( char1, char2 );
if ( idx == charcode )
{
if ( item->flags & PFR_KERN_2BYTE_ADJ )
kerning->x = item->base_adj + FT_NEXT_SHORT( p );
else
kerning->x = item->base_adj + FT_NEXT_CHAR( p );
break;
}
if ( idx > charcode )
min = mid + 1;
else
max = mid;
kerning->x = pair->kerning;
break;
}
FT_FRAME_EXIT();
if ( pidx < idx )
min = mid+1;
else
max = mid;
}
}

View File

@ -209,11 +209,14 @@ FT_BEGIN_HEADER
#define PFR_KERN_INDEX( g1, g2 ) \
( ( (FT_UInt32)(g1) << 16 ) | (FT_UInt16)(g2) )
#define PFR_KERN_PAIR_INDEX( pair ) \
PFR_KERN_INDEX( (pair)->glyph1, (pair)->glyph2 )
typedef struct PFR_KernPairRec_
{
FT_UInt glyph1;
FT_UInt glyph2;
FT_Vector kerning;
FT_Int kerning;
} PFR_KernPairRec, *PFR_KernPair;
@ -230,7 +233,7 @@ FT_BEGIN_HEADER
FT_BBox bbox;
FT_UInt flags;
FT_UInt standard_advance;
FT_Int ascent; /* optional, bbox.yMax if not present */
FT_Int descent; /* optional, bbox.yMin if not present */
FT_Int leading; /* optional, 0 if not present */
@ -258,6 +261,7 @@ FT_BEGIN_HEADER
FT_UInt num_kern_pairs;
PFR_KernItem kern_items;
PFR_KernItem* kern_items_tail;
PFR_KernPair kern_pairs;
/* not part of the spec, but used during load */
FT_UInt32 bct_offset;
@ -281,8 +285,8 @@ FT_BEGIN_HEADER
typedef enum PFR_KernFlags_
{
PFR_KERN_2BYTE_ADJ = 0x01,
PFR_KERN_2BYTE_CHAR = 0x02
PFR_KERN_2BYTE_CHAR = 0x01,
PFR_KERN_2BYTE_ADJ = 0x02
} PFR_KernFlags;