> The intended API looks like this now > > FT_Error > FT_Property_Set( FT_Library library, > const FT_String* module_name, > const FT_String* property_name, > void* value ); > > FT_Error > FT_Property_Get( FT_Library library, > const FT_String* module_name, > const FT_String* property_name, > void* *avalue ); > > which I'm going to implement the next few days.
And here it is. FT_Property_Get is slightly different now, namely FT_Error FT_Property_Get( FT_Library library, const FT_String* module_name, const FT_String* property_name, void* value ) A first property for the auto-hinter, `glyph-to-script-map' (without documentation yet), is implemented too. An application would do something like the following: /* the format of this structure is specific */ /* to the `glyph-to-script-map' property */ typedef struct map_property_ { FT_Face face; FT_Byte* map; } map_property; map_property prop; FT_Init_FreeType(&library); FT_New_Face(library, "foo.ttf", 0, &face); prop.face = face; error = FT_Property_Get(library, "autofitter", "glyph-to-script-map", &prop); /* now use OpenType features to fix the glyph to script mapping */ /* returned in prop.map array */ FT_Done_FreeType(library); I think that the interface is stable now. Please comment. Werner
diff --git a/include/freetype/fterrdef.h b/include/freetype/fterrdef.h index fb4b53b..bb06d79 100644 --- a/include/freetype/fterrdef.h +++ b/include/freetype/fterrdef.h @@ -4,7 +4,7 @@ /* */ /* FreeType error codes (specification). */ /* */ -/* Copyright 2002, 2004, 2006, 2007, 2010-2011 by */ +/* Copyright 2002, 2004, 2006, 2007, 2010-2012 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -56,6 +56,8 @@ "array allocation size too large" ) FT_ERRORDEF_( Missing_Module, 0x0B, \ "missing module" ) + FT_ERRORDEF_( Missing_Property, 0x0C, \ + "missing property" ) /* glyph/character errors */ diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h index 4cb089d..b0dc113 100644 --- a/include/freetype/ftmodapi.h +++ b/include/freetype/ftmodapi.h @@ -42,14 +42,15 @@ FT_BEGIN_HEADER /* Module Management */ /* */ /* <Abstract> */ - /* How to add, upgrade, and remove modules from FreeType. */ + /* How to add, upgrade, remove, and control modules from FreeType. */ /* */ /* <Description> */ /* The definitions below are used to manage modules within FreeType. */ /* Modules can be added, upgraded, and removed at runtime. */ + /* Additionally, some module properties can be controlled also. */ /* */ - /* Here is a list of module names (the possible values of the */ - /* `module_name' field in the @FT_Module_Class structure). */ + /* Here is a list of possible values of the `module_name' field in */ + /* the @FT_Module_Class structure. */ /* */ /* { */ /* autofitter */ @@ -72,6 +73,7 @@ FT_BEGIN_HEADER /* winfonts */ /* } */ /* */ + /* Note that the FreeType Cache sub-system is not a FreeType module. */ /* */ /*************************************************************************/ @@ -274,6 +276,130 @@ FT_BEGIN_HEADER FT_Module module ); + /********************************************************************** + * + * @function: + * FT_Property_Set + * + * @description: + * Set a property for a given module. + * + * @input: + * library :: + * A handle to the library the module is part of. + * + * module_name :: + * The module name. + * + * property_name :: + * The property name. Properties are described in the `Synopsis' + * subsection of the module's documentation. + * + * Note that only a few modules have properties. + * + * value :: + * A generic pointer to a variable or structure which gives the new + * value of the property. The exact definition of `value' is + * dependent on the property; see the `Synopsis' subsection of the + * module's documentation. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `module_name' isn't a valid module name, or `property_name' + * doesn't specify a valid property, or if `value' doesn't represent a + * valid value for the given property, an error is returned. + * + * The following example sets property `bar' (a simple integer) in + * module `foo' to value~1. + * + * { + * FT_UInt bar; + * + * + * bar = 1; + * FT_Property_Set( library, "foo", "bar", &bar ); + * } + * + * It is not possible to set properties of the FreeType Cache + * sub-system with FT_Property_Set; use @FTC_Property_Set instead. + * + * @since: + * 2.4.11 + * + */ + FT_Error + FT_Property_Set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + const void* value ); + + + /********************************************************************** + * + * @function: + * FT_Property_Get + * + * @description: + * Get a module's property value. + * + * @input: + * library :: + * A handle to the library the module is part of. + * + * module_name :: + * The module name. + * + * property_name :: + * The property name. Properties are described in the `Synopsis' + * subsection of the module's documentation. + * + * @inout: + * value :: + * A generic pointer to a variable or structure which gives the + * value of the property. The exact definition of `value' is + * dependent on the property; see the `Synopsis' subsection of the + * module's documentation. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `module_name' isn't a valid module name, an error is returned. + * If `property_name' doesn't specify a valid property for the given + * module, `*avalue' is set to NULL. + * + * The following example gets property `baz' (a range) in module `foo'. + * + * { + * typedef range_ + * { + * FT_Int32 min; + * FT_Int32 max; + * + * } range; + * + * range baz; + * + * + * FT_Property_Get( library, "foo", "baz", &baz ); + * } + * + * It is not possible to retrieve properties of the FreeType Cache + * sub-system with FT_Property_Get; use @FTC_Property_Get instead. + * + * @since: + * 2.4.11 + * + */ + FT_Error + FT_Property_Get( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + void* value ); + + /*************************************************************************/ /* */ /* <Function> */ @@ -455,13 +581,13 @@ FT_BEGIN_HEADER * scale glyph components with bytecode instructions. It produces * bad output for most other fonts. * - * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: + * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: * The library implements a bytecode interpreter that covers * the full instruction set of the TrueType virtual machine (this * was governed by patents until May 2010, hence the name). * * @since: - * 2.2 + * 2.2 * */ typedef enum FT_TrueTypeEngineType_ diff --git a/include/freetype/internal/ftserv.h b/include/freetype/internal/ftserv.h index 658b215..66395d8 100644 --- a/include/freetype/internal/ftserv.h +++ b/include/freetype/internal/ftserv.h @@ -676,6 +676,7 @@ FT_BEGIN_HEADER #define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h> #define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h> #define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h> +#define FT_SERVICE_PROPERTIES_H <freetype/internal/services/svprop.h> #define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h> #define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h> #define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> diff --git a/include/freetype/internal/services/svprop.h b/include/freetype/internal/services/svprop.h new file mode 100644 index 0000000..4d40c1c --- /dev/null +++ b/include/freetype/internal/services/svprop.h @@ -0,0 +1,81 @@ +/***************************************************************************/ +/* */ +/* svprop.h */ +/* */ +/* The FreeType property service (specification). */ +/* */ +/* Copyright 2012 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPROP_H__ +#define __SVPROP_H__ + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_PROPERTIES "properties" + + + typedef FT_Error + (*FT_Properties_SetFunc)( FT_Library library, + const char* property_name, + const void* value ); + + typedef FT_Error + (*FT_Properties_GetFunc)( FT_Library library, + const char* property_name, + void* value ); + + + FT_DEFINE_SERVICE( Properties ) + { + FT_Properties_SetFunc set_property; + FT_Properties_GetFunc get_property; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ + set_property_, \ + get_property_ ) \ + static const FT_Service_PropertiesRec class_ = \ + { \ + set_property_, \ + get_property_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ + set_property_, \ + get_property_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_PropertiesRec* clazz ) \ + { \ + clazz->set_property = set_property_; \ + clazz->get_property = get_property_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPROP_H__ */ + + +/* END */ diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c index 008bf4c..9a5bac2 100644 --- a/src/autofit/afglobal.c +++ b/src/autofit/afglobal.c @@ -57,22 +57,6 @@ #define AF_DIGIT 0x80 - /* - * Note that glyph_scripts[] is used to map each glyph into - * an index into the `af_script_classes' array. - * - */ - typedef struct AF_FaceGlobalsRec_ - { - FT_Face face; - FT_Long glyph_count; /* same as face->num_glyphs */ - FT_Byte* glyph_scripts; - - AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; - - } AF_FaceGlobalsRec; - - /* Compute the script index of each glyph within a given face. */ static FT_Error diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h index cc6860b..9137dce 100644 --- a/src/autofit/afglobal.h +++ b/src/autofit/afglobal.h @@ -5,7 +5,7 @@ /* Auto-fitter routines to compute global hinting values */ /* (specification). */ /* */ -/* Copyright 2003-2005, 2007, 2009, 2011 by */ +/* Copyright 2003-2005, 2007, 2009, 2011-2012 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -37,10 +37,26 @@ FT_BEGIN_HEADER /* + * Note that glyph_scripts[] is used to map each glyph into + * an index into the `af_script_classes' array. + * + */ + typedef struct AF_FaceGlobalsRec_ + { + FT_Face face; + FT_Long glyph_count; /* same as face->num_glyphs */ + FT_Byte* glyph_scripts; + + AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; + + } AF_FaceGlobalsRec; + + + /* * model the global hints data for a given face, decomposed into * script-specific items */ - typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; + typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; FT_LOCAL( FT_Error ) diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c index 04cd894..1bc791d 100644 --- a/src/autofit/afmodule.c +++ b/src/autofit/afmodule.c @@ -28,6 +28,108 @@ #endif #include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_PROPERTIES_H + + + FT_Error + af_property_set( FT_Library library, + const char* property_name, + const void* value ) + { + FT_UNUSED( library ); + FT_UNUSED( value ); + + FT_TRACE0(( "af_property_get: missing property `%s'\n", + property_name )); + return FT_Err_Missing_Property; + } + + + FT_Error + af_property_get( FT_Library library, + const char* property_name, + void* value ) + { + FT_Error error = FT_Err_Ok; + + FT_UNUSED( library ); + + + if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) + { + typedef struct map_property_ + { + FT_Face face; + FT_Byte* map; + + } map_property; + + map_property* prop = (map_property*)value; + + AF_FaceGlobals globals; + + + if ( !prop->face ) + return FT_Err_Invalid_Argument; + + globals = (AF_FaceGlobals)prop->face->autohint.data; + if ( !globals ) + { + /* trigger computation of the global script data */ + /* in case it hasn't been done yet */ + error = af_face_globals_new( prop->face, &globals ); + if ( !error ) + { + prop->face->autohint.data = + (FT_Pointer)globals; + prop->face->autohint.finalizer = + (FT_Generic_Finalizer)af_face_globals_free; + } + } + + if ( !error ) + prop->map = globals->glyph_scripts; + + return error; + } + + FT_TRACE0(( "af_property_get: missing property `%s'\n", + property_name )); + return FT_Err_Missing_Property; + } + + + FT_DEFINE_SERVICE_PROPERTIESREC( + af_service_properties, + (FT_Properties_SetFunc)af_property_set, + (FT_Properties_GetFunc)af_property_get ) + + + FT_DEFINE_SERVICEDESCREC1( + af_services, + FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET ) + + + FT_CALLBACK_DEF( FT_Module_Interface ) + af_get_interface( FT_Module module, + const char* module_interface ) + { + /* AF_SERVICES_GET derefers `library' in PIC mode */ +#ifdef FT_CONFIG_OPTION_PIC + FT_Library library; + + + if ( !module ) + return NULL; + library = module->library; + if ( !library ) + return NULL; +#else + FT_UNUSED( module ); +#endif + + return ft_service_list_lookup( AF_SERVICES_GET, module_interface ); + } typedef struct FT_AutofitterRec_ @@ -88,7 +190,7 @@ (FT_Module_Constructor)af_autofitter_init, (FT_Module_Destructor) af_autofitter_done, - (FT_Module_Requester) NULL ) + (FT_Module_Requester) af_get_interface ) /* END */ diff --git a/src/autofit/afpic.c b/src/autofit/afpic.c index 36a9cca..e6022f9 100644 --- a/src/autofit/afpic.c +++ b/src/autofit/afpic.c @@ -26,10 +26,22 @@ #ifdef FT_CONFIG_OPTION_PIC /* forward declaration of PIC init functions from afmodule.c */ + FT_Error + FT_Create_Class_af_services( FT_Library library, + FT_ServiceDescRec** output_class ); + + void + FT_Destroy_Class_af_services( FT_Library library, + FT_ServiceDescRec* clazz ); + + void + FT_Init_Class_af_service_properties( FT_Service_PropertiesRec* clazz ); + void FT_Init_Class_af_autofitter_interface( FT_Library library, FT_AutoHinter_InterfaceRec* clazz ); + /* forward declaration of PIC init functions from script classes */ #include "aflatin.h" #ifdef FT_OPTION_AUTOFIT2 @@ -49,7 +61,15 @@ if ( pic_container->autofit ) { - FT_FREE( pic_container->autofit ); + AFModulePIC* container = (AFModulePIC*)pic_container->autofit; + + + if ( container->af_services ) + FT_Destroy_Class_af_services( library, + container->af_services ); + container->af_services = NULL; + + FT_FREE( container ); pic_container->autofit = NULL; } } @@ -73,6 +93,13 @@ /* initialize pointer table - */ /* this is how the module usually expects this data */ + error = FT_Create_Class_af_services( library, + &container->af_services ); + if ( error ) + goto Exit; + + FT_Init_Class_af_service_properties( &container->af_service_properties ); + for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) { container->af_script_classes[ss] = @@ -98,8 +125,7 @@ FT_Init_Class_af_autofitter_interface( library, &container->af_autofitter_interface ); -/* Exit: */ - + Exit: if ( error ) autofit_module_class_pic_free( library ); return error; diff --git a/src/autofit/afpic.h b/src/autofit/afpic.h index 41c832a..7a07bdf 100644 --- a/src/autofit/afpic.h +++ b/src/autofit/afpic.h @@ -27,11 +27,17 @@ FT_BEGIN_HEADER #ifndef FT_CONFIG_OPTION_PIC -#define AF_SCRIPT_CLASSES_GET af_script_classes -#define AF_INTERFACE_GET af_autofitter_interface +#define AF_SERVICES_GET af_services +#define AF_SERVICE_PROPERTIES_GET af_service_properties + +#define AF_SCRIPT_CLASSES_GET af_script_classes +#define AF_INTERFACE_GET af_autofitter_interface #else /* FT_CONFIG_OPTION_PIC */ + /* some include files required for members of AFModulePIC */ +#include FT_SERVICE_PROPERTIES_H + #include "aftypes.h" /* increase these when you add new scripts, */ @@ -47,6 +53,9 @@ FT_BEGIN_HEADER typedef struct AFModulePIC_ { + FT_ServiceDescRec* af_services; + FT_Service_PropertiesRec af_service_properties; + AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT]; AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT]; FT_AutoHinter_InterfaceRec af_autofitter_interface; @@ -57,6 +66,11 @@ FT_BEGIN_HEADER #define GET_PIC( lib ) \ ( (AFModulePIC*)((lib)->pic_container.autofit) ) +#define AF_SERVICES_GET \ + ( GET_PIC( library )->af_services ) +#define AF_SERVICE_PROPERTIES_GET \ + ( GET_PIC( library)->af_service_properties ) + #define AF_SCRIPT_CLASSES_GET \ ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_script_classes ) #define AF_INTERFACE_GET \ diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index d8c7462..23af956 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -29,6 +29,7 @@ #include FT_TRUETYPE_TAGS_H #include FT_TRUETYPE_IDS_H +#include FT_SERVICE_PROPERTIES_H #include FT_SERVICE_SFNT_H #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_GLYPH_DICT_H @@ -4302,19 +4303,18 @@ { FT_Pointer result = NULL; + if ( module ) { FT_ASSERT( module->clazz && module->clazz->get_interface ); - /* first, look for the service in the module - */ + /* first, look for the service in the module */ if ( module->clazz->get_interface ) result = module->clazz->get_interface( module, service_id ); if ( result == NULL ) { - /* we didn't find it, look in all other modules then - */ + /* we didn't find it, look in all other modules then */ FT_Library library = module->library; FT_Module* cur = library->modules; FT_Module* limit = cur + library->num_modules; @@ -4383,6 +4383,116 @@ } + FT_Error + ft_property_do( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + void* value, + FT_Bool set ) + { + FT_Module* cur; + FT_Module* limit; + FT_Module_Interface interface; + + FT_Service_Properties service; + + const FT_String* set_name = "FT_Property_Set"; + const FT_String* get_name = "FT_Property_Get"; + const FT_String* func_name = set ? set_name : get_name; + + FT_Bool missing_func; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !module_name || !property_name || !value ) + return FT_Err_Invalid_Argument; + + cur = library->modules; + limit = cur + library->num_modules; + + /* search module */ + for ( ; cur < limit; cur++ ) + if ( !ft_strcmp( cur[0]->clazz->module_name, module_name ) ) + break; + + if ( cur == limit ) + { + FT_ERROR(( "%s: can't find module `%s'\n", + func_name, module_name )); + return FT_Err_Missing_Module; + } + + /* check whether we have a service interface */ + if ( !cur[0]->clazz->get_interface ) + { + FT_ERROR(( "%s: module `%s' doesn't support properties\n", + func_name, module_name )); + return FT_Err_Unimplemented_Feature; + } + + /* search property service */ + interface = cur[0]->clazz->get_interface( cur[0], + FT_SERVICE_ID_PROPERTIES ); + if ( !interface ) + { + FT_ERROR(( "%s: module `%s' doesn't support properties\n", + func_name, module_name )); + return FT_Err_Unimplemented_Feature; + } + + service = (FT_Service_Properties)interface; + + if ( set ) + missing_func = !service->set_property; + else + missing_func = !service->get_property; + + if ( missing_func ) + { + FT_ERROR(( "%s: property service of module `%s' is broken\n", + func_name, module_name )); + return FT_Err_Unimplemented_Feature; + } + + return set ? service->set_property( library, property_name, value ) + : service->get_property( library, property_name, value ); + } + + + /* documentation is in ftmodapi.h */ + + FT_Error + FT_Property_Set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + const void* value ) + { + return ft_property_do( library, + module_name, + property_name, + (void*)value, + TRUE ); + } + + + /* documentation is in ftmodapi.h */ + + FT_Error + FT_Property_Get( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + void* value ) + { + return ft_property_do( library, + module_name, + property_name, + value, + FALSE ); + } + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/
_______________________________________________ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel