diff --git a/src/db/db/dbCommonReader.cc b/src/db/db/dbCommonReader.cc index 108a62851..2c1a876df 100644 --- a/src/db/db/dbCommonReader.cc +++ b/src/db/db/dbCommonReader.cc @@ -23,6 +23,7 @@ #include "dbCommonReader.h" +#include "dbColdProxy.h" #include "dbStream.h" #include "tlXMLParser.h" @@ -475,7 +476,7 @@ CommonReaderBase::finish (db::Layout &layout) } if (name) { - // need to rename: add a new madding to m_layer_map_out and adjust the layout's layer properties + // need to rename: add a new mapping to m_layer_map_out and adjust the layout's layer properties db::LayerProperties lpp = lp; join_layer_names (lpp.name, *name); layout.set_properties (*i, lpp); @@ -580,9 +581,32 @@ CommonReader::read (db::Layout &layout, const db::LoadLayoutOptions &options) } // A cleanup may be necessary because of the following scenario: if library proxies contain subcells - // which are proxies itself, the proxy update may make them orphans (the proxies are regenerated). + // which are proxies themselves, the proxy update may make them orphans (the proxies are regenerated). // The cleanup will removed these. - layout.cleanup (); + + // Adressing issue #1835 (reading proxy-only GDS file renders empty layout) we do not delete + // the first (non-cold) proxy if there are only proxy top cells. + // We never clean up the top cell if there is a single one. This catches the case of having + // defunct proxies for top cells. + + std::set keep; + if (layout.end_top_cells () - layout.begin_top_down () == 1) { + keep.insert (*layout.begin_top_down ()); + } else { + for (auto c = layout.begin_top_down (); c != layout.end_top_cells (); ++c) { + const db::Cell *cptr = &layout.cell (*c); + if (cptr->is_proxy ()) { + if (! dynamic_cast (cptr) && keep.empty ()) { + keep.insert (*c); + } + } else { + keep.clear (); + break; + } + } + } + + layout.cleanup (keep); return layer_map_out (); } diff --git a/src/layui/layui/layLayoutViewFunctions.cc b/src/layui/layui/layLayoutViewFunctions.cc index 7cbe98685..da5bdafad 100644 --- a/src/layui/layui/layLayoutViewFunctions.cc +++ b/src/layui/layui/layLayoutViewFunctions.cc @@ -1230,11 +1230,12 @@ LayoutViewFunctions::do_cm_paste (bool interactive) void LayoutViewFunctions::cm_new_cell () { - lay::CellView cv = view ()->cellview (view ()->active_cellview_index ()); - if (! cv.is_valid ()) { + if (view ()->active_cellview_index () < 0) { throw tl::Exception (tl::to_string (tr ("No layout present to add a cell to"))); } + lay::CellView cv = view ()->cellview (view ()->active_cellview_index ()); + static double s_new_cell_window_size = 2.0; static std::string s_new_cell_cell_name; diff --git a/src/plugins/streamers/gds2/unit_tests/dbGDS2ReaderTests.cc b/src/plugins/streamers/gds2/unit_tests/dbGDS2ReaderTests.cc index c503bab0a..f9fca1052 100644 --- a/src/plugins/streamers/gds2/unit_tests/dbGDS2ReaderTests.cc +++ b/src/plugins/streamers/gds2/unit_tests/dbGDS2ReaderTests.cc @@ -704,3 +704,24 @@ TEST(5_issue893) db::compare_layouts (_this, layout, fn_au, db::WriteGDS2, 1); } +// PCell saved as top cell +TEST(6_issue1835) +{ + db::Manager m (false); + db::Layout layout (&m); + + db::LoadLayoutOptions options; + + { + tl::InputStream file (tl::testdata () + "/gds/issue_1835.gds"); + db::Reader reader (file); + reader.read (layout, options); + } + + tl_assert (layout.begin_top_down () != layout.end_top_cells ()); + layout.convert_cell_to_static (*layout.begin_top_down ()); + + std::string fn_au (tl::testdata () + "/gds/issue_1835_au.gds"); + db::compare_layouts (_this, layout, fn_au, db::WriteGDS2, 1); +} + diff --git a/testdata/gds/issue_1835.gds b/testdata/gds/issue_1835.gds new file mode 100644 index 000000000..ecd49c3f1 Binary files /dev/null and b/testdata/gds/issue_1835.gds differ diff --git a/testdata/gds/issue_1835_au.gds b/testdata/gds/issue_1835_au.gds new file mode 100644 index 000000000..8770350b0 Binary files /dev/null and b/testdata/gds/issue_1835_au.gds differ