Exemplo n.º 1
0
  ftc_cmap_family_compare( FTC_CMapFamily  cfam,
                           FTC_CMapQuery   cquery )
  {
    FT_Int  result = 0;


    /* first, compare face id and type */
    if ( cfam->desc.face_id != cquery->desc->face_id ||
         cfam->desc.type    != cquery->desc->type    )
      goto Exit;

    switch ( cfam->desc.type )
    {
    case FTC_CMAP_BY_INDEX:
      result = ( cfam->desc.u.index == cquery->desc->u.index );
      break;

    case FTC_CMAP_BY_ENCODING:
      result = ( cfam->desc.u.encoding == cquery->desc->u.encoding );
      break;

    case FTC_CMAP_BY_ID:
      result = ( cfam->desc.u.id.platform == cquery->desc->u.id.platform &&
                 cfam->desc.u.id.encoding == cquery->desc->u.id.encoding );
      break;

    default:
      ;
    }

    if ( result )
    {
      /* when found, update the 'family' and 'hash' field of the query */
      FTC_QUERY( cquery )->family = FTC_FAMILY( cfam );
      FTC_QUERY( cquery )->hash   = FTC_CMAP_HASH( cfam, cquery );
    }

  Exit:
    return FT_BOOL( result );
  }
Exemplo n.º 2
0
  FTC_CMapCache_Lookup( FTC_CMapCache  cmap_cache,
                        FTC_FaceID     face_id,
                        FT_Int         cmap_index,
                        FT_UInt32      char_code )
  {
    FTC_Cache         cache = FTC_CACHE( cmap_cache );
    FTC_CMapQueryRec  query;
    FTC_Node          node;
    FT_Error          error;
    FT_UInt           gindex = 0;
    FT_Offset         hash;
    FT_Int            no_cmap_change = 0;


    if ( cmap_index < 0 )
    {
      /* Treat a negative cmap index as a special value, meaning that you */
      /* don't want to change the FT_Face's character map through this    */
      /* call.  This can be useful if the face requester callback already */
      /* sets the face's charmap to the appropriate value.                */

      no_cmap_change = 1;
      cmap_index     = 0;
    }

    if ( !cache )
    {
      FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" ));
      return 0;
    }

    query.face_id    = face_id;
    query.cmap_index = (FT_UInt)cmap_index;
    query.char_code  = char_code;

    hash = FTC_CMAP_HASH( face_id, (FT_UInt)cmap_index, char_code );

#if 1
    FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
                          node, error );
#else
    error = FTC_Cache_Lookup( cache, hash, &query, &node );
#endif
    if ( error )
      goto Exit;

    FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) <
                FTC_CMAP_INDICES_MAX );

    /* something rotten can happen with rogue clients */
    if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >=
                    FTC_CMAP_INDICES_MAX ) )
      return 0; /* XXX: should return appropriate error */

    gindex = FTC_CMAP_NODE( node )->indices[char_code -
                                            FTC_CMAP_NODE( node )->first];
    if ( gindex == FTC_CMAP_UNKNOWN )
    {
      FT_Face  face;


      gindex = 0;

      error = FTC_Manager_LookupFace( cache->manager,
                                      FTC_CMAP_NODE( node )->face_id,
                                      &face );
      if ( error )
        goto Exit;

      if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
      {
        FT_CharMap  old, cmap  = NULL;


        old  = face->charmap;
        cmap = face->charmaps[cmap_index];

        if ( old != cmap && !no_cmap_change )
          FT_Set_Charmap( face, cmap );

        gindex = FT_Get_Char_Index( face, char_code );

        if ( old != cmap && !no_cmap_change )
          FT_Set_Charmap( face, old );
      }

      FTC_CMAP_NODE( node )->indices[char_code -
                                     FTC_CMAP_NODE( node )->first]
        = (FT_UShort)gindex;
    }

  Exit:
    return gindex;
  }
Exemplo n.º 3
0
  FTC_CMapCache_Lookup( FTC_CMapCache  cmap_cache,
                        FTC_FaceID     face_id,
                        FT_Int         cmap_index,
                        FT_UInt32      char_code )
  {
    FTC_Cache         cache = FTC_CACHE( cmap_cache );
    FTC_CMapQueryRec  query;
    FTC_Node          node;
    FT_Error          error;
    FT_UInt           gindex = 0;
    FT_PtrDist        hash;
    FT_Int            no_cmap_change = 0;


    if ( cmap_index < 0 )
    {
      /* Treat a negative cmap index as a special value, meaning that you */
      /* don't want to change the FT_Face's character map through this    */
      /* call.  This can be useful if the face requester callback already */
      /* sets the face's charmap to the appropriate value.                */

      no_cmap_change = 1;
      cmap_index     = 0;
    }

    if ( !cache )
    {
      FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" ));
      return 0;
    }

#ifdef FT_CONFIG_OPTION_OLD_INTERNALS

    /*
     * If cmap_index is greater than the maximum number of cachable
     * charmaps, we assume the request is from a legacy rogue client
     * using old internal header. See include/config/ftoption.h.
     */
    if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE && !no_cmap_change )
    {
      FTC_OldCMapDesc  desc = (FTC_OldCMapDesc) face_id;


      char_code     = (FT_UInt32)cmap_index;
      query.face_id = desc->face_id;


      switch ( desc->type )
      {
      case FTC_OLD_CMAP_BY_INDEX:
        query.cmap_index = desc->u.index;
        query.char_code  = (FT_UInt32)cmap_index;
        break;

      case FTC_OLD_CMAP_BY_ENCODING:
        {
          FT_Face  face;


          error = FTC_Manager_LookupFace( cache->manager, desc->face_id,
                                          &face );
          if ( error )
            return 0;

          FT_Select_Charmap( face, desc->u.encoding );

          return FT_Get_Char_Index( face, char_code );
        }

      default:
        return 0;
      }
    }
    else

