summaryrefslogtreecommitdiff
path: root/Build/source/libs/t1lib/t1base.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/t1lib/t1base.c')
-rw-r--r--Build/source/libs/t1lib/t1base.c1252
1 files changed, 1252 insertions, 0 deletions
diff --git a/Build/source/libs/t1lib/t1base.c b/Build/source/libs/t1lib/t1base.c
new file mode 100644
index 00000000000..d2d28dc6fd4
--- /dev/null
+++ b/Build/source/libs/t1lib/t1base.c
@@ -0,0 +1,1252 @@
+/*--------------------------------------------------------------------------
+ ----- File: t1base.c
+ ----- Author: Rainer Menzner (Rainer.Menzner@web.de)
+ ----- Date: 2004-03-04
+ ----- Description: This file is part of the t1-library. It contains basic
+ routines to initialize the data structures used
+ by the t1-library.
+ ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2004.
+ As of version 0.5, t1lib is distributed under the
+ GNU General Public Library Lincense. The
+ conditions can be found in the files LICENSE and
+ LGPL, which should reside in the toplevel
+ directory of the distribution. Please note that
+ there are parts of t1lib that are subject to
+ other licenses:
+ The parseAFM-package is copyrighted by Adobe Systems
+ Inc.
+ The type1 rasterizer is copyrighted by IBM and the
+ X11-consortium.
+ ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-)
+ ----- Credits: I want to thank IBM and the X11-consortium for making
+ their rasterizer freely available.
+ Also thanks to Piet Tutelaers for his ps2pk, from
+ which I took the rasterizer sources in a format
+ independ from X11.
+ Thanks to all people who make free software living!
+--------------------------------------------------------------------------*/
+
+
+#define T1BASE_C
+
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#if defined(_MSC_VER)
+# include <io.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+#else
+# include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+#include "../type1/ffilest.h"
+#include "../type1/types.h"
+#include "parseAFM.h"
+#include "../type1/objects.h"
+#include "../type1/spaces.h"
+#include "../type1/util.h"
+#include "../type1/fontfcn.h"
+#include "../type1/regions.h"
+
+
+#include "sysconf.h"
+#include "t1base.h"
+#include "t1types.h"
+#include "t1global.h"
+#include "t1env.h"
+#include "t1delete.h"
+
+
+static int test_for_t1_file( char *buffer );
+static int T1_pad=0;
+
+/* A fix for Encoding Vector problem. Initialization / Deinitialization
+ is now done in T1_InitLib() / T1-CloseLib. */
+extern boolean Init_BuiltInEncoding( void);
+extern psobj *StdEncArrayP;
+
+static const char* T1errmsg[] = {
+ "", /* -10 */
+ "", /* -9 */
+ "", /* -8 */
+ "", /* -7 */
+ "", /* -6 */
+ "Attempt to Load Multiple Master Font", /* T1ERR_SCAN_FONT_FORMAT -5 */
+ "Type 1 Font File Open Error", /* T1ERR_SCAN_FILE_OPEN_ERR -4 */
+ "Virtual Memory Exceeded", /* T1ERR_SCAN_OUT_OF_MEMORY -3 */
+ "Syntactical Error Scanning Font File", /* T1ERR_SCAN_ERROR -2 */
+ "Premature End of Font File Encountered", /* T1ERR_SCAN_FILE_EOF -1 */
+ "", /* 0 */
+ "Path Construction Error", /* T1ERR_PATH_ERROR 1 */
+ "Font is Corrupt", /* T1ERR_PARSE_ERROR 2 */
+ "Rasterization Aborted", /* T1ERR_TYPE1_ABORT 3 */
+ "", /* 4 */
+ "", /* 5 */
+ "", /* 6 */
+ "", /* 7 */
+ "", /* 8 */
+ "", /* 9 */
+ "Font ID Invalid in this Context", /* T1ERR_INVALID_FONTID 10 */
+ "Invalid Argument in Function Call", /* T1ERR_INVALID_PARAMETER 11 */
+ "Operation not Permitted", /* T1ERR_OP_NOT_PERMITTED 12 */
+ "Memory Allocation Error", /* T1ERR_ALLOC_MEM 13 */
+ "Error Opening File", /* T1ERR_FILE_OPEN_ERR 14 */
+ "Unspecified T1Lib Error", /* T1ERR_UNSPECIFIED 15 */
+ "Missing AFM Data", /* T1ERR_NO_AFM_DATA 16 */
+ "X11 Interface Error", /* T1ERR_X11 17 */
+ "Missing Component of Composite Character" /* T1ERR_COMPOSITE_CHAR 18 */
+ "Error Scanning Encoding File", /* T1ERR_SCAN_ENCODING 19 */
+ "", /* 20 */
+};
+
+
+/* T1_StrError(): Return an error message corresponding to the value of
+ t1err. */
+const char *T1_StrError( int t1err)
+{
+ int errind;
+
+ errind = t1err + 10;
+
+ if ( errind < 0 )
+ errind = 0;
+ if ( errind > 29 )
+ errind = 0;
+
+ return T1errmsg[errind];
+}
+
+
+
+/* This function is to be called by the user to initialize
+ the font mechanism */
+void *T1_InitLib( int log)
+{
+ int result;
+ int i;
+
+ char *usershome=NULL;
+ char *logfilepath=NULL;
+ char *envlogreq=NULL;
+ int usrforcelog=0;
+
+
+
+ /* Reset T1_errno */
+ T1_errno=0;
+
+ /* Assign pointer to global struct and set entry padding: */
+ pFontBase=&FontBase;
+ if (T1_pad)
+ pFontBase->bitmap_pad=T1_pad;
+ else
+ pFontBase->bitmap_pad=T1GLYPH_PAD;
+
+ pFontBase->pFontArray = NULL;
+ pFontBase->t1lib_flags=0;
+ /* Check for AA-caching */
+ if ((log & T1_AA_CACHING)){
+ pFontBase->t1lib_flags |= T1_AA_CACHING;
+ }
+ /* Check for AFM disable */
+ if ((log & T1_NO_AFM)) {
+ pFontBase->t1lib_flags |= T1_NO_AFM;
+ }
+
+ /* Check environment variable ENV_LOG_STRING. By this means, a user may
+ generate a log file even if at compile time log file creation has
+ been suppressed. Of course, if the loglevel is reduced after
+ initialization by the programmer, this environment variable takes
+ no effect! */
+ if ((envlogreq=getenv(ENV_LOG_STRING))!=NULL) {
+ if (strcmp( envlogreq, "logDebug")==0)
+ T1_SetLogLevel( T1LOG_DEBUG);
+ else if (strcmp( envlogreq, "logStatistic")==0)
+ T1_SetLogLevel( T1LOG_STATISTIC);
+ else if (strcmp( envlogreq, "logWarning")==0)
+ T1_SetLogLevel( T1LOG_WARNING);
+ else if (strcmp( envlogreq, "logError")==0)
+ T1_SetLogLevel( T1LOG_ERROR);
+ usrforcelog=1;
+ }
+
+ /* Open log-file: */
+ t1lib_log_file=NULL;
+ if ((log & LOGFILE) || (usrforcelog!=0)) {
+ pFontBase->t1lib_flags |= LOGFILE;
+ /* Try first opening in current directory: */
+ if ((t1lib_log_file=fopen( T1_LOG_FILE, "wb"))==NULL) {
+ if ((usershome=getenv("HOME"))!=NULL) {
+ logfilepath=(char *)malloc((strlen(usershome) +
+ strlen(T1_LOG_FILE) + 2
+ ) * sizeof(char));
+ strcpy( logfilepath, usershome);
+ strcat( logfilepath, DIRECTORY_SEP);
+ strcat( logfilepath, T1_LOG_FILE);
+ if ((t1lib_log_file=fopen( logfilepath, "wb"))==NULL){
+ t1lib_log_file=stderr;
+ }
+ free( logfilepath);
+ }
+ else {
+ t1lib_log_file=stderr;
+ }
+ }
+ if (t1lib_log_file==stderr) {
+ T1_PrintLog( "T1_InitLib()", "Unable to open a logfile, using stderr",
+ T1LOG_ERROR);
+ }
+ }
+
+ T1_PrintLog( "T1_InitLib()", "Initialization started",
+ T1LOG_STATISTIC);
+ /* Check for representation of data in memory: */
+ if ((pFontBase->endian=T1_CheckEndian())){
+ T1_PrintLog( "T1_InitLib()", "Using Big Endian data presentation (MSBFirst)",
+ T1LOG_DEBUG);
+ pFontBase->endian=1;
+ }
+ else{
+ T1_PrintLog( "T1_InitLib()", "Using Little Endian data presentation (LSBFirst)",
+ T1LOG_DEBUG);
+ pFontBase->endian=0;
+ }
+
+ /* Save version identifier */
+ sprintf( err_warn_msg_buf, "Version Identifier: %s", T1LIB_IDENT);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf,
+ T1LOG_DEBUG);
+ /* Save how t1lib is initialized */
+ sprintf( err_warn_msg_buf, "Initialization flags: 0x%X", log);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf,
+ T1LOG_DEBUG);
+ /* Save padding value in log file */
+ sprintf( err_warn_msg_buf, "Glyphs are padded to %d bits",
+ pFontBase->bitmap_pad);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf,
+ T1LOG_DEBUG);
+#ifdef __CHAR_UNSIGNED__
+ T1_PrintLog( "T1_InitLib()", "System-Info: char is unsigned",
+ T1LOG_DEBUG);
+#else
+ T1_PrintLog( "T1_InitLib()", "System-Info: char is signed",
+ T1LOG_DEBUG);
+#endif
+ sprintf( err_warn_msg_buf, "System-Info: sizeof(char): %d",
+ SIZEOF_CHAR);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
+ sprintf( err_warn_msg_buf, "System-Info: sizeof(short): %d",
+ SIZEOF_SHORT);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
+ sprintf( err_warn_msg_buf, "System-Info: sizeof(int): %d",
+ SIZEOF_INT);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
+ sprintf( err_warn_msg_buf, "System-Info: sizeof(long): %d",
+ SIZEOF_LONG);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
+ sprintf( err_warn_msg_buf, "System-Info: sizeof(long long): %d",
+ SIZEOF_LONG_LONG);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
+ sprintf( err_warn_msg_buf, "System-Info: sizeof(float): %d",
+ SIZEOF_FLOAT);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
+ sprintf( err_warn_msg_buf, "System-Info: sizeof(double): %d",
+ SIZEOF_DOUBLE);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
+ sprintf( err_warn_msg_buf, "System-Info: sizeof(long double): %d",
+ SIZEOF_LONG_DOUBLE);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
+ sprintf( err_warn_msg_buf, "System-Info: sizeof(void *): %d",
+ SIZEOF_VOID_P);
+ T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
+
+ intT1_SetupDefaultSearchPaths();
+ if (log & IGNORE_CONFIGFILE) {
+ pFontBase->t1lib_flags |= IGNORE_CONFIGFILE;
+ T1_PrintLog( "T1_InitLib()", "Skipping configuration file search!",
+ T1LOG_STATISTIC);
+ }
+ else {
+ if ((result=intT1_ScanConfigFile())==0)
+ T1_PrintLog( "T1_InitLib()", "Warning t1lib configuration file not found!",
+ T1LOG_WARNING);
+ }
+
+ /* Initialize builtin Standard Encoding */
+ if ( !(Init_BuiltInEncoding()) ) {
+ T1_PrintLog( "T1_InitLib()", "Unable initialize internal StandardEncoding!",
+ T1LOG_ERROR);
+ }
+
+ /* Set the default encoding to the fonts' internal encoding */
+ pFontBase->default_enc=NULL;
+
+ /* Initialize the no_fonts... values */
+ pFontBase->no_fonts=0;
+ pFontBase->no_fonts_ini=pFontBase->no_fonts;
+ pFontBase->no_fonts_limit=pFontBase->no_fonts;
+
+
+ /* Check whether to read font database */
+ if ((log & IGNORE_FONTDATABASE)){
+ pFontBase->t1lib_flags |= IGNORE_FONTDATABASE;
+
+ T1_Up=1; /* System has been initialized ! */
+ T1_PrintLog( "T1_InitLib()", "Initialization successfully finished (Database empty)",
+ T1LOG_STATISTIC);
+
+ return((void *) pFontBase);
+ }
+
+ result=0;
+ /* Read fontdatabase(s) */
+ i=0;
+ while (T1_FDB_ptr[i]!=NULL) {
+ if ((result=intT1_scanFontDBase(T1_FDB_ptr[i]))==-1){
+ T1_PrintLog( "T1_InitLib()", "Fatal error scanning Font Database File %s",
+ T1LOG_WARNING, T1_FDB_ptr[i]);
+ }
+ if (result>-1)
+ pFontBase->no_fonts+=result;
+ i++;
+
+ }
+ if (result == 0){
+ T1_PrintLog( "T1_InitLib()", "No fonts from Font Database File(s) found (T1_errno=%d)",
+ T1LOG_ERROR, T1_errno);
+ return(NULL);
+ }
+
+ /* Initialize the no_fonts... values */
+ pFontBase->no_fonts_ini=pFontBase->no_fonts;
+ pFontBase->no_fonts_limit=pFontBase->no_fonts;
+
+ T1_Up=1; /* System has been initialized ! */
+ T1_PrintLog( "T1_InitLib()", "Initialization successfully finished",
+ T1LOG_STATISTIC);
+
+ return((void *) pFontBase);
+}
+
+
+
+/* intT1_scanFontDBase():
+ - opens the file with the font definitions,
+ - reads the number of fonts defined and saves this in FontBase,
+ - allocates memory for all the filenames of the Type1 files
+ - tests for .pfa und .pfb files and saves the name found
+ - initializes an array that allows to acces these names by an
+ index number, the font_ID
+ - returns -1 on fatal error and the number of fonts located
+ successfullly
+ */
+int intT1_scanFontDBase( char *filename)
+{
+ int fd;
+ int filesize, i, j, k, m;
+ int found=0, located=0;
+ char *filebuffer;
+ int nofonts=0;
+ FONTPRIVATE* fontarrayP=NULL;
+
+#ifndef O_BINARY
+# define O_BINARY 0x0
+#endif
+
+ if ((fd=open( filename, O_RDONLY | O_BINARY))<3){
+ T1_PrintLog( "intT1_scanFontDBase()", "Font Database File %s not found!",
+ T1LOG_WARNING, filename);
+ T1_errno=T1ERR_FILE_OPEN_ERR;
+ return(-1);
+ }
+
+ /* Get the file size */
+ filesize=lseek( fd, 0, 2);
+ /* Reset fileposition to start */
+ lseek (fd, 0, 0);
+
+ if ((filebuffer=(char *)malloc(filesize*sizeof(char)
+ )) == NULL){
+ T1_PrintLog( "intT1_scanFontDBase()",
+ "Couldn't allocate memory for loading font database file %s",
+ T1LOG_ERROR, filename);
+ T1_errno=T1ERR_ALLOC_MEM;
+ return(-1);
+ }
+
+ i=read( fd, filebuffer, filesize);
+ close(fd); /* Close font database file */
+
+ i=j=m=0;
+
+ while (i<filesize) {
+ if (filebuffer[i]=='\n'){ /* We are at the end of line */
+ if (j==0) { /* Read the first line as the number of fonts */
+ filebuffer[i]=0;
+ sscanf( &filebuffer[0], "%d", &nofonts);
+ filebuffer[i]='\n'; /* Because it gives a better feeling */
+ /* (Re)Allocate memory for 'no_fonts' structures: */
+ if ((FontBase.pFontArray=(FONTPRIVATE *)
+ realloc( FontBase.pFontArray, (FontBase.no_fonts+nofonts)*sizeof(FONTPRIVATE))) == NULL) {
+ T1_PrintLog( "inT1_scanFontDBase()",
+ "Failed to allocate memory for FONTPRIVATE-area while scanning %s",
+ T1LOG_ERROR, filename);
+ T1_errno=T1ERR_ALLOC_MEM;
+ return(-1);
+ }
+ /* setup pointer to newly allocated area and do a reset */
+ fontarrayP=&(FontBase.pFontArray[FontBase.no_fonts]);
+ memset(fontarrayP, 0, nofonts*sizeof(FONTPRIVATE));
+ located=1; /* In order to increment m */
+ }
+ else { /* We are in the second or higher line */
+ k=i;
+ while (isspace((int)filebuffer[k])){
+ k--;
+ }
+ /* We are at the last printable character of a line; let's
+ step back (over the [afm/sfm]) to the period and replace it
+ by an ASCII 0 */
+ while ((filebuffer[k]!='.') && (!isspace((int)filebuffer[k])) ){
+ k--;
+ }
+ if (filebuffer[k]=='.'){ /* We have a name terminated with . */
+ filebuffer[k]=0; /* termination for string reading */
+ while (!isspace((int)filebuffer[k])){
+ k--;
+ }
+ }
+ else { /* The filename was without . and / or the first on the line */
+ ;
+ }
+ sscanf( &(filebuffer[k+1]), "%s", &(linebuf[0]));
+ /* We print error string before testing because after the call
+ to test_for_t1_file() filename is substituted by an emty
+ string if the file was not found: */
+ sprintf( err_warn_msg_buf, "Type 1 Font file %s.[pfa/pfb] not found (FontID=%d, SearchPath=%s)",
+ linebuf, m-1, T1_GetFileSearchPath(T1_PFAB_PATH));
+ if ((test_for_t1_file( &linebuf[0]))){
+ T1_PrintLog( "intT1_scanFontDBase()", err_warn_msg_buf, T1LOG_WARNING);
+ located=0;
+ }
+ else{
+ /* linebuf contains now the valid Type1 filename; let's
+ now copy this string into the appropriate place in the
+ FONTPRIVATE-struct: */
+ found++;
+ located=1;
+ if ((fontarrayP[m-1].pFontFileName=(char *)
+ calloc( strlen( &linebuf[0])+1, sizeof(char))) == NULL){
+ T1_PrintLog( "intT1_scanFontDBase()",
+ "Failed to allocate memory for Filename %s (FontID=%d)",
+ T1LOG_ERROR, &linebuf[0], m-1);
+ T1_errno=T1ERR_ALLOC_MEM;
+ return(-1);
+ }
+ strcpy( fontarrayP[m-1].pFontFileName, &linebuf[0]);
+ }
+ }
+ j++; /* Advance line counter */
+ if ((located))
+ m++;
+ }
+ if (j>nofonts) /* to ignore especially white space at end */
+ break;
+ i++; /* Step further in file position */
+ }
+ /* Return the memory for file reading */
+ free(filebuffer);
+
+ return( found);
+}
+
+
+/* T1_CloseLib(): Close the library and free all associated memory */
+int T1_CloseLib( void)
+{
+
+ int i, j, error=0;
+
+ if (T1_Up){
+ for (i=pFontBase->no_fonts; i; i--){
+ /* Free filename only if not NULL and if the font is physical!
+ Do it before removing the font since the physical information
+ is no more available afterwards. If necessary, an explicitly
+ specified AFM filename is also freed.
+ */
+ if ((pFontBase->pFontArray[i-1].pFontFileName!=NULL)
+ && (pFontBase->pFontArray[i-1].physical==1)){
+ free( pFontBase->pFontArray[i-1].pFontFileName);
+ pFontBase->pFontArray[i-1].pFontFileName=NULL;
+ if (pFontBase->pFontArray[i-1].pAfmFileName!=NULL){
+ free( pFontBase->pFontArray[i-1].pAfmFileName);
+ pFontBase->pFontArray[i-1].pAfmFileName=NULL;
+ }
+ }
+
+ /* Now, remove font: */
+ if ((j=T1_DeleteFont( i-1))){
+ error=1;
+ sprintf( err_warn_msg_buf, "T1_DeleteFont() returned %d for Font %d",
+ j, i-1);
+ T1_PrintLog( "T1_CloseLib()", err_warn_msg_buf, T1LOG_ERROR);
+ }
+ }
+ /* Free the FONTPRIVATE area */
+ if (pFontBase->pFontArray)
+ free( pFontBase->pFontArray);
+ else
+ error=1;
+
+ /* Get rid of internal StandardEncoding vector */
+ if ( StdEncArrayP != NULL ) {
+ free( StdEncArrayP);
+ StdEncArrayP = NULL;
+ }
+
+ /* Free search paths */
+ intT1_FreeSearchPaths();
+
+ /* Reset the flags */
+ pFontBase->t1lib_flags=0;
+
+ /* Indicate Library is no longer initialized */
+ pFontBase=NULL;
+ T1_Up=0;
+ T1_PrintLog( "T1_CloseLib()", "Library closed", T1LOG_STATISTIC);
+ if ((t1lib_log_file!=NULL) && (t1lib_log_file!=stderr))
+ fclose(t1lib_log_file);
+ t1lib_log_file=NULL;
+ }
+
+ return( error);
+}
+
+
+/* T1_AddFont(): Add a new fontfile to the fontdatabase.
+ Return values: >0: Assigned FontID
+ -1: Fontfile not found
+ -2: Error allocating memory for FONTPRIVATE-area
+ -3: No memory for saving font filename
+ */
+int T1_AddFont( char *fontfilename)
+{
+
+ char *FullName;
+ FONTPRIVATE *save_ptr;
+ int i;
+ int new_ID;
+
+
+ if (fontfilename==NULL){
+ T1_errno=T1ERR_INVALID_PARAMETER;
+ return(-1);
+ }
+
+ /* Check for existence of fontfile */
+ if ((FullName=intT1_Env_GetCompletePath(fontfilename,T1_PFAB_ptr))==NULL) {
+ T1_errno=T1ERR_FILE_OPEN_ERR;
+ return(-1);
+ }
+ free(FullName);
+
+ /* Check if free space for a new FONTPRIVATE is available; if not,
+ realloc memory some amount larger */
+ save_ptr=pFontBase->pFontArray;
+ if (pFontBase->no_fonts==pFontBase->no_fonts_limit){
+ if (pFontBase->pFontArray == NULL) {
+ /* In case this is the first font */
+ pFontBase->pFontArray=(FONTPRIVATE *)calloc(pFontBase->no_fonts_limit
+ + ADVANCE_FONTPRIVATE,
+ sizeof(FONTPRIVATE));
+ }
+ else {
+ /* We already have some fonts */
+ pFontBase->pFontArray=(FONTPRIVATE *)realloc(pFontBase->pFontArray,
+ (pFontBase->no_fonts_limit
+ + ADVANCE_FONTPRIVATE)
+ * sizeof(FONTPRIVATE));
+ if (pFontBase->pFontArray==NULL){
+ /* Restore pointer */
+ pFontBase->pFontArray=save_ptr;
+ T1_errno=T1ERR_ALLOC_MEM;
+ return(-2); /* No memory available */
+ }
+ }
+ pFontBase->no_fonts_limit += ADVANCE_FONTPRIVATE;
+ /* First, initialize newly allocated to be not used */
+ for ( i=pFontBase->no_fonts;
+ i<pFontBase->no_fonts+ADVANCE_FONTPRIVATE; i++){
+ pFontBase->pFontArray[i].pFontFileName=NULL;
+ pFontBase->pFontArray[i].pAfmFileName=NULL;
+ pFontBase->pFontArray[i].pAFMData=NULL;
+ pFontBase->pFontArray[i].pType1Data=NULL;
+ pFontBase->pFontArray[i].pEncMap=NULL;
+ pFontBase->pFontArray[i].pKernMap=NULL;
+ pFontBase->pFontArray[i].pFontEnc=NULL;
+ pFontBase->pFontArray[i].pFontSizeDeps=NULL;
+ pFontBase->pFontArray[i].vm_base=NULL;
+ pFontBase->pFontArray[i].FontMatrix[0]=0.0;
+ pFontBase->pFontArray[i].FontMatrix[1]=0.0;
+ pFontBase->pFontArray[i].FontMatrix[2]=0.0;
+ pFontBase->pFontArray[i].FontMatrix[3]=0.0;
+ pFontBase->pFontArray[i].FontTransform[0]=0.0;
+ pFontBase->pFontArray[i].FontTransform[1]=0.0;
+ pFontBase->pFontArray[i].FontTransform[2]=0.0;
+ pFontBase->pFontArray[i].FontTransform[3]=0.0;
+ pFontBase->pFontArray[i].slant=0.0;
+ pFontBase->pFontArray[i].extend=0.0;
+ pFontBase->pFontArray[i].physical=0;
+ pFontBase->pFontArray[i].refcount=0;
+ pFontBase->pFontArray[i].space_position=0;
+ pFontBase->pFontArray[i].info_flags=0;
+ }
+ }
+ /* no_fonts-1 was the largest allowed font ID */
+ new_ID=pFontBase->no_fonts;
+ pFontBase->no_fonts++;
+
+ if ((FontBase.pFontArray[new_ID].pFontFileName=(char *)
+ calloc( strlen( fontfilename)+1, sizeof(char))) == NULL){
+ T1_PrintLog( "T1_AddFont()",
+ "Failed to allocate memory for Filename %s (FontID=%d)",
+ T1LOG_ERROR, fontfilename, new_ID);
+ T1_errno=T1ERR_ALLOC_MEM;
+ return(-3);
+ }
+ strcpy( FontBase.pFontArray[new_ID].pFontFileName, fontfilename);
+
+ /* Generate logfile entry */
+ sprintf( err_warn_msg_buf, "Assigned FontID %d to fontfile %s",
+ new_ID, FontBase.pFontArray[new_ID].pFontFileName);
+ T1_PrintLog( "T1_AddFont()", err_warn_msg_buf,
+ T1LOG_STATISTIC);
+ /* Return FontID of newly declared font */
+ return( new_ID);
+
+}
+
+
+/* T1_PrintLog() generates entries in the log file. msg_txt is subject to scan
+ conversion and ... signifies a accordingly lrge variable list. */
+void T1_PrintLog( char *func_ident, char *msg_txt, int level, ...)
+{
+ va_list vararg;
+ static char levelid[4]={ 'E', 'W', 'S', 'D'};
+ time_t s_clock, *tp;
+
+ if (t1lib_log_file==NULL)
+ return;
+ if ((level>t1lib_log_level) || (level<1)){
+ return;
+ }
+ else{
+ /* initialize argument list */
+ va_start( vararg, level);
+
+ tp=&s_clock;
+ s_clock=time( tp);
+ /*
+ fprintf( t1lib_log_file, "(%c) (%.24s) %s: ",
+ levelid[level-1], ctime(&s_clock), func_ident);
+ */
+ /* Don't print the time stamp */
+ fprintf( t1lib_log_file, "(%c) %s: ", levelid[level-1], func_ident );
+ vfprintf( t1lib_log_file, msg_txt, vararg );
+ fprintf( t1lib_log_file, "\n");
+ fflush( t1lib_log_file);
+
+ /* cleanup variable list */
+ va_end( vararg);
+
+ return;
+ }
+}
+
+
+/* T1_SetLogLevel(): Set the level which a message must have so
+ that it is printed into the logfile. This function may be called
+ before T1_InitLib(). */
+void T1_SetLogLevel( int level)
+{
+ if ((level>0) && (level<5))
+ t1lib_log_level=level;
+ return;
+}
+
+
+
+/* T1_CheckForInit(): If no initialization of font mechanism has been
+ done, return -1, indicating an error. */
+int T1_CheckForInit(void)
+{
+ if(T1_Up)
+ return(0);
+ else
+ return(-1);
+
+}
+
+
+
+/* T1_CheckForFontID(): Checks the font mechanism concerning the specified
+ ID. It returns:
+ 0 if font belonging to FontID has not yet been loaded
+ 1 if font belonging to FontID has already been loaded
+ -1 if FontID is an invalid specification or t1lib not
+ initialized
+ */
+int T1_CheckForFontID( int FontID)
+{
+
+ /* FontID is invalid */
+ if ((FontID<0)||(FontID>(pFontBase->no_fonts - 1))||(T1_Up==0))
+ return(-1);
+
+ if (pFontBase->pFontArray[FontID].pType1Data==NULL)
+ return(0); /* has not yet been loaded */
+ else
+ return(1); /* has already been loaded */
+}
+
+
+
+
+/* test_for_t1_file returns 0 if a file "name.pfa" or "name.pfb"
+ was found. Else, -1 is returned. If successful, buffer contains the
+ found filename string */
+static int test_for_t1_file( char *buffer )
+{
+ int i=0;
+ char *FullName;
+
+ /* First case: A PostScript Font ASCII File without extension
+ (according to some UNIX-conventions) */
+ if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) {
+ free(FullName);
+ return(0);
+ }
+
+ while (buffer[i]!=0){
+ i++;
+ }
+ buffer[i]='.';
+ buffer[i+1]='p';
+ buffer[i+2]='f';
+ buffer[i+4]=0;
+
+
+ /* Second case: A PostScript Font ASCII File */
+ buffer[i+3]='a';
+ if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) {
+ free(FullName);
+ return(0);
+ }
+ /* Third case: A PostScript Font Binary File */
+ buffer[i+3]='b';
+ if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) {
+ free(FullName);
+ return(0);
+ }
+
+ /* If we get here no file was found => Set buffer
+ to an empty string and return -1 */
+
+ buffer[0]=0;
+ return(-1);
+}
+
+
+/* T1_GetFontFileName() returns a pointer to the filename of the font,
+ associated with FontID. This filename does not contain a full path.
+ */
+char *T1_GetFontFileName( int FontID)
+{
+
+ static char filename[MAXPATHLEN+1];
+
+ if (T1_CheckForInit())return(NULL);
+
+ /* Check first for valid FontID */
+ if ((FontID<0) || (FontID>FontBase.no_fonts)){
+ T1_errno=T1ERR_INVALID_FONTID;
+ return(NULL);
+ }
+
+ strcpy( filename, pFontBase->pFontArray[FontID].pFontFileName);
+
+ return( filename);
+
+}
+
+
+
+/* As suggested by Nicolai Langfeldt, we make it possible to specify
+ a completely independent path for the afm filename. This should
+ make t1lib usable in context with using the kpathsearch-library.
+ We allow setting those path´s after initialization, but before a
+ font is loaded.
+ returns 0: OK
+ -1: Operation could not be performed
+*/
+int T1_SetAfmFileName( int FontID, char *afm_name)
+{
+
+ if (T1_CheckForFontID(FontID)!=0){
+ /* Operation may not be applied because FontID is invalid
+ or font is loaded */
+ T1_errno=T1ERR_INVALID_FONTID;
+ return(-1);
+ }
+ if (afm_name==NULL) {
+ T1_errno=T1ERR_INVALID_PARAMETER;
+ return(-1);
+ }
+ if (pFontBase->pFontArray[FontID].pAfmFileName!=NULL){
+ /* we first free the current name */
+ free( pFontBase->pFontArray[FontID].pAfmFileName);
+ pFontBase->pFontArray[FontID].pAfmFileName=NULL;
+ }
+
+ if ((pFontBase->pFontArray[FontID].pAfmFileName=
+ (char *)malloc( (strlen(afm_name)+1)*sizeof( char)))==NULL) {
+ T1_errno=T1ERR_ALLOC_MEM;
+ return( -1);
+ }
+ strcpy( pFontBase->pFontArray[FontID].pAfmFileName, afm_name);
+
+ return(0);
+
+}
+
+
+
+/* We have a function for querying the name. Returns a pointer
+ to the string or NULL if name was not explicitly set .*/
+char *T1_GetAfmFileName( int FontID)
+{
+
+ static char filename[MAXPATHLEN+1];
+
+ if (T1_CheckForInit())return(NULL);
+
+ /* Check first for valid FontID */
+ if ((FontID<0) || (FontID>FontBase.no_fonts)){
+ T1_errno=T1ERR_INVALID_FONTID;
+ return(NULL);
+ }
+
+ if (pFontBase->pFontArray[FontID].pAfmFileName==NULL) {
+ return( NULL);
+ }
+
+ strcpy( filename, pFontBase->pFontArray[FontID].pAfmFileName);
+ return( filename);
+
+}
+
+
+
+/* T1_GetNoFonts(): Return the number of declared fonts */
+int T1_GetNoFonts(void)
+{
+ if (T1_CheckForInit())
+ return(-1);
+ return(FontBase.no_fonts);
+}
+
+
+
+/* T1_SetDeviceResolutions( x_res, y_res): Set the device's physical
+ resolution in horizontal and vertical direction, mesured in DPI
+ (Dots Per Inch). This should be done before the first font is
+ loaded! */
+int T1_SetDeviceResolutions( float x_res, float y_res)
+{
+
+ int i;
+
+ if (T1_CheckForInit())
+ ; /* Not initialized -> no size dependent data -> OK */
+ else
+ /* Check if size-dependent data is existent */
+ for ( i=T1_GetNoFonts(); i; i--)
+ if (pFontBase->pFontArray[i-1].pFontSizeDeps!=NULL){
+ T1_errno=T1ERR_OP_NOT_PERMITTED;
+ return(-1); /* There's is size dependent data for a font */
+ }
+
+ /* Save resolutions and calculate horizontal and vertical
+ scale factors to map desired bp to device pixel */
+ DeviceSpecifics.x_resolution=(float) x_res;
+ DeviceSpecifics.y_resolution=(float) y_res;
+ DeviceSpecifics.scale_x=(float)(((float)x_res)/BIGPOINTSPERINCH);
+ DeviceSpecifics.scale_y=(float)(((float)y_res)/BIGPOINTSPERINCH);
+ return(0);
+}
+
+
+/* T1_QueryX11Support(): Check at runtime to see if t1lib was compiled
+ with X11 interface: */
+int T1_QueryX11Support( void)
+{
+#ifndef T1LIB_NO_X11_SUPPORT
+ return(1);
+#else
+ return(0);
+#endif
+}
+
+
+
+
+/* int T1_CopyFont(): Copies the font associated with FontID to another
+ location. The pointers to type1- , afm- and encoding data as well as
+ the matrices remain completely untouched. However, size dependent data
+ is not copied. The produced font is marked as a "logical" font.
+ If no memory is available in the FONTPRIVATE-array, there's realloc'ed
+ some more memory. The FontID which is assigned to the newly generated
+ font is given as the return value, or < 0 if an error occurs. Also,
+ the refcount entry of the source font is incremented by one.
+
+ Return value -1: invalid FontID specified
+ -2: source font is not a "physical" font
+ -3: no memory for reallocation of FONTPRIVATEs
+ -4: no memory for one of the mapping tables
+ */
+int T1_CopyFont( int FontID)
+{
+ FONTPRIVATE *save_ptr;
+ int k;
+ int new_ID;
+
+
+ /* Check for a valid source font */
+ if (T1_CheckForFontID(FontID)!=1){
+ T1_errno=T1ERR_INVALID_FONTID;
+ return(-1);
+ }
+
+
+ /* Check if the font in question is a "physical" font, otherwise it may
+ not be copied */
+ if (pFontBase->pFontArray[FontID].physical==0){
+ T1_errno=T1ERR_OP_NOT_PERMITTED;
+ return(-2);
+ }
+
+
+ /* Check if free space for a new FONTPRIVATE is available; if not,
+ realloc memory some amount larger */
+ save_ptr=pFontBase->pFontArray;
+ if (pFontBase->no_fonts==pFontBase->no_fonts_limit){
+ pFontBase->pFontArray=(FONTPRIVATE *)realloc(pFontBase->pFontArray,
+ (pFontBase->no_fonts_limit
+ + ADVANCE_FONTPRIVATE)
+ * sizeof(FONTPRIVATE));
+ if (pFontBase->pFontArray==NULL){
+ /* Restore pointer */
+ pFontBase->pFontArray=save_ptr;
+ T1_errno=T1ERR_ALLOC_MEM;
+ return(-3);
+ }
+ /* We zero the newly allocated memory */
+ if (pFontBase->pFontArray != NULL) {
+ memset( pFontBase->pFontArray + pFontBase->no_fonts_limit, 0,
+ ADVANCE_FONTPRIVATE * sizeof(FONTPRIVATE));
+ }
+ pFontBase->no_fonts_limit += ADVANCE_FONTPRIVATE;
+ }
+ /* no_fonts-1 was the largest allowed font ID */
+ new_ID=pFontBase->no_fonts;
+ /* Copy FONTPRIVATE-structure: */
+ pFontBase->pFontArray[new_ID]=pFontBase->pFontArray[FontID];
+ /* (Re)Set some values explicitly, others remain untouched: */
+ pFontBase->pFontArray[new_ID].pFontSizeDeps=NULL;
+ pFontBase->pFontArray[new_ID].physical=0;
+ /* AFM-mapping tables are to be setup for logical fonts separately
+ (if AFM data is there) */
+ /* first, kerning map */
+ if (pFontBase->pFontArray[new_ID].pAFMData) {
+ k=pFontBase->pFontArray[new_ID].pAFMData->numOfPairs;
+ if (k>0){ /* kern map exists only if kerning pairs exist! */
+ if ((pFontBase->pFontArray[new_ID].pKernMap=
+ (METRICS_ENTRY *)malloc( k*sizeof( METRICS_ENTRY)))==NULL){
+ sprintf( err_warn_msg_buf, "Error allocating memory for kerning map (new_ID=%d)",
+ new_ID);
+ T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf,
+ T1LOG_WARNING);
+ T1_errno=T1ERR_ALLOC_MEM;
+ return(-4);
+ }
+ memcpy( pFontBase->pFontArray[new_ID].pKernMap,
+ pFontBase->pFontArray[FontID].pKernMap,
+ k*sizeof( METRICS_ENTRY));
+ }
+ else { /* no kerning pairs, bu AFM data present */
+ pFontBase->pFontArray[new_ID].pKernMap=NULL;
+ }
+ }
+ else { /* AFM data not present at all */
+ pFontBase->pFontArray[new_ID].pKernMap=NULL;
+ }
+
+ /* second, encoding map */
+ if (pFontBase->pFontArray[FontID].pEncMap!=NULL) {
+ if ((pFontBase->pFontArray[new_ID].pEncMap=
+ (int *)calloc(256,sizeof(int)))==NULL){
+ sprintf( err_warn_msg_buf,
+ "Error allocating memory for encoding map (new_ID=%d)",
+ new_ID);
+ T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf,
+ T1LOG_WARNING);
+ T1_errno=T1ERR_ALLOC_MEM;
+ return(-4);
+ }
+ memcpy( pFontBase->pFontArray[new_ID].pEncMap,
+ pFontBase->pFontArray[FontID].pEncMap,
+ 256*sizeof( int));
+ }
+
+ /* New font is logical --> indicate to which physical font it
+ refers by setting refcount: */
+ pFontBase->pFontArray[new_ID].refcount=FontID;
+
+ /* Now the struct is setup; increment no_fonts by 1 because
+ new_ID is a valid font specification from now on. */
+ pFontBase->no_fonts++;
+ /* Increment refcount in source font */
+ pFontBase->pFontArray[FontID].refcount++;
+
+ /* Generate logfile entry */
+ sprintf( err_warn_msg_buf, "Assigned FontID %d to fontfile %s",
+ new_ID, FontBase.pFontArray[new_ID].pFontFileName);
+ T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf,
+ T1LOG_STATISTIC);
+ return(new_ID);
+}
+
+
+
+/* T1_SetBitmapPad(): Set the value to which bitmap-scanlines are padded.
+ This has to be done before initialization because it is a very
+ rudimentary operation.
+ */
+int T1_SetBitmapPad( int pad)
+{
+ if (T1_Up){
+ /* Library is initialized --> return error */
+ T1_errno=T1ERR_OP_NOT_PERMITTED;
+ return(-1);
+ }
+ else{
+ switch (pad){
+ case 8:
+ T1_pad=8;
+ return(0);
+ case 16:
+ T1_pad=16;
+ return(0);
+#ifdef T1_AA_TYPE64
+ case 32:
+ T1_pad=32;
+ return(0);
+#endif
+ default:
+ T1_errno=T1ERR_INVALID_PARAMETER;
+ return(-1);
+ }
+ }
+}
+
+
+
+/* T1_GetBitmapPad(): Read the value to which scanlines of bitmap are
+ padded. This can be done before or after initialization. */
+int T1_GetBitmapPad( void)
+{
+ if (pFontBase) /* T1lib initialized --> return value from struct */
+ return( pFontBase->bitmap_pad);
+ else{
+ if (T1_pad)
+ return(T1_pad); /* pad is explicitly set --> return that value */
+ else
+ return( T1GLYPH_PAD); /* not expl. set --> return compilation default */
+ }
+}
+
+
+
+/* CheckEndian(): Checks whether the current machine is of little or big
+ endian architecture. This is important for concatenating bitmaps.
+ Function returns 0 if LittleEndian and 1 if BigEndian representation
+ is used on the current hardware.
+ */
+int T1_CheckEndian()
+{
+ unsigned char *charptr;
+
+ /* Generate test value */
+ unsigned short test=0x0001;
+
+ /* Read out memory as unsigned char */
+ charptr=(unsigned char *)(&test)+1;
+
+ /* Return value will be 1 if Big- and 0 if Little Endian */
+ return((int) *charptr);
+
+}
+
+
+
+/* T1_GetLibIdent(): Return the identifier string for the current version
+ of t1lib */
+char *T1_GetLibIdent( void)
+{
+ static char buf[15];
+
+ sprintf( buf, "%s", T1LIB_IDENT);
+
+ return( (char *)buf);
+}
+
+
+
+/* T1_SetRasterFlags(): Enable/Disable certain features in
+ the rasterizer */
+extern void T1_SetRasterFlags( int flags)
+{
+
+ T1_Type1OperatorFlags=flags;
+ return;
+
+}
+
+
+
+/* T1_GetFontFileName(): returns a pointer to the complete path filename
+ of the font, associated with FontID as it is in use by t1lib.
+ */
+char *T1_GetFontFilePath( int FontID)
+{
+
+ static char filepath[MAXPATHLEN+1];
+ char *FileNamePath=NULL;
+
+ /* is initialzed? */
+ if (T1_CheckForInit()) {
+ T1_errno=T1ERR_INVALID_FONTID;
+ return(NULL);
+ }
+
+ /* Check first for valid FontID */
+ if ((FontID<0) || (FontID>FontBase.no_fonts)){
+ T1_errno=T1ERR_INVALID_FONTID;
+ return(NULL);
+ }
+
+ /* lib is initialized and FontID is valid ->
+ we can really expect a name */
+ if ((FileNamePath=intT1_Env_GetCompletePath( pFontBase->pFontArray[FontID].pFontFileName,
+ T1_PFAB_ptr))==NULL) {
+ T1_PrintLog( "T1_GetFontFilePath()", "Couldn't locate font file for font %d in %s",
+ T1LOG_WARNING, FontID, T1_GetFileSearchPath(T1_PFAB_PATH));
+ T1_errno=T1ERR_FILE_OPEN_ERR;
+ return(NULL);
+ }
+
+ strcpy( filepath, FileNamePath);
+ free( FileNamePath);
+
+ return( filepath);
+
+}
+
+
+
+/* We have a function for querying the name. Returns a pointer
+ to the string or NULL if name was not explicitly set .*/
+char *T1_GetAfmFilePath( int FontID)
+{
+
+ static char filepath[MAXPATHLEN+1];
+ char *FontFileName;
+ char *AFMFilePath;
+ int i, j;
+
+ /* is initialized? */
+ if ((T1_CheckForInit())) {
+ T1_errno=T1ERR_INVALID_FONTID;
+ return(NULL);
+ }
+
+ /* Check first for valid FontID */
+ if ((FontID<0) || (FontID>FontBase.no_fonts)){
+ T1_errno=T1ERR_INVALID_FONTID;
+ return(NULL);
+ }
+
+ /* Check wether AFM-file loading was suppressed on user's request */
+ if ((pFontBase->t1lib_flags & T1_NO_AFM)!=0) {
+ /* this is no error condition, we simply return (NULL) */
+ return( NULL);
+ }
+
+ /* Check for explicitly associated metrics filename (via
+ "T1_SetAfmFileName()"). If it exists, we return it! */
+ if (pFontBase->pFontArray[FontID].pAfmFileName!=NULL) {
+ strcpy( filepath, pFontBase->pFontArray[FontID].pAfmFileName);
+ sprintf( err_warn_msg_buf, "Returning explicitly specified path %s for Font %d",
+ filepath, FontID);
+ T1_PrintLog( "T1_GetAfmFilePath()", err_warn_msg_buf, T1LOG_DEBUG);
+ return( filepath);
+ }
+
+ /* we have the usual case that the name of the metrics file has to be
+ deduced from the font file name */
+ FontFileName=T1_GetFontFileName( FontID);
+ i=strlen(FontFileName);
+ j=i;
+ strcpy( filepath, FontFileName);
+ while ( filepath[i] != '.'){
+ if (i==0) break;
+ else i--;
+ }
+ if (i==0){
+ /* We have a filename without extension -> append extension */
+ filepath[j]='.';
+ filepath[j+1]='a';
+ filepath[j+2]='f';
+ filepath[j+3]='m';
+ filepath[j+4]='\0';
+ }
+ else{
+ /* we found a '.' -> replace extension */
+ filepath[i+1]='a';
+ filepath[i+2]='f';
+ filepath[i+3]='m';
+ filepath[i+4]='\0';
+ }
+ /* Get full path of the afm file (The case of a full path name
+ name specification is valid) */
+ if ((AFMFilePath=intT1_Env_GetCompletePath( filepath, T1_AFM_ptr)) == NULL) {
+ return NULL;
+ }
+
+ strcpy( filepath, AFMFilePath);
+ free( AFMFilePath);
+
+ return( filepath);
+
+}
+
+