Пример #1
0
  static FT_Error
  cff_index_load_offsets( CFF_Index  idx )
  {
    FT_Error   error  = 0;
    FT_Stream  stream = idx->stream;
    FT_Memory  memory = stream->memory;


    if ( idx->count > 0 && idx->offsets == NULL )
    {
      FT_Byte    offsize = idx->off_size;
      FT_ULong   data_size;
      FT_Byte*   p;
      FT_Byte*   p_end;
      FT_ULong*  poff;


      data_size = (FT_ULong)( idx->count + 1 ) * offsize;

      if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
           FT_STREAM_SEEK( idx->start + 3 )             ||
           FT_FRAME_ENTER( data_size )                  )
        goto Exit;

      poff   = idx->offsets;
      p      = (FT_Byte*)stream->cursor;
      p_end  = p + data_size;

      switch ( offsize )
      {
      case 1:
        for ( ; p < p_end; p++, poff++ )
          poff[0] = p[0];
        break;

      case 2:
        for ( ; p < p_end; p += 2, poff++ )
          poff[0] = FT_PEEK_USHORT( p );
        break;

      case 3:
        for ( ; p < p_end; p += 3, poff++ )
          poff[0] = FT_PEEK_OFF3( p );
        break;

      default:
        for ( ; p < p_end; p += 4, poff++ )
          poff[0] = FT_PEEK_ULONG( p );
      }

      FT_FRAME_EXIT();
    }

  Exit:
    if ( error )
      FT_FREE( idx->offsets );

    return error;
  }
Пример #2
0
  tt_face_find_bdf_prop( TT_Face           face,
                         const char*       property_name,
                         BDF_PropertyRec  *aprop )
  {
    TT_BDF     bdf   = &face->bdf;
    FT_Size    size  = FT_FACE(face)->size;
    FT_Error   error = FT_Err_Ok;
    FT_Byte*   p;
    FT_UInt    count;
    FT_Byte*   strike;
    FT_Offset  property_len;


    aprop->type = BDF_PROPERTY_TYPE_NONE;

    if ( bdf->loaded == 0 )
    {
      error = tt_face_load_bdf_props( face, FT_FACE( face )->stream );
      if ( error )
        goto Exit;
    }

    count  = bdf->num_strikes;
    p      = bdf->table + 8;
    strike = p + 4 * count;

    error = FT_ERR( Invalid_Argument );

    if ( size == NULL || property_name == NULL )
      goto Exit;

    property_len = ft_strlen( property_name );
    if ( property_len == 0 )
      goto Exit;

    for ( ; count > 0; count-- )
    {
      FT_UInt  _ppem  = FT_NEXT_USHORT( p );
      FT_UInt  _count = FT_NEXT_USHORT( p );

      if ( _ppem == size->metrics.y_ppem )
      {
        count = _count;
        goto FoundStrike;
      }

      strike += 10 * _count;
    }
    goto Exit;

  FoundStrike:
    p = strike;
    for ( ; count > 0; count-- )
    {
      FT_UInt  type = FT_PEEK_USHORT( p + 4 );

      if ( ( type & 0x10 ) != 0 )
      {
        FT_UInt32  name_offset = FT_PEEK_ULONG( p     );
        FT_UInt32  value       = FT_PEEK_ULONG( p + 6 );

        /* be a bit paranoid for invalid entries here */
        if ( name_offset < bdf->strings_size                    &&
             property_len < bdf->strings_size - name_offset     &&
             ft_strncmp( property_name,
                         (const char*)bdf->strings + name_offset,
                         bdf->strings_size - name_offset ) == 0 )
        {
          switch ( type & 0x0F )
          {
          case 0x00:  /* string */
          case 0x01:  /* atoms */
            /* check that the content is really 0-terminated */
            if ( value < bdf->strings_size &&
                 ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )
            {
              aprop->type   = BDF_PROPERTY_TYPE_ATOM;
              aprop->u.atom = (const char*)bdf->strings + value;
              error         = FT_Err_Ok;
              goto Exit;
            }
            break;

          case 0x02:
            aprop->type      = BDF_PROPERTY_TYPE_INTEGER;
            aprop->u.integer = (FT_Int32)value;
            error            = FT_Err_Ok;
            goto Exit;

          case 0x03:
            aprop->type       = BDF_PROPERTY_TYPE_CARDINAL;
            aprop->u.cardinal = value;
            error             = FT_Err_Ok;
            goto Exit;

          default:
            ;
          }
        }
      }
      p += 10;
    }

  Exit:
    return error;
  }
