~ubuntu-branches/ubuntu/karmic/grace/karmic

« back to all changes in this revision

Viewing changes to T1lib/t1lib/t1base.c

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2002-03-19 14:19:58 UTC
  • Revision ID: james.westby@ubuntu.com-20020319141958-5gxna6vo1ek3zjml
Tags: upstream-5.1.7
ImportĀ upstreamĀ versionĀ 5.1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*--------------------------------------------------------------------------
 
2
  ----- File:        t1base.c 
 
3
  ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
 
4
  ----- Date:        2001-10-03
 
5
  ----- Description: This file is part of the t1-library. It contains basic
 
6
                     routines to initialize the data structures used
 
7
                     by the t1-library.
 
8
  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
 
9
                     As of version 0.5, t1lib is distributed under the
 
10
                     GNU General Public Library Lincense. The
 
11
                     conditions can be found in the files LICENSE and
 
12
                     LGPL, which should reside in the toplevel
 
13
                     directory of the distribution.  Please note that 
 
14
                     there are parts of t1lib that are subject to
 
15
                     other licenses:
 
16
                     The parseAFM-package is copyrighted by Adobe Systems
 
17
                     Inc.
 
18
                     The type1 rasterizer is copyrighted by IBM and the
 
19
                     X11-consortium.
 
20
  ----- Warranties:  Of course, there's NO WARRANTY OF ANY KIND :-)
 
21
  ----- Credits:     I want to thank IBM and the X11-consortium for making
 
22
                     their rasterizer freely available.
 
23
                     Also thanks to Piet Tutelaers for his ps2pk, from
 
24
                     which I took the rasterizer sources in a format
 
25
                     independ from X11.
 
26
                     Thanks to all people who make free software living!
 
27
--------------------------------------------------------------------------*/
 
28
 
 
29
 
 
30
#define T1BASE_C
 
31
 
 
32
 
 
33
#include <stdio.h>
 
34
#include <sys/types.h>
 
35
#include <sys/stat.h>
 
36
#include <fcntl.h>
 
37
#if defined(_MSC_VER)
 
38
# include <io.h>
 
39
# include <sys/types.h>
 
40
# include <sys/stat.h>
 
41
#else
 
42
# include <unistd.h>
 
43
#endif
 
44
#include <stdlib.h>
 
45
#include <math.h>
 
46
#include <time.h>
 
47
#include <string.h>
 
48
#include <ctype.h>
 
49
#include <stdarg.h>
 
50
 
 
51
#include "../type1/ffilest.h" 
 
52
#include "../type1/types.h"
 
53
#include "parseAFM.h" 
 
54
#include "../type1/objects.h"
 
55
#include "../type1/spaces.h"
 
56
#include "../type1/util.h"
 
57
#include "../type1/fontfcn.h"
 
58
#include "../type1/regions.h"
 
59
 
 
60
 
 
61
#include "sysconf.h"
 
62
#include "t1base.h"
 
63
#include "t1types.h"
 
64
#include "t1global.h"
 
65
#include "t1env.h"
 
66
#include "t1delete.h"
 
67
 
 
68
 
 
69
static int T1_pad=0;
 
70
 
 
71
 
 
72
/* This function is to be called by the user to initialize
 
73
   the font mechanism */
 
74
void *T1_InitLib( int log)
 
75
{
 
76
  int result;
 
77
  int i;
 
78
  
 
79
  char *usershome=NULL;
 
80
  char *logfilepath=NULL;
 
81
  char *envlogreq=NULL;
 
82
  int  usrforcelog=0;
 
83
  
 
84
  
 
85
  
 
86
  /* Reset T1_errno */
 
87
  T1_errno=0;
 
88
  
 
89
  /* Assign pointer to global struct and set entry padding: */
 
90
  pFontBase=&FontBase;
 
91
  if (T1_pad)
 
92
    pFontBase->bitmap_pad=T1_pad;
 
93
  else
 
94
    pFontBase->bitmap_pad=T1GLYPH_PAD;
 
95
 
 
96
  pFontBase->pFontArray = NULL;
 
97
  pFontBase->t1lib_flags=0;
 
98
  /* Check for AA-caching */
 
99
  if ((log & T1_AA_CACHING)){
 
100
    pFontBase->t1lib_flags |= T1_AA_CACHING;
 
101
  }
 
102
  /* Check for AFM disable */
 
103
  if ((log & T1_NO_AFM)) {
 
104
    pFontBase->t1lib_flags |= T1_NO_AFM;
 
105
  }
 
106
 
 
107
  /* Check environment variable ENV_LOG_STRING. By this means, a user may
 
108
     generate a log file even if at compile time log file creation has
 
109
     been suppressed. Of course, if the loglevel is reduced after
 
110
     initialization by the programmer, this environment variable takes
 
111
     no effect! */
 
112
  if ((envlogreq=getenv(ENV_LOG_STRING))!=NULL) {
 
113
    if (strcmp( envlogreq, "logDebug")==0)
 
114
      T1_SetLogLevel( T1LOG_DEBUG);
 
115
    else if (strcmp( envlogreq, "logStatistic")==0)
 
116
      T1_SetLogLevel( T1LOG_STATISTIC);
 
117
    else if (strcmp( envlogreq, "logWarning")==0)
 
118
      T1_SetLogLevel( T1LOG_WARNING);
 
119
    else if (strcmp( envlogreq, "logError")==0)
 
120
      T1_SetLogLevel( T1LOG_ERROR);
 
121
    usrforcelog=1;
 
122
  }
 
123
  
 
124
  /* Open log-file: */
 
125
  t1lib_log_file=NULL;
 
126
  if ((log & LOGFILE) || (usrforcelog!=0)) {
 
127
    pFontBase->t1lib_flags |= LOGFILE;
 
128
    /* Try first opening in current directory: */
 
129
    if ((t1lib_log_file=fopen( T1_LOG_FILE, "w"))==NULL) {
 
130
      if ((usershome=getenv("HOME"))!=NULL) {
 
131
        logfilepath=(char *)malloc((strlen(usershome) +
 
132
                                    strlen(T1_LOG_FILE) + 2
 
133
                                    ) * sizeof(char));
 
134
        strcpy( logfilepath, usershome);
 
135
        strcat( logfilepath, DIRECTORY_SEP);
 
136
        strcat( logfilepath, T1_LOG_FILE);
 
137
        if ((t1lib_log_file=fopen( logfilepath, "w"))==NULL){
 
138
          t1lib_log_file=stderr;
 
139
        }
 
140
        free( logfilepath);
 
141
      }
 
142
      else {
 
143
        t1lib_log_file=stderr;
 
144
      }
 
145
    }
 
146
    if (t1lib_log_file==stderr) {
 
147
      T1_PrintLog( "T1_InitLib()", "Unable to open a logfile, using stderr",
 
148
                   T1LOG_ERROR);
 
149
    }
 
150
  }
 
151
  
 
152
  T1_PrintLog( "T1_InitLib()", "Initialization started",
 
153
               T1LOG_STATISTIC);
 
154
  /* Check for representation of data in memory: */
 
155
  if ((pFontBase->endian=T1_CheckEndian())){
 
156
    T1_PrintLog( "T1_InitLib()", "Using Big Endian data presentation (MSBFirst)",
 
157
                 T1LOG_DEBUG);
 
158
    pFontBase->endian=1;
 
159
  }
 
160
  else{
 
161
    T1_PrintLog( "T1_InitLib()", "Using Little Endian data presentation (LSBFirst)",
 
162
                 T1LOG_DEBUG);
 
163
    pFontBase->endian=0;
 
164
  }
 
165
 
 
166
  /* Save version identifier */
 
167
  sprintf( err_warn_msg_buf, "Version Identifier: %s", T1LIB_IDENT);
 
168
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf,
 
169
               T1LOG_DEBUG);
 
