]>
git.saurik.com Git - wxWidgets.git/blob - src/freetype/cid/cidafm.c
1 /***************************************************************************/
5 /* AFM support for CID-keyed 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 <cid/cidafm.h>
30 #include <freetype/internal/ftstream.h>
31 #include <freetype/internal/t1types.h>
32 #include <freetype/internal/t1errors.h>
34 #include <stdlib.h> /* for qsort() */
35 #include <string.h> /* for strcmp() */
36 #include <ctype.h> /* for isalnum() */
39 /*************************************************************************/
41 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
42 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
43 /* messages during execution. */
46 #define FT_COMPONENT trace_cidafm
50 void CID_Done_AFM( FT_Memory memory
,
53 FREE( afm
->kern_pairs
);
59 #define IS_KERN_PAIR( p ) ( p[0] == 'K' && p[1] == 'P' )
61 #define IS_ALPHANUM( c ) ( isalnum( c ) || \
66 /* read a glyph name and return the equivalent glyph index */
68 FT_UInt
afm_atoindex( FT_Byte
** start
,
79 while ( ( *p
== ' ' || *p
== '\t' || *p
== ':' || *p
== ';' ) &&
84 /* now, read glyph name */
85 while ( IS_ALPHANUM( *p
) && p
< limit
)
90 if ( len
> 0 && len
< 64 )
95 /* copy glyph name to intermediate array */
96 MEM_Copy( temp
, *start
, len
);
99 /* lookup glyph name in face array */
100 for ( n
= 0; n
< type1
->num_glyphs
; n
++ )
102 char* gname
= (char*)type1
->glyph_names
[n
];
105 if ( gname
&& gname
[0] == temp
[0] && strcmp( gname
, temp
) == 0 )
117 /* read an integer */
119 int afm_atoi( FT_Byte
** start
,
127 /* skip everything that is not a number */
128 while ( p
< limit
&& !isdigit( *p
) )
137 while ( p
< limit
&& isdigit( *p
) )
139 sum
= sum
* 10 + ( *p
- '0' );
149 #define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 )
152 /* compare two kerning pairs */
154 int compare_kern_pairs( const void* a
,
157 CID_Kern_Pair
* pair1
= (CID_Kern_Pair
*)a
;
158 CID_Kern_Pair
* pair2
= (CID_Kern_Pair
*)b
;
160 FT_ULong index1
= KERN_INDEX( pair1
->glyph1
, pair1
->glyph2
);
161 FT_ULong index2
= KERN_INDEX( pair2
->glyph1
, pair2
->glyph2
);
164 return ( index1
- index2
);
168 /* parse an AFM file -- for now, only read the kerning pairs */
170 FT_Error
CID_Read_AFM( FT_Face cid_face
,
174 FT_Memory memory
= stream
->memory
;
180 T1_Font
* type1
= &((T1_Face
)t1_face
)->type1
;
184 if ( ACCESS_Frame( stream
->size
) )
187 start
= (FT_Byte
*)stream
->cursor
;
188 limit
= (FT_Byte
*)stream
->limit
;
191 /* we are now going to count the occurrences of `KP' or `KPX' in */
194 for ( p
= start
; p
< limit
- 3; p
++ )
196 if ( IS_KERN_PAIR( p
) )
200 /* Actually, kerning pairs are simply optional! */
204 /* allocate the pairs */
205 if ( ALLOC( afm
, sizeof ( *afm
) ) ||
206 ALLOC_ARRAY( afm
->kern_pairs
, count
, CID_Kern_Pair
) )
209 /* now, read each kern pair */
210 pair
= afm
->kern_pairs
;
211 afm
->num_pairs
= count
;
213 /* save in face object */
214 ((T1_Face
)t1_face
)->afm_data
= afm
;
216 for ( p
= start
; p
< limit
- 3; p
++ )
218 if ( IS_KERN_PAIR( p
) )
223 /* skip keyword (`KP' or `KPX') */
228 pair
->glyph1
= afm_atoindex( &q
, limit
, type1
);
229 pair
->glyph2
= afm_atoindex( &q
, limit
, type1
);
230 pair
->kerning
.x
= afm_atoi( &q
, limit
);
234 pair
->kerning
.y
= afm_atoi( &q
, limit
);
240 /* now, sort the kern pairs according to their glyph indices */
241 qsort( afm
->kern_pairs
, count
, sizeof ( CID_Kern_Pair
),
242 compare_kern_pairs
);
254 /* find the kerning for a given glyph pair */
256 void CID_Get_Kerning( CID_AFM
* afm
,
261 CID_Kern_Pair
*min
, *mid
, *max
;
262 FT_ULong index
= KERN_INDEX( glyph1
, glyph2
);
265 /* simple binary search */
266 min
= afm
->kern_pairs
;
267 max
= min
+ afm
->num_pairs
- 1;
274 mid
= min
+ ( max
- min
) / 2;
275 midi
= KERN_INDEX( mid
->glyph1
, mid
->glyph2
);
278 *kerning
= mid
->kerning
;