gerbv
gerb_image.c
Go to the documentation of this file.
1 /*
2  * gEDA - GNU Electronic Design Automation
3  * This files is a part of gerbv.
4  *
5  * Copyright (C) 2000-2003 Stefan Petersen (spe@stacken.kth.se)
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 <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34 
35 #include "common.h"
36 #include "gerb_image.h"
37 #include "gerber.h"
38 #include "amacro.h"
39 
40 typedef struct {
41  int oldAperture;
42  int newAperture;
43 } gerb_translation_entry_t;
44 
46 gerbv_create_image(gerbv_image_t *image, const gchar *type)
47 {
48  gerbv_destroy_image(image);
49 
50  /* Malloc space for image */
51  if (NULL == (image = g_new0(gerbv_image_t, 1))) {
52  return NULL;
53  }
54 
55  /* Malloc space for image->netlist */
56  if (NULL == (image->netlist = g_new0(gerbv_net_t, 1))) {
57  g_free(image);
58  return NULL;
59  }
60 
61  /* Malloc space for image->info */
62  if (NULL == (image->info = g_new0(gerbv_image_info_t, 1))) {
63  g_free(image->netlist);
64  g_free(image);
65  return NULL;
66  }
67 
68  /* Set aside position for stats struct */
69  image->gerbv_stats = NULL;
70  image->drill_stats = NULL;
71 
72  image->info->min_x = HUGE_VAL;
73  image->info->min_y = HUGE_VAL;
74  image->info->max_x = -HUGE_VAL;
75  image->info->max_y = -HUGE_VAL;
76 
77  /* create our first layer and fill with non-zero default values */
78  image->layers = g_new0 (gerbv_layer_t, 1);
79  image->layers->stepAndRepeat.X = 1;
80  image->layers->stepAndRepeat.Y = 1;
82 
83  /* create our first netstate and fill with non-zero default values */
84  image->states = g_new0 (gerbv_netstate_t, 1);
85  image->states->scaleA = 1;
86  image->states->scaleB = 1;
87 
88  /* fill in some values for our first net */
89  image->netlist->layer = image->layers;
90  image->netlist->state = image->states;
91 
92  if (type == NULL)
93  image->info->type = g_strdup (_("unknown"));
94  else
95  image->info->type = g_strdup (type);
96 
97  /* the individual file parsers will have to set this. */
98  image->info->attr_list = NULL;
99  image->info->n_attr = 0;
100 
101  return image;
102 }
103 
104 
105 void
107 {
108  int i;
109  gerbv_net_t *net, *tmp;
110  gerbv_layer_t *layer;
111  gerbv_netstate_t *state;
112  gerbv_simplified_amacro_t *sam,*sam2;
113 
114  if(image==NULL)
115  return;
116 
117  /*
118  * Free apertures
119  */
120  for (i = 0; i < APERTURE_MAX; i++)
121  if (image->aperture[i] != NULL) {
122  for (sam = image->aperture[i]->simplified; sam != NULL; ){
123  sam2 = sam->next;
124  g_free (sam);
125  sam = sam2;
126  }
127 
128  g_free(image->aperture[i]);
129  image->aperture[i] = NULL;
130  }
131 
132  /*
133  * Free aperture macro
134  */
135 
136  if (image->amacro) {
137  free_amacro(image->amacro);
138  }
139 
140  /*
141  * Free format
142  */
143  if (image->format)
144  g_free(image->format);
145 
146  /*
147  * Free info
148  */
149  if (image->info) {
150  g_free(image->info->name);
151  g_free(image->info->type);
152  gerbv_attribute_destroy_HID_attribute (image->info->attr_list, image->info->n_attr);
153  g_free(image->info);
154  }
155 
156  /*
157  * Free netlist
158  */
159  for (net = image->netlist; net != NULL; ) {
160  tmp = net;
161  net = net->next;
162  if (tmp->cirseg != NULL) {
163  g_free(tmp->cirseg);
164  tmp->cirseg = NULL;
165  }
166  if (tmp->label) {
167  g_string_free (tmp->label, TRUE);
168  }
169  g_free(tmp);
170  tmp = NULL;
171  }
172  for (layer = image->layers; layer != NULL; ) {
173  gerbv_layer_t *tempLayer = layer;
174 
175  layer = layer->next;
176  g_free (tempLayer->name);
177  g_free (tempLayer);
178  }
179  for (state = image->states; state != NULL; ) {
180  gerbv_netstate_t *tempState = state;
181 
182  state = state->next;
183  g_free (tempState);
184  }
187 
188  /*
189  * Free and reset the final image
190  */
191  g_free(image);
192  image = NULL;
193 
194  return;
195 }
196 
197 
198 /*
199  * Check that the parsed gerber image is complete.
200  * Returned errorcodes are:
201  * 0: No problems
202  * 1: Missing netlist
203  * 2: Missing format
204  * 4: Missing apertures
205  * 8: Missing info
206  * It could be any of above or'ed together
207  */
208 gerb_verify_error_t
209 gerbv_image_verify(gerbv_image_t const* image)
210 {
211  gerb_verify_error_t error = GERB_IMAGE_OK;
212  int i;
213  gerbv_net_t *net;
214  gboolean needs_aperture = FALSE;
215  gboolean in_parea = FALSE;
216 
217  if (image->netlist == NULL) error |= GERB_IMAGE_MISSING_NETLIST;
218  if (image->format == NULL) error |= GERB_IMAGE_MISSING_FORMAT;
219  if (image->info == NULL) error |= GERB_IMAGE_MISSING_INFO;
220 
221  /* Check if any net actually requires an aperture (i.e., draws or
222  * flashes outside a polygon area fill). G36/G37 polygon fills
223  * don't need apertures, so files using only polygon fills should
224  * not trigger a missing-apertures warning. */
225  if (image->netlist != NULL) {
226  for (net = image->netlist->next ; net != NULL; net = net->next) {
228  in_parea = TRUE;
230  in_parea = FALSE;
231  else if (!in_parea &&
234  needs_aperture = TRUE;
235  }
236  }
237 
238  /* If we have nets that need apertures but none are defined, complain */
239  if (needs_aperture) {
240  for (i = 0; i < APERTURE_MAX && image->aperture[i] == NULL; i++);
241  if (i == APERTURE_MAX) error |= GERB_IMAGE_MISSING_APERTURES;
242  }
243 
244  return error;
245 } /* gerb_image_verify */
246 
247 static void
248 gerbv_image_aperture_state(gerbv_aperture_state_t state)
249 {
250  switch (state) {
252  printf(_("..state off"));
253  break;
255  printf(_("..state on"));
256  break;
258  printf(_("..state flash"));
259  break;
260  default:
261  printf(_("..state unknown"));
262  }
263 }
264 
265 /* Dumps a written version of image to stdout */
266 void
267 gerbv_image_dump(gerbv_image_t const* image)
268 {
269  int i, j;
270  gerbv_aperture_t * const* aperture;
271  gerbv_net_t const * net;
272 
273  /* Apertures */
274  printf(_("Apertures:\n"));
275  aperture = image->aperture;
276  for (i = 0; i < APERTURE_MAX; i++) {
277  if (aperture[i]) {
278  printf(_(" Aperture no:%d is an "), i);
279  switch(aperture[i]->type) {
280  case GERBV_APTYPE_CIRCLE:
281  printf(_("circle"));
282  break;
284  printf(_("rectangle"));
285  break;
286  case GERBV_APTYPE_OVAL:
287  printf(_("oval"));
288  break;
290  printf(_("polygon"));
291  break;
292  case GERBV_APTYPE_MACRO:
293  printf(_("macro"));
294  break;
295  default:
296  printf(_("unknown"));
297  }
298  for (j = 0; j < aperture[i]->nuf_parameters; j++) {
299  printf(" %f", aperture[i]->parameter[j]);
300  }
301  printf("\n");
302  }
303  }
304 
305  /* Netlist */
306  net = image->netlist;
307  while (net){
308  printf(_("(%f,%f)->(%f,%f) with %d ("), net->start_x, net->start_y,
309  net->stop_x, net->stop_y, net->aperture);
310  printf("%s", _(gerbv_interpolation_name(net->interpolation)));
311  gerbv_image_aperture_state(net->aperture_state);
312  printf(")\n");
313  net = net->next;
314  }
315 } /* gerbv_image_dump */
316 
317 
319 gerbv_image_return_new_layer (gerbv_layer_t *previousLayer)
320 {
321  gerbv_layer_t *newLayer = g_new0 (gerbv_layer_t, 1);
322 
323  *newLayer = *previousLayer;
324  previousLayer->next = newLayer;
325  /* clear this boolean so we only draw the knockout once */
326  newLayer->knockout.firstInstance = FALSE;
327  newLayer->name = NULL;
328  newLayer->next = NULL;
329 
330  return newLayer;
331 } /* gerbv_image_return_new_layer */
332 
333 
335 gerbv_image_return_new_netstate (gerbv_netstate_t *previousState)
336 {
337  gerbv_netstate_t *newState = g_new0 (gerbv_netstate_t, 1);
338 
339  *newState = *previousState;
340  previousState->next = newState;
341  newState->scaleA = 1.0;
342  newState->scaleB = 1.0;
343  newState->next = NULL;
344 
345  return newState;
346 } /* gerbv_image_return_new_netstate */
347 
349 gerbv_image_duplicate_layer (gerbv_layer_t *oldLayer) {
350  gerbv_layer_t *newLayer = g_new (gerbv_layer_t,1);
351 
352  *newLayer = *oldLayer;
353  newLayer->name = g_strdup (oldLayer->name);
354  newLayer->next = NULL;
355  return newLayer;
356 }
357 
358 static gerbv_netstate_t *
359 gerbv_image_duplicate_state (gerbv_netstate_t *oldState)
360 {
361  gerbv_netstate_t *newState = g_new (gerbv_netstate_t, 1);
362 
363  *newState = *oldState;
364  newState->next = NULL;
365  return newState;
366 }
367 
368 static gerbv_aperture_t *
369 gerbv_image_duplicate_aperture (gerbv_aperture_t *oldAperture)
370 {
371  gerbv_aperture_t *newAperture = g_new0 (gerbv_aperture_t,1);
372  gerbv_simplified_amacro_t *simplifiedMacro, *tempSimplified;
373 
374  *newAperture = *oldAperture;
375 
376  /* delete the amacro section, since we really don't need it anymore
377  now that we have the simplified section */
378  newAperture->amacro = NULL;
379  newAperture->simplified = NULL;
380 
381  /* copy any simplified macros over */
382  tempSimplified = NULL;
383  for (simplifiedMacro = oldAperture->simplified; simplifiedMacro != NULL; simplifiedMacro = simplifiedMacro->next) {
384  gerbv_simplified_amacro_t *newSimplified = g_new0 (gerbv_simplified_amacro_t,1);
385  *newSimplified = *simplifiedMacro;
386  if (tempSimplified)
387  tempSimplified->next = newSimplified;
388  else
389  newAperture->simplified = newSimplified;
390  tempSimplified = newSimplified;
391  }
392  return newAperture;
393 }
394 
395 static void
396 gerbv_image_copy_all_nets (gerbv_image_t *sourceImage,
397  gerbv_image_t *destImage, gerbv_layer_t *lastLayer,
398  gerbv_netstate_t *lastState, gerbv_net_t *lastNet,
400  GArray *translationTable)
401 {
402  /* NOTE: destImage already contains apertures and data,
403  * latest data is: lastLayer, lastState, lastNet. */
404 
405  gerbv_net_t *currentNet, *newNet;
406  gerbv_layer_t *srcLayer = NULL;
407  gerbv_netstate_t *srcState = NULL;
408  gerbv_aperture_type_t aper_type;
409  gerbv_aperture_t *aper;
410  gerbv_simplified_amacro_t *sam;
411  int *trans_apers = NULL; /* Transformed apertures */
412  int aper_last_id = 0;
413  guint err_scale_circle = 0,
414  err_scale_line_macro = 0,
415  err_scale_poly_macro = 0,
416  err_scale_thermo_macro = 0,
417  err_scale_moire_macro = 0,
418  err_unknown_aperture = 0,
419  err_unknown_macro_aperture = 0,
420  err_rotate_oval = 0,
421  err_rotate_rect = 0;
422 
423  if (trans && (trans->mirrorAroundX || trans->mirrorAroundY)) {
424  if (sourceImage->layertype != GERBV_LAYERTYPE_DRILL) {
425  GERB_COMPILE_ERROR(_("Exporting mirrored file "
426  "is not supported!"));
427  return;
428  }
429  }
430 
431  if (trans && trans->inverted) {
432  GERB_COMPILE_ERROR(_("Exporting inverted file "
433  "is not supported!"));
434  return;
435  }
436 
437  if (trans) {
438  /* Find last used aperture to add transformed apertures if
439  * needed */
440  for (aper_last_id = APERTURE_MAX - 1; aper_last_id > 0;
441  aper_last_id--) {
442  if (destImage->aperture[aper_last_id] != NULL)
443  break;
444  }
445 
446  trans_apers = g_new (int, aper_last_id + 1);
447  /* Initialize trans_apers array */
448  for (int i = 0; i < aper_last_id + 1; i++)
449  trans_apers[i] = -1;
450  }
451 
452  for (currentNet = sourceImage->netlist; currentNet != NULL;
453  currentNet = currentNet->next) {
454 
455  /* Check for any new layers and duplicate them if needed.
456  * Compare against the source pointer, not the duplicated
457  * pointer, to avoid creating redundant duplicates when
458  * consecutive nets share the same layer. */
459  if (currentNet->layer != srcLayer) {
460  srcLayer = currentNet->layer;
461  lastLayer->next =
462  gerbv_image_duplicate_layer (currentNet->layer);
463  lastLayer = lastLayer->next;
464  }
465 
466  /* Check for any new states and duplicate them if needed.
467  * Same source-pointer tracking as layers above. */
468  if (currentNet->state != srcState) {
469  srcState = currentNet->state;
470  lastState->next =
471  gerbv_image_duplicate_state (currentNet->state);
472  lastState = lastState->next;
473  }
474 
475  /* Create and copy the actual net over */
476  newNet = g_new (gerbv_net_t, 1);
477  *newNet = *currentNet;
478 
479  if (currentNet->cirseg) {
480  newNet->cirseg = g_new (gerbv_cirseg_t, 1);
481  *(newNet->cirseg) = *(currentNet->cirseg);
482  }
483 
484  if (currentNet->label)
485  newNet->label = g_string_new (currentNet->label->str);
486  else
487  newNet->label = NULL;
488 
489  newNet->state = lastState;
490  newNet->layer = lastLayer;
491 
492  if (lastNet)
493  lastNet->next = newNet;
494  else
495  destImage->netlist = newNet;
496 
497  lastNet = newNet;
498 
499  /* Check if we need to translate the aperture number */
500  if (translationTable) {
501  for (guint i = 0; i < translationTable->len; i++) {
502  gerb_translation_entry_t translationEntry;
503 
504  translationEntry =
505  g_array_index (translationTable,
506  gerb_translation_entry_t, i);
507 
508  if (translationEntry.oldAperture ==
509  newNet->aperture) {
510  newNet->aperture =
511  translationEntry.newAperture;
512  break;
513  }
514  }
515  }
516 
517  if (trans == NULL)
518  continue;
519 
520  /* Transforming coords */
521  gerbv_transform_coord (&newNet->start_x,
522  &newNet->start_y, trans);
523  gerbv_transform_coord (&newNet->stop_x,
524  &newNet->stop_y, trans);
525 
526  if (newNet->cirseg) {
527  /* Circular interpolation only exported by start, stop
528  * end center coordinates. */
529  gerbv_transform_coord (&newNet->cirseg->cp_x,
530  &newNet->cirseg->cp_y, trans);
531  }
532 
533  if (destImage->aperture[newNet->aperture] == NULL)
534  continue;
535 
536  if (trans->scaleX == 1.0 && trans->scaleY == 1.0
537  && fabs(trans->rotation) < GERBV_PRECISION_ANGLE_RAD)
538  continue;
539 
540  /* Aperture is already transformed, use it */
541  if (trans_apers[newNet->aperture] != -1) {
542  newNet->aperture = trans_apers[newNet->aperture];
543  continue;
544  }
545 
546  /* Transforming apertures */
547  aper_type = destImage->aperture[newNet->aperture]->type;
548  switch (aper_type) {
549  case GERBV_APTYPE_NONE:
551  break;
552 
553  case GERBV_APTYPE_CIRCLE:
554  if (trans->scaleX == trans->scaleY
555  && trans->scaleX == 1.0) {
556  break;
557  }
558 
559  if (trans->scaleX == trans->scaleY) {
560  aper = gerbv_image_duplicate_aperture (
561  destImage->aperture[
562  newNet->aperture]);
563  aper->parameter[0] *= trans->scaleX;
564 
565  trans_apers[newNet->aperture] = ++aper_last_id;
566  destImage->aperture[aper_last_id] = aper;
567  newNet->aperture = aper_last_id;
568  } else {
569  err_scale_circle++;
570  }
571  break;
572 
574  case GERBV_APTYPE_OVAL:
575  if (trans->scaleX == 1.0 && trans->scaleY == 1.0
576  && fabs(fabs(trans->rotation) - M_PI)
577  < GERBV_PRECISION_ANGLE_RAD)
578  break;
579 
580  aper = gerbv_image_duplicate_aperture (
581  destImage->aperture[newNet->aperture]);
582  aper->parameter[0] *= trans->scaleX;
583  aper->parameter[1] *= trans->scaleY;
584 
585  if (fabs(fabs(trans->rotation) - M_PI_2)
586  < GERBV_PRECISION_ANGLE_RAD
587  || fabs(fabs(trans->rotation) - (M_PI+M_PI_2))
588  < GERBV_PRECISION_ANGLE_RAD) {
589  double t = aper->parameter[0];
590  aper->parameter[0] = aper->parameter[1];
591  aper->parameter[1] = t;
592  } else {
593  if (aper_type == GERBV_APTYPE_RECTANGLE)
594  err_rotate_rect++; /* TODO: make line21 macro */
595  else
596  err_rotate_oval++;
597 
598  break;
599  }
600 
601  trans_apers[newNet->aperture] = ++aper_last_id;
602  destImage->aperture[aper_last_id] = aper;
603  newNet->aperture = aper_last_id;
604 
605  break;
606 
607  case GERBV_APTYPE_MACRO:
608  aper = gerbv_image_duplicate_aperture (
609  destImage->aperture[newNet->aperture]);
610  sam = aper->simplified;
611 
612  for (; sam != NULL; sam = sam->next) {
613  switch (sam->type) {
615  sam->parameter[CIRCLE_CENTER_X] *=
616  trans->scaleX;
617  sam->parameter[CIRCLE_CENTER_Y] *=
618  trans->scaleY;
619  sam->parameter[CIRCLE_ROTATION] +=
620  RAD2DEG(trans->rotation);
621 
622  if (trans->scaleX != trans->scaleY) {
623  err_scale_circle++;
624  break;
625  }
626  sam->parameter[CIRCLE_DIAMETER] *=
627  trans->scaleX;
628  break;
629 
631  /* Vector line rectangle */
632  if (trans->scaleX == trans->scaleY) {
633  sam->parameter[LINE20_LINE_WIDTH] *=
634  trans->scaleX;
635  } else if (sam->parameter[LINE20_START_X] ==
636  sam->parameter[LINE20_END_X]) {
637  sam->parameter[LINE20_LINE_WIDTH] *=
638  trans->scaleX; /* Vertical */
639  } else if (sam->parameter[LINE20_START_Y] ==
640  sam->parameter[LINE20_END_Y]) {
641  sam->parameter[LINE20_LINE_WIDTH] *=
642  trans->scaleY; /* Horizontal */
643  } else {
644  /* TODO: make outline macro */
645  err_scale_line_macro++;
646  break;
647  }
648 
649  sam->parameter[LINE20_START_X] *=
650  trans->scaleX;
651  sam->parameter[LINE20_START_Y] *=
652  trans->scaleY;
653  sam->parameter[LINE20_END_X] *=
654  trans->scaleX;
655  sam->parameter[LINE20_END_Y] *=
656  trans->scaleY;
657 
658  /* LINE20_START_X, LINE20_START_Y,
659  * LINE20_END_X, LINE20_END_Y are not
660  * rotated, change only rotation angle */
661  sam->parameter[LINE20_ROTATION] +=
662  RAD2DEG(trans->rotation);
663  break;
664 
665 /* Compile time check if LINE21 and LINE22 parameters indexes are equal */
666 #if (LINE21_WIDTH != LINE22_WIDTH) \
667  || (LINE21_HEIGHT != LINE22_HEIGHT) \
668  || (LINE21_ROTATION != LINE22_ROTATION) \
669  || (LINE21_CENTER_X != LINE22_LOWER_LEFT_X) \
670  || (LINE21_CENTER_Y != LINE22_LOWER_LEFT_Y)
671 # error "LINE21 and LINE22 indexes are not equal"
672 #endif
673 
675  /* Centered line rectangle */
677  /* Lower left line rectangle */
678 
679  /* Using LINE21 parameters array
680  * indexes for LINE21 and LINE22, as
681  * they are equal */
682  if (trans->scaleX == trans->scaleY) {
683  sam->parameter[LINE21_WIDTH] *=
684  trans->scaleX;
685  sam->parameter[LINE21_HEIGHT] *=
686  trans->scaleX;
687 
688  } else if (fabs(sam->parameter[LINE21_ROTATION]) == 0
689  || fabs(sam->parameter[LINE21_ROTATION]) == 180) {
690  sam->parameter[LINE21_WIDTH] *=
691  trans->scaleX;
692  sam->parameter[LINE21_HEIGHT] *=
693  trans->scaleY;
694 
695  } else if (fabs(sam->parameter[LINE21_ROTATION]) == 90
696  || fabs(sam->parameter[LINE21_ROTATION]) == 270) {
697  double t;
698  t = sam->parameter[LINE21_WIDTH];
699  sam->parameter[LINE21_WIDTH] =
700  trans->scaleY *
701  sam->parameter[
702  LINE21_HEIGHT];
703  sam->parameter[LINE21_HEIGHT] =
704  trans->scaleX * t;
705  } else {
706  /* TODO: make outline macro */
707  err_scale_line_macro++;
708  break;
709  }
710 
711  sam->parameter[LINE21_CENTER_X] *=
712  trans->scaleX;
713  sam->parameter[LINE21_CENTER_Y] *=
714  trans->scaleY;
715 
716  sam->parameter[LINE21_ROTATION] +=
717  RAD2DEG(trans->rotation);
718  break;
719 
721  for (int i = 0; i < 1 + sam->parameter[
722  OUTLINE_NUMBER_OF_POINTS]; i++) {
723  sam->parameter[OUTLINE_X_IDX_OF_POINT(i)] *=
724  trans->scaleX;
725  sam->parameter[OUTLINE_Y_IDX_OF_POINT(i)] *=
726  trans->scaleY;
727  }
728 
729  sam->parameter[OUTLINE_ROTATION_IDX(sam->parameter)] +=
730  RAD2DEG(trans->rotation);
731  break;
732 #if 0
733 {
734 /* TODO */
735 #include "main.h"
736 gerbv_selection_item_t sItem = {sourceImage, currentNet};
737 selection_add_item (&screen.selectionInfo, &sItem);
738 }
739 #endif
740 
742  if (trans->scaleX == trans->scaleY) {
743  sam->parameter[POLYGON_CENTER_X]
744  *= trans->scaleX;
745  sam->parameter[POLYGON_CENTER_Y]
746  *= trans->scaleX;
747  sam->parameter[POLYGON_DIAMETER]
748  *= trans->scaleX;
749  } else {
750  /* TODO: make outline macro */
751  err_scale_poly_macro++;
752  break;
753  }
754 
755  sam->parameter[POLYGON_ROTATION] +=
756  RAD2DEG(trans->rotation);
757  break;
758 
760  if (trans->scaleX == trans->scaleY) {
761  sam->parameter[MOIRE_CENTER_X]
762  *= trans->scaleX;
763  sam->parameter[MOIRE_CENTER_Y]
764  *= trans->scaleX;
765  sam->parameter[MOIRE_OUTSIDE_DIAMETER]
766  *= trans->scaleX;
767  sam->parameter[MOIRE_CIRCLE_THICKNESS]
768  *= trans->scaleX;
769  sam->parameter[MOIRE_GAP_WIDTH]
770  *= trans->scaleX;
771  sam->parameter[MOIRE_CROSSHAIR_THICKNESS]
772  *= trans->scaleX;
773  sam->parameter[MOIRE_CROSSHAIR_LENGTH]
774  *= trans->scaleX;
775  } else {
776  err_scale_moire_macro++;
777  break;
778  }
779 
780  sam->parameter[MOIRE_ROTATION] +=
781  RAD2DEG(trans->rotation);
782  break;
783 
785  if (trans->scaleX == trans->scaleY) {
786  sam->parameter[THERMAL_CENTER_X]
787  *= trans->scaleX;
788  sam->parameter[THERMAL_CENTER_Y]
789  *= trans->scaleX;
790  sam->parameter[THERMAL_INSIDE_DIAMETER]
791  *= trans->scaleX;
792  sam->parameter[THERMAL_OUTSIDE_DIAMETER]
793  *= trans->scaleX;
794  sam->parameter[THERMAL_CROSSHAIR_THICKNESS]
795  *= trans->scaleX;
796  } else {
797  err_scale_thermo_macro++;
798  break;
799  }
800 
801  sam->parameter[THERMAL_ROTATION] +=
802  RAD2DEG(trans->rotation);
803  break;
804 
805  default:
806  /* TODO: free aper if it is skipped (i.e. unused)? */
807  err_unknown_macro_aperture++;
808  }
809  }
810 
811  trans_apers[newNet->aperture] = ++aper_last_id;
812  destImage->aperture[aper_last_id] = aper;
813  newNet->aperture = aper_last_id;
814 
815  break;
816  default:
817  err_unknown_aperture++;
818  }
819  }
820 
821  if (err_rotate_rect)
822  GERB_COMPILE_ERROR(ngettext(
823  "Can't rotate %u rectangular aperture to %.2f "
824  "degrees (non 90 multiply)!",
825  "Can't rotate %u rectangular apertures to %.2f "
826  "degrees (non 90 multiply)!", err_rotate_rect),
827  err_rotate_rect, RAD2DEG(trans->rotation));
828 
829  if (err_scale_line_macro)
830  GERB_COMPILE_ERROR(ngettext(
831  "Can't scale %u line macro!",
832  "Can't scale %u line macros!",
833  err_scale_line_macro), err_scale_line_macro);
834 
835  if (err_scale_poly_macro)
836  GERB_COMPILE_ERROR(ngettext(
837  "Can't scale %u polygon macro!",
838  "Can't scale %u polygon macros!",
839  err_scale_poly_macro), err_scale_poly_macro);
840 
841  if (err_scale_thermo_macro)
842  GERB_COMPILE_ERROR(ngettext(
843  "Can't scale %u thermal macro!",
844  "Can't scale %u thermal macros!",
845  err_scale_poly_macro), err_scale_poly_macro);
846 
847  if (err_scale_moire_macro)
848  GERB_COMPILE_ERROR(ngettext(
849  "Can't scale %u moire macro!",
850  "Can't scale %u moire macros!",
851  err_scale_poly_macro), err_scale_poly_macro);
852 
853  if (err_rotate_oval)
854  GERB_COMPILE_ERROR(ngettext(
855  "Can't rotate %u oval aperture to %.2f "
856  "degrees (non 90 multiply)!",
857  "Can't rotate %u oval apertures to %.2f "
858  "degrees (non 90 multiply)!", err_rotate_oval),
859  err_rotate_oval, RAD2DEG(trans->rotation));
860 
861  if (err_scale_circle)
862  GERB_COMPILE_ERROR(ngettext(
863  "Can't scale %u circle aperture to ellipse!",
864  "Can't scale %u circle apertures to ellipse!",
865  err_scale_circle), err_scale_circle);
866 
867  if (err_unknown_aperture)
868  GERB_COMPILE_ERROR(ngettext(
869  "Skipped %u aperture with unknown type!",
870  "Skipped %u apertures with unknown type!",
871  err_unknown_aperture), err_unknown_aperture);
872 
873  if (err_unknown_macro_aperture)
874  GERB_COMPILE_ERROR(ngettext(
875  "Skipped %u macro aperture!",
876  "Skipped %u macro apertures!",
877  err_unknown_macro_aperture),
878  err_unknown_macro_aperture);
879 
880  g_free (trans_apers);
881 }
882 
883 gint
884 gerbv_image_find_existing_aperture_match (gerbv_aperture_t *checkAperture, gerbv_image_t *imageToSearch) {
885  int i,j;
886  gboolean isMatch;
887 
888  for (i = 0; i < APERTURE_MAX; i++) {
889  if (imageToSearch->aperture[i] != NULL) {
890  if ((imageToSearch->aperture[i]->type == checkAperture->type) &&
891  (imageToSearch->aperture[i]->simplified == NULL) &&
892  (imageToSearch->aperture[i]->unit == checkAperture->unit)) {
893  /* check all parameters match too */
894  isMatch=TRUE;
895  for (j=0; j<APERTURE_PARAMETERS_MAX; j++){
896  if (imageToSearch->aperture[i]->parameter[j] != checkAperture->parameter[j])
897  isMatch = FALSE;
898  }
899  if (isMatch)
900  return i;
901  }
902  }
903  }
904  return 0;
905 }
906 
907 int
908 gerbv_image_find_unused_aperture_number (int startIndex, gerbv_image_t *image){
909  int i;
910 
911  for (i = startIndex; i < APERTURE_MAX; i++) {
912  if (image->aperture[i] == NULL) {
913  return i;
914  }
915  }
916  return -1;
917 }
918 
921  gerbv_image_t *newImage = gerbv_create_image(NULL, sourceImage->info->type);
922  int i;
923  int lastUsedApertureNumber = APERTURE_MIN - 1;
924  GArray *apertureNumberTable = g_array_new(FALSE,FALSE,sizeof(gerb_translation_entry_t));
925 
926  newImage->layertype = sourceImage->layertype;
927  /* copy information layer over */
928  *(newImage->info) = *(sourceImage->info);
929  newImage->info->name = g_strdup (sourceImage->info->name);
930  newImage->info->type = g_strdup (sourceImage->info->type);
931  newImage->info->plotterFilm = g_strdup (sourceImage->info->plotterFilm);
932  newImage->info->attr_list = gerbv_attribute_dup (sourceImage->info->attr_list,
933  sourceImage->info->n_attr);
934 
935  /* copy apertures over, compressing all the numbers down for a cleaner output, and
936  moving and apertures less than 10 up to the correct range */
937  for (i = 0; i < APERTURE_MAX; i++) {
938  if (sourceImage->aperture[i] != NULL) {
939  gerbv_aperture_t *newAperture = gerbv_image_duplicate_aperture (sourceImage->aperture[i]);
940 
941  lastUsedApertureNumber = gerbv_image_find_unused_aperture_number (lastUsedApertureNumber + 1, newImage);
942  /* store the aperture numbers (new and old) in the translation table */
943  gerb_translation_entry_t translationEntry={i,lastUsedApertureNumber};
944  g_array_append_val (apertureNumberTable,translationEntry);
945 
946  newImage->aperture[lastUsedApertureNumber] = newAperture;
947  }
948  }
949 
950  /* step through all nets and create new layers and states on the fly, since
951  we really don't have any other way to figure out where states and layers are used */
952  gerbv_image_copy_all_nets (sourceImage, newImage, newImage->layers, newImage->states, NULL, transform, apertureNumberTable);
953  g_array_free (apertureNumberTable, TRUE);
954  return newImage;
955 }
956 
957 void
958 gerbv_image_copy_image (gerbv_image_t *sourceImage, gerbv_user_transformation_t *transform, gerbv_image_t *destinationImage) {
959  int lastUsedApertureNumber = APERTURE_MIN - 1;
960  int i;
961  GArray *apertureNumberTable = g_array_new(FALSE,FALSE,sizeof(gerb_translation_entry_t));
962 
963  /* copy apertures over */
964  for (i = 0; i < APERTURE_MAX; i++) {
965  if (sourceImage->aperture[i] != NULL) {
966  gint existingAperture = gerbv_image_find_existing_aperture_match (sourceImage->aperture[i], destinationImage);
967 
968  /* if we already have an existing aperture in the destination image that matches what
969  we want, just use it instead */
970  if (existingAperture > 0) {
971  gerb_translation_entry_t translationEntry={i,existingAperture};
972  g_array_append_val (apertureNumberTable,translationEntry);
973  }
974  /* else, create a new aperture and put it in the destination image */
975  else {
976  gerbv_aperture_t *newAperture = gerbv_image_duplicate_aperture (sourceImage->aperture[i]);
977 
978  lastUsedApertureNumber = gerbv_image_find_unused_aperture_number (lastUsedApertureNumber + 1, destinationImage);
979  /* store the aperture numbers (new and old) in the translation table */
980  gerb_translation_entry_t translationEntry={i,lastUsedApertureNumber};
981  g_array_append_val (apertureNumberTable,translationEntry);
982 
983  destinationImage->aperture[lastUsedApertureNumber] = newAperture;
984  }
985  }
986  }
987  /* find the last layer, state, and net in the linked chains */
988  gerbv_netstate_t *lastState;
989  gerbv_layer_t *lastLayer;
990  gerbv_net_t *lastNet;
991 
992  for (lastState = destinationImage->states; lastState->next; lastState=lastState->next){}
993  for (lastLayer = destinationImage->layers; lastLayer->next; lastLayer=lastLayer->next){}
994  for (lastNet = destinationImage->netlist; lastNet->next; lastNet=lastNet->next){}
995 
996  /* and then copy them all to the destination image, using the aperture translation table we just built */
997  gerbv_image_copy_all_nets (sourceImage, destinationImage, lastLayer, lastState, lastNet, transform, apertureNumberTable);
998  g_array_free (apertureNumberTable, TRUE);
999 }
1000 
1001 void
1003  gerbv_net_t *tempNet;
1004 
1005  g_assert (currentNet);
1006  /* we have a match, so just zero out all the important data fields */
1007  currentNet->aperture = 0;
1009 
1010  /* if this is a polygon start, we need to erase all the rest of the
1011  nets in this polygon too */
1012  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_START){
1013  for (tempNet = currentNet->next; tempNet; tempNet = tempNet->next){
1014  tempNet->aperture = 0;
1016 
1017  if (tempNet->interpolation == GERBV_INTERPOLATION_PAREA_END) {
1019  break;
1020  }
1021  /* make sure we don't leave a polygon interpolation in, since
1022  it will still draw if it is */
1024  }
1025  }
1026  /* make sure we don't leave a polygon interpolation in, since
1027  it will still draw if it is */
1029 }
1030 
1031 void
1033  gdouble coordinateY, gdouble width, gdouble height) {
1034  gerbv_net_t *currentNet;
1035 
1036  /* run through and find last net pointer */
1037  for (currentNet = image->netlist; currentNet->next; currentNet = currentNet->next){}
1038 
1039  /* create the polygon start node */
1040  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1042 
1043  /* go to start point (we need this to create correct RS274X export code) */
1044  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1047  currentNet->start_x = coordinateX;
1048  currentNet->start_y = coordinateY;
1049  currentNet->stop_x = coordinateX;
1050  currentNet->stop_y = coordinateY;
1051 
1052  /* draw the 4 corners */
1053  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1056  currentNet->start_x = coordinateX;
1057  currentNet->start_y = coordinateY;
1058  currentNet->stop_x = coordinateX + width;
1059  currentNet->stop_y = coordinateY;
1060  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->stop_x,currentNet->stop_y,
1061  0,0,0,0);
1062  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1063 
1064  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1067  currentNet->stop_x = coordinateX + width;
1068  currentNet->stop_y = coordinateY + height;
1069  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->stop_x,currentNet->stop_y,
1070  0,0,0,0);
1071  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1072 
1073  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1076  currentNet->stop_x = coordinateX;
1077  currentNet->stop_y = coordinateY + height;
1078  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->stop_x,currentNet->stop_y,
1079  0,0,0,0);
1080  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1081 
1082  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1085  currentNet->stop_x = coordinateX;
1086  currentNet->stop_y = coordinateY;
1087  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->stop_x,currentNet->stop_y,
1088  0,0,0,0);
1089  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1090 
1091  /* create the polygon end node */
1092  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1094 
1095  return;
1096 }
1097 
1098 gerbv_net_t *
1099 gerb_image_return_aperture_index (gerbv_image_t *image, gdouble lineWidth, int *apertureIndex){
1100  gerbv_net_t *currentNet;
1101  gerbv_aperture_t *aperture=NULL;
1102  int i;
1103 
1104  /* run through and find last net pointer */
1105  for (currentNet = image->netlist; currentNet->next; currentNet = currentNet->next){}
1106 
1107  /* try to find an existing aperture that matches the requested width and type */
1108  for (i = 0; i < APERTURE_MAX; i++) {
1109  if (image->aperture[i] != NULL) {
1110  if ((image->aperture[i]->type == GERBV_APTYPE_CIRCLE) &&
1111  (fabs (image->aperture[i]->parameter[0] - lineWidth) < 0.001)){
1112  aperture = image->aperture[i];
1113  *apertureIndex = i;
1114  break;
1115  }
1116  }
1117  }
1118 
1119  if (!aperture) {
1120  /* we didn't find a useable old aperture, so create a new one */
1121  if (!gerber_create_new_aperture (image, apertureIndex,
1122  GERBV_APTYPE_CIRCLE, lineWidth, 0)) {
1123  /* if we didn't succeed, then return */
1124  return FALSE;
1125  }
1126  }
1127  return currentNet;
1128 }
1129 
1130 void
1131 gerbv_image_create_arc_object (gerbv_image_t *image, gdouble centerX, gdouble centerY,
1132  gdouble radius, gdouble startAngle, gdouble endAngle, gdouble lineWidth,
1133  gerbv_aperture_type_t apertureType) {
1134  int apertureIndex;
1135  gerbv_net_t *currentNet;
1136  gerbv_cirseg_t cirSeg = {centerX, centerY, radius, radius, startAngle, endAngle};
1137 
1138  currentNet = gerb_image_return_aperture_index(image, lineWidth, &apertureIndex);
1139 
1140  if (!currentNet)
1141  return;
1142 
1143  /* draw the arc */
1144  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1147  currentNet->aperture = apertureIndex;
1148  currentNet->start_x = centerX + (cos(DEG2RAD(startAngle)) * radius);
1149  currentNet->start_y = centerY + (sin(DEG2RAD(startAngle)) * radius);
1150  currentNet->stop_x = centerX + (cos(DEG2RAD(endAngle)) * radius);
1151  currentNet->stop_y = centerY + (sin(DEG2RAD(endAngle)) * radius);
1152  currentNet->cirseg = g_new0 (gerbv_cirseg_t,1);
1153  *(currentNet->cirseg) = cirSeg;
1154 
1155  gdouble angleDiff = currentNet->cirseg->angle2 - currentNet->cirseg->angle1;
1156  gint i, steps = fabs(angleDiff);
1157  for (i=0; i<=steps; i++){
1158  gdouble tempX = currentNet->cirseg->cp_x + currentNet->cirseg->width / 2.0 *
1159  cos (DEG2RAD(currentNet->cirseg->angle1 +
1160  (i*angleDiff)/steps));
1161  gdouble tempY = currentNet->cirseg->cp_y + currentNet->cirseg->width / 2.0 *
1162  sin (DEG2RAD(currentNet->cirseg->angle1 +
1163  (i*angleDiff)/steps));
1164  gerber_update_min_and_max (&currentNet->boundingBox,
1165  tempX, tempY,
1166  lineWidth/2,lineWidth/2,
1167  lineWidth/2,lineWidth/2);
1168  }
1169  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1170  return;
1171 }
1172 
1173 void
1174 gerbv_image_create_line_object (gerbv_image_t *image, gdouble startX, gdouble startY,
1175  gdouble endX, gdouble endY, gdouble lineWidth, gerbv_aperture_type_t apertureType) {
1176  int apertureIndex;
1177  gerbv_net_t *currentNet;
1178 
1179  currentNet = gerb_image_return_aperture_index(image, lineWidth, &apertureIndex);
1180 
1181  if (!currentNet)
1182  return;
1183 
1184  /* draw the line */
1185  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1187 
1188  /* if the start and end coordinates are the same, use a "flash" aperture state */
1189  if ((fabs(startX - endX) < 0.001) && (fabs(startY - endY) < 0.001))
1191  else
1193  currentNet->aperture = apertureIndex;
1194  currentNet->start_x = startX;
1195  currentNet->start_y = startY;
1196  currentNet->stop_x = endX;
1197  currentNet->stop_y = endY;
1198 
1199  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->stop_x,currentNet->stop_y,
1200  lineWidth/2,lineWidth/2,lineWidth/2,lineWidth/2);
1201  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->start_x,currentNet->start_y,
1202  lineWidth/2,lineWidth/2,lineWidth/2,lineWidth/2);
1203  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1204  return;
1205 }
1206 
1207 void
1208 gerbv_image_create_window_pane_objects (gerbv_image_t *image, gdouble lowerLeftX,
1209  gdouble lowerLeftY, gdouble width, gdouble height, gdouble areaReduction,
1210  gint paneRows, gint paneColumns, gdouble paneSeparation){
1211  int i,j;
1212  gdouble startX,startY,boxWidth,boxHeight;
1213 
1214  startX = lowerLeftX + (areaReduction * width) / 2.0;
1215  startY = lowerLeftY + (areaReduction * height) / 2.0;
1216  boxWidth = (width * (1.0 - areaReduction) - (paneSeparation * (paneColumns - 1))) / paneColumns;
1217  boxHeight = (height * (1.0 - areaReduction) - (paneSeparation * (paneRows - 1))) / paneRows;
1218 
1219  for (i=0; i<paneColumns; i++){
1220  for (j=0; j<paneRows; j++) {
1221  gerbv_image_create_rectangle_object (image, startX + (i * (boxWidth + paneSeparation)),
1222  startY + (j * (boxHeight + paneSeparation)),boxWidth, boxHeight);
1223  }
1224  }
1225 
1226  return;
1227 }
1228 
1229 gboolean
1230 gerbv_image_reduce_area_of_selected_objects (GArray *selectionArray,
1231  gdouble areaReduction, gint paneRows, gint paneColumns, gdouble paneSeparation){
1232  gdouble minX,minY,maxX,maxY;
1233 
1234  for (guint i=0; i<selectionArray->len; i++) {
1235  gerbv_selection_item_t sItem = g_array_index (selectionArray,gerbv_selection_item_t, i);
1236  gerbv_image_t *image = sItem.image;
1237  gerbv_net_t *currentNet = sItem.net;
1238 
1239  /* determine the object type first */
1240  minX = HUGE_VAL;
1241  maxX = -HUGE_VAL;
1242  minY = HUGE_VAL;
1243  maxY = -HUGE_VAL;
1244 
1245  switch (currentNet->interpolation) {
1247  /* if it's a polygon, just determine the overall area of it and delete it */
1249 
1250  for (currentNet = currentNet->next; currentNet; currentNet = currentNet->next){
1251  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_END)
1252  break;
1254  if (currentNet->stop_x < minX)
1255  minX = currentNet->stop_x;
1256  if (currentNet->stop_y < minY)
1257  minY = currentNet->stop_y;
1258  if (currentNet->stop_x > maxX)
1259  maxX = currentNet->stop_x;
1260  if (currentNet->stop_y > maxY)
1261  maxY = currentNet->stop_y;
1262  }
1264 
1265  break;
1266 
1271  gdouble dx=0,dy=0;
1272  gerbv_aperture_t *apert =
1273  image->aperture[currentNet->aperture];
1274 
1275  /* figure out the overall size of this element */
1276  switch (apert->type) {
1277  case GERBV_APTYPE_CIRCLE :
1278  case GERBV_APTYPE_OVAL :
1279  case GERBV_APTYPE_POLYGON :
1280  dx = dy = apert->parameter[0];
1281  break;
1282  case GERBV_APTYPE_RECTANGLE :
1283  dx = apert->parameter[0]/2;
1284  dy = apert->parameter[1]/2;
1285  break;
1286  default :
1287  break;
1288  }
1289  if (currentNet->start_x-dx < minX)
1290  minX = currentNet->start_x-dx;
1291  if (currentNet->start_y-dy < minY)
1292  minY = currentNet->start_y-dy;
1293  if (currentNet->start_x+dx > maxX)
1294  maxX = currentNet->start_x+dx;
1295  if (currentNet->start_y+dy > maxY)
1296  maxY = currentNet->start_y+dy;
1297 
1298  if (currentNet->stop_x-dx < minX)
1299  minX = currentNet->stop_x-dx;
1300  if (currentNet->stop_y-dy < minY)
1301  minY = currentNet->stop_y-dy;
1302  if (currentNet->stop_x+dx > maxX)
1303  maxX = currentNet->stop_x+dx;
1304  if (currentNet->stop_y+dy > maxY)
1305  maxY = currentNet->stop_y+dy;
1306 
1307  /* finally, delete node */
1309 
1310  break;
1311  }
1312 
1313  default:
1314  /* we don't current support arcs */
1315  return FALSE;
1316  }
1317 
1318  /* create new structures */
1319  gerbv_image_create_window_pane_objects (image, minX, minY, maxX - minX, maxY - minY,
1320  areaReduction, paneRows, paneColumns, paneSeparation);
1321  }
1322  return TRUE;
1323 }
1324 
1325 gboolean
1326 gerbv_image_move_selected_objects (GArray *selectionArray, gdouble translationX,
1327  gdouble translationY)
1328 {
1329  for (guint i=0; i<selectionArray->len; i++) {
1330  gerbv_selection_item_t sItem = g_array_index (selectionArray,gerbv_selection_item_t, i);
1331  gerbv_net_t *currentNet = sItem.net;
1332 
1333  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_START) {
1334  /* if it's a polygon, step through every vertex and translate the point */
1335  for (currentNet = currentNet->next; currentNet; currentNet = currentNet->next){
1336  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_END)
1337  break;
1338  currentNet->start_x += translationX;
1339  currentNet->start_y += translationY;
1340  currentNet->stop_x += translationX;
1341  currentNet->stop_y += translationY;
1342  }
1343  }
1344  else {
1345  /* otherwise, just move the single element */
1346  currentNet->start_x += translationX;
1347  currentNet->start_y += translationY;
1348  currentNet->stop_x += translationX;
1349  currentNet->stop_y += translationY;
1350  }
1351  }
1352  return TRUE;
1353 }
1354 
1355 gerbv_net_t *
1357  gerbv_net_t *currentNet=oldNet;
1358 
1359  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_START) {
1360  /* if it's a polygon, step to the next non-polygon net */
1361  for (currentNet = currentNet->next; currentNet; currentNet = currentNet->next){
1362  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_END) {
1363  return currentNet->next;
1364  }
1365  }
1366  return NULL;
1367  }
1368  else {
1369  return currentNet->next;
1370  }
1371 }
1372 
1373 void
1375  gerbv_net_t *currentNet;
1376 
1377  /* run through and find last net pointer */
1378  for (currentNet = parsed_image->netlist; currentNet->next; currentNet = currentNet->next){
1379  if (parsed_image->aperture[currentNet->aperture] == NULL) {
1380  parsed_image->aperture[currentNet->aperture] = g_new0 (gerbv_aperture_t, 1);
1381  parsed_image->aperture[currentNet->aperture]->type = GERBV_APTYPE_CIRCLE;
1382  parsed_image->aperture[currentNet->aperture]->parameter[0] = 0;
1383  parsed_image->aperture[currentNet->aperture]->parameter[1] = 0;
1384  }
1385  }
1386 }
Aperture macro parsing header info.
void gerbv_drill_stats_destroy(gerbv_drill_stats_t *stats)
Definition: drill_stats.c:101
void gerbv_destroy_image(gerbv_image_t *image)
Free an image structure.
Definition: gerb_image.c:106
void gerbv_image_create_rectangle_object(gerbv_image_t *image, gdouble coordinateX, gdouble coordinateY, gdouble width, gdouble height)
Draw a filled rectangle on the specified image
Definition: gerb_image.c:1032
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:958
gerbv_image_t * gerbv_create_image(gerbv_image_t *image, const gchar *type)
Allocate a new gerbv_image structure.
Definition: gerb_image.c:46
void gerbv_image_create_line_object(gerbv_image_t *image, gdouble startX, gdouble startY, gdouble endX, gdouble endY, gdouble lineWidth, gerbv_aperture_type_t apertureType)
Draw a line on the specified image.
Definition: gerb_image.c:1174
void gerbv_image_delete_net(gerbv_net_t *currentNet)
Delete a net in an existing image.
Definition: gerb_image.c:1002
gerbv_net_t * gerbv_image_return_next_renderable_object(gerbv_net_t *oldNet)
Return the next net entry which corresponds to a unique visible object.
Definition: gerb_image.c:1356
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:920
void gerbv_image_create_dummy_apertures(gerbv_image_t *parsed_image)
Create any missing apertures in the specified image.
Definition: gerb_image.c:1374
void gerbv_image_create_arc_object(gerbv_image_t *image, gdouble centerX, gdouble centerY, gdouble radius, gdouble startAngle, gdouble endAngle, gdouble lineWidth, gerbv_aperture_type_t apertureType)
Draw an arc on the specified image.
Definition: gerb_image.c:1131
Header info for the image editing and support functions.
void gerbv_stats_destroy(gerbv_stats_t *stats)
Definition: gerb_stats.c:103
Header info for the RS274X parsing functions.
const char * gerbv_interpolation_name(gerbv_interpolation_t interp)
Return string name of gerbv_interpolation_t interpolation.
Definition: gerbv.c:115
void gerbv_transform_coord(double *x, double *y, const gerbv_user_transformation_t *trans)
Definition: gerbv.c:1153
The main header file for the libgerbv library.
gerbv_aperture_state_t
Definition: gerbv.h:178
@ GERBV_APERTURE_STATE_OFF
Definition: gerbv.h:178
@ GERBV_APERTURE_STATE_ON
Definition: gerbv.h:179
@ GERBV_APERTURE_STATE_FLASH
Definition: gerbv.h:180
@ GERBV_POLARITY_DARK
Definition: gerbv.h:283
gerbv_aperture_type_t
Definition: gerbv.h:158
@ GERBV_APTYPE_MACRO_LINE20
Definition: gerbv.h:170
@ GERBV_APTYPE_MACRO_LINE21
Definition: gerbv.h:171
@ GERBV_APTYPE_OVAL
Definition: gerbv.h:162
@ GERBV_APTYPE_MACRO_OUTLINE
Definition: gerbv.h:166
@ GERBV_APTYPE_MACRO_CIRCLE
Definition: gerbv.h:165
@ GERBV_APTYPE_MACRO
Definition: gerbv.h:164
@ GERBV_APTYPE_CIRCLE
Definition: gerbv.h:160
@ GERBV_APTYPE_NONE
Definition: gerbv.h:159
@ GERBV_APTYPE_POLYGON
Definition: gerbv.h:163
@ GERBV_APTYPE_MACRO_POLYGON
Definition: gerbv.h:167
@ GERBV_APTYPE_RECTANGLE
Definition: gerbv.h:161
@ GERBV_APTYPE_MACRO_THERMAL
Definition: gerbv.h:169
@ GERBV_APTYPE_MACRO_LINE22
Definition: gerbv.h:172
@ GERBV_APTYPE_MACRO_MOIRE
Definition: gerbv.h:168
@ GERBV_INTERPOLATION_LINEARx01
Definition: gerbv.h:304
@ GERBV_INTERPOLATION_PAREA_START
Definition: gerbv.h:308
@ GERBV_INTERPOLATION_LINEARx001
Definition: gerbv.h:305
@ GERBV_INTERPOLATION_DELETED
Definition: gerbv.h:310
@ GERBV_INTERPOLATION_PAREA_END
Definition: gerbv.h:309
@ GERBV_INTERPOLATION_LINEARx10
Definition: gerbv.h:303
@ GERBV_INTERPOLATION_CCW_CIRCULAR
Definition: gerbv.h:307
@ GERBV_INTERPOLATION_LINEARx1
Definition: gerbv.h:302
@ GERBV_LAYERTYPE_DRILL
Definition: gerbv.h:329
Header info for common structs and functions used for the GUI application.
gerbv_amacro_t * amacro
Definition: gerbv.h:726
gerbv_stats_t * gerbv_stats
Definition: gerbv.h:730
gerbv_format_t * format
Definition: gerbv.h:727
gerbv_layer_t * layers
Definition: gerbv.h:724
gerbv_layertype_t layertype
Definition: gerbv.h:722
gerbv_net_t * netlist
Definition: gerbv.h:729
gerbv_drill_stats_t * drill_stats
Definition: gerbv.h:731
gerbv_aperture_t * aperture[APERTURE_MAX]
Definition: gerbv.h:723
gerbv_netstate_t * states
Definition: gerbv.h:725
gerbv_image_info_t * info
Definition: gerbv.h:728
gchar * name
Definition: gerbv.h:639
gerbv_step_and_repeat_t stepAndRepeat
Definition: gerbv.h:635
gerbv_polarity_t polarity
Definition: gerbv.h:638
gerbv_knockout_t knockout
Definition: gerbv.h:636
gpointer next
Definition: gerbv.h:640
gerbv_render_size_t boundingBox
Definition: gerbv.h:661
gerbv_layer_t * layer
Definition: gerbv.h:668
double stop_y
Definition: gerbv.h:660
GString * label
Definition: gerbv.h:667
gerbv_aperture_state_t aperture_state
Definition: gerbv.h:663
double stop_x
Definition: gerbv.h:659
double start_x
Definition: gerbv.h:657
gerbv_netstate_t * state
Definition: gerbv.h:669
struct gerbv_net * next
Definition: gerbv.h:666
double start_y
Definition: gerbv.h:658
gerbv_interpolation_t interpolation
Definition: gerbv.h:664
gerbv_cirseg_t * cirseg
Definition: gerbv.h:665
int aperture
Definition: gerbv.h:662
gdouble scaleA
Definition: gerbv.h:650
gdouble scaleB
Definition: gerbv.h:651
gpointer next
Definition: gerbv.h:652