forked from minhngoc25a/freetype2
872 lines
39 KiB
C
872 lines
39 KiB
C
/*******************************************************************
|
|
*
|
|
* ftsys.c
|
|
*
|
|
* Unix-specific system operations.
|
|
*
|
|
* Copyright 1996-1998 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.
|
|
*
|
|
*
|
|
* This implementation of the 'ftsys' component uses memory-mapped
|
|
* files, as well as the ANSI malloc/free functions..
|
|
*
|
|
* IMPORTANT NOTE :
|
|
*
|
|
* Porters, read carefully the comments in ftsys.h before trying
|
|
* to port this file to your system. It contains many essential
|
|
* remarks, and will ease your work greatly..
|
|
*
|
|
******************************************************************/
|
|
|
|
#include "ftsys.h"
|
|
#include "ftobjs.h"
|
|
#include "ftstream.h"
|
|
#include "ftdebug.h"
|
|
|
|
/* Memory-mapping includes and definitions.. */
|
|
/* */
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include <sys/mman.h>
|
|
#ifndef MAP_FILE
|
|
#define MAP_FILE 0x00
|
|
#endif
|
|
|
|
/*
|
|
* The prototype for munmap() is not provided on SunOS. This needs to
|
|
* have a check added later to see if the GNU C library is being used.
|
|
* If so, then this prototype is not needed.
|
|
*/
|
|
#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)
|
|
extern int munmap( caddr_t addr, int len );
|
|
#endif
|
|
|
|
#include <sys/stat.h>
|
|
#ifdef HAVE_FCNTL_H
|
|
#include <fcntl.h>
|
|
#endif
|
|
|
|
|
|
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
|
/* parameter of the PTRACE and PERROR macros, used to print/log */
|
|
/* messages during execution.. */
|
|
/* */
|
|
#undef FT_COMPONENT
|
|
#define FT_COMPONENT trace_io
|
|
|
|
|
|
|
|
|
|
/* To ease porting, we use the macro SYS_STREAM to name the system-specific */
|
|
/* stream type. For example, it is a "FILE*" with the ANSI libc, it will be */
|
|
/* a file descriptor, i.e. an integer, when using the Unix system api, etc. */
|
|
|
|
/* we identify each memory-mapped file through its address in memory */
|
|
/* hence the following macro definition.. */
|
|
|
|
#define SYS_STREAM void*
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* I/O ACCESS AND MANAGEMENT */
|
|
/* */
|
|
/* We only define the "ANSI" resource class in this class. It is */
|
|
/* disk-based, and provides a MRU cache, in order to only keep the file */
|
|
/* descriptors of the 10 most recently used resource files. */
|
|
/* */
|
|
/* it simply contains two lists. One contains the "cached" resources */
|
|
/* with a valid FILE* pointer, the second contains all other "flushed" */
|
|
/* resource objects. */
|
|
/* */
|
|
|
|
/* The FT_MMapFile class derives from FT_ResourceRec - description : */
|
|
/* */
|
|
/* <Struct> FT_AnsiFileRec */
|
|
/* */
|
|
/* <Fields> */
|
|
/* */
|
|
/* root :: */
|
|
/* the root resource class fields. */
|
|
/* */
|
|
/* pathname :: */
|
|
/* the file's pathname. Needed because we open and close font */
|
|
/* resources dynamically in order to limit the number of */
|
|
/* concurrently active mappings (this saves kernel resources). */
|
|
/* */
|
|
/* file_size :: */
|
|
/* the size in bytes of the resource. This field should be set to */
|
|
/* -1 until the resource is first opened.. */
|
|
/* */
|
|
|
|
#include <stdio.h>
|
|
|
|
typedef struct FT_MMapFileRec_
|
|
{
|
|
FT_ResourceRec root;
|
|
const char* pathname;
|
|
FT_Long file_size; /* file size in bytes */
|
|
|
|
} FT_MMapFileRec, *FT_MMapFile;
|
|
|
|
|
|
/* We use the macro STREAM_Name as a convenience to return a given */
|
|
/* ANSI resource's pathname. Its "stream" argument is a FT_Resource */
|
|
/* which is typecasted to the FT_AnsiFile class */
|
|
#define STREAM_Name(stream) ((FT_MMapFile)stream->resource)->pathname
|
|
|
|
/* We use the macro STREAM_File as a convenience to extract the */
|
|
/* system-specific stream handle from a given FreeType stream object */
|
|
#define STREAM_File(stream) ((void*)stream->stream_id.pointer)
|
|
|
|
|
|
|
|
/***************************************************************************/
|
|
/* */
|
|
/* <Function> MMapFile_Open */
|
|
/* */
|
|
/* <Description> */
|
|
/* This function is used to open a system-stream for a given resource. */
|
|
/* */
|
|
/* Note that it must update the target FreeType stream object with the */
|
|
/* system-stream handle and the resource's size. */
|
|
/* */
|
|
/* Also, the 'stream->base' field must be set to NULL for disk-based */
|
|
/* resource, and to the address in memory of the resource's first byte */
|
|
/* for a memory-based one. */
|
|
/* */
|
|
/* <Input> */
|
|
/* resource :: the source resource */
|
|
/* stream :: the target stream object */
|
|
/* */
|
|
/* <Return> */
|
|
/* Error code */
|
|
/* */
|
|
/* <Note> */
|
|
/* This function simply opens and maps the resource's file pathname */
|
|
/* */
|
|
/* The stream object IS NOT CREATED by this function, but by its caller. */
|
|
/* */
|
|
/***************************************************************************/
|
|
|
|
static
|
|
FT_Error MMapFile_Open( FT_MMapFile resource,
|
|
FT_Stream stream )
|
|
{
|
|
int file;
|
|
struct stat stat_buf;
|
|
|
|
/* open the file */
|
|
file = open( resource->pathname, O_RDONLY );
|
|
if (file < 0)
|
|
{
|
|
PERROR(( "UnixSys.MMapFile_Open : could not open '%s'\n",
|
|
resource->pathname ));
|
|
return FT_Err_Cannot_Open_Stream;
|
|
}
|
|
|
|
if (fstat( file, &stat_buf ) < 0)
|
|
{
|
|
PERROR(( "UnixSys.MMapFile_Open : could not 'fstat' file '%s'\n",
|
|
resource->pathname ));
|
|
goto Fail_Map;
|
|
}
|
|
|
|
if ( resource->file_size < 0 )
|
|
resource->file_size = stat_buf.st_size;
|
|
|
|
stream->resource = (FT_Resource)resource;
|
|
stream->system = resource->root.driver->system;
|
|
stream->size = resource->file_size;
|
|
stream->stream_id.pointer = mmap( NULL,
|
|
resource->file_size,
|
|
PROT_READ,
|
|
MAP_FILE | MAP_PRIVATE,
|
|
file,
|
|
0 );
|
|
|
|
if ( (long)stream->stream_id.pointer == -1 )
|
|
{
|
|
PERROR(( "UnixSys.MMapFile_Open : Could not map file '%s'\n",
|
|
resource->pathname ));
|
|
goto Fail_Map;
|
|
}
|
|
|
|
close(file);
|
|
stream->base = (FT_Byte*)stream->stream_id.pointer;
|
|
stream->cursor = stream->base;
|
|
|
|
PTRACE1(( "UnixSys.MMapFile_Open: opened '%s' (%d bytes) succesfully\n",
|
|
resource->pathname, resource->file_size ));
|
|
|
|
return FT_Err_Ok;
|
|
|
|
Fail_Map:
|
|
close(file);
|
|
stream->resource = NULL;
|
|
stream->size = 0;
|
|
stream->stream_id.pointer = NULL;
|
|
stream->base = NULL;
|
|
stream->cursor = NULL;
|
|
|
|
return FT_Err_Cannot_Open_Stream;
|
|
}
|
|
|
|
|
|
/***************************************************************************/
|
|
/* */
|
|
/* <Function> MMapFile_Close */
|
|
/* */
|
|
/* <Description> Closes a given stream */
|
|
/* */
|
|
/* <Input> */
|
|
/* stream :: the target stream object */
|
|
/* */
|
|
/* <Return> */
|
|
/* Error code */
|
|
/* */
|
|
/* <Note> */
|
|
/* This function simply unmaps the resource.. */
|
|
/* */
|
|
/***************************************************************************/
|
|
|
|
static
|
|
FT_Error MMapFile_Close( FT_Stream stream )
|
|
{
|
|
PTRACE1(( "Closing file '%s'\n", STREAM_Name(stream) ));
|
|
|
|
munmap ( (void*)stream->stream_id.pointer, stream->size );
|
|
|
|
stream->resource = NULL;
|
|
stream->stream_id.pointer = NULL;
|
|
stream->size = 0;
|
|
stream->base = NULL;
|
|
stream->cursor = NULL;
|
|
|
|
return FT_Err_Ok;
|
|
}
|
|
|
|
|
|
/***************************************************************************/
|
|
/* */
|
|
/* <Function> MMapFile_Seek */
|
|
/* */
|
|
/* <Description> Seek a stream to a given position */
|
|
/* */
|
|
/* <Input> */
|
|
/* stream :: the target stream object */
|
|
/* position :: offset in bytes from start of resource/stream */
|
|
/* */
|
|
/* <Return> */
|
|
/* Error code */
|
|
/* */
|
|
/* <Note> */
|
|
/* This function should never be called for memory-based resources.. */
|
|
/* */
|
|
/***************************************************************************/
|
|
|
|
static
|
|
FT_Error MMapFile_Seek( FT_Stream stream,
|
|
FT_Long position )
|
|
{
|
|
(void)stream;
|
|
(void)position;
|
|
return FT_Err_Invalid_Stream_Operation;
|
|
}
|
|
|
|
|
|
/***************************************************************************/
|
|
/* */
|
|
/* <Function> MMapFile_Skip */
|
|
/* */
|
|
/* <Description> Skip a given number of bytes in an MMap stream. */
|
|
/* Useful to skip pad bytes, for example. */
|
|
/* */
|
|
/* <Input> */
|
|
/* stream :: the target stream object */
|
|
/* count :: number of bytes to skip in the stream */
|
|
/* */
|
|
/* <Return> */
|
|
/* Error code */
|
|
/* */
|
|
/* <Note> */
|
|
/* This function should never be called for memory-based resources.. */
|
|
/* */
|
|
/***************************************************************************/
|
|
|
|
static
|
|
FT_Error MMapFile_Skip( FT_Stream stream,
|
|
FT_Long count )
|
|
{
|
|
(void)stream;
|
|
(void)count;
|
|
return FT_Err_Invalid_Stream_Operation;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
/* */
|
|
/* <Function> MMapFile_Pos */
|
|
/* */
|
|
/* <Description> Returns the current offset within an MMap stream's */
|
|
/* resource. */
|
|
/* */
|
|
/* <Input> */
|
|
/* stream :: the target stream object */
|
|
/* */
|
|
/* <Output> */
|
|
/* position :: current offset. -1 in case of error */
|
|
/* */
|
|
/* <Return> */
|
|
/* Error code. */
|
|
/* */
|
|
/* <Note> */
|
|
/* This function should never be called for memory-based resources.. */
|
|
/* */
|
|
/***************************************************************************/
|
|
|
|
static
|
|
FT_Error MMapFile_Pos( FT_Stream stream,
|
|
FT_Long* position )
|
|
{
|
|
(void)stream;
|
|
(void)position;
|
|
return FT_Err_Invalid_Stream_Operation;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
/* */
|
|
/* <Function> MMapFile_Read */
|
|
/* */
|
|
/* <Description> Read a given number of bytes from an MMap stream into */
|
|
/* memory. */
|
|
/* */
|
|
/* <Input> */
|
|
/* stream :: the target stream object */
|
|
/* buffer :: the target read buffer where data is copied */
|
|
/* size :: number of bytes to read from the stream */
|
|
/* */
|
|
/* <Output> */
|
|
/* read_bytes :: the number of bytes effectively read from the stream */
|
|
/* used in case of error (i.e. FT_Err_Invalid_Stream_Read) */
|
|
/* by some parts of the library.. */
|
|
/* <Return> */
|
|
/* Error code */
|
|
/* */
|
|
/* <Note> */
|
|
/* This function should never be called for memory-based resources.. */
|
|
/* */
|
|
/***************************************************************************/
|
|
|
|
static
|
|
FT_Error MMapFile_Read( FT_Stream stream,
|
|
FT_Byte* buffer,
|
|
FT_Long size,
|
|
FT_Long* read_bytes )
|
|
{
|
|
(void)stream;
|
|
(void)buffer;
|
|
(void)size;
|
|
(void)read_bytes;
|
|
return FT_Err_Invalid_Stream_Operation;
|
|
}
|
|
|
|
/* The following table is the "virtual method table" for the 'MMap */
|
|
/* resource class', which methods are defined above. Its address is */
|
|
/* set in the 'interface' field of all resource objects created by */
|
|
/* the function FT_Create_MMapFile (see below) */
|
|
|
|
static
|
|
FTRes_InterfaceRec FT_MMapFile_Interface =
|
|
{
|
|
(FTRes_Open_Func) MMapFile_Open,
|
|
(FTRes_Close_Func) MMapFile_Close,
|
|
(FTRes_Seek_Func) MMapFile_Seek,
|
|
(FTRes_Skip_Func) MMapFile_Skip,
|
|
(FTRes_Pos_Func) MMapFile_Pos,
|
|
(FTRes_Read_Func) MMapFile_Read,
|
|
};
|
|
|
|
|
|
/************************************************************************/
|
|
/* */
|
|
/* <Function> FT_Create_Resource */
|
|
/* */
|
|
/* <Description> */
|
|
/* Create a new resource object for a given library. Note that this */
|
|
/* function takes an ASCII 'pathname' as an argument. */
|
|
/* */
|
|
/* <Input> */
|
|
/* library :: handle to target library object */
|
|
/* pathanme :: ASCII pathname of the font file */
|
|
/* */
|
|
/* <Output> */
|
|
/* resource :: handle to new resource object */
|
|
/* */
|
|
/* <Return> */
|
|
/* Error code. 0 means success */
|
|
/* */
|
|
/* <Note> */
|
|
/* When porting the library to exotic environments, where an */
|
|
/* ASCII pathname isn't used to name files, developers should */
|
|
/* invoke directly their own resource creation function which */
|
|
/* must be placed in their port of the "ftsys" component. */
|
|
/* */
|
|
/* See the porting guide for more information.. */
|
|
/* */
|
|
EXPORT_FUNC
|
|
FT_Error FT_Create_Resource( FT_Library library,
|
|
const char* pathname,
|
|
FT_Resource* aresource )
|
|
{
|
|
FT_Int len;
|
|
FT_System system;
|
|
FT_MMapFile resource;
|
|
FT_Error error;
|
|
|
|
*aresource = NULL;
|
|
|
|
if (!library)
|
|
{
|
|
PERROR(( "Unix.New_Resource : null library handle\n" ));
|
|
return FT_Err_Invalid_Library_Handle;
|
|
}
|
|
|
|
system = library->system;
|
|
|
|
if ( !pathname )
|
|
goto Fail_Null;
|
|
|
|
len = strlen(pathname);
|
|
if (len == 0)
|
|
goto Fail_Null;
|
|
|
|
resource = NULL;
|
|
|
|
if ( ALLOC( resource, sizeof(*resource) ) ||
|
|
ALLOC( resource->pathname, len+1 ) )
|
|
goto Fail_Memory;
|
|
|
|
resource->root.library = library;
|
|
resource->root.interface = &FT_MMapFile_Interface;
|
|
resource->root.flags = FT_RESOURCE_TYPE_MEMORY_BASED;
|
|
resource->file_size = -1;
|
|
strcpy( (char*)resource->pathname, pathname );
|
|
|
|
PTRACE1(( "Create_MMapFile : MMap resource created for '%s'\n",
|
|
pathname ));
|
|
|
|
*aresource = (FT_Resource)resource;
|
|
return FT_Err_Ok;
|
|
|
|
Fail_Null:
|
|
PERROR(( "Create_MMapFile : null pathname !!\n" ));
|
|
return FT_Err_Invalid_Argument;
|
|
|
|
Fail_Memory:
|
|
if (resource)
|
|
FREE( resource->pathname );
|
|
FREE( resource );
|
|
PERROR(( "Create_MMapFile : error when creating resource !\n" ));
|
|
return error;
|
|
}
|
|
|
|
|
|
/***************************************************************************/
|
|
/* */
|
|
/* <Function> FT_Destroy_Resource */
|
|
/* */
|
|
/* <Description> Destroys an MMap resource object. */
|
|
/* This function is never called directly by the font */
|
|
/* drivers. Only by the higher-level part of FreeType */
|
|
/* (called the HLib), or client applications */
|
|
/* */
|
|
/* <Input> */
|
|
/* resource :: the MMap resource object */
|
|
/* */
|
|
/* <Note> */
|
|
/* This functions does not check that runs or streams are opened for */
|
|
/* the resource (for now, we assume developer intelligence. We'll most */
|
|
/* probably lower our standard later to ease debugging ;-) */
|
|
/* */
|
|
/***************************************************************************/
|
|
|
|
EXPORT_FUNC
|
|
FT_Error FT_Destroy_Resource( FT_Resource resource )
|
|
{
|
|
FT_System system = resource->library->system;
|
|
FT_MMapFile res = (FT_MMapFile)resource;
|
|
|
|
if ( !res || res->root.interface != &FT_MMapFile_Interface )
|
|
{
|
|
PERROR((
|
|
"Destroy_MMapFile : Trying to destroy an invalid resource !!\n" ));
|
|
return FT_Err_Invalid_Resource_Handle;
|
|
}
|
|
|
|
PTRACE1(( "Destroy_MMapFile : destroying resource for '%s'\n",
|
|
res->pathname ));
|
|
|
|
FREE( res->pathname );
|
|
FREE( res );
|
|
|
|
return FT_Err_Ok;
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* MEMORY MANAGEMENT */
|
|
/* */
|
|
/* */
|
|
/* This part copies the old FreeType 1.0 and 1.1 memory management */
|
|
/* scheme that was defined in the file "ttmemory.h". One can see that */
|
|
/* */
|
|
/* - a set of macros is defined for the memory operations used */
|
|
/* by the engine ( MEM_Copy, MEM_Move, MEM_Set ). This comes from */
|
|
/* the fact that many compilers are able to inline these ops directly */
|
|
/* within the compiled code, rather than generating a call to the */
|
|
/* C library. However, this obliges us to include the <string.h> */
|
|
/* header file. */
|
|
/* */
|
|
/* If you provide your own memory operations routine, you can get */
|
|
/* rid of the #include <string.h> below. */
|
|
/* */
|
|
/* */
|
|
/* - the FT_Alloc function has several essential properties that */
|
|
/* MUST be retained by each port : */
|
|
/* */
|
|
/* - it returns an error code, NOT the allocated block's base */
|
|
/* address */
|
|
/* */
|
|
/* - it takes the address of a target pointer, where the block's */
|
|
/* base address will be set. if the size is zero, its value */
|
|
/* will be NULL and the function returns successfully */
|
|
/* */
|
|
/* - in case of error, the pointer's value is set to NULL and */
|
|
/* an error code is returned.. */
|
|
/* */
|
|
/* - the new allocated block MUST be zero-filled. This is a strong */
|
|
/* convetion the rest of the engine relies on */
|
|
/* */
|
|
/* */
|
|
/* */
|
|
/* - the FT_Free function has also its essentials : */
|
|
/* */
|
|
/* - it takes the address of a pointer which value is the block's */
|
|
/* base address. This is UNLIKE a standard "free" which takes the */
|
|
/* the block's base directly. */
|
|
/* */
|
|
/* - it accepts succesfully the address of a pointer which value */
|
|
/* is NULL, in which case it simply returns. */
|
|
/* */
|
|
/* - the pointer is always set to NULL by the function */
|
|
/* */
|
|
/* */
|
|
/* - the MEM_Alloc, ALLOC and ALLOC_ARRAY macros are used by the */
|
|
/* library, and should NOT be modified by porters !! */
|
|
/* */
|
|
|
|
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
|
/* parameter of the PTRACE and PERROR macros, used to print/log */
|
|
/* messages during execution.. */
|
|
/* */
|
|
#undef FT_COMPONENT
|
|
#define FT_COMPONENT trace_memory
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* <Function> FT_Alloc */
|
|
/* */
|
|
/* <Description> */
|
|
/* Allocates a new bloc of memory. The returned area is always */
|
|
/* zero-filled, this is a strong convention in many FreeType parts */
|
|
/* */
|
|
/* <Input> */
|
|
/* system :: handle to a given 'system object' where allocation */
|
|
/* occurs.. */
|
|
/* */
|
|
/* size :: size in bytes of the block to allocate */
|
|
/* */
|
|
/* <Output> */
|
|
/* P :: pointer to the fresh new block. It should be set */
|
|
/* to NULL if 'size' is 0, of in case of error.. */
|
|
/* */
|
|
/* <Return> */
|
|
/* FreeType error code. 0 means success. */
|
|
/* */
|
|
/**************************************************************************/
|
|
|
|
BASE_FUNC
|
|
FT_Error FT_Alloc( FT_System system,
|
|
long size,
|
|
void* *P )
|
|
{
|
|
|
|
if (!P)
|
|
{
|
|
PERROR(( "FT_Alloc : invalid pointer address !!\n" ));
|
|
return FT_Err_Invalid_Argument;
|
|
}
|
|
|
|
if ( size > 0 )
|
|
{
|
|
*P = malloc( size );
|
|
if ( !*P )
|
|
{
|
|
PERROR(( "FT_Alloc : out of memory (%ld bytes requested) !!\n",
|
|
size ));
|
|
|
|
return FT_Err_Out_Of_Memory;
|
|
}
|
|
|
|
system->total_alloc += size;
|
|
|
|
/* ALWAYS ZERO-FILL THE BLOCK !!!!! */
|
|
MEM_Set( *P, 0, size );
|
|
}
|
|
else
|
|
*P = NULL;
|
|
|
|
PTRACE2(( "FT_Alloc : size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
|
|
size, (long)P, (long)*P ));
|
|
|
|
return FT_Err_Ok;
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* <Function> FT_Realloc */
|
|
/* */
|
|
/* <Description> */
|
|
/* Reallocates a block of memory pointed to by '*P' to 'Size' */
|
|
/* bytes from the hea^, possibly changing '*P'. */
|
|
/* */
|
|
/* <Input> */
|
|
/* system :: handle to a given 'system object' where allocation */
|
|
/* occurs.. */
|
|
/* */
|
|
/* size :: size in bytes of the block to allocate */
|
|
/* */
|
|
/* <InOut> */
|
|
/* P :: pointer to the fresh new block. It should be set */
|
|
/* to NULL if 'size' is 0, of in case of error.. */
|
|
/* */
|
|
/* <Return> */
|
|
/* FreeType error code. 0 means success. */
|
|
/* */
|
|
|
|
BASE_FUNC
|
|
int FT_Realloc( FT_System system,
|
|
long size,
|
|
void* *P )
|
|
{
|
|
void* Q;
|
|
|
|
if (!P)
|
|
{
|
|
PERROR(( "FT_Realloc : invalid pointer address !!\n" ));
|
|
return FT_Err_Invalid_Argument;
|
|
}
|
|
|
|
/* if the original pointer is NULL, call FT_Alloc */
|
|
if (!*P)
|
|
return FT_Alloc( system, size, P );
|
|
|
|
/* if the new block if zero-sized, clear the current one */
|
|
if (size <= 0)
|
|
return FT_Free( system, P );
|
|
|
|
Q = (void*)realloc( *P, size );
|
|
if (!Q)
|
|
{
|
|
PERROR(( "FT_Realloc : reallocation failed\n" ));
|
|
return FT_Err_Out_Of_Memory;
|
|
}
|
|
|
|
*P = Q;
|
|
return FT_Err_Ok;
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* <Function> FT_Free */
|
|
/* */
|
|
/* <Description> */
|
|
/* Releases a given block of memory allocated through FT_Alloc */
|
|
/* */
|
|
/* <Input> */
|
|
/* system :: handle to a given 'system object' where allocation */
|
|
/* occured.. */
|
|
/* */
|
|
/* P :: This is the _address_ of a _pointer_ which points to */
|
|
/* the allocated block. It is always set to NULL on exit */
|
|
/* */
|
|
/* <Return> */
|
|
/* FreeType error code. 0 means success. */
|
|
/* */
|
|
/* <Note> */
|
|
/* If P or *P are NULL, this function should return successfuly. This */
|
|
/* is a strong convention within all of FreeType and its drivers.. */
|
|
/* */
|
|
|
|
BASE_FUNC
|
|
FT_Error FT_Free( FT_System system,
|
|
void* *P )
|
|
{
|
|
(void)system; /* unused parameter. Gets rid of warnings */
|
|
|
|
PTRACE2(( "FT_Free : freeing pointer 0x%08lx (block 0x%08lx)\n",
|
|
(long)P, (P ? (long)*P : -1) ));
|
|
|
|
if ( !P || !*P )
|
|
return FT_Err_Ok;
|
|
|
|
free( *P );
|
|
*P = NULL;
|
|
|
|
return FT_Err_Ok;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* SYNCHRONIZATION MANAGEMENT */
|
|
/* */
|
|
/* */
|
|
/* This section deals with mutexes. The library can be compiled to */
|
|
/* three distinct thread-support levels ( namely single-threaded, */
|
|
/* thread-safe and re-entrant modes ). */
|
|
/* */
|
|
/* It protects its variables through the MUTEX_Lock and MUTEX_Release */
|
|
/* macros which are void in single-threaded mode. */
|
|
/* */
|
|
/* */
|
|
/* It defines a type-less mutex reference type, "TMutex", that you're */
|
|
/* free to redefine for your system's needs.. */
|
|
/* */
|
|
/* The default implementation of ftsys.c contains only dummy functions */
|
|
/* which always return succesfully. you NEED to specialize them in */
|
|
/* order to port ftsys.c in any multi-threaded environment... */
|
|
/* */
|
|
|
|
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
|
/* parameter of the PTRACE and PERROR macros, used to print/log */
|
|
/* messages during execution.. */
|
|
/* */
|
|
#undef FT_COMPONENT
|
|
#define FT_COMPONENT trace_sync
|
|
|
|
#ifdef FT_CONFIG_THREADS
|
|
|
|
|
|
BASE_FUNC
|
|
FT_Error FT_Mutex_Create ( FT_System system,
|
|
TMutex* mutex )
|
|
{
|
|
(void)system; /* unused parameter. Gets rid of warnings */
|
|
|
|
mutex = (void*)-1;
|
|
system->num_mutexes++;
|
|
return FT_Err_Ok;
|
|
/* Replace this line with your own mutex creation code */
|
|
}
|
|
|
|
|
|
BASE_FUNC
|
|
void FT_Mutex_Delete ( FT_System system,
|
|
TMutex* mutex )
|
|
{
|
|
(void)system; /* unused parameter. Gets rid of warnings */
|
|
|
|
mutex = (void*)0;
|
|
system->num_mutexes--;
|
|
/* Replace this line with your own mutex destruction code */
|
|
}
|
|
|
|
BASE_FUNC
|
|
void FT_Mutex_Lock ( FT_System system,
|
|
TMutex* mutex )
|
|
{
|
|
/* NOTE: It is legal to call this function with a NULL argument */
|
|
/* in which case an immediate return is appropriate. */
|
|
(void)system; /* unused parameter. Gets rid of warnings */
|
|
|
|
if ( !mutex )
|
|
return;
|
|
|
|
; /* Insert your own mutex locking code here */
|
|
}
|
|
|
|
|
|
void FT_Mutex_Release( FT_System system,
|
|
TMutex* mutex )
|
|
{
|
|
/* NOTE: It is legal to call this function with a NULL argument */
|
|
/* in which case an immediate return is appropriate */
|
|
(void)system; /* unused parameter. Gets rid of warnings */
|
|
|
|
if ( !mutex )
|
|
return;
|
|
; /* Insert your own mutex release code here */
|
|
}
|
|
|
|
#endif /* FT_CONFIG_THREADS */
|
|
|
|
|
|
|
|
|
|
EXPORT_FUNC
|
|
FT_Error FT_New_System( FT_System* system )
|
|
{
|
|
*system = (FT_System)malloc( sizeof(FT_SystemRec) );
|
|
if ( !*system )
|
|
return FT_Err_Out_Of_Memory;
|
|
|
|
/* the ANSI function 'free' is unable to return the number */
|
|
/* of released bytes. Hence, the 'current_alloc' field of the */
|
|
/* system object cannot be used */
|
|
|
|
(*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
|
|
FT_SYSTEM_FLAG_MUTEXES;
|
|
(*system)->total_alloc = 0;
|
|
(*system)->num_mutexes = 0;
|
|
|
|
/* initialise i/o management (nothing) */
|
|
|
|
/* initialise synchronisation (nothing) */
|
|
|
|
/* initialise streams */
|
|
|
|
return FT_Err_Ok;
|
|
}
|
|
|
|
|
|
|
|
EXPORT_FUNC
|
|
FT_Error FT_Done_System( FT_System system )
|
|
{
|
|
/* finalise syncrhonisation (nothing) */
|
|
|
|
/* finalise i/o management (nothing) */
|
|
|
|
/* finalise memory management */
|
|
free( system );
|
|
|
|
return FT_Err_Ok;
|
|
}
|
|
|