< prev index next >

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

Print this page




  65 
  66   /**************************************************************************
  67    *
  68    * Composite glyph flags.
  69    */
  70 #define ARGS_ARE_WORDS             0x0001
  71 #define ARGS_ARE_XY_VALUES         0x0002
  72 #define ROUND_XY_TO_GRID           0x0004
  73 #define WE_HAVE_A_SCALE            0x0008
  74 /* reserved                        0x0010 */
  75 #define MORE_COMPONENTS            0x0020
  76 #define WE_HAVE_AN_XY_SCALE        0x0040
  77 #define WE_HAVE_A_2X2              0x0080
  78 #define WE_HAVE_INSTR              0x0100
  79 #define USE_MY_METRICS             0x0200
  80 #define OVERLAP_COMPOUND           0x0400  /* we ignore this value */
  81 #define SCALED_COMPONENT_OFFSET    0x0800
  82 #define UNSCALED_COMPONENT_OFFSET  0x1000
  83 
  84 









  85   /**************************************************************************
  86    *
  87    * Return the horizontal metrics in font units for a given glyph.
  88    */
  89   FT_LOCAL_DEF( void )
  90   TT_Get_HMetrics( TT_Face     face,
  91                    FT_UInt     idx,
  92                    FT_Short*   lsb,
  93                    FT_UShort*  aw )
  94   {
  95     ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );
  96 
  97     FT_TRACE5(( "  advance width (font units): %d\n", *aw ));
  98     FT_TRACE5(( "  left side bearing (font units): %d\n", *lsb ));
  99   }
 100 
 101 
 102   /**************************************************************************
 103    *
 104    * Return the vertical metrics in font units for a given glyph.


 910 
 911 
 912   /**************************************************************************
 913    *
 914    * @Function:
 915    *   TT_Process_Simple_Glyph
 916    *
 917    * @Description:
 918    *   Once a simple glyph has been loaded, it needs to be processed.
 919    *   Usually, this means scaling and hinting through bytecode
 920    *   interpretation.
 921    */
 922   static FT_Error
 923   TT_Process_Simple_Glyph( TT_Loader  loader )
 924   {
 925     FT_GlyphLoader  gloader = loader->gloader;
 926     FT_Error        error   = FT_Err_Ok;
 927     FT_Outline*     outline;
 928     FT_Int          n_points;
 929 





 930 
 931     outline  = &gloader->current.outline;
 932     n_points = outline->n_points;
 933 
 934     /* set phantom points */
 935 
 936     outline->points[n_points    ] = loader->pp1;
 937     outline->points[n_points + 1] = loader->pp2;
 938     outline->points[n_points + 2] = loader->pp3;
 939     outline->points[n_points + 3] = loader->pp4;
 940 
 941     outline->tags[n_points    ] = 0;
 942     outline->tags[n_points + 1] = 0;
 943     outline->tags[n_points + 2] = 0;
 944     outline->tags[n_points + 3] = 0;
 945 
 946     n_points += 4;
 947 
 948 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 949 
 950     if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) ||
 951          FT_IS_VARIATION( FT_FACE( loader->face ) )      )
 952     {



 953       /* Deltas apply to the unscaled data. */
 954       error = TT_Vary_Apply_Glyph_Deltas( loader->face,
 955                                           loader->glyph_index,
 956                                           outline,

 957                                           (FT_UInt)n_points );
 958 
 959       /* recalculate linear horizontal and vertical advances */
 960       /* if we don't have HVAR and VVAR, respectively        */



 961       if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
 962         loader->linear = outline->points[n_points - 3].x -
 963                          outline->points[n_points - 4].x;
 964       if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
 965         loader->vadvance = outline->points[n_points - 1].x -
 966                            outline->points[n_points - 2].x;
 967 
 968       if ( error )
 969         return error;
 970     }
 971 
 972 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 973 
 974     if ( IS_HINTED( loader->load_flags ) )
 975     {
 976       tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
 977 
 978       FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
 979                      loader->zone.n_points + 4 );
 980     }
 981 
 982     {
 983 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 984       TT_Face    face   = loader->face;
 985       TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
 986 
 987       FT_String*  family         = face->root.family_name;
 988       FT_UInt     ppem           = loader->size->metrics->x_ppem;
 989       FT_String*  style          = face->root.style_name;


1004       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
1005       {
1006         /* scale, but only if enabled and only if TT hinting is being used */
1007         if ( IS_HINTED( loader->load_flags ) )
1008           x_scale_factor = sph_test_tweak_x_scaling( face,
1009                                                      family,
1010                                                      ppem,
1011                                                      style,
1012                                                      loader->glyph_index );
1013         /* scale the glyph */
1014         if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
1015              x_scale_factor != 1000                         )
1016         {
1017           x_scale = FT_MulDiv( loader->size->metrics->x_scale,
1018                                (FT_Long)x_scale_factor, 1000 );
1019           y_scale = loader->size->metrics->y_scale;
1020 
1021           /* compensate for any scaling by de/emboldening; */
1022           /* the amount was determined via experimentation */
1023           if ( x_scale_factor != 1000 && ppem > 11 )








1024             FT_Outline_EmboldenXY( outline,
1025                                    FT_MulFix( 1280 * ppem,
1026                                               1000 - x_scale_factor ),
1027                                    0 );





1028           do_scale = TRUE;
1029         }
1030       }
1031       else
1032 
1033 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
1034 
1035       {
1036         /* scale the glyph */
1037         if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1038         {
1039           x_scale = loader->size->metrics->x_scale;
1040           y_scale = loader->size->metrics->y_scale;
1041 
1042           do_scale = TRUE;
1043         }
1044       }
1045 
1046       if ( do_scale )
1047       {















1048         for ( ; vec < limit; vec++ )
1049         {
1050           vec->x = FT_MulFix( vec->x, x_scale );
1051           vec->y = FT_MulFix( vec->y, y_scale );
1052         }
1053       }