170
  /* Save how t1lib is initialized */
 
171
  sprintf( err_warn_msg_buf, "Initialization flags: 0x%X", log);
 
172
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf,
 
173
               T1LOG_DEBUG);
 
174
  /* Save padding value in log file */
 
175
  sprintf( err_warn_msg_buf, "Glyphs are padded to %d bits",
 
176
           pFontBase->bitmap_pad);
 
177
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf,
 
178
               T1LOG_DEBUG);
 
179
#ifdef __CHAR_UNSIGNED__
 
180
  T1_PrintLog( "T1_InitLib()", "System-Info: char is unsigned",
 
181
               T1LOG_DEBUG);
 
182
#else
 
183
  T1_PrintLog( "T1_InitLib()", "System-Info: char is signed",
 
184
               T1LOG_DEBUG);
 
185
#endif
 
186
  sprintf( err_warn_msg_buf, "System-Info: sizeof(char):         %d",
 
187
           SIZEOF_CHAR);
 
188
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
 
189
  sprintf( err_warn_msg_buf, "System-Info: sizeof(short):        %d",
 
190
           SIZEOF_SHORT);
 
191
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
 
192
  sprintf( err_warn_msg_buf, "System-Info: sizeof(int):          %d",
 
193
           SIZEOF_INT);
 
194
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
 
195
  sprintf( err_warn_msg_buf, "System-Info: sizeof(long):         %d",
 
196
           SIZEOF_LONG);
 
197
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
 
198
  sprintf( err_warn_msg_buf, "System-Info: sizeof(long long):    %d",
 
199
           SIZEOF_LONG_LONG);
 
200
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
 
201
  sprintf( err_warn_msg_buf, "System-Info: sizeof(float):        %d",
 
202
           SIZEOF_FLOAT);
 
203
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
 
204
  sprintf( err_warn_msg_buf, "System-Info: sizeof(double):       %d",
 
205
           SIZEOF_DOUBLE);
 
206
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
 
207
  sprintf( err_warn_msg_buf, "System-Info: sizeof(long double):  %d",
 
208
           SIZEOF_LONG_DOUBLE);
 
209
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
 
210
  sprintf( err_warn_msg_buf, "System-Info: sizeof(void *):       %d",
 
211
           SIZEOF_VOID_P);
 
212
  T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
 
213
  
 
214
  intT1_SetupDefaultSearchPaths();
 
215
  if (log & IGNORE_CONFIGFILE) {
 
216
    pFontBase->t1lib_flags |= IGNORE_CONFIGFILE;
 
217
    T1_PrintLog( "T1_InitLib()", "Skipping configuration file search!",
 
218
                 T1LOG_STATISTIC);
 
219
  }
 
220
  else {
 
221
    if ((result=intT1_ScanConfigFile())==0)
 
222
      T1_PrintLog( "T1_InitLib()", "Warning t1lib configuration file not found!",
 
223
                   T1LOG_WARNING);
 
224
  }
 
225
  
 
226
 
 
227
  /* Set the default encoding to the fonts' internal encoding */
 
228
  pFontBase->default_enc=NULL;
 
229
  
 
230
  /* Initialize the no_fonts... values */
 
231
  pFontBase->no_fonts=0;
 
232
  pFontBase->no_fonts_ini=pFontBase->no_fonts;
 
233
  pFontBase->no_fonts_limit=pFontBase->no_fonts;
 
234
 
 
235
  
 
236
  /* Check whether to read font database */
 
237
  if ((log & IGNORE_FONTDATABASE)){
 
238
    pFontBase->t1lib_flags |= IGNORE_FONTDATABASE;
 
239
 
 
240
    T1_Up=1;         /* System has been initialized ! */
 
241
    T1_PrintLog( "T1_InitLib()", "Initialization successfully finished (Database empty)",
 
242
                 T1LOG_STATISTIC);
 
243
    
 
244
    return((void *) pFontBase);
 
245
  }
 
246
 
 
247
  result=0;
 
248
  /* Read fontdatabase(s) */
 
249
  i=0;
 
250
  while (T1_FDB_ptr[i]!=NULL) {
 
251
    if ((result=intT1_scanFontDBase(T1_FDB_ptr[i]))==-1){
 
252
      T1_PrintLog( "T1_InitLib()", "Fatal error scanning Font Database File %s",
 
253
                   T1LOG_WARNING, T1_FDB_ptr[i]);
 
254
    }
 
255
    if (result>-1)
 
256
      pFontBase->no_fonts+=result;
 
257
    i++;
 
258
    
 
259
  }
 
260
  if (result == 0){
 
261
    T1_PrintLog( "T1_InitLib()", "No fonts from Font Database File(s) found (T1_errno=%d)",
 
262
                 T1LOG_ERROR, T1_errno);
 
263
    return(NULL);
 
264
  }
 
265
 
 
266
  /* Initialize the no_fonts... values */
 
267
  pFontBase->no_fonts_ini=pFontBase->no_fonts;
 
268
  pFontBase->no_fonts_limit=pFontBase->no_fonts;
 
269
 
 
270
  T1_Up=1;         /* System has been initialized ! */
 
271
  T1_PrintLog( "T1_InitLib()", "Initialization successfully finished",
 
272
             T1LOG_STATISTIC);
 
273
 
 
274
  return((void *) pFontBase);
 
275
}
 
276
 
 
277
 
 
278
 
 
279
/* intT1_scanFontDBase():
 
280
   - opens the file with the font definitions,
 
281
   - reads the number of fonts defined and saves this in FontBase,
 
282
   - allocates memory for all the filenames of the Type1 files
 
283
   - tests for .pfa und .pfb files and saves the name found
 
284
   - initializes an array that allows to acces these names by an
 
285
     index number, the font_ID
 
286
   - returns -1 on fatal error and the number of fonts located
 
287
     successfullly
 
288
   */
 
289
int intT1_scanFontDBase( char *filename)
 
290
{
 
291
  int fd;
 
292
  int filesize, i, j, k, m;
 
293
  int found=0, located=0;
 
294
  char *filebuffer;
 
295
  int nofonts=0;
 
296
  FONTPRIVATE* fontarrayP=NULL;
 
297
  
 
298
  
 
299
  if ((fd=open( filename, O_RDONLY))<3){
 
300
    T1_PrintLog( "intT1_scanFontDBase()", "Font Database File %s not found!",
 
301
                 T1LOG_WARNING, filename);
 
302
    T1_errno=T1ERR_FILE_OPEN_ERR;
 
303
    return(-1);
 
304
  }
 
305
 
 
306
  /* Get the file size */
 
307
  filesize=lseek( fd, 0, 2);
 
308
  /* Reset fileposition to start */
 
309
  lseek (fd, 0, 0); 
 
310
 
 
311
  if ((filebuffer=(char *)malloc(filesize*sizeof(char)
 
312
                                 )) == NULL){
 
313
    T1_PrintLog(  "intT1_scanFontDBase()",
 
314
                  "Couldn't allocate memory for loading font database file %s",
 
315
                  T1LOG_ERROR, filename);
 
316
    T1_errno=T1ERR_ALLOC_MEM;
 
317
    return(-1);
 
318
  }
 
319
  
 
320
  i=read( fd, filebuffer, filesize);
 
321
  close(fd);   /* Close font database file */
 
322
   
 
323
  i=j=m=0;
 
324
  
 
325
  while (i<filesize) {
 
326
    if (filebuffer[i]=='\n'){ /* We are at the end of line */
 
327
      if (j==0) {  /* Read the first line as the number of fonts */
 
328
        filebuffer[i]=0;
 
329
        sscanf( &filebuffer[0], "%d", &nofonts);
 
330
        filebuffer[i]='\n';  /* Because it gives a better feeling */
 
331
        /* (Re)Allocate memory for 'no_fonts' structures: */ 
 
332
        if ((FontBase.pFontArray=(FONTPRIVATE *)
 
333
             realloc( FontBase.pFontArray, (FontBase.no_fonts+nofonts)*sizeof(FONTPRIVATE))) == NULL) {
 
334
          T1_PrintLog( "inT1_scanFontDBase()",
 
335
                       "Failed to allocate memory for FONTPRIVATE-area while scanning %s",
 
336
                       T1LOG_ERROR, filename);
 
337
          T1_errno=T1ERR_ALLOC_MEM;
 
338
          return(-1);
 
339
        }
 
340
        /* setup pointer to newly allocated area and do a reset */
 
341
        fontarrayP=&(FontBase.pFontArray[FontBase.no_fonts]);
 
342
        memset(fontarrayP, 0, nofonts*sizeof(FONTPRIVATE));
 
343
        located=1; /* In  order to increment m */
 
344
      }
 
345
      else {       /* We are in the second or higher line */
 
346
        k=i;
 
347
        while (isspace((int)filebuffer[k])){
 
348
          k--;
 
349
        }
 
350
        /* We are at the last printable character of a line; let's 
 
351
           step back (over the [afm/sfm]) to the period and replace it
 
352
           by an ASCII 0 */
 
353
        while ((filebuffer[k]!='.') && (!isspace((int)filebuffer[k])) ){
 
354
          k--;
 
355
        }
 
356
        if (filebuffer[k]=='.'){ /* We have a name terminated with . */
 
357
          filebuffer[k]=0; /* termination for string reading */
 
358
          while (!isspace((int)filebuffer[k])){
 
359
            k--;
 
360
          }
 
361
        }
 
362
        else { /* The filename was without . and / or the first on the line */ 
 
363
          ;
 
364
        }
 
365
        sscanf( &(filebuffer[k+1]), "%s", &(linebuf[0]));
 
366
        /* We print error string before testing because after the call
 
367
           to test_for_t1_file() filename is substituted by an emty
 
368
           string if the file was not found: */
 
369
        sprintf( err_warn_msg_buf, "Type 1 Font file %s.[pfa/pfb] not found (FontID=%d, SearchPath=%s)",
 
370
                 linebuf, m-1, T1_GetFileSearchPath(T1_PFAB_PATH));
 
371
        if ((test_for_t1_file( &linebuf[0]))){
 
372
          T1_PrintLog( "intT1_scanFontDBase()", err_warn_msg_buf, T1LOG_WARNING);
 
373
          located=0;
 
374
        }
 
375
        else{
 
376
          /* linebuf contains now the valid Type1 filename; let's
 
377
             now copy this string into the appropriate place in the
 
378
             FONTPRIVATE-struct: */
 
379
          found++;
 
380
          located=1;
 
381
          if ((fontarrayP[m-1].pFontFileName=(char *)
 
382
               calloc( strlen( &linebuf[0])+1, sizeof(char))) == NULL){
 
383
            T1_PrintLog( "intT1_scanFontDBase()",
 
384
                         "Failed to allocate memory for Filename %s (FontID=%d)",
 
385
                         T1LOG_ERROR, &linebuf[0], m-1);
 
386
            T1_errno=T1ERR_ALLOC_MEM;
 
387
            return(-1);
 
388
          }
 
389
          strcpy( fontarrayP[m-1].pFontFileName, &linebuf[0]);
 
390
        }
 
391
      }
 
392
      j++; /* Advance line counter */
 
393
      if ((located))
 
394
        m++;
 
395
    }
 
396
    if (j>nofonts) /* to ignore especially white space at end */
 
397
      break;
 
398
    i++;   /* Step further in file position */
 
399
  }
 
400
  /* Return the memory for file reading */
 
401
  free(filebuffer); 
 
402
  
 
403
  return( found);
 
404
}
 
405
 
 
406
 
 
407
/* T1_CloseLib(): Close the library and free all associated memory */
 
408
int T1_CloseLib( void)
 
409
{
 
410
 
 
411
  int i, j, error=0;
 
412
 
 
413
  if (T1_Up){
 
414
    for (i=pFontBase->no_fonts; i; i--){
 
415
      /* Free filename only if not NULL and if the font is physical!
 
416
         Do it before removing the font since the physical information
 
417
         is no more available afterwards. If necessary, an explicitly
 
418
         specified AFM filename is also freed.
 
419
         */
 
420
      if ((pFontBase->pFontArray[i-1].pFontFileName!=NULL)
 
421
          && (pFontBase->pFontArray[i-1].physical==1)){
 
422
        free( pFontBase->pFontArray[i-1].pFontFileName);
 
423
        pFontBase->pFontArray[i-1].pFontFileName=NULL;
 
424
        if (pFontBase->pFontArray[i-1].pAfmFileName!=NULL){
 
425
          free( pFontBase->pFontArray[i-1].pAfmFileName);
 
426
          pFontBase->pFontArray[i-1].pAfmFileName=NULL;
 
427
        }
 
428
      }
 
429
      
 
430
      /* Now, remove font: */
 
431
      if ((j=T1_DeleteFont( i-1))){
 
432
        error=1;
 
433
        sprintf( err_warn_msg_buf, "T1_DeleteFont() returned %d for Font %d",
 
434
                 j, i-1);
 
435
        T1_PrintLog( "T1_CloseLib()", err_warn_msg_buf, T1LOG_ERROR);
 
436
      }
 
437
    }
 
438
    /* Free the FONTPRIVATE area */
 
439
    if (pFontBase->pFontArray)
 
440
      free( pFontBase->pFontArray);
 
441
    else
 
442
      error=1;
 
443
 
 
444
    /* Free search paths */
 
445
    intT1_FreeSearchPaths();
 
446
 
 
447
    /* Reset the flags */
 
448
    pFontBase->t1lib_flags=0;
 
449
    
 
450
    /* Indicate Library is no longer initialized */
 
451
    pFontBase=NULL;
 
452
    T1_Up=0;
 
453
    T1_PrintLog( "T1_CloseLib()", "Library closed", T1LOG_STATISTIC);
 
454
    if ((t1lib_log_file!=NULL) && (t1lib_log_file!=stderr))
 
455
      fclose(t1lib_log_file);
 
456
    t1lib_log_file=NULL;
 
457
  }
 
458
  
 
459
  return( error);
 
460
}
 
461
 
 
462
 
 
463
/* T1_AddFont(): Add a new fontfile to the fontdatabase.
 
464
   Return values: >0: Assigned FontID
 
465
                  -1: Fontfile not found
 
466
                  -2: Error allocating memory for FONTPRIVATE-area
 
467
                  -3: No memory for saving font filename
 
468
                  */
 
469
int T1_AddFont( char *fontfilename)
 
470
{
 
471
  
 
472
  char *FullName;
 
473
  FONTPRIVATE *save_ptr;
 
474
  int i;
 
475
  int new_ID;
 
476
  
 
477
  
 
478
  if (fontfilename==NULL){
 
479
    T1_errno=T1ERR_INVALID_PARAMETER;
 
480
    return(-1);
 
481
  }
 
482
  
 
483
  /* Check for existence of fontfile */
 
484
  if ((FullName=intT1_Env_GetCompletePath(fontfilename,T1_PFAB_ptr))==NULL) {
 
485
    T1_errno=T1ERR_FILE_OPEN_ERR;
 
486
    return(-1);
 
487
  }
 
488
  free(FullName);
 
489
 
 
490
  /* Check if free space for a new FONTPRIVATE is available; if not,
 
491
     realloc memory some amount larger */
 
492
  save_ptr=pFontBase->pFontArray;
 
493
  if (pFontBase->no_fonts==pFontBase->no_fonts_limit){
 
494
    if (pFontBase->pFontArray == NULL) {
 
495
      /* In case this is the first font */
 
496
      pFontBase->pFontArray=(FONTPRIVATE *)calloc(pFontBase->no_fonts_limit 
 
497
                                                  + ADVANCE_FONTPRIVATE,
 
498
                                                  sizeof(FONTPRIVATE));
 
499
    }
 
500
    else {
 
501
      /* We already have some fonts */
 
502
      pFontBase->pFontArray=(FONTPRIVATE *)realloc(pFontBase->pFontArray,
 
503
                                                   (pFontBase->no_fonts_limit
 
504
                                                    + ADVANCE_FONTPRIVATE)
 
505
                                                   * sizeof(FONTPRIVATE));
 
506
      if (pFontBase->pFontArray==NULL){
 
507
        /* Restore pointer */
 
508
        pFontBase->pFontArray=save_ptr;
 
509
        T1_errno=T1ERR_ALLOC_MEM;
 
510
        return(-2); /* No memory available */
 
511
      }
 
512
    }
 
513
    pFontBase->no_fonts_limit += ADVANCE_FONTPRIVATE;
 
514
    /* First, initialize newly allocated to be not used */
 
515
    for ( i=pFontBase->no_fonts;
 
516
          i<pFontBase->no_fonts+ADVANCE_FONTPRIVATE; i++){
 
517
      pFontBase->pFontArray[i].pFontFileName=NULL;
 
518
      pFontBase->pFontArray[i].pAfmFileName=NULL;
 
519
      pFontBase->pFontArray[i].pAFMData=NULL;
 
520
      pFontBase->pFontArray[i].pType1Data=NULL;
 
521
      pFontBase->pFontArray[i].pEncMap=NULL;
 
522
      pFontBase->pFontArray[i].pKernMap=NULL;
 
523
      pFontBase->pFontArray[i].pFontEnc=NULL;
 
524
      pFontBase->pFontArray[i].pFontSizeDeps=NULL;
 
525
      pFontBase->pFontArray[i].vm_base=NULL;
 
526
      pFontBase->pFontArray[i].FontMatrix[0]=0.0;
 
527
      pFontBase->pFontArray[i].FontMatrix[1]=0.0;
 
528
      pFontBase->pFontArray[i].FontMatrix[2]=0.0;
 
529
      pFontBase->pFontArray[i].FontMatrix[3]=0.0;
 
530
      pFontBase->pFontArray[i].FontTransform[0]=0.0;
 
531
      pFontBase->pFontArray[i].FontTransform[1]=0.0;
 
532
      pFontBase->pFontArray[i].FontTransform[2]=0.0;
 
533
      pFontBase->pFontArray[i].FontTransform[3]=0.0;
 
534
      pFontBase->pFontArray[i].slant=0.0;
 
535
      pFontBase->pFontArray[i].extend=0.0;
 
536
      pFontBase->pFontArray[i].physical=0;
 
537
      pFontBase->pFontArray[i].refcount=0; 
 
538
      pFontBase->pFontArray[i].space_position=0; 
 
539
      pFontBase->pFontArray[i].info_flags=0; 
 
540
    }
 
541
  }
 
542
  /* no_fonts-1 was the largest allowed font ID */
 
543
  new_ID=pFontBase->no_fonts;
 
544
  pFontBase->no_fonts++;
 
545
 
 
546
  if ((FontBase.pFontArray[new_ID].pFontFileName=(char *)
 
547
       calloc( strlen( fontfilename)+1, sizeof(char))) == NULL){
 
548
    T1_PrintLog( "T1_AddFont()",
 
549
                 "Failed to allocate memory for Filename %s (FontID=%d)",
 
550
                 T1LOG_ERROR, fontfilename, new_ID);
 
551
    T1_errno=T1ERR_ALLOC_MEM;
 
552
    return(-3);
 
553
  }
 
554
  strcpy( FontBase.pFontArray[new_ID].pFontFileName, fontfilename);
 
555
 
 
556
  /* Generate logfile entry */
 
557
  sprintf( err_warn_msg_buf, "Assigned FontID %d to fontfile %s",
 
558
           new_ID, FontBase.pFontArray[new_ID].pFontFileName);
 
559
  T1_PrintLog( "T1_AddFont()", err_warn_msg_buf,
 
560
               T1LOG_STATISTIC);
 
561
  /* Return FontID of newly declared font */
 
562
  return( new_ID);
 
563
  
 
564
}
 
565
 
 
566
 
 
567
/* T1_PrintLog() generates entries in the log file. msg_txt is subject to scan
 
568
   conversion and ... signifies a accordingly lrge variable list. */
 
569
void T1_PrintLog( char *func_ident, char *msg_txt, int level, ...)
 
