Beispiel #1
0
int
main(int argc, char *argv[])
{
  int c;
  FILE *ifp = 0, *ofp = 0;
  const char *ifp_filename = "<stdin>";
  struct font_reader fr;
  int max_blocklen = -1;
  
  Clp_Parser *clp =
    Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options);
  program_name = (char *)Clp_ProgramName(clp);
  
  /* interpret command line arguments using CLP */
  while (1) {
    int opt = Clp_Next(clp);
    switch (opt) {
      
     case BLOCK_LEN_OPT:
      max_blocklen = clp->val.i;
      if (max_blocklen <= 0) {
	max_blocklen = 1;
	error("warning: block length raised to %d", max_blocklen);
      }
      break;
      
     output_file:
     case OUTPUT_OPT:
      if (ofp)
	fatal_error("output file already specified");
      if (strcmp(clp->arg, "-") == 0)
	ofp = stdout;
      else {
	ofp = fopen(clp->arg, "wb");
	if (!ofp) fatal_error("%s: %s", clp->arg, strerror(errno));
      }
      break;
      
     case HELP_OPT:
      usage();
      exit(0);
      break;
      
     case VERSION_OPT:
      printf("t1binary (LCDF t1utils) %s\n", VERSION);
      printf("Copyright (C) 1992-2003 I. Lee Hetherington, Eddie Kohler et al.\n\
This is free software; see the source for copying conditions.\n\
There is NO warranty, not even for merchantability or fitness for a\n\
particular purpose.\n");
      exit(0);
      break;
      
     case Clp_NotOption:
      if (ifp && ofp)
	fatal_error("too many arguments");
      else if (ifp)
	goto output_file;
      if (strcmp(clp->arg, "-") == 0)
	ifp = stdin;
      else {
	ifp_filename = clp->arg;
	ifp = fopen(clp->arg, "r");
	if (!ifp) fatal_error("%s: %s", clp->arg, strerror(errno));
      }
      break;
      
     case Clp_Done:
      goto done;
      
     case Clp_BadOption:
      short_usage();
      exit(1);
      break;
      
    }
  }
  
 done:
  if (!ifp) ifp = stdin;
  if (!ofp) ofp = stdout;
  
#if defined(_MSDOS) || defined(_WIN32)
  /* As we are processing a PFB (binary) output */
  /* file, we must set its file mode to binary. */
  _setmode(_fileno(ofp), _O_BINARY);