1054 
1055 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1056       /* if we have a HVAR table, `pp1' and/or `pp2' are already adjusted */
1057       if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ||
1058            !IS_HINTED( loader->load_flags )                                 )
1059 #endif
1060       {
1061         loader->pp1 = outline->points[n_points - 4];
1062         loader->pp2 = outline->points[n_points - 3];
1063       }
1064 
1065 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1066       /* if we have a VVAR table, `pp3' and/or `pp4' are already adjusted */
1067       if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ||
1068            !IS_HINTED( loader->load_flags )                                 )
1069 #endif
1070       {
1071         loader->pp3 = outline->points[n_points - 2];
1072         loader->pp4 = outline->points[n_points - 1];
1073       }
1074     }
1075 
1076     if ( IS_HINTED( loader->load_flags ) )
1077     {
1078       loader->zone.n_points += 4;
1079 
1080       error = TT_Hint_Glyph( loader, 0 );
1081     }
1082 





1083     return error;
1084   }
1085 
1086 
1087   /**************************************************************************
1088    *
1089    * @Function:
1090    *   TT_Process_Composite_Component
1091    *
1092    * @Description:
1093    *   Once a composite component has been loaded, it needs to be
1094    *   processed.  Usually, this means transforming and translating.
1095    */
1096   static FT_Error
1097   TT_Process_Composite_Component( TT_Loader    loader,
1098                                   FT_SubGlyph  subglyph,
1099                                   FT_UInt      start_point,
1100                                   FT_UInt      num_base_points )
1101   {
1102     FT_GlyphLoader  gloader = loader->gloader;


1664       /* must initialize points before (possibly) overriding */
1665       /* glyph metrics from the incremental interface        */
1666       tt_loader_set_pp( loader );
1667 
1668 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1669       tt_get_metrics_incr_overrides( loader, glyph_index );
1670 #endif
1671 
1672 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1673 
1674       if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1675            FT_IS_VARIATION( FT_FACE( face ) )      )
1676       {
1677         /* a small outline structure with four elements for */
1678         /* communication with `TT_Vary_Apply_Glyph_Deltas'  */
1679         FT_Vector   points[4];
1680         char        tags[4]     = { 1, 1, 1, 1 };
1681         short       contours[4] = { 0, 1, 2, 3 };
1682         FT_Outline  outline;
1683 



1684 
1685         points[0].x = loader->pp1.x;
1686         points[0].y = loader->pp1.y;
1687         points[1].x = loader->pp2.x;
1688         points[1].y = loader->pp2.y;
1689 
1690         points[2].x = loader->pp3.x;
1691         points[2].y = loader->pp3.y;
1692         points[3].x = loader->pp4.x;
1693         points[3].y = loader->pp4.y;
1694 
1695         outline.n_points   = 4;
1696         outline.n_contours = 4;
1697         outline.points     = points;
1698         outline.tags       = tags;
1699         outline.contours   = contours;
1700 
1701         /* this must be done before scaling */
1702         error = TT_Vary_Apply_Glyph_Deltas( loader->face,
1703                                             glyph_index,
1704                                             &outline,

1705                                             (FT_UInt)outline.n_points );
1706         if ( error )
1707           goto Exit;
1708 
1709         loader->pp1.x = points[0].x;
1710         loader->pp1.y = points[0].y;
1711         loader->pp2.x = points[1].x;
1712         loader->pp2.y = points[1].y;
1713 
1714         loader->pp3.x = points[2].x;
1715         loader->pp3.y = points[2].y;
1716         loader->pp4.x = points[3].x;
1717         loader->pp4.y = points[3].y;
1718 
1719         /* recalculate linear horizontal and vertical advances */
1720         /* if we don't have HVAR and VVAR, respectively        */
1721         if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
1722           loader->linear = loader->pp2.x - loader->pp1.x;

1723         if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
1724           loader->vadvance = loader->pp4.x - loader->pp3.x;

1725       }
1726 
1727 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1728 
1729       /* scale phantom points, if necessary; */
1730       /* they get rounded in `TT_Hint_Glyph' */
1731       if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1732       {
1733         loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1734         loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1735         /* pp1.y and pp2.y are always zero */
1736 
1737         loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1738         loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1739         loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1740         loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1741       }
1742 
1743       error = FT_Err_Ok;
1744       goto Exit;


