# Configure paths for FreeType2
# Marcelo Magallon 2001-10-26, based on `gtk.m4` by Owen Taylor
#
# Copyright (C) 2001-2022 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.
#
# As a special exception to the FreeType project license, this file may be
# distributed as part of a program that contains a configuration script
# generated by Autoconf, under the same distribution terms as the rest of
# that program.
#
# serial 6

# AC_CHECK_FT2([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
# Test for FreeType 2, and define FT2_CFLAGS and FT2_LIBS.
# MINIMUM-VERSION is what libtool reports; the default is '7.0.1' (this is
# FreeType 2.0.4).
#
# To make this code work with older autoconf versions, `AS_HELP_STRING` is
# not quoted.
#
AC_DEFUN([AC_CHECK_FT2],
  [# Get the cflags and libraries from the freetype-config script
   #
   AC_ARG_WITH([ft-prefix],
     AS_HELP_STRING([--with-ft-prefix=PREFIX],
                    [Prefix where FreeType is installed (optional)]),
     [ft_config_prefix="$withval"],
     [ft_config_prefix=""])

   AC_ARG_WITH([ft-exec-prefix],
     AS_HELP_STRING([--with-ft-exec-prefix=PREFIX],
                    [Exec prefix where FreeType is installed (optional)]),
     [ft_config_exec_prefix="$withval"],
     [ft_config_exec_prefix=""])

   AC_ARG_ENABLE([freetypetest],
     AS_HELP_STRING([--disable-freetypetest],
                    [Do not try to compile and run a test FreeType program]),
     [],
     [enable_fttest=yes])

   if test x$ft_config_exec_prefix != x ; then
     ft_config_args="$ft_config_args --exec-prefix=$ft_config_exec_prefix"
     if test x${FT2_CONFIG+set} != xset ; then
       FT2_CONFIG=$ft_config_exec_prefix/bin/freetype-config
     fi
   fi

   if test x$ft_config_prefix != x ; then
     ft_config_args="$ft_config_args --prefix=$ft_config_prefix"
     if test x${FT2_CONFIG+set} != xset ; then
       FT2_CONFIG=$ft_config_prefix/bin/freetype-config
     fi
   fi

   if test "x$FT2_CONFIG" = x ; then
     AC_PATH_TOOL([FT2_CONFIG], [freetype-config], [no])
   fi

   min_ft_version=m4_if([$1], [], [7.0.1], [$1])
   AC_MSG_CHECKING([for FreeType -- version >= $min_ft_version])
   no_ft=""
   if test "$FT2_CONFIG" = "no" ; then
     no_ft=yes
   else
     FT2_CFLAGS=`$FT2_CONFIG $ft_config_args --cflags`
     FT2_LIBS=`$FT2_CONFIG $ft_config_args --libs`
     ft_config_major_version=`$FT2_CONFIG $ft_config_args --version | \
       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
     ft_config_minor_version=`$FT2_CONFIG $ft_config_args --version | \
       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
     ft_config_micro_version=`$FT2_CONFIG $ft_config_args --version | \
       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
     ft_min_major_version=`echo $min_ft_version | \
       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
     ft_min_minor_version=`echo $min_ft_version | \
       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
     ft_min_micro_version=`echo $min_ft_version | \
       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
     if test x$enable_fttest = xyes ; then
       ft_config_is_lt=""
       if test $ft_config_major_version -lt $ft_min_major_version ; then
         ft_config_is_lt=yes
       else
         if test $ft_config_major_version -eq $ft_min_major_version ; then
           if test $ft_config_minor_version -lt $ft_min_minor_version ; then
             ft_config_is_lt=yes
           else
             if test $ft_config_minor_version -eq $ft_min_minor_version ; then
               if test $ft_config_micro_version -lt $ft_min_micro_version ; then
                 ft_config_is_lt=yes
               fi
             fi
           fi
         fi
       fi
       if test x$ft_config_is_lt = xyes ; then
         no_ft=yes
       else
         ac_save_CFLAGS="$CFLAGS"
         ac_save_LIBS="$LIBS"
         CFLAGS="$CFLAGS $FT2_CFLAGS"
         LIBS="$FT2_LIBS $LIBS"

         #
         # Sanity checks for the results of freetype-config to some extent.
         #
         AC_RUN_IFELSE([
             AC_LANG_SOURCE([[

#include <ft2build.h>
#include <freetype/freetype.h>
#include <stdio.h>
#include <stdlib.h>

int
main()
{
  FT_Library library;
  FT_Error  error;

  error = FT_Init_FreeType(&library);

  if (error)
    return 1;
  else
  {
    FT_Done_FreeType(library);
    return 0;
  }
}

             ]])
           ],
           [],
           [no_ft=yes],
           [echo $ECHO_N "cross compiling; assuming OK... $ECHO_C"])

         CFLAGS="$ac_save_CFLAGS"
         LIBS="$ac_save_LIBS"
       fi             # test $ft_config_version -lt $ft_min_version
     fi               # test x$enable_fttest = xyes
   fi                 # test "$FT2_CONFIG" = "no"

   if test x$no_ft = x ; then
     AC_MSG_RESULT([yes])
     m4_if([$2], [], [:], [$2])
   else
     AC_MSG_RESULT([no])
     if test "$FT2_CONFIG" = "no" ; then
       AC_MSG_WARN([

  The freetype-config script installed by FreeType 2 could not be found.
  If FreeType 2 was installed in PREFIX, make sure PREFIX/bin is in
  your path, or set the FT2_CONFIG environment variable to the
  full path to freetype-config.
       ])
     else
       if test x$ft_config_is_lt = xyes ; then
         AC_MSG_WARN([

  Your installed version of the FreeType 2 library is too old.
  If you have different versions of FreeType 2, make sure that
  correct values for --with-ft-prefix or --with-ft-exec-prefix
  are used, or set the FT2_CONFIG environment variable to the
  full path to freetype-config.
         ])
       else
         AC_MSG_WARN([

  The FreeType test program failed to run.  If your system uses
  shared libraries and they are installed outside the normal
  system library path, make sure the variable LD_LIBRARY_PATH
  (or whatever is appropriate for your system) is correctly set.
         ])
       fi
     fi

     FT2_CFLAGS=""
     FT2_LIBS=""
     m4_if([$3], [], [:], [$3])
   fi

   AC_SUBST([FT2_CFLAGS])
   AC_SUBST([FT2_LIBS])])

# end of freetype2.m4
