< prev index next >

src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c

Print this page




  55 #include "tterrors.h"
  56 
  57 
  58 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  59 
  60 
  61 #define FT_Stream_FTell( stream )                         \
  62           (FT_ULong)( (stream)->cursor - (stream)->base )
  63 #define FT_Stream_SeekSet( stream, off )                               \
  64           (stream)->cursor =                                           \
  65             ( (off) < (FT_ULong)( (stream)->limit - (stream)->base ) ) \
  66                         ? (stream)->base + (off)                       \
  67                         : (stream)->limit
  68 
  69 
  70   /* some macros we need */
  71 #define FT_fdot14ToFixed( x )                \
  72         ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
  73 #define FT_intToFixed( i )                    \
  74         ( (FT_Fixed)( (FT_ULong)(i) << 16 ) )


  75 #define FT_fixedToInt( x )                                   \
  76         ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )


  77 
  78 
  79   /**************************************************************************
  80    *
  81    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
  82    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
  83    * messages during execution.
  84    */
  85 #undef  FT_COMPONENT
  86 #define FT_COMPONENT  ttgxvar
  87 
  88 
  89   /*************************************************************************/
  90   /*************************************************************************/
  91   /*****                                                               *****/
  92   /*****                       Internal Routines                       *****/
  93   /*****                                                               *****/
  94   /*************************************************************************/
  95   /*************************************************************************/
  96 


 380     {
 381       FT_TRACE5(( "  axis %d:\n", i ));
 382 
 383       segment->pairCount = FT_GET_USHORT();
 384       if ( (FT_ULong)segment->pairCount * 4 > table_len                ||
 385            FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) )
 386       {
 387         /* Failure.  Free everything we have done so far.  We must do */
 388         /* it right now since loading the `avar' table is optional.   */
 389 
 390         for ( j = i - 1; j >= 0; j-- )
 391           FT_FREE( blend->avar_segment[j].correspondence );
 392 
 393         FT_FREE( blend->avar_segment );
 394         blend->avar_segment = NULL;
 395         goto Exit;
 396       }
 397 
 398       for ( j = 0; j < segment->pairCount; j++ )
 399       {
 400         /* convert to Fixed */
 401         segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4;
 402         segment->correspondence[j].toCoord   = FT_GET_SHORT() * 4;

 403 
 404         FT_TRACE5(( "    mapping %.5f to %.5f\n",
 405                     segment->correspondence[j].fromCoord / 65536.0,
 406                     segment->correspondence[j].toCoord / 65536.0 ));
 407       }
 408 
 409       FT_TRACE5(( "\n" ));
 410     }
 411 
 412   Exit:
 413     FT_FRAME_EXIT();
 414   }
 415 
 416 
 417   static FT_Error
 418   ft_var_load_item_variation_store( TT_Face          face,
 419                                     FT_ULong         offset,
 420                                     GX_ItemVarStore  itemStore )
 421   {
 422     FT_Stream  stream = FT_FACE_STREAM( face );


1599     FT_FRAME_EXIT();
1600     if ( error )
1601       goto Exit;
1602 
1603     if ( blend->tuplecount != 0 )
1604     {
1605       if ( FT_NEW_ARRAY( blend->tuplecoords,
1606                          gvar_head.axisCount * blend->tuplecount ) )
1607         goto Exit;
1608 
1609       if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord )         ||
1610            FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) )
1611         goto Exit;
1612 
1613       for ( i = 0; i < blend->tuplecount; i++ )
1614       {
1615         FT_TRACE5(( "  [ " ));
1616         for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ )
1617         {
1618           blend->tuplecoords[i * gvar_head.axisCount + j] =
1619             FT_GET_SHORT() * 4;                 /* convert to FT_Fixed */
1620           FT_TRACE5(( "%.5f ",
1621             blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 ));
1622         }
1623         FT_TRACE5(( "]\n" ));
1624       }
1625 
1626       FT_TRACE5(( "\n" ));
1627 
1628       FT_FRAME_EXIT();
1629     }
1630 
1631   Exit:
1632     return error;
1633   }
1634 
1635 
1636   /**************************************************************************
1637    *
1638    * @Function:
1639    *   ft_var_apply_tuple


3037     FT_MM_Var*  mmvar;
3038 
3039     FT_UInt  num_instances;
3040 
3041 
3042     if ( !face->blend )
3043     {
3044       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
3045         goto Exit;
3046     }
3047 
3048     blend = face->blend;
3049     mmvar = blend->mmvar;
3050 
3051     num_instances = (FT_UInt)face->root.style_flags >> 16;
3052 
3053     /* `instance_index' starts with value 1, thus `>' */
3054     if ( instance_index > num_instances )
3055       goto Exit;
3056 
3057     if ( instance_index > 0 && mmvar->namedstyle )
3058     {
3059       FT_Memory     memory = face->root.memory;
3060       SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
3061 
3062       FT_Var_Named_Style*  named_style;
3063       FT_String*           style_name;
3064 
3065 
3066       named_style = mmvar->namedstyle + instance_index - 1;
3067 
3068       error = sfnt->get_name( face,
3069                               (FT_UShort)named_style->strid,
3070                               &style_name );
3071       if ( error )
3072         goto Exit;
3073 
3074       /* set (or replace) style name */
3075       FT_FREE( face->root.style_name );
3076       face->root.style_name = style_name;
3077 
3078       /* finally, select the named instance */
3079       error = TT_Set_Var_Design( face,
3080                                  mmvar->num_axis,
3081                                  named_style->coords );
3082       if ( error )




3083         goto Exit;
3084     }

