Add freetype librairy on the project ...

Remove internal data in memory ==> deprecated with assets
Set an abstraction of the loading of the freetype texture ==> must be done to be supported in Android
Correction of the stream error that generate a segmentaion fault in the Android system
This commit is contained in:
Edouard Dupin 2012-01-25 18:36:51 +01:00
parent d8b9535016
commit d0f57d33a7
244 changed files with 111050 additions and 403 deletions

View File

@ -5,11 +5,13 @@ include $(CLEAR_VARS)
LOCAL_MODULE := etk
LOCAL_STATIC_LIBRARIES := libzip
# load the common sources file of the platform
include $(LOCAL_PATH)/file.mk
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_CFLAGS := -D__PLATFORM__Android \
-Wno-write-strings \
-DDATA_IN_APK \
@ -17,12 +19,10 @@ LOCAL_CFLAGS := -D__PLATFORM__Android \
# load the common sources file of the platform
include $(LOCAL_PATH)/file.mk
LOCAL_SRC_FILES := $(FILE_LIST)
#for freetype : https://github.com/cdave1/freetype2-android
# Ewol Test Software :
LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog -lz

View File

@ -28,9 +28,7 @@
#include <etk/File.h>
#include <unistd.h>
#ifdef DATA_INTERNAL_BINARY
# include <GeneratedData.h>
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
# include <stdio.h>
# include <zip/zip.h>
#endif
@ -118,10 +116,7 @@ const etk::File& etk::File::operator= (const etk::File &etkF )
TK_ERROR("Missing close the file : \"" << GetCompleateName() << "\"");
fClose();
}
#ifdef DATA_INTERNAL_BINARY
m_idInternal = etkF.m_idInternal;
m_readingOffset = 0;
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
m_idZipFile = etkF.m_idZipFile;
m_zipData = NULL;
m_zipDataSize = 0;
@ -199,11 +194,7 @@ etk::String baseFolderCache = "~/.tmp/cache/";
// for specific device contraint :
void etk::SetBaseFolderData(const char * folder)
{
#ifdef DATA_INTERNAL_BINARY
for(int32_t iii=0; iii<internalDataFilesSize; iii++) {
TK_DEBUG("Internal date : \"" << internalDataFiles[iii].filename << "\" size=" << internalDataFiles[iii].fileLenght);
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
baseFolderData = "assets/";
s_fileAPK = folder;
loadAPK(s_fileAPK.c_str());
@ -226,9 +217,7 @@ void etk::File::SetCompleateName(etk::String &newFilename, etk::FileType_te type
char buf[MAX_FILE_NAME];
memset(buf, 0, MAX_FILE_NAME);
char * ok;
#ifdef DATA_INTERNAL_BINARY
m_idInternal = -1;
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
m_idZipFile = -1;
m_zipData = NULL;
m_zipDataSize = 0;
@ -285,17 +274,7 @@ void etk::File::SetCompleateName(etk::String &newFilename, etk::FileType_te type
#if ETK_DEBUG_LEVEL > 2
mode = "FILE_TYPE_DATA";
#endif
#ifdef DATA_INTERNAL_BINARY
for(int32_t iii=0; iii<internalDataFilesSize; iii++) {
if (destFilename == internalDataFiles[iii].filename) {
m_idInternal = iii;
break;
}
}
if (-1 == m_idInternal) {
TK_ERROR("File Does not existed ... in memory : \"" << destFilename << "\"");
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
etk::String tmpFilename = baseFolderData + destFilename;
for (int iii=0; iii<s_APKnbFiles; iii++) {
const char* name = zip_get_name(s_APKArchive, iii, 0);
@ -487,14 +466,7 @@ bool etk::File::LoadDataZip(void)
int32_t etk::File::Size(void)
{
#ifdef DATA_INTERNAL_BINARY
if (etk::FILE_TYPE_DATA == m_type) {
if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) {
return internalDataFiles[m_idInternal].fileLenght;
}
return 0;
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
if (etk::FILE_TYPE_DATA == m_type) {
if (true == LoadDataZip()) {
return m_zipDataSize;
@ -520,14 +492,7 @@ int32_t etk::File::Size(void)
bool etk::File::Exist(void)
{
#ifdef DATA_INTERNAL_BINARY
if (etk::FILE_TYPE_DATA == m_type) {
if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) {
return true;
}
return false;
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
if (etk::FILE_TYPE_DATA == m_type) {
if (m_idZipFile >= -1 && m_idZipFile < s_APKnbFiles) {
return true;
@ -549,16 +514,7 @@ bool etk::File::Exist(void)
bool etk::File::fOpenRead(void)
{
#ifdef DATA_INTERNAL_BINARY
if (etk::FILE_TYPE_DATA == m_type) {
m_readingOffset = 0;
if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) {
TK_DEBUG("Open file : " << GetCompleateName() << " with size=" << internalDataFiles[m_idInternal].fileLenght << " Octets");
return true;
}
return false;
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
if (etk::FILE_TYPE_DATA == m_type) {
return LoadDataZip();
}
@ -578,12 +534,7 @@ bool etk::File::fOpenRead(void)
bool etk::File::fOpenWrite(void)
{
#ifdef DATA_INTERNAL_BINARY
if (etk::FILE_TYPE_DATA == m_type) {
m_readingOffset = 0;
return false;
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
if (etk::FILE_TYPE_DATA == m_type) {
return false;
}
@ -603,15 +554,7 @@ bool etk::File::fOpenWrite(void)
bool etk::File::fClose(void)
{
#ifdef DATA_INTERNAL_BINARY
if (etk::FILE_TYPE_DATA == m_type) {
m_readingOffset = 0;
if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) {
return true;
}
return false;
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
if (etk::FILE_TYPE_DATA == m_type) {
if (NULL == m_zipData) {
TK_CRITICAL("File Already closed : \"" << GetCompleateName() << "\"");
@ -636,38 +579,7 @@ bool etk::File::fClose(void)
char * etk::File::fGets(char * elementLine, int32_t maxData)
{
memset(elementLine, 0, maxData);
#ifdef DATA_INTERNAL_BINARY
char * element = elementLine;
if (etk::FILE_TYPE_DATA == m_type) {
if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) {
//char * tmpData = internalDataFiles[iii].data + m_readingOffset;
if (m_readingOffset>internalDataFiles[m_idInternal].fileLenght) {
element[0] = '\0';
return NULL;
}
while (internalDataFiles[m_idInternal].data[m_readingOffset] != '\0') {
if( internalDataFiles[m_idInternal].data[m_readingOffset] == '\n'
|| internalDataFiles[m_idInternal].data[m_readingOffset] == '\r')
{
*element = internalDataFiles[m_idInternal].data[m_readingOffset];
element++;
m_readingOffset++;
*element = '\0';
return elementLine;
}
*element = internalDataFiles[m_idInternal].data[m_readingOffset];
element++;
m_readingOffset++;
if (m_readingOffset>internalDataFiles[m_idInternal].fileLenght) {
*element = '\0';
return elementLine;
}
}
}
elementLine[0] = '\0';
return NULL;
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
char * element = elementLine;
if (etk::FILE_TYPE_DATA == m_type) {//char * tmpData = internalDataFiles[iii].data + m_readingOffset;
if (NULL == m_zipData) {
@ -704,21 +616,7 @@ char * etk::File::fGets(char * elementLine, int32_t maxData)
int32_t etk::File::fRead(void * data, int32_t blockSize, int32_t nbBlock)
{
#ifdef DATA_INTERNAL_BINARY
if (etk::FILE_TYPE_DATA == m_type) {
if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) {
int32_t dataToRead = blockSize * nbBlock;
if (dataToRead + m_readingOffset > internalDataFiles[m_idInternal].fileLenght) {
nbBlock = ((internalDataFiles[m_idInternal].fileLenght - m_readingOffset) / blockSize);
dataToRead = blockSize * nbBlock;
}
memcpy(data, &internalDataFiles[m_idInternal].data[m_readingOffset], dataToRead);
m_readingOffset +=dataToRead;
return nbBlock;
}
return 0;
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
if (etk::FILE_TYPE_DATA == m_type) {
if (NULL == m_zipData) {
((char*)data)[0] = '\0';
@ -739,12 +637,7 @@ int32_t etk::File::fRead(void * data, int32_t blockSize, int32_t nbBlock)
int32_t etk::File::fWrite(void * data, int32_t blockSize, int32_t nbBlock)
{
#ifdef DATA_INTERNAL_BINARY
if (etk::FILE_TYPE_DATA == m_type) {
TK_CRITICAL("Can not write on data inside memory : \"" << GetCompleateName() << "\"");
return 0;
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
if (etk::FILE_TYPE_DATA == m_type) {
TK_CRITICAL("Can not write on data inside APK : \"" << GetCompleateName() << "\"");
return 0;
@ -756,33 +649,7 @@ int32_t etk::File::fWrite(void * data, int32_t blockSize, int32_t nbBlock)
bool etk::File::fSeek(long int offset, int origin)
{
#ifdef DATA_INTERNAL_BINARY
if (etk::FILE_TYPE_DATA == m_type) {
if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) {
int32_t positionEnd = 0;
switch(origin) {
case SEEK_END:
positionEnd = internalDataFiles[m_idInternal].fileLenght;
break;
case SEEK_CUR:
positionEnd = m_readingOffset;
break;
default:
positionEnd = 0;
break;
}
positionEnd += offset;
if (positionEnd < 0) {
positionEnd = 0;
} else if (positionEnd > internalDataFiles[m_idInternal].fileLenght) {
positionEnd = internalDataFiles[m_idInternal].fileLenght;
}
m_readingOffset = positionEnd;
return true;
}
return false;
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
if (etk::FILE_TYPE_DATA == m_type) {
if (NULL == m_zipData) {
return false;
@ -820,13 +687,7 @@ bool etk::File::fSeek(long int offset, int origin)
char * etk::File::GetDirectPointer(void)
{
#ifdef DATA_INTERNAL_BINARY
if (etk::FILE_TYPE_DATA == m_type) {
if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) {
return (char*)internalDataFiles[m_idInternal].data;
}
}
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
if (etk::FILE_TYPE_DATA == m_type) {
if (NULL == m_zipData) {
return NULL;

View File

@ -94,10 +94,7 @@ namespace etk
private :
etk::FileType_te m_type;
FILE * m_PointerFile;
#ifdef DATA_INTERNAL_BINARY
int32_t m_idInternal;
int32_t m_readingOffset;
#elif defined(DATA_IN_APK)
#if defined(DATA_IN_APK)
bool LoadDataZip(void);
int32_t m_idZipFile;
char * m_zipData;

View File

@ -462,8 +462,8 @@ template<class CLASS_TYPE> class RegExpNodeDigit : public RegExpNode<CLASS_TYPE>
for (j=0; j<RegExpNode<CLASS_TYPE>::m_multipleMax && tmpFind ==true && j < lenMax; j++) {
char tmpVal = data[currentPos+j];
//TK_DEBUG("compare : " << tmpVal);
if( '0' <= tmpVal
&& '9' >= tmpVal)
if( '0' <= tmpVal
&& '9' >= tmpVal)
{
//TK_DEBUG("find ++");
findLen += 1;
@ -2011,15 +2011,15 @@ template<class CLASS_TYPE> class RegExp {
case REGEXP_OPCODE_BRACKET_IN: find = (char*)"["; break;
case REGEXP_OPCODE_BRACE_IN: find = (char*)"{"; break;
case REGEXP_OPCODE_PTHESE_OUT: find = (char*)")"; break;
case REGEXP_OPCODE_BRACKET_OUT: find = (char*)"]"; break;
case REGEXP_OPCODE_BRACKET_OUT: find = (char*)"]"; break;
case REGEXP_OPCODE_BRACE_OUT: find = (char*)"}"; break;
case REGEXP_OPCODE_STAR: find = (char*)"*"; break;
case REGEXP_OPCODE_DOT: find = (char*)"."; break;
case REGEXP_OPCODE_DOT: find = (char*)"."; break;
case REGEXP_OPCODE_QUESTION: find = (char*)"?"; break;
case REGEXP_OPCODE_PLUS: find = (char*)"+"; break;
case REGEXP_OPCODE_PIPE: find = (char*)"|"; break;
case REGEXP_OPCODE_START_OF_LINE: find = (char*)"^"; break;
case REGEXP_OPCODE_END_OF_LINE: find = (char*)"$"; break;
case REGEXP_OPCODE_END_OF_LINE: find = (char*)"$"; break;
case REGEXP_OPCODE_DIGIT: find = (char*)"\\d"; break;
case REGEXP_OPCODE_DIGIT_NOT: find = (char*)"\\D"; break;
case REGEXP_OPCODE_LETTER: find = (char*)"\\l"; break;
@ -2028,10 +2028,11 @@ template<class CLASS_TYPE> class RegExp {
case REGEXP_OPCODE_SPACE_NOT: find = (char*)"\\S"; break;
case REGEXP_OPCODE_WORD: find = (char*)"\\w"; break;
case REGEXP_OPCODE_WORD_NOT: find = (char*)"\\W"; break;
case REGEXP_OPCODE_NO_CHAR: find = (char*)"\\@"; break;
default: break;
case REGEXP_OPCODE_NO_CHAR: find = (char*)"\\@"; break;
default: break;
}
if (NULL != find) {
(void)input;
TK_ERROR("can not have : '" << find << "' inside " << input << " element");
return false;
}

View File

@ -37,6 +37,9 @@
# define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "====> EWOL", __VA_ARGS__))
#endif
#define MAX_LOG_SIZE (16000)
#define MAX_LOG_SIZE_TMP (16000)
namespace etk{
class CEndl{};
class CHex{};
@ -44,112 +47,66 @@ namespace etk{
private:
bool hex;
public:
#if defined(__PLATFORM__Android)
private:
char m_tmpChar[2048];
char m_tmpChar[MAX_LOG_SIZE+1];
char tmp[MAX_LOG_SIZE_TMP];
public:
CCout(){
hex=false;
memset(m_tmpChar, 0, 2048*sizeof(char));
memset(m_tmpChar, 0, (MAX_LOG_SIZE+1)*sizeof(char));
};
~CCout() { };
CCout& operator << (int t) {
char tmp[256];
sprintf(tmp,"%d", t);
strcat(m_tmpChar, tmp);
snprintf(tmp, MAX_LOG_SIZE_TMP, "%d", t);
strncat(m_tmpChar, tmp, MAX_LOG_SIZE);
return *this;
}
CCout& operator << (unsigned int t) {
char tmp[256];
sprintf(tmp, "%d", t);
strcat(m_tmpChar, tmp);
snprintf(tmp, MAX_LOG_SIZE_TMP, "%d", t);
strncat(m_tmpChar, tmp, MAX_LOG_SIZE);
return *this;
}
CCout& operator << (long t) {
char tmp[256];
sprintf(tmp, "%ld", t);
strcat(m_tmpChar, tmp);
snprintf(tmp, MAX_LOG_SIZE_TMP, "%ld", t);
strncat(m_tmpChar, tmp, MAX_LOG_SIZE);
return *this;
}
CCout& operator << (double t) {
char tmp[256];
sprintf(tmp, "%f", t);
strcat(m_tmpChar, tmp);
snprintf(tmp, MAX_LOG_SIZE_TMP, "%f", t);
strncat(m_tmpChar, tmp, MAX_LOG_SIZE);
return *this;
}
CCout& operator << (float t) {
char tmp[256];
sprintf(tmp, "%f", t);
strcat(m_tmpChar, tmp);
snprintf(tmp, MAX_LOG_SIZE_TMP, "%f", t);
strncat(m_tmpChar, tmp, MAX_LOG_SIZE);
return *this;
}
CCout& operator << (char * t) {
char tmp[256];
sprintf(tmp, "%s", t);
strcat(m_tmpChar, tmp);
snprintf(tmp, MAX_LOG_SIZE_TMP, "%s", t);
strncat(m_tmpChar, tmp, MAX_LOG_SIZE);
return *this;
}
CCout& operator << (const char * t) {
char tmp[256];
sprintf(tmp, "%s", t);
strcat(m_tmpChar, tmp);
snprintf(tmp, MAX_LOG_SIZE_TMP, "%s", t);
strncat(m_tmpChar, tmp, MAX_LOG_SIZE);
return *this;
}
CCout& operator << (char t) {
char tmp[256];
sprintf(tmp, "%c", t);
strcat(m_tmpChar, tmp);
snprintf(tmp, MAX_LOG_SIZE_TMP, "%c", t);
strncat(m_tmpChar, tmp, MAX_LOG_SIZE);
return *this;
}
CCout& operator << (etk::CEndl t) {
strcat(m_tmpChar, "\n");
strncat(m_tmpChar, "\n", MAX_LOG_SIZE);
m_tmpChar[MAX_LOG_SIZE] = '\0';
#if defined(__PLATFORM__Android)
LOGI("%s", m_tmpChar);
memset(m_tmpChar, 0, 2048*sizeof(char));
return *this;
}
#else
CCout(){
hex=false;
};
~CCout() { };
CCout& operator << (int t) {
printf("%d", t);
return *this;
}
CCout& operator << (unsigned int t) {
printf("%d", t);
return *this;
}
CCout& operator << (long t) {
printf("%ld", t);
return *this;
}
CCout& operator << (double t) {
printf("%f", t);
return *this;
}
CCout& operator << (float t) {
printf("%f", t);
return *this;
}
CCout& operator << (char * t) {
printf("%s", t);
return *this;
}
CCout& operator << (const char * t) {
printf("%s", t);
return *this;
}
CCout& operator << (char t) {
printf("%c", t);
return *this;
}
CCout& operator << (etk::CEndl t) {
printf("\n");
return *this;
}
printf("%s", m_tmpChar);
#endif
memset(m_tmpChar, 0, (MAX_LOG_SIZE+1)*sizeof(char));
return *this;
}
};
extern etk::CCout cout;
extern etk::CEndl endl;

View File

@ -3,7 +3,7 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ewol
LOCAL_STATIC_LIBRARIES := libetk libtinyxml libzip libpng
LOCAL_STATIC_LIBRARIES := libetk libtinyxml libzip libpng libfreetype
LOCAL_C_INCLUDES := $(LOCAL_PATH)
@ -16,6 +16,7 @@ LOCAL_CFLAGS := -D__PLATFORM__Android \
-DEWOL_DEBUG_LEVEL=3 \
-DEWOL_VERSION_TAG_NAME="\"UNKNOW-debug\"" \
-DVERSION_BUILD_TIME="\"pasd_heure\"" \
-DEWOL_USE_FREE_TYPE \
-DDATA_IN_APK \
# load the common sources file of the platform

View File

@ -3,12 +3,12 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ewol
LOCAL_STATIC_LIBRARIES := etk tinyxml libzip libpng
LOCAL_STATIC_LIBRARIES := etk libfreetype tinyxml libzip libpng
LOCAL_C_INCLUDES := -I$(LOCAL_PATH)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_LDLIBS := -lGL -lGLU -lz -lX11 -lXxf86vm `pkg-config --libs freetype2`
LOCAL_EXPORT_LDLIBS := -lGL -lGLU -lz -lX11 -lXxf86vm
LOCAL_CFLAGS := -D__PLATFORM__Linux \
-Wno-write-strings \

View File

@ -28,12 +28,9 @@
#include <etk/VectorType.h>
#include <ewol/importgl.h>
#if defined(__PLATFORM__Linux)
# include <ft2build.h>
#else
# include <freetype/ft2build.h>
#endif
extern "C" {
#include <freetype/ft2build.h>
}
#include FT_FREETYPE_H
#undef __class__
@ -165,11 +162,13 @@ class FTFontInternal
} else {
EWOL_DEBUG(" flags = FT_FACE_FLAG_CID_KEYED (disable)");
}
/*
if ((FT_FACE_FLAG_TRICKY & m_fftFace->face_flags) != 0) {
EWOL_INFO(" flags = FT_FACE_FLAG_TRICKY (enable)");
} else {
EWOL_DEBUG(" flags = FT_FACE_FLAG_TRICKY (disable)");
}
*/
EWOL_INFO(" unit per EM = " << m_fftFace->units_per_EM);
EWOL_INFO(" num of fixed sizes = " << m_fftFace->num_fixed_sizes);
//EWOL_INFO(" Availlable sizes = " << (int)m_fftFace->available_sizes);
@ -183,35 +182,31 @@ class FTFontInternal
m_fileName = fontFileName;
m_FileBuffer = NULL;
m_FileSize = 0;
#if 0
int32_t error = FT_New_Face( library, m_fileName.GetCompleateName().c_str(), 0, &m_fftFace );
#else
if (false == m_fileName.Exist()) {
EWOL_ERROR("File Does not exist : " << m_fileName);
return;
}
m_FileSize = m_fileName.Size();
if (0==m_FileSize) {
EWOL_ERROR("This file is empty : " << m_fileName);
return;
}
if (false == m_fileName.fOpenRead()) {
EWOL_ERROR("Can not open the file : " << m_fileName);
return;
}
// allocate data
m_FileBuffer = new FT_Byte[m_FileSize];
if (NULL == m_FileBuffer) {
EWOL_ERROR("Error Memory allocation size=" << m_FileSize);
return;
}
// load data from the file :
m_fileName.fRead(m_FileBuffer, 1, m_FileSize);
// close the file:
m_fileName.fClose();
// load Face ...
int32_t error = FT_New_Memory_Face( library, m_FileBuffer, m_FileSize, 0, &m_fftFace );
#endif
if (false == m_fileName.Exist()) {
EWOL_ERROR("File Does not exist : " << m_fileName);
return;
}
m_FileSize = m_fileName.Size();
if (0==m_FileSize) {
EWOL_ERROR("This file is empty : " << m_fileName);
return;
}
if (false == m_fileName.fOpenRead()) {
EWOL_ERROR("Can not open the file : " << m_fileName);
return;
}
// allocate data
m_FileBuffer = new FT_Byte[m_FileSize];
if (NULL == m_FileBuffer) {
EWOL_ERROR("Error Memory allocation size=" << m_FileSize);
return;
}
// load data from the file :
m_fileName.fRead(m_FileBuffer, 1, m_FileSize);
// close the file:
m_fileName.fClose();
// load Face ...
int32_t error = FT_New_Memory_Face( library, m_FileBuffer, m_FileSize, 0, &m_fftFace );
if( FT_Err_Unknown_File_Format == error) {
EWOL_ERROR("... the font file could be opened and read, but it appears ... that its font format is unsupported");
} else if (0 != error) {
@ -232,7 +227,7 @@ class FTFontInternal
}
public:
etk::String GetFontName(void) {return m_fontName;};
bool GenerateBitmapFont(int32_t size, int32_t &height, int32_t textureId, etk::VectorType<freeTypeFontElement_ts> & listElement)
bool GenerateBitmapFont(int32_t size, int32_t &height, int32_t & textureId, etk::VectorType<freeTypeFontElement_ts> & listElement)
{
// 300dpi (hight quality) 96 dpi (normal quality)
int32_t fontQuality = 96;
@ -277,10 +272,17 @@ class FTFontInternal
}
int32_t nbLine = (nbElement / nbRaws) + 1;
int32_t textureHeight = nextP2(nbLine*glyphMaxHeight);
/*if (textureWidth < textureHeight) {
textureWidth = textureHeight;
}
if (textureWidth > textureHeight) {
textureHeight = textureWidth;
}*/
EWOL_DEBUG("Generate a text texture for char(" << nbRaws << "," << nbLine << ") with size=(" << textureWidth << "," << textureHeight << ")");
// Allocate Memory For The Texture Data.
GLubyte* expanded_data = new GLubyte[textureWidth * textureHeight];
int32_t byfferDataSize = textureWidth * textureHeight;
GLubyte* expanded_data = new GLubyte[byfferDataSize];
if (NULL == expanded_data) {
EWOL_ERROR("Allocation tmp data ERROR");
return false;
@ -360,17 +362,10 @@ class FTFontInternal
}
// update the Bitmap position drawing :
tmpRowStartPos += tmpWidth;
}
// Now We Just Setup Some Texture Parameters.
glBindTexture( GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA8, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, expanded_data );
// use the texture manager to have the texture availlable every restart of the screen
//textureId = LoadTexture(GL_TEXTURE_2D, 0, GL_ALPHA8, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, expanded_data, byfferDataSize * sizeof(GLubyte), "---FreeFont---" );
textureId = ewol::LoadTexture(GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, expanded_data, byfferDataSize * sizeof(GLubyte), "---FreeFont---" );
// With The Texture Created, We Don't Need The Expanded Data Anymore.
delete [] expanded_data;
@ -412,14 +407,12 @@ class FTFont{
freeTypeFontElement_ts tmpchar1;
tmpchar1.unicodeCharVal = 0;
m_elements.PushBack(tmpchar1);
for (int32_t iii=0x20; iii<127; iii++) {
for (int32_t iii=0x20; iii<0x7F; iii++) {
freeTypeFontElement_ts tmpchar;
tmpchar.unicodeCharVal = iii;
m_elements.PushBack(tmpchar);
}
m_size = size;
//generate font
glGenTextures(1, &m_textureId);
m_listLoadedTTFont[m_trueTypeFontId]->GenerateBitmapFont(m_size, m_lineHeight, m_textureId, m_elements);
}
~FTFont(void)
@ -446,7 +439,7 @@ class FTFont{
uint32_t GetOglId(void)
{
return m_textureId;
return ewol::GetTextureGLID(m_textureId);
};
int32_t GetSize(void)
@ -461,7 +454,7 @@ class FTFont{
private:
int32_t m_trueTypeFontId;
uint32_t m_textureId; // internal texture ID
int32_t m_textureId; // internal texture ID
int32_t m_size; // nb pixel height
int32_t m_lineHeight; // nb pixel height
int32_t m_interline; // nb pixel between 2 lines
@ -547,20 +540,6 @@ int32_t ewol::DrawText(int32_t fontID,
etk::VectorType<coord2D_ts> & coord,
etk::VectorType<texCoord_ts> & coordTex)
{
// TODO : This code des not work, why ????
/*
int32_t tmpstringLen = strlen(utf8String);
int32_t * tmpUnicodeString = new int32_t(tmpstringLen+1);
// TODO : generate a better convertor...
for (int32_t iii=0; iii<tmpstringLen; iii++) {
tmpUnicodeString[iii] = utf8String[iii];
}
tmpUnicodeString[tmpstringLen] = 0;
// unicode display ...
//DrawText(fontID, drawPosition, tmpUnicodeString, fontTextureId, coord, coordTex);
// clean temporary data ..
delete [] tmpUnicodeString;
*/
if(fontID>=m_listLoadedFont.Size() || fontID < 0) {
EWOL_WARNING("try to display text with an fontID that does not existed " << fontID);
return 0;
@ -569,12 +548,11 @@ int32_t ewol::DrawText(int32_t fontID,
char * tmpVal = (char*)utf8String;
fontTextureId = m_listLoadedFont[fontID]->GetOglId();
int32_t size = m_listLoadedFont[fontID]->GetHeight();
int32_t fontSize = m_listLoadedFont[fontID]->GetSize();
etkFloat_t posDrawX = drawPosition.x;
while(*tmpVal != 0) {
int32_t tmpChar = *tmpVal++;
uint32_t tmpChar = *tmpVal++;
int32_t charIndex;
if (tmpChar >= 0x80) {
charIndex = 0;
@ -689,13 +667,12 @@ int32_t ewol::DrawText(int32_t fontID,
uniChar_t * tmpVal = (uniChar_t *)unicodeString;
fontTextureId = m_listLoadedFont[fontID]->GetOglId();
int32_t size = m_listLoadedFont[fontID]->GetHeight();
int32_t fontSize = m_listLoadedFont[fontID]->GetSize();
etkFloat_t posDrawX = textPos.x;
while(*tmpVal != 0) {
int32_t tmpChar = *tmpVal++;
uint32_t tmpChar = *tmpVal++;
int32_t charIndex;
if (tmpChar >= 0x80) {
charIndex = 0;
@ -845,7 +822,7 @@ int32_t ewol::GetWidth(int32_t fontID, const uniChar_t * unicodeString)
etkFloat_t posDrawX = 0.0;
while(*tmpVal != 0) {
int32_t tmpChar = *tmpVal++;
uint32_t tmpChar = *tmpVal++;
int32_t charIndex;
if (tmpChar >= 0x80) {
charIndex = 0;
@ -880,7 +857,7 @@ int32_t ewol::GetWidth(int32_t fontID, const char * utf8String)
etkFloat_t posDrawX = 0.0;
while(*tmpVal != 0) {
int32_t tmpChar = *tmpVal++;
uint32_t tmpChar = *tmpVal++;
int32_t charIndex;
if (tmpChar >= 0x80) {
charIndex = 0;

View File

@ -311,14 +311,29 @@ class Bitmap
class LoadedTexture
{
public:
etk::File m_filename;
int32_t m_nbTimeLoaded;
int32_t m_imageSize; // must be x=y ...
uint32_t m_openGlTextureID;
Bitmap* m_imageData;
bool m_loaded;
etk::String m_filename;
int32_t m_nbTimeLoaded;
// openGl configuration :
uint32_t m_openGlTextureID;
int32_t m_target;
int32_t m_level;
int32_t m_internalFormat;
int32_t m_width;
int32_t m_height;
int32_t m_border;
int32_t m_format;
int32_t m_type;
char* m_data;
int32_t m_nbBytes;
bool m_loaded;
};
etk::VectorType<LoadedTexture*> listLoadedTexture;
static bool OGLContextLoaded=false;
@ -329,54 +344,133 @@ static bool OGLContextLoaded=false;
void ewol::TextureOGLContext(bool enable)
{
if (OGLContextLoaded != enable) {
EWOL_INFO("Change Open-GL context property : old=" << OGLContextLoaded << " new=" << enable);
OGLContextLoaded = enable;
if (true == OGLContextLoaded) {
EWOL_WARNING("POST loading the Texture");
EWOL_INFO(" ==> Set all Texture in openGL memory nb=" << listLoadedTexture.Size());
for (int32_t iii=0; iii < listLoadedTexture.Size(); iii++) {
GLuint textureid;
glGenTextures(1, &textureid);
glBindTexture(GL_TEXTURE_2D, textureid);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//--- mode nearest
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//#ifdef __PLATFORM__Linux
//--- Mode linear
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//#endif
EWOL_WARNING("Set in OpenGl texture =" << listLoadedTexture[iii]->m_imageData->Width()
<< "px different of height=" << listLoadedTexture[iii]->m_imageData->Height()
<< "px in file:" << listLoadedTexture[iii]->m_filename << " in id OGL : " << textureid);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
listLoadedTexture[iii]->m_imageData->Width(),
listLoadedTexture[iii]->m_imageData->Height(),
0, GL_RGBA, GL_UNSIGNED_BYTE,
listLoadedTexture[iii]->m_imageData->Data());
listLoadedTexture[iii]->m_openGlTextureID = textureid;
listLoadedTexture[iii]->m_loaded = true;
if (NULL != listLoadedTexture[iii]->m_data) {
GLuint textureid;
glGenTextures(1, &textureid);
glBindTexture(listLoadedTexture[iii]->m_target, textureid);
//glTexParameteri(tmpTex->m_target, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(tmpTex->m_target, GL_TEXTURE_WRAP_T, GL_REPEAT);
//--- mode nearest
//glTexParameteri(tmpTex->m_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//glTexParameteri(tmpTex->m_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//--- Mode linear
glTexParameteri(listLoadedTexture[iii]->m_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(listLoadedTexture[iii]->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
EWOL_INFO(" [" << iii << "] texture =(" << listLoadedTexture[iii]->m_width << "px," <<
listLoadedTexture[iii]->m_height << "px) in file:" <<
listLoadedTexture[iii]->m_filename << " OGl_Id=" <<textureid);
glTexImage2D(listLoadedTexture[iii]->m_target,
listLoadedTexture[iii]->m_level,
listLoadedTexture[iii]->m_internalFormat,
listLoadedTexture[iii]->m_width,
listLoadedTexture[iii]->m_height,
listLoadedTexture[iii]->m_border,
listLoadedTexture[iii]->m_format,
listLoadedTexture[iii]->m_type,
listLoadedTexture[iii]->m_data);
listLoadedTexture[iii]->m_openGlTextureID = textureid;
listLoadedTexture[iii]->m_loaded = true;
} else {
EWOL_ERROR("Can not load texture with no data ...");
}
}
ewol::ForceRedrawAll();
} else {
EWOL_INFO(" ==> UnSet all Texture in openGL memory nb=" << listLoadedTexture.Size());
for (int32_t iii=0; iii < listLoadedTexture.Size(); iii++) {
EWOL_DEBUG("unlink openGL texture ID=" << iii << " file:" << listLoadedTexture[iii]->m_filename);
glDeleteTextures(1,&listLoadedTexture[iii]->m_openGlTextureID);
EWOL_DEBUG(" [" << iii << "] file:" << listLoadedTexture[iii]->m_filename);
glDeleteTextures(1, &listLoadedTexture[iii]->m_openGlTextureID);
listLoadedTexture[iii]->m_loaded = false;
listLoadedTexture[iii]->m_openGlTextureID = -1;
}
}
EWOL_INFO(" *** END ***");
}
}
int32_t ewol::LoadTexture(int32_t target,
int32_t level,
int32_t internalFormat,
int32_t width,
int32_t height,
int32_t border,
int32_t format,
int32_t type,
const void* data,
int32_t nbBytes,
etk::String filename)
{
LoadedTexture *tmpTex = new LoadedTexture();
int32_t outTextureID = -1;
if (NULL == tmpTex){
EWOL_ERROR("Texture : Allocation ERROR... " << filename);
return -1;
}
tmpTex->m_filename = filename;
tmpTex->m_nbTimeLoaded = 1;
tmpTex->m_openGlTextureID = -1;
tmpTex->m_target = target;
tmpTex->m_level = level;
tmpTex->m_internalFormat = internalFormat;
tmpTex->m_width = width;
tmpTex->m_height = height;
tmpTex->m_border = border;
tmpTex->m_format = format;
tmpTex->m_type = type;
tmpTex->m_nbBytes = nbBytes;
tmpTex->m_data = new char[tmpTex->m_nbBytes+4096];
tmpTex->m_loaded = false;
if (NULL == tmpTex->m_data) {
EWOL_ERROR("Texture : Data Allocation ERROR... " << filename);
return -1;
}
memcpy(tmpTex->m_data, data, sizeof(char) * tmpTex->m_nbBytes);
if (true == OGLContextLoaded) {
uint32_t textureid = -1;
glGenTextures(1, &textureid);
glBindTexture(tmpTex->m_target, textureid);
//glTexParameteri(tmpTex->m_target, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(tmpTex->m_target, GL_TEXTURE_WRAP_T, GL_REPEAT);
//--- mode nearest
//glTexParameteri(tmpTex->m_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//glTexParameteri(tmpTex->m_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//--- Mode linear
glTexParameteri(tmpTex->m_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(tmpTex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
EWOL_INFO("Set in OpenGl texture =" << tmpTex->m_width << "px different of height=" << tmpTex->m_height << "px in file:" << filename << " in id OGL : " <<textureid);
glTexImage2D(tmpTex->m_target,
tmpTex->m_level,
tmpTex->m_internalFormat,
tmpTex->m_width,
tmpTex->m_height,
tmpTex->m_border,
tmpTex->m_format,
tmpTex->m_type,
tmpTex->m_data);
tmpTex->m_openGlTextureID = textureid;
tmpTex->m_loaded = true;
}
listLoadedTexture.PushBack(tmpTex);
outTextureID = listLoadedTexture.Size()-1;
return outTextureID;
}
int32_t ewol::LoadTexture(etk::File fileName)
{
int32_t outTextureID = -1;
if (listLoadedTexture.Size()!=0) {
for (int32_t iii=0; iii<listLoadedTexture.Size(); iii++) {
if (listLoadedTexture[iii]->m_filename == fileName) {
if (listLoadedTexture[iii]->m_filename == fileName.GetCompleateName()) {
listLoadedTexture[iii]->m_nbTimeLoaded++;
return listLoadedTexture[iii]->m_openGlTextureID;
}
@ -386,60 +480,27 @@ int32_t ewol::LoadTexture(etk::File fileName)
if (fileExtention == "bmp") {
if (false == fileName.Exist()) {
EWOL_ERROR("File does not Exist ... " << fileName);
return -1;
}
Bitmap * myBitmap = new Bitmap(fileName);
myBitmap->Display();
if (myBitmap->LoadOK() == true) {
if (myBitmap->Width()!= myBitmap->Height()) {
EWOL_ERROR("Texture can not have Width=" << myBitmap->Width() << "px different of height=" << myBitmap->Height() << "px in file:" << fileName);
return -1;
}
LoadedTexture *tmpTex = new LoadedTexture();
int32_t outTextureID = -1;
GLuint textureid = 0;
if (NULL != tmpTex) {
tmpTex->m_filename = fileName;
tmpTex->m_nbTimeLoaded = 1;
tmpTex->m_imageSize = myBitmap->Width();
tmpTex->m_openGlTextureID = -1;
tmpTex->m_imageData = myBitmap;
tmpTex->m_loaded = false;
if (true == OGLContextLoaded) {
glGenTextures(1, &textureid);
glBindTexture(GL_TEXTURE_2D, textureid);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//--- mode nearest
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//#ifdef __PLATFORM__Linux
//--- Mode linear
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//#endif
EWOL_WARNING("Set in OpenGl texture =" << myBitmap->Width() << "px different of height=" << myBitmap->Height() << "px in file:" << fileName << " in id OGL : " <<textureid);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, myBitmap->Width(), myBitmap->Height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, myBitmap->Data());
tmpTex->m_openGlTextureID = textureid;
tmpTex->m_loaded = true;
}
listLoadedTexture.PushBack(tmpTex);
outTextureID = listLoadedTexture.Size()-1;
} else {
EWOL_ERROR("Allocation ERROR... ");
}
return outTextureID;
} else {
return -1;
Bitmap * myBitmap = new Bitmap(fileName);
myBitmap->Display();
if (myBitmap->LoadOK() == true) {
if (myBitmap->Width()!= myBitmap->Height()) {
EWOL_ERROR("Texture can not have Width=" << myBitmap->Width() << "px different of height=" << myBitmap->Height() << "px in file:" << fileName);
return -1;
}
outTextureID = LoadTexture(GL_TEXTURE_2D, 0, GL_RGBA, myBitmap->Width(), myBitmap->Height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, myBitmap->Data(), myBitmap->Width()*myBitmap->Height()*4, fileName.GetCompleateName());
}
delete (myBitmap);
}
} else {
EWOL_ERROR("Extention not managed " << fileName << " Sopported extention : .bmp");
return -1;
}
return outTextureID;
}
void ewol::UnLoadTexture(uint32_t textureID)
{
EWOL_INFO("Unload a specific tecture ID=" << textureID);
if (textureID>=0 && (int32_t)textureID<listLoadedTexture.Size()) {
listLoadedTexture[textureID]->m_nbTimeLoaded--;
if (0 == listLoadedTexture[textureID]->m_nbTimeLoaded) {
@ -447,6 +508,10 @@ void ewol::UnLoadTexture(uint32_t textureID)
if (true == listLoadedTexture[textureID]->m_loaded) {
glDeleteTextures(1,&listLoadedTexture[textureID]->m_openGlTextureID);
}
if (NULL != listLoadedTexture[textureID]->m_data) {
delete[] listLoadedTexture[textureID]->m_data;
listLoadedTexture[textureID]->m_data = NULL;
}
delete(listLoadedTexture[textureID]);
listLoadedTexture[textureID] = NULL;
listLoadedTexture.Erase(textureID);
@ -469,7 +534,7 @@ int32_t ewol::GetTextureSize(uint32_t textureID)
{
for (int32_t iii=0; iii<listLoadedTexture.Size(); iii++) {
if (listLoadedTexture[iii]->m_openGlTextureID == textureID) {
return listLoadedTexture[iii]->m_imageSize;
return listLoadedTexture[iii]->m_width;
}
}
EWOL_ERROR("Can not find TextureId=" << textureID << " in the list of texture loaded...");

View File

@ -40,6 +40,7 @@ namespace ewol
};
*/
int32_t LoadTexture(etk::File fileName);
int32_t LoadTexture(int32_t target, int32_t level, int32_t internalFormat, int32_t width, int32_t height, int32_t border, int32_t format, int32_t type, const void* data, int32_t nbBytes, etk::String filename);
void UnLoadTexture(uint32_t textureID);
int32_t GetTextureSize(uint32_t textureID);
uint32_t GetTextureGLID(uint32_t textureID);

View File

@ -78,6 +78,7 @@ int32_t m_previous_y = -1;
int64_t m_previousTime = 0;
bool m_previousDouble = false;
bool firstInitDone = false;
/* Call to initialize the graphics state */
void EWOL_NativeInit(void)
@ -87,6 +88,7 @@ void EWOL_NativeInit(void)
sDemoStopped = 0;
sTimeOffsetInit = 0;
ewol::TextureOGLContext(true);
firstInitDone = true;
}
@ -247,22 +249,31 @@ void EWOL_NativeParamSetArchiveDir(int mode, const char* str)
switch(mode)
{
case 0:
EWOL_WARNING("Directory APK : path=" << str);
etk::SetBaseFolderData(str);
EWOL_DEBUG("Directory APK : path=" << str);
//if (firstInitDone == false)
{
etk::SetBaseFolderData(str);
}
break;
case 1:
EWOL_WARNING("Directory mode=FILE path=" << str);
etk::SetBaseFolderDataUser(str);
EWOL_DEBUG("Directory mode=FILE path=" << str);
//if (firstInitDone == false)
{
etk::SetBaseFolderDataUser(str);
}
break;
case 2:
EWOL_WARNING("Directory mode=CACHE path=" << str);
etk::SetBaseFolderCache(str);
EWOL_DEBUG("Directory mode=CACHE path=" << str);
//if (firstInitDone == false)
{
etk::SetBaseFolderCache(str);
}
break;
case 3:
EWOL_WARNING("Directory mode=EXTERNAL_CACHE path=" << str);
EWOL_DEBUG("Directory mode=EXTERNAL_CACHE path=" << str);
break;
default:
EWOL_WARNING("Directory mode=???? path=" << str);
EWOL_DEBUG("Directory mode=???? path=" << str);
break;
}
}

View File

@ -0,0 +1,35 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := freetype
LOCAL_STATIC_LIBRARIES :=
# load the common sources file of the platform
include $(LOCAL_PATH)/file.mk
LOCAL_C_INCLUDES := $(LOCAL_PATH) $(addprefix $(LOCAL_PATH)/, $(sort $(dir $(FILE_LIST))))
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_CFLAGS += -W -Wall \
-fPIC -DPIC \
-DDARWIN_NO_CARBON \
-DFT2_BUILD_LIBRARY \
-DANDROID_FONT_HACK=1
LOCAL_SRC_FILES:= $(FILE_LIST)
ifeq ($(TARGET_BUILD_TYPE),release)
LOCAL_CFLAGS += -O2
endif
include $(BUILD_STATIC_LIBRARY)
#for freetype : https://github.com/cdave1/freetype2-android

View File

@ -0,0 +1,32 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# load the common sources file of the platform
include $(LOCAL_PATH)/file.mk
LOCAL_MODULE := libfreetype
LOCAL_STATIC_LIBRARIES :=
LOCAL_C_INCLUDES := -I$(LOCAL_PATH) $(addprefix -I$(LOCAL_PATH)/, $(sort $(dir $(FILE_LIST))))
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_SRC_FILES := $(FILE_LIST)
LOCAL_CFLAGS += -W -Wall \
-fPIC -DPIC \
-DDARWIN_NO_CARBON \
-DFT2_BUILD_LIBRARY \
-DANDROID_FONT_HACK=1
LOCAL_SRC_FILES:= $(FILE_LIST)
ifeq ($(TARGET_BUILD_TYPE),release)
LOCAL_CFLAGS += -O2
endif
include $(BUILD_STATIC_LIBRARY)

View File

@ -0,0 +1,22 @@
FILE_LIST:= freetype/base/ftbbox.c \
freetype/base/ftbitmap.c \
freetype/base/ftglyph.c \
freetype/base/ftstroke.c \
freetype/base/ftxf86.c \
freetype/base/ftbase.c \
freetype/base/ftsystem.c \
freetype/base/ftinit.c \
freetype/base/ftgasp.c \
freetype/base/ftadvanc.c \
freetype/raster/raster.c \
freetype/sfnt/sfnt.c \
freetype/smooth/smooth.c \
freetype/autofit/autofit.c \
freetype/truetype/truetype.c \
freetype/cff/cff.c \
freetype/psnames/psnames.c \
freetype/pshinter/pshinter.c

View File

@ -0,0 +1,292 @@
/***************************************************************************/
/* */
/* afangles.c */
/* */
/* Routines used to compute vector angles with limited accuracy */
/* and very high speed. It also contains sorting routines (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006 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 "aftypes.h"
#if 0
FT_LOCAL_DEF( FT_Int )
af_corner_is_flat( FT_Pos x_in,
FT_Pos y_in,
FT_Pos x_out,
FT_Pos y_out )
{
FT_Pos ax = x_in;
FT_Pos ay = y_in;
FT_Pos d_in, d_out, d_corner;
if ( ax < 0 )
ax = -ax;
if ( ay < 0 )
ay = -ay;
d_in = ax + ay;
ax = x_out;
if ( ax < 0 )
ax = -ax;
ay = y_out;
if ( ay < 0 )
ay = -ay;
d_out = ax + ay;
ax = x_out + x_in;
if ( ax < 0 )
ax = -ax;
ay = y_out + y_in;
if ( ay < 0 )
ay = -ay;
d_corner = ax + ay;
return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
}
FT_LOCAL_DEF( FT_Int )
af_corner_orientation( FT_Pos x_in,
FT_Pos y_in,
FT_Pos x_out,
FT_Pos y_out )
{
FT_Pos delta;
delta = x_in * y_out - y_in * x_out;
if ( delta == 0 )
return 0;
else
return 1 - 2 * ( delta < 0 );
}
#endif
/*
* We are not using `af_angle_atan' anymore, but we keep the source
* code below just in case...
*/
#if 0
/*
* The trick here is to realize that we don't need a very accurate angle
* approximation. We are going to use the result of `af_angle_atan' to
* only compare the sign of angle differences, or check whether its
* magnitude is very small.
*
* The approximation
*
* dy * PI / (|dx|+|dy|)
*
* should be enough, and much faster to compute.
*/
FT_LOCAL_DEF( AF_Angle )
af_angle_atan( FT_Fixed dx,
FT_Fixed dy )
{
AF_Angle angle;
FT_Fixed ax = dx;
FT_Fixed ay = dy;
if ( ax < 0 )
ax = -ax;
if ( ay < 0 )
ay = -ay;
ax += ay;
if ( ax == 0 )
angle = 0;
else
{
angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay );
if ( dx < 0 )
{
if ( angle >= 0 )
angle = AF_ANGLE_PI - angle;
else
angle = -AF_ANGLE_PI - angle;
}
}
return angle;
}
#elif 0
/* the following table has been automatically generated with */
/* the `mather.py' Python script */
#define AF_ATAN_BITS 8
static const FT_Byte af_arctan[1L << AF_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( AF_Angle )
af_angle_atan( FT_Fixed dx,
FT_Fixed dy )
{
AF_Angle angle;
/* check trivial cases */
if ( dy == 0 )
{
angle = 0;
if ( dx < 0 )
angle = AF_ANGLE_PI;
return angle;
}
else if ( dx == 0 )
{
angle = AF_ANGLE_PI2;
if ( dy < 0 )
angle = -AF_ANGLE_PI2;
return angle;
}
angle = 0;
if ( dx < 0 )
{
dx = -dx;
dy = -dy;
angle = AF_ANGLE_PI;
}
if ( dy < 0 )
{
FT_Pos tmp;
tmp = dx;
dx = -dy;
dy = tmp;
angle -= AF_ANGLE_PI2;
}
if ( dx == 0 && dy == 0 )
return 0;
if ( dx == dy )
angle += AF_ANGLE_PI4;
else if ( dx > dy )
angle += af_arctan[FT_DivFix( dy, dx ) >> ( 16 - AF_ATAN_BITS )];
else
angle += AF_ANGLE_PI2 -
af_arctan[FT_DivFix( dx, dy ) >> ( 16 - AF_ATAN_BITS )];
if ( angle > AF_ANGLE_PI )
angle -= AF_ANGLE_2PI;
return angle;
}
#endif /* 0 */
FT_LOCAL_DEF( void )
af_sort_pos( FT_UInt count,
FT_Pos* table )
{
FT_UInt i, j;
FT_Pos 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;
}
}
}
FT_LOCAL_DEF( void )
af_sort_widths( FT_UInt count,
AF_Width table )
{
FT_UInt i, j;
AF_WidthRec swap;
for ( i = 1; i < count; i++ )
{
for ( j = i; j > 0; j-- )
{
if ( table[j].org > table[j - 1].org )
break;
swap = table[j];
table[j] = table[j - 1];
table[j - 1] = swap;
}
}
}
/* END */

View File

@ -0,0 +1,7 @@
/*
* afangles.h
*
* This is a dummy file, used to please the build system. It is never
* included by the auto-fitter sources.
*
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
/***************************************************************************/
/* */
/* afcjk.h */
/* */
/* Auto-fitter hinting routines for CJK script (specification). */
/* */
/* Copyright 2006, 2007 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 __AFCJK_H__
#define __AFCJK_H__
#include "afhints.h"
FT_BEGIN_HEADER
/* the CJK-specific script class */
FT_CALLBACK_TABLE const AF_ScriptClassRec
af_cjk_script_class;
FT_LOCAL( FT_Error )
af_cjk_metrics_init( AF_LatinMetrics metrics,
FT_Face face );
FT_LOCAL( void )
af_cjk_metrics_scale( AF_LatinMetrics metrics,
AF_Scaler scaler );
FT_LOCAL( FT_Error )
af_cjk_hints_init( AF_GlyphHints hints,
AF_LatinMetrics metrics );
FT_LOCAL( FT_Error )
af_cjk_hints_apply( AF_GlyphHints hints,
FT_Outline* outline,
AF_LatinMetrics metrics );
/* */
FT_END_HEADER
#endif /* __AFCJK_H__ */
/* END */

View File

@ -0,0 +1,62 @@
/***************************************************************************/
/* */
/* afdummy.c */
/* */
/* Auto-fitter dummy routines to be used if no hinting should be */
/* performed (body). */
/* */
/* Copyright 2003, 2004, 2005 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 "afdummy.h"
#include "afhints.h"
static FT_Error
af_dummy_hints_init( AF_GlyphHints hints,
AF_ScriptMetrics metrics )
{
af_glyph_hints_rescale( hints,
metrics );
return 0;
}
static FT_Error
af_dummy_hints_apply( AF_GlyphHints hints,
FT_Outline* outline )
{
FT_UNUSED( hints );
FT_UNUSED( outline );
return 0;
}
FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
af_dummy_script_class =
{
AF_SCRIPT_NONE,
NULL,
sizeof( AF_ScriptMetricsRec ),
(AF_Script_InitMetricsFunc) NULL,
(AF_Script_ScaleMetricsFunc)NULL,
(AF_Script_DoneMetricsFunc) NULL,
(AF_Script_InitHintsFunc) af_dummy_hints_init,
(AF_Script_ApplyHintsFunc) af_dummy_hints_apply
};
/* END */

View File

@ -0,0 +1,43 @@
/***************************************************************************/
/* */
/* afdummy.h */
/* */
/* Auto-fitter dummy routines to be used if no hinting should be */
/* performed (specification). */
/* */
/* Copyright 2003, 2004, 2005 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 __AFDUMMY_H__
#define __AFDUMMY_H__
#include "aftypes.h"
FT_BEGIN_HEADER
/* A dummy script metrics class used when no hinting should
* be performed. This is the default for non-latin glyphs!
*/
FT_CALLBACK_TABLE const AF_ScriptClassRec
af_dummy_script_class;
/* */
FT_END_HEADER
#endif /* __AFDUMMY_H__ */
/* END */

View File

@ -0,0 +1,40 @@
/***************************************************************************/
/* */
/* aferrors.h */
/* */
/* Autofitter error codes (specification only). */
/* */
/* Copyright 2005 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 is used to define the Autofitter error enumeration */
/* constants. */
/* */
/*************************************************************************/
#ifndef __AFERRORS_H__
#define __AFERRORS_H__
#include FT_MODULE_ERRORS_H
#undef __FTERRORS_H__
#define FT_ERR_PREFIX AF_Err_
#define FT_ERR_BASE FT_Mod_Err_Autofit
#include FT_ERRORS_H
#endif /* __AFERRORS_H__ */
/* END */

View File

@ -0,0 +1,289 @@
/***************************************************************************/
/* */
/* afglobal.c */
/* */
/* Auto-fitter routines to compute global hinting values (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 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 "afglobal.h"
#include "afdummy.h"
#include "aflatin.h"
#include "afcjk.h"
#include "afindic.h"
#include "aferrors.h"
#ifdef FT_OPTION_AUTOFIT2
#include "aflatin2.h"
#endif
/* populate this list when you add new scripts */
static AF_ScriptClass const af_script_classes[] =
{
&af_dummy_script_class,
#ifdef FT_OPTION_AUTOFIT2
&af_latin2_script_class,
#endif
&af_latin_script_class,
&af_cjk_script_class,
&af_indic_script_class,
NULL /* do not remove */
};
/* index of default script in `af_script_classes' */
#define AF_SCRIPT_LIST_DEFAULT 2
/* indicates an uncovered glyph */
#define AF_SCRIPT_LIST_NONE 255
/*
* Note that glyph_scripts[] is used to map each glyph into
* an index into the `af_script_classes' array.
*
*/
typedef struct AF_FaceGlobalsRec_
{
FT_Face face;
FT_UInt glyph_count; /* same as face->num_glyphs */
FT_Byte* glyph_scripts;
AF_ScriptMetrics metrics[AF_SCRIPT_MAX];
} AF_FaceGlobalsRec;
/* Compute the script index of each glyph within a given face. */
static FT_Error
af_face_globals_compute_script_coverage( AF_FaceGlobals globals )
{
FT_Error error = AF_Err_Ok;
FT_Face face = globals->face;
FT_CharMap old_charmap = face->charmap;
FT_Byte* gscripts = globals->glyph_scripts;
FT_UInt ss;
/* the value 255 means `uncovered glyph' */
FT_MEM_SET( globals->glyph_scripts,
AF_SCRIPT_LIST_NONE,
globals->glyph_count );
error = FT_Select_Charmap( face, FT_ENCODING_UNICODE );
if ( error )
{
/*
* Ignore this error; we simply use the default script.
* XXX: Shouldn't we rather disable hinting?
*/
error = AF_Err_Ok;
goto Exit;
}
/* scan each script in a Unicode charmap */
for ( ss = 0; af_script_classes[ss]; ss++ )
{
AF_ScriptClass clazz = af_script_classes[ss];
AF_Script_UniRange range;
if ( clazz->script_uni_ranges == NULL )
continue;
/*
* Scan all unicode points in the range and set the corresponding
* glyph script index.
*/
for ( range = clazz->script_uni_ranges; range->first != 0; range++ )
{
FT_ULong charcode = range->first;
FT_UInt gindex;
gindex = FT_Get_Char_Index( face, charcode );
if ( gindex != 0 &&
gindex < globals->glyph_count &&
gscripts[gindex] == AF_SCRIPT_LIST_NONE )
{
gscripts[gindex] = (FT_Byte)ss;
}
for (;;)
{
charcode = FT_Get_Next_Char( face, charcode, &gindex );
if ( gindex == 0 || charcode > range->last )
break;
if ( gindex < globals->glyph_count &&
gscripts[gindex] == AF_SCRIPT_LIST_NONE )
{
gscripts[gindex] = (FT_Byte)ss;
}
}
}
}
Exit:
/*
* By default, all uncovered glyphs are set to the latin script.
* XXX: Shouldn't we disable hinting or do something similar?
*/
{
FT_UInt nn;
for ( nn = 0; nn < globals->glyph_count; nn++ )
{
if ( gscripts[nn] == AF_SCRIPT_LIST_NONE )
gscripts[nn] = AF_SCRIPT_LIST_DEFAULT;
}
}
FT_Set_Charmap( face, old_charmap );
return error;
}
FT_LOCAL_DEF( FT_Error )
af_face_globals_new( FT_Face face,
AF_FaceGlobals *aglobals )
{
FT_Error error;
FT_Memory memory;
AF_FaceGlobals globals;
memory = face->memory;
if ( !FT_ALLOC( globals, sizeof ( *globals ) +
face->num_glyphs * sizeof ( FT_Byte ) ) )
{
globals->face = face;
globals->glyph_count = face->num_glyphs;
globals->glyph_scripts = (FT_Byte*)( globals + 1 );
error = af_face_globals_compute_script_coverage( globals );
if ( error )
{
af_face_globals_free( globals );
globals = NULL;
}
}
*aglobals = globals;
return error;
}
FT_LOCAL_DEF( void )
af_face_globals_free( AF_FaceGlobals globals )
{
if ( globals )
{
FT_Memory memory = globals->face->memory;
FT_UInt nn;
for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ )
{
if ( globals->metrics[nn] )
{
AF_ScriptClass clazz = af_script_classes[nn];
FT_ASSERT( globals->metrics[nn]->clazz == clazz );
if ( clazz->script_metrics_done )
clazz->script_metrics_done( globals->metrics[nn] );
FT_FREE( globals->metrics[nn] );
}
}
globals->glyph_count = 0;
globals->glyph_scripts = NULL; /* no need to free this one! */
globals->face = NULL;
FT_FREE( globals );
}
}
FT_LOCAL_DEF( FT_Error )
af_face_globals_get_metrics( AF_FaceGlobals globals,
FT_UInt gindex,
FT_UInt options,
AF_ScriptMetrics *ametrics )
{
AF_ScriptMetrics metrics = NULL;
FT_UInt gidx;
AF_ScriptClass clazz;
FT_UInt script = options & 15;
const FT_UInt script_max = sizeof ( af_script_classes ) /
sizeof ( af_script_classes[0] );
FT_Error error = AF_Err_Ok;
if ( gindex >= globals->glyph_count )
{
error = AF_Err_Invalid_Argument;
goto Exit;
}
gidx = script;
if ( gidx == 0 || gidx + 1 >= script_max )
gidx = globals->glyph_scripts[gindex];
clazz = af_script_classes[gidx];
if ( script == 0 )
script = clazz->script;
metrics = globals->metrics[clazz->script];
if ( metrics == NULL )
{
/* create the global metrics object when needed */
FT_Memory memory = globals->face->memory;
if ( FT_ALLOC( metrics, clazz->script_metrics_size ) )
goto Exit;
metrics->clazz = clazz;
if ( clazz->script_metrics_init )
{
error = clazz->script_metrics_init( metrics, globals->face );
if ( error )
{
if ( clazz->script_metrics_done )
clazz->script_metrics_done( metrics );
FT_FREE( metrics );
goto Exit;
}
}
globals->metrics[clazz->script] = metrics;
}
Exit:
*ametrics = metrics;
return error;
}
/* END */

View File

@ -0,0 +1,67 @@
/***************************************************************************/
/* */
/* afglobal.h */
/* */
/* Auto-fitter routines to compute global hinting values */
/* (specification). */
/* */
/* Copyright 2003, 2004, 2005, 2007 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 __AF_GLOBAL_H__
#define __AF_GLOBAL_H__
#include "aftypes.h"
FT_BEGIN_HEADER
/************************************************************************/
/************************************************************************/
/***** *****/
/***** F A C E G L O B A L S *****/
/***** *****/
/************************************************************************/
/************************************************************************/
/*
* model the global hints data for a given face, decomposed into
* script-specific items
*/
typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals;
FT_LOCAL( FT_Error )
af_face_globals_new( FT_Face face,
AF_FaceGlobals *aglobals );
FT_LOCAL( FT_Error )
af_face_globals_get_metrics( AF_FaceGlobals globals,
FT_UInt gindex,
FT_UInt options,
AF_ScriptMetrics *ametrics );
FT_LOCAL( void )
af_face_globals_free( AF_FaceGlobals globals );
/* */
FT_END_HEADER
#endif /* __AF_GLOBALS_H__ */
/* END */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,333 @@
/***************************************************************************/
/* */
/* afhints.h */
/* */
/* Auto-fitter hinting routines (specification). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 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 __AFHINTS_H__
#define __AFHINTS_H__
#include "aftypes.h"
#define xxAF_SORT_SEGMENTS
FT_BEGIN_HEADER
/*
* The definition of outline glyph hints. These are shared by all
* script analysis routines (until now).
*/
typedef enum AF_Dimension_
{
AF_DIMENSION_HORZ = 0, /* x coordinates, */
/* i.e., vertical segments & edges */
AF_DIMENSION_VERT = 1, /* y coordinates, */
/* i.e., horizontal segments & edges */
AF_DIMENSION_MAX /* do not remove */
} AF_Dimension;
/* hint directions -- the values are computed so that two vectors are */
/* in opposite directions iff `dir1 + dir2 == 0' */
typedef enum AF_Direction_
{
AF_DIR_NONE = 4,
AF_DIR_RIGHT = 1,
AF_DIR_LEFT = -1,
AF_DIR_UP = 2,
AF_DIR_DOWN = -2
} AF_Direction;
/* point hint flags */
typedef enum AF_Flags_
{
AF_FLAG_NONE = 0,
/* point type flags */
AF_FLAG_CONIC = 1 << 0,
AF_FLAG_CUBIC = 1 << 1,
AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC,
/* point extremum flags */
AF_FLAG_EXTREMA_X = 1 << 2,
AF_FLAG_EXTREMA_Y = 1 << 3,
/* point roundness flags */
AF_FLAG_ROUND_X = 1 << 4,
AF_FLAG_ROUND_Y = 1 << 5,
/* point touch flags */
AF_FLAG_TOUCH_X = 1 << 6,
AF_FLAG_TOUCH_Y = 1 << 7,
/* candidates for weak interpolation have this flag set */
AF_FLAG_WEAK_INTERPOLATION = 1 << 8,
/* all inflection points in the outline have this flag set */
AF_FLAG_INFLECTION = 1 << 9
} AF_Flags;
/* edge hint flags */
typedef enum AF_Edge_Flags_
{
AF_EDGE_NORMAL = 0,
AF_EDGE_ROUND = 1 << 0,
AF_EDGE_SERIF = 1 << 1,
AF_EDGE_DONE = 1 << 2
} AF_Edge_Flags;
typedef struct AF_PointRec_* AF_Point;
typedef struct AF_SegmentRec_* AF_Segment;
typedef struct AF_EdgeRec_* AF_Edge;
typedef struct AF_PointRec_
{
FT_UShort flags; /* point flags used by hinter */
FT_Char in_dir; /* direction of inwards vector */
FT_Char out_dir; /* direction of outwards vector */
FT_Pos ox, oy; /* original, scaled position */
FT_Short fx, fy; /* original, unscaled position (font units) */
FT_Pos x, y; /* current position */
FT_Pos u, v; /* current (x,y) or (y,x) depending on context */
AF_Point next; /* next point in contour */
AF_Point prev; /* previous point in contour */
} AF_PointRec;
typedef struct AF_SegmentRec_
{
FT_Byte flags; /* edge/segment flags for this segment */
FT_Char dir; /* segment direction */
FT_Short pos; /* position of segment */
FT_Short min_coord; /* minimum coordinate of segment */
FT_Short max_coord; /* maximum coordinate of segment */
FT_Short height; /* the hinted segment height */
AF_Edge edge; /* the segment's parent edge */
AF_Segment edge_next; /* link to next segment in parent edge */
AF_Segment link; /* (stem) link segment */
AF_Segment serif; /* primary segment for serifs */
FT_Pos num_linked; /* number of linked segments */
FT_Pos score; /* used during stem matching */
FT_Pos len; /* used during stem matching */
AF_Point first; /* first point in edge segment */
AF_Point last; /* last point in edge segment */
AF_Point* contour; /* ptr to first point of segment's contour */
} AF_SegmentRec;
typedef struct AF_EdgeRec_
{
FT_Short fpos; /* original, unscaled position (font units) */
FT_Pos opos; /* original, scaled position */
FT_Pos pos; /* current position */
FT_Byte flags; /* edge flags */
FT_Char dir; /* edge direction */
FT_Fixed scale; /* used to speed up interpolation between edges */
AF_Width blue_edge; /* non-NULL if this is a blue edge */
AF_Edge link;
AF_Edge serif;
FT_Short num_linked;
FT_Int score;
AF_Segment first;
AF_Segment last;
} AF_EdgeRec;
typedef struct AF_AxisHintsRec_
{
FT_Int num_segments;
FT_Int max_segments;
AF_Segment segments;
#ifdef AF_SORT_SEGMENTS
FT_Int mid_segments;
#endif
FT_Int num_edges;
FT_Int max_edges;
AF_Edge edges;
AF_Direction major_dir;
} AF_AxisHintsRec, *AF_AxisHints;
typedef struct AF_GlyphHintsRec_
{
FT_Memory memory;
FT_Fixed x_scale;
FT_Pos x_delta;
FT_Fixed y_scale;
FT_Pos y_delta;
FT_Pos edge_distance_threshold;
FT_Int max_points;
FT_Int num_points;
AF_Point points;
FT_Int max_contours;
FT_Int num_contours;
AF_Point* contours;
AF_AxisHintsRec axis[AF_DIMENSION_MAX];
FT_UInt32 scaler_flags; /* copy of scaler flags */
FT_UInt32 other_flags; /* free for script-specific */
/* implementations */
AF_ScriptMetrics metrics;
FT_Pos xmin_delta; /* used for warping */
FT_Pos xmax_delta;
} AF_GlyphHintsRec;
#define AF_HINTS_TEST_SCALER( h, f ) ( (h)->scaler_flags & (f) )
#define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) )
#ifdef AF_DEBUG
#define AF_HINTS_DO_HORIZONTAL( h ) \
( !_af_debug_disable_horz_hints && \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
#define AF_HINTS_DO_VERTICAL( h ) \
( !_af_debug_disable_vert_hints && \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
#define AF_HINTS_DO_ADVANCE( h ) \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
#define AF_HINTS_DO_BLUES( h ) ( !_af_debug_disable_blue_hints )
#else /* !AF_DEBUG */
#define AF_HINTS_DO_HORIZONTAL( h ) \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
#define AF_HINTS_DO_VERTICAL( h ) \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL )
#define AF_HINTS_DO_ADVANCE( h ) \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
#define AF_HINTS_DO_BLUES( h ) 1
#endif /* !AF_DEBUG */
FT_LOCAL( AF_Direction )
af_direction_compute( FT_Pos dx,
FT_Pos dy );
FT_LOCAL( FT_Error )
af_axis_hints_new_segment( AF_AxisHints axis,
FT_Memory memory,
AF_Segment *asegment );
FT_LOCAL( FT_Error)
af_axis_hints_new_edge( AF_AxisHints axis,
FT_Int fpos,
AF_Direction dir,
FT_Memory memory,
AF_Edge *edge );
FT_LOCAL( void )
af_glyph_hints_init( AF_GlyphHints hints,
FT_Memory memory );
/*
* recompute all AF_Point in a AF_GlyphHints from the definitions
* in a source outline
*/
FT_LOCAL( void )
af_glyph_hints_rescale( AF_GlyphHints hints,
AF_ScriptMetrics metrics );
FT_LOCAL( FT_Error )
af_glyph_hints_reload( AF_GlyphHints hints,
FT_Outline* outline,
FT_Bool get_inflections );
FT_LOCAL( void )
af_glyph_hints_save( AF_GlyphHints hints,
FT_Outline* outline );
FT_LOCAL( void )
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
AF_Dimension dim );
FT_LOCAL( void )
af_glyph_hints_align_strong_points( AF_GlyphHints hints,
AF_Dimension dim );
FT_LOCAL( void )
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
AF_Dimension dim );
#ifdef AF_USE_WARPER
FT_LOCAL( void )
af_glyph_hints_scale_dim( AF_GlyphHints hints,
AF_Dimension dim,
FT_Fixed scale,
FT_Pos delta );
#endif
FT_LOCAL( void )
af_glyph_hints_done( AF_GlyphHints hints );
/* */
#define AF_SEGMENT_LEN( seg ) ( (seg)->max_coord - (seg)->min_coord )
#define AF_SEGMENT_DIST( seg1, seg2 ) ( ( (seg1)->pos > (seg2)->pos ) \
? (seg1)->pos - (seg2)->pos \
: (seg2)->pos - (seg1)->pos )
FT_END_HEADER
#endif /* __AFHINTS_H__ */
/* END */

View File

@ -0,0 +1,134 @@
/***************************************************************************/
/* */
/* afindic.c */
/* */
/* Auto-fitter hinting routines for Indic scripts (body). */
/* */
/* Copyright 2007 by */
/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */
/* */
/* 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 "aftypes.h"
#include "aflatin.h"
#ifdef AF_CONFIG_OPTION_INDIC
#include "afindic.h"
#include "aferrors.h"
#include "afcjk.h"
#ifdef AF_USE_WARPER
#include "afwarp.h"
#endif
static FT_Error
af_indic_metrics_init( AF_LatinMetrics metrics,
FT_Face face )
{
/* use CJK routines */
return af_cjk_metrics_init( metrics, face );
}
static void
af_indic_metrics_scale( AF_LatinMetrics metrics,
AF_Scaler scaler )
{
/* use CJK routines */
af_cjk_metrics_scale( metrics, scaler );
}
static FT_Error
af_indic_hints_init( AF_GlyphHints hints,
AF_LatinMetrics metrics )
{
/* use CJK routines */
return af_cjk_hints_init( hints, metrics );
}
static FT_Error
af_indic_hints_apply( AF_GlyphHints hints,
FT_Outline* outline,
AF_LatinMetrics metrics)
{
/* use CJK routines */
return af_cjk_hints_apply( hints, outline, metrics );
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** I N D I C S C R I P T C L A S S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
static const AF_Script_UniRangeRec af_indic_uniranges[] =
{
#if 0
{ 0x0100, 0xFFFF }, /* why this? */
#endif
{ 0x0900, 0x0DFF}, /* Indic Range */
{ 0, 0 }
};
FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
af_indic_script_class =
{
AF_SCRIPT_INDIC,
af_indic_uniranges,
sizeof( AF_LatinMetricsRec ),
(AF_Script_InitMetricsFunc) af_indic_metrics_init,
(AF_Script_ScaleMetricsFunc)af_indic_metrics_scale,
(AF_Script_DoneMetricsFunc) NULL,
(AF_Script_InitHintsFunc) af_indic_hints_init,
(AF_Script_ApplyHintsFunc) af_indic_hints_apply
};
#else /* !AF_CONFIG_OPTION_INDIC */
static const AF_Script_UniRangeRec af_indic_uniranges[] =
{
{ 0, 0 }
};
FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
af_indic_script_class =
{
AF_SCRIPT_INDIC,
af_indic_uniranges,
sizeof( AF_LatinMetricsRec ),
(AF_Script_InitMetricsFunc) NULL,
(AF_Script_ScaleMetricsFunc)NULL,
(AF_Script_DoneMetricsFunc) NULL,
(AF_Script_InitHintsFunc) NULL,
(AF_Script_ApplyHintsFunc) NULL
};
#endif /* !AF_CONFIG_OPTION_INDIC */
/* END */

View File

@ -0,0 +1,41 @@
/***************************************************************************/
/* */
/* afindic.h */
/* */
/* Auto-fitter hinting routines for Indic scripts (specification). */
/* */
/* Copyright 2007 by */
/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */
/* */
/* 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 __AFINDIC_H__
#define __AFINDIC_H__
#include "afhints.h"
FT_BEGIN_HEADER
/* the Indic-specific script class */
FT_CALLBACK_TABLE const AF_ScriptClassRec
af_indic_script_class;
/* */
FT_END_HEADER
#endif /* __AFINDIC_H__ */
/* END */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,209 @@
/***************************************************************************/
/* */
/* aflatin.h */
/* */
/* Auto-fitter hinting routines for latin script (specification). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007 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 __AFLATIN_H__
#define __AFLATIN_H__
#include "afhints.h"
FT_BEGIN_HEADER
/* the latin-specific script class */
FT_CALLBACK_TABLE const AF_ScriptClassRec
af_latin_script_class;
/* constants are given with units_per_em == 2048 in mind */
#define AF_LATIN_CONSTANT( metrics, c ) \
( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 )
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** L A T I N G L O B A L M E T R I C S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/*
* The following declarations could be embedded in the file `aflatin.c';
* they have been made semi-public to allow alternate script hinters to
* re-use some of them.
*/
/* Latin (global) metrics management */
enum
{
AF_LATIN_BLUE_CAPITAL_TOP,
AF_LATIN_BLUE_CAPITAL_BOTTOM,
AF_LATIN_BLUE_SMALL_F_TOP,
AF_LATIN_BLUE_SMALL_TOP,
AF_LATIN_BLUE_SMALL_BOTTOM,
AF_LATIN_BLUE_SMALL_MINOR,
AF_LATIN_BLUE_MAX
};
#define AF_LATIN_IS_TOP_BLUE( b ) ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \
(b) == AF_LATIN_BLUE_SMALL_F_TOP || \
(b) == AF_LATIN_BLUE_SMALL_TOP )
#define AF_LATIN_MAX_WIDTHS 16
#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX
enum
{
AF_LATIN_BLUE_ACTIVE = 1 << 0,
AF_LATIN_BLUE_TOP = 1 << 1,
AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */
/* optimization */
AF_LATIN_BLUE_FLAG_MAX
};
typedef struct AF_LatinBlueRec_
{
AF_WidthRec ref;
AF_WidthRec shoot;
FT_UInt flags;
} AF_LatinBlueRec, *AF_LatinBlue;
typedef struct AF_LatinAxisRec_
{
FT_Fixed scale;
FT_Pos delta;
FT_UInt width_count;
AF_WidthRec widths[AF_LATIN_MAX_WIDTHS];
FT_Pos edge_distance_threshold;
FT_Pos standard_width;
FT_Bool extra_light;
/* ignored for horizontal metrics */
FT_Bool control_overshoot;
FT_UInt blue_count;
AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX];
FT_Fixed org_scale;
FT_Pos org_delta;
} AF_LatinAxisRec, *AF_LatinAxis;
typedef struct AF_LatinMetricsRec_
{
AF_ScriptMetricsRec root;
FT_UInt units_per_em;
AF_LatinAxisRec axis[AF_DIMENSION_MAX];
} AF_LatinMetricsRec, *AF_LatinMetrics;
FT_LOCAL( FT_Error )
af_latin_metrics_init( AF_LatinMetrics metrics,
FT_Face face );
FT_LOCAL( void )
af_latin_metrics_scale( AF_LatinMetrics metrics,
AF_Scaler scaler );
FT_LOCAL( void )
af_latin_metrics_init_widths( AF_LatinMetrics metrics,
FT_Face face,
FT_ULong charcode );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** L A T I N G L Y P H A N A L Y S I S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
enum
{
AF_LATIN_HINTS_HORZ_SNAP = 1 << 0, /* enable stem width snapping */
AF_LATIN_HINTS_VERT_SNAP = 1 << 1, /* enable stem height snapping */
AF_LATIN_HINTS_STEM_ADJUST = 1 << 2, /* enable stem width/height */
/* adjustment */
AF_LATIN_HINTS_MONO = 1 << 3 /* indicate monochrome */
/* rendering */
};
#define AF_LATIN_HINTS_DO_HORZ_SNAP( h ) \
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_HORZ_SNAP )
#define AF_LATIN_HINTS_DO_VERT_SNAP( h ) \
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_VERT_SNAP )
#define AF_LATIN_HINTS_DO_STEM_ADJUST( h ) \
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_STEM_ADJUST )
#define AF_LATIN_HINTS_DO_MONO( h ) \
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_MONO )
/*
* This shouldn't normally be exported. However, other scripts might
* like to use this function as-is.
*/
FT_LOCAL( FT_Error )
af_latin_hints_compute_segments( AF_GlyphHints hints,
AF_Dimension dim );
/*
* This shouldn't normally be exported. However, other scripts might
* want to use this function as-is.
*/
FT_LOCAL( void )
af_latin_hints_link_segments( AF_GlyphHints hints,
AF_Dimension dim );
/*
* This shouldn't normally be exported. However, other scripts might
* want to use this function as-is.
*/
FT_LOCAL( FT_Error )
af_latin_hints_compute_edges( AF_GlyphHints hints,
AF_Dimension dim );
FT_LOCAL( FT_Error )
af_latin_hints_detect_features( AF_GlyphHints hints,
AF_Dimension dim );
/* */
FT_END_HEADER
#endif /* __AFLATIN_H__ */
/* END */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
/***************************************************************************/
/* */
/* aflatin2.h */
/* */
/* Auto-fitter hinting routines for latin script (specification). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007 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 __AFLATIN2_H__
#define __AFLATIN2_H__
#include "afhints.h"
FT_BEGIN_HEADER
/* the latin-specific script class */
FT_CALLBACK_TABLE const AF_ScriptClassRec
af_latin2_script_class;
/* */
FT_END_HEADER
#endif /* __AFLATIN_H__ */
/* END */

View File

@ -0,0 +1,535 @@
/***************************************************************************/
/* */
/* afloader.c */
/* */
/* Auto-fitter glyph loading routines (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 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 "afloader.h"
#include "afhints.h"
#include "afglobal.h"
#include "aflatin.h"
#include "aferrors.h"
FT_LOCAL_DEF( FT_Error )
af_loader_init( AF_Loader loader,
FT_Memory memory )
{
FT_ZERO( loader );
af_glyph_hints_init( &loader->hints, memory );
#ifdef AF_DEBUG
_af_debug_hints = &loader->hints;
#endif
return FT_GlyphLoader_New( memory, &loader->gloader );
}
FT_LOCAL_DEF( FT_Error )
af_loader_reset( AF_Loader loader,
FT_Face face )
{
FT_Error error = AF_Err_Ok;
loader->face = face;
loader->globals = (AF_FaceGlobals)face->autohint.data;
FT_GlyphLoader_Rewind( loader->gloader );
if ( loader->globals == NULL )
{
error = af_face_globals_new( face, &loader->globals );
if ( !error )
{
face->autohint.data =
(FT_Pointer)loader->globals;
face->autohint.finalizer =
(FT_Generic_Finalizer)af_face_globals_free;
}
}
return error;
}
FT_LOCAL_DEF( void )
af_loader_done( AF_Loader loader )
{
af_glyph_hints_done( &loader->hints );
loader->face = NULL;
loader->globals = NULL;
#ifdef AF_DEBUG
_af_debug_hints = NULL;
#endif
FT_GlyphLoader_Done( loader->gloader );
loader->gloader = NULL;
}
static FT_Error
af_loader_load_g( AF_Loader loader,
AF_Scaler scaler,
FT_UInt glyph_index,
FT_Int32 load_flags,
FT_UInt depth )
{
FT_Error error;
FT_Face face = loader->face;
FT_GlyphLoader gloader = loader->gloader;
AF_ScriptMetrics metrics = loader->metrics;
AF_GlyphHints hints = &loader->hints;
FT_GlyphSlot slot = face->glyph;
FT_Slot_Internal internal = slot->internal;
error = FT_Load_Glyph( face, glyph_index, load_flags );
if ( error )
goto Exit;
loader->transformed = internal->glyph_transformed;
if ( loader->transformed )
{
FT_Matrix inverse;
loader->trans_matrix = internal->glyph_matrix;
loader->trans_delta = internal->glyph_delta;
inverse = loader->trans_matrix;
FT_Matrix_Invert( &inverse );
FT_Vector_Transform( &loader->trans_delta, &inverse );
}
/* set linear metrics */
slot->linearHoriAdvance = slot->metrics.horiAdvance;
slot->linearVertAdvance = slot->metrics.vertAdvance;
switch ( slot->format )
{
case FT_GLYPH_FORMAT_OUTLINE:
/* translate the loaded glyph when an internal transform is needed */
if ( loader->transformed )
FT_Outline_Translate( &slot->outline,
loader->trans_delta.x,
loader->trans_delta.y );
/* copy the outline points in the loader's current */
/* extra points which is used to keep original glyph coordinates */
error = FT_GLYPHLOADER_CHECK_POINTS( gloader,
slot->outline.n_points + 4,
slot->outline.n_contours );
if ( error )
goto Exit;
FT_ARRAY_COPY( gloader->current.outline.points,
slot->outline.points,
slot->outline.n_points );
FT_ARRAY_COPY( gloader->current.outline.contours,
slot->outline.contours,
slot->outline.n_contours );
FT_ARRAY_COPY( gloader->current.outline.tags,
slot->outline.tags,
slot->outline.n_points );
gloader->current.outline.n_points = slot->outline.n_points;
gloader->current.outline.n_contours = slot->outline.n_contours;
/* compute original horizontal phantom points (and ignore */
/* vertical ones) */
loader->pp1.x = hints->x_delta;
loader->pp1.y = hints->y_delta;
loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
hints->x_scale ) + hints->x_delta;
loader->pp2.y = hints->y_delta;
/* be sure to check for spacing glyphs */
if ( slot->outline.n_points == 0 )
goto Hint_Metrics;
/* now load the slot image into the auto-outline and run the */
/* automatic hinting process */
if ( metrics->clazz->script_hints_apply )
metrics->clazz->script_hints_apply( hints,
&gloader->current.outline,
metrics );
/* we now need to hint the metrics according to the change in */
/* width/positioning that occurred during the hinting process */
if ( scaler->render_mode != FT_RENDER_MODE_LIGHT )
{
FT_Pos old_rsb, old_lsb, new_lsb;
FT_Pos pp1x_uh, pp2x_uh;
AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ];
AF_Edge edge1 = axis->edges; /* leftmost edge */
AF_Edge edge2 = edge1 +
axis->num_edges - 1; /* rightmost edge */
if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) )
{
old_rsb = loader->pp2.x - edge2->opos;
old_lsb = edge1->opos;
new_lsb = edge1->pos;
/* remember unhinted values to later account */
/* for rounding errors */
pp1x_uh = new_lsb - old_lsb;
pp2x_uh = edge2->pos + old_rsb;
/* prefer too much space over too little space */
/* for very small sizes */
if ( old_lsb < 24 )
pp1x_uh -= 8;
if ( old_rsb < 24 )
pp2x_uh += 8;
loader->pp1.x = FT_PIX_ROUND( pp1x_uh );
loader->pp2.x = FT_PIX_ROUND( pp2x_uh );
if ( loader->pp1.x >= new_lsb && old_lsb > 0 )
loader->pp1.x -= 64;
if ( loader->pp2.x <= edge2->pos && old_rsb > 0 )
loader->pp2.x += 64;
slot->lsb_delta = loader->pp1.x - pp1x_uh;
slot->rsb_delta = loader->pp2.x - pp2x_uh;
}
else
{
FT_Pos pp1x = loader->pp1.x;
FT_Pos pp2x = loader->pp2.x;
loader->pp1.x = FT_PIX_ROUND( pp1x );
loader->pp2.x = FT_PIX_ROUND( pp2x );
slot->lsb_delta = loader->pp1.x - pp1x;
slot->rsb_delta = loader->pp2.x - pp2x;
}
}
else
{
FT_Pos pp1x = loader->pp1.x;
FT_Pos pp2x = loader->pp2.x;
loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta );
loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta );
slot->lsb_delta = loader->pp1.x - pp1x;
slot->rsb_delta = loader->pp2.x - pp2x;
}
/* good, we simply add the glyph to our loader's base */
FT_GlyphLoader_Add( gloader );
break;
case FT_GLYPH_FORMAT_COMPOSITE:
{
FT_UInt nn, num_subglyphs = slot->num_subglyphs;
FT_UInt num_base_subgs, start_point;
FT_SubGlyph subglyph;
start_point = gloader->base.outline.n_points;
/* first of all, copy the subglyph descriptors in the glyph loader */
error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );
if ( error )
goto Exit;
FT_ARRAY_COPY( gloader->current.subglyphs,
slot->subglyphs,
num_subglyphs );
gloader->current.num_subglyphs = num_subglyphs;
num_base_subgs = gloader->base.num_subglyphs;
/* now, read each subglyph independently */
for ( nn = 0; nn < num_subglyphs; nn++ )
{
FT_Vector pp1, pp2;
FT_Pos x, y;
FT_UInt num_points, num_new_points, num_base_points;
/* gloader.current.subglyphs can change during glyph loading due */
/* to re-allocation -- we must recompute the current subglyph on */
/* each iteration */
subglyph = gloader->base.subglyphs + num_base_subgs + nn;
pp1 = loader->pp1;
pp2 = loader->pp2;
num_base_points = gloader->base.outline.n_points;
error = af_loader_load_g( loader, scaler, subglyph->index,
load_flags, depth + 1 );
if ( error )
goto Exit;
/* recompute subglyph pointer */
subglyph = gloader->base.subglyphs + num_base_subgs + nn;
if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
{
pp1 = loader->pp1;
pp2 = loader->pp2;
}
else
{
loader->pp1 = pp1;
loader->pp2 = pp2;
}
num_points = gloader->base.outline.n_points;
num_new_points = num_points - num_base_points;
/* now perform the transform required for this subglyph */
if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE |
FT_SUBGLYPH_FLAG_XY_SCALE |
FT_SUBGLYPH_FLAG_2X2 ) )
{
FT_Vector* cur = gloader->base.outline.points +
num_base_points;
FT_Vector* limit = cur + num_new_points;
for ( ; cur < limit; cur++ )
FT_Vector_Transform( cur, &subglyph->transform );
}
/* apply offset */
if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
{
FT_Int k = subglyph->arg1;
FT_UInt l = subglyph->arg2;
FT_Vector* p1;
FT_Vector* p2;
if ( start_point + k >= num_base_points ||
l >= (FT_UInt)num_new_points )
{
error = AF_Err_Invalid_Composite;
goto Exit;
}
l += num_base_points;
/* for now, only use the current point coordinates; */
/* we may consider another approach in the near future */
p1 = gloader->base.outline.points + start_point + k;
p2 = gloader->base.outline.points + start_point + l;
x = p1->x - p2->x;
y = p1->y - p2->y;
}
else
{
x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
x = FT_PIX_ROUND( x );
y = FT_PIX_ROUND( y );
}
{
FT_Outline dummy = gloader->base.outline;
dummy.points += num_base_points;
dummy.n_points = (short)num_new_points;
FT_Outline_Translate( &dummy, x, y );
}
}
}
break;
default:
/* we don't support other formats (yet?) */
error = AF_Err_Unimplemented_Feature;
}
Hint_Metrics:
if ( depth == 0 )
{
FT_BBox bbox;
FT_Vector vvector;
vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX;
vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY;
vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale );
vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale );
/* transform the hinted outline if needed */
if ( loader->transformed )
{
FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
FT_Vector_Transform( &vvector, &loader->trans_matrix );
}
#if 1
/* we must translate our final outline by -pp1.x and compute */
/* the new metrics */
if ( loader->pp1.x )
FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
#endif
FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
bbox.yMin = FT_PIX_FLOOR( bbox.yMin );
bbox.xMax = FT_PIX_CEIL( bbox.xMax );
bbox.yMax = FT_PIX_CEIL( bbox.yMax );
slot->metrics.width = bbox.xMax - bbox.xMin;
slot->metrics.height = bbox.yMax - bbox.yMin;
slot->metrics.horiBearingX = bbox.xMin;
slot->metrics.horiBearingY = bbox.yMax;
slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x );
slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y );
/* for mono-width fonts (like Andale, Courier, etc.) we need */
/* to keep the original rounded advance width */
#if 0
if ( !FT_IS_FIXED_WIDTH( slot->face ) )
slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
else
slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
x_scale );
#else
if ( !FT_IS_FIXED_WIDTH( slot->face ) )
{
/* non-spacing glyphs must stay as-is */
if ( slot->metrics.horiAdvance )
slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
}
else
{
slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
metrics->scaler.x_scale );
/* Set delta values to 0. Otherwise code that uses them is */
/* going to ruin the fixed advance width. */
slot->lsb_delta = 0;
slot->rsb_delta = 0;
}
#endif
slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
metrics->scaler.y_scale );
slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
/* now copy outline into glyph slot */
FT_GlyphLoader_Rewind( internal->loader );
error = FT_GlyphLoader_CopyPoints( internal->loader, gloader );
if ( error )
goto Exit;
slot->outline = internal->loader->base.outline;
slot->format = FT_GLYPH_FORMAT_OUTLINE;
}
#ifdef DEBUG_HINTER
af_debug_hinter = hinter;
#endif
Exit:
return error;
}
FT_LOCAL_DEF( FT_Error )
af_loader_load_glyph( AF_Loader loader,
FT_Face face,
FT_UInt gindex,
FT_UInt32 load_flags )
{
FT_Error error;
FT_Size size = face->size;
AF_ScalerRec scaler;
if ( !size )
return AF_Err_Invalid_Argument;
FT_ZERO( &scaler );
scaler.face = face;
scaler.x_scale = size->metrics.x_scale;
scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */
scaler.y_scale = size->metrics.y_scale;
scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */
scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
scaler.flags = 0; /* XXX: fix this */
error = af_loader_reset( loader, face );
if ( !error )
{
AF_ScriptMetrics metrics;
FT_UInt options = 0;
#ifdef FT_OPTION_AUTOFIT2
/* XXX: undocumented hook to activate the latin2 hinter */
if ( load_flags & ( 1UL << 20 ) )
options = 2;
#endif
error = af_face_globals_get_metrics( loader->globals, gindex,
options, &metrics );
if ( !error )
{
loader->metrics = metrics;
if ( metrics->clazz->script_metrics_scale )
metrics->clazz->script_metrics_scale( metrics, &scaler );
else
metrics->scaler = scaler;
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
load_flags &= ~FT_LOAD_RENDER;
if ( metrics->clazz->script_hints_init )
{
error = metrics->clazz->script_hints_init( &loader->hints,
metrics );
if ( error )
goto Exit;
}
error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );
}
}
Exit:
return error;
}
/* END */

View File

@ -0,0 +1,73 @@
/***************************************************************************/
/* */
/* afloader.h */
/* */
/* Auto-fitter glyph loading routines (specification). */
/* */
/* Copyright 2003, 2004, 2005 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 __AF_LOADER_H__
#define __AF_LOADER_H__
#include "afhints.h"
#include "afglobal.h"
FT_BEGIN_HEADER
typedef struct AF_LoaderRec_
{
FT_Face face; /* current face */
AF_FaceGlobals globals; /* current face globals */
FT_GlyphLoader gloader; /* glyph loader */
AF_GlyphHintsRec hints;
AF_ScriptMetrics metrics;
FT_Bool transformed;
FT_Matrix trans_matrix;
FT_Vector trans_delta;
FT_Vector pp1;
FT_Vector pp2;
/* we don't handle vertical phantom points */
} AF_LoaderRec, *AF_Loader;
FT_LOCAL( FT_Error )
af_loader_init( AF_Loader loader,
FT_Memory memory );
FT_LOCAL( FT_Error )
af_loader_reset( AF_Loader loader,
FT_Face face );
FT_LOCAL( void )
af_loader_done( AF_Loader loader );
FT_LOCAL( FT_Error )
af_loader_load_glyph( AF_Loader loader,
FT_Face face,
FT_UInt gindex,
FT_UInt32 load_flags );
/* */
FT_END_HEADER
#endif /* __AF_LOADER_H__ */
/* END */

View File

@ -0,0 +1,97 @@
/***************************************************************************/
/* */
/* afmodule.c */
/* */
/* Auto-fitter module implementation (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006 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 "afmodule.h"
#include "afloader.h"
#ifdef AF_DEBUG
int _af_debug;
int _af_debug_disable_horz_hints;
int _af_debug_disable_vert_hints;
int _af_debug_disable_blue_hints;
void* _af_debug_hints;
#endif
#include FT_INTERNAL_OBJECTS_H
typedef struct FT_AutofitterRec_
{
FT_ModuleRec root;
AF_LoaderRec loader[1];
} FT_AutofitterRec, *FT_Autofitter;
FT_CALLBACK_DEF( FT_Error )
af_autofitter_init( FT_Autofitter module )
{
return af_loader_init( module->loader, module->root.library->memory );
}
FT_CALLBACK_DEF( void )
af_autofitter_done( FT_Autofitter module )
{
af_loader_done( module->loader );
}
FT_CALLBACK_DEF( FT_Error )
af_autofitter_load_glyph( FT_Autofitter module,
FT_GlyphSlot slot,
FT_Size size,
FT_UInt glyph_index,
FT_Int32 load_flags )
{
FT_UNUSED( size );
return af_loader_load_glyph( module->loader, slot->face,
glyph_index, load_flags );
}
FT_CALLBACK_TABLE_DEF
const FT_AutoHinter_ServiceRec af_autofitter_service =
{
NULL,
NULL,
NULL,
(FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph
};
FT_CALLBACK_TABLE_DEF
const FT_Module_Class autofit_module_class =
{
FT_MODULE_HINTER,
sizeof ( FT_AutofitterRec ),
"autofitter",
0x10000L, /* version 1.0 of the autofitter */
0x20000L, /* requires FreeType 2.0 or above */
(const void*)&af_autofitter_service,
(FT_Module_Constructor)af_autofitter_init,
(FT_Module_Destructor) af_autofitter_done,
(FT_Module_Requester) NULL
};
/* END */

View File

@ -0,0 +1,37 @@
/***************************************************************************/
/* */
/* afmodule.h */
/* */
/* Auto-fitter module implementation (specification). */
/* */
/* Copyright 2003, 2004, 2005 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 __AFMODULE_H__
#define __AFMODULE_H__
#include <freetype/ft2build.h>
#include FT_MODULE_H
FT_BEGIN_HEADER
FT_CALLBACK_TABLE
const FT_Module_Class autofit_module_class;
FT_END_HEADER
#endif /* __AFMODULE_H__ */
/* END */

View File

@ -0,0 +1,349 @@
/***************************************************************************/
/* */
/* aftypes.h */
/* */
/* Auto-fitter types (specification only). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 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 auto-fitter is a complete rewrite of the old auto-hinter.
* Its main feature is the ability to differentiate between different
* scripts in order to apply language-specific rules.
*
* The code has also been compartmentized into several entities that
* should make algorithmic experimentation easier than with the old
* code.
*
* Finally, we get rid of the Catharon license, since this code is
* released under the FreeType one.
*
*************************************************************************/
#ifndef __AFTYPES_H__
#define __AFTYPES_H__
#include <freetype/ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
FT_BEGIN_HEADER
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** D E B U G G I N G *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define xxAF_USE_WARPER /* only define to use warp hinting */
#define xxAF_DEBUG
#ifdef AF_DEBUG
#include <stdio.h>
#define AF_LOG( x ) do { if ( _af_debug ) printf x; } while ( 0 )
extern int _af_debug;
extern int _af_debug_disable_horz_hints;
extern int _af_debug_disable_vert_hints;
extern int _af_debug_disable_blue_hints;
extern void* _af_debug_hints;
#else /* !AF_DEBUG */
#define AF_LOG( x ) do {} while ( 0 ) /* nothing */
#endif /* !AF_DEBUG */
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** U T I L I T Y S T U F F *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
typedef struct AF_WidthRec_
{
FT_Pos org; /* original position/width in font units */
FT_Pos cur; /* current/scaled position/width in device sub-pixels */
FT_Pos fit; /* current/fitted position/width in device sub-pixels */
} AF_WidthRec, *AF_Width;
FT_LOCAL( void )
af_sort_pos( FT_UInt count,
FT_Pos* table );
FT_LOCAL( void )
af_sort_widths( FT_UInt count,
AF_Width widths );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** A N G L E T Y P E S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/*
* The auto-fitter doesn't need a very high angular accuracy;
* this allows us to speed up some computations considerably with a
* light Cordic algorithm (see afangles.c).
*/
typedef FT_Int AF_Angle;
#define AF_ANGLE_PI 256
#define AF_ANGLE_2PI ( AF_ANGLE_PI * 2 )
#define AF_ANGLE_PI2 ( AF_ANGLE_PI / 2 )
#define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 )
#if 0
/*
* compute the angle of a given 2-D vector
*/
FT_LOCAL( AF_Angle )
af_angle_atan( FT_Pos dx,
FT_Pos dy );
/*
* compute `angle2 - angle1'; the result is always within
* the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1]
*/
FT_LOCAL( AF_Angle )
af_angle_diff( AF_Angle angle1,
AF_Angle angle2 );
#endif /* 0 */
#define AF_ANGLE_DIFF( result, angle1, angle2 ) \
FT_BEGIN_STMNT \
AF_Angle _delta = (angle2) - (angle1); \
\
\
_delta %= AF_ANGLE_2PI; \
if ( _delta < 0 ) \
_delta += AF_ANGLE_2PI; \
\
if ( _delta > AF_ANGLE_PI ) \
_delta -= AF_ANGLE_2PI; \
\
result = _delta; \
FT_END_STMNT
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** O U T L I N E S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* opaque handle to glyph-specific hints -- see `afhints.h' for more
* details
*/
typedef struct AF_GlyphHintsRec_* AF_GlyphHints;
/* This structure is used to model an input glyph outline to
* the auto-hinter. The latter will set the `hints' field
* depending on the glyph's script.
*/
typedef struct AF_OutlineRec_
{
FT_Face face;
FT_Outline outline;
FT_UInt outline_resolution;
FT_Int advance;
FT_UInt metrics_resolution;
AF_GlyphHints hints;
} AF_OutlineRec;
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** S C A L E R S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/*
* A scaler models the target pixel device that will receive the
* auto-hinted glyph image.
*/
typedef enum AF_ScalerFlags_
{
AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */
AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */
AF_SCALER_FLAG_NO_ADVANCE = 4 /* disable advance hinting */
} AF_ScalerFlags;
typedef struct AF_ScalerRec_
{
FT_Face face; /* source font face */
FT_Fixed x_scale; /* from font units to 1/64th device pixels */
FT_Fixed y_scale; /* from font units to 1/64th device pixels */
FT_Pos x_delta; /* in 1/64th device pixels */
FT_Pos y_delta; /* in 1/64th device pixels */
FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc. */
FT_UInt32 flags; /* additional control flags, see above */
} AF_ScalerRec, *AF_Scaler;
#define AF_SCALER_EQUAL_SCALES( a, b ) \
( (a)->x_scale == (b)->x_scale && \
(a)->y_scale == (b)->y_scale && \
(a)->x_delta == (b)->x_delta && \
(a)->y_delta == (b)->y_delta )
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** S C R I P T S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/*
* The list of know scripts. Each different script corresponds to the
* following information:
*
* - A set of Unicode ranges to test whether the face supports the
* script.
*
* - A specific global analyzer that will compute global metrics
* specific to the script.
*
* - A specific glyph analyzer that will compute segments and
* edges for each glyph covered by the script.
*
* - A specific grid-fitting algorithm that will distort the
* scaled glyph outline according to the results of the glyph
* analyzer.
*
* Note that a given analyzer and/or grid-fitting algorithm can be
* used by more than one script.
*/
typedef enum AF_Script_
{
AF_SCRIPT_NONE = 0,
AF_SCRIPT_LATIN = 1,
AF_SCRIPT_CJK = 2,
AF_SCRIPT_INDIC = 3,
#ifdef FT_OPTION_AUTOFIT2
AF_SCRIPT_LATIN2,
#endif
/* add new scripts here. Don't forget to update the list in */
/* `afglobal.c'. */
AF_SCRIPT_MAX /* do not remove */
} AF_Script;
typedef struct AF_ScriptClassRec_ const* AF_ScriptClass;
typedef struct AF_ScriptMetricsRec_
{
AF_ScriptClass clazz;
AF_ScalerRec scaler;
} AF_ScriptMetricsRec, *AF_ScriptMetrics;
/* This function parses an FT_Face to compute global metrics for
* a specific script.
*/
typedef FT_Error
(*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics,
FT_Face face );
typedef void
(*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics,
AF_Scaler scaler );
typedef void
(*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics );
typedef FT_Error
(*AF_Script_InitHintsFunc)( AF_GlyphHints hints,
AF_ScriptMetrics metrics );
typedef void
(*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints,
FT_Outline* outline,
AF_ScriptMetrics metrics );
typedef struct AF_Script_UniRangeRec_
{
FT_UInt32 first;
FT_UInt32 last;
} AF_Script_UniRangeRec;
typedef const AF_Script_UniRangeRec *AF_Script_UniRange;
typedef struct AF_ScriptClassRec_
{
AF_Script script;
AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */
FT_UInt script_metrics_size;
AF_Script_InitMetricsFunc script_metrics_init;
AF_Script_ScaleMetricsFunc script_metrics_scale;
AF_Script_DoneMetricsFunc script_metrics_done;
AF_Script_InitHintsFunc script_hints_init;
AF_Script_ApplyHintsFunc script_hints_apply;
} AF_ScriptClassRec;
/* */
FT_END_HEADER
#endif /* __AFTYPES_H__ */
/* END */

View File

@ -0,0 +1,338 @@
/***************************************************************************/
/* */
/* afwarp.c */
/* */
/* Auto-fitter warping algorithm (body). */
/* */
/* Copyright 2006, 2007 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 "afwarp.h"
#ifdef AF_USE_WARPER
#if 1
static const AF_WarpScore
af_warper_weights[64] =
{
35, 32, 30, 25, 20, 15, 12, 10, 5, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, -1, -2, -5, -8,-10,-10,-20,-20,-30,-30,
-30,-30,-20,-20,-10,-10, -8, -5, -2, -1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 5, 10, 12, 15, 20, 25, 30, 32,
};
#else
static const AF_WarpScore
af_warper_weights[64] =
{
30, 20, 10, 5, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, -1, -2, -2, -5, -5,-10,-10,-15,-20,
-20,-15,-15,-10,-10, -5, -5, -2, -2, -1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4, 5, 10, 20,
};
#endif
static void
af_warper_compute_line_best( AF_Warper warper,
FT_Fixed scale,
FT_Pos delta,
FT_Pos xx1,
FT_Pos xx2,
AF_WarpScore base_distort,
AF_Segment segments,
FT_UInt num_segments )
{
FT_Int idx_min, idx_max, idx0;
FT_UInt nn;
AF_WarpScore scores[65];
for ( nn = 0; nn < 65; nn++ )
scores[nn] = 0;
idx0 = xx1 - warper->t1;
/* compute minimum and maximum indices */
{
FT_Pos xx1min = warper->x1min;
FT_Pos xx1max = warper->x1max;
FT_Pos w = xx2 - xx1;
if ( xx1min + w < warper->x2min )
xx1min = warper->x2min - w;
xx1max = warper->x1max;
if ( xx1max + w > warper->x2max )
xx1max = warper->x2max - w;
idx_min = xx1min - warper->t1;
idx_max = xx1max - warper->t1;
if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 )
{
AF_LOG(( "invalid indices:\n"
" min=%d max=%d, xx1=%ld xx2=%ld,\n"
" x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n",
idx_min, idx_max, xx1, xx2,
warper->x1min, warper->x1max,
warper->x2min, warper->x2max ));
return;
}
}
for ( nn = 0; nn < num_segments; nn++ )
{
FT_Pos len = segments[nn].max_coord - segments[nn].min_coord;
FT_Pos y0 = FT_MulFix( segments[nn].pos, scale ) + delta;
FT_Pos y = y0 + ( idx_min - idx0 );
FT_Int idx;
for ( idx = idx_min; idx <= idx_max; idx++, y++ )
scores[idx] += af_warper_weights[y & 63] * len;
}
/* find best score */
{
FT_Int idx;
for ( idx = idx_min; idx <= idx_max; idx++ )
{
AF_WarpScore score = scores[idx];
AF_WarpScore distort = base_distort + ( idx - idx0 );
if ( score > warper->best_score ||
( score == warper->best_score &&
distort < warper->best_distort ) )
{
warper->best_score = score;
warper->best_distort = distort;
warper->best_scale = scale;
warper->best_delta = delta + ( idx - idx0 );
}
}
}
}
FT_LOCAL_DEF( void )
af_warper_compute( AF_Warper warper,
AF_GlyphHints hints,
AF_Dimension dim,
FT_Fixed *a_scale,
FT_Pos *a_delta )
{
AF_AxisHints axis;
AF_Point points;
FT_Fixed org_scale;
FT_Pos org_delta;
FT_UInt nn, num_points, num_segments;
FT_Int X1, X2;
FT_Int w;
AF_WarpScore base_distort;
AF_Segment segments;
/* get original scaling transformation */
if ( dim == AF_DIMENSION_VERT )
{
org_scale = hints->y_scale;
org_delta = hints->y_delta;
}
else
{
org_scale = hints->x_scale;
org_delta = hints->x_delta;
}
warper->best_scale = org_scale;
warper->best_delta = org_delta;
warper->best_score = INT_MIN;
warper->best_distort = 0;
axis = &hints->axis[dim];
segments = axis->segments;
num_segments = axis->num_segments;
points = hints->points;
num_points = hints->num_points;
*a_scale = org_scale;
*a_delta = org_delta;
/* get X1 and X2, minimum and maximum in original coordinates */
if ( num_segments < 1 )
return;
#if 1
X1 = X2 = points[0].fx;
for ( nn = 1; nn < num_points; nn++ )
{
FT_Int X = points[nn].fx;
if ( X < X1 )
X1 = X;
if ( X > X2 )
X2 = X;
}
#else
X1 = X2 = segments[0].pos;
for ( nn = 1; nn < num_segments; nn++ )
{
FT_Int X = segments[nn].pos;
if ( X < X1 )
X1 = X;
if ( X > X2 )
X2 = X;
}
#endif
if ( X1 >= X2 )
return;
warper->x1 = FT_MulFix( X1, org_scale ) + org_delta;
warper->x2 = FT_MulFix( X2, org_scale ) + org_delta;
warper->t1 = AF_WARPER_FLOOR( warper->x1 );
warper->t2 = AF_WARPER_CEIL( warper->x2 );
warper->x1min = warper->x1 & ~31;
warper->x1max = warper->x1min + 32;
warper->x2min = warper->x2 & ~31;
warper->x2max = warper->x2min + 32;
if ( warper->x1max > warper->x2 )
warper->x1max = warper->x2;
if ( warper->x2min < warper->x1 )
warper->x2min = warper->x1;
warper->w0 = warper->x2 - warper->x1;
if ( warper->w0 <= 64 )
{
warper->x1max = warper->x1;
warper->x2min = warper->x2;
}
warper->wmin = warper->x2min - warper->x1max;
warper->wmax = warper->x2max - warper->x1min;
#if 1
{
int margin = 16;
if ( warper->w0 <= 128 )
{
margin = 8;
if ( warper->w0 <= 96 )
margin = 4;
}
if ( warper->wmin < warper->w0 - margin )
warper->wmin = warper->w0 - margin;
if ( warper->wmax > warper->w0 + margin )
warper->wmax = warper->w0 + margin;
}
if ( warper->wmin < warper->w0 * 3 / 4 )
warper->wmin = warper->w0 * 3 / 4;
if ( warper->wmax > warper->w0 * 5 / 4 )
warper->wmax = warper->w0 * 5 / 4;
#else
/* no scaling, just translation */
warper->wmin = warper->wmax = warper->w0;
#endif
for ( w = warper->wmin; w <= warper->wmax; w++ )
{
FT_Fixed new_scale;
FT_Pos new_delta;
FT_Pos xx1, xx2;
xx1 = warper->x1;
xx2 = warper->x2;
if ( w >= warper->w0 )
{
xx1 -= w - warper->w0;
if ( xx1 < warper->x1min )
{
xx2 += warper->x1min - xx1;
xx1 = warper->x1min;
}
}
else
{
xx1 -= w - warper->w0;
if ( xx1 > warper->x1max )
{
xx2 -= xx1 - warper->x1max;
xx1 = warper->x1max;
}
}
if ( xx1 < warper->x1 )
base_distort = warper->x1 - xx1;
else
base_distort = xx1 - warper->x1;
if ( xx2 < warper->x2 )
base_distort += warper->x2 - xx2;
else
base_distort += xx2 - warper->x2;
base_distort *= 10;
new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 );
new_delta = xx1 - FT_MulFix( X1, new_scale );
af_warper_compute_line_best( warper, new_scale, new_delta, xx1, xx2,
base_distort,
segments, num_segments );
}
{
FT_Fixed best_scale = warper->best_scale;
FT_Pos best_delta = warper->best_delta;
hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale )
+ best_delta;
hints->xmax_delta = FT_MulFix( X2, best_scale - org_scale )
+ best_delta;
*a_scale = best_scale;
*a_delta = best_delta;
}
}
#else /* !AF_USE_WARPER */
char af_warper_dummy = 0; /* make compiler happy */
#endif /* !AF_USE_WARPER */
/* END */

View File

@ -0,0 +1,64 @@
/***************************************************************************/
/* */
/* afwarp.h */
/* */
/* Auto-fitter warping algorithm (specification). */
/* */
/* Copyright 2006, 2007 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 __AFWARP_H__
#define __AFWARP_H__
#include "afhints.h"
FT_BEGIN_HEADER
#define AF_WARPER_SCALE
#define AF_WARPER_FLOOR( x ) ( (x) & ~63 )
#define AF_WARPER_CEIL( x ) AF_WARPER_FLOOR( (x) + 63 )
typedef FT_Int32 AF_WarpScore;
typedef struct AF_WarperRec_
{
FT_Pos x1, x2;
FT_Pos t1, t2;
FT_Pos x1min, x1max;
FT_Pos x2min, x2max;
FT_Pos w0, wmin, wmax;
FT_Fixed best_scale;
FT_Pos best_delta;
AF_WarpScore best_score;
AF_WarpScore best_distort;
} AF_WarperRec, *AF_Warper;
FT_LOCAL( void )
af_warper_compute( AF_Warper warper,
AF_GlyphHints hints,
AF_Dimension dim,
FT_Fixed *a_scale,
FT_Fixed *a_delta );
FT_END_HEADER
#endif /* __AFWARP_H__ */
/* END */

View File

@ -0,0 +1,40 @@
/***************************************************************************/
/* */
/* autofit.c */
/* */
/* Auto-fitter module (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007 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 <freetype/ft2build.h>
#include "afangles.c"
#include "afglobal.c"
#include "afhints.c"
#include "afdummy.c"
#include "aflatin.c"
#ifdef FT_OPTION_AUTOFIT2
#include "aflatin2.c"
#endif
#include "afcjk.c"
#include "afindic.c"
#include "afloader.c"
#include "afmodule.c"
#ifdef AF_USE_WARPER
#include "afwarp.c"
#endif
/* END */

View File

@ -0,0 +1,127 @@
#include <freetype/ft2build.h>
#include FT_ADVANCES_H
#include FT_INTERNAL_OBJECTS_H
static FT_Error
_ft_face_scale_advances( FT_Face face,
FT_Fixed* advances,
FT_UInt count,
FT_UInt flags )
{
FT_Fixed scale;
FT_UInt nn;
if ( (flags & FT_LOAD_NO_SCALE) )
return FT_Err_Ok;
if ( face->size == NULL )
return FT_Err_Invalid_Size_Handle;
if ( !(flags & FT_LOAD_VERTICAL_LAYOUT) )
scale = face->size->metrics.x_scale;
else
scale = face->size->metrics.y_scale;
/* this must be the same computation than to get linearHori/VertAdvance
* (see FT_Load_Glyph() implementation in src/base/ftobjs.c */
for (nn = 0; nn < count; nn++)
advances[nn] = FT_MulDiv( advances[nn], scale, 64 );
return 0;
}
/* at the moment, we can perform fast advance retrieval only in
the following cases:
- unscaled load
- unhinted load
- light-hinted load
*/
#define LOAD_ADVANCE_FAST_CHECK(flags) \
(((flags & (FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING)) != 0) || \
FT_LOAD_TARGET_MODE(flags) == FT_RENDER_MODE_LIGHT)
FT_EXPORT_DEF(FT_Error)
FT_Get_Advance( FT_Face face,
FT_UInt gindex,
FT_UInt flags,
FT_Fixed *padvance )
{
FT_Face_GetAdvancesFunc func;
if ( !face )
return FT_Err_Invalid_Face_Handle;
if (gindex >= (FT_UInt) face->num_glyphs )
return FT_Err_Invalid_Glyph_Index;
func = face->driver->clazz->get_advances;
if (func != NULL && LOAD_ADVANCE_FAST_CHECK(flags))
{
FT_Error error;
error = func( face, gindex, 1, flags, padvance );
if (!error)
return _ft_face_scale_advances( face, padvance, 1, flags );
if (error != FT_Err_Unimplemented_Feature)
return error;
}
return FT_Get_Advances( face, gindex, 1, flags, padvance );
}
FT_EXPORT_DEF(FT_Error)
FT_Get_Advances( FT_Face face,
FT_UInt start,
FT_UInt count,
FT_UInt flags,
FT_Fixed *padvances )
{
FT_Face_GetAdvancesFunc func;
FT_UInt num, end, nn;
FT_Error error = 0;
if ( !face )
return FT_Err_Invalid_Face_Handle;
num = (FT_UInt) face->num_glyphs;
end = start + count;
if (start >= num || end < start || end > num)
return FT_Err_Invalid_Glyph_Index;
if (count == 0)
return FT_Err_Ok;
func = face->driver->clazz->get_advances;
if (func != NULL && LOAD_ADVANCE_FAST_CHECK(flags))
{
error = func( face, start, count, flags, padvances );
if (!error) goto Exit;
if (error != FT_Err_Unimplemented_Feature)
return error;
}
error = 0;
if ((flags & FT_ADVANCE_FLAG_FAST_ONLY) != 0)
return FT_Err_Unimplemented_Feature;
flags |= FT_LOAD_ADVANCE_ONLY;
for (nn = 0; nn < count; nn++)
{
error = FT_Load_Glyph( face, start+nn, flags );
if (error) break;
padvances[nn] = (flags & FT_LOAD_VERTICAL_LAYOUT)
? face->glyph->advance.x
: face->glyph->advance.y;
}
if (error) return error;
Exit:
return _ft_face_scale_advances( face, padvances, count, flags );
}

View File

@ -0,0 +1,121 @@
/***************************************************************************/
/* */
/* ftapi.c */
/* */
/* The FreeType compatibility functions (body). */
/* */
/* Copyright 2002 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 <freetype/ft2build.h>
#include FT_LIST_H
#include FT_OUTLINE_H
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TABLES_H
#include FT_OUTLINE_H
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** ****/
/**** C O M P A T I B I L I T Y ****/
/**** ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* backwards compatibility API */
FT_BASE_DEF( void )
FT_New_Memory_Stream( FT_Library library,
FT_Byte* base,
FT_ULong size,
FT_Stream stream )
{
FT_UNUSED( library );
FT_Stream_OpenMemory( stream, base, size );
}
FT_BASE_DEF( FT_Error )
FT_Seek_Stream( FT_Stream stream,
FT_ULong pos )
{
return FT_Stream_Seek( stream, pos );
}
FT_BASE_DEF( FT_Error )
FT_Skip_Stream( FT_Stream stream,
FT_Long distance )
{
return FT_Stream_Skip( stream, distance );
}
FT_BASE_DEF( FT_Error )
FT_Read_Stream( FT_Stream stream,
FT_Byte* buffer,
FT_ULong count )
{
return FT_Stream_Read( stream, buffer, count );
}
FT_BASE_DEF( FT_Error )
FT_Read_Stream_At( FT_Stream stream,
FT_ULong pos,
FT_Byte* buffer,
FT_ULong count )
{
return FT_Stream_ReadAt( stream, pos, buffer, count );
}
FT_BASE_DEF( FT_Error )
FT_Extract_Frame( FT_Stream stream,
FT_ULong count,
FT_Byte** pbytes )
{
return FT_Stream_ExtractFrame( stream, count, pbytes );
}
FT_BASE_DEF( void )
FT_Release_Frame( FT_Stream stream,
FT_Byte** pbytes )
{
FT_Stream_ReleaseFrame( stream, pbytes );
}
FT_BASE_DEF( FT_Error )
FT_Access_Frame( FT_Stream stream,
FT_ULong count )
{
return FT_Stream_EnterFrame( stream, count );
}
FT_BASE_DEF( void )
FT_Forget_Frame( FT_Stream stream )
{
FT_Stream_ExitFrame( stream );
}
/* END */

View File

@ -0,0 +1,38 @@
/***************************************************************************/
/* */
/* ftbase.c */
/* */
/* Single object library component (body only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 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 <freetype/ft2build.h>
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include "ftcalc.c"
#include "ftdbgmem.c"
#include "ftgloadr.c"
#include "ftnames.c"
#include "ftobjs.c"
#include "ftoutln.c"
#include "ftrfork.c"
#include "ftstream.c"
#include "fttrigon.c"
#include "ftutil.c"
#if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON )
#include "ftmac.c"
#endif
/* END */

View File

@ -0,0 +1,659 @@
/***************************************************************************/
/* */
/* ftbbox.c */
/* */
/* FreeType bbox computation (body). */
/* */
/* Copyright 1996-2001, 2002, 2004, 2006 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 has a _single_ role: to compute exact outline bounding */
/* boxes. */
/* */
/*************************************************************************/
#include <freetype/ft2build.h>
#include FT_BBOX_H
#include FT_IMAGE_H
#include FT_OUTLINE_H
#include FT_INTERNAL_CALC_H
typedef struct TBBox_Rec_
{
FT_Vector last;
FT_BBox bbox;
} TBBox_Rec;
/*************************************************************************/
/* */
/* <Function> */
/* BBox_Move_To */
/* */
/* <Description> */
/* This function is used as a `move_to' and `line_to' emitter during */
/* FT_Outline_Decompose(). It simply records the destination point */
/* in `user->last'; no further computations are necessary since we */
/* use the cbox as the starting bbox which must be refined. */
/* */
/* <Input> */
/* to :: A pointer to the destination vector. */
/* */
/* <InOut> */
/* user :: A pointer to the current walk context. */
/* */
/* <Return> */
/* Always 0. Needed for the interface only. */
/* */
static int
BBox_Move_To( FT_Vector* to,
TBBox_Rec* user )
{
user->last = *to;
return 0;
}
#define CHECK_X( p, bbox ) \
( p->x < bbox.xMin || p->x > bbox.xMax )
#define CHECK_Y( p, bbox ) \
( p->y < bbox.yMin || p->y > bbox.yMax )
/*************************************************************************/
/* */
/* <Function> */
/* BBox_Conic_Check */
/* */
/* <Description> */
/* Finds the extrema of a 1-dimensional conic Bezier curve and update */
/* a bounding range. This version uses direct computation, as it */
/* doesn't need square roots. */
/* */
/* <Input> */
/* y1 :: The start coordinate. */
/* */
/* y2 :: The coordinate of the control point. */
/* */
/* y3 :: The end coordinate. */
/* */
/* <InOut> */
/* min :: The address of the current minimum. */
/* */
/* max :: The address of the current maximum. */
/* */
static void
BBox_Conic_Check( FT_Pos y1,
FT_Pos y2,
FT_Pos y3,
FT_Pos* min,
FT_Pos* max )
{
if ( y1 <= y3 && y2 == y1 ) /* flat arc */
goto Suite;
if ( y1 < y3 )
{
if ( y2 >= y1 && y2 <= y3 ) /* ascending arc */
goto Suite;
}
else
{
if ( y2 >= y3 && y2 <= y1 ) /* descending arc */
{
y2 = y1;
y1 = y3;
y3 = y2;
goto Suite;
}
}
y1 = y3 = y1 - FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 );
Suite:
if ( y1 < *min ) *min = y1;
if ( y3 > *max ) *max = y3;
}
/*************************************************************************/
/* */
/* <Function> */
/* BBox_Conic_To */
/* */
/* <Description> */
/* This function is used as a `conic_to' emitter during */
/* FT_Raster_Decompose(). It checks a conic Bezier curve with the */
/* current bounding box, and computes its extrema if necessary to */
/* update it. */
/* */
/* <Input> */
/* control :: A pointer to a control point. */
/* */
/* to :: A pointer to the destination vector. */
/* */
/* <InOut> */
/* user :: The address of the current walk context. */
/* */
/* <Return> */
/* Always 0. Needed for the interface only. */
/* */
/* <Note> */
/* In the case of a non-monotonous arc, we compute directly the */
/* extremum coordinates, as it is sufficiently fast. */
/* */
static int
BBox_Conic_To( FT_Vector* control,
FT_Vector* to,
TBBox_Rec* user )
{
/* we don't need to check `to' since it is always an `on' point, thus */
/* within the bbox */
if ( CHECK_X( control, user->bbox ) )
BBox_Conic_Check( user->last.x,
control->x,
to->x,
&user->bbox.xMin,
&user->bbox.xMax );
if ( CHECK_Y( control, user->bbox ) )
BBox_Conic_Check( user->last.y,
control->y,
to->y,
&user->bbox.yMin,
&user->bbox.yMax );
user->last = *to;
return 0;
}
/*************************************************************************/
/* */
/* <Function> */
/* BBox_Cubic_Check */
/* */
/* <Description> */
/* Finds the extrema of a 1-dimensional cubic Bezier curve and */
/* updates a bounding range. This version uses splitting because we */
/* don't want to use square roots and extra accuracy. */
/* */
/* <Input> */
/* p1 :: The start coordinate. */
/* */
/* p2 :: The coordinate of the first control point. */
/* */
/* p3 :: The coordinate of the second control point. */
/* */
/* p4 :: The end coordinate. */
/* */
/* <InOut> */
/* min :: The address of the current minimum. */
/* */
/* max :: The address of the current maximum. */
/* */
#if 0
static void
BBox_Cubic_Check( FT_Pos p1,
FT_Pos p2,
FT_Pos p3,
FT_Pos p4,
FT_Pos* min,
FT_Pos* max )
{
FT_Pos stack[32*3 + 1], *arc;
arc = stack;
arc[0] = p1;
arc[1] = p2;
arc[2] = p3;
arc[3] = p4;
do
{
FT_Pos y1 = arc[0];
FT_Pos y2 = arc[1];
FT_Pos y3 = arc[2];
FT_Pos y4 = arc[3];
if ( y1 == y4 )
{
if ( y1 == y2 && y1 == y3 ) /* flat */
goto Test;
}
else if ( y1 < y4 )
{
if ( y2 >= y1 && y2 <= y4 && y3 >= y1 && y3 <= y4 ) /* ascending */
goto Test;
}
else
{
if ( y2 >= y4 && y2 <= y1 && y3 >= y4 && y3 <= y1 ) /* descending */
{
y2 = y1;
y1 = y4;
y4 = y2;
goto Test;
}
}
/* unknown direction -- split the arc in two */
arc[6] = y4;
arc[1] = y1 = ( y1 + y2 ) / 2;
arc[5] = y4 = ( y4 + y3 ) / 2;
y2 = ( y2 + y3 ) / 2;
arc[2] = y1 = ( y1 + y2 ) / 2;
arc[4] = y4 = ( y4 + y2 ) / 2;
arc[3] = ( y1 + y4 ) / 2;
arc += 3;
goto Suite;
Test:
if ( y1 < *min ) *min = y1;
if ( y4 > *max ) *max = y4;
arc -= 3;
Suite:
;
} while ( arc >= stack );
}
#else
static void
test_cubic_extrema( FT_Pos y1,
FT_Pos y2,
FT_Pos y3,
FT_Pos y4,
FT_Fixed u,
FT_Pos* min,
FT_Pos* max )
{
/* FT_Pos a = y4 - 3*y3 + 3*y2 - y1; */
FT_Pos b = y3 - 2*y2 + y1;
FT_Pos c = y2 - y1;
FT_Pos d = y1;
FT_Pos y;
FT_Fixed uu;
FT_UNUSED ( y4 );
/* The polynomial is */
/* */
/* P(x) = a*x^3 + 3b*x^2 + 3c*x + d , */
/* */
/* dP/dx = 3a*x^2 + 6b*x + 3c . */
/* */
/* However, we also have */
/* */
/* dP/dx(u) = 0 , */
/* */
/* which implies by subtraction that */
/* */
/* P(u) = b*u^2 + 2c*u + d . */
if ( u > 0 && u < 0x10000L )
{
uu = FT_MulFix( u, u );
y = d + FT_MulFix( c, 2*u ) + FT_MulFix( b, uu );
if ( y < *min ) *min = y;
if ( y > *max ) *max = y;
}
}
static void
BBox_Cubic_Check( FT_Pos y1,
FT_Pos y2,
FT_Pos y3,
FT_Pos y4,
FT_Pos* min,
FT_Pos* max )
{
/* always compare first and last points */
if ( y1 < *min ) *min = y1;
else if ( y1 > *max ) *max = y1;
if ( y4 < *min ) *min = y4;
else if ( y4 > *max ) *max = y4;
/* now, try to see if there are split points here */
if ( y1 <= y4 )
{
/* flat or ascending arc test */
if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 )
return;
}
else /* y1 > y4 */
{
/* descending arc test */
if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 )
return;
}
/* There are some split points. Find them. */
{
FT_Pos a = y4 - 3*y3 + 3*y2 - y1;
FT_Pos b = y3 - 2*y2 + y1;
FT_Pos c = y2 - y1;
FT_Pos d;
FT_Fixed t;
/* We need to solve `ax^2+2bx+c' here, without floating points! */
/* The trick is to normalize to a different representation in order */
/* to use our 16.16 fixed point routines. */
/* */
/* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */
/* These values must fit into a single 16.16 value. */
/* */
/* We normalize a, b, and c to `8.16' fixed float values to ensure */
/* that its product is held in a `16.16' value. */
{
FT_ULong t1, t2;
int shift = 0;
/* The following computation is based on the fact that for */
/* any value `y', if `n' is the position of the most */
/* significant bit of `abs(y)' (starting from 0 for the */
/* least significant bit), then `y' is in the range */
/* */
/* -2^n..2^n-1 */
/* */
/* We want to shift `a', `b', and `c' concurrently in order */
/* to ensure that they all fit in 8.16 values, which maps */
/* to the integer range `-2^23..2^23-1'. */
/* */
/* Necessarily, we need to shift `a', `b', and `c' so that */
/* the most significant bit of its absolute values is at */
/* _most_ at position 23. */
/* */
/* We begin by computing `t1' as the bitwise `OR' of the */
/* absolute values of `a', `b', `c'. */
t1 = (FT_ULong)( ( a >= 0 ) ? a : -a );
t2 = (FT_ULong)( ( b >= 0 ) ? b : -b );
t1 |= t2;
t2 = (FT_ULong)( ( c >= 0 ) ? c : -c );
t1 |= t2;
/* Now we can be sure that the most significant bit of `t1' */
/* is the most significant bit of either `a', `b', or `c', */
/* depending on the greatest integer range of the particular */
/* variable. */
/* */
/* Next, we compute the `shift', by shifting `t1' as many */
/* times as necessary to move its MSB to position 23. This */
/* corresponds to a value of `t1' that is in the range */
/* 0x40_0000..0x7F_FFFF. */
/* */
/* Finally, we shift `a', `b', and `c' by the same amount. */
/* This ensures that all values are now in the range */
/* -2^23..2^23, i.e., they are now expressed as 8.16 */
/* fixed-float numbers. This also means that we are using */
/* 24 bits of precision to compute the zeros, independently */
/* of the range of the original polynomial coefficients. */
/* */
/* This algorithm should ensure reasonably accurate values */
/* for the zeros. Note that they are only expressed with */
/* 16 bits when computing the extrema (the zeros need to */
/* be in 0..1 exclusive to be considered part of the arc). */
if ( t1 == 0 ) /* all coefficients are 0! */
return;
if ( t1 > 0x7FFFFFUL )
{
do
{
shift++;
t1 >>= 1;
} while ( t1 > 0x7FFFFFUL );
/* this loses some bits of precision, but we use 24 of them */
/* for the computation anyway */
a >>= shift;
b >>= shift;
c >>= shift;
}
else if ( t1 < 0x400000UL )
{
do
{
shift++;
t1 <<= 1;
} while ( t1 < 0x400000UL );
a <<= shift;
b <<= shift;
c <<= shift;
}
}
/* handle a == 0 */
if ( a == 0 )
{
if ( b != 0 )
{
t = - FT_DivFix( c, b ) / 2;
test_cubic_extrema( y1, y2, y3, y4, t, min, max );
}
}
else
{
/* solve the equation now */
d = FT_MulFix( b, b ) - FT_MulFix( a, c );
if ( d < 0 )
return;
if ( d == 0 )
{
/* there is a single split point at -b/a */
t = - FT_DivFix( b, a );
test_cubic_extrema( y1, y2, y3, y4, t, min, max );
}
else
{
/* there are two solutions; we need to filter them */
d = FT_SqrtFixed( (FT_Int32)d );
t = - FT_DivFix( b - d, a );
test_cubic_extrema( y1, y2, y3, y4, t, min, max );
t = - FT_DivFix( b + d, a );
test_cubic_extrema( y1, y2, y3, y4, t, min, max );
}
}
}
}
#endif
/*************************************************************************/
/* */
/* <Function> */
/* BBox_Cubic_To */
/* */
/* <Description> */
/* This function is used as a `cubic_to' emitter during */
/* FT_Raster_Decompose(). It checks a cubic Bezier curve with the */
/* current bounding box, and computes its extrema if necessary to */
/* update it. */
/* */
/* <Input> */
/* control1 :: A pointer to the first control point. */
/* */
/* control2 :: A pointer to the second control point. */
/* */
/* to :: A pointer to the destination vector. */
/* */
/* <InOut> */
/* user :: The address of the current walk context. */
/* */
/* <Return> */
/* Always 0. Needed for the interface only. */
/* */
/* <Note> */
/* In the case of a non-monotonous arc, we don't compute directly */
/* extremum coordinates, we subdivide instead. */
/* */
static int
BBox_Cubic_To( FT_Vector* control1,
FT_Vector* control2,
FT_Vector* to,
TBBox_Rec* user )
{
/* we don't need to check `to' since it is always an `on' point, thus */
/* within the bbox */
if ( CHECK_X( control1, user->bbox ) ||
CHECK_X( control2, user->bbox ) )
BBox_Cubic_Check( user->last.x,
control1->x,
control2->x,
to->x,
&user->bbox.xMin,
&user->bbox.xMax );
if ( CHECK_Y( control1, user->bbox ) ||
CHECK_Y( control2, user->bbox ) )
BBox_Cubic_Check( user->last.y,
control1->y,
control2->y,
to->y,
&user->bbox.yMin,
&user->bbox.yMax );
user->last = *to;
return 0;
}
/* documentation is in ftbbox.h */
FT_EXPORT_DEF( FT_Error )
FT_Outline_Get_BBox( FT_Outline* outline,
FT_BBox *abbox )
{
FT_BBox cbox;
FT_BBox bbox;
FT_Vector* vec;
FT_UShort n;
if ( !abbox )
return FT_Err_Invalid_Argument;
if ( !outline )
return FT_Err_Invalid_Outline;
/* if outline is empty, return (0,0,0,0) */
if ( outline->n_points == 0 || outline->n_contours <= 0 )
{
abbox->xMin = abbox->xMax = 0;
abbox->yMin = abbox->yMax = 0;
return 0;
}
/* We compute the control box as well as the bounding box of */
/* all `on' points in the outline. Then, if the two boxes */
/* coincide, we exit immediately. */
vec = outline->points;
bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x;
bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y;
vec++;
for ( n = 1; n < outline->n_points; n++ )
{
FT_Pos x = vec->x;
FT_Pos y = vec->y;
/* update control box */
if ( x < cbox.xMin ) cbox.xMin = x;
if ( x > cbox.xMax ) cbox.xMax = x;
if ( y < cbox.yMin ) cbox.yMin = y;
if ( y > cbox.yMax ) cbox.yMax = y;
if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON )
{
/* update bbox for `on' points only */
if ( x < bbox.xMin ) bbox.xMin = x;
if ( x > bbox.xMax ) bbox.xMax = x;
if ( y < bbox.yMin ) bbox.yMin = y;
if ( y > bbox.yMax ) bbox.yMax = y;
}
vec++;
}
/* test two boxes for equality */
if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax ||
cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax )
{
/* the two boxes are different, now walk over the outline to */
/* get the Bezier arc extrema. */
static const FT_Outline_Funcs bbox_interface =
{
(FT_Outline_MoveTo_Func) BBox_Move_To,
(FT_Outline_LineTo_Func) BBox_Move_To,
(FT_Outline_ConicTo_Func)BBox_Conic_To,
(FT_Outline_CubicTo_Func)BBox_Cubic_To,
0, 0
};
FT_Error error;
TBBox_Rec user;
user.bbox = bbox;
error = FT_Outline_Decompose( outline, &bbox_interface, &user );
if ( error )
return error;
*abbox = user.bbox;
}
else
*abbox = bbox;
return FT_Err_Ok;
}
/* END */

View File

@ -0,0 +1,630 @@
/***************************************************************************/
/* */
/* ftbitmap.c */
/* */
/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */
/* bitmaps into 8bpp format (body). */
/* */
/* Copyright 2004, 2005, 2006, 2007 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 <freetype/ft2build.h>
#include FT_BITMAP_H
#include FT_INTERNAL_OBJECTS_H
static
const FT_Bitmap null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 };
/* documentation is in ftbitmap.h */
FT_EXPORT_DEF( void )
FT_Bitmap_New( FT_Bitmap *abitmap )
{
*abitmap = null_bitmap;
}
/* documentation is in ftbitmap.h */
FT_EXPORT_DEF( FT_Error )
FT_Bitmap_Copy( FT_Library library,
const FT_Bitmap *source,
FT_Bitmap *target)
{
FT_Memory memory = library->memory;
FT_Error error = FT_Err_Ok;
FT_Int pitch = source->pitch;
FT_ULong size;
if ( source == target )
return FT_Err_Ok;
if ( source->buffer == NULL )
{
*target = *source;
return FT_Err_Ok;
}
if ( pitch < 0 )
pitch = -pitch;
size = (FT_ULong)( pitch * source->rows );
if ( target->buffer )
{
FT_Int target_pitch = target->pitch;
FT_ULong target_size;
if ( target_pitch < 0 )
target_pitch = -target_pitch;
target_size = (FT_ULong)( target_pitch * target->rows );
if ( target_size != size )
(void)FT_QREALLOC( target->buffer, target_size, size );
}
else
(void)FT_QALLOC( target->buffer, size );
if ( !error )
{
unsigned char *p;
p = target->buffer;
*target = *source;
target->buffer = p;
FT_MEM_COPY( target->buffer, source->buffer, size );
}
return error;
}
static FT_Error
ft_bitmap_assure_buffer( FT_Memory memory,
FT_Bitmap* bitmap,
FT_UInt xpixels,
FT_UInt ypixels )
{
FT_Error error;
int pitch;
int new_pitch;
FT_UInt bpp;
FT_Int i, width, height;
unsigned char* buffer;
width = bitmap->width;
height = bitmap->rows;
pitch = bitmap->pitch;
if ( pitch < 0 )
pitch = -pitch;
switch ( bitmap->pixel_mode )
{
case FT_PIXEL_MODE_MONO:
bpp = 1;
new_pitch = ( width + xpixels + 7 ) >> 3;
break;
case FT_PIXEL_MODE_GRAY2:
bpp = 2;
new_pitch = ( width + xpixels + 3 ) >> 2;
break;
case FT_PIXEL_MODE_GRAY4:
bpp = 4;
new_pitch = ( width + xpixels + 1 ) >> 1;
break;
case FT_PIXEL_MODE_GRAY:
case FT_PIXEL_MODE_LCD:
case FT_PIXEL_MODE_LCD_V:
bpp = 8;
new_pitch = ( width + xpixels );
break;
default:
return FT_Err_Invalid_Glyph_Format;
}
/* if no need to allocate memory */
if ( ypixels == 0 && new_pitch <= pitch )
{
/* zero the padding */
FT_Int bit_width = pitch * 8;
FT_Int bit_last = ( width + xpixels ) * bpp;
if ( bit_last < bit_width )
{
FT_Byte* line = bitmap->buffer + ( bit_last >> 3 );
FT_Byte* end = bitmap->buffer + pitch;
FT_Int shift = bit_last & 7;
FT_UInt mask = 0xFF00U >> shift;
FT_Int count = height;
for ( ; count > 0; count--, line += pitch, end += pitch )
{
FT_Byte* write = line;
if ( shift > 0 )
{
write[0] = (FT_Byte)( write[0] & mask );
write++;
}
if ( write < end )
FT_MEM_ZERO( write, end-write );
}
}
return FT_Err_Ok;
}
if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
return error;
if ( bitmap->pitch > 0 )
{
FT_Int len = ( width * bpp + 7 ) >> 3;
for ( i = 0; i < bitmap->rows; i++ )
FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
bitmap->buffer + pitch * i, len );
}
else
{
FT_Int len = ( width * bpp + 7 ) >> 3;
for ( i = 0; i < bitmap->rows; i++ )
FT_MEM_COPY( buffer + new_pitch * i,
bitmap->buffer + pitch * i, len );
}
FT_FREE( bitmap->buffer );
bitmap->buffer = buffer;
if ( bitmap->pitch < 0 )
new_pitch = -new_pitch;
/* set pitch only, width and height are left untouched */
bitmap->pitch = new_pitch;
return FT_Err_Ok;
}
/* documentation is in ftbitmap.h */
FT_EXPORT_DEF( FT_Error )
FT_Bitmap_Embolden( FT_Library library,
FT_Bitmap* bitmap,
FT_Pos xStrength,
FT_Pos yStrength )
{
FT_Error error;
unsigned char* p;
FT_Int i, x, y, pitch;
FT_Int xstr, ystr;
if ( !library )
return FT_Err_Invalid_Library_Handle;
if ( !bitmap || !bitmap->buffer )
return FT_Err_Invalid_Argument;
xstr = FT_PIX_ROUND( xStrength ) >> 6;
ystr = FT_PIX_ROUND( yStrength ) >> 6;
if ( xstr == 0 && ystr == 0 )
return FT_Err_Ok;
else if ( xstr < 0 || ystr < 0 )
return FT_Err_Invalid_Argument;
switch ( bitmap->pixel_mode )
{
case FT_PIXEL_MODE_GRAY2:
case FT_PIXEL_MODE_GRAY4:
{
FT_Bitmap tmp;
FT_Int align;
if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )
align = ( bitmap->width + xstr + 3 ) / 4;
else
align = ( bitmap->width + xstr + 1 ) / 2;
FT_Bitmap_New( &tmp );
error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
if ( error )
return error;
FT_Bitmap_Done( library, bitmap );
*bitmap = tmp;
}
break;
case FT_PIXEL_MODE_MONO:
if ( xstr > 8 )
xstr = 8;
break;
case FT_PIXEL_MODE_LCD:
xstr *= 3;
break;
case FT_PIXEL_MODE_LCD_V:
ystr *= 3;
break;
}
error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
if ( error )
return error;
pitch = bitmap->pitch;
if ( pitch > 0 )
p = bitmap->buffer + pitch * ystr;
else
{
pitch = -pitch;
p = bitmap->buffer + pitch * ( bitmap->rows - 1 );
}
/* for each row */
for ( y = 0; y < bitmap->rows ; y++ )
{
/*
* Horizontally:
*
* From the last pixel on, make each pixel or'ed with the
* `xstr' pixels before it.
*/
for ( x = pitch - 1; x >= 0; x-- )
{
unsigned char tmp;
tmp = p[x];
for ( i = 1; i <= xstr; i++ )
{
if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
{
p[x] |= tmp >> i;
/* the maximum value of 8 for `xstr' comes from here */
if ( x > 0 )
p[x] |= p[x - 1] << ( 8 - i );
#if 0
if ( p[x] == 0xff )
break;
#endif
}
else
{
if ( x - i >= 0 )
{
if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
{
p[x] = (unsigned char)(bitmap->num_grays - 1);
break;
}
else
{
p[x] = (unsigned char)(p[x] + p[x-i]);
if ( p[x] == bitmap->num_grays - 1 )
break;
}
}
else
break;
}
}
}
/*
* Vertically:
*
* Make the above `ystr' rows or'ed with it.
*/
for ( x = 1; x <= ystr; x++ )
{
unsigned char* q;
q = p - bitmap->pitch * x;
for ( i = 0; i < pitch; i++ )
q[i] |= p[i];
}
p += bitmap->pitch;
}
bitmap->width += xstr;
bitmap->rows += ystr;
return FT_Err_Ok;
}
/* documentation is in ftbitmap.h */
FT_EXPORT_DEF( FT_Error )
FT_Bitmap_Convert( FT_Library library,
const FT_Bitmap *source,
FT_Bitmap *target,
FT_Int alignment )
{
FT_Error error = FT_Err_Ok;
FT_Memory memory;
if ( !library )
return FT_Err_Invalid_Library_Handle;
memory = library->memory;
switch ( source->pixel_mode )
{
case FT_PIXEL_MODE_MONO:
case FT_PIXEL_MODE_GRAY:
case FT_PIXEL_MODE_GRAY2:
case FT_PIXEL_MODE_GRAY4:
{
FT_Int pad;
FT_Long old_size;
old_size = target->rows * target->pitch;
if ( old_size < 0 )
old_size = -old_size;
target->pixel_mode = FT_PIXEL_MODE_GRAY;
target->rows = source->rows;
target->width = source->width;
pad = 0;
if ( alignment > 0 )
{
pad = source->width % alignment;
if ( pad != 0 )
pad = alignment - pad;
}
target->pitch = source->width + pad;
if ( target->rows * target->pitch > old_size &&
FT_QREALLOC( target->buffer,
old_size, target->rows * target->pitch ) )
return error;
}
break;
default:
error = FT_Err_Invalid_Argument;
}
switch ( source->pixel_mode )
{
case FT_PIXEL_MODE_MONO:
{
FT_Byte* s = source->buffer;
FT_Byte* t = target->buffer;
FT_Int i;
target->num_grays = 2;
for ( i = source->rows; i > 0; i-- )
{
FT_Byte* ss = s;
FT_Byte* tt = t;
FT_Int j;
/* get the full bytes */
for ( j = source->width >> 3; j > 0; j-- )
{
FT_Int val = ss[0]; /* avoid a byte->int cast on each line */
tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
tt[7] = (FT_Byte)( val & 0x01 );
tt += 8;
ss += 1;
}
/* get remaining pixels (if any) */
j = source->width & 7;
if ( j > 0 )
{
FT_Int val = *ss;
for ( ; j > 0; j-- )
{
tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
val <<= 1;
tt += 1;
}
}
s += source->pitch;
t += target->pitch;
}
}
break;
case FT_PIXEL_MODE_GRAY:
{
FT_Int width = source->width;
FT_Byte* s = source->buffer;
FT_Byte* t = target->buffer;
FT_Int s_pitch = source->pitch;
FT_Int t_pitch = target->pitch;
FT_Int i;
target->num_grays = 256;
for ( i = source->rows; i > 0; i-- )
{
FT_ARRAY_COPY( t, s, width );
s += s_pitch;
t += t_pitch;
}
}
break;
case FT_PIXEL_MODE_GRAY2:
{
FT_Byte* s = source->buffer;
FT_Byte* t = target->buffer;
FT_Int i;
target->num_grays = 4;
for ( i = source->rows; i > 0; i-- )
{
FT_Byte* ss = s;
FT_Byte* tt = t;
FT_Int j;
/* get the full bytes */
for ( j = source->width >> 2; j > 0; j-- )
{
FT_Int val = ss[0];
tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
tt[3] = (FT_Byte)( ( val & 0x03 ) );
ss += 1;
tt += 4;
}
j = source->width & 3;
if ( j > 0 )
{
FT_Int val = ss[0];
for ( ; j > 0; j-- )
{
tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
val <<= 2;
tt += 1;
}
}
s += source->pitch;
t += target->pitch;
}
}
break;
case FT_PIXEL_MODE_GRAY4:
{
FT_Byte* s = source->buffer;
FT_Byte* t = target->buffer;
FT_Int i;
target->num_grays = 16;
for ( i = source->rows; i > 0; i-- )
{
FT_Byte* ss = s;
FT_Byte* tt = t;
FT_Int j;
/* get the full bytes */
for ( j = source->width >> 1; j > 0; j-- )
{
FT_Int val = ss[0];
tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
tt[1] = (FT_Byte)( ( val & 0x0F ) );
ss += 1;
tt += 2;
}
if ( source->width & 1 )
tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
s += source->pitch;
t += target->pitch;
}
}
break;
default:
;
}
return error;
}
/* documentation is in ftbitmap.h */
FT_EXPORT_DEF( FT_Error )
FT_Bitmap_Done( FT_Library library,
FT_Bitmap *bitmap )
{
FT_Memory memory;
if ( !library )
return FT_Err_Invalid_Library_Handle;
if ( !bitmap )
return FT_Err_Invalid_Argument;
memory = library->memory;
FT_FREE( bitmap->buffer );
*bitmap = null_bitmap;
return FT_Err_Ok;
}
/* END */

View File

@ -0,0 +1,825 @@
/***************************************************************************/
/* */
/* ftcalc.c */
/* */
/* Arithmetic computations (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 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 <freetype/ft2build.h>
#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_OBJECTS_H
#ifdef FT_MULFIX_INLINED
#undef FT_MulFix
#endif
/* we need to define a 64-bits data type here */
#ifdef FT_LONG64
typedef FT_INT64 FT_Int64;
#else
typedef struct FT_Int64_
{
FT_UInt32 lo;
FT_UInt32 hi;
} FT_Int64;
#endif /* FT_LONG64 */
/*************************************************************************/
/* */
/* 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 is defined. */
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Fixed )
FT_RoundFix( FT_Fixed a )
{
return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL
: -((-a + 0x8000L ) & ~0xFFFFL );
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Fixed )
FT_CeilFix( FT_Fixed a )
{
return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL
: -((-a + 0xFFFFL ) & ~0xFFFFL );
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Fixed )
FT_FloorFix( FT_Fixed a )
{
return ( a >= 0 ) ? a & ~0xFFFFL
: -((-a) & ~0xFFFFL );
}
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
/* 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_INTERNALS */
#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;
}
#ifdef TT_USE_BYTECODE_INTERPRETER
/* documentation is in ftcalc.h */
FT_BASE_DEF( FT_Long )
FT_MulDiv_No_Round( 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
: 0x7FFFFFFFL );
return ( s > 0 ) ? d : -d;
}
#endif /* TT_USE_BYTECODE_INTERPRETER */
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Long )
FT_MulFix( FT_Long a,
FT_Long b )
{
#ifdef FT_MULFIX_ASSEMBLER
return FT_MULFIX_ASSEMBLER(a,b);
#else
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 + 0x8000L ) >> 16 );
return ( s > 0 ) ? c : -c ;
#endif
}
/* 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 );
}
#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;
}
static void
FT_Add64( FT_Int64* x,
FT_Int64* y,
FT_Int64 *z )
{
register FT_UInt32 lo, hi;
lo = x->lo + y->lo;
hi = x->hi + y->hi + ( lo < x->lo );
z->lo = lo;
z->hi = hi;
}
/* documentation is in freetype.h */
/* The FT_MulDiv function has been optimized thanks to ideas from */
/* Graham Asher. The trick is to optimize computation when everything */
/* fits within 32-bits (a rather common case). */
/* */
/* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */
/* */
/* 46340 is FLOOR(SQRT(2^31-1)). */
/* */
/* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */
/* */
/* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */
/* */
/* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */
/* */
/* and 2*0x157F0 = 176096 */
/* */
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 = FT_ABS( a );
s ^= b; b = FT_ABS( b );
s ^= c; c = FT_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 );
}
#ifdef TT_USE_BYTECODE_INTERPRETER
FT_BASE_DEF( FT_Long )
FT_MulDiv_No_Round( FT_Long a,
FT_Long b,
FT_Long c )
{
long s;
if ( a == 0 || b == c )
return a;
s = a; a = FT_ABS( a );
s ^= b; b = FT_ABS( b );
s ^= c; c = FT_ABS( c );
if ( a <= 46340L && b <= 46340L && c > 0 )
a = a * b / c;
else if ( c > 0 )
{
FT_Int64 temp;
ft_multo64( a, b, &temp );
a = ft_div64by32( temp.hi, temp.lo, c );
}
else
a = 0x7FFFFFFFL;
return ( s < 0 ? -a : a );
}
#endif /* TT_USE_BYTECODE_INTERPRETER */
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Long )
FT_MulFix( FT_Long a,
FT_Long b )
{
#ifdef FT_MULFIX_ASSEMBLER
return FT_MULFIX_ASSEMBLER(a,b);
#else
FT_Long sa, sb;
FT_ULong ua, ub;
if ( a == 0 || b == 0x10000L )
return a;
sa = ( a >> ( sizeof ( a ) * 8 - 1 ) );
a = ( a ^ sa ) - sa;
sb = ( b >> ( sizeof ( b ) * 8 - 1 ) );
b = ( b ^ sb ) - sb;
ua = (FT_ULong)a;
ub = (FT_ULong)b;
if ( ua <= 2048 && ub <= 1048576L )
ua = ( ua * ub + 0x8000U ) >> 16;
else
{
FT_ULong al = ua & 0xFFFFU;
ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) +
( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 );
}
sa ^= sb,
ua = (FT_ULong)(( ua ^ sa ) - sa);
return (FT_Long)ua;
#endif
}
/* 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 = FT_ABS(a);
s ^= b; b = FT_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 );
}
#if 0
/* 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 = FT_ABS( x );
s ^= y; y = FT_ABS( y );
ft_multo64( x, y, z );
if ( s < 0 )
{
z->lo = (FT_UInt32)-(FT_Int32)z->lo;
z->hi = ~z->hi + !( z->lo );
}
}
/* apparently, the second version of this code is not compiled correctly */
/* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */
#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 = FT_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 /* 0 */
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 = FT_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 /* 0 */
#endif /* 0 */
#endif /* FT_LONG64 */
/* documentation is in ftcalc.h */
FT_BASE_DEF( void )
FT_Matrix_Multiply_Scaled( const FT_Matrix* a,
FT_Matrix *b,
FT_Long scaling )
{
FT_Fixed xx, xy, yx, yy;
FT_Long val = 0x10000L * scaling;
if ( !a || !b )
return;
xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val );
xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val );
yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val );
yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val );
b->xx = xx; b->xy = xy;
b->yx = yx; b->yy = yy;
}
/* documentation is in ftcalc.h */
FT_BASE_DEF( void )
FT_Vector_Transform_Scaled( FT_Vector* vector,
const FT_Matrix* matrix,
FT_Long scaling )
{
FT_Pos xz, yz;
FT_Long val = 0x10000L * scaling;
if ( !vector || !matrix )
return;
xz = FT_MulDiv( vector->x, matrix->xx, val ) +
FT_MulDiv( vector->y, matrix->xy, val );
yz = FT_MulDiv( vector->x, matrix->yx, val ) +
FT_MulDiv( vector->y, matrix->yy, val );
vector->x = xz;
vector->y = yz;
}
/* documentation is in ftcalc.h */
FT_BASE_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;
}
/* documentation is in ftcalc.h */
FT_BASE_DEF( FT_Int )
ft_corner_orientation( FT_Pos in_x,
FT_Pos in_y,
FT_Pos out_x,
FT_Pos out_y )
{
FT_Int result;
/* deal with the trivial cases quickly */
if ( in_y == 0 )
{
if ( in_x >= 0 )
result = out_y;
else
result = -out_y;
}
else if ( in_x == 0 )
{
if ( in_y >= 0 )
result = -out_x;
else
result = out_x;
}
else if ( out_y == 0 )
{
if ( out_x >= 0 )
result = in_y;
else
result = -in_y;
}
else if ( out_x == 0 )
{
if ( out_y >= 0 )
result = -in_x;
else
result = in_x;
}
else /* general case */
{
#ifdef FT_LONG64
FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;
if ( delta == 0 )
result = 0;
else
result = 1 - 2 * ( delta < 0 );
#else
FT_Int64 z1, z2;
ft_multo64( in_x, out_y, &z1 );
ft_multo64( in_y, out_x, &z2 );
if ( z1.hi > z2.hi )
result = +1;
else if ( z1.hi < z2.hi )
result = -1;
else if ( z1.lo > z2.lo )
result = +1;
else if ( z1.lo < z2.lo )
result = -1;
else
result = 0;
#endif
}
return result;
}
/* documentation is in ftcalc.h */
FT_BASE_DEF( FT_Int )
ft_corner_is_flat( FT_Pos in_x,
FT_Pos in_y,
FT_Pos out_x,
FT_Pos out_y )
{
FT_Pos ax = in_x;
FT_Pos ay = in_y;
FT_Pos d_in, d_out, d_corner;
if ( ax < 0 )
ax = -ax;
if ( ay < 0 )
ay = -ay;
d_in = ax + ay;
ax = out_x;
if ( ax < 0 )
ax = -ax;
ay = out_y;
if ( ay < 0 )
ay = -ay;
d_out = ax + ay;
ax = out_x + in_x;
if ( ax < 0 )
ax = -ax;
ay = out_y + in_y;
if ( ay < 0 )
ay = -ay;
d_corner = ax + ay;
return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
}
/* END */

View File

@ -0,0 +1,998 @@
/***************************************************************************/
/* */
/* ftdbgmem.c */
/* */
/* Memory debugger (body). */
/* */
/* Copyright 2001, 2002, 2003, 2004, 2005, 2006 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 <freetype/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
#define KEEPALIVE /* `Keep alive' means that freed blocks aren't released
* to the heap. This is useful to detect double-frees
* or weird heap corruption, but it uses large amounts of
* memory, however.
*/
#include <stdio.h>
#include <stdlib.h>
FT_BASE_DEF( const char* ) _ft_debug_file = 0;
FT_BASE_DEF( long ) _ft_debug_lineno = 0;
extern void
FT_DumpMemory( FT_Memory memory );
typedef struct FT_MemSourceRec_* FT_MemSource;
typedef struct FT_MemNodeRec_* FT_MemNode;
typedef struct FT_MemTableRec_* FT_MemTable;
#define FT_MEM_VAL( addr ) ((FT_ULong)(FT_Pointer)( addr ))
/*
* This structure holds statistics for a single allocation/release
* site. This is useful to know where memory operations happen the
* most.
*/
typedef struct FT_MemSourceRec_
{
const char* file_name;
long line_no;
FT_Long cur_blocks; /* current number of allocated blocks */
FT_Long max_blocks; /* max. number of allocated blocks */
FT_Long all_blocks; /* total number of blocks allocated */
FT_Long cur_size; /* current cumulative allocated size */
FT_Long max_size; /* maximum cumulative allocated size */
FT_Long all_size; /* total cumulative allocated size */
FT_Long cur_max; /* current maximum allocated size */
FT_UInt32 hash;
FT_MemSource link;
} FT_MemSourceRec;
/*
* We don't need a resizable array for the memory sources, because
* their number is pretty limited within FreeType.
*/
#define FT_MEM_SOURCE_BUCKETS 128
/*
* This structure holds information related to a single allocated
* memory block. If KEEPALIVE is defined, blocks that are freed by
* FreeType are never released to the system. Instead, their `size'
* field is set to -size. This is mainly useful to detect double frees,
* at the price of large memory footprint during execution.
*/
typedef struct FT_MemNodeRec_
{
FT_Byte* address;
FT_Long size; /* < 0 if the block was freed */
FT_MemSource source;
#ifdef KEEPALIVE
const char* free_file_name;
FT_Long free_line_no;
#endif
FT_MemNode link;
} FT_MemNodeRec;
/*
* The global structure, containing compound statistics and all hash
* tables.
*/
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;
FT_ULong alloc_count;
FT_Bool bound_total;
FT_ULong alloc_total_max;
FT_Bool bound_count;
FT_ULong alloc_count_max;
FT_MemSource sources[FT_MEM_SOURCE_BUCKETS];
FT_Bool keep_alive;
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")
/*
* Prime numbers are ugly to handle. It would be better to implement
* L-Hashing, which is 10% faster and doesn't require divisions.
*/
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,
};
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;
}
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_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_MemNode *)
ft_mem_table_alloc( table,
new_size * sizeof ( FT_MemNode ) );
if ( new_buckets == NULL )
return;
FT_ARRAY_ZERO( new_buckets, 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 = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) );
if ( table == NULL )
goto Exit;
FT_ZERO( 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 = (FT_MemNode *)
memory->alloc( memory,
table->size * sizeof ( FT_MemNode ) );
if ( table->buckets )
FT_ARRAY_ZERO( table->buckets, table->size );
else
{
memory->free( memory, table );
table = NULL;
}
Exit:
return table;
}
static void
ft_mem_table_destroy( FT_MemTable table )
{
FT_ULong i;
FT_DumpMemory( table->memory );
if ( table )
{
FT_Long leak_count = 0;
FT_ULong leaks = 0;
/* remove all blocks from the table, revealing leaked ones */
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->source->file_name ),
node->source->line_no );
leak_count++;
leaks += node->size;
ft_mem_table_free( table, node->address );
}
node->address = NULL;
node->size = 0;
ft_mem_table_free( table, node );
node = next;
}
table->buckets[i] = 0;
}
ft_mem_table_free( table, table->buckets );
table->buckets = NULL;
table->size = 0;
table->nodes = 0;
/* remove all sources */
for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ )
{
FT_MemSource source, next;
for ( source = table->sources[i]; source != NULL; source = next )
{
next = source->link;
ft_mem_table_free( table, source );
}
table->sources[i] = NULL;
}
printf(
"FreeType: total memory allocations = %ld\n", table->alloc_total );
printf(
"FreeType: maximum memory footprint = %ld\n", table->alloc_max );
ft_mem_table_free( table, table );
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 FT_MemSource
ft_mem_table_get_source( FT_MemTable table )
{
FT_UInt32 hash;
FT_MemSource node, *pnode;
/* cast to FT_PtrDist first since void* can be larger */
/* than FT_UInt32 and GCC 4.1.1 emits a warning */
hash = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file +
(FT_UInt32)( 5 * _ft_debug_lineno );
pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
for ( ;; )
{
node = *pnode;
if ( node == NULL )
break;
if ( node->file_name == _ft_debug_file &&
node->line_no == _ft_debug_lineno )
goto Exit;
pnode = &node->link;
}
node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) );
if ( node == NULL )
ft_mem_debug_panic(
"not enough memory to perform memory debugging\n" );
node->file_name = _ft_debug_file;
node->line_no = _ft_debug_lineno;
node->cur_blocks = 0;
node->max_blocks = 0;
node->all_blocks = 0;
node->cur_size = 0;
node->max_size = 0;
node->all_size = 0;
node->cur_max = 0;
node->link = NULL;
node->hash = hash;
*pnode = node;
Exit:
return node;
}
static void
ft_mem_table_set( FT_MemTable table,
FT_Byte* address,
FT_ULong size,
FT_Long delta )
{
FT_MemNode *pnode, node;
if ( table )
{
FT_MemSource source;
pnode = ft_mem_table_get_nodep( table, address );
node = *pnode;
if ( node )
{
if ( node->size < 0 )
{
/* This block was already freed. Our memory is now completely */
/* corrupted! */
/* This can only happen in keep-alive mode. */
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 at"
" %p, of size %ld)\n"
"org=%s:%d new=%s:%d\n",
node->address, node->size,
FT_FILENAME( node->source->file_name ), node->source->line_no,
FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
}
}
/* we need to create a new node in this table */
node = (FT_MemNode)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->source = source = ft_mem_table_get_source( table );
if ( delta == 0 )
{
/* this is an allocation */
source->all_blocks++;
source->cur_blocks++;
if ( source->cur_blocks > source->max_blocks )
source->max_blocks = source->cur_blocks;
}
if ( size > (FT_ULong)source->cur_max )
source->cur_max = size;
if ( delta != 0 )
{
/* we are growing or shrinking a reallocated block */
source->cur_size += delta;
table->alloc_current += delta;
}
else
{
/* we are allocating a new block */
source->cur_size += size;
table->alloc_current += size;
}
source->all_size += size;
if ( source->cur_size > source->max_size )
source->max_size = source->cur_size;
node->free_file_name = NULL;
node->free_line_no = 0;
node->link = pnode[0];
pnode[0] = node;
table->nodes++;
table->alloc_total += 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,
FT_Long delta )
{
if ( table )
{
FT_MemNode *pnode, node;
pnode = ft_mem_table_get_nodep( table, address );
node = *pnode;
if ( node )
{
FT_MemSource source;
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( _ft_debug_file ), _ft_debug_lineno,
FT_FILENAME( node->source->file_name ), node->source->line_no,
FT_FILENAME( node->free_file_name ), node->free_line_no );
/* scramble the node's content for additional safety */
FT_MEM_SET( address, 0xF3, node->size );
if ( delta == 0 )
{
source = node->source;
source->cur_blocks--;
source->cur_size -= node->size;
table->alloc_current -= node->size;
}
if ( table->keep_alive )
{
/* we simply invert the node's size to indicate that the node */
/* was freed. */
node->size = -node->size;
node->free_file_name = _ft_debug_file;
node->free_line_no = _ft_debug_lineno;
}
else
{
table->nodes--;
*pnode = node->link;
node->size = 0;
node->source = NULL;
ft_mem_table_free( table, node );
if ( table->nodes * 3 < table->size ||
table->size * 3 < table->nodes )
ft_mem_table_resize( table );
}
}
else
ft_mem_debug_panic(
"trying to free unknown block at %p in (%s:%ld)\n",
address,
FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
}
}
extern FT_Pointer
ft_mem_debug_alloc( FT_Memory memory,
FT_Long size )
{
FT_MemTable table = (FT_MemTable)memory->user;
FT_Byte* block;
if ( size <= 0 )
ft_mem_debug_panic( "negative block size allocation (%ld)", size );
/* return NULL if the maximum number of allocations was reached */
if ( table->bound_count &&
table->alloc_count >= table->alloc_count_max )
return NULL;
/* return NULL if this allocation would overflow the maximum heap size */
if ( table->bound_total &&
table->alloc_total_max - table->alloc_current > (FT_ULong)size )
return NULL;
block = (FT_Byte *)ft_mem_table_alloc( table, size );
if ( block )
{
ft_mem_table_set( table, block, (FT_ULong)size, 0 );
table->alloc_count++;
}
_ft_debug_file = "<unknown>";
_ft_debug_lineno = 0;
return (FT_Pointer)block;
}
extern void
ft_mem_debug_free( FT_Memory memory,
FT_Pointer block )
{
FT_MemTable table = (FT_MemTable)memory->user;
if ( block == NULL )
ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
FT_FILENAME( _ft_debug_file ),
_ft_debug_lineno );
ft_mem_table_remove( table, (FT_Byte*)block, 0 );
if ( !table->keep_alive )
ft_mem_table_free( table, block );
table->alloc_count--;
_ft_debug_file = "<unknown>";
_ft_debug_lineno = 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 = (FT_MemTable)memory->user;
FT_MemNode node, *pnode;
FT_Pointer new_block;
FT_Long delta;
const char* file_name = FT_FILENAME( _ft_debug_file );
FT_Long line_no = _ft_debug_lineno;
/* unlikely, but possible */
if ( new_size == cur_size )
return block;
/* the following is valid according to ANSI C */
#if 0
if ( block == NULL || cur_size == 0 )
ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)",
file_name, line_no );
#endif
/* while the following is allowed in ANSI C also, we abort since */
/* such case should be handled by FreeType. */
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 ft_realloc request for %p. cur_size is "
"%ld instead of %ld in (%s:%ld)",
block, cur_size, node->size, file_name, line_no );
/* return NULL if the maximum number of allocations was reached */
if ( table->bound_count &&
table->alloc_count >= table->alloc_count_max )
return NULL;
delta = (FT_Long)( new_size - cur_size );
/* return NULL if this allocation would overflow the maximum heap size */
if ( delta > 0 &&
table->bound_total &&
table->alloc_current + (FT_ULong)delta > table->alloc_total_max )
return NULL;
new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size );
if ( new_block == NULL )
return NULL;
ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta );
ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size );
ft_mem_table_remove( table, (FT_Byte*)block, delta );
_ft_debug_file = "<unknown>";
_ft_debug_lineno = 0;
if ( !table->keep_alive )
ft_mem_table_free( table, block );
return new_block;
}
extern FT_Int
ft_mem_debug_init( FT_Memory memory )
{
FT_MemTable table;
FT_Int result = 0;
if ( getenv( "FT2_DEBUG_MEMORY" ) )
{
table = ft_mem_table_new( memory );
if ( table )
{
const char* p;
memory->user = table;
memory->alloc = ft_mem_debug_alloc;
memory->realloc = ft_mem_debug_realloc;
memory->free = ft_mem_debug_free;
p = getenv( "FT2_ALLOC_TOTAL_MAX" );
if ( p != NULL )
{
FT_Long total_max = ft_atol( p );
if ( total_max > 0 )
{
table->bound_total = 1;
table->alloc_total_max = (FT_ULong)total_max;
}
}
p = getenv( "FT2_ALLOC_COUNT_MAX" );
if ( p != NULL )
{
FT_Long total_count = ft_atol( p );
if ( total_count > 0 )
{
table->bound_count = 1;
table->alloc_count_max = (FT_ULong)total_count;
}
}
p = getenv( "FT2_KEEP_ALIVE" );
if ( p != NULL )
{
FT_Long keep_alive = ft_atol( p );
if ( keep_alive > 0 )
table->keep_alive = 1;
}
result = 1;
}
}
return result;
}
extern void
ft_mem_debug_done( FT_Memory memory )
{
FT_MemTable table = (FT_MemTable)memory->user;
if ( table )
{
memory->free = table->free;
memory->realloc = table->realloc;
memory->alloc = table->alloc;
ft_mem_table_destroy( table );
memory->user = NULL;
}
}
static int
ft_mem_source_compare( const void* p1,
const void* p2 )
{
FT_MemSource s1 = *(FT_MemSource*)p1;
FT_MemSource s2 = *(FT_MemSource*)p2;
if ( s2->max_size > s1->max_size )
return 1;
else if ( s2->max_size < s1->max_size )
return -1;
else
return 0;
}
extern void
FT_DumpMemory( FT_Memory memory )
{
FT_MemTable table = (FT_MemTable)memory->user;
if ( table )
{
FT_MemSource* bucket = table->sources;
FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS;
FT_MemSource* sources;
FT_UInt nn, count;
const char* fmt;
count = 0;
for ( ; bucket < limit; bucket++ )
{
FT_MemSource source = *bucket;
for ( ; source; source = source->link )
count++;
}
sources = (FT_MemSource*)ft_mem_table_alloc(
table, sizeof ( *sources ) * count );
count = 0;
for ( bucket = table->sources; bucket < limit; bucket++ )
{
FT_MemSource source = *bucket;
for ( ; source; source = source->link )
sources[count++] = source;
}
ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare );
printf( "FreeType Memory Dump: "
"current=%ld max=%ld total=%ld count=%ld\n",
table->alloc_current, table->alloc_max,
table->alloc_total, table->alloc_count );
printf( " block block sizes sizes sizes source\n" );
printf( " count high sum highsum max location\n" );
printf( "-------------------------------------------------\n" );
fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n";
for ( nn = 0; nn < count; nn++ )
{
FT_MemSource source = sources[nn];
printf( fmt,
source->cur_blocks, source->max_blocks,
source->cur_size, source->max_size, source->cur_max,
FT_FILENAME( source->file_name ),
source->line_no );
}
printf( "------------------------------------------------\n" );
ft_mem_table_free( table, sources );
}
}
#else /* !FT_DEBUG_MEMORY */
/* ANSI C doesn't like empty source files */
const FT_Byte _debug_mem_dummy = 0;
#endif /* !FT_DEBUG_MEMORY */
/* END */

View File

@ -0,0 +1,246 @@
/***************************************************************************/
/* */
/* ftdebug.c */
/* */
/* Debugging and logging component (body). */
/* */
/* Copyright 1996-2001, 2002, 2004, 2008 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 <freetype/ft2build.h>
#include FT_FREETYPE_H
#include FT_INTERNAL_DEBUG_H
#if defined( FT_DEBUG_LEVEL_ERROR )
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
FT_Message( const char* fmt, ... )
{
va_list ap;
va_start( ap, fmt );
vfprintf( stderr, fmt, ap );
va_end( ap );
}
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
FT_Panic( const char* fmt, ... )
{
va_list ap;
va_start( ap, fmt );
vfprintf( stderr, fmt, ap );
va_end( ap );
exit( EXIT_FAILURE );
}
#endif /* FT_DEBUG_LEVEL_ERROR */
#ifdef FT_DEBUG_LEVEL_TRACE
/* array of trace levels, initialized to 0 */
int ft_trace_levels[trace_count];
/* define array of trace toggle names */
#define FT_TRACE_DEF( x ) #x ,
static const char* ft_trace_toggles[trace_count + 1] =
{
#include FT_INTERNAL_TRACE_H
NULL
};
#undef FT_TRACE_DEF
/* documentation is in ftdebug.h */
FT_BASE_DEF( FT_Int )
FT_Trace_Get_Count( void )
{
return trace_count;
}
/* documentation is in ftdebug.h */
FT_BASE_DEF( const char * )
FT_Trace_Get_Name( FT_Int idx )
{
int max = FT_Trace_Get_Count();
if ( idx < max )
return ft_trace_toggles[idx];
else
return NULL;
}
/*************************************************************************/
/* */
/* Initialize the tracing sub-system. This is done by retrieving the */
/* value of the `FT2_DEBUG' environment variable. It must be a list of */
/* toggles, separated by spaces, `;', or `,'. Example: */
/* */
/* export FT2_DEBUG="any:3 memory:7 stream:5" */
/* */
/* This requests that all levels be set to 3, except the trace level for */
/* the memory and stream components which are set to 7 and 5, */
/* respectively. */
/* */
/* See the file <include/freetype/internal/fttrace.h> for details of the */
/* available toggle names. */
/* */
/* The level must be between 0 and 7; 0 means quiet (except for serious */
/* runtime errors), and 7 means _very_ verbose. */
/* */
FT_BASE_DEF( void )
ft_debug_init( void )
{
const char* ft2_debug = getenv( "FT2_DEBUG" );
if ( ft2_debug )
{
const char* p = ft2_debug;
const char* q;
for ( ; *p; p++ )
{
/* skip leading whitespace and separators */
if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )
continue;
/* read toggle name, followed by ':' */
q = p;
while ( *p && *p != ':' )
p++;
if ( *p == ':' && p > q )
{
FT_Int n, i, len = (FT_Int)( p - q );
FT_Int level = -1, found = -1;
for ( n = 0; n < trace_count; n++ )
{
const char* toggle = ft_trace_toggles[n];
for ( i = 0; i < len; i++ )
{
if ( toggle[i] != q[i] )
break;
}
if ( i == len && toggle[i] == 0 )
{
found = n;
break;
}
}
/* read level */
p++;
if ( *p )
{
level = *p++ - '0';
if ( level < 0 || level > 7 )
level = -1;
}
if ( found >= 0 && level >= 0 )
{
if ( found == trace_any )
{
/* special case for `any' */
for ( n = 0; n < trace_count; n++ )
ft_trace_levels[n] = level;
}
else
ft_trace_levels[found] = level;
}
}
}
}
}
#else /* !FT_DEBUG_LEVEL_TRACE */
FT_BASE_DEF( void )
ft_debug_init( void )
{
/* nothing */
}
FT_BASE_DEF( FT_Int )
FT_Trace_Get_Count( void )
{
return 0;
}
FT_BASE_DEF( const char * )
FT_Trace_Get_Name( FT_Int idx )
{
FT_UNUSED( idx );
return NULL;
}
#endif /* !FT_DEBUG_LEVEL_TRACE */
/* END */

View File

@ -0,0 +1,61 @@
/***************************************************************************/
/* */
/* ftgasp.c */
/* */
/* Access of TrueType's `gasp' table (body). */
/* */
/* Copyright 2007 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 <freetype/ft2build.h>
#include FT_GASP_H
#include FT_INTERNAL_TRUETYPE_TYPES_H
FT_EXPORT_DEF( FT_Int )
FT_Get_Gasp( FT_Face face,
FT_UInt ppem )
{
FT_Int result = FT_GASP_NO_TABLE;
if ( face && FT_IS_SFNT( face ) )
{
TT_Face ttface = (TT_Face)face;
if ( ttface->gasp.numRanges > 0 )
{
TT_GaspRange range = ttface->gasp.gaspRanges;
TT_GaspRange range_end = range + ttface->gasp.numRanges;
while ( ppem > range->maxPPEM )
{
range++;
if ( range >= range_end )
goto Exit;
}
result = range->gaspFlag;
/* ensure that we don't have spurious bits */
if ( ttface->gasp.version == 0 )
result &= 3;
}
}
Exit:
return result;
}
/* END */

View File

@ -0,0 +1,394 @@
/***************************************************************************/
/* */
/* ftgloadr.c */
/* */
/* The FreeType glyph loader (body). */
/* */
/* Copyright 2002, 2003, 2004, 2005, 2006 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 <freetype/ft2build.h>
#include FT_INTERNAL_GLYPH_LOADER_H
#include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_OBJECTS_H
#undef FT_COMPONENT
#define FT_COMPONENT trace_gloader
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** *****/
/***** G L Y P H L O A D E R *****/
/***** *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* */
/* The glyph loader is a simple object which is used to load a set of */
/* glyphs easily. It is critical for the correct loading of composites. */
/* */
/* Ideally, one can see it as a stack of abstract `glyph' objects. */
/* */
/* loader.base Is really the bottom of the stack. It describes a */
/* single glyph image made of the juxtaposition of */
/* several glyphs (those `in the stack'). */
/* */
/* loader.current Describes the top of the stack, on which a new */
/* glyph can be loaded. */
/* */
/* Rewind Clears the stack. */
/* Prepare Set up `loader.current' for addition of a new glyph */
/* image. */
/* Add Add the `current' glyph image to the `base' one, */
/* and prepare for another one. */
/* */
/* The glyph loader is now a base object. Each driver used to */
/* re-implement it in one way or the other, which wasted code and */
/* energy. */
/* */
/*************************************************************************/
/* create a new glyph loader */
FT_BASE_DEF( FT_Error )
FT_GlyphLoader_New( FT_Memory memory,
FT_GlyphLoader *aloader )
{
FT_GlyphLoader loader;
FT_Error error;
if ( !FT_NEW( loader ) )
{
loader->memory = memory;
*aloader = loader;
}
return error;
}
/* rewind the glyph loader - reset counters to 0 */
FT_BASE_DEF( void )
FT_GlyphLoader_Rewind( FT_GlyphLoader loader )
{
FT_GlyphLoad base = &loader->base;
FT_GlyphLoad current = &loader->current;
base->outline.n_points = 0;
base->outline.n_contours = 0;
base->num_subglyphs = 0;
*current = *base;
}
/* reset the glyph loader, frees all allocated tables */
/* and starts from zero */
FT_BASE_DEF( void )
FT_GlyphLoader_Reset( FT_GlyphLoader loader )
{
FT_Memory memory = loader->memory;
FT_FREE( loader->base.outline.points );
FT_FREE( loader->base.outline.tags );
FT_FREE( loader->base.outline.contours );
FT_FREE( loader->base.extra_points );
FT_FREE( loader->base.subglyphs );
loader->base.extra_points2 = NULL;
loader->max_points = 0;
loader->max_contours = 0;
loader->max_subglyphs = 0;
FT_GlyphLoader_Rewind( loader );
}
/* delete a glyph loader */
FT_BASE_DEF( void )
FT_GlyphLoader_Done( FT_GlyphLoader loader )
{
if ( loader )
{
FT_Memory memory = loader->memory;
FT_GlyphLoader_Reset( loader );
FT_FREE( loader );
}
}
/* re-adjust the `current' outline fields */
static void
FT_GlyphLoader_Adjust_Points( FT_GlyphLoader loader )
{
FT_Outline* base = &loader->base.outline;
FT_Outline* current = &loader->current.outline;
current->points = base->points + base->n_points;
current->tags = base->tags + base->n_points;
current->contours = base->contours + base->n_contours;
/* handle extra points table - if any */
if ( loader->use_extra )
{
loader->current.extra_points = loader->base.extra_points +
base->n_points;
loader->current.extra_points2 = loader->base.extra_points2 +
base->n_points;
}
}
FT_BASE_DEF( FT_Error )
FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader )
{
FT_Error error;
FT_Memory memory = loader->memory;
if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
{
loader->use_extra = 1;
loader->base.extra_points2 = loader->base.extra_points +
loader->max_points;
FT_GlyphLoader_Adjust_Points( loader );
}
return error;
}
/* re-adjust the `current' subglyphs field */
static void
FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader loader )
{
FT_GlyphLoad base = &loader->base;
FT_GlyphLoad current = &loader->current;
current->subglyphs = base->subglyphs + base->num_subglyphs;
}
/* Ensure that we can add `n_points' and `n_contours' to our glyph. */
/* This function reallocates its outline tables if necessary. Note that */
/* it DOESN'T change the number of points within the loader! */
/* */
FT_BASE_DEF( FT_Error )
FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader,
FT_UInt n_points,
FT_UInt n_contours )
{
FT_Memory memory = loader->memory;
FT_Error error = FT_Err_Ok;
FT_Outline* base = &loader->base.outline;
FT_Outline* current = &loader->current.outline;
FT_Bool adjust = 0;
FT_UInt new_max, old_max;
/* check points & tags */
new_max = base->n_points + current->n_points + n_points;
old_max = loader->max_points;
if ( new_max > old_max )
{
new_max = FT_PAD_CEIL( new_max, 8 );
if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
FT_RENEW_ARRAY( base->tags, old_max, new_max ) )
goto Exit;
if ( loader->use_extra )
{
if ( FT_RENEW_ARRAY( loader->base.extra_points,
old_max * 2, new_max * 2 ) )
goto Exit;
FT_ARRAY_MOVE( loader->base.extra_points + new_max,
loader->base.extra_points + old_max,
old_max );
loader->base.extra_points2 = loader->base.extra_points + new_max;
}
adjust = 1;
loader->max_points = new_max;
}
/* check contours */
old_max = loader->max_contours;
new_max = base->n_contours + current->n_contours +
n_contours;
if ( new_max > old_max )
{
new_max = FT_PAD_CEIL( new_max, 4 );
if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
goto Exit;
adjust = 1;
loader->max_contours = new_max;
}
if ( adjust )
FT_GlyphLoader_Adjust_Points( loader );
Exit:
return error;
}
/* Ensure that we can add `n_subglyphs' to our glyph. this function */
/* reallocates its subglyphs table if necessary. Note that it DOES */
/* NOT change the number of subglyphs within the loader! */
/* */
FT_BASE_DEF( FT_Error )
FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader,
FT_UInt n_subs )
{
FT_Memory memory = loader->memory;
FT_Error error = FT_Err_Ok;
FT_UInt new_max, old_max;
FT_GlyphLoad base = &loader->base;
FT_GlyphLoad current = &loader->current;
new_max = base->num_subglyphs + current->num_subglyphs + n_subs;
old_max = loader->max_subglyphs;
if ( new_max > old_max )
{
new_max = FT_PAD_CEIL( new_max, 2 );
if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) )
goto Exit;
loader->max_subglyphs = new_max;
FT_GlyphLoader_Adjust_Subglyphs( loader );
}
Exit:
return error;
}
/* prepare loader for the addition of a new glyph on top of the base one */
FT_BASE_DEF( void )
FT_GlyphLoader_Prepare( FT_GlyphLoader loader )
{
FT_GlyphLoad current = &loader->current;
current->outline.n_points = 0;
current->outline.n_contours = 0;
current->num_subglyphs = 0;
FT_GlyphLoader_Adjust_Points ( loader );
FT_GlyphLoader_Adjust_Subglyphs( loader );
}
/* add current glyph to the base image - and prepare for another */
FT_BASE_DEF( void )
FT_GlyphLoader_Add( FT_GlyphLoader loader )
{
FT_GlyphLoad base;
FT_GlyphLoad current;
FT_UInt n_curr_contours;
FT_UInt n_base_points;
FT_UInt n;
if ( !loader )
return;
base = &loader->base;
current = &loader->current;
n_curr_contours = current->outline.n_contours;
n_base_points = base->outline.n_points;
base->outline.n_points =
(short)( base->outline.n_points + current->outline.n_points );
base->outline.n_contours =
(short)( base->outline.n_contours + current->outline.n_contours );
base->num_subglyphs += current->num_subglyphs;
/* adjust contours count in newest outline */
for ( n = 0; n < n_curr_contours; n++ )
current->outline.contours[n] =
(short)( current->outline.contours[n] + n_base_points );
/* prepare for another new glyph image */
FT_GlyphLoader_Prepare( loader );
}
FT_BASE_DEF( FT_Error )
FT_GlyphLoader_CopyPoints( FT_GlyphLoader target,
FT_GlyphLoader source )
{
FT_Error error;
FT_UInt num_points = source->base.outline.n_points;
FT_UInt num_contours = source->base.outline.n_contours;
error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours );
if ( !error )
{
FT_Outline* out = &target->base.outline;
FT_Outline* in = &source->base.outline;
FT_ARRAY_COPY( out->points, in->points,
num_points );
FT_ARRAY_COPY( out->tags, in->tags,
num_points );
FT_ARRAY_COPY( out->contours, in->contours,
num_contours );
/* do we need to copy the extra points? */
if ( target->use_extra && source->use_extra )
{
FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points,
num_points );
FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2,
num_points );
}
out->n_points = (short)num_points;
out->n_contours = (short)num_contours;
FT_GlyphLoader_Adjust_Points( target );
}
return error;
}
/* END */

View File

@ -0,0 +1,688 @@
/***************************************************************************/
/* */
/* ftglyph.c */
/* */
/* FreeType convenience functions to handle glyphs (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007 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 <freetype/ft2build.h>
#include FT_GLYPH_H
#include FT_OUTLINE_H
#include FT_BITMAP_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( const 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 ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
FT_CALLBACK_DEF( FT_Error )
ft_bitmap_glyph_init( FT_Glyph bitmap_glyph,
FT_GlyphSlot slot )
{
FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
FT_Error error = FT_Err_Ok;
FT_Library library = FT_GLYPH( glyph )->library;
if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
{
error = FT_Err_Invalid_Glyph_Format;
goto Exit;
}
glyph->left = slot->bitmap_left;
glyph->top = slot->bitmap_top;
/* do lazy copying whenever possible */
if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
{
glyph->bitmap = slot->bitmap;
slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
}
else
{
FT_Bitmap_New( &glyph->bitmap );
error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap );
}
Exit:
return error;
}
FT_CALLBACK_DEF( FT_Error )
ft_bitmap_glyph_copy( FT_Glyph bitmap_source,
FT_Glyph bitmap_target )
{
FT_Library library = bitmap_source->library;
FT_BitmapGlyph source = (FT_BitmapGlyph)bitmap_source;
FT_BitmapGlyph target = (FT_BitmapGlyph)bitmap_target;
target->left = source->left;
target->top = source->top;
return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap );
}
FT_CALLBACK_DEF( void )
ft_bitmap_glyph_done( FT_Glyph bitmap_glyph )
{
FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
FT_Library library = FT_GLYPH( glyph )->library;
FT_Bitmap_Done( library, &glyph->bitmap );
}
FT_CALLBACK_DEF( void )
ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph,
FT_BBox* cbox )
{
FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
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 );
}
FT_CALLBACK_TABLE_DEF
const FT_Glyph_Class ft_bitmap_glyph_class =
{
sizeof ( FT_BitmapGlyphRec ),
FT_GLYPH_FORMAT_BITMAP,
ft_bitmap_glyph_init,
ft_bitmap_glyph_done,
ft_bitmap_glyph_copy,
0, /* FT_Glyph_TransformFunc */
ft_bitmap_glyph_bbox,
0 /* FT_Glyph_PrepareFunc */
};
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** FT_OutlineGlyph support ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
FT_CALLBACK_DEF( FT_Error )
ft_outline_glyph_init( FT_Glyph outline_glyph,
FT_GlyphSlot slot )
{
FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
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;
FT_Outline_Copy( source, target );
Exit:
return error;
}
FT_CALLBACK_DEF( void )
ft_outline_glyph_done( FT_Glyph outline_glyph )
{
FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline );
}
FT_CALLBACK_DEF( FT_Error )
ft_outline_glyph_copy( FT_Glyph outline_source,
FT_Glyph outline_target )
{
FT_OutlineGlyph source = (FT_OutlineGlyph)outline_source;
FT_OutlineGlyph target = (FT_OutlineGlyph)outline_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;
}
FT_CALLBACK_DEF( void )
ft_outline_glyph_transform( FT_Glyph outline_glyph,
const FT_Matrix* matrix,
const FT_Vector* delta )
{
FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
if ( matrix )
FT_Outline_Transform( &glyph->outline, matrix );
if ( delta )
FT_Outline_Translate( &glyph->outline, delta->x, delta->y );
}
FT_CALLBACK_DEF( void )
ft_outline_glyph_bbox( FT_Glyph outline_glyph,
FT_BBox* bbox )
{
FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
FT_Outline_Get_CBox( &glyph->outline, bbox );
}
FT_CALLBACK_DEF( FT_Error )
ft_outline_glyph_prepare( FT_Glyph outline_glyph,
FT_GlyphSlot slot )
{
FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
slot->format = FT_GLYPH_FORMAT_OUTLINE;
slot->outline = glyph->outline;
slot->outline.flags &= ~FT_OUTLINE_OWNER;
return FT_Err_Ok;
}
FT_CALLBACK_TABLE_DEF
const FT_Glyph_Class ft_outline_glyph_class =
{
sizeof ( FT_OutlineGlyphRec ),
FT_GLYPH_FORMAT_OUTLINE,
ft_outline_glyph_init,
ft_outline_glyph_done,
ft_outline_glyph_copy,
ft_outline_glyph_transform,
ft_outline_glyph_bbox,
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 ( !FT_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 )
{
error = FT_Err_Invalid_Argument;
goto Exit;
}
*target = 0;
if ( !source || !source->clazz )
{
error = FT_Err_Invalid_Argument;
goto Exit;
}
clazz = source->clazz;
error = ft_new_glyph( source->library, clazz, &copy );
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;
FT_Error error;
FT_Glyph glyph;
const FT_Glyph_Class* clazz = 0;
if ( !slot )
return FT_Err_Invalid_Slot_Handle;
library = slot->library;
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 ||
bbox_mode == FT_GLYPH_BBOX_PIXELS )
{
acbox->xMin = FT_PIX_FLOOR( acbox->xMin );
acbox->yMin = FT_PIX_FLOOR( acbox->yMin );
acbox->xMax = FT_PIX_CEIL( acbox->xMax );
acbox->yMax = FT_PIX_CEIL( acbox->yMax );
}
/* convert to integer pixels if needed */
if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE ||
bbox_mode == FT_GLYPH_BBOX_PIXELS )
{
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_Render_Mode render_mode,
FT_Vector* origin,
FT_Bool destroy )
{
FT_GlyphSlotRec dummy;
FT_GlyphSlot_InternalRec dummy_internal;
FT_Error error = FT_Err_Ok;
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;
/* when called with a bitmap glyph, do nothing and return successfully */
if ( clazz == &ft_bitmap_glyph_class )
goto Exit;
if ( !clazz || !clazz->glyph_prepare )
goto Bad;
FT_MEM_ZERO( &dummy, sizeof ( dummy ) );
FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) );
dummy.internal = &dummy_internal;
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*)(void*)&bitmap );
if ( error )
goto Exit;
#if 1
/* 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 1
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( (FT_Glyph)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 );
FT_FREE( glyph );
}
}
/* END */

View File

@ -0,0 +1,163 @@
/***************************************************************************/
/* */
/* ftinit.c */
/* */
/* FreeType initialization layer (body). */
/* */
/* Copyright 1996-2001, 2002, 2005, 2007 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 <freetype/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 ftmodapi.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 = 0x%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_Done_Memory( memory );
else
{
(*alibrary)->version_major = FREETYPE_MAJOR;
(*alibrary)->version_minor = FREETYPE_MINOR;
(*alibrary)->version_patch = FREETYPE_PATCH;
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 */

View File

@ -0,0 +1,351 @@
/***************************************************************************/
/* */
/* ftlcdfil.c */
/* */
/* FreeType API for color filtering of subpixel bitmap glyphs (body). */
/* */
/* Copyright 2006, 2008 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 <freetype/ft2build.h>
#include FT_LCD_FILTER_H
#include FT_IMAGE_H
#include FT_INTERNAL_OBJECTS_H
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
/* define USE_LEGACY to implement the legacy filter */
#define USE_LEGACY
/* FIR filter used by the default and light filters */
static void
_ft_lcd_filter_fir( FT_Bitmap* bitmap,
FT_Render_Mode mode,
FT_Library library )
{
FT_Byte* weights = library->lcd_weights;
FT_UInt width = (FT_UInt)bitmap->width;
FT_UInt height = (FT_UInt)bitmap->rows;
/* horizontal in-place FIR filter */
if ( mode == FT_RENDER_MODE_LCD && width >= 4 )
{
FT_Byte* line = bitmap->buffer;
for ( ; height > 0; height--, line += bitmap->pitch )
{
FT_UInt fir[5];
FT_UInt val1, xx;
val1 = line[0];
fir[0] = weights[2] * val1;
fir[1] = weights[3] * val1;
fir[2] = weights[4] * val1;
fir[3] = 0;
fir[4] = 0;
val1 = line[1];
fir[0] += weights[1] * val1;
fir[1] += weights[2] * val1;
fir[2] += weights[3] * val1;
fir[3] += weights[4] * val1;
for ( xx = 2; xx < width; xx++ )
{
FT_UInt val, pix;
val = line[xx];
pix = fir[0] + weights[0] * val;
fir[0] = fir[1] + weights[1] * val;
fir[1] = fir[2] + weights[2] * val;
fir[2] = fir[3] + weights[3] * val;
fir[3] = weights[4] * val;
pix >>= 8;
pix |= -( pix >> 8 );
line[xx - 2] = (FT_Byte)pix;
}
{
FT_UInt pix;
pix = fir[0] >> 8;
pix |= -( pix >> 8 );
line[xx - 2] = (FT_Byte)pix;
pix = fir[1] >> 8;
pix |= -( pix >> 8 );
line[xx - 1] = (FT_Byte)pix;
}
}
}
/* vertical in-place FIR filter */
else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 )
{
FT_Byte* column = bitmap->buffer;
FT_Int pitch = bitmap->pitch;
for ( ; width > 0; width--, column++ )
{
FT_Byte* col = column;
FT_UInt fir[5];
FT_UInt val1, yy;
val1 = col[0];
fir[0] = weights[2] * val1;
fir[1] = weights[3] * val1;
fir[2] = weights[4] * val1;
fir[3] = 0;
fir[4] = 0;
col += pitch;
val1 = col[0];
fir[0] += weights[1] * val1;
fir[1] += weights[2] * val1;
fir[2] += weights[3] * val1;
fir[3] += weights[4] * val1;
col += pitch;
for ( yy = 2; yy < height; yy++ )
{
FT_UInt val, pix;
val = col[0];
pix = fir[0] + weights[0] * val;
fir[0] = fir[1] + weights[1] * val;
fir[1] = fir[2] + weights[2] * val;
fir[2] = fir[3] + weights[3] * val;
fir[3] = weights[4] * val;
pix >>= 8;
pix |= -( pix >> 8 );
col[-2 * pitch] = (FT_Byte)pix;
col += pitch;
}
{
FT_UInt pix;
pix = fir[0] >> 8;
pix |= -( pix >> 8 );
col[-2 * pitch] = (FT_Byte)pix;
pix = fir[1] >> 8;
pix |= -( pix >> 8 );
col[-pitch] = (FT_Byte)pix;
}
}
}
}
#ifdef USE_LEGACY
/* intra-pixel filter used by the legacy filter */
static void
_ft_lcd_filter_legacy( FT_Bitmap* bitmap,
FT_Render_Mode mode,
FT_Library library )
{
FT_UInt width = (FT_UInt)bitmap->width;
FT_UInt height = (FT_UInt)bitmap->rows;
FT_Int pitch = bitmap->pitch;
static const int filters[3][3] =
{
{ 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 },
{ 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 },
{ 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 }
};
FT_UNUSED( library );
/* horizontal in-place intra-pixel filter */
if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
{
FT_Byte* line = bitmap->buffer;
for ( ; height > 0; height--, line += pitch )
{
FT_UInt xx;
for ( xx = 0; xx < width; xx += 3 )
{
FT_UInt r = 0;
FT_UInt g = 0;
FT_UInt b = 0;
FT_UInt p;
p = line[xx];
r += filters[0][0] * p;
g += filters[0][1] * p;
b += filters[0][2] * p;
p = line[xx + 1];
r += filters[1][0] * p;
g += filters[1][1] * p;
b += filters[1][2] * p;
p = line[xx + 2];
r += filters[2][0] * p;
g += filters[2][1] * p;
b += filters[2][2] * p;
line[xx] = (FT_Byte)( r / 65536 );
line[xx + 1] = (FT_Byte)( g / 65536 );
line[xx + 2] = (FT_Byte)( b / 65536 );
}
}
}
else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
{
FT_Byte* column = bitmap->buffer;
for ( ; width > 0; width--, column++ )
{
FT_Byte* col = column;
FT_Byte* col_end = col + height * pitch;
for ( ; col < col_end; col += 3 * pitch )
{
FT_UInt r = 0;
FT_UInt g = 0;
FT_UInt b = 0;
FT_UInt p;
p = col[0];
r += filters[0][0] * p;
g += filters[0][1] * p;
b += filters[0][2] * p;
p = col[pitch];
r += filters[1][0] * p;
g += filters[1][1] * p;
b += filters[1][2] * p;
p = col[pitch * 2];
r += filters[2][0] * p;
g += filters[2][1] * p;
b += filters[2][2] * p;
col[0] = (FT_Byte)( r / 65536 );
col[pitch] = (FT_Byte)( g / 65536 );
col[2 * pitch] = (FT_Byte)( b / 65536 );
}
}
}
}
#endif /* USE_LEGACY */
FT_EXPORT( FT_Error )
FT_Library_SetLcdFilter( FT_Library library,
FT_LcdFilter filter )
{
static const FT_Byte light_filter[5] =
{ 0, 85, 86, 85, 0 };
/* the values here sum up to a value larger than 256, */
/* providing a cheap gamma correction */
static const FT_Byte default_filter[5] =
{ 0x10, 0x40, 0x70, 0x40, 0x10 };
if ( library == NULL )
return FT_Err_Invalid_Argument;
switch ( filter )
{
case FT_LCD_FILTER_NONE:
library->lcd_filter_func = NULL;
library->lcd_extra = 0;
break;
case FT_LCD_FILTER_DEFAULT:
#if defined( FT_FORCE_LEGACY_LCD_FILTER )
library->lcd_filter_func = _ft_lcd_filter_legacy;
library->lcd_extra = 0;
#elif defined( FT_FORCE_LIGHT_LCD_FILTER )
memcpy( library->lcd_weights, light_filter, 5 );
library->lcd_filter_func = _ft_lcd_filter_fir;
library->lcd_extra = 2;
#else
memcpy( library->lcd_weights, default_filter, 5 );
library->lcd_filter_func = _ft_lcd_filter_fir;
library->lcd_extra = 2;
#endif
break;
case FT_LCD_FILTER_LIGHT:
memcpy( library->lcd_weights, light_filter, 5 );
library->lcd_filter_func = _ft_lcd_filter_fir;
library->lcd_extra = 2;
break;
#ifdef USE_LEGACY
case FT_LCD_FILTER_LEGACY:
library->lcd_filter_func = _ft_lcd_filter_legacy;
library->lcd_extra = 0;
break;
#endif
default:
return FT_Err_Invalid_Argument;
}
library->lcd_filter = filter;
return 0;
}
#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
FT_EXPORT( FT_Error )
FT_Library_SetLcdFilter( FT_Library library,
FT_LcdFilter filter )
{
FT_UNUSED( library );
FT_UNUSED( filter );
return FT_Err_Unimplemented_Feature;
}
#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
/* END */

View File

@ -0,0 +1,202 @@
/***************************************************************************/
/* */
/* ftmm.c */
/* */
/* Multiple Master font support (body). */
/* */
/* Copyright 1996-2001, 2003, 2004 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 <freetype/ft2build.h>
#include FT_MULTIPLE_MASTERS_H
#include FT_INTERNAL_OBJECTS_H
#include FT_SERVICE_MULTIPLE_MASTERS_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_mm
static FT_Error
ft_face_get_mm_service( FT_Face face,
FT_Service_MultiMasters *aservice )
{
FT_Error error;
*aservice = NULL;
if ( !face )
return FT_Err_Invalid_Face_Handle;
error = FT_Err_Invalid_Argument;
if ( FT_HAS_MULTIPLE_MASTERS( face ) )
{
FT_FACE_LOOKUP_SERVICE( face,
*aservice,
MULTI_MASTERS );
if ( aservice )
error = FT_Err_Ok;
}
return error;
}
/* documentation is in ftmm.h */
FT_EXPORT_DEF( FT_Error )
FT_Get_Multi_Master( FT_Face face,
FT_Multi_Master *amaster )
{
FT_Error error;
FT_Service_MultiMasters service;
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
error = FT_Err_Invalid_Argument;
if ( service->get_mm )
error = service->get_mm( face, amaster );
}
return error;
}
/* documentation is in ftmm.h */
FT_EXPORT_DEF( FT_Error )
FT_Get_MM_Var( FT_Face face,
FT_MM_Var* *amaster )
{
FT_Error error;
FT_Service_MultiMasters service;
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
error = FT_Err_Invalid_Argument;
if ( service->get_mm_var )
error = service->get_mm_var( face, amaster );
}
return error;
}
/* documentation is in ftmm.h */
FT_EXPORT_DEF( FT_Error )
FT_Set_MM_Design_Coordinates( FT_Face face,
FT_UInt num_coords,
FT_Long* coords )
{
FT_Error error;
FT_Service_MultiMasters service;
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
error = FT_Err_Invalid_Argument;
if ( service->set_mm_design )
error = service->set_mm_design( face, num_coords, coords );
}
return error;
}
/* documentation is in ftmm.h */
FT_EXPORT_DEF( FT_Error )
FT_Set_Var_Design_Coordinates( FT_Face face,
FT_UInt num_coords,
FT_Fixed* coords )
{
FT_Error error;
FT_Service_MultiMasters service;
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
error = FT_Err_Invalid_Argument;
if ( service->set_var_design )
error = service->set_var_design( face, num_coords, coords );
}
return error;
}
/* documentation is in ftmm.h */
FT_EXPORT_DEF( FT_Error )
FT_Set_MM_Blend_Coordinates( FT_Face face,
FT_UInt num_coords,
FT_Fixed* coords )
{
FT_Error error;
FT_Service_MultiMasters service;
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
error = FT_Err_Invalid_Argument;
if ( service->set_mm_blend )
error = service->set_mm_blend( face, num_coords, coords );
}
return error;
}
/* documentation is in ftmm.h */
/* This is exactly the same as the previous function. It exists for */
/* orthogonality. */
FT_EXPORT_DEF( FT_Error )
FT_Set_Var_Blend_Coordinates( FT_Face face,
FT_UInt num_coords,
FT_Fixed* coords )
{
FT_Error error;
FT_Service_MultiMasters service;
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
error = FT_Err_Invalid_Argument;
if ( service->set_mm_blend )
error = service->set_mm_blend( face, num_coords, coords );
}
return error;
}
/* END */

View File

@ -0,0 +1,94 @@
/***************************************************************************/
/* */
/* 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, 2002 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 <freetype/ft2build.h>
#include FT_SFNT_NAMES_H
#include FT_INTERNAL_TRUETYPE_TYPES_H
#include FT_INTERNAL_STREAM_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 idx,
FT_SfntName *aname )
{
FT_Error error = FT_Err_Invalid_Argument;
if ( aname && face && FT_IS_SFNT( face ) )
{
TT_Face ttface = (TT_Face)face;
if ( idx < (FT_UInt)ttface->num_names )
{
TT_NameEntryRec* entry = ttface->name_table.names + idx;
/* load name on demand */
if ( entry->stringLength > 0 && entry->string == NULL )
{
FT_Memory memory = face->memory;
FT_Stream stream = face->stream;
if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) ||
FT_STREAM_SEEK( entry->stringOffset ) ||
FT_STREAM_READ( entry->string, entry->stringLength ) )
{
FT_FREE( entry->string );
entry->stringLength = 0;
}
}
aname->platform_id = entry->platformID;
aname->encoding_id = entry->encodingID;
aname->language_id = entry->languageID;
aname->name_id = entry->nameID;
aname->string = (FT_Byte*)entry->string;
aname->string_len = entry->stringLength;
error = FT_Err_Ok;
}
}
return error;
}
#endif /* TT_CONFIG_OPTION_SFNT_NAMES */
/* END */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,281 @@
/***************************************************************************/
/* */
/* ftpatent.c */
/* */
/* FreeType API for checking patented TrueType bytecode instructions */
/* (body). */
/* */
/* Copyright 2007 by David Turner. */
/* */
/* 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 <freetype/ft2build.h>
#include FT_FREETYPE_H
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_STREAM_H
#include FT_SERVICE_SFNT_H
#include FT_SERVICE_TRUETYPE_GLYF_H
static FT_Bool
_tt_check_patents_in_range( FT_Stream stream,
FT_ULong size )
{
FT_Bool result = FALSE;
FT_Error error;
FT_Bytes p, end;
if ( FT_FRAME_ENTER( size ) )
return 0;
p = stream->cursor;
end = p + size;
while ( p < end )
{
switch (p[0])
{
case 0x06: /* SPvTL // */
case 0x07: /* SPvTL + */
case 0x08: /* SFvTL // */
case 0x09: /* SFvTL + */
case 0x0A: /* SPvFS */
case 0x0B: /* SFvFS */
result = TRUE;
goto Exit;
case 0x40:
if ( p + 1 >= end )
goto Exit;
p += p[1] + 2;
break;
case 0x41:
if ( p + 1 >= end )
goto Exit;
p += p[1] * 2 + 2;
break;
case 0x71: /* DELTAP2 */
case 0x72: /* DELTAP3 */
case 0x73: /* DELTAC0 */
case 0x74: /* DELTAC1 */
case 0x75: /* DELTAC2 */
result = TRUE;
goto Exit;
case 0xB0:
case 0xB1:
case 0xB2:
case 0xB3:
case 0xB4:
case 0xB5:
case 0xB6:
case 0xB7:
p += ( p[0] - 0xB0 ) + 2;
break;
case 0xB8:
case 0xB9:
case 0xBA:
case 0xBB:
case 0xBC:
case 0xBD:
case 0xBE:
case 0xBF:
p += ( p[0] - 0xB8 ) * 2 + 3;
break;
default:
p += 1;
break;
}
}
Exit:
FT_FRAME_EXIT();
return result;
}
static FT_Bool
_tt_check_patents_in_table( FT_Face face,
FT_ULong tag )
{
FT_Stream stream = face->stream;
FT_Error error;
FT_Service_SFNT_Table service;
FT_Bool result = FALSE;
FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
if ( service )
{
FT_ULong offset, size;
error = service->table_info( face, tag, &offset, &size );
if ( error ||
FT_STREAM_SEEK( offset ) )
goto Exit;
result = _tt_check_patents_in_range( stream, size );
}
Exit:
return result;
}
static FT_Bool
_tt_face_check_patents( FT_Face face )
{
FT_Stream stream = face->stream;
FT_UInt gindex;
FT_Error error;
FT_Bool result;
FT_Service_TTGlyf service;
result = _tt_check_patents_in_table( face, TTAG_fpgm );
if ( result )
goto Exit;
result = _tt_check_patents_in_table( face, TTAG_prep );
if ( result )
goto Exit;
FT_FACE_FIND_SERVICE( face, service, TT_GLYF );
if ( service == NULL )
goto Exit;
for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ )
{
FT_ULong offset, num_ins, size;
FT_Int num_contours;
offset = service->get_location( face, gindex, &size );
if ( size == 0 )
continue;
if ( FT_STREAM_SEEK( offset ) ||
FT_READ_SHORT( num_contours ) )
continue;
if ( num_contours >= 0 ) /* simple glyph */
{
if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) )
continue;
}
else /* compound glyph */
{
FT_Bool has_instr = 0;
if ( FT_STREAM_SKIP( 8 ) )
continue;
/* now read each component */
for (;;)
{
FT_UInt flags, toskip;
if( FT_READ_USHORT( flags ) )
break;
toskip = 2 + 1 + 1;
if ( ( flags & ( 1 << 0 ) ) != 0 ) /* ARGS_ARE_WORDS */
toskip += 2;
if ( ( flags & ( 1 << 3 ) ) != 0 ) /* WE_HAVE_A_SCALE */
toskip += 2;
else if ( ( flags & ( 1 << 6 ) ) != 0 ) /* WE_HAVE_X_Y_SCALE */
toskip += 4;
else if ( ( flags & ( 1 << 7 ) ) != 0 ) /* WE_HAVE_A_2x2 */
toskip += 8;
if ( ( flags & ( 1 << 8 ) ) != 0 ) /* WE_HAVE_INSTRUCTIONS */
has_instr = 1;
if ( FT_STREAM_SKIP( toskip ) )
goto NextGlyph;
if ( ( flags & ( 1 << 5 ) ) == 0 ) /* MORE_COMPONENTS */
break;
}
if ( !has_instr )
goto NextGlyph;
}
if ( FT_READ_USHORT( num_ins ) )
continue;
result = _tt_check_patents_in_range( stream, num_ins );
if ( result )
goto Exit;
NextGlyph:
;
}
Exit:
return result;
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Bool )
FT_Face_CheckTrueTypePatents( FT_Face face )
{
FT_Bool result = FALSE;
if ( face && FT_IS_SFNT( face ) )
result = _tt_face_check_patents( face );
return result;
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Bool )
FT_Face_SetUnpatentedHinting( FT_Face face,
FT_Bool value )
{
FT_Bool result = 0;
#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
!defined( TT_CONFIG_OPTION_BYTECODE_INTEPRETER )
if ( face && FT_IS_SFNT( face ) )
{
result = !face->internal->ignore_unpatented_hinter;
face->internal->ignore_unpatented_hinter = !value;
}
#else
FT_UNUSED( face );
FT_UNUSED( value );
#endif
return result;
}
/* END */

View File

@ -0,0 +1,811 @@
/***************************************************************************/
/* */
/* ftrfork.c */
/* */
/* Embedded resource forks accessor (body). */
/* */
/* Copyright 2004, 2005, 2006, 2007 by */
/* Masatake YAMATO and Redhat K.K. */
/* */
/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */
/* derived from ftobjs.c. */
/* */
/* 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. */
/* */
/***************************************************************************/
/***************************************************************************/
/* Development of the code in this file is support of */
/* Information-technology Promotion Agency, Japan. */
/***************************************************************************/
#include <freetype/ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_RFORK_H
#undef FT_COMPONENT
#define FT_COMPONENT trace_raccess
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** ****/
/**** Resource fork directory access ****/
/**** ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
FT_BASE_DEF( FT_Error )
FT_Raccess_Get_HeaderInfo( FT_Library library,
FT_Stream stream,
FT_Long rfork_offset,
FT_Long *map_offset,
FT_Long *rdata_pos )
{
FT_Error error;
unsigned char head[16], head2[16];
FT_Long map_pos, rdata_len;
int allzeros, allmatch, i;
FT_Long type_list;
FT_UNUSED( library );
error = FT_Stream_Seek( stream, rfork_offset );
if ( error )
return error;
error = FT_Stream_Read( stream, (FT_Byte *)head, 16 );
if ( error )
return error;
*rdata_pos = rfork_offset + ( ( head[0] << 24 ) |
( head[1] << 16 ) |
( head[2] << 8 ) |
head[3] );
map_pos = rfork_offset + ( ( head[4] << 24 ) |
( head[5] << 16 ) |
( head[6] << 8 ) |
head[7] );
rdata_len = ( head[ 8] << 24 ) |
( head[ 9] << 16 ) |
( head[10] << 8 ) |
head[11];
/* map_len = head[12] .. head[15] */
if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset )
return FT_Err_Unknown_File_Format;
error = FT_Stream_Seek( stream, map_pos );
if ( error )
return error;
head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */
error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );
if ( error )
return error;
allzeros = 1;
allmatch = 1;
for ( i = 0; i < 16; ++i )
{
if ( head2[i] != 0 )
allzeros = 0;
if ( head2[i] != head[i] )
allmatch = 0;
}
if ( !allzeros && !allmatch )
return FT_Err_Unknown_File_Format;
/* If we have reached this point then it is probably a mac resource */
/* file. Now, does it contain any interesting resources? */
/* Skip handle to next resource map, the file resource number, and */
/* attributes. */
(void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */
+ 2 /* skip file resource number */
+ 2 ); /* skip attributes */
if ( FT_READ_USHORT( type_list ) )
return error;
if ( type_list == -1 )
return FT_Err_Unknown_File_Format;
error = FT_Stream_Seek( stream, map_pos + type_list );
if ( error )
return error;
*map_offset = map_pos + type_list;
return FT_Err_Ok;
}
static int
ft_raccess_sort_ref_by_id( FT_RFork_Ref* a,
FT_RFork_Ref* b )
{
if ( a->res_id < b->res_id )
return -1;
else if ( a->res_id > b->res_id )
return 1;
else
return 0;
}
FT_BASE_DEF( FT_Error )
FT_Raccess_Get_DataOffsets( FT_Library library,
FT_Stream stream,
FT_Long map_offset,
FT_Long rdata_pos,
FT_Long tag,
FT_Long **offsets,
FT_Long *count )
{
FT_Error error;
int i, j, cnt, subcnt;
FT_Long tag_internal, rpos;
FT_Memory memory = library->memory;
FT_Long temp;
FT_Long *offsets_internal;
FT_RFork_Ref *ref;
error = FT_Stream_Seek( stream, map_offset );
if ( error )
return error;
if ( FT_READ_USHORT( cnt ) )
return error;
cnt++;
for ( i = 0; i < cnt; ++i )
{
if ( FT_READ_LONG( tag_internal ) ||
FT_READ_USHORT( subcnt ) ||
FT_READ_USHORT( rpos ) )
return error;
FT_TRACE2(( "Resource tags: %c%c%c%c\n",
(char)( 0xff & ( tag_internal >> 24 ) ),
(char)( 0xff & ( tag_internal >> 16 ) ),
(char)( 0xff & ( tag_internal >> 8 ) ),
(char)( 0xff & ( tag_internal >> 0 ) ) ));
if ( tag_internal == tag )
{
*count = subcnt + 1;
rpos += map_offset;
error = FT_Stream_Seek( stream, rpos );
if ( error )
return error;
if ( FT_NEW_ARRAY( ref, *count ) )
return error;
for ( j = 0; j < *count; ++j )
{
if ( FT_READ_USHORT( ref[j].res_id ) )
goto Exit;
if ( FT_STREAM_SKIP( 2 ) ) /* resource name */
goto Exit;
if ( FT_READ_LONG( temp ) )
goto Exit;
if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
goto Exit;
ref[j].offset = temp & 0xFFFFFFL;
}
ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ),
( int(*)(const void*, const void*) )
ft_raccess_sort_ref_by_id );
if ( FT_NEW_ARRAY( offsets_internal, *count ) )
goto Exit;
/* XXX: duplicated reference ID,
* gap between reference IDs are acceptable?
* further investigation on Apple implementation is needed.
*/
for ( j = 0; j < *count; ++j )
offsets_internal[j] = rdata_pos + ref[j].offset;
*offsets = offsets_internal;
error = FT_Err_Ok;
Exit:
FT_FREE( ref );
return error;
}
}
return FT_Err_Cannot_Open_Resource;
}
#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** ****/
/**** Guessing functions ****/
/**** ****/
/**** When you add a new guessing function, ****/
/**** update FT_RACCESS_N_RULES in ftrfork.h. ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
typedef FT_Error
(*raccess_guess_func)( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset );
static FT_Error
raccess_guess_apple_double( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset );
static FT_Error
raccess_guess_apple_single( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset );
static FT_Error
raccess_guess_darwin_ufs_export( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset );
static FT_Error
raccess_guess_darwin_newvfs( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset );
static FT_Error
raccess_guess_darwin_hfsplus( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset );
static FT_Error
raccess_guess_vfat( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset );
static FT_Error
raccess_guess_linux_cap( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset );
static FT_Error
raccess_guess_linux_double( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset );
static FT_Error
raccess_guess_linux_netatalk( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset );
/*************************************************************************/
/**** ****/
/**** Helper functions ****/
/**** ****/
/*************************************************************************/
static FT_Error
raccess_guess_apple_generic( FT_Library library,
FT_Stream stream,
char *base_file_name,
FT_Int32 magic,
FT_Long *result_offset );
static FT_Error
raccess_guess_linux_double_from_file_name( FT_Library library,
char * file_name,
FT_Long *result_offset );
static char *
raccess_make_file_name( FT_Memory memory,
const char *original_name,
const char *insertion );
FT_BASE_DEF( void )
FT_Raccess_Guess( FT_Library library,
FT_Stream stream,
char* base_name,
char **new_names,
FT_Long *offsets,
FT_Error *errors )
{
FT_Long i;
raccess_guess_func funcs[FT_RACCESS_N_RULES] =
{
raccess_guess_apple_double,
raccess_guess_apple_single,
raccess_guess_darwin_ufs_export,
raccess_guess_darwin_newvfs,
raccess_guess_darwin_hfsplus,
raccess_guess_vfat,
raccess_guess_linux_cap,
raccess_guess_linux_double,
raccess_guess_linux_netatalk,
};
for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
{
new_names[i] = NULL;
if ( NULL != stream )
errors[i] = FT_Stream_Seek( stream, 0 );
else
errors[i] = FT_Err_Ok;
if ( errors[i] )
continue ;
errors[i] = (funcs[i])( library, stream, base_name,
&(new_names[i]), &(offsets[i]) );
}
return;
}
static FT_Error
raccess_guess_apple_double( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
FT_Int32 magic = ( 0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x07 );
*result_file_name = NULL;
if ( NULL == stream )
return FT_Err_Cannot_Open_Stream;
return raccess_guess_apple_generic( library, stream, base_file_name,
magic, result_offset );
}
static FT_Error
raccess_guess_apple_single( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
FT_Int32 magic = (0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x00);
*result_file_name = NULL;
if ( NULL == stream )
return FT_Err_Cannot_Open_Stream;
return raccess_guess_apple_generic( library, stream, base_file_name,
magic, result_offset );
}
static FT_Error
raccess_guess_darwin_ufs_export( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
char* newpath;
FT_Error error;
FT_Memory memory;
FT_UNUSED( stream );
memory = library->memory;
newpath = raccess_make_file_name( memory, base_file_name, "._" );
if ( !newpath )
return FT_Err_Out_Of_Memory;
error = raccess_guess_linux_double_from_file_name( library, newpath,
result_offset );
if ( !error )
*result_file_name = newpath;
else
FT_FREE( newpath );
return error;
}
static FT_Error
raccess_guess_darwin_hfsplus( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
/*
Only meaningful on systems with hfs+ drivers (or Macs).
*/
FT_Error error;
char* newpath;
FT_Memory memory;
FT_Long base_file_len = ft_strlen( base_file_name );
FT_UNUSED( stream );
memory = library->memory;
if ( base_file_len + 6 > FT_INT_MAX )
return FT_Err_Array_Too_Large;
if ( FT_ALLOC( newpath, base_file_len + 6 ) )
return error;
FT_MEM_COPY( newpath, base_file_name, base_file_len );
FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );
*result_file_name = newpath;
*result_offset = 0;
return FT_Err_Ok;
}
static FT_Error
raccess_guess_darwin_newvfs( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
/*
Only meaningful on systems with Mac OS X (> 10.1).
*/
FT_Error error;
char* newpath;
FT_Memory memory;
FT_Long base_file_len = ft_strlen( base_file_name );
FT_UNUSED( stream );
memory = library->memory;
if ( base_file_len + 18 > FT_INT_MAX )
return FT_Err_Array_Too_Large;
if ( FT_ALLOC( newpath, base_file_len + 18 ) )
return error;
FT_MEM_COPY( newpath, base_file_name, base_file_len );
FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 );
*result_file_name = newpath;
*result_offset = 0;
return FT_Err_Ok;
}
static FT_Error
raccess_guess_vfat( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
char* newpath;
FT_Memory memory;
FT_UNUSED( stream );
memory = library->memory;
newpath = raccess_make_file_name( memory, base_file_name,
"resource.frk/" );
if ( !newpath )
return FT_Err_Out_Of_Memory;
*result_file_name = newpath;
*result_offset = 0;
return FT_Err_Ok;
}
static FT_Error
raccess_guess_linux_cap( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
char* newpath;
FT_Memory memory;
FT_UNUSED( stream );
memory = library->memory;
newpath = raccess_make_file_name( memory, base_file_name, ".resource/" );
if ( !newpath )
return FT_Err_Out_Of_Memory;
*result_file_name = newpath;
*result_offset = 0;
return FT_Err_Ok;
}
static FT_Error
raccess_guess_linux_double( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
char* newpath;
FT_Error error;
FT_Memory memory;
FT_UNUSED( stream );
memory = library->memory;
newpath = raccess_make_file_name( memory, base_file_name, "%" );
if ( !newpath )
return FT_Err_Out_Of_Memory;
error = raccess_guess_linux_double_from_file_name( library, newpath,
result_offset );
if ( !error )
*result_file_name = newpath;
else
FT_FREE( newpath );
return error;
}
static FT_Error
raccess_guess_linux_netatalk( FT_Library library,
FT_Stream stream,
char *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
char* newpath;
FT_Error error;
FT_Memory memory;
FT_UNUSED( stream );
memory = library->memory;
newpath = raccess_make_file_name( memory, base_file_name,
".AppleDouble/" );
if ( !newpath )
return FT_Err_Out_Of_Memory;
error = raccess_guess_linux_double_from_file_name( library, newpath,
result_offset );
if ( !error )
*result_file_name = newpath;
else
FT_FREE( newpath );
return error;
}
static FT_Error
raccess_guess_apple_generic( FT_Library library,
FT_Stream stream,
char *base_file_name,
FT_Int32 magic,
FT_Long *result_offset )
{
FT_Int32 magic_from_stream;
FT_Error error;
FT_Int32 version_number = 0;
FT_UShort n_of_entries;
int i;
FT_UInt32 entry_id, entry_offset, entry_length = 0;
const FT_UInt32 resource_fork_entry_id = 0x2;
FT_UNUSED( library );
FT_UNUSED( base_file_name );
FT_UNUSED( version_number );
FT_UNUSED( entry_length );
if ( FT_READ_LONG( magic_from_stream ) )
return error;
if ( magic_from_stream != magic )
return FT_Err_Unknown_File_Format;
if ( FT_READ_LONG( version_number ) )
return error;
/* filler */
error = FT_Stream_Skip( stream, 16 );
if ( error )
return error;
if ( FT_READ_USHORT( n_of_entries ) )
return error;
if ( n_of_entries == 0 )
return FT_Err_Unknown_File_Format;
for ( i = 0; i < n_of_entries; i++ )
{
if ( FT_READ_LONG( entry_id ) )
return error;
if ( entry_id == resource_fork_entry_id )
{
if ( FT_READ_LONG( entry_offset ) ||
FT_READ_LONG( entry_length ) )
continue;
*result_offset = entry_offset;
return FT_Err_Ok;
}
else
FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */
}
return FT_Err_Unknown_File_Format;
}
static FT_Error
raccess_guess_linux_double_from_file_name( FT_Library library,
char *file_name,
FT_Long *result_offset )
{
FT_Open_Args args2;
FT_Stream stream2;
char * nouse = NULL;
FT_Error error;
args2.flags = FT_OPEN_PATHNAME;
args2.pathname = file_name;
error = FT_Stream_New( library, &args2, &stream2 );
if ( error )
return error;
error = raccess_guess_apple_double( library, stream2, file_name,
&nouse, result_offset );
FT_Stream_Free( stream2, 0 );
return error;
}
static char*
raccess_make_file_name( FT_Memory memory,
const char *original_name,
const char *insertion )
{
char* new_name;
char* tmp;
const char* slash;
unsigned new_length;
FT_Error error = FT_Err_Ok;
FT_UNUSED( error );
new_length = ft_strlen( original_name ) + ft_strlen( insertion );
if ( FT_ALLOC( new_name, new_length + 1 ) )
return NULL;
tmp = ft_strrchr( original_name, '/' );
if ( tmp )
{
ft_strncpy( new_name, original_name, tmp - original_name + 1 );
new_name[tmp - original_name + 1] = '\0';
slash = tmp + 1;
}
else
{
slash = original_name;
new_name[0] = '\0';
}
ft_strcat( new_name, insertion );
ft_strcat( new_name, slash );
return new_name;
}
#else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
/*************************************************************************/
/* Dummy function; just sets errors */
/*************************************************************************/
FT_BASE_DEF( void )
FT_Raccess_Guess( FT_Library library,
FT_Stream stream,
char *base_name,
char **new_names,
FT_Long *offsets,
FT_Error *errors )
{
int i;
FT_UNUSED( library );
FT_UNUSED( stream );
FT_UNUSED( base_name );
for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
{
new_names[i] = NULL;
offsets[i] = 0;
errors[i] = FT_Err_Unimplemented_Feature;
}
}
#endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
/* END */

View File

@ -0,0 +1,845 @@
/***************************************************************************/
/* */
/* ftstream.c */
/* */
/* I/O stream support (body). */
/* */
/* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008 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 <freetype/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_Stream_OpenMemory( FT_Stream stream,
const FT_Byte* base,
FT_ULong size )
{
stream->base = (FT_Byte*) base;
stream->size = size;
stream->pos = 0;
stream->cursor = 0;
stream->read = 0;
stream->close = 0;
}
FT_BASE_DEF( void )
FT_Stream_Close( FT_Stream stream )
{
if ( stream && stream->close )
stream->close( stream );
}
FT_BASE_DEF( FT_Error )
FT_Stream_Seek( FT_Stream stream,
FT_ULong pos )
{
FT_Error error = FT_Err_Ok;
stream->pos = pos;
if ( stream->read )
{
if ( stream->read( stream, pos, 0, 0 ) )
{
FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
pos, stream->size ));
error = FT_Err_Invalid_Stream_Operation;
}
}
/* note that seeking to the first position after the file is valid */
else if ( pos > stream->size )
{
FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
pos, stream->size ));
error = FT_Err_Invalid_Stream_Operation;
}
return error;
}
FT_BASE_DEF( FT_Error )
FT_Stream_Skip( FT_Stream stream,
FT_Long distance )
{
if ( distance < 0 )
return FT_Err_Invalid_Stream_Operation;
return FT_Stream_Seek( 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_Stream_Read( FT_Stream stream,
FT_Byte* buffer,
FT_ULong count )
{
return FT_Stream_ReadAt( stream, stream->pos, buffer, count );
}
FT_BASE_DEF( FT_Error )
FT_Stream_ReadAt( 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_Stream_ReadAt: 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;
FT_MEM_COPY( buffer, stream->base + pos, read_bytes );
}
stream->pos = pos + read_bytes;
if ( read_bytes < count )
{
FT_ERROR(( "FT_Stream_ReadAt:" ));
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_ULong )
FT_Stream_TryRead( FT_Stream stream,
FT_Byte* buffer,
FT_ULong count )
{
FT_ULong read_bytes = 0;
if ( stream->pos >= stream->size )
goto Exit;
if ( stream->read )
read_bytes = stream->read( stream, stream->pos, buffer, count );
else
{
read_bytes = stream->size - stream->pos;
if ( read_bytes > count )
read_bytes = count;
FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes );
}
stream->pos += read_bytes;
Exit:
return read_bytes;
}
FT_BASE_DEF( FT_Error )
FT_Stream_ExtractFrame( FT_Stream stream,
FT_ULong count,
FT_Byte** pbytes )
{
FT_Error error;
error = FT_Stream_EnterFrame( stream, count );
if ( !error )
{
*pbytes = (FT_Byte*)stream->cursor;
/* equivalent to FT_Stream_ExitFrame(), with no memory block release */
stream->cursor = 0;
stream->limit = 0;
}
return error;
}
FT_BASE_DEF( void )
FT_Stream_ReleaseFrame( FT_Stream stream,
FT_Byte** pbytes )
{
if ( stream->read )
{
FT_Memory memory = stream->memory;
#ifdef FT_DEBUG_MEMORY
ft_mem_free( memory, *pbytes );
*pbytes = NULL;
#else
FT_FREE( *pbytes );
#endif
}
*pbytes = 0;
}
FT_BASE_DEF( FT_Error )
FT_Stream_EnterFrame( 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;
#ifdef FT_DEBUG_MEMORY
/* assume _ft_debug_file and _ft_debug_lineno are already set */
stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error );
if ( error )
goto Exit;
#else
if ( FT_QALLOC( stream->base, count ) )
goto Exit;
#endif
/* read it */
read_bytes = stream->read( stream, stream->pos,
stream->base, count );
if ( read_bytes < count )
{
FT_ERROR(( "FT_Stream_EnterFrame:" ));
FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n",
count, read_bytes ));
FT_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_Stream_EnterFrame:" ));
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_Stream_ExitFrame( 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_Stream_EnterFrame() call, and this is not an error. */
/* */
FT_ASSERT( stream );
if ( stream->read )
{
FT_Memory memory = stream->memory;
#ifdef FT_DEBUG_MEMORY
ft_mem_free( memory, stream->base );
stream->base = NULL;
#else
FT_FREE( stream->base );
#endif
}
stream->cursor = 0;
stream->limit = 0;
}
FT_BASE_DEF( FT_Char )
FT_Stream_GetChar( 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_Stream_GetShort( 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 = FT_NEXT_SHORT( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Short )
FT_Stream_GetShortLE( 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 = FT_NEXT_SHORT_LE( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Long )
FT_Stream_GetOffset( 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 = FT_NEXT_OFF3( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Long )
FT_Stream_GetLong( 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 = FT_NEXT_LONG( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Long )
FT_Stream_GetLongLE( 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 = FT_NEXT_LONG_LE( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Char )
FT_Stream_ReadChar( 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_Stream_ReadChar: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
return 0;
}
FT_BASE_DEF( FT_Short )
FT_Stream_ReadShort( 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 = FT_NEXT_SHORT( p );
}
else
goto Fail;
stream->pos += 2;
return result;
Fail:
*error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadShort:" ));
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
return 0;
}
FT_BASE_DEF( FT_Short )
FT_Stream_ReadShortLE( 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 = FT_NEXT_SHORT_LE( p );
}
else
goto Fail;
stream->pos += 2;
return result;
Fail:
*error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadShortLE:" ));
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
return 0;
}
FT_BASE_DEF( FT_Long )
FT_Stream_ReadOffset( 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 = FT_NEXT_OFF3( p );
}
else
goto Fail;
stream->pos += 3;
return result;
Fail:
*error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadOffset:" ));
FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
return 0;
}
FT_BASE_DEF( FT_Long )
FT_Stream_ReadLong( 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 = FT_NEXT_LONG( p );
}
else
goto Fail;
stream->pos += 4;
return result;
Fail:
FT_ERROR(( "FT_Stream_ReadLong: 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_Stream_ReadLongLE( 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 = FT_NEXT_LONG_LE( p );
}
else
goto Fail;
stream->pos += 4;
return result;
Fail:
FT_ERROR(( "FT_Stream_ReadLongLE:" ));
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_Stream_ReadFields( 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_Stream_EnterFrame( 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;
FT_MEM_COPY( p, cursor, len );
}
cursor += len;
fields++;
continue;
}
case ft_frame_byte:
case ft_frame_schar: /* read a single byte */
value = FT_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 = FT_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 = FT_NEXT_USHORT_LE(cursor);
sign_shift = 16;
break;
case ft_frame_long_be:
case ft_frame_ulong_be: /* read a 4-byte big-endian long */
value = FT_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 = FT_NEXT_ULONG_LE(cursor);
sign_shift = 0;
break;
case ft_frame_off3_be:
case ft_frame_uoff3_be: /* read a 3-byte big-endian long */
value = FT_NEXT_UOFF3(cursor);
sign_shift = 8;
break;
case ft_frame_off3_le:
case ft_frame_uoff3_le: /* read a 3-byte little-endian long */
value = FT_NEXT_UOFF3_LE(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 (8 / FT_CHAR_BIT):
*(FT_Byte*)p = (FT_Byte)value;
break;
case (16 / FT_CHAR_BIT):
*(FT_UShort*)p = (FT_UShort)value;
break;
case (32 / FT_CHAR_BIT):
*(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_Stream_ExitFrame( stream );
return error;
}
/* END */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,159 @@
/***************************************************************************/
/* */
/* ftsynth.c */
/* */
/* FreeType synthesizing code for emboldening and slanting (body). */
/* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 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 <freetype/ft2build.h>
#include FT_SYNTHESIS_H
#include FT_INTERNAL_OBJECTS_H
#include FT_OUTLINE_H
#include FT_BITMAP_H
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** EXPERIMENTAL OBLIQUING SUPPORT ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/* documentation is in ftsynth.h */
FT_EXPORT_DEF( void )
FT_GlyphSlot_Oblique( FT_GlyphSlot slot )
{
FT_Matrix transform;
FT_Outline* outline = &slot->outline;
/* only oblique outline glyphs */
if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
return;
/* we don't touch the advance width */
/* For italic, simply apply a shear transform, with an angle */
/* of about 12 degrees. */
transform.xx = 0x10000L;
transform.yx = 0x00000L;
transform.xy = 0x06000L;
transform.yy = 0x10000L;
FT_Outline_Transform( outline, &transform );
}
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** EXPERIMENTAL EMBOLDENING/OUTLINING SUPPORT ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
FT_EXPORT_DEF( FT_Error )
FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot )
{
if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP &&
!( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
{
FT_Bitmap bitmap;
FT_Error error;
FT_Bitmap_New( &bitmap );
error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
if ( error )
return error;
slot->bitmap = bitmap;
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
}
return FT_Err_Ok;
}
/* documentation is in ftsynth.h */
FT_EXPORT_DEF( void )
FT_GlyphSlot_Embolden( FT_GlyphSlot slot )
{
FT_Library library = slot->library;
FT_Face face = FT_SLOT_FACE( slot );
FT_Error error;
FT_Pos xstr, ystr;
if ( slot->format != FT_GLYPH_FORMAT_OUTLINE &&
slot->format != FT_GLYPH_FORMAT_BITMAP )
return;
/* some reasonable strength */
xstr = FT_MulFix( face->units_per_EM,
face->size->metrics.y_scale ) / 24;
ystr = xstr;
if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
{
error = FT_Outline_Embolden( &slot->outline, xstr );
/* ignore error */
/* this is more than enough for most glyphs; if you need accurate */
/* values, you have to call FT_Outline_Get_CBox */
xstr = xstr * 2;
ystr = xstr;
}
else if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
{
xstr = FT_PIX_FLOOR( xstr );
if ( xstr == 0 )
xstr = 1 << 6;
ystr = FT_PIX_FLOOR( ystr );
error = FT_GlyphSlot_Own_Bitmap( slot );
if ( error )
return;
error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );
if ( error )
return;
}
if ( slot->advance.x )
slot->advance.x += xstr;
if ( slot->advance.y )
slot->advance.y += ystr;
slot->metrics.width += xstr;
slot->metrics.height += ystr;
slot->metrics.horiBearingY += ystr;
slot->metrics.horiAdvance += xstr;
slot->metrics.vertBearingX -= xstr / 2;
slot->metrics.vertBearingY += ystr;
slot->metrics.vertAdvance += ystr;
if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
slot->bitmap_top += ystr >> 6;
}
/* END */

View File

@ -0,0 +1,301 @@
/***************************************************************************/
/* */
/* ftsystem.c */
/* */
/* ANSI-specific FreeType low-level system interface (body). */
/* */
/* Copyright 1996-2001, 2002, 2006 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 <freetype/ft2build.h>
#include FT_CONFIG_CONFIG_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_SYSTEM_H
#include FT_ERRORS_H
#include FT_TYPES_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_mem_alloc() or ft_mem_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 ft_smalloc( 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 ft_srealloc( 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 );
ft_sfree( 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 ) ( (FT_FILE*)stream->descriptor.pointer )
/*************************************************************************/
/* */
/* <Function> */
/* ft_ansi_stream_close */
/* */
/* <Description> */
/* The function to close a stream. */
/* */
/* <Input> */
/* stream :: A pointer to the stream object. */
/* */
FT_CALLBACK_DEF( void )
ft_ansi_stream_close( FT_Stream stream )
{
ft_fclose( STREAM_FILE( stream ) );
stream->descriptor.pointer = NULL;
stream->size = 0;
stream->base = 0;
}
/*************************************************************************/
/* */
/* <Function> */
/* ft_ansi_stream_io */
/* */
/* <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_ansi_stream_io( FT_Stream stream,
unsigned long offset,
unsigned char* buffer,
unsigned long count )
{
FT_FILE* file;
file = STREAM_FILE( stream );
ft_fseek( file, offset, SEEK_SET );
return (unsigned long)ft_fread( buffer, 1, count, file );
}
/* documentation is in ftstream.h */
FT_BASE_DEF( FT_Error )
FT_Stream_Open( FT_Stream stream,
const char* filepathname )
{
FT_FILE* file;
if ( !stream )
return FT_Err_Invalid_Stream_Handle;
file = ft_fopen( filepathname, "rb" );
if ( !file )
{
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " could not open `%s'\n", filepathname ));
return FT_Err_Cannot_Open_Resource;
}
ft_fseek( file, 0, SEEK_END );
stream->size = ft_ftell( file );
ft_fseek( file, 0, SEEK_SET );
stream->descriptor.pointer = file;
stream->pathname.pointer = (char*)filepathname;
stream->pos = 0;
stream->read = ft_ansi_stream_io;
stream->close = ft_ansi_stream_close;
FT_TRACE1(( "FT_Stream_Open:" ));
FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
filepathname, stream->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_BASE_DEF( FT_Memory )
FT_New_Memory( void )
{
FT_Memory memory;
memory = (FT_Memory)ft_smalloc( 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_BASE_DEF( void )
FT_Done_Memory( FT_Memory memory )
{
#ifdef FT_DEBUG_MEMORY
ft_mem_debug_done( memory );
#endif
memory->free( memory, memory );
}
/* END */

View File

@ -0,0 +1,546 @@
/***************************************************************************/
/* */
/* fttrigon.c */
/* */
/* FreeType trigonometric functions (body). */
/* */
/* Copyright 2001, 2002, 2003, 2004, 2005 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 <freetype/ft2build.h>
#include FT_INTERNAL_OBJECTS_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 & 0xFFFFL;
k1 = FT_TRIG_SCALE >> 16; /* constant */
k2 = FT_TRIG_SCALE & 0xFFFFL; /* 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 1
/* determine msb bit index in `shift' */
if ( z >= ( 1L << 16 ) )
{
z >>= 16;
shift += 16;
}
if ( z >= ( 1L << 8 ) )
{
z >>= 8;
shift += 8;
}
if ( z >= ( 1L << 4 ) )
{
z >>= 4;
shift += 4;
}
if ( z >= ( 1L << 2 ) )
{
z >>= 2;
shift += 2;
}
if ( z >= ( 1L << 1 ) )
{
z >>= 1;
shift += 1;
}
if ( shift <= 27 )
{
shift = 27 - shift;
vec->x = x << shift;
vec->y = y << shift;
}
else
{
shift -= 27;
vec->x = x >> shift;
vec->y = y >> shift;
shift = -shift;
}
#else /* 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;
}
#endif /* 0 */
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 = FT_PAD_ROUND( theta, 32 );
else
theta = -FT_PAD_ROUND( -theta, 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;
}
/* these macros return 0 for positive numbers,
and -1 for negative ones */
#define FT_SIGN_LONG( x ) ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) )
#define FT_SIGN_INT( x ) ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) )
#define FT_SIGN_INT32( x ) ( (x) >> 31 )
#define FT_SIGN_INT16( x ) ( (x) >> 15 )
/* 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 )
{
FT_Int32 half = 1L << ( shift - 1 );
vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;
vec->y = ( v.y + half + FT_SIGN_LONG( 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 );
if ( shift > 0 )
return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift;
return 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;
}
/* documentation is in fttrigon.h */
FT_EXPORT_DEF( void )
FT_Vector_From_Polar( FT_Vector* vec,
FT_Fixed length,
FT_Angle angle )
{
vec->x = length;
vec->y = 0;
FT_Vector_Rotate( vec, angle );
}
/* documentation is in fttrigon.h */
FT_EXPORT_DEF( FT_Angle )
FT_Angle_Diff( FT_Angle angle1,
FT_Angle angle2 )
{
FT_Angle delta = angle2 - angle1;
delta %= FT_ANGLE_2PI;
if ( delta < 0 )
delta += FT_ANGLE_2PI;
if ( delta > FT_ANGLE_PI )
delta -= FT_ANGLE_2PI;
return delta;
}
/* END */

View File

@ -0,0 +1,501 @@
/***************************************************************************/
/* */
/* ftutil.c */
/* */
/* FreeType utility file for memory and list management (body). */
/* */
/* Copyright 2002, 2004, 2005, 2006, 2007 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 <freetype/ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_OBJECTS_H
#include FT_LIST_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_memory
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** *****/
/***** M E M O R Y M A N A G E M E N T *****/
/***** *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
FT_BASE_DEF( FT_Pointer )
ft_mem_alloc( FT_Memory memory,
FT_Long size,
FT_Error *p_error )
{
FT_Error error;
FT_Pointer block = ft_mem_qalloc( memory, size, &error );
if ( !error && size > 0 )
FT_MEM_ZERO( block, size );
*p_error = error;
return block;
}
FT_BASE_DEF( FT_Pointer )
ft_mem_qalloc( FT_Memory memory,
FT_Long size,
FT_Error *p_error )
{
FT_Error error = FT_Err_Ok;
FT_Pointer block = NULL;
if ( size > 0 )
{
block = memory->alloc( memory, size );
if ( block == NULL )
error = FT_Err_Out_Of_Memory;
}
else if ( size < 0 )
{
/* may help catch/prevent security issues */
error = FT_Err_Invalid_Argument;
}
*p_error = error;
return block;
}
FT_BASE_DEF( FT_Pointer )
ft_mem_realloc( FT_Memory memory,
FT_Long item_size,
FT_Long cur_count,
FT_Long new_count,
void* block,
FT_Error *p_error )
{
FT_Error error = FT_Err_Ok;
block = ft_mem_qrealloc( memory, item_size,
cur_count, new_count, block, &error );
if ( !error && new_count > cur_count )
FT_MEM_ZERO( (char*)block + cur_count * item_size,
( new_count - cur_count ) * item_size );
*p_error = error;
return block;
}
FT_BASE_DEF( FT_Pointer )
ft_mem_qrealloc( FT_Memory memory,
FT_Long item_size,
FT_Long cur_count,
FT_Long new_count,
void* block,
FT_Error *p_error )
{
FT_Error error = FT_Err_Ok;
/* Note that we now accept `item_size == 0' as a valid parameter, in
* order to cover very weird cases where an ALLOC_MULT macro would be
* called.
*/
if ( cur_count < 0 || new_count < 0 || item_size < 0 )
{
/* may help catch/prevent nasty security issues */
error = FT_Err_Invalid_Argument;
}
else if ( new_count == 0 || item_size == 0 )
{
ft_mem_free( memory, block );
block = NULL;
}
else if ( new_count > FT_INT_MAX/item_size )
{
error = FT_Err_Array_Too_Large;
}
else if ( cur_count == 0 )
{
FT_ASSERT( block == NULL );
block = ft_mem_alloc( memory, new_count*item_size, &error );
}
else
{
FT_Pointer block2;
FT_Long cur_size = cur_count*item_size;
FT_Long new_size = new_count*item_size;
block2 = memory->realloc( memory, cur_size, new_size, block );
if ( block2 == NULL )
error = FT_Err_Out_Of_Memory;
else
block = block2;
}
*p_error = error;
return block;
}
FT_BASE_DEF( void )
ft_mem_free( FT_Memory memory,
const void *P )
{
if ( P )
memory->free( memory, (void*)P );
}
FT_BASE_DEF( FT_Pointer )
ft_mem_dup( FT_Memory memory,
const void* address,
FT_ULong size,
FT_Error *p_error )
{
FT_Error error;
FT_Pointer p = ft_mem_qalloc( memory, size, &error );
if ( !error && address )
ft_memcpy( p, address, size );
*p_error = error;
return p;
}
FT_BASE_DEF( FT_Pointer )
ft_mem_strdup( FT_Memory memory,
const char* str,
FT_Error *p_error )
{
FT_ULong len = str ? (FT_ULong)ft_strlen( str ) + 1
: 0;
return ft_mem_dup( memory, str, len, p_error );
}
FT_BASE_DEF( FT_Int )
ft_mem_strcpyn( char* dst,
const char* src,
FT_ULong size )
{
while ( size > 1 && *src != 0 )
{
*dst++ = *src++;
size--;
}
*dst = 0; /* always zero-terminate */
return *src != 0;
}
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** *****/
/***** D O U B L Y L I N K E D L I S T S *****/
/***** *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
#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 );
FT_FREE( cur );
cur = next;
}
list->head = 0;
list->tail = 0;
}
FT_BASE_DEF( FT_UInt32 )
ft_highpow2( FT_UInt32 value )
{
FT_UInt32 value2;
/*
* We simply clear the lowest bit in each iteration. When
* we reach 0, we know that the previous value was our result.
*/
for ( ;; )
{
value2 = value & (value - 1); /* clear lowest bit */
if ( value2 == 0 )
break;
value = value2;
}
return value;
}
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
FT_BASE_DEF( FT_Error )
FT_Alloc( FT_Memory memory,
FT_Long size,
void* *P )
{
FT_Error error;
(void)FT_ALLOC( *P, size );
return error;
}
FT_BASE_DEF( FT_Error )
FT_QAlloc( FT_Memory memory,
FT_Long size,
void* *p )
{
FT_Error error;
(void)FT_QALLOC( *p, size );
return error;
}
FT_BASE_DEF( FT_Error )
FT_Realloc( FT_Memory memory,
FT_Long current,
FT_Long size,
void* *P )
{
FT_Error error;
(void)FT_REALLOC( *P, current, size );
return error;
}
FT_BASE_DEF( FT_Error )
FT_QRealloc( FT_Memory memory,
FT_Long current,
FT_Long size,
void* *p )
{
FT_Error error;
(void)FT_QREALLOC( *p, current, size );
return error;
}
FT_BASE_DEF( void )
FT_Free( FT_Memory memory,
void* *P )
{
if ( *P )
FT_MEM_FREE( *P );
}
#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
/* END */

View File

@ -0,0 +1,51 @@
/***************************************************************************/
/* */
/* ftwinfnt.c */
/* */
/* FreeType API for accessing Windows FNT specific info (body). */
/* */
/* Copyright 2003, 2004 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 <freetype/ft2build.h>
#include FT_WINFONTS_H
#include FT_INTERNAL_OBJECTS_H
#include FT_SERVICE_WINFNT_H
/* documentation is in ftwinfnt.h */
FT_EXPORT_DEF( FT_Error )
FT_Get_WinFNT_Header( FT_Face face,
FT_WinFNT_HeaderRec *header )
{
FT_Service_WinFnt service;
FT_Error error;
error = FT_Err_Invalid_Argument;
if ( face != NULL )
{
FT_FACE_LOOKUP_SERVICE( face, service, WINFNT );
if ( service != NULL )
{
error = service->get_header( face, header );
}
}
return error;
}
/* END */

View File

@ -0,0 +1,40 @@
/***************************************************************************/
/* */
/* ftxf86.c */
/* */
/* FreeType utility file for X11 support (body). */
/* */
/* Copyright 2002, 2003, 2004 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 <freetype/ft2build.h>
#include FT_XFREE86_H
#include FT_INTERNAL_OBJECTS_H
#include FT_SERVICE_XFREE86_NAME_H
/* documentation is in ftxf86.h */
FT_EXPORT_DEF( const char* )
FT_Get_X11_Font_Format( FT_Face face )
{
const char* result = NULL;
if ( face )
FT_FACE_FIND_SERVICE( face, result, XF86_NAME );
return result;
}
/* END */

View File

@ -0,0 +1,29 @@
/***************************************************************************/
/* */
/* cff.c */
/* */
/* FreeType OpenType driver component (body only). */
/* */
/* Copyright 1996-2001, 2002 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 <freetype/ft2build.h>
#include "cffdrivr.c"
#include "cffparse.c"
#include "cffload.c"
#include "cffobjs.c"
#include "cffgload.c"
#include "cffcmap.c"
/* END */

View File

@ -0,0 +1,224 @@
/***************************************************************************/
/* */
/* cffcmap.c */
/* */
/* CFF character mapping table (cmap) support (body). */
/* */
/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 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 "cffcmap.h"
#include "cffload.h"
#include "cfferrs.h"
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CFF STANDARD (AND EXPERT) ENCODING CMAPS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_CALLBACK_DEF( FT_Error )
cff_cmap_encoding_init( CFF_CMapStd cmap )
{
TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
CFF_Font cff = (CFF_Font)face->extra.data;
CFF_Encoding encoding = &cff->encoding;
cmap->gids = encoding->codes;
return 0;
}
FT_CALLBACK_DEF( void )
cff_cmap_encoding_done( CFF_CMapStd cmap )
{
cmap->gids = NULL;
}
FT_CALLBACK_DEF( FT_UInt )
cff_cmap_encoding_char_index( CFF_CMapStd cmap,
FT_UInt32 char_code )
{
FT_UInt result = 0;
if ( char_code < 256 )
result = cmap->gids[char_code];
return result;
}
FT_CALLBACK_DEF( FT_UInt )
cff_cmap_encoding_char_next( CFF_CMapStd cmap,
FT_UInt32 *pchar_code )
{
FT_UInt result = 0;
FT_UInt32 char_code = *pchar_code;
*pchar_code = 0;
if ( char_code < 255 )
{
FT_UInt code = (FT_UInt)(char_code + 1);
for (;;)
{
if ( code >= 256 )
break;
result = cmap->gids[code];
if ( result != 0 )
{
*pchar_code = code;
break;
}
code++;
}
}
return result;
}
FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
cff_cmap_encoding_class_rec =
{
sizeof ( CFF_CMapStdRec ),
(FT_CMap_InitFunc) cff_cmap_encoding_init,
(FT_CMap_DoneFunc) cff_cmap_encoding_done,
(FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index,
(FT_CMap_CharNextFunc) cff_cmap_encoding_char_next,
NULL, NULL, NULL, NULL, NULL
};
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_CALLBACK_DEF( const char* )
cff_sid_to_glyph_name( TT_Face face,
FT_UInt idx )
{
CFF_Font cff = (CFF_Font)face->extra.data;
CFF_Charset charset = &cff->charset;
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
FT_UInt sid = charset->sids[idx];
return cff_index_get_sid_string( &cff->string_index, sid, psnames );
}
FT_CALLBACK_DEF( void )
cff_sid_free_glyph_name( TT_Face face,
const char* gname )
{
FT_Memory memory = FT_FACE_MEMORY( face );
FT_FREE( gname );
}
FT_CALLBACK_DEF( FT_Error )
cff_cmap_unicode_init( PS_Unicodes unicodes )
{
TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
FT_Memory memory = FT_FACE_MEMORY( face );
CFF_Font cff = (CFF_Font)face->extra.data;
CFF_Charset charset = &cff->charset;
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
/* can't build Unicode map for CID-keyed font */
if ( !charset->sids )
return CFF_Err_Invalid_Argument;
return psnames->unicodes_init( memory,
unicodes,
cff->num_glyphs,
(PS_GetGlyphNameFunc)&cff_sid_to_glyph_name,
(PS_FreeGlyphNameFunc)&cff_sid_free_glyph_name,
(FT_Pointer)face );
}
FT_CALLBACK_DEF( void )
cff_cmap_unicode_done( PS_Unicodes unicodes )
{
FT_Face face = FT_CMAP_FACE( unicodes );
FT_Memory memory = FT_FACE_MEMORY( face );
FT_FREE( unicodes->maps );
unicodes->num_maps = 0;
}
FT_CALLBACK_DEF( FT_UInt )
cff_cmap_unicode_char_index( PS_Unicodes unicodes,
FT_UInt32 char_code )
{
TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
CFF_Font cff = (CFF_Font)face->extra.data;
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
return psnames->unicodes_char_index( unicodes, char_code );
}
FT_CALLBACK_DEF( FT_UInt )
cff_cmap_unicode_char_next( PS_Unicodes unicodes,
FT_UInt32 *pchar_code )
{
TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
CFF_Font cff = (CFF_Font)face->extra.data;
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
return psnames->unicodes_char_next( unicodes, pchar_code );
}
FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
cff_cmap_unicode_class_rec =
{
sizeof ( PS_UnicodesRec ),
(FT_CMap_InitFunc) cff_cmap_unicode_init,
(FT_CMap_DoneFunc) cff_cmap_unicode_done,
(FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index,
(FT_CMap_CharNextFunc) cff_cmap_unicode_char_next,
NULL, NULL, NULL, NULL, NULL
};
/* END */

View File

@ -0,0 +1,69 @@
/***************************************************************************/
/* */
/* cffcmap.h */
/* */
/* CFF character mapping table (cmap) support (specification). */
/* */
/* Copyright 2002, 2003, 2006 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 __CFFCMAP_H__
#define __CFFCMAP_H__
#include "cffobjs.h"
FT_BEGIN_HEADER
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* standard (and expert) encoding cmaps */
typedef struct CFF_CMapStdRec_* CFF_CMapStd;
typedef struct CFF_CMapStdRec_
{
FT_CMapRec cmap;
FT_UShort* gids; /* up to 256 elements */
} CFF_CMapStdRec;
FT_CALLBACK_TABLE const FT_CMap_ClassRec
cff_cmap_encoding_class_rec;
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* unicode (synthetic) cmaps */
FT_CALLBACK_TABLE const FT_CMap_ClassRec
cff_cmap_unicode_class_rec;
FT_END_HEADER
#endif /* __CFFCMAP_H__ */
/* END */

View File

@ -0,0 +1,610 @@
/***************************************************************************/
/* */
/* cffdrivr.c */
/* */
/* OpenType font driver implementation (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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 <freetype/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 FT_SERVICE_CID_H
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
#include FT_SERVICE_POSTSCRIPT_INFO_H
#include FT_SERVICE_POSTSCRIPT_NAME_H
#include FT_SERVICE_TT_CMAP_H
#include "cffdrivr.h"
#include "cffgload.h"
#include "cffload.h"
#include "cffcmap.h"
#include "cfferrs.h"
#include FT_SERVICE_XFREE86_NAME_H
#include FT_SERVICE_GLYPH_DICT_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> */
/* cff_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. */
/* */
FT_CALLBACK_DEF( FT_Error )
cff_get_kerning( FT_Face ttface, /* TT_Face */
FT_UInt left_glyph,
FT_UInt right_glyph,
FT_Vector* kerning )
{
TT_Face face = (TT_Face)ttface;
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
kerning->x = 0;
kerning->y = 0;
if ( sfnt )
kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
return CFF_Err_Ok;
}
#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 */
/* FT_LOAD_??? 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. */
/* */
FT_CALLBACK_DEF( FT_Error )
Load_Glyph( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */
FT_Size cffsize, /* CFF_Size */
FT_UInt glyph_index,
FT_Int32 load_flags )
{
FT_Error error;
CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot;
CFF_Size size = (CFF_Size)cffsize;
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;
/* reset the size object if necessary */
if ( load_flags & FT_LOAD_NO_SCALE )
size = NULL;
if ( size )
{
/* these two objects must have the same parent */
if ( cffsize->face != cffslot->face )
return CFF_Err_Invalid_Face_Handle;
}
/* now load the glyph outline if necessary */
error = cff_slot_load( slot, size, glyph_index, load_flags );
/* force drop-out mode to 2 - irrelevant now */
/* slot->outline.dropout_mode = 2; */
return error;
}
FT_CALLBACK_DEF(FT_Error)
cff_get_advances( FT_Face ftface,
FT_UInt start,
FT_UInt count,
FT_UInt flags,
FT_Fixed* advances )
{
CFF_Face face = (CFF_Face) ftface;
FT_UInt nn;
FT_Error error = 0;
FT_GlyphSlot slot = face->root.glyph;
flags |= FT_LOAD_ADVANCE_ONLY;
for (nn = 0; nn < count; nn++)
{
error = Load_Glyph( slot, face->root.size, start+nn, flags );
if (error) break;
advances[nn] = (flags & FT_LOAD_VERTICAL_LAYOUT)
? slot->advance.y
: slot->advance.x;
}
return error;
}
/*
* GLYPH DICT SERVICE
*
*/
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;
FT_Service_PsCMaps psnames;
FT_Error error;
FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
if ( !psnames )
{
FT_ERROR(( "cff_get_glyph_name:" ));
FT_ERROR(( " cannot get glyph name from 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_index_get_sid_string( &font->string_index, sid, psnames );
if ( gname )
FT_STRCPYN( buffer, gname, buffer_max );
FT_FREE( gname );
error = CFF_Err_Ok;
Exit:
return error;
}
static FT_UInt
cff_get_name_index( CFF_Face face,
FT_String* glyph_name )
{
CFF_Font cff;
CFF_Charset charset;
FT_Service_PsCMaps psnames;
FT_Memory memory = FT_FACE_MEMORY( face );
FT_String* name;
FT_UShort sid;
FT_UInt i;
FT_Int result;
cff = (CFF_FontRec *)face->extra.data;
charset = &cff->charset;
FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
if ( !psnames )
return 0;
for ( i = 0; i < cff->num_glyphs; i++ )
{
sid = charset->sids[i];
if ( sid > 390 )
name = cff_index_get_name( &cff->string_index, sid - 391 );
else
name = (FT_String *)psnames->adobe_std_strings( sid );
if ( !name )
continue;
result = ft_strcmp( glyph_name, name );
if ( sid > 390 )
FT_FREE( name );
if ( !result )
return i;
}
return 0;
}
static const FT_Service_GlyphDictRec cff_service_glyph_dict =
{
(FT_GlyphDict_GetNameFunc) cff_get_glyph_name,
(FT_GlyphDict_NameIndexFunc)cff_get_name_index,
};
/*
* POSTSCRIPT INFO SERVICE
*
*/
static FT_Int
cff_ps_has_glyph_names( FT_Face face )
{
return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
}
static FT_Error
cff_ps_get_font_info( CFF_Face face,
PS_FontInfoRec* afont_info )
{
CFF_Font cff = (CFF_Font)face->extra.data;
FT_Error error = FT_Err_Ok;
if ( cff && cff->font_info == NULL )
{
CFF_FontRecDict dict = &cff->top_font.font_dict;
PS_FontInfoRec *font_info;
FT_Memory memory = face->root.memory;
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
goto Fail;
font_info->version = cff_index_get_sid_string( &cff->string_index,
dict->version,
psnames );
font_info->notice = cff_index_get_sid_string( &cff->string_index,
dict->notice,
psnames );
font_info->full_name = cff_index_get_sid_string( &cff->string_index,
dict->full_name,
psnames );
font_info->family_name = cff_index_get_sid_string( &cff->string_index,
dict->family_name,
psnames );
font_info->weight = cff_index_get_sid_string( &cff->string_index,
dict->weight,
psnames );
font_info->italic_angle = dict->italic_angle;
font_info->is_fixed_pitch = dict->is_fixed_pitch;
font_info->underline_position = (FT_Short)dict->underline_position;
font_info->underline_thickness = (FT_Short)dict->underline_thickness;
cff->font_info = font_info;
}
*afont_info = *cff->font_info;
Fail:
return error;
}
static const FT_Service_PsInfoRec cff_service_ps_info =
{
(PS_GetFontInfoFunc) cff_ps_get_font_info,
(PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
(PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */
};
/*
* POSTSCRIPT NAME SERVICE
*
*/
static const char*
cff_get_ps_name( CFF_Face face )
{
CFF_Font cff = (CFF_Font)face->extra.data;
return (const char*)cff->font_name;
}
static const FT_Service_PsFontNameRec cff_service_ps_name =
{
(FT_PsName_GetFunc)cff_get_ps_name
};
/*
* TT CMAP INFO
*
* If the charmap is a synthetic Unicode encoding cmap or
* a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO
* service defined in SFNT module.
*
* Otherwise call the service function in the sfnt module.
*
*/
static FT_Error
cff_get_cmap_info( FT_CharMap charmap,
TT_CMapInfo *cmap_info )
{
FT_CMap cmap = FT_CMAP( charmap );
FT_Error error = CFF_Err_Ok;
cmap_info->language = 0;
if ( cmap->clazz != &cff_cmap_encoding_class_rec &&
cmap->clazz != &cff_cmap_unicode_class_rec )
{
FT_Face face = FT_CMAP_FACE( cmap );
FT_Library library = FT_FACE_LIBRARY( face );
FT_Module sfnt = FT_Get_Module( library, "sfnt" );
FT_Service_TTCMaps service =
(FT_Service_TTCMaps)ft_module_get_service( sfnt,
FT_SERVICE_ID_TT_CMAP );
if ( service && service->get_cmap_info )
error = service->get_cmap_info( charmap, cmap_info );
}
return error;
}
static const FT_Service_TTCMapsRec cff_service_get_cmap_info =
{
(TT_CMap_Info_GetFunc)cff_get_cmap_info
};
/*
* CID INFO SERVICE
*
*/
static FT_Error
cff_get_ros( CFF_Face face,
const char* *registry,
const char* *ordering,
FT_Int *supplement )
{
FT_Error error = CFF_Err_Ok;
CFF_Font cff = (CFF_Font)face->extra.data;
if ( cff )
{
CFF_FontRecDict dict = &cff->top_font.font_dict;
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
if ( dict->cid_registry == 0xFFFFU )
{
error = CFF_Err_Invalid_Argument;
goto Fail;
}
if ( registry )
{
if ( cff->registry == NULL )
cff->registry = cff_index_get_sid_string( &cff->string_index,
dict->cid_registry,
psnames );
*registry = cff->registry;
}
if ( ordering )
{
if ( cff->ordering == NULL )
cff->ordering = cff_index_get_sid_string( &cff->string_index,
dict->cid_ordering,
psnames );
*ordering = cff->ordering;
}
if ( supplement )
*supplement = dict->cid_supplement;
}
Fail:
return error;
}
static const FT_Service_CIDRec cff_service_cid_info =
{
(FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros
};
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** ****/
/**** D R I V E R I N T E R F A C E ****/
/**** ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
static const FT_ServiceDescRec cff_services[] =
{
{ FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF },
{ FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info },
{ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name },
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
{ FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict },
#endif
{ FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info },
{ FT_SERVICE_ID_CID, &cff_service_cid_info },
{ NULL, NULL }
};
FT_CALLBACK_DEF( FT_Module_Interface )
cff_get_interface( FT_Module driver, /* CFF_Driver */
const char* module_interface )
{
FT_Module sfnt;
FT_Module_Interface result;
result = ft_service_list_lookup( cff_services, module_interface );
if ( result != NULL )
return result;
/* we pass our request to the `sfnt' module */
sfnt = FT_Get_Module( driver->library, "sfnt" );
return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
}
/* The FT_DriverInterface structure is defined in ftdriver.h. */
FT_CALLBACK_TABLE_DEF
const FT_Driver_ClassRec 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 */
cff_driver_init,
cff_driver_done,
cff_get_interface,
},
/* now the specific driver fields */
sizeof( TT_FaceRec ),
sizeof( CFF_SizeRec ),
sizeof( CFF_GlyphSlotRec ),
cff_face_init,
cff_face_done,
cff_size_init,
cff_size_done,
cff_slot_init,
cff_slot_done,
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
ft_stub_set_char_sizes,
ft_stub_set_pixel_sizes,
#endif
Load_Glyph,
cff_get_kerning,
0, /* FT_Face_AttachFunc */
cff_get_advances, /* FT_Face_GetAdvancesFunc */
cff_size_request,
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
cff_size_select
#else
0 /* FT_Size_SelectFunc */
#endif
};
/* END */

View File

@ -0,0 +1,39 @@
/***************************************************************************/
/* */
/* cffdrivr.h */
/* */
/* High-level OpenType driver interface (specification). */
/* */
/* Copyright 1996-2001, 2002 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 <freetype/ft2build.h>
#include FT_INTERNAL_DRIVER_H
FT_BEGIN_HEADER
FT_CALLBACK_TABLE
const FT_Driver_ClassRec cff_driver_class;
FT_END_HEADER
#endif /* __CFFDRIVER_H__ */
/* END */

View File

@ -0,0 +1,41 @@
/***************************************************************************/
/* */
/* cfferrs.h */
/* */
/* CFF error codes (specification only). */
/* */
/* 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. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* This file is used to define the CFF error enumeration constants. */
/* */
/*************************************************************************/
#ifndef __CFFERRS_H__
#define __CFFERRS_H__
#include FT_MODULE_ERRORS_H
#undef __FTERRORS_H__
#define FT_ERR_PREFIX CFF_Err_
#define FT_ERR_BASE FT_Mod_Err_CFF
#include FT_ERRORS_H
#endif /* __CFFERRS_H__ */
/* END */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,206 @@
/***************************************************************************/
/* */
/* cffgload.h */
/* */
/* OpenType Glyph Loader (specification). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 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 <freetype/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. */
/* */
/* loader :: The current glyph loader. */
/* */
/* base :: The base glyph outline. */
/* */
/* current :: The current glyph outline. */
/* */
/* last :: The last point position. */
/* */
/* 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. */
/* */
/* metrics_only :: A boolean indicating that we only want to compute */
/* the metrics of a given glyph, not load all of its */
/* points. */
/* */
/* hints_funcs :: Auxiliary pointer for hinting. */
/* */
/* hints_globals :: Auxiliary pointer for hinting. */
/* */
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_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_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_Bool width_only;
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 */
FT_Render_Mode hint_mode;
} CFF_Decoder;
FT_LOCAL( void )
cff_decoder_init( CFF_Decoder* decoder,
TT_Face face,
CFF_Size size,
CFF_GlyphSlot slot,
FT_Bool hinting,
FT_Render_Mode hint_mode );
FT_LOCAL( void )
cff_decoder_set_width_only( CFF_Decoder* decoder );
FT_LOCAL( FT_Error )
cff_decoder_prepare( CFF_Decoder* decoder,
CFF_Size size,
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_decoder_parse_charstrings( CFF_Decoder* decoder,
FT_Byte* charstring_base,
FT_ULong charstring_len );
FT_LOCAL( FT_Error )
cff_slot_load( CFF_GlyphSlot glyph,
CFF_Size size,
FT_UInt glyph_index,
FT_Int32 load_flags );
FT_END_HEADER
#endif /* __CFFGLOAD_H__ */
/* END */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
/***************************************************************************/
/* */
/* cffload.h */
/* */
/* OpenType & CFF data/program tables loader (specification). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2007 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 <freetype/ft2build.h>
#include "cfftypes.h"
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
FT_BEGIN_HEADER
FT_LOCAL( FT_UShort )
cff_get_standard_encoding( FT_UInt charcode );
FT_LOCAL( FT_String* )
cff_index_get_name( CFF_Index idx,
FT_UInt element );
FT_LOCAL( FT_String* )
cff_index_get_sid_string( CFF_Index idx,
FT_UInt sid,
FT_Service_PsCMaps psnames );
FT_LOCAL( FT_Error )
cff_index_access_element( CFF_Index idx,
FT_UInt element,
FT_Byte** pbytes,
FT_ULong* pbyte_len );
FT_LOCAL( void )
cff_index_forget_element( CFF_Index idx,
FT_Byte** pbytes );
FT_LOCAL( FT_UInt )
cff_charset_cid_to_gindex( CFF_Charset charset,
FT_UInt cid );
FT_LOCAL( FT_Error )
cff_font_load( FT_Stream stream,
FT_Int face_index,
CFF_Font font );
FT_LOCAL( void )
cff_font_done( CFF_Font font );
FT_LOCAL( FT_Byte )
cff_fd_select_get( CFF_FDSelect fdselect,
FT_UInt glyph_index );
FT_END_HEADER
#endif /* __CFFLOAD_H__ */
/* END */

View File

@ -0,0 +1,962 @@
/***************************************************************************/
/* */
/* cffobjs.c */
/* */
/* OpenType objects manager (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 <freetype/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_SERVICE_POSTSCRIPT_CMAPS_H
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
#include "cffobjs.h"
#include "cffload.h"
#include "cffcmap.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_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->root.face;
CFF_Font font = (CFF_Font)face->extra.data;
PSHinter_Service pshinter = (PSHinter_Service)font->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 )
cff_size_done( FT_Size cffsize ) /* CFF_Size */
{
CFF_Size size = (CFF_Size)cffsize;
CFF_Face face = (CFF_Face)size->root.face;
CFF_Font font = (CFF_Font)face->extra.data;
CFF_Internal internal = (CFF_Internal)cffsize->internal;
if ( internal )
{
PSH_Globals_Funcs funcs;
funcs = cff_size_get_globals_funcs( size );
if ( funcs )
{
FT_UInt i;
funcs->destroy( internal->topfont );
for ( i = font->num_subfonts; i > 0; i-- )
funcs->destroy( internal->subfonts[i - 1] );
}
/* `internal' is freed by destroy_size (in ftobjs.c) */
}
}
/* CFF and Type 1 private dictionaries have slightly different */
/* structures; we need to synthetize a Type 1 dictionary on the fly */
static void
cff_make_private_dict( CFF_SubFont subfont,
PS_Private priv )
{
CFF_Private cpriv = &subfont->private_dict;
FT_UInt n, count;
FT_MEM_ZERO( priv, 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 = (FT_Int)cpriv->blue_shift;
priv->blue_fuzz = (FT_Int)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;
}
FT_LOCAL_DEF( FT_Error )
cff_size_init( FT_Size cffsize ) /* CFF_Size */
{
CFF_Size size = (CFF_Size)cffsize;
FT_Error error = CFF_Err_Ok;
PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size );
if ( funcs )
{
CFF_Face face = (CFF_Face)cffsize->face;
CFF_Font font = (CFF_Font)face->extra.data;
CFF_Internal internal;
PS_PrivateRec priv;
FT_Memory memory = cffsize->face->memory;
FT_UInt i;
if ( FT_NEW( internal ) )
goto Exit;
cff_make_private_dict( &font->top_font, &priv );
error = funcs->create( cffsize->face->memory, &priv,
&internal->topfont );
if ( error )
goto Exit;
for ( i = font->num_subfonts; i > 0; i-- )
{
CFF_SubFont sub = font->subfonts[i - 1];
cff_make_private_dict( sub, &priv );
error = funcs->create( cffsize->face->memory, &priv,
&internal->subfonts[i - 1] );
if ( error )
goto Exit;
}
cffsize->internal = (FT_Size_Internal)(void*)internal;
}
size->strike_index = 0xFFFFFFFFUL;
Exit:
return error;
}
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
FT_LOCAL_DEF( FT_Error )
cff_size_select( FT_Size size,
FT_ULong strike_index )
{
CFF_Size cffsize = (CFF_Size)size;
PSH_Globals_Funcs funcs;
cffsize->strike_index = strike_index;
FT_Select_Metrics( size->face, strike_index );
funcs = cff_size_get_globals_funcs( cffsize );
if ( funcs )
{
CFF_Face face = (CFF_Face)size->face;
CFF_Font font = (CFF_Font)face->extra.data;
CFF_Internal internal = (CFF_Internal)size->internal;
FT_Int top_upm = font->top_font.font_dict.units_per_em;
FT_UInt i;
funcs->set_scale( internal->topfont,
size->metrics.x_scale, size->metrics.y_scale,
0, 0 );
for ( i = font->num_subfonts; i > 0; i-- )
{
CFF_SubFont sub = font->subfonts[i - 1];
FT_Int sub_upm = sub->font_dict.units_per_em;
FT_Pos x_scale, y_scale;
if ( top_upm != sub_upm )
{
x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
}
else
{
x_scale = size->metrics.x_scale;
y_scale = size->metrics.y_scale;
}
funcs->set_scale( internal->subfonts[i - 1],
x_scale, y_scale, 0, 0 );
}
}
return CFF_Err_Ok;
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
FT_LOCAL_DEF( FT_Error )
cff_size_request( FT_Size size,
FT_Size_Request req )
{
CFF_Size cffsize = (CFF_Size)size;
PSH_Globals_Funcs funcs;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
if ( FT_HAS_FIXED_SIZES( size->face ) )
{
CFF_Face cffface = (CFF_Face)size->face;
SFNT_Service sfnt = (SFNT_Service)cffface->sfnt;
FT_ULong strike_index;
if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) )
cffsize->strike_index = 0xFFFFFFFFUL;
else
return cff_size_select( size, strike_index );
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
FT_Request_Metrics( size->face, req );
funcs = cff_size_get_globals_funcs( cffsize );
if ( funcs )
{
CFF_Face cffface = (CFF_Face)size->face;
CFF_Font font = (CFF_Font)cffface->extra.data;
CFF_Internal internal = (CFF_Internal)size->internal;
FT_Int top_upm = font->top_font.font_dict.units_per_em;
FT_UInt i;
funcs->set_scale( internal->topfont,
size->metrics.x_scale, size->metrics.y_scale,
0, 0 );
for ( i = font->num_subfonts; i > 0; i-- )
{
CFF_SubFont sub = font->subfonts[i - 1];
FT_Int sub_upm = sub->font_dict.units_per_em;
FT_Pos x_scale, y_scale;
if ( top_upm != sub_upm )
{
x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
}
else
{
x_scale = size->metrics.x_scale;
y_scale = size->metrics.y_scale;
}
funcs->set_scale( internal->subfonts[i - 1],
x_scale, y_scale, 0, 0 );
}
}
return CFF_Err_Ok;
}
/*************************************************************************/
/* */
/* SLOT FUNCTIONS */
/* */
/*************************************************************************/
FT_LOCAL_DEF( void )
cff_slot_done( FT_GlyphSlot slot )
{
slot->internal->glyph_hints = 0;
}
FT_LOCAL_DEF( FT_Error )
cff_slot_init( FT_GlyphSlot slot )
{
CFF_Face face = (CFF_Face)slot->face;
CFF_Font font = (CFF_Font)face->extra.data;
PSHinter_Service pshinter = (PSHinter_Service)font->pshinter;
if ( pshinter )
{
FT_Module module;
module = FT_Get_Module( slot->face->driver->root.library,
"pshinter" );
if ( module )
{
T2_Hints_Funcs funcs;
funcs = pshinter->get_t2_funcs( module );
slot->internal->glyph_hints = (void*)funcs;
}
}
return CFF_Err_Ok;
}
/*************************************************************************/
/* */
/* FACE FUNCTIONS */
/* */
/*************************************************************************/
static FT_String*
cff_strcpy( FT_Memory memory,
const FT_String* source )
{
FT_Error error;
FT_String* result;
(void)FT_STRDUP( result, source );
FT_UNUSED( error );
return result;
}
FT_LOCAL_DEF( FT_Error )
cff_face_init( FT_Stream stream,
FT_Face cffface, /* CFF_Face */
FT_Int face_index,
FT_Int num_params,
FT_Parameter* params )
{
CFF_Face face = (CFF_Face)cffface;
FT_Error error;
SFNT_Service sfnt;
FT_Service_PsCMaps psnames;
PSHinter_Service pshinter;
FT_Bool pure_cff = 1;
FT_Bool sfnt_format = 0;
#if 0
FT_FACE_FIND_GLOBAL_SERVICE( face, sfnt, SFNT );
FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_NAMES );
FT_FACE_FIND_GLOBAL_SERVICE( face, pshinter, POSTSCRIPT_HINTER );
if ( !sfnt )
goto Bad_Format;
#else
sfnt = (SFNT_Service)FT_Get_Module_Interface(
cffface->driver->root.library, "sfnt" );
if ( !sfnt )
goto Bad_Format;
FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
pshinter = (PSHinter_Service)FT_Get_Module_Interface(
cffface->driver->root.library, "pshinter" );
#endif
/* create input stream from resource */
if ( FT_STREAM_SEEK( 0 ) )
goto Exit;
/* check whether 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;
/* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */
if ( face_index > 0 )
{
FT_ERROR(( "cff_face_init: invalid face index\n" ));
error = CFF_Err_Invalid_Argument;
goto Exit;
}
sfnt_format = 1;
/* now, the font can be either an OpenType/CFF font, or an SVG CEF */
/* font; in the latter 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 explicitly */
error = sfnt->load_cmap( 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 ( FT_STREAM_SEEK( 0 ) )
goto Exit;
error = CFF_Err_Ok;
}
/* now load and parse the CFF table in the file */
{
CFF_Font cff;
CFF_FontRecDict dict;
FT_Memory memory = cffface->memory;
FT_Int32 flags;
FT_UInt i;
if ( FT_NEW( cff ) )
goto Exit;
face->extra.data = cff;
error = cff_font_load( stream, face_index, cff );
if ( error )
goto Exit;
cff->pshinter = pshinter;
cff->psnames = (void*)psnames;
/* Complement the root flags with some interesting information. */
/* Note that this is only necessary for pure CFF and CEF fonts; */
/* SFNT based fonts use the `name' table instead. */
cffface->num_glyphs = cff->num_glyphs;
dict = &cff->top_font.font_dict;
/* we need the `PSNames' module for CFF and CEF formats */
/* which aren't CID-keyed */
if ( dict->cid_registry == 0xFFFFU && !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;
}
if ( pure_cff )
{
char* style_name = NULL;
/* set up num_faces */
cffface->num_faces = cff->num_faces;
/* compute number of glyphs */
if ( dict->cid_registry != 0xFFFFU )
cffface->num_glyphs = cff->charset.max_cid;
else
cffface->num_glyphs = cff->charstrings_index.count;
/* set global bbox, as well as EM size */
cffface->bbox.xMin = dict->font_bbox.xMin >> 16;
cffface->bbox.yMin = dict->font_bbox.yMin >> 16;
cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16;
cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16;
if ( !dict->units_per_em )
dict->units_per_em = 1000;
cffface->units_per_EM = dict->units_per_em;
cffface->ascender = (FT_Short)( cffface->bbox.yMax );
cffface->descender = (FT_Short)( cffface->bbox.yMin );
cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
if ( cffface->height < cffface->ascender - cffface->descender )
cffface->height = (FT_Short)( cffface->ascender - cffface->descender );
cffface->underline_position =
(FT_Short)( dict->underline_position >> 16 );
cffface->underline_thickness =
(FT_Short)( dict->underline_thickness >> 16 );
/* retrieve font family & style name */
cffface->family_name = cff_index_get_name( &cff->name_index,
face_index );
if ( cffface->family_name )
{
char* full = cff_index_get_sid_string( &cff->string_index,
dict->full_name,
psnames );
char* fullp = full;
char* family = cffface->family_name;
char* family_name = 0;
if ( dict->family_name )
{
family_name = cff_index_get_sid_string( &cff->string_index,
dict->family_name,
psnames);
if ( family_name )
family = family_name;
}
/* We try to extract the style name from the full name. */
/* We need to ignore spaces and dashes during the search. */
if ( full && family )
{
while ( *fullp )
{
/* skip common characters at the start of both strings */
if ( *fullp == *family )
{
family++;
fullp++;
continue;
}
/* ignore spaces and dashes in full name during comparison */
if ( *fullp == ' ' || *fullp == '-' )
{
fullp++;
continue;
}
/* ignore spaces and dashes in family name during comparison */
if ( *family == ' ' || *family == '-' )
{
family++;
continue;
}
if ( !*family && *fullp )
{
/* The full name begins with the same characters as the */
/* family name, with spaces and dashes removed. In this */
/* case, the remaining string in `fullp' will be used as */
/* the style name. */
style_name = cff_strcpy( memory, fullp );
}
break;
}
if ( family_name )
FT_FREE( family_name );
FT_FREE( full );
}
}
else
{
char *cid_font_name =
cff_index_get_sid_string( &cff->string_index,
dict->cid_font_name,
psnames );
/* do we have a `/FontName' for a CID-keyed font? */
if ( cid_font_name )
cffface->family_name = cid_font_name;
}
if ( style_name )
cffface->style_name = style_name;
else
/* assume "Regular" style if we don't know better */
cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
/*******************************************************************/
/* */
/* Compute face flags. */
/* */
flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */
FT_FACE_FLAG_HORIZONTAL | /* horizontal data */
FT_FACE_FLAG_HINTER; /* has native hinter */
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
cffface->face_flags = flags;
/*******************************************************************/
/* */
/* Compute style flags. */
/* */
flags = 0;
if ( dict->italic_angle )
flags |= FT_STYLE_FLAG_ITALIC;
{
char *weight = cff_index_get_sid_string( &cff->string_index,
dict->weight,
psnames );
if ( weight )
if ( !ft_strcmp( weight, "Bold" ) ||
!ft_strcmp( weight, "Black" ) )
flags |= FT_STYLE_FLAG_BOLD;
FT_FREE( weight );
}
/* double check */
if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )
if ( !ft_strncmp( cffface->style_name, "Bold", 4 ) ||
!ft_strncmp( cffface->style_name, "Black", 5 ) )
flags |= FT_STYLE_FLAG_BOLD;
cffface->style_flags = flags;
}
else
{
if ( !dict->units_per_em )
dict->units_per_em = face->root.units_per_EM;
}
/* Normalize the font matrix so that `matrix->xx' is 1; the */
/* scaling is done with `units_per_em' then (at this point, */
/* it already contains the scaling factor, but without */
/* normalization of the matrix). */
/* */
/* Note that the offsets must be expressed in integer font */
/* units. */
{
FT_Matrix* matrix = &dict->font_matrix;
FT_Vector* offset = &dict->font_offset;
FT_ULong* upm = &dict->units_per_em;
FT_Fixed temp = FT_ABS( matrix->yy );
if ( temp != 0x10000L )
{
*upm = FT_DivFix( *upm, temp );
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 );
}
offset->x >>= 16;
offset->y >>= 16;
}
for ( i = cff->num_subfonts; i > 0; i-- )
{
CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict;
CFF_FontRecDict top = &cff->top_font.font_dict;
FT_Matrix* matrix;
FT_Vector* offset;
FT_ULong* upm;
FT_Fixed temp;
if ( sub->units_per_em )
{
FT_Int scaling;
if ( top->units_per_em > 1 && sub->units_per_em > 1 )
scaling = FT_MIN( top->units_per_em, sub->units_per_em );
else
scaling = 1;
FT_Matrix_Multiply_Scaled( &top->font_matrix,
&sub->font_matrix,
scaling );
FT_Vector_Transform_Scaled( &sub->font_offset,
&top->font_matrix,
scaling );
sub->units_per_em = FT_MulDiv( sub->units_per_em,
top->units_per_em,
scaling );
}
else
{
sub->font_matrix = top->font_matrix;
sub->font_offset = top->font_offset;
sub->units_per_em = top->units_per_em;
}
matrix = &sub->font_matrix;
offset = &sub->font_offset;
upm = &sub->units_per_em;
temp = FT_ABS( matrix->yy );
if ( temp != 0x10000L )
{
*upm = FT_DivFix( *upm, temp );
/* if *upm is larger than 100*1000 we divide by 1000 -- */
/* this can happen if e.g. there is no top-font FontMatrix */
/* and the subfont FontMatrix already contains the complete */
/* scaling for the subfont (see section 5.11 of the PLRM) */
/* 100 is a heuristic value */
if ( *upm > 100L * 1000L )
*upm = ( *upm + 500 ) / 1000;
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 );
}
offset->x >>= 16;
offset->y >>= 16;
}
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
/* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
/* has unset this flag because of the 3.0 `post' table. */
if ( dict->cid_registry == 0xFFFFU )
cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
#endif
if ( dict->cid_registry != 0xFFFFU )
cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
/*******************************************************************/
/* */
/* Compute char maps. */
/* */
/* Try to synthetize a Unicode charmap if there is none available */
/* already. If an OpenType font contains a Unicode "cmap", we */
/* will use it, whatever be in the CFF part of the file. */
{
FT_CharMapRec cmaprec;
FT_CharMap cmap;
FT_UInt nn;
CFF_Encoding encoding = &cff->encoding;
for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )
{
cmap = cffface->charmaps[nn];
/* Windows Unicode (3,1)? */
if ( cmap->platform_id == 3 && cmap->encoding_id == 1 )
goto Skip_Unicode;
/* Deprecated Unicode platform id? */
if ( cmap->platform_id == 0 )
goto Skip_Unicode; /* Standard Unicode (deprecated) */
}
/* since CID-keyed fonts don't contain glyph names, we can't */
/* construct a cmap */
if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
goto Exit;
/* we didn't find a Unicode charmap -- synthesize one */
cmaprec.face = cffface;
cmaprec.platform_id = 3;
cmaprec.encoding_id = 1;
cmaprec.encoding = FT_ENCODING_UNICODE;
nn = (FT_UInt)cffface->num_charmaps;
FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL );
/* if no Unicode charmap was previously selected, select this one */
if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
cffface->charmap = cffface->charmaps[nn];
Skip_Unicode:
if ( encoding->count > 0 )
{
FT_CMap_Class clazz;
cmaprec.face = cffface;
cmaprec.platform_id = 7; /* Adobe platform id */
if ( encoding->offset == 0 )
{
cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD;
clazz = &cff_cmap_encoding_class_rec;
}
else if ( encoding->offset == 1 )
{
cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT;
clazz = &cff_cmap_encoding_class_rec;
}
else
{
cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM;
clazz = &cff_cmap_encoding_class_rec;
}
FT_CMap_New( clazz, NULL, &cmaprec, NULL );
}
}
}
Exit:
return error;
Bad_Format:
error = CFF_Err_Unknown_File_Format;
goto Exit;
}
FT_LOCAL_DEF( void )
cff_face_done( FT_Face cffface ) /* CFF_Face */
{
CFF_Face face = (CFF_Face)cffface;
FT_Memory memory = cffface->memory;
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
if ( sfnt )
sfnt->done_face( face );
{
CFF_Font cff = (CFF_Font)face->extra.data;
if ( cff )
{
cff_font_done( cff );
FT_FREE( face->extra.data );
}
}
}
FT_LOCAL_DEF( FT_Error )
cff_driver_init( FT_Module module )
{
FT_UNUSED( module );
return CFF_Err_Ok;
}
FT_LOCAL_DEF( void )
cff_driver_done( FT_Module module )
{
FT_UNUSED( module );
}
/* END */

View File

@ -0,0 +1,181 @@
/***************************************************************************/
/* */
/* cffobjs.h */
/* */
/* OpenType objects manager (specification). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 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 <freetype/ft2build.h>
#include FT_INTERNAL_OBJECTS_H
#include "cfftypes.h"
#include FT_INTERNAL_TRUETYPE_TYPES_H
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
#include FT_INTERNAL_POSTSCRIPT_HINTS_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 struct CFF_SizeRec_
{
FT_SizeRec root;
FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */
} CFF_SizeRec, *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;
/*************************************************************************/
/* */
/* <Type> */
/* CFF_Internal */
/* */
/* <Description> */
/* The interface to the `internal' field of `FT_Size'. */
/* */
typedef struct CFF_InternalRec_
{
PSH_Globals topfont;
PSH_Globals subfonts[CFF_MAX_CID_FONTS];
} CFF_InternalRec, *CFF_Internal;
/*************************************************************************/
/* */
/* 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;
/***********************************************************************/
/* */
/* TrueType driver class. */
/* */
typedef struct CFF_DriverRec_
{
FT_DriverRec root;
void* extension_component;
} CFF_DriverRec;
FT_LOCAL( FT_Error )
cff_size_init( FT_Size size ); /* CFF_Size */
FT_LOCAL( void )
cff_size_done( FT_Size size ); /* CFF_Size */
FT_LOCAL( FT_Error )
cff_size_request( FT_Size size,
FT_Size_Request req );
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
FT_LOCAL( FT_Error )
cff_size_select( FT_Size size,
FT_ULong strike_index );
#endif
FT_LOCAL( void )
cff_slot_done( FT_GlyphSlot slot );
FT_LOCAL( FT_Error )
cff_slot_init( FT_GlyphSlot slot );
/*************************************************************************/
/* */
/* Face functions */
/* */
FT_LOCAL( FT_Error )
cff_face_init( FT_Stream stream,
FT_Face face, /* CFF_Face */
FT_Int face_index,
FT_Int num_params,
FT_Parameter* params );
FT_LOCAL( void )
cff_face_done( FT_Face face ); /* CFF_Face */
/*************************************************************************/
/* */
/* Driver functions */
/* */
FT_LOCAL( FT_Error )
cff_driver_init( FT_Module module );
FT_LOCAL( void )
cff_driver_done( FT_Module module );
FT_END_HEADER
#endif /* __CFFOBJS_H__ */
/* END */

View File

@ -0,0 +1,843 @@
/***************************************************************************/
/* */
/* cffparse.c */
/* */
/* CFF token stream parser (body) */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008 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 <freetype/ft2build.h>
#include "cffparse.h"
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_DEBUG_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_fixed_thousand,
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 )
{
FT_MEM_ZERO( parser, 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;
}
static const FT_Long power_tens[] =
{
1L,
10L,
100L,
1000L,
10000L,
100000L,
1000000L,
10000000L,
100000000L,
1000000000L
};
/* read a real */
static FT_Fixed
cff_parse_real( FT_Byte* start,
FT_Byte* limit,
FT_Int power_ten,
FT_Int* scaling )
{
FT_Byte* p = start;
FT_UInt nib;
FT_UInt phase;
FT_Long result, number, rest, exponent;
FT_Int sign = 0, exponent_sign = 0;
FT_Int exponent_add, integer_length, fraction_length;
if ( scaling )
*scaling = 0;
result = 0;
number = 0;
rest = 0;
exponent = 0;
exponent_add = 0;
integer_length = 0;
fraction_length = 0;
/* 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 initial 0x1E. */
if ( phase )
{
p++;
/* Make sure we don't read past the end. */
if ( p >= limit )
goto Exit;
}
/* Get the nibble. */
nib = ( p[0] >> phase ) & 0xF;
phase = 4 - phase;
if ( nib == 0xE )
sign = 1;
else if ( nib > 9 )
break;
else
{
/* Increase exponent if we can't add the digit. */
if ( number >= 0xCCCCCCCL )
exponent_add++;
/* Skip leading zeros. */
else if ( nib || number )
{
integer_length++;
number = number * 10 + nib;
}
}
}
/* Read fraction 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 Exit;
}
/* Get the nibble. */
nib = ( p[0] >> phase ) & 0xF;
phase = 4 - phase;
if ( nib >= 10 )
break;
/* Skip leading zeros if possible. */
if ( !nib && !number )
exponent_add--;
/* Only add digit if we don't overflow. */
else if ( number < 0xCCCCCCCL )
{
fraction_length++;
number = number * 10 + nib;
}
}
/* Read exponent, if any. */
if ( nib == 12 )
{
exponent_sign = 1;
nib = 11;
}
if ( nib == 11 )
{
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 Exit;
}
/* Get the nibble. */
nib = ( p[0] >> phase ) & 0xF;
phase = 4 - phase;
if ( nib >= 10 )
break;
exponent = exponent * 10 + nib;
/* Arbitrarily limit exponent. */
if ( exponent > 1000 )
goto Exit;
}
if ( exponent_sign )
exponent = -exponent;
}
/* We don't check `power_ten' and `exponent_add'. */
exponent += power_ten + exponent_add;
if ( scaling )
{
/* Only use `fraction_length'. */
fraction_length += integer_length;
exponent += integer_length;
if ( fraction_length <= 5 )
{
if ( number > 0x7FFFL )
{
result = FT_DivFix( number, 10 );
*scaling = exponent - fraction_length + 1;
}
else
{
if ( exponent > 0 )
{
FT_Int new_fraction_length, shift;
/* Make `scaling' as small as possible. */
new_fraction_length = FT_MIN( exponent, 5 );
exponent -= new_fraction_length;
shift = new_fraction_length - fraction_length;
number *= power_tens[shift];
if ( number > 0x7FFFL )
{
number /= 10;
exponent += 1;
}
}
else
exponent -= fraction_length;
result = number << 16;
*scaling = exponent;
}
}
else
{
if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
{
result = FT_DivFix( number, power_tens[fraction_length - 4] );
*scaling = exponent - 4;
}
else
{
result = FT_DivFix( number, power_tens[fraction_length - 5] );
*scaling = exponent - 5;
}
}
}
else
{
integer_length += exponent;
fraction_length -= exponent;
/* Check for overflow and underflow. */
if ( FT_ABS( integer_length ) > 5 )
goto Exit;
/* Convert into 16.16 format. */
if ( fraction_length > 0 )
{
if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
goto Exit;
result = FT_DivFix( number, power_tens[fraction_length] );
}
else
{
number *= power_tens[-fraction_length];
if ( number > 0x7FFFL )
goto Exit;
result = number << 16;
}
}
if ( sign )
result = -result;
Exit:
return result;
}
/* 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, NULL ) >> 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, NULL )
: cff_parse_integer( d[0], d[1] ) << 16;
}
/* read a floating point number, either integer or real, */
/* but return `10^scaling' times the number read in */
static FT_Fixed
cff_parse_fixed_scaled( FT_Byte** d,
FT_Int scaling )
{
return **d ==
30 ? cff_parse_real( d[0], d[1], scaling, NULL )
: (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16,
power_tens[scaling] );
}
/* read a floating point number, either integer or real, */
/* and return it as precise as possible -- `scaling' returns */
/* the scaling factor (as a power of 10) */
static FT_Fixed
cff_parse_fixed_dynamic( FT_Byte** d,
FT_Int* scaling )
{
FT_ASSERT( scaling );
if ( **d == 30 )
return cff_parse_real( d[0], d[1], 0, scaling );
else
{
FT_Long number;
FT_Int integer_length;
number = cff_parse_integer( d[0], d[1] );
if ( number > 0x7FFFL )
{
for ( integer_length = 5; integer_length < 10; integer_length++ )
if ( number < power_tens[integer_length] )
break;
if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
{
*scaling = integer_length - 4;
return FT_DivFix( number, power_tens[integer_length - 4] );
}
else
{
*scaling = integer_length - 5;
return FT_DivFix( number, power_tens[integer_length - 5] );
}
}
else
{
*scaling = 0;
return number << 16;
}
}
}
static FT_Error
cff_parse_font_matrix( CFF_Parser parser )
{
CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
FT_Matrix* matrix = &dict->font_matrix;
FT_Vector* offset = &dict->font_offset;
FT_ULong* upm = &dict->units_per_em;
FT_Byte** data = parser->stack;
FT_Error error = CFF_Err_Stack_Underflow;
if ( parser->top >= parser->stack + 6 )
{
FT_Int scaling;
error = CFF_Err_Ok;
/* We expect a well-formed font matrix, this is, the matrix elements */
/* `xx' and `yy' are of approximately the same magnitude. To avoid */
/* loss of precision, we use the magnitude of element `xx' to scale */
/* all other elements. The scaling factor is then contained in the */
/* `units_per_em' value. */
matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
scaling = -scaling;
if ( scaling < 0 || scaling > 9 )
{
/* Return default matrix in case of unlikely values. */
matrix->xx = 0x10000L;
matrix->yx = 0;
matrix->yx = 0;
matrix->yy = 0x10000L;
offset->x = 0;
offset->y = 0;
*upm = 1;
goto Exit;
}
matrix->yx = cff_parse_fixed_scaled( data++, scaling );
matrix->xy = cff_parse_fixed_scaled( data++, scaling );
matrix->yy = cff_parse_fixed_scaled( data++, scaling );
offset->x = cff_parse_fixed_scaled( data++, scaling );
offset->y = cff_parse_fixed_scaled( data, scaling );
*upm = power_tens[scaling];
}
Exit:
return error;
}
static FT_Error
cff_parse_font_bbox( CFF_Parser parser )
{
CFF_FontRecDict dict = (CFF_FontRecDict)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_FontRecDict dict = (CFF_FontRecDict)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_FontRecDict dict = (CFF_FontRecDict)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_FIXED_1000( code, name ) \
CFF_FIELD( code, name, cff_kind_fixed_thousand )
#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;
*parser->top = p;
code = v;
if ( v == 12 )
{
/* two byte operator */
p++;
if ( p >= limit )
goto Syntax_Error;
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;
/* check that we have enough arguments -- except for */
/* delta encoded arrays, which can be empty */
if ( field->kind != cff_kind_delta && num_args < 1 )
goto Stack_Underflow;
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 );
goto Store_Number;
case cff_kind_fixed_thousand:
val = cff_parse_fixed_scaled( parser->stack, 3 );
Store_Number:
switch ( field->size )
{
case (8 / FT_CHAR_BIT):
*(FT_Byte*)q = (FT_Byte)val;
break;
case (16 / FT_CHAR_BIT):
*(FT_Short*)q = (FT_Short)val;
break;
case (32 / FT_CHAR_BIT):
*(FT_Int32*)q = (FT_Int)val;
break;
default: /* for 64-bit systems */
*(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 (8 / FT_CHAR_BIT):
*(FT_Byte*)q = (FT_Byte)val;
break;
case (16 / FT_CHAR_BIT):
*(FT_Short*)q = (FT_Short)val;
break;
case (32 / FT_CHAR_BIT):
*(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 */

View File

@ -0,0 +1,69 @@
/***************************************************************************/
/* */
/* cffparse.h */
/* */
/* CFF token stream parser (specification) */
/* */
/* Copyright 1996-2001, 2002, 2003 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 <freetype/ft2build.h>
#include "cfftypes.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_ParserRec_
{
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_ParserRec, *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 */

View File

@ -0,0 +1,97 @@
/***************************************************************************/
/* */
/* cfftoken.h */
/* */
/* CFF token definitions (specification only). */
/* */
/* Copyright 1996-2001, 2002, 2003 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_FontRecDictRec
#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_FIXED ( 0x103, underline_position )
CFF_FIELD_FIXED ( 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, embedded_postscript )
#if 0
CFF_FIELD_STRING ( 0x116, base_font_name )
CFF_FIELD_DELTA ( 0x117, base_font_blend, 16 )
CFF_FIELD_CALLBACK( 0x118, multiple_master )
CFF_FIELD_CALLBACK( 0x119, blend_axis_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_PrivateRec
#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_1000( 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 */

View File

@ -0,0 +1,274 @@
/***************************************************************************/
/* */
/* cfftypes.h */
/* */
/* Basic OpenType/CFF type definitions and interface (specification */
/* only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008 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 __CFFTYPES_H__
#define __CFFTYPES_H__
#include <freetype/ft2build.h>
#include FT_FREETYPE_H
#include FT_TYPE1_TABLES_H
FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Struct> */
/* CFF_IndexRec */
/* */
/* <Description> */
/* A structure used to model a CFF Index table. */
/* */
/* <Fields> */
/* stream :: The source input stream. */
/* */
/* start :: The position of the first index byte in the */
/* input stream. */
/* */
/* count :: The number of elements in the index. */
/* */
/* off_size :: The size in bytes of object offsets in index. */
/* */
/* data_offset :: The position of first data byte in the index's */
/* bytes. */
/* */
/* data_size :: The size of the data table in this index. */
/* */
/* offsets :: A table of element offsets in the index. Must be */
/* loaded explicitly. */
/* */
/* bytes :: If the index is loaded in memory, its bytes. */
/* */
typedef struct CFF_IndexRec_
{
FT_Stream stream;
FT_ULong start;
FT_UInt count;
FT_Byte off_size;
FT_ULong data_offset;
FT_ULong data_size;
FT_ULong* offsets;
FT_Byte* bytes;
} CFF_IndexRec, *CFF_Index;
typedef struct CFF_EncodingRec_
{
FT_UInt format;
FT_ULong offset;
FT_UInt count;
FT_UShort sids [256]; /* avoid dynamic allocations */
FT_UShort codes[256];
} CFF_EncodingRec, *CFF_Encoding;
typedef struct CFF_CharsetRec_
{
FT_UInt format;
FT_ULong offset;
FT_UShort* sids;
FT_UShort* cids; /* the inverse mapping of `sids'; only needed */
/* for CID-keyed fonts */
FT_UInt max_cid;
FT_UInt num_glyphs;
} CFF_CharsetRec, *CFF_Charset;
typedef struct CFF_FontRecDictRec_
{
FT_UInt version;
FT_UInt notice;
FT_UInt copyright;
FT_UInt full_name;
FT_UInt family_name;
FT_UInt weight;
FT_Bool is_fixed_pitch;
FT_Fixed italic_angle;
FT_Fixed underline_position;
FT_Fixed underline_thickness;
FT_Int paint_type;
FT_Int charstring_type;
FT_Matrix font_matrix;
FT_ULong units_per_em; /* temporarily used as scaling value also */
FT_Vector font_offset;
FT_ULong unique_id;
FT_BBox font_bbox;
FT_Pos stroke_width;
FT_ULong charset_offset;
FT_ULong encoding_offset;
FT_ULong charstrings_offset;
FT_ULong private_offset;
FT_ULong private_size;
FT_Long synthetic_base;
FT_UInt embedded_postscript;
/* these should only be used for the top-level font dictionary */
FT_UInt cid_registry;
FT_UInt cid_ordering;
FT_ULong cid_supplement;
FT_Long cid_font_version;
FT_Long cid_font_revision;
FT_Long cid_font_type;
FT_ULong cid_count;
FT_ULong cid_uid_base;
FT_ULong cid_fd_array_offset;
FT_ULong cid_fd_select_offset;
FT_UInt cid_font_name;
} CFF_FontRecDictRec, *CFF_FontRecDict;
typedef struct CFF_PrivateRec_
{
FT_Byte num_blue_values;
FT_Byte num_other_blues;
FT_Byte num_family_blues;
FT_Byte num_family_other_blues;
FT_Pos blue_values[14];
FT_Pos other_blues[10];
FT_Pos family_blues[14];
FT_Pos family_other_blues[10];
FT_Fixed blue_scale;
FT_Pos blue_shift;
FT_Pos blue_fuzz;
FT_Pos standard_width;
FT_Pos standard_height;
FT_Byte num_snap_widths;
FT_Byte num_snap_heights;
FT_Pos snap_widths[13];
FT_Pos snap_heights[13];
FT_Bool force_bold;
FT_Fixed force_bold_threshold;
FT_Int lenIV;
FT_Int language_group;
FT_Fixed expansion_factor;
FT_Long initial_random_seed;
FT_ULong local_subrs_offset;
FT_Pos default_width;
FT_Pos nominal_width;
} CFF_PrivateRec, *CFF_Private;
typedef struct CFF_FDSelectRec_
{
FT_Byte format;
FT_UInt range_count;
/* that's the table, taken from the file `as is' */
FT_Byte* data;
FT_UInt data_size;
/* small cache for format 3 only */
FT_UInt cache_first;
FT_UInt cache_count;
FT_Byte cache_fd;
} CFF_FDSelectRec, *CFF_FDSelect;
/* A SubFont packs a font dict and a private dict together. They are */
/* needed to support CID-keyed CFF fonts. */
typedef struct CFF_SubFontRec_
{
CFF_FontRecDictRec font_dict;
CFF_PrivateRec private_dict;
CFF_IndexRec local_subrs_index;
FT_UInt num_local_subrs;
FT_Byte** local_subrs;
} CFF_SubFontRec, *CFF_SubFont;
/* maximum number of sub-fonts in a CID-keyed file */
#define CFF_MAX_CID_FONTS 32
typedef struct CFF_FontRec_
{
FT_Stream stream;
FT_Memory memory;
FT_UInt num_faces;
FT_UInt num_glyphs;
FT_Byte version_major;
FT_Byte version_minor;
FT_Byte header_size;
FT_Byte absolute_offsize;
CFF_IndexRec name_index;
CFF_IndexRec top_dict_index;
CFF_IndexRec string_index;
CFF_IndexRec global_subrs_index;
CFF_EncodingRec encoding;
CFF_CharsetRec charset;
CFF_IndexRec charstrings_index;
CFF_IndexRec font_dict_index;
CFF_IndexRec private_index;
CFF_IndexRec local_subrs_index;
FT_String* font_name;
FT_UInt num_global_subrs;
FT_Byte** global_subrs;
CFF_SubFontRec top_font;
FT_UInt num_subfonts;
CFF_SubFont subfonts[CFF_MAX_CID_FONTS];
CFF_FDSelectRec fd_select;
/* interface to PostScript hinter */
void* pshinter;
/* interface to Postscript Names service */
void* psnames;
/* since version 2.3.0 */
PS_FontInfoRec* font_info; /* font info dictionary */
/* since version 2.3.6 */
FT_String* registry;
FT_String* ordering;
} CFF_FontRec, *CFF_Font;
FT_END_HEADER
#endif /* __CFFTYPES_H__ */
/* END */

View File

@ -0,0 +1,475 @@
/***************************************************************************/
/* */
/* ftconfig.h */
/* */
/* ANSI-specific configuration file (specification only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 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. */
/* */
/* This ANSI version should stay in `include/freetype/config'. */
/* */
/*************************************************************************/
#ifndef __FTCONFIG_H__
#define __FTCONFIG_H__
#include <freetype/ft2build.h>
#include FT_CONFIG_OPTIONS_H
#include FT_CONFIG_STANDARD_LIBRARY_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. */
/* */
/*************************************************************************/
/* There are systems (like the Texas Instruments 'C54x) where a `char' */
/* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */
/* `int' has 16 bits also for this system, sizeof(int) gives 1 which */
/* is probably unexpected. */
/* */
/* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */
/* `char' type. */
#ifndef FT_CHAR_BIT
#define FT_CHAR_BIT CHAR_BIT
#endif
/* The size of an `int' type. */
#if FT_UINT_MAX == 0xFFFFUL
#define FT_SIZEOF_INT (16 / FT_CHAR_BIT)
#elif FT_UINT_MAX == 0xFFFFFFFFUL
#define FT_SIZEOF_INT (32 / FT_CHAR_BIT)
#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
#define FT_SIZEOF_INT (64 / FT_CHAR_BIT)
#else
#error "Unsupported size of `int' type!"
#endif
/* The size of a `long' type. A five-byte `long' (as used e.g. on the */
/* DM642) is recognized but avoided. */
#if FT_ULONG_MAX == 0xFFFFFFFFUL
#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT)
#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT)
#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT)
#else
#error "Unsupported size of `long' type!"
#endif
/* Preferred alignment of data */
#define FT_ALIGNMENT 8
/* FT_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. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* Mac support */
/* */
/* This is the only necessary change, so it is defined here instead */
/* providing a new configuration file. */
/* */
#if ( defined( __APPLE__ ) && !defined( DARWIN_NO_CARBON ) ) || \
( defined( __MWERKS__ ) && defined( macintosh ) )
/* no Carbon frameworks for 64bit 10.4.x */
#include "AvailabilityMacros.h"
#if defined( __LP64__ ) && \
( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
#define DARWIN_NO_CARBON 1
#else
#define FT_MACINTOSH 1
#endif
#endif
/*************************************************************************/
/* */
/* <Section> */
/* basic_types */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* <Type> */
/* FT_Int16 */
/* */
/* <Description> */
/* A typedef for a 16bit signed integer type. */
/* */
typedef signed short FT_Int16;
/*************************************************************************/
/* */
/* <Type> */
/* FT_UInt16 */
/* */
/* <Description> */
/* A typedef for a 16bit unsigned integer type. */
/* */
typedef unsigned short FT_UInt16;
/* */
/* this #if 0 ... #endif clause is for documentation purposes */
#if 0
/*************************************************************************/
/* */
/* <Type> */
/* FT_Int32 */
/* */
/* <Description> */
/* A typedef for a 32bit signed integer type. The size depends on */
/* the configuration. */
/* */
typedef signed XXX FT_Int32;
/*************************************************************************/
/* */
/* <Type> */
/* FT_UInt32 */
/* */
/* A typedef for a 32bit unsigned integer type. The size depends on */
/* the configuration. */
/* */
typedef unsigned XXX FT_UInt32;
/* */
#endif
#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT)
typedef signed int FT_Int32;
typedef unsigned int FT_UInt32;
#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT)
typedef signed long FT_Int32;
typedef unsigned long FT_UInt32;
#else
#error "no 32bit type found -- please check your configuration files"
#endif
/* look up an integer type that is at least 32 bits */
#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT)
typedef int FT_Fast;
typedef unsigned int FT_UFast;
#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT)
typedef long FT_Fast;
typedef unsigned long FT_UFast;
#endif
#if !defined(FT_CONFIG_OPTION_NO_ASSEMBLER)
/* provide assembler fragments for performance-critical
* functions. these must be defined static __inline__
* with GCC
*/
#if defined(__GNUC__)
# if defined(__arm__) && !defined(__thumb__)
# define FT_MULFIX_ASSEMBLER FT_MulFix_arm
static __inline__ FT_Int32
FT_MulFix_arm( FT_Int32 a, FT_Int32 b )
{
register FT_Int32 t, t2;
asm __volatile__ (
"smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
"mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
"add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
"adds %1, %1, %0\n\t" /* %1 += %0 */
"adc %2, %2, #0\n\t" /* %2 += carry */
"mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */
"orr %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */
: "=r"(a), "=&r"(t2), "=&r"(t)
: "r"(a), "r"(b)
);
return a;
}
# endif
# if defined(i386)
# define FT__MULFIX_ASSEMBLER FT_MulFix_i386
static __inline__ FT_Int32
FT_MulFix_i386( FT_Int32 a, FT_Int32 b )
{
register FT_Int32 result;
__asm__ __volatile__ (
"imul %%edx\n"
"movl %%edx, %%ecx\n"
"sarl $31, %%ecx\n"
"addl $0x8000, %%ecx\n"
"addl %%ecx, %%eax\n"
"adcl $0, %%edx\n"
"shrl $16, %%eax\n"
"shll $16, %%edx\n"
"addl %%edx, %%eax\n"
: "=a"(result)
: "a"(a), "d"(b)
: "%ecx"
);
return result;
}
# endif
#endif /* __GNUC__ */
#endif /* !NO_ASSEMBLER */
#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
# ifdef FT_MULFIX_ASSEMBLER
# define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER
# endif
#endif
/* determine whether we have a 64-bit int type for platforms without */
/* Autoconf */
#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT)
/* FT_LONG64 must be defined if a 64-bit type is available */
#define FT_LONG64
#define FT_INT64 long
#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
/* this compiler provides the __int64 type */
#define FT_LONG64
#define FT_INT64 __int64
#elif defined( __BORLANDC__ ) /* Borland C++ */
/* XXXX: We should probably check the value of __BORLANDC__ in order */
/* to test the compiler version. */
/* this compiler provides the __int64 type */
#define FT_LONG64
#define FT_INT64 __int64
#elif defined( __WATCOMC__ ) /* Watcom C++ */
/* Watcom doesn't provide 64-bit data types */
#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */
#define FT_LONG64
#define FT_INT64 long long int
#elif defined( __GNUC__ )
/* GCC provides the `long long' type */
#define FT_LONG64
#define FT_INT64 long long int
#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
#define FT_BEGIN_STMNT do {
#define FT_END_STMNT } while ( 0 )
#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT
/*************************************************************************/
/* */
/* A 64-bit data type will create compilation problems if you compile */
/* in strict ANSI mode. To avoid them, we disable their use if */
/* __STDC__ is defined. You can however ignore this rule by */
/* defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */
/* */
#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 )
#ifdef __STDC__
/* undefine the 64-bit macros in strict ANSI compilation mode */
#undef FT_LONG64
#undef FT_INT64
#endif /* __STDC__ */
#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */
#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
#define FT_LOCAL( x ) static x
#define FT_LOCAL_DEF( x ) static x
#else
#ifdef __cplusplus
#define FT_LOCAL( x ) extern "C" x
#define FT_LOCAL_DEF( x ) extern "C" x
#else
#define FT_LOCAL( x ) extern x
#define FT_LOCAL_DEF( x ) x
#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 ) 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 */

View File

@ -0,0 +1,777 @@
/***************************************************************************/
/* */
/* ftheader.h */
/* */
/* Build macros of the FreeType 2 library. */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 __FT_HEADER_H__
#define __FT_HEADER_H__
/*@***********************************************************************/
/* */
/* <Macro> */
/* FT_BEGIN_HEADER */
/* */
/* <Description> */
/* This macro is used in association with @FT_END_HEADER in header */
/* files to ensure that the declarations within are properly */
/* encapsulated in an `extern "C" { .. }' block when included from a */
/* C++ compiler. */
/* */
#ifdef __cplusplus
#define FT_BEGIN_HEADER extern "C" {
#else
#define FT_BEGIN_HEADER /* nothing */
#endif
/*@***********************************************************************/
/* */
/* <Macro> */
/* FT_END_HEADER */
/* */
/* <Description> */
/* This macro is used in association with @FT_BEGIN_HEADER in header */
/* files to ensure that the declarations within are properly */
/* encapsulated in an `extern "C" { .. }' block when included from a */
/* C++ compiler. */
/* */
#ifdef __cplusplus
#define FT_END_HEADER }
#else
#define FT_END_HEADER /* nothing */
#endif
/*************************************************************************/
/* */
/* Aliases for the FreeType 2 public and configuration files. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* <Section> */
/* header_file_macros */
/* */
/* <Title> */
/* Header File Macros */
/* */
/* <Abstract> */
/* Macro definitions used to #include specific header files. */
/* */
/* <Description> */
/* The following macros are defined to the name of specific */
/* FreeType 2 header files. They can be used directly in #include */
/* statements as in: */
/* */
/* { */
/* #include FT_FREETYPE_H */
/* #include FT_MULTIPLE_MASTERS_H */
/* #include FT_GLYPH_H */
/* } */
/* */
/* There are several reasons why we are now using macros to name */
/* public header files. The first one is that such macros are not */
/* limited to the infamous 8.3 naming rule required by DOS (and */
/* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */
/* */
/* The second reason is that it allows for more flexibility in the */
/* way FreeType 2 is installed on a given system. */
/* */
/*************************************************************************/
/* configuration files */
/*************************************************************************
*
* @macro:
* FT_CONFIG_CONFIG_H
*
* @description:
* A macro used in #include statements to name the file containing
* FreeType 2 configuration data.
*
*/
#ifndef FT_CONFIG_CONFIG_H
#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h>
#endif
/*************************************************************************
*
* @macro:
* FT_CONFIG_STANDARD_LIBRARY_H
*
* @description:
* A macro used in #include statements to name the file containing
* FreeType 2 interface to the standard C library functions.
*
*/
#ifndef FT_CONFIG_STANDARD_LIBRARY_H
#define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h>
#endif
/*************************************************************************
*
* @macro:
* FT_CONFIG_OPTIONS_H
*
* @description:
* A macro used in #include statements to name the file containing
* FreeType 2 project-specific configuration options.
*
*/
#ifndef FT_CONFIG_OPTIONS_H
#define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h>
#endif
/*************************************************************************
*
* @macro:
* FT_CONFIG_MODULES_H
*
* @description:
* A macro used in #include statements to name the file containing the
* list of FreeType 2 modules that are statically linked to new library
* instances in @FT_Init_FreeType.
*
*/
#ifndef FT_CONFIG_MODULES_H
#define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h>
#endif
/* */
/* public headers */
/*************************************************************************
*
* @macro:
* FT_FREETYPE_H
*
* @description:
* A macro used in #include statements to name the file containing the
* base FreeType 2 API.
*
*/
#define FT_FREETYPE_H <freetype/freetype.h>
/*************************************************************************
*
* @macro:
* FT_ERRORS_H
*
* @description:
* A macro used in #include statements to name the file containing the
* list of FreeType 2 error codes (and messages).
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_ERRORS_H <freetype/fterrors.h>
/*************************************************************************
*
* @macro:
* FT_MODULE_ERRORS_H
*
* @description:
* A macro used in #include statements to name the file containing the
* list of FreeType 2 module error offsets (and messages).
*
*/
#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h>
/*************************************************************************
*
* @macro:
* FT_SYSTEM_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 interface to low-level operations (i.e., memory management
* and stream i/o).
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_SYSTEM_H <freetype/ftsystem.h>
/*************************************************************************
*
* @macro:
* FT_IMAGE_H
*
* @description:
* A macro used in #include statements to name the file containing type
* definitions related to glyph images (i.e., bitmaps, outlines,
* scan-converter parameters).
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_IMAGE_H <freetype/ftimage.h>
/*************************************************************************
*
* @macro:
* FT_TYPES_H
*
* @description:
* A macro used in #include statements to name the file containing the
* basic data types defined by FreeType 2.
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_TYPES_H <freetype/fttypes.h>
/*************************************************************************
*
* @macro:
* FT_LIST_H
*
* @description:
* A macro used in #include statements to name the file containing the
* list management API of FreeType 2.
*
* (Most applications will never need to include this file.)
*
*/
#define FT_LIST_H <freetype/ftlist.h>
/*************************************************************************
*
* @macro:
* FT_OUTLINE_H
*
* @description:
* A macro used in #include statements to name the file containing the
* scalable outline management API of FreeType 2.
*
*/
#define FT_OUTLINE_H <freetype/ftoutln.h>
/*************************************************************************
*
* @macro:
* FT_SIZES_H
*
* @description:
* A macro used in #include statements to name the file containing the
* API which manages multiple @FT_Size objects per face.
*
*/
#define FT_SIZES_H <freetype/ftsizes.h>
/*************************************************************************
*
* @macro:
* FT_MODULE_H
*
* @description:
* A macro used in #include statements to name the file containing the
* module management API of FreeType 2.
*
*/
#define FT_MODULE_H <freetype/ftmodapi.h>
/*************************************************************************
*
* @macro:
* FT_RENDER_H
*
* @description:
* A macro used in #include statements to name the file containing the
* renderer module management API of FreeType 2.
*
*/
#define FT_RENDER_H <freetype/ftrender.h>
/*************************************************************************
*
* @macro:
* FT_TYPE1_TABLES_H
*
* @description:
* A macro used in #include statements to name the file containing the
* types and API specific to the Type 1 format.
*
*/
#define FT_TYPE1_TABLES_H <freetype/t1tables.h>
/*************************************************************************
*
* @macro:
* FT_TRUETYPE_IDS_H
*
* @description:
* A macro used in #include statements to name the file containing the
* enumeration values which identify name strings, languages, encodings,
* etc. This file really contains a _large_ set of constant macro
* definitions, taken from the TrueType and OpenType specifications.
*
*/
#define FT_TRUETYPE_IDS_H <freetype/ttnameid.h>
/*************************************************************************
*
* @macro:
* FT_TRUETYPE_TABLES_H
*
* @description:
* A macro used in #include statements to name the file containing the
* types and API specific to the TrueType (as well as OpenType) format.
*
*/
#define FT_TRUETYPE_TABLES_H <freetype/tttables.h>
/*************************************************************************
*
* @macro:
* FT_TRUETYPE_TAGS_H
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of TrueType four-byte `tags' which identify blocks in
* SFNT-based font formats (i.e., TrueType and OpenType).
*
*/
#define FT_TRUETYPE_TAGS_H <freetype/tttags.h>
/*************************************************************************
*
* @macro:
* FT_BDF_H
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of an API which accesses BDF-specific strings from a
* face.
*
*/
#define FT_BDF_H <freetype/ftbdf.h>
/*************************************************************************
*
* @macro:
* FT_CID_H
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of an API which access CID font information from a
* face.
*
*/
#define FT_CID_H <freetype/ftcid.h>
/*************************************************************************
*
* @macro:
* FT_GZIP_H
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of an API which supports gzip-compressed files.
*
*/
#define FT_GZIP_H <freetype/ftgzip.h>
/*************************************************************************
*
* @macro:
* FT_LZW_H
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of an API which supports LZW-compressed files.
*
*/
#define FT_LZW_H <freetype/ftlzw.h>
/*************************************************************************
*
* @macro:
* FT_WINFONTS_H
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of an API which supports Windows FNT files.
*
*/
#define FT_WINFONTS_H <freetype/ftwinfnt.h>
/*************************************************************************
*
* @macro:
* FT_GLYPH_H
*
* @description:
* A macro used in #include statements to name the file containing the
* API of the optional glyph management component.
*
*/
#define FT_GLYPH_H <freetype/ftglyph.h>
/*************************************************************************
*
* @macro:
* FT_BITMAP_H
*
* @description:
* A macro used in #include statements to name the file containing the
* API of the optional bitmap conversion component.
*
*/
#define FT_BITMAP_H <freetype/ftbitmap.h>
/*************************************************************************
*
* @macro:
* FT_BBOX_H
*
* @description:
* A macro used in #include statements to name the file containing the
* API of the optional exact bounding box computation routines.
*
*/
#define FT_BBOX_H <freetype/ftbbox.h>
/*************************************************************************
*
* @macro:
* FT_CACHE_H
*
* @description:
* A macro used in #include statements to name the file containing the
* API of the optional FreeType 2 cache sub-system.
*
*/
#define FT_CACHE_H <freetype/ftcache.h>
/*************************************************************************
*
* @macro:
* FT_CACHE_IMAGE_H
*
* @description:
* A macro used in #include statements to name the file containing the
* `glyph image' API of the FreeType 2 cache sub-system.
*
* It is used to define a cache for @FT_Glyph elements. You can also
* use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to
* store small glyph bitmaps, as it will use less memory.
*
* This macro is deprecated. Simply include @FT_CACHE_H to have all
* glyph image-related cache declarations.
*
*/
#define FT_CACHE_IMAGE_H FT_CACHE_H
/*************************************************************************
*
* @macro:
* FT_CACHE_SMALL_BITMAPS_H
*
* @description:
* A macro used in #include statements to name the file containing the
* `small bitmaps' API of the FreeType 2 cache sub-system.
*
* It is used to define a cache for small glyph bitmaps in a relatively
* memory-efficient way. You can also use the API defined in
* @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images,
* including scalable outlines.
*
* This macro is deprecated. Simply include @FT_CACHE_H to have all
* small bitmaps-related cache declarations.
*
*/
#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H
/*************************************************************************
*
* @macro:
* FT_CACHE_CHARMAP_H
*
* @description:
* A macro used in #include statements to name the file containing the
* `charmap' API of the FreeType 2 cache sub-system.
*
* This macro is deprecated. Simply include @FT_CACHE_H to have all
* charmap-based cache declarations.
*
*/
#define FT_CACHE_CHARMAP_H FT_CACHE_H
/*************************************************************************
*
* @macro:
* FT_MAC_H
*
* @description:
* A macro used in #include statements to name the file containing the
* Macintosh-specific FreeType 2 API. The latter is used to access
* fonts embedded in resource forks.
*
* This header file must be explicitly included by client applications
* compiled on the Mac (note that the base API still works though).
*
*/
#define FT_MAC_H <freetype/ftmac.h>
/*************************************************************************
*
* @macro:
* FT_MULTIPLE_MASTERS_H
*
* @description:
* A macro used in #include statements to name the file containing the
* optional multiple-masters management API of FreeType 2.
*
*/
#define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h>
/*************************************************************************
*
* @macro:
* FT_SFNT_NAMES_H
*
* @description:
* A macro used in #include statements to name the file containing the
* optional FreeType 2 API which accesses embedded `name' strings in
* SFNT-based font formats (i.e., TrueType and OpenType).
*
*/
#define FT_SFNT_NAMES_H <freetype/ftsnames.h>
/*************************************************************************
*
* @macro:
* FT_OPENTYPE_VALIDATE_H
*
* @description:
* A macro used in #include statements to name the file containing the
* optional FreeType 2 API which validates OpenType tables (BASE, GDEF,
* GPOS, GSUB, JSTF).
*
*/
#define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h>
/*************************************************************************
*
* @macro:
* FT_GX_VALIDATE_H
*
* @description:
* A macro used in #include statements to name the file containing the
* optional FreeType 2 API which validates TrueTypeGX/AAT tables (feat,
* mort, morx, bsln, just, kern, opbd, trak, prop).
*
*/
#define FT_GX_VALIDATE_H <freetype/ftgxval.h>
/*************************************************************************
*
* @macro:
* FT_PFR_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which accesses PFR-specific data.
*
*/
#define FT_PFR_H <freetype/ftpfr.h>
/*************************************************************************
*
* @macro:
* FT_STROKER_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which provides functions to stroke outline paths.
*/
#define FT_STROKER_H <freetype/ftstroke.h>
/*************************************************************************
*
* @macro:
* FT_SYNTHESIS_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which performs artificial obliquing and emboldening.
*/
#define FT_SYNTHESIS_H <freetype/ftsynth.h>
/*************************************************************************
*
* @macro:
* FT_XFREE86_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which provides functions specific to the XFree86 and
* X.Org X11 servers.
*/
#define FT_XFREE86_H <freetype/ftxf86.h>
/*************************************************************************
*
* @macro:
* FT_TRIGONOMETRY_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which performs trigonometric computations (e.g.,
* cosines and arc tangents).
*/
#define FT_TRIGONOMETRY_H <freetype/fttrigon.h>
/*************************************************************************
*
* @macro:
* FT_LCD_FILTER_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which performs color filtering for subpixel rendering.
*/
#define FT_LCD_FILTER_H <freetype/ftlcdfil.h>
/*************************************************************************
*
* @macro:
* FT_UNPATENTED_HINTING_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which performs color filtering for subpixel rendering.
*/
#define FT_UNPATENTED_HINTING_H <freetype/ttunpat.h>
/*************************************************************************
*
* @macro:
* FT_INCREMENTAL_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which performs color filtering for subpixel rendering.
*/
#define FT_INCREMENTAL_H <freetype/ftincrem.h>
/*************************************************************************
*
* @macro:
* FT_GASP_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which returns entries from the TrueType GASP table.
*/
#define FT_GASP_H <freetype/ftgasp.h>
/*************************************************************************
*
* @macro:
* FT_ADVANCES_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which returns individual and ranged glyph advances
*/
#define FT_ADVANCES_H <freetype/ftadvanc.h>
/* */
#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h>
/* The internals of the cache sub-system are no longer exposed. We */
/* default to FT_CACHE_H at the moment just in case, but we know of */
/* no rogue client that uses them. */
/* */
#define FT_CACHE_MANAGER_H <freetype/ftcache.h>
#define FT_CACHE_INTERNAL_MRU_H <freetype/ftcache.h>
#define FT_CACHE_INTERNAL_MANAGER_H <freetype/ftcache.h>
#define FT_CACHE_INTERNAL_CACHE_H <freetype/ftcache.h>
#define FT_CACHE_INTERNAL_GLYPH_H <freetype/ftcache.h>
#define FT_CACHE_INTERNAL_IMAGE_H <freetype/ftcache.h>
#define FT_CACHE_INTERNAL_SBITS_H <freetype/ftcache.h>
#define FT_INCREMENTAL_H <freetype/ftincrem.h>
#define FT_TRUETYPE_UNPATENTED_H <freetype/ttunpat.h>
/*
* Include internal headers definitions from <freetype/internal/...>
* only when building the library.
*/
#ifdef FT2_BUILD_LIBRARY
#define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h>
#include FT_INTERNAL_INTERNAL_H
#endif /* FT2_BUILD_LIBRARY */
#endif /* __FT2_BUILD_H__ */
/* END */

View File

@ -0,0 +1,24 @@
/*
* This file registers the FreeType modules compiled into the library.
*
* If you use GNU make, this file IS NOT USED! Instead, it is created in
* the objects directory (normally `<topdir>/objs/') based on information
* from `<topdir>/modules.cfg'.
*
* Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile
* FreeType without GNU make.
*
*/
FT_USE_MODULE(autofit_module_class)
FT_USE_MODULE(tt_driver_class)
FT_USE_MODULE(cff_driver_class)
FT_USE_MODULE(psnames_module_class)
FT_USE_MODULE(pshinter_module_class)
FT_USE_MODULE(ft_raster1_renderer_class)
FT_USE_MODULE(sfnt_module_class)
FT_USE_MODULE(ft_smooth_renderer_class)
FT_USE_MODULE(ft_smooth_lcd_renderer_class)
FT_USE_MODULE(ft_smooth_lcdv_renderer_class)
/* EOF */

View File

@ -0,0 +1,691 @@
/***************************************************************************/
/* */
/* ftoption.h */
/* */
/* User-selectable configuration macros (specification only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 __FTOPTION_H__
#define __FTOPTION_H__
#include <freetype/ft2build.h>
FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* USER-SELECTABLE CONFIGURATION MACROS */
/* */
/* This file contains the default configuration macro definitions for */
/* a standard build of the FreeType library. There are three ways to */
/* use this file to build project-specific versions of the library: */
/* */
/* - You can modify this file by hand, but this is not recommended in */
/* cases where you would like to build several versions of the */
/* library from a single source directory. */
/* */
/* - You can put a copy of this file in your build directory, more */
/* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */
/* is the name of a directory that is included _before_ the FreeType */
/* include path during compilation. */
/* */
/* The default FreeType Makefiles and Jamfiles use the build */
/* directory `builds/<system>' by default, but you can easily change */
/* that for your own projects. */
/* */
/* - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it */
/* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */
/* locate this file during the build. For example, */
/* */
/* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */
/* #include <freetype/config/ftheader.h> */
/* */
/* will use `$BUILD/myftoptions.h' instead of this file for macro */
/* definitions. */
/* */
/* Note also that you can similarly pre-define the macro */
/* FT_CONFIG_MODULES_H used to locate the file listing of the modules */
/* that are statically linked to the library at compile time. By */
/* default, this file is <freetype/config/ftmodule.h>. */
/* */
/* We highly recommend using the third method whenever possible. */
/* */
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* */
/* Uncomment the line below if you want to activate sub-pixel rendering */
/* (a.k.a. LCD rendering, or ClearType) in this build of the library. */
/* */
/* Note that this feature is covered by several Microsoft patents */
/* and should not be activated in any default build of the library. */
/* */
/* This macro has no impact on the FreeType API, only on its */
/* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */
/* FT_Render_Glyph still generates a bitmap that is 3 times larger than */
/* the original size; the difference will be that each triplet of */
/* subpixels has R=G=B. */
/* */
/* This is done to allow FreeType clients to run unmodified, forcing */
/* them to display normal gray-level anti-aliased glyphs. */
/* */
/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
/*************************************************************************/
/* */
/* Many compilers provide a non-ANSI 64-bit data type that can be used */
/* by FreeType to speed up some computations. However, this will create */
/* some problems when compiling the library in strict ANSI mode. */
/* */
/* For this reason, the use of 64-bit integers is normally disabled when */
/* the __STDC__ macro is defined. You can however disable this by */
/* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */
/* */
/* For most compilers, this will only create compilation warnings when */
/* building the library. */
/* */
/* ObNote: The compiler-specific 64-bit integers are detected in the */
/* file `ftconfig.h' either statically or through the */
/* `configure' script on supported platforms. */
/* */
#undef FT_CONFIG_OPTION_FORCE_INT64
/*************************************************************************/
/* */
/* When this macro is defined, do not try to use an assembler version */
/* of performance-critical functions (e.g. FT_MulFix). you should only */
/* do that to verify that the assembler function works properly, or even */
/* to benchmarks the various implementations... */
/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */
/*************************************************************************/
/* */
/* When this macro is defined, try to use an inlined assembler version */
/* of the FT_MulFix function, which appears to be a hotspot when loading */
/* and hinting glyphs. */
/* */
/* note that if your compiler/cpu isn't supported, this will default to */
/* the standard and portable implementation found in src/base/ftcalc.c */
/* */
#define FT_CONFIG_OPTION_INLINE_MULFIX
/*************************************************************************/
/* */
/* LZW-compressed file support. */
/* */
/* FreeType now handles font files that have been compressed with the */
/* `compress' program. This is mostly used to parse many of the PCF */
/* files that come with various X11 distributions. The implementation */
/* uses NetBSD's `zopen' to partially uncompress the file on the fly */
/* (see src/lzw/ftgzip.c). */
/* */
/* Define this macro if you want to enable this `feature'. */
/* */
#define FT_CONFIG_OPTION_USE_LZW
/*************************************************************************/
/* */
/* Gzip-compressed file support. */
/* */
/* FreeType now handles font files that have been compressed with the */
/* `gzip' program. This is mostly used to parse many of the PCF files */
/* that come with XFree86. The implementation uses `zlib' to */
/* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */
/* */
/* Define this macro if you want to enable this `feature'. See also */
/* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */
/* */
#define FT_CONFIG_OPTION_USE_ZLIB
/*************************************************************************/
/* */
/* ZLib library selection */
/* */
/* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */
/* It allows FreeType's `ftgzip' component to link to the system's */
/* installation of the ZLib library. This is useful on systems like */
/* Unix or VMS where it generally is already available. */
/* */
/* If you let it undefined, the component will use its own copy */
/* of the zlib sources instead. These have been modified to be */
/* included directly within the component and *not* export external */
/* function names. This allows you to link any program with FreeType */
/* _and_ ZLib without linking conflicts. */
/* */
/* Do not #undef this macro here since the build system might define */
/* it for certain configurations only. */
/* */
/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */
/*************************************************************************/
/* */
/* DLL export compilation */
/* */
/* When compiling FreeType as a DLL, some systems/compilers need a */
/* special keyword in front OR after the return type of function */
/* declarations. */
/* */
/* Two macros are used within the FreeType source code to define */
/* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */
/* */
/* FT_EXPORT( return_type ) */
/* */
/* is used in a function declaration, as in */
/* */
/* FT_EXPORT( FT_Error ) */
/* FT_Init_FreeType( FT_Library* alibrary ); */
/* */
/* */
/* FT_EXPORT_DEF( return_type ) */
/* */
/* is used in a function definition, as in */
/* */
/* FT_EXPORT_DEF( FT_Error ) */
/* FT_Init_FreeType( FT_Library* alibrary ) */
/* { */
/* ... some code ... */
/* return FT_Err_Ok; */
/* } */
/* */
/* You can provide your own implementation of FT_EXPORT and */
/* FT_EXPORT_DEF here if you want. If you leave them undefined, they */
/* will be later automatically defined as `extern return_type' to */
/* allow normal compilation. */
/* */
/* Do not #undef these macros here since the build system might define */
/* them for certain configurations only. */
/* */
/* #define FT_EXPORT(x) extern x */
/* #define FT_EXPORT_DEF(x) x */
/*************************************************************************/
/* */
/* Glyph Postscript Names handling */
/* */
/* By default, FreeType 2 is compiled with the `PSNames' module. This */
/* module is in charge of converting a glyph name string into a */
/* Unicode value, or return a Macintosh standard glyph name for the */
/* use with the TrueType `post' table. */
/* */
/* Undefine this macro if you do not want `PSNames' compiled in your */
/* build of FreeType. This has the following effects: */
/* */
/* - The TrueType driver will provide its own set of glyph names, */
/* if you build it to support postscript names in the TrueType */
/* `post' table. */
/* */
/* - The Type 1 driver will not be able to synthetize a Unicode */
/* charmap out of the glyphs found in the fonts. */
/* */
/* You would normally undefine this configuration macro when building */
/* a version of FreeType that doesn't contain a Type 1 or CFF driver. */
/* */
#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES
/*************************************************************************/
/* */
/* Postscript Names to Unicode Values support */
/* */
/* By default, FreeType 2 is built with the `PSNames' module compiled */
/* in. Among other things, the module is used to convert a glyph name */
/* into a Unicode value. This is especially useful in order to */
/* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */
/* through a big table named the `Adobe Glyph List' (AGL). */
/* */
/* Undefine this macro if you do not want the Adobe Glyph List */
/* compiled in your `PSNames' module. The Type 1 driver will not be */
/* able to synthetize a Unicode charmap out of the glyphs found in the */
/* fonts. */
/* */
#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
/*************************************************************************/
/* */
/* Support for Mac fonts */
/* */
/* Define this macro if you want support for outline fonts in Mac */
/* format (mac dfont, mac resource, macbinary containing a mac */
/* resource) on non-Mac platforms. */
/* */
/* Note that the `FOND' resource isn't checked. */
/* */
#define FT_CONFIG_OPTION_MAC_FONTS
/*************************************************************************/
/* */
/* Guessing methods to access embedded resource forks */
/* */
/* Enable extra Mac fonts support on non-Mac platforms (e.g. */
/* GNU/Linux). */
/* */
/* Resource forks which include fonts data are stored sometimes in */
/* locations which users or developers don't expected. In some cases, */
/* resource forks start with some offset from the head of a file. In */
/* other cases, the actual resource fork is stored in file different */
/* from what the user specifies. If this option is activated, */
/* FreeType tries to guess whether such offsets or different file */
/* names must be used. */
/* */
/* Note that normal, direct access of resource forks is controlled via */
/* the FT_CONFIG_OPTION_MAC_FONTS option. */
/* */
#ifdef FT_CONFIG_OPTION_MAC_FONTS
#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
#endif
/*************************************************************************/
/* */
/* Allow the use of FT_Incremental_Interface to load typefaces that */
/* contain no glyph data, but supply it via a callback function. */
/* This allows FreeType to be used with the PostScript language, using */
/* the GhostScript interpreter. */
/* */
/* #define FT_CONFIG_OPTION_INCREMENTAL */
/*************************************************************************/
/* */
/* The size in bytes of the render pool used by the scan-line converter */
/* to do all of its work. */
/* */
/* This must be greater than 4KByte if you use FreeType to rasterize */
/* glyphs; otherwise, you may set it to zero to avoid unnecessary */
/* allocation of the render pool. */
/* */
#define FT_RENDER_POOL_SIZE 16384L
/*************************************************************************/
/* */
/* FT_MAX_MODULES */
/* */
/* The maximum number of modules that can be registered in a single */
/* FreeType library object. 32 is the default. */
/* */
#define FT_MAX_MODULES 32
/*************************************************************************/
/* */
/* Debug level */
/* */
/* FreeType can be compiled in debug or trace mode. In debug mode, */
/* errors are reported through the `ftdebug' component. In trace */
/* mode, additional messages are sent to the standard output during */
/* execution. */
/* */
/* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
/* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
/* */
/* Don't define any of these macros to compile in `release' mode! */
/* */
/* Do not #undef these macros here since the build system might define */
/* them for certain configurations only. */
/* */
/* #define FT_DEBUG_LEVEL_ERROR */
/* #define FT_DEBUG_LEVEL_TRACE */
/*************************************************************************/
/* */
/* Memory Debugging */
/* */
/* FreeType now comes with an integrated memory debugger that is */
/* capable of detecting simple errors like memory leaks or double */
/* deletes. To compile it within your build of the library, you */
/* should define FT_DEBUG_MEMORY here. */
/* */
/* Note that the memory debugger is only activated at runtime when */
/* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */
/* */
/* Do not #undef this macro here since the build system might define */
/* it for certain configurations only. */
/* */
/* #define FT_DEBUG_MEMORY */
/*************************************************************************/
/* */
/* Module errors */
/* */
/* If this macro is set (which is _not_ the default), the higher byte */
/* of an error code gives the module in which the error has occurred, */
/* while the lower byte is the real error code. */
/* */
/* Setting this macro makes sense for debugging purposes only, since */
/* it would break source compatibility of certain programs that use */
/* FreeType 2. */
/* */
/* More details can be found in the files ftmoderr.h and fterrors.h. */
/* */
#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** S F N T D R I V E R C O N F I G U R A T I O N ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */
/* embedded bitmaps in all formats using the SFNT module (namely */
/* TrueType & OpenType). */
/* */
#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */
/* load and enumerate the glyph Postscript names in a TrueType or */
/* OpenType file. */
/* */
/* Note that when you do not compile the `PSNames' module by undefining */
/* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */
/* contain additional code used to read the PS Names table from a font. */
/* */
/* (By default, the module uses `PSNames' to extract glyph names.) */
/* */
#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */
/* access the internal name table in a SFNT-based format like TrueType */
/* or OpenType. The name table contains various strings used to */
/* describe the font, like family name, copyright, version, etc. It */
/* does not contain any glyph name though. */
/* */
/* Accessing SFNT names is done through the functions declared in */
/* `freetype/ftnames.h'. */
/* */
#define TT_CONFIG_OPTION_SFNT_NAMES
/*************************************************************************/
/* */
/* TrueType CMap support */
/* */
/* Here you can fine-tune which TrueType CMap table format shall be */
/* supported. */
#define TT_CONFIG_CMAP_FORMAT_0
#define TT_CONFIG_CMAP_FORMAT_2
#define TT_CONFIG_CMAP_FORMAT_4
#define TT_CONFIG_CMAP_FORMAT_6
#define TT_CONFIG_CMAP_FORMAT_8
#define TT_CONFIG_CMAP_FORMAT_10
#define TT_CONFIG_CMAP_FORMAT_12
#define TT_CONFIG_CMAP_FORMAT_14
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */
/* a bytecode interpreter in the TrueType driver. Note that there are */
/* important patent issues related to the use of the interpreter. */
/* */
/* By undefining this, you will only compile the code necessary to load */
/* TrueType glyphs without hinting. */
/* */
/* Do not #undef this macro here, since the build system might */
/* define it for certain configurations only. */
/* */
/* #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
/*************************************************************************/
/* */
/* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */
/* of the TrueType bytecode interpreter is used that doesn't implement */
/* any of the patented opcodes and algorithms. Note that the */
/* the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you */
/* define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; with other words, */
/* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */
/* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */
/* */
/* This macro is only useful for a small number of font files (mostly */
/* for Asian scripts) that require bytecode interpretation to properly */
/* load glyphs. For all other fonts, this produces unpleasant results, */
/* thus the unpatented interpreter is never used to load glyphs from */
/* TrueType fonts unless one of the following two options is used. */
/* */
/* - The unpatented interpreter is explicitly activated by the user */
/* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */
/* when opening the FT_Face. */
/* */
/* - FreeType detects that the FT_Face corresponds to one of the */
/* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */
/* contains a hard-coded list of font names and other matching */
/* parameters (see function `tt_face_init' in file */
/* `src/truetype/ttobjs.c'). */
/* */
/* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */
/* */
/* { */
/* FT_Parameter parameter; */
/* FT_Open_Args open_args; */
/* */
/* */
/* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */
/* */
/* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */
/* open_args.pathname = my_font_pathname; */
/* open_args.num_params = 1; */
/* open_args.params = &parameter; */
/* */
/* error = FT_Open_Face( library, &open_args, index, &face ); */
/* ... */
/* } */
/* */
#define TT_CONFIG_OPTION_UNPATENTED_HINTING
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */
/* bytecode interpreter with a huge switch statement, rather than a call */
/* table. This results in smaller and faster code for a number of */
/* architectures. */
/* */
/* Note however that on some compiler/processor combinations, undefining */
/* this macro will generate faster, though larger, code. */
/* */
#define TT_CONFIG_OPTION_INTERPRETER_SWITCH
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */
/* TrueType glyph loader to use Apple's definition of how to handle */
/* component offsets in composite glyphs. */
/* */
/* Apple and MS disagree on the default behavior of component offsets */
/* in composites. Apple says that they should be scaled by the scaling */
/* factors in the transformation matrix (roughly, it's more complex) */
/* while MS says they should not. OpenType defines two bits in the */
/* composite flags array which can be used to disambiguate, but old */
/* fonts will not have them. */
/* */
/* http://partners.adobe.com/asn/developer/opentype/glyf.html */
/* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */
/* */
#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */
/* support for Apple's distortable font technology (fvar, gvar, cvar, */
/* and avar tables). This has many similarities to Type 1 Multiple */
/* Masters support. */
/* */
#define TT_CONFIG_OPTION_GX_VAR_SUPPORT
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_BDF if you want to include support for */
/* an embedded `BDF ' table within SFNT-based bitmap formats. */
/* */
#define TT_CONFIG_OPTION_BDF
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* */
/* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */
/* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */
/* required. */
/* */
#define T1_MAX_DICT_DEPTH 5
/*************************************************************************/
/* */
/* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */
/* calls during glyph loading. */
/* */
#define T1_MAX_SUBRS_CALLS 16
/*************************************************************************/
/* */
/* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */
/* minimum of 16 is required. */
/* */
/* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */
/* */
#define T1_MAX_CHARSTRINGS_OPERANDS 256
/*************************************************************************/
/* */
/* Define this configuration macro if you want to prevent the */
/* compilation of `t1afm', which is in charge of reading Type 1 AFM */
/* files into an existing face. Note that if set, the T1 driver will be */
/* unable to produce kerning distances. */
/* */
#undef T1_CONFIG_OPTION_NO_AFM
/*************************************************************************/
/* */
/* Define this configuration macro if you want to prevent the */
/* compilation of the Multiple Masters font support in the Type 1 */
/* driver. */
/* */
#undef T1_CONFIG_OPTION_NO_MM_SUPPORT
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* */
/* Compile autofit module with CJK (Chinese, Japanese, Korean) script */
/* support. */
/* */
#define AF_CONFIG_OPTION_CJK
/*************************************************************************/
/* */
/* Compile autofit module with Indic script support. */
/* */
#define AF_CONFIG_OPTION_INDIC
/* */
/*
* Define this variable if you want to keep the layout of internal
* structures that was used prior to FreeType 2.2. This also compiles in
* a few obsolete functions to avoid linking problems on typical Unix
* distributions.
*
* For embedded systems or building a new distribution from scratch, it
* is recommended to disable the macro since it reduces the library's code
* size and activates a few memory-saving optimizations as well.
*/
#define FT_CONFIG_OPTION_OLD_INTERNALS
/*
* This variable is defined if either unpatented or native TrueType
* hinting is requested by the definitions above.
*/
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#define TT_USE_BYTECODE_INTERPRETER
#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING
#define TT_USE_BYTECODE_INTERPRETER
#endif
FT_END_HEADER
#endif /* __FTOPTION_H__ */
/* END */

View File

@ -0,0 +1,180 @@
/***************************************************************************/
/* */
/* ftstdlib.h */
/* */
/* ANSI-specific library and header configuration file (specification */
/* only). */
/* */
/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 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 is used to group all #includes to the ANSI C library that */
/* FreeType normally requires. It also defines macros to rename the */
/* standard functions within the FreeType source code. */
/* */
/* Load a file which defines __FTSTDLIB_H__ before this one to override */
/* it. */
/* */
/*************************************************************************/
#ifndef __FTSTDLIB_H__
#define __FTSTDLIB_H__
#include <stddef.h>
#define ft_ptrdiff_t ptrdiff_t
/**********************************************************************/
/* */
/* integer limits */
/* */
/* UINT_MAX and ULONG_MAX are used to automatically compute the size */
/* of `int' and `long' in bytes at compile-time. So far, this works */
/* for all platforms the library has been tested on. */
/* */
/* Note that on the extremely rare platforms that do not provide */
/* integer types that are _exactly_ 16 and 32 bits wide (e.g. some */
/* old Crays where `int' is 36 bits), we do not make any guarantee */
/* about the correct behaviour of FT2 with all fonts. */
/* */
/* In these case, `ftconfig.h' will refuse to compile anyway with a */
/* message like `couldn't find 32-bit type' or something similar. */
/* */
/* IMPORTANT NOTE: We do not define aliases for heap management and */
/* i/o routines (i.e. malloc/free/fopen/fread/...) */
/* since these functions should all be encapsulated */
/* by platform-specific implementations of */
/* `ftsystem.c'. */
/* */
/**********************************************************************/
#include <limits.h>
#define FT_CHAR_BIT CHAR_BIT
#define FT_INT_MAX INT_MAX
#define FT_UINT_MAX UINT_MAX
#define FT_ULONG_MAX ULONG_MAX
/**********************************************************************/
/* */
/* character and string processing */
/* */
/**********************************************************************/
#include <string.h>
#define ft_memchr memchr
#define ft_memcmp memcmp
#define ft_memcpy memcpy
#define ft_memmove memmove
#define ft_memset memset
#define ft_strcat strcat
#define ft_strcmp strcmp
#define ft_strcpy strcpy
#define ft_strlen strlen
#define ft_strncmp strncmp
#define ft_strncpy strncpy
#define ft_strrchr strrchr
#define ft_strstr strstr
/**********************************************************************/
/* */
/* file handling */
/* */
/**********************************************************************/
#include <stdio.h>
#define FT_FILE FILE
#define ft_fclose fclose
#define ft_fopen fopen
#define ft_fread fread
#define ft_fseek fseek
#define ft_ftell ftell
#define ft_sprintf sprintf
/**********************************************************************/
/* */
/* sorting */
/* */
/**********************************************************************/
#include <stdlib.h>
#define ft_qsort qsort
#define ft_exit exit /* only used to exit from unhandled exceptions */
/**********************************************************************/
/* */
/* memory allocation */
/* */
/**********************************************************************/
#define ft_scalloc calloc
#define ft_sfree free
#define ft_smalloc malloc
#define ft_srealloc realloc
/**********************************************************************/
/* */
/* miscellaneous */
/* */
/**********************************************************************/
#define ft_atol atol
#define ft_labs labs
/**********************************************************************/
/* */
/* execution control */
/* */
/**********************************************************************/
#include <setjmp.h>
#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */
/* jmp_buf is defined as a macro */
/* on certain platforms */
#define ft_longjmp longjmp
#define ft_setjmp( b ) setjmp( *(jmp_buf*) &(b) ) /* same thing here */
/* the following is only used for debugging purposes, i.e., if */
/* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined */
#include <stdarg.h>
#endif /* __FTSTDLIB_H__ */
/* END */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
/***************************************************************************/
/* */
/* ft2build.h */
/* */
/* FreeType 2 build and setup macros. */
/* (Generic version) */
/* */
/* Copyright 1996-2001, 2006 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 corresponds to the default `ft2build.h' file for */
/* FreeType 2. It uses the `freetype' include root. */
/* */
/* Note that specific platforms might use a different configuration. */
/* See builds/unix/ft2unix.h for an example. */
/* */
/*************************************************************************/
#ifndef __FT2_BUILD_GENERIC_H__
#define __FT2_BUILD_GENERIC_H__
#include <freetype/config/ftheader.h>
#endif /* __FT2_BUILD_GENERIC_H__ */
/* END */

View File

@ -0,0 +1,61 @@
/***************************************************************************/
/* */
/* ft2build.h */
/* */
/* Build macros of the FreeType 2 library. */
/* */
/* Copyright 1996-2001, 2003, 2006 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 is a Unix-specific version of <ft2build.h> that should be used */
/* exclusively *after* installation of the library. */
/* */
/* It assumes that `/usr/local/include/freetype2' (or whatever is */
/* returned by the `freetype-config --cflags' or `pkg-config --cflags' */
/* command) is in your compilation include path. */
/* */
/* We don't need to do anything special in this release. However, for */
/* a future FreeType 2 release, the following installation changes will */
/* be performed: */
/* */
/* - The contents of `freetype-2.x/include/freetype' will be installed */
/* to `/usr/local/include/freetype2' instead of */
/* `/usr/local/include/freetype2/freetype'. */
/* */
/* - This file will #include <freetype2/config/ftheader.h>, instead */
/* of <freetype/config/ftheader.h>. */
/* */
/* - The contents of `ftheader.h' will be processed with `sed' to */
/* replace all `<freetype/xxx>' with `<freetype2/xxx>'. */
/* */
/* - Adding `/usr/local/include/freetype2' to your compilation include */
/* path will not be necessary anymore. */
/* */
/* These changes will be transparent to client applications which use */
/* freetype-config (or pkg-config). No modifications will be necessary */
/* to compile with the new scheme. */
/* */
/*************************************************************************/
#ifndef __FT2_BUILD_UNIX_H__
#define __FT2_BUILD_UNIX_H__
/* `<prefix>/include/freetype2' must be in your current inclusion path */
#include <freetype/config/ftheader.h>
#endif /* __FT2_BUILD_UNIX_H__ */
/* END */

View File

@ -0,0 +1,131 @@
/***************************************************************************/
/* */
/* ftadvanc.h */
/* */
/* FreeType access the glyph advances (specification only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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 __FREETYPE_ADVANCE_H__
#define __FREETYPE_ADVANCE_H__
#include <freetype/ft2build.h>
#include FT_FREETYPE_H
/*************************************************************************/
/* */
/* <Const> */
/* FT_ADVANCE_FLAG_FAST_ONLY */
/* */
/* <Description> */
/* a bit-flag to be or-ed to the 'flags' parameter of the */
/* @FT_Get_Advance and @FT_Get_Advances. */
/* */
/* when set, it indicates that you want these functions to fail */
/* if the corresponding hinting mode or font driver doesn't */
/* allow for very quick advance computation. */
/* */
/* typically, unscaled, unhinted, bitmapped and light-hinted glyphs */
/* can have their advance width(s) computed very quickly. */
/* */
/* not so for normal and bytecode hinted modes, which require */
/* loading/scaling/hinting the glyph outline instead, which is */
/* extremely slow by comparison */
/* */
#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000U
/*************************************************************************/
/* */
/* <Function> */
/* FT_Get_Advance */
/* */
/* <Description> */
/* Retrieve the advance of a given glyph outline in a FT_Face. */
/* by default, the unhinted advance is returned in font units */
/* */
/* <Input> */
/* face :: source FT_Face handle */
/* gindex :: glyph index */
/* load_flags :: a set of bit-flags similar to those used */
/* when calling @FT_Load_Glyph, used to determine */
/* what kind of advances you need. */
/* <Output> */
/* padvance :: the advance value, in either font units or 16.16 */
/* format. */
/* */
/* if @FT_LOAD_VERTICAL_LAYOUT is set, this is the */
/* vertical advance corresponding to a vertical layout. */
/* otherwise, it's the horizontal advance in an */
/* horizontal layout. */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */
/* if the corresponding's font backend doesn't have a quick way to */
/* retrieve the advances. */
/* */
/* A scaled advance is returned in 16.16 format, but isn't */
/* transformed by the affine transform specified by @FT_Set_Transform */
/* */
FT_EXPORT( FT_Error )
FT_Get_Advance( FT_Face face,
FT_UInt gindex,
FT_UInt load_flags,
FT_Fixed *padvance );
/*************************************************************************/
/* */
/* <Function> */
/* FT_Get_Advances */
/* */
/* <Description> */
/* Retrieve the advance of several glyph outlines in a FT_Face. */
/* by default, the unhinted advances are returned in font units */
/* */
/* <Input> */
/* face :: source FT_Face handle */
/* start :: first glyph index */
/* count :: number of advances you want to retrieve */
/* load_flags :: a set of bit-flags similar to those used when */
/* calling @FT_Load_Glyph. */
/* */
/* <Output> */
/* padvance :: the advances, in either font units or 16.16 format. */
/* this array must contain at least 'count' elements */
/* */
/* if @FT_LOAD_VERTICAL_LAYOUT is set, these are the */
/* vertical advances corresponding to a vertical layout. */
/* otherwise, they are the horizontal advances in an */
/* horizontal layout. */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */
/* if the corresponding's font backend doesn't have a quick way to */
/* retrieve the advances. */
/* */
/* Scaled advances are returned in 16.16 format, but aren't */
/* transformed by the affine transform specified by @FT_Set_Transform */
/* */
FT_EXPORT( FT_Error )
FT_Get_Advances( FT_Face face,
FT_UInt start,
FT_UInt count,
FT_UInt load_flags,
FT_Fixed *padvances );
/* */
#endif /* __FREETYPE_ADVANCE_H__ */

View File

@ -0,0 +1,94 @@
/***************************************************************************/
/* */
/* ftbbox.h */
/* */
/* FreeType exact bbox computation (specification). */
/* */
/* Copyright 1996-2001, 2003, 2007 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 has a _single_ role: to compute exact outline bounding */
/* boxes. */
/* */
/* It is separated from the rest of the engine for various technical */
/* reasons. It may well be integrated in `ftoutln' later. */
/* */
/*************************************************************************/
#ifndef __FTBBOX_H__
#define __FTBBOX_H__
#include <freetype/ft2build.h>
#include FT_FREETYPE_H
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Section> */
/* outline_processing */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* <Function> */
/* FT_Outline_Get_BBox */
/* */
/* <Description> */
/* Computes the exact bounding box of an outline. This is slower */
/* than computing the control box. However, it uses an advanced */
/* algorithm which returns _very_ quickly when the two boxes */
/* coincide. Otherwise, the outline Bézier arcs are traversed to */
/* extract their extrema. */
/* */
/* <Input> */
/* outline :: A pointer to the source outline. */
/* */
/* <Output> */
/* abbox :: The outline's exact bounding box. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_EXPORT( FT_Error )
FT_Outline_Get_BBox( FT_Outline* outline,
FT_BBox *abbox );
/* */
FT_END_HEADER
#endif /* __FTBBOX_H__ */
/* END */
/* Local Variables: */
/* coding: utf-8 */
/* End: */

View File

@ -0,0 +1,200 @@
/***************************************************************************/
/* */
/* ftbdf.h */
/* */
/* FreeType API for accessing BDF-specific strings (specification). */
/* */
/* Copyright 2002, 2003, 2004, 2006 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 __FTBDF_H__
#define __FTBDF_H__
#include <freetype/ft2build.h>
#include FT_FREETYPE_H
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Section> */
/* bdf_fonts */
/* */
/* <Title> */
/* BDF Files */
/* */
/* <Abstract> */
/* BDF specific API. */
/* */
/* <Description> */
/* This section contains the declaration of BDF specific functions. */
/* */
/*************************************************************************/
/**********************************************************************
*
* @enum:
* FT_PropertyType
*
* @description:
* A list of BDF property types.
*
* @values:
* BDF_PROPERTY_TYPE_NONE ::
* Value 0 is used to indicate a missing property.
*
* BDF_PROPERTY_TYPE_ATOM ::
* Property is a string atom.
*
* BDF_PROPERTY_TYPE_INTEGER ::
* Property is a 32-bit signed integer.
*
* BDF_PROPERTY_TYPE_CARDINAL ::
* Property is a 32-bit unsigned integer.
*/
typedef enum BDF_PropertyType_
{
BDF_PROPERTY_TYPE_NONE = 0,
BDF_PROPERTY_TYPE_ATOM = 1,
BDF_PROPERTY_TYPE_INTEGER = 2,
BDF_PROPERTY_TYPE_CARDINAL = 3
} BDF_PropertyType;
/**********************************************************************
*
* @type:
* BDF_Property
*
* @description:
* A handle to a @BDF_PropertyRec structure to model a given
* BDF/PCF property.
*/
typedef struct BDF_PropertyRec_* BDF_Property;
/**********************************************************************
*
* @struct:
* BDF_PropertyRec
*
* @description:
* This structure models a given BDF/PCF property.
*
* @fields:
* type ::
* The property type.
*
* u.atom ::
* The atom string, if type is @BDF_PROPERTY_TYPE_ATOM.
*
* u.integer ::
* A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER.
*
* u.cardinal ::
* An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL.
*/
typedef struct BDF_PropertyRec_
{
BDF_PropertyType type;
union {
const char* atom;
FT_Int32 integer;
FT_UInt32 cardinal;
} u;
} BDF_PropertyRec;
/**********************************************************************
*
* @function:
* FT_Get_BDF_Charset_ID
*
* @description:
* Retrieves a BDF font character set identity, according to
* the BDF specification.
*
* @input:
* face ::
* A handle to the input face.
*
* @output:
* acharset_encoding ::
* Charset encoding, as a C string, owned by the face.
*
* acharset_registry ::
* Charset registry, as a C string, owned by the face.
*
* @return:
* FreeType error code. 0 means success.
*
* @note:
* This function only works with BDF faces, returning an error otherwise.
*/
FT_EXPORT( FT_Error )
FT_Get_BDF_Charset_ID( FT_Face face,
const char* *acharset_encoding,
const char* *acharset_registry );
/**********************************************************************
*
* @function:
* FT_Get_BDF_Property
*
* @description:
* Retrieves a BDF property from a BDF or PCF font file.
*
* @input:
* face :: A handle to the input face.
*
* name :: The property name.
*
* @output:
* aproperty :: The property.
*
* @return:
* FreeType error code. 0 means success.
*
* @note:
* This function works with BDF _and_ PCF fonts. It returns an error
* otherwise. It also returns an error if the property is not in the
* font.
*
* In case of error, `aproperty->type' is always set to
* @BDF_PROPERTY_TYPE_NONE.
*/
FT_EXPORT( FT_Error )
FT_Get_BDF_Property( FT_Face face,
const char* prop_name,
BDF_PropertyRec *aproperty );
/* */
FT_END_HEADER
#endif /* __FTBDF_H__ */
/* END */

View File

@ -0,0 +1,206 @@
/***************************************************************************/
/* */
/* ftbitmap.h */
/* */
/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */
/* bitmaps into 8bpp format (specification). */
/* */
/* Copyright 2004, 2005, 2006 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 __FTBITMAP_H__
#define __FTBITMAP_H__
#include <freetype/ft2build.h>
#include FT_FREETYPE_H
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Section> */
/* bitmap_handling */
/* */
/* <Title> */
/* Bitmap Handling */
/* */
/* <Abstract> */
/* Handling FT_Bitmap objects. */
/* */
/* <Description> */
/* This section contains functions for converting FT_Bitmap objects. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* <Function> */
/* FT_Bitmap_New */
/* */
/* <Description> */
/* Initialize a pointer to an @FT_Bitmap structure. */
/* */
/* <InOut> */
/* abitmap :: A pointer to the bitmap structure. */
/* */
FT_EXPORT( void )
FT_Bitmap_New( FT_Bitmap *abitmap );
/*************************************************************************/
/* */
/* <Function> */
/* FT_Bitmap_Copy */
/* */
/* <Description> */
/* Copies an bitmap into another one. */
/* */
/* <Input> */
/* library :: A handle to a library object. */
/* */
/* source :: A handle to the source bitmap. */
/* */
/* <Output> */
/* target :: A handle to the target bitmap. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_EXPORT( FT_Error )
FT_Bitmap_Copy( FT_Library library,
const FT_Bitmap *source,
FT_Bitmap *target);
/*************************************************************************/
/* */
/* <Function> */
/* FT_Bitmap_Embolden */
/* */
/* <Description> */
/* Embolden a bitmap. The new bitmap will be about `xStrength' */
/* pixels wider and `yStrength' pixels higher. The left and bottom */
/* borders are kept unchanged. */
/* */
/* <Input> */
/* library :: A handle to a library object. */
/* */
/* xStrength :: How strong the glyph is emboldened horizontally. */
/* Expressed in 26.6 pixel format. */
/* */
/* yStrength :: How strong the glyph is emboldened vertically. */
/* Expressed in 26.6 pixel format. */
/* */
/* <InOut> */
/* bitmap :: A handle to the target bitmap. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The current implementation restricts `xStrength' to be less than */
/* or equal to 8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */
/* */
/* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */
/* you should call `FT_GlyphSlot_Own_Bitmap' on the slot first. */
/* */
FT_EXPORT( FT_Error )
FT_Bitmap_Embolden( FT_Library library,
FT_Bitmap* bitmap,
FT_Pos xStrength,
FT_Pos yStrength );
/*************************************************************************/
/* */
/* <Function> */
/* FT_Bitmap_Convert */
/* */
/* <Description> */
/* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, or 8bpp to a */
/* bitmap object with depth 8bpp, making the number of used bytes per */
/* line (a.k.a. the `pitch') a multiple of `alignment'. */
/* */
/* <Input> */
/* library :: A handle to a library object. */
/* */
/* source :: The source bitmap. */
/* */
/* alignment :: The pitch of the bitmap is a multiple of this */
/* parameter. Common values are 1, 2, or 4. */
/* */
/* <Output> */
/* target :: The target bitmap. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* It is possible to call @FT_Bitmap_Convert multiple times without */
/* calling @FT_Bitmap_Done (the memory is simply reallocated). */
/* */
/* Use @FT_Bitmap_Done to finally remove the bitmap object. */
/* */
/* The `library' argument is taken to have access to FreeType's */
/* memory handling functions. */
/* */
FT_EXPORT( FT_Error )
FT_Bitmap_Convert( FT_Library library,
const FT_Bitmap *source,
FT_Bitmap *target,
FT_Int alignment );
/*************************************************************************/
/* */
/* <Function> */
/* FT_Bitmap_Done */
/* */
/* <Description> */
/* Destroy a bitmap object created with @FT_Bitmap_New. */
/* */
/* <Input> */
/* library :: A handle to a library object. */
/* */
/* bitmap :: The bitmap object to be freed. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The `library' argument is taken to have access to FreeType's */
/* memory handling functions. */
/* */
FT_EXPORT( FT_Error )
FT_Bitmap_Done( FT_Library library,
FT_Bitmap *bitmap );
/* */
FT_END_HEADER
#endif /* __FTBITMAP_H__ */
/* END */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
/***************************************************************************/
/* */
/* This file defines the structure of the FreeType reference. */
/* It is used by the python script which generates the HTML files. */
/* */
/***************************************************************************/
/***************************************************************************/
/* */
/* <Chapter> */
/* general_remarks */
/* */
/* <Title> */
/* General Remarks */
/* */
/* <Sections> */
/* user_allocation */
/* */
/***************************************************************************/
/***************************************************************************/
/* */
/* <Chapter> */
/* core_api */
/* */
/* <Title> */
/* Core API */
/* */
/* <Sections> */
/* version */
/* basic_types */
/* base_interface */
/* glyph_variants */
/* glyph_management */
/* mac_specific */
/* sizes_management */
/* header_file_macros */
/* */
/***************************************************************************/
/***************************************************************************/
/* */
/* <Chapter> */
/* format_specific */
/* */
/* <Title> */
/* Format-Specific API */
/* */
/* <Sections> */
/* multiple_masters */
/* truetype_tables */
/* type1_tables */
/* sfnt_names */
/* bdf_fonts */
/* cid_fonts */
/* pfr_fonts */
/* winfnt_fonts */
/* font_formats */
/* gasp_table */
/* */
/***************************************************************************/
/***************************************************************************/
/* */
/* <Chapter> */
/* cache_subsystem */
/* */
/* <Title> */
/* Cache Sub-System */
/* */
/* <Sections> */
/* cache_subsystem */
/* */
/***************************************************************************/
/***************************************************************************/
/* */
/* <Chapter> */
/* support_api */
/* */
/* <Title> */
/* Support API */
/* */
/* <Sections> */
/* computations */
/* list_processing */
/* outline_processing */
/* bitmap_handling */
/* raster */
/* glyph_stroker */
/* system_interface */
/* module_management */
/* gzip */
/* lzw */
/* lcd_filtering */
/* */
/***************************************************************************/

View File

@ -0,0 +1,98 @@
/***************************************************************************/
/* */
/* ftcid.h */
/* */
/* FreeType API for accessing CID font information (specification). */
/* */
/* Copyright 2007 by Dereg Clegg. */
/* */
/* 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 __FTCID_H__
#define __FTCID_H__
#include <freetype/ft2build.h>
#include FT_FREETYPE_H
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Section> */
/* cid_fonts */
/* */
/* <Title> */
/* CID Fonts */
/* */
/* <Abstract> */
/* CID-keyed font specific API. */
/* */
/* <Description> */
/* This section contains the declaration of CID-keyed font specific */
/* functions. */
/* */
/*************************************************************************/
/**********************************************************************
*
* @function:
* FT_Get_CID_Registry_Ordering_Supplement
*
* @description:
* Retrieve the Registry/Ordering/Supplement triple (also known as the
* "R/O/S") from a CID-keyed font.
*
* @input:
* face ::
* A handle to the input face.
*
* @output:
* registry ::
* The registry, as a C string, owned by the face.
*
* ordering ::
* The ordering, as a C string, owned by the face.
*
* supplement ::
* The supplement.
*
* @return:
* FreeType error code. 0 means success.
*
* @note:
* This function only works with CID faces, returning an error
* otherwise.
*
* @since:
* 2.3.6
*/
FT_EXPORT( FT_Error )
FT_Get_CID_Registry_Ordering_Supplement( FT_Face face,
const char* *registry,
const char* *ordering,
FT_Int *supplement);
/* */
FT_END_HEADER
#endif /* __FTCID_H__ */
/* END */

View File

@ -0,0 +1,239 @@
/***************************************************************************/
/* */
/* fterrdef.h */
/* */
/* FreeType error codes (specification). */
/* */
/* Copyright 2002, 2004, 2006, 2007 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. */
/* */
/***************************************************************************/
/*******************************************************************/
/*******************************************************************/
/***** *****/
/***** LIST OF ERROR CODES/MESSAGES *****/
/***** *****/
/*******************************************************************/
/*******************************************************************/
/* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */
/* including this file. */
/* generic errors */
FT_NOERRORDEF_( Ok, 0x00, \
"no error" )
FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \
"cannot open resource" )
FT_ERRORDEF_( Unknown_File_Format, 0x02, \
"unknown file format" )
FT_ERRORDEF_( Invalid_File_Format, 0x03, \
"broken file" )
FT_ERRORDEF_( Invalid_Version, 0x04, \
"invalid FreeType version" )
FT_ERRORDEF_( Lower_Module_Version, 0x05, \
"module version is too low" )
FT_ERRORDEF_( Invalid_Argument, 0x06, \
"invalid argument" )
FT_ERRORDEF_( Unimplemented_Feature, 0x07, \
"unimplemented feature" )
FT_ERRORDEF_( Invalid_Table, 0x08, \
"broken table" )
FT_ERRORDEF_( Invalid_Offset, 0x09, \
"broken offset within table" )
FT_ERRORDEF_( Array_Too_Large, 0x0A, \
"array allocation size too large" )
/* glyph/character errors */
FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \
"invalid glyph index" )
FT_ERRORDEF_( Invalid_Character_Code, 0x11, \
"invalid character code" )
FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \
"unsupported glyph image format" )
FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \
"cannot render this glyph format" )
FT_ERRORDEF_( Invalid_Outline, 0x14, \
"invalid outline" )
FT_ERRORDEF_( Invalid_Composite, 0x15, \
"invalid composite glyph" )
FT_ERRORDEF_( Too_Many_Hints, 0x16, \
"too many hints" )
FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \
"invalid pixel size" )
/* handle errors */
FT_ERRORDEF_( Invalid_Handle, 0x20, \
"invalid object handle" )
FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \
"invalid library handle" )
FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \
"invalid module handle" )
FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \
"invalid face handle" )
FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \
"invalid size handle" )
FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \
"invalid glyph slot handle" )
FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \
"invalid charmap handle" )
FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \
"invalid cache manager handle" )
FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \
"invalid stream handle" )
/* driver errors */
FT_ERRORDEF_( Too_Many_Drivers, 0x30, \
"too many modules" )
FT_ERRORDEF_( Too_Many_Extensions, 0x31, \
"too many extensions" )
/* memory errors */
FT_ERRORDEF_( Out_Of_Memory, 0x40, \
"out of memory" )
FT_ERRORDEF_( Unlisted_Object, 0x41, \
"unlisted object" )
/* stream errors */
FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \
"cannot open stream" )
FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \
"invalid stream seek" )
FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \
"invalid stream skip" )
FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \
"invalid stream read" )
FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \
"invalid stream operation" )
FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \
"invalid frame operation" )
FT_ERRORDEF_( Nested_Frame_Access, 0x57, \
"nested frame access" )
FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \
"invalid frame read" )
/* raster errors */
FT_ERRORDEF_( Raster_Uninitialized, 0x60, \
"raster uninitialized" )
FT_ERRORDEF_( Raster_Corrupted, 0x61, \
"raster corrupted" )
FT_ERRORDEF_( Raster_Overflow, 0x62, \
"raster overflow" )
FT_ERRORDEF_( Raster_Negative_Height, 0x63, \
"negative height while rastering" )
/* cache errors */
FT_ERRORDEF_( Too_Many_Caches, 0x70, \
"too many registered caches" )
/* TrueType and SFNT errors */
FT_ERRORDEF_( Invalid_Opcode, 0x80, \
"invalid opcode" )
FT_ERRORDEF_( Too_Few_Arguments, 0x81, \
"too few arguments" )
FT_ERRORDEF_( Stack_Overflow, 0x82, \
"stack overflow" )
FT_ERRORDEF_( Code_Overflow, 0x83, \
"code overflow" )
FT_ERRORDEF_( Bad_Argument, 0x84, \
"bad argument" )
FT_ERRORDEF_( Divide_By_Zero, 0x85, \
"division by zero" )
FT_ERRORDEF_( Invalid_Reference, 0x86, \
"invalid reference" )
FT_ERRORDEF_( Debug_OpCode, 0x87, \
"found debug opcode" )
FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \
"found ENDF opcode in execution stream" )
FT_ERRORDEF_( Nested_DEFS, 0x89, \
"nested DEFS" )
FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \
"invalid code range" )
FT_ERRORDEF_( Execution_Too_Long, 0x8B, \
"execution context too long" )
FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \
"too many function definitions" )
FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \
"too many instruction definitions" )
FT_ERRORDEF_( Table_Missing, 0x8E, \
"SFNT font table missing" )
FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \
"horizontal header (hhea) table missing" )
FT_ERRORDEF_( Locations_Missing, 0x90, \
"locations (loca) table missing" )
FT_ERRORDEF_( Name_Table_Missing, 0x91, \
"name table missing" )
FT_ERRORDEF_( CMap_Table_Missing, 0x92, \
"character map (cmap) table missing" )
FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \
"horizontal metrics (hmtx) table missing" )
FT_ERRORDEF_( Post_Table_Missing, 0x94, \
"PostScript (post) table missing" )
FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \
"invalid horizontal metrics" )
FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \
"invalid character map (cmap) format" )
FT_ERRORDEF_( Invalid_PPem, 0x97, \
"invalid ppem value" )
FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \
"invalid vertical metrics" )
FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \
"could not find context" )
FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \
"invalid PostScript (post) table format" )
FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \
"invalid PostScript (post) table" )
/* CFF, CID, and Type 1 errors */
FT_ERRORDEF_( Syntax_Error, 0xA0, \
"opcode syntax error" )
FT_ERRORDEF_( Stack_Underflow, 0xA1, \
"argument stack underflow" )
FT_ERRORDEF_( Ignore, 0xA2, \
"ignore" )
/* BDF errors */
FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \
"`STARTFONT' field missing" )
FT_ERRORDEF_( Missing_Font_Field, 0xB1, \
"`FONT' field missing" )
FT_ERRORDEF_( Missing_Size_Field, 0xB2, \
"`SIZE' field missing" )
FT_ERRORDEF_( Missing_Chars_Field, 0xB3, \
"`CHARS' field missing" )
FT_ERRORDEF_( Missing_Startchar_Field, 0xB4, \
"`STARTCHAR' field missing" )
FT_ERRORDEF_( Missing_Encoding_Field, 0xB5, \
"`ENCODING' field missing" )
FT_ERRORDEF_( Missing_Bbx_Field, 0xB6, \
"`BBX' field missing" )
FT_ERRORDEF_( Bbx_Too_Big, 0xB7, \
"`BBX' too big" )
FT_ERRORDEF_( Corrupted_Font_Header, 0xB8, \
"Font header corrupted or missing fields" )
FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xB9, \
"Font glyphs corrupted or missing fields" )
/* END */

View File

@ -0,0 +1,206 @@
/***************************************************************************/
/* */
/* fterrors.h */
/* */
/* FreeType error code handling (specification). */
/* */
/* Copyright 1996-2001, 2002, 2004, 2007 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 special header file is used to define the handling of FT2 */
/* enumeration constants. It can also be used to generate error message */
/* strings with a small macro trick explained below. */
/* */
/* I - Error Formats */
/* ----------------- */
/* */
/* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */
/* defined in ftoption.h in order to make the higher byte indicate */
/* the module where the error has happened (this is not compatible */
/* with standard builds of FreeType 2). You can then use the macro */
/* FT_ERROR_BASE macro to extract the generic error code from an */
/* FT_Error value. */
/* */
/* */
/* II - Error Message strings */
/* -------------------------- */
/* */
/* The error definitions below are made through special macros that */
/* allow client applications to build a table of error message strings */
/* if they need it. The strings are not included in a normal build of */
/* FreeType 2 to save space (most client applications do not use */
/* them). */
/* */
/* To do so, you have to define the following macros before including */
/* this file: */
/* */
/* FT_ERROR_START_LIST :: */
/* This macro is called before anything else to define the start of */
/* the error list. It is followed by several FT_ERROR_DEF calls */
/* (see below). */
/* */
/* FT_ERROR_DEF( e, v, s ) :: */
/* This macro is called to define one single error. */
/* `e' is the error code identifier (e.g. FT_Err_Invalid_Argument). */
/* `v' is the error numerical value. */
/* `s' is the corresponding error string. */
/* */
/* FT_ERROR_END_LIST :: */
/* This macro ends the list. */
/* */
/* Additionally, you have to undefine __FTERRORS_H__ before #including */
/* this file. */
/* */
/* Here is a simple example: */
/* */
/* { */
/* #undef __FTERRORS_H__ */
/* #define FT_ERRORDEF( e, v, s ) { e, s }, */
/* #define FT_ERROR_START_LIST { */
/* #define FT_ERROR_END_LIST { 0, 0 } }; */
/* */
/* const struct */
/* { */
/* int err_code; */
/* const char* err_msg; */
/* } ft_errors[] = */
/* */
/* #include FT_ERRORS_H */
/* } */
/* */
/*************************************************************************/
#ifndef __FTERRORS_H__
#define __FTERRORS_H__
/* include module base error codes */
#include FT_MODULE_ERRORS_H
/*******************************************************************/
/*******************************************************************/
/***** *****/
/***** SETUP MACROS *****/
/***** *****/
/*******************************************************************/
/*******************************************************************/
#undef FT_NEED_EXTERN_C
#undef FT_ERR_XCAT
#undef FT_ERR_CAT
#define FT_ERR_XCAT( x, y ) x ## y
#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
/* FT_ERR_PREFIX is used as a prefix for error identifiers. */
/* By default, we use `FT_Err_'. */
/* */
#ifndef FT_ERR_PREFIX
#define FT_ERR_PREFIX FT_Err_
#endif
/* FT_ERR_BASE is used as the base for module-specific errors. */
/* */
#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS
#ifndef FT_ERR_BASE
#define FT_ERR_BASE FT_Mod_Err_Base
#endif
#else
#undef FT_ERR_BASE
#define FT_ERR_BASE 0
#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */
/* If FT_ERRORDEF is not defined, we need to define a simple */
/* enumeration type. */
/* */
#ifndef FT_ERRORDEF
#define FT_ERRORDEF( e, v, s ) e = v,
#define FT_ERROR_START_LIST enum {
#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) };
#ifdef __cplusplus
#define FT_NEED_EXTERN_C
extern "C" {
#endif
#endif /* !FT_ERRORDEF */
/* this macro is used to define an error */
#define FT_ERRORDEF_( e, v, s ) \
FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s )
/* this is only used for <module>_Err_Ok, which must be 0! */
#define FT_NOERRORDEF_( e, v, s ) \
FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s )
#ifdef FT_ERROR_START_LIST
FT_ERROR_START_LIST
#endif
/* now include the error codes */
#include FT_ERROR_DEFINITIONS_H
#ifdef FT_ERROR_END_LIST
FT_ERROR_END_LIST
#endif
/*******************************************************************/
/*******************************************************************/
/***** *****/
/***** SIMPLE CLEANUP *****/
/***** *****/
/*******************************************************************/
/*******************************************************************/
#ifdef FT_NEED_EXTERN_C
}
#endif
#undef FT_ERROR_START_LIST
#undef FT_ERROR_END_LIST
#undef FT_ERRORDEF
#undef FT_ERRORDEF_
#undef FT_NOERRORDEF_
#undef FT_NEED_EXTERN_C
#undef FT_ERR_CONCAT
#undef FT_ERR_BASE
/* FT_KEEP_ERR_PREFIX is needed for ftvalid.h */
#ifndef FT_KEEP_ERR_PREFIX
#undef FT_ERR_PREFIX
#endif
#endif /* __FTERRORS_H__ */
/* END */

View File

@ -0,0 +1,113 @@
/***************************************************************************/
/* */
/* ftgasp.h */
/* */
/* Access of TrueType's `gasp' table (specification). */
/* */
/* Copyright 2007, 2008 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 _FT_GASP_H_
#define _FT_GASP_H_
#include <freetype/ft2build.h>
#include FT_FREETYPE_H
/***************************************************************************
*
* @section:
* gasp_table
*
* @title:
* Gasp Table
*
* @abstract:
* Retrieving TrueType `gasp' table entries
*
* @description:
* The function @FT_Get_Gasp can be used to query a TrueType or OpenType
* font for specific entries in their `gasp' table, if any. This is
* mainly useful when implementing native TrueType hinting with the
* bytecode interpreter to duplicate the Windows text rendering results.
*/
/*************************************************************************
*
* @enum:
* FT_GASP_XXX
*
* @description:
* A list of values and/or bit-flags returned by the @FT_Get_Gasp
* function.
*
* @values:
* FT_GASP_NO_TABLE ::
* This special value means that there is no GASP table in this face.
* It is up to the client to decide what to do.
*
* FT_GASP_DO_GRIDFIT ::
* Grid-fitting and hinting should be performed at the specified ppem.
* This *really* means TrueType bytecode interpretation.
*
* FT_GASP_DO_GRAY ::
* Anti-aliased rendering should be performed at the specified ppem.
*
* FT_GASP_SYMMETRIC_SMOOTHING ::
* Smoothing along multiple axes must be used with ClearType.
*
* FT_GASP_SYMMETRIC_GRIDFIT ::
* Grid-fitting must be used with ClearType's symmetric smoothing.
*
* @note:
* `ClearType' is Microsoft's implementation of LCD rendering, partly
* protected by patents.
*
* @since:
* 2.3.0
*/
#define FT_GASP_NO_TABLE -1
#define FT_GASP_DO_GRIDFIT 0x01
#define FT_GASP_DO_GRAY 0x02
#define FT_GASP_SYMMETRIC_SMOOTHING 0x08
#define FT_GASP_SYMMETRIC_GRIDFIT 0x10
/*************************************************************************
*
* @func:
* FT_Get_Gasp
*
* @description:
* Read the `gasp' table from a TrueType or OpenType font file and
* return the entry corresponding to a given character pixel size.
*
* @input:
* face :: The source face handle.
* ppem :: The vertical character pixel size.
*
* @return:
* Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no
* `gasp' table in the face.
*
* @since:
* 2.3.0
*/
FT_EXPORT( FT_Int )
FT_Get_Gasp( FT_Face face,
FT_UInt ppem );
/* */
#endif /* _FT_GASP_H_ */
/* END */

Some files were not shown because too many files have changed in this diff Show More