1 /***************************************************************************/ 2 /* */ 3 /* afmodule.c */ 4 /* */ 5 /* Auto-fitter module implementation (body). */ 6 /* */ 7 /* Copyright 2003-2006, 2009, 2011-2014 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 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 #include "afglobal.h" 20 #include "afmodule.h" 21 #include "afloader.h" 22 #include "aferrors.h" 23 #include "afpic.h" 24 25 #ifdef FT_DEBUG_AUTOFIT 26 int _af_debug_disable_horz_hints; 27 int _af_debug_disable_vert_hints; 28 int _af_debug_disable_blue_hints; 29 void* _af_debug_hints; 30 #endif 31 32 #include FT_INTERNAL_OBJECTS_H 33 #include FT_INTERNAL_DEBUG_H 34 #include FT_AUTOHINTER_H 35 #include FT_SERVICE_PROPERTIES_H 36 37 38 /*************************************************************************/ 39 /* */ 40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 41 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 42 /* messages during execution. */ 43 /* */ 44 #undef FT_COMPONENT 45 #define FT_COMPONENT trace_afmodule 46 47 48 static FT_Error af_property_get_face_globals(FT_Face face,AF_FaceGlobals * aglobals,AF_Module module)49 af_property_get_face_globals( FT_Face face, 50 AF_FaceGlobals* aglobals, 51 AF_Module module ) 52 { 53 FT_Error error = FT_Err_Ok; 54 AF_FaceGlobals globals; 55 56 57 if ( !face ) 58 return FT_THROW( Invalid_Argument ); 59 60 globals = (AF_FaceGlobals)face->autohint.data; 61 if ( !globals ) 62 { 63 /* trigger computation of the global style data */ 64 /* in case it hasn't been done yet */ 65 error = af_face_globals_new( face, &globals, module ); 66 if ( !error ) 67 { 68 face->autohint.data = 69 (FT_Pointer)globals; 70 face->autohint.finalizer = 71 (FT_Generic_Finalizer)af_face_globals_free; 72 } 73 } 74 75 if ( !error ) 76 *aglobals = globals; 77 78 return error; 79 } 80 81 82 static FT_Error af_property_set(FT_Module ft_module,const char * property_name,const void * value)83 af_property_set( FT_Module ft_module, 84 const char* property_name, 85 const void* value ) 86 { 87 FT_Error error = FT_Err_Ok; 88 AF_Module module = (AF_Module)ft_module; 89 90 91 if ( !ft_strcmp( property_name, "fallback-script" ) ) 92 { 93 FT_UInt* fallback_script = (FT_UInt*)value; 94 95 FT_UInt ss; 96 97 98 /* We translate the fallback script to a fallback style that uses */ 99 /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its */ 100 /* coverage value. */ 101 for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) 102 { 103 AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; 104 105 106 if ( style_class->script == *fallback_script && 107 style_class->coverage == AF_COVERAGE_DEFAULT ) 108 { 109 module->fallback_style = ss; 110 break; 111 } 112 } 113 114 if ( !AF_STYLE_CLASSES_GET[ss] ) 115 { 116 FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n", 117 fallback_script, property_name )); 118 return FT_THROW( Invalid_Argument ); 119 } 120 121 return error; 122 } 123 else if ( !ft_strcmp( property_name, "default-script" ) ) 124 { 125 FT_UInt* default_script = (FT_UInt*)value; 126 127 128 module->default_script = *default_script; 129 130 return error; 131 } 132 else if ( !ft_strcmp( property_name, "increase-x-height" ) ) 133 { 134 FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; 135 AF_FaceGlobals globals; 136 137 138 error = af_property_get_face_globals( prop->face, &globals, module ); 139 if ( !error ) 140 globals->increase_x_height = prop->limit; 141 142 return error; 143 } 144 145 FT_TRACE0(( "af_property_set: missing property `%s'\n", 146 property_name )); 147 return FT_THROW( Missing_Property ); 148 } 149 150 151 static FT_Error af_property_get(FT_Module ft_module,const char * property_name,void * value)152 af_property_get( FT_Module ft_module, 153 const char* property_name, 154 void* value ) 155 { 156 FT_Error error = FT_Err_Ok; 157 AF_Module module = (AF_Module)ft_module; 158 FT_UInt fallback_style = module->fallback_style; 159 FT_UInt default_script = module->default_script; 160 161 162 if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) 163 { 164 FT_Prop_GlyphToScriptMap* prop = (FT_Prop_GlyphToScriptMap*)value; 165 AF_FaceGlobals globals; 166 167 168 error = af_property_get_face_globals( prop->face, &globals, module ); 169 if ( !error ) 170 prop->map = globals->glyph_styles; 171 172 return error; 173 } 174 else if ( !ft_strcmp( property_name, "fallback-script" ) ) 175 { 176 FT_UInt* val = (FT_UInt*)value; 177 178 AF_StyleClass style_class = AF_STYLE_CLASSES_GET[fallback_style]; 179 180 181 *val = style_class->script; 182 183 return error; 184 } 185 else if ( !ft_strcmp( property_name, "default-script" ) ) 186 { 187 FT_UInt* val = (FT_UInt*)value; 188 189 190 *val = default_script; 191 192 return error; 193 } 194 else if ( !ft_strcmp( property_name, "increase-x-height" ) ) 195 { 196 FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; 197 AF_FaceGlobals globals; 198 199 200 error = af_property_get_face_globals( prop->face, &globals, module ); 201 if ( !error ) 202 prop->limit = globals->increase_x_height; 203 204 return error; 205 } 206 207 208 FT_TRACE0(( "af_property_get: missing property `%s'\n", 209 property_name )); 210 return FT_THROW( Missing_Property ); 211 } 212 213 214 FT_DEFINE_SERVICE_PROPERTIESREC( 215 af_service_properties, 216 (FT_Properties_SetFunc)af_property_set, 217 (FT_Properties_GetFunc)af_property_get ) 218 219 220 FT_DEFINE_SERVICEDESCREC1( 221 af_services, 222 FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET ) 223 224 FT_CALLBACK_DEF(FT_Module_Interface)225 FT_CALLBACK_DEF( FT_Module_Interface ) 226 af_get_interface( FT_Module module, 227 const char* module_interface ) 228 { 229 /* AF_SERVICES_GET derefers `library' in PIC mode */ 230 #ifdef FT_CONFIG_OPTION_PIC 231 FT_Library library; 232 233 234 if ( !module ) 235 return NULL; 236 library = module->library; 237 if ( !library ) 238 return NULL; 239 #else 240 FT_UNUSED( module ); 241 #endif 242 243 return ft_service_list_lookup( AF_SERVICES_GET, module_interface ); 244 } 245 246 247 FT_CALLBACK_DEF( FT_Error ) af_autofitter_init(FT_Module ft_module)248 af_autofitter_init( FT_Module ft_module ) /* AF_Module */ 249 { 250 AF_Module module = (AF_Module)ft_module; 251 252 253 module->fallback_style = AF_STYLE_FALLBACK; 254 module->default_script = AF_SCRIPT_DEFAULT; 255 256 return af_loader_init( module ); 257 } 258 259 260 FT_CALLBACK_DEF( void ) af_autofitter_done(FT_Module ft_module)261 af_autofitter_done( FT_Module ft_module ) /* AF_Module */ 262 { 263 AF_Module module = (AF_Module)ft_module; 264 265 266 af_loader_done( module ); 267 } 268 269 270 FT_CALLBACK_DEF( FT_Error ) af_autofitter_load_glyph(AF_Module module,FT_GlyphSlot slot,FT_Size size,FT_UInt glyph_index,FT_Int32 load_flags)271 af_autofitter_load_glyph( AF_Module module, 272 FT_GlyphSlot slot, 273 FT_Size size, 274 FT_UInt glyph_index, 275 FT_Int32 load_flags ) 276 { 277 FT_UNUSED( size ); 278 279 return af_loader_load_glyph( module, slot->face, 280 glyph_index, load_flags ); 281 } 282 283 284 FT_DEFINE_AUTOHINTER_INTERFACE( 285 af_autofitter_interface, 286 NULL, /* reset_face */ 287 NULL, /* get_global_hints */ 288 NULL, /* done_global_hints */ 289 (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph ) /* load_glyph */ 290 291 292 FT_DEFINE_MODULE( 293 autofit_module_class, 294 295 FT_MODULE_HINTER, 296 sizeof ( AF_ModuleRec ), 297 298 "autofitter", 299 0x10000L, /* version 1.0 of the autofitter */ 300 0x20000L, /* requires FreeType 2.0 or above */ 301 302 (const void*)&AF_INTERFACE_GET, 303 304 (FT_Module_Constructor)af_autofitter_init, 305 (FT_Module_Destructor) af_autofitter_done, 306 (FT_Module_Requester) af_get_interface ) 307 308 309 /* END */ 310