570
{
 
571
  va_list vararg;
 
572
  static char levelid[4]={ 'E', 'W', 'S', 'D'};
 
573
  time_t s_clock, *tp;
 
574
  
 
575
  if (t1lib_log_file==NULL)
 
576
    return;
 
577
  if ((level>t1lib_log_level) || (level<1)){
 
578
    return;
 
579
  }
 
580
  else{
 
581
    /* initialize argument list */
 
582
    va_start( vararg, level);
 
583
    
 
584
    tp=&s_clock;
 
585
    s_clock=time( tp);
 
586
    /*
 
587
    fprintf( t1lib_log_file, "(%c) (%.24s) %s: ",
 
588
             levelid[level-1], ctime(&s_clock), func_ident);
 
589
             */
 
590
    /* Don't print the time stamp */
 
591
    fprintf( t1lib_log_file, "(%c) %s: ", levelid[level-1], func_ident );
 
592
    vfprintf( t1lib_log_file, msg_txt, vararg );
 
593
    fprintf( t1lib_log_file, "\n");
 
594
    fflush( t1lib_log_file);
 
595
 
 
596
    /* cleanup variable list */
 
597
    va_end( vararg);
 
598
    
 
599
    return;
 
600
  }
 
601
}
 
602
 
 
603
 
 
604
/* T1_SetLogLevel(): Set the level which a message must have so
 
605
   that it is printed into the logfile. This function may be called
 
606
   before T1_InitLib(). */
 
607
void T1_SetLogLevel( int level)
 
608
{
 
609
  if ((level>0) && (level<5))
 
610
    t1lib_log_level=level;
 
611
  return;
 
612
}
 
613
 
 
614
 
 
615
 
 
616
/* CheckForInit(): If no initialization of font mechanism has been
 
617
   done, return -1, indicating an error. */
 
618
int CheckForInit(void)
 
619
{
 
620
  if(T1_Up)
 
621
    return(0);
 
622
  else
 
623
    return(-1);
 
624
  
 
625
}
 
626
 
 
627
 
 
628
 
 
629
/* CheckForFontID(): Checks the font mechanism concerning the specified
 
630
   ID. It returns:
 
631
                   0  if font belonging to FontID has not yet been loaded
 
632
                   1  if font belonging to FontID has already been loaded
 
633
                   -1 if FontID is an invalid specification or t1lib not
 
634
                      initialized
 
635
                   */
 
636
int CheckForFontID( int FontID)
 
637
{
 
638
 
 
639
  /* FontID is invalid */
 
640
  if ((FontID<0)||(FontID>(pFontBase->no_fonts - 1))||(T1_Up==0))
 
641
    return(-1);
 
642
  
 
643
  if (pFontBase->pFontArray[FontID].pType1Data==NULL)
 
644
    return(0);     /* has not yet been loaded */
 
645
  else
 
646
    return(1);     /* has already been loaded */
 
647
}
 
648
 
 
649
 
 
650
 
 
651
 
 
652
/* test_for_t1_file returns 0 if a file "name.pfa" or "name.pfb"
 
653
   was found. Else, -1 is returned. If successful, buffer contains the
 
654
   found filename string */
 
655
int test_for_t1_file( char *buffer )
 
656
{
 
657
  int i=0;
 
658
  char *FullName;
 
659
  
 
660
  /* First case: A PostScript Font ASCII File without extension
 
661
     (according to some UNIX-conventions) */
 
662
  if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) {
 
663
    free(FullName);
 
664
    return(0);
 
665
  }
 
666
 
 
667
  while (buffer[i]!=0){
 
668
    i++;
 
669
  }
 
670
  buffer[i]='.';
 
671
  buffer[i+1]='p';
 
672
  buffer[i+2]='f';
 
673
  buffer[i+4]=0;
 
674
 
 
675
  
 
676
  /* Second case: A PostScript Font ASCII File */
 
677
  buffer[i+3]='a';
 
678
  if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) {
 
679
    free(FullName);
 
680
    return(0);
 
681
  }
 
682
  /* Third case: A PostScript Font Binary File */
 
683
  buffer[i+3]='b';
 
684
  if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) {
 
685
    free(FullName);
 
686
    return(0);
 
687
  }
 
688
  
 
689
  /* If we get here no file was found => Set buffer
 
690
     to an empty string and return -1 */
 
691
  
 
692
  buffer[0]=0;
 
693
  return(-1);
 
694
}
 
695
 
 
696
 
 
697
/* T1_GetFontFileName() returns a pointer to the filename of the font,
 
698
   associated with FontID. This filename does not contain a full path.
 
699
   */
 
700
char *T1_GetFontFileName( int FontID)
 
701
{
 
702
 
 
703
  static char filename[MAXPATHLEN+1];
 
704
  
 
705
  if (CheckForInit())return(NULL);
 
706
 
 
707
  /* Check first for valid FontID */
 
708
  if ((FontID<0) || (FontID>FontBase.no_fonts)){
 
709
    T1_errno=T1ERR_INVALID_FONTID;
 
710
    return(NULL);
 
711
  }
 
712
  
 
713
  strcpy( filename, pFontBase->pFontArray[FontID].pFontFileName);
 
714
  
 
715
  return( filename);
 
716
  
 
717
}
 
718
 
 
719
 
 
720
 
 
721
/* As suggested by Nicolai Langfeldt, we make it possible to specify
 
722
   a completely independent path for the afm filename. This should
 
723
   make t1lib usable in context with using the kpathsearch-library.
 
724
   We allow setting those pathļæ½s after initialization, but before a
 
725
   font is loaded.
 
726
   returns  0:   OK
 
727
           -1:   Operation could not be performed
 
728
*/
 
729
int T1_SetAfmFileName( int FontID, char *afm_name)
 
730
{
 
731
 
 
732
  if (CheckForFontID(FontID)!=0){
 
733
    /* Operation may not be applied because FontID is invalid
 
734
       or font is loaded */
 
735
    T1_errno=T1ERR_INVALID_FONTID;
 
736
    return(-1);
 
737
  }
 
738
  if (afm_name==NULL) {
 
739
    T1_errno=T1ERR_INVALID_PARAMETER;
 
740
    return(-1);
 
741
  }
 
742
  if (pFontBase->pFontArray[FontID].pAfmFileName!=NULL){
 
743
    /* we first free the current name */
 
744
    free( pFontBase->pFontArray[FontID].pAfmFileName);
 
745
    pFontBase->pFontArray[FontID].pAfmFileName=NULL;
 
746
  }
 
747
  
 
748
  if ((pFontBase->pFontArray[FontID].pAfmFileName=
 
749
       (char *)malloc( (strlen(afm_name)+1)*sizeof( char)))==NULL) {
 
750
    T1_errno=T1ERR_ALLOC_MEM;
 
751
    return( -1);
 
752
  }
 
753
  strcpy( pFontBase->pFontArray[FontID].pAfmFileName, afm_name);
 
754
          
 
755
  return(0);
 
756
  
 
757
}
 
758
 
 
759
                  
 
760
 
 
761
/* We have a function for querying the name. Returns a pointer
 
762
   to the string or NULL if name was not explicitly set .*/
 
763
char *T1_GetAfmFileName( int FontID)
 
