text:
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TRIGONOMETRY_H

#include <math.h>
#include <stdio.h>

#define  PI   3.14159265358979323846
#define  SPI  (PI/FT_ANGLE_PI)

/* the precision in 16.16 fixed-point checks. Expect between 2 and 5 */
/* noise LSB bits during operations, due to rounding errors..        */
#define  THRESHOLD  64

  static  error = 0;

  static void
  test_cos( void )
  {
    int  i;

    for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L )
    {
      FT_Fixed  f1, f2;
      double    d2;

      f1 = FT_Cos(i);
      d2 = cos( i*SPI );
      f2 = (FT_Fixed)(d2*65536.0);

      if ( abs( f2-f1 ) > THRESHOLD )
      {
        error = 1;
        printf( "FT_Cos[%3d] = %.7f  cos[%3d] = %.7f\n",
                (i >> 16), f1/65536.0, (i >> 16), d2 );
      }
    }
  }

  static void
  test_sin( void )
  {
    int  i;

    for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L )
    {
      FT_Fixed  f1, f2;
      double    d2;

      f1 = FT_Sin(i);
      d2 = sin( i*SPI );
      f2 = (FT_Fixed)(d2*65536.0);

      if ( abs( f2-f1 ) > THRESHOLD )
      {
        error = 1;
        printf( "FT_Sin[%3d] = %.7f  sin[%3d] = %.7f\n",
                (i >> 16), f1/65536.0, (i >> 16), d2 );
      }
    }
  }

  static void
  test_tan( void )
  {
    int  i;

    for ( i = 0; i < FT_ANGLE_PI2 - 0x2000000L; i += 0x10000L )
    {
      FT_Fixed  f1, f2;
      double    d2;

      f1 = FT_Tan(i);
      d2 = tan( i*SPI );
      f2 = (FT_Fixed)(d2*65536.0);

      if ( abs( f2-f1 ) > THRESHOLD )
      {
        error = 1;
        printf( "FT_Tan[%3d] = %.7f  tan[%3d] = %.7f\n",
                (i >> 16), f1/65536.0, (i >> 16), d2 );
      }
    }
  }

  static void
  test_atan2( void )
  {
    int  i;

    for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L )
    {
      FT_Fixed  c2, s2;
      double    l, a, c1, s1;
      int       j;

      l  = 5.0;
      a  = i*SPI;

      c1 = l * cos(a);
      s1 = l * sin(a);

      c2 = (FT_Fixed)(c1*65536.0);
      s2 = (FT_Fixed)(s1*65536.0);

      j  = FT_Atan2( c2, s2 );
      if ( j < 0 )
        j += FT_ANGLE_2PI;

      if ( abs( i - j ) > 1 )
      {
        printf( "FT_Atan2( %.7f, %.7f ) = %.5f, atan = %.5f\n",
                c2/65536.0, s2/65536.0, j/65536.0, i/65536.0 );
      }
    }
  }

  static void
  test_unit( void )
  {
    int  i;

    for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L )
    {
      FT_Vector  v;
      double     a, c1, s1;
      FT_Fixed   c2, s2;

      FT_Vector_Unit( &v, i );
      a  = ( i*SPI );
      c1 = cos(a);
      s1 = sin(a);
      c2 = (FT_Fixed)(c1*65536.0);
      s2 = (FT_Fixed)(s1*65536.0);

      if ( abs( v.x-c2 ) > THRESHOLD ||
           abs( v.y-s2 ) > THRESHOLD )
      {
        error = 1;
        printf( "FT_Vector_Unit[%3d] = ( %.7f, %.7f )  vec = ( %.7f, %.7f )\n",
                (i >> 16),
                v.x/65536.0, v.y/65536.0,
                c1, s1 );
      }
    }
  }

  static void
  test_length( void )
  {
    int  i;

    for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L )
    {
      FT_Vector  v;
      FT_Fixed   l, l2;

      l   = (FT_Fixed)(500.0*65536.0);
      v.x = (FT_Fixed)( l * cos( i*SPI ) );
      v.y = (FT_Fixed)( l * sin( i*SPI ) );
      l2  = FT_Vector_Length( &v );

      if ( abs( l2-l ) > THRESHOLD )
      {
        error = 1;
        printf( "FT_Length( %.7f, %.7f ) = %.5f, length = %.5f\n",
                v.x/65536.0, v.y/65536.0, l2/65536.0, l/65536.0 );
      }
    }
  }

  static void
  test_rotate( void )
  {
    int  rotate;

    for ( rotate = 0; rotate < FT_ANGLE_2PI; rotate += 0x10000L )
    {
      double  ra, cra, sra;
      int     i;

      ra  = rotate*SPI;
      cra = cos( ra );
      sra = sin( ra );

      for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L )
      {
        FT_Fixed   c2, s2, c4, s4;
        FT_Vector  v;
        double     l, a, c1, s1, c3, s3;

        l  = 500.0;
        a  = i*SPI;

        c1 = l * cos(a);
        s1 = l * sin(a);

        v.x = c2 = (FT_Fixed)(c1*65536.0);
        v.y = s2 = (FT_Fixed)(s1*65536.0);

        FT_Vector_Rotate( &v, rotate );

        c3 = c1 * cra - s1 * sra;
        s3 = c1 * sra + s1 * cra;

        c4 = (FT_Fixed)(c3*65536.0);
        s4 = (FT_Fixed)(s3*65536.0);

        if ( abs( c4 - v.x ) > THRESHOLD ||
             abs( s4 - v.y ) > THRESHOLD )
        {
          error = 1;
          printf( "FT_Rotate( (%.7f,%.7f), %.5f ) = ( %.7f, %.7f ), rot = ( %.7f, %.7f )\n",
                  c1, s1, ra,
                  c2/65536.0, s2/65536.0,
                  c4/65536.0, s4/65536.0 );
        }
      }
    }
  }

  int main( void )
  {
    test_cos();
    test_sin();
    test_tan();
    test_atan2();
    test_unit();
    test_length();
    test_rotate();

    if (!error)
      printf( "trigonometry test ok !\n" );

    return !error;
  }

repo_language: C

mime_type: text/x-c


text:
# Files that don't get a copyright, or which are taken from elsewhere.
#
# All lines in this file are patterns, including the comment lines; this
# means that e.g. `FTL.TXT' matches all files that have this string in
# the file name (including the path relative to the current directory,
# always starting with `./').
#
# Don't put empty lines into this file!
#
.gitignore
#
builds/unix/pkg.m4
#
docs/FTL.TXT
docs/GPLv2.TXT
#
include/freetype/internal/fthash.h
#
src/base/fthash.c
src/base/md5.c
src/base/md5.h
#
src/bdf/bdf.c
src/bdf/bdf.h
src/bdf/bdfdrivr.c
src/bdf/bdfdrivr.h
src/bdf/bdferror.h
src/bdf/bdflib.c
src/bdf/module.mk
src/bdf/README
src/bdf/rules.mk
#
src/pcf/module.mk
src/pcf/pcf.c
src/pcf/pcf.h
src/pcf/pcfdrivr.c
src/pcf/pcfdrivr.h
src/pcf/pcferror.h
src/pcf/pcfread.c
src/pcf/pcfread.h
src/pcf/pcfutil.c
src/pcf/pcfutil.h
src/pcf/README
src/pcf/rules.mk
#
src/gzip/adler32.c
src/gzip/infblock.c
src/gzip/infblock.h
src/gzip/infcodes.c
src/gzip/infcodes.h
src/gzip/inffixed.h
src/gzip/inflate.c
src/gzip/inftrees.c
src/gzip/inftrees.h
src/gzip/infutil.c
src/gzip/infutil.h
src/gzip/zconf.h
src/gzip/zlib.h
src/gzip/zutil.c
src/gzip/zutil.h
#
src/tools/apinames.c
src/tools/ftrandom/ftrandom.c
#
# EOF


text:
ftrandom
========

This program expects a set of directories containing good fonts, and a set
of extensions of fonts to be tested.  It will randomly pick a font, copy it,
introduce an error and then test it.

The FreeType tests are quite basic; for each erroneous font ftrandom

  . forks off a new tester,
  . initializes the library,
  . opens each font in the file,
  . loads each glyph,
  . optionally reviews the contours of the glyph,
  . optionally rasterizes the glyph, and
  . closes the face.

If a tester takes longer than 20 seconds, ftrandom saves the erroneous font
and continues.  If the tester exits normally or with an error, then the
superstructure removes the test font and continues.

Command line options
--------------------

  --all                    Test every font in the directory(ies) no matter
                           what its extension.
  --check-outlines         Call `FT_Outline_Decompose' on each glyph.
  --dir <dir>              Append <dir> to the list of directories to search
                           for good fonts.  No recursive search.
  --error-count <cnt>      Introduce <cnt> single-byte errors into the
                           erroneous fonts (default: 1).
  --error-fraction <frac>  Multiply the file size of the font by <frac> and
                           introduce that many errors into the erroneous
                           font file.  <frac> should be in the range [0;1]
                           (default: 0.0).
  --ext <ext>              Add <ext> to the set of font types tested.
  --help                   Print out this list of options.
  --nohints                Specify FT_LOAD_NO_HINTING when loading glyphs.
  --rasterize              Call `FT_Render_Glyph' as well as loading it.
  --result <dir>           This is the directory in which test files are
                           placed.
  --test <file>            Run a single test on a pre-generated testcase.
                           This is done in the current process so it can be
                           debugged more easily.

The default font extensions tested by ftrandom are

  .ttf .otf .ttc .cid .pfb .pfa .bdf .pcf .pfr .fon .otb .cff

The default font directory is controlled by the macro `GOOD_FONTS_DIR' in
the source code (and can be thus specified during compilation); its default
value is

  /usr/local/share/fonts

The default result directory is `results' (in the current directory).

Compilation
-----------

Two possible solutions.

. Run ftrandom within a debugging tool like `valgrind' to catch various
  memory issues.

. Compile FreeType with sanitizer flags as provided by gcc or clang, for
  example, then link it with ftrandom.


text:
/* Copyright (C) 2005, 2007, 2008, 2013 by George Williams */
/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.

 * The name of the author may not be used to endorse or promote products
 * derived from this software without specific prior written permission.

 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* modified by Werner Lemberg <wl@gnu.org>       */
/* This file is now part of the FreeType library */

#define _XOPEN_SOURCE 500 /* for `kill', `strdup', `random', and `srandom' */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <dirent.h>
#include <signal.h>
#include <time.h>

#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H

#define true     1
#define false    0
#define forever  for (;;)

  static int    check_outlines = false;
  static int    nohints        = false;
  static int    rasterize      = false;
  static char*  results_dir    = "results";

