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