[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: CVS update: convert_sym.c



  User: ahvezda 
  Date: 05/08/19 21:46:25

  Modified:    .        convert_sym.c
  Log:
  Commited updated converter by Jeff McLamb
  
  
  
  
  Revision  Changes    Path
  1.11      +695 -181  eda/geda/devel/utils/src/convert_sym.c
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: convert_sym.c
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/utils/src/convert_sym.c,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -b -r1.10 -r1.11
  --- convert_sym.c	7 Feb 2005 23:57:14 -0000	1.10
  +++ convert_sym.c	20 Aug 2005 01:46:25 -0000	1.11
  @@ -7,6 +7,18 @@
    *
    *     Copyright (C) 1999-2002  Mike Jarabek
    *   
  + *     CHANGE HISTORY:
  + *
  + *     Updated 8/16/2005 by Jeff McLamb (mclamb AT bustech.com)
  + *       - Updated to support gEDA file format version 1
  + *       - Added capability to import more graphic styles from ViewDraw
  + *       - Corrected bug associated with absense of library reference in
  + *         local ViewDraw symbols
  + *       - Removed command-line option -s; no longer necessary
  + *       - Mapped ViewDraw "SIGNAL" attribute to gEDA "net" attribute
  + *       - Mapped ViewDraw "HETERO" attribute to a new "split" attribute
  + *       - Mapped ViewDraw "PINTYPE" attributes to correct gEDA pintypes
  + *   
    *   This program is free software; you can redistribute it and/or
    *   modify it under the terms of the GNU General Public License
    *   as published by the Free Software Foundation; either version 2
  @@ -21,7 +33,7 @@
    *   along with this program; if not, write to the Free Software
    *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
    *
  - * 	$Id: convert_sym.c,v 1.10 2005/02/07 23:57:14 danmc Exp $	 
  + * 	$Id: convert_sym.c,v 1.11 2005/08/20 01:46:25 ahvezda Exp $	 
    */
   
   #include <stdio.h>
  @@ -40,7 +52,7 @@
   
   #if 0 /* removed by AVH just to make a -Wall -Werror happy */
   #ifndef lint
  -static char vcid[] = "$Id: convert_sym.c,v 1.10 2005/02/07 23:57:14 danmc Exp $";
  +static char vcid[] = "$Id: convert_sym.c,v 1.11 2005/08/20 01:46:25 ahvezda Exp $";
   #endif /* lint */
   #endif
   
  @@ -51,8 +63,16 @@
   
   /* local defines */
   #define MAX_TEXTLEN      1024
  -#define MAX_NODES         300
  -#define MAX_POINTS        300
  +#define MAX_NODES        1024
  +#define MAX_POINTS       1024
  +
  +/* gEDA style enumerators */
  +typedef enum {END_NONE, END_SQUARE, END_ROUND} OBJECT_END;
  +typedef enum {TYPE_SOLID, TYPE_DOTTED, TYPE_DASHED, TYPE_CENTER,
  +              TYPE_PHANTOM, TYPE_ERASE} OBJECT_TYPE;
  +typedef enum {FILLING_HOLLOW, FILLING_FILL, FILLING_MESH, FILLING_HATCH,
  +              FILLING_VOID} OBJECT_FILLING;
  +typedef enum {NORMAL_PIN, BUS_PIN} OBJECT_PINTYPE;
   
   /* Viewdraw Colours
    *
  @@ -68,6 +88,36 @@
    *
    */
   
  +/* ViewDraw fill styles:
  + * 0  = Hollow, no fill
  + * 1  = Solid, full fill
  + * 2  = Grey92, mostly fill, thick array of empty space
  + * 4  = Grey50, 50% dot fill
  + * 6  = Grey08, thicker array of dots
  + * 7  = Grey04, thin array of dots
  + * 8  = Diagdn2, widely-spaced diagonals from top left to bottom right
  + * 11 = Diagdn1, narrowly-spaced diagonals from top left to bottom right
  + * 13 = Diagup2, widely-spaced diagonals from bottom left to top right
  + * 16 = Diagup1, narrowly-spaced diagonals from bottom left to top right
  + * 19 = Horiz, narrowly-spaced horizontal lines
  + * 21 = Vert, narrowly-spaced vertical lines
  + * 22 = Grid2, widely-spaced square grid
  + * 23 = Grid1, narrowly-spaced square grid
  + * 24 = X2, widely-spaced diagonal crosshatch
  + * 25 = X1, narrowly-spaced diagonal crosshatch
  +*/
  +
  +/* ViewDraw line styles:
  + * 0 = Solid
  + * 1 = Dash
  + * 2 = Center, alternating short and long dashes
  + * 3 = Phantom, alternating dash and two dots
  + * 4 = Big dash
  + * 5 = Dot
  + * 6 = Dash-dot, alternating dashes and dots
  + * 7 = Medium dash
  +*/
  +
   /* tables */
   int colormap[16] =   /* index is viewlogic colour, entry is geda color */
   {
  @@ -89,6 +139,106 @@
     1, /* 15 */
   };
   
  +/* Fill style structure */
  +struct FillStyle {
  +  OBJECT_FILLING fill_type;  /* gEDA object fill type */
  +  int fill_width;            /* width of the fill lines */
  +  int fill_angle1;           /* first angle of fill lines */
  +  int fill_pitch1;           /* first pitch/spacing of fill lines */
  +  int fill_angle2;           /* second angle of fill lines */
  +  int fill_pitch2;           /* second pitch/spacing of fill lines */
  +};
  +
  +/* index is ViewDraw fill style, entry is above gEDA FillStyle struct */
  +struct FillStyle fillmap[26] = 
  +{  
  +  /* 0  = Hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 1  = Solid, full fill */
  +  {FILLING_FILL,   -1,  -1, -1,  -1, -1},
  +  /* 2  = Grey92, mostly fill, thick array of empty space */
  +  {FILLING_MESH,   20,  45, 30, 135, 30},
  +  /* 3  = Undefined; assume hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 4  = Grey50, 50% dot fill */
  +  {FILLING_MESH,   10,  45, 20, 135, 20},
  +  /* 5  = Undefined; assume hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 6  = Grey08, thicker array of dots */
  +  {FILLING_MESH,    0,  45, 40, 135, 40}, /* Can't do dots; use mesh */
  +  /* 7  = Grey04, sparse array of dots */
  +  {FILLING_MESH,    0,  45, 80, 135, 80}, /* Can't do dots; use mesh */
  +  /* 8  = Diagdn2, widely-spaced diagonals from top left to bottom right */
  +  {FILLING_HATCH,   0, 135, 80,  -1, -1},
  +  /* 9  = Undefined; assume hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 10 = Undefined; assume hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 11 = Diagdn1, narrowly-spaced diagonals from top left to bottom right */
  +  {FILLING_HATCH,   0, 135, 40,  -1, -1},
  +  /* 12 = Undefined; assume hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 13 = Diagup2, widely-spaced diagonals from bottom left to top right */
  +  {FILLING_HATCH,   0,  45, 80,  -1, -1},
  +  /* 14 = Undefined; assume hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 15 = Undefined; assume hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 16 = Diagup1, narrowly-spaced diagonals from bottom left to top right */
  +  {FILLING_HATCH,   0,  45, 40,  -1, -1},
  +  /* 17 = Undefined; assume hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 18 = Undefined; assume hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 19 = Horiz, narrowly-spaced horizontal lines */
  +  {FILLING_HATCH,  10,   0, 40,  -1, -1},
  +  /* 20 = Undefined; assume hollow, no fill */
  +  {FILLING_HOLLOW, -1,  -1, -1,  -1, -1},
  +  /* 21 = Vert, narrowly-spaced vertical lines */
  +  {FILLING_HATCH,  10,  90, 40,  -1, -1},
  +  /* 22 = Grid2, widely-spaced square grid */
  +  {FILLING_MESH,    0,   0, 80,  90, 80},
  +  /* 23 = Grid1, narrowly-spaced square grid */
  +  {FILLING_MESH,    0,   0, 40,  90, 40},
  +  /* 24 = X2, widely-spaced diagonal crosshatch */
  +  {FILLING_MESH,    0,  45, 80, 135, 80},
  +  /* 25 = X1, narrowly-spaced diagonal crosshatch */
  +  {FILLING_MESH,    0,  45, 40, 135, 40},
  +}; /* fillmap */
  +
  +#define FILL_DEFAULT (struct FillStyle){FILLING_HOLLOW, -1, -1, -1, -1, -1}
  +
  +/* Line style structure */
  +struct LineStyle {
  +  int line_width;             /* width of line */
  +  OBJECT_END line_capstyle;   /* gEDA line cap style (end style) */
  +  OBJECT_TYPE line_dashstyle; /* gEDA line dash style */
  +  int line_dashlength;        /* length of line dashes */
  +  int line_dashspace;         /* space between line dashes */
  +};
  +
  +struct LineStyle linemap[8] = 
  +{  
  +  /* 0 = Solid */
  +  {0, END_NONE, TYPE_SOLID,    -1,  -1},
  +  /* 1 = Dash */
  +  {0, END_NONE, TYPE_DASHED,  100, 100},
  +  /* 2 = Center, alternating short and long dashes */
  +  {0, END_NONE, TYPE_CENTER,  100, 100},
  +  /* 3 = Phantom, alternating dash and two dots */
  +  {0, END_NONE, TYPE_PHANTOM, 100, 100},
  +  /* 4 = Big dash */
  +  {0, END_NONE, TYPE_DASHED,  400, 100},
  +  /* 5 = Dot */
  +  {0, END_NONE, TYPE_DOTTED,   -1, 100},
  +  /* 6 = Dash-dot, alternating dashes and dots */
  +  {0, END_NONE, TYPE_CENTER,  100, 100},
  +  /* 7 = Medium dash */
  +  {0, END_NONE, TYPE_DASHED,  200, 100},
  +}; /* linemap */
  +
  +#define LINE_DEFAULT (struct LineStyle){0, END_NONE, TYPE_SOLID, -1, -1}
  +
   /* attribute translation table */
   struct Translation {
     char *origName;       /* name as it appears on a viewlogic schematic */
  @@ -103,15 +253,13 @@
   
   struct Translation translations[] = 
   {
  -  {"PKG_TYPE", "PHYSICAL", REPLACE_NAME},
  -  {"PART_SPEC","device",   REPLACE_NAME},
  +  {"PKG_TYPE", "footprint", REPLACE_NAME},
     {"LEVEL",    "",         KILL},
  -  {"P/D_NUM",  "",         KILL},
  -  {"NC",       "",         KILL},
  -  {"REFDES",   "refdes",     REPLACE_NAME},
  -  /*{"PINTYPE",  "",         KILL},*/
  +  /* {"NC",       "",          KILL}, */
     {"NAME",     "",         KILL},
     {"LABEL",    "",         KILL},
  +  {"SIGNAL",   "net",       REPLACE_NAME},
  +  {"HETERO",   "split",     REPLACE_NAME},
   };
   
   unsigned int nTranslations = sizeof(translations)/sizeof(struct Translation);
  @@ -123,14 +271,14 @@
   void         strtolower(char *s);
   int get_continued_string(char *buf, size_t buffer_size, FILE *fp);
   int get_style(FILE *fp, unsigned int *colour, 
  -	      unsigned int *fillstyle,
  -	      unsigned int *linestyle);
  +	      struct LineStyle *linestyle,
  +	      struct FillStyle *fillstyle);
   void set_orientation(int *angle, int *mirror, int orientation);
   
   /* conversion readers */
   void do_nop(FILE *fp);
   void do_bounding_box(FILE *fp);
  -void do_unnatached_attribute(FILE *fp);
  +void do_unattached_attribute(FILE *fp);
   void do_attached_attribute(FILE *fp);
   void do_text(FILE *fp);
   void do_line(FILE *fp);
  @@ -152,15 +300,21 @@
   void attribute_object(int x, int y, unsigned int color, unsigned int  size,
   		      unsigned int visibility, unsigned int show_name_value, 
   		      int angle, char *name, char *value, unsigned int origin);
  -void line_object( int x1, int y1, int x2, int y2, unsigned int color);
  -void circle_object(int bx, int by, unsigned int radius, unsigned int bcolor);
  -void pin_object(int x1, int y1, int x2, int y2, unsigned int color);
  +void line_object(int x1, int y1, int x2, int y2, unsigned int color,
  +                 struct LineStyle *linestyle);
  +void circle_object(int bx, int by, unsigned int radius, unsigned int bcolor,
  +                   struct LineStyle *linestyle, struct FillStyle *fillstyle);
  +void pin_object(int x1, int y1, int x2, int y2, unsigned int color,
  +                OBJECT_PINTYPE pintype, unsigned int whichend);
   void box_object(int x1, int y1, unsigned int width, unsigned int height,
  -		unsigned int color);
  +		unsigned int color, struct LineStyle *linestyle,
  +                struct FillStyle *fillstyle);
   void arc_object(int x1, int y1, unsigned int radius, 
  -		int start_angle, int sweep_angle, unsigned int color);
  +		int start_angle, int sweep_angle, unsigned int color,
  +                struct LineStyle *linestyle);
   void net_segment(int x1, int y1, int x2, int y2, unsigned int color);
  -void bus_segment(int x1, int y1, int x2, int y2, unsigned int color);
  +void bus_segment(int x1, int y1, int x2, int y2, unsigned int color,
  +                 int ripperdir);
   void complex_object(int x, int y, unsigned int selectable, 
   	       int angle, unsigned int mirror, char *name);
   void begin_attach(void);
  @@ -186,7 +340,7 @@
   int net_nodes_x[MAX_NODES];
   int net_nodes_y[MAX_NODES];
   int scale          = 10;   /* scale factor for viewlogic-geda conversion */
  -int symbol_mode    = 0;
  +/* int symbol_mode    = 0; */
   int records_processed = 0; /* used to keep track of the number of viewlogic
   			    * records processed for diagnostics
   			    */
  @@ -200,9 +354,8 @@
   usage(char *cmd)
   {
     fprintf(stderr,
  -	  "Usage:\n\t%s [-s] <viewlogic_filename>\n"
  +	  "Usage:\n\t%s <viewlogic_filename>\n"
   	  " Where:\n"
  -	  "\t-s                   converting symbol file.\n" 
   	  "\t<viewlogic_filename> is the name of the file you\n"
   	  "\t\t\t  want to convert to gEDA format\n", cmd);
     exit(1);
  @@ -217,13 +370,13 @@
   
     int ch;
   
  -  while ((ch = getopt (argc, argv, "s?h")) != -1) {
  +  while ((ch = getopt (argc, argv, "?h")) != -1) {
       switch (ch) {
  -
  +/*
       case 's':
         symbol_mode = 1;
         break;
  -      
  +*/      
       case '?':
       case 'h':
       default:
  @@ -264,7 +417,7 @@
     char buf[MAX_TEXTLEN];
   
     /* output pre-amble */
  -  printf("v 19991011\n"); /* Set the version of the file to a fixed date AVH */
  +  printf("v 20050313 1\n"); /* Version timestamp 20050313, file version 1 */
     reset_attributes();
   
   
  @@ -277,7 +430,7 @@
   	  break;
   	    
   	case 'U':
  -	  do_unnatached_attribute(fp);
  +	  do_unattached_attribute(fp);
   	  break;
   
   	case 'A':
  @@ -382,6 +535,10 @@
   void
   do_bounding_box(FILE *fp)
   {
  +  unsigned int color;
  +  struct LineStyle linestyle;
  +  struct FillStyle fillstyle;
  +
     /* just fetch the values and store */
     if(fscanf(fp,"%d %d %d %d\n", &minx, &miny, &maxx, &maxy) != 4)
       {
  @@ -395,19 +552,30 @@
     maxx *= scale;
     maxy *= scale;
   
  +/* Do not draw the bounding box, only retrieve the min and max values */
  +#if 0
     if (symbol_mode == 0)
  -    box_object(minx, miny, maxx-minx, maxy-miny, GRAPHIC_COLOR);
  +  {
  +    color = GRAPHIC_COLOR;
  +    linestyle = LINE_DEFAULT;
  +    fillstyle = FILL_DEFAULT;
  +    box_object(minx, miny, maxx-minx, maxy-miny, color, &linestyle,
  +               &fillstyle);
  +  }
  +#endif
   }
   
   
   void
  -do_unnatached_attribute(FILE *fp)
  +do_unattached_attribute(FILE *fp)
   {
     int x,y,angle;
     unsigned int dummy, color, size, origin, viewvis;
  -  unsigned int linestyle, fillstyle, index;
  +  unsigned int index;
     unsigned int visibility, show_name_value;
     char text[MAX_TEXTLEN], *name, *value;
  +  struct LineStyle linestyle;
  +  struct FillStyle fillstyle;
   
     /* if we are inside of a pin definition, terminate */
     reset_attributes();
  @@ -434,7 +602,9 @@
     y *= scale;
     color = DETACHED_ATTRIBUTE_COLOR;
   
  -  get_style(fp, &dummy, &fillstyle, &linestyle);
  +  linestyle = LINE_DEFAULT;
  +  fillstyle = FILL_DEFAULT;
  +  get_style(fp, &dummy, &linestyle, &fillstyle);
   
     /* evaluate visibility for attributes */
     switch(viewvis)
  @@ -469,8 +639,15 @@
     /* find name and value pair */
     name = text;
     index = strindex(text,'=');
  +  if (text[index] == '=')
  +  {
     text[index] = 0;
     value = &text[index+1];
  +  }
  +  else
  +  {
  +    value = NULL;
  +  }
   
     attribute_object( x, y, color, size, visibility, show_name_value, angle,
   		    name, value, origin );
  @@ -483,8 +660,10 @@
     int x,y,angle;
     unsigned int color, dummy, size, origin, viewvis;
     unsigned int visibility, show_name_value;
  -  unsigned int fillstyle, linestyle, index;
  +  unsigned int index;
     char text[MAX_TEXTLEN],text2[MAX_TEXTLEN],*name,*value;
  +  struct LineStyle linestyle;
  +  struct FillStyle fillstyle;
   
     /* for the moment just represent as text */
     
  @@ -506,7 +685,9 @@
     get_continued_string(text, MAX_TEXTLEN, fp);
   
     color = ATTRIBUTE_COLOR;
  -  get_style(fp, &dummy, &fillstyle, &linestyle);
  +  linestyle = LINE_DEFAULT;
  +  fillstyle = FILL_DEFAULT;
  +  get_style(fp, &dummy, &linestyle, &fillstyle);
   
     /* evaluate visibility for attributes */
     switch(viewvis)
  @@ -522,8 +703,8 @@
         break;
   
       case 2:   /* only name visible */
  -      visibility = 2;
  -      show_name_value = 1;
  +      visibility = 1;
  +      show_name_value = 2;
         break;
   
       case 3:   /* only value visible */
  @@ -541,6 +722,84 @@
     begin_attach();
     if(pin_attributes) /* are we adding to a pin ? */
     {   
  +    /* translate pintype attribute */
  +    if (strncmp(text, "PINTYPE=", 8) == 0)
  +    {
  +      value = &text[strindex(text,'=')+1];
  +      if (strcmp(value, "ANALOG") == 0)
  +      {
  +#ifdef HAVE_SNPRINTF
  +        snprintf(text, MAX_TEXTLEN, "pintype=pas");
  +#else
  +        sprintf(text, "pintype=pas");
  +#endif
  +      }
  +      else if (strcmp(value, "BI") == 0)
  +      {
  +#ifdef HAVE_SNPRINTF
  +        snprintf(text, MAX_TEXTLEN, "pintype=io");
  +#else
  +        sprintf(text, "pintype=io");
  +#endif
  +      }
  +      else if (strcmp(value, "IN") == 0)
  +      {
  +#ifdef HAVE_SNPRINTF
  +        snprintf(text, MAX_TEXTLEN, "pintype=in");
  +#else
  +        sprintf(text, "pintype=in");
  +#endif
  +      }
  +      else if (strcmp(value, "OCL") == 0)
  +      {
  +#ifdef HAVE_SNPRINTF
  +        snprintf(text, MAX_TEXTLEN, "pintype=oc");
  +#else
  +        sprintf(text, "pintype=oc");
  +#endif
  +      }
  +      else if (strcmp(value, "OEM") == 0)
  +      {
  +#ifdef HAVE_SNPRINTF
  +        snprintf(text, MAX_TEXTLEN, "pintype=oe");
  +#else
  +        sprintf(text, "pintype=oe");
  +#endif
  +      }
  +      else if (strcmp(value, "OUT") == 0)
  +      {
  +#ifdef HAVE_SNPRINTF
  +        snprintf(text, MAX_TEXTLEN, "pintype=out");
  +#else
  +        sprintf(text, "pintype=out");
  +#endif
  +      }
  +      else if (strcmp(value, "TRI") == 0)
  +      {
  +#ifdef HAVE_SNPRINTF
  +        snprintf(text, MAX_TEXTLEN, "pintype=tri");
  +#else
  +        sprintf(text, "pintype=tri");
  +#endif
  +      }
  +      else
  +      {
  +        fprintf(stderr,"Error: Invalid or unknown pin type \"%s\" for record "
  +	        "#%d in %s()\n", value, records_processed, __FUNCTION__);
  +        exit(1);
  +      }
  +
  +      /* find name and value pair */
  +      name = text;
  +      index = strindex(text,'=');
  +      text[index] = 0;
  +      value = &text[index+1];
  +      attribute_object( x, y, color, size, visibility, show_name_value,
  +                        angle, name, value, origin );
  +
  +      /* done attaching pin attributes */
  +      return;
  +    }
       /* attach the pinseq and pinnumber attributes */
       if(text[0] == '#')
       {
  @@ -585,8 +844,15 @@
     
     name = text;
     index = strindex(text,'=');
  +  if (text[index] == '=')
  +  {
     text[index] = 0;
     value = &text[index+1];
  +  }
  +  else
  +  {
  +    value = NULL;
  +  }
     
     attribute_object( x, y, color, size, visibility, show_name_value, angle,
                       name, value, origin );
  @@ -597,9 +863,11 @@
   {
     int x,y,angle;
     unsigned int size, origin;
  -  unsigned int color, linestyle, fillstyle, show_name_value;
  +  unsigned int color, show_name_value;
     unsigned int visibility;
     char text[MAX_TEXTLEN];
  +  struct LineStyle linestyle;
  +  struct FillStyle fillstyle;
   
     
     /* if we are inside of a pin definition, terminate */
  @@ -627,7 +895,9 @@
     show_name_value = 0;
   
     /* get possible colour change */
  -  get_style(fp, &color, &fillstyle, &linestyle);
  +  linestyle = LINE_DEFAULT;
  +  fillstyle = FILL_DEFAULT;
  +  get_style(fp, &color, &linestyle, &fillstyle);
   
     text_object(x, y, color, size, visibility, show_name_value, angle, text, \
   	      origin);
  @@ -639,7 +909,8 @@
   {
     int x[MAX_POINTS],y[MAX_POINTS];
     unsigned int pairs,color,i;
  -  unsigned int fillstyle, linestyle;
  +  struct LineStyle linestyle;
  +  struct FillStyle fillstyle;
     
   
     /* if we are inside of a pin definition, terminate */
  @@ -672,15 +943,20 @@
         x[i] *= scale;
         y[i] *= scale;
       }
  -  getc(fp); /* slurp up last CR */
  +
  +  /* slurp up trailing CR/NL */
  +  if (getc(fp) == '\r')
  +    getc(fp);
   
     color = GRAPHIC_COLOR;
  +  linestyle = LINE_DEFAULT;
  +  fillstyle = FILL_DEFAULT;
     /* now check for an optional style record */
  -  get_style(fp, &color, &fillstyle, &linestyle);
  +  get_style(fp, &color, &linestyle, &fillstyle);
   
     /* now, output the line as a series of geda lines */
     for(i=1; i<pairs; i++)
  -      line_object(x[i-1],y[i-1],x[i],y[i],color);
  +      line_object(x[i-1],y[i-1],x[i],y[i],color,&linestyle);
   
   }
   
  @@ -689,8 +965,14 @@
   do_pin(FILE *fp)
   {
     unsigned int pindir, pinsense, color;
  -  unsigned int radius, radius2, bcolor;
  -  int x1, y1, x2, y2, bx, by;
  +  unsigned int bradius = 25;
  +  unsigned int bdiameter = 2*bradius;
  +  unsigned int bcolor = LOGIC_BUBBLE_COLOR;
  +  int x1, y1, x2, y2, bx, by, bx1, by1, bx2, by2;
  +  OBJECT_PINTYPE pintype;
  +  unsigned int whichend;
  +  struct LineStyle linestyle;
  +  struct FillStyle fillstyle;
   
     /* if we are inside of a pin definition, terminate */
     reset_attributes();
  @@ -711,86 +993,109 @@
     y1 *= scale;
     x2 *= scale;
     y2 *= scale;
  +  bx1 = x1;
  +  by1 = y1;
  +  bx2 = x2;
  +  by2 = y2;
     color = PIN_COLOR;
   
   
  -  /* if this pin has to be of negative polarity, add a bitty bubble
  -   * and adjust the size of the pin
  -   */
  -  radius = 25;
  -  radius2 = 2*radius;
  -  bcolor = LOGIC_BUBBLE_COLOR;
  -  
  -  if(pinsense == 1) {
  -    
  -    /* print "pindir:" pindir */
  -    /* get the bubble on the right end */
  -
  -    /* one of the coordinates will match up with the bounding box
  -     * then just choose the other end for the bubble
  -     */
  -
  -    if(x1 == minx)         /* left hand side of pin touches bounding box */
  +  /* Determine the 'whichend' parameter and the coordinates for the "bubble" */
  +  /* if we need to use one.  We need a "bubble" when pinsense=1. */
  +  switch (pindir)
         {    
  -	bx = x2-radius;
  -	by = y2;
  -	x2 -= radius2;
  -      } 
  -    else if (x1 == maxx)   /* left end touches right side */
  +    case 0: /* Pin on top */
  +      if (y1 > y2)
         { 
  -	bx = x2+radius;
  -	by = y2;
  -	x2 += radius2;
  +        whichend = 0;
  +        bx = x2;
  +        by = y2+bradius;
  +        by2 += bdiameter;
         }
  -    else if (x2 == minx)   /* right end touches left side */
  +      else
         {
  -	bx = x1-radius;
  -	by = y1;
  -	x1 -= radius2;
  +        whichend = 1;
  +        bx = x1;
  +        by = y1+bradius;
  +        by1 += bdiameter;
         } 
  -    else if (x2 == maxx)   /* right end touches right side */
  +      break;
  +    case 1: /* Pin on bottom */
  +      if (y1 < y2)
         {
  -	bx = x1+radius;
  -	by = y1;
  -	x1 += radius2;
  +        whichend = 0;
  +        bx = x2;
  +        by = y2-bradius;
  +        by2 -= bdiameter;
         }
  -    else if (y1 == miny)   /* left end touches bottom */
  +      else
         {
  -	bx = x2;
  -	by = y2-radius;
  -	y2 -= radius2;
  +        whichend = 1;
  +        bx = x1;
  +        by = y1-bradius;
  +        by1 -= bdiameter;
         }
  -    else if (y1 == maxy)   /* left end touches top */
  +      break;
  +    case 2: /* Pin on left */
  +      if (x1 < x2)
         {
  -	bx = x2;
  -	by = y2+radius;
  -	y2 += radius2;
  +        whichend = 0;
  +        bx = x2-bradius;
  +        by = y2;
  +        bx2 -= bdiameter;
         }
  -    else if (y2 == miny)   /* right end touches bottom */
  +      else
         {
  -	bx = x1;
  -	by = y1-radius;
  -	y1 -= radius2;
  +        whichend = 1;
  +        bx = x1-bradius;
  +        by = y1;
  +        bx1 -= bdiameter;
         }
  -    else if (y2 == maxy)   /* right end touches top */
  +      break;
  +    case 3: /* Pin on right */
  +      if (x1 > x2)
         {
  -	bx = x1;
  -	by = y1+radius;
  -	y1 += radius2;
  +        whichend = 0;
  +        bx = x2+bradius;
  +        by = y2;
  +        bx2 += bdiameter;
         } 
       else
         {
  -	fprintf(stderr,"Error: Unable to determine pin sense "
  -		"for record #%d in %s()\n"
  -		"\tminx: %d, miny: %d, maxx: %d, maxy: %d\n",
  -		records_processed, __FUNCTION__, minx, miny, maxx, maxy);
  -	return;
  +        whichend = 1;
  +        bx = x1+bradius;
  +        by = y1;
  +        bx1 += bdiameter;
         }
  +      break;
  +    default:
  +      /* Invalid pin direction */
  +      fprintf(stderr,"Error: Invalid pin direction %d in "
  +	      "ViewLogic file at record #%d, in function %s()\n",
  +	      pindir, records_processed, __FUNCTION__);
  +      exit(1);
  +  }
  +
  +  /* if this pin has to be of negative polarity, add a bitty bubble
  +   * and adjust the size of the pin
  +   */
  +  if(pinsense == 1)
  +  {
  +    x1 = bx1;
  +    y1 = by1;
  +    x2 = bx2;
  +    y2 = by2;
  +
  +    linestyle = LINE_DEFAULT;
  +    fillstyle = FILL_DEFAULT;
   
  -    circle_object(bx,by,radius,bcolor);
  +    circle_object(bx,by,bradius,bcolor,&linestyle,&fillstyle);
     }
   
  -  pin_object(x1,y1,x2,y2,color);
  +  /* For now, only normal pins are supported */
  +  pintype = NORMAL_PIN;
  +
  +  pin_object(x1,y1,x2,y2,color,pintype,whichend);
   
   
     add_attributes = 1;   /* add attributes */
  @@ -804,7 +1109,9 @@
   do_box(FILE *fp)
   {
     int x1, y1, x2, y2, width, height;
  -  unsigned int color, fillstyle, linestyle;
  +  unsigned int color;
  +  struct LineStyle linestyle;
  +  struct FillStyle fillstyle;
   
     
     /* if we are inside of a pin definition, terminate */
  @@ -830,9 +1137,11 @@
     height = y2-y1;
     color  = GRAPHIC_COLOR;
   
  -  get_style(fp, &color, &fillstyle, &linestyle);
  +  linestyle = LINE_DEFAULT;
  +  fillstyle = FILL_DEFAULT;
  +  get_style(fp, &color, &linestyle, &fillstyle);
   
  -  box_object(x1,y1,width,height,color);
  +  box_object(x1,y1,width,height,color,&linestyle,&fillstyle);
   }
   
   void
  @@ -840,7 +1149,8 @@
   {
     int x, y;
     unsigned int radius, color;
  -  unsigned int fillstyle, linestyle;
  +  struct LineStyle linestyle;
  +  struct FillStyle fillstyle;
   
     /* if we are inside of a pin definition, terminate */
     reset_attributes();
  @@ -860,20 +1170,24 @@
     radius *=  scale;
     color = GRAPHIC_COLOR;
   
  -  get_style(fp, &color, &fillstyle, &linestyle);
  +  linestyle = LINE_DEFAULT;
  +  fillstyle = FILL_DEFAULT;
  +  get_style(fp, &color, &linestyle, &fillstyle);
   
  -  circle_object(x,y,radius,color);
  +  circle_object(x,y,radius,color,&linestyle,&fillstyle);
   }
   
   void 
   do_arc(FILE *fp)
   {
     int x1, y1, x2, y2, x3, y3;
  -  unsigned int color, fillstyle, linestyle;
  +  unsigned int color;
     double x2p, y2p, x3p, y3p, yop, xop, xo, yo; 
     double to_rad;
     double gstart, sweep_angle, start_angle, end_angle;
     double radius;
  +  struct LineStyle linestyle;
  +  struct FillStyle fillstyle;
   
     /* if we are inside of a pin definition, terminate */
     reset_attributes();
  @@ -899,7 +1213,9 @@
     x3 *= scale;
     y3 *= scale;
     color = GRAPHIC_COLOR;
  -  get_style(fp, &color, &fillstyle, &linestyle);
  +  linestyle = LINE_DEFAULT;
  +  fillstyle = FILL_DEFAULT;
  +  get_style(fp, &color, &linestyle, &fillstyle);
   
     x2p = x2 - x1;
     y2p = y2 - y1;
  @@ -913,8 +1229,8 @@
     if(fabs(x2p * y3p - y2p * x3p) < 0.00001)
       {
         /* some miscreant entered a degenerate arc, just output lines */
  -      line_object(x1,y1,x2,y2,color);
  -      line_object(x2,y2,x3,y3,color);
  +      line_object(x1,y1,x2,y2,color,&linestyle);
  +      line_object(x2,y2,x3,y3,color,&linestyle);
         return;
       }
         
  @@ -952,18 +1268,20 @@
   
     
     arc_object((int)xo,(int)yo, (unsigned int)radius,
  -	     (int)gstart,(int)sweep_angle, color);
  +	     (int)gstart,(int)sweep_angle, color, &linestyle);
   
   }
   
   void 
   do_label(FILE *fp)
   {
  -  int x, y, angle, foo;
  +  int x, y, angle, global, overbar;
     unsigned int color, size, origin, visibility, show_name_value;
  -  unsigned int fillstyle, linestyle;
     char text[MAX_TEXTLEN];
     char text2[MAX_TEXTLEN];
  +  struct LineStyle linestyle;
  +  struct FillStyle fillstyle;
  +  int i, length;
   
     /* labels have the following format:
      *   L #X #Y #SIZE #ROTATION #ORIGIN #GLOBAL #VISIBILITY #OVERBAR TEXT
  @@ -971,8 +1289,8 @@
   
     /* reproduce as simple text, unless it is a label for an object */
   
  -  if(fscanf(fp,"%d %d %u %d %d %d %d %*d", 
  -	    &x, &y, &size, &angle, &origin, &foo, &visibility) != 7)
  +  if(fscanf(fp, "%d %d %u %d %d %d %d %d", &x, &y, &size, &angle, &origin,
  +            &global, &visibility, &overbar) != 8)
       {
         fprintf(stderr,"Error: Invalid label record #%d in %s()\n",
   	      records_processed, __FUNCTION__);
  @@ -986,7 +1304,22 @@
   
     /* read in the text */
     get_continued_string(text2, MAX_TEXTLEN, fp);
  -  get_style(fp, &color, &fillstyle, &linestyle);
  +
  +  /* if ViewDraw showed the label with an overbar, append a '~' to the */
  +  /* beginning of the name.  gEDA does not support overbars, so the '~' lets */
  +  /* the designer know he's dealing with an active low signal */
  +  if (overbar)
  +  {
  +    length = strlen(text2);
  +    text2[length + 1] = 0;
  +    for (i = length; i > 0; i--)
  +      text2[i] = text2[i - 1];
  +    text2[0] = '~';
  +  }
  +
  +  linestyle = LINE_DEFAULT;
  +  fillstyle = FILL_DEFAULT;
  +  get_style(fp, &color, &linestyle, &fillstyle);
   
     /* if we are inside a pin definition, mangle the pin name */
     if(net_attributes == 1) /* a netname on a net is its netname */
  @@ -1111,6 +1444,7 @@
   do_net_segment_bus(FILE *fp)
   {
     unsigned int n1, n2, color;
  +  int ripperdir;
   
     reset_attributes();
   
  @@ -1127,9 +1461,12 @@
   
     color = BUS_COLOR;
   
  +  /* For now, we'll use ripperdir=0 (no nets connected to bus yet) */
  +  ripperdir = 0;
  +
     /* output a geda bus segment */
     bus_segment(net_nodes_x[n1], net_nodes_y[n1], 
  -	      net_nodes_x[n2], net_nodes_y[n2], color);
  +	      net_nodes_x[n2], net_nodes_y[n2], color, ripperdir);
   
     /* there could be attributes to follow */
     add_attributes = 1;   /* add attributes */
  @@ -1140,10 +1477,12 @@
   void 
   do_instance(FILE *fp)
   {
  +  char text[MAX_TEXTLEN];
     char lib[MAX_TEXTLEN], name[MAX_TEXTLEN], symName[MAX_TEXTLEN];
     unsigned int extension, selectable;
     int x, y, angle, orientation, mirror;
     float scale_factor;
  +  int result, index, i;
   
     reset_attributes();
   
  @@ -1151,14 +1490,30 @@
      *  I #instance LIB:NAME #PAGE #X #Y #ROTATION #MAGNIFICATION '
      */
   
  +  text[0] = 0;
     lib[0] = 0;
     name[0] = 0;
     extension = 9999;
     x = 0;
     y = 0;
   
  -  if(fscanf(fp,"%*d %[a-zA-Z0-9]:%[a-zA-Z0-9] %u %d %d %d %g %*s\n",
  -	    lib, name, &extension, &x, &y, &orientation, &scale_factor) < 5)
  +  /* Instance doesn't necessarily have to have the LIB:NAME convention, so */
  +  /* read this in as a full string and parse later */
  +  /* if(fscanf(fp,"%*d %[a-zA-Z0-9]:%[a-zA-Z0-9] %u %d %d %d %g %*s\n", */
  +  result = fscanf(fp,"%*d %s %u %d %d %d %g %*s\n",
  +                  text, &extension, &x, &y, &orientation, &scale_factor);
  +  /* find library and symbol name */
  +  index = strindex(text, ':');
  +  if (index > 0 || text[0] == ':')
  +  {
  +    text[index] = 0;
  +    strcpy(lib, text);
  +    strcpy(name, &text[index+1]);
  +  }
  +  else
  +    strcpy(name, text);
  +  /* Check for input errors */
  +  if (result < 6)
       {
         fprintf(stderr,"Error: Invalid instance record #%d in %s()\n"
   	      "lib:'%s', name:'%s'\n"
  @@ -1169,13 +1524,21 @@
         
     x *= scale;
     y *= scale;
  +
  +  /* ViewDraw components are always selectable */
     selectable = 1;
   
  +  /* Correct orientation */
     set_orientation(&angle, &mirror, orientation);
         
     /* fix case */
     strtolower(name);
   
  +  /* replace dashes in the name with underscores */
  +  for (i = strlen(name) - 1; i >= 0; i--)
  +    if (name[i] == '-')
  +      name[i] = '_';
  +
     /* produce proper file name: */
   #ifdef HAVE_SNPRINTF
     snprintf(symName, MAX_TEXTLEN, "%s-%d.sym",name,extension);
  @@ -1192,7 +1555,8 @@
   
   }
   
  -/* Viewlogic mirror over y-axis, but gschem mirror over x-axis. */
  +/* ViewDraw mirrors components over the x-axis, but gSchem mirrors over the */
  +/* y-axis. */
   /* This makes (270, 1) viewlogic -> (90, 1) gschem */
   /*        and (90, 1)  viewlogic -> (270, 1) gschem */ 
   /*        and (180, 1)  viewlogic -> (0, 1) gschem */ 
  @@ -1248,6 +1612,7 @@
   {
     unsigned int text_size;
     unsigned int textlen;
  +  unsigned int numlines;
   
     /* fudge the text size, in viewdraw it is actually the height
      * in geda it is the point size.  The Variable text_size contains
  @@ -1256,6 +1621,24 @@
      */
     text_size = (int)(size * 0.72);
   
  +  /* Translate ViewDraw text origin to gEDA
  +   *  ViewDraw's text origin is specified like this:
  +   * 1 4 7
  +   * 2 5 8
  +   * 3 6 9
  +   * where 1 is the top left corner of the text and 9 is the bottom right,
  +   * etc.
  +   * gEDA's text origin is specified like this:
  +   * 2 5 8
  +   * 1 4 7
  +   * 0 3 6
  +   * so, the below conversion is necessary
  +   */
  +  origin = (((origin - 1) / 3) * 6) + 3 - origin;
  +
  +  /* No longer necessary to emulate ViewDraw text origin, it is now supported */
  +  /* by gEDA */
  +#if 0
     /* emulate the viewdraw text origin by shifting the text around */
     
     /* if the origin is one of the ones that are along the center line,
  @@ -1308,7 +1691,22 @@
       {
         x -= textlen;
       }
  +#endif
   
  +  /* Translate ViewDraw text rotation to gEDA text angle
  +   *  ViewDraw's text rotation is specified like this:
  +   * 0 = 0 degrees, no rotation
  +   * 1 = 90 degrees
  +   * 2 = 180 degrees
  +   * 3 = 270 degrees
  +   * gEDA's text angle is specified in degrees, so the below conversion is
  +   * necessary
  +   */
  +  angle *= 90;
  +
  +  /* gEDA now supports rotated text, so we no longer need to force angle to */
  +  /* be 0 */
  +#if 0
     /* currently angled/rotated text is not supported, print a
      * warning, and force the orientation
      */
  @@ -1319,7 +1717,11 @@
   	      "at record #%d\n",
   	      text,records_processed);
       }
  +#endif
   
  +  /* Since x and y are automatically multiplied by 10 (the scale factor), */
  +  /* the below operation is not necessary */
  +#if 0
     /* force text to start on a 10 unit boundary */
     if((x % 10) < 5)
       x = x - (x % 10);
  @@ -1330,20 +1732,14 @@
       y = y - (y % 10);
     else
       y = y + (10 - (x % 10));
  +#endif
       
  +  /* Only one line of text per statement allowed in ViewDraw, so this is */
  +  /* always 1 */
  +  numlines = 1;
   
  -  /* XXX Fix GEDA!, text size limited to 79 chars! */
  -  if(strlen(text) >= 79)
  -    {
  -      fprintf(stderr,"Warning: Text '%s' truncated to 79 chars at "
  -	      "record #%d!! FIXME! in %s()\n",
  -	      text, records_processed, __FUNCTION__);
  -      text[79]=0;
  -    }
  -
  -
  -  printf( "T %d %d %u %u %u %u %d\n%s\n", x, y, color, text_size, 
  -	  visibility, show_name_value, angle, text);
  +  printf( "T %d %d %u %u %u %u %d %u %u\n%s\n", x, y, color, text_size, 
  +	  visibility, show_name_value, angle, origin, numlines, text);
   
   }
   
  @@ -1354,12 +1750,20 @@
   		 int angle, char *name, char *value, unsigned int origin) 
   {
   
  -  char text[MAX_TEXTLEN], tmpName[MAX_TEXTLEN];
  -  unsigned int i, done;
  +  char text[MAX_TEXTLEN], text2[MAX_TEXTLEN];
  +  char tmpName[MAX_TEXTLEN], tmpValue[MAX_TEXTLEN];
  +  unsigned int i, j, done, length;
   
     /* make a copy of the attribute to work with */
     strncpy(tmpName, name, MAX_TEXTLEN-1);
     tmpName[MAX_TEXTLEN-1] = 0;   /* terminate in case strncpy doesnt */
  +  if (value == NULL)
  +    tmpValue[0] = 0;   /* no value with ViewDraw attribute */
  +  else
  +  {
  +    strncpy(tmpValue, value, MAX_TEXTLEN-1);
  +    tmpValue[MAX_TEXTLEN-1] = 0;   /* terminate in case strncpy doesnt */
  +  }
     
     /* look up attribute name in translation attribute list
      * and translate or print approprate message 
  @@ -1384,7 +1788,7 @@
   	  case KILL:
   	    fprintf(stderr,"Warning: Killing attribute `%s=%s' at (%d,%d)"
   		    " from record #%d\n",
  -		    tmpName, value,x,y,records_processed);
  +		    tmpName, tmpValue,x,y,records_processed);
   	    done = 1;
   	    return;
   
  @@ -1392,22 +1796,83 @@
   	    fprintf(stderr,"Warning: attribute name `%s=%s' at (%d,%d) "
   		    "at record #%d, found during conversion\n"
   		    "\tpassing it through unchanged\n",
  -		    tmpName,value,x,y,records_processed);
  +		    tmpName,tmpValue,x,y,records_processed);
   	    done = 1;
   	    break;
   	  default:
   	    fprintf(stderr,"Error: Unknown action code for attribute\n"
   		    "`%s=%s' at record #%d in %s()\n",
  -		    tmpName,value,records_processed,__FUNCTION__);
  +		    tmpName,tmpValue,records_processed,__FUNCTION__);
   	    exit(1);
   	  }
       }	  
   
  +  /* if attribute name was not replaced/dropped, convert to lowercase */
  +  /* and pass on */
  +  if (!done)
  +    strtolower(tmpName);
  +
  +  /* If we are changing a ViewDraw SIGNAL attribute to a net attribute, */
  +  /* replace the ';' delimiter with a ':' */
  +  if (strcmp(tmpName, "net") == 0)
  +    tmpValue[strindex(tmpValue, ';')] = ':';
  +
  +  /* If we are changing a ViewDraw HETERO attribute to a split attribute, */
  +  /* format the new value correctly */
  +  if (strcmp(tmpName, "split") == 0)
  +  {
  +    strcpy(text2, tmpValue);
  +    strtolower(text2);
  +    j = 0;
  +    length = strlen(text2);
  +    for (i = 0; i < length; i++)
  +    {
  +      /* Drop parentheses */
  +      if (text2[i] != '(' && text2[i] != ')')
  +      {
  +        /* Convert dashes to underscores */
  +        if (text2[i] == '-')
  +          tmpValue[j++] = '_';
  +        /* insert gEDA symbol file extension before comma */
  +        else if (text2[i] == ',')
  +        {
  +#ifdef HAVE_SNPRINTF
  +          snprintf(&tmpValue[j], MAX_TEXTLEN, "-1.sch,");
  +#else
  +          sprintf(&tmpValue[j], "-1.sch,");
  +#endif
  +          j += 7;
  +        }
  +        else
  +          tmpValue[j++] = text2[i];
  +      }
  +    }
  +    /* append gEDA symbol file extension to the end */
  +#ifdef HAVE_SNPRINTF
  +    snprintf(&tmpValue[j], MAX_TEXTLEN, "-1.sch");
  +#else
  +    sprintf(&tmpValue[j], "-1.sch");
  +#endif
  +  }
  +
  +  /* If we have an NC attribute with no value, convert to netname=NC */
  +  if (strcmp(tmpName, "nc") == 0 && tmpValue[0] == 0)
  +  {
  +#ifdef HAVE_SNPRINTF
  +    snprintf(tmpName, MAX_TEXTLEN, "netname");
  +    snprintf(tmpValue, MAX_TEXTLEN, "NC");
  +#else
  +    snprintf(tmpName, "netname");
  +    sprintf(tmpValue, "NC");
  +#endif
  +    show_name_value = 1;
  +  }
  +
     /* just add an = into the middle */
   #ifdef HAVE_SNPRINTF
  -  snprintf(text, MAX_TEXTLEN, "%s=%s", tmpName, value);
  +  snprintf(text, MAX_TEXTLEN, "%s=%s", tmpName, tmpValue);
   #else  
  -  sprintf(text, "%s=%s", tmpName, value);
  +  sprintf(text, "%s=%s", tmpName, tmpValue);
   #endif
   
     text_object( x, y, color, size, visibility, show_name_value, \
  @@ -1417,36 +1882,62 @@
   
   
   void
  -line_object(int x1, int y1, int x2, int y2, unsigned int color)
  +line_object(int x1, int y1, int x2, int y2, unsigned int color,
  +            struct LineStyle *linestyle)
   {
  -  printf( "L %d %d %d %d %u\n",x1,y1,x2,y2,color);
  +  printf("L %d %d %d %d %u %i %i %i %i %i\n", x1, y1, x2, y2, color,
  +         linestyle->line_width, linestyle->line_capstyle,
  +         linestyle->line_dashstyle,linestyle->line_dashlength,
  +         linestyle->line_dashspace);
   }
   
   void
  -circle_object(int bx, int by, unsigned int radius, unsigned int bcolor)
  +circle_object(int bx, int by, unsigned int radius, unsigned int bcolor,
  +              struct LineStyle *linestyle, struct FillStyle *fillstyle)
   {  
  -  printf("V %d %d %u %u\n",bx,by,radius,bcolor);
  +  printf("V %d %d %u %u %i %i %i %i %i %i %i %i %i %i %i\n",
  +         bx, by, radius, bcolor,
  +         linestyle->line_width, linestyle->line_capstyle,
  +         linestyle->line_dashstyle,linestyle->line_dashlength,
  +         linestyle->line_dashspace,
  +         fillstyle->fill_type, fillstyle->fill_width,
  +         fillstyle->fill_angle1, fillstyle->fill_pitch1,
  +         fillstyle->fill_angle2, fillstyle->fill_pitch2);
   }
   
   void
  -pin_object(int x1, int y1, int x2, int y2, unsigned int color)
  +pin_object(int x1, int y1, int x2, int y2, unsigned int color,
  +           OBJECT_PINTYPE pintype, unsigned int whichend)
   {
  -    printf("P %d %d %d %d %u\n",x1,y1,x2,y2,color);
  +    printf("P %d %d %d %d %u %u %u\n", x1, y1, x2, y2, color,
  +           pintype, whichend);
   }
   
   void
   box_object(int x1, int y1, unsigned int width, unsigned int height,
  -	   unsigned int color)
  +	   unsigned int color, struct LineStyle *linestyle,
  +           struct FillStyle *fillstyle)
   {
  -  printf("B %d %d %u %u %u\n",x1,y1,width,height,color);
  +  printf("B %d %d %u %u %u %i %i %i %i %i %i %i %i %i %i %i\n", x1, y1,
  +         width, height, color,
  +         linestyle->line_width, linestyle->line_capstyle,
  +         linestyle->line_dashstyle,linestyle->line_dashlength,
  +         linestyle->line_dashspace,
  +         fillstyle->fill_type, fillstyle->fill_width,
  +         fillstyle->fill_angle1, fillstyle->fill_pitch1,
  +         fillstyle->fill_angle2, fillstyle->fill_pitch2);
   }
   
   void
   arc_object(int x1, int y1, unsigned int radius, 
  -	   int start_angle, int sweep_angle, unsigned int color)
  +	   int start_angle, int sweep_angle, unsigned int color,
  +           struct LineStyle *linestyle)
   {
  -  printf("A %d %d %u %d %d %u\n",x1, y1, radius, 
  -	 start_angle, sweep_angle, color);
  +  printf("A %d %d %u %d %d %u %i %i %i %i %i\n", x1, y1, radius, 
  +	 start_angle, sweep_angle, color,
  +         linestyle->line_width, linestyle->line_capstyle,
  +         linestyle->line_dashstyle, linestyle->line_dashlength,
  +         linestyle->line_dashspace);
   }
   
   void
  @@ -1456,9 +1947,9 @@
   }
   
   void
  -bus_segment(int x1, int y1, int x2, int y2, unsigned int color )
  +bus_segment(int x1, int y1, int x2, int y2, unsigned int color, int ripperdir)
   {
  -  printf("U %d %d %d %d %u\n", x1, y1, x2, y2, color);
  +  printf("U %d %d %d %d %u %i\n", x1, y1, x2, y2, color, ripperdir);
   }
   
   void
  @@ -1523,9 +2014,9 @@
     /* read in the text */
     fgets(buf, buffer_size, fp);
     records_processed++;
  -  /* nuke trailing CR, if there */
  +  /* nuke trailing CR/NL, if there */
     text_len=strlen(buf);
  -  if(buf[text_len-1] == '\n')
  +  while (buf[text_len-1] == '\n' || buf[text_len-1] == '\r')
       {
         buf[text_len-1] = 0;
         text_len--;
  @@ -1538,7 +2029,8 @@
         fgets(&buf[text_len], MAX_TEXTLEN-text_len,fp);  /* read in next chunk */
         records_processed++;
         text_len=strlen(buf);                 /* update text length */
  -      if(buf[text_len-1] == '\n')           /* nuke any trailing CR's */
  +      /* nuke trailing CR/NL, if there */
  +      while (buf[text_len-1] == '\n' || buf[text_len-1] == '\r')
   	{
   	  buf[text_len-1] = 0;
   	  text_len--;
  @@ -1555,15 +2047,16 @@
   
   /* read in a possible style record to modify the current style */
   int get_style(FILE *fp, unsigned int *colour, 
  -	      unsigned int *fillstyle,
  -	      unsigned int *linestyle)
  +	      struct LineStyle *linestyle,
  +	      struct FillStyle *fillstyle)
   {
     int c;
  +  unsigned int vdfillstyle, vdlinestyle;
   
     c = getc(fp);
     if(c == 'Q') /* do we have a modifier? */
       {
  -      if(fscanf(fp,"%u %u %u\n", colour, fillstyle, linestyle) != 3)
  +      if(fscanf(fp,"%u %u %u\n", colour, &vdfillstyle, &vdlinestyle) != 3)
   	{
   	  fprintf(stderr,"Error: Invalid modifier record #%d in %s()\n",
   		  records_processed, __FUNCTION__);
  @@ -1579,6 +2072,27 @@
   	  exit(1);
   	}
         *colour = colormap[*colour]; 
  +
  +      /* re-map vdfillstyle to gEDA FillStyle */
  +      if (vdfillstyle > 25)
  +      {
  +        fprintf(stderr,"Warning: Invalid fill style %u in record #%d, "
  +                "in %s().  Assuming \"Hollow\" fill style.\n",
  +                vdfillstyle,records_processed, __FUNCTION__);
  +        vdfillstyle = 0;
  +      }
  +      memcpy(fillstyle, &fillmap[vdfillstyle], sizeof(struct FillStyle));
  +
  +      /* re-map vdlinestyle to gEDA LineStyle */
  +      if (vdlinestyle > 7)
  +      {
  +        fprintf(stderr,"Warning: Invalid line style %u in record #%d, "
  +                "in %s().  Assuming \"Solid\" line style.\n",
  +                vdlinestyle,records_processed, __FUNCTION__);
  +        vdlinestyle = 0;
  +      }
  +      memcpy(linestyle, &linemap[vdlinestyle], sizeof(struct LineStyle));
  +
         records_processed++;
       }
     else