ftp.nice.ch/pub/next/unix/fonts/font.conversion.NIHS.bs.tar.gz#/font_conversion_NIHS.bs/mfrc/Source/mfrc.c

This is mfrc.c in view mode; [Download] [Up]

#include <stdio.h>
#include <sys/types.h>
#include <strings.h>
#include <ctype.h>
#include <stdlib.h>

#include "mfrc.h"

int cmpid(rl1,rl2)
ref_list *rl1, *rl2;
{
    return rl1->id - rl2->id;
}

int main(argc,argv)
int argc;
char **argv;
{
    char *progname;
    FILE *fp, *of;
    info_header infobuf;
    type_info typbuf;
    ref_list *rfptr, *rfent;
    unsigned char *pdata, *cp, *cp2;
    char onm[BUFSIZ], anm[BUFSIZ];
    unsigned long rsrc,rsd,rsm;
    long rslen;
    unsigned short rstl;
    short rstypes;
    int c,len;

    progname = argv[0];
    if (argc < 2) {
        fprintf(stderr, "Usage: %s file ...\n", progname);
        exit(1);
    }

    while (--argc) {
        ++argv;
        fp = fopen(*argv,"r");
        if (fp == NULL) {
            perror(*argv);
            continue;
        }

        fprintf(stderr,"%s: ",*argv);
        if (fread(&infobuf,sizeof(info_header),1,fp) < 1 ) {
            fclose(fp);
            fprintf(stderr,"No header\n");
            continue;
        }

        if (infobuf.version || infobuf.nlen) {
            rsrc = sizeof(info_header) + (infobuf.dlen[0]<<24) +
              (infobuf.dlen[1]<<16) + (infobuf.dlen[2]<<8) +
              infobuf.dlen[3];

            if ((infobuf.type[0]!='L') || (infobuf.type[1]!='W')
              || (infobuf.type[2]!='F')
              || (infobuf.type[3]!='N')) {
                fclose(fp);
                fprintf(stderr,"File not type LWFN.\n");
                continue;
            }

            if (rsrc > sizeof(info_header))
                fseek(fp,rsrc,SEEK_SET);
        }
        else rsrc = 0;

        fread(&rsd,4,1,fp);
        fread(&rsm,4,1,fp);
        fseek(fp,rsrc+rsm+24,SEEK_SET);
        fread(&rstl,2,1,fp);
        fseek(fp,rsrc+rsm+rstl,SEEK_SET);
        fread(&rstypes,2,1,fp);

        while (rstypes >= 0) {
            fread(&typbuf,sizeof(typbuf),1,fp);
            if (typbuf.rtype == POST_TYPE)
                break;
            --rstypes;
        }

        if (rstypes < 0) {
            fclose(fp);
            fprintf(stderr,"No POST resources.\n");
            continue;
        }

        /* Read list of POST resources and sort by resource ID */
        fseek(fp,rsrc+rsm+rstl+typbuf.offset,SEEK_SET);
        rfptr = (ref_list *)malloc(sizeof(ref_list) * (typbuf.nrsc+1));
        fread(rfptr,sizeof(ref_list),typbuf.nrsc+1,fp);
        qsort(rfptr,typbuf.nrsc+1,sizeof(ref_list),cmpid);

        /* Process POST resources */
        of=NULL;
        onm[0] = '\0';
        rfent = rfptr;
        len=0;
        while (typbuf.nrsc-- >= 0) {
            fseek(fp,rsrc+rsd+(rfent->offset & 0xffffff),SEEK_SET);
            fread(&rslen,4,1,fp);
            pdata = (unsigned char *)malloc(rslen);
            fread(pdata,rslen,1,fp);
            switch (pdata[0]) {
                case POST_TEXT:
                    if (!of) {
                        cp=pdata+2;
                        while (cp < pdata+rslen) {
                            if (*cp == '/') {
                                if (!strncmp((char *)cp,"/FontName",9)) {
                                    cp += 9;
                                    if (isspace(*cp)) {
                                        while (*cp++ != '/');
                                        cp2=(unsigned char *)onm;
                                        while (!isspace((char)*cp))
                                            *cp2++ = *cp++;
                                        *cp2 = '\0';
                                        break;
                                    }
                                }
                            }
                            cp++;
                        }
                        if (!onm[0])
                            sprintf(onm,"%s.psf",*argv);
                        of=fopen(onm,"w");
                        if (!of) {
                            perror(onm);
                            free(pdata);
                            fprintf(stderr,"%s: ",*argv);
                            continue;
                        }
                    }
                    cp=pdata+2;
                    while (cp < pdata+rslen) {
                        if (*cp == '\r')
                            *cp='\n';
                        cp++;
                    }
                    if (len) {
                        fprintf(of,"\n");
                        len=0;
                    }
                    fwrite(pdata+2,rslen-2,1,of);
                    break;
                case POST_DATA:
                    if (!of) {
                        fprintf(stderr, "Data before text.\n");
                        free(pdata);
                        fprintf(stderr,"%s: ",*argv);
                        continue;
                    }
                    cp=pdata+2;
                    while (cp < pdata+rslen) {
                        fprintf(of,"%02x",*cp++);
                        if (++len > 31) {
                            fprintf(of,"\n");
                            len = 0;
                        }
                    }
                    break;
                case POST_END:
                    break;
                default:
                    fprintf(stderr, "Unknown POST resource type %d.\n",
                            pdata[0]);
            } /* end switch */
            free(pdata);
            ++rfent;
        } /* while more POST resources */
        if (len)
            fprintf(of,"\n");
        fclose(of);
        fclose(fp);
        free(rfptr);

        /* check for afm file */
        if (!onm[0]) {
            fprintf(stderr,"no font data.\n");
            continue;
        }
        fprintf(stderr,"converted to %s.\n",onm);
        strcpy(anm,*argv);
        strcat(anm,".afm");
        fp=fopen(anm,"r");
        if (!fp)
            continue;

        if (fread(&infobuf,sizeof(info_header),1,fp) < 1) {
            fclose(fp);
            continue;
        }

        if (infobuf.version || infobuf.nlen) {
            rslen = (infobuf.dlen[0]<<24) + (infobuf.dlen[1]<<16)
              + (infobuf.dlen[2]<<8) + infobuf.dlen[3];
            if (rslen < 1) {
                fclose(fp);
                continue;
            }
        }
        else rslen=0;

        strcat(onm,".afm");
        of=fopen(onm,"w");
        if (!of) {
            fclose(fp);
            continue;
        }
        do {
            c=getc(fp);
            if (c=='\r')
                putc('\n',of);
            else
                putc(c,of);
        } while (--rslen);
        fclose(of);
        fclose(fp);
    } /* while more files */

    return 0;
} /* end main */

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.