Revert "dtudcfonted, dtudcexch: delete from repository"
[oweals/cde.git] / cde / programs / dtudcfonted / libfal / falfont.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: falfont.c /main/8 1996/07/04 02:35:37 cde-fuj $ */
24 /*
25  *  (c) Copyright 1995 FUJITSU LIMITED
26  *  This is source code modified by FUJITSU LIMITED under the Joint
27  *  Development Agreement for the CDEnext PST.
28  *  This is unpublished proprietary source code of FUJITSU LIMITED
29  */
30
31
32 #include        <signal.h>
33 #include        <locale.h>
34 #include        <stdio.h>
35 #include        <string.h>
36 #include        <stdlib.h>
37
38 #include        <sys/mman.h>
39 #include        <errno.h>
40
41 #include        <sys/types.h>
42 #include        <sys/stat.h>
43 #include        <fcntl.h>
44 #include        <unistd.h>
45
46 #include        "FaLib.h"
47 #include        "falfont.h"
48 #include        "udcutil.h"
49
50
51 #define MKFONTLIST      (1<<1)
52 #define SRCHFNAME       (1<<2)
53 #define FONTOFID        (1<<3)
54
55 typedef struct _FontIDInfo {
56         FalFontID       fid ;
57         int             cd_set ;
58         int             dspcode ;
59         int             islock ;
60 } FontIDInfo ;
61
62 typedef struct _MngFontID {
63         int             num ;
64         FontIDInfo      **finf ;
65 } MngFontID ;
66
67 /*** structures for UDC fontpath ***/
68 static FalFontPath      orgn = { 0, NULL };     /* for libfal */
69 static FalFontPath      copy = { 0, NULL };     /* report to the user */
70 static FalFontPath      wpath = { 0, NULL };    /* for libfal */
71
72 /***** Variables for notice kind of error *****/
73 int     fal_utyerror;
74 int     fal_utyderror;
75 int     fal_utyexists;
76 unsigned long   fal_utyerrno ;
77 char    fal_err_file[ FAL_LINE_MAX+1 ] ;
78
79 char    fal_err_file_buf[ sizeof(fal_err_file) ] ;
80
81 #define fal_seterrcode( uty, der, errno, func ) { \
82     fal_utyerror  =  (uty); \
83     fal_utyderror =  (der) ; \
84     fal_utyerrno  =  (errno) ; \
85     fal_utyerrno  |= ((func)<<8) ; \
86 }
87
88 /***** flags *****/
89 static  int     execDefined ;
90 static  int     execUndefined ;
91 static  int     IsDefaultPath = FALSE ;
92 static  MngFontID       mngfid = { 0, NULL } ;
93 static  int     tmp_codeset = 0 ;
94 static  char    *fal_locale = NULL ;
95 static  char    *charset_str_buf = NULL ;
96 static  int     *codeset_list_sav = NULL ;
97 static  int     codeset_list_num = 0 ;
98
99 /* declaration of inner functions */
100 char    *fal_get_base_name();
101
102 static  FILE    *open_fonts_list() ;
103 static  int     falGetGlyph() ;
104 static  int     falGetCharIndex() ;
105 static  int     falZoom() ;
106 static  int     exline() ;
107 static  char    falGetMask() ;
108 static  int     chk_key_str() ;
109 static  int     fal_make_fontlist() ;
110 static  int     fal_sort_fontlist() ;
111 static  int     set_default_path() ;
112 static  int     cpy_default_path() ;
113 static  int     comp_default_path() ;
114 static  int     fal_clear_font_path() ;
115 static  int     set_font_pathlist() ;
116
117 static  int     fal_split_data() ;
118 static  int     fal_clear_data() ;
119 static  int     CR_to_NULL() ;
120 static  int     fal_cmp_data() ;
121 static  int     new_target() ;
122
123 int     set_struct() ;
124 int     fal_eq_data() ;
125
126 void    set_errfile_str() ;
127
128 static  int     fal_init() ;
129 static  int     fal_add_fidinf() ;
130 static  int     fal_read_fidinf() ;
131 static  int     fal_del_fidinf() ;
132 static  int     fal_conv_code_to_glyph() ;
133 static  int     fal_conv_glyph_to_code() ;
134 static  int     falReadFontInfoLists() ;
135 static  int     fal_get_def_fontdata() ;
136 static  int     falgetfontlist() ;
137 static  int     fal_get_undef_fontdata() ;
138 static  void    clear_charset_info() ;
139 static  int     make_default_path() ;
140 static  int     file_lock() ;
141 static  int     file_unlock() ;
142 static  int     is_lock() ;
143
144 extern  int     falReadFontProp() ;
145 extern  int     falReadGpfProp() ;
146 extern  int     falInitReadPcfProp() ;
147 extern  int     fal_get_codeset() ;
148 extern  int     falInitReadPcf() ;
149 extern  void    falGetPcfGSize() ;
150 extern  int     falPcfGlyph() ;
151 extern  int     fal_code_to_glyph() ;
152 extern  int     fal_glyph_to_code() ;
153
154
155
156 static int
157 fal_init()
158 {
159     memset( fal_err_file, '\0', sizeof(fal_err_file) ) ;
160     memset( fal_err_file_buf, '\0', sizeof(fal_err_file_buf) ) ;
161
162     if ( !fal_locale ){
163         char    *lcl ;
164         if( (lcl = (char *)getenv( "LANG" )) == NULL ){
165             lcl = "C" ;
166         }
167         if( (fal_locale = (char *)strdup( lcl )) == NULL ){
168             fal_utyerror = _FAL_MALOC_ER;
169             fal_utyderror = 0;
170             fal_utyerrno = FAL_ERR_MALLOC ;
171             return FAL_ERROR;
172         }
173     }
174     return 0 ;
175 }
176
177 void
178 set_errfile_str( obuf, ibuf )
179 char    *obuf ;
180 char    *ibuf ;
181 {
182     char        *sp ;
183
184     if( (strlen(ibuf)+1) > sizeof(fal_err_file) ){
185         sp = ibuf ;
186         sp += ((strlen(ibuf)+1) - sizeof(fal_err_file)) ;
187         strcpy( obuf, sp ) ;
188     }else{
189         strcpy( obuf, ibuf ) ;
190     }
191 }
192
193 /*
194  * open a fontfile by "RDONLY"
195  */
196 FalFontID
197 FalOpenFont( file, protect_key_data, codeset )
198 char    *file;
199 int     protect_key_data;
200 int     codeset;
201 {
202         FalFontID       __FalOpenFont();
203
204         return  __FalOpenFont( file, protect_key_data, codeset, 0 );
205 }
206
207 /*
208  * open a fontfile by "RDWR"
209  *
210  *
211  * lock flag
212  *      1: ON ---  open mode "RDWR"
213  *      0: OFF --  for "FalOpenFont()"
214  */
215 FalFontID
216 __FalOpenFont( file, protect_key_data, codeset, lockflag )
217 char    *file;
218 int     protect_key_data;
219 int     codeset;
220 int     lockflag;
221 {
222         int     fd ;
223         char    *buf;
224         char    *openfontfile;
225         struct  stat st;
226         Oak_FontInf  *finf;
227
228         if ( !(openfontfile = (char *)malloc( strlen( file ) + 1 )) ) {
229             fal_seterrcode( _FAL_MALOC_ER, 0,
230                             FAL_ERR_MALLOC , FAL_FUNCNUM_OPNFNT ) ;
231             return      (FalFontID)FAL_ERROR;
232         }
233         strcpy( openfontfile, file );
234
235         /* read a condition of a fontfile */
236         if ( stat( openfontfile, &st ) < 0 ) {
237                 set_errfile_str( fal_err_file, openfontfile ) ;
238                 free( openfontfile );
239                 fal_utyerror = _FAL_STAT_ER;
240                 fal_utyderror = errno;
241                 fal_utyerrno = FAL_ERR_STAT ;
242                 fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
243                 return  (FalFontID)FAL_ERROR;
244         }
245
246         CHK_PROTECT_KEY( protect_key_data, openfontfile, fal_utyerror, fal_utyderror ) ;
247
248         if ( st.st_size < sizeof( FontInfoRec ) ) {
249                 set_errfile_str( fal_err_file, openfontfile ) ;
250                 free( openfontfile );
251                 fal_utyerror = _FAL_FONT_ER;
252                 fal_utyderror = 0;
253                 fal_utyerrno = FAL_ERR_FONT ;
254                 fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
255                 return  (FalFontID)FAL_ERROR;
256         }
257
258         /* open a fontfile */
259         if ( lockflag == 1 ) {
260                 int     ret ;
261                 if ( (fd = open( openfontfile, O_RDWR )) < 0 ) {
262                     set_errfile_str( fal_err_file, openfontfile ) ;
263                     free( openfontfile );
264                     fal_utyerror = _FAL_OPEN_ER;
265                     fal_utyderror = errno;
266                     fal_utyerrno = FAL_ERR_FNT_OPN ;
267                     fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
268                     return (FalFontID)FAL_ERROR;
269                 }
270                 ret = is_lock( fd ) ;
271                 if( ret != 0 ){
272                     set_errfile_str( fal_err_file, openfontfile ) ;
273                     free( openfontfile );
274                     fal_utyerror = _FAL_OPEN_ER;
275                     fal_utyderror = errno;
276                     fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
277                     close( fd );
278                     return (FalFontID)FAL_ERROR;
279                 }
280         } else {
281                 if ( (fd = open( openfontfile, O_RDONLY)) < 0 ) {
282                     set_errfile_str( fal_err_file, openfontfile ) ;
283                     free( openfontfile );
284                     fal_utyerror = _FAL_OPEN_ER;
285                     fal_utyderror = errno;
286                     fal_utyerrno = FAL_ERR_FNT_OPN ;
287                     fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
288                     return (FalFontID)FAL_ERROR;
289                 }
290         }
291
292         /* read a fontfile */
293         if ( !(finf = ( Oak_FontInf * )malloc(sizeof( Oak_FontInf ) )) ) {
294                 free( openfontfile );
295                 fal_utyerror = _FAL_MALOC_ER;
296                 fal_utyderror = 0;
297                 fal_utyerrno = FAL_ERR_MALLOC ;
298                 fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
299                 close( fd );
300                 return  (FalFontID)FAL_ERROR;
301         }
302
303
304 #if     defined( SVR4 )
305         /* use "mmap()" */
306         buf = (char *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
307         if ( buf != (char *)-1 ) {
308             /* if "mmap" is normal end */
309             if ( lockflag == 0 ) {
310                     close( fd );
311             }
312             finf->ismmap = TRUE;
313             finf->fsize = st.st_size;
314         } else {
315 #endif
316             /* if "mmap" is abnormal end , try "read()" */
317             finf->ismmap = FALSE;
318             if ( !(buf = (char *)malloc(st.st_size)) ) {
319                 free( openfontfile );
320                 fal_utyerror = _FAL_MALOC_ER;
321                 fal_utyderror = 0;
322                 fal_utyerrno = FAL_ERR_MALLOC ;
323                 fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
324                 free( finf );
325                 close( fd );
326                 return  (FalFontID)FAL_ERROR;
327             }
328             if ( read(fd, buf, st.st_size) != st.st_size ) {
329                 set_errfile_str( fal_err_file, openfontfile ) ;
330                 free( openfontfile );
331                 fal_utyerror = _FAL_READ_ER;
332                 fal_utyderror = errno;
333                 fal_utyerrno = FAL_ERR_FNT_RD ;
334                 fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
335                 free( finf );
336                 free( buf );
337                 close( fd );
338                 return  (FalFontID)FAL_ERROR;
339             }
340 #if     defined( SVR4 )
341         }
342 #endif
343
344         if ( !(finf->fname = (char *)strdup( openfontfile )) ) {
345             fal_seterrcode( _FAL_MALOC_ER, 0,
346                             FAL_ERR_MALLOC , FAL_FUNCNUM_OPNFNT ) ;
347             free( openfontfile );
348             free( finf );
349             free( buf );
350             close( fd );
351             return      (FalFontID)FAL_ERROR;
352         }
353
354         /* case of a pcf font */
355         if ( strcmp( FILE_SUFFIX( openfontfile ), PCFSUFFIX ) == 0 ) {
356             if ( falInitReadPcf( &finf->pcfinf, buf ) ) {
357                 fal_utyerror = _FAL_PKEY_ER;
358                 fal_utyderror = 0;
359                 fal_utyerrno = FAL_ERR_FONT ;
360                 fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
361                 goto FalError01 ;
362             }
363             finf->isFef = FALSE;
364             finf->isPcf = TRUE;
365             finf->pFinf = &finf->pcfinf.info;
366         } else {
367             FAL_GET_SNF_HEADER( buf, protect_key_data, fal_utyerror, fal_utyderror, fd, finf, openfontfile ) ;
368         }
369         finf->buf = buf;
370
371         if ( finf->isFef ){
372                 finf->pCinf
373                     = (CharInfoPtr)( (char *)finf->pFinf
374                     + sizeof( FontInfoRec ) );
375                 finf->pGlyphs
376                     = (unsigned char *)((char *)finf->pCinf
377                     + (sizeof(CharInfoRec) * GETNUMCHARS(finf->pFinf)));
378                 finf->width
379                     = finf->pFinf->maxbounds.metrics.rightSideBearing
380                     - finf->pFinf->maxbounds.metrics.leftSideBearing;
381                 finf->height
382                     = finf->pFinf->maxbounds.metrics.ascent
383                     + finf->pFinf->maxbounds.metrics.descent;
384         } else if ( finf->isPcf ) {
385                 finf->pCinf = NULL;
386                 finf->pGlyphs = NULL;
387                 falGetPcfGSize( &finf->pcfinf, &finf->width, &finf->height);
388         } else {
389             fal_utyerror = _FAL_FONT_ER;
390             fal_utyderror = 0;
391             fal_utyerrno = FAL_ERR_FONT ;
392             fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
393             goto FalError01 ;
394         }
395
396         finf->start = (finf->pFinf->firstRow << 8) | finf->pFinf->firstCol;
397         finf->end = (finf->pFinf->lastRow << 8) | finf->pFinf->lastCol;
398
399         finf->fd = fd;
400         finf->sptnBufL = 0;
401         finf->sptnBuf = (char *)0;
402         finf->dptnBufL = 0;
403         finf->dptnBuf = (char *)0;
404         finf->dbufL = 0;
405         finf->dbuf = (char *)0;
406
407         finf->sptnBufL = ((finf->width + 7) / 8) * (finf->height);
408         finf->sptnBuf = (char *)malloc(finf->sptnBufL);
409         if ( finf->sptnBuf == NULL ) {
410             fal_utyerror = _FAL_MALOC_ER;
411             fal_utyderror = 0;
412             fal_utyerrno = FAL_ERR_MALLOC ;
413             fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
414             goto FalError01 ;
415         }
416
417         /* Save font information */
418         if( fal_add_fidinf( (FalFontID)finf, codeset,
419                 ((tmp_codeset)?tmp_codeset:codeset),
420                 lockflag ) == FAL_ERROR )
421         {
422                 fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
423                 goto FalError01 ;
424         }
425
426         /* Lock the font file */
427         if ( lockflag == 1 ) {
428             if ( file_lock( finf->fd ) == FAL_ERROR ) {
429                 set_errfile_str( fal_err_file, openfontfile ) ;
430                 fal_utyerror = _FAL_OPEN_ER;
431                 fal_utyderror = errno;
432                 fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
433                 goto FalError01 ;
434             }
435         }
436         free( openfontfile );
437
438         return( ( FalFontID ) finf );
439
440 FalError01:
441
442 #if     defined( SVR4 )
443         if ( finf->ismmap == TRUE ) {
444             munmap( buf, finf->fsize );
445         } else {
446             free( buf );
447             close( fd );
448         }
449 #else
450         free( buf );
451         close( fd );
452 #endif
453         set_errfile_str( fal_err_file, openfontfile ) ;
454         free( openfontfile );
455         free( finf->fname );
456         finf->fname = NULL;
457         free(finf);
458
459         return  (FalFontID)FAL_ERROR;
460 }
461
462
463
464 #if NeedFunctionPrototypes
465 FalCloseFont(
466         FalFontID       fid )
467 #else
468 FalCloseFont( fid )
469 FalFontID       fid;
470 #endif
471 {
472         int     __FalCloseFont();
473         FontIDInfo      fontid_inf ;
474
475         if( fal_read_fidinf( fid, &fontid_inf ) == FAL_ERROR ) {
476                 fal_utyerrno |= (FAL_FUNCNUM_CLSFNT<<8) ;
477                 return  FAL_ERROR;
478         }
479
480         return  __FalCloseFont( fid, fontid_inf.islock );
481 }
482
483
484 /*
485  * close a fontfile
486  *
487  *
488  * lock flag
489  *      1: ON ---  open a font by "RDWR" mode
490  *      0: OFF --  for "FalOpenFont()"
491  */
492 __FalCloseFont( fid, lockflag )
493 FalFontID       fid;
494 int     lockflag;
495 {
496         Oak_FontInf  *finf;
497
498         finf = ( Oak_FontInf * )fid;
499
500         if ( finf == NULL ) {
501                 fal_utyerror = _FAL_PARM_ER;
502                 fal_utyderror = 0;
503                 fal_utyerrno = FAL_ERR_PARM ;
504                 fal_utyerrno |= (FAL_FUNCNUM_CLSFNT<<8) ;
505                 return  FAL_ERROR;
506         }
507
508         set_errfile_str( fal_err_file_buf, finf->fname ) ;
509         free( finf->fname );
510         if ( finf->buf != NULL ) {
511 #if     defined( SVR4 )
512                 if ( finf->ismmap == TRUE ) {
513                         munmap( finf->buf, finf->fsize );
514                         if ( lockflag == 1 ) {
515                             close( finf->fd );
516                         }
517                 } else {
518                         free( finf->buf );
519                         close( finf->fd );
520                 }
521 #else
522                 free( finf->buf );
523                 close( finf->fd );
524 #endif
525
526                 free( finf->sptnBuf );
527                 free( finf->dptnBuf );
528                 free( finf->dbuf );
529
530                 free ( finf );
531         }
532         if ( lockflag == 1 ) {
533             if ( file_unlock( finf->fd ) == FAL_ERROR ) {
534                 set_errfile_str( fal_err_file, fal_err_file_buf ) ;
535                 fal_utyerrno |= (FAL_FUNCNUM_CLSFNT<<8) ;
536                 return  FAL_ERROR;
537             }
538         }
539
540         if ( fal_del_fidinf( fid ) == FAL_ERROR ) {
541                 fal_utyerrno |= (FAL_FUNCNUM_CLSFNT<<8) ;
542                 return  FAL_ERROR;
543         }
544
545         return  _FAL_OK;
546 }
547
548 #if NeedFunctionPrototypes
549 FalQueryFont(
550         FalFontID       fid,
551         FalFontinfo     *fontinfo )
552 #else
553 FalQueryFont( fid, fontinfo )
554 FalFontID       fid;
555 FalFontinfo     *fontinfo;
556 #endif
557 {
558         Oak_FontInf     *finf;
559         unsigned int    inner_start, inner_end ;
560         FontIDInfo      fontid_inf ;
561
562         if( fal_read_fidinf( fid, &fontid_inf ) == FAL_ERROR ){
563                 fal_utyerrno |= (FAL_FUNCNUM_QRY<<8) ;
564                 return FAL_ERROR;
565         }
566         finf = ( Oak_FontInf * )fid;
567         if ( finf == NULL || fontinfo == NULL ) {
568                 fal_utyerror = _FAL_PARM_ER;
569                 if (finf == NULL) {
570                         fal_utyderror = _FAL_Q_P_FINF_DER;
571                 } else {
572                         fal_utyderror = _FAL_Q_P_FONT_DER;
573                 }
574                 fal_utyerrno = FAL_ERR_PARM ;
575                 fal_utyerrno |= (FAL_FUNCNUM_QRY<<8) ;
576                 return  FAL_ERROR;
577         }
578
579         fontinfo->width  = (int)finf->width;
580         fontinfo->height = (int)finf->height;
581
582         if( (fal_conv_glyph_to_code( finf, fontid_inf.dspcode,
583             fontid_inf.cd_set, finf->start, &inner_start ) == FAL_ERROR ) ||
584             (fal_conv_glyph_to_code( finf, fontid_inf.dspcode,
585             fontid_inf.cd_set, finf->end, &inner_end  ) == FAL_ERROR ))
586         {
587                 fal_utyerrno |= (FAL_FUNCNUM_QRY<<8) ;
588                 return  FAL_ERROR;
589         }
590
591         fontinfo->top    = inner_start ;
592         fontinfo->bottom = inner_end ;
593
594         return  _FAL_OK;
595 }
596
597 #if NeedFunctionPrototypes
598 char    *
599 FalReadFont(
600         FalFontID       fid,
601         int             code,
602         int             width,
603         int             height )
604 #else
605 char    *
606 FalReadFont( fid, code, width, height )
607 FalFontID       fid;
608 int             code ;
609 int             width ;
610 int             height ;
611 #endif
612 {
613         Oak_FontInf     *finf;
614         int     zoom_on ;
615         char    *toglyph;
616         int     ptnBsize;
617         unsigned int    inner_code;     /* an inside code of a file */
618
619         finf = ( Oak_FontInf * )fid;
620
621         if ( finf == NULL ) {
622                 fal_utyerror = _FAL_PARM_ER;
623                 fal_utyderror = _FAL_R_P_FINF_DER;
624                 fal_utyerrno = FAL_ERR_PARM ;
625                 fal_utyerrno |= (FAL_FUNCNUM_RDFNT<<8) ;
626                 return  (char *)FAL_ERROR;
627         }
628         if (width < 0) {
629                 fal_utyerror = _FAL_PARM_ER;
630                 fal_utyderror = _FAL_R_P_W_DER;
631                 fal_utyerrno = FAL_ERR_PARM ;
632                 fal_utyerrno |= (FAL_FUNCNUM_RDFNT<<8) ;
633                 return  (char *)FAL_ERROR;
634         }
635         if (height < 0) {
636                 fal_utyerror = _FAL_PARM_ER;
637                 fal_utyderror = _FAL_R_P_H_DER;
638                 fal_utyerrno = FAL_ERR_PARM ;
639                 fal_utyerrno |= (FAL_FUNCNUM_RDFNT<<8) ;
640                 return  (char *)FAL_ERROR;
641         }
642
643         if (width == 0) {
644                 width = finf->width;
645         }
646         if (height == 0) {
647                 height = finf->height;
648         }
649         if ( (width != finf->width) || (height != finf->height) ) {
650                 zoom_on = TRUE;
651         } else {
652                 zoom_on = FALSE;
653         }
654
655         memset(finf->sptnBuf, 0, finf->sptnBufL);
656
657         if( fal_conv_code_to_glyph( fid, code, &inner_code ) == FAL_ERROR ) {
658                 fal_utyexists = 1;
659                 fal_utyerrno |= (FAL_FUNCNUM_RDFNT<<8) ;
660                 return  (char *)0;
661         }
662
663         if ( finf->isPcf) {
664                 /* case of a pcf font */
665                 falPcfGlyph( finf->sptnBuf, finf, inner_code );
666         } else {
667                 /* case of a snf font */
668                 falGetGlyph( finf->sptnBuf, finf, inner_code );
669         }
670         if ( zoom_on == TRUE ) {
671                 ptnBsize = ((width + 7)/8)*height;
672                 if ( ptnBsize > finf->dptnBufL ) {
673                         if ( finf->dptnBuf == NULL ) {
674                                 toglyph = (char *)malloc( ptnBsize );
675                         } else {
676                                 toglyph = (char *)realloc( finf->dptnBuf, ptnBsize );
677                         }
678                         if ( toglyph == NULL ) {
679                                 fal_utyerror = _FAL_MALOC_ER;
680                                 fal_utyderror = 0;
681                                 fal_utyerrno = FAL_ERR_MALLOC ;
682                                 fal_utyerrno |= (FAL_FUNCNUM_RDFNT<<8) ;
683                                 return  (char *)FAL_ERROR;
684                         }
685                         finf->dptnBufL = ptnBsize;
686                         finf->dptnBuf = toglyph;
687                 }
688                 ptnBsize = (width + 7) / 8;
689                 if ( ptnBsize > finf->dbufL ) {
690                         if ( finf->dbuf == NULL ) {
691                                 toglyph = (char *)malloc( ptnBsize );
692                         } else {
693                                 toglyph = (char *)realloc( finf->dbuf, ptnBsize );
694                         }
695                         if ( toglyph == NULL ) {
696                                 fal_utyerror = _FAL_MALOC_ER;
697                                 fal_utyderror = 0;
698                                 fal_utyerrno = FAL_ERR_MALLOC ;
699                                 fal_utyerrno |= (FAL_FUNCNUM_RDFNT<<8) ;
700                                 return  (char *)FAL_ERROR;
701                         }
702                         finf->dbufL = ptnBsize;
703                         finf->dbuf = toglyph;
704                 }
705                 falZoom(
706                     finf->dptnBuf, finf->sptnBuf,
707                     finf->width, finf->height, width, height, finf->dbuf
708                     );
709                 return( finf->dptnBuf );
710         } else {
711                 return  finf->sptnBuf;
712         }
713 }
714
715 static
716 falGetGlyph( glyph, finf, code )
717 char    *glyph;
718 Oak_FontInf     *finf;
719 int     code;
720 {
721         int     in_dwidth, out_dwidth, ix, i, j;
722         char    *glyph_p, *inp, p_mask, falGetMask();
723         CharInfoPtr     CharInfP;
724         int     codeRow, codeCol;
725         unsigned int    inner_code;             /* an inside code of a file */
726
727         inner_code = code;
728         codeCol = inner_code & 0xff;    /* a lower byte of an inside code */
729         codeRow = (inner_code >> 8) & 0xff; /* a upper byte of a code */
730
731         /* code check */
732         if (
733             ((code < finf->start) || (code > finf->end)) ||
734             ((codeCol < finf->pFinf->firstCol) ||
735             (codeCol > finf->pFinf->lastCol)) ||
736             ((codeRow < finf->pFinf->firstRow) ||
737             (codeRow > finf->pFinf->lastRow))
738             ) {
739                 fal_utyexists = 1;
740                 return  0;
741         }
742
743         /* Get a character index */
744         ix = falGetCharIndex( finf, inner_code );
745         CharInfP = finf->pCinf;
746
747         if ( !CharInfP[ix].exists ) {
748                 fal_utyexists = 1;
749                 return  0;
750         } else {
751                 fal_utyexists = 0;
752         }
753
754         in_dwidth
755             = (finf->width + SNF_BOUND - 1)
756             / SNF_BOUND * (SNF_BOUND / 8);
757         out_dwidth = (finf->width + 7) / 8;
758
759         p_mask = falGetMask( finf->width );
760
761         glyph_p = (char *)finf->pGlyphs + CharInfP[ix].byteOffset;
762         for ( i = 0; i < finf->height; i++ ) {
763                 inp = glyph_p + ( in_dwidth * i );
764                 for ( j = 0; j < out_dwidth-1; j++ ) {
765                         *glyph++ = *inp++;
766                 }
767                 *glyph++ = *inp++ & p_mask;
768         }
769         return  0;
770 }
771
772 static
773 falGetCharIndex( finf, code )
774 Oak_FontInf     *finf;
775 int     code;   /* an inside code of a file */
776 {
777         int     nColperRow, nRow, nCol;
778
779         nColperRow = finf->pFinf->lastCol  - finf->pFinf->firstCol + 1;
780         nRow = ((code >> 8) & 0xff) - finf->pFinf->firstRow;
781         nCol = (code & 0xff) - finf->pFinf->firstCol;
782
783         return  ( nRow * nColperRow + nCol );
784 }
785
786 static
787 falZoom( dmem, smem, sw, sh, dw, dh, dbuf )
788 char    *dmem;
789 char    *smem;
790 int     sw;
791 int     sh;
792 int     dw;
793 int     dh;
794 char    *dbuf;
795 {
796         int     swidth;
797         int     dwidth;
798         int     i, lcnt;
799         char    *sp, *dp;
800
801         swidth = (sw + 7) / 8;
802         dwidth = (dw + 7) / 8;
803
804         lcnt = 0;
805         sp = smem;
806         dp = dmem;
807         for ( i=0; i < sh; i++ ) {
808                 lcnt += dh;
809                 if ( lcnt >= sh ) {
810                         exline( sp, dbuf, sw, dw );
811                         sp += swidth;
812                         lcnt -= sh;
813                         memcpy( dp, dbuf, dwidth );
814                         dp += dwidth;
815                         for ( ; lcnt >= sh; lcnt -= sh ) {
816                                 memcpy( dp, dbuf, dwidth );
817                                 dp += dwidth;
818                         }
819                 } else {
820                         sp += swidth;
821                 }
822         }
823         return  0;
824 }
825
826 static
827 exline( sp, dbuf, sw, dw )
828 char    *sp;
829 char    *dbuf;
830 int     sw;
831 int     dw;
832 {
833         int     i, bit, sval, dval, dcnt, bcnt;
834
835         bcnt = dval = 0;
836         dcnt = 8;
837
838         for ( i = 0; i < sw; i++ ) {
839                 if ( i % 8 == 0 ) {
840                         sval = *sp++;
841                 }
842                 bit = ( (sval & 0x80) ? 1 : 0 );
843                 sval <<=  1;
844                 for ( bcnt += dw; bcnt >= sw; bcnt -= sw ) {
845                         dval = ( dval << 1 ) | bit;
846                         if ( --dcnt == 0 ) {
847                                 *dbuf++ = (char)dval;
848                                 dval = 0;
849                                 dcnt = 8;
850                         }
851                 }
852         }
853         if ( dcnt != 8 ) {
854                 dval <<= dcnt;
855                 *dbuf = (char)dval;
856         }
857         return  0;
858 }
859
860 static unsigned char    _Fal_Mask_Tab[8] = {
861         0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe
862 };
863
864 static char
865 falGetMask( width )
866 int     width;
867 {
868         int     ix = width % 8;
869         return  _Fal_Mask_Tab[ix];
870 }
871
872
873 /* a difinition of a style */
874 static FalFontDB fal_db_style[] = {
875         { FAL_FONT_MINCHO,      FAL_FONT_STR_MINCHO },
876         { FAL_FONT_GOTHIC,      FAL_FONT_STR_GOTHIC },
877         { FAL_FONT_MARU_GOTHIC, FAL_FONT_STR_MARU_GOTHIC },
878         { FAL_FONT_TEXTBOOK,    FAL_FONT_STR_TEXTBOOK },
879         { FAL_FONT_BRASH_GYOU,  FAL_FONT_STR_BRASH_GYOU },
880         { FAL_FONT_BRASH_KAI,   FAL_FONT_STR_BRASH_KAI },
881         { FAL_FONT_HANDWRITING, FAL_FONT_STR_HANDWRITING },
882         { FAL_FONT_UNKNOWN,     ""}
883 };
884
885 /* a difinition of a shape */
886 static FalFontDB fal_db_shape[] = {
887         { FAL_FONT_ZENKAKU,     FAL_FONT_STR_ZENKAKU },
888         { FAL_FONT_HANKAKU,     FAL_FONT_STR_HANKAKU },
889         { FAL_FONT_QUARTER,     FAL_FONT_STR_QUARTER },
890         { FAL_FONT_UNKNOWN,     ""}
891 };
892
893 FAL_DB_OPTION ;
894
895 /*********************************************************/
896 /* make a font information list and carry to user      */
897 /*********************************************************/
898
899 #if NeedFunctionPrototypes
900 int
901 FalGetFontList(
902         FalFontData *key_data,
903         int mask,
904         FalFontDataList **list_ret )
905 #else
906 int
907 FalGetFontList( key_data, mask, list_ret )
908 FalFontData     *key_data;      /* a structure of a searching information */
909 int             mask;           /* a mask */
910 FalFontDataList **list_ret;     /* maked a address of a structure */
911 #endif
912 {
913
914         FalFontDataList *fls;   /* a pointer of a structure of "FalFontDataList()" */
915
916         /* clear an error's data */
917         fal_utyerror  = 0;
918         fal_utyderror = 0;
919         fal_utyerrno = 0 ;
920
921         /* change mode */
922         SET_EXECDEFAULT( mask, execDefined, execUndefined ) ;
923
924         /* interface check */
925         if ( list_ret == NULL ) {
926                 fal_utyerror  = _FAL_PARM_ER;
927                 fal_utyderror = _FAL_L_P_LST_DER;
928                 fal_utyerrno = FAL_ERR_PARM ;
929                 fal_utyerrno |= (FAL_FUNCNUM_GFLST<<8) ;
930                 return FAL_ERROR ;
931         }
932
933         /* character check */
934         if ( chk_key_str( key_data, mask ) == FAL_ERROR ) {
935                 fal_utyerrno |= (FAL_FUNCNUM_GFLST<<8) ;
936                 return  FAL_ERROR;
937         }
938
939         /* error check */
940         if ( orgn.path == NULL ) {
941                 if ( set_default_path() == FAL_ERROR ) {
942                         fal_utyerrno |= (FAL_FUNCNUM_GFLST<<8) ;
943                         return FAL_ERROR ;
944                 }
945         }
946
947         /* make an structure of "FalFontDataList()" */
948         if ((fls = (FalFontDataList *)malloc( sizeof( FalFontDataList ))) == NULL){
949                 fal_utyerror = _FAL_MALOC_ER;
950                 fal_utyerrno = FAL_ERR_MALLOC ;
951                 fal_utyerrno |= (FAL_FUNCNUM_GFLST<<8) ;
952                 return FAL_ERROR ;
953         }
954
955         /* inital set for search */
956         fls->num  = 0;
957         fls->list = NULL;
958
959         /* make font infomation list */
960         if ( fal_make_fontlist( fls, key_data, mask ) == FAL_ERROR) {
961                 switch( fal_utyerror ) {
962                         case _FAL_FLST_ER :
963                         case _FAL_DATA_OPEN_ER :
964                                 fal_utyderror = 1;
965                 }
966                 FalFreeFontList( fls );
967                 fal_utyerrno &= 0xff;
968                 fal_utyerrno |= (FAL_FUNCNUM_GFLST<<8) ;
969                 return  FAL_ERROR;
970         }
971         /* sort element of font infomation list */
972         if( fal_sort_fontlist( fls ) == FAL_ERROR ) {
973                 FalFreeFontList( fls );
974                 fal_utyerrno &= 0xff;
975                 fal_utyerrno |= (FAL_FUNCNUM_GFLST<<8) ;
976                 return FAL_ERROR ;
977         }
978
979         *list_ret = fls;
980         return  0;
981 }
982
983
984
985 /***********************************************************************/
986 /* search a character "key" of a structure                             */
987 /***********************************************************************/
988
989 static int
990 chk_key_str( key, mask )
991 FalFontData     *key;           /* a structure of saerching information */
992 int             mask;           /* a mask                               */
993 {
994         int     flg = 0;
995
996         if( key == NULL ) {
997                 return 0 ;
998         }
999
1000         /* check a character of setting a mask */
1001         /* xlfd name */
1002         if ((mask & FAL_FONT_MASK_XLFDNAME) && (key->xlfdname == NULL)) {
1003                 flg++;
1004         }
1005         /* style */
1006         if ((mask & FAL_FONT_MASK_STYLE_NAME) && (key->style.name == NULL)) {
1007                 flg++;
1008         }
1009         /* shape */
1010         if ((mask & FAL_FONT_MASK_SHAPE_NAME) && (key->shape.name == NULL)) {
1011                 flg++;
1012         }
1013         CHK_KEY_STR_OPTION( mask, key, flg ) ;
1014         /* error check */
1015         if ( flg ) {
1016                 fal_utyerror  = _FAL_PARM_ER;
1017                 fal_utyderror = _FAL_L_P_KEY_DER;
1018                 fal_utyerrno = FAL_ERR_PARM ;
1019                 return FAL_ERROR ;
1020         }
1021         return 0 ;
1022 }
1023
1024
1025 /***************************************************************/
1026 /* read a font information and add a list or make a list       */
1027 /***************************************************************/
1028
1029
1030 static int
1031 fal_make_fontlist( fls, key, mask )
1032 FalFontDataList *fls;   /* a pointer of a structure of a font information list */
1033 FalFontData     *key;   /* a structure of searching information */
1034 int             mask;   /* a mask for a saerch */
1035 {
1036         return  falReadFontInfoLists(MKFONTLIST,
1037                                 key, mask, fls,
1038                                 NULL, NULL,
1039                                 NULL, NULL) ;
1040 }
1041
1042
1043 /**************************************************/
1044 /* free a structure of "FalFontDataList()"        */
1045 /**************************************************/
1046
1047 #if NeedFunctionPrototypes
1048 int
1049 FalFreeFontList(
1050         FalFontDataList *list )
1051 #else
1052 int
1053 FalFreeFontList( list )
1054 FalFontDataList *list;
1055 #endif
1056 {
1057         int     i;
1058
1059         /* parametter check */
1060         if ( list == NULL ) {
1061                 fal_utyerror = _FAL_PARM_ER;
1062                 fal_utyerrno = FAL_ERR_PARM ;
1063                 fal_utyerrno |= (FAL_FUNCNUM_FRFLST<<8) ;
1064                 return  FAL_ERROR;
1065         }
1066         /* free a structure's array of "FalFontData()" */
1067         if ( list->list != NULL ) {
1068                 for ( i = 0;  i < list->num; i++ ) {
1069                         /* free a structure's character of "FalFontData()" */
1070                         free( list->list[i].xlfdname );
1071                         free( list->list[i].style.name );
1072                         free( list->list[i].shape.name );
1073                         FAL_FREE_FONTLIST_OPTION( list ) ;
1074                 }
1075                 /* free a structure's array of "FalFontData()" */
1076                 free( list->list );
1077         }
1078         list->num  = 0 ;
1079         list->list = NULL ;
1080
1081         /* free a structure of " FalFontDataList()" */
1082         free( list );
1083         return  0;
1084 }
1085
1086
1087 /***********************************************************************/
1088 /* split string for "FalFontData()"                                    */
1089 /***********************************************************************/
1090
1091 static int
1092 fal_split_data( buf, elm_num, elm)
1093 char    *buf;
1094 int     elm_num;
1095 char    *elm[];
1096 {
1097         int         cnt;
1098         int         strtop_flg;
1099
1100         /* check a comment */
1101         if ((*buf == '#') || (*buf == '\0')) {
1102                 return  _FAL_TRY_NEXT;
1103         }
1104         /* check a pathname */
1105         if ( *buf == '/' ) {
1106                 return  _FAL_TRY_NEXT;
1107         }
1108         /* divide a data */
1109         for ( cnt = 0, strtop_flg = 1 ; *buf != '\0';  buf++ ){
1110                 if ( strtop_flg ) {
1111                         elm[cnt] = buf;
1112                         cnt++;
1113                         strtop_flg = 0;
1114                 }
1115                 if ( *buf == ':' ) {
1116                         *buf = '\0';
1117                         strtop_flg++;
1118                 }
1119         }
1120         if ( cnt != elm_num ) {
1121                 set_errfile_str( fal_err_file, fal_err_file_buf ) ;
1122                 fal_utyerror = _FAL_FLST_ER;
1123                 fal_utyerrno = FAL_ERR_FDATA_DSC ;
1124                 return  FAL_ERROR;
1125         }
1126         return  0;
1127 }
1128
1129 /***********************************************************************/
1130 /* clear a structure of "FalFontData()"                                */
1131 /***********************************************************************/
1132
1133 static int
1134 fal_clear_data(tmp)
1135 FalFontData     *tmp;
1136 {
1137         /* search a character */
1138         free(tmp->xlfdname);
1139         free(tmp->style.name);
1140         free(tmp->shape.name);
1141         FAL_CLEAR_DATA_OPTION( tmp ) ;
1142         memset(tmp, 0, sizeof(*tmp));
1143         return 0  ;
1144 }
1145
1146 static int
1147 fal_check_already_exist( data, lst )
1148 FalFontData     *data;
1149 FalFontDataList *lst;
1150 {
1151         int             i;
1152         int             mask ;
1153
1154         mask =  FAL_FONT_MASK_XLFDNAME | FAL_FONT_MASK_STYLE_NAME
1155             | FAL_FONT_MASK_SIZE_H | FAL_FONT_MASK_CODE_SET ;
1156
1157         for ( i=0 ; i < lst->num ; i++ ){
1158                 switch ( fal_cmp_data( &(lst->list[i]), data, mask ) ) {
1159                 case 0:
1160                         return(i);
1161                 default:
1162                         continue;
1163                 }
1164         }
1165         return(-1);
1166 }
1167
1168
1169
1170 static int
1171 fal_sort_fontlist( lst )
1172 FalFontDataList *lst;
1173 {
1174         int             i,j;
1175         FalFontDataList srt;
1176         FalFontData             target;
1177         int                     target_entry;
1178
1179         if( lst->num == 0 ){
1180             return 0 ;
1181         }
1182
1183         srt.num  = lst->num;
1184
1185         if (( srt.list = malloc(sizeof(FalFontData) * srt.num)) == NULL) {
1186                 fal_utyerrno = FAL_ERR_MALLOC ;
1187                 return  FAL_ERROR;
1188         }
1189         memmove (srt.list, lst->list, sizeof(FalFontData) * srt.num);
1190         /* start to sort */
1191         for ( i=0 ; i < srt.num -1 ; i++ ) {
1192
1193                 memmove( &target, &(srt.list[i]), sizeof(FalFontData));
1194                 target_entry = i;
1195
1196                 for ( j=i+1 ; j < srt.num ; j++ ) {
1197                         if ( new_target( &target, &(srt.list[j]) ) ) {
1198                                 memmove( &target, &(srt.list[j]), sizeof(FalFontData));
1199                                 target_entry = j;
1200                         }
1201                 }
1202                 if (target_entry != i) {
1203                         memmove( &target, &(srt.list[target_entry]),
1204                             sizeof(FalFontData)
1205                             );
1206                         memmove( &(srt.list[i+1]), &(srt.list[i]),
1207                             sizeof(FalFontData)*(target_entry -i)
1208                             );
1209                         memmove( &(srt.list[i]), &target,
1210                             sizeof(FalFontData)
1211                             );
1212                 }
1213         }
1214         free(lst->list);
1215         lst->list = srt.list;
1216         return 0 ;
1217 }
1218
1219
1220
1221 /***************************************/
1222 /* change a character for a number     */
1223 /***************************************/
1224
1225 static int
1226 fal_atoi(str, val)
1227 char    *str;
1228 int     *val;
1229 {
1230         char    *ptr;
1231         char    *str_end;
1232         int             tmp;
1233
1234         str_end = strchr( str, '\0' );
1235
1236         tmp = (int)strtol(str, &ptr, 10);
1237
1238         /* error check */
1239         if ((ptr == str) || (ptr != str_end)) {
1240                 set_errfile_str( fal_err_file, fal_err_file_buf ) ;
1241                 fal_utyerror = _FAL_FLST_ER;
1242                 fal_utyerrno = FAL_ERR_FDATA_DSC ;
1243                 return(FAL_ERROR);
1244         }
1245         *val = tmp;
1246         return 0 ;
1247 }
1248
1249 /*******************************/
1250 /* get a codeset               */
1251 /*******************************/
1252
1253 static int
1254 fal_set_cs(str, cs)
1255 char    *str;
1256 int     *cs;
1257 {
1258         if (!strcmp(str, "CS0")) {
1259                 *cs = FAL_FONT_CS0;
1260         } else if (!strcmp(str, "CS1")) {
1261                 *cs = FAL_FONT_CS1;
1262         } else if (!strcmp(str, "CS2")) {
1263                 *cs = FAL_FONT_CS2;
1264         } else if (!strcmp(str, "CS3")) {
1265                 *cs = FAL_FONT_CS3;
1266         } else {
1267                 set_errfile_str( fal_err_file, fal_err_file_buf ) ;
1268                 fal_utyerror = _FAL_FLST_ER;
1269                 fal_utyerrno = FAL_ERR_FDATA_DSC ;
1270                 return(FAL_ERROR);
1271         }
1272         return(0);
1273 }
1274
1275
1276 /******************************************/
1277 /* get a equipment of an output permission*/
1278 /******************************************/
1279
1280
1281 static int
1282 fal_set_prm(str, prm)
1283 char    *str;
1284 int     *prm;
1285 {
1286         int     tmp = 0;
1287         for (     ; *str != '\0'  ; str++) {
1288             if( *str == 'P' ) {
1289                 tmp |= FAL_FONT_PRINTER;
1290             } else if( *str == 'D' ) {
1291                 tmp |= FAL_FONT_DISPLAY;
1292             } else {
1293                 set_errfile_str( fal_err_file, fal_err_file_buf ) ;
1294                 fal_utyerror = _FAL_FLST_ER;
1295                 fal_utyerrno = FAL_ERR_FDATA_DSC ;
1296                 return FAL_ERROR ;
1297             }
1298         }
1299         *prm = tmp;
1300         return 0 ;
1301 }
1302
1303 static int fal_read_db( str, db )
1304 char    *str;
1305 FalFontDB       *db;
1306 {
1307         int             i;
1308
1309         for(i=0 ; db[i].def != FAL_FONT_UNKNOWN ; i++) {
1310                 if (!strcmp(str, db[i].name)) {
1311                         return(db[i].def);
1312                 }
1313         }
1314         return FAL_FONT_UNKNOWN ;
1315 }
1316
1317
1318 /***************************************/
1319 /* make a structure of "FalFontPath()" */
1320 /***************************************/
1321
1322 int
1323 FalGetFontPath( dlist_ret )
1324 FalFontPath     **dlist_ret;
1325 {
1326
1327         /* clear an error data */
1328         fal_utyerror  = 0;
1329         fal_utyderror = 0;
1330         fal_utyerrno = 0 ;
1331
1332         /* get current locale */
1333         if( fal_init() )        return FAL_ERROR ;
1334
1335         /* parametter check */
1336         if ( dlist_ret == NULL ) {
1337                 fal_utyerror = _FAL_PARM_ER;
1338                 fal_utyerrno = FAL_ERR_PARM ;
1339                 return  FAL_ERROR;
1340         }
1341         if ( orgn.path == NULL ) {
1342                 if ( set_default_path() == FAL_ERROR ) {
1343                         return  FAL_ERROR;
1344                 }
1345                 if ( cpy_default_path( &copy ) == FAL_ERROR ){
1346                         return  FAL_ERROR;
1347                 }
1348         } else if ( copy.path == NULL ) {
1349                 if ( cpy_default_path(&copy) == FAL_ERROR ){
1350                         return  FAL_ERROR;
1351                 }
1352         } else {
1353
1354                 if ( comp_default_path( &copy ) == FAL_ERROR ) {
1355                         fal_clear_font_path( &copy );
1356                         if ( cpy_default_path(&copy) == FAL_ERROR ){
1357                                 return  FAL_ERROR;
1358                         }
1359                 }
1360         }
1361         *dlist_ret = &copy;
1362         return  0;
1363 }
1364
1365 static int
1366 set_default_path()
1367 {
1368         return  set_font_pathlist(&orgn, 0) ;
1369 }
1370
1371 static int
1372 cpy_default_path( p )
1373 FalFontPath     *p;
1374 {
1375         int         i;
1376         FalFontPath tmp;
1377
1378         if ((orgn.num == 0) || (orgn.path == NULL)) {
1379                 p->num  = 0;
1380                 p->path = NULL;
1381                 return  0;
1382         }
1383
1384         if (
1385                 (tmp.path = (char **)malloc(sizeof(char *) * (orgn.num) ))
1386                 == NULL
1387         ){
1388                 fal_utyerror = _FAL_MALOC_ER;
1389                 fal_utyerrno = FAL_ERR_MALLOC ;
1390                 return  FAL_ERROR;
1391         }
1392         tmp.num = 0;
1393         for ( i = 0 ; i< orgn.num ; i++ ) {
1394         char    *tmp_str;
1395         /* malloc & copy in strdup */
1396                 if ((tmp_str = (char *)strdup((orgn.path)[i])) == NULL) {
1397                         fal_clear_font_path( &tmp );
1398                         fal_utyerror = _FAL_MALOC_ER;
1399                         fal_utyerrno = FAL_ERR_MALLOC ;
1400                         return FAL_ERROR ;
1401                 }
1402                 tmp.path[i] = tmp_str;
1403                 tmp.num++;
1404         }
1405         p->num  = tmp.num;
1406         p->path = tmp.path;
1407         return  0;
1408 }
1409
1410 static int
1411 comp_default_path(p)
1412 FalFontPath     *p;
1413 {
1414         int         i;
1415
1416         if ( p->num != orgn.num ) {
1417             set_errfile_str( fal_err_file, fal_err_file_buf ) ;
1418             fal_utyerrno = FAL_ERR_FPATH ;
1419             return      FAL_ERROR;
1420         }
1421         for ( i = 0; i < p->num; i++ ) {
1422             if( strcmp( p->path[i], orgn.path[i] ) ) {
1423                 set_errfile_str( fal_err_file, fal_err_file_buf ) ;
1424                 fal_utyerrno = FAL_ERR_FPATH ;
1425                 return  FAL_ERROR;
1426              }
1427         }
1428         return  0;
1429 }
1430
1431
1432 static int
1433 fal_clear_font_path( ls )
1434 FalFontPath     *ls;
1435 {
1436         int             i;
1437
1438         if (ls->path != NULL) {
1439                 /* free a fontpath character */
1440                 for (i=0 ; i < ls->num ; i++) {
1441                         if ((ls->path[i] != NULL) && (ls->path[i] == orgn.path[i])) {
1442                                 free(ls->path[i]);
1443                         }
1444                 }
1445                 /* free a character pointer array */
1446                 free( ls->path );
1447                 ls->path = NULL;
1448         }
1449         ls->num = 0;
1450
1451         return  0;
1452 }
1453
1454
1455 /* access number */
1456 #define FAL_FONT_ELM_FILENAME   0
1457 #define FAL_FONT_ELM_SIZE_W     1
1458 #define FAL_FONT_ELM_SIZE_H     2
1459 #define FAL_FONT_ELM_LETTER_W   3
1460 #define FAL_FONT_ELM_LETTER_H   4
1461 #define FAL_FONT_ELM_LETTER_X   5
1462 #define FAL_FONT_ELM_LETTER_Y   6
1463 #define FAL_FONT_ELM_STYLE_NAME 7
1464 #define FAL_FONT_ELM_SHAPE_NAME 8
1465
1466 #define FAL_FONT_ELM_CODE_SET   10
1467 #define FAL_FONT_ELM_PERMISSION 11
1468 #define FAL_FONT_ELM_XLFDNAME   12
1469
1470 int
1471 set_struct( tmp_data, elm )
1472 FalFontData     *tmp_data;
1473 char    *elm[];
1474 {
1475         char    *dup_p;
1476
1477         /* data information */
1478
1479         /* a width of a character size */
1480         if ( fal_atoi(
1481                         elm[FAL_FONT_ELM_SIZE_W], &(tmp_data->size.w )
1482                         ) == FAL_ERROR
1483         ) {
1484                 goto FalError02 ;
1485         }
1486         /* a height of a character size */
1487         if ( fal_atoi(
1488                          elm[FAL_FONT_ELM_SIZE_H], &(tmp_data->size.h )
1489                          ) == FAL_ERROR
1490         ) {
1491                 goto FalError02 ;
1492         }
1493         /* a width of a letter size */
1494         if ( fal_atoi(
1495                         elm[FAL_FONT_ELM_LETTER_W], &(tmp_data->letter.w )
1496                         ) == FAL_ERROR
1497         ) {
1498                 goto FalError02 ;
1499         }
1500         /* a height of a letter size */
1501         if ( fal_atoi(
1502                         elm[FAL_FONT_ELM_LETTER_H], &(tmp_data->letter.h )
1503                         ) == FAL_ERROR
1504         ) {
1505                 goto FalError02 ;
1506         }
1507         /* position x of a letter size */
1508         if ( fal_atoi(
1509                         elm[FAL_FONT_ELM_LETTER_X], &(tmp_data->letter.x )
1510                         ) == FAL_ERROR
1511         ) {
1512                 goto FalError02 ;
1513         }
1514         /* position y of a letter size */
1515         if ( fal_atoi(
1516                         elm[FAL_FONT_ELM_LETTER_Y], &(tmp_data->letter.y )
1517                         ) == FAL_ERROR
1518         ) {
1519                 goto FalError02 ;
1520         }
1521         /* codeset */
1522         if ( fal_set_cs(
1523                         elm[FAL_FONT_ELM_CODE_SET], &(tmp_data->cd_set )
1524                         ) == FAL_ERROR
1525         ) {
1526                 goto FalError02 ;
1527         }
1528         /* a equipment of an output permission */
1529         if ( fal_set_prm(
1530                         elm[FAL_FONT_ELM_PERMISSION], &(tmp_data->prm )
1531                         ) == FAL_ERROR
1532         ) {
1533                 goto FalError02 ;
1534         }
1535
1536         /* character information */
1537
1538         /* xlfd name */
1539         if ( ( dup_p = (char *)strdup( elm[FAL_FONT_ELM_XLFDNAME] ) ) == NULL ) {
1540                 fal_utyerrno = FAL_ERR_MALLOC ;
1541                 return  FAL_ERROR;
1542         }
1543         tmp_data->xlfdname = dup_p;
1544
1545         /* character style (character) */
1546         if ( ( dup_p = (char *)strdup( elm[FAL_FONT_ELM_STYLE_NAME] ) ) == NULL) {
1547                 free( tmp_data->xlfdname );
1548                 fal_utyerror = _FAL_MALOC_ER;
1549                 fal_utyerrno = FAL_ERR_MALLOC ;
1550                 return  FAL_ERROR;
1551         }
1552         tmp_data->style.name = dup_p;
1553
1554         /* character style (numerical) */
1555         tmp_data->style.def
1556                 = fal_read_db( tmp_data->style.name, (FalFontDB *)&fal_db_style );
1557
1558         /* character shape (character) */
1559         if ( ( dup_p = (char *)strdup( elm[FAL_FONT_ELM_SHAPE_NAME] ) ) == NULL ) {
1560                 free( tmp_data->style.name );
1561                 free( tmp_data->xlfdname );
1562                 fal_utyerror = _FAL_MALOC_ER;
1563                 fal_utyerrno = FAL_ERR_MALLOC ;
1564                 return  FAL_ERROR;
1565         }
1566         tmp_data->shape.name = dup_p;
1567
1568         /* character shape (numerical) */
1569         tmp_data->shape.def
1570                 = fal_read_db( tmp_data->shape.name, (FalFontDB *)&fal_db_shape );
1571
1572         SET_STRUCT_OPTION( dup_p, elm, tmp_data, fal_utyerror, fal_db_group ) ;
1573         return  0;
1574
1575 FalError02:
1576         set_errfile_str( fal_err_file, fal_err_file_buf ) ;
1577         fal_utyerrno = FAL_ERR_FDATA_DSC ;
1578         return  FAL_ERROR;
1579 }
1580
1581 /* get a full path name */
1582 int     searchFontFileName( data, fullPathName )
1583 FalFontData     data;
1584 char    *fullPathName;
1585 {
1586         int     rtn ;
1587         rtn =   falReadFontInfoLists(SRCHFNAME,
1588                                 NULL, NULL, NULL,
1589                                 data, fullPathName,
1590                                 NULL, NULL) ;
1591         if( fal_utyerrno != 0 ){
1592             fal_utyerrno |= (FAL_FUNCNUM_SRCHFNM<<8) ;
1593         }
1594         return rtn ;
1595 }
1596
1597
1598 int     fal_eq_data( data, tmp_data )
1599 FalFontData     data;
1600 FalFontData     tmp_data;
1601 {
1602         int     flg = 0;
1603
1604         /* xlfd name */
1605         if ( strcmp( data.xlfdname, tmp_data.xlfdname ) != 0 ) {
1606                 flg++;
1607         }
1608
1609         /* a width of a character size */
1610         if ( ( flg == 0 ) && ( data.size.h != tmp_data.size.h ) ) {
1611                 flg++;
1612         }
1613
1614         /* a height of a character size */
1615         if ( ( flg == 0 ) && ( data.size.w != tmp_data.size.w ) ) {
1616                 flg++;
1617         }
1618         /* a height of a letter size */
1619         if ( ( flg == 0 ) && ( data.letter.h != tmp_data.letter.h ) ) {
1620                 flg++;
1621         }
1622
1623         /* a width of a letter size */
1624         if ( ( flg == 0 ) && ( data.letter.w != tmp_data.letter.w ) ) {
1625                 flg++;
1626         }
1627
1628         /* position x of a letter size */
1629         if ( ( flg == 0 ) && ( data.letter.x != tmp_data.letter.x ) ) {
1630                 flg++;
1631         }
1632
1633         /* position y of a letter size */
1634         if ( ( flg == 0 ) && ( data.letter.y != tmp_data.letter.y ) ) {
1635                 flg++;
1636         }
1637
1638         /* a definition data of a character style */
1639         if ( ( flg == 0 ) && ( data.style.def != tmp_data.style.def ) ) {
1640                 flg++;
1641         }
1642
1643         /* character style */
1644         if ( (data.style.name != NULL) && (tmp_data.style.name != NULL) ) {
1645             if ( ( flg == 0 ) && ( strcmp( data.style.name, tmp_data.style.name ) != 0 ) ) {
1646                 flg++;
1647             }
1648         }
1649
1650         /* a definition data of a character shape */
1651         if ( ( flg == 0 ) && ( data.shape.def != tmp_data.shape.def ) ) {
1652                 flg++;
1653         }
1654
1655         /* character shape */
1656         if ( (data.shape.name != NULL) && (tmp_data.shape.name != NULL) ) {
1657             if ( ( flg == 0 ) && ( strcmp( data.shape.name, tmp_data.shape.name ) != 0 ) ) {
1658                 flg++;
1659             }
1660         }
1661
1662         FAL_EQ_DATA_OPTION( flg, data, tmp_data ) ;
1663
1664         /* code set */
1665         if ( ( flg == 0 ) && ( data.cd_set != tmp_data.cd_set ) ) {
1666                 flg++;
1667         }
1668
1669         /* an equipment of an output permission */
1670         if ( ( flg == 0 ) && ( data.prm != tmp_data.prm ) ) {
1671                 flg++;
1672         }
1673
1674         if ( flg == 0 ) {
1675                 return  0;
1676         } else if ( flg != 0 ) {
1677                 return  _FAL_TRY_NEXT;
1678         } else {
1679                 set_errfile_str( fal_err_file, fal_err_file_buf ) ;
1680                 fal_utyerrno = FAL_ERR_FDATA_DSC ;
1681                 return  FAL_ERROR;
1682         }
1683 }
1684
1685
1686 static int
1687 CR_to_NULL(buf)
1688 char    *buf;
1689 {
1690         for(  ; *buf != '\0'; buf++ ) {
1691                 if (*buf == '\n') {
1692                         *buf = '\0';
1693                         break;
1694                 }
1695         }
1696         return 0 ;
1697 }
1698
1699 char *fal_get_base_name( str )
1700 char    *str;
1701 {
1702         char    *str_slash;
1703
1704         str_slash = strrchr( str, '/');
1705         if ( str_slash == NULL ) {
1706                 return( str );
1707         }
1708         return( ++str_slash );
1709 }
1710
1711
1712 static int
1713 fal_cmp_data( op1, key, mask )
1714 FalFontData     *op1;
1715 FalFontData     *key;
1716 int     mask ;
1717 {
1718         if ( mask == 0 ) {
1719                 return(0);
1720         }
1721
1722         if ( key == NULL ) {
1723                 return(0);
1724         }
1725
1726         if (
1727                 ( mask & FAL_FONT_MASK_XLFDNAME )
1728                 && strcmp( op1->xlfdname, key->xlfdname )
1729         ) {
1730                 return  _FAL_TRY_NEXT;
1731         }
1732         if (
1733                 ( mask & FAL_FONT_MASK_SIZE_W )
1734                 && (op1->size.w != key->size.w )
1735         ) {
1736                 return  _FAL_TRY_NEXT;
1737         }
1738         if (
1739                 ( mask & FAL_FONT_MASK_SIZE_H )
1740                 && (op1->size.h != key->size.h )
1741         ) {
1742                 return  _FAL_TRY_NEXT;
1743         }
1744         if (
1745                 ( mask & FAL_FONT_MASK_LETTER_W )
1746                 && ( op1->letter.w != key->letter.w )
1747         ) {
1748                 return  _FAL_TRY_NEXT;
1749         }
1750         if (
1751                 ( mask & FAL_FONT_MASK_LETTER_H )
1752                 && ( op1->letter.h != key->letter.h )
1753         ) {
1754                 return  _FAL_TRY_NEXT;
1755         }
1756         if (
1757                 ( mask & FAL_FONT_MASK_LETTER_X )
1758                 && ( op1->letter.x != key->letter.x )
1759         ) {
1760                 return  _FAL_TRY_NEXT;
1761         }
1762         if (
1763                 ( mask & FAL_FONT_MASK_LETTER_Y )
1764                 && ( op1->letter.y != key->letter.y )
1765         ) {
1766                 return  _FAL_TRY_NEXT;
1767         }
1768         if (
1769                 ( mask & FAL_FONT_MASK_STYLE_DEF )
1770                 && ( op1->style.def != key->style.def )
1771         ) {
1772                 return  _FAL_TRY_NEXT;
1773         }
1774         if( (op1->style.name != NULL) && (key->style.name != NULL) ) {
1775             if (
1776                 ( mask & FAL_FONT_MASK_STYLE_NAME )
1777                 && strcmp( op1->style.name, key->style.name )
1778             ) {
1779                 return  _FAL_TRY_NEXT;
1780             }
1781         }
1782         if (
1783                 ( mask & FAL_FONT_MASK_SHAPE_DEF )
1784                 && ( op1->shape.def != key->shape.def )
1785         ) {
1786                 return  _FAL_TRY_NEXT;
1787         }
1788         if( (op1->shape.name != NULL) && (key->shape.name != NULL) ) {
1789             if (
1790                 ( mask & FAL_FONT_MASK_SHAPE_NAME )
1791                 && strcmp( op1->shape.name, key->shape.name )
1792             ) {
1793                 return  _FAL_TRY_NEXT;
1794             }
1795         }
1796         FAL_CMP_DATA_OPTION( mask, op1, key ) ;
1797         if (
1798                 ( mask & FAL_FONT_MASK_CODE_SET )
1799                 && ( op1->cd_set != key->cd_set )
1800         ) {
1801                 return  _FAL_TRY_NEXT;
1802         }
1803         if ( mask & FAL_FONT_MASK_PERMISSION ) {
1804                 int     cmp_prm;
1805                 cmp_prm = key->prm & (FAL_FONT_DISPLAY | FAL_FONT_PRINTER);
1806                 if ( ( op1->prm & cmp_prm ) != cmp_prm ) {
1807                         return  _FAL_TRY_NEXT;
1808                 }
1809         }
1810         return  0;
1811 }
1812
1813
1814 /* sort flag                      */
1815 /* return data Â¡Â§   sort    ... 1 */
1816 /*                  no sort ... 0 */
1817
1818 static int
1819 new_target( target, choose )
1820 FalFontData     *target;
1821 FalFontData     *choose;
1822 {
1823         FalFontData     diff;
1824         DEF_STR_CHK ;
1825
1826         DEF_STR_SET ;
1827
1828         diff.style.def = choose->style.def - target->style.def;
1829         if( (choose->style.name != NULL) && (target->style.name != NULL) ) {
1830             str_chk.style =  strcmp( choose->style.name, target->style.name ) ;
1831         }
1832
1833         NEW_TARGET_SET( diff, choose, target, str_chk ) ;
1834
1835         diff.shape.def = choose->shape.def - target->shape.def;
1836         if( (choose->shape.name != NULL) && (target->shape.name != NULL) ) {
1837             str_chk.shape =  strcmp( choose->shape.name, target->shape.name ) ;
1838         }
1839
1840         diff.cd_set   = choose->cd_set   - target->cd_set;
1841         diff.size.h   = choose->size.h   - target->size.h;
1842         diff.size.w   = choose->size.w   - target->size.w;
1843         diff.letter.h = choose->letter.h - target->letter.h;
1844         diff.letter.w = choose->letter.w - target->letter.w;
1845
1846         /* style */
1847         if ( target->style.def == FAL_FONT_UNKNOWN ) {
1848                 if ( choose->style.def > 0 ) {
1849                         return  1;
1850                 }
1851                 /* style is FAL_FONT_UNKNOWN both "target" and "choose" */
1852                 if ( str_chk.style < 0 ) {
1853                         return  1;
1854                 }
1855                 if ( str_chk.style > 0) {
1856                         return  0;
1857                 }
1858         } else if ( choose->style.def == FAL_FONT_UNKNOWN ) {
1859                 return  0;
1860         }
1861         /* target->style.def and choose->style.def is not FAL_FONT_UNKNOWN */
1862         if (diff.style.def < 0) {
1863                 return  1;
1864         }
1865         if ( diff.style.def > 0) {
1866                 return  0;
1867         }
1868
1869         NEW_TARGET_CHK( diff, choose, target, str_chk ) ;
1870
1871         /* character shape */
1872         if ( target->shape.def == FAL_FONT_UNKNOWN ) {
1873                 if ( choose->shape.def > 0 ) {
1874                         return  1;
1875                 }
1876                 if ( str_chk.shape < 0 ) {
1877                         return  1;
1878                 }
1879                 if ( str_chk.shape > 0 ) {
1880                         return  0;
1881                 }
1882         } else if (choose->shape.def == FAL_FONT_UNKNOWN ) {
1883                 return  0;
1884         }
1885         if ( diff.shape.def < 0 ) {
1886                 return  1;
1887         }
1888         if ( diff.shape.def > 0 ) {
1889                 return  0;
1890         }
1891
1892         /* codeset */
1893         if ( diff.cd_set  < 0 ) {
1894                 return  1;
1895         }
1896         if (diff.cd_set > 0) {
1897                 return  0;
1898         }
1899
1900         /* character size height */
1901         if ( diff.size.h < 0 ) {
1902                 return  1;
1903         }
1904         if ( diff.size.h > 0 ) {
1905                 return  0;
1906         }
1907
1908         /* letter size height */
1909         if ( diff.letter.h < 0 ) {
1910                 return  1;
1911         }
1912         if ( diff.letter.h > 0 ) {
1913                 return  0;
1914         }
1915
1916         /* character size wide */
1917         if ( diff.size.w < 0 ) {
1918                 return  1;
1919         }
1920         if ( diff.size.w > 0 ) {
1921                 return  0;
1922         }
1923
1924         /* letter size wide */
1925         if ( diff.letter.w < 0 ) {
1926                 return  1;
1927         }
1928         if ( diff.letter.w > 0 ) {
1929                 return  0;
1930         }
1931
1932         return  0;
1933 }
1934
1935 #if NeedFunctionPrototypes
1936 int     FalFontOfFontID(
1937         FalFontID       fid,
1938         FalFontData     *fontdata )
1939 #else
1940 int     FalFontOfFontID( fid, fontdata )
1941 FalFontID       fid;
1942 FalFontData     *fontdata;
1943 #endif
1944 {
1945         int     rtn ;
1946         rtn =   falReadFontInfoLists(FONTOFID,
1947                                 NULL, NULL, NULL,
1948                                 NULL, NULL,
1949                                 fid, fontdata) ;
1950         if( fal_utyerrno != 0 ){
1951             fal_utyerrno |= (FAL_FUNCNUM_FID<<8) ;
1952         }
1953         return rtn ;
1954 }
1955
1956 #if NeedFunctionPrototypes
1957 FalFontID
1958 FalOpenSysFont(
1959         FalFontData     *open_font_data,
1960         int             font_data_mask,
1961         FalFontDataList **missing_font_list_return )
1962 #else
1963 FalFontID
1964 FalOpenSysFont( open_font_data, font_data_mask, missing_font_list_return )
1965 FalFontData     *open_font_data;
1966 int             font_data_mask;
1967 FalFontDataList **missing_font_list_return;
1968 #endif
1969 {
1970         int             retFL;  /* return a data of FontList */
1971         FalFontID       retOF;  /* return a data of OpenFont */
1972         char    fname[FAL_LINE_MAX];
1973
1974         /* follow "font_data_mask" and call "FalGetFontList()" */
1975         retFL = FalGetFontList(
1976                         open_font_data, font_data_mask, missing_font_list_return
1977                 );
1978         /* case of an abnormal end */
1979         if ( retFL != 0 ) {
1980                 *missing_font_list_return = NULL;
1981                 return  0;
1982         }
1983
1984         if ( (*missing_font_list_return)->num > 1 ) {
1985                 return  0;
1986         } else if ( (*missing_font_list_return)->num == 1 ) {
1987         /* investigator an font file name */
1988                 int     slct_cdset, prm, islock, dspcode ;
1989                 if (
1990                         searchFontFileName(
1991                                 (*missing_font_list_return)->list[0], fname
1992                         ) == FAL_ERROR
1993                 ){
1994                         FalFreeFontList( *missing_font_list_return  );
1995                         fal_utyerrno &= 0xff ;
1996                         fal_utyerrno |= (FAL_FUNCNUM_SRCHFNM<<8) ;
1997                         *missing_font_list_return = NULL;
1998                         return  0;
1999                 }
2000                 /* open a font by "__FalOpenFont()" */
2001                 slct_cdset = (*missing_font_list_return)->list[0].cd_set ;
2002                 dspcode  = ( font_data_mask & FAL_FONT_MASK_GLYPH_INDEX )?
2003                         FAL_FONT_GLYPH_INDEX : slct_cdset ;
2004                 prm = ((*missing_font_list_return)->list[0].prm ) ?
2005                         (*missing_font_list_return)->list[0].prm :
2006                         FAL_FONT_DISPLAY | FAL_FONT_PRINTER ;
2007                 islock = (( font_data_mask & FAL_FONT_MASK_UPDATE )? 1 : 0 );
2008                 retOF = __FalOpenFont( fname, prm, dspcode, islock );
2009
2010                 if ( retOF == (FalFontID)FAL_ERROR ) {
2011                 /* abnomal end */
2012                         FalFreeFontList( *missing_font_list_return );
2013                         fal_utyerrno &= 0xff ;
2014                         fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
2015                         *missing_font_list_return = NULL;
2016                         return  0;
2017                 } else {
2018                 /* normal end ( return  retOF ) */
2019                         *missing_font_list_return = NULL;
2020                         FalFreeFontList( *missing_font_list_return );
2021                         if( fal_add_fidinf( retOF,
2022                                 dspcode, slct_cdset, islock ) == FAL_ERROR ){
2023                                 fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
2024                                 return 0 ;
2025                         }
2026                         return  retOF;
2027                 }
2028         } else if ( (*missing_font_list_return)->num == 0 ) {
2029         /*
2030          * set NULL in "missing_font_list_return"
2031          */
2032                 FalFreeFontList( *missing_font_list_return );
2033                 *missing_font_list_return = NULL;
2034                 return  0;
2035         } else {
2036         /* case abnormal */
2037                 *missing_font_list_return = NULL;
2038                 fal_utyerrno = FAL_ERR_FATAL ;
2039                 fal_utyerrno |= (FAL_FUNCNUM_OPNFNT<<8) ;
2040                 return  0;
2041         }
2042 }
2043
2044
2045 /********************************************************
2046 *       function to access fonts.list
2047 ********************************************************/
2048 static
2049 FILE    *open_fonts_list()
2050 {
2051
2052         FILE    *fp;
2053         char    *locale                 = NULL ;
2054         char    *fal_search_path        = NULL ;
2055         char    flist_d[FAL_LINE_MAX] ;
2056         char    flist_c[FAL_LINE_MAX] ;
2057         char    flist_l[FAL_LINE_MAX] ;
2058
2059         GETLISTFILEPATH( locale, fal_search_path, flist_d, flist_c, flist_l, FONTS_LIST_FILE ) ;
2060
2061         if ( ( fp = fopen( flist_l, "r" ) ) == NULL ) {
2062             if( (fp = fopen( flist_c, "r" )) == NULL ) {
2063                 if( (fp = fopen( flist_d, "r" )) == NULL ) {
2064                     set_errfile_str( fal_err_file, flist_d ) ;
2065                     set_errfile_str( fal_err_file_buf, flist_d ) ;
2066                     fal_utyerror = _FAL_DATA_OPEN_ER;
2067                     fal_utyderror = errno;
2068                     fal_utyerrno = FAL_ERR_FDATA_OPN ;
2069                 }else{
2070                     /* Save full path of fonts.list. */
2071                     set_errfile_str( fal_err_file_buf, flist_d ) ;
2072                     if( IsDefaultPath == TRUE ) IsDefaultPath = FALSE ;
2073                 }
2074             }else{
2075                 /* Save full path of fonts.list. */
2076                 set_errfile_str( fal_err_file_buf, flist_c ) ;
2077                 if( IsDefaultPath == TRUE )     IsDefaultPath = FALSE ;
2078             }
2079         }else{
2080             /* Save full path of fonts.list. */
2081             set_errfile_str( fal_err_file_buf, flist_l ) ;
2082             if( IsDefaultPath == TRUE ) IsDefaultPath = FALSE ;
2083         }
2084
2085         return( fp ) ;
2086 }
2087
2088
2089
2090 /*
2091  *      functions to read "fonts.dir" files
2092  */
2093
2094 /***************************************************************/
2095 /* read a font information and add a list or make a list       */
2096 /***************************************************************/
2097
2098
2099 static int
2100 set_font_pathlist(pathlist, nodef)
2101 FalFontPath     *pathlist ;
2102 int             nodef ;
2103 {
2104         FILE    *fp;
2105         char    buf[FAL_LINE_MAX];
2106         char    *font_path = NULL ;
2107         char    **tmp_list ;
2108         int     num;
2109
2110         errno = 0;
2111         /* open a font directory information file */
2112         if ((fp = open_fonts_list()) == NULL) {
2113             /* Make default path list */
2114             if( errno == ENOENT || errno == EACCES || errno == EISDIR ){
2115                 if ( make_default_path(pathlist) ) {
2116                     return FAL_ERROR ;
2117                 }
2118                 return 0 ;
2119             }
2120             return FAL_ERROR ;
2121         }
2122         memset( buf, '\0', sizeof(buf) ) ;
2123
2124         while ( fgets( buf, FAL_LINE_MAX, fp ) != (char *)NULL ){
2125                 struct  stat    statbuf ;
2126                 char    *ep ;
2127
2128                 CR_to_NULL(buf);
2129
2130                 if( buf[0] == '#' ){            /* comments */
2131                     continue ;
2132                 }else if( buf[0] == '/' ){      /* font path */
2133
2134                     /* add font_path to pathlist */
2135                     if( font_path ){
2136                         num = pathlist->num;
2137                         if (pathlist->path == NULL) {
2138                             tmp_list = (char **)malloc(sizeof(char *)*(num +1));
2139                         } else {
2140                             tmp_list = (char **)realloc(pathlist->path, sizeof(char *)*(num+1));
2141                         }
2142                         if (tmp_list == NULL) {
2143                             fclose( fp );
2144                             free( font_path );
2145                             fal_clear_font_path( pathlist );
2146                             fal_utyerror = _FAL_MALOC_ER;
2147                             fal_utyerrno = FAL_ERR_MALLOC ;
2148                             return FAL_ERROR ;
2149                         }
2150                         pathlist->path = tmp_list;
2151                         pathlist->path[num] = font_path;
2152                         pathlist->num++;
2153                     }
2154
2155                     /* get font_path */
2156                     if ((font_path = (char *)strdup(buf)) == NULL) {
2157                         fclose( fp );
2158                         fal_clear_font_path( pathlist );
2159                         fal_utyerror = _FAL_MALOC_ER;
2160                         fal_utyerrno = FAL_ERR_MALLOC ;
2161                         return FAL_ERROR ;
2162                     }
2163                     ep = font_path + strlen( font_path ) - 1 ;
2164                     *ep = '/';                  /* ':' -> '/' */
2165                     if( *(ep-1) == '/' )        *ep = '\0';
2166
2167                     if( stat( font_path, &statbuf ) ) {
2168                         free( font_path ) ;
2169                         font_path = NULL ;
2170                         continue;
2171                     }
2172                     if( !(statbuf.st_mode & S_IFDIR) ) {
2173                         free( font_path ) ;
2174                         font_path = NULL ;
2175                         continue;
2176                     }
2177
2178                 }else{  /* font file */
2179                     if( nodef ){
2180                         if( font_path ){
2181                             free( font_path ) ;
2182                             font_path = NULL ;
2183                         }
2184                     }
2185                     continue ;
2186                 }
2187
2188         }
2189         /* add font_path to pathlist */
2190         if( font_path ){
2191             num = pathlist->num;
2192             if (pathlist->path == NULL) {
2193                     tmp_list = (char **)malloc(sizeof(char *)*(num +1));
2194             } else {
2195                     tmp_list = (char **)realloc(pathlist->path, sizeof(char *)*(num+1));
2196             }
2197             if (tmp_list == NULL) {
2198                 fclose( fp );
2199                 free( font_path );
2200                 fal_clear_font_path( pathlist );
2201                 fal_utyerror = _FAL_MALOC_ER;
2202                 fal_utyerrno = FAL_ERR_MALLOC ;
2203                 return FAL_ERROR ;
2204             }
2205             pathlist->path = tmp_list;
2206             pathlist->path[num] = font_path;
2207             pathlist->num++;
2208         }
2209
2210         if ( feof(fp) != 0 ){
2211             fclose(fp);
2212             return 0 ;
2213         }
2214         fclose(fp);
2215         fal_clear_font_path( pathlist );
2216         set_errfile_str( fal_err_file, fal_err_file_buf ) ;
2217         fal_utyerror = _FAL_READ_PATH_ER;
2218         fal_utyerrno = FAL_ERR_FPATH ;
2219         return  FAL_ERROR;
2220 }
2221
2222
2223
2224 static int
2225 make_default_path(pathlist)
2226 FalFontPath     *pathlist ;
2227 {
2228         struct  stat    statbuf ;
2229         char    pbuf[FAL_LINE_MAX], *dir, *p ;
2230         char    *path, **plist ;
2231         char    *sp, *ep ;
2232         int     len, num;
2233
2234         memset( pbuf, '\0', sizeof(pbuf) ) ;
2235
2236         p = pbuf ;
2237         if( (dir = getenv( "DTUDCFONTPATH" )) != NULL ) {
2238                 len = strlen( dir ) ;
2239                 strcpy( p, dir ) ;
2240                 p[len++] = ':' ;
2241                 p += len ;
2242         }
2243         strcpy( p, DTUDCFONTPATH ) ;
2244         strcat( p, ":" ) ;
2245
2246         sp = pbuf ;
2247         while ( (ep = strchr( sp, ':' )) != (char *)NULL ){
2248
2249             /* get path */
2250             *ep = '\0' ;
2251             if ((path = (char *)malloc(sizeof(char) * (strlen(sp)+2))) == NULL) {
2252                 fal_clear_font_path( pathlist );
2253                 fal_utyerror = _FAL_MALOC_ER;
2254                 fal_utyerrno = FAL_ERR_MALLOC ;
2255                 return FAL_ERROR ;
2256             }
2257             strcpy( path, sp ) ;
2258             len = strlen( sp ) ;
2259             path[len++] = '/' ;
2260             path[len] = '\0' ;
2261             if( path[len-2] == '/' )    path[len-1] = '\0';
2262
2263             if( stat(path, &statbuf) ) {
2264                 free( path ) ;
2265                 sp = ep + 1 ;
2266                 continue;
2267             }
2268             if( !(statbuf.st_mode & S_IFDIR) ) {
2269                 free( path ) ;
2270                 sp = ep + 1 ;
2271                 continue;
2272             }
2273
2274             /* add path to pathlist */
2275             num = pathlist->num;
2276             if (pathlist->path == NULL) {
2277                 plist = (char **)malloc(sizeof(char *)*(num +1));
2278             } else {
2279                 plist = (char **)realloc(pathlist->path, sizeof(char *)*(num+1));
2280             }
2281             if (plist == NULL) {
2282                 fal_clear_font_path( pathlist );
2283                 fal_utyerror = _FAL_MALOC_ER;
2284                 fal_utyerrno = FAL_ERR_MALLOC ;
2285                 free(path);
2286                 return FAL_ERROR ;
2287             }
2288             pathlist->path = plist;
2289             pathlist->path[num] = path;
2290             pathlist->num++;
2291             sp = ep + 1 ;
2292         }
2293         if( execDefined == TRUE )       execDefined = FALSE ;
2294         if( IsDefaultPath == FALSE )    IsDefaultPath = TRUE ;
2295         fal_utyerror = 0 ;
2296         fal_utyderror = 0 ;
2297         fal_utyerrno = 0 ;
2298         return  0 ;
2299 }
2300
2301
2302
2303
2304 static  int
2305 falReadFontInfoLists(func, lstkey, mask, fls, fnkey, fullpath, fid, fdata)
2306 int             func ;
2307                             /* parameters for FalGetFontList    */
2308 FalFontData     *lstkey;
2309 int             mask;
2310 FalFontDataList *fls;
2311                             /* parameters for searchFontFileName        */
2312 FalFontData     fnkey;
2313 char            *fullpath;
2314                             /* parameters for FalFontOfFontID   */
2315 FalFontID       fid ;
2316 FalFontData     *fdata;
2317 {
2318     FILE        *fp;
2319     char        pname[ FAL_LINE_MAX ] ;
2320     Oak_FontInf *finf;
2321
2322     FalFontData tmp_data;
2323     FontIDInfo  fontid_inf;
2324     char        *elm[FAL_DATA_ELM * 3];
2325     char        buf[FAL_LINE_MAX * 3];
2326
2327     struct      stat    statbuf ;
2328     char        *keyfname, *fontFileName, *fonts_list_file ;
2329     int         i, j ;
2330     int         fontnum ;
2331     int         codeset_num, *codeset_list ;
2332
2333     keyfname = fontFileName = fonts_list_file = NULL ;
2334     codeset_num = 0 ;
2335     codeset_list = NULL ;
2336     if( func & FONTOFID ){
2337         finf = (Oak_FontInf *)fid ;
2338         keyfname = finf->fname ;
2339     }
2340
2341     /* get current locale */
2342     if( fal_init() )    return FAL_ERROR ;
2343
2344     /* get font path list */
2345     if( wpath.path==NULL ) {
2346         if( set_font_pathlist( &wpath, 1 ) ) {
2347             return FAL_ERROR ;
2348         }
2349     }
2350     /*
2351      * If execDefined is true, this function read detail informations
2352      * of the fonts descripted in fonts.list.
2353      */
2354     if( execDefined == TRUE && IsDefaultPath == FALSE ) {
2355         /* open an information file */
2356         if ((fp = open_fonts_list()) == NULL) {
2357             return FAL_ERROR ;
2358         }
2359         memset( pname, 0, sizeof( pname ) );
2360
2361         while ( fgets( buf, FAL_LINE_MAX, fp ) != ( char * ) NULL ) {
2362             int     eq;
2363
2364             /* clear an area */
2365             memset( elm, 0, sizeof( elm ) );
2366             memset( &tmp_data, 0, sizeof( tmp_data ) );
2367             CR_to_NULL( buf );
2368
2369             /*
2370              * get font information of a font
2371              */
2372             switch( fal_get_def_fontdata(func, pname, buf, elm, &tmp_data, keyfname ) ) {
2373                 case    _FAL_TRY_NEXT:
2374                     if( buf[0] == '/' ) {
2375                         buf[strlen( buf ) -1] = '/' ;
2376                         strcpy( pname, buf ) ;
2377                     }
2378                     continue;
2379                 case    0:
2380                     break;
2381                 case    FAL_ERROR:
2382                 default:
2383                     goto FalError ;
2384             }
2385
2386             switch( func ) {
2387             case MKFONTLIST :           /* FalGetFontList       */
2388                 switch( falgetfontlist(&tmp_data, lstkey, mask, fls, 1) ){
2389                 case _FAL_TRY_NEXT :
2390                     continue ;
2391                 case 0:
2392                     break;
2393                 case FAL_ERROR:
2394                 default:
2395                     goto FalError ;
2396                 }
2397                 break ;
2398             case SRCHFNAME :            /* searchFontFileName   */
2399                 eq = fal_eq_data( fnkey, tmp_data ) ;
2400                 switch ( eq ) {
2401                     case 0 :
2402                         sprintf( fullpath, "%s%s", pname, elm[ FAL_FONT_ELM_FILENAME ] );
2403                         fal_clear_data( &tmp_data ) ;
2404                         fclose(fp) ;
2405                         return 0 ;
2406                     case _FAL_TRY_NEXT :
2407                         fal_clear_data( &tmp_data ) ;
2408                         break ;
2409                     default :   /* FAL_ERROR */
2410                         goto FalError ;
2411                 }
2412                 break ;
2413             case FONTOFID :             /* FalFontOfFontID      */
2414                 memmove( fdata, &tmp_data, sizeof(FalFontData) ) ;
2415                 fclose(fp) ;
2416                 return 0 ;
2417             default :
2418                 fal_utyerrno = FAL_ERR_PARM ;
2419                 goto FalError ;
2420             }
2421
2422         }       /* end of while loop */
2423         /* EOF */
2424         if ( feof( fp ) != 0 ) {
2425             fclose( fp );
2426         }else{
2427             set_errfile_str( fal_err_file, fal_err_file_buf ) ;
2428             fal_utyerror = _FAL_DATA_READ_ER;
2429             fal_utyerrno = FAL_ERR_FDATA_RD ;
2430             fclose( fp );
2431             return FAL_ERROR ;
2432         }
2433
2434         if( (func & SRCHFNAME) && (execUndefined == FALSE) ){
2435             fal_utyerrno = FAL_ERR_NOFONT ;
2436             return  FAL_ERROR  ;
2437         }
2438
2439     }   /* execDefined */
2440
2441     /*
2442      * If execUnefined is true, this function read list of font path,
2443      * and get the name of font file from fonts.dir.
2444      */
2445     if( execUndefined == TRUE ) {
2446
2447         /*
2448         * search font path
2449         */
2450         for( i=0; i<wpath.num; i++ ) {
2451             FalFontData *p_bak ;
2452
2453             fonts_list_file = (char *)malloc( sizeof(char) * ( strlen(wpath.path[i]) + strlen(FONTSDIR) + 1 ) ) ;
2454             if( fonts_list_file == (char *)NULL ) {
2455                 fal_utyerror = _FAL_MALOC_ER;
2456                 fal_utyerrno = FAL_ERR_MALLOC ;
2457                 return FAL_ERROR ;
2458             }
2459             sprintf( fonts_list_file, "%s%s", wpath.path[i], FONTSDIR ) ;
2460
2461             if( stat( fonts_list_file, &statbuf ) ) {
2462                 FreeString( fonts_list_file ) ;
2463                 continue ;
2464             }
2465             if( !(statbuf.st_mode & S_IFREG) ) {
2466                 FreeString( fonts_list_file ) ;
2467                 continue ;
2468             }
2469             errno = 0 ;
2470             /* open "fonts.dir" */
2471             if ((fp = fopen( fonts_list_file, "r" )) == NULL) {
2472                 if( errno == EACCES ) {
2473                     FreeString( fonts_list_file ) ;
2474                     continue ;
2475                 }else{
2476                     set_errfile_str( fal_err_file, fonts_list_file ) ;
2477                     FreeString( fonts_list_file ) ;
2478                     fal_utyerror = _FAL_OPEN_ER;
2479                     fal_utyderror = errno ;
2480                     fal_utyerrno = FAL_ERR_FNTDIR_OPN ;
2481                     return FAL_ERROR ;
2482                 }
2483             }
2484             /* Save full path of fonts.dir */
2485             set_errfile_str( fal_err_file_buf, fonts_list_file ) ;
2486             FreeString( fonts_list_file ) ;
2487
2488             /* Get number of fonts in current path */
2489             if( fgets( buf, FAL_LINE_MAX, fp ) == (char *)NULL ) {
2490                 set_errfile_str( fal_err_file, fal_err_file_buf ) ;
2491                 fal_utyerror = _FAL_DATA_READ_ER;
2492                 fal_utyerrno = FAL_ERR_FNTDIR_RD ;
2493                 fclose(fp);
2494                 return  FAL_ERROR;
2495             }
2496             fontnum = atoi( buf );
2497
2498             /* Get list of font informations */
2499             if( func & MKFONTLIST){
2500                 if ( fls->list == NULL ) {
2501                     p_bak  = (FalFontData *)malloc(sizeof(FalFontData) * (fls->num + fontnum));
2502                 } else {
2503                     p_bak  = (FalFontData *)realloc(fls->list, sizeof(FalFontData)*(fls->num + fontnum));
2504                 }
2505                 if ( p_bak == NULL ) {
2506                     fal_utyerror = _FAL_MALOC_ER;
2507                     fal_utyerrno = FAL_ERR_MALLOC ;
2508                     return  FAL_ERROR  ;
2509                 }
2510                 fls->list = p_bak ;
2511             }
2512
2513             memset( buf, 0, sizeof(buf));
2514
2515             while( fgets( buf, FAL_LINE_MAX, fp ) != (char *)NULL ) {
2516                 int     tmp_num, eq ;
2517                 char    *ep, *xlfd ;
2518
2519                 /* set FalFontData */
2520                 CR_to_NULL(buf);        /* '\n' -> '\0' */
2521                 memset( &tmp_data, 0, sizeof(FalFontData));
2522
2523                 /* parse string of font file */
2524                 if( (ep = strchr( buf, ' ' )) == (char *)NULL ) continue ;
2525                 else    *ep = 0 ;
2526                 /* refuse font file (not gpf) */
2527                 if(
2528                     ( strcmp( FILE_SUFFIX(buf), PCFSUFFIX ) != 0 ) &&
2529                     ( strcmp( FILE_SUFFIX(buf), SNFSUFFIX ) != 0 ) &&
2530                     ( ISOPTFONT(buf) != 0 )
2531                 ){
2532                     continue ;
2533                 }
2534
2535                 /* get string of font file */
2536                 if( (func & SRCHFNAME) || (func & FONTOFID) ){
2537                     fontFileName = (char *)malloc( sizeof(char) * ( strlen(wpath.path[i]) + strlen(buf) + 1 ) ) ;
2538                     if( fontFileName == (char *)NULL ) {
2539                         fal_utyerror = _FAL_MALOC_ER;
2540                         fal_utyerrno = FAL_ERR_MALLOC ;
2541                         return FAL_ERROR ;
2542                     }
2543                     sprintf( fontFileName, "%s%s", wpath.path[i], buf ) ;
2544                 }
2545
2546                 /* read font file and get properties */
2547                 xlfd = ++ep ;
2548                 switch( fal_get_undef_fontdata(func, fontFileName, xlfd, &tmp_data, keyfname, &codeset_num, &codeset_list) )
2549                 {
2550                     case _FAL_TRY_NEXT :
2551                         if( (func & SRCHFNAME) || (func & FONTOFID) )   FreeString( fontFileName ) ;
2552                         fal_clear_data( &tmp_data );
2553                         memset( buf, 0, sizeof(buf));
2554                         continue ;
2555                     case 0:
2556                         if( (func & FONTOFID) ) FreeString( fontFileName ) ;
2557                         break;
2558                     case FAL_ERROR:
2559                     default:
2560                         if( (func & SRCHFNAME) || (func & FONTOFID) )   FreeString( fontFileName ) ;
2561                         goto FalError ;
2562                 }
2563
2564                 if( !(func & FONTOFID) && (codeset_num == 0) ){
2565                     if( (func & SRCHFNAME) )    FreeString( fontFileName ) ;
2566                     fal_clear_data( &tmp_data );
2567                     memset( buf, 0, sizeof(buf));
2568                     continue ;
2569                 }
2570
2571                 switch( func ) {
2572                 case MKFONTLIST :               /* FalGetFontList       */
2573                     tmp_num = fls->num ;
2574                 case SRCHFNAME :                /* searchFontFileName   */
2575                     /* set font data */
2576                     for( j=0; j<codeset_num; j++ ) {
2577                         tmp_data.cd_set = FALGETFALCODESET( codeset_list[j] ) ;
2578
2579                         if( func & MKFONTLIST ){        /* FalGetFontList */
2580                             /* Ignore fonts already exists. */
2581                             if ( fal_check_already_exist(&tmp_data, fls) >= 0 ) {
2582                                 continue;
2583                             }
2584
2585                             switch( falgetfontlist(&tmp_data, lstkey, mask, fls, 1) ){
2586                             case _FAL_TRY_NEXT :
2587                                 continue ;
2588                             case 0:
2589                                 break;
2590                             case FAL_ERROR:
2591                             default:
2592                                 goto FalError ;
2593                             }
2594                         }
2595                         if( func & SRCHFNAME ){         /* searchFontFileName */
2596                             eq = fal_eq_data( fnkey, tmp_data ) ;
2597                             switch ( eq ) {
2598                                 case 0 :
2599                                     strcpy( fullpath, fontFileName );
2600                                     fal_clear_data( &tmp_data ) ;
2601                                     FreeString( fontFileName ) ;
2602                                     tmp_codeset = tmp_data.cd_set ;
2603                                     fclose(fp) ;
2604                                     /* clear code set informations */
2605                                     clear_charset_info() ;
2606                                     return 0  ;
2607                                 case _FAL_TRY_NEXT :
2608                                     break ;
2609                                 default :       /* FAL_ERROR */
2610                                     FreeString( fontFileName ) ;
2611                                     goto FalError ;
2612                             }
2613                         }
2614                     }   /* for loop */
2615                     if( func & MKFONTLIST ){    /* FalGetFontList */
2616                         if( fls->num == tmp_num )       fal_clear_data( &tmp_data ) ;
2617                     }
2618                     if( func & SRCHFNAME ){     /* searchFontFileName */
2619                         fal_clear_data( &tmp_data ) ;
2620                         FreeString( fontFileName ) ;    /* _FAL_TRY_NEXT */
2621                     }
2622                     break ;
2623
2624                 case FONTOFID :         /* FalFontOfFontID      */
2625                     memmove( fdata, &tmp_data, sizeof(FalFontData) ) ;
2626                     if( fal_read_fidinf( fid, &fontid_inf ) != FAL_ERROR )
2627                         fdata->cd_set = fontid_inf.cd_set ;
2628                     else {
2629                         fdata->cd_set = 0 ;
2630                         goto FalError ;
2631                     }
2632                     fclose(fp) ;
2633                     return 0  ;
2634
2635                 default :
2636                     goto FalError ;
2637                 }
2638
2639                 memset(buf, 0, sizeof(buf));
2640             }   /* while loop */
2641
2642             if ( feof(fp) != 0 ) {
2643                 fclose(fp);
2644             }else{
2645                 set_errfile_str( fal_err_file, fal_err_file_buf ) ;
2646                 fal_utyerror = _FAL_DATA_READ_ER;
2647                 fal_utyerrno = FAL_ERR_FNTDIR_RD ;
2648                 fclose(fp);
2649                 return  FAL_ERROR;
2650             }
2651
2652         }       /* for loop */
2653
2654         /* clear code set informations */
2655         clear_charset_info() ;
2656
2657         if( (func & SRCHFNAME) || (func & FONTOFID) ){
2658             fal_utyerrno = FAL_ERR_NOFONT ;
2659             return  FAL_ERROR  ;
2660         }
2661
2662     }   /* execUndefined */
2663
2664     return 0  ;
2665
2666 FalError:
2667
2668     clear_charset_info() ;
2669     fal_clear_data( &tmp_data ) ;
2670     fclose(fp) ;
2671     return FAL_ERROR ;
2672
2673 }
2674
2675
2676 /* clear code set informations */
2677 static void
2678 clear_charset_info()
2679 {
2680         if( charset_str_buf )   free( charset_str_buf ) ;
2681         charset_str_buf = NULL ;
2682         if( codeset_list_sav )  free( codeset_list_sav ) ;
2683         codeset_list_sav = NULL ;
2684         codeset_list_num = 0 ;
2685 }
2686
2687
2688 static  int
2689 fal_get_def_fontdata(func, pname, buf, elm, tmp_data, key_fname)
2690 int             func ;
2691 char            *pname ;        /* font path */
2692 char            *buf ;          /* buffer for fgets() */
2693 char            **elm ;
2694 FalFontData     *tmp_data ;
2695 char            *key_fname ;
2696 {
2697         int     rtn ;
2698         char    tmp_fname[FAL_LINE_MAX] ;
2699
2700         if( (rtn = fal_split_data( buf, FAL_DATA_ELM, elm )) ) {
2701             return  rtn ;
2702         }
2703
2704         if( func & FONTOFID ){
2705             sprintf( tmp_fname, "%s%s", pname, elm[ FAL_FONT_ELM_FILENAME ] );
2706             if( strcmp( tmp_fname, key_fname ) )        return _FAL_TRY_NEXT ;
2707         }
2708
2709         /* set informations to structrue */
2710         if ( set_struct( tmp_data, elm ) == FAL_ERROR ) {
2711             return  FAL_ERROR;
2712         }
2713         return 0 ;
2714 }
2715
2716
2717
2718 static  int
2719 falgetfontlist(tmp_data, key, mask, fls, fontnum)
2720 FalFontData     *tmp_data ;
2721 FalFontData     *key ;
2722 int             mask ;
2723 FalFontDataList *fls ;
2724 int             fontnum ;
2725 {
2726     FalFontData *p_bak ;
2727
2728     if( fontnum == 0 ){
2729         return _FAL_TRY_NEXT ;
2730     }
2731
2732     /* compare with key data */
2733     if ( fal_cmp_data(tmp_data, key, mask) == _FAL_TRY_NEXT ) {
2734         return _FAL_TRY_NEXT ;
2735     }
2736
2737     if ( fls->list == NULL ) {
2738         p_bak  = malloc(sizeof(FalFontData) * (fls->num + fontnum));
2739     } else {
2740         p_bak  = realloc(fls->list, sizeof(FalFontData)*(fls->num + fontnum));
2741     }
2742     if ( p_bak == NULL ) {
2743         fal_utyerror = _FAL_MALOC_ER;
2744         fal_utyerrno = FAL_ERR_MALLOC ;
2745         return  FAL_ERROR  ;
2746     }
2747     fls->list = p_bak;
2748     memmove(&(fls->list[fls->num]), tmp_data, sizeof(FalFontData));
2749     fls->num++; /* update number of fonts */
2750
2751     return 0 ;
2752 }
2753
2754
2755
2756 static  int
2757 fal_get_undef_fontdata(func, full_path, xlfd, tmp_data, key_fname, codeset_num, codeset_list)
2758 int             func ;
2759 char            *full_path ;
2760 char            *xlfd ;
2761 FalFontData     *tmp_data ;
2762 char            *key_fname ;
2763 int             *codeset_num ;
2764 int             **codeset_list ;
2765 {
2766         int     rtn, pix ;
2767         char    *char_set ;
2768         char    xlfdname[ FAL_LINE_MAX ], *family, *pixsize ;
2769         char    *cbuf, *ep ;
2770
2771         /* FalFontOfFontID() */
2772         if( func & FONTOFID ){
2773             if( strcmp( full_path, key_fname ) )  return _FAL_TRY_NEXT ;
2774         }
2775
2776         /*
2777          * parse XLFD and get font informations
2778          */
2779         cbuf = ep = family = pixsize = NULL ;
2780         /* XLFD */
2781         strcpy( xlfdname, xlfd ) ;
2782         /* pixel size */
2783         GETXLFDELMSTR( pixsize, xlfd, XLFD_ELM_PIXEL_SIZE ) ;
2784         ep = (char *)strchr( pixsize, '\0' ) ;
2785         pix = (int)strtol( pixsize, &cbuf, 10 ) ;
2786         if( cbuf == pixsize || cbuf != ep ){
2787             return _FAL_TRY_NEXT ;
2788         }
2789         /* family name */
2790         GETXLFDELMSTR( family, xlfd, XLFD_ELM_FAMILY_NAME ) ;
2791
2792         /* set font data */
2793         if( (tmp_data->style.name = (char *)strdup( family )) == NULL ) {
2794             fal_utyerror = _FAL_MALOC_ER ;
2795             fal_utyerrno = FAL_ERR_MALLOC ;
2796             return FAL_ERROR ;
2797         }
2798         if( (tmp_data->xlfdname = (char *)strdup( xlfdname )) == NULL ) {
2799             fal_utyerror = _FAL_MALOC_ER ;
2800             fal_utyerrno = FAL_ERR_MALLOC ;
2801             return FAL_ERROR ;
2802         }
2803         tmp_data->size.h = pix ;
2804         tmp_data->size.w = -1 ;
2805
2806         /* FalGetFontList() and searchFontFilename() */
2807         if( (func & MKFONTLIST) || (func & SRCHFNAME) ){
2808             GETCHARSETSTR( char_set, tmp_data->xlfdname ) ;
2809             /* code set infomations exist */
2810             if( charset_str_buf && !strcmp( charset_str_buf, char_set ) ) {
2811                 *codeset_num  = codeset_list_num ;
2812                 *codeset_list = codeset_list_sav ;
2813             }else{
2814                 /* clear code set infomations */
2815                 clear_charset_info() ;
2816                 /* get code set infomations */
2817                 if( (rtn = fal_get_codeset( fal_locale, char_set, codeset_list, codeset_num )) ){
2818                     return rtn ;
2819                 }
2820                 /* save code set infomations */
2821                 if( (charset_str_buf = (char *)strdup( char_set )) == NULL ) {
2822                     fal_utyerror = _FAL_MALOC_ER ;
2823                     fal_utyerrno = FAL_ERR_MALLOC ;
2824                     return FAL_ERROR ;
2825                 }
2826                 codeset_list_num = *codeset_num  ;
2827                 codeset_list_sav = *codeset_list ;
2828             }
2829         }
2830         return 0 ;
2831 }
2832
2833
2834
2835 /*
2836  *      get file name of fonts
2837  */
2838
2839 #if NeedFunctionPrototypes
2840 int
2841 FalFontIDToFileName(
2842         FalFontID       fid,
2843         char            **file_name )
2844 #else
2845 int
2846 FalFontIDToFileName( fid, file_name )
2847 FalFontID       fid;
2848 char            **file_name;
2849 #endif
2850 {
2851         char            *fname ;
2852         Oak_FontInf     *finf ;
2853         if( fid == NULL ) {
2854                 fal_utyerror  = _FAL_PARM_ER ;
2855                 fal_utyderror = _FAL_R_P_FINF_DER ;
2856                 fal_utyerrno = FAL_ERR_PARM ;
2857                 fal_utyerrno |= (FAL_FUNCNUM_IDTOFNM<<8) ;
2858                 return FAL_ERROR ;
2859         }
2860         if( file_name == NULL ) {
2861                 fal_utyerror  = _FAL_PARM_ER ;
2862                 fal_utyderror = _FAL_R_P_W_DER ;
2863                 fal_utyerrno = FAL_ERR_PARM ;
2864                 fal_utyerrno |= (FAL_FUNCNUM_IDTOFNM<<8) ;
2865                 return FAL_ERROR ;
2866         }
2867         finf = (Oak_FontInf *)fid ;
2868         if( (fname = (char *)strdup( finf->fname )) == NULL ) {
2869                 fal_utyerror = _FAL_MALOC_ER ;
2870                 fal_utyerrno = FAL_ERR_MALLOC ;
2871                 fal_utyerrno |= (FAL_FUNCNUM_IDTOFNM<<8) ;
2872                 return FAL_ERROR ;
2873         }
2874         *file_name = fname ;
2875         return 0 ;
2876 }
2877
2878
2879 #if NeedFunctionPrototypes
2880 int
2881 FalFree(
2882         void    *list )
2883 #else
2884 int
2885 FalFree( list )
2886 void    *list ;
2887 #endif
2888 {
2889         if( list == NULL ) {
2890                 fal_utyerror  = _FAL_PARM_ER ;
2891                 fal_utyerrno = FAL_ERR_PARM ;
2892                 fal_utyerrno |= (FAL_FUNCNUM_FREE<<8) ;
2893                 return FAL_ERROR  ;
2894         }
2895         free( list ) ;
2896         return 0  ;
2897 }
2898
2899
2900
2901 int
2902 FalFreeGI( ginf, num )
2903 FalGIInf        *ginf ;
2904 int             num ;
2905 {
2906         int     i ;
2907         if( ginf == NULL ) {
2908                 fal_utyerror  = _FAL_PARM_ER ;
2909                 fal_utyerrno = FAL_ERR_PARM ;
2910                 return FAL_ERROR ;
2911         }
2912         for( i=0; i<num; i++ ) {
2913                 if( ginf[i].charset_str != NULL )
2914                         free( ginf[i].charset_str ) ;
2915         }
2916         free( ginf ) ;
2917         return 0  ;
2918 }
2919
2920
2921 /*
2922  *      This functions manage the relation of FontID
2923  *      between code set number.
2924  */
2925
2926 static  int
2927 fal_add_fidinf( fid, dspcode, cd_set, islock )
2928 FalFontID       fid ;
2929 int             dspcode ;
2930 int             cd_set ;
2931 int             islock ;
2932 {
2933         int             exist, i, cnt ;
2934         FontIDInfo      **flist ;
2935         if( fid == NULL ) {
2936                 fal_utyerror  = _FAL_PARM_ER ;
2937                 fal_utyerrno = FAL_ERR_PARM ;
2938                 return FAL_ERROR ;
2939         }
2940         exist = 0 ;
2941         for( i=0; i<mngfid.num; i++ ) {
2942                 if( fid == mngfid.finf[i]->fid ) {
2943                         exist++ ;
2944                         mngfid.finf[i]->dspcode = dspcode ;
2945                         mngfid.finf[i]->cd_set  = cd_set ;
2946                         mngfid.finf[i]->islock  = islock ;
2947                         break ;
2948                 }
2949         }
2950         /* add new data */
2951         if( !exist ) {
2952             if( mngfid.finf == NULL ) {
2953                 cnt = 0 ;
2954                 if( (flist = (FontIDInfo **)malloc( sizeof(FontIDInfo *) )) == NULL ) {
2955                         fal_utyerror = _FAL_MALOC_ER ;
2956                         fal_utyerrno = FAL_ERR_MALLOC ;
2957                         return FAL_ERROR ;
2958                 }
2959             } else {
2960                 cnt = mngfid.num ;
2961                 if( (flist = (FontIDInfo **)realloc(
2962                         mngfid.finf, sizeof(FontIDInfo *) * (cnt + 1) )) == NULL )
2963                 {
2964                         fal_utyerror = _FAL_MALOC_ER ;
2965                         fal_utyerrno = FAL_ERR_MALLOC ;
2966                         return FAL_ERROR ;
2967                 }
2968             }
2969             if( (flist[cnt] = (FontIDInfo *)malloc( sizeof(FontIDInfo) )) == NULL ) {
2970                 fal_utyerror = _FAL_MALOC_ER ;
2971                 fal_utyerrno = FAL_ERR_MALLOC ;
2972                 free(flist);
2973                 return FAL_ERROR ;
2974             }
2975             flist[cnt]->fid     = fid ;
2976             flist[cnt]->cd_set  = cd_set ;
2977             flist[cnt]->dspcode         = dspcode ;
2978             flist[cnt]->islock  = islock ;
2979
2980             mngfid.num  = cnt + 1 ;
2981             mngfid.finf = flist ;
2982         }
2983
2984         return 0 ;
2985 }
2986
2987 static  int
2988 fal_read_fidinf( fid, fontid_inf )
2989 FalFontID       fid ;
2990 FontIDInfo      *fontid_inf;
2991 {
2992         int     i ;
2993         if( fid == NULL ) {
2994                 fal_utyerror = _FAL_PARM_ER ;
2995                 fal_utyerrno = FAL_ERR_PARM ;
2996                 return FAL_ERROR ;
2997         }
2998         for( i=0; i<mngfid.num; i++ ) {
2999                 if( mngfid.finf[i]->fid == fid ) {
3000                         fontid_inf->fid     =  fid ;
3001                         fontid_inf->cd_set  =  mngfid.finf[i]->cd_set ;
3002                         fontid_inf->dspcode =  mngfid.finf[i]->dspcode ;
3003                         fontid_inf->islock  =  mngfid.finf[i]->islock ;
3004                         return 0 ;
3005                 }
3006         }
3007         fal_utyerror = _FAL_PARM_ER ;
3008         fal_utyerrno = FAL_ERR_FID_RD ;
3009         return FAL_ERROR ;
3010 }
3011
3012
3013 static  int
3014 fal_del_fidinf( fid )
3015 FalFontID       fid ;
3016 {
3017         int     i, cnt, target ;
3018         FontIDInfo      **flist ;
3019
3020         for( i=0; i<mngfid.num; i++ ) {
3021                 if( mngfid.finf[i]->fid == fid ) {
3022                         target = i ;
3023                         break ;
3024                 }
3025         }
3026         cnt = mngfid.num - 1 ;
3027         free( mngfid.finf[target] ) ;
3028         for( i=target; i<mngfid.num; i++ ) {
3029                 mngfid.finf[i] = mngfid.finf[i+1] ;
3030         }
3031         if( cnt > 0 ) {
3032                 if( (flist = (FontIDInfo **)realloc(
3033                         mngfid.finf, sizeof(FontIDInfo *) * cnt )) == NULL )
3034                 {
3035                         fal_utyerror = _FAL_MALOC_ER ;
3036                         fal_utyerrno = FAL_ERR_MALLOC ;
3037                         return FAL_ERROR ;
3038                 }
3039                 mngfid.num = cnt ;
3040                 mngfid.finf = flist ;
3041         } else {
3042                 free( mngfid.finf ) ;
3043                 mngfid.num = 0 ;
3044                 mngfid.finf = NULL ;
3045         }
3046         return 0 ;
3047 }
3048
3049 /*
3050  *      convert codepoint into glyph index
3051  */
3052
3053 static int
3054 fal_conv_code_to_glyph( fid, code, glidx )
3055 FalFontID       fid ;
3056 unsigned int    code ;
3057 unsigned int    *glidx ;
3058 {
3059         Oak_FontInf     *finf ;
3060         FalFontData     tmp_data ;
3061         FalGIInf        *gi ;
3062         FontIDInfo      fontid_inf ;
3063         int             gnum ;
3064         int             i ;
3065         int             inner_code = 0 ;
3066         char            *char_set ;
3067         static FalFontID        cmpfid = 0 ;
3068         static  char    charset_name[FAL_LINE_MAX] ;
3069
3070         finf = (Oak_FontInf *)fid ;
3071         /*
3072          *      get code set number
3073          */
3074         if( fal_read_fidinf( fid, &fontid_inf ) == FAL_ERROR ) {
3075                 return  FAL_ERROR;
3076         }
3077
3078         if( fontid_inf.dspcode != FAL_FONT_GLYPH_INDEX ){
3079                 /*
3080                  *      get string of "CHARSET_REGISTRY"
3081                  */
3082                 memset( &tmp_data, 0, sizeof(FalFontData) ) ;
3083
3084                 if( cmpfid != fid ){
3085                     if( falReadGpfProp( FAL_READ_FONTINFO, finf, FAL_FONT_PRM, &tmp_data ) ) {
3086                             fal_clear_data( &tmp_data ) ;
3087                             return      FAL_ERROR;
3088                     }
3089                     GETCHARSETSTR( char_set, tmp_data.xlfdname ) ;
3090                     snprintf( charset_name, sizeof(charset_name), "%s", char_set ) ;
3091                 }
3092
3093                 /*
3094                 *       convert codepoint into glyph index
3095                 */
3096                 if( COMM_SBFNT_ISSBFNT( charset_name ) ) {
3097                     inner_code = code ;
3098                     FAL_OPT_CONVCPTOGI( fontid_inf.dspcode, inner_code ) ;
3099                 } else {
3100                     if( fal_code_to_glyph( fal_locale, code, &gi, &gnum ) ) {
3101                         fal_clear_data( &tmp_data ) ;
3102                         return  FAL_ERROR;
3103                     }
3104                     if( gnum==1 ){
3105                         inner_code = gi[0].glyph_index ;
3106                     }else{
3107                         for( i=0; i<gnum; i++ ) {
3108                             if( !strcmp( gi[i].charset_str, char_set ) ) {
3109                                 inner_code = gi[i].glyph_index ;
3110                                 break ;
3111                             }
3112                         }
3113                     }
3114                     FalFreeGI( gi, gnum ) ;
3115                 }
3116                 fal_clear_data( &tmp_data ) ;
3117         }else{
3118                 inner_code = code;                      /* glyph index */
3119         }
3120         *glidx = inner_code ;
3121
3122         return 0 ;
3123 }
3124
3125
3126 /*
3127  *      convert codepoint into glyph index
3128  */
3129
3130 static int
3131 fal_conv_glyph_to_code( finf, dspcode, cd_set, glidx, code )
3132 Oak_FontInf     *finf ;
3133 int             dspcode ;
3134 int             cd_set ;
3135 unsigned int    glidx ;
3136 unsigned int    *code ;
3137 {
3138         FalFontData     tmp_data ;
3139         int             inner_code ;
3140         char            *char_set ;
3141
3142         /*
3143          *      get code set number
3144          */
3145         if( dspcode != FAL_FONT_GLYPH_INDEX ){
3146                 /*
3147                  *      get string of "CHARSET_REGISTRY"
3148                  */
3149                 memset( &tmp_data, 0, sizeof(tmp_data) ) ;
3150                 if( falReadGpfProp( FAL_READ_FONTINFO, finf, FAL_FONT_PRM, &tmp_data ) ) {
3151                         fal_clear_data( &tmp_data ) ;
3152                         return  FAL_ERROR;
3153                 }
3154                 GETCHARSETSTR( char_set, tmp_data.xlfdname ) ;
3155
3156                 /*
3157                 *       convert glyph index into codepoint
3158                 */
3159                 if( COMM_SBFNT_ISSBFNT( char_set ) ) {
3160                     inner_code = glidx ;
3161                     FAL_OPT_CONVGITOCP( dspcode, inner_code ) ;
3162                 } else {
3163                     if( fal_glyph_to_code( fal_locale, char_set, cd_set, glidx, &inner_code ) ) {
3164                         fal_clear_data( &tmp_data ) ;
3165                         return  FAL_ERROR;
3166                     }
3167                 }
3168                 fal_clear_data( &tmp_data ) ;
3169         }else{
3170                 inner_code = glidx ;            /* glyph index */
3171         }
3172         *code = inner_code ;
3173
3174         return 0 ;
3175 }
3176
3177
3178 static  int
3179 file_lock( fd )
3180 int     fd;             /* a file descripter */
3181 {
3182         struct flock    flpar;
3183
3184         flpar.l_type = F_RDLCK;
3185         flpar.l_start = 0;
3186         flpar.l_len = 0;
3187         flpar.l_whence = 0;
3188
3189         if ( fcntl( fd, F_SETLK, &flpar ) == -1 ) {
3190                 fal_utyerrno = FAL_ERR_FILELCK ;
3191                 return  FAL_ERROR ;
3192         }
3193
3194         return  0;
3195 }
3196
3197 static  int
3198 file_unlock( fd )
3199 int     fd;     /* a file descripter */
3200 {
3201         struct flock    flpar;
3202
3203         flpar.l_type = F_UNLCK;
3204         flpar.l_start = 0;
3205         flpar.l_len = 0;
3206         flpar.l_whence = 0;
3207
3208         if ( fcntl( fd, F_SETLK, &flpar ) == -1 ){
3209                 fal_utyerrno = FAL_ERR_FILEUNLCK ;
3210                 return  FAL_ERROR ;
3211         }
3212         return  0;
3213 }
3214
3215 static  int
3216 is_lock( fd )
3217 int     fd;     /* file descripter */
3218 {
3219         struct flock    flpar;
3220
3221         flpar.l_type = F_WRLCK;
3222         flpar.l_start = 0;
3223         flpar.l_len = 0;
3224         flpar.l_whence = 0;
3225
3226         if ( fcntl( fd, F_GETLK, &flpar ) == -1 ) {
3227                 fal_utyerrno = FAL_ERR_FILEGETLCK ;
3228                 return  FAL_ERROR ;
3229         }
3230
3231         if ( flpar.l_type == F_UNLCK ){
3232                 return  0 ;
3233         } else {
3234                 fal_utyerrno = FAL_ERR_LCKD ;
3235                 return  1 ;
3236         }
3237 }
3238
3239 /********************< end of falfont.c >*********************************/