2 * gEDA - GNU Electronic Design Automation
3 * This file is a part of gerbv.
5 * Copyright (C) 2008 Julian Lamb
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
25 \brief The main code for the Gerber Viewer GUI application and command line processing
49 #include <gdk/gdkkeysyms.h>
59 #include "callbacks.h"
60 #include "interface.h"
64 /* DEBUG printing. #define DEBUG 1 in config.h to use this fcn. */
66 #define dprintf printf("%s(): ", __FUNCTION__); printf
68 #define dprintf if(0) printf
71 #define NUMBER_OF_DEFAULT_COLORS 18
72 #define NUMBER_OF_DEFAULT_TRANSFORMATIONS 20
74 static gerbv_layer_color mainDefaultColors
[NUMBER_OF_DEFAULT_COLORS
] = {
95 static gerbv_user_transformation_t mainDefaultTransformations
[NUMBER_OF_DEFAULT_TRANSFORMATIONS
] = {
96 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
97 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
98 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
99 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
100 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
101 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
102 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
103 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
104 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
105 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
106 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
107 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
108 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
109 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
110 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
111 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
112 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
113 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
114 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
115 {0,0,1,1,0,FALSE
,FALSE
,FALSE
},
118 #ifdef HAVE_GETOPT_LONG
121 const struct option longopts
[] = {
122 /* name has_arg flag val */
123 {"border", required_argument
, NULL
, 'B'},
124 {"dpi", required_argument
, NULL
, 'D'},
125 {"version", no_argument
, NULL
, 'V'},
126 {"origin", required_argument
, NULL
, 'O'},
127 {"window_inch", required_argument
, NULL
, 'W'},
128 {"antialias", no_argument
, NULL
, 'a'},
129 {"background", required_argument
, NULL
, 'b'},
130 {"dump", no_argument
, NULL
, 'd'},
131 {"foreground", required_argument
, NULL
, 'f'},
132 {"help", no_argument
, NULL
, 'h'},
133 {"log", required_argument
, NULL
, 'l'},
134 {"output", required_argument
, NULL
, 'o'},
135 {"project", required_argument
, NULL
, 'p'},
136 {"tools", required_argument
, NULL
, 't'},
137 {"translate", required_argument
, NULL
, 'T'},
138 {"window", required_argument
, NULL
, 'w'},
139 {"export", required_argument
, NULL
, 'x'},
140 {"geometry", required_argument
, &longopt_val
, 1},
141 /* GDK/GDK debug flags to be "let through" */
142 {"gtk-module", required_argument
, &longopt_val
, 2},
143 {"g-fatal-warnings",no_argument
, &longopt_val
, 2},
144 {"gtk-debug", required_argument
, &longopt_val
, 2},
145 {"gtk-no-debug", required_argument
, &longopt_val
, 2},
146 {"gdk-debug", required_argument
, &longopt_val
, 2},
147 {"gdk-no-debug", required_argument
, &longopt_val
, 2},
148 {"display", required_argument
, &longopt_val
, 2},
149 {"sync", no_argument
, &longopt_val
, 2},
150 {"no-xshm", no_argument
, &longopt_val
, 2},
151 {"name", required_argument
, &longopt_val
, 2},
152 {"class", required_argument
, &longopt_val
, 2},
155 #endif /* HAVE_GETOPT_LONG*/
156 const char *opt_options
= "Vadh:B:D:O:W:b:f:l:o:p:t:T:w:x:";
158 /**Global state variable to keep track of what's happening on the screen.
159 Declared extern in gerbv_screen.h
161 gerbv_project_t
*mainProject
;
162 gerbv_screen_t screen
;
164 gboolean logToFileOption
;
165 gchar
*logToFileFilename
;
167 /* ------------------------------------------------------------------ */
169 main_open_project_from_filename(gerbv_project_t
*gerbvProject
, gchar
*filename
)
171 project_list_t
*project_list
, *originalList
;
172 gint i
,maxLayerNumber
= -1;
174 dprintf("Opening project = %s\n", (gchar
*) filename
);
175 originalList
= project_list
= read_project_file(filename
);
178 /* first, get the max layer number in the project list */
179 while (project_list
) {
180 if (project_list
->layerno
> maxLayerNumber
)
181 maxLayerNumber
= project_list
->layerno
;
182 project_list
= project_list
->next
;
184 project_list
= originalList
;
185 /* increase the layer count each time and find (if any) the corresponding entry */
186 for (i
= -1; i
<=maxLayerNumber
; i
++){
187 project_list
= originalList
;
188 while (project_list
) {
189 if (project_list
->layerno
== i
) {
190 GdkColor colorTemplate
= {0,project_list
->rgb
[0],
191 project_list
->rgb
[1],project_list
->rgb
[2]};
193 gerbvProject
->background
= colorTemplate
;
196 gchar
*fullName
= NULL
;
197 gchar
*dirName
= NULL
;
198 gint fileIndex
= gerbvProject
->last_loaded
+ 1;
200 if (!g_path_is_absolute (project_list
->filename
)) {
201 /* build the full pathname to the layer */
202 dirName
= g_path_get_dirname (filename
);
203 fullName
= g_build_filename (dirName
,
204 project_list
->filename
, NULL
);
207 fullName
= g_strdup (project_list
->filename
);
209 if (gerbv_open_image(gerbvProject
, fullName
,
211 project_list
->attr_list
,
212 project_list
->n_attr
, TRUE
) == -1) {
213 GERB_MESSAGE("could not read file: %s", fullName
);
219 * Change color from default to from the project list
221 gerbvProject
->file
[fileIndex
]->color
= colorTemplate
;
222 gerbvProject
->file
[fileIndex
]->transform
.inverted
= project_list
->inverted
;
223 gerbvProject
->file
[fileIndex
]->isVisible
= project_list
->visible
;
227 project_list
= project_list
->next
;
230 project_destroy_project_list (originalList
);
232 * Save project filename for later use
234 if (gerbvProject
->project
) {
235 g_free(gerbvProject
->project
);
236 gerbvProject
->project
= NULL
;
238 gerbvProject
->project
= g_strdup (filename
);
239 if (gerbvProject
->project
== NULL
)
240 GERB_FATAL_ERROR("malloc gerbvProject->project failed\n");
243 GERB_MESSAGE("could not read %s[%d]\n", (gchar
*) filename
,
244 gerbvProject
->last_loaded
);
246 } /* gerbv_open_project_from_filename */
248 /* ------------------------------------------------------------------ */
250 main_save_project_from_filename(gerbv_project_t
*gerbvProject
, gchar
*filename
)
252 project_list_t
*project_list
= NULL
, *tmp
;
254 gchar
*dirName
= g_path_get_dirname (filename
);
256 project_list
= g_new0 (project_list_t
, 1);
257 project_list
->next
= project_list
;
258 project_list
->layerno
= -1;
259 project_list
->filename
= g_strdup(gerbvProject
->path
);
260 project_list
->rgb
[0] = gerbvProject
->background
.red
;
261 project_list
->rgb
[1] = gerbvProject
->background
.green
;
262 project_list
->rgb
[2] = gerbvProject
->background
.blue
;
263 project_list
->next
= NULL
;
265 /* loop over all layer files */
266 for (idx
= 0; idx
<= gerbvProject
->last_loaded
; idx
++) {
267 if (gerbvProject
->file
[idx
]) {
268 tmp
= g_new0 (project_list_t
, 1);
269 tmp
->next
= project_list
;
272 /* figure out the relative path to the layer from the project
274 if (strncmp (dirName
, gerbvProject
->file
[idx
]->fullPathname
, strlen(dirName
)) == 0) {
275 /* skip over the common dirname and the separator */
276 tmp
->filename
= g_strdup(gerbvProject
->file
[idx
]->fullPathname
+ strlen(dirName
) + 1);
278 /* if we can't figure out a relative path, just save the
280 tmp
->filename
= g_strdup(gerbvProject
->file
[idx
]->fullPathname
);
282 tmp
->rgb
[0] = gerbvProject
->file
[idx
]->color
.red
;
283 tmp
->rgb
[1] = gerbvProject
->file
[idx
]->color
.green
;
284 tmp
->rgb
[2] = gerbvProject
->file
[idx
]->color
.blue
;
285 tmp
->inverted
= gerbvProject
->file
[idx
]->transform
.inverted
;
286 tmp
->visible
= gerbvProject
->file
[idx
]->isVisible
;
292 if (write_project_file(gerbvProject
, gerbvProject
->project
, project_list
)) {
293 GERB_MESSAGE("Failed to write project\n");
295 project_destroy_project_list (project_list
);
297 } /* gerbv_save_project_from_filename */
299 /* ------------------------------------------------------------------ */
301 main_save_as_project_from_filename(gerbv_project_t
*gerbvProject
, gchar
*filename
)
305 * Save project filename for later use
307 if (gerbvProject
->project
) {
308 g_free(gerbvProject
->project
);
309 gerbvProject
->project
= NULL
;
311 gerbvProject
->project
= g_strdup(filename
);
312 if (gerbvProject
->project
== NULL
)
313 GERB_FATAL_ERROR("malloc gerbvProject->project failed\n");
314 main_save_project_from_filename (gerbvProject
, filename
);
315 } /* gerbv_save_as_project_from_filename */
318 /* ------------------------------------------------------------------ */
320 main(int argc
, char *argv
[])
324 int req_width
= -1, req_height
= -1;
325 #ifdef HAVE_GETOPT_LONG
326 int req_x
= 0, req_y
= 0;
329 char *project_filename
= NULL
;
330 gboolean exportFromCommandline
= FALSE
, userSuppliedOrigin
=FALSE
, userSuppliedWindow
=FALSE
,
331 userSuppliedAntiAlias
=FALSE
, userSuppliedWindowInPixels
=FALSE
, userSuppliedDpi
=FALSE
;
332 gint layerctr
=0, transformCount
= 0, exportType
= 0;
333 gchar
*exportFilename
= NULL
;
334 gfloat userSuppliedOriginX
=0.0,userSuppliedOriginY
=0.0,userSuppliedDpiX
=72.0, userSuppliedDpiY
=72.0,
335 userSuppliedWidth
=0, userSuppliedHeight
=0, userSuppliedBorder
=0.05;
338 * Setup the screen info. Must do this before getopt, since getopt
339 * eventually will set some variables in screen.
341 memset((void *)&screen
, 0, sizeof(gerbv_screen_t
));
342 screen
.state
= NORMAL
;
344 mainProject
= gerbv_create_project();
345 mainProject
->execname
= g_strdup(argv
[0]);
346 mainProject
->execpath
= g_path_get_dirname(argv
[0]);
348 /* set default rendering mode */
350 /* Cairo seems to render faster on Windows, so use it for default */
351 screenRenderInfo
.renderType
= 2;
353 screenRenderInfo
.renderType
= 0;
356 logToFileOption
= FALSE
;
357 logToFileFilename
= NULL
;
359 * Now process command line flags
362 #ifdef HAVE_GETOPT_LONG
363 (read_opt
= getopt_long(argc
, argv
, opt_options
,
364 longopts
, &longopt_idx
))
366 (read_opt
= getopt(argc
, argv
, opt_options
))
367 #endif /* HAVE_GETOPT_LONG */
371 #ifdef HAVE_GETOPT_LONG
373 /* Only long options like GDK/GTK debug */
374 switch (longopt_val
) {
375 case 0: /* default value if nothing is set */
376 fprintf(stderr
, "Not handled option %s\n", longopts
[longopt_idx
].name
);
378 case 1: /* geometry */
380 req_width
= (int)strtol(optarg
, &rest
, 10);
386 fprintf(stderr
, "Split X and Y parameters with an x\n");
391 req_height
= (int)strtol(rest
, &rest
, 10);
396 if ((rest
[0] == 0) || ((rest
[0] != '-') && (rest
[0] != '+')))
399 req_x
= (int)strtol(rest
, &rest
, 10);
404 if ((rest
[0] == 0) || ((rest
[0] != '-') && (rest
[0] != '+')))
407 req_y
= (int)strtol(rest
, &rest
, 10);
417 #endif /* HAVE_GETOPT_LONG */
419 if (optarg
== NULL
) {
420 fprintf(stderr
, "You must specify the border in the format <alpha>.\n");
423 if (strlen (optarg
) > 10) {
424 fprintf(stderr
, "Specified border is not recognized.\n");
427 sscanf (optarg
,"%f",&userSuppliedBorder
);
428 if (userSuppliedBorder
< 0) {
429 fprintf(stderr
, "Specified border is smaller than zero!\n");
432 userSuppliedBorder
/=100.0;
435 if (optarg
== NULL
) {
436 fprintf(stderr
, "You must give an resolution in the format <DPI X,DPI Y> or <DPI_X_and_Y>.\n");
439 if (strlen (optarg
) > 20) {
440 fprintf(stderr
, "Specified resolution is not recognized.\n");
443 if(strchr(optarg
, 'x')!=NULL
){
444 sscanf (optarg
,"%fx%f",&userSuppliedDpiX
,&userSuppliedDpiY
);
446 sscanf (optarg
,"%f",&userSuppliedDpiX
);
447 userSuppliedDpiY
= userSuppliedDpiX
;
449 if ((userSuppliedDpiX
<= 0) || (userSuppliedDpiY
<= 0)) {
450 fprintf(stderr
, "Specified resolution should be greater than 0.\n");
453 userSuppliedDpi
=TRUE
;
456 if (optarg
== NULL
) {
457 fprintf(stderr
, "You must give an origin in the format <lower_left_X x lower_left_Y>.\n");
460 if (strlen (optarg
) > 20) {
461 fprintf(stderr
, "Specified origin is not recognized.\n");
464 sscanf (optarg
,"%fx%f",&userSuppliedOriginX
,&userSuppliedOriginY
);
465 userSuppliedOrigin
=TRUE
;
468 printf("gerbv version %s\n", VERSION
);
469 printf("Copyright (C) 2001 -- 2008 by Stefan Petersen\n");
470 printf("and the respective original authors listed in the source files.\n");
473 userSuppliedAntiAlias
= TRUE
;
475 case 'b' : // Set background to this color
476 if (optarg
== NULL
) {
477 fprintf(stderr
, "You must give an background color in the hex-format <#RRGGBB>.\n");
480 if ((strlen (optarg
) != 7)||(optarg
[0]!='#')) {
481 fprintf(stderr
, "Specified color format is not recognized.\n");
485 sscanf (optarg
,"#%2x%2x%2x",&r
,&g
,&b
);
486 if ( (r
<0)||(r
>255)||(g
<0)||(g
>255)||(b
<0)||(b
>255)) {
488 fprintf(stderr
, "Specified color values should be between 00 and FF.\n");
491 mainProject
->background
.red
= r
*257;
492 mainProject
->background
.green
= g
*257;
493 mainProject
->background
.blue
= b
*257;
495 case 'f' : // Set layer colors to this color (foreground color)
496 if (optarg
== NULL
) {
497 fprintf(stderr
, "You must give an foreground color in the hex-format <#RRGGBB> or <#RRGGBBAA>.\n");
500 if (((strlen (optarg
) != 7)&&(strlen (optarg
) != 9))||(optarg
[0]!='#')) {
501 fprintf(stderr
, "Specified color format is not recognized.\n");
505 if(strlen(optarg
)==7){
506 sscanf (optarg
,"#%2x%2x%2x",&r
,&g
,&b
);
510 sscanf (optarg
,"#%2x%2x%2x%2x",&r
,&g
,&b
,&a
);
513 if ( (r
<0)||(r
>255)||(g
<0)||(g
>255)||(b
<0)||(b
>255)||(a
<0)||(a
>255) ) {
515 fprintf(stderr
, "Specified color values should be between 0x00 (0) and 0xFF (255).\n");
518 mainDefaultColors
[layerctr
].red
= r
;
519 mainDefaultColors
[layerctr
].green
= g
;
520 mainDefaultColors
[layerctr
].blue
= b
;
521 mainDefaultColors
[layerctr
].alpha
= a
;
523 /* just reset the counter back to 0 if we read too many */
524 if (layerctr
== NUMBER_OF_DEFAULT_COLORS
)
528 if (optarg
== NULL
) {
529 fprintf(stderr
, "You must give a filename to send log to\n");
532 logToFileOption
= TRUE
;
533 logToFileFilename
= optarg
;
536 if (optarg
== NULL
) {
537 fprintf(stderr
, "You must give a filename to export to.\n");
540 exportFilename
= optarg
;
543 if (optarg
== NULL
) {
544 fprintf(stderr
, "You must give a project filename\n");
547 project_filename
= optarg
;
550 if (optarg
== NULL
) {
551 fprintf(stderr
, "You must give a filename to read the tools from.\n");
554 if (!gerbv_process_tools_file(optarg
)) {
555 fprintf(stderr
, "*** ERROR processing tools file \"%s\".\n", optarg
);
556 fprintf(stderr
, "Make sure all lines of the file are formatted like this:\n");
557 fprintf(stderr
, "T01 0.024\nT02 0.032\nT03 0.040\n...\n");
558 fprintf(stderr
, "*** EXITING to prevent erroneous display.\n");
562 case 'T' : // Translate the layer
563 if (optarg
== NULL
) {
564 fprintf(stderr
, "You must give a translation in the format <X,Y>.\n");
567 if (strlen (optarg
) > 30) {
568 fprintf(stderr
, "The translation format is not recognized.\n");
571 float transX
=0, transY
=0;
573 sscanf (optarg
,"%f,%f",&transX
,&transY
);
574 mainDefaultTransformations
[transformCount
].translateX
= transX
;
575 mainDefaultTransformations
[transformCount
].translateY
= transY
;
577 /* just reset the counter back to 0 if we read too many */
578 if (transformCount
== NUMBER_OF_DEFAULT_TRANSFORMATIONS
)
582 userSuppliedWindowInPixels
= TRUE
;
584 if (optarg
== NULL
) {
585 fprintf(stderr
, "You must give a window size in the format <width x height>.\n");
588 if (strlen (optarg
) > 20) {
589 fprintf(stderr
, "Specified window size is not recognized.\n");
592 sscanf (optarg
, "%fx%f", &userSuppliedWidth
, &userSuppliedHeight
);
593 if (((userSuppliedWidth
< 0.001) || (userSuppliedHeight
< 0.001)) ||
594 ((userSuppliedWidth
> 2000) || (userSuppliedHeight
> 2000))) {
595 fprintf(stderr
, "Specified window size is out of bounds.\n");
598 userSuppliedWindow
= TRUE
;
601 if (optarg
== NULL
) {
602 fprintf(stderr
, "You must supply an export type.\n");
605 if (strcmp (optarg
,"png") == 0) {
607 exportFromCommandline
= TRUE
;
609 else if (strcmp (optarg
,"pdf") == 0) {
611 exportFromCommandline
= TRUE
;
612 } else if (strcmp (optarg
,"svg") == 0) {
614 exportFromCommandline
= TRUE
;
615 } else if (strcmp (optarg
,"ps") == 0) {
617 exportFromCommandline
= TRUE
;
619 else if (strcmp (optarg
,"rs274x") == 0) {
621 exportFromCommandline
= TRUE
;
623 else if (strcmp (optarg
,"drill") == 0) {
625 exportFromCommandline
= TRUE
;
628 fprintf(stderr
, "Unrecognized export type.\n");
633 screen
.dump_parsed_image
= 1;
637 #ifdef HAVE_GETOPT_LONG
638 printf("Usage: gerbv [OPTIONS...] [FILE...]\n\n");
639 printf("Available options:\n");
640 printf(" -B, --border=<b> Border around the image in percent of the\n");
641 printf(" width/height. Defaults to 5%%.\n");
642 printf(" -D, --dpi=<XxY>or<R> Resolution (Dots per inch) for the output\n");
643 printf(" bitmap. With the format <XxY>, different\n");
644 printf(" resolutions for X- and Y-direction are used.\n");
645 printf(" With the format <R>, both are the same.\n");
646 printf(" -O, --origin=<XxY> Use the specified coordinates (in inches)\n");
647 printf(" for the lower left corner.\n");
648 printf(" -V, --version Print version of gerbv.\n");
649 printf(" -a, --antialias Use antialiasing for generated bitmap output.\n");
650 printf(" -b, --background=<hex> Use background color <hex> (like #RRGGBB).\n");
651 printf(" -f, --foreground=<hex> Use foreground color <hex> (like #RRGGBB or\n");
652 printf(" #RRGGBBAA for setting the alpha).\n");
653 printf(" Use multiple -f flags to set the color for\n");
654 printf(" multiple layers.\n");
655 printf(" -h, --help Print this help message.\n");
656 printf(" -l, --log=<logfile> Send error messages to <logfile>.\n");
657 printf(" -o, --output=<filename> Export to <filename>\n");
658 printf(" -p, --project=<prjfile> Load project file <prjfile>\n");
659 printf(" -W, --window_inch=<WxH> Window size in inches <WxH> for the\n");
660 printf(" exported image.\n");
661 printf(" -w, --window=<WxH> Window size in pixels <WxH> for the\n");
662 printf(" exported image. Autoscales to fit\n");
663 printf(" if no resolution is specified. If a\n");
664 printf(" resolution is specified, it will clip.\n");
665 printf(" -t, --tools=<toolfile> Read Excellon tools from file <toolfile>.\n");
666 printf(" -T, --translate=<X,Y> Translate the image by <X,Y> (useful for\n");
667 printf(" arranging panels). Use multiple -T flags\n");
668 printf(" for multiple layers.\n");
669 printf(" -x, --export=<png/pdf/ps/svg/ Export a rendered picture to a file with\n");
670 printf(" rs274x/drill> the specified format.\n");
674 printf("Usage: gerbv [OPTIONS...] [FILE...]\n\n");
675 printf("Available options:\n");
676 printf(" -B<b> Border around the image in percent of the\n");
677 printf(" width/height. Defaults to 5%%.\n");
678 printf(" -D<XxY>or<R> Resolution (Dots per inch) for the output\n");
679 printf(" bitmap. With the format <XxY>, different\n");
680 printf(" resolutions for X- and Y-direction are used.\n");
681 printf(" With the format <R>, both are the same.\n");
682 printf(" -O<XxY> Use the specified coordinates (in inches)\n");
683 printf(" for the lower left corner.\n");
684 printf(" -V Print version of gerbv.\n");
685 printf(" -a Use antialiasing for generated bitmap output.\n");
686 printf(" -b<hexcolor> Use background color <hexcolor> (like #RRGGBB)\n");
687 printf(" -f<hexcolor> Use foreground color <hexcolor> (like #RRGGBB or\n");
688 printf(" #RRGGBBAA for setting the alpha).\n");
689 printf(" Use multiple -f flags to set the color for\n");
690 printf(" multiple layers.\n");
691 printf(" -h Print this help message.\n");
692 printf(" -l<logfile> Send error messages to <logfile>\n");
693 printf(" -o<filename> Export to <filename>\n");
694 printf(" -p<prjfile> Load project file <prjfile>\n");
695 printf(" -W<WxH> Window size in inches <WxH> for the\n");
696 printf(" exported image\n");
697 printf(" -w<WxH> Window size in pixels <WxH> for the\n");
698 printf(" exported image. Autoscales to fit\n");
699 printf(" if no resolution is specified. If a\n");
700 printf(" resolution is specified, it will clip.\n");
701 printf(" exported image\n");
702 printf(" -t<toolfile> Read Excellon tools from file <toolfile>\n");
703 printf(" -T<X,Y> Translate the image by <X,Y> (useful for\n");
704 printf(" arranging panels). Use multiple -T flags\n");
705 printf(" for multiple layers.\n");
706 printf(" -x <png/pdf/ps/svg/ Export a rendered picture to a file with\n");
707 printf(" rs274x/drill> the specified format\n");
709 #endif /* HAVE_GETOPT_LONG */
713 printf("Not handled option [%d=%c]\n", read_opt
, read_opt
);
718 * If project is given, load that one and use it for files and colors.
719 * Else load files (eventually) given on the command line.
720 * This limits you to either give files on the commandline or just load
723 if (project_filename
) {
724 printf("Loading project %s...\n", project_filename
);
725 /* calculate the absolute pathname to the project if the user
726 used a relative path */
727 g_free (mainProject
->path
);
728 if (!g_path_is_absolute(project_filename
)) {
729 gchar
*fullName
= g_build_filename (g_get_current_dir (),
730 project_filename
, NULL
);
731 main_open_project_from_filename (mainProject
, fullName
);
732 mainProject
->path
= g_path_get_dirname (fullName
);
735 main_open_project_from_filename (mainProject
, project_filename
);
736 mainProject
->path
= g_path_get_dirname (project_filename
);
739 gint loadedIndex
= 0;
740 for(i
= optind
; i
< argc
; i
++) {
741 g_free (mainProject
->path
);
742 if (!g_path_is_absolute(argv
[i
])) {
743 gchar
*fullName
= g_build_filename (g_get_current_dir (),
745 gerbv_open_layer_from_filename_with_color (mainProject
, fullName
,
746 mainDefaultColors
[loadedIndex
% NUMBER_OF_DEFAULT_COLORS
].red
*257,
747 mainDefaultColors
[loadedIndex
% NUMBER_OF_DEFAULT_COLORS
].green
*257,
748 mainDefaultColors
[loadedIndex
% NUMBER_OF_DEFAULT_COLORS
].blue
*257,
749 mainDefaultColors
[loadedIndex
% NUMBER_OF_DEFAULT_COLORS
].alpha
*257);
750 mainProject
->path
= g_path_get_dirname (fullName
);
753 gerbv_open_layer_from_filename_with_color (mainProject
, argv
[i
],
754 mainDefaultColors
[loadedIndex
% NUMBER_OF_DEFAULT_COLORS
].red
*257,
755 mainDefaultColors
[loadedIndex
% NUMBER_OF_DEFAULT_COLORS
].green
*257,
756 mainDefaultColors
[loadedIndex
% NUMBER_OF_DEFAULT_COLORS
].blue
*257,
757 mainDefaultColors
[loadedIndex
% NUMBER_OF_DEFAULT_COLORS
].alpha
*257);
758 mainProject
->path
= g_path_get_dirname (argv
[i
]);
764 screen
.unit
= GERBV_DEFAULT_UNIT
;
765 if (exportFromCommandline
) {
766 /* load the info struct with the default values */
768 gboolean freeFilename
= FALSE
;
770 if (!exportFilename
) {
771 if (exportType
== 1) {
772 exportFilename
= g_strdup ("output.png");
773 } else if (exportType
== 2) {
774 exportFilename
= g_strdup ("output.pdf");
775 } else if (exportType
== 3) {
776 exportFilename
= g_strdup ("output.svg");
777 } else if (exportType
== 4){
778 exportFilename
= g_strdup ("output.ps");
779 } else if (exportType
== 5){
780 exportFilename
= g_strdup ("output.gbx");
782 exportFilename
= g_strdup ("output.cnc");
787 gerbv_render_size_t bb
;
788 gerbv_render_get_boundingbox(mainProject
, &bb
);
789 // Set origin to the left-bottom corner if it is not specified
790 if(!userSuppliedOrigin
){
791 userSuppliedOriginX
= bb
.left
;
792 userSuppliedOriginY
= bb
.top
;
795 float width
= bb
.right
- userSuppliedOriginX
+ 0.001; // Plus a little extra to prevent from
796 float height
= bb
.bottom
- userSuppliedOriginY
+ 0.001; // missing items due to round-off errors
797 // If the user did not specify a height and width, autoscale w&h till full size from origin.
798 if(!userSuppliedWindow
){
799 userSuppliedWidth
= width
;
800 userSuppliedHeight
= height
;
802 // If size was specified in pixels, and no resolution was specified, autoscale resolution till fit
803 if( (!userSuppliedDpi
)&& userSuppliedWindowInPixels
){
804 userSuppliedDpiX
= MIN(((userSuppliedWidth
-0.5) / width
),((userSuppliedHeight
-0.5) / height
));
805 userSuppliedDpiY
= userSuppliedDpiX
;
806 userSuppliedOriginX
-= 0.5/userSuppliedDpiX
;
807 userSuppliedOriginY
-= 0.5/userSuppliedDpiY
;
811 // Add the border size (if there is one)
812 if(userSuppliedBorder
!=0){
813 // If supplied in inches, add a border around the image
814 if(!userSuppliedWindowInPixels
){
815 userSuppliedOriginX
-= (userSuppliedWidth
*userSuppliedBorder
)/2.0;
816 userSuppliedOriginY
-= (userSuppliedHeight
*userSuppliedBorder
)/2.0;
817 userSuppliedWidth
+= userSuppliedWidth
*userSuppliedBorder
;
818 userSuppliedHeight
+= userSuppliedHeight
*userSuppliedBorder
;
820 // If supplied in pixels, shrink image content for border_size
822 userSuppliedOriginX
-= ((userSuppliedWidth
/userSuppliedDpiX
)*userSuppliedBorder
)/2.0;
823 userSuppliedOriginY
-= ((userSuppliedHeight
/userSuppliedDpiX
)*userSuppliedBorder
)/2.0;
824 userSuppliedDpiX
-= (userSuppliedDpiX
*userSuppliedBorder
);
825 userSuppliedDpiY
-= (userSuppliedDpiY
*userSuppliedBorder
);
829 if(!userSuppliedWindowInPixels
){
830 userSuppliedWidth
*= userSuppliedDpiX
;
831 userSuppliedHeight
*= userSuppliedDpiY
;
834 // Make sure there is something valid in it. It could become negative if
835 // the userSuppliedOrigin is further than the bb.right or bb.top.
836 if(userSuppliedWidth
<=0)
837 userSuppliedWidth
= 1;
838 if(userSuppliedHeight
<=0)
839 userSuppliedHeight
= 1;
842 gerbv_render_info_t renderInfo
= {userSuppliedDpiX
, userSuppliedDpiY
,
843 userSuppliedOriginX
, userSuppliedOriginY
, userSuppliedAntiAlias
?3:2,
844 userSuppliedWidth
,userSuppliedHeight
};
846 if (exportType
== 1) {
847 gerbv_export_png_file_from_project (mainProject
, &renderInfo
, exportFilename
);
848 } else if (exportType
== 2) {
849 gerbv_export_pdf_file_from_project (mainProject
, &renderInfo
, exportFilename
);
850 } else if (exportType
== 3) {
851 gerbv_export_svg_file_from_project (mainProject
, &renderInfo
, exportFilename
);
852 } else if (exportType
== 4) {
853 gerbv_export_postscript_file_from_project (mainProject
, &renderInfo
, exportFilename
);
854 } else if (exportType
== 5) {
855 if (mainProject
->file
[0]->image
) {
856 gerbv_image_t
*exportImage
;
857 exportImage
= gerbv_image_duplicate_image (mainProject
->file
[0]->image
, &mainDefaultTransformations
[0]);
858 /* if we have more than one file, we need to merge them before exporting */
859 for(i
= mainProject
->last_loaded
; i
> 0; i
--) {
860 if (mainProject
->file
[i
]) {
861 gerbv_image_copy_image (mainProject
->file
[i
]->image
, &mainDefaultTransformations
[i
], exportImage
);
864 gerbv_export_rs274x_file_from_image (exportFilename
, exportImage
,
865 &mainProject
->file
[0]->transform
);
866 gerbv_destroy_image (exportImage
);
869 fprintf(stderr
, "A valid file was not loaded.\n");
872 } else if (exportType
== 6) {
873 if (mainProject
->file
[0]->image
) {
874 gerbv_image_t
*exportImage
;
875 exportImage
= gerbv_image_duplicate_image (mainProject
->file
[0]->image
, &mainDefaultTransformations
[0]);
876 /* if we have more than one file, we need to merge them before exporting */
877 for(i
= mainProject
->last_loaded
; i
> 0; i
--) {
878 if (mainProject
->file
[i
]) {
879 gerbv_image_copy_image (mainProject
->file
[i
]->image
, &mainDefaultTransformations
[i
], exportImage
);
882 gerbv_export_drill_file_from_image (exportFilename
, exportImage
,
883 &mainProject
->file
[0]->transform
);
884 gerbv_destroy_image (exportImage
);
887 fprintf(stderr
, "A valid file was not loaded.\n");
893 free (exportFilename
);
894 /* exit now and don't start up gtk if this is a command line export */
897 gtk_init (&argc
, &argv
);
898 interface_create_gui (req_width
, req_height
);
900 /* we've exited the GTK loop, so free all resources */
901 render_free_screen_resources();
902 gerbv_destroy_project (mainProject
);