< prev index next >

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

Print this page


   1 /****************************************************************************
   2  *
   3  * ttgxvar.c
   4  *
   5  *   TrueType GX Font Variation loader
   6  *
   7  * Copyright (C) 2004-2019 by
   8  * David Turner, Robert Wilhelm, Werner Lemberg, and George Williams.
   9  *
  10  * This file is part of the FreeType project, and may only be used,
  11  * modified, and distributed under the terms of the FreeType project
  12  * license, LICENSE.TXT.  By continuing to use, modify, or distribute
  13  * this file you indicate that you have read the license and
  14  * understand and accept it fully.
  15  *
  16  */
  17 
  18 
  19   /**************************************************************************
  20    *
  21    * Apple documents the `fvar', `gvar', `cvar', and `avar' tables at
  22    *
  23    *   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html
  24    *
  25    * The documentation for `gvar' is not intelligible; `cvar' refers you
  26    * to `gvar' and is thus also incomprehensible.
  27    *


1453    *   better be there too.
1454    *
1455    * @InOut:
1456    *   face ::
1457    *     The font face.
1458    *
1459    * @Return:
1460    *   FreeType error code.  0 means success.
1461    */
1462   static FT_Error
1463   ft_var_load_gvar( TT_Face  face )
1464   {
1465     FT_Stream     stream = FT_FACE_STREAM( face );
1466     FT_Memory     memory = stream->memory;
1467     GX_Blend      blend  = face->blend;
1468     FT_Error      error;
1469     FT_UInt       i, j;
1470     FT_ULong      table_len;
1471     FT_ULong      gvar_start;
1472     FT_ULong      offsetToData;

1473     GX_GVar_Head  gvar_head;
1474 
1475     static const FT_Frame_Field  gvar_fields[] =
1476     {
1477 
1478 #undef  FT_STRUCTURE
1479 #define FT_STRUCTURE  GX_GVar_Head
1480 
1481       FT_FRAME_START( 20 ),
1482         FT_FRAME_LONG  ( version ),
1483         FT_FRAME_USHORT( axisCount ),
1484         FT_FRAME_USHORT( globalCoordCount ),
1485         FT_FRAME_ULONG ( offsetToCoord ),
1486         FT_FRAME_USHORT( glyphCount ),
1487         FT_FRAME_USHORT( flags ),
1488         FT_FRAME_ULONG ( offsetToData ),
1489       FT_FRAME_END
1490     };
1491 
1492 


1513     }
1514 
1515     if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
1516     {
1517       FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n"
1518                   "                  table are different\n" ));
1519       error = FT_THROW( Invalid_Table );
1520       goto Exit;
1521     }
1522 
1523     /* rough sanity check, ignoring offsets */
1524     if ( (FT_ULong)gvar_head.globalCoordCount * gvar_head.axisCount >
1525            table_len / 2 )
1526     {
1527       FT_TRACE1(( "ft_var_load_gvar:"
1528                   " invalid number of global coordinates\n" ));
1529       error = FT_THROW( Invalid_Table );
1530       goto Exit;
1531     }
1532 
1533     /* rough sanity check: offsets can be either 2 or 4 bytes */
1534     if ( (FT_ULong)gvar_head.glyphCount *
1535            ( ( gvar_head.flags & 1 ) ? 4 : 2 ) > table_len )




1536     {
1537       FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" ));
1538       error = FT_THROW( Invalid_Table );
1539       goto Exit;
1540     }
1541 
1542     FT_TRACE2(( "loaded\n" ));
1543 
1544     blend->gvar_size   = table_len;
1545     blend->tuplecount  = gvar_head.globalCoordCount;
1546     blend->gv_glyphcnt = gvar_head.glyphCount;
1547     offsetToData       = gvar_start + gvar_head.offsetToData;
1548 
1549     FT_TRACE5(( "gvar: there %s %d shared coordinate%s:\n",
1550                 blend->tuplecount == 1 ? "is" : "are",
1551                 blend->tuplecount,
1552                 blend->tuplecount == 1 ? "" : "s" ));
1553 
1554     if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) )
1555       goto Exit;
1556 




