Index: trunk/src/Makefile.dep =================================================================== --- trunk/src/Makefile.dep (revision 4581) +++ trunk/src/Makefile.dep (revision 4582) @@ -2384,7 +2384,7 @@ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/hash.h \ crosshair.h rubberband.h hid.h error.h drc.h buffer.h error.h plug_io.h \ mymem.h misc.h mymem.h rats.h netlist.h route_style.h set.h plugins.h \ - hid_actions.h compat_misc.h dolists.h + hid_actions.h compat_misc.h misc_util.h dolists.h ../src_plugins/smartdisperse/smartdisperse.o: \ ../src_plugins/smartdisperse/smartdisperse.c \ ../src_3rd/liblihata/genht/htpi.h ../src_3rd/liblihata/genht/ht.h \ @@ -2635,7 +2635,7 @@ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/genvector/vtp0.h list_conf.h \ - plug_io.h create.h compat_misc.h hid_actions.h paths.h + plug_io.h create.h compat_misc.h hid_actions.h paths.h rtree.h box.o: box.c ../config.h box.h math_helper.h global_typedefs.h pcb_bool.h \ unit.h global_objs.h ../src_3rd/genlist/gendlist.h attrib.h flag.h \ globalconst.h polyarea.h macro.h move.h misc_util.h @@ -2858,7 +2858,7 @@ data.h global_element.h list_element.h ht_element.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ ../src_3rd/liblihata/genht/hash.h crosshair.h rubberband.h hid.h error.h \ - drc.h buffer.h mymem.h rtree.h list_common.h obj_all.h + drc.h buffer.h mymem.h rtree.h list_common.h obj_all.h math_helper.h draw.o: draw.c ../config.h conf_core.h conf.h global_typedefs.h \ pcb_bool.h unit.h pcb-printf.h ../src_3rd/genvector/gds_char.h \ ../src_3rd/genvector/genvector_impl.h \ Index: trunk/src/board.c =================================================================== --- trunk/src/board.c (revision 4581) +++ trunk/src/board.c (revision 4582) @@ -32,6 +32,7 @@ #include "compat_misc.h" #include "hid_actions.h" #include "paths.h" +#include "rtree.h" PCBType *PCB; @@ -187,3 +188,37 @@ ptr->Data->Layer[solder_silk_layer].SelectedColor = conf_core.appearance.color.element_selected; } +typedef struct { + int nplated; + int nunplated; +} HoleCountStruct; + +static r_dir_t hole_counting_callback(const BoxType * b, void *cl) +{ + PinTypePtr pin = (PinTypePtr) b; + HoleCountStruct *hcs = (HoleCountStruct *) cl; + if (TEST_FLAG(PCB_FLAG_HOLE, pin)) + hcs->nunplated++; + else + hcs->nplated++; + return R_DIR_FOUND_CONTINUE; +} + + +/* --------------------------------------------------------------------------- + * counts the number of plated and unplated holes in the design within + * a given area of the board. To count for the whole board, pass NULL + * within_area. + */ +void CountHoles(int *plated, int *unplated, const BoxType * within_area) +{ + HoleCountStruct hcs = { 0, 0 }; + + r_search(PCB->Data->pin_tree, within_area, NULL, hole_counting_callback, &hcs, NULL); + r_search(PCB->Data->via_tree, within_area, NULL, hole_counting_callback, &hcs, NULL); + + if (plated != NULL) + *plated = hcs.nplated; + if (unplated != NULL) + *unplated = hcs.nunplated; +} Index: trunk/src/board.h =================================================================== --- trunk/src/board.h (revision 4581) +++ trunk/src/board.h (revision 4582) @@ -124,6 +124,8 @@ void pcb_colors_from_settings(PCBTypePtr); +void CountHoles(int *plated, int *unplated, const BoxType * within_area); + #define SWAP_X(x) (SWAP_SIGN_X(x)) #define SWAP_Y(y) (PCB->MaxHeight +SWAP_SIGN_Y(y)) Index: trunk/src/data.c =================================================================== --- trunk/src/data.c (revision 4581) +++ trunk/src/data.c (revision 4582) @@ -34,6 +34,7 @@ #include "rtree.h" #include "list_common.h" #include "obj_all.h" +#include "math_helper.h" /* --------------------------------------------------------------------------- * some shared identifiers @@ -267,3 +268,80 @@ hasNoObjects = hasNoObjects && LAYER_IS_EMPTY(&(Data->Layer[i])); return (hasNoObjects); } + +/* --------------------------------------------------------------------------- + * gets minimum and maximum coordinates + * returns NULL if layout is empty + */ +BoxTypePtr GetDataBoundingBox(DataTypePtr Data) +{ + static BoxType box; + /* FIX ME: use r_search to do this much faster */ + + /* preset identifiers with highest and lowest possible values */ + box.X1 = box.Y1 = MAX_COORD; + box.X2 = box.Y2 = -MAX_COORD; + + /* now scan for the lowest/highest X and Y coordinate */ + VIA_LOOP(Data); + { + box.X1 = MIN(box.X1, via->X - via->Thickness / 2); + box.Y1 = MIN(box.Y1, via->Y - via->Thickness / 2); + box.X2 = MAX(box.X2, via->X + via->Thickness / 2); + box.Y2 = MAX(box.Y2, via->Y + via->Thickness / 2); + } + END_LOOP; + ELEMENT_LOOP(Data); + { + box.X1 = MIN(box.X1, element->BoundingBox.X1); + box.Y1 = MIN(box.Y1, element->BoundingBox.Y1); + box.X2 = MAX(box.X2, element->BoundingBox.X2); + box.Y2 = MAX(box.Y2, element->BoundingBox.Y2); + { + TextTypePtr text = &NAMEONPCB_TEXT(element); + box.X1 = MIN(box.X1, text->BoundingBox.X1); + box.Y1 = MIN(box.Y1, text->BoundingBox.Y1); + box.X2 = MAX(box.X2, text->BoundingBox.X2); + box.Y2 = MAX(box.Y2, text->BoundingBox.Y2); + }; + } + END_LOOP; + ALLLINE_LOOP(Data); + { + box.X1 = MIN(box.X1, line->Point1.X - line->Thickness / 2); + box.Y1 = MIN(box.Y1, line->Point1.Y - line->Thickness / 2); + box.X1 = MIN(box.X1, line->Point2.X - line->Thickness / 2); + box.Y1 = MIN(box.Y1, line->Point2.Y - line->Thickness / 2); + box.X2 = MAX(box.X2, line->Point1.X + line->Thickness / 2); + box.Y2 = MAX(box.Y2, line->Point1.Y + line->Thickness / 2); + box.X2 = MAX(box.X2, line->Point2.X + line->Thickness / 2); + box.Y2 = MAX(box.Y2, line->Point2.Y + line->Thickness / 2); + } + ENDALL_LOOP; + ALLARC_LOOP(Data); + { + box.X1 = MIN(box.X1, arc->BoundingBox.X1); + box.Y1 = MIN(box.Y1, arc->BoundingBox.Y1); + box.X2 = MAX(box.X2, arc->BoundingBox.X2); + box.Y2 = MAX(box.Y2, arc->BoundingBox.Y2); + } + ENDALL_LOOP; + ALLTEXT_LOOP(Data); + { + box.X1 = MIN(box.X1, text->BoundingBox.X1); + box.Y1 = MIN(box.Y1, text->BoundingBox.Y1); + box.X2 = MAX(box.X2, text->BoundingBox.X2); + box.Y2 = MAX(box.Y2, text->BoundingBox.Y2); + } + ENDALL_LOOP; + ALLPOLYGON_LOOP(Data); + { + box.X1 = MIN(box.X1, polygon->BoundingBox.X1); + box.Y1 = MIN(box.Y1, polygon->BoundingBox.Y1); + box.X2 = MAX(box.X2, polygon->BoundingBox.X2); + box.Y2 = MAX(box.Y2, polygon->BoundingBox.Y2); + } + ENDALL_LOOP; + return (IsDataEmpty(Data) ? NULL : &box); +} + Index: trunk/src/data.h =================================================================== --- trunk/src/data.h (revision 4581) +++ trunk/src/data.h (revision 4582) @@ -126,5 +126,6 @@ void FreeDataMemory(DataTypePtr); pcb_bool IsDataEmpty(DataTypePtr); +BoxTypePtr GetDataBoundingBox(DataTypePtr Data); #endif Index: trunk/src/misc.c =================================================================== --- trunk/src/misc.c (revision 4581) +++ trunk/src/misc.c (revision 4582) @@ -216,118 +216,7 @@ r_insert_entry(Data->element_tree, box, 0); } -typedef struct { - int nplated; - int nunplated; -} HoleCountStruct; - -static r_dir_t hole_counting_callback(const BoxType * b, void *cl) -{ - PinTypePtr pin = (PinTypePtr) b; - HoleCountStruct *hcs = (HoleCountStruct *) cl; - if (TEST_FLAG(PCB_FLAG_HOLE, pin)) - hcs->nunplated++; - else - hcs->nplated++; - return R_DIR_FOUND_CONTINUE; -} - /* --------------------------------------------------------------------------- - * counts the number of plated and unplated holes in the design within - * a given area of the board. To count for the whole board, pass NULL - * within_area. - */ -void CountHoles(int *plated, int *unplated, const BoxType * within_area) -{ - HoleCountStruct hcs = { 0, 0 }; - - r_search(PCB->Data->pin_tree, within_area, NULL, hole_counting_callback, &hcs, NULL); - r_search(PCB->Data->via_tree, within_area, NULL, hole_counting_callback, &hcs, NULL); - - if (plated != NULL) - *plated = hcs.nplated; - if (unplated != NULL) - *unplated = hcs.nunplated; -} - - -/* --------------------------------------------------------------------------- - * gets minimum and maximum coordinates - * returns NULL if layout is empty - */ -BoxTypePtr GetDataBoundingBox(DataTypePtr Data) -{ - static BoxType box; - /* FIX ME: use r_search to do this much faster */ - - /* preset identifiers with highest and lowest possible values */ - box.X1 = box.Y1 = MAX_COORD; - box.X2 = box.Y2 = -MAX_COORD; - - /* now scan for the lowest/highest X and Y coordinate */ - VIA_LOOP(Data); - { - box.X1 = MIN(box.X1, via->X - via->Thickness / 2); - box.Y1 = MIN(box.Y1, via->Y - via->Thickness / 2); - box.X2 = MAX(box.X2, via->X + via->Thickness / 2); - box.Y2 = MAX(box.Y2, via->Y + via->Thickness / 2); - } - END_LOOP; - ELEMENT_LOOP(Data); - { - box.X1 = MIN(box.X1, element->BoundingBox.X1); - box.Y1 = MIN(box.Y1, element->BoundingBox.Y1); - box.X2 = MAX(box.X2, element->BoundingBox.X2); - box.Y2 = MAX(box.Y2, element->BoundingBox.Y2); - { - TextTypePtr text = &NAMEONPCB_TEXT(element); - box.X1 = MIN(box.X1, text->BoundingBox.X1); - box.Y1 = MIN(box.Y1, text->BoundingBox.Y1); - box.X2 = MAX(box.X2, text->BoundingBox.X2); - box.Y2 = MAX(box.Y2, text->BoundingBox.Y2); - }; - } - END_LOOP; - ALLLINE_LOOP(Data); - { - box.X1 = MIN(box.X1, line->Point1.X - line->Thickness / 2); - box.Y1 = MIN(box.Y1, line->Point1.Y - line->Thickness / 2); - box.X1 = MIN(box.X1, line->Point2.X - line->Thickness / 2); - box.Y1 = MIN(box.Y1, line->Point2.Y - line->Thickness / 2); - box.X2 = MAX(box.X2, line->Point1.X + line->Thickness / 2); - box.Y2 = MAX(box.Y2, line->Point1.Y + line->Thickness / 2); - box.X2 = MAX(box.X2, line->Point2.X + line->Thickness / 2); - box.Y2 = MAX(box.Y2, line->Point2.Y + line->Thickness / 2); - } - ENDALL_LOOP; - ALLARC_LOOP(Data); - { - box.X1 = MIN(box.X1, arc->BoundingBox.X1); - box.Y1 = MIN(box.Y1, arc->BoundingBox.Y1); - box.X2 = MAX(box.X2, arc->BoundingBox.X2); - box.Y2 = MAX(box.Y2, arc->BoundingBox.Y2); - } - ENDALL_LOOP; - ALLTEXT_LOOP(Data); - { - box.X1 = MIN(box.X1, text->BoundingBox.X1); - box.Y1 = MIN(box.Y1, text->BoundingBox.Y1); - box.X2 = MAX(box.X2, text->BoundingBox.X2); - box.Y2 = MAX(box.Y2, text->BoundingBox.Y2); - } - ENDALL_LOOP; - ALLPOLYGON_LOOP(Data); - { - box.X1 = MIN(box.X1, polygon->BoundingBox.X1); - box.Y1 = MIN(box.Y1, polygon->BoundingBox.Y1); - box.X2 = MAX(box.X2, polygon->BoundingBox.X2); - box.Y2 = MAX(box.Y2, polygon->BoundingBox.Y2); - } - ENDALL_LOOP; - return (IsDataEmpty(Data) ? NULL : &box); -} - -/* --------------------------------------------------------------------------- * transforms symbol coordinates so that the left edge of each symbol * is at the zero position. The y coordinates are moved so that min(y) = 0 * Index: trunk/src/misc.h =================================================================== --- trunk/src/misc.h (revision 4581) +++ trunk/src/misc.h (revision 4582) @@ -37,8 +37,6 @@ void r_delete_element(DataTypePtr, ElementTypePtr); void SetPolygonBoundingBox(PolygonTypePtr); void SetElementBoundingBox(DataTypePtr, ElementTypePtr, FontTypePtr); -void CountHoles(int *, int *, const BoxType *); -BoxTypePtr GetDataBoundingBox(DataTypePtr); void SetFontInfo(FontTypePtr); BoxTypePtr GetObjectBoundingBox(int, void *, void *, void *); Index: trunk/src/misc_util.c =================================================================== --- trunk/src/misc_util.c (revision 4581) +++ trunk/src/misc_util.c (revision 4582) @@ -181,3 +181,35 @@ (*s)++; return ret_val; } + +/* --------------------------------------------------------------------------- + * strips leading and trailing blanks from the passed string and + * returns a pointer to the new 'duped' one or NULL if the old one + * holds only white space characters + */ +char *StripWhiteSpaceAndDup(const char *S) +{ + const char *p1, *p2; + char *copy; + size_t length; + + if (!S || !*S) + return (NULL); + + /* strip leading blanks */ + for (p1 = S; *p1 && isspace((int) *p1); p1++); + + /* strip trailing blanks and get string length */ + length = strlen(p1); + for (p2 = p1 + length - 1; length && isspace((int) *p2); p2--, length--); + + /* string is not empty -> allocate memory */ + if (length) { + copy = (char *) realloc(NULL, length + 1); + strncpy(copy, p1, length); + copy[length] = '\0'; + return (copy); + } + else + return (NULL); +} Index: trunk/src/misc_util.h =================================================================== --- trunk/src/misc_util.h (revision 4581) +++ trunk/src/misc_util.h (revision 4582) @@ -50,4 +50,6 @@ char *Concat(const char *, ...); /* end with NULL */ int mem_any_set(unsigned char *ptr, int bytes); +char *StripWhiteSpaceAndDup(const char *S); + #endif Index: trunk/src/mymem.c =================================================================== --- trunk/src/mymem.c (revision 4581) +++ trunk/src/mymem.c (revision 4582) @@ -177,38 +177,6 @@ reset_obj_mem(ElementType, element); } -/* --------------------------------------------------------------------------- - * strips leading and trailing blanks from the passed string and - * returns a pointer to the new 'duped' one or NULL if the old one - * holds only white space characters - */ -char *StripWhiteSpaceAndDup(const char *S) -{ - const char *p1, *p2; - char *copy; - size_t length; - - if (!S || !*S) - return (NULL); - - /* strip leading blanks */ - for (p1 = S; *p1 && isspace((int) *p1); p1++); - - /* strip trailing blanks and get string length */ - length = strlen(p1); - for (p2 = p1 + length - 1; length && isspace((int) *p2); p2--, length--); - - /* string is not empty -> allocate memory */ - if (length) { - copy = (char *) realloc(NULL, length + 1); - strncpy(copy, p1, length); - copy[length] = '\0'; - return (copy); - } - else - return (NULL); -} - LineType *GetElementLineMemory(ElementType *Element) { LineType *line = calloc(sizeof(LineType), 1); Index: trunk/src/mymem.h =================================================================== --- trunk/src/mymem.h (revision 4581) +++ trunk/src/mymem.h (revision 4582) @@ -58,8 +58,6 @@ void FreePolygonMemory(PolygonTypePtr); void FreeElementMemory(ElementTypePtr); -char *StripWhiteSpaceAndDup(const char *); - void RemoveFreePolygon(PolygonType * data); void RemoveFreeElement(ElementType * data); Index: trunk/src_plugins/shand_cmd/command.c =================================================================== --- trunk/src_plugins/shand_cmd/command.c (revision 4581) +++ trunk/src_plugins/shand_cmd/command.c (revision 4582) @@ -49,6 +49,7 @@ #include "plugins.h" #include "hid_actions.h" #include "compat_misc.h" +#include "misc_util.h" /* ---------------------------------------------------------------------- */