/****************************************************************************
 *
 * psmodule.c
 *
 *   psnames module implementation (body).
 *
 * Copyright (C) 1996-2020 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 <freetype/internal/ftdebug.h>
#include <freetype/internal/ftobjs.h>
#include <freetype/internal/services/svpscmap.h>

#include "psmodule.h"

  /*
   * The file `pstables.h' with its arrays and its function
   * `ft_get_adobe_glyph_index' is useful for other projects also (for
   * example, `pdfium' is using it).  However, if used as a C++ header,
   * including it in two different source files makes it necessary to use
   * `extern const' for the declaration of its arrays, otherwise the data
   * would be duplicated as mandated by the C++ standard.
   *
   * For this reason, we use `DEFINE_PS_TABLES' to guard the function
   * definitions, and `DEFINE_PS_TABLES_DATA' to provide both proper array
   * declarations and definitions.
   */
#include "pstables.h"
#define  DEFINE_PS_TABLES
#define  DEFINE_PS_TABLES_DATA
#include "pstables.h"

#include "psnamerr.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     = NULL;

    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 = FT_THROW( 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 + EXTRA_GLYPH_LIST_SIZE,
                                count );
          error = FT_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,        /* unicode_value         */
    (PS_Unicodes_InitFunc)     ps_unicodes_init,        /* unicodes_init         */
    (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,  /* unicodes_char_index   */
    (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,   /* unicodes_char_next    */

    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,   /* macintosh_name        */
    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings     */

    t1_standard_encoding,                               /* adobe_std_encoding    */
    t1_expert_encoding                                  /* adobe_expert_encoding */
  )

#else

  FT_DEFINE_SERVICE_PSCMAPSREC(
    pscmaps_interface,

    NULL,                                               /* unicode_value         */
    NULL,                                               /* unicodes_init         */
    NULL,                                               /* unicodes_char_index   */
    NULL,                                               /* unicodes_char_next    */

    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,   /* macintosh_name        */
    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings     */

    t1_standard_encoding,                               /* adobe_std_encoding    */
    t1_expert_encoding                                  /* adobe_expert_encoding */
  )

#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */


  FT_DEFINE_SERVICEDESCREC1(
    pscmaps_services,

    FT_SERVICE_ID_POSTSCRIPT_CMAPS, &pscmaps_interface )


  static FT_Pointer
  psnames_get_service( FT_Module    module,
                       const char*  service_id )
  {
    FT_UNUSED( module );

    return ft_service_list_lookup( pscmaps_services, service_id );
  }

#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */


#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
#define PUT_PS_NAMES_SERVICE( a )  NULL
#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*)&pscmaps_interface ),   /* module specific interface */

    (FT_Module_Constructor)NULL,                                       /* module_init   */
    (FT_Module_Destructor) NULL,                                       /* module_done   */
    (FT_Module_Requester)  PUT_PS_NAMES_SERVICE( psnames_get_service ) /* get_interface */
  )


/* END */
