* docs/CHANGES: Updated.
FreeType now can read kerning values from PFM files. * src/type1/t1afm.c (T1_Done_AFM): Renamed to... (T1_Done_Metrics): This. Update all callers. (T1_Read_AFM): Make it static. Don't enter and leave a frame. (LITTLE_ENDIAN_USHORT, LITTLE_ENDIAN_UINT): New macros. (T1_Read_PFM): New function. (T1_Read_Metrics): New higher-level function to be used instead of T1Read_AFM. Update all callers.
This commit is contained in:
parent
3273a99160
commit
d232f59383
19
ChangeLog
19
ChangeLog
@ -1,3 +1,22 @@
|
||||
2004-08-01 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* docs/CHANGES: Updated.
|
||||
|
||||
2004-08-01 George Williams <gww@silcom.com>
|
||||
|
||||
FreeType now can read kerning values from PFM files.
|
||||
|
||||
* src/type1/t1afm.c (T1_Done_AFM): Renamed to...
|
||||
(T1_Done_Metrics): This.
|
||||
Update all callers.
|
||||
(T1_Read_AFM): Make it static.
|
||||
Don't enter and leave a frame.
|
||||
(LITTLE_ENDIAN_USHORT, LITTLE_ENDIAN_UINT): New macros.
|
||||
(T1_Read_PFM): New function.
|
||||
(T1_Read_Metrics): New higher-level function to be used instead of
|
||||
T1Read_AFM.
|
||||
Update all callers.
|
||||
|
||||
2004-07-31 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/pcf/pcfread (pcf_load_font), src/bdf/bdfdrivr.c
|
||||
|
22
docs/CHANGES
22
docs/CHANGES
@ -1,3 +1,25 @@
|
||||
LATEST CHANGES BETWEEN 2.1.10 and 2.1.9
|
||||
|
||||
I. IMPORTANT BUG FIXES
|
||||
|
||||
- The size comparison for BDF and PCF files could fail sometimes.
|
||||
|
||||
- Some CFF files were still not loaded correctly. Patch from
|
||||
Derek Noonburg.
|
||||
|
||||
- The stroker still had some serious bugs.
|
||||
|
||||
|
||||
II. IMPORTANT CHANGES
|
||||
|
||||
- George Williams contributed code to read kerning data from PFM
|
||||
files.
|
||||
|
||||
- FreeType now uses the TT_NAME_ID_PREFERRED_FAMILY and
|
||||
TT_NAME_ID_PREFERRED_SUBFAMILY strings (if available) for
|
||||
setting family and style in SFNT fonts (patch from Kornfeld
|
||||
Eliyahu Peter).
|
||||
|
||||
|
||||
LATEST CHANGES BETWEEN 2.1.9 and 2.1.8
|
||||
|
||||
|
@ -33,8 +33,8 @@
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
T1_Done_AFM( FT_Memory memory,
|
||||
T1_AFM* afm )
|
||||
T1_Done_Metrics( FT_Memory memory,
|
||||
T1_AFM* afm )
|
||||
{
|
||||
FT_FREE( afm->kern_pairs );
|
||||
afm->num_pairs = 0;
|
||||
@ -153,11 +153,11 @@
|
||||
|
||||
|
||||
/* parse an AFM file -- for now, only read the kerning pairs */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
static FT_Error
|
||||
T1_Read_AFM( FT_Face t1_face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Error error = T1_Err_Ok;
|
||||
FT_Memory memory = stream->memory;
|
||||
FT_Byte* start;
|
||||
FT_Byte* limit;
|
||||
@ -168,9 +168,6 @@
|
||||
T1_AFM* afm = 0;
|
||||
|
||||
|
||||
if ( FT_FRAME_ENTER( stream->size ) )
|
||||
return error;
|
||||
|
||||
start = (FT_Byte*)stream->cursor;
|
||||
limit = (FT_Byte*)stream->limit;
|
||||
p = start;
|
||||
@ -233,6 +230,173 @@
|
||||
if ( error )
|
||||
FT_FREE( afm );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#define LITTLE_ENDIAN_USHORT( p ) (FT_UShort)( ( (p)[0] ) | \
|
||||
( (p)[1] << 8 ) )
|
||||
|
||||
#define LITTLE_ENDIAN_UINT( p ) (FT_UInt)( ( (p)[0] ) | \
|
||||
( (p)[1] << 8 ) | \
|
||||
( (p)[2] << 16 ) | \
|
||||
( (p)[3] << 24 ) )
|
||||
|
||||
|
||||
/* parse a PFM file -- for now, only read the kerning pairs */
|
||||
static FT_Error
|
||||
T1_Read_PFM( FT_Face t1_face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error = T1_Err_Ok;
|
||||
FT_Memory memory = stream->memory;
|
||||
FT_Byte* start;
|
||||
FT_Byte* limit;
|
||||
FT_Byte* p;
|
||||
FT_Int kern_count = 0;
|
||||
T1_Kern_Pair* pair;
|
||||
T1_AFM* afm = 0;
|
||||
FT_Int width_table_length;
|
||||
FT_CharMap oldcharmap;
|
||||
FT_CharMap charmap;
|
||||
FT_Int n;
|
||||
|
||||
|
||||
start = (FT_Byte*)stream->cursor;
|
||||
limit = (FT_Byte*)stream->limit;
|
||||
p = start;
|
||||
|
||||
/* Figure out how long the width table is. */
|
||||
/* This info is a little-endian short at offset 99. */
|
||||
p = start + 99;
|
||||
if ( p + 2 > limit )
|
||||
{
|
||||
error = T1_Err_Unknown_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
width_table_length = LITTLE_ENDIAN_USHORT( p );
|
||||
|
||||
p += 18 + width_table_length;
|
||||
if ( p + 0x12 > limit || LITTLE_ENDIAN_USHORT( p ) < 0x12 )
|
||||
/* extension table is probably optional */
|
||||
goto Exit;
|
||||
|
||||
/* Kerning offset is 14 bytes from start of extensions table. */
|
||||
p += 14;
|
||||
p = start + LITTLE_ENDIAN_UINT( p );
|
||||
if ( p + 2 > limit )
|
||||
{
|
||||
error = T1_Err_Unknown_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
kern_count = LITTLE_ENDIAN_USHORT( p );
|
||||
p += 2;
|
||||
if ( p + 4 * kern_count > limit )
|
||||
{
|
||||
error = T1_Err_Unknown_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Actually, kerning pairs are simply optional! */
|
||||
if ( kern_count == 0 )
|
||||
goto Exit;
|
||||
|
||||
/* allocate the pairs */
|
||||
if ( FT_NEW( afm ) || FT_NEW_ARRAY( afm->kern_pairs, kern_count ) )
|
||||
goto Exit;
|
||||
|
||||
/* save in face object */
|
||||
((T1_Face)t1_face)->afm_data = afm;
|
||||
|
||||
t1_face->face_flags |= FT_FACE_FLAG_KERNING;
|
||||
|
||||
/* now, read each kern pair */
|
||||
pair = afm->kern_pairs;
|
||||
afm->num_pairs = kern_count;
|
||||
limit = p + 4 * kern_count;
|
||||
|
||||
/* PFM kerning data are stored by encoding rather than glyph index, */
|
||||
/* so find the PostScript charmap of this font and install it */
|
||||
/* temporarily. If we find no PostScript charmap, then just use */
|
||||
/* the default and hope it is the right one. */
|
||||
oldcharmap = t1_face->charmap;
|
||||
charmap = NULL;
|
||||
|
||||
for ( n = 0; n < t1_face->num_charmaps; n++ )
|
||||
{
|
||||
charmap = t1_face->charmaps[n];
|
||||
/* check against PostScript pseudo platform */
|
||||
if ( charmap->platform_id == 7 )
|
||||
{
|
||||
error = FT_Set_Charmap( t1_face, charmap );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Kerning info is stored as: */
|
||||
/* */
|
||||
/* encoding of first glyph (1 byte) */
|
||||
/* encoding of second glyph (1 byte) */
|
||||
/* offset (little-endian short) */
|
||||
for ( ; p < limit ; p+=4 )
|
||||
{
|
||||
pair->glyph1 = FT_Get_Char_Index( t1_face, p[0] );
|
||||
pair->glyph2 = FT_Get_Char_Index( t1_face, p[1] );
|
||||
|
||||
pair->kerning.x = (FT_Short)LITTLE_ENDIAN_USHORT(p + 2);
|
||||
pair->kerning.y = 0;
|
||||
|
||||
pair++;
|
||||
}
|
||||
|
||||
if ( oldcharmap != NULL )
|
||||
error = FT_Set_Charmap( t1_face, oldcharmap );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* now, sort the kern pairs according to their glyph indices */
|
||||
ft_qsort( afm->kern_pairs, kern_count, sizeof ( T1_Kern_Pair ),
|
||||
compare_kern_pairs );
|
||||
|
||||
Exit:
|
||||
if ( error )
|
||||
FT_FREE( afm );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* parse a metrics file -- either AFM or PFM depending on what */
|
||||
/* it turns out to be */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
T1_Read_Metrics( FT_Face t1_face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Byte* start;
|
||||
|
||||
|
||||
if ( FT_FRAME_ENTER( stream->size ) )
|
||||
return error;
|
||||
|
||||
start = (FT_Byte*)stream->cursor;
|
||||
|
||||
if ( stream->size >= ft_strlen( "StartFontMetrics" ) &&
|
||||
ft_strncmp( (const char*)start, "StartFontMetrics",
|
||||
ft_strlen( "StartFontMetrics" ) ) == 0 )
|
||||
error = T1_Read_AFM( t1_face, stream );
|
||||
|
||||
else if ( stream->size > 6 &&
|
||||
start[0] == 0x00 && start[1] == 0x01 &&
|
||||
LITTLE_ENDIAN_UINT( start + 2 ) == stream->size )
|
||||
error = T1_Read_PFM( t1_face, stream );
|
||||
|
||||
else
|
||||
error = T1_Err_Unknown_File_Format;
|
||||
|
||||
FT_FRAME_EXIT();
|
||||
|
||||
return error;
|
||||
|
@ -44,12 +44,12 @@ FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
T1_Read_AFM( FT_Face face,
|
||||
FT_Stream stream );
|
||||
T1_Read_Metrics( FT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
FT_LOCAL( void )
|
||||
T1_Done_AFM( FT_Memory memory,
|
||||
T1_AFM* afm );
|
||||
T1_Done_Metrics( FT_Memory memory,
|
||||
T1_AFM* afm );
|
||||
|
||||
FT_LOCAL( void )
|
||||
T1_Get_Kerning( T1_AFM* afm,
|
||||
|
@ -294,7 +294,7 @@
|
||||
(FT_Face_AttachFunc) 0,
|
||||
#else
|
||||
(FT_Face_GetKerningFunc) Get_Kerning,
|
||||
(FT_Face_AttachFunc) T1_Read_AFM,
|
||||
(FT_Face_AttachFunc) T1_Read_Metrics,
|
||||
#endif
|
||||
(FT_Face_GetAdvancesFunc) 0
|
||||
};
|
||||
|
@ -233,7 +233,7 @@
|
||||
#ifndef T1_CONFIG_OPTION_NO_AFM
|
||||
/* release afm data if present */
|
||||
if ( face->afm_data )
|
||||
T1_Done_AFM( memory, (T1_AFM*)face->afm_data );
|
||||
T1_Done_Metrics( memory, (T1_AFM*)face->afm_data );
|
||||
#endif
|
||||
|
||||
/* release unicode map, if any */
|
||||
|
Loading…
Reference in New Issue
Block a user