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
|