#define GOOD_FONTS_DIR  "/usr/local/share/fonts"

  static char*  default_dir_list[] =
  {
    GOOD_FONTS_DIR,
    NULL
  };

  static char*  default_ext_list[] =
  {
    "ttf",
    "otf",
    "ttc",
    "cid",
    "pfb",
    "pfa",
    "bdf",
    "pcf",
    "pfr",
    "fon",
    "otb",
    "cff",
    NULL
  };

  static unsigned int  error_count    = 1;
  static double        error_fraction = 0.0;

  static FT_F26Dot6  font_size = 12 * 64;

  static struct fontlist
  {
    char*         name;
    long          len;
    unsigned int  isbinary: 1;
    unsigned int  isascii: 1;
    unsigned int  ishex: 1;

  } *fontlist;

  static unsigned int  fcnt;

  static int
  FT_MoveTo( const FT_Vector  *to,
             void             *user )
  {
    FT_UNUSED( to );
    FT_UNUSED( user );

    return 0;
  }

  static int
  FT_LineTo( const FT_Vector  *to,
             void             *user )
  {
    FT_UNUSED( to );
    FT_UNUSED( user );

    return 0;
  }

  static int
  FT_ConicTo( const FT_Vector  *_cp,
              const FT_Vector  *to,
              void             *user )
  {
    FT_UNUSED( _cp );
    FT_UNUSED( to );
    FT_UNUSED( user );

    return 0;
  }

  static int
  FT_CubicTo( const FT_Vector  *cp1,
              const FT_Vector  *cp2,
              const FT_Vector  *to,
              void             *user )
  {
    FT_UNUSED( cp1 );
    FT_UNUSED( cp2 );
    FT_UNUSED( to );
    FT_UNUSED( user );

    return 0;
  }

  static FT_Outline_Funcs outlinefuncs =
  {
    FT_MoveTo,
    FT_LineTo,
    FT_ConicTo,
    FT_CubicTo,
    0, 0          /* No shift, no delta */
  };

  static void
  TestFace( FT_Face  face )
  {
    unsigned int  gid;
    int           load_flags = FT_LOAD_DEFAULT;

    if ( check_outlines         &&
         FT_IS_SCALABLE( face ) )
      load_flags = FT_LOAD_NO_BITMAP;

    if ( nohints )
      load_flags |= FT_LOAD_NO_HINTING;

    FT_Set_Char_Size( face, 0, font_size, 72, 72 );

    for ( gid = 0; gid < face->num_glyphs; gid++ )
    {
      if ( check_outlines         &&
           FT_IS_SCALABLE( face ) )
      {
        if ( !FT_Load_Glyph( face, gid, load_flags ) )
          FT_Outline_Decompose( &face->glyph->outline, &outlinefuncs, NULL );
      }
      else
        FT_Load_Glyph( face, gid, load_flags );

      if ( rasterize )
        FT_Render_Glyph( face->glyph, ft_render_mode_normal );
    }

    FT_Done_Face( face );
  }

  static void
  ExecuteTest( char*  testfont )
  {
    FT_Library  context;
    FT_Face     face;

    if ( FT_Init_FreeType( &context ) )
    {
      fprintf( stderr, "Can't initialize FreeType.\n" );
      exit( 1 );
    }

    if ( FT_New_Face( context, testfont, 0, &face ) )
    {
      /* The font is erroneous, so if this fails that's ok. */
      exit( 0 );
    }

    if ( face->num_faces == 1 )
      TestFace( face );
    else
    {
      long  i, num;

      num = face->num_faces;
      FT_Done_Face( face );

      for ( i = 0; i < num; i++ )
      {
        if ( !FT_New_Face( context, testfont, i, &face ) )
          TestFace( face );
      }
    }

    FT_Done_FreeType( context );

    exit( 0 );
  }

  static int
  extmatch( char*   filename,
            char**  extensions )
  {
    int    i;
    char*  pt;

    if ( !extensions )
      return true;

    pt = strrchr( filename, '.' );
    if ( !pt )
      return false;
    if ( pt < strrchr( filename, '/' ) )
      return false;

    for ( i = 0; extensions[i] != NULL; i++ )
      if ( strcasecmp( pt + 1, extensions[i] ) == 0 ||
           strcasecmp( pt,     extensions[i] ) == 0 )
        return true;

    return false;
  }

  static void
  figurefiletype( struct fontlist*  item )
  {
    FILE*  foo;

    item->isbinary = item->isascii = item->ishex = false;

    foo = fopen( item->name, "rb" );
    if ( foo )
    {
      /* Try to guess the file type from the first few characters... */
      int  ch1 = getc( foo );
      int  ch2 = getc( foo );
      int  ch3 = getc( foo );
      int  ch4 = getc( foo );

      fclose( foo );

      if ( ( ch1 == 0   && ch2 == 1   && ch3 == 0   && ch4 == 0   ) ||
           ( ch1 == 'O' && ch2 == 'T' && ch3 == 'T' && ch4 == 'O' ) ||
           ( ch1 == 't' && ch2 == 'r' && ch3 == 'u' && ch4 == 'e' ) ||
           ( ch1 == 't' && ch2 == 't' && ch3 == 'c' && ch4 == 'f' ) )
      {
        /* ttf, otf, ttc files */
        item->isbinary = true;
      }
      else if ( ch1 == 0x80 && ch2 == '\01' )
      {
        /* PFB header */
        item->isbinary = true;
      }
      else if ( ch1 == '%' && ch2 == '!' )
      {
        /* Random PostScript */
        if ( strstr( item->name, ".pfa" ) ||
             strstr( item->name, ".PFA" ) )
          item->ishex = true;
        else
          item->isascii = true;
      }
      else if ( ch1 == 1 && ch2 == 0 && ch3 == 4 )
      {
        /* Bare CFF */
        item->isbinary = true;
      }
      else if ( ch1 == 'S' && ch2 == 'T' && ch3 == 'A' && ch4 == 'R' )
      {
        /* BDF */
        item->ishex = true;
      }
      else if ( ch1 == 'P' && ch2 == 'F' && ch3 == 'R' && ch4 == '0' )
      {
        /* PFR */
        item->isbinary = true;
      }
      else if ( ( ch1 == '\1' && ch2 == 'f' && ch3 == 'c' && ch4 == 'p' ) ||
                ( ch1 == 'M'  && ch2 == 'Z' )                             )
      {
        /* Windows FON */
        item->isbinary = true;
      }
      else
      {
        fprintf( stderr,
                 "Can't recognize file type of `%s', assuming binary\n",
                 item->name );
        item->isbinary = true;
      }
    }
    else
    {
      fprintf( stderr, "Can't open `%s' for typing the file.\n",
               item->name );
      item->isbinary = true;
    }
  }

  static void
  FindFonts( char**  fontdirs,
             char**  extensions )
  {
    int           i;
    unsigned int  max;
    char          buffer[1025];
    struct stat   statb;

    max  = 0;
    fcnt = 0;

    for ( i = 0; fontdirs[i] != NULL; i++ )
    {
      DIR*            examples;
      struct dirent*  ent;

      examples = opendir( fontdirs[i] );
      if ( !examples )
      {
        fprintf( stderr,
                 "Can't open example font directory `%s'\n",
                 fontdirs[i] );
        exit( 1 );
      }

      while ( ( ent = readdir( examples ) ) != NULL )
      {
        snprintf( buffer, sizeof ( buffer ),
                  "%s/%s", fontdirs[i], ent->d_name );
        if ( stat( buffer, &statb ) == -1 || S_ISDIR( statb.st_mode ) )
          continue;
        if ( !extensions || extmatch( buffer, extensions ) )
        {
          if ( fcnt >= max )
          {
            max += 100;
            fontlist = realloc( fontlist, max * sizeof ( struct fontlist ) );
            if ( !fontlist )
            {
              fprintf( stderr, "Can't allocate memory\n" );
              exit( 1 );
            }
          }

          fontlist[fcnt].name = strdup( buffer );
          fontlist[fcnt].len  = statb.st_size;

          figurefiletype( &fontlist[fcnt] );
          fcnt++;
        }
      }

      closedir( examples );
    }

    if ( fcnt == 0 )
    {
      fprintf( stderr, "Can't find matching font files.\n" );
      exit( 1 );
    }

    fontlist[fcnt].name = NULL;
  }

  static unsigned int
  getErrorCnt( struct fontlist*  item )
  {
    if ( error_count == 0 && error_fraction == 0.0 )
      return 0;

    return error_count + (unsigned int)( error_fraction * item->len );
  }

  static int
  getRandom( int  low,
             int  high )
  {
    if ( low - high < 0x10000L )
      return low + ( ( random() >> 8 ) % ( high + 1 - low ) );

    return low + ( random() % ( high + 1 - low ) );
  }

  static int
  copyfont( struct fontlist*  item,
            char*             newfont )
  {
    static char   buffer[8096];
    FILE          *good, *newf;
    size_t        len;
    unsigned int  i, err_cnt;

    good = fopen( item->name, "r" );
    if ( !good )
    {
      fprintf( stderr, "Can't open `%s'\n", item->name );
      return false;
    }

    newf = fopen( newfont, "w+" );
    if ( !newf )
    {
      fprintf( stderr, "Can't create temporary output file `%s'\n",
               newfont );
      exit( 1 );
    }

    while ( ( len = fread( buffer, 1, sizeof ( buffer ), good ) ) > 0 )
      fwrite( buffer, 1, len, newf );

    fclose( good );

    err_cnt = getErrorCnt( item );
    for ( i = 0; i < err_cnt; i++ )
    {
      fseek( newf, getRandom( 0, (int)( item->len - 1 ) ), SEEK_SET );

      if ( item->isbinary )
        putc( getRandom( 0, 0xFF ), newf );
      else if ( item->isascii )
        putc( getRandom( 0x20, 0x7E ), newf );
      else
      {
        int  hex = getRandom( 0, 15 );

        if ( hex < 10 )
          hex += '0';
        else
          hex += 'A' - 10;

        putc( hex, newf );
      }
    }

    if ( ferror( newf ) )
    {
      fclose( newf );
      unlink( newfont );
      return false;
    }

    fclose( newf );

    return true;
  }

  static int  child_pid;

  static void
  abort_test( int  sig )
  {
    FT_UNUSED( sig );

    /* If a time-out happens, then kill the child */
    kill( child_pid, SIGFPE );
    write( 2, "Timeout... ", 11 );
  }

  static void
  do_test( void )
  {
    int         i        = getRandom( 0, (int)( fcnt - 1 ) );
    static int  test_num = 0;
    char        buffer[1024];

    sprintf( buffer, "%s/test%d", results_dir, test_num++ );

    if ( copyfont ( &fontlist[i], buffer ) )
    {
      signal( SIGALRM, abort_test );
      /* Anything that takes more than 20 seconds */
      /* to parse and/or rasterize is an error.   */
      alarm( 20 );
      if ( ( child_pid = fork() ) == 0 )
        ExecuteTest( buffer );
      else if ( child_pid != -1 )
      {
        int  status;

        waitpid( child_pid, &status, 0 );
        alarm( 0 );
        if ( WIFSIGNALED ( status ) )
          printf( "Error found in file `%s'\n", buffer );
        else
          unlink( buffer );
      }
      else
      {
        fprintf( stderr, "Can't fork test case.\n" );
        exit( 1 );
      }
      alarm( 0 );
    }
  }

  static void
  usage( FILE*  out,
         char*  name )
  {
    char**  d = default_dir_list;
    char**  e = default_ext_list;

    fprintf( out, "%s [options] -- Generate random erroneous fonts\n"
                  "  and attempt to parse them with FreeType.\n\n", name );

    fprintf( out, "  --all                    All non-directory files are assumed to be fonts.\n" );
    fprintf( out, "  --check-outlines         Make sure we can parse the outlines of each glyph.\n" );
    fprintf( out, "  --dir <path>             Append <path> to list of font search directories\n"
                  "                           (no recursive search).\n" );
    fprintf( out, "  --error-count <cnt>      Introduce <cnt> single byte errors into each font\n"
                  "                           (default: 1)\n" );
    fprintf( out, "  --error-fraction <frac>  Introduce <frac>*filesize single byte errors\n"
                  "                           into each font (default: 0.0).\n" );
    fprintf( out, "  --ext <ext>              Add <ext> to list of extensions indicating fonts.\n" );
    fprintf( out, "  --help                   Print this.\n" );
    fprintf( out, "  --nohints                Turn off hinting.\n" );
    fprintf( out, "  --rasterize              Attempt to rasterize each glyph.\n" );
    fprintf( out, "  --results <path>         Place the created test fonts into <path>\n"
                  "                           (default: `results')\n" );
    fprintf( out, "  --size <float>           Use the given font size for the tests.\n" );
    fprintf( out, "  --test <file>            Run a single test on an already existing file.\n" );
    fprintf( out, "\n" );

    fprintf( out, "Default font extensions:\n" );
    fprintf( out, " " );
    while ( *e )
      fprintf( out, " .%s", *e++ );
    fprintf( out, "\n" );

    fprintf( out, "Default font directories:\n" );
    fprintf( out, " " );
    while ( *d )
      fprintf( out, " %s", *d++ );
    fprintf( out, "\n" );
  }

  int
  main( int     argc,
        char**  argv )
  {
    char    **dirs, **exts;
    int     dcnt = 0, ecnt = 0, rset = false, allexts = false;
    int     i;
    time_t  now;
    char*   testfile = NULL;

    dirs = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) );
    exts = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) );

    for ( i = 1; i < argc; i++ )
    {
      char*  pt = argv[i];
      char*  end;

      if ( pt[0] == '-' && pt[1] == '-' )
        pt++;

      if ( strcmp( pt, "-all" ) == 0 )
        allexts = true;
      else if ( strcmp( pt, "-check-outlines" ) == 0 )
        check_outlines = true;
      else if ( strcmp( pt, "-dir" ) == 0 )
        dirs[dcnt++] = argv[++i];
      else if ( strcmp( pt, "-error-count" ) == 0 )
      {
        if ( !rset )
          error_fraction = 0.0;
        rset = true;
        error_count = (unsigned int)strtoul( argv[++i], &end, 10 );
        if ( *end != '\0' )
        {
          fprintf( stderr, "Bad value for error-count: %s\n", argv[i] );
          exit( 1 );
        }
      }
      else if ( strcmp( pt, "-error-fraction" ) == 0 )
      {
        if ( !rset )
          error_count = 0;
        rset = true;
        error_fraction = strtod( argv[++i], &end );
        if ( *end != '\0' )
        {
          fprintf( stderr, "Bad value for error-fraction: %s\n", argv[i] );
          exit( 1 );
        }
        if ( error_fraction < 0.0 || error_fraction > 1.0 )
        {
          fprintf( stderr, "error-fraction must be in the range [0;1]\n" );
          exit( 1 );
        }
      }
      else if ( strcmp( pt, "-ext" ) == 0 )
        exts[ecnt++] = argv[++i];
      else if ( strcmp( pt, "-help" ) == 0 )
      {
        usage( stdout, argv[0] );
        exit( 0 );
      }
      else if ( strcmp( pt, "-nohints" ) == 0 )
        nohints = true;
      else if ( strcmp( pt, "-rasterize" ) == 0 )
        rasterize = true;
      else if ( strcmp( pt, "-results" ) == 0 )
        results_dir = argv[++i];
      else if ( strcmp( pt, "-size" ) == 0 )
      {
        font_size = (FT_F26Dot6)( strtod( argv[++i], &end ) * 64 );
        if ( *end != '\0' || font_size < 64 )
        {
          fprintf( stderr, "Bad value for size: %s\n", argv[i] );
          exit( 1 );
        }
      }
      else if ( strcmp( pt, "-test" ) == 0 )
        testfile = argv[++i];
      else
      {
        usage( stderr, argv[0] );
        exit( 1 );
      }
    }

    if ( allexts )
    {
      free( exts );
      exts = NULL;
    }
    else if ( ecnt == 0 )
    {
      free( exts );
      exts = default_ext_list;
    }

    if ( dcnt == 0 )
    {
      free( dirs );
      dirs = default_dir_list;
    }

    if ( testfile )
      ExecuteTest( testfile );         /* This should never return */

    time( &now );
    srandom( (unsigned int)now );

    FindFonts( dirs, exts );
    mkdir( results_dir, 0755 );

    forever
      do_test();

    return 0;
  }

