freetype-devel
[Top][All Lists]
Advanced

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

Re: [Devel] FT_Set_Hint_Flags problem


From: David Turner
Subject: Re: [Devel] FT_Set_Hint_Flags problem
Date: Wed, 07 May 2003 10:09:36 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.3) Gecko/20030312

Hi Owen,

Owen Taylor wrote:
I've attached the semi-public interfaces in Pango to the mail, as you'll
see, it's pretty high level and simple; no details of the OpenType
tables are exported other than the script/language/feature hierarchy.

Thanks a lot, I've attached a prototype header of what could become the
API of the replacement OpenType Layout code. The documentation is included
in the comments, as always. You'll notice that:

  - it's very similar to what you sent :-)

  - the caller must provide in-memory images of the various
    OTL tables to the library.

  - it doesn't include something like "otl_ruleset_shape" since
    I've not finalized a good "OTL_String" type for now.


My idea is the following:

  - port the original FreeType 1 / Pango code so that it implements
    this new API. I expect doing this with a few tricks like macro
    renaming, implementing "fake" FT_Stream to access the tables,
    etc.. but nothing that really alters the code structure.

    the idea is that Werner's code works and should be used as a
    reference implementation (including all necessary patches)


  - once the reference is completed and working, rewrite the
    implementation to use direct in-memory table parsing (after
    validation) instead.

I have actually already written much code to implement the 'new'
implementation, but I'll halt this progress for the reference right
now. One important thing is that I want the new code to have zero
dependencies on FreeType, so that we may be able to distribute it
standalone when needed.

This is also a good way to let more people test the damn thing :-)

One major difference between ICU and the freetype1 code internally
is that ICU apparently does the table parsing on-demand; that may
be a fairly big win if you have a large font with many OpenType
features, only a few of that are needed at once.

That's true, and the tables' format really seem to be designed to
be parsed directly. One important point for me is robustness however,
and the ICU code is unfortunately very fragile to broken tables, which
is why my approach will be a bit different.

Any comments welcomed,

- David Turner
- The FreeType Project  (www.freetype.org)

--
This message and any attachments (the "message") is intended solely for the
addressees and is confidential. If you receive this message in error, please
delete it and immediately notify the sender.
Any use not in accordance with its purpose, any dissemination or disclosure,
either whole or partial, is prohibited except formal approval.
The E-Mail transmission can not guarantee the integrity of this message.
CANAL+TECHNOLOGIES will not therefore be liable for the message if modified.


#ifndef __OPENTYPE_LAYOUT_H__
#define __OPENTYPE_LAYOUT_H__

#include <stddef.h>
#include "otlconf.h"

OTL_BEGIN_HEADER

 /************************************************************************/
 /************************************************************************/
 /*****                                                              *****/
 /*****                       BASE DATA TYPES                        *****/
 /*****                                                              *****/
 /************************************************************************/
 /************************************************************************/

 /************************************************************
  *
  * @type: OTL_Byte
  *
  * @description:
  *   a convenient typedef for 8-bit unsigned bytes
  */
  typedef unsigned char     OTL_Byte;

 /************************************************************
  *
  * @type: OTL_Bytes
  *
  * @description:
  *   a convenient typedef for pointers to constant bytes.
  */
  typedef const OTL_Byte*   OTL_Bytes;  /* pointer to constant bytes !! */

 /************************************************************
  *
  * @type: OTL_Error
  *
  * @description:
  *   error code types. See @OTL_ERR_XXX
  */
  typedef int               OTL_Error;

 /************************************************************
  *
  * @type: OTL_Pointer
  *
  * @description:
  *   generic pointer type
  */
  typedef void*             OTL_Pointer;

 /************************************************************
  *
  * @type: OTL_UInt
  *
  * @description:
  *   convenient typedef for the unsigned integer type
  */
  typedef unsigned int      OTL_UInt;

 /************************************************************
  *
  * @type: OTL_Int
  *
  * @description:
  *   typedef for the signed integer type. used for consistency
  */
  typedef int               OTL_Int;

 /************************************************************
  *
  * @type: OTL_Long
  *
  * @description:
  *   typedef for the signed long integer type. used for consistency
  */
  typedef long              OTL_Long;

 /************************************************************
  *
  * @type: OTL_ULong
  *
  * @description:
  *   convenient typedef for the unsigned long type
  */
  typedef unsigned long     OTL_ULong;

 /************************************************************
  *
  * @type: OTL_Int16
  *
  * @description:
  *   convenient typedef for the 16-bit signed integer type
  */
  typedef short             OTL_Int16;

 /************************************************************
  *
  * @type: OTL_UInt16
  *
  * @description:
  *   convenient typedef for the 16-bit unsigned integer type
  */
  typedef unsigned short    OTL_UInt16;


 /************************************************************
  *
  * @type: OTL_Int32
  *
  * @description:
  *   convenient typedef for the 32-bit signed integer type
  */