3085     else
3086       error = TT_Set_Var_Design( face, 0, NULL );
3087 
3088     face->root.face_index  = ( instance_index << 16 )             |
3089                              ( face->root.face_index & 0xFFFFL );
3090     face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
3091 
3092   Exit:
3093     return error;
3094   }
3095 
3096 
3097   /*************************************************************************/
3098   /*************************************************************************/
3099   /*****                                                               *****/
3100   /*****                     GX VAR PARSING ROUTINES                   *****/
3101   /*****                                                               *****/
3102   /*************************************************************************/
3103   /*************************************************************************/
3104 
3105 















3106   /**************************************************************************
3107    *
3108    * @Function:
3109    *   tt_face_vary_cvt
3110    *
3111    * @Description:
3112    *   Modify the loaded cvt table according to the `cvar' table and the
3113    *   font's blend.
3114    *
3115    * @InOut:
3116    *   face ::
3117    *     A handle to the target face object.
3118    *
3119    * @Input:
3120    *   stream ::
3121    *     A handle to the input stream.
3122    *
3123    * @Return:
3124    *   FreeType error code.  0 means success.
3125    *
3126    *   Most errors are ignored.  It is perfectly valid not to have a
3127    *   `cvar' table even if there is a `gvar' and `fvar' table.
3128    */
3129   FT_LOCAL_DEF( FT_Error )
3130   tt_face_vary_cvt( TT_Face    face,
3131                     FT_Stream  stream )
3132   {
3133     FT_Error   error;
3134     FT_Memory  memory = stream->memory;
3135 


3136     FT_ULong  table_start;
3137     FT_ULong  table_len;
3138 
3139     FT_UInt   tupleCount;
3140     FT_ULong  offsetToData;
3141 
3142     FT_ULong  here;
3143     FT_UInt   i, j;
3144 
3145     FT_Fixed*  tuple_coords    = NULL;
3146     FT_Fixed*  im_start_coords = NULL;
3147     FT_Fixed*  im_end_coords   = NULL;
3148 
3149     GX_Blend  blend = face->blend;
3150 
3151     FT_UInt  point_count;
3152     FT_UInt  spoint_count = 0;
3153 
3154     FT_UShort*  sharedpoints = NULL;
3155     FT_UShort*  localpoints  = NULL;


3244                 ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" ));
3245 
3246     if ( FT_NEW_ARRAY( cvt_deltas, face->cvt_size ) )
3247       goto FExit;
3248 
3249     for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ )
3250     {
3251       FT_UInt   tupleDataSize;
3252       FT_UInt   tupleIndex;
3253       FT_Fixed  apply;
3254 
3255 
3256       FT_TRACE6(( "  tuple %d:\n", i ));
3257 
3258       tupleDataSize = FT_GET_USHORT();
3259       tupleIndex    = FT_GET_USHORT();
3260 
3261       if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
3262       {
3263         for ( j = 0; j < blend->num_axis; j++ )
3264           tuple_coords[j] = FT_GET_SHORT() * 4;  /* convert from        */
3265                                                  /* short frac to fixed */
3266       }
3267       else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
3268       {
3269         FT_TRACE2(( "tt_face_vary_cvt:"
3270                     " invalid tuple index\n" ));
3271 
3272         error = FT_THROW( Invalid_Table );
3273         goto FExit;
3274       }
3275       else
3276       {
3277         if ( !blend->tuplecoords )
3278         {
3279           FT_TRACE2(( "tt_face_vary_cvt:"
3280                       " no valid tuple coordinates available\n" ));
3281 
3282           error = FT_THROW( Invalid_Table );
3283           goto FExit;
3284         }
3285 
3286         FT_MEM_COPY(
3287           tuple_coords,
3288           blend->tuplecoords +
3289             ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis,
3290           blend->num_axis * sizeof ( FT_Fixed ) );
3291       }
3292 
3293       if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
3294       {
3295         for ( j = 0; j < blend->num_axis; j++ )
3296           im_start_coords[j] = FT_GET_SHORT() * 4;
3297         for ( j = 0; j < blend->num_axis; j++ )
3298           im_end_coords[j] = FT_GET_SHORT() * 4;
3299       }
3300 
3301       apply = ft_var_apply_tuple( blend,
3302                                   (FT_UShort)tupleIndex,
3303                                   tuple_coords,
3304                                   im_start_coords,
3305                                   im_end_coords );
3306 
3307       if ( apply == 0 )              /* tuple isn't active for our blend */
3308       {
3309         offsetToData += tupleDataSize;
3310         continue;
3311       }
3312 
3313       here = FT_Stream_FTell( stream );
3314 
3315       FT_Stream_SeekSet( stream, offsetToData );
3316 
3317       if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS )
3318       {


3343         int  count = 0;
3344 #endif
3345 
3346 
3347         FT_TRACE7(( "    CVT deltas:\n" ));
3348 
3349         /* this means that there are deltas for every entry in cvt */
3350         for ( j = 0; j < face->cvt_size; j++ )
3351         {
3352           FT_Fixed  old_cvt_delta;
3353 
3354 
3355           old_cvt_delta = cvt_deltas[j];
3356           cvt_deltas[j] = old_cvt_delta + FT_MulFix( deltas[j], apply );
3357 
3358 #ifdef FT_DEBUG_LEVEL_TRACE
3359           if ( old_cvt_delta != cvt_deltas[j] )
3360           {
3361             FT_TRACE7(( "      %d: %f -> %f\n",
3362                         j,
3363                         ( FT_intToFixed( face->cvt[j] ) +
3364                           old_cvt_delta ) / 65536.0,
3365                         ( FT_intToFixed( face->cvt[j] ) +
3366                           cvt_deltas[j] ) / 65536.0 ));
3367             count++;
3368           }
3369 #endif
3370         }
3371 
3372 #ifdef FT_DEBUG_LEVEL_TRACE
3373         if ( !count )
3374           FT_TRACE7(( "      none\n" ));
3375 #endif
3376       }
3377 
3378       else
3379       {
3380 #ifdef FT_DEBUG_LEVEL_TRACE
3381         int  count = 0;
3382 #endif
3383 
3384 
3385         FT_TRACE7(( "    CVT deltas:\n" ));
3386 
3387         for ( j = 0; j < point_count; j++ )
3388         {
3389           int       pindex;
3390           FT_Fixed  old_cvt_delta;
3391 
3392 
3393           pindex = points[j];
3394           if ( (FT_ULong)pindex >= face->cvt_size )
3395             continue;
3396 
3397           old_cvt_delta      = cvt_deltas[pindex];
3398           cvt_deltas[pindex] = old_cvt_delta + FT_MulFix( deltas[j], apply );
3399 
3400 #ifdef FT_DEBUG_LEVEL_TRACE
3401           if ( old_cvt_delta != cvt_deltas[pindex] )
3402           {
3403             FT_TRACE7(( "      %d: %f -> %f\n",
3404                         pindex,
3405                         ( FT_intToFixed( face->cvt[pindex] ) +
3406                           old_cvt_delta ) / 65536.0,
3407                         ( FT_intToFixed( face->cvt[pindex] ) +
3408                           cvt_deltas[pindex] ) / 65536.0 ));
3409             count++;
3410           }
3411 #endif
3412         }
3413 
3414 #ifdef FT_DEBUG_LEVEL_TRACE
3415         if ( !count )
3416           FT_TRACE7(( "      none\n" ));
3417 #endif
3418       }
3419 
3420       if ( localpoints != ALL_POINTS )
3421         FT_FREE( localpoints );
3422       FT_FREE( deltas );
3423 
3424       offsetToData += tupleDataSize;
3425 
3426       FT_Stream_SeekSet( stream, here );
3427     }
3428 
3429     FT_TRACE5(( "\n" ));
3430 
3431     for ( i = 0; i < face->cvt_size; i++ )
3432       face->cvt[i] += FT_fixedToInt( cvt_deltas[i] );
3433 
3434   FExit:
3435     FT_FRAME_EXIT();
3436 
3437   Exit:
3438     if ( sharedpoints != ALL_POINTS )
3439       FT_FREE( sharedpoints );
3440     FT_FREE( tuple_coords );
3441     FT_FREE( im_start_coords );
3442     FT_FREE( im_end_coords );
3443     FT_FREE( cvt_deltas );
3444 