1557     if ( gvar_head.flags & 1 )
1558     {
1559       FT_ULong  limit = gvar_start + table_len;

1560 
1561 
1562       /* long offsets (one more offset than glyphs, to mark size of last) */
1563       if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) )
1564         goto Exit;
1565 
1566       for ( i = 0; i <= blend->gv_glyphcnt; i++ )
1567       {
1568         blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG();
1569         /* use `>', not `>=' */
1570         if ( blend->glyphoffsets[i] > limit )


1571         {
1572           FT_TRACE2(( "ft_var_load_gvar:"
1573                       " invalid glyph variation data offset for index %d\n",
1574                       i ));
1575           error = FT_THROW( Invalid_Table );
1576           break;








1577         }
1578       }
1579     }
1580     else
1581     {
1582       FT_ULong  limit = gvar_start + table_len;

1583 
1584 
1585       /* short offsets (one more offset than glyphs, to mark size of last) */
1586       if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) )
1587         goto Exit;
1588 
1589       for ( i = 0; i <= blend->gv_glyphcnt; i++ )
1590       {
1591         blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2;
1592         /* use `>', not `>=' */
1593         if ( blend->glyphoffsets[i] > limit )


1594         {
1595           FT_TRACE2(( "ft_var_load_gvar:"
1596                       " invalid glyph variation data offset for index %d\n",
1597                       i ));
1598           error = FT_THROW( Invalid_Table );
1599           break;








1600         }
1601       }
1602     }
1603 


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
1645    *
1646    * @Description:
1647    *   Figure out whether a given tuple (design) applies to the current
1648    *   blend, and if so, what is the scaling factor.
1649    *
1650    * @Input:
1651    *   blend ::
1652    *     The current blend of the font.
1653    *
1654    *   tupleIndex ::
1655    *     A flag saying whether this is an intermediate
1656    *     tuple or not.
1657    *


2110 
2111       if ( FT_NEW( face->blend ) )
2112         goto Exit;
2113 
2114       num_axes              = fvar_head.axisCount;
2115       face->blend->num_axis = num_axes;
2116     }
2117     else
2118       num_axes = face->blend->num_axis;
2119 
2120     /* `num_instances' holds the number of all named instances, */
2121     /* including the default instance which might be missing    */
2122     /* in fvar's table of named instances                       */
2123     num_instances = (FT_UInt)face->root.style_flags >> 16;
2124 
2125     /* prepare storage area for MM data; this cannot overflow   */
2126     /* 32-bit arithmetic because of the size limits used in the */
2127     /* `fvar' table validity check in `sfnt_init_face'          */
2128 
2129     /* the various `*_size' variables, which we also use as     */
2130     /* offsets into the `mmlen' array, must be multiples of the */
2131     /* pointer size (except the last one); without such an      */
2132     /* alignment there might be runtime errors due to           */
2133     /* misaligned addresses                                     */
2134 #undef  ALIGN_SIZE
2135 #define ALIGN_SIZE( n ) \
2136           ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) )
2137 
2138     mmvar_size       = ALIGN_SIZE( sizeof ( FT_MM_Var ) );
2139     axis_flags_size  = ALIGN_SIZE( num_axes *
2140                                    sizeof ( FT_UShort ) );
2141     axis_size        = ALIGN_SIZE( num_axes *
2142                                    sizeof ( FT_Var_Axis ) );
2143     namedstyle_size  = ALIGN_SIZE( num_instances *
2144                                    sizeof ( FT_Var_Named_Style ) );
2145     next_coords_size = ALIGN_SIZE( num_instances *
2146                                    num_axes *
2147                                    sizeof ( FT_Fixed ) );
2148     next_name_size   = num_axes * 5;
2149 
2150     if ( need_init )