/* EOF */


text:
# TOP_DIR and OBJ_DIR should be set by the user to the right directories,
# if necessary.

TOP_DIR ?= ../../..
OBJ_DIR ?= $(TOP_DIR)/objs

# The setup below is for gcc on a Unix-like platform,
# where FreeType has been set up to create a static library
# (which is the default).

VPATH = $(OBJ_DIR) \
        $(OBJ_DIR)/.libs

SRC_DIR = $(TOP_DIR)/src/tools/ftrandom

CC = gcc
WFLAGS = -Wmissing-prototypes \
         -Wunused \
         -Wimplicit \
         -Wreturn-type \
         -Wparentheses \
         -pedantic \
         -Wformat \
         -Wchar-subscripts \
         -Wsequence-point
CFLAGS = $(WFLAGS) \
         -g
INCLUDES = -I $(TOP_DIR)/include
LDFLAGS =
LIBS = -lm \
       -lz \
       -lpng \
       -lbz2 \
       -lharfbuzz

all: $(OBJ_DIR)/ftrandom

$(OBJ_DIR)/ftrandom.o: $(SRC_DIR)/ftrandom.c
	$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<

$(OBJ_DIR)/ftrandom: $(OBJ_DIR)/ftrandom.o libfreetype.a
	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

# EOF


text:
/****************************************************************************
 *
 * ft2build.h
 *
 *   FreeType 2 build and setup macros.
 *
 * 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.
 *
 */

  /**************************************************************************
   *
   * This is the 'entry point' for FreeType header file inclusions.  It is
   * the only header file which should be included directly; all other
   * FreeType header files should be accessed with macro names (after
   * including `ft2build.h`).
   *
   * A typical example is
   *
   * ```
   *   #include <ft2build.h>
   *   #include FT_FREETYPE_H
   * ```
   *
   */

#ifndef FT2BUILD_H_
#define FT2BUILD_H_

#include <freetype/config/ftheader.h>

#endif /* FT2BUILD_H_ */

/* END */


text:
/****************************************************************************
 *
 * ftwinfnt.h
 *
 *   FreeType API for accessing Windows fnt-specific data.
 *
 * Copyright (C) 2003-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 FTWINFNT_H_
#define FTWINFNT_H_

#include <ft2build.h>
#include FT_FREETYPE_H

#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif

FT_BEGIN_HEADER

  /**************************************************************************
   *
   * @section:
   *   winfnt_fonts
   *
   * @title:
   *   Window FNT Files
   *
   * @abstract:
   *   Windows FNT-specific API.
   *
   * @description:
   *   This section contains the declaration of Windows FNT-specific
   *   functions.
   *
   */

  /**************************************************************************
   *
   * @enum:
   *   FT_WinFNT_ID_XXX
   *
   * @description:
   *   A list of valid values for the `charset` byte in @FT_WinFNT_HeaderRec.
   *   Exact mapping tables for the various 'cpXXXX' encodings (except for
   *   'cp1361') can be found at 'ftp://ftp.unicode.org/Public/' in the
   *   `MAPPINGS/VENDORS/MICSFT/WINDOWS` subdirectory.  'cp1361' is roughly a
   *   superset of `MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT`.
   *
   * @values:
   *   FT_WinFNT_ID_DEFAULT ::
   *     This is used for font enumeration and font creation as a 'don't
   *     care' value.  Valid font files don't contain this value.  When
   *     querying for information about the character set of the font that is
   *     currently selected into a specified device context, this return
   *     value (of the related Windows API) simply denotes failure.
   *
   *   FT_WinFNT_ID_SYMBOL ::
   *     There is no known mapping table available.
   *
   *   FT_WinFNT_ID_MAC ::
   *     Mac Roman encoding.
   *
   *   FT_WinFNT_ID_OEM ::
   *     From Michael Poettgen <michael@poettgen.de>:
   *
   *     The 'Windows Font Mapping' article says that `FT_WinFNT_ID_OEM` is
   *     used for the charset of vector fonts, like `modern.fon`,
   *     `roman.fon`, and `script.fon` on Windows.
   *
   *     The 'CreateFont' documentation says: The `FT_WinFNT_ID_OEM` value
   *     specifies a character set that is operating-system dependent.
   *
   *     The 'IFIMETRICS' documentation from the 'Windows Driver Development
   *     Kit' says: This font supports an OEM-specific character set.  The
   *     OEM character set is system dependent.
   *
   *     In general OEM, as opposed to ANSI (i.e., 'cp1252'), denotes the
   *     second default codepage that most international versions of Windows
   *     have.  It is one of the OEM codepages from
   *
   *     https://docs.microsoft.com/en-us/windows/desktop/intl/code-page-identifiers
   *     ,
   *
   *     and is used for the 'DOS boxes', to support legacy applications.  A
   *     German Windows version for example usually uses ANSI codepage 1252
   *     and OEM codepage 850.
   *
   *   FT_WinFNT_ID_CP874 ::
   *     A superset of Thai TIS 620 and ISO 8859-11.
   *
   *   FT_WinFNT_ID_CP932 ::
   *     A superset of Japanese Shift-JIS (with minor deviations).
   *
   *   FT_WinFNT_ID_CP936 ::
   *     A superset of simplified Chinese GB 2312-1980 (with different
   *     ordering and minor deviations).
   *
   *   FT_WinFNT_ID_CP949 ::
   *     A superset of Korean Hangul KS~C 5601-1987 (with different ordering
   *     and minor deviations).
   *
   *   FT_WinFNT_ID_CP950 ::
   *     A superset of traditional Chinese Big~5 ETen (with different
   *     ordering and minor deviations).
   *
   *   FT_WinFNT_ID_CP1250 ::
   *     A superset of East European ISO 8859-2 (with slightly different
   *     ordering).
   *
   *   FT_WinFNT_ID_CP1251 ::
   *     A superset of Russian ISO 8859-5 (with different ordering).
   *
   *   FT_WinFNT_ID_CP1252 ::
   *     ANSI encoding.  A superset of ISO 8859-1.
   *
   *   FT_WinFNT_ID_CP1253 ::
   *     A superset of Greek ISO 8859-7 (with minor modifications).
   *
   *   FT_WinFNT_ID_CP1254 ::
   *     A superset of Turkish ISO 8859-9.
   *
   *   FT_WinFNT_ID_CP1255 ::
   *     A superset of Hebrew ISO 8859-8 (with some modifications).
   *
   *   FT_WinFNT_ID_CP1256 ::
   *     A superset of Arabic ISO 8859-6 (with different ordering).
   *
   *   FT_WinFNT_ID_CP1257 ::
   *     A superset of Baltic ISO 8859-13 (with some deviations).
   *
   *   FT_WinFNT_ID_CP1258 ::
   *     For Vietnamese.  This encoding doesn't cover all necessary
   *     characters.
   *
   *   FT_WinFNT_ID_CP1361 ::
   *     Korean (Johab).
   */