#if OTL_SIZEOF_INT == 4
  typedef int               OTL_Int32;
#elif OTL_SIZEOF_LONG == 4
  typedef long              OTL_Int32;
#else
#  error "no 32-bits type found"
#endif

 /************************************************************
  *
  * @type: OTL_UInt32
  *
  * @description:
  *   convenient typedef for the 32-bit unsigned integer type
  */
#if OTL_SIZEOF_INT == 4
  typedef unsigned int      OTL_UInt32;
#elif OTL_SIZEOF_LONG == 4
  typedef unsigned long     OTL_UInt32;
#else
#  error "no 32-bits type found"
#endif

 /************************************************************
  *
  * @type: OTL_Bool
  *
  * @description:
  *   convenient typedef for a boolean type
  */
  typedef int               OTL_Bool;

 /************************************************************
  *
  * @type: OTL_UInt32
  *
  * @description:
  *   convenient typedef for the 32-bit table tags per se
  *   the OpenType spec.
  */
  typedef OTL_UInt32        OTL_Tag;

 /* */
  typedef OTL_ULong         OTL_Size;

  typedef OTL_Long          OTL_SSize;

 /************************************************************************/
 /************************************************************************/
 /*****                                                              *****/
 /*****                    MEMORY MANAGEMENT                         *****/
 /*****                                                              *****/
 /************************************************************************/
 /************************************************************************/

 /************************************************************
  *
  * @type: OTL_Memory
  *
  * @description:
  *   a handle to a @OTL_MemoryRec structure used to model
  *   a given memory manager
  */
  typedef struct OTL_MemoryRec_ const *  OTL_Memory;

 /************************************************************
  *
  * @functype: OTL_Memory_AllocFunc
  *
  * @description:
  *   a callback type used to allocate memory within the
  *   OpenType Layout library. You can typecast the ISO C
  *   "malloc" to it
  *
  * @input:
  *   size     :: size of new block in bytes. always > 0
  *   mem_data :: optional user-provided data
  *
  * @return:
  *   new block address, NULL if not enough memory is available
  */
  typedef OTL_Pointer  (*OTL_Memory_AllocFunc)( OTL_Size     size,
                                                OTL_Pointer  mem_data );

 /************************************************************
  *
  * @functype: OTL_Memory_FreeFunc
  *
  * @description:
  *   a callback type used to free memory within the
  *   OpenType Layout library. You can typecast the ISO C
  *   "free" to it
  *
  * @input:
  *   block    :: target block address, never NULL
  *   mem_data :: optional user-provided data
  */
  typedef void         (*OTL_Memory_FreeFunc)( OTL_Pointer  block,
                                               OTL_Pointer  mem_data );

 /************************************************************
  *
  * @functype: OTL_Memory_ReallocFunc
  *
  * @description:
  *   a callback type used to reallocate memory within the
  *   OpenType Layout library. You can typecast the ISO C
  *   "realloc" to it
  *
  * @input:
  *   block    :: target block address, never NULL
  *   new_size :: new size in bytes
  *   mem_data :: optional user-provided data
  */
  typedef OTL_Pointer  (*OTL_Memory_ReallocFunc)( OTL_Pointer  block,
                                                  OTL_Size     new_size,
                                                  OTL_Pointer  mem_data );

 /************************************************************
  *
  * @struct: OTL_MemoryRec
  *
  * @description:
  *   a structure used to model the memory manager to the
  *   OpenType Layout library
  *
  * @fields:
  *   mem_data    :: optional user-provided pointer
  *   mem_alloc   :: memory allocation callback
  *   mem_free    :: memory release callback
  *   mem_realloc :: memory reallocation callback
  */
  typedef struct OTL_MemoryRec_
  {
    OTL_Pointer             mem_data;
    OTL_Memory_AllocFunc    mem_alloc;
    OTL_Memory_ReallocFunc  mem_realloc;
    OTL_Memory_FreeFunc     mem_free;

  } OTL_MemoryRec;

 /************************************************************************/
 /************************************************************************/
 /*****                                                              *****/
 /*****                       ERROR CODES                            *****/
 /*****                                                              *****/
 /************************************************************************/
 /************************************************************************/

 /************************************************************
  *
  * @enum: OTL_ERR_XXX
  *
  * @description:
  *   the list of error values returned by the OpenType Layout
  *   library.
  *
  * @values:
  *   OTL_ERR_OK ::
  *     value 0 always means success
  *
  *   OTL_ERR_ARGUMENT ::
  *     a function has been called with an invalid argument
  *
  *   OTL_ERR_BAD_DATA ::
  *     a function has been provided with an invalid OpenType
  *     Layout table
  *
  *   OTL_ERR_MEMORY ::
  *     there was not enough memory to perform the requested
  *     operation.
  */
  enum
  {
    OTL_ERR_OK = 0,
    OTL_ERR_ARGUMENT,
    OTL_ERR_BAD_DATA,
    OTL_ERR_MEMORY,

    OTL_ERR_MAX  /* do not remove */
  };


 /************************************************************************/
 /************************************************************************/
 /*****                                                              *****/
 /*****                    OPENTYPE LAYOUT INFO                      *****/
 /*****                                                              *****/
 /************************************************************************/
 /************************************************************************/


 /************************************************************
  *
  * @enum: OTL_TableType
  *
  * @description:
  *   the list of supported table types
  *
  * @values:
  *   OTL_TABLE_TYPE_GDEF :: glyph class definition table
  *   OTL_TABLE_TYPE_GPOS :: glyph positioning table
  *   OTL_TABLE_TYPE_GSUB :: glyph substitution table
  *   OTL_TABLE_TYPE_BASE :: baseline table
  *   OTL_TABLE_TYPE_JSTF :: justification table
  */
  typedef enum
  {
    OTL_TABLE_TYPE_GDEF,
    OTL_TABLE_TYPE_GPOS,
    OTL_TABLE_TYPE_GSUB,
    OTL_TABLE_TYPE_BASE,
    OTL_TABLE_TYPE_JSTF,

    OTL_TABLE_TYPE_MAX  /* do not remove */

  } OTL_TableType;


 /************************************************************
  *
  * @struct: OTL_TableDescRec
  *
  * @description:
  *   a small structure used to describe the in-memory image
  *   of a given OpenType Layout table to the library
  *
  * @fields:
  *   type    :: table type
  *   address :: table address, cannot be NULL
  *   size    :: table size in bytes
  */
  typedef struct OTL_TableDescRec_
  {
    OTL_TableType   type;
    OTL_Bytes       address;
    OTL_Size        size;

  } OTL_TableDescRec;


 /************************************************************
  *
  * @type: OTL_Info
  *
  * @description:
  *   opaque handle to an object used to model the information
  *   contained in one or more OpenType Layout tables
  */
  typedef struct OTL_InfoRec_*   OTL_Info;


 /************************************************************
  *
  * @function: otl_info_new
  *
  * @description:
  *   create a new @OTL_Info object from the description(s) of
  *   one or more in-memory OpenType Layout tables
  *
  * @input:
  *   tables      :: array of table descriptors
  *   table_count :: number of table descriptors in the array
  *   memory      :: memory allocator to use. NULL for standard
  *                  "malloc/free/realloc"
  *
  * @output:
  *   ainfo  :: new @OTL_Info handle, NULL in case of error
  *
  * @return:
  *   error code. 0 means success
  *
  * @note:
  *   the OpenType Layout tables may be parsed directly by the
  *   @OTL_Info object, they musn't be freed until @otl_info_free
  *   is called.
  */
  OTL_API( OTL_Error )
  otl_info_new( OTL_TableDescRec*   tables,
                OTL_UInt            table_count,
                OTL_Memory          memory,
                OTL_Info           *ainfo );

 /************************************************************
  *
  * @function: otl_info_free
  *
  * @description:
  *   release an existing @OTL_Info object
  *
  * @input:
  *   info  :: target handle
  *
  * @note:
  *   you should release the in-memory table images *after*
  *   calling this function
  */
  OTL_API( void )
  otl_info_free( OTL_Info  info );


 /************************************************************
  *
  * @function: otl_info_get_scripts
  *
  * @description:
  *   retrieve the list of scripts supported by a given
  *   @OTL_Info object
  *
  * @input:
  *   info  :: target handle
  *
  * @output:
  *   atags :: handle to an array of 4-byte tags describing
  *            the scripts
  *
  * @return:
  *   number of scripts in the array
  *
  * @note:
  *   the tags array is owned by the @OTL_Info, but its
  *   content may change in any later call to an @OTL_Info
  *   function.
  */
  OTL_API( OTL_Int )
  otl_info_get_scripts( OTL_Info    info,
                        OTL_Tag*   *atags );

 /************************************************************
  *
  * @function: otl_info_has_script
  *
  * @description:
  *   checks that an @OTL_Info supports a given script
  *
  * @input:
  *   info       :: target info handle
  *   script_tag :: 4-byte script tag
  *
  * @return:
  *   boolean. TRUE if the script tag is in the array
  *   returned by @otl_info_get_scripts
  */
  OTL_API( OTL_Bool )
  otl_info_has_script( OTL_Info   info,
                       OTL_Tag    script_tag );

 /************************************************************
  *
  * @function: otl_info_get_langsys
  *
  * @description:
  *   retrieve the list of language system tags for a given
  *   script in an @OTL_Info object
  *
  * @input:
  *   info       :: target handle
  *   script_tag :: 4-byte script tag
  *
  * @output:
  *   atags :: handle to an array of 4-byte tags describing
  *            the language systems. Certain scripts have a
  *            "default" language system identified with the
  *            special value @OTL_LANGSYS_TAG_DEFAULT
  *
  * @return:
  *   number of scripts in the array, 0 in case of error
  *   (e.g. the script tag is invalid)
  *
  * @note:
  *   the tags array is owned by the @OTL_Info, but its
  *   content may change in any later call to an @OTL_Info
  *   function.
  */

