Exemple #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;
  }
  static FT_Error
  tt_face_load_bdf_props( TT_Face    face,
                          FT_Stream  stream )
  {
    TT_BDF    bdf = &face->bdf;
    FT_ULong  length;
    FT_Error  error;


    FT_ZERO( bdf );

    error = tt_face_goto_table( face, TTAG_BDF, stream, &length );
    if ( error                                  ||
         length < 8                             ||
         FT_FRAME_EXTRACT( length, bdf->table ) )
    {
      error = FT_THROW( Invalid_Table );
      goto Exit;
    }

    bdf->table_end = bdf->table + length;

    {
      FT_Byte*   p           = bdf->table;
      FT_UInt    version     = FT_NEXT_USHORT( p );
      FT_UInt    num_strikes = FT_NEXT_USHORT( p );
      FT_ULong   strings     = FT_NEXT_ULONG ( p );
      FT_UInt    count;
      FT_Byte*   strike;


      if ( version != 0x0001                 ||
           strings < 8                       ||
           ( strings - 8 ) / 4 < num_strikes ||
           strings + 1 > length              )
      {
        goto BadTable;
      }

      bdf->num_strikes  = num_strikes;
      bdf->strings      = bdf->table + strings;
      bdf->strings_size = length - strings;

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


      for ( ; count > 0; count-- )
      {
        FT_UInt  num_items = FT_PEEK_USHORT( p + 2 );

        /*
         *  We don't need to check the value sets themselves, since this
         *  is done later.
         */
        strike += 10 * num_items;

        p += 4;
      }

      if ( strike > bdf->strings )
        goto BadTable;
    }

    bdf->loaded = 1;

  Exit:
    return error;

  BadTable:
    FT_FRAME_RELEASE( bdf->table );
    FT_ZERO( bdf );
    error = FT_THROW( Invalid_Table );
    goto Exit;
  }
  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;
  }