[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Devel] bugfix and improvement for Macintosh sfnt load!

From: Martin Muskens
Subject: [Devel] bugfix and improvement for Macintosh sfnt load!
Date: Thu, 21 Mar 2002 10:41:06 +0100


in ftmac the routine FT_New_Face_From_SFNT contains a bug.

The line
                sfnt = GetResource( 'sfnt', sfnt_id );
loads the sftt in memory, but because it is a handle (Mac handle) this memory 
can be "unloaded" by the OS.
When making the allocation
                ALLOC( sfnt_data, (FT_Long)sfnt_size ) 
this sometimes happens. ( Japanese fonts are BIG)
After that, the line 
                memcpy( sfnt_data, *sfnt, sfnt_size );
doesn't copy the sfnt anymore, but garbage.

What's also a problem with large files, is that sfnt and sfnt_data after the 
                ALLOC( sfnt_data, (FT_Long)sfnt_size )
both are (large) blocks of memory that both contain ( after the memcpy) the 
same data.
This can be avoided.

Here is my proposal for the new routine:

  static FT_Error
  FT_New_Face_From_SFNT( FT_Library  library,
                         short       sfnt_id,
                         FT_Long     face_index,
                         FT_Face*    aface )
    Handle     sfnt = NULL;
    FT_Byte*   sfnt_data;
    size_t     sfnt_size;
    FT_Stream  stream = NULL;
    FT_Error   error = 0;
    FT_Memory  memory = library->memory;

    SetResLoad (false); // tell the resource manager not to load the data in 
memory ( *sfnt stays 0x00000000 )
    sfnt = GetResource( 'sfnt', sfnt_id );
    SetResLoad (true);// tell the resource manager to load resources normal 

    if ( ResError() )
      return FT_Err_Invalid_Handle;

        sfnt_size = GetResourceSizeOnDisk( sfnt ); // get the resource size 
from disk ( = also more accurate than GetHandleSize )

    if ( ALLOC( sfnt_data, (FT_Long)sfnt_size ) )
      ReleaseResource( sfnt );
      return error;

    ReadPartialResource(sfnt, 0, sfnt_data, sfnt_size );

    ReleaseResource( sfnt );

    return open_face_from_buffer( library,
                                  aface );

This routine only needs the memory block one time. There is also no chance of 
losing the data.

best regards

Martin Muskens

reply via email to

[Prev in Thread] Current Thread [Next in Thread]