Пример #3
0
  static void
  t42_parse_sfnts( T42_Face    face,
                   T42_Loader  loader )
  {
    T42_Parser  parser = &loader->parser;
    FT_Memory   memory = parser->root.memory;
    FT_Byte*    cur;
    FT_Byte*    limit  = parser->root.limit;
    FT_Error    error;
    FT_Int      num_tables = 0;
    FT_ULong    count;

    FT_Long     n, string_size, old_string_size, real_size;
    FT_Byte*    string_buf = NULL;
    FT_Bool     allocated  = 0;

    T42_Load_Status  status;


    /* The format is                                */
    /*                                              */
    /*   /sfnts [ <hexstring> <hexstring> ... ] def */
    /*                                              */
    /* or                                           */
    /*                                              */
    /*   /sfnts [                                   */
    /*      <num_bin_bytes> RD <binary data>        */
    /*      <num_bin_bytes> RD <binary data>        */
    /*      ...                                     */
    /*   ] def                                      */
    /*                                              */
    /* with exactly one space after the `RD' token. */

    T1_Skip_Spaces( parser );

    if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' )
    {
      FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Fail;
    }

    T1_Skip_Spaces( parser );
    status          = BEFORE_START;
    string_size     = 0;
    old_string_size = 0;
    count           = 0;

    while ( parser->root.cursor < limit )
    {
      cur = parser->root.cursor;

      if ( *cur == ']' )
      {
        parser->root.cursor++;
        goto Exit;
      }

      else if ( *cur == '<' )
      {
        T1_Skip_PS_Token( parser );
        if ( parser->root.error )
          goto Exit;

        /* don't include delimiters */
        string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 );
        if ( !string_size )
        {
          FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Fail;
        }
        if ( FT_REALLOC( string_buf, old_string_size, string_size ) )
          goto Fail;

        allocated = 1;

        parser->root.cursor = cur;
        (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 );
        old_string_size = string_size;
        string_size = real_size;
      }

      else if ( ft_isdigit( *cur ) )
      {
        if ( allocated )
        {
          FT_ERROR(( "t42_parse_sfnts: "
                     "can't handle mixed binary and hex strings\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Fail;
        }

        string_size = T1_ToInt( parser );
        if ( string_size < 0 )
        {
          FT_ERROR(( "t42_parse_sfnts: invalid string size\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Fail;
        }

        T1_Skip_PS_Token( parser );             /* `RD' */
        if ( parser->root.error )
          return;

        string_buf = parser->root.cursor + 1;   /* one space after `RD' */

        if ( limit - parser->root.cursor < string_size )
        {
          FT_ERROR(( "t42_parse_sfnts: too much binary data\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Fail;
        }
        else
          parser->root.cursor += string_size + 1;
      }

      if ( !string_buf )
      {
        FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Fail;
      }

      /* A string can have a trailing zero (odd) byte for padding. */
      /* Ignore it.                                                */
      if ( ( string_size & 1 ) && string_buf[string_size - 1] == 0 )
        string_size--;

      if ( !string_size )
      {
        FT_ERROR(( "t42_parse_sfnts: invalid string\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Fail;
      }

      for ( n = 0; n < string_size; n++ )
      {
        switch ( status )
        {
        case BEFORE_START:
          /* load offset table, 12 bytes */
          if ( count < 12 )
          {
            face->ttf_data[count++] = string_buf[n];
            continue;
          }
          else
          {
            num_tables     = 16 * face->ttf_data[4] + face->ttf_data[5];
            status         = BEFORE_TABLE_DIR;
            face->ttf_size = 12 + 16 * num_tables;

            if ( (FT_ULong)( limit - parser->root.cursor ) < face->ttf_size )
            {
              FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" ));
              error = FT_THROW( Invalid_File_Format );
              goto Fail;
            }

            if ( FT_REALLOC( face->ttf_data, 12, face->ttf_size ) )
              goto Fail;
          }
          /* fall through */

        case BEFORE_TABLE_DIR:
          /* the offset table is read; read the table directory */
          if ( count < face->ttf_size )
          {
            face->ttf_data[count++] = string_buf[n];
            continue;
          }
          else
          {
            int       i;
            FT_ULong  len;


            for ( i = 0; i < num_tables; i++ )
            {
              FT_Byte*  p = face->ttf_data + 12 + 16 * i + 12;


              len = FT_PEEK_ULONG( p );

              /* Pad to a 4-byte boundary length */
              face->ttf_size += ( len + 3 ) & ~3;
            }

            status = OTHER_TABLES;

            /* there are no more than 256 tables, so no size check here */
            if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables,
                             face->ttf_size + 1 ) )
              goto Fail;
          }
          /* fall through */

        case OTHER_TABLES:
          /* all other tables are just copied */
          if ( count >= face->ttf_size )
          {
            FT_ERROR(( "t42_parse_sfnts: too much binary data\n" ));
            error = FT_THROW( Invalid_File_Format );
            goto Fail;
          }
          face->ttf_data[count++] = string_buf[n];
        }
      }

      T1_Skip_Spaces( parser );
    }

    /* if control reaches this point, the format was not valid */
    error = FT_THROW( Invalid_File_Format );

  Fail:
    parser->root.error = error;

  Exit:
    if ( allocated )
      FT_FREE( string_buf );
  }