1847 
1848       /* store the offset of instructions */
1849       ins_pos = loader->ins_pos;
1850 
1851       /* all data we need are read */
1852       face->forget_glyph_frame( loader );
1853       opened_frame = 0;
1854 
1855 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1856 
1857       if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1858            FT_IS_VARIATION( FT_FACE( face ) )      )
1859       {
1860         short        i, limit;
1861         FT_SubGlyph  subglyph;
1862 
1863         FT_Outline  outline;
1864         FT_Vector*  points   = NULL;
1865         char*       tags     = NULL;
1866         short*      contours = NULL;

1867 
1868 
1869         limit = (short)gloader->current.num_subglyphs;
1870 
1871         /* construct an outline structure for              */
1872         /* communication with `TT_Vary_Apply_Glyph_Deltas' */
1873         outline.n_points   = (short)( gloader->current.num_subglyphs + 4 );
1874         outline.n_contours = outline.n_points;
1875 
1876         outline.points   = NULL;
1877         outline.tags     = NULL;
1878         outline.contours = NULL;
1879 
1880         if ( FT_NEW_ARRAY( points, outline.n_points )   ||
1881              FT_NEW_ARRAY( tags, outline.n_points )     ||
1882              FT_NEW_ARRAY( contours, outline.n_points ) )

1883           goto Exit1;
1884 
1885         subglyph = gloader->current.subglyphs;
1886 
1887         for ( i = 0; i < limit; i++, subglyph++ )
1888         {
1889           /* applying deltas for anchor points doesn't make sense, */
1890           /* but we don't have to specially check this since       */
1891           /* unused delta values are zero anyways                  */
1892           points[i].x = subglyph->arg1;
1893           points[i].y = subglyph->arg2;
1894           tags[i]     = 1;
1895           contours[i] = i;
1896         }
1897 
1898         points[i].x = loader->pp1.x;
1899         points[i].y = loader->pp1.y;
1900         tags[i]     = 1;
1901         contours[i] = i;
1902 


1911         points[i].y = loader->pp3.y;
1912         tags[i]     = 1;
1913         contours[i] = i;
1914 
1915         i++;
1916         points[i].x = loader->pp4.x;
1917         points[i].y = loader->pp4.y;
1918         tags[i]     = 1;
1919         contours[i] = i;
1920 
1921         outline.points   = points;
1922         outline.tags     = tags;
1923         outline.contours = contours;
1924 
1925         /* this call provides additional offsets */
1926         /* for each component's translation      */
1927         if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas(
1928                              face,
1929                              glyph_index,
1930                              &outline,

1931                              (FT_UInt)outline.n_points ) ) )
1932           goto Exit1;
1933 
1934         subglyph = gloader->current.subglyphs;
1935 
1936         for ( i = 0; i < limit; i++, subglyph++ )
1937         {
1938           if ( subglyph->flags & ARGS_ARE_XY_VALUES )
1939           {
1940             subglyph->arg1 = (FT_Int16)points[i].x;
1941             subglyph->arg2 = (FT_Int16)points[i].y;
1942           }
1943         }
1944 
1945         loader->pp1.x = points[i + 0].x;
1946         loader->pp1.y = points[i + 0].y;
1947         loader->pp2.x = points[i + 1].x;
1948         loader->pp2.y = points[i + 1].y;
1949 
1950         loader->pp3.x = points[i + 2].x;
1951         loader->pp3.y = points[i + 2].y;
1952         loader->pp4.x = points[i + 3].x;
1953         loader->pp4.y = points[i + 3].y;
1954 
1955         /* recalculate linear horizontal and vertical advances */
1956         /* if we don't have HVAR and VVAR, respectively        */
1957         if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
1958           loader->linear = loader->pp2.x - loader->pp1.x;


1959         if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
1960           loader->vadvance = loader->pp4.x - loader->pp3.x;


1961 
1962       Exit1:
1963         FT_FREE( outline.points );
1964         FT_FREE( outline.tags );
1965         FT_FREE( outline.contours );

1966 
1967         if ( error )
1968           goto Exit;
1969       }
1970 
1971 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1972 
1973       /* scale phantom points, if necessary; */
1974       /* they get rounded in `TT_Hint_Glyph' */
1975       if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1976       {
1977         loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1978         loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1979         /* pp1.y and pp2.y are always zero */
1980 
1981         loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1982         loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1983         loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1984         loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1985       }


2071           /*    (1)               (2)                   (3)           */
2072           /*                                                          */
2073           /* (1) points that exist from the beginning                 */
2074           /* (2) component points that have been loaded so far        */
2075           /* (3) points of the newly loaded component                 */
2076           error = TT_Process_Composite_Component( loader,
2077                                                   subglyph,
2078                                                   start_point,
2079                                                   num_base_points );
2080           if ( error )
2081             goto Exit;
2082         }
2083 
2084         loader->stream   = old_stream;
2085         loader->byte_len = old_byte_len;
2086 
2087         /* process the glyph */
2088         loader->ins_pos = ins_pos;
2089         if ( IS_HINTED( loader->load_flags ) &&
2090 #ifdef TT_USE_BYTECODE_INTERPRETER

2091              subglyph->flags & WE_HAVE_INSTR &&
2092 #endif
2093              num_points > start_point )
2094         {
2095           error = TT_Process_Composite_Glyph( loader,
2096                                               start_point,
2097                                               start_contour );
2098           if ( error )
2099             goto Exit;
2100         }
2101       }
2102     }
2103 
2104     /***********************************************************************/
2105     /***********************************************************************/
2106     /***********************************************************************/
2107 
2108   Exit:
2109 
2110     if ( opened_frame )


