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, n_nets;;
213  gerbv_net_t *net;
214 
215  if (image->netlist == NULL) error |= GERB_IMAGE_MISSING_NETLIST;
216  if (image->format == NULL) error |= GERB_IMAGE_MISSING_FORMAT;
217  if (image->info == NULL) error |= GERB_IMAGE_MISSING_INFO;
218 
219  /* Count how many nets we have */
220  n_nets = 0;
221  if (image->netlist != NULL) {
222  for (net = image->netlist->next ; net != NULL; net = net->next) {
223  n_nets++;
224  }
225  }
226 
227  /* If we have nets but no apertures are defined, then complain */
228  if( n_nets > 0) {
229  for (i = 0; i < APERTURE_MAX && image->aperture[i] == NULL; i++);
230  if (i == APERTURE_MAX) error |= GERB_IMAGE_MISSING_APERTURES;
231  }
232 
233  return error;
234 } /* gerb_image_verify */
235 
236 static void
237 gerbv_image_aperture_state(gerbv_aperture_state_t state)
238 {
239  switch (state) {
241  printf(_("..state off"));
242  break;
244  printf(_("..state on"));
245  break;
247  printf(_("..state flash"));
248  break;
249  default:
250  printf(_("..state unknown"));
251  }
252 }
253 
254 /* Dumps a written version of image to stdout */
255 void
256 gerbv_image_dump(gerbv_image_t const* image)
257 {
258  int i, j;
259  gerbv_aperture_t * const* aperture;
260  gerbv_net_t const * net;
261 
262  /* Apertures */
263  printf(_("Apertures:\n"));
264  aperture = image->aperture;
265  for (i = 0; i < APERTURE_MAX; i++) {
266  if (aperture[i]) {
267  printf(_(" Aperture no:%d is an "), i);
268  switch(aperture[i]->type) {
269  case GERBV_APTYPE_CIRCLE:
270  printf(_("circle"));
271  break;
273  printf(_("rectangle"));
274  break;
275  case GERBV_APTYPE_OVAL:
276  printf(_("oval"));
277  break;
279  printf(_("polygon"));
280  break;
281  case GERBV_APTYPE_MACRO:
282  printf(_("macro"));
283  break;
284  default:
285  printf(_("unknown"));
286  }
287  for (j = 0; j < aperture[i]->nuf_parameters; j++) {
288  printf(" %f", aperture[i]->parameter[j]);
289  }
290  printf("\n");
291  }
292  }
293 
294  /* Netlist */
295  net = image->netlist;
296  while (net){
297  printf(_("(%f,%f)->(%f,%f) with %d ("), net->start_x, net->start_y,
298  net->stop_x, net->stop_y, net->aperture);
299  printf("%s", _(gerbv_interpolation_name(net->interpolation)));
300  gerbv_image_aperture_state(net->aperture_state);
301  printf(")\n");
302  net = net->next;
303  }
304 } /* gerbv_image_dump */
305 
306 
308 gerbv_image_return_new_layer (gerbv_layer_t *previousLayer)
309 {
310  gerbv_layer_t *newLayer = g_new0 (gerbv_layer_t, 1);
311 
312  *newLayer = *previousLayer;
313  previousLayer->next = newLayer;
314  /* clear this boolean so we only draw the knockout once */
315  newLayer->knockout.firstInstance = FALSE;
316  newLayer->name = NULL;
317  newLayer->next = NULL;
318 
319  return newLayer;
320 } /* gerbv_image_return_new_layer */
321 
322 
324 gerbv_image_return_new_netstate (gerbv_netstate_t *previousState)
325 {
326  gerbv_netstate_t *newState = g_new0 (gerbv_netstate_t, 1);
327 
328  *newState = *previousState;
329  previousState->next = newState;
330  newState->scaleA = 1.0;
331  newState->scaleB = 1.0;
332  newState->next = NULL;
333 
334  return newState;
335 } /* gerbv_image_return_new_netstate */
336 
338 gerbv_image_duplicate_layer (gerbv_layer_t *oldLayer) {
339  gerbv_layer_t *newLayer = g_new (gerbv_layer_t,1);
340 
341  *newLayer = *oldLayer;
342  newLayer->name = g_strdup (oldLayer->name);
343  newLayer->next = NULL;
344  return newLayer;
345 }
346 
347 static gerbv_netstate_t *
348 gerbv_image_duplicate_state (gerbv_netstate_t *oldState)
349 {
350  gerbv_netstate_t *newState = g_new (gerbv_netstate_t, 1);
351 
352  *newState = *oldState;
353  newState->next = NULL;
354  return newState;
355 }
356 
357 static gerbv_aperture_t *
358 gerbv_image_duplicate_aperture (gerbv_aperture_t *oldAperture)
359 {
360  gerbv_aperture_t *newAperture = g_new0 (gerbv_aperture_t,1);
361  gerbv_simplified_amacro_t *simplifiedMacro, *tempSimplified;
362 
363  *newAperture = *oldAperture;
364 
365  /* delete the amacro section, since we really don't need it anymore
366  now that we have the simplified section */
367  newAperture->amacro = NULL;
368  newAperture->simplified = NULL;
369 
370  /* copy any simplified macros over */
371  tempSimplified = NULL;
372  for (simplifiedMacro = oldAperture->simplified; simplifiedMacro != NULL; simplifiedMacro = simplifiedMacro->next) {
373  gerbv_simplified_amacro_t *newSimplified = g_new0 (gerbv_simplified_amacro_t,1);
374  *newSimplified = *simplifiedMacro;
375  if (tempSimplified)
376  tempSimplified->next = newSimplified;
377  else
378  newAperture->simplified = newSimplified;
379  tempSimplified = newSimplified;
380  }
381  return newAperture;
382 }
383 
384 static void
385 gerbv_image_copy_all_nets (gerbv_image_t *sourceImage,
386  gerbv_image_t *destImage, gerbv_layer_t *lastLayer,
387  gerbv_netstate_t *lastState, gerbv_net_t *lastNet,
389  GArray *translationTable)
390 {
391  /* NOTE: destImage already contains apertures and data,
392  * latest data is: lastLayer, lastState, lastNet. */
393 
394  gerbv_net_t *currentNet, *newNet;
395  gerbv_layer_t *srcLayer = NULL;
396  gerbv_netstate_t *srcState = NULL;
397  gerbv_aperture_type_t aper_type;
398  gerbv_aperture_t *aper;
399  gerbv_simplified_amacro_t *sam;
400  int *trans_apers = NULL; /* Transformed apertures */
401  int aper_last_id = 0;
402  guint err_scale_circle = 0,
403  err_scale_line_macro = 0,
404  err_scale_poly_macro = 0,
405  err_scale_thermo_macro = 0,
406  err_scale_moire_macro = 0,
407  err_unknown_aperture = 0,
408  err_unknown_macro_aperture = 0,
409  err_rotate_oval = 0,
410  err_rotate_rect = 0;
411 
412  if (trans && (trans->mirrorAroundX || trans->mirrorAroundY)) {
413  if (sourceImage->layertype != GERBV_LAYERTYPE_DRILL) {
414  GERB_COMPILE_ERROR(_("Exporting mirrored file "
415  "is not supported!"));
416  return;
417  }
418  }
419 
420  if (trans && trans->inverted) {
421  GERB_COMPILE_ERROR(_("Exporting inverted file "
422  "is not supported!"));
423  return;
424  }
425 
426  if (trans) {
427  /* Find last used aperture to add transformed apertures if
428  * needed */
429  for (aper_last_id = APERTURE_MAX - 1; aper_last_id > 0;
430  aper_last_id--) {
431  if (destImage->aperture[aper_last_id] != NULL)
432  break;
433  }
434 
435  trans_apers = g_new (int, aper_last_id + 1);
436  /* Initialize trans_apers array */
437  for (int i = 0; i < aper_last_id + 1; i++)
438  trans_apers[i] = -1;
439  }
440 
441  for (currentNet = sourceImage->netlist; currentNet != NULL;
442  currentNet = currentNet->next) {
443 
444  /* Check for any new layers and duplicate them if needed.
445  * Compare against the source pointer, not the duplicated
446  * pointer, to avoid creating redundant duplicates when
447  * consecutive nets share the same layer. */
448  if (currentNet->layer != srcLayer) {
449  srcLayer = currentNet->layer;
450  lastLayer->next =
451  gerbv_image_duplicate_layer (currentNet->layer);
452  lastLayer = lastLayer->next;
453  }
454 
455  /* Check for any new states and duplicate them if needed.
456  * Same source-pointer tracking as layers above. */
457  if (currentNet->state != srcState) {
458  srcState = currentNet->state;
459  lastState->next =
460  gerbv_image_duplicate_state (currentNet->state);
461  lastState = lastState->next;
462  }
463 
464  /* Create and copy the actual net over */
465  newNet = g_new (gerbv_net_t, 1);
466  *newNet = *currentNet;
467 
468  if (currentNet->cirseg) {
469  newNet->cirseg = g_new (gerbv_cirseg_t, 1);
470  *(newNet->cirseg) = *(currentNet->cirseg);
471  }
472 
473  if (currentNet->label)
474  newNet->label = g_string_new (currentNet->label->str);
475  else
476  newNet->label = NULL;
477 
478  newNet->state = lastState;
479  newNet->layer = lastLayer;
480 
481  if (lastNet)
482  lastNet->next = newNet;
483  else
484  destImage->netlist = newNet;
485 
486  lastNet = newNet;
487 
488  /* Check if we need to translate the aperture number */
489  if (translationTable) {
490  for (guint i = 0; i < translationTable->len; i++) {
491  gerb_translation_entry_t translationEntry;
492 
493  translationEntry =
494  g_array_index (translationTable,
495  gerb_translation_entry_t, i);
496 
497  if (translationEntry.oldAperture ==
498  newNet->aperture) {
499  newNet->aperture =
500  translationEntry.newAperture;
501  break;
502  }
503  }
504  }
505 
506  if (trans == NULL)
507  continue;
508 
509  /* Transforming coords */
510  gerbv_transform_coord (&newNet->start_x,
511  &newNet->start_y, trans);
512  gerbv_transform_coord (&newNet->stop_x,
513  &newNet->stop_y, trans);
514 
515  if (newNet->cirseg) {
516  /* Circular interpolation only exported by start, stop
517  * end center coordinates. */
518  gerbv_transform_coord (&newNet->cirseg->cp_x,
519  &newNet->cirseg->cp_y, trans);
520  }
521 
522  if (destImage->aperture[newNet->aperture] == NULL)
523  continue;
524 
525  if (trans->scaleX == 1.0 && trans->scaleY == 1.0
526  && fabs(trans->rotation) < GERBV_PRECISION_ANGLE_RAD)
527  continue;
528 
529  /* Aperture is already transformed, use it */
530  if (trans_apers[newNet->aperture] != -1) {
531  newNet->aperture = trans_apers[newNet->aperture];
532  continue;
533  }
534 
535  /* Transforming apertures */
536  aper_type = destImage->aperture[newNet->aperture]->type;
537  switch (aper_type) {
538  case GERBV_APTYPE_NONE:
540  break;
541 
542  case GERBV_APTYPE_CIRCLE:
543  if (trans->scaleX == trans->scaleY
544  && trans->scaleX == 1.0) {
545  break;
546  }
547 
548  if (trans->scaleX == trans->scaleY) {
549  aper = gerbv_image_duplicate_aperture (
550  destImage->aperture[
551  newNet->aperture]);
552  aper->parameter[0] *= trans->scaleX;
553 
554  trans_apers[newNet->aperture] = ++aper_last_id;
555  destImage->aperture[aper_last_id] = aper;
556  newNet->aperture = aper_last_id;
557  } else {
558  err_scale_circle++;
559  }
560  break;
561 
563  case GERBV_APTYPE_OVAL:
564  if (trans->scaleX == 1.0 && trans->scaleY == 1.0
565  && fabs(fabs(trans->rotation) - M_PI)
566  < GERBV_PRECISION_ANGLE_RAD)
567  break;
568 
569  aper = gerbv_image_duplicate_aperture (
570  destImage->aperture[newNet->aperture]);
571  aper->parameter[0] *= trans->scaleX;
572  aper->parameter[1] *= trans->scaleY;
573 
574  if (fabs(fabs(trans->rotation) - M_PI_2)
575  < GERBV_PRECISION_ANGLE_RAD
576  || fabs(fabs(trans->rotation) - (M_PI+M_PI_2))
577  < GERBV_PRECISION_ANGLE_RAD) {
578  double t = aper->parameter[0];
579  aper->parameter[0] = aper->parameter[1];
580  aper->parameter[1] = t;
581  } else {
582  if (aper_type == GERBV_APTYPE_RECTANGLE)
583  err_rotate_rect++; /* TODO: make line21 macro */
584  else
585  err_rotate_oval++;
586 
587  break;
588  }
589 
590  trans_apers[newNet->aperture] = ++aper_last_id;
591  destImage->aperture[aper_last_id] = aper;
592  newNet->aperture = aper_last_id;
593 
594  break;
595 
596  case GERBV_APTYPE_MACRO:
597  aper = gerbv_image_duplicate_aperture (
598  destImage->aperture[newNet->aperture]);
599  sam = aper->simplified;
600 
601  for (; sam != NULL; sam = sam->next) {
602  switch (sam->type) {
604  sam->parameter[CIRCLE_CENTER_X] *=
605  trans->scaleX;
606  sam->parameter[CIRCLE_CENTER_Y] *=
607  trans->scaleY;
608  sam->parameter[CIRCLE_ROTATION] +=
609  RAD2DEG(trans->rotation);
610 
611  if (trans->scaleX != trans->scaleY) {
612  err_scale_circle++;
613  break;
614  }
615  sam->parameter[CIRCLE_DIAMETER] *=
616  trans->scaleX;
617  break;
618 
620  /* Vector line rectangle */
621  if (trans->scaleX == trans->scaleY) {
622  sam->parameter[LINE20_LINE_WIDTH] *=
623  trans->scaleX;
624  } else if (sam->parameter[LINE20_START_X] ==
625  sam->parameter[LINE20_END_X]) {
626  sam->parameter[LINE20_LINE_WIDTH] *=
627  trans->scaleX; /* Vertical */
628  } else if (sam->parameter[LINE20_START_Y] ==
629  sam->parameter[LINE20_END_Y]) {
630  sam->parameter[LINE20_LINE_WIDTH] *=
631  trans->scaleY; /* Horizontal */
632  } else {
633  /* TODO: make outline macro */
634  err_scale_line_macro++;
635  break;
636  }
637 
638  sam->parameter[LINE20_START_X] *=
639  trans->scaleX;
640  sam->parameter[LINE20_START_Y] *=
641  trans->scaleY;
642  sam->parameter[LINE20_END_X] *=
643  trans->scaleX;
644  sam->parameter[LINE20_END_Y] *=
645  trans->scaleY;
646 
647  /* LINE20_START_X, LINE20_START_Y,
648  * LINE20_END_X, LINE20_END_Y are not
649  * rotated, change only rotation angle */
650  sam->parameter[LINE20_ROTATION] +=
651  RAD2DEG(trans->rotation);
652  break;
653 
654 /* Compile time check if LINE21 and LINE22 parameters indexes are equal */
655 #if (LINE21_WIDTH != LINE22_WIDTH) \
656  || (LINE21_HEIGHT != LINE22_HEIGHT) \
657  || (LINE21_ROTATION != LINE22_ROTATION) \
658  || (LINE21_CENTER_X != LINE22_LOWER_LEFT_X) \
659  || (LINE21_CENTER_Y != LINE22_LOWER_LEFT_Y)
660 # error "LINE21 and LINE22 indexes are not equal"
661 #endif
662 
664  /* Centered line rectangle */
666  /* Lower left line rectangle */
667 
668  /* Using LINE21 parameters array
669  * indexes for LINE21 and LINE22, as
670  * they are equal */
671  if (trans->scaleX == trans->scaleY) {
672  sam->parameter[LINE21_WIDTH] *=
673  trans->scaleX;
674  sam->parameter[LINE21_HEIGHT] *=
675  trans->scaleX;
676 
677  } else if (fabs(sam->parameter[LINE21_ROTATION]) == 0
678  || fabs(sam->parameter[LINE21_ROTATION]) == 180) {
679  sam->parameter[LINE21_WIDTH] *=
680  trans->scaleX;
681  sam->parameter[LINE21_HEIGHT] *=
682  trans->scaleY;
683 
684  } else if (fabs(sam->parameter[LINE21_ROTATION]) == 90
685  || fabs(sam->parameter[LINE21_ROTATION]) == 270) {
686  double t;
687  t = sam->parameter[LINE21_WIDTH];
688  sam->parameter[LINE21_WIDTH] =
689  trans->scaleY *
690  sam->parameter[
691  LINE21_HEIGHT];
692  sam->parameter[LINE21_HEIGHT] =
693  trans->scaleX * t;
694  } else {
695  /* TODO: make outline macro */
696  err_scale_line_macro++;
697  break;
698  }
699 
700  sam->parameter[LINE21_CENTER_X] *=
701  trans->scaleX;
702  sam->parameter[LINE21_CENTER_Y] *=
703  trans->scaleY;
704 
705  sam->parameter[LINE21_ROTATION] +=
706  RAD2DEG(trans->rotation);
707  break;
708 
710  for (int i = 0; i < 1 + sam->parameter[
711  OUTLINE_NUMBER_OF_POINTS]; i++) {
712  sam->parameter[OUTLINE_X_IDX_OF_POINT(i)] *=
713  trans->scaleX;
714  sam->parameter[OUTLINE_Y_IDX_OF_POINT(i)] *=
715  trans->scaleY;
716  }
717 
718  sam->parameter[OUTLINE_ROTATION_IDX(sam->parameter)] +=
719  RAD2DEG(trans->rotation);
720  break;
721 #if 0
722 {
723 /* TODO */
724 #include "main.h"
725 gerbv_selection_item_t sItem = {sourceImage, currentNet};
726 selection_add_item (&screen.selectionInfo, &sItem);
727 }
728 #endif
729 
731  if (trans->scaleX == trans->scaleY) {
732  sam->parameter[POLYGON_CENTER_X]
733  *= trans->scaleX;
734  sam->parameter[POLYGON_CENTER_Y]
735  *= trans->scaleX;
736  sam->parameter[POLYGON_DIAMETER]
737  *= trans->scaleX;
738  } else {
739  /* TODO: make outline macro */
740  err_scale_poly_macro++;
741  break;
742  }
743 
744  sam->parameter[POLYGON_ROTATION] +=
745  RAD2DEG(trans->rotation);
746  break;
747 
749  if (trans->scaleX == trans->scaleY) {
750  sam->parameter[MOIRE_CENTER_X]
751  *= trans->scaleX;
752  sam->parameter[MOIRE_CENTER_Y]
753  *= trans->scaleX;
754  sam->parameter[MOIRE_OUTSIDE_DIAMETER]
755  *= trans->scaleX;
756  sam->parameter[MOIRE_CIRCLE_THICKNESS]
757  *= trans->scaleX;
758  sam->parameter[MOIRE_GAP_WIDTH]
759  *= trans->scaleX;
760  sam->parameter[MOIRE_CROSSHAIR_THICKNESS]
761  *= trans->scaleX;
762  sam->parameter[MOIRE_CROSSHAIR_LENGTH]
763  *= trans->scaleX;
764  } else {
765  err_scale_moire_macro++;
766  break;
767  }
768 
769  sam->parameter[MOIRE_ROTATION] +=
770  RAD2DEG(trans->rotation);
771  break;
772 
774  if (trans->scaleX == trans->scaleY) {
775  sam->parameter[THERMAL_CENTER_X]
776  *= trans->scaleX;
777  sam->parameter[THERMAL_CENTER_Y]
778  *= trans->scaleX;
779  sam->parameter[THERMAL_INSIDE_DIAMETER]
780  *= trans->scaleX;
781  sam->parameter[THERMAL_OUTSIDE_DIAMETER]
782  *= trans->scaleX;
783  sam->parameter[THERMAL_CROSSHAIR_THICKNESS]
784  *= trans->scaleX;
785  } else {
786  err_scale_thermo_macro++;
787  break;
788  }
789 
790  sam->parameter[THERMAL_ROTATION] +=
791  RAD2DEG(trans->rotation);
792  break;
793 
794  default:
795  /* TODO: free aper if it is skipped (i.e. unused)? */
796  err_unknown_macro_aperture++;
797  }
798  }
799 
800  trans_apers[newNet->aperture] = ++aper_last_id;
801  destImage->aperture[aper_last_id] = aper;
802  newNet->aperture = aper_last_id;
803 
804  break;
805  default:
806  err_unknown_aperture++;
807  }
808  }
809 
810  if (err_rotate_rect)
811  GERB_COMPILE_ERROR(ngettext(
812  "Can't rotate %u rectangular aperture to %.2f "
813  "degrees (non 90 multiply)!",
814  "Can't rotate %u rectangular apertures to %.2f "
815  "degrees (non 90 multiply)!", err_rotate_rect),
816  err_rotate_rect, RAD2DEG(trans->rotation));
817 
818  if (err_scale_line_macro)
819  GERB_COMPILE_ERROR(ngettext(
820  "Can't scale %u line macro!",
821  "Can't scale %u line macros!",
822  err_scale_line_macro), err_scale_line_macro);
823 
824  if (err_scale_poly_macro)
825  GERB_COMPILE_ERROR(ngettext(
826  "Can't scale %u polygon macro!",
827  "Can't scale %u polygon macros!",
828  err_scale_poly_macro), err_scale_poly_macro);
829 
830  if (err_scale_thermo_macro)
831  GERB_COMPILE_ERROR(ngettext(
832  "Can't scale %u thermal macro!",
833  "Can't scale %u thermal macros!",
834  err_scale_poly_macro), err_scale_poly_macro);
835 
836  if (err_scale_moire_macro)
837  GERB_COMPILE_ERROR(ngettext(
838  "Can't scale %u moire macro!",
839  "Can't scale %u moire macros!",
840  err_scale_poly_macro), err_scale_poly_macro);
841 
842  if (err_rotate_oval)
843  GERB_COMPILE_ERROR(ngettext(
844  "Can't rotate %u oval aperture to %.2f "
845  "degrees (non 90 multiply)!",
846  "Can't rotate %u oval apertures to %.2f "
847  "degrees (non 90 multiply)!", err_rotate_oval),
848  err_rotate_oval, RAD2DEG(trans->rotation));
849 
850  if (err_scale_circle)
851  GERB_COMPILE_ERROR(ngettext(
852  "Can't scale %u circle aperture to ellipse!",
853  "Can't scale %u circle apertures to ellipse!",
854  err_scale_circle), err_scale_circle);
855 
856  if (err_unknown_aperture)
857  GERB_COMPILE_ERROR(ngettext(
858  "Skipped %u aperture with unknown type!",
859  "Skipped %u apertures with unknown type!",
860  err_unknown_aperture), err_unknown_aperture);
861 
862  if (err_unknown_macro_aperture)
863  GERB_COMPILE_ERROR(ngettext(
864  "Skipped %u macro aperture!",
865  "Skipped %u macro apertures!",
866  err_unknown_macro_aperture),
867  err_unknown_macro_aperture);
868 
869  g_free (trans_apers);
870 }
871 
872 gint
873 gerbv_image_find_existing_aperture_match (gerbv_aperture_t *checkAperture, gerbv_image_t *imageToSearch) {
874  int i,j;
875  gboolean isMatch;
876 
877  for (i = 0; i < APERTURE_MAX; i++) {
878  if (imageToSearch->aperture[i] != NULL) {
879  if ((imageToSearch->aperture[i]->type == checkAperture->type) &&
880  (imageToSearch->aperture[i]->simplified == NULL) &&
881  (imageToSearch->aperture[i]->unit == checkAperture->unit)) {
882  /* check all parameters match too */
883  isMatch=TRUE;
884  for (j=0; j<APERTURE_PARAMETERS_MAX; j++){
885  if (imageToSearch->aperture[i]->parameter[j] != checkAperture->parameter[j])
886  isMatch = FALSE;
887  }
888  if (isMatch)
889  return i;
890  }
891  }
892  }
893  return 0;
894 }
895 
896 int
897 gerbv_image_find_unused_aperture_number (int startIndex, gerbv_image_t *image){
898  int i;
899 
900  for (i = startIndex; i < APERTURE_MAX; i++) {
901  if (image->aperture[i] == NULL) {
902  return i;
903  }
904  }
905  return -1;
906 }
907 
910  gerbv_image_t *newImage = gerbv_create_image(NULL, sourceImage->info->type);
911  int i;
912  int lastUsedApertureNumber = APERTURE_MIN - 1;
913  GArray *apertureNumberTable = g_array_new(FALSE,FALSE,sizeof(gerb_translation_entry_t));
914 
915  newImage->layertype = sourceImage->layertype;
916  /* copy information layer over */
917  *(newImage->info) = *(sourceImage->info);
918  newImage->info->name = g_strdup (sourceImage->info->name);
919  newImage->info->type = g_strdup (sourceImage->info->type);
920  newImage->info->plotterFilm = g_strdup (sourceImage->info->plotterFilm);
921  newImage->info->attr_list = gerbv_attribute_dup (sourceImage->info->attr_list,
922  sourceImage->info->n_attr);
923 
924  /* copy apertures over, compressing all the numbers down for a cleaner output, and
925  moving and apertures less than 10 up to the correct range */
926  for (i = 0; i < APERTURE_MAX; i++) {
927  if (sourceImage->aperture[i] != NULL) {
928  gerbv_aperture_t *newAperture = gerbv_image_duplicate_aperture (sourceImage->aperture[i]);
929 
930  lastUsedApertureNumber = gerbv_image_find_unused_aperture_number (lastUsedApertureNumber + 1, newImage);
931  /* store the aperture numbers (new and old) in the translation table */
932  gerb_translation_entry_t translationEntry={i,lastUsedApertureNumber};
933  g_array_append_val (apertureNumberTable,translationEntry);
934 
935  newImage->aperture[lastUsedApertureNumber] = newAperture;
936  }
937  }
938 
939  /* step through all nets and create new layers and states on the fly, since
940  we really don't have any other way to figure out where states and layers are used */
941  gerbv_image_copy_all_nets (sourceImage, newImage, newImage->layers, newImage->states, NULL, transform, apertureNumberTable);
942  g_array_free (apertureNumberTable, TRUE);
943  return newImage;
944 }
945 
946 void
947 gerbv_image_copy_image (gerbv_image_t *sourceImage, gerbv_user_transformation_t *transform, gerbv_image_t *destinationImage) {
948  int lastUsedApertureNumber = APERTURE_MIN - 1;
949  int i;
950  GArray *apertureNumberTable = g_array_new(FALSE,FALSE,sizeof(gerb_translation_entry_t));
951 
952  /* copy apertures over */
953  for (i = 0; i < APERTURE_MAX; i++) {
954  if (sourceImage->aperture[i] != NULL) {
955  gint existingAperture = gerbv_image_find_existing_aperture_match (sourceImage->aperture[i], destinationImage);
956 
957  /* if we already have an existing aperture in the destination image that matches what
958  we want, just use it instead */
959  if (existingAperture > 0) {
960  gerb_translation_entry_t translationEntry={i,existingAperture};
961  g_array_append_val (apertureNumberTable,translationEntry);
962  }
963  /* else, create a new aperture and put it in the destination image */
964  else {
965  gerbv_aperture_t *newAperture = gerbv_image_duplicate_aperture (sourceImage->aperture[i]);
966 
967  lastUsedApertureNumber = gerbv_image_find_unused_aperture_number (lastUsedApertureNumber + 1, destinationImage);
968  /* store the aperture numbers (new and old) in the translation table */
969  gerb_translation_entry_t translationEntry={i,lastUsedApertureNumber};
970  g_array_append_val (apertureNumberTable,translationEntry);
971 
972  destinationImage->aperture[lastUsedApertureNumber] = newAperture;
973  }
974  }
975  }
976  /* find the last layer, state, and net in the linked chains */
977  gerbv_netstate_t *lastState;
978  gerbv_layer_t *lastLayer;
979  gerbv_net_t *lastNet;
980 
981  for (lastState = destinationImage->states; lastState->next; lastState=lastState->next){}
982  for (lastLayer = destinationImage->layers; lastLayer->next; lastLayer=lastLayer->next){}
983  for (lastNet = destinationImage->netlist; lastNet->next; lastNet=lastNet->next){}
984 
985  /* and then copy them all to the destination image, using the aperture translation table we just built */
986  gerbv_image_copy_all_nets (sourceImage, destinationImage, lastLayer, lastState, lastNet, transform, apertureNumberTable);
987  g_array_free (apertureNumberTable, TRUE);
988 }
989 
990 void
992  gerbv_net_t *tempNet;
993 
994  g_assert (currentNet);
995  /* we have a match, so just zero out all the important data fields */
996  currentNet->aperture = 0;
998 
999  /* if this is a polygon start, we need to erase all the rest of the
1000  nets in this polygon too */
1001  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_START){
1002  for (tempNet = currentNet->next; tempNet; tempNet = tempNet->next){
1003  tempNet->aperture = 0;
1005 
1006  if (tempNet->interpolation == GERBV_INTERPOLATION_PAREA_END) {
1008  break;
1009  }
1010  /* make sure we don't leave a polygon interpolation in, since
1011  it will still draw if it is */
1013  }
1014  }
1015  /* make sure we don't leave a polygon interpolation in, since
1016  it will still draw if it is */
1018 }
1019 
1020 void
1022  gdouble coordinateY, gdouble width, gdouble height) {
1023  gerbv_net_t *currentNet;
1024 
1025  /* run through and find last net pointer */
1026  for (currentNet = image->netlist; currentNet->next; currentNet = currentNet->next){}
1027 
1028  /* create the polygon start node */
1029  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1031 
1032  /* go to start point (we need this to create correct RS274X export code) */
1033  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1036  currentNet->start_x = coordinateX;
1037  currentNet->start_y = coordinateY;
1038  currentNet->stop_x = coordinateX;
1039  currentNet->stop_y = coordinateY;
1040 
1041  /* draw the 4 corners */
1042  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1045  currentNet->start_x = coordinateX;
1046  currentNet->start_y = coordinateY;
1047  currentNet->stop_x = coordinateX + width;
1048  currentNet->stop_y = coordinateY;
1049  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->stop_x,currentNet->stop_y,
1050  0,0,0,0);
1051  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1052 
1053  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1056  currentNet->stop_x = coordinateX + width;
1057  currentNet->stop_y = coordinateY + height;
1058  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->stop_x,currentNet->stop_y,
1059  0,0,0,0);
1060  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1061 
1062  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1065  currentNet->stop_x = coordinateX;
1066  currentNet->stop_y = coordinateY + height;
1067  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->stop_x,currentNet->stop_y,
1068  0,0,0,0);
1069  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1070 
1071  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1074  currentNet->stop_x = coordinateX;
1075  currentNet->stop_y = coordinateY;
1076  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->stop_x,currentNet->stop_y,
1077  0,0,0,0);
1078  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1079 
1080  /* create the polygon end node */
1081  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1083 
1084  return;
1085 }
1086 
1087 gerbv_net_t *
1088 gerb_image_return_aperture_index (gerbv_image_t *image, gdouble lineWidth, int *apertureIndex){
1089  gerbv_net_t *currentNet;
1090  gerbv_aperture_t *aperture=NULL;
1091  int i;
1092 
1093  /* run through and find last net pointer */
1094  for (currentNet = image->netlist; currentNet->next; currentNet = currentNet->next){}
1095 
1096  /* try to find an existing aperture that matches the requested width and type */
1097  for (i = 0; i < APERTURE_MAX; i++) {
1098  if (image->aperture[i] != NULL) {
1099  if ((image->aperture[i]->type == GERBV_APTYPE_CIRCLE) &&
1100  (fabs (image->aperture[i]->parameter[0] - lineWidth) < 0.001)){
1101  aperture = image->aperture[i];
1102  *apertureIndex = i;
1103  break;
1104  }
1105  }
1106  }
1107 
1108  if (!aperture) {
1109  /* we didn't find a useable old aperture, so create a new one */
1110  if (!gerber_create_new_aperture (image, apertureIndex,
1111  GERBV_APTYPE_CIRCLE, lineWidth, 0)) {
1112  /* if we didn't succeed, then return */
1113  return FALSE;
1114  }
1115  }
1116  return currentNet;
1117 }
1118 
1119 void
1120 gerbv_image_create_arc_object (gerbv_image_t *image, gdouble centerX, gdouble centerY,
1121  gdouble radius, gdouble startAngle, gdouble endAngle, gdouble lineWidth,
1122  gerbv_aperture_type_t apertureType) {
1123  int apertureIndex;
1124  gerbv_net_t *currentNet;
1125  gerbv_cirseg_t cirSeg = {centerX, centerY, radius, radius, startAngle, endAngle};
1126 
1127  currentNet = gerb_image_return_aperture_index(image, lineWidth, &apertureIndex);
1128 
1129  if (!currentNet)
1130  return;
1131 
1132  /* draw the arc */
1133  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1136  currentNet->aperture = apertureIndex;
1137  currentNet->start_x = centerX + (cos(DEG2RAD(startAngle)) * radius);
1138  currentNet->start_y = centerY + (sin(DEG2RAD(startAngle)) * radius);
1139  currentNet->stop_x = centerX + (cos(DEG2RAD(endAngle)) * radius);
1140  currentNet->stop_y = centerY + (sin(DEG2RAD(endAngle)) * radius);
1141  currentNet->cirseg = g_new0 (gerbv_cirseg_t,1);
1142  *(currentNet->cirseg) = cirSeg;
1143 
1144  gdouble angleDiff = currentNet->cirseg->angle2 - currentNet->cirseg->angle1;
1145  gint i, steps = fabs(angleDiff);
1146  for (i=0; i<=steps; i++){
1147  gdouble tempX = currentNet->cirseg->cp_x + currentNet->cirseg->width / 2.0 *
1148  cos (DEG2RAD(currentNet->cirseg->angle1 +
1149  (i*angleDiff)/steps));
1150  gdouble tempY = currentNet->cirseg->cp_y + currentNet->cirseg->width / 2.0 *
1151  sin (DEG2RAD(currentNet->cirseg->angle1 +
1152  (i*angleDiff)/steps));
1153  gerber_update_min_and_max (&currentNet->boundingBox,
1154  tempX, tempY,
1155  lineWidth/2,lineWidth/2,
1156  lineWidth/2,lineWidth/2);
1157  }
1158  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1159  return;
1160 }
1161 
1162 void
1163 gerbv_image_create_line_object (gerbv_image_t *image, gdouble startX, gdouble startY,
1164  gdouble endX, gdouble endY, gdouble lineWidth, gerbv_aperture_type_t apertureType) {
1165  int apertureIndex;
1166  gerbv_net_t *currentNet;
1167 
1168  currentNet = gerb_image_return_aperture_index(image, lineWidth, &apertureIndex);
1169 
1170  if (!currentNet)
1171  return;
1172 
1173  /* draw the line */
1174  currentNet = gerber_create_new_net (currentNet, NULL, NULL);
1176 
1177  /* if the start and end coordinates are the same, use a "flash" aperture state */
1178  if ((fabs(startX - endX) < 0.001) && (fabs(startY - endY) < 0.001))
1180  else
1182  currentNet->aperture = apertureIndex;
1183  currentNet->start_x = startX;
1184  currentNet->start_y = startY;
1185  currentNet->stop_x = endX;
1186  currentNet->stop_y = endY;
1187 
1188  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->stop_x,currentNet->stop_y,
1189  lineWidth/2,lineWidth/2,lineWidth/2,lineWidth/2);
1190  gerber_update_min_and_max (&currentNet->boundingBox,currentNet->start_x,currentNet->start_y,
1191  lineWidth/2,lineWidth/2,lineWidth/2,lineWidth/2);
1192  gerber_update_image_min_max (&currentNet->boundingBox, 0, 0, image);
1193  return;
1194 }
1195 
1196 void
1197 gerbv_image_create_window_pane_objects (gerbv_image_t *image, gdouble lowerLeftX,
1198  gdouble lowerLeftY, gdouble width, gdouble height, gdouble areaReduction,
1199  gint paneRows, gint paneColumns, gdouble paneSeparation){
1200  int i,j;
1201  gdouble startX,startY,boxWidth,boxHeight;
1202 
1203  startX = lowerLeftX + (areaReduction * width) / 2.0;
1204  startY = lowerLeftY + (areaReduction * height) / 2.0;
1205  boxWidth = (width * (1.0 - areaReduction) - (paneSeparation * (paneColumns - 1))) / paneColumns;
1206  boxHeight = (height * (1.0 - areaReduction) - (paneSeparation * (paneRows - 1))) / paneRows;
1207 
1208  for (i=0; i<paneColumns; i++){
1209  for (j=0; j<paneRows; j++) {
1210  gerbv_image_create_rectangle_object (image, startX + (i * (boxWidth + paneSeparation)),
1211  startY + (j * (boxHeight + paneSeparation)),boxWidth, boxHeight);
1212  }
1213  }
1214 
1215  return;
1216 }
1217 
1218 gboolean
1219 gerbv_image_reduce_area_of_selected_objects (GArray *selectionArray,
1220  gdouble areaReduction, gint paneRows, gint paneColumns, gdouble paneSeparation){
1221  gdouble minX,minY,maxX,maxY;
1222 
1223  for (guint i=0; i<selectionArray->len; i++) {
1224  gerbv_selection_item_t sItem = g_array_index (selectionArray,gerbv_selection_item_t, i);
1225  gerbv_image_t *image = sItem.image;
1226  gerbv_net_t *currentNet = sItem.net;
1227 
1228  /* determine the object type first */
1229  minX = HUGE_VAL;
1230  maxX = -HUGE_VAL;
1231  minY = HUGE_VAL;
1232  maxY = -HUGE_VAL;
1233 
1234  switch (currentNet->interpolation) {
1236  /* if it's a polygon, just determine the overall area of it and delete it */
1238 
1239  for (currentNet = currentNet->next; currentNet; currentNet = currentNet->next){
1240  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_END)
1241  break;
1243  if (currentNet->stop_x < minX)
1244  minX = currentNet->stop_x;
1245  if (currentNet->stop_y < minY)
1246  minY = currentNet->stop_y;
1247  if (currentNet->stop_x > maxX)
1248  maxX = currentNet->stop_x;
1249  if (currentNet->stop_y > maxY)
1250  maxY = currentNet->stop_y;
1251  }
1253 
1254  break;
1255 
1260  gdouble dx=0,dy=0;
1261  gerbv_aperture_t *apert =
1262  image->aperture[currentNet->aperture];
1263 
1264  /* figure out the overall size of this element */
1265  switch (apert->type) {
1266  case GERBV_APTYPE_CIRCLE :
1267  case GERBV_APTYPE_OVAL :
1268  case GERBV_APTYPE_POLYGON :
1269  dx = dy = apert->parameter[0];
1270  break;
1271  case GERBV_APTYPE_RECTANGLE :
1272  dx = apert->parameter[0]/2;
1273  dy = apert->parameter[1]/2;
1274  break;
1275  default :
1276  break;
1277  }
1278  if (currentNet->start_x-dx < minX)
1279  minX = currentNet->start_x-dx;
1280  if (currentNet->start_y-dy < minY)
1281  minY = currentNet->start_y-dy;
1282  if (currentNet->start_x+dx > maxX)
1283  maxX = currentNet->start_x+dx;
1284  if (currentNet->start_y+dy > maxY)
1285  maxY = currentNet->start_y+dy;
1286 
1287  if (currentNet->stop_x-dx < minX)
1288  minX = currentNet->stop_x-dx;
1289  if (currentNet->stop_y-dy < minY)
1290  minY = currentNet->stop_y-dy;
1291  if (currentNet->stop_x+dx > maxX)
1292  maxX = currentNet->stop_x+dx;
1293  if (currentNet->stop_y+dy > maxY)
1294  maxY = currentNet->stop_y+dy;
1295 
1296  /* finally, delete node */
1298 
1299  break;
1300  }
1301 
1302  default:
1303  /* we don't current support arcs */
1304  return FALSE;
1305  }
1306 
1307  /* create new structures */
1308  gerbv_image_create_window_pane_objects (image, minX, minY, maxX - minX, maxY - minY,
1309  areaReduction, paneRows, paneColumns, paneSeparation);
1310  }
1311  return TRUE;
1312 }
1313 
1314 gboolean
1315 gerbv_image_move_selected_objects (GArray *selectionArray, gdouble translationX,
1316  gdouble translationY)
1317 {
1318  for (guint i=0; i<selectionArray->len; i++) {
1319  gerbv_selection_item_t sItem = g_array_index (selectionArray,gerbv_selection_item_t, i);
1320  gerbv_net_t *currentNet = sItem.net;
1321 
1322  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_START) {
1323  /* if it's a polygon, step through every vertex and translate the point */
1324  for (currentNet = currentNet->next; currentNet; currentNet = currentNet->next){
1325  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_END)
1326  break;
1327  currentNet->start_x += translationX;
1328  currentNet->start_y += translationY;
1329  currentNet->stop_x += translationX;
1330  currentNet->stop_y += translationY;
1331  }
1332  }
1333  else {
1334  /* otherwise, just move the single element */
1335  currentNet->start_x += translationX;
1336  currentNet->start_y += translationY;
1337  currentNet->stop_x += translationX;
1338  currentNet->stop_y += translationY;
1339  }
1340  }
1341  return TRUE;
1342 }
1343 
1344 gerbv_net_t *
1346  gerbv_net_t *currentNet=oldNet;
1347 
1348  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_START) {
1349  /* if it's a polygon, step to the next non-polygon net */
1350  for (currentNet = currentNet->next; currentNet; currentNet = currentNet->next){
1351  if (currentNet->interpolation == GERBV_INTERPOLATION_PAREA_END) {
1352  return currentNet->next;
1353  }
1354  }
1355  return NULL;
1356  }
1357  else {
1358  return currentNet->next;
1359  }
1360 }
1361 
1362 void
1364  gerbv_net_t *currentNet;
1365 
1366  /* run through and find last net pointer */
1367  for (currentNet = parsed_image->netlist; currentNet->next; currentNet = currentNet->next){
1368  if (parsed_image->aperture[currentNet->aperture] == NULL) {
1369  parsed_image->aperture[currentNet->aperture] = g_new0 (gerbv_aperture_t, 1);
1370  parsed_image->aperture[currentNet->aperture]->type = GERBV_APTYPE_CIRCLE;
1371  parsed_image->aperture[currentNet->aperture]->parameter[0] = 0;
1372  parsed_image->aperture[currentNet->aperture]->parameter[1] = 0;
1373  }
1374  }
1375 }
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:1021
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:947
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:1163
void gerbv_image_delete_net(gerbv_net_t *currentNet)
Delete a net in an existing image.
Definition: gerb_image.c:991
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:1345
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:909
void gerbv_image_create_dummy_apertures(gerbv_image_t *parsed_image)
Create any missing apertures in the specified image.
Definition: gerb_image.c:1363
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:1120
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