764
{
 
765
 
 
766
  static char filename[MAXPATHLEN+1];
 
767
  
 
768
  if (CheckForInit())return(NULL);
 
769
 
 
770
  /* Check first for valid FontID */
 
771
  if ((FontID<0) || (FontID>FontBase.no_fonts)){
 
772
    T1_errno=T1ERR_INVALID_FONTID;
 
773
    return(NULL);
 
774
  }
 
775
 
 
776
  if (pFontBase->pFontArray[FontID].pAfmFileName==NULL) {
 
777
    return( NULL);
 
778
  }
 
779
  
 
780
  strcpy( filename, pFontBase->pFontArray[FontID].pAfmFileName);
 
781
  return( filename);
 
782
  
 
783
}
 
784
 
 
785
 
 
786
  
 
787
/* T1_Get_no_fonts(): Return the number of declared fonts */
 
788
int  T1_Get_no_fonts(void)
 
789
{
 
790
  if (CheckForInit())return(-1);
 
791
  return(FontBase.no_fonts);
 
792
}
 
793
 
 
794
        
 
795
 
 
796
/* T1_SetDeviceResolutions( x_res, y_res): Set the device's physical
 
797
   resolution in horizontal and vertical direction, mesured in DPI
 
798
   (Dots Per Inch). This should be done before the first font is
 
799
   loaded! */
 
800
int T1_SetDeviceResolutions( float x_res, float y_res)
 
801
{
 
802
 
 
803
  int i;
 
804
  
 
805
  if (CheckForInit())
 
806
    ;   /* Not initialized -> no size dependent data -> OK */
 
807
  else
 
808
    /* Check if size-dependent data is existent */
 
809
    for ( i=T1_Get_no_fonts(); i; i--)
 
810
      if (pFontBase->pFontArray[i-1].pFontSizeDeps!=NULL){
 
811
        T1_errno=T1ERR_OP_NOT_PERMITTED;
 
812
        return(-1); /* There's is size dependent data for a font */
 
813
      }
 
814
  
 
815
  /* Save resolutions and calculate horizontal and vertical
 
816
     scale factors to map desired bp to device pixel */
 
817
  DeviceSpecifics.x_resolution=(float) x_res;
 
818
  DeviceSpecifics.y_resolution=(float) y_res;
 
819
  DeviceSpecifics.scale_x=(float)(((float)x_res)/BIGPOINTSPERINCH);
 
820
  DeviceSpecifics.scale_y=(float)(((float)y_res)/BIGPOINTSPERINCH);
 
821
  return(0);
 
822
}
 
823
 
 
824
 
 
825
/* T1_QueryX11Support(): Check at runtime to see if t1lib was compiled
 
826
   with X11 interface: */
 
827
int T1_QueryX11Support( void)
 
828
{
 
829
#ifndef T1LIB_NO_X11_SUPPORT
 
830
  return(1);
 
831
#else
 
832
  return(0);
 
833
#endif
 
834
}
 
835
 
 
836
 
 
837
 
 
838
 
 
839
/* int T1_CopyFont(): Copies the font associated with FontID to another
 
840
   location. The pointers to type1- , afm- and encoding data as well as
 
841
   the matrices remain completely untouched. However, size dependent data
 
842
   is not copied. The produced font is marked as a "logical" font.
 
843
   If no memory is available in the FONTPRIVATE-array, there's realloc'ed
 
844
   some more memory. The FontID which is assigned to the newly generated
 
845
   font is given as the return value, or < 0 if an error occurs. Also,
 
846
   the refcount entry of the source font is incremented by one.
 
847
 
 
848
   Return value -1: invalid FontID specified
 
849
                -2: source font is not a "physical" font
 
850
                -3: no memory for reallocation of FONTPRIVATEs
 
851
                -4: no memory for one of the mapping tables
 
852
                */
 
853
int T1_CopyFont( int FontID)
 
854
{
 
855
  FONTPRIVATE *save_ptr;
 
856
  int k;
 
857
  int new_ID;
 
858
  
 
859
  
 
860
  /* Check for a valid source font */
 
861
  if (CheckForFontID(FontID)!=1){
 
862
    T1_errno=T1ERR_INVALID_FONTID;
 
863
    return(-1);
 
864
  }
 
865
 
 
866
 
 
867
  /* Check if the font in question is a "physical" font, otherwise it may
 
868
     not be copied */
 
869
  if (pFontBase->pFontArray[FontID].physical==0){
 
870
    T1_errno=T1ERR_OP_NOT_PERMITTED;
 
871
    return(-2);
 
872
  }
 
873
  
 
874
  
 
875
  /* Check if free space for a new FONTPRIVATE is available; if not,
 
876
     realloc memory some amount larger */
 
877
  save_ptr=pFontBase->pFontArray;
 
878
  if (pFontBase->no_fonts==pFontBase->no_fonts_limit){
 
879
    pFontBase->pFontArray=(FONTPRIVATE *)realloc(pFontBase->pFontArray,
 
880
                                                 (pFontBase->no_fonts_limit
 
881
                                                  + ADVANCE_FONTPRIVATE)
 
882
                                                 * sizeof(FONTPRIVATE));
 
883
    if (pFontBase->pFontArray==NULL){
 
884
      /* Restore pointer */
 
885
      pFontBase->pFontArray=save_ptr;
 
886
      T1_errno=T1ERR_ALLOC_MEM;
 
887
      return(-3);
 
888
    }
 
889
    /* We zero the newly allocated memory */
 
890
    if (pFontBase->pFontArray != NULL) {
 
891
      memset( pFontBase->pFontArray + pFontBase->no_fonts_limit, 0,
 
892
              ADVANCE_FONTPRIVATE * sizeof(FONTPRIVATE));
 
893
    }
 
894
    pFontBase->no_fonts_limit += ADVANCE_FONTPRIVATE;
 
895
  }
 
896
  /* no_fonts-1 was the largest allowed font ID */
 
897
  new_ID=pFontBase->no_fonts;
 
898
  /* Copy FONTPRIVATE-structure: */
 
899
  pFontBase->pFontArray[new_ID]=pFontBase->pFontArray[FontID];
 
900
  /* (Re)Set some values explicitly, others remain untouched: */  
 
901
  pFontBase->pFontArray[new_ID].pFontSizeDeps=NULL;
 
902
  pFontBase->pFontArray[new_ID].physical=0;
 
903
  /* AFM-mapping tables are to be setup for logical fonts separately
 
904
   (if AFM data is there) */
 
905
  /* first, kerning map */
 
906
  if (pFontBase->pFontArray[new_ID].pAFMData) {
 
907
    k=pFontBase->pFontArray[new_ID].pAFMData->numOfPairs;
 
908
    if (k>0){ /* kern map exists only if kerning pairs exist! */
 
909
      if ((pFontBase->pFontArray[new_ID].pKernMap=
 
910
           (METRICS_ENTRY *)malloc( k*sizeof( METRICS_ENTRY)))==NULL){
 
911
        sprintf( err_warn_msg_buf, "Error allocating memory for kerning map (new_ID=%d)",
 
912
                 new_ID);
 
913
        T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf,
 
914
                     T1LOG_WARNING);
 
915
        T1_errno=T1ERR_ALLOC_MEM;
 
916
        return(-4);
 
917
      }
 
918
      memcpy( pFontBase->pFontArray[new_ID].pKernMap,
 
919
              pFontBase->pFontArray[FontID].pKernMap,
 
920
              k*sizeof( METRICS_ENTRY));
 
921
    } 
 
922
    else { /* no kerning pairs, bu AFM data present */
 
923
      pFontBase->pFontArray[new_ID].pKernMap=NULL;
 
924
    }
 
925
  } 
 