#define FT_WinFNT_ID_CP1252    0
#define FT_WinFNT_ID_DEFAULT   1
#define FT_WinFNT_ID_SYMBOL    2
#define FT_WinFNT_ID_MAC      77
#define FT_WinFNT_ID_CP932   128
#define FT_WinFNT_ID_CP949   129
#define FT_WinFNT_ID_CP1361  130
#define FT_WinFNT_ID_CP936   134
#define FT_WinFNT_ID_CP950   136
#define FT_WinFNT_ID_CP1253  161
#define FT_WinFNT_ID_CP1254  162
#define FT_WinFNT_ID_CP1258  163
#define FT_WinFNT_ID_CP1255  177
#define FT_WinFNT_ID_CP1256  178
#define FT_WinFNT_ID_CP1257  186
#define FT_WinFNT_ID_CP1251  204
#define FT_WinFNT_ID_CP874   222
#define FT_WinFNT_ID_CP1250  238
#define FT_WinFNT_ID_OEM     255

  /**************************************************************************
   *
   * @struct:
   *   FT_WinFNT_HeaderRec
   *
   * @description:
   *   Windows FNT Header info.
   */
  typedef struct  FT_WinFNT_HeaderRec_
  {
    FT_UShort  version;
    FT_ULong   file_size;
    FT_Byte    copyright[60];
    FT_UShort  file_type;
    FT_UShort  nominal_point_size;
    FT_UShort  vertical_resolution;
    FT_UShort  horizontal_resolution;
    FT_UShort  ascent;
    FT_UShort  internal_leading;
    FT_UShort  external_leading;
    FT_Byte    italic;
    FT_Byte    underline;
    FT_Byte    strike_out;
    FT_UShort  weight;
    FT_Byte    charset;
    FT_UShort  pixel_width;
    FT_UShort  pixel_height;
    FT_Byte    pitch_and_family;
    FT_UShort  avg_width;
    FT_UShort  max_width;
    FT_Byte    first_char;
    FT_Byte    last_char;
    FT_Byte    default_char;
    FT_Byte    break_char;
    FT_UShort  bytes_per_row;
    FT_ULong   device_offset;
    FT_ULong   face_name_offset;
    FT_ULong   bits_pointer;
    FT_ULong   bits_offset;
    FT_Byte    reserved;
    FT_ULong   flags;
    FT_UShort  A_space;
    FT_UShort  B_space;
    FT_UShort  C_space;
    FT_UShort  color_table_offset;
    FT_ULong   reserved1[4];

  } FT_WinFNT_HeaderRec;

  /**************************************************************************
   *
   * @struct:
   *   FT_WinFNT_Header
   *
   * @description:
   *   A handle to an @FT_WinFNT_HeaderRec structure.
   */
  typedef struct FT_WinFNT_HeaderRec_*  FT_WinFNT_Header;

  /**************************************************************************
   *
   * @function:
   *    FT_Get_WinFNT_Header
   *
   * @description:
   *    Retrieve a Windows FNT font info header.
   *
   * @input:
   *    face ::
   *      A handle to the input face.
   *
   * @output:
   *    aheader ::
   *      The WinFNT header.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   This function only works with Windows FNT faces, returning an error
   *   otherwise.
   */
  FT_EXPORT( FT_Error )
  FT_Get_WinFNT_Header( FT_Face               face,
                        FT_WinFNT_HeaderRec  *aheader );

  /* */

FT_END_HEADER

#endif /* FTWINFNT_H_ */

/* END */

/* Local Variables: */
/* coding: utf-8    */
/* End:             */


text:
/****************************************************************************
 *
 * ftgzip.h
 *
 *   Gzip-compressed stream support.
 *
 * Copyright (C) 2002-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 FTGZIP_H_
#define FTGZIP_H_

#include <ft2build.h>
#include FT_FREETYPE_H

#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif

FT_BEGIN_HEADER

  /**************************************************************************
   *
   * @section:
   *   gzip
   *
   * @title:
   *   GZIP Streams
   *
   * @abstract:
   *   Using gzip-compressed font files.
   *
   * @description:
   *   This section contains the declaration of Gzip-specific functions.
   *
   */

  /**************************************************************************
   *
   * @function:
   *   FT_Stream_OpenGzip
   *
   * @description:
   *   Open a new stream to parse gzip-compressed font files.  This is mainly
   *   used to support the compressed `*.pcf.gz` fonts that come with
   *   XFree86.
   *
   * @input:
   *   stream ::
   *     The target embedding stream.
   *
   *   source ::
   *     The source stream.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   The source stream must be opened _before_ calling this function.
   *
   *   Calling the internal function `FT_Stream_Close` on the new stream will
   *   **not** call `FT_Stream_Close` on the source stream.  None of the
   *   stream objects will be released to the heap.
   *
   *   The stream implementation is very basic and resets the decompression
   *   process each time seeking backwards is needed within the stream.
   *
   *   In certain builds of the library, gzip compression recognition is
   *   automatically handled when calling @FT_New_Face or @FT_Open_Face.
   *   This means that if no font driver is capable of handling the raw
   *   compressed file, the library will try to open a gzipped stream from it
   *   and re-open the face with it.
   *
   *   This function may return `FT_Err_Unimplemented_Feature` if your build
   *   of FreeType was not compiled with zlib support.
   */
  FT_EXPORT( FT_Error )
  FT_Stream_OpenGzip( FT_Stream  stream,
                      FT_Stream  source );

  /**************************************************************************
   *
   * @function:
   *   FT_Gzip_Uncompress
   *
   * @description:
   *   Decompress a zipped input buffer into an output buffer.  This function
   *   is modeled after zlib's `uncompress` function.
   *
   * @input:
   *   memory ::
   *     A FreeType memory handle.
   *
   *   input ::
   *     The input buffer.
   *
   *   input_len ::
   *     The length of the input buffer.
   *
   * @output:
   *   output ::
   *     The output buffer.
   *
   * @inout:
   *   output_len ::
   *     Before calling the function, this is the total size of the output
   *     buffer, which must be large enough to hold the entire uncompressed
   *     data (so the size of the uncompressed data must be known in
   *     advance).  After calling the function, `output_len` is the size of
   *     the used data in `output`.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   This function may return `FT_Err_Unimplemented_Feature` if your build
   *   of FreeType was not compiled with zlib support.
   *
   * @since:
   *   2.5.1
   */
  FT_EXPORT( FT_Error )
  FT_Gzip_Uncompress( FT_Memory       memory,
                      FT_Byte*        output,
                      FT_ULong*       output_len,
                      const FT_Byte*  input,
                      FT_ULong        input_len );

  /* */

FT_END_HEADER

#endif /* FTGZIP_H_ */

/* END */


text:
/****************************************************************************
 *
 * ftbbox.h
 *
 *   FreeType exact bbox computation (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.
 *
 */

  /**************************************************************************
   *
   * This component has a _single_ role: to compute exact outline bounding
   * boxes.
   *
   * It is separated from the rest of the engine for various technical
   * reasons.  It may well be integrated in 'ftoutln' later.
   *
   */

#ifndef FTBBOX_H_
#define FTBBOX_H_

#include <ft2build.h>
#include FT_FREETYPE_H

#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif

FT_BEGIN_HEADER

  /**************************************************************************
   *
   * @section:
   *   outline_processing
   *
   */

  /**************************************************************************
   *
   * @function:
   *   FT_Outline_Get_BBox
   *
   * @description:
   *   Compute the exact bounding box of an outline.  This is slower than
   *   computing the control box.  However, it uses an advanced algorithm
   *   that returns _very_ quickly when the two boxes coincide.  Otherwise,
   *   the outline Bezier arcs are traversed to extract their extrema.
   *
   * @input:
   *   outline ::
   *     A pointer to the source outline.
   *
   * @output:
   *   abbox ::
   *     The outline's exact bounding box.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   If the font is tricky and the glyph has been loaded with
   *   @FT_LOAD_NO_SCALE, the resulting BBox is meaningless.  To get
   *   reasonable values for the BBox it is necessary to load the glyph at a
   *   large ppem value (so that the hinting instructions can properly shift
   *   and scale the subglyphs), then extracting the BBox, which can be
   *   eventually converted back to font units.
   */
  FT_EXPORT( FT_Error )
  FT_Outline_Get_BBox( FT_Outline*  outline,
                       FT_BBox     *abbox );

  /* */

FT_END_HEADER

#endif /* FTBBOX_H_ */

/* END */

/* Local Variables: */
/* coding: utf-8    */
/* End:             */