#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */

    {
      query.face_id    = face_id;
      query.cmap_index = (FT_UInt)cmap_index;
      query.char_code  = char_code;
    }

    hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );

#if 1
    FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
                          node, error );
#else
    error = FTC_Cache_Lookup( cache, hash, &query, &node );
#endif
    if ( error )
      goto Exit;

    FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) <
                FTC_CMAP_INDICES_MAX );

    /* something rotten can happen with rogue clients */
    if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >=
                    FTC_CMAP_INDICES_MAX ) )
      return 0; /* XXX: should return appropriate error */

    gindex = FTC_CMAP_NODE( node )->indices[char_code -
                                            FTC_CMAP_NODE( node )->first];
    if ( gindex == FTC_CMAP_UNKNOWN )
    {
      FT_Face  face;


      gindex = 0;

      error = FTC_Manager_LookupFace( cache->manager,
                                      FTC_CMAP_NODE( node )->face_id,
                                      &face );
      if ( error )
        goto Exit;

#ifdef FT_MAX_CHARMAP_CACHEABLE
      /* something rotten can happen with rogue clients */
      if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE )
        return 0; /* XXX: should return appropriate error */
#endif

      if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
      {
        FT_CharMap  old, cmap  = NULL;


        old  = face->charmap;
        cmap = face->charmaps[cmap_index];

        if ( old != cmap && !no_cmap_change )
          FT_Set_Charmap( face, cmap );

        gindex = FT_Get_Char_Index( face, char_code );

        if ( old != cmap && !no_cmap_change )
          FT_Set_Charmap( face, old );
      }

      FTC_CMAP_NODE( node )->indices[char_code -
                                     FTC_CMAP_NODE( node )->first]
        = (FT_UShort)gindex;
    }

  Exit:
    return gindex;
  }
Exemplo n.º 4
0
  ftc_cmap_family_init( FTC_CMapFamily  cfam,
                        FTC_CMapQuery   cquery,
                        FTC_Cache       cache )
  {
    FTC_Manager   manager = cache->manager;
    FTC_CMapDesc  desc = cquery->desc;
    FT_UInt32     hash = 0;
    FT_Error      error;
    FT_Face       face;


    /* setup charmap descriptor */
    cfam->desc = *desc;

    /* let's see whether the rest is correct too */
    error = FTC_Manager_Lookup_Face( manager, desc->face_id, &face );
    if ( !error )
    {
      FT_UInt      count = face->num_charmaps;
      FT_UInt      idx   = count;
      FT_CharMap*  cur   = face->charmaps;


      switch ( desc->type )
      {
      case FTC_CMAP_BY_INDEX:
        idx  = desc->u.index;
        hash = idx * 33;
        break;

      case FTC_CMAP_BY_ENCODING:
        for ( idx = 0; idx < count; idx++, cur++ )
          if ( cur[0]->encoding == desc->u.encoding )
            break;

        hash = idx * 67;
        break;

      case FTC_CMAP_BY_ID:
        for ( idx = 0; idx < count; idx++, cur++ )
        {
          if ( (FT_UInt)cur[0]->platform_id == desc->u.id.platform &&
               (FT_UInt)cur[0]->encoding_id == desc->u.id.encoding )
          {
            hash = ( ( desc->u.id.platform << 8 ) | desc->u.id.encoding ) * 7;
            break;
          }
        }
        break;

      default:
        ;
      }

      if ( idx >= count )
        goto Bad_Descriptor;

      /* compute hash value, both in family and query */
      cfam->index               = idx;
      cfam->hash                = hash ^ FTC_FACE_ID_HASH( desc->face_id );
      FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery );

      error = ftc_family_init( FTC_FAMILY( cfam ),
                               FTC_QUERY( cquery ), cache );
    }

    return error;

  Bad_Descriptor:
    FT_ERROR(( "ftp_cmap_family_init: invalid charmap descriptor\n" ));
    return FTC_Err_Invalid_Argument;
  }