Revert "dtudcfonted, dtudcexch: delete from repository"
[oweals/cde.git] / cde / programs / dtudcfonted / libfal / readpcf.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: readpcf.c /main/5 1996/06/05 16:42:29 ageorge $ */
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        <stdlib.h>
34 #include        <string.h>
35 #include        <errno.h>
36 #include        <sys/types.h>
37 #include        <sys/stat.h>
38 #include        <sys/mman.h>
39 #include        "FaLib.h"
40 #include        "falfont.h"
41
42 #ifndef GLYPHPADOPTIONS
43 #define GLYPHPADOPTIONS 4
44 #endif
45
46 static  CARD32  getLSB32();
47 static  int     getINT32();
48 static  int     getINT16();
49 static  Bool    seekToType();
50 static  void    getMetric();
51 static  Bool    getAccel();
52 int     falInitReadPcf();
53 static  void    ByteSwap();
54 static  void    repadBits();
55 int     falPcfGlyph();
56 void    falGetPcfGSize();
57 int     falInitReadPcfProp() ;
58 int     falInitReadSnfProp() ;
59 int     falReadGpfProp() ;
60
61 extern  void    BitOrderInvert() ;
62 extern  void    set_errfile_str() ;
63
64 static CARD32
65 getLSB32( p)
66 unsigned char *p;
67 {
68         CARD32  c;
69
70         c = *p++;
71         c |= (CARD32)(*p++) << 8;
72         c |= (CARD32)(*p++) << 16;
73         c |= (CARD32)(*p) << 24;
74
75         return c;
76 }
77
78 static int
79 getINT32( p, format)
80 unsigned char *p;
81 CARD32      format;
82 {
83         CARD32         c;
84
85         if (PCF_BYTE_ORDER(format) == MSBFirst) {
86                 c = (CARD32)(*p++) << 24;
87                 c |= (CARD32)(*p++) << 16;
88                 c |= (CARD32)(*p++) << 8;
89                 c |= (CARD32)(*p);
90         } else {
91                 c = (CARD32)(*p++);
92                 c |= (CARD32)(*p++) << 8;
93                 c |= (CARD32)(*p++) << 16;
94                 c |= (CARD32)(*p) << 24;
95         }
96
97         return (int)c;
98 }
99
100 static int
101 getINT16( p, format)
102 unsigned char *p;
103 CARD32      format;
104 {
105         CARD32         c;
106
107         if (PCF_BYTE_ORDER(format) == MSBFirst) {
108                 c = (CARD32)(*p++) << 8;
109                 c |= (CARD32)(*p);
110         } else {
111                 c = (CARD32)(*p++);
112                 c |= (CARD32)(*p) << 8;
113         }
114
115         return (int)c;
116 }
117
118 static Bool
119 seekToType( tables, ntables, type, formatp, sizep, offsetp)
120 PCFTablePtr tables;
121 int         ntables;
122 CARD32      type;
123 CARD32  *formatp;
124 CARD32  *sizep;
125 CARD32  *offsetp;
126 {
127         int     i;
128
129         for ( i = 0; i < ntables; i++) {
130                 if ( getLSB32( (unsigned char *)&tables[i].type ) == type) {
131                         if ( formatp)
132                                 *formatp = getLSB32( (unsigned char *)&tables[i].format);
133                         if ( sizep)
134                                 *sizep = getLSB32( (unsigned char *)&tables[i].size);
135                         if ( offsetp)
136                                 *offsetp = getLSB32( (unsigned char *)&tables[i].offset);
137                         return(TRUE);
138                 }
139         }
140         return(FALSE);
141 }
142
143
144
145 static void
146 getMetric( buf, format, metric)
147 caddr_t buf;
148 CARD32      format;
149 xCharInfo  *metric;
150 {
151         metric->leftSideBearing = getINT16( (unsigned char *)buf, (CARD32)format);
152         buf += 2;
153         metric->rightSideBearing = getINT16( (unsigned char *)buf, (CARD32)format);
154         buf += 2;
155         metric->characterWidth = getINT16( (unsigned char *)buf, (CARD32)format);
156         buf += 2;
157         metric->ascent = getINT16( (unsigned char *)buf, (CARD32)format);
158         buf += 2;
159         metric->descent = getINT16( (unsigned char *)buf, (CARD32)format);
160         buf += 2;
161         metric->attributes = getINT16( (unsigned char *)buf, (CARD32)format);
162         buf += 2;
163 }
164
165 static Bool
166 getAccel( pFontInfo,  maxink, buf_top, tables, ntables, type)
167 FontInfoPtr     pFontInfo;
168 xCharInfo       *maxink;
169 caddr_t         buf_top;
170 PCFTablePtr     tables;
171 int             ntables;
172 CARD32          type;
173 {
174         CARD32  format;
175         CARD32  offset;
176         caddr_t buffer;
177
178         if ( !seekToType( tables, ntables, (CARD32)type, &format, (CARD32 *)NULL, &offset))
179                 return FALSE;
180
181         buffer = buf_top + offset;
182         format = getLSB32( (unsigned char *)buffer );
183         buffer += 4;
184         if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
185             !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
186                 return FALSE;
187         }
188         pFontInfo->noOverlap = *buffer++;
189         pFontInfo->constantMetrics = *buffer++;
190         pFontInfo->terminalFont = *buffer++;
191         pFontInfo->constantWidth = *buffer++;
192         pFontInfo->inkInside = *buffer++;
193         pFontInfo->inkMetrics = *buffer++;
194         pFontInfo->drawDirection = *buffer++;
195         /*  pFontInfo->anamorphic = FALSE; */
196         /* natural alignment */ buffer++;
197         pFontInfo->fontAscent = getINT32( (unsigned char *)buffer, (CARD32)format);
198         buffer += 4;
199         pFontInfo->fontDescent = getINT32( (unsigned char *)buffer, (CARD32)format);
200         buffer +=4;
201
202         /*  pFontInfo->maxOverlap = getINT32( (unsigned char *)buffer, (CARD32)format); */ buffer += 4;
203         getMetric(buffer, format, &pFontInfo->minbounds.metrics);
204         buffer += 12;
205         getMetric(buffer, format, &pFontInfo->maxbounds.metrics);
206         buffer += 12;
207         if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
208                 buffer += 12;
209                 getMetric( buffer, format, maxink);
210         } else {
211                 *maxink = pFontInfo->maxbounds.metrics;
212         }
213         return TRUE;
214 }
215
216 int
217 falInitReadPcf( pcfinf, buftop)
218 struct pcf_inf *pcfinf;
219 caddr_t buftop;
220 {
221         CARD32  format;
222         CARD32  offset;
223         CARD32      *bitmapSizes;
224         xCharInfo       maxink;
225         caddr_t buffp;
226
227         if ( getLSB32( (unsigned char *)buftop ) != PCF_FILE_VERSION)
228                 goto Bail;
229
230         pcfinf->ntables = getLSB32( (unsigned char *)(buftop + 4) );
231
232         pcfinf->tables = (PCFTablePtr)(buftop + 8);
233
234         if ( !getAccel( &pcfinf->info, &maxink, buftop, pcfinf->tables, pcfinf->ntables,
235             (CARD32)PCF_BDF_ACCELERATORS))
236                 if ( !getAccel( &pcfinf->info, &maxink, buftop, pcfinf->tables, pcfinf->ntables,
237                     (CARD32)PCF_ACCELERATORS))
238                         goto Bail;
239
240         pcfinf->org_bounds = pcfinf->info.maxbounds.metrics;
241
242         if ( !seekToType( pcfinf->tables, pcfinf->ntables, (CARD32)PCF_BITMAPS,
243                         &format, (CARD32 *)NULL, &offset))
244                 goto Bail;
245
246         buffp = buftop + offset;
247
248         format = getLSB32( (unsigned char *)buffp );
249         buffp += 4;
250         if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
251                 goto Bail;
252
253         pcfinf->nbitmaps = getINT32( (unsigned char *)buffp, (CARD32)format);
254         buffp += 4;
255         pcfinf->offsets = (CARD32 *)buffp;
256         buffp += sizeof( *pcfinf->offsets) * pcfinf->nbitmaps;
257
258         bitmapSizes = (CARD32 *)buffp;
259         pcfinf->sizebitmaps = getINT32( (unsigned char *)&bitmapSizes[PCF_GLYPH_PAD_INDEX(format)], (CARD32)format);
260         pcfinf->bmp_fmt = format;
261         buffp += sizeof( *bitmapSizes) * GLYPHPADOPTIONS;
262         pcfinf->bitmaps = buffp;
263         buffp += pcfinf->sizebitmaps;
264
265         if ( !seekToType( pcfinf->tables, pcfinf->ntables, (CARD32)PCF_BDF_ENCODINGS,
266                         &format, (CARD32 *)NULL, &offset))
267                 goto Bail;
268
269         buffp = buftop + offset;
270         format = getLSB32( (unsigned char *)buffp );
271         buffp += 4;
272         if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
273                 goto Bail;
274
275         pcfinf->info.firstCol   = getINT16( (unsigned char *)buffp, (CARD32)format);
276         buffp += 2;
277         pcfinf->info.lastCol    = getINT16( (unsigned char *)buffp, (CARD32)format);
278         buffp += 2;
279         pcfinf->info.firstRow   = getINT16( (unsigned char *)buffp, (CARD32)format);
280         buffp += 2;
281         pcfinf->info.lastRow    = getINT16( (unsigned char *)buffp, (CARD32)format);
282         buffp += 2;
283         /*
284             pcfinf->info.defaultCh      = getINT16( (unsigned char *)buffp, (CARD32)format); buffp += 2;
285         */
286         pcfinf->info.chDefault  = getINT16( (unsigned char *)buffp, (CARD32)format);
287         buffp += 2;
288
289         pcfinf->info.allExist   = FALSE;
290         pcfinf->enc_fmt = format;
291         pcfinf->encodingOffsets = (CARD16 *)buffp;
292
293         return 0;
294 Bail:
295         return -1;
296 }
297
298 static void
299 ByteSwap( p, scan)
300 char    *p;
301 int     scan;
302 {
303         char    w;
304
305         switch( scan) {
306         case 1:
307                 break;
308         case 2:
309                 w = *p;
310                 *p = *(p + 1);
311                 *(p + 1) = w;
312                 break;
313         case 4:
314                 w = *p;
315                 *p = *(p + 3);
316                 *(p + 3) = w;
317                 w = *(p + 1);
318                 *(p + 1) = *(p + 2);
319                 *(p + 2) = w;
320                 break;
321         }
322 }
323 static void
324 repadBits( src, format, width, height, dest)
325 char    *src;
326 CARD32  format;
327 int     width, height;
328 char    *dest;
329 {
330         int     bit, byte, glyph, scan;
331         int     src_bytewidth, dest_bytewidth;
332         char    work[8];
333         int     i, j;
334
335         bit = PCF_BIT_ORDER( format);
336         byte = PCF_BYTE_ORDER( format);
337         glyph = PCF_GLYPH_PAD( format);
338         scan = PCF_SCAN_UNIT( format);
339
340         src_bytewidth = (( width + ( 8 * glyph ) - 1)/( 8 * glyph)) * glyph;
341         dest_bytewidth = ( width + 7) /8;
342
343         for ( i = 0; i < height; i++, src += src_bytewidth,
344             dest += dest_bytewidth) {
345                 for ( j = 0; j < src_bytewidth; j += scan) {
346                         memcpy( work, src + j, scan);
347                         if ( bit == LSBFirst)
348                                 BitOrderInvert( work, scan );
349                         if ( byte == LSBFirst)
350                                 ByteSwap( work, scan);
351                         if (( j + scan) >= dest_bytewidth) {
352                                 memcpy( dest + j, work, dest_bytewidth - j);
353                                 break;
354                         }
355                         memcpy( dest + j, work, scan);
356                 }
357         }
358 }
359
360 int
361 falPcfGlyph( glyph, finf, code)
362 char    *glyph;
363 Oak_FontInf  *finf;
364 int     code;
365 {
366         int     encode;
367         int     inner_code;
368         char    *bitmap;
369         int     encodingOffset;
370         int             codeRow, codeCol;
371         int     bytewidth;
372         int bmp_adj, ptn_adj;
373         int adj_hi;
374         int cpy_height;
375         int bmp_height;
376
377         if ( !glyph){
378                 fal_utyerrno = FAL_ERR_PARM ;
379                 return FAL_ERROR ;
380         }
381
382         inner_code = code;
383         codeCol = inner_code & 0xff;
384         codeRow = (inner_code >> 8) & 0xff;
385
386         /* code check */
387         if (
388             ((code < finf->start) || (code > finf->end))||
389             ((codeCol < finf->pFinf->firstCol)||(codeCol > finf->pFinf->lastCol))||
390             ((codeRow < finf->pFinf->firstRow)||(codeRow > finf->pFinf->lastRow))
391             ) {
392                 fal_utyexists = 1;
393                 return(-1);
394         }
395
396         encode = (codeRow - finf->pFinf->firstRow) * ( finf->pFinf->lastCol - finf->pFinf->firstCol + 1);
397         encode += codeCol - finf->pFinf->firstCol;
398         encodingOffset = getINT16( (unsigned char *)(finf->pcfinf.encodingOffsets + encode), finf->pcfinf.enc_fmt);
399
400         if (encodingOffset == 0xFFFF) {
401                 fal_utyexists = 1;
402                 return(-1);
403         }
404         fal_utyexists = 0;
405
406         bitmap = finf->pcfinf.bitmaps + getINT32( (unsigned char *)(finf->pcfinf.offsets + encodingOffset), finf->pcfinf.bmp_fmt);
407
408         bmp_height = finf->pFinf->maxbounds.metrics.ascent
409             + finf->pFinf->maxbounds.metrics.descent;
410         if (( adj_hi = finf->pFinf->maxbounds.metrics.ascent
411             - finf->pcfinf.org_bounds.ascent) > 0) {
412                 bytewidth = 8 * PCF_GLYPH_PAD( finf->pcfinf.bmp_fmt);
413                 bytewidth = (( finf->width + bytewidth - 1)/ bytewidth ) * PCF_GLYPH_PAD( finf->pcfinf.bmp_fmt);
414                 bmp_adj = bytewidth * adj_hi;
415                 ptn_adj = 0;
416                 if (( cpy_height = bmp_height - adj_hi) > finf->height)
417                         cpy_height = finf->height;
418         } else if ( adj_hi < 0) {
419                 adj_hi *= -1;
420                 bytewidth = ( finf->width + 7) / 8;
421                 bmp_adj = 0;
422                 ptn_adj = bytewidth * adj_hi;
423                 if (( cpy_height = finf->height - adj_hi) > bmp_height)
424                         cpy_height = bmp_height;
425         } else {
426                 bmp_adj = 0;
427                 ptn_adj = 0;
428                 cpy_height = finf->height;
429         }
430
431         repadBits( bitmap + bmp_adj , finf->pcfinf.bmp_fmt, finf->width, cpy_height, glyph + ptn_adj);
432         return(0);
433 }
434
435 void
436 falGetPcfGSize( pcfinf, widthp, heightp)
437 struct pcf_inf *pcfinf;
438 unsigned int   *widthp, *heightp;
439 {
440         unsigned int    w, h;
441
442         w = pcfinf->org_bounds.rightSideBearing
443             - pcfinf->org_bounds.leftSideBearing;
444         h = pcfinf->org_bounds.ascent + pcfinf->org_bounds.descent;
445
446         *widthp = w;
447         *heightp = h;
448 }
449
450
451
452
453 /********************************************************
454  *
455  * functions for collect GPF file properties
456  *
457  *******************************************************/
458
459 #include "fontstruct.h"
460
461 static  char    *getPcfFontProp();
462 static  char    *getSnfFontProp();
463 /*
464 * read properties and get font style and
465 * letter size
466 */
467
468 int
469 falReadFontProp( file, protect_key_data, databuff, islock )
470 char                    *file ;         /* name of font file */
471 int                     protect_key_data ;
472 FalFontData             *databuff ;
473 int                     islock ;
474 {
475         Oak_FontInf     finf;
476         int             fd ;
477         char            *buf;
478         char            *openfontfile;
479         struct  stat    st;
480         int             rtn ;
481
482         /* initialezation  */
483         openfontfile = file ;
484
485         /* read a condition of a fontfile */
486         if ( stat( openfontfile, &st ) < 0 ) {
487                 set_errfile_str( fal_err_file, openfontfile ) ;
488                 fal_utyerror = _FAL_STAT_ER;
489                 fal_utyderror = errno;
490                 fal_utyerrno = FAL_ERR_STAT ;
491                 return  FAL_ERROR;
492         }
493
494         if ( st.st_size < sizeof( FontInfoRec ) ) {
495                 fal_utyerror = _FAL_FONT_ER;
496                 fal_utyderror = 0;
497                 fal_utyerrno = FAL_ERR_FONT ;
498                 return  FAL_ERROR;
499         }
500
501         /* open a fontfile */
502         if ( (fd = open( openfontfile, ((islock)? O_RDONLY : O_RDWR) )) < 0 ) {
503              switch( errno ) {
504                 case EACCES :
505                     return _FAL_TRY_NEXT ;
506                 default :
507                     set_errfile_str( fal_err_file, openfontfile ) ;
508                     fal_utyerror = _FAL_OPEN_ER;
509                     fal_utyderror = errno;
510                     fal_utyerrno = FAL_ERR_FNT_OPN ;
511                     return      FAL_ERROR;
512              }
513         }
514
515 #if     defined( SVR4 )
516         buf = (char *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
517         if ( buf != (char *)-1 ) {
518                 /* if "mmap" is normal end */
519                 close( fd );
520                 finf.ismmap = TRUE;
521                 finf.fsize = st.st_size;
522         } else {
523                 /* if "mmap" is abnormal end , try "read()" */
524                 finf.ismmap = FALSE;
525                 if ( !(buf = (char *)malloc(st.st_size)) ) {
526                         fal_utyerror = _FAL_MALOC_ER;
527                         fal_utyderror = 0;
528                         fal_utyerrno = FAL_ERR_MALLOC ;
529                         close( fd );
530                         return  FAL_ERROR;
531                 }
532                 if ( read(fd, buf, st.st_size) != st.st_size ) {
533                         set_errfile_str( fal_err_file, openfontfile ) ;
534                         fal_utyerror = _FAL_READ_ER;
535                         fal_utyderror = errno;
536                         fal_utyerrno = FAL_ERR_FNT_RD ;
537                         free( buf );
538                         close( fd );
539                         return  FAL_ERROR;
540                 }
541         }
542 #else
543         finf.ismmap = FALSE;
544         if ( !(buf = (char *)malloc( st.st_size )) ) {
545                 fal_utyerror = _FAL_MALOC_ER;
546                 fal_utyderror = 0;
547                 fal_utyerrno = FAL_ERR_MALLOC ;
548                 close( fd );
549                 return  FAL_ERROR;
550         }
551         if ( read(fd, buf, st.st_size) != st.st_size ) {
552                 set_errfile_str( fal_err_file, openfontfile ) ;
553                 fal_utyerror = _FAL_READ_ER;
554                 fal_utyderror = errno;
555                 fal_utyerrno = FAL_ERR_FNT_RD ;
556                 free( buf );
557                 close( fd );
558                 return  FAL_ERROR;
559         }
560 #endif
561
562         finf.fname = openfontfile ;
563         finf.buf   = buf ;
564
565         /*
566         *       open GPF font file
567         */
568         rtn = falReadGpfProp( FAL_UPDATE_FONTINFO, &finf, protect_key_data, databuff ) ;
569 #if     defined( SVR4 )
570         if ( finf.ismmap == TRUE ) {
571                 munmap( buf, finf.fsize );
572         } else {
573                 free(buf);
574                 close(fd);
575         }
576 #else
577         free( buf );
578         close( fd );
579 #endif
580
581         return( rtn ) ;
582 }
583
584
585 /*
586 *       get properties of GPF format file
587 */
588 int
589 falReadGpfProp( updflg, finf, protect_key_data, databuff )
590 int             updflg ;
591 Oak_FontInf     *finf;
592 int             protect_key_data ;
593 FalFontData     *databuff ;
594 {
595         char            *openfontfile;
596         int             rtn ;
597
598         /* initialize  */
599         openfontfile = finf->fname ;
600
601         if( updflg == FAL_UPDATE_FONTINFO ) {
602             /* case of a PCF format font */
603             if ( strcmp( FILE_SUFFIX( openfontfile ), PCFSUFFIX ) == 0 ) {
604
605                 finf->isFef = FALSE;
606                 finf->isPcf = TRUE;
607
608             }
609             else        /* case of a SNF format font */
610             {
611                 FAL_READ_SNF_HEADER( finf, protect_key_data, fal_utyerror, fal_utyderror ) ;
612             }
613         }       /* updflg */
614
615         /*
616         *       get font properties
617         */
618         if ( finf->isFef ){
619                 /* read SNF format property */
620                 if ( rtn = falInitReadSnfProp( finf, (caddr_t)finf->pFinf, databuff ) ) {
621                         if( rtn == _FAL_TRY_NEXT ){
622                                 return( rtn ) ;
623                         }
624                         fal_utyerror = _FAL_FONT_ER;
625                         fal_utyderror = 0;
626                         return  FAL_ERROR;
627                 }
628         } else if ( finf->isPcf ) {
629                 /* read PCF format property */
630                 if ( rtn = falInitReadPcfProp( updflg, finf, databuff ) ) {
631                         if( rtn == _FAL_TRY_NEXT ){
632                                 return( rtn ) ;
633                         }
634                         fal_utyerror = _FAL_FONT_ER;
635                         fal_utyderror = 0;
636                         return  FAL_ERROR;
637                 }
638
639                 if( updflg == FAL_UPDATE_FONTINFO ) {
640                         finf->pFinf = &finf->pcfinf.info;
641                         finf->pCinf = NULL;
642                         finf->pGlyphs = NULL;
643                 }
644         } else {
645                 fal_utyerror = _FAL_FONT_ER;
646                 fal_utyderror = 0;
647                 fal_utyerrno = FAL_ERR_FONT ;
648                 return  FAL_ERROR;
649         }
650
651         return(0);
652 }
653
654
655 /*
656 *       get properties of PCF format file
657 */
658 int
659 falInitReadPcfProp( updflg, finf, databuff )
660 int             updflg ;
661 Oak_FontInf     *finf;
662 FalFontData     *databuff ;
663 {
664         struct pcf_inf  *pcfinf;
665         caddr_t         buftop;
666         xCharInfo       maxink;
667         caddr_t buffp;
668         int     lb, rb, as, ds ;
669
670
671
672         pcfinf = &finf->pcfinf ;
673         buftop = finf->buf ;
674
675         if ( getLSB32( (unsigned char *)buftop ) != PCF_FILE_VERSION)
676                 return _FAL_TRY_NEXT ;
677
678         if( updflg == FAL_UPDATE_FONTINFO ) {
679                 pcfinf->ntables = getLSB32( (unsigned char *)(buftop + 4) );
680
681                 pcfinf->tables = (PCFTablePtr)(buftop + 8);
682
683                 if ( !getAccel( &pcfinf->info, &maxink, buftop, pcfinf->tables,
684                         pcfinf->ntables, (CARD32)PCF_BDF_ACCELERATORS)) {
685                         if ( !getAccel( &pcfinf->info, &maxink, buftop, pcfinf->tables,
686                                 pcfinf->ntables, (CARD32)PCF_ACCELERATORS)) {
687                             fal_utyerrno = FAL_ERR_FONT ;
688                             goto Bail;
689                         }
690                 }
691
692         }
693
694         /*
695         *       read property
696         */
697
698         if( updflg == FAL_UPDATE_FONTINFO ) {
699                 pcfinf->org_bounds = pcfinf->info.maxbounds.metrics;
700         }
701
702         lb = pcfinf->org_bounds.leftSideBearing ;
703         rb = pcfinf->org_bounds.rightSideBearing ;
704         as = pcfinf->org_bounds.ascent  ;
705         ds = pcfinf->org_bounds.descent ;
706
707         databuff->size.w = rb - lb ;
708         databuff->size.h = as + ds ;
709
710         /*
711         * read property "FONT"
712         */
713         if ( buffp = getPcfFontProp( buftop, pcfinf->tables,
714                                      pcfinf->ntables, "FONT" )) {
715                 if( (databuff->xlfdname = (char *)strdup( buffp )) == (char *)NULL ){
716                         fal_utyerrno = FAL_ERR_MALLOC ;
717                         goto Bail;
718                 }
719         }else{
720                 set_errfile_str( fal_err_file, finf->fname ) ;
721                 fal_utyerrno = FAL_ERR_PROP_FONT ;
722                 return( _FAL_TRY_NEXT ) ;
723         }
724
725         /*
726         * read property "FAMILY_NAME"
727         */
728         if ( buffp = getPcfFontProp( buftop, pcfinf->tables,
729                                      pcfinf->ntables, "FAMILY_NAME")) {
730                 if( (databuff->style.name = (char *)strdup( buffp )) == NULL ){
731                         fal_utyerrno = FAL_ERR_MALLOC ;
732                         goto Bail ;
733                 }
734         }else{
735                 set_errfile_str( fal_err_file, finf->fname ) ;
736                 fal_utyerrno = FAL_ERR_PROP_FNAME ;
737                 return( _FAL_TRY_NEXT ) ;
738         }
739
740         return 0;
741 Bail:
742         return -1;
743 }
744
745
746
747 static char *
748 getPcfFontProp( buftop, tables, ntables, propname)
749 caddr_t buftop;
750 PCFTablePtr     tables;
751 int             ntables;
752 char            *propname;
753 {
754         caddr_t buffer;
755         int name_ofs;
756         int i ;
757         int nprops;
758         char *propstr ;
759         CARD32  format, offset;
760
761         if ( !seekToType( tables, ntables, (CARD32)PCF_PROPERTIES, &format, (CARD32 *)NULL, &offset))
762                 return NULL;
763
764         buffer = buftop + offset;
765         format = getLSB32( (unsigned char *)buffer );
766         buffer += 4;
767         if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT))
768                 return NULL;
769
770         nprops = getINT32( (unsigned char *)buffer, (CARD32)format);
771         buffer += 4;
772         propstr = buffer + (4 * ((nprops * 9 + 3) / 4)) + 4;
773
774         for ( i=0; i < nprops ; i++ ) {
775                 name_ofs = getINT32( (unsigned char *)buffer, (CARD32)format ) ;
776                 buffer += 4 ;   /* name */
777                 if ( strcmp( propstr + name_ofs, propname) == 0) {
778                         if ( *buffer) {         /* isStringProp */
779                                 return( propstr + getINT32( (unsigned char *)(buffer + 1), (CARD32)format) );
780                         }else{
781                                 return((char *)(intptr_t)getINT32( (unsigned char *)(buffer + 1), (CARD32)format) );
782                         }
783                 }
784                 buffer += 5 ;   /* isStringProp + value */
785         }
786
787         return( NULL);
788 }
789
790
791 /*
792 *       get properties of SNF format file
793 */
794 int
795 falInitReadSnfProp( finf, buftop, databuff )
796 Oak_FontInf             *finf;          /* pointer to the infomation structure */
797 caddr_t                 buftop;         /* font file */
798 FalFontData             *databuff ;
799 {
800         caddr_t stprop ;
801         int     lb, rb, as, ds ;
802         char    *propptr ;
803         char    *fnt = NULL, *fam ;
804         int     nprops, bitmapSize, num_chars ;
805
806
807         /* initialize pointer */
808         nprops    = finf->pFinf->nProps ;
809         num_chars = ( finf->pFinf->lastRow - finf->pFinf->firstRow + 1 ) *
810                     ( finf->pFinf->lastCol - finf->pFinf->firstCol + 1 ) ;
811         bitmapSize = BYTESOFGLYPHINFO(finf->pFinf) ;
812
813         stprop = buftop ;
814         stprop += sizeof(FontInfoRec) ;
815         stprop += num_chars * sizeof(CharInfoRec) ;
816         stprop += bitmapSize ;
817
818         /*
819         *        read property "FONTBOUNDINGBOX"
820         */
821         lb = finf->pFinf->maxbounds.metrics.leftSideBearing ;
822         rb = finf->pFinf->maxbounds.metrics.rightSideBearing ;
823         as = finf->pFinf->maxbounds.metrics.ascent  ;
824         ds = finf->pFinf->maxbounds.metrics.descent ;
825
826         /*
827         *       read property "FONT"
828         */
829         if ( propptr = getSnfFontProp( stprop, nprops, "FONT" )) {
830                 if( (fnt = (char *)strdup( propptr )) == NULL ){
831                         fal_utyerrno = FAL_ERR_MALLOC ;
832                         goto Bail;
833                 }
834         }else{
835                 set_errfile_str( fal_err_file, finf->fname ) ;
836                 fal_utyerrno = FAL_ERR_PROP_FONT ;
837                 return( _FAL_TRY_NEXT ) ;
838         }
839
840         /*
841         *       read property "FAMILY_NAME"
842         */
843         if ( propptr = getSnfFontProp( stprop, nprops, "FAMILY_NAME")) {
844                 if( (fam = (char *)strdup( propptr )) == NULL ){
845                         fal_utyerrno = FAL_ERR_MALLOC ;
846                         goto Bail ;
847                 }
848         }else{
849                 set_errfile_str( fal_err_file, finf->fname ) ;
850                 fal_utyerrno = FAL_ERR_PROP_FNAME ;
851                 free(fnt);
852                 return( _FAL_TRY_NEXT ) ;
853         }
854
855         /*
856         *       set data buffer
857         */
858
859         databuff->size.w = rb - lb ;
860         databuff->size.h = as + ds ;
861
862         databuff->xlfdname      = fnt ;
863         databuff->style.name    = fam ;
864
865         return 0;
866 Bail:
867         free(fnt);
868         return -1;
869 }
870
871
872
873 static char *
874 getSnfFontProp( buftop, nprops, propname )
875 caddr_t         buftop;
876 int             nprops ;
877 char            *propname;
878 {
879         caddr_t buffer;
880         int name_ofs;
881         int i ;
882         char *propstr ;
883         FontPropRec     *ProcRec ;
884
885         ProcRec = (FontPropRec *)buftop ;
886         buffer  = (char *)buftop ;
887         propstr = buffer + nprops * sizeof(FontPropRec) ;
888
889         for ( i=0; i < nprops ; i++, ProcRec++ ) {
890                 name_ofs = ProcRec->name ;
891                 if( strcmp( propstr + name_ofs, propname ) == 0 ){
892                         if( ProcRec->indirect ){
893                             return( propstr + ProcRec->value ) ;
894                         }else{
895                             return( (char *) (intptr_t) ProcRec->value ) ;
896                         }
897                 }
898         }
899
900         return( NULL);
901 }
902
903 /***********************< end of readpcf.c >********************/