util/dttypes: remove register keyword
[oweals/cde.git] / cde / programs / dtudcfonted / dtcpgpf / cpgpf.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: cpgpf.c /main/6 1996/11/08 02:03:36 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        <stdio.h>
33 #include        <locale.h>
34 #include        <fcntl.h>
35 #include        <signal.h>
36 #include        <sys/types.h>
37 #include        <sys/stat.h>
38 #ifndef SVR4
39 #if !defined( SYSV )
40 #include        <sys/resource.h>
41 #endif
42 #include        <sys/wait.h>
43 #else
44 #include        <wait.h>
45 #endif
46
47 #include        <unistd.h>
48 #include        <string.h>
49 #include        <stdlib.h>
50
51 #include        "bdfgpf.h"
52
53 #include        <X11/Xmd.h>
54 #include        <X11/Xproto.h>
55 #include        "fontstruct.h"
56
57 #include        "FaLib.h"
58 #include        "snfstruct.h"
59 #include        "udcutil.h"
60
61 #include        <errno.h>
62
63 #define START_CODE      0
64 #define END_CODE        1
65 #define INPUT_FONT      0
66 #define OUTPUT_FONT     1
67
68 #define RESIZE_BY_RATE( a, r )   ((int)( (float)(a) * (r)))
69 #define DEF_RESOLUTION  ((78 / 72.27) * 100)
70
71 static  void    put_error_and_exit();
72 static  void    put_help();
73 static  void    sigint_out() ;
74 static  void    getDefaultCh() ;
75 static  void    MkFontProp() ;
76
77 static  int     CpyGpfInit() ;
78 static  int     writeGpf() ;
79 static  int     check_width() ;
80 static  int     check_height() ;
81 static  int     check_width_height() ;
82 static  int     getGpfFileName() ;
83 static  int     readGpf() ;
84 static  int     readBdfHeaderAndPut() ;
85 static  int     check_code() ;
86 static  int     readBdfToMemory() ;
87 static  int     cpg_atoi() ;
88 static  int     is_in_udcregion() ; 
89
90 extern  int     fal_code_to_glyph() ;
91
92 static struct ptobhead WriteGpf;
93
94 static  char    *targ_file = NULL;      /* UDC_file_name */
95 static  char    *com = NULL;            /* command_name */
96 static  char    create_font[BUFSIZE] ;
97 static  int     new_target = 0 ;
98 static  unsigned int    firstCol, lastCol, firstRow, lastRow ;
99 static  char    *locale ;
100 static  char    *spacing ;
101 static  char    *char_set ;
102 static  char    *xlfdname ;
103
104
105 static void
106 sigint_out()
107 {
108     if (WriteGpf.out_file) {
109         Unlink_Tmpfile( WriteGpf.out_file, com );
110     }
111     exit( 0 );
112 }
113
114
115 main( argc, argv )
116 int     argc;
117 char    **argv ;
118 {
119         int     code_area , help, no_infile, no_style, type ;
120         int     rtn, i, exit_code ;
121 #ifndef ROOT_ONLY
122         int     exit_stat;
123 #endif
124         struct btophead InputGpf;       /* input file  */
125         struct btophead OutputGpf;      /* output file */
126         struct stat     statbuf;
127         char            isnf_file[BUFSIZE] ;
128         char            osnf_file[BUFSIZE] ;
129         char            readbuf[BUFSIZE];
130         char            *istyle, *ostyle ;
131         char            *ixlfdname, *oxlfdname ;
132         int             chk_fd;
133         FalGlyphRegion  *gr ;
134         int             num_gr ;
135         char            *start_code, *end_code ;
136         int             startcode, endcode ;
137
138         int     code_no;
139         char    *codeset = DEFAULT_CODESET;
140
141         /*
142          * initiation of parameters
143          */
144         com = argv[0];
145         *create_font = '\0' ;
146         if( (locale = (char *)getenv( "LANG" )) == NULL ){
147             locale = "C" ;
148         }
149
150         memset( &InputGpf, 0, sizeof(struct btophead) ) ;
151         memset( &OutputGpf, 0, sizeof(struct btophead) ) ;
152         memset( &WriteGpf, 0, sizeof(struct ptobhead) ) ;
153
154         COMM_SETDEFAULTSTYLE( istyle ) ;
155         COMM_SETDEFAULTSTYLE( ostyle ) ;
156
157         InputGpf.in_file = OutputGpf.in_file = WriteGpf.out_file = NULL;
158         ixlfdname = oxlfdname = '\0' ;
159         spacing = char_set = xlfdname = NULL ;
160
161         gr              = NULL ;
162         num_gr          = 0 ;
163         firstCol = firstRow = 0xff ;
164         lastCol = lastRow = 0 ;
165
166         start_code = end_code = '\0' ;
167         startcode       = MIN_CODE ;
168         endcode         = MAX_CODE ;
169
170         /* get full path of font compilers */
171         if (!( bdftopcf = get_cmd_path( getenv( "PATH" ), BDFTOPCF_CMD ))) {
172                 bdftopcf = BDFTOPCF;
173         }
174         if (!( oakgtobdf = get_cmd_path( getenv( "PATH" ), SNFTOBDF_CMD ))) {
175                 oakgtobdf = SNFTOBDF;
176         }
177         if (!( bdftosnf = get_cmd_path( getenv( "PATH" ), BDFTOSNF_CMD ))) {
178                 bdftosnf = BDFTOSNF;
179         }
180         /*****************************************************************
181         * check options
182         *****************************************************************/
183         code_area = NORMAL;
184         help = no_infile = no_style = type = 0;
185
186         for ( i = 1; i < argc; i++ ) {
187                 if ( *argv[i] != '-' ) {
188                     if( !InputGpf.in_file ){
189                         InputGpf.in_file = argv[i] ;
190                     }else if( !OutputGpf.in_file ){
191                         OutputGpf.in_file = argv[i] ;
192                     } else {
193                         put_help(com);
194                         exit( 1 );
195                     }
196                 }else if ( !strcmp( argv[i], "-ig" ) ) {
197                     if ( ( i < argc-1) && (*argv[i+1] != '-' ) ) {
198                         InputGpf.in_file = argv[++i];
199                     } else {
200                         no_infile = 1;
201                     }
202                 } else if ( !strcmp( argv[i], "-og" ) ) {
203                     if ( (i < argc-1) && (*argv[i+1] != '-') ){
204                         OutputGpf.in_file = argv[++i];
205                     } else {
206                         no_infile = 2;
207                     }
208                 } else if ( !strcmp( argv[i], "-system" ) ) {
209                         code_area |= SYSTM;
210                 } else if ( !strcmp( argv[i], "-help" ) ) {
211                         help = 1;
212                 } else if ( !strcmp(argv[i], "-width") ) {
213                     if ((i < argc-1) && (*argv[i+1] != '-')) {
214                         OutputGpf.p_width =  check_width( com, argv[++i]);
215                         if (OutputGpf.p_width == 0) {
216                             exit(1);
217                         }
218                     } else {
219                         USAGE1("%s : The character width is not specified.\n", com);
220                         exit( 1 );
221                     }
222                 } else if ( !strcmp(argv[i], "-height") ) {
223                     if ((i < argc-1) && (*argv[i+1] != '-')) {
224                         OutputGpf.p_height = check_height( argv[0], argv[++i]);
225                         if (OutputGpf.p_height == 0) {
226                             exit(1);
227                         }
228                     } else {
229                         USAGE1("%s :  The character height is not specified.\n", com);
230                         exit(1);
231                     }
232                 } else if ( !strcmp(argv[i], "-start") ) {
233                     if ((i < argc-1) && (*argv[i+1] != '-')) {
234                         start_code = argv[++i] ;
235                     } else {
236                         USAGE1("%s : The extract start code is not specified.\n", com);
237                         exit( 1 );
238                     }
239                 } else if ( !strcmp(argv[i], "-end" ) ) {
240                     if ( ( i < argc-1 ) && ( *argv[i+1] != '-' ) ) {
241                         end_code = argv[++i] ;
242                     } else {
243                         USAGE1("%s : The extract end code is not specified.\n", com);
244                         exit( 1 );
245                     }
246                 } else if ( !strcmp( argv[i], "-istyle" ) ) {
247                     if ( ( i < argc-1 ) && ( *argv[i+1] != '-' ) ){
248                         istyle = argv[++i];
249                     } else {
250                         no_style = 1;
251                     }
252                 } else if ( !strcmp( argv[i], "-ostyle" ) ) {
253                     if ( ( i < argc-1 ) && ( *argv[i+1] != '-' ) ){
254                         ostyle = argv[++i];
255                     } else {
256                         no_style = 2;
257                     }
258                 } else if ( !strcmp( argv[i], "-codeset" ) ) {
259                     if ( ( i < argc - 1 ) && ( *argv[i+1] != '-' )){
260                         codeset = argv[++i];
261                         COMM_SET_CODESET( codeset, code_area ) ;
262                     }
263                 } else if ( !strcmp( argv[i], "-ixlfd" ) ) {
264                     if ( i < argc - 1 ){
265                         ixlfdname = argv[++i];
266                     }
267                 } else if ( !strcmp( argv[i], "-oxlfd" ) ) {
268                     if ( i < argc - 1 ){
269                         oxlfdname = argv[++i];
270                     }
271                 } else if ( COMM_SBOPT_STRCMP( argv, i ) ) {
272                     COMM_SBOPT_SETSBOPT( code_area ) ;
273                 } else if ( COMM_TYPE_STRCMP( argv, i ) ) {
274                     COMM_TYPE_SETTYPE( argc, argv, i, type ) ;
275                 } else {
276                     put_help(com);
277                     exit( 1 );
278                 }
279         }
280
281         /* help_message */
282         if ( help == 1 ) {
283                 put_help( com );
284                 exit( 0 );
285         }
286         COMM_SBOPT_CHECKSBOPT( com, code_area ) ;
287
288         if ( no_infile ) {
289             if ( no_infile == 1 )
290                 USAGE1("%s : The font file name for input cannot be omitted.\n", com );
291             else
292                 USAGE1("%s : The font file name for output cannot be omitted.\n", com );
293             exit( 1 );
294         }
295
296         if ( (code_no = cpg_atoi( codeset)) == -1 ) {
297             USAGE1("%s : The code set number is illegal.\n", com );
298             exit( 1 );
299         }
300
301         if ( no_style ) {
302             if ( no_style == 1 )
303                 USAGE1("%s : The style for input cannot be omitted.\n", com );
304             else
305                 USAGE1("%s : The style for output cannot be omitted.\n", com );
306             USAGE1("%s : The style is not specified.\n", com ) ;
307             exit( 1 );
308         }
309
310         /*****************************************************************
311         * get file name
312         *****************************************************************/
313         /* copy origin */
314         if ( getGpfFileName( com, &InputGpf, code_area, code_no, ixlfdname, isnf_file, istyle ) ) {
315             exit( 1 );
316         }
317
318         /* copy target */
319         if ( getGpfFileName( com, &OutputGpf, code_area, code_no, oxlfdname, osnf_file, ostyle ) ) {
320             exit( 1 );
321         }
322
323         /*
324          * refuse proportional fonts
325          */
326         if( ( !stat( OutputGpf.in_file, &statbuf ) )){
327             if ( GetUdcFontName( OutputGpf.in_file, NULL, &xlfdname ) ) {
328                 USAGE2("%s : This font cannot get XLFD(%s). Terminates abnormally.\n", com, OutputGpf.in_file );
329                 exit( 1 );
330             }
331             GETSPACINGSTR( spacing, xlfdname ) ;
332             if ( !strcmp( "p", spacing ) || !strcmp( "P", spacing ) ) {
333                 USAGE2("%s : cannot edit proportional fonts.(SPACING \"%s\")\n", com, spacing );
334                 exit( 1 );
335             }
336         }else{
337             /* new file */
338             if( !(code_area & SYSTM) ){
339                 USAGE2("%s : \"%s\" does not exists.\n", com, OutputGpf.in_file );
340                 exit( 1 );
341             }
342         }
343         if( xlfdname )  free( xlfdname ) ;
344         if ( GetUdcFontName( InputGpf.in_file, NULL, &xlfdname ) ) {
345             USAGE2("%s : This font cannot get XLFD(%s). Terminates abnormally.\n", com, InputGpf.in_file );
346             exit( 1 );
347         }
348         GETSPACINGSTR( spacing, xlfdname ) ;
349         if ( !strcmp( "p", spacing ) || !strcmp( "P", spacing ) ) {
350             USAGE2("%s : cannot edit proportional fonts.(SPACING \"%s\")\n", com, spacing );
351             exit( 1 );
352         }
353         GETCHARSETSTR( char_set, xlfdname ) ;
354
355         /*****************************************************************
356         * get UDC code region
357         *****************************************************************/
358         if ( !(code_area & SYSTM) ) {
359             if ( GetUdcRegion( com, code_no, InputGpf.in_file, &num_gr, &gr ) ) {
360                 USAGE1("%s : This font cannot get UDC code region. Terminates abnormally.\n", com);
361                 exit( 1 );
362             }
363         } else {
364             num_gr = 1 ;
365             if( (gr = (FalGlyphRegion *)malloc( sizeof(FalGlyphRegion) * num_gr )) == NULL ) {
366                 USAGE1("%s : malloc error. Terminates abnormally.\n", com);
367                 exit( 1 );
368             }
369             gr[0].start = MIN_CODE ;
370             gr[0].end   = MAX_CODE ;
371         }
372
373         /*
374          * check specified code region
375          */
376         if( start_code && end_code ) {
377             if( (startcode = check_code(com, start_code, START_CODE, char_set, num_gr, gr )) < 0 ) {
378                 exit( 1 );
379             }
380             if( (endcode = check_code(com, end_code, END_CODE, char_set, num_gr, gr )) < 0 ) {
381                 exit( 1 );
382             }
383
384             if ( startcode > endcode ) {
385                 USAGE1("%s : The specification of extract start/end code is improper.\n", com);
386                 exit( 1 );
387             }
388
389             if( is_in_udcregion( startcode, endcode, num_gr, gr ) ){
390                 USAGE3("%s : The specified code \"%s-%s\" is outside of the UDC code region.\n", com, start_code, end_code );
391                 USAGE("The UDC code region of specified font is showed below.\n" );
392                 for( i=0; i<num_gr; i++ )
393                     USAGE2("\t0x%x-0x%x\n", gr[i].start, gr[i].end );
394                 exit( 1 );
395             }
396         }
397
398         /*****************************************************************
399         * check status of font file
400         *****************************************************************/
401         /* get InputGpf.in_file */
402         if ((targ_file = GetRealFileName( OutputGpf.in_file )) == NULL){
403             if( errno == ENOENT && (code_area & SYSTM) ){
404                 /* create new file */
405                 if ( ( chk_fd = open( OutputGpf.in_file, O_RDWR | O_CREAT, 0644 ) ) < 0  ) {
406                     USAGE2("%s : The font file of substance \"%s\" cannot be create.\n", com , OutputGpf.in_file );
407                     exit( 1 );
408                 }
409                 targ_file = OutputGpf.in_file ;
410                 new_target = 1 ;
411                 close( chk_fd );
412             }else{
413                 USAGE2("%s : It is not possible to refer to the substance of the font file. \"%s\"\n", com, OutputGpf.in_file);
414                 exit(1);
415             }
416         }
417         WriteGpf.snf_file = targ_file;
418
419         if ( ( chk_fd = open( targ_file, O_RDWR ) ) < 0  ) {
420             USAGE2("%s : The font file of substance \"%s\" cannot be opened.\n", com , targ_file );
421             exit( 1 );
422         }
423         if ( isLock( chk_fd ) == 1 ) {
424             USAGE2("%s : \"%s\" is opened by other application. \n", WriteGpf.snf_file, com );
425             close( chk_fd );
426             exit( 1 );
427         }
428         close( chk_fd );
429
430         /*****************************************************************
431         * set code category to inner structure
432         *****************************************************************/
433
434         WriteGpf.start_code     = MIN_CODE;
435         WriteGpf.end_code       = MAX_CODE;
436         WriteGpf.code_category  = ALL_CODE;
437
438         COMM_SBFNT_SETUDCAREA( argv[0], OutputGpf, char_set, code_area, num_gr, gr ) ;
439
440         /*
441          * CpyGpfInit() 
442          *
443          * GPFTOBDF, BDFTOGPF
444          *
445          *  (InputGpf.in_file)  --> GPFTOBDF ==H 
446          *                                     H
447          *  (OutputGpf.in_file) --> GPFTOBDF ==H 
448          *                                     H
449          *                                  dtcpgpf
450          *                                     H
451          * (WriteGpf.out_file) <--  BDFTOGPF ==H
452          *
453          */
454
455         signal( SIGHUP , (void(*)())sigint_out );
456         signal( SIGINT , (void(*)())sigint_out );
457         signal( SIGQUIT, (void(*)())sigint_out );
458         signal( SIGTERM, (void(*)())sigint_out );
459
460         if ( rtn = CpyGpfInit( &InputGpf, &OutputGpf, &WriteGpf, type ) ) {
461             if ( WriteGpf.out_file ) {
462                 Unlink_Tmpfile( WriteGpf.out_file, com );
463             }
464             put_error_and_exit( &InputGpf, &WriteGpf, rtn, com );
465         }
466
467         /* read copy origin */
468         if ( (rtn = readGpf( &InputGpf, readbuf, startcode, endcode, num_gr, gr )) ){
469             if ( WriteGpf.out_file ) {
470                 Unlink_Tmpfile( WriteGpf.out_file, com );
471             }
472             put_error_and_exit( &InputGpf, &WriteGpf, rtn, com );
473         }
474         fclose( InputGpf.input );
475
476         /* read copy target */
477         if( (rtn = readBdfHeaderAndPut(&OutputGpf, &WriteGpf, readbuf)) ) {
478             if ( WriteGpf.out_file ) {
479                 Unlink_Tmpfile( WriteGpf.out_file, com );
480             }
481             put_error_and_exit( &InputGpf, &WriteGpf, rtn, com );
482         }
483         fclose( OutputGpf.input );
484         wait( 0 );
485
486         /*
487          * write SNF output file
488          */
489         if ( ( rtn = writeGpf( &InputGpf, &OutputGpf, &WriteGpf ) ) ) {
490             if ( WriteGpf.out_file ) {
491                 Unlink_Tmpfile( WriteGpf.out_file, com );
492             }
493             put_error_and_exit( &InputGpf, &WriteGpf, rtn, com );
494         }
495
496 #ifdef ROOT_ONLY
497         if ( pclose( WriteGpf.output ) ) {
498                 Unlink_Tmpfile( WriteGpf.out_file, com );
499                 put_error_and_exit( &InputGpf, &WriteGpf, PCLOSE_ERROR, com );
500         }
501 #else
502         fclose( WriteGpf.output );
503         wait( &exit_stat );
504 #if !defined( SVR4 ) && !defined( SYSV )
505         if ( !WIFEXITED(exit_stat) ) {
506 #else
507         if ( ! ( WIFEXITED(exit_stat) && !WEXITSTATUS(exit_stat) ) ) {
508 #endif
509                 USAGE3("%s: The error occurred by %s (%08x).\n", com, oakgtobdf, exit_stat);
510                 Unlink_Tmpfile( WriteGpf.out_file, com );
511                 put_error_and_exit( &InputGpf, &WriteGpf, FATAL_ERROR, com );
512         }
513 #endif
514         signal( SIGHUP , SIG_IGN );
515         signal( SIGINT , SIG_IGN );
516         signal( SIGQUIT, SIG_IGN );
517         signal( SIGTERM, SIG_IGN );
518
519         sleep( 1 );
520         if ( ( stat( WriteGpf.out_file, &statbuf ) ) || ( statbuf.st_size == 0 )
521             ) {
522                 Unlink_Tmpfile( WriteGpf.out_file, com );
523                 put_error_and_exit( &InputGpf, &WriteGpf, BDF_WRITE, com );
524         }
525         if ( stat( WriteGpf.snf_file, &statbuf ) ) {
526                 Unlink_Tmpfile( WriteGpf.out_file, com );
527                 exit( 1 );
528         }
529         exit_code = Make_NewFefFile( WriteGpf.snf_file, WriteGpf.out_file,
530             FONT_FILE_PARM, (uid_t)statbuf.st_uid, (gid_t)statbuf.st_gid, com ) ;
531
532         if( !exit_code ){
533             if( *create_font != '\0' && new_target )
534                 fprintf( stdout, "%s : New font <%s> is created.\n", com, create_font );
535         }
536         exit( exit_code );
537 }
538
539
540 static  int
541 getGpfFileName( com, gpfinf, code_area, code_no, xlfdname, snf_file, style )
542 char    *com ;
543 struct  btophead        *gpfinf ;
544 int     code_area ;
545 int     code_no ;
546 char    *xlfdname ;
547 char    *snf_file ;
548 char    *style ;
549 {
550
551
552         if ( gpfinf->in_file == NULL && xlfdname == NULL ) {
553             if ( code_area & SYSTM ) {
554                 USAGE1("%s : The GPF output file name cannot be omitted.\n", com );
555             } else {    /* string of charcter size */
556                 USAGE1("%s : The character size specification cannot be omitted.\n", com );
557             }
558             return -1 ;
559         }
560
561         /* open GPF file */
562         if ( !(code_area & SYSTM) ) {
563             if( xlfdname ) {
564                 if ( GetUdcFileName( com, code_no, xlfdname, snf_file ) ) {
565                     USAGE2("%s : Failed to get font file.( XLFD: %s ) Terminates abnormally.\n", com, xlfdname );
566                     return -1 ;
567                 }
568                 gpfinf->in_file = snf_file ;
569             } else {
570
571                 switch ( GetFileName( com, gpfinf->in_file, style, code_no, snf_file ) ) {
572                 case 0:
573                         gpfinf->in_file = snf_file;
574                         break;
575                 case -1:
576                         return -1 ;
577                 default:
578                         USAGE1("%s : The font file name cannot be obtained. Terminates abnormally.\n", com);
579                         return -1 ;
580                 }
581             }
582         }
583
584         return 0 ;
585 }
586
587
588 static 
589 CpyGpfInit(i_gpf, o_gpf, w_gpf, type )
590 struct btophead *i_gpf;
591 struct btophead *o_gpf;
592 struct ptobhead *w_gpf;
593 int             type ;
594 {
595         FontInfoRec     *finf;
596         int     ifd[2], ofd[2], snf_fd, permission;
597         char    buf[BUFSIZE];
598 #ifdef ROOT_ONLY
599         char    command[BUFSIZE], *ep ;
600 #else
601         int     pfd[2], out_fd ;
602 #endif
603
604         /* SNF format */
605         if( !new_target ){
606             if ( ChkPcfFontFile( w_gpf->snf_file ) ) {
607                 permission = 0 ;
608                 if( (snf_fd = open( w_gpf->snf_file, O_RDONLY ) ) >= 0 ) {
609                     COMM_SNF_FILEVERSION( snf_fd, finf, buf, permission ) ;
610                     if ( permission < 0 ) {
611                         return BDF_INVAL;
612                     }
613                 } else {
614                     return BDF_OPEN_IN;
615                 }
616             }
617         }else{
618             COMM_SNF_NEWTARGET( permission ) ;
619         }
620
621         /* open pipe for copy origin gpf */
622         if (pipe(ifd) != 0) {
623                 return  PIPE_ERROR;
624         }
625         switch ( fork() ) {
626         case    0:
627                 close( ifd[0] );
628                 close( 1 );
629                 if ( dup( ifd[1] ) < 0 ) {
630                     return      DUP_ERROR;
631                 }
632                 close( ifd[1] );
633                 /* SNFTOBDF */
634                 execl( oakgtobdf, oakgtobdf, i_gpf->in_file, 0 );
635                 return  EXEC_ERROR;
636         case    -1:
637                 return  FORK_ERROR;
638         default:
639                 break;
640         }
641         close( ifd[1] );
642         if ( ( i_gpf->input = fdopen( ifd[0], "r" ) ) == NULL ) {
643                 return  FDOPEN_ERROR;
644         }
645
646         /* open pipe for copy target gpf */
647         if (pipe(ofd) != 0) {
648                 return  PIPE_ERROR;
649         }
650         switch ( fork() ) {
651         case    0:
652                 close( ofd[0] );
653                 close( 1 );
654                 if ( dup( ofd[1] ) < 0 ) {
655                     return      DUP_ERROR;
656                 }
657                 close( ofd[1] );
658                 /* SNFTOBDF */
659                 if( !new_target ){
660                     execl( oakgtobdf, oakgtobdf, o_gpf->in_file, "-H", 0 );
661                 }else{
662                     execl( oakgtobdf, oakgtobdf, i_gpf->in_file, "-H", 0 );
663                 }
664                 return  EXEC_ERROR;
665         case    -1:
666                 return  FORK_ERROR;
667         default:
668                 break;
669         }
670         close( ofd[1] );
671         if ( ( o_gpf->input = fdopen( ofd[0], "r" ) ) == NULL ) {
672                 return  FDOPEN_ERROR;
673         }
674
675         /* open pipe for target gpf */
676         if ( !( w_gpf->out_file = GetTmpPath( targ_file ) ) ) {
677                 return  MKTMP_ERROR;
678         }
679
680 #ifdef ROOT_ONLY
681         if( ChkPcfFontFile( w_gpf->snf_file ) == 0 ) {
682                 sprintf(command, "%s > %s", bdftopcf, w_gpf->out_file) ;
683         } else {
684                 COMM_SNF_POPEN( permission, w_gpf->snf_file, w_gpf->out_file, ep, buf, command ) ;
685         }
686         if ((w_gpf->output = popen(command, "w")) == NULL) {
687                 return(POPEN_ERROR);
688         }
689 #else   /* ROOT_ONLY */
690         if ( pipe( pfd ) != 0 ) {
691                 return  PIPE_ERROR;
692         }
693         switch ( fork() ) {
694         case    0:
695             if ( ( out_fd = open( w_gpf->out_file, O_WRONLY | O_CREAT, 0664 ) ) < 0 ) {
696                 return  BDF_OPEN_OUT;
697             }
698             close( 0 );
699             if ( dup(pfd[0]) < 0 ) {
700                 return  DUP_ERROR;
701             }
702             close( pfd[0] );
703             close( pfd[1] );
704             close( 1 );
705             if( dup( out_fd ) < 0 ) {
706                 close( out_fd );
707                 return  DUP_ERROR;
708             }
709             close( out_fd );
710             /* pcf format */
711             if ( ChkPcfFontFile( w_gpf->snf_file ) == 0 ) {
712                 execl( bdftopcf, bdftopcf, 0 );
713                 return  PCFFONTC_ERROR;
714             }
715             /* snf format */
716             if( type )  permission = type ;
717             COMM_SNF_EXECLBDFTOSNF( permission, buf, w_gpf->snf_file ) ;
718             return SNFFONTC_ERROR;
719
720         case    -1:
721             return FORK_ERROR;
722         default:
723                 break;
724         }
725         close( pfd[0] );
726         if ( ( w_gpf->output = fdopen( pfd[1], "w" ) ) == NULL ) {
727             return      FDOPEN_ERROR;
728         }
729 #endif  /* ROOT_ONLY */
730         return  0;
731 }
732
733
734
735 static  int
736 readGpf(i_gpf, buf, startcode, endcode, num_gr, gr)
737 struct btophead *i_gpf;
738 char            *buf;
739 int             startcode ;
740 int             endcode ;
741 FalGlyphRegion  *gr ;
742 {
743         int     nchar, rtn;
744
745         if ( ( rtn = ReadBdfHeader( i_gpf, buf ) ) ) {
746             return rtn;
747         }
748
749         nchar = i_gpf->num_chars ;
750
751         if ( ( i_gpf->code = (int *)malloc( sizeof(int) * nchar ) ) == NULL ) {
752             return MALLOC_ERROR;
753         }
754
755         if ( ( i_gpf->ptn = (char **)malloc( sizeof(char *) * nchar ) ) == NULL ) {
756             return MALLOC_ERROR;
757         }
758
759         return  readBdfToMemory( i_gpf, buf, startcode, endcode, num_gr, gr ) ;
760 }
761
762
763
764 static  int
765 readBdfHeaderAndPut(o_gpf, w_gpf, buf)
766 struct btophead *o_gpf;
767 struct ptobhead *w_gpf;
768 char            *buf;
769 {
770         FILE    *fp ;
771         char    *p;
772         int     getstat, zoom, property ;
773
774         getstat = zoom = property = 0 ;
775
776         if( o_gpf->p_width || o_gpf->p_height ){
777             zoom = 1 ;
778         }
779         if ( (fp = fopen( w_gpf->out_file, "w" )) == NULL ) {
780             return BDF_OPEN_HEAD ;
781         }
782
783         while ( 1 ) {
784                 if ( fgets( buf, BUFSIZE, o_gpf->input ) == NULL ) {
785                         fclose(fp) ;
786                         return  BDF_INVAL;
787                 }
788                 p = buf;
789                 SCAN_TO_NONSP( p )
790                 if ( !strncmp( p, SIZE, strlen( SIZE ) ) ) {
791                         if ( ( sscanf( p, "SIZE %f%d",
792                             &(o_gpf->bdf_point), &(o_gpf->bdf_xdpi))) != 2 ) {
793                                 fclose(fp) ;
794                                 return  BDF_INVAL;
795                         }
796                         fprintf( fp, "%s", buf );
797                         getstat |= 0x01;
798
799                 } else if ( !strncmp( p, FONTBOUNDINGBOX, strlen( FONTBOUNDINGBOX ) ) ) {
800                         if ( ( sscanf( p, "FONTBOUNDINGBOX %d%d%d%d",
801                             &(o_gpf->bdf_width), &(o_gpf->bdf_height),
802                             &(o_gpf->bdf_x), &(o_gpf->bdf_y) )) != 4) {
803                                 fclose(fp) ;
804                                 return  BDF_INVAL;
805                         }
806                         /* -width / -height */
807                         if( zoom ){
808                             /* -width / -height */
809                             if( o_gpf->p_width )  o_gpf->bdf_width  = o_gpf->p_width ;
810                             if( o_gpf->p_height ) o_gpf->bdf_height = o_gpf->p_height ;
811                             fprintf( fp, "FONTBOUNDINGBOX %d %d %d %d\n",
812                                 o_gpf->bdf_width, o_gpf->bdf_height,
813                                 o_gpf->bdf_x, o_gpf->bdf_y );
814                         }else{
815                             fprintf( fp, "%s", buf );
816                         }
817                         getstat |= 0x02;
818
819                 } else if ( !strncmp( p, "ENDPROPERTIES", strlen( "ENDPROPERTIES" ) ) ) {
820                         fprintf( fp, "%s", buf );
821                         fclose(fp) ;
822                         getstat |= 0x04;
823                         break;
824                 } else {
825
826                     if( zoom ){
827                         if ( !strncmp( p, "STARTPROPERTIES", strlen( "STARTPROPERTIES" ) ) ) {
828                             property = 1 ;
829                             fprintf( fp, "%s", buf );
830                         } else if ( !strncmp( p, "FONT ", strlen( "FONT " ) ) ) {
831                             char        font[BUFSIZE] ;
832                             if( property ){
833                                 if( (sscanf( buf, "FONT \"%s\"", font )) != 1 ){
834                                     fclose(fp) ;
835                                     return      BDF_INVAL;
836                                 }
837                                 MkFontProp( o_gpf->bdf_height, font, create_font ) ;
838                                 fprintf( fp, "FONT \"%s\"\n", create_font ) ;
839                             }else{
840                                 if( (sscanf( buf, "FONT %s", font )) != 1 ){
841                                     fclose(fp) ;
842                                     return      BDF_INVAL;
843                                 }
844                                 MkFontProp( o_gpf->p_height, font, create_font ) ;
845                                 fprintf( fp, "FONT %s\n", create_font ) ;
846                             }
847                         } else if ( !strncmp( p, "PIXEL_SIZE ", strlen( "PIXEL_SIZE " ) ) ) {
848                             fprintf( fp, "PIXEL_SIZE %d\n", o_gpf->bdf_height ) ;
849                         } else if ( !strncmp( p, "AVERAGE_WIDTH ", strlen( "AVERAGE_WIDTH " ) ) ) {
850                             fprintf( fp, "AVERAGE_WIDTH %d\n", o_gpf->bdf_height*10 ) ;
851                         } else if ( !strncmp( p, "POINT_SIZE ", strlen( "POINT_SIZE " ) ) ) {
852                             fprintf( fp, "POINT_SIZE %d\n", o_gpf->bdf_height*10 );
853                         } else if ( !strncmp( p, "RESOLUTION ", strlen( "RESOLUTION " ) ) ) {
854                             int resol ;
855                             if( (sscanf( buf, "RESOLUTION %d\n", &resol )) != 1 ){
856                                 fclose(fp) ;
857                                 return  BDF_INVAL;
858                             }
859                             fprintf( fp, "RESOLUTION %d\n", (int)((resol<0)?DEF_RESOLUTION:resol) );
860                         } else if ( !strncmp( p, "X_HEIGHT ", strlen( "X_HEIGHT " ) ) ) {
861                             fprintf( fp, "X_HEIGHT %d\n", o_gpf->bdf_height );
862                         } else if ( !strncmp( p, "QUAD_WIDTH ", strlen( "QUAD_WIDTH " ) ) ) {
863                             fprintf( fp, "QUAD_WIDTH %d\n", o_gpf->bdf_width );
864                         } else if ( !strncmp( p, "FONT_ASCENT ", strlen( "FONT_ASCENT " ) ) ) {
865                             fprintf( fp, "FONT_ASCENT %d\n", (o_gpf->bdf_height + o_gpf->bdf_y) );
866                         } else if ( !strncmp( p, "FONT_DESCENT ", strlen( "FONT_DESCENT " ) ) ) {
867                             fprintf( fp, "FONT_DESCENT %d\n", -(o_gpf->bdf_y) );
868                         } else if ( !strncmp( p, "DEFAULT_CHAR ", strlen( "DEFAULT_CHAR " ) ) ) {
869                             fprintf( fp, "DEFAULT_CHAR %d\n", ((firstRow << 8) + firstCol) );
870                         } else {
871                             fprintf( fp, "%s", buf );
872                         }
873                     } else {    /* zoom */
874                         fprintf( fp, "%s", buf );
875                     }
876                 }
877
878         }       /* while loop */
879         fclose(fp) ;
880         if ( getstat != 0x07 ) {
881                 return  BDF_INVAL;
882         }
883
884         return  0;
885 }
886
887
888 static 
889 writeGpf( i_gpf, o_gpf, w_gpf )
890 struct btophead *i_gpf;
891 struct btophead *o_gpf;
892 struct ptobhead *w_gpf;
893 {
894         FILE    *fp ;
895         char    rdbuf[BUFSIZE] ;
896
897         /* put BDF header from temporary file */
898         if ( (fp = fopen( w_gpf->out_file, "r" )) == NULL ) {
899             return BDF_OPEN_HEAD ;
900         }
901         while( fgets( rdbuf, BUFSIZE, fp ) != (char *)NULL ){
902             fprintf( w_gpf->output, "%s", rdbuf ) ;
903         }
904         if( feof(fp) != 0 ){
905             fclose(fp) ;
906         }else{
907             fclose(fp) ;
908             return BDF_READ_HEAD ;
909         }
910
911         /* set specified width or height */
912         w_gpf->bdf_width        = o_gpf->bdf_width ;
913         w_gpf->bdf_height       = o_gpf->bdf_height ;
914         w_gpf->bdf_x            = o_gpf->bdf_x;
915         w_gpf->bdf_y            = o_gpf->bdf_y;
916         w_gpf->bdf_point        = o_gpf->bdf_point;
917         w_gpf->bdf_xdpi         = o_gpf->bdf_xdpi;
918
919         w_gpf->p_width          = i_gpf->bdf_width;
920         w_gpf->p_height         = i_gpf->bdf_height;
921
922         if( w_gpf->bdf_width != w_gpf->p_width ||
923             w_gpf->bdf_height != w_gpf->p_height ) {
924             w_gpf->zoomf = 1;
925         }else{
926             w_gpf->zoomf = 0;
927         }
928
929         w_gpf->num_chars        = i_gpf->num_chars;
930         w_gpf->code             = i_gpf->code;
931         w_gpf->ptn              = i_gpf->ptn;
932
933         return  WritePtnToBdf( w_gpf );
934 }
935
936
937
938 static int
939 check_width( prog_name, len_str )
940 char    *prog_name;
941 char    *len_str;
942 {
943         return( check_width_height( prog_name, len_str, 0) );
944 }
945
946
947 static int
948 check_height( prog_name, len_str )
949 char    *prog_name;
950 char    *len_str;
951 {
952         return( check_width_height( prog_name, len_str, 1) );
953 }
954
955 static int
956 check_width_height( prog_name, len_str, mode )
957 char    *prog_name;
958 char    *len_str;
959 int     mode;           /* width ... 0 , height ... 1 */
960 {
961         int             ret;
962         char    *tmp;
963
964         ret = (int)strtol( len_str, &tmp, 10 ); /* <-- ret = atoi( len_str ) */
965         if ((tmp == len_str) || (ret < MIN_FONT_WIDTH) || (ret > MAX_FONT_WIDTH)) {
966                 switch( mode ) {
967                 case 0:
968                         USAGE2("%s : The specification of the character width is improper.\"%s\"¡¥\n",
969                             prog_name, len_str);
970                         break;
971                 case 1:
972                         USAGE2("%s : The specification of the character height is improper.\"%s\"¡¥\n",
973                             prog_name, len_str);
974                         break;
975                 default:
976                         break;
977                 }
978                 return(0);
979         }
980         return( ret );
981 }
982
983
984
985 static  int
986 check_code( prog_name, code_str, mode, charset, num_gr, gr )
987 char    *prog_name;
988 char    *code_str;
989 int     mode;           /* start_code ... 0, end_code ... 1 */
990 char    *charset ;
991 int     num_gr ;
992 FalGlyphRegion  *gr ;
993 {
994         int             err_flg = 0;
995         int             code_num;
996         char    *tmp;
997         FalGIInf        *gi ;
998         int             num_gi ;
999         int             i, code ;
1000
1001         code = (int)strtol(code_str, &tmp, 16);
1002         if ( tmp == code_str ) {
1003             err_flg = 1;
1004         }
1005
1006         if( COMM_SBFNT_ISSBFNT( charset ) ) {
1007             code_num = code ;
1008             CONVGLYPHINDEX( code_num ) ;
1009         } else {
1010             if( fal_code_to_glyph( locale, code, &gi, &num_gi) ) {
1011                 USAGE2("%s : Failed to convert code point into glyph index.\"%s\" \n", prog_name, code_str ) ;
1012                 err_flg = 1;
1013             }
1014             if( num_gi==1 ){
1015                 code_num = gi[0].glyph_index ;
1016                 err_flg = 0 ;
1017             }else{
1018                 for( i=0; i<num_gi; i++ ) {
1019                     if( !strcmp( gi[i].charset_str, char_set ) ) {
1020                         code_num = gi[i].glyph_index ;
1021                         err_flg = 0 ;
1022                         break ;
1023                     } else              err_flg = 1 ;
1024                 }
1025             }
1026         }
1027         if( !err_flg ) {
1028             for( i=0; i<num_gr; i++ ) {
1029                 if( (code_num >= gr[i].start) && (code_num <= gr[i].end) )
1030                     return( code_num );
1031             }
1032             err_flg = 1 ;
1033         }
1034         if (err_flg) {
1035             switch( mode ) {
1036             case 0:
1037                 USAGE2("%s : The specification of the extract start code is improper.\"%s\"¡¥\n",
1038                     prog_name, code_str);
1039                 break;
1040             case 1:
1041                 USAGE2("%s : The specification of the extract end code is improper.\"%s\"¡¥\n",
1042                     prog_name, code_str);
1043                 break;
1044             default:
1045                 USAGE2("%s : The specification of the extract code is improper.\"%s\"¡¥\n",
1046                     prog_name, code_str);
1047             }
1048             return(-1);
1049         }
1050         return(-1);
1051
1052 }
1053
1054
1055
1056 static  int
1057 readBdfToMemory(head, buf, startcode, endcode, num_gr, gr)
1058 struct btophead *head;
1059 char   *buf;
1060 int     startcode ;
1061 int     endcode ;
1062 int     num_gr ;
1063 FalGlyphRegion  *gr ;
1064 {
1065         int         code, mwidth, num_char, bsize, rtn;
1066         char    *ptn;
1067
1068         num_char = 0;
1069         mwidth = (head->bdf_width + 7) / 8;
1070         bsize = mwidth * head->bdf_height;
1071         while(1) {
1072             if ((rtn = GetBdfCode(head, buf, &code)) < 0) {
1073                 return(rtn);    /* contain BDF_INVAL */
1074             } else if (rtn == FILE_END) {
1075                 head->num_chars = num_char;
1076                 break;
1077             }
1078             if ( !IsInRegion( code, num_gr, gr ) &&
1079                 ( startcode > code || endcode < code )
1080             ){
1081                 continue;
1082             }
1083             getDefaultCh( (unsigned int)code ) ;
1084
1085             head->code[num_char] = code;
1086             if ( ( ptn = head->ptn[num_char++] = (char *)malloc( bsize ) ) == NULL ) {
1087                 return(MALLOC_ERROR);
1088             }
1089             if ((rtn = GetBdfPtn(head, buf, ptn, mwidth, bsize)) != 0) {
1090                 return(rtn);
1091             }
1092         }
1093         return(0);
1094 }
1095
1096
1097 static  void
1098 getDefaultCh( code )
1099 unsigned int    code ;
1100 {
1101         unsigned int    cbuf ;
1102         cbuf = code ;
1103         if( (cbuf & 0xff) < firstCol )  firstCol = cbuf & 0xff ;
1104         if( (cbuf >> 8)   < firstRow )  firstRow = cbuf >> 8 ;
1105         if( (cbuf & 0xff) > lastCol )   lastCol = cbuf & 0xff ;
1106         if( (cbuf >> 8)   > lastRow )   lastRow = cbuf >> 8 ;
1107 }
1108
1109
1110 static  int
1111 cpg_atoi( numstr )
1112 char    *numstr ;
1113 {
1114         int     val ;
1115         char    *ep, *cbuf ;
1116
1117         ep = (char *)strchr( numstr, '\0' ) ;
1118         val = (int)strtol( numstr, &cbuf, 10 ) ;
1119         if ( cbuf == numstr || cbuf != ep ) {
1120             return -1 ;
1121         }
1122         return val ;
1123 }
1124
1125 static  int
1126 is_in_udcregion( start, end, num_gr, gr ) 
1127 int     start, end, num_gr ;
1128 FalGlyphRegion  *gr ;
1129 {
1130         int     i ;
1131         if( start < gr[0].start && end < gr[0].start ){
1132             return -1 ;
1133         }
1134         for( i=0; i<num_gr-1; i++ ){
1135             if( (start > gr[i].end && start < gr[i+1].start )
1136              && (end > gr[i].end && end < gr[i+1].start )
1137             )
1138             return -1 ;
1139         }
1140         if( start > gr[num_gr-1].end && end > gr[num_gr-1].end ){
1141             return -1 ;
1142         }
1143         return 0 ;
1144 }
1145
1146
1147 static  void
1148 MkFontProp(font_height, font, output)
1149 int             font_height ;
1150 char            *font;
1151 char            *output;
1152 {
1153         char    fbuf[BUFSIZE], split[BUFSIZE] ;
1154         char    *ep, *pix_sz, *point_sz, *rsl_x, *av_width, *char_set ;
1155
1156         snprintf( fbuf, sizeof(fbuf), "%s", font ) ;
1157         snprintf( split, sizeof(split), "%s", font ) ;
1158         ep = fbuf ;
1159         ep += strlen( fbuf ) ;
1160         ep-- ;
1161         if( *ep == '"' )        *ep = '\0' ;
1162         POINTXLFDELM( pix_sz, fbuf, XLFD_ELM_PIXEL_SIZE ) ;
1163         POINTXLFDELM( point_sz, split, XLFD_ELM_POINT_SIZE ) ;
1164         POINTXLFDELM( rsl_x, split, XLFD_ELM_RESOLUTION_X ) ;
1165         POINTXLFDELM( av_width, split, XLFD_ELM_AVERAGE_WIDTH ) ;
1166         POINTXLFDELM( char_set, fbuf, XLFD_ELM_CHARSET_REGISTRY ) ;
1167         *pix_sz = '\0' ;
1168         *av_width = '\0' ;
1169
1170         sprintf(output, "%s-%d-%s-%d%s", fbuf,
1171                         font_height,    /* pixel size */
1172                         rsl_x,
1173                         font_height*10, /* average width */
1174                         char_set );
1175 }
1176
1177
1178
1179 static  void
1180 put_error_and_exit(ptob_in, ptob_out, er_no, prog_name)
1181 struct btophead *ptob_in;
1182 struct ptobhead *ptob_out;
1183 int     er_no;
1184 char    *prog_name;
1185 {
1186         ErrMsgTable_AndExit( er_no, ptob_in->in_file, ptob_out->out_file,
1187             NULL, NULL, NULL, prog_name );
1188         return;
1189 }
1190
1191
1192
1193 static  void
1194 put_help( prog_name )
1195 char    *prog_name;
1196 {
1197         USAGE1("Usage: %s -ixlfd oxlfd  -oxlfd oxlfd\n", prog_name);
1198         USAGE("\t[in_character_size][out_character_size]\n");
1199         USAGE("\t[-start start_code][-end end_code]\n");
1200         USAGE("\t[-istyle ostyle][-ostyle ostyle]");
1201         COMM_HELP_MSG ;
1202         USAGE1("%s can copy glyphs of gpf file in the following code area.\n", prog_name);
1203         USAGE("codeset \t\tcode area\n");
1204         USAGE("----------------------------------------\n");
1205         DispUdcCpArea() ;
1206         USAGE("If the -start and -end option is omitted, the start/end code of each extractive area is specified.\n");
1207         USAGE("The xlfd name and character size may be obtained using dtlsgpf command.\n");
1208         return;
1209 }
1210