text:
/****************************************************************************
 *
 * ftmm.h
 *
 *   FreeType Multiple Master font 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 FTMM_H_
#define FTMM_H_

#include <ft2build.h>
#include FT_TYPE1_TABLES_H

FT_BEGIN_HEADER

  /**************************************************************************
   *
   * @section:
   *   multiple_masters
   *
   * @title:
   *   Multiple Masters
   *
   * @abstract:
   *   How to manage Multiple Masters fonts.
   *
   * @description:
   *   The following types and functions are used to manage Multiple Master
   *   fonts, i.e., the selection of specific design instances by setting
   *   design axis coordinates.
   *
   *   Besides Adobe MM fonts, the interface supports Apple's TrueType GX and
   *   OpenType variation fonts.  Some of the routines only work with Adobe
   *   MM fonts, others will work with all three types.  They are similar
   *   enough that a consistent interface makes sense.
   *
   */

  /**************************************************************************
   *
   * @struct:
   *   FT_MM_Axis
   *
   * @description:
   *   A structure to model a given axis in design space for Multiple Masters
   *   fonts.
   *
   *   This structure can't be used for TrueType GX or OpenType variation
   *   fonts.
   *
   * @fields:
   *   name ::
   *     The axis's name.
   *
   *   minimum ::
   *     The axis's minimum design coordinate.
   *
   *   maximum ::
   *     The axis's maximum design coordinate.
   */
  typedef struct  FT_MM_Axis_
  {
    FT_String*  name;
    FT_Long     minimum;
    FT_Long     maximum;

  } FT_MM_Axis;

  /**************************************************************************
   *
   * @struct:
   *   FT_Multi_Master
   *
   * @description:
   *   A structure to model the axes and space of a Multiple Masters font.
   *
   *   This structure can't be used for TrueType GX or OpenType variation
   *   fonts.
   *
   * @fields:
   *   num_axis ::
   *     Number of axes.  Cannot exceed~4.
   *
   *   num_designs ::
   *     Number of designs; should be normally 2^num_axis even though the
   *     Type~1 specification strangely allows for intermediate designs to be
   *     present.  This number cannot exceed~16.
   *
   *   axis ::
   *     A table of axis descriptors.
   */
  typedef struct  FT_Multi_Master_
  {
    FT_UInt     num_axis;
    FT_UInt     num_designs;
    FT_MM_Axis  axis[T1_MAX_MM_AXIS];

  } FT_Multi_Master;

  /**************************************************************************
   *
   * @struct:
   *   FT_Var_Axis
   *
   * @description:
   *   A structure to model a given axis in design space for Multiple
   *   Masters, TrueType GX, and OpenType variation fonts.
   *
   * @fields:
   *   name ::
   *     The axis's name.  Not always meaningful for TrueType GX or OpenType
   *     variation fonts.
   *
   *   minimum ::
   *     The axis's minimum design coordinate.
   *
   *   def ::
   *     The axis's default design coordinate.  FreeType computes meaningful
   *     default values for Adobe MM fonts.
   *
   *   maximum ::
   *     The axis's maximum design coordinate.
   *
   *   tag ::
   *     The axis's tag (the equivalent to 'name' for TrueType GX and
   *     OpenType variation fonts).  FreeType provides default values for
   *     Adobe MM fonts if possible.
   *
   *   strid ::
   *     The axis name entry in the font's 'name' table.  This is another
   *     (and often better) version of the 'name' field for TrueType GX or
   *     OpenType variation fonts.  Not meaningful for Adobe MM fonts.
   *
   * @note:
   *   The fields `minimum`, `def`, and `maximum` are 16.16 fractional values
   *   for TrueType GX and OpenType variation fonts.  For Adobe MM fonts, the
   *   values are integers.
   */
  typedef struct  FT_Var_Axis_
  {
    FT_String*  name;

    FT_Fixed    minimum;
    FT_Fixed    def;
    FT_Fixed    maximum;

    FT_ULong    tag;
    FT_UInt     strid;

  } FT_Var_Axis;

  /**************************************************************************
   *
   * @struct:
   *   FT_Var_Named_Style
   *
   * @description:
   *   A structure to model a named instance in a TrueType GX or OpenType
   *   variation font.
   *
   *   This structure can't be used for Adobe MM fonts.
   *
   * @fields:
   *   coords ::
   *     The design coordinates for this instance.  This is an array with one
   *     entry for each axis.
   *
   *   strid ::
   *     The entry in 'name' table identifying this instance.
   *
   *   psid ::
   *     The entry in 'name' table identifying a PostScript name for this
   *     instance.  Value 0xFFFF indicates a missing entry.
   */
  typedef struct  FT_Var_Named_Style_
  {
    FT_Fixed*  coords;
    FT_UInt    strid;
    FT_UInt    psid;   /* since 2.7.1 */

  } FT_Var_Named_Style;

  /**************************************************************************
   *
   * @struct:
   *   FT_MM_Var
   *
   * @description:
   *   A structure to model the axes and space of an Adobe MM, TrueType GX,
   *   or OpenType variation font.
   *
   *   Some fields are specific to one format and not to the others.
   *
   * @fields:
   *   num_axis ::
   *     The number of axes.  The maximum value is~4 for Adobe MM fonts; no
   *     limit in TrueType GX or OpenType variation fonts.
   *
   *   num_designs ::
   *     The number of designs; should be normally 2^num_axis for Adobe MM
   *     fonts.  Not meaningful for TrueType GX or OpenType variation fonts
   *     (where every glyph could have a different number of designs).
   *
   *   num_namedstyles ::
   *     The number of named styles; a 'named style' is a tuple of design
   *     coordinates that has a string ID (in the 'name' table) associated
   *     with it.  The font can tell the user that, for example,
   *     [Weight=1.5,Width=1.1] is 'Bold'.  Another name for 'named style' is
   *     'named instance'.
   *
   *     For Adobe Multiple Masters fonts, this value is always zero because
   *     the format does not support named styles.
   *
   *   axis ::
   *     An axis descriptor table.  TrueType GX and OpenType variation fonts
   *     contain slightly more data than Adobe MM fonts.  Memory management
   *     of this pointer is done internally by FreeType.
   *
   *   namedstyle ::
   *     A named style (instance) table.  Only meaningful for TrueType GX and
   *     OpenType variation fonts.  Memory management of this pointer is done
   *     internally by FreeType.
   */
  typedef struct  FT_MM_Var_
  {
    FT_UInt              num_axis;
    FT_UInt              num_designs;
    FT_UInt              num_namedstyles;
    FT_Var_Axis*         axis;
    FT_Var_Named_Style*  namedstyle;

  } FT_MM_Var;

  /**************************************************************************
   *
   * @function:
   *   FT_Get_Multi_Master
   *
   * @description:
   *   Retrieve a variation descriptor of a given Adobe MM font.
   *
   *   This function can't be used with TrueType GX or OpenType variation
   *   fonts.
   *
   * @input:
   *   face ::
   *     A handle to the source face.
   *
   * @output:
   *   amaster ::
   *     The Multiple Masters descriptor.
   *
   * @return:
   *   FreeType error code.  0~means success.
   */
  FT_EXPORT( FT_Error )
  FT_Get_Multi_Master( FT_Face           face,
                       FT_Multi_Master  *amaster );

  /**************************************************************************
   *
   * @function:
   *   FT_Get_MM_Var
   *
   * @description:
   *   Retrieve a variation descriptor for a given font.
   *
   *   This function works with all supported variation formats.
   *
   * @input:
   *   face ::
   *     A handle to the source face.
   *
   * @output:
   *   amaster ::
   *     The variation descriptor.  Allocates a data structure, which the
   *     user must deallocate with a call to @FT_Done_MM_Var after use.
   *
   * @return:
   *   FreeType error code.  0~means success.
   */
  FT_EXPORT( FT_Error )
  FT_Get_MM_Var( FT_Face      face,
                 FT_MM_Var*  *amaster );

  /**************************************************************************
   *
   * @function:
   *   FT_Done_MM_Var
   *
   * @description:
   *   Free the memory allocated by @FT_Get_MM_Var.
   *
   * @input:
   *   library ::
   *     A handle of the face's parent library object that was used in the
   *     call to @FT_Get_MM_Var to create `amaster`.
   *
   * @return:
   *   FreeType error code.  0~means success.
   */
  FT_EXPORT( FT_Error )
  FT_Done_MM_Var( FT_Library   library,
                  FT_MM_Var   *amaster );

  /**************************************************************************
   *
   * @function:
   *   FT_Set_MM_Design_Coordinates
   *
   * @description:
   *   For Adobe MM fonts, choose an interpolated font design through design
   *   coordinates.
   *
   *   This function can't be used with TrueType GX or OpenType variation
   *   fonts.
   *
   * @inout:
   *   face ::
   *     A handle to the source face.
   *
   * @input:
   *   num_coords ::
   *     The number of available design coordinates.  If it is larger than
   *     the number of axes, ignore the excess values.  If it is smaller than
   *     the number of axes, use default values for the remaining axes.
   *
   *   coords ::
   *     An array of design coordinates.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   [Since 2.8.1] To reset all axes to the default values, call the
   *   function with `num_coords` set to zero and `coords` set to `NULL`.
   *
   *   [Since 2.9] If `num_coords` is larger than zero, this function sets
   *   the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags` field
   *   (i.e., @FT_IS_VARIATION will return true).  If `num_coords` is zero,
   *   this bit flag gets unset.
   */
  FT_EXPORT( FT_Error )
  FT_Set_MM_Design_Coordinates( FT_Face   face,
                                FT_UInt   num_coords,
                                FT_Long*  coords );

  /**************************************************************************
   *
   * @function:
   *   FT_Set_Var_Design_Coordinates
   *
   * @description:
   *   Choose an interpolated font design through design coordinates.
   *
   *   This function works with all supported variation formats.
   *
   * @inout:
   *   face ::
   *     A handle to the source face.
   *
   * @input:
   *   num_coords ::
   *     The number of available design coordinates.  If it is larger than
   *     the number of axes, ignore the excess values.  If it is smaller than
   *     the number of axes, use default values for the remaining axes.
   *
   *   coords ::
   *     An array of design coordinates.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   [Since 2.8.1] To reset all axes to the default values, call the
   *   function with `num_coords` set to zero and `coords` set to `NULL`.
   *   [Since 2.9] 'Default values' means the currently selected named
   *   instance (or the base font if no named instance is selected).
   *
   *   [Since 2.9] If `num_coords` is larger than zero, this function sets
   *   the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags` field
   *   (i.e., @FT_IS_VARIATION will return true).  If `num_coords` is zero,
   *   this bit flag gets unset.
   */
  FT_EXPORT( FT_Error )
  FT_Set_Var_Design_Coordinates( FT_Face    face,
                                 FT_UInt    num_coords,
                                 FT_Fixed*  coords );

  /**************************************************************************
   *
   * @function:
   *   FT_Get_Var_Design_Coordinates
   *
   * @description:
   *   Get the design coordinates of the currently selected interpolated
   *   font.
   *
   *   This function works with all supported variation formats.
   *
   * @input:
   *   face ::
   *     A handle to the source face.
   *
   *   num_coords ::
   *     The number of design coordinates to retrieve.  If it is larger than
   *     the number of axes, set the excess values to~0.
   *
   * @output:
   *   coords ::
   *     The design coordinates array.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @since:
   *   2.7.1
   */
  FT_EXPORT( FT_Error )
  FT_Get_Var_Design_Coordinates( FT_Face    face,
                                 FT_UInt    num_coords,
                                 FT_Fixed*  coords );

  /**************************************************************************
   *
   * @function:
   *   FT_Set_MM_Blend_Coordinates
   *
   * @description:
   *   Choose an interpolated font design through normalized blend
   *   coordinates.
   *
   *   This function works with all supported variation formats.
   *
   * @inout:
   *   face ::
   *     A handle to the source face.
   *
   * @input:
   *   num_coords ::
   *     The number of available design coordinates.  If it is larger than
   *     the number of axes, ignore the excess values.  If it is smaller than
   *     the number of axes, use default values for the remaining axes.
   *
   *   coords ::
   *     The design coordinates array (each element must be between 0 and 1.0
   *     for Adobe MM fonts, and between -1.0 and 1.0 for TrueType GX and
   *     OpenType variation fonts).
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   [Since 2.8.1] To reset all axes to the default values, call the
   *   function with `num_coords` set to zero and `coords` set to `NULL`.
   *   [Since 2.9] 'Default values' means the currently selected named
   *   instance (or the base font if no named instance is selected).
   *
   *   [Since 2.9] If `num_coords` is larger than zero, this function sets
   *   the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags` field
   *   (i.e., @FT_IS_VARIATION will return true).  If `num_coords` is zero,
   *   this bit flag gets unset.
   */
  FT_EXPORT( FT_Error )
  FT_Set_MM_Blend_Coordinates( FT_Face    face,
                               FT_UInt    num_coords,
                               FT_Fixed*  coords );

  /**************************************************************************
   *
   * @function:
   *   FT_Get_MM_Blend_Coordinates
   *
   * @description:
   *   Get the normalized blend coordinates of the currently selected
   *   interpolated font.
   *
   *   This function works with all supported variation formats.
   *
   * @input:
   *   face ::
   *     A handle to the source face.
   *
   *   num_coords ::
   *     The number of normalized blend coordinates to retrieve.  If it is
   *     larger than the number of axes, set the excess values to~0.5 for
   *     Adobe MM fonts, and to~0 for TrueType GX and OpenType variation
   *     fonts.
   *
   * @output:
   *   coords ::
   *     The normalized blend coordinates array.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @since:
   *   2.7.1
   */
  FT_EXPORT( FT_Error )
  FT_Get_MM_Blend_Coordinates( FT_Face    face,
                               FT_UInt    num_coords,
                               FT_Fixed*  coords );

  /**************************************************************************
   *
   * @function:
   *   FT_Set_Var_Blend_Coordinates
   *
   * @description:
   *   This is another name of @FT_Set_MM_Blend_Coordinates.
   */
  FT_EXPORT( FT_Error )
  FT_Set_Var_Blend_Coordinates( FT_Face    face,
                                FT_UInt    num_coords,
                                FT_Fixed*  coords );

  /**************************************************************************
   *
   * @function:
   *   FT_Get_Var_Blend_Coordinates
   *
   * @description:
   *   This is another name of @FT_Get_MM_Blend_Coordinates.
   *
   * @since:
   *   2.7.1
   */
  FT_EXPORT( FT_Error )
  FT_Get_Var_Blend_Coordinates( FT_Face    face,
                                FT_UInt    num_coords,
                                FT_Fixed*  coords );

  /**************************************************************************
   *
   * @function:
   *   FT_Set_MM_WeightVector
   *
   * @description:
   *   For Adobe MM fonts, choose an interpolated font design by directly
   *   setting the weight vector.
   *
   *   This function can't be used with TrueType GX or OpenType variation
   *   fonts.
   *
   * @inout:
   *   face ::
   *     A handle to the source face.
   *
   * @input:
   *   len ::
   *     The length of the weight vector array.  If it is larger than the
   *     number of designs, the extra values are ignored.  If it is less than
   *     the number of designs, the remaining values are set to zero.
   *
   *   weightvector ::
   *     An array representing the weight vector.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   Adobe Multiple Master fonts limit the number of designs, and thus the
   *   length of the weight vector to~16.
   *
   *   If `len` is zero and `weightvector` is `NULL`, the weight vector array
   *   is reset to the default values.
   *
   *   The Adobe documentation also states that the values in the
   *   WeightVector array must total 1.0 +/-~0.001.  In practice this does
   *   not seem to be enforced, so is not enforced here, either.
   *
   * @since:
   *   2.10
   */
  FT_EXPORT( FT_Error )
  FT_Set_MM_WeightVector( FT_Face    face,
                          FT_UInt    len,
                          FT_Fixed*  weightvector );

  /**************************************************************************
   *
   * @function:
   *   FT_Get_MM_WeightVector
   *
   * @description:
   *   For Adobe MM fonts, retrieve the current weight vector of the font.
   *
   *   This function can't be used with TrueType GX or OpenType variation
   *   fonts.
   *
   * @inout:
   *   face ::
   *     A handle to the source face.
   *
   *   len ::
   *     A pointer to the size of the array to be filled.  If the size of the
   *     array is less than the number of designs, `FT_Err_Invalid_Argument`
   *     is returned, and `len` is set to the required size (the number of
   *     designs).  If the size of the array is greater than the number of
   *     designs, the remaining entries are set to~0.  On successful
   *     completion, `len` is set to the number of designs (i.e., the number
   *     of values written to the array).
   *
   * @output:
   *   weightvector ::
   *     An array to be filled.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   Adobe Multiple Master fonts limit the number of designs, and thus the
   *   length of the WeightVector to~16.
   *
   * @since:
   *   2.10
   */
  FT_EXPORT( FT_Error )
  FT_Get_MM_WeightVector( FT_Face    face,
                          FT_UInt*   len,
                          FT_Fixed*  weightvector );

  /**************************************************************************
   *
   * @enum:
   *   FT_VAR_AXIS_FLAG_XXX
   *
   * @description:
   *   A list of bit flags used in the return value of
   *   @FT_Get_Var_Axis_Flags.
   *
   * @values:
   *   FT_VAR_AXIS_FLAG_HIDDEN ::
   *     The variation axis should not be exposed to user interfaces.
   *
   * @since:
   *   2.8.1
   */
