mirror of https://github.com/KLayout/klayout.git
Fixed #29 (permissive mode for OASIS writer on odd-width paths)
This commit adds "permissive" mode to OASIS writer to allow odd-width paths (which are rounded). This commit contains in addition: * The check for odd-width paths is done post-scaling, so reducing the DBU is a workaround * Unit tests for the RBA binding of SaveLayoutOptions * Documentation updates on some SaveLayoutOptions attributes * Using Ruby predicate notation for cif_blank_separator? (note question mark) for consistency. The old notation is still there but deprecated * --permissive option on buddies command lines where applicable
This commit is contained in:
parent
c1e501197c
commit
be80682853
|
|
@ -189,6 +189,11 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
|
|||
"With this option, shape arrays will be expanded and recompressed. This may result in a better "
|
||||
"compression ratio, but at the cost of slower execution."
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"#--permissive", &m_oasis_writer_options.permissive, "Permissive mode",
|
||||
"In permissive mode, certain forbidden objects are reported as warnings, not as errors: "
|
||||
"paths with odd width, polygons with less than three points etc."
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"#--write-std-properties", &m_oasis_writer_options.write_std_properties, "Writes some global standard properties",
|
||||
"This is an integer describing what standard properties shall be written. 0 is \"none\", "
|
||||
|
|
|
|||
|
|
@ -2362,7 +2362,13 @@ OASISWriter::write (const db::SimplePolygon &polygon, db::properties_id_type pro
|
|||
}
|
||||
|
||||
if (m_pointlist.size () < 2) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Polygons with less than three points cannot be written to OASIS files (cell ")) + mp_layout->cell_name (mp_cell->cell_index ()) + tl::to_string (QObject::tr (", position ")) + tl::to_string (start.x ()) + ", " + tl::to_string (start.y ()) + " DBU)");
|
||||
std::string msg = tl::to_string (QObject::tr ("Polygons with less than three points cannot be written to OASIS files (cell ")) + mp_layout->cell_name (mp_cell->cell_index ()) + tl::to_string (QObject::tr (", position ")) + tl::to_string (start.x ()) + ", " + tl::to_string (start.y ()) + " DBU)";
|
||||
if (m_options.permissive) {
|
||||
tl::warn << msg;
|
||||
return;
|
||||
} else {
|
||||
throw tl::Exception (msg);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char info = 0x00;
|
||||
|
|
@ -2457,7 +2463,13 @@ OASISWriter::write (const db::Polygon &polygon, db::properties_id_type prop_id,
|
|||
}
|
||||
|
||||
if (m_pointlist.size () < 2) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Polygons with less than three points cannot be written to OASIS files (cell ")) + mp_layout->cell_name (mp_cell->cell_index ()) + tl::to_string (QObject::tr (", position ")) + tl::to_string (start.x ()) + ", " + tl::to_string (start.y ()) + " DBU)");
|
||||
std::string msg = tl::to_string (QObject::tr ("Polygons with less than three points cannot be written to OASIS files (cell ")) + mp_layout->cell_name (mp_cell->cell_index ()) + tl::to_string (QObject::tr (", position ")) + tl::to_string (start.x ()) + ", " + tl::to_string (start.y ()) + " DBU)";
|
||||
if (m_options.permissive) {
|
||||
tl::warn << msg;
|
||||
return;
|
||||
} else {
|
||||
throw tl::Exception (msg);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char info = 0x00;
|
||||
|
|
@ -2594,6 +2606,8 @@ OASISWriter::write (const db::Box &box, db::properties_id_type prop_id, const db
|
|||
void
|
||||
OASISWriter::write (const db::Path &path, db::properties_id_type prop_id, const db::Repetition &rep)
|
||||
{
|
||||
typedef db::coord_traits<db::Coord>::distance_type ucoord;
|
||||
|
||||
// don't write empty paths
|
||||
if (path.begin () == path.end ()) {
|
||||
return;
|
||||
|
|
@ -2605,6 +2619,9 @@ OASISWriter::write (const db::Path &path, db::properties_id_type prop_id, const
|
|||
// for round paths, circles are placed to mimic the extensions
|
||||
if (! path.round ()) {
|
||||
ext = path.extensions ();
|
||||
// Because we scale the width already, we also need to scale the extensions for comparing them
|
||||
ext.first = safe_scale (m_sf, ext.first);
|
||||
ext.second = safe_scale (m_sf, ext.second);
|
||||
}
|
||||
|
||||
db::Path::iterator e = path.begin ();
|
||||
|
|
@ -2615,15 +2632,21 @@ OASISWriter::write (const db::Path &path, db::properties_id_type prop_id, const
|
|||
m_pointlist.push_back (*e - start);
|
||||
}
|
||||
|
||||
db::Coord hw = path.width () / 2;
|
||||
if (hw * 2 != path.width ()) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Paths with odd width cannot be written to OASIS files (cell ")) + mp_layout->cell_name (mp_cell->cell_index ()) + tl::to_string (QObject::tr (", position ")) + tl::to_string (start.x ()) + ", " + tl::to_string (start.y ()) + " DBU)");
|
||||
}
|
||||
|
||||
if (m_pointlist.empty ()) {
|
||||
|
||||
if (path.round ()) {
|
||||
|
||||
db::Coord w = safe_scale (m_sf, path.width ());
|
||||
db::Coord hw = w / 2;
|
||||
if (hw * 2 != w) {
|
||||
std::string msg = tl::to_string (QObject::tr ("Circles with odd diameter cannot be written to OASIS files (cell ")) + mp_layout->cell_name (mp_cell->cell_index ()) + tl::to_string (QObject::tr (", position ")) + tl::to_string (start.x ()) + ", " + tl::to_string (start.y ()) + " DBU)";
|
||||
if (m_options.permissive) {
|
||||
tl::warn << msg << " - " << tl::to_string (QObject::tr ("circle diameter is rounded"));
|
||||
} else {
|
||||
throw tl::Exception (msg);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char info = 0;
|
||||
if (mm_layer != m_layer) {
|
||||
info |= 0x01;
|
||||
|
|
@ -2658,7 +2681,8 @@ OASISWriter::write (const db::Path &path, db::properties_id_type prop_id, const
|
|||
}
|
||||
if (info & 0x20) {
|
||||
mm_circle_radius = hw;
|
||||
write_ucoord (hw);
|
||||
// NOTE: the radius has already been scaled, so we don't use write_ucoord here
|
||||
write ((ucoord) hw);
|
||||
}
|
||||
if (info & 0x10) {
|
||||
mm_geometry_x = start.x ();
|
||||
|
|
@ -2678,17 +2702,25 @@ OASISWriter::write (const db::Path &path, db::properties_id_type prop_id, const
|
|||
}
|
||||
|
||||
} else {
|
||||
// Single-point paths are translated into polygons
|
||||
write (path.polygon (), prop_id, rep);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
db::Point end = start + m_pointlist.back ();
|
||||
|
||||
if (m_pointlist.size () < 1) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Paths with less than two points cannot be written to OASIS files (cell ")) + mp_layout->cell_name (mp_cell->cell_index ()) + tl::to_string (QObject::tr (", position ")) + tl::to_string (start.x ()) + ", " + tl::to_string (start.y ()) + " DBU)");
|
||||
db::Coord w = safe_scale (m_sf, path.width ());
|
||||
db::Coord hw = w / 2;
|
||||
if (hw * 2 != w) {
|
||||
std::string msg = tl::to_string (QObject::tr ("Paths with odd width cannot be written to OASIS files (cell ")) + mp_layout->cell_name (mp_cell->cell_index ()) + tl::to_string (QObject::tr (", position ")) + tl::to_string (start.x ()) + ", " + tl::to_string (start.y ()) + " DBU)";
|
||||
if (m_options.permissive) {
|
||||
tl::warn << msg << " - " << tl::to_string (QObject::tr ("path diameter is rounded"));
|
||||
} else {
|
||||
throw tl::Exception (msg);
|
||||
}
|
||||
}
|
||||
|
||||
db::Point end = start + m_pointlist.back ();
|
||||
|
||||
unsigned char info = 0x00;
|
||||
|
||||
if (mm_layer != m_layer) {
|
||||
|
|
@ -2730,7 +2762,8 @@ OASISWriter::write (const db::Path &path, db::properties_id_type prop_id, const
|
|||
}
|
||||
if (info & 0x40) {
|
||||
mm_path_halfwidth = hw;
|
||||
write_ucoord (hw);
|
||||
// NOTE: the half-width has already been scaled, so we don't use write_ucoord here
|
||||
write ((ucoord) hw);
|
||||
}
|
||||
|
||||
if (info & 0x80) {
|
||||
|
|
@ -2758,10 +2791,12 @@ OASISWriter::write (const db::Path &path, db::properties_id_type prop_id, const
|
|||
write_byte (ext_scheme);
|
||||
|
||||
if ((ext_scheme & 0x0c) == 0x0c) {
|
||||
write_coord (ext.first);
|
||||
// NOTE: ext.first is already scaled, so we don't use write_coord
|
||||
write (ext.first);
|
||||
}
|
||||
if ((ext_scheme & 0x03) == 0x03) {
|
||||
write_coord (ext.second);
|
||||
// NOTE: ext.second is already scaled, so we don't use write_coord
|
||||
write (ext.second);
|
||||
}
|
||||
|
||||
mm_path_start_extension = ext.first;
|
||||
|
|
@ -2814,7 +2849,8 @@ OASISWriter::write (const db::Path &path, db::properties_id_type prop_id, const
|
|||
|
||||
if (info & 0x20) {
|
||||
mm_circle_radius = hw;
|
||||
write_ucoord (hw);
|
||||
// NOTE: the half-width has already been scaled, so we don't use write_ucoord here
|
||||
write ((ucoord) hw);
|
||||
}
|
||||
if (info & 0x10) {
|
||||
mm_geometry_x = start.x ();
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public:
|
|||
* @brief The constructor
|
||||
*/
|
||||
OASISWriterOptions ()
|
||||
: compression_level (2), write_cblocks (false), strict_mode (false), recompress (false), write_std_properties (1), subst_char ("*")
|
||||
: compression_level (2), write_cblocks (false), strict_mode (false), recompress (false), permissive (false), write_std_properties (1), subst_char ("*")
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -95,6 +95,16 @@ public:
|
|||
*/
|
||||
bool recompress;
|
||||
|
||||
/**
|
||||
* @brief Permissive mode
|
||||
*
|
||||
* In permissive mode, a warning is issued for certain cases rather than
|
||||
* an error:
|
||||
* - Polygons with less than three points (omitted)
|
||||
* - Paths/circles with odd diameter (rounded)
|
||||
*/
|
||||
bool permissive;
|
||||
|
||||
/**
|
||||
* @brief Write global standard properties
|
||||
*
|
||||
|
|
|
|||
|
|
@ -74,86 +74,29 @@
|
|||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="2" colspan="3">
|
||||
<widget class="QCheckBox" name="write_cblocks">
|
||||
<property name="text">
|
||||
<string>Use CBLOCK compression for each cell (RFC1951)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Strict mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="3">
|
||||
<widget class="QSlider" name="compression_slider">
|
||||
<item row="4" column="2" colspan="3">
|
||||
<widget class="QComboBox" name="std_prop_mode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(high) 10</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0 (low)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Compaction level
|
||||
(repetition detection)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>No standard properties</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Global standard properties</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Global + per-cell bounding boxes</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2" colspan="3">
|
||||
|
|
@ -163,40 +106,10 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>CBLOCK compression</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Substitution character</string>
|
||||
<string>Strict mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -263,29 +176,130 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2" colspan="3">
|
||||
<widget class="QComboBox" name="std_prop_mode">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Substitution character</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>No standard properties</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Global standard properties</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Global + per-cell bounding boxes</string>
|
||||
</property>
|
||||
</item>
|
||||
<property name="text">
|
||||
<string>0 (low)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="3">
|
||||
<widget class="QSlider" name="compression_slider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>CBLOCK compression</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Compaction level
|
||||
(repetition detection)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="3">
|
||||
<widget class="QCheckBox" name="write_cblocks">
|
||||
<property name="text">
|
||||
<string>Use CBLOCK compression for each cell (RFC1951)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(high) 10</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2" colspan="3">
|
||||
<widget class="QCheckBox" name="permissive">
|
||||
<property name="text">
|
||||
<string>Don't fail on paths with odd width and other odd shapes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Permissive mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
|||
|
|
@ -138,10 +138,11 @@ gsi::ClassExt<db::SaveLayoutOptions> cif_writer_options (
|
|||
"This option is useful for enhanced compatibility with other tools.\n"
|
||||
"\nThis property has been added in version 0.23.10.\n"
|
||||
) +
|
||||
gsi::method_ext ("cif_dummy_calls", &get_cif_dummy_calls,
|
||||
gsi::method_ext ("cif_dummy_calls?|#cif_dummy_calls", &get_cif_dummy_calls,
|
||||
"@brief Gets a flag indicating whether dummy calls shall be written\n"
|
||||
"See \\cif_dummy_calls= method for a description of that property."
|
||||
"\nThis property has been added in version 0.23.10.\n"
|
||||
"\nThe predicate version (cif_blank_separator?) has been added in version 0.25.1.\n"
|
||||
) +
|
||||
gsi::method_ext ("cif_blank_separator=", &set_cif_blank_separator,
|
||||
"@brief Sets a flag indicating whether blanks shall be used as x/y separator characters\n"
|
||||
|
|
@ -149,10 +150,11 @@ gsi::ClassExt<db::SaveLayoutOptions> cif_writer_options (
|
|||
"rather than comma characters."
|
||||
"\nThis property has been added in version 0.23.10.\n"
|
||||
) +
|
||||
gsi::method_ext ("cif_blank_separator", &get_cif_blank_separator,
|
||||
gsi::method_ext ("cif_blank_separator?|#cif_blank_separator", &get_cif_blank_separator,
|
||||
"@brief Gets a flag indicating whether blanks shall be used as x/y separator characters\n"
|
||||
"See \\cif_blank_separator= method for a description of that property."
|
||||
"\nThis property has been added in version 0.23.10.\n"
|
||||
"\nThe predicate version (cif_blank_separator?) has been added in version 0.25.1.\n"
|
||||
),
|
||||
""
|
||||
);
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ OASISWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const la
|
|||
mp_ui->strict_mode->setChecked (options->strict_mode);
|
||||
mp_ui->std_prop_mode->setCurrentIndex (options->write_std_properties);
|
||||
mp_ui->subst_char->setText (tl::to_qstring (options->subst_char));
|
||||
mp_ui->permissive->setChecked (options->permissive);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,6 +95,7 @@ OASISWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const lay::Te
|
|||
options->strict_mode = mp_ui->strict_mode->isChecked ();
|
||||
options->write_std_properties = mp_ui->std_prop_mode->currentIndex ();
|
||||
options->subst_char = tl::to_string (mp_ui->subst_char->text ());
|
||||
options->permissive = mp_ui->permissive->isChecked ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +129,8 @@ public:
|
|||
tl::make_member (&db::OASISWriterOptions::write_cblocks, "write-cblocks") +
|
||||
tl::make_member (&db::OASISWriterOptions::strict_mode, "strict-mode") +
|
||||
tl::make_member (&db::OASISWriterOptions::write_std_properties, "write-std-properties") +
|
||||
tl::make_member (&db::OASISWriterOptions::subst_char, "subst-char")
|
||||
tl::make_member (&db::OASISWriterOptions::subst_char, "subst-char") +
|
||||
tl::make_member (&db::OASISWriterOptions::permissive, "permissive")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
@ -157,6 +160,16 @@ static bool get_oasis_recompress (const db::SaveLayoutOptions *options)
|
|||
return options->get_options<db::OASISWriterOptions> ().recompress;
|
||||
}
|
||||
|
||||
static void set_oasis_permissive (db::SaveLayoutOptions *options, bool f)
|
||||
{
|
||||
options->get_options<db::OASISWriterOptions> ().permissive = f;
|
||||
}
|
||||
|
||||
static bool get_oasis_permissive (const db::SaveLayoutOptions *options)
|
||||
{
|
||||
return options->get_options<db::OASISWriterOptions> ().permissive;
|
||||
}
|
||||
|
||||
static void set_oasis_write_std_properties (db::SaveLayoutOptions *options, bool f)
|
||||
{
|
||||
db::OASISWriterOptions &oasis_options = options->get_options<db::OASISWriterOptions> ();
|
||||
|
|
@ -251,22 +264,34 @@ gsi::ClassExt<db::SaveLayoutOptions> oasis_writer_options (
|
|||
"See \\oasis_substitution_char for details. This attribute has been introduced in version 0.23.\n"
|
||||
) +
|
||||
gsi::method_ext ("oasis_recompress=", &set_oasis_recompress,
|
||||
"@brief Set OASIS recompression mode\n"
|
||||
"@brief Sets OASIS recompression mode\n"
|
||||
"@args flag\n"
|
||||
"If this flag is true, shape arrays already existing will be resolved and compression is applied "
|
||||
"to the individual shapes again. If this flag is false (the default), shape arrays already existing "
|
||||
"will be written as such.\n"
|
||||
"\n"
|
||||
"Setting this property clears all format specific options for other formats such as GDS.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23."
|
||||
) +
|
||||
gsi::method_ext ("oasis_recompress?", &get_oasis_recompress,
|
||||
"@brief Get the OASIS recompression mode\n"
|
||||
"See \\oasis_recompression= method for a description of the OASIS compression level."
|
||||
"@brief Gets the OASIS recompression mode\n"
|
||||
"See \\oasis_recompress= method for a description of this predicate."
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23."
|
||||
) +
|
||||
gsi::method_ext ("oasis_permissive=", &set_oasis_permissive,
|
||||
"@brief Sets OASIS permissive mode\n"
|
||||
"@args flag\n"
|
||||
"If this flag is true, certain shapes which cannot be written to OASIS are reported as warnings, "
|
||||
"not as errors. For example, paths with odd width (are rounded) or polygons with less than three points (are skipped).\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25.1."
|
||||
) +
|
||||
gsi::method_ext ("oasis_permissive?", &get_oasis_permissive,
|
||||
"@brief Gets the OASIS permissive mode\n"
|
||||
"See \\oasis_permissive= method for a description of this predicate."
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25.1."
|
||||
) +
|
||||
gsi::method_ext ("oasis_write_cell_bounding_boxes=", &set_oasis_write_cell_bounding_boxes,
|
||||
"@brief Sets a value indicating whether cell bounding boxes are written\n"
|
||||
"@args flag\n"
|
||||
|
|
@ -277,8 +302,6 @@ gsi::ClassExt<db::SaveLayoutOptions> oasis_writer_options (
|
|||
"S_TOP_CELL (see \\oasis_write_std_properties=).\n"
|
||||
"By default, cell bounding boxes are not written, but standard properties are.\n"
|
||||
"\n"
|
||||
"Setting this property clears all format specific options for other formats such as GDS.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.24.3."
|
||||
) +
|
||||
gsi::method_ext ("oasis_write_cell_bounding_boxes?", &get_oasis_write_cell_bounding_boxes,
|
||||
|
|
@ -296,7 +319,6 @@ gsi::ClassExt<db::SaveLayoutOptions> oasis_writer_options (
|
|||
"\n"
|
||||
"By default, this flag is true and standard properties are written.\n"
|
||||
"\n"
|
||||
"Setting this property clears all format specific options for other formats such as GDS.\n"
|
||||
"Setting this property to false clears the oasis_write_cell_bounding_boxes flag too.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.24."
|
||||
|
|
@ -314,7 +336,6 @@ gsi::ClassExt<db::SaveLayoutOptions> oasis_writer_options (
|
|||
"1 produces shape arrays in a simple fashion. 2 and higher compression levels will use a more elaborate "
|
||||
"algorithm to find shape arrays which uses 2nd and futher neighbor distances. The higher the level, the "
|
||||
"higher the memory requirements and run times.\n"
|
||||
"Setting this property clears all format specific options for other formats such as GDS.\n"
|
||||
) +
|
||||
gsi::method_ext ("oasis_compression_level", &get_oasis_compression,
|
||||
"@brief Get the OASIS compression level\n"
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ RUBYTEST (layMarkers, "layMarkers.rb")
|
|||
RUBYTEST (layMenuTest, "layMenuTest.rb")
|
||||
RUBYTEST (laySession, "laySession.rb")
|
||||
RUBYTEST (layTechnologies, "layTechnologies.rb")
|
||||
RUBYTEST (laySaveLayoutOptions, "laySaveLayoutOptions.rb")
|
||||
#if defined(HAVE_QTBINDINGS)
|
||||
RUBYTEST (qtbinding, "qtbinding.rb")
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,170 @@
|
|||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
if !$:.member?(File::dirname($0))
|
||||
$:.push(File::dirname($0))
|
||||
end
|
||||
|
||||
load("test_prologue.rb")
|
||||
|
||||
class SaveLayoutOptions_TestClass < TestBase
|
||||
|
||||
# SaveLayoutOptions tests
|
||||
def test_1
|
||||
|
||||
opt = RBA::SaveLayoutOptions::new
|
||||
|
||||
# just smoke test - no query methods, so we can't check the results
|
||||
opt.add_cell(1)
|
||||
opt.add_this_cell(1)
|
||||
opt.add_layer(1, RBA::LayerInfo::new(17, 5))
|
||||
opt.clear_cells
|
||||
opt.deselect_all_layers
|
||||
opt.select_cell(1)
|
||||
opt.select_this_cell(1)
|
||||
opt.select_all_cells
|
||||
opt.select_all_layers
|
||||
|
||||
|
||||
opt.dbu = 0.5
|
||||
assert_equal(opt.dbu, 0.5)
|
||||
|
||||
opt.scale_factor = 1.5
|
||||
assert_equal(opt.scale_factor, 1.5)
|
||||
|
||||
opt.keep_instances = false
|
||||
assert_equal(opt.keep_instances?, false)
|
||||
opt.keep_instances = true
|
||||
assert_equal(opt.keep_instances?, true)
|
||||
|
||||
opt.write_context_info = false
|
||||
assert_equal(opt.write_context_info?, false)
|
||||
opt.write_context_info = true
|
||||
assert_equal(opt.write_context_info?, true)
|
||||
|
||||
opt.no_empty_cells = false
|
||||
assert_equal(opt.no_empty_cells?, false)
|
||||
opt.no_empty_cells = true
|
||||
assert_equal(opt.no_empty_cells?, true)
|
||||
|
||||
opt.format = "CIF"
|
||||
assert_equal(opt.format, "CIF")
|
||||
opt.format = "DXF"
|
||||
assert_equal(opt.format, "DXF")
|
||||
|
||||
opt.cif_blank_separator = true
|
||||
assert_equal(opt.cif_blank_separator?, true)
|
||||
opt.cif_blank_separator = false
|
||||
assert_equal(opt.cif_blank_separator?, false)
|
||||
|
||||
opt.cif_dummy_calls = true
|
||||
assert_equal(opt.cif_dummy_calls?, true)
|
||||
opt.cif_dummy_calls = false
|
||||
assert_equal(opt.cif_dummy_calls?, false)
|
||||
|
||||
opt.dxf_polygon_mode = 2
|
||||
assert_equal(opt.dxf_polygon_mode, 2)
|
||||
|
||||
opt.gds2_libname = "MYLIB"
|
||||
assert_equal(opt.gds2_libname, "MYLIB")
|
||||
|
||||
opt.gds2_max_cellname_length = 42
|
||||
assert_equal(opt.gds2_max_cellname_length, 42)
|
||||
|
||||
opt.gds2_user_units = 0.75
|
||||
assert_equal(opt.gds2_user_units, 0.75)
|
||||
|
||||
opt.gds2_max_vertex_count = 4242
|
||||
assert_equal(opt.gds2_max_vertex_count, 4242)
|
||||
|
||||
opt.gds2_multi_xy_records = true
|
||||
assert_equal(opt.gds2_multi_xy_records, true)
|
||||
opt.gds2_multi_xy_records = false
|
||||
assert_equal(opt.gds2_multi_xy_records, false)
|
||||
|
||||
opt.gds2_no_zero_length_paths = true
|
||||
assert_equal(opt.gds2_no_zero_length_paths?, true)
|
||||
opt.gds2_no_zero_length_paths = false
|
||||
assert_equal(opt.gds2_no_zero_length_paths?, false)
|
||||
|
||||
opt.gds2_write_cell_properties = true
|
||||
assert_equal(opt.gds2_write_cell_properties?, true)
|
||||
opt.gds2_write_cell_properties = false
|
||||
assert_equal(opt.gds2_write_cell_properties?, false)
|
||||
|
||||
opt.gds2_write_file_properties = true
|
||||
assert_equal(opt.gds2_write_file_properties?, true)
|
||||
opt.gds2_write_file_properties = false
|
||||
assert_equal(opt.gds2_write_file_properties?, false)
|
||||
|
||||
opt.gds2_write_timestamps = true
|
||||
assert_equal(opt.gds2_write_timestamps?, true)
|
||||
opt.gds2_write_timestamps = false
|
||||
assert_equal(opt.gds2_write_timestamps?, false)
|
||||
|
||||
# DXF+CIF attributes are kept with GDS2
|
||||
assert_equal(opt.dxf_polygon_mode, 2)
|
||||
|
||||
opt.oasis_compression_level = 5
|
||||
assert_equal(opt.oasis_compression_level, 5)
|
||||
|
||||
opt.oasis_permissive = true
|
||||
assert_equal(opt.oasis_permissive?, true)
|
||||
opt.oasis_permissive = false
|
||||
assert_equal(opt.oasis_permissive?, false)
|
||||
|
||||
opt.oasis_recompress = true
|
||||
assert_equal(opt.oasis_recompress?, true)
|
||||
opt.oasis_recompress = false
|
||||
assert_equal(opt.oasis_recompress?, false)
|
||||
|
||||
opt.oasis_strict_mode = true
|
||||
assert_equal(opt.oasis_strict_mode?, true)
|
||||
opt.oasis_strict_mode = false
|
||||
assert_equal(opt.oasis_strict_mode?, false)
|
||||
|
||||
opt.oasis_write_cblocks = true
|
||||
assert_equal(opt.oasis_write_cblocks?, true)
|
||||
opt.oasis_write_cblocks = false
|
||||
assert_equal(opt.oasis_write_cblocks?, false)
|
||||
|
||||
opt.oasis_write_cell_bounding_boxes = true
|
||||
assert_equal(opt.oasis_write_cell_bounding_boxes?, true)
|
||||
opt.oasis_write_cell_bounding_boxes = false
|
||||
assert_equal(opt.oasis_write_cell_bounding_boxes?, false)
|
||||
|
||||
opt.oasis_write_std_properties = true
|
||||
assert_equal(opt.oasis_write_std_properties?, true)
|
||||
opt.oasis_write_std_properties = false
|
||||
assert_equal(opt.oasis_write_std_properties?, false)
|
||||
|
||||
opt.oasis_substitution_char = "+"
|
||||
assert_equal(opt.oasis_substitution_char, "+")
|
||||
|
||||
|
||||
opt.set_format_from_filename("a.gds")
|
||||
assert_equal(opt.format, "GDS2")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
||||
|
||||
Loading…
Reference in New Issue