⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttfile.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************* * *  ttfile.c (extended version)                                 2.1 * *    File I/O Component (body). * *  Copyright 1996-1999 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. * *  NOTES: * *   This implementation relies on the ANSI libc.  You may wish to *   modify it to get rid of libc and go straight to the your *   platform's stream routines. * *   The same source code can be used for thread-safe and re-entrant *   builds of the library. * *  Changes between 2.0 and 2.1 : * *  - it is now possible to close a stream's file handle explicitely *    through the new API "TT_Flush_Stream". This will simply close *    a stream's file handle (useful to save system resources when *    dealing with lots of opened fonts). Of course, the function *    "TT_Use_Stream" will automatically re-open a stream's handle if *    necessary. * *  - added "TT_Stream_Size" to replace "TT_File_Size" which wasn't *    used anyway. This one returns the size of any stream, even *    flushed one (when the previous TT_File_Size could only return *    the size of the current working stream). This is used by the *    new "Load_TrueType_Any" function in the tables loader. * ******************************************************************/#include "ttconfig.h"#include <stdio.h>#include <string.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include "freetype.h"#include "tttypes.h"#include "ttdebug.h"#include "ttengine.h"#include "ttmutex.h"#include "ttmemory.h"#include "ttfile.h"     /* our prototypes *//* required by the tracing mode */#undef  TT_COMPONENT#define TT_COMPONENT  trace_file/* For now, we don't define additional error messages in the core library *//* to report open-on demand errors. Define these error as standard ones   */#define TT_Err_Could_Not_ReOpen_File  TT_Err_Could_Not_Open_File#define TT_Err_Could_Not_ReSeek_File  TT_Err_Could_Not_Open_File  /* This definition is mandatory for each file component! */  EXPORT_FUNC  const TFileFrame  TT_Null_FileFrame = { NULL, 0, 0 };/* It has proven useful to do some bounds checks during development phase. *//* They should probably be undefined for speed reasons in a later release. */#if DEBUG_FILE#define CHECK_FRAME( frame, n )                          \  do {                                                   \    if ( frame.cursor + n > frame.address + frame.size ) \      Panic( "Frame boundary error!\n" );                \  } while ( 0 )#else#define CHECK_FRAME( frame, n )  /* nothing */#endif  /* Because a stream can be flushed, i.e. its file handle can be      */  /* closed to save system resources, we must keep the stream's file   */  /* pathname to be able to re-open it on demand when it is flushed    */  struct  TStream_Rec_;  typedef struct TStream_Rec_  TStream_Rec;  typedef TStream_Rec*         PStream_Rec;  struct  TStream_Rec_  {    Bool      opened;                  /* is the stream handle opened ?    */    TT_Text*  name;                    /* the file's pathname              */    Long      position;                /* current position within the file */    FILE*     file;                    /* file handle                      */    Long      base;                    /* stream base in file              */    Long      size;                    /* stream size in file              */  };  /* We support embedded TrueType files by allowing them to be       */  /* inside any file, at any location, hence the 'base' argument.    */  /* Note however that the current implementation does not allow you */  /* to specify a 'base' index when opening a file.                  */  /* (will come later)                                               */  /* I still don't know if this will turn out useful ??   - DavidT   */#define STREAM2REC( x )  ( (TStream_Rec*)HANDLE_Val( x ) )  static  TT_Error  Stream_Activate  ( PStream_Rec  stream );  static  TT_Error  Stream_Deactivate( PStream_Rec  stream );#ifndef TT_CONFIG_OPTION_THREAD_SAFE  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/  /****                                                           ****/  /****  N O N   R E E N T R A N T   I M P L E M E N T A T I O N  ****/  /****                                                           ****/  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/  /* in non-rentrant builds, we allocate a single block where we'll  */  /* place all the frames smaller than FRAME_CACHE_SIZE, rather than */  /* allocating a new block on each access.  Bigger frames will be   */  /* malloced normally in the heap.                                  */  /*                                                                 */  /* See TT_Access_Frame() and TT_Forget_Frame() for details.        */#define FRAME_CACHE_SIZE  2048  /* The TFile_Component structure holds all the data that was */  /* previously declared static or global in this component.   */  /*                                                           */  /* It is accessible through the 'engine.file_component'      */  /* variable in re-entrant builds, or directly through the    */  /* static 'files' variable in other builds.                  */  struct  TFile_Component_  {    TMutex       lock;        /* used by the thread-safe build only */    Byte*        frame_cache; /* frame cache     */    PStream_Rec  stream;      /* current stream  */    TFileFrame   frame;       /* current frame   */  };  typedef struct TFile_Component_  TFile_Component;  static TFile_Component  files;#define CUR_Stream  files.stream#define CUR_Frame   files.frame#define STREAM_VARS  /* void */#define STREAM_VAR   /* void *//* The macro CUR_Stream denotes the current input stream.            *//* Note that for the re-entrant version, the 'stream' name has been  *//* chosen according to the macro STREAM_ARGS.                        *//* The macro CUR_Frame denotes the current file frame.              *//* Note that for the re-entrant version, the 'frame' name has been  *//* chosen according to the macro FRAME_ARGS.                        *//* The macro STREAM_VAR is used when calling public functions *//* that need an 'optional' stream argument.                   *//******************************************************************* * *  Function    :  TTFile_Init * *  Description :  Initializes the File component. * ******************************************************************/  LOCAL_FUNC  TT_Error  TTFile_Init( PEngine_Instance  engine )  {    TT_Error  error;    MUTEX_Create( files.lock );    files.stream = NULL;    ZERO_Frame( files.frame );    if ( ALLOC( files.frame_cache, FRAME_CACHE_SIZE ) )      return error;    return TT_Err_Ok;  }/******************************************************************* * *  Function    :  TTFile_Done * *  Description :  Finalizes the File component. * ******************************************************************/  LOCAL_FUNC  TT_Error  TTFile_Done( PEngine_Instance  engine )  {    FREE( files.frame_cache );    MUTEX_Destroy( files.lock );    return TT_Err_Ok;  }/******************************************************************* * *  Function    : TT_Use_Stream * *  Description : Copies or duplicates a given stream. * *  Input  :  org_stream   original stream *            stream       target stream (copy or duplicate) * *  Output :  Error code. * ******************************************************************/  EXPORT_FUNC  TT_Error  TT_Use_Stream( TT_Stream   org_stream,                           TT_Stream*  stream )  {     MUTEX_Lock( files.lock );                /* lock file mutex    */     *stream = org_stream;                    /* copy the stream    */     files.stream = STREAM2REC(org_stream);   /* set current stream */     Stream_Activate( files.stream );     return TT_Err_Ok;  }/******************************************************************* * *  Function    : TT_Done_Stream * *  Description : Releases a given stream. * *  Input  :  stream  target stream * *  Output :  Error code. * ******************************************************************/  EXPORT_FUNC  TT_Error  TT_Done_Stream( TT_Stream*  stream )  {     HANDLE_Set( *stream, NULL );     MUTEX_Release( files.lock );     return TT_Err_Ok;  }/******************************************************************* * *  Function    :  TT_Access_Frame * *  Description :  Notifies the component that we're going to read *                 'size' bytes from the current file position. *                 This function should load/cache/map these bytes *                 so that they will be addressed by the GET_xxx *                 functions easily. * *  Input  :  size   number of bytes to access. * *  Output :  SUCCESS on success. FAILURE on error. * *  Notes:    The function fails if the byte range is not within the *            the file, or if there is not enough memory to cache *            the bytes properly (which usually means that `size' is *            too big in both cases). * ******************************************************************/  EXPORT_FUNC  TT_Error  TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long  size )  {    TT_Error  error;    if ( CUR_Frame.address != NULL )      return TT_Err_Nested_Frame_Access;    if ( size <= FRAME_CACHE_SIZE )    {      /* use the cache */      CUR_Frame.address = files.frame_cache;      CUR_Frame.size    = FRAME_CACHE_SIZE;    }    else    {      if ( ALLOC( CUR_Frame.address, size ) )        return error;      CUR_Frame.size    = size;    }    error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size );    if (error)    {      if ( size > FRAME_CACHE_SIZE )        FREE( CUR_Frame.address );      CUR_Frame.address = NULL;      CUR_Frame.size    = 0;    }    CUR_Frame.cursor = CUR_Frame.address;    return error;  }/******************************************************************* * *  Function    :  TT_Check_And_Access_Frame * *  Description :  Notifies the component that we're going to read *                 `size' bytes from the current file position. *                 This function should load/cache/map these bytes *                 so that they will be addressed by the GET_xxx *                 functions easily. * *  Input  :  size   number of bytes to access. * *  Output :  SUCCESS on success. FAILURE on error. * *  Notes:    The function truncates `size' if the byte range is not *            within the file. * *            It will fail if there is not enough memory to cache *            the bytes properly (which usually means that `size' is *            too big). * *            It will fail if you make two consecutive calls *            to TT_Access_Frame(), without a TT_Forget_Frame() between *            them. * *            The only difference with TT_Access_Frame() is that we *            check that the frame is within the current file.  We *            otherwise truncate it. * ******************************************************************/  EXPORT_FUNC  TT_Error  TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long  size )  {    TT_Error  error;    Long      readBytes, requested;    if ( CUR_Frame.address != NULL )      return TT_Err_Nested_Frame_Access;    if ( size <= FRAME_CACHE_SIZE )    {      /* use the cache */      CUR_Frame.address = files.frame_cache;      CUR_Frame.size    = FRAME_CACHE_SIZE;    }    else    {      if ( ALLOC( CUR_Frame.address, size ) )        return error;      CUR_Frame.size    = size;    }    requested = size;    readBytes = CUR_Stream->size - TT_File_Pos( STREAM_VAR );    if ( size > readBytes )      size = readBytes;    error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size );    if (error)    {      if ( requested > FRAME_CACHE_SIZE )        FREE( CUR_Frame.address );      CUR_Frame.address = NULL;      CUR_Frame.size    = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -