(*******************************************************************
 *
 *  FreeType.Pas
 *
 *    High-level interface specification.
 *
 *  Copyright 1996 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.
 *
 *  Notes :
 *
 *    This is the only file that should be included by client
 *    application sources for the final release. All other types
 *    and functions defined in the "tt*.h" files are library
 *    internals, and should not be included ( except of course
 *    during development, as now )
 *
 ******************************************************************)

unit FreeType;

interface

type

{$IFDEF OS2}
  TT_Int    = Longint;
{$ELSE}
  TT_Int    = Integer;
{$ENDIF}

  TT_Long   = longint;
  TT_ULong  = longint;  (* there are no unsigned longs in Pascal :-(        *)
                        (* it will probably be a good idea to use cardinals *)
                        (* with Delphi and Virtual a bit later..            *)
  TT_Short  = integer;
  TT_UShort = word;

  TT_Fixed  = LongInt;  (* Signed Fixed 16.16 Float *)

  TT_FWord  = Integer;  (* Distance in FUnits *)
  TT_UFWord = Word;     (* Unsigned Distance  *)

  TT_F2Dot14 = Integer; (* signed fixed float 2.14 used for *)
                        (* unary vectors, with layout :     *)
                        (*                                  *)
                        (*  s : 1  -- sign bit              *)
                        (*  m : 1  -- mantissa bit          *)
                        (*  f : 14 -- unsigned fractional   *)
                        (*                                  *)
                        (*  's:m' is the 2-bit signed int   *)
                        (*  value to which the *positive*   *)
                        (*  fractional part should be       *)
                        (*  added.                          *)
                        (*                                  *)

  TT_F26Dot6 = LongInt; (* 26.6 fixed float, used for pixel coordinates *)

  (******************************************************)
  (*  a simple unit vector type                         *)
  (*                                                    *)
  TT_UnitVector = record

      x : TT_F2Dot14;
      y : TT_F2Dot14;
  end;

  (******************************************************)
  (*  a simple vector type                              *)
  (*                                                    *)
  TT_Vector = record

      x : TT_F26Dot6;
      y : TT_F26Dot6;
  end;

  (******************************************************)
  (*  a simple 2x2 matrix type                          *)
  (*                                                    *)
  TT_Matrix = record

      xx, xy : TT_Fixed;
      yx, yy : TT_Fixed;
  end;

  (******************************************************)
  (*  the engine's error condition type - 0 always      *)
  (*  means success.                                    *)
  (*                                                    *)
  TT_Error = TT_Int;


  TT_Coordinates  = array[0..99] of TT_F26dot6;
  TT_PCoordinates = ^TT_Coordinates;

  TT_TouchTable   = array[0..9] of byte;
  TT_PTouchTable  = ^TT_TouchTable;

  TT_ConStarts  = array[0..9] of word;
  TT_PConStarts = ^TT_ConStarts;

  (******************************************************)
  (*  glyph outline description                         *)
  (*                                                    *)
  TT_Outline = record

      points    : Integer;          (* number of points         *)
      contours  : Integer;          (* number of contours       *)

      xCoord    : TT_PCoordinates;  (* array of x coordinates   *)
      yCoord    : TT_PCoordinates;  (* array of y coordinates   *)
      flag      : TT_PTouchTable;   (* array of point flags     *)

      conEnds   : TT_PConStarts;    (* array of contours starts *)

      owner     : Boolean;          (* this flag is set when the outline *)
                                    (* owns the arrays it uses.          *)

      high_precision : Boolean;
      second_pass    : Boolean;
      dropout_mode   : Byte;
  end;

  (******************************************************)
  (*  glyph metrics structure                           *)
  (*                                                    *)
  TT_Glyph_Metrics = record

      leftSideBearing : TT_F26dot6;
      advanceWidth    : TT_F26dot6;

      xMin : TT_F26dot6;
      yMin : TT_F26dot6;
      xMax : TT_F26dot6;
      yMax : TT_F26dot6;
  end;

  (******************************************************)
  (*  instance metrics. used to return information to   *)
  (*  clients regarding an instance's important state   *)
  (*                                                    *)
  TT_Instance_Metrics = record

      pointsize    : integer;

      x_ppem       : integer;
      y_ppem       : integer;

      x_scale      : TT_Fixed;
      y_scale      : TT_Fixed;

      x_resolution : integer;
      y_resolution : integer;
  end;

const
  TT_Flow_Down = -1;
  TT_Flow_Up   = +1;

type

  (******************************************************)
  (*  a record used to describe a bitmap or pixmap to   *)
  (*  the rasterizer.                                   *)
  (*                                                    *)
  TT_Raster_Map  = record

      Rows   : longint;      (* rows number of the bitmap    *)
      Cols   : longint;      (* columns (bytes) per row      *)
      Width  : longint;      (* pixels per row               *)
      Buffer : pointer;      (* bit/pixmap data              *)
      Size   : longint;      (* bit/pixmap data size (bytes) *)
      Flow   : longint;      (* bit/pixmap's flow            *)
  end;

  (******************************************************)
  (*  The TrueType font header table structure          *)
  (*                                                    *)
  TT_Header = record

      table_version   : TT_Fixed;
      font_revision   : TT_Fixed;

      checksum_adjust : TT_Long;
      magic_number    : TT_Long;

      flags           : TT_UShort;
      units_per_EM    : TT_UShort;

      created         : array[0..1] of TT_Long;
      modified        : array[0..1] of TT_Long;

      xMin, yMin      : TT_FWord;
      xMax, yMax      : TT_FWord;

      mac_style       : TT_UShort;
      lowest_rec_PPEM : TT_UShort;
      font_direction  : TT_Short;

      index_to_loc_format : TT_Short;
      glyph_data_format   : TT_Short;
  end;

  (******************************************************)
  (*  The TrueType horizontal header table structure    *)
  (*                                                    *)
  TT_Horizontal_Header = record

      version   : TT_Fixed;
      ascender  : TT_FWord;
      descender : TT_FWord;
      line_gap  : TT_FWord;

      advance_Width_Max      : TT_UShort;
      min_left_side_bearing  : TT_Short;
      min_right_side_bearing : TT_Short;
      xMax_extent            : TT_Short;
      caret_slope_rise       : TT_Short;
      caret_slope_run        : TT_Short;

      reserved  : array[0..4] of TT_SHort;

      metric_data_format     : TT_Short;
      number_of_HMetrics     : TT_UShort;
  end;

  (******************************************************)
  (*  The TrueType OS/2 table structure                 *)
  (*                                                    *)
  TT_OS2 = record
      version             : TT_UShort;   (* $0001 *)
      xAvgCharWidth       : TT_Short;
      usWeightClass       : TT_UShort;
      usWidthClass        : TT_UShort;
      fsType              : TT_Short;
      ySubscriptXSize     : TT_Short;
      ySubscriptYSize     : TT_Short;
      ySubScriptXOffset   : TT_Short;
      ySubscriptYOffset   : TT_Short;
      ySuperscriptXSize   : TT_Short;
      ySuperscriptYSize   : TT_Short;
      ySuperscriptXOffset : TT_Short;
      ySuperscriptYOffset : TT_Short;
      yStrikeoutSize      : TT_Short;
      yStrikeoutPosition  : TT_Short;
      sFamilyClass        : TT_Short;
      panose              : array[0..9] of Byte;
      ulUnicodeRange1     : TT_ULong;   (* bits  0-31  *)
      ulUnicodeRange2     : TT_ULong;   (* bits 32-63  *)
      ulUnicodeRange3     : TT_ULong;   (* bits 64-95  *)
      ulUnicodeRange4     : TT_ULong;   (* bits 96-127 *)
      achVendID           : array[0..3] of Byte;
      fsSelection         : TT_UShort;
      usFirstCharIndex    : TT_UShort;
      usLastCharIndex     : TT_UShort;
      sTypoAscender       : TT_UShort;
      sTypoDescender      : TT_UShort;
      sTypoLineGap        : TT_UShort;
      usWinAscent         : TT_UShort;
      usWinDescent        : TT_UShort;

      (* only version 1 tables *)
      ulCodePageRange1    : TT_ULong;
      ulCodePageRange2    : TT_ULong;
  end;

  (******************************************************)
  (*  The TrueType Postscript table structure           *)
  (*                                                    *)
  TT_Postscript = record

      FormatType         : TT_Fixed;
      italicAngle        : TT_Fixed;
      underlinePosition  : TT_Short;
      underlineThickness : TT_Short;
      isFixedPitch       : TT_ULong;
      minMemType42       : TT_ULong;
      maxMemType42       : TT_ULong;
      minMemType1        : TT_ULong;
      maxMemType1        : TT_ULong;
  end;

  (******************************************************)
  (*  face properties. use to report important face     *)
  (*  data to clients                                   *)
  (*                                                    *)
  TT_Face_Properties = record

      num_glyphs   : integer;
      max_points   : integer;
      max_contours : integer;
      max_faces    : integer;

      header       : ^TT_Header;
      horizontal   : ^TT_Horizontal_Header;
      os2          : ^TT_OS2;
      postscript   : ^TT_Postscript;
  end;

  (******************************************************)
  (*  Objects handle types                              *)
  (*                                                    *)
  TT_Stream   = record z : Pointer; end;
  TT_Face     = record z : Pointer; end;
  TT_Instance = record z : Pointer; end;
  TT_Glyph    = record z : Pointer; end;
  TT_CharMap  = record z : Pointer; end;

  TT_Gray_Palette = array[0..4] of byte;

  (******************************************************************)
  (*                                                                *)
  (*                         ERROR CODES                            *)
  (*                                                                *)
  (******************************************************************)

const
  (* ------------------- Success is always 0 ---------------------- *)

  TT_Err_Ok                      =  0;

  (* -------------------------------------------------------------- *)

  TT_Err_Invalid_Face_Handle     = $0001;
  TT_Err_Invalid_Instance_Handle = $0002;
  TT_Err_Invalid_Glyph_Handle    = $0003;
  TT_Err_Invalid_CharMap_Handle  = $0004;
  TT_Err_Invalid_Result_Address  = $0005;
  TT_Err_Invalid_Glyph_Index     = $0006;
  TT_Err_Invalid_Argument        = $0007;
  TT_Err_Could_Not_Open_File     = $0008;
  TT_Err_File_Is_Not_Collection  = $0009;

  TT_Err_Table_Missing           = $000A;
  TT_Err_Invalid_Horiz_Metrics   = $000B;
  TT_Err_Invalid_CharMap_Format  = $000C;

  TT_Err_Invalid_File_Format     = $0010;
  TT_Err_File_Error              = $0011;

  TT_Err_Invalid_Engine          = $0020;
  TT_Err_Too_Many_Extensions     = $0021;
  TT_Err_Extensions_Unsupported  = $0022;
  TT_Err_Invalid_Extension_Id    = $0023;

  TT_Err_Max_Profile_Missing     = $0080;
  TT_Err_Header_Table_Missing    = $0081;
  TT_Err_Horiz_Header_Missing    = $0082;
  TT_Err_Locations_Missing       = $0083;
  TT_Err_Name_Table_Missing      = $0084;
  TT_Err_CMap_Table_Missing      = $0085;
  TT_Err_Hmtx_Table_Missing      = $0086;
  TT_Err_OS2_Table_Missing       = $0087;
  TT_Err_Post_Table_Missing      = $0088;

  (* -------------------------------------------------------------- *)

  TT_Err_Out_Of_Memory           = $0100;

  (* -------------------------------------------------------------- *)

  TT_Err_Invalid_File_Offset     = $0200;
  TT_Err_Invalid_File_Read       = $0201;
  TT_Err_Invalid_Frame_Access    = $0202;

  (* -------------------------------------------------------------- *)

  TT_Err_Too_Many_Points         = $0300;
  TT_Err_Too_Many_Contours       = $0301;
  TT_Err_Invalid_Composite       = $0302;
  TT_Err_Too_Many_Ins            = $0303;

  (* -------------------------------------------------------------- *)

  TT_Err_Invalid_Opcode          = $0400;
  TT_Err_Too_Few_Arguments       = $0401;
  TT_Err_Stack_Overflow          = $0402;
  TT_Err_Code_Overflow           = $0403;
  TT_Err_Bad_Argument            = $0404;
  TT_Err_Divide_By_Zero          = $0405;
  TT_Err_Storage_Overflow        = $0406;
  TT_Err_Cvt_Overflow            = $0407;
  TT_Err_Invalid_Reference       = $0408;
  TT_Err_Invalid_Distance        = $0409;
  TT_Err_Interpolate_Twilight    = $040A;
  TT_Err_Debug_Opcode            = $040B;
  TT_Err_ENDF_In_Exec_Stream     = $040C;
  TT_Err_Out_Of_CodeRanges       = $040D;
  TT_Err_Nested_DEFs             = $040E;
  TT_Err_Invalid_CodeRange       = $040F;
  TT_Err_Invalid_Displacement    = $0410;

  TT_Err_Nested_Frame_Access     = $0500;
  TT_Err_Invalid_Cache_List      = $0501;
  TT_Err_Could_Not_Find_Context  = $0502;
  TT_Err_UNlisted_Object         = $0503;

  TT_Err_Raster_Pool_Overflow    = $0600;
  TT_Err_Raster_Negative_Height  = $0601;
  TT_Err_Invalid_Value           = $0602;
  TT_Err_Raster_Not_Initialised  = $0603;

  (* -------------------------------------------------------------- *)

  (***********************************************************************)
  (*                                                                     *)
  (*                  Base Library Functions                             *)
  (*                                                                     *)
  (***********************************************************************)

  (*****************************************************************)
  (*  Initialise the engine                                        *)
  (*                                                               *)
  function TT_Init_FreeType : TT_Error;

  (*****************************************************************)
  (*  Finalise the engine - discards all objects                   *)
  (*                                                               *)
  procedure TT_Done_FreeType;

  (*****************************************************************)
  (*  Set the gray-level palette used for font-smoothing           *)
  (*                                                               *)
  (*  it is an array of 5 bytes following this convention :        *)
  (*                                                               *)
  (*    palette[0] := background (white)                           *)
  (*    palette[1] := light                                        *)
  (*    palette[2] := medium                                       *)
  (*    palette[3] := dark                                         *)
  (*    palette[4] := foreground (black)                           *)
  (*                                                               *)
  function TT_Set_Raster_Palette( palette : TT_Gray_Palette ) : TT_Error;

  (***********************************************************************)
  (*                                                                     *)
  (*                    Face Management functions                        *)
  (*                                                                     *)
  (***********************************************************************)

  (*****************************************************************)
  (*  Open a new font file and returns a handle for it in '_face'  *)
  (*                                                               *)
  (*  The file can be a TrueType collection, in which case the     *)
  (*  first embedded font will be loaded.                          *)
  (*                                                               *)
  function TT_Open_Face( fontname  : string;
                         var _face : TT_Face ) : TT_Error;

  (*****************************************************************)
  (*  Open a font file embedded in a collection.                   *)
  (*                                                               *)
  function TT_Open_Collection( fontname  : string;
                               faceIndex : integer;
                               var _face : TT_Face ) : TT_Error;

  (*****************************************************************)
  (*  Return face properties in 'prop'                             *)
  (*                                                               *)
  function TT_Get_Face_Properties( _face    : TT_Face;
                                   var prop : TT_Face_Properties ) : TT_Error;

  (*****************************************************************)
  (*  Set face's generic pointer                                   *)
  (*                                                               *)
  function TT_Set_Face_Pointer( _face : TT_Face;
                                data  : Pointer ) : TT_Error;

  (*****************************************************************)
  (*  Get face's generic pointer                                   *)
  (*                                                               *)
  function TT_Get_Face_Pointer( _face : TT_Face ) : Pointer;

  (*****************************************************************)
  (*  close a given face object. This releases all child objects   *)
  (*  like instances and glyphs                                    *)
  (*                                                               *)
  function TT_Close_Face( _face : TT_Face ) : TT_Error;

  (***********************************************************************)
  (*                                                                     *)
  (*                  Instance management functions                      *)
  (*                                                                     *)
  (***********************************************************************)

  (*****************************************************************)
  (*  open a new face instance and return a handle in '_ins'       *)
  (*                                                               *)
  function TT_New_Instance( _face    : TT_Face;
                            var _ins : TT_Instance ) : TT_Error;

  (*****************************************************************)
  (*  set an instance's device resolutions, expressed in dpi       *)
  (*                                                               *)
  function TT_Set_Instance_Resolutions( _ins         : TT_Instance;
                                        x_resolution : Integer;
                                        y_resolution : Integer ) : TT_Error;

  (*****************************************************************)
  (*  set an instance's point size (assumes width==height)         *)
  (*                                                               *)
  function TT_Set_Instance_PointSize( _ins      : TT_Instance;
                                      pointsize : Integer ) : TT_Error;

  (*****************************************************************)
  (*  set an instance's point size (assumes width==height)         *)
  (*                                                               *)
  function TT_Set_Instance_CharSize( _ins     : TT_Instance;
                                     charsize : Integer ) : TT_Error;

  (*****************************************************************)
  (*  set an instance's point size (assumes width==height)         *)
  (*                                                               *)
  function TT_Set_Instance_CharSizes( _ins      : TT_Instance;
                                      charsizex : Integer;
                                      charsizey : Integer ) : TT_Error;

  (*****************************************************************)
  (*  set an instance's height and width, expressed in pixels      *)
  (*                                                               *)
  function TT_Set_Instance_PixelSizes( _ins      : TT_Instance;
                                       pixelX    : Integer;
                                       pixelY    : Integer;
                                       pointsize : Integer ) : TT_Error;

  (*****************************************************************)
  (*  set an instance's height and width, expressed in pixels      *)
  (*                                                               *)

  (*****************************************************************)
  (*  the core truetype engine doesn't provide _direct_ support    *)
  (*  for rotation or stretching. This means that the transforms   *)
  (*  must be applied on the glyph outline by a higher-level       *)
  (*  library or the client application. However, we use two flags *)
  (*  to notice the TrueType hinter that the glyphs will be        *)
  (*  transformed later.                                           *)
  (*                                                               *)
  (*    rotated   : set if the glyphs are to be rotated            *)
  (*    distorted : set if the glyphs are to be distorted          *)
  (*                                                               *)
  (*  an application is any transform that doesn't keep distances  *)
  (*  constants. skewing and stretching are examples of distorsion *)
  (*                                                               *)
  function TT_Set_Instance_Transforms( _ins      : TT_Instance;
                                       rotated   : Boolean;
                                       distorted : Boolean ) : TT_Error;

  (*****************************************************************)
  (*  Return instance metrics in 'm'                               *)
  (*                                                               *)
  function TT_Get_Instance_Metrics( _ins  : TT_Instance;
                                    var m : TT_Instance_Metrics ) : TT_Error;

  (*****************************************************************)
  (*  Set instance generic pointer                                 *)
  (*                                                               *)
  function TT_Set_Instance_Pointer( _ins : TT_Instance;
                                    data : Pointer ) : TT_Error;

  (*****************************************************************)
  (*  Get instance generic pointer                                 *)
  (*                                                               *)
  function TT_Get_Instance_Pointer( _ins : TT_Instance ) : Pointer;

  (*****************************************************************)
  (*  Close an instance                                            *)
  (*                                                               *)
  function TT_Done_Instance( _ins : TT_Instance ) : TT_Error;

  (***********************************************************************)
  (*                                                                     *)
  (*                  Glyph management functions                         *)
  (*                                                                     *)
  (***********************************************************************)

  (*****************************************************************)
  (*  Create a new glyph container, return a handle in '_glyph'    *)
  (*                                                               *)
  function TT_New_Glyph( _face      : TT_Face;
                         var _glyph : TT_Glyph ) : TT_Error;

  (*****************************************************************)
  (*  Releases a glyph container                                   *)
  (*                                                               *)
  function TT_Done_Glyph( _glyph : TT_Glyph ) : TT_Error;

  (*****************************************************************)
  (*  Load a glyph inside a container                              *)
  (*                                                               *)
  function  TT_Load_Glyph( _instance   : TT_Instance;
                           _glyph      : TT_Glyph;
                           glyph_index : Integer;
                           load_flags  : Integer ) : TT_Error;

const
  TT_Load_Scale_Glyph = 1;  (* ask the loader to scale the glyph  *)
                            (* to the current pointsize/transform *)

  TT_Load_Hint_Glyph  = 2;  (* when scaling is on, ask the loader *)
                            (* to hint the glyph too..            *)

  TT_Load_Debug       = 16;

  TT_Load_Default     = TT_Load_Scale_Glyph or
                        TT_Load_Hint_Glyph;


  (*****************************************************************)
  (*  Get a glyph's outline                                        *)
  (*                                                               *)
  function TT_Get_Glyph_Outline( _glyph      : TT_Glyph;
                                 var outline : TT_Outline ) : TT_Error;

  (*****************************************************************)
  (*  Get a glyph's metrics                                        *)
  (*                                                               *)
  function TT_Get_Glyph_Metrics( _glyph       : TT_Glyph;
                                 var gmetrics : TT_Glyph_Metrics ) : TT_Error;

  (*****************************************************************)
  (*  Render a glyph's bitmap                                      *)
  (*                                                               *)
  function TT_Get_Glyph_Bitmap( _glyph   : TT_Glyph;
                                var map  : TT_Raster_Map;
                                x_offset : TT_F26Dot6;
                                y_offset : TT_F26Dot6 ) : TT_Error;

  (*****************************************************************)
  (*  Render a glyph's pixmap (i.e. smoothed glyph )               *)
  (*                                                               *)
  function TT_Get_Glyph_Pixmap( _glyph   : TT_Glyph;
                                var map  : TT_Raster_Map;
                                x_offset : TT_F26Dot6;
                                y_offset : TT_F26Dot6 ) : TT_Error;

  (***********************************************************************)
  (*                                                                     *)
  (*                      Outline functions                              *)
  (*                                                                     *)
  (***********************************************************************)

  (*****************************************************************)
  (*  Apply translation to an outline                              *)
  (*                                                               *)
  function TT_Translate_Outline( var out : TT_Outline;
                                 x, y    : TT_F26Dot6 ) : TT_Error;

  (*****************************************************************)
  (*  Apply a 2x2 transform to an outline                          *)
  (*                                                               *)
  function TT_Transform_Outline( var out : TT_Outline;
                                 var mat : TT_Matrix ) : TT_Error;

  (*****************************************************************)
  (*  Apply a 2x2 transform to a vector                            *)
  (*                                                               *)
  function TT_Transform_Vector( var x, y : TT_F26Dot6;
                                var mat  : TT_Matrix ) : TT_Error;

  (*****************************************************************)
  (*  Render an outline into a bitmap                              *)
  (*                                                               *)
  function TT_Get_Outline_Bitmap( var out : TT_Outline;
                                  var map : TT_raster_Map ) : TT_Error;

  (*****************************************************************)
  (*  Render an outline into a pixmap                              *)
  (*                                                               *)
  function TT_Get_Outline_Pixmap( var out : TT_Outline;
                                  var map : TT_raster_Map ) : TT_Error;

  (*****************************************************************)
  (*  Create a new glyph outline                                   *)
  (*                                                               *)
  function TT_New_Outline( n_points   : integer;
                           n_contours : integer;
                           var out    : TT_Outline ) : TT_Error;

  (*****************************************************************)
  (*  Copy a glyph outline into another one                        *)
  (*                                                               *)
  function TT_Copy_Outline( var source : TT_Outline;
                            var target : TT_Outline ) : TT_Error;

  (*****************************************************************)
  (*  Clone a given outline. This will create the outline, then    *)
  (*  copy the source in it                                        *)
  (*                                                               *)
  function TT_Clone_Outline( var source : TT_Outline;
                             var target : TT_Outline ) : TT_Error;

  (*****************************************************************)
  (*  Discards a glyph outline                                     *)
  (*                                                               *)
  function TT_Done_Outline( var out : TT_Outline ) : TT_Error;

  (***********************************************************************)
  (*                                                                     *)
  (*                     Character Mapping support                       *)
  (*                                                                     *)
  (***********************************************************************)

  (*****************************************************************)
  (*  Get a face's number of character maps                        *)
  (*                                                               *)
  function  TT_Get_CharMap_Count( face : TT_Face ) : integer;

  (*****************************************************************)
  (*  Get a given char. map's ID in a face                         *)
  (*                                                               *)
  function  TT_Get_CharMap_ID( face         : TT_Face;
                               charmapIndex : integer;
                               var platform : integer;
                               var encoding : integer ) : TT_Error;

  (*****************************************************************)
  (*  Get a handle to a given char. map                            *)
  (*                                                               *)
  function  TT_Get_CharMap( face         : TT_Face;
                            charmapIndex : integer;
                            var charMap  : TT_CharMap ) : TT_Error;

  (*****************************************************************)
  (*  Translate from char. code to glyph index                     *)
  (*                                                               *)
  function  TT_Char_Index( charmap  : TT_CharMap;
                           charCode : word ) : integer;

  (***********************************************************************)
  (*                                                                     *)
  (*                        Names Table support                          *)
  (*                                                                     *)
  (***********************************************************************)

  (*****************************************************************)
  (*  Return number of name table entries                          *)
  (*                                                               *)
  function  TT_Get_Name_Count( face : TT_Face ) : integer;

  (*****************************************************************)
  (*  Return the ID of a given name table entry                    *)
  (*                                                               *)
  function  TT_Get_Name_ID( face         : TT_Face;
                            nameIndex    : integer;
                            var platform : integer;
                            var encoding : integer;
                            var language : integer;
                            var nameid   : integer ) : TT_Error;

  (*****************************************************************)
  (*  Return a given name table string                             *)
  (*                                                               *)
  function  TT_Get_Name_String( face      : TT_Face;
                                nameIndex : integer;
                                var str   : Pointer;
                                var len   : integer ) : TT_Error;

  (***********************************************************************)
  (*                                                                     *)
  (*                        Font Storage Access                          *)
  (*                                                                     *)
  (***********************************************************************)

  (*****************************************************************)
  (*  Access font data and copies it into user block               *)
  (*                                                               *)
  function  TT_Get_Font_Data( face       : TT_Face;
                              tableTag   : Longint;
                              offset     : Longint;
                              var buffer;
                              var length : longint ) : TT_Error;

implementation

uses
  TTTypes,
  TTError,
  TTCalc,
  TTMemory,
  TTLists,
  TTCache,
  TTFile,
  TTCMap,
  TTObjs,
  TTLoad,
  TTGLoad,
  TTRaster,
  TTInterp;

var
  raster_palette : TT_Gray_Palette;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Init_FreeType : TT_Error;
  begin
    if TTMemory_Init or
       TTLists_Init  or
       TTFile_Init   or
       TTObjs_Init   or
       TTRaster_Init then
    begin
      TT_Init_FreeType := error;
      exit;
    end;

    TT_Init_FreeType := TT_Err_Ok;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  procedure TT_Done_FreeType;
  begin
    TTRaster_Done;
    TTObjs_Done;
    TTFile_Done;
    TTLists_Done;
    TTMemory_Done;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Set_Raster_Palette( palette : TT_Gray_Palette ) : TT_Error;
  begin
    raster_palette := palette;
    TT_Set_Raster_Palette := TT_Err_Ok;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Open_Face( fontname  : string;
                         var _face : TT_Face ) : TT_Error;
  var
    input        : TFont_Input;
  begin
    input.fontIndex := 0;

    if TT_Open_Stream( fontname, input.stream ) then
    begin
      TT_Open_Face    := error;
      exit;
    end;

    Cache_New( objs_face_cache^, Pointer(_face), @input );

    TT_Open_Face := error;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Open_Collection( fontname  : string;
                               faceIndex : integer;
                               var _face : TT_Face ) : TT_Error;
  var
    input : TFont_Input;
  begin
    input.fontIndex := faceIndex;

    if TT_Open_Stream( fontname, input.stream ) then
    begin
      TT_Open_Collection := error;
      exit;
    end;

    Cache_New( objs_face_cache^, Pointer(_face), @input );

    TT_Open_Collection := error;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Get_Face_Properties( _face    : TT_Face;
                                   var prop : TT_Face_Properties ) : TT_Error;
  var
    face : PFace;
  begin
    face := _face.z;
    if face <> nil then
    begin
      with prop do
      begin
        num_Glyphs   := face^.numGlyphs;
        max_Points   := face^.maxPoints;
        max_Contours := face^.maxContours;
        max_Faces    := face^.ttcHeader.dirCount;
        header       := @face^.fontHeader;
        horizontal   := @face^.horizontalHeader;
        os2          := @face^.os2;
        postscript   := @face^.postscript;
      end;
      TT_Get_Face_Properties := TT_Err_Ok;
    end
    else
      TT_Get_Face_Properties := TT_Err_Invalid_Face_Handle;
  end;


  (*****************************************************************)
  (*  Set face's generic pointer                                   *)
  (*                                                               *)
  function TT_Set_Face_Pointer( _face : TT_Face;
                                data  : Pointer ) : TT_Error;
  var
    face :PFace;
  begin
    face := PFace(_face.z);
    if face <> nil then
      begin
        face^.generic       := data;
        TT_Set_Face_Pointer := TT_Err_Ok;
      end
    else
      TT_Set_Face_Pointer := TT_Err_Invalid_Face_Handle;
  end;

  (*****************************************************************)
  (*  Get face's generic pointer                                   *)
  (*                                                               *)
  function TT_Get_Face_Pointer( _face : TT_Face ) : Pointer;
  var
    face : PFace;
  begin
    face := PFace(_face.z);
    if face <> nil then
      TT_Get_Face_Pointer := face^.generic
    else
      TT_get_Face_Pointer := nil;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Close_Face( _face : TT_Face ) : TT_Error;
  var
    face : PFace;
  begin
    face := _face.z;
    if face <> nil then
      begin
        error := TT_Err_Ok;
        Cache_Done( objs_face_cache^, _face.z );
        TT_Close_Face := error;
      end
    else
      TT_Close_Face := TT_Err_Invalid_Face_Handle;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_New_Instance( _face    : TT_Face;
                            var _ins : TT_Instance ) : TT_Error;
  var
    face : PFace;
    ins  : PInstance;
  begin
    face := _face.z;
    if face <> nil then
      begin
        error := TT_Err_Ok;
        if not Cache_New( face^.instances, _ins.z, face ) then
          Instance_Init( _ins.z );
        TT_New_Instance := error;
      end
    else
      TT_New_Instance := TT_Err_Invalid_Face_Handle;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Set_Instance_Resolutions( _ins         : TT_Instance;
                                        x_resolution : Integer;
                                        y_resolution : Integer ) : TT_Error;
  var
    ins : PInstance;
  begin
    ins := _ins.z;
    if ins <> nil then
      begin
        ins^.metrics.x_resolution   := x_resolution;
        ins^.metrics.y_resolution   := y_resolution;
        ins^.valid                  := False;
        TT_Set_Instance_Resolutions := TT_Err_Ok;
      end
    else
        TT_Set_Instance_Resolutions := TT_Err_Invalid_Instance_Handle;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Set_Instance_CharSize( _ins     : TT_Instance;
                                     charsize : Integer ) : TT_Error;
  var
    ins : PInstance;
  begin
    TT_Set_Instance_CharSize :=
      TT_Set_Instance_CharSizes( _ins, charsize, charsize );
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Set_Instance_CharSizes( _ins      : TT_Instance;
                                      charsizex : Integer;
                                      charsizey : Integer ) : TT_Error;
  var
    ins : PInstance;
  begin
    if (charsizex < 1*64) or (charsizey < 1*64) then
      begin
        TT_Set_Instance_CharSizes := TT_Err_Bad_Argument;
        exit;
      end;

    ins := _ins.z;
    if ins <> nil then
      begin
        with ins^.metrics do
        begin
          x_ppem   := ( charsizex * x_resolution + 36*64 ) div (72*64);
          x_scale1 := x_ppem*64;
          x_scale2 := ins^.owner^.fontHeader.units_per_EM;

          y_ppem   := ( charsizey * y_resolution + 36*64 ) div (72*64);
          y_scale1 := y_ppem*64;
          y_scale2 := x_scale2;
        end;

        if charsizex > charsizey then
          ins^.metrics.pointsize  := charsizex
        else
          ins^.metrics.pointsize  := charsizey;

        ins^.valid                := False;
        TT_Set_Instance_CharSizes := TT_Err_Ok;
      end
    else
      TT_Set_Instance_CharSizes := TT_Err_Invalid_Instance_Handle;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Set_Instance_PointSize( _ins      : TT_Instance;
                                      pointsize : integer ) : TT_Error;
  begin
    TT_Set_Instance_PointSize :=
      TT_Set_Instance_CharSize( _ins, pointsize*64 );
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Set_Instance_PixelSizes( _ins      : TT_Instance;
                                       pixelX    : Integer;
                                       pixelY    : Integer;
                                       pointsize : Integer ) : TT_Error;
  var
    ins : PInstance;
  begin
    ins := _ins.z;
    if ins <> nil then
      begin
        ins^.metrics.x_ppem    := pixelX;
        ins^.metrics.y_ppem    := pixelY;
        ins^.metrics.pointSize := pointsize;

        ins^.metrics.x_scale1  := ins^.metrics.x_ppem * 64;
        ins^.metrics.x_scale2  := ins^.owner^.fontHeader.units_per_EM;
        ins^.metrics.y_scale1  := ins^.metrics.y_ppem * 64;
        ins^.metrics.y_scale2  := ins^.metrics.x_scale2;

        ins^.valid             := false;

        TT_Set_Instance_PixelSizes := TT_Err_Ok;
      end
    else
      TT_Set_Instance_PixelSizes := TT_Err_Invalid_Instance_Handle;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Set_Instance_Transforms( _ins      : TT_Instance;
                                       rotated   : Boolean;
                                       distorted : Boolean ) : TT_Error;
  var
    ins : PInstance;
  begin
    ins := _ins.z;
    if ins <> nil then
      begin
        ins^.metrics.rotated   := rotated;
        ins^.metrics.stretched := distorted;
        TT_Set_Instance_Transforms := TT_Err_Ok;
      end
    else
      TT_Set_Instance_Transforms := TT_Err_Invalid_Instance_Handle;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Get_Instance_Metrics( _ins  : TT_Instance;
                                    var m : TT_Instance_Metrics ) : TT_Error;
  var
    ins : PInstance;
  begin
    ins := _ins.z;
    if ins <> nil then
      begin
        if not ins^.valid then
          if Instance_Reset( ins, False ) then
          begin
            TT_Get_Instance_Metrics := error;
            exit;
          end;

        with m do
        begin
          pointSize    := ins^.metrics.pointSize;

          x_scale      := MulDiv_Round( $10000,
                                        ins^.metrics.x_scale1,
                                        ins^.metrics.x_scale2 );

          y_scale      := MulDiv_Round( $10000,
                                        ins^.metrics.y_scale1,
                                        ins^.metrics.y_scale2 );

          x_resolution := ins^.metrics.x_resolution;
          y_resolution := ins^.metrics.y_resolution;

          x_ppem       := ins^.metrics.x_ppem;
          y_ppem       := ins^.metrics.y_ppem;

          TT_Get_Instance_Metrics := TT_Err_Ok;
        end;
      end
    else
      TT_Get_Instance_Metrics := TT_Err_Invalid_Instance_Handle;
  end;


  (*****************************************************************)
  (*  Set instance generic pointer                                 *)
  (*                                                               *)
  function TT_Set_Instance_Pointer( _ins : TT_Instance;
                                    data : Pointer ) : TT_Error;
  var
    ins : PInstance;
  begin
    ins := PInstance(_ins.z);
    if ins <> nil then
      begin
        ins^.generic := data;
        TT_Set_Instance_Pointer := TT_Err_Ok;
      end
    else
      TT_Set_Instance_Pointer := TT_Err_Invalid_Instance_Handle;
  end;

  (*****************************************************************)
  (*  Get instance generic pointer                                 *)
  (*                                                               *)
  function TT_Get_Instance_Pointer( _ins : TT_Instance ) : Pointer;
  var
    ins : PInstance;
  begin
    ins := PInstance(_ins.z);
    if ins <> nil then
      TT_Get_Instance_Pointer := ins^.generic
    else
      TT_Get_Instance_Pointer := nil;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Done_Instance( _ins : TT_Instance ) : TT_Error;
  var
    ins : PInstance;
  begin
    ins := PInstance(_ins.z);
    if ins <> nil then
      begin
        error := TT_Err_Ok;
        Cache_Done( ins^.owner^.instances, ins );
        TT_Done_Instance := error;
      end
    else
      TT_Done_Instance := TT_Err_Invalid_Instance_Handle;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_New_Glyph( _face      : TT_Face;
                         var _glyph : TT_Glyph ) : TT_Error;
  var
    face : PFace;
  begin
    face := PFace(_face.z);
    if face <> nil then
      begin
        error := TT_Err_Ok;
        Cache_New( objs_glyph_cache^, _glyph.z, _face.z );
        TT_New_Glyph := error;
      end
    else
      TT_New_Glyph := TT_Err_Invalid_Face_Handle;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Done_Glyph( _glyph : TT_Glyph ) : TT_Error;
  var
    glyph : PGlyph;
  begin
    glyph := PGlyph(_glyph.z);
    if glyph <> nil then
      begin
        error := TT_Err_Ok;
        Cache_Done( objs_glyph_cache^, glyph );
        TT_Done_Glyph := error;
      end
    else
      TT_Done_Glyph := TT_Err_Invalid_Glyph_Handle;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function  TT_Load_Glyph( _instance   : TT_Instance;
                           _glyph      : TT_Glyph;
                           glyph_index : Integer;
                           load_flags  : Integer ) : TT_Error;
  var
    ins   : PInstance;
    glyph : PGlyph;
  begin
    ins := PInstance(_instance.z);
    if ins = nil then
      begin
        TT_Load_Glyph := TT_Err_Invalid_Instance_Handle;
        exit;
      end;

    glyph := PGlyph(_glyph.z);
    if glyph = nil then
      begin
        TT_Load_Glyph := TT_Err_Invalid_Glyph_Handle;
        exit;
      end;

    if ins^.owner <> glyph^.face then
      begin
        TT_Load_Glyph := TT_Err_Invalid_Face_Handle;
        exit;
      end;

    if not ins^.valid then
      if Instance_Reset( ins, False ) then
      begin
        TT_Load_Glyph := error;
        exit;
      end;

    error := TT_Err_Ok;
    Load_TrueType_Glyph( ins, glyph, glyph_index, load_flags );
    TT_Load_Glyph := error;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  procedure Glyph2Outline( glyph       : PGlyph;
                           var outline : TT_Outline );
  begin
    with outline do
    begin
      points   := glyph^.num_points;
      contours := glyph^.num_contours;
      xCoord   := glyph^.x_coord;
      yCoord   := glyph^.y_coord;
      flag     := glyph^.touch;
      conEnds  := glyph^.endContours;
      owner    := false;

      high_precision := glyph^.high_precision;
      second_pass    := true;
      dropout_mode   := glyph^.scan_type;
    end;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Get_Glyph_Outline( _glyph      : TT_Glyph;
                                 var outline : TT_Outline ) : TT_Error;
  var
    glyph : PGlyph;
  begin
    glyph := PGlyph(_glyph.z);
    if glyph <> nil then
      begin
        Glyph2Outline( glyph, outline );
        TT_Get_Glyph_Outline := TT_Err_Ok;
      end
    else
      TT_Get_Glyph_Outline := TT_Err_Invalid_Glyph_Handle;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Get_Glyph_Metrics( _glyph       : TT_Glyph;
                                 var gmetrics : TT_Glyph_Metrics ) : TT_Error;
  var
    glyph : PGlyph;
  begin
    glyph := PGlyph(_glyph.z);
    if glyph <> nil then
      begin
        with gmetrics do
        begin
          xMin := glyph^.xMin;
          xMax := glyph^.xMax;
          yMin := glyph^.yMin;
          yMax := glyph^.yMax;

          advanceWidth    := glyph^.advanceWidth;
          leftSideBearing := glyph^.leftSideBearing;
        end;
        TT_Get_Glyph_Metrics := TT_Err_Ok;
      end
    else
      TT_Get_Glyph_Metrics := TT_Err_Invalid_Glyph_Handle;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Get_Glyph_Bitmap( _glyph   : TT_Glyph;
                                var map  : TT_raster_Map;
                                x_offset : TT_F26Dot6;
                                y_offset : TT_F26Dot6 ) : TT_Error;
  var
    glyph   : PGlyph;
    outline : TT_Outline;
    n       : Int;
  begin
    glyph := _glyph.z;
    if glyph <> nil then
      begin
        Glyph2Outline( glyph, outline );
        outline.dropout_mode := 2;

        TT_Translate_Outline( outline, x_offset, y_offset );
        TT_Get_Glyph_Bitmap := TT_Get_Outline_Bitmap( outline, map );
        TT_Translate_Outline( outline, -x_offset, -y_offset );
      end
    else
      TT_Get_Glyph_Bitmap := TT_Err_Invalid_Glyph_Handle;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Get_Glyph_Pixmap( _glyph   : TT_Glyph;
                                var map  : TT_raster_Map;
                                x_offset : TT_F26Dot6;
                                y_offset : TT_F26Dot6 ) : TT_Error;
  var
    glyph   : PGlyph;
    outline : TT_Outline;
    n       : Int;
  begin
    glyph := _glyph.z;
    if glyph <> nil then
      begin
        Glyph2Outline( glyph, outline );

        (* XXX: for now, we only use dropout mode #2 *)
        outline.dropout_mode := 2;

        TT_translate_Outline( outline, x_offset, y_offset );
        TT_Get_Glyph_Pixmap := TT_Get_Outline_Pixmap( outline, map );
        TT_translate_Outline( outline, -x_offset, -y_offset );
      end
    else
      TT_Get_Glyph_Pixmap := TT_Err_Invalid_Glyph_Handle;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Translate_Outline( var out : TT_Outline;
                                 x, y    : TT_F26Dot6 ) : TT_Error;
  var
    n : integer;
  begin
    if x <> 0 then
      for n := 0 to out.points-1 do
        inc( out.xCoord^[n], x );

    if y <> 0 then
      for n := 0 to out.points-1 do
        inc( out.yCoord^[n], y );

    TT_Translate_Outline := TT_Err_Ok;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Transform_Outline( var out : TT_Outline;
                                 var mat : TT_Matrix ) : TT_Error;
  var
    n            : integer;
    x, y, nx, ny : TT_F26Dot6;
  begin
    for n := 0 to out.points-1 do
    begin
      x  := out.xCoord^[n];
      y  := out.yCoord^[n];

      nx := MulDiv_Round( mat.xx, x, $10000 ) +
            MulDiv_Round( mat.xy, y, $10000 );

      ny := MulDiv_ROund( mat.yx, x, $10000 ) +
            MulDiv_Round( mat.yy, y, $10000 );

      out.xCoord^[n] := nx;
      out.yCoord^[n] := ny;
    end;

    TT_Transform_Outline := TT_Err_Ok;
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function TT_Transform_Vector( var x, y : TT_F26Dot6;
                                var mat  : TT_Matrix ) : TT_Error;
  var
    nx, ny : TT_F26Dot6;
  begin
    nx := MulDiv_Round( mat.xx, x, $10000 ) +
          MulDiv_Round( mat.xy, y, $10000 );

    ny := MulDiv_Round( mat.yx, x, $10000 ) +
          MulDiv_Round( mat.yy, y, $10000 );

    x := nx;
    y := ny;

    TT_Transform_Vector := TT_Err_Ok;
  end;

  (*****************************************************************)
  (*  Render an outline into a bitmap                              *)
  (*                                                               *)
  function TT_Get_Outline_Bitmap( var out      : TT_Outline;
                                  var map      : TT_raster_Map ) : TT_Error;
  begin
    if Render_Glyph( out, map ) then
      TT_Get_Outline_Bitmap := error
    else
      TT_Get_Outline_Bitmap := TT_Err_Ok;
  end;

  (*****************************************************************)
  (*  Render an outline into a pixmap                              *)
  (*                                                               *)
  function TT_Get_Outline_Pixmap( var out      : TT_Outline;
                                  var map      : TT_raster_Map ) : TT_Error;
  begin
    if Render_Gray_Glyph( out, map ) then
      TT_Get_Outline_Pixmap := error
    else
      TT_Get_Outline_Pixmap := TT_Err_Ok;
  end;

  (*****************************************************************)
  (*  Create a new glyph outline                                   *)
  (*                                                               *)
  function TT_New_Outline( n_points   : integer;
                           n_contours : integer;
                           var out    : TT_Outline ) : TT_Error;
  label
    Fail;
  begin
    out.points   := n_points;
    out.contours := n_contours;
    out.xCoord   := nil;
    out.yCoord   := nil;
    out.flag     := nil;
    out.conEnds  := nil;
    out.owner    := true;

    if Alloc( Pointer(out.xCoord),  n_points*4 ) or
       Alloc( Pointer(out.yCoord),  n_points*4 ) or
       Alloc( Pointer(out.flag),    n_points )   or
       Alloc( Pointer(out.conEnds), n_contours*2 ) then goto Fail;

    TT_New_Outline := TT_Err_Ok;
    exit;

  Fail:
    TT_Done_Outline( out );
    TT_New_Outline := error;
  end;

  (*****************************************************************)
  (*  Copy a glyph outline into another one                        *)
  (*                                                               *)
  function TT_Copy_Outline( var source : TT_Outline;
                            var target : TT_Outline ) : TT_Error;
  begin
    if (source.points   = target.points) and
       (source.contours = target.contours) then
      begin
        move( source.xCoord^, target.xCoord^, source.points*4 );
        move( source.yCoord^, target.yCoord^, source.points*4 );
        move( source.flag^,   target.flag^,   source.points );
        move( source.conEnds^,target.conEnds^,source.contours*2 );
      end
    else
      TT_Copy_Outline := TT_Err_Invalid_Argument;
  end;

  (*****************************************************************)
  (*  Clone a given outline. This will create the outline, then    *)
  (*  copy the source in it                                        *)
  (*                                                               *)
  function TT_Clone_Outline( var source : TT_Outline;
                             var target : TT_Outline ) : TT_Error;
  begin
    error := TT_New_Outline( source.points, source.contours, target );
    if error = TT_Err_Ok then
      TT_Copy_Outline( source, target );

    TT_Clone_Outline := error;
  end;

  (*****************************************************************)
  (*  Discards a glyph outline                                     *)
  (*                                                               *)
  function TT_Done_Outline( var out : TT_Outline ) : TT_Error;
  begin
    if out.owner then
      begin
        Free( Pointer(out.conEnds) );
        Free( Pointer(out.flag) );
        Free( Pointer(out.yCoord) );
        Free( Pointer(out.xCoord) );
        out.points   := 0;
        out.contours := 0;
        TT_Done_Outline := TT_Err_Ok;
      end
    else
      TT_Done_Outline := TT_Err_Invalid_Argument;
  end;

  (***********************************************************************)
  (*                                                                     *)
  (*                     Character Mapping support                       *)
  (*                                                                     *)
  (***********************************************************************)

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function  TT_Get_CharMap_Count( face : TT_Face ) : integer;
  var
    faze : PFace;
  begin
    faze := PFace(face.z);
    if faze = nil then
      TT_Get_CharMap_Count := -1
    else
      TT_Get_CharMap_Count := faze^.numCMaps;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function  TT_Get_CharMap_ID( face         : TT_Face;
                               charmapIndex : integer;
                               var platform : integer;
                               var encoding : integer ) : TT_Error;
  var
    faze : PFace;
    cmap : PCMapTable;
  begin
    faze := PFace(face.z);
    if faze = nil then
    begin
      TT_Get_CharMap_ID := TT_Err_Invalid_Face_Handle;
      exit;
    end;

    if (charmapIndex < 0) or (charmapIndex >= faze^.numCMaps) then
    begin
      TT_Get_CharMap_ID := TT_Err_Invalid_Argument;
      exit;
    end;

    cmap     := @faze^.cMaps^[charmapIndex];
    platform := cmap^.platformID;
    encoding := cmap^.platformEncodingID;

    TT_Get_CharMap_ID := TT_Err_Ok;
  end;


  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function  TT_Get_CharMap( face         : TT_Face;
                            charmapIndex : integer;
                            var charMap  : TT_CharMap ) : TT_Error;
  var
    faze : PFace;
  begin
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function  TT_Char_Index( charmap  : TT_CharMap;
                           charCode : word ) : integer;
  begin
  end;

  (***********************************************************************)
  (*                                                                     *)
  (*                        Names Table support                          *)
  (*                                                                     *)
  (***********************************************************************)

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function  TT_Get_Name_Count( face : TT_Face ) : integer;
  begin
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function  TT_Get_Name_ID( face         : TT_Face;
                            nameIndex    : integer;
                            var platform : integer;
                            var encoding : integer;
                            var language : integer;
                            var nameid   : integer ) : TT_Error;
  begin
  end;

  (*****************************************************************)
  (*                                                               *)
  (*                                                               *)
  function  TT_Get_Name_String( face      : TT_Face;
                                nameIndex : integer;
                                var str   : Pointer;
                                var len   : integer ) : TT_Error;
  begin
  end;

  (*****************************************************************)
  (*  Access font data and copies it into user block               *)
  (*                                                               *)
  function  TT_Get_Font_Data( face       : TT_Face;
                              tableTag   : Longint;
                              offset     : Longint;
                              var buffer;
                              var length : longint ) : TT_Error;
  var
    faze : PFace;
  begin
    faze := PFace(face.z);
    if faze = nil then
      begin
        TT_Get_Font_Data := TT_Err_Invalid_Face_Handle;
        length := 0;
      end
    else
      begin
        TT_Get_Font_Data := TT_Err_Ok;
        if Load_TrueType_Any( faze, tableTag, offset, buffer, length ) then
          TT_Get_Font_Data := error;
      end;
  end;


end.

