[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/tcpdf/fonts/old/pfm2afm/source/ -> pfm2afm.c (source)

   1  /********************************************************************
   2   *                                                                  *
   3   *  Title:  pfm2afm - Convert Windows .pfm files to .afm files      *
   4   *                                                                  *
   5   *  Author: Ken Borgendale   10/9/91  Version 1.0                   *
   6   *                                                                  *
   7   *  Function:                                                       *
   8   *      Convert a Windows .pfm (Printer Font Metrics) file to a     *
   9   *      .afm (Adobe Font Metrics) file.  The purpose of this is     *
  10   *      to allow fonts put out for Windows to be used with OS/2.    *
  11   *                                                                  *
  12   *  Syntax:                                                         *
  13   *      pfm2afm  infile  [outfile] -a                               *
  14   *                                                                  *
  15   *  Copyright:                                                      *
  16   *      pfm2afm - Copyright (C) IBM Corp., 1991                     *
  17   *                                                                  *
  18   *      This code is released for public use as long as the         *
  19   *      copyright remains intact.  This code is provided asis       *
  20   *      without any warrenties, express or implied.                 *
  21   *                                                                  *
  22   *  Notes:                                                          *
  23   *      1. Much of the information in the original .afm file is     *
  24   *         lost when the .pfm file is created, and thus cannot be   *
  25   *         reconstructed by this utility.  This is especially true  *
  26   *         of data for characters not in the Windows character set. *
  27   *                                                                  *
  28   *      2. This module is coded to be compiled by the MSC 6.0.      *
  29   *         For other compilers, be careful of the packing of the    *
  30   *         PFM structure.                                           *
  31   *                                                                  *
  32   ********************************************************************/
  33  
  34  
  35  /********************************************************************
  36   *  Modified:  Russell Lang <[email protected]>                 *
  37   *             1994-01-06  Version 1.1                              *
  38   *  Compiles with EMX/GCC                                           *
  39   *  Changed to AFM 3.0                                              *
  40   *  Put PFM Copyright in Notice instead of Comment                  *
  41   *  Added ItalicAngle                                               *
  42   *  Added UnderlinePosition                                         *
  43   *  Added UnderlineThickness                                        *
  44   *                                                                  *
  45   *  Modified 1995-03-10  rjl (fixes from Norman Walsh)              *
  46   *  Dodge compiler bug when creating descender                      *
  47   ********************************************************************/
  48  
  49  
  50  /********************************************************************
  51   *  Modified:  Olivier Plathey <[email protected]>                   *
  52   *             2002-08-10  Version 1.11                             *
  53   *  Compiles with MinGW                                             *
  54   *  Output Descender as negative value                              *
  55   *  Removed double spaces in character entries                      *
  56   *                                                                  *
  57   *             2005-03-12  Version 1.12                             *
  58   *  Doubled size of BUFSIZE                                         *
  59   ********************************************************************/
  60  
  61  #include <stdio.h>
  62  #include <string.h>
  63  #include <stdlib.h>
  64  #include "pfm2afm.h"
  65  
  66  #define BUFSIZE 8192
  67  /*
  68   *  Function Prototypes
  69   */
  70  void  help (void);
  71  void  parseargs (int argc, uchar * * argv);
  72  void  openpfm(void);
  73  void  openafm(void);
  74  void  putheader(void);
  75  void  putchartab(void);
  76  void  outchar(int code, ushort width, const uchar * name);
  77  void  putkerntab(KERN * kerntab, int kerncnt);
  78  void  puttrailer(void);
  79  void  outval(int val);
  80  void  outreal(float val);
  81  
  82  /*
  83   *  Global variables
  84   */
  85  FILE   * inf;                /* Input file */
  86  FILE   * outf;               /* Output file */
  87  uchar  infname[272];         /* Input file name */
  88  uchar  outfname[272];        /* Output file name */
  89  uchar  * buffer;             /* .pfm read buffer */
  90  PFM    * pfm;                /* .pfm header */
  91  PSX    * psx;                /* Metrics extension */
  92  
  93  uchar    debugflag;          /* Debug information flag */
  94  uchar    allflag;
  95  uchar    isMono;             /* Font is mono-spaced */
  96  
  97  /*
  98   *  Do the function
  99   */
 100  MAINENT main(int argc, uchar * *argv) {
 101  
 102      /* Parse arguments */
 103      parseargs(argc, argv);
 104  
 105      /* Open and check input file */
 106      openpfm();
 107  
 108      /* Make output file name and open */
 109      openafm();
 110  
 111      /* Put out header information */
 112      putheader();
 113  
 114      /* Put out character table */
 115      putchartab();
 116  
 117      /* Put out kerning table */
 118      if (pfm->kernpairs) {
 119          putkerntab((KERN *)(buffer+pfm->kernpairs+2),
 120                     *(ushort *)(buffer+pfm->kernpairs));
 121      }
 122      if (pfm->kerntrack) { /* rjl */
 123      fprintf(stderr, "Ignoring track kern table\n");
 124      }
 125  
 126      /* Put out trailer line */
 127      puttrailer();
 128  
 129      /* Cleanup */
 130      if (buffer)
 131          free(buffer);
 132      fclose(inf);
 133      fclose(outf);
 134      return 0;
 135  }
 136  
 137  /*
 138   *  Put out normal help
 139   */
 140  void  help (void) {
 141      puts("\npfm2afm - Convert Windows pfm to afm - Version 1.11\n");
 142      puts("This utility converts Windows pfm files for Adobe type 1 fonts");
 143      puts("to afm files for use on OS/2.  This allows fonts created for");
 144      puts("Windows, and shipped without the afm file to be used on OS/2.\n");
 145      puts("pfm2afm  infile  [outfile]  -opts");
 146      puts("    The extension .pfm is added to the infile if it has none.");
 147      puts("    The outfile is defaulted from the input file name.");
 148      puts("    -a = All codepoints in range");
 149      puts("\nNote that pfm files are missing some of the data necessary to");
 150      puts("construct afm files, so the conversion may not be perfect.\n");
 151      puts("Ken Borgendale  -  [email protected]\n");
 152      puts("Russell Lang    -  [email protected]\n");
 153      exit (1);
 154  }
 155  
 156  
 157  /*
 158   *  Parse arguments.  This is the full arg treatment, which is sort of
 159   *  overkill for one option, but it allows more to be added later.
 160   */
 161  void  parseargs (int argc, uchar * * argv) {
 162      uchar  swchar;
 163      int    argcnt;
 164      int    filecnt;
 165      uchar * argp;
 166  
 167      argcnt = 1;
 168      filecnt = 0;
 169      /* Read the arguments and decide what we are doing */
 170      while (argcnt<argc) {
 171          argp = argv[argcnt];
 172          /* Check for switches.  Files may not start with - or / */
 173          if (*argp == '-' || *argp == OPTSEP) {
 174              /* Process switches */
 175              swchar = (uchar)tolower(argp[1]);
 176              argp += 2;
 177              switch (swchar) {
 178              case '?':
 179                  help();      /* Does not return */
 180  
 181              /* All codepoints */
 182              case 'a':
 183                  allflag = 0;
 184                  break;
 185  
 186              /* Debug option */
 187              case 'd':
 188                  debugflag = 1;
 189                  break;
 190  
 191              default:
 192                  fputs("Unknown options: ", stderr);
 193                  fputs(argp-2, stderr);
 194                  fputc('\n', stderr);
 195              }
 196          } else {
 197              if (*argp=='?') {
 198                  help();      /* Does not return */
 199              }
 200              switch(++filecnt) {
 201              case 1:
 202                  strcpy(infname, argp);
 203                  break;
 204              case 2:
 205                  strcpy(outfname, argp);
 206                  break;
 207              default:
 208                  fputs("Extra parameter ignored: ", stderr);
 209                  fputs(argp, stderr);
 210                  fputc('\n', stderr);
 211              }
 212          }
 213          argcnt++;
 214      }
 215  
 216      /* We require the input file name */
 217      if (!filecnt) help();
 218  }
 219  
 220  
 221  /*
 222   *  Open the .pfm file and check it
 223   */
 224  void  openpfm(void) {
 225      uchar   * cp;
 226      int       len;
 227  
 228      /* Check for a file extension */
 229      cp = infname+strlen(infname)-1;
 230      while (cp>=infname && *cp!='.' && *cp!='\\' && *cp!='/' && *cp!=':')
 231         cp--;
 232      if (*cp!='.')
 233          strcat(infname, ".pfm");
 234      /* Open the file */
 235      inf = fopen(infname, "rb");
 236      if (!inf) {
 237          fputs("Unable to open input file - ", stderr);
 238          fputs(infname, stderr);
 239          fputc('\n', stderr);
 240          exit(4);
 241      }
 242      /* Read the file */
 243      buffer = malloc(BUFSIZE);
 244      len = fread(buffer, 1, BUFSIZE, inf);
 245      if (len<256 || len==BUFSIZE) {
 246          fputs("Input file read error - ", stderr);
 247          fputs(infname, stderr);
 248          fputc('\n', stderr);
 249          exit(6);
 250      }
 251      /* Do consistency check */
 252      pfm = (PFM *) buffer;
 253      if (len != (int)pfm->len &&  /* Check length field matches file length */
 254          pfm->extlen != 30 &&     /* Check length of PostScript extension   */
 255          pfm->fontname>75 && pfm->fontname<512) {  /* Font name specified */
 256          fputs("Not a valid Windows type 1 .pfm file - ", stderr);
 257          fputs(infname, stderr);
 258          fputc('\n', stderr);
 259          exit(6);
 260      }
 261  }
 262  
 263  /*
 264   *  Create the .afm file
 265   */
 266  void  openafm(void) {
 267      uchar  * cp;
 268  
 269      /* Add .pfm if there is none */
 270      if (!*outfname) {
 271          strcpy(outfname, infname);
 272          cp = outfname+strlen(outfname)-1;
 273          while (cp >= outfname && *cp!='.' && *cp!='\\' && *cp!='/' && *cp!=':')
 274             cp--;
 275          if (*cp=='.') *cp=0;
 276          strcat(outfname, ".afm");
 277      }
 278      /* Open the file */
 279      outf = fopen(outfname, "w");
 280      if (!outf) {
 281          fputs("Unable to open output file - ", stderr);
 282          fputs(outfname, stderr);
 283          fputc('\n', stderr);
 284          exit(5);
 285      }
 286  }
 287  
 288  /*
 289   *  Put out the header of the .afm file
 290   */
 291  void  putheader(void) {
 292      uchar * cp;
 293      int temp;  /* rjl 1995-03-10 */
 294  
 295      fputs("StartFontMetrics 3.0\n", outf);
 296      if (*pfm->copyright) {
 297          fputs("Notice ", outf);
 298          fputs(pfm->copyright, outf);
 299          fputc('\n', outf);
 300      }
 301      fputs("FontName ", outf);
 302      fputs(buffer+pfm->fontname, outf);
 303      fputs("\nEncodingScheme ", outf);
 304      if (pfm->charset) {
 305          fputs("FontSpecific\n", outf);
 306      } else {
 307          fputs("AdobeStandardEncoding\n", outf);
 308      }
 309      /*
 310       * The .pfm is missing full name, so construct from font name by
 311       * changing the hyphen to a space.  This actually works in a lot
 312       * of cases.
 313       */
 314      fputs("FullName ", outf);
 315      cp = buffer+pfm->fontname;
 316      while (*cp) {
 317          if (*cp=='-') *cp=' ';
 318          fputc(*cp, outf);
 319          cp++;
 320      }
 321      if (pfm->face) {
 322          fputs("\nFamilyName ", outf);
 323          fputs(buffer+pfm->face, outf);
 324      }
 325  
 326      fputs("\nWeight ", outf);
 327      if (pfm->weight>475) fputs("Bold", outf);
 328      else if (pfm->weight<325 && pfm->weight)
 329          fputs("Light", outf);
 330      else fputs("Medium", outf);
 331  
 332      /*
 333       *  The mono flag in the pfm actually indicates whether there is a
 334       *  table of font widths, not if they are all the same.
 335       */
 336      fputs("\nIsFixedPitch ", outf);
 337      if (!(pfm->kind&1) ||                  /* Flag for mono */
 338          pfm->avgwidth == pfm->maxwidth ) {  /* Avg width = max width */
 339          fputs("true", outf);
 340          isMono = 1;
 341      } else {
 342          fputs("false", outf);
 343          isMono = 0;
 344      }
 345  
 346      /*
 347       * The font bounding box is lost, but try to reconstruct it.
 348       * Much of this is just guess work.  The bounding box is required in
 349       * the .afm, but is not used by the PM font installer.
 350       */
 351      psx = (PSX *)(buffer+pfm->psext);
 352      fputs("\nFontBBox", outf);
 353      if (isMono) outval(-20);      /* Just guess at left bounds */
 354      else outval(-100);
 355      temp = psx->descender; /* rjl 1995-03-10 */
 356      temp = -(temp+5); /* rjl 1995-03-10 */
 357      outval(temp);  /* Descender is given as positive value */ /* rjl 1995-03-10 */
 358      /*     outval(-(psx->descender+5));  /* Descender is given as positive value */
 359      outval(pfm->maxwidth+10);
 360      outval(pfm->ascent+5);
 361  
 362      /*
 363       * Give other metrics that were kept
 364       */
 365      fputs("\nCapHeight", outf);
 366      outval((int)psx->capheight);
 367      fputs("\nXHeight", outf);
 368      outval((int)psx->xheight);
 369      fputs("\nDescender", outf);
 370      outval((int)-psx->descender); /* output negative value*/
 371      fputs("\nAscender", outf);
 372      /* outval((int)psx->ascender); */
 373      outval((int)pfm->ascent); /* rjl */
 374      /* extra keys added by rjl */
 375      if (psx->len >= sizeof(psx)) {
 376      fputs("\nItalicAngle", outf);
 377          outreal(psx->slant/10.0);
 378      fputs("\nUnderlinePosition", outf);
 379          outval((int)-psx->underlineoffset);
 380      fputs("\nUnderlineThickness", outf);
 381          outval((int)psx->underlinewidth);
 382      }
 383      fputc('\n', outf);
 384  }
 385  
 386  /*
 387   *  Put out the character tables.  According to the .afm spec, the
 388   *  characters must be put out sorted in encoding order.
 389   *
 390   *  Most Windows .pfm files have the characters in the range 20-ff in
 391   *  the Windows code page (819 + quotes).
 392   */
 393  void  putchartab(void) {
 394      int    count, i, j;
 395      ushort spwidth;
 396      ushort * ctab;
 397      uchar  back[256];
 398  
 399      /*
 400       * Compute the count by getting rid of non-existant chars.  This
 401       * is complicated by the fact that Windows encodes the .pfm file
 402       * with a space metric for non-existant chars.
 403       */
 404      memset(back, 0, 256);
 405      count = pfm->lastchar - pfm->firstchar + 1;
 406      spwidth = 0;
 407      /* Compute width of space */
 408      ctab = (ushort *)(buffer+pfm->chartab);
 409      if (pfm->firstchar>=' ' && pfm->lastchar<=' ') {
 410          spwidth = ctab[' '-pfm->firstchar];
 411      }
 412  
 413      if (!pfm->charset) {
 414          /*
 415           *  Loop thru the chars, deleting those that we presume
 416           *  do not really exist.
 417           */
 418          for (i=pfm->firstchar; i<=(int)pfm->lastchar; i++) {
 419              if (Win2PSStd[i]) {
 420                  back[Win2PSStd[i]] = (uchar)i;
 421              } else {
 422                  if (!allflag) {
 423                      if (*ctab==spwidth) {   /* Default width */
 424                          if (!(WinClass[i]&1)) {
 425                              *ctab = 0;
 426                              count--;
 427                          }
 428                      } else {                /* Not default width */
 429                          if (!WinClass[i]) {
 430                              *ctab = 0;
 431                              count--;
 432                          }
 433                      }
 434                  }
 435              }
 436              ctab++;
 437          }
 438      }
 439  
 440      /* Put out the header */
 441      fputs("StartCharMetrics", outf);
 442      outval(count);
 443      fputc('\n', outf);
 444  
 445      /* Put out all encoded chars */
 446      if (pfm->charset) {
 447      /*
 448       * If the charset is not the Windows standard, just put out
 449       * unnamed entries.
 450       */
 451          ctab = (ushort *)(buffer+pfm->chartab);
 452          for (i=pfm->firstchar; i<=(int)pfm->lastchar; i++) {
 453              if (*ctab) {
 454                  outchar(i, *ctab, NULL);
 455              }
 456              ctab++;
 457          }
 458      } else {
 459          ctab = (ushort *)(buffer+pfm->chartab);
 460          for (i=0; i<256; i++) {
 461              j = back[i];
 462              if (j) {
 463                  outchar(i, ctab[j-pfm->firstchar], WinChars[j]);
 464                  ctab[j-pfm->firstchar] = 0;
 465              }
 466          }
 467          /* Put out all non-encoded chars */
 468          ctab = (ushort *)(buffer+pfm->chartab);
 469          for (i=pfm->firstchar; i<=(int)pfm->lastchar; i++) {
 470              if (*ctab) {
 471                  outchar(-1, *ctab, WinChars[i]);
 472              }
 473              ctab++;
 474          }
 475      }
 476      /* Put out the trailer */
 477      fputs("EndCharMetrics\n", outf);
 478  }
 479  
 480  /*
 481   *  Output a character entry
 482   */
 483  void  outchar(int code, ushort width, const uchar * name) {
 484      fputs("C", outf);
 485      outval(code);
 486      fputs(" ; WX", outf);
 487      outval(width);
 488      if (name) {
 489          fputs(" ; N ", outf);
 490          fputs(name, outf);
 491      }
 492      fputs(" ;\n", outf);
 493  }
 494  
 495  /*
 496   *  Put out the kerning tables
 497   */
 498  void  putkerntab(KERN * kerntab, int kerncnt) {
 499      int    count, i;
 500      KERN * kp;
 501  
 502      /* Count non-zero kern pairs */
 503      count = kerncnt;
 504      kp = kerntab;
 505      for (i=0; i<kerncnt; i++) {
 506          if (!kp->kern)
 507              count--;
 508          kp++;
 509      }
 510  
 511      /* Put out header */
 512      fputs("StartKernData\nStartKernPairs", outf);
 513      outval(count);
 514      fputc('\n', outf);
 515  
 516      /* Put out each non-zero pair */
 517      kp = kerntab;
 518      while (kerncnt) {
 519          if (kp->kern) {
 520              fputs("KPX ", outf);
 521              fputs(WinChars[kp->first], outf);
 522              fputc(' ', outf);
 523              fputs(WinChars[kp->second], outf);
 524              outval((int)kp->kern);
 525              fputc('\n', outf);
 526          }
 527          kp++;
 528          kerncnt--;
 529      }
 530  
 531      /* Put out trailer */
 532      fputs("EndKernPairs\nEndKernData\n", outf);
 533  }
 534  
 535  /*
 536   *  Put out the trailer of the .afm file
 537   */
 538  void  puttrailer(void) {
 539      fputs("EndFontMetrics\n", outf);
 540  }
 541  
 542  /*
 543   *  Output a decimal value
 544   */
 545  void outval(int v) {
 546      char chx[16];
 547  #ifdef unix
 548      sprintf(chx, "%d", v);  /* rjl 1995-03-10 */
 549  #else
 550      itoa(v, chx, 10);
 551  #endif
 552      fputc(' ', outf);
 553      fputs(chx, outf);
 554  }
 555  
 556  /*
 557   *  Output a real value
 558   */
 559  void outreal(float v) {
 560      fprintf(outf," %g",v);
 561  }


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1