home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / os2 / hpgl312.zip / HP2XX.C < prev    next >
C/C++ Source or Header  |  1993-04-18  |  27KB  |  1,028 lines

  1. /*
  2.    Copyright (c) 1991 - 1993 Heinz W. Werntges.  All rights reserved.
  3.    Distributed by Free Software Foundation, Inc.
  4.  
  5. This file is part of HP2xx.
  6.  
  7. HP2xx is distributed in the hope that it will be useful, but
  8. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  9. to anyone for the consequences of using it or for whether it serves any
  10. particular purpose or works at all, unless he says so in writing.  Refer
  11. to the GNU General Public License, Version 2 or later, for full details.
  12.  
  13. Everyone is granted permission to copy, modify and redistribute
  14. HP2xx, but only under the conditions described in the GNU General Public
  15. License.  A copy of this license is supposed to have been
  16. given to you along with HP2xx so you can know your rights and
  17. responsibilities.  It should be in a file named COPYING.  Among other
  18. things, the copyright notice and this notice must be preserved on all
  19. copies.
  20.  
  21. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  22. */
  23.  
  24. /** hp2xx : A converter of HPGL files into popular raster and vector formats
  25.  **
  26.  **    xx =  mf (MetaFont), eps (PostScript), pcl (HP-PCL Level3),
  27.  **          pre(view), pcx (PaintBrush-Format), img (GEM),
  28.  **          pic (ATARI bitmap), pbm (Portable Bitmap), ...
  29.  **
  30.  ** (c) 1992, 1993  Heinz W. Werntges and the HP2xx team
  31.  **
  32.  ** Author:
  33.  **
  34.  **    HWW    Heinz W. Werntges  (werntges@convex.rz.uni-duesseldorf.de)
  35.  **        Fruchtstr. 2,  4000 Duesseldorf 1, Germany
  36.  **
  37.  **
  38.  ** Amiga stuff & PBM & ILBM by:
  39.  **
  40.  **    CHL    Claus H. Langhans (Claus_Langhans@wildcat.fido.de)
  41.  **        Unter den Nussbaeumen 19, 6233 Kelkheim (Ts.), Germany
  42.  **
  43.  **
  44.  ** Atari stuff & IMG by:
  45.  **
  46.  **    NM    Norbert Meyer (sorry - no email)
  47.  **        Reinhold-Schneider-Str. 83, 4000 Duesseldorf 13
  48.  **
  49.  **    AS    Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de)
  50.  **
  51.  **    JE    Joern Eggers (II040EG@DTHAC11.bitnet)
  52.  **
  53.  **
  54.  ** X11 previewer by:
  55.  **
  56.  **    MSch    Michael Schoene (michael@nero.uni-bonn.de)
  57.  **        Karolinger Str. 81,  4000 Duesseldorf 1, Germany
  58.  **
  59.  **
  60.  ** Many thanks to all the other fine people who supported HP2xx by testing,
  61.  ** correcting, porting, suggesting improvements, and otherwise spending
  62.  ** their time on HP2xx, especially:
  63.  **
  64.  ** -- Michael Schmitz
  65.  **  & Gerhard Steger      for their invaluable help with VAX/VMS,
  66.  ** -- Horst Szillat     for his contributions to OS2 and PM programming,
  67.  ** -- Juergen Gross     for access to a HP 9000 machine
  68.  ** -- Roland Emmerich   for proofreading, beta-testing, and his HGC support
  69.  ** -- Jon Gillian       for valuable suggestions
  70.  **-------------------------------------------------------------------------
  71.  **/
  72.  
  73. /** hp2xx.c:
  74.  **
  75.  ** 91/01/12  V 1.00  HWW  PC version
  76.  ** 91/01/17  V 1.01  HWW  Disk swapping added
  77.  ** 91/01/19  V 1.02  HWW  Reorganized: mf mode revived, pcx mode added
  78.  ** 91/01/29  V 1.03  HWW  SUN portation; HP-specials added
  79.  ** 91/01/31  V 1.04  HWW  (-F) FF added
  80.  ** 91/02/01  V 1.05  HWW  Flag -S added (Deskjet specials)
  81.  ** 91/02/15  V 1.06  HWW  stdlib.h & VAX_C supported
  82.  ** 91/02/19  V 2.01  HWW  file unchanged, but new package release!
  83.  ** 91/06/09  V 2.10  HWW  (beta) More options; options x & y changed to o & O
  84.  ** 91/06/15  V 2.11  HWW  (beta) VGA option added; PCX bug (on SUN) removed
  85.  ** 91/06/20  V 2.12  HWW  Rotate (-r) option & Copyright added
  86.  ** 91/06/20  V 2.12b HWW  Minor reformatting
  87.  ** 91/06/29  V 2.13a HWW  PostScript support
  88.  ** 91/08/28  V 2.14  HWW  ATARI 32K format added (prelim.)
  89.  ** 91/10/15  V 2.14c HWW  atari & stad formats; hwtools.h eliminated
  90.  ** 91/10/20  V 2.14d HWW  ATARI-->pic (packing removed)
  91.  ** 91/10/24  V 2.15  HWW  ATARI-->pic stable now; "LT;" & "LT0;" supported
  92.  ** 91/11/22  V 2.16b HWW  "SPn;" support
  93.  ** 92/01/12  V 2.17  HWW  HPGL scanner improved, to_ps() debugged, ps --> eps,
  94.  **              More portabel code (ATARI acknowledged)
  95.  ** 92/02/06  V 2.18e HWW  Better parser, IMG & various previews supported,
  96.  **              preview control via -h, -w; -W removed!
  97.  ** 92/02/21  V 2.19d HWW  LB etc. supported, PG; (option -P) added
  98.  ** 92/03/03  V 2.20c HWW  Modes added: -m epic,em,pac(ATARI) / LB bugs fixed
  99.  ** 92/04/15  V 2.20d HWW  Width & height treated symmetrically now
  100.  ** 92/04/28  V 2.20e HWW  -m pre: -d, -D effective again, default 75; PBM added
  101.  ** 92/05/02  V 2.21a HWW  -m pre is default now. New opt: -l logfile
  102.  ** 92/05/19  V 3.00c HWW  Color support (VGA preview), multiple input files
  103.  ** 92/05/25  V 3.00f HWW  Color support (more modes)
  104.  ** 92/06/09  V 3.01d HWW  XT,YT,TL,SM supported; ATARI update acknowledged;
  105.  **               Mode list added for easier expansion; debugged
  106.  ** 92/10/20  V 3.02a HWW  LT now fully supported
  107.  ** 92/11/08  V 3.02b HWW  Page range allowed
  108.  ** 92/12/10  V 3.02c HWW  Mode "cad" added; DJ version: bug fix extended;
  109.  ** 92/12/12  V 3.02d HWW  2 bug fixes for option -f
  110.  ** 92/12/16  V 3.03a HWW  Option -t (+truesize) added
  111.  ** 92/12/27  V 3.03b HWW  -S int (for Deskjet color support)
  112.  ** 93/01/02  V 3.10a HWW  Source brushed up; ready for distribution
  113.  ** 93/02/08  V 3.12a HWW  Support of Joern Eggers' cs mode added (ATARI only)
  114.  **               HAS_X11, HAS_SUNVIEW: added/modified
  115.  ** 93/04/13  V 3.12b HWW  UC added (A. Treindl), small changes; CMYK added,
  116.  **               New previewer selection scheme
  117.  **/
  118.  
  119.  
  120. #include <stdio.h>
  121. #include <stdlib.h>
  122. #include <string.h>
  123. #include <ctype.h>
  124. #include <math.h>
  125. #include "bresnham.h"
  126. #include "hp2xx.h"
  127. #include "getopt.h"
  128.  
  129.  
  130.  
  131. /**
  132.  ** When adding your special mode, add a symbol here.
  133.  ** Please not the alphabetical order (and keep it).
  134.  **/
  135.  
  136. typedef    enum{
  137.     XX_CAD, XX_CS, XX_EM, XX_EPIC, XX_EPS, XX_ILBM, XX_IMG, XX_MF,
  138.     XX_PBM, XX_PCL, XX_PCX, XX_PAC, XX_PIC, XX_PRE,
  139.     XX_TERM    /* Dummy: terminator    */
  140. } hp2xx_mode;
  141.  
  142.  
  143. /**
  144.  ** When adding your special mode, add a line here.
  145.  ** Please not the alphabetical order (and keep it).
  146.  **/
  147.  
  148. static struct {
  149.     hp2xx_mode    mode;
  150.     char        *modestr;
  151. } ModeList[] = {
  152.     {XX_CAD,    "cad"},    /* LaTeX: TeXcad compatible output    */
  153. #ifdef    ATARI
  154.     {XX_CS,        "cs"},    /* LaTeX using \special{...} for C. Strunk's TeX    */
  155. #endif
  156.     {XX_EM,        "em"},    /* LaTeX using \special{em:...}        */
  157.     {XX_EPIC,    "epic"},/* LaTeX using epic.sty macros        */
  158.     {XX_EPS,    "eps"},    /* Encapulated PostScript        */
  159. #ifdef    AMIGA
  160.     {XX_ILBM,    "ilbm"},/* Special AMIGA format            */
  161. #endif
  162.     {XX_IMG,    "img"},    /* Digital Research IMG raster format    */
  163.     {XX_MF,        "mf"},    /* Metafont source output        */
  164.     {XX_PBM,    "pbm"},    /* Portable Bitmap            */
  165.     {XX_PCL,    "pcl"},    /* HP-PCL Level 5 printer code        */
  166.     {XX_PCX,    "pcx"},    /* Painbtbrush's PCX raster format    */
  167. #ifdef    PIC_PAC
  168.     {XX_PAC,    "pac"},    /* for ATARI, e.g. used by StaD        */
  169.     {XX_PIC,    "pic"},    /* for ATARI. Try to replace by IMG    */
  170. #endif
  171.     {XX_PRE,    "pre"},    /* DEFAULT: Preview on screen        */
  172.     {XX_TERM,    ""},    /* Dummy: List terminator    */
  173. };
  174.  
  175.  
  176. static    Logfile_flag = FALSE;
  177.  
  178.  
  179. void    SilentWait (void)
  180. {
  181. char    dummy[80];
  182.  
  183. /**
  184.  ** Get anything typed including '\n' if stderr does NOT go to a file
  185.  ** or else the user may be invisibly prompted
  186.  **/
  187.   if (!Logfile_flag)
  188.     fgets (dummy,80,stdin);
  189. }
  190.  
  191.  
  192.  
  193.  
  194. void    Wait (void)
  195. {
  196. #ifdef    UNIX
  197.   if (getenv("TERM") == (char *) NULL)
  198.     return;
  199. #endif
  200.   printf ("\nPress <Return> to continue ...\n");
  201.   SilentWait ();
  202. }
  203.  
  204.  
  205.  
  206.  
  207.  
  208. void    print_supported_modes(void)
  209. {
  210. int    i;
  211.  
  212.   fprintf(stderr, "(%s", ModeList[0].modestr);
  213.   for (i=1; ModeList[i].mode != XX_TERM; i++)
  214.     fprintf(stderr, ",%s", ModeList[i].modestr);
  215.   fprintf(stderr, ")\n");
  216. }
  217.  
  218.  
  219.  
  220.  
  221. void    Send_ID(void)
  222. {
  223.   fprintf(stderr,"\n%s\n%s\n%s\n%s\n%s\n",
  224.   "hp2xx is free software and you are welcome to distribute copies of it",
  225.   "  under certain conditions. There is absolutely no warranty for hp2xx!",
  226.   "For full details, read file COPYING (shipped along with this package),",
  227.   "  or write to:\t\tFree Software Foundation, Inc.",
  228.   "\t\t\t675 Mass Ave, Cambridge, MA 02139, USA");
  229.  
  230.   fprintf(stderr,"\n%s%s\n",
  231.     "HP2xx:\tA HPGL converter (xx = mf, eps, pcl, pcx, img ...)\n",
  232.     "\tV 3.12  (93/04/13)   (c) 1991 - 1993  Heinz W. Werntges\n"
  233. #ifdef AMIGA
  234.     "\tAmiga additions (V 2.00) by Claus Langhans (92/12/16)\n"
  235. #endif /* AMIGA */
  236. #ifdef ATARI
  237.     "\tAtari additions (V 2.10) by N. Meyer / J. Eggers / A. Schwab  (93/01/xx)\n"
  238. #endif /* ATARI */
  239.     );
  240. }
  241.  
  242.  
  243.  
  244. void    usage_msg (PAR *p)
  245. {
  246. if (p->quiet)
  247.     return;
  248.  
  249. Send_ID();
  250.  
  251. #ifdef ATARI
  252. fprintf (stderr,"Usage:\tdouble-click on HP2XX.TTP, type parameters into\n");
  253. fprintf (stderr,"\tcommand-line with following syntax:\n");
  254. fprintf (stderr,"\t[options] [hpglfile]\n");
  255. fprintf (stderr,"\n\t(if command-line offers not enough space for all parameters\n");
  256. fprintf (stderr,"\tuse a command-line interpreter for starting HP2xx)\n");
  257. #else
  258. fprintf (stderr,"Usage:\thp2xx [options] [file1 [file2 ...]]\n");
  259. #endif    /* ATARI */
  260.  
  261. fprintf (stderr,"\tUnix: Filter usage (.. | hp2xx -q -f- [options] | ..) ok\n");
  262. Wait();
  263.  
  264. fprintf (stderr,"\nOpt fmt   defaults\tComment:\n");
  265. fprintf (stderr,
  266. "---------------------------------------------------------------------------\n");
  267. fprintf (stderr,"-m strg   %s\t\tMode ", p->mode); print_supported_modes();
  268. fprintf (stderr,"-f strg   (auto gen.)\tName of output file ('-' = to stdout)\n");
  269. fprintf (stderr,"-l strg   (stderr)\tName of log file\n");
  270. fprintf (stderr,"-p strg   %1d%1d%1d%1d%1d%1d%1d%1d\tPensize(s) (in 1/10 mm (mf,ps) or dots (rest)).\n",
  271.     p->pensize[1], p->pensize[2], p->pensize[3], p->pensize[4],
  272.     p->pensize[5], p->pensize[6], p->pensize[7], p->pensize[8]);
  273. fprintf (stderr,"\t\t\t\"strg\" must consist of 1 to 8 digits '0'-'9'\n");
  274. fprintf (stderr,"-c strg   %1d%1d%1d%1d%1d%1d%1d%1d\tPen color(s) (see manual for details).\n",
  275.     p->pencolor[1], p->pencolor[2], p->pencolor[3], p->pencolor[4],
  276.     p->pencolor[5], p->pencolor[6], p->pencolor[7], p->pencolor[8]);
  277. fprintf (stderr,"-P n:n    %d:%d\t\tPage range (0:0 = all pages).\n",
  278.     p->first_page, p->last_page);
  279. fprintf (stderr,"-q        %s\t\tQuiet mode (no diagnostics)\n",
  280.     FLAGSTATE(p->quiet));
  281. fprintf (stderr,"-r float%5.1f\t\tRotation angle [deg]. -r90 = landscape\n",
  282.     p->rotation);
  283. fprintf (stderr,"-s strg   %s\tName of swap file\n",
  284.     p->swapfile);
  285.  
  286. fprintf (stderr,"\nBitmap controls:\n");
  287. fprintf (stderr,"-d int    %d\t\tDPI value for x or x&y, if -D unused.\n",
  288.     p->dpi_x);
  289. fprintf (stderr,"-D int    %d\t\tDPI value for y ONLY\n", p->dpi_x);
  290.      /* x, not y! */
  291. Wait();
  292.  
  293. fprintf (stderr,"\nPCL-exclusive options:\n");
  294. fprintf (stderr,"-i         %s\tPre-initialize printer\n",
  295.     FLAGSTATE (p->init_p));
  296. fprintf (stderr,"-F         %s\tSend a FormFeed at end\n",
  297.     FLAGSTATE(p->formfeed));
  298. fprintf (stderr,"-S int     %d\tUse Deskjet special commands (0=off, 1=B/W, 3=CMY, 4=CMYK)\n",
  299.     p->specials);
  300. fprintf (stderr,"NOTE:    \tOnly valid for -d: 300/150/100/75; -D invalid!\n");
  301.  
  302. fprintf (stderr,"\nPCL / PostScript / Preview options:\n");
  303. fprintf (stderr,"-o float %5.1f\tX offset [mm] of picture\n", p->xoff);
  304. fprintf (stderr,"-O float %5.1f\tY offset [mm] of picture\n", p->yoff);
  305.  
  306. fprintf (stderr,"\nSize controls:\n");
  307.  
  308. fprintf (stderr,"-a float %5.1f\tAspect factor (x/y correction). Valid: > 0.0\n",
  309.     p->aspectfactor);
  310. fprintf (stderr,"-h float %5.1f\tHeight [mm] of picture\n",p->height);
  311. fprintf (stderr,"-w float %5.1f\tWidth  [mm] of picture\n",p->width );
  312. fprintf (stderr,"-t         %s\tShow true HPGL size. Disables -a -h -w !\n",
  313.     FLAGSTATE (p->truesize));
  314. fprintf (stderr,"-x float   -\tManual HPGL-coord range presetting: x0\n");
  315. fprintf (stderr,"-X float   -\tManual HPGL-coord range presetting: x1\n");
  316. fprintf (stderr,"-y float   -\tManual HPGL-coord range presetting: y0\n");
  317. fprintf (stderr,"-Y float   -\tManual HPGL-coord range presetting: y1\n");
  318.  
  319. #ifdef DOS
  320. fprintf (stderr,"\n-V int   %d\tVGA mode byte (decimal). Change at own risk!\n",
  321.         p->vga_mode);
  322. #endif
  323.  
  324. Wait();
  325.  
  326. fprintf (stderr,"Corresponding long options:\n\n");
  327. fprintf (stderr,
  328.     "hp2xx   [--mode] [--colors] [--pensizes] [--pages] [--quiet]\n");
  329. fprintf (stderr,"\t[--width] [--height] [--aspectfactor] [--truesize]\n");
  330. fprintf (stderr,"\t[--x0] [--x1] [--y0] [--y1] [--xoffset] [--yoffset]\n");
  331. fprintf (stderr,"\t[--DPI] [--DPI_x] [--DPI_y]\n");
  332. fprintf (stderr,"\t[--outfile] [--logfile] [--swapfile]\n");
  333. fprintf (stderr,"\t[--PCL_formfeed] [--PCL_init] [--PCL_Deskjet]\n");
  334. #ifdef DOS
  335. fprintf (stderr,"\t[--VGAmodebyte]");
  336. #endif
  337. fprintf (stderr,"\t[--help]\n");
  338.  
  339.  
  340. #ifdef PURE_C
  341. fprintf(stderr,"\nPress RETURN key\n");
  342. getchar();
  343. #endif
  344. }
  345.  
  346.  
  347.  
  348.  
  349. void    reset_par (PAR *pp)
  350. /**
  351.  ** Reset some parameter struct elements which may have been changed
  352.  ** by action() to their defaults
  353.  **/
  354. {
  355.   pp->x0    =  1e10;    /* HP7550A's range is about     */
  356.   pp->x1    = -1e10;    /* [-2^24, 2^24], so we're safe */
  357.   pp->y0    =  1e10;
  358.   pp->y1    = -1e10;
  359.   pp->pen    = 1;
  360. }
  361.  
  362.  
  363.  
  364.  
  365. void    preset_par (PAR *pp)
  366. /**
  367.  ** Pre-set constant parameter struct elements with reasonable defaults
  368.  **/
  369. {
  370. int    i;
  371.  
  372.   pp->logfile    = "";
  373.   pp->outfile    = "";
  374.   pp->swapfile    = "hp2xx.swp";
  375.   pp->mode    = "pre";
  376.   pp->aspectfactor = 1.0;
  377.   pp->xoff    = 0.0;
  378.   pp->yoff    = 0.0;
  379.   pp->height    = 200.0;
  380.   pp->width    = 200.0;
  381.   pp->truesize    = FALSE;
  382.   pp->rotation    = 0.0;
  383.   pp->first_page= 0;
  384.   pp->last_page    = 0;
  385.   pp->init_p    = FALSE;
  386.   pp->formfeed    = FALSE;
  387.   pp->quiet    = FALSE;
  388.   pp->specials    = 0;
  389.   pp->dpi_x    = 75;
  390.   pp->dpi_y    = 0;
  391.   pp->vga_mode    = 18;        /* 0x12: VGA 640x480, 16 colors */
  392.   pp->maxpensize= 1;        /* in pixel or 1/10 mm        */
  393.   pp->maxcolor    = 1;        /* max. color index        */
  394.   pp->pensize[0]= 0;        /* in pixel or 1/10 mm        */
  395.   pp->pencolor[0]= xxBackground;
  396.   for (i=1; i<=8; i++)
  397.   {
  398.     pp->pensize [i]    = 1;    /* in pixel or 1/10 mm        */
  399.     pp->pencolor[i]    = xxForeground;
  400.   }
  401.   pp->is_color    = FALSE;
  402.   pp->Clut[xxBackground][0]= 255;  pp->Clut[xxBackground][1]    = 255;
  403.   pp->Clut[xxBackground][2]= 255;
  404.   pp->Clut[xxForeground][0]= 0;       pp->Clut[xxForeground][1]    = 0;
  405.   pp->Clut[xxForeground][2]= 0;
  406.   pp->Clut[xxRed][0]    = 255;       pp->Clut[xxRed][1]        = 0;
  407.   pp->Clut[xxRed][2]    = 0;
  408.   pp->Clut[xxGreen][0]    = 0;       pp->Clut[xxGreen][1]        = 255;
  409.   pp->Clut[xxGreen][2]    = 0;
  410.   pp->Clut[xxBlue][0]    = 0;       pp->Clut[xxBlue][1]        = 0;
  411.   pp->Clut[xxBlue][2]    = 255;
  412.   pp->Clut[xxCyan][0]    = 0;       pp->Clut[xxCyan][1]        = 255;
  413.   pp->Clut[xxCyan][2]    = 255;
  414.   pp->Clut[xxMagenta][0]= 255;       pp->Clut[xxMagenta][1]    = 0;
  415.   pp->Clut[xxMagenta][2]= 255;
  416.   pp->Clut[xxYellow][0]    = 255;       pp->Clut[xxYellow][1]    = 255;
  417.   pp->Clut[xxYellow][2]    = 0;
  418.   reset_par (pp);
  419. }
  420.  
  421.  
  422.  
  423.  
  424. void    Send_Copyright(void)
  425. /**
  426.  **    Remnant of older (non-GNU) releases. Leave here if you like
  427.  **/
  428. {
  429. static    unsigned char msg[] =
  430.     {0xaf,0xa8,0xcd,0xd5,0x97,0xdd,0xdd,0x9f,
  431.      0x85,0x8d,0xc6,0x8c,0x85,0xed,0x8b,0x85,
  432.      0xf2,0xc0,0xd7,0xcb,0xd1,0xc2,0xc0,0xd6,
  433.      0xaf,0xa8,0xa5};
  434. unsigned char    *p;
  435.  
  436.   p = msg;
  437.   while (*p!=0xa5)
  438.     putc ((*p++ ^ 0xa5), stderr);
  439.   exit  (100);
  440. }
  441.  
  442.  
  443.  
  444.  
  445. void    autoset_outfile_name(PAR *pp, char *inp_name)
  446. {
  447. int    len, i;
  448.  
  449.   if (*pp->outfile=='-')/* If output explicitly to stdout:        */
  450.     return;        /*    then nothing's to do here            */
  451.  
  452.   if (isalpha(*pp->outfile))/* If this lookks like an output file name:    */
  453.     return;        /*    Just accept it! Add validity check later?    */
  454.  
  455.   len = strlen(inp_name);
  456.   if (!len)        /* If input from stdin:                */
  457.   {            /*    then supply a default file name        */
  458.     pp->outfile="hp2xx.out";
  459.     return;
  460.   }
  461.  
  462.   if (strcmp(pp->mode,"pre") == 0)
  463.     return;        /* If preview mode:                */
  464.             /*    then output file name is unused        */
  465.  
  466.   for (i=len-1; i; i--)    /* Search for (last) '.' char in path        */
  467.     if (inp_name[i] == '.')
  468.         break;
  469.   i++;
  470.  
  471. /**
  472.  ** We can assume a valid inp_name file name here.
  473.  ** If not, the following fopen() in main() will fail
  474.  ** and no harm will be done by an incorrect output file name.
  475.  **/
  476.  
  477.   if ((pp->outfile = malloc(len+2+strlen(pp->mode))) == NULL)
  478.   {
  479.     fprintf(stderr,"Error: No mem for output file name!\n");
  480.     perror ("autoset_outfile_name");
  481.     exit   (ERROR);
  482.   }
  483.   strcpy(pp->outfile, inp_name);
  484.  
  485.   if (i==1 || len-i > 3) /* No or non-DOS extension: Add mode string    */
  486.   {
  487.     strcat(pp->outfile, ".");
  488.     strcat(pp->outfile, pp->mode);    /* Mode string is extension!    */
  489.   }
  490.   else
  491.     strcpy(pp->outfile+i, pp->mode);    /* Replace extension    */
  492. }
  493.  
  494.  
  495.  
  496.  
  497.  
  498. void    action (PAR *p, FILE *hd)
  499. {
  500. FILE        *td;
  501. PicBuf        *picbuf;
  502. DevPt        Maxdotcoord;
  503. hp2xx_mode    xx_mode=XX_TERM;
  504. int        i;
  505.  
  506.   if (!p->quiet)
  507.     Send_ID();
  508.   for (i=0; ModeList[i].mode != XX_TERM; i++)
  509.     if (strncmp(p->mode, ModeList[i].modestr,
  510.         strlen(ModeList[i].modestr)) == 0)
  511.     {
  512.         xx_mode = ModeList[i].mode;
  513.         break;
  514.     }
  515.  
  516. /**
  517.  ** Read HPGL data, put them into compact temporary binary file, and obtain
  518.  ** scaling data (xmin/xmax/ymin/ymax in plotter coordinates)
  519.  **/
  520.  
  521. #if defined(DOS) && defined (GNU)
  522.     /**
  523.      ** GNU libc.a (DJ's DOS port) bug fix (part 1 of 2):
  524.      **     tmpfile() does not seem to work!
  525.      ** See code below for part 2/2 (removing hp2xx.$$$).
  526.      ** NOTE:
  527.      **    If program terminates abnormally,
  528.      **    delete hp2xx.$$$ manually!!
  529.      **/
  530.   if ((td = fopen("hp2xx.$$$","w+b")) == NULL)
  531. #elif defined(AMIGA)
  532.   if ((td = fopen("t:hp2xx.tmp","w+b")) == NULL)
  533. #else
  534.   if ((td = tmpfile()) == NULL)
  535. #endif
  536.   {
  537.     perror("hp2xx -- opening temporary file");
  538.     exit (1);
  539.   }
  540.   read_HPGL (p, hd, td, &Maxdotcoord);
  541.   if (hd != stdin)
  542.     fclose (hd);
  543.  
  544. /**********************************************************
  545.  ** Vector modes:
  546.  **/
  547.   switch (xx_mode)
  548.   {
  549.     case XX_MF:
  550.     rewind    (td);        /* Rewind temp file after filling it*/
  551.     to_mftex(p, td, 0); /* Output conversion/generation    */
  552.     fclose    (td);        /* Close & unlink temp file     */
  553.     return;
  554.  
  555.     case XX_EM:
  556.     rewind    (td);
  557.     to_mftex(p, td, 1);
  558.     fclose    (td);
  559.     return;
  560.  
  561.     case XX_EPIC:
  562.     rewind    (td);
  563.     to_mftex(p, td, 2);
  564.     fclose    (td);
  565.     return;
  566.  
  567.     case XX_CAD:
  568.     rewind    (td);
  569.     to_mftex(p, td, 3);
  570.     fclose    (td);
  571.     return;
  572.  
  573. #ifdef    ATARI
  574.     case XX_CS:
  575.     rewind    (td);
  576.     to_mftex(p, td, 4);
  577.     fclose    (td);
  578.     return;
  579. #endif
  580.  
  581.     case XX_EPS:
  582.     rewind    (td);
  583.     to_eps    (p, td);
  584.     fclose    (td);
  585.     return;
  586.  
  587.     /* default: drop through    */
  588.     default:
  589.     break;
  590.   }
  591.  
  592.  
  593. /**********************************************************
  594.  ** Common part for all pixel-oriented formats:
  595.  **     Buffer allocation / vector-to-raster conversion
  596.  **/
  597.  
  598. /**
  599.  ** 1) Allocate virtual plotter area
  600.  **/
  601.   Maxdotcoord.x += (p->maxpensize - 1);
  602.   Maxdotcoord.y += (p->maxpensize - 1);
  603.   if ((picbuf = allocate_PicBuf (&Maxdotcoord, p)) == NULL)
  604.   {
  605.     fprintf(stderr,"Fatal error: cannot allocate %d*%d picture buffer\n",
  606.         Maxdotcoord.x, Maxdotcoord.y);
  607.     exit(ERROR);
  608.   }
  609.  
  610. /**
  611.  ** 2) Read vectors from temporary file and plot them in memory buffer
  612.  **/
  613.   tmpfile_to_PicBuf (picbuf, p, td);
  614.   fclose (td); /* Close & unlink tmpfile */
  615.  
  616. #if defined(DOS) && defined (GNU)
  617. /**
  618.  ** GNU libc.a (DJ's DOS port) bug fix (part 2 of 2):
  619.  **/
  620.   unlink ("hp2xx.$$$");
  621. #endif
  622.  
  623.  
  624.  
  625. /**********************************************************
  626.  ** Raster modes:
  627.  **/
  628.  
  629.   switch (xx_mode)
  630.   {
  631.   case XX_PCL:    PicBuf_to_PCL (picbuf,p); break; /* HP PCL Level 3    */
  632.   case XX_PCX:    PicBuf_to_PCX (picbuf,p); break; /* Paintbrush PCX    */
  633. #ifdef    PIC_PAC
  634.   case XX_PIC:    PicBuf_to_PIC (picbuf,p); break; /* ATARI 32K format    */
  635.   case XX_PAC:    PicBuf_to_PAC (picbuf,p); break; /* ATARI STaD format    */
  636. #endif                         /*   To be phased out!    */
  637. #ifdef    AMIGA
  638.   case XX_ILBM:    PicBuf_to_ILBM(picbuf,p); break; /* AMIGA IFF-ILBM fmt    */
  639. #endif
  640.   case XX_IMG:    PicBuf_to_IMG (picbuf,p); break; /* GEM's IMG format    */
  641.   case XX_PBM:    PicBuf_to_PBM (picbuf,p); break; /* Portable BitMap fmt    */
  642.  
  643.   case XX_PRE:
  644. /**********************************************************
  645.  ** Previewers (depending on hardware platform):
  646.  **/
  647. #if   defined(HAS_DOS_DJGR)
  648.         PicBuf_to_DJ_GR (picbuf,p); break;
  649. #elif defined(HAS_DOS_VGA)
  650.         PicBuf_to_VGA    (picbuf,p); break;
  651. #elif defined(HAS_OS2_EMX)
  652.         PicBuf_to_OS2    (picbuf,p); break;
  653. #elif defined(HAS_OS2_PM)
  654.         PicBuf_to_PM    (picbuf,p); break;
  655. #elif defined(HAS_UNIX_X11)
  656.         PicBuf_to_X11    (picbuf,p); break;
  657. #elif defined(HAS_UNIX_SUNVIEW)
  658.         PicBuf_to_Sunview(picbuf,p);break;
  659. #elif defined(ATARI)
  660.         PicBuf_to_ATARI    (picbuf,p); break;
  661. #elif defined(AMIGA)
  662.         PicBuf_to_AMIGA    (picbuf,p); break;
  663. #elif defined(VAX)
  664.         PicBuf_to_UIS    (picbuf,p); break;
  665. #else
  666.         PicBuf_to_Dummy    (); break;
  667. #endif    /* defined(...)    */
  668.  
  669. /**********************************************************
  670.  ** Done -- clean up
  671.  **/
  672.   default:    fprintf(stderr,"%s: Not implemented!\n", p->mode); break;
  673.   }
  674.  
  675.   free_PicBuf (picbuf, p->swapfile);
  676. }
  677.  
  678.  
  679.  
  680.  
  681.  
  682. /**
  683.  ** main(): Process command line & call action routine
  684.  **/
  685.  
  686. void    main (int argc, char *argv[])
  687. {
  688. PAR    par;
  689. double    width, height;
  690. int    c, i,j, longind;
  691. char    *p;
  692. FILE    *hd;
  693.  
  694. char    *shortopts = "a:c:d:D:f:h:l:m:o:O:p:P:r:s:S:V:w:x:X:y:Y:FHiqt";
  695. struct    option longopts[] = {
  696.     {"mode",    1, NULL,    'm'},
  697.     {"pencolors",    1, NULL,    'c'},
  698.     {"pensizes",    1, NULL,    'p'},
  699.     {"pages",    1, NULL,    'P'},
  700.     {"quiet",    0, NULL,    'q'},
  701.  
  702.     {"DPI",        1, NULL,    'd'},
  703.     {"DPI_x",    1, NULL,    'd'},
  704.     {"DPI_y",    1, NULL,    'D'},
  705.  
  706.     {"PCL_formfeed",0, NULL,    'F'},
  707.     {"PCL_init",    0, NULL,    'i'},
  708.     {"PCL_Deskjet",    1, NULL,    'S'},
  709.  
  710.     {"outfile",    1, NULL,    'f'},
  711.     {"logfile",    1, NULL,    'l'},
  712.     {"swapfile",    1, NULL,    's'},
  713.  
  714.     {"aspectfactor",1, NULL,    'a'},
  715.     {"height",    1, NULL,    'h'},
  716.     {"width",    1, NULL,    'w'},
  717.     {"truesize",    0, NULL,    't'},
  718.  
  719.     {"x0",        1, NULL,    'x'},
  720.     {"x1",        1, NULL,    'X'},
  721.     {"y0",        1, NULL,    'y'},
  722.     {"y1",        1, NULL,    'Y'},
  723.  
  724.     {"xoffset",    1, NULL,    'o'},
  725.     {"yoffset",    1, NULL,    'O'},
  726.  
  727. #ifdef DOS
  728.     {"VGAmodebyte",1, NULL,    'V'},
  729. #endif
  730.     {"help",    0, NULL,    'H'}
  731. };
  732.  
  733.   preset_par (&par);
  734.   width = par.width;    /* Copy defaults    */
  735.   height= par.height;
  736.  
  737.   if (argc == 1)
  738.   {
  739.     usage_msg (&par);
  740.     exit (0);
  741.   }
  742.  
  743.   while ((c=getopt_long(argc,argv, shortopts, longopts, &longind)) != EOF)
  744.     switch (c)    /* Easy addition of options ... */
  745.     {
  746.       case 'a':
  747.         par.aspectfactor = atof (optarg);
  748.         if (par.aspectfactor <= 0.0)
  749.         {
  750.             fprintf(stderr,"Aspect factor: %g illegal\n",
  751.                 par.aspectfactor);
  752.             exit(ERROR);
  753.         }
  754.         break;
  755.  
  756.       case 'c':
  757.         i = strlen(optarg);
  758.         if ((i<1) || (i>8))
  759.         {
  760.             fprintf(stderr,"Invalid pencolor string: %s\n", optarg);
  761.             exit(ERROR);
  762.         }
  763.         for (j=1, p = optarg; j <= i; j++, p++)
  764.         {
  765.             switch (*p-'0')
  766.             {
  767.             case xxBackground:par.pencolor[j] = xxBackground; break;
  768.             case xxForeground:par.pencolor[j] = xxForeground; break;
  769.             case xxRed:      par.pencolor[j] = xxRed;      break;
  770.             case xxGreen:      par.pencolor[j] = xxGreen;      break;
  771.             case xxBlue:      par.pencolor[j] = xxBlue;      break;
  772.             case xxCyan:      par.pencolor[j] = xxCyan;      break;
  773.             case xxMagenta:      par.pencolor[j] = xxMagenta;      break;
  774.             case xxYellow:      par.pencolor[j] = xxYellow;      break;
  775.             default :
  776.                   fprintf(stderr,
  777.                     "Invalid color of pen %d: %c\n", j, *p);
  778.                   exit(ERROR);
  779.             }
  780.             if (par.pencolor[j] != xxBackground &&
  781.             par.pencolor[j] != xxForeground)
  782.                 par.is_color = TRUE;
  783.         }
  784.         break;
  785.  
  786.       case 'd':
  787.         switch (par.dpi_x = atoi (optarg))
  788.         {
  789.           case 75:
  790.             break;
  791.           case 100:
  792.           case 150:
  793.           case 300:
  794.             if ((!par.quiet) && (strcmp(par.mode,"pcl")==0))
  795.             fprintf(stderr,
  796.             "Warning: DPI setting is no PCL level 3 feature!\n");
  797.             break;
  798.           default:
  799.             if ((!par.quiet) && (strcmp(par.mode,"pcl")==0))
  800.             fprintf(stderr,
  801.             "Warning: DPI value %d is invalid for PCL mode\n",
  802.                 par.dpi_x);
  803.             break;
  804.         }
  805.         break;
  806.  
  807.       case 'D':
  808.         par.dpi_y = atoi (optarg);
  809.         if ((!par.quiet) && (strcmp(par.mode,"pcl")==0))
  810.             fprintf(stderr,"Warning: %s\n",
  811.             "Different DPI for x & y is invalid for PCL mode");
  812.         break;
  813.  
  814.       case 'F':
  815.         par.formfeed = TRUE;
  816.         break;
  817.  
  818.       case 'f':
  819.         par.outfile = optarg;
  820.         break;
  821.  
  822.       case 'h':
  823.         par.height = height = atof (optarg);
  824.         if (height < 0.1)
  825.             fprintf(stderr,
  826.                 "Warning: Small height: %g mm\n", height);
  827.         if (height > 300.0)
  828.             fprintf(stderr,
  829.                 "Warning: Huge  height: %g mm\n", height);
  830.         break;
  831.  
  832.       case 'i':
  833.         par.init_p = TRUE;
  834.         break;
  835.  
  836.       case 'l':
  837.         par.logfile = optarg;
  838.         if (freopen(par.logfile, "w", stderr) == NULL)
  839.         {
  840.             perror ("Cannot open log file");
  841.             fprintf(stderr, "Error redirecting stderr\n");
  842.             fprintf(stderr, "Continuing with output to stderr\n");
  843.         }
  844.         else
  845.             Logfile_flag = TRUE;
  846.         break;
  847.  
  848.       case 'm':
  849.         par.mode = optarg;
  850.         for (i=0; ModeList[i].mode != XX_TERM; i++)
  851.             if (strcmp(ModeList[i].modestr, par.mode) == 0)
  852.                 break;
  853.         if (ModeList[i].mode == XX_TERM)
  854.         {
  855.             fprintf(stderr,
  856.             "'%s': unknown mode!\n", par.mode);
  857.             fprintf(stderr,"Supported are: ");
  858.             print_supported_modes();
  859.             Send_Copyright();
  860.         }
  861.         break;
  862.  
  863.       case 'o':
  864.         par.xoff = atof (optarg);
  865.         if (par.xoff < 0.0)
  866.         {
  867.             fprintf(stderr,"Illegal X offset: %g < 0\n",
  868.                 par.xoff);
  869.             exit(ERROR);
  870.         }
  871.         if (par.xoff > 210.0)    /* About DIN A4 width */
  872.         {
  873.             fprintf(stderr,"Illegal X offset: %g > 210\n",
  874.                 par.xoff);
  875.             exit(ERROR);
  876.         }
  877.         break;
  878.  
  879.       case 'O':
  880.         par.yoff = atof (optarg);
  881.         if (par.yoff < 0.0)
  882.         {
  883.             fprintf(stderr,"Illegal Y offset: %g < 0\n",
  884.                 par.yoff);
  885.             exit(ERROR);
  886.         }
  887.         if (par.yoff > 300.0)    /* About DIN A4 height */
  888.         {
  889.             fprintf(stderr,"Illegal Y offset: %g > 300\n",
  890.                 par.yoff);
  891.             exit(ERROR);
  892.         }
  893.         break;
  894.  
  895.       case 'p':
  896.         i = strlen(optarg);
  897.         if ((i<1) || (i>8))
  898.         {
  899.             fprintf(stderr,"Invalid pensize string: %s\n", optarg);
  900.             exit(ERROR);
  901.         }
  902.         for (j=1, p = optarg; j <= i; j++, p++)
  903.         {
  904.             if ((*p < '0') || (*p > '9'))
  905.             {
  906.                 fprintf(stderr,"Invalid size of pen %d: %c\n",
  907.                     j, *p);
  908.                 exit(ERROR);
  909.             }
  910.             par.pensize[j] = *p - '0';
  911.             if (par.maxpensize < par.pensize[j])
  912.                 par.maxpensize = par.pensize[j];
  913.         }
  914.         break;
  915.  
  916.       case 'P':
  917.         if (*optarg == ':')
  918.         {
  919.             par.first_page = 0;
  920.             optarg++;
  921.             if (sscanf(optarg,"%d", &par.last_page) != 1)
  922.                 par.last_page = 0;
  923.         }
  924.         else
  925.             switch (sscanf(optarg,"%d%*c%d",
  926.                 &par.first_page, &par.last_page))
  927.             {
  928.               case 1:
  929.                 par.last_page = 0;
  930.                 break;
  931.               case 2:
  932.                 break;
  933.               default:
  934.                 fprintf(stderr,"Illegal page range.\n");
  935.                 usage_msg (&par);
  936.                 exit(ERROR);
  937.             }
  938.         break;
  939.  
  940.       case 'q':
  941.         par.quiet = TRUE;
  942.         break;
  943.  
  944.       case 'r':
  945.         par.rotation = atof(optarg);
  946.         break;
  947.  
  948.       case 'S':
  949.         par.specials = atoi (optarg);
  950.         break;
  951.  
  952.       case 's':
  953.         par.swapfile = optarg;
  954.         break;
  955.  
  956.       case 't':
  957.         par.truesize = TRUE;
  958.         break;
  959.  
  960.       case 'V':
  961.         par.vga_mode = atoi (optarg);
  962.         break;
  963.  
  964.       case 'w':
  965.         par.width = width = atof (optarg);
  966.         if (width < 0.1)
  967.             fprintf(stderr,
  968.                 "Warning: Small width: %g mm\n", width);
  969.         if (width > 300.0)
  970.             fprintf(stderr,
  971.                 "Warning: Huge  width: %g mm\n", width);
  972.         break;
  973.  
  974.       case 'x':
  975.         par.x0 = atof (optarg);
  976.         break;
  977.  
  978.       case 'X':
  979.         par.x1 = atof (optarg);
  980.         break;
  981.  
  982.       case 'y':
  983.         par.y0 = atof (optarg);
  984.         break;
  985.  
  986.       case 'Y':
  987.         par.y1 = atof (optarg);
  988.         break;
  989.  
  990.       case 'H':
  991.       case '?':
  992.       default:
  993.         usage_msg (&par);
  994.         exit (ERROR);
  995.     }
  996.  
  997. /**
  998.  ** Place consistency checks here
  999.  ** - I'm just not in the mood for writing them myself ...
  1000.  **/
  1001.  
  1002.   if (par.dpi_y == 0)
  1003.     par.dpi_y = par.dpi_x;
  1004.  
  1005.   if (optind == argc)        /* No  filename: use stdin    */
  1006.   {
  1007.     autoset_outfile_name (&par, argv[optind]);
  1008.     action (&par, stdin);
  1009.   }
  1010.   else    for ( ; optind < argc; optind++)
  1011.     {            /* Multiple-input file handling: */
  1012.         autoset_outfile_name (&par, argv[optind]);
  1013.         if ((hd=fopen (argv[optind], READ_BIN)) == NULL)
  1014.         {
  1015.             perror("hp2xx");
  1016.             exit (ERROR);
  1017.         }
  1018.         action (&par, hd);    /* action() closes file    */
  1019.         reset_par (&par);
  1020.         par.width = width;    /* Restore width/height    */
  1021.         par.height= height;    /* Changed in hpgl.c !    */
  1022.     }
  1023.  
  1024.   if (*par.logfile)
  1025.     fclose (stderr);
  1026.   exit (0);
  1027. }
  1028.