2594             exec->grayscale_cleartype = grayscale_cleartype;
2595             reexecute                 = TRUE;
2596           }
2597         }
2598 #endif
2599 
2600         /* a change from mono to grayscale rendering (and vice versa) */
2601         /* requires a re-execution of the CVT program                 */
2602         if ( grayscale != exec->grayscale )
2603         {
2604           FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
2605                       " re-executing `prep' table\n" ));
2606 
2607           exec->grayscale = grayscale;
2608           reexecute       = TRUE;
2609         }
2610       }
2611 
2612       if ( reexecute )
2613       {
2614         FT_UInt  i;
2615 
2616 
2617         for ( i = 0; i < size->cvt_size; i++ )
2618           size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
2619         error = tt_size_run_prep( size, pedantic );
2620         if ( error )
2621           return error;
2622       }
2623 
2624       /* check whether the cvt program has disabled hinting */
2625       if ( exec->GS.instruct_control & 1 )
2626         load_flags |= FT_LOAD_NO_HINTING;
2627 
2628       /* load default graphics state -- if needed */
2629       if ( exec->GS.instruct_control & 2 )
2630         exec->GS = tt_default_graphics_state;
2631 
2632 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2633       /* check whether we have a font hinted for ClearType --           */
2634       /* note that this flag can also be modified in a glyph's bytecode */
2635       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
2636            exec->GS.instruct_control & 4                            )
2637         exec->ignore_x_mode = 0;
2638 #endif


