gerbv  2.10.1-dev~93f1b5
main.c
Go to the documentation of this file.
1 /*
2  * gEDA - GNU Electronic Design Automation
3  * This file is a part of gerbv.
4  *
5  * Copyright (C) 2008 Julian Lamb
6  *
7  * $Id$
8  *
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.
13  *
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.
18  *
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
22  */
23 
29 #include "gerbv.h"
30 
31 #include <assert.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <math.h>
36 
37 #ifdef WIN32
38 #include <windows.h>
39 #endif
40 
41 #ifdef HAVE_STRING_H
42 #include <string.h>
43 #endif
44 
45 #ifdef HAVE_UNISTD_H
46 #include <unistd.h>
47 #endif
48 
49 #ifdef HAVE_GETOPT_H
50 #include <getopt.h>
51 #endif
52 
53 #include "common.h"
54 #include "main.h"
55 #include "callbacks.h"
56 #include "interface.h"
57 #include "render.h"
58 #include "project.h"
59 
60 #if (DEBUG)
61 #define dprintf \
62  printf("%s(): ", __FUNCTION__); \
63  printf
64 #else
65 #define dprintf \
66  if (0) \
67  printf
68 #endif
69 
70 #define NUMBER_OF_DEFAULT_COLORS 18
71 #define NUMBER_OF_DEFAULT_TRANSFORMATIONS 20
72 
73 static void gerbv_print_help(void);
74 
75 static int
76 getopt_configured(int argc, char* const argv[], const char* optstring, const struct option* longopts, int* longindex);
77 static int getopt_lengh_unit(const char* optarg, double* input_div, gerbv_screen_t* screen);
78 
79 static gerbv_layer_color mainDefaultColors[NUMBER_OF_DEFAULT_COLORS] = {
80  {115, 115, 222, 177},
81  {255, 127, 115, 177},
82  {193, 0, 224, 177},
83  {117, 242, 103, 177},
84  { 0, 195, 195, 177},
85  {213, 253, 51, 177},
86  {209, 27, 104, 177},
87  {255, 197, 51, 177},
88  {186, 186, 186, 177},
89  {211, 211, 255, 177},
90  {253, 210, 206, 177},
91  {236, 194, 242, 177},
92  {208, 249, 204, 177},
93  {183, 255, 255, 177},
94  {241, 255, 183, 177},
95  {255, 202, 225, 177},
96  {253, 238, 197, 177},
97  {226, 226, 226, 177}
98 };
99 
100 static gerbv_user_transformation_t mainDefaultTransformations[NUMBER_OF_DEFAULT_TRANSFORMATIONS] = {
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},
116  {0, 0, 1, 1, 0, FALSE, FALSE, FALSE},
117  {0, 0, 1, 1, 0, FALSE, FALSE, FALSE},
118  {0, 0, 1, 1, 0, FALSE, FALSE, FALSE},
119  {0, 0, 1, 1, 0, FALSE, FALSE, FALSE},
120  {0, 0, 1, 1, 0, FALSE, FALSE, FALSE},
121 };
122 
123 #ifdef HAVE_GETOPT_LONG
124 int longopt_val = 0;
125 int longopt_idx = 0;
126 const struct option longopts[] = {
127  /* name has_arg flag val */
128  { "border", required_argument, NULL, 'B'},
129  { "dpi", required_argument, NULL, 'D'},
130  { "version", no_argument, NULL, 'V'},
131  { "origin", required_argument, NULL, 'O'},
132  { "window_inch", required_argument, NULL, 'W'},
133  { "antialias", no_argument, NULL, 'a'},
134  { "background", required_argument, NULL, 'b'},
135  { "dump", no_argument, NULL, 'd'},
136  { "foreground", required_argument, NULL, 'f'},
137  { "rotate", required_argument, NULL, 'r'},
138  { "mirror", required_argument, NULL, 'm'},
139  { "help", no_argument, NULL, 'h'},
140  { "log", required_argument, NULL, 'l'},
141  { "output", required_argument, NULL, 'o'},
142  { "project", required_argument, NULL, 'p'},
143  { "tools", required_argument, NULL, 't'},
144  { "translate", required_argument, NULL, 'T'},
145  { "units", required_argument, NULL, 'u'},
146  { "window", required_argument, NULL, 'w'},
147  { "export", required_argument, NULL, 'x'},
148  { "geometry", required_argument, &longopt_val, 1},
149  /* GDK/GDK debug flags to be "let through" */
150  { "gtk-module", required_argument, &longopt_val, 2},
151  {"g-fatal-warnings", no_argument, &longopt_val, 2},
152  { "gtk-debug", required_argument, &longopt_val, 2},
153  { "gtk-no-debug", required_argument, &longopt_val, 2},
154  { "gdk-debug", required_argument, &longopt_val, 2},
155  { "gdk-no-debug", required_argument, &longopt_val, 2},
156  { "display", required_argument, &longopt_val, 2},
157  { "sync", no_argument, &longopt_val, 2},
158  { "no-xshm", no_argument, &longopt_val, 2},
159  { "name", required_argument, &longopt_val, 2},
160  { "class", required_argument, &longopt_val, 2},
161  { 0, 0, 0, 0},
162 };
163 #endif /* HAVE_GETOPT_LONG*/
164 const char* opt_options = "VadhB:D:O:W:b:f:r:m:l:o:p:t:T:u:w:x:";
165 
170 gerbv_screen_t screen;
171 
172 gboolean logToFileOption;
173 gchar* logToFileFilename;
174 
175 /* Coords like "0x2" parsed by "%fx%f" will result in first number = 2 and
176  second number 0. Replace 'x' in coordinate string with ';'*/
177 static void
178 care_for_x_in_cords(char* string) {
179  char* found;
180  found = strchr(string, 'x');
181  if (!found)
182  found = strchr(string, 'X');
183  if (found)
184  *found = ';';
185 }
186 
187 /* ------------------------------------------------------------------ */
188 void
189 main_open_project_from_filename(gerbv_project_t* gerbvProject, gchar* filename) {
190  project_list_t * list, *plist;
191  gint i, max_layer_num = -1;
192  gerbv_fileinfo_t* file_info;
193 
194  dprintf("Opening project = %s\n", (gchar*)filename);
195  list = read_project_file(filename);
196 
197  if (!list) {
198  GERB_COMPILE_WARNING(_("Could not read \"%s\" (loaded %d)"), (gchar*)filename, gerbvProject->last_loaded);
199 
200  return;
201  }
202 
203  /* Get the max layer number in the project list */
204  plist = list;
205  while (plist) {
206  if (plist->layerno > max_layer_num)
207  max_layer_num = plist->layerno;
208 
209  plist = plist->next;
210  }
211 
212  /* Increase the layer count each time and find (if any) the
213  * corresponding entry */
214  for (i = -1; i <= max_layer_num; i++) {
215  plist = list;
216  while (plist) {
217  if (plist->layerno != i) {
218  plist = plist->next;
219  continue;
220  }
221 
222  GdkColor colorTemplate = { 0, plist->rgb[0], plist->rgb[1], plist->rgb[2] };
223  if (i == -1) {
224  screen.background_is_from_project = TRUE;
225  gerbvProject->background = colorTemplate;
226  plist = plist->next;
227  continue;
228  }
229 
230  gchar* fullName = NULL;
231  gchar* dirName = NULL;
232  gint fileIndex = gerbvProject->last_loaded + 1;
233 
234  if (!g_path_is_absolute(plist->filename)) {
235  /* Build the full pathname to the layer */
236  dirName = g_path_get_dirname(filename);
237  fullName = g_build_filename(dirName, plist->filename, NULL);
238  } else {
239  fullName = g_strdup(plist->filename);
240  }
241 
242  if (gerbv_open_image(gerbvProject, fullName, fileIndex, FALSE, plist->attr_list, plist->n_attr, TRUE)
243  == -1) {
244  GERB_MESSAGE(_("could not read file: %s"), fullName);
245  plist = plist->next;
246  continue;
247  }
248 
249  g_free(dirName);
250  g_free(fullName);
251 
252  /* Change color from default to from the project list */
253  file_info = gerbvProject->file[fileIndex];
254  file_info->color = colorTemplate;
255  file_info->alpha = plist->alpha;
256  file_info->transform.inverted = plist->inverted;
257  file_info->transform.translateX = plist->translate_x;
258  file_info->transform.translateY = plist->translate_y;
259  file_info->transform.rotation = plist->rotation;
260  file_info->transform.scaleX = plist->scale_x;
261  file_info->transform.scaleY = plist->scale_y;
262  file_info->transform.mirrorAroundX = plist->mirror_x;
263  file_info->transform.mirrorAroundY = plist->mirror_y;
264  file_info->isVisible = plist->visible;
265 
266  plist = plist->next;
267  }
268  }
269 
270  project_destroy_project_list(list);
271 
272  /* Save project filename for later use */
273  if (gerbvProject->project) {
274  g_free(gerbvProject->project);
275  gerbvProject->project = NULL;
276  }
277  gerbvProject->project = g_strdup(filename);
278  if (gerbvProject->project == NULL)
279  GERB_FATAL_ERROR("malloc gerbvProject->project failed in %s()", __FUNCTION__);
280 } /* gerbv_open_project_from_filename */
281 
282 /* ------------------------------------------------------------------ */
283 void
284 main_save_project_from_filename(gerbv_project_t* gerbvProject, gchar* filename) {
285  project_list_t * list, *plist;
286  gchar* dirName = g_path_get_dirname(filename);
287  gerbv_fileinfo_t* file_info;
288  int idx;
289 
290  list = g_new0(project_list_t, 1);
291  list->next = NULL;
292  list->layerno = -1;
293  list->filename = g_strdup(gerbvProject->path);
294  list->rgb[0] = gerbvProject->background.red;
295  list->rgb[1] = gerbvProject->background.green;
296  list->rgb[2] = gerbvProject->background.blue;
297 
298  /* loop over all layer files */
299  for (idx = 0; idx <= gerbvProject->last_loaded; idx++) {
300  if (gerbvProject->file[idx]) {
301  plist = g_new0(project_list_t, 1);
302  plist->next = list;
303  plist->layerno = idx;
304 
305  /* figure out the relative path to the layer from the project
306  directory */
307  if (strncmp(dirName, gerbvProject->file[idx]->fullPathname, strlen(dirName)) == 0) {
308  /* skip over the common dirname and the separator */
309  plist->filename = g_strdup(gerbvProject->file[idx]->fullPathname + strlen(dirName) + 1);
310  } else {
311  /* if we can't figure out a relative path, just save the
312  * absolute one */
313  plist->filename = g_strdup(gerbvProject->file[idx]->fullPathname);
314  }
315  file_info = gerbvProject->file[idx];
316  plist->rgb[0] = file_info->color.red;
317  plist->rgb[1] = file_info->color.green;
318  plist->rgb[2] = file_info->color.blue;
319  plist->alpha = file_info->alpha;
320  plist->inverted = file_info->transform.inverted;
321  plist->visible = file_info->isVisible;
322  plist->translate_x = file_info->transform.translateX;
323  plist->translate_y = file_info->transform.translateY;
324  plist->rotation = file_info->transform.rotation;
325  plist->scale_x = file_info->transform.scaleX;
326  plist->scale_y = file_info->transform.scaleY;
327  plist->mirror_x = file_info->transform.mirrorAroundX;
328  plist->mirror_y = file_info->transform.mirrorAroundY;
329  list = plist;
330  }
331  }
332 
333  if (write_project_file(gerbvProject, gerbvProject->project, list)) {
334  GERB_MESSAGE(_("Failed to write project"));
335  }
336  project_destroy_project_list(list);
337  g_free(dirName);
338 } /* gerbv_save_project_from_filename */
339 
340 /* ------------------------------------------------------------------ */
341 void
342 main_save_as_project_from_filename(gerbv_project_t* gerbvProject, gchar* filename) {
343 
344  /*
345  * Save project filename for later use
346  */
347  if (gerbvProject->project) {
348  g_free(gerbvProject->project);
349  gerbvProject->project = NULL;
350  }
351  gerbvProject->project = g_strdup(filename);
352  if (gerbvProject->project == NULL)
353  GERB_FATAL_ERROR("malloc gerbvProject->project failed in %s()", __FUNCTION__);
354  main_save_project_from_filename(gerbvProject, filename);
355 } /* gerbv_save_as_project_from_filename */
356 
357 GArray* log_array_tmp = NULL;
358 
359 /* Temporary log messages handler. It will store log messages before GUI
360  * initialization. */
361 void
362 callbacks_temporary_handle_log_messages(
363  const gchar* log_domain, GLogLevelFlags log_level, const gchar* message, gpointer user_data
364 ) {
365  struct log_struct item;
366 
367  item.domain = g_strdup(log_domain);
368  item.level = log_level;
369  item.message = g_strdup(message);
370  g_array_append_val(log_array_tmp, item);
371 
372  g_log_default_handler(log_domain, log_level, message, user_data);
373 }
374 
375 #ifdef WIN32
376 static void
377 wait_console_for_win(void) {
378  FILE* console = fopen("CONOUT$", "w");
379 
380  fprintf(console, _("\n*** Press Enter to continue ***"));
381  fflush(console);
382 }
383 
384 /* Attach console in application which is build with -mwindows flag */
385 static void
386 attach_console_for_win(void) {
387  if (((HANDLE)_get_osfhandle(fileno(stdout)) == INVALID_HANDLE_VALUE
388  || (HANDLE)_get_osfhandle(fileno(stderr)) == INVALID_HANDLE_VALUE)
389  && AttachConsole(ATTACH_PARENT_PROCESS)) {
390 
391  if ((HANDLE)_get_osfhandle(fileno(stdout)) == INVALID_HANDLE_VALUE)
392  freopen("CONOUT$", "w", stdout);
393 
394  if ((HANDLE)_get_osfhandle(fileno(stderr)) == INVALID_HANDLE_VALUE)
395  freopen("CONOUT$", "w", stderr);
396 
397  atexit(wait_console_for_win);
398  }
399 }
400 #else
401 static void
402 attach_console_for_win(void) {}
403 #endif
404 
405 /* ------------------------------------------------------------------ */
406 int
407 main(int argc, char* argv[]) {
408  int read_opt;
409  int i, r, g, b, a;
410  int req_width = -1, req_height = -1;
411 #ifdef HAVE_GETOPT_LONG
412  char* rest;
413 #endif
414  char* project_filename = NULL;
415  gboolean userSuppliedOrigin = FALSE, userSuppliedWindow = FALSE, userSuppliedAntiAlias = FALSE,
416  userSuppliedWindowInPixels = FALSE, userSuppliedDpi = FALSE;
417  gint layerctr = 0, transformCount = 0;
418  gdouble initial_rotation = 0.0;
419  gdouble input_divisor = 1.0; /* 1.0 for inch */
420  int unit_flag_counter;
421  gboolean initial_mirror_x = FALSE;
422  gboolean initial_mirror_y = FALSE;
423  const gchar* exportFilename = NULL;
424  gfloat userSuppliedOriginX = 0.0, userSuppliedOriginY = 0.0, userSuppliedDpiX = 72.0, userSuppliedDpiY = 72.0,
425  userSuppliedWidth = 0, userSuppliedHeight = 0, userSuppliedBorder = GERBV_DEFAULT_BORDER_COEFF;
426 
427  gerbv_image_t* exportImage;
428 
429  enum exp_type {
430  EXP_TYPE_NONE = -1,
431  EXP_TYPE_PNG,
432  EXP_TYPE_PDF,
433  EXP_TYPE_SVG,
434  EXP_TYPE_PS,
435  EXP_TYPE_RS274X,
436  EXP_TYPE_DRILL,
437  EXP_TYPE_IDRILL,
438  };
439  enum exp_type exportType = EXP_TYPE_NONE;
440  const char* export_type_names[] = { "png", "pdf", "svg", "ps", "rs274x", "drill", "idrill", NULL };
441  const gchar* export_def_file_names[] = { "output.png", "output.pdf", "output.svg", "output.ps",
442  "output.gbx", "output.cnc", "output.ncp", NULL };
443 
444  const gchar* settings_schema_env = "GSETTINGS_SCHEMA_DIR";
445 #ifdef WIN32
446  /* On Windows executable can be not in bin/ dir */
447  const gchar* settings_schema_fallback_dir =
448  "share/glib-2.0/schemas" G_SEARCHPATH_SEPARATOR_S "../share/glib-2.0/schemas";
449 #else
450  const gchar* settings_schema_fallback_dir = "../share/glib-2.0/schemas";
451 #endif
452  gchar* env_val;
453 
454 #if ENABLE_NLS
455  setlocale(LC_ALL, "");
456  bindtextdomain(PACKAGE, LOCALEDIR);
457 #ifdef WIN32
458  bind_textdomain_codeset(PACKAGE, "UTF-8");
459 #endif
460  textdomain(PACKAGE);
461 #endif
462 
463  attach_console_for_win();
464 
465  /*
466  * Setup the screen info. Must do this before getopt, since getopt
467  * eventually will set some variables in screen.
468  */
469  memset((void*)&screen, 0, sizeof(gerbv_screen_t));
470  screen.state = NORMAL;
471  screen.unit = GERBV_DEFAULT_UNIT;
472 
474  mainProject->execname = g_strdup(argv[0]);
475  mainProject->execpath = g_path_get_dirname(argv[0]);
476 
477  /* Add "fallback" directory with settings schema file from this
478  * executable path */
479  if (NULL == g_getenv(settings_schema_env))
480  /* Empty env var */
481  env_val = g_strconcat(mainProject->execpath, G_DIR_SEPARATOR_S, settings_schema_fallback_dir, NULL);
482  else
483  /* Not empty env var */
484  env_val = g_strconcat(
485  g_getenv(settings_schema_env), G_SEARCHPATH_SEPARATOR_S, mainProject->execpath, G_DIR_SEPARATOR_S,
486  settings_schema_fallback_dir, NULL
487  );
488  g_setenv(settings_schema_env, env_val, TRUE);
489  g_free(env_val);
490 
491  /* set default rendering mode */
492 #ifdef WIN32
493  /* Cairo seems to render faster on Windows, so use it for default */
494  screenRenderInfo.renderType = GERBV_RENDER_TYPE_CAIRO_NORMAL;
495 #else
496  screenRenderInfo.renderType = GERBV_RENDER_TYPE_GDK;
497 #endif
498 
499  logToFileOption = FALSE;
500  logToFileFilename = NULL;
501 
502  log_array_tmp = g_array_new(TRUE, FALSE, sizeof(struct log_struct));
503  g_log_set_handler(
504  NULL, G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION | G_LOG_LEVEL_MASK, callbacks_temporary_handle_log_messages, NULL
505  );
506 
507  /* 1. Process "length unit" command line flag */
508  unit_flag_counter = 0;
509  opterr = 0; /* Disable getopt() error messages */
510  while (-1 != (read_opt = getopt_configured(argc, argv, opt_options, longopts, &longopt_idx))) {
511  switch (read_opt) {
512  case 'u':
513  unit_flag_counter++;
514 
515  if (!getopt_lengh_unit(optarg, &input_divisor, &screen))
516  GERB_COMPILE_WARNING(_("Unrecognized length unit \"%s\" in command line"), optarg);
517 
518  break;
519  }
520  }
521 
522  /* 2. Process all other command line flags */
523  optind = 0; /* Reset getopt() index */
524  opterr = 1; /* Enable getopt() error messages */
525  while (-1 != (read_opt = getopt_configured(argc, argv, opt_options, longopts, &longopt_idx))) {
526  switch (read_opt) {
527 #ifdef HAVE_GETOPT_LONG
528  case 0:
529  /* Only long options like GDK/GTK debug */
530  switch (longopt_val) {
531  case 0: /* default value if nothing is set */
532  GERB_COMPILE_WARNING(
533  _("Not handled option \"%s\" in command line"), longopts[longopt_idx].name
534  );
535  break;
536  case 1: /* geometry */
537  errno = 0;
538  req_width = (int)strtol(optarg, &rest, 10);
539  if (errno) {
540  perror(_("Width"));
541  break;
542  }
543  if (rest[0] != 'x') {
544  fprintf(stderr, _("Split X and Y parameters with an x\n"));
545  break;
546  }
547  rest++;
548  errno = 0;
549  req_height = (int)strtol(rest, &rest, 10);
550  if (errno) {
551  perror(_("Height"));
552  break;
553  }
554  /*
555  if ((rest[0] == 0) || ((rest[0] != '-') && (rest[0] != '+')))
556  break;
557  errno = 0;
558  req_x = (int)strtol(rest, &rest, 10);
559  if (errno) {
560  perror("X");
561  break;
562  }
563  if ((rest[0] == 0) || ((rest[0] != '-') && (rest[0] != '+')))
564  break;
565  errno = 0;
566  req_y = (int)strtol(rest, &rest, 10);
567  if (errno) {
568  perror("Y");
569  break;
570  }
571  */
572  break;
573  default: break;
574  }
575  break;
576 #endif /* HAVE_GETOPT_LONG */
577  case 'B':
578  if (optarg == NULL) {
579  fprintf(stderr, _("You must specify the border in the format <alpha>.\n"));
580  exit(1);
581  }
582  if (strlen(optarg) > 10) {
583  fprintf(stderr, _("Specified border is not recognized.\n"));
584  exit(1);
585  }
586  sscanf(optarg, "%f", &userSuppliedBorder);
587  if (userSuppliedBorder < 0) {
588  fprintf(stderr, _("Specified border is smaller than zero!\n"));
589  exit(1);
590  }
591  userSuppliedBorder /= 100.0;
592  break;
593  case 'D':
594  if (optarg == NULL) {
595  fprintf(stderr, _("You must give an resolution in the format <DPI_XxDPI_Y> or <DPI_X_and_Y>.\n"));
596  exit(1);
597  }
598  if (strlen(optarg) > 20) {
599  fprintf(stderr, _("Specified resolution is not recognized.\n"));
600  exit(1);
601  }
602  if (strchr(optarg, 'x') != NULL) {
603  sscanf(optarg, "%fx%f", &userSuppliedDpiX, &userSuppliedDpiY);
604  } else {
605  sscanf(optarg, "%f", &userSuppliedDpiX);
606  userSuppliedDpiY = userSuppliedDpiX;
607  }
608  if ((userSuppliedDpiX <= 0) || (userSuppliedDpiY <= 0)) {
609  fprintf(stderr, _("Specified resolution should be greater than 0.\n"));
610  exit(1);
611  }
612  userSuppliedDpi = TRUE;
613  break;
614  case 'O':
615  if (optarg == NULL) {
616  fprintf(
617  stderr, _("You must give an origin in the format "
618  "<XxY> or <X;Y>.\n")
619  );
620  exit(1);
621  }
622  if (strlen(optarg) > 20) {
623  fprintf(stderr, _("Specified origin is not recognized.\n"));
624  exit(1);
625  }
626 
627  care_for_x_in_cords(optarg);
628  sscanf(optarg, "%f;%f", &userSuppliedOriginX, &userSuppliedOriginY);
629  userSuppliedOriginX /= input_divisor;
630  userSuppliedOriginY /= input_divisor;
631  userSuppliedOrigin = TRUE;
632  break;
633  case 'V':
634  printf(_("gerbv version %s\n"), VERSION);
635  printf(
636  _("Copyright (C) 2001-2008 by Stefan Petersen\n"
637  "and the respective original authors listed in the source files.\n")
638  );
639  exit(0);
640  case 'a': userSuppliedAntiAlias = TRUE; break;
641  case 'b': // Set background to this color
642  if (optarg == NULL) {
643  fprintf(
644  stderr, _("You must give an background color "
645  "in the hex-format <#RRGGBB>.\n")
646  );
647  exit(1);
648  }
649  if ((strlen(optarg) != 7) || (optarg[0] != '#')) {
650  fprintf(
651  stderr, _("Specified color format "
652  "is not recognized.\n")
653  );
654  exit(1);
655  }
656  r = g = b = -1;
657  sscanf(optarg, "#%2x%2x%2x", &r, &g, &b);
658  if ((r < 0) || (r > 255) || (g < 0) || (g > 255) || (b < 0) || (b > 255)) {
659 
660  fprintf(
661  stderr, _("Specified color values should be "
662  "between 00 and FF.\n")
663  );
664  exit(1);
665  }
666 
667  screen.background_is_from_cmdline = TRUE;
668  mainProject->background.red = r * 257;
669  mainProject->background.green = g * 257;
670  mainProject->background.blue = b * 257;
671 
672  break;
673  case 'f': // Set layer colors to this color (foreground color)
674  if (optarg == NULL) {
675  fprintf(
676  stderr, _("You must give an foreground color in the hex-format <#RRGGBB> or <#RRGGBBAA>.\n")
677  );
678  exit(1);
679  }
680  if (((strlen(optarg) != 7) && (strlen(optarg) != 9)) || (optarg[0] != '#')) {
681  fprintf(stderr, _("Specified color format is not recognized.\n"));
682  exit(1);
683  }
684  r = g = b = a = -1;
685  if (strlen(optarg) == 7) {
686  sscanf(optarg, "#%2x%2x%2x", &r, &g, &b);
687  a = 177;
688  } else {
689  sscanf(optarg, "#%2x%2x%2x%2x", &r, &g, &b, &a);
690  }
691 
692  if ((r < 0) || (r > 255) || (g < 0) || (g > 255) || (b < 0) || (b > 255) || (a < 0) || (a > 255)) {
693 
694  fprintf(stderr, _("Specified color values should be between 0x00 (0) and 0xFF (255).\n"));
695  exit(1);
696  }
697  mainDefaultColors[layerctr].red = r;
698  mainDefaultColors[layerctr].green = g;
699  mainDefaultColors[layerctr].blue = b;
700  mainDefaultColors[layerctr].alpha = a;
701  layerctr++;
702  /* just reset the counter back to 0 if we read too many */
703  if (layerctr == NUMBER_OF_DEFAULT_COLORS)
704  layerctr = 0;
705  break;
706  case 'r': // Set initial orientation for all layers (rotation)
707  if (optarg == NULL) {
708  fprintf(stderr, _("You must give the initial rotation angle\n"));
709  exit(1);
710  }
711  errno = 0;
712  initial_rotation = (gdouble)strtod(optarg, &rest);
713  if (errno) {
714  perror(_("Rotate"));
715  exit(1);
716  }
717  if (*rest) {
718  fprintf(stderr, _("Failed parsing rotate value\n"));
719  exit(1);
720  }
721  break;
722  case 'm': // Set initial mirroring state for all layers
723  if (optarg == NULL) {
724  fprintf(stderr, _("You must give the axis to mirror about\n"));
725  exit(1);
726  }
727  if (strchr(optarg, 'x') != NULL || strchr(optarg, 'X') != NULL) {
728  initial_mirror_x = TRUE;
729  }
730  if (strchr(optarg, 'y') != NULL || strchr(optarg, 'Y') != NULL) {
731  initial_mirror_y = TRUE;
732  }
733  if (!(initial_mirror_x || initial_mirror_y)) {
734  fprintf(stderr, _("Failed parsing mirror axis\n"));
735  exit(1);
736  }
737  break;
738  case 'l':
739  if (optarg == NULL) {
740  fprintf(stderr, _("You must give a filename to send log to\n"));
741  exit(1);
742  }
743  logToFileOption = TRUE;
744  logToFileFilename = optarg;
745  break;
746  case 'o':
747  if (optarg == NULL) {
748  fprintf(stderr, _("You must give a filename to export to.\n"));
749  exit(1);
750  }
751  exportFilename = optarg;
752  break;
753  case 'p':
754  if (optarg == NULL) {
755  fprintf(stderr, _("You must give a project filename\n"));
756  exit(1);
757  }
758  project_filename = optarg;
759  break;
760  case 't':
761  if (optarg == NULL) {
762  fprintf(stderr, _("You must give a filename to read the tools from.\n"));
763  exit(1);
764  }
765  if (!gerbv_process_tools_file(optarg)) {
766  fprintf(stderr, _("*** ERROR processing tools file \"%s\".\n"), optarg);
767  fprintf(
768  stderr, _("Make sure all lines of the file are formatted like this:\n"
769  "T01 0.024\nT02 0.032\nT03 0.040\n...\n"
770  "*** EXITING to prevent erroneous display.\n")
771  );
772  exit(1);
773  }
774  break;
775  case 'T': // Translate the layer
776  if (optarg == NULL) {
777  fprintf(
778  stderr, _("You must give a translation in the format "
779  "<XxY> or <X;Y>.\n")
780  );
781  exit(1);
782  }
783  if (strlen(optarg) > 30) {
784  fprintf(stderr, _("The translation format is not recognized.\n"));
785  exit(1);
786  }
787 
788  float transX = 0, transY = 0, rotate = 0;
789 
790  care_for_x_in_cords(optarg);
791  sscanf(optarg, "%f;%fr%f", &transX, &transY, &rotate);
792  transX /= input_divisor;
793  transY /= input_divisor;
794  mainDefaultTransformations[transformCount].translateX = transX;
795  mainDefaultTransformations[transformCount].translateY = transY;
796  mainDefaultTransformations[transformCount].rotation = DEG2RAD(rotate);
797  transformCount++;
798  /* just reset the counter back to 0 if we read too many */
799  if (transformCount == NUMBER_OF_DEFAULT_TRANSFORMATIONS)
800  transformCount = 0;
801  break;
802  case 'u':
803  if (unit_flag_counter == 1)
804  /* Length unit flag occurred only once and processed */
805  break;
806 
807  /* Length unit flag occurred more than once, process each one */
808  if (!getopt_lengh_unit(optarg, &input_divisor, &screen))
809  GERB_COMPILE_WARNING(_("Unrecognized length unit \"%s\" in command line"), optarg);
810 
811  break;
812 
813  case 'w': userSuppliedWindowInPixels = TRUE;
814  case 'W':
815  if (optarg == NULL) {
816  fprintf(stderr, _("You must give a window size in the format <width x height>.\n"));
817  exit(1);
818  }
819  if (strlen(optarg) > 20) {
820  fprintf(stderr, _("Specified window size is not recognized.\n"));
821  exit(1);
822  }
823  sscanf(optarg, "%fx%f", &userSuppliedWidth, &userSuppliedHeight);
824  if (((userSuppliedWidth < 0.001) || (userSuppliedHeight < 0.001))
825  || ((userSuppliedWidth > 2000) || (userSuppliedHeight > 2000))) {
826  fprintf(stderr, _("Specified window size is out of bounds.\n"));
827  exit(1);
828  }
829  userSuppliedWindow = TRUE;
830  break;
831  case 'x':
832  if (optarg == NULL) {
833  fprintf(stderr, _("You must supply an export type.\n"));
834  exit(1);
835  }
836 
837  for (i = 0; export_type_names[i] != NULL; i++) {
838  if (strcmp(optarg, export_type_names[i]) == 0) {
839  exportType = i;
840  break;
841  }
842  }
843 
844  if (exportType == EXP_TYPE_NONE) {
845  fprintf(stderr, _("Unrecognized \"%s\" export type.\n"), optarg);
846  exit(1);
847  }
848  break;
849  case 'd': screen.dump_parsed_image = 1; break;
850  case '?':
851  case 'h':
852  gerbv_print_help();
853 
854  exit(1);
855  break;
856  default:
857  /* This should not be reached */
858  GERB_COMPILE_WARNING(_("Not handled option '%c' in command line"), read_opt);
859  }
860  }
861 
862  /*
863  * If no project_filename and only file ends in .gvp, use as project file. -erco 02/20/2020
864  */
865  if (!project_filename && // project not set?
866  optind == (argc - 1) && // only one file specified?
867  gerbv_endswith(argv[optind], ".gvp")) { // only file ends in .gvp?
868  project_filename = argv[optind];
869  }
870 
871  /*
872  * If project is given, load that one and use it for files and colors.
873  * Else load files (eventually) given on the command line.
874  * This limits you to either give files on the commandline or just load
875  * a project.
876  */
877 
878  if (project_filename) {
879  dprintf(_("Loading project %s...\n"), project_filename);
880  /* calculate the absolute pathname to the project if the user
881  used a relative path */
882  g_free(mainProject->path);
883  if (!g_path_is_absolute(project_filename)) {
884  gchar* currentDir = g_get_current_dir();
885  gchar* fullName = g_build_filename(currentDir, project_filename, NULL);
886  main_open_project_from_filename(mainProject, fullName);
887  mainProject->path = g_path_get_dirname(fullName);
888  g_free(fullName);
889  g_free(currentDir);
890  } else {
891  main_open_project_from_filename(mainProject, project_filename);
892  mainProject->path = g_path_get_dirname(project_filename);
893  }
894  } else {
895  gint loadedIndex = 0;
896  for (i = optind; i < argc; i++) {
897  g_free(mainProject->path);
898  if (!g_path_is_absolute(argv[i])) {
899  gchar* currentDir = g_get_current_dir();
900  gchar* fullName = g_build_filename(currentDir, argv[i], NULL);
902  mainProject, fullName, mainDefaultColors[loadedIndex % NUMBER_OF_DEFAULT_COLORS].red * 257,
903  mainDefaultColors[loadedIndex % NUMBER_OF_DEFAULT_COLORS].green * 257,
904  mainDefaultColors[loadedIndex % NUMBER_OF_DEFAULT_COLORS].blue * 257,
905  mainDefaultColors[loadedIndex % NUMBER_OF_DEFAULT_COLORS].alpha * 257
906  );
907  mainProject->path = g_path_get_dirname(fullName);
908  g_free(fullName);
909  g_free(currentDir);
910  } else {
912  mainProject, argv[i], mainDefaultColors[loadedIndex % NUMBER_OF_DEFAULT_COLORS].red * 257,
913  mainDefaultColors[loadedIndex % NUMBER_OF_DEFAULT_COLORS].green * 257,
914  mainDefaultColors[loadedIndex % NUMBER_OF_DEFAULT_COLORS].blue * 257,
915  mainDefaultColors[loadedIndex % NUMBER_OF_DEFAULT_COLORS].alpha * 257
916  );
917  mainProject->path = g_path_get_dirname(argv[i]);
918  }
919  loadedIndex++;
920  }
921  }
922 
923  if (initial_rotation != 0.0) {
924  /* Set initial layer orientation */
925 
926  gdouble initial_radians = DEG2RAD(initial_rotation);
927 
928  dprintf("Rotating all layers by %.0f degrees\n", (float)initial_rotation);
929  for (i = 0; i < mainProject->max_files; i++) {
930  if (mainProject->file[i])
931  mainProject->file[i]->transform.rotation = initial_radians;
932  }
933  }
934 
935  if (initial_mirror_x || initial_mirror_y) {
936  /* Set initial mirroring of all layers */
937 
938  if (initial_mirror_x) {
939  dprintf("Mirroring all layers about x axis\n");
940  }
941  if (initial_mirror_y) {
942  dprintf("Mirroring all layers about y axis\n");
943  }
944 
945  for (i = 0; i < mainProject->max_files; i++) {
946  if (mainProject->file[i]) {
947  mainProject->file[i]->transform.mirrorAroundX = initial_mirror_x;
948  mainProject->file[i]->transform.mirrorAroundY = initial_mirror_y;
949  }
950  }
951  }
952 
953  if (exportType != EXP_TYPE_NONE) {
954  /* load the info struct with the default values */
955 
956  if (!exportFilename)
957  exportFilename = export_def_file_names[exportType];
958 
960  gerbv_render_get_boundingbox(mainProject, &bb);
961  // Set origin to the left-bottom corner if it is not specified
962  if (!userSuppliedOrigin) {
963  userSuppliedOriginX = bb.left;
964  userSuppliedOriginY = bb.top;
965  }
966 
967  float width = bb.right - userSuppliedOriginX + 0.001; // Plus a little extra to prevent from
968  float height = bb.bottom - userSuppliedOriginY + 0.001; // missing items due to round-off errors
969  // If the user did not specify a height and width, autoscale w&h till full size from origin.
970  if (!userSuppliedWindow) {
971  userSuppliedWidth = width;
972  userSuppliedHeight = height;
973  } else {
974  // If size was specified in pixels, and no resolution was specified, autoscale resolution till fit
975  if ((!userSuppliedDpi) && userSuppliedWindowInPixels) {
976  userSuppliedDpiX = MIN((userSuppliedWidth - 0.5) / width, (userSuppliedHeight - 0.5) / height);
977  userSuppliedDpiY = userSuppliedDpiX;
978  userSuppliedOriginX -= 0.5 / userSuppliedDpiX;
979  userSuppliedOriginY -= 0.5 / userSuppliedDpiY;
980  }
981  }
982 
983  // Add the border size (if there is one)
984  if (userSuppliedBorder != 0) {
985  // If supplied in inches, add a border around the image
986  if (!userSuppliedWindowInPixels) {
987  userSuppliedOriginX -= (userSuppliedWidth * userSuppliedBorder) / 2.0;
988  userSuppliedOriginY -= (userSuppliedHeight * userSuppliedBorder) / 2.0;
989  userSuppliedWidth += userSuppliedWidth * userSuppliedBorder;
990  userSuppliedHeight += userSuppliedHeight * userSuppliedBorder;
991  }
992  // If supplied in pixels, shrink image content for border_size
993  else {
994  userSuppliedOriginX -= ((userSuppliedWidth / userSuppliedDpiX) * userSuppliedBorder) / 2.0;
995  userSuppliedOriginY -= ((userSuppliedHeight / userSuppliedDpiX) * userSuppliedBorder) / 2.0;
996  userSuppliedDpiX -= (userSuppliedDpiX * userSuppliedBorder);
997  userSuppliedDpiY -= (userSuppliedDpiY * userSuppliedBorder);
998  }
999  }
1000 
1001  if (!userSuppliedWindowInPixels) {
1002  userSuppliedWidth *= userSuppliedDpiX;
1003  userSuppliedHeight *= userSuppliedDpiY;
1004  }
1005 
1006  // Make sure there is something valid in it. It could become negative if
1007  // the userSuppliedOrigin is further than the bb.right or bb.top.
1008  if (userSuppliedWidth <= 0)
1009  userSuppliedWidth = 1;
1010  if (userSuppliedHeight <= 0)
1011  userSuppliedHeight = 1;
1012 
1013  gerbv_render_info_t renderInfo = { userSuppliedDpiX,
1014  userSuppliedDpiY,
1015  userSuppliedOriginX,
1016  userSuppliedOriginY,
1017  userSuppliedAntiAlias ? GERBV_RENDER_TYPE_CAIRO_HIGH_QUALITY
1019  userSuppliedWidth,
1020  userSuppliedHeight };
1021 
1022  switch (exportType) {
1023  case EXP_TYPE_PNG: gerbv_export_png_file_from_project(mainProject, &renderInfo, exportFilename); break;
1024  case EXP_TYPE_PDF: gerbv_export_pdf_file_from_project(mainProject, &renderInfo, exportFilename); break;
1025  case EXP_TYPE_SVG: gerbv_export_svg_file_from_project(mainProject, &renderInfo, exportFilename); break;
1026  case EXP_TYPE_PS:
1027  gerbv_export_postscript_file_from_project(mainProject, &renderInfo, exportFilename);
1028  break;
1029  case EXP_TYPE_RS274X:
1030  case EXP_TYPE_DRILL:
1031  case EXP_TYPE_IDRILL:
1032  if (!mainProject->file[0]->image) {
1033  fprintf(stderr, _("A valid file was not loaded.\n"));
1034  exit(1);
1035  }
1036 
1037  exportImage = gerbv_image_duplicate_image(mainProject->file[0]->image, &mainDefaultTransformations[0]);
1038 
1039  /* If more than one file, merge them before exporting */
1040  for (i = mainProject->last_loaded; i > 0; i--) {
1041  if (mainProject->file[i])
1043  mainProject->file[i]->image, &mainDefaultTransformations[i], exportImage
1044  );
1045  }
1046 
1047  switch (exportType) {
1048  case EXP_TYPE_RS274X:
1050  exportFilename, exportImage, &mainProject->file[0]->transform
1051  );
1052  break;
1053  case EXP_TYPE_DRILL:
1055  exportFilename, exportImage, &mainProject->file[0]->transform
1056  );
1057  break;
1058  case EXP_TYPE_IDRILL:
1060  exportFilename, exportImage, &mainProject->file[0]->transform
1061  );
1062  break;
1063  default: break;
1064  }
1065 
1066  gerbv_destroy_image(exportImage);
1067  break;
1068  default: fprintf(stderr, _("A valid file was not loaded.\n")); exit(1);
1069  }
1070 
1071  /* exit now and don't start up gtk if this is a command line export */
1072  exit(0);
1073  }
1074  gtk_init(&argc, &argv);
1075  interface_create_gui(req_width, req_height);
1076 
1077  /* we've exited the GTK loop, so free all resources */
1078  render_free_screen_resources();
1080  return 0;
1081 } /* main */
1082 
1083 static int
1084 getopt_configured(int argc, char* const argv[], const char* optstring, const struct option* longopts, int* longindex) {
1085 #ifdef HAVE_GETOPT_LONG
1086  return getopt_long(argc, argv, optstring, longopts, longindex);
1087 #else
1088  return getopt(argc, argv, optstring);
1089 #endif
1090 }
1091 
1092 static int
1093 getopt_lengh_unit(const char* optarg, double* input_div, gerbv_screen_t* screen) {
1094  if (strncasecmp(optarg, "mm", 2) == 0) {
1095  *input_div = 25.4;
1096  screen->unit = GERBV_MMS;
1097  screen->unit_is_from_cmdline = TRUE;
1098  } else if (strncasecmp(optarg, "mil", 3) == 0) {
1099  *input_div = 1000.0;
1100  screen->unit = GERBV_MILS;
1101  screen->unit_is_from_cmdline = TRUE;
1102  } else if (strncasecmp(optarg, "inch", 4) == 0) {
1103  *input_div = 1.0;
1104  screen->unit = GERBV_INS;
1105  screen->unit_is_from_cmdline = TRUE;
1106  } else {
1107  return 0;
1108  }
1109 
1110  return 1;
1111 }
1112 
1113 static void
1114 gerbv_print_help(void) {
1115  printf(
1116  _("Usage: gerbv [OPTIONS...] [FILE...]\n"
1117  "\n"
1118  "Available options:\n")
1119  );
1120 
1121 #ifdef HAVE_GETOPT_LONG
1122  printf(
1123  _(" -B, --border=<b> Border around the image in percent of the\n"
1124  " width/height. Defaults to %d%%.\n"),
1125  (int)(100 * GERBV_DEFAULT_BORDER_COEFF)
1126  );
1127 #else
1128  printf(
1129  _(" -B<b> Border around the image in percent of the\n"
1130  " width/height. Defaults to %d%%.\n"),
1131  (int)(100 * GERBV_DEFAULT_BORDER_COEFF)
1132  );
1133 #endif
1134 
1135 #ifdef HAVE_GETOPT_LONG
1136  printf(
1137  _(" -D, --dpi=<XxY|R> Resolution (Dots per inch) for the output\n"
1138  " bitmap. With the format <XxY>, different\n"
1139  " resolutions for X- and Y-direction are used.\n"
1140  " With the format <R>, both are the same.\n")
1141  );
1142 #else
1143  printf(
1144  _(" -D<XxY|R> Resolution (Dots per inch) for the output\n"
1145  " bitmap. With the format <XxY>, different\n"
1146  " resolutions for X- and Y-direction are used.\n"
1147  " With the format <R>, both are the same.\n")
1148  );
1149 #endif
1150 
1151 #ifdef HAVE_GETOPT_LONG
1152  printf(
1153  _(" -O, --origin=<XxY|X;Y> Use the specified coordinates (in inches)\n"
1154  " for the lower left corner.\n")
1155  );
1156 #else
1157  printf(
1158  _(" -O<XxY|X;Y> Use the specified coordinates (in inches)\n"
1159  " for the lower left corner.\n")
1160  );
1161 #endif
1162 
1163 #ifdef HAVE_GETOPT_LONG
1164  printf(_(" -V, --version Print version of Gerbv.\n"));
1165 #else
1166  printf(_(" -V Print version of Gerbv.\n"));
1167 #endif
1168 
1169 #ifdef HAVE_GETOPT_LONG
1170  printf(_(" -a, --antialias Use antialiasing for generated bitmap output.\n"));
1171 #else
1172  printf(_(" -a Use antialiasing for generated bitmap output.\n"));
1173 #endif
1174 
1175 #ifdef HAVE_GETOPT_LONG
1176  printf(_(" -b, --background=<hex> Use background color <hex> (like #RRGGBB).\n"));
1177 #else
1178  printf(_(" -b<hexcolor> Use background color <hexcolor> (like #RRGGBB).\n"));
1179 #endif
1180 
1181 #ifdef HAVE_GETOPT_LONG
1182  printf(
1183  _(" -f, --foreground=<hex> Use foreground color <hex> (like #RRGGBB or\n"
1184  " #RRGGBBAA for setting the alpha).\n"
1185  " Use multiple -f flags to set the color for\n"
1186  " multiple layers.\n")
1187  );
1188 #else
1189  printf(
1190  _(" -f<hexcolor> Use foreground color <hexcolor> (like #RRGGBB or\n"
1191  " #RRGGBBAA for setting the alpha).\n"
1192  " Use multiple -f flags to set the color for\n"
1193  " multiple layers.\n")
1194  );
1195 #endif
1196 
1197 #ifdef HAVE_GETOPT_LONG
1198  printf(_(" -r, --rotate=<degree> Set initial orientation for all layers.\n"));
1199 #else
1200  printf(_(" -r<degree> Set initial orientation for all layers.\n"));
1201 #endif
1202 
1203 #ifdef HAVE_GETOPT_LONG
1204  printf(_(" -m, --mirror=<axis> Set initial mirroring axis (X or Y).\n"));
1205 #else
1206  printf(_(" -m<axis> Set initial mirroring axis (X or Y).\n"));
1207 #endif
1208 
1209 #ifdef HAVE_GETOPT_LONG
1210  printf(_(" -h, --help Print this help message.\n"));
1211 #else
1212  printf(_(" -h Print this help message.\n"));
1213 #endif
1214 
1215 #ifdef HAVE_GETOPT_LONG
1216  printf(_(" -l, --log=<logfile> Send error messages to <logfile>.\n"));
1217 #else
1218  printf(_(" -l<logfile> Send error messages to <logfile>.\n"));
1219 #endif
1220 
1221 #ifdef HAVE_GETOPT_LONG
1222  printf(_(" -o, --output=<filename> Export to <filename>.\n"));
1223 #else
1224  printf(_(" -o<filename> Export to <filename>.\n"));
1225 #endif
1226 
1227 #ifdef HAVE_GETOPT_LONG
1228  printf(_(" -p, --project=<prjfile> Load project file <prjfile>.\n"));
1229 #else
1230  printf(_(" -p<prjfile> Load project file <prjfile>.\n"));
1231 #endif
1232 
1233 #ifdef HAVE_GETOPT_LONG
1234  printf(
1235  _(" -u, --units=<inch|mm|mil>\n"
1236  " Use given unit for coordinates.\n"
1237  " Default to inch.\n")
1238  );
1239 #else
1240  printf(
1241  _(" -u<inch|mm|mil> Use given unit for coordinates.\n"
1242  " Default to inch.\n")
1243  );
1244 #endif
1245 
1246 #ifdef HAVE_GETOPT_LONG
1247  printf(_(" -W, --window_inch=<WxH> Window size in inches <WxH> for the exported image.\n"));
1248 #else
1249  printf(_(" -W<WxH> Window size in inches <WxH> for the exported image.\n"));
1250 #endif
1251 
1252 #ifdef HAVE_GETOPT_LONG
1253  printf(
1254  _(" -w, --window=<WxH> Window size in pixels <WxH> for the exported image.\n"
1255  " Autoscales to fit if no resolution is specified.\n"
1256  " If a resolution is specified, it will clip\n"
1257  " exported image.\n")
1258  );
1259 #else
1260  printf(
1261  _(" -w<WxH> Window size in pixels <WxH> for the exported image.\n"
1262  " Autoscales to fit if no resolution is specified.\n"
1263  " If a resolution is specified, it will clip\n"
1264  " exported image.\n")
1265  );
1266 #endif
1267 
1268 #ifdef HAVE_GETOPT_LONG
1269  printf(_(" -t, --tools=<toolfile> Read Excellon tools from file <toolfile>.\n"));
1270 #else
1271  printf(_(" -t<toolfile> Read Excellon tools from file <toolfile>\n"));
1272 #endif
1273 
1274 #ifdef HAVE_GETOPT_LONG
1275  printf(
1276  _(" -T, --translate=<XxYrR| Translate image by X and Y and rotate by R degree.\n"
1277  " X;YrR> Useful for arranging panels.\n"
1278  " Use multiple -T flags for multiple layers.\n"
1279  " Only evaluated when exporting as RS274X or drill.\n")
1280  );
1281 #else
1282  printf(
1283  _(" -T<XxYrR|X;YrR> Translate image by X and Y and rotate by R degree.\n"
1284  " Useful for arranging panels.\n"
1285  " Use multiple -T flags for multiple files.\n"
1286  " Only evaluated when exporting as RS274X or drill.\n")
1287  );
1288 #endif
1289 
1290 #ifdef HAVE_GETOPT_LONG
1291  printf(
1292  _(" -x, --export=<png|pdf|ps|svg|rs274x|drill|idrill>\n"
1293  " Export a rendered picture to a file with\n"
1294  " the specified format.\n")
1295  );
1296 #else
1297  printf(
1298  _(" -x<png|pdf|ps|svg| Export a rendered picture to a file with\n"
1299  " rs274x|drill| the specified format.\n"
1300  " idrill>\n")
1301  );
1302 #endif
1303 }
Header info for the GUI callback functions.
Contains basic defines.
gboolean gerbv_export_drill_file_from_image(const gchar *filename, gerbv_image_t *inputImage, gerbv_user_transformation_t *transform)
Export an image to a new file in Excellon drill format.
Definition: export-drill.c:43
void gerbv_export_png_file_from_project(gerbv_project_t *gerbvProject, gerbv_render_info_t *renderInfo, const gchar *filename)
Render a project to a PNG file using user-specified render info.
Definition: export-image.c:89
void gerbv_export_pdf_file_from_project(gerbv_project_t *gerbvProject, gerbv_render_info_t *renderInfo, const gchar *filename)
Render a project to a PDF file using user-specified render info.
Definition: export-image.c:110
void gerbv_export_svg_file_from_project(gerbv_project_t *gerbvProject, gerbv_render_info_t *renderInfo, const gchar *filename)
Render a project to a file using user-specified render info.
Definition: export-image.c:139
void gerbv_export_postscript_file_from_project(gerbv_project_t *gerbvProject, gerbv_render_info_t *renderInfo, const gchar *filename)
Render a project to a Postscript file using user-specified render info.
Definition: export-image.c:125
gboolean gerbv_export_isel_drill_file_from_image(const gchar *filename, gerbv_image_t *inputImage, gerbv_user_transformation_t *transform)
Export an image to a new file in ISEL NCP drill format.
gboolean gerbv_export_rs274x_file_from_image(const gchar *filename, gerbv_image_t *inputImage, gerbv_user_transformation_t *transform)
Export an image to a new file in RS274X format.
void gerbv_destroy_image(gerbv_image_t *image)
Free an image structure.
Definition: gerb_image.c:104
void gerbv_image_copy_image(gerbv_image_t *sourceImage, gerbv_user_transformation_t *transform, gerbv_image_t *destinationImage)
Copy an image into an existing image, effectively merging the two together.
Definition: gerb_image.c:854
gerbv_image_t * gerbv_image_duplicate_image(gerbv_image_t *sourceImage, gerbv_user_transformation_t *transform)
Duplicate an existing image and return the new copy.
Definition: gerb_image.c:815
void gerbv_destroy_project(gerbv_project_t *gerbvProject)
Free a project and all related variables.
Definition: gerbv.c:181
gerbv_project_t * gerbv_create_project(void)
Create a new project structure and initialize some important variables.
Definition: gerbv.c:164
void gerbv_open_layer_from_filename_with_color(gerbv_project_t *gerbvProject, const gchar *filename, guint16 red, guint16 green, guint16 blue, guint16 alpha)
Open a file, parse the contents, and add a new layer to an existing project while setting the color o...
Definition: gerbv.c:230
gboolean gerbv_endswith(const char *path, const char *ext)
Definition: gerbv.c:1070
The main header file for the libgerbv library.
@ GERBV_RENDER_TYPE_CAIRO_HIGH_QUALITY
Definition: gerbv.h:371
@ GERBV_RENDER_TYPE_GDK
Definition: gerbv.h:368
@ GERBV_RENDER_TYPE_CAIRO_NORMAL
Definition: gerbv.h:370
Header info for the GUI building functions for Gerber Viewer.
gerbv_project_t * mainProject
Global state variable to keep track of what's happening on the screen.
Definition: main.c:169
Header info for common structs and functions used for the GUI application.
project_list_t * read_project_file(const char *filename)
Reads the content of a project file.
Definition: project.c:894
Header info for loading and saving project files.
Header info for the rendering support functions for gerbv.
guint16 alpha
Definition: gerbv.h:748
gchar * fullPathname
Definition: gerbv.h:751
gerbv_image_t * image
Definition: gerbv.h:746
gerbv_user_transformation_t transform
Definition: gerbv.h:754
GdkColor color
Definition: gerbv.h:747
gboolean isVisible
Definition: gerbv.h:749
gerbv_fileinfo_t ** file
Definition: gerbv.h:763
gchar * project
Definition: gerbv.h:772
GdkColor background
Definition: gerbv.h:761
gchar * execname
Definition: gerbv.h:771
gchar * path
Definition: gerbv.h:769
gchar * execpath
Definition: gerbv.h:770
int max_files
Definition: gerbv.h:762
int last_loaded
Definition: gerbv.h:765
gerbv_render_types_t renderType
Definition: gerbv.h:789