3445     return error;
3446   }
3447 
3448 
3449   /* Shift the original coordinates of all points between indices `p1' */
3450   /* and `p2', using the same difference as given by index `ref'.      */
3451 
3452   /* modeled after `af_iup_shift' */
3453 
3454   static void
3455   tt_delta_shift( int         p1,
3456                   int         p2,
3457                   int         ref,
3458                   FT_Vector*  in_points,
3459                   FT_Vector*  out_points )
3460   {
3461     int        p;
3462     FT_Vector  delta;
3463 
3464 


3652    *   TT_Vary_Apply_Glyph_Deltas
3653    *
3654    * @Description:
3655    *   Apply the appropriate deltas to the current glyph.
3656    *
3657    * @Input:
3658    *   face ::
3659    *     A handle to the target face object.
3660    *
3661    *   glyph_index ::
3662    *     The index of the glyph being modified.
3663    *
3664    *   n_points ::
3665    *     The number of the points in the glyph, including
3666    *     phantom points.
3667    *
3668    * @InOut:
3669    *   outline ::
3670    *     The outline to change.
3671    *





3672    * @Return:
3673    *   FreeType error code.  0 means success.
3674    */
3675   FT_LOCAL_DEF( FT_Error )
3676   TT_Vary_Apply_Glyph_Deltas( TT_Face      face,
3677                               FT_UInt      glyph_index,
3678                               FT_Outline*  outline,

3679                               FT_UInt      n_points )
3680   {
3681     FT_Error   error;
3682     FT_Stream  stream = face->root.stream;
3683     FT_Memory  memory = stream->memory;
3684 
3685     FT_Vector*  points_org = NULL;  /* coordinates in 16.16 format */
3686     FT_Vector*  points_out = NULL;  /* coordinates in 16.16 format */
3687     FT_Bool*    has_delta  = NULL;
3688 
3689     FT_ULong  glyph_start;
3690 
3691     FT_UInt   tupleCount;
3692     FT_ULong  offsetToData;
3693     FT_ULong  dataSize;
3694 
3695     FT_ULong  here;
3696     FT_UInt   i, j;
3697 
3698     FT_Fixed*  tuple_coords    = NULL;


3700     FT_Fixed*  im_end_coords   = NULL;
3701 
3702     GX_Blend  blend = face->blend;
3703 
3704     FT_UInt  point_count;
3705     FT_UInt  spoint_count = 0;
3706 
3707     FT_UShort*  sharedpoints = NULL;
3708     FT_UShort*  localpoints  = NULL;
3709     FT_UShort*  points;
3710 
3711     FT_Fixed*  deltas_x       = NULL;
3712     FT_Fixed*  deltas_y       = NULL;
3713     FT_Fixed*  point_deltas_x = NULL;
3714     FT_Fixed*  point_deltas_y = NULL;
3715 
3716 
3717     if ( !face->doblend || !blend )
3718       return FT_THROW( Invalid_Argument );
3719 






3720     if ( glyph_index >= blend->gv_glyphcnt      ||
3721          blend->glyphoffsets[glyph_index] ==
3722            blend->glyphoffsets[glyph_index + 1] )
3723     {
3724       FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
3725                   " no variation data for this glyph\n" ));
3726       return FT_Err_Ok;
3727     }
3728 
3729     if ( FT_NEW_ARRAY( points_org, n_points ) ||
3730          FT_NEW_ARRAY( points_out, n_points ) ||
3731          FT_NEW_ARRAY( has_delta, n_points )  )
3732       goto Fail1;
3733 
3734     dataSize = blend->glyphoffsets[glyph_index + 1] -
3735                  blend->glyphoffsets[glyph_index];
3736 
3737     if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) ||
3738          FT_FRAME_ENTER( dataSize )                         )
3739       goto Fail1;


