From f9762009c6142b047917265223e9861171c86216 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 3 Apr 2021 18:24:57 +0200 Subject: [PATCH 01/15] Bugfix: don't forget to initialize child classes in gsi expressions. --- src/gsi/gsi/gsiExpression.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gsi/gsi/gsiExpression.cc b/src/gsi/gsi/gsiExpression.cc index b844158a6..1c1d4ba3f 100644 --- a/src/gsi/gsi/gsiExpression.cc +++ b/src/gsi/gsi/gsiExpression.cc @@ -1074,21 +1074,22 @@ initialize_expressions () gsi::initialize (); // Go through all classes (maybe again) - for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) { + std::list classes = gsi::ClassBase::classes_in_definition_order (); + for (std::list::const_iterator c = classes.begin (); c != classes.end (); ++c) { // Skip external classes - if (c->is_external ()) { + if ((*c)->is_external ()) { continue; } // install the method table: - ExpressionMethodTable::initialize_class (&*c); + ExpressionMethodTable::initialize_class (*c); // register a function that creates a class object (use a function to avoid issues with // late destruction of global variables which the class object is already gone) - const tl::VariantUserClassBase *cc = c->var_cls_cls (); + const tl::VariantUserClassBase *cc = (*c)->var_cls_cls (); if (cc) { - tl::Eval::define_global_function (c->name (), new EvalClassFunction (cc)); + tl::Eval::define_global_function ((*c)->name (), new EvalClassFunction (cc)); } } From 85c3128c131a7113565c912162d97239432d39f4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 3 Apr 2021 18:26:53 +0200 Subject: [PATCH 02/15] Adding --blend-mode to buddy scripts for mitigating the risk of joining files --- Changelog | 2 ++ src/buddies/src/bd/bdReaderOptions.cc | 11 +++++++++++ src/buddies/src/bd/bdReaderOptions.h | 1 + src/buddies/unit_tests/bdBasicTests.cc | 3 +++ 4 files changed, 17 insertions(+) diff --git a/Changelog b/Changelog index 62ecba455..080a87422 100644 --- a/Changelog +++ b/Changelog @@ -80,6 +80,8 @@ Iterated OASIS instances are stored and handled in a leaner way in viewer mode * Enhancement: Buddy scripts can concatenate files with "+" for input Concatenation happens by "blending files". Beware of the risk this implies. + A new option "--blend-mode" has been introduced for supporting overwrite, skip + and variant formation in case of cell name conflicts. See buddy script help. * Enhancement: Layer maps now support n:m layer mapping This allows mapping n input layers to one logical layer (merging) and also one input layer to m logical ones (clone layer). This applies to the diff --git a/src/buddies/src/bd/bdReaderOptions.cc b/src/buddies/src/bd/bdReaderOptions.cc index 57c31cd95..51981f562 100644 --- a/src/buddies/src/bd/bdReaderOptions.cc +++ b/src/buddies/src/bd/bdReaderOptions.cc @@ -39,6 +39,7 @@ GenericReaderOptions::GenericReaderOptions () m_common_enable_text_objects = load_options.get_option_by_name ("text_enabled").to_bool (); m_common_enable_properties = load_options.get_option_by_name ("properties_enabled").to_bool (); + m_cell_conflict_resolution = load_options.get_options ().cell_conflict_resolution; m_gds2_box_mode = load_options.get_option_by_name ("gds2_box_mode").to_uint (); m_gds2_allow_big_records = load_options.get_option_by_name ("gds2_allow_big_records").to_bool (); @@ -197,6 +198,15 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) "Each line in this file is read as one layer mapping expression. " "Empty lines or lines starting with a hash (#) character or with double slashes (//) are ignored." ) + << tl::arg (group + + "--" + m_long_prefix + "blend-mode=mode", &m_cell_conflict_resolution, "Specifies how cell conflicts are resolved when using file concatenation", + "When concatenating file with '+', the reader will handle cells with the same names according to this mode:\n" + "\n" + "* 0: joins everything (default, risk of spoiling layouts)\n" + "* 1: overwrite\n" + "* 2: skip new cell\n" + "* 3: create a variant with a new name" + ) ; } @@ -684,6 +694,7 @@ GenericReaderOptions::configure (db::LoadLayoutOptions &load_options) const load_options.set_option_by_name ("create_other_layers", m_create_other_layers); load_options.set_option_by_name ("text_enabled", m_common_enable_text_objects); load_options.set_option_by_name ("properties_enabled", m_common_enable_properties); + load_options.get_options ().cell_conflict_resolution = db::CellConflictResolution (m_cell_conflict_resolution); load_options.set_option_by_name ("gds2_box_mode", m_gds2_box_mode); load_options.set_option_by_name ("gds2_allow_big_records", m_gds2_allow_big_records); diff --git a/src/buddies/src/bd/bdReaderOptions.h b/src/buddies/src/bd/bdReaderOptions.h index 2f877dc00..c3cd38ca7 100644 --- a/src/buddies/src/bd/bdReaderOptions.h +++ b/src/buddies/src/bd/bdReaderOptions.h @@ -101,6 +101,7 @@ private: bool m_create_other_layers; double m_dbu; bool m_keep_layer_names; + unsigned int m_cell_conflict_resolution; // common GDS2+OASIS bool m_common_enable_text_objects; diff --git a/src/buddies/unit_tests/bdBasicTests.cc b/src/buddies/unit_tests/bdBasicTests.cc index 3f47be648..d53ef81b6 100644 --- a/src/buddies/unit_tests/bdBasicTests.cc +++ b/src/buddies/unit_tests/bdBasicTests.cc @@ -235,6 +235,7 @@ TEST(10) // General "-im=1/0 3,4/0-255 A:17/0", "-is", + "--blend-mode=1", // OASIS "--expect-strict-mode=1" }; @@ -258,6 +259,7 @@ TEST(10) EXPECT_EQ (stream_opt.get_option_by_name ("dxf_text_scaling").to_int (), 100); EXPECT_EQ (stream_opt.get_option_by_name ("layer_map").to_user ().to_string (), "layer_map()"); EXPECT_EQ (stream_opt.get_option_by_name ("create_other_layers").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("cell_conflict_resolution").to_string (), "AddToCell"); EXPECT_EQ (stream_opt.get_option_by_name ("properties_enabled").to_bool (), true); EXPECT_EQ (stream_opt.get_option_by_name ("text_enabled").to_bool (), true); EXPECT_EQ (stream_opt.get_option_by_name ("gds2_box_mode").to_uint (), (unsigned int) 1); @@ -283,6 +285,7 @@ TEST(10) EXPECT_EQ (stream_opt.get_option_by_name ("dxf_text_scaling").to_int (), 75); EXPECT_EQ (stream_opt.get_option_by_name ("layer_map").to_user ().to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')"); EXPECT_EQ (stream_opt.get_option_by_name ("create_other_layers").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("cell_conflict_resolution").to_string (), "OverwriteCell"); EXPECT_EQ (stream_opt.get_option_by_name ("properties_enabled").to_bool (), false); EXPECT_EQ (stream_opt.get_option_by_name ("text_enabled").to_bool (), false); EXPECT_EQ (stream_opt.get_option_by_name ("gds2_box_mode").to_uint (), (unsigned int) 3); From ac9aa475abb03d9acf0c6af2233b029835740f18 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 4 Apr 2021 18:41:35 +0200 Subject: [PATCH 03/15] Properly handle external classes such as PCellDeclarationHelper in gsi::initialize_expressions --- src/gsi/gsi/gsiClassBase.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gsi/gsi/gsiClassBase.cc b/src/gsi/gsi/gsiClassBase.cc index f0e705de3..04e1b86a1 100644 --- a/src/gsi/gsi/gsiClassBase.cc +++ b/src/gsi/gsi/gsiClassBase.cc @@ -642,7 +642,6 @@ static void collect_classes (const gsi::ClassBase *cls, std::list::const_iterator cc = cls->begin_child_classes (); cc != cls->end_child_classes (); ++cc) { - tl_assert (cc->declaration () != 0); collect_classes (cc.operator-> (), unsorted_classes); } } @@ -678,7 +677,7 @@ ClassBase::classes_in_definition_order (const char *mod_name) continue; } - if ((*c)->declaration () != *c && taken.find ((*c)->declaration ()) == taken.end ()) { + if ((*c)->declaration () && (*c)->declaration () != *c && taken.find ((*c)->declaration ()) == taken.end ()) { // can't produce this class yet - it's a reference to another class which is not produced yet. tl_assert ((*c)->declaration () != 0); more_classes.push_back (*c); @@ -710,8 +709,8 @@ ClassBase::classes_in_definition_order (const char *mod_name) // don't handle classes twice if (taken.find (*c) != taken.end ()) { // not considered. - } else if ((*c)->declaration () != *c && taken.find ((*c)->declaration ()) == taken.end ()) { - // can't produce this class yet - it's a child of a parent that is not produced yet. + } else if ((*c)->declaration () && (*c)->declaration () != *c && taken.find ((*c)->declaration ()) == taken.end ()) { + // can't produce this class yet - it refers to a class whic is not available. tl::error << tl::sprintf ("class %s.%s refers to another class (%s.%s) which is not available", (*c)->module (), (*c)->name (), (*c)->declaration ()->module (), (*c)->declaration ()->name ()); } else if ((*c)->parent () != 0 && taken.find ((*c)->parent ()) == taken.end ()) { // can't produce this class yet - it's a child of a parent that is not produced yet. From 7b9a1ffdeeff03146814f6fdb233481669a41d53 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 4 Apr 2021 21:34:43 +0200 Subject: [PATCH 04/15] Made 'rename' blend mode default for buddy scripts --- src/buddies/src/bd/bdReaderOptions.cc | 8 ++++---- src/buddies/unit_tests/bdBasicTests.cc | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/buddies/src/bd/bdReaderOptions.cc b/src/buddies/src/bd/bdReaderOptions.cc index 51981f562..934f8a4ed 100644 --- a/src/buddies/src/bd/bdReaderOptions.cc +++ b/src/buddies/src/bd/bdReaderOptions.cc @@ -39,7 +39,7 @@ GenericReaderOptions::GenericReaderOptions () m_common_enable_text_objects = load_options.get_option_by_name ("text_enabled").to_bool (); m_common_enable_properties = load_options.get_option_by_name ("properties_enabled").to_bool (); - m_cell_conflict_resolution = load_options.get_options ().cell_conflict_resolution; + m_cell_conflict_resolution = (unsigned int) db::CellConflictResolution::RenameCell; m_gds2_box_mode = load_options.get_option_by_name ("gds2_box_mode").to_uint (); m_gds2_allow_big_records = load_options.get_option_by_name ("gds2_allow_big_records").to_bool (); @@ -200,12 +200,12 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) ) << tl::arg (group + "--" + m_long_prefix + "blend-mode=mode", &m_cell_conflict_resolution, "Specifies how cell conflicts are resolved when using file concatenation", - "When concatenating file with '+', the reader will handle cells with the same names according to this mode:\n" + "When concatenating files with '+', the reader will handle cells with identical names according to this mode:\n" "\n" - "* 0: joins everything (default, risk of spoiling layouts)\n" + "* 0: joins everything (unsafe)\n" "* 1: overwrite\n" "* 2: skip new cell\n" - "* 3: create a variant with a new name" + "* 3: rename cell (safe, default)" ) ; } diff --git a/src/buddies/unit_tests/bdBasicTests.cc b/src/buddies/unit_tests/bdBasicTests.cc index d53ef81b6..5029c0b87 100644 --- a/src/buddies/unit_tests/bdBasicTests.cc +++ b/src/buddies/unit_tests/bdBasicTests.cc @@ -294,3 +294,22 @@ TEST(10) EXPECT_EQ (stream_opt.get_option_by_name ("oasis_expect_strict_mode").to_int (), 1); } + +// Testing reader options - blend mode "Rename" is default +TEST(11) +{ + bd::GenericReaderOptions opt; + tl::CommandLineOptions cmd; + + opt.add_options (cmd); + + const char *argv[] = { "x" }; + + cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); + + db::LoadLayoutOptions stream_opt; + opt.configure (stream_opt); + + EXPECT_EQ (stream_opt.get_option_by_name ("cell_conflict_resolution").to_string (), "RenameCell"); +} + From 2c245af13a4af0aa3ede3e0fd25be75a1c6884ed Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 5 Apr 2021 00:27:14 +0200 Subject: [PATCH 05/15] Fixed an assertion happining with Qt binding enabled --- src/gsi/gsi/gsiClassBase.cc | 1 - src/gsi/gsi/gsiExpression.cc | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gsi/gsi/gsiClassBase.cc b/src/gsi/gsi/gsiClassBase.cc index 04e1b86a1..7ee9acd8f 100644 --- a/src/gsi/gsi/gsiClassBase.cc +++ b/src/gsi/gsi/gsiClassBase.cc @@ -679,7 +679,6 @@ ClassBase::classes_in_definition_order (const char *mod_name) if ((*c)->declaration () && (*c)->declaration () != *c && taken.find ((*c)->declaration ()) == taken.end ()) { // can't produce this class yet - it's a reference to another class which is not produced yet. - tl_assert ((*c)->declaration () != 0); more_classes.push_back (*c); continue; } diff --git a/src/gsi/gsi/gsiExpression.cc b/src/gsi/gsi/gsiExpression.cc index 1c1d4ba3f..911d38fcc 100644 --- a/src/gsi/gsi/gsiExpression.cc +++ b/src/gsi/gsi/gsiExpression.cc @@ -1077,8 +1077,12 @@ initialize_expressions () std::list classes = gsi::ClassBase::classes_in_definition_order (); for (std::list::const_iterator c = classes.begin (); c != classes.end (); ++c) { - // Skip external classes - if ((*c)->is_external ()) { + // we might encounter a child class which is a reference to a top-level class (e.g. + // duplication of enums into child classes). In this case we should create a reference inside the + // target class. + if ((*c)->declaration () != *c) { + tl_assert ((*c)->parent () != 0); // top-level classes should be merged + // TODO: implement (see rba.cc:1544 for example) continue; } From 9b86ea96d25971a94095ecb9ffcd99e69c0c6f1c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 5 Apr 2021 00:30:33 +0200 Subject: [PATCH 06/15] Fixed another assertion --- src/gsi/gsi/gsiExpression.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gsi/gsi/gsiExpression.cc b/src/gsi/gsi/gsiExpression.cc index 911d38fcc..4bf00218f 100644 --- a/src/gsi/gsi/gsiExpression.cc +++ b/src/gsi/gsi/gsiExpression.cc @@ -1077,10 +1077,13 @@ initialize_expressions () std::list classes = gsi::ClassBase::classes_in_definition_order (); for (std::list::const_iterator c = classes.begin (); c != classes.end (); ++c) { - // we might encounter a child class which is a reference to a top-level class (e.g. - // duplication of enums into child classes). In this case we should create a reference inside the - // target class. - if ((*c)->declaration () != *c) { + if ((*c)->is_external ()) { + // skip external classes + continue; + } else if ((*c)->declaration () != *c) { + // we might encounter a child class which is a reference to a top-level class (e.g. + // duplication of enums into child classes). In this case we should create a reference inside the + // target class. tl_assert ((*c)->parent () != 0); // top-level classes should be merged // TODO: implement (see rba.cc:1544 for example) continue; From d7c79a3d32928a62edadfe8de2088f40e500c641 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 6 Apr 2021 22:49:53 +0200 Subject: [PATCH 07/15] Reversed the interpretation of 'good' row/column combination until further clarification. --- src/edt/edt/InstPropertiesPage.ui | 457 +++++++++++++++++------------- 1 file changed, 255 insertions(+), 202 deletions(-) diff --git a/src/edt/edt/InstPropertiesPage.ui b/src/edt/edt/InstPropertiesPage.ui index 5742e7095..e02041b6d 100644 --- a/src/edt/edt/InstPropertiesPage.ui +++ b/src/edt/edt/InstPropertiesPage.ui @@ -473,16 +473,6 @@ - - - - - 1 - 0 - - - - @@ -503,16 +493,6 @@ - - - - - 1 - 0 - - - - @@ -603,97 +583,6 @@ - - - - - - - 0 - 0 - 0 - - - - - - - 85 - 87 - 83 - - - - - - - 243 - 243 - 243 - - - - - - - - - 0 - 0 - 0 - - - - - - - 85 - 87 - 83 - - - - - - - 243 - 243 - 243 - - - - - - - - - 190 - 190 - 190 - - - - - - - 190 - 190 - 190 - - - - - - - 239 - 239 - 239 - - - - - - QFrame::NoFrame @@ -728,97 +617,6 @@ - - - - - - - 0 - 0 - 0 - - - - - - - 85 - 87 - 83 - - - - - - - 243 - 243 - 243 - - - - - - - - - 0 - 0 - 0 - - - - - - - 85 - 87 - 83 - - - - - - - 243 - 243 - 243 - - - - - - - - - 190 - 190 - 190 - - - - - - - 190 - 190 - 190 - - - - - - - 239 - 239 - 239 - - - - - - QFrame::NoFrame @@ -851,6 +649,256 @@ + + + + + + + + + 136 + 138 + 133 + + + + + + + 238 + 238 + 236 + + + + + + + 136 + 138 + 133 + + + + + + + + + 136 + 138 + 133 + + + + + + + 238 + 238 + 236 + + + + + + + 136 + 138 + 133 + + + + + + + + + 190 + 190 + 190 + + + + + + + 239 + 239 + 239 + + + + + + + 0 + 0 + 0 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 1 + 0 + + + + + + + + + + + + + + + + 136 + 138 + 133 + + + + + + + 238 + 238 + 236 + + + + + + + 136 + 138 + 133 + + + + + + + + + 136 + 138 + 133 + + + + + + + 238 + 238 + 236 + + + + + + + 136 + 138 + 133 + + + + + + + + + 190 + 190 + 190 + + + + + + + 239 + 239 + 239 + + + + + + + 0 + 0 + 0 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 1 + 0 + + + + + + + @@ -978,14 +1026,19 @@ browse_pb lib_cbx param_tab_widget + cw_le + ch_le pos_x_le pos_y_le angle_le mirror_cbx mag_le + array_grp rows_le columns_le row_x_le + row_y_le + column_x_le column_y_le dbu_cb abs_cb From 217f957d60b95a531239dd3221560b9341dac9c4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 7 Apr 2021 22:16:52 +0200 Subject: [PATCH 08/15] Some more safety against accessing deleted user objects (stored point in temporary UserObject or DUserObject gets destroyed on destruction of the holder) - using C++ move semantics (overdue) --- src/ant/ant/antService.cc | 3 +- src/db/db/dbBoxTree.h | 47 ++++++++++++++++++ src/db/db/dbLayer.h | 47 ++++++++++++++++++ src/db/db/dbUserObject.h | 26 ++++++++++ src/laybasic/laybasic/layAnnotationShapes.cc | 50 ++++++++++++++++++-- src/laybasic/laybasic/layAnnotationShapes.h | 26 ++++++++++ src/tl/tl/tlReuseVector.h | 27 +++++++++++ src/tl/tl/tlVector.h | 16 +++++++ 8 files changed, 238 insertions(+), 4 deletions(-) diff --git a/src/ant/ant/antService.cc b/src/ant/ant/antService.cc index e5d74cef7..f9666fd2c 100644 --- a/src/ant/ant/antService.cc +++ b/src/ant/ant/antService.cc @@ -1274,8 +1274,9 @@ Service::end_move (const db::DPoint &, lay::angle_constraint_type) // compute moved object and replace ant::Object *rnew = new ant::Object (*robj); rnew->transform (m_trans); + int new_id = rnew->id (); mp_view->annotation_shapes ().replace (s->first, db::DUserObject (rnew)); - annotation_changed_event (rnew->id ()); + annotation_changed_event (new_id); } diff --git a/src/db/db/dbBoxTree.h b/src/db/db/dbBoxTree.h index acd9c37a2..cc687ca54 100644 --- a/src/db/db/dbBoxTree.h +++ b/src/db/db/dbBoxTree.h @@ -760,6 +760,15 @@ public: // .. nothing else .. } + /** + * @brief Move constructor + */ + box_tree (box_tree &&b) + : m_objects (b.m_objects), m_elements (b.m_elements), mp_root (b.mp_root) + { + b.mp_root = 0; + } + /** * @brief Assignment */ @@ -774,6 +783,21 @@ public: return *this; } + /** + * @brief Assignment (move) + */ + box_tree &operator= (box_tree &&b) + { + clear (); + m_objects = b.m_objects; + m_elements = b.m_elements; + if (b.mp_root) { + mp_root = b.mp_root; + b.mp_root = 0; + } + return *this; + } + /** * @brief The destructor */ @@ -1729,6 +1753,15 @@ public: // .. nothing else .. } + /** + * @brief Move constructor + */ + unstable_box_tree (unstable_box_tree &&b) + : m_objects (b.m_objects), mp_root (b.mp_root) + { + b.mp_root = 0; + } + /** * @brief Assignment */ @@ -1742,6 +1775,20 @@ public: return *this; } + /** + * @brief Assignment (move) + */ + unstable_box_tree &operator= (unstable_box_tree &&b) + { + clear (); + m_objects = b.m_objects; + if (b.mp_root) { + mp_root = b.mp_root; + b.mp_root = 0; + } + return *this; + } + /** * @brief The destructor */ diff --git a/src/db/db/dbLayer.h b/src/db/db/dbLayer.h index 2f54619f6..453c8648f 100644 --- a/src/db/db/dbLayer.h +++ b/src/db/db/dbLayer.h @@ -107,6 +107,14 @@ struct layer operator= (d); } + /** + * @brief The move constructor + */ + layer (const layer &&d) + { + operator= (d); + } + /** * @brief The assignment operator * @@ -123,6 +131,20 @@ struct layer return *this; } + /** + * @brief The assignment operator (move semantics) + */ + layer &operator= (const layer &&d) + { + if (&d != this) { + m_box_tree = d.m_box_tree; + m_bbox = d.m_bbox; + m_bbox_dirty = d.m_bbox_dirty; + m_tree_dirty = d.m_tree_dirty; + } + return *this; + } + /** * @brief Get the iterator for an object given by a pointer */ @@ -207,6 +229,18 @@ struct layer return m_box_tree.insert (sh); } + /** + * @brief Insert a new shape object (move semantics) + */ + iterator insert (const Sh &&sh) + { + // inserting will make the bbox and the tree "dirty" - i.e. + // it will need to be updated. + m_bbox_dirty = true; + m_tree_dirty = true; + return m_box_tree.insert (sh); + } + /** * @brief Replace the given element with a new one * @@ -228,6 +262,19 @@ struct layer return *ncpos; } + /** + * @brief Replace the given element with a new one (move semantics) + */ + Sh &replace (iterator pos, const Sh &&sh) + { + m_bbox_dirty = true; + m_tree_dirty = true; + non_const_iterator ncpos; + to_non_const_box_tree_iter (pos, ncpos, StableTag ()); + *ncpos = sh; + return *ncpos; + } + /** * @brief Erasing of an element * diff --git a/src/db/db/dbUserObject.h b/src/db/db/dbUserObject.h index 8961480ba..f9a3c0b92 100644 --- a/src/db/db/dbUserObject.h +++ b/src/db/db/dbUserObject.h @@ -206,6 +206,18 @@ public: } } + /** + * @brief The move constructor + */ + user_object (user_object &&d) + : mp_obj (0) + { + if (d.mp_obj) { + set_ptr (d.mp_obj); + d.mp_obj = 0; + } + } + /** * @brief Assignment operator */ @@ -219,6 +231,20 @@ public: return *this; } + /** + * @brief Assignment operator (move) + */ + user_object &operator= (user_object &&d) + { + if (d.mp_obj) { + set_ptr (d.mp_obj); + d.mp_obj = 0; + } else { + set_ptr (0); + } + return *this; + } + /** * @brief The destructor */ diff --git a/src/laybasic/laybasic/layAnnotationShapes.cc b/src/laybasic/laybasic/layAnnotationShapes.cc index c7babddd1..10a43b865 100644 --- a/src/laybasic/laybasic/layAnnotationShapes.cc +++ b/src/laybasic/laybasic/layAnnotationShapes.cc @@ -89,6 +89,12 @@ AnnotationShapes::AnnotationShapes (const AnnotationShapes &d) operator= (d); } +AnnotationShapes::AnnotationShapes (const AnnotationShapes &&d) + : db::LayoutStateModel (true /*busy*/), db::Object (d) +{ + operator= (d); +} + AnnotationShapes::~AnnotationShapes () { clear (); @@ -106,7 +112,21 @@ AnnotationShapes::operator= (const AnnotationShapes &d) } return *this; } -void + +AnnotationShapes & +AnnotationShapes::operator= (const AnnotationShapes &&d) +{ + if (&d != this) { + clear (); + if (manager () && manager ()->transacting ()) { + manager ()->queue (this, new AnnotationLayerOp (true /*insert*/, d.m_layer.begin (), d.m_layer.end ())); + } + m_layer = d.m_layer; + } + return *this; +} + +void AnnotationShapes::clear () { if (manager () && manager ()->transacting ()) { @@ -126,7 +146,17 @@ AnnotationShapes::insert (const shape_type &sh) return *m_layer.insert (sh); } -void +const AnnotationShapes::shape_type & +AnnotationShapes::insert (const shape_type &&sh) +{ + if (manager () && manager ()->transacting ()) { + manager ()->queue (this, new AnnotationLayerOp (true /*insert*/, sh)); + } + invalidate_state (); // HINT: must come before the change is done! + return *m_layer.insert (sh); +} + +void AnnotationShapes::reserve (size_t n) { m_layer.reserve (n); @@ -156,7 +186,21 @@ AnnotationShapes::replace (iterator pos, const shape_type &sh) return *pos; } -void +const AnnotationShapes::shape_type & +AnnotationShapes::replace (iterator pos, const shape_type &&sh) +{ + if (&*pos != &sh && *pos != sh) { + if (manager () && manager ()->transacting ()) { + manager ()->queue (this, new AnnotationLayerOp (false /*not insert*/, *pos)); + manager ()->queue (this, new AnnotationLayerOp (true /*insert*/, sh)); + } + invalidate_state (); // HINT: must come before the change is done! + m_layer.replace (pos, sh); + } + return *pos; +} + +void AnnotationShapes::redo (db::Op *op) { AnnotationLayerOp *layop = dynamic_cast (op); diff --git a/src/laybasic/laybasic/layAnnotationShapes.h b/src/laybasic/laybasic/layAnnotationShapes.h index f715c8597..c60abb5e5 100644 --- a/src/laybasic/laybasic/layAnnotationShapes.h +++ b/src/laybasic/laybasic/layAnnotationShapes.h @@ -135,16 +135,37 @@ public: */ AnnotationShapes (const AnnotationShapes &d); + /** + * @brief Copy ctor + */ + AnnotationShapes (const AnnotationShapes &&d); + /** * @brief Assignment operator */ AnnotationShapes &operator= (const AnnotationShapes &d); + /** + * @brief Assignment operator (move) + */ + AnnotationShapes &operator= (const AnnotationShapes &&d); + /** * @brief Insert a shape_type */ const shape_type &insert (const shape_type &sh); + /** + * @brief Insert a sequence of DUserObject shapes + * + * Inserts a sequence of shapes [from,to) + */ + + /** + * @brief Insert a shape_type (move semantics) + */ + const shape_type &insert (const shape_type &&sh); + /** * @brief Insert a sequence of DUserObject shapes * @@ -212,6 +233,11 @@ public: */ const shape_type &replace (iterator pos, const shape_type &sh); + /** + * @brief Replace an element at the given position with another shape (move semantics) + */ + const shape_type &replace (iterator pos, const shape_type &&sh); + /** * @brief updates the bbox * diff --git a/src/tl/tl/tlReuseVector.h b/src/tl/tl/tlReuseVector.h index 5a2eb6435..d9ff78cda 100644 --- a/src/tl/tl/tlReuseVector.h +++ b/src/tl/tl/tlReuseVector.h @@ -535,6 +535,19 @@ public: } } + /** + * @brief Move constructor + * + * See operator= for a description of the copy operation. + */ + reuse_vector (reuse_vector &&d) + { + mp_start = d.mp_start; d.mp_start = 0; + mp_finish = d.mp_finish; d.mp_finish = 0; + mp_capacity = d.mp_capacity; d.mp_capacity = 0; + mp_rdata = d.mp_rdata; d.mp_rdata = 0; + } + /** * @brief Destructor */ @@ -562,6 +575,20 @@ public: return *this; } + /** + * @brief Assignment (move) + */ + reuse_vector &operator= (reuse_vector &&d) + { + if (&d != this) { + mp_start = d.mp_start; d.mp_start = 0; + mp_finish = d.mp_finish; d.mp_finish = 0; + mp_capacity = d.mp_capacity; d.mp_capacity = 0; + mp_rdata = d.mp_rdata; d.mp_rdata = 0; + } + return *this; + } + /** * @brief Assignment * diff --git a/src/tl/tl/tlVector.h b/src/tl/tl/tlVector.h index b4ce0e5a1..0bbd77803 100644 --- a/src/tl/tl/tlVector.h +++ b/src/tl/tl/tlVector.h @@ -60,6 +60,11 @@ public: */ explicit vector (const tl::vector &d) : base (d) { } + /** + * @brief Move constructor + */ + explicit vector (const tl::vector &&d) : base (d) { } + /** * @brief Assignment */ @@ -71,6 +76,17 @@ public: return *this; } + /** + * @brief Assignment (Move) + */ + vector &operator= (const tl::vector &&d) + { + if (&d != this) { + base::operator= (d); + } + return *this; + } + /** * @brief Initialization with value and length */ From 90b131a6917042c42e533b932db64666bdd3b6d6 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 7 Apr 2021 23:15:23 +0200 Subject: [PATCH 09/15] Fixed a warning about open transaction on snap/swap points in ruler properties - undo text is somewhat weak now :( --- src/ant/ant/antPropertiesPage.cc | 3 --- src/laybasic/laybasic/layPropertiesDialog.cc | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ant/ant/antPropertiesPage.cc b/src/ant/ant/antPropertiesPage.cc index 721cd8c24..98bb0fcd5 100644 --- a/src/ant/ant/antPropertiesPage.cc +++ b/src/ant/ant/antPropertiesPage.cc @@ -122,7 +122,6 @@ PropertiesPage::swap_points_clicked () y1->setText (ty1); y2->setText (ty2); - db::Transaction t (manager (), tl::to_string (QObject::tr ("Swap ruler points"))); emit edited (); } @@ -224,7 +223,6 @@ PropertiesPage::snap_to_layout_clicked () y2->setText (ys); } - db::Transaction t (manager (), tl::to_string (snap_p1 ? QObject::tr ("Snap first ruler point") : QObject::tr ("Snap second ruler point"))); emit edited (); break; @@ -249,7 +247,6 @@ PropertiesPage::snap_to_layout_clicked () x2->setText (tl::to_qstring (tl::micron_to_string (ee.second.x ()))); y2->setText (tl::to_qstring (tl::micron_to_string (ee.second.y ()))); - db::Transaction t (manager (), tl::to_string (QObject::tr ("Snap both ruler points"))); emit edited (); } diff --git a/src/laybasic/laybasic/layPropertiesDialog.cc b/src/laybasic/laybasic/layPropertiesDialog.cc index ddd8b0390..6aa420e11 100644 --- a/src/laybasic/laybasic/layPropertiesDialog.cc +++ b/src/laybasic/laybasic/layPropertiesDialog.cc @@ -265,7 +265,7 @@ PropertiesDialog::apply () { BEGIN_PROTECTED - db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Auto-apply changes")), m_transaction_id); + db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes")), m_transaction_id); try { From 25b46def1713ca066042e5b1d4f583a52cb46377 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 7 Apr 2021 23:22:16 +0200 Subject: [PATCH 10/15] Disallow zero columns and rows count for AREFs --- src/edt/edt/edtInstPropertiesPage.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/edt/edt/edtInstPropertiesPage.cc b/src/edt/edt/edtInstPropertiesPage.cc index 2360211db..4034061fe 100644 --- a/src/edt/edt/edtInstPropertiesPage.cc +++ b/src/edt/edt/edtInstPropertiesPage.cc @@ -542,6 +542,9 @@ InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & try { tl::from_string (tl::to_string (rows_le->text ()), rows); + if (rows < 1) { + throw tl::Exception (tl::to_string (tr ("Rows count can't be zero"))); + } lay::indicate_error (rows_le, (tl::Exception *) 0); } catch (tl::Exception &ex) { lay::indicate_error (rows_le, &ex); @@ -550,6 +553,9 @@ InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & try { tl::from_string (tl::to_string (columns_le->text ()), cols); + if (cols < 1) { + throw tl::Exception (tl::to_string (tr ("Columns count can't be zero"))); + } lay::indicate_error (columns_le, (tl::Exception *) 0); } catch (tl::Exception &ex) { lay::indicate_error (columns_le, &ex); From 9ec5fb73841a48d477bb14f7964c6bf8d0f9e326 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 7 Apr 2021 23:52:39 +0200 Subject: [PATCH 11/15] Bugfix: LVS netlist browser did not navigate to device bbox correctly. --- src/laybasic/laybasic/layNetlistBrowserPage.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc index c63bcade2..2a74de56c 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.cc +++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc @@ -1027,6 +1027,8 @@ NetlistBrowserPage::adjust_view () ebox += bbox_for_device_abstract (layout, a->device_abstract, a->trans); } + trans *= device->trans (); + } else if (net) { db::cell_index_type cell_index = net->circuit ()->cell_index (); From c4e5310c95a8c3c49a416e3eca6683d6b71089b6 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 8 Apr 2021 00:32:03 +0200 Subject: [PATCH 12/15] Bugfix: holes and hulls are not neccessarily merged --- src/db/db/dbRegionUtils.h | 4 ++-- src/db/unit_tests/dbDeepRegionTests.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/db/db/dbRegionUtils.h b/src/db/db/dbRegionUtils.h index f1da9196d..a7e67ce61 100644 --- a/src/db/db/dbRegionUtils.h +++ b/src/db/db/dbRegionUtils.h @@ -558,7 +558,7 @@ public: virtual void process (const db::Polygon &poly, std::vector &res) const; virtual const TransformationReducer *vars () const { return 0; } - virtual bool result_is_merged () const { return true; } // we believe so ... + virtual bool result_is_merged () const { return false; } // isn't merged for nested holes :( virtual bool requires_raw_input () const { return false; } virtual bool wants_variants () const { return true; } virtual bool result_must_not_be_merged () const { return false; } @@ -577,7 +577,7 @@ public: virtual void process (const db::Polygon &poly, std::vector &res) const; virtual const TransformationReducer *vars () const { return 0; } - virtual bool result_is_merged () const { return true; } // we believe so ... + virtual bool result_is_merged () const { return false; } // isn't merged for nested hulls :( virtual bool requires_raw_input () const { return false; } virtual bool wants_variants () const { return true; } virtual bool result_must_not_be_merged () const { return false; } diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index 46b57bf22..f02a2f1db 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -694,8 +694,8 @@ TEST(10_HullsAndHoles) db::Region hulls = r1_sized.hulls (); db::Region holes = r1_sized.holes (); - EXPECT_EQ (hulls.is_merged (), true); - EXPECT_EQ (holes.is_merged (), true); + EXPECT_EQ (hulls.is_merged (), false); + EXPECT_EQ (holes.is_merged (), false); db::Layout target; unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); From 870fd2e0bdecac332f4ef07828151538d852ce9c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 8 Apr 2021 23:30:47 +0200 Subject: [PATCH 13/15] Fixed some valgrind issues. --- src/db/db/dbCompoundOperation.cc | 5 +---- src/db/db/dbPolygonTools.cc | 2 +- src/db/unit_tests/dbCompoundOperationTests.cc | 1 + src/plugins/streamers/gds2/db_plugin/dbGDS2Reader.cc | 8 +++++++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/db/db/dbCompoundOperation.cc b/src/db/db/dbCompoundOperation.cc index db4aedd84..e3e9b8d7c 100644 --- a/src/db/db/dbCompoundOperation.cc +++ b/src/db/db/dbCompoundOperation.cc @@ -357,10 +357,7 @@ CompoundRegionMultiInputOperationNode::init () CompoundRegionMultiInputOperationNode::~CompoundRegionMultiInputOperationNode () { - for (tl::shared_collection::iterator i = m_children.begin (); i != m_children.end (); ++i) { - delete i.operator-> (); - } - m_children.clear (); + // .. nothing yet .. } void diff --git a/src/db/db/dbPolygonTools.cc b/src/db/db/dbPolygonTools.cc index 808133e68..6d37ab289 100644 --- a/src/db/db/dbPolygonTools.cc +++ b/src/db/db/dbPolygonTools.cc @@ -1626,7 +1626,7 @@ AreaMap::reinitialize (const db::Point &p0, const db::Vector &d, const db::Vecto m_ny = ny; if (mp_av) { - delete mp_av; + delete[] mp_av; } mp_av = new area_type [nx * ny]; diff --git a/src/db/unit_tests/dbCompoundOperationTests.cc b/src/db/unit_tests/dbCompoundOperationTests.cc index a465fc28f..a0d305afa 100644 --- a/src/db/unit_tests/dbCompoundOperationTests.cc +++ b/src/db/unit_tests/dbCompoundOperationTests.cc @@ -99,6 +99,7 @@ void run_test1 (tl::TestBase *_this, bool deep) unsigned int l1002 = ly.get_layer (db::LayerProperties (1002, 0)); res.insert_into (&ly, *ly.begin_top_down (), l1002); + primary = new db::CompoundRegionOperationPrimaryNode (); db::CompoundRegionCheckOperationNode space_check (primary, db::SpaceRelation, false /*==all polygons*/, 1050, check_options); res = r.cop_to_edge_pairs (space_check); diff --git a/src/plugins/streamers/gds2/db_plugin/dbGDS2Reader.cc b/src/plugins/streamers/gds2/db_plugin/dbGDS2Reader.cc index 8d974cb6d..ae3a6dfb7 100644 --- a/src/plugins/streamers/gds2/db_plugin/dbGDS2Reader.cc +++ b/src/plugins/streamers/gds2/db_plugin/dbGDS2Reader.cc @@ -206,7 +206,13 @@ GDS2Reader::get_string () void GDS2Reader::get_string (std::string &s) const { - s.assign ((const char *) mp_rec_buf, 0, m_reclen); + if (m_reclen == 0) { + s.clear (); + } else if (mp_rec_buf [m_reclen - 1] != 0) { + s.assign ((const char *) mp_rec_buf, m_reclen); + } else { + s.assign ((const char *) mp_rec_buf, m_reclen - 1); + } } void From 93a6f2baa79896fd1aef785a5984a6676d094159 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 11 Apr 2021 09:40:27 +0200 Subject: [PATCH 14/15] Warning for non-orthogonal array vectors; important bugfix: editing array vectors wasn't working properly in absolute coordinate mode --- src/edt/edt/InstPropertiesPage.ui | 536 ++++++++++----------------- src/edt/edt/edtInstPropertiesPage.cc | 16 +- src/edt/edt/edtPropertiesPageUtils.h | 14 + 3 files changed, 223 insertions(+), 343 deletions(-) diff --git a/src/edt/edt/InstPropertiesPage.ui b/src/edt/edt/InstPropertiesPage.ui index e02041b6d..eafa2d192 100644 --- a/src/edt/edt/InstPropertiesPage.ui +++ b/src/edt/edt/InstPropertiesPage.ui @@ -456,21 +456,38 @@ 6 - - - - Column vector (x,y) + + + + QFrame::NoFrame - - - - - - x = - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + QFrame::Raised + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 1 + 0 + + + + + @@ -483,104 +500,6 @@ - - - - y = - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - x = - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Row vector (x,y) - - - - - - - Rows/Columns - - - - - - - columns = - - - - - - - - 1 - 0 - - - - - - - - rows = - - - - - - - - 1 - 0 - - - - - - - - This is instance [r,c] of array with - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <b>Warning</b>: although row and column vectors can be arbitrary combination, some design systems and mask makers only accept orthogonal (rectangular) arrays. Set the gray fields to 0 in this case. - - - true - - - @@ -615,6 +534,80 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + y = + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Rows/Columns + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 1 + 0 + + + + + + + + + + + + 1 + 0 + + + + @@ -649,98 +642,75 @@ - - - - - - - - - 136 - 138 - 133 - - - - - - - 238 - 238 - 236 - - - - - - - 136 - 138 - 133 - - - - - - - - - 136 - 138 - 133 - - - - - - - 238 - 238 - 236 - - - - - - - 136 - 138 - 133 - - - - - - - - - 190 - 190 - 190 - - - - - - - 239 - 239 - 239 - - - - - - - 0 - 0 - 0 - - - - - + + + + Column vector (x,y) + + + + + + + x = + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + x = + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + This is instance [r,c] of array with + + + + + + + + 1 + 0 + + + + + + + + columns = + + + + + + + rows = + + + + + + + Row vector (x,y) + + + + + + + false QFrame::NoFrame @@ -748,151 +718,33 @@ QFrame::Raised - - - 0 - - - 0 - - - 0 - - - 0 - + - + - - 1 + + 0 0 + + + + + :/warn.png + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + - - - - - - - - - - - - 136 - 138 - 133 - - - - - - - 238 - 238 - 236 - - - - - - - 136 - 138 - 133 - - - - - - - - - 136 - 138 - 133 - - - - - - - 238 - 238 - 236 - - - - - - - 136 - 138 - 133 - - - - - - - - - 190 - 190 - 190 - - - - - - - 239 - 239 - 239 - - - - - - - 0 - 0 - 0 - - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 1 - 0 - + + + Although row and column vectors can be arbitrary combination, some design systems and mask makers only accept arrays where row and column vectors are orthogonal and parallel to x and y axes. + + + true @@ -1046,6 +898,8 @@ sel_pb inst_pb - + + + diff --git a/src/edt/edt/edtInstPropertiesPage.cc b/src/edt/edt/edtInstPropertiesPage.cc index 4034061fe..3ba054717 100644 --- a/src/edt/edt/edtInstPropertiesPage.cc +++ b/src/edt/edt/edtInstPropertiesPage.cc @@ -45,6 +45,12 @@ namespace edt // ------------------------------------------------------------------------- // InstPropertiesPage implementation +static bool is_orthogonal (const db::DVector &rv, const db::DVector &cv) +{ + return (db::coord_traits::equal (rv.x (), 0) && db::coord_traits::equal (cv.y (), 0)) || + (db::coord_traits::equal (rv.y (), 0) && db::coord_traits::equal (cv.x (), 0)); +} + InstPropertiesPage::InstPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent) : lay::PropertiesPage (parent, manager, service), mp_service (service), m_enable_cb_callback (true), mp_pcell_parameters (0) { @@ -323,6 +329,8 @@ InstPropertiesPage::update () } + ortho_warning_frame->setEnabled (! is_orthogonal (db::CplxTrans (dbu) * rowv, db::CplxTrans (dbu) * columnv)); + } else { array_grp->setChecked (false); @@ -334,6 +342,8 @@ InstPropertiesPage::update () column_y_le->setText (QString ()); inst_lbl->setText (QString ()); + ortho_warning_frame->setEnabled (false); + } pos_x_le->setText (tl::to_qstring (coord_to_string ((gt * db::ICplxTrans (t)).disp ().x (), dbu, du))); @@ -562,8 +572,10 @@ InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & has_error = true; } - db::DVector rv = db::DVector (dpoint_from_dpoint (db::DPoint (rx, ry), dbu, du, t)); - db::DVector cv = db::DVector (dpoint_from_dpoint (db::DPoint (cx, cy), dbu, du, t)); + db::DVector rv = dvector_from_dvector (db::DVector (rx, ry), dbu, du, t); + db::DVector cv = dvector_from_dvector (db::DVector (cx, cy), dbu, du, t); + + ortho_warning_frame->setEnabled (! is_orthogonal (rv, cv)); bool set_a = (! rv.equal (a_org * dbu) || ! is_array_org); bool set_na = (rows != na_org || ! is_array_org); diff --git a/src/edt/edt/edtPropertiesPageUtils.h b/src/edt/edt/edtPropertiesPageUtils.h index e2fcb3a72..dc173b3b1 100644 --- a/src/edt/edt/edtPropertiesPageUtils.h +++ b/src/edt/edt/edtPropertiesPageUtils.h @@ -438,6 +438,20 @@ db::DCoord dcoord_from_dcoord (double d, double dbu, bool du, const db::CplxTran */ db::DPoint dpoint_from_dpoint (const db::DPoint &dp, double dbu, bool du, const db::DCplxTrans &t); +/** + * @brief Converts a micron or DBU vector to a micron point + * + * @param dp The point to convert + * @param dbu The database unit + * @param du A flag indicating whether the input point is given in database units (du = true) or micron (du = false) + * @param t A transformation (in DBU space) to apply to the point + * @return The micron-unit point + * + * The transformation is intended to be a global-to-local transformation so the output value is + * a point in local-cell micron units. + */ +db::DVector dvector_from_dvector (const db::DVector &dp, double dbu, bool du, const db::DCplxTrans &t); + /** * @brief Gets a dimension value from a string * From e0d2be2ca6ddb031ff2035dcf36d523ea61e9e0c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 11 Apr 2021 09:50:40 +0200 Subject: [PATCH 15/15] Typo fixed --- src/edt/edt/InstPropertiesPage.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/edt/edt/InstPropertiesPage.ui b/src/edt/edt/InstPropertiesPage.ui index eafa2d192..94d2f3e4a 100644 --- a/src/edt/edt/InstPropertiesPage.ui +++ b/src/edt/edt/InstPropertiesPage.ui @@ -741,7 +741,7 @@ - Although row and column vectors can be arbitrary combination, some design systems and mask makers only accept arrays where row and column vectors are orthogonal and parallel to x and y axes. + Although row and column vectors can be arbitrary combinations, some design systems and mask makers only accept arrays where row and column vectors are orthogonal and parallel to x and y axes. true