static int new_entry_line(config_t *cfg, const char *entry, const char *val, unsigned int *index) { int ret; char *eout, *vout; ret = search_entry(cfg, NULL, entry, index, &eout, &vout); if ( ret < 0 ) return op_insert_line(cfg, create_new_line(entry, val), *index); free_val(&eout); free_val(&vout); op_modify_line(&cfg->content[*index], create_new_line(entry, val)); return 0; }
static int new_section_line(config_t *cfg, const char *section, const char *entry, const char *val, unsigned int *index) { int ret; char *eout, *vout; unsigned int eindex; ret = search_section(cfg, section, *index); if ( ret < 0 ) { char buf[1024]; snprintf(buf, sizeof(buf), "[%s]", section); if ( *index ) *index = adjust_insertion_point(cfg, *index); else *index = cfg->elements; ret = op_insert_line(cfg, strdup(buf), *index); if ( ret < 0 ) return ret; return (! entry) ? 0 : op_insert_line(cfg, create_new_line(entry, val), *index + 1); } *index = ret; if ( ! entry ) return 0; eindex = *index + 1; ret = search_entry(cfg, section, entry, &eindex, &eout, &vout); if ( ret < 0 ) return op_insert_line(cfg, create_new_line(entry, val), eindex); free_val(&eout); free_val(&vout); op_modify_line(&cfg->content[eindex], create_new_line(entry, val)); return 0; }
/*! * \brief Create an Element for a SIP package. * * \return \c EXIT_SUCCESS when an element was created, * \c EXIT_FAILURE when errors were encountered. */ int sip_create_element () { gdouble xmax; gdouble xmin; gdouble ymax; gdouble ymin; gdouble x_text; gdouble y_text; gint i; gint pin_number; gchar *pin_pad_name = g_strdup (""); FlagType pad_flag; ElementTypePtr element; if (!element) { if (verbose) { g_log ("", G_LOG_LEVEL_WARNING, _("could not create a valid element pointer for a %s package."), footprint_type); } return (EXIT_FAILURE); } /* Define the center of our universe and guess for a place where to * put the element mark */ element->MarkX = 0; element->MarkY = 0; /* Determine (extreme) courtyard dimensions based on pin/pad * properties */ /* Determine (extreme) courtyard dimensions based on package * properties */ if ((multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package)) < xmin) { xmin = (multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package)); } if ((multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package)) > xmax) { xmax = (multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package)); } if ((multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package)) < ymin) { ymin = (multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package)); } if ((multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package)) > ymax) { ymax = (multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package)); } /* If the user input is using even more real-estate then use it */ if (multiplier * (-courtyard_length / 2.0) < xmin) { xmin = multiplier * (-courtyard_length / 2.0); } if (multiplier * (courtyard_length / 2.0) > xmax) { xmax = multiplier * (courtyard_length / 2.0); } if (multiplier * (-courtyard_width / 2.0) < ymin) { ymin = multiplier * (-courtyard_width / 2.0); } if (multiplier * (courtyard_width / 2.0) > ymax) { ymax = multiplier * (courtyard_width / 2.0); } /* Store the courtyard dimensions in Virtual (bounding) Box. */ element->VBox.X1 = (int) xmin; element->VBox.Y1 = (int) ymin; element->VBox.X2 = (int) xmax; element->VBox.Y2 = (int) ymax; /* Guess for a place where to put the element name */ element->Name[1].Scale = 100; /* 100 percent */ element->Name[1].X = 0.0 ; /* already in mil/100 */ element->Name[1].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[1].TextString = footprint_name; element->Name[1].Element = element; element->Name[1].Direction = EAST; element->Name[1].ID = ID++; /* Guess for a place where to put the element refdes */ element->Name[2].Scale = 100; /* 100 percent */ element->Name[2].X = 0.0 ; /* already in mil/100 */ element->Name[2].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[2].TextString = footprint_refdes; element->Name[2].Element = element; element->Name[2].Direction = EAST; element->Name[2].ID = ID++; /* Guess for a place where to put the element value */ element->Name[3].Scale = 100; /* 100 percent */ element->Name[3].X = 0.0 ; /* already in mil/100 */ element->Name[3].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[3].TextString = footprint_value; element->Name[3].Element = element; element->Name[3].Direction = EAST; element->Name[3].ID = ID++; /* Create pin and/or pad entities */ for (i = 0; (i < number_of_rows); i++) { pin_number = 1 + i; if (pad_shapes_type == SQUARE) { pad_flag.f = SQUARE; } else if (pin1_square && (pin_number == 1)) { pad_flag.f = SQUARE; } else { pad_flag.f = CLEAR; } create_new_pin ( element, (int) (multiplier * (-pitch_x / 2.0)), /* x0 coordinate */ (int) (multiplier * ((((-number_of_rows - 1) / 2.0) +1 + i) * pitch_y)), /* y0-coordinate */ (int) (multiplier * pad_diameter), /* width of the annulus ring (pad) */ (int) (multiplier * 2 * pad_clearance), /* clearance */ (int) (multiplier * (pad_diameter + (2 * pad_solder_mask_clearance))), /* solder mask clearance */ (int) (multiplier * pin_drill_diameter), /* pin drill diameter */ pin_pad_name, /* pin name */ g_strdup_printf ("%d", pin_number), /* pin number */ pad_flag /* flags */ ); if (!strcmp (pad_shape, "rounded pad, elongated")) { pad_flag.f = ONSOLDER; create_new_pad ( element, (int) (multiplier * (-pitch_x - pad_width + pad_length) / 2.0), /* x0 coordinate */ (int) (multiplier * ((((-number_of_rows - 1) / 2.0) + 1 + i) * pitch_y)), /* y0-coordinate */ (int) (multiplier * (-pitch_x + pad_width - pad_length) / 2.0), /* x1 coordinate */ (int) (multiplier * ((((-number_of_rows - 1) / 2.0) + 1 + i) * pitch_y)), /* y1-coordinate */ (int) (multiplier * pad_width), /* pad width */ (int) (multiplier * 2 * pad_clearance), /* clearance */ (int) (multiplier * (pad_width + (2 * pad_solder_mask_clearance))), /* solder mask clearance */ "", /* pad name */ g_strdup_printf ("%d", pin_number), /* pin number */ pad_flag /* flags */ ); } } /* Create a package body on the silkscreen. */ if (silkscreen_package_outline) { create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); } /* Create a pin #1 marker on the silkscreen. */ if (silkscreen_indicate_1) { /* Write a marker around pin #1 inside the package outline */ create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), /* x0-coordinate */ (int) (multiplier * ((((-number_of_rows - 1) / 2.0) + 1.5) * pitch_y)), /* y0-coordinate */ (int) (multiplier * (package_body_length / 2.0)), /* x1-coordinate */ (int) (multiplier * ((((-number_of_rows - 1) / 2.0) + 1.5) * pitch_y)), /* y1-coordinate */ (int) (multiplier * silkscreen_line_width) ); /* Write a triangle shaped marker between package outline and maximum used real estate */ if (xmax > ((multiplier * package_body_length) / 2)) { create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), /* x0-coordinate */ (int) (multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y)), /* y0-coordinate */ (int) ((multiplier * (-package_body_length / 2.0)) - 2500), /* x1-coordinate */ (int) ((multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y)) - 1250), /* y1-coordinate */ (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), /* x0-coordinate */ (int) (multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y)), /* y0-coordinate */ (int) ((multiplier * (-package_body_length / 2.0)) - 2500), /* x1-coordinate */ (int) ((multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y)) + 1250), /* y1-coordinate */ (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) ((multiplier * (-package_body_length / 2.0)) - 2500), /* x0-coordinate */ (int) ((multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y)) - 1250), /* y0-coordinate */ (int) ((multiplier * (-package_body_length / 2.0)) - 2500), /* x1-coordinate */ (int) ((multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y)) + 1250), /* y1-coordinate */ (int) (multiplier * silkscreen_line_width) ); } } /* Create a courtyard outline on the silkscreen. */ if (courtyard) { create_new_line ( element, (int) (xmin), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmin), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmax), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmax), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmin), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmax), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmax), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (xmin), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); } /* Create attributes. */ if (attributes_in_footprint) { element = create_attributes_in_element (element); } /* We are ready creating an element. */ if (verbose) { g_log ("", G_LOG_LEVEL_INFO, _("created an element for a %s package: %s."), footprint_type, footprint_filename); } current_element = (ElementTypePtr) &element; return (EXIT_SUCCESS); }
/*! * \brief Create an Element for a DIOAD package. * * \return \c EXIT_SUCCESS when an element was created, * \c EXIT_FAILURE when errors were encountered. */ int dioad_create_element () { gdouble xmax; gdouble xmin; gdouble ymax; gdouble ymin; gdouble x_text; gdouble y_text; gdouble dx; gint pin_number; gchar *pin_pad_name = g_strdup (""); FlagType pad_flag; ElementTypePtr element; if (!element) { if (verbose) { g_log ("", G_LOG_LEVEL_WARNING, (_("[%s] could not create a valid element pointer for an element.")), footprint_type); } return (EXIT_FAILURE); } /* Define the center of our universe and guess for a place where to * put the element mark */ element->MarkX = 0; element->MarkY = 0; /* Determine (extreme) courtyard dimensions based on pin/pad * properties */ if (pad_shapes_type == ROUND_ELONGATED) { xmin = multiplier * ( (-pitch_x / 2.0) - (pad_length / 2.0) - pad_solder_mask_clearance ); xmax = multiplier * ( (pitch_x / 2.0) + (pad_length / 2.0) + pad_solder_mask_clearance ); ymin = multiplier * ( (-pitch_y / 2.0) - (pad_width / 2.0) - pad_solder_mask_clearance ); ymax = multiplier * ( (pitch_y / 2.0) + (pad_width / 2.0) + pad_solder_mask_clearance ); } else { xmin = multiplier * ( (-pitch_x / 2.0) - (pad_diameter / 2.0) - pad_solder_mask_clearance ); xmax = multiplier * ( (pitch_x / 2.0) + (pad_diameter / 2.0) + pad_solder_mask_clearance ); ymin = multiplier * ( (-pitch_y / 2.0) - (pad_diameter / 2.0) - pad_solder_mask_clearance ); ymax = multiplier * ( (pitch_y / 2.0) + (pad_diameter / 2.0) + pad_solder_mask_clearance ); } /* Determine (extreme) courtyard dimensions based on package * properties */ if ((multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package)) < xmin) { xmin = (multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package)); } if ((multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package)) > xmax) { xmax = (multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package)); } if ((multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package)) < ymin) { ymin = (multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package)); } if ((multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package)) > ymax) { ymax = (multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package)); } /* If the user input is using even more real-estate then use it */ if (multiplier * (-courtyard_length / 2.0) < xmin) { xmin = multiplier * (-courtyard_length / 2.0); } if (multiplier * (courtyard_length / 2.0) > xmax) { xmax = multiplier * (courtyard_length / 2.0); } if (multiplier * (-courtyard_width / 2.0) < ymin) { ymin = multiplier * (-courtyard_width / 2.0); } if (multiplier * (courtyard_width / 2.0) > ymax) { ymax = multiplier * (courtyard_width / 2.0); } /* Store the courtyard dimensions in Virtual (bounding) Box. */ element->VBox.X1 = (int) xmin; element->VBox.Y1 = (int) ymin; element->VBox.X2 = (int) xmax; element->VBox.Y2 = (int) ymax; /* Guess for a place where to put the element name */ element->Name[1].Scale = 100; /* 100 percent */ element->Name[1].X = 0.0 ; /* already in mil/100 */ element->Name[1].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[1].TextString = footprint_name; element->Name[1].Element = element; element->Name[1].Direction = EAST; element->Name[1].ID = ID++; /* Guess for a place where to put the element refdes */ element->Name[2].Scale = 100; /* 100 percent */ element->Name[2].X = 0.0 ; /* already in mil/100 */ element->Name[2].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[2].TextString = footprint_refdes; element->Name[2].Element = element; element->Name[2].Direction = EAST; element->Name[2].ID = ID++; /* Guess for a place where to put the element value */ element->Name[3].Scale = 100; /* 100 percent */ element->Name[3].X = 0.0 ; /* already in mil/100 */ element->Name[3].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[3].TextString = footprint_value; element->Name[3].Element = element; element->Name[3].Direction = EAST; element->Name[3].ID = ID++; /* Create pin and/or pad entities */ if (pad_shapes_type == SQUARE) { pad_flag.f = SQUARE; } else if (pad_shapes_type == OCTAGONAL) { pad_flag.f = OCTAGON; } else { pad_flag.f = CLEAR; } create_new_pin ( element, (int) (multiplier * ((pitch_x + pad_diameter) / 2.0)), /* x0 coordinate */ 0, /* y0-coordinate */ (int) (multiplier * pad_diameter), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * (pad_diameter + pad_solder_mask_clearance)), /* solder mask clearance */ (int) (multiplier * pin_drill_diameter), /* pin drill diameter */ "A", /* pin name */ "2", /* pin number */ pad_flag /* flags */ ); /* Overrule previous settings in favour of pin 1 square setting */ if (pin1_square) { pad_flag.f = SQUARE; } create_new_pin ( element, (int) (multiplier * ((-pitch_x - pad_diameter) / 2.0)), /* x0 coordinate */ 0, /* y0-coordinate */ (int) (multiplier * pad_diameter), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * (pad_diameter + pad_solder_mask_clearance)), /* solder mask clearance */ (int) (multiplier * pin_drill_diameter), /* pin drill diameter */ "C", /* pin name */ "1", /* pin number */ pad_flag /* flags */ ); if (pad_shapes_type == ROUND_ELONGATED) { /* Add pads on component side */ pad_flag.f = CLEAR; create_new_pad ( element, (int) (multiplier * ((-pitch_x - pad_length + pad_width) / 2.0)), /* x0 coordinate */ 0, /* y0-coordinate */ (int) (multiplier * ((-pitch_x + pad_length - pad_width) / 2.0)), /* x1 coordinate */ 0, /* y1-coordinate */ (int) (multiplier * pad_width), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * ((pad_length > pad_width ? pad_width : pad_length) + (2 * pad_solder_mask_clearance))), /* solder mask clearance */ "C", /* pin name */ "1", /* pin number */ pad_flag /* flags */ ); create_new_pad ( element, (int) (multiplier * ((pitch_x + pad_length - pad_width) / 2.0)), /* x0 coordinate */ 0, /* y0-coordinate */ (int) (multiplier * ((pitch_x - pad_length + pad_width) / 2.0)), /* x1 coordinate */ 0, /* y1-coordinate */ (int) (multiplier * pad_width), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * ((pad_length > pad_width ? pad_width : pad_length) + (2 * pad_solder_mask_clearance))), /* solder mask clearance */ "A", /* pin name */ "2", /* pin number */ pad_flag /* flags */ ); /* Add pads on solder side */ pad_flag.f = ONSOLDER; create_new_pad ( element, (int) (multiplier * ((-pitch_x - pad_length + pad_width) / 2.0)), /* x0 coordinate */ 0, /* y0-coordinate */ (int) (multiplier * ((-pitch_x + pad_length - pad_width) / 2.0)), /* x1 coordinate */ 0, /* y1-coordinate */ (int) (multiplier * pad_width), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * ((pad_length > pad_width ? pad_width : pad_length) + (2 * pad_solder_mask_clearance))), /* solder mask clearance */ "C", /* pin name */ "1", /* pin number */ pad_flag /* flags */ ); create_new_pad ( element, (int) (multiplier * ((pitch_x + pad_length - pad_width) / 2.0)), /* x0 coordinate */ 0, /* y0-coordinate */ (int) (multiplier * ((pitch_x - pad_length + pad_width) / 2.0)), /* x1 coordinate */ 0, /* y1-coordinate */ (int) (multiplier * pad_width), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * ((pad_length > pad_width ? pad_width : pad_length) + (2 * pad_solder_mask_clearance))), /* solder mask clearance */ "A", /* pin name */ "2", /* pin number */ pad_flag /* flags */ ); } /* Create a package body on the silkscreen. */ if (silkscreen_package_outline) { create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); /* Now draw some leads if available real estate allows for it. */ if (package_body_length < ((pitch_x - pad_diameter - pad_solder_mask_clearance) / 2.0) - silkscreen_line_width) { create_new_line ( element, (int) (multiplier * (package_body_length / 2.0)), 0, (int) ((multiplier * (pitch_x - pad_diameter - pad_solder_mask_clearance) / 2.0) - silkscreen_line_width), 0, (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), 0, (int) ((multiplier * (-pitch_x + pad_diameter + pad_solder_mask_clearance) / 2.0) + silkscreen_line_width), 0, (int) (multiplier * silkscreen_line_width) ); } } /* Create a pin #1 marker on the silkscreen. */ if (silkscreen_indicate_1) { for (dx = 0.0; dx = (3.0 * silkscreen_line_width); dx = dx + silkscreen_line_width) { create_new_line ( element, (int) (multiplier * ((-package_body_length / 2.0) + dx)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * ((-package_body_length / 2.0) + dx)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); } } /* Create a courtyard outline on the silkscreen. */ if (courtyard) { create_new_line ( element, (int) (xmin), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmin), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmax), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmax), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmin), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmax), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmax), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (xmin), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); } /* Create attributes. */ if (attributes_in_footprint) { element = create_attributes_in_element (element); } /* We are ready creating an element. */ if (verbose) { g_log ("", G_LOG_LEVEL_INFO, (_("[%s] created an element for element: %s.")), footprint_type, footprint_filename); } current_element = (ElementTypePtr) &element; return (EXIT_SUCCESS); }
/*! * \brief Create an Element for a PGA package. * * \return \c EXIT_SUCCESS when an element was created, * \c EXIT_FAILURE when errors were encountered. */ int pga_create_element () { gdouble xmax; gdouble xmin; gdouble ymax; gdouble ymin; gdouble x_text; gdouble y_text; gdouble dx; gint pin_number; gchar *pin_pad_name = g_strdup (""); FlagType pad_flag; ElementTypePtr element; gint i; gint j; if (!element) { if (verbose) g_log ("", G_LOG_LEVEL_WARNING, _("could not create a valid element pointer for a %s package."), footprint_type); return (EXIT_FAILURE); } /* Define the center of our universe and guess for a place where to * put the element mark */ element->MarkX = 0; element->MarkY = 0; /* Determine (extreme) courtyard dimensions based on pin/pad * properties */ /* Determine (extreme) courtyard dimensions based on package * properties */ if ((multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package)) < xmin) { xmin = (multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package)); } if ((multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package)) > xmax) { xmax = (multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package)); } if ((multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package)) < ymin) { ymin = (multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package)); } if ((multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package)) > ymax) { ymax = (multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package)); } /* If the user input is using even more real-estate then use it */ if (multiplier * (-courtyard_length / 2.0) < xmin) { xmin = multiplier * (-courtyard_length / 2.0); } if (multiplier * (courtyard_length / 2.0) > xmax) { xmax = multiplier * (courtyard_length / 2.0); } if (multiplier * (-courtyard_width / 2.0) < ymin) { ymin = multiplier * (-courtyard_width / 2.0); } if (multiplier * (courtyard_width / 2.0) > ymax) { ymax = multiplier * (courtyard_width / 2.0); } /* Store the courtyard dimensions in Virtual (bounding) Box. */ element->VBox.X1 = (int) xmin; element->VBox.Y1 = (int) ymin; element->VBox.X2 = (int) xmax; element->VBox.Y2 = (int) ymax; /* Guess for a place where to put the element name */ element->Name[1].Scale = 100; /* 100 percent */ element->Name[1].X = 0.0 ; /* already in mil/100 */ element->Name[1].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[1].TextString = footprint_name; element->Name[1].Element = element; element->Name[1].Direction = EAST; element->Name[1].ID = ID++; /* Guess for a place where to put the element refdes */ element->Name[2].Scale = 100; /* 100 percent */ element->Name[2].X = 0.0 ; /* already in mil/100 */ element->Name[2].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[2].TextString = footprint_refdes; element->Name[2].Element = element; element->Name[2].Direction = EAST; element->Name[2].ID = ID++; /* Guess for a place where to put the element value */ element->Name[3].Scale = 100; /* 100 percent */ element->Name[3].X = 0.0 ; /* already in mil/100 */ element->Name[3].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[3].TextString = footprint_value; element->Name[3].Element = element; element->Name[3].Direction = EAST; element->Name[3].ID = ID++; /* Create pin and/or pad entities */ if (pad_shapes_type == SQUARE) { pad_flag.f = SQUARE; } else { pad_flag.f = CLEAR; } pin_number = 1; for (i = 0; (i < number_of_rows); i++) /* one row at a time [A .. ZZ ..] etc. * where i is one or more letters of the alphabet, * excluding "I", "O", "Q", "S" and "Z" */ { for (j = 0; (j < number_of_columns); j++) /* all columns of a row [1 .. n] * where j is a member of the positive Natural numbers (N) */ { if (pin1_square && (pin_number == 1)) pad_flag.f = SQUARE; else pad_flag.f = CLEAR; pin_pad_name = g_strdup_printf ("%s%d", (row_letters[i]), (j + 1)); if (get_pin_pad_exception (pin_pad_name)) { create_new_pin ( element, (int) (multiplier * ((((- number_of_columns -1) / 2.0) + 1 + j) * pitch_x)), /* x0 coordinate */ (int) (multiplier * ((((-number_of_rows - 1) / 2.0) + 1 + i) * pitch_y)), /* y0-coordinate */ (int) (multiplier * pad_diameter), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * (pad_diameter + pad_solder_mask_clearance)), /* solder mask clearance */ (int) (multiplier * pin_drill_diameter), /* pin drill diameter */ pin_pad_name, /* pin name */ g_strdup_printf ("%d", pin_number), /* pin number */ pad_flag /* flags */ ); } pin_number++; } } /* Create a package body. */ if (courtyard) { create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); } /* Create a pin #1 marker on the silkscreen. */ if (silkscreen_indicate_1) { fprintf (fp, "# Write a pin 1 marker on the silkscreen\n"); for (dx = 0.0; dx < (pitch_x / 2.0); dx = dx + silkscreen_line_width) { create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * ((-package_body_width / 2.0) + dx)), (int) (multiplier * ((-package_body_length / 2.0) + dx)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); } } /* Create a courtyard. */ if (courtyard) { create_new_line ( element, (int) (xmin), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmin), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmax), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmax), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmin), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmax), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmax), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (xmin), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); } /* Create attributes. */ if (attributes_in_footprint) { element = create_attributes_in_element (element); } /* We are ready creating an element. */ if (verbose) { g_log ("", G_LOG_LEVEL_INFO, _("created an element for a %s package: %s."), footprint_type, footprint_filename); } current_element = (ElementTypePtr) &element; return (EXIT_SUCCESS); }
/*! * \brief Create an Element for a RESM package. * * \return \c EXIT_SUCCESS when an element was created, * \c EXIT_FAILURE when errors were encountered. */ int resm_create_element () { gdouble xmax; gdouble xmin; gdouble ymax; gdouble ymin; gdouble x_text; gdouble y_text; gdouble dx; gint pin_number; gchar *pin_pad_name = g_strdup (""); FlagType pad_flag; ElementTypePtr element; if (!element) { if (verbose) { g_log ("", G_LOG_LEVEL_WARNING, _("could not create a valid element pointer for a %s package."), footprint_type); } return (EXIT_FAILURE); } /* Define the center of our universe and guess for a place where to * put the element mark */ element->MarkX = 0; element->MarkY = 0; /* Determine (extreme) courtyard dimensions based on pin/pad * properties */ xmin = multiplier * ((-pitch_x / 2.0) - (pad_length / 2.0) - pad_solder_mask_clearance); xmax = multiplier * (pitch_x / 2.0 + pad_length / 2.0 + pad_solder_mask_clearance); ymin = multiplier * ((-pad_width / 2.0) - pad_solder_mask_clearance); ymax = multiplier * (pad_width / 2.0 + pad_solder_mask_clearance); /* Determine (extreme) courtyard dimensions based on package * properties */ if ((multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package)) < xmin) { xmin = (multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package)); } if ((multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package)) > xmax) { xmax = (multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package)); } if ((multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package)) < ymin) { ymin = (multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package)); } if ((multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package)) > ymax) { ymax = (multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package)); } /* If the user input is using even more real-estate then use it */ if (multiplier * (-courtyard_length / 2.0) < xmin) { xmin = multiplier * (-courtyard_length / 2.0); } if (multiplier * (courtyard_length / 2.0) > xmax) { xmax = multiplier * (courtyard_length / 2.0); } if (multiplier * (-courtyard_width / 2.0) < ymin) { ymin = multiplier * (-courtyard_width / 2.0); } if (multiplier * (courtyard_width / 2.0) > ymax) { ymax = multiplier * (courtyard_width / 2.0); } /* Store the courtyard dimensions in Virtual (bounding) Box. */ element->VBox.X1 = (int) xmin; element->VBox.Y1 = (int) ymin; element->VBox.X2 = (int) xmax; element->VBox.Y2 = (int) ymax; /* Guess for a place where to put the element name */ element->Name[1].Scale = 100; /* 100 percent */ element->Name[1].X = 0.0 ; /* already in mil/100 */ element->Name[1].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[1].TextString = footprint_name; element->Name[1].Element = element; element->Name[1].Direction = EAST; element->Name[1].ID = ID++; /* Guess for a place where to put the element refdes */ element->Name[2].Scale = 100; /* 100 percent */ element->Name[2].X = 0.0 ; /* already in mil/100 */ element->Name[2].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[2].TextString = footprint_refdes; element->Name[2].Element = element; element->Name[2].Direction = EAST; element->Name[2].ID = ID++; /* Guess for a place where to put the element value */ element->Name[3].Scale = 100; /* 100 percent */ element->Name[3].X = 0.0 ; /* already in mil/100 */ element->Name[3].Y = (ymin - 10000.0); /* already in mil/100 */ element->Name[3].TextString = footprint_value; element->Name[3].Element = element; element->Name[3].Direction = EAST; element->Name[3].ID = ID++; /* Create pin and/or pad entities */ if (pad_shapes_type == SQUARE) { pad_flag.f = SQUARE; } else { pad_flag.f = CLEAR; } if (pad_length > pad_width) /* Write pads parallel to x-axis */ { /* Pad #2 */ create_new_pad ( element, (int) (multiplier * ((pitch_x - pad_length + pad_width) / 2.0)), /* x0 coordinate */ 0, /* y0-coordinate */ (int) (multiplier * ((pitch_x + pad_length - pad_width) / 2.0)), /* x1 coordinate */ 0, /* y1-coordinate */ (int) (multiplier * pad_width), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * (pad_width + (2 * pad_solder_mask_clearance))), /* solder mask clearance */ "", /* pad name */ "2", /* pin number */ pad_flag /* flags */ ); /* Write pad #1 with a square pad if checked */ if (pin1_square) { pad_flag.f = SQUARE; } /* Pad #1 */ create_new_pad ( element, (int) (multiplier * ((-pitch_x - pad_length + pad_width) / 2.0)), /* x0 coordinate */ 0, /* y0-coordinate */ (int) (multiplier * ((-pitch_x + pad_length - pad_width) / 2.0)), /* x1 coordinate */ 0, /* y1-coordinate */ (int) (multiplier * pad_width), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * (pad_width + (2 * pad_solder_mask_clearance))), /* solder mask clearance */ "", /* pad name */ "1", /* pin number */ pad_flag /* flags */ ); } else /* write pads perpendiclar to x-axis */ { /* Pad #2 */ create_new_pad ( element, (int) (multiplier * (pitch_x / 2.0)), /* x0 coordinate */ (int) (multiplier * ((pad_width - pad_length) / 2.0)), /* y0-coordinate */ (int) (multiplier * (pitch_x / 2.0)), /* x1 coordinate */ (int) (multiplier * ((-pad_width + pad_length) / 2.0)), /* y1-coordinate */ (int) (multiplier * pad_length), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * (pad_length + (2 * pad_solder_mask_clearance))), /* solder mask clearance */ "", /* pad name */ "2", /* pin number */ pad_flag /* flags */ ); /* Write pad #1 with a square pad if checked */ if (pin1_square) { pad_flag.f = SQUARE; } /* Pad #1 */ create_new_pad ( element, (int) (multiplier * (-pitch_x / 2.0)), /* x0 coordinate */ (int) (multiplier * ((pad_width - pad_length) / 2.0)), /* y0-coordinate */ (int) (multiplier * (-pitch_x / 2)), /* x1 coordinate */ (int) (multiplier * ((-pad_width + pad_length) / 2.0)), /* y1-coordinate */ (int) (multiplier * pad_length), /* pad width */ (int) (multiplier * pad_clearance), /* clearance */ (int) (multiplier * (pad_length + (2 * pad_solder_mask_clearance))), /* solder mask clearance */ "", /* pad name */ "1", /* pin number */ pad_flag /* flags */ ); } /* Create a package body. */ if (silkscreen_package_outline && package_body_width) { if (pad_width >= package_body_width) { create_new_line ( element, (int) (multiplier * (((-pitch_x + pad_length) / 2.0) + pad_solder_mask_clearance + silkscreen_line_width)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * (((pitch_x - pad_length) / 2.0) - pad_solder_mask_clearance - silkscreen_line_width)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (((-pitch_x + pad_length) / 2.0) + pad_solder_mask_clearance + silkscreen_line_width)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (((pitch_x - pad_length) / 2.0) - pad_solder_mask_clearance - silkscreen_line_width)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); } else { /* lines parallel to X-axis */ create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); /* lines perpendicular to X-axis */ create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (((-pad_width - silkscreen_line_width) / 2.0) - pad_solder_mask_clearance)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * (-package_body_length / 2.0)), (int) (multiplier * (((pad_width + silkscreen_line_width) / 2.0) + pad_solder_mask_clearance)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (((-pad_width - silkscreen_line_width) / 2.0) - pad_solder_mask_clearance)), (int) (multiplier * silkscreen_line_width) ); create_new_line ( element, (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * (package_body_length / 2.0)), (int) (multiplier * (((pad_width + silkscreen_line_width) / 2.0) + pad_solder_mask_clearance)), (int) (multiplier * silkscreen_line_width) ); } } /* Create a pin #1 marker. */ if (silkscreen_indicate_1) { if (pad_width >= package_body_width) { create_new_line ( element, (int) (multiplier * (((-pitch_x + pad_length) / 2.0) + pad_solder_mask_clearance + silkscreen_line_width)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * (((-pitch_x + pad_length) / 2.0) + pad_solder_mask_clearance + silkscreen_line_width)), (int) (multiplier * (package_body_width / 2.0)), (int) (multiplier * silkscreen_line_width) ); } else { create_new_arc ( element, (int) (multiplier * (((-package_body_length) / 2.0) - 2 * silkscreen_line_width)), (int) (multiplier * (-package_body_width / 2.0)), (int) (multiplier * 0.5 * silkscreen_line_width), (int) (multiplier * 0.5 * silkscreen_line_width), 0, 360, (int) (multiplier * silkscreen_line_width) ); } } /* Create a courtyard. */ if (courtyard) { create_new_line ( element, (int) (xmin), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmin), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmax), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmax), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmin), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (xmax), /* already in mil/100 */ (int) (ymin), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); create_new_line ( element, (int) (xmax), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (xmin), /* already in mil/100 */ (int) (ymax), /* already in mil/100 */ (int) (multiplier * courtyard_line_width) ); } /* Create attributes. */ if (attributes_in_footprint) { element = create_attributes_in_element (element); } /* We are ready creating an element. */ if (verbose) { g_log ("", G_LOG_LEVEL_INFO, _("created an element for a %s package: %s."), footprint_type, footprint_filename); } current_element = (ElementTypePtr) &element; return (EXIT_SUCCESS); }
static void end_unknown_segments (TrackNewSegment *new_segments, int count) { int i; int start_point = 0; NodeNeighbour end_node = NODE_NEIGHBOUR_NULL; editor_track_util_create_db (track_point_pos (start_point)); for (i=0; i<count; i++) { int type = new_segments[i].type; int end_point = new_segments[i].point_id; int end_node_id = -1; switch (type) { case TRACK_ROAD_TURN: if (editor_track_util_length (start_point, end_point) < (editor_track_point_distance () * 2)) { RoadMapPosition pos; RoadMapPosition *pos1; RoadMapPosition *pos2; pos1 = track_point_pos (start_point); pos2 = track_point_pos (end_point); pos.longitude = (pos1->longitude + pos2->longitude) / 2; pos.latitude = (pos1->latitude + pos2->latitude) / 2; if (cur_node.plugin_id == ROADMAP_PLUGIN_ID) { cur_node.id = editor_track_util_roadmap_node_to_editor (&cur_node); cur_node.plugin_id = EditorPluginID; } else { editor_point_set_pos (cur_node.id, &pos); } start_point = end_point; continue; } break; case TRACK_ROAD_ROUNDABOUT: if (cur_node.plugin_id == ROADMAP_PLUGIN_ID) { cur_node.id = editor_track_util_roadmap_node_to_editor (&cur_node); cur_node.plugin_id = EditorPluginID; } create_new_line (start_point, end_point, cur_node.id, cur_node.id, ROADMAP_ROAD_STREET); start_point = end_point; continue; break; } if ((i == (count - 1)) && (TrackConfirmedStreet.valid)) { /* we are connecting to a known road */ end_point = editor_track_util_new_road_end (&TrackConfirmedLine, track_point_pos (end_point), end_point, TrackConfirmedStreet.line_direction, &end_node); if (end_node.plugin_id == ROADMAP_PLUGIN_ID) { end_node.id = editor_track_util_roadmap_node_to_editor (&end_node); end_node.plugin_id = EditorPluginID; } end_node_id = end_node.id; } if ((i < (count -1)) || (start_point != (end_point -1))) { int line_id = create_new_line (start_point, end_point, -1, end_node_id, ROADMAP_ROAD_STREET); if ((line_id != -1) && ((type == TRACK_ROAD_CONNECTION) || !EditorAllowNewRoads)) { editor_line_set_flag (line_id, ED_LINE_CONNECTION); } } start_point = end_point; } track_reset_points (start_point); }
static int add_road_connection (int point_id, RoadMapTracking *new_street, RoadMapNeighbour *new_line) { int from_point; int end_point; int line_id; NodeNeighbour end_node = NODE_NEIGHBOUR_NULL; int road_type = 0; editor_log_push ("add_road_connection"); from_point = editor_track_util_new_road_start (&TrackConfirmedLine, track_point_pos (point_id), point_id, TrackConfirmedStreet.line_direction, &cur_node); assert (from_point != -1); if (from_point == -1) { return -1; } if (editor_track_known_end_segment (&TrackPreviousLine.line, from_point, &TrackConfirmedLine.line, &TrackConfirmedStreet, is_new_track)) { is_new_track = 0; } track_reset_points (from_point); /*FIXME the whole previous line thing is not used and broken */ TrackPreviousLine = TrackConfirmedLine; TrackConfirmedLine = *new_line; TrackConfirmedStreet = *new_street; end_point = editor_track_util_new_road_end (&TrackConfirmedLine, track_point_pos (points_count - 1), points_count - 1, TrackConfirmedStreet.line_direction, &end_node); if ((cur_node.plugin_id == ROADMAP_PLUGIN_ID) && (end_node.plugin_id == ROADMAP_PLUGIN_ID)) { /* This a known connection road */ road_type = 0; } else { road_type = ED_LINE_CONNECTION; } if (!EditorAllowNewRoads) { road_type = ED_LINE_CONNECTION; } if (end_node.plugin_id == ROADMAP_PLUGIN_ID) { end_node.id = editor_track_util_roadmap_node_to_editor (&end_node); end_node.plugin_id = EditorPluginID; } line_id = create_new_line (0, end_point, -1, end_node.id, ROADMAP_ROAD_STREET); if (road_type == ED_LINE_CONNECTION) { if (line_id != -1) { editor_line_set_flag (line_id, ED_LINE_CONNECTION); } } track_reset_points (end_point); return from_point + end_point; }