#endif
  
  /* prepare font reader and pfb writer */
  fr.output_ascii = pfb_output_ascii;
  fr.output_binary = pfb_output_binary;
  fr.output_end = pfb_output_end;
  init_pfb_writer(&w, max_blocklen, ofp);
  
  /* peek at first byte to see if it is the PFB marker 0x80 */
  c = getc(ifp);
  ungetc(c, ifp);
  
  /* do the file */
  if (c == PFB_MARKER)
    process_pfb(ifp, ifp_filename, &fr);
  else if (c == '%')
    process_pfa(ifp, ifp_filename, &fr);
  else
    fatal_error("%s does not start with font marker (`%%' or 0x80)", ifp_filename);
  
  fclose(ifp);
  fclose(ofp);
  
  if (!w.binary_blocks_written)
    fatal_error("no binary blocks written! Are you sure this was a font?");
  
  return 0;
}
int
main(int argc, char *argv[])
{
    Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options);
    char buf[BUFSIZ];
    const char *paper = NULL, *output = NULL;
    FILE *pf, *of;
    int overflow, nest, is_ps2write = -1, ps2write_state = 0;
    int colorize = 1, lighten = 1, newcoloropt = 0, random_random_seed = 1;
    int rotate = 0;
    uint32_t random_seed = 0;

    program_name = Clp_ProgramName(clp);

    while (1) {
        int opt = Clp_Next(clp);
        switch (opt) {

          case DIR_OPT:
            catdir(clp->vstr, 0, colorize, lighten, rotate);
            newcoloropt = 0;
            break;

          case FILE_OPT:
            addcat(clp->vstr, colorize, lighten, rotate);
            newcoloropt = 0;
            break;

          case PAPER_OPT:
            if (paper) {
                fprintf(stderr, "%s: `--paper` specified twice\n", program_name);
                usage_error();
            }
            paper = clp->vstr;
            break;

          case OUTPUT_OPT:
            if (output) {
                fprintf(stderr, "%s: `--output` specified twice\n", program_name);
                usage_error();
            }
            output = clp->vstr;
            break;

          case SEED_OPT:
            if (clp->negated)
                random_random_seed = -1;
            else if (!clp->have_val)
                random_random_seed = 1;
            else
                random_random_seed = 0, random_seed = clp->val.u;
            break;

          case COLORIZE_OPT:
            colorize = !clp->negated;
            newcoloropt = 1;
            break;

          case LIGHTEN_OPT:
            lighten = !clp->negated;
            newcoloropt = 1;
            break;

          case ROTATE_OPT:
            if (clp->negated)
                rotate = 0;
            else if (clp->have_val)
                rotate = clp->val.i;
            else
                rotate = 20;
            newcoloropt = 1;
            break;

          case NOCOLORIZE_OPT:
            colorize = 0;
            newcoloropt = 1;
            break;

          case NOLIGHTEN_OPT:
            lighten = 0;
            newcoloropt = 1;
            break;

          case MAXCATS_OPT:
            maxcats = clp->val.i;
            break;

          case HELP_OPT:
            usage();
            exit(0);

          case VERSION_OPT:
            printf("yapteaparprfotci %s\n", VERSION);
            printf("Copyright (c) 2005-2016 Eddie Kohler\n\
This is free software; see the source for copying conditions.\n\
There is NO warranty, not even for merchantability or fitness for a\n\
particular purpose.\n");
            exit(0);
            break;

          case Clp_NotOption:
            if (paper) {
                fprintf(stderr, "%s: too many arguments\n", program_name);
                usage_error();
            }
            paper = clp->vstr;
            break;

          case Clp_Done:
            goto done;

          case Clp_BadOption:
            usage_error();

        }
    }

  done:
    if (newcoloropt)
        fprintf(stderr, "%s: warning: last colorize/lighten options ignored\n(These options only affect subsequently-named cat imagery.)\n", program_name);
    if (!ncats)
        fprintf(stderr, "%s: warning: no cat imagery!  (Try `-d DIR` or `-f FILE`.)\n", program_name);
    if (!paper || strcmp(paper, "-") == 0) {
        pf = stdin;
        paper = "<stdin>";
    } else {
        pf = fopen(paper, "r");
        if (!pf) {
            perror(paper);
            exit(1);
        }
        fclose(stdin);
    }

    // Set random seed
    if (random_random_seed == 0)
        srandom(random_seed);
    else if (random_random_seed > 0) {
#if HAVE_SRANDOMDEV
        srandomdev();
#else
        int i;
        srandom(time(NULL));
        for (i = 0; i < getpid() % 43; i++)
            (void) random();
#endif
    }

    // Check for PDF
    if (fgets(buf, sizeof(buf), pf) == NULL) {
        fprintf(stderr, "%s: Empty file\n", paper);
        exit(1);
    }
    int need_pdf = 0;
    if (memcmp(buf, "%PDF-", 5) == 0) {
        int pipe1[2];
        if (pipe(pipe1) != 0) {
            perror(program_name);
            exit(1);
        }

        pid_t child = fork();
        if (child == 0) {
            size_t nread;

            close(STDOUT_FILENO);
            close(pipe1[0]);
            dup2(pipe1[1], STDOUT_FILENO);
            close(pipe1[1]);
            FILE* p = popen("pdf2ps -dLanguageLevel=3 - -", "w");
            if (!p) {
                perror("pdftops");
                exit(1);
            }
            close(STDOUT_FILENO);

            fputs(buf, p);
            while ((nread = fread(buf, 1, sizeof(buf), pf)))
                fwrite(buf, 1, nread, p);

            pclose(p);
            exit(0);
        } else if (child < 0) {
            perror(program_name);
            exit(1);
        }

        fclose(pf);
        close(pipe1[1]);
        pf = fdopen(pipe1[0], "r");
        if (fgets(buf, sizeof(buf), pf) == NULL) {
            fprintf(stderr, "%s: PDF conversion failed\n", paper);
            exit(1);
        }
        need_pdf = 1;
    }

    // Output
    if (need_pdf) {
        char* ocmd = malloc(strlen(output ? output : "-") * 2 + 20);
        char* opos;
        const char* ipos;
        strcpy(ocmd, "ps2pdf - ");
        opos = ocmd + strlen(ocmd);
        for (ipos = output ? output : "-"; *ipos; ++ipos)
            if (isalnum(*ipos) || *ipos == '/' || *ipos == '.')
                *opos++ = *ipos;
            else {
                *opos++ = '\\';
                *opos++ = *ipos;
            }
        *opos++ = 0;
        of = popen(ocmd, "w");
        free(ocmd);
    } else if (!output || strcmp(output, "-") == 0)
        of = stdout;
    else if (!(of = fopen(output, "w"))) {
        perror(output);
        exit(1);
    }

    // Actually process
    overflow = nest = 0;
    do {
        char *newline = strchr(buf, '\n');
        if (is_ps2write > 0 && ps2write_state)
            ps2write_state = check_ps2write(ps2write_state, buf);
        else if (is_ps2write < 0) {
            if (buf[0] != '%')
                is_ps2write = 0;
            else if (memcmp(buf, "%%Creator:", 10) == 0)
                is_ps2write = strstr(buf, "ps2write") != 0;
        }
        fputs(buf, of);
        if (!overflow && newline && memcmp(buf, "%%BeginDocument:", 16) == 0)
            nest++;
        else if (!overflow && newline && memcmp(buf, "%%EndDocument", 13) == 0)
            nest--;
        if (!overflow && newline && memcmp(buf, "%%Page: ", 8) == 0 && nest == 0) {
            double bbox[4] = {0, 0, 612, 792};
            if (fgets(buf, sizeof(buf), pf) != NULL
                && memcmp(buf, "%%PageBoundingBox: ", 19) == 0)
                sscanf(buf + 19, "%lg %lg %lg %lg", &bbox[0], &bbox[1], &bbox[2], &bbox[3]);
            cat(of, 0, bbox);
            ps2write_state = 1;
            continue;
        }
        overflow = (newline == NULL);
    } while (fgets(buf, sizeof(buf), pf) != NULL);

    if (need_pdf)
        pclose(of);
    else
        fclose(of);
    return 0;
}