2
0

addcpf.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  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: addcpf.c /main/9 1996/11/08 02:00:29 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. #include <stdio.h>
  31. #include <locale.h>
  32. #include <fcntl.h>
  33. #include <signal.h>
  34. #include <sys/types.h>
  35. #include <sys/stat.h>
  36. #ifndef SVR4
  37. #if !defined( SYSV )
  38. #include <sys/resource.h>
  39. #endif
  40. #include <sys/wait.h>
  41. #else
  42. #include <wait.h>
  43. #endif
  44. #include <unistd.h>
  45. #include <string.h>
  46. #include <stdlib.h>
  47. #include "bdfgpf.h"
  48. #include <X11/Xmd.h>
  49. #include <X11/Xproto.h>
  50. #include <X11/fonts/fontstruct.h>
  51. #include "FaLib.h"
  52. #include "snfstruct.h"
  53. #include "udcutil.h"
  54. #include <errno.h>
  55. static int rw_init(struct ptobhead *r_gpf,
  56. struct btophead *r_snf,
  57. struct ptobhead *w_snf,
  58. int init_all);
  59. static int readSnf(struct ptobhead *r_gpf,
  60. struct btophead *r_snf,
  61. struct ptobhead *w_snf,
  62. char *buf);
  63. static int readSnf_with_init(struct ptobhead *r_gpf,
  64. struct btophead *r_snf,
  65. struct ptobhead *w_snf,
  66. int init,
  67. char *buf,
  68. int num_gr,
  69. FalGlyphRegion *gr);
  70. static int readSnfHeader(struct ptobhead *r_gpf,
  71. struct btophead *r_snf,
  72. struct ptobhead *w_snf,
  73. char *buf) ;
  74. static int readBdfHeaderAndPut(struct btophead *r_snf,
  75. struct ptobhead *w_snf,
  76. char *buf) ;
  77. static int mergePtn(char *com,
  78. struct ptobhead *r_gpf,
  79. struct btophead *r_snf,
  80. char *buf,
  81. int code_area,
  82. int modify,
  83. char *prog_name,
  84. int num_gr,
  85. FalGlyphRegion *gr,
  86. int code_no) ;
  87. static int ModifyPtn(struct ptobhead *r_gpf,
  88. struct btophead *r_snf,
  89. char *buf,
  90. int ix);
  91. static int InsertPtn(struct ptobhead *r_gpf,
  92. struct btophead *r_snf,
  93. char *buf,
  94. int code,
  95. int ix);
  96. static int writeSnf(struct btophead *r_snf, struct ptobhead *w_snf) ;
  97. static void put_error_and_exit(struct ptobhead *ptob_in,
  98. struct btophead *btop,
  99. struct ptobhead *ptob_out,
  100. int er_no,
  101. char *prog_name);
  102. static void put_help(char *prog_name);
  103. static int readBdfToMemory_with_init(struct btophead *head,
  104. int init,
  105. char *buf,
  106. int num_gr,
  107. FalGlyphRegion *gr);
  108. extern int fal_glyph_to_code(char *locale,
  109. char *charset_str,
  110. int codeset,
  111. unsigned long glyph_index,
  112. unsigned long *codepoint);
  113. static struct ptobhead WriteSnf;
  114. static char *targ_file = NULL; /* UDC_file_name */
  115. static char *com = NULL; /* command_name */
  116. static char *spacing ;
  117. static char *char_set ;
  118. static char *util_locale ;
  119. static pid_t gtob_pid = 0;
  120. static pid_t btop_pid = 0;
  121. #if defined( SVR4 ) || defined( SYSV ) || defined(CSRG_BASED) || \
  122. defined(__linux__)
  123. static int chld_stat ;
  124. #else
  125. static union wait chld_stat ;
  126. #endif
  127. static void
  128. sigint_out(void)
  129. {
  130. if (WriteSnf.out_file) {
  131. Unlink_Tmpfile( WriteSnf.out_file, com );
  132. }
  133. exit( 0 );
  134. }
  135. int main(int argc, char *argv[])
  136. {
  137. int code_area , init, modify, help, no_infile, no_style;
  138. int fupd = 0 ;
  139. int init_all, rtn, i;
  140. #ifndef ROOT_ONLY
  141. int exit_stat;
  142. #endif
  143. struct btophead ReadSnf; /* output file (GPF) */
  144. struct ptobhead ReadGpf; /* input file (CPF) */
  145. struct stat statbuf;
  146. char snf_file[BUFSIZE] ;
  147. char buf[BUFSIZE];
  148. char *style ;
  149. char *xlfdname, *cbuf ;
  150. int chk_fd;
  151. FalGlyphRegion *gr ;
  152. int num_gr ;
  153. char *ep ;
  154. int code_no;
  155. char *codeset = DEFAULT_CODESET;
  156. if( (util_locale = (char *)getenv( "LANG" )) == NULL ){
  157. util_locale = "C" ;
  158. }
  159. ReadSnf.in_file = ReadGpf.in_file = WriteSnf.out_file = NULL;
  160. com = argv[0];
  161. COMM_SETDEFAULTSTYLE( style ) ;
  162. cbuf = xlfdname = ep = '\0' ;
  163. gr = NULL ;
  164. num_gr = 0 ;
  165. spacing = char_set = NULL ;
  166. if (!( bdftopcf = get_cmd_path( getenv( "PATH" ), BDFTOPCF_CMD ))) {
  167. bdftopcf = BDFTOPCF;
  168. }
  169. if (!( oakgtobdf = get_cmd_path( getenv( "PATH" ), SNFTOBDF_CMD ))) {
  170. oakgtobdf = SNFTOBDF;
  171. }
  172. if (!( bdftosnf = get_cmd_path( getenv( "PATH" ), BDFTOSNF_CMD ))) {
  173. bdftosnf = BDFTOSNF;
  174. }
  175. code_area = NORMAL;
  176. init = modify = help = no_infile = no_style = init_all = 0;
  177. for ( i = 1; i < argc; i++ ) {
  178. if ( !strcmp( argv[i], "-g" ) ) {
  179. if ( ( i < argc-1) && (*argv[i+1] != '-' ) ) {
  180. ReadSnf.in_file = argv[++i];
  181. }
  182. } else if ( !strcmp( argv[i], "-p" ) ) {
  183. if ( (i < argc-1) && (*argv[i+1] != '-') ){
  184. ReadGpf.in_file = argv[++i];
  185. } else {
  186. no_infile = 1;
  187. }
  188. } else if ( !strcmp( argv[i], "-init" ) ) {
  189. init = 1;
  190. } else if ( !strcmp( argv[i], "-modify" ) ) {
  191. modify = 1;
  192. } else if ( !strcmp( argv[i], "-system" ) ) {
  193. code_area |= SYSTM;
  194. } else if ( !strcmp( argv[i], "-help" ) ) {
  195. help = 1;
  196. } else if ( !strcmp( argv[i], "-style" ) ) {
  197. if ( ( i < argc-1 ) && ( *argv[i+1] != '-' ) ){
  198. style = argv[++i];
  199. } else {
  200. no_style = 1;
  201. }
  202. } else if ( !strcmp( argv[i], "-codeset" ) ) {
  203. if ( ( i < argc - 1 ) && ( *argv[i+1] != '-' )){
  204. codeset = argv[++i];
  205. COMM_SET_CODESET( codeset, code_area ) ;
  206. }
  207. } else if ( !strcmp( argv[i], "-xlfd" ) ) {
  208. if ( i < argc - 1 ){
  209. xlfdname = argv[++i];
  210. }
  211. } else if ( COMM_SBOPT_STRCMP( argv, i ) ) {
  212. COMM_SBOPT_SETSBOPT( code_area ) ;
  213. } else if ( !strcmp( argv[i], "-f" ) ) {
  214. fupd = 1;
  215. } else {
  216. put_help(argv[0]);
  217. exit( 1 );
  218. }
  219. }
  220. /* help_message */
  221. if ( help == 1 ) {
  222. put_help( argv[0] );
  223. exit( 0 );
  224. }
  225. COMM_SBOPT_CHECKSBOPT( argv[0], code_area ) ;
  226. if ( no_infile ) {
  227. USAGE1("%s : The input file name following -p option cannot be omitted.\n", argv[0] );
  228. exit( 1 );
  229. }
  230. ep = (char *)strchr( codeset, '\0' ) ;
  231. code_no = (int)strtol( codeset, &cbuf, 10 ) ;
  232. if ( cbuf == codeset || cbuf != ep ) {
  233. USAGE2("%s : The codeset number is not right.¡Ê %s ¡Ë\n",
  234. argv[0], codeset );
  235. exit( 1 );
  236. }
  237. if ( no_style ) {
  238. USAGE1("%s : The style is not specified.\n", argv[0] ) ;
  239. exit( 1 );
  240. }
  241. if ( ReadSnf.in_file == NULL && xlfdname == NULL ) {
  242. if ( code_area & SYSTM ) {
  243. USAGE1("%s : The GPF output file name cannot be omitted.\n", argv[0] );
  244. } else { /* string of charcter size */
  245. USAGE1("%s : The character size specification cannot be omitted.\n", argv[0] );
  246. }
  247. exit( 1 );
  248. }
  249. /* open GPF file */
  250. if ( !(code_area & SYSTM) ) {
  251. if( xlfdname ) {
  252. if ( GetUdcFileName( argv[0], code_no, xlfdname, snf_file ) ) {
  253. USAGE1("%s : Failed to get font file. Terminates abnormally.\n", argv[0]);
  254. exit( 1 );
  255. }
  256. ReadSnf.in_file = snf_file ;
  257. } else {
  258. switch ( GetFileName( argv[0], ReadSnf.in_file, style, code_no, snf_file ) ) {
  259. case 0:
  260. ReadSnf.in_file = snf_file;
  261. break;
  262. case -1:
  263. exit(1);
  264. default:
  265. USAGE1("%s : The font file name cannot be obtained. Terminates abnormally.\n", argv[0]);
  266. exit(1);
  267. }
  268. }
  269. if ( GetUdcRegion( argv[0], code_no, ReadSnf.in_file, &num_gr, &gr ) ) {
  270. USAGE1("%s : This font cannot get UDC code region. Terminates abnormally.\n", argv[0]);
  271. exit( 1 );
  272. }
  273. } else {
  274. num_gr = 1 ;
  275. if( (gr = (FalGlyphRegion *)malloc( sizeof(FalGlyphRegion) * num_gr )) == NULL ) {
  276. USAGE1("%s : malloc error. Terminates abnormally.\n", argv[0]);
  277. exit( 1 );
  278. }
  279. gr[0].start = MIN_CODE ;
  280. gr[0].end = MAX_CODE ;
  281. }
  282. /*
  283. * refuse proportional fonts
  284. */
  285. if ( GetUdcFontName( ReadSnf.in_file, NULL, &xlfdname ) ) {
  286. USAGE1("%s : This font cannot get XLFD. Terminates abnormally.\n", argv[0]);
  287. exit( 1 );
  288. }
  289. GETSPACINGSTR( spacing, xlfdname ) ;
  290. if ( !strcmp( "p", spacing ) || !strcmp( "P", spacing ) ) {
  291. USAGE2("%s cannot edit proportional fonts.(SPACING \"%s\")\n", argv[0], spacing );
  292. exit( 1 );
  293. }
  294. GETCHARSETSTR( char_set, xlfdname ) ;
  295. /* get ReadSnf.in_file */
  296. if ((targ_file = GetRealFileName( ReadSnf.in_file )) == NULL){
  297. USAGE2("%s : It was not possible to refer to the substance of the font file. \"%s\"\n", argv[0], ReadSnf.in_file);
  298. exit(1);
  299. }
  300. WriteSnf.snf_file = targ_file;
  301. if ( ( chk_fd = open( targ_file, O_RDWR ) ) < 0 ) {
  302. USAGE2("%s : The font file of substance \"%s\" cannot be opened.\n", argv[0] , targ_file );
  303. exit( 1 );
  304. }
  305. if( !fupd ){
  306. if ( isLock( chk_fd ) == 1 ) {
  307. USAGE1("%s : Editing by other application. \n", argv[0] );
  308. close( chk_fd );
  309. exit( 1 );
  310. }
  311. }
  312. close( chk_fd );
  313. /* We read whole characters from gpf file. */
  314. ReadSnf.start_code = MIN_CODE;
  315. ReadSnf.end_code = MAX_CODE;
  316. ReadSnf.code_category = ALL_CODE;
  317. switch ( code_area ) {
  318. case SYSTM:
  319. ReadGpf.start_code = MIN_CODE;
  320. ReadGpf.end_code = MAX_CODE;
  321. ReadGpf.code_category = ALL_CODE;
  322. break;
  323. case SYSTM | CDSET1 :
  324. ReadGpf.start_code = MIN_CODE;
  325. ReadGpf.end_code = MAX_CODE;
  326. ReadGpf.code_category = ALL_CODE;
  327. break;
  328. default:
  329. COMM_SBFNT_SETUDCAREA( argv[0], ReadGpf, char_set, code_area, num_gr, gr ) ;
  330. }
  331. COMM_SBFNT_CONVCODETOGI( char_set, ReadSnf ) ;
  332. COMM_SBFNT_CONVCODETOGI( char_set, ReadGpf ) ;
  333. signal( SIGHUP , (void(*)())sigint_out );
  334. signal( SIGINT , (void(*)())sigint_out );
  335. signal( SIGQUIT, (void(*)())sigint_out );
  336. signal( SIGTERM, (void(*)())sigint_out );
  337. /*
  338. * rw_init()
  339. *
  340. * GPFTOBDF, BDFTOGPF
  341. *
  342. * (ReadSnf.in_file) --> GPFTOBDF ==H
  343. * H
  344. * dtaddcpf <-- (ReadGpf.in_file)
  345. * H
  346. * (WriteSnf.out_file) <-- BDFTOGPF ==H
  347. *
  348. */
  349. if ( rtn = rw_init( &ReadGpf, &ReadSnf, &WriteSnf, init_all ) ) {
  350. if ( WriteSnf.out_file ) {
  351. Unlink_Tmpfile( WriteSnf.out_file, argv[0] );
  352. }
  353. put_error_and_exit( &ReadGpf, &ReadSnf, &WriteSnf, rtn, argv[0] );
  354. }
  355. if ( rtn = ReadGpfHeader( &ReadGpf, buf ) ) {
  356. if ( WriteSnf.out_file ) {
  357. Unlink_Tmpfile( WriteSnf.out_file, argv[0] );
  358. }
  359. put_error_and_exit( &ReadGpf, &ReadSnf, &WriteSnf, rtn, argv[0] );
  360. }
  361. if ( init_all ) {
  362. /* We read only header of gpf file. */
  363. rtn = readSnfHeader( &ReadGpf, &ReadSnf, &WriteSnf, buf );
  364. } else if ( init ) {
  365. /* We read characters in UDC area from gpf file. */
  366. rtn = readSnf_with_init( &ReadGpf, &ReadSnf, &WriteSnf,
  367. init, buf, num_gr, gr );
  368. } else {
  369. /* We read whole characters from gpf file. */
  370. rtn = readSnf( &ReadGpf, &ReadSnf, &WriteSnf, buf );
  371. }
  372. if ( rtn ) {
  373. if ( WriteSnf.out_file ) {
  374. Unlink_Tmpfile( WriteSnf.out_file, argv[0] );
  375. }
  376. put_error_and_exit( &ReadGpf, &ReadSnf, &WriteSnf, rtn, argv[0] );
  377. }
  378. fclose( ReadSnf.input );
  379. WaitID( gtob_pid, chld_stat ) ;
  380. if ( ( rtn = mergePtn( argv[0], &ReadGpf, &ReadSnf, buf, code_area, modify, argv[0], num_gr, gr, code_no ) ) ) {
  381. if ( WriteSnf.out_file ) {
  382. Unlink_Tmpfile( WriteSnf.out_file, argv[0] );
  383. }
  384. put_error_and_exit( &ReadGpf, &ReadSnf, &WriteSnf, rtn, argv[0] );
  385. }
  386. /* write SNF output file */
  387. if ( ( rtn = writeSnf( &ReadSnf, &WriteSnf ) ) ) {
  388. if ( WriteSnf.out_file ) {
  389. Unlink_Tmpfile( WriteSnf.out_file, argv[0] );
  390. }
  391. put_error_and_exit( &ReadGpf, &ReadSnf, &WriteSnf, rtn, argv[0] );
  392. }
  393. #ifdef ROOT_ONLY
  394. if ( pclose( WriteSnf.output ) ) {
  395. Unlink_Tmpfile( WriteSnf.out_file, argv[0] );
  396. put_error_and_exit( &ReadGpf, &ReadSnf, &WriteSnf, PCLOSE_ERROR, argv[0] );
  397. }
  398. #else
  399. fclose( WriteSnf.output );
  400. WaitID( btop_pid, chld_stat ) ;
  401. #if !defined( SVR4 ) && !defined( SYSV ) && !defined(__FreeBSD__)
  402. if ( !WIFEXITED(chld_stat) ) {
  403. #else
  404. if ( ! ( WIFEXITED(chld_stat) && !WEXITSTATUS(chld_stat) ) ) {
  405. #endif
  406. USAGE4("%s: The error occurred by %s (%08x). Cannot write %s\n",
  407. argv[0], bdftopcf, chld_stat, WriteSnf.out_file);
  408. Unlink_Tmpfile( WriteSnf.out_file, argv[0] );
  409. put_error_and_exit( &ReadGpf, &ReadSnf, &WriteSnf,
  410. FATAL_ERROR, argv[0] );
  411. }
  412. #endif
  413. signal( SIGHUP , SIG_IGN );
  414. signal( SIGINT , SIG_IGN );
  415. signal( SIGQUIT, SIG_IGN );
  416. signal( SIGTERM, SIG_IGN );
  417. if ( ( stat( WriteSnf.out_file, &statbuf ) ) ||
  418. ( statbuf.st_size == 0 )
  419. ) {
  420. Unlink_Tmpfile( WriteSnf.out_file, argv[0] );
  421. put_error_and_exit( &ReadGpf, &ReadSnf, &WriteSnf,
  422. BDF_WRITE, argv[0] );
  423. }
  424. if ( stat( WriteSnf.snf_file, &statbuf ) ) {
  425. Unlink_Tmpfile( WriteSnf.out_file, argv[0] );
  426. exit( 1 );
  427. }
  428. exit( Make_NewFefFile(
  429. WriteSnf.snf_file, WriteSnf.out_file,
  430. FONT_FILE_PARM,
  431. (uid_t)statbuf.st_uid, (gid_t)statbuf.st_gid,
  432. argv[0] ));
  433. }
  434. static
  435. rw_init(
  436. struct ptobhead *r_gpf,
  437. struct btophead *r_snf,
  438. struct ptobhead *w_snf,
  439. int init_all)
  440. {
  441. FontInfoRec *finf;
  442. int fd[2], snf_fd, permission;
  443. char buf[BUFSIZE];
  444. #ifdef ROOT_ONLY
  445. char command[BUFSIZE], *ep ;
  446. #else
  447. int pfd[2], ofd;
  448. #endif
  449. if ( r_gpf->in_file == NULL ) {
  450. r_gpf->input = stdin;
  451. } else {
  452. if ( ( r_gpf->input = fopen(r_gpf->in_file, "r")) == NULL ) {
  453. return GPF_OPEN_IN;
  454. }
  455. }
  456. /* SNF format */
  457. if ( ChkPcfFontFile( w_snf->snf_file ) ) {
  458. if( (snf_fd = open( w_snf->snf_file, O_RDONLY ) ) >= 0 ) {
  459. return BDF_OPEN_IN;
  460. }
  461. }
  462. if (pipe(fd) != 0) {
  463. return PIPE_ERROR;
  464. }
  465. switch (gtob_pid = fork()) {
  466. case 0:
  467. close( fd[0] );
  468. close( 1 );
  469. if ( dup( fd[1] ) < 0 ) {
  470. return DUP_ERROR;
  471. }
  472. close( fd[1] );
  473. /* SNFTOBDF */
  474. execl( oakgtobdf, oakgtobdf, r_snf->in_file, 0 );
  475. return EXEC_ERROR;
  476. case -1:
  477. return FORK_ERROR;
  478. default:
  479. break;
  480. }
  481. close( fd[1] );
  482. if ( ( r_snf->input = fdopen( fd[0], "r" ) ) == NULL ) {
  483. return FDOPEN_ERROR;
  484. }
  485. if ( !( w_snf->out_file = GetTmpPath( targ_file ) ) ) {
  486. return MKTMP_ERROR;
  487. }
  488. #ifdef ROOT_ONLY
  489. if( ChkPcfFontFile( w_snf->snf_file ) == 0 ) {
  490. sprintf(command, "%s > %s", bdftopcf, w_snf->out_file) ;
  491. } else {
  492. COMM_SNF_POPEN( permission, w_snf->snf_file, w_snf->out_file, ep, buf, command ) ;
  493. }
  494. if ((w_snf->output = popen(command, "w")) == NULL) {
  495. return(POPEN_ERROR);
  496. }
  497. #else /* ROOT_ONLY */
  498. if ( pipe( pfd ) != 0 ) {
  499. return PIPE_ERROR;
  500. }
  501. switch (btop_pid = fork()) {
  502. case 0:
  503. if ( ( ofd = open( w_snf->out_file, O_WRONLY | O_CREAT, 0664 ) ) < 0 ) {
  504. return BDF_OPEN_OUT;
  505. }
  506. close( 0 );
  507. if ( dup(pfd[0]) < 0 ) {
  508. return DUP_ERROR;
  509. }
  510. close( pfd[0] );
  511. close( pfd[1] );
  512. close( 1 );
  513. if( dup( ofd ) < 0 ) {
  514. close( ofd );
  515. return DUP_ERROR;
  516. }
  517. close( ofd );
  518. if ( ChkPcfFontFile( w_snf->snf_file ) == 0 ) {
  519. execl( bdftopcf, bdftopcf, 0 );
  520. return PCFFONTC_ERROR;
  521. }
  522. COMM_SNF_EXECLBDFTOSNF( permission, buf, w_snf->snf_file ) ;
  523. return SNFFONTC_ERROR;
  524. case -1:
  525. return FORK_ERROR;
  526. default:
  527. break;
  528. }
  529. close( pfd[0] );
  530. if ( ( w_snf->output = fdopen( pfd[1], "w" ) ) == NULL ) {
  531. return FDOPEN_ERROR;
  532. }
  533. #endif /* ROOT_ONLY */
  534. return 0;
  535. }
  536. static
  537. readSnf(
  538. struct ptobhead *r_gpf,
  539. struct btophead *r_snf,
  540. struct ptobhead *w_snf,
  541. char *buf)
  542. {
  543. int nchar, rtn;
  544. if ( ( rtn = readBdfHeaderAndPut( r_snf, w_snf, buf ) ) ) {
  545. return rtn;
  546. }
  547. nchar = r_snf->num_chars + r_gpf->num_chars;
  548. if ( ( r_snf->code = (int *)malloc( sizeof(int) * nchar ) ) == NULL ) {
  549. return MALLOC_ERROR;
  550. }
  551. if ( ( r_snf->ptn = (char **)malloc( sizeof(char *) * nchar ) ) == NULL ) {
  552. return MALLOC_ERROR;
  553. }
  554. return ReadBdfToMemory( r_snf, buf ) ;
  555. }
  556. static
  557. readSnf_with_init(
  558. struct ptobhead *r_gpf,
  559. struct btophead *r_snf,
  560. struct ptobhead *w_snf,
  561. int init,
  562. char *buf,
  563. int num_gr,
  564. FalGlyphRegion *gr)
  565. {
  566. int nchar, rtn;
  567. if ( ( rtn = readBdfHeaderAndPut( r_snf, w_snf, buf ) ) ) {
  568. return rtn;
  569. }
  570. nchar = r_snf->num_chars + r_gpf->num_chars;
  571. if ( ( r_snf->code = (int *)malloc( sizeof(int) * nchar ) ) == NULL ) {
  572. return MALLOC_ERROR;
  573. }
  574. if ( ( r_snf->ptn = (char **)malloc( sizeof(char *) * nchar ) ) == NULL ) {
  575. return MALLOC_ERROR;
  576. }
  577. return readBdfToMemory_with_init( r_snf, init, buf, num_gr, gr ) ;
  578. }
  579. static
  580. readSnfHeader(
  581. struct ptobhead *r_gpf,
  582. struct btophead *r_snf,
  583. struct ptobhead *w_snf,
  584. char *buf)
  585. {
  586. int rtn;
  587. if ( ( rtn = readBdfHeaderAndPut( r_snf, w_snf, buf ) ) ) {
  588. return rtn;
  589. }
  590. r_snf->num_chars = 0;
  591. if ( ( r_snf->code = (int *)malloc( sizeof(int) * r_gpf->num_chars ) ) == NULL ) {
  592. return MALLOC_ERROR;
  593. }
  594. if ( ( r_snf->ptn = (char **)malloc( sizeof(char *) * r_gpf->num_chars ) ) == NULL ) {
  595. return MALLOC_ERROR;
  596. }
  597. return 0;
  598. }
  599. static
  600. readBdfHeaderAndPut(struct btophead *r_snf, struct ptobhead *w_snf, char *buf)
  601. {
  602. char *p;
  603. int getstat = 0;
  604. while ( 1 ) {
  605. if ( fgets( buf, BUFSIZE, r_snf->input ) == NULL ) {
  606. return BDF_INVAL;
  607. }
  608. p = buf;
  609. SCAN_TO_NONSP( p )
  610. if ( !strncmp( p, SIZE, strlen( SIZE ) ) ) {
  611. if ( ( sscanf( p, "SIZE %f%d",
  612. &(r_snf->bdf_point), &(r_snf->bdf_xdpi))) != 2 ) {
  613. return BDF_INVAL;
  614. }
  615. fprintf( w_snf->output, "%s", buf );
  616. getstat |= 0x01;
  617. } else if ( !strncmp( p, FONTBOUNDINGBOX, strlen( FONTBOUNDINGBOX ) ) ) {
  618. if ( ( sscanf( p, "FONTBOUNDINGBOX %d%d%d%d",
  619. &(r_snf->bdf_width), &(r_snf->bdf_height),
  620. &(r_snf->bdf_x), &(r_snf->bdf_y) )) != 4) {
  621. return BDF_INVAL;
  622. }
  623. fprintf( w_snf->output, "%s", buf );
  624. getstat |= 0x02;
  625. } else if ( !strncmp( p, CHARS, strlen( CHARS ) ) ) {
  626. if ( ( sscanf( p, "CHARS %d", &( r_snf->num_chars ) ) ) != 1 ) {
  627. return BDF_INVAL;
  628. }
  629. getstat |= 0x04;
  630. break;
  631. } else {
  632. fprintf( w_snf->output, "%s", buf );
  633. }
  634. }
  635. if ( getstat != 0x07 ) {
  636. return BDF_INVAL;
  637. }
  638. return 0;
  639. }
  640. #define DispCodePoint( command, char_set, gidx, dspcode, code_no, locale ){\
  641. if( COMM_SBFNT_ISSBFNT( (char_set) ) ){\
  642. dspcode = DISPCODEPOINT( (char_set), (gidx) ) ;\
  643. }else{\
  644. if( fal_glyph_to_code( (locale), (char_set), FALGETFALCODESET((code_no)), (gidx), &(dspcode) ) ){\
  645. USAGE3("%s : Failed to convert glyph index into code point.(0x%x charset: %s)\n", (command), (gidx), (char_set) ) ;\
  646. return -1 ;\
  647. }\
  648. }\
  649. }
  650. static
  651. mergePtn(
  652. char *com,
  653. struct ptobhead *r_gpf,
  654. struct btophead *r_snf,
  655. char *buf,
  656. int code_area,
  657. int modify,
  658. char *prog_name,
  659. int num_gr,
  660. FalGlyphRegion *gr,
  661. int code_no)
  662. {
  663. int code, rtn, msize, i, j;
  664. long unsigned int dspcode;
  665. char *ptn;
  666. if ( ( r_gpf->p_width != r_snf->bdf_width )
  667. || ( r_gpf->p_height != r_snf->bdf_height )
  668. ) {
  669. r_gpf->zoomf = 1;
  670. msize = ( r_gpf->p_width + 7 ) / 8 * r_gpf->p_height;
  671. if ( ( ptn = (char *)malloc( msize ) ) == NULL ) {
  672. return MALLOC_ERROR;
  673. }
  674. r_gpf->ptn = &ptn;
  675. } else {
  676. r_gpf->zoomf = 0;
  677. }
  678. for ( i = 0; i < r_gpf->num_chars; i++ ) {
  679. if ( ( rtn = GetGpfCode( r_gpf, buf, &code ) ) < 0 ) {
  680. return rtn;
  681. } else if ( rtn == FILE_END ) {
  682. break;
  683. }
  684. if( COMM_SBFNT_ISSBFNT( char_set ) ) CONVGLYPHINDEX( code ) ;
  685. if (
  686. ( code < r_gpf->start_code) || ( code > r_gpf->end_code )
  687. ||( !IN_CODE( r_gpf->code_category, SHIFT_ON( code ) ) )
  688. ||(
  689. (r_gpf->code_category == ALL_CODE) &&
  690. !( code_area & SYSTM ) &&
  691. IsInRegion( code, num_gr, gr )
  692. )
  693. ) {
  694. DispCodePoint( com, char_set, code, dspcode, code_no, util_locale ) ;
  695. USAGE2("%s : The font of a specified code cannot be added/changed \"0x%x\".\n", prog_name, dspcode );
  696. if( fgets(buf, BUFSIZE, r_gpf->input) == NULL){
  697. return -1;
  698. } else {
  699. continue;
  700. }
  701. }
  702. for ( j = 0; j < r_snf->num_chars; j++ ) {
  703. if ( r_snf->code[j] == code ) {
  704. if ( !modify ) {
  705. DispCodePoint( com, char_set, code, dspcode, code_no, util_locale ) ;
  706. USAGE2("%s : The font has already been registered in a specified code. \"0x%x\"\n", prog_name, dspcode );
  707. if(fgets( buf, BUFSIZE, r_gpf->input ) == NULL){
  708. return -1;
  709. } else {
  710. break;
  711. }
  712. }
  713. if ( ( rtn = ModifyPtn( r_gpf, r_snf, buf, j ) ) ) {
  714. return rtn;
  715. }
  716. break;
  717. } else if ( r_snf->code[j] > code ) {
  718. if ( ( rtn = InsertPtn( r_gpf, r_snf, buf, code, j ) ) ) {
  719. return rtn;
  720. }
  721. break;
  722. }
  723. }
  724. if ( j == r_snf->num_chars ) {
  725. if ( ( rtn = InsertPtn( r_gpf, r_snf, buf, code, j ) ) ) {
  726. return rtn;
  727. }
  728. }
  729. }
  730. return 0;
  731. }
  732. static
  733. ModifyPtn(
  734. struct ptobhead *r_gpf,
  735. struct btophead *r_snf,
  736. char *buf,
  737. int ix)
  738. {
  739. int mwidth, msize, rtn;
  740. mwidth = ( r_gpf->p_width + 7 ) / 8;
  741. msize = mwidth * r_gpf->p_height;
  742. if ( r_gpf->zoomf ) {
  743. if ( ( rtn = GetGpfPtn( r_gpf, buf, r_gpf->ptn[0], mwidth, msize ) ) ) {
  744. return rtn;
  745. }
  746. if ( ( rtn = PtnZoom( r_snf->ptn[ix], r_gpf->ptn[0],
  747. r_gpf->p_width, r_gpf->p_height,
  748. r_snf->bdf_width, r_snf->bdf_height ) ) ) {
  749. return rtn;
  750. }
  751. } else {
  752. if ( ( rtn = GetGpfPtn( r_gpf, buf, r_snf->ptn[ix], mwidth, msize ) ) ) {
  753. return rtn;
  754. }
  755. }
  756. return 0;
  757. }
  758. static
  759. InsertPtn(
  760. struct ptobhead *r_gpf,
  761. struct btophead *r_snf,
  762. char *buf,
  763. int code,
  764. int ix)
  765. {
  766. int mwidth, msize, rtn, i;
  767. for ( i = r_snf->num_chars; i > ix; i-- ) {
  768. r_snf->code[i] = r_snf->code[i-1];
  769. r_snf->ptn[i] = r_snf->ptn[i-1];
  770. }
  771. r_snf->code[ix] = code;
  772. r_snf->num_chars++;
  773. mwidth = (r_snf->bdf_width + 7) / 8;
  774. msize = mwidth * r_snf->bdf_height;
  775. if ( ( r_snf->ptn[ix] = (char *)malloc( msize ) ) == NULL ) {
  776. return MALLOC_ERROR;
  777. }
  778. if ( r_gpf->zoomf ) {
  779. mwidth = (r_gpf->p_width + 7) / 8;
  780. msize = mwidth * r_gpf->p_height;
  781. if ( ( rtn = GetGpfPtn( r_gpf, buf, r_gpf->ptn[0], mwidth, msize ) ) ) {
  782. return rtn;
  783. }
  784. if ( ( rtn = PtnZoom( r_snf->ptn[ix], r_gpf->ptn[0],
  785. r_gpf->p_width, r_gpf->p_height,
  786. r_snf->bdf_width, r_snf->bdf_height ) ) ) {
  787. return rtn;
  788. }
  789. } else {
  790. if ( ( rtn = GetGpfPtn( r_gpf, buf, r_snf->ptn[ix], mwidth, msize ) ) ) {
  791. return rtn;
  792. }
  793. }
  794. return(0);
  795. }
  796. static
  797. writeSnf(struct btophead *r_snf, struct ptobhead *w_snf)
  798. {
  799. w_snf->zoomf = 0;
  800. w_snf->num_chars = r_snf->num_chars;
  801. w_snf->code = r_snf->code;
  802. w_snf->ptn = r_snf->ptn;
  803. w_snf->bdf_width = r_snf->bdf_width;
  804. w_snf->bdf_height = r_snf->bdf_height;
  805. w_snf->bdf_x = r_snf->bdf_x;
  806. w_snf->bdf_y = r_snf->bdf_y;
  807. w_snf->bdf_point = r_snf->bdf_point;
  808. w_snf->bdf_xdpi = r_snf->bdf_xdpi;
  809. return WritePtnToBdf( w_snf );
  810. }
  811. static void
  812. put_error_and_exit(
  813. struct ptobhead *ptob_in,
  814. struct btophead *btop,
  815. struct ptobhead *ptob_out,
  816. int er_no,
  817. char *prog_name)
  818. {
  819. ErrMsgTable_AndExit( er_no, ptob_in->in_file, ptob_out->out_file,
  820. btop->in_file, NULL,
  821. ptob_in->bdf_file,
  822. prog_name
  823. );
  824. return;
  825. }
  826. static void
  827. put_help(char *prog_name)
  828. {
  829. USAGE1("Usage: %s -xlfd xlfd_name \n", prog_name);
  830. USAGE("\t\t[-g character_size][-p character_pattern_file_name]\n");
  831. USAGE("\t\t[-style style]");
  832. USAGE("\t\t[-init]\t(clear whole glyphs of gpf file that used for user defined characters)\n" ) ;
  833. USAGE("\t\t[-modify]\t(permits the change of font)\n");
  834. COMM_HELP_MSG ;
  835. USAGE1("%s can insert or modify glyphs in the following code area.\n", prog_name);
  836. USAGE("codeset \t\tcode area\n");
  837. USAGE("----------------------------------------\n");
  838. DispUdcCpArea(stdout) ;
  839. USAGE("The xlfd name and character size may be obtained using dtlsgpf command.\n");
  840. return;
  841. }
  842. static int
  843. readBdfToMemory_with_init(
  844. struct btophead *head,
  845. int init,
  846. char *buf,
  847. int num_gr,
  848. FalGlyphRegion *gr)
  849. {
  850. int code, mwidth, num_char, bsize, rtn ;
  851. char *ptn;
  852. num_char = 0;
  853. mwidth = (head->bdf_width + 7) / 8;
  854. bsize = mwidth * head->bdf_height;
  855. while(1) {
  856. if ((rtn = GetBdfCode(head, buf, &code)) < 0) {
  857. return(rtn); /* contain BDF_INVAL */
  858. } else if (rtn == FILE_END) {
  859. head->num_chars = num_char;
  860. break;
  861. }
  862. rtn = IsInRegion( code, num_gr, gr ) ;
  863. if (
  864. ( code < head->start_code) || ( code > head->end_code )
  865. ||( !IN_CODE( head->code_category, SHIFT_ON( code ) ) )
  866. ||(
  867. (head->code_category == ALL_CODE)
  868. && ( (init)? ((rtn)?0:1) : ((rtn)?1:0) )
  869. ||( COMM_ISDEFAULTCHAR( code ) )
  870. )
  871. ) {
  872. continue;
  873. }
  874. head->code[num_char] = code;
  875. if ((ptn = head->ptn[num_char++] =
  876. (char *)malloc(bsize)) == NULL) {
  877. return(MALLOC_ERROR);
  878. }
  879. if ((rtn = GetBdfPtn(head, buf, ptn, mwidth, bsize)) != 0) {
  880. return(rtn);
  881. }
  882. }
  883. return(0);
  884. }