#define FT_VAR_AXIS_FLAG_HIDDEN  1

  /**************************************************************************
   *
   * @function:
   *   FT_Get_Var_Axis_Flags
   *
   * @description:
   *   Get the 'flags' field of an OpenType Variation Axis Record.
   *
   *   Not meaningful for Adobe MM fonts (`*flags` is always zero).
   *
   * @input:
   *   master ::
   *     The variation descriptor.
   *
   *   axis_index ::
   *     The index of the requested variation axis.
   *
   * @output:
   *   flags ::
   *     The 'flags' field.  See @FT_VAR_AXIS_FLAG_XXX for possible values.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @since:
   *   2.8.1
   */
  FT_EXPORT( FT_Error )
  FT_Get_Var_Axis_Flags( FT_MM_Var*  master,
                         FT_UInt     axis_index,
                         FT_UInt*    flags );

  /**************************************************************************
   *
   * @function:
   *   FT_Set_Named_Instance
   *
   * @description:
   *   Set or change the current named instance.
   *
   * @input:
   *   face ::
   *     A handle to the source face.
   *
   *   instance_index ::
   *     The index of the requested instance, starting with value 1.  If set
   *     to value 0, FreeType switches to font access without a named
   *     instance.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   The function uses the value of `instance_index` to set bits 16-30 of
   *   the face's `face_index` field.  It also resets any variation applied
   *   to the font, and the @FT_FACE_FLAG_VARIATION bit of the face's
   *   `face_flags` field gets reset to zero (i.e., @FT_IS_VARIATION will
   *   return false).
   *
   *   For Adobe MM fonts (which don't have named instances) this function
   *   simply resets the current face to the default instance.
   *
   * @since:
   *   2.9
   */
  FT_EXPORT( FT_Error )
  FT_Set_Named_Instance( FT_Face  face,
                         FT_UInt  instance_index );

  /* */

FT_END_HEADER

#endif /* FTMM_H_ */

/* END */


text:
/****************************************************************************
 *
 * ftmodapi.h
 *
 *   FreeType modules public 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 FTMODAPI_H_
#define FTMODAPI_H_

#include <ft2build.h>
#include FT_FREETYPE_H

#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif

FT_BEGIN_HEADER

  /**************************************************************************
   *
   * @section:
   *   module_management
   *
   * @title:
   *   Module Management
   *
   * @abstract:
   *   How to add, upgrade, remove, and control modules from FreeType.
   *
   * @description:
   *   The definitions below are used to manage modules within FreeType.
   *   Modules can be added, upgraded, and removed at runtime.  Additionally,
   *   some module properties can be controlled also.
   *
   *   Here is a list of possible values of the `module_name` field in the
   *   @FT_Module_Class structure.
   *
   *   ```
   *     autofitter
   *     bdf
   *     cff
   *     gxvalid
   *     otvalid
   *     pcf
   *     pfr
   *     psaux
   *     pshinter
   *     psnames
   *     raster1
   *     sfnt
   *     smooth, smooth-lcd, smooth-lcdv
   *     truetype
   *     type1
   *     type42
   *     t1cid
   *     winfonts
   *   ```
   *
   *   Note that the FreeType Cache sub-system is not a FreeType module.
   *
   * @order:
   *   FT_Module
   *   FT_Module_Constructor
   *   FT_Module_Destructor
   *   FT_Module_Requester
   *   FT_Module_Class
   *
   *   FT_Add_Module
   *   FT_Get_Module
   *   FT_Remove_Module
   *   FT_Add_Default_Modules
   *
   *   FT_Property_Set
   *   FT_Property_Get
   *   FT_Set_Default_Properties
   *
   *   FT_New_Library
   *   FT_Done_Library
   *   FT_Reference_Library
   *
   *   FT_Renderer
   *   FT_Renderer_Class
   *
   *   FT_Get_Renderer
   *   FT_Set_Renderer
   *
   *   FT_Set_Debug_Hook
   *
   */

  /* module bit flags */
#define FT_MODULE_FONT_DRIVER         1  /* this module is a font driver  */
#define FT_MODULE_RENDERER            2  /* this module is a renderer     */
#define FT_MODULE_HINTER              4  /* this module is a glyph hinter */
#define FT_MODULE_STYLER              8  /* this module is a styler       */

#define FT_MODULE_DRIVER_SCALABLE      0x100  /* the driver supports      */
                                              /* scalable fonts           */
#define FT_MODULE_DRIVER_NO_OUTLINES   0x200  /* the driver does not      */
                                              /* support vector outlines  */
#define FT_MODULE_DRIVER_HAS_HINTER    0x400  /* the driver provides its  */
                                              /* own hinter               */
#define FT_MODULE_DRIVER_HINTS_LIGHTLY 0x800  /* the driver's hinter      */
                                              /* produces LIGHT hints     */

  /* deprecated values */
#define ft_module_font_driver         FT_MODULE_FONT_DRIVER
#define ft_module_renderer            FT_MODULE_RENDERER
#define ft_module_hinter              FT_MODULE_HINTER
#define ft_module_styler              FT_MODULE_STYLER

