freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ft-devel] controlling FreeType modules


From: Werner LEMBERG
Subject: Re: [ft-devel] controlling FreeType modules
Date: Tue, 28 Aug 2012 13:29:31 +0200 (CEST)

> 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 );
+  }
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]