freetype-devel
[Top][All Lists]
Advanced

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

[Devel] Freetype Auto-hinter bug...


From: Malcolm Taylor
Subject: [Devel] Freetype Auto-hinter bug...
Date: Wed, 25 Feb 2004 14:41:33 +1300
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6a) Gecko/20031030

Hi,

Not sure if this is the right place to email this bug report. Also could someone email me directly if they get this?

I've found a bug in the auto-hinter. It has to do with updating the character advance.

In ahhint.c:
>>>>>>>
     /* we now need to hint the metrics according to the change in */
     /* width/positioning that occured during the hinting process  */
     if(outline->num_vedges>0)
     {
       FT_Pos   old_advance, old_rsb, old_lsb, new_lsb;
       AH_Edge  edge1 = outline->vert_edges;     /* leftmost edge  */
       AH_Edge  edge2 = edge1 +
                        outline->num_vedges - 1; /* rightmost edge */


       old_advance = hinter->pp2.x;
       old_rsb     = old_advance - edge2->opos;
       old_lsb     = edge1->opos;
       new_lsb     = edge1->pos;

       hinter->pp1.x = ( ( new_lsb    - old_lsb ) + 32 ) & -64;
       hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64;

#if 0
       /* try to fix certain bad advance computations */
       if ( hinter->pp2.x + hinter->pp1.x == edge2->pos && old_rsb > 4 )
         hinter->pp2.x += 64;
#endif
     }
     else {
       hinter->pp1.x = ( hinter->pp1.x + 32 ) & -64;
       hinter->pp2.x = ( hinter->pp2.x + 32 ) & -64;
     }

<<<<<<<

replaces:

>>>>>>>
     /* we now need to hint the metrics according to the change in */
     /* width/positioning that occured during the hinting process  */
     {
       FT_Pos   old_advance, old_rsb, old_lsb, new_lsb;
       AH_Edge  edge1 = outline->vert_edges;     /* leftmost edge  */
       AH_Edge  edge2 = edge1 +
                        outline->num_vedges - 1; /* rightmost edge */


       old_advance = hinter->pp2.x;
       old_rsb     = old_advance - edge2->opos;
       old_lsb     = edge1->opos;
       new_lsb     = edge1->pos;

       hinter->pp1.x = ( ( new_lsb    - old_lsb ) + 32 ) & -64;
       hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64;

#if 0
       /* try to fix certain bad advance computations */
       if ( hinter->pp2.x + hinter->pp1.x == edge2->pos && old_rsb > 4 )
         hinter->pp2.x += 64;
#endif
     }
<<<<<<<

There are some glyphs where outline->num_vedges==0, and so the edge1 and edge2 above are pointing to potentially uninitialised memory (especially edge2). For this reason I added the check above, which just rounds the point values if this is true.

I found this since using Arial Unicode MS if used before Verdana would make some Verdana characters return the wrong advance (inconsistently).

Malcolm




reply via email to

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