#define ft_module_driver_scalable       FT_MODULE_DRIVER_SCALABLE
#define ft_module_driver_no_outlines    FT_MODULE_DRIVER_NO_OUTLINES
#define ft_module_driver_has_hinter     FT_MODULE_DRIVER_HAS_HINTER
#define ft_module_driver_hints_lightly  FT_MODULE_DRIVER_HINTS_LIGHTLY

  typedef FT_Pointer  FT_Module_Interface;

  /**************************************************************************
   *
   * @functype:
   *   FT_Module_Constructor
   *
   * @description:
   *   A function used to initialize (not create) a new module object.
   *
   * @input:
   *   module ::
   *     The module to initialize.
   */
  typedef FT_Error
  (*FT_Module_Constructor)( FT_Module  module );

  /**************************************************************************
   *
   * @functype:
   *   FT_Module_Destructor
   *
   * @description:
   *   A function used to finalize (not destroy) a given module object.
   *
   * @input:
   *   module ::
   *     The module to finalize.
   */
  typedef void
  (*FT_Module_Destructor)( FT_Module  module );

  /**************************************************************************
   *
   * @functype:
   *   FT_Module_Requester
   *
   * @description:
   *   A function used to query a given module for a specific interface.
   *
   * @input:
   *   module ::
   *     The module to be searched.
   *
   *   name ::
   *     The name of the interface in the module.
   */
  typedef FT_Module_Interface
  (*FT_Module_Requester)( FT_Module    module,
                          const char*  name );

  /**************************************************************************
   *
   * @struct:
   *   FT_Module_Class
   *
   * @description:
   *   The module class descriptor.  While being a public structure necessary
   *   for FreeType's module bookkeeping, most of the fields are essentially
   *   internal, not to be used directly by an application.
   *
   * @fields:
   *   module_flags ::
   *     Bit flags describing the module.
   *
   *   module_size ::
   *     The size of one module object/instance in bytes.
   *
   *   module_name ::
   *     The name of the module.
   *
   *   module_version ::
   *     The version, as a 16.16 fixed number (major.minor).
   *
   *   module_requires ::
   *     The version of FreeType this module requires, as a 16.16 fixed
   *     number (major.minor).  Starts at version 2.0, i.e., 0x20000.
   *
   *   module_interface ::
   *     A typeless pointer to a structure (which varies between different
   *     modules) that holds the module's interface functions.  This is
   *     essentially what `get_interface` returns.
   *
   *   module_init ::
   *     The initializing function.
   *
   *   module_done ::
   *     The finalizing function.
   *
   *   get_interface ::
   *     The interface requesting function.
   */
  typedef struct  FT_Module_Class_
  {
    FT_ULong               module_flags;
    FT_Long                module_size;
    const FT_String*       module_name;
    FT_Fixed               module_version;
    FT_Fixed               module_requires;

    const void*            module_interface;

    FT_Module_Constructor  module_init;
    FT_Module_Destructor   module_done;
    FT_Module_Requester    get_interface;

  } FT_Module_Class;

  /**************************************************************************
   *
   * @function:
   *   FT_Add_Module
   *
   * @description:
   *   Add a new module to a given library instance.
   *
   * @inout:
   *   library ::
   *     A handle to the library object.
   *
   * @input:
   *   clazz ::
   *     A pointer to class descriptor for the module.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   An error will be returned if a module already exists by that name, or
   *   if the module requires a version of FreeType that is too great.
   */
  FT_EXPORT( FT_Error )
  FT_Add_Module( FT_Library              library,
                 const FT_Module_Class*  clazz );

  /**************************************************************************
   *
   * @function:
   *   FT_Get_Module
   *
   * @description:
   *   Find a module by its name.
   *
   * @input:
   *   library ::
   *     A handle to the library object.
   *
   *   module_name ::
   *     The module's name (as an ASCII string).
   *
   * @return:
   *   A module handle.  0~if none was found.
   *
   * @note:
   *   FreeType's internal modules aren't documented very well, and you
   *   should look up the source code for details.
   */
  FT_EXPORT( FT_Module )
  FT_Get_Module( FT_Library   library,
                 const char*  module_name );

  /**************************************************************************
   *
   * @function:
   *   FT_Remove_Module
   *
   * @description:
   *   Remove a given module from a library instance.
   *
   * @inout:
   *   library ::
   *     A handle to a library object.
   *
   * @input:
   *   module ::
   *     A handle to a module object.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   The module object is destroyed by the function in case of success.
   */
  FT_EXPORT( FT_Error )
  FT_Remove_Module( FT_Library  library,
                    FT_Module   module );

  /**************************************************************************
   *
   * @function:
   *    FT_Property_Set
   *
   * @description:
   *    Set a property for a given module.
   *
   * @input:
   *    library ::
   *      A handle to the library the module is part of.
   *
   *    module_name ::
   *      The module name.
   *
   *    property_name ::
   *      The property name.  Properties are described in section
   *      @properties.
   *
   *      Note that only a few modules have properties.
   *
   *    value ::
   *      A generic pointer to a variable or structure that gives the new
   *      value of the property.  The exact definition of `value` is
   *      dependent on the property; see section @properties.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *    If `module_name` isn't a valid module name, or `property_name`
   *    doesn't specify a valid property, or if `value` doesn't represent a
   *    valid value for the given property, an error is returned.
   *
   *    The following example sets property 'bar' (a simple integer) in
   *    module 'foo' to value~1.
   *
   *    ```
   *      FT_UInt  bar;
   *
   *
   *      bar = 1;
   *      FT_Property_Set( library, "foo", "bar", &bar );
   *    ```
   *
   *    Note that the FreeType Cache sub-system doesn't recognize module
   *    property changes.  To avoid glyph lookup confusion within the cache
   *    you should call @FTC_Manager_Reset to completely flush the cache if a
   *    module property gets changed after @FTC_Manager_New has been called.
   *
   *    It is not possible to set properties of the FreeType Cache sub-system
   *    itself with FT_Property_Set; use @FTC_Property_Set instead.
   *
   * @since:
   *   2.4.11
   *
   */
  FT_EXPORT( FT_Error )
  FT_Property_Set( FT_Library        library,
                   const FT_String*  module_name,
                   const FT_String*  property_name,
                   const void*       value );

  /**************************************************************************
   *
   * @function:
   *    FT_Property_Get
   *
   * @description:
   *    Get a module's property value.
   *
   * @input:
   *    library ::
   *      A handle to the library the module is part of.
   *
   *    module_name ::
   *      The module name.
   *
   *    property_name ::
   *      The property name.  Properties are described in section
   *      @properties.
   *
   * @inout:
   *    value ::
   *      A generic pointer to a variable or structure that gives the value
   *      of the property.  The exact definition of `value` is dependent on
   *      the property; see section @properties.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *    If `module_name` isn't a valid module name, or `property_name`
   *    doesn't specify a valid property, or if `value` doesn't represent a
   *    valid value for the given property, an error is returned.
   *
   *    The following example gets property 'baz' (a range) in module 'foo'.
   *
   *    ```
   *      typedef  range_
   *      {
   *        FT_Int32  min;
   *        FT_Int32  max;
   *
   *      } range;
   *
   *      range  baz;
   *
   *
   *      FT_Property_Get( library, "foo", "baz", &baz );
   *    ```
   *
   *    It is not possible to retrieve properties of the FreeType Cache
   *    sub-system with FT_Property_Get; use @FTC_Property_Get instead.
   *
   * @since:
   *   2.4.11
   *
   */
  FT_EXPORT( FT_Error )
  FT_Property_Get( FT_Library        library,
                   const FT_String*  module_name,
                   const FT_String*  property_name,
                   void*             value );

  /**************************************************************************
   *
   * @function:
   *   FT_Set_Default_Properties
   *
   * @description:
   *   If compilation option `FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES` is
   *   set, this function reads the `FREETYPE_PROPERTIES` environment
   *   variable to control driver properties.  See section @properties for
   *   more.
   *
   *   If the compilation option is not set, this function does nothing.
   *
   *   `FREETYPE_PROPERTIES` has the following syntax form (broken here into
   *   multiple lines for better readability).
   *
   *   ```
   *     <optional whitespace>
   *     <module-name1> ':'
   *     <property-name1> '=' <property-value1>
   *     <whitespace>
   *     <module-name2> ':'
   *     <property-name2> '=' <property-value2>
   *     ...
   *   ```
   *
   *   Example:
   *
   *   ```
   *     FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
   *                         cff:no-stem-darkening=1 \
   *                         autofitter:warping=1
   *   ```
   *
   * @inout:
   *   library ::
   *     A handle to a new library object.
   *
   * @since:
   *   2.8
   */
  FT_EXPORT( void )
  FT_Set_Default_Properties( FT_Library  library );

  /**************************************************************************
   *
   * @function:
   *   FT_Reference_Library
   *
   * @description:
   *   A counter gets initialized to~1 at the time an @FT_Library structure
   *   is created.  This function increments the counter.  @FT_Done_Library
   *   then only destroys a library if the counter is~1, otherwise it simply
   *   decrements the counter.
   *
   *   This function helps in managing life-cycles of structures that
   *   reference @FT_Library objects.
   *
   * @input:
   *   library ::
   *     A handle to a target library object.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @since:
   *   2.4.2
   */
  FT_EXPORT( FT_Error )
  FT_Reference_Library( FT_Library  library );

  /**************************************************************************
   *
   * @function:
   *   FT_New_Library
   *
   * @description:
   *   This function is used to create a new FreeType library instance from a
   *   given memory object.  It is thus possible to use libraries with
   *   distinct memory allocators within the same program.  Note, however,
   *   that the used @FT_Memory structure is expected to remain valid for the
   *   life of the @FT_Library object.
   *
   *   Normally, you would call this function (followed by a call to
   *   @FT_Add_Default_Modules or a series of calls to @FT_Add_Module, and a
   *   call to @FT_Set_Default_Properties) instead of @FT_Init_FreeType to
   *   initialize the FreeType library.
   *
   *   Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a library
   *   instance.
   *
   * @input:
   *   memory ::
   *     A handle to the original memory object.
   *
   * @output:
   *   alibrary ::
   *     A pointer to handle of a new library object.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   See the discussion of reference counters in the description of
   *   @FT_Reference_Library.
   */
  FT_EXPORT( FT_Error )
  FT_New_Library( FT_Memory    memory,
                  FT_Library  *alibrary );

  /**************************************************************************
   *
   * @function:
   *   FT_Done_Library
   *
   * @description:
   *   Discard a given library object.  This closes all drivers and discards
   *   all resource objects.
   *
   * @input:
   *   library ::
   *     A handle to the target library.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   See the discussion of reference counters in the description of
   *   @FT_Reference_Library.
   */
  FT_EXPORT( FT_Error )
  FT_Done_Library( FT_Library  library );

  /**************************************************************************
   *
   * @functype:
   *   FT_DebugHook_Func
   *
   * @description:
   *   A drop-in replacement (or rather a wrapper) for the bytecode or
   *   charstring interpreter's main loop function.
   *
   *   Its job is essentially
   *
   *   - to activate debug mode to enforce single-stepping,
   *
   *   - to call the main loop function to interpret the next opcode, and
   *
   *   - to show the changed context to the user.
   *
   *   An example for such a main loop function is `TT_RunIns` (declared in
   *   FreeType's internal header file `src/truetype/ttinterp.h`).
   *
   *   Have a look at the source code of the `ttdebug` FreeType demo program
   *   for an example of a drop-in replacement.
   *
   * @inout:
   *   arg ::
   *     A typeless pointer, to be cast to the main loop function's data
   *     structure (which depends on the font module).  For TrueType fonts
   *     it is bytecode interpreter's execution context, `TT_ExecContext`,
   *     which is declared in FreeType's internal header file `tttypes.h`.
   */
  typedef FT_Error
  (*FT_DebugHook_Func)( void*  arg );

  /**************************************************************************
   *
   * @enum:
   *   FT_DEBUG_HOOK_XXX
   *
   * @description:
   *   A list of named debug hook indices.
   *
   * @values:
   *   FT_DEBUG_HOOK_TRUETYPE::
   *     This hook index identifies the TrueType bytecode debugger.
   */
