util/dttypes: remove register keyword
[oweals/cde.git] / cde / programs / dtudcfonted / comsub.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 /* comsub.c 1.36 - Fujitsu source for CDEnext    96/09/09 15:30:40      */
24 /* $XConsortium: comsub.c /main/8 1996/09/19 19:36:37 cde-fuj $ */
25 /*
26  *  (c) Copyright 1995 FUJITSU LIMITED
27  *  This is source code modified by FUJITSU LIMITED under the Joint
28  *  Development Agreement for the CDEnext PST.
29  *  This is unpublished proprietary source code of FUJITSU LIMITED
30  */
31
32
33 #include <stdio.h>
34 #include <signal.h>
35 #include <sys/types.h>
36 #include <sys/wait.h>
37 #include <math.h>
38 #include <locale.h>
39
40 #include <X11/Intrinsic.h>
41 #include "fssxeg.h"
42 #include "falfont.h"
43 #include "ufontrsrc.h"
44
45 static void writePtn();
46 static void sig_receive();
47 char    *get_cmd_path() ; 
48
49 extern Resource resource;
50
51 /***********************************************************************
52  manage the character patterns 
53  **********************************************************************/
54
55 #define GUADDPTNN       100     /* number of charcters for memory allocation  */
56 /* this structure corresopnds to single font file */
57 typedef struct {                /* area to manage character patterns    */
58     char        flag;           /* invalid(=0)/valid(=1)                */
59     int         width;          /* pattern width                        */
60     int         height;         /* pattern height                       */
61     int         nptn;           /* number of characters in editting     */
62     int         nmaxptn;        /* maximum number of characters in editting */
63     int         ptnsize;        /* size per byte of single pattern      */
64     UINT        ptnmemsize;     /* size of memory of whole patterns     */
65     USHORT      *ntoc;          /* character list / relative code       */
66     USHORT      *ctop;          /* relative code / bitmap area          */
67     char        *ptn;           /* pointer to the bimap area            */
68     int cptnnum;                /* current pattern number               */
69 } PATTERN_MNG;
70
71 static PATTERN_MNG      pm;             /* Pattern_Manage */
72
73 /* selection window for XLFD */
74 extern  FalFontData     fullFontData;
75 extern  FalFontData     copyFontData;
76 extern int CodePoint;
77
78 char                    *fullpath=NULL;
79 int                     begin_code=0, last_code=0;
80
81 FalCodeRegion   CodeArea[10];
82 char            AreaStr[160];
83
84 #define FAL_ERROR_STR resource.falerrmsg[((fal_utyerrno & 0xff) > 25) ? 0 : (fal_utyerrno & 0xff)]
85
86 FalFontID               font_id;
87
88 static char *
89 get_locale()
90 {
91     char *loc;
92
93     if ((loc = getenv("LANG")) != NULL) {
94         return(loc);
95     } else {
96         return("C");
97     }
98 }
99
100 /* contents :   convert the sequential number in the editor into 
101  *              relative code in the system area 
102  * values   :   -1   : terminated abnormally 
103  *              else : relative code 
104  */
105
106 int
107 ptnSqToNo( num )
108 int     num;                    /* sequential number    */
109 {
110     if( (pm.flag == 0) || (num >= pm.nptn) )
111         return( -1 );
112
113     return( pm.ntoc[num] );
114 }
115
116
117
118
119 /* contents :   convert the relative code in the system area into 
120  *              sequential number in the editor 
121  * values   :   -1   : terminated abnormally 
122  *              else : sequential number 
123  */
124
125 int
126 ptnNoToSq( ncode )
127 int     ncode;                  /* relative code        */
128 {
129     int         sq;
130
131     if( pm.flag == 0 )
132         return( -1 );
133
134     for( sq=0   ; sq < pm.nptn   ; sq++ ) {
135         if( pm.ntoc[sq] == ncode )
136             return( sq );
137     }
138
139     return( -1 );
140 }
141
142
143
144
145 /*
146  * contents : convert the character code into relative code 
147  * values   : relative code 
148  * caution  : There is no security against unusal character code. 
149  */
150
151 int
152 codeToNo( code )
153 int     code;                   /* character code */
154 {
155     return( code - begin_code);
156 }
157
158
159
160
161 /*
162  * contents : convert the relative code into character code 
163  * values   : character code 
164  * caution  : There is no security against unusal character code. 
165  */
166
167 int
168 noToCode( sno )
169 int     sno;                    /* relative code */
170 {
171     return( sno + begin_code);
172 }
173
174
175 /*
176  * contents : judge the input code with the system defined character area 
177  * values   : 0 : in the system defined area 
178  *           -1 : not in the system defined area
179  */
180
181 int
182 codeCheck( code )
183 int     code;
184 {
185     if (code < begin_code || code > last_code) {
186         return( -1 );
187     }
188     return( 0 );
189 }
190
191 /*
192  * contents : allocate memories for character patterns
193  *
194  * values   :   ID : sequential number of the area
195  *              -1 : terminated abnormally 
196  */
197
198 static int
199 ptnOpen(n, maxc, width, height)
200 int     n;                      /* initial number of charcters  */
201 int     maxc;
202 int     width;                  /* pattern width                */
203 int     height;                 /* pattern height               */
204 {
205     int         i;
206     int         fpsize;
207
208     if( (n < 0) || (width <= 0) || (height <= 0) )
209         return( -1 );
210
211     if( pm.flag != 0 ) {
212         return( -1 );
213     }
214
215     pm.width   = width;
216     pm.height  = height;
217     pm.nptn    = 0;
218     pm.nmaxptn = n + GUADDPTNN;
219     pm.ptnsize = height * ((width+7)/8);
220     fpsize = pm.ptnsize + 1;
221     pm.ptnmemsize = (UINT) ( fpsize * pm.nmaxptn ) ;
222
223     if(( pm.ntoc = (USHORT *)calloc(maxc, sizeof(USHORT)) ) == NULL) {
224         return( -1 );
225     }
226     if(( pm.ctop = (USHORT *)calloc(maxc, sizeof(USHORT)) ) == NULL ) {
227         free( pm.ntoc );
228         return( -1 );
229     }
230     if(( pm.ptn  = (char   *)malloc(fpsize*pm.nmaxptn) ) == NULL ) {
231         free( pm.ctop );
232         free( pm.ntoc );
233         return( -1 );
234     }
235
236     for( i=0   ; i < maxc   ; i++ ) {
237         pm.ntoc[i] = 0xFFFF;
238         pm.ctop[i] = 0xFFFF;
239     }
240     /* set null to each character pattern area */
241     for( i=0   ; i < pm.nmaxptn   ; i++ ) {
242         pm.ptn[fpsize * i] = 0;
243     }
244     pm.cptnnum = 0;
245     pm.flag = 1;
246
247     return( 0 );
248 }
249
250
251
252
253 /*
254  * contents :   set free memories for character patterns
255  * values   :   0  : terminated normally 
256  *              -1 : terminated abnormally 
257  */
258
259 int
260 ptnClose()
261 {
262     if( pm.flag == 0 ) {
263         return( -1 );
264     }
265     pm.flag = 0;
266     free( pm.ntoc );
267     free( pm.ctop );
268     free( pm.ptn );
269
270     return( 0 );
271 }
272
273
274
275
276 /*
277  * contents :   add character pattern to the character management area 
278  *
279  * values   :   0  : same code was exists and replaced it 
280  *              1  : add new pattern 
281  *              -1 : terminated abnormally
282  */
283
284 int
285 ptnAdd( code, ptn )
286 int     code;                   /* code to be add       */
287 char    *ptn;                   /* pointer to the pattern */
288 {
289     int         fpsize;
290     int         ncode;
291     USHORT      pno;
292     char        *pf;
293     char        *pp;
294     int         i;
295     char        *re_ptn;
296     UINT        re_ptnmemsize;
297     int         cpn;
298
299     if( pm.flag == 0 )
300         return( -1 );
301
302     fpsize = pm.ptnsize + 1;
303     ncode = codeToNo( code );
304
305     if( (pno = pm.ctop[ncode]) != 0xFFFF ) {
306         pf = pm.ptn + fpsize*pno;
307         pp = pf + 1;
308         for( i=0   ; i < pm.ptnsize   ; i++ ) 
309             pp[i] = ptn[i];
310         return( 0 );
311     }
312
313     if( pm.nptn >= pm.nmaxptn ) {
314         re_ptnmemsize = pm.ptnmemsize + GUADDPTNN*fpsize;
315         if(pm.ptn == NULL) {
316             re_ptn = malloc( re_ptnmemsize );
317         } else {
318             re_ptn = realloc(pm.ptn, re_ptnmemsize);
319         }
320         if (re_ptn == NULL) {
321             return( -1 );
322         }
323         pm.ptnmemsize = re_ptnmemsize;
324         pm.ptn     = re_ptn;
325         for( i=pm.nmaxptn   ; i < pm.nmaxptn + GUADDPTNN   ; i++ ) {
326             pm.ptn[fpsize * i] = 0;
327         }
328         pm.nmaxptn += GUADDPTNN;
329     }
330
331     cpn = pm.cptnnum + 1;
332     for( i=0   ; i < pm.nmaxptn   ; i++, cpn++ ) {
333         if( cpn >= pm.nmaxptn ) {
334             cpn = 0;
335         }
336         if( pm.ptn[fpsize * cpn] == 0 ) {
337             break;
338         }
339     }
340     pm.cptnnum     = cpn;
341
342     pm.ctop[ncode] = (USHORT) cpn;
343     pf = pm.ptn + fpsize*cpn;
344     pp = pf + 1;
345     pf[0] = 1;
346     for( i=0   ; i < pm.ptnsize   ; i++ ) 
347         pp[i] = ptn[i];
348
349     for( i=pm.nptn   ; i >=0   ; i-- ) {
350         if( ncode > (int)pm.ntoc[i] ) {
351             break;
352         }
353         pm.ntoc[i+1] = pm.ntoc[i];
354     }
355     pm.ntoc[i+1] = (USHORT) ncode;
356     pm.nptn      += 1;
357
358     return( 1 );
359 }
360
361
362 /*
363  * contents :   get a character pattern from the character management area 
364  * values   :   0  : terminated normally 
365  *              -1 : terminated abnormally 
366  */
367
368 int
369 ptnGet( code, ptn )
370 int     code;
371 char    *ptn;
372 {
373     int         ncode;
374     int         fpsize;
375     USHORT      pno;
376     char        *pf;
377     char        *pp;
378     int         i;
379
380     if( (pm.flag == 0) || (codeCheck(code) == -1) )
381         return( -1 );
382
383     ncode  = codeToNo( code );
384     fpsize = pm.ptnsize +1;
385
386     if( (pno = pm.ctop[ncode]) == 0xFFFF )
387         return( -1 );
388
389     pf = pm.ptn + pno*fpsize;
390     pp = pf +1;
391
392     for( i=0   ; i < pm.ptnsize   ; i++ )
393         ptn[i] = pp[i];
394
395     return( 0 );
396 }
397
398
399 /*
400  * contents :   judge the character pattern exist or not 
401  * values   :   1  : exists
402  *              0  : not exists
403  *              -1 : terminated abnormally 
404  */
405
406 int
407 ptnSense( code )
408 int     code;
409 {
410     if( (pm.flag == 0) || (codeCheck(code) == -1) )
411         return( -1 );
412
413     if( pm.ctop[ codeToNo(code) ] == 0xFFFF )
414         return( 0 );
415     else
416         return( 1 );
417 }
418
419
420 /*
421  * contents :   delete the character pattern 
422  * values   :   1  : deleted 
423  *              0  : the pattern does not exist
424  *              -1 : terminated abnormally
425  */
426
427 int
428 ptnDel( code )
429 int     code;
430 {
431     int         ncode;
432     int         fpsize;
433     USHORT      pno;
434     char        *pf;
435     int         i;
436
437     if( (pm.flag == 0) || (codeCheck(code) == -1) )
438         return( -1 );
439
440     ncode  = codeToNo( code );
441     fpsize = pm.ptnsize +1;
442
443     if( (pno = pm.ctop[ncode]) == 0xFFFF ) {
444         return( 0 );
445     }
446
447     pf = pm.ptn + pno*fpsize;
448
449     pf[0] = 0;
450     pm.ctop[ncode] = 0xFFFF;
451
452     for( i=0   ; i < pm.nptn   ; i++ ) {
453         if( (int)pm.ntoc[i] == ncode )
454             break;
455     }
456     for(      ; i < pm.nptn   ; i++ )
457         pm.ntoc[i] = pm.ntoc[i+1];
458
459     pm.nptn --;
460     return( 1 );
461 }
462
463
464 /*
465  * contents :   get the infomation of the character
466  * values   :   0  : terminated normally 
467  *              -1 : terminated abnormally 
468  */
469
470 int
471 ptnGetInfo( n, width, height )
472 int     *n;                     /* the number of characters in editting */
473 int     *width;                 /* pattern width        */
474 int     *height;                /* pattern height       */
475 {
476     if( pm.flag == 0 )
477         return( -1 );
478
479     *n = pm.nptn;
480     *width = pm.width;
481     *height = pm.height;
482     
483     return( 0 );
484 }
485
486
487 /********************************************************************
488  *    handle bit map file(1)                                        *
489  ********************************************************************/
490
491 struct {                        /* infomation of character pattern */
492     int         width;          /* pattern width */
493     int         height;         /* pattern height */
494     int         xbytesize;
495 } bitInfo = { 16, 16 ,2 };
496
497
498 /*
499  * contents : set infomation for handling bit-mapped files 
500  */
501
502 static void
503 bitSetInfo( width, height)
504 int     width;                  /* pattern width        */
505 int     height;                 /* pattern height       */
506 {
507     bitInfo.width     = width;
508     bitInfo.height    = height;
509     bitInfo.xbytesize = (width+7)/8;
510
511     return;
512 }
513
514
515 /*
516  * contents : set the bit at specefied coordinate on 
517  */
518
519 void
520 bitSet( ptn, cx, cy )
521 char    *ptn;
522 int     cx;
523 int     cy;
524 {
525     if((cx < 0) || (bitInfo.width <= cx) || (cy < 0) || (bitInfo.height <= cy))
526         return;
527     ptn[ bitInfo.xbytesize*cy + cx/8 ] |= (char)( 0x80 >> (cx%8) );
528 }
529
530
531 /*
532  * contents : set the bit at specefied coordinate off
533  */
534
535 void
536 bitReset( ptn, cx, cy )
537 char    *ptn;
538 int     cx;
539 int     cy;
540 {
541     if((cx < 0) || (bitInfo.width <= cx) || (cy < 0) || (bitInfo.height <= cy))
542         return;
543     ptn[ bitInfo.xbytesize*cy + cx/8 ] &= ~(char)( 0x80 >> (cx%8) );
544 }
545
546
547 /*
548  * contents : returns 1 ( bit on ) or 0 ( bit off )
549  */
550
551 int
552 bitRead( ptn, cx, cy )
553 char    *ptn;
554 int     cx;
555 int     cy;
556 {
557     if((cx < 0) || (bitInfo.width <= cx) || (cy < 0) || (bitInfo.height <= cy))
558         return( 0 );
559     return( ptn[ bitInfo.xbytesize*cy + cx/8 ] 
560                 &
561            (char)( 0x80 >> (cx%8) ) ?   1   :   0
562     );
563 }
564
565
566 /*
567  * contents : clear the specefied bitmap file
568  */
569
570 void
571 bitPtnClear( ptn )
572 char    *ptn;
573 {
574     int         i;
575
576     for( i=0   ; i < bitInfo.height * bitInfo.xbytesize    ; i++ )
577         ptn[i] = 0;
578 }
579
580
581 /*
582  * contents : copy the bit-mapped file
583  */
584
585 void
586 bitPtnCopy( d_ptn, s_ptn )
587 char    *d_ptn;                 /* pointer of the destination file      */
588 char    *s_ptn;                 /* pointer of the source file           */
589 {
590     int i;
591
592     for( i=0   ; i < bitInfo.height * bitInfo.xbytesize   ; i++ )
593         d_ptn[i] = s_ptn[i];
594 }
595
596
597
598 /************************************************************************
599  *    handle bit map file(2)                                            *
600  *    caution : You must call bitSetInfo() before use these functions.  *
601  *                                                                      *
602  ************************************************************************/
603
604 /*
605  * contents :   draw lines between desired two points
606  * values   :   0  : terminated normally 
607  *              -1 : outside of the edtting pane 
608  */
609
610 int
611 bitDrawLine( ptn, x1, y1, x2, y2 ,mode )
612 char    *ptn;                   /* pointer of the bit map file */
613 int     x1;
614 int     y1;
615 int     x2;
616 int     y2;
617 int     mode;                   /* 0: erase 1: draw     */
618 {
619     float       dx, dy;
620     float       x, y;
621     float       delta;
622     int         i;
623
624     if( (x1 < 0) || (x2 < 0) || (y1 < 0) || (y2 < 0) ||
625         (bitInfo.width  <= x1) || (bitInfo.width <= x2) ||
626         (bitInfo.height <= y1) || (bitInfo.height <= y2) )
627         return( -1 );
628
629     dx = x2 - x1;
630     dy = y2 - y1;
631      x = x1 + 0.5;
632      y = y1 + 0.5;
633
634     delta = abs((int)dx) > abs((int)dy) ?   dx  :   dy;
635     if( delta < 0 )
636         delta = -delta;
637     if( delta == 0)
638         delta = 0.75;
639     dx /= delta;
640     dy /= delta;
641
642     for(i=0   ; i <= (int)delta   ; i++ ) {
643         mode == 0 ? bitReset(ptn,(int)x,(int)y)   :   bitSet(ptn,(int)x,(int)y);
644         x += dx;
645         y += dy;
646     }
647     return( 0 );
648 }
649
650
651 /*
652  * contents :   draw circle
653  * values   :   0  : terminated normally 
654  *              -1 : terminated abnormally
655  */
656
657 int
658 bitDrawCircle( ptn, x1, y1, x2, y2, mode )
659 char    *ptn;
660 int     x1;
661 int     y1;
662 int     x2;
663 int     y2;
664 int     mode;
665 {
666     int         dx, dy;
667     int         i,x;            
668     double      rad, half;
669
670     if( (x1 < 0) || (y1 < 0) || (x2 < 0.0) || ( y2 < 0.0) ) {
671         return( -1 );
672     }
673
674     dx = abs(x2 - x1);
675     dy = abs(y2 - y1);
676     rad = sqrt((double)(dx * dx + dy * dy)) + 0.5;
677     half = rad * sqrt(2.0)/2;
678     for (i = 0; i <= (int)half; i++) {
679         x = (int)sqrt(rad * rad - (double)(i*i));
680         if( mode ) {
681             bitSet  (ptn, x1 - x, y1 - i);
682             bitSet  (ptn, x1 - x, y1 + i);
683             bitSet  (ptn, x1 + x, y1 - i);
684             bitSet  (ptn, x1 + x, y1 + i);
685             bitSet  (ptn, x1 - i, y1 - x);
686             bitSet  (ptn, x1 - i, y1 + x);
687             bitSet  (ptn, x1 + i, y1 - x);
688             bitSet  (ptn, x1 + i, y1 + x);
689         } else {
690             bitReset(ptn, x1 - x, y1 - i);
691             bitReset(ptn, x1 - x, y1 + i);
692             bitReset(ptn, x1 + x, y1 - i);
693             bitReset(ptn, x1 + x, y1 + i);
694             bitReset(ptn, x1 - i, y1 - x);
695             bitReset(ptn, x1 - i, y1 + x);
696             bitReset(ptn, x1 + i, y1 - x);
697             bitReset(ptn, x1 + i, y1 + x);
698         }
699     }
700     return( 0 );
701 }
702
703
704 /*
705  * contents :   draw rectangle
706  * values   :   0  : terminated normally 
707  *              -1 : terminated abnormally
708  */
709
710 int
711 bitDrawRect( ptn, x, y, width, height, mode )
712 char    *ptn;
713 int     x;
714 int     y;
715 int     width;
716 int     height;
717 int     mode;
718 {
719     int         i;
720
721     width --;
722     height --;
723
724     if( (x < 0) || (y < 0) || (width < 0) || (height < 0) ||
725         (bitInfo.width <= width +x) || (bitInfo.height <= height +y) )
726         return( -1 );
727
728     for( i=x   ; i <= width+x   ; i++ ) {
729         if( mode == 0 ) {
730             bitReset( ptn, i, y );
731             bitReset( ptn, i, height+y ); 
732         }
733         else {
734             bitSet( ptn, i, y );
735             bitSet( ptn, i, height+y ); 
736         }
737     }
738     for( i=y+1   ; i < height +y   ; i++ ) {
739         if( mode == 0 ) {
740             bitReset( ptn, x, i );
741             bitReset( ptn, x+width, i ); 
742         }
743         else {
744             bitSet( ptn, x, i );
745             bitSet( ptn, x +width, i ); 
746         }
747     }
748         
749     return( 0 );
750 }
751
752
753 /*
754  * contents :   clear the inside of the specefied rectangle 
755  * values   :   0  : terminated normally 
756  *              -1 : terminated abnormally 
757  */
758
759 int 
760 bitDrawCls( ptn, x, y, width, height )
761 char    *ptn;
762 int     x;
763 int     y;
764 int     width;  
765 int     height;
766 {
767     int         i, j;
768
769     width --;
770     height --;
771
772     if( (x < 0) || (y < 0) || (width < 0) || (height < 0) ||
773         (bitInfo.width <= width +x) || (bitInfo.height <= height +y) )
774         return( -1 );
775
776     for( i=x   ; i <= width +x   ; i++ ) {
777         for( j=y   ; j <= height +y   ; j++ )
778             bitReset( ptn, i, j );
779     }
780
781     return( 0 );
782 }
783
784
785 /*
786  * contents :   paint out the inside of the desired rectangle 
787  * values   :   0  : terminated normally 
788  *              -1 : terminated abnormally 
789  */
790
791 int
792 bitDrawSet( ptn, x, y, width, height )
793 char    *ptn;
794 int     x;
795 int     y;
796 int     width;
797 int     height; 
798 {
799     int         i, j;
800
801     width --;
802     height --;
803
804     if( (x < 0) || (y < 0) || (width < 0) || (height < 0) ||
805         (bitInfo.width <= width +x) || (bitInfo.height <= height +y) )
806         return( -1 );
807
808     for( i=x   ; i <= width +x   ; i++ ) {
809         for( j=y   ; j <= height +y   ; j++ )
810             bitSet( ptn, i, j );
811     }
812     return(0);
813 }
814
815
816 /*
817  * contents :   reverse the inside of the desired rectangle 
818  * values   :   0  : terminated normally 
819  *              -1 : terminated abnormally 
820  */
821
822 int
823 bitDrawRev( ptn, x, y, width, height )
824 char    *ptn;   
825 int     x;
826 int     y;
827 int     width;
828 int     height;
829 {
830     int         i, j;
831
832     width --;
833     height --;
834
835     if( (x < 0) || (y < 0) || (width < 0) || (height < 0) ||
836         (bitInfo.width <= width +x) || (bitInfo.height <= height +y) )
837         return( -1 );
838
839     for( i=x   ; i <= width +x   ; i++ ) {
840         for( j=y   ; j <= height +y   ; j++ ) {
841             if( bitRead( ptn, i, j ) == 0 )
842                 bitSet ( ptn, i, j );
843             else
844                 bitReset( ptn, i, j );
845         }
846     }
847
848     return( 0 );
849 }
850
851
852 static char cut_buffer[MAXPTNBYTE];
853 static int cut_buffer_w=0;
854 static int cut_buffer_h=0;
855 /*
856  * contents :   copy the specified rectangle area
857  * values   :   0  : terminated normally 
858  *              -1 : terminated abnormally
859  */
860
861 int
862 bitDrawCpy(ptn, sx, sy, width, height, cut_flag)
863 char    *ptn;
864 int     sx;
865 int     sy;
866 int     width;
867 int     height;
868 int     cut_flag;
869 {
870     int         i, j;
871
872     if ((sx < 0) || (sy < 0) || (width < 2) || (height < 2) ||
873         (bitInfo.width < width +sx) || (bitInfo.height < height +sy))
874         return( -1 );
875
876     cut_buffer_w = width;
877     cut_buffer_h = height;
878
879     for (i=0; i < width; i++) {
880         for (j=0; j < height; j++) {
881             if (bitRead(ptn, i + sx, j + sy) != 0)
882                 bitSet(cut_buffer, i, j);
883             else
884                 bitReset(cut_buffer, i, j);
885             if (cut_flag)
886                 bitReset(ptn, i + sx, j + sy);
887         }
888     }
889     return( 0 );
890 }
891
892 int
893 bitDrawPaste(ptn, dx, dy)
894 char    *ptn;
895 int     dx;
896 int     dy;
897 {
898     int         i, j;
899     int         width, height;
900
901     if((dx < 0) || (dy < 0) || (cut_buffer == 0) ||
902                         (cut_buffer_w == 0) || (cut_buffer_h == 0))
903         return( -1 );
904
905     width  = (cut_buffer_w <= bitInfo.width - dx)
906                                 ? cut_buffer_w : bitInfo.width - dx;
907     height = (cut_buffer_h <= bitInfo.height - dy)
908                                 ? cut_buffer_h : bitInfo.height - dy;
909
910     for (i=0; i < width; i++) {
911         for (j=0; j < height; j++) {
912             if( bitRead(cut_buffer, i, j) != 0 )
913                 bitSet (ptn, i + dx, j + dy);
914             else
915                 bitReset(ptn, i + dx, j + dy);
916         }
917     }
918     return( 0 );
919 }
920
921
922
923 /*
924  * contents :   rotate the inside of the area specified 
925  * values   :   0  : terminated normally 
926  *              -1 : terminated abnormally 
927  */
928
929 int
930 bitDrawRoll( ptn, x, y, width, height )
931 char    *ptn;
932 int     x;
933 int     y;
934 int     width;
935 int     height;
936 {
937     char *point;
938     int xx, yy;
939     int count;
940
941     if( (x < 0) || (y < 0) || (width < 0) || (height < 0) ||
942         (bitInfo.width < width +x) || (bitInfo.height < height +y) )
943         return( -1 );
944
945     point = (char *)malloc((width * height) * sizeof(int));
946
947     for(count=0,yy=0; yy < height; yy++) {
948         for(xx=0; xx < width; xx++ ) {
949             point[count++] = bitRead(ptn, x + xx, y + yy);
950             bitReset(ptn, x + xx, y + yy);
951         }
952     }
953
954     for(count=0,yy=0; yy < height; yy++) {
955         for(xx=0; xx < width; xx++ ) {
956             point[count++] == 0 ? bitReset(ptn, x + height - yy - 1, y + xx)
957                                 : bitSet(ptn, x + height - yy - 1, y + xx);
958         }
959     }
960
961     free(point);
962     return( 0 );
963 }
964
965
966 /*
967  * contents :   reverse the top-bottom symmetry of the rectangle specified 
968  * values   :   0  : terminated normally 
969  *              -1 : terminated abnormally
970  */
971
972 int
973 bitDrawSymV( ptn, x, y, width, height )
974 char    *ptn;
975 int     x;
976 int     y;
977 int     width;
978 int     height; 
979 {
980     int         k, j;
981     int         d1, d2;
982
983     width --;
984     height --;
985
986     if( (x < 0) || (y < 0) || (width < 0) || (height < 0) ||
987         (bitInfo.width <= width +x) || (bitInfo.height <= height +y) )
988         return( -1 );
989
990     for( k=0   ; k <= width   ; k++ ) {
991         for( j=0   ; j <(height+1)/2   ; j++ ) {
992             d1 = bitRead( ptn, x +k,        y +j );
993             d2 = bitRead( ptn, x +k, y + height -j );
994
995             d1 == 0 ? bitReset( ptn, x +k, y +height -j )
996                       : bitSet( ptn, x +k, y +height -j );
997             d2 == 0 ? bitReset( ptn, x +k,        y +j )
998                       : bitSet( ptn, x +k,        y +j );
999         }
1000     }
1001     return( 0 );
1002 }
1003
1004
1005 /*
1006  * contents :   reverse the left-right symmetry of the rectangle specified 
1007  * values   :   0  : terminated normally 
1008  *              -1 : terminated abnormally 
1009  */
1010
1011 int
1012 bitDrawSymH( ptn, x, y, width, height )
1013 char    *ptn;
1014 int     x;
1015 int     y;
1016 int     width;
1017 int     height;
1018 {
1019     int         k, j;
1020     int         d1, d2;
1021
1022     width --;
1023     height --;
1024
1025     if( (x < 0) || (y < 0) || (width < 0) || (height < 0) ||
1026         (bitInfo.width <= width +x) || (bitInfo.height <= height +y) )
1027         return( -1 );
1028
1029     for( k=0   ; k < (width+1)/2   ; k++ ) {
1030         for( j=0   ; j <= height   ; j++ ) {
1031             d1 = bitRead( ptn, x +k,        y +j );
1032             d2 = bitRead( ptn, x +width -k, y +j );
1033
1034             d1 == 0 ? bitReset( ptn, x +width -k, y +j )
1035                       : bitSet( ptn, x +width -k, y +j );
1036             d2 == 0 ? bitReset( ptn, x +k,        y +j )
1037                       : bitSet( ptn, x +k,        y +j );
1038         }
1039     }
1040     return( 0 );
1041 }
1042
1043
1044 static char *
1045 char_set(char *str)
1046 {
1047     int i, count;
1048     char *p;
1049     for (i=strlen(str),p=&(str[i]),count=0; i && count < 2; i--,p--) {
1050         if (*p == '-')
1051             count ++;
1052     }
1053     if (count == 2)
1054         return(p + 2);
1055     else
1056         return(str);
1057 }
1058
1059
1060 /****************************************************************
1061  *   read and write SNF file                                    *
1062  *                                                              *
1063  *                                                              *
1064  ****************************************************************/
1065
1066 /*
1067  * contents : read character patterns from specified SNF file
1068  * values   : number of the area that was allocated to manage font file 
1069  *              -1 : terminated abnormally 
1070  *              -2 : file is locked 
1071  */
1072 int
1073 readSNF(fdata, width, height, err)
1074 FalFontData **fdata;
1075 int     *width;
1076 int     *height;
1077 char    *err;
1078 {
1079     FalFontinfo         finfo;
1080     int                 start, end;
1081     int                 code;
1082     int                 mask;
1083     int                 i;
1084     char                *ptn;
1085     static FalFontDataList      *fulllist;
1086     char                *mes;
1087
1088     FalGlyphRegion      *gr, *gr_p;
1089     int                 num_gr;
1090     char                tmp[16];
1091     unsigned int        s, e;
1092
1093
1094     if (fulllist) {
1095         FalFreeFontList(fulllist);
1096         fulllist = NULL;
1097     }
1098     mask =  FAL_FONT_MASK_XLFDNAME | FAL_FONT_MASK_UPDATE |
1099                 FAL_FONT_MASK_DEFINED | FAL_FONT_MASK_UNDEFINED;
1100     if (fullFontData.cd_set != -1) {
1101         mask |= FAL_FONT_MASK_CODE_SET;
1102     }
1103     if (! CodePoint) {
1104         mask |= FAL_FONT_MASK_GLYPH_INDEX;
1105     }
1106     if (FalGetFontList(&fullFontData, mask, &fulllist) == FAL_ERROR) {
1107         strcpy(err, FAL_ERROR_STR);
1108         return(-1);
1109     }
1110     if(fulllist == NULL) {
1111         strcpy(err, resource.mn_no_font);
1112         return(-1);
1113     }
1114     if (fulllist->num != 1) {
1115         FalFreeFontList(fulllist);
1116         fulllist = NULL;
1117         strcpy(err, resource.mn_plural_font);
1118         return(-1);
1119     }
1120     *fdata = &(fulllist->list[0]);
1121     font_id = FalOpenSysFont(&fullFontData, mask, &fulllist);
1122     mes = 0;
1123     if (font_id == 0 && (fal_utyerrno & 0xff) == FAL_ERR_FNT_OPN) {
1124         mes = (char *) malloc(strlen(resource.mn_no_perm)+strlen(fal_err_file)+10);
1125         if (mes == NULL) {
1126             strcpy(err, resource.mn_no_mem);
1127             FalFreeFontList(fulllist);
1128             return( -1 );
1129         }
1130         sprintf(mes, "%sfile: %s", resource.mn_no_perm, fal_err_file);
1131
1132         mask &= ~FAL_FONT_MASK_UPDATE;
1133         font_id = FalOpenSysFont(&fullFontData, mask, &fulllist);
1134         if (font_id == 0) {
1135             free(mes);
1136             strcpy(err, FAL_ERROR_STR);
1137             FalFreeFontList(fulllist);
1138             return( -1 );
1139         }
1140     } else if (font_id == 0) {
1141         strcpy(err, FAL_ERROR_STR);
1142         FalFreeFontList(fulllist);
1143         return( -1 );
1144     }
1145     if (fullpath != NULL)
1146         FalFree(fullpath);
1147     if (FalFontIDToFileName(font_id, &fullpath) == FAL_ERROR) {
1148         strcpy(err, FAL_ERROR_STR);
1149         if (mes)
1150             free(mes);
1151         return( -1 );
1152     }
1153
1154     if( FalQueryFont( font_id, &finfo ) == FAL_ERROR ) {
1155         strcpy(err, FAL_ERROR_STR);
1156         FalCloseFont( font_id );
1157         if (mes)
1158             free(mes);
1159         return( -1 );
1160     }
1161     *width = finfo.width;
1162     *height = finfo.height;
1163
1164     fullFontData.cd_set = (* fdata)->cd_set;
1165     if (CodePoint) {
1166         if (FalGetUDCCPArea(get_locale(),(* fdata)->cd_set,
1167                 char_set(( *fdata)->xlfdname), (FalCodeRegion **) &gr, &num_gr) == FAL_ERROR) {
1168             strcpy(err, FAL_ERROR_STR);
1169             FalCloseFont( font_id );
1170             if (mes)
1171                 free(mes);
1172             return( -1 );
1173         }
1174     } else {
1175         if (FalGetUDCGIArea(get_locale(),(* fdata)->cd_set,
1176                 char_set(( *fdata)->xlfdname), &gr, &num_gr) == FAL_ERROR) {
1177             strcpy(err, FAL_ERROR_STR);
1178             FalCloseFont( font_id );
1179             if (mes)
1180                 free(mes);
1181             return( -1 );
1182         }
1183     }
1184     if (! num_gr) {
1185         FalCloseFont( font_id );
1186         strcpy(err, resource.mn_not_udc);
1187         if (mes)
1188             free(mes);
1189         return( -1 );
1190     }
1191     if (mes) {
1192         Error_message2(NULL, mes);
1193         free(mes);
1194         fullFontData.prm = True;
1195     }
1196     start = gr->start;  
1197     end = gr->end;      
1198     for (i=0, gr_p=gr; i < num_gr; i++, gr_p++) {
1199         CodeArea[i].start = gr_p->start;
1200         CodeArea[i].end = gr_p->end;
1201         s = (gr_p->start & 0xff00) >> 8;
1202         e = (gr_p->end & 0xff00) >> 8;
1203         if (i == 0) {
1204             sprintf(tmp, "0x%x:0x%x", s, e);
1205             strcpy(AreaStr, tmp);
1206         } else {
1207             sprintf(tmp, ",0x%x:0x%x", s, e);
1208             strcat(AreaStr, tmp);
1209         }
1210         if (start > gr_p->start)
1211             start = gr_p->start;
1212         if (end < gr_p->end)
1213             end = gr_p->end;
1214     }
1215     CodeArea[i].start = -1;
1216     begin_code = start;
1217     last_code = end;
1218
1219     if (start > end) {
1220         FalCloseFont( font_id );
1221         sprintf(err, "%s\nStart address = %x End address = %x\n", resource.mn_illegal_area, start, end);
1222         return( -1 );
1223     }
1224
1225     if( ptnOpen(1, end - start + 1, finfo.width, finfo.height) < 0 ) {
1226         FalCloseFont( font_id );
1227         strcpy(err, resource.mn_no_mem);
1228         return( -1 );
1229     }
1230     bitSetInfo( finfo.width, finfo.height );
1231
1232     for (i=0, gr_p=gr; i < num_gr; i++, gr_p++) {
1233         if (start > gr_p->start)
1234             gr_p->start = start;
1235         if (end < gr_p->end)
1236             gr_p->end = end;
1237         start = gr_p->end;
1238
1239         if (! CodePoint) {
1240                 for (code=gr_p->start; code <= gr_p->end; code++) {
1241                     if (code & 0x80) {
1242                         code &= 0xff00;
1243                         code += 0x100;
1244                         continue;
1245                     }
1246
1247                     ptn  = (char *)FalReadFont( font_id, code, finfo.width, finfo.height );
1248                     if( ptn == (char *)FAL_ERROR ) {
1249                         strcpy(err, FAL_ERROR_STR);
1250                         FalFree(gr);
1251                         FalCloseFont( font_id );
1252
1253                         ptnClose();
1254                         return( -1 );
1255                     }
1256                     if( EXISTS_FLAG == 0 ) {
1257                         if( ptnAdd( code, ptn ) != 1 ) {
1258                             FalFree(gr);
1259                             strcpy(err, resource.mn_no_read);
1260                             FalCloseFont( font_id );
1261
1262                             ptnClose();
1263                             return( -1 );
1264                         }
1265                     }
1266                 }
1267         } else {
1268                 for (code=gr_p->start; code <= gr_p->end; code++) {
1269                     if (! (code & 0x80)) {
1270                         code &= 0xff00;
1271                         code |= 0x80;
1272                         continue;
1273                     }
1274
1275                     ptn  = (char *)FalReadFont( font_id, code, finfo.width, finfo.height );
1276                     if( ptn == (char *)FAL_ERROR ) {
1277                         strcpy(err, FAL_ERROR_STR);
1278                         FalFree(gr);
1279                         FalCloseFont( font_id );
1280
1281                         ptnClose();
1282                         return( -1 );
1283                     }
1284                     if( EXISTS_FLAG == 0 ) {
1285                         if( ptnAdd( code, ptn ) != 1 ) {
1286                             FalFree(gr);
1287                             strcpy(err, resource.mn_no_read);
1288                             FalCloseFont( font_id );
1289
1290                             ptnClose();
1291                             return( -1 );
1292                         }
1293                     }
1294                 }
1295         }
1296     }
1297     FalFree(gr);
1298     *err = 0;
1299     return( 0 );
1300 }
1301
1302 static void
1303 bicopy(s1, s2, size)
1304 char *s1, *s2;
1305 int size;
1306 {
1307     register int i;
1308     for(i=size; i; i--, s1++, s2++)
1309         *s2 = *s1;
1310 }
1311
1312 int
1313 copySNF(start, end, ptn, num, err)
1314 int     start;
1315 int     end;
1316 char    ***ptn;
1317 int     *num;
1318 char    *err;
1319 {
1320     FalFontID           fid;
1321     int                 mask;
1322     char                ** _ptn, **p;
1323     int                 i;
1324     static FalFontDataList      *copylist;
1325     int                 count;
1326     char                *point;
1327     int                 size;
1328
1329     mask =  FAL_FONT_MASK_XLFDNAME | FAL_FONT_MASK_DEFINED |
1330                                                 FAL_FONT_MASK_UNDEFINED;
1331     if (copyFontData.cd_set != -1) {
1332         mask |= FAL_FONT_MASK_CODE_SET;
1333     }
1334     if (! CodePoint) {
1335         mask |= FAL_FONT_MASK_GLYPH_INDEX;
1336     }
1337
1338     fid = FalOpenSysFont(&copyFontData, mask, &copylist);
1339     if (fid == 0) {
1340         strcpy(err, FAL_ERROR_STR);
1341         FalFreeFontList(copylist);
1342         return( -1 );
1343     }
1344
1345     _ptn = (char **)malloc(sizeof(char *) * (end - start + 1));
1346     if (! CodePoint) {
1347         for (i = start, count = 0, p = _ptn; i <= end; i++) {
1348             if (i & 0x80) {
1349                 i &= 0xff00;
1350                 i += 0x100;
1351                 continue;
1352             }
1353             point  = (char *)FalReadFont( fid, i, pm.width, pm.height );
1354             if( point == (char *)FAL_ERROR ) {
1355                 strcpy(err, FAL_ERROR_STR);
1356                 FalCloseFont( fid );
1357                 return( -1 );
1358             }
1359             if (EXISTS_FLAG != 0)
1360                 continue;
1361             size = pm.height * ((pm.width+7)/8);
1362             *p  = (char *) XtMalloc(size);
1363             bicopy(point, *p, size);
1364             count++; p++;
1365         }
1366     } else {
1367         for (i = start, count = 0, p = _ptn; i <= end; i++) {
1368             if (! (i & 0x80)) {
1369                 i &= 0xff00;
1370                 i |= 0x80;
1371                 continue;
1372             }
1373             point  = (char *)FalReadFont( fid, i, pm.width, pm.height );
1374             if( point == (char *)FAL_ERROR ) {
1375                 strcpy(err, FAL_ERROR_STR);
1376                 FalCloseFont( fid );
1377                 return( -1 );
1378             }
1379             if (EXISTS_FLAG != 0)
1380                 continue;
1381             size = pm.height * ((pm.width+7)/8);
1382             *p  = (char *) XtMalloc(size);
1383             bicopy(point, *p, size);
1384             count++; p++;
1385         }
1386     }
1387     *num = count;
1388     *ptn = _ptn;
1389     FalCloseFont( fid );
1390     if (count == 0) {
1391         strcpy(err, resource.mg_non_code);
1392         return( -1 );
1393     }
1394     return( 0 );
1395 }
1396
1397 void
1398 freeSNF(addr, count)
1399 char **addr;
1400 int count;
1401 {
1402     char **p;
1403     for (p=addr; count; count--, p++)
1404         XtFree(*p);
1405     XtFree((char *)addr);
1406 }
1407
1408 static int      sig_flg = 0;            /* flag for signal              */
1409
1410 /*
1411  * contents :   write character patterns to the specified SNF file 
1412  * values   :   0  : terminated normally 
1413  *              -1 : terminated abnormally 
1414  *            1xxx : process is not completed ¡Êxxx:persents finished¡Ë
1415  * 
1416  *
1417  */
1418
1419 int
1420 writeSNF( restart, err )
1421 int             restart;        /* ON:continue OFF:initial      */
1422 int             *err;           /* errors :                     */
1423 {
1424     static int          pfstdi[2];
1425     static FILE         *fstdi;
1426     static int          nptn;
1427     static int          width, height;
1428     static int          n;
1429     static int          persents = 0;
1430     char                *argv[8];
1431     int                 code;
1432     int                 endst;
1433     int                 persents_;
1434         
1435     char        ptn[MAXPTNBYTE];
1436     char        code_set[2];
1437
1438     FalGIInf    *gi;
1439     int         num_gi;
1440
1441     char        *command;
1442
1443     /* get command path */
1444     if (!(command = (char *)get_cmd_path(getenv("PATH"), resource.l_ptog_cmd))){
1445         command = resource.l_ptog;
1446     }
1447
1448     if (fullFontData.cd_set == FAL_FONT_CS0)
1449         sprintf(code_set, "0");
1450     else if (fullFontData.cd_set == FAL_FONT_CS1)
1451         sprintf(code_set, "1");
1452     else if (fullFontData.cd_set == FAL_FONT_CS2)
1453         sprintf(code_set, "2");
1454     else if (fullFontData.cd_set == FAL_FONT_CS3)
1455         sprintf(code_set, "3");
1456
1457     /* signal set */
1458     signal( SIGPIPE, sig_receive );
1459     sig_flg = 0;
1460
1461     if( restart == 0 ) {
1462
1463         persents = 0;
1464
1465         if( ptnGetInfo( &nptn, &width, &height ) != 0 ) {
1466             *err = 100;
1467             return( -1 );
1468         }
1469
1470         if( pipe(pfstdi) !=0 ) {
1471             *err = 101;
1472             return( -1 );
1473         }
1474
1475         switch( fork() ) {
1476         case -1:
1477             close( pfstdi[0] );    
1478             close( pfstdi[1] );    
1479             *err = 102;
1480             return( -1 );
1481         case 0:
1482             close( 0 );                 /** 0 ... stdin **/
1483
1484             dup(   pfstdi[0] );
1485             close( pfstdi[0] );
1486             close( pfstdi[1] );    
1487             argv[0] = resource.l_ptog_cmd;
1488             argv[1] = "-codeset";
1489             argv[2] = code_set;
1490             argv[3] = "-xlfd";
1491             argv[4] = fullFontData.xlfdname;
1492             argv[5] = "-init";
1493             argv[6] = "-f";
1494             argv[7] = NULL;
1495             execv (command, argv );
1496             exit( 103 );
1497         }
1498
1499
1500         close( pfstdi[0] );
1501         fstdi = (FILE *)fdopen( pfstdi[1], "w" );
1502         fprintf( fstdi, "numfonts:%d\n", nptn );
1503         fprintf( fstdi, "width:%d\n",    width );
1504         fprintf( fstdi, "height:%d\n",   height );
1505
1506         bitSetInfo( width, height );
1507         n = 0;
1508     }
1509
1510     while( (n < nptn) && ( sig_flg == 0) ) {
1511         code = noToCode( ptnSqToNo(n) );
1512         if( ptnGet(code, ptn ) != 0 ) {
1513             fclose( fstdi );
1514             close( pfstdi[1] );
1515             *err = 104;
1516             return( -1 );
1517         }
1518
1519         if (CodePoint) {
1520             fal_code_to_glyph(get_locale(), code, &gi, &num_gi);
1521             fprintf( fstdi, "code:0x%x\n", gi[0].glyph_index );
1522             FalFreeGI(gi, num_gi);
1523         } else {
1524             fprintf( fstdi, "code:0x%x\n", code );
1525         }
1526         writePtn(ptn, width, height, fstdi);
1527
1528         n++;
1529         if ( sig_flg != 0 )
1530             break;
1531         if( n == nptn ) {
1532             persents = 0;
1533             return( 1101 );
1534         }
1535         if( (persents_ = (n*100)/nptn) != persents ) {
1536                 persents = persents_;
1537                 return( 1000 + persents );
1538         }
1539     }
1540
1541     if(sig_flg == 0 )    fprintf( fstdi,  "enddata\n" );
1542
1543     fclose( fstdi );
1544     close( pfstdi[1] );
1545
1546     wait( &endst );
1547
1548
1549     if ( WIFEXITED(endst) && !WEXITSTATUS(endst) ) {
1550         *err = 0;
1551         return( 0 );
1552     }
1553     else {
1554         if ( WIFEXITED(endst) ) 
1555             *err = WEXITSTATUS(endst);
1556         else{
1557             if ( WIFSTOPPED(endst) )
1558                 *err = ( WTERMSIG(endst) << 8 );
1559         }
1560         return( -1 );
1561     }
1562 }
1563
1564
1565 /*
1566  * contents : set flag when dtudcfonted received signal
1567  */
1568
1569 static void
1570 sig_receive()
1571 {
1572     sig_flg = 1;
1573     return;
1574 }
1575
1576
1577 /*
1578  * contents : convert bit map file into SNF file 
1579  */
1580
1581 static void
1582 writePtn(ptn, width, height, fp)
1583 char    *ptn;
1584 int     width;
1585 int     height;
1586 FILE    *fp;
1587 {
1588     int         i, j, k;
1589     int         nbyte;
1590     int         tw;
1591     char        p, *pbuf;
1592     static char buf[ (MAXPTNSIZE+1)*MAXPTNSIZE+1 ];
1593
1594     nbyte = (width + 7) / 8;
1595
1596     pbuf = buf;
1597     for (i=0   ; i < height   ; i++) {
1598         for (j=0, tw=width   ; j < nbyte   ; j++ ) {
1599             p = *ptn++;
1600             for ( k=0   ; (k < 8) && (tw > 0)   ; k++, tw--) {
1601                 if (p & 0x80)
1602                     *pbuf++ = '0';
1603                 else
1604                     *pbuf++ = '-';
1605                 p = p << 1;
1606             }
1607         }
1608         *pbuf++ = '\n';
1609     }
1610     *pbuf = '\0';
1611     fprintf(fp, "%s", buf);
1612 }