3020    *
3021    * @Description:
3022    *   Set the given named instance, also resetting any further
3023    *   variation.
3024    *
3025    * @Input:
3026    *   face ::
3027    *     A handle to the source face.
3028    *
3029    *   instance_index ::
3030    *     The instance index, starting with value 1.
3031    *     Value 0 indicates to not use an instance.
3032    *
3033    * @Return:
3034    *   FreeType error code.  0~means success.
3035    */
3036   FT_LOCAL_DEF( FT_Error )
3037   TT_Set_Named_Instance( TT_Face  face,
3038                          FT_UInt  instance_index )
3039   {
3040     FT_Error    error = FT_ERR( Invalid_Argument );
3041     GX_Blend    blend;
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 );


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;
3784 
3785     glyph_start = FT_Stream_FTell( stream );
3786 
3787     /* each set of glyph variation data is formatted similarly to `cvar' */
3788 
3789     if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis )    ||


   1 /****************************************************************************
   2  *
   3  * ttgxvar.c
   4  *
   5  *   TrueType GX Font Variation loader
   6  *
   7  * Copyright (C) 2004-2020 by
   8  * David Turner, Robert Wilhelm, Werner Lemberg, and George Williams.
   9  *
  10  * This file is part of the FreeType project, and may only be used,
  11  * modified, and distributed under the terms of the FreeType project
  12  * license, LICENSE.TXT.  By continuing to use, modify, or distribute
  13  * this file you indicate that you have read the license and
  14  * understand and accept it fully.
  15  *
  16  */
  17 
  18 
  19   /**************************************************************************
  20    *
  21    * Apple documents the `fvar', `gvar', `cvar', and `avar' tables at
  22    *
  23    *   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html
  24    *
  25    * The documentation for `gvar' is not intelligible; `cvar' refers you
  26    * to `gvar' and is thus also incomprehensible.
  27    *


1453    *   better be there too.
1454    *
1455    * @InOut:
1456    *   face ::
1457    *     The font face.
1458    *
1459    * @Return:
1460    *   FreeType error code.  0 means success.
1461    */
1462   static FT_Error
1463   ft_var_load_gvar( TT_Face  face )
1464   {
1465     FT_Stream     stream = FT_FACE_STREAM( face );
1466     FT_Memory     memory = stream->memory;
1467     GX_Blend      blend  = face->blend;
1468     FT_Error      error;
1469     FT_UInt       i, j;
1470     FT_ULong      table_len;
1471     FT_ULong      gvar_start;
1472     FT_ULong      offsetToData;
1473     FT_ULong      offsets_len;
1474     GX_GVar_Head  gvar_head;
1475 
1476     static const FT_Frame_Field  gvar_fields[] =
1477     {
1478 
1479 #undef  FT_STRUCTURE
1480 #define FT_STRUCTURE  GX_GVar_Head
1481 
1482       FT_FRAME_START( 20 ),
1483         FT_FRAME_LONG  ( version ),
1484         FT_FRAME_USHORT( axisCount ),
1485         FT_FRAME_USHORT( globalCoordCount ),
1486         FT_FRAME_ULONG ( offsetToCoord ),
1487         FT_FRAME_USHORT( glyphCount ),
1488         FT_FRAME_USHORT( flags ),
1489         FT_FRAME_ULONG ( offsetToData ),
1490       FT_FRAME_END
1491     };
1492 
1493 


1514     }
1515 
1516     if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
1517     {
1518       FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n"
1519                   "                  table are different\n" ));
1520       error = FT_THROW( Invalid_Table );
1521       goto Exit;
1522     }
1523 
1524     /* rough sanity check, ignoring offsets */
1525     if ( (FT_ULong)gvar_head.globalCoordCount * gvar_head.axisCount >
1526            table_len / 2 )
1527     {
1528       FT_TRACE1(( "ft_var_load_gvar:"
1529                   " invalid number of global coordinates\n" ));
1530       error = FT_THROW( Invalid_Table );
1531       goto Exit;
1532     }
1533 
1534     /* offsets can be either 2 or 4 bytes                  */
1535     /* (one more offset than glyphs, to mark size of last) */
1536     offsets_len = ( gvar_head.glyphCount + 1 ) *
1537                   ( ( gvar_head.flags & 1 ) ? 4L : 2L );
1538 
1539     /* rough sanity check */
1540     if (offsets_len > table_len )
1541     {
1542       FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" ));
1543       error = FT_THROW( Invalid_Table );
1544       goto Exit;
1545     }
1546 
1547     FT_TRACE2(( "loaded\n" ));
1548 
1549     blend->gvar_size = table_len;


