4 * PCB, interactive printed circuit board design
6 * NELMA (Numerical capacitance calculator) export HID
7 * Copyright (C) 2006 Tomaz Solc (tomaz.solc@tablix.org)
9 * PNG export code is based on the PNG export HID
10 * Copyright (C) 2006 Dan McMahill
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This HID exports a PCB layout into: o One layer mask file (PNG format) per
30 * copper layer. o Nelma configuration file that contains netlist and pin
37 * If you have a section of a net that does not contain any pins then that
38 * section will be missing from the Nelma's copper geometry.
42 * this section will be ignored by Nelma | |
44 * || ||=======|| || component layer ||
45 * || || || ||=============|| ||============||
50 * Single layer layouts are always exported correctly.
67 #include "error.h" /* Message() */
73 #include "../hidint.h"
74 #include "hid/common/hidnogui.h"
75 #include "hid/common/draw_helpers.h"
79 #include "hid/common/hidinit.h"
81 #ifdef HAVE_LIBDMALLOC
85 #define CRASH fprintf(stderr, "HID error: pcb called unimplemented PNG function %s.\n", __FUNCTION__); abort()
87 /* Needed for PNG export */
90 /* the descriptor used by the gd library */
93 /* so I can figure out what rgb value c refers to */
97 struct hid_gc_struct
{
101 unsigned char r
, g
, b
;
103 struct color_struct
*color
;
107 static HID nelma_hid
;
109 static struct color_struct
*black
= NULL
, *white
= NULL
;
110 static Coord linewidth
= -1;
111 static gdImagePtr lastbrush
= (gdImagePtr
)((void *) -1);
113 /* gd image and file for PNG export */
114 static gdImagePtr nelma_im
= NULL
;
115 static FILE *nelma_f
= NULL
;
121 * Which groups of layers to export into PNG layer masks. 1 means export, 0
122 * means do not export.
124 static int nelma_export_group
[MAX_LAYER
];
126 /* Group that is currently exported. */
127 static int nelma_cur_group
;
129 /* Filename prefix that will be used when saving files. */
130 static const char *nelma_basename
= NULL
;
132 /* Horizontal DPI (grid points per inch) */
133 static int nelma_dpi
= -1;
135 /* Height of the copper layers in micrometers. */
138 * The height of the copper layer is currently taken as the vertical grid
139 * step, since this is the smallest vertical feature in the layout.
141 static int nelma_copperh
= -1;
142 /* Height of the substrate layers in micrometers. */
143 static int nelma_substrateh
= -1;
144 /* Relative permittivity of the substrate. */
145 static double nelma_substratee
= -1;
147 /* Permittivity of empty space (As/Vm) */
148 static const double nelma_air_epsilon
= 8.85e-12;
150 HID_Attribute nelma_attribute_list
[] = {
151 /* other HIDs expect this to be first. */
153 /* %start-doc options "nelma Options"
155 @item -- basename <string>
160 {"basename", "File name prefix",
161 HID_String
, 0, 0, {0, 0, 0}, 0, 0},
162 #define HA_basename 0
164 /* %start-doc options "nelma Options"
167 Horizontal scale factor (grid points/inch).
171 {"dpi", "Horizontal scale factor (grid points/inch)",
172 HID_Integer
, 0, 1000, {100, 0, 0}, 0, 0},
175 /* %start-doc options "nelma Options"
177 @item --copper-height <num>
178 Copper layer height (um).
182 {"copper-height", "Copper layer height (um)",
183 HID_Integer
, 0, 200, {100, 0, 0}, 0, 0},
186 /* %start-doc options "nelma Options"
188 @item --substrate-height <num>
189 Substrate layer height (um).
193 {"substrate-height", "Substrate layer height (um)",
194 HID_Integer
, 0, 10000, {2000, 0, 0}, 0, 0},
195 #define HA_substrateh 3
197 /* %start-doc options "nelma Options"
199 @item --substrate-epsilon <num>
200 Substrate relative epsilon.
204 {"substrate-epsilon", "Substrate relative epsilon",
205 HID_Real
, 0, 100, {0, 0, 4.0}, 0, 0},
206 #define HA_substratee 4
209 #define NUM_OPTIONS (sizeof(nelma_attribute_list)/sizeof(nelma_attribute_list[0]))
211 REGISTER_ATTRIBUTES(nelma_attribute_list
)
212 static HID_Attr_Val nelma_values
[NUM_OPTIONS
];
214 /* *** Utility funcions **************************************************** */
216 /* convert from default PCB units to nelma units */
217 static int pcb_to_nelma (Coord pcb
)
219 return COORD_TO_INCH(pcb
) * nelma_dpi
;
223 nelma_get_png_name(const char *basename
, const char *suffix
)
228 len
= strlen(basename
) + strlen(suffix
) + 6;
229 buf
= (char *)malloc(sizeof(*buf
) * len
);
231 sprintf(buf
, "%s.%s.png", basename
, suffix
);
236 /* Retrieves coordinates (in default PCB units) of a pin or pad. */
237 /* Copied from netlist.c */
239 pin_name_to_xy (LibraryEntryType
* pin
, Coord
*x
, Coord
*y
)
242 if (!SeekPad(pin
, &conn
, false))
246 *x
= ((PinType
*) (conn
.ptr2
))->X
;
247 *y
= ((PinType
*) (conn
.ptr2
))->Y
;
250 *x
= ((PadType
*) (conn
.ptr2
))->Point1
.X
;
251 *y
= ((PadType
*) (conn
.ptr2
))->Point1
.Y
;
257 /* *** Exporting netlist data and geometry to the nelma config file ******** */
260 nelma_write_space(FILE * out
)
268 xh
= 2.54e-2 / ((double) nelma_dpi
);
269 zh
= nelma_copperh
* 1e-6;
271 fprintf(out
, "\n/* **** Space **** */\n\n");
273 fprintf(out
, "space pcb {\n");
274 fprintf(out
, "\tstep = { %e, %e, %e }\n", xh
, xh
, zh
);
275 fprintf(out
, "\tlayers = {\n");
277 fprintf(out
, "\t\t\"air-top\",\n");
278 fprintf(out
, "\t\t\"air-bottom\"");
281 for (i
= 0; i
< MAX_LAYER
; i
++)
282 if (nelma_export_group
[i
]) {
283 idx
= (i
>= 0 && i
< max_group
) ?
284 PCB
->LayerGroups
.Entries
[i
][0] : i
;
285 ext
= layer_type_to_file_name(idx
, FNS_fixed
);
289 fprintf(out
, "\t\t\"substrate-%d\"", z
);
293 fprintf(out
, "\t\t\"%s\"", ext
);
296 fprintf(out
, "\n\t}\n");
302 nelma_write_material(FILE * out
, char *name
, char *type
, double e
)
304 fprintf(out
, "material %s {\n", name
);
305 fprintf(out
, "\ttype = \"%s\"\n", type
);
306 fprintf(out
, "\tpermittivity = %e\n", e
);
307 fprintf(out
, "\tconductivity = 0.0\n");
308 fprintf(out
, "\tpermeability = 0.0\n");
313 nelma_write_materials(FILE * out
)
315 fprintf(out
, "\n/* **** Materials **** */\n\n");
317 nelma_write_material(out
, "copper", "metal", nelma_air_epsilon
);
318 nelma_write_material(out
, "air", "dielectric", nelma_air_epsilon
);
319 nelma_write_material(out
, "composite", "dielectric",
320 nelma_air_epsilon
* nelma_substratee
);
324 nelma_write_nets(FILE * out
)
327 LibraryMenuType
*net
;
328 LibraryEntryType
*pin
;
334 netlist
= PCB
->NetlistLib
;
336 fprintf(out
, "\n/* **** Nets **** */\n\n");
338 for (n
= 0; n
< netlist
.MenuN
; n
++) {
339 net
= &netlist
.Menu
[n
];
341 /* Weird, but correct */
342 fprintf(out
, "net %s {\n", &net
->Name
[2]);
344 fprintf(out
, "\tobjects = {\n");
346 for (m
= 0; m
< net
->EntryN
; m
++) {
347 pin
= &net
->Entry
[m
];
349 /* pin_name_to_xy(pin, &x, &y); */
351 for (i
= 0; i
< MAX_LAYER
; i
++)
352 if (nelma_export_group
[i
]) {
353 idx
= (i
>= 0 && i
< max_group
) ?
354 PCB
->LayerGroups
.Entries
[i
][0] : i
;
355 ext
= layer_type_to_file_name(idx
, FNS_fixed
);
357 if (m
!= 0 || i
!= 0)
359 fprintf(out
, "\t\t\"%s-%s\"", pin
->ListEntry
,
365 fprintf(out
, "\t}\n");
371 nelma_write_layer(FILE * out
, int z
, int h
,
372 const char *name
, int full
,
376 LibraryMenuType
*net
;
377 LibraryEntryType
*pin
;
381 fprintf(out
, "layer %s {\n", name
);
382 fprintf(out
, "\theight = %d\n", h
);
383 fprintf(out
, "\tz-order = %d\n", z
);
384 fprintf(out
, "\tmaterial = \"%s\"\n", mat
);
387 fprintf(out
, "\tobjects = {\n");
388 netlist
= PCB
->NetlistLib
;
390 for (n
= 0; n
< netlist
.MenuN
; n
++) {
391 net
= &netlist
.Menu
[n
];
393 for (m
= 0; m
< net
->EntryN
; m
++) {
394 pin
= &net
->Entry
[m
];
396 if (m
!= 0 || n
!= 0)
398 fprintf(out
, "\t\t\"%s-%s\"", pin
->ListEntry
,
403 fprintf(out
, "\n\t}\n");
409 nelma_write_layers(FILE * out
)
419 subh
= nelma_substrateh
/ nelma_copperh
;
421 fprintf(out
, "\n/* **** Layers **** */\n\n");
423 /* Air layers on top and bottom of the stack */
424 /* Their height is double substrate height. */
425 nelma_write_layer(out
, 1, 2 * subh
, "air-top", 0, "air");
426 nelma_write_layer(out
, 1000, 2 * subh
, "air-bottom", 0, "air");
429 for (i
= 0; i
< MAX_LAYER
; i
++)
430 if (nelma_export_group
[i
]) {
431 idx
= (i
>= 0 && i
< max_group
) ?
432 PCB
->LayerGroups
.Entries
[i
][0] : i
;
433 ext
= layer_type_to_file_name(idx
, FNS_fixed
);
436 sprintf(buf
, "substrate-%d", z
);
437 nelma_write_layer(out
,
446 * FIXME: for layers that are not on top or bottom,
447 * the material should be "composite"
449 nelma_write_layer(out
, z
, 1, ext
, 1, "air");
456 nelma_write_object(FILE * out
, LibraryEntryType
*pin
)
459 Coord px
= 0, py
= 0;
465 pin_name_to_xy (pin
, &px
, &py
);
467 x
= pcb_to_nelma (px
);
468 y
= pcb_to_nelma (py
);
470 for (i
= 0; i
< MAX_LAYER
; i
++)
471 if (nelma_export_group
[i
]) {
472 idx
= (i
>= 0 && i
< max_group
) ?
473 PCB
->LayerGroups
.Entries
[i
][0] : i
;
474 ext
= layer_type_to_file_name(idx
, FNS_fixed
);
476 fprintf(out
, "object %s-%s {\n", pin
->ListEntry
, ext
);
477 fprintf(out
, "\tposition = { 0, 0 }\n");
478 fprintf(out
, "\tmaterial = \"copper\"\n");
479 fprintf(out
, "\ttype = \"image\"\n");
480 fprintf(out
, "\trole = \"net\"\n");
482 f
= nelma_get_png_name(nelma_basename
, ext
);
484 fprintf(out
, "\tfile = \"%s\"\n", f
);
488 fprintf(out
, "\tfile-pos = { %d, %d }\n", x
, y
);
494 nelma_write_objects(FILE * out
)
497 LibraryMenuType
*net
;
498 LibraryEntryType
*pin
;
502 netlist
= PCB
->NetlistLib
;
504 fprintf(out
, "\n/* **** Objects **** */\n\n");
506 for (n
= 0; n
< netlist
.MenuN
; n
++) {
507 net
= &netlist
.Menu
[n
];
509 for (m
= 0; m
< net
->EntryN
; m
++) {
510 pin
= &net
->Entry
[m
];
512 nelma_write_object(out
, pin
);
517 /* *** Main export callback ************************************************ */
520 nelma_parse_arguments(int *argc
, char ***argv
)
522 hid_register_attributes(nelma_attribute_list
,
523 sizeof(nelma_attribute_list
) /
524 sizeof(nelma_attribute_list
[0]));
525 hid_parse_command_line(argc
, argv
);
528 static HID_Attribute
*
529 nelma_get_export_options(int *n
)
531 static char *last_made_filename
= 0;
534 derive_default_filename(PCB
->Filename
,
535 &nelma_attribute_list
[HA_basename
],
537 &last_made_filename
);
542 return nelma_attribute_list
;
545 /* Populates nelma_export_group array */
547 nelma_choose_groups()
552 /* Set entire array to 0 (don't export any layer groups by default */
553 memset(nelma_export_group
, 0, sizeof(nelma_export_group
));
555 for (n
= 0; n
< max_copper_layer
; n
++) {
556 layer
= &PCB
->Data
->Layer
[n
];
558 if (layer
->LineN
|| layer
->TextN
|| layer
->ArcN
||
560 /* layer isn't empty */
563 * is this check necessary? It seems that special
564 * layers have negative indexes?
567 if (SL_TYPE(n
) == 0) {
568 /* layer is a copper layer */
569 m
= GetLayerGroupNumberByNumber(n
);
571 /* the export layer */
572 nelma_export_group
[m
] = 1;
582 * Allocate white and black -- the first color allocated becomes the
586 white
= (struct color_struct
*) malloc(sizeof(*white
));
587 white
->r
= white
->g
= white
->b
= 255;
588 white
->c
= gdImageColorAllocate(nelma_im
, white
->r
, white
->g
, white
->b
);
590 black
= (struct color_struct
*) malloc(sizeof(*black
));
591 black
->r
= black
->g
= black
->b
= 0;
592 black
->c
= gdImageColorAllocate(nelma_im
, black
->r
, black
->g
, black
->b
);
596 nelma_start_png(const char *basename
, const char *suffix
)
601 buf
= nelma_get_png_name(basename
, suffix
);
603 h
= pcb_to_nelma(PCB
->MaxHeight
);
604 w
= pcb_to_nelma(PCB
->MaxWidth
);
606 /* nelma_im = gdImageCreate (w, h); */
608 /* Nelma only works with true color images */
609 nelma_im
= gdImageCreate(w
, h
);
610 nelma_f
= fopen(buf
, "wb");
612 nelma_alloc_colors();
620 #ifdef HAVE_GDIMAGEPNG
621 gdImagePng(nelma_im
, nelma_f
);
623 Message("NELMA: PNG not supported by gd. Can't write layer mask.\n");
625 gdImageDestroy(nelma_im
);
636 nelma_start_png_export()
642 region
.X2
= PCB
->MaxWidth
;
643 region
.Y2
= PCB
->MaxHeight
;
646 lastbrush
= (gdImagePtr
)((void *) -1);
648 hid_expose_callback(&nelma_hid
, ®ion
, 0);
652 nelma_do_export(HID_Attr_Val
* options
)
654 int save_ons
[MAX_LAYER
+ 2];
663 nelma_get_export_options(0);
664 for (i
= 0; i
< NUM_OPTIONS
; i
++) {
665 nelma_values
[i
] = nelma_attribute_list
[i
].default_val
;
667 options
= nelma_values
;
669 nelma_basename
= options
[HA_basename
].str_value
;
670 if (!nelma_basename
) {
671 nelma_basename
= "pcb-out";
673 nelma_dpi
= options
[HA_dpi
].int_value
;
675 fprintf(stderr
, "ERROR: dpi may not be < 0\n");
678 nelma_copperh
= options
[HA_copperh
].int_value
;
679 nelma_substrateh
= options
[HA_substrateh
].int_value
;
680 nelma_substratee
= options
[HA_substratee
].real_value
;
682 nelma_choose_groups();
684 for (i
= 0; i
< MAX_LAYER
; i
++) {
685 if (nelma_export_group
[i
]) {
690 idx
= (i
>= 0 && i
< max_group
) ?
691 PCB
->LayerGroups
.Entries
[i
][0] : i
;
693 nelma_start_png(nelma_basename
,
694 layer_type_to_file_name(idx
, FNS_fixed
));
696 hid_save_and_show_layer_ons(save_ons
);
697 nelma_start_png_export();
698 hid_restore_layer_ons(save_ons
);
704 len
= strlen(nelma_basename
) + 4;
705 buf
= (char *)malloc(sizeof(*buf
) * len
);
707 sprintf(buf
, "%s.em", nelma_basename
);
708 nelma_config
= fopen(buf
, "w");
712 fprintf(nelma_config
, "/* Made with PCB Nelma export HID */");
714 fprintf(nelma_config
, "/* %s */", ctime(&t
));
716 nelma_write_nets(nelma_config
);
717 nelma_write_objects(nelma_config
);
718 nelma_write_layers(nelma_config
);
719 nelma_write_materials(nelma_config
);
720 nelma_write_space(nelma_config
);
722 fclose(nelma_config
);
725 /* *** PNG export (slightly modified code from PNG export HID) ************* */
728 nelma_set_layer(const char *name
, int group
, int empty
)
730 int idx
= (group
>= 0 && group
< max_group
) ?
731 PCB
->LayerGroups
.Entries
[group
][0] : group
;
734 name
= PCB
->Data
->Layer
[idx
].Name
;
736 if (strcmp(name
, "invisible") == 0) {
739 is_drill
= (SL_TYPE(idx
) == SL_PDRILL
|| SL_TYPE(idx
) == SL_UDRILL
);
740 is_mask
= (SL_TYPE(idx
) == SL_MASK
);
743 /* Don't print masks */
748 * Print 'holes', so that we can fill gaps in the copper
753 if (group
== nelma_cur_group
) {
762 hidGC rv
= (hidGC
) malloc(sizeof(struct hid_gc_struct
));
763 rv
->me_pointer
= &nelma_hid
;
766 rv
->color
= (struct color_struct
*) malloc(sizeof(*rv
->color
));
767 rv
->color
->r
= rv
->color
->g
= rv
->color
->b
= 0;
773 nelma_destroy_gc(hidGC gc
)
779 nelma_use_mask(enum mask_mode mode
)
785 nelma_set_color(hidGC gc
, const char *name
)
787 if (nelma_im
== NULL
) {
793 if (!strcmp(name
, "drill")) {
798 if (!strcmp(name
, "erase")) {
799 /* FIXME -- should be background, not white */
810 nelma_set_line_cap(hidGC gc
, EndCapStyle style
)
816 nelma_set_line_width(hidGC gc
, Coord width
)
822 nelma_set_draw_xor(hidGC gc
, int xor_
)
828 nelma_set_draw_faded(hidGC gc
, int faded
)
837 if (gc
->me_pointer
!= &nelma_hid
) {
838 fprintf(stderr
, "Fatal: GC from another HID passed to nelma HID\n");
841 if (linewidth
!= gc
->width
) {
842 /* Make sure the scaling doesn't erase lines completely */
844 if (SCALE (gc->width) == 0 && gc->width > 0)
845 gdImageSetThickness (im, 1);
848 gdImageSetThickness(nelma_im
, pcb_to_nelma(gc
->width
));
849 linewidth
= gc
->width
;
852 if (lastbrush
!= gc
->brush
|| need_brush
) {
853 static void *bcache
= 0;
863 r
= pcb_to_nelma(gc
->width
/ 2);
867 r
= pcb_to_nelma(gc
->width
);
871 sprintf(name
, "#%.2x%.2x%.2x_%c_%d", gc
->color
->r
, gc
->color
->g
,
872 gc
->color
->b
, type
, r
);
874 if (hid_cache_color(0, name
, &bval
, &bcache
)) {
875 gc
->brush
= (gdImagePtr
)bval
.ptr
;
879 gc
->brush
= gdImageCreate(2 * r
+ 1, 2 * r
+ 1);
881 gc
->brush
= gdImageCreate(r
+ 1, r
+ 1);
882 bg
= gdImageColorAllocate(gc
->brush
, 255, 255, 255);
884 gdImageColorAllocate(gc
->brush
, gc
->color
->r
, gc
->color
->g
,
886 gdImageColorTransparent(gc
->brush
, bg
);
889 * if we shrunk to a radius/box width of zero, then just use
890 * a single pixel to draw with.
893 gdImageFilledRectangle(gc
->brush
, 0, 0, 0, 0, fg
);
896 gdImageFilledEllipse(gc
->brush
, r
, r
, 2 * r
, 2 * r
, fg
);
898 gdImageFilledRectangle(gc
->brush
, 0, 0, r
, r
, fg
);
900 bval
.ptr
= gc
->brush
;
901 hid_cache_color(1, name
, &bval
, &bcache
);
904 gdImageSetBrush(nelma_im
, gc
->brush
);
905 lastbrush
= gc
->brush
;
911 nelma_draw_rect(hidGC gc
, Coord x1
, Coord y1
, Coord x2
, Coord y2
)
914 gdImageRectangle(nelma_im
,
915 pcb_to_nelma(x1
), pcb_to_nelma(y1
),
916 pcb_to_nelma(x2
), pcb_to_nelma(y2
), gc
->color
->c
);
920 nelma_fill_rect(hidGC gc
, Coord x1
, Coord y1
, Coord x2
, Coord y2
)
923 gdImageSetThickness(nelma_im
, 0);
925 gdImageFilledRectangle(nelma_im
, pcb_to_nelma(x1
), pcb_to_nelma(y1
),
926 pcb_to_nelma(x2
), pcb_to_nelma(y2
), gc
->color
->c
);
930 nelma_draw_line(hidGC gc
, Coord x1
, Coord y1
, Coord x2
, Coord y2
)
932 if (x1
== x2
&& y1
== y2
) {
933 Coord w
= gc
->width
/ 2;
934 nelma_fill_rect(gc
, x1
- w
, y1
- w
, x1
+ w
, y1
+ w
);
939 gdImageSetThickness(nelma_im
, 0);
941 gdImageLine(nelma_im
, pcb_to_nelma(x1
), pcb_to_nelma(y1
),
942 pcb_to_nelma(x2
), pcb_to_nelma(y2
), gdBrushed
);
946 nelma_draw_arc(hidGC gc
, Coord cx
, Coord cy
, Coord width
, Coord height
,
947 Angle start_angle
, Angle delta_angle
)
952 * in gdImageArc, 0 degrees is to the right and +90 degrees is down
953 * in pcb, 0 degrees is to the left and +90 degrees is down
955 start_angle
= 180 - start_angle
;
956 delta_angle
= -delta_angle
;
957 if (delta_angle
> 0) {
959 ea
= start_angle
+ delta_angle
;
961 sa
= start_angle
+ delta_angle
;
966 * make sure we start between 0 and 360 otherwise gd does strange
969 sa
= NormalizeAngle (sa
);
970 ea
= NormalizeAngle (ea
);
973 printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n",
974 cx
, cy
, width
, height
, start_angle
, delta_angle
, sa
, ea
);
975 printf("gdImageArc (%p, %d, %d, %d, %d, %d, %d, %d)\n",
976 im
, SCALE_X(cx
), SCALE_Y(cy
),
977 SCALE(width
), SCALE(height
), sa
, ea
, gc
->color
->c
);
980 gdImageSetThickness(nelma_im
, 0);
982 gdImageArc(nelma_im
, pcb_to_nelma(cx
), pcb_to_nelma(cy
),
983 pcb_to_nelma(2 * width
), pcb_to_nelma(2 * height
), sa
, ea
, gdBrushed
);
987 nelma_fill_circle(hidGC gc
, Coord cx
, Coord cy
, Coord radius
)
991 gdImageSetThickness(nelma_im
, 0);
993 gdImageFilledEllipse(nelma_im
, pcb_to_nelma(cx
), pcb_to_nelma(cy
),
994 pcb_to_nelma(2 * radius
), pcb_to_nelma(2 * radius
), gc
->color
->c
);
999 nelma_fill_polygon(hidGC gc
, int n_coords
, Coord
*x
, Coord
*y
)
1004 points
= (gdPoint
*) malloc(n_coords
* sizeof(gdPoint
));
1005 if (points
== NULL
) {
1006 fprintf(stderr
, "ERROR: nelma_fill_polygon(): malloc failed\n");
1010 for (i
= 0; i
< n_coords
; i
++) {
1011 points
[i
].x
= pcb_to_nelma(x
[i
]);
1012 points
[i
].y
= pcb_to_nelma(y
[i
]);
1014 gdImageSetThickness(nelma_im
, 0);
1016 gdImageFilledPolygon(nelma_im
, points
, n_coords
, gc
->color
->c
);
1021 nelma_calibrate(double xval
, double yval
)
1027 nelma_set_crosshair(int x
, int y
, int a
)
1031 /* *** Miscellaneous ******************************************************* */
1033 #include "dolists.h"
1038 memset (&nelma_hid
, 0, sizeof (HID
));
1040 common_nogui_init (&nelma_hid
);
1041 common_draw_helpers_init (&nelma_hid
);
1043 nelma_hid
.struct_size
= sizeof (HID
);
1044 nelma_hid
.name
= "nelma";
1045 nelma_hid
.description
= "Numerical analysis package export";
1046 nelma_hid
.exporter
= 1;
1047 nelma_hid
.poly_before
= 1;
1049 nelma_hid
.get_export_options
= nelma_get_export_options
;
1050 nelma_hid
.do_export
= nelma_do_export
;
1051 nelma_hid
.parse_arguments
= nelma_parse_arguments
;
1052 nelma_hid
.set_layer
= nelma_set_layer
;
1053 nelma_hid
.make_gc
= nelma_make_gc
;
1054 nelma_hid
.destroy_gc
= nelma_destroy_gc
;
1055 nelma_hid
.use_mask
= nelma_use_mask
;
1056 nelma_hid
.set_color
= nelma_set_color
;
1057 nelma_hid
.set_line_cap
= nelma_set_line_cap
;
1058 nelma_hid
.set_line_width
= nelma_set_line_width
;
1059 nelma_hid
.set_draw_xor
= nelma_set_draw_xor
;
1060 nelma_hid
.set_draw_faded
= nelma_set_draw_faded
;
1061 nelma_hid
.draw_line
= nelma_draw_line
;
1062 nelma_hid
.draw_arc
= nelma_draw_arc
;
1063 nelma_hid
.draw_rect
= nelma_draw_rect
;
1064 nelma_hid
.fill_circle
= nelma_fill_circle
;
1065 nelma_hid
.fill_polygon
= nelma_fill_polygon
;
1066 nelma_hid
.fill_rect
= nelma_fill_rect
;
1067 nelma_hid
.calibrate
= nelma_calibrate
;
1068 nelma_hid
.set_crosshair
= nelma_set_crosshair
;
1070 hid_register_hid (&nelma_hid
);
1072 #include "nelma_lists.h"