ttkern.c revision cad4f915555f1eb190753da9b4b8bd58130e4739
1e5680279b21106173e342eab28552ae0e027196aDavid Turner/***************************************************************************/ 2e5680279b21106173e342eab28552ae0e027196aDavid Turner/* */ 3e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg/* ttkern.c */ 4e5680279b21106173e342eab28552ae0e027196aDavid Turner/* */ 5e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg/* Load the basic TrueType kerning table. This doesn't handle */ 6e5680279b21106173e342eab28552ae0e027196aDavid Turner/* kerning data within the GPOS table at the moment. */ 7e5680279b21106173e342eab28552ae0e027196aDavid Turner/* */ 842f5c714c055d9d8cade2ede35c3abb5ae448a2cWerner Lemberg/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ 9e5680279b21106173e342eab28552ae0e027196aDavid Turner/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 10e5680279b21106173e342eab28552ae0e027196aDavid Turner/* */ 11e5680279b21106173e342eab28552ae0e027196aDavid Turner/* This file is part of the FreeType project, and may only be used, */ 12e5680279b21106173e342eab28552ae0e027196aDavid Turner/* modified, and distributed under the terms of the FreeType project */ 13e5680279b21106173e342eab28552ae0e027196aDavid Turner/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 14e5680279b21106173e342eab28552ae0e027196aDavid Turner/* this file you indicate that you have read the license and */ 15e5680279b21106173e342eab28552ae0e027196aDavid Turner/* understand and accept it fully. */ 16e5680279b21106173e342eab28552ae0e027196aDavid Turner/* */ 17e5680279b21106173e342eab28552ae0e027196aDavid Turner/***************************************************************************/ 18e5680279b21106173e342eab28552ae0e027196aDavid Turner 19e5680279b21106173e342eab28552ae0e027196aDavid Turner 20e5680279b21106173e342eab28552ae0e027196aDavid Turner#include <ft2build.h> 21e5680279b21106173e342eab28552ae0e027196aDavid Turner#include FT_INTERNAL_DEBUG_H 22e5680279b21106173e342eab28552ae0e027196aDavid Turner#include FT_INTERNAL_STREAM_H 23e5680279b21106173e342eab28552ae0e027196aDavid Turner#include FT_TRUETYPE_TAGS_H 24e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg#include "ttkern.h" 25e5680279b21106173e342eab28552ae0e027196aDavid Turner 26e5680279b21106173e342eab28552ae0e027196aDavid Turner#include "sferrors.h" 27e5680279b21106173e342eab28552ae0e027196aDavid Turner 28e5680279b21106173e342eab28552ae0e027196aDavid Turner 29e5680279b21106173e342eab28552ae0e027196aDavid Turner /*************************************************************************/ 30e5680279b21106173e342eab28552ae0e027196aDavid Turner /* */ 31e5680279b21106173e342eab28552ae0e027196aDavid Turner /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 32e5680279b21106173e342eab28552ae0e027196aDavid Turner /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 33e5680279b21106173e342eab28552ae0e027196aDavid Turner /* messages during execution. */ 34e5680279b21106173e342eab28552ae0e027196aDavid Turner /* */ 35e5680279b21106173e342eab28552ae0e027196aDavid Turner#undef FT_COMPONENT 36e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg#define FT_COMPONENT trace_ttkern 37e5680279b21106173e342eab28552ae0e027196aDavid Turner 38e5680279b21106173e342eab28552ae0e027196aDavid Turner 39e5680279b21106173e342eab28552ae0e027196aDavid Turner#undef TT_KERN_INDEX 40e5680279b21106173e342eab28552ae0e027196aDavid Turner#define TT_KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) ) 41e5680279b21106173e342eab28552ae0e027196aDavid Turner 42e5680279b21106173e342eab28552ae0e027196aDavid Turner 43e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_LOCAL_DEF( FT_Error ) 44e5680279b21106173e342eab28552ae0e027196aDavid Turner tt_face_load_kern( TT_Face face, 45e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_Stream stream ) 46e5680279b21106173e342eab28552ae0e027196aDavid Turner { 47e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_Error error; 48e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_ULong table_size; 49e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_Byte* p; 50e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_Byte* p_limit; 51e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_UInt nn, num_tables; 52e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_UInt32 avail = 0, ordered = 0; 53e5680279b21106173e342eab28552ae0e027196aDavid Turner 54e5680279b21106173e342eab28552ae0e027196aDavid Turner 55e5680279b21106173e342eab28552ae0e027196aDavid Turner /* the kern table is optional; exit silently if it is missing */ 56e5680279b21106173e342eab28552ae0e027196aDavid Turner error = face->goto_table( face, TTAG_kern, stream, &table_size ); 57e5680279b21106173e342eab28552ae0e027196aDavid Turner if ( error ) 58e5680279b21106173e342eab28552ae0e027196aDavid Turner goto Exit; 59e5680279b21106173e342eab28552ae0e027196aDavid Turner 60e5680279b21106173e342eab28552ae0e027196aDavid Turner if ( table_size < 4 ) /* the case of a malformed table */ 61e5680279b21106173e342eab28552ae0e027196aDavid Turner { 62858abbedc0c156965aba830bfc2072a3c21144cfWerner Lemberg FT_ERROR(( "tt_face_load_kern:" 63858abbedc0c156965aba830bfc2072a3c21144cfWerner Lemberg " kerning table is too small - ignored\n" )); 64e5680279b21106173e342eab28552ae0e027196aDavid Turner error = SFNT_Err_Table_Missing; 65e5680279b21106173e342eab28552ae0e027196aDavid Turner goto Exit; 66e5680279b21106173e342eab28552ae0e027196aDavid Turner } 67e5680279b21106173e342eab28552ae0e027196aDavid Turner 68e5680279b21106173e342eab28552ae0e027196aDavid Turner if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) ) 69e5680279b21106173e342eab28552ae0e027196aDavid Turner { 70858abbedc0c156965aba830bfc2072a3c21144cfWerner Lemberg FT_ERROR(( "tt_face_load_kern:" 71858abbedc0c156965aba830bfc2072a3c21144cfWerner Lemberg " could not extract kerning table\n" )); 72e5680279b21106173e342eab28552ae0e027196aDavid Turner goto Exit; 73e5680279b21106173e342eab28552ae0e027196aDavid Turner } 74e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 75e5680279b21106173e342eab28552ae0e027196aDavid Turner face->kern_table_size = table_size; 76e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 77e5680279b21106173e342eab28552ae0e027196aDavid Turner p = face->kern_table; 78e5680279b21106173e342eab28552ae0e027196aDavid Turner p_limit = p + table_size; 79e5680279b21106173e342eab28552ae0e027196aDavid Turner 80e5680279b21106173e342eab28552ae0e027196aDavid Turner p += 2; /* skip version */ 81e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg num_tables = FT_NEXT_USHORT( p ); 82e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 83e5680279b21106173e342eab28552ae0e027196aDavid Turner if ( num_tables > 32 ) /* we only support up to 32 sub-tables */ 84e5680279b21106173e342eab28552ae0e027196aDavid Turner num_tables = 32; 85e5680279b21106173e342eab28552ae0e027196aDavid Turner 86e5680279b21106173e342eab28552ae0e027196aDavid Turner for ( nn = 0; nn < num_tables; nn++ ) 87e5680279b21106173e342eab28552ae0e027196aDavid Turner { 88607dec79bb6ad524a9d2e7f93b836b795fe234cfWerner Lemberg FT_UInt num_pairs, length, coverage; 89e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_Byte* p_next; 90cad4f915555f1eb190753da9b4b8bd58130e4739Suzuki, Toshiya (鈴木俊哉) FT_UInt32 mask = (FT_UInt32)1UL << nn; 91e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 92e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 93e5680279b21106173e342eab28552ae0e027196aDavid Turner if ( p + 6 > p_limit ) 94e5680279b21106173e342eab28552ae0e027196aDavid Turner break; 95e5680279b21106173e342eab28552ae0e027196aDavid Turner 96e5680279b21106173e342eab28552ae0e027196aDavid Turner p_next = p; 97e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 98607dec79bb6ad524a9d2e7f93b836b795fe234cfWerner Lemberg p += 2; /* skip version */ 99e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg length = FT_NEXT_USHORT( p ); 100e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg coverage = FT_NEXT_USHORT( p ); 101e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 102e5680279b21106173e342eab28552ae0e027196aDavid Turner if ( length <= 6 ) 103e5680279b21106173e342eab28552ae0e027196aDavid Turner break; 104e5680279b21106173e342eab28552ae0e027196aDavid Turner 105e5680279b21106173e342eab28552ae0e027196aDavid Turner p_next += length; 106e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 10742f5c714c055d9d8cade2ede35c3abb5ae448a2cWerner Lemberg if ( p_next > p_limit ) /* handle broken table */ 10842f5c714c055d9d8cade2ede35c3abb5ae448a2cWerner Lemberg p_next = p_limit; 109ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner 110e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg /* only use horizontal kerning tables */ 111e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg if ( ( coverage & ~8 ) != 0x0001 || 112e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg p + 8 > p_limit ) 113e5680279b21106173e342eab28552ae0e027196aDavid Turner goto NextTable; 114e5680279b21106173e342eab28552ae0e027196aDavid Turner 115e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg num_pairs = FT_NEXT_USHORT( p ); 116e5680279b21106173e342eab28552ae0e027196aDavid Turner p += 6; 117e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 11842f5c714c055d9d8cade2ede35c3abb5ae448a2cWerner Lemberg if ( ( p_next - p ) / 6 < (int)num_pairs ) /* handle broken count */ 11942f5c714c055d9d8cade2ede35c3abb5ae448a2cWerner Lemberg num_pairs = (FT_UInt)( ( p_next - p ) / 6 ); 120e5680279b21106173e342eab28552ae0e027196aDavid Turner 121e5680279b21106173e342eab28552ae0e027196aDavid Turner avail |= mask; 122e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 123e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg /* 124e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg * Now check whether the pairs in this table are ordered. 125e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg * We then can use binary search. 126e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg */ 127e5680279b21106173e342eab28552ae0e027196aDavid Turner if ( num_pairs > 0 ) 128e5680279b21106173e342eab28552ae0e027196aDavid Turner { 129e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_UInt count; 130e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_UInt old_pair; 131e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 132e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 133e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg old_pair = FT_NEXT_ULONG( p ); 134e5680279b21106173e342eab28552ae0e027196aDavid Turner p += 2; 135e5680279b21106173e342eab28552ae0e027196aDavid Turner 136e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg for ( count = num_pairs - 1; count > 0; count-- ) 137e5680279b21106173e342eab28552ae0e027196aDavid Turner { 138e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_UInt32 cur_pair; 139e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 140e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 141e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg cur_pair = FT_NEXT_ULONG( p ); 142e5680279b21106173e342eab28552ae0e027196aDavid Turner if ( cur_pair <= old_pair ) 143e5680279b21106173e342eab28552ae0e027196aDavid Turner break; 144e5680279b21106173e342eab28552ae0e027196aDavid Turner 145e5680279b21106173e342eab28552ae0e027196aDavid Turner p += 2; 146e5680279b21106173e342eab28552ae0e027196aDavid Turner old_pair = cur_pair; 147e5680279b21106173e342eab28552ae0e027196aDavid Turner } 148e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 149e5680279b21106173e342eab28552ae0e027196aDavid Turner if ( count == 0 ) 150e5680279b21106173e342eab28552ae0e027196aDavid Turner ordered |= mask; 151e5680279b21106173e342eab28552ae0e027196aDavid Turner } 152e5680279b21106173e342eab28552ae0e027196aDavid Turner 153e5680279b21106173e342eab28552ae0e027196aDavid Turner NextTable: 154e5680279b21106173e342eab28552ae0e027196aDavid Turner p = p_next; 155e5680279b21106173e342eab28552ae0e027196aDavid Turner } 156e5680279b21106173e342eab28552ae0e027196aDavid Turner 157e5680279b21106173e342eab28552ae0e027196aDavid Turner face->num_kern_tables = nn; 158e5680279b21106173e342eab28552ae0e027196aDavid Turner face->kern_avail_bits = avail; 159e5680279b21106173e342eab28552ae0e027196aDavid Turner face->kern_order_bits = ordered; 160e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 161e5680279b21106173e342eab28552ae0e027196aDavid Turner Exit: 162e5680279b21106173e342eab28552ae0e027196aDavid Turner return error; 163e5680279b21106173e342eab28552ae0e027196aDavid Turner } 164e5680279b21106173e342eab28552ae0e027196aDavid Turner 165e5680279b21106173e342eab28552ae0e027196aDavid Turner 166e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_LOCAL_DEF( void ) 167e5680279b21106173e342eab28552ae0e027196aDavid Turner tt_face_done_kern( TT_Face face ) 168e5680279b21106173e342eab28552ae0e027196aDavid Turner { 169e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_Stream stream = face->root.stream; 170e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 171e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 172e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_FRAME_RELEASE( face->kern_table ); 173e5680279b21106173e342eab28552ae0e027196aDavid Turner face->kern_table_size = 0; 174e5680279b21106173e342eab28552ae0e027196aDavid Turner face->num_kern_tables = 0; 175e5680279b21106173e342eab28552ae0e027196aDavid Turner face->kern_avail_bits = 0; 176e5680279b21106173e342eab28552ae0e027196aDavid Turner face->kern_order_bits = 0; 177e5680279b21106173e342eab28552ae0e027196aDavid Turner } 178e5680279b21106173e342eab28552ae0e027196aDavid Turner 179e5680279b21106173e342eab28552ae0e027196aDavid Turner 180e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_LOCAL_DEF( FT_Int ) 181e5680279b21106173e342eab28552ae0e027196aDavid Turner tt_face_get_kerning( TT_Face face, 182e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_UInt left_glyph, 183e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_UInt right_glyph ) 184e5680279b21106173e342eab28552ae0e027196aDavid Turner { 185e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_Int result = 0; 186e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_UInt count, mask = 1; 187e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_Byte* p = face->kern_table; 188ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner FT_Byte* p_limit = p + face->kern_table_size; 189e5680279b21106173e342eab28552ae0e027196aDavid Turner 190e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 191e5680279b21106173e342eab28552ae0e027196aDavid Turner p += 4; 192e5680279b21106173e342eab28552ae0e027196aDavid Turner mask = 0x0001; 193e5680279b21106173e342eab28552ae0e027196aDavid Turner 194ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner for ( count = face->num_kern_tables; 195ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner count > 0 && p + 6 <= p_limit; 196ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner count--, mask <<= 1 ) 197e5680279b21106173e342eab28552ae0e027196aDavid Turner { 198e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_Byte* base = p; 199e5680279b21106173e342eab28552ae0e027196aDavid Turner FT_Byte* next = base; 200e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_UInt version = FT_NEXT_USHORT( p ); 201e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_UInt length = FT_NEXT_USHORT( p ); 202e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_UInt coverage = FT_NEXT_USHORT( p ); 203ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner FT_UInt num_pairs; 204fa0eb0c95fa954a3097d62c440303c403f466942David Turner FT_Int value = 0; 205e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 206b19b0810cd887a4c1036121b0d3e9bb93278a0a9Werner Lemberg FT_UNUSED( version ); 207b19b0810cd887a4c1036121b0d3e9bb93278a0a9Werner Lemberg 208e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 209e5680279b21106173e342eab28552ae0e027196aDavid Turner next = base + length; 210e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 21142f5c714c055d9d8cade2ede35c3abb5ae448a2cWerner Lemberg if ( next > p_limit ) /* handle broken table */ 212ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner next = p_limit; 213ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner 214e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg if ( ( face->kern_avail_bits & mask ) == 0 ) 215e5680279b21106173e342eab28552ae0e027196aDavid Turner goto NextTable; 216e5680279b21106173e342eab28552ae0e027196aDavid Turner 217e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg if ( p + 8 > next ) 218e5680279b21106173e342eab28552ae0e027196aDavid Turner goto NextTable; 219e5680279b21106173e342eab28552ae0e027196aDavid Turner 220ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner num_pairs = FT_NEXT_USHORT( p ); 221ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner p += 6; 222ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner 22342f5c714c055d9d8cade2ede35c3abb5ae448a2cWerner Lemberg if ( ( next - p ) / 6 < (int)num_pairs ) /* handle broken count */ 22442f5c714c055d9d8cade2ede35c3abb5ae448a2cWerner Lemberg num_pairs = (FT_UInt)( ( next - p ) / 6 ); 225ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner 226e5680279b21106173e342eab28552ae0e027196aDavid Turner switch ( coverage >> 8 ) 227e5680279b21106173e342eab28552ae0e027196aDavid Turner { 228e5680279b21106173e342eab28552ae0e027196aDavid Turner case 0: 229e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg { 230ab7e52b1c78b27d74e9555c6488c46bd62101804David Turner FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph ); 231e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 232e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 233e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg if ( face->kern_order_bits & mask ) /* binary search */ 234e5680279b21106173e342eab28552ae0e027196aDavid Turner { 235e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_UInt min = 0; 236e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_UInt max = num_pairs; 237fa0eb0c95fa954a3097d62c440303c403f466942David Turner 238e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 239e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg while ( min < max ) 240e5680279b21106173e342eab28552ae0e027196aDavid Turner { 241e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_UInt mid = ( min + max ) >> 1; 242e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_Byte* q = p + 6 * mid; 243e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_ULong key; 244e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 245e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 246e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg key = FT_NEXT_ULONG( q ); 247e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 248e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg if ( key == key0 ) 249e5680279b21106173e342eab28552ae0e027196aDavid Turner { 250e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg value = FT_PEEK_SHORT( q ); 251e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg goto Found; 252e5680279b21106173e342eab28552ae0e027196aDavid Turner } 253e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg if ( key < key0 ) 254e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg min = mid + 1; 255e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg else 256e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg max = mid; 257e5680279b21106173e342eab28552ae0e027196aDavid Turner } 258e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg } 259e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg else /* linear search */ 260e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg { 26142137bc6145c426702b90d0cec5c5acd332739aeDavid Turner FT_UInt count2; 26242137bc6145c426702b90d0cec5c5acd332739aeDavid Turner 263fa3651e7d8af95b080db00d25a5ada0a5f77ef3dWerner Lemberg 26442137bc6145c426702b90d0cec5c5acd332739aeDavid Turner for ( count2 = num_pairs; count2 > 0; count2-- ) 265e5680279b21106173e342eab28552ae0e027196aDavid Turner { 266e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg FT_ULong key = FT_NEXT_ULONG( p ); 267e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 268e5680279b21106173e342eab28552ae0e027196aDavid Turner 269e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg if ( key == key0 ) 270e5680279b21106173e342eab28552ae0e027196aDavid Turner { 271e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg value = FT_PEEK_SHORT( p ); 272e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg goto Found; 273e5680279b21106173e342eab28552ae0e027196aDavid Turner } 274e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg p += 2; 275e5680279b21106173e342eab28552ae0e027196aDavid Turner } 276e5680279b21106173e342eab28552ae0e027196aDavid Turner } 277e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg } 278e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg break; 279e5680279b21106173e342eab28552ae0e027196aDavid Turner 280e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg /* 281fa3651e7d8af95b080db00d25a5ada0a5f77ef3dWerner Lemberg * We don't support format 2 because we haven't seen a single font 282e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg * using it in real life... 283e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg */ 284e5680279b21106173e342eab28552ae0e027196aDavid Turner 285e5680279b21106173e342eab28552ae0e027196aDavid Turner default: 286e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg ; 287e5680279b21106173e342eab28552ae0e027196aDavid Turner } 288e5680279b21106173e342eab28552ae0e027196aDavid Turner 289fa0eb0c95fa954a3097d62c440303c403f466942David Turner goto NextTable; 290e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 291fa0eb0c95fa954a3097d62c440303c403f466942David Turner Found: 2926e87ed9f04f7914e15f9284b0b762b730222c399Werner Lemberg if ( coverage & 8 ) /* override or add */ 293e5680279b21106173e342eab28552ae0e027196aDavid Turner result = value; 294e5680279b21106173e342eab28552ae0e027196aDavid Turner else 295e5680279b21106173e342eab28552ae0e027196aDavid Turner result += value; 296e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 297e5680279b21106173e342eab28552ae0e027196aDavid Turner NextTable: 298e5680279b21106173e342eab28552ae0e027196aDavid Turner p = next; 299e5680279b21106173e342eab28552ae0e027196aDavid Turner } 300e5680279b21106173e342eab28552ae0e027196aDavid Turner 301e5680279b21106173e342eab28552ae0e027196aDavid Turner return result; 302e5680279b21106173e342eab28552ae0e027196aDavid Turner } 303e5680279b21106173e342eab28552ae0e027196aDavid Turner 304e5680279b21106173e342eab28552ae0e027196aDavid Turner#undef TT_KERN_INDEX 305e793092d0a9f4d4d383315bcefd485dcbe4804b3Werner Lemberg 306e5680279b21106173e342eab28552ae0e027196aDavid Turner/* END */ 307