/****************************************************************************
 *
 * ftdrv.h
 *
 *   FreeType internal font driver interface (specification).
 *
 * Copyright (C) 1996-2020 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 FTDRV_H_
#define FTDRV_H_


#include <freetype/ftmodapi.h>

#include "compiler-macros.h"

FT_BEGIN_HEADER


  typedef FT_Error
  (*FT_Face_InitFunc)( FT_Stream      stream,
                       FT_Face        face,
                       FT_Int         typeface_index,
                       FT_Int         num_params,
                       FT_Parameter*  parameters );

  typedef void
  (*FT_Face_DoneFunc)( FT_Face  face );


  typedef FT_Error
  (*FT_Size_InitFunc)( FT_Size  size );

  typedef void
  (*FT_Size_DoneFunc)( FT_Size  size );


  typedef FT_Error
  (*FT_Slot_InitFunc)( FT_GlyphSlot  slot );

  typedef void
  (*FT_Slot_DoneFunc)( FT_GlyphSlot  slot );


  typedef FT_Error
  (*FT_Size_RequestFunc)( FT_Size          size,
                          FT_Size_Request  req );

  typedef FT_Error
  (*FT_Size_SelectFunc)( FT_Size   size,
                         FT_ULong  size_index );

  typedef FT_Error
  (*FT_Slot_LoadFunc)( FT_GlyphSlot  slot,
                       FT_Size       size,
                       FT_UInt       glyph_index,
                       FT_Int32      load_flags );


  typedef FT_Error
  (*FT_Face_GetKerningFunc)( FT_Face     face,
                             FT_UInt     left_glyph,
                             FT_UInt     right_glyph,
                             FT_Vector*  kerning );


  typedef FT_Error
  (*FT_Face_AttachFunc)( FT_Face    face,
                         FT_Stream  stream );


  typedef FT_Error
  (*FT_Face_GetAdvancesFunc)( FT_Face    face,
                              FT_UInt    first,
                              FT_UInt    count,
                              FT_Int32   flags,
                              FT_Fixed*  advances );


  /**************************************************************************
   *
   * @struct:
   *   FT_Driver_ClassRec
   *
   * @description:
   *   The font driver class.  This structure mostly contains pointers to
   *   driver methods.
   *
   * @fields:
   *   root ::
   *     The parent module.
   *
   *   face_object_size ::
   *     The size of a face object in bytes.
   *
   *   size_object_size ::
   *     The size of a size object in bytes.
   *
   *   slot_object_size ::
   *     The size of a glyph object in bytes.
   *
   *   init_face ::
   *     The format-specific face constructor.
   *
   *   done_face ::
   *     The format-specific face destructor.
   *
   *   init_size ::
   *     The format-specific size constructor.
   *
   *   done_size ::
   *     The format-specific size destructor.
   *
   *   init_slot ::
   *     The format-specific slot constructor.
   *
   *   done_slot ::
   *     The format-specific slot destructor.
   *
   *
   *   load_glyph ::
   *     A function handle to load a glyph to a slot.  This field is
   *     mandatory!
   *
   *   get_kerning ::
   *     A function handle to return the unscaled kerning for a given pair of
   *     glyphs.  Can be set to 0 if the format doesn't support kerning.
   *
   *   attach_file ::
   *     This function handle is used to read additional data for a face from
   *     another file/stream.  For example, this can be used to add data from
   *     AFM or PFM files on a Type 1 face, or a CIDMap on a CID-keyed face.
   *
   *   get_advances ::
   *     A function handle used to return advance widths of 'count' glyphs
   *     (in font units), starting at 'first'.  The 'vertical' flag must be
   *     set to get vertical advance heights.  The 'advances' buffer is
   *     caller-allocated.  The idea of this function is to be able to
   *     perform device-independent text layout without loading a single
   *     glyph image.
   *
   *   request_size ::
   *     A handle to a function used to request the new character size.  Can
   *     be set to 0 if the scaling done in the base layer suffices.
   *
   *   select_size ::
   *     A handle to a function used to select a new fixed size.  It is used
   *     only if @FT_FACE_FLAG_FIXED_SIZES is set.  Can be set to 0 if the
   *     scaling done in the base layer suffices.
   * @note:
   *   Most function pointers, with the exception of `load_glyph`, can be set
   *   to 0 to indicate a default behaviour.
   */
  typedef struct  FT_Driver_ClassRec_
  {
    FT_Module_Class          root;

    FT_Long                  face_object_size;
    FT_Long                  size_object_size;
    FT_Long                  slot_object_size;

    FT_Face_InitFunc         init_face;
    FT_Face_DoneFunc         done_face;

    FT_Size_InitFunc         init_size;
    FT_Size_DoneFunc         done_size;

    FT_Slot_InitFunc         init_slot;
    FT_Slot_DoneFunc         done_slot;

    FT_Slot_LoadFunc         load_glyph;

    FT_Face_GetKerningFunc   get_kerning;
    FT_Face_AttachFunc       attach_file;
    FT_Face_GetAdvancesFunc  get_advances;

    /* since version 2.2 */
    FT_Size_RequestFunc      request_size;
    FT_Size_SelectFunc       select_size;

  } FT_Driver_ClassRec, *FT_Driver_Class;


  /**************************************************************************
   *
   * @macro:
   *   FT_DECLARE_DRIVER
   *
   * @description:
   *   Used to create a forward declaration of an FT_Driver_ClassRec struct
   *   instance.
   *
   * @macro:
   *   FT_DEFINE_DRIVER
   *
   * @description:
   *   Used to initialize an instance of FT_Driver_ClassRec struct.
   *
   *   `ftinit.c` (ft_create_default_module_classes) already contains a
   *   mechanism to call these functions for the default modules described in
   *   `ftmodule.h`.
   *
   *   The struct will be allocated in the global scope (or the scope where
   *   the macro is used).
   */
#define FT_DECLARE_DRIVER( class_ )  \
  FT_CALLBACK_TABLE                  \
  const FT_Driver_ClassRec  class_;

#define FT_DEFINE_DRIVER(                    \
          class_,                            \
          flags_,                            \
          size_,                             \
          name_,                             \
          version_,                          \
          requires_,                         \
          interface_,                        \
          init_,                             \
          done_,                             \
          get_interface_,                    \
          face_object_size_,                 \
          size_object_size_,                 \
          slot_object_size_,                 \
          init_face_,                        \
          done_face_,                        \
          init_size_,                        \
          done_size_,                        \
          init_slot_,                        \
          done_slot_,                        \
          load_glyph_,                       \
          get_kerning_,                      \
          attach_file_,                      \
          get_advances_,                     \
          request_size_,                     \
          select_size_ )                     \
  FT_CALLBACK_TABLE_DEF                      \
  const FT_Driver_ClassRec  class_ =         \
  {                                          \
    FT_DEFINE_ROOT_MODULE( flags_,           \
                           size_,            \
                           name_,            \
                           version_,         \
                           requires_,        \
                           interface_,       \
                           init_,            \
                           done_,            \
                           get_interface_ )  \
                                             \
    face_object_size_,                       \
    size_object_size_,                       \
    slot_object_size_,                       \
                                             \
    init_face_,                              \
    done_face_,                              \
                                             \
    init_size_,                              \
    done_size_,                              \
                                             \
    init_slot_,                              \
    done_slot_,                              \
                                             \
    load_glyph_,                             \
                                             \
    get_kerning_,                            \
    attach_file_,                            \
    get_advances_,                           \
                                             \
    request_size_,                           \
    select_size_                             \
  };


FT_END_HEADER

#endif /* FTDRV_H_ */


/* END */
