Back to index

tetex-bin  3.0
psspecial.c
Go to the documentation of this file.
00001 /*  $Header$
00002     
00003     This is dvipdfm, a DVI to PDF translator.
00004     Copyright (C) 1998, 1999 by Mark A. Wicks
00005     
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010     
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015     
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019     
00020     The author may be contacted via the e-mail address
00021     
00022     mwicks@kettering.edu
00023 */
00024 
00025 #include <stdlib.h>
00026 #include "system.h"
00027 #include "mem.h"
00028 #include "mfileio.h"
00029 #include "psspecial.h"
00030 #include "pdfparse.h"
00031 #include "pdfspecial.h"
00032 #include "psimage.h"
00033 #include "mpost.h"
00034 #include "pdfdoc.h"
00035 
00036 #define HOFFSET 1
00037 #define VOFFSET 2
00038 #define HSIZE   3
00039 #define VSIZE   4
00040 #define HSCALE  5
00041 #define VSCALE  6
00042 #define ANGLE   7
00043 #define CLIP    8
00044 #define LLX     9
00045 #define LLY    10
00046 #define URX    11
00047 #define URY    12
00048 #define RWI    13
00049 #define RHI    14
00050 
00051 struct keys
00052 {
00053   char *key;
00054   int id;
00055 } keys[] = {
00056   {"hoffset", HOFFSET},
00057   {"voffset", VOFFSET},
00058   {"hsize", HSIZE},
00059   {"vsize", VSIZE},
00060   {"hscale", HSCALE},
00061   {"vscale", VSCALE},
00062   {"angle", ANGLE},
00063   {"clip", CLIP},
00064   {"llx", LLX},
00065   {"lly", LLY},
00066   {"urx", URX},
00067   {"ury", URY},
00068   {"rwi", RWI},
00069   {"rhi", RHI},
00070 };
00071 
00072 static int parse_psfile (char **start, char *end, double x_user, double y_user) 
00073 {
00074   char *key, *val, *filename = NULL;
00075   double hoffset = 0.0, voffset = 0.0;
00076   double hsize = 0.0, vsize = 0.0;
00077   int error = 0;
00078   struct xform_info *p = new_xform_info();
00079   skip_white(start, end);
00080   parse_key_val (start, end, &key, &val);
00081   if (key && val) {
00082     filename = val;
00083     RELEASE (key);
00084     skip_white (start, end);
00085     while (*start < end) {
00086       parse_key_val (start, end, &key, &val);
00087       if (key) {
00088        int i;
00089        for (i=0; i<sizeof(keys)/sizeof(keys[0]); i++) {
00090          if (!strcmp (key, keys[i].key))
00091            break;
00092        }
00093        if (i == sizeof(keys)/sizeof(keys[0])) {
00094          fprintf (stderr, "\nUnknown key in special: %s\n", key);
00095          break;
00096        }
00097        if (val) {
00098          if (is_a_number(val)) {
00099            switch (keys[i].id) {
00100            case HOFFSET:
00101              hoffset = atof (val);
00102              break;
00103            case VOFFSET:
00104              voffset = atof (val);
00105              break;
00106            case HSIZE:
00107              hsize = atof (val);
00108              break;
00109            case VSIZE:
00110              vsize = atof (val);
00111              break;
00112            case HSCALE:
00113              p -> xscale = atof(val)/100.0;
00114              break;
00115            case VSCALE:
00116              p -> yscale = atof(val)/100.0;
00117              break;
00118            case ANGLE:
00119              p -> rotate = atof(val)*M_PI/180.0;
00120              break;
00121            case LLX:
00122              p -> user_bbox = 1;
00123              p -> u_llx = atof(val);
00124              break;
00125            case LLY:
00126              p -> user_bbox = 1;
00127              p -> u_lly = atof(val);
00128              break;
00129            case URX:
00130              p -> user_bbox = 1;
00131              p -> u_urx = atof(val);
00132              break;
00133            case URY:
00134              p -> user_bbox = 1;
00135              p -> u_ury = atof(val);
00136              break;
00137            case RWI:
00138              p -> width = atof(val)/10.0;
00139              break;
00140            case RHI:
00141              p -> height = atof(val)/10.0;
00142              break;
00143            default:
00144              if (keys[i].id == CLIP) {
00145               fprintf (stderr, "\nPSfile key \"clip\" takes no value\n");
00146              } else
00147               fprintf (stderr, "\nPSfile key \"%s=%s\" not recognized\n",
00148                       key, val);
00149              error = 1;
00150            }
00151          } else {
00152            fprintf (stderr, "\nPSfile key \"%s\" assigned nonnumeric value\n", key);
00153            error = 1;
00154          }
00155          RELEASE (val);
00156        } else {  /* Keywords without values */
00157          switch (keys[i].id) {
00158          case CLIP:
00159            p -> clip  = 1;
00160            break;
00161          default:
00162            fprintf (stderr, "\nPSfile key \"%s\" needs a value\n",
00163                    key);
00164            error = 1;
00165          }
00166        }
00167        RELEASE (key);
00168       } else {
00169        fprintf (stderr, "\nInvalid keyword in PSfile special\n");
00170        dump (*start, end);
00171        break;
00172       }
00173       skip_white (start, end);
00174     } /* If here and *start == end we got something */
00175     if (*start == end && validate_image_xform_info (p)) {
00176       pdf_obj *result;
00177       result = embed_image (filename, p, x_user, y_user, NULL);
00178       if (result)
00179        pdf_release_obj (result);
00180     }
00181   } else {
00182     fprintf (stderr, "\nPSfile special has no filename\n");
00183     error = 1;
00184   }
00185   if (filename)
00186     RELEASE (filename);
00187   release_xform_info (p);
00188   return !error;
00189 }
00190 
00191 static void do_texfig (char **start, char *end)
00192 {
00193   char *filename;
00194   struct xform_info *p;
00195   skip_white (start, end);
00196   if (*start < end && (filename = parse_val_ident (start, end))) {
00197     p = new_xform_info (); /* Leave this empty */
00198     p-> yscale = -1;
00199     if (validate_image_xform_info (p)) {
00200       pdf_obj *result;
00201       result = embed_image (filename, p, 0.0, 0.0, NULL);
00202       if (result)
00203        pdf_release_obj (result);
00204     }
00205     release_xform_info (p);
00206     RELEASE (filename);
00207   } else {
00208     fprintf (stderr, "Expecting filename here:\n");
00209     dump (*start, end);
00210   }
00211 }
00212 
00213 
00214 int ps_parse_special (char *buffer, UNSIGNED_QUAD size, double x_user,
00215                     double y_user)
00216 {
00217   char *start = buffer, *end;
00218   static int block_pending = 0;
00219   static double pending_x=0.0, pending_y=0.0;
00220   int result = 0;
00221   end = buffer + size;
00222   skip_white (&start, end);
00223   if (!strncmp (start, "PSfile", strlen("PSfile")) ||
00224       !strncmp (start, "psfile", strlen("PSfile"))) {
00225     result = 1; /* This means it is a PSfile special, not that it was
00226                  successful */
00227     parse_psfile(&start, end, x_user, y_user);
00228   } else if (!strncmp (start, "ps::[begin]", strlen("ps::[begin]"))) {
00229     start += strlen("ps::[begin]");
00230     block_pending = 1;
00231     pending_x = x_user;
00232     pending_y = y_user;
00233     result = 1; /* Likewise */
00234     do_raw_ps_special (&start, end, 1, x_user, y_user);
00235   } else if (!strncmp (start, "ps::[end]", strlen("ps::[end]"))) {
00236     if (block_pending) {
00237       start += strlen("ps::[end]");
00238       do_raw_ps_special (&start, end, 1, pending_x, pending_y);
00239       block_pending = 0;
00240     } else {
00241       fprintf (stderr, "\nps::[end] without ps::[begin] ignored.\n");
00242     }
00243     result = 1; /* Likewise */
00244   } else if (!strncmp (start, "ps: plotfile", strlen("ps: plotfile"))) {
00245     /* This is a bizarre, ugly  special case.. Not really postscript
00246        code */
00247     start += strlen ("ps: plotfile");
00248     result = 1;
00249     do_texfig (&start, end);
00250   } else if (!strncmp (start, "ps::", strlen("ps::")) ||
00251             !strncmp (start, "PS::", strlen("PS::"))) {
00252     /* dvipdfm doesn't distinguish between ps:: and ps: */
00253     start += 4;
00254     result = 1; /* Likewise */
00255     do_raw_ps_special (&start, end, 1, 
00256                      block_pending?pending_x:x_user, block_pending?pending_y:y_user);
00257   } else if (!strncmp (start, "ps:", strlen("ps:")) ||
00258             !strncmp (start, "PS:", strlen("PS:"))) {
00259     start += 3;
00260     result = 1; /* Likewise */
00261     do_raw_ps_special (&start, end, 1,
00262                      block_pending?pending_x:x_user, block_pending?pending_y:y_user);
00263   }
00264   return result;
00265 }