diff --git a/src/db/db/dbAsIfFlatEdges.cc b/src/db/db/dbAsIfFlatEdges.cc index 26bfe7689..9cb62ba1a 100644 --- a/src/db/db/dbAsIfFlatEdges.cc +++ b/src/db/db/dbAsIfFlatEdges.cc @@ -59,6 +59,16 @@ AsIfFlatEdges::~AsIfFlatEdges () // .. nothing yet .. } +AsIfFlatEdges & +AsIfFlatEdges::operator= (const AsIfFlatEdges &other) +{ + if (this != &other) { + m_bbox_valid = other.m_bbox_valid; + m_bbox = other.m_bbox; + } + return *this; +} + std::string AsIfFlatEdges::to_string (size_t nmax) const { diff --git a/src/db/db/dbAsIfFlatEdges.h b/src/db/db/dbAsIfFlatEdges.h index 7a94c35c5..55c79ade0 100644 --- a/src/db/db/dbAsIfFlatEdges.h +++ b/src/db/db/dbAsIfFlatEdges.h @@ -185,10 +185,9 @@ protected: virtual RegionDelegate *pull_generic (const Region ®ion) const; virtual EdgesDelegate *selected_interacting_generic (const Edges &edges, bool inverse) const; virtual EdgesDelegate *selected_interacting_generic (const Region ®ion, bool inverse) const; - -private: AsIfFlatEdges &operator= (const AsIfFlatEdges &other); +private: mutable bool m_bbox_valid; mutable db::Box m_bbox; diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 0a9278df1..37481614e 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -55,6 +55,17 @@ AsIfFlatRegion::~AsIfFlatRegion () // .. nothing yet .. } +AsIfFlatRegion & +AsIfFlatRegion::operator= (const AsIfFlatRegion &other) +{ + if (this != &other) { + m_bbox_valid = other.m_bbox_valid; + m_bbox = other.m_bbox; + } + + return *this; +} + std::string AsIfFlatRegion::to_string (size_t nmax) const { diff --git a/src/db/db/dbAsIfFlatRegion.h b/src/db/db/dbAsIfFlatRegion.h index ed232d858..fb3a1c548 100644 --- a/src/db/db/dbAsIfFlatRegion.h +++ b/src/db/db/dbAsIfFlatRegion.h @@ -255,9 +255,10 @@ protected: template static void produce_markers_for_angle_check (const db::Polygon &poly, const Trans &tr, double min, double max, bool inverse, db::Shapes &shapes); -private: AsIfFlatRegion &operator= (const AsIfFlatRegion &other); +private: + mutable bool m_bbox_valid; mutable db::Box m_bbox; diff --git a/src/db/db/dbAsIfFlatTexts.cc b/src/db/db/dbAsIfFlatTexts.cc index d3b67790d..df65c4a25 100644 --- a/src/db/db/dbAsIfFlatTexts.cc +++ b/src/db/db/dbAsIfFlatTexts.cc @@ -51,6 +51,16 @@ AsIfFlatTexts::~AsIfFlatTexts () // .. nothing yet .. } +AsIfFlatTexts & +AsIfFlatTexts::operator= (const AsIfFlatTexts &other) +{ + if (this != &other) { + m_bbox_valid = other.m_bbox_valid; + m_bbox = other.m_bbox; + } + return *this; +} + std::string AsIfFlatTexts::to_string (size_t nmax) const { diff --git a/src/db/db/dbAsIfFlatTexts.h b/src/db/db/dbAsIfFlatTexts.h index f10d7bdea..b0f4611fe 100644 --- a/src/db/db/dbAsIfFlatTexts.h +++ b/src/db/db/dbAsIfFlatTexts.h @@ -78,9 +78,9 @@ public: protected: void update_bbox (const db::Box &box); void invalidate_bbox (); + AsIfFlatTexts &operator= (const AsIfFlatTexts &other); private: - AsIfFlatTexts &operator= (const AsIfFlatTexts &other); mutable bool m_bbox_valid; mutable db::Box m_bbox; diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index fd99ab58a..d8371e563 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -145,6 +145,25 @@ DeepEdges::DeepEdges (const DeepEdges &other) } } +DeepEdges & +DeepEdges::operator= (const DeepEdges &other) +{ + if (this != &other) { + + AsIfFlatEdges::operator= (other); + + m_deep_layer = other.m_deep_layer.copy (); + m_merged_edges_valid = other.m_merged_edges_valid; + m_is_merged = other.m_is_merged; + if (m_merged_edges_valid) { + m_merged_edges = other.m_merged_edges; + } + + } + + return *this; +} + void DeepEdges::init () { m_merged_edges_valid = false; diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 893eba147..f56fc2be6 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -150,6 +150,25 @@ DeepRegion::DeepRegion (const DeepRegion &other) } } +DeepRegion & +DeepRegion::operator= (const DeepRegion &other) +{ + if (this != &other) { + + AsIfFlatRegion::operator= (other); + + m_deep_layer = other.m_deep_layer.copy (); + m_merged_polygons_valid = other.m_merged_polygons_valid; + m_is_merged = other.m_is_merged; + if (m_merged_polygons_valid) { + m_merged_polygons = other.m_merged_polygons; + } + + } + + return *this; +} + void DeepRegion::init () { m_merged_polygons_valid = false; diff --git a/src/db/db/dbDeepTexts.cc b/src/db/db/dbDeepTexts.cc index 3145b2bf3..1def0413e 100644 --- a/src/db/db/dbDeepTexts.cc +++ b/src/db/db/dbDeepTexts.cc @@ -115,6 +115,16 @@ DeepTexts::DeepTexts (const DeepTexts &other) // .. nothing yet .. } +DeepTexts & +DeepTexts::operator= (const DeepTexts &other) +{ + if (this != &other) { + AsIfFlatTexts::operator= (other); + m_deep_layer = other.m_deep_layer.copy (); + } + return *this; +} + DeepTexts::DeepTexts (const DeepLayer &dl) : AsIfFlatTexts (), m_deep_layer (dl) { diff --git a/src/db/db/dbLayout.cc b/src/db/db/dbLayout.cc index c82051019..b4e626d99 100644 --- a/src/db/db/dbLayout.cc +++ b/src/db/db/dbLayout.cc @@ -32,6 +32,9 @@ #include "dbLibraryManager.h" #include "dbLibrary.h" #include "dbRegion.h" +#include "dbEdgePairs.h" +#include "dbEdges.h" +#include "dbTexts.h" #include "tlTimer.h" #include "tlLog.h" #include "tlInternational.h" @@ -661,6 +664,12 @@ Layout::insert (db::cell_index_type cell, int layer, const db::EdgePairs &edge_p edge_pairs.insert_into (this, cell, layer); } +void +Layout::insert (db::cell_index_type cell, int layer, const db::Texts &texts) +{ + texts.insert_into (this, cell, layer); +} + void Layout::flatten (const db::Cell &source_cell, db::Cell &target_cell, const db::ICplxTrans &t, int levels) { diff --git a/src/db/db/dbLayout.h b/src/db/db/dbLayout.h index 670248cbc..dd39be48e 100644 --- a/src/db/db/dbLayout.h +++ b/src/db/db/dbLayout.h @@ -66,6 +66,7 @@ class LayerMapping; class Region; class Edges; class EdgePairs; +class Texts; template class generic_repository; typedef generic_repository GenericRepository; @@ -1123,6 +1124,15 @@ public: */ void insert (db::cell_index_type cell, int layer, const db::EdgePairs &edge_pairs); + /** + * @brief Inserts a text collection (potentially hierarchical) into the given cell and layer + * + * If the text collection is flat (conceptionally), it will be put into the cell. + * If the text collection is hierarchical, a cell hierarchy will be built below the + * given cell. + */ + void insert (db::cell_index_type cell, int layer, const db::Texts &texts); + /** * @brief Delete a cell plus all subcells * diff --git a/src/db/db/gsiDeclDbLayout.cc b/src/db/db/gsiDeclDbLayout.cc index 685dfbd22..d6d5c9975 100644 --- a/src/db/db/gsiDeclDbLayout.cc +++ b/src/db/db/gsiDeclDbLayout.cc @@ -33,6 +33,9 @@ #include "dbPCellDeclaration.h" #include "dbHash.h" #include "dbRegion.h" +#include "dbEdges.h" +#include "dbEdgePairs.h" +#include "dbTexts.h" #include "dbLayoutUtils.h" #include "tlStream.h" @@ -1188,6 +1191,30 @@ Class decl_Layout ("db", "Layout", "\n" "This method has been introduced in version 0.26.\n" ) + + gsi::method ("insert", (void (db::Layout::*) (db::cell_index_type, int, const db::EdgePairs &)) &db::Layout::insert, + gsi::arg ("cell_index"), gsi::arg ("layer"), gsi::arg ("edge_pairs"), + "@brief Inserts an edge pair collection into the given cell and layer\n" + "If the edge pair collection is (conceptionally) flat, it will be inserted into the cell's shapes " + "list as a flat sequence of edge pairs.\n" + "If the edge pair collection is deep (hierarchical), it will create a subhierarchy below the given " + "cell and it's edge pairs will be put into the respective cells. Suitable subcells will be picked " + "for inserting the edge pairs. If a hierarchy already exists below the given cell, the algorithm will " + "try to reuse this hierarchy.\n" + "\n" + "This method has been introduced in version 0.27.\n" + ) + + gsi::method ("insert", (void (db::Layout::*) (db::cell_index_type, int, const db::Texts &)) &db::Layout::insert, + gsi::arg ("cell_index"), gsi::arg ("layer"), gsi::arg ("texts"), + "@brief Inserts an text collection into the given cell and layer\n" + "If the text collection is (conceptionally) flat, it will be inserted into the cell's shapes " + "list as a flat sequence of texts.\n" + "If the text collection is deep (hierarchical), it will create a subhierarchy below the given " + "cell and it's texts will be put into the respective cells. Suitable subcells will be picked " + "for inserting the texts. If a hierarchy already exists below the given cell, the algorithm will " + "try to reuse this hierarchy.\n" + "\n" + "This method has been introduced in version 0.27.\n" + ) + gsi::method_ext ("flatten", &flatten, gsi::arg ("cell_index"), gsi::arg ("levels"), gsi::arg ("prune"), "@brief Flattens the given cell\n" "\n" diff --git a/src/db/unit_tests/dbDeepTextsTests.cc b/src/db/unit_tests/dbDeepTextsTests.cc index 0c30659ab..a833feb89 100644 --- a/src/db/unit_tests/dbDeepTextsTests.cc +++ b/src/db/unit_tests/dbDeepTextsTests.cc @@ -28,6 +28,7 @@ #include "dbDeepShapeStore.h" #include "dbRegion.h" #include "dbEdges.h" +#include "dbTextsUtils.h" #include "tlUnitTest.h" #include "tlStream.h" @@ -143,3 +144,37 @@ TEST(2_Interactions) CHECKPOINT(); db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_texts_au2.gds"); } + +TEST(3_Filtering) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/deep_texts_l3.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + db::DeepShapeStore dss; + + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + + db::Texts texts2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss); + + db::Layout target; + unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), texts2.filtered (db::TextStringFilter ("L2", false))); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), texts2.filtered (db::TextStringFilter ("L2", true))); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), texts2.filtered (db::TextPatternFilter ("L*A", false))); + + texts2.filter (db::TextPatternFilter ("L*A", true)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), texts2); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_texts_au3.gds"); +} diff --git a/testdata/algo/deep_texts_au3.gds b/testdata/algo/deep_texts_au3.gds new file mode 100644 index 000000000..766da2bcc Binary files /dev/null and b/testdata/algo/deep_texts_au3.gds differ diff --git a/testdata/algo/deep_texts_l3.gds b/testdata/algo/deep_texts_l3.gds new file mode 100644 index 000000000..4db693c1a Binary files /dev/null and b/testdata/algo/deep_texts_l3.gds differ