freetype-devel
[Top][All Lists]
Advanced

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

Re: [ft-devel] Known problem with FT_StreamRec::base being non-NULL also


From: mpsuzuki
Subject: Re: [ft-devel] Known problem with FT_StreamRec::base being non-NULL also for file-based streams?
Date: Tue, 2 Mar 2010 11:18:28 +0900

Hi,

On Mon, 1 Mar 2010 23:26:13 +0200
Tor Lillqvist <address@hidden> wrote:
>I noticed a problem in the Pango FreeType backend on Windows, where it
>would see a FT_StreamRec with a non-NULL base field, and thus assume
>it is a memory-based stream as the comment in ftsystem.h promises (and
>that base points to the whole font file mapped into memory).

Hmm, the discussion is the thread with subject
"PangoF2 in win32 not applying GSUB"?
  http://www.mail-archive.com/address@hidden/msg01638.html

>I did some debugging, but did not really understand the root cause.

Thank you for efforts, I was watching the thread but
yet I didn't have Pango on Win32 at present...

>Anyway, what seems to be going on is that FreeType in
>FT_Stream_EnterFrame() sets base to non-NULL,

Indeed. FT_Stream_EnterFrame() allocates the buffer
to store the data with requested length.

    233   FT_BASE_DEF( FT_Error )
    234   FT_Stream_EnterFrame( FT_Stream  stream,
    235                         FT_ULong   count )
    236   {

    ...

    244     if ( stream->read )
    245     {

    ...

    249 #ifdef FT_DEBUG_MEMORY
    250       /* assume _ft_debug_file and _ft_debug_lineno are already set */
    251       stream->base = (unsigned char*)ft_mem_qalloc( memory, count, 
&error );
    252       if ( error )
    253         goto Exit;
    254 #else
    255       if ( FT_QALLOC( stream->base, count ) )
    256         goto Exit;
    257 #endif
    258       /* read it */
    259       read_bytes = stream->read( stream, stream->pos,
    260                                  stream->base, count );


>                                              and then in a
>corresponding FT_Stream_ExitFrame() it is set back to NULL.

Indeed. It is to indicate the buffer is freed.

    299   FT_BASE_DEF( void )
    300   FT_Stream_ExitFrame( FT_Stream  stream )
    301   {

    ...

    313     if ( stream->read )
    314     {

    ...

    317 #ifdef FT_DEBUG_MEMORY
    318       ft_mem_free( memory, stream->base );
    319       stream->base = NULL;
    320 #else
    321       FT_FREE( stream->base );
    322 #endif

>                                                            Presumably
>this is supposed to all happen just internally, and the calling code
>outside of FreeType is not supposed to see a FT_StreamRec with
>non-NULL base?

* when FT_Stream object is memory based (a stream
  created from a memory image, or, a file mmap()-ed
  by FT2 internally), FT_StreamRec.base is always
  non-NULL. The value is constant since its creation.

* when FT_Stream object is NOT memory based (the
  streams accessed by standard file I/O, compressed
  file I/O, etc), FT_StreamRec.base is designed to
  be 0 in the eyes of FT2 clients. However, it is
  used for temporal buffer to store the data loaded
  from the file, as you described "dangerous"
  (I sympathize).

Yet I'm not sure about the scenario how non-NULL
FT_StreamRec.base becomes visible for FT2 client.
I think most part of FT2 is written with a pair of
FT_Stream_EnterFrame() & FT_Stream_ExitFrame().
If non-NULL FT_StreamRec.base of non-memory stream
is exposed FT2 clients, it would be a bug.

>               These functions are called repeatedly in pairs,
>occasionally several "enter" followed by one "exit", hmm. But then at
>one point the "exit" function isn't called, and a non-NULL base
>"escapes" into the upper levels. 

Indeed. If you know the function calling the final 
FT_Stream_EnterFrame() and exposes internal base
value to FT2 client, please let me know.

>                                 Any idea what could be happening? Has
>there been problems like this reported for other platforms where
>memory-mapped font files aren't used?

Umm, I cannot remember.

Regards,
mpsuzuki


BTW, in FT2 internals (so, stream->base is not reliable),
the detection if the stream is memory based /or not is
done by checking if the function pointer stream->read is
NULL (memory based) or non-NULL (file etc).
How about using

    if ( face->stream->read == NULL )

instead of

    if ( face->stream->base != NULL )

for the conditional to detect memory based stream?




reply via email to

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