зеркало из https://github.com/mozilla/pjs.git
Update to freetype 2.1.0. Not part of the default build.
This commit is contained in:
Родитель
1e632eef6d
Коммит
b065698ab6
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,29 +0,0 @@
|
|||
|
||||
Special note to Unix users
|
||||
==========================
|
||||
|
||||
Please read the file "README.UNX", it contains important
|
||||
information regarding the installation of FreeType on Unix
|
||||
systems, especially GNU based operating systems like GNU/Linux.
|
||||
|
||||
|
||||
FreeType 2.0.8
|
||||
==============
|
||||
|
||||
Please read the docs/CHANGES file, it contains IMPORTANT
|
||||
INFORMATION.
|
||||
|
||||
Read the files "docs/INSTALL" or "docs/BUILD" for installation
|
||||
instructions.
|
||||
|
||||
Note that the FreeType 2 documentation is now available as a
|
||||
separate package from our sites. See:
|
||||
|
||||
ftp://ftp.freetype.org/pub/freetype2/ftdocs-2.0.8.tar.bz2
|
||||
ftp://ftp.freetype.org/pub/freetype2/ftdocs-2.0.8.tar.gz
|
||||
ftp://ftp.freetype.org/pub/freetype2/ftdoc207.zip
|
||||
|
||||
Enjoy!
|
||||
|
||||
|
||||
The FreeType Team
|
|
@ -1,107 +0,0 @@
|
|||
|
||||
SPECIAL NOTE FOR UNIX USERS
|
||||
===========================
|
||||
|
||||
If you are installing this release of FreeType on a system that
|
||||
already uses release 2.0.5 (or even an older version), you have to
|
||||
perform a few special steps to ensure that everything goes well.
|
||||
|
||||
|
||||
|
||||
I. Enable the TrueType bytecode hinter if you need it
|
||||
-----------------------------------------------------
|
||||
|
||||
The TrueType bytecode interpreter is disabled in all public
|
||||
releases of the FreeType packages for patents reasons (see
|
||||
http://www.freetype.org/patents.html for more details).
|
||||
|
||||
However, many Linux distributions do enable the interpreter in the
|
||||
FreeType packages (DEB/RPM/etc.) they produce for their platforms.
|
||||
If you are using TrueType fonts on your system, you most probably
|
||||
want to enable it manually by doing the following:
|
||||
|
||||
- open the file "include/freetype/config/ftoption.h"
|
||||
|
||||
- locate a line that says:
|
||||
|
||||
#undef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
|
||||
- change it to:
|
||||
|
||||
#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
|
||||
of course, this must be done _before_ compiling the library
|
||||
|
||||
|
||||
|
||||
II. Determine the correct installation path
|
||||
-------------------------------------------
|
||||
|
||||
By default, the source package will install the library in
|
||||
"/usr/local". However, many Unix distributions now install the
|
||||
library in "/usr", since FreeType is becoming a critical system
|
||||
component.
|
||||
|
||||
If FreeType is already installed on your system, type
|
||||
|
||||
freetype-config --prefix
|
||||
|
||||
on the command line. This should return the installation path to
|
||||
use below (e.g. "/usr" or "/usr/local"). Otherwise, simply use
|
||||
"/usr".
|
||||
|
||||
Then, to build and install the library, type:
|
||||
|
||||
./configure --prefix=<yourprefix>
|
||||
make
|
||||
make install (as root)
|
||||
|
||||
where "<yourprefix>" must be replaced by the prefix returned by
|
||||
the "freetype-config" command.
|
||||
|
||||
|
||||
|
||||
III. Take care of XFree86 version 4
|
||||
-----------------------------------
|
||||
|
||||
Certain recent Linux distributions will install _several_ versions
|
||||
of FreeType on your system. For example, on a fresh Mandrake 8.1
|
||||
system, you can find the following files:
|
||||
|
||||
/usr/lib/libfreetype.so which links to
|
||||
/usr/lib/libfreetype.6.1.0.so
|
||||
|
||||
and
|
||||
|
||||
/usr/X11R6/lib/libfreetype.so which links to
|
||||
/usr/X11R6/lib/libfreetype.6.0.so
|
||||
|
||||
Note that these files correspond to two distinct versions of the
|
||||
library! It seems that this surprising issue is due to the
|
||||
install scripts of recent XFree86 servers (from 4.1.0) which
|
||||
irremediably install their own (dated) version of the library in
|
||||
"/usr/X11R6/lib".
|
||||
|
||||
In certain _rare_ cases you may experience minor problems if you
|
||||
install this release of the library in "/usr" only, namely, that
|
||||
certain applications will not benefit from the bug fixes and
|
||||
rendering improvements you'd expect.
|
||||
|
||||
There are two good ways to deal with this situation:
|
||||
|
||||
- Install the library _twice_, in "/usr" and in "/usr/X11R6"
|
||||
(you have to do that each time you install a new FreeType
|
||||
release though).
|
||||
|
||||
- Change the link in /usr/X11R6/lib/libfreetype.so to point to
|
||||
|
||||
/usr/lib/libfreetype.so,
|
||||
|
||||
and get rid of
|
||||
|
||||
/usr/X11R6/lib/libfreetype.6.0.so
|
||||
|
||||
The FreeType Team is not responsible for this problem, so please
|
||||
contact either the XFree86 development team or your Linux
|
||||
distributor to help clear this issue in case the information given
|
||||
here doesn't help.
|
|
@ -1,123 +0,0 @@
|
|||
// TetiSoft: replaced vprintf() with KVPrintF() and commented out exit()
|
||||
extern void __stdargs KVPrintF( const char *formatString, const void *values );
|
||||
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftdebug.c */
|
||||
/* */
|
||||
/* Debugging and logging component (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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 component contains various macros and functions used to ease the */
|
||||
/* debugging of the FreeType engine. Its main purpose is in assertion */
|
||||
/* checking, tracing, and error detection. */
|
||||
/* */
|
||||
/* There are now three debugging modes: */
|
||||
/* */
|
||||
/* - trace mode */
|
||||
/* */
|
||||
/* Error and trace messages are sent to the log file (which can be the */
|
||||
/* standard error output). */
|
||||
/* */
|
||||
/* - error mode */
|
||||
/* */
|
||||
/* Only error messages are generated. */
|
||||
/* */
|
||||
/* - release mode: */
|
||||
/* */
|
||||
/* No error message is sent or generated. The code is free from any */
|
||||
/* debugging parts. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
char ft_trace_levels[trace_max];
|
||||
#endif
|
||||
|
||||
|
||||
#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE )
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Message( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start( ap, fmt );
|
||||
// vprintf( fmt, ap );
|
||||
KVPrintF( fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Panic( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start( ap, fmt );
|
||||
// vprintf( fmt, ap );
|
||||
KVPrintF( fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
// exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_SetTraceLevel( FT_Trace component,
|
||||
char level )
|
||||
{
|
||||
if ( component >= trace_max )
|
||||
return;
|
||||
|
||||
/* if component is `trace_any', change _all_ levels at once */
|
||||
if ( component == trace_any )
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
for ( n = trace_any; n < trace_max; n++ )
|
||||
ft_trace_levels[n] = level;
|
||||
}
|
||||
else /* otherwise, only change individual component */
|
||||
ft_trace_levels[component] = level;
|
||||
}
|
||||
|
||||
#endif /* FT_DEBUG_LEVEL_TRACE */
|
||||
|
||||
#endif /* FT_DEBUG_LEVEL_TRACE || FT_DEBUG_LEVEL_ERROR */
|
||||
|
||||
|
||||
/* ANSI C doesn't allow empty files, so we insert a dummy symbol */
|
||||
extern const int ft_debug_dummy;
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,440 +0,0 @@
|
|||
// TetiSoft: Modified to avoid fopen() fclose() fread() fseek() ftell()
|
||||
// malloc() realloc() and free() which can't be used in an amiga
|
||||
// shared run-time library linked with libinit.o
|
||||
|
||||
#include <exec/memory.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
// Avoid warnings "struct X declared inside parameter list"
|
||||
#include <exec/devices.h>
|
||||
#include <exec/io.h>
|
||||
#include <exec/semaphores.h>
|
||||
#include <dos/exall.h>
|
||||
#endif
|
||||
|
||||
// Necessary with OS3.9 includes
|
||||
#define __USE_SYSBASE
|
||||
|
||||
#include <proto/exec.h>
|
||||
#include <proto/dos.h>
|
||||
|
||||
#ifndef __GNUC__
|
||||
/* TetiSoft: Missing in alib_protos.h, see amiga.lib autodoc
|
||||
* (These amiga.lib functions work under AmigaOS V33 and up)
|
||||
*/
|
||||
extern APTR __asm AsmCreatePool(register __d0 ULONG memFlags,
|
||||
register __d1 ULONG puddleSize,
|
||||
register __d2 ULONG threshSize,
|
||||
register __a6 struct ExecBase *SysBase);
|
||||
|
||||
extern VOID __asm AsmDeletePool(register __a0 APTR poolHeader,
|
||||
register __a6 struct ExecBase *SysBase);
|
||||
|
||||
extern APTR __asm AsmAllocPooled(register __a0 APTR poolHeader,
|
||||
register __d0 ULONG memSize,
|
||||
register __a6 struct ExecBase *SysBase);
|
||||
|
||||
extern VOID __asm AsmFreePooled(register __a0 APTR poolHeader,
|
||||
register __a1 APTR memory,
|
||||
register __d0 ULONG memSize,
|
||||
register __a6 struct ExecBase *SysBase);
|
||||
#endif
|
||||
|
||||
|
||||
// TetiSoft: C implementation of AllocVecPooled (see autodoc exec/AllocPooled)
|
||||
APTR AllocVecPooled(APTR poolHeader, ULONG memSize)
|
||||
{
|
||||
ULONG newSize = memSize + sizeof(ULONG);
|
||||
#ifdef __GNUC__
|
||||
ULONG *mem = AllocPooled(poolHeader, newSize);
|
||||
#else
|
||||
ULONG *mem = AsmAllocPooled(poolHeader, newSize, SysBase);
|
||||
#endif
|
||||
|
||||
if (!mem)
|
||||
return NULL;
|
||||
*mem = newSize;
|
||||
return mem + 1;
|
||||
}
|
||||
|
||||
// TetiSoft: C implementation of FreeVecPooled (see autodoc exec/AllocPooled)
|
||||
void FreeVecPooled(APTR poolHeader, APTR memory)
|
||||
{
|
||||
ULONG *realmem = (ULONG *)memory - 1;
|
||||
|
||||
#ifdef __GNUC__
|
||||
FreePooled(poolHeader, realmem, *realmem);
|
||||
#else
|
||||
AsmFreePooled(poolHeader, realmem, *realmem, SysBase);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftsystem.c */
|
||||
/* */
|
||||
/* ANSI-specific FreeType low-level system interface (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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 file contains the default interface used by FreeType to access */
|
||||
/* low-level, i.e. memory management, i/o access as well as thread */
|
||||
/* synchronisation. It can be replaced by user-specific routines if */
|
||||
/* necessary. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_SYSTEM_H
|
||||
#include FT_ERRORS_H
|
||||
#include FT_TYPES_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* MEMORY MANAGEMENT INTERFACE */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* It is not necessary to do any error checking for the */
|
||||
/* allocation-related functions. This will be done by the higher level */
|
||||
/* routines like FT_Alloc() or FT_Realloc(). */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_alloc */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory allocation function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* size :: The requested size in bytes. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of newly allocated block. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void* )
|
||||
ft_alloc( FT_Memory memory,
|
||||
long size )
|
||||
{
|
||||
// FT_UNUSED( memory );
|
||||
|
||||
// return malloc( size );
|
||||
return AllocVecPooled( memory->user, size );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_realloc */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory reallocation function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* cur_size :: The current size of the allocated memory block. */
|
||||
/* */
|
||||
/* new_size :: The newly requested size in bytes. */
|
||||
/* */
|
||||
/* block :: The current address of the block in memory. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of the reallocated memory block. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void* )
|
||||
ft_realloc( FT_Memory memory,
|
||||
long cur_size,
|
||||
long new_size,
|
||||
void* block )
|
||||
{
|
||||
// FT_UNUSED( memory );
|
||||
// FT_UNUSED( cur_size );
|
||||
|
||||
// return realloc( block, new_size );
|
||||
|
||||
void* new_block;
|
||||
|
||||
new_block = AllocVecPooled ( memory->user, new_size );
|
||||
if ( new_block != NULL )
|
||||
{
|
||||
CopyMem ( block, new_block,
|
||||
( new_size > cur_size ) ? cur_size : new_size );
|
||||
FreeVecPooled ( memory->user, block );
|
||||
}
|
||||
return new_block;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_free */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory release function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* block :: The address of block in memory to be freed. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_free( FT_Memory memory,
|
||||
void* block )
|
||||
{
|
||||
// FT_UNUSED( memory );
|
||||
|
||||
// free( block );
|
||||
|
||||
FreeVecPooled( memory->user, block );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* RESOURCE MANAGEMENT INTERFACE */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_io
|
||||
|
||||
/* We use the macro STREAM_FILE for convenience to extract the */
|
||||
/* system-specific stream handle from a given FreeType stream object */
|
||||
//#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer )
|
||||
#define STREAM_FILE( stream ) ( (BPTR)stream->descriptor.pointer ) // TetiSoft
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_close_stream */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The function to close a stream. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* stream :: A pointer to the stream object. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_close_stream( FT_Stream stream )
|
||||
{
|
||||
// fclose( STREAM_FILE( stream ) );
|
||||
Close( STREAM_FILE( stream ) ); // TetiSoft
|
||||
|
||||
stream->descriptor.pointer = NULL;
|
||||
stream->size = 0;
|
||||
stream->base = 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_io_stream */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The function to open a stream. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* stream :: A pointer to the stream object. */
|
||||
/* */
|
||||
/* offset :: The position in the data stream to start reading. */
|
||||
/* */
|
||||
/* buffer :: The address of buffer to store the read data. */
|
||||
/* */
|
||||
/* count :: The number of bytes to read from the stream. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The number of bytes actually read. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( unsigned long )
|
||||
ft_io_stream( FT_Stream stream,
|
||||
unsigned long offset,
|
||||
unsigned char* buffer,
|
||||
unsigned long count )
|
||||
{
|
||||
// FILE* file;
|
||||
BPTR file; // TetiSoft
|
||||
|
||||
|
||||
file = STREAM_FILE( stream );
|
||||
|
||||
// fseek( file, offset, SEEK_SET );
|
||||
Seek( file, offset, OFFSET_BEGINNING ); // TetiSoft
|
||||
|
||||
// return (unsigned long)fread( buffer, 1, count, file );
|
||||
return (unsigned long)FRead( file, buffer, 1, count);
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_New_Stream( const char* filepathname,
|
||||
FT_Stream astream )
|
||||
{
|
||||
// FILE* file;
|
||||
BPTR file; // TetiSoft
|
||||
struct FileInfoBlock *fib; // TetiSoft
|
||||
|
||||
|
||||
if ( !astream )
|
||||
return FT_Err_Invalid_Stream_Handle;
|
||||
|
||||
// file = fopen( filepathname, "rb" );
|
||||
file = Open( filepathname, MODE_OLDFILE ); // TetiSoft
|
||||
if ( !file )
|
||||
{
|
||||
FT_ERROR(( "FT_New_Stream:" ));
|
||||
FT_ERROR(( " could not open `%s'\n", filepathname ));
|
||||
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
}
|
||||
|
||||
// fseek( file, 0, SEEK_END );
|
||||
// astream->size = ftell( file );
|
||||
// fseek( file, 0, SEEK_SET );
|
||||
fib = AllocDosObject( DOS_FIB, NULL );
|
||||
if ( !fib )
|
||||
{
|
||||
Close ( file );
|
||||
FT_ERROR(( "FT_New_Stream:" ));
|
||||
FT_ERROR(( " could not open `%s'\n", filepathname ));
|
||||
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
}
|
||||
if (!( ExamineFH ( file, fib )))
|
||||
{
|
||||
FreeDosObject(DOS_FIB, fib);
|
||||
Close ( file );
|
||||
FT_ERROR(( "FT_New_Stream:" ));
|
||||
FT_ERROR(( " could not open `%s'\n", filepathname ));
|
||||
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
}
|
||||
astream->size = fib->fib_Size;
|
||||
FreeDosObject(DOS_FIB, fib);
|
||||
|
||||
// astream->descriptor.pointer = file;
|
||||
astream->descriptor.pointer = (void *)file;
|
||||
|
||||
astream->pathname.pointer = (char*)filepathname;
|
||||
astream->pos = 0;
|
||||
|
||||
astream->read = ft_io_stream;
|
||||
astream->close = ft_close_stream;
|
||||
|
||||
FT_TRACE1(( "FT_New_Stream:" ));
|
||||
FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
|
||||
filepathname, astream->size ));
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
|
||||
extern FT_Int
|
||||
ft_mem_debug_init( FT_Memory memory );
|
||||
|
||||
extern void
|
||||
ft_mem_debug_done( FT_Memory memory );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Memory )
|
||||
FT_New_Memory( void )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
// memory = (FT_Memory)malloc( sizeof ( *memory ) );
|
||||
memory = (FT_Memory)AllocVec( sizeof ( *memory ), MEMF_PUBLIC );
|
||||
if ( memory )
|
||||
{
|
||||
// memory->user = 0;
|
||||
#ifdef __GNUC__
|
||||
memory->user = CreatePool ( MEMF_PUBLIC, 2048, 2048 );
|
||||
#else
|
||||
memory->user = AsmCreatePool ( MEMF_PUBLIC, 2048, 2048, SysBase );
|
||||
#endif
|
||||
if ( memory->user == NULL )
|
||||
{
|
||||
FreeVec ( memory );
|
||||
memory = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
memory->alloc = ft_alloc;
|
||||
memory->realloc = ft_realloc;
|
||||
memory->free = ft_free;
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
ft_mem_debug_init( memory );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Done_Memory( FT_Memory memory )
|
||||
{
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
ft_mem_debug_done( memory );
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
DeletePool( memory->user );
|
||||
#else
|
||||
AsmDeletePool( memory->user, SysBase );
|
||||
#endif
|
||||
FreeVec( memory );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,155 +0,0 @@
|
|||
#
|
||||
# FreeType 2 host platform detection rules
|
||||
#
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
# This sub-Makefile is in charge of detecting the current platform. It sets
|
||||
# the following variables:
|
||||
#
|
||||
# BUILD The configuration and system-specific directory. Usually
|
||||
# `freetype/builds/$(PLATFORM)' but can be different for
|
||||
# custom builds of the library.
|
||||
#
|
||||
# The following variables must be defined in system specific `detect.mk'
|
||||
# files:
|
||||
#
|
||||
# PLATFORM The detected platform. This will default to `ansi' if
|
||||
# auto-detection fails.
|
||||
# CONFIG_FILE The configuration sub-makefile to use. This usually depends
|
||||
# on the compiler defined in the `CC' environment variable.
|
||||
# DELETE The shell command used to remove a given file.
|
||||
# COPY The shell command used to copy one file.
|
||||
# SEP The platform-specific directory separator.
|
||||
# CC The compiler to use.
|
||||
#
|
||||
# You need to set the following variable(s) before calling it:
|
||||
#
|
||||
# TOP The top-most directory in the FreeType library source
|
||||
# hierarchy. If not defined, it will default to `.'.
|
||||
|
||||
# If TOP is not defined, default it to `.'
|
||||
#
|
||||
ifndef TOP
|
||||
TOP := .
|
||||
endif
|
||||
|
||||
# Set auto-detection default to `ansi' resp. UNIX-like operating systems.
|
||||
# Note that we delay evaluation of $(BUILD_CONFIG_), $(BUILD), and
|
||||
# $(CONFIG_RULES).
|
||||
#
|
||||
PLATFORM := ansi
|
||||
DELETE := $(RM)
|
||||
COPY := cp
|
||||
SEP := /
|
||||
|
||||
BUILD_CONFIG_ = $(TOP)$(SEP)builds$(SEP)
|
||||
BUILD = $(BUILD_CONFIG_)$(PLATFORM)
|
||||
CONFIG_RULES = $(BUILD)$(SEP)$(CONFIG_FILE)
|
||||
|
||||
# We define the BACKSLASH variable to hold a single back-slash character.
|
||||
# This is needed because a line like
|
||||
#
|
||||
# SEP := \
|
||||
#
|
||||
# does not work with GNU Make (the backslash is interpreted as a line
|
||||
# continuation). While a line like
|
||||
#
|
||||
# SEP := \\
|
||||
#
|
||||
# really defines $(SEP) as `\' on Unix, and `\\' on Dos and Windows!
|
||||
#
|
||||
BACKSLASH := $(strip \ )
|
||||
|
||||
# Find all auto-detectable platforms.
|
||||
#
|
||||
PLATFORMS_ := $(notdir $(subst /detect.mk,,$(wildcard $(BUILD_CONFIG_)*/detect.mk)))
|
||||
.PHONY: $(PLATFORMS_) ansi
|
||||
|
||||
# Filter out platform specified as setup target.
|
||||
#
|
||||
PLATFORM := $(firstword $(filter $(MAKECMDGOALS),$(PLATFORMS_)))
|
||||
|
||||
# If no setup target platform was specified, enable auto-detection/
|
||||
# default platform.
|
||||
#
|
||||
ifeq ($(PLATFORM),)
|
||||
PLATFORM := ansi
|
||||
endif
|
||||
|
||||
# If the user has explicitly asked for `ansi' on the command line,
|
||||
# disable auto-detection.
|
||||
#
|
||||
ifeq ($(findstring ansi,$(MAKECMDGOALS)),)
|
||||
# Now, include all detection rule files found in the `builds/<system>'
|
||||
# directories. Note that the calling order of the various `detect.mk'
|
||||
# files isn't predictable.
|
||||
#
|
||||
include $(wildcard $(BUILD_CONFIG_)*/detect.mk)
|
||||
endif
|
||||
|
||||
# In case no detection rule file was successful, use the default.
|
||||
#
|
||||
ifndef CONFIG_FILE
|
||||
CONFIG_FILE := ansi.mk
|
||||
setup: std_setup
|
||||
.PHONY: setup
|
||||
endif
|
||||
|
||||
# The following targets are equivalent, with the exception that they use
|
||||
# a slightly different syntax for the `echo' command.
|
||||
#
|
||||
# std_setup: defined for most (i.e. Unix-like) platforms
|
||||
# dos_setup: defined for Dos-ish platforms like Dos, Windows & OS/2
|
||||
#
|
||||
.PHONY: std_setup dos_setup
|
||||
|
||||
std_setup:
|
||||
@echo ""
|
||||
@echo "$(PROJECT_TITLE) build system -- automatic system detection"
|
||||
@echo ""
|
||||
@echo "The following settings are used:"
|
||||
@echo ""
|
||||
@echo " platform $(PLATFORM)"
|
||||
@echo " compiler $(CC)"
|
||||
@echo " configuration directory $(BUILD)"
|
||||
@echo " configuration rules $(CONFIG_RULES)"
|
||||
@echo ""
|
||||
@echo "If this does not correspond to your system or settings please remove the file"
|
||||
@echo "\`$(CONFIG_MK)' from this directory then read the INSTALL file for help."
|
||||
@echo ""
|
||||
@echo "Otherwise, simply type \`make' again to build the library."
|
||||
@echo ""
|
||||
@$(COPY) $(CONFIG_RULES) $(CONFIG_MK)
|
||||
|
||||
|
||||
# Special case for Dos, Windows, OS/2, where echo "" doesn't work correctly!
|
||||
#
|
||||
dos_setup:
|
||||
@type builds\newline
|
||||
@echo $(PROJECT_TITLE) build system -- automatic system detection
|
||||
@type builds\newline
|
||||
@echo The following settings are used:
|
||||
@type builds\newline
|
||||
@echo platformÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$(PLATFORM)
|
||||
@echo compilerÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$(CC)
|
||||
@echo configuration directoryÿÿÿÿÿÿ$(BUILD)
|
||||
@echo configuration rulesÿÿÿÿÿÿÿÿÿÿ$(CONFIG_RULES)
|
||||
@type builds\newline
|
||||
@echo If this does not correspond to your system or settings please remove the file
|
||||
@echo '$(CONFIG_MK)' from this directory then read the INSTALL file for help.
|
||||
@type builds\newline
|
||||
@echo Otherwise, simply type 'make' again to build the library.
|
||||
@type builds\newline
|
||||
@$(COPY) $(subst /,\,$(CONFIG_RULES) $(CONFIG_MK)) > nul
|
||||
|
||||
# EOF
|
|
@ -1,304 +0,0 @@
|
|||
#
|
||||
# FreeType 2 library sub-Makefile
|
||||
#
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
# DO NOT INVOKE THIS MAKEFILE DIRECTLY! IT IS MEANT TO BE INCLUDED BY
|
||||
# OTHER MAKEFILES.
|
||||
|
||||
|
||||
# The following variables (set by other Makefile components, in the
|
||||
# environment, or on the command line) are used:
|
||||
#
|
||||
# BUILD The architecture dependent directory,
|
||||
# e.g. `$(TOP)/builds/unix'.
|
||||
#
|
||||
# OBJ_DIR The directory in which object files are created.
|
||||
#
|
||||
# LIB_DIR The directory in which the library is created.
|
||||
#
|
||||
# INCLUDES A list of directories to be included additionally.
|
||||
# Usually empty.
|
||||
#
|
||||
# CFLAGS Compilation flags. This overrides the default settings
|
||||
# in the platform-specific configuration files.
|
||||
#
|
||||
# FTSYS_SRC If set, its value is used as the name of a replacement
|
||||
# file for `src/base/ftsystem.c'.
|
||||
#
|
||||
# FTDEBUG_SRC If set, its value is used as the name of a replacement
|
||||
# file for `src/base/ftdebug.c'. [For a normal build, this
|
||||
# file does nothing.]
|
||||
#
|
||||
# FT_MODULE_LIST The file which contains the list of modules for the
|
||||
# current build. Usually, this is automatically created by
|
||||
# `modules.mk'.
|
||||
#
|
||||
# BASE_OBJ_S
|
||||
# BASE_OBJ_M A list of base objects (for single object and multiple
|
||||
# object builds, respectively). Set up in
|
||||
# `src/base/rules.mk'.
|
||||
#
|
||||
# BASE_EXT_OBJ A list of base extension objects. Set up in
|
||||
# `src/base/rules.mk'.
|
||||
#
|
||||
# DRV_OBJ_S
|
||||
# DRV_OBJ_M A list of driver objects (for single object and multiple
|
||||
# object builds, respectively). Set up cumulatively in
|
||||
# `src/<driver>/rules.mk'.
|
||||
#
|
||||
# CLEAN
|
||||
# DISTCLEAN The sub-makefiles can append additional stuff to these two
|
||||
# variables which is to be removed for the `clean' resp.
|
||||
# `distclean' target.
|
||||
#
|
||||
# TOP, SEP,
|
||||
# LIBRARY, CC,
|
||||
# A, I, O, T Check `config.mk' for details.
|
||||
|
||||
|
||||
# The targets `objects' and `library' are defined at the end of this
|
||||
# Makefile after all other rules have been included.
|
||||
#
|
||||
.PHONY: single multi objects library
|
||||
|
||||
# default target -- build single objects and library
|
||||
#
|
||||
single: objects library
|
||||
|
||||
# `multi' target -- build multiple objects and library
|
||||
#
|
||||
multi: objects library
|
||||
|
||||
|
||||
# The FreeType source directory, usually `./src'.
|
||||
#
|
||||
SRC := $(TOP)$(SEP)src
|
||||
|
||||
|
||||
# The directory where the base layer components are placed, usually
|
||||
# `./src/base'.
|
||||
#
|
||||
BASE_DIR := $(SRC)$(SEP)base
|
||||
|
||||
# The build header file used to define all public header file names
|
||||
# as macro.
|
||||
#
|
||||
ifndef FT_BUILD_H
|
||||
FT_BUILD_H := $(TOP)$(SEP)include$(SEP)ft2build.h
|
||||
FTBUILD_CMD :=
|
||||
else
|
||||
FTBUILD_CMD = $(D)FT_BUILD_H=$(FT_BUILD_H)
|
||||
endif
|
||||
|
||||
# A few short-cuts in order to avoid typing $(SEP) all the time for the
|
||||
# directory separator.
|
||||
#
|
||||
# For example: $(SRC_) equals to `./src/' where `.' is $(TOP).
|
||||
#
|
||||
#
|
||||
SRC_ := $(SRC)$(SEP)
|
||||
BASE_ := $(BASE_DIR)$(SEP)
|
||||
OBJ_ := $(OBJ_DIR)$(SEP)
|
||||
LIB_ := $(LIB_DIR)$(SEP)
|
||||
PUBLIC_ := $(TOP)$(SEP)include$(SEP)freetype$(SEP)
|
||||
INTERNAL_ := $(PUBLIC_)internal$(SEP)
|
||||
CONFIG_ := $(PUBLIC_)config$(SEP)
|
||||
CACHE_ := $(PUBLIC_)cache$(SEP)
|
||||
|
||||
|
||||
# The final name of the library file.
|
||||
#
|
||||
PROJECT_LIBRARY := $(LIB_)$(LIBRARY).$A
|
||||
|
||||
|
||||
# include paths
|
||||
#
|
||||
# IMPORTANT NOTE: The architecture-dependent directory must ALWAYS be placed
|
||||
# in front of the include list. Porters are then able to
|
||||
# put their own version of some of the FreeType components
|
||||
# in the `freetype/builds/<system>' directory, as these
|
||||
# files will override the default sources.
|
||||
#
|
||||
INCLUDES := $(BUILD) $(TOP)$(SEP)include
|
||||
|
||||
INCLUDE_FLAGS = $(INCLUDES:%=$I%)
|
||||
|
||||
|
||||
# C flags used for the compilation of an object file. This must include at
|
||||
# least the paths for the `base' and `builds/<system>' directories;
|
||||
# debug/optimization/warning flags + ansi compliance if needed.
|
||||
#
|
||||
FT_CFLAGS = $(CFLAGS) $(INCLUDE_FLAGS)
|
||||
FT_CC = $(CC) $(FT_CFLAGS)
|
||||
FT_COMPILE = $(CC) $(ANSIFLAGS) $(FT_CFLAGS)
|
||||
|
||||
|
||||
# Include the `modules' rules file.
|
||||
#
|
||||
include $(TOP)/builds/modules.mk
|
||||
|
||||
|
||||
# Initialize the list of objects.
|
||||
#
|
||||
OBJECTS_LIST :=
|
||||
|
||||
|
||||
# Define $(PUBLIC_H) as the list of all public header files located in
|
||||
# `$(TOP)/include/freetype'. $(BASE_H), $(CACHE_H), and $(CONFIG_H) are
|
||||
# defined similarly.
|
||||
#
|
||||
# This is used to simplify the dependency rules -- if one of these files
|
||||
# changes, the whole library is recompiled.
|
||||
#
|
||||
PUBLIC_H := $(wildcard $(PUBLIC_)*.h)
|
||||
BASE_H := $(wildcard $(INTERNAL_)*.h)
|
||||
CONFIG_H := $(wildcard $(CONFIG_)*.h) \
|
||||
$(wildcard $(BUILD)$(SEP)freetype$(SEP)config$(SEP)*.h)
|
||||
CACHE_H := $(wildcard $(CACHE_)*.h)
|
||||
|
||||
FREETYPE_H := $(PUBLIC_H) $(BASE_H) $(CONFIG_H) $(CACHE_H)
|
||||
|
||||
|
||||
# ftsystem component
|
||||
#
|
||||
ifndef FTSYS_SRC
|
||||
FTSYS_SRC = $(BASE_)ftsystem.c
|
||||
endif
|
||||
|
||||
FTSYS_OBJ = $(OBJ_)ftsystem.$O
|
||||
|
||||
OBJECTS_LIST += $(FTSYS_OBJ)
|
||||
|
||||
$(FTSYS_OBJ): $(FTSYS_SRC) $(FREETYPE_H)
|
||||
$(FT_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
# ftdebug component
|
||||
#
|
||||
ifndef FTDEBUG_SRC
|
||||
FTDEBUG_SRC = $(BASE_)ftdebug.c
|
||||
endif
|
||||
|
||||
FTDEBUG_OBJ = $(OBJ_)ftdebug.$O
|
||||
|
||||
OBJECTS_LIST += $(FTDEBUG_OBJ)
|
||||
|
||||
$(FTDEBUG_OBJ): $(FTDEBUG_SRC) $(FREETYPE_H)
|
||||
$(FT_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
# Include all rule files from FreeType components.
|
||||
#
|
||||
include $(wildcard $(SRC)/*/rules.mk)
|
||||
|
||||
|
||||
# ftinit component
|
||||
#
|
||||
# The C source `ftinit.c' contains the FreeType initialization routines.
|
||||
# It is able to automatically register one or more drivers when the API
|
||||
# function FT_Init_FreeType() is called.
|
||||
#
|
||||
# The set of initial drivers is determined by the driver Makefiles
|
||||
# includes above. Each driver Makefile updates the FTINIT_xxx lists
|
||||
# which contain additional include paths and macros used to compile the
|
||||
# single `ftinit.c' source.
|
||||
#
|
||||
FTINIT_SRC := $(BASE_)ftinit.c
|
||||
FTINIT_OBJ := $(OBJ_)ftinit.$O
|
||||
|
||||
OBJECTS_LIST += $(FTINIT_OBJ)
|
||||
|
||||
$(FTINIT_OBJ): $(FTINIT_SRC) $(FREETYPE_H) $(FT_MODULE_LIST)
|
||||
$(FT_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
# All FreeType library objects
|
||||
#
|
||||
# By default, we include the base layer extensions. These could be
|
||||
# omitted on builds which do not want them.
|
||||
#
|
||||
OBJ_M = $(BASE_OBJ_M) $(BASE_EXT_OBJ) $(DRV_OBJS_M)
|
||||
OBJ_S = $(BASE_OBJ_S) $(BASE_EXT_OBJ) $(DRV_OBJS_S)
|
||||
|
||||
|
||||
# The target `multi' on the Make command line indicates that we want to
|
||||
# compile each source file independently.
|
||||
#
|
||||
# Otherwise, each module/driver is compiled in a single object file through
|
||||
# source file inclusion (see `src/base/ftbase.c' or
|
||||
# `src/truetype/truetype.c' for examples).
|
||||
#
|
||||
BASE_OBJECTS := $(OBJECTS_LIST)
|
||||
|
||||
ifneq ($(findstring multi,$(MAKECMDGOALS)),)
|
||||
OBJECTS_LIST += $(OBJ_M)
|
||||
else
|
||||
OBJECTS_LIST += $(OBJ_S)
|
||||
endif
|
||||
|
||||
objects: $(OBJECTS_LIST)
|
||||
|
||||
library: $(PROJECT_LIBRARY)
|
||||
|
||||
.c.$O:
|
||||
$(FT_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
.PHONY: clean_project_std distclean_project_std
|
||||
|
||||
# Standard cleaning and distclean rules. These are not accepted
|
||||
# on all systems though.
|
||||
#
|
||||
clean_project_std:
|
||||
-$(DELETE) $(BASE_OBJECTS) $(OBJ_M) $(OBJ_S) $(CLEAN)
|
||||
|
||||
distclean_project_std: clean_project_std
|
||||
-$(DELETE) $(PROJECT_LIBRARY)
|
||||
-$(DELETE) *.orig *~ core *.core $(DISTCLEAN)
|
||||
|
||||
|
||||
.PHONY: clean_project_dos distclean_project_dos
|
||||
|
||||
# The Dos command shell does not support very long list of arguments, so
|
||||
# we are stuck with wildcards.
|
||||
#
|
||||
# Don't break the command lines with; this prevents the "del" command from
|
||||
# working correctly on Win9x.
|
||||
#
|
||||
clean_project_dos:
|
||||
-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(OBJ_))*.$O $(CLEAN) $(NO_OUTPUT)
|
||||
|
||||
distclean_project_dos: clean_project_dos
|
||||
-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) $(DISTCLEAN) $(NO_OUTPUT)
|
||||
|
||||
|
||||
.PHONY: remove_config_mk
|
||||
|
||||
# Remove configuration file (used for distclean).
|
||||
#
|
||||
remove_config_mk:
|
||||
-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(CONFIG_MK)) $(NO_OUTPUT)
|
||||
|
||||
|
||||
.PHONY: clean distclean
|
||||
|
||||
# The `config.mk' file must define `clean_freetype' and
|
||||
# `distclean_freetype'. Implementations may use to relay these to either
|
||||
# the `std' or `dos' versions from above, or simply provide their own
|
||||
# implementation.
|
||||
#
|
||||
clean: clean_project
|
||||
distclean: distclean_project remove_config_mk
|
||||
|
||||
# EOF
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,96 +0,0 @@
|
|||
dnl This file is part of the FreeType project.
|
||||
dnl
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl
|
||||
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([ftconfig.in])
|
||||
|
||||
dnl configuration file -- stay in 8.3 limit
|
||||
AC_CONFIG_HEADER(ftconfig.h:ftconfig.in)
|
||||
|
||||
version_info='8:0:2'
|
||||
AC_SUBST(version_info)
|
||||
ft_version=`echo $version_info | tr : .`
|
||||
AC_SUBST(ft_version)
|
||||
|
||||
dnl checks for system type
|
||||
AC_CANONICAL_TARGET([])
|
||||
|
||||
dnl checks for programs
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
|
||||
dnl get Compiler flags right.
|
||||
if test "x$CC" = xgcc; then
|
||||
XX_CFLAGS="-Wall"
|
||||
XX_ANSIFLAGS="-pedantic -ansi"
|
||||
else
|
||||
case "$host" in
|
||||
*-dec-osf*)
|
||||
CFLAGS=
|
||||
XX_CFLAGS="-std1 -g3"
|
||||
XX_ANSIFLAGS=
|
||||
;;
|
||||
*)
|
||||
XX_CFLAGS=
|
||||
XX_ANSIFLAGS=
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AC_SUBST(XX_CFLAGS)
|
||||
AC_SUBST(XX_ANSIFLAGS)
|
||||
|
||||
AC_CHECK_PROG(RMF, rm, rm -f)
|
||||
AC_CHECK_PROG(RMDIR, rmdir, rmdir)
|
||||
|
||||
dnl Since this file will be finally moved to another directory we make
|
||||
dnl the path of the install script absolute. This small code snippet has
|
||||
dnl been taken from automake's `ylwrap' script.
|
||||
AC_PROG_INSTALL
|
||||
case "$INSTALL" in
|
||||
/*)
|
||||
;;
|
||||
*/*)
|
||||
INSTALL="`pwd`/$INSTALL" ;;
|
||||
esac
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(fcntl.h unistd.h)
|
||||
|
||||
dnl checks for typedefs, structures, and compiler characteristics
|
||||
AC_C_CONST
|
||||
AC_CHECK_SIZEOF(int)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
|
||||
dnl checks for library functions
|
||||
|
||||
dnl Here we check whether we can use our mmap file component.
|
||||
AC_FUNC_MMAP
|
||||
if test "$ac_cv_func_mmap_fixed_mapped" != yes; then
|
||||
FTSYS_SRC='$(BASE_)ftsystem.c'
|
||||
else
|
||||
FTSYS_SRC='$(BUILD)/ftsystem.c'
|
||||
|
||||
FT_MUNMAP_DECL
|
||||
FT_MUNMAP_PARAM
|
||||
fi
|
||||
AC_SUBST(FTSYS_SRC)
|
||||
|
||||
AC_CHECK_FUNCS(memcpy memmove)
|
||||
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
dnl create the Unix-specific sub-Makefiles `builds/unix/unix-def.mk'
|
||||
dnl and 'builds/unix/unix-cc.mk' that will be used by the build system
|
||||
dnl
|
||||
AC_CONFIG_FILES([unix-cc.mk:unix-cc.in unix-def.mk:unix-def.in freetype-config])
|
||||
|
||||
dnl re-generate the Jamfile to use libtool now
|
||||
dnl
|
||||
AC_CONFIG_FILE([../../Jamfile:../../Jamfile.in])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
dnl end of configure.ac
|
|
@ -1,261 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftconfig.in */
|
||||
/* */
|
||||
/* UNIX-specific configuration file (specification only). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* This header file contains a number of macro definitions that are used */
|
||||
/* by the rest of the engine. Most of the macros here are automatically */
|
||||
/* determined at compile time, and you should not need to change it to */
|
||||
/* port FreeType, except to compile the library with a non-ANSI */
|
||||
/* compiler. */
|
||||
/* */
|
||||
/* Note however that if some specific modifications are needed, we */
|
||||
/* advise you to place a modified copy in your build directory. */
|
||||
/* */
|
||||
/* The build directory is usually `freetype/builds/<system>', and */
|
||||
/* contains system-specific files that are always included first when */
|
||||
/* building the library. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#ifndef __FTCONFIG_H__
|
||||
#define __FTCONFIG_H__
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CONFIG_OPTIONS_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* PLATFORM-SPECIFIC CONFIGURATION MACROS */
|
||||
/* */
|
||||
/* These macros can be toggled to suit a specific system. The current */
|
||||
/* ones are defaults used to compile FreeType in an ANSI C environment */
|
||||
/* (16bit compilers are also supported). Copy this file to your own */
|
||||
/* `freetype/builds/<system>' directory, and edit it to port the engine. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#define HAVE_UNISTD_H 0
|
||||
#define HAVE_FCNTL_H 0
|
||||
|
||||
#define SIZEOF_INT 2
|
||||
#define SIZEOF_LONG 2
|
||||
|
||||
|
||||
#define FT_SIZEOF_INT SIZEOF_INT
|
||||
#define FT_SIZEOF_LONG SIZEOF_LONG
|
||||
|
||||
|
||||
/* Preferred alignment of data */
|
||||
#define FT_ALIGNMENT 8
|
||||
|
||||
|
||||
/* UNUSED is a macro used to indicate that a given parameter is not used */
|
||||
/* -- this is only used to get rid of unpleasant compiler warnings */
|
||||
#ifndef FT_UNUSED
|
||||
#define FT_UNUSED( arg ) ( (arg) = (arg) )
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* AUTOMATIC CONFIGURATION MACROS */
|
||||
/* */
|
||||
/* These macros are computed from the ones defined above. Don't touch */
|
||||
/* their definition, unless you know precisely what you are doing. No */
|
||||
/* porter should need to mess with them. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* IntN types */
|
||||
/* */
|
||||
/* Used to guarantee the size of some specific integers. */
|
||||
/* */
|
||||
typedef signed short FT_Int16;
|
||||
typedef unsigned short FT_UInt16;
|
||||
|
||||
#if FT_SIZEOF_INT == 4
|
||||
|
||||
typedef signed int FT_Int32;
|
||||
typedef unsigned int FT_UInt32;
|
||||
|
||||
#elif FT_SIZEOF_LONG == 4
|
||||
|
||||
typedef signed long FT_Int32;
|
||||
typedef unsigned long FT_UInt32;
|
||||
|
||||
#else
|
||||
#error "no 32bit type found -- please check your configuration files"
|
||||
#endif
|
||||
|
||||
#if FT_SIZEOF_LONG == 8
|
||||
|
||||
/* FT_LONG64 must be defined if a 64-bit type is available */
|
||||
#define FT_LONG64
|
||||
#define FT_INT64 long
|
||||
|
||||
#else
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Many compilers provide the non-ANSI `long long' 64-bit type. You can */
|
||||
/* activate it by defining the FTCALC_USE_LONG_LONG macro in */
|
||||
/* `ftoption.h'. */
|
||||
/* */
|
||||
/* Note that this will produce many -ansi warnings during library */
|
||||
/* compilation, and that in many cases, the generated code will be */
|
||||
/* neither smaller nor faster! */
|
||||
/* */
|
||||
#ifdef FTCALC_USE_LONG_LONG
|
||||
|
||||
#define FT_LONG64
|
||||
#define FT_INT64 long long
|
||||
|
||||
#endif /* FTCALC_USE_LONG_LONG */
|
||||
#endif /* FT_SIZEOF_LONG == 8 */
|
||||
|
||||
|
||||
#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#define FT_LOCAL static
|
||||
#define FT_LOCAL_DEF static
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define FT_LOCAL extern "C"
|
||||
#define FT_LOCAL_DEF extern "C"
|
||||
#else
|
||||
#define FT_LOCAL extern
|
||||
#define FT_LOCAL_DEF extern
|
||||
#endif
|
||||
|
||||
#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */
|
||||
|
||||
|
||||
#ifndef FT_BASE
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define FT_BASE( x ) extern "C" x
|
||||
#else
|
||||
#define FT_BASE( x ) extern x
|
||||
#endif
|
||||
|
||||
#endif /* !FT_BASE */
|
||||
|
||||
|
||||
#ifndef FT_BASE_DEF
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define FT_BASE_DEF( x ) extern "C" x
|
||||
#else
|
||||
#define FT_BASE_DEF( x ) extern x
|
||||
#endif
|
||||
|
||||
#endif /* !FT_BASE_DEF */
|
||||
|
||||
|
||||
#ifndef FT_EXPORT
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define FT_EXPORT( x ) extern "C" x
|
||||
#else
|
||||
#define FT_EXPORT( x ) extern x
|
||||
#endif
|
||||
|
||||
#endif /* !FT_EXPORT */
|
||||
|
||||
|
||||
#ifndef FT_EXPORT_DEF
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define FT_EXPORT_DEF( x ) extern "C" x
|
||||
#else
|
||||
#define FT_EXPORT_DEF( x ) extern x
|
||||
#endif
|
||||
|
||||
#endif /* !FT_EXPORT_DEF */
|
||||
|
||||
|
||||
#ifndef FT_EXPORT_VAR
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define FT_EXPORT_VAR( x ) extern "C" x
|
||||
#else
|
||||
#define FT_EXPORT_VAR( x ) extern x
|
||||
#endif
|
||||
|
||||
#endif /* !FT_EXPORT_VAR */
|
||||
|
||||
/* The following macros are needed to compile the library with a */
|
||||
/* C++ compiler and with 16bit compilers. */
|
||||
/* */
|
||||
|
||||
/* This is special. Within C++, you must specify `extern "C"' for */
|
||||
/* functions which are used via function pointers, and you also */
|
||||
/* must do that for structures which contain function pointers to */
|
||||
/* assure C linkage -- it's not possible to have (local) anonymous */
|
||||
/* functions which are accessed by (global) function pointers. */
|
||||
/* */
|
||||
/* */
|
||||
/* FT_CALLBACK_DEF is used to _define_ a callback function. */
|
||||
/* */
|
||||
/* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */
|
||||
/* contains pointers to callback functions. */
|
||||
/* */
|
||||
/* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */
|
||||
/* that contains pointers to callback functions. */
|
||||
/* */
|
||||
/* */
|
||||
/* Some 16bit compilers have to redefine these macros to insert */
|
||||
/* the infamous `_cdecl' or `__fastcall' declarations. */
|
||||
/* */
|
||||
#ifndef FT_CALLBACK_DEF
|
||||
#ifdef __cplusplus
|
||||
#define FT_CALLBACK_DEF( x ) extern "C" x
|
||||
#else
|
||||
#define FT_CALLBACK_DEF( x ) static x
|
||||
#endif
|
||||
#endif /* FT_CALLBACK_DEF */
|
||||
|
||||
#ifndef FT_CALLBACK_TABLE
|
||||
#ifdef __cplusplus
|
||||
#define FT_CALLBACK_TABLE extern "C"
|
||||
#define FT_CALLBACK_TABLE_DEF extern "C"
|
||||
#else
|
||||
#define FT_CALLBACK_TABLE extern
|
||||
#define FT_CALLBACK_TABLE_DEF /* nothing */
|
||||
#endif
|
||||
#endif /* FT_CALLBACK_TABLE */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __FTCONFIG_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,334 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftsystem.c */
|
||||
/* */
|
||||
/* Unix-specific FreeType low-level system interface (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
/* we use our special ftconfig.h file, not the standard one */
|
||||
#include <ftconfig.h>
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_SYSTEM_H
|
||||
#include FT_ERRORS_H
|
||||
#include FT_TYPES_H
|
||||
#include FT_INTERNAL_OBJECTS_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
|
||||
|
||||
#ifdef MUNMAP_USES_VOIDP
|
||||
#define MUNMAP_ARG_CAST void *
|
||||
#else
|
||||
#define MUNMAP_ARG_CAST char *
|
||||
#endif
|
||||
|
||||
#ifdef NEED_MUNMAP_DECL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#else
|
||||
extern
|
||||
#endif
|
||||
int
|
||||
munmap( char* addr,
|
||||
int len );
|
||||
|
||||
#define MUNMAP_ARG_CAST char *
|
||||
|
||||
#endif /* NEED_DECLARATION_MUNMAP */
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* MEMORY MANAGEMENT INTERFACE */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_alloc */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory allocation function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* size :: The requested size in bytes. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of newly allocated block. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void* )
|
||||
ft_alloc( FT_Memory memory,
|
||||
long size )
|
||||
{
|
||||
FT_UNUSED( memory );
|
||||
|
||||
return malloc( size );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_realloc */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory reallocation function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* cur_size :: The current size of the allocated memory block. */
|
||||
/* */
|
||||
/* new_size :: The newly requested size in bytes. */
|
||||
/* */
|
||||
/* block :: The current address of the block in memory. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of the reallocated memory block. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void* )
|
||||
ft_realloc( FT_Memory memory,
|
||||
long cur_size,
|
||||
long new_size,
|
||||
void* block )
|
||||
{
|
||||
FT_UNUSED( memory );
|
||||
FT_UNUSED( cur_size );
|
||||
|
||||
return realloc( block, new_size );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_free */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory release function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* block :: The address of block in memory to be freed. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_free( FT_Memory memory,
|
||||
void* block )
|
||||
{
|
||||
FT_UNUSED( memory );
|
||||
|
||||
free( block );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* RESOURCE MANAGEMENT INTERFACE */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_io
|
||||
|
||||
/* We use the macro STREAM_FILE for convenience to extract the */
|
||||
/* system-specific stream handle from a given FreeType stream object */
|
||||
#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_close_stream */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The function to close a stream. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* stream :: A pointer to the stream object. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_close_stream( FT_Stream stream )
|
||||
{
|
||||
munmap( (MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size );
|
||||
|
||||
stream->descriptor.pointer = NULL;
|
||||
stream->size = 0;
|
||||
stream->base = 0;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_New_Stream( const char* filepathname,
|
||||
FT_Stream stream )
|
||||
{
|
||||
int file;
|
||||
struct stat stat_buf;
|
||||
|
||||
|
||||
if ( !stream )
|
||||
return FT_Err_Invalid_Stream_Handle;
|
||||
|
||||
/* open the file */
|
||||
file = open( filepathname, O_RDONLY );
|
||||
if ( file < 0 )
|
||||
{
|
||||
FT_ERROR(( "FT_New_Stream:" ));
|
||||
FT_ERROR(( " could not open `%s'\n", filepathname ));
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
}
|
||||
|
||||
/* Here we ensure that a "fork" will _not_ duplicate */
|
||||
/* our opened input streams on Unix. This is critical */
|
||||
/* since it avoids some (possible) access control */
|
||||
/* issues and cleans up the kernel file table a bit. */
|
||||
/* */
|
||||
#ifdef F_SETFD
|
||||
#ifdef FD_CLOEXEC
|
||||
(void) fcntl( file, F_SETFD, FD_CLOEXEC );
|
||||
#else
|
||||
(void) fcntl( file, F_SETFD, 1 );
|
||||
#endif /* FD_CLOEXEC */
|
||||
#endif /* F_SETFD */
|
||||
|
||||
if ( fstat( file, &stat_buf ) < 0 )
|
||||
{
|
||||
FT_ERROR(( "FT_New_Stream:" ));
|
||||
FT_ERROR(( " could not `fstat' file `%s'\n", filepathname ));
|
||||
goto Fail_Map;
|
||||
}
|
||||
|
||||
stream->size = stat_buf.st_size;
|
||||
stream->pos = 0;
|
||||
stream->base = (unsigned char *)mmap( NULL,
|
||||
stream->size,
|
||||
PROT_READ,
|
||||
MAP_FILE | MAP_PRIVATE,
|
||||
file,
|
||||
0 );
|
||||
|
||||
if ( (long)stream->base == -1 )
|
||||
{
|
||||
FT_ERROR(( "FT_New_Stream:" ));
|
||||
FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
|
||||
goto Fail_Map;
|
||||
}
|
||||
|
||||
close( file );
|
||||
|
||||
stream->descriptor.pointer = stream->base;
|
||||
stream->pathname.pointer = (char*)filepathname;
|
||||
|
||||
stream->close = ft_close_stream;
|
||||
stream->read = 0;
|
||||
|
||||
FT_TRACE1(( "FT_New_Stream:" ));
|
||||
FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
|
||||
filepathname, stream->size ));
|
||||
|
||||
return FT_Err_Ok;
|
||||
|
||||
Fail_Map:
|
||||
close( file );
|
||||
|
||||
stream->base = NULL;
|
||||
stream->size = 0;
|
||||
stream->pos = 0;
|
||||
|
||||
return FT_Err_Cannot_Open_Stream;
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
|
||||
extern FT_Int
|
||||
ft_mem_debug_init( FT_Memory memory );
|
||||
|
||||
extern void
|
||||
ft_mem_debug_done( FT_Memory memory );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Memory )
|
||||
FT_New_Memory( void )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
memory = (FT_Memory)malloc( sizeof ( *memory ) );
|
||||
if ( memory )
|
||||
{
|
||||
memory->user = 0;
|
||||
memory->alloc = ft_alloc;
|
||||
memory->realloc = ft_realloc;
|
||||
memory->free = ft_free;
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
ft_mem_debug_init( memory );
|
||||
#endif
|
||||
}
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Done_Memory( FT_Memory memory )
|
||||
{
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
ft_mem_debug_done( memory );
|
||||
#endif
|
||||
memory->free( memory, memory );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,73 +0,0 @@
|
|||
#
|
||||
# FreeType 2 installation instructions for Unix systems
|
||||
#
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
.PHONY: install uninstall
|
||||
|
||||
# Unix installation and deinstallation targets.
|
||||
install: $(PROJECT_LIBRARY)
|
||||
$(MKINSTALLDIRS) $(libdir) \
|
||||
$(includedir)/freetype2/freetype/config \
|
||||
$(includedir)/freetype2/freetype/internal \
|
||||
$(includedir)/freetype2/freetype/cache \
|
||||
$(bindir)
|
||||
$(LIBTOOL) --mode=install $(INSTALL) $(PROJECT_LIBRARY) $(libdir)
|
||||
-for P in $(PUBLIC_H) ; do \
|
||||
$(INSTALL_DATA) $$P $(includedir)/freetype2/freetype ; \
|
||||
done
|
||||
-for P in $(BASE_H) ; do \
|
||||
$(INSTALL_DATA) $$P $(includedir)/freetype2/freetype/internal ; \
|
||||
done
|
||||
-for P in $(CONFIG_H) ; do \
|
||||
$(INSTALL_DATA) $$P $(includedir)/freetype2/freetype/config ; \
|
||||
done
|
||||
-for P in $(CACHE_H) ; do \
|
||||
$(INSTALL_DATA) $$P $(includedir)/freetype2/freetype/cache ; \
|
||||
done
|
||||
$(INSTALL_DATA) $(BUILD)/ft2unix.h $(includedir)/ft2build.h
|
||||
$(INSTALL_SCRIPT) -m 755 $(BUILD)/freetype-config \
|
||||
$(bindir)/freetype-config
|
||||
|
||||
|
||||
uninstall:
|
||||
-$(LIBTOOL) --mode=uninstall $(RM) $(libdir)/$(LIBRARY).$A
|
||||
-$(DELETE) $(includedir)/freetype2/freetype/cache/*
|
||||
-$(DELDIR) $(includedir)/freetype2/freetype/cache
|
||||
-$(DELETE) $(includedir)/freetype2/freetype/config/*
|
||||
-$(DELDIR) $(includedir)/freetype2/freetype/config
|
||||
-$(DELETE) $(includedir)/freetype2/freetype/internal/*
|
||||
-$(DELDIR) $(includedir)/freetype2/freetype/internal
|
||||
-$(DELETE) $(includedir)/freetype2/freetype/*
|
||||
-$(DELDIR) $(includedir)/freetype2/freetype
|
||||
-$(DELDIR) $(includedir)/freetype2
|
||||
-$(DELETE) $(includedir)/ft2build.h
|
||||
-$(DELETE) $(bindir)/freetype-config
|
||||
|
||||
|
||||
.PHONY: clean_project_unix distclean_project_unix
|
||||
|
||||
# Unix cleaning and distclean rules.
|
||||
#
|
||||
clean_project_unix:
|
||||
-$(DELETE) $(BASE_OBJECTS) $(OBJ_M) $(OBJ_S)
|
||||
-$(DELETE) $(patsubst %.$O,%.$(SO),$(BASE_OBJECTS) $(OBJ_M) $(OBJ_S)) \
|
||||
$(CLEAN)
|
||||
|
||||
distclean_project_unix: clean_project_unix
|
||||
-$(DELETE) $(PROJECT_LIBRARY)
|
||||
-$(DELETE) $(OBJ_DIR)/.libs/*
|
||||
-$(DELDIR) $(OBJ_DIR)/.libs
|
||||
-$(DELETE) *.orig *~ core *.core $(DISTCLEAN)
|
||||
|
||||
# EOF
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,238 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftconfig.h */
|
||||
/* */
|
||||
/* VMS-specific configuration file (specification only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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 header file contains a number of macro definitions that are used */
|
||||
/* by the rest of the engine. Most of the macros here are automatically */
|
||||
/* determined at compile time, and you should not need to change it to */
|
||||
/* port FreeType, except to compile the library with a non-ANSI */
|
||||
/* compiler. */
|
||||
/* */
|
||||
/* Note however that if some specific modifications are needed, we */
|
||||
/* advise you to place a modified copy in your build directory. */
|
||||
/* */
|
||||
/* The build directory is usually `freetype/builds/<system>', and */
|
||||
/* contains system-specific files that are always included first when */
|
||||
/* building the library. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#ifndef FTCONFIG_H
|
||||
#define FTCONFIG_H
|
||||
|
||||
|
||||
/* Include the header file containing all developer build options */
|
||||
#include <ft2build.h>
|
||||
#include FT_CONFIG_OPTIONS_H
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* PLATFORM-SPECIFIC CONFIGURATION MACROS */
|
||||
/* */
|
||||
/* These macros can be toggled to suit a specific system. The current */
|
||||
/* ones are defaults used to compile FreeType in an ANSI C environment */
|
||||
/* (16bit compilers are also supported). Copy this file to your own */
|
||||
/* `freetype/builds/<system>' directory, and edit it to port the engine. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
#define SIZEOF_LONG 4
|
||||
|
||||
|
||||
#define FT_SIZEOF_INT 4
|
||||
#define FT_SIZEOF_LONG 4
|
||||
|
||||
|
||||
/* Preferred alignment of data */
|
||||
#define FT_ALIGNMENT 8
|
||||
|
||||
|
||||
/* UNUSED is a macro used to indicate that a given parameter is not used */
|
||||
/* -- this is only used to get rid of unpleasant compiler warnings */
|
||||
#ifndef FT_UNUSED
|
||||
#define FT_UNUSED( arg ) ( (arg) = (arg) )
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* AUTOMATIC CONFIGURATION MACROS */
|
||||
/* */
|
||||
/* These macros are computed from the ones defined above. Don't touch */
|
||||
/* their definition, unless you know precisely what you are doing. No */
|
||||
/* porter should need to mess with them. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* IntN types */
|
||||
/* */
|
||||
/* Used to guarantee the size of some specific integers. */
|
||||
/* */
|
||||
typedef signed short FT_Int16;
|
||||
typedef unsigned short FT_UInt16;
|
||||
|
||||
#if FT_SIZEOF_INT == 4
|
||||
|
||||
typedef signed int FT_Int32;
|
||||
typedef unsigned int FT_UInt32;
|
||||
|
||||
#elif FT_SIZEOF_LONG == 4
|
||||
|
||||
typedef signed long FT_Int32;
|
||||
typedef unsigned long FT_UInt32;
|
||||
|
||||
#else
|
||||
#error "no 32bit type found -- please check your configuration files"
|
||||
#endif
|
||||
|
||||
#if FT_SIZEOF_LONG == 8
|
||||
|
||||
/* FT_LONG64 must be defined if a 64-bit type is available */
|
||||
#define FT_LONG64
|
||||
#define FT_INT64 long
|
||||
|
||||
#else
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Many compilers provide the non-ANSI `long long' 64-bit type. You can */
|
||||
/* activate it by defining the FTCALC_USE_LONG_LONG macro in */
|
||||
/* `ftoption.h'. */
|
||||
/* */
|
||||
/* Note that this will produce many -ansi warnings during library */
|
||||
/* compilation, and that in many cases, the generated code will be */
|
||||
/* neither smaller nor faster! */
|
||||
/* */
|
||||
#ifdef FTCALC_USE_LONG_LONG
|
||||
|
||||
#define FT_LONG64
|
||||
#define FT_INT64 long long
|
||||
|
||||
#endif /* FTCALC_USE_LONG_LONG */
|
||||
#endif /* FT_SIZEOF_LONG == 8 */
|
||||
|
||||
|
||||
#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#define LOCAL_DEF static
|
||||
#define LOCAL_FUNC static
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define LOCAL_DEF extern "C"
|
||||
#define LOCAL_FUNC extern "C"
|
||||
#else
|
||||
#define LOCAL_DEF extern
|
||||
#define LOCAL_FUNC extern
|
||||
#endif
|
||||
|
||||
#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */
|
||||
|
||||
#ifndef FT_BASE
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define FT_BASE( x ) extern "C" x
|
||||
#else
|
||||
#define FT_BASE( x ) extern x
|
||||
#endif
|
||||
|
||||
#endif /* !FT_BASE */
|
||||
|
||||
#ifndef BASE_DEF
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define BASE_DEF( x ) extern "C" x
|
||||
#else
|
||||
#define BASE_DEF( x ) extern x
|
||||
#endif
|
||||
|
||||
#endif /* !BASE_DEF */
|
||||
|
||||
|
||||
#ifndef FT_EXPORT
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define FT_EXPORT( x ) extern "C" x
|
||||
#else
|
||||
#define FT_EXPORT( x ) extern x
|
||||
#endif
|
||||
|
||||
#endif /* !FT_EXPORT */
|
||||
|
||||
#ifndef FT_EXPORT_DEF
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define FT_EXPORT_DEF( x ) extern "C" x
|
||||
#else
|
||||
#define FT_EXPORT_DEF( x ) extern x
|
||||
#endif
|
||||
|
||||
#endif /* !FT_EXPORT_DEF */
|
||||
|
||||
|
||||
#ifndef FT_EXPORT_VAR
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define FT_EXPORT_VAR( x ) extern "C" x
|
||||
#else
|
||||
#define FT_EXPORT_VAR( x ) extern x
|
||||
#endif
|
||||
|
||||
#endif /* !FT_EXPORT_VAR */
|
||||
|
||||
|
||||
/* This is special. Within C++, you must specify `extern "C"' for */
|
||||
/* functions which are used via function pointers, and you also */
|
||||
/* must do that for structures which contain function pointers to */
|
||||
/* assure C linkage -- it's not possible to have (local) anonymous */
|
||||
/* functions which are accessed by (global) function pointers. */
|
||||
/* */
|
||||
#ifdef __cplusplus
|
||||
|
||||
#define FT_CALLBACK_DEF( x ) extern "C" x
|
||||
#define FT_CALLBACK_TABLE extern "C"
|
||||
#define FT_CALLBACK_TABLE_DEF extern "C"
|
||||
|
||||
#else
|
||||
|
||||
#define FT_CALLBACK_DEF( x ) static x
|
||||
#define FT_CALLBACK_TABLE extern
|
||||
#define FT_CALLBACK_TABLE_DEF
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* FTCONFIG_H */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,321 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftsystem.c */
|
||||
/* */
|
||||
/* Unix-specific FreeType low-level system interface (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
/* we use our special ftconfig.h file, not the standard one */
|
||||
#include <ftconfig.h>
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_SYSTEM_H
|
||||
#include FT_ERRORS_H
|
||||
#include FT_TYPES_H
|
||||
#include FT_INTERNAL_OBJECTS_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
|
||||
|
||||
#ifdef MUNMAP_USES_VOIDP
|
||||
#define MUNMAP_ARG_CAST void *
|
||||
#else
|
||||
#define MUNMAP_ARG_CAST char *
|
||||
#endif
|
||||
|
||||
#ifdef NEED_MUNMAP_DECL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#else
|
||||
extern
|
||||
#endif
|
||||
int
|
||||
munmap( char* addr,
|
||||
int len );
|
||||
|
||||
#define MUNMAP_ARG_CAST char *
|
||||
|
||||
#endif /* NEED_DECLARATION_MUNMAP */
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* MEMORY MANAGEMENT INTERFACE */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_alloc */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory allocation function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* size :: The requested size in bytes. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of newly allocated block. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void* )
|
||||
ft_alloc( FT_Memory memory,
|
||||
long size )
|
||||
{
|
||||
FT_UNUSED( memory );
|
||||
|
||||
return malloc( size );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_realloc */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory reallocation function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* cur_size :: The current size of the allocated memory block. */
|
||||
/* */
|
||||
/* new_size :: The newly requested size in bytes. */
|
||||
/* */
|
||||
/* block :: The current address of the block in memory. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of the reallocated memory block. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void* )
|
||||
ft_realloc( FT_Memory memory,
|
||||
long cur_size,
|
||||
long new_size,
|
||||
void* block )
|
||||
{
|
||||
FT_UNUSED( memory );
|
||||
FT_UNUSED( cur_size );
|
||||
|
||||
return realloc( block, new_size );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_free */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory release function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* block :: The address of block in memory to be freed. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_free( FT_Memory memory,
|
||||
void* block )
|
||||
{
|
||||
FT_UNUSED( memory );
|
||||
|
||||
free( block );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* RESOURCE MANAGEMENT INTERFACE */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_io
|
||||
|
||||
/* We use the macro STREAM_FILE for convenience to extract the */
|
||||
/* system-specific stream handle from a given FreeType stream object */
|
||||
#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_close_stream */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The function to close a stream. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* stream :: A pointer to the stream object. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_close_stream( FT_Stream stream )
|
||||
{
|
||||
munmap( (MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size );
|
||||
|
||||
stream->descriptor.pointer = NULL;
|
||||
stream->size = 0;
|
||||
stream->base = 0;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_New_Stream( const char* filepathname,
|
||||
FT_Stream stream )
|
||||
{
|
||||
int file;
|
||||
struct stat stat_buf;
|
||||
|
||||
|
||||
if ( !stream )
|
||||
return FT_Err_Invalid_Stream_Handle;
|
||||
|
||||
/* open the file */
|
||||
file = open( filepathname, O_RDONLY );
|
||||
if ( file < 0 )
|
||||
{
|
||||
FT_ERROR(( "FT_New_Stream:" ));
|
||||
FT_ERROR(( " could not open `%s'\n", filepathname ));
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
}
|
||||
|
||||
if ( fstat( file, &stat_buf ) < 0 )
|
||||
{
|
||||
FT_ERROR(( "FT_New_Stream:" ));
|
||||
FT_ERROR(( " could not `fstat' file `%s'\n", filepathname ));
|
||||
goto Fail_Map;
|
||||
}
|
||||
|
||||
stream->size = stat_buf.st_size;
|
||||
stream->pos = 0;
|
||||
stream->base = (unsigned char *)mmap( NULL,
|
||||
stream->size,
|
||||
PROT_READ,
|
||||
MAP_FILE | MAP_PRIVATE,
|
||||
file,
|
||||
0 );
|
||||
|
||||
if ( (long)stream->base == -1 )
|
||||
{
|
||||
FT_ERROR(( "FT_New_Stream:" ));
|
||||
FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
|
||||
goto Fail_Map;
|
||||
}
|
||||
|
||||
close( file );
|
||||
|
||||
stream->descriptor.pointer = stream->base;
|
||||
stream->pathname.pointer = (char*)filepathname;
|
||||
|
||||
stream->close = ft_close_stream;
|
||||
stream->read = 0;
|
||||
|
||||
FT_TRACE1(( "FT_New_Stream:" ));
|
||||
FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
|
||||
filepathname, stream->size ));
|
||||
|
||||
return FT_Err_Ok;
|
||||
|
||||
Fail_Map:
|
||||
close( file );
|
||||
|
||||
stream->base = NULL;
|
||||
stream->size = 0;
|
||||
stream->pos = 0;
|
||||
|
||||
return FT_Err_Cannot_Open_Stream;
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
|
||||
extern FT_Int
|
||||
ft_mem_debug_init( FT_Memory memory );
|
||||
|
||||
extern void
|
||||
ft_mem_debug_done( FT_Memory memory );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Memory )
|
||||
FT_New_Memory( void )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
memory = (FT_Memory)malloc( sizeof ( *memory ) );
|
||||
if ( memory )
|
||||
{
|
||||
memory->user = 0;
|
||||
memory->alloc = ft_alloc;
|
||||
memory->realloc = ft_realloc;
|
||||
memory->free = ft_free;
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
ft_mem_debug_init( memory );
|
||||
#endif
|
||||
}
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Done_Memory( FT_Memory memory )
|
||||
{
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
ft_mem_debug_done( memory );
|
||||
#endif
|
||||
memory->free( memory, memory );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,11 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Call the 'configure' script located in 'builds/unix'.
|
||||
#
|
||||
# This should re-generate the following files:
|
||||
#
|
||||
# config.mk
|
||||
# Jamfile
|
||||
# install
|
||||
#
|
||||
CFG="$@" make setup unix
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,164 +0,0 @@
|
|||
The FreeType Project LICENSE
|
||||
----------------------------
|
||||
|
||||
2000-Feb-08
|
||||
|
||||
Copyright 1996-2000 by
|
||||
David Turner, Robert Wilhelm, and Werner Lemberg
|
||||
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The FreeType Project is distributed in several archive packages;
|
||||
some of them may contain, in addition to the FreeType font engine,
|
||||
various tools and contributions which rely on, or relate to, the
|
||||
FreeType Project.
|
||||
|
||||
This license applies to all files found in such packages, and
|
||||
which do not fall under their own explicit license. The license
|
||||
affects thus the FreeType font engine, the test programs,
|
||||
documentation and makefiles, at the very least.
|
||||
|
||||
This license was inspired by the BSD, Artistic, and IJG
|
||||
(Independent JPEG Group) licenses, which all encourage inclusion
|
||||
and use of free software in commercial and freeware products
|
||||
alike. As a consequence, its main points are that:
|
||||
|
||||
o We don't promise that this software works. However, we will be
|
||||
interested in any kind of bug reports. (`as is' distribution)
|
||||
|
||||
o You can use this software for whatever you want, in parts or
|
||||
full form, without having to pay us. (`royalty-free' usage)
|
||||
|
||||
o You may not pretend that you wrote this software. If you use
|
||||
it, or only parts of it, in a program, you must acknowledge
|
||||
somewhere in your documentation that you have used the
|
||||
FreeType code. (`credits')
|
||||
|
||||
We specifically permit and encourage the inclusion of this
|
||||
software, with or without modifications, in commercial products.
|
||||
We disclaim all warranties covering The FreeType Project and
|
||||
assume no liability related to The FreeType Project.
|
||||
|
||||
|
||||
Legal Terms
|
||||
===========
|
||||
|
||||
0. Definitions
|
||||
--------------
|
||||
|
||||
Throughout this license, the terms `package', `FreeType Project',
|
||||
and `FreeType archive' refer to the set of files originally
|
||||
distributed by the authors (David Turner, Robert Wilhelm, and
|
||||
Werner Lemberg) as the `FreeType Project', be they named as alpha,
|
||||
beta or final release.
|
||||
|
||||
`You' refers to the licensee, or person using the project, where
|
||||
`using' is a generic term including compiling the project's source
|
||||
code as well as linking it to form a `program' or `executable'.
|
||||
This program is referred to as `a program using the FreeType
|
||||
engine'.
|
||||
|
||||
This license applies to all files distributed in the original
|
||||
FreeType Project, including all source code, binaries and
|
||||
documentation, unless otherwise stated in the file in its
|
||||
original, unmodified form as distributed in the original archive.
|
||||
If you are unsure whether or not a particular file is covered by
|
||||
this license, you must contact us to verify this.
|
||||
|
||||
The FreeType Project is copyright (C) 1996-2000 by David Turner,
|
||||
Robert Wilhelm, and Werner Lemberg. All rights reserved except as
|
||||
specified below.
|
||||
|
||||
1. No Warranty
|
||||
--------------
|
||||
|
||||
THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
|
||||
USE, OF THE FREETYPE PROJECT.
|
||||
|
||||
2. Redistribution
|
||||
-----------------
|
||||
|
||||
This license grants a worldwide, royalty-free, perpetual and
|
||||
irrevocable right and license to use, execute, perform, compile,
|
||||
display, copy, create derivative works of, distribute and
|
||||
sublicense the FreeType Project (in both source and object code
|
||||
forms) and derivative works thereof for any purpose; and to
|
||||
authorize others to exercise some or all of the rights granted
|
||||
herein, subject to the following conditions:
|
||||
|
||||
o Redistribution of source code must retain this license file
|
||||
(`FTL.TXT') unaltered; any additions, deletions or changes to
|
||||
the original files must be clearly indicated in accompanying
|
||||
documentation. The copyright notices of the unaltered,
|
||||
original files must be preserved in all copies of source
|
||||
files.
|
||||
|
||||
o Redistribution in binary form must provide a disclaimer that
|
||||
states that the software is based in part of the work of the
|
||||
FreeType Team, in the distribution documentation. We also
|
||||
encourage you to put an URL to the FreeType web page in your
|
||||
documentation, though this isn't mandatory.
|
||||
|
||||
These conditions apply to any software derived from or based on
|
||||
the FreeType Project, not just the unmodified files. If you use
|
||||
our work, you must acknowledge us. However, no fee need be paid
|
||||
to us.
|
||||
|
||||
3. Advertising
|
||||
--------------
|
||||
|
||||
Neither the FreeType authors and contributors nor you shall use
|
||||
the name of the other for commercial, advertising, or promotional
|
||||
purposes without specific prior written permission.
|
||||
|
||||
We suggest, but do not require, that you use one or more of the
|
||||
following phrases to refer to this software in your documentation
|
||||
or advertising materials: `FreeType Project', `FreeType Engine',
|
||||
`FreeType library', or `FreeType Distribution'.
|
||||
|
||||
As you have not signed this license, you are not required to
|
||||
accept it. However, as the FreeType Project is copyrighted
|
||||
material, only this license, or another one contracted with the
|
||||
authors, grants you the right to use, distribute, and modify it.
|
||||
Therefore, by using, distributing, or modifying the FreeType
|
||||
Project, you indicate that you understand and accept all the terms
|
||||
of this license.
|
||||
|
||||
4. Contacts
|
||||
-----------
|
||||
|
||||
There are two mailing lists related to FreeType:
|
||||
|
||||
o freetype@freetype.org
|
||||
|
||||
Discusses general use and applications of FreeType, as well as
|
||||
future and wanted additions to the library and distribution.
|
||||
If you are looking for support, start in this list if you
|
||||
haven't found anything to help you in the documentation.
|
||||
|
||||
o devel@freetype.org
|
||||
|
||||
Discusses bugs, as well as engine internals, design issues,
|
||||
specific licenses, porting, etc.
|
||||
|
||||
o http://www.freetype.org
|
||||
|
||||
Holds the current FreeType web page, which will allow you to
|
||||
download our latest development version and read online
|
||||
documentation.
|
||||
|
||||
You can also contact us individually at:
|
||||
|
||||
David Turner <david.turner@freetype.org>
|
||||
Robert Wilhelm <robert.wilhelm@freetype.org>
|
||||
Werner Lemberg <werner.lemberg@freetype.org>
|
||||
|
||||
|
||||
--- end of LICENSE.TXT ---
|
|
@ -1,130 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ahangles.h */
|
||||
/* */
|
||||
/* A routine used to compute vector angles with limited accuracy */
|
||||
/* and very high speed (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
/* be used, modified, and distributed under the terms of the Catharon */
|
||||
/* Open Source License that should come with this file under the name */
|
||||
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/* Note that this license is compatible with the FreeType license. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "ahangles.h"
|
||||
|
||||
|
||||
/* the following table has been automatically generated with */
|
||||
/* the `mather.py' Python script */
|
||||
|
||||
const AH_Angle ah_arctan[1L << AH_ATAN_BITS] =
|
||||
{
|
||||
0, 0, 1, 1, 1, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 5,
|
||||
5, 5, 6, 6, 6, 7, 7, 7,
|
||||
8, 8, 8, 9, 9, 9, 10, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 12,
|
||||
13, 13, 13, 14, 14, 14, 14, 15,
|
||||
15, 15, 16, 16, 16, 17, 17, 17,
|
||||
18, 18, 18, 18, 19, 19, 19, 20,
|
||||
20, 20, 21, 21, 21, 21, 22, 22,
|
||||
22, 23, 23, 23, 24, 24, 24, 24,
|
||||
25, 25, 25, 26, 26, 26, 26, 27,
|
||||
27, 27, 28, 28, 28, 28, 29, 29,
|
||||
29, 30, 30, 30, 30, 31, 31, 31,
|
||||
31, 32, 32, 32, 33, 33, 33, 33,
|
||||
34, 34, 34, 34, 35, 35, 35, 35,
|
||||
36, 36, 36, 36, 37, 37, 37, 38,
|
||||
38, 38, 38, 39, 39, 39, 39, 40,
|
||||
40, 40, 40, 41, 41, 41, 41, 42,
|
||||
42, 42, 42, 42, 43, 43, 43, 43,
|
||||
44, 44, 44, 44, 45, 45, 45, 45,
|
||||
46, 46, 46, 46, 46, 47, 47, 47,
|
||||
47, 48, 48, 48, 48, 48, 49, 49,
|
||||
49, 49, 50, 50, 50, 50, 50, 51,
|
||||
51, 51, 51, 51, 52, 52, 52, 52,
|
||||
52, 53, 53, 53, 53, 53, 54, 54,
|
||||
54, 54, 54, 55, 55, 55, 55, 55,
|
||||
56, 56, 56, 56, 56, 57, 57, 57,
|
||||
57, 57, 57, 58, 58, 58, 58, 58,
|
||||
59, 59, 59, 59, 59, 59, 60, 60,
|
||||
60, 60, 60, 61, 61, 61, 61, 61,
|
||||
61, 62, 62, 62, 62, 62, 62, 63,
|
||||
63, 63, 63, 63, 63, 64, 64, 64
|
||||
};
|
||||
|
||||
|
||||
FT_LOCAL_DEF AH_Angle
|
||||
ah_angle( FT_Vector* v )
|
||||
{
|
||||
FT_Pos dx, dy;
|
||||
AH_Angle angle;
|
||||
|
||||
|
||||
dx = v->x;
|
||||
dy = v->y;
|
||||
|
||||
/* check trivial cases */
|
||||
if ( dy == 0 )
|
||||
{
|
||||
angle = 0;
|
||||
if ( dx < 0 )
|
||||
angle = AH_PI;
|
||||
return angle;
|
||||
}
|
||||
else if ( dx == 0 )
|
||||
{
|
||||
angle = AH_HALF_PI;
|
||||
if ( dy < 0 )
|
||||
angle = -AH_HALF_PI;
|
||||
return angle;
|
||||
}
|
||||
|
||||
angle = 0;
|
||||
if ( dx < 0 )
|
||||
{
|
||||
dx = -v->x;
|
||||
dy = -v->y;
|
||||
angle = AH_PI;
|
||||
}
|
||||
|
||||
if ( dy < 0 )
|
||||
{
|
||||
FT_Pos tmp;
|
||||
|
||||
|
||||
tmp = dx;
|
||||
dx = -dy;
|
||||
dy = tmp;
|
||||
angle -= AH_HALF_PI;
|
||||
}
|
||||
|
||||
if ( dx == 0 && dy == 0 )
|
||||
return 0;
|
||||
|
||||
if ( dx == dy )
|
||||
angle += AH_PI / 4;
|
||||
else if ( dx > dy )
|
||||
angle += ah_arctan[FT_DivFix( dy, dx ) >> ( 16 - AH_ATAN_BITS )];
|
||||
else
|
||||
angle += AH_HALF_PI -
|
||||
ah_arctan[FT_DivFix( dx, dy ) >> ( 16 - AH_ATAN_BITS )];
|
||||
|
||||
if ( angle > AH_PI )
|
||||
angle -= AH_2PI;
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,59 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ahangles.h */
|
||||
/* */
|
||||
/* A routine used to compute vector angles with limited accuracy */
|
||||
/* and very high speed (specification). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
/* be used, modified, and distributed under the terms of the Catharon */
|
||||
/* Open Source License that should come with this file under the name */
|
||||
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/* Note that this license is compatible with the FreeType license. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __AHANGLES_H__
|
||||
#define __AHANGLES_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include "ahtypes.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* PI expressed in ah_angles -- we don't really need an important */
|
||||
/* precision, so 256 should be enough */
|
||||
#define AH_PI 256
|
||||
#define AH_2PI ( AH_PI * 2 )
|
||||
#define AH_HALF_PI ( AH_PI / 2 )
|
||||
#define AH_2PIMASK ( AH_2PI - 1 )
|
||||
|
||||
/* the number of bits used to express an arc tangent; */
|
||||
/* see the structure of the lookup table */
|
||||
#define AH_ATAN_BITS 8
|
||||
|
||||
extern
|
||||
const AH_Angle ah_arctan[1L << AH_ATAN_BITS];
|
||||
|
||||
|
||||
FT_LOCAL AH_Angle
|
||||
ah_angle( FT_Vector* v );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AHANGLES_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,395 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ahglobal.c */
|
||||
/* */
|
||||
/* Routines used to compute global metrics automatically (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
/* be used, modified, and distributed under the terms of the Catharon */
|
||||
/* Open Source License that should come with this file under the name */
|
||||
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/* Note that this license is compatible with the FreeType license. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include "ahglobal.h"
|
||||
#include "ahglyph.h"
|
||||
|
||||
|
||||
#define MAX_TEST_CHARACTERS 12
|
||||
|
||||
static
|
||||
const char* blue_chars[ah_blue_max] =
|
||||
{
|
||||
"THEZOCQS",
|
||||
"HEZLOCUS",
|
||||
"xzroesc",
|
||||
"xzroesc",
|
||||
"pqgjy"
|
||||
};
|
||||
|
||||
|
||||
/* simple insertion sort */
|
||||
static void
|
||||
sort_values( FT_Int count,
|
||||
FT_Pos* table )
|
||||
{
|
||||
FT_Int i, j, swap;
|
||||
|
||||
|
||||
for ( i = 1; i < count; i++ )
|
||||
{
|
||||
for ( j = i; j > 0; j-- )
|
||||
{
|
||||
if ( table[j] > table[j - 1] )
|
||||
break;
|
||||
|
||||
swap = table[j];
|
||||
table[j] = table[j - 1];
|
||||
table[j - 1] = swap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ah_hinter_compute_blues( AH_Hinter* hinter )
|
||||
{
|
||||
AH_Blue blue;
|
||||
AH_Globals* globals = &hinter->globals->design;
|
||||
FT_Pos flats [MAX_TEST_CHARACTERS];
|
||||
FT_Pos rounds[MAX_TEST_CHARACTERS];
|
||||
FT_Int num_flats;
|
||||
FT_Int num_rounds;
|
||||
|
||||
FT_Face face;
|
||||
FT_GlyphSlot glyph;
|
||||
FT_Error error;
|
||||
FT_CharMap charmap;
|
||||
|
||||
|
||||
face = hinter->face;
|
||||
glyph = face->glyph;
|
||||
|
||||
/* save current charmap */
|
||||
charmap = face->charmap;
|
||||
|
||||
/* do we have a Unicode charmap in there? */
|
||||
error = FT_Select_Charmap( face, ft_encoding_unicode );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* we compute the blues simply by loading each character from the */
|
||||
/* 'blue_chars[blues]' string, then compute its top-most and */
|
||||
/* bottom-most points */
|
||||
|
||||
AH_LOG(( "blue zones computation\n" ));
|
||||
AH_LOG(( "------------------------------------------------\n" ));
|
||||
|
||||
for ( blue = ah_blue_capital_top; blue < ah_blue_max; blue++ )
|
||||
{
|
||||
const char* p = blue_chars[blue];
|
||||
const char* limit = p + MAX_TEST_CHARACTERS;
|
||||
FT_Pos *blue_ref, *blue_shoot;
|
||||
|
||||
|
||||
AH_LOG(( "blue %3d: ", blue ));
|
||||
|
||||
num_flats = 0;
|
||||
num_rounds = 0;
|
||||
|
||||
for ( ; p < limit; p++ )
|
||||
{
|
||||
FT_UInt glyph_index;
|
||||
FT_Vector* extremum;
|
||||
FT_Vector* points;
|
||||
FT_Vector* point_limit;
|
||||
FT_Vector* point;
|
||||
FT_Bool round;
|
||||
|
||||
|
||||
/* exit if we reach the end of the string */
|
||||
if ( !*p )
|
||||
break;
|
||||
|
||||
AH_LOG(( "`%c'", *p ));
|
||||
|
||||
/* load the character in the face -- skip unknown or empty ones */
|
||||
glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
|
||||
if ( glyph_index == 0 )
|
||||
continue;
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
|
||||
if ( error || glyph->outline.n_points <= 0 )
|
||||
continue;
|
||||
|
||||
/* now compute min or max point indices and coordinates */
|
||||
points = glyph->outline.points;
|
||||
point_limit = points + glyph->outline.n_points;
|
||||
point = points;
|
||||
extremum = point;
|
||||
point++;
|
||||
|
||||
if ( AH_IS_TOP_BLUE( blue ) )
|
||||
{
|
||||
for ( ; point < point_limit; point++ )
|
||||
if ( point->y > extremum->y )
|
||||
extremum = point;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( ; point < point_limit; point++ )
|
||||
if ( point->y < extremum->y )
|
||||
extremum = point;
|
||||
}
|
||||
|
||||
AH_LOG(( "%5d", (int)extremum->y ));
|
||||
|
||||
/* now, check whether the point belongs to a straight or round */
|
||||
/* segment; we first need to find in which contour the extremum */
|
||||
/* lies, then see its previous and next points */
|
||||
{
|
||||
FT_Int index = (FT_Int)( extremum - points );
|
||||
FT_Int n;
|
||||
FT_Int first, last, prev, next, end;
|
||||
FT_Pos dist;
|
||||
|
||||
|
||||
last = -1;
|
||||
first = 0;
|
||||
|
||||
for ( n = 0; n < glyph->outline.n_contours; n++ )
|
||||
{
|
||||
end = glyph->outline.contours[n];
|
||||
if ( end >= index )
|
||||
{
|
||||
last = end;
|
||||
break;
|
||||
}
|
||||
first = end + 1;
|
||||
}
|
||||
|
||||
/* XXX: should never happen! */
|
||||
if ( last < 0 )
|
||||
continue;
|
||||
|
||||
/* now look for the previous and next points that are not on the */
|
||||
/* same Y coordinate. Threshold the `closeness'... */
|
||||
|
||||
prev = index;
|
||||
next = prev;
|
||||
|
||||
do
|
||||
{
|
||||
if ( prev > first )
|
||||
prev--;
|
||||
else
|
||||
prev = last;
|
||||
|
||||
dist = points[prev].y - extremum->y;
|
||||
if ( dist < -5 || dist > 5 )
|
||||
break;
|
||||
|
||||
} while ( prev != index );
|
||||
|
||||
do
|
||||
{
|
||||
if ( next < last )
|
||||
next++;
|
||||
else
|
||||
next = first;
|
||||
|
||||
dist = points[next].y - extremum->y;
|
||||
if ( dist < -5 || dist > 5 )
|
||||
break;
|
||||
|
||||
} while ( next != index );
|
||||
|
||||
/* now, set the `round' flag depending on the segment's kind */
|
||||
round = FT_BOOL(
|
||||
FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_Curve_Tag_On ||
|
||||
FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_Curve_Tag_On );
|
||||
|
||||
AH_LOG(( "%c ", round ? 'r' : 'f' ));
|
||||
}
|
||||
|
||||
if ( round )
|
||||
rounds[num_rounds++] = extremum->y;
|
||||
else
|
||||
flats[num_flats++] = extremum->y;
|
||||
}
|
||||
|
||||
AH_LOG(( "\n" ));
|
||||
|
||||
/* we have computed the contents of the `rounds' and `flats' tables, */
|
||||
/* now determine the reference and overshoot position of the blue; */
|
||||
/* we simply take the median value after a simple short */
|
||||
sort_values( num_rounds, rounds );
|
||||
sort_values( num_flats, flats );
|
||||
|
||||
blue_ref = globals->blue_refs + blue;
|
||||
blue_shoot = globals->blue_shoots + blue;
|
||||
if ( num_flats == 0 && num_rounds == 0 )
|
||||
{
|
||||
*blue_ref = -10000;
|
||||
*blue_shoot = -10000;
|
||||
}
|
||||
else if ( num_flats == 0 )
|
||||
{
|
||||
*blue_ref =
|
||||
*blue_shoot = rounds[num_rounds / 2];
|
||||
}
|
||||
else if ( num_rounds == 0 )
|
||||
{
|
||||
*blue_ref =
|
||||
*blue_shoot = flats[num_flats / 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
*blue_ref = flats[num_flats / 2];
|
||||
*blue_shoot = rounds[num_rounds / 2];
|
||||
}
|
||||
|
||||
/* there are sometimes problems: if the overshoot position of top */
|
||||
/* zones is under its reference position, or the opposite for bottom */
|
||||
/* zones. We must thus check everything there and correct the errors */
|
||||
if ( *blue_shoot != *blue_ref )
|
||||
{
|
||||
FT_Pos ref = *blue_ref;
|
||||
FT_Pos shoot = *blue_shoot;
|
||||
FT_Bool over_ref = FT_BOOL( shoot > ref );
|
||||
|
||||
|
||||
if ( AH_IS_TOP_BLUE( blue ) ^ over_ref )
|
||||
*blue_shoot = *blue_ref = ( shoot + ref ) / 2;
|
||||
}
|
||||
|
||||
AH_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
|
||||
}
|
||||
|
||||
/* reset original face charmap */
|
||||
FT_Set_Charmap( face, charmap );
|
||||
error = 0;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ah_hinter_compute_widths( AH_Hinter* hinter )
|
||||
{
|
||||
/* scan the array of segments in each direction */
|
||||
AH_Outline* outline = hinter->glyph;
|
||||
AH_Segment* segments;
|
||||
AH_Segment* limit;
|
||||
AH_Globals* globals = &hinter->globals->design;
|
||||
FT_Pos* widths;
|
||||
FT_Int dimension;
|
||||
FT_Int* p_num_widths;
|
||||
FT_Error error = 0;
|
||||
FT_Pos edge_distance_threshold = 32000;
|
||||
|
||||
|
||||
globals->num_widths = 0;
|
||||
globals->num_heights = 0;
|
||||
|
||||
/* For now, compute the standard width and height from the `o' */
|
||||
/* character. I started computing the stem width of the `i' and the */
|
||||
/* stem height of the "-", but it wasn't too good. Moreover, we now */
|
||||
/* have a single character that gives us standard width and height. */
|
||||
{
|
||||
FT_UInt glyph_index;
|
||||
|
||||
|
||||
glyph_index = FT_Get_Char_Index( hinter->face, 'o' );
|
||||
if ( glyph_index == 0 )
|
||||
return 0;
|
||||
|
||||
error = FT_Load_Glyph( hinter->face, glyph_index, FT_LOAD_NO_SCALE );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
error = ah_outline_load( hinter->glyph, hinter->face );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
ah_outline_compute_segments( hinter->glyph );
|
||||
ah_outline_link_segments( hinter->glyph );
|
||||
}
|
||||
|
||||
segments = outline->horz_segments;
|
||||
limit = segments + outline->num_hsegments;
|
||||
widths = globals->heights;
|
||||
p_num_widths = &globals->num_heights;
|
||||
|
||||
for ( dimension = 1; dimension >= 0; dimension-- )
|
||||
{
|
||||
AH_Segment* seg = segments;
|
||||
AH_Segment* link;
|
||||
FT_Int num_widths = 0;
|
||||
|
||||
|
||||
for ( ; seg < limit; seg++ )
|
||||
{
|
||||
link = seg->link;
|
||||
/* we only consider stem segments there! */
|
||||
if ( link && link->link == seg && link > seg )
|
||||
{
|
||||
FT_Int dist;
|
||||
|
||||
|
||||
dist = seg->pos - link->pos;
|
||||
if ( dist < 0 )
|
||||
dist = -dist;
|
||||
|
||||
if ( num_widths < 12 )
|
||||
widths[num_widths++] = dist;
|
||||
}
|
||||
}
|
||||
|
||||
sort_values( num_widths, widths );
|
||||
*p_num_widths = num_widths;
|
||||
|
||||
/* we will now try to find the smallest width */
|
||||
if ( num_widths > 0 && widths[0] < edge_distance_threshold )
|
||||
edge_distance_threshold = widths[0];
|
||||
|
||||
segments = outline->vert_segments;
|
||||
limit = segments + outline->num_vsegments;
|
||||
widths = globals->widths;
|
||||
p_num_widths = &globals->num_widths;
|
||||
|
||||
}
|
||||
|
||||
/* Now, compute the edge distance threshold as a fraction of the */
|
||||
/* smallest width in the font. Set it in `hinter.glyph' too! */
|
||||
if ( edge_distance_threshold == 32000 )
|
||||
edge_distance_threshold = 50;
|
||||
|
||||
/* let's try 20% */
|
||||
hinter->glyph->edge_distance_threshold = edge_distance_threshold / 5;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
ah_hinter_compute_globals( AH_Hinter* hinter )
|
||||
{
|
||||
return ah_hinter_compute_widths( hinter ) ||
|
||||
ah_hinter_compute_blues ( hinter );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,49 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ahglobal.h */
|
||||
/* */
|
||||
/* Routines used to compute global metrics automatically */
|
||||
/* (specification). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
/* be used, modified, and distributed under the terms of the Catharon */
|
||||
/* Open Source License that should come with this file under the name */
|
||||
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/* Note that this license is compatible with the FreeType license. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __AHGLOBAL_H__
|
||||
#define __AHGLOBAL_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "ahtypes.h"
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
#define AH_IS_TOP_BLUE( b ) ( (b) == ah_blue_capital_top || \
|
||||
(b) == ah_blue_small_top )
|
||||
|
||||
|
||||
/* compute global metrics automatically */
|
||||
FT_LOCAL
|
||||
FT_Error ah_hinter_compute_globals( AH_Hinter* hinter );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AHGLOBAL_H__ */
|
||||
|
||||
|
||||
/* END */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,93 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ahglyph.h */
|
||||
/* */
|
||||
/* Routines used to load and analyze a given glyph before hinting */
|
||||
/* (specification). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
/* be used, modified, and distributed under the terms of the Catharon */
|
||||
/* Open Source License that should come with this file under the name */
|
||||
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/* Note that this license is compatible with the FreeType license. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __AHGLYPH_H__
|
||||
#define __AHGLYPH_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "ahtypes.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
typedef enum AH_UV_
|
||||
{
|
||||
ah_uv_fxy,
|
||||
ah_uv_fyx,
|
||||
ah_uv_oxy,
|
||||
ah_uv_oyx,
|
||||
ah_uv_ox,
|
||||
ah_uv_oy,
|
||||
ah_uv_yx,
|
||||
ah_uv_xy /* should always be last! */
|
||||
|
||||
} AH_UV;
|
||||
|
||||
|
||||
FT_LOCAL void
|
||||
ah_setup_uv( AH_Outline* outline,
|
||||
AH_UV source );
|
||||
|
||||
|
||||
/* AH_Outline functions - they should be typically called in this order */
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
ah_outline_new( FT_Memory memory,
|
||||
AH_Outline** aoutline );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
ah_outline_load( AH_Outline* outline,
|
||||
FT_Face face );
|
||||
|
||||
FT_LOCAL void
|
||||
ah_outline_compute_segments( AH_Outline* outline );
|
||||
|
||||
FT_LOCAL void
|
||||
ah_outline_link_segments( AH_Outline* outline );
|
||||
|
||||
FT_LOCAL void
|
||||
ah_outline_detect_features( AH_Outline* outline );
|
||||
|
||||
FT_LOCAL void
|
||||
ah_outline_compute_blue_edges( AH_Outline* outline,
|
||||
AH_Face_Globals* globals );
|
||||
|
||||
FT_LOCAL void
|
||||
ah_outline_scale_blue_edges( AH_Outline* outline,
|
||||
AH_Face_Globals* globals );
|
||||
|
||||
FT_LOCAL void
|
||||
ah_outline_save( AH_Outline* outline,
|
||||
AH_Loader* loader );
|
||||
|
||||
FT_LOCAL void
|
||||
ah_outline_done( AH_Outline* outline );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AHGLYPH_H__ */
|
||||
|
||||
|
||||
/* END */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,75 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ahhint.h */
|
||||
/* */
|
||||
/* Glyph hinter (declaration). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
/* be used, modified, and distributed under the terms of the Catharon */
|
||||
/* Open Source License that should come with this file under the name */
|
||||
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/* Note that this license is compatible with the FreeType license. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __AHHINT_H__
|
||||
#define __AHHINT_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "ahglobal.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
#define AH_HINT_DEFAULT 0
|
||||
#define AH_HINT_NO_ALIGNMENT 1
|
||||
#define AH_HINT_NO_HORZ_EDGES 0x20000L
|
||||
#define AH_HINT_NO_VERT_EDGES 0x40000L
|
||||
|
||||
|
||||
/* create a new empty hinter object */
|
||||
FT_LOCAL FT_Error
|
||||
ah_hinter_new( FT_Library library,
|
||||
AH_Hinter** ahinter );
|
||||
|
||||
/* Load a hinted glyph in the hinter */
|
||||
FT_LOCAL FT_Error
|
||||
ah_hinter_load_glyph( AH_Hinter* hinter,
|
||||
FT_GlyphSlot slot,
|
||||
FT_Size size,
|
||||
FT_UInt glyph_index,
|
||||
FT_Int load_flags );
|
||||
|
||||
/* finalize a hinter object */
|
||||
FT_LOCAL void
|
||||
ah_hinter_done( AH_Hinter* hinter );
|
||||
|
||||
FT_LOCAL void
|
||||
ah_hinter_done_face_globals( AH_Face_Globals* globals );
|
||||
|
||||
FT_LOCAL void
|
||||
ah_hinter_get_global_hints( AH_Hinter* hinter,
|
||||
FT_Face face,
|
||||
void** global_hints,
|
||||
long* global_len );
|
||||
|
||||
FT_LOCAL void
|
||||
ah_hinter_done_global_hints( AH_Hinter* hinter,
|
||||
void* global_hints );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AHHINT_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,133 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ahloader.h */
|
||||
/* */
|
||||
/* Glyph loader for the auto-hinting module (declaration only). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
/* be used, modified, and distributed under the terms of the Catharon */
|
||||
/* Open Source License that should come with this file under the name */
|
||||
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/* Note that this license is compatible with the FreeType license. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* This defines the AH_GlyphLoader type in two different ways: */
|
||||
/* */
|
||||
/* - If the module is compiled within FreeType 2, the type is simply a */
|
||||
/* typedef to FT_GlyphLoader. */
|
||||
/* */
|
||||
/* - If the module is compiled as a standalone object, AH_GlyphLoader */
|
||||
/* has its own implementation. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#ifndef __AHLOADER_H__
|
||||
#define __AHLOADER_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
#ifdef _STANDALONE_
|
||||
|
||||
typedef struct AH_GlyphLoad_
|
||||
{
|
||||
FT_Outline outline; /* outline */
|
||||
FT_UInt num_subglyphs; /* number of subglyphs */
|
||||
FT_SubGlyph* subglyphs; /* subglyphs */
|
||||
FT_Vector* extra_points; /* extra points table */
|
||||
|
||||
} AH_GlyphLoad;
|
||||
|
||||
|
||||
struct AH_GlyphLoader_
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_UInt max_points;
|
||||
FT_UInt max_contours;
|
||||
FT_UInt max_subglyphs;
|
||||
FT_Bool use_extra;
|
||||
|
||||
AH_GlyphLoad base;
|
||||
AH_GlyphLoad current;
|
||||
|
||||
void* other; /* for possible future extensions */
|
||||
};
|
||||
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
AH_GlyphLoader_New( FT_Memory memory,
|
||||
AH_GlyphLoader** aloader );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
AH_GlyphLoader_Create_Extra( AH_GlyphLoader* loader );
|
||||
|
||||
FT_LOCAL void
|
||||
AH_GlyphLoader_Done( AH_GlyphLoader* loader );
|
||||
|
||||
FT_LOCAL void
|
||||
AH_GlyphLoader_Reset( AH_GlyphLoader* loader );
|
||||
|
||||
FT_LOCAL void
|
||||
AH_GlyphLoader_Rewind( AH_GlyphLoader* loader );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
AH_GlyphLoader_Check_Points( AH_GlyphLoader* loader,
|
||||
FT_UInt n_points,
|
||||
FT_UInt n_contours );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
AH_GlyphLoader_Check_Subglyphs( AH_GlyphLoader* loader,
|
||||
FT_UInt n_subs );
|
||||
|
||||
FT_LOCAL void
|
||||
AH_GlyphLoader_Prepare( AH_GlyphLoader* loader );
|
||||
|
||||
FT_LOCAL void
|
||||
AH_GlyphLoader_Add( AH_GlyphLoader* loader );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
AH_GlyphLoader_Copy_Points( AH_GlyphLoader* target,
|
||||
FT_GlyphLoader* source );
|
||||
|
||||
#else /* _STANDALONE */
|
||||
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
#define AH_Load FT_GlyphLoad
|
||||
#define AH_Loader FT_GlyphLoader
|
||||
|
||||
#define ah_loader_new FT_GlyphLoader_New
|
||||
#define ah_loader_done FT_GlyphLoader_Done
|
||||
#define ah_loader_reset FT_GlyphLoader_Reset
|
||||
#define ah_loader_rewind FT_GlyphLoader_Rewind
|
||||
#define ah_loader_create_extra FT_GlyphLoader_Create_Extra
|
||||
#define ah_loader_check_points FT_GlyphLoader_Check_Points
|
||||
#define ah_loader_check_subglyphs FT_GlyphLoader_Check_Subglyphs
|
||||
#define ah_loader_prepare FT_GlyphLoader_Prepare
|
||||
#define ah_loader_add FT_GlyphLoader_Add
|
||||
#define ah_loader_copy_points FT_GlyphLoader_Copy_Points
|
||||
|
||||
#endif /* _STANDALONE_ */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AHLOADER_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,136 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ahmodule.c */
|
||||
/* */
|
||||
/* Auto-hinting module implementation (declaration). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
/* be used, modified, and distributed under the terms of the Catharon */
|
||||
/* Open Source License that should come with this file under the name */
|
||||
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/* Note that this license is compatible with the FreeType license. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_MODULE_H
|
||||
#include "ahhint.h"
|
||||
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
extern AH_Hinter* ah_debug_hinter = NULL;
|
||||
extern FT_Bool ah_debug_disable_horz = 0;
|
||||
extern FT_Bool ah_debug_disable_vert = 0;
|
||||
#endif
|
||||
|
||||
typedef struct FT_AutoHinterRec_
|
||||
{
|
||||
FT_ModuleRec root;
|
||||
AH_Hinter* hinter;
|
||||
|
||||
} FT_AutoHinterRec;
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ft_autohinter_init( FT_AutoHinter module )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
error = ah_hinter_new( module->root.library, &module->hinter );
|
||||
#ifdef DEBUG_HINTER
|
||||
if ( !error )
|
||||
ah_debug_hinter = module->hinter;
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_autohinter_done( FT_AutoHinter module )
|
||||
{
|
||||
ah_hinter_done( module->hinter );
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
ah_debug_hinter = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ft_autohinter_load( FT_AutoHinter module,
|
||||
FT_GlyphSlot slot,
|
||||
FT_Size size,
|
||||
FT_UInt glyph_index,
|
||||
FT_ULong load_flags )
|
||||
{
|
||||
return ah_hinter_load_glyph( module->hinter,
|
||||
slot, size, glyph_index, load_flags );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_autohinter_reset( FT_AutoHinter module,
|
||||
FT_Face face )
|
||||
{
|
||||
UNUSED( module );
|
||||
|
||||
if ( face->autohint.data )
|
||||
ah_hinter_done_face_globals( (AH_Face_Globals*)(face->autohint.data) );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_autohinter_get_globals( FT_AutoHinter module,
|
||||
FT_Face face,
|
||||
void** global_hints,
|
||||
long* global_len )
|
||||
{
|
||||
ah_hinter_get_global_hints( module->hinter, face,
|
||||
global_hints, global_len );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_autohinter_done_globals( FT_AutoHinter module,
|
||||
void* global_hints )
|
||||
{
|
||||
ah_hinter_done_global_hints( module->hinter, global_hints );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FT_AutoHinter_Interface autohinter_interface =
|
||||
{
|
||||
ft_autohinter_reset,
|
||||
ft_autohinter_load,
|
||||
ft_autohinter_get_globals,
|
||||
ft_autohinter_done_globals
|
||||
};
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FT_Module_Class autohint_module_class =
|
||||
{
|
||||
ft_module_hinter,
|
||||
sizeof ( FT_AutoHinterRec ),
|
||||
|
||||
"autohinter",
|
||||
0x10000L, /* version 1.0 of the autohinter */
|
||||
0x20000L, /* requires FreeType 2.0 or above */
|
||||
|
||||
(const void*)&autohinter_interface,
|
||||
|
||||
(FT_Module_Constructor)ft_autohinter_init,
|
||||
(FT_Module_Destructor) ft_autohinter_done,
|
||||
(FT_Module_Requester) 0
|
||||
};
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,883 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ahoptim.c */
|
||||
/* */
|
||||
/* FreeType auto hinting outline optimization (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
/* be used, modified, and distributed under the terms of the Catharon */
|
||||
/* Open Source License that should come with this file under the name */
|
||||
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/* Note that this license is compatible with the FreeType license. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* This module is in charge of optimising the outlines produced by the */
|
||||
/* auto-hinter in direct mode. This is required at small pixel sizes in */
|
||||
/* order to ensure coherent spacing, among other things.. */
|
||||
/* */
|
||||
/* The technique used in this module is a simplified simulated */
|
||||
/* annealing. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_OBJECTS_H /* for ALLOC_ARRAY() and FREE() */
|
||||
#include "ahoptim.h"
|
||||
|
||||
|
||||
/* define this macro to use brute force optimisation -- this is slow, */
|
||||
/* but a good way to perfect the distortion function `by hand' through */
|
||||
/* tweaking */
|
||||
#define AH_BRUTE_FORCE
|
||||
|
||||
|
||||
#define xxxAH_DEBUG_OPTIM
|
||||
|
||||
|
||||
#undef LOG
|
||||
#ifdef AH_DEBUG_OPTIM
|
||||
|
||||
#define LOG( x ) optim_log ## x
|
||||
|
||||
#else
|
||||
|
||||
#define LOG( x )
|
||||
|
||||
#endif /* AH_DEBUG_OPTIM */
|
||||
|
||||
|
||||
#ifdef AH_DEBUG_OPTIM
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FLOAT( x ) ( (float)( (x) / 64.0 ) )
|
||||
|
||||
static void
|
||||
optim_log( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start( ap, fmt );
|
||||
vprintf( fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
AH_Dump_Stems( AH_Optimizer* optimizer )
|
||||
{
|
||||
int n;
|
||||
AH_Stem* stem;
|
||||
|
||||
|
||||
stem = optimizer->stems;
|
||||
for ( n = 0; n < optimizer->num_stems; n++, stem++ )
|
||||
{
|
||||
LOG(( " %c%2d [%.1f:%.1f]={%.1f:%.1f}="
|
||||
"<%1.f..%1.f> force=%.1f speed=%.1f\n",
|
||||
optimizer->vertical ? 'V' : 'H', n,
|
||||
FLOAT( stem->edge1->opos ), FLOAT( stem->edge2->opos ),
|
||||
FLOAT( stem->edge1->pos ), FLOAT( stem->edge2->pos ),
|
||||
FLOAT( stem->min_pos ), FLOAT( stem->max_pos ),
|
||||
FLOAT( stem->force ), FLOAT( stem->velocity ) ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
AH_Dump_Stems2( AH_Optimizer* optimizer )
|
||||
{
|
||||
int n;
|
||||
AH_Stem* stem;
|
||||
|
||||
|
||||
stem = optimizer->stems;
|
||||
for ( n = 0; n < optimizer->num_stems; n++, stem++ )
|
||||
{
|
||||
LOG(( " %c%2d [%.1f]=<%1.f..%1.f> force=%.1f speed=%.1f\n",
|
||||
optimizer->vertical ? 'V' : 'H', n,
|
||||
FLOAT( stem->pos ),
|
||||
FLOAT( stem->min_pos ), FLOAT( stem->max_pos ),
|
||||
FLOAT( stem->force ), FLOAT( stem->velocity ) ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
AH_Dump_Springs( AH_Optimizer* optimizer )
|
||||
{
|
||||
int n;
|
||||
AH_Spring* spring;
|
||||
AH_Stem* stems;
|
||||
|
||||
|
||||
spring = optimizer->springs;
|
||||
stems = optimizer->stems;
|
||||
LOG(( "%cSprings ", optimizer->vertical ? 'V' : 'H' ));
|
||||
|
||||
for ( n = 0; n < optimizer->num_springs; n++, spring++ )
|
||||
{
|
||||
LOG(( " [%d-%d:%.1f:%1.f:%.1f]",
|
||||
spring->stem1 - stems, spring->stem2 - stems,
|
||||
FLOAT( spring->owidth ),
|
||||
FLOAT( spring->stem2->pos -
|
||||
( spring->stem1->pos + spring->stem1->width ) ),
|
||||
FLOAT( spring->tension ) ));
|
||||
}
|
||||
|
||||
LOG(( "\n" ));
|
||||
}
|
||||
|
||||
#endif /* AH_DEBUG_OPTIM */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** COMPUTE STEMS AND SPRINGS IN AN OUTLINE ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
static int
|
||||
valid_stem_segments( AH_Segment* seg1,
|
||||
AH_Segment* seg2 )
|
||||
{
|
||||
return seg1->serif == 0 &&
|
||||
seg2 &&
|
||||
seg2->link == seg1 &&
|
||||
seg1->pos < seg2->pos &&
|
||||
seg1->min_coord <= seg2->max_coord &&
|
||||
seg2->min_coord <= seg1->max_coord;
|
||||
}
|
||||
|
||||
|
||||
/* compute all stems in an outline */
|
||||
static int
|
||||
optim_compute_stems( AH_Optimizer* optimizer )
|
||||
{
|
||||
AH_Outline* outline = optimizer->outline;
|
||||
FT_Fixed scale;
|
||||
FT_Memory memory = optimizer->memory;
|
||||
FT_Error error = 0;
|
||||
FT_Int dimension;
|
||||
AH_Edge* edges;
|
||||
AH_Edge* edge_limit;
|
||||
AH_Stem** p_stems;
|
||||
FT_Int* p_num_stems;
|
||||
|
||||
|
||||
edges = outline->horz_edges;
|
||||
edge_limit = edges + outline->num_hedges;
|
||||
scale = outline->y_scale;
|
||||
|
||||
p_stems = &optimizer->horz_stems;
|
||||
p_num_stems = &optimizer->num_hstems;
|
||||
|
||||
for ( dimension = 1; dimension >= 0; dimension-- )
|
||||
{
|
||||
AH_Stem* stems = 0;
|
||||
FT_Int num_stems = 0;
|
||||
AH_Edge* edge;
|
||||
|
||||
|
||||
/* first of all, count the number of stems in this direction */
|
||||
for ( edge = edges; edge < edge_limit; edge++ )
|
||||
{
|
||||
AH_Segment* seg = edge->first;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
if (valid_stem_segments( seg, seg->link ) )
|
||||
num_stems++;
|
||||
|
||||
seg = seg->edge_next;
|
||||
|
||||
} while ( seg != edge->first );
|
||||
}
|
||||
|
||||
/* now allocate the stems and build their table */
|
||||
if ( num_stems > 0 )
|
||||
{
|
||||
AH_Stem* stem;
|
||||
|
||||
|
||||
if ( ALLOC_ARRAY( stems, num_stems, AH_Stem ) )
|
||||
goto Exit;
|
||||
|
||||
stem = stems;
|
||||
for ( edge = edges; edge < edge_limit; edge++ )
|
||||
{
|
||||
AH_Segment* seg = edge->first;
|
||||
AH_Segment* seg2;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
seg2 = seg->link;
|
||||
if ( valid_stem_segments( seg, seg2 ) )
|
||||
{
|
||||
AH_Edge* edge1 = seg->edge;
|
||||
AH_Edge* edge2 = seg2->edge;
|
||||
|
||||
|
||||
stem->edge1 = edge1;
|
||||
stem->edge2 = edge2;
|
||||
stem->opos = edge1->opos;
|
||||
stem->pos = edge1->pos;
|
||||
stem->owidth = edge2->opos - edge1->opos;
|
||||
stem->width = edge2->pos - edge1->pos;
|
||||
|
||||
/* compute min_coord and max_coord */
|
||||
{
|
||||
FT_Pos min_coord = seg->min_coord;
|
||||
FT_Pos max_coord = seg->max_coord;
|
||||
|
||||
|
||||
if ( seg2->min_coord > min_coord )
|
||||
min_coord = seg2->min_coord;
|
||||
|
||||
if ( seg2->max_coord < max_coord )
|
||||
max_coord = seg2->max_coord;
|
||||
|
||||
stem->min_coord = min_coord;
|
||||
stem->max_coord = max_coord;
|
||||
}
|
||||
|
||||
/* compute minimum and maximum positions for stem -- */
|
||||
/* note that the left-most/bottom-most stem has always */
|
||||
/* a fixed position */
|
||||
if ( stem == stems || edge1->blue_edge || edge2->blue_edge )
|
||||
{
|
||||
/* this stem cannot move; it is snapped to a blue edge */
|
||||
stem->min_pos = stem->pos;
|
||||
stem->max_pos = stem->pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this edge can move; compute its min and max positions */
|
||||
FT_Pos pos1 = stem->opos;
|
||||
FT_Pos pos2 = pos1 + stem->owidth - stem->width;
|
||||
FT_Pos min1 = pos1 & -64;
|
||||
FT_Pos min2 = pos2 & -64;
|
||||
|
||||
|
||||
stem->min_pos = min1;
|
||||
stem->max_pos = min1 + 64;
|
||||
if ( min2 < min1 )
|
||||
stem->min_pos = min2;
|
||||
else
|
||||
stem->max_pos = min2 + 64;
|
||||
|
||||
/* XXX: just to see what it does */
|
||||
stem->max_pos += 64;
|
||||
|
||||
/* just for the case where direct hinting did some */
|
||||
/* incredible things (e.g. blue edge shifts) */
|
||||
if ( stem->min_pos > stem->pos )
|
||||
stem->min_pos = stem->pos;
|
||||
|
||||
if ( stem->max_pos < stem->pos )
|
||||
stem->max_pos = stem->pos;
|
||||
}
|
||||
|
||||
stem->velocity = 0;
|
||||
stem->force = 0;
|
||||
|
||||
stem++;
|
||||
}
|
||||
seg = seg->edge_next;
|
||||
|
||||
} while ( seg != edge->first );
|
||||
}
|
||||
}
|
||||
|
||||
*p_stems = stems;
|
||||
*p_num_stems = num_stems;
|
||||
|
||||
edges = outline->vert_edges;
|
||||
edge_limit = edges + outline->num_vedges;
|
||||
scale = outline->x_scale;
|
||||
|
||||
p_stems = &optimizer->vert_stems;
|
||||
p_num_stems = &optimizer->num_vstems;
|
||||
}
|
||||
|
||||
Exit:
|
||||
|
||||
#ifdef AH_DEBUG_OPTIM
|
||||
AH_Dump_Stems( optimizer );
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* returns the spring area between two stems, 0 if none */
|
||||
static FT_Pos
|
||||
stem_spring_area( AH_Stem* stem1,
|
||||
AH_Stem* stem2 )
|
||||
{
|
||||
FT_Pos area1 = stem1->max_coord - stem1->min_coord;
|
||||
FT_Pos area2 = stem2->max_coord - stem2->min_coord;
|
||||
FT_Pos min = stem1->min_coord;
|
||||
FT_Pos max = stem1->max_coord;
|
||||
FT_Pos area;
|
||||
|
||||
|
||||
/* order stems */
|
||||
if ( stem2->opos <= stem1->opos + stem1->owidth )
|
||||
return 0;
|
||||
|
||||
if ( min < stem2->min_coord )
|
||||
min = stem2->min_coord;
|
||||
|
||||
if ( max < stem2->max_coord )
|
||||
max = stem2->max_coord;
|
||||
|
||||
area = ( max-min );
|
||||
if ( 2 * area < area1 && 2 * area < area2 )
|
||||
area = 0;
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
/* compute all springs in an outline */
|
||||
static int
|
||||
optim_compute_springs( AH_Optimizer* optimizer )
|
||||
{
|
||||
/* basically, a spring exists between two stems if most of their */
|
||||
/* surface is aligned */
|
||||
FT_Memory memory = optimizer->memory;
|
||||
|
||||
AH_Stem* stems;
|
||||
AH_Stem* stem_limit;
|
||||
AH_Stem* stem;
|
||||
int dimension;
|
||||
int error = 0;
|
||||
|
||||
FT_Int* p_num_springs;
|
||||
AH_Spring** p_springs;
|
||||
|
||||
|
||||
stems = optimizer->horz_stems;
|
||||
stem_limit = stems + optimizer->num_hstems;
|
||||
|
||||
p_springs = &optimizer->horz_springs;
|
||||
p_num_springs = &optimizer->num_hsprings;
|
||||
|
||||
for ( dimension = 1; dimension >= 0; dimension-- )
|
||||
{
|
||||
FT_Int num_springs = 0;
|
||||
AH_Spring* springs = 0;
|
||||
|
||||
|
||||
/* first of all, count stem springs */
|
||||
for ( stem = stems; stem + 1 < stem_limit; stem++ )
|
||||
{
|
||||
AH_Stem* stem2;
|
||||
|
||||
|
||||
for ( stem2 = stem+1; stem2 < stem_limit; stem2++ )
|
||||
if ( stem_spring_area( stem, stem2 ) )
|
||||
num_springs++;
|
||||
}
|
||||
|
||||
/* then allocate and build the springs table */
|
||||
if ( num_springs > 0 )
|
||||
{
|
||||
AH_Spring* spring;
|
||||
|
||||
|
||||
/* allocate table of springs */
|
||||
if ( ALLOC_ARRAY( springs, num_springs, AH_Spring ) )
|
||||
goto Exit;
|
||||
|
||||
/* fill the springs table */
|
||||
spring = springs;
|
||||
for ( stem = stems; stem+1 < stem_limit; stem++ )
|
||||
{
|
||||
AH_Stem* stem2;
|
||||
FT_Pos area;
|
||||
|
||||
|
||||
for ( stem2 = stem + 1; stem2 < stem_limit; stem2++ )
|
||||
{
|
||||
area = stem_spring_area( stem, stem2 );
|
||||
if ( area )
|
||||
{
|
||||
/* add a new spring here */
|
||||
spring->stem1 = stem;
|
||||
spring->stem2 = stem2;
|
||||
spring->owidth = stem2->opos - ( stem->opos + stem->owidth );
|
||||
spring->tension = 0;
|
||||
|
||||
spring++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*p_num_springs = num_springs;
|
||||
*p_springs = springs;
|
||||
|
||||
stems = optimizer->vert_stems;
|
||||
stem_limit = stems + optimizer->num_vstems;
|
||||
|
||||
p_springs = &optimizer->vert_springs;
|
||||
p_num_springs = &optimizer->num_vsprings;
|
||||
}
|
||||
|
||||
Exit:
|
||||
|
||||
#ifdef AH_DEBUG_OPTIM
|
||||
AH_Dump_Springs( optimizer );
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** OPTIMIZE THROUGH MY STRANGE SIMULATED ANNEALING ALGO ;-) ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef AH_BRUTE_FORCE
|
||||
|
||||
/* compute all spring tensions */
|
||||
static void
|
||||
optim_compute_tensions( AH_Optimizer* optimizer )
|
||||
{
|
||||
AH_Spring* spring = optimizer->springs;
|
||||
AH_Spring* limit = spring + optimizer->num_springs;
|
||||
|
||||
|
||||
for ( ; spring < limit; spring++ )
|
||||
{
|
||||
AH_Stem* stem1 = spring->stem1;
|
||||
AH_Stem* stem2 = spring->stem2;
|
||||
FT_Int status;
|
||||
|
||||
FT_Pos width;
|
||||
FT_Pos tension;
|
||||
FT_Pos sign;
|
||||
|
||||
|
||||
/* compute the tension; it simply is -K*(new_width-old_width) */
|
||||
width = stem2->pos - ( stem1->pos + stem1->width );
|
||||
tension = width - spring->owidth;
|
||||
|
||||
sign = 1;
|
||||
if ( tension < 0 )
|
||||
{
|
||||
sign = -1;
|
||||
tension = -tension;
|
||||
}
|
||||
|
||||
if ( width <= 0 )
|
||||
tension = 32000;
|
||||
else
|
||||
tension = ( tension << 10 ) / width;
|
||||
|
||||
tension = -sign * FT_MulFix( tension, optimizer->tension_scale );
|
||||
spring->tension = tension;
|
||||
|
||||
/* now, distribute tension among the englobing stems, if they */
|
||||
/* are able to move */
|
||||
status = 0;
|
||||
if ( stem1->pos <= stem1->min_pos )
|
||||
status |= 1;
|
||||
if ( stem2->pos >= stem2->max_pos )
|
||||
status |= 2;
|
||||
|
||||
if ( !status )
|
||||
tension /= 2;
|
||||
|
||||
if ( ( status & 1 ) == 0 )
|
||||
stem1->force -= tension;
|
||||
|
||||
if ( ( status & 2 ) == 0 )
|
||||
stem2->force += tension;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* compute all stem movements -- returns 0 if nothing moved */
|
||||
static int
|
||||
optim_compute_stem_movements( AH_Optimizer* optimizer )
|
||||
{
|
||||
AH_Stem* stems = optimizer->stems;
|
||||
AH_Stem* limit = stems + optimizer->num_stems;
|
||||
AH_Stem* stem = stems;
|
||||
int moved = 0;
|
||||
|
||||
|
||||
/* set initial forces to velocity */
|
||||
for ( stem = stems; stem < limit; stem++ )
|
||||
{
|
||||
stem->force = stem->velocity;
|
||||
stem->velocity /= 2; /* XXX: Heuristics */
|
||||
}
|
||||
|
||||
/* compute the sum of forces applied on each stem */
|
||||
optim_compute_tensions( optimizer );
|
||||
|
||||
#ifdef AH_DEBUG_OPTIM
|
||||
AH_Dump_Springs( optimizer );
|
||||
AH_Dump_Stems2( optimizer );
|
||||
#endif
|
||||
|
||||
/* now, see whether something can move */
|
||||
for ( stem = stems; stem < limit; stem++ )
|
||||
{
|
||||
if ( stem->force > optimizer->tension_threshold )
|
||||
{
|
||||
/* there is enough tension to move the stem to the right */
|
||||
if ( stem->pos < stem->max_pos )
|
||||
{
|
||||
stem->pos += 64;
|
||||
stem->velocity = stem->force / 2;
|
||||
moved = 1;
|
||||
}
|
||||
else
|
||||
stem->velocity = 0;
|
||||
}
|
||||
else if ( stem->force < optimizer->tension_threshold )
|
||||
{
|
||||
/* there is enough tension to move the stem to the left */
|
||||
if ( stem->pos > stem->min_pos )
|
||||
{
|
||||
stem->pos -= 64;
|
||||
stem->velocity = stem->force / 2;
|
||||
moved = 1;
|
||||
}
|
||||
else
|
||||
stem->velocity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* return 0 if nothing moved */
|
||||
return moved;
|
||||
}
|
||||
|
||||
#endif /* AH_BRUTE_FORCE */
|
||||
|
||||
|
||||
/* compute current global distortion from springs */
|
||||
static FT_Pos
|
||||
optim_compute_distortion( AH_Optimizer* optimizer )
|
||||
{
|
||||
AH_Spring* spring = optimizer->springs;
|
||||
AH_Spring* limit = spring + optimizer->num_springs;
|
||||
FT_Pos distortion = 0;
|
||||
|
||||
|
||||
for ( ; spring < limit; spring++ )
|
||||
{
|
||||
AH_Stem* stem1 = spring->stem1;
|
||||
AH_Stem* stem2 = spring->stem2;
|
||||
FT_Pos width;
|
||||
|
||||
width = stem2->pos - ( stem1->pos + stem1->width );
|
||||
width -= spring->owidth;
|
||||
if ( width < 0 )
|
||||
width = -width;
|
||||
|
||||
distortion += width;
|
||||
}
|
||||
|
||||
return distortion;
|
||||
}
|
||||
|
||||
|
||||
/* record stems configuration in `best of' history */
|
||||
static void
|
||||
optim_record_configuration( AH_Optimizer* optimizer )
|
||||
{
|
||||
FT_Pos distortion;
|
||||
AH_Configuration* configs = optimizer->configs;
|
||||
AH_Configuration* limit = configs + optimizer->num_configs;
|
||||
AH_Configuration* config;
|
||||
|
||||
|
||||
distortion = optim_compute_distortion( optimizer );
|
||||
LOG(( "config distortion = %.1f ", FLOAT( distortion * 64 ) ));
|
||||
|
||||
/* check that we really need to add this configuration to our */
|
||||
/* sorted history */
|
||||
if ( limit > configs && limit[-1].distortion < distortion )
|
||||
{
|
||||
LOG(( "ejected\n" ));
|
||||
return;
|
||||
}
|
||||
|
||||
/* add new configuration at the end of the table */
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
config = limit;
|
||||
if ( optimizer->num_configs < AH_MAX_CONFIGS )
|
||||
optimizer->num_configs++;
|
||||
else
|
||||
config--;
|
||||
|
||||
config->distortion = distortion;
|
||||
|
||||
for ( n = 0; n < optimizer->num_stems; n++ )
|
||||
config->positions[n] = optimizer->stems[n].pos;
|
||||
}
|
||||
|
||||
/* move the current configuration towards the front of the list */
|
||||
/* when necessary -- yes this is slow bubble sort ;-) */
|
||||
while ( config > configs && config[0].distortion < config[-1].distortion )
|
||||
{
|
||||
AH_Configuration temp;
|
||||
|
||||
|
||||
config--;
|
||||
temp = config[0];
|
||||
config[0] = config[1];
|
||||
config[1] = temp;
|
||||
}
|
||||
LOG(( "recorded!\n" ));
|
||||
}
|
||||
|
||||
|
||||
#ifdef AH_BRUTE_FORCE
|
||||
|
||||
/* optimize outline in a single direction */
|
||||
static void
|
||||
optim_compute( AH_Optimizer* optimizer )
|
||||
{
|
||||
int n;
|
||||
FT_Bool moved;
|
||||
|
||||
AH_Stem* stem = optimizer->stems;
|
||||
AH_Stem* limit = stem + optimizer->num_stems;
|
||||
|
||||
|
||||
/* empty, exit */
|
||||
if ( stem >= limit )
|
||||
return;
|
||||
|
||||
optimizer->num_configs = 0;
|
||||
|
||||
stem = optimizer->stems;
|
||||
for ( ; stem < limit; stem++ )
|
||||
stem->pos = stem->min_pos;
|
||||
|
||||
do
|
||||
{
|
||||
/* record current configuration */
|
||||
optim_record_configuration( optimizer );
|
||||
|
||||
/* now change configuration */
|
||||
moved = 0;
|
||||
for ( stem = optimizer->stems; stem < limit; stem++ )
|
||||
{
|
||||
if ( stem->pos < stem->max_pos )
|
||||
{
|
||||
stem->pos += 64;
|
||||
moved = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
stem->pos = stem->min_pos;
|
||||
}
|
||||
} while ( moved );
|
||||
|
||||
/* now, set the best stem positions */
|
||||
for ( n = 0; n < optimizer->num_stems; n++ )
|
||||
{
|
||||
AH_Stem* stem = optimizer->stems + n;
|
||||
FT_Pos pos = optimizer->configs[0].positions[n];
|
||||
|
||||
|
||||
stem->edge1->pos = pos;
|
||||
stem->edge2->pos = pos + stem->width;
|
||||
|
||||
stem->edge1->flags |= ah_edge_done;
|
||||
stem->edge2->flags |= ah_edge_done;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* AH_BRUTE_FORCE */
|
||||
|
||||
/* optimize outline in a single direction */
|
||||
static void
|
||||
optim_compute( AH_Optimizer* optimizer )
|
||||
{
|
||||
int n, counter, counter2;
|
||||
|
||||
|
||||
optimizer->num_configs = 0;
|
||||
optimizer->tension_scale = 0x80000L;
|
||||
optimizer->tension_threshold = 64;
|
||||
|
||||
/* record initial configuration threshold */
|
||||
optim_record_configuration( optimizer );
|
||||
|
||||
counter = 0;
|
||||
for ( counter2 = optimizer->num_stems*8; counter2 >= 0; counter2-- )
|
||||
{
|
||||
if ( counter == 0 )
|
||||
counter = 2 * optimizer->num_stems;
|
||||
|
||||
if ( !optim_compute_stem_movements( optimizer ) )
|
||||
break;
|
||||
|
||||
optim_record_configuration( optimizer );
|
||||
|
||||
counter--;
|
||||
if ( counter == 0 )
|
||||
optimizer->tension_scale /= 2;
|
||||
}
|
||||
|
||||
/* now, set the best stem positions */
|
||||
for ( n = 0; n < optimizer->num_stems; n++ )
|
||||
{
|
||||
AH_Stem* stem = optimizer->stems + n;
|
||||
FT_Pos pos = optimizer->configs[0].positions[n];
|
||||
|
||||
|
||||
stem->edge1->pos = pos;
|
||||
stem->edge2->pos = pos + stem->width;
|
||||
|
||||
stem->edge1->flags |= ah_edge_done;
|
||||
stem->edge2->flags |= ah_edge_done;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* AH_BRUTE_FORCE */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** HIGH-LEVEL OPTIMIZER API ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* releases the optimization data */
|
||||
void
|
||||
AH_Optimizer_Done( AH_Optimizer* optimizer )
|
||||
{
|
||||
if ( optimizer )
|
||||
{
|
||||
FT_Memory memory = optimizer->memory;
|
||||
|
||||
|
||||
FREE( optimizer->horz_stems );
|
||||
FREE( optimizer->vert_stems );
|
||||
FREE( optimizer->horz_springs );
|
||||
FREE( optimizer->vert_springs );
|
||||
FREE( optimizer->positions );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* loads the outline into the optimizer */
|
||||
int
|
||||
AH_Optimizer_Init( AH_Optimizer* optimizer,
|
||||
AH_Outline* outline,
|
||||
FT_Memory memory )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
MEM_Set( optimizer, 0, sizeof ( *optimizer ) );
|
||||
optimizer->outline = outline;
|
||||
optimizer->memory = memory;
|
||||
|
||||
LOG(( "initializing new optimizer\n" ));
|
||||
/* compute stems and springs */
|
||||
error = optim_compute_stems ( optimizer ) ||
|
||||
optim_compute_springs( optimizer );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
|
||||
/* allocate stem positions history and configurations */
|
||||
{
|
||||
int n, max_stems;
|
||||
|
||||
|
||||
max_stems = optimizer->num_hstems;
|
||||
if ( max_stems < optimizer->num_vstems )
|
||||
max_stems = optimizer->num_vstems;
|
||||
|
||||
if ( ALLOC_ARRAY( optimizer->positions,
|
||||
max_stems * AH_MAX_CONFIGS, FT_Pos ) )
|
||||
goto Fail;
|
||||
|
||||
optimizer->num_configs = 0;
|
||||
for ( n = 0; n < AH_MAX_CONFIGS; n++ )
|
||||
optimizer->configs[n].positions = optimizer->positions +
|
||||
n * max_stems;
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
Fail:
|
||||
AH_Optimizer_Done( optimizer );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* compute optimal outline */
|
||||
void
|
||||
AH_Optimizer_Compute( AH_Optimizer* optimizer )
|
||||
{
|
||||
optimizer->num_stems = optimizer->num_hstems;
|
||||
optimizer->stems = optimizer->horz_stems;
|
||||
optimizer->num_springs = optimizer->num_hsprings;
|
||||
optimizer->springs = optimizer->horz_springs;
|
||||
|
||||
if ( optimizer->num_springs > 0 )
|
||||
{
|
||||
LOG(( "horizontal optimization ------------------------\n" ));
|
||||
optim_compute( optimizer );
|
||||
}
|
||||
|
||||
optimizer->num_stems = optimizer->num_vstems;
|
||||
optimizer->stems = optimizer->vert_stems;
|
||||
optimizer->num_springs = optimizer->num_vsprings;
|
||||
optimizer->springs = optimizer->vert_springs;
|
||||
|
||||
if ( optimizer->num_springs )
|
||||
{
|
||||
LOG(( "vertical optimization --------------------------\n" ));
|
||||
optim_compute( optimizer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,505 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ahtypes.h */
|
||||
/* */
|
||||
/* General types and definitions for the auto-hint module */
|
||||
/* (specification only). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
/* be used, modified, and distributed under the terms of the Catharon */
|
||||
/* Open Source License that should come with this file under the name */
|
||||
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/* Note that this license is compatible with the FreeType license. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __AHTYPES_H__
|
||||
#define __AHTYPES_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
#include <../src/autohint/ahloader.h>
|
||||
#else
|
||||
#include "ahloader.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define xxAH_DEBUG
|
||||
|
||||
|
||||
#ifdef AH_DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
#define AH_LOG( x ) printf ## x
|
||||
|
||||
#else
|
||||
|
||||
#define AH_LOG( x ) do ; while ( 0 ) /* nothing */
|
||||
|
||||
#endif /* AH_DEBUG */
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** COMPILE-TIME BUILD OPTIONS ****/
|
||||
/**** ****/
|
||||
/**** Toggle these configuration macros to experiment with `features' ****/
|
||||
/**** of the auto-hinter. ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* If this option is defined, only strong interpolation will be used to */
|
||||
/* place the points between edges. Otherwise, `smooth' points are */
|
||||
/* detected and later hinted through weak interpolation to correct some */
|
||||
/* unpleasant artefacts. */
|
||||
/* */
|
||||
#undef AH_OPTION_NO_WEAK_INTERPOLATION
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* If this option is defined, only weak interpolation will be used to */
|
||||
/* place the points between edges. Otherwise, `strong' points are */
|
||||
/* detected and later hinted through strong interpolation to correct */
|
||||
/* some unpleasant artefacts. */
|
||||
/* */
|
||||
#undef AH_OPTION_NO_STRONG_INTERPOLATION
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Undefine this macro if you don't want to hint the metrics. There is */
|
||||
/* no reason to do this (at least for non-CJK scripts), except for */
|
||||
/* experimentation. */
|
||||
/* */
|
||||
#define AH_HINT_METRICS
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Define this macro if you do not want to insert extra edges at a */
|
||||
/* glyph's x and y extremum (if there isn't one already available). */
|
||||
/* This helps to reduce a number of artefacts and allows hinting of */
|
||||
/* metrics. */
|
||||
/* */
|
||||
#undef AH_OPTION_NO_EXTREMUM_EDGES
|
||||
|
||||
|
||||
/* don't touch for now */
|
||||
#define AH_MAX_WIDTHS 12
|
||||
#define AH_MAX_HEIGHTS 12
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** TYPE DEFINITIONS ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* see agangles.h */
|
||||
typedef FT_Int AH_Angle;
|
||||
|
||||
|
||||
/* hint flags */
|
||||
#define ah_flag_none 0
|
||||
|
||||
/* bezier control points flags */
|
||||
#define ah_flag_conic 1
|
||||
#define ah_flag_cubic 2
|
||||
#define ah_flag_control ( ah_flag_conic | ah_flag_cubic )
|
||||
|
||||
/* extrema flags */
|
||||
#define ah_flag_extrema_x 4
|
||||
#define ah_flag_extrema_y 8
|
||||
|
||||
/* roundness */
|
||||
#define ah_flag_round_x 16
|
||||
#define ah_flag_round_y 32
|
||||
|
||||
/* touched */
|
||||
#define ah_flag_touch_x 64
|
||||
#define ah_flag_touch_y 128
|
||||
|
||||
/* weak interpolation */
|
||||
#define ah_flag_weak_interpolation 256
|
||||
|
||||
typedef FT_Int AH_Flags;
|
||||
|
||||
|
||||
/* edge hint flags */
|
||||
#define ah_edge_normal 0
|
||||
#define ah_edge_round 1
|
||||
#define ah_edge_serif 2
|
||||
#define ah_edge_done 4
|
||||
|
||||
typedef FT_Int AH_Edge_Flags;
|
||||
|
||||
|
||||
/* hint directions -- the values are computed so that two vectors are */
|
||||
/* in opposite directions iff `dir1+dir2 == 0' */
|
||||
#define ah_dir_none 4
|
||||
#define ah_dir_right 1
|
||||
#define ah_dir_left -1
|
||||
#define ah_dir_up 2
|
||||
#define ah_dir_down -2
|
||||
|
||||
typedef FT_Int AH_Direction;
|
||||
|
||||
|
||||
typedef struct AH_Point AH_Point;
|
||||
typedef struct AH_Segment AH_Segment;
|
||||
typedef struct AH_Edge AH_Edge;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Struct> */
|
||||
/* AH_Point */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A structure used to model an outline point to the AH_Outline type. */
|
||||
/* */
|
||||
/* <Fields> */
|
||||
/* flags :: The current point hint flags. */
|
||||
/* */
|
||||
/* ox, oy :: The current original scaled coordinates. */
|
||||
/* */
|
||||
/* fx, fy :: The current coordinates in font units. */
|
||||
/* */
|
||||
/* x, y :: The current hinted coordinates. */
|
||||
/* */
|
||||
/* u, v :: Point coordinates -- meaning varies with context. */
|
||||
/* */
|
||||
/* in_dir :: The direction of the inwards vector (prev->point). */
|
||||
/* */
|
||||
/* out_dir :: The direction of the outwards vector (point->next). */
|
||||
/* */
|
||||
/* in_angle :: The angle of the inwards vector. */
|
||||
/* */
|
||||
/* out_angle :: The angle of the outwards vector. */
|
||||
/* */
|
||||
/* next :: The next point in same contour. */
|
||||
/* */
|
||||
/* prev :: The previous point in same contour. */
|
||||
/* */
|
||||
struct AH_Point
|
||||
{
|
||||
AH_Flags flags; /* point flags used by hinter */
|
||||
FT_Pos ox, oy;
|
||||
FT_Pos fx, fy;
|
||||
FT_Pos x, y;
|
||||
FT_Pos u, v;
|
||||
|
||||
AH_Direction in_dir; /* direction of inwards vector */
|
||||
AH_Direction out_dir; /* direction of outwards vector */
|
||||
|
||||
AH_Angle in_angle;
|
||||
AH_Angle out_angle;
|
||||
|
||||
AH_Point* next; /* next point in contour */
|
||||
AH_Point* prev; /* previous point in contour */
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Struct> */
|
||||
/* AH_Segment */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A structure used to describe an edge segment to the auto-hinter. */
|
||||
/* A segment is simply a sequence of successive points located on the */
|
||||
/* same horizontal or vertical `position', in a given direction. */
|
||||
/* */
|
||||
/* <Fields> */
|
||||
/* flags :: The segment edge flags (straight, rounded, etc.). */
|
||||
/* */
|
||||
/* dir :: The segment direction. */
|
||||
/* */
|
||||
/* first :: The first point in the segment. */
|
||||
/* */
|
||||
/* last :: The last point in the segment. */
|
||||
/* */
|
||||
/* contour :: A pointer to the first point of the segment's */
|
||||
/* contour. */
|
||||
/* */
|
||||
/* pos :: The segment position in font units. */
|
||||
/* */
|
||||
/* size :: The segment size. */
|
||||
/* */
|
||||
/* edge :: The edge of the current segment. */
|
||||
/* */
|
||||
/* edge_next :: The next segment on the same edge. */
|
||||
/* */
|
||||
/* link :: The pairing segment for this edge. */
|
||||
/* */
|
||||
/* serif :: The primary segment for serifs. */
|
||||
/* */
|
||||
/* num_linked :: The number of other segments that link to this one. */
|
||||
/* */
|
||||
/* score :: Used to score the segment when selecting them. */
|
||||
/* */
|
||||
struct AH_Segment
|
||||
{
|
||||
AH_Edge_Flags flags;
|
||||
AH_Direction dir;
|
||||
|
||||
AH_Point* first; /* first point in edge segment */
|
||||
AH_Point* last; /* last point in edge segment */
|
||||
AH_Point** contour; /* ptr to first point of segment's contour */
|
||||
|
||||
FT_Pos pos; /* position of segment */
|
||||
FT_Pos min_coord; /* minimum coordinate of segment */
|
||||
FT_Pos max_coord; /* maximum coordinate of segment */
|
||||
|
||||
AH_Edge* edge;
|
||||
AH_Segment* edge_next;
|
||||
|
||||
AH_Segment* link; /* link segment */
|
||||
AH_Segment* serif; /* primary segment for serifs */
|
||||
FT_Pos num_linked; /* number of linked segments */
|
||||
FT_Int score;
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Struct> */
|
||||
/* AH_Edge */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A structure used to describe an edge, which really is a horizontal */
|
||||
/* or vertical coordinate to be hinted depending on the segments */
|
||||
/* located on it. */
|
||||
/* */
|
||||
/* <Fields> */
|
||||
/* flags :: The segment edge flags (straight, rounded, etc.). */
|
||||
/* */
|
||||
/* dir :: The main segment direction on this edge. */
|
||||
/* */
|
||||
/* first :: The first edge segment. */
|
||||
/* */
|
||||
/* last :: The last edge segment. */
|
||||
/* */
|
||||
/* fpos :: The original edge position in font units. */
|
||||
/* */
|
||||
/* opos :: The original scaled edge position. */
|
||||
/* */
|
||||
/* pos :: The hinted edge position. */
|
||||
/* */
|
||||
/* link :: The linked edge. */
|
||||
/* */
|
||||
/* serif :: The serif edge. */
|
||||
/* */
|
||||
/* num_paired :: The number of other edges that pair to this one. */
|
||||
/* */
|
||||
/* score :: Used to score the edge when selecting them. */
|
||||
/* */
|
||||
/* blue_edge :: Indicate the blue zone edge this edge is related to. */
|
||||
/* Only set for some of the horizontal edges in a Latin */
|
||||
/* font. */
|
||||
/* */
|
||||
struct AH_Edge
|
||||
{
|
||||
AH_Edge_Flags flags;
|
||||
AH_Direction dir;
|
||||
|
||||
AH_Segment* first;
|
||||
AH_Segment* last;
|
||||
|
||||
FT_Pos fpos;
|
||||
FT_Pos opos;
|
||||
FT_Pos pos;
|
||||
|
||||
AH_Edge* link;
|
||||
AH_Edge* serif;
|
||||
FT_Int num_linked;
|
||||
|
||||
FT_Int score;
|
||||
FT_Pos* blue_edge;
|
||||
};
|
||||
|
||||
|
||||
/* an outline as seen by the hinter */
|
||||
typedef struct AH_Outline_
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
AH_Direction vert_major_dir; /* vertical major direction */
|
||||
AH_Direction horz_major_dir; /* horizontal major direction */
|
||||
|
||||
FT_Fixed x_scale;
|
||||
FT_Fixed y_scale;
|
||||
FT_Pos edge_distance_threshold;
|
||||
|
||||
FT_Int max_points;
|
||||
FT_Int num_points;
|
||||
AH_Point* points;
|
||||
|
||||
FT_Int max_contours;
|
||||
FT_Int num_contours;
|
||||
AH_Point** contours;
|
||||
|
||||
FT_Int num_hedges;
|
||||
AH_Edge* horz_edges;
|
||||
|
||||
FT_Int num_vedges;
|
||||
AH_Edge* vert_edges;
|
||||
|
||||
FT_Int num_hsegments;
|
||||
AH_Segment* horz_segments;
|
||||
|
||||
FT_Int num_vsegments;
|
||||
AH_Segment* vert_segments;
|
||||
|
||||
} AH_Outline;
|
||||
|
||||
|
||||
#define ah_blue_capital_top 0 /* THEZOCQS */
|
||||
#define ah_blue_capital_bottom ( ah_blue_capital_top + 1 ) /* HEZLOCUS */
|
||||
#define ah_blue_small_top ( ah_blue_capital_bottom + 1 ) /* xzroesc */
|
||||
#define ah_blue_small_bottom ( ah_blue_small_top + 1 ) /* xzroesc */
|
||||
#define ah_blue_small_minor ( ah_blue_small_bottom + 1 ) /* pqgjy */
|
||||
#define ah_blue_max ( ah_blue_small_minor + 1 )
|
||||
|
||||
typedef FT_Int AH_Blue;
|
||||
|
||||
|
||||
#define ah_hinter_monochrome 1
|
||||
#define ah_hinter_optimize 2
|
||||
|
||||
typedef FT_Int AH_Hinter_Flags;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Struct> */
|
||||
/* AH_Globals */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Holds the global metrics for a given font face (be it in design */
|
||||
/* units or scaled pixel values). */
|
||||
/* */
|
||||
/* <Fields> */
|
||||
/* num_widths :: The number of widths. */
|
||||
/* */
|
||||
/* num_heights :: The number of heights. */
|
||||
/* */
|
||||
/* widths :: Snap widths, including standard one. */
|
||||
/* */
|
||||
/* heights :: Snap height, including standard one. */
|
||||
/* */
|
||||
/* blue_refs :: The reference positions of blue zones. */
|
||||
/* */
|
||||
/* blue_shoots :: The overshoot positions of blue zones. */
|
||||
/* */
|
||||
typedef struct AH_Globals_
|
||||
{
|
||||
FT_Int num_widths;
|
||||
FT_Int num_heights;
|
||||
|
||||
FT_Pos widths [AH_MAX_WIDTHS];
|
||||
FT_Pos heights[AH_MAX_HEIGHTS];
|
||||
|
||||
FT_Pos blue_refs [ah_blue_max];
|
||||
FT_Pos blue_shoots[ah_blue_max];
|
||||
|
||||
} AH_Globals;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Struct> */
|
||||
/* AH_Face_Globals */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Holds the complete global metrics for a given font face (i.e., the */
|
||||
/* design units version + a scaled version + the current scales */
|
||||
/* used). */
|
||||
/* */
|
||||
/* <Fields> */
|
||||
/* face :: A handle to the source face object */
|
||||
/* */
|
||||
/* design :: The globals in font design units. */
|
||||
/* */
|
||||
/* scaled :: Scaled globals in sub-pixel values. */
|
||||
/* */
|
||||
/* x_scale :: The current horizontal scale. */
|
||||
/* */
|
||||
/* y_scale :: The current vertical scale. */
|
||||
/* */
|
||||
typedef struct AH_Face_Globals_
|
||||
{
|
||||
FT_Face face;
|
||||
AH_Globals design;
|
||||
AH_Globals scaled;
|
||||
FT_Fixed x_scale;
|
||||
FT_Fixed y_scale;
|
||||
FT_Bool control_overshoot;
|
||||
|
||||
} AH_Face_Globals;
|
||||
|
||||
|
||||
typedef struct AH_Hinter
|
||||
{
|
||||
FT_Memory memory;
|
||||
AH_Hinter_Flags flags;
|
||||
|
||||
FT_Int algorithm;
|
||||
FT_Face face;
|
||||
|
||||
AH_Face_Globals* globals;
|
||||
|
||||
AH_Outline* glyph;
|
||||
|
||||
AH_Loader* loader;
|
||||
FT_Vector pp1;
|
||||
FT_Vector pp2;
|
||||
|
||||
FT_Bool transformed;
|
||||
FT_Vector trans_delta;
|
||||
FT_Matrix trans_matrix;
|
||||
|
||||
} AH_Hinter;
|
||||
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
extern AH_Hinter* ah_debug_hinter;
|
||||
extern FT_Bool ah_debug_disable_horz;
|
||||
extern FT_Bool ah_debug_disable_vert;
|
||||
#else
|
||||
# define ah_debug_disable_horz 0
|
||||
# define ah_debug_disable_vert 0
|
||||
#endif /* DEBUG_HINTER */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AHTYPES_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,25 +0,0 @@
|
|||
#
|
||||
# FreeType 2 auto-hinter module compilation rules for VMS
|
||||
#
|
||||
|
||||
|
||||
# Copyright 2001 Catharon Productions Inc.
|
||||
#
|
||||
# This file is part of the Catharon Typography Project and shall only
|
||||
# be used, modified, and distributed under the terms of the Catharon
|
||||
# Open Source License that should come with this file under the name
|
||||
# `CatharonLicense.txt'. By continuing to use, modify, or distribute
|
||||
# this file you indicate that you have read the license and
|
||||
# understand and accept it fully.
|
||||
#
|
||||
# Note that this license is compatible with the FreeType license.
|
||||
|
||||
|
||||
CFLAGS=$(COMP_FLAGS)$(DEBUG)/incl=([--.include],[--.src.autohint])
|
||||
|
||||
OBJS=autohint.obj
|
||||
|
||||
all : $(OBJS)
|
||||
library [--.lib]freetype.olb $(OBJS)
|
||||
|
||||
# EOF
|
|
@ -1,78 +0,0 @@
|
|||
#
|
||||
# FreeType 2 auto-hinter module configuration rules
|
||||
#
|
||||
|
||||
|
||||
# Copyright 2000 Catharon Productions Inc.
|
||||
# Author: David Turner
|
||||
#
|
||||
# This file is part of the Catharon Typography Project and shall only
|
||||
# be used, modified, and distributed under the terms of the Catharon
|
||||
# Open Source License that should come with this file under the name
|
||||
# `CatharonLicense.txt'. By continuing to use, modify, or distribute
|
||||
# this file you indicate that you have read the license and
|
||||
# understand and accept it fully.
|
||||
#
|
||||
# Note that this license is compatible with the FreeType license.
|
||||
|
||||
|
||||
# AUTO driver directory
|
||||
#
|
||||
AUTO_DIR := $(SRC_)autohint
|
||||
AUTO_DIR_ := $(AUTO_DIR)$(SEP)
|
||||
|
||||
|
||||
# compilation flags for the driver
|
||||
#
|
||||
AUTO_COMPILE := $(FT_COMPILE) $I$(AUTO_DIR)
|
||||
|
||||
|
||||
# AUTO driver sources (i.e., C files)
|
||||
#
|
||||
AUTO_DRV_SRC := $(AUTO_DIR_)ahangles.c \
|
||||
$(AUTO_DIR_)ahglobal.c \
|
||||
$(AUTO_DIR_)ahglyph.c \
|
||||
$(AUTO_DIR_)ahhint.c \
|
||||
$(AUTO_DIR_)ahmodule.c
|
||||
|
||||
# AUTO driver headers
|
||||
#
|
||||
AUTO_DRV_H := $(AUTO_DRV_SRC:%c=%h) \
|
||||
$(AUTO_DIR_)ahloader.h \
|
||||
$(AUTO_DIR_)ahtypes.h \
|
||||
$(AUTO_DIR_)aherrors.h
|
||||
|
||||
|
||||
# AUTO driver object(s)
|
||||
#
|
||||
# AUTO_DRV_OBJ_M is used during `multi' builds.
|
||||
# AUTO_DRV_OBJ_S is used during `single' builds.
|
||||
#
|
||||
AUTO_DRV_OBJ_M := $(AUTO_DRV_SRC:$(AUTO_DIR_)%.c=$(OBJ_)%.$O)
|
||||
AUTO_DRV_OBJ_S := $(OBJ_)autohint.$O
|
||||
|
||||
# AUTO driver source file for single build
|
||||
#
|
||||
AUTO_DRV_SRC_S := $(AUTO_DIR_)autohint.c
|
||||
|
||||
|
||||
# AUTO driver - single object
|
||||
#
|
||||
$(AUTO_DRV_OBJ_S): $(AUTO_DRV_SRC_S) $(AUTO_DRV_SRC) \
|
||||
$(FREETYPE_H) $(AUTO_DRV_H)
|
||||
$(AUTO_COMPILE) $T$@ $(AUTO_DRV_SRC_S)
|
||||
|
||||
|
||||
# AUTO driver - multiple objects
|
||||
#
|
||||
$(OBJ_)%.$O: $(AUTO_DIR_)%.c $(FREETYPE_H) $(AUTO_DRV_H)
|
||||
$(AUTO_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
# update main driver object lists
|
||||
#
|
||||
DRV_OBJS_S += $(AUTO_DRV_OBJ_S)
|
||||
DRV_OBJS_M += $(AUTO_DRV_OBJ_M)
|
||||
|
||||
|
||||
# EOF
|
|
@ -1,36 +0,0 @@
|
|||
# FreeType 2 src/base Jamfile (c) 2001 David Turner
|
||||
#
|
||||
|
||||
SubDir FT2_TOP src base ;
|
||||
|
||||
SubDirHdrs [ FT2_SubDir src base ] ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = ftcalc ftextend ftlist ftobjs ftstream ftoutln ftnames fttrigon
|
||||
ftdbgmem ;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = ftbase ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# Add the optional/replaceable files.
|
||||
#
|
||||
Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c
|
||||
ftbbox.c ftdebug.c ;
|
||||
|
||||
# Add Macintosh-specific file to the library when necessary.
|
||||
#
|
||||
if $(MAC)
|
||||
{
|
||||
Library $(FT2_LIB) : ftmac.c ;
|
||||
}
|
||||
|
||||
# end of src/base Jamfile
|
|
@ -1,36 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftbase.c */
|
||||
/* */
|
||||
/* Single object library component (body only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#include "ftcalc.c"
|
||||
#include "fttrigon.c"
|
||||
#include "ftobjs.c"
|
||||
#include "ftstream.c"
|
||||
#include "ftlist.c"
|
||||
#include "ftoutln.c"
|
||||
#include "ftnames.c"
|
||||
#include "ftdbgmem.c"
|
||||
|
||||
#if 0
|
||||
#include "ftextend.c"
|
||||
#endif
|
||||
|
||||
/* END */
|
|
@ -1,705 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftcalc.c */
|
||||
/* */
|
||||
/* Arithmetic computations (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Support for 1-complement arithmetic has been totally dropped in this */
|
||||
/* release. You can still write your own code if you need it. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Implementing basic computation routines. */
|
||||
/* */
|
||||
/* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */
|
||||
/* and FT_FloorFix() are declared in freetype.h. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_CALC_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
|
||||
/* we need to define a 64-bits data type here */
|
||||
#ifndef FT_CONFIG_OPTION_OLD_CALCS
|
||||
|
||||
#ifdef FT_LONG64
|
||||
|
||||
typedef FT_INT64 FT_Int64;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct FT_Int64_
|
||||
{
|
||||
FT_UInt32 lo;
|
||||
FT_UInt32 hi;
|
||||
|
||||
} FT_Int64;
|
||||
|
||||
#endif /* FT_LONG64 */
|
||||
|
||||
#endif /* !FT_CONFIG_OPTION_OLD_CALCS */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_calc
|
||||
|
||||
|
||||
/* The following three functions are available regardless of whether */
|
||||
/* FT_LONG64 or FT_CONFIG_OPTION_OLD_CALCS is defined. */
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_RoundFix( FT_Fixed a )
|
||||
{
|
||||
return ( a >= 0 ) ? ( a + 0x8000L ) & -0x10000L
|
||||
: -((-a + 0x8000L ) & -0x10000L );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_CeilFix( FT_Fixed a )
|
||||
{
|
||||
return ( a >= 0 ) ? ( a + 0xFFFFL ) & -0x10000L
|
||||
: -((-a + 0xFFFFL ) & -0x10000L );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_FloorFix( FT_Fixed a )
|
||||
{
|
||||
return ( a >= 0 ) ? a & -0x10000L
|
||||
: -((-a) & -0x10000L );
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_OLD_CALCS
|
||||
|
||||
static const FT_Long ft_square_roots[63] =
|
||||
{
|
||||
1L, 1L, 2L, 3L, 4L, 5L, 8L, 11L,
|
||||
16L, 22L, 32L, 45L, 64L, 90L, 128L, 181L,
|
||||
256L, 362L, 512L, 724L, 1024L, 1448L, 2048L, 2896L,
|
||||
4096L, 5892L, 8192L, 11585L, 16384L, 23170L, 32768L, 46340L,
|
||||
|
||||
65536L, 92681L, 131072L, 185363L, 262144L, 370727L,
|
||||
524288L, 741455L, 1048576L, 1482910L, 2097152L, 2965820L,
|
||||
4194304L, 5931641L, 8388608L, 11863283L, 16777216L, 23726566L,
|
||||
|
||||
33554432L, 47453132L, 67108864L, 94906265L,
|
||||
134217728L, 189812531L, 268435456L, 379625062L,
|
||||
536870912L, 759250125L, 1073741824L, 1518500250L,
|
||||
2147483647L
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
/* documentation is in ftcalc.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Int32 )
|
||||
FT_Sqrt32( FT_Int32 x )
|
||||
{
|
||||
FT_ULong val, root, newroot, mask;
|
||||
|
||||
|
||||
root = 0;
|
||||
mask = 0x40000000L;
|
||||
val = (FT_ULong)x;
|
||||
|
||||
do
|
||||
{
|
||||
newroot = root + mask;
|
||||
if ( newroot <= val )
|
||||
{
|
||||
val -= newroot;
|
||||
root = newroot + mask;
|
||||
}
|
||||
|
||||
root >>= 1;
|
||||
mask >>= 2;
|
||||
|
||||
} while ( mask != 0 );
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_OLD_CALCS */
|
||||
|
||||
|
||||
#ifdef FT_LONG64
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Long )
|
||||
FT_MulDiv( FT_Long a,
|
||||
FT_Long b,
|
||||
FT_Long c )
|
||||
{
|
||||
FT_Int s;
|
||||
FT_Long d;
|
||||
|
||||
|
||||
s = 1;
|
||||
if ( a < 0 ) { a = -a; s = -1; }
|
||||
if ( b < 0 ) { b = -b; s = -s; }
|
||||
if ( c < 0 ) { c = -c; s = -s; }
|
||||
|
||||
d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c
|
||||
: 0x7FFFFFFFL );
|
||||
|
||||
return ( s > 0 ) ? d : -d;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Long )
|
||||
FT_MulFix( FT_Long a,
|
||||
FT_Long b )
|
||||
{
|
||||
FT_Int s = 1;
|
||||
FT_Long c;
|
||||
|
||||
|
||||
if ( a < 0 ) { a = -a; s = -1; }
|
||||
if ( b < 0 ) { b = -b; s = -s; }
|
||||
|
||||
c = (FT_Long)( ( (FT_Int64)a * b + 0x8000 ) >> 16 );
|
||||
return ( s > 0 ) ? c : -c ;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Long )
|
||||
FT_DivFix( FT_Long a,
|
||||
FT_Long b )
|
||||
{
|
||||
FT_Int32 s;
|
||||
FT_UInt32 q;
|
||||
|
||||
s = 1;
|
||||
if ( a < 0 ) { a = -a; s = -1; }
|
||||
if ( b < 0 ) { b = -b; s = -s; }
|
||||
|
||||
if ( b == 0 )
|
||||
/* check for division by 0 */
|
||||
q = 0x7FFFFFFFL;
|
||||
else
|
||||
/* compute result directly */
|
||||
q = (FT_UInt32)( ( ( (FT_Int64)a << 16 ) + ( b >> 1 ) ) / b );
|
||||
|
||||
return ( s < 0 ? -(FT_Long)q : (FT_Long)q );
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_OLD_CALCS
|
||||
|
||||
/* a helper function for FT_Sqrt64() */
|
||||
|
||||
static int
|
||||
ft_order64( FT_Int64 z )
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
|
||||
while ( z )
|
||||
{
|
||||
z = (unsigned FT_INT64)z >> 1;
|
||||
j++;
|
||||
}
|
||||
return j - 1;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcalc.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Int32 )
|
||||
FT_Sqrt64( FT_Int64 l )
|
||||
{
|
||||
FT_Int64 r, s;
|
||||
|
||||
|
||||
if ( l <= 0 ) return 0;
|
||||
if ( l == 1 ) return 1;
|
||||
|
||||
r = ft_square_roots[ft_order64( l )];
|
||||
|
||||
do
|
||||
{
|
||||
s = r;
|
||||
r = ( r + l / r ) >> 1;
|
||||
|
||||
} while ( r > s || r * r > l );
|
||||
|
||||
return (FT_Int32)r;
|
||||
}
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_OLD_CALCS */
|
||||
|
||||
|
||||
#else /* FT_LONG64 */
|
||||
|
||||
|
||||
static void
|
||||
ft_multo64( FT_UInt32 x,
|
||||
FT_UInt32 y,
|
||||
FT_Int64 *z )
|
||||
{
|
||||
FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2;
|
||||
|
||||
|
||||
lo1 = x & 0x0000FFFFU; hi1 = x >> 16;
|
||||
lo2 = y & 0x0000FFFFU; hi2 = y >> 16;
|
||||
|
||||
lo = lo1 * lo2;
|
||||
i1 = lo1 * hi2;
|
||||
i2 = lo2 * hi1;
|
||||
hi = hi1 * hi2;
|
||||
|
||||
/* Check carry overflow of i1 + i2 */
|
||||
i1 += i2;
|
||||
hi += (FT_UInt32)( i1 < i2 ) << 16;
|
||||
|
||||
hi += i1 >> 16;
|
||||
i1 = i1 << 16;
|
||||
|
||||
/* Check carry overflow of i1 + lo */
|
||||
lo += i1;
|
||||
hi += ( lo < i1 );
|
||||
|
||||
z->lo = lo;
|
||||
z->hi = hi;
|
||||
}
|
||||
|
||||
|
||||
static FT_UInt32
|
||||
ft_div64by32( FT_UInt32 hi,
|
||||
FT_UInt32 lo,
|
||||
FT_UInt32 y )
|
||||
{
|
||||
FT_UInt32 r, q;
|
||||
FT_Int i;
|
||||
|
||||
|
||||
q = 0;
|
||||
r = hi;
|
||||
|
||||
if ( r >= y )
|
||||
return (FT_UInt32)0x7FFFFFFFL;
|
||||
|
||||
i = 32;
|
||||
do
|
||||
{
|
||||
r <<= 1;
|
||||
q <<= 1;
|
||||
r |= lo >> 31;
|
||||
|
||||
if ( r >= (FT_UInt32)y )
|
||||
{
|
||||
r -= y;
|
||||
q |= 1;
|
||||
}
|
||||
lo <<= 1;
|
||||
} while ( --i );
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcalc.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Add64( FT_Int64* x,
|
||||
FT_Int64* y,
|
||||
FT_Int64 *z )
|
||||
{
|
||||
register FT_UInt32 lo, hi, max;
|
||||
|
||||
|
||||
max = x->lo > y->lo ? x->lo : y->lo;
|
||||
lo = x->lo + y->lo;
|
||||
hi = x->hi + y->hi + ( lo < max );
|
||||
|
||||
z->lo = lo;
|
||||
z->hi = hi;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Long )
|
||||
FT_MulDiv( FT_Long a,
|
||||
FT_Long b,
|
||||
FT_Long c )
|
||||
{
|
||||
long s;
|
||||
|
||||
|
||||
if ( a == 0 || b == c )
|
||||
return a;
|
||||
|
||||
s = a; a = ABS( a );
|
||||
s ^= b; b = ABS( b );
|
||||
s ^= c; c = ABS( c );
|
||||
|
||||
if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 )
|
||||
{
|
||||
a = ( a * b + ( c >> 1 ) ) / c;
|
||||
}
|
||||
else if ( c > 0 )
|
||||
{
|
||||
FT_Int64 temp, temp2;
|
||||
|
||||
|
||||
ft_multo64( a, b, &temp );
|
||||
|
||||
temp2.hi = 0;
|
||||
temp2.lo = (FT_UInt32)(c >> 1);
|
||||
FT_Add64( &temp, &temp2, &temp );
|
||||
a = ft_div64by32( temp.hi, temp.lo, c );
|
||||
}
|
||||
else
|
||||
a = 0x7FFFFFFFL;
|
||||
|
||||
return ( s < 0 ? -a : a );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Long )
|
||||
FT_MulFix( FT_Long a,
|
||||
FT_Long b )
|
||||
{
|
||||
FT_Long s;
|
||||
FT_ULong ua, ub;
|
||||
|
||||
|
||||
if ( a == 0 || b == 0x10000L )
|
||||
return a;
|
||||
|
||||
s = a; a = ABS(a);
|
||||
s ^= b; b = ABS(b);
|
||||
|
||||
ua = (FT_ULong)a;
|
||||
ub = (FT_ULong)b;
|
||||
|
||||
if ( ua <= 2048 && ub <= 1048576L )
|
||||
{
|
||||
ua = ( ua * ub + 0x8000 ) >> 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_ULong al = ua & 0xFFFF;
|
||||
|
||||
|
||||
ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) +
|
||||
( ( al * ( ub & 0xFFFF ) + 0x8000 ) >> 16 );
|
||||
}
|
||||
|
||||
return ( s < 0 ? -(FT_Long)ua : ua );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Long )
|
||||
FT_DivFix( FT_Long a,
|
||||
FT_Long b )
|
||||
{
|
||||
FT_Int32 s;
|
||||
FT_UInt32 q;
|
||||
|
||||
|
||||
s = a; a = ABS(a);
|
||||
s ^= b; b = ABS(b);
|
||||
|
||||
if ( b == 0 )
|
||||
{
|
||||
/* check for division by 0 */
|
||||
q = 0x7FFFFFFFL;
|
||||
}
|
||||
else if ( ( a >> 16 ) == 0 )
|
||||
{
|
||||
/* compute result directly */
|
||||
q = (FT_UInt32)( (a << 16) + (b >> 1) ) / (FT_UInt32)b;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we need more bits; we have to do it by hand */
|
||||
FT_Int64 temp, temp2;
|
||||
|
||||
temp.hi = (FT_Int32) (a >> 16);
|
||||
temp.lo = (FT_UInt32)(a << 16);
|
||||
temp2.hi = 0;
|
||||
temp2.lo = (FT_UInt32)( b >> 1 );
|
||||
FT_Add64( &temp, &temp2, &temp );
|
||||
q = ft_div64by32( temp.hi, temp.lo, b );
|
||||
}
|
||||
|
||||
return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcalc.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_MulTo64( FT_Int32 x,
|
||||
FT_Int32 y,
|
||||
FT_Int64 *z )
|
||||
{
|
||||
FT_Int32 s;
|
||||
|
||||
|
||||
s = x; x = ABS( x );
|
||||
s ^= y; y = ABS( y );
|
||||
|
||||
ft_multo64( x, y, z );
|
||||
|
||||
if ( s < 0 )
|
||||
{
|
||||
z->lo = (FT_UInt32)-(FT_Int32)z->lo;
|
||||
z->hi = ~z->hi + !( z->lo );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcalc.h */
|
||||
|
||||
/* apparently, the second version of this code is not compiled correctly */
|
||||
/* on Mac machines with the MPW C compiler.. tsss, tsss, tss... */
|
||||
#if 1
|
||||
FT_EXPORT_DEF( FT_Int32 )
|
||||
FT_Div64by32( FT_Int64* x,
|
||||
FT_Int32 y )
|
||||
{
|
||||
FT_Int32 s;
|
||||
FT_UInt32 q, r, i, lo;
|
||||
|
||||
|
||||
s = x->hi;
|
||||
if ( s < 0 )
|
||||
{
|
||||
x->lo = (FT_UInt32)-(FT_Int32)x->lo;
|
||||
x->hi = ~x->hi + !x->lo;
|
||||
}
|
||||
s ^= y; y = ABS( y );
|
||||
|
||||
/* Shortcut */
|
||||
if ( x->hi == 0 )
|
||||
{
|
||||
if ( y > 0 )
|
||||
q = x->lo / y;
|
||||
else
|
||||
q = 0x7FFFFFFFL;
|
||||
|
||||
return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
|
||||
}
|
||||
|
||||
r = x->hi;
|
||||
lo = x->lo;
|
||||
|
||||
if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */
|
||||
return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL );
|
||||
/* Return Max/Min Int32 if division overflow. */
|
||||
/* This includes division by zero! */
|
||||
q = 0;
|
||||
for ( i = 0; i < 32; i++ )
|
||||
{
|
||||
r <<= 1;
|
||||
q <<= 1;
|
||||
r |= lo >> 31;
|
||||
|
||||
if ( r >= (FT_UInt32)y )
|
||||
{
|
||||
r -= y;
|
||||
q |= 1;
|
||||
}
|
||||
lo <<= 1;
|
||||
}
|
||||
|
||||
return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
|
||||
}
|
||||
#else
|
||||
FT_EXPORT_DEF( FT_Int32 )
|
||||
FT_Div64by32( FT_Int64* x,
|
||||
FT_Int32 y )
|
||||
{
|
||||
FT_Int32 s;
|
||||
FT_UInt32 q;
|
||||
|
||||
|
||||
s = x->hi;
|
||||
if ( s < 0 )
|
||||
{
|
||||
x->lo = (FT_UInt32)-(FT_Int32)x->lo;
|
||||
x->hi = ~x->hi + !x->lo;
|
||||
}
|
||||
s ^= y; y = ABS( y );
|
||||
|
||||
/* Shortcut */
|
||||
if ( x->hi == 0 )
|
||||
{
|
||||
if ( y > 0 )
|
||||
q = ( x->lo + ( y >> 1 ) ) / y;
|
||||
else
|
||||
q = 0x7FFFFFFFL;
|
||||
|
||||
return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
|
||||
}
|
||||
|
||||
q = ft_div64by32( x->hi, x->lo, y );
|
||||
|
||||
return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_OLD_CALCS
|
||||
|
||||
|
||||
/* two helper functions for FT_Sqrt64() */
|
||||
|
||||
static void
|
||||
FT_Sub64( FT_Int64* x,
|
||||
FT_Int64* y,
|
||||
FT_Int64* z )
|
||||
{
|
||||
register FT_UInt32 lo, hi;
|
||||
|
||||
|
||||
lo = x->lo - y->lo;
|
||||
hi = x->hi - y->hi - ( (FT_Int32)lo < 0 );
|
||||
|
||||
z->lo = lo;
|
||||
z->hi = hi;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ft_order64( FT_Int64* z )
|
||||
{
|
||||
FT_UInt32 i;
|
||||
int j;
|
||||
|
||||
|
||||
i = z->lo;
|
||||
j = 0;
|
||||
if ( z->hi )
|
||||
{
|
||||
i = z->hi;
|
||||
j = 32;
|
||||
}
|
||||
|
||||
while ( i > 0 )
|
||||
{
|
||||
i >>= 1;
|
||||
j++;
|
||||
}
|
||||
return j - 1;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcalc.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Int32 )
|
||||
FT_Sqrt64( FT_Int64* l )
|
||||
{
|
||||
FT_Int64 l2;
|
||||
FT_Int32 r, s;
|
||||
|
||||
|
||||
if ( (FT_Int32)l->hi < 0 ||
|
||||
( l->hi == 0 && l->lo == 0 ) )
|
||||
return 0;
|
||||
|
||||
s = ft_order64( l );
|
||||
if ( s == 0 )
|
||||
return 1;
|
||||
|
||||
r = ft_square_roots[s];
|
||||
do
|
||||
{
|
||||
s = r;
|
||||
r = ( r + FT_Div64by32( l, r ) ) >> 1;
|
||||
FT_MulTo64( r, r, &l2 );
|
||||
FT_Sub64 ( l, &l2, &l2 );
|
||||
|
||||
} while ( r > s || (FT_Int32)l2.hi < 0 );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_OLD_CALCS */
|
||||
|
||||
|
||||
#endif /* FT_LONG64 */
|
||||
|
||||
|
||||
/* a not-so-fast but working 16.16 fixed point square root function */
|
||||
|
||||
FT_EXPORT_DEF( FT_Int32 )
|
||||
FT_SqrtFixed( FT_Int32 x )
|
||||
{
|
||||
FT_UInt32 root, rem_hi, rem_lo, test_div;
|
||||
FT_Int count;
|
||||
|
||||
|
||||
root = 0;
|
||||
|
||||
if ( x > 0 )
|
||||
{
|
||||
rem_hi = 0;
|
||||
rem_lo = x;
|
||||
count = 24;
|
||||
do
|
||||
{
|
||||
rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 );
|
||||
rem_lo <<= 2;
|
||||
root <<= 1;
|
||||
test_div = ( root << 1 ) + 1;
|
||||
|
||||
if ( rem_hi >= test_div )
|
||||
{
|
||||
rem_hi -= test_div;
|
||||
root += 1;
|
||||
}
|
||||
} while ( --count );
|
||||
}
|
||||
|
||||
return (FT_Int32)root;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,672 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftdbgmem.c */
|
||||
/* */
|
||||
/* Memory debugger (body). */
|
||||
/* */
|
||||
/* Copyright 2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_MEMORY_H
|
||||
#include FT_SYSTEM_H
|
||||
#include FT_ERRORS_H
|
||||
#include FT_TYPES_H
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
typedef struct FT_MemNodeRec_* FT_MemNode;
|
||||
typedef struct FT_MemTableRec_* FT_MemTable;
|
||||
|
||||
#define FT_MEM_VAL( addr ) ((FT_ULong)(FT_Pointer)( addr ))
|
||||
|
||||
typedef struct FT_MemNodeRec_
|
||||
{
|
||||
FT_Byte* address;
|
||||
FT_Long size; /* < 0 if the block was freed */
|
||||
|
||||
const char* alloc_file_name;
|
||||
FT_Long alloc_line_no;
|
||||
|
||||
const char* free_file_name;
|
||||
FT_Long free_line_no;
|
||||
|
||||
FT_MemNode link;
|
||||
|
||||
} FT_MemNodeRec;
|
||||
|
||||
|
||||
typedef struct FT_MemTableRec_
|
||||
{
|
||||
FT_ULong size;
|
||||
FT_ULong nodes;
|
||||
FT_MemNode* buckets;
|
||||
|
||||
FT_ULong alloc_total;
|
||||
FT_ULong alloc_current;
|
||||
FT_ULong alloc_max;
|
||||
|
||||
const char* file_name;
|
||||
FT_Long line_no;
|
||||
|
||||
FT_Memory memory;
|
||||
FT_Pointer memory_user;
|
||||
FT_Alloc_Func alloc;
|
||||
FT_Free_Func free;
|
||||
FT_Realloc_Func realloc;
|
||||
|
||||
} FT_MemTableRec;
|
||||
|
||||
|
||||
#define FT_MEM_SIZE_MIN 7
|
||||
#define FT_MEM_SIZE_MAX 13845163
|
||||
|
||||
#define FT_FILENAME( x ) ((x) ? (x) : "unknown file")
|
||||
|
||||
|
||||
static const FT_UInt ft_mem_primes[] =
|
||||
{
|
||||
7,
|
||||
11,
|
||||
19,
|
||||
37,
|
||||
73,
|
||||
109,
|
||||
163,
|
||||
251,
|
||||
367,
|
||||
557,
|
||||
823,
|
||||
1237,
|
||||
1861,
|
||||
2777,
|
||||
4177,
|
||||
6247,
|
||||
9371,
|
||||
14057,
|
||||
21089,
|
||||
31627,
|
||||
47431,
|
||||
71143,
|
||||
106721,
|
||||
160073,
|
||||
240101,
|
||||
360163,
|
||||
540217,
|
||||
810343,
|
||||
1215497,
|
||||
1823231,
|
||||
2734867,
|
||||
4102283,
|
||||
6153409,
|
||||
9230113,
|
||||
13845163,
|
||||
};
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
extern void
|
||||
ft_mem_debug_panic( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
printf( "FreeType.Debug: " );
|
||||
|
||||
va_start( ap, fmt );
|
||||
vprintf( fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
printf( "\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
|
||||
static FT_ULong
|
||||
ft_mem_closest_prime( FT_ULong num )
|
||||
{
|
||||
FT_UInt i;
|
||||
|
||||
|
||||
for ( i = 0;
|
||||
i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ )
|
||||
if ( ft_mem_primes[i] > num )
|
||||
return ft_mem_primes[i];
|
||||
|
||||
return FT_MEM_SIZE_MAX;
|
||||
}
|
||||
|
||||
|
||||
static FT_Pointer
|
||||
ft_mem_table_alloc( FT_MemTable table,
|
||||
FT_Long size )
|
||||
{
|
||||
FT_Memory memory = table->memory;
|
||||
FT_Pointer block;
|
||||
|
||||
|
||||
memory->user = table->memory_user;
|
||||
block = table->alloc( memory, size );
|
||||
memory->user = table;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_table_free( FT_MemTable table,
|
||||
FT_Pointer block )
|
||||
{
|
||||
FT_Memory memory = table->memory;
|
||||
|
||||
|
||||
memory->user = table->memory_user;
|
||||
table->free( memory, block );
|
||||
memory->user = table;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_table_resize( FT_MemTable table )
|
||||
{
|
||||
FT_ULong new_size;
|
||||
|
||||
|
||||
new_size = ft_mem_closest_prime( table->nodes );
|
||||
if ( new_size != table->size )
|
||||
{
|
||||
FT_MemNode* new_buckets ;
|
||||
FT_ULong i;
|
||||
|
||||
|
||||
new_buckets = ft_mem_table_alloc( table,
|
||||
new_size * sizeof ( FT_MemNode ) );
|
||||
if ( new_buckets == NULL )
|
||||
return;
|
||||
|
||||
MEM_Set( new_buckets, 0, sizeof ( FT_MemNode ) * new_size );
|
||||
|
||||
for ( i = 0; i < table->size; i++ )
|
||||
{
|
||||
FT_MemNode node, next, *pnode;
|
||||
FT_ULong hash;
|
||||
|
||||
|
||||
node = table->buckets[i];
|
||||
while ( node )
|
||||
{
|
||||
next = node->link;
|
||||
hash = FT_MEM_VAL( node->address ) % new_size;
|
||||
pnode = new_buckets + hash;
|
||||
|
||||
node->link = pnode[0];
|
||||
pnode[0] = node;
|
||||
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
|
||||
if ( table->buckets )
|
||||
ft_mem_table_free( table, table->buckets );
|
||||
|
||||
table->buckets = new_buckets;
|
||||
table->size = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static FT_MemTable
|
||||
ft_mem_table_new( FT_Memory memory )
|
||||
{
|
||||
FT_MemTable table;
|
||||
|
||||
|
||||
table = memory->alloc( memory, sizeof ( *table ) );
|
||||
if ( table == NULL )
|
||||
goto Exit;
|
||||
|
||||
MEM_Set( table, 0, sizeof ( *table ) );
|
||||
|
||||
table->size = FT_MEM_SIZE_MIN;
|
||||
table->nodes = 0;
|
||||
|
||||
table->memory = memory;
|
||||
|
||||
table->memory_user = memory->user;
|
||||
|
||||
table->alloc = memory->alloc;
|
||||
table->realloc = memory->realloc;
|
||||
table->free = memory->free;
|
||||
|
||||
table->buckets = memory->alloc( memory,
|
||||
table->size * sizeof ( FT_MemNode ) );
|
||||
if ( table->buckets )
|
||||
MEM_Set( table->buckets, 0, sizeof ( FT_MemNode ) * table->size );
|
||||
else
|
||||
{
|
||||
memory->free( memory, table );
|
||||
table = NULL;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return table;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_table_destroy( FT_MemTable table )
|
||||
{
|
||||
FT_ULong i;
|
||||
|
||||
|
||||
if ( table )
|
||||
{
|
||||
FT_Long leak_count = 0;
|
||||
FT_ULong leaks = 0;
|
||||
|
||||
|
||||
for ( i = 0; i < table->size; i++ )
|
||||
{
|
||||
FT_MemNode *pnode = table->buckets + i, next, node = *pnode;
|
||||
|
||||
|
||||
while ( node )
|
||||
{
|
||||
next = node->link;
|
||||
node->link = 0;
|
||||
|
||||
if ( node->size > 0 )
|
||||
{
|
||||
printf(
|
||||
"leaked memory block at address %p, size %8ld in (%s:%ld)\n",
|
||||
node->address, node->size,
|
||||
FT_FILENAME( node->alloc_file_name ),
|
||||
node->alloc_line_no );
|
||||
|
||||
leak_count++;
|
||||
leaks += node->size;
|
||||
|
||||
ft_mem_table_free( table, node->address );
|
||||
}
|
||||
|
||||
node->address = NULL;
|
||||
node->size = 0;
|
||||
|
||||
free( node );
|
||||
node = next;
|
||||
}
|
||||
table->buckets[i] = 0;
|
||||
}
|
||||
ft_mem_table_free( table, table->buckets );
|
||||
table->buckets = NULL;
|
||||
|
||||
table->size = 0;
|
||||
table->nodes = 0;
|
||||
free( table );
|
||||
|
||||
printf(
|
||||
"FreeType: total memory allocations = %ld\n", table->alloc_total );
|
||||
printf(
|
||||
"FreeType: maximum memory footprint = %ld\n", table->alloc_max );
|
||||
|
||||
if ( leak_count > 0 )
|
||||
ft_mem_debug_panic(
|
||||
"FreeType: %ld bytes of memory leaked in %ld blocks\n",
|
||||
leaks, leak_count );
|
||||
printf( "FreeType: No memory leaks detected!\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static FT_MemNode*
|
||||
ft_mem_table_get_nodep( FT_MemTable table,
|
||||
FT_Byte* address )
|
||||
{
|
||||
FT_ULong hash;
|
||||
FT_MemNode *pnode, node;
|
||||
|
||||
|
||||
hash = FT_MEM_VAL( address );
|
||||
pnode = table->buckets + ( hash % table->size );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
node = pnode[0];
|
||||
if ( !node )
|
||||
break;
|
||||
|
||||
if ( node->address == address )
|
||||
break;
|
||||
|
||||
pnode = &node->link;
|
||||
}
|
||||
return pnode;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_table_set( FT_MemTable table,
|
||||
FT_Byte* address,
|
||||
FT_ULong size )
|
||||
{
|
||||
FT_MemNode *pnode, node;
|
||||
|
||||
|
||||
if ( table )
|
||||
{
|
||||
pnode = ft_mem_table_get_nodep( table, address );
|
||||
node = *pnode;
|
||||
if ( node )
|
||||
{
|
||||
if ( node->size < 0 )
|
||||
{
|
||||
/* this block was already freed. This means that our memory is */
|
||||
/* now completely corrupted! */
|
||||
ft_mem_debug_panic(
|
||||
"memory heap corrupted (allocating freed block)" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this block was already allocated. This means that our memory */
|
||||
/* is also corrupted! */
|
||||
ft_mem_debug_panic(
|
||||
"memory heap corrupted (re-allocating allocated block)" );
|
||||
}
|
||||
}
|
||||
|
||||
/* we need to create a new node in this table */
|
||||
node = ft_mem_table_alloc( table, sizeof ( *node ) );
|
||||
if ( node == NULL )
|
||||
ft_mem_debug_panic( "not enough memory to run memory tests" );
|
||||
|
||||
node->address = address;
|
||||
node->size = size;
|
||||
|
||||
node->alloc_file_name = table->file_name;
|
||||
node->alloc_line_no = table->line_no;
|
||||
|
||||
node->free_file_name = NULL;
|
||||
node->free_line_no = 0;
|
||||
|
||||
node->link = pnode[0];
|
||||
|
||||
pnode[0] = node;
|
||||
table->nodes++;
|
||||
|
||||
table->alloc_total += size;
|
||||
table->alloc_current += size;
|
||||
if ( table->alloc_current > table->alloc_max )
|
||||
table->alloc_max = table->alloc_current;
|
||||
|
||||
if ( table->nodes * 3 < table->size ||
|
||||
table->size * 3 < table->nodes )
|
||||
ft_mem_table_resize( table );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_table_remove( FT_MemTable table,
|
||||
FT_Byte* address )
|
||||
{
|
||||
if ( table )
|
||||
{
|
||||
FT_MemNode *pnode, node;
|
||||
|
||||
|
||||
pnode = ft_mem_table_get_nodep( table, address );
|
||||
node = *pnode;
|
||||
if ( node )
|
||||
{
|
||||
if ( node->size < 0 )
|
||||
ft_mem_debug_panic(
|
||||
"freeing memory block at %p more than once at (%s:%ld)\n"
|
||||
"block allocated at (%s:%ld) and released at (%s:%ld)",
|
||||
address,
|
||||
FT_FILENAME( table->file_name ), table->line_no,
|
||||
FT_FILENAME( node->alloc_file_name ), node->alloc_line_no,
|
||||
FT_FILENAME( node->free_file_name ), node->free_line_no );
|
||||
|
||||
/* we simply invert the node's size to indicate that the node */
|
||||
/* was freed. We also change its contents. */
|
||||
MEM_Set( address, 0xF3, node->size );
|
||||
|
||||
table->alloc_current -= node->size;
|
||||
node->size = -node->size;
|
||||
node->free_file_name = table->file_name;
|
||||
node->free_line_no = table->line_no;
|
||||
}
|
||||
else
|
||||
ft_mem_debug_panic(
|
||||
"trying to free unknown block at %p in (%s:%ld)\n",
|
||||
address,
|
||||
FT_FILENAME( table->file_name ), table->line_no );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern FT_Pointer
|
||||
ft_mem_debug_alloc( FT_Memory memory,
|
||||
FT_Long size )
|
||||
{
|
||||
FT_MemTable table = memory->user;
|
||||
FT_Byte* block;
|
||||
|
||||
|
||||
if ( size <= 0 )
|
||||
ft_mem_debug_panic( "negative block size allocation (%ld)", size );
|
||||
|
||||
block = ft_mem_table_alloc( table, size );
|
||||
if ( block )
|
||||
ft_mem_table_set( table, block, (FT_ULong)size );
|
||||
|
||||
table->file_name = NULL;
|
||||
table->line_no = 0;
|
||||
|
||||
return (FT_Pointer) block;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
ft_mem_debug_free( FT_Memory memory,
|
||||
FT_Pointer block )
|
||||
{
|
||||
FT_MemTable table = memory->user;
|
||||
|
||||
|
||||
if ( block == NULL )
|
||||
ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
|
||||
FT_FILENAME( table->file_name ),
|
||||
table->line_no );
|
||||
|
||||
ft_mem_table_remove( table, (FT_Byte*)block );
|
||||
|
||||
/* we never really free the block */
|
||||
table->file_name = NULL;
|
||||
table->line_no = 0;
|
||||
}
|
||||
|
||||
|
||||
extern FT_Pointer
|
||||
ft_mem_debug_realloc( FT_Memory memory,
|
||||
FT_Long cur_size,
|
||||
FT_Long new_size,
|
||||
FT_Pointer block )
|
||||
{
|
||||
FT_MemTable table = memory->user;
|
||||
FT_MemNode node, *pnode;
|
||||
FT_Pointer new_block;
|
||||
|
||||
const char* file_name = FT_FILENAME( table->file_name );
|
||||
FT_Long line_no = table->line_no;
|
||||
|
||||
|
||||
if ( block == NULL || cur_size == 0 )
|
||||
ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)",
|
||||
file_name, line_no );
|
||||
|
||||
if ( new_size <= 0 )
|
||||
ft_mem_debug_panic(
|
||||
"trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)",
|
||||
block, cur_size, file_name, line_no );
|
||||
|
||||
/* check 'cur_size' value */
|
||||
pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block );
|
||||
node = *pnode;
|
||||
if ( !node )
|
||||
ft_mem_debug_panic(
|
||||
"trying to reallocate unknown block at %p in (%s:%ld)",
|
||||
block, file_name, line_no );
|
||||
|
||||
if ( node->size <= 0 )
|
||||
ft_mem_debug_panic(
|
||||
"trying to reallocate freed block at %p in (%s:%ld)",
|
||||
block, file_name, line_no );
|
||||
|
||||
if ( node->size != cur_size )
|
||||
ft_mem_debug_panic( "invalid realloc request for %p. cur_size is "
|
||||
"%ld instead of %ld in (%s:%ld)",
|
||||
block, cur_size, node->size, file_name, line_no );
|
||||
|
||||
new_block = ft_mem_debug_alloc( memory, new_size );
|
||||
if ( new_block == NULL )
|
||||
return NULL;
|
||||
|
||||
memcpy( new_block, block, cur_size < new_size ? cur_size : new_size );
|
||||
|
||||
table->file_name = file_name;
|
||||
table->line_no = line_no;
|
||||
|
||||
ft_mem_debug_free( memory, (FT_Byte*)block );
|
||||
|
||||
return new_block;
|
||||
}
|
||||
|
||||
|
||||
extern FT_Int
|
||||
ft_mem_debug_init( FT_Memory memory )
|
||||
{
|
||||
FT_MemTable table;
|
||||
FT_Int result = 0;
|
||||
|
||||
|
||||
if ( getenv( "FT_DEBUG_MEMORY" ) )
|
||||
{
|
||||
table = ft_mem_table_new( memory );
|
||||
if ( table )
|
||||
{
|
||||
memory->user = table;
|
||||
memory->alloc = ft_mem_debug_alloc;
|
||||
memory->realloc = ft_mem_debug_realloc;
|
||||
memory->free = ft_mem_debug_free;
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
ft_mem_debug_done( FT_Memory memory )
|
||||
{
|
||||
FT_MemTable table = memory->user;
|
||||
|
||||
|
||||
if ( table )
|
||||
{
|
||||
memory->free = table->free;
|
||||
memory->realloc = table->realloc;
|
||||
memory->alloc = table->alloc;
|
||||
|
||||
ft_mem_table_destroy( table );
|
||||
memory->user = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Alloc_Debug( FT_Memory memory,
|
||||
FT_Long size,
|
||||
void* *P,
|
||||
const char* file_name,
|
||||
FT_Long line_no )
|
||||
{
|
||||
FT_MemTable table = memory->user;
|
||||
|
||||
|
||||
if ( table )
|
||||
{
|
||||
table->file_name = file_name;
|
||||
table->line_no = line_no;
|
||||
}
|
||||
return FT_Alloc( memory, size, P );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Realloc_Debug( FT_Memory memory,
|
||||
FT_Long current,
|
||||
FT_Long size,
|
||||
void* *P,
|
||||
const char* file_name,
|
||||
FT_Long line_no )
|
||||
{
|
||||
FT_MemTable table = memory->user;
|
||||
|
||||
|
||||
if ( table )
|
||||
{
|
||||
table->file_name = file_name;
|
||||
table->line_no = line_no;
|
||||
}
|
||||
return FT_Realloc( memory, current, size, P );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Free_Debug( FT_Memory memory,
|
||||
FT_Pointer block,
|
||||
const char* file_name,
|
||||
FT_Long line_no )
|
||||
{
|
||||
FT_MemTable table = memory->user;
|
||||
|
||||
|
||||
if ( table )
|
||||
{
|
||||
table->file_name = file_name;
|
||||
table->line_no = line_no;
|
||||
}
|
||||
FT_Free( memory, block );
|
||||
}
|
||||
|
||||
|
||||
#else /* !FT_DEBUG_MEMORY */
|
||||
|
||||
/* ANSI C doesn't like empty source files */
|
||||
const FT_Byte _debug_mem_dummy = 0;
|
||||
|
||||
#endif /* !FT_DEBUG_MEMORY */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,118 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftdebug.c */
|
||||
/* */
|
||||
/* Debugging and logging component (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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 component contains various macros and functions used to ease the */
|
||||
/* debugging of the FreeType engine. Its main purpose is in assertion */
|
||||
/* checking, tracing, and error detection. */
|
||||
/* */
|
||||
/* There are now three debugging modes: */
|
||||
/* */
|
||||
/* - trace mode */
|
||||
/* */
|
||||
/* Error and trace messages are sent to the log file (which can be the */
|
||||
/* standard error output). */
|
||||
/* */
|
||||
/* - error mode */
|
||||
/* */
|
||||
/* Only error messages are generated. */
|
||||
/* */
|
||||
/* - release mode: */
|
||||
/* */
|
||||
/* No error message is sent or generated. The code is free from any */
|
||||
/* debugging parts. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
char ft_trace_levels[trace_max];
|
||||
#endif
|
||||
|
||||
|
||||
#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE )
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Message( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start( ap, fmt );
|
||||
vprintf( fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Panic( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start( ap, fmt );
|
||||
vprintf( fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_SetTraceLevel( FT_Trace component,
|
||||
char level )
|
||||
{
|
||||
if ( component >= trace_max )
|
||||
return;
|
||||
|
||||
/* if component is `trace_any', change _all_ levels at once */
|
||||
if ( component == trace_any )
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
for ( n = trace_any; n < trace_max; n++ )
|
||||
ft_trace_levels[n] = level;
|
||||
}
|
||||
else /* otherwise, only change individual component */
|
||||
ft_trace_levels[component] = level;
|
||||
}
|
||||
|
||||
#endif /* FT_DEBUG_LEVEL_TRACE */
|
||||
|
||||
#endif /* FT_DEBUG_LEVEL_TRACE || FT_DEBUG_LEVEL_ERROR */
|
||||
|
||||
|
||||
/* ANSI C doesn't allow empty files, so we insert a dummy symbol */
|
||||
extern const int ft_debug_dummy;
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,679 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftglyph.c */
|
||||
/* */
|
||||
/* FreeType convenience functions to handle glyphs (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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 file contains the definition of several convenience functions */
|
||||
/* that can be used by client applications to easily retrieve glyph */
|
||||
/* bitmaps and outlines from a given face. */
|
||||
/* */
|
||||
/* These functions should be optional if you are writing a font server */
|
||||
/* or text layout engine on top of FreeType. However, they are pretty */
|
||||
/* handy for many other simple uses of the library. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_GLYPH_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_glyph
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** Convenience functions ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Matrix_Multiply( FT_Matrix* a,
|
||||
FT_Matrix* b )
|
||||
{
|
||||
FT_Fixed xx, xy, yx, yy;
|
||||
|
||||
|
||||
if ( !a || !b )
|
||||
return;
|
||||
|
||||
xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx );
|
||||
xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy );
|
||||
yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx );
|
||||
yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy );
|
||||
|
||||
b->xx = xx; b->xy = xy;
|
||||
b->yx = yx; b->yy = yy;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Matrix_Invert( FT_Matrix* matrix )
|
||||
{
|
||||
FT_Pos delta, xx, yy;
|
||||
|
||||
|
||||
if ( !matrix )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
/* compute discriminant */
|
||||
delta = FT_MulFix( matrix->xx, matrix->yy ) -
|
||||
FT_MulFix( matrix->xy, matrix->yx );
|
||||
|
||||
if ( !delta )
|
||||
return FT_Err_Invalid_Argument; /* matrix can't be inverted */
|
||||
|
||||
matrix->xy = - FT_DivFix( matrix->xy, delta );
|
||||
matrix->yx = - FT_DivFix( matrix->yx, delta );
|
||||
|
||||
xx = matrix->xx;
|
||||
yy = matrix->yy;
|
||||
|
||||
matrix->xx = FT_DivFix( yy, delta );
|
||||
matrix->yy = FT_DivFix( xx, delta );
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** FT_BitmapGlyph support ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static FT_Error
|
||||
ft_bitmap_copy( FT_Memory memory,
|
||||
FT_Bitmap* source,
|
||||
FT_Bitmap* target )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Int pitch = source->pitch;
|
||||
FT_ULong size;
|
||||
|
||||
|
||||
*target = *source;
|
||||
|
||||
if ( pitch < 0 )
|
||||
pitch = -pitch;
|
||||
|
||||
size = (FT_ULong)( pitch * source->rows );
|
||||
|
||||
if ( !ALLOC( target->buffer, size ) )
|
||||
MEM_Copy( target->buffer, source->buffer, size );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_bitmap_glyph_init( FT_BitmapGlyph glyph,
|
||||
FT_GlyphSlot slot )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Library library = FT_GLYPH(glyph)->library;
|
||||
FT_Memory memory = library->memory;
|
||||
|
||||
|
||||
if ( slot->format != ft_glyph_format_bitmap )
|
||||
{
|
||||
error = FT_Err_Invalid_Glyph_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* grab the bitmap in the slot - do lazy copying whenever possible */
|
||||
glyph->bitmap = slot->bitmap;
|
||||
glyph->left = slot->bitmap_left;
|
||||
glyph->top = slot->bitmap_top;
|
||||
|
||||
if ( slot->flags & ft_glyph_own_bitmap )
|
||||
slot->flags &= ~ft_glyph_own_bitmap;
|
||||
else
|
||||
{
|
||||
/* copy the bitmap into a new buffer */
|
||||
error = ft_bitmap_copy( memory, &slot->bitmap, &glyph->bitmap );
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_bitmap_glyph_copy( FT_BitmapGlyph source,
|
||||
FT_BitmapGlyph target )
|
||||
{
|
||||
FT_Memory memory = source->root.library->memory;
|
||||
|
||||
|
||||
target->left = source->left;
|
||||
target->top = source->top;
|
||||
|
||||
return ft_bitmap_copy( memory, &source->bitmap, &target->bitmap );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_bitmap_glyph_done( FT_BitmapGlyph glyph )
|
||||
{
|
||||
FT_Memory memory = FT_GLYPH(glyph)->library->memory;
|
||||
|
||||
|
||||
FREE( glyph->bitmap.buffer );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_bitmap_glyph_bbox( FT_BitmapGlyph glyph,
|
||||
FT_BBox* cbox )
|
||||
{
|
||||
cbox->xMin = glyph->left << 6;
|
||||
cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 );
|
||||
cbox->yMax = glyph->top << 6;
|
||||
cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 );
|
||||
}
|
||||
|
||||
|
||||
const FT_Glyph_Class ft_bitmap_glyph_class =
|
||||
{
|
||||
sizeof( FT_BitmapGlyphRec ),
|
||||
ft_glyph_format_bitmap,
|
||||
|
||||
(FT_Glyph_Init_Func) ft_bitmap_glyph_init,
|
||||
(FT_Glyph_Done_Func) ft_bitmap_glyph_done,
|
||||
(FT_Glyph_Copy_Func) ft_bitmap_glyph_copy,
|
||||
(FT_Glyph_Transform_Func)0,
|
||||
(FT_Glyph_BBox_Func) ft_bitmap_glyph_bbox,
|
||||
(FT_Glyph_Prepare_Func) 0
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** FT_OutlineGlyph support ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_outline_glyph_init( FT_OutlineGlyph glyph,
|
||||
FT_GlyphSlot slot )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Library library = FT_GLYPH(glyph)->library;
|
||||
FT_Outline* source = &slot->outline;
|
||||
FT_Outline* target = &glyph->outline;
|
||||
|
||||
|
||||
/* check format in glyph slot */
|
||||
if ( slot->format != ft_glyph_format_outline )
|
||||
{
|
||||
error = FT_Err_Invalid_Glyph_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* allocate new outline */
|
||||
error = FT_Outline_New( library, source->n_points, source->n_contours,
|
||||
&glyph->outline );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* copy it */
|
||||
MEM_Copy( target->points, source->points,
|
||||
source->n_points * sizeof ( FT_Vector ) );
|
||||
|
||||
MEM_Copy( target->tags, source->tags,
|
||||
source->n_points * sizeof ( FT_Byte ) );
|
||||
|
||||
MEM_Copy( target->contours, source->contours,
|
||||
source->n_contours * sizeof ( FT_Short ) );
|
||||
|
||||
/* copy all flags, except the `ft_outline_owner' one */
|
||||
target->flags = source->flags | ft_outline_owner;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_outline_glyph_done( FT_OutlineGlyph glyph )
|
||||
{
|
||||
FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_outline_glyph_copy( FT_OutlineGlyph source,
|
||||
FT_OutlineGlyph target )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Library library = FT_GLYPH( source )->library;
|
||||
|
||||
|
||||
error = FT_Outline_New( library, source->outline.n_points,
|
||||
source->outline.n_contours, &target->outline );
|
||||
if ( !error )
|
||||
FT_Outline_Copy( &source->outline, &target->outline );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_outline_glyph_transform( FT_OutlineGlyph glyph,
|
||||
FT_Matrix* matrix,
|
||||
FT_Vector* delta )
|
||||
{
|
||||
if ( matrix )
|
||||
FT_Outline_Transform( &glyph->outline, matrix );
|
||||
|
||||
if ( delta )
|
||||
FT_Outline_Translate( &glyph->outline, delta->x, delta->y );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_outline_glyph_bbox( FT_OutlineGlyph glyph,
|
||||
FT_BBox* bbox )
|
||||
{
|
||||
FT_Outline_Get_CBox( &glyph->outline, bbox );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_outline_glyph_prepare( FT_OutlineGlyph glyph,
|
||||
FT_GlyphSlot slot )
|
||||
{
|
||||
slot->format = ft_glyph_format_outline;
|
||||
slot->outline = glyph->outline;
|
||||
slot->outline.flags &= ~ft_outline_owner;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
const FT_Glyph_Class ft_outline_glyph_class =
|
||||
{
|
||||
sizeof( FT_OutlineGlyphRec ),
|
||||
ft_glyph_format_outline,
|
||||
|
||||
(FT_Glyph_Init_Func) ft_outline_glyph_init,
|
||||
(FT_Glyph_Done_Func) ft_outline_glyph_done,
|
||||
(FT_Glyph_Copy_Func) ft_outline_glyph_copy,
|
||||
(FT_Glyph_Transform_Func)ft_outline_glyph_transform,
|
||||
(FT_Glyph_BBox_Func) ft_outline_glyph_bbox,
|
||||
(FT_Glyph_Prepare_Func) ft_outline_glyph_prepare
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** FT_Glyph class and API ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static FT_Error
|
||||
ft_new_glyph( FT_Library library,
|
||||
const FT_Glyph_Class* clazz,
|
||||
FT_Glyph* aglyph )
|
||||
{
|
||||
FT_Memory memory = library->memory;
|
||||
FT_Error error;
|
||||
FT_Glyph glyph;
|
||||
|
||||
|
||||
*aglyph = 0;
|
||||
|
||||
if ( !ALLOC( glyph, clazz->glyph_size ) )
|
||||
{
|
||||
glyph->library = library;
|
||||
glyph->clazz = clazz;
|
||||
glyph->format = clazz->glyph_format;
|
||||
|
||||
*aglyph = glyph;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Glyph_Copy( FT_Glyph source,
|
||||
FT_Glyph *target )
|
||||
{
|
||||
FT_Glyph copy;
|
||||
FT_Error error;
|
||||
const FT_Glyph_Class* clazz;
|
||||
|
||||
|
||||
/* check arguments */
|
||||
if ( !target || !source || !source->clazz )
|
||||
{
|
||||
error = FT_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*target = 0;
|
||||
|
||||
clazz = source->clazz;
|
||||
error = ft_new_glyph( source->library, clazz, © );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
copy->advance = source->advance;
|
||||
copy->format = source->format;
|
||||
|
||||
if ( clazz->glyph_copy )
|
||||
error = clazz->glyph_copy( source, copy );
|
||||
|
||||
if ( error )
|
||||
FT_Done_Glyph( copy );
|
||||
else
|
||||
*target = copy;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Glyph( FT_GlyphSlot slot,
|
||||
FT_Glyph *aglyph )
|
||||
{
|
||||
FT_Library library = slot->library;
|
||||
FT_Error error;
|
||||
FT_Glyph glyph;
|
||||
|
||||
const FT_Glyph_Class* clazz = 0;
|
||||
|
||||
|
||||
if ( !slot )
|
||||
return FT_Err_Invalid_Slot_Handle;
|
||||
|
||||
if ( !aglyph )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
/* if it is a bitmap, that's easy :-) */
|
||||
if ( slot->format == ft_glyph_format_bitmap )
|
||||
clazz = &ft_bitmap_glyph_class;
|
||||
|
||||
/* it it is an outline too */
|
||||
else if ( slot->format == ft_glyph_format_outline )
|
||||
clazz = &ft_outline_glyph_class;
|
||||
|
||||
else
|
||||
{
|
||||
/* try to find a renderer that supports the glyph image format */
|
||||
FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 );
|
||||
|
||||
|
||||
if ( render )
|
||||
clazz = &render->glyph_class;
|
||||
}
|
||||
|
||||
if ( !clazz )
|
||||
{
|
||||
error = FT_Err_Invalid_Glyph_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* create FT_Glyph object */
|
||||
error = ft_new_glyph( library, clazz, &glyph );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* copy advance while converting it to 16.16 format */
|
||||
glyph->advance.x = slot->advance.x << 10;
|
||||
glyph->advance.y = slot->advance.y << 10;
|
||||
|
||||
/* now import the image from the glyph slot */
|
||||
error = clazz->glyph_init( glyph, slot );
|
||||
|
||||
/* if an error occurred, destroy the glyph */
|
||||
if ( error )
|
||||
FT_Done_Glyph( glyph );
|
||||
else
|
||||
*aglyph = glyph;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Glyph_Transform( FT_Glyph glyph,
|
||||
FT_Matrix* matrix,
|
||||
FT_Vector* delta )
|
||||
{
|
||||
const FT_Glyph_Class* clazz;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
if ( !glyph || !glyph->clazz )
|
||||
error = FT_Err_Invalid_Argument;
|
||||
else
|
||||
{
|
||||
clazz = glyph->clazz;
|
||||
if ( clazz->glyph_transform )
|
||||
{
|
||||
/* transform glyph image */
|
||||
clazz->glyph_transform( glyph, matrix, delta );
|
||||
|
||||
/* transform advance vector */
|
||||
if ( matrix )
|
||||
FT_Vector_Transform( &glyph->advance, matrix );
|
||||
}
|
||||
else
|
||||
error = FT_Err_Invalid_Glyph_Format;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Glyph_Get_CBox( FT_Glyph glyph,
|
||||
FT_UInt bbox_mode,
|
||||
FT_BBox *acbox )
|
||||
{
|
||||
const FT_Glyph_Class* clazz;
|
||||
|
||||
|
||||
if ( !acbox )
|
||||
return;
|
||||
|
||||
acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0;
|
||||
|
||||
if ( !glyph || !glyph->clazz )
|
||||
return;
|
||||
else
|
||||
{
|
||||
clazz = glyph->clazz;
|
||||
if ( !clazz->glyph_bbox )
|
||||
return;
|
||||
else
|
||||
{
|
||||
/* retrieve bbox in 26.6 coordinates */
|
||||
clazz->glyph_bbox( glyph, acbox );
|
||||
|
||||
/* perform grid fitting if needed */
|
||||
if ( bbox_mode & ft_glyph_bbox_gridfit )
|
||||
{
|
||||
acbox->xMin &= -64;
|
||||
acbox->yMin &= -64;
|
||||
acbox->xMax = ( acbox->xMax + 63 ) & -64;
|
||||
acbox->yMax = ( acbox->yMax + 63 ) & -64;
|
||||
}
|
||||
|
||||
/* convert to integer pixels if needed */
|
||||
if ( bbox_mode & ft_glyph_bbox_truncate )
|
||||
{
|
||||
acbox->xMin >>= 6;
|
||||
acbox->yMin >>= 6;
|
||||
acbox->xMax >>= 6;
|
||||
acbox->yMax >>= 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Glyph_To_Bitmap( FT_Glyph* the_glyph,
|
||||
FT_ULong render_mode,
|
||||
FT_Vector* origin,
|
||||
FT_Bool destroy )
|
||||
{
|
||||
FT_GlyphSlotRec dummy;
|
||||
FT_Error error;
|
||||
FT_Glyph glyph;
|
||||
FT_BitmapGlyph bitmap = NULL;
|
||||
|
||||
const FT_Glyph_Class* clazz;
|
||||
|
||||
|
||||
/* check argument */
|
||||
if ( !the_glyph )
|
||||
goto Bad;
|
||||
|
||||
/* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
|
||||
/* then calling FT_Render_Glyph_Internal() */
|
||||
|
||||
glyph = *the_glyph;
|
||||
if ( !glyph )
|
||||
goto Bad;
|
||||
|
||||
clazz = glyph->clazz;
|
||||
if ( !clazz || !clazz->glyph_prepare )
|
||||
goto Bad;
|
||||
|
||||
MEM_Set( &dummy, 0, sizeof ( dummy ) );
|
||||
dummy.library = glyph->library;
|
||||
dummy.format = clazz->glyph_format;
|
||||
|
||||
/* create result bitmap glyph */
|
||||
error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class,
|
||||
(FT_Glyph*)&bitmap );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
#if 0
|
||||
/* if `origin' is set, translate the glyph image */
|
||||
if ( origin )
|
||||
FT_Glyph_Transform( glyph, 0, origin );
|
||||
#else
|
||||
FT_UNUSED( origin );
|
||||
#endif
|
||||
|
||||
/* prepare dummy slot for rendering */
|
||||
error = clazz->glyph_prepare( glyph, &dummy );
|
||||
if ( !error )
|
||||
error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
|
||||
|
||||
#if 0
|
||||
if ( !destroy && origin )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
v.x = -origin->x;
|
||||
v.y = -origin->y;
|
||||
FT_Glyph_Transform( glyph, 0, &v );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* in case of success, copy the bitmap to the glyph bitmap */
|
||||
error = ft_bitmap_glyph_init( bitmap, &dummy );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* copy advance */
|
||||
bitmap->root.advance = glyph->advance;
|
||||
|
||||
if ( destroy )
|
||||
FT_Done_Glyph( glyph );
|
||||
|
||||
*the_glyph = FT_GLYPH( bitmap );
|
||||
|
||||
Exit:
|
||||
if ( error && bitmap )
|
||||
FT_Done_Glyph( FT_GLYPH( bitmap ) );
|
||||
|
||||
return error;
|
||||
|
||||
Bad:
|
||||
error = FT_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Done_Glyph( FT_Glyph glyph )
|
||||
{
|
||||
if ( glyph )
|
||||
{
|
||||
FT_Memory memory = glyph->library->memory;
|
||||
const FT_Glyph_Class* clazz = glyph->clazz;
|
||||
|
||||
|
||||
if ( clazz->glyph_done )
|
||||
clazz->glyph_done( glyph );
|
||||
|
||||
FREE( glyph );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,155 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftinit.c */
|
||||
/* */
|
||||
/* FreeType initialization layer (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The purpose of this file is to implement the following two */
|
||||
/* functions: */
|
||||
/* */
|
||||
/* FT_Add_Default_Modules(): */
|
||||
/* This function is used to add the set of default modules to a */
|
||||
/* fresh new library object. The set is taken from the header file */
|
||||
/* `freetype/config/ftmodule.h'. See the document `FreeType 2.0 */
|
||||
/* Build System' for more information. */
|
||||
/* */
|
||||
/* FT_Init_FreeType(): */
|
||||
/* This function creates a system object for the current platform, */
|
||||
/* builds a library out of it, then calls FT_Default_Drivers(). */
|
||||
/* */
|
||||
/* Note that even if FT_Init_FreeType() uses the implementation of the */
|
||||
/* system object defined at build time, client applications are still */
|
||||
/* able to provide their own `ftsystem.c'. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_MODULE_H
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_init
|
||||
|
||||
#undef FT_USE_MODULE
|
||||
#ifdef __cplusplus
|
||||
#define FT_USE_MODULE( x ) extern "C" const FT_Module_Class* x;
|
||||
#else
|
||||
#define FT_USE_MODULE( x ) extern const FT_Module_Class* x;
|
||||
#endif
|
||||
|
||||
|
||||
#include FT_CONFIG_MODULES_H
|
||||
|
||||
|
||||
#undef FT_USE_MODULE
|
||||
#define FT_USE_MODULE( x ) (const FT_Module_Class*)&x,
|
||||
|
||||
static
|
||||
const FT_Module_Class* const ft_default_modules[] =
|
||||
{
|
||||
#include FT_CONFIG_MODULES_H
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftmodule.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Add_Default_Modules( FT_Library library )
|
||||
{
|
||||
FT_Error error;
|
||||
const FT_Module_Class* const* cur;
|
||||
|
||||
|
||||
/* test for valid `library' delayed to FT_Add_Module() */
|
||||
|
||||
cur = ft_default_modules;
|
||||
while ( *cur )
|
||||
{
|
||||
error = FT_Add_Module( library, *cur );
|
||||
/* notify errors, but don't stop */
|
||||
if ( error )
|
||||
{
|
||||
FT_ERROR(( "FT_Add_Default_Module: Cannot install `%s', error = %x\n",
|
||||
(*cur)->module_name, error ));
|
||||
}
|
||||
cur++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Init_FreeType( FT_Library *alibrary )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
/* First of all, allocate a new system object -- this function is part */
|
||||
/* of the system-specific component, i.e. `ftsystem.c'. */
|
||||
|
||||
memory = FT_New_Memory();
|
||||
if ( !memory )
|
||||
{
|
||||
FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" ));
|
||||
return FT_Err_Unimplemented_Feature;
|
||||
}
|
||||
|
||||
/* build a library out of it, then fill it with the set of */
|
||||
/* default drivers. */
|
||||
|
||||
error = FT_New_Library( memory, alibrary );
|
||||
if ( !error )
|
||||
FT_Add_Default_Modules( *alibrary );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Done_FreeType( FT_Library library )
|
||||
{
|
||||
if ( library )
|
||||
{
|
||||
FT_Memory memory = library->memory;
|
||||
|
||||
|
||||
/* Discard the library object */
|
||||
FT_Done_Library( library );
|
||||
|
||||
/* discard memory manager */
|
||||
FT_Done_Memory( memory );
|
||||
}
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,217 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftlist.c */
|
||||
/* */
|
||||
/* Generic list support for FreeType (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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 file implements functions relative to list processing. Its */
|
||||
/* data structures are defined in `freetype/internal/ftlist.h'. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_LIST_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_list
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_ListNode )
|
||||
FT_List_Find( FT_List list,
|
||||
void* data )
|
||||
{
|
||||
FT_ListNode cur;
|
||||
|
||||
|
||||
cur = list->head;
|
||||
while ( cur )
|
||||
{
|
||||
if ( cur->data == data )
|
||||
return cur;
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return (FT_ListNode)0;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_List_Add( FT_List list,
|
||||
FT_ListNode node )
|
||||
{
|
||||
FT_ListNode before = list->tail;
|
||||
|
||||
|
||||
node->next = 0;
|
||||
node->prev = before;
|
||||
|
||||
if ( before )
|
||||
before->next = node;
|
||||
else
|
||||
list->head = node;
|
||||
|
||||
list->tail = node;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_List_Insert( FT_List list,
|
||||
FT_ListNode node )
|
||||
{
|
||||
FT_ListNode after = list->head;
|
||||
|
||||
|
||||
node->next = after;
|
||||
node->prev = 0;
|
||||
|
||||
if ( !after )
|
||||
list->tail = node;
|
||||
else
|
||||
after->prev = node;
|
||||
|
||||
list->head = node;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_List_Remove( FT_List list,
|
||||
FT_ListNode node )
|
||||
{
|
||||
FT_ListNode before, after;
|
||||
|
||||
|
||||
before = node->prev;
|
||||
after = node->next;
|
||||
|
||||
if ( before )
|
||||
before->next = after;
|
||||
else
|
||||
list->head = after;
|
||||
|
||||
if ( after )
|
||||
after->prev = before;
|
||||
else
|
||||
list->tail = before;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_List_Up( FT_List list,
|
||||
FT_ListNode node )
|
||||
{
|
||||
FT_ListNode before, after;
|
||||
|
||||
|
||||
before = node->prev;
|
||||
after = node->next;
|
||||
|
||||
/* check whether we are already on top of the list */
|
||||
if ( !before )
|
||||
return;
|
||||
|
||||
before->next = after;
|
||||
|
||||
if ( after )
|
||||
after->prev = before;
|
||||
else
|
||||
list->tail = before;
|
||||
|
||||
node->prev = 0;
|
||||
node->next = list->head;
|
||||
list->head->prev = node;
|
||||
list->head = node;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_List_Iterate( FT_List list,
|
||||
FT_List_Iterator iterator,
|
||||
void* user )
|
||||
{
|
||||
FT_ListNode cur = list->head;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
while ( cur )
|
||||
{
|
||||
FT_ListNode next = cur->next;
|
||||
|
||||
|
||||
error = iterator( cur, user );
|
||||
if ( error )
|
||||
break;
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_List_Finalize( FT_List list,
|
||||
FT_List_Destructor destroy,
|
||||
FT_Memory memory,
|
||||
void* user )
|
||||
{
|
||||
FT_ListNode cur;
|
||||
|
||||
|
||||
cur = list->head;
|
||||
while ( cur )
|
||||
{
|
||||
FT_ListNode next = cur->next;
|
||||
void* data = cur->data;
|
||||
|
||||
|
||||
if ( destroy )
|
||||
destroy( memory, data, user );
|
||||
|
||||
FREE( cur );
|
||||
cur = next;
|
||||
}
|
||||
|
||||
list->head = 0;
|
||||
list->tail = 0;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,879 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftmac.c */
|
||||
/* */
|
||||
/* Mac FOND support. Written by just@letterror.com. */
|
||||
/* */
|
||||
/* Copyright 1996-2001 by */
|
||||
/* Just van Rossum, 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
|
||||
|
||||
Mac suitcase files can (and often do!) contain multiple fonts. To
|
||||
support this I use the face_index argument of FT_(Open|New)_Face()
|
||||
functions, and pretend the suitcase file is a collection.
|
||||
Warning: although the FOND driver sets face->num_faces field to the
|
||||
number of available fonts, but the Type 1 driver sets it to 1 anyway.
|
||||
So this field is currently not reliable, and I don't see a clean way
|
||||
to resolve that. The face_index argument translates to
|
||||
Get1IndResource( 'FOND', face_index + 1 );
|
||||
so clients should figure out the resource index of the FOND.
|
||||
(I'll try to provide some example code for this at some point.)
|
||||
|
||||
|
||||
The Mac FOND support works roughly like this:
|
||||
|
||||
- Check whether the offered stream points to a Mac suitcase file.
|
||||
This is done by checking the file type: it has to be 'FFIL' or 'tfil'.
|
||||
The stream that gets passed to our init_face() routine is a stdio
|
||||
stream, which isn't usable for us, since the FOND resources live
|
||||
in the resource fork. So we just grab the stream->pathname field.
|
||||
|
||||
- Read the FOND resource into memory, then check whether there is
|
||||
a TrueType font and/or (!) a Type 1 font available.
|
||||
|
||||
- If there is a Type 1 font available (as a separate 'LWFN' file),
|
||||
read its data into memory, massage it slightly so it becomes
|
||||
PFB data, wrap it into a memory stream, load the Type 1 driver
|
||||
and delegate the rest of the work to it by calling FT_Open_Face().
|
||||
(XXX TODO: after this has been done, the kerning data from the FOND
|
||||
resource should be appended to the face: on the Mac there are usually
|
||||
no AFM files available. However, this is tricky since we need to map
|
||||
Mac char codes to ps glyph names to glyph ID's...)
|
||||
|
||||
- If there is a TrueType font (an 'sfnt' resource), read it into
|
||||
memory, wrap it into a memory stream, load the TrueType driver
|
||||
and delegate the rest of the work to it, by calling FT_Open_Face().
|
||||
*/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include "truetype/ttobjs.h"
|
||||
#include "type1/t1objs.h"
|
||||
|
||||
#include <Resources.h>
|
||||
#include <Fonts.h>
|
||||
#include <Errors.h>
|
||||
#include <Files.h>
|
||||
#include <TextUtils.h>
|
||||
|
||||
#include <ctype.h> /* for isupper() and isalnum() */
|
||||
|
||||
#include FT_MAC_H
|
||||
|
||||
|
||||
/* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over
|
||||
TrueType in case *both* are available (this is not common,
|
||||
but it *is* possible). */
|
||||
#ifndef PREFER_LWFN
|
||||
#define PREFER_LWFN 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Quick'n'dirty Pascal string to C string converter.
|
||||
Warning: this call is not thread safe! Use with caution. */
|
||||
static char*
|
||||
p2c_str( unsigned char* pstr )
|
||||
{
|
||||
static char cstr[256];
|
||||
|
||||
|
||||
strncpy( cstr, (char*)pstr + 1, pstr[0] );
|
||||
cstr[pstr[0]] = '\0';
|
||||
return cstr;
|
||||
}
|
||||
|
||||
|
||||
/* Given a pathname, fill in a file spec. */
|
||||
static int
|
||||
file_spec_from_path( const char* pathname,
|
||||
FSSpec* spec )
|
||||
{
|
||||
Str255 p_path;
|
||||
FT_ULong path_len;
|
||||
|
||||
|
||||
/* convert path to a pascal string */
|
||||
path_len = strlen( pathname );
|
||||
if ( path_len > 255 )
|
||||
return -1;
|
||||
p_path[0] = (unsigned char)path_len;
|
||||
strncpy( (char*)p_path + 1, pathname, path_len );
|
||||
|
||||
if ( FSMakeFSSpec( 0, 0, p_path, spec ) != noErr )
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return the file type of the file specified by spec. */
|
||||
static OSType
|
||||
get_file_type( FSSpec* spec )
|
||||
{
|
||||
FInfo finfo;
|
||||
|
||||
|
||||
if ( FSpGetFInfo( spec, &finfo ) != noErr )
|
||||
return 0; /* file might not exist */
|
||||
|
||||
return finfo.fdType;
|
||||
}
|
||||
|
||||
|
||||
/* is this a Mac OS X .dfont file */
|
||||
static Boolean
|
||||
is_dfont( FSSpec* spec )
|
||||
{
|
||||
int nameLen = spec->name[0];
|
||||
|
||||
|
||||
if ( spec->name[nameLen - 5] == '.' &&
|
||||
spec->name[nameLen - 4] == 'd' &&
|
||||
spec->name[nameLen - 3] == 'f' &&
|
||||
spec->name[nameLen - 2] == 'o' &&
|
||||
spec->name[nameLen - 1] == 'n' &&
|
||||
spec->name[nameLen ] == 't' )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Given a PostScript font name, create the Macintosh LWFN file name. */
|
||||
static void
|
||||
create_lwfn_name( char* ps_name,
|
||||
Str255 lwfn_file_name )
|
||||
{
|
||||
int max = 5, count = 0;
|
||||
FT_Byte* p = lwfn_file_name;
|
||||
FT_Byte* q = (FT_Byte*)ps_name;
|
||||
|
||||
|
||||
lwfn_file_name[0] = 0;
|
||||
|
||||
while ( *q )
|
||||
{
|
||||
if ( isupper( *q ) )
|
||||
{
|
||||
if ( count )
|
||||
max = 3;
|
||||
count = 0;
|
||||
}
|
||||
if ( count < max && ( isalnum( *q ) || *q == '_' ) )
|
||||
{
|
||||
*++p = *q;
|
||||
lwfn_file_name[0]++;
|
||||
count++;
|
||||
}
|
||||
q++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Given a file reference, answer its location as a vRefNum
|
||||
and a dirID. */
|
||||
static FT_Error
|
||||
get_file_location( short ref_num,
|
||||
short* v_ref_num,
|
||||
long* dir_id,
|
||||
unsigned char* file_name )
|
||||
{
|
||||
FCBPBRec pb;
|
||||
OSErr error;
|
||||
|
||||
pb.ioNamePtr = file_name;
|
||||
pb.ioVRefNum = 0;
|
||||
pb.ioRefNum = ref_num;
|
||||
pb.ioFCBIndx = 0;
|
||||
|
||||
|
||||
error = PBGetFCBInfoSync( &pb );
|
||||
if ( error == noErr )
|
||||
{
|
||||
*v_ref_num = pb.ioFCBVRefNum;
|
||||
*dir_id = pb.ioFCBParID;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Make a file spec for an LWFN file from a FOND resource and
|
||||
a file name. */
|
||||
static FT_Error
|
||||
make_lwfn_spec( Handle fond,
|
||||
unsigned char* file_name,
|
||||
FSSpec* spec )
|
||||
{
|
||||
FT_Error error;
|
||||
short ref_num, v_ref_num;
|
||||
long dir_id;
|
||||
Str255 fond_file_name;
|
||||
|
||||
|
||||
ref_num = HomeResFile( fond );
|
||||
|
||||
error = ResError();
|
||||
if ( !error )
|
||||
error = get_file_location( ref_num, &v_ref_num,
|
||||
&dir_id, fond_file_name );
|
||||
if ( !error )
|
||||
error = FSMakeFSSpec( v_ref_num, dir_id, file_name, spec );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Look inside the FOND data, answer whether there should be an SFNT
|
||||
resource, and answer the name of a possible LWFN Type 1 file.
|
||||
|
||||
Thanks to Paul Miller (paulm@profoundeffects.com) for the fix
|
||||
to load a face OTHER than the first one in the FOND!
|
||||
*/
|
||||
static void
|
||||
parse_fond( char* fond_data,
|
||||
short* have_sfnt,
|
||||
short* sfnt_id,
|
||||
Str255 lwfn_file_name,
|
||||
short face_index )
|
||||
{
|
||||
AsscEntry* assoc;
|
||||
AsscEntry* base_assoc;
|
||||
FamRec* fond;
|
||||
|
||||
|
||||
*sfnt_id = 0;
|
||||
*have_sfnt = 0;
|
||||
lwfn_file_name[0] = 0;
|
||||
|
||||
fond = (FamRec*)fond_data;
|
||||
assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
|
||||
base_assoc = assoc;
|
||||
assoc += face_index; /* add on the face_index! */
|
||||
|
||||
/* if the face at this index is not scalable,
|
||||
fall back to the first one (old behavior) */
|
||||
if ( assoc->fontSize == 0 )
|
||||
{
|
||||
*have_sfnt = 1;
|
||||
*sfnt_id = assoc->fontID;
|
||||
}
|
||||
else if ( base_assoc->fontSize == 0 )
|
||||
{
|
||||
*have_sfnt = 1;
|
||||
*sfnt_id = base_assoc->fontID;
|
||||
}
|
||||
|
||||
if ( fond->ffStylOff )
|
||||
{
|
||||
unsigned char* p = (unsigned char*)fond_data;
|
||||
StyleTable* style;
|
||||
unsigned short string_count;
|
||||
unsigned char* name_table = 0;
|
||||
char ps_name[256];
|
||||
unsigned char* names[64];
|
||||
int i;
|
||||
|
||||
|
||||
p += fond->ffStylOff;
|
||||
style = (StyleTable*)p;
|
||||
p += sizeof ( StyleTable );
|
||||
string_count = *(unsigned short*)(p);
|
||||
p += sizeof ( short );
|
||||
|
||||
for ( i = 0 ; i < string_count && i < 64; i++ )
|
||||
{
|
||||
names[i] = p;
|
||||
p += names[i][0];
|
||||
p++;
|
||||
}
|
||||
strcpy( ps_name, p2c_str( names[0] ) ); /* Family name */
|
||||
|
||||
if ( style->indexes[0] > 1 )
|
||||
{
|
||||
unsigned char* suffixes = names[style->indexes[0] - 1];
|
||||
|
||||
|
||||
for ( i = 1; i <= suffixes[0]; i++ )
|
||||
strcat( ps_name, p2c_str( names[suffixes[i] - 1] ) );
|
||||
}
|
||||
create_lwfn_name( ps_name, lwfn_file_name );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Read Type 1 data from the POST resources inside the LWFN file,
|
||||
return a PFB buffer. This is somewhat convoluted because the FT2
|
||||
PFB parser wants the ASCII header as one chunk, and the LWFN
|
||||
chunks are often not organized that way, so we'll glue chunks
|
||||
of the same type together. */
|
||||
static FT_Error
|
||||
read_lwfn( FT_Memory memory,
|
||||
FSSpec* lwfn_spec,
|
||||
FT_Byte** pfb_data,
|
||||
FT_ULong* size )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
short res_ref, res_id;
|
||||
unsigned char *buffer, *p, *size_p;
|
||||
FT_ULong total_size = 0;
|
||||
FT_ULong post_size, pfb_chunk_size;
|
||||
Handle post_data;
|
||||
char code, last_code;
|
||||
|
||||
|
||||
res_ref = FSpOpenResFile( lwfn_spec, fsRdPerm );
|
||||
if ( ResError() )
|
||||
return FT_Err_Out_Of_Memory;
|
||||
UseResFile( res_ref );
|
||||
|
||||
/* First pass: load all POST resources, and determine the size of
|
||||
the output buffer. */
|
||||
res_id = 501;
|
||||
last_code = -1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
post_data = Get1Resource( 'POST', res_id++ );
|
||||
if ( post_data == NULL )
|
||||
break; /* we're done */
|
||||
|
||||
code = (*post_data)[0];
|
||||
|
||||
if ( code != last_code )
|
||||
{
|
||||
if ( code == 5 )
|
||||
total_size += 2; /* just the end code */
|
||||
else
|
||||
total_size += 6; /* code + 4 bytes chunk length */
|
||||
}
|
||||
|
||||
total_size += GetHandleSize( post_data ) - 2;
|
||||
last_code = code;
|
||||
}
|
||||
|
||||
if ( ALLOC( buffer, (FT_Long)total_size ) )
|
||||
goto Error;
|
||||
|
||||
/* Second pass: append all POST data to the buffer, add PFB fields.
|
||||
Glue all consecutive chunks of the same type together. */
|
||||
p = buffer;
|
||||
res_id = 501;
|
||||
last_code = -1;
|
||||
pfb_chunk_size = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
post_data = Get1Resource( 'POST', res_id++ );
|
||||
if ( post_data == NULL )
|
||||
break; /* we're done */
|
||||
|
||||
post_size = (FT_ULong)GetHandleSize( post_data ) - 2;
|
||||
code = (*post_data)[0];
|
||||
|
||||
if ( code != last_code )
|
||||
{
|
||||
if ( last_code != -1 )
|
||||
{
|
||||
/* we're done adding a chunk, fill in the size field */
|
||||
*size_p++ = (FT_Byte)( pfb_chunk_size & 0xFF );
|
||||
*size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8 ) & 0xFF );
|
||||
*size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF );
|
||||
*size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF );
|
||||
pfb_chunk_size = 0;
|
||||
}
|
||||
|
||||
*p++ = 0x80;
|
||||
if ( code == 5 )
|
||||
*p++ = 0x03; /* the end */
|
||||
else if ( code == 2 )
|
||||
*p++ = 0x02; /* binary segment */
|
||||
else
|
||||
*p++ = 0x01; /* ASCII segment */
|
||||
|
||||
if ( code != 5 )
|
||||
{
|
||||
size_p = p; /* save for later */
|
||||
p += 4; /* make space for size field */
|
||||
}
|
||||
}
|
||||
|
||||
memcpy( p, *post_data + 2, post_size );
|
||||
pfb_chunk_size += post_size;
|
||||
p += post_size;
|
||||
last_code = code;
|
||||
}
|
||||
|
||||
*pfb_data = buffer;
|
||||
*size = total_size;
|
||||
|
||||
Error:
|
||||
CloseResFile( res_ref );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Finalizer for a memory stream; gets called by FT_Done_Face().
|
||||
It frees the memory it uses. */
|
||||
static void
|
||||
memory_stream_close( FT_Stream stream )
|
||||
{
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
FREE( stream->base );
|
||||
|
||||
stream->size = 0;
|
||||
stream->base = 0;
|
||||
stream->close = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new memory stream from a buffer and a size. */
|
||||
static FT_Error
|
||||
new_memory_stream( FT_Library library,
|
||||
FT_Byte* base,
|
||||
FT_ULong size,
|
||||
FT_Stream_Close close,
|
||||
FT_Stream* astream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
FT_Stream stream;
|
||||
|
||||
|
||||
if ( !library )
|
||||
return FT_Err_Invalid_Library_Handle;
|
||||
|
||||
if ( !base )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
*astream = 0;
|
||||
memory = library->memory;
|
||||
if ( ALLOC( stream, sizeof ( *stream ) ) )
|
||||
goto Exit;
|
||||
|
||||
FT_New_Memory_Stream( library,
|
||||
base,
|
||||
size,
|
||||
stream );
|
||||
|
||||
stream->close = close;
|
||||
|
||||
*astream = stream;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new FT_Face given a buffer and a driver name. */
|
||||
static FT_Error
|
||||
open_face_from_buffer( FT_Library library,
|
||||
FT_Byte* base,
|
||||
FT_ULong size,
|
||||
FT_Long face_index,
|
||||
char* driver_name,
|
||||
FT_Face* aface )
|
||||
{
|
||||
FT_Open_Args args;
|
||||
FT_Error error;
|
||||
FT_Stream stream;
|
||||
FT_Memory memory = library->memory;
|
||||
|
||||
|
||||
error = new_memory_stream( library,
|
||||
base,
|
||||
size,
|
||||
memory_stream_close,
|
||||
&stream );
|
||||
if ( error )
|
||||
{
|
||||
FREE( base );
|
||||
return error;
|
||||
}
|
||||
|
||||
args.flags = ft_open_stream;
|
||||
args.stream = stream;
|
||||
if ( driver_name )
|
||||
{
|
||||
args.flags = args.flags | ft_open_driver;
|
||||
args.driver = FT_Get_Module( library, driver_name );
|
||||
}
|
||||
|
||||
error = FT_Open_Face( library, &args, face_index, aface );
|
||||
if ( error == FT_Err_Ok )
|
||||
(*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
|
||||
else
|
||||
{
|
||||
FT_Done_Stream( stream );
|
||||
FREE( stream );
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new FT_Face from a file spec to an LWFN file. */
|
||||
static FT_Error
|
||||
FT_New_Face_From_LWFN( FT_Library library,
|
||||
FSSpec* spec,
|
||||
FT_Long face_index,
|
||||
FT_Face* aface )
|
||||
{
|
||||
FT_Byte* pfb_data;
|
||||
FT_ULong pfb_size;
|
||||
FT_Error error;
|
||||
FT_Memory memory = library->memory;
|
||||
|
||||
|
||||
error = read_lwfn( library->memory, spec, &pfb_data, &pfb_size );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
#if 0
|
||||
{
|
||||
FILE* f;
|
||||
char* path;
|
||||
|
||||
|
||||
path = p2c_str( spec->name );
|
||||
strcat( path, ".PFB" );
|
||||
f = fopen( path, "wb" );
|
||||
if ( f )
|
||||
{
|
||||
fwrite( pfb_data, 1, pfb_size, f );
|
||||
fclose( f );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return open_face_from_buffer( library,
|
||||
pfb_data,
|
||||
pfb_size,
|
||||
face_index,
|
||||
"type1",
|
||||
aface );
|
||||
}
|
||||
|
||||
|
||||
/* Create a new FT_Face from an SFNT resource, specified by res ID. */
|
||||
static FT_Error
|
||||
FT_New_Face_From_SFNT( FT_Library library,
|
||||
short sfnt_id,
|
||||
FT_Long face_index,
|
||||
FT_Face* aface )
|
||||
{
|
||||
Handle sfnt = NULL;
|
||||
FT_Byte* sfnt_data;
|
||||
size_t sfnt_size;
|
||||
FT_Stream stream = NULL;
|
||||
FT_Error error = 0;
|
||||
FT_Memory memory = library->memory;
|
||||
|
||||
|
||||
sfnt = GetResource( 'sfnt', sfnt_id );
|
||||
if ( ResError() )
|
||||
return FT_Err_Invalid_Handle;
|
||||
|
||||
sfnt_size = (FT_ULong)GetHandleSize( sfnt );
|
||||
if ( ALLOC( sfnt_data, (FT_Long)sfnt_size ) )
|
||||
{
|
||||
ReleaseResource( sfnt );
|
||||
return error;
|
||||
}
|
||||
|
||||
HLock( sfnt );
|
||||
memcpy( sfnt_data, *sfnt, sfnt_size );
|
||||
HUnlock( sfnt );
|
||||
ReleaseResource( sfnt );
|
||||
|
||||
return open_face_from_buffer( library,
|
||||
sfnt_data,
|
||||
sfnt_size,
|
||||
face_index,
|
||||
"truetype",
|
||||
aface );
|
||||
}
|
||||
|
||||
|
||||
/* Create a new FT_Face from a file spec to a suitcase file. */
|
||||
static FT_Error
|
||||
FT_New_Face_From_Suitcase( FT_Library library,
|
||||
FSSpec* spec,
|
||||
FT_Long face_index,
|
||||
FT_Face* aface )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
short res_ref, res_index;
|
||||
Handle fond;
|
||||
|
||||
|
||||
res_ref = FSpOpenResFile( spec, fsRdPerm );
|
||||
if ( ResError() )
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
UseResFile( res_ref );
|
||||
|
||||
/* face_index may be -1, in which case we
|
||||
just need to do a sanity check */
|
||||
if ( face_index < 0 )
|
||||
res_index = 1;
|
||||
else
|
||||
{
|
||||
res_index = (short)( face_index + 1 );
|
||||
face_index = 0;
|
||||
}
|
||||
fond = Get1IndResource( 'FOND', res_index );
|
||||
if ( ResError() )
|
||||
{
|
||||
error = FT_Err_Cannot_Open_Resource;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
error = FT_New_Face_From_FOND( library, fond, face_index, aface );
|
||||
|
||||
Error:
|
||||
CloseResFile( res_ref );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new FT_Face from a file spec to a suitcase file. */
|
||||
static FT_Error
|
||||
FT_New_Face_From_dfont( FT_Library library,
|
||||
FSSpec* spec,
|
||||
FT_Long face_index,
|
||||
FT_Face* aface )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
short res_ref, res_index;
|
||||
Handle fond;
|
||||
FSRef hostContainerRef;
|
||||
|
||||
|
||||
error = FSpMakeFSRef( spec, &hostContainerRef );
|
||||
if ( error == noErr )
|
||||
error = FSOpenResourceFile( &hostContainerRef,
|
||||
0, NULL, fsRdPerm, &res_ref );
|
||||
|
||||
if ( error != noErr )
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
|
||||
UseResFile( res_ref );
|
||||
|
||||
/* face_index may be -1, in which case we
|
||||
just need to do a sanity check */
|
||||
if ( face_index < 0 )
|
||||
res_index = 1;
|
||||
else
|
||||
{
|
||||
res_index = (short)( face_index + 1 );
|
||||
face_index = 0;
|
||||
}
|
||||
fond = Get1IndResource( 'FOND', res_index );
|
||||
if ( ResError() )
|
||||
{
|
||||
error = FT_Err_Cannot_Open_Resource;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
error = FT_New_Face_From_FOND( library, fond, face_index, aface );
|
||||
|
||||
Error:
|
||||
CloseResFile( res_ref );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation in ftmac.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_New_Face_From_FOND( FT_Library library,
|
||||
Handle fond,
|
||||
FT_Long face_index,
|
||||
FT_Face *aface )
|
||||
{
|
||||
short sfnt_id, have_sfnt, have_lwfn = 0;
|
||||
Str255 lwfn_file_name;
|
||||
short fond_id;
|
||||
OSType fond_type;
|
||||
Str255 fond_name;
|
||||
FSSpec lwfn_spec;
|
||||
FT_Error error = FT_Err_Unknown_File_Format;
|
||||
|
||||
|
||||
GetResInfo( fond, &fond_id, &fond_type, fond_name );
|
||||
if ( ResError() != noErr || fond_type != 'FOND' )
|
||||
return FT_Err_Invalid_File_Format;
|
||||
|
||||
HLock( fond );
|
||||
parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
|
||||
HUnlock( fond );
|
||||
|
||||
if ( lwfn_file_name[0] )
|
||||
{
|
||||
if ( make_lwfn_spec( fond, lwfn_file_name, &lwfn_spec ) == FT_Err_Ok )
|
||||
have_lwfn = 1; /* yeah, we got one! */
|
||||
else
|
||||
have_lwfn = 0; /* no LWFN file found */
|
||||
}
|
||||
|
||||
if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
|
||||
return FT_New_Face_From_LWFN( library,
|
||||
&lwfn_spec,
|
||||
face_index,
|
||||
aface );
|
||||
else if ( have_sfnt )
|
||||
return FT_New_Face_From_SFNT( library,
|
||||
sfnt_id,
|
||||
face_index,
|
||||
aface );
|
||||
|
||||
return FT_Err_Unknown_File_Format;
|
||||
}
|
||||
|
||||
|
||||
/* documentation in ftmac.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_GetFile_From_Mac_Name( char* fontName,
|
||||
FSSpec* pathSpec,
|
||||
FT_Long* face_index )
|
||||
{
|
||||
OptionBits options = kFMUseGlobalScopeOption;
|
||||
|
||||
FMFontFamilyIterator famIter;
|
||||
OSStatus status = FMCreateFontFamilyIterator( NULL, NULL,
|
||||
options,
|
||||
&famIter );
|
||||
FMFont the_font = NULL;
|
||||
FMFontFamily family = NULL;
|
||||
|
||||
|
||||
*face_index = 0;
|
||||
while ( status == 0 && !the_font )
|
||||
{
|
||||
status = FMGetNextFontFamily( &famIter, &family );
|
||||
if ( status == 0 )
|
||||
{
|
||||
int stat2;
|
||||
FMFontFamilyInstanceIterator instIter;
|
||||
Str255 famNameStr;
|
||||
char famName[256];
|
||||
|
||||
|
||||
/* get the family name */
|
||||
FMGetFontFamilyName( family, famNameStr );
|
||||
CopyPascalStringToC( famNameStr, famName );
|
||||
|
||||
/* iterate through the styles */
|
||||
FMCreateFontFamilyInstanceIterator( family, &instIter );
|
||||
|
||||
*face_index = 0;
|
||||
stat2 = 0;
|
||||
while ( stat2 == 0 && !the_font )
|
||||
{
|
||||
FMFontStyle style;
|
||||
FMFontSize size;
|
||||
FMFont font;
|
||||
|
||||
|
||||
stat2 = FMGetNextFontFamilyInstance( &instIter, &font,
|
||||
&style, &size );
|
||||
if ( stat2 == 0 && size == 0 )
|
||||
{
|
||||
char fullName[256];
|
||||
|
||||
|
||||
/* build up a complete face name */
|
||||
strcpy( fullName, famName );
|
||||
if ( style & bold )
|
||||
strcat( fullName, " Bold" );
|
||||
if ( style & italic )
|
||||
strcat( fullName, " Italic" );
|
||||
|
||||
/* compare with the name we are looking for */
|
||||
if ( strcmp( fullName, fontName ) == 0 )
|
||||
{
|
||||
/* found it! */
|
||||
the_font = font;
|
||||
}
|
||||
else
|
||||
++(*face_index);
|
||||
}
|
||||
}
|
||||
|
||||
FMDisposeFontFamilyInstanceIterator( &instIter );
|
||||
}
|
||||
}
|
||||
|
||||
FMDisposeFontFamilyIterator( &famIter );
|
||||
|
||||
if ( the_font )
|
||||
{
|
||||
FMGetFontContainer( the_font, pathSpec );
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
else
|
||||
return FT_Err_Unknown_File_Format;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_New_Face */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* This is the Mac-specific implementation of FT_New_Face. In */
|
||||
/* addition to the standard FT_New_Face() functionality, it also */
|
||||
/* accepts pathnames to Mac suitcase files. For further */
|
||||
/* documentation see the original FT_New_Face() in freetype.h. */
|
||||
/* */
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_New_Face( FT_Library library,
|
||||
const char* pathname,
|
||||
FT_Long face_index,
|
||||
FT_Face *aface )
|
||||
{
|
||||
FT_Open_Args args;
|
||||
FSSpec spec;
|
||||
OSType file_type;
|
||||
|
||||
|
||||
/* test for valid `library' and `aface' delayed to FT_Open_Face() */
|
||||
if ( !pathname )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
if ( file_spec_from_path( pathname, &spec ) )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
file_type = get_file_type( &spec );
|
||||
if ( file_type == 'FFIL' || file_type == 'tfil' )
|
||||
return FT_New_Face_From_Suitcase( library, &spec, face_index, aface );
|
||||
else if ( file_type == 'LWFN' )
|
||||
return FT_New_Face_From_LWFN( library, &spec, face_index, aface );
|
||||
else if ( is_dfont( &spec ) )
|
||||
return FT_New_Face_From_dfont( library, &spec, face_index, aface );
|
||||
else /* let it fall through to normal loader (.ttf, .otf, etc.) */
|
||||
{
|
||||
args.flags = ft_open_pathname;
|
||||
args.pathname = (char*)pathname;
|
||||
|
||||
return FT_Open_Face( library, &args, face_index, aface );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,77 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftnames.c */
|
||||
/* */
|
||||
/* Simple interface to access SFNT name tables (which are used */
|
||||
/* to hold font names, copyright info, notices, etc.) (body). */
|
||||
/* */
|
||||
/* This is _not_ used to retrieve glyph names! */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_SFNT_NAMES_H
|
||||
#include FT_INTERNAL_TRUETYPE_TYPES_H
|
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_SFNT_NAMES
|
||||
|
||||
|
||||
/* documentation is in ftnames.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_UInt )
|
||||
FT_Get_Sfnt_Name_Count( FT_Face face )
|
||||
{
|
||||
return (face && FT_IS_SFNT( face )) ? ((TT_Face)face)->num_names : 0;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftnames.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Sfnt_Name( FT_Face face,
|
||||
FT_UInt index,
|
||||
FT_SfntName *aname )
|
||||
{
|
||||
FT_Error error = FT_Err_Invalid_Argument;
|
||||
|
||||
|
||||
if ( aname && face && FT_IS_SFNT( face ) )
|
||||
{
|
||||
TT_Face ttface = (TT_Face)face;
|
||||
|
||||
|
||||
if ( index < (FT_UInt)ttface->num_names )
|
||||
{
|
||||
TT_NameRec* name = ttface->name_table.names + index;
|
||||
|
||||
|
||||
aname->platform_id = name->platformID;
|
||||
aname->encoding_id = name->encodingID;
|
||||
aname->language_id = name->languageID;
|
||||
aname->name_id = name->nameID;
|
||||
aname->string = (FT_Byte*)name->string;
|
||||
aname->string_len = name->stringLength;
|
||||
|
||||
error = FT_Err_Ok;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_SFNT_NAMES */
|
||||
|
||||
|
||||
/* END */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,656 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftoutln.c */
|
||||
/* */
|
||||
/* FreeType outline management (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* All functions are declared in freetype.h. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_outline
|
||||
|
||||
|
||||
static
|
||||
const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Outline_Decompose( FT_Outline* outline,
|
||||
const FT_Outline_Funcs* interface,
|
||||
void* user )
|
||||
{
|
||||
#undef SCALED
|
||||
#define SCALED( x ) ( ( (x) << shift ) - delta )
|
||||
|
||||
FT_Vector v_last;
|
||||
FT_Vector v_control;
|
||||
FT_Vector v_start;
|
||||
|
||||
FT_Vector* point;
|
||||
FT_Vector* limit;
|
||||
char* tags;
|
||||
|
||||
FT_Error error;
|
||||
|
||||
FT_Int n; /* index of contour in outline */
|
||||
FT_UInt first; /* index of first point in contour */
|
||||
FT_Int tag; /* current point's state */
|
||||
|
||||
FT_Int shift;
|
||||
FT_Pos delta;
|
||||
|
||||
|
||||
if ( !outline || !interface )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
shift = interface->shift;
|
||||
delta = interface->delta;
|
||||
first = 0;
|
||||
|
||||
for ( n = 0; n < outline->n_contours; n++ )
|
||||
{
|
||||
FT_Int last; /* index of last point in contour */
|
||||
|
||||
|
||||
last = outline->contours[n];
|
||||
limit = outline->points + last;
|
||||
|
||||
v_start = outline->points[first];
|
||||
v_last = outline->points[last];
|
||||
|
||||
v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y );
|
||||
v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y );
|
||||
|
||||
v_control = v_start;
|
||||
|
||||
point = outline->points + first;
|
||||
tags = outline->tags + first;
|
||||
tag = FT_CURVE_TAG( tags[0] );
|
||||
|
||||
/* A contour cannot start with a cubic control point! */
|
||||
if ( tag == FT_Curve_Tag_Cubic )
|
||||
goto Invalid_Outline;
|
||||
|
||||
/* check first point to determine origin */
|
||||
if ( tag == FT_Curve_Tag_Conic )
|
||||
{
|
||||
/* first point is conic control. Yes, this happens. */
|
||||
if ( FT_CURVE_TAG( outline->tags[last] ) == FT_Curve_Tag_On )
|
||||
{
|
||||
/* start at last point if it is on the curve */
|
||||
v_start = v_last;
|
||||
limit--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if both first and last points are conic, */
|
||||
/* start at their middle and record its position */
|
||||
/* for closure */
|
||||
v_start.x = ( v_start.x + v_last.x ) / 2;
|
||||
v_start.y = ( v_start.y + v_last.y ) / 2;
|
||||
|
||||
v_last = v_start;
|
||||
}
|
||||
point--;
|
||||
tags--;
|
||||
}
|
||||
|
||||
error = interface->move_to( &v_start, user );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
while ( point < limit )
|
||||
{
|
||||
point++;
|
||||
tags++;
|
||||
|
||||
tag = FT_CURVE_TAG( tags[0] );
|
||||
switch ( tag )
|
||||
{
|
||||
case FT_Curve_Tag_On: /* emit a single line_to */
|
||||
{
|
||||
FT_Vector vec;
|
||||
|
||||
|
||||
vec.x = SCALED( point->x );
|
||||
vec.y = SCALED( point->y );
|
||||
|
||||
error = interface->line_to( &vec, user );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
continue;
|
||||
}
|
||||
|
||||
case FT_Curve_Tag_Conic: /* consume conic arcs */
|
||||
v_control.x = SCALED( point->x );
|
||||
v_control.y = SCALED( point->y );
|
||||
|
||||
Do_Conic:
|
||||
if ( point < limit )
|
||||
{
|
||||
FT_Vector vec;
|
||||
FT_Vector v_middle;
|
||||
|
||||
|
||||
point++;
|
||||
tags++;
|
||||
tag = FT_CURVE_TAG( tags[0] );
|
||||
|
||||
vec.x = SCALED( point->x );
|
||||
vec.y = SCALED( point->y );
|
||||
|
||||
if ( tag == FT_Curve_Tag_On )
|
||||
{
|
||||
error = interface->conic_to( &v_control, &vec, user );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( tag != FT_Curve_Tag_Conic )
|
||||
goto Invalid_Outline;
|
||||
|
||||
v_middle.x = ( v_control.x + vec.x ) / 2;
|
||||
v_middle.y = ( v_control.y + vec.y ) / 2;
|
||||
|
||||
error = interface->conic_to( &v_control, &v_middle, user );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
v_control = vec;
|
||||
goto Do_Conic;
|
||||
}
|
||||
|
||||
error = interface->conic_to( &v_control, &v_start, user );
|
||||
goto Close;
|
||||
|
||||
default: /* FT_Curve_Tag_Cubic */
|
||||
{
|
||||
FT_Vector vec1, vec2;
|
||||
|
||||
|
||||
if ( point + 1 > limit ||
|
||||
FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic )
|
||||
goto Invalid_Outline;
|
||||
|
||||
point += 2;
|
||||
tags += 2;
|
||||
|
||||
vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y );
|
||||
vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y );
|
||||
|
||||
if ( point <= limit )
|
||||
{
|
||||
FT_Vector vec;
|
||||
|
||||
|
||||
vec.x = SCALED( point->x );
|
||||
vec.y = SCALED( point->y );
|
||||
|
||||
error = interface->cubic_to( &vec1, &vec2, &vec, user );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
continue;
|
||||
}
|
||||
|
||||
error = interface->cubic_to( &vec1, &vec2, &v_start, user );
|
||||
goto Close;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* close the contour with a line segment */
|
||||
error = interface->line_to( &v_start, user );
|
||||
|
||||
Close:
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
first = last + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
||||
Invalid_Outline:
|
||||
return FT_Err_Invalid_Outline;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Outline_New_Internal( FT_Memory memory,
|
||||
FT_UInt numPoints,
|
||||
FT_Int numContours,
|
||||
FT_Outline *anoutline )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
if ( !anoutline || !memory )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
*anoutline = null_outline;
|
||||
|
||||
if ( ALLOC_ARRAY( anoutline->points, numPoints * 2L, FT_Pos ) ||
|
||||
ALLOC_ARRAY( anoutline->tags, numPoints, FT_Byte ) ||
|
||||
ALLOC_ARRAY( anoutline->contours, numContours, FT_UShort ) )
|
||||
goto Fail;
|
||||
|
||||
anoutline->n_points = (FT_UShort)numPoints;
|
||||
anoutline->n_contours = (FT_Short)numContours;
|
||||
anoutline->flags |= ft_outline_owner;
|
||||
|
||||
return FT_Err_Ok;
|
||||
|
||||
Fail:
|
||||
anoutline->flags |= ft_outline_owner;
|
||||
FT_Outline_Done_Internal( memory, anoutline );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Outline_New( FT_Library library,
|
||||
FT_UInt numPoints,
|
||||
FT_Int numContours,
|
||||
FT_Outline *anoutline )
|
||||
{
|
||||
if ( !library )
|
||||
return FT_Err_Invalid_Library_Handle;
|
||||
|
||||
return FT_Outline_New_Internal( library->memory, numPoints,
|
||||
numContours, anoutline );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Outline_Check( FT_Outline* outline )
|
||||
{
|
||||
if ( outline )
|
||||
{
|
||||
FT_Int n_points = outline->n_points;
|
||||
FT_Int n_contours = outline->n_contours;
|
||||
FT_Int end0, end;
|
||||
FT_Int n;
|
||||
|
||||
|
||||
/* empty glyph? */
|
||||
if ( n_points == 0 && n_contours == 0 )
|
||||
return 0;
|
||||
|
||||
/* check point and contour counts */
|
||||
if ( n_points <= 0 || n_contours <= 0 )
|
||||
goto Bad;
|
||||
|
||||
end0 = end = -1;
|
||||
for ( n = 0; n < n_contours; n++ )
|
||||
{
|
||||
end = outline->contours[n];
|
||||
|
||||
/* note that we don't accept empty contours */
|
||||
if ( end <= end0 || end >= n_points )
|
||||
goto Bad;
|
||||
|
||||
end0 = end;
|
||||
}
|
||||
|
||||
if ( end != n_points - 1 )
|
||||
goto Bad;
|
||||
|
||||
/* XXX: check the that array */
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bad:
|
||||
return FT_Err_Invalid_Argument;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Outline_Copy( FT_Outline* source,
|
||||
FT_Outline *target )
|
||||
{
|
||||
FT_Int is_owner;
|
||||
|
||||
|
||||
if ( !source || !target ||
|
||||
source->n_points != target->n_points ||
|
||||
source->n_contours != target->n_contours )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
MEM_Copy( target->points, source->points,
|
||||
source->n_points * sizeof ( FT_Vector ) );
|
||||
|
||||
MEM_Copy( target->tags, source->tags,
|
||||
source->n_points * sizeof ( FT_Byte ) );
|
||||
|
||||
MEM_Copy( target->contours, source->contours,
|
||||
source->n_contours * sizeof ( FT_Short ) );
|
||||
|
||||
/* copy all flags, except the `ft_outline_owner' one */
|
||||
is_owner = target->flags & ft_outline_owner;
|
||||
target->flags = source->flags;
|
||||
|
||||
target->flags &= ~ft_outline_owner;
|
||||
target->flags |= is_owner;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Outline_Done_Internal( FT_Memory memory,
|
||||
FT_Outline* outline )
|
||||
{
|
||||
if ( outline )
|
||||
{
|
||||
if ( outline->flags & ft_outline_owner )
|
||||
{
|
||||
FREE( outline->points );
|
||||
FREE( outline->tags );
|
||||
FREE( outline->contours );
|
||||
}
|
||||
*outline = null_outline;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
else
|
||||
return FT_Err_Invalid_Argument;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Outline_Done( FT_Library library,
|
||||
FT_Outline* outline )
|
||||
{
|
||||
/* check for valid `outline' in FT_Outline_Done_Internal() */
|
||||
|
||||
if ( !library )
|
||||
return FT_Err_Invalid_Library_Handle;
|
||||
|
||||
return FT_Outline_Done_Internal( library->memory, outline );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Outline_Get_CBox( FT_Outline* outline,
|
||||
FT_BBox *acbox )
|
||||
{
|
||||
FT_Pos xMin, yMin, xMax, yMax;
|
||||
|
||||
|
||||
if ( outline && acbox )
|
||||
{
|
||||
if ( outline->n_points == 0 )
|
||||
{
|
||||
xMin = 0;
|
||||
yMin = 0;
|
||||
xMax = 0;
|
||||
yMax = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Vector* vec = outline->points;
|
||||
FT_Vector* limit = vec + outline->n_points;
|
||||
|
||||
|
||||
xMin = xMax = vec->x;
|
||||
yMin = yMax = vec->y;
|
||||
vec++;
|
||||
|
||||
for ( ; vec < limit; vec++ )
|
||||
{
|
||||
FT_Pos x, y;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
if ( x < xMin ) xMin = x;
|
||||
if ( x > xMax ) xMax = x;
|
||||
|
||||
y = vec->y;
|
||||
if ( y < yMin ) yMin = y;
|
||||
if ( y > yMax ) yMax = y;
|
||||
}
|
||||
}
|
||||
acbox->xMin = xMin;
|
||||
acbox->xMax = xMax;
|
||||
acbox->yMin = yMin;
|
||||
acbox->yMax = yMax;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Outline_Translate( FT_Outline* outline,
|
||||
FT_Pos xOffset,
|
||||
FT_Pos yOffset )
|
||||
{
|
||||
FT_UShort n;
|
||||
FT_Vector* vec = outline->points;
|
||||
|
||||
|
||||
for ( n = 0; n < outline->n_points; n++ )
|
||||
{
|
||||
vec->x += xOffset;
|
||||
vec->y += yOffset;
|
||||
vec++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Outline_Reverse( FT_Outline* outline )
|
||||
{
|
||||
FT_UShort n;
|
||||
FT_Int first, last;
|
||||
|
||||
|
||||
first = 0;
|
||||
|
||||
for ( n = 0; n < outline->n_contours; n++ )
|
||||
{
|
||||
last = outline->contours[n];
|
||||
|
||||
/* reverse point table */
|
||||
{
|
||||
FT_Vector* p = outline->points + first;
|
||||
FT_Vector* q = outline->points + last;
|
||||
FT_Vector swap;
|
||||
|
||||
|
||||
while ( p < q )
|
||||
{
|
||||
swap = *p;
|
||||
*p = *q;
|
||||
*q = swap;
|
||||
p++;
|
||||
q--;
|
||||
}
|
||||
}
|
||||
|
||||
/* reverse tags table */
|
||||
{
|
||||
char* p = outline->tags + first;
|
||||
char* q = outline->tags + last;
|
||||
char swap;
|
||||
|
||||
|
||||
while ( p < q )
|
||||
{
|
||||
swap = *p;
|
||||
*p = *q;
|
||||
*q = swap;
|
||||
p++;
|
||||
q--;
|
||||
}
|
||||
}
|
||||
|
||||
first = last + 1;
|
||||
}
|
||||
|
||||
outline->flags ^= ft_outline_reverse_fill;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Outline_Render( FT_Library library,
|
||||
FT_Outline* outline,
|
||||
FT_Raster_Params* params )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Bool update = 0;
|
||||
FT_Renderer renderer;
|
||||
FT_ListNode node;
|
||||
|
||||
|
||||
if ( !library )
|
||||
return FT_Err_Invalid_Library_Handle;
|
||||
|
||||
if ( !params )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
renderer = library->cur_renderer;
|
||||
node = library->renderers.head;
|
||||
|
||||
params->source = (void*)outline;
|
||||
|
||||
error = FT_Err_Cannot_Render_Glyph;
|
||||
while ( renderer )
|
||||
{
|
||||
error = renderer->raster_render( renderer->raster, params );
|
||||
if ( !error || FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph )
|
||||
break;
|
||||
|
||||
/* FT_Err_Cannot_Render_Glyph is returned if the render mode */
|
||||
/* is unsupported by the current renderer for this glyph image */
|
||||
/* format */
|
||||
|
||||
/* now, look for another renderer that supports the same */
|
||||
/* format */
|
||||
renderer = FT_Lookup_Renderer( library, ft_glyph_format_outline,
|
||||
&node );
|
||||
update = 1;
|
||||
}
|
||||
|
||||
/* if we changed the current renderer for the glyph image format */
|
||||
/* we need to select it as the next current one */
|
||||
if ( !error && update && renderer )
|
||||
FT_Set_Renderer( library, renderer, 0, 0 );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Outline_Get_Bitmap( FT_Library library,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap *abitmap )
|
||||
{
|
||||
FT_Raster_Params params;
|
||||
|
||||
|
||||
if ( !abitmap )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
/* other checks are delayed to FT_Outline_Render() */
|
||||
|
||||
params.target = abitmap;
|
||||
params.flags = 0;
|
||||
|
||||
if ( abitmap->pixel_mode == ft_pixel_mode_grays )
|
||||
params.flags |= ft_raster_flag_aa;
|
||||
|
||||
return FT_Outline_Render( library, outline, ¶ms );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Vector_Transform( FT_Vector* vector,
|
||||
FT_Matrix* matrix )
|
||||
{
|
||||
FT_Pos xz, yz;
|
||||
|
||||
|
||||
if ( !vector || !matrix )
|
||||
return;
|
||||
|
||||
xz = FT_MulFix( vector->x, matrix->xx ) +
|
||||
FT_MulFix( vector->y, matrix->xy );
|
||||
|
||||
yz = FT_MulFix( vector->x, matrix->yx ) +
|
||||
FT_MulFix( vector->y, matrix->yy );
|
||||
|
||||
vector->x = xz;
|
||||
vector->y = yz;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Outline_Transform( FT_Outline* outline,
|
||||
FT_Matrix* matrix )
|
||||
{
|
||||
FT_Vector* vec = outline->points;
|
||||
FT_Vector* limit = vec + outline->n_points;
|
||||
|
||||
|
||||
for ( ; vec < limit; vec++ )
|
||||
FT_Vector_Transform( vec, matrix );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,804 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftstream.c */
|
||||
/* */
|
||||
/* I/O stream support (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_stream
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_New_Memory_Stream( FT_Library library,
|
||||
FT_Byte* base,
|
||||
FT_ULong size,
|
||||
FT_Stream stream )
|
||||
{
|
||||
stream->memory = library->memory;
|
||||
stream->base = base;
|
||||
stream->size = size;
|
||||
stream->pos = 0;
|
||||
stream->cursor = 0;
|
||||
stream->read = 0;
|
||||
stream->close = 0;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Seek_Stream( FT_Stream stream,
|
||||
FT_ULong pos )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
stream->pos = pos;
|
||||
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, pos, 0, 0 ) )
|
||||
{
|
||||
FT_ERROR(( "FT_Seek_Stream:" ));
|
||||
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
pos, stream->size ));
|
||||
|
||||
error = FT_Err_Invalid_Stream_Operation;
|
||||
}
|
||||
else
|
||||
error = FT_Err_Ok;
|
||||
}
|
||||
/* note that seeking to the first position after the file is valid */
|
||||
else if ( pos > stream->size )
|
||||
{
|
||||
FT_ERROR(( "FT_Seek_Stream:" ));
|
||||
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
pos, stream->size ));
|
||||
|
||||
error = FT_Err_Invalid_Stream_Operation;
|
||||
}
|
||||
|
||||
else
|
||||
error = FT_Err_Ok;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Skip_Stream( FT_Stream stream,
|
||||
FT_Long distance )
|
||||
{
|
||||
return FT_Seek_Stream( stream, (FT_ULong)( stream->pos + distance ) );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Long )
|
||||
FT_Stream_Pos( FT_Stream stream )
|
||||
{
|
||||
return stream->pos;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Read_Stream( FT_Stream stream,
|
||||
FT_Byte* buffer,
|
||||
FT_ULong count )
|
||||
{
|
||||
return FT_Read_Stream_At( stream, stream->pos, buffer, count );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Read_Stream_At( FT_Stream stream,
|
||||
FT_ULong pos,
|
||||
FT_Byte* buffer,
|
||||
FT_ULong count )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_ULong read_bytes;
|
||||
|
||||
|
||||
if ( pos >= stream->size )
|
||||
{
|
||||
FT_ERROR(( "FT_Read_Stream_At:" ));
|
||||
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
pos, stream->size ));
|
||||
|
||||
return FT_Err_Invalid_Stream_Operation;
|
||||
}
|
||||
|
||||
if ( stream->read )
|
||||
read_bytes = stream->read( stream, pos, buffer, count );
|
||||
else
|
||||
{
|
||||
read_bytes = stream->size - pos;
|
||||
if ( read_bytes > count )
|
||||
read_bytes = count;
|
||||
|
||||
MEM_Copy( buffer, stream->base + pos, read_bytes );
|
||||
}
|
||||
|
||||
stream->pos = pos + read_bytes;
|
||||
|
||||
if ( read_bytes < count )
|
||||
{
|
||||
FT_ERROR(( "FT_Read_Stream_At:" ));
|
||||
FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n",
|
||||
count, read_bytes ));
|
||||
|
||||
error = FT_Err_Invalid_Stream_Operation;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Extract_Frame( FT_Stream stream,
|
||||
FT_ULong count,
|
||||
FT_Byte** pbytes )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
error = FT_Access_Frame( stream, count );
|
||||
if ( !error )
|
||||
{
|
||||
*pbytes = (FT_Byte*)stream->cursor;
|
||||
|
||||
/* equivalent to FT_Forget_Frame(), with no memory block release */
|
||||
stream->cursor = 0;
|
||||
stream->limit = 0;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Release_Frame( FT_Stream stream,
|
||||
FT_Byte** pbytes )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
FREE( *pbytes );
|
||||
}
|
||||
*pbytes = 0;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Access_Frame( FT_Stream stream,
|
||||
FT_ULong count )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_ULong read_bytes;
|
||||
|
||||
|
||||
/* check for nested frame access */
|
||||
FT_Assert( stream && stream->cursor == 0 );
|
||||
|
||||
if ( stream->read )
|
||||
{
|
||||
/* allocate the frame in memory */
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
if ( ALLOC( stream->base, count ) )
|
||||
goto Exit;
|
||||
|
||||
/* read it */
|
||||
read_bytes = stream->read( stream, stream->pos,
|
||||
stream->base, count );
|
||||
if ( read_bytes < count )
|
||||
{
|
||||
FT_ERROR(( "FT_Access_Frame:" ));
|
||||
FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n",
|
||||
count, read_bytes ));
|
||||
|
||||
FREE( stream->base );
|
||||
error = FT_Err_Invalid_Stream_Operation;
|
||||
}
|
||||
stream->cursor = stream->base;
|
||||
stream->limit = stream->cursor + count;
|
||||
stream->pos += read_bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* check current and new position */
|
||||
if ( stream->pos >= stream->size ||
|
||||
stream->pos + count > stream->size )
|
||||
{
|
||||
FT_ERROR(( "FT_Access_Frame:" ));
|
||||
FT_ERROR(( " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
|
||||
stream->pos, count, stream->size ));
|
||||
|
||||
error = FT_Err_Invalid_Stream_Operation;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* set cursor */
|
||||
stream->cursor = stream->base + stream->pos;
|
||||
stream->limit = stream->cursor + count;
|
||||
stream->pos += count;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Forget_Frame( FT_Stream stream )
|
||||
{
|
||||
/* IMPORTANT: The assertion stream->cursor != 0 was removed, given */
|
||||
/* that it is possible to access a frame of length 0 in */
|
||||
/* some weird fonts (usually, when accessing an array of */
|
||||
/* 0 records, like in some strange kern tables). */
|
||||
/* */
|
||||
/* In this case, the loader code handles the 0-length table */
|
||||
/* gracefully; however, stream.cursor is really set to 0 by the */
|
||||
/* FT_Access_Frame() call, and this is not an error. */
|
||||
/* */
|
||||
FT_Assert( stream );
|
||||
|
||||
if ( stream->read )
|
||||
{
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
FREE( stream->base );
|
||||
}
|
||||
stream->cursor = 0;
|
||||
stream->limit = 0;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Char )
|
||||
FT_Get_Char( FT_Stream stream )
|
||||
{
|
||||
FT_Char result;
|
||||
|
||||
|
||||
FT_Assert( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
if ( stream->cursor < stream->limit )
|
||||
result = *stream->cursor++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Short )
|
||||
FT_Get_Short( FT_Stream stream )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_Short result;
|
||||
|
||||
|
||||
FT_Assert( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
p = stream->cursor;
|
||||
if ( p + 1 < stream->limit )
|
||||
result = NEXT_Short( p );
|
||||
stream->cursor = p;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Short )
|
||||
FT_Get_ShortLE( FT_Stream stream )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_Short result;
|
||||
|
||||
|
||||
FT_Assert( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
p = stream->cursor;
|
||||
if ( p + 1 < stream->limit )
|
||||
result = NEXT_ShortLE( p );
|
||||
stream->cursor = p;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Long )
|
||||
FT_Get_Offset( FT_Stream stream )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_Long result;
|
||||
|
||||
|
||||
FT_Assert( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
p = stream->cursor;
|
||||
if ( p + 2 < stream->limit )
|
||||
result = NEXT_Offset( p );
|
||||
stream->cursor = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Long )
|
||||
FT_Get_Long( FT_Stream stream )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_Long result;
|
||||
|
||||
|
||||
FT_Assert( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
p = stream->cursor;
|
||||
if ( p + 3 < stream->limit )
|
||||
result = NEXT_Long( p );
|
||||
stream->cursor = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Long )
|
||||
FT_Get_LongLE( FT_Stream stream )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_Long result;
|
||||
|
||||
|
||||
FT_Assert( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
p = stream->cursor;
|
||||
if ( p + 3 < stream->limit )
|
||||
result = NEXT_LongLE( p );
|
||||
stream->cursor = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Char )
|
||||
FT_Read_Char( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte result = 0;
|
||||
|
||||
|
||||
FT_Assert( stream );
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
|
||||
goto Fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( stream->pos < stream->size )
|
||||
result = stream->base[stream->pos];
|
||||
else
|
||||
goto Fail;
|
||||
}
|
||||
stream->pos++;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
*error = FT_Err_Invalid_Stream_Operation;
|
||||
FT_ERROR(( "FT_Read_Char:" ));
|
||||
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Short )
|
||||
FT_Read_Short( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte reads[2];
|
||||
FT_Byte* p = 0;
|
||||
FT_Short result = 0;
|
||||
|
||||
|
||||
FT_Assert( stream );
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
if ( stream->pos + 1 < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
|
||||
goto Fail;
|
||||
|
||||
p = reads;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = stream->base + stream->pos;
|
||||
}
|
||||
|
||||
if ( p )
|
||||
result = NEXT_Short( p );
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos += 2;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
*error = FT_Err_Invalid_Stream_Operation;
|
||||
FT_ERROR(( "FT_Read_Short:" ));
|
||||
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Short )
|
||||
FT_Read_ShortLE( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte reads[2];
|
||||
FT_Byte* p = 0;
|
||||
FT_Short result = 0;
|
||||
|
||||
|
||||
FT_Assert( stream );
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
if ( stream->pos + 1 < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
|
||||
goto Fail;
|
||||
|
||||
p = reads;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = stream->base + stream->pos;
|
||||
}
|
||||
|
||||
if ( p )
|
||||
result = NEXT_ShortLE( p );
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos += 2;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
*error = FT_Err_Invalid_Stream_Operation;
|
||||
FT_ERROR(( "FT_Read_Short:" ));
|
||||
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Long )
|
||||
FT_Read_Offset( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte reads[3];
|
||||
FT_Byte* p = 0;
|
||||
FT_Long result = 0;
|
||||
|
||||
|
||||
FT_Assert( stream );
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
if ( stream->pos + 2 < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if (stream->read( stream, stream->pos, reads, 3L ) != 3L )
|
||||
goto Fail;
|
||||
|
||||
p = reads;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = stream->base + stream->pos;
|
||||
}
|
||||
|
||||
if ( p )
|
||||
result = NEXT_Offset( p );
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos += 3;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
*error = FT_Err_Invalid_Stream_Operation;
|
||||
FT_ERROR(( "FT_Read_Offset:" ));
|
||||
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Long )
|
||||
FT_Read_Long( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte reads[4];
|
||||
FT_Byte* p = 0;
|
||||
FT_Long result = 0;
|
||||
|
||||
|
||||
FT_Assert( stream );
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
if ( stream->pos + 3 < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
|
||||
goto Fail;
|
||||
|
||||
p = reads;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = stream->base + stream->pos;
|
||||
}
|
||||
|
||||
if ( p )
|
||||
result = NEXT_Long( p );
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos += 4;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
FT_ERROR(( "FT_Read_Long:" ));
|
||||
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
*error = FT_Err_Invalid_Stream_Operation;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Long )
|
||||
FT_Read_LongLE( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte reads[4];
|
||||
FT_Byte* p = 0;
|
||||
FT_Long result = 0;
|
||||
|
||||
|
||||
FT_Assert( stream );
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
if ( stream->pos + 3 < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
|
||||
goto Fail;
|
||||
|
||||
p = reads;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = stream->base + stream->pos;
|
||||
}
|
||||
|
||||
if ( p )
|
||||
result = NEXT_LongLE( p );
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos += 4;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
FT_ERROR(( "FT_Read_Long:" ));
|
||||
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
*error = FT_Err_Invalid_Stream_Operation;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Read_Fields( FT_Stream stream,
|
||||
const FT_Frame_Field* fields,
|
||||
void* structure )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Bool frame_accessed = 0;
|
||||
FT_Byte* cursor = stream->cursor;
|
||||
|
||||
|
||||
if ( !fields || !stream )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
error = FT_Err_Ok;
|
||||
do
|
||||
{
|
||||
FT_ULong value;
|
||||
FT_Int sign_shift;
|
||||
FT_Byte* p;
|
||||
|
||||
|
||||
switch ( fields->value )
|
||||
{
|
||||
case ft_frame_start: /* access a new frame */
|
||||
error = FT_Access_Frame( stream, fields->offset );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
frame_accessed = 1;
|
||||
cursor = stream->cursor;
|
||||
fields++;
|
||||
continue; /* loop! */
|
||||
|
||||
case ft_frame_bytes: /* read a byte sequence */
|
||||
case ft_frame_skip: /* skip some bytes */
|
||||
{
|
||||
FT_UInt len = fields->size;
|
||||
|
||||
|
||||
if ( cursor + len > stream->limit )
|
||||
{
|
||||
error = FT_Err_Invalid_Stream_Operation;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( fields->value == ft_frame_bytes )
|
||||
{
|
||||
p = (FT_Byte*)structure + fields->offset;
|
||||
MEM_Copy( p, cursor, len );
|
||||
}
|
||||
cursor += len;
|
||||
fields++;
|
||||
continue;
|
||||
}
|
||||
|
||||
case ft_frame_byte:
|
||||
case ft_frame_schar: /* read a single byte */
|
||||
value = NEXT_Byte(cursor);
|
||||
sign_shift = 24;
|
||||
break;
|
||||
|
||||
case ft_frame_short_be:
|
||||
case ft_frame_ushort_be: /* read a 2-byte big-endian short */
|
||||
value = NEXT_UShort(cursor);
|
||||
sign_shift = 16;
|
||||
break;
|
||||
|
||||
case ft_frame_short_le:
|
||||
case ft_frame_ushort_le: /* read a 2-byte little-endian short */
|
||||
value = NEXT_UShortLE(cursor);
|
||||
sign_shift = 16;
|
||||
break;
|
||||
|
||||
case ft_frame_long_be:
|
||||
case ft_frame_ulong_be: /* read a 4-byte big-endian long */
|
||||
value = NEXT_ULong(cursor);
|
||||
sign_shift = 0;
|
||||
break;
|
||||
|
||||
case ft_frame_long_le:
|
||||
case ft_frame_ulong_le: /* read a 4-byte little-endian long */
|
||||
value = NEXT_ULongLE(cursor);
|
||||
sign_shift = 0;
|
||||
break;
|
||||
|
||||
case ft_frame_off3_be:
|
||||
case ft_frame_uoff3_be: /* read a 3-byte big-endian long */
|
||||
value = NEXT_UOffset(cursor);
|
||||
sign_shift = 8;
|
||||
break;
|
||||
|
||||
case ft_frame_off3_le:
|
||||
case ft_frame_uoff3_le: /* read a 3-byte little-endian long */
|
||||
value = NEXT_UOffsetLE(cursor);
|
||||
sign_shift = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* otherwise, exit the loop */
|
||||
stream->cursor = cursor;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* now, compute the signed value is necessary */
|
||||
if ( fields->value & FT_FRAME_OP_SIGNED )
|
||||
value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );
|
||||
|
||||
/* finally, store the value in the object */
|
||||
|
||||
p = (FT_Byte*)structure + fields->offset;
|
||||
switch ( fields->size )
|
||||
{
|
||||
case 1:
|
||||
*(FT_Byte*)p = (FT_Byte)value;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*(FT_UShort*)p = (FT_UShort)value;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*(FT_UInt32*)p = (FT_UInt32)value;
|
||||
break;
|
||||
|
||||
default: /* for 64-bit systems */
|
||||
*(FT_ULong*)p = (FT_ULong)value;
|
||||
}
|
||||
|
||||
/* go to next field */
|
||||
fields++;
|
||||
}
|
||||
while ( 1 );
|
||||
|
||||
Exit:
|
||||
/* close the frame if it was opened by this read */
|
||||
if ( frame_accessed )
|
||||
FT_Forget_Frame( stream );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,305 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftsystem.c */
|
||||
/* */
|
||||
/* ANSI-specific FreeType low-level system interface (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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 file contains the default interface used by FreeType to access */
|
||||
/* low-level, i.e. memory management, i/o access as well as thread */
|
||||
/* synchronisation. It can be replaced by user-specific routines if */
|
||||
/* necessary. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_SYSTEM_H
|
||||
#include FT_ERRORS_H
|
||||
#include FT_TYPES_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* MEMORY MANAGEMENT INTERFACE */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* It is not necessary to do any error checking for the */
|
||||
/* allocation-related functions. This will be done by the higher level */
|
||||
/* routines like FT_Alloc() or FT_Realloc(). */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_alloc */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory allocation function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* size :: The requested size in bytes. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of newly allocated block. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void* )
|
||||
ft_alloc( FT_Memory memory,
|
||||
long size )
|
||||
{
|
||||
FT_UNUSED( memory );
|
||||
|
||||
return malloc( size );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_realloc */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory reallocation function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* cur_size :: The current size of the allocated memory block. */
|
||||
/* */
|
||||
/* new_size :: The newly requested size in bytes. */
|
||||
/* */
|
||||
/* block :: The current address of the block in memory. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of the reallocated memory block. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void* )
|
||||
ft_realloc( FT_Memory memory,
|
||||
long cur_size,
|
||||
long new_size,
|
||||
void* block )
|
||||
{
|
||||
FT_UNUSED( memory );
|
||||
FT_UNUSED( cur_size );
|
||||
|
||||
return realloc( block, new_size );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_free */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The memory release function. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A pointer to the memory object. */
|
||||
/* */
|
||||
/* block :: The address of block in memory to be freed. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_free( FT_Memory memory,
|
||||
void* block )
|
||||
{
|
||||
FT_UNUSED( memory );
|
||||
|
||||
free( block );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* RESOURCE MANAGEMENT INTERFACE */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_io
|
||||
|
||||
/* We use the macro STREAM_FILE for convenience to extract the */
|
||||
/* system-specific stream handle from a given FreeType stream object */
|
||||
#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_close_stream */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The function to close a stream. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* stream :: A pointer to the stream object. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_close_stream( FT_Stream stream )
|
||||
{
|
||||
fclose( STREAM_FILE( stream ) );
|
||||
|
||||
stream->descriptor.pointer = NULL;
|
||||
stream->size = 0;
|
||||
stream->base = 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* ft_io_stream */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* The function to open a stream. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* stream :: A pointer to the stream object. */
|
||||
/* */
|
||||
/* offset :: The position in the data stream to start reading. */
|
||||
/* */
|
||||
/* buffer :: The address of buffer to store the read data. */
|
||||
/* */
|
||||
/* count :: The number of bytes to read from the stream. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The number of bytes actually read. */
|
||||
/* */
|
||||
FT_CALLBACK_DEF( unsigned long )
|
||||
ft_io_stream( FT_Stream stream,
|
||||
unsigned long offset,
|
||||
unsigned char* buffer,
|
||||
unsigned long count )
|
||||
{
|
||||
FILE* file;
|
||||
|
||||
|
||||
file = STREAM_FILE( stream );
|
||||
|
||||
fseek( file, offset, SEEK_SET );
|
||||
|
||||
return (unsigned long)fread( buffer, 1, count, file );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_New_Stream( const char* filepathname,
|
||||
FT_Stream astream )
|
||||
{
|
||||
FILE* file;
|
||||
|
||||
|
||||
if ( !astream )
|
||||
return FT_Err_Invalid_Stream_Handle;
|
||||
|
||||
file = fopen( filepathname, "rb" );
|
||||
if ( !file )
|
||||
{
|
||||
FT_ERROR(( "FT_New_Stream:" ));
|
||||
FT_ERROR(( " could not open `%s'\n", filepathname ));
|
||||
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
}
|
||||
|
||||
fseek( file, 0, SEEK_END );
|
||||
astream->size = ftell( file );
|
||||
fseek( file, 0, SEEK_SET );
|
||||
|
||||
astream->descriptor.pointer = file;
|
||||
astream->pathname.pointer = (char*)filepathname;
|
||||
astream->pos = 0;
|
||||
|
||||
astream->read = ft_io_stream;
|
||||
astream->close = ft_close_stream;
|
||||
|
||||
FT_TRACE1(( "FT_New_Stream:" ));
|
||||
FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
|
||||
filepathname, astream->size ));
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
|
||||
extern FT_Int
|
||||
ft_mem_debug_init( FT_Memory memory );
|
||||
|
||||
extern void
|
||||
ft_mem_debug_done( FT_Memory memory );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Memory )
|
||||
FT_New_Memory( void )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
memory = (FT_Memory)malloc( sizeof ( *memory ) );
|
||||
if ( memory )
|
||||
{
|
||||
memory->user = 0;
|
||||
memory->alloc = ft_alloc;
|
||||
memory->realloc = ft_realloc;
|
||||
memory->free = ft_free;
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
ft_mem_debug_init( memory );
|
||||
#endif
|
||||
}
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Done_Memory( FT_Memory memory )
|
||||
{
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
ft_mem_debug_done( memory );
|
||||
#endif
|
||||
memory->free( memory, memory );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,450 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* fttrigon.c */
|
||||
/* */
|
||||
/* FreeType trigonometric functions (body). */
|
||||
/* */
|
||||
/* Copyright 2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_TRIGONOMETRY_H
|
||||
|
||||
|
||||
/* the following is 0.2715717684432231 * 2^30 */
|
||||
#define FT_TRIG_COSCALE 0x11616E8EUL
|
||||
|
||||
/* this table was generated for FT_PI = 180L << 16, i.e. degrees */
|
||||
#define FT_TRIG_MAX_ITERS 23
|
||||
|
||||
static const FT_Fixed
|
||||
ft_trig_arctan_table[24] =
|
||||
{
|
||||
4157273L, 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L,
|
||||
58666L, 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
|
||||
57L, 29L, 14L, 7L, 4L, 2L, 1L
|
||||
};
|
||||
|
||||
/* the Cordic shrink factor, multiplied by 2^32 */
|
||||
#define FT_TRIG_SCALE 1166391785UL /* 0x4585BA38UL */
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_HAS_INT64
|
||||
|
||||
/* multiply a given value by the CORDIC shrink factor */
|
||||
static FT_Fixed
|
||||
ft_trig_downscale( FT_Fixed val )
|
||||
{
|
||||
FT_Fixed s;
|
||||
FT_Int64 v;
|
||||
|
||||
|
||||
s = val;
|
||||
val = ( val >= 0 ) ? val : -val;
|
||||
|
||||
v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL;
|
||||
val = (FT_Fixed)( v >> 32 );
|
||||
|
||||
return ( s >= 0 ) ? val : -val;
|
||||
}
|
||||
|
||||
#else /* !FT_CONFIG_HAS_INT64 */
|
||||
|
||||
/* multiply a given value by the CORDIC shrink factor */
|
||||
static FT_Fixed
|
||||
ft_trig_downscale( FT_Fixed val )
|
||||
{
|
||||
FT_Fixed s;
|
||||
FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3;
|
||||
|
||||
|
||||
s = val;
|
||||
val = ( val >= 0 ) ? val : -val;
|
||||
|
||||
v1 = (FT_UInt32)val >> 16;
|
||||
v2 = (FT_UInt32)val & 0xFFFF;
|
||||
|
||||
k1 = FT_TRIG_SCALE >> 16; /* constant */
|
||||
k2 = FT_TRIG_SCALE & 0xFFFF; /* constant */
|
||||
|
||||
hi = k1 * v1;
|
||||
lo1 = k1 * v2 + k2 * v1; /* can't overflow */
|
||||
|
||||
lo2 = ( k2 * v2 ) >> 16;
|
||||
lo3 = ( lo1 >= lo2 ) ? lo1 : lo2;
|
||||
lo1 += lo2;
|
||||
|
||||
hi += lo1 >> 16;
|
||||
if ( lo1 < lo3 )
|
||||
hi += 0x10000UL;
|
||||
|
||||
val = (FT_Fixed)hi;
|
||||
|
||||
return ( s >= 0 ) ? val : -val;
|
||||
}
|
||||
|
||||
#endif /* !FT_CONFIG_HAS_INT64 */
|
||||
|
||||
|
||||
static FT_Int
|
||||
ft_trig_prenorm( FT_Vector* vec )
|
||||
{
|
||||
FT_Fixed x, y, z;
|
||||
FT_Int shift;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
|
||||
shift = 0;
|
||||
|
||||
if ( z < ( 1L << 27 ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
z <<= 1;
|
||||
} while ( z < ( 1L << 27 ) );
|
||||
|
||||
vec->x = x << shift;
|
||||
vec->y = y << shift;
|
||||
}
|
||||
else if ( z > ( 1L << 28 ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
z >>= 1;
|
||||
} while ( z > ( 1L << 28 ) );
|
||||
|
||||
vec->x = x >> shift;
|
||||
vec->y = y >> shift;
|
||||
shift = -shift;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_trig_pseudo_rotate( FT_Vector* vec,
|
||||
FT_Angle theta )
|
||||
{
|
||||
FT_Int i;
|
||||
FT_Fixed x, y, xtemp;
|
||||
const FT_Fixed *arctanptr;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
/* Get angle between -90 and 90 degrees */
|
||||
while ( theta <= -FT_ANGLE_PI2 )
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
theta += FT_ANGLE_PI;
|
||||
}
|
||||
|
||||
while ( theta > FT_ANGLE_PI2 )
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
theta -= FT_ANGLE_PI;
|
||||
}
|
||||
|
||||
/* Initial pseudorotation, with left shift */
|
||||
arctanptr = ft_trig_arctan_table;
|
||||
|
||||
if ( theta < 0 )
|
||||
{
|
||||
xtemp = x + ( y << 1 );
|
||||
y = y - ( x << 1 );
|
||||
x = xtemp;
|
||||
theta += *arctanptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
xtemp = x - ( y << 1 );
|
||||
y = y + ( x << 1 );
|
||||
x = xtemp;
|
||||
theta -= *arctanptr++;
|
||||
}
|
||||
|
||||
/* Subsequent pseudorotations, with right shifts */
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
if ( theta < 0 )
|
||||
{
|
||||
xtemp = x + ( y >> i );
|
||||
y = y - ( x >> i );
|
||||
x = xtemp;
|
||||
theta += *arctanptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
xtemp = x - ( y >> i );
|
||||
y = y + ( x >> i );
|
||||
x = xtemp;
|
||||
theta -= *arctanptr++;
|
||||
}
|
||||
} while ( ++i < FT_TRIG_MAX_ITERS );
|
||||
|
||||
vec->x = x;
|
||||
vec->y = y;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_trig_pseudo_polarize( FT_Vector* vec )
|
||||
{
|
||||
FT_Fixed theta;
|
||||
FT_Fixed yi, i;
|
||||
FT_Fixed x, y;
|
||||
const FT_Fixed *arctanptr;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
/* Get the vector into the right half plane */
|
||||
theta = 0;
|
||||
if ( x < 0 )
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
theta = 2 * FT_ANGLE_PI2;
|
||||
}
|
||||
|
||||
if ( y > 0 )
|
||||
theta = - theta;
|
||||
|
||||
arctanptr = ft_trig_arctan_table;
|
||||
|
||||
if ( y < 0 )
|
||||
{
|
||||
/* Rotate positive */
|
||||
yi = y + ( x << 1 );
|
||||
x = x - ( y << 1 );
|
||||
y = yi;
|
||||
theta -= *arctanptr++; /* Subtract angle */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rotate negative */
|
||||
yi = y - ( x << 1 );
|
||||
x = x + ( y << 1 );
|
||||
y = yi;
|
||||
theta += *arctanptr++; /* Add angle */
|
||||
}
|
||||
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
if ( y < 0 )
|
||||
{
|
||||
/* Rotate positive */
|
||||
yi = y + ( x >> i );
|
||||
x = x - ( y >> i );
|
||||
y = yi;
|
||||
theta -= *arctanptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rotate negative */
|
||||
yi = y - ( x >> i );
|
||||
x = x + ( y >> i );
|
||||
y = yi;
|
||||
theta += *arctanptr++;
|
||||
}
|
||||
} while ( ++i < FT_TRIG_MAX_ITERS );
|
||||
|
||||
/* round theta */
|
||||
if ( theta >= 0 )
|
||||
theta = ( theta + 16 ) & -32;
|
||||
else
|
||||
theta = - (( -theta + 16 ) & -32);
|
||||
|
||||
vec->x = x;
|
||||
vec->y = theta;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_Cos( FT_Angle angle )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
v.x = FT_TRIG_COSCALE >> 2;
|
||||
v.y = 0;
|
||||
ft_trig_pseudo_rotate( &v, angle );
|
||||
|
||||
return v.x / ( 1 << 12 );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_Sin( FT_Angle angle )
|
||||
{
|
||||
return FT_Cos( FT_ANGLE_PI2 - angle );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_Tan( FT_Angle angle )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
v.x = FT_TRIG_COSCALE >> 2;
|
||||
v.y = 0;
|
||||
ft_trig_pseudo_rotate( &v, angle );
|
||||
|
||||
return FT_DivFix( v.y, v.x );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Angle )
|
||||
FT_Atan2( FT_Fixed dx,
|
||||
FT_Fixed dy )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
if ( dx == 0 && dy == 0 )
|
||||
return 0;
|
||||
|
||||
v.x = dx;
|
||||
v.y = dy;
|
||||
ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_polarize( &v );
|
||||
|
||||
return v.y;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Vector_Unit( FT_Vector* vec,
|
||||
FT_Angle angle )
|
||||
{
|
||||
vec->x = FT_TRIG_COSCALE >> 2;
|
||||
vec->y = 0;
|
||||
ft_trig_pseudo_rotate( vec, angle );
|
||||
vec->x >>= 12;
|
||||
vec->y >>= 12;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Vector_Rotate( FT_Vector* vec,
|
||||
FT_Angle angle )
|
||||
{
|
||||
FT_Int shift;
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
v.x = vec->x;
|
||||
v.y = vec->y;
|
||||
|
||||
if ( angle && ( v.x != 0 || v.y != 0 ) )
|
||||
{
|
||||
shift = ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_rotate( &v, angle );
|
||||
v.x = ft_trig_downscale( v.x );
|
||||
v.y = ft_trig_downscale( v.y );
|
||||
|
||||
if ( shift >= 0 )
|
||||
{
|
||||
vec->x = v.x >> shift;
|
||||
vec->y = v.y >> shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = -shift;
|
||||
vec->x = v.x << shift;
|
||||
vec->y = v.y << shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_Vector_Length( FT_Vector* vec )
|
||||
{
|
||||
FT_Int shift;
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
v = *vec;
|
||||
|
||||
/* handle trivial cases */
|
||||
if ( v.x == 0 )
|
||||
{
|
||||
return ( v.y >= 0 ) ? v.y : -v.y;
|
||||
}
|
||||
else if ( v.y == 0 )
|
||||
{
|
||||
return ( v.x >= 0 ) ? v.x : -v.x;
|
||||
}
|
||||
|
||||
/* general case */
|
||||
shift = ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_polarize( &v );
|
||||
|
||||
v.x = ft_trig_downscale( v.x );
|
||||
return ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Vector_Polarize( FT_Vector* vec,
|
||||
FT_Fixed *length,
|
||||
FT_Angle *angle )
|
||||
{
|
||||
FT_Int shift;
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
v = *vec;
|
||||
|
||||
if ( v.x == 0 && v.y == 0 )
|
||||
return;
|
||||
|
||||
shift = ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_polarize( &v );
|
||||
|
||||
v.x = ft_trig_downscale( v.x );
|
||||
|
||||
*length = ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift );
|
||||
*angle = v.y;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,87 +0,0 @@
|
|||
#
|
||||
# FreeType 2 base layer configuration rules
|
||||
#
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
# It sets the following variables which are used by the master Makefile
|
||||
# after the call:
|
||||
#
|
||||
# BASE_OBJ_S: The single-object base layer.
|
||||
# BASE_OBJ_M: A list of all objects for a multiple-objects build.
|
||||
# BASE_EXT_OBJ: A list of base layer extensions, i.e., components found
|
||||
# in `freetype/src/base' which are not compiled within the
|
||||
# base layer proper.
|
||||
#
|
||||
# BASE_H is defined in freetype.mk to simplify the dependency rules.
|
||||
|
||||
|
||||
BASE_COMPILE := $(FT_COMPILE) $I$(SRC_)base
|
||||
|
||||
|
||||
# Base layer sources
|
||||
#
|
||||
# ftsystem, ftinit, and ftdebug are handled by freetype.mk
|
||||
#
|
||||
BASE_SRC := $(BASE_)ftcalc.c \
|
||||
$(BASE_)fttrigon.c \
|
||||
$(BASE_)ftextend.c \
|
||||
$(BASE_)ftlist.c \
|
||||
$(BASE_)ftobjs.c \
|
||||
$(BASE_)ftstream.c \
|
||||
$(BASE_)ftoutln.c \
|
||||
$(BASE_)ftnames.c \
|
||||
$(BASE_)ftdbgmem.c
|
||||
|
||||
# Base layer `extensions' sources
|
||||
#
|
||||
# An extension is added to the library file (.a or .lib) as a separate
|
||||
# object. It will then be linked to the final executable only if one of its
|
||||
# symbols is used by the application.
|
||||
#
|
||||
BASE_EXT_SRC := $(BASE_)ftglyph.c \
|
||||
$(BASE_)ftmm.c \
|
||||
$(BASE_)ftbbox.c
|
||||
|
||||
# Default extensions objects
|
||||
#
|
||||
BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_)%.c=$(OBJ_)%.$O)
|
||||
|
||||
|
||||
# Base layer object(s)
|
||||
#
|
||||
# BASE_OBJ_M is used during `multi' builds (each base source file compiles
|
||||
# to a single object file).
|
||||
#
|
||||
# BASE_OBJ_S is used during `single' builds (the whole base layer is
|
||||
# compiled as a single object file using ftbase.c).
|
||||
#
|
||||
BASE_OBJ_M := $(BASE_SRC:$(BASE_)%.c=$(OBJ_)%.$O)
|
||||
BASE_OBJ_S := $(OBJ_)ftbase.$O
|
||||
|
||||
# Base layer root source file for single build
|
||||
#
|
||||
BASE_SRC_S := $(BASE_)ftbase.c
|
||||
|
||||
|
||||
# Base layer - single object build
|
||||
#
|
||||
$(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H)
|
||||
$(BASE_COMPILE) $T$@ $(BASE_SRC_S)
|
||||
|
||||
|
||||
# Multiple objects build + extensions
|
||||
#
|
||||
$(OBJ_)%.$O: $(BASE_)%.c $(FREETYPE_H)
|
||||
$(BASE_COMPILE) $T$@ $<
|
||||
|
||||
# EOF
|
|
@ -1,26 +0,0 @@
|
|||
#
|
||||
# FreeType 2 Cache compilation rules for VMS
|
||||
#
|
||||
|
||||
|
||||
# Copyright 2001 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.
|
||||
|
||||
|
||||
CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.cache])
|
||||
|
||||
OBJS=ftcache.obj
|
||||
|
||||
all : $(OBJS)
|
||||
library [--.lib]freetype.olb $(OBJS)
|
||||
|
||||
ftcache.obj : ftcache.c ftlru.c ftcmanag.c ftccache.c ftcglyph.c ftcimage.c \
|
||||
ftcsbits.c ftccmap.c
|
||||
|
||||
# EOF
|
|
@ -1,624 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftccache.c */
|
||||
/* */
|
||||
/* The FreeType internal cache interface (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CACHE_MANAGER_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
#include "ftcerror.h"
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CACHE NODE DEFINITIONS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
ftc_node_done( FTC_Node node,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_Family family;
|
||||
FTC_FamilyEntry entry;
|
||||
|
||||
|
||||
entry = cache->manager->families.entries + node->fam_index;
|
||||
family = entry->family;
|
||||
|
||||
/* remove from parent set table - eventually destroy the set */
|
||||
if ( --family->num_nodes == 0 )
|
||||
FT_LruList_Remove( cache->families, (FT_LruNode) family );
|
||||
}
|
||||
|
||||
|
||||
/* add a new node to the head of the manager's circular MRU list */
|
||||
static void
|
||||
ftc_node_mru_link( FTC_Node node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
FTC_Node first = manager->nodes_list;
|
||||
|
||||
|
||||
if ( first )
|
||||
{
|
||||
node->mru_prev = first->mru_prev;
|
||||
node->mru_next = first;
|
||||
|
||||
first->mru_prev->mru_next = node;
|
||||
first->mru_prev = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->mru_next = node;
|
||||
node->mru_prev = node;
|
||||
}
|
||||
|
||||
manager->nodes_list = node;
|
||||
manager->num_nodes++;
|
||||
}
|
||||
|
||||
|
||||
/* remove a node from the manager's MRU list */
|
||||
static void
|
||||
ftc_node_mru_unlink( FTC_Node node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
FTC_Node prev = node->mru_prev;
|
||||
FTC_Node next = node->mru_next;
|
||||
FTC_Node first = manager->nodes_list;
|
||||
|
||||
|
||||
prev->mru_next = next;
|
||||
next->mru_prev = prev;
|
||||
|
||||
if ( node->mru_next == first )
|
||||
{
|
||||
/* this is the last node in the list; update its head pointer */
|
||||
if ( node == first )
|
||||
manager->nodes_list = NULL;
|
||||
else
|
||||
first->mru_prev = prev;
|
||||
}
|
||||
|
||||
node->mru_next = NULL;
|
||||
node->mru_prev = NULL;
|
||||
manager->num_nodes--;
|
||||
}
|
||||
|
||||
|
||||
/* move a node to the head of the manager's MRU list */
|
||||
static void
|
||||
ftc_node_mru_up( FTC_Node node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
FTC_Node first = manager->nodes_list;
|
||||
|
||||
|
||||
if ( node != first )
|
||||
{
|
||||
ftc_node_mru_unlink( node, manager );
|
||||
ftc_node_mru_link( node, manager );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* remove a node from its cache's hash table */
|
||||
static void
|
||||
ftc_node_hash_unlink( FTC_Node node,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_Node *pnode = cache->buckets + ( node->hash % cache->size );
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ( *pnode == NULL )
|
||||
{
|
||||
FT_ERROR(( "FreeType.cache.hash_unlink: unknown node!\n" ));
|
||||
return;
|
||||
}
|
||||
|
||||
if ( *pnode == node )
|
||||
{
|
||||
*pnode = node->link;
|
||||
node->link = NULL;
|
||||
|
||||
cache->nodes--;
|
||||
return;
|
||||
}
|
||||
|
||||
pnode = &(*pnode)->link;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* add a node to the "top" of its cache's hash table */
|
||||
static void
|
||||
ftc_node_hash_link( FTC_Node node,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_Node *pnode = cache->buckets + ( node->hash % cache->size );
|
||||
|
||||
|
||||
node->link = *pnode;
|
||||
*pnode = node;
|
||||
|
||||
cache->nodes++;
|
||||
}
|
||||
|
||||
|
||||
/* remove a node from the cache manager */
|
||||
FT_EXPORT_DEF( void )
|
||||
ftc_node_destroy( FTC_Node node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
FT_Memory memory = manager->library->memory;
|
||||
FTC_Cache cache;
|
||||
FTC_FamilyEntry entry;
|
||||
FTC_Cache_Class clazz;
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
/* find node's cache */
|
||||
if ( node->fam_index >= manager->families.count )
|
||||
{
|
||||
FT_ERROR(( "ftc_node_destroy: invalid node handle\n" ));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
entry = manager->families.entries + node->fam_index;
|
||||
cache = entry->cache;
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
if ( cache == NULL )
|
||||
{
|
||||
FT_ERROR(( "ftc_node_destroy: invalid node handle\n" ));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
clazz = cache->clazz;
|
||||
|
||||
manager->cur_weight -= clazz->node_weight( node, cache );
|
||||
|
||||
/* remove node from mru list */
|
||||
ftc_node_mru_unlink( node, manager );
|
||||
|
||||
/* remove node from cache's hash table */
|
||||
ftc_node_hash_unlink( node, cache );
|
||||
|
||||
/* now finalize it */
|
||||
if ( clazz->node_done )
|
||||
clazz->node_done( node, cache );
|
||||
|
||||
FREE( node );
|
||||
|
||||
/* check, just in case of general corruption :-) */
|
||||
if ( manager->num_nodes == 0 )
|
||||
FT_ERROR(( "ftc_node_destroy: invalid cache node count! = %d\n",
|
||||
manager->num_nodes ));
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CACHE FAMILY DEFINITIONS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
ftc_family_init( FTC_Family family,
|
||||
FTC_Query query,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_Manager manager = cache->manager;
|
||||
FT_Memory memory = manager->library->memory;
|
||||
FTC_FamilyEntry entry;
|
||||
|
||||
|
||||
family->cache = cache;
|
||||
family->num_nodes = 0;
|
||||
|
||||
/* now add to manager's family table */
|
||||
error = ftc_family_table_alloc( &manager->families, memory, &entry );
|
||||
if ( !error )
|
||||
{
|
||||
entry->cache = cache;
|
||||
entry->family = family;
|
||||
family->fam_index = entry->index;
|
||||
|
||||
query->family = family; /* save family in query */
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
ftc_family_done( FTC_Family family )
|
||||
{
|
||||
FTC_Manager manager = family->cache->manager;
|
||||
|
||||
|
||||
/* remove from manager's family table */
|
||||
ftc_family_table_free( &manager->families, family->fam_index );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** ABSTRACT CACHE CLASS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
#define FTC_PRIMES_MIN 7
|
||||
#define FTC_PRIMES_MAX 13845163
|
||||
|
||||
static const FT_UInt ftc_primes[] =
|
||||
{
|
||||
7,
|
||||
11,
|
||||
19,
|
||||
37,
|
||||
73,
|
||||
109,
|
||||
163,
|
||||
251,
|
||||
367,
|
||||
557,
|
||||
823,
|
||||
1237,
|
||||
1861,
|
||||
2777,
|
||||
4177,
|
||||
6247,
|
||||
9371,
|
||||
14057,
|
||||
21089,
|
||||
31627,
|
||||
47431,
|
||||
71143,
|
||||
106721,
|
||||
160073,
|
||||
240101,
|
||||
360163,
|
||||
540217,
|
||||
810343,
|
||||
1215497,
|
||||
1823231,
|
||||
2734867,
|
||||
4102283,
|
||||
6153409,
|
||||
9230113,
|
||||
13845163,
|
||||
};
|
||||
|
||||
|
||||
static FT_UFast
|
||||
ftc_prime_closest( FT_UFast num )
|
||||
{
|
||||
FT_UInt i;
|
||||
|
||||
|
||||
for ( i = 0; i < sizeof ( ftc_primes ) / sizeof ( ftc_primes[0] ); i++ )
|
||||
if ( ftc_primes[i] > num )
|
||||
return ftc_primes[i];
|
||||
|
||||
return FTC_PRIMES_MAX;
|
||||
}
|
||||
|
||||
|
||||
#define FTC_CACHE_RESIZE_TEST( c ) \
|
||||
( (c)->nodes*3 < (c)->size || \
|
||||
(c)->size*3 < (c)->nodes )
|
||||
|
||||
|
||||
static void
|
||||
ftc_cache_resize( FTC_Cache cache )
|
||||
{
|
||||
FT_UFast new_size;
|
||||
|
||||
|
||||
new_size = ftc_prime_closest( cache->nodes );
|
||||
if ( new_size != cache->size )
|
||||
{
|
||||
FT_Memory memory = cache->memory;
|
||||
FT_Error error;
|
||||
FTC_Node* new_buckets ;
|
||||
FT_ULong i;
|
||||
|
||||
|
||||
/* no need to report an error; we'll simply keep using the same */
|
||||
/* buckets number / size */
|
||||
if ( ALLOC_ARRAY( new_buckets, new_size, FTC_Node ) )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < cache->size; i++ )
|
||||
{
|
||||
FTC_Node node, next, *pnode;
|
||||
FT_UFast hash;
|
||||
|
||||
|
||||
node = cache->buckets[i];
|
||||
while ( node )
|
||||
{
|
||||
next = node->link;
|
||||
hash = node->hash % new_size;
|
||||
pnode = new_buckets + hash;
|
||||
|
||||
node->link = pnode[0];
|
||||
pnode[0] = node;
|
||||
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
|
||||
if ( cache->buckets )
|
||||
FREE( cache->buckets );
|
||||
|
||||
cache->buckets = new_buckets;
|
||||
cache->size = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
ftc_cache_init( FTC_Cache cache )
|
||||
{
|
||||
FT_Memory memory = cache->memory;
|
||||
FTC_Cache_Class clazz = cache->clazz;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
cache->nodes = 0;
|
||||
cache->size = FTC_PRIMES_MIN;
|
||||
|
||||
if ( ALLOC_ARRAY( cache->buckets, cache->size, FTC_Node ) )
|
||||
goto Exit;
|
||||
|
||||
/* now, initialize the lru list of families for this cache */
|
||||
if ( clazz->family_size > 0 )
|
||||
{
|
||||
FT_LruList_ClassRec* lru_class = &cache->family_class;
|
||||
|
||||
|
||||
lru_class->list_size = sizeof( FT_LruListRec );
|
||||
lru_class->list_init = NULL;
|
||||
lru_class->list_done = NULL;
|
||||
|
||||
lru_class->node_size = clazz->family_size;
|
||||
lru_class->node_init = (FT_LruNode_InitFunc) clazz->family_init;
|
||||
lru_class->node_done = (FT_LruNode_DoneFunc) clazz->family_done;
|
||||
lru_class->node_flush = (FT_LruNode_FlushFunc) NULL;
|
||||
lru_class->node_compare = (FT_LruNode_CompareFunc)clazz->family_compare;
|
||||
|
||||
error = FT_LruList_New( (FT_LruList_Class) lru_class,
|
||||
0, /* max items == 0 => unbounded list */
|
||||
cache,
|
||||
memory,
|
||||
&cache->families );
|
||||
if ( error )
|
||||
FREE( cache->buckets );
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
ftc_cache_clear( FTC_Cache cache )
|
||||
{
|
||||
if ( cache )
|
||||
{
|
||||
FT_Memory memory = cache->memory;
|
||||
FTC_Cache_Class clazz = cache->clazz;
|
||||
FTC_Manager manager = cache->manager;
|
||||
FT_UFast i;
|
||||
|
||||
|
||||
for ( i = 0; i < cache->size; i++ )
|
||||
{
|
||||
FTC_Node *pnode = cache->buckets + i, next, node = *pnode;
|
||||
|
||||
|
||||
while ( node )
|
||||
{
|
||||
next = node->link;
|
||||
node->link = NULL;
|
||||
|
||||
/* remove node from mru list */
|
||||
ftc_node_mru_unlink( node, manager );
|
||||
|
||||
/* now finalize it */
|
||||
manager->cur_weight -= clazz->node_weight( node, cache );
|
||||
|
||||
if ( clazz->node_done )
|
||||
clazz->node_done( node, cache );
|
||||
|
||||
FREE( node );
|
||||
node = next;
|
||||
}
|
||||
cache->buckets[i] = NULL;
|
||||
}
|
||||
|
||||
cache->nodes = 0;
|
||||
|
||||
/* destroy the families */
|
||||
if ( cache->families )
|
||||
FT_LruList_Reset( cache->families );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
ftc_cache_done( FTC_Cache cache )
|
||||
{
|
||||
if ( cache )
|
||||
{
|
||||
FT_Memory memory = cache->memory;
|
||||
|
||||
|
||||
ftc_cache_clear( cache );
|
||||
|
||||
FREE( cache->buckets );
|
||||
cache->size = 0;
|
||||
|
||||
if ( cache->families )
|
||||
{
|
||||
FT_LruList_Destroy( cache->families );
|
||||
cache->families = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Look up a node in "top" of its cache's hash table. */
|
||||
/* If not found, create a new node. */
|
||||
/* */
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
ftc_cache_lookup( FTC_Cache cache,
|
||||
FTC_Query query,
|
||||
FTC_Node *anode )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_LruNode lru;
|
||||
|
||||
|
||||
/* some argument checks are delayed to ftc_glyph_cache_lookup */
|
||||
if ( !cache || !query || !anode )
|
||||
return FTC_Err_Invalid_Argument;
|
||||
|
||||
*anode = NULL;
|
||||
|
||||
query->hash = 0;
|
||||
query->family = NULL;
|
||||
|
||||
error = FT_LruList_Lookup( cache->families, query, &lru );
|
||||
if ( !error )
|
||||
{
|
||||
FTC_Family family = (FTC_Family) lru;
|
||||
FT_UFast hash = query->hash;
|
||||
FTC_Node* bucket = cache->buckets + (hash % cache->size);
|
||||
|
||||
|
||||
if ( query->family != family ||
|
||||
family->fam_index >= cache->manager->families.size )
|
||||
{
|
||||
FT_ERROR((
|
||||
"ftc_cache_lookup: invalid query (bad 'family' field)\n" ));
|
||||
return FT_Err_Invalid_Argument;
|
||||
}
|
||||
|
||||
if ( *bucket )
|
||||
{
|
||||
FTC_Node* pnode = bucket;
|
||||
FTC_Node_CompareFunc compare = cache->clazz->node_compare;
|
||||
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
FTC_Node node;
|
||||
|
||||
|
||||
node = *pnode;
|
||||
if ( node == NULL )
|
||||
break;
|
||||
|
||||
if ( (FT_UInt)node->fam_index == family->fam_index &&
|
||||
compare( node, query, cache ) )
|
||||
{
|
||||
/* move to head of bucket list */
|
||||
if ( pnode != bucket )
|
||||
{
|
||||
*pnode = node->link;
|
||||
node->link = *bucket;
|
||||
*bucket = node;
|
||||
}
|
||||
|
||||
/* move to head of MRU list */
|
||||
if ( node != cache->manager->nodes_list )
|
||||
ftc_node_mru_up( node, cache->manager );
|
||||
|
||||
*anode = node;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
pnode = &(*pnode)->link;
|
||||
}
|
||||
}
|
||||
|
||||
/* didn't find a node, create a new one */
|
||||
{
|
||||
FTC_Cache_Class clazz = cache->clazz;
|
||||
FTC_Manager manager = cache->manager;
|
||||
FT_Memory memory = cache->memory;
|
||||
FTC_Node node;
|
||||
|
||||
|
||||
if ( ALLOC( node, clazz->node_size ) )
|
||||
goto Exit;
|
||||
|
||||
node->fam_index = (FT_UShort) family->fam_index;
|
||||
node->hash = query->hash;
|
||||
node->ref_count = 0;
|
||||
|
||||
error = clazz->node_init( node, query, cache );
|
||||
if ( error )
|
||||
{
|
||||
FREE( node );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
ftc_node_hash_link( node, cache );
|
||||
ftc_node_mru_link( node, cache->manager );
|
||||
|
||||
cache->manager->cur_weight += clazz->node_weight( node, cache );
|
||||
|
||||
/* now try to compress the node pool when necessary */
|
||||
if ( manager->cur_weight >= manager->max_weight )
|
||||
{
|
||||
node->ref_count++;
|
||||
FTC_Manager_Compress( manager );
|
||||
node->ref_count--;
|
||||
}
|
||||
|
||||
/* try to resize the hash table if appropriate */
|
||||
if ( FTC_CACHE_RESIZE_TEST( cache ) )
|
||||
ftc_cache_resize( cache );
|
||||
|
||||
*anode = node;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,390 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftccmap.c */
|
||||
/* */
|
||||
/* FreeType CharMap cache (body) */
|
||||
/* */
|
||||
/* Copyright 2000-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_CACHE_H
|
||||
#include FT_CACHE_CHARMAP_H
|
||||
#include FT_CACHE_MANAGER_H
|
||||
#include FT_INTERNAL_MEMORY_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
#include "ftcerror.h"
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Each FTC_CMapNode contains a simple array to map a range of character */
|
||||
/* codes to equivalent glyph indices. */
|
||||
/* */
|
||||
/* For now, the implementation is very basic: Each node maps a range of */
|
||||
/* 128 consecutive character codes to their correspondingglyph indices. */
|
||||
/* */
|
||||
/* We could do more complex things, but I don't think it is really very */
|
||||
/* useful. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* number of glyph indices / character code per node */
|
||||
#define FTC_CMAP_INDICES_MAX 128
|
||||
|
||||
|
||||
typedef struct FTC_CMapNodeRec_
|
||||
{
|
||||
FTC_NodeRec node;
|
||||
FT_UInt32 first; /* first character in node */
|
||||
FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */
|
||||
|
||||
} FTC_CMapNodeRec, *FTC_CMapNode;
|
||||
|
||||
|
||||
#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
|
||||
|
||||
|
||||
/* compute node hash value from cmap family and "requested" glyph index */
|
||||
#define FTC_CMAP_HASH( cfam, cquery ) \
|
||||
( (cfam)->hash + ( (cquery)->char_code / FTC_CMAP_INDICES_MAX ) )
|
||||
|
||||
/* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
|
||||
/* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */
|
||||
#define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 )
|
||||
|
||||
|
||||
/* the charmap query */
|
||||
typedef struct FTC_CMapQueryRec_
|
||||
{
|
||||
FTC_QueryRec query;
|
||||
FTC_CMapDesc desc;
|
||||
FT_UInt32 char_code;
|
||||
|
||||
} FTC_CMapQueryRec, *FTC_CMapQuery;
|
||||
|
||||
|
||||
#define FTC_CMAP_QUERY( x ) ( (FTC_CMapQuery)( x ) )
|
||||
|
||||
|
||||
/* the charmap family */
|
||||
typedef struct FTC_CMapFamilyRec_
|
||||
{
|
||||
FTC_FamilyRec family;
|
||||
FT_UInt32 hash;
|
||||
FTC_CMapDescRec desc;
|
||||
FT_UInt index;
|
||||
|
||||
} FTC_CMapFamilyRec, *FTC_CMapFamily;
|
||||
|
||||
|
||||
#define FTC_CMAP_FAMILY( x ) ( (FTC_CMapFamily)( x ) )
|
||||
#define FTC_CMAP_FAMILY_MEMORY( x ) FTC_FAMILY( x )->memory
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CHARMAP NODES *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* no need for specific finalizer; we use "ftc_node_done" directly */
|
||||
|
||||
/* initialize a new cmap node */
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_cmap_node_init( FTC_CMapNode cnode,
|
||||
FTC_CMapQuery cquery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FT_UInt32 first;
|
||||
FT_UInt n;
|
||||
FT_UNUSED( cache );
|
||||
|
||||
|
||||
first = ( cquery->char_code / FTC_CMAP_INDICES_MAX ) *
|
||||
FTC_CMAP_INDICES_MAX;
|
||||
|
||||
cnode->first = first;
|
||||
for ( n = 0; n < FTC_CMAP_INDICES_MAX; n++ )
|
||||
cnode->indices[n] = FTC_CMAP_UNKNOWN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* compute the weight of a given cmap node */
|
||||
FT_CALLBACK_DEF( FT_ULong )
|
||||
ftc_cmap_node_weight( FTC_CMapNode cnode )
|
||||
{
|
||||
FT_UNUSED( cnode );
|
||||
|
||||
return sizeof ( *cnode );
|
||||
}
|
||||
|
||||
|
||||
/* compare a cmap node to a given query */
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_cmap_node_compare( FTC_CMapNode cnode,
|
||||
FTC_CMapQuery cquery )
|
||||
{
|
||||
FT_UInt32 offset = (FT_UInt32)( cquery->char_code - cnode->first );
|
||||
|
||||
|
||||
return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CHARMAP FAMILY *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_cmap_family_init( FTC_CMapFamily cfam,
|
||||
FTC_CMapQuery cquery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_Manager manager = cache->manager;
|
||||
FTC_CMapDesc desc = cquery->desc;
|
||||
FT_UInt32 hash = 0;
|
||||
FT_Error error;
|
||||
FT_Face face;
|
||||
|
||||
|
||||
/* setup charmap descriptor */
|
||||
cfam->desc = *desc;
|
||||
|
||||
/* let's see whether the rest is correct too */
|
||||
error = FTC_Manager_Lookup_Face( manager, desc->face_id, &face );
|
||||
if ( !error )
|
||||
{
|
||||
FT_UInt count = face->num_charmaps;
|
||||
FT_UInt index = count;
|
||||
FT_CharMap* cur = face->charmaps;
|
||||
|
||||
|
||||
switch ( desc->type )
|
||||
{
|
||||
case FTC_CMAP_BY_INDEX:
|
||||
index = desc->u.index;
|
||||
hash = index * 33;
|
||||
break;
|
||||
|
||||
case FTC_CMAP_BY_ENCODING:
|
||||
for ( index = 0; index < count; index++, cur++ )
|
||||
if ( cur[0]->encoding == desc->u.encoding )
|
||||
break;
|
||||
|
||||
hash = index * 67;
|
||||
break;
|
||||
|
||||
case FTC_CMAP_BY_ID:
|
||||
for ( index = 0; index < count; index++, cur++ )
|
||||
{
|
||||
if ( (FT_UInt)cur[0]->platform_id == desc->u.id.platform &&
|
||||
(FT_UInt)cur[0]->encoding_id == desc->u.id.encoding )
|
||||
{
|
||||
hash = ( ( desc->u.id.platform << 8 ) | desc->u.id.encoding ) * 7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
if ( index >= count )
|
||||
goto Bad_Descriptor;
|
||||
|
||||
/* compute hash value, both in family and query */
|
||||
cfam->index = index;
|
||||
cfam->hash = hash ^ FTC_FACE_ID_HASH( desc->face_id );
|
||||
FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery );
|
||||
|
||||
error = ftc_family_init( FTC_FAMILY( cfam ),
|
||||
FTC_QUERY( cquery ), cache );
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
Bad_Descriptor:
|
||||
FT_ERROR(( "ftp_cmap_family_init: invalid charmap descriptor\n" ));
|
||||
return FT_Err_Invalid_Argument;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_cmap_family_compare( FTC_CMapFamily cfam,
|
||||
FTC_CMapQuery cquery )
|
||||
{
|
||||
FT_Int result = 0;
|
||||
|
||||
|
||||
/* first, compare face id and type */
|
||||
if ( cfam->desc.face_id != cquery->desc->face_id ||
|
||||
cfam->desc.type != cquery->desc->type )
|
||||
goto Exit;
|
||||
|
||||
switch ( cfam->desc.type )
|
||||
{
|
||||
case FTC_CMAP_BY_INDEX:
|
||||
result = ( cfam->desc.u.index == cquery->desc->u.index );
|
||||
break;
|
||||
|
||||
case FTC_CMAP_BY_ENCODING:
|
||||
result = ( cfam->desc.u.encoding == cquery->desc->u.encoding );
|
||||
break;
|
||||
|
||||
case FTC_CMAP_BY_ID:
|
||||
result = ( cfam->desc.u.id.platform == cquery->desc->u.id.platform &&
|
||||
cfam->desc.u.id.encoding == cquery->desc->u.id.encoding );
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
if ( result )
|
||||
{
|
||||
/* when found, update the 'family' and 'hash' field of the query */
|
||||
FTC_QUERY( cquery )->family = FTC_FAMILY( cfam );
|
||||
FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery );
|
||||
}
|
||||
|
||||
Exit:
|
||||
return FT_BOOL( result );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** GLYPH IMAGE CACHE *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FTC_Cache_ClassRec ftc_cmap_cache_class =
|
||||
{
|
||||
sizeof ( FTC_CacheRec ),
|
||||
(FTC_Cache_InitFunc) ftc_cache_init,
|
||||
(FTC_Cache_ClearFunc)ftc_cache_clear,
|
||||
(FTC_Cache_DoneFunc) ftc_cache_done,
|
||||
|
||||
sizeof ( FTC_CMapFamilyRec ),
|
||||
(FTC_Family_InitFunc) ftc_cmap_family_init,
|
||||
(FTC_Family_CompareFunc)ftc_cmap_family_compare,
|
||||
(FTC_Family_DoneFunc) ftc_family_done,
|
||||
|
||||
sizeof ( FTC_CMapNodeRec ),
|
||||
(FTC_Node_InitFunc) ftc_cmap_node_init,
|
||||
(FTC_Node_WeightFunc) ftc_cmap_node_weight,
|
||||
(FTC_Node_CompareFunc)ftc_cmap_node_compare,
|
||||
(FTC_Node_DoneFunc) ftc_node_done
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftccmap.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_CMapCache_New( FTC_Manager manager,
|
||||
FTC_CMapCache *acache )
|
||||
{
|
||||
return FTC_Manager_Register_Cache(
|
||||
manager,
|
||||
(FTC_Cache_Class)&ftc_cmap_cache_class,
|
||||
FTC_CACHE_P( acache ) );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftccmap.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_UInt )
|
||||
FTC_CMapCache_Lookup( FTC_CMapCache cache,
|
||||
FTC_CMapDesc desc,
|
||||
FT_UInt32 char_code )
|
||||
{
|
||||
FTC_CMapQueryRec cquery;
|
||||
FTC_CMapNode node;
|
||||
FT_Error error;
|
||||
FT_UInt gindex = 0;
|
||||
|
||||
|
||||
if ( !cache || !desc )
|
||||
{
|
||||
FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" ));
|
||||
return 0;
|
||||
}
|
||||
|
||||
cquery.desc = desc;
|
||||
cquery.char_code = char_code;
|
||||
|
||||
error = ftc_cache_lookup( FTC_CACHE( cache ),
|
||||
FTC_QUERY( &cquery ),
|
||||
(FTC_Node*)&node );
|
||||
if ( !error )
|
||||
{
|
||||
FT_UInt offset = (FT_UInt)( char_code - node->first );
|
||||
|
||||
|
||||
gindex = node->indices[offset];
|
||||
if ( gindex == FTC_CMAP_UNKNOWN )
|
||||
{
|
||||
FT_Face face;
|
||||
|
||||
|
||||
/* we need to use FT_Get_Char_Index */
|
||||
gindex = 0;
|
||||
|
||||
error = FTC_Manager_Lookup_Face( FTC_CACHE(cache)->manager,
|
||||
desc->face_id,
|
||||
&face );
|
||||
if ( !error )
|
||||
{
|
||||
FT_CharMap old, cmap = NULL;
|
||||
FT_UInt cmap_index;
|
||||
|
||||
|
||||
/* save old charmap, select new one */
|
||||
old = face->charmap;
|
||||
cmap_index = FTC_CMAP_FAMILY( FTC_QUERY( &cquery )->family )->index;
|
||||
cmap = face->charmaps[cmap_index];
|
||||
|
||||
FT_Set_Charmap( face, cmap );
|
||||
|
||||
/* perform lookup */
|
||||
gindex = FT_Get_Char_Index( face, char_code );
|
||||
node->indices[offset] = (FT_UInt16)gindex;
|
||||
|
||||
/* restore old charmap */
|
||||
FT_Set_Charmap( face, old );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gindex;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,393 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftcimage.c */
|
||||
/* */
|
||||
/* FreeType Image cache (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CACHE_H
|
||||
#include FT_CACHE_IMAGE_H
|
||||
#include FT_CACHE_INTERNAL_GLYPH_H
|
||||
#include FT_INTERNAL_MEMORY_H
|
||||
|
||||
#include "ftcerror.h"
|
||||
|
||||
#include <string.h> /* memcmp() */
|
||||
#include <stdlib.h> /* labs() */
|
||||
|
||||
|
||||
/* the FT_Glyph image node type */
|
||||
typedef struct FTC_ImageNodeRec_
|
||||
{
|
||||
FTC_GlyphNodeRec gnode;
|
||||
FT_Glyph glyph;
|
||||
|
||||
} FTC_ImageNodeRec, *FTC_ImageNode;
|
||||
|
||||
|
||||
#define FTC_IMAGE_NODE( x ) ( (FTC_ImageNode)( x ) )
|
||||
#define FTC_IMAGE_NODE_GINDEX( x ) FTC_GLYPH_NODE_GINDEX( x )
|
||||
|
||||
|
||||
/* the glyph image query */
|
||||
typedef struct FTC_ImageQueryRec_
|
||||
{
|
||||
FTC_GlyphQueryRec gquery;
|
||||
FTC_ImageDesc desc;
|
||||
|
||||
} FTC_ImageQueryRec, *FTC_ImageQuery;
|
||||
|
||||
|
||||
#define FTC_IMAGE_QUERY( x ) ( (FTC_ImageQuery)( x ) )
|
||||
|
||||
|
||||
/* the glyph image set type */
|
||||
typedef struct FTC_ImageFamilyRec_
|
||||
{
|
||||
FTC_GlyphFamilyRec gfam;
|
||||
FTC_ImageDesc desc;
|
||||
|
||||
} FTC_ImageFamilyRec, *FTC_ImageFamily;
|
||||
|
||||
|
||||
#define FTC_IMAGE_FAMILY( x ) ( (FTC_ImageFamily)( x ) )
|
||||
#define FTC_IMAGE_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &(x)->gfam )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** GLYPH IMAGE NODES *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* finalize a given glyph image node */
|
||||
FT_CALLBACK_DEF( void )
|
||||
ftc_image_node_done( FTC_ImageNode inode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
if ( inode->glyph )
|
||||
{
|
||||
FT_Done_Glyph( inode->glyph );
|
||||
inode->glyph = NULL;
|
||||
}
|
||||
|
||||
ftc_glyph_node_done( FTC_GLYPH_NODE( inode ), cache );
|
||||
}
|
||||
|
||||
|
||||
/* initialize a new glyph image node */
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_image_node_init( FTC_ImageNode inode,
|
||||
FTC_GlyphQuery gquery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family );
|
||||
FT_Error error;
|
||||
FT_Face face;
|
||||
FT_Size size;
|
||||
|
||||
|
||||
/* initialize its inner fields */
|
||||
ftc_glyph_node_init( FTC_GLYPH_NODE( inode ),
|
||||
gquery->gindex,
|
||||
FTC_GLYPH_FAMILY( ifam ) );
|
||||
|
||||
/* we will now load the glyph image */
|
||||
error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager,
|
||||
&ifam->desc.font,
|
||||
&face, &size );
|
||||
if ( !error )
|
||||
{
|
||||
FT_UInt gindex = FTC_GLYPH_NODE_GINDEX( inode );
|
||||
FT_UInt load_flags = FT_LOAD_DEFAULT;
|
||||
FT_UInt type = ifam->desc.type;
|
||||
|
||||
|
||||
if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_bitmap )
|
||||
{
|
||||
load_flags |= FT_LOAD_RENDER;
|
||||
if ( type & ftc_image_flag_monochrome )
|
||||
load_flags |= FT_LOAD_MONOCHROME;
|
||||
|
||||
/* disable embedded bitmaps loading if necessary */
|
||||
if ( type & ftc_image_flag_no_sbits )
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
}
|
||||
else if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_outline )
|
||||
{
|
||||
/* disable embedded bitmaps loading */
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
if ( type & ftc_image_flag_unscaled )
|
||||
load_flags |= FT_LOAD_NO_SCALE;
|
||||
}
|
||||
|
||||
if ( type & ftc_image_flag_unhinted )
|
||||
load_flags |= FT_LOAD_NO_HINTING;
|
||||
|
||||
if ( type & ftc_image_flag_autohinted )
|
||||
load_flags |= FT_LOAD_FORCE_AUTOHINT;
|
||||
|
||||
error = FT_Load_Glyph( face, gindex, load_flags );
|
||||
if ( !error )
|
||||
{
|
||||
if ( face->glyph->format == ft_glyph_format_bitmap ||
|
||||
face->glyph->format == ft_glyph_format_outline )
|
||||
{
|
||||
/* ok, copy it */
|
||||
FT_Glyph glyph;
|
||||
|
||||
|
||||
error = FT_Get_Glyph( face->glyph, &glyph );
|
||||
if ( !error )
|
||||
{
|
||||
inode->glyph = glyph;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
error = FTC_Err_Invalid_Argument;
|
||||
}
|
||||
}
|
||||
|
||||
/* in case of error */
|
||||
ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_ULong )
|
||||
ftc_image_node_weight( FTC_ImageNode inode )
|
||||
{
|
||||
FT_ULong size = 0;
|
||||
FT_Glyph glyph = inode->glyph;
|
||||
|
||||
|
||||
switch ( glyph->format )
|
||||
{
|
||||
case ft_glyph_format_bitmap:
|
||||
{
|
||||
FT_BitmapGlyph bitg;
|
||||
|
||||
|
||||
bitg = (FT_BitmapGlyph)glyph;
|
||||
size = bitg->bitmap.rows * labs( bitg->bitmap.pitch ) +
|
||||
sizeof ( *bitg );
|
||||
}
|
||||
break;
|
||||
|
||||
case ft_glyph_format_outline:
|
||||
{
|
||||
FT_OutlineGlyph outg;
|
||||
|
||||
|
||||
outg = (FT_OutlineGlyph)glyph;
|
||||
size = outg->outline.n_points *
|
||||
( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) +
|
||||
outg->outline.n_contours * sizeof ( FT_Short ) +
|
||||
sizeof ( *outg );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
size += sizeof ( *inode );
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** GLYPH IMAGE SETS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_image_family_init( FTC_ImageFamily ifam,
|
||||
FTC_ImageQuery iquery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_Manager manager = cache->manager;
|
||||
FT_Error error;
|
||||
FT_Face face;
|
||||
|
||||
|
||||
ifam->desc = iquery->desc;
|
||||
|
||||
/* we need to compute "iquery.item_total" now */
|
||||
error = FTC_Manager_Lookup_Face( manager,
|
||||
iquery->desc.font.face_id,
|
||||
&face );
|
||||
if ( !error )
|
||||
{
|
||||
error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( ifam ),
|
||||
FTC_IMAGE_DESC_HASH( &ifam->desc ),
|
||||
1,
|
||||
face->num_glyphs,
|
||||
FTC_GLYPH_QUERY( iquery ),
|
||||
cache );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_image_family_compare( FTC_ImageFamily ifam,
|
||||
FTC_ImageQuery iquery )
|
||||
{
|
||||
FT_Bool result;
|
||||
|
||||
|
||||
result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &ifam->desc, &iquery->desc ) );
|
||||
if ( result )
|
||||
FTC_GLYPH_FAMILY_FOUND( ifam, iquery );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** GLYPH IMAGE CACHE *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FTC_Cache_ClassRec ftc_image_cache_class =
|
||||
{
|
||||
sizeof ( FTC_CacheRec ),
|
||||
(FTC_Cache_InitFunc) ftc_cache_init,
|
||||
(FTC_Cache_ClearFunc)ftc_cache_clear,
|
||||
(FTC_Cache_DoneFunc) ftc_cache_done,
|
||||
|
||||
sizeof ( FTC_ImageFamilyRec ),
|
||||
(FTC_Family_InitFunc) ftc_image_family_init,
|
||||
(FTC_Family_CompareFunc)ftc_image_family_compare,
|
||||
(FTC_Family_DoneFunc) ftc_glyph_family_done,
|
||||
|
||||
sizeof ( FTC_ImageNodeRec ),
|
||||
(FTC_Node_InitFunc) ftc_image_node_init,
|
||||
(FTC_Node_WeightFunc) ftc_image_node_weight,
|
||||
(FTC_Node_CompareFunc)ftc_glyph_node_compare,
|
||||
(FTC_Node_DoneFunc) ftc_image_node_done
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftcimage.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_ImageCache_New( FTC_Manager manager,
|
||||
FTC_ImageCache *acache )
|
||||
{
|
||||
return FTC_Manager_Register_Cache(
|
||||
manager,
|
||||
(FTC_Cache_Class)&ftc_image_cache_class,
|
||||
FTC_CACHE_P( acache ) );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcimage.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_ImageCache_Lookup( FTC_ImageCache cache,
|
||||
FTC_ImageDesc* desc,
|
||||
FT_UInt gindex,
|
||||
FT_Glyph *aglyph,
|
||||
FTC_Node *anode )
|
||||
{
|
||||
FTC_ImageQueryRec iquery;
|
||||
FTC_ImageNode node;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
/* some argument checks are delayed to ftc_glyph_cache_lookup */
|
||||
if ( aglyph )
|
||||
*aglyph = NULL;
|
||||
|
||||
*aglyph = NULL;
|
||||
|
||||
if ( anode )
|
||||
*anode = NULL;
|
||||
|
||||
iquery.gquery.gindex = gindex;
|
||||
iquery.desc = *desc;
|
||||
|
||||
error = ftc_cache_lookup( FTC_CACHE( cache ),
|
||||
FTC_QUERY( &iquery ),
|
||||
(FTC_Node*)&node );
|
||||
if ( !error )
|
||||
{
|
||||
*aglyph = node->glyph;
|
||||
|
||||
if ( anode )
|
||||
{
|
||||
*anode = (FTC_Node)node;
|
||||
FTC_NODE( node )->ref_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* backwards-compatibility functions */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_Image_Cache_New( FTC_Manager manager,
|
||||
FTC_Image_Cache *acache )
|
||||
{
|
||||
return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_Image_Cache_Lookup( FTC_Image_Cache icache,
|
||||
FTC_Image_Desc* desc,
|
||||
FT_UInt gindex,
|
||||
FT_Glyph *aglyph )
|
||||
{
|
||||
FTC_ImageDesc desc0;
|
||||
|
||||
|
||||
if ( !desc )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
desc0.font = desc->font;
|
||||
desc0.type = (FT_UInt32)desc->image_type;
|
||||
|
||||
return FTC_ImageCache_Lookup( (FTC_ImageCache)icache,
|
||||
&desc0,
|
||||
gindex,
|
||||
aglyph,
|
||||
NULL );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,766 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftcmanag.c */
|
||||
/* */
|
||||
/* FreeType Cache Manager (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CACHE_H
|
||||
#include FT_CACHE_MANAGER_H
|
||||
#include FT_CACHE_INTERNAL_LRU_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_SIZES_H
|
||||
|
||||
#include "ftcerror.h"
|
||||
|
||||
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_cache
|
||||
|
||||
#define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** FACE LRU IMPLEMENTATION *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
typedef struct FTC_FaceNodeRec_* FTC_FaceNode;
|
||||
typedef struct FTC_SizeNodeRec_* FTC_SizeNode;
|
||||
|
||||
|
||||
typedef struct FTC_FaceNodeRec_
|
||||
{
|
||||
FT_LruNodeRec lru;
|
||||
FT_Face face;
|
||||
|
||||
} FTC_FaceNodeRec;
|
||||
|
||||
|
||||
typedef struct FTC_SizeNodeRec_
|
||||
{
|
||||
FT_LruNodeRec lru;
|
||||
FT_Size size;
|
||||
|
||||
} FTC_SizeNodeRec;
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_face_node_init( FTC_FaceNode node,
|
||||
FTC_FaceID face_id,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
error = manager->request_face( face_id,
|
||||
manager->library,
|
||||
manager->request_data,
|
||||
&node->face );
|
||||
if ( !error )
|
||||
{
|
||||
/* destroy initial size object; it will be re-created later */
|
||||
if ( node->face->size )
|
||||
FT_Done_Size( node->face->size );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* helper function for ftc_face_node_done() */
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_size_node_select( FTC_SizeNode node,
|
||||
FT_Face face )
|
||||
{
|
||||
return FT_BOOL( node->size->face == face );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ftc_face_node_done( FTC_FaceNode node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
FT_Face face = node->face;
|
||||
|
||||
|
||||
/* we must begin by removing all sizes for the target face */
|
||||
/* from the manager's list */
|
||||
FT_LruList_Remove_Selection( manager->sizes_list,
|
||||
(FT_LruNode_SelectFunc)ftc_size_node_select,
|
||||
face );
|
||||
|
||||
/* all right, we can discard the face now */
|
||||
FT_Done_Face( face );
|
||||
node->face = NULL;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FT_LruList_ClassRec ftc_face_list_class =
|
||||
{
|
||||
sizeof ( FT_LruListRec ),
|
||||
(FT_LruList_InitFunc)0,
|
||||
(FT_LruList_DoneFunc)0,
|
||||
|
||||
sizeof ( FTC_FaceNodeRec ),
|
||||
(FT_LruNode_InitFunc) ftc_face_node_init,
|
||||
(FT_LruNode_DoneFunc) ftc_face_node_done,
|
||||
(FT_LruNode_FlushFunc) 0, /* no flushing needed */
|
||||
(FT_LruNode_CompareFunc)0, /* direct comparison of FTC_FaceID handles */
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_Manager_Lookup_Face( FTC_Manager manager,
|
||||
FTC_FaceID face_id,
|
||||
FT_Face *aface )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_FaceNode node;
|
||||
|
||||
|
||||
if ( aface == NULL )
|
||||
return FTC_Err_Bad_Argument;
|
||||
|
||||
*aface = NULL;
|
||||
|
||||
if ( !manager )
|
||||
return FTC_Err_Invalid_Cache_Handle;
|
||||
|
||||
error = FT_LruList_Lookup( manager->faces_list,
|
||||
(FT_LruKey)face_id,
|
||||
(FT_LruNode*)&node );
|
||||
if ( !error )
|
||||
*aface = node->face;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** SIZES LRU IMPLEMENTATION *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
typedef struct FTC_SizeQueryRec_
|
||||
{
|
||||
FT_Face face;
|
||||
FT_UInt width;
|
||||
FT_UInt height;
|
||||
|
||||
} FTC_SizeQueryRec, *FTC_SizeQuery;
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_size_node_init( FTC_SizeNode node,
|
||||
FTC_SizeQuery query )
|
||||
{
|
||||
FT_Face face = query->face;
|
||||
FT_Size size;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
node->size = NULL;
|
||||
error = FT_New_Size( face, &size );
|
||||
if ( !error )
|
||||
{
|
||||
FT_Activate_Size( size );
|
||||
error = FT_Set_Pixel_Sizes( query->face,
|
||||
query->width,
|
||||
query->height );
|
||||
if ( error )
|
||||
FT_Done_Size( size );
|
||||
else
|
||||
node->size = size;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ftc_size_node_done( FTC_SizeNode node )
|
||||
{
|
||||
if ( node->size )
|
||||
{
|
||||
FT_Done_Size( node->size );
|
||||
node->size = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_size_node_flush( FTC_SizeNode node,
|
||||
FTC_SizeQuery query )
|
||||
{
|
||||
FT_Size size = node->size;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
if ( size->face == query->face )
|
||||
{
|
||||
FT_Activate_Size( size );
|
||||
error = FT_Set_Pixel_Sizes( query->face, query->width, query->height );
|
||||
if ( error )
|
||||
{
|
||||
FT_Done_Size( size );
|
||||
node->size = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Done_Size( size );
|
||||
node->size = NULL;
|
||||
|
||||
error = ftc_size_node_init( node, query );
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_size_node_compare( FTC_SizeNode node,
|
||||
FTC_SizeQuery query )
|
||||
{
|
||||
FT_Size size = node->size;
|
||||
|
||||
|
||||
return FT_BOOL( size->face == query->face &&
|
||||
(FT_UInt)size->metrics.x_ppem == query->width &&
|
||||
(FT_UInt)size->metrics.y_ppem == query->height );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FT_LruList_ClassRec ftc_size_list_class =
|
||||
{
|
||||
sizeof ( FT_LruListRec ),
|
||||
(FT_LruList_InitFunc)0,
|
||||
(FT_LruList_DoneFunc)0,
|
||||
|
||||
sizeof ( FTC_SizeNodeRec ),
|
||||
(FT_LruNode_InitFunc) ftc_size_node_init,
|
||||
(FT_LruNode_DoneFunc) ftc_size_node_done,
|
||||
(FT_LruNode_FlushFunc) ftc_size_node_flush,
|
||||
(FT_LruNode_CompareFunc)ftc_size_node_compare
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_Manager_Lookup_Size( FTC_Manager manager,
|
||||
FTC_Font font,
|
||||
FT_Face *aface,
|
||||
FT_Size *asize )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
/* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */
|
||||
if ( aface )
|
||||
*aface = 0;
|
||||
|
||||
if ( asize )
|
||||
*asize = 0;
|
||||
|
||||
error = FTC_Manager_Lookup_Face( manager, font->face_id, aface );
|
||||
if ( !error )
|
||||
{
|
||||
FTC_SizeQueryRec query;
|
||||
FTC_SizeNode node;
|
||||
|
||||
|
||||
query.face = *aface;
|
||||
query.width = font->pix_width;
|
||||
query.height = font->pix_height;
|
||||
|
||||
error = FT_LruList_Lookup( manager->sizes_list,
|
||||
(FT_LruKey)&query,
|
||||
(FT_LruNode*)&node );
|
||||
if ( !error )
|
||||
{
|
||||
/* select the size as the current one for this face */
|
||||
FT_Activate_Size( node->size );
|
||||
|
||||
if ( asize )
|
||||
*asize = node->size;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** SET TABLE MANAGEMENT *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static void
|
||||
ftc_family_table_init( FTC_FamilyTable table )
|
||||
{
|
||||
table->count = 0;
|
||||
table->size = 0;
|
||||
table->entries = NULL;
|
||||
table->free = FTC_FAMILY_ENTRY_NONE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ftc_family_table_done( FTC_FamilyTable table,
|
||||
FT_Memory memory )
|
||||
{
|
||||
FREE( table->entries );
|
||||
table->free = 0;
|
||||
table->count = 0;
|
||||
table->size = 0;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
ftc_family_table_alloc( FTC_FamilyTable table,
|
||||
FT_Memory memory,
|
||||
FTC_FamilyEntry *aentry )
|
||||
{
|
||||
FTC_FamilyEntry entry;
|
||||
FT_Error error = 0;
|
||||
|
||||
|
||||
/* re-allocate table size when needed */
|
||||
if ( table->free == FTC_FAMILY_ENTRY_NONE && table->count >= table->size )
|
||||
{
|
||||
FT_UInt old_size = table->size;
|
||||
FT_UInt new_size, index;
|
||||
|
||||
|
||||
if ( old_size == 0 )
|
||||
new_size = 8;
|
||||
else
|
||||
{
|
||||
new_size = old_size * 2;
|
||||
|
||||
/* check for (unlikely) overflow */
|
||||
if ( new_size < old_size )
|
||||
new_size = 65534;
|
||||
}
|
||||
|
||||
if ( REALLOC_ARRAY( table->entries, old_size, new_size,
|
||||
FTC_FamilyEntryRec ) )
|
||||
return error;
|
||||
|
||||
table->size = new_size;
|
||||
|
||||
entry = table->entries + old_size;
|
||||
table->free = old_size;
|
||||
|
||||
for ( index = old_size; index + 1 < new_size; index++, entry++ )
|
||||
{
|
||||
entry->link = index + 1;
|
||||
entry->index = index;
|
||||
}
|
||||
|
||||
entry->link = FTC_FAMILY_ENTRY_NONE;
|
||||
entry->index = index;
|
||||
}
|
||||
|
||||
if ( table->free != FTC_FAMILY_ENTRY_NONE )
|
||||
{
|
||||
entry = table->entries + table->free;
|
||||
table->free = entry->link;
|
||||
}
|
||||
else if ( table->count < table->size )
|
||||
{
|
||||
entry = table->entries + table->count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_ERROR(( "ftc_family_table_alloc: internal bug!" ));
|
||||
return FT_Err_Invalid_Argument;
|
||||
}
|
||||
|
||||
entry->link = FTC_FAMILY_ENTRY_NONE;
|
||||
table->count++;
|
||||
|
||||
*aentry = entry;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
ftc_family_table_free( FTC_FamilyTable table,
|
||||
FT_UInt index )
|
||||
{
|
||||
/* simply add it to the linked list of free entries */
|
||||
if ( index < table->count )
|
||||
{
|
||||
FTC_FamilyEntry entry = table->entries + index;
|
||||
|
||||
|
||||
if ( entry->link != FTC_FAMILY_ENTRY_NONE )
|
||||
FT_ERROR(( "ftc_family_table_free: internal bug!\n" ));
|
||||
else
|
||||
{
|
||||
entry->link = table->free;
|
||||
table->free = entry->index;
|
||||
table->count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CACHE MANAGER ROUTINES *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_Manager_New( FT_Library library,
|
||||
FT_UInt max_faces,
|
||||
FT_UInt max_sizes,
|
||||
FT_ULong max_bytes,
|
||||
FTC_Face_Requester requester,
|
||||
FT_Pointer req_data,
|
||||
FTC_Manager *amanager )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
FTC_Manager manager = 0;
|
||||
|
||||
|
||||
if ( !library )
|
||||
return FTC_Err_Invalid_Library_Handle;
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
if ( ALLOC( manager, sizeof ( *manager ) ) )
|
||||
goto Exit;
|
||||
|
||||
if ( max_faces == 0 )
|
||||
max_faces = FTC_MAX_FACES_DEFAULT;
|
||||
|
||||
if ( max_sizes == 0 )
|
||||
max_sizes = FTC_MAX_SIZES_DEFAULT;
|
||||
|
||||
if ( max_bytes == 0 )
|
||||
max_bytes = FTC_MAX_BYTES_DEFAULT;
|
||||
|
||||
error = FT_LruList_New( &ftc_face_list_class,
|
||||
max_faces,
|
||||
manager,
|
||||
memory,
|
||||
&manager->faces_list );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
error = FT_LruList_New( &ftc_size_list_class,
|
||||
max_sizes,
|
||||
manager,
|
||||
memory,
|
||||
&manager->sizes_list );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
manager->library = library;
|
||||
manager->max_weight = max_bytes;
|
||||
manager->cur_weight = 0;
|
||||
|
||||
manager->request_face = requester;
|
||||
manager->request_data = req_data;
|
||||
|
||||
ftc_family_table_init( &manager->families );
|
||||
|
||||
*amanager = manager;
|
||||
|
||||
Exit:
|
||||
if ( error && manager )
|
||||
{
|
||||
FT_LruList_Destroy( manager->faces_list );
|
||||
FT_LruList_Destroy( manager->sizes_list );
|
||||
FREE( manager );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FTC_Manager_Done( FTC_Manager manager )
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_UInt index;
|
||||
|
||||
|
||||
if ( !manager || !manager->library )
|
||||
return;
|
||||
|
||||
memory = manager->library->memory;
|
||||
|
||||
/* now discard all caches */
|
||||
for (index = 0; index < FTC_MAX_CACHES; index++ )
|
||||
{
|
||||
FTC_Cache cache = manager->caches[index];
|
||||
|
||||
|
||||
if ( cache )
|
||||
{
|
||||
cache->clazz->cache_done( cache );
|
||||
FREE( cache );
|
||||
manager->caches[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* discard families table */
|
||||
ftc_family_table_done( &manager->families, memory );
|
||||
|
||||
/* discard faces and sizes */
|
||||
FT_LruList_Destroy( manager->faces_list );
|
||||
manager->faces_list = 0;
|
||||
|
||||
FT_LruList_Destroy( manager->sizes_list );
|
||||
manager->sizes_list = 0;
|
||||
|
||||
FREE( manager );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FTC_Manager_Reset( FTC_Manager manager )
|
||||
{
|
||||
if ( manager )
|
||||
{
|
||||
FT_LruList_Reset( manager->sizes_list );
|
||||
FT_LruList_Reset( manager->faces_list );
|
||||
}
|
||||
/* XXX: FIXME: flush the caches? */
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FTC_Manager_Check( FTC_Manager manager )
|
||||
{
|
||||
FTC_Node node, first;
|
||||
|
||||
|
||||
first = manager->nodes_list;
|
||||
|
||||
/* check node weights */
|
||||
if ( first )
|
||||
{
|
||||
FT_ULong weight = 0;
|
||||
|
||||
|
||||
node = first;
|
||||
|
||||
do
|
||||
{
|
||||
FTC_FamilyEntry entry = manager->families.entries + node->fam_index;
|
||||
FTC_Cache cache;
|
||||
|
||||
if ( (FT_UInt)node->fam_index >= manager->families.count ||
|
||||
entry->link != FTC_FAMILY_ENTRY_NONE )
|
||||
FT_ERROR(( "FTC_Manager_Check: invalid node (family index = %ld\n",
|
||||
node->fam_index ));
|
||||
else
|
||||
{
|
||||
cache = entry->cache;
|
||||
weight += cache->clazz->node_weight( node, cache );
|
||||
}
|
||||
|
||||
node = node->mru_next;
|
||||
|
||||
} while ( node != first );
|
||||
|
||||
if ( weight != manager->cur_weight )
|
||||
FT_ERROR(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n",
|
||||
manager->cur_weight, weight ));
|
||||
}
|
||||
|
||||
/* check circular list */
|
||||
if ( first )
|
||||
{
|
||||
FT_UFast count = 0;
|
||||
|
||||
|
||||
node = first;
|
||||
do
|
||||
{
|
||||
count++;
|
||||
node = node->mru_next;
|
||||
|
||||
} while ( node != first );
|
||||
|
||||
if ( count != manager->num_nodes )
|
||||
FT_ERROR((
|
||||
"FTC_Manager_Check: invalid cache node count %d instead of %d\n",
|
||||
manager->num_nodes, count ));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FT_DEBUG_ERROR */
|
||||
|
||||
|
||||
/* `Compress' the manager's data, i.e., get rid of old cache nodes */
|
||||
/* that are not referenced anymore in order to limit the total */
|
||||
/* memory used by the cache. */
|
||||
|
||||
/* documentation is in ftcmanag.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FTC_Manager_Compress( FTC_Manager manager )
|
||||
{
|
||||
FTC_Node node, first;
|
||||
|
||||
|
||||
if ( !manager )
|
||||
return;
|
||||
|
||||
first = manager->nodes_list;
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
FTC_Manager_Check( manager );
|
||||
|
||||
FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n",
|
||||
manager->cur_weight, manager->max_weight,
|
||||
manager->num_nodes ));
|
||||
#endif
|
||||
|
||||
if ( manager->cur_weight < manager->max_weight || first == NULL )
|
||||
return;
|
||||
|
||||
/* go to last node - it's a circular list */
|
||||
node = first->mru_prev;
|
||||
do
|
||||
{
|
||||
FTC_Node prev = node->mru_prev;
|
||||
|
||||
|
||||
prev = ( node == first ) ? NULL : node->mru_prev;
|
||||
|
||||
if ( node->ref_count <= 0 )
|
||||
ftc_node_destroy( node, manager );
|
||||
|
||||
node = prev;
|
||||
|
||||
} while ( node && manager->cur_weight > manager->max_weight );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcmanag.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_Manager_Register_Cache( FTC_Manager manager,
|
||||
FTC_Cache_Class clazz,
|
||||
FTC_Cache *acache )
|
||||
{
|
||||
FT_Error error = FTC_Err_Invalid_Argument;
|
||||
FTC_Cache cache = NULL;
|
||||
|
||||
|
||||
if ( manager && clazz && acache )
|
||||
{
|
||||
FT_Memory memory = manager->library->memory;
|
||||
FT_UInt index = 0;
|
||||
|
||||
|
||||
/* check for an empty cache slot in the manager's table */
|
||||
for ( index = 0; index < FTC_MAX_CACHES; index++ )
|
||||
{
|
||||
if ( manager->caches[index] == 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
/* return an error if there are too many registered caches */
|
||||
if ( index >= FTC_MAX_CACHES )
|
||||
{
|
||||
error = FTC_Err_Too_Many_Caches;
|
||||
FT_ERROR(( "FTC_Manager_Register_Cache:" ));
|
||||
FT_ERROR(( " too many registered caches\n" ));
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( !ALLOC( cache, clazz->cache_size ) )
|
||||
{
|
||||
cache->manager = manager;
|
||||
cache->memory = memory;
|
||||
cache->clazz = clazz;
|
||||
|
||||
/* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */
|
||||
/* IF IT IS NOT SET CORRECTLY */
|
||||
cache->cache_index = index;
|
||||
|
||||
if ( clazz->cache_init )
|
||||
{
|
||||
error = clazz->cache_init( cache );
|
||||
if ( error )
|
||||
{
|
||||
if ( clazz->cache_done )
|
||||
clazz->cache_done( cache );
|
||||
|
||||
FREE( cache );
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
manager->caches[index] = cache;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
*acache = cache;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcmanag.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FTC_Node_Unref( FTC_Node node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
if ( node && (FT_UInt)node->fam_index < manager->families.count &&
|
||||
manager->families.entries[node->fam_index].cache )
|
||||
{
|
||||
node->ref_count--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,534 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftcsbits.c */
|
||||
/* */
|
||||
/* FreeType sbits manager (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CACHE_H
|
||||
#include FT_CACHE_SMALL_BITMAPS_H
|
||||
#include FT_CACHE_INTERNAL_GLYPH_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_ERRORS_H
|
||||
|
||||
#include "ftcerror.h"
|
||||
|
||||
#include <string.h> /* memcmp() */
|
||||
|
||||
|
||||
#define FTC_SBIT_ITEMS_PER_NODE 16
|
||||
|
||||
|
||||
typedef struct FTC_SBitNodeRec_* FTC_SBitNode;
|
||||
|
||||
typedef struct FTC_SBitNodeRec_
|
||||
{
|
||||
FTC_GlyphNodeRec gnode;
|
||||
FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE];
|
||||
|
||||
} FTC_SBitNodeRec;
|
||||
|
||||
|
||||
#define FTC_SBIT_NODE( x ) ( (FTC_SBitNode)( x ) )
|
||||
|
||||
|
||||
typedef struct FTC_SBitQueryRec_
|
||||
{
|
||||
FTC_GlyphQueryRec gquery;
|
||||
FTC_ImageDesc desc;
|
||||
|
||||
} FTC_SBitQueryRec, *FTC_SBitQuery;
|
||||
|
||||
|
||||
#define FTC_SBIT_QUERY( x ) ( (FTC_SBitQuery)( x ) )
|
||||
|
||||
|
||||
typedef struct FTC_SBitFamilyRec_* FTC_SBitFamily;
|
||||
|
||||
/* sbit family structure */
|
||||
typedef struct FTC_SBitFamilyRec_
|
||||
{
|
||||
FTC_GlyphFamilyRec gfam;
|
||||
FTC_ImageDesc desc;
|
||||
|
||||
} FTC_SBitFamilyRec;
|
||||
|
||||
|
||||
#define FTC_SBIT_FAMILY( x ) ( (FTC_SBitFamily)( x ) )
|
||||
#define FTC_SBIT_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &( x )->cset )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** SBIT CACHE NODES *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
static FT_Error
|
||||
ftc_sbit_copy_bitmap( FTC_SBit sbit,
|
||||
FT_Bitmap* bitmap,
|
||||
FT_Memory memory )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Int pitch = bitmap->pitch;
|
||||
FT_ULong size;
|
||||
|
||||
|
||||
if ( pitch < 0 )
|
||||
pitch = -pitch;
|
||||
|
||||
size = (FT_ULong)( pitch * bitmap->rows );
|
||||
|
||||
if ( !ALLOC( sbit->buffer, size ) )
|
||||
MEM_Copy( sbit->buffer, bitmap->buffer, size );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ftc_sbit_node_done( FTC_SBitNode snode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_SBit sbit = snode->sbits;
|
||||
FT_UInt count = FTC_GLYPH_NODE( snode )->item_count;
|
||||
FT_Memory memory = cache->memory;
|
||||
|
||||
|
||||
for ( ; count > 0; sbit++, count-- )
|
||||
FREE( sbit->buffer );
|
||||
|
||||
ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ftc_sbit_node_load( FTC_SBitNode snode,
|
||||
FTC_Manager manager,
|
||||
FTC_SBitFamily sfam,
|
||||
FT_UInt gindex,
|
||||
FT_ULong *asize )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode );
|
||||
FT_Memory memory;
|
||||
FT_Face face;
|
||||
FT_Size size;
|
||||
FTC_SBit sbit;
|
||||
|
||||
|
||||
if ( gindex < (FT_UInt)gnode->item_start ||
|
||||
gindex >= (FT_UInt)gnode->item_start + gnode->item_count )
|
||||
{
|
||||
FT_ERROR(( "ftc_sbit_node_load: invalid glyph index" ));
|
||||
return FTC_Err_Invalid_Argument;
|
||||
}
|
||||
|
||||
memory = manager->library->memory;
|
||||
|
||||
sbit = snode->sbits + ( gindex - gnode->item_start );
|
||||
|
||||
error = FTC_Manager_Lookup_Size( manager, &sfam->desc.font,
|
||||
&face, &size );
|
||||
if ( !error )
|
||||
{
|
||||
FT_UInt load_flags = FT_LOAD_DEFAULT;
|
||||
FT_UInt type = sfam->desc.type;
|
||||
|
||||
|
||||
/* determine load flags, depending on the font description's */
|
||||
/* image type */
|
||||
|
||||
if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_bitmap )
|
||||
{
|
||||
if ( type & ftc_image_flag_monochrome )
|
||||
load_flags |= FT_LOAD_MONOCHROME;
|
||||
|
||||
/* disable embedded bitmaps loading if necessary */
|
||||
if ( type & ftc_image_flag_no_sbits )
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_ERROR((
|
||||
"ftc_sbit_node_load: cannot load scalable glyphs in an"
|
||||
" sbit cache, please check your arguments!\n" ));
|
||||
error = FTC_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* always render glyphs to bitmaps */
|
||||
load_flags |= FT_LOAD_RENDER;
|
||||
|
||||
if ( type & ftc_image_flag_unhinted )
|
||||
load_flags |= FT_LOAD_NO_HINTING;
|
||||
|
||||
if ( type & ftc_image_flag_autohinted )
|
||||
load_flags |= FT_LOAD_FORCE_AUTOHINT;
|
||||
|
||||
/* by default, indicates a `missing' glyph */
|
||||
sbit->buffer = 0;
|
||||
|
||||
error = FT_Load_Glyph( face, gindex, load_flags );
|
||||
if ( !error )
|
||||
{
|
||||
FT_Int temp;
|
||||
FT_GlyphSlot slot = face->glyph;
|
||||
FT_Bitmap* bitmap = &slot->bitmap;
|
||||
FT_Int xadvance, yadvance;
|
||||
|
||||
|
||||
/* check that our values fit into 8-bit containers! */
|
||||
/* If this is not the case, our bitmap is too large */
|
||||
/* and we will leave it as `missing' with sbit.buffer = 0 */
|
||||
|
||||
#define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d )
|
||||
#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d )
|
||||
|
||||
/* XXX: FIXME: add support for vertical layouts maybe */
|
||||
|
||||
/* horizontal advance in pixels */
|
||||
xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6;
|
||||
yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6;
|
||||
|
||||
if ( CHECK_BYTE( bitmap->rows ) &&
|
||||
CHECK_BYTE( bitmap->width ) &&
|
||||
CHECK_CHAR( bitmap->pitch ) &&
|
||||
CHECK_CHAR( slot->bitmap_left ) &&
|
||||
CHECK_CHAR( slot->bitmap_top ) &&
|
||||
CHECK_CHAR( xadvance ) &&
|
||||
CHECK_CHAR( yadvance ) )
|
||||
{
|
||||
sbit->width = (FT_Byte)bitmap->width;
|
||||
sbit->height = (FT_Byte)bitmap->rows;
|
||||
sbit->pitch = (FT_Char)bitmap->pitch;
|
||||
sbit->left = (FT_Char)slot->bitmap_left;
|
||||
sbit->top = (FT_Char)slot->bitmap_top;
|
||||
sbit->xadvance = (FT_Char)xadvance;
|
||||
sbit->yadvance = (FT_Char)yadvance;
|
||||
sbit->format = (FT_Byte)bitmap->pixel_mode;
|
||||
|
||||
/* grab the bitmap when possible - this is a hack !! */
|
||||
if ( slot->flags & ft_glyph_own_bitmap )
|
||||
{
|
||||
slot->flags &= ~ft_glyph_own_bitmap;
|
||||
sbit->buffer = bitmap->buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* copy the bitmap into a new buffer -- ignore error */
|
||||
error = ftc_sbit_copy_bitmap( sbit, bitmap, memory );
|
||||
}
|
||||
|
||||
/* now, compute size */
|
||||
if ( asize )
|
||||
*asize = ABS( sbit->pitch ) * sbit->height;
|
||||
|
||||
} /* glyph dimensions ok */
|
||||
|
||||
} /* glyph loading successful */
|
||||
|
||||
/* ignore the errors that might have occurred -- */
|
||||
/* we mark unloaded glyphs with `sbit.buffer == 0' */
|
||||
/* and 'width == 255', 'height == 0' */
|
||||
/* */
|
||||
if ( error )
|
||||
{
|
||||
sbit->width = 255;
|
||||
error = 0;
|
||||
/* sbit->buffer == NULL too! */
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_sbit_node_init( FTC_SBitNode snode,
|
||||
FTC_GlyphQuery gquery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
ftc_glyph_node_init( FTC_GLYPH_NODE( snode ),
|
||||
gquery->gindex,
|
||||
FTC_GLYPH_FAMILY( gquery->query.family ) );
|
||||
|
||||
error = ftc_sbit_node_load( snode,
|
||||
cache->manager,
|
||||
FTC_SBIT_FAMILY( FTC_QUERY( gquery )->family ),
|
||||
gquery->gindex,
|
||||
NULL );
|
||||
if ( error )
|
||||
ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_ULong )
|
||||
ftc_sbit_node_weight( FTC_SBitNode snode )
|
||||
{
|
||||
FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode );
|
||||
FT_UInt count = gnode->item_count;
|
||||
FTC_SBit sbit = snode->sbits;
|
||||
FT_Int pitch;
|
||||
FT_ULong size;
|
||||
|
||||
|
||||
/* the node itself */
|
||||
size = sizeof ( *snode );
|
||||
|
||||
/* the sbit records */
|
||||
size += FTC_GLYPH_NODE( snode )->item_count * sizeof ( FTC_SBitRec );
|
||||
|
||||
for ( ; count > 0; count--, sbit++ )
|
||||
{
|
||||
if ( sbit->buffer )
|
||||
{
|
||||
pitch = sbit->pitch;
|
||||
if ( pitch < 0 )
|
||||
pitch = -pitch;
|
||||
|
||||
/* add the size of a given glyph image */
|
||||
size += pitch * sbit->height;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_sbit_node_compare( FTC_SBitNode snode,
|
||||
FTC_SBitQuery squery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_GlyphQuery gquery = FTC_GLYPH_QUERY( squery );
|
||||
FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode );
|
||||
FT_Bool result;
|
||||
|
||||
|
||||
result = ftc_glyph_node_compare( gnode, gquery );
|
||||
if ( result )
|
||||
{
|
||||
/* check if we need to load the glyph bitmap now */
|
||||
FT_UInt gindex = gquery->gindex;
|
||||
FTC_SBit sbit = snode->sbits + ( gindex - gnode->item_start );
|
||||
|
||||
|
||||
if ( sbit->buffer == NULL && sbit->width != 255 )
|
||||
{
|
||||
FT_ULong size;
|
||||
|
||||
|
||||
/* yes, it's safe to ignore errors here */
|
||||
ftc_sbit_node_load( snode,
|
||||
cache->manager,
|
||||
FTC_SBIT_FAMILY( FTC_QUERY( squery )->family ),
|
||||
gindex,
|
||||
&size );
|
||||
|
||||
cache->manager->cur_weight += size;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** SBITS FAMILIES *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_sbit_family_init( FTC_SBitFamily sfam,
|
||||
FTC_SBitQuery squery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_Manager manager = cache->manager;
|
||||
FT_Error error;
|
||||
FT_Face face;
|
||||
|
||||
|
||||
sfam->desc = squery->desc;
|
||||
|
||||
/* we need to compute "cquery.item_total" now */
|
||||
error = FTC_Manager_Lookup_Face( manager,
|
||||
squery->desc.font.face_id,
|
||||
&face );
|
||||
if ( !error )
|
||||
{
|
||||
error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( sfam ),
|
||||
FTC_IMAGE_DESC_HASH( &sfam->desc ),
|
||||
FTC_SBIT_ITEMS_PER_NODE,
|
||||
face->num_glyphs,
|
||||
FTC_GLYPH_QUERY( squery ),
|
||||
cache );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_sbit_family_compare( FTC_SBitFamily sfam,
|
||||
FTC_SBitQuery squery )
|
||||
{
|
||||
FT_Bool result;
|
||||
|
||||
|
||||
/* we need to set the "cquery.cset" field or our query for */
|
||||
/* faster glyph comparisons in ftc_sbit_node_compare */
|
||||
/* */
|
||||
result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &sfam->desc, &squery->desc ) );
|
||||
if ( result )
|
||||
FTC_GLYPH_FAMILY_FOUND( sfam, squery );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** SBITS CACHE *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FTC_Cache_ClassRec ftc_sbit_cache_class =
|
||||
{
|
||||
sizeof ( FTC_CacheRec ),
|
||||
(FTC_Cache_InitFunc) ftc_cache_init,
|
||||
(FTC_Cache_ClearFunc)ftc_cache_clear,
|
||||
(FTC_Cache_DoneFunc) ftc_cache_done,
|
||||
|
||||
sizeof ( FTC_SBitFamilyRec ),
|
||||
(FTC_Family_InitFunc) ftc_sbit_family_init,
|
||||
(FTC_Family_CompareFunc)ftc_sbit_family_compare,
|
||||
(FTC_Family_DoneFunc) ftc_glyph_family_done,
|
||||
|
||||
sizeof ( FTC_SBitNodeRec ),
|
||||
(FTC_Node_InitFunc) ftc_sbit_node_init,
|
||||
(FTC_Node_WeightFunc) ftc_sbit_node_weight,
|
||||
(FTC_Node_CompareFunc)ftc_sbit_node_compare,
|
||||
(FTC_Node_DoneFunc) ftc_sbit_node_done
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftcsbits.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_SBitCache_New( FTC_Manager manager,
|
||||
FTC_SBitCache *acache )
|
||||
{
|
||||
return FTC_Manager_Register_Cache( manager,
|
||||
&ftc_sbit_cache_class,
|
||||
(FTC_Cache*)acache );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcsbits.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_SBitCache_Lookup( FTC_SBitCache cache,
|
||||
FTC_ImageDesc* desc,
|
||||
FT_UInt gindex,
|
||||
FTC_SBit *ansbit,
|
||||
FTC_Node *anode )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_SBitQueryRec squery;
|
||||
FTC_SBitNode node;
|
||||
|
||||
|
||||
/* other argument checks delayed to ftc_cache_lookup */
|
||||
if ( !ansbit )
|
||||
return FTC_Err_Invalid_Argument;
|
||||
|
||||
*ansbit = NULL;
|
||||
|
||||
if ( anode )
|
||||
*anode = NULL;
|
||||
|
||||
squery.gquery.gindex = gindex;
|
||||
squery.desc = *desc;
|
||||
|
||||
error = ftc_cache_lookup( FTC_CACHE( cache ),
|
||||
FTC_QUERY( &squery ),
|
||||
(FTC_Node*)&node );
|
||||
if ( !error )
|
||||
{
|
||||
*ansbit = node->sbits + ( gindex - FTC_GLYPH_NODE( node )->item_start );
|
||||
|
||||
if ( anode )
|
||||
{
|
||||
*anode = FTC_NODE( node );
|
||||
FTC_NODE( node )->ref_count++;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* backwards-compatibility functions */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_SBit_Cache_New( FTC_Manager manager,
|
||||
FTC_SBit_Cache *acache )
|
||||
{
|
||||
return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache,
|
||||
FTC_Image_Desc* desc,
|
||||
FT_UInt gindex,
|
||||
FTC_SBit *ansbit )
|
||||
{
|
||||
FTC_ImageDesc desc0;
|
||||
|
||||
|
||||
if ( !desc )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
desc0.font = desc->font;
|
||||
desc0.type = (FT_UInt32)desc->image_type;
|
||||
|
||||
return FTC_SBitCache_Lookup( (FTC_SBitCache)cache,
|
||||
&desc0,
|
||||
gindex,
|
||||
ansbit,
|
||||
NULL );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,338 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftlru.c */
|
||||
/* */
|
||||
/* Simple LRU list-cache (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CACHE_H
|
||||
#include FT_CACHE_INTERNAL_LRU_H
|
||||
#include FT_LIST_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
#include "ftcerror.h"
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_LruList_New( FT_LruList_Class clazz,
|
||||
FT_UInt max_nodes,
|
||||
FT_Pointer user_data,
|
||||
FT_Memory memory,
|
||||
FT_LruList *alist )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_LruList list;
|
||||
|
||||
|
||||
if ( !alist || !clazz )
|
||||
return FTC_Err_Invalid_Argument;
|
||||
|
||||
*alist = NULL;
|
||||
if ( !ALLOC( list, clazz->list_size ) )
|
||||
{
|
||||
/* initialize common fields */
|
||||
list->clazz = clazz;
|
||||
list->memory = memory;
|
||||
list->max_nodes = max_nodes;
|
||||
list->data = user_data;
|
||||
|
||||
if ( clazz->list_init )
|
||||
{
|
||||
error = clazz->list_init( list );
|
||||
if ( error )
|
||||
{
|
||||
if ( clazz->list_done )
|
||||
clazz->list_done( list );
|
||||
|
||||
FREE( list );
|
||||
}
|
||||
}
|
||||
|
||||
*alist = list;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_LruList_Destroy( FT_LruList list )
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_LruList_Class clazz;
|
||||
|
||||
|
||||
if ( !list )
|
||||
return;
|
||||
|
||||
memory = list->memory;
|
||||
clazz = list->clazz;
|
||||
|
||||
FT_LruList_Reset( list );
|
||||
|
||||
if ( clazz->list_done )
|
||||
clazz->list_done( list );
|
||||
|
||||
FREE( list );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_LruList_Reset( FT_LruList list )
|
||||
{
|
||||
FT_LruNode node;
|
||||
FT_LruList_Class clazz;
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
if ( !list )
|
||||
return;
|
||||
|
||||
node = list->nodes;
|
||||
clazz = list->clazz;
|
||||
memory = list->memory;
|
||||
|
||||
while ( node )
|
||||
{
|
||||
FT_LruNode next = node->next;
|
||||
|
||||
|
||||
if ( clazz->node_done )
|
||||
clazz->node_done( node, list->data );
|
||||
|
||||
FREE( node );
|
||||
node = next;
|
||||
}
|
||||
|
||||
list->nodes = NULL;
|
||||
list->num_nodes = 0;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_LruList_Lookup( FT_LruList list,
|
||||
FT_LruKey key,
|
||||
FT_LruNode *anode )
|
||||
{
|
||||
FT_Error error = 0;
|
||||
FT_LruNode node, *pnode;
|
||||
FT_LruList_Class clazz;
|
||||
FT_LruNode* plast;
|
||||
FT_LruNode result = NULL;
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
if ( !list || !key || !anode )
|
||||
return FTC_Err_Invalid_Argument;
|
||||
|
||||
pnode = &list->nodes;
|
||||
plast = pnode;
|
||||
node = NULL;
|
||||
clazz = list->clazz;
|
||||
memory = list->memory;
|
||||
|
||||
if ( clazz->node_compare )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
node = *pnode;
|
||||
if ( node == NULL )
|
||||
break;
|
||||
|
||||
if ( clazz->node_compare( node, key, list->data ) )
|
||||
break;
|
||||
|
||||
plast = pnode;
|
||||
pnode = &(*pnode)->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
node = *pnode;
|
||||
if ( node == NULL )
|
||||
break;
|
||||
|
||||
if ( node->key == key )
|
||||
break;
|
||||
|
||||
plast = pnode;
|
||||
pnode = &(*pnode)->next;
|
||||
}
|
||||
}
|
||||
|
||||
if ( node )
|
||||
{
|
||||
/* move element to top of list */
|
||||
if ( list->nodes != node )
|
||||
{
|
||||
*pnode = node->next;
|
||||
node->next = list->nodes;
|
||||
list->nodes = node;
|
||||
}
|
||||
result = node;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* we haven't found the relevant element. We will now try */
|
||||
/* to create a new one. */
|
||||
/* */
|
||||
|
||||
/* first, check if our list if full, when appropriate */
|
||||
if ( list->max_nodes > 0 && list->num_nodes >= list->max_nodes )
|
||||
{
|
||||
/* this list list is full; we will now flush */
|
||||
/* the oldest node, if there's one! */
|
||||
FT_LruNode last = *plast;
|
||||
|
||||
|
||||
if ( last )
|
||||
{
|
||||
if ( clazz->node_flush )
|
||||
{
|
||||
error = clazz->node_flush( last, key, list->data );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( clazz->node_done )
|
||||
clazz->node_done( last, list->data );
|
||||
|
||||
last->key = key;
|
||||
error = clazz->node_init( last, key, list->data );
|
||||
}
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
/* move it to the top of the list */
|
||||
*plast = NULL;
|
||||
last->next = list->nodes;
|
||||
list->nodes = last;
|
||||
|
||||
result = last;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* in case of error during the flush or done/init cycle, */
|
||||
/* we need to discard the node */
|
||||
if ( clazz->node_done )
|
||||
clazz->node_done( last, list->data );
|
||||
|
||||
*plast = NULL;
|
||||
list->num_nodes--;
|
||||
|
||||
FREE( last );
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise, simply allocate a new node */
|
||||
if ( ALLOC( node, clazz->node_size ) )
|
||||
goto Exit;
|
||||
|
||||
node->key = key;
|
||||
error = clazz->node_init( node, key, list->data );
|
||||
if ( error )
|
||||
{
|
||||
FREE( node );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
result = node;
|
||||
node->next = list->nodes;
|
||||
list->nodes = node;
|
||||
list->num_nodes++;
|
||||
|
||||
Exit:
|
||||
*anode = result;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_LruList_Remove( FT_LruList list,
|
||||
FT_LruNode node )
|
||||
{
|
||||
FT_LruNode *pnode;
|
||||
|
||||
|
||||
if ( !list || !node )
|
||||
return;
|
||||
|
||||
pnode = &list->nodes;
|
||||
for (;;)
|
||||
{
|
||||
if ( *pnode == node )
|
||||
{
|
||||
FT_Memory memory = list->memory;
|
||||
FT_LruList_Class clazz = list->clazz;
|
||||
|
||||
|
||||
*pnode = node->next;
|
||||
node->next = NULL;
|
||||
|
||||
if ( clazz->node_done )
|
||||
clazz->node_done( node, list->data );
|
||||
|
||||
FREE( node );
|
||||
list->num_nodes--;
|
||||
break;
|
||||
}
|
||||
|
||||
pnode = &(*pnode)->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_LruList_Remove_Selection( FT_LruList list,
|
||||
FT_LruNode_SelectFunc select_func,
|
||||
FT_Pointer select_data )
|
||||
{
|
||||
FT_LruNode *pnode, node;
|
||||
FT_LruList_Class clazz;
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
if ( !list || !select_func )
|
||||
return;
|
||||
|
||||
memory = list->memory;
|
||||
clazz = list->clazz;
|
||||
pnode = &list->nodes;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
node = *pnode;
|
||||
if ( node == NULL )
|
||||
break;
|
||||
|
||||
if ( select_func( node, select_data, list->data ) )
|
||||
{
|
||||
*pnode = node->next;
|
||||
node->next = NULL;
|
||||
|
||||
if ( clazz->node_done )
|
||||
clazz->node_done( node, list );
|
||||
|
||||
FREE( node );
|
||||
}
|
||||
else
|
||||
pnode = &(*pnode)->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,80 +0,0 @@
|
|||
#
|
||||
# FreeType 2 Cache configuration rules
|
||||
#
|
||||
|
||||
|
||||
# Copyright 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.
|
||||
|
||||
|
||||
# Cache driver directory
|
||||
#
|
||||
CACHE_DIR := $(SRC_)cache
|
||||
CACHE_DIR_ := $(CACHE_DIR)$(SEP)
|
||||
|
||||
CACHE_H_DIR := $(PUBLIC_)cache
|
||||
CACHE_H_DIR_ := $(CACHE_H_DIR)$(SEP)
|
||||
|
||||
# compilation flags for the driver
|
||||
#
|
||||
Cache_COMPILE := $(FT_COMPILE) $I$(CACHE_DIR)
|
||||
|
||||
|
||||
# Cache driver sources (i.e., C files)
|
||||
#
|
||||
Cache_DRV_SRC := $(CACHE_DIR_)ftlru.c \
|
||||
$(CACHE_DIR_)ftcmanag.c \
|
||||
$(CACHE_DIR_)ftccache.c \
|
||||
$(CACHE_DIR_)ftcglyph.c \
|
||||
$(CACHE_DIR_)ftcsbits.c \
|
||||
$(CACHE_DIR_)ftcimage.c \
|
||||
$(CACHE_DIR_)ftccmap.c
|
||||
|
||||
# Cache driver headers
|
||||
#
|
||||
Cache_DRV_H := $(CACHE_H_DIR_)ftlru.h \
|
||||
$(CACHE_H_DIR_)ftcmanag.h \
|
||||
$(CACHE_H_DIR_)ftcglyph.h \
|
||||
$(CACHE_H_DIR_)ftcimage.h \
|
||||
$(CACHE_DIR_)ftcerror.h
|
||||
|
||||
|
||||
# Cache driver object(s)
|
||||
#
|
||||
# Cache_DRV_OBJ_M is used during `multi' builds.
|
||||
# Cache_DRV_OBJ_S is used during `single' builds.
|
||||
#
|
||||
Cache_DRV_OBJ_M := $(Cache_DRV_SRC:$(CACHE_DIR_)%.c=$(OBJ_)%.$O)
|
||||
Cache_DRV_OBJ_S := $(OBJ_)ftcache.$O
|
||||
|
||||
# Cache driver source file for single build
|
||||
#
|
||||
Cache_DRV_SRC_S := $(CACHE_DIR_)ftcache.c
|
||||
|
||||
|
||||
# Cache driver - single object
|
||||
#
|
||||
$(Cache_DRV_OBJ_S): $(Cache_DRV_SRC_S) $(Cache_DRV_SRC) \
|
||||
$(FREETYPE_H) $(Cache_DRV_H)
|
||||
$(Cache_COMPILE) $T$@ $(Cache_DRV_SRC_S)
|
||||
|
||||
|
||||
# Cache driver - multiple objects
|
||||
#
|
||||
$(OBJ_)%.$O: $(CACHE_DIR_)%.c $(FREETYPE_H) $(Cache_DRV_H)
|
||||
$(Cache_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
# update main driver object lists
|
||||
#
|
||||
DRV_OBJS_S += $(Cache_DRV_OBJ_S)
|
||||
DRV_OBJS_M += $(Cache_DRV_OBJ_M)
|
||||
|
||||
|
||||
# EOF
|
|
@ -1,539 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cffdrivr.c */
|
||||
/* */
|
||||
/* OpenType font driver implementation (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include FT_INTERNAL_SFNT_H
|
||||
#include FT_TRUETYPE_IDS_H
|
||||
|
||||
#include "cffdrivr.h"
|
||||
#include "cffgload.h"
|
||||
#include "cffload.h"
|
||||
|
||||
#include "cfferrs.h"
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_cffdriver
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/**** F A C E S ****/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#undef PAIR_TAG
|
||||
#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
|
||||
(FT_ULong)right )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* Get_Kerning */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A driver method used to return the kerning vector between two */
|
||||
/* glyphs of the same face. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A handle to the source face object. */
|
||||
/* */
|
||||
/* left_glyph :: The index of the left glyph in the kern pair. */
|
||||
/* */
|
||||
/* right_glyph :: The index of the right glyph in the kern pair. */
|
||||
/* */
|
||||
/* <Output> */
|
||||
/* kerning :: The kerning vector. This is in font units for */
|
||||
/* scalable formats, and in pixels for fixed-sizes */
|
||||
/* formats. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* Only horizontal layouts (left-to-right & right-to-left) are */
|
||||
/* supported by this function. Other layouts, or more sophisticated */
|
||||
/* kernings, are out of scope of this method (the basic driver */
|
||||
/* interface is meant to be simple). */
|
||||
/* */
|
||||
/* They can be implemented by format-specific interfaces. */
|
||||
/* */
|
||||
static FT_Error
|
||||
Get_Kerning( TT_Face face,
|
||||
FT_UInt left_glyph,
|
||||
FT_UInt right_glyph,
|
||||
FT_Vector* kerning )
|
||||
{
|
||||
TT_Kern_0_Pair* pair;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return CFF_Err_Invalid_Face_Handle;
|
||||
|
||||
kerning->x = 0;
|
||||
kerning->y = 0;
|
||||
|
||||
if ( face->kern_pairs )
|
||||
{
|
||||
/* there are some kerning pairs in this font file! */
|
||||
FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph );
|
||||
FT_Long left, right;
|
||||
|
||||
|
||||
left = 0;
|
||||
right = face->num_kern_pairs - 1;
|
||||
|
||||
while ( left <= right )
|
||||
{
|
||||
FT_Int middle = left + ( ( right - left ) >> 1 );
|
||||
FT_ULong cur_pair;
|
||||
|
||||
|
||||
pair = face->kern_pairs + middle;
|
||||
cur_pair = PAIR_TAG( pair->left, pair->right );
|
||||
|
||||
if ( cur_pair == search_tag )
|
||||
goto Found;
|
||||
|
||||
if ( cur_pair < search_tag )
|
||||
left = middle + 1;
|
||||
else
|
||||
right = middle - 1;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return CFF_Err_Ok;
|
||||
|
||||
Found:
|
||||
kerning->x = pair->value;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
#undef PAIR_TAG
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* Load_Glyph */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A driver method used to load a glyph within a given glyph slot. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* slot :: A handle to the target slot object where the glyph */
|
||||
/* will be loaded. */
|
||||
/* */
|
||||
/* size :: A handle to the source face size at which the glyph */
|
||||
/* must be scaled, loaded, etc. */
|
||||
/* */
|
||||
/* glyph_index :: The index of the glyph in the font file. */
|
||||
/* */
|
||||
/* load_flags :: A flag indicating what to load for this glyph. The */
|
||||
/* FTLOAD_??? constants can be used to control the */
|
||||
/* glyph loading process (e.g., whether the outline */
|
||||
/* should be scaled, whether to load bitmaps or not, */
|
||||
/* whether to hint the outline, etc). */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
static FT_Error
|
||||
Load_Glyph( CFF_GlyphSlot slot,
|
||||
CFF_Size size,
|
||||
FT_UShort glyph_index,
|
||||
FT_UInt load_flags )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
if ( !slot )
|
||||
return CFF_Err_Invalid_Slot_Handle;
|
||||
|
||||
/* check whether we want a scaled outline or bitmap */
|
||||
if ( !size )
|
||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
||||
|
||||
if ( load_flags & FT_LOAD_NO_SCALE )
|
||||
size = NULL;
|
||||
|
||||
/* reset the size object if necessary */
|
||||
if ( size )
|
||||
{
|
||||
/* these two object must have the same parent */
|
||||
if ( size->face != slot->root.face )
|
||||
return CFF_Err_Invalid_Face_Handle;
|
||||
}
|
||||
|
||||
/* now load the glyph outline if necessary */
|
||||
error = CFF_Load_Glyph( slot, size, glyph_index, load_flags );
|
||||
|
||||
/* force drop-out mode to 2 - irrelevant now */
|
||||
/* slot->outline.dropout_mode = 2; */
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/**** C H A R A C T E R M A P P I N G S ****/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static FT_Error
|
||||
cff_get_glyph_name( CFF_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_Pointer buffer,
|
||||
FT_UInt buffer_max )
|
||||
{
|
||||
CFF_Font* font = (CFF_Font*)face->extra.data;
|
||||
FT_Memory memory = FT_FACE_MEMORY( face );
|
||||
FT_String* gname;
|
||||
FT_UShort sid;
|
||||
PSNames_Interface* psnames;
|
||||
FT_Error error;
|
||||
|
||||
psnames = (PSNames_Interface*)FT_Get_Module_Interface(
|
||||
face->root.driver->root.library, "psnames" );
|
||||
|
||||
if ( !psnames )
|
||||
{
|
||||
FT_ERROR(( "CFF_Init_Face:" ));
|
||||
FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
|
||||
FT_ERROR(( " " ));
|
||||
FT_ERROR(( " without the `PSNames' module\n" ));
|
||||
error = CFF_Err_Unknown_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* first, locate the sid in the charset table */
|
||||
sid = font->charset.sids[glyph_index];
|
||||
|
||||
/* now, lookup the name itself */
|
||||
gname = CFF_Get_String( &font->string_index, sid, psnames );
|
||||
|
||||
if ( buffer_max > 0 )
|
||||
{
|
||||
FT_UInt len = strlen( gname );
|
||||
|
||||
|
||||
if ( len >= buffer_max )
|
||||
len = buffer_max - 1;
|
||||
|
||||
MEM_Copy( buffer, gname, len );
|
||||
((FT_Byte*)buffer)[len] = 0;
|
||||
}
|
||||
|
||||
FREE ( gname );
|
||||
error = CFF_Err_Ok;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* cff_get_char_index */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Uses a charmap to return a given character code's glyph index. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* charmap :: A handle to the source charmap object. */
|
||||
/* charcode :: The character code. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Glyph index. 0 means `undefined character code'. */
|
||||
/* */
|
||||
static FT_UInt
|
||||
cff_get_char_index( TT_CharMap charmap,
|
||||
FT_Long charcode )
|
||||
{
|
||||
FT_Error error;
|
||||
CFF_Face face;
|
||||
TT_CMapTable* cmap;
|
||||
|
||||
|
||||
cmap = &charmap->cmap;
|
||||
face = (CFF_Face)charmap->root.face;
|
||||
|
||||
/* Load table if needed */
|
||||
if ( !cmap->loaded )
|
||||
{
|
||||
SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
|
||||
|
||||
|
||||
error = sfnt->load_charmap( face, cmap, face->root.stream );
|
||||
if ( error )
|
||||
return 0;
|
||||
|
||||
cmap->loaded = TRUE;
|
||||
}
|
||||
|
||||
return ( cmap->get_index ? cmap->get_index( cmap, charcode ) : 0 );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* cff_get_next_char */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Uses a charmap to return the next encoded charcode. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* charmap :: A handle to the source charmap object. */
|
||||
/* charcode :: The character code. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Char code. 0 means `no encoded chars above the given one'. */
|
||||
/* */
|
||||
static FT_Long
|
||||
cff_get_next_char( TT_CharMap charmap,
|
||||
FT_Long charcode )
|
||||
{
|
||||
FT_Error error;
|
||||
CFF_Face face;
|
||||
TT_CMapTable* cmap;
|
||||
|
||||
|
||||
cmap = &charmap->cmap;
|
||||
face = (CFF_Face)charmap->root.face;
|
||||
|
||||
/* Load table if needed */
|
||||
if ( !cmap->loaded )
|
||||
{
|
||||
SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
|
||||
|
||||
|
||||
error = sfnt->load_charmap( face, cmap, face->root.stream );
|
||||
if ( error )
|
||||
return 0;
|
||||
|
||||
cmap->loaded = TRUE;
|
||||
}
|
||||
|
||||
return ( cmap->get_next_char ? cmap->get_next_char( cmap, charcode ) : 0 );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* cff_get_name_index */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Uses the psnames module and the CFF font's charset to to return a */
|
||||
/* a given glyph name's glyph index. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A handle to the source face object. */
|
||||
/* */
|
||||
/* glyph_name :: The glyph name. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Glyph index. 0 means `undefined character code'. */
|
||||
/* */
|
||||
static FT_UInt
|
||||
cff_get_name_index( CFF_Face face,
|
||||
FT_String* glyph_name )
|
||||
{
|
||||
CFF_Font* cff;
|
||||
CFF_Charset* charset;
|
||||
PSNames_Interface* psnames;
|
||||
FT_Memory memory = FT_FACE_MEMORY( face );
|
||||
FT_String* name;
|
||||
FT_UShort sid;
|
||||
FT_UInt i;
|
||||
FT_Int result;
|
||||
|
||||
|
||||
cff = face->extra.data;
|
||||
charset = &cff->charset;
|
||||
|
||||
psnames = (PSNames_Interface*)FT_Get_Module_Interface(
|
||||
face->root.driver->root.library, "psnames" );
|
||||
|
||||
for ( i = 0; i < cff->num_glyphs; i++ )
|
||||
{
|
||||
sid = charset->sids[i];
|
||||
|
||||
if ( sid > 390 )
|
||||
name = CFF_Get_Name( &cff->string_index, sid - 391 );
|
||||
else
|
||||
name = (FT_String *)psnames->adobe_std_strings( sid );
|
||||
|
||||
result = strcmp( glyph_name, name );
|
||||
|
||||
if ( sid > 390 )
|
||||
FREE( name );
|
||||
|
||||
if ( !result )
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/**** D R I V E R I N T E R F A C E ****/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static FT_Module_Interface
|
||||
cff_get_interface( CFF_Driver driver,
|
||||
const char* interface )
|
||||
{
|
||||
FT_Module sfnt;
|
||||
|
||||
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
|
||||
|
||||
if ( strcmp( (const char*)interface, "glyph_name" ) == 0 )
|
||||
return (FT_Module_Interface)cff_get_glyph_name;
|
||||
|
||||
if ( strcmp( (const char*)interface, "name_index" ) == 0 )
|
||||
return (FT_Module_Interface)cff_get_name_index;
|
||||
|
||||
#endif
|
||||
|
||||
/* we simply pass our request to the `sfnt' module */
|
||||
sfnt = FT_Get_Module( driver->root.root.library, "sfnt" );
|
||||
|
||||
return sfnt ? sfnt->clazz->get_interface( sfnt, interface ) : 0;
|
||||
}
|
||||
|
||||
|
||||
/* The FT_DriverInterface structure is defined in ftdriver.h. */
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FT_Driver_Class cff_driver_class =
|
||||
{
|
||||
/* begin with the FT_Module_Class fields */
|
||||
{
|
||||
ft_module_font_driver |
|
||||
ft_module_driver_scalable |
|
||||
ft_module_driver_has_hinter,
|
||||
|
||||
sizeof( CFF_DriverRec ),
|
||||
"cff",
|
||||
0x10000L,
|
||||
0x20000L,
|
||||
|
||||
0, /* module-specific interface */
|
||||
|
||||
(FT_Module_Constructor)CFF_Driver_Init,
|
||||
(FT_Module_Destructor) CFF_Driver_Done,
|
||||
(FT_Module_Requester) cff_get_interface,
|
||||
},
|
||||
|
||||
/* now the specific driver fields */
|
||||
sizeof( TT_FaceRec ),
|
||||
sizeof( FT_SizeRec ),
|
||||
sizeof( CFF_GlyphSlotRec ),
|
||||
|
||||
(FTDriver_initFace) CFF_Face_Init,
|
||||
(FTDriver_doneFace) CFF_Face_Done,
|
||||
(FTDriver_initSize) CFF_Size_Init,
|
||||
(FTDriver_doneSize) CFF_Size_Done,
|
||||
(FTDriver_initGlyphSlot)CFF_GlyphSlot_Init,
|
||||
(FTDriver_doneGlyphSlot)CFF_GlyphSlot_Done,
|
||||
|
||||
(FTDriver_setCharSizes) CFF_Size_Reset,
|
||||
(FTDriver_setPixelSizes)CFF_Size_Reset,
|
||||
|
||||
(FTDriver_loadGlyph) Load_Glyph,
|
||||
(FTDriver_getCharIndex) cff_get_char_index,
|
||||
|
||||
(FTDriver_getKerning) Get_Kerning,
|
||||
(FTDriver_attachFile) 0,
|
||||
(FTDriver_getAdvances) 0,
|
||||
|
||||
(FTDriver_getNextChar) cff_get_next_char
|
||||
};
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* getDriverClass */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* This function is used when compiling the TrueType driver as a */
|
||||
/* shared library (`.DLL' or `.so'). It will be used by the */
|
||||
/* high-level library of FreeType to retrieve the address of the */
|
||||
/* driver's generic interface. */
|
||||
/* */
|
||||
/* It shouldn't be implemented in a static build, as each driver must */
|
||||
/* have the same function as an exported entry point. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of the TrueType's driver generic interface. The */
|
||||
/* format-specific interface can then be retrieved through the method */
|
||||
/* interface->get_format_interface. */
|
||||
/* */
|
||||
FT_EXPORT_DEF( const FT_Driver_Class* )
|
||||
getDriverClass( void )
|
||||
{
|
||||
return &cff_driver_class;
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,39 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cffdrivr.h */
|
||||
/* */
|
||||
/* High-level OpenType driver interface (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CFFDRIVER_H__
|
||||
#define __CFFDRIVER_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DRIVER_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE
|
||||
const FT_Driver_Class cff_driver_class;
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __CFFDRIVER_H__ */
|
||||
|
||||
|
||||
/* END */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,207 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cffgload.h */
|
||||
/* */
|
||||
/* OpenType Glyph Loader (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CFFGLOAD_H__
|
||||
#define __CFFGLOAD_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "cffobjs.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
#define CFF_MAX_OPERANDS 48
|
||||
#define CFF_MAX_SUBRS_CALLS 32
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Structure> */
|
||||
/* CFF_Builder */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A structure used during glyph loading to store its outline. */
|
||||
/* */
|
||||
/* <Fields> */
|
||||
/* memory :: The current memory object. */
|
||||
/* */
|
||||
/* face :: The current face object. */
|
||||
/* */
|
||||
/* glyph :: The current glyph slot. */
|
||||
/* */
|
||||
/* current :: The current glyph outline. */
|
||||
/* */
|
||||
/* base :: The base glyph outline. */
|
||||
/* */
|
||||
/* max_points :: maximum points in builder outline */
|
||||
/* */
|
||||
/* max_contours :: Maximal number of contours in builder outline. */
|
||||
/* */
|
||||
/* last :: The last point position. */
|
||||
/* */
|
||||
/* scale_x :: The horizontal scale (FUnits to sub-pixels). */
|
||||
/* */
|
||||
/* scale_y :: The vertical scale (FUnits to sub-pixels). */
|
||||
/* */
|
||||
/* pos_x :: The horizontal translation (if composite glyph). */
|
||||
/* */
|
||||
/* pos_y :: The vertical translation (if composite glyph). */
|
||||
/* */
|
||||
/* left_bearing :: The left side bearing point. */
|
||||
/* */
|
||||
/* advance :: The horizontal advance vector. */
|
||||
/* */
|
||||
/* bbox :: Unused. */
|
||||
/* */
|
||||
/* path_begun :: A flag which indicates that a new path has begun. */
|
||||
/* */
|
||||
/* load_points :: If this flag is not set, no points are loaded. */
|
||||
/* */
|
||||
/* no_recurse :: Set but not used. */
|
||||
/* */
|
||||
/* error :: An error code that is only used to report memory */
|
||||
/* allocation problems. */
|
||||
/* */
|
||||
/* metrics_only :: A boolean indicating that we only want to compute */
|
||||
/* the metrics of a given glyph, not load all of its */
|
||||
/* points. */
|
||||
/* */
|
||||
typedef struct CFF_Builder_
|
||||
{
|
||||
FT_Memory memory;
|
||||
TT_Face face;
|
||||
CFF_GlyphSlot glyph;
|
||||
FT_GlyphLoader* loader;
|
||||
FT_Outline* base;
|
||||
FT_Outline* current;
|
||||
|
||||
FT_Vector last;
|
||||
|
||||
FT_Fixed scale_x;
|
||||
FT_Fixed scale_y;
|
||||
|
||||
FT_Pos pos_x;
|
||||
FT_Pos pos_y;
|
||||
|
||||
FT_Vector left_bearing;
|
||||
FT_Vector advance;
|
||||
|
||||
FT_BBox bbox; /* bounding box */
|
||||
FT_Bool path_begun;
|
||||
FT_Bool load_points;
|
||||
FT_Bool no_recurse;
|
||||
|
||||
FT_Error error; /* only used for memory errors */
|
||||
FT_Bool metrics_only;
|
||||
|
||||
void* hints_funcs; /* hinter-specific */
|
||||
void* hints_globals; /* hinter-specific */
|
||||
|
||||
} CFF_Builder;
|
||||
|
||||
|
||||
/* execution context charstring zone */
|
||||
|
||||
typedef struct CFF_Decoder_Zone_
|
||||
{
|
||||
FT_Byte* base;
|
||||
FT_Byte* limit;
|
||||
FT_Byte* cursor;
|
||||
|
||||
} CFF_Decoder_Zone;
|
||||
|
||||
|
||||
typedef struct CFF_Decoder_
|
||||
{
|
||||
CFF_Builder builder;
|
||||
CFF_Font* cff;
|
||||
|
||||
FT_Fixed stack[CFF_MAX_OPERANDS + 1];
|
||||
FT_Fixed* top;
|
||||
|
||||
CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS + 1];
|
||||
CFF_Decoder_Zone* zone;
|
||||
|
||||
FT_Int flex_state;
|
||||
FT_Int num_flex_vectors;
|
||||
FT_Vector flex_vectors[7];
|
||||
|
||||
FT_Pos glyph_width;
|
||||
FT_Pos nominal_width;
|
||||
|
||||
FT_Bool read_width;
|
||||
FT_Int num_hints;
|
||||
FT_Fixed* buildchar;
|
||||
FT_Int len_buildchar;
|
||||
|
||||
FT_UInt num_locals;
|
||||
FT_UInt num_globals;
|
||||
|
||||
FT_Int locals_bias;
|
||||
FT_Int globals_bias;
|
||||
|
||||
FT_Byte** locals;
|
||||
FT_Byte** globals;
|
||||
|
||||
FT_Byte** glyph_names; /* for pure CFF fonts only */
|
||||
FT_UInt num_glyphs; /* number of glyphs in font */
|
||||
|
||||
} CFF_Decoder;
|
||||
|
||||
|
||||
FT_LOCAL void
|
||||
CFF_Init_Decoder( CFF_Decoder* decoder,
|
||||
TT_Face face,
|
||||
CFF_Size size,
|
||||
CFF_GlyphSlot slot,
|
||||
FT_Bool hinting );
|
||||
|
||||
FT_LOCAL void
|
||||
CFF_Prepare_Decoder( CFF_Decoder* decoder,
|
||||
FT_UInt glyph_index );
|
||||
|
||||
#if 0 /* unused until we support pure CFF fonts */
|
||||
|
||||
/* Compute the maximum advance width of a font through quick parsing */
|
||||
FT_LOCAL FT_Error
|
||||
CFF_Compute_Max_Advance( TT_Face face,
|
||||
FT_Int* max_advance );
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CFF_Parse_CharStrings( CFF_Decoder* decoder,
|
||||
FT_Byte* charstring_base,
|
||||
FT_Int charstring_len );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CFF_Load_Glyph( CFF_GlyphSlot glyph,
|
||||
CFF_Size size,
|
||||
FT_Int glyph_index,
|
||||
FT_Int load_flags );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __CFFGLOAD_H__ */
|
||||
|
||||
|
||||
/* END */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,74 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cffload.h */
|
||||
/* */
|
||||
/* OpenType & CFF data/program tables loader (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CFFLOAD_H__
|
||||
#define __CFFLOAD_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_CFF_TYPES_H
|
||||
#include FT_INTERNAL_POSTSCRIPT_NAMES_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
FT_LOCAL FT_UShort
|
||||
CFF_Get_Standard_Encoding( FT_UInt charcode );
|
||||
|
||||
|
||||
FT_LOCAL FT_String*
|
||||
CFF_Get_Name( CFF_Index* index,
|
||||
FT_UInt element );
|
||||
|
||||
FT_LOCAL FT_String*
|
||||
CFF_Get_String( CFF_Index* index,
|
||||
FT_UInt sid,
|
||||
PSNames_Interface* interface );
|
||||
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CFF_Access_Element( CFF_Index* index,
|
||||
FT_UInt element,
|
||||
FT_Byte** pbytes,
|
||||
FT_ULong* pbyte_len );
|
||||
|
||||
FT_LOCAL void
|
||||
CFF_Forget_Element( CFF_Index* index,
|
||||
FT_Byte** pbytes );
|
||||
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CFF_Load_Font( FT_Stream stream,
|
||||
FT_Int face_index,
|
||||
CFF_Font* font );
|
||||
|
||||
FT_LOCAL void
|
||||
CFF_Done_Font( CFF_Font* font );
|
||||
|
||||
|
||||
FT_LOCAL FT_Byte
|
||||
CFF_Get_FD( CFF_FD_Select* select,
|
||||
FT_UInt glyph_index );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __CFFLOAD_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,784 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cffobjs.c */
|
||||
/* */
|
||||
/* OpenType objects manager (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_CALC_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include FT_ERRORS_H
|
||||
#include FT_TRUETYPE_IDS_H
|
||||
#include FT_TRUETYPE_TAGS_H
|
||||
#include FT_INTERNAL_SFNT_H
|
||||
#include FT_INTERNAL_POSTSCRIPT_NAMES_H
|
||||
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
|
||||
#include "cffobjs.h"
|
||||
#include "cffload.h"
|
||||
|
||||
#include "cfferrs.h"
|
||||
|
||||
#include <string.h> /* for strlen() */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_cffobjs
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* SIZE FUNCTIONS */
|
||||
/* */
|
||||
/* Note that we store the global hints in the size's "internal" root */
|
||||
/* field. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
static PSH_Globals_Funcs
|
||||
CFF_Size_Get_Globals_Funcs( CFF_Size size )
|
||||
{
|
||||
CFF_Face face = (CFF_Face)size->face;
|
||||
CFF_Font* font = face->extra.data;
|
||||
PSHinter_Interface* pshinter = font->pshinter;
|
||||
FT_Module module;
|
||||
|
||||
|
||||
module = FT_Get_Module( size->face->driver->root.library,
|
||||
"pshinter" );
|
||||
return ( module && pshinter && pshinter->get_globals_funcs )
|
||||
? pshinter->get_globals_funcs( module )
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF void
|
||||
CFF_Size_Done( CFF_Size size )
|
||||
{
|
||||
if ( size->internal )
|
||||
{
|
||||
PSH_Globals_Funcs funcs;
|
||||
|
||||
|
||||
funcs = CFF_Size_Get_Globals_Funcs( size );
|
||||
if ( funcs )
|
||||
funcs->destroy( (PSH_Globals)size->internal );
|
||||
|
||||
size->internal = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CFF_Size_Init( CFF_Size size )
|
||||
{
|
||||
FT_Error error = 0;
|
||||
PSH_Globals_Funcs funcs = CFF_Size_Get_Globals_Funcs( size );
|
||||
|
||||
|
||||
if ( funcs )
|
||||
{
|
||||
PSH_Globals globals;
|
||||
CFF_Face face = (CFF_Face)size->face;
|
||||
CFF_Font* font = face->extra.data;
|
||||
CFF_SubFont* subfont = &font->top_font;
|
||||
|
||||
CFF_Private* cpriv = &subfont->private_dict;
|
||||
T1_Private priv;
|
||||
|
||||
|
||||
/* IMPORTANT: The CFF and Type1 private dictionaries have */
|
||||
/* slightly different structures; we need to */
|
||||
/* synthetize a type1 dictionary on the fly here. */
|
||||
|
||||
{
|
||||
FT_UInt n, count;
|
||||
|
||||
|
||||
MEM_Set( &priv, 0, sizeof ( priv ) );
|
||||
|
||||
count = priv.num_blue_values = cpriv->num_blue_values;
|
||||
for ( n = 0; n < count; n++ )
|
||||
priv.blue_values[n] = (FT_Short)cpriv->blue_values[n];
|
||||
|
||||
count = priv.num_other_blues = cpriv->num_other_blues;
|
||||
for ( n = 0; n < count; n++ )
|
||||
priv.other_blues[n] = (FT_Short)cpriv->other_blues[n];
|
||||
|
||||
count = priv.num_family_blues = cpriv->num_family_blues;
|
||||
for ( n = 0; n < count; n++ )
|
||||
priv.family_blues[n] = (FT_Short)cpriv->family_blues[n];
|
||||
|
||||
count = priv.num_family_other_blues = cpriv->num_family_other_blues;
|
||||
for ( n = 0; n < count; n++ )
|
||||
priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
|
||||
|
||||
priv.blue_scale = cpriv->blue_scale;
|
||||
priv.blue_shift = cpriv->blue_shift;
|
||||
priv.blue_fuzz = cpriv->blue_fuzz;
|
||||
|
||||
priv.standard_width[0] = (FT_UShort)cpriv->standard_width;
|
||||
priv.standard_height[0] = (FT_UShort)cpriv->standard_height;
|
||||
|
||||
count = priv.num_snap_widths = cpriv->num_snap_widths;
|
||||
for ( n = 0; n < count; n++ )
|
||||
priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
|
||||
|
||||
count = priv.num_snap_heights = cpriv->num_snap_heights;
|
||||
for ( n = 0; n < count; n++ )
|
||||
priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
|
||||
|
||||
priv.force_bold = cpriv->force_bold;
|
||||
priv.language_group = cpriv->language_group;
|
||||
priv.lenIV = cpriv->lenIV;
|
||||
}
|
||||
|
||||
error = funcs->create( size->face->memory, &priv, &globals );
|
||||
if ( !error )
|
||||
size->internal = (FT_Size_Internal)(void*)globals;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CFF_Size_Reset( CFF_Size size )
|
||||
{
|
||||
PSH_Globals_Funcs funcs = CFF_Size_Get_Globals_Funcs( size );
|
||||
FT_Error error = 0;
|
||||
|
||||
|
||||
if ( funcs )
|
||||
error = funcs->set_scale( (PSH_Globals)size->internal,
|
||||
size->metrics.x_scale,
|
||||
size->metrics.y_scale,
|
||||
0, 0 );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* SLOT FUNCTIONS */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
FT_LOCAL_DEF void
|
||||
CFF_GlyphSlot_Done( CFF_GlyphSlot slot )
|
||||
{
|
||||
slot->root.internal->glyph_hints = 0;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CFF_GlyphSlot_Init( CFF_GlyphSlot slot )
|
||||
{
|
||||
CFF_Face face = (CFF_Face)slot->root.face;
|
||||
CFF_Font* font = face->extra.data;
|
||||
PSHinter_Interface* pshinter = font->pshinter;
|
||||
|
||||
|
||||
if ( pshinter )
|
||||
{
|
||||
FT_Module module;
|
||||
|
||||
|
||||
module = FT_Get_Module( slot->root.face->driver->root.library,
|
||||
"pshinter" );
|
||||
if ( module )
|
||||
{
|
||||
T2_Hints_Funcs funcs;
|
||||
|
||||
|
||||
funcs = pshinter->get_t2_funcs( module );
|
||||
slot->root.internal->glyph_hints = (void*)funcs;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* FACE FUNCTIONS */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
static FT_String*
|
||||
CFF_StrCopy( FT_Memory memory,
|
||||
const FT_String* source )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_String* result = 0;
|
||||
FT_Int len = (FT_Int)strlen( source );
|
||||
|
||||
|
||||
if ( !ALLOC( result, len + 1 ) )
|
||||
{
|
||||
MEM_Copy( result, source, len );
|
||||
result[len] = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* this function is used to build a Unicode charmap from the glyph names */
|
||||
/* in a file */
|
||||
static FT_Error
|
||||
CFF_Build_Unicode_Charmap( CFF_Face face,
|
||||
FT_ULong base_offset,
|
||||
PSNames_Interface* psnames )
|
||||
{
|
||||
CFF_Font* font = (CFF_Font*)face->extra.data;
|
||||
FT_Memory memory = FT_FACE_MEMORY(face);
|
||||
FT_UInt n, num_glyphs = face->root.num_glyphs;
|
||||
const char** glyph_names;
|
||||
FT_Error error;
|
||||
CFF_Font_Dict* dict = &font->top_font.font_dict;
|
||||
FT_ULong charset_offset;
|
||||
FT_Byte format;
|
||||
FT_Stream stream = face->root.stream;
|
||||
|
||||
|
||||
charset_offset = dict->charset_offset;
|
||||
if ( !charset_offset )
|
||||
{
|
||||
FT_ERROR(( "CFF_Build_Unicode_Charmap: charset table is missing\n" ));
|
||||
error = CFF_Err_Invalid_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* allocate the charmap */
|
||||
if ( ALLOC( face->charmap, ...
|
||||
|
||||
/* seek to charset table and allocate glyph names table */
|
||||
if ( FILE_Seek( base_offset + charset_offset ) ||
|
||||
ALLOC_ARRAY( glyph_names, num_glyphs, const char* ) )
|
||||
goto Exit;
|
||||
|
||||
/* now, read each glyph name and store it in the glyph name table */
|
||||
if ( READ_Byte( format ) )
|
||||
goto Fail;
|
||||
|
||||
switch ( format )
|
||||
{
|
||||
case 0: /* format 0 - one SID per glyph */
|
||||
{
|
||||
const char** gname = glyph_names;
|
||||
const char** limit = gname + num_glyphs;
|
||||
|
||||
|
||||
if ( ACCESS_Frame( num_glyphs * 2 ) )
|
||||
goto Fail;
|
||||
|
||||
for ( ; gname < limit; gname++ )
|
||||
gname[0] = CFF_Get_String( &font->string_index,
|
||||
GET_UShort(),
|
||||
psnames );
|
||||
FORGET_Frame();
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: /* format 1 - sequential ranges */
|
||||
case 2: /* format 2 - sequential ranges with 16-bit counts */
|
||||
{
|
||||
const char** gname = glyph_names;
|
||||
const char** limit = gname + num_glyphs;
|
||||
FT_UInt len = 3;
|
||||
|
||||
|
||||
if ( format == 2 )
|
||||
len++;
|
||||
|
||||
while ( gname < limit )
|
||||
{
|
||||
FT_UInt first;
|
||||
FT_UInt count;
|
||||
|
||||
|
||||
if ( ACCESS_Frame( len ) )
|
||||
goto Fail;
|
||||
|
||||
first = GET_UShort();
|
||||
if ( format == 3 )
|
||||
count = GET_UShort();
|
||||
else
|
||||
count = GET_Byte();
|
||||
|
||||
FORGET_Frame();
|
||||
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
gname[0] = CFF_Get_String( &font->string_index,
|
||||
first,
|
||||
psnames );
|
||||
gname++;
|
||||
first++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: /* unknown charset format! */
|
||||
FT_ERROR(( "CFF_Build_Unicode_Charmap: unknown charset format!\n" ));
|
||||
error = CFF_Err_Invalid_File_Format;
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
/* all right, the glyph names were loaded; we now need to create */
|
||||
/* the corresponding unicode charmap */
|
||||
|
||||
Fail:
|
||||
for ( n = 0; n < num_glyphs; n++ )
|
||||
FREE( glyph_names[n] );
|
||||
|
||||
FREE( glyph_names );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
static FT_Encoding
|
||||
find_encoding( int platform_id,
|
||||
int encoding_id )
|
||||
{
|
||||
typedef struct TEncoding
|
||||
{
|
||||
int platform_id;
|
||||
int encoding_id;
|
||||
FT_Encoding encoding;
|
||||
|
||||
} TEncoding;
|
||||
|
||||
static
|
||||
const TEncoding tt_encodings[] =
|
||||
{
|
||||
{ TT_PLATFORM_ISO, -1, ft_encoding_unicode },
|
||||
|
||||
{ TT_PLATFORM_APPLE_UNICODE, -1, ft_encoding_unicode },
|
||||
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, ft_encoding_apple_roman },
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, ft_encoding_unicode },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, ft_encoding_sjis },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, ft_encoding_gb2312 },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, ft_encoding_big5 },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, ft_encoding_wansung },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, ft_encoding_johab }
|
||||
};
|
||||
|
||||
const TEncoding *cur, *limit;
|
||||
|
||||
|
||||
cur = tt_encodings;
|
||||
limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] );
|
||||
|
||||
for ( ; cur < limit; cur++ )
|
||||
{
|
||||
if ( cur->platform_id == platform_id )
|
||||
{
|
||||
if ( cur->encoding_id == encoding_id ||
|
||||
cur->encoding_id == -1 )
|
||||
return cur->encoding;
|
||||
}
|
||||
}
|
||||
|
||||
return ft_encoding_none;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* CFF_Face_Init */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Initializes a given OpenType face object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* stream :: The source font stream. */
|
||||
/* */
|
||||
/* face_index :: The index of the font face in the resource. */
|
||||
/* */
|
||||
/* num_params :: Number of additional generic parameters. Ignored. */
|
||||
/* */
|
||||
/* params :: Additional generic parameters. Ignored. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* face :: The newly built face object. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CFF_Face_Init( FT_Stream stream,
|
||||
CFF_Face face,
|
||||
FT_Int face_index,
|
||||
FT_Int num_params,
|
||||
FT_Parameter* params )
|
||||
{
|
||||
FT_Error error;
|
||||
SFNT_Interface* sfnt;
|
||||
PSNames_Interface* psnames;
|
||||
PSHinter_Interface* pshinter;
|
||||
FT_Bool pure_cff = 1;
|
||||
FT_Bool sfnt_format = 0;
|
||||
|
||||
|
||||
sfnt = (SFNT_Interface*)FT_Get_Module_Interface(
|
||||
face->root.driver->root.library, "sfnt" );
|
||||
if ( !sfnt )
|
||||
goto Bad_Format;
|
||||
|
||||
psnames = (PSNames_Interface*)FT_Get_Module_Interface(
|
||||
face->root.driver->root.library, "psnames" );
|
||||
|
||||
pshinter = (PSHinter_Interface*)FT_Get_Module_Interface(
|
||||
face->root.driver->root.library, "pshinter" );
|
||||
|
||||
/* create input stream from resource */
|
||||
if ( FILE_Seek( 0 ) )
|
||||
goto Exit;
|
||||
|
||||
/* check that we have a valid OpenType file */
|
||||
error = sfnt->init_face( stream, face, face_index, num_params, params );
|
||||
if ( !error )
|
||||
{
|
||||
if ( face->format_tag != 0x4F54544FL ) /* `OTTO'; OpenType/CFF font */
|
||||
{
|
||||
FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
|
||||
goto Bad_Format;
|
||||
}
|
||||
|
||||
/* if we are performing a simple font format check, exit immediately */
|
||||
if ( face_index < 0 )
|
||||
return CFF_Err_Ok;
|
||||
|
||||
sfnt_format = 1;
|
||||
|
||||
/* now, the font can be either an OpenType/CFF font, or an SVG CEF */
|
||||
/* font in the later case; it doesn't have a `head' table */
|
||||
error = face->goto_table( face, TTAG_head, stream, 0 );
|
||||
if ( !error )
|
||||
{
|
||||
pure_cff = 0;
|
||||
|
||||
/* load font directory */
|
||||
error = sfnt->load_face( stream, face,
|
||||
face_index, num_params, params );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* load the `cmap' table by hand */
|
||||
error = sfnt->load_charmaps( face, stream );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* XXX: we don't load the GPOS table, as OpenType Layout */
|
||||
/* support will be added later to a layout library on top of */
|
||||
/* FreeType 2 */
|
||||
}
|
||||
|
||||
/* now, load the CFF part of the file */
|
||||
error = face->goto_table( face, TTAG_CFF, stream, 0 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* rewind to start of file; we are going to load a pure-CFF font */
|
||||
if ( FILE_Seek( 0 ) )
|
||||
goto Exit;
|
||||
error = CFF_Err_Ok;
|
||||
}
|
||||
|
||||
/* now load and parse the CFF table in the file */
|
||||
{
|
||||
CFF_Font* cff;
|
||||
FT_Memory memory = face->root.memory;
|
||||
FT_Face root;
|
||||
FT_UInt flags;
|
||||
|
||||
|
||||
if ( ALLOC( cff, sizeof ( *cff ) ) )
|
||||
goto Exit;
|
||||
|
||||
face->extra.data = cff;
|
||||
error = CFF_Load_Font( stream, face_index, cff );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
cff->pshinter = pshinter;
|
||||
|
||||
/* Complement the root flags with some interesting information. */
|
||||
/* Note that this is only necessary for pure CFF and CEF fonts. */
|
||||
|
||||
root = &face->root;
|
||||
root->num_glyphs = cff->num_glyphs;
|
||||
|
||||
if ( pure_cff )
|
||||
{
|
||||
CFF_Font_Dict* dict = &cff->top_font.font_dict;
|
||||
|
||||
|
||||
/* we need the `PSNames' module for pure-CFF and CEF formats */
|
||||
if ( !psnames )
|
||||
{
|
||||
FT_ERROR(( "CFF_Face_Init:" ));
|
||||
FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
|
||||
FT_ERROR(( " " ));
|
||||
FT_ERROR(( " without the `PSNames' module\n" ));
|
||||
goto Bad_Format;
|
||||
}
|
||||
|
||||
/* Set up num_faces. */
|
||||
root->num_faces = cff->num_faces;
|
||||
|
||||
/* compute number of glyphs */
|
||||
if ( dict->cid_registry )
|
||||
root->num_glyphs = dict->cid_count;
|
||||
else
|
||||
root->num_glyphs = cff->charstrings_index.count;
|
||||
|
||||
/* set global bbox, as well as EM size */
|
||||
root->bbox = dict->font_bbox;
|
||||
root->ascender = (FT_Short)( root->bbox.yMax >> 16 );
|
||||
root->descender = (FT_Short)( root->bbox.yMin >> 16 );
|
||||
root->height = (FT_Short)(
|
||||
( ( root->ascender - root->descender ) * 12 ) / 10 );
|
||||
|
||||
if ( dict->units_per_em )
|
||||
root->units_per_EM = dict->units_per_em;
|
||||
else
|
||||
root->units_per_EM = 1000;
|
||||
|
||||
/* retrieve font family & style name */
|
||||
root->family_name = CFF_Get_Name( &cff->name_index, face_index );
|
||||
if ( dict->cid_registry )
|
||||
root->style_name = CFF_StrCopy( memory, "Regular" ); /* XXXX */
|
||||
else
|
||||
root->style_name = CFF_Get_String( &cff->string_index,
|
||||
dict->weight,
|
||||
psnames );
|
||||
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* Compute face flags. */
|
||||
/* */
|
||||
flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */
|
||||
FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
|
||||
|
||||
if ( sfnt_format )
|
||||
flags |= FT_FACE_FLAG_SFNT;
|
||||
|
||||
/* fixed width font? */
|
||||
if ( dict->is_fixed_pitch )
|
||||
flags |= FT_FACE_FLAG_FIXED_WIDTH;
|
||||
|
||||
/* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
|
||||
#if 0
|
||||
/* kerning available? */
|
||||
if ( face->kern_pairs )
|
||||
flags |= FT_FACE_FLAG_KERNING;
|
||||
#endif
|
||||
|
||||
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
|
||||
flags |= FT_FACE_FLAG_GLYPH_NAMES;
|
||||
#endif
|
||||
|
||||
root->face_flags = flags;
|
||||
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* Compute style flags. */
|
||||
/* */
|
||||
flags = 0;
|
||||
|
||||
if ( dict->italic_angle )
|
||||
flags |= FT_STYLE_FLAG_ITALIC;
|
||||
|
||||
/* XXX: may not be correct */
|
||||
if ( cff->top_font.private_dict.force_bold )
|
||||
flags |= FT_STYLE_FLAG_BOLD;
|
||||
|
||||
root->style_flags = flags;
|
||||
|
||||
/* set the charmaps if any */
|
||||
if ( sfnt_format )
|
||||
{
|
||||
/*****************************************************************/
|
||||
/* */
|
||||
/* Polish the charmaps. */
|
||||
/* */
|
||||
/* Try to set the charmap encoding according to the platform & */
|
||||
/* encoding ID of each charmap. */
|
||||
/* */
|
||||
TT_CharMap charmap;
|
||||
FT_Int n;
|
||||
|
||||
|
||||
charmap = face->charmaps;
|
||||
root->num_charmaps = face->num_charmaps;
|
||||
|
||||
/* allocate table of pointers */
|
||||
if ( ALLOC_ARRAY( root->charmaps, root->num_charmaps, FT_CharMap ) )
|
||||
goto Exit;
|
||||
|
||||
for ( n = 0; n < root->num_charmaps; n++, charmap++ )
|
||||
{
|
||||
FT_Int platform = charmap->cmap.platformID;
|
||||
FT_Int encoding = charmap->cmap.platformEncodingID;
|
||||
|
||||
|
||||
charmap->root.face = (FT_Face)face;
|
||||
charmap->root.platform_id = (FT_UShort)platform;
|
||||
charmap->root.encoding_id = (FT_UShort)encoding;
|
||||
charmap->root.encoding = find_encoding( platform, encoding );
|
||||
|
||||
/* now, set root->charmap with a unicode charmap */
|
||||
/* wherever available */
|
||||
if ( !root->charmap &&
|
||||
charmap->root.encoding == ft_encoding_unicode )
|
||||
root->charmap = (FT_CharMap)charmap;
|
||||
|
||||
root->charmaps[n] = (FT_CharMap)charmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
||||
Bad_Format:
|
||||
error = CFF_Err_Unknown_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* CFF_Face_Done */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Finalizes a given face object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A pointer to the face object to destroy. */
|
||||
/* */
|
||||
FT_LOCAL_DEF void
|
||||
CFF_Face_Done( CFF_Face face )
|
||||
{
|
||||
FT_Memory memory = face->root.memory;
|
||||
SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
|
||||
|
||||
|
||||
if ( sfnt )
|
||||
sfnt->done_face( face );
|
||||
|
||||
{
|
||||
CFF_Font* cff = (CFF_Font*)face->extra.data;
|
||||
|
||||
|
||||
if ( cff )
|
||||
{
|
||||
CFF_Done_Font( cff );
|
||||
FREE( face->extra.data );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* CFF_Driver_Init */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Initializes a given OpenType driver object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* driver :: A handle to the target driver object. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CFF_Driver_Init( CFF_Driver driver )
|
||||
{
|
||||
/* init extension registry if needed */
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
|
||||
|
||||
return TT_Init_Extensions( driver );
|
||||
|
||||
#else
|
||||
|
||||
FT_UNUSED( driver );
|
||||
|
||||
return CFF_Err_Ok;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* CFF_Driver_Done */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Finalizes a given OpenType driver. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* driver :: A handle to the target OpenType driver. */
|
||||
/* */
|
||||
FT_LOCAL_DEF void
|
||||
CFF_Driver_Done( CFF_Driver driver )
|
||||
{
|
||||
/* destroy extensions registry if needed */
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
|
||||
|
||||
TT_Done_Extensions( driver );
|
||||
|
||||
#else
|
||||
|
||||
FT_UNUSED( driver );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,158 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cffobjs.h */
|
||||
/* */
|
||||
/* OpenType objects manager (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CFFOBJS_H__
|
||||
#define __CFFOBJS_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_INTERNAL_CFF_TYPES_H
|
||||
#include FT_INTERNAL_POSTSCRIPT_NAMES_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Type> */
|
||||
/* CFF_Driver */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A handle to an OpenType driver object. */
|
||||
/* */
|
||||
typedef struct CFF_DriverRec_* CFF_Driver;
|
||||
|
||||
typedef TT_Face CFF_Face;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Type> */
|
||||
/* CFF_Size */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A handle to an OpenType size object. */
|
||||
/* */
|
||||
typedef FT_Size CFF_Size;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Type> */
|
||||
/* CFF_GlyphSlot */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A handle to an OpenType glyph slot object. */
|
||||
/* */
|
||||
typedef struct CFF_GlyphSlotRec_
|
||||
{
|
||||
FT_GlyphSlotRec root;
|
||||
|
||||
FT_Bool hint;
|
||||
FT_Bool scaled;
|
||||
|
||||
FT_Fixed x_scale;
|
||||
FT_Fixed y_scale;
|
||||
|
||||
} CFF_GlyphSlotRec, *CFF_GlyphSlot;
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Subglyph transformation record. */
|
||||
/* */
|
||||
typedef struct CFF_Transform_
|
||||
{
|
||||
FT_Fixed xx, xy; /* transformation matrix coefficients */
|
||||
FT_Fixed yx, yy;
|
||||
FT_F26Dot6 ox, oy; /* offsets */
|
||||
|
||||
} CFF_Transform;
|
||||
|
||||
|
||||
/* this is only used in the case of a pure CFF font with no charmap */
|
||||
typedef struct CFF_CharMapRec_
|
||||
{
|
||||
TT_CharMapRec root;
|
||||
PS_Unicodes unicodes;
|
||||
|
||||
} CFF_CharMapRec, *CFF_CharMap;
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/* */
|
||||
/* TrueType driver class. */
|
||||
/* */
|
||||
typedef struct CFF_DriverRec_
|
||||
{
|
||||
FT_DriverRec root;
|
||||
void* extension_component;
|
||||
|
||||
} CFF_DriverRec;
|
||||
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CFF_Size_Init( CFF_Size size );
|
||||
|
||||
FT_LOCAL void
|
||||
CFF_Size_Done( CFF_Size size );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CFF_Size_Reset( CFF_Size size );
|
||||
|
||||
FT_LOCAL void
|
||||
CFF_GlyphSlot_Done( CFF_GlyphSlot slot );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CFF_GlyphSlot_Init( CFF_GlyphSlot slot );
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Face functions */
|
||||
/* */
|
||||
FT_LOCAL FT_Error
|
||||
CFF_Face_Init( FT_Stream stream,
|
||||
CFF_Face face,
|
||||
FT_Int face_index,
|
||||
FT_Int num_params,
|
||||
FT_Parameter* params );
|
||||
|
||||
FT_LOCAL void
|
||||
CFF_Face_Done( CFF_Face face );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Driver functions */
|
||||
/* */
|
||||
FT_LOCAL FT_Error
|
||||
CFF_Driver_Init( CFF_Driver driver );
|
||||
|
||||
FT_LOCAL void
|
||||
CFF_Driver_Done( CFF_Driver driver );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __CFFOBJS_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,677 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cffparse.c */
|
||||
/* */
|
||||
/* CFF token stream parser (body) */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "cffparse.h"
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
|
||||
#include "cfferrs.h"
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_cffparse
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
cff_kind_none = 0,
|
||||
cff_kind_num,
|
||||
cff_kind_fixed,
|
||||
cff_kind_string,
|
||||
cff_kind_bool,
|
||||
cff_kind_delta,
|
||||
cff_kind_callback,
|
||||
|
||||
cff_kind_max /* do not remove */
|
||||
};
|
||||
|
||||
|
||||
/* now generate handlers for the most simple fields */
|
||||
typedef FT_Error (*CFF_Field_Reader)( CFF_Parser* parser );
|
||||
|
||||
typedef struct CFF_Field_Handler_
|
||||
{
|
||||
int kind;
|
||||
int code;
|
||||
FT_UInt offset;
|
||||
FT_Byte size;
|
||||
CFF_Field_Reader reader;
|
||||
FT_UInt array_max;
|
||||
FT_UInt count_offset;
|
||||
|
||||
} CFF_Field_Handler;
|
||||
|
||||
|
||||
FT_LOCAL_DEF void
|
||||
CFF_Parser_Init( CFF_Parser* parser,
|
||||
FT_UInt code,
|
||||
void* object )
|
||||
{
|
||||
MEM_Set( parser, 0, sizeof ( *parser ) );
|
||||
|
||||
parser->top = parser->stack;
|
||||
parser->object_code = code;
|
||||
parser->object = object;
|
||||
}
|
||||
|
||||
|
||||
/* read an integer */
|
||||
static FT_Long
|
||||
cff_parse_integer( FT_Byte* start,
|
||||
FT_Byte* limit )
|
||||
{
|
||||
FT_Byte* p = start;
|
||||
FT_Int v = *p++;
|
||||
FT_Long val = 0;
|
||||
|
||||
|
||||
if ( v == 28 )
|
||||
{
|
||||
if ( p + 2 > limit )
|
||||
goto Bad;
|
||||
|
||||
val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
|
||||
p += 2;
|
||||
}
|
||||
else if ( v == 29 )
|
||||
{
|
||||
if ( p + 4 > limit )
|
||||
goto Bad;
|
||||
|
||||
val = ( (FT_Long)p[0] << 24 ) |
|
||||
( (FT_Long)p[1] << 16 ) |
|
||||
( (FT_Long)p[2] << 8 ) |
|
||||
p[3];
|
||||
p += 4;
|
||||
}
|
||||
else if ( v < 247 )
|
||||
{
|
||||
val = v - 139;
|
||||
}
|
||||
else if ( v < 251 )
|
||||
{
|
||||
if ( p + 1 > limit )
|
||||
goto Bad;
|
||||
|
||||
val = ( v - 247 ) * 256 + p[0] + 108;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( p + 1 > limit )
|
||||
goto Bad;
|
||||
|
||||
val = -( v - 251 ) * 256 - p[0] - 108;
|
||||
p++;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return val;
|
||||
|
||||
Bad:
|
||||
val = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
/* read a real */
|
||||
static FT_Fixed
|
||||
cff_parse_real( FT_Byte* start,
|
||||
FT_Byte* limit,
|
||||
FT_Int power_ten )
|
||||
{
|
||||
FT_Byte* p = start;
|
||||
FT_Long num, divider, result, exp;
|
||||
FT_Int sign = 0, exp_sign = 0;
|
||||
FT_UInt nib;
|
||||
FT_UInt phase;
|
||||
|
||||
|
||||
result = 0;
|
||||
num = 0;
|
||||
divider = 1;
|
||||
|
||||
/* first of all, read the integer part */
|
||||
phase = 4;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* If we entered this iteration with phase == 4, we need to */
|
||||
/* read a new byte. This also skips past the intial 0x1E. */
|
||||
if ( phase )
|
||||
{
|
||||
p++;
|
||||
|
||||
/* Make sure we don't read past the end. */
|
||||
if ( p >= limit )
|
||||
goto Bad;
|
||||
}
|
||||
|
||||
/* Get the nibble. */
|
||||
nib = ( p[0] >> phase ) & 0xF;
|
||||
phase = 4 - phase;
|
||||
|
||||
if ( nib == 0xE )
|
||||
sign = 1;
|
||||
else if ( nib > 9 )
|
||||
break;
|
||||
else
|
||||
result = result * 10 + nib;
|
||||
}
|
||||
|
||||
/* read decimal part, if any */
|
||||
if ( nib == 0xa )
|
||||
for (;;)
|
||||
{
|
||||
/* If we entered this iteration with phase == 4, we need */
|
||||
/* to read a new byte. */
|
||||
if ( phase )
|
||||
{
|
||||
p++;
|
||||
|
||||
/* Make sure we don't read past the end. */
|
||||
if ( p >= limit )
|
||||
goto Bad;
|
||||
}
|
||||
|
||||
/* Get the nibble. */
|
||||
nib = ( p[0] >> phase ) & 0xF;
|
||||
phase = 4 - phase;
|
||||
if ( nib >= 10 )
|
||||
break;
|
||||
|
||||
if ( divider < 10000000L )
|
||||
{
|
||||
num = num * 10 + nib;
|
||||
divider *= 10;
|
||||
}
|
||||
}
|
||||
|
||||
/* read exponent, if any */
|
||||
if ( nib == 12 )
|
||||
{
|
||||
exp_sign = 1;
|
||||
nib = 11;
|
||||
}
|
||||
|
||||
if ( nib == 11 )
|
||||
{
|
||||
exp = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* If we entered this iteration with phase == 4, we need */
|
||||
/* to read a new byte. */
|
||||
if ( phase )
|
||||
{
|
||||
p++;
|
||||
|
||||
/* Make sure we don't read past the end. */
|
||||
if ( p >= limit )
|
||||
goto Bad;
|
||||
}
|
||||
|
||||
/* Get the nibble. */
|
||||
nib = ( p[0] >> phase ) & 0xF;
|
||||
phase = 4 - phase;
|
||||
if ( nib >= 10 )
|
||||
break;
|
||||
|
||||
exp = exp * 10 + nib;
|
||||
}
|
||||
|
||||
if ( exp_sign )
|
||||
exp = -exp;
|
||||
|
||||
power_ten += exp;
|
||||
}
|
||||
|
||||
/* raise to power of ten if needed */
|
||||
while ( power_ten > 0 )
|
||||
{
|
||||
result = result * 10;
|
||||
num = num * 10;
|
||||
|
||||
power_ten--;
|
||||
}
|
||||
|
||||
while ( power_ten < 0 )
|
||||
{
|
||||
result = result / 10;
|
||||
divider = divider * 10;
|
||||
|
||||
power_ten++;
|
||||
}
|
||||
|
||||
/* Move the integer part into the high 16 bits. */
|
||||
result <<= 16;
|
||||
|
||||
/* Place the decimal part into the low 16 bits. */
|
||||
if ( num )
|
||||
result |= FT_DivFix( num, divider );
|
||||
|
||||
if ( sign )
|
||||
result = -result;
|
||||
|
||||
Exit:
|
||||
return result;
|
||||
|
||||
Bad:
|
||||
result = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
/* read a number, either integer or real */
|
||||
static FT_Long
|
||||
cff_parse_num( FT_Byte** d )
|
||||
{
|
||||
return ( **d == 30 ? ( cff_parse_real ( d[0], d[1], 0 ) >> 16 )
|
||||
: cff_parse_integer( d[0], d[1] ) );
|
||||
}
|
||||
|
||||
|
||||
/* read a floating point number, either integer or real */
|
||||
static FT_Fixed
|
||||
cff_parse_fixed( FT_Byte** d )
|
||||
{
|
||||
return ( **d == 30 ? cff_parse_real ( d[0], d[1], 0 )
|
||||
: cff_parse_integer( d[0], d[1] ) << 16 );
|
||||
}
|
||||
|
||||
/* read a floating point number, either integer or real, */
|
||||
/* but return 1000 times the number read in. */
|
||||
static FT_Fixed
|
||||
cff_parse_fixed_thousand( FT_Byte** d )
|
||||
{
|
||||
return **d ==
|
||||
30 ? cff_parse_real ( d[0], d[1], 3 )
|
||||
: (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16, 1000 );
|
||||
}
|
||||
|
||||
static FT_Error
|
||||
cff_parse_font_matrix( CFF_Parser* parser )
|
||||
{
|
||||
CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object;
|
||||
FT_Matrix* matrix = &dict->font_matrix;
|
||||
FT_Vector* offset = &dict->font_offset;
|
||||
FT_UShort* upm = &dict->units_per_em;
|
||||
FT_Byte** data = parser->stack;
|
||||
FT_Error error;
|
||||
FT_Fixed temp;
|
||||
|
||||
|
||||
error = CFF_Err_Stack_Underflow;
|
||||
|
||||
if ( parser->top >= parser->stack + 6 )
|
||||
{
|
||||
matrix->xx = cff_parse_fixed_thousand( data++ );
|
||||
matrix->yx = cff_parse_fixed_thousand( data++ );
|
||||
matrix->xy = cff_parse_fixed_thousand( data++ );
|
||||
matrix->yy = cff_parse_fixed_thousand( data++ );
|
||||
offset->x = cff_parse_fixed_thousand( data++ );
|
||||
offset->y = cff_parse_fixed_thousand( data );
|
||||
|
||||
temp = ABS( matrix->yy );
|
||||
|
||||
*upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) );
|
||||
|
||||
if ( temp != 0x10000L )
|
||||
{
|
||||
matrix->xx = FT_DivFix( matrix->xx, temp );
|
||||
matrix->yx = FT_DivFix( matrix->yx, temp );
|
||||
matrix->xy = FT_DivFix( matrix->xy, temp );
|
||||
matrix->yy = FT_DivFix( matrix->yy, temp );
|
||||
offset->x = FT_DivFix( offset->x, temp );
|
||||
offset->y = FT_DivFix( offset->y, temp );
|
||||
}
|
||||
|
||||
/* note that the offsets must be expressed in integer font units */
|
||||
offset->x >>= 16;
|
||||
offset->y >>= 16;
|
||||
|
||||
error = CFF_Err_Ok;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
cff_parse_font_bbox( CFF_Parser* parser )
|
||||
{
|
||||
CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object;
|
||||
FT_BBox* bbox = &dict->font_bbox;
|
||||
FT_Byte** data = parser->stack;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
error = CFF_Err_Stack_Underflow;
|
||||
|
||||
if ( parser->top >= parser->stack + 4 )
|
||||
{
|
||||
bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
|
||||
bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
|
||||
bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
|
||||
bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) );
|
||||
error = CFF_Err_Ok;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
cff_parse_private_dict( CFF_Parser* parser )
|
||||
{
|
||||
CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object;
|
||||
FT_Byte** data = parser->stack;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
error = CFF_Err_Stack_Underflow;
|
||||
|
||||
if ( parser->top >= parser->stack + 2 )
|
||||
{
|
||||
dict->private_size = cff_parse_num( data++ );
|
||||
dict->private_offset = cff_parse_num( data );
|
||||
error = CFF_Err_Ok;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
cff_parse_cid_ros( CFF_Parser* parser )
|
||||
{
|
||||
CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object;
|
||||
FT_Byte** data = parser->stack;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
error = CFF_Err_Stack_Underflow;
|
||||
|
||||
if ( parser->top >= parser->stack + 3 )
|
||||
{
|
||||
dict->cid_registry = (FT_UInt)cff_parse_num ( data++ );
|
||||
dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ );
|
||||
dict->cid_supplement = (FT_ULong)cff_parse_num( data );
|
||||
error = CFF_Err_Ok;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#define CFF_FIELD_NUM( code, name ) \
|
||||
CFF_FIELD( code, name, cff_kind_num )
|
||||
#define CFF_FIELD_FIXED( code, name ) \
|
||||
CFF_FIELD( code, name, cff_kind_fixed )
|
||||
#define CFF_FIELD_STRING( code, name ) \
|
||||
CFF_FIELD( code, name, cff_kind_string )
|
||||
#define CFF_FIELD_BOOL( code, name ) \
|
||||
CFF_FIELD( code, name, cff_kind_bool )
|
||||
#define CFF_FIELD_DELTA( code, name, max ) \
|
||||
CFF_FIELD( code, name, cff_kind_delta )
|
||||
|
||||
#define CFF_FIELD_CALLBACK( code, name ) \
|
||||
{ \
|
||||
cff_kind_callback, \
|
||||
code | CFFCODE, \
|
||||
0, 0, \
|
||||
cff_parse_ ## name, \
|
||||
0, 0 \
|
||||
},
|
||||
|
||||
#undef CFF_FIELD
|
||||
#define CFF_FIELD( code, name, kind ) \
|
||||
{ \
|
||||
kind, \
|
||||
code | CFFCODE, \
|
||||
FT_FIELD_OFFSET( name ), \
|
||||
FT_FIELD_SIZE( name ), \
|
||||
0, 0, 0 \
|
||||
},
|
||||
|
||||
#undef CFF_FIELD_DELTA
|
||||
#define CFF_FIELD_DELTA( code, name, max ) \
|
||||
{ \
|
||||
cff_kind_delta, \
|
||||
code | CFFCODE, \
|
||||
FT_FIELD_OFFSET( name ), \
|
||||
FT_FIELD_SIZE_DELTA( name ), \
|
||||
0, \
|
||||
max, \
|
||||
FT_FIELD_OFFSET( num_ ## name ) \
|
||||
},
|
||||
|
||||
#define CFFCODE_TOPDICT 0x1000
|
||||
#define CFFCODE_PRIVATE 0x2000
|
||||
|
||||
static const CFF_Field_Handler cff_field_handlers[] =
|
||||
{
|
||||
|
||||
#include "cfftoken.h"
|
||||
|
||||
{ 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CFF_Parser_Run( CFF_Parser* parser,
|
||||
FT_Byte* start,
|
||||
FT_Byte* limit )
|
||||
{
|
||||
FT_Byte* p = start;
|
||||
FT_Error error = CFF_Err_Ok;
|
||||
|
||||
|
||||
parser->top = parser->stack;
|
||||
parser->start = start;
|
||||
parser->limit = limit;
|
||||
parser->cursor = start;
|
||||
|
||||
while ( p < limit )
|
||||
{
|
||||
FT_UInt v = *p;
|
||||
|
||||
|
||||
if ( v >= 27 && v != 31 )
|
||||
{
|
||||
/* it's a number; we will push its position on the stack */
|
||||
if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
|
||||
goto Stack_Overflow;
|
||||
|
||||
*parser->top ++ = p;
|
||||
|
||||
/* now, skip it */
|
||||
if ( v == 30 )
|
||||
{
|
||||
/* skip real number */
|
||||
p++;
|
||||
for (;;)
|
||||
{
|
||||
if ( p >= limit )
|
||||
goto Syntax_Error;
|
||||
v = p[0] >> 4;
|
||||
if ( v == 15 )
|
||||
break;
|
||||
v = p[0] & 0xF;
|
||||
if ( v == 15 )
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else if ( v == 28 )
|
||||
p += 2;
|
||||
else if ( v == 29 )
|
||||
p += 4;
|
||||
else if ( v > 246 )
|
||||
p += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is not a number, hence it's an operator. Compute its code */
|
||||
/* and look for it in our current list. */
|
||||
|
||||
FT_UInt code;
|
||||
FT_UInt num_args = (FT_UInt)
|
||||
( parser->top - parser->stack );
|
||||
const CFF_Field_Handler* field;
|
||||
|
||||
|
||||
/* first of all, a trivial check */
|
||||
if ( num_args < 1 )
|
||||
goto Stack_Underflow;
|
||||
|
||||
*parser->top = p;
|
||||
code = v;
|
||||
if ( v == 12 )
|
||||
{
|
||||
/* two byte operator */
|
||||
p++;
|
||||
code = 0x100 | p[0];
|
||||
}
|
||||
code = code | parser->object_code;
|
||||
|
||||
for ( field = cff_field_handlers; field->kind; field++ )
|
||||
{
|
||||
if ( field->code == (FT_Int)code )
|
||||
{
|
||||
/* we found our field's handler; read it */
|
||||
FT_Long val;
|
||||
FT_Byte* q = (FT_Byte*)parser->object + field->offset;
|
||||
|
||||
|
||||
switch ( field->kind )
|
||||
{
|
||||
case cff_kind_bool:
|
||||
case cff_kind_string:
|
||||
case cff_kind_num:
|
||||
val = cff_parse_num( parser->stack );
|
||||
goto Store_Number;
|
||||
|
||||
case cff_kind_fixed:
|
||||
val = cff_parse_fixed( parser->stack );
|
||||
|
||||
Store_Number:
|
||||
switch ( field->size )
|
||||
{
|
||||
case 1:
|
||||
*(FT_Byte*)q = (FT_Byte)val;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*(FT_Short*)q = (FT_Short)val;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*(FT_Int32*)q = (FT_Int)val;
|
||||
break;
|
||||
|
||||
default: /* for 64-bit systems where long is 8 bytes */
|
||||
*(FT_Long*)q = val;
|
||||
}
|
||||
break;
|
||||
|
||||
case cff_kind_delta:
|
||||
{
|
||||
FT_Byte* qcount = (FT_Byte*)parser->object +
|
||||
field->count_offset;
|
||||
|
||||
FT_Byte** data = parser->stack;
|
||||
|
||||
|
||||
if ( num_args > field->array_max )
|
||||
num_args = field->array_max;
|
||||
|
||||
/* store count */
|
||||
*qcount = (FT_Byte)num_args;
|
||||
|
||||
val = 0;
|
||||
while ( num_args > 0 )
|
||||
{
|
||||
val += cff_parse_num( data++ );
|
||||
switch ( field->size )
|
||||
{
|
||||
case 1:
|
||||
*(FT_Byte*)q = (FT_Byte)val;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*(FT_Short*)q = (FT_Short)val;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*(FT_Int32*)q = (FT_Int)val;
|
||||
break;
|
||||
|
||||
default: /* for 64-bit systems */
|
||||
*(FT_Long*)q = val;
|
||||
}
|
||||
|
||||
q += field->size;
|
||||
num_args--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* callback */
|
||||
error = field->reader( parser );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
}
|
||||
goto Found;
|
||||
}
|
||||
}
|
||||
|
||||
/* this is an unknown operator, or it is unsupported; */
|
||||
/* we will ignore it for now. */
|
||||
|
||||
Found:
|
||||
/* clear stack */
|
||||
parser->top = parser->stack;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
||||
Stack_Overflow:
|
||||
error = CFF_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
|
||||
Stack_Underflow:
|
||||
error = CFF_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
|
||||
Syntax_Error:
|
||||
error = CFF_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,69 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cffparse.h */
|
||||
/* */
|
||||
/* CFF token stream parser (specification) */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CFF_PARSE_H__
|
||||
#define __CFF_PARSE_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_CFF_TYPES_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
#define CFF_MAX_STACK_DEPTH 96
|
||||
|
||||
#define CFF_CODE_TOPDICT 0x1000
|
||||
#define CFF_CODE_PRIVATE 0x2000
|
||||
|
||||
|
||||
typedef struct CFF_Parser_
|
||||
{
|
||||
FT_Byte* start;
|
||||
FT_Byte* limit;
|
||||
FT_Byte* cursor;
|
||||
|
||||
FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1];
|
||||
FT_Byte** top;
|
||||
|
||||
FT_UInt object_code;
|
||||
void* object;
|
||||
|
||||
} CFF_Parser;
|
||||
|
||||
|
||||
FT_LOCAL void
|
||||
CFF_Parser_Init( CFF_Parser* parser,
|
||||
FT_UInt code,
|
||||
void* object );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CFF_Parser_Run( CFF_Parser* parser,
|
||||
FT_Byte* start,
|
||||
FT_Byte* limit );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CFF_PARSE_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,97 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cfftoken.h */
|
||||
/* */
|
||||
/* CFF token definitions */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CFF_Font_Dict
|
||||
|
||||
#undef CFFCODE
|
||||
#define CFFCODE CFFCODE_TOPDICT
|
||||
|
||||
CFF_FIELD_STRING ( 0, version )
|
||||
CFF_FIELD_STRING ( 1, notice )
|
||||
CFF_FIELD_STRING ( 0x100, copyright )
|
||||
CFF_FIELD_STRING ( 2, full_name )
|
||||
CFF_FIELD_STRING ( 3, family_name )
|
||||
CFF_FIELD_STRING ( 4, weight )
|
||||
CFF_FIELD_BOOL ( 0x101, is_fixed_pitch )
|
||||
CFF_FIELD_FIXED ( 0x102, italic_angle )
|
||||
CFF_FIELD_NUM ( 0x103, underline_position )
|
||||
CFF_FIELD_NUM ( 0x104, underline_thickness )
|
||||
CFF_FIELD_NUM ( 0x105, paint_type )
|
||||
CFF_FIELD_NUM ( 0x106, charstring_type )
|
||||
CFF_FIELD_CALLBACK( 0x107, font_matrix )
|
||||
CFF_FIELD_NUM ( 13, unique_id )
|
||||
CFF_FIELD_CALLBACK( 5, font_bbox )
|
||||
CFF_FIELD_NUM ( 0x108, stroke_width )
|
||||
CFF_FIELD_NUM ( 15, charset_offset )
|
||||
CFF_FIELD_NUM ( 16, encoding_offset )
|
||||
CFF_FIELD_NUM ( 17, charstrings_offset )
|
||||
CFF_FIELD_CALLBACK( 18, private_dict )
|
||||
CFF_FIELD_NUM ( 0x114, synthetic_base )
|
||||
CFF_FIELD_STRING ( 0x115, postscript )
|
||||
CFF_FIELD_STRING ( 0x116, base_font_name )
|
||||
|
||||
#if 0
|
||||
CFF_FIELD_DELTA ( 0x117, base_font_blend, 16 )
|
||||
CFF_FIELD_CALLBACK( 0x118, multiple_master )
|
||||
CFF_FIELD_CALLBACK( 0x119, blend_axit_types )
|
||||
#endif
|
||||
|
||||
CFF_FIELD_CALLBACK( 0x11E, cid_ros )
|
||||
CFF_FIELD_NUM ( 0x11F, cid_font_version )
|
||||
CFF_FIELD_NUM ( 0x120, cid_font_revision )
|
||||
CFF_FIELD_NUM ( 0x121, cid_font_type )
|
||||
CFF_FIELD_NUM ( 0x122, cid_count )
|
||||
CFF_FIELD_NUM ( 0x123, cid_uid_base )
|
||||
CFF_FIELD_NUM ( 0x124, cid_fd_array_offset )
|
||||
CFF_FIELD_NUM ( 0x125, cid_fd_select_offset )
|
||||
CFF_FIELD_STRING ( 0x126, cid_font_name )
|
||||
|
||||
#if 0
|
||||
CFF_FIELD_NUM ( 0x127, chameleon )
|
||||
#endif
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CFF_Private
|
||||
#undef CFFCODE
|
||||
#define CFFCODE CFFCODE_PRIVATE
|
||||
|
||||
CFF_FIELD_DELTA( 6, blue_values, 14 )
|
||||
CFF_FIELD_DELTA( 7, other_blues, 10 )
|
||||
CFF_FIELD_DELTA( 8, family_blues, 14 )
|
||||
CFF_FIELD_DELTA( 9, family_other_blues, 10 )
|
||||
CFF_FIELD_FIXED( 0x109, blue_scale )
|
||||
CFF_FIELD_NUM ( 0x10A, blue_shift )
|
||||
CFF_FIELD_NUM ( 0x10B, blue_fuzz )
|
||||
CFF_FIELD_NUM ( 10, standard_width )
|
||||
CFF_FIELD_NUM ( 11, standard_height )
|
||||
CFF_FIELD_DELTA( 0x10C, snap_widths, 13 )
|
||||
CFF_FIELD_DELTA( 0x10D, snap_heights, 13 )
|
||||
CFF_FIELD_BOOL ( 0x10E, force_bold )
|
||||
CFF_FIELD_FIXED( 0x10F, force_bold_threshold )
|
||||
CFF_FIELD_NUM ( 0x110, lenIV )
|
||||
CFF_FIELD_NUM ( 0x111, language_group )
|
||||
CFF_FIELD_FIXED( 0x112, expansion_factor )
|
||||
CFF_FIELD_NUM ( 0x113, initial_random_seed )
|
||||
CFF_FIELD_NUM ( 19, local_subrs_offset )
|
||||
CFF_FIELD_NUM ( 20, default_width )
|
||||
CFF_FIELD_NUM ( 21, nominal_width )
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,23 +0,0 @@
|
|||
#
|
||||
# FreeType 2 OpenType/CFF driver compilation rules for VMS
|
||||
#
|
||||
|
||||
|
||||
# Copyright 2001 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.
|
||||
|
||||
|
||||
CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.cff])
|
||||
|
||||
OBJS=cff.obj
|
||||
|
||||
all : $(OBJS)
|
||||
library [--.lib]freetype.olb $(OBJS)
|
||||
|
||||
# EOF
|
|
@ -1,70 +0,0 @@
|
|||
#
|
||||
# FreeType 2 OpenType/CFF driver configuration rules
|
||||
#
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
# OpenType driver directory
|
||||
#
|
||||
CFF_DIR := $(SRC_)cff
|
||||
CFF_DIR_ := $(CFF_DIR)$(SEP)
|
||||
|
||||
|
||||
CFF_COMPILE := $(FT_COMPILE) $I$(CFF_DIR)
|
||||
|
||||
|
||||
# CFF driver sources (i.e., C files)
|
||||
#
|
||||
CFF_DRV_SRC := $(CFF_DIR_)cffobjs.c \
|
||||
$(CFF_DIR_)cffload.c \
|
||||
$(CFF_DIR_)cffgload.c \
|
||||
$(CFF_DIR_)cffparse.c \
|
||||
$(CFF_DIR_)cffdrivr.c
|
||||
|
||||
# CFF driver headers
|
||||
#
|
||||
CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \
|
||||
$(CFF_DIR_)cfftoken.h \
|
||||
$(CFF_DIR_)cfferrs.h
|
||||
|
||||
|
||||
# CFF driver object(s)
|
||||
#
|
||||
# CFF_DRV_OBJ_M is used during `multi' builds
|
||||
# CFF_DRV_OBJ_S is used during `single' builds
|
||||
#
|
||||
CFF_DRV_OBJ_M := $(CFF_DRV_SRC:$(CFF_DIR_)%.c=$(OBJ_)%.$O)
|
||||
CFF_DRV_OBJ_S := $(OBJ_)cff.$O
|
||||
|
||||
# CFF driver source file for single build
|
||||
#
|
||||
CFF_DRV_SRC_S := $(CFF_DIR_)cff.c
|
||||
|
||||
|
||||
# CFF driver - single object
|
||||
#
|
||||
$(CFF_DRV_OBJ_S): $(CFF_DRV_SRC_S) $(CFF_DRV_SRC) $(FREETYPE_H) $(CFF_DRV_H)
|
||||
$(CFF_COMPILE) $T$@ $(CFF_DRV_SRC_S)
|
||||
|
||||
|
||||
# CFF driver - multiple objects
|
||||
#
|
||||
$(OBJ_)%.$O: $(CFF_DIR_)%.c $(FREETYPE_H) $(CFF_DRV_H)
|
||||
$(CFF_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
# update main driver object lists
|
||||
#
|
||||
DRV_OBJS_S += $(CFF_DRV_OBJ_S)
|
||||
DRV_OBJS_M += $(CFF_DRV_OBJ_M)
|
||||
|
||||
# EOF
|
|
@ -1,368 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidgload.c */
|
||||
/* */
|
||||
/* CID-keyed Type1 Glyph Loader (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "cidload.h"
|
||||
#include "cidgload.h"
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include FT_OUTLINE_H
|
||||
|
||||
#include "ciderrs.h"
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_cidgload
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cid_load_glyph( T1_Decoder* decoder,
|
||||
FT_UInt glyph_index )
|
||||
{
|
||||
CID_Face face = (CID_Face)decoder->builder.face;
|
||||
CID_Info* cid = &face->cid;
|
||||
FT_Byte* p;
|
||||
FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
|
||||
FT_UInt fd_select;
|
||||
FT_ULong off1, glyph_len;
|
||||
FT_Stream stream = face->root.stream;
|
||||
FT_Error error = 0;
|
||||
|
||||
|
||||
/* read the CID font dict index and charstring offset from the CIDMap */
|
||||
if ( FILE_Seek( cid->data_offset + cid->cidmap_offset +
|
||||
glyph_index * entry_len ) ||
|
||||
ACCESS_Frame( 2 * entry_len ) )
|
||||
goto Exit;
|
||||
|
||||
p = (FT_Byte*)stream->cursor;
|
||||
fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
|
||||
off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
|
||||
p += cid->fd_bytes;
|
||||
glyph_len = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
|
||||
|
||||
FORGET_Frame();
|
||||
|
||||
/* now, if the glyph is not empty, set up the subrs array, and parse */
|
||||
/* the charstrings */
|
||||
if ( glyph_len > 0 )
|
||||
{
|
||||
CID_FontDict* dict;
|
||||
CID_Subrs* cid_subrs = face->subrs + fd_select;
|
||||
FT_Byte* charstring;
|
||||
FT_Memory memory = face->root.memory;
|
||||
|
||||
|
||||
/* setup subrs */
|
||||
decoder->num_subrs = cid_subrs->num_subrs;
|
||||
decoder->subrs = cid_subrs->code;
|
||||
decoder->subrs_len = 0;
|
||||
|
||||
/* setup font matrix */
|
||||
dict = cid->font_dicts + fd_select;
|
||||
|
||||
decoder->font_matrix = dict->font_matrix;
|
||||
decoder->font_offset = dict->font_offset;
|
||||
decoder->lenIV = dict->private_dict.lenIV;
|
||||
|
||||
/* the charstrings are encoded (stupid!) */
|
||||
/* load the charstrings, then execute it */
|
||||
|
||||
if ( ALLOC( charstring, glyph_len ) )
|
||||
goto Exit;
|
||||
|
||||
if ( !FILE_Read_At( cid->data_offset + off1, charstring, glyph_len ) )
|
||||
{
|
||||
FT_Int cs_offset;
|
||||
|
||||
|
||||
/* Adjustment for seed bytes. */
|
||||
cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
|
||||
|
||||
/* Decrypt only if lenIV >= 0. */
|
||||
if ( decoder->lenIV >= 0 )
|
||||
cid_decrypt( charstring, glyph_len, 4330 );
|
||||
|
||||
error = decoder->funcs.parse_charstrings( decoder,
|
||||
charstring + cs_offset,
|
||||
glyph_len - cs_offset );
|
||||
}
|
||||
|
||||
FREE( charstring );
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/********** *********/
|
||||
/********** *********/
|
||||
/********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
|
||||
/********** *********/
|
||||
/********** The following code is in charge of computing *********/
|
||||
/********** the maximum advance width of the font. It *********/
|
||||
/********** quickly processes each glyph charstring to *********/
|
||||
/********** extract the value from either a `sbw' or `seac' *********/
|
||||
/********** operator. *********/
|
||||
/********** *********/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CID_Compute_Max_Advance( CID_Face face,
|
||||
FT_Int* max_advance )
|
||||
{
|
||||
FT_Error error;
|
||||
T1_Decoder decoder;
|
||||
FT_Int glyph_index;
|
||||
|
||||
PSAux_Interface* psaux = (PSAux_Interface*)face->psaux;
|
||||
|
||||
|
||||
*max_advance = 0;
|
||||
|
||||
/* Initialize load decoder */
|
||||
error = psaux->t1_decoder_funcs->init( &decoder,
|
||||
(FT_Face)face,
|
||||
0, /* size */
|
||||
0, /* glyph slot */
|
||||
0, /* glyph names! XXX */
|
||||
0, /* blend == 0 */
|
||||
0, /* hinting == 0 */
|
||||
cid_load_glyph );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
decoder.builder.metrics_only = 1;
|
||||
decoder.builder.load_points = 0;
|
||||
|
||||
/* for each glyph, parse the glyph charstring and extract */
|
||||
/* the advance width */
|
||||
for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
|
||||
glyph_index++ )
|
||||
{
|
||||
/* now get load the unscaled outline */
|
||||
error = cid_load_glyph( &decoder, glyph_index );
|
||||
/* ignore the error if one occurred - skip to next glyph */
|
||||
}
|
||||
|
||||
*max_advance = decoder.builder.advance.x;
|
||||
|
||||
return CID_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/********** *********/
|
||||
/********** *********/
|
||||
/********** UNHINTED GLYPH LOADER *********/
|
||||
/********** *********/
|
||||
/********** The following code is in charge of loading a *********/
|
||||
/********** single outline. It completely ignores hinting *********/
|
||||
/********** and is used when FT_LOAD_NO_HINTING is set. *********/
|
||||
/********** *********/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CID_Load_Glyph( CID_GlyphSlot glyph,
|
||||
CID_Size size,
|
||||
FT_Int glyph_index,
|
||||
FT_Int load_flags )
|
||||
{
|
||||
FT_Error error;
|
||||
T1_Decoder decoder;
|
||||
CID_Face face = (CID_Face)glyph->root.face;
|
||||
FT_Bool hinting;
|
||||
|
||||
PSAux_Interface* psaux = (PSAux_Interface*)face->psaux;
|
||||
FT_Matrix font_matrix;
|
||||
FT_Vector font_offset;
|
||||
|
||||
|
||||
if ( load_flags & FT_LOAD_NO_RECURSE )
|
||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
||||
|
||||
glyph->x_scale = size->root.metrics.x_scale;
|
||||
glyph->y_scale = size->root.metrics.y_scale;
|
||||
|
||||
glyph->root.outline.n_points = 0;
|
||||
glyph->root.outline.n_contours = 0;
|
||||
|
||||
hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
|
||||
( load_flags & FT_LOAD_NO_HINTING ) == 0 );
|
||||
|
||||
glyph->root.format = ft_glyph_format_outline;
|
||||
|
||||
{
|
||||
error = psaux->t1_decoder_funcs->init( &decoder,
|
||||
(FT_Face)face,
|
||||
(FT_Size)size,
|
||||
(FT_GlyphSlot)glyph,
|
||||
0, /* glyph names -- XXX */
|
||||
0, /* blend == 0 */
|
||||
hinting,
|
||||
cid_load_glyph );
|
||||
|
||||
/* set up the decoder */
|
||||
decoder.builder.no_recurse = FT_BOOL(
|
||||
( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
|
||||
|
||||
error = cid_load_glyph( &decoder, glyph_index );
|
||||
|
||||
font_matrix = decoder.font_matrix;
|
||||
font_offset = decoder.font_offset;
|
||||
|
||||
/* save new glyph tables */
|
||||
psaux->t1_decoder_funcs->done( &decoder );
|
||||
}
|
||||
|
||||
/* now, set the metrics -- this is rather simple, as */
|
||||
/* the left side bearing is the xMin, and the top side */
|
||||
/* bearing the yMax */
|
||||
if ( !error )
|
||||
{
|
||||
glyph->root.outline.flags &= ft_outline_owner;
|
||||
glyph->root.outline.flags |= ft_outline_reverse_fill;
|
||||
|
||||
/* for composite glyphs, return only left side bearing and */
|
||||
/* advance width */
|
||||
if ( load_flags & FT_LOAD_NO_RECURSE )
|
||||
{
|
||||
FT_Slot_Internal internal = glyph->root.internal;
|
||||
|
||||
|
||||
glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
|
||||
glyph->root.metrics.horiAdvance = decoder.builder.advance.x;
|
||||
|
||||
internal->glyph_matrix = font_matrix;
|
||||
internal->glyph_delta = font_offset;
|
||||
internal->glyph_transformed = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_BBox cbox;
|
||||
FT_Glyph_Metrics* metrics = &glyph->root.metrics;
|
||||
|
||||
|
||||
/* copy the _unscaled_ advance width */
|
||||
metrics->horiAdvance = decoder.builder.advance.x;
|
||||
glyph->root.linearHoriAdvance = decoder.builder.advance.x;
|
||||
glyph->root.internal->glyph_transformed = 0;
|
||||
|
||||
/* make up vertical metrics */
|
||||
metrics->vertBearingX = 0;
|
||||
metrics->vertBearingY = 0;
|
||||
metrics->vertAdvance = 0;
|
||||
|
||||
glyph->root.linearVertAdvance = 0;
|
||||
glyph->root.format = ft_glyph_format_outline;
|
||||
|
||||
if ( size && size->root.metrics.y_ppem < 24 )
|
||||
glyph->root.outline.flags |= ft_outline_high_precision;
|
||||
|
||||
/* apply the font matrix */
|
||||
FT_Outline_Transform( &glyph->root.outline, &font_matrix );
|
||||
|
||||
FT_Outline_Translate( &glyph->root.outline,
|
||||
font_offset.x,
|
||||
font_offset.y );
|
||||
|
||||
if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
|
||||
{
|
||||
/* scale the outline and the metrics */
|
||||
FT_Int n;
|
||||
FT_Outline* cur = decoder.builder.base;
|
||||
FT_Vector* vec = cur->points;
|
||||
FT_Fixed x_scale = glyph->x_scale;
|
||||
FT_Fixed y_scale = glyph->y_scale;
|
||||
|
||||
|
||||
/* First of all, scale the points */
|
||||
if ( !hinting )
|
||||
for ( n = cur->n_points; n > 0; n--, vec++ )
|
||||
{
|
||||
vec->x = FT_MulFix( vec->x, x_scale );
|
||||
vec->y = FT_MulFix( vec->y, y_scale );
|
||||
}
|
||||
|
||||
FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
|
||||
|
||||
/* Then scale the metrics */
|
||||
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
|
||||
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
|
||||
|
||||
metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
|
||||
metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
|
||||
|
||||
if ( hinting )
|
||||
{
|
||||
metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64;
|
||||
metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64;
|
||||
|
||||
metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64;
|
||||
metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64;
|
||||
}
|
||||
}
|
||||
|
||||
/* compute the other metrics */
|
||||
FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
|
||||
|
||||
/* grid fit the bounding box if necessary */
|
||||
if ( hinting )
|
||||
{
|
||||
cbox.xMin &= -64;
|
||||
cbox.yMin &= -64;
|
||||
cbox.xMax = ( cbox.xMax + 63 ) & -64;
|
||||
cbox.yMax = ( cbox.yMax + 63 ) & -64;
|
||||
}
|
||||
|
||||
metrics->width = cbox.xMax - cbox.xMin;
|
||||
metrics->height = cbox.yMax - cbox.yMin;
|
||||
|
||||
metrics->horiBearingX = cbox.xMin;
|
||||
metrics->horiBearingY = cbox.yMax;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,51 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidgload.h */
|
||||
/* */
|
||||
/* OpenType Glyph Loader (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CIDGLOAD_H__
|
||||
#define __CIDGLOAD_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "cidobjs.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* Compute the maximum advance width of a font through quick parsing */
|
||||
FT_LOCAL FT_Error
|
||||
CID_Compute_Max_Advance( CID_Face face,
|
||||
FT_Int* max_advance );
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CID_Load_Glyph( CID_GlyphSlot glyph,
|
||||
CID_Size size,
|
||||
FT_Int glyph_index,
|
||||
FT_Int load_flags );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __CIDGLOAD_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,549 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidload.c */
|
||||
/* */
|
||||
/* CID-keyed Type1 font loader (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include FT_MULTIPLE_MASTERS_H
|
||||
#include FT_INTERNAL_TYPE1_TYPES_H
|
||||
|
||||
#include "cidload.h"
|
||||
|
||||
#include "ciderrs.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h> /* for isspace(), isalnum() */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_cidload
|
||||
|
||||
|
||||
/* read a single offset */
|
||||
FT_LOCAL_DEF FT_Long
|
||||
cid_get_offset( FT_Byte** start,
|
||||
FT_Byte offsize )
|
||||
{
|
||||
FT_Long result;
|
||||
FT_Byte* p = *start;
|
||||
|
||||
|
||||
for ( result = 0; offsize > 0; offsize-- )
|
||||
{
|
||||
result <<= 8;
|
||||
result |= *p++;
|
||||
}
|
||||
|
||||
*start = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF void
|
||||
cid_decrypt( FT_Byte* buffer,
|
||||
FT_Offset length,
|
||||
FT_UShort seed )
|
||||
{
|
||||
while ( length > 0 )
|
||||
{
|
||||
FT_Byte plain;
|
||||
|
||||
|
||||
plain = (FT_Byte)( *buffer ^ ( seed >> 8 ) );
|
||||
seed = (FT_UShort)( ( *buffer + seed ) * 52845U + 22719 );
|
||||
*buffer++ = plain;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** TYPE 1 SYMBOL PARSING *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
static FT_Error
|
||||
cid_load_keyword( CID_Face face,
|
||||
CID_Loader* loader,
|
||||
const T1_Field* keyword )
|
||||
{
|
||||
FT_Error error;
|
||||
CID_Parser* parser = &loader->parser;
|
||||
FT_Byte* object;
|
||||
void* dummy_object;
|
||||
CID_Info* cid = &face->cid;
|
||||
|
||||
|
||||
/* if the keyword has a dedicated callback, call it */
|
||||
if ( keyword->type == t1_field_callback )
|
||||
{
|
||||
keyword->reader( (FT_Face)face, parser );
|
||||
error = parser->root.error;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* we must now compute the address of our target object */
|
||||
switch ( keyword->location )
|
||||
{
|
||||
case t1_field_cid_info:
|
||||
object = (FT_Byte*)cid;
|
||||
break;
|
||||
|
||||
case t1_field_font_info:
|
||||
object = (FT_Byte*)&cid->font_info;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
CID_FontDict* dict;
|
||||
|
||||
|
||||
if ( parser->num_dict < 0 )
|
||||
{
|
||||
FT_ERROR(( "cid_load_keyword: invalid use of `%s'!\n",
|
||||
keyword->ident ));
|
||||
error = CID_Err_Syntax_Error;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
dict = cid->font_dicts + parser->num_dict;
|
||||
switch ( keyword->location )
|
||||
{
|
||||
case t1_field_private:
|
||||
object = (FT_Byte*)&dict->private_dict;
|
||||
break;
|
||||
|
||||
default:
|
||||
object = (FT_Byte*)dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dummy_object = object;
|
||||
|
||||
/* now, load the keyword data in the object's field(s) */
|
||||
if ( keyword->type == t1_field_integer_array ||
|
||||
keyword->type == t1_field_fixed_array )
|
||||
error = CID_Load_Field_Table( &loader->parser, keyword,
|
||||
&dummy_object );
|
||||
else
|
||||
error = CID_Load_Field( &loader->parser, keyword, &dummy_object );
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
parse_font_bbox( CID_Face face,
|
||||
CID_Parser* parser )
|
||||
{
|
||||
FT_Fixed temp[4];
|
||||
FT_BBox* bbox = &face->cid.font_bbox;
|
||||
|
||||
|
||||
(void)CID_ToFixedArray( parser, 4, temp, 0 );
|
||||
bbox->xMin = FT_RoundFix( temp[0] );
|
||||
bbox->yMin = FT_RoundFix( temp[1] );
|
||||
bbox->xMax = FT_RoundFix( temp[2] );
|
||||
bbox->yMax = FT_RoundFix( temp[3] );
|
||||
|
||||
return CID_Err_Ok; /* this is a callback function; */
|
||||
/* we must return an error code */
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
parse_font_matrix( CID_Face face,
|
||||
CID_Parser* parser )
|
||||
{
|
||||
FT_Matrix* matrix;
|
||||
FT_Vector* offset;
|
||||
CID_FontDict* dict;
|
||||
FT_Face root = (FT_Face)&face->root;
|
||||
FT_Fixed temp[6];
|
||||
FT_Fixed temp_scale;
|
||||
|
||||
|
||||
if ( parser->num_dict >= 0 )
|
||||
{
|
||||
dict = face->cid.font_dicts + parser->num_dict;
|
||||
matrix = &dict->font_matrix;
|
||||
offset = &dict->font_offset;
|
||||
|
||||
(void)CID_ToFixedArray( parser, 6, temp, 3 );
|
||||
|
||||
temp_scale = ABS( temp[3] );
|
||||
|
||||
/* Set Units per EM based on FontMatrix values. We set the value to */
|
||||
/* `1000/temp_scale', because temp_scale was already multiplied by */
|
||||
/* 1000 (in t1_tofixed(), from psobjs.c). */
|
||||
root->units_per_EM = (FT_UShort)( FT_DivFix( 0x10000L,
|
||||
FT_DivFix( temp_scale, 1000 ) ) );
|
||||
|
||||
/* we need to scale the values by 1.0/temp[3] */
|
||||
if ( temp_scale != 0x10000L )
|
||||
{
|
||||
temp[0] = FT_DivFix( temp[0], temp_scale );
|
||||
temp[1] = FT_DivFix( temp[1], temp_scale );
|
||||
temp[2] = FT_DivFix( temp[2], temp_scale );
|
||||
temp[4] = FT_DivFix( temp[4], temp_scale );
|
||||
temp[5] = FT_DivFix( temp[5], temp_scale );
|
||||
temp[3] = 0x10000L;
|
||||
}
|
||||
|
||||
matrix->xx = temp[0];
|
||||
matrix->yx = temp[1];
|
||||
matrix->xy = temp[2];
|
||||
matrix->yy = temp[3];
|
||||
|
||||
/* note that the font offsets are expressed in integer font units */
|
||||
offset->x = temp[4] >> 16;
|
||||
offset->y = temp[5] >> 16;
|
||||
}
|
||||
|
||||
return CID_Err_Ok; /* this is a callback function; */
|
||||
/* we must return an error code */
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
parse_fd_array( CID_Face face,
|
||||
CID_Parser* parser )
|
||||
{
|
||||
CID_Info* cid = &face->cid;
|
||||
FT_Memory memory = face->root.memory;
|
||||
FT_Error error = CID_Err_Ok;
|
||||
FT_Long num_dicts;
|
||||
|
||||
|
||||
num_dicts = CID_ToInt( parser );
|
||||
|
||||
if ( !cid->font_dicts )
|
||||
{
|
||||
FT_Int n;
|
||||
|
||||
|
||||
if ( ALLOC_ARRAY( cid->font_dicts, num_dicts, CID_FontDict ) )
|
||||
goto Exit;
|
||||
|
||||
cid->num_dicts = (FT_UInt)num_dicts;
|
||||
|
||||
/* don't forget to set a few defaults */
|
||||
for ( n = 0; n < cid->num_dicts; n++ )
|
||||
{
|
||||
CID_FontDict* dict = cid->font_dicts + n;
|
||||
|
||||
|
||||
/* default value for lenIV */
|
||||
dict->private_dict.lenIV = 4;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
const T1_Field cid_field_records[] =
|
||||
{
|
||||
|
||||
#include "cidtoken.h"
|
||||
|
||||
T1_FIELD_CALLBACK( "FontBBox", parse_font_bbox )
|
||||
T1_FIELD_CALLBACK( "FDArray", parse_fd_array )
|
||||
T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix )
|
||||
{ 0, t1_field_cid_info, t1_field_none, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
is_alpha( char c )
|
||||
{
|
||||
return ( isalnum( (int)c ) ||
|
||||
c == '.' ||
|
||||
c == '_' );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
cid_parse_dict( CID_Face face,
|
||||
CID_Loader* loader,
|
||||
FT_Byte* base,
|
||||
FT_Long size )
|
||||
{
|
||||
CID_Parser* parser = &loader->parser;
|
||||
|
||||
|
||||
parser->root.cursor = base;
|
||||
parser->root.limit = base + size;
|
||||
parser->root.error = 0;
|
||||
|
||||
{
|
||||
FT_Byte* cur = base;
|
||||
FT_Byte* limit = cur + size;
|
||||
|
||||
|
||||
for ( ;cur < limit; cur++ )
|
||||
{
|
||||
/* look for `%ADOBeginFontDict' */
|
||||
if ( *cur == '%' && cur + 20 < limit &&
|
||||
strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 )
|
||||
{
|
||||
cur += 17;
|
||||
|
||||
/* if /FDArray was found, then cid->num_dicts is > 0, and */
|
||||
/* we can start increasing parser->num_dict */
|
||||
if ( face->cid.num_dicts > 0 )
|
||||
parser->num_dict++;
|
||||
}
|
||||
/* look for immediates */
|
||||
else if ( *cur == '/' && cur + 2 < limit )
|
||||
{
|
||||
FT_Byte* cur2;
|
||||
FT_Int len;
|
||||
|
||||
|
||||
cur++;
|
||||
|
||||
cur2 = cur;
|
||||
while ( cur2 < limit && is_alpha( *cur2 ) )
|
||||
cur2++;
|
||||
|
||||
len = (FT_Int)( cur2 - cur );
|
||||
if ( len > 0 && len < 22 )
|
||||
{
|
||||
/* now compare the immediate name to the keyword table */
|
||||
const T1_Field* keyword = cid_field_records;
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
FT_Byte* name;
|
||||
|
||||
|
||||
name = (FT_Byte*)keyword->ident;
|
||||
if ( !name )
|
||||
break;
|
||||
|
||||
if ( cur[0] == name[0] &&
|
||||
len == (FT_Int)strlen( (const char*)name ) )
|
||||
{
|
||||
FT_Int n;
|
||||
|
||||
|
||||
for ( n = 1; n < len; n++ )
|
||||
if ( cur[n] != name[n] )
|
||||
break;
|
||||
|
||||
if ( n >= len )
|
||||
{
|
||||
/* we found it - run the parsing callback */
|
||||
parser->root.cursor = cur2;
|
||||
CID_Skip_Spaces( parser );
|
||||
parser->root.error = cid_load_keyword( face,
|
||||
loader,
|
||||
keyword );
|
||||
if ( parser->root.error )
|
||||
return parser->root.error;
|
||||
|
||||
cur = parser->root.cursor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
keyword++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return parser->root.error;
|
||||
}
|
||||
|
||||
|
||||
/* read the subrmap and the subrs of each font dict */
|
||||
static FT_Error
|
||||
cid_read_subrs( CID_Face face )
|
||||
{
|
||||
CID_Info* cid = &face->cid;
|
||||
FT_Memory memory = face->root.memory;
|
||||
FT_Stream stream = face->root.stream;
|
||||
FT_Error error;
|
||||
FT_Int n;
|
||||
CID_Subrs* subr;
|
||||
FT_UInt max_offsets = 0;
|
||||
FT_ULong* offsets = 0;
|
||||
|
||||
|
||||
if ( ALLOC_ARRAY( face->subrs, cid->num_dicts, CID_Subrs ) )
|
||||
goto Exit;
|
||||
|
||||
subr = face->subrs;
|
||||
for ( n = 0; n < cid->num_dicts; n++, subr++ )
|
||||
{
|
||||
CID_FontDict* dict = cid->font_dicts + n;
|
||||
FT_Int lenIV = dict->private_dict.lenIV;
|
||||
FT_UInt count, num_subrs = dict->num_subrs;
|
||||
FT_ULong data_len;
|
||||
FT_Byte* p;
|
||||
|
||||
|
||||
/* reallocate offsets array if needed */
|
||||
if ( num_subrs + 1 > max_offsets )
|
||||
{
|
||||
FT_UInt new_max = ( num_subrs + 1 + 3 ) & -4;
|
||||
|
||||
|
||||
if ( REALLOC_ARRAY( offsets, max_offsets, new_max, FT_ULong ) )
|
||||
goto Fail;
|
||||
|
||||
max_offsets = new_max;
|
||||
}
|
||||
|
||||
/* read the subrmap's offsets */
|
||||
if ( FILE_Seek( cid->data_offset + dict->subrmap_offset ) ||
|
||||
ACCESS_Frame( ( num_subrs + 1 ) * dict->sd_bytes ) )
|
||||
goto Fail;
|
||||
|
||||
p = (FT_Byte*)stream->cursor;
|
||||
for ( count = 0; count <= num_subrs; count++ )
|
||||
offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes );
|
||||
|
||||
FORGET_Frame();
|
||||
|
||||
/* now, compute the size of subrs charstrings, */
|
||||
/* allocate, and read them */
|
||||
data_len = offsets[num_subrs] - offsets[0];
|
||||
|
||||
if ( ALLOC_ARRAY( subr->code, num_subrs + 1, FT_Byte* ) ||
|
||||
ALLOC( subr->code[0], data_len ) )
|
||||
goto Fail;
|
||||
|
||||
if ( FILE_Seek( cid->data_offset + offsets[0] ) ||
|
||||
FILE_Read( subr->code[0], data_len ) )
|
||||
goto Fail;
|
||||
|
||||
/* set up pointers */
|
||||
for ( count = 1; count <= num_subrs; count++ )
|
||||
{
|
||||
FT_UInt len;
|
||||
|
||||
|
||||
len = offsets[count] - offsets[count - 1];
|
||||
subr->code[count] = subr->code[count - 1] + len;
|
||||
}
|
||||
|
||||
/* decrypt subroutines, but only if lenIV >= 0 */
|
||||
if ( lenIV >= 0 )
|
||||
{
|
||||
for ( count = 0; count < num_subrs; count++ )
|
||||
{
|
||||
FT_UInt len;
|
||||
|
||||
|
||||
len = offsets[count + 1] - offsets[count];
|
||||
cid_decrypt( subr->code[count], len, 4330 );
|
||||
}
|
||||
}
|
||||
|
||||
subr->num_subrs = num_subrs;
|
||||
}
|
||||
|
||||
Exit:
|
||||
FREE( offsets );
|
||||
return error;
|
||||
|
||||
Fail:
|
||||
if ( face->subrs )
|
||||
{
|
||||
for ( n = 0; n < cid->num_dicts; n++ )
|
||||
{
|
||||
if ( face->subrs[n].code )
|
||||
FREE( face->subrs[n].code[0] );
|
||||
|
||||
FREE( face->subrs[n].code );
|
||||
}
|
||||
FREE( face->subrs );
|
||||
}
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
t1_init_loader( CID_Loader* loader,
|
||||
CID_Face face )
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
|
||||
MEM_Set( loader, 0, sizeof ( *loader ) );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
t1_done_loader( CID_Loader* loader )
|
||||
{
|
||||
CID_Parser* parser = &loader->parser;
|
||||
|
||||
|
||||
/* finalize parser */
|
||||
CID_Done_Parser( parser );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CID_Open_Face( CID_Face face )
|
||||
{
|
||||
CID_Loader loader;
|
||||
CID_Parser* parser;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
t1_init_loader( &loader, face );
|
||||
|
||||
parser = &loader.parser;
|
||||
error = CID_New_Parser( parser, face->root.stream, face->root.memory,
|
||||
(PSAux_Interface*)face->psaux );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
error = cid_parse_dict( face, &loader,
|
||||
parser->postscript,
|
||||
parser->postscript_len );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
face->cid.data_offset = loader.parser.data_offset;
|
||||
error = cid_read_subrs( face );
|
||||
|
||||
Exit:
|
||||
t1_done_loader( &loader );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,57 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidload.h */
|
||||
/* */
|
||||
/* CID-keyed Type1 font loader (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CIDLOAD_H__
|
||||
#define __CIDLOAD_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include "cidparse.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
typedef struct CID_Loader_
|
||||
{
|
||||
CID_Parser parser; /* parser used to read the stream */
|
||||
FT_Int num_chars; /* number of characters in encoding */
|
||||
|
||||
} CID_Loader;
|
||||
|
||||
|
||||
FT_LOCAL FT_Long
|
||||
cid_get_offset( FT_Byte** start,
|
||||
FT_Byte offsize );
|
||||
|
||||
FT_LOCAL void
|
||||
cid_decrypt( FT_Byte* buffer,
|
||||
FT_Offset length,
|
||||
FT_UShort seed );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CID_Open_Face( CID_Face face );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __CIDLOAD_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,541 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidobjs.c */
|
||||
/* */
|
||||
/* CID objects manager (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include "cidgload.h"
|
||||
#include "cidload.h"
|
||||
#include FT_INTERNAL_POSTSCRIPT_NAMES_H
|
||||
#include FT_INTERNAL_POSTSCRIPT_AUX_H
|
||||
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
|
||||
|
||||
#include "ciderrs.h"
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_cidobjs
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* SLOT FUNCTIONS */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
FT_LOCAL_DEF void
|
||||
CID_GlyphSlot_Done( CID_GlyphSlot slot )
|
||||
{
|
||||
slot->root.internal->glyph_hints = 0;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CID_GlyphSlot_Init( CID_GlyphSlot slot )
|
||||
{
|
||||
CID_Face face;
|
||||
PSHinter_Interface* pshinter;
|
||||
|
||||
|
||||
face = (CID_Face) slot->root.face;
|
||||
pshinter = face->pshinter;
|
||||
|
||||
if ( pshinter )
|
||||
{
|
||||
FT_Module module;
|
||||
|
||||
|
||||
module = FT_Get_Module( slot->root.face->driver->root.library,
|
||||
"pshinter" );
|
||||
if ( module )
|
||||
{
|
||||
T1_Hints_Funcs funcs;
|
||||
|
||||
|
||||
funcs = pshinter->get_t1_funcs( module );
|
||||
slot->root.internal->glyph_hints = (void*)funcs;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* SIZE FUNCTIONS */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
static PSH_Globals_Funcs
|
||||
CID_Size_Get_Globals_Funcs( CID_Size size )
|
||||
{
|
||||
CID_Face face = (CID_Face)size->root.face;
|
||||
PSHinter_Interface* pshinter = face->pshinter;
|
||||
FT_Module module;
|
||||
|
||||
|
||||
module = FT_Get_Module( size->root.face->driver->root.library,
|
||||
"pshinter" );
|
||||
return ( module && pshinter && pshinter->get_globals_funcs )
|
||||
? pshinter->get_globals_funcs( module )
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF void
|
||||
CID_Size_Done( CID_Size size )
|
||||
{
|
||||
if ( size->root.internal )
|
||||
{
|
||||
PSH_Globals_Funcs funcs;
|
||||
|
||||
|
||||
funcs = CID_Size_Get_Globals_Funcs( size );
|
||||
if ( funcs )
|
||||
funcs->destroy( (PSH_Globals)size->root.internal );
|
||||
|
||||
size->root.internal = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CID_Size_Init( CID_Size size )
|
||||
{
|
||||
FT_Error error = 0;
|
||||
PSH_Globals_Funcs funcs = CID_Size_Get_Globals_Funcs( size );
|
||||
|
||||
|
||||
if ( funcs )
|
||||
{
|
||||
PSH_Globals globals;
|
||||
CID_Face face = (CID_Face)size->root.face;
|
||||
CID_FontDict* dict = face->cid.font_dicts + face->root.face_index;
|
||||
T1_Private* priv = &dict->private_dict;
|
||||
|
||||
|
||||
error = funcs->create( size->root.face->memory, priv, &globals );
|
||||
if ( !error )
|
||||
size->root.internal = (FT_Size_Internal)(void*)globals;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CID_Size_Reset( CID_Size size )
|
||||
{
|
||||
PSH_Globals_Funcs funcs = CID_Size_Get_Globals_Funcs( size );
|
||||
FT_Error error = 0;
|
||||
|
||||
|
||||
if ( funcs )
|
||||
error = funcs->set_scale( (PSH_Globals)size->root.internal,
|
||||
size->root.metrics.x_scale,
|
||||
size->root.metrics.y_scale,
|
||||
0, 0 );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* FACE FUNCTIONS */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* CID_Face_Done */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Finalizes a given face object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A pointer to the face object to destroy. */
|
||||
/* */
|
||||
FT_LOCAL_DEF void
|
||||
CID_Face_Done( CID_Face face )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
if ( face )
|
||||
{
|
||||
CID_Info* cid = &face->cid;
|
||||
T1_FontInfo* info = &cid->font_info;
|
||||
|
||||
|
||||
memory = face->root.memory;
|
||||
|
||||
/* release subrs */
|
||||
if ( face->subrs )
|
||||
{
|
||||
FT_Int n;
|
||||
|
||||
|
||||
for ( n = 0; n < cid->num_dicts; n++ )
|
||||
{
|
||||
CID_Subrs* subr = face->subrs + n;
|
||||
|
||||
|
||||
if ( subr->code )
|
||||
{
|
||||
FREE( subr->code[0] );
|
||||
FREE( subr->code );
|
||||
}
|
||||
}
|
||||
|
||||
FREE( face->subrs );
|
||||
}
|
||||
|
||||
/* release FontInfo strings */
|
||||
FREE( info->version );
|
||||
FREE( info->notice );
|
||||
FREE( info->full_name );
|
||||
FREE( info->family_name );
|
||||
FREE( info->weight );
|
||||
|
||||
/* release font dictionaries */
|
||||
FREE( cid->font_dicts );
|
||||
cid->num_dicts = 0;
|
||||
|
||||
/* release other strings */
|
||||
FREE( cid->cid_font_name );
|
||||
FREE( cid->registry );
|
||||
FREE( cid->ordering );
|
||||
|
||||
face->root.family_name = 0;
|
||||
face->root.style_name = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* CID_Face_Init */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Initializes a given CID face object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* stream :: The source font stream. */
|
||||
/* */
|
||||
/* face_index :: The index of the font face in the resource. */
|
||||
/* */
|
||||
/* num_params :: Number of additional generic parameters. Ignored. */
|
||||
/* */
|
||||
/* params :: Additional generic parameters. Ignored. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* face :: The newly built face object. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CID_Face_Init( FT_Stream stream,
|
||||
CID_Face face,
|
||||
FT_Int face_index,
|
||||
FT_Int num_params,
|
||||
FT_Parameter* params )
|
||||
{
|
||||
FT_Error error;
|
||||
PSNames_Interface* psnames;
|
||||
PSAux_Interface* psaux;
|
||||
PSHinter_Interface* pshinter;
|
||||
|
||||
FT_UNUSED( num_params );
|
||||
FT_UNUSED( params );
|
||||
FT_UNUSED( face_index );
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
face->root.num_faces = 1;
|
||||
|
||||
psnames = (PSNames_Interface*)face->psnames;
|
||||
if ( !psnames )
|
||||
{
|
||||
psnames = (PSNames_Interface*)FT_Get_Module_Interface(
|
||||
FT_FACE_LIBRARY( face ), "psnames" );
|
||||
|
||||
face->psnames = psnames;
|
||||
}
|
||||
|
||||
psaux = (PSAux_Interface*)face->psaux;
|
||||
if ( !psaux )
|
||||
{
|
||||
psaux = (PSAux_Interface*)FT_Get_Module_Interface(
|
||||
FT_FACE_LIBRARY( face ), "psaux" );
|
||||
|
||||
face->psaux = psaux;
|
||||
}
|
||||
|
||||
pshinter = (PSHinter_Interface*)face->pshinter;
|
||||
if ( !pshinter )
|
||||
{
|
||||
pshinter = (PSHinter_Interface*)FT_Get_Module_Interface(
|
||||
FT_FACE_LIBRARY( face ), "pshinter" );
|
||||
|
||||
face->pshinter = pshinter;
|
||||
}
|
||||
|
||||
/* open the tokenizer; this will also check the font format */
|
||||
if ( FILE_Seek( 0 ) )
|
||||
goto Exit;
|
||||
|
||||
error = CID_Open_Face( face );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* if we just wanted to check the format, leave successfully now */
|
||||
if ( face_index < 0 )
|
||||
goto Exit;
|
||||
|
||||
/* check the face index */
|
||||
if ( face_index != 0 )
|
||||
{
|
||||
FT_ERROR(( "CID_Face_Init: invalid face index\n" ));
|
||||
error = CID_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Now, load the font program into the face object */
|
||||
{
|
||||
/* Init the face object fields */
|
||||
/* Now set up root face fields */
|
||||
{
|
||||
FT_Face root = (FT_Face)&face->root;
|
||||
|
||||
|
||||
root->num_glyphs = face->cid.cid_count;
|
||||
root->num_charmaps = 0;
|
||||
|
||||
root->face_index = face_index;
|
||||
root->face_flags = FT_FACE_FLAG_SCALABLE;
|
||||
|
||||
root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
|
||||
|
||||
if ( face->cid.font_info.is_fixed_pitch )
|
||||
root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
|
||||
|
||||
/* XXX: TODO: add kerning with .afm support */
|
||||
|
||||
/* get style name -- be careful, some broken fonts only */
|
||||
/* have a /FontName dictionary entry! */
|
||||
root->family_name = face->cid.font_info.family_name;
|
||||
if ( root->family_name )
|
||||
{
|
||||
char* full = face->cid.font_info.full_name;
|
||||
char* family = root->family_name;
|
||||
|
||||
while ( *family && *full == *family )
|
||||
{
|
||||
family++;
|
||||
full++;
|
||||
}
|
||||
|
||||
root->style_name = ( *full == ' ' ) ? full + 1
|
||||
: (char *)"Regular";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* do we have a `/FontName'? */
|
||||
if ( face->cid.cid_font_name )
|
||||
{
|
||||
root->family_name = face->cid.cid_font_name;
|
||||
root->style_name = (char *)"Regular";
|
||||
}
|
||||
}
|
||||
|
||||
/* no embedded bitmap support */
|
||||
root->num_fixed_sizes = 0;
|
||||
root->available_sizes = 0;
|
||||
|
||||
root->bbox = face->cid.font_bbox;
|
||||
if ( !root->units_per_EM )
|
||||
root->units_per_EM = 1000;
|
||||
|
||||
root->ascender = (FT_Short)( face->cid.font_bbox.yMax >> 16 );
|
||||
root->descender = (FT_Short)( face->cid.font_bbox.yMin >> 16 );
|
||||
root->height = (FT_Short)(
|
||||
( ( root->ascender + root->descender ) * 12 ) / 10 );
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* now compute the maximum advance width */
|
||||
|
||||
root->max_advance_width = face->type1.private_dict.standard_width[0];
|
||||
|
||||
/* compute max advance width for proportional fonts */
|
||||
if ( !face->type1.font_info.is_fixed_pitch )
|
||||
{
|
||||
FT_Int max_advance;
|
||||
|
||||
|
||||
error = CID_Compute_Max_Advance( face, &max_advance );
|
||||
|
||||
/* in case of error, keep the standard width */
|
||||
if ( !error )
|
||||
root->max_advance_width = max_advance;
|
||||
else
|
||||
error = 0; /* clear error */
|
||||
}
|
||||
|
||||
root->max_advance_height = root->height;
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
root->underline_position = face->cid.font_info.underline_position;
|
||||
root->underline_thickness = face->cid.font_info.underline_thickness;
|
||||
|
||||
root->internal->max_points = 0;
|
||||
root->internal->max_contours = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* charmap support - synthetize unicode charmap when possible */
|
||||
{
|
||||
FT_Face root = &face->root;
|
||||
FT_CharMap charmap = face->charmaprecs;
|
||||
|
||||
|
||||
/* synthesize a Unicode charmap if there is support in the `psnames' */
|
||||
/* module */
|
||||
if ( face->psnames )
|
||||
{
|
||||
PSNames_Interface* psnames = (PSNames_Interface*)face->psnames;
|
||||
|
||||
|
||||
if ( psnames->unicode_value )
|
||||
{
|
||||
error = psnames->build_unicodes(
|
||||
root->memory,
|
||||
face->type1.num_glyphs,
|
||||
(const char**)face->type1.glyph_names,
|
||||
&face->unicode_map );
|
||||
if ( !error )
|
||||
{
|
||||
root->charmap = charmap;
|
||||
charmap->face = (FT_Face)face;
|
||||
charmap->encoding = ft_encoding_unicode;
|
||||
charmap->platform_id = 3;
|
||||
charmap->encoding_id = 1;
|
||||
charmap++;
|
||||
}
|
||||
|
||||
/* simply clear the error in case of failure (which really */
|
||||
/* means that out of memory or no unicode glyph names) */
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* now, support either the standard, expert, or custom encodings */
|
||||
charmap->face = (FT_Face)face;
|
||||
charmap->platform_id = 7; /* a new platform id for Adobe fonts? */
|
||||
|
||||
switch ( face->type1.encoding_type )
|
||||
{
|
||||
case t1_encoding_standard:
|
||||
charmap->encoding = ft_encoding_adobe_standard;
|
||||
charmap->encoding_id = 0;
|
||||
break;
|
||||
|
||||
case t1_encoding_expert:
|
||||
charmap->encoding = ft_encoding_adobe_expert;
|
||||
charmap->encoding_id = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
charmap->encoding = ft_encoding_adobe_custom;
|
||||
charmap->encoding_id = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
root->charmaps = face->charmaps;
|
||||
root->num_charmaps = charmap - face->charmaprecs + 1;
|
||||
face->charmaps[0] = &face->charmaprecs[0];
|
||||
face->charmaps[1] = &face->charmaprecs[1];
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* CID_Driver_Init */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Initializes a given CID driver object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* driver :: A handle to the target driver object. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CID_Driver_Init( CID_Driver driver )
|
||||
{
|
||||
FT_UNUSED( driver );
|
||||
|
||||
return CID_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* CID_Driver_Done */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Finalizes a given CID driver. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* driver :: A handle to the target CID driver. */
|
||||
/* */
|
||||
FT_LOCAL_DEF void
|
||||
CID_Driver_Done( CID_Driver driver )
|
||||
{
|
||||
FT_UNUSED( driver );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,158 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidobjs.h */
|
||||
/* */
|
||||
/* CID objects manager (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CIDOBJS_H__
|
||||
#define __CIDOBJS_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include FT_INTERNAL_TYPE1_TYPES_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* The following structures must be defined by the hinter */
|
||||
typedef struct CID_Size_Hints_ CID_Size_Hints;
|
||||
typedef struct CID_Glyph_Hints_ CID_Glyph_Hints;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Type> */
|
||||
/* CID_Driver */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A handle to a Type 1 driver object. */
|
||||
/* */
|
||||
typedef struct CID_DriverRec_* CID_Driver;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Type> */
|
||||
/* CID_Size */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A handle to a Type 1 size object. */
|
||||
/* */
|
||||
typedef struct CID_SizeRec_* CID_Size;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Type> */
|
||||
/* CID_GlyphSlot */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A handle to a Type 1 glyph slot object. */
|
||||
/* */
|
||||
typedef struct CID_GlyphSlotRec_* CID_GlyphSlot;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Type> */
|
||||
/* CID_CharMap */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A handle to a Type 1 character mapping object. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* The Type 1 format doesn't use a charmap but an encoding table. */
|
||||
/* The driver is responsible for making up charmap objects */
|
||||
/* corresponding to these tables. */
|
||||
/* */
|
||||
typedef struct CID_CharMapRec_* CID_CharMap;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* HERE BEGINS THE TYPE 1 SPECIFIC STUFF */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
typedef struct CID_SizeRec_
|
||||
{
|
||||
FT_SizeRec root;
|
||||
FT_Bool valid;
|
||||
|
||||
} CID_SizeRec;
|
||||
|
||||
|
||||
typedef struct CID_GlyphSlotRec_
|
||||
{
|
||||
FT_GlyphSlotRec root;
|
||||
|
||||
FT_Bool hint;
|
||||
FT_Bool scaled;
|
||||
|
||||
FT_Fixed x_scale;
|
||||
FT_Fixed y_scale;
|
||||
|
||||
} CID_GlyphSlotRec;
|
||||
|
||||
|
||||
FT_LOCAL void
|
||||
CID_GlyphSlot_Done( CID_GlyphSlot slot );
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CID_GlyphSlot_Init( CID_GlyphSlot slot );
|
||||
|
||||
|
||||
FT_LOCAL void
|
||||
CID_Size_Done( CID_Size size );
|
||||
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CID_Size_Init( CID_Size size );
|
||||
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CID_Size_Reset( CID_Size size );
|
||||
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CID_Face_Init( FT_Stream stream,
|
||||
CID_Face face,
|
||||
FT_Int face_index,
|
||||
FT_Int num_params,
|
||||
FT_Parameter* params );
|
||||
|
||||
|
||||
FT_LOCAL void
|
||||
CID_Face_Done( CID_Face face );
|
||||
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CID_Driver_Init( CID_Driver driver );
|
||||
|
||||
|
||||
FT_LOCAL void
|
||||
CID_Driver_Done( CID_Driver driver );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __CIDOBJS_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,157 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidparse.c */
|
||||
/* */
|
||||
/* CID-keyed Type1 parser (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_CALC_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
|
||||
#include "cidparse.h"
|
||||
|
||||
#include "ciderrs.h"
|
||||
|
||||
#include <string.h> /* for strncmp() */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_cidparse
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** INPUT STREAM PARSER *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_LOCAL_DEF FT_Error
|
||||
CID_New_Parser( CID_Parser* parser,
|
||||
FT_Stream stream,
|
||||
FT_Memory memory,
|
||||
PSAux_Interface* psaux )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_ULong base_offset, offset, ps_len;
|
||||
FT_Byte buffer[256 + 10];
|
||||
FT_Int buff_len;
|
||||
|
||||
|
||||
MEM_Set( parser, 0, sizeof ( *parser ) );
|
||||
psaux->t1_parser_funcs->init( &parser->root, 0, 0, memory );
|
||||
|
||||
parser->stream = stream;
|
||||
|
||||
base_offset = FILE_Pos();
|
||||
|
||||
/* first of all, check the font format in the header */
|
||||
if ( ACCESS_Frame( 31 ) )
|
||||
goto Exit;
|
||||
|
||||
if ( strncmp( (char *)stream->cursor,
|
||||
"%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
|
||||
{
|
||||
FT_TRACE2(( "[not a valid CID-keyed font]\n" ));
|
||||
error = CID_Err_Unknown_File_Format;
|
||||
}
|
||||
|
||||
FORGET_Frame();
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* now, read the rest of the file, until we find a `StartData' */
|
||||
buff_len = 256;
|
||||
for (;;)
|
||||
{
|
||||
FT_Byte *p, *limit = buffer + 256;
|
||||
FT_ULong top_position;
|
||||
|
||||
|
||||
/* fill input buffer */
|
||||
buff_len -= 256;
|
||||
if ( buff_len > 0 )
|
||||
MEM_Move( buffer, limit, buff_len );
|
||||
|
||||
p = buffer + buff_len;
|
||||
|
||||
if ( FILE_Read( p, 256 + 10 - buff_len ) )
|
||||
goto Exit;
|
||||
|
||||
top_position = FILE_Pos() - buff_len;
|
||||
buff_len = 256 + 10;
|
||||
|
||||
/* look for `StartData' */
|
||||
for ( p = buffer; p < limit; p++ )
|
||||
{
|
||||
if ( p[0] == 'S' && strncmp( (char*)p, "StartData", 9 ) == 0 )
|
||||
{
|
||||
/* save offset of binary data after `StartData' */
|
||||
offset = (FT_ULong)( top_position - ( limit - p ) + 10 );
|
||||
goto Found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Found:
|
||||
/* we have found the start of the binary data. We will now */
|
||||
/* rewind and extract the frame of corresponding to the Postscript */
|
||||
/* section */
|
||||
|
||||
ps_len = offset - base_offset;
|
||||
if ( FILE_Seek( base_offset ) ||
|
||||
EXTRACT_Frame( ps_len, parser->postscript ) )
|
||||
goto Exit;
|
||||
|
||||
parser->data_offset = offset;
|
||||
parser->postscript_len = ps_len;
|
||||
parser->root.base = parser->postscript;
|
||||
parser->root.cursor = parser->postscript;
|
||||
parser->root.limit = parser->root.cursor + ps_len;
|
||||
parser->num_dict = -1;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF void
|
||||
CID_Done_Parser( CID_Parser* parser )
|
||||
{
|
||||
/* always free the private dictionary */
|
||||
if ( parser->postscript )
|
||||
{
|
||||
FT_Stream stream = parser->stream;
|
||||
|
||||
|
||||
RELEASE_Frame( parser->postscript );
|
||||
}
|
||||
parser->root.funcs.done( &parser->root );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,116 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidparse.h */
|
||||
/* */
|
||||
/* CID-keyed Type1 parser (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CIDPARSE_H__
|
||||
#define __CIDPARSE_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_TYPE1_TYPES_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include FT_INTERNAL_POSTSCRIPT_AUX_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Struct> */
|
||||
/* CID_Parser */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A CID_Parser is an object used to parse a Type 1 fonts very */
|
||||
/* quickly. */
|
||||
/* */
|
||||
/* <Fields> */
|
||||
/* root :: the root T1_Parser fields */
|
||||
/* */
|
||||
/* stream :: The current input stream. */
|
||||
/* */
|
||||
/* postscript :: A pointer to the data to be parsed. */
|
||||
/* */
|
||||
/* postscript_len :: The length of the data to be parsed. */
|
||||
/* */
|
||||
/* data_offset :: The start position of the binary data (i.e., the */
|
||||
/* end of the data to be parsed. */
|
||||
/* */
|
||||
/* cid :: A structure which holds the information about */
|
||||
/* the current font. */
|
||||
/* */
|
||||
/* num_dict :: The number of font dictionaries. */
|
||||
/* */
|
||||
typedef struct CID_Parser_
|
||||
{
|
||||
T1_Parser root;
|
||||
FT_Stream stream;
|
||||
|
||||
FT_Byte* postscript;
|
||||
FT_Int postscript_len;
|
||||
|
||||
FT_ULong data_offset;
|
||||
|
||||
CID_Info* cid;
|
||||
FT_Int num_dict;
|
||||
|
||||
} CID_Parser;
|
||||
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
CID_New_Parser( CID_Parser* parser,
|
||||
FT_Stream stream,
|
||||
FT_Memory memory,
|
||||
PSAux_Interface* psaux );
|
||||
|
||||
FT_LOCAL void
|
||||
CID_Done_Parser( CID_Parser* parser );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* PARSING ROUTINES */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
#define CID_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root )
|
||||
#define CID_Skip_Alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root )
|
||||
|
||||
#define CID_ToInt( p ) (p)->root.funcs.to_int( &(p)->root )
|
||||
#define CID_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t )
|
||||
|
||||
#define CID_ToCoordArray( p, m, c ) \
|
||||
(p)->root.funcs.to_coord_array( &(p)->root, m, c )
|
||||
#define CID_ToFixedArray( p, m, f, t ) \
|
||||
(p)->root.funcs.to_fixed_array( &(p)->root, m, f, t )
|
||||
#define CID_ToToken( p, t ) \
|
||||
(p)->root.funcs.to_token( &(p)->root, t )
|
||||
#define CID_ToTokenArray( p, t, m, c ) \
|
||||
(p)->root.funcs.to_token_array( &(p)->root, t, m, c )
|
||||
|
||||
#define CID_Load_Field( p, f, o ) \
|
||||
(p)->root.funcs.load_field( &(p)->root, f, o, 0, 0 )
|
||||
#define CID_Load_Field_Table( p, f, o ) \
|
||||
(p)->root.funcs.load_field_table( &(p)->root, f, o, 0, 0 )
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __CIDPARSE_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,367 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidriver.c */
|
||||
/* */
|
||||
/* CID driver interface (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "cidriver.h"
|
||||
#include "cidgload.h"
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include FT_INTERNAL_POSTSCRIPT_NAMES_H
|
||||
|
||||
#include "ciderrs.h"
|
||||
|
||||
#include <string.h> /* for strcmp() */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_ciddriver
|
||||
|
||||
|
||||
|
||||
static const char*
|
||||
cid_get_postscript_name( CID_Face face )
|
||||
{
|
||||
return (const char*)face->cid.cid_font_name;
|
||||
}
|
||||
|
||||
|
||||
static FT_Module_Interface
|
||||
CID_Get_Interface( FT_Driver driver,
|
||||
const FT_String* interface )
|
||||
{
|
||||
FT_UNUSED( driver );
|
||||
FT_UNUSED( interface );
|
||||
|
||||
if ( strcmp( (const char*)interface, "postscript_name" ) == 0 )
|
||||
return (FT_Module_Interface)cid_get_postscript_name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* unimplemented yet */
|
||||
|
||||
static FT_Error
|
||||
cid_Get_Kerning( T1_Face face,
|
||||
FT_UInt left_glyph,
|
||||
FT_UInt right_glyph,
|
||||
FT_Vector* kerning )
|
||||
{
|
||||
CID_AFM* afm;
|
||||
|
||||
|
||||
kerning->x = 0;
|
||||
kerning->y = 0;
|
||||
|
||||
afm = (CID_AFM*)face->afm_data;
|
||||
if ( afm )
|
||||
CID_Get_Kerning( afm, left_glyph, right_glyph, kerning );
|
||||
|
||||
return CID_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* Cid_Get_Char_Index */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Uses a charmap to return a given character code's glyph index. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* charmap :: A handle to the source charmap object. */
|
||||
/* */
|
||||
/* charcode :: The character code. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Glyph index. 0 means `undefined character code'. */
|
||||
/* */
|
||||
static FT_UInt
|
||||
CID_Get_Char_Index( FT_CharMap charmap,
|
||||
FT_Long charcode )
|
||||
{
|
||||
T1_Face face;
|
||||
FT_UInt result = 0;
|
||||
PSNames_Interface* psnames;
|
||||
|
||||
|
||||
face = (T1_Face)charmap->face;
|
||||
psnames = (PSNames_Interface*)face->psnames;
|
||||
if ( psnames )
|
||||
switch ( charmap->encoding )
|
||||
{
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* Unicode encoding support */
|
||||
/* */
|
||||
case ft_encoding_unicode:
|
||||
/* use the `PSNames' module to synthetize the Unicode charmap */
|
||||
result = psnames->lookup_unicode( &face->unicode_map,
|
||||
(FT_ULong)charcode );
|
||||
|
||||
/* the function returns 0xFFFF if the Unicode charcode has */
|
||||
/* no corresponding glyph. */
|
||||
if ( result == 0xFFFF )
|
||||
result = 0;
|
||||
goto Exit;
|
||||
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* Custom Type 1 encoding */
|
||||
/* */
|
||||
case ft_encoding_adobe_custom:
|
||||
{
|
||||
T1_Encoding* encoding = &face->type1.encoding;
|
||||
|
||||
|
||||
if ( charcode >= encoding->code_first &&
|
||||
charcode <= encoding->code_last )
|
||||
result = encoding->char_index[charcode];
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* Adobe Standard & Expert encoding support */
|
||||
/* */
|
||||
default:
|
||||
if ( charcode < 256 )
|
||||
{
|
||||
FT_UInt code;
|
||||
FT_Int n;
|
||||
const char* glyph_name;
|
||||
|
||||
|
||||
code = psnames->adobe_std_encoding[charcode];
|
||||
if ( charmap->encoding == ft_encoding_adobe_expert )
|
||||
code = psnames->adobe_expert_encoding[charcode];
|
||||
|
||||
glyph_name = psnames->adobe_std_strings( code );
|
||||
if ( !glyph_name )
|
||||
break;
|
||||
|
||||
for ( n = 0; n < face->type1.num_glyphs; n++ )
|
||||
{
|
||||
const char* gname = face->type1.glyph_names[n];
|
||||
|
||||
|
||||
if ( gname && gname[0] == glyph_name[0] &&
|
||||
strcmp( gname, glyph_name ) == 0 )
|
||||
{
|
||||
result = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* Cid_Get_Next_Char */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Uses a charmap to return the next encoded char after. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* charmap :: A handle to the source charmap object. */
|
||||
/* */
|
||||
/* charcode :: The character code. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Next char code. 0 means `no more char codes'. */
|
||||
/* */
|
||||
static FT_Long
|
||||
CID_Get_Next_Char( FT_CharMap charmap,
|
||||
FT_Long charcode )
|
||||
{
|
||||
T1_Face face;
|
||||
PSNames_Interface* psnames;
|
||||
|
||||
|
||||
face = (T1_Face)charmap->face;
|
||||
psnames = (PSNames_Interface*)face->psnames;
|
||||
|
||||
if ( psnames )
|
||||
switch ( charmap->encoding )
|
||||
{
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* Unicode encoding support */
|
||||
/* */
|
||||
case ft_encoding_unicode:
|
||||
/* use the `PSNames' module to synthetize the Unicode charmap */
|
||||
return psnames->next_unicode (&face->unicode_map,
|
||||
(FT_ULong)charcode );
|
||||
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* Custom Type 1 encoding */
|
||||
/* */
|
||||
case ft_encoding_adobe_custom:
|
||||
{
|
||||
T1_Encoding* encoding = &face->type1.encoding;
|
||||
|
||||
|
||||
charcode++;
|
||||
if ( charcode < encoding->code_first )
|
||||
charcode = encoding->code_first;
|
||||
while ( charcode <= encoding->code_last )
|
||||
{
|
||||
if ( encoding->char_index[charcode] )
|
||||
return charcode;
|
||||
charcode++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* Adobe Standard & Expert encoding support */
|
||||
/* */
|
||||
default:
|
||||
while ( ++charcode < 256 )
|
||||
{
|
||||
FT_UInt code;
|
||||
FT_Int n;
|
||||
const char* glyph_name;
|
||||
|
||||
|
||||
code = psnames->adobe_std_encoding[charcode];
|
||||
if ( charmap->encoding == ft_encoding_adobe_expert )
|
||||
code = psnames->adobe_expert_encoding[charcode];
|
||||
|
||||
glyph_name = psnames->adobe_std_strings( code );
|
||||
if ( !glyph_name )
|
||||
continue;
|
||||
|
||||
for ( n = 0; n < face->type1.num_glyphs; n++ )
|
||||
{
|
||||
const char* gname = face->type1.glyph_names[n];
|
||||
|
||||
|
||||
if ( gname && gname[0] == glyph_name[0] &&
|
||||
strcmp( gname, glyph_name ) == 0 )
|
||||
{
|
||||
return charcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FT_Driver_Class t1cid_driver_class =
|
||||
{
|
||||
/* first of all, the FT_Module_Class fields */
|
||||
{
|
||||
ft_module_font_driver |
|
||||
ft_module_driver_scalable |
|
||||
ft_module_driver_has_hinter ,
|
||||
|
||||
sizeof( FT_DriverRec ),
|
||||
"t1cid", /* module name */
|
||||
0x10000L, /* version 1.0 of driver */
|
||||
0x20000L, /* requires FreeType 2.0 */
|
||||
|
||||
0,
|
||||
|
||||
(FT_Module_Constructor)CID_Driver_Init,
|
||||
(FT_Module_Destructor) CID_Driver_Done,
|
||||
(FT_Module_Requester) CID_Get_Interface
|
||||
},
|
||||
|
||||
/* then the other font drivers fields */
|
||||
sizeof( CID_FaceRec ),
|
||||
sizeof( CID_SizeRec ),
|
||||
sizeof( CID_GlyphSlotRec ),
|
||||
|
||||
(FTDriver_initFace) CID_Face_Init,
|
||||
(FTDriver_doneFace) CID_Face_Done,
|
||||
|
||||
(FTDriver_initSize) CID_Size_Init,
|
||||
(FTDriver_doneSize) CID_Size_Done,
|
||||
(FTDriver_initGlyphSlot)CID_GlyphSlot_Init,
|
||||
(FTDriver_doneGlyphSlot)CID_GlyphSlot_Done,
|
||||
|
||||
(FTDriver_setCharSizes) CID_Size_Reset,
|
||||
(FTDriver_setPixelSizes)CID_Size_Reset,
|
||||
|
||||
(FTDriver_loadGlyph) CID_Load_Glyph,
|
||||
(FTDriver_getCharIndex) CID_Get_Char_Index,
|
||||
|
||||
(FTDriver_getKerning) 0,
|
||||
(FTDriver_attachFile) 0,
|
||||
|
||||
(FTDriver_getAdvances) 0,
|
||||
|
||||
(FTDriver_getNextChar) CID_Get_Next_Char
|
||||
};
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* getDriverClass */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* This function is used when compiling the TrueType driver as a */
|
||||
/* shared library (`.DLL' or `.so'). It will be used by the */
|
||||
/* high-level library of FreeType to retrieve the address of the */
|
||||
/* driver's generic interface. */
|
||||
/* */
|
||||
/* It shouldn't be implemented in a static build, as each driver must */
|
||||
/* have the same function as an exported entry point. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of the TrueType's driver generic interface. The */
|
||||
/* format-specific interface can then be retrieved through the method */
|
||||
/* interface->get_format_interface. */
|
||||
/* */
|
||||
FT_EXPORT_DEF( const FT_Driver_Class* )
|
||||
getDriverClass( void )
|
||||
{
|
||||
return &t1cid_driver_class;
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,39 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidriver.h */
|
||||
/* */
|
||||
/* High-level CID driver interface (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CIDRIVER_H__
|
||||
#define __CIDRIVER_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DRIVER_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE
|
||||
const FT_Driver_Class t1cid_driver_class;
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __CIDRIVER_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,96 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* cidtoken.h */
|
||||
/* */
|
||||
/* CID token definitions (specification only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CID_Info
|
||||
#undef T1CODE
|
||||
#define T1CODE t1_field_cid_info
|
||||
|
||||
T1_FIELD_STRING( "CIDFontName", cid_font_name )
|
||||
T1_FIELD_NUM ( "CIDFontVersion", cid_version )
|
||||
T1_FIELD_NUM ( "CIDFontType", cid_font_type )
|
||||
T1_FIELD_STRING( "Registry", registry )
|
||||
T1_FIELD_STRING( "Ordering", ordering )
|
||||
T1_FIELD_NUM ( "Supplement", supplement )
|
||||
T1_FIELD_NUM ( "UIDBase", uid_base )
|
||||
T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset )
|
||||
T1_FIELD_NUM ( "FDBytes", fd_bytes )
|
||||
T1_FIELD_NUM ( "GDBytes", gd_bytes )
|
||||
T1_FIELD_NUM ( "CIDCount", cid_count )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE T1_FontInfo
|
||||
#undef T1CODE
|
||||
#define T1CODE t1_field_font_info
|
||||
|
||||
T1_FIELD_STRING( "version", version )
|
||||
T1_FIELD_STRING( "Notice", notice )
|
||||
T1_FIELD_STRING( "FullName", full_name )
|
||||
T1_FIELD_STRING( "FamilyName", family_name )
|
||||
T1_FIELD_STRING( "Weight", weight )
|
||||
T1_FIELD_FIXED ( "ItalicAngle", italic_angle )
|
||||
T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch )
|
||||
T1_FIELD_NUM ( "UnderlinePosition", underline_position )
|
||||
T1_FIELD_NUM ( "UnderlineThickness", underline_thickness )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CID_FontDict
|
||||
#undef T1CODE
|
||||
#define T1CODE t1_field_font_dict
|
||||
|
||||
T1_FIELD_NUM ( "PaintType", paint_type )
|
||||
T1_FIELD_NUM ( "FontType", font_type )
|
||||
T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset )
|
||||
T1_FIELD_NUM ( "SDBytes", sd_bytes )
|
||||
T1_FIELD_NUM ( "SubrCount", num_subrs )
|
||||
T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar )
|
||||
T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold )
|
||||
T1_FIELD_FIXED( "ExpansionFactor", expansion_factor )
|
||||
T1_FIELD_NUM ( "StrokeWidth", stroke_width )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE T1_Private
|
||||
#undef T1CODE
|
||||
#define T1CODE t1_field_private
|
||||
|
||||
T1_FIELD_NUM ( "UniqueID", unique_id )
|
||||
T1_FIELD_NUM ( "lenIV", lenIV )
|
||||
T1_FIELD_NUM ( "LanguageGroup", language_group )
|
||||
T1_FIELD_NUM ( "password", password )
|
||||
|
||||
T1_FIELD_FIXED ( "BlueScale", blue_scale )
|
||||
T1_FIELD_NUM ( "BlueShift", blue_shift )
|
||||
T1_FIELD_NUM ( "BlueFuzz", blue_fuzz )
|
||||
|
||||
T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 )
|
||||
T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 )
|
||||
T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 )
|
||||
T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 )
|
||||
|
||||
T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 )
|
||||
T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 )
|
||||
T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 )
|
||||
|
||||
T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 )
|
||||
T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 )
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,70 +0,0 @@
|
|||
#
|
||||
# FreeType 2 CID driver configuration rules
|
||||
#
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
# CID driver directory
|
||||
#
|
||||
CID_DIR := $(SRC_)cid
|
||||
CID_DIR_ := $(CID_DIR)$(SEP)
|
||||
|
||||
|
||||
CID_COMPILE := $(FT_COMPILE) $I$(CID_DIR)
|
||||
|
||||
|
||||
# CID driver sources (i.e., C files)
|
||||
#
|
||||
CID_DRV_SRC := $(CID_DIR_)cidparse.c \
|
||||
$(CID_DIR_)cidload.c \
|
||||
$(CID_DIR_)cidriver.c \
|
||||
$(CID_DIR_)cidgload.c \
|
||||
$(CID_DIR_)cidobjs.c
|
||||
|
||||
# CID driver headers
|
||||
#
|
||||
CID_DRV_H := $(CID_DRV_SRC:%.c=%.h) \
|
||||
$(CID_DIR_)cidtoken.h \
|
||||
$(CID_DIR_)ciderrs.h
|
||||
|
||||
|
||||
# CID driver object(s)
|
||||
#
|
||||
# CID_DRV_OBJ_M is used during `multi' builds
|
||||
# CID_DRV_OBJ_S is used during `single' builds
|
||||
#
|
||||
CID_DRV_OBJ_M := $(CID_DRV_SRC:$(CID_DIR_)%.c=$(OBJ_)%.$O)
|
||||
CID_DRV_OBJ_S := $(OBJ_)type1cid.$O
|
||||
|
||||
# CID driver source file for single build
|
||||
#
|
||||
CID_DRV_SRC_S := $(CID_DIR_)type1cid.c
|
||||
|
||||
|
||||
# CID driver - single object
|
||||
#
|
||||
$(CID_DRV_OBJ_S): $(CID_DRV_SRC_S) $(CID_DRV_SRC) $(FREETYPE_H) $(CID_DRV_H)
|
||||
$(CID_COMPILE) $T$@ $(CID_DRV_SRC_S)
|
||||
|
||||
|
||||
# CID driver - multiple objects
|
||||
#
|
||||
$(OBJ_)%.$O: $(CID_DIR_)%.c $(FREETYPE_H) $(CID_DRV_H)
|
||||
$(CID_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
# update main driver object lists
|
||||
#
|
||||
DRV_OBJS_S += $(CID_DRV_OBJ_S)
|
||||
DRV_OBJS_M += $(CID_DRV_OBJ_M)
|
||||
|
||||
# EOF
|
|
@ -1,35 +0,0 @@
|
|||
#
|
||||
# FreeType 2 pcf driver compilation rules for VMS
|
||||
#
|
||||
|
||||
|
||||
# Copyright (C) 2001 by
|
||||
# Francesco Zappa Nardelli
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
|
||||
CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.pcf])
|
||||
|
||||
OBJS=pcf.obj
|
||||
|
||||
all : $(OBJS)
|
||||
library [--.lib]freetype.olb $(OBJS)
|
||||
|
||||
# EOF
|
|
@ -1,234 +0,0 @@
|
|||
/* pcf.h
|
||||
|
||||
FreeType font driver for pcf fonts
|
||||
|
||||
Copyright (C) 2000-2001 by
|
||||
Francesco Zappa Nardelli
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __PCF_H__
|
||||
#define __PCF_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DRIVER_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
typedef struct PCF_TableRec_
|
||||
{
|
||||
FT_ULong type;
|
||||
FT_ULong format;
|
||||
FT_ULong size;
|
||||
FT_ULong offset;
|
||||
|
||||
} PCF_TableRec, *PCF_Table;
|
||||
|
||||
|
||||
typedef struct PCF_TocRec_
|
||||
{
|
||||
FT_ULong version;
|
||||
FT_ULong count;
|
||||
PCF_Table tables;
|
||||
|
||||
} PCF_TocRec, *PCF_Toc;
|
||||
|
||||
|
||||
typedef struct PCF_ParseProperty_
|
||||
{
|
||||
FT_Long name;
|
||||
FT_Byte isString;
|
||||
FT_Long value;
|
||||
|
||||
} PCF_ParsePropertyRec, *PCF_ParseProperty;
|
||||
|
||||
|
||||
typedef struct PCF_Property_
|
||||
{
|
||||
FT_String* name;
|
||||
FT_Byte isString;
|
||||
|
||||
union
|
||||
{
|
||||
FT_String* atom;
|
||||
FT_Long integer;
|
||||
FT_ULong cardinal;
|
||||
|
||||
} value;
|
||||
|
||||
} PCF_PropertyRec, *PCF_Property;
|
||||
|
||||
|
||||
typedef struct PCF_Compressed_Metric_
|
||||
{
|
||||
FT_Byte leftSideBearing;
|
||||
FT_Byte rightSideBearing;
|
||||
FT_Byte characterWidth;
|
||||
FT_Byte ascent;
|
||||
FT_Byte descent;
|
||||
|
||||
} PCF_Compressed_MetricRec, *PCF_Compressed_Metric;
|
||||
|
||||
|
||||
typedef struct PCF_Metric_
|
||||
{
|
||||
FT_Short leftSideBearing;
|
||||
FT_Short rightSideBearing;
|
||||
FT_Short characterWidth;
|
||||
FT_Short ascent;
|
||||
FT_Short descent;
|
||||
FT_Short attributes;
|
||||
FT_ULong bits;
|
||||
|
||||
} PCF_MetricRec, *PCF_Metric;
|
||||
|
||||
|
||||
typedef struct PCF_AccelRec_
|
||||
{
|
||||
FT_Byte noOverlap;
|
||||
FT_Byte constantMetrics;
|
||||
FT_Byte terminalFont;
|
||||
FT_Byte constantWidth;
|
||||
FT_Byte inkInside;
|
||||
FT_Byte inkMetrics;
|
||||
FT_Byte drawDirection;
|
||||
FT_Long fontAscent;
|
||||
FT_Long fontDescent;
|
||||
FT_Long maxOverlap;
|
||||
PCF_MetricRec minbounds;
|
||||
PCF_MetricRec maxbounds;
|
||||
PCF_MetricRec ink_minbounds;
|
||||
PCF_MetricRec ink_maxbounds;
|
||||
|
||||
} PCF_AccelRec, *PCF_Accel;
|
||||
|
||||
|
||||
typedef struct PCD_Encoding_
|
||||
{
|
||||
FT_Long enc;
|
||||
FT_Short glyph;
|
||||
|
||||
} PCF_EncodingRec, *PCF_Encoding;
|
||||
|
||||
|
||||
typedef struct PCF_FaceRec_
|
||||
{
|
||||
FT_FaceRec root;
|
||||
|
||||
char* charset_encoding;
|
||||
char* charset_registry;
|
||||
|
||||
PCF_TocRec toc;
|
||||
PCF_AccelRec accel;
|
||||
|
||||
int nprops;
|
||||
PCF_Property properties;
|
||||
|
||||
FT_Long nmetrics;
|
||||
PCF_Metric metrics;
|
||||
FT_Long nencodings;
|
||||
PCF_Encoding encodings;
|
||||
|
||||
FT_Short defaultChar;
|
||||
|
||||
FT_ULong bitmapsFormat;
|
||||
|
||||
FT_CharMap charmap_handle;
|
||||
FT_CharMapRec charmap; /* a single charmap per face */
|
||||
|
||||
} PCF_FaceRec, *PCF_Face;
|
||||
|
||||
|
||||
/* macros for pcf font format */
|
||||
|
||||
#define LSBFirst 0
|
||||
#define MSBFirst 1
|
||||
|
||||
#define PCF_FILE_VERSION ( ( 'p' << 24 ) | \
|
||||
( 'c' << 16 ) | \
|
||||
( 'f' << 8 ) | 1 )
|
||||
#define PCF_FORMAT_MASK 0xFFFFFF00L
|
||||
|
||||
#define PCF_DEFAULT_FORMAT 0x00000000L
|
||||
#define PCF_INKBOUNDS 0x00000200L
|
||||
#define PCF_ACCEL_W_INKBOUNDS 0x00000100L
|
||||
#define PCF_COMPRESSED_METRICS 0x00000100L
|
||||
|
||||
#define PCF_FORMAT_MATCH( a, b ) \
|
||||
( ( (a) & PCF_FORMAT_MASK ) == ( (b) & PCF_FORMAT_MASK ) )
|
||||
|
||||
#define PCF_GLYPH_PAD_MASK ( 3 << 0 )
|
||||
#define PCF_BYTE_MASK ( 1 << 2 )
|
||||
#define PCF_BIT_MASK ( 1 << 3 )
|
||||
#define PCF_SCAN_UNIT_MASK ( 3 << 4 )
|
||||
|
||||
#define PCF_BYTE_ORDER( f ) \
|
||||
( ( (f) & PCF_BYTE_MASK ) ? MSBFirst : LSBFirst )
|
||||
#define PCF_BIT_ORDER( f ) \
|
||||
( ( (f) & PCF_BIT_MASK ) ? MSBFirst : LSBFirst )
|
||||
#define PCF_GLYPH_PAD_INDEX( f ) \
|
||||
( (f) & PCF_GLYPH_PAD_MASK )
|
||||
#define PCF_GLYPH_PAD( f ) \
|
||||
( 1 << PCF_GLYPH_PAD_INDEX( f ) )
|
||||
#define PCF_SCAN_UNIT_INDEX( f ) \
|
||||
( ( (f) & PCF_SCAN_UNIT_MASK ) >> 4 )
|
||||
#define PCF_SCAN_UNIT( f ) \
|
||||
( 1 << PCF_SCAN_UNIT_INDEX( f ) )
|
||||
#define PCF_FORMAT_BITS( f ) \
|
||||
( (f) & ( PCF_GLYPH_PAD_MASK | \
|
||||
PCF_BYTE_MASK | \
|
||||
PCF_BIT_MASK | \
|
||||
PCF_SCAN_UNIT_MASK ) )
|
||||
|
||||
#define PCF_SIZE_TO_INDEX( s ) ( (s) == 4 ? 2 : (s) == 2 ? 1 : 0 )
|
||||
#define PCF_INDEX_TO_SIZE( b ) ( 1 << b )
|
||||
|
||||
#define PCF_FORMAT( bit, byte, glyph, scan ) \
|
||||
( ( PCF_SIZE_TO_INDEX( scan ) << 4 ) | \
|
||||
( ( (bit) == MSBFirst ? 1 : 0 ) << 3 ) | \
|
||||
( ( (byte) == MSBFirst ? 1 : 0 ) << 2 ) | \
|
||||
( PCF_SIZE_TO_INDEX( glyph ) << 0 ) )
|
||||
|
||||
#define PCF_PROPERTIES ( 1 << 0 )
|
||||
#define PCF_ACCELERATORS ( 1 << 1 )
|
||||
#define PCF_METRICS ( 1 << 2 )
|
||||
#define PCF_BITMAPS ( 1 << 3 )
|
||||
#define PCF_INK_METRICS ( 1 << 4 )
|
||||
#define PCF_BDF_ENCODINGS ( 1 << 5 )
|
||||
#define PCF_SWIDTHS ( 1 << 6 )
|
||||
#define PCF_GLYPH_NAMES ( 1 << 7 )
|
||||
#define PCF_BDF_ACCELERATORS ( 1 << 8 )
|
||||
|
||||
#define GLYPHPADOPTIONS 4 /* I'm not sure about this */
|
||||
|
||||
FT_LOCAL FT_Error
|
||||
pcf_load_font( FT_Stream,
|
||||
PCF_Face );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __PCF_H__ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,402 +0,0 @@
|
|||
/* pcfdriver.c
|
||||
|
||||
FreeType font driver for pcf files
|
||||
|
||||
Copyright (C) 2000-2001 by
|
||||
Francesco Zappa Nardelli
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
#include "pcf.h"
|
||||
#include "pcfdriver.h"
|
||||
#include "pcfutil.h"
|
||||
|
||||
#include "pcferror.h"
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_pcfdriver
|
||||
|
||||
|
||||
static FT_Error
|
||||
PCF_Face_Done( PCF_Face face )
|
||||
{
|
||||
FT_Memory memory = FT_FACE_MEMORY( face );
|
||||
|
||||
|
||||
FREE( face->encodings );
|
||||
FREE( face->metrics );
|
||||
|
||||
/* free properties */
|
||||
{
|
||||
PCF_Property prop = face->properties;
|
||||
FT_Int i;
|
||||
|
||||
for ( i = 0; i < face->nprops; i++ )
|
||||
{
|
||||
prop = &face->properties[i];
|
||||
|
||||
FREE( prop->name );
|
||||
if ( prop->isString )
|
||||
FREE( prop->value );
|
||||
}
|
||||
|
||||
FREE( face->properties );
|
||||
}
|
||||
|
||||
FREE( face->toc.tables );
|
||||
FREE( face->root.family_name );
|
||||
FREE( face->root.available_sizes );
|
||||
FREE( face->charset_encoding );
|
||||
FREE( face->charset_registry );
|
||||
|
||||
FT_TRACE4(( "DONE_FACE!!!\n" ));
|
||||
|
||||
return PCF_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
PCF_Face_Init( FT_Stream stream,
|
||||
PCF_Face face,
|
||||
FT_Int face_index,
|
||||
FT_Int num_params,
|
||||
FT_Parameter* params )
|
||||
{
|
||||
FT_Error error = PCF_Err_Ok;
|
||||
|
||||
FT_UNUSED( num_params );
|
||||
FT_UNUSED( params );
|
||||
FT_UNUSED( face_index );
|
||||
|
||||
|
||||
error = pcf_load_font( stream, face );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
|
||||
return PCF_Err_Ok;
|
||||
|
||||
Fail:
|
||||
FT_TRACE2(( "[not a valid PCF file]\n" ));
|
||||
PCF_Face_Done( face );
|
||||
|
||||
return PCF_Err_Unknown_File_Format; /* error */
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
PCF_Set_Pixel_Size( FT_Size size )
|
||||
{
|
||||
PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
|
||||
|
||||
|
||||
FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem,
|
||||
face->root.available_sizes->height ));
|
||||
|
||||
if ( size->metrics.y_ppem == face->root.available_sizes->height )
|
||||
{
|
||||
size->metrics.ascender = face->accel.fontAscent << 6;
|
||||
size->metrics.descender = face->accel.fontDescent * (-64);
|
||||
#if 0
|
||||
size->metrics.height = face->accel.maxbounds.ascent << 6;
|
||||
#endif
|
||||
size->metrics.height = size->metrics.ascender -
|
||||
size->metrics.descender;
|
||||
|
||||
size->metrics.max_advance = face->accel.maxbounds.characterWidth << 6;
|
||||
|
||||
return PCF_Err_Ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_TRACE4(( "size WRONG\n" ));
|
||||
return PCF_Err_Invalid_Pixel_Size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
PCF_Glyph_Load( FT_GlyphSlot slot,
|
||||
FT_Size size,
|
||||
FT_UInt glyph_index,
|
||||
FT_Int load_flags )
|
||||
{
|
||||
PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
|
||||
FT_Stream stream = face->root.stream;
|
||||
FT_Error error = PCF_Err_Ok;
|
||||
FT_Memory memory = FT_FACE(face)->memory;
|
||||
FT_Bitmap* bitmap = &slot->bitmap;
|
||||
PCF_Metric metric;
|
||||
int bytes;
|
||||
|
||||
|
||||
FT_UNUSED( load_flags );
|
||||
|
||||
|
||||
FT_TRACE4(( "load_glyph %d ---", glyph_index ));
|
||||
|
||||
if ( !face )
|
||||
{
|
||||
error = PCF_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
metric = face->metrics + glyph_index;
|
||||
|
||||
bitmap->rows = metric->ascent + metric->descent;
|
||||
bitmap->width = metric->rightSideBearing - metric->leftSideBearing;
|
||||
bitmap->num_grays = 1;
|
||||
bitmap->pixel_mode = ft_pixel_mode_mono;
|
||||
|
||||
FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n",
|
||||
PCF_BIT_ORDER( face->bitmapsFormat ),
|
||||
PCF_BYTE_ORDER( face->bitmapsFormat ),
|
||||
PCF_GLYPH_PAD( face->bitmapsFormat ) ));
|
||||
|
||||
switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
|
||||
{
|
||||
case 1:
|
||||
bitmap->pitch = ( bitmap->width + 7 ) >> 3;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
return PCF_Err_Invalid_File_Format;
|
||||
}
|
||||
|
||||
/* XXX: to do: are there cases that need repadding the bitmap? */
|
||||
bytes = bitmap->pitch * bitmap->rows;
|
||||
|
||||
if ( ALLOC( bitmap->buffer, bytes ) )
|
||||
goto Exit;
|
||||
|
||||
if ( FILE_Seek( metric->bits ) ||
|
||||
FILE_Read( bitmap->buffer, bytes ) )
|
||||
goto Exit;
|
||||
|
||||
if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
|
||||
BitOrderInvert( bitmap->buffer,bytes );
|
||||
|
||||
if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) !=
|
||||
PCF_BIT_ORDER( face->bitmapsFormat ) ) )
|
||||
{
|
||||
switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
TwoByteSwap( bitmap->buffer, bytes );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
FourByteSwap( bitmap->buffer, bytes );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
slot->bitmap_left = metric->leftSideBearing;
|
||||
slot->bitmap_top = metric->ascent;
|
||||
|
||||
slot->metrics.horiAdvance = metric->characterWidth << 6 ;
|
||||
slot->metrics.horiBearingX = metric->rightSideBearing << 6 ;
|
||||
slot->metrics.horiBearingY = metric->ascent << 6 ;
|
||||
slot->metrics.width = metric->characterWidth << 6 ;
|
||||
slot->metrics.height = bitmap->rows << 6;
|
||||
|
||||
slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16;
|
||||
slot->format = ft_glyph_format_bitmap;
|
||||
slot->flags = ft_glyph_own_bitmap;
|
||||
|
||||
FT_TRACE4(( " --- ok\n" ));
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_UInt
|
||||
PCF_Char_Get_Index( FT_CharMap charmap,
|
||||
FT_Long char_code )
|
||||
{
|
||||
PCF_Face face = (PCF_Face)charmap->face;
|
||||
PCF_Encoding en_table = face->encodings;
|
||||
int low, high, mid;
|
||||
|
||||
|
||||
FT_TRACE4(( "get_char_index %ld\n", char_code ));
|
||||
|
||||
low = 0;
|
||||
high = face->nencodings - 1;
|
||||
while ( low <= high )
|
||||
{
|
||||
mid = ( low + high ) / 2;
|
||||
if ( char_code < en_table[mid].enc )
|
||||
high = mid - 1;
|
||||
else if ( char_code > en_table[mid].enc )
|
||||
low = mid + 1;
|
||||
else
|
||||
return en_table[mid].glyph;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static FT_Long
|
||||
PCF_Char_Get_Next( FT_CharMap charmap,
|
||||
FT_Long char_code )
|
||||
{
|
||||
PCF_Face face = (PCF_Face)charmap->face;
|
||||
PCF_Encoding en_table = face->encodings;
|
||||
int low, high, mid;
|
||||
|
||||
|
||||
FT_TRACE4(( "get_next_char %ld\n", char_code ));
|
||||
|
||||
char_code++;
|
||||
low = 0;
|
||||
high = face->nencodings - 1;
|
||||
|
||||
while ( low <= high )
|
||||
{
|
||||
mid = ( low + high ) / 2;
|
||||
if ( char_code < en_table[mid].enc )
|
||||
high = mid - 1;
|
||||
else if ( char_code > en_table[mid].enc )
|
||||
low = mid + 1;
|
||||
else
|
||||
return char_code;
|
||||
}
|
||||
|
||||
if ( high < 0 )
|
||||
high = 0;
|
||||
|
||||
while ( high < face->nencodings )
|
||||
{
|
||||
if ( en_table[high].enc >= char_code )
|
||||
return en_table[high].enc;
|
||||
high++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FT_Driver_Class pcf_driver_class =
|
||||
{
|
||||
{
|
||||
ft_module_font_driver,
|
||||
sizeof ( FT_DriverRec ),
|
||||
|
||||
"pcf",
|
||||
0x10000L,
|
||||
0x20000L,
|
||||
|
||||
0,
|
||||
|
||||
(FT_Module_Constructor)0,
|
||||
(FT_Module_Destructor) 0,
|
||||
(FT_Module_Requester) 0
|
||||
},
|
||||
|
||||
sizeof( PCF_FaceRec ),
|
||||
sizeof( FT_SizeRec ),
|
||||
sizeof( FT_GlyphSlotRec ),
|
||||
|
||||
(FTDriver_initFace) PCF_Face_Init,
|
||||
(FTDriver_doneFace) PCF_Face_Done,
|
||||
(FTDriver_initSize) 0,
|
||||
(FTDriver_doneSize) 0,
|
||||
(FTDriver_initGlyphSlot)0,
|
||||
(FTDriver_doneGlyphSlot)0,
|
||||
|
||||
(FTDriver_setCharSizes) PCF_Set_Pixel_Size,
|
||||
(FTDriver_setPixelSizes)PCF_Set_Pixel_Size,
|
||||
|
||||
(FTDriver_loadGlyph) PCF_Glyph_Load,
|
||||
(FTDriver_getCharIndex) PCF_Char_Get_Index,
|
||||
|
||||
(FTDriver_getKerning) 0,
|
||||
(FTDriver_attachFile) 0,
|
||||
(FTDriver_getAdvances) 0,
|
||||
|
||||
(FTDriver_getNextChar) PCF_Char_Get_Next,
|
||||
};
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* getDriverClass */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* This function is used when compiling the TrueType driver as a */
|
||||
/* shared library (`.DLL' or `.so'). It will be used by the */
|
||||
/* high-level library of FreeType to retrieve the address of the */
|
||||
/* driver's generic interface. */
|
||||
/* */
|
||||
/* It shouldn't be implemented in a static build, as each driver must */
|
||||
/* have the same function as an exported entry point. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The address of the TrueType's driver generic interface. The */
|
||||
/* format-specific interface can then be retrieved through the method */
|
||||
/* interface->get_format_interface. */
|
||||
/* */
|
||||
FT_EXPORT_DEF( const FT_Driver_Class* )
|
||||
getDriverClass( void )
|
||||
{
|
||||
return &pcf_driver_class;
|
||||
}
|
||||
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,44 +0,0 @@
|
|||
/* pcfdriver.h
|
||||
|
||||
FreeType font driver for pcf fonts
|
||||
|
||||
Copyright 2000-2001 by
|
||||
Francesco Zappa Nardelli
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __PCFDRIVER_H__
|
||||
#define __PCFDRIVER_H__
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_DRIVER_H
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
FT_EXPORT_VAR( const FT_Driver_Class ) pcf_driver_class;
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __PCFDRIVER_H__ */
|
||||
|
||||
|
||||
/* END */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,80 +0,0 @@
|
|||
#
|
||||
# FreeType 2 pcf driver configuration rules
|
||||
#
|
||||
|
||||
|
||||
# Copyright (C) 2000 by
|
||||
# Francesco Zappa Nardelli
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
|
||||
# pcf driver directory
|
||||
#
|
||||
PCF_DIR := $(SRC_)pcf
|
||||
PCF_DIR_ := $(PCF_DIR)$(SEP)
|
||||
|
||||
|
||||
PCF_COMPILE := $(FT_COMPILE) $I$(PCF_DIR)
|
||||
|
||||
|
||||
# pcf driver sources (i.e., C files)
|
||||
#
|
||||
PCF_DRV_SRC := $(PCF_DIR_)pcfread.c \
|
||||
$(PCF_DIR_)pcfdriver.c \
|
||||
$(PCF_DIR_)pcfutil.c
|
||||
|
||||
# pcf driver headers
|
||||
#
|
||||
PCF_DRV_H := $(PCF_DIR_)pcf.h \
|
||||
$(PCF_DIR_)pcfdriver.h \
|
||||
$(PCF_DIR_)pcfutil.h \
|
||||
$(PCF_DIR_)pcferror.h
|
||||
|
||||
# pcf driver object(s)
|
||||
#
|
||||
# PCF_DRV_OBJ_M is used during `multi' builds
|
||||
# PCF_DRV_OBJ_S is used during `single' builds
|
||||
#
|
||||
PCF_DRV_OBJ_M := $(PCF_DRV_SRC:$(PCF_DIR_)%.c=$(OBJ_)%.$O)
|
||||
PCF_DRV_OBJ_S := $(OBJ_)pcf.$O
|
||||
|
||||
# Windows driver source file for single build
|
||||
#
|
||||
PCF_DRV_SRC_S := $(PCF_DIR_)pcf.c
|
||||
|
||||
|
||||
# pcf driver - single object
|
||||
#
|
||||
$(PCF_DRV_OBJ_S): $(PCF_DRV_SRC_S) $(PCF_DRV_SRC) $(FREETYPE_H) $(PCF_DRV_H)
|
||||
$(PCF_COMPILE) $T$@ $(PCF_DRV_SRC_S)
|
||||
|
||||
|
||||
# pcf driver - multiple objects
|
||||
#
|
||||
$(OBJ_)%.$O: $(PCF_DIR_)%.c $(FREETYPE_H) $(PCF_DRV_H)
|
||||
$(PCF_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
# update main driver object lists
|
||||
#
|
||||
DRV_OBJS_S += $(PCF_DRV_OBJ_S)
|
||||
DRV_OBJS_M += $(PCF_DRV_OBJ_M)
|
||||
|
||||
# EOF
|
|
@ -1,23 +0,0 @@
|
|||
# FreeType 2 src/psaux Jamfile (c) 2001 David Turner
|
||||
#
|
||||
|
||||
SubDir FT2_TOP src psaux ;
|
||||
|
||||
SubDirHdrs [ FT2_SubDir src psaux ] ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = psauxmod psobjs t1decode ;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = psaux ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/psaux Jamfile
|
|
@ -1,23 +0,0 @@
|
|||
#
|
||||
# FreeType 2 PSaux driver compilation rules for VMS
|
||||
#
|
||||
|
||||
|
||||
# Copyright 2001 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.
|
||||
|
||||
|
||||
CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.psaux])
|
||||
|
||||
OBJS=psaux.obj
|
||||
|
||||
all : $(OBJS)
|
||||
library [--.lib]freetype.olb $(OBJS)
|
||||
|
||||
# EOF
|
|
@ -1,27 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* psaux.c */
|
||||
/* */
|
||||
/* FreeType auxiliary PostScript driver component (body only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "psobjs.c"
|
||||
#include "psauxmod.c"
|
||||
#include "t1decode.c"
|
||||
|
||||
|
||||
/* END */
|
|
@ -1,105 +0,0 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* psauxmod.c */
|
||||
/* */
|
||||
/* FreeType auxiliary PostScript module implementation (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001 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. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "psauxmod.h"
|
||||
#include "psobjs.h"
|
||||
#include "t1decode.h"
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const PS_Table_Funcs ps_table_funcs =
|
||||
{
|
||||
PS_Table_New,
|
||||
PS_Table_Done,
|
||||
PS_Table_Add,
|
||||
PS_Table_Release
|
||||
};
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const T1_Parser_Funcs t1_parser_funcs =
|
||||
{
|
||||
T1_Init_Parser,
|
||||
T1_Done_Parser,
|
||||
T1_Skip_Spaces,
|
||||
T1_Skip_Alpha,
|
||||
T1_ToInt,
|
||||
T1_ToFixed,
|
||||
T1_ToCoordArray,
|
||||
T1_ToFixedArray,
|
||||
T1_ToToken,
|
||||
T1_ToTokenArray,
|
||||
T1_Load_Field,
|
||||
T1_Load_Field_Table
|
||||
};
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const T1_Builder_Funcs t1_builder_funcs =
|
||||
{
|
||||
T1_Builder_Init,
|
||||
T1_Builder_Done,
|
||||
T1_Builder_Check_Points,
|
||||
T1_Builder_Add_Point,
|
||||
T1_Builder_Add_Point1,
|
||||
T1_Builder_Add_Contour,
|
||||
T1_Builder_Start_Point,
|
||||
T1_Builder_Close_Contour
|
||||
};
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const T1_Decoder_Funcs t1_decoder_funcs =
|
||||
{
|
||||
T1_Decoder_Init,
|
||||
T1_Decoder_Done,
|
||||
T1_Decoder_Parse_Charstrings
|
||||
};
|
||||
|
||||
|
||||
static
|
||||
const PSAux_Interface psaux_interface =
|
||||
{
|
||||
&ps_table_funcs,
|
||||
&t1_parser_funcs,
|
||||
&t1_builder_funcs,
|
||||
&t1_decoder_funcs,
|
||||
|
||||
T1_Decrypt
|
||||
};
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FT_Module_Class psaux_module_class =
|
||||
{
|
||||
0,
|
||||
sizeof( FT_ModuleRec ),
|
||||
"psaux",
|
||||
0x10000L,
|
||||
0x20000L,
|
||||
|
||||
&psaux_interface, /* module-specific interface */
|
||||
|
||||
(FT_Module_Constructor)0,
|
||||
(FT_Module_Destructor) 0,
|
||||
(FT_Module_Requester) 0
|
||||
};
|
||||
|
||||
|
||||
/* END */
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче