* 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:
parent
4748730ac6
commit
b0b1ea3fea
10
ChangeLog
10
ChangeLog
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user