#define  OTL_LANGSYS_TAG_DEFAULT   0x0000

  OTL_API( OTL_Int )
  otl_info_get_langsys( OTL_Info    info,
                        OTL_Tag     script_tag,
                        OTL_Tag*   *atags );

 /************************************************************
  *
  * @function: otl_info_has_langsys
  *
  * @description:
  *   checks that a given language is supported by a script
  *   in an @OTL_Info object
  *
  * @input:
  *   info         :: target handle
  *   script_tag   :: 4-byte script tag
  *   langsys_tag  :: 4-byte tag of the language system
  *
  * @return:
  *   boolean. TRUE if the language system tag is in the
  *   array returned by @otl_info_get_langsys
  *
  * @note:
  *   you can use the special tag @OTL_LANGSYS_TAG_DEFAULT
  *   to check wether a script has a "default" language system
  */
  OTL_API( OTL_Bool )
  otl_info_has_langsys( OTL_Info    info,
                        OTL_Tag     script_tag,
                         OTL_Tag    langsys_tag );


 /************************************************************
  *
  * @function: otl_info_get_features
  *
  * @description:
  *   return the list of feature tags corresponding to a
  *   given (script,langsys) pair in an @OTL_Info object
  *
  * @input:
  *   info          :: target handle
  *   script_tag    :: script tag
  *   langsys_tag   :: language system tag
  *
  * @output:
  *   atags         :: pointer to an array of feature tags
  *   agpos_req_tag :: tag of the GPOS required feature
  *   agsub_req_tag :: tag of the GSUB required feature
  *
  * @return:
  *   number of tags in the 'atags' array. 0 in case of
  *   error (e.g. bad script or langsys tag)
  *
  * @note:
  *   the '*atags' array is owned by the @OTL_Info object but
  *   its content may change when any other @OTL_Info function
  *   is called
  *
  *   the special value @OTL_FEATURE_TAG_NONE is returned
  *   in 'agpos_req_tag' or 'agsub_req_tag' when there is no
  *   corresponding required feature, or when there is no
  *   corresponding GPOS or GSUB table in the parent @OTL_Info
  */
  OTL_API( OTL_Int )
  otl_info_get_features( OTL_Info   info,
                         OTL_Tag    script_tag,
                         OTL_Tag    langsys_tag,
                         OTL_Tag*  *atags,
                         OTL_Tag   *agpos_req_tag,
                         OTL_Tag   *agsub_req_tag );

