freetype
[Top][All Lists]
Advanced

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

Re: [ft] Help finding glyphs in TTF files


From: Michael Franklin
Subject: Re: [ft] Help finding glyphs in TTF files
Date: Mon, 1 Apr 2013 05:44:51 -0700 (PDT)

>Just to be sure: The TTF files for ARM and Linux Mint are *really*
>identical, right?

Yep, I wrote a program on each platform to output the files as hex strings and 
compared the two files.  They were identical.  This further verifies that my 
disk IO routines are working well.  But, again, this has been working fine for 
my other libraries.


>What about using different compilation optimization options?

Tried that too.  Same behavior for O0, O1, and O2.  I'm using O2 for my arm 
system.

>  if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 )
>  {
>    /* validate this cmap sub-table */
>    error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
>  }
>
>  if ( valid.validator.error == 0 )
>  ...
>
>On the ARM platform, `valid.validator.error' is incorrectly non-zero...

Well, I looked into this in detail and found that setjmp and longjmp are 
working properly.  The problem is in the clazz->validate function; more 
specifically tt_cmap4_validate in ttcmap.c.  It fails here:

/* Some fonts handle the last segment incorrectly.  In */
/* theory, 0xFFFF might point to an ordinary glyph --  */
/* a cmap 4 is versatile and could be used for any     */
/* encoding, not only Unicode.  However, reality shows */
/* that far too many fonts are sloppy and incorrectly  */
/* set all fields but `start' and `end' for the last   */
/* segment if it contains only a single character.     */
/*                                                     */
/* We thus omit the test here, delaying it to the      */
/* routines which actually access the cmap.            */
else if ( n != num_segs - 1                       ||
        !( start == 0xFFFFU && end == 0xFFFFU ) )
{
    if ( p < glyph_ids                              ||
         p + ( end - start + 1 ) * 2 > valid->limit )
      FT_INVALID_DATA;
}

p + (end - start + 1) *2 is greater than valid->limit.  I compared start, end, 
delta, offset with with working executable on my Windows 8 computer, and I see 
the following:

**ARM
start = 0
end = 126
delta = 32
offset = 9856

**Windows 8  //Switched from Linux Mint to Windows 8 here (Thanks for the 
Visual Studio 2010 solution)

start = 32
end = 126
delta = -29    /*  Notice my magic number -29 here */
offset = 0


I then examined the contents of face->cmap_table on both platforms, and they 
are completely different.  Not off by a couple of bytes, but rather totally 
different.  I've navigated through the code and found that the cmap is loaded 
in tt_face_load_cmap, and it appears that the cmap is loaded using the 
FT_FRAME_EXTRACT macro.

To make a long story short face->cmap_table is pointing to the wrong stuff.  
I'm currently tracing data coming off the disk and comparing it with PC 
program.  I've added the following trace to FT_Stream_EnterFrame:

#else
      if ( FT_QALLOC( stream->base, count ) )
        goto Exit;
#endif
      /* read it */
      printf("Reading: %d, %d, %d, ", stream->pos, stream->base, count);    
//My Trace
      read_bytes = stream->read( stream, stream->pos,
                                 stream->base, count );
      printf("%d\r\n", read_bytes);                                             
                  //My Trace
      if ( read_bytes < count )



*** Here's what I see on my Windows 8 program:
Reading: 268, 13759296, 16, 16
Reading: 284, 13759296, 16, 16
Reading: 12, 13759648, 16, 16    // stream->base advanced by 352 bytes
Reading: 300, 13759648, 54, 54

** Here's what I see on my ARM platform for the same part of the program
Reading: 268, 536905480, 16, 16
Reading: 284, 536905480, 16, 16
Reading: 12, 536906728, 16, 16    // stream->base advanced by 1248 bytes
Reading: 300, 536906728, 54, 54

FINALLY, MY QUESTION:
Should base->stream advance by the same number of bytes on both platforms?  It 
appears base->stream is set in FT_QMALLOC.  I'm wondering if something's wrong 
with my ARM platform's malloc.  I'm using the newlib C library.

Thanks again for any help.
Mike


----- Original Message -----
From: Werner LEMBERG <address@hidden>
To: address@hidden
Cc: address@hidden
Sent: Sunday, March 31, 2013 10:32 PM
Subject: Re: [ft] Help finding glyphs in TTF files


Just to be sure: The TTF files for ARM and Linux Mint are *really*
identical, right?

>>What compiler warnings do you get?
>
> The only warning I get is that 'gray_dump_cell's is defined but not
> used due to the FT_DEBUG_LEVEL_TRACE define.

Yes, this is expected and harmless.

> It looks like the setjmp/longjmp code is just doing a validation.  I
> commented out this code, but the behavior is the same, so unless I'm
> not understanding well, I don't think this is the source of the
> problem.

Mhmm, I'm not sure that you are correct.  Can you use a debugger?  The
problematic code is in function `tt_face_build_cmaps' (in file
src/sfnt/ttcmap.c):

  if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 )
  {
    /* validate this cmap sub-table */
    error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
  }

  if ( valid.validator.error == 0 )
  ...

On the ARM platform, `valid.validator.error' is incorrectly non-zero...

What about using different compilation optimization options?


    Werner



reply via email to

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