2701    *
2702    *   load_flags ::
2703    *     A flag indicating what to load for this glyph.  The
2704    *     FT_LOAD_XXX constants can be used to control the
2705    *     glyph loading process (e.g., whether the outline
2706    *     should be scaled, whether to load bitmaps or not,
2707    *     whether to hint the outline, etc).
2708    *
2709    * @Return:
2710    *   FreeType error code.  0 means success.
2711    */
2712   FT_LOCAL_DEF( FT_Error )
2713   TT_Load_Glyph( TT_Size       size,
2714                  TT_GlyphSlot  glyph,
2715                  FT_UInt       glyph_index,
2716                  FT_Int32      load_flags )
2717   {
2718     FT_Error      error;
2719     TT_LoaderRec  loader;
2720 
2721 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
2722 #define IS_DEFAULT_INSTANCE  ( !( FT_IS_NAMED_INSTANCE( glyph->face ) ||  \
2723                                   FT_IS_VARIATION( glyph->face )      ) )
2724 #else
2725 #define IS_DEFAULT_INSTANCE  1
2726 #endif
2727 
2728 
2729     FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
2730 
2731 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2732 
2733     /* try to load embedded bitmap (if any) */
2734     if ( size->strike_index != 0xFFFFFFFFUL      &&
2735          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
2736          IS_DEFAULT_INSTANCE                     )
2737     {
2738       FT_Fixed  x_scale = size->root.metrics.x_scale;
2739       FT_Fixed  y_scale = size->root.metrics.y_scale;
2740 
2741 
2742       error = load_sbit_image( size, glyph, glyph_index, load_flags );
2743       if ( FT_ERR_EQ( error, Missing_Bitmap ) )
2744       {
2745         /* the bitmap strike is incomplete and misses the requested glyph; */
2746         /* if we have a bitmap-only font, return an empty glyph            */
2747         if ( !FT_IS_SCALABLE( glyph->face ) )
2748         {
2749           TT_Face  face = (TT_Face)glyph->face;
2750 
2751           FT_Short  left_bearing = 0;
2752           FT_Short  top_bearing  = 0;
2753 
2754           FT_UShort  advance_width  = 0;
2755           FT_UShort  advance_height = 0;
2756 




  65 
  66   /**************************************************************************
  67    *
  68    * Composite glyph flags.
  69    */
  70 #define ARGS_ARE_WORDS             0x0001
  71 #define ARGS_ARE_XY_VALUES         0x0002
  72 #define ROUND_XY_TO_GRID           0x0004
  73 #define WE_HAVE_A_SCALE            0x0008
  74 /* reserved                        0x0010 */
  75 #define MORE_COMPONENTS            0x0020
  76 #define WE_HAVE_AN_XY_SCALE        0x0040
  77 #define WE_HAVE_A_2X2              0x0080
  78 #define WE_HAVE_INSTR              0x0100
  79 #define USE_MY_METRICS             0x0200
  80 #define OVERLAP_COMPOUND           0x0400  /* we ignore this value */
  81 #define SCALED_COMPONENT_OFFSET    0x0800
  82 #define UNSCALED_COMPONENT_OFFSET  0x1000
  83 
  84 
  85 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  86 #define IS_DEFAULT_INSTANCE( _face )             \
  87           ( !( FT_IS_NAMED_INSTANCE( _face ) ||  \
  88                FT_IS_VARIATION( _face )      ) )
  89 #else
  90 #define IS_DEFAULT_INSTANCE( _face )  1
  91 #endif
  92 
  93 
  94   /**************************************************************************
  95    *
  96    * Return the horizontal metrics in font units for a given glyph.
  97    */
  98   FT_LOCAL_DEF( void )
  99   TT_Get_HMetrics( TT_Face     face,
 100                    FT_UInt     idx,
 101                    FT_Short*   lsb,
 102                    FT_UShort*  aw )
 103   {
 104     ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );
 105 
 106     FT_TRACE5(( "  advance width (font units): %d\n", *aw ));
 107     FT_TRACE5(( "  left side bearing (font units): %d\n", *lsb ));
 108   }
 109 
 110 
 111   /**************************************************************************
 112    *
 113    * Return the vertical metrics in font units for a given glyph.


 919 
 920 
 921   /**************************************************************************
 922    *
 923    * @Function:
 924    *   TT_Process_Simple_Glyph
 925    *
 926    * @Description:
 927    *   Once a simple glyph has been loaded, it needs to be processed.
 928    *   Usually, this means scaling and hinting through bytecode
 929    *   interpretation.
 930    */
 931   static FT_Error
 932   TT_Process_Simple_Glyph( TT_Loader  loader )
 933   {
 934     FT_GlyphLoader  gloader = loader->gloader;
 935     FT_Error        error   = FT_Err_Ok;
 936     FT_Outline*     outline;
 937     FT_Int          n_points;
 938 
 939 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 940     FT_Memory   memory    = loader->face->root.memory;
 941     FT_Vector*  unrounded = NULL;
 942 #endif
 943 
 944 
 945     outline  = &gloader->current.outline;
 946     n_points = outline->n_points;
 947 
 948     /* set phantom points */
 949 
 950     outline->points[n_points    ] = loader->pp1;
 951     outline->points[n_points + 1] = loader->pp2;
 952     outline->points[n_points + 2] = loader->pp3;
 953     outline->points[n_points + 3] = loader->pp4;
 954 
 955     outline->tags[n_points    ] = 0;
 956     outline->tags[n_points + 1] = 0;
 957     outline->tags[n_points + 2] = 0;
 958     outline->tags[n_points + 3] = 0;
 959 
 960     n_points += 4;
 961 
 962 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 963 
 964     if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )

 965     {
 966       if ( FT_NEW_ARRAY( unrounded, n_points ) )
 967         goto Exit;
 968 
 969       /* Deltas apply to the unscaled data. */
 970       error = TT_Vary_Apply_Glyph_Deltas( loader->face,
 971                                           loader->glyph_index,
 972                                           outline,
 973                                           unrounded,
 974                                           (FT_UInt)n_points );
 975 
 976       /* recalculate linear horizontal and vertical advances */
 977       /* if we don't have HVAR and VVAR, respectively        */
 978 
 979       /* XXX: change all FreeType modules to store `linear' and `vadvance' */
 980       /*      in 26.6 format before the `base' module scales them to 16.16 */
 981       if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
 982         loader->linear = FT_PIX_ROUND( unrounded[n_points - 3].x -
 983                                        unrounded[n_points - 4].x ) / 64;
 984       if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
 985         loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].x -
 986                                          unrounded[n_points - 2].x ) / 64;
 987 
 988       if ( error )
 989         goto Exit;
 990     }
 991 
 992 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 993 
 994     if ( IS_HINTED( loader->load_flags ) )
 995     {
 996       tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
 997 
 998       FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
 999                      loader->zone.n_points + 4 );
