34#define FT_COMPONENT ttkern
38#define TT_KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) )
41 FT_LOCAL_DEF( FT_Error )
42 tt_face_load_kern( TT_Face face,
49 FT_UInt nn, num_tables;
50 FT_UInt32 avail = 0, ordered = 0;
54 error = face->goto_table( face, TTAG_kern, stream, &table_size );
60 FT_ERROR((
"tt_face_load_kern:"
61 " kerning table is too small - ignored\n" ));
62 error = FT_THROW( Table_Missing );
66 if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) )
68 FT_ERROR((
"tt_face_load_kern:"
69 " could not extract kerning table\n" ));
73 face->kern_table_size = table_size;
76 p_limit = p + table_size;
79 num_tables = FT_NEXT_USHORT( p );
81 if ( num_tables > 32 )
84 for ( nn = 0; nn < num_tables; nn++ )
86 FT_UInt num_pairs, length, coverage, format;
88 FT_UInt32 mask = (FT_UInt32)1UL << nn;
91 if ( p + 6 > p_limit )
97 length = FT_NEXT_USHORT( p );
98 coverage = FT_NEXT_USHORT( p );
100 if ( length <= 6 + 8 )
105 if ( p_next > p_limit )
108 format = coverage >> 8;
115 if ( ( coverage & 3U ) != 0x0001 ||
119 num_pairs = FT_NEXT_USHORT( p );
122 if ( ( p_next - p ) < 6 * (
int)num_pairs )
123 num_pairs = (FT_UInt)( ( p_next - p ) / 6 );
137 old_pair = FT_NEXT_ULONG( p );
140 for ( count = num_pairs - 1; count > 0; count-- )
145 cur_pair = FT_NEXT_ULONG( p );
146 if ( cur_pair < old_pair )
161 face->num_kern_tables = nn;
162 face->kern_avail_bits = avail;
163 face->kern_order_bits = ordered;
171 tt_face_done_kern( TT_Face face )
173 FT_Stream stream = face->root.stream;
176 FT_FRAME_RELEASE( face->kern_table );
177 face->kern_table_size = 0;
178 face->num_kern_tables = 0;
179 face->kern_avail_bits = 0;
180 face->kern_order_bits = 0;
184 FT_LOCAL_DEF( FT_Int )
185 tt_face_get_kerning( TT_Face face,
187 FT_UInt right_glyph )
196 if ( !face->kern_table )
199 p = face->kern_table;
200 p_limit = p + face->kern_table_size;
205 for ( count = face->num_kern_tables;
206 count > 0 && p + 6 <= p_limit;
207 count--, mask <<= 1 )
211 FT_UInt version = FT_NEXT_USHORT( p );
212 FT_UInt length = FT_NEXT_USHORT( p );
213 FT_UInt coverage = FT_NEXT_USHORT( p );
217 FT_UNUSED( version );
220 next = base + length;
222 if ( next > p_limit )
225 if ( ( face->kern_avail_bits & mask ) == 0 )
228 FT_ASSERT( p + 8 <= next );
230 num_pairs = FT_NEXT_USHORT( p );
233 if ( ( next - p ) < 6 * (
int)num_pairs )
234 num_pairs = (FT_UInt)( ( next - p ) / 6 );
236 switch ( coverage >> 8 )
240 FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph );
243 if ( face->kern_order_bits & mask )
246 FT_UInt max = num_pairs;
251 FT_UInt mid = ( min + max ) >> 1;
252 FT_Byte* q = p + 6 * mid;
256 key = FT_NEXT_ULONG( q );
260 value = FT_PEEK_SHORT( q );
274 for ( count2 = num_pairs; count2 > 0; count2-- )
276 FT_ULong key = FT_NEXT_ULONG( p );
281 value = FT_PEEK_SHORT( p );