Edit

kc3-lang/freetype/src/psnames/psmodule.c

Branch :

  • Show log

    Commit

  • Author : Werner Lemberg
    Date : 2003-06-23 19:26:53
    Hash : 43ba0842
    Message : * src/tools/glnames.py: Updated to AGL 2.0. * src/psnames/pstables.h: Regenerated. * include/freetype/cache/ftcglyph.h, include/freetype/ttnameid.h, src/base/ftcalc.c, src/base/fttrigon.c, src/cff/cffgload.c, src/otlayout/otlgsub.c, src/pshinter/pshrec.c, src/psnames/psmodule.c, src/sfnt/sfobjs.c, src/truetype/ttdriver.c: Decorate constants with `U' and `L' if appropriate. * include/freetype/ftmoderr.h: Updated to include recent module additions. * src/pshinter/pshnterr.h (FT_ERR_BASE): Define as `FT_Mod_Err_PShinter'. * src/type42/t42error.h (FT_ERR_BASE): Define as `FT_Mod_Err_Type42'. * src/pshinter/pshrec.h (PS_HINTS_MAGIC): Removed. Not used. * include/freetype/config/ftconfig.h [__MWERKS__]: Define FT_LONG64 and FT_INT64.

  • src/psnames/psmodule.c
  • /***************************************************************************/
    /*                                                                         */
    /*  psmodule.c                                                             */
    /*                                                                         */
    /*    PSNames module implementation (body).                                */
    /*                                                                         */
    /*  Copyright 1996-2001, 2002, 2003 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 <ft2build.h>
    #include FT_INTERNAL_POSTSCRIPT_NAMES_H
    #include FT_INTERNAL_OBJECTS_H
    
    #include "psmodule.h"
    #include "pstables.h"
    
    #include "psnamerr.h"
    
    
    #ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES
    
    
    #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
    
    
      /* 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', etc.                        */
      /*                                                                     */
      static FT_UInt32
      ps_unicode_value( const char*  glyph_name )
      {
        FT_Int  n;
        char    first = glyph_name[0];
        char    temp[64];
    
    
        /* 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_ULong     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 */
            if ( d >= 16 )
              break;
    
            value = ( value << 4 ) + d;
          }
    
          /* there must be exactly four hex digits */
          if ( ( *p == '\0' || *p == '.' ) && count == 0 )
            return value;
        }
    
        /* If the name begins with `u', followed by four to six uppercase */
        /* hexadicimal digits, it is a hard-coded unicode character code. */
        if ( glyph_name[0] == 'u' )
        {
          FT_Int       count;
          FT_ULong     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 ( ( *p == '\0' || *p == '.' ) && count <= 2 )
            return value;
        }
    
        /* look for a non-initial dot in the glyph name in order to */
        /* sort-out variants like `A.swash', `e.final', etc.        */
        {
          const char*  p;
          int          len;
    
    
          p = glyph_name;
    
          while ( *p && *p != '.' )
            p++;
    
          len = (int)( p - glyph_name );
    
          if ( *p && len < 64 )
          {
            ft_strncpy( temp, glyph_name, len );
            temp[len]  = 0;
            glyph_name = temp;
          }
        }
    
        /* now, look up the glyph in the Adobe Glyph List */
        for ( n = 0; n < NUM_ADOBE_GLYPHS; n++ )
        {
          const char*  name = sid_standard_names[n];
    
    
          if ( first == name[0] && ft_strcmp( glyph_name, name ) == 0 )
            return ps_names_to_unicode[n];
        }
    
        /* not found, there is probably no Unicode value for this glyph name */
        return 0;
      }
    
    
      /* 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;
    
    
        return ( map1->unicode - map2->unicode );
      }
    
    
      /* Builds a table that maps Unicode values to glyph indices */
      static FT_Error
      ps_build_unicode_table( FT_Memory     memory,
                              FT_UInt       num_glyphs,
                              const char**  glyph_names,
                              PS_Unicodes*  table )
      {
        FT_Error  error;
    
    
        /* we first allocate the table */
        table->num_maps = 0;
        table->maps     = 0;
    
        if ( !FT_NEW_ARRAY( table->maps, num_glyphs ) )
        {
          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 = glyph_names[n];
    
    
            if ( gname )
            {
              uni_char = ps_unicode_value( gname );
    
              if ( uni_char != 0 && uni_char != 0xFFFFL )
              {
                map->unicode     = (FT_UInt)uni_char;
                map->glyph_index = n;
                map++;
              }
            }
          }
    
          /* now, compress the table a bit */
          count = (FT_UInt)( map - table->maps );
    
          if ( count > 0 && FT_REALLOC( table->maps,
                                        num_glyphs * sizeof ( PS_UniMap ),
                                        count * sizeof ( PS_UniMap ) ) )
            count = 0;
    
          if ( count == 0 )
          {
            FT_FREE( table->maps );
            if ( !error )
              error = PSnames_Err_Invalid_Argument;  /* no unicode chars here! */
          }
          else
            /* sort the table in increasing order of unicode values */
            ft_qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps );
    
          table->num_maps = count;
        }
    
        return error;
      }
    
    
      static FT_UInt
      ps_lookup_unicode( PS_Unicodes*  table,
                         FT_ULong      unicode )
      {
        PS_UniMap  *min, *max, *mid;
    
    
        /* perform a binary search on the table */
    
        min = table->maps;
        max = min + table->num_maps - 1;
    
        while ( min <= max )
        {
          mid = min + ( max - min ) / 2;
          if ( mid->unicode == unicode )
            return mid->glyph_index;
    
          if ( min == max )
            break;
    
          if ( mid->unicode < unicode )
            min = mid + 1;
          else
            max = mid - 1;
        }
    
        return 0xFFFFU;
      }
    
    
      static FT_ULong
      ps_next_unicode( PS_Unicodes*  table,
                       FT_ULong      unicode )
      {
        PS_UniMap  *min, *max, *mid;
    
    
        unicode++;
        /* perform a binary search on the table */
    
        min = table->maps;
        max = min + table->num_maps - 1;
    
        while ( min <= max )
        {
          mid = min + ( max - min ) / 2;
          if ( mid->unicode == unicode )
            return unicode;
    
          if ( min == max )
            break;
    
          if ( mid->unicode < unicode )
            min = mid + 1;
          else
            max = mid - 1;
        }
    
        if ( max < table->maps )
          max = table->maps;
    
        while ( max < table->maps + table->num_maps )
        {
          if ( unicode < max->unicode )
            return max->unicode;
          max++;
        }
    
        return 0;
      }
    
    
    #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
    
    
      static const char*
      ps_get_macintosh_name( FT_UInt  name_index )
      {
        if ( name_index >= 258 )
          name_index = 0;
    
        return ps_glyph_names[mac_standard_names[name_index]];
      }
    
    
      static const char*
      ps_get_standard_strings( FT_UInt  sid )
      {
        return ( sid < NUM_SID_GLYPHS ? sid_standard_names[sid] : 0 );
      }
    
    
      static
      const PSNames_Interface  psnames_interface =
      {
    #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
    
        (PS_Unicode_Value_Func)    ps_unicode_value,
        (PS_Build_Unicodes_Func)   ps_build_unicode_table,
        (PS_Lookup_Unicode_Func)   ps_lookup_unicode,
    
    #else
    
        0,
        0,
        0,
    
    #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
    
        (PS_Macintosh_Name_Func)    ps_get_macintosh_name,
        (PS_Adobe_Std_Strings_Func) ps_get_standard_strings,
    
        t1_standard_encoding,
        t1_expert_encoding,
    
    #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
        (PS_Next_Unicode_Func)     ps_next_unicode
    #else
        0
    #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
    
      };
    
    
    #endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */
    
    
      FT_CALLBACK_TABLE_DEF
      const FT_Module_Class  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 */
    
    #ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES
        0,
    #else
        (void*)&psnames_interface,   /* module specific interface */
    #endif
    
        (FT_Module_Constructor)0,
        (FT_Module_Destructor) 0,
        (FT_Module_Requester)  0
      };
    
    
    /* END */