3790     {
3791       points_org[j].x = FT_intToFixed( outline->points[j].x );
3792       points_org[j].y = FT_intToFixed( outline->points[j].y );
3793     }
3794 
3795     for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ )
3796     {
3797       FT_UInt   tupleDataSize;
3798       FT_UInt   tupleIndex;
3799       FT_Fixed  apply;
3800 
3801 
3802       FT_TRACE6(( "  tuple %d:\n", i ));
3803 
3804       tupleDataSize = FT_GET_USHORT();
3805       tupleIndex    = FT_GET_USHORT();
3806 
3807       if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
3808       {
3809         for ( j = 0; j < blend->num_axis; j++ )
3810           tuple_coords[j] = FT_GET_SHORT() * 4;   /* convert from        */
3811                                                   /* short frac to fixed */
3812       }
3813       else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
3814       {
3815         FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
3816                     " invalid tuple index\n" ));
3817 
3818         error = FT_THROW( Invalid_Table );
3819         goto Fail3;
3820       }
3821       else
3822         FT_MEM_COPY(
3823           tuple_coords,
3824           blend->tuplecoords +
3825             ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis,
3826           blend->num_axis * sizeof ( FT_Fixed ) );
3827 
3828       if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
3829       {
3830         for ( j = 0; j < blend->num_axis; j++ )
3831           im_start_coords[j] = FT_GET_SHORT() * 4;
3832         for ( j = 0; j < blend->num_axis; j++ )
3833           im_end_coords[j] = FT_GET_SHORT() * 4;
3834       }
3835 
3836       apply = ft_var_apply_tuple( blend,
3837                                   (FT_UShort)tupleIndex,
3838                                   tuple_coords,
3839                                   im_start_coords,
3840                                   im_end_coords );
3841 
3842       if ( apply == 0 )              /* tuple isn't active for our blend */
3843       {
3844         offsetToData += tupleDataSize;
3845         continue;
3846       }
3847 
3848       here = FT_Stream_FTell( stream );
3849 
3850       FT_Stream_SeekSet( stream, offsetToData );
3851 
3852       if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS )
3853       {


4047 #ifdef FT_DEBUG_LEVEL_TRACE
4048         if ( !count )
4049           FT_TRACE7(( "      none\n" ));
4050 #endif
4051       }
4052 
4053       if ( localpoints != ALL_POINTS )
4054         FT_FREE( localpoints );
4055       FT_FREE( deltas_x );
4056       FT_FREE( deltas_y );
4057 
4058       offsetToData += tupleDataSize;
4059 
4060       FT_Stream_SeekSet( stream, here );
4061     }
4062 
4063     FT_TRACE5(( "\n" ));
4064 
4065     for ( i = 0; i < n_points; i++ )
4066     {



4067       outline->points[i].x += FT_fixedToInt( point_deltas_x[i] );
4068       outline->points[i].y += FT_fixedToInt( point_deltas_y[i] );
4069     }
4070 
4071   Fail3:
4072     FT_FREE( point_deltas_x );
4073     FT_FREE( point_deltas_y );
4074 
4075   Fail2:
4076     if ( sharedpoints != ALL_POINTS )
4077       FT_FREE( sharedpoints );
4078     FT_FREE( tuple_coords );
4079     FT_FREE( im_start_coords );
4080     FT_FREE( im_end_coords );
4081 
4082     FT_FRAME_EXIT();
4083 
4084   Fail1:
4085     FT_FREE( points_org );
4086     FT_FREE( points_out );




  55 #include "tterrors.h"
  56 
  57 
  58 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  59 
  60 
  61 #define FT_Stream_FTell( stream )                         \
  62           (FT_ULong)( (stream)->cursor - (stream)->base )
  63 #define FT_Stream_SeekSet( stream, off )                               \
  64           (stream)->cursor =                                           \
  65             ( (off) < (FT_ULong)( (stream)->limit - (stream)->base ) ) \
  66                         ? (stream)->base + (off)                       \
  67                         : (stream)->limit
  68 
  69 
  70   /* some macros we need */
  71 #define FT_fdot14ToFixed( x )                  \
  72           ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
  73 #define FT_intToFixed( i )                      \
  74           ( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
  75 #define FT_fdot6ToFixed( i )                    \
  76           ( (FT_Fixed)( (FT_ULong)(i) << 10 ) )
  77 #define FT_fixedToInt( x )                          \
  78           ( (FT_Short)( ( (x) + 0x8000U ) >> 16 ) )
  79 #define FT_fixedToFdot6( x )                    \
  80           ( (FT_Pos)( ( (x) + 0x200 ) >> 10 ) )
  81 
  82 
  83   /**************************************************************************
  84    *
  85    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
  86    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
  87    * messages during execution.
  88    */
  89 #undef  FT_COMPONENT
  90 #define FT_COMPONENT  ttgxvar
  91 
  92 
  93   /*************************************************************************/
  94   /*************************************************************************/
  95   /*****                                                               *****/
  96   /*****                       Internal Routines                       *****/
  97   /*****                                                               *****/
  98   /*************************************************************************/
  99   /*************************************************************************/
 100 


 384     {
 385       FT_TRACE5(( "  axis %d:\n", i ));
 386 
 387       segment->pairCount = FT_GET_USHORT();
 388       if ( (FT_ULong)segment->pairCount * 4 > table_len                ||
 389            FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) )
 390       {
 391         /* Failure.  Free everything we have done so far.  We must do */
 392         /* it right now since loading the `avar' table is optional.   */
 393 
 394         for ( j = i - 1; j >= 0; j-- )
 395           FT_FREE( blend->avar_segment[j].correspondence );
 396 
 397         FT_FREE( blend->avar_segment );
 398         blend->avar_segment = NULL;
 399         goto Exit;
 400       }
 401 
 402       for ( j = 0; j < segment->pairCount; j++ )
 403       {
 404         segment->correspondence[j].fromCoord =
 405           FT_fdot14ToFixed( FT_GET_SHORT() );
 406         segment->correspondence[j].toCoord =
 407           FT_fdot14ToFixed( FT_GET_SHORT() );
 408 
 409         FT_TRACE5(( "    mapping %.5f to %.5f\n",
 410                     segment->correspondence[j].fromCoord / 65536.0,
 411                     segment->correspondence[j].toCoord / 65536.0 ));
 412       }
 413 
 414       FT_TRACE5(( "\n" ));
 415     }
 416 
 417   Exit:
 418     FT_FRAME_EXIT();
 419   }
 420 
 421 
 422   static FT_Error
 423   ft_var_load_item_variation_store( TT_Face          face,
 424                                     FT_ULong         offset,
 425                                     GX_ItemVarStore  itemStore )
 426   {
 427     FT_Stream  stream = FT_FACE_STREAM( face );


1604     FT_FRAME_EXIT();
1605     if ( error )
1606       goto Exit;
1607 
1608     if ( blend->tuplecount != 0 )
1609     {
1610       if ( FT_NEW_ARRAY( blend->tuplecoords,
1611                          gvar_head.axisCount * blend->tuplecount ) )
1612         goto Exit;
1613 
1614       if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord )         ||
1615            FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) )
1616         goto Exit;
1617 
1618       for ( i = 0; i < blend->tuplecount; i++ )
1619       {
1620         FT_TRACE5(( "  [ " ));
1621         for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ )
1622         {
1623           blend->tuplecoords[i * gvar_head.axisCount + j] =
1624             FT_fdot14ToFixed( FT_GET_SHORT() );
1625           FT_TRACE5(( "%.5f ",
1626             blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 ));
1627         }
1628         FT_TRACE5(( "]\n" ));
1629       }
1630 
1631       FT_TRACE5(( "\n" ));
1632 
1633       FT_FRAME_EXIT();
1634     }
1635 
1636   Exit:
1637     return error;
1638   }
1639 
1640 
1641   /**************************************************************************
1642    *
1643    * @Function:
1644    *   ft_var_apply_tuple


3042     FT_MM_Var*  mmvar;
3043 
3044     FT_UInt  num_instances;
3045 
3046 
3047     if ( !face->blend )
3048     {
3049       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
3050         goto Exit;
3051     }
3052 
3053     blend = face->blend;
3054     mmvar = blend->mmvar;
3055 
3056     num_instances = (FT_UInt)face->root.style_flags >> 16;
3057 
3058     /* `instance_index' starts with value 1, thus `>' */
3059     if ( instance_index > num_instances )
3060       goto Exit;
3061 
3062     if ( instance_index > 0 )
3063     {
3064       FT_Memory     memory = face->root.memory;
3065       SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
3066 
3067       FT_Var_Named_Style*  named_style;
3068       FT_String*           style_name;
3069 
3070 
3071       named_style = mmvar->namedstyle + instance_index - 1;
3072 
3073       error = sfnt->get_name( face,
3074                               (FT_UShort)named_style->strid,
3075                               &style_name );
3076       if ( error )
3077         goto Exit;
3078 
3079       /* set (or replace) style name */
3080       FT_FREE( face->root.style_name );
3081       face->root.style_name = style_name;
3082 
3083       /* finally, select the named instance */
3084       error = TT_Set_Var_Design( face,
3085                                  mmvar->num_axis,
3086                                  named_style->coords );
3087       if ( error )
3088       {
3089         /* internal error code -1 means `no change' */
3090         if ( error == -1 )
3091           error = FT_Err_Ok;
3092         goto Exit;
3093       }
3094     }
3095     else
3096       error = TT_Set_Var_Design( face, 0, NULL );
3097 
3098     face->root.face_index  = ( instance_index << 16 )             |
3099                              ( face->root.face_index & 0xFFFFL );
3100     face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
3101 
3102   Exit:
3103     return error;
3104   }
3105 
3106 
3107   /*************************************************************************/
3108   /*************************************************************************/
3109   /*****                                                               *****/
3110   /*****                     GX VAR PARSING ROUTINES                   *****/
3111   /*****                                                               *****/
3112   /*************************************************************************/
3113   /*************************************************************************/
3114 
3115 
3116   static FT_Error
3117   tt_cvt_ready_iterator( FT_ListNode  node,
3118                          void*        user )
3119   {
3120     TT_Size  size = (TT_Size)node->data;
3121 
3122     FT_UNUSED( user );
3123 
3124 
3125     size->cvt_ready = -1;
3126 
3127     return FT_Err_Ok;
3128   }
3129 
3130 
3131   /**************************************************************************
3132    *
3133    * @Function:
3134    *   tt_face_vary_cvt
3135    *
3136    * @Description:
3137    *   Modify the loaded cvt table according to the `cvar' table and the
3138    *   font's blend.
3139    *
3140    * @InOut:
3141    *   face ::
3142    *     A handle to the target face object.
3143    *
3144    * @Input:
3145    *   stream ::
3146    *     A handle to the input stream.
3147    *
3148    * @Return:
3149    *   FreeType error code.  0 means success.
3150    *
3151    *   Most errors are ignored.  It is perfectly valid not to have a
3152    *   `cvar' table even if there is a `gvar' and `fvar' table.
3153    */
3154   FT_LOCAL_DEF( FT_Error )
3155   tt_face_vary_cvt( TT_Face    face,
3156                     FT_Stream  stream )
3157   {
3158     FT_Error   error;
3159     FT_Memory  memory = stream->memory;
3160 
3161     FT_Face  root = &face->root;
3162 
3163     FT_ULong  table_start;
3164     FT_ULong  table_len;
3165 
3166     FT_UInt   tupleCount;
3167     FT_ULong  offsetToData;
3168 
3169     FT_ULong  here;
3170     FT_UInt   i, j;
3171 
3172     FT_Fixed*  tuple_coords    = NULL;
3173     FT_Fixed*  im_start_coords = NULL;
3174     FT_Fixed*  im_end_coords   = NULL;
3175 
3176     GX_Blend  blend = face->blend;
3177 
3178     FT_UInt  point_count;
3179     FT_UInt  spoint_count = 0;
3180 
3181     FT_UShort*  sharedpoints = NULL;
3182     FT_UShort*  localpoints  = NULL;


3271                 ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" ));
3272 
3273     if ( FT_NEW_ARRAY( cvt_deltas, face->cvt_size ) )
3274       goto FExit;
3275 
3276     for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ )
3277     {
3278       FT_UInt   tupleDataSize;
3279       FT_UInt   tupleIndex;
3280       FT_Fixed  apply;
3281 
3282 
3283       FT_TRACE6(( "  tuple %d:\n", i ));
3284 
3285       tupleDataSize = FT_GET_USHORT();
3286       tupleIndex    = FT_GET_USHORT();
3287 
3288       if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
3289       {
3290         for ( j = 0; j < blend->num_axis; j++ )
3291           tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );

3292       }
3293       else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
3294       {
3295         FT_TRACE2(( "tt_face_vary_cvt:"
3296                     " invalid tuple index\n" ));
3297 
3298         error = FT_THROW( Invalid_Table );
3299         goto FExit;
3300       }
3301       else
3302       {
3303         if ( !blend->tuplecoords )
3304         {
3305           FT_TRACE2(( "tt_face_vary_cvt:"
3306                       " no valid tuple coordinates available\n" ));
3307 
3308           error = FT_THROW( Invalid_Table );
3309           goto FExit;
3310         }
3311 
3312         FT_MEM_COPY(
3313           tuple_coords,
3314           blend->tuplecoords +
3315             ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis,
3316           blend->num_axis * sizeof ( FT_Fixed ) );
3317       }
3318 
3319       if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
3320       {
3321         for ( j = 0; j < blend->num_axis; j++ )
3322           im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
3323         for ( j = 0; j < blend->num_axis; j++ )
3324           im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
3325       }
3326 
3327       apply = ft_var_apply_tuple( blend,
3328                                   (FT_UShort)tupleIndex,
3329                                   tuple_coords,
3330                                   im_start_coords,
3331                                   im_end_coords );
3332 
3333       if ( apply == 0 )              /* tuple isn't active for our blend */
3334       {
3335         offsetToData += tupleDataSize;
3336         continue;
3337       }
3338 
3339       here = FT_Stream_FTell( stream );
3340 
3341       FT_Stream_SeekSet( stream, offsetToData );
3342 
3343       if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS )
3344       {


3369         int  count = 0;
3370 #endif
3371 
3372 
3373         FT_TRACE7(( "    CVT deltas:\n" ));
3374 
3375         /* this means that there are deltas for every entry in cvt */
3376         for ( j = 0; j < face->cvt_size; j++ )
3377         {
3378           FT_Fixed  old_cvt_delta;
3379 
3380 
3381           old_cvt_delta = cvt_deltas[j];
3382           cvt_deltas[j] = old_cvt_delta + FT_MulFix( deltas[j], apply );
3383 
3384 #ifdef FT_DEBUG_LEVEL_TRACE
3385           if ( old_cvt_delta != cvt_deltas[j] )
3386           {
3387             FT_TRACE7(( "      %d: %f -> %f\n",
3388                         j,
3389                         ( FT_fdot6ToFixed( face->cvt[j] ) +
3390                           old_cvt_delta ) / 65536.0,
3391                         ( FT_fdot6ToFixed( face->cvt[j] ) +
3392                           cvt_deltas[j] ) / 65536.0 ));
3393             count++;
3394           }
3395 #endif
3396         }
3397 
3398 #ifdef FT_DEBUG_LEVEL_TRACE
3399         if ( !count )
3400           FT_TRACE7(( "      none\n" ));
3401 #endif
3402       }
3403 
3404       else
3405       {
3406 #ifdef FT_DEBUG_LEVEL_TRACE
3407         int  count = 0;
3408 #endif
3409 
3410 
3411         FT_TRACE7(( "    CVT deltas:\n" ));
3412 
3413         for ( j = 0; j < point_count; j++ )
3414         {
3415           int       pindex;
3416           FT_Fixed  old_cvt_delta;
3417 
3418 
3419           pindex = points[j];
3420           if ( (FT_ULong)pindex >= face->cvt_size )
3421             continue;
3422 
3423           old_cvt_delta      = cvt_deltas[pindex];
3424           cvt_deltas[pindex] = old_cvt_delta + FT_MulFix( deltas[j], apply );
3425 
3426 #ifdef FT_DEBUG_LEVEL_TRACE
3427           if ( old_cvt_delta != cvt_deltas[pindex] )
3428           {
3429             FT_TRACE7(( "      %d: %f -> %f\n",
3430                         pindex,
3431                         ( FT_fdot6ToFixed( face->cvt[pindex] ) +
3432                           old_cvt_delta ) / 65536.0,
3433                         ( FT_fdot6ToFixed( face->cvt[pindex] ) +
3434                           cvt_deltas[pindex] ) / 65536.0 ));
3435             count++;
3436           }
3437 #endif
3438         }
3439 
3440 #ifdef FT_DEBUG_LEVEL_TRACE
3441         if ( !count )
3442           FT_TRACE7(( "      none\n" ));
3443 #endif
3444       }
3445 
3446       if ( localpoints != ALL_POINTS )
3447         FT_FREE( localpoints );
3448       FT_FREE( deltas );
3449 
3450       offsetToData += tupleDataSize;
3451 
3452       FT_Stream_SeekSet( stream, here );
3453     }
3454 
3455     FT_TRACE5(( "\n" ));
3456 
3457     for ( i = 0; i < face->cvt_size; i++ )
3458       face->cvt[i] += FT_fixedToFdot6( cvt_deltas[i] );
3459 
3460   FExit:
3461     FT_FRAME_EXIT();
3462 
3463   Exit:
3464     if ( sharedpoints != ALL_POINTS )
3465       FT_FREE( sharedpoints );
3466     FT_FREE( tuple_coords );
3467     FT_FREE( im_start_coords );
3468     FT_FREE( im_end_coords );
3469     FT_FREE( cvt_deltas );
3470 
3471     /* iterate over all FT_Size objects and set `cvt_ready' to -1 */
3472     /* to trigger rescaling of all CVT values                     */
3473     FT_List_Iterate( &root->sizes_list,
3474                      tt_cvt_ready_iterator,
3475                      NULL );
3476 
3477     return error;
3478   }
3479 
3480 
3481   /* Shift the original coordinates of all points between indices `p1' */
3482   /* and `p2', using the same difference as given by index `ref'.      */
3483 
3484   /* modeled after `af_iup_shift' */
3485 
3486   static void
3487   tt_delta_shift( int         p1,
3488                   int         p2,
3489                   int         ref,
3490                   FT_Vector*  in_points,
3491                   FT_Vector*  out_points )
3492   {
3493     int        p;
3494     FT_Vector  delta;
3495 
3496 


3684    *   TT_Vary_Apply_Glyph_Deltas
3685    *
3686    * @Description:
3687    *   Apply the appropriate deltas to the current glyph.
3688    *
3689    * @Input:
3690    *   face ::
3691    *     A handle to the target face object.
3692    *
3693    *   glyph_index ::
3694    *     The index of the glyph being modified.
3695    *
3696    *   n_points ::
3697    *     The number of the points in the glyph, including
3698    *     phantom points.
3699    *
3700    * @InOut:
3701    *   outline ::
3702    *     The outline to change.
3703    *
3704    * @Output:
3705    *   unrounded ::
3706    *     An array with `n_points' elements that is filled with unrounded
3707    *     point coordinates (in 26.6 format).
3708    *
3709    * @Return:
3710    *   FreeType error code.  0 means success.
3711    */
3712   FT_LOCAL_DEF( FT_Error )
3713   TT_Vary_Apply_Glyph_Deltas( TT_Face      face,
3714                               FT_UInt      glyph_index,
3715                               FT_Outline*  outline,
3716                               FT_Vector*   unrounded,
3717                               FT_UInt      n_points )
3718   {
3719     FT_Error   error;
3720     FT_Stream  stream = face->root.stream;
3721     FT_Memory  memory = stream->memory;
3722 
3723     FT_Vector*  points_org = NULL;  /* coordinates in 16.16 format */
3724     FT_Vector*  points_out = NULL;  /* coordinates in 16.16 format */
3725     FT_Bool*    has_delta  = NULL;
3726 
3727     FT_ULong  glyph_start;
3728 
3729     FT_UInt   tupleCount;
3730     FT_ULong  offsetToData;
3731     FT_ULong  dataSize;
3732 
3733     FT_ULong  here;
3734     FT_UInt   i, j;
3735 
3736     FT_Fixed*  tuple_coords    = NULL;


3738     FT_Fixed*  im_end_coords   = NULL;
3739 
3740     GX_Blend  blend = face->blend;
3741 
3742     FT_UInt  point_count;
3743     FT_UInt  spoint_count = 0;
3744 
3745     FT_UShort*  sharedpoints = NULL;
3746     FT_UShort*  localpoints  = NULL;
3747     FT_UShort*  points;
3748 
3749     FT_Fixed*  deltas_x       = NULL;
3750     FT_Fixed*  deltas_y       = NULL;
3751     FT_Fixed*  point_deltas_x = NULL;
3752     FT_Fixed*  point_deltas_y = NULL;
3753 
3754 
3755     if ( !face->doblend || !blend )
3756       return FT_THROW( Invalid_Argument );
3757 
3758     for ( i = 0; i < n_points; i++ )
3759     {
3760       unrounded[i].x = INT_TO_F26DOT6( outline->points[i].x );
3761       unrounded[i].y = INT_TO_F26DOT6( outline->points[i].y );
3762     }
3763 
3764     if ( glyph_index >= blend->gv_glyphcnt      ||
3765          blend->glyphoffsets[glyph_index] ==
3766            blend->glyphoffsets[glyph_index + 1] )
3767     {
3768       FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
3769                   " no variation data for this glyph\n" ));
3770       return FT_Err_Ok;
3771     }
3772 
3773     if ( FT_NEW_ARRAY( points_org, n_points ) ||
3774          FT_NEW_ARRAY( points_out, n_points ) ||
3775          FT_NEW_ARRAY( has_delta, n_points )  )
3776       goto Fail1;
3777 
3778     dataSize = blend->glyphoffsets[glyph_index + 1] -
3779                  blend->glyphoffsets[glyph_index];
3780 
3781     if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) ||
3782          FT_FRAME_ENTER( dataSize )                         )
3783       goto Fail1;


3834     {
3835       points_org[j].x = FT_intToFixed( outline->points[j].x );
3836       points_org[j].y = FT_intToFixed( outline->points[j].y );
3837     }
3838 
3839     for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ )
3840     {
3841       FT_UInt   tupleDataSize;
3842       FT_UInt   tupleIndex;
3843       FT_Fixed  apply;
3844 
3845 
3846       FT_TRACE6(( "  tuple %d:\n", i ));
3847 
3848       tupleDataSize = FT_GET_USHORT();
3849       tupleIndex    = FT_GET_USHORT();
3850 
3851       if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
3852       {
3853         for ( j = 0; j < blend->num_axis; j++ )
3854           tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );

3855       }
3856       else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
3857       {
3858         FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
3859                     " invalid tuple index\n" ));
3860 
3861         error = FT_THROW( Invalid_Table );
3862         goto Fail3;
3863       }
3864       else
3865         FT_MEM_COPY(
3866           tuple_coords,
3867           blend->tuplecoords +
3868             ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis,
3869           blend->num_axis * sizeof ( FT_Fixed ) );
3870 
3871       if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
3872       {
3873         for ( j = 0; j < blend->num_axis; j++ )
3874           im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
3875         for ( j = 0; j < blend->num_axis; j++ )
3876           im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
3877       }
3878 
3879       apply = ft_var_apply_tuple( blend,
3880                                   (FT_UShort)tupleIndex,
3881                                   tuple_coords,
3882                                   im_start_coords,
3883                                   im_end_coords );
3884 
3885       if ( apply == 0 )              /* tuple isn't active for our blend */
3886       {
3887         offsetToData += tupleDataSize;
3888         continue;
3889       }
3890 
3891       here = FT_Stream_FTell( stream );
3892 
3893       FT_Stream_SeekSet( stream, offsetToData );
3894 
3895       if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS )
3896       {


4090 #ifdef FT_DEBUG_LEVEL_TRACE
4091         if ( !count )
4092           FT_TRACE7(( "      none\n" ));
4093 #endif
4094       }
4095 
4096       if ( localpoints != ALL_POINTS )
4097         FT_FREE( localpoints );
4098       FT_FREE( deltas_x );
4099       FT_FREE( deltas_y );
4100 
4101       offsetToData += tupleDataSize;
4102 
4103       FT_Stream_SeekSet( stream, here );
4104     }
4105 
4106     FT_TRACE5(( "\n" ));
4107 
4108     for ( i = 0; i < n_points; i++ )
4109     {
4110       unrounded[i].x += FT_fixedToFdot6( point_deltas_x[i] );
4111       unrounded[i].y += FT_fixedToFdot6( point_deltas_y[i] );
4112 
4113       outline->points[i].x += FT_fixedToInt( point_deltas_x[i] );
4114       outline->points[i].y += FT_fixedToInt( point_deltas_y[i] );
4115     }
4116 
4117   Fail3:
4118     FT_FREE( point_deltas_x );
4119     FT_FREE( point_deltas_y );
4120 
4121   Fail2:
4122     if ( sharedpoints != ALL_POINTS )
4123       FT_FREE( sharedpoints );
4124     FT_FREE( tuple_coords );
4125     FT_FREE( im_start_coords );
4126     FT_FREE( im_end_coords );
4127 
4128     FT_FRAME_EXIT();
4129 
4130   Fail1:
4131     FT_FREE( points_org );
4132     FT_FREE( points_out );


< prev index next >