(root)/
freetype-2.13.2/
src/
base/
ftsystem.c
       1  /****************************************************************************
       2   *
       3   * ftsystem.c
       4   *
       5   *   ANSI-specific FreeType low-level system interface (body).
       6   *
       7   * Copyright (C) 1996-2023 by
       8   * David Turner, Robert Wilhelm, and Werner Lemberg.
       9   *
      10   * This file is part of the FreeType project, and may only be used,
      11   * modified, and distributed under the terms of the FreeType project
      12   * license, LICENSE.TXT.  By continuing to use, modify, or distribute
      13   * this file you indicate that you have read the license and
      14   * understand and accept it fully.
      15   *
      16   */
      17  
      18    /**************************************************************************
      19     *
      20     * This file contains the default interface used by FreeType to access
      21     * low-level, i.e. memory management, i/o access as well as thread
      22     * synchronisation.  It can be replaced by user-specific routines if
      23     * necessary.
      24     *
      25     */
      26  
      27  
      28  #include <ft2build.h>
      29  #include FT_CONFIG_CONFIG_H
      30  #include <freetype/internal/ftdebug.h>
      31  #include <freetype/internal/ftstream.h>
      32  #include <freetype/ftsystem.h>
      33  #include <freetype/fterrors.h>
      34  #include <freetype/fttypes.h>
      35  
      36  
      37    /**************************************************************************
      38     *
      39     *                      MEMORY MANAGEMENT INTERFACE
      40     *
      41     */
      42  
      43    /**************************************************************************
      44     *
      45     * It is not necessary to do any error checking for the
      46     * allocation-related functions.  This will be done by the higher level
      47     * routines like ft_mem_alloc() or ft_mem_realloc().
      48     *
      49     */
      50  
      51  
      52    /**************************************************************************
      53     *
      54     * @Function:
      55     *   ft_alloc
      56     *
      57     * @Description:
      58     *   The memory allocation function.
      59     *
      60     * @Input:
      61     *   memory ::
      62     *     A pointer to the memory object.
      63     *
      64     *   size ::
      65     *     The requested size in bytes.
      66     *
      67     * @Return:
      68     *   The address of newly allocated block.
      69     */
      70    FT_CALLBACK_DEF( void* )
      71    ft_alloc( FT_Memory  memory,
      72              long       size )
      73    {
      74      FT_UNUSED( memory );
      75  
      76      return ft_smalloc( (size_t)size );
      77    }
      78  
      79  
      80    /**************************************************************************
      81     *
      82     * @Function:
      83     *   ft_realloc
      84     *
      85     * @Description:
      86     *   The memory reallocation function.
      87     *
      88     * @Input:
      89     *   memory ::
      90     *     A pointer to the memory object.
      91     *
      92     *   cur_size ::
      93     *     The current size of the allocated memory block.
      94     *
      95     *   new_size ::
      96     *     The newly requested size in bytes.
      97     *
      98     *   block ::
      99     *     The current address of the block in memory.
     100     *
     101     * @Return:
     102     *   The address of the reallocated memory block.
     103     */
     104    FT_CALLBACK_DEF( void* )
     105    ft_realloc( FT_Memory  memory,
     106                long       cur_size,
     107                long       new_size,
     108                void*      block )
     109    {
     110      FT_UNUSED( memory );
     111      FT_UNUSED( cur_size );
     112  
     113      return ft_srealloc( block, (size_t)new_size );
     114    }
     115  
     116  
     117    /**************************************************************************
     118     *
     119     * @Function:
     120     *   ft_free
     121     *
     122     * @Description:
     123     *   The memory release function.
     124     *
     125     * @Input:
     126     *   memory ::
     127     *     A pointer to the memory object.
     128     *
     129     *   block ::
     130     *     The address of block in memory to be freed.
     131     */
     132    FT_CALLBACK_DEF( void )
     133    ft_free( FT_Memory  memory,
     134             void*      block )
     135    {
     136      FT_UNUSED( memory );
     137  
     138      ft_sfree( block );
     139    }
     140  
     141  
     142    /**************************************************************************
     143     *
     144     *                    RESOURCE MANAGEMENT INTERFACE
     145     *
     146     */
     147  
     148  #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
     149  
     150    /**************************************************************************
     151     *
     152     * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     153     * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     154     * messages during execution.
     155     */
     156  #undef  FT_COMPONENT
     157  #define FT_COMPONENT  io
     158  
     159    /* We use the macro STREAM_FILE for convenience to extract the       */
     160    /* system-specific stream handle from a given FreeType stream object */
     161  #define STREAM_FILE( stream )  ( (FT_FILE*)stream->descriptor.pointer )
     162  
     163  
     164    /**************************************************************************
     165     *
     166     * @Function:
     167     *   ft_ansi_stream_close
     168     *
     169     * @Description:
     170     *   The function to close a stream.
     171     *
     172     * @Input:
     173     *   stream ::
     174     *     A pointer to the stream object.
     175     */
     176    FT_CALLBACK_DEF( void )
     177    ft_ansi_stream_close( FT_Stream  stream )
     178    {
     179      ft_fclose( STREAM_FILE( stream ) );
     180  
     181      stream->descriptor.pointer = NULL;
     182      stream->size               = 0;
     183      stream->base               = NULL;
     184    }
     185  
     186  
     187    /**************************************************************************
     188     *
     189     * @Function:
     190     *   ft_ansi_stream_io
     191     *
     192     * @Description:
     193     *   The function to open a stream.
     194     *
     195     * @Input:
     196     *   stream ::
     197     *     A pointer to the stream object.
     198     *
     199     *   offset ::
     200     *     The position in the data stream to start reading.
     201     *
     202     *   buffer ::
     203     *     The address of buffer to store the read data.
     204     *
     205     *   count ::
     206     *     The number of bytes to read from the stream.
     207     *
     208     * @Return:
     209     *   The number of bytes actually read.  If `count' is zero (that is,
     210     *   the function is used for seeking), a non-zero return value
     211     *   indicates an error.
     212     */
     213    FT_CALLBACK_DEF( unsigned long )
     214    ft_ansi_stream_io( FT_Stream       stream,
     215                       unsigned long   offset,
     216                       unsigned char*  buffer,
     217                       unsigned long   count )
     218    {
     219      FT_FILE*  file;
     220  
     221  
     222      if ( offset > stream->size && !count )
     223        return 1;
     224  
     225      file = STREAM_FILE( stream );
     226  
     227      if ( stream->pos != offset )
     228        ft_fseek( file, (long)offset, SEEK_SET );
     229  
     230      /* Avoid calling `fread` with `buffer=NULL` and `count=0`, */
     231      /* which is undefined behaviour.                           */
     232      if ( !count )
     233        return 0;
     234  
     235      return (unsigned long)ft_fread( buffer, 1, count, file );
     236    }
     237  
     238  
     239    /* documentation is in ftstream.h */
     240  
     241    FT_BASE_DEF( FT_Error )
     242    FT_Stream_Open( FT_Stream    stream,
     243                    const char*  filepathname )
     244    {
     245      FT_FILE*  file;
     246  
     247  
     248      if ( !stream )
     249        return FT_THROW( Invalid_Stream_Handle );
     250  
     251      stream->descriptor.pointer = NULL;
     252      stream->pathname.pointer   = (char*)filepathname;
     253      stream->base               = NULL;
     254      stream->pos                = 0;
     255      stream->read               = NULL;
     256      stream->close              = NULL;
     257  
     258      file = ft_fopen( filepathname, "rb" );
     259      if ( !file )
     260      {
     261        FT_ERROR(( "FT_Stream_Open:"
     262                   " could not open `%s'\n", filepathname ));
     263  
     264        return FT_THROW( Cannot_Open_Resource );
     265      }
     266  
     267      ft_fseek( file, 0, SEEK_END );
     268      stream->size = (unsigned long)ft_ftell( file );
     269      if ( !stream->size )
     270      {
     271        FT_ERROR(( "FT_Stream_Open:" ));
     272        FT_ERROR(( " opened `%s' but zero-sized\n", filepathname ));
     273        ft_fclose( file );
     274        return FT_THROW( Cannot_Open_Stream );
     275      }
     276      ft_fseek( file, 0, SEEK_SET );
     277  
     278      stream->descriptor.pointer = file;
     279      stream->read  = ft_ansi_stream_io;
     280      stream->close = ft_ansi_stream_close;
     281  
     282      FT_TRACE1(( "FT_Stream_Open:" ));
     283      FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n",
     284                  filepathname, stream->size ));
     285  
     286      return FT_Err_Ok;
     287    }
     288  
     289  #endif /* !FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */
     290  
     291  #ifdef FT_DEBUG_MEMORY
     292  
     293    extern FT_Int
     294    ft_mem_debug_init( FT_Memory  memory );
     295  
     296    extern void
     297    ft_mem_debug_done( FT_Memory  memory );
     298  
     299  #endif
     300  
     301  
     302    /* documentation is in ftobjs.h */
     303  
     304    FT_BASE_DEF( FT_Memory )
     305    FT_New_Memory( void )
     306    {
     307      FT_Memory  memory;
     308  
     309  
     310      memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) );
     311      if ( memory )
     312      {
     313        memory->user    = NULL;
     314        memory->alloc   = ft_alloc;
     315        memory->realloc = ft_realloc;
     316        memory->free    = ft_free;
     317  #ifdef FT_DEBUG_MEMORY
     318        ft_mem_debug_init( memory );
     319  #endif
     320      }
     321  
     322      return memory;
     323    }
     324  
     325  
     326    /* documentation is in ftobjs.h */
     327  
     328    FT_BASE_DEF( void )
     329    FT_Done_Memory( FT_Memory  memory )
     330    {
     331  #ifdef FT_DEBUG_MEMORY
     332      ft_mem_debug_done( memory );
     333  #endif
     334      ft_sfree( memory );
     335    }
     336  
     337  
     338  /* END */