#ifndef CSCH_UTIL_WIRENET_H #define CSCH_UTIL_WIRENET_H #include /* Create a line object to be part of a wire-net. Undoable. There are three cases on which wirenet: - if either end is connected to a wirenet, or both ends connected to the same wirenet, the line is created within that wirenet group - if one end is connected to one wirenet and the other end is connected to another wirenet, the wirenet at x2;y2 is merged into the wirenet at x1;y1 and the new line is added in the remaining wirenet group - if neither endpoint lands on an existing wirenet, a new wirenet group is created. Returns the new line object. */ csch_chdr_t *csch_wirenet_draw(csch_sheet_t *sheet, csch_comm_str_t stroke_name, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2); /* Recalculate all junction marks on a wirenet, removing stale ones and adding new ines where multiple lines are crossing */ void csch_wirenet_recalc_junctions(csch_sheet_t *sheet, csch_cgrp_t *wirenet); /* Recalculate wirenets after a line has changed geometry if the line was in a wirenet. Potential outcome include: - wirenet split in two if the bridge object is (re)moved - two or more wirenets merged - input line object changes its parent (jumps wirenet) */ void csch_wirenet_recalc_line_chg(csch_sheet_t *sheet, csch_line_t *line); /* Return true if object is a wirenet junction */ RND_INLINE int csch_obj_is_junction(csch_chdr_t *obj); void csch_recalc_obj_conn(csch_sheet_t *sheet, csch_chdr_t *wobj, csch_displayer_t target, csch_displayer_t target2); /* Inhibit wirenet recalculations and recalculate everything once at the end; useful during multiple wirenet line manipulation operations bundled */ void csch_wirenet_recalc_freeze(csch_sheet_t *sheet); void csch_wirenet_recalc_unfreeze(csch_sheet_t *sheet); void csch_wirenet_recalc_obj_conn(csch_sheet_t *sheet, csch_chdr_t *wobj); /* Count number of junctions on a wire object wno. If mid_cnt_out is not NULL, load it with the number of junctions that are not falling at either endpoint of wno. */ int csch_wire_count_junctions(csch_chdr_t *wno, int *mid_cnt_out); /* Returns true if line between x1;y1 and x2;y2 is safe to draw: a random other line won't have its endpoint in the middle of the new line */ int csch_is_wireline_safe(csch_sheet_t *sheet, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2); /* Called after an object is removed from a wirenet; removes floaters if the wirenet is empty */ void csch_wirenet_post_remove_checks(csch_sheet_t *sheet, csch_cgrp_t *wn, int undoable); /* Return the wire that's at x;y; if ignore_line is not NULL, ignore that object (useful if there are multiple lines on the same spot) */ csch_line_t *csch_find_wire_at(csch_sheet_t *sheet, csch_coord_t x, csch_coord_t y, csch_chdr_t *ignore_line); /*** low level ***/ /* Create a new wire line within a wirenet without updating or recalculating the wirenet */ csch_line_t *csch_wirenet_draw_line_in(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_comm_str_t stroke_name, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2); /* merges any lines that connect with "line" from within the same wirenet and has the same direction; if remove_overlap is 0, line is never removed; if remove_overlap is 1, if line fully overlaps with an existing wire from one end of that wire, the wire is truncated (and line is removed) */ void csch_wirenet_recalc_merge(csch_sheet_t *sheet, csch_line_t *line, int remove_overlap); /*** implementation ***/ RND_INLINE int csch_obj_is_junction(csch_chdr_t *obj) { /* simplest case: zero-length line is implied to be a junction */ if (obj->type == CSCH_CTYPE_LINE) { csch_line_t *line = (csch_line_t *)obj; if ((line->spec.p1.x == line->spec.p2.x) && (line->spec.p1.y == line->spec.p2.y)) return 1; } /* non-line drawing object, or line with non-zero length: check if parent is a junction grp */ if (!csch_obj_is_grp(obj)) obj = &obj->parent->hdr; if (csch_obj_is_grp(obj)) { /* more complex junction graphics must go in a role=junction grp */ csch_cgrp_t *grp = (csch_cgrp_t *)obj; return (grp->role == CSCH_ROLE_JUNCTION); } return 0; /* anything else is wire */ } #endif