926
  else { /* AFM data not present at all */
 
927
    pFontBase->pFontArray[new_ID].pKernMap=NULL;
 
928
  }
 
929
 
 
930
  /* second, encoding map */
 
931
  if (pFontBase->pFontArray[FontID].pEncMap!=NULL) {
 
932
    if ((pFontBase->pFontArray[new_ID].pEncMap=
 
933
         (int *)calloc(256,sizeof(int)))==NULL){
 
934
      sprintf( err_warn_msg_buf,
 
935
               "Error allocating memory for encoding map (new_ID=%d)",
 
936
               new_ID);
 
937
      T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf,
 
938
                   T1LOG_WARNING);
 
939
      T1_errno=T1ERR_ALLOC_MEM;
 
940
      return(-4);
 
941
    }
 
942
    memcpy( pFontBase->pFontArray[new_ID].pEncMap,
 
943
            pFontBase->pFontArray[FontID].pEncMap,
 
944
            256*sizeof( int));
 
945
  }
 
946
  
 
947
  /* New font is logical --> indicate to which physical font it
 
948
     refers by setting refcount: */
 
949
  pFontBase->pFontArray[new_ID].refcount=FontID;
 
950
  
 
951
  /* Now the struct is setup; increment no_fonts by 1 because
 
952
     new_ID is a valid font specification from now on. */
 
953
  pFontBase->no_fonts++;
 
954
  /* Increment refcount in source font */
 
955
  pFontBase->pFontArray[FontID].refcount++;
 
956
 
 
957
  /* Generate logfile entry */
 
958
  sprintf( err_warn_msg_buf, "Assigned FontID %d to fontfile %s",
 
959
           new_ID, FontBase.pFontArray[new_ID].pFontFileName);
 
960
  T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf,
 
961
               T1LOG_STATISTIC);
 
962
  return(new_ID);
 
963
}
 
964
 
 
965
 
 
966
 
 
967
/* T1_SetBitmapPad(): Set the value to which bitmap-scanlines are padded.
 
968
   This has to be done before initialization because it is a very
 
969
   rudimentary operation.
 
970
   */
 
971
int T1_SetBitmapPad( int pad)
 
972
{
 
973
  if (T1_Up){
 
974
    /* Library is initialized --> return error */
 
975
    T1_errno=T1ERR_OP_NOT_PERMITTED;
 
976
    return(-1);
 
977
  }
 
978
  else{
 
979
    switch (pad){
 
980
    case 8: 
 
981
      T1_pad=8;
 
982
      return(0);
 
983
    case 16:
 
984
      T1_pad=16;
 
985
      return(0);
 
986
#ifdef T1_AA_TYPE64
 
987
    case 32:
 
988
      T1_pad=32;
 
989
      return(0);
 
990
#endif
 
991
    default:
 
992
      T1_errno=T1ERR_INVALID_PARAMETER;
 
993
      return(-1);
 
994
    }
 
995
  }
 
996
}
 
997
 
 
998
 
 
999
 
 
1000
/* T1_GetBitmapPad(): Read the value to which scanlines of bitmap are
 
1001
   padded. This can be done before or after initialization. */
 
1002
int T1_GetBitmapPad( void)
 
1003
{
 
1004
  if (pFontBase) /* T1lib initialized --> return value from struct */
 
1005
    return( pFontBase->bitmap_pad);
 
1006
  else{
 
1007
    if (T1_pad) 
 
1008
      return(T1_pad);  /* pad is explicitly set --> return that value */
 
1009
    else
 
1010
      return( T1GLYPH_PAD); /* not expl. set --> return compilation default */
 
1011
  }
 
1012
}
 
1013
 
 
1014
 
 
1015
 
 
1016
/* bin_dump(): Print a binary dump of a byte, short and
 
1017
   long variable (used for debug purposes only): */
 
1018
void bin_dump_c(unsigned char value, char space_flag)
 
1019
{
 
1020
  int i,j;
 
1021
  
 
1022
  for (i=0;i<=7;i++){
 
1023
    if ((j=((value)>>i)&0x01))
 
1024
      printf("X");
 
1025
    else
 
1026
      printf(".");
 
1027
  }
 
1028
  if (space_flag)
 
1029
    printf(" ");
 
1030
 
 
1031
}
 
1032
 
 
1033
void bin_dump_s(unsigned short value, char space_flag)
 
1034
{
 
1035
  int i,j;
 
1036
 
 
1037
  if (T1_CheckEndian()){
 
1038
    for (i=8;i<=15;i++){
 
1039
      if ((j=((value)>>i)&0x01))
 
1040
        printf("X");
 
1041
      else
 
1042
        printf(".");
 
1043
    }
 
1044
    for (i=0;i<=7;i++){
 
1045
      if ((j=((value)>>i)&0x01))
 
1046
        printf("X");
 
1047
      else
 
1048
        printf(".");
 
1049
    }
 
1050
  }
 
1051
  else{
 
1052
    for (i=0;i<=15;i++){
 
1053
      if ((j=((value)>>i)&0x01))
 
1054
        printf("X");
 
1055
      else
 
1056
        printf(".");
 
1057
    }
 
1058
  }
 
1059
  if (space_flag)
 
1060
    printf(" ");
 
1061
  
 
1062
}
 
1063
 
 
1064
void bin_dump_l(unsigned long value, char space_flag)
 
1065
{
 
1066
  int i,j;
 
1067
  
 
1068
  if (T1_CheckEndian()){
 
1069
    for (i=24;i<=31;i++){
 
1070
      if ((j=((value)>>i)&0x01))
 
1071
        printf("X");
 
1072
      else
 
1073
        printf(".");
 
1074
    }
 
1075
    for (i=16;i<=23;i++){
 
1076
      if ((j=((value)>>i)&0x01))
 
1077
        printf("X");
 
1078
      else
 
1079
        printf(".");
 
1080
    }
 
1081
    for (i=8;i<=15;i++){
 
1082
      if ((j=((value)>>i)&0x01))
 
1083
        printf("X");
 
1084
      else
 
1085
        printf(".");
 
1086
    }
 
1087
    for (i=0;i<=7;i++){
 
1088
      if ((j=((value)>>i)&0x01))
 
1089
        printf("X");
 
1090
      else
 
1091
        printf(".");
 
1092
    }
 
1093
  }
 
1094
  else{
 
1095
    for (i=0;i<=31;i++){
 
1096
      if ((j=((value)>>i)&0x01))
 
1097
        printf("X");
 
1098
      else
 
1099
        printf(".");
 
1100
    }
 
1101
  }
 
1102
  if (space_flag)
 
1103
    printf(" ");
 
1104
 
 
1105
}
 
