dxf.c

Go to the documentation of this file.
00001 
00250 #ifdef HAVE_CONFIG_H
00251 #include "config.h"
00252 #endif
00253 
00254 #include <stdio.h>
00255 #include <stdarg.h>
00256 #include <stdlib.h>
00257 #include <string.h>
00258 #include <time.h>
00259 
00260 #include "global.h"
00261 #include "data.h"
00262 #include "error.h"
00263 #include "misc.h"
00264 
00265 #include "hid.h"
00266 #include "../hidint.h"
00267 
00268 #ifdef HAVE_LIBDMALLOC
00269 #include <dmalloc.h>
00270 #endif
00271 
00275 RCSID ("$Id$");
00276 
00280 #define CRASH fprintf(stderr, "HID error: pcb called unimplemented DXF function %s.\n", __FUNCTION__); abort()
00281 
00285 #define DXF_X(pcb, x) ((long) ((x) / 100))
00286 
00290 #define DXF_Y(pcb, y) ((long) (((pcb)->MaxHeight - (y))) / 100)
00291 
00295 #define DXF_XOffset(pcb, x) ((long) ((x) / 100))
00296 
00300 #define DXF_YOffset(pcb, y) ((long) (-(y) / 100))
00301 
00302 #define DXF_ROUND(x) ((int)(((x) + 50) / 100) * 100)
00303 
00307 #define DEBUG 1
00308 
00313 #define DXF_COLOR_BYBLOCK 0
00314 
00318 #define DXF_COLOR_RED 1
00319 
00323 #define DXF_COLOR_YELLOW 2
00324 
00328 #define DXF_COLOR_GREEN 3
00329 
00333 #define DXF_COLOR_CYAN 4
00334 
00338 #define DXF_COLOR_BLUE 5
00339 
00343 #define DXF_COLOR_MAGENTA 6
00344 
00348 #define DXF_COLOR_WHITE 7
00349 
00353 #define DXF_COLOR_GREY 8
00354 
00359 #define DXF_COLOR_BYLAYER 256
00360 
00365 #define DXF_MODELSPACE 0
00366 
00372 #define DXF_PAPERSPACE 1
00373 
00378 #define DXF_DEFAULT_LAYER "0"
00379 
00384 #define DXF_DEFAULT_LINETYPE "BYLAYER"
00385 
00390 #define DXF_DEFAULT_TEXTSTYLE "STANDARD"
00391 
00398 #define DXF_DEFAULT_XREF_PATH_NAME "parts"
00399 
00409 #define DXF_DIR_SEPARATOR "\\"
00410 
00418 #define DXF_DEFAULT_HATCH_PATTERN_NAME "SOLID"
00419 
00420 /*
00421  * forward declaration.
00422  */
00423 static HID dxf_hid;
00424 
00428 enum ApertureShape
00429 {
00430         ROUND, 
00431         OCTAGON, 
00432         SQUARE,  
00433         ROUNDCLEAR, 
00434         SQUARECLEAR, 
00435         THERMAL 
00436 };
00437 
00441 typedef enum ApertureShape ApertureShape;
00442 
00446 typedef struct Aperture
00447 {
00448         int dCode; 
00449         int apertureSize; 
00450         ApertureShape apertureShape; 
00452 } Aperture;
00453 
00457 typedef struct
00458 {
00459         DynamicStringType appList; 
00460         int lastdCode; 
00461         int lastTherm; 
00462         int nextAperture; 
00463         Aperture aperture[GBX_MAXAPERTURECOUNT]; 
00464 } Apertures;
00465 
00469 typedef struct
00470 {
00471         int diam; 
00472         int x; 
00473         int y; 
00474 } DxfPendingDrills;
00475 
00479 static int is_mask;
00480 
00484 static int current_mask;
00485 
00489 static int is_drill;
00490 
00491 static int was_drill;
00492 
00493 static Apertures *layerapps = 0;
00494 
00495 static Apertures *curapp;
00496 
00497 static int n_layerapps = 0;
00498 
00499 static int c_layerapps = 0;
00500 
00504 DxfPendingDrills *dxf_pending_drills = 0;
00505 
00509 int dxf_n_pending_drills = 0;
00510 
00514 int dxf_max_pending_drills = 0;
00515 
00523 static int
00524 dxf_find_aperture_code
00525 (
00526         int width, 
00527         ApertureShape shape 
00528 )
00529 {
00530         int i;
00531         Aperture *ap;
00532         char appMacro[256];
00533         /*
00534          * we never draw zero-width lines.
00535          */
00536         if (width == 0)
00537         {
00538                 return (0);
00539         }
00540         /*
00541          * search for an appropriate aperture.
00542          */
00543         for (i = 0; i < curapp->nextAperture; i++)
00544         {
00545                 ap = &(curapp->aperture[i]);
00546                 if (ap->apertureSize == width && ap->apertureShape == shape)
00547                 {
00548                         return (ap->dCode);
00549                 }
00550         }
00551         appMacro[0] = '\0';
00552         /*
00553          * aperture not found, create a new aperture and add it to the list.
00554          */
00555         if (curapp->nextAperture < GBX_MAXAPERTURECOUNT)
00556         {
00557                 i = curapp->nextAperture++;
00558                 ap = &(curapp->aperture[i]);
00559                 ap->dCode = curapp->lastdCode++;
00560                 ap->apertureSize = width;
00561                 ap->apertureShape = shape;
00562                 switch (shape)
00563                 {
00564                         case ROUND:
00565                                 sprintf
00566                                 (
00567                                         appMacro,
00568                                         "ROUND aperture here",
00569                                         ap->dCode,
00570                                         width / 100000.0
00571                                 );
00572                                 break;
00573                         case SQUARE:
00574                                 sprintf
00575                                 (
00576                                         appMacro,
00577                                         "SQUARE aperure here",
00578                                         ap->dCode,
00579                                         width / 100000.0,
00580                                         width / 100000.0
00581                                 );
00582                                 break;
00583                         case OCTAGON:
00584                                 sprintf
00585                                 (
00586                                         appMacro,
00587                                         "OCTAGON aperture here",
00588                                         curapp->lastTherm,
00589                                         width / (100000.0 * COS_22_5_DEGREE),
00590                                         ap->dCode,
00591                                         curapp->lastTherm
00592                                 );
00593                                 curapp->lastTherm++;
00594                                 break;
00595 #if 0
00596                         case THERMAL:
00597                                 sprintf
00598                                 (
00599                                         appMacro,
00600                                         "THERMAL aperture here",
00601                                         lastTherm,
00602                                         gap / 100000.0,
00603                                         width / 100000.0,
00604                                         finger / 100000.0,
00605                                         ap->dCode,
00606                                         lastTherm
00607                                  );
00608                                 lastTherm++;
00609                                 break;
00610                         case ROUNDCLEAR:
00611                                 sprintf
00612                                 (
00613                                         appMacro,
00614                                         "ROUNDCLEAR aperture here",
00615                                         ap->dCode,
00616                                         gap / 100000.0,
00617                                         width / 100000.0
00618                                 );
00619                                 break;
00620                         case SQUARECLEAR:
00621                                 sprintf
00622                                 (
00623                                         appMacro,
00624                                         "SQUARECLEAR aperture here",
00625                                         ap->dCode,
00626                                         gap / 100000.0,
00627                                         gap / 100000.0,
00628                                         width / 100000.0,
00629                                         width / 100000.0
00630                                 );
00631                                 break;
00632 #else
00633 #endif
00634                         default:
00635                                 break;
00636                 }
00637                 DSAddString (&(curapp->appList), appMacro);
00638                 return (ap->dCode);
00639         }
00640         else
00641         {
00642                 Message (_("Error, too many apertures needed for Gerber file.\n"));
00643                 return (10);
00644         }
00645 }
00646 
00647 static void
00648 dxf_init_apertures ()
00649 {
00650         layerapps = 0;
00651         n_layerapps = 0;
00652 }
00653 
00654 static void
00655 dxf_set_app_layer
00656 (
00657         int l
00658 )
00659 {
00660         if (l >= n_layerapps)
00661         {
00662                 int prev = n_layerapps;
00663                 n_layerapps = l + 1;
00664                 layerapps = MyRealloc (layerapps, n_layerapps * sizeof (Apertures), "dxf_set_app_layer");
00665                 curapp = layerapps + prev;
00666                 while (curapp < layerapps + n_layerapps)
00667                 {
00668                         curapp->appList.Data = NULL;
00669                         curapp->appList.MaxLength = 0;
00670                         curapp->lastdCode = 11;
00671                         curapp->lastTherm = 1;
00672                         curapp->nextAperture = 0;
00673                         curapp++;
00674                 }
00675         }
00676         curapp = layerapps + l;
00677 }
00678 
00695 typedef struct hid_gc_struct
00696 {
00697         EndCapStyle cap; 
00698         int width; 
00699         int color; 
00700         int erase; 
00701         int drill; 
00702 } hid_gc_struct;
00703 
00707 static HID_Attribute dxf_options[] =
00708 {
00709   {"dxffile", "DXF layer filename base", HID_String, 0, 0, {0, 0, 0}, 0, 0},
00710 #define HA_dxffile 0
00711   {"metric", "export DXF files in mm", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0},
00712 #define HA_metric 1
00713   {"layer color BYBLOCK", "export entities in color BYBLOCK", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0},
00714 #define HA_color_byblock 2
00715   {"xrefs", "export a DXF file with xrefs", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0},
00716 #define HA_xrefs 3
00717   {"xreffile", "DXF Xrefs filename", HID_String, 0, 0, {0, 0, 0}, 0, 0},
00718 #define HA_xreffile 4
00719   {"verbose", "verbose output (comments)", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0},
00720 #define HA_verbose 5
00721 };
00722 
00723 #define NUM_OPTIONS (sizeof(dxf_options)/sizeof(dxf_options[0]))
00724 
00733 static HID_Attr_Val dxf_values[NUM_OPTIONS];
00734 
00738 typedef struct _StringList
00739 {
00740         char *str; 
00741         struct _StringList *next; 
00742 } StringList;
00743 
00747 typedef struct _DxfList
00748 {
00749         char *descr; 
00750         char *value; 
00751         int num; 
00752         StringList *refdes; 
00754         struct _DxfList *next; 
00756 } DxfList;
00757 
00761 static FILE *f = 0;
00762 
00766 static char *dxf_filename;
00767 
00771 static char *dxf_header_filename;
00772 
00776 static char *dxf_filesuffix;
00777 
00781 static char *dxf_layername = 0;
00782 
00786 static int lncount = 0;
00787 
00791 static int dxf_xrefs;
00792 
00796 static char *dxf_xref_filename;
00797 
00801 static int dxf_metric;
00802 
00806 static int dxf_color_is_byblock;
00807 
00811 static int dxf_verbose;
00812 
00816 static int dxf_id_code = 0;
00817 
00818 static int finding_apertures = 0;
00819 
00820 static int pagecount = 0;
00821 
00822 static int linewidth = -1;
00823 
00824 static int lastgroup = -1;
00825 
00826 static int lastcap = -1;
00827 
00828 static int lastcolor = -1;
00829 
00830 static int print_group[MAX_LAYER];
00831 
00832 static int print_layer[MAX_LAYER];
00833 
00837 static int dxf_lastX;
00838 
00842 static int dxf_lastY;
00843 
00847 static int
00848 dxf_group_for_layer
00849 (
00850         int l
00851 )
00852 {
00853         if ((l < max_layer + 2) && (l >= 0))
00854         {
00855                 return GetLayerGroupNumberByNumber (l);
00856         }
00857               /*
00858                * something unique.
00859          */
00860         return max_layer + 3 + l;
00861 }
00862 
00866 static int
00867 dxf_layer_sort
00868 (
00869         const void *va,
00870         const void *vb
00871 )
00872 {
00873         int a = *(int *) va;
00874         int b = *(int *) vb;
00875         int d = dxf_group_for_layer (b) - dxf_group_for_layer (a);
00876         if (d) return d;
00877         return b - a;
00878 }
00879 
00883 static double
00884 dxf_xy_to_angle
00885 (
00886         double x,
00887         double y
00888 )
00889 {
00890 #if DEBUG
00891         fprintf (stderr, "[File: %s: line: %d] Entering dxf_xy_to_angle () function.\n", __FILE__, __LINE__);
00892 #endif
00893         double theta;
00894         if ((x > 0.0) && (y >= 0.0)) theta = 180.0;
00895         else if ((x <= 0.0) && (y > 0.0)) theta = 90.0;
00896         else if ((x < 0.0) && (y <= 0.0)) theta = 0.0;
00897         else if ((x >= 0.0) && (y < 0.0)) theta = 270.0;
00898         else
00899         {
00900                 theta = 0.0;
00901                 Message ("Warning in dxf.c|dxf_xy_to_angle ():\n"
00902                          "     unable to figure out angle of element\n"
00903                          "     because the pin is at the centroid of the part.\n"
00904                          "     This is a BUG!!!\n"
00905                          "     Setting to %g degrees\n", theta);
00906         }
00907 #if DEBUG
00908         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_xy_to_angle () function.\n", __FILE__, __LINE__);
00909 #endif
00910         return (theta);
00911 }
00912 
00919 static char *
00920 dxf_clean_string
00921 (
00922         char *in
00923 )
00924 {
00925 #if DEBUG
00926         fprintf (stderr, "[File: %s: line: %d] Entering dxf_clean_string () function.\n", __FILE__, __LINE__);
00927 #endif
00928         char *out;
00929         int i;
00930         if ((out = malloc ((strlen (in) + 1) * sizeof (char))) == NULL)
00931         {
00932                 fprintf (stderr, "Error in dxf.c|dxf_clean_string(): malloc() failed.\n");
00933                 exit (1);
00934         }
00935         for (i = 0; i <= strlen (in); i++)
00936         {
00937                 switch (in[i])
00938                 {
00939                         case '"':
00940                                 out[i] = '\'';
00941                                 break;
00942                         default:
00943                                 out[i] = in[i];
00944                 }
00945         }
00946 #if DEBUG
00947         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_clean_string () function.\n", __FILE__, __LINE__);
00948 #endif
00949         return (out);
00950 }
00951 
00955 static StringList *
00956 dxf_string_insert
00957 (
00958         char *str,
00959         StringList * list
00960 )
00961 {
00962 #if DEBUG
00963         fprintf (stderr, "[File: %s: line: %d] Entering dxf_string_insert () function.\n", __FILE__, __LINE__);
00964 #endif
00965         StringList *new;
00966         StringList *cur;
00967         if ((new = (StringList *) malloc (sizeof (StringList))) == NULL)
00968         {
00969                 fprintf (stderr, "Error in dxf.c|dxf_string_insert(): malloc() failed.\n");
00970                 exit (1);
00971         }
00972         new->next = NULL;
00973         new->str = strdup (str);
00974         if (list == NULL)
00975         {
00976                 return (new);
00977         }
00978         cur = list;
00979         while (cur->next != NULL) cur = cur->next;
00980         cur->next = new;
00981 #if DEBUG
00982         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_string_insert () function.\n", __FILE__, __LINE__);
00983 #endif
00984         return (list);
00985 }
00986 
01036 static void
01037 dxf_write_block
01038 (
01039         FILE *fp, 
01040         int id_code, 
01041         char *xref_name, 
01042         char *block_name, 
01043         char *linetype, 
01045         char *layer, 
01046         double x0, 
01047         double y0, 
01048         double z0, 
01049         double thickness, 
01051         int color, 
01053         int paperspace, 
01055         int block_type 
01067 )
01068 {
01069 #if DEBUG
01070         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_block () function.\n", __FILE__, __LINE__);
01071         fprintf (stderr, "[DXF entity with code %x]\n", id_code);
01072 #endif
01073         char *dxf_entity_name = strdup ("BLOCK");
01074         if (block_name == "")
01075         {
01076                 fprintf (stderr, "Warning: empty block name string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
01077                 fprintf (stderr, "         %s entity is discarded from output.\n", dxf_entity_name);
01078                 return;
01079         }
01080         if (xref_name == "")
01081         {
01082                 fprintf (stderr, "Warning: empty xref name string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
01083                 fprintf (stderr, "         %s entity is discarded from output.\n", dxf_entity_name);
01084                 return;
01085         }
01086         if (strcmp (layer, "") == 0)
01087         {
01088                 fprintf (stderr, "Warning: empty layer string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
01089                 fprintf (stderr, "    %s entity is relocated to layer 0.\n", dxf_entity_name);
01090                 layer = strdup (DXF_DEFAULT_LAYER);
01091         }
01092         fprintf (fp, "  0\n%s\n", dxf_entity_name);
01093         if (id_code != -1) fprintf (fp, "  5\n%x\n", id_code);
01094         /* group code 102 stuff goes here  */
01095         fprintf (fp, "100\nAcDbEntity\n"); /* subclass marker (AcDbEntity) */
01096         fprintf (fp, "  8\n%s\n", layer);
01097         fprintf (fp, "100\nAcDbBlockBegin\n"); /* subclass marker (AcDbBlockBegin) */
01098         fprintf (fp, "  2\n%s\n", block_name);
01099         fprintf (fp, " 70\n%d\n", block_type);
01100         fprintf (fp, " 10\n%f\n", x0);
01101         fprintf (fp, " 20\n%f\n", y0);
01102         fprintf (fp, " 30\n%f\n", z0);
01103         fprintf (fp, "  3\n%s\n", block_name);
01104         if ((block_type && 4) || (block_type && 32)) fprintf (fp, "  1\n%s%s%s.dwg\n", xref_name, DXF_DIR_SEPARATOR, block_name);
01105 //        if (strcmp (linetype, DXF_DEFAULT_LINETYPE) != 0) fprintf (fp, "  6\n%s\n", linetype);
01106 //        if (thickness != 0.0) fprintf (fp, " 39\n%f\n", thickness);
01107 //        if (color != DXF_COLOR_BYLAYER) fprintf (fp, " 62\n%d\n", color);
01108         if (paperspace == DXF_PAPERSPACE) fprintf (fp, " 67\n%d\n", DXF_PAPERSPACE);
01109         fprintf (fp, "  0\nENDBLK\n");
01110         if (id_code != -1) fprintf (fp, "  5\n%x\n", id_code);
01111         /* group code 102 stuff goes here */
01112         fprintf (fp, "100\nAcDbBlockEnd\n"); /* subclass marker (AcDbBlockEnd) */
01113 #if DEBUG
01114         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_block () function.\n", __FILE__, __LINE__);
01115 #endif
01116 }
01117 
01129 static void
01130 dxf_write_table_block_record
01131 (
01132         FILE *fp 
01133 )
01134 {
01135 #if DEBUG
01136         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_table_block_record () function.\n", __FILE__, __LINE__);
01137 #endif
01138 
01139 #if DEBUG
01140         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_table_block_record () function.\n", __FILE__, __LINE__);
01141 #endif
01142 }
01143 
01153 static void
01154 dxf_write_circle
01155 (
01156         FILE *fp, 
01157         int id_code, 
01158         char *linetype, 
01159         char *layer, 
01160         double x0, 
01161         double y0, 
01162         double z0, 
01163         double extr_x0, 
01165         double extr_y0, 
01167         double extr_z0, 
01169         double thickness, 
01170         double radius, 
01171         int color, 
01172         int paperspace 
01174 )
01175 {
01176 #if DEBUG
01177         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_circle () function.\n", __FILE__, __LINE__);
01178         fprintf (stderr, "[DXF entity with code %x]\n", id_code);
01179 #endif
01180         char *dxf_entity_name = strdup ("CIRCLE");
01181         if (radius == 0.0)
01182         {
01183                 fprintf (stderr, "Error: radius value equals 0.0 for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
01184                 return;
01185         }
01186         if (strcmp (layer, "") == 0)
01187         {
01188                 fprintf (stderr, "Warning: empty layer string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
01189                 fprintf (stderr, "    %s entity is relocated to layer 0", dxf_entity_name);
01190                 layer = strdup (DXF_DEFAULT_LAYER);
01191         }
01192         fprintf (fp, "  0\n%s\n", dxf_entity_name);
01193         fprintf (fp, "100\nAcDbCircle\n"); /* subclass marker (AcDbCircle) */
01194         if (id_code != -1) fprintf (fp, "  5\n%x\n", id_code);
01195         if (strcmp (linetype, DXF_DEFAULT_LINETYPE) != 0) fprintf (fp, "  6\n%s\n", linetype);
01196         fprintf (fp, "  8\n%s\n", layer);
01197         fprintf (fp, " 10\n%f\n", x0);
01198         fprintf (fp, " 20\n%f\n", y0);
01199         fprintf (fp, " 30\n%f\n", z0);
01200         fprintf (fp, " 210\n%f\n", extr_x0);
01201         fprintf (fp, " 220\n%f\n", extr_y0);
01202         fprintf (fp, " 230\n%f\n", extr_z0);
01203         if (thickness != 0.0) fprintf (fp, " 39\n%f\n", thickness);
01204         fprintf (fp, " 40\n%f\n", radius);
01205         if (color != DXF_COLOR_BYLAYER) fprintf (fp, " 62\n%d\n", color);
01206         if (paperspace == DXF_PAPERSPACE) fprintf (fp, " 67\n%d\n", DXF_PAPERSPACE);
01207 #if DEBUG
01208         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_circle () function.\n", __FILE__, __LINE__);
01209 #endif
01210         return;
01211 }
01212 
01224 static void
01225 dxf_write_comment
01226 (
01227         FILE *fp, 
01228         char *comment_string) 
01229 {
01230 #if DEBUG
01231         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_comment () function.\n", __FILE__, __LINE__);
01232 #endif
01233         /*
01234          * no use in writing an empty comment string to file.
01235          */
01236         if (comment_string == "")
01237         {
01238                 return;
01239         }
01240         fprintf (fp, "999\n%s\n", comment_string);
01241 #if DEBUG
01242         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_comment () function.\n", __FILE__, __LINE__);
01243 #endif
01244 }
01245 
01260 static void
01261 dxf_write_ellipse
01262 (
01263         FILE *fp, 
01264         int id_code, 
01265         char *linetype, 
01266         char *layer, 
01267         double x0, 
01268         double y0, 
01269         double z0, 
01270         double x1, 
01272         double y1, 
01274         double z1, 
01276         double extr_x0, 
01278         double extr_y0, 
01280         double extr_z0, 
01282         double thickness, 
01283         double ratio, 
01285         double start_angle, 
01287         double end_angle, 
01289         int color, 
01290         int paperspace 
01292 )
01293 {
01294 #if DEBUG
01295         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_ellipse () function.\n", __FILE__, __LINE__);
01296 #endif
01297         char *dxf_entity_name = strdup ("ELLIPSE");
01298         if (ratio == 0.0)
01299         {
01300                 fprintf (stderr, "Error: ratio value equals 0.0 for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
01301                 return;
01302         }
01303         if (strcmp (layer, "") == 0)
01304         {
01305                 fprintf (stderr, "Warning: empty layer string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
01306                 fprintf (stderr, "    %s entity is relocated to layer 0", dxf_entity_name);
01307                 layer = strdup (DXF_DEFAULT_LAYER);
01308         }
01309         fprintf (fp, "  0\n%s\n", dxf_entity_name);
01310         fprintf (fp, "100\nAcDbEllipse\n"); /* subclass marker (AcDbEllipse) */
01311         if (id_code != -1) fprintf (fp, "  5\n%x\n", id_code);
01312         if (strcmp (linetype, DXF_DEFAULT_LINETYPE) != 0) fprintf (fp, "  6\n%s\n", linetype);
01313         fprintf (fp, "  8\n%s\n", layer);
01314         fprintf (fp, " 10\n%f\n", x0);
01315         fprintf (fp, " 20\n%f\n", y0);
01316         fprintf (fp, " 30\n%f\n", z0);
01317         fprintf (fp, " 11\n%f\n", x1);
01318         fprintf (fp, " 21\n%f\n", y1);
01319         fprintf (fp, " 31\n%f\n", z1);
01320         fprintf (fp, " 210\n%f\n", extr_x0);
01321         fprintf (fp, " 220\n%f\n", extr_y0);
01322         fprintf (fp, " 230\n%f\n", extr_z0);
01323         if (thickness != 0.0) fprintf (fp, " 39\n%f\n", thickness);
01324         fprintf (fp, " 40\n%f\n", ratio);
01325         fprintf (fp, " 41\n%f\n", start_angle);
01326         fprintf (fp, " 42\n%f\n", end_angle);
01327         if (color != DXF_COLOR_BYLAYER) fprintf (fp, " 62\n%d\n", color);
01328         if (paperspace == DXF_PAPERSPACE) fprintf (fp, " 67\n%d\n", DXF_PAPERSPACE);
01329 #if DEBUG
01330         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_ellipse () function.\n", __FILE__, __LINE__);
01331 #endif
01332         return;
01333 }
01334 
01338 static void
01339 dxf_write_endsection
01340 (
01341         FILE *fp 
01342 )
01343 {
01344 #if DEBUG
01345         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_endsection () function.\n", __FILE__, __LINE__);
01346 #endif
01347         fprintf (fp, "  0\nENDSEC\n");
01348 #if DEBUG
01349         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_endsection () function.\n", __FILE__, __LINE__);
01350 #endif
01351 }
01352 
01365 static void
01366 dxf_write_endseq
01367 (
01368         FILE *fp 
01369 )
01370 {
01371 #if DEBUG
01372         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_endseq () function.\n", __FILE__, __LINE__);
01373 #endif
01374         fprintf (fp, "  0\nENDSEQ\n");
01375 #if DEBUG
01376         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_endseq () function.\n", __FILE__, __LINE__);
01377 #endif
01378 }
01379 
01380 
01384 static void
01385 dxf_write_eof
01386 (
01387         FILE *fp 
01388 )
01389 {
01390 #if DEBUG
01391         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_eof () function.\n", __FILE__, __LINE__);
01392 #endif
01393         fprintf (fp, "  0\nEOF\n");
01394 #if DEBUG
01395         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_eof () function.\n", __FILE__, __LINE__);
01396 #endif
01397 }
01398 
01407 static void
01408 dxf_write_hatch
01409 (
01410         FILE *fp, 
01411         char *pattern_name, 
01412         int id_code, 
01413         char *linetype, 
01414         char *layer, 
01415         double x0, 
01416         double y0, 
01417         double z0, 
01418         double extr_x0, 
01420         double extr_y0, 
01422         double extr_z0, 
01424         double thickness, 
01425         double pattern_scale, 
01426         double pixel_size, 
01427         double pattern_angle, 
01428         int color, 
01429         int paperspace, 
01431         int solid_fill, 
01434         int associative, 
01437         int style, 
01441         int pattern_style, 
01445         int pattern_double, 
01449         int pattern_def_lines, 
01451         int boundary_paths, 
01453         int seed_points, 
01454                 double *seed_x0, 
01455                 double *seed_y0 
01456 )
01457 {
01458 #if DEBUG
01459         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_hatch () function.\n", __FILE__, __LINE__);
01460         fprintf (stderr, "[DXF entity with code %x]\n", id_code);
01461 #endif
01462         char *dxf_entity_name = strdup ("HATCH");
01463         int i;
01464         if (strcmp (layer, "") == 0)
01465         {
01466                 fprintf (stderr, "Warning: empty layer string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
01467                 fprintf (stderr, "    %s entity is relocated to layer 0", dxf_entity_name);
01468                 layer = strdup (DXF_DEFAULT_LAYER);
01469         }
01470         fprintf (fp, "  0\n%s\n", dxf_entity_name);
01471         fprintf (fp, "100\nAcDbHatch\n");/* subclass marker (AcDbHatch) */
01472         fprintf (fp, "  2\n%s\n", pattern_name);
01473         if (id_code != -1) fprintf (fp, "  5\n%x\n", id_code);
01474         if (strcmp (linetype, DXF_DEFAULT_LINETYPE) != 0) fprintf (fp, "  6\n%s\n", linetype);
01475         fprintf (fp, "  8\n%s\n", layer);
01476         fprintf (fp, " 10\n%f\n", x0);
01477         fprintf (fp, " 20\n%f\n", y0);
01478         fprintf (fp, " 30\n%f\n", z0);
01479         fprintf (fp, "210\n%f\n", extr_x0);
01480         fprintf (fp, "220\n%f\n", extr_y0);
01481         fprintf (fp, "230\n%f\n", extr_z0);
01482         if (thickness != 0.0) fprintf (fp, " 39\n%f\n", thickness);
01483         if (!solid_fill) fprintf (fp, " 42\n%f\n", pattern_scale);
01484         fprintf (fp, " 47\n%f\n", pixel_size);
01485         if (!solid_fill) fprintf (fp, " 52\n%f\n", pattern_angle);
01486         if (color != DXF_COLOR_BYLAYER) fprintf (fp, " 62\n%d\n", color);
01487         if (paperspace == DXF_PAPERSPACE) fprintf (fp, " 67\n%d\n", DXF_PAPERSPACE);
01488         fprintf (fp, " 70\n%d\n", solid_fill);
01489         fprintf (fp, " 71\n%d\n", associative);
01490         fprintf (fp, " 75\n%d\n", style);
01491         if (!solid_fill) fprintf (fp, " 77\n%d\n", pattern_double);
01492         fprintf (fp, " 78\n%d\n", pattern_def_lines);
01493         fprintf (fp, " 98\n%d\n", seed_points);
01494         for (i = 0; i < seed_points; i++)
01495         {
01496                 fprintf (fp, " 10\n%f\n", seed_x0[i]);
01497                 fprintf (fp, " 20\n%f\n", seed_y0[i]);
01498         }
01499         fprintf (fp, " 91\n%d\n", boundary_paths);
01500 #if DEBUG
01501         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_hatch () function.\n", __FILE__, __LINE__);
01502 #endif
01503         return;
01504 }
01505 
01511 static void
01512 dxf_write_hatch_boundary_path_polyline
01513 (
01514         FILE *fp, 
01515         int type_flag, 
01516         int polyline_has_bulge, 
01518         int polyline_is_closed, 
01520         int polyline_vertices 
01522 )
01523 {
01524 #if DEBUG
01525         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_hatch_boundary_path_polyline () function.\n", __FILE__, __LINE__);
01526 #endif
01527         fprintf (fp, " 92\n%d\n", type_flag);
01528         fprintf (fp, " 72\n%d\n", polyline_has_bulge);
01529         fprintf (fp, " 73\n%d\n", polyline_is_closed);
01530         fprintf (fp, " 93\n%d\n", polyline_vertices);
01531 #if DEBUG
01532         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_hatch_boundary_path_polyline () function.\n", __FILE__, __LINE__);
01533 #endif
01534         return;
01535 }
01536 
01542 static void
01543 dxf_write_hatch_boundary_path_polyline_vertex
01544 (
01545         FILE *fp, 
01546         double x0, 
01547         double y0, 
01548         double bulge 
01549 )
01550 {
01551 #if DEBUG
01552         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_hatch_boundary_polyline_vertex () function.\n", __FILE__, __LINE__);
01553 #endif
01554         fprintf (fp, " 10\n%f\n", x0);
01555         fprintf (fp, " 20\n%f\n", y0);
01556         if (bulge != 0.0) fprintf (fp, " 42\n%f\n", bulge);
01557 #if DEBUG
01558         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_hatch_boundary_polyline_vertex () function.\n", __FILE__, __LINE__);
01559 #endif
01560         return;
01561 }
01562 
01586 static void
01587 dxf_write_header_imperial_new
01588 (
01589         FILE *fp 
01590 )
01591 {
01592 #if DEBUG
01593         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_header_imperial_new () function.\n", __FILE__, __LINE__);
01594 #endif
01595         /*
01596          * write an imperial HEADER section.
01597          */
01598         fprintf (fp, "  0\nSECTION\n");
01599         fprintf (fp, "  2\nHEADER\n");
01600         fprintf (fp, "  9\n$ACADVER\n  1\nAC1014\n");
01601         fprintf (fp, "  9\n$ACADMAINTVER\n 70\n     0\n");
01602         fprintf (fp, "  9\n$DWGCODEPAGE\n  3\nANSI_1252\n");
01603         fprintf (fp, "  9\n$INSBASE\n 10\n0.0\n 20\n0.0\n 30\n0.0\n");
01604         /*
01605          * more lines to be added.
01606          */
01607 
01608 #if DEBUG
01609         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_header_imperial_new () function.\n", __FILE__, __LINE__);
01610 #endif
01611 }
01612 
01636 static void
01637 dxf_write_header_metric_new
01638 (
01639         FILE *fp 
01640 )
01641 {
01642 #if DEBUG
01643         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_header_metric_new () function.\n", __FILE__, __LINE__);
01644 #endif
01645         /*
01646          * write a metric HEADER section.
01647          */
01648         fprintf (fp, "  0\nSECTION\n");
01649         fprintf (fp, "  2\nHEADER\n");
01650         fprintf (fp, "  9\n$ACADVER\n  1\nAC1014\n");
01651         fprintf (fp, "  9\n$ACADMAINTVER\n 70\n     0\n");
01652         fprintf (fp, "  9\n$DWGCODEPAGE\n  3\nANSI_1252\n");
01653         fprintf (fp, "  9\n$INSBASE\n 10\n0.0\n 20\n0.0\n 30\n0.0\n");
01654         fprintf (fp, "  9\n$EXTMIN\n 10\n-0.012816\n 20\n-0.009063\n 30\n-0.001526\n");
01655         fprintf (fp, "  9\n$EXTMAX\n 10\n88.01056\n 20\n35.022217\n 30\n0.0\n");
01656         fprintf (fp, "  9\n$LIMMIN\n 10\n0.0\n 20\n0.0\n");
01657         fprintf (fp, "  9\n$LIMMAX\n 10\n420.0\n 20\n297.0\n");
01658         fprintf (fp, "  9\n$ORTHOMODE\n 70\n     0\n");
01659         fprintf (fp, "  9\n$REGENMODE\n 70\n     1\n");
01660         fprintf (fp, "  9\n$FILLMODE\n 70\n     1\n");
01661         fprintf (fp, "  9\n$QTEXTMODE\n 70\n     0\n");
01662         fprintf (fp, "  9\n$MIRRTEXT\n 70\n     1\n");
01663         fprintf (fp, "  9\n$DRAGMODE\n 70\n     2\n");
01664         fprintf (fp, "  9\n$LTSCALE\n 40\n1.0\n");
01665         fprintf (fp, "  9\n$OSMODE\n 70\n   125\n");
01666         fprintf (fp, "  9\n$ATTMODE\n 70\n     1\n");
01667         fprintf (fp, "  9\n$TEXTSIZE\n 40\n2.5\n");
01668         fprintf (fp, "  9\n$TRACEWID\n 40\n1.0\n");
01669         fprintf (fp, "  9\n$TEXTSTYLE\n  7\nSTANDARD\n");
01670         fprintf (fp, "  9\n$CLAYER\n  8\n0\n");
01671         fprintf (fp, "  9\n$CELTYPE\n  6\nBYLAYER\n");
01672         fprintf (fp, "  9\n$CECOLOR\n 62\n   256\n");
01673         fprintf (fp, "  9\n$CELTSCALE\n 40\n1.0\n");
01674         fprintf (fp, "  9\n$DELOBJ\n 70\n     1\n");
01675         fprintf (fp, "  9\n$DISPSILH\n 70\n     0\n");
01676         fprintf (fp, "  9\n$DIMSCALE\n 40\n1.0\n");
01677         fprintf (fp, "  9\n$DIMASZ\n 40\n2.5\n");
01678         fprintf (fp, "  9\n$DIMEXO\n 40\n0.625\n");
01679         fprintf (fp, "  9\n$DIMDLI\n 40\n3.75\n");
01680         fprintf (fp, "  9\n$DIMRND\n 40\n0.0\n");
01681         fprintf (fp, "  9\n$DIMDLE\n 40\n0.0\n");
01682         fprintf (fp, "  9\n$DIMEXE\n 40\n1.25\n");
01683         fprintf (fp, "  9\n$DIMTP\n 40\n0.0\n");
01684         fprintf (fp, "  9\n$DIMTM\n 40\n0.0\n");
01685         fprintf (fp, "  9\n$DIMTXT\n 40\n2.5\n");
01686         fprintf (fp, "  9\n$DIMCEN\n 40\n2.5\n");
01687         fprintf (fp, "  9\n$DIMTSZ\n 40\n0.0\n");
01688         fprintf (fp, "  9\n$DIMTOL\n 70\n     0\n");
01689         fprintf (fp, "  9\n$DIMLIM\n 70\n     0\n");
01690         fprintf (fp, "  9\n$DIMTIH\n 70\n     0\n");
01691         fprintf (fp, "  9\n$DIMTOH\n 70\n     0\n");
01692         fprintf (fp, "  9\n$DIMSE1\n 70\n     0\n");
01693         fprintf (fp, "  9\n$DIMSE2\n 70\n     0\n");
01694         fprintf (fp, "  9\n$DIMTAD\n 70\n     1\n");
01695         fprintf (fp, "  9\n$DIMZIN\n 70\n     8\n");
01696         fprintf (fp, "  9\n$DIMBLK\n  1\n\n");
01697         fprintf (fp, "  9\n$DIMASO\n 70\n     1\n");
01698         fprintf (fp, "  9\n$DIMSHO\n 70\n     1\n");
01699         fprintf (fp, "  9\n$DIMPOST\n  1\n\n");
01700         fprintf (fp, "  9\n$DIMAPOST\n  1\n\n");
01701         fprintf (fp, "  9\n$DIMALT\n 70\n     0\n");
01702         fprintf (fp, "  9\n$DIMALTD\n 70\n     4\n");
01703         fprintf (fp, "  9\n$DIMALTF\n 40\n0.0394\n");
01704         fprintf (fp, "  9\n$DIMLFAC\n 40\n1.0\n");
01705         fprintf (fp, "  9\n$DIMTOFL\n 70\n     1\n");
01706         fprintf (fp, "  9\n$DIMTVP\n 40\n0.0\n");
01707         fprintf (fp, "  9\n$DIMTIX\n 70\n     0\n");
01708         fprintf (fp, "  9\n$DIMSOXD\n 70\n     0\n");
01709         fprintf (fp, "  9\n$DIMSAH\n 70\n     0\n");
01710         fprintf (fp, "  9\n$DIMBLK1\n  1\n\n");
01711         fprintf (fp, "  9\n$DIMBLK2\n  1\n\n");
01712         fprintf (fp, "  9\n$DIMSTYLE\n  2\nSTANDARD\n");
01713         fprintf (fp, "  9\n$DIMCLRD\n 70\n     0\n");
01714         fprintf (fp, "  9\n$DIMCLRE\n 70\n     0\n");
01715         fprintf (fp, "  9\n$DIMCLRT\n 70\n     0\n");
01716         fprintf (fp, "  9\n$DIMTFAC\n 40\n1.0\n");
01717         fprintf (fp, "  9\n$DIMGAP\n 40\n0.625\n");
01718         fprintf (fp, "  9\n$DIMJUST\n 70\n     0\n");
01719         fprintf (fp, "  9\n$DIMSD1\n 70\n     0\n");
01720         fprintf (fp, "  9\n$DIMSD2\n 70\n     0\n");
01721         fprintf (fp, "  9\n$DIMTOLJ\n 70\n     1\n");
01722         fprintf (fp, "  9\n$DIMTZIN\n 70\n     0\n");
01723         fprintf (fp, "  9\n$DIMALTZ\n 70\n     0\n");
01724         fprintf (fp, "  9\n$DIMALTTZ\n 70\n     0\n");
01725         fprintf (fp, "  9\n$DIMFIT\n 70\n     3\n");
01726         fprintf (fp, "  9\n$DIMUPT\n 70\n     0\n");
01727         fprintf (fp, "  9\n$DIMUNIT\n 70\n     2\n");
01728         fprintf (fp, "  9\n$DIMDEC\n 70\n     4\n");
01729         fprintf (fp, "  9\n$DIMTDEC\n 70\n     4\n");
01730         fprintf (fp, "  9\n$DIMALTU\n 70\n     2\n");
01731         fprintf (fp, "  9\n$DIMALTTD\n 70\n     2\n");
01732         fprintf (fp, "  9\n$DIMTXSTY\n  7\nSTANDARD\n");
01733         fprintf (fp, "  9\n$DIMAUNIT\n 70\n     0\n");
01734         fprintf (fp, "  9\n$LUNITS\n 70\n     2\n");
01735         fprintf (fp, "  9\n$LUPREC\n 70\n     4\n");
01736         fprintf (fp, "  9\n$SKETCHINC\n 40\n1.0\n");
01737         fprintf (fp, "  9\n$FILLETRAD\n 40\n1.0\n");
01738         fprintf (fp, "  9\n$AUNITS\n 70\n     0\n");
01739         fprintf (fp, "  9\n$AUPREC\n 70\n     0\n");
01740         fprintf (fp, "  9\n$MENU\n  1\n.\n");
01741         fprintf (fp, "  9\n$ELEVATION\n 40\n0.0\n");
01742         fprintf (fp, "  9\n$PELEVATION\n 40\n0.0\n");
01743         fprintf (fp, "  9\n$THICKNESS\n 40\n0.0\n");
01744         fprintf (fp, "  9\n$LIMCHECK\n 70\n     0\n");
01745         fprintf (fp, "  9\n$BLIPMODE\n 70\n     0\n");
01746         fprintf (fp, "  9\n$CHAMFERA\n 40\n10.0\n");
01747         fprintf (fp, "  9\n$CHAMFERB\n 40\n10.0\n");
01748         fprintf (fp, "  9\n$CHAMFERC\n 40\n0.0\n");
01749         fprintf (fp, "  9\n$CHAMFERD\n 40\n0.0\n");
01750         fprintf (fp, "  9\n$SKPOLY\n 70\n     0\n");
01751         fprintf (fp, "  9\n$TDCREATE\n 40\n2452949.844398842\n");
01752         fprintf (fp, "  9\n$TDUPDATE\n 40\n2453105.563639282\n");
01753         fprintf (fp, "  9\n$TDINDWG\n 40\n0.0994079282\n");
01754         fprintf (fp, "  9\n$TDUSRTIMER\n 40\n0.0994079282\n");
01755         fprintf (fp, "  9\n$USRTIMER\n 70\n     1\n");
01756         fprintf (fp, "  9\n$ANGBASE\n 50\n0.0\n");
01757         fprintf (fp, "  9\n$ANGDIR\n 70\n     0\n");
01758         fprintf (fp, "  9\n$PDMODE\n 70\n    98\n");
01759         fprintf (fp, "  9\n$PDSIZE\n 40\n0.0\n");
01760         fprintf (fp, "  9\n$PLINEWID\n 40\n0.0\n");
01761         fprintf (fp, "  9\n$COORDS\n 70\n     2\n");
01762         fprintf (fp, "  9\n$SPLFRAME\n 70\n     0\n");
01763         fprintf (fp, "  9\n$SPLINETYPE\n 70\n     6\n");
01764         fprintf (fp, "  9\n$SPLINESEGS\n 70\n     8\n");
01765         fprintf (fp, "  9\n$ATTDIA\n 70\n     0\n");
01766         fprintf (fp, "  9\n$ATTREQ\n 70\n     1\n");
01767         fprintf (fp, "  9\n$HANDLING\n 70\n     1\n");
01768         fprintf (fp, "  9\n$HANDSEED\n  5\n262\n");
01769         fprintf (fp, "  9\n$SURFTAB1\n 70\n     6\n");
01770         fprintf (fp, "  9\n$SURFTAB2\n 70\n     6\n");
01771         fprintf (fp, "  9\n$SURFTYPE\n 70\n     6\n");
01772         fprintf (fp, "  9\n$SURFU\n 70\n     6\n");
01773         fprintf (fp, "  9\n$SURFV\n 70\n     6\n");
01774         fprintf (fp, "  9\n$UCSNAME\n  2\n\n");
01775         fprintf (fp, "  9\n$UCSORG\n 10\n0.0\n 20\n0.0\n 30\n0.0\n");
01776         fprintf (fp, "  9\n$UCSXDIR\n 10\n1.0\n 20\n0.0\n 30\n0.0\n");
01777         fprintf (fp, "  9\n$UCSYDIR\n 10\n0.0\n 20\n1.0\n 30\n0.0\n");
01778         fprintf (fp, "  9\n$PUCSNAME\n  2\n\n");
01779         fprintf (fp, "  9\n$PUCSORG\n 10\n0.0\n 20\n0.0\n 30\n0.0\n");
01780         fprintf (fp, "  9\n$PUCSXDIR\n 10\n1.0\n 20\n0.0\n 30\n0.0\n");
01781         fprintf (fp, "  9\n$PUCSYDIR\n 10\n0.0\n 20\n1.0\n 30\n0.0\n");
01782         fprintf (fp, "  9\n$USERI1\n 70\n     0\n");
01783         fprintf (fp, "  9\n$USERI2\n 70\n     0\n");
01784         fprintf (fp, "  9\n$USERI3\n 70\n     0\n");
01785         fprintf (fp, "  9\n$USERI4\n 70\n     0\n");
01786         fprintf (fp, "  9\n$USERI5\n 70\n     0\n");
01787         fprintf (fp, "  9\n$USERR1\n 40\n0.0\n");
01788         fprintf (fp, "  9\n$USERR2\n 40\n0.0\n");
01789         fprintf (fp, "  9\n$USERR3\n 40\n0.0\n");
01790         fprintf (fp, "  9\n$USERR4\n 40\n0.0\n");
01791         fprintf (fp, "  9\n$USERR5\n 40\n0.0\n");
01792         fprintf (fp, "  9\n$WORLDVIEW\n 70\n     1\n");
01793         fprintf (fp, "  9\n$SHADEDGE\n 70\n     3\n");
01794         fprintf (fp, "  9\n$SHADEDIF\n 70\n    70\n");
01795         fprintf (fp, "  9\n$TILEMODE\n 70\n     1\n");
01796         fprintf (fp, "  9\n$MAXACTVP\n 70\n    48\n");
01797         fprintf (fp, "  9\n$PINSBASE\n 10\n0.0\n 20\n0.0\n 30\n0.0\n");
01798         fprintf (fp, "  9\n$PLIMCHECK\n 70\n     0\n");
01799         fprintf (fp, "  9\n$PEXTMIN\n 10\n1.000000E+20\n 20\n1.000000E+20\n 30\n1.000000E+20\n");
01800         fprintf (fp, "  9\n$PEXTMAX\n 10\n-1.000000E+20\n 20\n-1.000000E+20\n 30\n-1.000000E+20\n");
01801         fprintf (fp, "  9\n$PLIMMIN\n 10\n0.0\n 20\n0.0\n");
01802         fprintf (fp, "  9\n$PLIMMAX\n 10\n420.0\n 20\n297.0");
01803         fprintf (fp, "  9\n$UNITMODE\n 70\n     0\n");
01804         fprintf (fp, "  9\n$VISRETAIN\n 70\n     1\n");
01805         fprintf (fp, "  9\n$PLINEGEN\n 70\n     0\n");
01806         fprintf (fp, "  9\n$PSLTSCALE\n 70\n     1\n");
01807         fprintf (fp, "  9\n$TREEDEPTH\n 70\n  3020\n");
01808         fprintf (fp, "  9\n$PICKSTYLE\n 70\n     1\n");
01809         fprintf (fp, "  9\n$CMLSTYLE\n  2\nSTANDARD\n");
01810         fprintf (fp, "  9\n$CMLJUST\n 70\n     0\n");
01811         fprintf (fp, "  9\n$CMLSCALE\n 40\n1.0\n");
01812         fprintf (fp, "  9\n$PROXYGRAPHICS\n 70\n     1\n");
01813         fprintf (fp, "  9\n$MEASUREMENT\n 70\n     0\n");
01814         fprintf (fp, "  0\nENDSEC\n");
01815         /*
01816          * write a CLASSES section.
01817          */
01818         fprintf (fp, "  0\nSECTION\n");
01819         fprintf (fp, "  2\nCLASSES\n");
01820         fprintf (fp, "  0\nENDSEC\n");
01821         /*
01822          * write a TABLES section.
01823          */
01824         fprintf (fp, "  0\nSECTION\n");
01825         fprintf (fp, "  2\nTABLES\n");
01826         /*
01827          * write a VPORT (viewport) table entry
01828          */
01829         fprintf (fp, "  0\nTABLE\n");
01830         fprintf (fp, "  2\nVPORT\n");
01831         fprintf (fp, "  5\n23A\n");
01832         fprintf (fp, "100\nAcDbSymbolTable\n");
01833         fprintf (fp, " 70\n     2\n");
01834         fprintf (fp, "  0\nVPORT\n");
01835         fprintf (fp, "  5\n261\n");
01836         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
01837         fprintf (fp, "100\nAcDbViewportTableRecord\n");
01838         fprintf (fp, "  2\n*ACTIVE\n");
01839         fprintf (fp, " 70\n     0\n");
01840         fprintf (fp, " 10\n0.0\n 20\n0.0\n");
01841         fprintf (fp, " 11\n1.0\n 21\n1.0\n");
01842         fprintf (fp, " 12\n43.998872\n 22\n17.506577\n");
01843         fprintf (fp, " 13\n0.0\n 23\n0.0\n");
01844         fprintf (fp, " 14\n1.0\n 24\n1.0\n");
01845         fprintf (fp, " 15\n10.0\n 25\n10.0\n");
01846         fprintf (fp, " 16\n0.0\n 26\n0.0\n 36\n1.0\n");
01847         fprintf (fp, " 17\n0.0\n 27\n0.0\n 37\n0.0\n");
01848         fprintf (fp, " 40\n47.164502\n");
01849         fprintf (fp, " 41\n1.882514\n");
01850         fprintf (fp, " 42\n50.0\n");
01851         fprintf (fp, " 43\n0.0\n");
01852         fprintf (fp, " 44\n0.0\n");
01853         fprintf (fp, " 50\n0.0\n");
01854         fprintf (fp, " 51\n0.0\n");
01855         fprintf (fp, " 71\n     0\n");
01856         fprintf (fp, " 72\n   100\n");
01857         fprintf (fp, " 73\n     1\n");
01858         fprintf (fp, " 74\n     3\n");
01859         fprintf (fp, " 75\n     0\n");
01860         fprintf (fp, " 76\n     0\n");
01861         fprintf (fp, " 77\n     0\n");
01862         fprintf (fp, " 78\n     0\n");
01863         fprintf (fp, "  0\nENDTAB\n");
01864         /*
01865          * write LTYPE (linetype) table entries.
01866          */
01867         fprintf (fp, "  0\nTABLE\n");
01868         fprintf (fp, "  2\nLTYPE\n");
01869         fprintf (fp, "  5\n237\n");
01870         fprintf (fp, "100\nAcDbSymbolTable\n");
01871         fprintf (fp, " 70\n     1\n");
01872         fprintf (fp, "  0\nLTYPE\n");
01873         fprintf (fp, "  5\n244\n");
01874         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
01875         /*
01876          * write a record entry for a BYBLOCK linetype.
01877          */
01878         fprintf (fp, "100\nAcDbLinetypeTableRecord\n");
01879         fprintf (fp, "  2\nBYBLOCK\n");
01880         fprintf (fp, " 70\n     0\n");
01881         fprintf (fp, "  3\n\n");
01882         fprintf (fp, " 72\n    65\n");
01883         fprintf (fp, " 73\n     0\n");
01884         fprintf (fp, " 40\n0.0\n");
01885         fprintf (fp, "  0\nLTYPE\n");
01886         fprintf (fp, "  5\n245\n");
01887         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
01888         /*
01889          * write a record entry for a BYLAYER linetype.
01890          */
01891         fprintf (fp, "100\nAcDbLinetypeTableRecord\n");
01892         fprintf (fp, "  2\nBYLAYER\n");
01893         fprintf (fp, " 70\n     0\n");
01894         fprintf (fp, "  3\n\n");
01895         fprintf (fp, " 72\n    65\n");
01896         fprintf (fp, " 73\n     0\n");
01897         fprintf (fp, " 40\n0.0\n");
01898         fprintf (fp, "  0\nLTYPE\n");
01899         fprintf (fp, "  5\n246\n");
01900         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
01901         /*
01902          * write a record entry for a CONTINUOUS linetype.
01903          */
01904         fprintf (fp, "100\nAcDbLinetypeTableRecord\n");
01905         fprintf (fp, "  2\nCONTINUOUS\n");
01906         fprintf (fp, " 70\n     0\n");
01907         fprintf (fp, "  3\nSolid line\n");
01908         fprintf (fp, " 72\n    65\n");
01909         fprintf (fp, " 73\n     0\n");
01910         fprintf (fp, " 40\n0.0\n");
01911         fprintf (fp, "  0\nENDTAB\n");
01912         /*
01913          * write LAYER table entries.
01914          */
01915         fprintf (fp, "  0\nTABLE\n");
01916         fprintf (fp, "  2\nLAYER\n");
01917         fprintf (fp, "  5\n234\n");
01918         fprintf (fp, "100\nAcDbSymbolTable\n");
01919         fprintf (fp, " 70\n     2\n");
01920         fprintf (fp, "  0\nLAYER\n");
01921         fprintf (fp, "  5\n240\n");
01922         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
01923         /*
01924          * write a record entry for layer "0".
01925          */
01926         fprintf (fp, "100\nAcDbLayerTableRecord\n");
01927         fprintf (fp, "  2\n0\n");
01928         fprintf (fp, " 70\n     0\n");
01929         fprintf (fp, " 62\n     7\n");
01930         fprintf (fp, "  6\nCONTINUOUS\n");
01931         fprintf (fp, "  0\nLAYER\n");
01932         fprintf (fp, "  5\n251\n");
01933         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
01934         /*
01935          * write a record entry for a layer "ASHADE".
01936          */
01937         fprintf (fp, "100\nAcDbLayerTableRecord\n");
01938         fprintf (fp, "  2\nASHADE\n");
01939         fprintf (fp, " 70\n     4\n");
01940         fprintf (fp, " 62\n     7\n");
01941         fprintf (fp, "  6\nCONTINUOUS\n");
01942         fprintf (fp, "  0\nENDTAB\n");
01943         /*
01944          * write STYLE table entries.
01945          */
01946         fprintf (fp, "  0\nTABLE\n");
01947         fprintf (fp, "  2\nSTYLE\n");
01948         fprintf (fp, "  5\n235\n");
01949         fprintf (fp, "100\nAcDbSymbolTable\n");
01950         fprintf (fp, " 70\n     2\n");
01951         fprintf (fp, "  0\nSTYLE\n");
01952         fprintf (fp, "  5\n241\n");
01953         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
01954         /*
01955          * write a record entry for a style "STANDARD".
01956          */
01957         fprintf (fp, "100\nAcDbTextStyleTableRecord\n");
01958         fprintf (fp, "  2\nSTANDARD\n");
01959         fprintf (fp, " 70\n     0\n");
01960         fprintf (fp, " 40\n0.0\n");
01961         fprintf (fp, " 41\n1.0\n");
01962         fprintf (fp, " 50\n0.0\n");
01963         fprintf (fp, " 71\n     0\n");
01964         fprintf (fp, " 42\n2.5\n");
01965         fprintf (fp, "  3\ntxt\n");
01966         fprintf (fp, "  4\n\n");
01967         fprintf (fp, "  0\nSTYLE\n");
01968         fprintf (fp, "  5\n252\n");
01969         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
01970         /*
01971          * write a record entry for a style "ASHADE".
01972          */
01973         fprintf (fp, "100\nAcDbTextStyleTableRecord\n");
01974         fprintf (fp, "  2\nASHADE\n");
01975         fprintf (fp, " 70\n     0\n");
01976         fprintf (fp, " 40\n0.2\n");
01977         fprintf (fp, " 41\n1.0\n");
01978         fprintf (fp, " 50\n0.0\n");
01979         fprintf (fp, " 71\n     0\n");
01980         fprintf (fp, " 42\n2.5\n");
01981         fprintf (fp, "  3\nsimplex.shx\n");
01982         fprintf (fp, "  4\n\n");
01983         fprintf (fp, "  0\nENDTAB\n");
01984         /*
01985          * write a VIEW table entry.
01986          */
01987         fprintf (fp, "  0\nTABLE\n");
01988         fprintf (fp, "  2\nVIEW\n");
01989         fprintf (fp, "  5\n238\n");
01990         fprintf (fp, "100\nAcDbSymbolTable\n");
01991         fprintf (fp, " 70\n     0\n");
01992         fprintf (fp, "  0\nENDTAB\n");
01993         /*
01994          * write a UCS (User Coordinate System) table entry.
01995          */
01996         fprintf (fp, "  0\nTABLE\n");
01997         fprintf (fp, "  2\nUCS\n");
01998         fprintf (fp, "  5\n239\n");
01999         fprintf (fp, "100\nAcDbSymbolTable\n");
02000         fprintf (fp, " 70\n     0\n");
02001         fprintf (fp, "  0\nENDTAB\n");
02002         /*
02003          * write a APPID (APPlication ID) table entry.
02004          */
02005         fprintf (fp, "  0\nTABLE\n");
02006         fprintf (fp, "  2\nAPPID\n");
02007         fprintf (fp, "  5\n23B\n");
02008         fprintf (fp, "100\nAcDbSymbolTable\n");
02009         fprintf (fp, " 70\n     6\n");
02010         fprintf (fp, "  0\nAPPID\n");
02011         fprintf (fp, "  5\n242\n");
02012         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
02013         /*
02014          * write a record entry for a appid "ACAD".
02015          */
02016         fprintf (fp, "100\nAcDbRegAppTableRecord\n");
02017         fprintf (fp, "  2\nACAD\n");
02018         fprintf (fp, " 70\n     0\n");
02019         fprintf (fp, "  0\nAPPID\n");
02020         fprintf (fp, "  5\n253\n");
02021         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
02022         /*
02023          * write a record entry for a appid "AVE_RENDER".
02024          */
02025         fprintf (fp, "100\nAcDbRegAppTableRecord\n");
02026         fprintf (fp, "  2\nAVE_RENDER\n");
02027         fprintf (fp, " 70\n     0\n");
02028         fprintf (fp, "  0\nAPPID\n");
02029         fprintf (fp, "  5\n254\n");
02030         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
02031         /*
02032          * write a record entry for a appid "AVE_ENTITY_MATERIAL".
02033          */
02034         fprintf (fp, "100\nAcDbRegAppTableRecord\n");
02035         fprintf (fp, "  2\nAVE_ENTITY_MATERIAL\n");
02036         fprintf (fp, " 70\n     0\n");
02037         fprintf (fp, "  0\nAPPID\n");
02038         fprintf (fp, "  5\n255\n");
02039         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
02040         /*
02041          * write a record entry for a appid "AVE_FINISH".
02042          */
02043         fprintf (fp, "100\nAcDbRegAppTableRecord\n");
02044         fprintf (fp, "  2\nAVE_FINISH\n");
02045         fprintf (fp, " 70\n     0\n");
02046         fprintf (fp, "  0\nAPPID\n");
02047         fprintf (fp, "  5\n256\n");
02048         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
02049         /*
02050          * write a record entry for a appid "AVE_MATERIAL".
02051          */
02052         fprintf (fp, "100\nAcDbRegAppTableRecord\n");
02053         fprintf (fp, "  2\nAVE_MATERIAL\n");
02054         fprintf (fp, " 70\n     0\n");
02055         fprintf (fp, "  0\nAPPID\n");
02056         fprintf (fp, "  5\n257\n");
02057         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
02058         /*
02059          * write a record entry for a appid "AVE_GLOBAL".
02060          */
02061         fprintf (fp, "100\nAcDbRegAppTableRecord\n");
02062         fprintf (fp, "  2\nAVE_GLOBAL\n");
02063         fprintf (fp, " 70\n     0\n");
02064         fprintf (fp, "  0\nENDTAB\n");
02065         /*
02066          * write a DIMSTYLE (DIMensioning STYLE) table entry.
02067          */
02068         fprintf (fp, "  0\nTABLE\n");
02069         fprintf (fp, "  2\nDIMSTYLE\n");
02070         fprintf (fp, "  5\n23C\n");
02071         fprintf (fp, "100\nAcDbSymbolTable\n");
02072         fprintf (fp, " 70\n     1\n");
02073         fprintf (fp, "  0\nDIMSTYLE\n");
02074         fprintf (fp, "105\n258\n");
02075         fprintf (fp, "100\nAcDbSymbolTableRecord\n");
02076         /*
02077          * write a record entry for a dimstyle "STANDARD".
02078          */
02079         fprintf (fp, "100\nAcDbDimStyleTableRecord\n");
02080         fprintf (fp, "  2\nSTANDARD\n");
02081         fprintf (fp, " 70\n     0\n");
02082         fprintf (fp, "  3\n\n");
02083         fprintf (fp, "  4\n\n");
02084         fprintf (fp, "  5\n\n");
02085         fprintf (fp, "  6\n\n");
02086         fprintf (fp, "  7\n\n");
02087         fprintf (fp, " 40\n1.0\n");
02088         fprintf (fp, " 41\n0.18\n");
02089         fprintf (fp, " 42\n0.0625\n");
02090         fprintf (fp, " 43\n0.38\n");
02091         fprintf (fp, " 44\n0.18\n");
02092         fprintf (fp, " 45\n0.0\n");
02093         fprintf (fp, " 46\n0.0\n");
02094         fprintf (fp, " 47\n0.0\n");
02095         fprintf (fp, " 48\n0.0\n");
02096         fprintf (fp, "140\n0.18\n");
02097         fprintf (fp, "141\n0.09\n");
02098         fprintf (fp, "142\n0.0\n");
02099         fprintf (fp, "143\n25.4\n");
02100         fprintf (fp, "144\n1.0\n");
02101         fprintf (fp, "145\n0.0\n");
02102         fprintf (fp, "146\n1.0\n");
02103         fprintf (fp, "147\n0.09\n");
02104         fprintf (fp, " 71\n     0\n");
02105         fprintf (fp, " 72\n     0\n");
02106         fprintf (fp, " 73\n     1\n");
02107         fprintf (fp, " 74\n     1\n");
02108         fprintf (fp, " 75\n     0\n");
02109         fprintf (fp, " 76\n     0\n");
02110         fprintf (fp, " 77\n     0\n");
02111         fprintf (fp, " 78\n     0\n");
02112         fprintf (fp, "170\n     0\n");
02113         fprintf (fp, "171\n     2\n");
02114         fprintf (fp, "172\n     0\n");
02115         fprintf (fp, "173\n     0\n");
02116         fprintf (fp, "174\n     0\n");
02117         fprintf (fp, "175\n     0\n");
02118         fprintf (fp, "176\n     0\n");
02119         fprintf (fp, "177\n     0\n");
02120         fprintf (fp, "178\n     0\n");
02121         fprintf (fp, "270\n     2\n");
02122         fprintf (fp, "271\n     4\n");
02123         fprintf (fp, "272\n     4\n");
02124         fprintf (fp, "273\n     2\n");
02125         fprintf (fp, "274\n     2\n");
02126         fprintf (fp, "340\n241\n"); /* this doesn't look like good dxf syntax to me */
02127         fprintf (fp, "275\n     0\n");
02128         fprintf (fp, "280\n     0\n");
02129         fprintf (fp, "281\n     0\n");
02130         fprintf (fp, "282\n     0\n");
02131         fprintf (fp, "283\n     1\n");
02132         fprintf (fp, "284\n     0\n");
02133         fprintf (fp, "285\n     0\n");
02134         fprintf (fp, "286\n     0\n");
02135         fprintf (fp, "287\n     3\n");
02136         fprintf (fp, "288\n     0\n");
02137         fprintf (fp, "  0\nENDTAB\n");
02138 #if DEBUG
02139         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_header_metric_new () function.\n", __FILE__, __LINE__);
02140 #endif
02141 }
02142 
02169 static void
02170 dxf_write_header
02171 (
02172         FILE *fp 
02173 )
02174 {
02175 #if DEBUG
02176         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_header () function.\n", __FILE__, __LINE__);
02177 #endif
02178         FILE *f_temp = 0;
02179         char *temp = NULL;
02180         if (dxf_metric)
02181         {
02182                 dxf_header_filename = strdup ("hid/dxf/template/metric_header.dxf");
02183         }
02184         else
02185         {
02186                 dxf_header_filename = strdup ("hid/dxf/template/imperial_header.dxf");
02187         }
02188         /*
02189          * check if template metric header file exists and open file read-only.
02190          */
02191         f_temp = fopen (dxf_header_filename, "r");
02192         if (!f_temp)
02193         {
02194                 gui->log ("Error in dxf_write_header_from_template (): cannot open file %s for reading.\n", dxf_header_filename);
02195                 if (dxf_metric)
02196                 {
02197                         dxf_write_header_metric_new (fp);
02198                 }
02199                 else
02200                 {
02201                         dxf_write_header_imperial_new (fp);
02202                 }
02203         }
02204         else
02205         {
02206                 /*
02207                  * do until EOF of the template file:
02208                  * copy line by line from template file (f_temp) to destination file (fp).
02209                  */
02210                 while (f_temp != EOF)
02211                 {
02212                         fscanf (f_temp, "%s", temp);
02213                         fprintf (fp, "%s", temp);
02214                 }
02215                 /*
02216                  * when we're done close the template file.
02217                  */
02218                 fclose (f_temp);
02219         }
02220         /*
02221          * write block record table.
02222          */
02223         dxf_write_table_block_record (fp);
02224         /*
02225          * write ENDSEC marker to close header.
02226          */
02227         dxf_write_endsection (fp);
02228 #if DEBUG
02229         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_header () function.\n", __FILE__, __LINE__);
02230 #endif
02231 }
02232 
02236 static void
02237 dxf_write_insert
02238 (
02239         FILE *fp, 
02240         int id_code, 
02241         char *block_name, 
02242         char *linetype, 
02243         char *layer, 
02244         double x0, 
02245         double y0, 
02246         double z0, 
02247         double thickness, 
02248         double rel_x_scale, 
02249         double rel_y_scale, 
02250         double rel_z_scale, 
02251         double column_spacing, 
02252         double row_spacing, 
02253         double rot_angle, 
02254         int color, 
02255         int attribute_follows, 
02256         int paperspace, 
02257         int columns, 
02258         int rows 
02259 )
02260 {
02261 #if DEBUG
02262         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_insert () function.\n", __FILE__, __LINE__);
02263         fprintf (stderr, "[DXF entity with ID code %x]\n", id_code);
02264 #endif
02265         char *dxf_entity_name = strdup ("INSERT");
02266         if (block_name == "")
02267         {
02268                 fprintf (stderr, "Warning: empty block name string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02269                 fprintf (stderr, "         %s entity is discarded from output.\n", dxf_entity_name);
02270                 return;
02271         }
02272         if (strcmp (layer, "") == 0)
02273         {
02274                 fprintf (stderr, "Warning: empty layer string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02275                 fprintf (stderr, "    %s entity is relocated to layer 0.\n", dxf_entity_name);
02276                 layer = strdup (DXF_DEFAULT_LAYER);
02277         }
02278         if (rel_x_scale == 0.0)
02279         {
02280                 fprintf (stderr, "Warning: relative X-scale factor has a value of 0.0 for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02281                 fprintf (stderr, "    default relative X-scale of 1.0 applied to %s entity.\n", dxf_entity_name);
02282                 rel_x_scale = 1.0;
02283         }
02284         if (rel_y_scale == 0.0)
02285         {
02286                 fprintf (stderr, "Warning: relative Y-scale factor has a value of 0.0 for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02287                 fprintf (stderr, "    default relative Y-scale of 1.0 applied to %s entity.\n", dxf_entity_name);
02288                 rel_y_scale = 1.0;
02289         }
02290         if (rel_z_scale == 0.0)
02291         {
02292                 fprintf (stderr, "Warning: relative Z-scale factor has a value of 0.0 for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02293                 fprintf (stderr, "    default relative Z-scale of 1.0 applied to %s entity.\n", dxf_entity_name);
02294                 rel_z_scale = 1.0;
02295         }
02296         if ((columns > 1) && (column_spacing == 0.0))
02297         {
02298                 fprintf (stderr, "Warning: number of columns is greater than 1 and the column spacing has a value of 0.0 for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02299                 fprintf (stderr, "    default number of columns value of 1 applied to %s entity.\n", dxf_entity_name);
02300                 columns = 1;
02301         }
02302         if ((rows > 1) && (row_spacing == 0.0))
02303         {
02304                 fprintf (stderr, "Warning: number of rows is greater than 1 and the row spacing has a value of 0.0 for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02305                 fprintf (stderr, "    default number of rows value of 1 applied to %s entity.\n", dxf_entity_name);
02306                 rows = 1;
02307         }
02308         fprintf (fp, "  0\n%s\n", dxf_entity_name);
02309         fprintf (fp, "  2\n%s\n", block_name);
02310         if (id_code != -1) fprintf (fp, "  5\n%x\n", id_code);
02311         if (strcmp (linetype, DXF_DEFAULT_LINETYPE) != 0) fprintf (fp, "  6\n%s\n", linetype);
02312         fprintf (fp, "  8\n%s\n", layer);
02313         fprintf (fp, " 10\n%f\n", x0);
02314         fprintf (fp, " 20\n%f\n", y0);
02315         fprintf (fp, " 30\n%f\n", z0);
02316         if (thickness != 0.0) fprintf (fp, " 39\n%f\n", thickness);
02317         if (rel_x_scale != 1.0) fprintf (fp, " 41\n%f\n", rel_x_scale);
02318         if (rel_y_scale != 1.0) fprintf (fp, " 42\n%f\n", rel_y_scale);
02319         if (rel_z_scale != 1.0) fprintf (fp, " 43\n%f\n", rel_z_scale);
02320         if ((columns > 1) && (column_spacing > 0.0)) fprintf (fp, " 44\n%f\n", column_spacing);
02321         if ((rows > 1) && (row_spacing > 0.0)) fprintf (fp, " 45\n%f\n", row_spacing);
02322         if (rot_angle != 0.0) fprintf (fp, " 50\n%f\n", rot_angle);
02323         if (color != DXF_COLOR_BYLAYER) fprintf (fp, " 62\n%d\n", color);
02324         if (attribute_follows != 0) fprintf (fp, " 66\n%d\n", attribute_follows);
02325         if (paperspace == DXF_PAPERSPACE) fprintf (fp, " 67\n%d\n", DXF_PAPERSPACE);
02326         if (columns > 1) fprintf (fp, " 70\n%d\n", columns);
02327         if (rows > 1) fprintf (fp, " 71\n%d\n", rows);
02328 #if DEBUG
02329         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_insert () function.\n", __FILE__, __LINE__);
02330 #endif
02331 }
02332 
02348 static void
02349 dxf_write_polyline
02350 (
02351         FILE *fp, 
02352         int id_code, 
02353         char *linetype, 
02354         char *layer, 
02355         double x0, 
02356         double y0, 
02357         double z0, 
02358         double extr_x0, 
02359         double extr_y0, 
02360         double extr_z0, 
02361         double thickness, 
02362         double start_width, 
02363         double end_width, 
02364         int color, 
02365         int vertices_follow, 
02366         int paperspace, 
02367         int flag, 
02376         int polygon_mesh_M_vertex_count, 
02377         int polygon_mesh_N_vertex_count, 
02378         int smooth_M_surface_density, 
02379         int smooth_N_surface_density, 
02380         int surface_type 
02385 )
02386 {
02387 #if DEBUG
02388         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_polyline () function.\n", __FILE__, __LINE__);
02389         fprintf (stderr, "[DXF entity with code %x]\n", id_code);
02390 #endif
02391         char *dxf_entity_name = strdup ("POLYLINE");
02392         if (x0 != 0.0)
02393         {
02394                 fprintf (stderr, "Warning: start point has an invalid X-value for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02395                 fprintf (stderr, "         %s entity is discarded from output.\n", dxf_entity_name);
02396                 return;
02397         }
02398         if (y0 != 0.0)
02399         {
02400                 fprintf (stderr, "Warning: start point has an invalid Y-value for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02401                 fprintf (stderr, "         %s entity is discarded from output.\n", dxf_entity_name);
02402                 return;
02403         }
02404         if (vertices_follow != 1)
02405         {
02406                 fprintf (stderr, "Warning: vertices follow flag has an invalid value for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02407                 fprintf (stderr, "         %s entity is discarded from output.\n", dxf_entity_name);
02408                 return;
02409         }
02410         if (strcmp (layer, "") == 0)
02411         {
02412                 fprintf (stderr, "Warning: empty layer string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02413                 fprintf (stderr, "         %s entity is relocated to layer 0\n", dxf_entity_name);
02414                 layer = strdup (DXF_DEFAULT_LAYER);
02415         }
02416         fprintf (fp, "  0\n%s\n", dxf_entity_name);
02417         fprintf (fp, "100\nAcDb3dPolyline\n"); /* Subclass marker (AcDb2dPolyline or AcDb3dPolyline) */
02418         if (id_code != -1) fprintf (fp, "  5\n%x\n", id_code);
02419         if (strcmp (linetype, DXF_DEFAULT_LINETYPE) != 0) fprintf (fp, "  6\n%s\n", linetype);
02420         fprintf (fp, "  8\n%s\n", layer);
02421         fprintf (fp, " 10\n%f\n", x0);
02422         fprintf (fp, " 20\n%f\n", y0);
02423         fprintf (fp, " 30\n%f\n", z0);
02424         fprintf (fp, "210\n%f\n", extr_x0);
02425         fprintf (fp, "220\n%f\n", extr_y0);
02426         fprintf (fp, "230\n%f\n", extr_z0);
02427         if (thickness != 0.0) fprintf (fp, " 39\n%f\n", thickness);
02428         if (start_width != 0.0) fprintf (fp, " 40\n%f\n", start_width);
02429         if (end_width != 0.0) fprintf (fp, " 41\n%f\n", end_width);
02430         if (color != DXF_COLOR_BYLAYER) fprintf (fp, " 62\n%d\n", color);
02431         fprintf (fp, " 66\n%d\n", vertices_follow);
02432         if (paperspace == DXF_PAPERSPACE) fprintf (fp, " 67\n%d\n", DXF_PAPERSPACE);
02433         fprintf (fp, " 70\n%d\n", flag);
02434         fprintf (fp, " 71\n%d\n", polygon_mesh_M_vertex_count);
02435         fprintf (fp, " 72\n%d\n", polygon_mesh_N_vertex_count);
02436         fprintf (fp, " 73\n%d\n", smooth_M_surface_density);
02437         fprintf (fp, " 74\n%d\n", smooth_N_surface_density);
02438         fprintf (fp, " 75\n%d\n", surface_type);
02439 #if DEBUG
02440         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_polyline () function.\n", __FILE__, __LINE__);
02441 #endif
02442 }
02443 
02447 static void
02448 dxf_write_section
02449 (
02450         FILE *fp, 
02451         char *section_name 
02452 )
02453 {
02454 #if DEBUG
02455         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_section () function.\n", __FILE__, __LINE__);
02456 #endif
02457         /*
02458          * no use in writing an empty string to file.
02459          */
02460         if (section_name == "") return;
02461         fprintf (fp, "  0\nSECTION\n  2\n%s\n", section_name);
02462 #if DEBUG
02463         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_section () function.\n", __FILE__, __LINE__);
02464 #endif
02465 }
02466 
02470 static void
02471 dxf_write_solid
02472 (
02473         FILE *fp, 
02474         int id_code, 
02475         char *linetype, 
02476         char *layer, 
02477         double x0, 
02478         double y0, 
02479         double z0, 
02480         double x1, 
02481         double y1, 
02482         double z1, 
02483         double x2, 
02484         double y2, 
02485         double z2, 
02486         double x3, 
02487         double y3, 
02488         double z3, 
02489         double thickness, 
02490         int color, 
02491         int paperspace 
02492 )
02493 {
02494 #if DEBUG
02495         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_solid () function.\n", __FILE__, __LINE__);
02496         fprintf (stderr, "[DXF entity with code %x]\n", id_code);
02497 #endif
02498         char *dxf_entity_name = strdup ("SOLID");
02499         if (strcmp (layer, "") == 0)
02500         {
02501                 fprintf (stderr, "Warning: empty layer string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02502                 fprintf (stderr, "    %s entity is relocated to layer 0", dxf_entity_name);
02503                 layer = strdup (DXF_DEFAULT_LAYER);
02504         }
02505         fprintf (fp, "  0\n%s\n", dxf_entity_name);
02506         if (id_code != -1) fprintf (fp, "  5\n%x\n", id_code);
02507         if (strcmp (linetype, DXF_DEFAULT_LINETYPE) != 0) fprintf (fp, "  6\n%s\n", linetype);
02508         fprintf (fp, "  8\n%s\n", layer);
02509         fprintf (fp, " 10\n%f\n", x0);
02510         fprintf (fp, " 20\n%f\n", y0);
02511         fprintf (fp, " 30\n%f\n", z0);
02512         fprintf (fp, " 11\n%f\n", x1);
02513         fprintf (fp, " 21\n%f\n", y1);
02514         fprintf (fp, " 31\n%f\n", z1);
02515         fprintf (fp, " 12\n%f\n", x2);
02516         fprintf (fp, " 22\n%f\n", y2);
02517         fprintf (fp, " 32\n%f\n", z2);
02518         fprintf (fp, " 13\n%f\n", x3);
02519         fprintf (fp, " 23\n%f\n", y3);
02520         fprintf (fp, " 33\n%f\n", z3);
02521         if (thickness != 0.0) fprintf (fp, " 39\n%f\n", thickness);
02522         if (color != DXF_COLOR_BYLAYER) fprintf (fp, " 62\n%d\n", color);
02523         if (paperspace == DXF_PAPERSPACE) fprintf (fp, " 67\n%d\n", DXF_PAPERSPACE);
02524 #if DEBUG
02525         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_solid () function.\n", __FILE__, __LINE__);
02526 #endif
02527 }
02528 
02532 static void
02533 dxf_write_vertex
02534 (
02535         FILE *fp, 
02536         int id_code, 
02537         char *linetype, 
02538         char *layer, 
02539         double x0, 
02540         double y0, 
02541         double z0, 
02542         double thickness, 
02543         double start_width, 
02544         double end_width, 
02545         double bulge, 
02548         double curve_fit_tangent_direction, 
02549         int color, 
02550         int paperspace, 
02551         int flag 
02561 )
02562 {
02563 #if DEBUG
02564         fprintf (stderr, "[File: %s: line: %d] Entering dxf_write_vertex () function.\n", __FILE__, __LINE__);
02565         fprintf (stderr, "[DXF entity with code %x]\n", id_code);
02566 #endif
02567         char *dxf_entity_name = strdup ("VERTEX");
02568         if (strcmp (layer, "") == 0)
02569         {
02570                 fprintf (stderr, "Warning: empty layer string for the %s entity with id-code: %x\n", dxf_entity_name, id_code);
02571                 fprintf (stderr, "    %s entity is relocated to layer 0", dxf_entity_name);
02572                 layer = strdup (DXF_DEFAULT_LAYER);
02573         }
02574 
02575         fprintf (fp, "  0\n%s\n", dxf_entity_name);
02576         if (id_code != -1) fprintf (fp, "  5\n%x\n", id_code);
02577         if (strcmp (linetype, DXF_DEFAULT_LINETYPE) != 0) fprintf (fp, "  6\n%s\n", linetype);
02578         fprintf (fp, "  8\n%s\n", layer);
02579         fprintf (fp, " 10\n%f\n", x0);
02580         fprintf (fp, " 20\n%f\n", y0);
02581         fprintf (fp, " 30\n%f\n", z0);
02582         if (thickness != 0.0) fprintf (fp, " 39\n%f\n", thickness);
02583         if (start_width != 0.0) fprintf (fp, " 40\n%f\n", start_width);
02584         if (end_width != 0.0) fprintf (fp, " 41\n%f\n", end_width);
02585         if (bulge != 0.0) fprintf (fp, " 42\n%f\n", bulge);
02586         if (curve_fit_tangent_direction != 0.0) fprintf (fp, " 50\n%f\n", curve_fit_tangent_direction);
02587         if (color != DXF_COLOR_BYLAYER) fprintf (fp, " 62\n%d\n", color);
02588         if (paperspace == DXF_PAPERSPACE) fprintf (fp, " 67\n%d\n", DXF_PAPERSPACE);
02589         fprintf (fp, " 70\n%d\n", flag);
02590 #if DEBUG
02591         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_write_vertex () function.\n", __FILE__, __LINE__);
02592 #endif
02593 }
02594 
02605 static HID_Attribute *
02606 dxf_get_export_options (int *n)
02607 {
02608 #if DEBUG
02609         fprintf (stderr, "[File: %s: line: %d] Entering dxf_get_export_options () function.\n", __FILE__, __LINE__);
02610 #endif
02611         static char *last_dxf_filename = 0;
02612         static char *last_dxf_xref_filename = 0;
02613         if (PCB)
02614         {
02615                 derive_default_filename (PCB->Filename, &dxf_options[HA_dxffile], "", &last_dxf_filename);
02616                 derive_default_filename (PCB->Filename, &dxf_options[HA_xreffile], "", &last_dxf_xref_filename);
02617         }
02618         if (n)
02619         {
02620                 *n = NUM_OPTIONS;
02621         }
02622 #if DEBUG
02623         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_get_export_options () function.\n", __FILE__, __LINE__);
02624 #endif
02625         return dxf_options;
02626 }
02627 
02631 static DxfList *
02632 dxf_insert
02633 (
02634         char *refdes, 
02635         char *descr, 
02636         char *value, 
02637         DxfList * dxf 
02638 )
02639 {
02640 #if DEBUG
02641         fprintf (stderr, "[File: %s: line: %d] Entering dxf_insert () function.\n", __FILE__, __LINE__);
02642 #endif
02643         DxfList *new, *cur, *prev = NULL;
02644         if (dxf == NULL)
02645         {
02646         /*
02647          * this is the first element so automatically create an entry.
02648          */
02649         if ((new = (DxfList *) malloc (sizeof (DxfList))) == NULL)
02650         {
02651                 fprintf (stderr, "Error in dxf.c|dxf_insert (): malloc() failed.\n");
02652                 exit (1);
02653         }
02654         new->next = NULL;
02655         new->descr = strdup (descr);
02656         new->value = strdup (value);
02657         new->num = 1;
02658         new->refdes = dxf_string_insert (refdes, NULL);
02659         return (new);
02660         }
02661         /*
02662          * search and see if we already have used one of these components.
02663          */
02664         cur = dxf;
02665         while (cur != NULL)
02666         {
02667                 if ((NSTRCMP (descr, cur->descr) == 0) && (NSTRCMP (value, cur->value) == 0))
02668                 {
02669                         cur->num++;
02670                         cur->refdes = dxf_string_insert (refdes, cur->refdes);
02671                         break;
02672                 }
02673                 prev = cur;
02674                 cur = cur->next;
02675         }
02676         if (cur == NULL)
02677         {
02678                 if ((new = (DxfList *) malloc (sizeof (DxfList))) == NULL)
02679                 {
02680                         fprintf (stderr, "Error in dxf.c|dxf_insert (): malloc() failed.\n");
02681                         exit (1);
02682                 }
02683                 prev->next = new;
02684                 new->next = NULL;
02685                 new->descr = strdup (descr);
02686                 new->value = strdup (value);
02687                 new->num = 1;
02688                 new->refdes = dxf_string_insert (refdes, NULL);
02689         }
02690 #if DEBUG
02691         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_insert () function.\n", __FILE__, __LINE__);
02692 #endif
02693         return (dxf);
02694 }
02695 
02719 static int
02720 dxf_export_xref_file (void)
02721 {
02722 #if DEBUG
02723         fprintf (stderr, "[File: %s: line: %d] Entering dxf_export_xref_file () function.\n", __FILE__, __LINE__);
02724 #endif
02725         char utcTime[64];
02726         double x;
02727         double y;
02728         double theta = 0.0;
02729         double sumx;
02730         double sumy;
02731         double pin1x = 0.0;
02732         double pin1y = 0.0;
02733         double pin1angle = 0.0;
02734         double pin2x = 0.0;
02735         double pin2y = 0.0;
02736         double pin2angle;
02737         int found_pin1;
02738         int found_pin2;
02739         int pin_cnt;
02740         time_t currenttime;
02741         FILE *fp = 0;
02742         DxfList *dxf = NULL;
02743         DxfList *lastb;
02744         char *dxf_block_name = NULL;
02745         char *dxf_xref_name = NULL;
02746         double dxf_x0 = 0.0;
02747         double dxf_y0 = 0.0;
02748         double dxf_rot_angle = 0.0;
02749         fp = fopen (dxf_xref_filename, "w");
02750         if (!fp)
02751         {
02752                 gui->log ("Error in dxf.c|dxf_export_xref_file (): cannot open file %s for writing.\n", dxf_xref_filename);
02753                 return 1;
02754         }
02755         /*
02756          * create a portable timestamp.
02757          */
02758         currenttime = time (NULL);
02759         strftime (utcTime, sizeof (utcTime), "%c UTC", gmtime (&currenttime));
02760         /*
02761          * write pcb header information as DXF comments.
02762          */
02763         dxf_write_comment (fp, "# PCB DXF HID - Xrefs Version 0.0.1");
02764         dxf_write_comment (fp, "# Date: ");
02765         dxf_write_comment (fp, strdup (utcTime));
02766         dxf_write_comment (fp, "# Author: ");
02767         dxf_write_comment (fp, strdup (pcb_author ()));
02768         dxf_write_comment (fp, "# Title: ");
02769         dxf_write_comment (fp, strdup (UNKNOWN (PCB->Name)));
02770         /*
02771          * write dxf header information.
02772          */
02773         dxf_write_header (fp);
02774         dxf_write_section (fp, "BLOCKS");
02775         /*
02776          * lookup all elements on pcb and insert element in the list of elements.
02777          */
02778         ELEMENT_LOOP (PCB->Data);
02779         {
02780                 /*
02781                  * insert the elements into the dxf list.
02782                  */
02783                 dxf = dxf_insert (UNKNOWN (NAMEONPCB_NAME (element)),
02784                                   UNKNOWN (DESCRIPTION_NAME (element)),
02785                                   UNKNOWN (VALUE_NAME (element)), dxf);
02786         }
02787         END_LOOP; /* End of ELEMENT_LOOP  */
02788         /*
02789          * now write a single block definition for every unique element to
02790          * the BLOCKS section of the DXF file.
02791          * since these are all supposed to be Xref blocks they are not to
02792          * contain entities, just the path and filename (including extension).
02793          * write a section BLOCKS marker to the DXF file.
02794          */
02795         while (dxf != NULL)
02796         {
02797                 dxf_block_name = strdup (dxf_clean_string (dxf->descr));
02798                 dxf_xref_name = DXF_DEFAULT_XREF_PATH_NAME;
02799                 dxf_write_block
02800                 (
02801                         fp,
02802                         dxf_id_code,
02803                         dxf_xref_name,
02804                         dxf_block_name,
02805                         DXF_DEFAULT_LINETYPE, /* linetype, */
02806                         DXF_DEFAULT_LAYER, /* layer, */
02807                         0.0, /* dxf_x0, */
02808                         0.0, /* dxf_y0, */
02809                         0.0, /* dxf_z0, */
02810                         0.0, /* dxf_thickness, */
02811                         DXF_COLOR_BYLAYER, /* dxf_color, */
02812                         0, /* dxf_paperspace, */
02813                         36 /* dxf_block_type*/
02814                 );
02815                 dxf_id_code++;
02816                 lastb = dxf;
02817                 dxf = dxf->next;
02818                 free (lastb);
02819         }
02820         /*
02821          * write an ENDSEC marker to the DXF file.
02822          */
02823         dxf_write_endsection (fp);
02824         /*
02825          * write a section ENTITIES marker to the DXF file.
02826          */
02827         dxf_write_section (fp, "ENTITIES");
02828         /*
02829          * for each element we calculate the centroid of the footprint.
02830          * in addition, we need to extract some notion of rotation.
02831          */
02832         ELEMENT_LOOP (PCB->Data);
02833         {
02834                 /*
02835                  * initialize our pin count and our totals for finding the centroid.
02836                  */
02837                 pin_cnt = 0;
02838                 sumx = 0.0;
02839                 sumy = 0.0;
02840                 found_pin1 = 0;
02841                 found_pin2 = 0;
02842                 /*
02843                  * iterate over the pins and pads keeping a running count of how
02844                  * many pins/pads total and the sum of x and y coordinates.
02845                  * While we're at it, store the location of pin/pad #1 and #2 if
02846                  * we can find them.
02847                  */
02848                 PIN_LOOP (element);
02849                 {
02850                         sumx += (double) pin->X;
02851                         sumy += (double) pin->Y;
02852                         pin_cnt++;
02853                         if (NSTRCMP (pin->Number, "1") == 0)
02854                         {
02855                                 pin1x = (double) pin->X;
02856                                 pin1y = (double) pin->Y;
02857                                 pin1angle = 0.0; /* pins have no notion of angle  */
02858                                 found_pin1 = 1;
02859                         }
02860                         else if (NSTRCMP (pin->Number, "2") == 0)
02861                         {
02862                                 pin2x = (double) pin->X;
02863                                 pin2y = (double) pin->Y;
02864                                 pin2angle = 0.0; /* pins have no notion of angle  */
02865                                 found_pin2 = 1;
02866                         }
02867                 }
02868                 END_LOOP; /* End of PIN_LOOP  */
02869                 PAD_LOOP (element);
02870                 {
02871                         sumx += (pad->Point1.X + pad->Point2.X) / 2.0;
02872                         sumy += (pad->Point1.Y + pad->Point2.Y) / 2.0;
02873                         pin_cnt++;
02874                         if (NSTRCMP (pad->Number, "1") == 0)
02875                         {
02876                                 pin1x = (double) (pad->Point1.X + pad->Point2.X) / 2.0;
02877                                 pin1y = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0;
02878                                 /*
02879                                  * NOTE: we swap the Y points, because in PCB
02880                                  * the Y-axis is inverted, and increasing Y
02881                                  * moves down.
02882                                  * we want to deal with a right-handed
02883                                  * Cartesian Coordinate System where
02884                                  * increasing Y moves up.
02885                                  */
02886                                 pin1angle = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y, pad->Point2.X - pad->Point1.X);
02887                                 found_pin1 = 1;
02888                         }
02889                         else if (NSTRCMP (pad->Number, "2") == 0)
02890                         {
02891                                 pin2x = (double) (pad->Point1.X + pad->Point2.X) / 2.0;
02892                                 pin2y = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0;
02893                                 pin2angle = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y, pad->Point2.X - pad->Point1.X);
02894                                 found_pin2 = 1;
02895                         }
02896                 }
02897                 END_LOOP; /* End of PAD_LOOP  */
02898                 if (pin_cnt > 0)
02899                 {
02900                         x = sumx / (double) pin_cnt;
02901                         y = sumy / (double) pin_cnt;
02902                         if (found_pin1)
02903                         {
02904                                 /*
02905                                  * recenter pin #1 onto the axis which cross
02906                                  * at the part centroid.
02907                                  */
02908                                 pin1x -= x;
02909                                 pin1y -= y;
02910                                 pin1y = -1.0 * pin1y;
02911                                 /*
02912                                  * if only 1 pin, use pin 1's angle.
02913                                  */
02914                                 if (pin_cnt == 1) theta = pin1angle;
02915                                 else
02916                                 {
02917                                 /*
02918                                  * if pin #1 is at (0,0) use pin #2 for
02919                                  * rotation.
02920                                  */
02921                                         if ((pin1x == 0.0) && (pin1y == 0.0))
02922                                         {
02923                                                 if (found_pin2) theta = dxf_xy_to_angle (pin2x, pin2y);
02924                                                 else
02925                                                 {
02926                                                         Message  ("Warning in dxf.c|dxf_export_xref_file ():\n"
02927                                                                   "     unable to figure out angle of element\n"
02928                                                                   "     %s because pin #1 is at the centroid of the part\n"
02929                                                                   "     and I could not find pin #2's location.\n"
02930                                                                   "     Setting to %g degrees.\n", UNKNOWN (NAMEONPCB_NAME (element)), theta);
02931                                                 }
02932                                         }
02933                                         else theta = dxf_xy_to_angle (pin1x, pin1y);
02934                                 }
02935                         }
02936                         /*
02937                          * we did not find pin #1.
02938                          */
02939                         else
02940                         {
02941                                 theta = 0.0;
02942                                 Message  ("Warning in dxf.c|dxf_export_xref_file ():\n"
02943                                           "     unable to figure out angle because I could\n"
02944                                           "     not find pin #1 of element %s.\n"
02945                                           "     Setting to %g degrees.\n", UNKNOWN (NAMEONPCB_NAME (element)), theta);
02946                         }
02947                         dxf_block_name = strdup (dxf_clean_string (UNKNOWN (DESCRIPTION_NAME (element))));
02948                         if (dxf_metric)
02949                         {
02950                                 /*
02951                                  * convert mils to mm.
02952                                  */
02953                                 dxf_x0 = MIL_TO_MM * x;
02954                                 /*
02955                                  * convert mils to mm and a right handed
02956                                  * Cartesian Coordinate System.
02957                                  */
02958                                 dxf_y0 = MIL_TO_MM * (PCB->MaxHeight - y);
02959                         }
02960                         else
02961                         {
02962                                 /*
02963                                  * no need to convert, some things remain the
02964                                  * same.
02965                                  */
02966                                 dxf_x0 = x;
02967                                 /*
02968                                  * only convert to a right handed Cartesian
02969                                  * Coordinate System.
02970                                  */
02971                                 dxf_y0 = (PCB->MaxHeight - y);
02972                         }
02973 #if 0
02974                         /*
02975                          * convert the rotation angle as well:
02976                          * theta -> CW, DXF -> CCW.
02977                          */
02982                         if (theta == 0.0) dxf_rot_angle = 90.0;
02983                         else if (theta == 90.0) dxf_rot_angle = 0.0;
02984                         else if (theta == 180.0) dxf_rot_angle = 270.0;
02985                         else if (theta == 270.0) dxf_rot_angle = 180.0;
02986                         else
02987                         {
02988                                 dxf_rot_angle = 0.0;
02989                                 Message  ("Warning in dxf.c|dxf_export_xref_file ():\n"
02990                                           "     unable to figure out angle of dxf block\n"
02991                                           "     %s because pcb angle theta is not Cardinal [0.0, 90.0, 180.0, 270.0].\n"
02992                                           "     Setting dxf_rot_angle to %g degrees\n", UNKNOWN (NAMEONPCB_NAME (element)), dxf_rot_angle);
02993                        }
02994 #endif
02995                        dxf_write_insert
02996                        (
02997                                fp,
02998                                dxf_id_code,
02999                                dxf_block_name,
03000                                DXF_DEFAULT_LINETYPE, /* dxf_linetype, */
03001                                DXF_DEFAULT_LAYER, /* dxf_layer, */
03002                                dxf_x0,
03003                                dxf_y0,
03004                                0.0, /* dxf_z0, */
03005                                0.0, /* dxf_thickness, */
03006                                1.0, /* dxf_rel_x_scale, */
03007                                1.0, /* dxf_rel_y_scale, */
03008                                1.0, /* dxf_rel_z_scale, */
03009                                0.0, /* dxf_column_spacing, */
03010                                0.0, /* dxf_row_spacing, */
03011                                dxf_rot_angle,
03012                                DXF_COLOR_BYLAYER, /* dxf_color, */
03013                                0, /* dxf_attribute_follows, */
03014                                0, /* dxf_paperspace, */
03015                                1, /* dxf_columns, */
03016                                1 /* dxf_rows */
03017                         );
03018                 }
03019                 dxf_id_code++;
03020         }
03021         END_LOOP; /* End of ELEMENT_LOOP  */
03022         /*
03023          * write an ENDSEC marker to the DXF file.
03024          */
03025         dxf_write_endsection(fp);
03026         /*
03027          * write an EOF marker and close the DXFfile.
03028          */
03029         dxf_write_eof (fp);
03030         fclose (fp);
03031         dxf_id_code = 0;
03032 #if DEBUG
03033         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_export_xref_file () function.\n", __FILE__, __LINE__);
03034 #endif
03035         return (0);
03036 }
03037 
03041 static void
03042 dxf_maybe_close_file ()
03043 {
03044 #if DEBUG
03045         fprintf (stderr, "[File: %s: line: %d] Entering dxf_maybe_close_file () function.\n", __FILE__, __LINE__);
03046 #endif
03047         if (f)
03048         {
03049                 /*
03050                  * write an EOF marker and close the DXFfile.
03051                  */
03052                 dxf_write_eof (f);
03053                 fclose (f);
03054         }
03055         f = 0;
03056         dxf_id_code = 0;
03057 #if DEBUG
03058         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_maybe_close_file () function.\n", __FILE__, __LINE__);
03059 #endif
03060 }
03061 
03077 static void
03078 dxf_do_export (HID_Attr_Val * options)
03079 {
03080 #if DEBUG
03081         fprintf (stderr, "[File: %s: line: %d] Entering dxf_do_export () function.\n", __FILE__, __LINE__);
03082 #endif
03083         char *dxf_fnbase = NULL;
03084         int i;
03085         static int saved_layer_stack[MAX_LAYER];
03086         BoxType region;
03087         int save_ons[MAX_LAYER + 2];
03088         if (!options)
03089         {
03090                 dxf_get_export_options (0);
03091                 for (i = 0; i < NUM_OPTIONS; i++)
03092                 {
03093                         dxf_values[i] = dxf_options[i].default_val;
03094                 }
03095                 options = dxf_values;
03096         }
03097         /*
03098          * verbose output (dxf files to contain comments).
03099          */
03100         dxf_verbose = options[HA_verbose].int_value;
03101         /*
03102          * output to be in in mils or mm.
03103          */
03104         dxf_metric = options[HA_metric].int_value;
03105         /*
03106          * entity color to be BYBLOCK (or by layer number).
03107          */
03108         dxf_color_is_byblock = options[HA_color_byblock].int_value;
03109         /*
03110          * if xrefs file needs to be extracted.
03111          */
03112         dxf_xrefs = options[HA_xrefs].int_value;
03113         if (dxf_xrefs)
03114         {
03115                 /*
03116                  * determine a file name for the xref file.
03117                  */
03118                 dxf_xref_filename = options[HA_xreffile].str_value;
03119                 if (!dxf_xref_filename)
03120                 {
03121                         dxf_xref_filename = "pcb-out_xrefs";
03122                 }
03123                 i = strlen (dxf_xref_filename);
03124                 dxf_xref_filename = MyRealloc (dxf_xref_filename, i + 40, "dxf");
03125                 strcat (dxf_xref_filename, "_xrefs.dxf");
03126                 dxf_filesuffix = dxf_xref_filename + strlen (dxf_xref_filename);
03127                 dxf_export_xref_file ();
03128         }
03129         /*
03130          * determine a file name base for the DXF layer files.
03131          */
03132         dxf_fnbase = options[HA_dxffile].str_value;
03133         if (!dxf_fnbase)
03134         {
03135                 dxf_fnbase = "pcb_layers";
03136         }
03137         i = strlen (dxf_fnbase);
03138         dxf_filename = MyRealloc (dxf_filename, i + 40, "dxf");
03139         strcpy (dxf_filename, dxf_fnbase);
03140         strcat (dxf_filename, "_");
03141         dxf_filesuffix = dxf_filename + strlen (dxf_filename);
03142         memset (print_group, 0, sizeof (print_group));
03143         memset (print_layer, 0, sizeof (print_layer));
03144         /*
03145          * use this to temporarily enable all layers.
03146          */
03147         hid_save_and_show_layer_ons (save_ons);
03148         for (i = 0; i < max_layer; i++)
03149         {
03150                 LayerType *layer = PCB->Data->Layer + i;
03151                 if (layer->LineN || layer->TextN || layer->ArcN || layer->PolygonN)
03152                 {
03153                         print_group[GetLayerGroupNumberByNumber (i)] = 1;
03154                 }
03155         }
03156         print_group[GetLayerGroupNumberByNumber (max_layer)] = 1;
03157         print_group[GetLayerGroupNumberByNumber (max_layer + 1)] = 1;
03158         for (i = 0; i < max_layer; i++)
03159         {
03160                 if (print_group[GetLayerGroupNumberByNumber (i)])
03161                 {
03162                         print_layer[i] = 1;
03163                 }
03164         }
03165         memcpy (saved_layer_stack, LayerStack, sizeof (LayerStack));
03166         qsort (LayerStack, max_layer, sizeof (LayerStack[0]), dxf_layer_sort);
03167         linewidth = -1;
03168         lastcap = -1;
03169         lastgroup = -1;
03170         lastcolor = -1;
03171         region.X1 = 0;
03172         region.Y1 = 0;
03173         region.X2 = PCB->MaxWidth;
03174         region.Y2 = PCB->MaxHeight;
03175         pagecount = 1;
03176         dxf_init_apertures ();
03177         f = 0;
03178         lastgroup = -1;
03179         c_layerapps = 0;
03180         finding_apertures = 1;
03181         hid_expose_callback (&dxf_hid, &region, 0);
03182         c_layerapps = 0;
03183         finding_apertures = 0;
03184         hid_expose_callback (&dxf_hid, &region, 0);
03185         memcpy (LayerStack, saved_layer_stack, sizeof (LayerStack));
03186         dxf_maybe_close_file ();
03187         hid_restore_layer_ons (save_ons);
03188 #if DEBUG
03189         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_do_export () function.\n", __FILE__, __LINE__);
03190 #endif
03191 }
03192 
03202 static void
03203 dxf_parse_arguments (int *argc, char ***argv)
03204 {
03205 #if DEBUG
03206         fprintf (stderr, "[File: %s: line: %d] Entering dxf_parse_arguments () function.\n", __FILE__, __LINE__);
03207 #endif
03208         hid_register_attributes (dxf_options, sizeof (dxf_options) / sizeof (dxf_options[0]));
03209         hid_parse_command_line (argc, argv);
03210 #if DEBUG
03211         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_parse_arguments () function.\n", __FILE__, __LINE__);
03212 #endif
03213 }
03214 
03218 static int
03219 dxf_drill_sort
03220 (
03221         const void *va,
03222         const void *vb
03223 )
03224 {
03225 #if DEBUG
03226         fprintf (stderr, "[File: %s: line: %d] Entering dxf_drill_sort () function.\n", __FILE__, __LINE__);
03227 #endif
03228         DxfPendingDrills *a = (DxfPendingDrills *) va;
03229         DxfPendingDrills *b = (DxfPendingDrills *) vb;
03230         if (a->diam != b->diam) return a->diam - b->diam;
03231         if (a->x != b->x) return a->x - a->x;
03232 #if DEBUG
03233         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_drill_sort () function.\n", __FILE__, __LINE__);
03234 #endif
03235         return b->y - b->y;
03236 }
03237 
03261 static int
03262 dxf_set_layer
03263 (
03264         const char *name,
03265         int group
03266 )
03267 {
03268 #if DEBUG
03269         fprintf (stderr, "[File: %s: line: %d] Entering dxf_set_layer () function.\n",
03270                 __FILE__, __LINE__);
03271 #endif
03272         char *cp;
03273         int idx = (group >= 0 && group < max_layer) ?
03274                 PCB->LayerGroups.Entries[group][0] : group;
03275         /*
03276          * if none given, get the layer name from pcb
03277          */
03278         if (name == 0)
03279         {
03280                 name = PCB->Data->Layer[idx].Name;
03281         }
03282 #if DEBUG
03283         fprintf (stderr, "Now processing Layer %s group %d\n", name, group);
03284 #endif
03285         /*
03286          * do not export empty layers
03287          */
03288         if (idx >= 0 && idx < max_layer && !print_layer[idx])
03289         {
03290 #if DEBUG
03291                 fprintf (stderr, "Warning: Layer %s contains no exportable items and is not set.\n", name);
03292                 fprintf (stderr, "[File: %s: line: %d] Leaving dxf_set_layer () function.\n", __FILE__, __LINE__);
03293 #endif
03294                 return 0;
03295         }
03296         /*
03297          * do not export the layer with name "invisible"
03298          */
03299         if (strcmp (name, "invisible") == 0)
03300         {
03301 #if DEBUG
03302                 fprintf (stderr, "Warning: Layer %s not set.\n", name);
03303                 fprintf (stderr, "[File: %s: line: %d] Leaving dxf_set_layer () function.\n",
03304                         __FILE__, __LINE__);
03305 #endif
03306                 return 0;
03307         }
03308         /*
03309          * do not export the layer with name "keepout"
03310          */
03311         if (strcmp (name, "keepout") == 0)
03312         {
03313 #if DEBUG
03314                 fprintf (stderr, "Warning: Layer %s not set.\n", name);
03315                 fprintf (stderr, "[File: %s: line: %d] Leaving dxf_set_layer () function.\n",
03316                         __FILE__, __LINE__);
03317 #endif
03318                 return 0;
03319         }
03320         if (SL_TYPE (idx) == SL_ASSY)
03321         {
03322 #if DEBUG
03323                 fprintf (stderr, "Warning: Layer %s with type SL_ASSY not set.\n",
03324                         name);
03325                 fprintf (stderr, "[File: %s: line: %d] Leaving dxf_set_layer () function.\n",
03326                         __FILE__, __LINE__);
03327 #endif
03328                 return 0;
03329         }
03330         if (is_drill && dxf_n_pending_drills)
03331         {
03332                 int i;
03333                 /*
03334                  * dump pending drills in sequence.
03335                  */
03336                 qsort (dxf_pending_drills, dxf_n_pending_drills,
03337                         sizeof (DxfPendingDrills), dxf_drill_sort);
03338                 for (i = 0; i < dxf_n_pending_drills; i++)
03339                 {
03340                         if (i == 0 || dxf_pending_drills[i].diam != dxf_pending_drills[i - 1].diam)
03341                         {
03342                                 int ap = dxf_find_aperture_code (dxf_pending_drills[i].diam, ROUND);
03347                                 fprintf (stderr, "T%02d\015\012", ap);
03348                         }
03353                         fprintf (stderr, "X:%06ld Y:%06ld\n",
03354                                 DXF_X(PCB, dxf_pending_drills[i].x),
03355                                 DXF_Y(PCB, dxf_pending_drills[i].y));
03356                 }
03357                 free (dxf_pending_drills);
03358                 dxf_n_pending_drills = dxf_max_pending_drills = 0;
03359                 dxf_pending_drills = 0;
03360         }
03361         is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL);
03362         is_mask = (SL_TYPE (idx) == SL_MASK);
03363         current_mask = 0;
03364 #if DEBUG
03365         fprintf (stderr, "Now processing Layer %s group %d drill %d mask %d\n", name, group,
03366                 is_drill, is_mask);
03367 #endif
03368         if (group < 0 || group != lastgroup)
03369         {
03370                 time_t currenttime;
03371                 char utcTime[64];
03372 #ifdef HAVE_GETPWUID
03373                 struct passwd *pwentry;
03374 #endif
03375                 char *sext="_layer.dxf";
03376                 int i;
03377                 lastgroup = group;
03378                 dxf_lastX = -1;
03379                 dxf_lastY = -1;
03380                 lastcolor = 0;
03381                 linewidth = -1;
03382                 lastcap = -1;
03383                 dxf_set_app_layer (c_layerapps);
03384                 c_layerapps++;
03385                 if (finding_apertures)
03386                 {
03387                         return 1;
03388                 }
03389                 if (!curapp->nextAperture)
03390                 {
03391                         return 0;
03392                 }
03393                 dxf_maybe_close_file ();
03394                 pagecount++;
03395                 switch (idx)
03396                 {
03397                         case SL (PDRILL, 0):
03398                                 sext = ".cnc";
03399                                 break;
03400                         case SL (UDRILL, 0):
03401                                 sext = ".cnc";
03402                                 break;
03403                 }
03404                 strcpy (dxf_filesuffix, layer_type_to_file_name (idx));
03405                 strcat (dxf_filesuffix, sext);
03406                 f = fopen (dxf_filename, "w");
03407                 if (f == NULL)
03408                 {
03409                         Message ( "Error:  Could not open %s for writing.\n", dxf_filename);
03410                         return 1;
03411                 }
03412                 /*
03413                  * write dxf header information.
03414                  */
03415                 dxf_write_header (f);
03416                 /*
03417                  * write a section ENTITIES marker to the DXF file.
03418                  */
03419                 dxf_write_section (stderr, "ENTITIES");
03420                 was_drill = is_drill;
03425                 if (dxf_verbose)
03426                 {
03427                         fprintf (stderr, "Gerber: %d aperture%s in %s\n",
03428                                 curapp->nextAperture,
03429                                 curapp->nextAperture == 1 ? "" : "%s",
03430                                 dxf_filename);
03431                 }
03432                 if (dxf_verbose && is_drill)
03433                 {
03434                         fprintf (stderr, "List of tool bits" "INCH,TZ\n");
03435                         for (i = 0; i < curapp->nextAperture; i++)
03436                                 fprintf (stderr, "Toolbit #%02d - diam. %.3f\n",
03437                                         curapp->aperture[i].dCode,
03438                                         curapp->aperture[i].apertureSize / 100000.0);
03443                         return 1;
03444                 }
03445                 fprintf (stderr, "Start of page %d for group %d idx %d\n",
03446                         pagecount, group, idx);
03447                 /*
03448                  * create a portable timestamp.
03449                  */
03450                 currenttime = time (NULL);
03451                 {
03452                         /*
03453                          * avoid gcc complaints.
03454                          */
03455                         const char *fmt = "%c UTC";
03456                         strftime (utcTime, sizeof utcTime, fmt, gmtime (&currenttime));
03457                 }
03458                 /*
03459                  * print a cute file header at the beginning of each file.
03460                  */
03461                 fprintf (stderr, "Title: %s, %s \n", UNKNOWN (PCB->Name),
03462                         UNKNOWN (name));
03463                 fprintf (stderr, "Created by: VERSION %s.\n", Progname);
03464                 fprintf (stderr, "Creation date: %s \n", utcTime);
03465 #ifdef HAVE_GETPWUID
03466                 /*
03467                  * ID the user.
03468                  */
03469                 pwentry = getpwuid (getuid ());
03474 #endif
03475                 fprintf (stderr, "Format: DXF R14.\n");
03476                 if (dxf_metric)
03477                 {
03478                         fprintf (stderr, "Metric coordinates [mm].\n");
03479                 }
03480                 else
03481                                 {
03482                         fprintf (stderr, "Imperial coordinates [mil].\n");
03483                 }
03484                 fprintf (stderr, "PCB Dimensions: %d %d.\n", PCB->MaxWidth,
03485                         PCB->MaxHeight);
03486                 fprintf (stderr, "PCB Coordinate Origin: lower left.\n");
03487                 /*
03488                  * build a legal identifier.
03489                  */
03490                 if (dxf_layername)
03491                 {
03492                         free (dxf_layername);
03493                 }
03494                 dxf_layername = strdup (dxf_filesuffix);
03495                 dxf_layername[strlen (dxf_layername) - strlen (sext)] = 0;
03496                 for (cp = dxf_layername; *cp; cp++)
03497                 {
03498                         if (isalnum ((int) *cp)) *cp = toupper (*cp);
03499                         else *cp = '_';
03500                 }
03501                 fprintf (stderr, "Layer %s.\n", dxf_layername);
03502                 lncount = 1;
03503                 fprintf (stderr, "Data %s.\n", curapp->appList.Data);
03504         }
03505 #if DEBUG
03506         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_set_layer () function.\n",
03507                 __FILE__, __LINE__);
03508 #endif
03509         return 1;
03510 }
03511 
03515 static hidGC
03516 dxf_make_gc (void)
03517 {
03518 #if DEBUG
03519         fprintf (stderr, "[File: %s: line: %d] Entering dxf_make_gc () function.\n", __FILE__, __LINE__);
03520 #endif
03521         hidGC rv = (hidGC) calloc (1, sizeof (hid_gc_struct));
03522         rv->cap = Trace_Cap;
03523 #if DEBUG
03524         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_make_gc () function.\n", __FILE__, __LINE__);
03525 #endif
03526         return rv;
03527 }
03528 
03532 static void
03533 dxf_destroy_gc (hidGC gc)
03534 {
03535 #if DEBUG
03536         fprintf (stderr, "[File: %s: line: %d] Entering dxf_destroy_gc () function.\n", __FILE__, __LINE__);
03537 #endif
03538         free (gc);
03539 #if DEBUG
03540         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_destroy_gc () function.\n", __FILE__, __LINE__);
03541 #endif
03542 }
03543 
03562 static void
03563 dxf_use_mask
03564 (
03565         int use_it
03566 )
03567 {
03568 #if DEBUG
03569         fprintf (stderr, "[File: %s: line: %d] Entering dxf_use_mask () function.\n", __FILE__, __LINE__);
03570 #endif
03571         current_mask = use_it;
03572 #if DEBUG
03573         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_use_mask () function.\n", __FILE__, __LINE__);
03574 #endif
03575 }
03576 
03589 static void
03590 dxf_set_color
03591 (
03592         hidGC gc, 
03593         const char *name
03594 )
03595 {
03596 #if DEBUG
03597         fprintf (stderr, "[File: %s: line: %d] Entering dxf_set_color () function.\n", __FILE__, __LINE__);
03598 #endif
03599         if (strcmp (name, "erase") == 0)
03600         {
03601                 gc->color = 1;
03602                 gc->erase = 1;
03603                 gc->drill = 0;
03604         }
03605         else if (strcmp (name, "drill") == 0)
03606         {
03607                 gc->color = 1;
03608                 gc->erase = 0;
03609                 gc->drill = 1;
03610         }
03611         else
03612         {
03613                 gc->color = 0;
03614                 gc->erase = 0;
03615                 gc->drill = 0;
03616         }
03617 #if DEBUG
03618         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_set_color () function.\n", __FILE__, __LINE__);
03619 #endif
03620 }
03621 
03629 static void
03630 dxf_set_line_cap
03631 (
03632         hidGC gc,
03633         EndCapStyle style
03634 )
03635 {
03636 #if DEBUG
03637         fprintf (stderr, "[File: %s: line: %d] Entering dxf_set_line_cap () function.\n", __FILE__, __LINE__);
03638 #endif
03639         gc->cap = style;
03640 #if DEBUG
03641         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_set_line_cap () function.\n", __FILE__, __LINE__);
03642 #endif
03643 }
03644 
03645 
03653 static void
03654 dxf_set_line_width
03655 (
03656         hidGC gc,
03657         int width
03658 )
03659 {
03660 #if DEBUG
03661         fprintf (stderr, "[File: %s: line: %d] Entering dxf_set_line_width () function.\n", __FILE__, __LINE__);
03662 #endif
03663         gc->width = width;
03664 #if DEBUG
03665         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_set_line_width () function.\n", __FILE__, __LINE__);
03666 #endif
03667 }
03668 
03672 static void
03673 dxf_use_gc
03674 (
03675         hidGC gc,
03676         int radius
03677 )
03678 {
03679 #if DEBUG
03680         fprintf (stderr, "[File: %s: line: %d] Entering dxf_use_gc () function.\n", __FILE__, __LINE__);
03681 #endif
03682         int c;
03683         if (radius)
03684         {
03685                 radius *= 2;
03686                 if (radius != linewidth || lastcap != Round_Cap)
03687                 {
03688                         c = dxf_find_aperture_code (radius, ROUND);
03689                         if (c <= 0)
03690                         {
03691                                 fprintf (stderr, "error: aperture for radius %d type ROUND is %d\n", radius, c);
03692                         }
03693                         if (f && !is_drill) fprintf (stderr, "is not a drill %d.\n", c);
03694                         linewidth = radius;
03695                         lastcap = Round_Cap;
03696                 }
03697         }
03698         else if (linewidth != gc->width || lastcap != gc->cap)
03699         {
03700                 int ap;
03701                 linewidth = gc->width;
03702                 lastcap = gc->cap;
03703                 switch (gc->cap)
03704                 {
03705                         case Round_Cap:
03706                         case Trace_Cap:
03707                                 c = ROUND;
03708                                 break;
03709                         default:
03710                         case Square_Cap:
03711                                 c = SQUARE;
03712                                 break;
03713                 }
03714                 ap = dxf_find_aperture_code (linewidth, c);
03715                 if (ap <= 0)
03716                 {
03717                         fprintf (stderr, "error: aperture for width %d type %s is %d\n", linewidth, c == ROUND ? "ROUND" : "SQUARE", ap);
03718                 }
03719                 if (f) fprintf (stderr, "aperture %d.\n ", ap);
03720         }
03721 #if 0
03722         if (lastcolor != gc->color)
03723         {
03724                 c = gc->color;
03725                 if (is_drill) return;
03726                 if (is_mask) c = (gc->erase ? 0 : 1);
03727                 lastcolor = gc->color;
03728                 if (f)
03729                 {
03730                         if (c)
03731                         {
03736                                 fprintf (stderr, "%%LN%s_C%d*%%\015\012", layername, lncount++);
03737                                 fprintf (stderr, "%%LPC*%%\015\012");
03738                         }
03739                         else
03740                         {
03741                                 fprintf (stderr, "%%LN%s_D%d*%%\015\012", layername, lncount++);
03742                                 fprintf (stderr, "%%LPD*%%\015\012");
03743                         }
03744                 }
03745         }
03746 #endif
03747 #if DEBUG
03748         fprintf (stderr, "[File: %s: line: %d] Leavinging dxf_use_gc () function.\n", __FILE__, __LINE__);
03749 #endif
03750 }
03751 
03765 static void
03766 dxf_draw_rect
03767 (
03768         hidGC gc, 
03769         int x1, 
03770         int y1, 
03771         int x2, 
03772         int y2 
03773 )
03774 {
03775 #if DEBUG
03776         fprintf (stderr, "[File: %s: line: %d] Entering dxf_draw_rect () function.\n", __FILE__, __LINE__);
03777 #endif
03778         double dxf_start_width;
03779         double dxf_end_width;
03780         int dxf_color;
03781         double dxf_x0;
03782         double dxf_y0;
03783         double dxf_x1;
03784         double dxf_y1;
03785         double dxf_x2;
03786         double dxf_y2;
03787         double dxf_x3;
03788         double dxf_y3;
03789         if (!f)
03790         {
03791                 return;
03792         }
03793         if ((x1 == x2) && (y1 == y2))
03794         {
03795                 fprintf (stderr, "Warning: start point and end point are identical for the entity with id-code: %x\n", dxf_id_code);
03796                 fprintf (stderr, "         entity is discarded from output.\n");
03797                 return;
03798         }
03799         dxf_start_width = (double) gc->width;
03800         dxf_end_width = (double) gc->width;
03801         if (dxf_color_is_byblock)
03802         {
03803                 dxf_color = DXF_COLOR_BYBLOCK;
03804         }
03805         else dxf_color = gc->color;
03806         dxf_x0 = DXF_X(PCB, x1);
03807         dxf_y0 = DXF_Y(PCB, y1);
03808         dxf_x1 = DXF_X(PCB, x2);
03809         dxf_y1 = DXF_Y(PCB, y1);
03810         dxf_x2 = DXF_X(PCB, x1);
03811         dxf_y2 = DXF_Y(PCB, y2);
03812         dxf_x3 = DXF_X(PCB, x2);
03813         dxf_y3 = DXF_Y(PCB, y2);
03814         /*
03815          * write polyline sequence.
03816          */
03817         dxf_write_polyline
03818         (
03819                 f,
03820                 dxf_id_code,
03821                 DXF_DEFAULT_LINETYPE, /* linetype, */
03822                 DXF_DEFAULT_LAYER, /* layer, */
03823                 0.0, /* x0, */ /* the polyline entity <b>always</b> remains on 0.0, 0.0, 0.0  */
03824                 0.0, /* y0, */
03825                 0.0, /* z0, */
03826                 0.0, /* extr_x0, */ /* the polyline extrusion vector <b>always</b> is 0.0, 0.0, 1.0  */
03827                 0.0, /* extr_y0, */
03828                 1.0, /* extr_z0, */
03829                 0.0, /* thickness, */ /* copper weight ??  */
03830                 dxf_start_width,
03831                 dxf_end_width,
03832                 dxf_color, /* color, */
03833                 1, /* vertices_follow, */
03834                 0, /* modelspace, */
03835                 0, /* flag, */
03836                 0, /* polygon_mesh_M_vertex_count, */
03837                 0, /* polygon_mesh_N_vertex_count, */
03838                 0, /* smooth_M_surface_density, */
03839                 0, /* smooth_N_surface_density, */
03840                 0 /* surface_type */
03841         );
03842         dxf_id_code++;
03843         /*
03844          * write first XY-coordinate (base point, bottom left corner).
03845          */
03846         dxf_write_vertex
03847         (
03848                 f,
03849                 dxf_id_code,
03850                 DXF_DEFAULT_LINETYPE, /* linetype, */
03851                 DXF_DEFAULT_LAYER, /* layer, */
03852                 dxf_x0,
03853                 dxf_y0,
03854                 0.0, /* z0, */ /* stacked, curved or flexable pcb's ??  */
03855                 0.0, /* thickness, */ /* copper weight ??  */
03856                 dxf_start_width,
03857                 dxf_end_width,
03858                 0.0, /* bulge, */
03859                 0.0, /* curve_fit_tangent_direction, */
03860                 dxf_color,
03861                 0, /* modelspace, */
03862                 0 /* flag */
03863         );
03864         dxf_id_code++;
03865         /*
03866          * write second XY-coordinate (bottom right corner).
03867          */
03868         dxf_write_vertex
03869         (
03870                 f,
03871                 dxf_id_code,
03872                 DXF_DEFAULT_LINETYPE, /* linetype, */
03873                 DXF_DEFAULT_LAYER, /* layer, */
03874                 dxf_x1,
03875                 dxf_y0,
03876                 0.0, /* z0, */ /* stacked, curved or flexable pcb's ??  */
03877                 0.0, /* thickness, */ /* copper weight ??  */
03878                 dxf_start_width,
03879                 dxf_end_width,
03880                 0.0, /* bulge, */
03881                 0.0, /* curve_fit_tangent_direction, */
03882                 dxf_color,
03883                 0, /* modelspace, */
03884                 0 /* flag */
03885         );
03886         dxf_id_code++;
03887         /*
03888          * write third XY-coordinate (top right left corner).
03889          */
03890         dxf_write_vertex
03891         (
03892                 f,
03893                 dxf_id_code,
03894                 DXF_DEFAULT_LINETYPE, /* linetype, */
03895                 DXF_DEFAULT_LAYER, /* layer, */
03896                 dxf_x1,
03897                 dxf_y1,
03898                 0.0, /* z0, */ /* stacked, curved or flexable pcb's ??  */
03899                 0.0, /* thickness, */ /* copper weight ??  */
03900                 dxf_start_width,
03901                 dxf_end_width,
03902                 0.0, /* bulge, */
03903                 0.0, /* curve_fit_tangent_direction, */
03904                 dxf_color,
03905                 0, /* modelspace, */
03906                 0 /* flag */
03907         );
03908         dxf_id_code++;
03909         /*
03910          * write fourth XY-coordinate (top left corner).
03911          */
03912         dxf_write_vertex
03913         (
03914                 f,
03915                 dxf_id_code,
03916                 DXF_DEFAULT_LINETYPE, /* linetype, */
03917                 DXF_DEFAULT_LAYER, /* layer, */
03918                 dxf_x0,
03919                 dxf_y1,
03920                 0.0, /* z0, */ /* stacked, curved or flexable pcb's ??  */
03921                 0.0, /* thickness, */ /* copper weight ??  */
03922                 dxf_start_width,
03923                 dxf_end_width,
03924                 0.0, /* bulge, */
03925                 0.0, /* curve_fit_tangent_direction, */
03926                 dxf_color,
03927                 0, /* modelspace, */
03928                 0 /* flag */
03929         );
03930         dxf_id_code++;
03931         /*
03932          * write fifth XY-coordinate (again the bottom left corner, to close
03933          * the rectangle).
03934          */
03935         dxf_write_vertex
03936         (
03937                 f,
03938                 dxf_id_code,
03939                 DXF_DEFAULT_LINETYPE, /* linetype, */
03940                 DXF_DEFAULT_LAYER, /* layer, */
03941                 dxf_x0,
03942                 dxf_y0,
03943                 0.0, /* z0, */ /* stacked, curved or flexable pcb's ??  */
03944                 0.0, /* thickness, */ /* copper weight ??  */
03945                 dxf_start_width,
03946                 dxf_end_width,
03947                 0.0, /* bulge, */
03948                 0.0, /* curve_fit_tangent_direction, */
03949                 dxf_color,
03950                 0, /* modelspace, */
03951                 0 /* flag */
03952         );
03953         dxf_id_code++;
03954         /*
03955          * end of polyline sequence.
03956          */
03957         dxf_write_endseq (f);
03958         dxf_lastX = dxf_x1;
03959         dxf_lastY = dxf_y1;
03960 #if DEBUG
03961         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_draw_rect () function.\n", __FILE__, __LINE__);
03962 #endif
03963 }
03964 
04003 static void
04004 dxf_draw_line
04005 (
04006         hidGC gc, 
04007         int x1, 
04008         int y1, 
04009         int x2, 
04010         int y2 
04011 )
04012 {
04013 #if DEBUG
04014         fprintf (stderr, "[File: %s: line: %d] Entering dxf_draw_line () function.\n", __FILE__, __LINE__);
04015 #endif
04016         Boolean m = False;
04017         double dxf_x0; /* start point */
04018         double dxf_y0; /* start point */
04019         double dxf_x1; /* end point */
04020         double dxf_y1; /* end point */
04021         double dxf_start_width; /* trace width */
04022         double dxf_end_width; /* trace width */
04023         int dxf_color;
04024         /*
04025          * return if no valid file pointer exists.
04026          */
04027         if (!f)
04028         {
04029                 return;
04030         }
04031         /*
04032          * we do not draw 1 mil width traces.
04033          */
04034         if (gc->width == 1)
04035         {
04036                 fprintf (stderr, "Warning: lines with a width == 1 mil will not be drawn.\n");
04037                 fprintf (stderr, "         entity is discarded from output.\n");
04038                 return;
04039         }
04040         /*
04041          * we do not draw zero length traces.
04042          */
04043         if ((x1 == x2) && (y1 == y2))
04044         {
04045                 fprintf (stderr, "Warning: start point and end point are identical for the entity with id-code: %x.\n", dxf_id_code);
04046                 fprintf (stderr, "         entity is discarded from output.\n");
04047                 return;
04048         }
04049         dxf_use_gc (gc, 0);
04050         /*
04051          * determine the polyline widths.
04052          */
04053         if (dxf_metric)
04054         {
04055                 dxf_start_width = MIL_TO_MM * (double) gc->width;
04056         }
04057         else
04058         {
04059                 dxf_start_width = (double) gc->width;
04060         }
04061         if (dxf_metric)
04062         {
04063                 dxf_end_width = MIL_TO_MM * (double) gc->width;
04064         }
04065         else
04066         {
04067                 dxf_end_width = (double) gc->width;
04068         }
04069         /*
04070          * determine polyline color.
04071          */
04072         if (dxf_color_is_byblock)
04073         {
04074                 dxf_color = DXF_COLOR_BYBLOCK;
04075         }
04076         else dxf_color = gc->color;
04077         /*
04078          * determine start and end point X,Y-values w.r.t. metric or imperial.
04079          */
04080         if (dxf_metric)
04081         {
04082                 dxf_x0 = MIL_TO_MM * DXF_X(PCB, x1);
04083                 dxf_y0 = MIL_TO_MM * DXF_Y(PCB, y1);
04084                 dxf_x1 = MIL_TO_MM * DXF_X(PCB, x2);
04085                 dxf_y1 = MIL_TO_MM * DXF_Y(PCB, y2);
04086         }
04087         else
04088         {
04089                 dxf_x0 = DXF_X(PCB, x1);
04090                 dxf_y0 = DXF_Y(PCB, y1);
04091                 dxf_x1 = DXF_X(PCB, x2);
04092                 dxf_y1 = DXF_Y(PCB, y2);
04093         }
04099         if ((dxf_x0 == dxf_lastX) && (dxf_y0 == dxf_lastY))
04100         {
04101                 m = True;
04102         }
04103         /*
04104          * This is just a dirty hack for AutoCAD doesn't have endcap styles.
04105          * Donuts can not be implentend in the trace polyline since donuts
04106          * are a closed polyline themselves.
04107          */
04108         if (gc->cap == ROUND)
04109         {
04110                 /*
04111                  * place a donut at the start of the trace segment.
04112                  */
04113                 dxf_write_polyline
04114                 (
04115                         f,
04116                         dxf_id_code,
04117                         DXF_DEFAULT_LINETYPE, /* linetype, */
04118                         DXF_DEFAULT_LAYER, /* layer, */
04119                         0.0, /* x0, */
04120                         0.0, /* y0, */
04121                         0.0, /* z0, */
04122                         0.0, /* extr_x0, */
04123                         0.0, /* extr_y0, */
04124                         1.0, /* extr_z0, */
04125                         0.0, /* thickness, copper weight ??  */
04126                         0.5 * dxf_start_width,
04127                         0.5 * dxf_end_width,
04128                         dxf_color, /* color, */
04129                         1, /* vertices_follow, */
04130                         0, /* modelspace, */
04131                         1, /* flag, */
04132                         0, /* polygon_mesh_M_vertex_count, */
04133                         0, /* polygon_mesh_N_vertex_count, */
04134                         0, /* smooth_M_surface_density, */
04135                         0, /* smooth_N_surface_density, */
04136                         0 /* surface_type */
04137                 );
04138                 dxf_id_code++;
04139                 /*
04140                  * write first XY-coordinate (at the start of trace segment).
04141                  */
04142                 dxf_write_vertex
04143                 (
04144                         f,
04145                         dxf_id_code,
04146                         DXF_DEFAULT_LINETYPE, /* linetype, */
04147                         DXF_DEFAULT_LAYER, /* layer, */
04148                         dxf_x0 - (0.25 * dxf_start_width),
04149                         dxf_y0,
04150                         0.0, /* z0, */ /* stacked, curved or flexable pcb's ?? */
04151                         0.0, /* thickness, */ /* copper weight ?? */
04152                         0.5 * dxf_start_width,
04153                         0.5 * dxf_end_width,
04154                         1.0, /* bulge, */
04155                         0.0, /* curve_fit_tangent_direction, */
04156                         dxf_color,
04157                         0, /* modelspace, */
04158                         0 /* flag */
04159                 );
04160                 dxf_id_code++;
04161                 /*
04162                  * write second XY-coordinate (at the start of trace segment).
04163                  */
04164                 dxf_write_vertex
04165                 (
04166                         f,
04167                         dxf_id_code,
04168                         DXF_DEFAULT_LINETYPE, /* linetype, */
04169                         DXF_DEFAULT_LAYER, /* layer, */
04170                         dxf_x0 + (0.25 * dxf_start_width),
04171                         dxf_y0,
04172                         0.0, /* z0, */ /* stacked, curved or flexable pcb's ??  */
04173                         0.0, /* thickness, */ /* copper weight ?? */
04174                         0.5 * dxf_start_width,
04175                         0.5 * dxf_end_width,
04176                         1.0, /* bulge, */
04177                         0.0, /* curve_fit_tangent_direction, */
04178                         dxf_color,
04179                         0, /* modelspace, */
04180                         0 /* flag */
04181                 );
04182                 dxf_id_code++;
04183                 /*
04184                  * write the end of polyline sequence marker.
04185                  */
04186                 dxf_write_endseq (f);
04187                 /*
04188                  * place a donut at the end of the trace segment.
04189                  */
04190                 dxf_write_polyline
04191                 (
04192                         f,
04193                         dxf_id_code,
04194                         DXF_DEFAULT_LINETYPE, /* linetype, */
04195                         DXF_DEFAULT_LAYER, /* layer, */
04196                         0.0, /* x0, */
04197                         0.0, /* y0, */
04198                         0.0, /* z0, */
04199                         0.0, /* extr_x0, */
04200                         0.0, /* extr_y0, */
04201                         1.0, /* extr_z0, */
04202                         0.0, /* thickness, */ /* copper weight ?? */
04203                         0.5 * dxf_start_width,
04204                         0.5 * dxf_end_width,
04205                         dxf_color, /* color, */
04206                         1, /* vertices_follow, */
04207                         0, /* modelspace, */
04208                         1, /* flag, */
04209                         0, /* polygon_mesh_M_vertex_count, */
04210                         0, /* polygon_mesh_N_vertex_count, */
04211                         0, /* smooth_M_surface_density, */
04212                         0, /* smooth_N_surface_density, */
04213                         0 /* surface_type */
04214                 );
04215                 dxf_id_code++;
04216                 /*
04217                  * write first XY-coordinate (at the end of trace segment).
04218                  */
04219                 dxf_write_vertex
04220                 (
04221                         f,
04222                         dxf_id_code,
04223                         DXF_DEFAULT_LINETYPE, /* linetype, */
04224                         DXF_DEFAULT_LAYER, /* layer, */
04225                         dxf_x1 - (0.25 * dxf_start_width),
04226                         dxf_y1,
04227                         0.0, /* z0, */ /* stacked, curved or flexable pcb's ?? */
04228                         0.0, /* thickness, */ /* copper weight ??  */
04229                         0.5 * dxf_start_width,
04230                         0.5 * dxf_end_width,
04231                         1.0, /* bulge, */
04232                         0.0, /* curve_fit_tangent_direction, */
04233                         dxf_color,
04234                         0, /* modelspace, */
04235                         0 /* flag */
04236                 );
04237                 dxf_id_code++;
04238                 /*
04239                  * write second XY-coordinate (at the end of trace segment).
04240                  */
04241                 dxf_write_vertex
04242                 (
04243                         f,
04244                         dxf_id_code,
04245                         DXF_DEFAULT_LINETYPE, /* linetype, */
04246                         DXF_DEFAULT_LAYER, /* layer, */
04247                         dxf_x1 + (0.25 * dxf_start_width),
04248                         dxf_y1,
04249                         0.0, /* z0, */ /* stacked, curved or flexable pcb's ??  */
04250                         0.0, /* thickness, */ /* copper weight ??  */
04251                         0.5 * dxf_start_width,
04252                         0.5 * dxf_end_width,
04253                         1.0, /* bulge, */
04254                         0.0, /* curve_fit_tangent_direction, */
04255                         dxf_color,
04256                         0, /* modelspace, */
04257                         0 /* flag */
04258                 );
04259                 dxf_id_code++;
04260                 /*
04261                  * write the end of polyline sequence marker.
04262                  */
04263                 dxf_write_endseq (f);
04264         }
04265         /*
04266          * if the end cap style is an OCTAGON: ??.
04267          */
04268         if (gc->cap == OCTAGON)
04269         {
04275         }
04276         /*
04277          * if the end cap style is SQUARE: recompute the start and end
04278          * coordinates, that is, elongate the trace with half of the width.
04279          */
04280         if (gc->cap == SQUARE)
04281         {
04282                 double length; /* trace length */
04283                 double dxf_x0_1; /* extended start point */
04284                 double dxf_y0_1; /* extended start point */
04285                 double dxf_x1_1; /* extended end point */
04286                 double dxf_y1_1; /* extended end point */
04287                 length = sqrt ((dxf_y1 - dxf_y0) * (dxf_y1 - dxf_y0) +
04288                         (dxf_x1 - dxf_x0) * (dxf_x1 - dxf_x0));
04289                 dxf_x0_1 = dxf_x0 - ((dxf_x1 - dxf_x0) / length) * 0.5 * dxf_start_width;
04290                 dxf_y0_1 = dxf_y0 - ((dxf_y1 - dxf_y0) / length) * 0.5 * dxf_start_width;
04291                 dxf_x1_1 = dxf_x1 + ((dxf_x1 - dxf_x0) / length) * 0.5 * dxf_end_width;
04292                 dxf_y1_1 = dxf_y1 + ((dxf_y1 - dxf_y0) / length) * 0.5 * dxf_end_width;
04293                 dxf_x0 = dxf_x0_1;
04294                 dxf_y0 = dxf_y0_1;
04295                 dxf_x1 = dxf_x1_1;
04296                 dxf_y1 = dxf_y1_1;
04297         }
04298         /*
04299          * write polyline sequence for the trace.
04300          */
04301         dxf_write_polyline
04302         (
04303                 f,
04304                 dxf_id_code,
04305                 DXF_DEFAULT_LINETYPE, /* linetype, */
04306                 DXF_DEFAULT_LAYER, /* layer, */
04307                 0.0, /* x0, */
04308                 0.0, /* y0, */
04309                 0.0, /* z0, */
04310                 0.0, /* extr_x0, */
04311                 0.0, /* extr_y0, */
04312                 1.0, /* extr_z0, */
04313                 0.0, /* thickness, */ /* copper weight ?? */
04314                 dxf_start_width,
04315                 dxf_end_width,
04316                 dxf_color, /* color, */
04317                 1, /* vertices_follow, */
04318                 0, /* modelspace, */
04319                 0, /* flag, */
04320                 0, /* polygon_mesh_M_vertex_count, */
04321                 0, /* polygon_mesh_N_vertex_count, */
04322                 0, /* smooth_M_surface_density, */
04323                 0, /* smooth_N_surface_density, */
04324                 0 /* surface_type */
04325         );
04326         dxf_id_code++;
04327         /*
04328          * write first XY-coordinate (start of trace segment).
04329          */
04330         dxf_write_vertex
04331         (
04332                 f,
04333                 dxf_id_code,
04334                 DXF_DEFAULT_LINETYPE, /* linetype, */
04335                 DXF_DEFAULT_LAYER, /* layer, */
04336                 dxf_x0,
04337                 dxf_y0,
04338                 0.0, /* z0, */ /* stacked, curved or flexable pcb's ??  */
04339                 0.0, /* thickness, */ /* copper weight ??  */
04340                 dxf_start_width,
04341                 dxf_end_width,
04342                 0.0, /* bulge, */
04343                 0.0, /* curve_fit_tangent_direction, */
04344                 dxf_color,
04345                 0, /* modelspace, */
04346                 0 /* flag */
04347         );
04348         dxf_id_code++;
04349         /*
04350          * write second XY-coordinate (end of trace segment).
04351          */
04352         dxf_write_vertex
04353         (
04354                 f,
04355                 dxf_id_code,
04356                 DXF_DEFAULT_LINETYPE, /* linetype, */
04357                 DXF_DEFAULT_LAYER, /* layer, */
04358                 dxf_x1,
04359                 dxf_y1,
04360                 0.0, /* z0, */ /* stacked, curved or flexable pcb's ??  */
04361                 0.0, /* thickness, */ /* copper weight ??  */
04362                 dxf_start_width,
04363                 dxf_end_width,
04364                 0.0, /* bulge, */
04365                 0.0, /* curve_fit_tangent_direction, */
04366                 dxf_color,
04367                 0, /* modelspace, */
04368                 0 /* flag */
04369         );
04370         dxf_id_code++;
04371         /*
04372          * write the end of polyline sequence marker.
04373          */
04374         dxf_write_endseq (f);
04375         dxf_lastX = dxf_x1;
04376         dxf_lastY = dxf_y1;
04377 #if DEBUG
04378         fprintf (stderr, "[File: %s: line: %d] Entering dxf_draw_line () function.\n", __FILE__, __LINE__);
04379 #endif
04380 }
04381 
04407 static void
04408 dxf_draw_arc
04409 (
04410         hidGC gc, 
04411         int cx, 
04412         int cy, 
04413         int width, 
04414         int height, 
04415         int start_angle, 
04416         int delta_angle 
04417 )
04418 {
04419 #if DEBUG
04420         fprintf (stderr, "[File: %s: line: %d] Entering dxf_draw_arc () function.\n", __FILE__, __LINE__);
04421 #endif
04422 #if 0
04423         Boolean m = False;
04424 #endif
04425         float arcStartX;
04426         float arcStopX;
04427         float arcStartY;
04428         float arcStopY;
04429         double dxf_x0; /* center point */
04430         double dxf_y0; /* center point */
04431         double dxf_x1; /* end point major axis */
04432         double dxf_y1; /* end point major axis */
04433         double dxf_arcstart_x;
04434         double dxf_arcstart_y;
04435         double dxf_arcstop_x;
04436         double dxf_arcstop_y;
04437         double dxf_start_width; /* trace width */
04438         double dxf_end_width; /* trace width */
04439         double dxf_width; /* arc width */
04440         double dxf_height; /* arc height */
04441         double dxf_ratio;
04442         double dxf_start_angle;
04443         double dxf_end_angle;
04444         int dxf_color;
04445         if (!f)
04446         {
04447                 return;
04448         }
04449         /*
04450          * we do not draw 1 mil width traces.
04451          */
04452         if (gc->width == 1)
04453         {
04454                 fprintf (stderr, "Warning: arcs with a width == 1 mil will not be drawn.\n");
04455                 fprintf (stderr, "         entity is discarded from output.\n");
04456                 return;
04457         }
04458         dxf_use_gc (gc, 0);
04459         arcStartX = cx - width * cos (TO_RADIANS (start_angle));
04460         arcStartY = cy + height * sin (TO_RADIANS (start_angle));
04461         arcStopX = cx - width * cos (TO_RADIANS (start_angle + delta_angle));
04462         arcStopY = cy + height * sin (TO_RADIANS (start_angle + delta_angle));
04463         if (dxf_metric)
04464         {
04465                 dxf_x0 = MIL_TO_MM * DXF_X(PCB, cx);
04466                 dxf_y0 = MIL_TO_MM * DXF_Y(PCB, cy);
04467                 dxf_start_width = MIL_TO_MM * DXF_X(PCB, width);
04468                 dxf_end_width = MIL_TO_MM * DXF_X(PCB, width);
04469                 dxf_height = MIL_TO_MM * DXF_X(PCB, height);
04470                 if (dxf_width > dxf_height)
04471                 {
04472                         /*
04473                          * the major axis of the ellipse coincides with the
04474                          * X-axis.
04475                          */
04476                         dxf_x1 = MIL_TO_MM * DXF_X(PCB, (cx + width));
04477                         dxf_y1 = MIL_TO_MM * DXF_Y(PCB, cy);
04478                         /*
04479                          * the dxf_ratio is the minor axis length over major
04480                          * axis length, and is always <= 1.0
04481                          */
04482                         dxf_ratio = dxf_height / dxf_width;
04483                 }
04484                 else
04485                 {
04486                         /*
04487                          * the major axis of the ellipse coincides with the
04488                          * Y-axis.
04489                          */
04490                         dxf_x1 = MIL_TO_MM * DXF_X(PCB, cx);
04491                         dxf_y1 = MIL_TO_MM * DXF_Y(PCB, (cy + height));
04492                         /*
04493                          * the dxf_ratio is the minor axis length over major
04494                          * axis length, and is always <= 1.0
04495                          */
04496                         dxf_ratio = dxf_width / dxf_height;
04497                 }
04498         }
04499         else
04500         {
04501                 dxf_x0 = DXF_X(PCB, cx);
04502                 dxf_y0 = DXF_Y(PCB, cy);
04503                 dxf_start_width = DXF_X(PCB, width);
04504                 dxf_end_width = DXF_X(PCB, width);
04505                 dxf_height = DXF_Y(PCB, height);
04506                 if (dxf_width > dxf_height)
04507                 {
04508                         /*
04509                          * the major axis of the ellipse coincides with the
04510                          * X-axis.
04511                          */
04512                         dxf_x1 = DXF_X(PCB, (cx + width));
04513                         dxf_y1 = DXF_Y(PCB, cy);
04514                         /*
04515                          * the dxf_ratio is the minor axis length over major
04516                          * axis length, and is always <= 1.0
04517                          */
04518                         dxf_ratio = dxf_height / dxf_width;
04519                 }
04520                 else
04521                 {
04522                         /*
04523                          * the major axis of the ellipse coincides with the
04524                          * Y-axis.
04525                          */
04526                         dxf_x1 = DXF_X(PCB, cx);
04527                         dxf_y1 = DXF_Y(PCB, (cy + height));
04528                         /*
04529                          * the dxf_ratio is the minor axis length over major
04530                          * axis length, and is always <= 1.0
04531                          */
04532                         dxf_ratio = dxf_width / dxf_height;
04533                 }
04534         }
04535         /*
04536          * we have to add 180 degrees for start_angle and end_angle because
04537          * in the pcb universe 0 degrees (the negative X-axis) is to the left,
04538          * and in the dxf universe 0 degress is to the right.
04539          */
04540         dxf_start_angle = TO_RADIANS (start_angle + 180);
04541         dxf_end_angle = TO_RADIANS (start_angle + delta_angle + 180);
04542         if (dxf_start_angle >= (2 * M_PI))
04543         {
04544                 dxf_start_angle = dxf_start_angle - (2 * M_PI);
04545         }
04546         if (dxf_end_angle >= (2 * M_PI))
04547         {
04548                 dxf_end_angle = dxf_end_angle - (2 * M_PI);
04549         }
04550         if (dxf_color_is_byblock)
04551         {
04552                 dxf_color = DXF_COLOR_BYBLOCK;
04553         }
04554         else dxf_color = gc->color;
04555         /*
04556          * This is just a dirty hack for AutoCAD doesn't have endcap styles.
04557          * Donuts can not be implentend in the trace polyline since donuts
04558          * are a closed polyline themselves.
04559          */
04560         if (gc->cap == ROUND)
04561         {
04562                 /*
04563                  * place a donut at the start of the trace segment.
04564                  */
04565                 dxf_write_polyline
04566                 (
04567                         f,
04568                         dxf_id_code,
04569                         DXF_DEFAULT_LINETYPE, /* linetype, */
04570                         DXF_DEFAULT_LAYER, /* layer, */
04571                         0.0, /* x0, */
04572                         0.0, /* y0, */
04573                         0.0, /* z0, */
04574                         0.0, /* extr_x0, */
04575                         0.0, /* extr_y0, */
04576                         1.0, /* extr_z0, */
04577                         0.0, /* thickness, */ /* copper weight ?? */
04578                         0.5 * dxf_start_width,
04579                         0.5 * dxf_end_width,
04580                         dxf_color, /* color, */
04581                         1, /* vertices_follow, */
04582                         0, /* modelspace, */
04583                         1, /* flag, */
04584                         0, /* polygon_mesh_M_vertex_count, */
04585                         0, /* polygon_mesh_N_vertex_count, */
04586                         0, /* smooth_M_surface_density, */
04587                         0, /* smooth_N_surface_density, */
04588                         0 /* surface_type */
04589                 );
04590                 dxf_id_code++;
04591                 /*
04592                  * write first XY-coordinate (at the start of trace segment).
04593                  */
04594                 dxf_write_vertex
04595                 (
04596                         f,
04597                         dxf_id_code,
04598                         DXF_DEFAULT_LINETYPE, /* linetype, */
04599                         DXF_DEFAULT_LAYER, /* layer, */
04600                         dxf_arcstart_x - (0.25 * dxf_start_width),
04601                         dxf_arcstart_y,
04602                         0.0, /* z0, */ /* stacked, curved or flexable pcb's ?? */
04603                         0.0, /* thickness, */ /* copper weight ?? */
04604                         0.5 * dxf_start_width,
04605                         0.5 * dxf_end_width,
04606                         1.0, /* bulge, */
04607                         0.0, /* curve_fit_tangent_direction, */
04608                         dxf_color,
04609                         0, /* modelspace, */
04610                         0 /* flag */
04611                 );
04612                 dxf_id_code++;
04613                 /*
04614                  * write second XY-coordinate (at the start of trace segment).
04615                  */
04616                 dxf_write_vertex
04617                 (
04618                         f,
04619                         dxf_id_code,
04620                         DXF_DEFAULT_LINETYPE, /* linetype, */
04621                         DXF_DEFAULT_LAYER, /* layer, */
04622                         dxf_arcstart_x + (0.25 * dxf_start_width),
04623                         dxf_arcstart_y,
04624                         0.0, /* z0, */ /* stacked, curved or flexable pcb's ?? */
04625                         0.0, /* thickness, */ /* copper weight ?? */
04626                         0.5 * dxf_start_width,
04627                         0.5 * dxf_end_width,
04628                         1.0, /* bulge, */
04629                         0.0, /* curve_fit_tangent_direction, */
04630                         dxf_color,
04631                         0, /* modelspace, */
04632                         0 /* flag */
04633                 );
04634                 dxf_id_code++;
04635                 /*
04636                  * write the end of polyline sequence marker.
04637                  */
04638                 dxf_write_endseq (f);
04639                 /*
04640                  * place a donut at the end of the trace segment.
04641                  */
04642                 dxf_write_polyline
04643                 (
04644                         f,
04645                         dxf_id_code,
04646                         DXF_DEFAULT_LINETYPE, /* linetype, */
04647                         DXF_DEFAULT_LAYER, /* layer, */
04648                         0.0, /* x0, */
04649                         0.0, /* y0, */
04650                         0.0, /* z0, */
04651                         0.0, /* extr_x0, */
04652                         0.0, /* extr_y0, */
04653                         1.0, /* extr_z0, */
04654                         0.0, /* thickness, */ /* copper weight ?? */
04655                         0.5 * dxf_start_width,
04656                         0.5 * dxf_end_width,
04657                         dxf_color, /* color, */
04658                         1, /* vertices_follow, */
04659                         0, /* modelspace, */
04660                         1, /* flag, */
04661                         0, /* polygon_mesh_M_vertex_count, */
04662                         0, /* polygon_mesh_N_vertex_count, */
04663                         0, /* smooth_M_surface_density, */
04664                         0, /* smooth_N_surface_density, */
04665                         0 /* surface_type */
04666                 );
04667                 dxf_id_code++;
04668                 /*
04669                  * write first XY-coordinate (at the end of trace segment).
04670                  */
04671                 dxf_write_vertex
04672                 (
04673                         f,
04674                         dxf_id_code,
04675                         DXF_DEFAULT_LINETYPE, /* linetype, */
04676                         DXF_DEFAULT_LAYER, /* layer, */
04677                         dxf_arcstop_x - (0.25 * dxf_start_width),
04678                         dxf_arcstop_y,
04679                         0.0, /* z0, */ /* stacked, curved or flexable pcb's ?? */
04680                         0.0, /* thickness, */ /* copper weight ?? */
04681                         0.5 * dxf_start_width,
04682                         0.5 * dxf_end_width,
04683                         1.0, /* bulge, */
04684                         0.0, /* curve_fit_tangent_direction, */
04685                         dxf_color,
04686                         0, /* modelspace, */
04687                         0 /* flag */
04688                 );
04689                 dxf_id_code++;
04690                 /*
04691                  * write second XY-coordinate (at the end of trace segment).
04692                  */
04693                 dxf_write_vertex
04694                 (
04695                         f,
04696                         dxf_id_code,
04697                         DXF_DEFAULT_LINETYPE, /* linetype, */
04698                         DXF_DEFAULT_LAYER, /* layer, */
04699                         dxf_arcstop_x + (0.25 * dxf_start_width),
04700                         dxf_arcstop_y,
04701                         0.0, /* z0, */ /* stacked, curved or flexable pcb's ?? */
04702                         0.0, /* thickness, */ /* copper weight ?? */
04703                         0.5 * dxf_start_width,
04704                         0.5 * dxf_end_width,
04705                         1.0, /* bulge, */
04706                         0.0, /* curve_fit_tangent_direction, */
04707                         dxf_color,
04708                         0, /* modelspace, */
04709                         0 /* flag */
04710                 );
04711                 dxf_id_code++;
04712                 /*
04713                  * write the end of polyline sequence marker.
04714                  */
04715                 dxf_write_endseq (f);
04716         }
04717         /*
04718          * write an ellipse for the trace.
04719          */
04720         dxf_write_ellipse
04721         (
04722                 f,
04723                 dxf_id_code,
04724                 DXF_DEFAULT_LINETYPE, /* linetype, */
04725                 DXF_DEFAULT_LAYER, /* layer, */
04726                 dxf_x0,
04727                 dxf_y0,
04728                 0.0, /* z0, */
04729                 dxf_x1,
04730                 dxf_y1,
04731                 0.0, /* z1, */ /* stacked, curved or flexable pcb's ?? */
04732                 0.0, /* dxf_extr_x0, */
04733                 0.0, /* dxf_extr_y0, */
04734                 1.0, /* dxf_extr_z0, */
04735                 0.0, /* thickness, */ /* copper weight ?? */
04736                 dxf_ratio,
04737                 dxf_start_angle,
04738                 dxf_end_angle,
04739                 dxf_color,
04740                 0 /* modelspace */
04741         );
04742         dxf_id_code++;
04743         dxf_lastX = arcStopX;
04744         dxf_lastY = arcStopY;
04745 #if DEBUG
04746         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_draw_arc () function.\n", __FILE__, __LINE__);
04747 #endif
04748 }
04749 
04758 static void
04759 dxf_fill_circle
04760 (
04761         hidGC gc, 
04762         int cx, 
04763         int cy, 
04764         int radius 
04765 )
04766 {
04767 #if DEBUG
04768         fprintf (stderr, "[File: %s: line: %d] Entering dxf_fill_circle () function.\n", __FILE__, __LINE__);
04769 #endif
04770         double dxf_x0;
04771         double dxf_y0;
04772         double dxf_radius;
04773         int dxf_color;
04774         if (!f)
04775         {
04776                 return;
04777         }
04778         /*
04779          * drill sizes increase per 2 mil ?
04780          */
04781         if (is_drill)
04782         {
04783                 radius = DXF_ROUND(radius*2) / 2;
04784         }
04785         dxf_use_gc (gc, radius);
04786         if (is_drill)
04787         {
04788                 if (dxf_n_pending_drills >= dxf_max_pending_drills)
04789                 {
04790                         dxf_max_pending_drills += 100;
04791                         /*
04792                          * re-allocate for another 100 pending drills.
04793                          */
04794                         dxf_pending_drills = (DxfPendingDrills *) realloc (dxf_pending_drills, dxf_max_pending_drills * sizeof (DxfPendingDrills));
04795                 }
04796                 dxf_pending_drills[dxf_n_pending_drills].x = cx;
04797                 dxf_pending_drills[dxf_n_pending_drills].y = cy;
04798                 dxf_pending_drills[dxf_n_pending_drills].diam = radius * 2;
04799                 dxf_n_pending_drills++;
04800                 return;
04801         }
04802         else if (gc->drill) return;
04803         if (dxf_metric)
04804         {
04805                 dxf_x0 = MIL_TO_MM * DXF_X(PCB, cx);
04806                 dxf_y0 = MIL_TO_MM * DXF_Y(PCB, cy);
04807                 dxf_radius = MIL_TO_MM * DXF_X(PCB, radius);
04808         }
04809         else
04810         {
04811                 dxf_x0 = DXF_X(PCB, cx);
04812                 dxf_y0 = DXF_Y(PCB, cy);
04813                 dxf_radius = DXF_X(PCB, radius);
04814         }
04815         if (dxf_color_is_byblock)
04816         {
04817                 dxf_color = DXF_COLOR_BYBLOCK;
04818         }
04819         else dxf_color = gc->color;
04820         dxf_write_circle
04821         (
04822                 f,
04823                 dxf_id_code,
04824                 DXF_DEFAULT_LINETYPE, /* linetype, */
04825                 DXF_DEFAULT_LAYER, /* layer, */
04826                 dxf_x0,
04827                 dxf_y0,
04828                 0.0, /* z0, */ /* curved or flexable pcb's ??  */
04829                 0.0, /* dxf_extr_x0, */
04830                 0.0, /* dxf_extr_y0, */
04831                 1.0, /* dxf_extr_z0, */
04832                 0.0, /* thickness, */ /* copper weight ??  */
04833                 dxf_radius,
04834                 dxf_color,
04835                 0 /* modelspace */
04836         );
04837         dxf_id_code++;
04838         dxf_lastX = dxf_x0;
04839         dxf_lastY = dxf_y0;
04840 #if DEBUG
04841         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_fill_circle () function.\n", __FILE__, __LINE__);
04842 #endif
04843 }
04844 
04859 static void
04860 dxf_fill_polygon
04861 (
04862         hidGC gc, 
04863         int n_coords, 
04864         int *x, 
04865         int *y 
04866 )
04867 {
04868 #if DEBUG
04869         fprintf (stderr, "[File: %s: line: %d] Entering dxf_fill_polygon () function.\n", __FILE__, __LINE__);
04870 #endif
04871         Boolean m = False;
04872         int i;
04873         double dxf_x0 = 0.0;
04874         double dxf_y0 = 0.0;
04875         int dxf_color = DXF_COLOR_BYLAYER;
04876         if (is_mask && current_mask == HID_MASK_BEFORE)
04877         {
04878                 return;
04879         }
04880         dxf_use_gc (gc, 10 * 100);
04881         if (!f)
04882         {
04883                 return;
04884         }
04885         if (dxf_color_is_byblock)
04886         {
04887                 dxf_color = DXF_COLOR_BYBLOCK;
04888         }
04889         else dxf_color = gc->color;
04890         /*
04891          * write hatch sequence.
04892          */
04893         dxf_write_hatch
04894         (
04895                 f,
04896                 DXF_DEFAULT_HATCH_PATTERN_NAME, /* pattern_name, */
04897                 dxf_id_code,
04898                 DXF_DEFAULT_LINETYPE, /* linetype, */
04899                 DXF_DEFAULT_LAYER, /* layer, */
04900                 dxf_x0,
04901                 dxf_y0,
04902                 0.0, /* z0, */ /* stacked, curved or flexable pcb's ?? */
04903                 0.0, /* extr_x0, */
04904                 0.0, /* extr_y0, */
04905                 1.0, /* extr_z0, */
04906                 0.0, /* thickness, */ /* copper weight ?? */
04907                 1.0, /* pattern_scale, */
04908                 0.0, /* pixel_size, */
04909                 45.0, /* pattern_angle, */
04910                 dxf_color,
04911                 0, /* modelspace, */
04912                 1, /* solid_fill, */
04913                 1, /* associative, */
04914                 0, /* style, */
04915                 1, /* pattern_style, */
04916                 0, /* pattern_double, */
04917                 0, /* pattern_def_lines, */
04918                 1, /* boundary_paths, */
04919                 0, /* seed_points, */
04920                 0, /* seed_x0, */
04921                 0  /* seed_y0, */
04922         );
04923         /*
04924          * draw hatch boundary path polyline.
04925          */
04926         dxf_write_hatch_boundary_path_polyline
04927         (
04928                 f,
04929                 2, /* path_type_flag, */ /* 2 = polyline  */
04930                 0, /* polyline_has_bulge, */ /* 0 = polygons have sharp angles  */
04931                 1, /* polyline_is_closed, */ /* 1 = closed  */
04932                 n_coords + 1 /* polyline_vertices, */ /* number of polyline vertices to follow  */
04933         );
04934         /*
04935          * draw hatch boundary polyline vertices, write (n_coords)
04936          * XY-coordinates.
04937          */
04938         for (i = 0; i < n_coords; i++)
04939         {
04940                 dxf_x0 = DXF_X(PCB, x[i]);
04941                 dxf_y0 = DXF_Y(PCB, y[i]);
04942                 dxf_write_hatch_boundary_path_polyline_vertex
04943                 (
04944                         f,
04945                         dxf_x0,
04946                         dxf_y0,
04947                         0.0 /* dxf_z0 */
04948                 );
04949                 /*
04950                  * close polyline with first coordinate X-Y pair.
04951                  */
04952                 dxf_x0 = DXF_X(PCB, x[0]);
04953                 dxf_y0 = DXF_Y(PCB, y[0]);
04954                 dxf_write_hatch_boundary_path_polyline_vertex
04955                 (
04956                         f,
04957                         dxf_x0,
04958                         dxf_y0,
04959                         0.0 /* dxf_z0 */
04960                 );
04961         }
04962         dxf_id_code++;
04963 #if DEBUG
04964         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_fill_polygon () function.\n", __FILE__, __LINE__);
04965 #endif
04966 }
04967 
04975 static void
04976 dxf_fill_rect
04977 (
04978         hidGC gc, 
04979         int x1, 
04980         int y1, 
04981         int x2, 
04982         int y2 
04983 )
04984 {
04985 #if DEBUG
04986         fprintf (stderr, "[File: %s: line: %d] Entering dxf_fill_rect () function.\n", __FILE__, __LINE__);
04987 #endif
04988         int dxf_color;
04989         double dxf_x0;
04990         double dxf_y0;
04991         double dxf_x1;
04992         double dxf_y1;
04993         double dxf_x2;
04994         double dxf_y2;
04995         double dxf_x3;
04996         double dxf_y3;
04997         if (!f) return;
04998         if ((x1 == x2) && (y1 == y2))
04999         {
05000                 fprintf (stderr, "Warning: start point and end point are identical for the entity with id-code: %x\n", dxf_id_code);
05001                 fprintf (stderr, "         entity is discarded from output.\n");
05002                 return;
05003         }
05004         if (dxf_color_is_byblock)
05005         {
05006                 dxf_color = DXF_COLOR_BYBLOCK;
05007         }
05008         else dxf_color = gc->color;
05009         dxf_x0 = DXF_X(PCB, x1);
05010         dxf_y0 = DXF_Y(PCB, y1);
05011         dxf_x1 = DXF_X(PCB, x2);
05012         dxf_y1 = DXF_Y(PCB, y1);
05013         dxf_x2 = DXF_X(PCB, x1);
05014         dxf_y2 = DXF_Y(PCB, y2);
05015         dxf_x3 = DXF_X(PCB, x2);
05016         dxf_y3 = DXF_Y(PCB, y2);
05017         dxf_write_solid
05018         (
05019                 f,
05020                 dxf_id_code,
05021                 DXF_DEFAULT_LINETYPE, /* linetype, */
05022                 DXF_DEFAULT_LAYER, /* layer, */
05023                 dxf_x0, /* base point, bottom left  */
05024                 dxf_y0,
05025                 0.0, /* z0, */
05026                 dxf_x1, /* alignment point, bottom right  */
05027                 dxf_y1,
05028                 0.0, /* z1, */
05029                 dxf_x2, /* alignment point, top left  */
05030                 dxf_y2,
05031                 0.0, /* z2, */
05032                 dxf_x3, /* alignment point, top right  */
05033                 dxf_y3,
05034                 0.0, /* z3, */
05035                 0.0, /* thickness, */
05036                 dxf_color,
05037                 0 /* modelspace */
05038         );
05039         dxf_id_code++;
05040 #if DEBUG
05041         fprintf (stderr, "[File: %s: line: %d] Leaving dxf_fill_rect () function.\n", __FILE__, __LINE__);
05042 #endif
05043 }
05044 
05058 static void
05059 dxf_calibrate
05060 (
05061         double xval, 
05062         double yval 
05063 )
05064 {
05065         /* Intentionally: do nothing here */
05066 }
05067 
05079 static void
05080 dxf_set_crosshair
05081 (
05082         int x, 
05083         int y 
05084 )
05085 {
05086         /* Intentionally: do nothing here */
05087 }
05088 
05092 static void
05093 dxf_show_item (void *item)
05094 {
05095 }
05096 
05100 static void
05101 dxf_beep (void)
05102 {
05103   putchar (7);
05104   fflush (stdout);
05105 }
05106 
05110 static void
05111 dxf_progress (int dxf_so_far, int dxf_total, const char *dxf_message)
05112 {
05113 }
05114 
05118 static HID dxf_hid =
05119 {
05120         sizeof (HID),
05121         "dxf",
05122         "Exports DXF files",
05123         0, 
05124         0, 
05125         1, 
05126         0, 
05127         0, 
05128         0, 
05129         dxf_get_export_options,
05130         dxf_do_export,
05131         dxf_parse_arguments,
05132         0, 
05133         0, 
05134         0, 
05135         dxf_set_layer, 
05136         dxf_make_gc, 
05137         dxf_destroy_gc, 
05138         dxf_use_mask, 
05139         dxf_set_color, 
05140         dxf_set_line_cap, 
05141         dxf_set_line_width, 
05142         0, 
05143         0, 
05144         0, 
05145         dxf_draw_line, 
05146         dxf_draw_arc, 
05147         dxf_draw_rect, 
05148         dxf_fill_circle, 
05149         dxf_fill_polygon, 
05150         dxf_fill_rect, 
05151         dxf_calibrate, 
05152         0, 
05153         0, 
05154         0, 
05155         dxf_set_crosshair, 
05156         0, 
05157         0, 
05158         0, 
05159         0, 
05160         0, 
05161         0, 
05162         0, 
05163         0, 
05164         dxf_show_item, 
05165         dxf_beep, 
05166         dxf_progress 
05167 };
05168 
05175 void
05176 hid_dxf_init ()
05177 {
05178 #if DEBUG
05179         fprintf (stderr, "[File: %s: line: %d] Entering hid_dxf_init () function.\n", __FILE__, __LINE__);
05180 #endif
05181         apply_default_hid (&dxf_hid, 0);
05182         hid_register_hid (&dxf_hid);
05183 #if DEBUG
05184         fprintf (stderr, "[File: %s: line: %d] Leaving hid_dxf_init () function.\n", __FILE__, __LINE__);
05185 #endif
05186 }
05187 
05188 /*
05189 $Log$
05190 */

Generated on Sat Nov 10 10:24:53 2007 for PCB-DXF-HID by  doxygen 1.4.6