diff --git a/include/freetype/internal/ftdebug.h b/include/freetype/internal/ftdebug.h index df5357ad5..35026a9f0 100644 --- a/include/freetype/internal/ftdebug.h +++ b/include/freetype/internal/ftdebug.h @@ -31,9 +31,28 @@ #include "compiler-macros.h" + /************************************************************************** + * + * Additional include files for supporting logging in FreeType using + * external logging library ~ src/dlg and freetype/ftlogging.h + * + */ + +#ifdef FT_LOGGING +#include <../src/dlg/dlg/dlg.h> +#include <../src/dlg/dlg/output.h> +#endif /* FT_LOGGING */ + FT_BEGIN_HEADER + /* force the definition of FT_DEBUG_LEVEL_TRACE if FT_LOGGING is already*/ + /* defined; therefore the following #ifdefs */ + /* */ +#ifdef FT_LOGGING +#undef FT_DEBUG_LEVEL_TRACE +#define FT_DEBUG_LEVEL_TRACE +#endif /* FT_LOGGING */ /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */ /* is already defined; this simplifies the following #ifdefs */ @@ -84,18 +103,47 @@ FT_BEGIN_HEADER * */ +#ifdef FT_LOGGING + + /************************************************************************* + * + * If FT_LOGGING is enabled, trace messages will be sent to dlg's API and + * if is FT_LOGGING is disabled trace messages will be sent to + * FT_Message(defined in ftdebug.c) + * Therefore the following macros: + * + */ + +#define FT_LOG( level, varformat ) \ + do \ + { \ + if( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \ + dlg_trace varformat; \ + }while( 0 ) + +#else + +#define FT_LOG( level, varformat ) \ + do \ + { \ + if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \ + { \ + FT_Message varformat; \ + } \ + } while ( 0 ) + +#endif /* FT_LOGGING */ + + + + #ifdef FT_DEBUG_LEVEL_TRACE /* we need two macros here to make cpp expand `FT_COMPONENT' */ #define FT_TRACE_COMP( x ) FT_TRACE_COMP_( x ) #define FT_TRACE_COMP_( x ) trace_ ## x -#define FT_TRACE( level, varformat ) \ - do \ - { \ - if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \ - FT_Message varformat; \ - } while ( 0 ) +#define FT_TRACE( level, varformat ) FT_LOG( level, varformat ) #else /* !FT_DEBUG_LEVEL_TRACE */ @@ -204,8 +252,29 @@ FT_BEGIN_HEADER #ifdef FT_DEBUG_LEVEL_ERROR +#ifdef FT_LOGGING + + /************************************************************************* + * + * If FT_LOGGING is enabled, error messages will be sent to dlg's API and + * if is FT_LOGGING is disabled error messages will be sent to + * FT_Message(defined in ftdebug.c) + * Therefore the following macros: + * + */ + +#define FT_ERROR( varformat ) \ + do \ + { \ + dlg_trace varformat; \ + } while ( 0 ) + +#else + #define FT_ERROR( varformat ) FT_Message varformat +#endif /* FT_LOGGING */ + #else /* !FT_DEBUG_LEVEL_ERROR */ #define FT_ERROR( varformat ) do { } while ( 0 ) /* nothing */ @@ -277,6 +346,50 @@ FT_BEGIN_HEADER FT_BASE( void ) ft_debug_init( void ); +#ifdef FT_LOGGING + +/**************************************************************************** + * + * dlg uses output handlers to control how and where the log messages are + * printed. + * Therefore we need to define an output handler specific to FreeType, it + * will act as a default output handler of Freetype. + * + */ + + FT_BASE( void ) + ft_log_handler( const struct dlg_origin* origin, + const char* string, + void* data ); + + + /************************************************************************** + * + * Variables used when FT_LOGGING is enabled to control logging: + * + * 1. ft_default_log_handler: stores the function pointer which is used + * internally by FreeType to print logs to file. + * + * These are defined in ftdebug.c + */ + extern dlg_handler ft_default_log_handler; + + /************************************************************************** + * + * If FT_LOGGING macro is enabled, Freetype needs to initialize and + * un-initialize FILE* using following functions + * These functions are defined in ftdebug.c + * + */ + + FT_BASE( void ) + ft_logging_init( void ); + + FT_BASE( void ) + ft_logging_deinit( void ); + +#endif /* FT_LOGGING */ + FT_END_HEADER #endif /* FTDEBUG_H_ */ diff --git a/src/base/ftdebug.c b/src/base/ftdebug.c index 62cf680b0..322dbb5b5 100644 --- a/src/base/ftdebug.c +++ b/src/base/ftdebug.c @@ -44,6 +44,27 @@ #include #include +#ifdef FT_LOGGING + + /************************************************************************** + * + * Variable used when FT_LOGGING is enabled to control logging: + * + * 1. ft_default_trace_level: stores the value of trace levels which are + * provided to FreeType using FT2_DEBUG environment variable. + * + * 2. ft_fileptr: store the FILE* + * + * Static Variables are defined here to remove [ -Wunused-variable ] + * warning + * + */ + static const char* ft_default_trace_level = NULL; + static FILE* ft_fileptr = NULL; + + dlg_handler ft_default_log_handler = NULL; + +#endif #ifdef FT_DEBUG_LEVEL_ERROR @@ -314,5 +335,57 @@ #endif /* !FT_DEBUG_LEVEL_TRACE */ +#ifdef FT_LOGGING + + /************************************************************************** + * + * If FT_LOGGING is enabled, FreeType needs to initialize all logging + * variables to write logs. + * Therefore it uses `ft_logging_init()` function to initialize a + * loggging variables and `ft_logging_deinit()` to un-initialize the + * logging variables. + * + */ + + FT_BASE_DEF( void ) + ft_logging_init( void ) + { + ft_default_log_handler = ft_log_handler; + ft_default_trace_level = ft_getenv( "FT2_DEBUG" ); + if( ft_getenv( "FT_LOGGING_FILE" ) ) + ft_fileptr = fopen( ft_getenv( "FT_LOGGING_FILE" ) , "w" ); + else + ft_fileptr = stderr; + + ft_debug_init(); + /* We need to set the default FreeType specific dlg's output handler */ + dlg_set_handler( ft_default_log_handler, NULL ); + + } + + FT_BASE_DEF( void ) + ft_logging_deinit( void ) + { + fclose( ft_fileptr ); + } + + /************************************************************************* + * + * An Output log handler specific to FreeType used by dlg library. + * + */ + FT_BASE_DEF( void ) + ft_log_handler( const struct dlg_origin* origin, + const char* string, void* data ) + { + ( void ) data; + const char* features = "%c"; + + dlg_generic_outputf_stream( ft_fileptr, features, origin, string, + dlg_default_output_styles, true ); + + } + +#endif /* FT_LOGGING */ /* END */ diff --git a/src/base/ftinit.c b/src/base/ftinit.c index 0acc75e46..c4de2f3d4 100644 --- a/src/base/ftinit.c +++ b/src/base/ftinit.c @@ -201,6 +201,10 @@ FT_Error error; FT_Memory memory; + /* If logging is enabled initialize the FILE* */ +#ifdef FT_LOGGING + ft_logging_init(); +#endif /* FT_LOGGING */ /* check of `alibrary' delayed to `FT_New_Library' */ @@ -248,6 +252,11 @@ /* discard memory manager */ FT_Done_Memory( memory ); + /* If logging is enabled we need to close the FILE* */ +#ifdef FT_LOGGING + ft_logging_deinit(); +#endif /* FT_LOGGING */ + return FT_Err_Ok; } diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 8adfdffe1..47f583e25 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -5273,10 +5273,12 @@ if ( !memory || !alibrary ) return FT_THROW( Invalid_Argument ); +#ifndef FT_LOGGING #ifdef FT_DEBUG_LEVEL_ERROR /* init debugging support */ ft_debug_init(); -#endif +#endif /* FT_DEBUG_LEVEL_ERROR */ +#endif /* FT_LOGGING */ /* first of all, allocate the library object */ if ( FT_NEW( library ) )