diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 8a7255ae8..34e789960 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -1409,19 +1409,15 @@ get_merged_shapes_of_net (const db::hier_clusters &clusters, db::c size_t p = 0; for (db::recursive_cluster_shape_iterator rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) { - if (p == 0) { - db::PolygonRef pr = (rci.trans () * rci->polygon_ref ()); - db::PolygonRef::polygon_edge_iterator e = pr.begin_edge (); - if (! e.at_end ()) { - // pick one reference point for the label - if (! any_ref || (*e).p1 () < ref) { - ref = (*e).p1 (); - any_ref = true; - } - ep.insert (pr, ++p); + db::PolygonRef pr = (rci.trans () * rci->polygon_ref ()); + db::PolygonRef::polygon_edge_iterator e = pr.begin_edge (); + if (! e.at_end ()) { + // pick one reference point for the label + if (! any_ref || (*e).p1 () < ref) { + ref = (*e).p1 (); + any_ref = true; } - } else { - ep.insert (rci.trans () * rci->polygon_ref (), ++p); + ep.insert (pr, ++p); } } diff --git a/src/db/db/gsiDeclDbBox.cc b/src/db/db/gsiDeclDbBox.cc index 42a6789a2..dfacc8f3c 100644 --- a/src/db/db/gsiDeclDbBox.cc +++ b/src/db/db/gsiDeclDbBox.cc @@ -59,6 +59,16 @@ struct box_defs return new C (); } + static C *new_sq (coord_type s) + { + return new C (-s / 2, -s / 2, s / 2, s / 2); + } + + static C *new_wh (coord_type w, coord_type h) + { + return new C (-w / 2, -h / 2, w / 2, h / 2); + } + static C *new_lbrt (coord_type l, coord_type b, coord_type r, coord_type t) { return new C (l, b, r, t); @@ -86,11 +96,21 @@ struct box_defs return box->enlarge (vector_type (x, y)); } + static C &enlarge1 (C *box, coord_type s) + { + return box->enlarge (vector_type (s, s)); + } + static C enlarged (const C *box, coord_type x, coord_type y) { return box->enlarged (vector_type (x, y)); } + static C enlarged1 (const C *box, coord_type s) + { + return box->enlarged (vector_type (s, s)); + } + static C &move (C *box, coord_type x, coord_type y) { return box->move (vector_type (x, y)); @@ -121,6 +141,20 @@ struct box_defs "box is also an empty box. The width, height, p1 and p2 attributes of an empty box are undefined. " "Use \\empty? to get a value indicating whether the box is empty.\n" ) + + constructor ("new", &new_sq, + "@brief Creates a square with the given dimensions centered around the origin\n" + "\n" + "Note that for integer-unit boxes, the dimension has to be an even number to avoid rounding.\n" + "\n" + "This convenience constructor has been introduced in version 0.28." + ) + + constructor ("new", &new_wh, + "@brief Creates a rectangle with given width and height, centered around the origin\n" + "\n" + "Note that for integer-unit boxes, the dimensions have to be an even number to avoid rounding.\n" + "\n" + "This convenience constructor has been introduced in version 0.28." + ) + constructor ("new", &new_lbrt, gsi::arg ("left"), gsi::arg ("bottom"), gsi::arg ("right"), gsi::arg ("top"), "@brief Creates a box with four coordinates\n" "\n" @@ -347,7 +381,7 @@ struct box_defs "This is a convenience method which takes two values instead of a Point object.\n" "This method has been introduced in version 0.23.\n" "\n" - "@return The enlarged box.\n" + "@return The moved box.\n" ) + method ("move", &C::move, gsi::arg ("distance"), "@brief Moves the box by a certain distance\n" @@ -376,20 +410,36 @@ struct box_defs "@brief Enlarges the box by a certain amount.\n" "\n" "\n" - "This is a convenience method which takes two values instead of a Point object.\n" + "This is a convenience method which takes two values instead of a Vector object.\n" "This method has been introduced in version 0.23.\n" "\n" "@return A reference to this box.\n" ) + + method_ext ("enlarge", &box_defs::enlarge1, gsi::arg ("d"), + "@brief Enlarges the box by a certain amount on all sides.\n" + "\n" + "This is a convenience method which takes one values instead of two values. It will apply the given enlargement in both directions.\n" + "This method has been introduced in version 0.28.\n" + "\n" + "@return A reference to this box.\n" + ) + method_ext ("enlarged", &box_defs::enlarged, gsi::arg ("dx"), gsi::arg ("dy"), "@brief Enlarges the box by a certain amount.\n" "\n" "\n" - "This is a convenience method which takes two values instead of a Point object.\n" + "This is a convenience method which takes two values instead of a Vector object.\n" "This method has been introduced in version 0.23.\n" "\n" "@return The enlarged box.\n" ) + + method_ext ("enlarged", &box_defs::enlarged1, gsi::arg ("d"), + "@brief Enlarges the box by a certain amount on all sides.\n" + "\n" + "This is a convenience method which takes one values instead of two values. It will apply the given enlargement in both directions.\n" + "This method has been introduced in version 0.28.\n" + "\n" + "@return The enlarged box.\n" + ) + method ("enlarge", &C::enlarge, gsi::arg ("enlargement"), "@brief Enlarges the box by a certain amount.\n" "\n" diff --git a/src/edt/edt/edtInstPropertiesPage.cc b/src/edt/edt/edtInstPropertiesPage.cc index 8cfdac462..96cb7530f 100644 --- a/src/edt/edt/edtInstPropertiesPage.cc +++ b/src/edt/edt/edtInstPropertiesPage.cc @@ -78,6 +78,7 @@ InstPropertiesPage::InstPropertiesPage (edt::Service *service, db::Manager *mana connect (lib_cbx, SIGNAL (activated (int)), this, SIGNAL (edited ())); connect (cell_name_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + array_grp->setCheckable (true); connect (array_grp, SIGNAL (clicked ()), this, SIGNAL (edited ())); connect (rows_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); connect (columns_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); @@ -106,7 +107,7 @@ InstPropertiesPage::InstPropertiesPage (edt::Service *service, db::Manager *mana angle_le->setReadOnly (true); mag_le->setReadOnly (true); lib_cbx->setEnabled (false); - array_grp->setEnabled (false); + array_grp->setCheckable (false); mirror_cbx->setEnabled (false); } @@ -369,7 +370,12 @@ InstPropertiesPage::update () if (pos->back ().inst_ptr.is_regular_array (rowv, columnv, rows, columns)) { - array_grp->setChecked (true); + if (readonly ()) { + array_grp->setEnabled (true); + } else { + array_grp->setChecked (true); + } + rows_le->setText (tl::to_qstring (tl::to_string (rows))); columns_le->setText (tl::to_qstring (tl::to_string (columns))); row_x_le->setText (tl::to_qstring (coord_to_string ((gt * rowv).x (), dbu, du))); @@ -390,7 +396,12 @@ InstPropertiesPage::update () } else { - array_grp->setChecked (false); + if (readonly ()) { + array_grp->setEnabled (false); + } else { + array_grp->setChecked (false); + } + rows_le->setText (QString ()); columns_le->setText (QString ()); row_x_le->setText (QString ()); diff --git a/src/lay/lay/layApplication.cc b/src/lay/lay/layApplication.cc index 707416e5a..13ce2719a 100644 --- a/src/lay/lay/layApplication.cc +++ b/src/lay/lay/layApplication.cc @@ -258,7 +258,10 @@ ApplicationBase::parse_cmd (int &argc, char **argv) } } - m_config_file_to_write = tl::to_string (QDir (tl::to_qstring (m_appdata_path)).absoluteFilePath (QString::fromUtf8 ("klayoutrc"))); + m_config_file_to_write.clear (); + if (! m_appdata_path.empty ()) { + m_config_file_to_write = tl::to_string (QDir (tl::to_qstring (m_appdata_path)).absoluteFilePath (QString::fromUtf8 ("klayoutrc"))); + } // Hint: the order is reverse in the sense that the first one wins ... for (std::vector ::const_iterator p = m_klayout_path.end (); p != m_klayout_path.begin (); ) { @@ -733,10 +736,12 @@ ApplicationBase::init_app () std::vector global_modules = scan_global_modules (); m_load_macros.insert (m_load_macros.begin (), global_modules.begin (), global_modules.end ()); + size_t local_folders = (lay::get_appdata_path ().empty () ? 0 : 1); + for (std::vector ::const_iterator p = m_klayout_path.begin (); p != m_klayout_path.end (); ++p) { - if (p == m_klayout_path.begin ()) { + if (p - m_klayout_path.begin () < local_folders) { mc->add_path (*p, tl::to_string (QObject::tr ("Local")), std::string (), false); - } else if (m_klayout_path.size () == 2) { + } else if (m_klayout_path.size () == 1 + local_folders) { mc->add_path (*p, tl::to_string (QObject::tr ("Global")), std::string (), true); } else { mc->add_path (*p, tl::to_string (QObject::tr ("Global")) + " - " + *p, std::string (), true); diff --git a/src/lay/lay/layHelpSource.cc b/src/lay/lay/layHelpSource.cc index beb1aa7c0..8889038e8 100644 --- a/src/lay/lay/layHelpSource.cc +++ b/src/lay/lay/layHelpSource.cc @@ -274,13 +274,18 @@ HelpSource::initialize_index () bool ok = false; const QString help_index_cache_file = QString::fromUtf8 ("help-index.xml"); - std::string per_user_cache_file = tl::to_string (QDir (tl::to_qstring (lay::ApplicationBase::instance ()->appdata_path ())).absoluteFilePath (help_index_cache_file)); + std::string per_user_cache_file; + if (! lay::ApplicationBase::instance ()->appdata_path ().empty ()) { + per_user_cache_file = tl::to_string (QDir (tl::to_qstring (lay::ApplicationBase::instance ()->appdata_path ())).absoluteFilePath (help_index_cache_file)); + } // Try to obtain the help index from the installation or application path std::vector cache_files; cache_files.push_back (tl::to_string (QDir (tl::to_qstring (lay::ApplicationBase::instance ()->inst_path ())).absoluteFilePath (help_index_cache_file))); - cache_files.push_back (per_user_cache_file); + if (! per_user_cache_file.empty ()) { + cache_files.push_back (per_user_cache_file); + } for (std::vector::const_iterator c = cache_files.begin (); ! ok && c != cache_files.end (); ++c) { @@ -307,7 +312,7 @@ HelpSource::initialize_index () } - if (! ok) { + if (! ok && ! per_user_cache_file.empty ()) { // If no index is found, create one in "per_user_cache_file" produce_index_file (per_user_cache_file); } diff --git a/src/lay/lay/layMacroController.cc b/src/lay/lay/layMacroController.cc index 41167c001..aa1c392b6 100644 --- a/src/lay/lay/layMacroController.cc +++ b/src/lay/lay/layMacroController.cc @@ -262,7 +262,7 @@ MacroController::drop_url (const std::string &path_or_url) macro->load_from (path); macro->set_file_path (path); - if (macro->is_autorun () || macro->show_in_menu ()) { + if ((macro->is_autorun () || macro->show_in_menu ()) && ! lay::ApplicationBase::instance ()->appdata_path ().empty ()) { // install macro permanently if (QMessageBox::question (mp_mw, diff --git a/src/lay/lay/laySystemPaths.cc b/src/lay/lay/laySystemPaths.cc index d43f8578f..236a4dca9 100644 --- a/src/lay/lay/laySystemPaths.cc +++ b/src/lay/lay/laySystemPaths.cc @@ -40,8 +40,9 @@ namespace lay std::string get_appdata_path () { - if (tl::has_env ("KLAYOUT_HOME")) { - return tl::get_env ("KLAYOUT_HOME"); + const char *klayout_home_env = "KLAYOUT_HOME"; + if (tl::has_env (klayout_home_env)) { + return tl::get_env (klayout_home_env); } QDir appdata_dir = QDir::homePath (); @@ -105,11 +106,18 @@ get_klayout_path () std::vector klayout_path; // generate the klayout path: the first component is always the appdata path - klayout_path.push_back (get_appdata_path ()); + std::string adp = get_appdata_path (); + if (! adp.empty ()) { + klayout_path.push_back (adp); + } - std::string env = tl::get_env ("KLAYOUT_PATH"); - if (! env.empty ()) { - split_path (env, klayout_path); + const char *klayout_path_env = "KLAYOUT_PATH"; + + if (tl::has_env (klayout_path_env)) { + std::string env = tl::get_env (klayout_path_env); + if (! env.empty ()) { + split_path (env, klayout_path); + } } else { klayout_path.push_back (tl::get_inst_path ()); } diff --git a/src/layui/layui/layWidgets.cc b/src/layui/layui/layWidgets.cc index e79b6ebcf..3d7c9100d 100644 --- a/src/layui/layui/layWidgets.cc +++ b/src/layui/layui/layWidgets.cc @@ -210,9 +210,13 @@ DitherPatternSelectionButton::update_menu () lay::DitherPattern patterns; std::string s; - lay::Dispatcher::instance ()->config_get (cfg_stipple_palette, s); - lay::StipplePalette palette; - palette.from_string (s); + if (lay::Dispatcher::instance ()) { + lay::Dispatcher::instance ()->config_get (cfg_stipple_palette, s); + } + lay::StipplePalette palette = lay::StipplePalette::default_palette (); + if (! s.empty ()) { + palette.from_string (s); + } // fill the list of stipple palette items for (unsigned int i = 0; i < palette.stipples (); ++i) { @@ -910,9 +914,13 @@ ColorButton::build_color_menu (QMenu *menu, QObject *receiver, const char *brows try { std::string s; - lay::Dispatcher::instance ()->config_get (cfg_color_palette, s); - lay::ColorPalette palette; - palette.from_string (s); + if (lay::Dispatcher::instance ()) { + lay::Dispatcher::instance ()->config_get (cfg_color_palette, s); + } + lay::ColorPalette palette = lay::ColorPalette::default_palette (); + if (! s.empty ()) { + palette.from_string (s); + } QMenu *submenu = 0; diff --git a/src/tl/tl/tlException.h b/src/tl/tl/tlException.h index 2b8295c34..cea2a2b35 100644 --- a/src/tl/tl/tlException.h +++ b/src/tl/tl/tlException.h @@ -175,7 +175,9 @@ private: struct TL_PUBLIC TypeError : public Exception { - using Exception::Exception; + TypeError (const std::string &msg) + : Exception (msg) + { } }; /** diff --git a/testdata/drc/drcSimpleTests_au5.gds b/testdata/drc/drcSimpleTests_au5.gds index 3902b4aed..c77c4e703 100644 Binary files a/testdata/drc/drcSimpleTests_au5.gds and b/testdata/drc/drcSimpleTests_au5.gds differ diff --git a/testdata/drc/drcSimpleTests_au6.gds b/testdata/drc/drcSimpleTests_au6.gds index 70ac9f50b..0b311b67b 100644 Binary files a/testdata/drc/drcSimpleTests_au6.gds and b/testdata/drc/drcSimpleTests_au6.gds differ diff --git a/testdata/drc/drcSimpleTests_au7.gds b/testdata/drc/drcSimpleTests_au7.gds index e2e886e00..b96c9dd3c 100644 Binary files a/testdata/drc/drcSimpleTests_au7.gds and b/testdata/drc/drcSimpleTests_au7.gds differ diff --git a/testdata/ruby/dbBoxTest.rb b/testdata/ruby/dbBoxTest.rb index 4f6c1de10..39d3d2f01 100644 --- a/testdata/ruby/dbBoxTest.rb +++ b/testdata/ruby/dbBoxTest.rb @@ -29,6 +29,15 @@ class DBBox_TestClass < TestBase # DBox basics def test_1_DBox + a = RBA::DBox::new( 20 ) + assert_equal( a.to_s, "(-10,-10;10,10)" ) + + a = RBA::DBox::new( 21 ) + assert_equal( a.to_s, "(-10.5,-10.5;10.5,10.5)" ) + + a = RBA::DBox::new( 20, 40 ) + assert_equal( a.to_s, "(-10,-20;10,20)" ) + a = RBA::DBox::new( -10, 21, 11, 17 ) assert_equal( a.to_s, "(-10,17;11,21)" ) assert_equal( RBA::DBox::from_s(a.to_s).to_s, a.to_s ) @@ -64,6 +73,12 @@ class DBBox_TestClass < TestBase a.enlarge( RBA::DPoint::new(1, -1) ) assert_equal( a.to_s, "(-11,22;12,24)" ) + aa = a.dup + a.enlarge( 2.0 ) + assert_equal( a.to_s, "(-13,20;14,26)" ) + a.enlarge( -2.0 ) + assert_equal( aa.enlarged( 2.0 ).to_s, "(-13,20;14,26)" ) + aa = a.dup a.enlarge( -1, 1 ) assert_equal( a.to_s, "(-10,21;11,25)" ) @@ -233,6 +248,15 @@ class DBBox_TestClass < TestBase # Box basics def test_1_Box + a = RBA::Box::new( 20 ) + assert_equal( a.to_s, "(-10,-10;10,10)" ) + + a = RBA::Box::new( 21 ) + assert_equal( a.to_s, "(-10,-10;10,10)" ) + + a = RBA::Box::new( 20, 40 ) + assert_equal( a.to_s, "(-10,-20;10,20)" ) + a = RBA::Box::new( -10, 21, 11, 17 ) assert_equal( a.to_s, "(-10,17;11,21)" ) assert_equal( RBA::Box::from_s(a.to_s).to_s, a.to_s ) @@ -265,6 +289,12 @@ class DBBox_TestClass < TestBase a.move( RBA::Point::new(1, 1) ).move( RBA::Point::new(-2, 2) ) assert_equal( a.to_s, "(-10,21;11,25)" ) + aa = a.dup + a.enlarge( 2 ) + assert_equal( a.to_s, "(-12,19;13,27)" ) + a.enlarge( -2 ) + assert_equal( aa.enlarged( 2 ).to_s, "(-12,19;13,27)" ) + a.enlarge( RBA::Point::new(1, -1) ) assert_equal( a.to_s, "(-11,22;12,24)" )