1 /***************************************************************************/
2 /*                                                                         */
3 /*  afmodule.c                                                             */
4 /*                                                                         */
5 /*    Auto-fitter module implementation (body).                            */
6 /*                                                                         */
7 /*  Copyright 2003-2006, 2009, 2011-2013 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   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 script 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   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 
96       module->fallback_script = *fallback_script;
97 
98       return error;
99     }
100     else if ( !ft_strcmp( property_name, "increase-x-height" ) )
101     {
102       FT_Prop_IncreaseXHeight*  prop = (FT_Prop_IncreaseXHeight*)value;
103       AF_FaceGlobals            globals;
104 
105 
106       error = af_property_get_face_globals( prop->face, &globals, module );
107       if ( !error )
108         globals->increase_x_height = prop->limit;
109 
110       return error;
111     }
112 
113     FT_TRACE0(( "af_property_set: missing property `%s'\n",
114                 property_name ));
115     return FT_THROW( Missing_Property );
116   }
117 
118 
119   FT_Error
af_property_get(FT_Module ft_module,const char * property_name,void * value)120   af_property_get( FT_Module    ft_module,
121                    const char*  property_name,
122                    void*        value )
123   {
124     FT_Error   error           = FT_Err_Ok;
125     AF_Module  module          = (AF_Module)ft_module;
126     FT_UInt    fallback_script = module->fallback_script;
127 
128 
129     if ( !ft_strcmp( property_name, "glyph-to-script-map" ) )
130     {
131       FT_Prop_GlyphToScriptMap*  prop = (FT_Prop_GlyphToScriptMap*)value;
132       AF_FaceGlobals             globals;
133 
134 
135       error = af_property_get_face_globals( prop->face, &globals, module );
136       if ( !error )
137         prop->map = globals->glyph_scripts;
138 
139       return error;
140     }
141     else if ( !ft_strcmp( property_name, "fallback-script" ) )
142     {
143       FT_UInt*  val = (FT_UInt*)value;
144 
145 
146       *val = fallback_script;
147 
148       return error;
149     }
150     else if ( !ft_strcmp( property_name, "increase-x-height" ) )
151     {
152       FT_Prop_IncreaseXHeight*  prop = (FT_Prop_IncreaseXHeight*)value;
153       AF_FaceGlobals            globals;
154 
155 
156       error = af_property_get_face_globals( prop->face, &globals, module );
157       if ( !error )
158         prop->limit = globals->increase_x_height;
159 
160       return error;
161     }
162 
163 
164     FT_TRACE0(( "af_property_get: missing property `%s'\n",
165                 property_name ));
166     return FT_THROW( Missing_Property );
167   }
168 
169 
170   FT_DEFINE_SERVICE_PROPERTIESREC(
171     af_service_properties,
172     (FT_Properties_SetFunc)af_property_set,
173     (FT_Properties_GetFunc)af_property_get )
174 
175 
176   FT_DEFINE_SERVICEDESCREC1(
177     af_services,
178     FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET )
179 
180 
FT_CALLBACK_DEF(FT_Module_Interface)181   FT_CALLBACK_DEF( FT_Module_Interface )
182   af_get_interface( FT_Module    module,
183                     const char*  module_interface )
184   {
185     /* AF_SERVICES_GET derefers `library' in PIC mode */
186 #ifdef FT_CONFIG_OPTION_PIC
187     FT_Library  library;
188 
189 
190     if ( !module )
191       return NULL;
192     library = module->library;
193     if ( !library )
194       return NULL;
195 #else
196     FT_UNUSED( module );
197 #endif
198 
199     return ft_service_list_lookup( AF_SERVICES_GET, module_interface );
200   }
201 
202 
203   FT_CALLBACK_DEF( FT_Error )
af_autofitter_init(FT_Module ft_module)204   af_autofitter_init( FT_Module  ft_module )      /* AF_Module */
205   {
206     AF_Module  module = (AF_Module)ft_module;
207 
208 
209     module->fallback_script = AF_SCRIPT_FALLBACK;
210 
211     return af_loader_init( module );
212   }
213 
214 
215   FT_CALLBACK_DEF( void )
af_autofitter_done(FT_Module ft_module)216   af_autofitter_done( FT_Module  ft_module )      /* AF_Module */
217   {
218     AF_Module  module = (AF_Module)ft_module;
219 
220 
221     af_loader_done( module );
222   }
223 
224 
225   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)226   af_autofitter_load_glyph( AF_Module     module,
227                             FT_GlyphSlot  slot,
228                             FT_Size       size,
229                             FT_UInt       glyph_index,
230                             FT_Int32      load_flags )
231   {
232     FT_UNUSED( size );
233 
234     return af_loader_load_glyph( module, slot->face,
235                                  glyph_index, load_flags );
236   }
237 
238 
239   FT_DEFINE_AUTOHINTER_INTERFACE(
240     af_autofitter_interface,
241     NULL,                                                    /* reset_face */
242     NULL,                                              /* get_global_hints */
243     NULL,                                             /* done_global_hints */
244     (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph )  /* load_glyph */
245 
246 
247   FT_DEFINE_MODULE(
248     autofit_module_class,
249 
250     FT_MODULE_HINTER,
251     sizeof ( AF_ModuleRec ),
252 
253     "autofitter",
254     0x10000L,   /* version 1.0 of the autofitter  */
255     0x20000L,   /* requires FreeType 2.0 or above */
256 
257     (const void*)&AF_INTERFACE_GET,
258 
259     (FT_Module_Constructor)af_autofitter_init,
260     (FT_Module_Destructor) af_autofitter_done,
261     (FT_Module_Requester)  af_get_interface )
262 
263 
264 /* END */
265