Ignore:
Timestamp:
Dec 3, 2006, 7:29:08 PM (15 years ago)
Author:
Eugene Romanenko
Message:

update to latest freetype cvs, (closes #76)

Location:
trunk/poppler/freetype2/src
Files:
1 added
1 deleted
69 edited

Legend:

Unmodified
Added
Removed
  • trunk/poppler/freetype2/src/autofit/afangles.c

    r150 r165  
    66/*    and very high speed.  It also contains sorting routines (body).      */
    77/*                                                                         */
    8 /*  Copyright 2003, 2004, 2005 by                                          */
     8/*  Copyright 2003, 2004, 2005, 2006 by                                    */
    99/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    1010/*                                                                         */
     
    2121
    2222
    23 #if 1
     23#if 0
     24
     25  FT_LOCAL_DEF( FT_Int )
     26  af_corner_is_flat( FT_Pos  x_in,
     27                     FT_Pos  y_in,
     28                     FT_Pos  x_out,
     29                     FT_Pos  y_out )
     30  {
     31    FT_Pos  ax = x_in;
     32    FT_Pos  ay = y_in;
     33
     34    FT_Pos  d_in, d_out, d_corner;
     35
     36
     37    if ( ax < 0 )
     38      ax = -ax;
     39    if ( ay < 0 )
     40      ay = -ay;
     41    d_in = ax + ay;
     42
     43    ax = x_out;
     44    if ( ax < 0 )
     45      ax = -ax;
     46    ay = y_out;
     47    if ( ay < 0 )
     48      ay = -ay;
     49    d_out = ax + ay;
     50
     51    ax = x_out + x_in;
     52    if ( ax < 0 )
     53      ax = -ax;
     54    ay = y_out + y_in;
     55    if ( ay < 0 )
     56      ay = -ay;
     57    d_corner = ax + ay;
     58
     59    return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
     60  }
     61
     62
     63  FT_LOCAL_DEF( FT_Int )
     64  af_corner_orientation( FT_Pos  x_in,
     65                         FT_Pos  y_in,
     66                         FT_Pos  x_out,
     67                         FT_Pos  y_out )
     68  {
     69    FT_Pos  delta;
     70
     71
     72    delta = x_in * y_out - y_in * x_out;
     73
     74    if ( delta == 0 )
     75      return 0;
     76    else
     77      return 1 - 2 * ( delta < 0 );
     78  }
     79
     80#endif
     81
     82
     83  /*
     84   *  We are not using `af_angle_atan' anymore, but we keep the source
     85   *  code below just in case...
     86   */
     87
     88
     89#if 0
     90
     91
     92  /*
     93   *  The trick here is to realize that we don't need a very accurate angle
     94   *  approximation.  We are going to use the result of `af_angle_atan' to
     95   *  only compare the sign of angle differences, or check whether its
     96   *  magnitude is very small.
     97   *
     98   *  The approximation
     99   *
     100   *    dy * PI / (|dx|+|dy|)
     101   *
     102   *  should be enough, and much faster to compute.
     103   */
     104  FT_LOCAL_DEF( AF_Angle )
     105  af_angle_atan( FT_Fixed  dx,
     106                 FT_Fixed  dy )
     107  {
     108    AF_Angle  angle;
     109    FT_Fixed  ax = dx;
     110    FT_Fixed  ay = dy;
     111
     112
     113    if ( ax < 0 )
     114      ax = -ax;
     115    if ( ay < 0 )
     116      ay = -ay;
     117
     118    ax += ay;
     119
     120    if ( ax == 0 )
     121      angle = 0;
     122    else
     123    {
     124      angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay );
     125      if ( dx < 0 )
     126      {
     127        if ( angle >= 0 )
     128          angle = AF_ANGLE_PI - angle;
     129        else
     130          angle = -AF_ANGLE_PI - angle;
     131      }
     132    }
     133
     134    return angle;
     135  }
     136
     137
     138#elif 0
     139
    24140
    25141  /* the following table has been automatically generated with */
     
    125241
    126242
    127 #else /* 0 */
    128 
    129 /*
    130  * a python script used to generate the following table
    131  *
    132 
    133 import sys, math
    134 
    135 units = 256
    136 scale = units/math.pi
    137 comma = ""
    138 
    139 print ""
    140 print "table of arctan( 1/2^n ) for PI = " + repr( units / 65536.0 ) + " units"
    141 
    142 r = [-1] + range( 32 )
    143 
    144 for n in r:
    145     if n >= 0:
    146         x = 1.0 / ( 2.0 ** n )   # tangent value
    147     else:
    148         x = 2.0 ** ( -n )
    149 
    150     angle  = math.atan( x )      # arctangent
    151     angle2 = angle * scale       # arctangent in FT_Angle units
    152 
    153     # determine which integer value for angle gives the best tangent
    154     lo  = int( angle2 )
    155     hi  = lo + 1
    156     tlo = math.tan( lo / scale )
    157     thi = math.tan( hi / scale )
    158 
    159     errlo = abs( tlo - x )
    160     errhi = abs( thi - x )
    161 
    162     angle2 = hi
    163     if errlo < errhi:
    164         angle2 = lo
    165 
    166     if angle2 <= 0:
    167         break
    168 
    169     sys.stdout.write( comma + repr( int( angle2 ) ) )
    170     comma = ", "
    171 
    172 *
    173 * end of python script
    174 */
    175 
    176 
    177   /* this table was generated for AF_ANGLE_PI = 256 */
    178 #define AF_ANGLE_MAX_ITERS  8
    179 #define AF_TRIG_MAX_ITERS   8
    180 
    181   static const FT_Fixed
    182   af_angle_arctan_table[9] =
    183   {
    184     90, 64, 38, 20, 10, 5, 3, 1, 1
    185   };
    186 
    187 
    188   static FT_Int
    189   af_angle_prenorm( FT_Vector*  vec )
    190   {
    191     FT_Fixed  x, y, z;
    192     FT_Int    shift;
    193 
    194 
    195     x = vec->x;
    196     y = vec->y;
    197 
    198     z     = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
    199     shift = 0;
    200 
    201     if ( z < ( 1L << 27 ) )
    202     {
    203       do
    204       {
    205         shift++;
    206         z <<= 1;
    207       } while ( z < ( 1L << 27 ) );
    208 
    209       vec->x = x << shift;
    210       vec->y = y << shift;
    211     }
    212     else if ( z > ( 1L << 28 ) )
    213     {
    214       do
    215       {
    216         shift++;
    217         z >>= 1;
    218       } while ( z > ( 1L << 28 ) );
    219 
    220       vec->x = x >> shift;
    221       vec->y = y >> shift;
    222       shift  = -shift;
    223     }
    224     return shift;
    225   }
    226 
    227 
    228   static void
    229   af_angle_pseudo_polarize( FT_Vector*  vec )
    230   {
    231     FT_Fixed         theta;
    232     FT_Fixed         yi, i;
    233     FT_Fixed         x, y;
    234     const FT_Fixed  *arctanptr;
    235 
    236 
    237     x = vec->x;
    238     y = vec->y;
    239 
    240     /* Get the vector into the right half plane */
    241     theta = 0;
    242     if ( x < 0 )
    243     {
    244       x = -x;
    245       y = -y;
    246       theta = AF_ANGLE_PI;
    247     }
    248 
    249     if ( y > 0 )
    250       theta = -theta;
    251 
    252     arctanptr = af_angle_arctan_table;
    253 
    254     if ( y < 0 )
    255     {
    256       /* Rotate positive */
    257       yi     = y + ( x << 1 );
    258       x      = x - ( y << 1 );
    259       y      = yi;
    260       theta -= *arctanptr++;  /* Subtract angle */
    261     }
    262     else
    263     {
    264       /* Rotate negative */
    265       yi     = y - ( x << 1 );
    266       x      = x + ( y << 1 );
    267       y      = yi;
    268       theta += *arctanptr++;  /* Add angle */
    269     }
    270 
    271     i = 0;
    272     do
    273     {
    274       if ( y < 0 )
    275       {
    276         /* Rotate positive */
    277         yi     = y + ( x >> i );
    278         x      = x - ( y >> i );
    279         y      = yi;
    280         theta -= *arctanptr++;
    281       }
    282       else
    283       {
    284         /* Rotate negative */
    285         yi     = y - ( x >> i );
    286         x      = x + ( y >> i );
    287         y      = yi;
    288         theta += *arctanptr++;
    289       }
    290     } while ( ++i < AF_TRIG_MAX_ITERS );
    291 
    292 #if 0
    293     /* round theta */
    294     if ( theta >= 0 )
    295       theta =  FT_PAD_ROUND( theta, 2 );
    296     else
    297       theta = -FT_PAD_ROUND( -theta, 2 );
    298 #endif
    299 
    300     vec->x = x;
    301     vec->y = theta;
    302   }
    303 
    304 
    305   /* cf. documentation in fttrigon.h */
    306 
    307   FT_LOCAL_DEF( AF_Angle )
    308   af_angle_atan( FT_Fixed  dx,
    309                  FT_Fixed  dy )
    310   {
    311     FT_Vector  v;
    312 
    313 
    314     if ( dx == 0 && dy == 0 )
    315       return 0;
    316 
    317     v.x = dx;
    318     v.y = dy;
    319     af_angle_prenorm( &v );
    320     af_angle_pseudo_polarize( &v );
    321 
    322     return v.y;
    323   }
    324 
    325 
    326   FT_LOCAL_DEF( AF_Angle )
    327   af_angle_diff( AF_Angle  angle1,
    328                  AF_Angle  angle2 )
    329   {
    330     AF_Angle  delta = angle2 - angle1;
    331 
    332 
    333     delta %= AF_ANGLE_2PI;
    334     if ( delta < 0 )
    335       delta += AF_ANGLE_2PI;
    336 
    337     if ( delta > AF_ANGLE_PI )
    338       delta -= AF_ANGLE_2PI;
    339 
    340     return delta;
    341   }
    342 
    343243#endif /* 0 */
    344244
     
    390290
    391291
    392 #ifdef TEST
    393 
    394 #include <stdio.h>
    395 #include <math.h>
    396 
    397 int main( void )
    398 {
    399   int  angle;
    400   int  dist;
    401 
    402 
    403   for ( dist = 100; dist < 1000; dist++ )
    404   {
    405     for ( angle = AF_ANGLE_PI; angle < AF_ANGLE_2PI * 4; angle++ )
    406     {
    407       double  a = ( angle * 3.1415926535 ) / ( 1.0 * AF_ANGLE_PI );
    408       int     dx, dy, angle1, angle2, delta;
    409 
    410 
    411       dx = dist * cos( a );
    412       dy = dist * sin( a );
    413 
    414       angle1 = ( ( atan2( dy, dx ) * AF_ANGLE_PI ) / 3.1415926535 );
    415       angle2 = af_angle_atan( dx, dy );
    416       delta  = ( angle2 - angle1 ) % AF_ANGLE_2PI;
    417       if ( delta < 0 )
    418         delta = -delta;
    419 
    420       if ( delta >= 2 )
    421       {
    422         printf( "dist:%4d angle:%4d => (%4d,%4d) angle1:%4d angle2:%4d\n",
    423                 dist, angle, dx, dy, angle1, angle2 );
    424       }
    425     }
    426   }
    427   return 0;
    428 }
    429 
    430 #endif /* TEST */
    431 
    432 
    433292/* END */
  • trunk/poppler/freetype2/src/autofit/afcjk.c

    r150 r165  
    14381438  static const AF_Script_UniRangeRec  af_cjk_uniranges[] =
    14391439  {
    1440     { 0x0100,  0xFFFF },
     1440#if 0
     1441    { 0x0100,  0xFFFF },  /* why this? */
     1442#endif
    14411443    { 0x2E80,  0x2EFF },  /* CJK Radicals Supplement */
    14421444    { 0x2F00,  0x2FDF },  /* Kangxi Radicals */
  • trunk/poppler/freetype2/src/autofit/afhints.c

    r150 r165  
    1919#include "afhints.h"
    2020#include "aferrors.h"
     21#include FT_INTERNAL_CALC_H
    2122
    2223
     
    5455
    5556    segment = axis->segments + axis->num_segments++;
     57#if 0
    5658    FT_ZERO( segment );
     59#endif
    5760
    5861  Exit:
     
    189192  af_glyph_hints_dump_segments( AF_GlyphHints  hints )
    190193  {
    191     AF_Point  points = hints->points;
    192194    FT_Int    dimension;
    193195
     
    204206               dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
    205207      printf ( "  [ index |  pos |  dir  | link | serif |"
    206                " numl | first | start ]\n" );
     208               " height  | extra ]\n" );
    207209
    208210      for ( seg = segments; seg < limit; seg++ )
    209211      {
    210         printf ( "  [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
     212        printf ( "  [ %5d | %4d | %5s | %4d | %5d | %5d | %5d ]\n",
    211213                 seg - segments,
    212214                 (int)seg->pos,
     
    214216                 AF_INDEX_NUM( seg->link, segments ),
    215217                 AF_INDEX_NUM( seg->serif, segments ),
    216                  (int)seg->num_linked,
    217                  seg->first - points,
    218                  seg->last - points );
     218                 seg->height,
     219                 seg->height - ( seg->max_coord - seg->min_coord ) );
    219220      }
    220221      printf( "\n" );
     
    263264  }
    264265
    265 #endif /* AF_DEBUG */
    266 
     266#else /* !AF_DEBUG */
     267
     268  /* these empty stubs are only used to link the `ftgrid' test program */
     269  /* when debugging is disabled                                        */
     270
     271  void
     272  af_glyph_hints_dump_points( AF_GlyphHints  hints )
     273  {
     274    FT_UNUSED( hints );
     275  }
     276
     277
     278  void
     279  af_glyph_hints_dump_segments( AF_GlyphHints  hints )
     280  {
     281    FT_UNUSED( hints );
     282  }
     283
     284
     285  void
     286  af_glyph_hints_dump_edges( AF_GlyphHints  hints )
     287  {
     288    FT_UNUSED( hints );
     289  }
     290
     291#endif /* !AF_DEBUG */
    267292
    268293
     
    272297                        FT_Pos  dy )
    273298  {
     299
    274300#if 1
    275     AF_Direction  dir = AF_DIR_NONE;
    276 
    277 
    278     /* atan(1/12) == 4.7 degrees */
    279 
    280     if ( dx < 0 )
    281     {
    282       if ( dy < 0 )
    283       {
    284         if ( -dx * 12 < -dy )
    285           dir = AF_DIR_DOWN;
    286 
    287         else if ( -dy * 12 < -dx )
    288           dir = AF_DIR_LEFT;
    289       }
    290       else /* dy >= 0 */
    291       {
    292         if ( -dx * 12 < dy )
    293           dir = AF_DIR_UP;
    294 
    295         else if ( dy * 12 < -dx )
    296           dir = AF_DIR_LEFT;
    297       }
    298     }
    299     else /* dx >= 0 */
    300     {
    301       if ( dy < 0 )
    302       {
    303         if ( dx * 12 < -dy )
    304           dir = AF_DIR_DOWN;
    305 
    306         else if ( -dy * 12 < dx )
    307           dir = AF_DIR_RIGHT;
    308       }
    309       else  /* dy >= 0 */
    310       {
    311         if ( dx * 12 < dy )
    312           dir = AF_DIR_UP;
    313 
    314         else if ( dy * 12 < dx )
    315           dir = AF_DIR_RIGHT;
    316       }
    317     }
     301
     302    FT_Pos        ll, ss;  /* long and short arm lengths */
     303    AF_Direction  dir;     /* candidate direction        */
     304
     305
     306    if ( dy >= dx )
     307    {
     308      if ( dy >= -dx )
     309      {
     310        dir = AF_DIR_UP;
     311        ll  = dy;
     312        ss  = dx;
     313      }
     314      else
     315      {
     316        dir = AF_DIR_LEFT;
     317        ll  = -dx;
     318        ss  = dy;
     319      }
     320    }
     321    else /* dy < dx */
     322    {
     323      if ( dy >= -dx )
     324      {
     325        dir = AF_DIR_RIGHT;
     326        ll  = dx;
     327        ss  = dy;
     328      }
     329      else
     330      {
     331        dir = AF_DIR_DOWN;
     332        ll  = dy;
     333        ss  = dx;
     334      }
     335    }
     336
     337    ss *= 12;
     338    if ( FT_ABS(ll) <= FT_ABS(ss) )
     339      dir = AF_DIR_NONE;
    318340
    319341    return dir;
     
    349371
    350372  /* compute all inflex points in a given glyph */
     373
     374#if 1
     375
     376  static void
     377  af_glyph_hints_compute_inflections( AF_GlyphHints  hints )
     378  {
     379    AF_Point*  contour       = hints->contours;
     380    AF_Point*  contour_limit = contour + hints->num_contours;
     381
     382
     383    /* do each contour separately */
     384    for ( ; contour < contour_limit; contour++ )
     385    {
     386      AF_Point  point = contour[0];
     387      AF_Point  first = point;
     388      AF_Point  start = point;
     389      AF_Point  end   = point;
     390      AF_Point  before;
     391      AF_Point  after;
     392      FT_Pos    in_x, in_y, out_x, out_y;
     393      AF_Angle  orient_prev, orient_cur;
     394      FT_Int    finished = 0;
     395
     396
     397      /* compute first segment in contour */
     398      first = point;
     399
     400      start = end = first;
     401      do
     402      {
     403        end = end->next;
     404        if ( end == first )
     405          goto Skip;
     406
     407        in_x = end->fx - start->fx;
     408        in_y = end->fy - start->fy;
     409
     410      } while ( in_x == 0 && in_y == 0 );
     411
     412      /* extend the segment start whenever possible */
     413      before = start;
     414      do
     415      {
     416        do
     417        {
     418          start  = before;
     419          before = before->prev;
     420          if ( before == first )
     421            goto Skip;
     422
     423          out_x = start->fx - before->fx;
     424          out_y = start->fy - before->fy;
     425
     426        } while ( out_x == 0 && out_y == 0 );
     427
     428        orient_prev = ft_corner_orientation( in_x, in_y, out_x, out_y );
     429
     430      } while ( orient_prev == 0 );
     431
     432      first = start;
     433
     434      in_x = out_x;
     435      in_y = out_y;
     436
     437      /* now process all segments in the contour */
     438      do
     439      {
     440        /* first, extend current segment's end whenever possible */
     441        after = end;
     442        do
     443        {
     444          do
     445          {
     446            end   = after;
     447            after = after->next;
     448            if ( after == first )
     449              finished = 1;
     450
     451            out_x = after->fx - end->fx;
     452            out_y = after->fy - end->fy;
     453
     454          } while ( out_x == 0 && out_y == 0 );
     455
     456          orient_cur = ft_corner_orientation( in_x, in_y, out_x, out_y );
     457
     458        } while ( orient_cur == 0 );
     459
     460        if ( ( orient_prev + orient_cur ) == 0 )
     461        {
     462          /* we have an inflection point here */
     463          do
     464          {
     465            start->flags |= AF_FLAG_INFLECTION;
     466            start = start->next;
     467
     468          } while ( start != end );
     469
     470          start->flags |= AF_FLAG_INFLECTION;
     471        }
     472
     473        start = end;
     474        end   = after;
     475
     476        orient_prev = orient_cur;
     477        in_x        = out_x;
     478        in_y        = out_y;
     479
     480      } while ( !finished );
     481
     482    Skip:
     483      ;
     484    }
     485  }
     486
     487#else /* old code */
     488
    351489  static void
    352490  af_glyph_hints_compute_inflections( AF_GlyphHints  hints )
     
    455593    }
    456594  }
     595
     596#endif /* old code */
    457597
    458598
     
    703843          else if ( point->out_dir == point->in_dir )
    704844          {
    705             AF_Angle  angle_in, angle_out, delta;
    706 
     845
     846#if 1
    707847
    708848            if ( point->out_dir != AF_DIR_NONE )
    709849              goto Is_Weak_Point;
    710850
     851            if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) )
     852              goto Is_Weak_Point;
     853
     854#else /* old code */
     855
     856            AF_Angle  angle_in, angle_out, delta;
     857
     858
     859            if ( point->out_dir != AF_DIR_NONE )
     860              goto Is_Weak_Point;
     861
    711862            angle_in  = af_angle_atan( in_x, in_y );
    712863            angle_out = af_angle_atan( out_x, out_y );
     
    716867            if ( delta < 2 && delta > -2 )
    717868              goto Is_Weak_Point;
     869
     870#endif /* old code */
     871
    718872          }
    719873          else if ( point->in_dir == -point->out_dir )
     
    11531307    AF_Point  points_limit = points + hints->num_points;
    11541308    AF_Point  point;
    1155    
     1309
    11561310
    11571311    if ( dim == AF_DIMENSION_HORZ )
  • trunk/poppler/freetype2/src/autofit/afhints.h

    r150 r165  
    126126    FT_Short    min_coord;   /* minimum coordinate of segment       */
    127127    FT_Short    max_coord;   /* maximum coordinate of segment       */
     128    FT_Short    height;      /* the hinted segment height           */
    128129
    129130    AF_Edge     edge;        /* the segment's parent edge           */
     
    214215#define AF_HINTS_TEST_OTHER( h, f )   ( (h)->other_flags  & (f) )
    215216
     217
     218#ifdef AF_DEBUG
     219
     220#define AF_HINTS_DO_HORIZONTAL( h )                                     \
     221          ( !_af_debug_disable_horz_hints                            && \
     222            !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
     223
     224#define AF_HINTS_DO_VERTICAL( h )                                     \
     225          ( !_af_debug_disable_vert_hints                          && \
     226            !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
     227
     228#define AF_HINTS_DO_ADVANCE( h )                                \
     229          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
     230
     231#define AF_HINTS_DO_BLUES( h )  ( !_af_debug_disable_blue_hints )
     232
     233#else /* !AF_DEBUG */
     234
    216235#define AF_HINTS_DO_HORIZONTAL( h )                                \
    217236          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
     
    222241#define AF_HINTS_DO_ADVANCE( h )                                \
    223242          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
     243
     244#define AF_HINTS_DO_BLUES( h )  1
     245
     246#endif /* !AF_DEBUG */
    224247
    225248
  • trunk/poppler/freetype2/src/autofit/aflatin.c

    r150 r165  
    472472      {
    473473        FT_Pos  scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
    474         FT_Pos  fitted = FT_PIX_ROUND( scaled );
     474        FT_Pos  fitted = ( scaled + 40 ) & ~63;
    475475
    476476
     
    591591    FT_Error      error         = AF_Err_Ok;
    592592    AF_Segment    segment       = NULL;
     593    AF_SegmentRec seg0;
    593594    AF_Point*     contour       = hints->contours;
    594595    AF_Point*     contour_limit = contour + hints->num_contours;
     
    601602    FT_Pos    max_coord = -32000;
    602603#endif
     604
     605
     606    FT_ZERO( &seg0 );
     607    seg0.score = 32000;
     608    seg0.flags = AF_EDGE_NORMAL;
    603609
    604610    major_dir   = (AF_Direction)FT_ABS( axis->major_dir );
     
    718724            segment->min_coord = (FT_Short)min_pos;
    719725            segment->max_coord = (FT_Short)max_pos;
     726            segment->height    = segment->max_coord - segment->min_coord;
    720727
    721728            on_edge = 0;
     
    743750            goto Exit;
    744751
     752          segment[0]        = seg0;
    745753          segment->dir      = (FT_Char)segment_dir;
    746           segment->flags    = AF_EDGE_NORMAL;
    747754          min_pos = max_pos = point->u;
    748755          segment->first    = point;
    749756          segment->last     = point;
    750757          segment->contour  = contour;
    751           segment->score    = 32000;
    752           segment->len      = 0;
    753           segment->link     = NULL;
    754758          on_edge           = 1;
    755759
     
    767771
    768772    } /* contours */
     773
     774
     775    /* now slightly increase the height of segments when this makes */
     776    /* sense -- this is used to better detect and ignore serifs     */
     777    {
     778      AF_Segment  segments     = axis->segments;
     779      AF_Segment  segments_end = segments + axis->num_segments;
     780
     781
     782      for ( segment = segments; segment < segments_end; segment++ )
     783      {
     784        AF_Point  first   = segment->first;
     785        AF_Point  last    = segment->last;
     786        FT_Pos    first_v = first->v;
     787        FT_Pos    last_v  = last->v;
     788
     789
     790        if ( first == last )
     791          continue;
     792
     793        if ( first_v < last_v )
     794        {
     795          AF_Point  p;
     796
     797
     798          p = first->prev;
     799          if ( p->v < first_v )
     800            segment->height += ( first_v - p->v ) >> 1;
     801
     802          p = last->next;
     803          if ( p->v > last_v )
     804            segment->height += ( p->v - last_v ) >> 1;
     805        }
     806        else
     807        {
     808          AF_Point  p;
     809
     810
     811          p = first->prev;
     812          if ( p->v > first_v )
     813            segment->height += ( p->v - first_v ) >> 1;
     814
     815          p = last->next;
     816          if ( p->v < last_v )
     817            segment->height += ( last_v - p->v ) >> 1;
     818        }
     819      }
     820    }
    769821
    770822#ifdef AF_HINT_METRICS
     
    811863          goto Exit;
    812864
     865        segment[0]     = seg0;
    813866        segment->dir   = segment_dir;
    814         segment->flags = AF_EDGE_NORMAL;
    815867        segment->first = min_point;
    816868        segment->last  = min_point;
    817869        segment->pos   = min_pos;
    818         segment->score = 32000;
    819         segment->len   = 0;
    820         segment->link  = NULL;
    821870
    822871        segment = NULL;
     
    831880          goto Exit;
    832881
     882        segment[0]     = seg0;
    833883        segment->dir   = segment_dir;
    834         segment->flags = AF_EDGE_NORMAL;
    835884        segment->first = max_point;
    836885        segment->last  = max_point;
    837886        segment->pos   = max_pos;
    838         segment->score = 32000;
    839         segment->len   = 0;
    840         segment->link  = NULL;
    841887
    842888        segment = NULL;
     
    866912      len_threshold = 1;
    867913
    868     len_score = AF_LATIN_CONSTANT( hints->metrics, 3000 );
     914    len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );
    869915
    870916    /* now compare each segment to the others */
     
    927973      if ( seg2 )
    928974      {
    929         seg2->num_linked++;
    930975        if ( seg2->link != seg1 )
    931976        {
     
    954999    FT_Fixed      scale;
    9551000    FT_Pos        edge_distance_threshold;
     1001    FT_Pos        segment_length_threshold;
    9561002
    9571003
     
    9631009    up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP
    9641010                                          : AF_DIR_RIGHT;
     1011
     1012    /*
     1013     *  We ignore all segments that are less than 1 pixels in length,
     1014     *  to avoid many problems with serif fonts.  We compute the
     1015     *  corresponding threshold in font units.
     1016     */
     1017    if ( dim == AF_DIMENSION_HORZ )
     1018        segment_length_threshold = FT_DivFix( 96, hints->y_scale );
     1019    else
     1020        segment_length_threshold = 0;
    9651021
    9661022    /*********************************************************************/
     
    9941050
    9951051
     1052      if ( seg->height < segment_length_threshold )
     1053        continue;
     1054
    9961055      /* look for an edge corresponding to the segment */
    9971056      for ( ee = 0; ee < axis->num_edges; ee++ )
     
    11111170          /* check for links -- if seg->serif is set, then seg->link must */
    11121171          /* be ignored                                                   */
    1113           is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );
    1114 
    1115           if ( seg->link || is_serif )
     1172          is_serif = (FT_Bool)( seg->serif               &&
     1173                                seg->serif->edge         &&
     1174                                seg->serif->edge != edge );
     1175
     1176          if ( ( seg->link && seg->link->edge != NULL ) || is_serif )
    11161177          {
    11171178            AF_Edge     edge2;
     
    15251586    {
    15261587      /* strong hinting process: snap the stem width to integer pixels */
     1588      FT_Pos  org_dist = dist;
     1589
    15271590
    15281591      dist = af_latin_snap_width( axis->widths, axis->width_count, dist );
     
    15601623
    15611624          else if ( dist < 128 )
     1625          {
     1626            /* We only round to an integer width if the corresponding */
     1627            /* distortion is less than 1/4 pixel.  Otherwise this     */
     1628            /* makes everything worse since the diagonals, which are  */
     1629            /* not hinted, appear a lot bolder or thinner than the    */
     1630            /* vertical stems.                                        */
     1631
     1632            FT_Int  delta;
     1633
     1634
    15621635            dist = ( dist + 22 ) & ~63;
     1636            delta = dist - org_dist;
     1637            if ( delta < 0 )
     1638              delta = -delta;
     1639
     1640            if (delta >= 16)
     1641            {
     1642              dist = org_dist;
     1643              if ( dist < 48 )
     1644                dist = ( dist + 64 ) >> 1;
     1645            }
     1646          }
    15631647          else
    15641648            /* round otherwise to prevent color fringes in LCD mode */
     
    15931677
    15941678    stem_edge->pos = base_edge->pos + fitted_width;
     1679
     1680    AF_LOG(( "LINK: edge %d (opos=%.2f) linked to (%.2f), "
     1681             "dist was %.2f, now %.2f\n",
     1682             stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
     1683             stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
    15951684  }
    15961685
     
    16341723    /* if needed -- that's only for horizontal edges            */
    16351724
    1636     if ( dim == AF_DIMENSION_VERT )
     1725    if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) )
    16371726    {
    16381727      for ( edge = edges; edge < edge_limit; edge++ )
     
    16631752          continue;
    16641753
     1754        AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), "
     1755                 "was (%.2f)\n",
     1756                 edge1-edges, edge1->opos / 64.0, blue->fit / 64.0,
     1757                 edge1->pos / 64.0 ));
     1758
    16651759        edge1->pos    = blue->fit;
    16661760        edge1->flags |= AF_EDGE_DONE;
     
    16981792
    16991793      /* this should not happen, but it's better to be safe */
    1700       if ( edge2->blue_edge || edge2 < edge )
    1701       {
     1794      if ( edge2->blue_edge )
     1795      {
     1796        AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges ));
     1797
    17021798        af_latin_align_linked_edge( hints, dim, edge2, edge );
    17031799        edge->flags |= AF_EDGE_DONE;
     
    17441840
    17451841          edge->pos  = cur_pos1 - cur_len / 2;
    1746           edge2->pos = cur_pos1 + cur_len / 2;
    1747 
     1842          edge2->pos = edge->pos + cur_len;
    17481843        }
    17491844        else
    17501845          edge->pos = FT_PIX_ROUND( edge->opos );
    17511846
     1847        AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) "
     1848                 "snapped to (%.2f) (%.2f)\n",
     1849                 edge-edges, edge->opos / 64.0,
     1850                 edge2-edges, edge2->opos / 64.0,
     1851                 edge->pos / 64.0, edge2->pos / 64.0 ));
    17521852        anchor = edge;
    17531853
     
    17711871                   (AF_Edge_Flags)edge2->flags );
    17721872
    1773         if ( cur_len < 96 )
     1873        if ( edge2->flags & AF_EDGE_DONE )
     1874          edge->pos = edge2->pos - cur_len;
     1875
     1876        else if ( cur_len < 96 )
    17741877        {
    17751878          FT_Pos  u_off, d_off;
     
    18011904          edge->pos  = cur_pos1 - cur_len / 2;
    18021905          edge2->pos = cur_pos1 + cur_len / 2;
     1906
     1907          AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) "
     1908                   "snapped to (%.2f) and (%.2f)\n",
     1909                   edge-edges, edge->opos / 64.0,
     1910                   edge2-edges, edge2->opos / 64.0,
     1911                   edge->pos / 64.0, edge2->pos / 64.0 ));
    18031912        }
    18041913        else
     
    18251934          edge->pos  = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
    18261935          edge2->pos = edge->pos + cur_len;
     1936
     1937          AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) "
     1938                   "snapped to (%.2f) and (%.2f)\n",
     1939                   edge-edges, edge->opos / 64.0,
     1940                   edge2-edges, edge2->opos / 64.0,
     1941                   edge->pos / 64.0, edge2->pos / 64.0 ));
    18271942        }
    18281943
     
    18311946
    18321947        if ( edge > edges && edge->pos < edge[-1].pos )
     1948        {
     1949          AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n",
     1950                   edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
    18331951          edge->pos = edge[-1].pos;
     1952        }
    18341953      }
    18351954    }
     
    19052024      for ( edge = edges; edge < edge_limit; edge++ )
    19062025      {
     2026        FT_Pos  delta;
     2027
     2028
    19072029        if ( edge->flags & AF_EDGE_DONE )
    19082030          continue;
    19092031
     2032        delta = 1000;
     2033
    19102034        if ( edge->serif )
     2035        {
     2036          delta = edge->serif->opos - edge->opos;
     2037          if ( delta < 0 )
     2038            delta = -delta;
     2039        }
     2040
     2041        if ( delta < 64 + 16 )
     2042        {
    19112043          af_latin_align_serif_edge( hints, edge->serif, edge );
     2044          AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) "
     2045                   "aligned to (%.2f)\n",
     2046                   edge-edges, edge->opos / 64.0,
     2047                   edge->serif - edges, edge->serif->opos / 64.0,
     2048                   edge->pos / 64.0 ));
     2049        }
    19122050        else if ( !anchor )
    19132051        {
     2052          AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n",
     2053                   edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
    19142054          edge->pos = FT_PIX_ROUND( edge->opos );
    19152055          anchor    = edge;
    19162056        }
    19172057        else
    1918           edge->pos = anchor->pos +
    1919                       FT_PIX_ROUND( edge->opos - anchor->opos );
     2058        {
     2059          AF_Edge  before, after;
     2060
     2061
     2062          for ( before = edge - 1; before >= edges; before-- )
     2063            if ( before->flags & AF_EDGE_DONE )
     2064              break;
     2065
     2066          for ( after = edge + 1; after < edge_limit; after++ )
     2067            if ( after->flags & AF_EDGE_DONE )
     2068              break;
     2069
     2070          if ( before >= edges && before < edge   &&
     2071               after < edge_limit && after > edge )
     2072            edge->pos = before->pos +
     2073                          FT_MulDiv( edge->opos - before->opos,
     2074                                     after->pos - before->pos,
     2075                                     after->opos - before->opos );
     2076          else
     2077            edge->pos = anchor->pos +
     2078                          FT_PIX_ROUND( edge->opos - anchor->opos );
     2079
     2080          AF_LOG(( "SERIF_LINK: edge %d (opos=%.2f) snapped to (%.2f)\n",
     2081                   edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
     2082        }
    19202083
    19212084        edge->flags |= AF_EDGE_DONE;
  • trunk/poppler/freetype2/src/autofit/afloader.c

    r150 r165  
    3131
    3232    af_glyph_hints_init( &loader->hints, memory );
    33 
     33#ifdef AF_DEBUG
     34    _af_debug_hints = &loader->hints;
     35#endif
    3436    return FT_GlyphLoader_New( memory, &loader->gloader );
    3537  }
     
    7274    loader->globals = NULL;
    7375
     76#ifdef AF_DEBUG
     77    _af_debug_hints = NULL;
     78#endif
    7479    FT_GlyphLoader_Done( loader->gloader );
    7580    loader->gloader = NULL;
  • trunk/poppler/freetype2/src/autofit/afmodule.c

    r150 r165  
    55/*    Auto-fitter module implementation (body).                            */
    66/*                                                                         */
    7 /*  Copyright 2003, 2004, 2005 by                                          */
     7/*  Copyright 2003, 2004, 2005, 2006 by                                    */
    88/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    99/*                                                                         */
     
    1919#include "afmodule.h"
    2020#include "afloader.h"
     21
     22#ifdef AF_DEBUG
     23  int    _af_debug;
     24  int    _af_debug_disable_horz_hints;
     25  int    _af_debug_disable_vert_hints;
     26  int    _af_debug_disable_blue_hints;
     27  void*  _af_debug_hints;
     28#endif
    2129
    2230#include FT_INTERNAL_OBJECTS_H
  • trunk/poppler/freetype2/src/autofit/aftypes.h

    r150 r165  
    5555
    5656#define xxAF_USE_WARPER  /* only define to use warp hinting */
    57 #define xxAF_DEBUG
     57#define AF_DEBUG
    5858
    5959#ifdef AF_DEBUG
    6060
    6161#include <stdio.h>
    62 
    63 #define AF_LOG( x )  printf x
    64 
    65 #else
     62#define AF_LOG( x )  do { if ( _af_debug ) printf x; } while ( 0 )
     63
     64extern int    _af_debug;
     65extern int    _af_debug_disable_horz_hints;
     66extern int    _af_debug_disable_vert_hints;
     67extern int    _af_debug_disable_blue_hints;
     68extern void*  _af_debug_hints;
     69
     70#else /* !AF_DEBUG */
    6671
    6772#define AF_LOG( x )  do ; while ( 0 )        /* nothing */
    6873
    69 #endif /* AF_DEBUG */
     74#endif /* !AF_DEBUG */
    7075
    7176
     
    119124
    120125
     126#if 0
    121127  /*
    122128   *  compute the angle of a given 2-D vector
     
    127133
    128134
    129 #if 0
    130135  /*
    131136   *  compute `angle2 - angle1'; the result is always within
  • trunk/poppler/freetype2/src/base/ftbase.c

    r150 r165  
    55/*    Single object library component (body only).                         */
    66/*                                                                         */
    7 /*  Copyright 1996-2001, 2002, 2003, 2004 by                               */
     7/*  Copyright 1996-2001, 2002, 2003, 2004, 2006 by                         */
    88/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    99/*                                                                         */
     
    2121#define  FT_MAKE_OPTION_SINGLE_OBJECT
    2222
     23#include "ftcalc.c"
     24#include "ftdbgmem.c"
     25#include "ftgloadr.c"
     26#include "ftnames.c"
     27#include "ftobjs.c"
     28#include "ftoutln.c"
     29#include "ftrfork.c"
     30#include "ftstream.c"
     31#include "fttrigon.c"
    2332#include "ftutil.c"
    24 #include "ftdbgmem.c"
    25 #include "ftstream.c"
    26 #include "ftcalc.c"
    27 #include "fttrigon.c"
    28 #include "ftoutln.c"
    29 #include "ftgloadr.c"
    30 #include "ftobjs.c"
    31 #include "ftnames.c"
    32 #include "ftrfork.c"
    3333
    3434#if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON )
  • trunk/poppler/freetype2/src/base/ftcalc.c

    r150 r165  
    160160
    161161
    162 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
     162#ifdef TT_USE_BYTECODE_INTERPRETER
    163163
    164164  /* documentation is in ftcalc.h */
     
    184184  }
    185185
    186 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
     186#endif /* TT_USE_BYTECODE_INTERPRETER */
    187187
    188188
     
    229229
    230230
    231 #else /* FT_LONG64 */
     231#else /* !FT_LONG64 */
    232232
    233233
     
    303303            FT_Int64  *z )
    304304  {
    305     register FT_UInt32  lo, hi, max;
    306 
    307 
    308     max = x->lo > y->lo ? x->lo : y->lo;
    309     lo  = x->lo + y->lo;
    310     hi  = x->hi + y->hi + ( lo < max );
     305    register FT_UInt32  lo, hi;
     306
     307
     308    lo = x->lo + y->lo;
     309    hi = x->hi + y->hi + ( lo < x->lo );
    311310
    312311    z->lo = lo;
     
    316315
    317316  /* documentation is in freetype.h */
     317
     318  /* The FT_MulDiv function has been optimized thanks to ideas from      */
     319  /* Graham Asher.  The trick is to optimize computation when everything */
     320  /* fits within 32-bits (a rather common case).                         */
     321  /*                                                                     */
     322  /*  we compute 'a*b+c/2', then divide it by 'c'. (positive values)     */
     323  /*                                                                     */
     324  /*  46340 is FLOOR(SQRT(2^31-1)).                                      */
     325  /*                                                                     */
     326  /*  if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 )         */
     327  /*                                                                     */
     328  /*  0x7FFFFFFF - 0x7FFEA810 = 0x157F0                                  */
     329  /*                                                                     */
     330  /*  if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF )                */
     331  /*                                                                     */
     332  /*  and 2*0x157F0 = 176096                                             */
     333  /*                                                                     */
    318334
    319335  FT_EXPORT_DEF( FT_Long )
     
    354370
    355371
    356 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
     372#ifdef TT_USE_BYTECODE_INTERPRETER
    357373
    358374  FT_BASE_DEF( FT_Long )
     
    388404  }
    389405
    390 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
     406#endif /* TT_USE_BYTECODE_INTERPRETER */
    391407
    392408
     
    397413             FT_Long  b )
    398414  {
    399 #if 1
     415    /* use inline assembly to speed up things a bit */
     416
     417#if defined( __GNUC__ ) && defined( i386 )
     418
     419    FT_Long  result;
     420
     421
     422    __asm__ __volatile__ (
     423      "imul  %%edx\n"
     424      "movl  %%edx, %%ecx\n"
     425      "sarl  $31, %%ecx\n"
     426      "addl  $0x8000, %%ecx\n"
     427      "addl  %%ecx, %%eax\n"
     428      "adcl  $0, %%edx\n"
     429      "shrl  $16, %%eax\n"
     430      "shll  $16, %%edx\n"
     431      "addl  %%edx, %%eax\n"
     432      "mov   %%eax, %0\n"
     433      : "=r"(result)
     434      : "a"(a), "d"(b)
     435      : "%ecx"
     436    );
     437    return result;
     438
     439#elif 1
     440
    400441    FT_Long   sa, sb;
    401442    FT_ULong  ua, ub;
     
    406447
    407448    sa = ( a >> ( sizeof ( a ) * 8 - 1 ) );
    408      a = ( a ^ sa ) - sa;
     449    a = ( a ^ sa ) - sa;
    409450    sb = ( b >> ( sizeof ( b ) * 8 - 1 ) );
    410      b = ( b ^ sb ) - sb;
     451    b = ( b ^ sb ) - sb;
    411452
    412453    ua = (FT_ULong)a;
     
    414455
    415456    if ( ua <= 2048 && ub <= 1048576L )
    416     {
    417       ua = ( ua * ub + 0x8000 ) >> 16;
    418     }
     457      ua = ( ua * ub + 0x8000U ) >> 16;
    419458    else
    420459    {
    421       FT_ULong  al = ua & 0xFFFF;
     460      FT_ULong  al = ua & 0xFFFFU;
    422461
    423462
    424463      ua = ( ua >> 16 ) * ub +  al * ( ub >> 16 ) +
    425            ( ( al * ( ub & 0xFFFF ) + 0x8000 ) >> 16 );
     464           ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 );
    426465    }
    427466
     
    440479      return a;
    441480
    442     s  = a; a = FT_ABS(a);
    443     s ^= b; b = FT_ABS(b);
     481    s  = a; a = FT_ABS( a );
     482    s ^= b; b = FT_ABS( b );
    444483
    445484    ua = (FT_ULong)a;
     
    447486
    448487    if ( ua <= 2048 && ub <= 1048576L )
    449     {
    450       ua = ( ua * ub + 0x8000L ) >> 16;
    451     }
     488      ua = ( ua * ub + 0x8000UL ) >> 16;
    452489    else
    453490    {
    454       FT_ULong  al = ua & 0xFFFFL;
     491      FT_ULong  al = ua & 0xFFFFUL;
    455492
    456493
    457494      ua = ( ua >> 16 ) * ub +  al * ( ub >> 16 ) +
    458            ( ( al * ( ub & 0xFFFFL ) + 0x8000L ) >> 16 );
     495           ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 );
    459496    }
    460497
     
    532569
    533570  /* apparently, the second version of this code is not compiled correctly */
    534   /* on Mac machines with the MPW C compiler..  tsk, tsk, tsk...         */
     571  /* on Mac machines with the MPW C compiler..  tsk, tsk, tsk...           */
    535572
    536573#if 1
     
    569606      return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL );
    570607                             /* Return Max/Min Int32 if division overflow. */
    571                              /* This includes division by zero! */
     608                             /* This includes division by zero!            */
    572609    q = 0;
    573610    for ( i = 0; i < 32; i++ )
     
    665702
    666703
     704  /* documentation is in ftcalc.h */
     705
     706  FT_BASE_DEF( FT_Int )
     707  ft_corner_orientation( FT_Pos  in_x,
     708                         FT_Pos  in_y,
     709                         FT_Pos  out_x,
     710                         FT_Pos  out_y )
     711  {
     712    FT_Int  result;
     713
     714
     715    /* deal with the trivial cases quickly */
     716    if ( in_y == 0 )
     717    {
     718      if ( in_x >= 0 )
     719        result = out_y;
     720      else
     721        result = -out_y;
     722    }
     723    else if ( in_x == 0 )
     724    {
     725      if ( in_y >= 0 )
     726        result = -out_x;
     727      else
     728        result = out_x;
     729    }
     730    else if ( out_y == 0 )
     731    {
     732      if ( out_x >= 0 )
     733        result = in_y;
     734      else
     735        result = -in_y;
     736    }
     737    else if ( out_x == 0 )
     738    {
     739      if ( out_y >= 0 )
     740        result = -in_x;
     741      else
     742        result =  in_x;
     743    }
     744    else /* general case */
     745    {
     746
     747#ifdef FT_LONG64
     748
     749      FT_Int64  delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;
     750
     751
     752      if ( delta == 0 )
     753        result = 0;
     754      else
     755        result = 1 - 2 * ( delta < 0 );
     756
     757#else
     758
     759      FT_Int64  z1, z2;
     760
     761
     762      ft_multo64( in_x, out_y, &z1 );
     763      ft_multo64( in_y, out_x, &z2 );
     764
     765      if ( z1.hi > z2.hi )
     766        result = +1;
     767      else if ( z1.hi < z2.hi )
     768        result = -1;
     769      else if ( z1.lo > z2.lo )
     770        result = +1;
     771      else if ( z1.lo < z2.lo )
     772        result = -1;
     773      else
     774        result = 0;
     775
     776#endif
     777    }
     778
     779    return result;
     780  }
     781
     782
     783  /* documentation is in ftcalc.h */
     784
     785  FT_BASE_DEF( FT_Int )
     786  ft_corner_is_flat( FT_Pos  in_x,
     787                     FT_Pos  in_y,
     788                     FT_Pos  out_x,
     789                     FT_Pos  out_y )
     790  {
     791    FT_Pos  ax = in_x;
     792    FT_Pos  ay = in_y;
     793
     794    FT_Pos  d_in, d_out, d_corner;
     795
     796
     797    if ( ax < 0 )
     798      ax = -ax;
     799    if ( ay < 0 )
     800      ay = -ay;
     801    d_in = ax + ay;
     802
     803    ax = out_x;
     804    if ( ax < 0 )
     805      ax = -ax;
     806    ay = out_y;
     807    if ( ay < 0 )
     808      ay = -ay;
     809    d_out = ax + ay;
     810
     811    ax = out_x + in_x;
     812    if ( ax < 0 )
     813      ax = -ax;
     814    ay = out_y + in_y;
     815    if ( ay < 0 )
     816      ay = -ay;
     817    d_corner = ax + ay;
     818
     819    return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
     820  }
     821
     822
    667823/* END */
  • trunk/poppler/freetype2/src/base/ftdbgmem.c

    r150 r165  
    461461
    462462
    463     hash  = (FT_UInt32)(void*)_ft_debug_file +
     463    /* cast to FT_PtrDist first since void* can be larger */
     464    /* than FT_UInt32 and GCC 4.1.1 emits a warning       */
     465    hash  = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file +
    464466              (FT_UInt32)( 5 * _ft_debug_lineno );
    465467    pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
  • trunk/poppler/freetype2/src/base/ftgloadr.c

    r150 r165  
    55/*    The FreeType glyph loader (body).                                    */
    66/*                                                                         */
    7 /*  Copyright 2002, 2003, 2004, 2005 by                                    */
     7/*  Copyright 2002, 2003, 2004, 2005, 2006 by                              */
    88/*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
    99/*                                                                         */
     
    113113    FT_FREE( loader->base.subglyphs );
    114114
     115    loader->base.extra_points2 = NULL;
     116
    115117    loader->max_points    = 0;
    116118    loader->max_contours  = 0;
     
    150152    /* handle extra points table - if any */
    151153    if ( loader->use_extra )
    152       loader->current.extra_points =
    153         loader->base.extra_points + base->n_points;
     154    {
     155      loader->current.extra_points  = loader->base.extra_points +
     156                                      base->n_points;
     157
     158      loader->current.extra_points2 = loader->base.extra_points2 +
     159                                      base->n_points;
     160    }
    154161  }
    155162
     
    162169
    163170
    164     if ( !FT_NEW_ARRAY( loader->base.extra_points, loader->max_points ) )
    165     {
    166       loader->use_extra = 1;
     171    if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
     172    {
     173      loader->use_extra          = 1;
     174      loader->base.extra_points2 = loader->base.extra_points +
     175                                   loader->max_points;
     176
    167177      FT_GlyphLoader_Adjust_Points( loader );
    168178    }
     
    213223        goto Exit;
    214224
    215       if ( loader->use_extra &&
    216            FT_RENEW_ARRAY( loader->base.extra_points, old_max, new_max ) )
    217         goto Exit;
     225      if ( loader->use_extra )
     226      {
     227        if ( FT_RENEW_ARRAY( loader->base.extra_points,
     228                             old_max * 2, new_max * 2 ) )
     229          goto Exit;
     230
     231        FT_ARRAY_MOVE( loader->base.extra_points + new_max,
     232                       loader->base.extra_points + old_max,
     233                       old_max );
     234
     235        loader->base.extra_points2 = loader->base.extra_points + new_max;
     236      }
    218237
    219238      adjust = 1;
     
    356375      /* do we need to copy the extra points? */
    357376      if ( target->use_extra && source->use_extra )
     377      {
    358378        FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points,
    359379                       num_points );
     380        FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2,
     381                       num_points );
     382      }
    360383
    361384      out->n_points   = (short)num_points;
  • trunk/poppler/freetype2/src/base/ftgxval.c

    r150 r165  
    55/*    FreeType API for validating TrueTyepGX/AAT tables (body).            */
    66/*                                                                         */
    7 /*  Copyright 2004, 2005 by                                                */
     7/*  Copyright 2004, 2005, 2006 by                                          */
    88/*  Masatake YAMATO, Redhat K.K,                                           */
    99/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
     
    6363                                 table_length );
    6464    else
    65       error = FT_Err_Invalid_Argument;
     65      error = FT_Err_Unimplemented_Feature;
    6666
    6767  Exit:
     
    109109                                 ckern_table );
    110110    else
    111       error = FT_Err_Invalid_Argument;
     111      error = FT_Err_Unimplemented_Feature;
    112112
    113113  Exit:
  • trunk/poppler/freetype2/src/base/ftmac.c

    r150 r165  
    5454      wrap it into a memory stream, load the TrueType driver and delegate
    5555      the rest of the work to it, by calling FT_Open_Face().
     56
     57    - Some suitcase fonts (notably Onyx) might point the `LWFN' file to
     58      itself, even though it doesn't contains `POST' resources.  To handle
     59      this special case without opening the file an extra time, we just
     60      ignore errors from the `LWFN' and fallback to the `sfnt' if both are
     61      available.
    5662  */
    5763
     
    6571  /* expands to `static inline' which doesn't survive the   */
    6672  /* -ansi compilation flag of GCC.                         */
     73#undef  OS_INLINE
    6774#define OS_INLINE   static __inline__
    6875#include <Carbon/Carbon.h>
     
    7077#include <Resources.h>
    7178#include <Fonts.h>
     79#include <Endian.h>
    7280#include <Errors.h>
    7381#include <Files.h>
     
    537545    /* Isn't that cute? :-)                                */
    538546
    539     return 1 + *( (short*)( fond_data + sizeof ( FamRec ) ) );
     547    return EndianS16_BtoN( *( (short*)( fond_data +
     548                                        sizeof ( FamRec ) ) ) ) + 1;
    540549  }
    541550
     
    550559
    551560    fond     = (FamRec*)fond_data;
    552     face_all = *( (short *)( fond_data + sizeof ( FamRec ) ) ) + 1;
     561    face_all = EndianS16_BtoN( *( (short *)( fond_data +
     562                                             sizeof ( FamRec ) ) ) ) + 1;
    553563    assoc    = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
    554564    face     = 0;
     
    556566    for ( i = 0; i < face_all; i++ )
    557567    {
    558       if ( 0 == assoc[i].fontSize )
     568      if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) )
    559569        face++;
    560570    }
     
    598608      /* if the face at this index is not scalable,
    599609         fall back to the first one (old behavior) */
    600       if ( assoc->fontSize == 0 )
     610      if ( EndianS16_BtoN( assoc->fontSize ) == 0 )
    601611      {
    602612        *have_sfnt = 1;
    603         *sfnt_id   = assoc->fontID;
     613        *sfnt_id   = EndianS16_BtoN( assoc->fontID );
    604614      }
    605615      else if ( base_assoc->fontSize == 0 )
    606616      {
    607617        *have_sfnt = 1;
    608         *sfnt_id   = base_assoc->fontID;
     618        *sfnt_id   = EndianS16_BtoN( base_assoc->fontID );
    609619      }
    610620    }
    611621
    612     if ( fond->ffStylOff )
     622    if ( EndianS32_BtoN( fond->ffStylOff ) )
    613623    {
    614624      unsigned char*  p = (unsigned char*)fond_data;
     
    620630
    621631
    622       p += fond->ffStylOff;
     632      p += EndianS32_BtoN( fond->ffStylOff );
    623633      style = (StyleTable*)p;
    624634      p += sizeof ( StyleTable );
    625       string_count = *(unsigned short*)(p);
     635      string_count = EndianS16_BtoN( *(short*)(p) );
    626636      p += sizeof ( short );
    627637
     
    771781    UInt8     buff[HFS_MAXPATHLEN];
    772782    FT_Error  err;
     783    short     num_faces;
    773784
    774785
     
    777788    HLock( fond );
    778789    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );
    779     HUnlock( fond );
    780790
    781791    if ( lwfn_file_name[0] )
     
    788798
    789799    if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
    790       return 1;
     800      num_faces = 1;
    791801    else
    792       return count_faces_scalable( *fond );
     802      num_faces = count_faces_scalable( *fond );
     803
     804    HUnlock( fond );
     805    return num_faces;
    793806  }
    794807
     
    10111024    if ( error == FT_Err_Ok )
    10121025      (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
     1026    else
     1027      FT_Stream_Free( stream, 0 );
    10131028
    10141029    return error;
     
    11511166    UInt8     path_lwfn[HFS_MAXPATHLEN];
    11521167    OSErr     err;
    1153     FT_Error  error;
     1168    FT_Error  error = FT_Err_Ok;
    11541169
    11551170
     
    12341249
    12351250    if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
    1236       return FT_New_Face_From_LWFN( library,
    1237                                     path_lwfn,
    1238                                     face_index,
    1239                                     aface );
     1251      error = FT_New_Face_From_LWFN( library,
     1252                                     path_lwfn,
     1253                                     face_index,
     1254                                     aface );
     1255    else
     1256      error = FT_Err_Unknown_File_Format;
    12401257
    12411258  found_no_lwfn_file:
    1242     if ( have_sfnt )
    1243       return FT_New_Face_From_SFNT( library,
    1244                                     sfnt_id,
    1245                                     face_index,
    1246                                     aface );
    1247 
    1248     return FT_Err_Unknown_File_Format;
     1259    if ( have_sfnt && FT_Err_Ok != error )
     1260      error = FT_New_Face_From_SFNT( library,
     1261                                     sfnt_id,
     1262                                     face_index,
     1263                                     aface );
     1264
     1265    return error;
    12491266  }
    12501267
  • trunk/poppler/freetype2/src/base/ftobjs.c

    r150 r165  
    7979  ft_validator_run( FT_Validator  valid )
    8080  {
    81     int  result;
    82 
    83 
    84     result = ft_setjmp( valid->jump_buffer );
    85     return result;
     81    /* This function doesn't work!  None should call it. */
     82    FT_UNUSED( valid );
     83
     84    return -1;
    8685  }
    8786
     
    9190                      FT_Error      error )
    9291  {
     92    /* since the cast below also disables the compiler's */
     93    /* type check, we introduce a dummy variable, which  */
     94    /* will be optimized away                            */
     95    volatile jmp_buf* jump_buffer = &valid->jump_buffer;
     96
     97
    9398    valid->error = error;
    94     ft_longjmp( valid->jump_buffer, 1 );
     99
     100    /* throw away volatileness; use `jump_buffer' or the  */
     101    /* compiler may warn about an unused local variable   */
     102    ft_longjmp( *(jmp_buf*) jump_buffer, 1 );
    95103  }
    96104
     
    542550      return FT_Err_Invalid_Face_Handle;
    543551
    544     if ( glyph_index >= (FT_UInt)face->num_glyphs )
    545       return FT_Err_Invalid_Argument;
     552    /* The validity test for `glyph_index' is performed by the */
     553    /* font drivers.                                           */
    546554
    547555    slot = face->glyph;
     
    566574    }
    567575
    568     if ( FT_LOAD_TARGET_MODE( load_flags ) == FT_RENDER_MODE_LIGHT )
    569       load_flags |= FT_LOAD_FORCE_AUTOHINT;
    570 
    571     /* auto-hinter is preferred and should be used */
    572     if ( ( !FT_DRIVER_HAS_HINTER( driver )         ||
    573            ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ) &&
    574          !( load_flags & FT_LOAD_NO_HINTING )        &&
    575          !( load_flags & FT_LOAD_NO_AUTOHINT )       )
    576     {
    577       /* check whether it works for this face */
    578       autohint =
    579         FT_BOOL( hinter                                   &&
    580                  FT_DRIVER_IS_SCALABLE( driver )          &&
    581                  FT_DRIVER_USES_OUTLINES( driver )        &&
    582                  face->internal->transform_matrix.yy > 0  &&
    583                  face->internal->transform_matrix.yx == 0 );
     576    /*
     577     * Determine whether we need to auto-hint or not.
     578     * The general rules are:
     579     *
     580     * - Do only auto-hinting if we have a hinter module,
     581     *   a scalable font format dealing with outlines,
     582     *   and no transforms except simple slants.
     583     *
     584     * - Then, autohint if FT_LOAD_FORCE_AUTOHINT is set
     585     *   or if we don't have a native font hinter.
     586     *
     587     * - Otherwise, auto-hint for LIGHT hinting mode.
     588     *
     589     * - Exception: The font requires the unpatented
     590     *   bytecode interpreter to load properly.
     591     */
     592
     593    autohint = 0;
     594    if ( hinter                                    &&
     595         ( load_flags & FT_LOAD_NO_HINTING  ) == 0 &&
     596         ( load_flags & FT_LOAD_NO_AUTOHINT ) == 0 &&
     597         FT_DRIVER_IS_SCALABLE( driver )           &&
     598         FT_DRIVER_USES_OUTLINES( driver )         &&
     599         face->internal->transform_matrix.yy > 0   &&
     600         face->internal->transform_matrix.yx == 0  )
     601    {
     602      if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) != 0 ||
     603           !FT_DRIVER_HAS_HINTER( driver )              )
     604        autohint = 1;
     605      else
     606      {
     607        FT_Render_Mode  mode = FT_LOAD_TARGET_MODE( load_flags );
     608
     609
     610        if ( mode == FT_RENDER_MODE_LIGHT             ||
     611             face->internal->ignore_unpatented_hinter )
     612          autohint = 1;
     613      }
    584614    }
    585615
     
    15321562      error = IsMacResource( library, stream2, offsets[i],
    15331563                             face_index, aface );
    1534       FT_Stream_Close( stream2 );
     1564      FT_Stream_Free( stream2, 0 );
    15351565
    15361566      FT_TRACE3(( "%s\n", error ? "failed": "successful" ));
     
    25452575      return FT_Err_Invalid_Face_Handle;
    25462576
     2577    if ( encoding == FT_ENCODING_NONE )
     2578      return FT_Err_Invalid_Argument;
     2579
    25472580    /* FT_ENCODING_UNICODE is special.  We try to find the `best' Unicode */
    25482581    /* charmap available, i.e., one with UCS-4 characters, if possible.   */
     
    37223755#if 1
    37233756    /* XXX Modules are removed in the reversed order so that  */
    3724     /* type42 module is removed before truetype module.  This */ 
     3757    /* type42 module is removed before truetype module.  This */
    37253758    /* avoids double free in some occasions.  It is a hack.   */
    37263759    while ( library->num_modules > 0 )
     
    38623895#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
    38633896
    3864  
     3897
    38653898  FT_EXPORT_DEF( FT_Error )
    38663899  FT_Get_SubGlyph_Info( FT_GlyphSlot  glyph,
     
    38733906  {
    38743907    FT_Error  error = FT_Err_Invalid_Argument;
    3875      
    3876 
    3877     if ( glyph != NULL                              && 
     3908
     3909
     3910    if ( glyph != NULL                              &&
    38783911         glyph->format == FT_GLYPH_FORMAT_COMPOSITE &&
    38793912         sub_index < glyph->num_subglyphs           )
    38803913    {
    38813914      FT_SubGlyph  subg = glyph->subglyphs + sub_index;
    3882        
     3915
    38833916
    38843917      *p_index     = subg->index;
  • trunk/poppler/freetype2/src/base/ftotval.c

    r150 r165  
    55/*    FreeType API for validating OpenType tables (body).                  */
    66/*                                                                         */
    7 /*  Copyright 2004 by                                                      */
     7/*  Copyright 2004, 2006 by                                                */
    88/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    99/*                                                                         */
     
    6363                                 JSTF_table );
    6464    else
    65       error = FT_Err_Invalid_Argument;
     65      error = FT_Err_Unimplemented_Feature;
    6666
    6767  Exit:
  • trunk/poppler/freetype2/src/base/ftoutln.c

    r150 r165  
    733733  }
    734734
    735  
     735
    736736  static FT_Bool
    737737  ft_contour_enclosed( FT_Outline*  outline,
     
    935935  {
    936936    FT_Pos      xmin       = 32768L;
    937     FT_Vector*  xmin_point = NULL;
     937    FT_Pos      xmin_ymin  = 32768L;
     938    FT_Pos      xmin_ymax  = -32768L;
    938939    FT_Vector*  xmin_first = NULL;
    939940    FT_Vector*  xmin_last  = NULL;
     
    944945    FT_Vector*  last;
    945946    FT_Vector*  prev;
    946     FT_Vector*  next;
     947    FT_Vector*  point;
     948
     949    int         i;
     950    FT_Pos      ray_y[3];
     951    int         result[3];
    947952
    948953
    949954    if ( !outline || outline->n_points <= 0 )
    950955      return FT_ORIENTATION_TRUETYPE;
     956
     957    /* We use the nonzero winding rule to find the orientation.       */
     958    /* Since glyph outlines behave much more `regular' than arbitrary */
     959    /* cubic or quadratic curves, this test deals with the polygon    */
     960    /* only which is spanned up by the control points.                */
    951961
    952962    first = outline->points;
     
    955965          contour++, first = last + 1 )
    956966    {
    957       FT_Vector*  point;
    958       FT_Int      on_curve;
    959       FT_Int      on_curve_count = 0;
    960       FT_Pos      tmp_xmin       = 32768L;
    961       FT_Vector*  tmp_xmin_point = NULL;
     967      FT_Pos  contour_xmin = 32768L;
     968      FT_Pos  contour_xmax = -32768L;
     969      FT_Pos  contour_ymin = 32768L;
     970      FT_Pos  contour_ymax = -32768L;
     971
    962972
    963973      last = outline->points + *contour;
     
    969979      for ( point = first; point <= last; ++point )
    970980      {
    971         /* Count on-curve points.  If there are less than 3 on-curve */
    972         /* points, just bypass this contour.                         */
    973         on_curve        = outline->tags[point - outline->points] & 1;
    974         on_curve_count += on_curve;
    975 
    976         if ( point->x < tmp_xmin && on_curve )
    977         {
    978           tmp_xmin       = point->x;
    979           tmp_xmin_point = point;
    980         }
    981       }
    982 
    983       if ( on_curve_count > 2 && tmp_xmin < xmin )
    984       {
    985         xmin       = tmp_xmin;
    986         xmin_point = tmp_xmin_point;
     981        if ( point->x < contour_xmin )
     982          contour_xmin = point->x;
     983
     984        if ( point->x > contour_xmax )
     985          contour_xmax = point->x;
     986
     987        if ( point->y < contour_ymin )
     988          contour_ymin = point->y;
     989
     990        if ( point->y > contour_ymax )
     991          contour_ymax = point->y;
     992      }
     993
     994      if ( contour_xmin < xmin          &&
     995           contour_xmin != contour_xmax &&
     996           contour_ymin != contour_ymax )
     997      {
     998        xmin       = contour_xmin;
     999        xmin_ymin  = contour_ymin;
     1000        xmin_ymax  = contour_ymax;
    9871001        xmin_first = first;
    9881002        xmin_last  = last;
     
    9901004    }
    9911005
    992     if ( !xmin_point )
     1006    if ( xmin == 32768 )
    9931007      return FT_ORIENTATION_TRUETYPE;
    9941008
    995     prev = ( xmin_point == xmin_first ) ? xmin_last : xmin_point - 1;
    996     next = ( xmin_point == xmin_last ) ? xmin_first : xmin_point + 1;
    997 
    998     /* Skip off-curve points */
    999     while ( ( outline->tags[prev - outline->points] & 1 ) == 0 )
    1000     {
    1001       if ( prev == xmin_first )
    1002         prev = xmin_last;
    1003       else
    1004         --prev;
    1005     }
    1006 
    1007     while ( ( outline->tags[next - outline->points] & 1 ) == 0 )
    1008     {
    1009       if ( next == xmin_last )
    1010         next = xmin_first;
    1011       else
    1012         ++next;
    1013     }
    1014 
    1015     if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) >
    1016          FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) )
    1017       return FT_ORIENTATION_POSTSCRIPT;
    1018     else
    1019       return FT_ORIENTATION_TRUETYPE;
     1009    ray_y[0] = ( xmin_ymin * 3 + xmin_ymax     ) >> 2;
     1010    ray_y[1] = ( xmin_ymin     + xmin_ymax     ) >> 1;
     1011    ray_y[2] = ( xmin_ymin     + xmin_ymax * 3 ) >> 2;
     1012
     1013    for ( i = 0; i < 3; i++ )
     1014    {
     1015      FT_Pos      left_x;
     1016      FT_Pos      right_x;
     1017      FT_Vector*  left1;
     1018      FT_Vector*  left2;
     1019      FT_Vector*  right1;
     1020      FT_Vector*  right2;
     1021
     1022
     1023    RedoRay:
     1024      left_x  = 32768L;
     1025      right_x = -32768L;
     1026
     1027      left1 = left2 = right1 = right2 = NULL;
     1028
     1029      prev = xmin_last;
     1030      for ( point = xmin_first; point <= xmin_last; prev = point, ++point )
     1031      {
     1032        FT_Pos  tmp_x;
     1033
     1034
     1035        if ( point->y == ray_y[i] || prev->y == ray_y[i] )
     1036        {
     1037          ray_y[i]++;
     1038          goto RedoRay;
     1039        }
     1040
     1041        if ( ( point->y < ray_y[i] && prev->y < ray_y[i] ) ||
     1042             ( point->y > ray_y[i] && prev->y > ray_y[i] ) )
     1043          continue;
     1044
     1045        tmp_x = FT_MulDiv( point->x - prev->x,
     1046                           ray_y[i] - prev->y,
     1047                           point->y - prev->y ) + prev->x;
     1048
     1049        if ( tmp_x < left_x )
     1050        {
     1051          left_x = tmp_x;
     1052          left1  = prev;
     1053          left2  = point;
     1054        }
     1055
     1056        if ( tmp_x > right_x )
     1057        {
     1058          right_x = tmp_x;
     1059          right1  = prev;
     1060          right2  = point;
     1061        }
     1062      }
     1063
     1064      if ( left1 && right1 )
     1065      {
     1066        if ( left1->y < left2->y && right1->y > right2->y )
     1067          result[i] = FT_ORIENTATION_TRUETYPE;
     1068        else if ( left1->y > left2->y && right1->y < right2->y )
     1069          result[i] = FT_ORIENTATION_POSTSCRIPT;
     1070        else
     1071          result[i] = FT_ORIENTATION_NONE;
     1072      }
     1073    }
     1074
     1075    if ( result[0] != FT_ORIENTATION_NONE                     &&
     1076         ( result[0] == result[1] || result[0] == result[2] ) )
     1077      return result[0];
     1078
     1079    if ( result[1] != FT_ORIENTATION_NONE && result[1] == result[2] )
     1080      return result[1];
     1081
     1082    return FT_ORIENTATION_TRUETYPE;
    10201083  }
    10211084
  • trunk/poppler/freetype2/src/base/ftrfork.c

    r150 r165  
    648648                                        &nouse, result_offset );
    649649
    650     FT_Stream_Close( stream2 );
     650    FT_Stream_Free( stream2, 0 );
    651651
    652652    return error;
  • trunk/poppler/freetype2/src/base/ftsynth.c

    r150 r165  
    138138    }
    139139
    140     /* assume the layout is horizontal */
    141     slot->advance.x += xstr;
     140    if ( slot->advance.x )
     141      slot->advance.x += xstr;
     142
     143    if ( slot->advance.y )
     144      slot->advance.y += ystr;
    142145
    143146    slot->metrics.width        += xstr;
  • trunk/poppler/freetype2/src/base/ftutil.c

    r150 r165  
    121121
    122122
    123     if ( cur_count < 0 || new_count < 0 || item_size <= 0 )
     123    /* Note that we now accept `item_size == 0' as a valid parameter, in
     124     * order to cover very weird cases where an ALLOC_MULT macro would be
     125     * called.
     126     */
     127    if ( cur_count < 0 || new_count < 0 || item_size < 0 )
    124128    {
    125129      /* may help catch/prevent nasty security issues */
    126130      error = FT_Err_Invalid_Argument;
    127131    }
    128     else if ( new_count == 0 )
     132    else if ( new_count == 0 || item_size == 0 )
    129133    {
    130134      ft_mem_free( memory, block );
  • trunk/poppler/freetype2/src/bdf/bdfdrivr.c

    r150 r165  
    436436          bsize->size =
    437437            (FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L );
     438        else
     439          bsize->size = bsize->width << 6;
    438440
    439441        prop = bdf_get_font_property( font, "PIXEL_SIZE" );
     
    647649                  FT_Int32      load_flags )
    648650  {
    649     BDF_Face     face   = (BDF_Face)FT_SIZE_FACE( size );
     651    BDF_Face     bdf    = (BDF_Face)FT_SIZE_FACE( size );
     652    FT_Face      face   = FT_FACE( bdf );
    650653    FT_Error     error  = BDF_Err_Ok;
    651654    FT_Bitmap*   bitmap = &slot->bitmap;
    652655    bdf_glyph_t  glyph;
    653     int          bpp    = face->bdffont->bpp;
     656    int          bpp    = bdf->bdffont->bpp;
    654657
    655658    FT_UNUSED( load_flags );
    656659
    657660
    658     if ( !face )
     661    if ( !face || glyph_index >= (FT_UInt)face->num_glyphs )
    659662    {
    660663      error = BDF_Err_Invalid_Argument;
     
    664667    /* index 0 is the undefined glyph */
    665668    if ( glyph_index == 0 )
    666       glyph_index = face->default_glyph;
     669      glyph_index = bdf->default_glyph;
    667670    else
    668671      glyph_index--;
    669672
    670673    /* slot, bitmap => freetype, glyph => bdflib */
    671     glyph = face->bdffont->glyphs[glyph_index];
     674    glyph = bdf->bdffont->glyphs[glyph_index];
    672675
    673676    bitmap->rows  = glyph.bbx.height;
     
    711714     */
    712715    ft_synthesize_vertical_metrics( &slot->metrics,
    713                                     face->bdffont->bbx.height << 6 );
     716                                    bdf->bdffont->bbx.height << 6 );
    714717
    715718  Exit:
  • trunk/poppler/freetype2/src/bdf/bdflib.c

    r150 r165  
    22052205                 bdf_font_t*    *font )
    22062206  {
    2207     unsigned long  lineno;
     2207    unsigned long  lineno = 0; /* make compiler happy */
    22082208    _bdf_parse_t   *p;
    22092209
     
    22252225                             (void *)p, &lineno );
    22262226    if ( error )
    2227       goto Exit;
     2227      goto Fail;
    22282228
    22292229    if ( p->font != 0 )
     
    23172317                             p->font->comments_len,
    23182318                             p->font->comments_len + 1 ) )
    2319           goto Exit;
     2319          goto Fail;
    23202320
    23212321        p->font->comments[p->font->comments_len] = 0;
     
    23382338
    23392339    return error;
     2340
     2341  Fail:
     2342    bdf_free_font( p->font );
     2343
     2344    memory = extmemory;
     2345
     2346    FT_FREE( p->font );
     2347
     2348    goto Exit;
    23402349  }
    23412350
  • trunk/poppler/freetype2/src/cache/ftccmap.c

    r150 r165  
    306306     *
    307307     *  It is also very unlikely that a rogue client is interested
    308      *  in Unicode values 0 to 3.
     308     *  in Unicode values 0 to 15.
     309     *
     310     *  NOTE: The original threshold was 4, but we found a font from the
     311     *        Adobe Acrobat Reader Pack, named `KozMinProVI-Regular.otf',
     312     *        which contains more than 5 charmaps.
    309313     */
    310     if ( cmap_index >= 4 )
     314    if ( cmap_index >= 16 )
    311315    {
    312316      FTC_OldCMapDesc  desc = (FTC_OldCMapDesc) face_id;
  • trunk/poppler/freetype2/src/cff/cffcmap.c

    r150 r165  
    121121
    122122  FT_CALLBACK_DEF( const char* )
    123   cff_sid_to_glyph_name( CFF_Font  cff,
     123  cff_sid_to_glyph_name( TT_Face   face,
    124124                         FT_UInt   idx )
    125125  {
     126    CFF_Font            cff     = (CFF_Font)face->extra.data;
    126127    CFF_Charset         charset = &cff->charset;
    127128    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;
     
    130131
    131132    return cff_index_get_sid_string( &cff->string_index, sid, psnames );
     133  }
     134
     135
     136  FT_CALLBACK_DEF( void )
     137  cff_sid_free_glyph_name( TT_Face      face,
     138                           const char*  gname )
     139  {
     140    FT_Memory  memory = FT_FACE_MEMORY( face );
     141
     142
     143    FT_FREE( gname );
    132144  }
    133145
     
    150162                                   unicodes,
    151163                                   cff->num_glyphs,
    152                                    (PS_Glyph_NameFunc)&cff_sid_to_glyph_name,
    153                                    (FT_Pointer)cff );
     164                                   (PS_GetGlyphNameFunc)&cff_sid_to_glyph_name,
     165                                   (PS_FreeGlyphNameFunc)&cff_sid_free_glyph_name,
     166                                   (FT_Pointer)face );
    154167  }
    155168
  • trunk/poppler/freetype2/src/cff/cffgload.c

    r150 r165  
    22862286
    22872287
     2288    /* in a CID-keyed font, consider `glyph_index' as a CID and map */
     2289    /* it immediately to the real glyph_index -- if it isn't a      */
     2290    /* subsetted font, glyph_indices and CIDs are identical, though */
     2291    if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
     2292         cff->charset.cids )
     2293    {
     2294      if ( glyph_index < cff->charset.max_cid )
     2295        glyph_index = cff->charset.cids[glyph_index];
     2296      else
     2297        return CFF_Err_Invalid_Argument;
     2298    }
     2299    else if ( glyph_index >= cff->num_glyphs )
     2300      return CFF_Err_Invalid_Argument;
     2301
    22882302    if ( load_flags & FT_LOAD_NO_RECURSE )
    22892303      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
     
    23762390      FT_ULong  charstring_len;
    23772391
    2378 
    2379       /* in a CID-keyed font, consider `glyph_index' as a CID and map */
    2380       /* it immediately to the real glyph_index -- if it isn't a      */
    2381       /* subsetted font, glyph_indices and CIDs are identical, though */
    2382       if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
    2383            cff->charset.cids )
    2384       {
    2385         if ( glyph_index < cff->charset.max_cid )
    2386           glyph_index = cff->charset.cids[glyph_index];
    2387         else
    2388           glyph_index = 0;
    2389       }
    23902392
    23912393      cff_decoder_init( &decoder, face, size, glyph, hinting,
  • trunk/poppler/freetype2/src/cff/cffload.c

    r150 r165  
    10641064
    10651065
    1066   /* read a CFF offset from memory */
    1067   static FT_ULong
    1068   cff_get_offset( FT_Byte*  p,
    1069                   FT_Byte   off_size )
    1070   {
    1071     FT_ULong  result;
    1072 
    1073 
    1074     for ( result = 0; off_size > 0; off_size-- )
    1075     {
    1076       result <<= 8;
    1077       result  |= *p++;
    1078     }
    1079 
    1080     return result;
    1081   }
    1082 
    1083 
    10841066  static FT_Error
    10851067  cff_new_index( CFF_Index  idx,
     
    11021084      FT_ULong   data_size;
    11031085      FT_ULong*  poff;
     1086      FT_Byte*   p_end;
    11041087
    11051088
     
    11091092        goto Exit;
    11101093
     1094      if ( offsize < 1 || offsize > 4 )
     1095      {
     1096        error = FT_Err_Invalid_Table;
     1097        goto Exit;
     1098      }
     1099
    11111100      idx->stream   = stream;
    11121101      idx->count    = count;
     
    11181107        goto Exit;
    11191108
    1120       poff = idx->offsets;
    1121       p    = (FT_Byte*)stream->cursor;
    1122 
    1123       for ( ; (FT_Short)count >= 0; count-- )
     1109      poff   = idx->offsets;
     1110      p      = (FT_Byte*)stream->cursor;
     1111      p_end  = p + data_size;
     1112
     1113      switch ( offsize )
    11241114      {
    1125         poff[0] = cff_get_offset( p, offsize );
    1126         poff++;
    1127         p += offsize;
     1115      case 1:
     1116        for ( ; p < p_end; p++, poff++ )
     1117          poff[0] = p[0];
     1118        break;
     1119
     1120      case 2:
     1121        for ( ; p < p_end; p += 2, poff++ )
     1122          poff[0] = FT_PEEK_USHORT( p );
     1123        break;
     1124
     1125      case 3:
     1126        for ( ; p < p_end; p += 3, poff++ )
     1127          poff[0] = FT_PEEK_OFF3( p );
     1128        break;
     1129
     1130      default:
     1131        for ( ; p < p_end; p += 4, poff++ )
     1132          poff[0] = FT_PEEK_ULONG( p );
    11281133      }
    11291134
     
    14941499  /*************************************************************************/
    14951500
     1501  static FT_Error
     1502  cff_charset_compute_cids( CFF_Charset  charset,
     1503                            FT_UInt      num_glyphs,
     1504                            FT_Memory    memory )
     1505  {
     1506    FT_Error   error   = FT_Err_Ok;
     1507    FT_UInt    i;
     1508    FT_UShort  max_cid = 0;
     1509
     1510
     1511    if ( charset->max_cid > 0 )
     1512      goto Exit;
     1513
     1514    for ( i = 0; i < num_glyphs; i++ )
     1515      if ( charset->sids[i] > max_cid )
     1516        max_cid = charset->sids[i];
     1517    max_cid++;
     1518
     1519    if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
     1520      goto Exit;
     1521
     1522    for ( i = 0; i < num_glyphs; i++ )
     1523      charset->cids[charset->sids[i]] = (FT_UShort)i;
     1524
     1525    charset->max_cid = max_cid;
     1526
     1527  Exit:
     1528    return error;
     1529  }
     1530
     1531
     1532  static void
     1533  cff_charset_free_cids( CFF_Charset  charset,
     1534                         FT_Memory    memory )
     1535  {
     1536    FT_FREE( charset->cids );
     1537    charset->max_cid = 0;
     1538  }
     1539
     1540
    14961541  static void
    14971542  cff_charset_done( CFF_Charset  charset,
     
    15011546
    15021547
     1548    cff_charset_free_cids( charset, memory );
     1549
    15031550    FT_FREE( charset->sids );
    1504     FT_FREE( charset->cids );
    15051551    charset->format = 0;
    15061552    charset->offset = 0;
     
    16731719    /* we have to invert the `sids' array for subsetted CID-keyed fonts */
    16741720    if ( invert )
    1675     {
    1676       FT_UInt    i;
    1677       FT_UShort  max_cid = 0;
    1678 
    1679 
    1680       for ( i = 0; i < num_glyphs; i++ )
    1681         if ( charset->sids[i] > max_cid )
    1682           max_cid = charset->sids[i];
    1683       max_cid++;
    1684 
    1685       if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
    1686         goto Exit;
    1687       FT_MEM_ZERO( charset->cids, sizeof ( FT_UShort ) * max_cid );
    1688 
    1689       for ( i = 0; i < num_glyphs; i++ )
    1690         charset->cids[charset->sids[i]] = (FT_UShort)i;
    1691 
    1692       charset->max_cid = max_cid;
    1693     }
     1721      error = cff_charset_compute_cids( charset, num_glyphs, memory );
    16941722
    16951723  Exit:
     
    18971925    else
    18981926    {
    1899       FT_UInt i;
    1900 
    1901 
    19021927      /* We take into account the fact a CFF font can use a predefined */
    19031928      /* encoding without containing all of the glyphs encoded by this */
     
    19221947        encoding->count = 0;
    19231948
     1949        error = cff_charset_compute_cids( charset, num_glyphs,
     1950                                          stream->memory );
     1951        if ( error )
     1952          goto Exit;
     1953
    19241954        for ( j = 0; j < 256; j++ )
    19251955        {
    1926           /* If j is encoded, find the GID for it. */
    1927           if ( encoding->sids[j] )
     1956          FT_UInt  sid = encoding->sids[j];
     1957          FT_UInt  gid = 0;
     1958
     1959
     1960          if ( sid )
     1961            gid = charset->cids[sid];
     1962
     1963          if ( gid != 0 )
    19281964          {
    1929             for ( i = 1; i < num_glyphs; i++ )
    1930               /* We matched, so break. */
    1931               if ( charset->sids[i] == encoding->sids[j] )
    1932                 break;
    1933 
    1934             /* i will be equal to num_glyphs if we exited the above */
    1935             /* loop without a match.  In this case, we also have to */
    1936             /* fix the code to SID mapping.                         */
    1937             if ( i == num_glyphs )
    1938             {
    1939               encoding->codes[j] = 0;
    1940               encoding->sids [j] = 0;
    1941             }
    1942             else
    1943             {
    1944               encoding->codes[j] = (FT_UShort)i;
    1945 
    1946               /* update encoding count */
    1947               if ( encoding->count < j + 1 )
    1948                 encoding->count = j + 1;
    1949             }
     1965            encoding->codes[j] = (FT_UShort)gid;
     1966
     1967            if ( encoding->count < j + 1 )
     1968              encoding->count = j + 1;
     1969          }
     1970          else
     1971          {
     1972            encoding->codes[j] = 0;
     1973            encoding->sids [j] = 0;
    19501974          }
    19511975        }
     
    20142038    if ( error )
    20152039      goto Exit;
    2016  
     2040
    20172041    /* if it is a CID font, we stop there */
    20182042    if ( top->cid_registry != 0xFFFFU )
     
    22992323      for ( idx = 0; idx < font->num_subfonts; idx++ )
    23002324        cff_subfont_done( memory, font->subfonts[idx] );
     2325
     2326      /* the subfonts array has been allocated as a single block */
     2327      FT_FREE( font->subfonts[0] );
    23012328    }
    23022329
  • trunk/poppler/freetype2/src/cid/cidgload.c

    r150 r165  
    231231      return error;
    232232
     233    /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
     234    /*       if we ever support CID-keyed multiple master fonts     */
     235
    233236    decoder.builder.metrics_only = 1;
    234237    decoder.builder.load_points  = 0;
     
    245248
    246249    *max_advance = decoder.builder.advance.x;
     250
     251    psaux->t1_decoder_funcs->done( &decoder );
    247252
    248253    return CID_Err_Ok;
     
    271276
    272277
     278    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
     279    {
     280      error = CID_Err_Invalid_Argument;
     281      goto Exit;
     282    }
     283
    273284    if ( load_flags & FT_LOAD_NO_RECURSE )
    274285      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
     
    285296    cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
    286297
    287     {
    288       error = psaux->t1_decoder_funcs->init( &decoder,
    289                                              cidglyph->face,
    290                                              cidsize,
    291                                              cidglyph,
    292                                              0, /* glyph names -- XXX */
    293                                              0, /* blend == 0 */
    294                                              hinting,
    295                                              FT_LOAD_TARGET_MODE( load_flags ),
    296                                              cid_load_glyph );
    297 
    298       /* set up the decoder */
    299       decoder.builder.no_recurse = FT_BOOL(
    300         ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
    301 
    302       error = cid_load_glyph( &decoder, glyph_index );
    303 
    304       font_matrix = decoder.font_matrix;
    305       font_offset = decoder.font_offset;
    306 
    307       /* save new glyph tables */
    308       psaux->t1_decoder_funcs->done( &decoder );
    309     }
    310 
    311     /* now, set the metrics -- this is rather simple, as   */
     298    error = psaux->t1_decoder_funcs->init( &decoder,
     299                                           cidglyph->face,
     300                                           cidsize,
     301                                           cidglyph,
     302                                           0, /* glyph names -- XXX */
     303                                           0, /* blend == 0 */
     304                                           hinting,
     305                                           FT_LOAD_TARGET_MODE( load_flags ),
     306                                           cid_load_glyph );
     307    if ( error )
     308      goto Exit;
     309
     310    /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
     311    /*       if we ever support CID-keyed multiple master fonts     */
     312
     313    /* set up the decoder */
     314    decoder.builder.no_recurse = FT_BOOL(
     315      ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
     316
     317    error = cid_load_glyph( &decoder, glyph_index );
     318    if ( error )
     319      goto Exit;
     320
     321    font_matrix = decoder.font_matrix;
     322    font_offset = decoder.font_offset;
     323
     324    /* save new glyph tables */
     325    psaux->t1_decoder_funcs->done( &decoder );
     326
     327    /* now set the metrics -- this is rather simple, as    */
    312328    /* the left side bearing is the xMin, and the top side */
    313329    /* bearing the yMax                                    */
    314     if ( !error )
    315     {
    316       cidglyph->outline.flags &= FT_OUTLINE_OWNER;
    317       cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
    318 
    319       /* for composite glyphs, return only left side bearing and */
    320       /* advance width                                           */
    321       if ( load_flags & FT_LOAD_NO_RECURSE )
     330    cidglyph->outline.flags &= FT_OUTLINE_OWNER;
     331    cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
     332
     333    /* for composite glyphs, return only left side bearing and */
     334    /* advance width                                           */
     335    if ( load_flags & FT_LOAD_NO_RECURSE )
     336    {
     337      FT_Slot_Internal  internal = cidglyph->internal;
     338
     339
     340      cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x;
     341      cidglyph->metrics.horiAdvance  = decoder.builder.advance.x;
     342
     343      internal->glyph_matrix      = font_matrix;
     344      internal->glyph_delta       = font_offset;
     345      internal->glyph_transformed = 1;
     346    }
     347    else
     348    {
     349      FT_BBox            cbox;
     350      FT_Glyph_Metrics*  metrics = &cidglyph->metrics;
     351      FT_Vector          advance;
     352
     353
     354      /* copy the _unscaled_ advance width */
     355      metrics->horiAdvance                  = decoder.builder.advance.x;
     356      cidglyph->linearHoriAdvance           = decoder.builder.advance.x;
     357      cidglyph->internal->glyph_transformed = 0;
     358
     359      /* make up vertical ones */
     360      metrics->vertAdvance        = ( face->cid.font_bbox.yMax -
     361                                      face->cid.font_bbox.yMin ) >> 16;
     362      cidglyph->linearVertAdvance = metrics->vertAdvance;
     363
     364      cidglyph->format            = FT_GLYPH_FORMAT_OUTLINE;
     365
     366      if ( size && cidsize->metrics.y_ppem < 24 )
     367        cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
     368
     369      /* apply the font matrix */
     370      FT_Outline_Transform( &cidglyph->outline, &font_matrix );
     371
     372      FT_Outline_Translate( &cidglyph->outline,
     373                            font_offset.x,
     374                            font_offset.y );
     375
     376      advance.x = metrics->horiAdvance;
     377      advance.y = 0;
     378      FT_Vector_Transform( &advance, &font_matrix );
     379      metrics->horiAdvance = advance.x + font_offset.x;
     380
     381      advance.x = 0;
     382      advance.y = metrics->vertAdvance;
     383      FT_Vector_Transform( &advance, &font_matrix );
     384      metrics->vertAdvance = advance.y + font_offset.y;
     385
     386      if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
    322387      {
    323         FT_Slot_Internal  internal = cidglyph->internal;
    324 
    325 
    326         cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x;
    327         cidglyph->metrics.horiAdvance  = decoder.builder.advance.x;
    328 
    329         internal->glyph_matrix         = font_matrix;
    330         internal->glyph_delta          = font_offset;
    331         internal->glyph_transformed    = 1;
     388        /* scale the outline and the metrics */
     389        FT_Int       n;
     390        FT_Outline*  cur = decoder.builder.base;
     391        FT_Vector*   vec = cur->points;
     392        FT_Fixed     x_scale = glyph->x_scale;
     393        FT_Fixed     y_scale = glyph->y_scale;
     394
     395
     396        /* First of all, scale the points */
     397        if ( !hinting || !decoder.builder.hints_funcs )
     398          for ( n = cur->n_points; n > 0; n--, vec++ )
     399          {
     400            vec->x = FT_MulFix( vec->x, x_scale );
     401            vec->y = FT_MulFix( vec->y, y_scale );
     402          }
     403
     404        /* Then scale the metrics */
     405        metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
     406        metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
    332407      }
    333       else
    334       {
    335         FT_BBox            cbox;
    336         FT_Glyph_Metrics*  metrics = &cidglyph->metrics;
    337         FT_Vector          advance;
    338 
    339 
    340         /* copy the _unscaled_ advance width */
    341         metrics->horiAdvance                  = decoder.builder.advance.x;
    342         cidglyph->linearHoriAdvance           = decoder.builder.advance.x;
    343         cidglyph->internal->glyph_transformed = 0;
    344 
    345         /* make up vertical ones */
    346         metrics->vertAdvance        = ( face->cid.font_bbox.yMax -
    347                                         face->cid.font_bbox.yMin ) >> 16;
    348         cidglyph->linearVertAdvance = metrics->vertAdvance;
    349 
    350         cidglyph->format            = FT_GLYPH_FORMAT_OUTLINE;
    351 
    352         if ( size && cidsize->metrics.y_ppem < 24 )
    353           cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
    354 
    355         /* apply the font matrix */
    356         FT_Outline_Transform( &cidglyph->outline, &font_matrix );
    357 
    358         FT_Outline_Translate( &cidglyph->outline,
    359                               font_offset.x,
    360                               font_offset.y );
    361 
    362         advance.x = metrics->horiAdvance;
    363         advance.y = 0;
    364         FT_Vector_Transform( &advance, &font_matrix );
    365         metrics->horiAdvance = advance.x + font_offset.x;
    366         advance.x = 0;
    367         advance.y = metrics->vertAdvance;
    368         FT_Vector_Transform( &advance, &font_matrix );
    369         metrics->vertAdvance = advance.y + font_offset.y;
    370 
    371         if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
    372         {
    373           /* scale the outline and the metrics */
    374           FT_Int       n;
    375           FT_Outline*  cur = decoder.builder.base;
    376           FT_Vector*   vec = cur->points;
    377           FT_Fixed     x_scale = glyph->x_scale;
    378           FT_Fixed     y_scale = glyph->y_scale;
    379 
    380 
    381           /* First of all, scale the points */
    382           if ( !hinting || !decoder.builder.hints_funcs )
    383             for ( n = cur->n_points; n > 0; n--, vec++ )
    384             {
    385               vec->x = FT_MulFix( vec->x, x_scale );
    386               vec->y = FT_MulFix( vec->y, y_scale );
    387             }
    388 
    389           /* Then scale the metrics */
    390           metrics->horiAdvance  = FT_MulFix( metrics->horiAdvance,  x_scale );
    391           metrics->vertAdvance  = FT_MulFix( metrics->vertAdvance,  y_scale );
    392         }
    393 
    394         /* compute the other metrics */
    395         FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
    396 
    397         metrics->width  = cbox.xMax - cbox.xMin;
    398         metrics->height = cbox.yMax - cbox.yMin;
    399 
    400         metrics->horiBearingX = cbox.xMin;
    401         metrics->horiBearingY = cbox.yMax;
    402 
    403         /* make up vertical ones */
    404         ft_synthesize_vertical_metrics( metrics,
    405                                         metrics->vertAdvance );
    406       }
    407     }
    408 
     408
     409      /* compute the other metrics */
     410      FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
     411
     412      metrics->width  = cbox.xMax - cbox.xMin;
     413      metrics->height = cbox.yMax - cbox.yMin;
     414
     415      metrics->horiBearingX = cbox.xMin;
     416      metrics->horiBearingY = cbox.yMax;
     417
     418      /* make up vertical ones */
     419      ft_synthesize_vertical_metrics( metrics,
     420                                      metrics->vertAdvance );
     421    }
     422
     423  Exit:
    409424    return error;
    410425  }
  • trunk/poppler/freetype2/src/cid/cidload.c

    r150 r165  
    55/*    CID-keyed Type1 font loader (body).                                  */
    66/*                                                                         */
    7 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005 by                         */
     7/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */
    88/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    99/*                                                                         */
     
    241241#include "cidtoken.h"
    242242
    243     T1_FIELD_CALLBACK( "FDArray",    parse_fd_array )
    244     T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix )
    245 
    246     { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 }
     243    T1_FIELD_CALLBACK( "FDArray",    parse_fd_array, 0 )
     244    T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, 0 )
     245
     246    { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }
    247247  };
    248248
  • trunk/poppler/freetype2/src/cid/cidtoken.h

    r150 r165  
    55/*    CID token definitions (specification only).                          */
    66/*                                                                         */
    7 /*  Copyright 1996-2001, 2002, 2003 by                                     */
     7/*  Copyright 1996-2001, 2002, 2003, 2006 by                               */
    88/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    99/*                                                                         */
     
    2222#define T1CODE        T1_FIELD_LOCATION_CID_INFO
    2323
    24   T1_FIELD_KEY   ( "CIDFontName", cid_font_name )
    25   T1_FIELD_NUM   ( "CIDFontVersion", cid_version )
    26   T1_FIELD_NUM   ( "CIDFontType", cid_font_type )
    27   T1_FIELD_STRING( "Registry", registry )
    28   T1_FIELD_STRING( "Ordering", ordering )
    29   T1_FIELD_NUM   ( "Supplement", supplement )
    30   T1_FIELD_NUM   ( "UIDBase", uid_base )
    31   T1_FIELD_NUM   ( "CIDMapOffset", cidmap_offset )
    32   T1_FIELD_NUM   ( "FDBytes", fd_bytes )
    33   T1_FIELD_NUM   ( "GDBytes", gd_bytes )
    34   T1_FIELD_NUM   ( "CIDCount", cid_count )
     24  T1_FIELD_KEY   ( "CIDFontName",    cid_font_name, 0 )
     25  T1_FIELD_NUM   ( "CIDFontVersion", cid_version,   0 )
     26  T1_FIELD_NUM   ( "CIDFontType",    cid_font_type, 0 )
     27  T1_FIELD_STRING( "Registry",       registry,      0 )
     28  T1_FIELD_STRING( "Ordering",       ordering,      0 )
     29  T1_FIELD_NUM   ( "Supplement",     supplement,    0 )
     30  T1_FIELD_NUM   ( "UIDBase",        uid_base,      0 )
     31  T1_FIELD_NUM   ( "CIDMapOffset",   cidmap_offset, 0 )
     32  T1_FIELD_NUM   ( "FDBytes",        fd_bytes,      0 )
     33  T1_FIELD_NUM   ( "GDBytes",        gd_bytes,      0 )
     34  T1_FIELD_NUM   ( "CIDCount",       cid_count,     0 )
    3535
    3636
     
    4040#define T1CODE        T1_FIELD_LOCATION_FONT_INFO
    4141
    42   T1_FIELD_STRING( "version", version )
    43   T1_FIELD_STRING( "Notice", notice )
    44   T1_FIELD_STRING( "FullName", full_name )
    45   T1_FIELD_STRING( "FamilyName", family_name )
    46   T1_FIELD_STRING( "Weight", weight )
    47   T1_FIELD_NUM   ( "ItalicAngle", italic_angle )
    48   T1_FIELD_BOOL  ( "isFixedPitch", is_fixed_pitch )
    49   T1_FIELD_NUM   ( "UnderlinePosition", underline_position )
    50   T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness )
     42  T1_FIELD_STRING( "version",            version,             0 )
     43  T1_FIELD_STRING( "Notice",             notice,              0 )
     44  T1_FIELD_STRING( "FullName",           full_name,           0 )
     45  T1_FIELD_STRING( "FamilyName",         family_name,         0 )
     46  T1_FIELD_STRING( "Weight",             weight,              0 )
     47  T1_FIELD_NUM   ( "ItalicAngle",        italic_angle,        0 )
     48  T1_FIELD_BOOL  ( "isFixedPitch",       is_fixed_pitch,      0 )
     49  T1_FIELD_NUM   ( "UnderlinePosition",  underline_position,  0 )
     50  T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness, 0 )
    5151
    5252
     
    5656#define T1CODE        T1_FIELD_LOCATION_FONT_DICT
    5757
    58   T1_FIELD_NUM  ( "PaintType", paint_type )
    59   T1_FIELD_NUM  ( "FontType", font_type )
    60   T1_FIELD_NUM  ( "SubrMapOffset", subrmap_offset )
    61   T1_FIELD_NUM  ( "SDBytes", sd_bytes )
    62   T1_FIELD_NUM  ( "SubrCount", num_subrs )
    63   T1_FIELD_NUM  ( "lenBuildCharArray", len_buildchar )
    64   T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold )
    65   T1_FIELD_FIXED( "ExpansionFactor", expansion_factor )
    66   T1_FIELD_FIXED( "StrokeWidth", stroke_width )
     58  T1_FIELD_NUM  ( "PaintType",          paint_type,          0 )
     59  T1_FIELD_NUM  ( "FontType",           font_type,           0 )
     60  T1_FIELD_NUM  ( "SubrMapOffset",      subrmap_offset,      0 )
     61  T1_FIELD_NUM  ( "SDBytes",            sd_bytes,            0 )
     62  T1_FIELD_NUM  ( "SubrCount",          num_subrs,           0 )
     63  T1_FIELD_NUM  ( "lenBuildCharArray",  len_buildchar,       0 )
     64  T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold, 0 )
     65  T1_FIELD_FIXED( "ExpansionFactor",    expansion_factor,    0 )
     66  T1_FIELD_FIXED( "StrokeWidth",        stroke_width,        0 )
    6767
    6868
     
    7272#define T1CODE        T1_FIELD_LOCATION_PRIVATE
    7373
    74   T1_FIELD_NUM       ( "UniqueID", unique_id )
    75   T1_FIELD_NUM       ( "lenIV", lenIV )
    76   T1_FIELD_NUM       ( "LanguageGroup", language_group )
    77   T1_FIELD_NUM       ( "password", password )
     74  T1_FIELD_NUM       ( "UniqueID",         unique_id,      0 )
     75  T1_FIELD_NUM       ( "lenIV",            lenIV,          0 )
     76  T1_FIELD_NUM       ( "LanguageGroup",    language_group, 0 )
     77  T1_FIELD_NUM       ( "password",         password,       0 )
    7878
    79   T1_FIELD_FIXED_1000( "BlueScale", blue_scale )
    80   T1_FIELD_NUM       ( "BlueShift", blue_shift )
    81   T1_FIELD_NUM       ( "BlueFuzz",  blue_fuzz )
     79  T1_FIELD_FIXED_1000( "BlueScale",        blue_scale,     0 )
     80  T1_FIELD_NUM       ( "BlueShift",        blue_shift,     0 )
     81  T1_FIELD_NUM       ( "BlueFuzz",         blue_fuzz,      0 )
    8282
    83   T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 )
    84   T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 )
    85   T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 )
    86   T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 )
     83  T1_FIELD_NUM_TABLE ( "BlueValues",       blue_values,        14, 0 )
     84  T1_FIELD_NUM_TABLE ( "OtherBlues",       other_blues,        10, 0 )
     85  T1_FIELD_NUM_TABLE ( "FamilyBlues",      family_blues,       14, 0 )
     86  T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, 0 )
    8787
    88   T1_FIELD_NUM_TABLE2( "StdHW", standard_width,  1 )
    89   T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 )
    90   T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 )
     88  T1_FIELD_NUM_TABLE2( "StdHW",            standard_width,      1, 0 )
     89  T1_FIELD_NUM_TABLE2( "StdVW",            standard_height,     1, 0 )
     90  T1_FIELD_NUM_TABLE2( "MinFeature",       min_feature,         2, 0 )
    9191
    92   T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 )
    93   T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 )
     92  T1_FIELD_NUM_TABLE ( "StemSnapH",        snap_widths,        12, 0 )
     93  T1_FIELD_NUM_TABLE ( "StemSnapV",        snap_heights,       12, 0 )
    9494
    9595#undef  FT_STRUCTURE
     
    9898#define T1CODE        T1_FIELD_LOCATION_BBOX
    9999
    100   T1_FIELD_BBOX( "FontBBox", xMin )
     100  T1_FIELD_BBOX( "FontBBox", xMin, 0 )
    101101
    102102
  • trunk/poppler/freetype2/src/gxvalid/gxvmod.c

    r150 r165  
    55/*    FreeType's TrueTypeGX/AAT validation module implementation (body).   */
    66/*                                                                         */
    7 /*  Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
     7/*  Copyright 2004, 2005, 2006                                             */
     8/*  by suzuki toshiya, Masatake YAMATO, Red Hat K.K.,                      */
    89/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    910/*                                                                         */
     
    4849
    4950  static FT_Error
    50   gxv_load_table( FT_Face    face,
    51                   FT_Tag     tag,
    52                   FT_Byte**  table,
    53                   FT_ULong*  table_len )
     51  gxv_load_table( FT_Face             face,
     52                  FT_Tag              tag,
     53                  FT_Byte* volatile*  table,
     54                  FT_ULong*           table_len )
    5455  {
    5556    FT_Error   error;
     
    7374
    7475
    75 #define GXV_TABLE_DECL( _sfnt )           \
    76           FT_Byte   *_sfnt        = NULL; \
    77           FT_ULong  len_ ## _sfnt = 0
     76#define GXV_TABLE_DECL( _sfnt )                     \
     77          FT_Byte* volatile  _sfnt          = NULL; \
     78          FT_ULong            len_ ## _sfnt = 0
    7879
    7980#define GXV_TABLE_LOAD( _sfnt )                                     \
     
    9293            ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \
    9394                               FT_VALIDATE_DEFAULT );                \
    94             if ( ft_validator_run( &valid ) == 0 )                   \
     95            if ( ft_setjmp( valid.jump_buffer ) == 0 )               \
    9596              gxv_ ## _sfnt ## _validate( _sfnt, face, &valid );     \
    9697            error = valid.error;                                     \
     
    110111                FT_UInt   table_count )
    111112  {
    112     FT_Memory        memory = FT_FACE_MEMORY( face );
    113 
    114     FT_Error         error = GXV_Err_Ok;
    115     FT_ValidatorRec valid;
     113    FT_Memory volatile        memory = FT_FACE_MEMORY( face );
     114
     115    FT_Error                  error = GXV_Err_Ok;
     116    FT_ValidatorRec volatile valid;
    116117
    117118    FT_UInt  i;
     
    192193                         FT_Bytes*  ckern_table )
    193194  {
    194     FT_Memory        memory = FT_FACE_MEMORY( face );
    195 
    196     FT_Byte*         ckern     = NULL;
    197     FT_ULong         len_ckern = 0;
    198 
    199     FT_Error         error = GXV_Err_Ok;
    200     FT_ValidatorRec  valid;
     195    FT_Memory volatile        memory = FT_FACE_MEMORY( face );
     196
     197    FT_Byte* volatile         ckern     = NULL;
     198    FT_ULong                  len_ckern = 0;
     199
     200    /* without volatile on `error' GCC 4.1.1. emits:                         */
     201    /*  warning: variable 'error' might be clobbered by 'longjmp' or 'vfork' */
     202    /* this warning seems spurious but ---                                   */
     203    FT_Error volatile         error = GXV_Err_Ok;
     204    FT_ValidatorRec volatile  valid;
    201205
    202206
     
    211215      ft_validator_init( &valid, ckern, ckern + len_ckern,
    212216                         FT_VALIDATE_DEFAULT );
    213       if ( ft_validator_run( &valid ) == 0 )
     217      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    214218        gxv_kern_validate_classic( ckern, face,
    215219                                   ckern_flags & FT_VALIDATE_CKERN, &valid );
  • trunk/poppler/freetype2/src/gzip/ftgzip.c

    r150 r165  
    555555
    556556
     557  static FT_ULong
     558  ft_gzip_get_uncompressed_size( FT_Stream  stream )
     559  {
     560    FT_Error  error;
     561    FT_ULong  old_pos;
     562    FT_ULong  result = 0;
     563
     564
     565    old_pos = stream->pos;
     566    if ( !FT_Stream_Seek( stream, stream->size - 4 ) )
     567    {
     568      result = (FT_ULong)FT_Stream_ReadLong( stream, &error );
     569      if ( error )
     570        result = 0;
     571
     572      FT_Stream_Seek( stream, old_pos );
     573    }
     574
     575    return result;
     576  }
     577
     578
    557579  FT_EXPORT_DEF( FT_Error )
    558580  FT_Stream_OpenGzip( FT_Stream  stream,
     
    587609    }
    588610
     611    /*
     612     *  We use the following trick to try to dramatically improve the
     613     *  performance while dealing with small files.  If the original stream
     614     *  size is less than a certain threshold, we try to load the whole font
     615     *  file into memory.  This saves us from using the 32KB buffer needed
     616     *  to inflate the file, plus the two 4KB intermediate input/output
     617     *  buffers used in the `FT_GZipFile' structure.
     618     */
     619    {
     620      FT_ULong  zip_size = ft_gzip_get_uncompressed_size( source );
     621
     622
     623      if ( zip_size != 0 && zip_size < 40 * 1024 )
     624      {
     625        FT_Byte*  zip_buff;
     626
     627
     628        if ( !FT_ALLOC( zip_buff, zip_size ) )
     629        {
     630          FT_ULong  count;
     631
     632
     633          count = ft_gzip_file_io( zip, 0, zip_buff, zip_size );
     634          if ( count == zip_size )
     635          {
     636            ft_gzip_file_done( zip );
     637            FT_FREE( zip );
     638
     639            stream->descriptor.pointer = NULL;
     640
     641            stream->size  = zip_size;
     642            stream->pos   = 0;
     643            stream->base  = zip_buff;
     644            stream->read  = NULL;
     645            stream->close = ft_gzip_stream_close;
     646
     647            goto Exit;
     648          }
     649
     650          ft_gzip_file_io( zip, 0, NULL, 0 );
     651          FT_FREE( zip_buff );
     652        }
     653        error = 0;
     654      }
     655    }
     656
    589657    stream->size  = 0x7FFFFFFFL;  /* don't know the real size! */
    590658    stream->pos   = 0;
  • trunk/poppler/freetype2/src/gzip/inftrees.c

    r150 r165  
    132132
    133133
     134  /* Make comiler happy */
     135  r.base = 0;
     136
    134137  /* Generate counts for each bit length */
    135138  p = c;
  • trunk/poppler/freetype2/src/otvalid/otvmod.c

    r150 r165  
    55/*    FreeType's OpenType validation module implementation (body).         */
    66/*                                                                         */
    7 /*  Copyright 2004, 2005 by                                                */
     7/*  Copyright 2004, 2005, 2006 by                                          */
    88/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    99/*                                                                         */
     
    4040
    4141  static FT_Error
    42   otv_load_table( FT_Face    face,
    43                   FT_Tag     tag,
    44                   FT_Byte*  *table,
    45                   FT_ULong  *table_len )
     42  otv_load_table( FT_Face             face,
     43                  FT_Tag              tag,
     44                  FT_Byte* volatile*  table,
     45                  FT_ULong*           table_len )
    4646  {
    4747    FT_Error   error;
     
    6666
    6767  static FT_Error
    68   otv_validate( FT_Face    face,
    69                 FT_UInt    ot_flags,
    70                 FT_Bytes  *ot_base,
    71                 FT_Bytes  *ot_gdef,
    72                 FT_Bytes  *ot_gpos,
    73                 FT_Bytes  *ot_gsub,
    74                 FT_Bytes  *ot_jstf )
    75   {
    76     FT_Error         error = OTV_Err_Ok;
    77     FT_Byte          *base, *gdef, *gpos, *gsub, *jstf;
    78     FT_ULong         len_base, len_gdef, len_gpos, len_gsub, len_jstf;
    79     FT_ValidatorRec  valid;
     68  otv_validate( FT_Face volatile   face,
     69                FT_UInt            ot_flags,
     70                FT_Bytes          *ot_base,
     71                FT_Bytes          *ot_gdef,
     72                FT_Bytes          *ot_gpos,
     73                FT_Bytes          *ot_gsub,
     74                FT_Bytes          *ot_jstf )
     75  {
     76    FT_Error                  error = OTV_Err_Ok;
     77    FT_Byte* volatile         base;
     78    FT_Byte* volatile         gdef;
     79    FT_Byte* volatile         gpos;
     80    FT_Byte* volatile         gsub;
     81    FT_Byte* volatile         jstf;
     82    FT_ULong                  len_base, len_gdef, len_gpos, len_gsub, len_jstf;
     83    FT_ValidatorRec volatile  valid;
    8084
    8185
     
    125129    {
    126130      ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT );
    127       if ( ft_validator_run( &valid ) == 0 )
     131      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    128132        otv_BASE_validate( base, &valid );
    129133      error = valid.error;
     
    135139    {
    136140      ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT );
    137       if ( ft_validator_run( &valid ) == 0 )
     141      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    138142        otv_GPOS_validate( gpos, face->num_glyphs, &valid );
    139143      error = valid.error;
     
    145149    {
    146150      ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT );
    147       if ( ft_validator_run( &valid ) == 0 )
     151      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    148152        otv_GSUB_validate( gsub, face->num_glyphs, &valid );
    149153      error = valid.error;
     
    155159    {
    156160      ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT );
    157       if ( ft_validator_run( &valid ) == 0 )
     161      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    158162        otv_GDEF_validate( gdef, gsub, gpos, &valid );
    159163      error = valid.error;
     
    165169    {
    166170      ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT );
    167       if ( ft_validator_run( &valid ) == 0 )
     171      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    168172        otv_JSTF_validate( jstf, gsub, gpos, face->num_glyphs, &valid );
    169173      error = valid.error;
  • trunk/poppler/freetype2/src/pcf/pcfdrivr.c

    r150 r165  
    204204    /* free properties */
    205205    {
    206       PCF_Property  prop = face->properties;
     206      PCF_Property  prop;
    207207      FT_Int        i;
    208208
    209209
    210       for ( i = 0; i < face->nprops; i++ )
    211       {
    212         prop = &face->properties[i];
    213 
    214         FT_FREE( prop->name );
    215         if ( prop->isString )
    216           FT_FREE( prop->value.atom );
    217       }
    218 
     210      if ( face->properties )
     211      {
     212        for ( i = 0; i < face->nprops; i++ )
     213        {
     214          prop = &face->properties[i];
     215
     216          if ( prop ) {
     217            FT_FREE( prop->name );
     218            if ( prop->isString )
     219              FT_FREE( prop->value.atom );
     220          }
     221        }
     222      }
    219223      FT_FREE( face->properties );
    220224    }
     
    258262      FT_Error  error2;
    259263
     264
     265      PCF_Face_Done( pcfface );
    260266
    261267      /* this didn't work, try gzip support! */
     
    358364  Fail:
    359365    FT_TRACE2(( "[not a valid PCF file]\n" ));
     366    PCF_Face_Done( pcfface );
    360367    error = PCF_Err_Unknown_File_Format;  /* error */
    361368    goto Exit;
     
    436443    FT_TRACE4(( "load_glyph %d ---", glyph_index ));
    437444
    438     if ( !face )
     445    if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs )
    439446    {
    440447      error = PCF_Err_Invalid_Argument;
  • trunk/poppler/freetype2/src/pcf/pcfread.c

    r150 r165  
    103103
    104104    if ( toc->version != PCF_FILE_VERSION                 ||
    105          toc->count   >  FT_ARRAY_MAX( face->toc.tables ) )
     105         toc->count   >  FT_ARRAY_MAX( face->toc.tables ) ||
     106         toc->count   == 0                                )
    106107      return PCF_Err_Invalid_File_Format;
    107108
     
    117118    }
    118119
     120    /* Sort tables and check for overlaps.  Because they are almost      */
     121    /* always ordered already, an in-place bubble sort with simultaneous */
     122    /* boundary checking seems appropriate.                              */
     123    tables = face->toc.tables;
     124
     125    for ( n = 0; n < toc->count - 1; n++ )
     126    {
     127      FT_UInt  i, have_change;
     128
     129
     130      have_change = 0;
     131
     132      for ( i = 0; i < toc->count - 1 - n; i++ )
     133      {
     134        PCF_TableRec  tmp;
     135
     136
     137        if ( tables[i].offset > tables[i + 1].offset )
     138        {
     139          tmp           = tables[i];
     140          tables[i]     = tables[i + 1];
     141          tables[i + 1] = tmp;
     142
     143          have_change = 1;
     144        }
     145
     146        if ( ( tables[i].size   > tables[i + 1].offset )                  ||
     147             ( tables[i].offset > tables[i + 1].offset - tables[i].size ) )
     148          return PCF_Err_Invalid_Offset;
     149      }
     150
     151      if ( !have_change )
     152        break;
     153    }
     154
    119155#if defined( FT_DEBUG_LEVEL_TRACE )
    120156
     
    131167      for ( i = 0; i < toc->count; i++ )
    132168      {
    133         for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ )
     169        for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] );
     170              j++ )
    134171          if ( tables[i].type == (FT_UInt)( 1 << j ) )
    135172            name = tableNames[j];
     
    154191
    155192
     193#define PCF_METRIC_SIZE  12
     194
    156195  static
    157196  const FT_Frame_Field  pcf_metric_header[] =
     
    160199#define FT_STRUCTURE  PCF_MetricRec
    161200
    162     FT_FRAME_START( 12 ),
     201    FT_FRAME_START( PCF_METRIC_SIZE ),
    163202      FT_FRAME_SHORT_LE( leftSideBearing ),
    164203      FT_FRAME_SHORT_LE( rightSideBearing ),
     
    177216#define FT_STRUCTURE  PCF_MetricRec
    178217
    179     FT_FRAME_START( 12 ),
     218    FT_FRAME_START( PCF_METRIC_SIZE ),
    180219      FT_FRAME_SHORT( leftSideBearing ),
    181220      FT_FRAME_SHORT( rightSideBearing ),
     
    188227
    189228
     229#define PCF_COMPRESSED_METRIC_SIZE  5
     230
    190231  static
    191232  const FT_Frame_Field  pcf_compressed_metric_header[] =
     
    194235#define FT_STRUCTURE  PCF_Compressed_MetricRec
    195236
    196     FT_FRAME_START( 5 ),
     237    FT_FRAME_START( PCF_COMPRESSED_METRIC_SIZE ),
    197238      FT_FRAME_BYTE( leftSideBearing ),
    198239      FT_FRAME_BYTE( rightSideBearing ),
     
    222263               : pcf_metric_header;
    223264
    224       /* the following sets 'error' but doesn't return in case of failure */
     265      /* the following sets `error' but doesn't return in case of failure */
    225266      (void)FT_STREAM_READ_FIELDS( fields, metric );
    226267    }
     
    262303      if ( tables[i].type == type )
    263304      {
    264         if ( stream->pos > tables[i].offset ) {
     305        if ( stream->pos > tables[i].offset )
     306        {
    265307          error = PCF_Err_Invalid_Stream_Skip;
    266308          goto Fail;
    267309        }
    268310
    269         if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) {
     311        if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) )
     312        {
    270313          error = PCF_Err_Invalid_Stream_Skip;
    271314          goto Fail;
    272315        }
    273316
    274         *asize   = tables[i].size;  /* unused - to be removed */
     317        *asize   = tables[i].size;
    275318        *aformat = tables[i].format;
    276319
     
    299342
    300343
     344#define PCF_PROPERTY_SIZE  9
     345
    301346  static
    302347  const FT_Frame_Field  pcf_property_header[] =
     
    305350#define FT_STRUCTURE  PCF_ParsePropertyRec
    306351
    307     FT_FRAME_START( 9 ),
     352    FT_FRAME_START( PCF_PROPERTY_SIZE ),
    308353      FT_FRAME_LONG_LE( name ),
    309354      FT_FRAME_BYTE   ( isString ),
     
    319364#define FT_STRUCTURE  PCF_ParsePropertyRec
    320365
    321     FT_FRAME_START( 9 ),
     366    FT_FRAME_START( PCF_PROPERTY_SIZE ),
    322367      FT_FRAME_LONG( name ),
    323368      FT_FRAME_BYTE( isString ),
     
    354399  {
    355400    PCF_ParseProperty  props      = 0;
    356     PCF_Property       properties = 0;
    357     FT_Int             nprops, i;
     401    PCF_Property       properties;
     402    FT_UInt            nprops, i;
    358403    FT_ULong           format, size;
    359404    FT_Error           error;
     
    391436    FT_TRACE4(( "  nprop = %d\n", nprops ));
    392437
     438    /* rough estimate */
     439    if ( nprops > size / PCF_PROPERTY_SIZE )
     440    {
     441      error = PCF_Err_Invalid_Table;
     442      goto Bail;
     443    }
     444
     445    face->nprops = nprops;
     446
    393447    if ( FT_NEW_ARRAY( props, nprops ) )
    394448      goto Bail;
     
    428482    FT_TRACE4(( "  string_size = %ld\n", string_size ));
    429483
     484    /* rough estimate */
     485    if ( string_size > size - nprops * PCF_PROPERTY_SIZE )
     486    {
     487      error = PCF_Err_Invalid_Table;
     488      goto Bail;
     489    }
     490
    430491    if ( FT_NEW_ARRAY( strings, string_size ) )
    431492      goto Bail;
     
    438499      goto Bail;
    439500
     501    face->properties = properties;
     502
    440503    for ( i = 0; i < nprops; i++ )
    441504    {
    442       /* XXX: make atom */
     505      FT_Long  name_offset = props[i].name;
     506
     507
     508      if ( ( name_offset < 0 )                     ||
     509           ( (FT_ULong)name_offset > string_size ) )
     510      {
     511        error = PCF_Err_Invalid_Offset;
     512        goto Bail;
     513      }
     514
    443515      if ( FT_NEW_ARRAY( properties[i].name,
    444                          ft_strlen( strings + props[i].name ) + 1 ) )
     516                         ft_strlen( strings + name_offset ) + 1 ) )
    445517        goto Bail;
    446       ft_strcpy( properties[i].name, strings + props[i].name );
     518      ft_strcpy( properties[i].name, strings + name_offset );
    447519
    448520      FT_TRACE4(( "  %s:", properties[i].name ));
     
    452524      if ( props[i].isString )
    453525      {
     526        FT_Long  value_offset = props[i].value;
     527
     528
     529        if ( ( value_offset < 0 )                     ||
     530             ( (FT_ULong)value_offset > string_size ) )
     531        {
     532          error = PCF_Err_Invalid_Offset;
     533          goto Bail;
     534        }
     535
    454536        if ( FT_NEW_ARRAY( properties[i].value.atom,
    455                            ft_strlen( strings + props[i].value ) + 1 ) )
     537                           ft_strlen( strings + value_offset ) + 1 ) )
    456538          goto Bail;
    457539        ft_strcpy( properties[i].value.atom, strings + props[i].value );
     
    467549    }
    468550
    469     face->properties = properties;
    470     face->nprops = nprops;
    471 
    472     FT_FREE( props );
    473     FT_FREE( strings );
    474 
    475     return PCF_Err_Ok;
    476 
     551    error = PCF_Err_Ok;
     552   
    477553  Bail:
    478554    FT_FREE( props );
     
    489565    FT_Error    error    = PCF_Err_Ok;
    490566    FT_Memory   memory   = FT_FACE(face)->memory;
    491     FT_ULong    format   = 0;
    492     FT_ULong    size     = 0;
     567    FT_ULong    format, size;
    493568    PCF_Metric  metrics  = 0;
    494     int         i;
    495     int         nmetrics = -1;
     569    FT_ULong    nmetrics, i;
    496570
    497571
     
    505579      return error;
    506580
    507     error = FT_READ_ULONG_LE( format );
     581    if ( FT_READ_ULONG_LE( format ) )
     582      goto Bail;
    508583
    509584    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )     &&
     
    525600        (void)FT_READ_USHORT_LE( nmetrics );
    526601    }
    527     if ( error || nmetrics == -1 )
     602    if ( error )
    528603      return PCF_Err_Invalid_File_Format;
    529604
    530605    face->nmetrics = nmetrics;
     606
     607    FT_TRACE4(( "pcf_get_metrics:\n" ));
     608
     609    FT_TRACE4(( "  number of metrics: %d\n", nmetrics ));
     610
     611    /* rough estimate */
     612    if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
     613    {
     614      if ( nmetrics > size / PCF_METRIC_SIZE )
     615        return PCF_Err_Invalid_Table;
     616    }
     617    else
     618    {
     619      if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )
     620        return PCF_Err_Invalid_Table;
     621    }
    531622
    532623    if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
    533624      return PCF_Err_Out_Of_Memory;
    534625
    535     FT_TRACE4(( "pcf_get_metrics:\n" ));
    536 
    537626    metrics = face->metrics;
    538627    for ( i = 0; i < nmetrics; i++ )
     
    542631      metrics[i].bits = 0;
    543632
    544       FT_TRACE4(( "  idx %d: width=%d, "
     633      FT_TRACE5(( "  idx %d: width=%d, "
    545634                  "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
    546635                  i,
     
    558647    if ( error )
    559648      FT_FREE( face->metrics );
     649
     650  Bail:
    560651    return error;
    561652  }
     
    598689      return PCF_Err_Invalid_File_Format;
    599690
     691    FT_TRACE4(( "pcf_get_bitmaps:\n" ));
     692
     693    FT_TRACE4(( "  number of bitmaps: %d\n", nbitmaps ));
     694
    600695    if ( nbitmaps != face->nmetrics )
    601696      return PCF_Err_Invalid_File_Format;
     
    603698    if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
    604699      return error;
    605 
    606     FT_TRACE4(( "pcf_get_bitmaps:\n" ));
    607700
    608701    for ( i = 0; i < nbitmaps; i++ )
     
    613706        (void)FT_READ_LONG_LE( offsets[i] );
    614707
    615       FT_TRACE4(( "  bitmap %d: offset %ld (0x%lX)\n",
     708      FT_TRACE5(( "  bitmap %d: offset %ld (0x%lX)\n",
    616709                  i, offsets[i], offsets[i] ));
    617710    }
     
    641734
    642735    for ( i = 0; i < nbitmaps; i++ )
    643       face->metrics[i].bits = stream->pos + offsets[i];
     736    {
     737      /* rough estimate */
     738      if ( ( offsets[i] < 0 )              ||
     739           ( (FT_ULong)offsets[i] > size ) )
     740      {
     741        FT_ERROR(( "pcf_get_bitmaps:"));
     742        FT_ERROR(( " invalid offset to bitmap data of glyph %d\n", i ));
     743      }
     744      else
     745        face->metrics[i].bits = stream->pos + offsets[i];
     746    }
    644747
    645748    face->bitmapsFormat = format;
    646749
    647     FT_FREE ( offsets );
    648     return error;
    649 
    650750  Bail:
    651     FT_FREE ( offsets );
     751    FT_FREE( offsets );
    652752    return error;
    653753  }
     
    735835        tmpEncoding[j].glyph = (FT_Short)encodingOffset;
    736836
    737         FT_TRACE4(( "  code %d (0x%04X): idx %d\n",
     837        FT_TRACE5(( "  code %d (0x%04X): idx %d\n",
    738838                    tmpEncoding[j].enc, tmpEncoding[j].enc,
    739839                    tmpEncoding[j].glyph ));
     
    829929      goto Bail;
    830930
    831     error = FT_READ_ULONG_LE( format );
     931    if ( FT_READ_ULONG_LE( format ) )
     932      goto Bail;
    832933
    833934    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )    &&
     
    877978      accel->ink_maxbounds = accel->maxbounds;
    878979    }
    879     return error;
    880980
    881981  Bail:
     
    10831183        root->family_name = NULL;
    10841184
    1085       /* Note: We shift all glyph indices by +1 since we must
     1185      /*
     1186       * Note: We shift all glyph indices by +1 since we must
    10861187       * respect the convention that glyph 0 always corresponds
    1087        * to the "missing glyph".
     1188       * to the `missing glyph'.
    10881189       *
    1089        * This implies bumping the number of "available" glyphs by 1.
     1190       * This implies bumping the number of `available' glyphs by 1.
    10901191       */
    10911192      root->num_glyphs = face->nmetrics + 1;
     
    11721273    if ( error )
    11731274    {
    1174       /* this is done to respect the behaviour of the original */
     1275      /* This is done to respect the behaviour of the original */
    11751276      /* PCF font driver.                                      */
    11761277      error = PCF_Err_Invalid_File_Format;
  • trunk/poppler/freetype2/src/pcf/pcfutil.c

    r150 r165  
    33Copyright 1990, 1994, 1998  The Open Group
    44
    5 All Rights Reserved.
     5Permission to use, copy, modify, distribute, and sell this software and its
     6documentation for any purpose is hereby granted without fee, provided that
     7the above copyright notice appear in all copies and that both that
     8copyright notice and this permission notice appear in supporting
     9documentation.
    610
    711The above copyright notice and this permission notice shall be included in
  • trunk/poppler/freetype2/src/pfr/pfrobjs.c

    r150 r165  
    129129
    130130      pfrface->face_index = face_index;
    131       pfrface->num_glyphs = phy_font->num_chars;
     131      pfrface->num_glyphs = phy_font->num_chars + 1;
    132132      pfrface->face_flags = FT_FACE_FLAG_SCALABLE;
    133133
     
    297297      gindex--;
    298298
    299     /* check that the glyph index is correct */
    300     FT_ASSERT( gindex < face->phy_font.num_chars );
     299    if ( !face || gindex >= face->phy_font.num_chars )
     300    {
     301      error = PFR_Err_Invalid_Argument;
     302      goto Exit;
     303    }
    301304
    302305    /* try to load an embedded bitmap */
     
    477480
    478481      {
    479         FT_UInt    count    = item->pair_count;
    480         FT_UInt    size     = item->pair_size;
    481         FT_UInt    power    = (FT_UInt)ft_highpow2( (FT_UInt32)count );
    482         FT_UInt    probe    = power * size;
    483         FT_UInt    extra    = count - power;
    484         FT_Byte*   base     = stream->cursor;
    485         FT_Bool    twobytes = FT_BOOL( item->flags & 1 );
     482        FT_UInt    count       = item->pair_count;
     483        FT_UInt    size        = item->pair_size;
     484        FT_UInt    power       = (FT_UInt)ft_highpow2( (FT_UInt32)count );
     485        FT_UInt    probe       = power * size;
     486        FT_UInt    extra       = count - power;
     487        FT_Byte*   base        = stream->cursor;
     488        FT_Bool    twobytes    = FT_BOOL( item->flags & 1 );
     489        FT_Bool    twobyte_adj = FT_BOOL( item->flags & 2 );
    486490        FT_Byte*   p;
    487491        FT_UInt32  cpair;
     
    501505
    502506          if ( cpair < pair )
     507          {
     508            if ( twobyte_adj )
     509              p += 2;
     510            else
     511              p++;
    503512            base = p;
     513          }
    504514        }
    505515
     
    534544
    535545        Found:
    536           if ( item->flags & 2 )
     546          if ( twobyte_adj )
    537547            value = FT_PEEK_SHORT( p );
    538548          else
  • trunk/poppler/freetype2/src/psaux/psconv.c

    r150 r165  
    332332  {
    333333    FT_Byte*  p;
    334     FT_UInt   r = 0;
     334    FT_UInt   r   = 0;
     335    FT_UInt   w   = 0;
     336    FT_UInt   pad = 0x01;
    335337
    336338
    337339    n *= 2;
    338     for ( p = *cursor; r < n && p < limit; p++ )
     340
     341#if 1
     342
     343    p  = *cursor;
     344    if ( n > (FT_UInt)( limit - p ) )
     345      n = (FT_UInt)( limit - p );
     346
     347    /* we try to process two nibbles at a time to be as fast as possible */
     348    for ( ; r < n; r++ )
     349    {
     350      FT_UInt  c = p[r];
     351
     352
     353      if ( IS_PS_SPACE( c ) )
     354        continue;
     355
     356      if ( c OP 0x80 )
     357        break;
     358
     359      c = ft_char_table[c & 0x7F];
     360      if ( (unsigned)c >= 16 )
     361        break;
     362
     363      pad = ( pad << 4 ) | c;
     364      if ( pad & 0x100 )
     365      {
     366        buffer[w++] = (FT_Byte)pad;
     367        pad         = 0x01;
     368      }
     369    }
     370
     371    if ( pad != 0x01 )
     372      buffer[w++] = (FT_Byte)( pad << 4 );
     373
     374    *cursor = p + r;
     375
     376    return w;
     377
     378#else /* 0 */
     379
     380    for ( r = 0; r < n; r++ )
    339381    {
    340382      FT_Char  c;
     
    349391      c = ft_char_table[*p & 0x7f];
    350392
    351       if ( c < 0 || c >= 16 )
    352         break;
    353 
    354       if ( r % 2 )
     393      if ( (unsigned)c >= 16 )
     394        break;
     395
     396      if ( r & 1 )
    355397      {
    356398        *buffer = (FT_Byte)(*buffer + c);
     
    366408
    367409    return ( r + 1 ) / 2;
     410
     411#endif /* 0 */
     412
    368413  }
    369414
     
    376421                       FT_UShort*  seed )
    377422  {
    378     FT_Byte*   p;
    379     FT_UInt    r;
    380     FT_UShort  s = *seed;
    381 
     423    FT_Byte*  p;
     424    FT_UInt   r;
     425    FT_UInt   s = *seed;
     426
     427
     428#if 1
     429
     430    p = *cursor;
     431    if ( n > (FT_UInt)(limit - p) )
     432      n = (FT_UInt)(limit - p);
     433
     434    for ( r = 0; r < n; r++ )
     435    {
     436      FT_UInt  val = p[r];
     437      FT_UInt  b   = ( val ^ ( s >> 8 ) );
     438
     439
     440      s         = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
     441      buffer[r] = (FT_Byte) b;
     442    }
     443
     444    *cursor = p + n;
     445    *seed   = (FT_UShort)s;
     446
     447#else /* 0 */
    382448
    383449    for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
     
    389455      *buffer++ = b;
    390456    }
    391 
    392457    *cursor = p;
    393458    *seed   = s;
    394459
     460#endif /* 0 */
     461
    395462    return r;
    396463  }
  • trunk/poppler/freetype2/src/psaux/psconv.h

    r150 r165  
    6464
    6565
    66 #define IS_PS_NEWLINE( ch ) \
    67   ( ( ch ) == '\r' ||       \
    68     ( ch ) == '\n' )
    69 
    70 #define IS_PS_SPACE( ch )  \
    71   ( ( ch ) == ' '       || \
    72     IS_PS_NEWLINE( ch ) || \
    73     ( ch ) == '\t'      || \
    74     ( ch ) == '\f'      || \
    75     ( ch ) == '\0' )
    76 
    77 #define IS_PS_SPECIAL( ch ) \
    78   ( ( ch ) == '/' ||        \
    79     ( ch ) == '(' ||        \
    80     ( ch ) == ')' ||        \
    81     ( ch ) == '<' ||        \
    82     ( ch ) == '>' ||        \
    83     ( ch ) == '[' ||        \
    84     ( ch ) == ']' ||        \
    85     ( ch ) == '{' ||        \
    86     ( ch ) == '}' ||        \
    87     ( ch ) == '%' )
    88 
    89 #define IS_PS_DELIM( ch )  \
    90   ( IS_PS_SPACE( ch )   || \
    91     IS_PS_SPECIAL( ch ) )
    92 
    93 #define IS_PS_DIGIT( ch )  ( ( ch ) >= '0' && ( ch ) <= '9' )
    94 
    95 #define IS_PS_XDIGIT( ch )                \
    96   ( IS_PS_DIGIT( ( ch ) )              || \
    97     ( ( ch ) >= 'A' && ( ch ) <= 'F' ) || \
    98     ( ( ch ) >= 'a' && ( ch ) <= 'f' ) )
    99 
    100 #define IS_PS_BASE85( ch ) ( ( ch ) >= '!' && ( ch ) <= 'u' )
    101 
    10266FT_END_HEADER
    10367
  • trunk/poppler/freetype2/src/psaux/psobjs.c

    r150 r165  
    2828
    2929  /*************************************************************************/
     30  /*                                                                       */
     31  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     32  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     33  /* messages during execution.                                            */
     34  /*                                                                       */
     35#undef  FT_COMPONENT
     36#define FT_COMPONENT  trace_psobjs
     37
     38
     39  /*************************************************************************/
    3040  /*************************************************************************/
    3141  /*****                                                               *****/
     
    119129
    120130    /* copy elements and shift offsets */
    121     if (old_base )
     131    if ( old_base )
    122132    {
    123133      FT_MEM_COPY( table->block, old_base, table->capacity );
     
    313323
    314324
    315   /* first character must be `(' */
    316 
    317   static void
     325#define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' )
     326
     327
     328  /* first character must be `(';                               */
     329  /* *acur is positioned at the character after the closing `)' */
     330
     331  static FT_Error
    318332  skip_literal_string( FT_Byte*  *acur,
    319333                       FT_Byte*   limit )
    320334  {
    321     FT_Byte*  cur   = *acur;
    322     FT_Int    embed = 0;
     335    FT_Byte*      cur   = *acur;
     336    FT_Int        embed = 0;
     337    FT_Error      error = PSaux_Err_Invalid_File_Format;
     338    unsigned int  i;
    323339
    324340
    325341    while ( cur < limit )
    326342    {
    327       if ( *cur == '\\' )
    328         cur++;
    329       else if ( *cur == '(' )
     343      FT_Byte  c = *cur;
     344
     345
     346      ++cur;
     347
     348      if ( c == '\\' )
     349      {
     350        /* Red Book 3rd ed., section `Literal Text Strings', p. 29:     */
     351        /* A backslash can introduce three different types              */
     352        /* of escape sequences:                                         */
     353        /*   - a special escaped char like \r, \n, etc.                 */
     354        /*   - a one-, two-, or three-digit octal number                */
     355        /*   - none of the above in which case the backslash is ignored */
     356
     357        if ( cur == limit )
     358          /* error (or to be ignored?) */
     359          break;
     360
     361        switch ( *cur )
     362        {
     363          /* skip `special' escape */
     364        case 'n':
     365        case 'r':
     366        case 't':
     367        case 'b':
     368        case 'f':
     369        case '\\':
     370        case '(':
     371        case ')':
     372          ++cur;
     373          break;
     374
     375        default:
     376          /* skip octal escape or ignore backslash */
     377          for ( i = 0; i < 3 && cur < limit; ++i )
     378          {
     379            if ( ! IS_OCTAL_DIGIT( *cur ) )
     380              break;
     381
     382            ++cur;
     383          }
     384        }
     385      }
     386      else if ( c == '(' )
    330387        embed++;
    331       else if ( *cur == ')' )
     388      else if ( c == ')' )
    332389      {
    333390        embed--;
    334391        if ( embed == 0 )
    335392        {
    336           cur++;
     393          error = PSaux_Err_Ok;
    337394          break;
    338395        }
    339396      }
    340       cur++;
    341397    }
    342398
    343399    *acur = cur;
     400
     401    return error;
    344402  }
    345403
     
    347405  /* first character must be `<' */
    348406
    349   static void
    350   skip_string( PS_Parser  parser )
    351   {
    352     FT_Byte*  cur   = parser->cursor;
    353     FT_Byte*  limit = parser->limit;
     407  static FT_Error
     408  skip_string( FT_Byte*  *acur,
     409               FT_Byte*   limit )
     410  {
     411    FT_Byte*  cur = *acur;
     412    FT_Error  err =  PSaux_Err_Ok;
    354413
    355414
     
    368427    {
    369428      FT_ERROR(( "skip_string: missing closing delimiter `>'\n" ));
    370       parser->error = PSaux_Err_Invalid_File_Format;
     429      err = PSaux_Err_Invalid_File_Format;
    371430    }
    372431    else
    373432      cur++;
    374433
    375     parser->cursor = cur;
     434    *acur = cur;
     435    return err;
     436  }
     437
     438
     439  /* first character must be the opening brace that */
     440  /* starts the procedure                           */
     441
     442  /* NB: [ and ] need not match:                    */
     443  /* `/foo {[} def' is a valid PostScript fragment, */
     444  /* even within a Type1 font                       */
     445
     446  static FT_Error
     447  skip_procedure( FT_Byte*  *acur,
     448                  FT_Byte*   limit )
     449  {
     450    FT_Byte*  cur;
     451    FT_Int    embed = 0;
     452    FT_Error  error = PSaux_Err_Ok;
     453
     454
     455    FT_ASSERT( **acur == '{' );
     456
     457    for ( cur = *acur; cur < limit && error == PSaux_Err_Ok; ++cur )
     458    {
     459      switch ( *cur )
     460      {
     461      case '{':
     462        ++embed;
     463        break;
     464
     465      case '}':
     466        --embed;
     467        if ( embed == 0 )
     468        {
     469          ++cur;
     470          goto end;
     471        }
     472        break;
     473
     474      case '(':
     475        error = skip_literal_string( &cur, limit );
     476        break;
     477
     478      case '<':
     479        error = skip_string( &cur, limit );
     480        break;
     481
     482      case '%':
     483        skip_comment( &cur, limit );
     484        break;
     485      }
     486    }
     487
     488  end:
     489    if ( embed != 0 )
     490      error = PSaux_Err_Invalid_File_Format;
     491
     492    *acur = cur;
     493
     494    return error;
    376495  }
    377496
     
    394513    FT_Byte*  cur   = parser->cursor;
    395514    FT_Byte*  limit = parser->limit;
     515    FT_Error  error = PSaux_Err_Ok;
    396516
    397517
     
    401521
    402522    /* self-delimiting, single-character tokens */
    403     if ( *cur == '[' || *cur == ']' ||
    404          *cur == '{' || *cur == '}' )
     523    if ( *cur == '[' || *cur == ']' )
    405524    {
    406525      cur++;
     
    408527    }
    409528
     529    /* skip balanced expressions (procedures and strings) */
     530
     531    if ( *cur == '{' )                              /* {...} */
     532    {
     533      error = skip_procedure( &cur, limit );
     534      goto Exit;
     535    }
     536
    410537    if ( *cur == '(' )                              /* (...) */
    411538    {
    412       skip_literal_string( &cur, limit );
     539      error = skip_literal_string( &cur, limit );
    413540      goto Exit;
    414541    }
     
    420547        cur++;
    421548        cur++;
    422         goto Exit;
    423549      }
    424       parser->cursor = cur;
    425       skip_string( parser );
    426       return;
     550      else
     551        error = skip_string( &cur, limit );
     552
     553      goto Exit;
    427554    }
    428555
     
    434561        FT_ERROR(( "ps_parser_skip_PS_token: "
    435562                   "unexpected closing delimiter `>'\n" ));
    436         parser->error = PSaux_Err_Invalid_File_Format;
     563        error = PSaux_Err_Invalid_File_Format;
    437564        goto Exit;
    438565      }
     
    447574    while ( cur < limit )
    448575    {
    449       if ( *cur == ')' )
    450       {
    451         FT_ERROR(( "ps_parser_skip_PS_token: "
    452                    "unexpected closing delimiter `)'\n" ));
    453         parser->error = PSaux_Err_Invalid_File_Format;
    454         goto Exit;
    455       }
    456       else if ( IS_PS_DELIM( *cur ) )
     576      /* *cur might be invalid (e.g., ')' or '}'), but this   */
     577      /* is handled by the test `cur == parser->cursor' below */
     578      if ( IS_PS_DELIM( *cur ) )
    457579        break;
    458580
     
    461583
    462584  Exit:
     585    if ( cur == parser->cursor )
     586    {
     587      FT_ERROR(( "ps_parser_skip_PS_token: "
     588                 "current token is `%c', which is self-delimiting "
     589                 "but invalid at this point\n",
     590                 *cur ));
     591     
     592      error = PSaux_Err_Invalid_File_Format;
     593    }
     594
     595    FT_ASSERT( parser->error == PSaux_Err_Ok );
     596    parser->error  = error;
    463597    parser->cursor = cur;
    464598  }
     
    481615    FT_Byte*  cur;
    482616    FT_Byte*  limit;
    483     FT_Byte   starter, ender;
    484617    FT_Int    embed;
    485618
     
    504637      token->type  = T1_TOKEN_TYPE_STRING;
    505638      token->start = cur;
    506       skip_literal_string( &cur, limit );
    507       if ( cur < limit )
     639
     640      if ( skip_literal_string( &cur, limit ) == PSaux_Err_Ok )
    508641        token->limit = cur;
    509642      break;
     
    511644      /************* check for programs/array *****************/
    512645    case '{':
    513       token->type = T1_TOKEN_TYPE_ARRAY;
    514       ender = '}';
    515       goto Lookup_Ender;
     646      token->type  = T1_TOKEN_TYPE_ARRAY;
     647      token->start = cur;
     648
     649      if ( skip_procedure( &cur, limit ) == PSaux_Err_Ok )
     650        token->limit = cur;
     651      break;
    516652
    517653      /************* check for table/array ********************/
     654      /* XXX: in theory we should also look for "<<"          */
     655      /*      since this is semantically equivalent to "[";   */
     656      /*      in practice it doesn't matter (?)               */
    518657    case '[':
    519       token->type = T1_TOKEN_TYPE_ARRAY;
    520       ender = ']';
    521       /* fall through */
    522 
    523     Lookup_Ender:
     658      token->type  = T1_TOKEN_TYPE_ARRAY;
    524659      embed        = 1;
    525       starter      = *cur;
    526660      token->start = cur++;
    527661
     
    533667      while ( cur < limit && !parser->error )
    534668      {
    535         if ( *cur == starter )
     669        /* XXX: this is wrong because it does not      */
     670        /*      skip comments, procedures, and strings */
     671        if ( *cur == '[' )
    536672          embed++;
    537         else if ( *cur == ender )
     673        else if ( *cur == ']' )
    538674        {
    539675          embed--;
     
    556692    default:
    557693      token->start = cur;
    558       token->type  = T1_TOKEN_TYPE_ANY;
     694      token->type  = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY );
    559695      ps_parser_skip_PS_token( parser );
    560696      cur = parser->cursor;
     
    572708  }
    573709
     710
     711  /* NB: `tokens' can be NULL if we only want to count */
     712  /* the number of array elements                      */
    574713
    575714  FT_LOCAL_DEF( void )
     
    608747          break;
    609748
    610         if ( cur < limit )
     749        if ( tokens != NULL && cur < limit )
    611750          *cur = token;
    612751
     
    623762
    624763  /* first character must be a delimiter or a part of a number */
     764  /* NB: `coords' can be NULL if we just want to skip the      */
     765  /*     array; in this case we ignore `max_coords'            */
    625766
    626767  static FT_Int
     
    655796    while ( cur < limit )
    656797    {
     798      FT_Short dummy;
     799
     800
    657801      /* skip whitespace in front of data */
    658802      skip_spaces( &cur, limit );
     
    660804        goto Exit;
    661805
    662       if ( count >= max_coords )
    663         break;
    664 
    665       if ( c == ender )
     806      if ( coords != NULL && count >= max_coords )
     807        break;
     808
     809      if ( *cur == ender )
    666810      {
    667811        cur++;
     
    669813      }
    670814
    671       coords[count] =
     815      /* call PS_Conv_ToFixed() even if coords == NULL */
     816      /* to properly parse number at `cur'             */
     817      *( coords != NULL ? &coords[count] : &dummy ) =
    672818        (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
    673819      count++;
     
    684830
    685831  /* first character must be a delimiter or a part of a number */
     832  /* NB: `values' can be NULL if we just want to skip the      */
     833  /*     array in this case we ignore `max_values'             */
    686834
    687835  static FT_Int
     
    717865    while ( cur < limit )
    718866    {
     867      FT_Fixed dummy;
     868
     869
    719870      /* skip whitespace in front of data */
    720871      skip_spaces( &cur, limit );
     
    722873        goto Exit;
    723874
    724       if ( count >= max_values )
    725         break;
    726 
    727       if ( c == ender )
     875      if ( values != NULL && count >= max_values )
     876        break;
     877
     878      if ( *cur == ender )
    728879      {
    729880        cur++;
     
    731882      }
    732883
    733       values[count] = PS_Conv_ToFixed( &cur, limit, power_ten );
     884      /* call PS_Conv_ToFixed() even if coords == NULL */
     885      /* to properly parse number at `cur'             */
     886      *( values != NULL ? &values[count] : &dummy ) =
     887        PS_Conv_ToFixed( &cur, limit, power_ten );
    734888      count++;
    735889
     
    9581112            break;
    9591113
    960           if ( field->type == T1_FIELD_TYPE_KEY )
     1114          /* we allow both a string or a name   */
     1115          /* for cases like /FontName (foo) def */
     1116          if ( token.type == T1_TOKEN_TYPE_KEY )
    9611117          {
    9621118            /* don't include leading `/' */
     
    9641120            cur++;
    9651121          }
     1122          else if ( token.type == T1_TOKEN_TYPE_STRING )
     1123          {
     1124            /* don't include delimiting parentheses    */
     1125            /* XXX we don't handle <<...>> here        */
     1126            /* XXX should we convert octal escapes?    */
     1127            /*     if so, what encoding should we use? */
     1128            cur++;
     1129            len -= 2;
     1130          }
    9661131          else
    9671132          {
    968             /* don't include delimiting parentheses */
    969             cur++;
    970             len -= 2;
     1133            FT_ERROR(( "ps_parser_load_field: expected a name or string "
     1134                       "but found token of type %d instead\n",
     1135                       token.type ));
     1136            error = PSaux_Err_Invalid_File_Format;
     1137            goto Exit;
     1138          }
     1139
     1140          /* for this to work (FT_String**)q must have been */
     1141          /* initialized to NULL                            */
     1142          if ( *(FT_String**)q != NULL )
     1143          {
     1144            FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n",
     1145                        field->ident ));
     1146            FT_FREE( *(FT_String**)q );
     1147            *(FT_String**)q = NULL;
    9711148          }
    9721149
     
    10391216
    10401217
    1041 #if 1
    10421218    fieldrec.type = T1_FIELD_TYPE_INTEGER;
    1043     if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY )
     1219    if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY ||
     1220         field->type == T1_FIELD_TYPE_BBOX        )
    10441221      fieldrec.type = T1_FIELD_TYPE_FIXED;
    1045 #endif
    10461222
    10471223    ps_parser_to_token_array( parser, elements,
     
    10581234    old_limit  = parser->limit;
    10591235
    1060     /* we store the elements count */
    1061     *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
    1062       (FT_Byte)num_elements;
     1236    /* we store the elements count if necessary */
     1237    if ( field->type != T1_FIELD_TYPE_BBOX )
     1238      *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
     1239        (FT_Byte)num_elements;
    10631240
    10641241    /* we now load each element, adjusting the field.offset on each one */
  • trunk/poppler/freetype2/src/psaux/t1cmap.c

    r150 r165  
    277277                                   unicodes,
    278278                                   face->type1.num_glyphs,
    279                                    (PS_Glyph_NameFunc)&t1_get_glyph_name,
     279                                   (PS_GetGlyphNameFunc)&t1_get_glyph_name,
     280                                   (PS_FreeGlyphNameFunc)NULL,
    280281                                   (FT_Pointer)face );
    281282  }
  • trunk/poppler/freetype2/src/psaux/t1decode.c

    r150 r165  
    55/*    PostScript Type 1 decoding routines (body).                          */
    66/*                                                                         */
    7 /*  Copyright 2000-2001, 2002, 2003, 2004, 2005 by                         */
     7/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by                   */
    88/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    99/*                                                                         */
     
    6666    op_return,
    6767    op_setcurrentpoint,
     68    op_unknown15,
    6869
    6970    op_max    /* never remove this one */
     
    100101    0, /* pop */
    101102    0, /* return */
    102     2  /* setcurrentpoint */
     103    2, /* setcurrentpoint */
     104    2  /* opcode 15 (undocumented and obsolete) */
    103105  };
    104106
     
    324326    T1_Builder       builder = &decoder->builder;
    325327    FT_Pos           x, y, orig_x, orig_y;
     328    FT_Int           known_othersubr_result_cnt   = 0;
     329    FT_Int           unknown_othersubr_result_cnt = 0;
    326330
    327331    T1_Hints_Funcs   hinter;
     
    345349    hinter = (T1_Hints_Funcs)builder->hints_funcs;
    346350
     351    /* a font that reads BuildCharArray without setting */
     352    /* its values first is buggy, but ...               */
     353    FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
     354               ( decoder->buildchar == NULL ) );
     355
     356    if ( decoder->len_buildchar > 0 )
     357      memset( &decoder->buildchar[0],
     358              0,
     359              sizeof( decoder->buildchar[0] ) *
     360                decoder->len_buildchar );
     361
     362    FT_TRACE4(( "\nStart charstring\n" ));
     363
    347364    zone->base           = charstring_base;
    348365    limit = zone->limit  = charstring_base + charstring_len;
     
    366383
    367384
     385      FT_ASSERT( known_othersubr_result_cnt == 0   ||
     386                 unknown_othersubr_result_cnt == 0 );
     387
     388      FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
     389
    368390      /*********************************************************************/
    369391      /*                                                                   */
     
    415437
    416438      case 15:          /* undocumented, obsolete operator */
    417         op = op_none;
     439        op = op_unknown15;
    418440        break;
    419441
     
    518540                     "invalid byte (%d)\n", ip[-1] ));
    519541          goto Syntax_Error;
     542        }
     543      }
     544
     545      if ( unknown_othersubr_result_cnt > 0 )
     546      {
     547        switch ( op )
     548        {
     549        case op_callsubr:
     550        case op_return:
     551        case op_none:
     552        case op_pop:
     553          break;
     554
     555        default:
     556          /* all operands have been transferred by previous pops */
     557          unknown_othersubr_result_cnt = 0;
     558          break;
    520559        }
    521560      }
     
    541580      else if ( op == op_callothersubr )  /* callothersubr */
    542581      {
     582        FT_Int  subr_no;
     583        FT_Int  arg_cnt;
     584
     585
    543586        FT_TRACE4(( " callothersubr" ));
    544587
     
    547590
    548591        top -= 2;
    549         switch ( (FT_Int)top[1] )
     592
     593        subr_no = (FT_Int)top[1];
     594        arg_cnt = (FT_Int)top[0];
     595
     596        /***********************************************************/
     597        /*                                                         */
     598        /* remove all operands to callothersubr from the stack     */
     599        /*                                                         */
     600        /* for handled othersubrs, where we know the number of     */
     601        /* arguments, we increase the stack by the value of        */
     602        /* known_othersubr_result_cnt                              */
     603        /*                                                         */
     604        /* for unhandled othersubrs the following pops adjust the  */
     605        /* stack pointer as necessary                              */
     606
     607        if ( arg_cnt > top - decoder->stack )
     608          goto Stack_Underflow;
     609
     610        top -= arg_cnt;
     611
     612        known_othersubr_result_cnt   = 0;
     613        unknown_othersubr_result_cnt = 0;
     614
     615        /* XXX TODO: The checks to `arg_count == <whatever>'       */
     616        /* might not be correct; an othersubr expects a certain    */
     617        /* number of operands on the PostScript stack (as opposed  */
     618        /* to the T1 stack) but it doesn't have to put them there  */
     619        /* by itself; previous othersubrs might have left the      */
     620        /* operands there if they were not followed by an          */
     621        /* appropriate number of pops                              */
     622        /*                                                         */
     623        /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
     624        /* accept a font that contains charstrings like            */
     625        /*                                                         */
     626        /*     100 200 2 20 callothersubr                          */
     627        /*     300 1 20 callothersubr pop                          */
     628        /*                                                         */
     629        /* Perhaps this is the reason why BuildCharArray exists.   */
     630
     631        switch ( subr_no )
    550632        {
    551633        case 1:                     /* start flex feature */
    552           if ( top[0] != 0 )
     634          if ( arg_cnt != 0 )
    553635            goto Unexpected_OtherSubr;
    554636
     
    565647
    566648
    567             if ( top[0] != 0 )
     649            if ( arg_cnt != 0 )
    568650              goto Unexpected_OtherSubr;
    569651
     
    581663
    582664        case 0:                     /* end flex feature */
    583           if ( top[0] != 3 )
     665          if ( arg_cnt != 3 )
    584666            goto Unexpected_OtherSubr;
    585667
     
    592674          }
    593675
    594           /* now consume the remaining `pop pop setcurpoint' */
    595           if ( ip + 6 > limit ||
    596                ip[0] != 12 || ip[1] != 17 || /* pop */
    597                ip[2] != 12 || ip[3] != 17 || /* pop */
    598                ip[4] != 12 || ip[5] != 33 )  /* setcurpoint */
    599           {
    600             FT_ERROR(( "t1_decoder_parse_charstrings: "
    601                        "invalid flex charstring\n" ));
    602             goto Syntax_Error;
    603           }
    604 
    605           ip += 6;
    606           decoder->flex_state = 0;
     676          /* the two `results' are popped by the following setcurrentpoint */
     677          known_othersubr_result_cnt = 2;
    607678          break;
    608679
    609680        case 3:                     /* change hints */
    610           if ( top[0] != 1 )
     681          if ( arg_cnt != 1 )
    611682            goto Unexpected_OtherSubr;
    612683
    613           /* eat the following `pop' */
    614           if ( ip + 2 > limit )
    615           {
    616             FT_ERROR(( "t1_decoder_parse_charstrings: "
    617                        "invalid escape (12+%d)\n", ip[-1] ));
    618             goto Syntax_Error;
    619           }
    620 
    621           if ( ip[0] != 12 || ip[1] != 17 )
    622           {
    623             FT_ERROR(( "t1_decoder_parse_charstrings: " ));
    624             FT_ERROR(( "`pop' expected, found (%d %d)\n", ip[0], ip[1] ));
    625             goto Syntax_Error;
    626           }
    627           ip += 2;
     684          known_othersubr_result_cnt = 1;
    628685
    629686          if ( hinter )
     
    657714            }
    658715
    659             num_points = (FT_UInt)top[1] - 13 + ( top[1] == 18 );
    660             if ( top[0] != (FT_Int)( num_points * blend->num_designs ) )
     716            num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 );
     717            if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )
    661718            {
    662719              FT_ERROR(( "t1_decoder_parse_charstrings: " ));
     
    664721              goto Syntax_Error;
    665722            }
    666 
    667             top -= blend->num_designs * num_points;
    668             if ( top < decoder->stack )
    669               goto Stack_Underflow;
    670723
    671724            /* we want to compute:                                   */
     
    696749              *values++ = tmp;
    697750            }
    698             /* note that `top' will be incremented later by calls to `pop' */
     751
     752            known_othersubr_result_cnt = num_points;
    699753            break;
    700754          }
    701755
     756#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
     757
     758          /* We cannot yet enable these since currently  */
     759          /* our T1 stack stores integers which lack the */
     760          /* precision to express the values             */
     761
     762        case 19:
     763          /* <idx> 1 19 callothersubr                             */
     764          /* => replace elements starting from index cvi( <idx> ) */
     765          /*    of BuildCharArray with WeightVector               */
     766          {
     767            FT_Int    idx;
     768            PS_Blend  blend = decoder->blend;
     769
     770
     771            if ( arg_cnt != 1 || blend == NULL )
     772              goto Unexpected_OtherSubr;
     773
     774            idx = top[0];
     775
     776            if ( idx < 0                                                 ||
     777                 idx + blend->num_designs > decoder->face->len_buildchar )
     778              goto Unexpected_OtherSubr;
     779
     780            memcpy( &decoder->buildchar[idx],
     781                    blend->weight_vector,
     782                    blend->num_designs *
     783                      sizeof( blend->weight_vector[ 0 ] ) );
     784          }
     785          break;
     786
     787        case 20:
     788          /* <arg1> <arg2> 2 20 callothersubr pop   */
     789          /* ==> push <arg1> + <arg2> onto T1 stack */
     790          if ( arg_cnt != 2 )
     791            goto Unexpected_OtherSubr;
     792
     793          top[0] += top[1]; /* XXX (over|under)flow */
     794
     795          known_othersubr_result_cnt = 1;
     796          break;
     797
     798        case 21:
     799          /* <arg1> <arg2> 2 21 callothersubr pop   */
     800          /* ==> push <arg1> - <arg2> onto T1 stack */
     801          if ( arg_cnt != 2 )
     802            goto Unexpected_OtherSubr;
     803
     804          top[0] -= top[1]; /* XXX (over|under)flow */
     805
     806          known_othersubr_result_cnt = 1;
     807          break;
     808
     809        case 22:
     810          /* <arg1> <arg2> 2 22 callothersubr pop   */
     811          /* ==> push <arg1> * <arg2> onto T1 stack */
     812          if ( arg_cnt != 2 )
     813            goto Unexpected_OtherSubr;
     814
     815          top[0] *= top[1]; /* XXX (over|under)flow */
     816
     817          known_othersubr_result_cnt = 1;
     818          break;
     819
     820        case 23:
     821          /* <arg1> <arg2> 2 23 callothersubr pop   */
     822          /* ==> push <arg1> / <arg2> onto T1 stack */
     823          if ( arg_cnt != 2 || top[1] == 0 )
     824            goto Unexpected_OtherSubr;
     825
     826          top[0] /= top[1]; /* XXX (over|under)flow */
     827
     828          known_othersubr_result_cnt = 1;
     829          break;
     830
     831#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */
     832
     833        case 24:
     834          /* <val> <idx> 2 24 callothersubr              */
     835          /* => set BuildCharArray[cvi( <idx> )] = <val> */
     836          {
     837            FT_Int    idx;
     838            PS_Blend  blend = decoder->blend;
     839
     840            if ( arg_cnt != 2 || blend == NULL )
     841              goto Unexpected_OtherSubr;
     842
     843            idx = top[1];
     844
     845            if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
     846              goto Unexpected_OtherSubr;
     847
     848            decoder->buildchar[idx] = top[0];
     849          }
     850          break;
     851
     852        case 25:
     853          /* <idx> 1 25 callothersubr pop       */
     854          /* => push BuildCharArray[cvi( idx )] */
     855          /*    onto T1 stack                   */
     856          {
     857            FT_Int    idx;
     858            PS_Blend  blend = decoder->blend;
     859
     860            if ( arg_cnt != 1 || blend == NULL )
     861              goto Unexpected_OtherSubr;
     862
     863            idx = top[0];
     864
     865            if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
     866              goto Unexpected_OtherSubr;
     867
     868            top[0] = decoder->buildchar[idx];
     869          }
     870
     871          known_othersubr_result_cnt = 1;
     872          break;
     873
     874#if 0
     875        case 26:
     876          /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
     877          /*                      leave mark on T1 stack                    */
     878          /* <val> <idx>      ==> set BuildCharArray[cvi( <idx> )] = <val>  */
     879          XXX who has left his mark on the (PostScript) stack ?;
     880          break;
     881#endif
     882
     883        case 27:
     884          /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
     885          /* ==> push <res1> onto T1 stack if <val1> <= <val2>,  */
     886          /*     otherwise push <res2>                          */
     887          if ( arg_cnt != 4 )
     888            goto Unexpected_OtherSubr;
     889
     890          if ( top[2] > top[3] )
     891            top[0] = top[1];
     892
     893          known_othersubr_result_cnt = 1;
     894          break;
     895
     896#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
     897        case 28:
     898          /* 0 28 callothersubr pop                               */
     899          /* => push random value from interval [0, 1) onto stack */
     900          if ( arg_cnt != 0 )
     901            goto Unexpected_OtherSubr;
     902
     903          top[0] = FT_rand();
     904          known_othersubr_result_cnt = 1;
     905          break;
     906#endif
     907
    702908        default:
     909          FT_ERROR(( "t1_decoder_parse_charstrings: "
     910                     "unknown othersubr [%d %d], wish me luck!\n",
     911                     arg_cnt, subr_no ));
     912          unknown_othersubr_result_cnt = arg_cnt;
     913          break;
     914
    703915        Unexpected_OtherSubr:
    704916          FT_ERROR(( "t1_decoder_parse_charstrings: "
    705                      "invalid othersubr [%d %d]!\n", top[0], top[1] ));
     917                     "invalid othersubr [%d %d]!\n", arg_cnt, subr_no ));
    706918          goto Syntax_Error;
    707919        }
     920
     921        top += known_othersubr_result_cnt;
     922
    708923        decoder->top = top;
    709924      }
     
    713928
    714929
     930        FT_ASSERT( num_args >= 0 );
     931
    715932        if ( top - decoder->stack < num_args )
    716933          goto Stack_Underflow;
     934
     935        /* XXX Operators usually take their operands from the        */
     936        /*     bottom of the stack, i.e., the operands are           */
     937        /*     decoder->stack[0], ..., decoder->stack[num_args - 1]; */
     938        /*     only div, callsubr, and callothersubr are different.  */
     939        /*     In practice it doesn't matter (?).                    */
     940
     941#ifdef FT_DEBUG_LEVEL_TRACE
     942
     943        switch ( op )
     944        {
     945        case op_callsubr:
     946        case op_div:
     947        case op_callothersubr:
     948        case op_pop:
     949        case op_return:
     950          break;
     951
     952        default:
     953          if ( top - decoder->stack != num_args )
     954            FT_TRACE0(( "\nMore operands on the stack than expected "
     955                        "(have %d, expected %d)\n",
     956                        top - decoder->stack, num_args ));
     957            break;
     958        }
     959
     960#endif /* FT_DEBUG_LEVEL_TRACE */
    717961
    718962        top -= num_args;
     
    741985          FT_GlyphLoader_Add( builder->loader );
    742986
     987          FT_TRACE4(( "\n" ));
     988
     989          /* the compiler should optimize away this empty loop but ... */
     990
     991#ifdef FT_DEBUG_LEVEL_TRACE
     992
     993          if ( decoder->len_buildchar > 0 )
     994          {
     995            FT_UInt  i;
     996
     997
     998            FT_TRACE4(( "BuildCharArray = [ " ));
     999
     1000            for ( i = 0; i < decoder->len_buildchar; ++i )
     1001              FT_TRACE4(( "%d ", decoder->buildchar[ i ] ));
     1002
     1003            FT_TRACE4(( "]\n" ));
     1004          }
     1005
     1006#endif /* FT_DEBUG_LEVEL_TRACE */
     1007
     1008          FT_TRACE4(( "\n" ));
     1009
    7431010          /* return now! */
    744           FT_TRACE4(( "\n\n" ));
    7451011          return PSaux_Err_Ok;
    7461012
     
    9981264          FT_TRACE4(( " pop" ));
    9991265
    1000           /* theoretically, the arguments are already on the stack */
    1001           top++;
     1266          if ( known_othersubr_result_cnt > 0 )
     1267          {
     1268            known_othersubr_result_cnt--;
     1269            /* ignore, we pushed the operands ourselves */
     1270            break;
     1271          }
     1272
     1273          if ( unknown_othersubr_result_cnt == 0 )
     1274          {
     1275            FT_ERROR(( "t1_decoder_parse_charstrings: "
     1276                       "no more operands for othersubr!\n" ));
     1277            goto Syntax_Error;
     1278          }
     1279
     1280          unknown_othersubr_result_cnt--;
     1281          top++;   /* `push' the operand to callothersubr onto the stack */
    10021282          break;
    10031283
     
    10741354          FT_TRACE4(( " setcurrentpoint" ));
    10751355
    1076           FT_ERROR(( "t1_decoder_parse_charstrings: " ));
    1077           FT_ERROR(( "unexpected `setcurrentpoint'\n" ));
    1078           goto Syntax_Error;
     1356          /* From the T1 specs, section 6.4:                        */
     1357          /*                                                        */
     1358          /*   The setcurrentpoint command is used only in          */
     1359          /*   conjunction with results from OtherSubrs procedures. */
     1360
     1361          /* known_othersubr_result_cnt != 0 is already handled above */
     1362          if ( decoder->flex_state != 1 )
     1363          {
     1364            FT_ERROR(( "t1_decoder_parse_charstrings: " ));
     1365            FT_ERROR(( "unexpected `setcurrentpoint'\n" ));
     1366
     1367            goto Syntax_Error;
     1368          }
     1369          else
     1370            decoder->flex_state = 0;
     1371          break;
     1372
     1373        case op_unknown15:
     1374          FT_TRACE4(( " opcode_15" ));
     1375          /* nothing to do except to pop the two arguments */
     1376          break;
    10791377
    10801378        default:
     
    10831381          goto Syntax_Error;
    10841382        }
     1383
     1384        /* XXX Operators usually clear the operand stack;  */
     1385        /*     only div, callsubr, callothersubr, pop, and */
     1386        /*     return are different.                       */
     1387        /*     In practice it doesn't matter (?).          */
    10851388
    10861389        decoder->top = top;
     
    11441447    t1_builder_init( &decoder->builder, face, size, slot, hinting );
    11451448
     1449    /* decoder->buildchar and decoder->len_buildchar have to be  */
     1450    /* initialized by the caller since we cannot know the length */
     1451    /* of the BuildCharArray                                     */
     1452
    11461453    decoder->num_glyphs     = (FT_UInt)face->num_glyphs;
    11471454    decoder->glyph_names    = glyph_names;
     
    11521459    decoder->funcs          = t1_decoder_funcs;
    11531460
    1154     return 0;
     1461    return PSaux_Err_Ok;
    11551462  }
    11561463
  • trunk/poppler/freetype2/src/pshinter/pshalgo.c

    r150 r165  
    55/*    PostScript hinting algorithm (body).                                 */
    66/*                                                                         */
    7 /*  Copyright 2001, 2002, 2003, 2004, 2005 by                              */
     7/*  Copyright 2001, 2002, 2003, 2004, 2005, 2006 by                        */
    88/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    99/*                                                                         */
     
    2020#include FT_INTERNAL_OBJECTS_H
    2121#include FT_INTERNAL_DEBUG_H
     22#include FT_INTERNAL_CALC_H
    2223#include "pshalgo.h"
    2324
     
    880881  /*************************************************************************/
    881882
     883#if 1
     884
     885#define  psh_corner_is_flat      ft_corner_is_flat
     886#define  psh_corner_orientation  ft_corner_orientation
     887
     888#else
     889
     890  FT_LOCAL_DEF( FT_Int )
     891  psh_corner_is_flat( FT_Pos  x_in,
     892                      FT_Pos  y_in,
     893                      FT_Pos  x_out,
     894                      FT_Pos  y_out )
     895  {
     896    FT_Pos  ax = x_in;
     897    FT_Pos  ay = y_in;
     898
     899    FT_Pos  d_in, d_out, d_corner;
     900
     901
     902    if ( ax < 0 )
     903      ax = -ax;
     904    if ( ay < 0 )
     905      ay = -ay;
     906    d_in = ax + ay;
     907
     908    ax = x_out;
     909    if ( ax < 0 )
     910      ax = -ax;
     911    ay = y_out;
     912    if ( ay < 0 )
     913      ay = -ay;
     914    d_out = ax + ay;
     915
     916    ax = x_out + x_in;
     917    if ( ax < 0 )
     918      ax = -ax;
     919    ay = y_out + y_in;
     920    if ( ay < 0 )
     921      ay = -ay;
     922    d_corner = ax + ay;
     923
     924    return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
     925  }
     926
     927  static FT_Int
     928  psh_corner_orientation( FT_Pos  in_x,
     929                          FT_Pos  in_y,
     930                          FT_Pos  out_x,
     931                          FT_Pos  out_y )
     932  {
     933    FT_Int  result;
     934
     935
     936    /* deal with the trivial cases quickly */
     937    if ( in_y == 0 )
     938    {
     939      if ( in_x >= 0 )
     940        result = out_y;
     941      else
     942        result = -out_y;
     943    }
     944    else if ( in_x == 0 )
     945    {
     946      if ( in_y >= 0 )
     947        result = -out_x;
     948      else
     949        result = out_x;
     950    }
     951    else if ( out_y == 0 )
     952    {
     953      if ( out_x >= 0 )
     954        result = in_y;
     955      else
     956        result = -in_y;
     957    }
     958    else if ( out_x == 0 )
     959    {
     960      if ( out_y >= 0 )
     961        result = -in_x;
     962      else
     963        result =  in_x;
     964    }
     965    else /* general case */
     966    {
     967      long long  delta = (long long)in_x * out_y - (long long)in_y * out_x;
     968
     969      if ( delta == 0 )
     970        result = 0;
     971      else
     972        result = 1 - 2 * ( delta < 0 );
     973    }
     974
     975    return result;
     976  }
     977
     978#endif /* !1 */
     979
     980
    882981#ifdef COMPUTE_INFLEXS
    883982
     
    892991    {
    893992      PSH_Point  first, start, end, before, after;
    894       FT_Angle   angle_in, angle_seg, angle_out;
    895       FT_Angle   diff_in, diff_out;
     993      FT_Pos     in_x, in_y, out_x, out_y;
     994      FT_Int     orient_prev, orient_cur;
    896995      FT_Int     finished = 0;
    897996
     
    9111010          goto Skip;
    9121011
    913       } while ( PSH_POINT_EQUAL_ORG( end, first ) );
    914 
    915       angle_seg = PSH_POINT_ANGLE( start, end );
     1012        in_x = end->org_u - start->org_u;
     1013        in_y = end->org_v - start->org_v;
     1014
     1015      } while ( in_x == 0 && in_y == 0 );
    9161016
    9171017      /* extend the segment start whenever possible */
     
    9261026            goto Skip;
    9271027
    928         } while ( PSH_POINT_EQUAL_ORG( before, start ) );
    929 
    930         angle_in = PSH_POINT_ANGLE( before, start );
    931 
    932       } while ( angle_in == angle_seg );
    933 
    934       first   = start;
    935       diff_in = FT_Angle_Diff( angle_in, angle_seg );
     1028          out_x = start->org_u - before->org_u;
     1029          out_y = start->org_v - before->org_v;
     1030
     1031        } while ( out_x == 0 && out_y == 0 );
     1032
     1033        orient_prev = psh_corner_orientation( in_x, in_y, out_x, out_y );
     1034
     1035      } while ( orient_prev != 0 );
     1036
     1037      first = start;
     1038      in_x  = out_x;
     1039      in_y  = out_y;
    9361040
    9371041      /* now, process all segments in the contour */
     
    9491053              finished = 1;
    9501054
    951           } while ( PSH_POINT_EQUAL_ORG( end, after ) );
    952 
    953           angle_out = PSH_POINT_ANGLE( end, after );
    954 
    955         } while ( angle_out == angle_seg );
    956 
    957         diff_out = FT_Angle_Diff( angle_seg, angle_out );
    958 
    959         if ( ( diff_in ^ diff_out ) < 0 )
    960         {
    961           /* diff_in and diff_out have different signs, we have */
    962           /* inflection points here...                          */
    963 
     1055            out_x = after->org_u - end->org_u;
     1056            out_y = after->org_v - end->org_v;
     1057
     1058          } while ( out_x == 0 && out_y == 0 );
     1059
     1060          orient_cur = psh_corner_orientation( in_x, in_y, out_x, out_y );
     1061
     1062        } while ( orient_cur == 0 );
     1063
     1064        if ( ( orient_cur ^ orient_prev ) < 0 )
     1065        {
    9641066          do
    9651067          {
     
    9721074        }
    9731075
    974         start     = end;
    975         end       = after;
    976         angle_seg = angle_out;
    977         diff_in   = diff_out;
     1076        start       = end;
     1077        end         = after;
     1078        orient_prev = orient_cur;
     1079        in_x        = out_x;
     1080        in_y        = out_y;
    9781081
    9791082      } while ( !finished );
     
    12001303        if ( point->flags & PSH_POINT_OFF )
    12011304          point->flags |= PSH_POINT_SMOOTH;
    1202         else if ( point->dir_in  != PSH_DIR_NONE ||
    1203                   point->dir_out != PSH_DIR_NONE )
    1204         {
    1205           if ( point->dir_in == point->dir_out )
    1206             point->flags |= PSH_POINT_SMOOTH;
    1207         }
    1208         else
    1209         {
    1210           FT_Angle  angle_in, angle_out, diff;
    1211 
    1212 
    1213           angle_in  = FT_Atan2( dxi, dyi );
    1214           angle_out = FT_Atan2( dxo, dyo );
    1215 
    1216           diff = angle_in - angle_out;
    1217           if ( diff < 0 )
    1218             diff = -diff;
    1219 
    1220           if ( diff > FT_ANGLE_PI )
    1221             diff = FT_ANGLE_2PI - diff;
    1222 
    1223           if ( diff < FT_ANGLE_PI / 16 )
     1305
     1306        else if ( point->dir_in == point->dir_out )
     1307        {
     1308          if ( point->dir_out != PSH_DIR_NONE           ||
     1309               psh_corner_is_flat( dxi, dyi, dxo, dyo ) )
    12241310            point->flags |= PSH_POINT_SMOOTH;
    12251311        }
     
    13831469
    13841470  static void
    1385   psh_hint_table_find_strong_point( PSH_Hint_Table  table,
    1386                                     PSH_Point       point,
    1387                                     FT_Int          threshold,
    1388                                     FT_Int          major_dir )
     1471  psh_hint_table_find_strong_points( PSH_Hint_Table  table,
     1472                                     PSH_Point       point,
     1473                                     FT_UInt         count,
     1474                                     FT_Int          threshold,
     1475                                     FT_Int          major_dir )
    13891476  {
    13901477    PSH_Hint*  sort      = table->sort;
    13911478    FT_UInt    num_hints = table->num_hints;
    1392     FT_