diff options
Diffstat (limited to 'Build/source/libs/freetype/freetype-1.5/lib/extend/ftxkern.c')
-rw-r--r-- | Build/source/libs/freetype/freetype-1.5/lib/extend/ftxkern.c | 645 |
1 files changed, 0 insertions, 645 deletions
diff --git a/Build/source/libs/freetype/freetype-1.5/lib/extend/ftxkern.c b/Build/source/libs/freetype/freetype-1.5/lib/extend/ftxkern.c deleted file mode 100644 index 40649d93e81..00000000000 --- a/Build/source/libs/freetype/freetype-1.5/lib/extend/ftxkern.c +++ /dev/null @@ -1,645 +0,0 @@ -/******************************************************************* - * - * ftxkern.c 1.0 - * - * Kerning support extension. - * - * Copyright 1996-2002 by - * David Turner, Robert Wilhelm, and Werner Lemberg. - * - * This file is part of the FreeType project, and may only be used - * modified and distributed under the terms of the FreeType project - * license, LICENSE.TXT. By continuing to use, modify, or distribute - * this file you indicate that you have read the license and - * understand and accept it fully. - * - * - * The kerning support is currently part of the engine extensions. - * - ******************************************************************/ - -#include "ftxkern.h" - -#include "ttextend.h" -#include "tttypes.h" -#include "ttdebug.h" -#include "ttload.h" -#include "ttmemory.h" -#include "ttfile.h" -#include "ttobjs.h" -#include "tttags.h" - - -/* Required by the tracing mode */ -#undef TT_COMPONENT -#define TT_COMPONENT trace_any - -#define KERNING_ID Build_Extension_ID( 'k', 'e', 'r', 'n' ) - -#undef KERN_INDEX -#define KERN_INDEX(g1,g2) (((TT_ULong)g1 << 16) | g2) - - /* compare two kerning pairs, for sorting */ - static int compare_kern_pairs( const void* a, const void* b ) - { - TT_Kern_0_Pair* pair1 = (TT_Kern_0_Pair*)a; - TT_Kern_0_Pair* pair2 = (TT_Kern_0_Pair*)b; - - TT_ULong index1 = KERN_INDEX( pair1->left, pair1->right ); - TT_ULong index2 = KERN_INDEX( pair2->left, pair2->right ); - - return ( index1 < index2 ? -1 : - ( index1 > index2 ? 1 : 0 )); - } - - - /* a simple shell sort algorithm to avoid calling qsort */ - /* (since this creates problems on 16-bit machines) */ - static void - sort_kern_pairs( TT_Kern_0_Pair* pairs, - int count ) - { - TT_Kern_0_Pair *i, *j, *limit = pairs + count; - TT_Kern_0_Pair temp; - int gap; - - - /* compute initial gap */ - for ( gap = 0; ++gap < count; gap *= 3 ) - ; - - while ( gap /= 3 ) - { - for ( i = pairs + gap; i < limit; i++ ) - { - for ( j = i - gap; ; j -= gap ) - { - TT_Kern_0_Pair* k = j + gap; - - - if ( compare_kern_pairs( j, k ) < 0 ) - break; - - temp = *j; - *j = *k; - *k = temp; - - if ( j < pairs + gap ) - break; - } - } - } - } - - - - /* check whether the kern table is sorted */ - static int - is_sorted( TT_Kern_0_Pair* table, TT_ULong num_pairs ) - { - TT_ULong i; - - for ( i=1; i<num_pairs; i++ ) - { - if ( compare_kern_pairs(&table[i-1], &table[i]) != -1 ) - return 0; - } - return 1; - } - - -/******************************************************************* - * - * Function : SubTable_Load_0 - * - * Description : Loads a format 0 kerning subtable data. - * - * Input : kern0 pointer to the kerning subtable - * - * Output : error code - * - * Notes : - Assumes that the stream is already `used' - * - * - the file cursor must be set by the caller - * - * - in case of error, the function _must_ destroy - * the data it allocates! - * - ******************************************************************/ - - static TT_Error - Subtable_Load_0( TT_Kern_0* kern0, - PFace input ) - { - DEFINE_LOAD_LOCALS( input->stream ); - - UShort num_pairs, n; - - - if ( ACCESS_Frame( 8L ) ) - return error; - - num_pairs = GET_UShort(); - kern0->nPairs = 0; - kern0->searchRange = GET_UShort(); - kern0->entrySelector = GET_UShort(); - kern0->rangeShift = GET_UShort(); - - /* we only set kern0->nPairs if the subtable has been loaded */ - - FORGET_Frame(); - - if ( ALLOC_ARRAY( kern0->pairs, num_pairs, TT_Kern_0_Pair ) ) - return error; - - if ( ACCESS_Frame( num_pairs * 6L ) ) - goto Fail; - - for ( n = 0; n < num_pairs; n++ ) - { - kern0->pairs[n].left = GET_UShort(); - kern0->pairs[n].right = GET_UShort(); - kern0->pairs[n].value = GET_UShort(); - - if ( kern0->pairs[n].left >= input->numGlyphs || - kern0->pairs[n].right >= input->numGlyphs ) - { - FORGET_Frame(); - error = TT_Err_Invalid_Kerning_Table; - goto Fail; - } - } - - FORGET_Frame(); - - /* we're ok, set the pairs count */ - kern0->nPairs = num_pairs; - - /* the spec says that the kerning pairs must be sorted, - but some brain damaged font producers don't do that correctly.. (JvR 3/4/2000) */ - if ( !is_sorted( kern0->pairs, num_pairs ) ) - sort_kern_pairs( kern0->pairs, num_pairs ); - - return TT_Err_Ok; - - Fail: - FREE( kern0->pairs ); - return error; - } - - -/******************************************************************* - * - * Function : SubTable_Load_2 - * - * Description : Loads a format 2 kerning subtable data. - * - * Input : kern2 pointer to the kerning subtable - * length subtable length. This is required as - * the subheader doesn't give any indication - * of the size of the `array' table. - * - * Output : error code - * - * Notes : - Assumes that the stream is already `used' - * - * - the file cursor must be set by the caller - * - * - in case of error, the function _must_ destroy - * the data it allocates! - * - ******************************************************************/ - - static TT_Error - Subtable_Load_2( TT_Kern_2* kern2, - PFace input ) - { - DEFINE_LOAD_LOCALS( input->stream ); - - Long table_base; - - UShort left_offset, right_offset, array_offset; - ULong array_size; - UShort left_max, right_max, n; - - - /* record the table offset */ - table_base = FILE_Pos(); - - if ( ACCESS_Frame( 8L ) ) - return error; - - kern2->rowWidth = GET_UShort(); - left_offset = GET_UShort(); - right_offset = GET_UShort(); - array_offset = GET_UShort(); - - FORGET_Frame(); - - /* first load left and right glyph classes */ - - if ( FILE_Seek( table_base + left_offset ) || - ACCESS_Frame( 4L ) ) - return error; - - kern2->leftClass.firstGlyph = GET_UShort(); - kern2->leftClass.nGlyphs = GET_UShort(); - - FORGET_Frame(); - - if ( ALLOC_ARRAY( kern2->leftClass.classes, - kern2->leftClass.nGlyphs, - UShort ) ) - return error; - - /* load left offsets */ - - if ( ACCESS_Frame( kern2->leftClass.nGlyphs * 2L ) ) - goto Fail_Left; - - for ( n = 0; n < kern2->leftClass.nGlyphs; n++ ) - kern2->leftClass.classes[n] = GET_UShort(); - - FORGET_Frame(); - - /* right class */ - - if ( FILE_Seek( table_base + right_offset ) || - ACCESS_Frame( 4L ) ) - goto Fail_Left; - - kern2->rightClass.firstGlyph = GET_UShort(); - kern2->rightClass.nGlyphs = GET_UShort(); - - FORGET_Frame(); - - if ( ALLOC_ARRAY( kern2->rightClass.classes, - kern2->rightClass.nGlyphs, - UShort ) ) - goto Fail_Left; - - /* load right offsets */ - - if ( ACCESS_Frame( kern2->rightClass.nGlyphs * 2L ) ) - goto Fail_Right; - - for ( n = 0; n < kern2->rightClass.nGlyphs; n++ ) - kern2->rightClass.classes[n] = GET_UShort(); - - FORGET_Frame(); - - /* Now load the kerning array. We don't have its size, we */ - /* must compute it from what we know. */ - - /* We thus compute the maximum left and right offsets and */ - /* add them to get the array size. */ - - left_max = right_max = 0; - - for ( n = 0; n < kern2->leftClass.nGlyphs; n++ ) - left_max = MAX( left_max, kern2->leftClass.classes[n] ); - - for ( n = 0; n < kern2->rightClass.nGlyphs; n++ ) - right_max = MAX( right_max, kern2->leftClass.classes[n] ); - - array_size = left_max + right_max + 2; - - if ( ALLOC( kern2->array, array_size ) ) - goto Fail_Right; - - if ( ACCESS_Frame( array_size ) ) - goto Fail_Array; - - for ( n = 0; (UInt)n < array_size/2; n++ ) - kern2->array[n] = GET_Short(); - - FORGET_Frame(); - - /* we're good now */ - - return TT_Err_Ok; - - Fail_Array: - FREE( kern2->array ); - - Fail_Right: - FREE( kern2->rightClass.classes ); - kern2->rightClass.nGlyphs = 0; - - Fail_Left: - FREE( kern2->leftClass.classes ); - kern2->leftClass.nGlyphs = 0; - - return error; - } - - -/******************************************************************* - * - * Function : Kerning_Create - * - * Description : Creates the kerning directory if a face is - * loaded. The tables however are loaded on - * demand to save space. - * - * Input : face pointer to the parent face object - * kern pointer to the extension's kerning field - * - * Output : error code - * - * Notes : as in all constructors, the memory allocated isn't - * released in case of failure. Rather, the task is left - * to the destructor (which is called if an error - * occurs during the loading of a face). - * - ******************************************************************/ - - static TT_Error - Kerning_Create( void* ext, - PFace face ) - { - DEFINE_LOAD_LOCALS( face->stream ); - - TT_Kerning* kern = (TT_Kerning*)ext; - UShort num_tables; - Long table; - - TT_Kern_Subtable* sub; - - - /* by convention */ - if ( !kern ) - return TT_Err_Ok; - - /* Now load the kerning directory. We're called from the face */ - /* constructor. We thus need not use the stream. */ - - kern->version = 0; - kern->nTables = 0; - kern->tables = NULL; - - table = TT_LookUp_Table( face, TTAG_kern ); - if ( table < 0 ) - return TT_Err_Ok; /* The table is optional */ - - if ( FILE_Seek( face->dirTables[table].Offset ) || - ACCESS_Frame( 4L ) ) - return error; - - kern->version = GET_UShort(); - num_tables = GET_UShort(); - - FORGET_Frame(); - - /* we don't set kern->nTables until we have allocated the array */ - - if ( ALLOC_ARRAY( kern->tables, num_tables, TT_Kern_Subtable ) ) - return error; - - kern->nTables = num_tables; - - /* now load the directory entries, but do _not_ load the tables ! */ - - sub = kern->tables; - - for ( table = 0; table < num_tables; table++ ) - { - if ( ACCESS_Frame( 6L ) ) - return error; - - sub->loaded = FALSE; /* redundant, but good to see */ - sub->version = GET_UShort(); - sub->length = GET_UShort() - 6; /* substract header length */ - sub->format = GET_Byte(); - sub->coverage = GET_Byte(); - - FORGET_Frame(); - - sub->offset = FILE_Pos(); - - /* now skip to the next table */ - - if ( FILE_Skip( sub->length ) ) - return error; - - sub++; - } - - /* that's fine, leave now */ - - return TT_Err_Ok; - } - - -/******************************************************************* - * - * Function : Kerning_Destroy - * - * Description : Destroys all kerning information. - * - * Input : kern pointer to the extension's kerning field - * - * Output : error code - * - * Notes : This function is a destructor; it must be able - * to destroy partially built tables. - * - ******************************************************************/ - - static TT_Error - Kerning_Destroy( void* ext, - PFace face ) - { - TT_Kerning* kern = (TT_Kerning*)ext; - TT_Kern_Subtable* sub; - UShort n; - - - /* by convention */ - if ( !kern ) - return TT_Err_Ok; - - if ( kern->nTables == 0 ) - return TT_Err_Ok; /* no tables to release */ - - /* scan the table directory and release loaded entries */ - - sub = kern->tables; - for ( n = 0; n < kern->nTables; n++ ) - { - if ( sub->loaded ) - { - switch ( sub->format ) - { - case 0: - FREE( sub->t.kern0.pairs ); - sub->t.kern0.nPairs = 0; - sub->t.kern0.searchRange = 0; - sub->t.kern0.entrySelector = 0; - sub->t.kern0.rangeShift = 0; - break; - - case 2: - FREE( sub->t.kern2.leftClass.classes ); - sub->t.kern2.leftClass.firstGlyph = 0; - sub->t.kern2.leftClass.nGlyphs = 0; - - FREE( sub->t.kern2.rightClass.classes ); - sub->t.kern2.rightClass.firstGlyph = 0; - sub->t.kern2.rightClass.nGlyphs = 0; - - FREE( sub->t.kern2.array ); - sub->t.kern2.rowWidth = 0; - break; - - default: - ; /* invalid subtable format - do nothing */ - } - - sub->loaded = FALSE; - sub->version = 0; - sub->offset = 0; - sub->length = 0; - sub->coverage = 0; - sub->format = 0; - } - sub++; - } - - FREE( kern->tables ); - kern->nTables = 0; - - return TT_Err_Ok; - } - - -/******************************************************************* - * - * Function : TT_Get_Kerning_Directory - * - * Description : Returns a given face's kerning directory. - * - * Input : face handle to the face object - * directory pointer to client's target directory - * - * Output : error code - * - * Notes : The kerning table directory is loaded with the face - * through the extension constructor. However, the kerning - * tables themselves are only loaded on demand, as they - * may represent a lot of data, unneeded by most uses of - * the engine. - * - ******************************************************************/ - - FT_EXPORT_FUNC( TT_Error ) - TT_Get_Kerning_Directory( TT_Face face, - TT_Kerning* directory ) - { - PFace faze = HANDLE_Face( face ); - TT_Error error; - TT_Kerning* kerning; - - - if ( !faze ) - return TT_Err_Invalid_Face_Handle; - - /* copy directory header */ - error = TT_Extension_Get( faze, KERNING_ID, (void**)&kerning ); - if ( !error ) - *directory = *kerning; - - return error; - } - - -/******************************************************************* - * - * Function : TT_Load_Kerning_Table - * - * Description : Loads a kerning table intro memory. - * - * Input : face face handle - * kern_index index in the face's kerning directory - * - * Output : error code - * - * Notes : - * - ******************************************************************/ - - FT_EXPORT_FUNC( TT_Error ) - TT_Load_Kerning_Table( TT_Face face, - TT_UShort kern_index ) - { - TT_Error error; - TT_Stream stream; - - TT_Kerning* kern; - TT_Kern_Subtable* sub; - - - PFace faze = HANDLE_Face( face ); - - if ( !faze ) - return TT_Err_Invalid_Face_Handle; - - error = TT_Extension_Get( faze, KERNING_ID, (void**)&kern ); - if ( error ) - return error; - - if ( kern->nTables == 0 ) - return TT_Err_Table_Missing; - - if ( kern_index >= kern->nTables ) - return TT_Err_Invalid_Argument; - - sub = kern->tables + kern_index; - - if ( sub->format != 0 && sub->format != 2 ) - return TT_Err_Invalid_Kerning_Table_Format; - - /* now access stream */ - if ( USE_Stream( faze->stream, stream ) ) - return error; - - if ( FILE_Seek( sub->offset ) ) - goto Fail; - - if ( sub->format == 0 ) - error = Subtable_Load_0( &sub->t.kern0, faze ); - else if ( sub->format == 2 ) - error = Subtable_Load_2( &sub->t.kern2, faze ); - - if ( !error ) - sub->loaded = TRUE; - - Fail: - /* release stream */ - DONE_Stream( stream ); - - return error; - } - - - FT_EXPORT_FUNC( TT_Error ) - TT_Init_Kerning_Extension( TT_Engine engine ) - { - PEngine_Instance _engine = HANDLE_Engine( engine ); - - TT_Error error; - - - if ( !_engine ) - return TT_Err_Invalid_Engine; - - error = TT_Register_Extension( _engine, - KERNING_ID, - sizeof ( TT_Kerning ), - Kerning_Create, - Kerning_Destroy ); - return error; - } - - -/* END */ |