Esempio n. 1
0
int 
main(int argc, char** argv)
{
  size_t l;
  unsigned int i;
  long index, code;
  FILE *config_file;
  char *configline, *oldconfigline, *p, *q;
  Font font;
  encoding *enc;
  long inenc_array[256];
  char *fontname;
  size_t fontname_len;
  char *pk_filename, *tfm_filename, *enc_filename, *cfg_filename;
  char *real_ttfname, *real_cfg_filename;
  int dpi = 0, ptsize;
  Boolean hinting = True;
  Boolean quiet = False;
  Boolean no_dpi = False;
  Boolean testing = False;


  TeX_search_init(argv[0], "ttf2pk", "TTF2PK");

  if (argc == 1)
    oops("Need at least two arguments.\n"
         "Try `ttf2pk --help' for more information.");

  if (argc == 2)
  {
    if (strcmp(argv[1], "--help") == 0)
      usage();
    else if (strcmp(argv[1], "--version") == 0)
      version();
  }

  while (argv[1][0] == '-')
  {
    if (argv[1][1] == 'q')
      quiet = True;
    else if (argv[1][1] == 'n')
      no_dpi = True;
    else if (argv[1][1] == 't')
      testing = True;
    else
      oops("Unknown option `%s'.\n"
           "Try `ttf2pk --help' for more information.", argv[1]);

    argv++;
    argc--;
  }

  if (testing)
  {
    if (argc != 2)
      oops("Need exactly one parameter for `-t' option.\n"
           "Try `ttf2pk --help' for more information.");
  }
  else if (argc != 3)
    oops("Need at most two arguments.\n"
         "Try `ttf2pk --help' for more information.");

  if (!quiet)
    printf("This is %s\n", ident);

  if (!testing)
    if ((dpi = atoi(argv[2])) <= 50)
      oops("dpi value must be larger than 50.");

  fontname = argv[1];
  fontname_len = strlen(fontname);
  enc_filename = NULL;

  ptsize = 10;

  init_font_structure(&font);

  cfg_filename = newstring("ttfonts.map");
  real_cfg_filename = TeX_search_config_file(&cfg_filename);
  if (!real_cfg_filename)
    oops("Cannot find file ttfonts.map.");

  config_file = fopen(real_cfg_filename, "rt");
  if (config_file == NULL)
    oops("Cannot open file ttfonts.map.");

  do
  {
    configline = get_line(config_file);
    if (!configline)
      oops("Error while reading ttfonts.map.");
    if (!*configline)
    {
      /*
       *   This is the only error message we suppress if the -q flag
       *   is set, making it possible to call ttf2pk silently.
       */
      if (!quiet)
        fprintf(stdout,
                "%s: ERROR: Cannot find font %s in ttfonts.map.\n",
                progname, fontname);
      exit(2);
    }
  } while (compare(&font, configline, fontname));

  fclose(config_file);

  if (testing)
  {
    if (!quiet)
      fprintf(stdout, "%s\n", configline);
    exit(0);
  }

  /*
   *   Parse the line from the config file.  We split the config line buffer
   *   into substrings according to the given options.
   */

  l = strlen(configline);
  if (configline[l - 1] == '\n')
    configline[l - 1] = '\0';     /* strip newline */

  oldconfigline = newstring(configline);

  p = configline;
  while (isspace(*p))
    p++;
  while (*p && !isspace(*p))
    p++;

  q = p;

  while (*p && isspace(*p))
    p++;
  if (!*p)
    boops(oldconfigline, q - configline, "TTF file missing.");

  font.ttfname = p;

  while (*p && !isspace(*p))
    p++;
  if (*p)
    *p++ = '\0';      

  for (; *p; p++)
  {
    if (isspace(*p))
      continue;

    if (!strncmp(p, "Slant", 5))
    {
      p = strip_equal(configline, oldconfigline, p + 5);
      if (sscanf(p, "%f", &(font.slant)) == 0)
        boops(oldconfigline, p - configline, "Bad `Slant' parameter.");
    }
    else if (!strncmp(p, "Encoding", 8))
    {
      if (have_sfd)
        boops(oldconfigline, p - configline,
              "No `Encoding' parameter allowed for subfonts.");

      p = strip_equal(configline, oldconfigline, p + 8);
      if (!*p)
        boops(oldconfigline, p - configline, "Bad `Encoding' parameter.");
      enc_filename = p;
    }
    else if (!strncmp(p, "Extend", 6))
    {
      p = strip_equal(configline, oldconfigline, p + 6);
      if (sscanf(p, "%f", &(font.efactor)) == 0)
        boops(oldconfigline, p - configline, "Bad `Extend' parameter.");
    }
    else if (!strncmp(p, "Fontindex", 9))
    {
      p = strip_equal(configline, oldconfigline, p + 9);
      if (sscanf(p, "%lu", &(font.fontindex)) < 0)
        boops(oldconfigline, p - configline, "Bad `Fontindex' parameter.");
    }
    else if (!strncmp(p, "Pid", 3))
    {
      p = strip_equal(configline, oldconfigline, p + 3);
      if (sscanf(p, "%hu", &(font.pid)) < 0)
        boops(oldconfigline, p - configline, "Bad `Pid' parameter.");
      have_pid = True;
    }
    else if (!strncmp(p, "Eid", 3))
    {
      p = strip_equal(configline, oldconfigline, p + 3);
      if (sscanf(p, "%hu", &(font.eid)) < 0)
        boops(oldconfigline, p - configline, "Bad `Eid' parameter.");
      have_eid = True;
    }
    else if (!strncmp(p, "Hinting", 7))
    {
      p = strip_equal(configline, oldconfigline, p + 7);
      if (p[1] == 'N' || p[1] == 'n' ||
          p[0] == 'Y' || p[1] == 'y' ||
          p[0] == '1')
        hinting = True;
      else if (p[1] == 'F' || p[1] == 'f' ||
               p[0] == 'N' || p[1] == 'n' ||
               p[0] == '0')
        hinting = False;
      else
        boops(oldconfigline, p - configline, "Bad `Hinting' parameter.");
    }
    else if (!strncmp(p, "PS", 2))
    {
      p = strip_equal(configline, oldconfigline, p + 2);
      if (p[1] != '\0' &&
          (p[2] == 'l' || p[2] == 'L'))
        font.PSnames = Only;
      else if (p[1] == 'N' || p[1] == 'n' ||
               p[0] == 'Y' || p[0] == 'y' ||
               p[0] == '1')
        font.PSnames = Yes;
      else if (p[1] == 'F' || p[1] == 'f' ||
               p[0] == 'N' || p[0] == 'n' ||
               p[0] == '0')
        font.PSnames = No;
      else
        boops(oldconfigline, p - configline, "Bad `PS' parameter.");

      if (have_sfd)
        boops(oldconfigline, p - configline,
              "No `PS' parameter allowed for subfonts.");
    }
    else if (!strncmp(p, "Rotate", 6))
    {
      p = strip_equal(configline, oldconfigline, p + 6);
      if (p[1] == 'N' || p[1] == 'n' ||
          p[0] == 'Y' || p[1] == 'y' ||
          p[0] == '1')
        font.rotate = True;
      else if (p[1] == 'F' || p[1] == 'f' ||
               p[0] == 'N' || p[1] == 'n' ||
               p[0] == '0')
        font.rotate = False;
      else
        boops(oldconfigline, p - configline, "Bad `Rotate' parameter.");

      if (!have_sfd)
        boops(oldconfigline, p - configline,
              "No `Rotate' parameter allowed for non-subfonts.");
    }
    else if (!strncmp(p, "Y-Offset", 8))
    {
      p = strip_equal(configline, oldconfigline, p + 8);
      if (sscanf(p, "%f", &(font.y_offset)) == 0)
        boops(oldconfigline, p - configline, "Bad `Y-Offset' parameter.");
    }
    else if (!strncmp(p, "Replacement", 11))
    {
      p = strip_equal(configline, oldconfigline, p + 11);
      if (!*p)
        boops(oldconfigline, p - configline, "Bad `Replacement' parameter.");
      font.replacementname = p;
    }
    else
    {
      char *new_name, *old_name;
      stringlist *sl;


      old_name = p;
      while (*p && !isspace(*p) && *p != '=')
        p++;

      q = p;
      p = strip_equal(configline, oldconfigline, p);
      *q = '\0';

      new_name = p;
      while (*p && !isspace(*p))
        p++;
      if (*p)
        *p++ = '\0';

      sl = newstringlist();
      sl->new_name = new_name;
      sl->old_name = old_name;
      sl->next = font.replacements;
      font.replacements = sl;

      p--;                      /* to make the next while loop work */
    }

    while (*p && !isspace(*p))
      p++;
    if (*p)
      *p = '\0';
  }

  if (font.PSnames == Only)
    if (have_pid || have_eid)
      boops(oldconfigline, 0,
            "No `Pid' or `Eid' parameters allowed if `PS=Only' is set.");

  font.replacementname = newstring(font.replacementname);
  get_replacements(&font);

  tfm_filename = newstring(fontname);
  TFMopen(&tfm_filename);

  pk_filename = mymalloc(fontname_len + 10);
  if (no_dpi)
    sprintf(pk_filename, "%s.pk", fontname);
  else
    sprintf(pk_filename, "%s.%dpk", fontname, dpi);
  PKopen(pk_filename, fontname, dpi);

  font.ttfname = newstring(font.ttfname);
  real_ttfname = TeX_search_ttf_file(&(font.ttfname));
  if (!real_ttfname)
    oops("Cannot find `%s'.", font.ttfname);
  TTFopen(real_ttfname, &font, dpi, ptsize, quiet);

  enc_filename = newstring(enc_filename);
  enc = readencoding(&enc_filename, &font, True);
  if (enc)
  {
    char *name;


    restore_glyph(enc, &font);

    for (i = 0; i <= 0xFF; i++)
    {
      name = enc->vec[i];
      if (!font.PSnames)
      {
        code = adobename_to_code(name);
        if (code < 0 && strcmp(name, ".notdef") != 0)
          warning("Cannot map character `%s'.", name);
        inenc_array[i] = code;
      }
      else
      {
        /* we search the glyph index */
        index = TTFsearch_PS_name(name);
        if (index < 0)
          warning("Cannot map character `%s'.", name);
        inenc_array[i] = index | 0x10000;
      }
    }
  }
  else
  {
    if (font.replacements)
      warning("Replacement glyphs will be ignored.");

    if (have_sfd)
      TTFget_subfont(&font, inenc_array);
    else
      /* get the table of glyph names too */
      enc = TTFget_first_glyphs(&font, inenc_array);
  }

  for (i = 0; i <= 0xFF; i++)
  {
    byte *bitmap;
    int w, h, hoff, voff;


    if ((code = inenc_array[i]) >= 0)
    {
      if (!quiet)
      {
        printf("Processing glyph %3ld   %s index 0x%04x  %s\n",
               (long)i, (code >= 0x10000) ? "glyph" : "code",
               (unsigned int)(code & 0xFFFF), enc ? enc->vec[i] : "");
        fflush(stdout);
      }

      if (TTFprocess(&font, code,
                     &bitmap, &w, &h, &hoff, &voff, hinting, quiet))
        PKputglyph(i,
                   -hoff, -voff, w - hoff, h - voff,
                   w, h, bitmap);
      else
        warning("Cannot render glyph with %s index 0x%x.",
                (code >= 0x10000) ? "glyph" : "code",
                (unsigned int)(code & 0xFFFF));
    }
  }

  PKclose();
  exit(0);      /* for safety reasons */
  return 0;     /* never reached */
}
Esempio n. 2
0
static void
handle_options(int argc, char *argv[], Font *fnt)
{
  register int lastext;
  register int i;
  size_t l;
  int arginc;
  char *temp;
  char c;
  char *vpl_name = NULL;
  Boolean have_capheight = 0;
  Boolean have_sfd = 0;
  int sfd_begin, postfix_begin;
  int base_name;
  stringlist* sl;


  /* scan first whether the -q switch is set */
  for (i = 1; i < argc; i++)
    if (argv[i][0] == '-' && argv[i][1] == 'q')
      quiet = True;

  if (!quiet)
    printf("This is %s\n", ident);

  /* Make VPL file identical to that created under Unix */
  fnt->titlebuf = (char *)mymalloc(strlen(progname) + strlen(argv[1]) +
                                   1 + 1);
  sprintf(fnt->titlebuf, "%s %s", progname, argv[1]);


  /*
   *   TrueType font name.
   */

  fnt->ttfname = newstring(argv[1]);

  /*
   *   The other arguments.  We delay the final processing of some switches
   *   until the tfm font name has been scanned -- if it contains two `@'s,
   *   many switches are ignored.
   */

  while (argc > 2 && *argv[2] == '-')
  {
    arginc = 2;
    i = argv[2][1];

    switch (i)
    {
    case 'v':
      makevpl = 1;
      if (argc <= 3)
        oops("Missing parameter for -v option.");
      if (vpl_name)
        free(vpl_name);
      vpl_name = newstring(argv[3]);
      handle_extension(&vpl_name, ".vpl");
      break;

    case 'V':
      makevpl = 2;
      if (argc <= 3)
        oops("Missing parameter for -V option.");
      if (vpl_name)
        free(vpl_name);
      vpl_name = newstring(argv[3]);
      handle_extension(&vpl_name, ".vpl");
      break;

    case 'f':
      if (argc <= 3)
        oops("Missing parameter for -f option.");
      if (sscanf(argv[3], "%lu", &(fnt->fontindex)) == 0)
        oops("Invalid font index.");
      fnt->fontindexparam = argv[3];
      break;

    case 'E':
      if (argc <= 3)
        oops("Missing parameter for -E option.");
      if (sscanf(argv[3], "%hu", &(fnt->eid)) == 0)
        oops("Invalid encoding ID.");
      fnt->eidparam = argv[3];
      break;

    case 'P':
      if (argc <= 3)
        oops("Missing parameter for -P option.");
      if (sscanf(argv[3], "%hu", &(fnt->pid)) == 0)
        oops("Invalid platform ID.");
      fnt->pidparam = argv[3];
      break;

    case 'e':
      if (argc <= 3)
        oops("Missing parameter for -e option.");
      if (sscanf(argv[3], "%f", &(fnt->efactor)) == 0 || fnt->efactor < 0.01)
        oops("Bad extension factor.");
      fnt->efactorparam = argv[3];
      break;

    case 'c':
      if (argc <= 3)
        oops("Missing parameter for -c option.");
      have_capheight = True;
      if (sscanf(argv[3], "%f", &(fnt->capheight)) == 0)
        fnt->capheight = 0;
      break;

    case 's':
      if (argc <= 3)
        oops("Missing parameter for -s option.");
      if (sscanf(argv[3], "%f", &(fnt->slant)) == 0)
        oops("Bad slant parameter.");
      fnt->slantparam = argv[3];
      break;

    case 'p':
      if (argc <= 3)
        oops("Missing parameter for -p option.");
      if (fnt->inencname)
        free(fnt->inencname);
      fnt->inencname = newstring(argv[3]);
      break;

    case 'T':
      if (argc <= 3)
        oops("Missing parameter for -T option.");
      if (fnt->inencname)
        free(fnt->inencname);
      if (fnt->outencname)
        free(fnt->outencname);
      fnt->inencname = newstring(argv[3]);
      fnt->outencname = newstring(argv[3]);
      break;

    case 't':
      if (argc <= 3)
        oops("Missing parameter for -T option.");
      if (fnt->outencname)
        free(fnt->outencname);
      fnt->outencname = newstring(argv[3]);
      break;

    case 'r':
      if (argc <= 4)
        oops("Not enough parameters for -r option.");
      sl = newstringlist();
      sl->old_name = newstring(argv[3]);
      sl->new_name = newstring(argv[4]);
      sl->single_replacement = True;
      sl->next = fnt->replacements;
      fnt->replacements = sl;
      arginc = 3;
      break;

    case 'R':
      if (argc <= 3)
        oops("Missing parameter for -R option.");
      if (fnt->replacementname)
        free(fnt->replacementname);
      fnt->replacementname = newstring(argv[3]);
      break;

    case 'y':
      if (argc <= 3)
        oops("Missing parameter for -y option.");
      if (sscanf(argv[3], "%f", &(fnt->y_offset)) == 0)
        oops("Invalid y-offset.");
      fnt->y_offsetparam = argv[3];
      break;

    case 'O':
      forceoctal = True;
      arginc = 1;
      break;

    case 'n':
      fnt->PSnames = Yes;
      arginc = 1;
      break;

    case 'N':
      fnt->PSnames = Only;
      arginc = 1;
      break;

    case 'u':
      pedantic = True;
      arginc = 1;
      break;

    case 'q':
      quiet = True;
      arginc = 1;
      break;

    case 'L':
      if (argc <= 3)
        oops("Missing parameter for -L option.");
      if (fnt->ligname)
        free(fnt->ligname);
      fnt->ligname = newstring(argv[3]);
      fnt->subfont_ligs = True;
      break;

    case 'l':
      fnt->subfont_ligs = True;
      arginc = 1;
      break;

    case 'w':
      fnt->write_enc = True;
      arginc = 1;
      break;

    case 'x':
      fnt->rotate = True;
      arginc = 1;
      break;

    case 'o':
      if (argc <= 3)
        oops("Missing parameter for -o option.");
      if (vpl_name)
        free(vpl_name);
      vpl_name = newstring(argv[3]);
      handle_extension(&vpl_name, ".ovp");
      break;

    default:
      if (argc <= 3 || argv[3][0] == '-')
      {
        warning("Unknown option `%s' will be ignored.\n", argv[2]);
        arginc = 1;
      }
      else
        warning("Unknown option `%s %s' will be ignored.\n",
                argv[2], argv[3]);
    }

    for (i = 0; i < arginc; i++)
    {
      l = strlen(fnt->titlebuf);
      fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf,
                                        l + strlen(argv[2]) + 1 + 1);
      sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]);
      argv++;
      argc--;
    }
  }

  /* Read replacement glyph name file */

  get_replacements(fnt);

  if (argc > 3 || (argc == 3 && *argv[2] == '-'))
    oops("Need at most two non-option arguments.");

  /*
   *   The tfm file name.
   */

  if (argc == 2)
    temp = newstring(fnt->ttfname);
  else
  {
    temp = newstring(argv[2]);
    l = strlen(fnt->titlebuf);
    fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf,
                                      l + strlen(argv[2]) + 1 + 1);
    sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]);
  }

  handle_sfd(temp, &sfd_begin, &postfix_begin);

  if (sfd_begin > -1)
  {
    have_sfd = True;
    i = sfd_begin - 2;
  }
  else
    i = strlen(temp) - 1;

  /*
   *   Now we search the beginning of the name without directory.
   */

  for (; i >= 0; i--)
    if (temp[i] == '/' || temp[i] == ':' || temp[i] == '\\')
      break;

  base_name = i + 1;

  /*
   *   We store the path (with the final directory separator).
   */

  if (base_name > 0)
  {
    c = temp[base_name];
    temp[base_name] = '\0';
    fnt->tfm_path = newstring(temp);
    temp[base_name] = c;
  }

  if (have_sfd)
  {
    /* the prefix and the sfd file name */

    if (temp[base_name])
      fnt->outname = newstring(temp + base_name);

    fnt->sfdname = newstring(temp + sfd_begin);
  }
  else
    postfix_begin = base_name;

  /*
   *   Get the extension.
   */

  lastext = -1;
  for (i = postfix_begin; temp[i]; i++)
    if (temp[i] == '.')
      lastext = i;

  if (argc == 2 && lastext >= 0)
  {
    temp[lastext] = '\0';       /* remove TTF file extension */
    lastext = -1;
  }

  if (lastext == -1)
    fnt->tfm_ext = newstring(".tfm");
  else
  {
    fnt->tfm_ext = newstring(temp + lastext);
    temp[lastext] = '\0';
  }

  if (have_sfd)
  {
    if (temp[postfix_begin])
      fnt->outname_postfix = newstring(temp + postfix_begin);
  }
  else
  {
    if (temp[base_name])
      fnt->outname = newstring(temp + base_name);
    else
      oops("Invalid tfm file name.");
  }


  /*
   *   Now we can process the remaining parameters.
   */

  if (have_sfd)
  {
    if (makevpl)
    {
      warning("Ignoring `-v' and `-V' switches for subfonts.");
      makevpl = 0;
    }
    if (vpl_name)
      if ((fnt->vplout = fopen(vpl_name, "wb")) == NULL)
        oops("Cannot open ovp output file.");
    if (have_capheight)
      warning("Ignoring `-c' switch for subfonts.");
    if (fnt->inencname || fnt->outencname)
    {
      warning("Ignoring `-p', `-t', and `-T' switches for subfonts.");
      fnt->inencname = NULL;
      fnt->outencname = NULL;
    }
    if (fnt->y_offsetparam && !fnt->rotate)
      warning("Ignoring `-y' switch for non-rotated subfonts.");
    if (fnt->PSnames)
    {
      warning("Ignoring `-n' or '-N' switch for subfonts.");
      fnt->PSnames = No;
    }

    init_sfd(fnt, True);
  }
  else
  {
    if (have_capheight && fnt->capheight < 0.01)
      oops("Bad small caps height.");

    if (vpl_name)
      if ((fnt->vplout = fopen(vpl_name, "wb")) == NULL)
        oops("Cannot open vpl output file.");
  
    if (fnt->subfont_ligs)
    {
      warning("Ignoring `-l' switch for non-subfont.");
      fnt->subfont_ligs = False;
    }

    if (fnt->rotate)
    {
      warning("Ignoring `-x' switch for non-subfont.");
      fnt->rotate = False;
    }

    if (fnt->write_enc)
    {
      warning("Ignoring `-w' switch for non-subfont.");
      fnt->write_enc = False;
    }

    if (fnt->y_offsetparam)
      warning("Ignoring `-y' switch for non-subfont.");
  }

  if (fnt->PSnames == Only)
  {
    if (fnt->pidparam || fnt->eidparam)
    {
      warning("Ignoring `-P' and `-E' options if `-N' switch is selected.");
      fnt->pidparam = NULL;
      fnt->eidparam = NULL;
    }
  }

  if (vpl_name)
    free(vpl_name);
  free(temp);
}