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

📄 ttmmap.c

📁 字体缩放显示
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************* * *  ttmmap.c                                                     2.0 * *    Memory-Mapped file component ( replaces ttfile.c ). * *  Copyright 1996-2001 by David Williss, *  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. * *  Changes between 2.0 and 1.3 : * *  - adopted new design/separation introduced in ttfile.c 2.0 * ******************************************************************/#include "ttconfig.h"#include <stdio.h>#include <string.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#include <folders.h>#include <resources.h>#include "freetype.h"#include "tttypes.h"#include "ttdebug.h"#include "ttengine.h"#include "ttmutex.h"#include "ttmemory.h"#include "ttfile.h"     /* our prototypes */  /* This definition is mandatory for each file component! */  FT_EXPORT_VAR( const TFileFrame )  TT_Null_FileFrame = { NULL, 0, 0 };  /* It has proven useful to do some bounds checks during   */  /* development phase.  Define DEBUG_FILE when compiling   */  /* this component to enable them.                         */#ifdef 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 ) \  do {                          \  } while( 0 )#endif  struct _TFileMap  {    String*  base;       /* base address of mapped file       */    Int      refcount;   /* reference count for handle region */    Long     size;       /* stream size in file               */    Long     offset;     /* offset in file                    */    Handle   handle;     /* Macintosh style handle to lock/unlock */    short    resid;      /* Id of resource file to close when done */  };  typedef struct _TFileMap  TFileMap;#define MAP_Address( map )  (Byte*)( (map)->base + (map)->offset )  /* The stream record structure */  typedef struct _TStream_Rec  {    TFileMap*  map;     /* mapped file description */    Long       pos ;    /* cursor in mapped file   */  } TStream_Rec;  typedef TStream_Rec*  PStream_Rec;#define STREAM2REC( x )  ( (TStream_Rec*)HANDLE_Val( x ) )#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  ****/  /****                                                           ****/  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/  /* 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 */    PStream_Rec  stream;      /* current stream  */    TFileFrame   frame;       /* current frame   */  };  typedef struct _TFile_Component  TFile_Component;/* 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.                   */#define CUR_Stream   files.stream            /* thread-safe macros */#define CUR_Frame    files.frame#define STREAM_VARS  /* void */#define STREAM_VAR   /* void */  /* the 'files' variable is only defined in non-reentrant builds */  static TFile_Component  files;/******************************************************************* * *  Function    :  TTFile_Init * *  Description :  Initializes the File component. * ******************************************************************/ FT_INTERNAL_FUNC( TT_Error ) TTFile_Init( PEngine_Instance  engine ) {   MUTEX_Create( files.lock );   files.stream = NULL;   ZERO_Frame( files.frame );   return TT_Err_Ok; }/******************************************************************* * *  Function    :  TTFile_Done * *  Description :  Finalizes the File component. * ******************************************************************/ FT_INTERNAL_FUNC( TT_Error ) TTFile_Done( PEngine_Instance  engine ) {   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 * ******************************************************************/  FT_EXPORT_FUNC( TT_Error )  TT_Use_Stream( TT_Stream   org_stream,                 TT_Stream*  stream )  {    MUTEX_Lock( files.lock );    *stream = org_stream;    files.stream = STREAM2REC( org_stream );  /* set current stream */    return TT_Err_Ok;  }/******************************************************************* * *  Function    : TT_Done_Stream * *  Description : Releases a given stream. * *  Input  :  stream * *  Output :  Error code * ******************************************************************/ FT_EXPORT_FUNC( TT_Error ) TT_Done_Stream( TT_Stream*  stream ) {   HANDLE_Set( *stream, NULL );   MUTEX_Release( files.lock );   return TT_Err_Ok; }#else /* TT_CONFIG_OPTION_THREAD_SAFE */  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/  /********                                                   ********/  /********  R E E N T R A N T   I M P L E M E N T A T I O N  ********/  /********                                                   ********/  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/#define CUR_Stream   STREAM2REC( stream )      /* re-entrant macros */#define CUR_Frame    (*frame)#define STREAM_VARS  stream,#define STREAM_VAR   stream/******************************************************************* * *  Function    :  TTFile_Init * *  Description :  Initializes the File component. * ******************************************************************/ FT_INTERNAL_FUNC( TT_Error ) TTFile_Init( PEngine_Instance  engine ) {   engine.file_component = NULL;   return TT_Err_Ok; }/******************************************************************* * *  Function    :  TTFile_Done * *  Description :  Finalizes the File component. * ******************************************************************/ FT_INTERNAL_FUNC( TT_Error ) TTFile_Done( PEngine_Instance  engine ) {   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.  The output stream is set to NULL in *            case of Failure. * ******************************************************************/  FT_EXPORT_FUNC( TT_Error )  TT_Use_Stream( TT_Stream   input_stream,                           TT_Stream*  copy )  {    TT_Error     error;    PStream_Rec  stream_rec;    PStream_Rec  copy_rec;    stream_rec = STREAM2REC( input_stream );    if ( ALLOC( copy_rec, sizeof ( TStream_Rec ) ) )      goto Fail;    HANDLE_Set( *copy, copy_rec );    copy_rec->map->refcount++;    copy_rec->pos = 0;    return TT_Err_Ok;  Fail:    HANDLE_Set( *copy, NULL );    return error;  }/******************************************************************* * *  Function    : TT_Done_Stream * *  Description : Releases a given stream. * *  Input  :  stream * *  Output :  error code * ******************************************************************/ FT_EXPORT_FUNC( TT_Error ) TT_Done_Stream( TT_Stream*  stream ) {   return TT_Close_Stream( stream ); }#endif /* TT_CONFIG_OPTION_THREAD_SAFE */  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/  /***********                                             ***********/  /***********  C O M M O N   I M P L E M E N T A T I O N  ***********/  /***********                                             ***********/  /*******************************************************************/  /*******************************************************************/  /*******************************************************************//******************************************************************* * *  Function    :  AllocateMap * *  Description :  Allocates a new map from the table. * *  Output :  Pointer to new stream rec.  NULL in case of failure. * ******************************************************************/  static TFileMap*  Allocate_Map( void )  {    TFileMap*  result;    if ( MEM_Alloc( result, sizeof ( TFileMap ) ) )      return NULL;    result->refcount = 1;    return result;  }/******************************************************************* * *  Function    :  ReleaseMap * *  Description :  Releases a used map to the table if reference i *                 counter reaches zero. * *  Input  :  map * *  Output :  None. * *  Note : Called by TT_Close_File() * ******************************************************************/  static void  Release_Map ( TFileMap*  map )  {    map->refcount--;    if ( map->refcount <= 0 )    {      /* MacOS System calls */      HUnlock(map->handle);                   ReleaseResource(map->handle);      CloseResFile(map->resid);      FREE( map );    }  }/* Whadda ya mean "strdup undefined"? Fine, I'll define my own! */  static char *  mystrdup( const char *str )  {    char *ret;        if ( TT_Alloc(strlen(str) + 1, (void**)&ret) != 0 ) return(NULL);    strcpy(ret, str);    return(ret);  }/******************************************************************* * *  Function    :  TT_Open_Stream * *  Description :  Opens the font file and saves the total file size. * *  Input  :  error          address of stream's error variable *                           (re-entrant build only). *            filepathname   pathname of the file to open *            stream         address of target TT_Stream structure * *  Output :  SUCCESS on success, FAILURE on error. *            The target stream is set to -1 in case of failure. * ******************************************************************//***  This is not a totally generic implementation.  It currently assumes the filename**  starts with "fonts:" and uses slashes instead of colons like Mac code normally** would.  Given a filename of the form "fonts:/filename/resname", Load the resource** and lock the handle**** The "fonts:" at the beginning is just a convention I came up with to **  indicate the Fonts folder inside the current System folder (find via FindFolder())*/  FT_INTERNAL_FUNC( TT_Error )  TT_Open_Stream( const String*  filepathname,                   TT_Stream*     stream )  {    TT_Error     error;    Int          file;    PStream_Rec  stream_rec;    TFileMap*    map;    int          size, err = 0;    short        vRefNum, res = -1;    Str255       FontName;    char         *cp, *p, *fname, *sep;    Str63        myName;    long         dirID;    if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) )      return error;    map = Allocate_Map();    if ( !map )    {      error = TT_Err_Out_Of_Memory;      goto Memory_Fail;    }        stream_rec = STREAM2REC( *stream );    /* Find the dirID of the Fonts folder in the current System folder */    if (FindFolder(kOnSystemDisk, kFontsFolderType, kDontCreateFolder, &vRefNum, &dirID))         goto File_Fail;    /* Break the name apart */    fname = mystrdup(filepathname); /* Make a copy so we can muck with it */    sep = ":/";     /* Things that can seperate file path componants */        strtok(fname, sep);             /* Skip over "fonts:" */        if ((p = strtok(NULL, sep)) == NULL)        /* Get filename */        goto File_Fail;    strcpy(myName + 1, p);                      /* Make this a Pascal string (Yuck!) */    myName[0] = strlen(p);         if ((p = strtok(NULL, sep)) == NULL)        /* Get res name */        goto File_Fail;    strcpy(FontName+1, p);                      /* Make this a Pascal string (Yuck!) */    FontName[0] = strlen(p);        FREE( fname );        if ((cp = strchr(FontName, '.')) != NULL)   /* Strip off ".ttf" , if any */        *cp = 0;        /* Read the font into a buffer */    if ((map->resid = HOpenResFile(vRefNum, dirID, myName, fsRdPerm)) == -1)        goto File_Fail;        if ((map->handle = Get1NamedResource('sfnt', FontName)) == NULL)        goto Map_Fail;        HLock(map->handle);    map->base   = *map->handle;    map->offset = 0;    map->size   = GetResourceSizeOnDisk(map->handle);    if ( map->base == NULL )        goto Lock_Fail;    stream_rec->map = map;    stream_rec->pos = 0;#ifndef TT_CONFIG_OPTION_THREAD_SAFE    CUR_Stream = stream_rec;#endif    return TT_Err_Ok;  Lock_Fail:    ReleaseResource(map->handle);      Map_Fail:    CloseResFile(map->resid);  File_Fail:    error = TT_Err_Could_Not_Open_File;    FREE( map );  Memory_Fail:    FREE( *stream );    FREE( fname );    return error;  }/*******************************************************************

⌨️ 快捷键说明

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