1550     offsetToData     = gvar_start + gvar_head.offsetToData;
1551 
1552     FT_TRACE5(( "gvar: there %s %d shared coordinate%s:\n",
1553                 gvar_head.globalCoordCount == 1 ? "is" : "are",
1554                 gvar_head.globalCoordCount,
1555                 gvar_head.globalCoordCount == 1 ? "" : "s" ));
1556 
1557     if ( FT_FRAME_ENTER( offsets_len ) )
1558       goto Exit;
1559 
1560     /* offsets (one more offset than glyphs, to mark size of last) */
1561     if ( FT_NEW_ARRAY( blend->glyphoffsets, gvar_head.glyphCount + 1 ) )
1562       goto Fail2;
1563 
1564     if ( gvar_head.flags & 1 )
1565     {
1566       FT_ULong  limit      = gvar_start + table_len;
1567       FT_ULong  max_offset = 0;
1568 
1569 
1570       for ( i = 0; i <= gvar_head.glyphCount; i++ )




1571       {
1572         blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG();
1573 
1574         if ( max_offset <= blend->glyphoffsets[i] )
1575           max_offset = blend->glyphoffsets[i];
1576         else
1577         {
1578           FT_TRACE2(( "ft_var_load_gvar:"
1579                       " glyph variation data offset %d not monotonic\n",
1580                       i ));
1581           blend->glyphoffsets[i] = max_offset;
1582         }
1583 
1584         /* use `<', not `<=' */
1585         if ( limit < blend->glyphoffsets[i] )
1586         {
1587           FT_TRACE2(( "ft_var_load_gvar:"
1588                       " glyph variation data offset %d out of range\n",
1589                       i ));
1590           blend->glyphoffsets[i] = limit;
1591         }
1592       }
1593     }
1594     else
1595     {
1596       FT_ULong  limit      = gvar_start + table_len;
1597       FT_ULong  max_offset = 0;
1598 
1599 
1600       for ( i = 0; i <= gvar_head.glyphCount; i++ )




1601       {
1602         blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2;
1603 
1604         if ( max_offset <= blend->glyphoffsets[i] )
1605           max_offset = blend->glyphoffsets[i];
1606         else
1607         {
1608           FT_TRACE2(( "ft_var_load_gvar:"
1609                       " glyph variation data offset %d not monotonic\n",
1610                       i ));
1611           blend->glyphoffsets[i] = max_offset;
1612         }
1613 
1614         /* use `<', not `<=' */
1615         if ( limit < blend->glyphoffsets[i] )
1616         {
1617           FT_TRACE2(( "ft_var_load_gvar:"
1618                       " glyph variation data offset %d out of range\n",
1619                       i ));
1620           blend->glyphoffsets[i] = limit;
1621         }
1622       }
1623     }
1624 
1625     blend->gv_glyphcnt = gvar_head.glyphCount;
1626 
1627     FT_FRAME_EXIT();


1628 
1629     if ( gvar_head.globalCoordCount != 0 )
1630     {




1631       if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) ||
1632            FT_FRAME_ENTER( gvar_head.globalCoordCount *
1633                            gvar_head.axisCount * 2L )             )
1634       {
1635         FT_TRACE2(( "ft_var_load_gvar:"
1636                     " glyph variation shared tuples missing\n" ));
1637         goto Fail;
1638       }
1639 
1640       if ( FT_NEW_ARRAY( blend->tuplecoords,
1641                          gvar_head.axisCount * gvar_head.globalCoordCount ) )
1642         goto Fail2;
1643 
1644       for ( i = 0; i < gvar_head.globalCoordCount; i++ )
1645       {
1646         FT_TRACE5(( "  [ " ));
1647         for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ )
1648         {
1649           blend->tuplecoords[i * gvar_head.axisCount + j] =
1650             FT_fdot14ToFixed( FT_GET_SHORT() );
1651           FT_TRACE5(( "%.5f ",
1652             blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 ));
1653         }
1654         FT_TRACE5(( "]\n" ));
1655       }
1656 
1657       blend->tuplecount = gvar_head.globalCoordCount;
1658 
1659       FT_TRACE5(( "\n" ));
1660 
1661       FT_FRAME_EXIT();
1662     }
1663 
1664   Exit:
1665     return error;
1666 
1667   Fail2:
1668     FT_FRAME_EXIT();
1669 
1670   Fail:
1671     FT_FREE( blend->glyphoffsets );
1672     blend->gv_glyphcnt = 0;
1673     goto Exit;
1674   }
1675 
1676 
1677   /**************************************************************************
1678    *
1679    * @Function:
1680    *   ft_var_apply_tuple
1681    *
1682    * @Description:
1683    *   Figure out whether a given tuple (design) applies to the current
1684    *   blend, and if so, what is the scaling factor.
1685    *
1686    * @Input:
1687    *   blend ::
1688    *     The current blend of the font.
1689    *
1690    *   tupleIndex ::
1691    *     A flag saying whether this is an intermediate
1692    *     tuple or not.
1693    *


2146 
2147       if ( FT_NEW( face->blend ) )
2148         goto Exit;
2149 
2150       num_axes              = fvar_head.axisCount;
2151       face->blend->num_axis = num_axes;
2152     }
2153     else
2154       num_axes = face->blend->num_axis;
2155 
2156     /* `num_instances' holds the number of all named instances, */
2157     /* including the default instance which might be missing    */
2158     /* in fvar's table of named instances                       */
2159     num_instances = (FT_UInt)face->root.style_flags >> 16;
2160 
2161     /* prepare storage area for MM data; this cannot overflow   */
2162     /* 32-bit arithmetic because of the size limits used in the */
2163     /* `fvar' table validity check in `sfnt_init_face'          */
2164 
2165     /* the various `*_size' variables, which we also use as     */
2166     /* offsets into the `mmvar' array, must be multiples of the */
2167     /* pointer size (except the last one); without such an      */
2168     /* alignment there might be runtime errors due to           */
2169     /* misaligned addresses                                     */
2170 #undef  ALIGN_SIZE
2171 #define ALIGN_SIZE( n ) \
2172           ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) )
2173 
2174     mmvar_size       = ALIGN_SIZE( sizeof ( FT_MM_Var ) );
2175     axis_flags_size  = ALIGN_SIZE( num_axes *
2176                                    sizeof ( FT_UShort ) );
2177     axis_size        = ALIGN_SIZE( num_axes *
2178                                    sizeof ( FT_Var_Axis ) );
2179     namedstyle_size  = ALIGN_SIZE( num_instances *
2180                                    sizeof ( FT_Var_Named_Style ) );
2181     next_coords_size = ALIGN_SIZE( num_instances *
2182                                    num_axes *
2183                                    sizeof ( FT_Fixed ) );
2184     next_name_size   = num_axes * 5;
2185 
2186     if ( need_init )


