From 0f8fd88e83a9a465f9433f3e0561031bb03f8980 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Thu, 30 Aug 2012 23:31:55 +0200 Subject: [PATCH] Implement properties to control FreeType modules. * include/freetype/fterrdef.h (FT_Err_Missing_Property): New error code. * include/freetype/ftmodapi.h (FT_Property_Set, FT_Property_Get): New API. * include/freetype/internal/services/svprop.h: New file. * include/freetype/internal/ftserv.h (FT_SERVICE_PROPERTIES_H): New macro. * src/base/ftobjs.c: Include FT_SERVICE_PROPERTIES_H. (ft_property_do, FT_Property_Set, FT_Property_Get): New functions. --- ChangeLog | 16 +++ include/freetype/fterrdef.h | 4 +- include/freetype/ftmodapi.h | 136 +++++++++++++++++++- include/freetype/internal/ftserv.h | 1 + include/freetype/internal/services/svprop.h | 81 ++++++++++++ src/base/ftobjs.c | 118 ++++++++++++++++- 6 files changed, 346 insertions(+), 10 deletions(-) create mode 100644 include/freetype/internal/services/svprop.h diff --git a/ChangeLog b/ChangeLog index 394168395..0322f01a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2012-08-30 Werner Lemberg + + Implement properties to control FreeType modules. + + * include/freetype/fterrdef.h (FT_Err_Missing_Property): New error + code. + * include/freetype/ftmodapi.h (FT_Property_Set, FT_Property_Get): + New API. + + * include/freetype/internal/services/svprop.h: New file. + * include/freetype/internal/ftserv.h (FT_SERVICE_PROPERTIES_H): New + macro. + + * src/base/ftobjs.c: Include FT_SERVICE_PROPERTIES_H. + (ft_property_do, FT_Property_Set, FT_Property_Get): New functions. + 2012-08-29 Werner Lemberg [docmaker] Allow `-' in tags and identifiers. diff --git a/include/freetype/fterrdef.h b/include/freetype/fterrdef.h index fb4b53bca..bb06d79e9 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 4cb089dba..aedfc54df 100644 --- a/include/freetype/ftmodapi.h +++ b/include/freetype/ftmodapi.h @@ -42,14 +42,15 @@ FT_BEGIN_HEADER /* Module Management */ /* */ /* */ - /* How to add, upgrade, and remove modules from FreeType. */ + /* How to add, upgrade, remove, and control modules from FreeType. */ /* */ /* */ /* 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, 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 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 ); + + /*************************************************************************/ /* */ /* */ @@ -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 658b21509..66395d8f4 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 #define FT_SERVICE_POSTSCRIPT_INFO_H #define FT_SERVICE_POSTSCRIPT_NAME_H +#define FT_SERVICE_PROPERTIES_H #define FT_SERVICE_SFNT_H #define FT_SERVICE_TRUETYPE_ENGINE_H #define FT_SERVICE_TT_CMAP_H diff --git a/include/freetype/internal/services/svprop.h b/include/freetype/internal/services/svprop.h new file mode 100644 index 000000000..4d40c1cdc --- /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/base/ftobjs.c b/src/base/ftobjs.c index d8c746281..23af95695 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 ); + } + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/