1000     }
1001 
1002     {
1003 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
1004       TT_Face    face   = loader->face;
1005       TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
1006 
1007       FT_String*  family         = face->root.family_name;
1008       FT_UInt     ppem           = loader->size->metrics->x_ppem;
1009       FT_String*  style          = face->root.style_name;


1024       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
1025       {
1026         /* scale, but only if enabled and only if TT hinting is being used */
1027         if ( IS_HINTED( loader->load_flags ) )
1028           x_scale_factor = sph_test_tweak_x_scaling( face,
1029                                                      family,
1030                                                      ppem,
1031                                                      style,
1032                                                      loader->glyph_index );
1033         /* scale the glyph */
1034         if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
1035              x_scale_factor != 1000                         )
1036         {
1037           x_scale = FT_MulDiv( loader->size->metrics->x_scale,
1038                                (FT_Long)x_scale_factor, 1000 );
1039           y_scale = loader->size->metrics->y_scale;
1040 
1041           /* compensate for any scaling by de/emboldening; */
1042           /* the amount was determined via experimentation */
1043           if ( x_scale_factor != 1000 && ppem > 11 )
1044           {
1045 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1046             FT_Vector*  orig_points = outline->points;
1047 
1048 
1049             if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
1050               outline->points = unrounded;
1051 #endif
1052             FT_Outline_EmboldenXY( outline,
1053                                    FT_MulFix( 1280 * ppem,
1054                                               1000 - x_scale_factor ),
1055                                    0 );
1056 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1057             if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
1058               outline->points = orig_points;
1059 #endif
1060           }
1061           do_scale = TRUE;
1062         }
1063       }
1064       else
1065 
1066 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
1067 
1068       {
1069         /* scale the glyph */
1070         if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1071         {
1072           x_scale = loader->size->metrics->x_scale;
1073           y_scale = loader->size->metrics->y_scale;
1074 
1075           do_scale = TRUE;
1076         }
1077       }
1078 
1079       if ( do_scale )
1080       {
1081 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1082         if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
1083         {
1084           FT_Vector*  u = unrounded;
1085 
1086 
1087           for ( ; vec < limit; vec++, u++ )
1088           {
1089             vec->x = ( FT_MulFix( u->x, x_scale ) + 32 ) >> 6;
1090             vec->y = ( FT_MulFix( u->y, y_scale ) + 32 ) >> 6;
1091           }
1092         }
1093         else
1094 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1095         {
1096           for ( ; vec < limit; vec++ )
1097           {
1098             vec->x = FT_MulFix( vec->x, x_scale );
1099             vec->y = FT_MulFix( vec->y, y_scale );
1100           }
1101         }
1102       }
1103 
1104 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1105       /* if we have a HVAR table, `pp1' and/or `pp2' are already adjusted */
1106       if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ||
1107            !IS_HINTED( loader->load_flags )                                 )
1108 #endif
1109       {
1110         loader->pp1 = outline->points[n_points - 4];
1111         loader->pp2 = outline->points[n_points - 3];
1112       }
1113 
1114 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1115       /* if we have a VVAR table, `pp3' and/or `pp4' are already adjusted */
1116       if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ||
1117            !IS_HINTED( loader->load_flags )                                 )
1118 #endif
1119       {
1120         loader->pp3 = outline->points[n_points - 2];
1121         loader->pp4 = outline->points[n_points - 1];
1122       }
1123     }
1124 
1125     if ( IS_HINTED( loader->load_flags ) )
1126     {
1127       loader->zone.n_points += 4;
1128 
1129       error = TT_Hint_Glyph( loader, 0 );
1130     }
1131 
1132 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1133   Exit:
1134     FT_FREE( unrounded );
1135 #endif
1136 
1137     return error;
1138   }
1139 
1140 
1141   /**************************************************************************
1142    *
1143    * @Function:
1144    *   TT_Process_Composite_Component
1145    *
1146    * @Description:
1147    *   Once a composite component has been loaded, it needs to be
1148    *   processed.  Usually, this means transforming and translating.
1149    */
1150   static FT_Error
1151   TT_Process_Composite_Component( TT_Loader    loader,
1152                                   FT_SubGlyph  subglyph,
1153                                   FT_UInt      start_point,
1154                                   FT_UInt      num_base_points )
1155   {
1156     FT_GlyphLoader  gloader = loader->gloader;


1718       /* must initialize points before (possibly) overriding */
1719       /* glyph metrics from the incremental interface        */
1720       tt_loader_set_pp( loader );
1721 
1722 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1723       tt_get_metrics_incr_overrides( loader, glyph_index );
1724 #endif
1725 
1726 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1727 
1728       if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1729            FT_IS_VARIATION( FT_FACE( face ) )      )
1730       {
1731         /* a small outline structure with four elements for */
1732         /* communication with `TT_Vary_Apply_Glyph_Deltas'  */
1733         FT_Vector   points[4];
1734         char        tags[4]     = { 1, 1, 1, 1 };
1735         short       contours[4] = { 0, 1, 2, 3 };
1736         FT_Outline  outline;
1737 
1738         /* unrounded values */
1739         FT_Vector  unrounded[4] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
1740 
1741 
1742         points[0].x = loader->pp1.x;
1743         points[0].y = loader->pp1.y;
1744         points[1].x = loader->pp2.x;
1745         points[1].y = loader->pp2.y;
1746 
1747         points[2].x = loader->pp3.x;
1748         points[2].y = loader->pp3.y;
1749         points[3].x = loader->pp4.x;
1750         points[3].y = loader->pp4.y;
1751 
1752         outline.n_points   = 4;
1753         outline.n_contours = 4;
1754         outline.points     = points;
1755         outline.tags       = tags;
1756         outline.contours   = contours;
1757 
1758         /* this must be done before scaling */
1759         error = TT_Vary_Apply_Glyph_Deltas( loader->face,
1760                                             glyph_index,
1761                                             &outline,
1762                                             unrounded,
1763                                             (FT_UInt)outline.n_points );
1764         if ( error )
1765           goto Exit;
1766 
1767         loader->pp1.x = points[0].x;
1768         loader->pp1.y = points[0].y;
1769         loader->pp2.x = points[1].x;
1770         loader->pp2.y = points[1].y;
1771 
1772         loader->pp3.x = points[2].x;
1773         loader->pp3.y = points[2].y;
1774         loader->pp4.x = points[3].x;
1775         loader->pp4.y = points[3].y;
1776 
1777         /* recalculate linear horizontal and vertical advances */
1778         /* if we don't have HVAR and VVAR, respectively        */
1779         if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
1780           loader->linear = FT_PIX_ROUND( unrounded[1].x -
1781                                          unrounded[0].x ) / 64;
1782         if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
1783           loader->vadvance = FT_PIX_ROUND( unrounded[3].x -
1784                                            unrounded[2].x ) / 64;
1785       }
1786 
1787 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1788 
1789       /* scale phantom points, if necessary; */
1790       /* they get rounded in `TT_Hint_Glyph' */
1791       if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1792       {
1793         loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1794         loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1795         /* pp1.y and pp2.y are always zero */
1796 
1797         loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1798         loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1799         loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1800         loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1801       }
1802 
1803       error = FT_Err_Ok;
1804       goto Exit;


