diff -r a501f5ec7b34 -r 0f5961910e27 misc/libfreetype/src/psnames/psmodule.c --- a/misc/libfreetype/src/psnames/psmodule.c Tue Jul 16 11:14:27 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,597 +0,0 @@ -/***************************************************************************/ -/* */ -/* psmodule.c */ -/* */ -/* PSNames module implementation (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008 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. */ -/* */ -/***************************************************************************/ - - -#include -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_POSTSCRIPT_CMAPS_H - -#include "psmodule.h" -#include "pstables.h" - -#include "psnamerr.h" -#include "pspic.h" - - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - -#define VARIANT_BIT 0x80000000UL -#define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) ) - - - /* Return the Unicode value corresponding to a given glyph. Note that */ - /* we do deal with glyph variants by detecting a non-initial dot in */ - /* the name, as in `A.swash' or `e.final'; in this case, the */ - /* VARIANT_BIT is set in the return value. */ - /* */ - static FT_UInt32 - ps_unicode_value( const char* glyph_name ) - { - /* If the name begins with `uni', then the glyph name may be a */ - /* hard-coded unicode character code. */ - if ( glyph_name[0] == 'u' && - glyph_name[1] == 'n' && - glyph_name[2] == 'i' ) - { - /* determine whether the next four characters following are */ - /* hexadecimal. */ - - /* XXX: Add code to deal with ligatures, i.e. glyph names like */ - /* `uniXXXXYYYYZZZZ'... */ - - FT_Int count; - FT_UInt32 value = 0; - const char* p = glyph_name + 3; - - - for ( count = 4; count > 0; count--, p++ ) - { - char c = *p; - unsigned int d; - - - d = (unsigned char)c - '0'; - if ( d >= 10 ) - { - d = (unsigned char)c - 'A'; - if ( d >= 6 ) - d = 16; - else - d += 10; - } - - /* Exit if a non-uppercase hexadecimal character was found */ - /* -- this also catches character codes below `0' since such */ - /* negative numbers cast to `unsigned int' are far too big. */ - if ( d >= 16 ) - break; - - value = ( value << 4 ) + d; - } - - /* there must be exactly four hex digits */ - if ( count == 0 ) - { - if ( *p == '\0' ) - return value; - if ( *p == '.' ) - return (FT_UInt32)( value | VARIANT_BIT ); - } - } - - /* If the name begins with `u', followed by four to six uppercase */ - /* hexadecimal digits, it is a hard-coded unicode character code. */ - if ( glyph_name[0] == 'u' ) - { - FT_Int count; - FT_UInt32 value = 0; - const char* p = glyph_name + 1; - - - for ( count = 6; count > 0; count--, p++ ) - { - char c = *p; - unsigned int d; - - - d = (unsigned char)c - '0'; - if ( d >= 10 ) - { - d = (unsigned char)c - 'A'; - if ( d >= 6 ) - d = 16; - else - d += 10; - } - - if ( d >= 16 ) - break; - - value = ( value << 4 ) + d; - } - - if ( count <= 2 ) - { - if ( *p == '\0' ) - return value; - if ( *p == '.' ) - return (FT_UInt32)( value | VARIANT_BIT ); - } - } - - /* Look for a non-initial dot in the glyph name in order to */ - /* find variants like `A.swash', `e.final', etc. */ - { - const char* p = glyph_name; - const char* dot = NULL; - - - for ( ; *p; p++ ) - { - if ( *p == '.' && p > glyph_name ) - { - dot = p; - break; - } - } - - /* now look up the glyph in the Adobe Glyph List */ - if ( !dot ) - return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p ); - else - return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) | - VARIANT_BIT ); - } - } - - - /* ft_qsort callback to sort the unicode map */ - FT_CALLBACK_DEF( int ) - compare_uni_maps( const void* a, - const void* b ) - { - PS_UniMap* map1 = (PS_UniMap*)a; - PS_UniMap* map2 = (PS_UniMap*)b; - FT_UInt32 unicode1 = BASE_GLYPH( map1->unicode ); - FT_UInt32 unicode2 = BASE_GLYPH( map2->unicode ); - - - /* sort base glyphs before glyph variants */ - if ( unicode1 == unicode2 ) - { - if ( map1->unicode > map2->unicode ) - return 1; - else if ( map1->unicode < map2->unicode ) - return -1; - else - return 0; - } - else - { - if ( unicode1 > unicode2 ) - return 1; - else if ( unicode1 < unicode2 ) - return -1; - else - return 0; - } - } - - - /* support for extra glyphs not handled (well) in AGL; */ - /* we add extra mappings for them if necessary */ - -#define EXTRA_GLYPH_LIST_SIZE 10 - - static const FT_UInt32 ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] = - { - /* WGL 4 */ - 0x0394, - 0x03A9, - 0x2215, - 0x00AD, - 0x02C9, - 0x03BC, - 0x2219, - 0x00A0, - /* Romanian */ - 0x021A, - 0x021B - }; - - static const char ft_extra_glyph_names[] = - { - 'D','e','l','t','a',0, - 'O','m','e','g','a',0, - 'f','r','a','c','t','i','o','n',0, - 'h','y','p','h','e','n',0, - 'm','a','c','r','o','n',0, - 'm','u',0, - 'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0, - 's','p','a','c','e',0, - 'T','c','o','m','m','a','a','c','c','e','n','t',0, - 't','c','o','m','m','a','a','c','c','e','n','t',0 - }; - - static const FT_Int - ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] = - { - 0, - 6, - 12, - 21, - 28, - 35, - 38, - 53, - 59, - 72 - }; - - - static void - ps_check_extra_glyph_name( const char* gname, - FT_UInt glyph, - FT_UInt* extra_glyphs, - FT_UInt *states ) - { - FT_UInt n; - - - for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) - { - if ( ft_strcmp( ft_extra_glyph_names + - ft_extra_glyph_name_offsets[n], gname ) == 0 ) - { - if ( states[n] == 0 ) - { - /* mark this extra glyph as a candidate for the cmap */ - states[n] = 1; - extra_glyphs[n] = glyph; - } - - return; - } - } - } - - - static void - ps_check_extra_glyph_unicode( FT_UInt32 uni_char, - FT_UInt *states ) - { - FT_UInt n; - - - for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) - { - if ( uni_char == ft_extra_glyph_unicodes[n] ) - { - /* disable this extra glyph from being added to the cmap */ - states[n] = 2; - - return; - } - } - } - - - /* Build a table that maps Unicode values to glyph indices. */ - static FT_Error - ps_unicodes_init( FT_Memory memory, - PS_Unicodes table, - FT_UInt num_glyphs, - PS_GetGlyphNameFunc get_glyph_name, - PS_FreeGlyphNameFunc free_glyph_name, - FT_Pointer glyph_data ) - { - FT_Error error; - - FT_UInt extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - FT_UInt extra_glyphs[EXTRA_GLYPH_LIST_SIZE]; - - - /* we first allocate the table */ - table->num_maps = 0; - table->maps = 0; - - if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) - { - FT_UInt n; - FT_UInt count; - PS_UniMap* map; - FT_UInt32 uni_char; - - - map = table->maps; - - for ( n = 0; n < num_glyphs; n++ ) - { - const char* gname = get_glyph_name( glyph_data, n ); - - - if ( gname ) - { - ps_check_extra_glyph_name( gname, n, - extra_glyphs, extra_glyph_list_states ); - uni_char = ps_unicode_value( gname ); - - if ( BASE_GLYPH( uni_char ) != 0 ) - { - ps_check_extra_glyph_unicode( uni_char, - extra_glyph_list_states ); - map->unicode = uni_char; - map->glyph_index = n; - map++; - } - - if ( free_glyph_name ) - free_glyph_name( glyph_data, gname ); - } - } - - for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) - { - if ( extra_glyph_list_states[n] == 1 ) - { - /* This glyph name has an additional representation. */ - /* Add it to the cmap. */ - - map->unicode = ft_extra_glyph_unicodes[n]; - map->glyph_index = extra_glyphs[n]; - map++; - } - } - - /* now compress the table a bit */ - count = (FT_UInt)( map - table->maps ); - - if ( count == 0 ) - { - /* No unicode chars here! */ - FT_FREE( table->maps ); - if ( !error ) - error = PSnames_Err_No_Unicode_Glyph_Name; - } - else - { - /* Reallocate if the number of used entries is much smaller. */ - if ( count < num_glyphs / 2 ) - { - (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count ); - error = PSnames_Err_Ok; - } - - /* Sort the table in increasing order of unicode values, */ - /* taking care of glyph variants. */ - ft_qsort( table->maps, count, sizeof ( PS_UniMap ), - compare_uni_maps ); - } - - table->num_maps = count; - } - - return error; - } - - - static FT_UInt - ps_unicodes_char_index( PS_Unicodes table, - FT_UInt32 unicode ) - { - PS_UniMap *min, *max, *mid, *result = NULL; - - - /* Perform a binary search on the table. */ - - min = table->maps; - max = min + table->num_maps - 1; - - while ( min <= max ) - { - FT_UInt32 base_glyph; - - - mid = min + ( ( max - min ) >> 1 ); - - if ( mid->unicode == unicode ) - { - result = mid; - break; - } - - base_glyph = BASE_GLYPH( mid->unicode ); - - if ( base_glyph == unicode ) - result = mid; /* remember match but continue search for base glyph */ - - if ( min == max ) - break; - - if ( base_glyph < unicode ) - min = mid + 1; - else - max = mid - 1; - } - - if ( result ) - return result->glyph_index; - else - return 0; - } - - - static FT_UInt32 - ps_unicodes_char_next( PS_Unicodes table, - FT_UInt32 *unicode ) - { - FT_UInt result = 0; - FT_UInt32 char_code = *unicode + 1; - - - { - FT_UInt min = 0; - FT_UInt max = table->num_maps; - FT_UInt mid; - PS_UniMap* map; - FT_UInt32 base_glyph; - - - while ( min < max ) - { - mid = min + ( ( max - min ) >> 1 ); - map = table->maps + mid; - - if ( map->unicode == char_code ) - { - result = map->glyph_index; - goto Exit; - } - - base_glyph = BASE_GLYPH( map->unicode ); - - if ( base_glyph == char_code ) - result = map->glyph_index; - - if ( base_glyph < char_code ) - min = mid + 1; - else - max = mid; - } - - if ( result ) - goto Exit; /* we have a variant glyph */ - - /* we didn't find it; check whether we have a map just above it */ - char_code = 0; - - if ( min < table->num_maps ) - { - map = table->maps + min; - result = map->glyph_index; - char_code = BASE_GLYPH( map->unicode ); - } - } - - Exit: - *unicode = char_code; - return result; - } - - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - - static const char* - ps_get_macintosh_name( FT_UInt name_index ) - { - if ( name_index >= FT_NUM_MAC_NAMES ) - name_index = 0; - - return ft_standard_glyph_names + ft_mac_names[name_index]; - } - - - static const char* - ps_get_standard_strings( FT_UInt sid ) - { - if ( sid >= FT_NUM_SID_NAMES ) - return 0; - - return ft_standard_glyph_names + ft_sid_names[sid]; - } - - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, - (PS_Unicode_ValueFunc) ps_unicode_value, - (PS_Unicodes_InitFunc) ps_unicodes_init, - (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, - (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, - - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, - - t1_standard_encoding, - t1_expert_encoding - ) - -#else - - FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, - 0, - 0, - 0, - 0, - - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, - - t1_standard_encoding, - t1_expert_encoding - ) - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - - FT_DEFINE_SERVICEDESCREC1(pscmaps_services, - FT_SERVICE_ID_POSTSCRIPT_CMAPS, &FT_PSCMAPS_INTERFACE_GET - ) - - - - - static FT_Pointer - psnames_get_service( FT_Module module, - const char* service_id ) - { - FT_UNUSED( module ); - - return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id ); - } - -#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - -#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES -#define PUT_PS_NAMES_SERVICE(a) 0 -#else -#define PUT_PS_NAMES_SERVICE(a) a -#endif - - FT_DEFINE_MODULE(psnames_module_class, - - 0, /* this is not a font driver, nor a renderer */ - sizeof ( FT_ModuleRec ), - - "psnames", /* driver name */ - 0x10000L, /* driver version */ - 0x20000L, /* driver requires FreeType 2 or above */ - - PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET), /* module specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) PUT_PS_NAMES_SERVICE(psnames_get_service) - ) - - - -/* END */