3056    *
3057    * @Description:
3058    *   Set the given named instance, also resetting any further
3059    *   variation.
3060    *
3061    * @Input:
3062    *   face ::
3063    *     A handle to the source face.
3064    *
3065    *   instance_index ::
3066    *     The instance index, starting with value 1.
3067    *     Value 0 indicates to not use an instance.
3068    *
3069    * @Return:
3070    *   FreeType error code.  0~means success.
3071    */
3072   FT_LOCAL_DEF( FT_Error )
3073   TT_Set_Named_Instance( TT_Face  face,
3074                          FT_UInt  instance_index )
3075   {
3076     FT_Error    error;
3077     GX_Blend    blend;
3078     FT_MM_Var*  mmvar;
3079 
3080     FT_UInt  num_instances;
3081 
3082 
3083     if ( !face->blend )
3084     {
3085       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
3086         goto Exit;
3087     }
3088 
3089     blend = face->blend;
3090     mmvar = blend->mmvar;
3091 
3092     num_instances = (FT_UInt)face->root.style_flags >> 16;
3093 
3094     /* `instance_index' starts with value 1, thus `>' */
3095     if ( instance_index > num_instances )
3096     {
3097       error = FT_ERR( Invalid_Argument );
3098       goto Exit;
3099     }
3100 
3101     if ( instance_index > 0 )
3102     {
3103       FT_Memory     memory = face->root.memory;
3104       SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
3105 
3106       FT_Var_Named_Style*  named_style;
3107       FT_String*           style_name;
3108 
3109 
3110       named_style = mmvar->namedstyle + instance_index - 1;
3111 
3112       error = sfnt->get_name( face,
3113                               (FT_UShort)named_style->strid,
3114                               &style_name );
3115       if ( error )
3116         goto Exit;
3117 
3118       /* set (or replace) style name */
3119       FT_FREE( face->root.style_name );


3788     FT_Fixed*  deltas_x       = NULL;
3789     FT_Fixed*  deltas_y       = NULL;
3790     FT_Fixed*  point_deltas_x = NULL;
3791     FT_Fixed*  point_deltas_y = NULL;
3792 
3793 
3794     if ( !face->doblend || !blend )
3795       return FT_THROW( Invalid_Argument );
3796 
3797     for ( i = 0; i < n_points; i++ )
3798     {
3799       unrounded[i].x = INT_TO_F26DOT6( outline->points[i].x );
3800       unrounded[i].y = INT_TO_F26DOT6( outline->points[i].y );
3801     }
3802 
3803     if ( glyph_index >= blend->gv_glyphcnt      ||
3804          blend->glyphoffsets[glyph_index] ==
3805            blend->glyphoffsets[glyph_index + 1] )
3806     {
3807       FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
3808                   " no variation data for glyph %d\n", glyph_index ));
3809       return FT_Err_Ok;
3810     }
3811 
3812     if ( FT_NEW_ARRAY( points_org, n_points ) ||
3813          FT_NEW_ARRAY( points_out, n_points ) ||
3814          FT_NEW_ARRAY( has_delta, n_points )  )
3815       goto Fail1;
3816 
3817     dataSize = blend->glyphoffsets[glyph_index + 1] -
3818                  blend->glyphoffsets[glyph_index];
3819 
3820     if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) ||
3821          FT_FRAME_ENTER( dataSize )                         )
3822       goto Fail1;
3823 
3824     glyph_start = FT_Stream_FTell( stream );
3825 
3826     /* each set of glyph variation data is formatted similarly to `cvar' */
3827 
3828     if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis )    ||


< prev index next >