diff options
Diffstat (limited to 'Build/source/libs/freetype/lib/ttfile.c')
-rw-r--r-- | Build/source/libs/freetype/lib/ttfile.c | 1176 |
1 files changed, 1176 insertions, 0 deletions
diff --git a/Build/source/libs/freetype/lib/ttfile.c b/Build/source/libs/freetype/lib/ttfile.c new file mode 100644 index 00000000000..256082dad55 --- /dev/null +++ b/Build/source/libs/freetype/lib/ttfile.c @@ -0,0 +1,1176 @@ +/******************************************************************* + * + * ttfile.c (extended version) 2.1 + * + * File I/O Component (body). + * + * Copyright 1996-2000 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! */ + FT_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. + * + ******************************************************************/ + + FT_INTERNAL_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. + * + ******************************************************************/ + + FT_INTERNAL_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. + * + ******************************************************************/ + + FT_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. + * + ******************************************************************/ + + FT_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). + * + ******************************************************************/ + + FT_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. + * + ******************************************************************/ + + FT_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; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + FT_EXPORT_FUNC( TT_Error ) + TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + if ( CUR_Frame.size > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + + ZERO_Frame( CUR_Frame ); + + 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 ********/ + /******** ********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/* a simple macro to access the file component's data */ +#define files ( *((TFile_Component*)engine.file_component) ) + +#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 ) + { + 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 : Duplicates a stream for a new usage. + * + * Input : input_stream source stream to duplicate + * copy address of target duplicate stream + * + * Output : error code. + * The target stream is set to NULL in case of failure. + * + ******************************************************************/ + + FT_EXPORT_FUNC( TT_Error ) + TT_Use_Stream( TT_Stream input_stream, + TT_Stream* copy ) + { + PStream_Rec rec = STREAM2REC( input_stream ); + + return TT_Open_Stream( rec->name, copy ); + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream target stream + * + * Output : + * + ******************************************************************/ + + FT_EXPORT_FUNC( TT_Error ) + TT_Done_Stream( TT_Stream* stream ) + { + return TT_Close_Stream( stream ); + } + + +/******************************************************************* + * + * 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). + * + ******************************************************************/ + + FT_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 ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + FREE( CUR_Frame.address ); + 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. + * + ******************************************************************/ + + FT_EXPORT_FUNC( TT_Error ) + TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = 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 ) + { + FREE( CUR_Frame.address ); + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + FT_EXPORT_FUNC( TT_Error ) + TT_Forget_Frame( STREAM_ARGS FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + FREE( CUR_Frame.address ); + ZERO_Frame( CUR_Frame ); + + return TT_Err_Ok; + } + +#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 : Stream_Activate + * + * Description : activates a stream, this will either: + * - open a new file handle if the stream is closed + * - move the stream to the head of the linked list + * + * Input : stream the stream to activate + * + * Output : error condition. + * + * Note : This function is also called with fresh new streams + * created by TT_Open_Stream(). They have their 'size' + * field set to -1. + * + ******************************************************************/ + + static TT_Error Stream_Activate( PStream_Rec stream ) + { + if ( !stream->opened ) + { + if ( (stream->file = fopen( (TT_Text*)stream->name, "rb" )) == 0 ) + return TT_Err_Could_Not_ReOpen_File; + + stream->opened = TRUE; + + /* A newly created stream has a size field of -1 */ + if ( stream->size < 0 ) + { + fseek( stream->file, 0, SEEK_END ); + stream->size = ftell( stream->file ); + fseek( stream->file, 0, SEEK_SET ); + } + + /* Reset cursor in file */ + if ( stream->position ) + { + if ( fseek( stream->file, stream->position, SEEK_SET ) != 0 ) + { + /* error during seek */ + fclose( stream->file ); + stream->opened = FALSE; + return TT_Err_Could_Not_ReSeek_File; + } + } + } + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Stream_DeActivate + * + * Description : deactivates a stream, this will : + * - close its file handle if it was opened + * - remove it from the opened list if necessary + * + * Input : stream the stream to deactivate + * + * Output : Error condition + * + * Note : the function is called whenever a stream is deleted + * (_not_ when a stream handle's is closed due to an + * activation). However, the stream record isn't + * destroyed by it.. + * + ******************************************************************/ + + static TT_Error Stream_Deactivate( PStream_Rec stream ) + { + if ( stream->opened ) + { + /* Save its current position within the file */ + stream->position = ftell( stream->file ); + fclose( stream->file ); + stream->file = 0; + stream->opened = FALSE; + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Stream_Size + * + * Description : Returns the length of a given stream, even if it + * is flushed. + * + * Input : stream the stream + * + * Output : Length of stream in bytes. + * + ******************************************************************/ + + FT_EXPORT_FUNC( Long ) + TT_Stream_Size( TT_Stream stream ) + { + PStream_Rec rec = STREAM2REC( stream ); + + + if ( rec ) + return rec->size; + else + return 0; /* invalid stream - return 0 */ + } + + +/******************************************************************* + * + * 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 sucess, FAILURE on error. + * The target stream is set to -1 in case of failure. + * + ******************************************************************/ + + FT_INTERNAL_FUNC( TT_Error ) + TT_Open_Stream( const TT_Text* filepathname, + TT_Stream* stream ) + { + Int len; + TT_Error error; + PStream_Rec stream_rec; + + if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) ) + return error; + + stream_rec = STREAM2REC( *stream ); + + stream_rec->file = NULL; + stream_rec->size = -1L; + stream_rec->base = 0; + stream_rec->opened = FALSE; + stream_rec->position = 0; + + len = strlen( filepathname ) + 1; + if ( ALLOC( stream_rec->name, len ) ) + goto Fail; + + strncpy( stream_rec->name, filepathname, len ); + + error = Stream_Activate( stream_rec ); + if ( error ) + goto Fail_Activate; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + CUR_Stream = stream_rec; +#endif + + return TT_Err_Ok; + + Fail_Activate: + FREE( stream_rec->name ); + Fail: + FREE( stream_rec ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes a stream. + * + * Input : stream address of target TT_Stream structure + * + * Output : SUCCESS (always). + * + ******************************************************************/ + + FT_INTERNAL_FUNC( TT_Error ) + TT_Close_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + Stream_Deactivate( rec ); + FREE( rec->name ); + FREE( rec ); + + HANDLE_Set( *stream, NULL ); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : Flushes a stream, i.e., closes its file handle. + * + * Input : stream address of target TT_Stream structure + * + * Output : Error code + * + * NOTE : Never flush the current opened stream. This means that + * you should _never_ call this function between a + * TT_Use_Stream() and a TT_Done_Stream()! + * + ******************************************************************/ + + FT_EXPORT_FUNC( TT_Error ) + TT_Flush_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + if ( rec ) + { + Stream_Deactivate( rec ); + return TT_Err_Ok; + } + else + return TT_Err_Invalid_Argument; + } + + +/******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seeks the file cursor to a different position. + * + * Input : position new position in file + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + FT_EXPORT_FUNC( TT_Error ) + TT_Seek_File( STREAM_ARGS Long position ) + { + position += CUR_Stream->base; + + if ( fseek( CUR_Stream->file, position, SEEK_SET ) ) + return TT_Err_Invalid_File_Offset; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skips forward the file cursor. + * + * Input : distance number of bytes to skip + * + * Output : see TT_Seek_File() + * + ******************************************************************/ + + FT_EXPORT_FUNC( TT_Error ) + TT_Skip_File( STREAM_ARGS Long distance ) + { + return TT_Seek_File( STREAM_VARS ftell( CUR_Stream->file ) - + CUR_Stream->base + distance ); + } + + +/******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copies it to memory. + * + * Input : buffer target buffer + * count length in bytes to read + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + FT_EXPORT_FUNC( TT_Error ) + TT_Read_File( STREAM_ARGS void* buffer, Long count ) + { + if ( fread( buffer, 1, count, CUR_Stream->file ) != (ULong)count ) + return TT_Err_Invalid_File_Read; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Reads file at a specified position. + * + * Input : position position to seek to before read + * buffer target buffer + * count number of bytes to read + * + * Output : SUCCESS on success. FAILURE if error. + * + ******************************************************************/ + + FT_EXPORT_FUNC( TT_Error ) + TT_Read_At_File( STREAM_ARGS Long position, + void* buffer, + Long count ) + { + TT_Error error; + + + if ( (error = TT_Seek_File( STREAM_VARS position )) != TT_Err_Ok || + (error = TT_Read_File( STREAM_VARS buffer, count )) != TT_Err_Ok ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_File_Pos + * + * Description : Returns current file seek pointer. + * + * Input : none + * + * Output : Current file position. + * + ******************************************************************/ + + FT_EXPORT_FUNC( Long ) + TT_File_Pos( STREAM_ARG ) + { + return ftell( CUR_Stream->file ) - CUR_Stream->base; + } + + +/******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted Byte. + * + ******************************************************************/ +#if 0 + FT_EXPORT_FUNC( Byte ) + TT_Get_Byte( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Byte)(*CUR_Frame.cursor++); + } +#endif + + +/******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted char. + * + ******************************************************************/ + + FT_EXPORT_FUNC( Char ) + TT_Get_Char( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Char)(*CUR_Frame.cursor++); + } + + +/******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted short. + * + ******************************************************************/ + + FT_EXPORT_FUNC( Short ) + TT_Get_Short( FRAME_ARG ) + { + Short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = (Short)((CUR_Frame.cursor[0] << 8) | + CUR_Frame.cursor[1]); + + CUR_Frame.cursor += 2; + + return getshort; + } + + +/******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame. + * + * Input : None or current frame + * + * Output : Extracted ushort. + * + ******************************************************************/ +#if 0 + FT_EXPORT_FUNC( UShort ) + TT_Get_UShort( FRAME_ARG ) + { + UShort getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = (UShort)((CUR_Frame.cursor[0] << 8) | + CUR_Frame.cursor[1]); + + CUR_Frame.cursor += 2; + + return getshort; + } +#endif + + +/******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame. + * + * Input : None or current frame + * + * Output : Extracted long. + * + ******************************************************************/ + + FT_EXPORT_FUNC( Long ) + TT_Get_Long( FRAME_ARG ) + { + Long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ((Long)CUR_Frame.cursor[0] << 24) | + ((Long)CUR_Frame.cursor[1] << 16) | + ((Long)CUR_Frame.cursor[2] << 8 ) | + (Long)CUR_Frame.cursor[3]; + + CUR_Frame.cursor += 4; + + return getlong; + } + + +/******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame. + * + * Input : None or current frame + * + * Output : Extracted ulong. + * + ******************************************************************/ +#if 0 + FT_EXPORT_FUNC( ULong ) + TT_Get_ULong( FRAME_ARG ) + { + ULong getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ( ((ULong)CUR_Frame.cursor[0] << 24) | + ((ULong)CUR_Frame.cursor[1] << 16) | + ((ULong)CUR_Frame.cursor[2] << 8 ) | + (ULong)CUR_Frame.cursor[3] ); + + CUR_Frame.cursor += 4; + + return getlong; + } +#endif + + +/* END */ |