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:
Matthias Koefferlein 2017-11-29 22:30:14 +01:00
parent c1e501197c
commit be80682853
8 changed files with 414 additions and 155 deletions

View File

@ -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\", "

View File

@ -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 ();

View File

@ -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
*

View File

@ -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>

View File

@ -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"
),
""
);

View File

@ -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"

View File

@ -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

170
testdata/ruby/laySaveLayoutOptions.rb vendored Normal file
View File

@ -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")