1
/*--------------------------------------------------------------------------
3
----- Author: Rainer Menzner (Rainer.Menzner@web.de)
5
----- Description: This file is part of the t1-library. It contains basic
6
routines to initialize the data structures used
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
16
The parseAFM-package is copyrighted by Adobe Systems
18
The type1 rasterizer is copyrighted by IBM and the
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
26
Thanks to all people who make free software living!
27
--------------------------------------------------------------------------*/
34
#include <sys/types.h>
39
# include <sys/types.h>
40
# include <sys/stat.h>
51
#include "../type1/ffilest.h"
52
#include "../type1/types.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"
72
/* This function is to be called by the user to initialize
74
void *T1_InitLib( int log)
80
char *logfilepath=NULL;
89
/* Assign pointer to global struct and set entry padding: */
92
pFontBase->bitmap_pad=T1_pad;
94
pFontBase->bitmap_pad=T1GLYPH_PAD;
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;
102
/* Check for AFM disable */
103
if ((log & T1_NO_AFM)) {
104
pFontBase->t1lib_flags |= T1_NO_AFM;
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
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);
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
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;
143
t1lib_log_file=stderr;
146
if (t1lib_log_file==stderr) {
147
T1_PrintLog( "T1_InitLib()", "Unable to open a logfile, using stderr",
152
T1_PrintLog( "T1_InitLib()", "Initialization started",
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)",
161
T1_PrintLog( "T1_InitLib()", "Using Little Endian data presentation (LSBFirst)",
166
/* Save version identifier */
167
sprintf( err_warn_msg_buf, "Version Identifier: %s", T1LIB_IDENT);
168
T1_PrintLog( "T1_InitLib()", err_warn_msg_buf,
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,
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,
179
#ifdef __CHAR_UNSIGNED__
180
T1_PrintLog( "T1_InitLib()", "System-Info: char is unsigned",
183
T1_PrintLog( "T1_InitLib()", "System-Info: char is signed",
186
sprintf( err_warn_msg_buf, "System-Info: sizeof(char): %d",
188
T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
189
sprintf( err_warn_msg_buf, "System-Info: sizeof(short): %d",
191
T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
192
sprintf( err_warn_msg_buf, "System-Info: sizeof(int): %d",
194
T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
195
sprintf( err_warn_msg_buf, "System-Info: sizeof(long): %d",
197
T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
198
sprintf( err_warn_msg_buf, "System-Info: sizeof(long long): %d",
200
T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
201
sprintf( err_warn_msg_buf, "System-Info: sizeof(float): %d",
203
T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
204
sprintf( err_warn_msg_buf, "System-Info: sizeof(double): %d",
206
T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
207
sprintf( err_warn_msg_buf, "System-Info: sizeof(long double): %d",
209
T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
210
sprintf( err_warn_msg_buf, "System-Info: sizeof(void *): %d",
212
T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG);
214
intT1_SetupDefaultSearchPaths();
215
if (log & IGNORE_CONFIGFILE) {
216
pFontBase->t1lib_flags |= IGNORE_CONFIGFILE;
217
T1_PrintLog( "T1_InitLib()", "Skipping configuration file search!",
221
if ((result=intT1_ScanConfigFile())==0)
222
T1_PrintLog( "T1_InitLib()", "Warning t1lib configuration file not found!",
227
/* Set the default encoding to the fonts' internal encoding */
228
pFontBase->default_enc=NULL;
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;
236
/* Check whether to read font database */
237
if ((log & IGNORE_FONTDATABASE)){
238
pFontBase->t1lib_flags |= IGNORE_FONTDATABASE;
240
T1_Up=1; /* System has been initialized ! */
241
T1_PrintLog( "T1_InitLib()", "Initialization successfully finished (Database empty)",
244
return((void *) pFontBase);
248
/* Read fontdatabase(s) */
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]);
256
pFontBase->no_fonts+=result;
261
T1_PrintLog( "T1_InitLib()", "No fonts from Font Database File(s) found (T1_errno=%d)",
262
T1LOG_ERROR, T1_errno);
266
/* Initialize the no_fonts... values */
267
pFontBase->no_fonts_ini=pFontBase->no_fonts;
268
pFontBase->no_fonts_limit=pFontBase->no_fonts;
270
T1_Up=1; /* System has been initialized ! */
271
T1_PrintLog( "T1_InitLib()", "Initialization successfully finished",
274
return((void *) pFontBase);
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
289
int intT1_scanFontDBase( char *filename)
292
int filesize, i, j, k, m;
293
int found=0, located=0;
296
FONTPRIVATE* fontarrayP=NULL;
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;
306
/* Get the file size */
307
filesize=lseek( fd, 0, 2);
308
/* Reset fileposition to start */
311
if ((filebuffer=(char *)malloc(filesize*sizeof(char)
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;
320
i=read( fd, filebuffer, filesize);
321
close(fd); /* Close font database file */
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 */
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;
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 */
345
else { /* We are in the second or higher line */
347
while (isspace((int)filebuffer[k])){
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
353
while ((filebuffer[k]!='.') && (!isspace((int)filebuffer[k])) ){
356
if (filebuffer[k]=='.'){ /* We have a name terminated with . */
357
filebuffer[k]=0; /* termination for string reading */
358
while (!isspace((int)filebuffer[k])){
362
else { /* The filename was without . and / or the first on the line */
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);
376
/* linebuf contains now the valid Type1 filename; let's
377
now copy this string into the appropriate place in the
378
FONTPRIVATE-struct: */
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;
389
strcpy( fontarrayP[m-1].pFontFileName, &linebuf[0]);
392
j++; /* Advance line counter */
396
if (j>nofonts) /* to ignore especially white space at end */
398
i++; /* Step further in file position */
400
/* Return the memory for file reading */
407
/* T1_CloseLib(): Close the library and free all associated memory */
408
int T1_CloseLib( void)
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.
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;
430
/* Now, remove font: */
431
if ((j=T1_DeleteFont( i-1))){
433
sprintf( err_warn_msg_buf, "T1_DeleteFont() returned %d for Font %d",
435
T1_PrintLog( "T1_CloseLib()", err_warn_msg_buf, T1LOG_ERROR);
438
/* Free the FONTPRIVATE area */
439
if (pFontBase->pFontArray)
440
free( pFontBase->pFontArray);
444
/* Free search paths */
445
intT1_FreeSearchPaths();
447
/* Reset the flags */
448
pFontBase->t1lib_flags=0;
450
/* Indicate Library is no longer initialized */
453
T1_PrintLog( "T1_CloseLib()", "Library closed", T1LOG_STATISTIC);
454
if ((t1lib_log_file!=NULL) && (t1lib_log_file!=stderr))
455
fclose(t1lib_log_file);
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
469
int T1_AddFont( char *fontfilename)
473
FONTPRIVATE *save_ptr;
478
if (fontfilename==NULL){
479
T1_errno=T1ERR_INVALID_PARAMETER;
483
/* Check for existence of fontfile */
484
if ((FullName=intT1_Env_GetCompletePath(fontfilename,T1_PFAB_ptr))==NULL) {
485
T1_errno=T1ERR_FILE_OPEN_ERR;
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));
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 */
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;
542
/* no_fonts-1 was the largest allowed font ID */
543
new_ID=pFontBase->no_fonts;
544
pFontBase->no_fonts++;
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;
554
strcpy( FontBase.pFontArray[new_ID].pFontFileName, fontfilename);
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,
561
/* Return FontID of newly declared font */
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, ...)
572
static char levelid[4]={ 'E', 'W', 'S', 'D'};
575
if (t1lib_log_file==NULL)
577
if ((level>t1lib_log_level) || (level<1)){
581
/* initialize argument list */
582
va_start( vararg, level);
587
fprintf( t1lib_log_file, "(%c) (%.24s) %s: ",
588
levelid[level-1], ctime(&s_clock), func_ident);
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);
596
/* cleanup variable list */
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)
609
if ((level>0) && (level<5))
610
t1lib_log_level=level;
616
/* CheckForInit(): If no initialization of font mechanism has been
617
done, return -1, indicating an error. */
618
int CheckForInit(void)
629
/* CheckForFontID(): Checks the font mechanism concerning the specified
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
636
int CheckForFontID( int FontID)
639
/* FontID is invalid */
640
if ((FontID<0)||(FontID>(pFontBase->no_fonts - 1))||(T1_Up==0))
643
if (pFontBase->pFontArray[FontID].pType1Data==NULL)
644
return(0); /* has not yet been loaded */
646
return(1); /* has already been loaded */
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 )
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) {
667
while (buffer[i]!=0){
676
/* Second case: A PostScript Font ASCII File */
678
if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) {
682
/* Third case: A PostScript Font Binary File */
684
if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) {
689
/* If we get here no file was found => Set buffer
690
to an empty string and return -1 */
697
/* T1_GetFontFileName() returns a pointer to the filename of the font,
698
associated with FontID. This filename does not contain a full path.
700
char *T1_GetFontFileName( int FontID)
703
static char filename[MAXPATHLEN+1];
705
if (CheckForInit())return(NULL);
707
/* Check first for valid FontID */
708
if ((FontID<0) || (FontID>FontBase.no_fonts)){
709
T1_errno=T1ERR_INVALID_FONTID;
713
strcpy( filename, pFontBase->pFontArray[FontID].pFontFileName);
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
727
-1: Operation could not be performed
729
int T1_SetAfmFileName( int FontID, char *afm_name)
732
if (CheckForFontID(FontID)!=0){
733
/* Operation may not be applied because FontID is invalid
735
T1_errno=T1ERR_INVALID_FONTID;
738
if (afm_name==NULL) {
739
T1_errno=T1ERR_INVALID_PARAMETER;
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;
748
if ((pFontBase->pFontArray[FontID].pAfmFileName=
749
(char *)malloc( (strlen(afm_name)+1)*sizeof( char)))==NULL) {
750
T1_errno=T1ERR_ALLOC_MEM;
753
strcpy( pFontBase->pFontArray[FontID].pAfmFileName, afm_name);
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)
766
static char filename[MAXPATHLEN+1];
768
if (CheckForInit())return(NULL);
770
/* Check first for valid FontID */
771
if ((FontID<0) || (FontID>FontBase.no_fonts)){
772
T1_errno=T1ERR_INVALID_FONTID;
776
if (pFontBase->pFontArray[FontID].pAfmFileName==NULL) {
780
strcpy( filename, pFontBase->pFontArray[FontID].pAfmFileName);
787
/* T1_Get_no_fonts(): Return the number of declared fonts */
788
int T1_Get_no_fonts(void)
790
if (CheckForInit())return(-1);
791
return(FontBase.no_fonts);
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
800
int T1_SetDeviceResolutions( float x_res, float y_res)
806
; /* Not initialized -> no size dependent data -> OK */
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 */
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);
825
/* T1_QueryX11Support(): Check at runtime to see if t1lib was compiled
826
with X11 interface: */
827
int T1_QueryX11Support( void)
829
#ifndef T1LIB_NO_X11_SUPPORT
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.
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
853
int T1_CopyFont( int FontID)
855
FONTPRIVATE *save_ptr;
860
/* Check for a valid source font */
861
if (CheckForFontID(FontID)!=1){
862
T1_errno=T1ERR_INVALID_FONTID;
867
/* Check if the font in question is a "physical" font, otherwise it may
869
if (pFontBase->pFontArray[FontID].physical==0){
870
T1_errno=T1ERR_OP_NOT_PERMITTED;
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;
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));
894
pFontBase->no_fonts_limit += ADVANCE_FONTPRIVATE;
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)",
913
T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf,
915
T1_errno=T1ERR_ALLOC_MEM;
918
memcpy( pFontBase->pFontArray[new_ID].pKernMap,
919
pFontBase->pFontArray[FontID].pKernMap,
920
k*sizeof( METRICS_ENTRY));
922
else { /* no kerning pairs, bu AFM data present */
923
pFontBase->pFontArray[new_ID].pKernMap=NULL;
926
else { /* AFM data not present at all */
927
pFontBase->pFontArray[new_ID].pKernMap=NULL;
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)",
937
T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf,
939
T1_errno=T1ERR_ALLOC_MEM;
942
memcpy( pFontBase->pFontArray[new_ID].pEncMap,
943
pFontBase->pFontArray[FontID].pEncMap,
947
/* New font is logical --> indicate to which physical font it
948
refers by setting refcount: */
949
pFontBase->pFontArray[new_ID].refcount=FontID;
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++;
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,
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.
971
int T1_SetBitmapPad( int pad)
974
/* Library is initialized --> return error */
975
T1_errno=T1ERR_OP_NOT_PERMITTED;
992
T1_errno=T1ERR_INVALID_PARAMETER;
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)
1004
if (pFontBase) /* T1lib initialized --> return value from struct */
1005
return( pFontBase->bitmap_pad);
1008
return(T1_pad); /* pad is explicitly set --> return that value */
1010
return( T1GLYPH_PAD); /* not expl. set --> return compilation default */
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)
1023
if ((j=((value)>>i)&0x01))
1033
void bin_dump_s(unsigned short value, char space_flag)
1037
if (T1_CheckEndian()){
1038
for (i=8;i<=15;i++){
1039
if ((j=((value)>>i)&0x01))
1045
if ((j=((value)>>i)&0x01))
1052
for (i=0;i<=15;i++){
1053
if ((j=((value)>>i)&0x01))
1064
void bin_dump_l(unsigned long value, char space_flag)
1068
if (T1_CheckEndian()){
1069
for (i=24;i<=31;i++){
1070
if ((j=((value)>>i)&0x01))
1075
for (i=16;i<=23;i++){
1076
if ((j=((value)>>i)&0x01))
1081
for (i=8;i<=15;i++){
1082
if ((j=((value)>>i)&0x01))
1088
if ((j=((value)>>i)&0x01))
1095
for (i=0;i<=31;i++){
1096
if ((j=((value)>>i)&0x01))
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.
1114
int T1_CheckEndian()
1116
unsigned char *charptr;
1118
/* Generate test value */
1119
unsigned short test=0x0001;
1121
/* Read out memory as unsigned char */
1122
charptr=(unsigned char *)(&test)+1;
1124
/* Return value will be 1 if Big- and 0 if Little Endian */
1125
return((int) *charptr);
1131
/* T1_GetLibIdent(): Return the identifier string for the current version
1133
char *T1_GetLibIdent( void)
1135
static char buf[15];
1137
sprintf( buf, "%s", T1LIB_IDENT);
1139
return( (char *)buf);
1144
/* T1_SetRasterFlags(): Enable/Disable certain features in
1146
extern void T1_SetRasterFlags( int flags)
1149
T1_Type1OperatorFlags=flags;
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.
1159
char *T1_GetFontFilePath( int FontID)
1162
static char filepath[MAXPATHLEN+1];
1163
char *FileNamePath=NULL;
1165
/* is initialzed? */
1166
if (CheckForInit()) {
1167
T1_errno=T1ERR_INVALID_FONTID;
1171
/* Check first for valid FontID */
1172
if ((FontID<0) || (FontID>FontBase.no_fonts)){
1173
T1_errno=T1ERR_INVALID_FONTID;
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;
1187
strcpy( filepath, FileNamePath);
1188
free( FileNamePath);
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)
1201
static char filepath[MAXPATHLEN+1];
1206
/* is initialized? */
1207
if ((CheckForInit())) {
1208
T1_errno=T1ERR_INVALID_FONTID;
1212
/* Check first for valid FontID */
1213
if ((FontID<0) || (FontID>FontBase.no_fonts)){
1214
T1_errno=T1ERR_INVALID_FONTID;
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) */
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",
1230
T1_PrintLog( "T1_GetAfmFilePath()", err_warn_msg_buf, T1LOG_DEBUG);
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);
1239
strcpy( filepath, FontFileName);
1240
while ( filepath[i] != '.'){
1245
/* We have a filename without extension -> append extension */
1253
/* we found a '.' -> replace extension */
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);