]>
git.saurik.com Git - wxWidgets.git/blob - src/freetype/type1z/z1afm.c
   1 /***************************************************************************/ 
   5 /*    AFM support for Type 1 fonts (body).                                 */ 
   7 /*  Copyright 1996-2000 by                                                 */ 
   8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */ 
  10 /*  This file is part of the FreeType project, and may only be used,       */ 
  11 /*  modified, and distributed under the terms of the FreeType project      */ 
  12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */ 
  13 /*  this file you indicate that you have read the license and              */ 
  14 /*  understand and accept it fully.                                        */ 
  16 /***************************************************************************/ 
  19 #ifdef FT_FLAT_COMPILE 
  25 #include <type1z/z1afm.h> 
  30 #include <freetype/internal/ftstream.h> 
  31 #include <freetype/internal/t1types.h> 
  33 #include <stdlib.h>  /* for qsort()   */ 
  34 #include <string.h>  /* for strcmp()  */ 
  35 #include <ctype.h>   /* for isalnum() */ 
  38   /*************************************************************************/ 
  40   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */ 
  41   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */ 
  42   /* messages during execution.                                            */ 
  45 #define FT_COMPONENT  trace_z1afm 
  49   void  Z1_Done_AFM( FT_Memory  memory
, 
  52     FREE( afm
->kern_pairs 
); 
  58 #define IS_KERN_PAIR( p )  ( p[0] == 'K' && p[1] == 'P' ) 
  60 #define IS_ALPHANUM( c )  ( isalnum( c ) || \ 
  65   /* read a glyph name and return the equivalent glyph index */ 
  67   FT_UInt  
afm_atoindex( FT_Byte
**  start
, 
  78     while ( ( *p 
== ' ' || *p 
== '\t' || *p 
== ':' || *p 
== ';' ) && 
  83     /* now, read glyph name */ 
  84     while ( IS_ALPHANUM( *p 
) && p 
< limit 
) 
  89     if ( len 
> 0 && len 
< 64 ) 
  94       /* copy glyph name to intermediate array */ 
  95       MEM_Copy( temp
, *start
, len 
); 
  98       /* lookup glyph name in face array */ 
  99       for ( n 
= 0; n 
< type1
->num_glyphs
; n
++ ) 
 101         char*  gname 
= (char*)type1
->glyph_names
[n
]; 
 104         if ( gname 
&& gname
[0] == temp
[0] && strcmp( gname
, temp 
) == 0 ) 
 116   /* read an integer */ 
 118   int  afm_atoi( FT_Byte
**  start
, 
 126     /* skip everything that is not a number */ 
 127     while ( p 
< limit 
&& !isdigit( *p 
) ) 
 136     while ( p 
< limit 
&& isdigit( *p 
) ) 
 138       sum 
= sum 
* 10 + ( *p 
- '0' ); 
 148 #define KERN_INDEX( g1, g2 )  ( ( (FT_ULong)g1 << 16 ) | g2 ) 
 151   /* compare two kerning pairs */ 
 153   int  compare_kern_pairs( const void*  a
, 
 156     Z1_Kern_Pair
*  pair1 
= (Z1_Kern_Pair
*)a
; 
 157     Z1_Kern_Pair
*  pair2 
= (Z1_Kern_Pair
*)b
; 
 159     FT_ULong  index1 
= KERN_INDEX( pair1
->glyph1
, pair1
->glyph2 
); 
 160     FT_ULong  index2 
= KERN_INDEX( pair2
->glyph1
, pair2
->glyph2 
); 
 163     return ( index1 
- index2 
); 
 167   /* parse an AFM file -- for now, only read the kerning pairs */ 
 169   FT_Error  
Z1_Read_AFM( FT_Face    t1_face
, 
 173     FT_Memory      memory 
= stream
->memory
; 
 179     T1_Font
*       type1 
= &((T1_Face
)t1_face
)->type1
; 
 183     if ( ACCESS_Frame( stream
->size 
) ) 
 186     start 
= (FT_Byte
*)stream
->cursor
; 
 187     limit 
= (FT_Byte
*)stream
->limit
; 
 190     /* we are now going to count the occurences of `KP' or `KPX' in */ 
 193     for ( p 
= start
; p 
< limit 
- 3; p
++ ) 
 195       if ( IS_KERN_PAIR( p 
) ) 
 199     /* Actually, kerning pairs are simply optional! */ 
 203     /* allocate the pairs */ 
 204     if ( ALLOC( afm
, sizeof ( *afm 
) )                       || 
 205          ALLOC_ARRAY( afm
->kern_pairs
, count
, Z1_Kern_Pair 
) ) 
 208     /* now, read each kern pair */ 
 209     pair           
= afm
->kern_pairs
; 
 210     afm
->num_pairs 
= count
; 
 212     /* save in face object */ 
 213     ((T1_Face
)t1_face
)->afm_data 
= afm
; 
 215     for ( p 
= start
; p 
< limit 
- 3; p
++ ) 
 217       if ( IS_KERN_PAIR( p 
) ) 
 222         /* skip keyword (KP or KPX) */ 
 227         pair
->glyph1    
= afm_atoindex( &q
, limit
, type1 
); 
 228         pair
->glyph2    
= afm_atoindex( &q
, limit
, type1 
); 
 229         pair
->kerning
.x 
= afm_atoi( &q
, limit 
); 
 233           pair
->kerning
.y 
= afm_atoi( &q
, limit 
); 
 239     /* now, sort the kern pairs according to their glyph indices */ 
 240     qsort( afm
->kern_pairs
, count
, sizeof ( Z1_Kern_Pair 
), 
 241            compare_kern_pairs 
); 
 253   /* find the kerning for a given glyph pair */ 
 255   void  Z1_Get_Kerning( Z1_AFM
*     afm
, 
 260     Z1_Kern_Pair  
*min
, *mid
, *max
; 
 261     FT_ULong      index 
= KERN_INDEX( glyph1
, glyph2 
); 
 264     /* simple binary search */ 
 265     min 
= afm
->kern_pairs
; 
 266     max 
= min 
+ afm
->num_pairs 
- 1; 
 273       mid  
= min 
+ ( max 
- min 
) / 2; 
 274       midi 
= KERN_INDEX( mid
->glyph1
, mid
->glyph2 
); 
 278         *kerning 
= mid
->kerning
;