/*! * \brief Write a SIP pin through hole footprint. * * The pin/pad numbering scheme of the SIP package is: \n * 1 \n * 2 \n * 3 \n * 4 \n * * \return \c EXIT_FAILURE when errors were encountered, * \c EXIT_SUCCESS when OK. */ int sip_write_footprint () { gdouble xmax; gdouble xmin; gdouble ymax; gdouble ymin; gdouble x_text; gdouble y_text; gint pin_number; gchar *pin_pad_name = g_strdup (""); gchar *pin_pad_flags = g_strdup (""); gint i; number_of_columns = 1; /* Attempt to open a file with write permission. */ fp = fopen (footprint_filename, "w"); if (!fp) { g_log ("", G_LOG_LEVEL_WARNING, _("could not open file for %s footprint: %s."), footprint_type, footprint_filename); fclose (fp); return (EXIT_FAILURE); } /* Print a license if requested. */ if (license_in_footprint) { write_license (); } /* Determine (extreme) courtyard dimensions based on pin/pad * properties */ xmin = multiplier * ( (((pad_diameter > pad_length) ? pad_diameter : pad_length) / -2.0) - pad_solder_mask_clearance ); xmax = multiplier * ( (((pad_diameter > pad_length) ? pad_diameter : pad_length) / 2.0) + pad_solder_mask_clearance ); ymin = multiplier * ( (((-number_of_rows + 1) / 2.0) * pitch_y) - (((pad_diameter > pad_width) ? pad_diameter : pad_width) / 2.0) - pad_solder_mask_clearance ); ymax = multiplier * ( (((number_of_rows - 1 ) / 2.0) * pitch_y) + (((pad_diameter > pad_width) ? pad_diameter : 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); } /* Write element header * Guess for a place where to put the refdes text */ x_text = 0.0 ; /* already in mil/100 */ y_text = (ymin - 10000.0); /* already in mil/100 */ write_element_header (x_text, y_text); /* Write pin and/or pad entities */ for (i = 0; (i < number_of_rows); i++) { pin_number = 1 + i; write_pin ( pin_number, /* pin number */ pin_pad_name, /* pin name */ 0, /* x0 coordinate */ multiplier * ((((-number_of_rows - 1) / 2.0) +1 + i) * pitch_y), /* y0-coordinate */ multiplier * pad_diameter, /* width of the annulus ring (pad) */ multiplier * 2 * pad_clearance, /* clearance */ multiplier * (pad_diameter + (2 * pad_solder_mask_clearance)), /* solder mask clearance */ multiplier * pin_drill_diameter, /* pin drill diameter */ (pin1_square && (pin_number == 1)) ? "square" : pin_pad_flags /* flags */ ); if (!strcmp (pad_shape, "rounded pad, elongated")) { if (!strcmp (pin_pad_flags, "")) pin_pad_flags = g_strconcat (pin_pad_flags, "onsolder", NULL); else pin_pad_flags = g_strconcat (pin_pad_flags, ",onsolder", NULL); write_pad ( pin_number, /* pad number = pin_number */ pin_pad_name, /* pad name */ multiplier * (-pad_width + pad_length) / 2.0, /* x0 coordinate */ multiplier * ((((-number_of_rows - 1) / 2.0) + 1 + i) * pitch_y), /* y0-coordinate */ multiplier * (pad_width - pad_length) / 2.0, /* x1 coordinate */ multiplier * ((((-number_of_rows - 1) / 2.0) + 1 + i) * pitch_y), /* y1-coordinate */ multiplier * pad_width, /* width of the pad */ multiplier * 2 * pad_clearance, /* clearance */ multiplier * (pad_width + (2 * pad_solder_mask_clearance)), /* solder mask clearance */ pin_pad_flags /* flags */ ); } } /* Write a package body on the silkscreen */ if (silkscreen_package_outline) { fprintf (fp, "# Write a package body on the silkscreen\n"); write_rectangle ( multiplier * ((-package_body_length) / 2.0), /* xmin-coordinate */ multiplier * ((-package_body_width) / 2.0), /* ymin-coordinate */ multiplier * ((package_body_length) / 2.0), /* xmax-coordinate */ multiplier * ((package_body_width) / 2.0), /* ymax-coordiante */ multiplier * silkscreen_line_width ); } /* Write a pin #1 marker on the silkscreen */ if (silkscreen_indicate_1) { fprintf (fp, "# Write a pin 1 marker on the silkscreen\n"); /* Write a marker around pin #1 inside the package outline */ write_element_line ( multiplier * (-package_body_length / 2.0), /* x0-coordinate */ multiplier * ((((-number_of_rows - 1) / 2.0) + 1.5) * pitch_y), /* y0-coordinate */ multiplier * (package_body_length / 2.0), /* x1-coordinate */ multiplier * ((((-number_of_rows - 1) / 2.0) + 1.5) * pitch_y), /* y1-coordinate */ multiplier * (silkscreen_line_width) ); /* Write a triangle shaped marker between package outline and maximum used real estate */ if (xmax > ((multiplier * package_body_length) / 2)) { write_element_line ( multiplier * (-package_body_length / 2.0), /* x0-coordinate */ multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y), /* y0-coordinate */ (multiplier * (-package_body_length / 2.0)) - 2500 , /* x1-coordinate */ (multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y)) - 1250, /* y1-coordinate */ multiplier * (silkscreen_line_width) ); write_element_line ( multiplier * (-package_body_length / 2.0), /* x0-coordinate */ multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y), /* y0-coordinate */ (multiplier * (-package_body_length / 2.0)) - 2500 , /* x1-coordinate */ (multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y)) + 1250, /* y1-coordinate */ multiplier * (silkscreen_line_width) ); write_element_line ( (multiplier * (-package_body_length / 2.0)) - 2500 , /* x0-coordinate */ (multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y)) - 1250, /* y0-coordinate */ (multiplier * (-package_body_length / 2.0)) - 2500 , /* x1-coordinate */ (multiplier * (((-number_of_rows + 1) / 2.0) * pitch_y)) + 1250, /* y1-coordinate */ multiplier * (silkscreen_line_width) ); } } /* Write a courtyard on the silkscreen */ if (courtyard) { fprintf (fp, "# Write a courtyard on the silkscreen\n"); write_rectangle ( xmin, /* already in mil/100 */ ymin, /* already in mil/100 */ xmax, /* already in mil/100 */ ymax, /* already in mil/100 */ multiplier * courtyard_line_width ); } /* Write attributes to the footprint file. */ if (attributes_in_footprint) { write_attributes (); } /* Finishing touch. */ fprintf (fp, "\n"); fprintf (fp, ")\n"); fclose (fp); /* We are ready creating a footprint. */ if (verbose) { g_log ("", G_LOG_LEVEL_INFO, _("wrote a footprint for a %s package: %s."), footprint_type, footprint_filename); } return (EXIT_SUCCESS); }
bool ImageOutput::write_image (TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride, ProgressCallback progress_callback, void *progress_callback_data) { bool native = (format == TypeDesc::UNKNOWN); stride_t pixel_bytes = native ? (stride_t) m_spec.pixel_bytes (native) : format.size() * m_spec.nchannels; if (xstride == AutoStride) xstride = pixel_bytes; m_spec.auto_stride (xstride, ystride, zstride, format, m_spec.nchannels, m_spec.width, m_spec.height); if (supports ("rectangles")) { // Use a rectangle if we can return write_rectangle (0, m_spec.width, 0, m_spec.height, 0, m_spec.depth, format, data, xstride, ystride, zstride); } bool ok = true; if (progress_callback && progress_callback (progress_callback_data, 0.0f)) return ok; if (m_spec.tile_width && supports ("tiles")) { // Tiled image for (int z = 0; z < m_spec.depth; z += m_spec.tile_depth) { int zend = std::min (z+m_spec.z+m_spec.tile_depth, m_spec.z+m_spec.depth); for (int y = 0; y < m_spec.height; y += m_spec.tile_height) { int yend = std::min (y+m_spec.y+m_spec.tile_height, m_spec.y+m_spec.height); const char *d = (const char *)data + z*zstride + y*ystride; ok &= write_tiles (m_spec.x, m_spec.x+m_spec.width, y+m_spec.y, yend, z+m_spec.z, zend, format, d, xstride, ystride, zstride); if (progress_callback && progress_callback (progress_callback_data, (float)(z*m_spec.height+y)/(m_spec.height*m_spec.depth))) return ok; } } } else { // Scanline image const int chunk = 256; for (int z = 0; z < m_spec.depth; ++z) for (int y = 0; y < m_spec.height && ok; y += chunk) { int yend = std::min (y+m_spec.y+chunk, m_spec.y+m_spec.height); const char *d = (const char *)data + z*zstride + y*ystride; ok &= write_scanlines (y+m_spec.y, yend, z+m_spec.z, format, d, xstride, ystride); if (progress_callback && progress_callback (progress_callback_data, (float)(z*m_spec.height+y)/(m_spec.height*m_spec.depth))) return ok; } } if (progress_callback) progress_callback (progress_callback_data, 1.0f); return ok; }
/*! * \brief Write a TH footprint for a DIOAD package. * * \return \c EXIT_FAILURE when errors were encountered, * \c EXIT_SUCCESS when OK. */ int dioad_write_footprint () { gdouble xmax; gdouble xmin; gdouble ymax; gdouble ymin; gdouble x_text; gdouble y_text; gdouble dx; gchar *pin_pad_flags = g_strdup (""); /* Attempt to open a file with write permission. */ fp = fopen (footprint_filename, "w"); if (!fp) { g_log ("", G_LOG_LEVEL_WARNING, (_("could not open file for %s footprint: %s.")), footprint_type, footprint_filename); fclose (fp); return (EXIT_FAILURE); } /* Print a license if requested. */ if (license_in_footprint) { write_license (); } /* 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); } /* Write element header * Guess for a place where to put the refdes text */ x_text = 0.0 ; /* already in mil/100 */ y_text = (ymin - 10000.0); /* already in mil/100 */ write_element_header (x_text, y_text); /* Write pin and/or pad entities */ if (pad_shapes_type == SQUARE) { pin_pad_flags = g_strdup ("square"); } else if (pad_shapes_type == OCTAGONAL) { pin_pad_flags = g_strdup ("octagon"); } else { pin_pad_flags = g_strdup (""); } write_pin ( 2, /* pin number */ "A", /* pin name */ multiplier * ((pitch_x + pad_diameter) / 2.0), /* x0 coordinate */ 0, /* y0-coordinate */ multiplier * pad_diameter, /* width of the annulus ring (pad) */ multiplier * pad_clearance, /* clearance */ multiplier * (pad_diameter + pad_solder_mask_clearance), /* solder mask clearance */ multiplier * pin_drill_diameter, /* pin drill diameter */ pin_pad_flags /* flags */ ); /* Overrule previous settings in favour of pin 1 square setting */ if (pin1_square) { pin_pad_flags = g_strdup ("square"); } write_pin ( 1, /* pin number */ "C", /* pin name */ multiplier * ((-pitch_x - pad_diameter) / 2.0), /* x0 coordinate */ 0, /* y0-coordinate */ multiplier * pad_diameter, /* width of the annulus ring (pad) */ multiplier * pad_clearance, /* clearance */ multiplier * (pad_diameter + pad_solder_mask_clearance), /* solder mask clearance */ multiplier * pin_drill_diameter, /* pin drill diameter */ pin_pad_flags /* flags */ ); if (pad_shapes_type == ROUND_ELONGATED) { /* Add pads on component side */ pin_pad_flags = g_strdup (""); write_pad ( 1, /* pad number */ "C", /* pad name */ multiplier * ((-pitch_x - pad_length + pad_width) / 2.0), /* x0 coordinate */ 0, /* y0-coordinate */ multiplier * ((-pitch_x + pad_length - pad_width) / 2.0), /* x1 coordinate */ 0, /* y1-coordinate */ multiplier * pad_width, /* width of the pad */ multiplier * pad_clearance, /* clearance */ multiplier * (pad_width + (2 * pad_solder_mask_clearance)), /* solder mask clearance */ pin_pad_flags /* flags */ ); write_pad ( 2, /* pad number */ "A", /* pad name */ multiplier * ((pitch_x - pad_length + pad_width) / 2.0), /* x0 coordinate */ 0, /* y0-coordinate */ multiplier * ((pitch_x + pad_length - pad_width) / 2.0), /* x1 coordinate */ 0, /* y1-coordinate */ multiplier * pad_width, /* width of the pad */ multiplier * pad_clearance, /* clearance */ multiplier * ((pad_length > pad_width ? pad_width : pad_length) + (2 * pad_solder_mask_clearance)), /* solder mask clearance */ pin_pad_flags /* flags */ ); /* Add pads on solder side */ pin_pad_flags = g_strdup ("onsolder"); write_pad ( 1, /* pad number */ "C", /* pad name */ multiplier * ((-pitch_x - pad_length + pad_width) / 2.0), /* x0 coordinate */ 0, /* y0-coordinate */ multiplier * ((-pitch_x + pad_length - pad_width) / 2.0), /* x1 coordinate */ 0, /* y1-coordinate */ multiplier * pad_width, /* width of the pad */ multiplier * pad_clearance, /* clearance */ multiplier * (pad_width + (2 * pad_solder_mask_clearance)), /* solder mask clearance */ pin_pad_flags /* flags */ ); write_pad ( 2, /* pad number */ "A", /* pad name */ multiplier * ((pitch_x - pad_length + pad_width) / 2.0), /* x0 coordinate */ 0, /* y0-coordinate */ multiplier * ((pitch_x + pad_length - pad_width) / 2.0), /* x1 coordinate */ 0, /* y1-coordinate */ multiplier * pad_width, /* width of the pad */ multiplier * pad_clearance, /* clearance */ multiplier * ((pad_length > pad_width ? pad_width : pad_length) + (2 * pad_solder_mask_clearance)), /* solder mask clearance */ pin_pad_flags /* flags */ ); } /* Write package body on silkscreen */ if (silkscreen_package_outline) { fprintf (fp, (_("# Write a package body on the silkscreen\n"))); write_rectangle ( multiplier * (-package_body_length / 2.0), multiplier * (-package_body_width / 2.0), multiplier * (package_body_length / 2.0), multiplier * (package_body_width / 2.0), 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) { write_element_line ( multiplier * (package_body_length / 2.0), 0, multiplier * (((pitch_x - pad_diameter - pad_solder_mask_clearance) / 2.0) - silkscreen_line_width), 0, multiplier * silkscreen_line_width ); write_element_line ( multiplier * (-package_body_length / 2.0), 0, multiplier * (((-pitch_x + pad_diameter + pad_solder_mask_clearance) / 2.0) + silkscreen_line_width), 0, multiplier * silkscreen_line_width ); } } /* Write 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) { write_element_line ( multiplier * ((-package_body_length / 2.0) + dx), multiplier * (package_body_width / 2.0) , multiplier * ((-package_body_length / 2.0) + dx), multiplier * (-package_body_width / 2.0), multiplier * silkscreen_line_width ); } } /* Write a courtyard on the silkscreen */ if (courtyard) { fprintf (fp, (_("# Write a courtyard on the silkscreen\n"))); write_rectangle ( xmin, /* already in mil/100 */ ymin, /* already in mil/100 */ xmax, /* already in mil/100 */ ymax, /* already in mil/100 */ multiplier * courtyard_line_width ); } /* Write attributes to the footprint file. */ if (attributes_in_footprint) { write_attributes (); } /* Finishing touch. */ fprintf (fp, "\n"); fprintf (fp, ")\n"); fclose (fp); /* We are ready creating a footprint. */ if (verbose) { g_log ("", G_LOG_LEVEL_INFO, (_("wrote a footprint for a %s package: %s.")), footprint_type, footprint_filename); } return (EXIT_SUCCESS); }
/*! * \brief Write a footprint for a PGA package. * * \return \c EXIT_FAILURE when errors were encountered, * \c EXIT_SUCCESS when OK. */ int pga_write_footprint () { 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 (""); gchar *pin_pad_flags = g_strdup (""); gint i; gint j; /* Attempt to open a file with write permission. */ fp = fopen (footprint_filename, "w"); if (!fp) { g_log ("", G_LOG_LEVEL_WARNING, _("could not open file for %s footprint: %s."), footprint_type, footprint_filename); fclose (fp); return (EXIT_FAILURE); } /* Print a license if requested. */ if (license_in_footprint) { write_license (); } /* Determine (extreme) courtyard dimensions based on pin/pad * properties */ xmin = multiplier * ( ((-pitch_x * number_of_columns) / 2.0) - (pad_diameter / 2.0) - pad_solder_mask_clearance ); xmax = multiplier * ( ((pitch_x * number_of_columns) / 2.0) + (pad_diameter / 2.0) + pad_solder_mask_clearance ); ymin = multiplier * ( ((-pitch_y * number_of_rows) / 2.0) - (pad_diameter / 2.0) - pad_solder_mask_clearance ); ymax = multiplier * ( ((pitch_y * number_of_rows) / 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); /* Write element header * Guess for a place where to put the refdes text */ x_text = 0.0 ; /* already in mil/100 */ y_text = (ymin - 10000.0); /* already in mil/100 */ write_element_header (x_text, y_text); /* Write pin and/or pad entities */ 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)) pin_pad_flags = g_strdup ("square"); else pin_pad_flags = g_strdup (""); pin_pad_name = g_strdup_printf ("%s%d", (row_letters[i]), (j + 1)); if (get_pin_pad_exception (pin_pad_name)) { write_pin ( pin_number, /* pin number */ pin_pad_name, /* pin name */ multiplier * ((((- number_of_columns -1) / 2.0) + 1 + j) * pitch_x), /* x0 coordinate */ multiplier * ((((-number_of_rows - 1) / 2.0) + 1 + i) * pitch_y), /* y0-coordinate */ multiplier * pad_diameter, /* width of the annulus ring (pad) */ multiplier * pad_clearance, /* clearance */ multiplier * (pad_diameter + pad_solder_mask_clearance), /* solder mask clearance */ multiplier * pin_drill_diameter, /* pin drill diameter */ pin_pad_flags /* flags */ ); } pin_number++; } } /* Write a package body on the silkscreen */ if (silkscreen_package_outline) { fprintf (fp, "# Write a package body on the silkscreen\n"); write_rectangle ( multiplier * (-package_body_length / 2.0), multiplier * (-package_body_width / 2.0), multiplier * (package_body_length / 2.0), multiplier * (package_body_width / 2.0), multiplier * silkscreen_line_width ); } /* Write 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) { write_element_line ( multiplier * (-package_body_length / 2.0), multiplier * ((-package_body_width / 2.0) + dx), multiplier * ((-package_body_length / 2.0) + dx), multiplier * (-package_body_width / 2.0), multiplier * (silkscreen_line_width) ); } } /* Write a courtyard on the silkscreen */ if (courtyard) { fprintf (fp, "# Write a courtyard on the silkscreen\n"); write_rectangle ( xmin, /* already in mil/100 */ ymin, /* already in mil/100 */ xmax, /* already in mil/100 */ ymax, /* already in mil/100 */ multiplier * courtyard_line_width ); } /* Write attributes to the footprint file. */ if (attributes_in_footprint) { write_attributes (); } /* Finishing touch. */ fprintf (fp, "\n"); fprintf (fp, ")\n"); fclose (fp); /* We are ready creating a footprint. */ if (verbose) { g_log ("", G_LOG_LEVEL_INFO, _("wrote a footprint for a %s package: %s."), footprint_type, footprint_filename); } return (EXIT_SUCCESS); }
/*! * \brief Write a footprint with two pads for a RESM package. * * \return \c EXIT_FAILURE when errors were encountered, * \c EXIT_SUCCESS when OK. */ int resm_write_footprint () { gdouble xmax; gdouble xmin; gdouble ymax; gdouble ymin; gdouble x_text; gdouble y_text; gchar *pin_pad_flags = g_strdup (""); /* Attempt to open a file with write permission. */ fp = fopen (footprint_filename, "w"); if (!fp) { if (verbose) { g_log ("", G_LOG_LEVEL_WARNING, _("could not open file for %s footprint: %s."), footprint_type, footprint_filename); } fclose (fp); return (EXIT_FAILURE); } /* Print a license if requested. */ if (license_in_footprint) { write_license (); } /* 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); } /* Write element header * Guess for a place where to put the refdes text */ x_text = 0.0 ; /* already in mil/100 */ y_text = (ymin - 10000.0); /* already in mil/100 */ write_element_header (x_text, y_text); /* Write pin and/or pad entities */ if (!strcmp (pad_shape, "rectangular pad")) { pin_pad_flags = g_strdup ("square"); } if (pad_length > pad_width) /* Write pads parallel to x-axis */ { /* Pad #1 */ write_pad ( 1, /* pad number */ "", /* pad name */ multiplier * ((-pitch_x - pad_length + pad_width) / 2.0), /* x0 coordinate */ 0, /* y0-coordinate */ multiplier * ((-pitch_x + pad_length - pad_width) / 2.0), /* x1 coordinate */ 0, /* y1-coordinate */ multiplier * pad_width, /* width of the pad */ multiplier * pad_clearance, /* clearance */ multiplier * (pad_width + (2 * pad_solder_mask_clearance)), /* solder mask clearance */ /* Write pin #1 with a square pad if checked */ (pin1_square) ? "square" : pin_pad_flags /* flags */ ); /* Pad #2 */ write_pad ( 2, /* pad number */ "", /* pad name */ multiplier * ((pitch_x - pad_length + pad_width) / 2.0), /* x0 coordinate */ 0, /* y0-coordinate */ multiplier * ((pitch_x + pad_length - pad_width) / 2.0), /* x1 coordinate */ 0, /* y1-coordinate */ multiplier * pad_width, /* width of the pad */ multiplier * pad_clearance, /* clearance */ multiplier * (pad_width + (2 * pad_solder_mask_clearance)), /* solder mask clearance */ pin_pad_flags /* flags */ ); } else /* write pads perpendiclar to x-axis */ { /* Pad #1 */ write_pad ( 1, /* pad number */ "", /* pad name */ multiplier * (-pitch_x / 2.0), /* x0-coordinate */ multiplier * ((pad_width - pad_length) / 2.0), /* y0-coordinate */ multiplier * (-pitch_x / 2), /* x1-coordinate */ multiplier * ((-pad_width + pad_length) / 2.0), /* y1-coordinate */ multiplier * pad_length, /* width of the pad */ multiplier * pad_clearance, /* clearance */ multiplier * (pad_length + (2 * pad_solder_mask_clearance)), /* solder mask clearance */ /* Write pin #1 with a square pad if checked */ (pin1_square) ? "square" : pin_pad_flags /* flags */ ); /* Pad #2 */ write_pad ( 2, /* pad number */ "", /* pad name */ multiplier * (pitch_x / 2.0), /* x0-coordinate */ multiplier * ((pad_width - pad_length) / 2.0), /* y0-coordinate */ multiplier * (pitch_x / 2.0), /* x1-coordinate */ multiplier * ((-pad_width + pad_length) / 2.0), /* y1-coordinate */ multiplier * pad_length, /* width of the pad */ multiplier * pad_clearance, /* clearance */ multiplier * (pad_length + (2 * pad_solder_mask_clearance)), /* solder mask clearance */ pin_pad_flags /* flags */ ); } /* Write a package body on the silkscreen */ if (silkscreen_package_outline && package_body_width) { fprintf (fp, "# Write a package body on the silkscreen\n"); if (pad_width >= package_body_width) { write_element_line ( multiplier * (((-pitch_x + pad_length) / 2.0) + pad_solder_mask_clearance + silkscreen_line_width), multiplier * (package_body_width / 2.0), multiplier * (((pitch_x - pad_length) / 2.0) - pad_solder_mask_clearance - silkscreen_line_width), multiplier * (package_body_width / 2.0), multiplier * silkscreen_line_width ); write_element_line ( multiplier * (((-pitch_x + pad_length) / 2.0) + pad_solder_mask_clearance + silkscreen_line_width), multiplier * (-package_body_width / 2.0), multiplier * (((pitch_x - pad_length) / 2.0) - pad_solder_mask_clearance - silkscreen_line_width), multiplier * (-package_body_width / 2.0), multiplier * silkscreen_line_width ); } else { /* lines parallel to X-axis */ write_element_line ( multiplier * (-package_body_length / 2.0), multiplier * (package_body_width / 2.0), multiplier * (package_body_length / 2.0), multiplier * (package_body_width / 2.0), multiplier * silkscreen_line_width ); write_element_line ( multiplier * (-package_body_length / 2.0), multiplier * (-package_body_width / 2.0), multiplier * (package_body_length / 2.0), multiplier * (-package_body_width / 2.0), multiplier * silkscreen_line_width ); /* lines perpendicular to X-axis */ write_element_line ( multiplier * (-package_body_length / 2.0), multiplier * (-package_body_width / 2.0), multiplier * (-package_body_length / 2.0), multiplier * (((-pad_width - silkscreen_line_width) / 2.0) - pad_solder_mask_clearance), multiplier * silkscreen_line_width ); write_element_line ( multiplier * (-package_body_length / 2.0), multiplier * (package_body_width / 2.0), multiplier * (-package_body_length / 2.0), multiplier * (((pad_width + silkscreen_line_width) / 2.0) + pad_solder_mask_clearance), multiplier * silkscreen_line_width ); write_element_line ( multiplier * (package_body_length / 2.0), multiplier * (-package_body_width / 2.0), multiplier * (package_body_length / 2.0), multiplier * (((-pad_width - silkscreen_line_width) / 2.0) - pad_solder_mask_clearance), multiplier * silkscreen_line_width ); write_element_line ( multiplier * (package_body_length / 2.0), multiplier * (package_body_width / 2.0), multiplier * (package_body_length / 2.0), multiplier * (((pad_width + silkscreen_line_width) / 2.0) + pad_solder_mask_clearance), multiplier * silkscreen_line_width ); } } /* Write a pin #1 marker on the silkscreen */ if (silkscreen_indicate_1) { fprintf (fp, "# Write a pin 1 marker on the silkscreen\n"); if (pad_width >= package_body_width) { write_element_line ( multiplier * (((-pitch_x + pad_length) / 2.0) + pad_solder_mask_clearance + silkscreen_line_width), multiplier * (-package_body_width / 2.0), multiplier * (((-pitch_x + pad_length) / 2.0) + pad_solder_mask_clearance + silkscreen_line_width), multiplier * (package_body_width / 2.0), multiplier * silkscreen_line_width ); } else { write_element_arc ( multiplier * (((-package_body_length) / 2.0) - 2 * silkscreen_line_width), multiplier * (-package_body_width / 2.0), multiplier * 0.5 * silkscreen_line_width, multiplier * 0.5 * silkscreen_line_width, 0, 360, multiplier * silkscreen_line_width ); } } /* Write a courtyard on the silkscreen */ if (courtyard) { fprintf (fp, "# Write a courtyard on the silkscreen\n"); write_rectangle ( xmin, /* already in mil/100 */ ymin, /* already in mil/100 */ xmax, /* already in mil/100 */ ymax, /* already in mil/100 */ multiplier * courtyard_line_width ); } /* Write attributes to the footprint file. */ if (attributes_in_footprint) { write_attributes (); } /* Finishing touch. */ fprintf (fp, "\n"); fprintf (fp, ")\n"); fclose (fp); /* We are ready creating a footprint. */ if (verbose) { g_log ("", G_LOG_LEVEL_INFO, _("wrote a footprint for a %s package: %s."), footprint_type, footprint_filename); } return (EXIT_SUCCESS); }
bool ImageOutput::write_image (TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride, ProgressCallback progress_callback, void *progress_callback_data) { bool native = (format == TypeDesc::UNKNOWN); stride_t pixel_bytes = (stride_t) m_spec.pixel_bytes (native); if (native && xstride == AutoStride) xstride = pixel_bytes; m_spec.auto_stride (xstride, ystride, zstride, format, m_spec.nchannels, m_spec.width, m_spec.height); if (supports ("rectangles")) { // Use a rectangle if we can return write_rectangle (0, m_spec.width-1, 0, m_spec.height-1, 0, m_spec.depth-1, format, data, xstride, ystride, zstride); } bool ok = true; if (progress_callback) if (progress_callback (progress_callback_data, 0.0f)) return ok; if (m_spec.tile_width && supports ("tiles")) { // Tiled image // FIXME: what happens if the image dimensions are smaller than // the tile dimensions? Or if one of the tiles runs past the // right or bottom edge? Do we need to allocate a full tile and // copy into it before calling write_tile? That's probably the // safe thing to do. Or should that handling be pushed all the // way into write_tile itself? // Locally allocate a single tile to gracefully deal with image // dimensions smaller than a tile, or if one of the tiles runs // past the right or bottom edge. Then we copy from our tile to // the user data, only copying valid pixel ranges. size_t tilexstride = pixel_bytes; size_t tileystride = tilexstride * m_spec.tile_width; size_t tilezstride = tileystride * m_spec.tile_height; size_t tile_pixels = (size_t)m_spec.tile_width * (size_t)m_spec.tile_height * (size_t)std::max(1,m_spec.tile_depth); std::vector<char> pels (tile_pixels * pixel_bytes); for (int z = 0; z < m_spec.depth; z += m_spec.tile_depth) for (int y = 0; y < m_spec.height; y += m_spec.tile_height) { for (int x = 0; x < m_spec.width && ok; x += m_spec.tile_width) { // Now copy out the scanlines // FIXME -- can we do less work for the tiles that // don't overlap image boundaries? int ntz = std::min (z+m_spec.tile_depth, m_spec.depth) - z; int nty = std::min (y+m_spec.tile_height, m_spec.height) - y; int ntx = std::min (x+m_spec.tile_width, m_spec.width) - x; for (int tz = 0; tz < ntz; ++tz) { for (int ty = 0; ty < nty; ++ty) { // FIXME -- doesn't work for non-contiguous scanlines memcpy (&pels[ty*tileystride+tz*tilezstride], (char *)data + x*xstride + (y+ty)*ystride + (z+tz)*zstride, ntx*tilexstride); } } ok &= write_tile (x+m_spec.x, y+m_spec.y, z+m_spec.z, format, &pels[0]); } if (progress_callback) if (progress_callback (progress_callback_data, (float)y/m_spec.height)) return ok; } } else { // Scanline image for (int z = 0; z < m_spec.depth; ++z) for (int y = 0; y < m_spec.height && ok; ++y) { ok &= write_scanline (y+m_spec.y, z+m_spec.z, format, (const char *)data + z*zstride + y*ystride, xstride); if (progress_callback && !(y & 0x0f)) if (progress_callback (progress_callback_data, (float)y/m_spec.height)) return ok; } } if (progress_callback) progress_callback (progress_callback_data, 1.0f); return ok; }