#define  OTL_FEATURE_TAG_NONE   0x0000

 /************************************************************************/
 /************************************************************************/
 /*****                                                              *****/
 /*****                    OPENTYPE LAYOUT RULESETS                  *****/
 /*****                                                              *****/
 /************************************************************************/
 /************************************************************************/

 /************************************************************
  *
  * @type: OTL_RuleSet
  *
  * @description:
  *   opaque handle to an object used to model a list of
  *   "lookups" to apply to glyph strings according to the
  *   rules defined by the OpenType Layout specification
  *
  *   each ruleset is specific to a given @OTL_Info and
  *   should be freed before it
  */
  typedef struct OTL_RuleSetRec_*   OTL_RuleSet;


 /************************************************************
  *
  * @function: otl_ruleset_new
  *
  * @description:
  *   create a new ruleset from a given @OTL_Info.
  *
  * @input:
  *   info :: parent @OTL_Info
  *
  * @output:
  *   aruleset :: new ruleset handle. NULL in case of error
  *
  * @return:
  *   error code. 0 means success
  *
  * @note:
  *   the ruleset is initially empty. It should be destroyed
  *   with @otl_ruleset_free before its parent @OTL_Info
  */
  OTL_API( OTL_Error )
  otl_ruleset_new( OTL_Info      info,
                   OTL_RuleSet  *aruleset );

 /************************************************************
  *
  * @function: otl_ruleset_free
  *
  * @description:
  *   free a given ruleset.
  *
  * @input:
  *   ruleset  :: target handle. can be NULL
  */
  OTL_API( void )
  otl_ruleset_free( OTL_RuleSet  ruleset );

 /************************************************************
  *
  * @function: otl_ruleset_clear
  *
  * @description:
  *   clear a given ruleset. i.e. "empty" it
  *
  * @input:
  *   ruleset  :: target handle.
  */
  OTL_API( void )
  otl_ruleset_clear( OTL_RuleSet  ruleset );

 /************************************************************
  *
  * @function: otl_ruleset_set_feature
  *
  * @description:
  *   sets all rules corresponding to a given feature tag
  *   in a given ruleset
  *
  * @input:
  *   ruleset     :: target handle.
  *   feature_tag :: 4-byte feature tag
  *
  * @note:
  *   this function does nothing is the feature is not listed
  *   by the parent @OTL_Info. this allows you to use
  *   @OTL_FEATURE_TAG_NONE when needed.
  */
  OTL_API( void )
  otl_ruleset_set_feature( OTL_RuleSet  ruleset,
                           OTL_Tag      feature_tag );

 /* */

OTL_END_HEADER

#endif /* __OPENTYPE_LAYOUT_H__ */

reply via email to

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