diff --git a/src/buddies/src/bd/bdWriterOptions.cc b/src/buddies/src/bd/bdWriterOptions.cc
index 099d2460c..27eefe679 100644
--- a/src/buddies/src/bd/bdWriterOptions.cc
+++ b/src/buddies/src/bd/bdWriterOptions.cc
@@ -30,34 +30,43 @@ namespace bd
{
GenericWriterOptions::GenericWriterOptions ()
- : m_scale_factor (1.0),
- m_dbu (0.0),
- m_dont_write_empty_cells (false),
- m_keep_instances (false),
- m_write_context_info (true),
- m_gds2_max_vertex_count (8000),
- m_gds2_no_zero_length_paths (false),
- m_gds2_multi_xy_records (false),
- m_gds2_resolve_skew_arrays (false),
- m_gds2_max_cellname_length (32000),
- m_gds2_libname ("LIB"),
- m_gds2_user_units (1.0),
- m_gds2_write_timestamps (true),
- m_gds2_write_cell_properties (false),
- m_gds2_write_file_properties (false),
- m_oasis_compression_level (2),
- m_oasis_write_cblocks (false),
- m_oasis_strict_mode (false),
- m_oasis_recompress (false),
- m_oasis_permissive (false),
- m_oasis_write_std_properties (1),
- m_oasis_subst_char ("*"),
- m_cif_dummy_calls (false),
- m_cif_blank_separator (false),
- m_magic_lambda (1.0),
- m_dxf_polygon_mode (0)
+ : m_scale_factor (1.0)
{
- // .. nothing yet ..
+ db::SaveLayoutOptions save_options;
+
+ m_dbu = save_options.get_option_by_name ("dbu").to_double ();
+
+ m_dont_write_empty_cells = save_options.get_option_by_name ("no_empty_cells").to_bool ();
+ m_keep_instances = save_options.get_option_by_name ("keep_instances").to_bool ();
+ m_write_context_info = save_options.get_option_by_name ("write_context_info").to_bool ();
+
+ m_gds2_max_vertex_count = save_options.get_option_by_name ("gds2_max_vertex_count").to_uint ();
+ m_gds2_no_zero_length_paths = save_options.get_option_by_name ("gds2_no_zero_length_paths").to_bool ();
+ m_gds2_multi_xy_records = save_options.get_option_by_name ("gds2_multi_xy_records").to_bool ();
+ m_gds2_resolve_skew_arrays = save_options.get_option_by_name ("gds2_resolve_skew_arrays").to_bool ();
+ m_gds2_max_cellname_length = save_options.get_option_by_name ("gds2_max_cellname_length").to_uint ();
+ m_gds2_libname = save_options.get_option_by_name ("gds2_libname").to_string ();
+ m_gds2_user_units = save_options.get_option_by_name ("gds2_user_units").to_double ();
+ m_gds2_write_timestamps = save_options.get_option_by_name ("gds2_write_timestamps").to_bool ();
+ m_gds2_write_cell_properties = save_options.get_option_by_name ("gds2_write_cell_properties").to_bool ();
+ m_gds2_write_file_properties = save_options.get_option_by_name ("gds2_write_file_properties").to_bool ();
+
+ m_oasis_compression_level = save_options.get_option_by_name ("oasis_compression_level").to_int ();
+ m_oasis_write_cblocks = save_options.get_option_by_name ("oasis_write_cblocks").to_bool ();
+ m_oasis_strict_mode = save_options.get_option_by_name ("oasis_strict_mode").to_bool ();
+ m_oasis_recompress = save_options.get_option_by_name ("oasis_recompress").to_bool ();
+ m_oasis_permissive = save_options.get_option_by_name ("oasis_permissive").to_bool ();
+ m_oasis_write_std_properties = save_options.get_option_by_name ("oasis_write_std_properties").to_int ();
+ m_oasis_subst_char = save_options.get_option_by_name ("oasis_substitution_char").to_string ();
+
+ m_cif_dummy_calls = save_options.get_option_by_name ("cif_dummy_calls").to_bool ();
+ m_cif_blank_separator = save_options.get_option_by_name ("cif_blank_separator").to_bool ();
+
+ // The default options do not specify a lambda, but we prefer having a default here:
+ // m_magic_lambda = save_options.get_option_by_name ("mag_lambda").to_double ();
+ m_magic_lambda = 1.0;
+
+ m_dxf_polygon_mode = save_options.get_option_by_name ("dxf_polygon_mode").to_int ();
}
const std::string GenericWriterOptions::gds2_format_name = "GDS2";
@@ -210,10 +219,14 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
"* 2++ - enhanced shape array search algorithm using 2nd and further neighbor distances as well\n"
)
<< tl::arg (group +
- "-ob|--cblocks", &m_oasis_write_cblocks, "Uses CBLOCK compression"
+ "-ob|--cblocks", &m_oasis_write_cblocks, "Uses CBLOCK compression",
+ "Please note that since version 0.27.12, CBLOCK compression is enabled by default. If you do not want "
+ "CBLOCK compression, use '--cblocks=false'."
)
<< tl::arg (group +
- "-ot|--strict-mode", &m_oasis_strict_mode, "Uses strict mode"
+ "-ot|--strict-mode", &m_oasis_strict_mode, "Uses strict mode",
+ "Please note that since version 0.27.12, strict mode is enabled by default. If you do not want "
+ "strict mode, use '--strict-mode=false'."
)
<< tl::arg (group +
"#--recompress", &m_oasis_recompress, "Compresses shape arrays again",
diff --git a/src/buddies/unit_tests/bdBasicTests.cc b/src/buddies/unit_tests/bdBasicTests.cc
index 39c6a13d5..1846ab5f5 100644
--- a/src/buddies/unit_tests/bdBasicTests.cc
+++ b/src/buddies/unit_tests/bdBasicTests.cc
@@ -58,9 +58,9 @@ TEST(1)
"--write-cell-properties",
"--write-file-properties",
// OASIS
- "-ob",
+ "-ob=false",
"-ok=9",
- "-ot",
+ "-ot=false",
"--recompress",
"--subst-char=XY",
"--write-std-properties=2"
@@ -85,9 +85,9 @@ TEST(1)
EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("gds2_user_units").to_double ()), "1");
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_cell_properties").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_file_properties").to_bool (), false);
- EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_cblocks").to_bool (), false);
+ EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_cblocks").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_compression_level").to_int (), 2);
- EXPECT_EQ (stream_opt.get_option_by_name ("oasis_strict_mode").to_bool (), false);
+ EXPECT_EQ (stream_opt.get_option_by_name ("oasis_strict_mode").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_recompress").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_substitution_char").to_string (), "*");
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_std_properties_ext").to_int (), 1);
@@ -110,9 +110,9 @@ TEST(1)
EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("gds2_user_units").to_double ()), "2.5");
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_cell_properties").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_file_properties").to_bool (), true);
- EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_cblocks").to_bool (), true);
+ EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_cblocks").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_compression_level").to_int (), 9);
- EXPECT_EQ (stream_opt.get_option_by_name ("oasis_strict_mode").to_bool (), true);
+ EXPECT_EQ (stream_opt.get_option_by_name ("oasis_strict_mode").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_recompress").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_substitution_char").to_string (), "X");
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_std_properties_ext").to_int (), 2);
diff --git a/src/db/db/dbLayoutStateModel.cc b/src/db/db/dbLayoutStateModel.cc
index 7a25be793..1118e34ef 100644
--- a/src/db/db/dbLayoutStateModel.cc
+++ b/src/db/db/dbLayoutStateModel.cc
@@ -78,11 +78,11 @@ LayoutStateModel::invalidate_bboxes (unsigned int index)
m_all_bboxes_dirty = true;
}
} else {
- if (index >= (unsigned int) m_bboxes_dirty.size ()) {
- m_bboxes_dirty.resize (index + 1, false);
- }
- if ((! m_all_bboxes_dirty && ! m_bboxes_dirty [index]) || m_busy) {
+ if ((! m_all_bboxes_dirty && (index >= (unsigned int) m_bboxes_dirty.size () || ! m_bboxes_dirty [index])) || m_busy) {
do_invalidate_bboxes (index); // must be called before the bboxes are invalidated (stopping of redraw thread requires this)
+ if (index >= (unsigned int) m_bboxes_dirty.size ()) {
+ m_bboxes_dirty.resize (index + 1, false);
+ }
m_bboxes_dirty [index] = true;
}
}
diff --git a/src/db/db/dbShapes3.cc b/src/db/db/dbShapes3.cc
index 7a86bdde5..090feb347 100644
--- a/src/db/db/dbShapes3.cc
+++ b/src/db/db/dbShapes3.cc
@@ -48,6 +48,21 @@ iterator_from_shape (const db::layer &layer, const d
return layer.begin () + (shape.basic_ptr (typename Sh::tag ()) - &*layer.begin ());
}
+template
+inline bool
+iterator_from_shape_is_valid (const db::layer &layer, const db::Shape &shape)
+{
+ typename db::layer::iterator iter = shape.basic_iter (typename Sh::tag ());
+ return iter.vector () == layer.begin ().vector () && iter.is_valid ();
+}
+
+template
+inline bool
+iterator_from_shape_is_valid (const db::layer &layer, const db::Shape &shape)
+{
+ return layer.size () < (shape.basic_ptr (typename Sh::tag ()) - &*layer.begin ());
+}
+
// -------------------------------------------------------------------------------
template
@@ -260,10 +275,11 @@ Shapes::is_valid_shape_by_tag (Tag /*tag*/, const shape_type &shape) const
throw tl::Exception (tl::to_string (tr ("Function 'is_valid' is permitted only in editable mode")));
}
if (! shape.has_prop_id ()) {
- return iterator_from_shape (get_layer (), shape).is_valid ();
+ typedef typename Tag::object_type s_type;
+ return iterator_from_shape_is_valid (get_layer (), shape);
} else {
typedef db::object_with_properties swp_type;
- return iterator_from_shape (get_layer (), shape).is_valid ();
+ return iterator_from_shape_is_valid (get_layer (), shape);
}
}
diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb
index 1382f2524..7dce0a451 100644
--- a/src/drc/drc/built-in-macros/_drc_engine.rb
+++ b/src/drc/drc/built-in-macros/_drc_engine.rb
@@ -1594,6 +1594,14 @@ CODE
# @brief Specifies cell filters on the default source
# @synopsis select(args)
# See \Source#select for a description of that function.
+ # Using the global version does not create a new source, but
+ # modifies the default source.
+ #
+ # @code
+ # # Selects only B cell instances below the top cell
+ # select("-", "+B*")
+ # l1 = input(1, 0)
+ # @/code
def select(*args)
self._context("select") do
diff --git a/src/drc/drc/built-in-macros/_drc_source.rb b/src/drc/drc/built-in-macros/_drc_source.rb
index 0af32c75a..2e969e463 100644
--- a/src/drc/drc/built-in-macros/_drc_source.rb
+++ b/src/drc/drc/built-in-macros/_drc_source.rb
@@ -161,9 +161,11 @@ module DRC
# %DRC%
# @name select
# @brief Adds cell name expressions to the cell filters
- # @synopsis source.select(filter1, filter2, ...)
+ # @synopsis new_source = source.select(filter1, filter2, ...)
# This method will construct a new source object with the given cell filters
- # applied.
+ # applied. Note that there is a global version of "select" which does not
+ # create a new source, but acts on the default source.
+ #
# Cell filters will enable or disable cells plus their subtree.
# Cells can be switched on and off, which makes the hierarchy traversal
# stop or begin delivering shapes at the given cell. The arguments of
@@ -184,8 +186,8 @@ module DRC
# code:
#
# @code
- # layout_with_selection = source.select("-TOP", "+B")
- # l1 = source.input(1, 0)
+ # source_with_selection = source.select("-TOP", "+B")
+ # l1 = source_with_selection.input(1, 0)
# ...
# @/code
#
@@ -201,8 +203,8 @@ module DRC
# first "-*" selection, all cells including the children of "B" are disabled:
#
# @code
- # layout_with_selection = source.select("-*", "+B")
- # l1 = source.input(1, 0)
+ # source_with_selection = source.select("-*", "+B")
+ # l1 = source_with_selection.input(1, 0)
# ...
# @/code
#
@@ -210,8 +212,8 @@ module DRC
# and will start with a disabled top cell regardless of its name:
#
# @code
- # layout_with_selection = source.select("-", "+B")
- # l1 = source.input(1, 0)
+ # source_with_selection = source.select("-", "+B")
+ # l1 = source_with_selection.input(1, 0)
# ...
# @/code
diff --git a/src/edt/edt/edtPartialService.cc b/src/edt/edt/edtPartialService.cc
index e50f94f82..689380c52 100644
--- a/src/edt/edt/edtPartialService.cc
+++ b/src/edt/edt/edtPartialService.cc
@@ -1028,13 +1028,16 @@ PartialService::PartialService (db::Manager *manager, lay::LayoutViewBase *view,
m_snap_to_objects (true),
m_top_level_sel (false),
m_hover (false),
- m_hover_wait (false)
-{
+ m_hover_wait (false),
+ dm_selection_to_view (this, &edt::PartialService::do_selection_to_view)
+{
#if defined(HAVE_QT)
m_timer.setInterval (100 /*hover time*/);
m_timer.setSingleShot (true);
connect (&m_timer, SIGNAL (timeout ()), this, SLOT (timeout ()));
#endif
+
+ mp_view->geom_changed_event.add (this, &edt::PartialService::selection_to_view);
}
PartialService::~PartialService ()
@@ -2398,8 +2401,14 @@ PartialService::select (const db::DBox &box, SelectionMode mode)
return false;
}
-void
+void
PartialService::selection_to_view ()
+{
+ dm_selection_to_view ();
+}
+
+void
+PartialService::do_selection_to_view ()
{
// if dragging, establish the current displacement
db::DTrans move_trans;
@@ -2424,6 +2433,17 @@ PartialService::selection_to_view ()
size_t n_marker = 0;
size_t n_inst_marker = 0;
+ // Reduce the selection to valid paths (issue-1145)
+ std::vector invalid_objects;
+ for (partial_objects::iterator r = m_selection.begin (); r != m_selection.end (); ++r) {
+ if (! r->first.is_valid (view ())) {
+ invalid_objects.push_back (r);
+ }
+ }
+ for (auto i = invalid_objects.begin (); i != invalid_objects.end (); ++i) {
+ m_selection.erase (*i);
+ }
+
if (! m_selection.empty ()) {
// build the transformation variants cache
diff --git a/src/edt/edt/edtPartialService.h b/src/edt/edt/edtPartialService.h
index 22ab958ac..6b205ddbd 100644
--- a/src/edt/edt/edtPartialService.h
+++ b/src/edt/edt/edtPartialService.h
@@ -31,6 +31,7 @@
#include "layRubberBox.h"
#include "laySnap.h"
#include "tlAssert.h"
+#include "tlDeferredExecution.h"
#include "edtUtils.h"
#include "edtConfig.h"
@@ -339,11 +340,15 @@ private:
bool m_hover_wait;
db::DPoint m_hover_point;
+ // Deferred method to update the selection
+ tl::DeferredMethod dm_selection_to_view;
+
void hover_reset ();
void clear_partial_transient_selection ();
bool partial_select (const db::DBox &box, lay::Editable::SelectionMode mode);
void selection_to_view ();
+ void do_selection_to_view ();
db::DPoint snap (const db::DPoint &p) const;
db::DVector snap (const db::DVector &p) const;
diff --git a/src/edt/edt/edtService.cc b/src/edt/edt/edtService.cc
index 27a7f8b40..e49d0248b 100644
--- a/src/edt/edt/edtService.cc
+++ b/src/edt/edt/edtService.cc
@@ -79,7 +79,7 @@ Service::Service (db::Manager *manager, lay::LayoutViewBase *view, db::ShapeIter
m_seq (0),
dm_selection_to_view (this, &edt::Service::do_selection_to_view)
{
- // .. nothing yet ..
+ mp_view->geom_changed_event.add (this, &edt::Service::selection_to_view);
}
Service::Service (db::Manager *manager, lay::LayoutViewBase *view)
@@ -99,7 +99,7 @@ Service::Service (db::Manager *manager, lay::LayoutViewBase *view)
m_seq (0),
dm_selection_to_view (this, &edt::Service::do_selection_to_view)
{
- // .. nothing yet ..
+ mp_view->geom_changed_event.add (this, &edt::Service::selection_to_view);
}
Service::~Service ()
@@ -1511,6 +1511,19 @@ Service::do_selection_to_view ()
// build the transformation variants cache
TransformationVariants tv (view ());
+ // Reduce the selection to valid paths (issue-1145)
+ std::vector::iterator> invalid_objects;
+ for (std::set::iterator r = m_selection.begin (); r != m_selection.end (); ++r) {
+ if (! r->is_valid (view ())) {
+ invalid_objects.push_back (r);
+ }
+ }
+ for (auto i = invalid_objects.begin (); i != invalid_objects.end (); ++i) {
+ m_selection.erase (*i);
+ }
+
+ // Build markers
+
for (std::set::iterator r = m_selection.begin (); r != m_selection.end (); ++r) {
const lay::CellView &cv = view ()->cellview (r->cv_index ());
diff --git a/src/edt/edt/gsiDeclEdt.cc b/src/edt/edt/gsiDeclEdt.cc
index 95a55f333..4478d0ca0 100644
--- a/src/edt/edt/gsiDeclEdt.cc
+++ b/src/edt/edt/gsiDeclEdt.cc
@@ -167,7 +167,12 @@ gsi::Class decl_ObjectInstPath ("lay", "ObjectInstPath",
"\n"
"This method has been introduced with version 0.24.\n"
) +
- gsi::method ("cv_index", &lay::ObjectInstPath::cv_index,
+ gsi::method ("is_valid?", &lay::ObjectInstPath::is_valid, gsi::arg ("view"),
+ "@brief Gets a value indicating whether the instance path refers to a valid object in the context of the given view\n"
+ "\n"
+ "This predicate has been introduced in version 0.27.12.\n"
+ ) +
+ gsi::method ("cv_index", &lay::ObjectInstPath::cv_index,
"@brief Gets the cellview index that describes which cell view the shape or instance is located in\n"
) +
gsi::method ("cv_index=", &lay::ObjectInstPath::set_cv_index, gsi::arg ("index"),
diff --git a/src/lay/lay/doc/about/drc_ref_global.xml b/src/lay/lay/doc/about/drc_ref_global.xml
index 31c87f7cf..277db525d 100644
--- a/src/lay/lay/doc/about/drc_ref_global.xml
+++ b/src/lay/lay/doc/about/drc_ref_global.xml
@@ -1597,6 +1597,14 @@ out = l1.drc(primary & secondary(l2))
See Source#select for a description of that function.
+Using the global version does not create a new source, but
+modifies the default source.
+
+
+# Selects only B cell instances below the top cell
+select("-", "+B*")
+l1 = input(1, 0)
+
"sep" - Synonym for "separation"
diff --git a/src/lay/lay/doc/about/drc_ref_source.xml b/src/lay/lay/doc/about/drc_ref_source.xml
index 439157065..37bcc2458 100644
--- a/src/lay/lay/doc/about/drc_ref_source.xml
+++ b/src/lay/lay/doc/about/drc_ref_source.xml
@@ -320,11 +320,13 @@ Use the global version of "polygons" without a source object to address the defa
Usage:
-- source.select(filter1, filter2, ...)
+- new_source = source.select(filter1, filter2, ...)
This method will construct a new source object with the given cell filters
-applied.
+applied. Note that there is a global version of "select" which does not
+create a new source, but acts on the default source.
+
Cell filters will enable or disable cells plus their subtree.
Cells can be switched on and off, which makes the hierarchy traversal
stop or begin delivering shapes at the given cell. The arguments of
@@ -345,8 +347,8 @@ To disable the TOP cell but enabled a hypothetical cell B below the top cell, us
code:
-layout_with_selection = source.select("-TOP", "+B")
-l1 = source.input(1, 0)
+source_with_selection = source.select("-TOP", "+B")
+l1 = source_with_selection.input(1, 0)
...
@@ -362,8 +364,8 @@ The following code will just select "B" without its children, because in the
first "-*" selection, all cells including the children of "B" are disabled:
-layout_with_selection = source.select("-*", "+B")
-l1 = source.input(1, 0)
+source_with_selection = source.select("-*", "+B")
+l1 = source_with_selection.input(1, 0)
...
@@ -371,8 +373,8 @@ The short form "-" will disable the top cell. This code is identical to the firs
and will start with a disabled top cell regardless of its name:
-layout_with_selection = source.select("-", "+B")
-l1 = source.input(1, 0)
+source_with_selection = source.select("-", "+B")
+l1 = source_with_selection.input(1, 0)
...
diff --git a/src/laybasic/laybasic/layObjectInstPath.cc b/src/laybasic/laybasic/layObjectInstPath.cc
index 8d8f5a870..d22f654e8 100644
--- a/src/laybasic/laybasic/layObjectInstPath.cc
+++ b/src/laybasic/laybasic/layObjectInstPath.cc
@@ -26,6 +26,7 @@
#include "layObjectInstPath.h"
#include "layCellView.h"
+#include "layLayoutViewBase.h"
#include "tlException.h"
namespace lay {
@@ -39,6 +40,42 @@ ObjectInstPath::ObjectInstPath ()
// .. nothing yet ..
}
+bool
+ObjectInstPath::is_valid (lay::LayoutViewBase *view) const
+{
+ const lay::CellView &cv = view->cellview (cv_index ());
+ if (! cv.is_valid ()) {
+ return false;
+ }
+
+ const db::Layout &ly = cv->layout ();
+ db::cell_index_type ci = topcell ();
+ if (! ly.is_valid_cell_index (ci)) {
+ return false;
+ }
+
+ for (auto p = begin (); p != end (); ++p) {
+ if (! ly.cell (ci).is_valid (p->inst_ptr)) {
+ return false;
+ }
+ ci = p->inst_ptr.cell_index ();
+ if (! ly.is_valid_cell_index (ci)) {
+ return false;
+ }
+ }
+
+ if (! is_cell_inst ()) {
+ if (! ly.is_valid_layer (layer ())) {
+ return false;
+ }
+ if (! ly.cell (ci).shapes (layer ()).is_valid (shape ())) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
db::cell_index_type
ObjectInstPath::cell_index_tot () const
{
diff --git a/src/laybasic/laybasic/layObjectInstPath.h b/src/laybasic/laybasic/layObjectInstPath.h
index 13c4ca095..580fb43ef 100644
--- a/src/laybasic/laybasic/layObjectInstPath.h
+++ b/src/laybasic/laybasic/layObjectInstPath.h
@@ -37,7 +37,7 @@
namespace lay
{
- class LayoutView;
+ class LayoutViewBase;
}
namespace lay {
@@ -299,6 +299,15 @@ public:
m_seq = s;
}
+ /**
+ * @brief Gets a value indicating whether the object path is valid
+ *
+ * After the layout has been modified, this method is able to check
+ * whether the object path (including shape if applicable) still points
+ * to a valid object.
+ */
+ bool is_valid (lay::LayoutViewBase *view) const;
+
private:
unsigned int m_cv_index;
db::cell_index_type m_topcell;
diff --git a/src/layui/layui/layDialogs.cc b/src/layui/layui/layDialogs.cc
index 5128640d3..2a19ef4fa 100644
--- a/src/layui/layui/layDialogs.cc
+++ b/src/layui/layui/layDialogs.cc
@@ -98,7 +98,7 @@ LayerSourceDialog::exec_dialog (std::string &s)
// NewLayoutPropertiesDialog implementation
NewLayoutPropertiesDialog::NewLayoutPropertiesDialog (QWidget *parent)
- : QDialog (parent)
+ : QDialog (parent), m_default_dbu (0.0)
{
setObjectName (QString::fromUtf8 ("new_layout_properties_dialog"));
@@ -117,14 +117,20 @@ NewLayoutPropertiesDialog::~NewLayoutPropertiesDialog ()
void
NewLayoutPropertiesDialog::tech_changed ()
{
- double dbu = 0.001;
+ double dbu = 0.0;
int technology_index = mp_ui->tech_cbx->currentIndex ();
if (technology_index >= 0 && technology_index < (int) db::Technologies::instance ()->technologies ()) {
dbu = db::Technologies::instance ()->begin () [technology_index].dbu ();
}
+ m_default_dbu = dbu;
+
#if QT_VERSION >= 0x40700
- mp_ui->dbu_le->setPlaceholderText (tl::to_qstring (tl::to_string (dbu)));
+ if (dbu > 1e-10) {
+ mp_ui->dbu_le->setPlaceholderText (tl::to_qstring (tl::to_string (dbu)));
+ } else {
+ mp_ui->dbu_le->setPlaceholderText (QString ());
+ }
#endif
}
@@ -142,6 +148,8 @@ NewLayoutPropertiesDialog::exec_dialog (std::string &technology, std::string &ce
}
+ tech_changed ();
+
mp_ui->window_le->setText (tl::to_qstring (tl::to_string (size)));
if (dbu > 1e-10) {
mp_ui->dbu_le->setText (tl::to_qstring (tl::to_string (dbu)));
@@ -174,7 +182,7 @@ NewLayoutPropertiesDialog::exec_dialog (std::string &technology, std::string &ce
if (! mp_ui->dbu_le->text ().isEmpty ()) {
tl::from_string_ext (tl::to_string (mp_ui->dbu_le->text ()), dbu);
} else {
- dbu = 0.0;
+ dbu = m_default_dbu;
}
cell_name = tl::to_string (mp_ui->topcell_le->text ());
diff --git a/src/layui/layui/layDialogs.h b/src/layui/layui/layDialogs.h
index b78de3731..cf752d5b9 100644
--- a/src/layui/layui/layDialogs.h
+++ b/src/layui/layui/layDialogs.h
@@ -338,6 +338,7 @@ private:
virtual void accept ();
Ui::NewLayoutPropertiesDialog *mp_ui;
+ double m_default_dbu;
};
/**
diff --git a/src/layui/layui/layWidgets.cc b/src/layui/layui/layWidgets.cc
index 7f8207279..1878937b1 100644
--- a/src/layui/layui/layWidgets.cc
+++ b/src/layui/layui/layWidgets.cc
@@ -390,10 +390,8 @@ BEGIN_PROTECTED
mp_private->view->manager ()->commit ();
- insertItem (index, tl::to_qstring (lp.to_string ()));
- setCurrentIndex (index);
-
- mp_private->layers.push_back (std::make_pair (lp, int (l)));
+ // NOTE: add_new_layers has triggered update_layer_list which already added the new layer
+ set_current_layer (lp);
}
diff --git a/src/plugins/streamers/oasis/db_plugin/dbOASISFormat.h b/src/plugins/streamers/oasis/db_plugin/dbOASISFormat.h
index 5b4198287..15379afb5 100644
--- a/src/plugins/streamers/oasis/db_plugin/dbOASISFormat.h
+++ b/src/plugins/streamers/oasis/db_plugin/dbOASISFormat.h
@@ -101,7 +101,7 @@ public:
* @brief The constructor
*/
OASISWriterOptions ()
- : compression_level (2), write_cblocks (false), strict_mode (false), recompress (false), permissive (false), write_std_properties (1), subst_char ("*")
+ : compression_level (2), write_cblocks (true), strict_mode (true), recompress (false), permissive (false), write_std_properties (1), subst_char ("*")
{
// .. nothing yet ..
}
diff --git a/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc b/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc
index 8d486117e..6d721f182 100644
--- a/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc
+++ b/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc
@@ -1176,6 +1176,11 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save
m_options = options.get_options ();
mp_stream = &stream;
+ if (stream.is_compressing ()) {
+ std::string msg = tl::to_string (tr ("File compression is discouraged in OASIS, please use CBLOCK compression"));
+ tl::warn << msg;
+ }
+
double dbu = (options.dbu () == 0.0) ? layout.dbu () : options.dbu ();
m_sf = options.scale_factor () * (layout.dbu () / dbu);
if (fabs (m_sf - 1.0) < 1e-9) {
diff --git a/src/plugins/streamers/oasis/lay_plugin/OASISWriterOptionPage.ui b/src/plugins/streamers/oasis/lay_plugin/OASISWriterOptionPage.ui
index 143dc4c6b..33cae9bb9 100644
--- a/src/plugins/streamers/oasis/lay_plugin/OASISWriterOptionPage.ui
+++ b/src/plugins/streamers/oasis/lay_plugin/OASISWriterOptionPage.ui
@@ -6,8 +6,8 @@
0
0
- 590
- 248
+ 633
+ 338
@@ -74,46 +74,35 @@
6
- -
-
-
-
- 0
- 0
-
-
-
-
-
- No standard properties
-
-
- -
-
- Global standard properties
-
-
- -
-
- Global + per-cell bounding boxes
-
-
-
-
- -
-
+
-
+
- Write strict-mode OASIS files
+
- -
+
-
Strict mode
- -
+
-
+
+
+ Standard properties
+
+
+
+ -
+
+
+ Substitution character
+
+
+
+ -
QFrame::NoFrame
@@ -169,17 +158,86 @@
- -
-
+
-
+
+
+
+ 0
+ 0
+
+
- Standard properties
+ 0 (low)
- -
-
+
-
+
+
+
+ 0
+ 0
+
+
+
-
+
+ No standard properties
+
+
+ -
+
+ Global standard properties
+
+
+ -
+
+ Global + per-cell bounding boxes
+
+
+
+
+ -
+
- Substitution character
+ Write strict-mode OASIS files
+
+
+
+ -
+
+
+ Use CBLOCK compression for each cell (RFC1951)
+
+
+
+ -
+
+
+ Don't fail on paths with odd width and other odd shapes
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Compaction level
+(repetition detection)
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+
+
+ -
+
+
+ Permissive mode
@@ -199,17 +257,54 @@
- -
-
-
-
- 0
- 0
-
+
-
+
+
+ QFrame::NoFrame
-
- 0 (low)
+
+ QFrame::Raised
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+ :/warn.png
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+ File compression - i.e. ".gz" - is discouraged in OASIS, please consider using CBLOCK compression
+
+
+ true
+
+
+
+
-
@@ -234,13 +329,6 @@
- -
-
-
-
-
-
-
-
@@ -248,30 +336,6 @@
- -
-
-
-
- 0
- 0
-
-
-
- Compaction level
-(repetition detection)
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
-
- -
-
-
- Use CBLOCK compression for each cell (RFC1951)
-
-
-
-
@@ -289,17 +353,53 @@
-
-
-
- Don't fail on paths with odd width and other odd shapes
+
+
+ QFrame::NoFrame
-
-
- -
-
-
- Permissive mode
+
+ QFrame::Raised
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+ :/warn.png
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+ Strict mode is recommended as strict mode OASIS files can be read more efficiently by some readers
+
+
+ true
+
+
+
+
@@ -329,6 +429,8 @@
strict_mode
subst_char
-
+
+
+
diff --git a/src/plugins/streamers/oasis/lay_plugin/layOASISWriterPlugin.cc b/src/plugins/streamers/oasis/lay_plugin/layOASISWriterPlugin.cc
index 259371da4..2b25fb806 100644
--- a/src/plugins/streamers/oasis/lay_plugin/layOASISWriterPlugin.cc
+++ b/src/plugins/streamers/oasis/lay_plugin/layOASISWriterPlugin.cc
@@ -24,9 +24,7 @@
#include "dbOASIS.h"
#include "dbOASISWriter.h"
#include "dbSaveLayoutOptions.h"
-#include "layStream.h"
-
-#include "ui_OASISWriterOptionPage.h"
+#include "layOASISWriterPlugin.h"
#include
@@ -36,25 +34,14 @@ namespace lay
// ---------------------------------------------------------------
// OASISWriterOptionPage definition and implementation
-class OASISWriterOptionPage
- : public StreamWriterOptionsPage
-{
-public:
- OASISWriterOptionPage (QWidget *parent);
- ~OASISWriterOptionPage ();
-
- void setup (const db::FormatSpecificWriterOptions *options, const db::Technology *tech);
- void commit (db::FormatSpecificWriterOptions *options, const db::Technology *tech, bool gzip);
-
-private:
- Ui::OASISWriterOptionPage *mp_ui;
-};
-
OASISWriterOptionPage::OASISWriterOptionPage (QWidget *parent)
: StreamWriterOptionsPage (parent)
{
mp_ui = new Ui::OASISWriterOptionPage ();
mp_ui->setupUi (this);
+
+ connect (mp_ui->write_cblocks, SIGNAL (clicked(bool)), this, SLOT (flags_changed()));
+ connect (mp_ui->strict_mode, SIGNAL (clicked(bool)), this, SLOT (flags_changed()));
}
OASISWriterOptionPage::~OASISWriterOptionPage ()
@@ -69,13 +56,22 @@ OASISWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const db
if (options) {
mp_ui->compression_slider->setValue (options->compression_level);
mp_ui->write_cblocks->setChecked (options->write_cblocks);
+ mp_ui->cblock_warning_frame->setEnabled (! options->write_cblocks);
mp_ui->strict_mode->setChecked (options->strict_mode);
+ mp_ui->strict_mode_warning_frame->setEnabled (! 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);
}
}
+void
+OASISWriterOptionPage::flags_changed ()
+{
+ mp_ui->cblock_warning_frame->setEnabled (! mp_ui->write_cblocks->isChecked ());
+ mp_ui->strict_mode_warning_frame->setEnabled (! mp_ui->strict_mode->isChecked ());
+}
+
void
OASISWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/, bool gzip)
{
diff --git a/src/plugins/streamers/oasis/lay_plugin/layOASISWriterPlugin.h b/src/plugins/streamers/oasis/lay_plugin/layOASISWriterPlugin.h
index 30f781f8d..d1873df5d 100644
--- a/src/plugins/streamers/oasis/lay_plugin/layOASISWriterPlugin.h
+++ b/src/plugins/streamers/oasis/lay_plugin/layOASISWriterPlugin.h
@@ -24,10 +24,30 @@
#ifndef HDR_layOASISWriterPlugin_h
#define HDR_layOASISWriterPlugin_h
+#include "layStream.h"
+#include "ui_OASISWriterOptionPage.h"
+
namespace lay
{
- // .. nothing yet (but needed for MOC) ..
+class OASISWriterOptionPage
+ : public StreamWriterOptionsPage
+{
+Q_OBJECT
+
+public:
+ OASISWriterOptionPage (QWidget *parent);
+ ~OASISWriterOptionPage ();
+
+ void setup (const db::FormatSpecificWriterOptions *options, const db::Technology *tech);
+ void commit (db::FormatSpecificWriterOptions *options, const db::Technology *tech, bool gzip);
+
+public slots:
+ void flags_changed ();
+
+private:
+ Ui::OASISWriterOptionPage *mp_ui;
+};
}
diff --git a/src/plugins/streamers/oasis/unit_tests/dbOASISWriterTests.cc b/src/plugins/streamers/oasis/unit_tests/dbOASISWriterTests.cc
index c632840b3..4f66ae73d 100644
--- a/src/plugins/streamers/oasis/unit_tests/dbOASISWriterTests.cc
+++ b/src/plugins/streamers/oasis/unit_tests/dbOASISWriterTests.cc
@@ -57,6 +57,10 @@ void run_test (tl::TestBase *_this, const char *file, bool scaling_test, int com
tl::OutputStream stream (tmp_file);
db::OASISWriter writer;
db::SaveLayoutOptions options;
+ db::OASISWriterOptions oasis_options;
+ oasis_options.write_cblocks = false;
+ oasis_options.strict_mode = false;
+ options.set_options (oasis_options);
writer.write (layout, stream, options);
}
@@ -158,6 +162,7 @@ void run_test (tl::TestBase *_this, const char *file, bool scaling_test, int com
db::OASISWriter writer;
db::SaveLayoutOptions options;
db::OASISWriterOptions oasis_options;
+ oasis_options.write_cblocks = false;
oasis_options.strict_mode = false;
oasis_options.write_std_properties = 2;
options.set_options (oasis_options);
@@ -557,6 +562,7 @@ TEST(100)
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
+ options.set_option_by_name ("oasis_strict_mode", false);
options.set_format ("OASIS");
db::Writer writer (options);
writer.write (g, out);
@@ -1225,6 +1231,7 @@ TEST(115)
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
+ options.set_option_by_name ("oasis_strict_mode", false);
options.set_format ("OASIS");
db::Writer writer (options);
writer.write (g, out);
@@ -1302,6 +1309,7 @@ TEST(116)
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions write_options;
+ write_options.set_option_by_name ("oasis_strict_mode", false);
write_options.set_format ("OASIS");
db::Writer writer (write_options);
writer.write (g, out);
@@ -1354,6 +1362,7 @@ TEST(116)
write_options.set_format ("OASIS");
db::OASISWriterOptions oas_write_options;
oas_write_options.write_std_properties = 0;
+ oas_write_options.strict_mode = false;
write_options.set_options (oas_write_options);
db::Writer writer (write_options);
writer.write (g, out);
@@ -1403,6 +1412,7 @@ TEST(116)
write_options.set_format ("OASIS");
db::OASISWriterOptions oas_write_options;
oas_write_options.write_std_properties = 2;
+ oas_write_options.strict_mode = false;
write_options.set_options (oas_write_options);
db::Writer writer (write_options);
writer.write (g, out);
@@ -1462,6 +1472,7 @@ TEST(116)
db::OASISWriterOptions oas_write_options;
oas_write_options.write_std_properties = 2;
oas_write_options.strict_mode = true;
+ oas_write_options.write_cblocks = false;
write_options.set_options (oas_write_options);
db::Writer writer (write_options);
writer.write (g, out);
@@ -1522,6 +1533,7 @@ TEST(116)
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions write_options;
write_options.set_format ("OASIS");
+ write_options.set_option_by_name ("oasis_strict_mode", false);
db::Writer writer (write_options);
writer.write (g, out);
}
@@ -1572,6 +1584,7 @@ TEST(116)
db::SaveLayoutOptions write_options;
write_options.select_cell (c2.cell_index ());
write_options.set_format ("OASIS");
+ write_options.set_option_by_name ("oasis_strict_mode", false);
db::Writer writer (write_options);
writer.write (g, out);
}
diff --git a/src/tl/tl/tlStream.h b/src/tl/tl/tlStream.h
index d34c630a3..b126ad656 100644
--- a/src/tl/tl/tlStream.h
+++ b/src/tl/tl/tlStream.h
@@ -726,6 +726,14 @@ public:
return false;
}
+ /**
+ * @brief Returns a value indicating whether that stream is compressing
+ */
+ virtual bool is_compressing () const
+ {
+ return false;
+ }
+
/**
* @brief Rejects the output - for delegates supporting unrolling, this means the original file is restored
*/
@@ -972,6 +980,11 @@ protected:
*/
virtual void seek_file (size_t /*s*/) { }
+ /**
+ * @brief Returns a value indicating whether this steam is compressing
+ */
+ virtual bool is_compressing () const { return true; }
+
private:
// No copying
OutputZLibFile (const OutputZLibFile &);
@@ -1244,6 +1257,14 @@ public:
}
}
+ /**
+ * @brief Returns a value indicating whether that stream is compressing
+ */
+ bool is_compressing () const
+ {
+ return mp_delegate != 0 && mp_delegate->is_compressing ();
+ }
+
/**
* @brief Returns a value indicating whether that stream supports seek
*/
diff --git a/testdata/python/dbLayoutTest.py b/testdata/python/dbLayoutTest.py
index 6c47dc483..46271a566 100644
--- a/testdata/python/dbLayoutTest.py
+++ b/testdata/python/dbLayoutTest.py
@@ -1122,7 +1122,11 @@ class DBLayoutTest(unittest.TestCase):
shape.set_property("42", "the answer")
ly.write(file_gds)
- ly.write(file_oas)
+
+ opt = pya.SaveLayoutOptions()
+ opt.format = "OASIS"
+ opt.oasis_strict_mode = False
+ ly.write(file_oas, opt)
ly2 = pya.Layout()
ly2.read(file_gds)