1106
 
 
1107
 
 
1108
 
 
1109
/* CheckEndian(): Checks whether the current machine is of little or big
 
1110
   endian architecture. This is important for concatenating bitmaps.
 
1111
   Function returns 0 if LittleEndian and 1 if BigEndian representation
 
1112
   is used  on the current hardware.
 
1113
   */
 
1114
int T1_CheckEndian()
 
1115
{
 
1116
  unsigned char *charptr;
 
1117
 
 
1118
  /* Generate test value */
 
1119
  unsigned short test=0x0001;
 
1120
 
 
1121
  /* Read out memory as unsigned char */
 
1122
  charptr=(unsigned char *)(&test)+1;
 
1123
 
 
1124
  /* Return value will be 1 if Big- and 0 if Little Endian */
 
1125
  return((int) *charptr);
 
1126
  
 
1127
}
 
1128
 
 
1129
 
 
1130
 
 
1131
/* T1_GetLibIdent(): Return the identifier string for the current version
 
1132
   of t1lib */
 
1133
char *T1_GetLibIdent( void)
 
1134
{
 
1135
  static char buf[15];
 
1136
 
 
1137
  sprintf( buf, "%s", T1LIB_IDENT);
 
1138
  
 
1139
  return( (char *)buf);
 
1140
}
 
1141
 
 
1142
 
 
1143
 
 
1144
/* T1_SetRasterFlags(): Enable/Disable certain features in
 
1145
   the rasterizer */
 
1146
extern void T1_SetRasterFlags( int flags)
 
1147
 
1148
  
 
1149
  T1_Type1OperatorFlags=flags;
 
1150
  return;
 
1151
  
 
1152
}
 
1153
 
 
1154
 
 
1155
 
 
1156
/* T1_GetFontFileName(): returns a pointer to the complete path filename
 
1157
   of the font, associated with FontID as it is in use by t1lib.
 
1158
   */
 
1159
char *T1_GetFontFilePath( int FontID)
 
1160
{
 
1161
 
 
1162
  static char filepath[MAXPATHLEN+1];
 
1163
  char *FileNamePath=NULL;
 
1164
  
 
1165
  /* is initialzed? */
 
1166
  if (CheckForInit()) {
 
1167
    T1_errno=T1ERR_INVALID_FONTID;
 
1168
    return(NULL);
 
1169
  }
 
1170
  
 
1171
  /* Check first for valid FontID */
 
1172
  if ((FontID<0) || (FontID>FontBase.no_fonts)){
 
1173
    T1_errno=T1ERR_INVALID_FONTID;
 
1174
    return(NULL);
 
1175
  }
 
1176
 
 
1177
  /* lib is initialized and FontID is valid ->
 
1178
     we can really expect a name */
 
1179
  if ((FileNamePath=intT1_Env_GetCompletePath( pFontBase->pFontArray[FontID].pFontFileName, 
 
1180
                                               T1_PFAB_ptr))==NULL) { 
 
1181
    T1_PrintLog( "T1_GetFontFilePath()", "Couldn't locate font file for font %d in %s", 
 
1182
                 T1LOG_WARNING, FontID, T1_GetFileSearchPath(T1_PFAB_PATH)); 
 
1183
    T1_errno=T1ERR_FILE_OPEN_ERR; 
 
1184
    return(NULL); 
 
1185
  } 
 
1186
  
 
1187
  strcpy( filepath, FileNamePath);
 
1188
  free( FileNamePath);
 
1189
  
 
1190
  return( filepath);
 
1191
  
 
1192
}
 
1193
 
 
1194
 
 
1195
 
 
1196
/* We have a function for querying the name. Returns a pointer
 
1197
   to the string or NULL if name was not explicitly set .*/
 
1198
char *T1_GetAfmFilePath( int FontID)
 
1199
{
 
1200
  
 
1201
  static char filepath[MAXPATHLEN+1];
 
1202
  char *FontFileName;
 
1203
  char *AFMFilePath;
 
1204
  int i, j;
 
1205
  
 
1206
  /* is initialized? */
 
1207
  if ((CheckForInit())) {
 
1208
    T1_errno=T1ERR_INVALID_FONTID;
 
1209
    return(NULL);
 
1210
  }
 
1211
  
 
1212
  /* Check first for valid FontID */
 
1213
  if ((FontID<0) || (FontID>FontBase.no_fonts)){
 
1214
    T1_errno=T1ERR_INVALID_FONTID;
 
1215
    return(NULL);
 
1216
  }
 
1217
 
 
1218
  /* Check wether AFM-file loading was suppressed on user's request */
 
1219
  if ((pFontBase->t1lib_flags & T1_NO_AFM)!=0) {
 
1220
    /* this is no error condition, we simply return (NULL) */
 
1221
    return( NULL);
 
1222
  }
 
1223
  
 
1224
  /* Check for explicitly associated metrics filename (via
 
1225
     "T1_SetAfmFileName()"). If it exists, we return it! */
 
1226
  if (pFontBase->pFontArray[FontID].pAfmFileName!=NULL) {
 
1227
    strcpy( filepath, pFontBase->pFontArray[FontID].pAfmFileName);
 
1228
    sprintf( err_warn_msg_buf, "Returning explicitly specified path %s for Font %d",
 
1229
             filepath, FontID);
 
1230
    T1_PrintLog( "T1_GetAfmFilePath()", err_warn_msg_buf, T1LOG_DEBUG);
 
1231
    return( filepath);
 
1232
  }
 
1233
  
 
1234
  /* we have the usual case that the name of the metrics file has to be
 
1235
     deduced from the font file name */
 
1236
  FontFileName=T1_GetFontFileName( FontID);
 
1237
  i=strlen(FontFileName);
 
1238
  j=i;
 
1239
  strcpy( filepath, FontFileName);
 
1240
  while ( filepath[i] != '.'){
 
1241
    if (i==0) break;
 
1242
    else i--;
 
1243
  }
 
1244
  if (i==0){
 
1245
    /* We have a filename without extension -> append extension */
 
1246
    filepath[j]='.';
 
1247
    filepath[j+1]='a'; 
 
1248
    filepath[j+2]='f'; 
 
1249
    filepath[j+3]='m'; 
 
1250
    filepath[j+4]='\0'; 
 
1251
  }
 
1252
  else{
 
1253
    /* we found a '.' -> replace extension */
 
1254
    filepath[i+1]='a';
 
1255
    filepath[i+2]='f';
 
1256
    filepath[i+3]='m';
 
1257
    filepath[i+4]='\0';
 
1258
  }
 
1259
  /* Get full path of the afm file (The case of a full path name
 
1260
     name specification is valid */
 
1261
  AFMFilePath=intT1_Env_GetCompletePath( filepath, T1_AFM_ptr);
 
1262
  strcpy( filepath, AFMFilePath);
 
1263
  free( AFMFilePath);
 
1264
  
 
1265
  return( filepath);
 
1266
  
 
1267
}