1907 
1908       /* store the offset of instructions */
1909       ins_pos = loader->ins_pos;
1910 
1911       /* all data we need are read */
1912       face->forget_glyph_frame( loader );
1913       opened_frame = 0;
1914 
1915 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1916 
1917       if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1918            FT_IS_VARIATION( FT_FACE( face ) )      )
1919       {
1920         short        i, limit;
1921         FT_SubGlyph  subglyph;
1922 
1923         FT_Outline  outline;
1924         FT_Vector*  points    = NULL;
1925         char*       tags      = NULL;
1926         short*      contours  = NULL;
1927         FT_Vector*  unrounded = NULL;
1928 
1929 
1930         limit = (short)gloader->current.num_subglyphs;
1931 
1932         /* construct an outline structure for              */
1933         /* communication with `TT_Vary_Apply_Glyph_Deltas' */
1934         outline.n_points   = (short)( gloader->current.num_subglyphs + 4 );
1935         outline.n_contours = outline.n_points;
1936 
1937         outline.points   = NULL;
1938         outline.tags     = NULL;
1939         outline.contours = NULL;
1940 
1941         if ( FT_NEW_ARRAY( points, outline.n_points )    ||
1942              FT_NEW_ARRAY( tags, outline.n_points )      ||
1943              FT_NEW_ARRAY( contours, outline.n_points )  ||
1944              FT_NEW_ARRAY( unrounded, outline.n_points ) )
1945           goto Exit1;
1946 
1947         subglyph = gloader->current.subglyphs;
1948 
1949         for ( i = 0; i < limit; i++, subglyph++ )
1950         {
1951           /* applying deltas for anchor points doesn't make sense, */
1952           /* but we don't have to specially check this since       */
1953           /* unused delta values are zero anyways                  */
1954           points[i].x = subglyph->arg1;
1955           points[i].y = subglyph->arg2;
1956           tags[i]     = 1;
1957           contours[i] = i;
1958         }
1959 
1960         points[i].x = loader->pp1.x;
1961         points[i].y = loader->pp1.y;
1962         tags[i]     = 1;
1963         contours[i] = i;
1964 


1973         points[i].y = loader->pp3.y;
1974         tags[i]     = 1;
1975         contours[i] = i;
1976 
1977         i++;
1978         points[i].x = loader->pp4.x;
1979         points[i].y = loader->pp4.y;
1980         tags[i]     = 1;
1981         contours[i] = i;
1982 
1983         outline.points   = points;
1984         outline.tags     = tags;
1985         outline.contours = contours;
1986 
1987         /* this call provides additional offsets */
1988         /* for each component's translation      */
1989         if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas(
1990                              face,
1991                              glyph_index,
1992                              &outline,
1993                              unrounded,
1994                              (FT_UInt)outline.n_points ) ) )
1995           goto Exit1;
1996 
1997         subglyph = gloader->current.subglyphs;
1998 
1999         for ( i = 0; i < limit; i++, subglyph++ )
2000         {
2001           if ( subglyph->flags & ARGS_ARE_XY_VALUES )
2002           {
2003             subglyph->arg1 = (FT_Int16)points[i].x;
2004             subglyph->arg2 = (FT_Int16)points[i].y;
2005           }
2006         }
2007 
2008         loader->pp1.x = points[i + 0].x;
2009         loader->pp1.y = points[i + 0].y;
2010         loader->pp2.x = points[i + 1].x;
2011         loader->pp2.y = points[i + 1].y;
2012 
2013         loader->pp3.x = points[i + 2].x;
2014         loader->pp3.y = points[i + 2].y;
2015         loader->pp4.x = points[i + 3].x;
2016         loader->pp4.y = points[i + 3].y;
2017 
2018         /* recalculate linear horizontal and vertical advances */
2019         /* if we don't have HVAR and VVAR, respectively        */
2020         if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
2021           loader->linear =
2022             FT_PIX_ROUND( unrounded[outline.n_points - 3].x -
2023                           unrounded[outline.n_points - 4].x ) / 64;
2024         if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
2025           loader->vadvance =
2026             FT_PIX_ROUND( unrounded[outline.n_points - 1].x -
2027                           unrounded[outline.n_points - 2].x ) / 64;
2028 
2029       Exit1:
2030         FT_FREE( outline.points );
2031         FT_FREE( outline.tags );
2032         FT_FREE( outline.contours );
2033         FT_FREE( unrounded );
2034 
2035         if ( error )
2036           goto Exit;
2037       }
2038 
2039 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
2040 
2041       /* scale phantom points, if necessary; */
2042       /* they get rounded in `TT_Hint_Glyph' */
2043       if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
2044       {
2045         loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
2046         loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
2047         /* pp1.y and pp2.y are always zero */
2048 
2049         loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
2050         loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
2051         loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
2052         loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
2053       }


