static void write_xml_wire (Wire *wire, parseXmlContext *ctxt) { xmlNodePtr node_wire; gchar *str; Coords start_pos, end_pos; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); // Create a node for the wire. node_wire = xmlNewChild (ctxt->node_wires, ctxt->ns, BAD_CAST "wire", NULL); if (!node_wire) { g_warning ("Failed during save of wire.\n"); return; } wire_get_start_pos (wire, &start_pos); wire_get_end_pos (wire, &end_pos); Node *node; Coords last, current, tmp; GSList *iter, *copy; copy = g_slist_sort (g_slist_copy (wire_get_nodes (wire)), cmp_nodes); current = last = start_pos; for (iter = copy; iter; iter = iter->next) { node = iter->data; if (node==NULL) { g_warning ("Node of wire did not exist [%p].", node); continue; } tmp = node->key; if (coords_equal(&tmp, &start_pos)) continue; if (coords_equal(&tmp, &end_pos)) continue; last = current; current = tmp; str = g_strdup_printf ("(%g %g)(%g %g)", last.x, last.y, current.x, current.y); xmlNewChild (node_wire, ctxt->ns, BAD_CAST "points", BAD_CAST str); g_free (str); } last = current; current = end_pos; str = g_strdup_printf ("(%g %g)(%g %g)", last.x, last.y, current.x, current.y); xmlNewChild (node_wire, ctxt->ns, BAD_CAST "points", BAD_CAST str); g_free (str); g_slist_free (copy); }
inline gint coords_compare (const Coords *a, const Coords *b) { if (coords_equal (a, b)) return 0; if ((a->x > b->x) || (fabs (a->x - b->x) < (COORDS_DELTA * COORDS_DELTA) && (a->y > b->y))) return -1; return +1; }
/** * add/register the wire to the nodestore * * @param store * @param wire * @returns TRUE if the wire was added or merged, else FALSE */ gboolean node_store_add_wire (NodeStore *store, Wire *wire) { GList *list; Node *node; int i = 0; g_return_val_if_fail (store, FALSE); g_return_val_if_fail (IS_NODE_STORE (store), FALSE); g_return_val_if_fail (wire, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); // Check for intersection with other wires. for (list = store->wires; list; list = list->next) { g_assert (list->data != NULL); g_assert (IS_WIRE (list->data)); Coords where = {-77.77, -77.77}; Wire *other = list->data; if (do_wires_intersect (wire, other, &where)) { if (is_t_crossing (wire, other, &where) || is_t_crossing (other, wire, &where)) { node = node_store_get_or_create_node (store, where); node_add_wire (node, wire); node_add_wire (node, other); wire_add_node (wire, node); wire_add_node (other, node); NG_DEBUG ("Add wire %p to wire %p @ %lf,%lf.\n", wire, other, where.x, where.y); } else { // magic node removal if a x crossing is overlapped with another wire node = node_store_get_node (store, where); NG_DEBUG ("Nuke that node [ %p ] at coords inbetween", node); if (node) { Coords c[4]; wire_get_start_and_end_pos (other, c + 0, c + 1); wire_get_start_and_end_pos (wire, c + 2, c + 3); if (!coords_equal (&where, c + 0) && !coords_equal (&where, c + 1) && !coords_equal (&where, c + 2) && !coords_equal (&where, c + 3)) { wire_remove_node (wire, node); wire_remove_node (other, node); node_remove_wire (node, wire); node_remove_wire (node, other); } } } } } // Check for overlapping with other wires. do { for (list = store->wires; list; list = list->next) { g_assert (list->data != NULL); g_assert (IS_WIRE (list->data)); Wire *other = list->data; Coords so, eo; const gboolean overlap = do_wires_overlap (wire, other, &so, &eo); NG_DEBUG ("overlap [ %p] and [ %p ] -- %s", wire, other, overlap == TRUE ? "YES" : "NO"); if (overlap) { Node *sn = node_store_get_node (store, eo); Node *en = node_store_get_node (store, so); #if 1 wire = vulcanize_wire (store, wire, other, &so, &eo); node_store_remove_wire (store, g_object_ref (other)); // equiv // wire_unregister // XXX FIXME this // modifies the list // we iterate over! // delay this until idle, so all handlers like adding view // representation are completed so existing wire-items can be deleted // properly // this is not fancy nor nice but seems to work fairly nicly g_idle_add (delayed_wire_delete, other); break; NG_DEBUG ("overlapping of %p with %p ", wire, other); #else if (!sn && !en) { wire = vulcanize_wire (store, wire, other, &so, &eo); } else if (!sn) { NG_DEBUG ("do_something(TM) : %p sn==NULL ", other); } else if (!en) { NG_DEBUG ("do_something(TM) : %p en==NULL ", other); } else { NG_DEBUG ("do_something(TM) : %p else ", other); } #endif } else { NG_DEBUG ("not of %p with %p ", wire, other); } } } while (list); // Check for intersection with parts (pins). for (list = store->parts; list; list = list->next) { g_assert (list->data != NULL); g_assert (IS_PART (list->data)); Coords part_pos; gint num_pins = -1; Part *part = list->data; num_pins = part_get_num_pins (part); item_data_get_pos (ITEM_DATA (part), &part_pos); // Go through all the parts and see which of their // pins that intersect the wire. for (i = 0; i < num_pins; i++) { Pin *pins; Coords lookup_pos; pins = part_get_pins (part); lookup_pos.x = part_pos.x + pins[i].offset.x; lookup_pos.y = part_pos.y + pins[i].offset.y; // If there is a wire at this pin's position, // add it to the return list. if (is_point_on_wire (wire, &lookup_pos)) { Node *node; node = node_store_get_node (store, lookup_pos); if (node != NULL) { // Add the wire to the node (pin) that it intersected. node_add_wire (node, wire); wire_add_node (wire, node); NG_DEBUG ("Add wire %p to pin (node) %p.\n", wire, node); } else { g_warning ("Bug: Found no node at pin at (%g %g).\n", lookup_pos.x, lookup_pos.y); } } } } g_object_set (G_OBJECT (wire), "store", store, NULL); store->wires = g_list_prepend (store->wires, wire); store->items = g_list_prepend (store->items, wire); return TRUE; }