00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ft2build.h>
00020 #include FT_ADVANCES_H
00021 #include FT_INTERNAL_OBJECTS_H
00022
00023
00024 static FT_Error
00025 _ft_face_scale_advances( FT_Face face,
00026 FT_Fixed* advances,
00027 FT_UInt count,
00028 FT_Int32 flags )
00029 {
00030 FT_Fixed scale;
00031 FT_UInt nn;
00032
00033
00034 if ( flags & FT_LOAD_NO_SCALE )
00035 return FT_Err_Ok;
00036
00037 if ( face->size == NULL )
00038 return FT_Err_Invalid_Size_Handle;
00039
00040 if ( flags & FT_LOAD_VERTICAL_LAYOUT )
00041 scale = face->size->metrics.y_scale;
00042 else
00043 scale = face->size->metrics.x_scale;
00044
00045
00046
00047
00048 for ( nn = 0; nn < count; nn++ )
00049 advances[nn] = FT_MulDiv( advances[nn], scale, 64 );
00050
00051 return FT_Err_Ok;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #define LOAD_ADVANCE_FAST_CHECK( flags ) \
00063 ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \
00064 FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
00065
00066
00067
00068
00069 FT_EXPORT_DEF( FT_Error )
00070 FT_Get_Advance( FT_Face face,
00071 FT_UInt gindex,
00072 FT_Int32 flags,
00073 FT_Fixed *padvance )
00074 {
00075 FT_Face_GetAdvancesFunc func;
00076
00077
00078 if ( !face )
00079 return FT_Err_Invalid_Face_Handle;
00080
00081 if ( gindex >= (FT_UInt)face->num_glyphs )
00082 return FT_Err_Invalid_Glyph_Index;
00083
00084 func = face->driver->clazz->get_advances;
00085 if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
00086 {
00087 FT_Error error;
00088
00089
00090 error = func( face, gindex, 1, flags, padvance );
00091 if ( !error )
00092 return _ft_face_scale_advances( face, padvance, 1, flags );
00093
00094 if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )
00095 return error;
00096 }
00097
00098 return FT_Get_Advances( face, gindex, 1, flags, padvance );
00099 }
00100
00101
00102
00103
00104 FT_EXPORT_DEF( FT_Error )
00105 FT_Get_Advances( FT_Face face,
00106 FT_UInt start,
00107 FT_UInt count,
00108 FT_Int32 flags,
00109 FT_Fixed *padvances )
00110 {
00111 FT_Face_GetAdvancesFunc func;
00112 FT_UInt num, end, nn;
00113 FT_Error error = FT_Err_Ok;
00114
00115
00116 if ( !face )
00117 return FT_Err_Invalid_Face_Handle;
00118
00119 num = (FT_UInt)face->num_glyphs;
00120 end = start + count;
00121 if ( start >= num || end < start || end > num )
00122 return FT_Err_Invalid_Glyph_Index;
00123
00124 if ( count == 0 )
00125 return FT_Err_Ok;
00126
00127 func = face->driver->clazz->get_advances;
00128 if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
00129 {
00130 error = func( face, start, count, flags, padvances );
00131 if ( !error )
00132 goto Exit;
00133
00134 if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )
00135 return error;
00136 }
00137
00138 error = FT_Err_Ok;
00139
00140 if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
00141 return FT_Err_Unimplemented_Feature;
00142
00143 flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
00144 for ( nn = 0; nn < count; nn++ )
00145 {
00146 error = FT_Load_Glyph( face, start + nn, flags );
00147 if ( error )
00148 break;
00149
00150 padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
00151 ? face->glyph->advance.y
00152 : face->glyph->advance.x;
00153 }
00154
00155 if ( error )
00156 return error;
00157
00158 Exit:
00159 return _ft_face_scale_advances( face, padvances, count, flags );
00160 }
00161
00162
00163