2139           /*    (1)               (2)                   (3)           */
2140           /*                                                          */
2141           /* (1) points that exist from the beginning                 */
2142           /* (2) component points that have been loaded so far        */
2143           /* (3) points of the newly loaded component                 */
2144           error = TT_Process_Composite_Component( loader,
2145                                                   subglyph,
2146                                                   start_point,
2147                                                   num_base_points );
2148           if ( error )
2149             goto Exit;
2150         }
2151 
2152         loader->stream   = old_stream;
2153         loader->byte_len = old_byte_len;
2154 
2155         /* process the glyph */
2156         loader->ins_pos = ins_pos;
2157         if ( IS_HINTED( loader->load_flags ) &&
2158 #ifdef TT_USE_BYTECODE_INTERPRETER
2159              subglyph                        &&
2160              subglyph->flags & WE_HAVE_INSTR &&
2161 #endif
2162              num_points > start_point )
2163         {
2164           error = TT_Process_Composite_Glyph( loader,
2165                                               start_point,
2166                                               start_contour );
2167           if ( error )
2168             goto Exit;
2169         }
2170       }
2171     }
2172 
2173     /***********************************************************************/
2174     /***********************************************************************/
2175     /***********************************************************************/
2176 
2177   Exit:
2178 
2179     if ( opened_frame )


2663             exec->grayscale_cleartype = grayscale_cleartype;
2664             reexecute                 = TRUE;
2665           }
2666         }
2667 #endif
2668 
2669         /* a change from mono to grayscale rendering (and vice versa) */
2670         /* requires a re-execution of the CVT program                 */
2671         if ( grayscale != exec->grayscale )
2672         {
2673           FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
2674                       " re-executing `prep' table\n" ));
2675 
2676           exec->grayscale = grayscale;
2677           reexecute       = TRUE;
2678         }
2679       }
2680 
2681       if ( reexecute )
2682       {





2683         error = tt_size_run_prep( size, pedantic );
2684         if ( error )
2685           return error;
2686       }
2687 
2688       /* check whether the cvt program has disabled hinting */
2689       if ( exec->GS.instruct_control & 1 )
2690         load_flags |= FT_LOAD_NO_HINTING;
2691 
2692       /* load default graphics state -- if needed */
2693       if ( exec->GS.instruct_control & 2 )
2694         exec->GS = tt_default_graphics_state;
2695 
2696 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2697       /* check whether we have a font hinted for ClearType --           */
2698       /* note that this flag can also be modified in a glyph's bytecode */
2699       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
2700            exec->GS.instruct_control & 4                            )
2701         exec->ignore_x_mode = 0;
2702 #endif


2765    *
2766    *   load_flags ::
2767    *     A flag indicating what to load for this glyph.  The
2768    *     FT_LOAD_XXX constants can be used to control the
2769    *     glyph loading process (e.g., whether the outline
2770    *     should be scaled, whether to load bitmaps or not,
2771    *     whether to hint the outline, etc).
2772    *
2773    * @Return:
2774    *   FreeType error code.  0 means success.
2775    */
2776   FT_LOCAL_DEF( FT_Error )
2777   TT_Load_Glyph( TT_Size       size,
2778                  TT_GlyphSlot  glyph,
2779                  FT_UInt       glyph_index,
2780                  FT_Int32      load_flags )
2781   {
2782     FT_Error      error;
2783     TT_LoaderRec  loader;
2784 







2785 
2786     FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
2787 
2788 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2789 
2790     /* try to load embedded bitmap (if any) */
2791     if ( size->strike_index != 0xFFFFFFFFUL      &&
2792          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
2793          IS_DEFAULT_INSTANCE( glyph->face )      )
2794     {
2795       FT_Fixed  x_scale = size->root.metrics.x_scale;
2796       FT_Fixed  y_scale = size->root.metrics.y_scale;
2797 
2798 
2799       error = load_sbit_image( size, glyph, glyph_index, load_flags );
2800       if ( FT_ERR_EQ( error, Missing_Bitmap ) )
2801       {
2802         /* the bitmap strike is incomplete and misses the requested glyph; */
2803         /* if we have a bitmap-only font, return an empty glyph            */
2804         if ( !FT_IS_SCALABLE( glyph->face ) )
2805         {
2806           TT_Face  face = (TT_Face)glyph->face;
2807 
2808           FT_Short  left_bearing = 0;
2809           FT_Short  top_bearing  = 0;
2810 
2811           FT_UShort  advance_width  = 0;
2812           FT_UShort  advance_height = 0;
2813 


< prev index next >