#define FT_DEBUG_HOOK_TRUETYPE  0

  /**************************************************************************
   *
   * @function:
   *   FT_Set_Debug_Hook
   *
   * @description:
   *   Set a debug hook function for debugging the interpreter of a font
   *   format.
   *
   *   While this is a public API function, an application needs access to
   *   FreeType's internal header files to do something useful.
   *
   *   Have a look at the source code of the `ttdebug` FreeType demo program
   *   for an example of its usage.
   *
   * @inout:
   *   library ::
   *     A handle to the library object.
   *
   * @input:
   *   hook_index ::
   *     The index of the debug hook.  You should use defined enumeration
   *     macros like @FT_DEBUG_HOOK_TRUETYPE.
   *
   *   debug_hook ::
   *     The function used to debug the interpreter.
   *
   * @note:
   *   Currently, four debug hook slots are available, but only one (for the
   *   TrueType interpreter) is defined.
   */
  FT_EXPORT( void )
  FT_Set_Debug_Hook( FT_Library         library,
                     FT_UInt            hook_index,
                     FT_DebugHook_Func  debug_hook );

  /**************************************************************************
   *
   * @function:
   *   FT_Add_Default_Modules
   *
   * @description:
   *   Add the set of default drivers to a given library object.  This is
   *   only useful when you create a library object with @FT_New_Library
   *   (usually to plug a custom memory manager).
   *
   * @inout:
   *   library ::
   *     A handle to a new library object.
   */
  FT_EXPORT( void )
  FT_Add_Default_Modules( FT_Library  library );

  /**************************************************************************
   *
   * @section:
   *   truetype_engine
   *
   * @title:
   *   The TrueType Engine
   *
   * @abstract:
   *   TrueType bytecode support.
   *
   * @description:
   *   This section contains a function used to query the level of TrueType
   *   bytecode support compiled in this version of the library.
   *
   */

  /**************************************************************************
   *
   * @enum:
   *    FT_TrueTypeEngineType
   *
   * @description:
   *    A list of values describing which kind of TrueType bytecode engine is
   *    implemented in a given FT_Library instance.  It is used by the
   *    @FT_Get_TrueType_Engine_Type function.
   *
   * @values:
   *    FT_TRUETYPE_ENGINE_TYPE_NONE ::
   *      The library doesn't implement any kind of bytecode interpreter.
   *
   *    FT_TRUETYPE_ENGINE_TYPE_UNPATENTED ::
   *      Deprecated and removed.
   *
   *    FT_TRUETYPE_ENGINE_TYPE_PATENTED ::
   *      The library implements a bytecode interpreter that covers the full
   *      instruction set of the TrueType virtual machine (this was governed
   *      by patents until May 2010, hence the name).
   *
   * @since:
   *    2.2
   *
   */
  typedef enum  FT_TrueTypeEngineType_
  {
    FT_TRUETYPE_ENGINE_TYPE_NONE = 0,
    FT_TRUETYPE_ENGINE_TYPE_UNPATENTED,
    FT_TRUETYPE_ENGINE_TYPE_PATENTED

  } FT_TrueTypeEngineType;

  /**************************************************************************
   *
   * @function:
   *    FT_Get_TrueType_Engine_Type
   *
   * @description:
   *    Return an @FT_TrueTypeEngineType value to indicate which level of the
   *    TrueType virtual machine a given library instance supports.
   *
   * @input:
   *    library ::
   *      A library instance.
   *
   * @return:
   *    A value indicating which level is supported.
   *
   * @since:
   *    2.2
   *
   */
  FT_EXPORT( FT_TrueTypeEngineType )
  FT_Get_TrueType_Engine_Type( FT_Library  library );

  /* */

FT_END_HEADER

#endif /* FTMODAPI_H_ */

/* END */


text:
/****************************************************************************
 *
 * ftcolor.h
 *
 *   FreeType's glyph color management (specification).
 *
 * Copyright (C) 2018-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 FTCOLOR_H_
#define FTCOLOR_H_

#include <ft2build.h>
#include FT_FREETYPE_H

#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif

FT_BEGIN_HEADER

  /**************************************************************************
   *
   * @section:
   *   color_management
   *
   * @title:
   *   Glyph Color Management
   *
   * @abstract:
   *   Retrieving and manipulating OpenType's 'CPAL' table data.
   *
   * @description:
   *   The functions described here allow access and manipulation of color
   *   palette entries in OpenType's 'CPAL' tables.
   */

  /**************************************************************************
   *
   * @struct:
   *   FT_Color
   *
   * @description:
   *   This structure models a BGRA color value of a 'CPAL' palette entry.
   *
   *   The used color space is sRGB; the colors are not pre-multiplied, and
   *   alpha values must be explicitly set.
   *
   * @fields:
   *   blue ::
   *     Blue value.
   *
   *   green ::
   *     Green value.
   *
   *   red ::
   *     Red value.
   *
   *   alpha ::
   *     Alpha value, giving the red, green, and blue color's opacity.
   *
   * @since:
   *   2.10
   */
  typedef struct  FT_Color_
  {
    FT_Byte  blue;
    FT_Byte  green;
    FT_Byte  red;
    FT_Byte  alpha;

  } FT_Color;

  /**************************************************************************
   *
   * @enum:
   *   FT_PALETTE_XXX
   *
   * @description:
   *   A list of bit field constants used in the `palette_flags` array of the
   *   @FT_Palette_Data structure to indicate for which background a palette
   *   with a given index is usable.
   *
   * @values:
   *   FT_PALETTE_FOR_LIGHT_BACKGROUND ::
   *     The palette is appropriate to use when displaying the font on a
   *     light background such as white.
   *
   *   FT_PALETTE_FOR_DARK_BACKGROUND ::
   *     The palette is appropriate to use when displaying the font on a dark
   *     background such as black.
   *
   * @since:
   *   2.10
   */
#define FT_PALETTE_FOR_LIGHT_BACKGROUND  0x01
#define FT_PALETTE_FOR_DARK_BACKGROUND   0x02

  /**************************************************************************
   *
   * @struct:
   *   FT_Palette_Data
   *
   * @description:
   *   This structure holds the data of the 'CPAL' table.
   *
   * @fields:
   *   num_palettes ::
   *     The number of palettes.
   *
   *   palette_name_ids ::
   *     An optional read-only array of palette name IDs with `num_palettes`
   *     elements, corresponding to entries like 'dark' or 'light' in the
   *     font's 'name' table.
   *
   *     An empty name ID in the 'CPAL' table gets represented as value
   *     0xFFFF.
   *
   *     `NULL` if the font's 'CPAL' table doesn't contain appropriate data.
   *
   *   palette_flags ::
   *     An optional read-only array of palette flags with `num_palettes`
   *     elements.  Possible values are an ORed combination of
   *     @FT_PALETTE_FOR_LIGHT_BACKGROUND and
   *     @FT_PALETTE_FOR_DARK_BACKGROUND.
   *
   *     `NULL` if the font's 'CPAL' table doesn't contain appropriate data.
   *
   *   num_palette_entries ::
   *     The number of entries in a single palette.  All palettes have the
   *     same size.
   *
   *   palette_entry_name_ids ::
   *     An optional read-only array of palette entry name IDs with
   *     `num_palette_entries`.  In each palette, entries with the same index
   *     have the same function.  For example, index~0 might correspond to
   *     string 'outline' in the font's 'name' table to indicate that this
   *     palette entry is used for outlines, index~1 might correspond to
   *     'fill' to indicate the filling color palette entry, etc.
   *
   *     An empty entry name ID in the 'CPAL' table gets represented as value
   *     0xFFFF.
   *
   *     `NULL` if the font's 'CPAL' table doesn't contain appropriate data.
   *
   * @note:
   *   Use function @FT_Get_Sfnt_Name to map name IDs and entry name IDs to
   *   name strings.
   *
   *   Use function @FT_Palette_Select to get the colors associated with a
   *   palette entry.
   *
   * @since:
   *   2.10
   */
  typedef struct  FT_Palette_Data_ {
    FT_UShort         num_palettes;
    const FT_UShort*  palette_name_ids;
    const FT_UShort*  palette_flags;

    FT_UShort         num_palette_entries;
    const FT_UShort*  palette_entry_name_ids;

  } FT_Palette_Data;

  /**************************************************************************
   *
   * @function:
   *   FT_Palette_Data_Get
   *
   * @description:
   *   Retrieve the face's color palette data.
   *
   * @input:
   *   face ::
   *     The source face handle.
   *
   * @output:
   *   apalette ::
   *     A pointer to an @FT_Palette_Data structure.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   All arrays in the returned @FT_Palette_Data structure are read-only.
   *
   *   This function always returns an error if the config macro
   *   `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`.
   *
   * @since:
   *   2.10
   */
  FT_EXPORT( FT_Error )
  FT_Palette_Data_Get( FT_Face           face,
                       FT_Palette_Data  *apalette );

  /**************************************************************************
   *
   * @function:
   *   FT_Palette_Select
   *
   * @description:
   *   This function has two purposes.
   *
   *   (1) It activates a palette for rendering color glyphs, and
   *
   *   (2) it retrieves all (unmodified) color entries of this palette.  This
   *       function returns a read-write array, which means that a calling
   *       application can modify the palette entries on demand.
   *
   * A corollary of (2) is that calling the function, then modifying some
   * values, then calling the function again with the same arguments resets
   * all color entries to the original 'CPAL' values; all user modifications
   * are lost.
   *
   * @input:
   *   face ::
   *     The source face handle.
   *
   *   palette_index ::
   *     The palette index.
   *
   * @output:
   *   apalette ::
   *     An array of color entries for a palette with index `palette_index`,
   *     having `num_palette_entries` elements (as found in the
   *     `FT_Palette_Data` structure).  If `apalette` is set to `NULL`, no
   *     array gets returned (and no color entries can be modified).
   *
   *     In case the font doesn't support color palettes, `NULL` is returned.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   The array pointed to by `apalette_entries` is owned and managed by
   *   FreeType.
   *
   *   This function always returns an error if the config macro
   *   `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`.
   *
   * @since:
   *   2.10
   */
  FT_EXPORT( FT_Error )
  FT_Palette_Select( FT_Face     face,
                     FT_UShort   palette_index,
                     FT_Color*  *apalette );

  /**************************************************************************
   *
   * @function:
   *   FT_Palette_Set_Foreground_Color
   *
   * @description:
   *   'COLR' uses palette index 0xFFFF to indicate a 'text foreground
   *   color'.  This function sets this value.
   *
   * @input:
   *   face ::
   *     The source face handle.
   *
   *   foreground_color ::
   *     An `FT_Color` structure to define the text foreground color.
   *
   * @return:
   *   FreeType error code.  0~means success.
   *
   * @note:
   *   If this function isn't called, the text foreground color is set to
   *   white opaque (BGRA value 0xFFFFFFFF) if
   *   @FT_PALETTE_FOR_DARK_BACKGROUND is present for the current palette,
   *   and black opaque (BGRA value 0x000000FF) otherwise, including the case
   *   that no palette types are available in the 'CPAL' table.
   *
   *   This function always returns an error if the config macro
   *   `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`.
   *
   * @since:
   *   2.10
   */
  FT_EXPORT( FT_Error )
  FT_Palette_Set_Foreground_Color( FT_Face   face,
                                   FT_Color  foreground_color );

  /* */

FT_END_HEADER

#endif /* FTCOLOR_H_ */

/* END */