mirror of https://github.com/KLayout/klayout.git
WIP: reworked and implemented a property translation/selection/enabling scheme for the shape containers + GSI binding.
This commit is contained in:
parent
500051ef1d
commit
8ac08778c2
|
|
@ -375,6 +375,7 @@ HEADERS = \
|
|||
dbRegionUtils.h \
|
||||
dbEdgesUtils.h \
|
||||
dbRegionProcessors.h \
|
||||
gsiDeclDbContainerHelpers.h \
|
||||
gsiDeclDbHelpers.h \
|
||||
dbNetlistCompare.h \
|
||||
dbNetlistReader.h \
|
||||
|
|
|
|||
|
|
@ -314,6 +314,11 @@ const db::RecursiveShapeIterator *DeepEdgePairs::iter () const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void DeepEdgePairs::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
DeepShapeCollectionDelegateBase::apply_property_translator (pt);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *DeepEdgePairs::properties_repository ()
|
||||
{
|
||||
return &deep_layer ().layout ().properties_repository ();
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ public:
|
|||
virtual const db::EdgePair *nth (size_t n) const;
|
||||
virtual bool has_valid_edge_pairs () const;
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -454,6 +454,11 @@ DeepEdges::iter () const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void DeepEdges::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
DeepShapeCollectionDelegateBase::apply_property_translator (pt);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *DeepEdges::properties_repository ()
|
||||
{
|
||||
return &deep_layer ().layout ().properties_repository ();
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ public:
|
|||
virtual bool has_valid_merged_edges () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -475,6 +475,11 @@ DeepRegion::iter () const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void DeepRegion::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
DeepShapeCollectionDelegateBase::apply_property_translator (pt);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *DeepRegion::properties_repository ()
|
||||
{
|
||||
return &deep_layer ().layout ().properties_repository ();
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ public:
|
|||
virtual bool has_valid_merged_polygons () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -477,7 +477,6 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Region ®ion, bool for_n
|
|||
|
||||
// try to maintain the texts on top level - go through shape iterator
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> ii = region.begin_iter ();
|
||||
bool regard_props = ((ii.first.shape_flags () & db::ShapeIterator::RegardProperties) != 0);
|
||||
db::ICplxTrans ttop = trans * ii.second;
|
||||
|
||||
// The chain of operators for producing clipped and reduced polygon references
|
||||
|
|
@ -489,7 +488,7 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Region ®ion, bool for_n
|
|||
if (for_netlist && ii.first->is_text () && ii.first.layout () && ii.first.cell () != ii.first.top_cell ()) {
|
||||
// Skip texts on levels below top cell. For the reasoning see the description of this method.
|
||||
} else {
|
||||
red.push (*ii.first, regard_props ? ii.first->prop_id () : 0, ttop * ii.first.trans (), world, 0, shapes);
|
||||
red.push (*ii.first, ii.first.prop_id (), ttop * ii.first.trans (), world, 0, shapes);
|
||||
}
|
||||
|
||||
++ii.first;
|
||||
|
|
@ -518,12 +517,11 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Edges &edges, const db::IC
|
|||
db::Box world = db::Box::world ();
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> ii = edges.begin_iter ();
|
||||
bool regard_props = ((ii.first.shape_flags () & db::ShapeIterator::RegardProperties) != 0);
|
||||
db::ICplxTrans ttop = trans * ii.second;
|
||||
|
||||
db::EdgeBuildingHierarchyBuilderShapeReceiver eb (&layout (), ii.first.layout (), false);
|
||||
while (! ii.first.at_end ()) {
|
||||
eb.push (*ii.first, regard_props ? ii.first->prop_id () : 0, ttop * ii.first.trans (), world, 0, shapes);
|
||||
eb.push (*ii.first, ii.first.prop_id (), ttop * ii.first.trans (), world, 0, shapes);
|
||||
++ii.first;
|
||||
}
|
||||
|
||||
|
|
@ -549,13 +547,12 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Texts &texts, const db::IC
|
|||
db::Box world = db::Box::world ();
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> ii = texts.begin_iter ();
|
||||
bool regard_props = ((ii.first.shape_flags () & db::ShapeIterator::RegardProperties) != 0);
|
||||
db::ICplxTrans ttop = trans * ii.second;
|
||||
|
||||
db::TextBuildingHierarchyBuilderShapeReceiver tb (&layout (), ii.first.layout ());
|
||||
|
||||
while (! ii.first.at_end ()) {
|
||||
tb.push (*ii.first, regard_props ? ii.first->prop_id () : 0, ttop * ii.first.trans (), world, 0, shapes);
|
||||
tb.push (*ii.first, ii.first.prop_id (), ttop * ii.first.trans (), world, 0, shapes);
|
||||
++ii.first;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -338,6 +338,11 @@ const db::RecursiveShapeIterator *DeepTexts::iter () const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void DeepTexts::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
DeepShapeCollectionDelegateBase::apply_property_translator (pt);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *DeepTexts::properties_repository ()
|
||||
{
|
||||
return &deep_layer ().layout ().properties_repository ();
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public:
|
|||
virtual const db::Text *nth (size_t n) const;
|
||||
virtual bool has_valid_texts () const;
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ public:
|
|||
virtual bool has_valid_edge_pairs () const = 0;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const = 0;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt) = 0;
|
||||
virtual db::PropertiesRepository *properties_repository () = 0;
|
||||
virtual const db::PropertiesRepository *properties_repository () const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -340,6 +340,7 @@ public:
|
|||
virtual bool has_valid_merged_edges () const = 0;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const = 0;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt) = 0;
|
||||
virtual db::PropertiesRepository *properties_repository () = 0;
|
||||
virtual const db::PropertiesRepository *properties_repository () const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public:
|
|||
virtual bool has_valid_edge_pairs () const { return true; }
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &) { }
|
||||
virtual db::PropertiesRepository *properties_repository () { return 0; }
|
||||
virtual const db::PropertiesRepository *properties_repository () const { return 0; }
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ public:
|
|||
virtual bool has_valid_merged_edges () const { return true; }
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &) { }
|
||||
virtual db::PropertiesRepository *properties_repository () { return 0; }
|
||||
virtual const db::PropertiesRepository *properties_repository () const { return 0; }
|
||||
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ public:
|
|||
virtual db::properties_id_type nth_prop_id (size_t) const { tl_assert (false); }
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &) { }
|
||||
virtual db::PropertiesRepository *properties_repository () { return 0; }
|
||||
virtual const db::PropertiesRepository *properties_repository () const { return 0; }
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public:
|
|||
virtual bool has_valid_texts () const { return true; }
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &) { }
|
||||
virtual db::PropertiesRepository *properties_repository () { return 0; }
|
||||
virtual const db::PropertiesRepository *properties_repository () const { return 0; }
|
||||
|
||||
|
|
|
|||
|
|
@ -188,6 +188,13 @@ const db::RecursiveShapeIterator *FlatEdgePairs::iter () const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void FlatEdgePairs::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
db::Shapes new_edge_pairs;
|
||||
new_edge_pairs.assign (*mp_edge_pairs, pt);
|
||||
mp_edge_pairs->swap (new_edge_pairs);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *FlatEdgePairs::properties_repository ()
|
||||
{
|
||||
return mp_properties_repository.get_non_const ();
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ public:
|
|||
virtual bool has_valid_edge_pairs () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -345,6 +345,13 @@ const db::RecursiveShapeIterator *FlatEdges::iter () const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void FlatEdges::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
db::Shapes new_edges;
|
||||
new_edges.assign (*mp_edges, pt);
|
||||
mp_edges->swap (new_edges);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *FlatEdges::properties_repository ()
|
||||
{
|
||||
return mp_properties_repository.get_non_const ();
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ public:
|
|||
virtual bool has_valid_merged_edges () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -419,6 +419,13 @@ const db::RecursiveShapeIterator *FlatRegion::iter () const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void FlatRegion::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
db::Shapes new_polygons;
|
||||
new_polygons.assign (*mp_polygons, pt);
|
||||
mp_polygons->swap (new_polygons);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *FlatRegion::properties_repository ()
|
||||
{
|
||||
return mp_properties_repository.get_non_const ();
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ public:
|
|||
virtual bool has_valid_merged_polygons () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -188,6 +188,13 @@ const db::RecursiveShapeIterator *FlatTexts::iter () const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void FlatTexts::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
db::Shapes new_texts;
|
||||
new_texts.assign (*mp_texts, pt);
|
||||
mp_texts->swap (new_texts);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *FlatTexts::properties_repository ()
|
||||
{
|
||||
return mp_properties_repository.get_non_const ();
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ public:
|
|||
virtual bool has_valid_texts () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -152,13 +152,13 @@ static std::pair<bool, std::set<db::Box> > compute_clip_variant (const db::Box &
|
|||
}
|
||||
|
||||
HierarchyBuilder::HierarchyBuilder (db::Layout *target, unsigned int target_layer, const db::ICplxTrans &trans, HierarchyBuilderShapeReceiver *pipe)
|
||||
: mp_target (target), m_initial_pass (true), m_ignore_properties (true), m_cm_new_entry (false), m_target_layer (target_layer), m_trans (trans)
|
||||
: mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (target_layer), m_trans (trans)
|
||||
{
|
||||
set_shape_receiver (pipe);
|
||||
}
|
||||
|
||||
HierarchyBuilder::HierarchyBuilder (db::Layout *target, const db::ICplxTrans &trans, HierarchyBuilderShapeReceiver *pipe)
|
||||
: mp_target (target), m_initial_pass (true), m_ignore_properties (true), m_cm_new_entry (false), m_target_layer (0), m_trans (trans)
|
||||
: mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (0), m_trans (trans)
|
||||
{
|
||||
set_shape_receiver (pipe);
|
||||
}
|
||||
|
|
@ -179,7 +179,6 @@ HierarchyBuilder::reset ()
|
|||
{
|
||||
m_initial_pass = true;
|
||||
mp_initial_cell = 0;
|
||||
m_ignore_properties = true;
|
||||
|
||||
m_cells_to_be_filled.clear ();
|
||||
m_cell_map.clear ();
|
||||
|
|
@ -245,8 +244,6 @@ HierarchyBuilder::begin (const RecursiveShapeIterator *iter)
|
|||
tl_assert (compare_iterators_with_respect_to_target_hierarchy (m_source, *iter) == 0);
|
||||
}
|
||||
|
||||
m_ignore_properties = ((iter->shape_flags () & db::ShapeIterator::RegardProperties) == 0);
|
||||
|
||||
m_cell_stack.clear ();
|
||||
m_cells_seen.clear ();
|
||||
|
||||
|
|
@ -278,7 +275,6 @@ HierarchyBuilder::end (const RecursiveShapeIterator *iter)
|
|||
{
|
||||
tl_assert (! iter->layout () || ! iter->top_cell () || m_cell_stack.size () == 1);
|
||||
|
||||
m_ignore_properties = true;
|
||||
m_initial_pass = false;
|
||||
m_cells_seen.clear ();
|
||||
mp_initial_cell = m_cell_stack.empty () ? 0 : m_cell_stack.front ().second.front ();
|
||||
|
|
@ -411,11 +407,11 @@ HierarchyBuilder::new_inst_member (const RecursiveShapeIterator *iter, const db:
|
|||
}
|
||||
|
||||
void
|
||||
HierarchyBuilder::shape (const RecursiveShapeIterator * /*iter*/, const db::Shape &shape, const db::ICplxTrans &apply_always, const db::ICplxTrans & /*trans*/, const db::Box ®ion, const box_tree_type *complex_region)
|
||||
HierarchyBuilder::shape (const RecursiveShapeIterator *iter, const db::Shape &shape, const db::ICplxTrans &apply_always, const db::ICplxTrans & /*trans*/, const db::Box ®ion, const box_tree_type *complex_region)
|
||||
{
|
||||
for (std::vector<db::Cell *>::const_iterator c = m_cell_stack.back ().second.begin (); c != m_cell_stack.back ().second.end (); ++c) {
|
||||
db::Shapes &shapes = (*c)->shapes (m_target_layer);
|
||||
mp_pipe->push (shape, m_ignore_properties ? 0 : shape.prop_id (), m_trans * apply_always, region, complex_region, &shapes);
|
||||
mp_pipe->push (shape, iter->prop_id (), m_trans * apply_always, region, complex_region, &shapes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -406,7 +406,6 @@ private:
|
|||
tl::weak_ptr<db::Layout> mp_target;
|
||||
HierarchyBuilderShapeReceiver *mp_pipe;
|
||||
bool m_initial_pass;
|
||||
bool m_ignore_properties;
|
||||
db::RecursiveShapeIterator m_source;
|
||||
cell_map_type m_cell_map;
|
||||
original_target_to_variants_map_type m_original_targets_to_variants_map;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ namespace
|
|||
if (! m_rec_iter.at_end ()) {
|
||||
m_rec_iter->edge_pair (m_shape);
|
||||
m_shape.transform (m_iter_trans * m_rec_iter.trans ());
|
||||
m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::RegardProperties) != 0 ? m_rec_iter->prop_id () : 0;
|
||||
m_prop_id = m_rec_iter.prop_id ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -202,6 +202,12 @@ OriginalLayerEdgePairs::iter () const
|
|||
return &m_iter;
|
||||
}
|
||||
|
||||
void
|
||||
OriginalLayerEdgePairs::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
m_iter.apply_property_translator (pt);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *
|
||||
OriginalLayerEdgePairs::properties_repository ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ public:
|
|||
virtual bool has_valid_edge_pairs () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ namespace
|
|||
if (! m_rec_iter.at_end ()) {
|
||||
m_rec_iter->edge (m_shape);
|
||||
m_shape.transform (m_iter_trans * m_rec_iter.trans ());
|
||||
m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::RegardProperties) != 0 ? m_rec_iter->prop_id () : 0;
|
||||
m_prop_id = m_rec_iter.prop_id ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -251,6 +251,12 @@ OriginalLayerEdges::iter () const
|
|||
return &m_iter;
|
||||
}
|
||||
|
||||
void
|
||||
OriginalLayerEdges::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
m_iter.apply_property_translator (pt);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *
|
||||
OriginalLayerEdges::properties_repository ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ public:
|
|||
virtual bool has_valid_merged_edges () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ namespace
|
|||
if (! m_rec_iter.at_end ()) {
|
||||
m_rec_iter->polygon (m_polygon);
|
||||
m_polygon.transform (m_iter_trans * m_rec_iter.trans (), false);
|
||||
m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::RegardProperties) != 0 ? m_rec_iter->prop_id () : 0;
|
||||
m_prop_id = m_rec_iter.prop_id ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -369,6 +369,12 @@ OriginalLayerRegion::iter () const
|
|||
return &m_iter;
|
||||
}
|
||||
|
||||
void
|
||||
OriginalLayerRegion::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
m_iter.apply_property_translator (pt);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *
|
||||
OriginalLayerRegion::properties_repository ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ public:
|
|||
virtual bool has_valid_merged_polygons () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ namespace
|
|||
if (! m_rec_iter.at_end ()) {
|
||||
m_rec_iter->text (m_shape);
|
||||
m_shape.transform (m_iter_trans * m_rec_iter.trans ());
|
||||
m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::RegardProperties) != 0 ? m_rec_iter->prop_id () : 0;
|
||||
m_prop_id = m_rec_iter.prop_id ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -202,6 +202,12 @@ OriginalLayerTexts::iter () const
|
|||
return &m_iter;
|
||||
}
|
||||
|
||||
void
|
||||
OriginalLayerTexts::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
m_iter.apply_property_translator (pt);
|
||||
}
|
||||
|
||||
db::PropertiesRepository *
|
||||
OriginalLayerTexts::properties_repository ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ public:
|
|||
virtual bool has_valid_texts () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -213,5 +213,135 @@ PropertiesRepository::translate (const PropertiesRepository &rep, properties_id_
|
|||
return properties_id (new_pset);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// PropertiesRepository implementation
|
||||
|
||||
PropertiesTranslator::PropertiesTranslator ()
|
||||
: m_pass (true), m_null (true)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
PropertiesTranslator::PropertiesTranslator (bool pass)
|
||||
: m_pass (pass), m_null (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
PropertiesTranslator::PropertiesTranslator (const std::map<db::properties_id_type, db::properties_id_type> &map)
|
||||
: m_map (map), m_pass (false), m_null (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
PropertiesTranslator
|
||||
PropertiesTranslator::operator* (const PropertiesTranslator &other) const
|
||||
{
|
||||
if (other.m_pass) {
|
||||
|
||||
// NOTE: by handling this first, "pass_all * null" will give "pass_all" which is desired
|
||||
// for RecursiveShapeIterator::apply_property_translator.
|
||||
return *this;
|
||||
|
||||
} else if (m_pass) {
|
||||
|
||||
return other;
|
||||
|
||||
} else {
|
||||
|
||||
std::map<db::properties_id_type, db::properties_id_type> new_map;
|
||||
|
||||
for (auto i = other.m_map.begin (); i != other.m_map.end (); ++i) {
|
||||
auto ii = m_map.find (i->second);
|
||||
if (ii != m_map.end ()) {
|
||||
new_map.insert (std::make_pair (i->first, ii->second));
|
||||
}
|
||||
}
|
||||
|
||||
return PropertiesTranslator (new_map);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
db::properties_id_type
|
||||
PropertiesTranslator::operator() (db::properties_id_type id) const
|
||||
{
|
||||
if (m_pass || id == 0) {
|
||||
return id;
|
||||
} else {
|
||||
auto i = m_map.find (id);
|
||||
return i != m_map.end () ? i->second : 0;
|
||||
}
|
||||
}
|
||||
|
||||
PropertiesTranslator
|
||||
PropertiesTranslator::make_remove_all ()
|
||||
{
|
||||
return PropertiesTranslator (false);
|
||||
}
|
||||
|
||||
PropertiesTranslator
|
||||
PropertiesTranslator::make_pass_all ()
|
||||
{
|
||||
return PropertiesTranslator (true);
|
||||
}
|
||||
|
||||
PropertiesTranslator
|
||||
PropertiesTranslator::make_filter (db::PropertiesRepository &repo, const std::set<tl::Variant> &keys)
|
||||
{
|
||||
std::map<db::properties_id_type, db::properties_id_type> map;
|
||||
std::set<db::property_names_id_type> names_selected;
|
||||
|
||||
for (auto k = keys.begin (); k != keys.end (); ++k) {
|
||||
names_selected.insert (repo.prop_name_id (*k));
|
||||
}
|
||||
|
||||
db::PropertiesRepository org_repo = repo;
|
||||
|
||||
for (auto p = org_repo.begin (); p != org_repo.end (); ++p) {
|
||||
db::PropertiesRepository::properties_set new_set;
|
||||
for (auto i = p->second.begin (); i != p->second.end (); ++i) {
|
||||
if (names_selected.find (i->first) != names_selected.end ()) {
|
||||
new_set.insert (*i);
|
||||
}
|
||||
}
|
||||
if (! new_set.empty ()) {
|
||||
map.insert (std::make_pair (p->first, repo.properties_id (new_set)));
|
||||
}
|
||||
}
|
||||
|
||||
return PropertiesTranslator (map);
|
||||
}
|
||||
|
||||
PropertiesTranslator
|
||||
PropertiesTranslator::make_key_mapper (db::PropertiesRepository &repo, const std::map<tl::Variant, tl::Variant> &keys)
|
||||
{
|
||||
std::map<db::properties_id_type, db::properties_id_type> map;
|
||||
std::map<db::property_names_id_type, db::property_names_id_type> name_map;
|
||||
|
||||
for (auto k = keys.begin (); k != keys.end (); ++k) {
|
||||
name_map.insert (std::make_pair (repo.prop_name_id (k->first), repo.prop_name_id (k->second)));
|
||||
}
|
||||
|
||||
db::PropertiesRepository org_repo = repo;
|
||||
|
||||
for (auto p = org_repo.begin (); p != org_repo.end (); ++p) {
|
||||
db::PropertiesRepository::properties_set new_set;
|
||||
for (auto i = p->second.begin (); i != p->second.end (); ++i) {
|
||||
auto nm = name_map.find (i->first);
|
||||
if (nm != name_map.end ()) {
|
||||
new_set.insert (std::make_pair (nm->second, i->second));
|
||||
}
|
||||
}
|
||||
if (! new_set.empty ()) {
|
||||
map.insert (std::make_pair (p->first, repo.properties_id (new_set)));
|
||||
}
|
||||
}
|
||||
|
||||
return PropertiesTranslator (map);
|
||||
}
|
||||
|
||||
|
||||
} // namespace db
|
||||
|
||||
|
|
|
|||
|
|
@ -239,6 +239,117 @@ private:
|
|||
db::LayoutStateModel *mp_state_model;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A map for selecting/translating properties
|
||||
*
|
||||
* The following rules apply:
|
||||
* - All non-mapped properties are mapped to 0 (removed)
|
||||
* - 0 is always mapped to 0
|
||||
* - Do not include key or value 0 in the map passed to the constructor
|
||||
*
|
||||
* A "pass translator" will pass all IDs unchanged.
|
||||
*
|
||||
* Note that a property translator - specifically the filters and
|
||||
* mappers created by "make_filter" and "make_key_mapper" - are snapshots.
|
||||
* As creating new filters will generate new property IDs for the mapping
|
||||
* targets, property translators generated previously may become invalid.
|
||||
* In general it is safe to concatenate new translators after old ones.
|
||||
* The old ones will not map the property IDs understood by the new ones,
|
||||
* but as such IDs cannot become input to the old translator, this should
|
||||
* not matter.
|
||||
*/
|
||||
|
||||
class DB_PUBLIC PropertiesTranslator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor - this creates a null translator
|
||||
*/
|
||||
PropertiesTranslator ();
|
||||
|
||||
/**
|
||||
* @brief Creates a "pass all" (pass = true) or "remove all" (pass = false) translator
|
||||
*/
|
||||
PropertiesTranslator (bool pass);
|
||||
|
||||
/**
|
||||
* @brief Creates a property ID mapper from a table
|
||||
*/
|
||||
PropertiesTranslator (const std::map<db::properties_id_type, db::properties_id_type> &map);
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the translator is "pass"
|
||||
*/
|
||||
bool is_pass () const
|
||||
{
|
||||
return m_pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the translator is "empty" (remove all)
|
||||
*/
|
||||
bool is_empty () const
|
||||
{
|
||||
return ! m_pass && m_map.empty ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the translator is "null" (default-constructed)
|
||||
*/
|
||||
bool is_null () const
|
||||
{
|
||||
return m_null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Concatenates two translators (the right one first)
|
||||
*/
|
||||
PropertiesTranslator operator* (const PropertiesTranslator &other) const;
|
||||
|
||||
/**
|
||||
* @brief Concatenates two translators (the right one first) - in place version
|
||||
*/
|
||||
PropertiesTranslator &operator*= (const PropertiesTranslator &other)
|
||||
{
|
||||
*this = this->operator* (other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Translation of the property ID
|
||||
*/
|
||||
db::properties_id_type operator() (db::properties_id_type id) const;
|
||||
|
||||
/**
|
||||
* @brief Factory: create a "remove all" translator
|
||||
*/
|
||||
static PropertiesTranslator make_remove_all ();
|
||||
|
||||
/**
|
||||
* @brief Factory: create a "pass all" translator
|
||||
*/
|
||||
static PropertiesTranslator make_pass_all ();
|
||||
|
||||
/**
|
||||
* @brief Factory: create a filter translator
|
||||
*
|
||||
* The translator delivered by this function will leave only the given keys in the properties.
|
||||
*/
|
||||
static PropertiesTranslator make_filter (db::PropertiesRepository &repo, const std::set<tl::Variant> &keys);
|
||||
|
||||
/**
|
||||
* @brief Factory: create a key mapper translator
|
||||
*
|
||||
* The translator delivered by this function will translate the given keys to new ones
|
||||
* and remove non-listed keys.
|
||||
*/
|
||||
static PropertiesTranslator make_key_mapper (db::PropertiesRepository &repo, const std::map<tl::Variant, tl::Variant> &keys);
|
||||
|
||||
private:
|
||||
std::map<db::properties_id_type, db::properties_id_type> m_map;
|
||||
bool m_pass, m_null;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Collect memory statistics
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ RecursiveShapeIterator &RecursiveShapeIterator::operator= (const RecursiveShapeI
|
|||
m_shape = d.m_shape;
|
||||
m_trans = d.m_trans;
|
||||
m_global_trans = d.m_global_trans;
|
||||
m_property_translator = d.m_property_translator;
|
||||
m_trans_stack = d.m_trans_stack;
|
||||
m_inst_iterators = d.m_inst_iterators;
|
||||
m_inst_array_iterators = d.m_inst_array_iterators;
|
||||
|
|
@ -284,6 +285,7 @@ RecursiveShapeIterator::init ()
|
|||
mp_cell = 0;
|
||||
m_current_layer = 0;
|
||||
m_global_trans = cplx_trans_type ();
|
||||
m_property_translator = db::PropertiesTranslator ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -320,6 +320,41 @@ public:
|
|||
return mp_top_cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the installed property translator
|
||||
*
|
||||
* The property translator is not automatically applied, but available to consumers
|
||||
* of shapes to perform property translation.
|
||||
*/
|
||||
const db::PropertiesTranslator &property_translator () const
|
||||
{
|
||||
return m_property_translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Applies a PropertyTranslator
|
||||
*
|
||||
* The property translator is available for receivers of the recursive shape
|
||||
* iterator items. This method will apply an additional property translator
|
||||
* atop of existing ones.
|
||||
*/
|
||||
void apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
m_property_translator = pt * m_property_translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a PropertyTranslator
|
||||
*
|
||||
* The property translator is available for receivers of the recursive shape
|
||||
* iterator items. This method will apply an additional property translator
|
||||
* atop of existing ones.
|
||||
*/
|
||||
void set_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
m_property_translator = pt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the basic region the iterator is using (will be world if none is set)
|
||||
* In addition to the basic region, a complex region may be defined that is further confining the
|
||||
|
|
@ -648,6 +683,21 @@ public:
|
|||
*/
|
||||
bool at_end () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the translated property ID
|
||||
*
|
||||
* This version employs the property translator to deliver the real property ID.
|
||||
*/
|
||||
db::properties_id_type prop_id () const
|
||||
{
|
||||
if (m_property_translator.is_null ()) {
|
||||
return 0;
|
||||
} else {
|
||||
validate (0);
|
||||
return m_property_translator (m_shape->prop_id ());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the current cell's index
|
||||
*/
|
||||
|
|
@ -765,6 +815,7 @@ private:
|
|||
bool m_overlapping;
|
||||
std::set<db::cell_index_type> m_start, m_stop;
|
||||
cplx_trans_type m_global_trans;
|
||||
db::PropertiesTranslator m_property_translator;
|
||||
|
||||
tl::weak_ptr<layout_type> mp_layout;
|
||||
const cell_type *mp_top_cell;
|
||||
|
|
|
|||
|
|
@ -109,22 +109,6 @@ Region::iter () const
|
|||
return *(i ? i : &def_iter);
|
||||
}
|
||||
|
||||
const db::PropertiesRepository &
|
||||
Region::properties_repository () const
|
||||
{
|
||||
static db::PropertiesRepository empty_prop_repo;
|
||||
const db::PropertiesRepository *r = delegate () ? delegate ()->properties_repository () : 0;
|
||||
return *(r ? r : &empty_prop_repo);
|
||||
}
|
||||
|
||||
db::PropertiesRepository &
|
||||
Region::properties_repository ()
|
||||
{
|
||||
db::PropertiesRepository *r = delegate () ? delegate ()->properties_repository () : 0;
|
||||
tl_assert (r != 0);
|
||||
return *r;
|
||||
}
|
||||
|
||||
void
|
||||
Region::set_delegate (RegionDelegate *delegate, bool keep_attributes)
|
||||
{
|
||||
|
|
@ -396,6 +380,8 @@ static void fill_texts (const Iter &iter, const std::string &pat, bool pattern,
|
|||
const db::Layout *layout = 0;
|
||||
|
||||
if (org_deep) {
|
||||
// NOTE: deep regions can store texts in a special way - as small boxes with a special property attached.
|
||||
// The property will give the text string. This function can restore these pseudo-texts as Text objects.
|
||||
layout = &org_deep->deep_layer ().layout ();
|
||||
const db::DeepShapeStore *store = org_deep->deep_layer ().store ();
|
||||
if (! store->text_property_name ().is_nil ()) {
|
||||
|
|
|
|||
|
|
@ -1796,20 +1796,6 @@ public:
|
|||
*/
|
||||
const db::RecursiveShapeIterator &iter () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the property repository
|
||||
*
|
||||
* Use this object to decode property IDs.
|
||||
*/
|
||||
const db::PropertiesRepository &properties_repository () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the property repository
|
||||
*
|
||||
* Use this object to decode and encode property IDs.
|
||||
*/
|
||||
db::PropertiesRepository &properties_repository ();
|
||||
|
||||
/**
|
||||
* @brief Equality
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -316,6 +316,8 @@ public:
|
|||
virtual bool has_valid_merged_polygons () const = 0;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const = 0;
|
||||
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt) = 0;
|
||||
virtual db::PropertiesRepository *properties_repository () = 0;
|
||||
virtual const db::PropertiesRepository *properties_repository () const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbShapeCollection.h"
|
||||
#include "dbPropertiesRepository.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------
|
||||
|
||||
DeepShapeCollectionDelegateBase::DeepShapeCollectionDelegateBase ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
DeepShapeCollectionDelegateBase::DeepShapeCollectionDelegateBase (const DeepShapeCollectionDelegateBase &other)
|
||||
{
|
||||
m_deep_layer = other.m_deep_layer.copy ();
|
||||
}
|
||||
|
||||
DeepShapeCollectionDelegateBase &
|
||||
DeepShapeCollectionDelegateBase::operator= (const DeepShapeCollectionDelegateBase &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
m_deep_layer = other.m_deep_layer.copy ();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
DeepShapeCollectionDelegateBase::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
db::Layout &layout = m_deep_layer.layout ();
|
||||
for (auto c = layout.begin (); c != layout.end (); ++c) {
|
||||
|
||||
db::Shapes &shapes = c->shapes (m_deep_layer.layer ());
|
||||
|
||||
db::Shapes new_shapes;
|
||||
new_shapes.assign (shapes, pt);
|
||||
shapes.swap (new_shapes);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------
|
||||
// ShapeCollection implementation
|
||||
|
||||
const db::PropertiesRepository &
|
||||
ShapeCollection::properties_repository () const
|
||||
{
|
||||
static db::PropertiesRepository empty_prop_repo;
|
||||
const db::PropertiesRepository *r = get_delegate () ? get_delegate ()->properties_repository () : 0;
|
||||
return *(r ? r : &empty_prop_repo);
|
||||
}
|
||||
|
||||
db::PropertiesRepository &
|
||||
ShapeCollection::properties_repository ()
|
||||
{
|
||||
db::PropertiesRepository *r = get_delegate () ? get_delegate ()->properties_repository () : 0;
|
||||
tl_assert (r != 0);
|
||||
return *r;
|
||||
}
|
||||
|
||||
void
|
||||
ShapeCollection::apply_property_translator (const db::PropertiesTranslator &pt)
|
||||
{
|
||||
if (get_delegate ()) {
|
||||
get_delegate ()->apply_property_translator (pt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -26,31 +26,25 @@
|
|||
#include "dbCommon.h"
|
||||
#include "dbDeepShapeStore.h"
|
||||
#include "tlUniqueId.h"
|
||||
#include "tlVariant.h"
|
||||
#include "gsiObject.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
class PropertiesTranslator;
|
||||
class PropertiesRepository;
|
||||
|
||||
/**
|
||||
* @brief A base class for the deep collection delegates
|
||||
*/
|
||||
class DB_PUBLIC DeepShapeCollectionDelegateBase
|
||||
{
|
||||
public:
|
||||
DeepShapeCollectionDelegateBase () { }
|
||||
DeepShapeCollectionDelegateBase ();
|
||||
DeepShapeCollectionDelegateBase (const DeepShapeCollectionDelegateBase &other);
|
||||
|
||||
DeepShapeCollectionDelegateBase (const DeepShapeCollectionDelegateBase &other)
|
||||
{
|
||||
m_deep_layer = other.m_deep_layer.copy ();
|
||||
}
|
||||
|
||||
DeepShapeCollectionDelegateBase &operator= (const DeepShapeCollectionDelegateBase &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
m_deep_layer = other.m_deep_layer.copy ();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
DeepShapeCollectionDelegateBase &operator= (const DeepShapeCollectionDelegateBase &other);
|
||||
|
||||
const db::DeepLayer &deep_layer () const
|
||||
{
|
||||
|
|
@ -62,6 +56,8 @@ public:
|
|||
return m_deep_layer;
|
||||
}
|
||||
|
||||
void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
|
||||
protected:
|
||||
virtual void set_deep_layer (const db::DeepLayer &dl)
|
||||
{
|
||||
|
|
@ -83,6 +79,10 @@ public:
|
|||
virtual ~ShapeCollectionDelegateBase () { }
|
||||
|
||||
virtual DeepShapeCollectionDelegateBase *deep () { return 0; }
|
||||
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator & /*pt*/) = 0;
|
||||
virtual db::PropertiesRepository *properties_repository () = 0;
|
||||
virtual const db::PropertiesRepository *properties_repository () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -96,6 +96,30 @@ public:
|
|||
virtual ~ShapeCollection () { }
|
||||
|
||||
virtual ShapeCollectionDelegateBase *get_delegate () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Applies a PropertyTranslator
|
||||
*
|
||||
* This method will translate the property IDs according to the given property translator.
|
||||
*
|
||||
* Note that the property translator needs to be built from the PropertiesRepository
|
||||
* delivered by "properties_repository".
|
||||
*/
|
||||
void apply_property_translator (const db::PropertiesTranslator &pt);
|
||||
|
||||
/**
|
||||
* @brief Gets the property repository
|
||||
*
|
||||
* Use this object to decode and encode property IDs.
|
||||
*/
|
||||
db::PropertiesRepository &properties_repository ();
|
||||
|
||||
/**
|
||||
* @brief Gets the property repository (const version)
|
||||
*
|
||||
* Use this object to decode property IDs.
|
||||
*/
|
||||
const db::PropertiesRepository &properties_repository () const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,7 +171,6 @@ public:
|
|||
Properties = (1 << Null),
|
||||
All = (1 << Null) - 1,
|
||||
AllWithProperties = (1 << (Null + 1)) - 1,
|
||||
RegardProperties = (1 << (Null + 1)), // special flag, not evaluated on query but in receiver (indicates to regard shapes with different properties as different entities)
|
||||
Nothing = 0
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ public:
|
|||
virtual bool has_valid_texts () const = 0;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const = 0;
|
||||
virtual void apply_property_translator (const db::PropertiesTranslator &pt) = 0;
|
||||
virtual db::PropertiesRepository *properties_repository () = 0;
|
||||
virtual const db::PropertiesRepository *properties_repository () const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_gsiDeclDbContainerHelpers
|
||||
#define HDR_gsiDeclDbContainerHelpers
|
||||
|
||||
#include "dbPropertiesRepository.h"
|
||||
#include "tlVariant.h"
|
||||
#include "gsiDecl.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
template <class Container>
|
||||
static void enable_properties (Container *c)
|
||||
{
|
||||
c->apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
static void remove_properties (Container *c)
|
||||
{
|
||||
c->apply_property_translator (db::PropertiesTranslator::make_remove_all ());
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
static void filter_properties (Container *c, const std::vector<tl::Variant> &keys)
|
||||
{
|
||||
std::set<tl::Variant> kf;
|
||||
kf.insert (keys.begin (), keys.end ());
|
||||
c->apply_property_translator (db::PropertiesTranslator::make_filter (c->properties_repository (), kf));
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
static void map_properties (Container *c, const std::map<tl::Variant, tl::Variant> &map)
|
||||
{
|
||||
c->apply_property_translator (db::PropertiesTranslator::make_key_mapper (c->properties_repository (), map));
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
static gsi::Methods
|
||||
make_property_methods ()
|
||||
{
|
||||
return
|
||||
gsi::method_ext ("enable_properties", &enable_properties<Container>,
|
||||
"@brief Enables properties for the given container.\n"
|
||||
"This method has an effect mainly on original layers and will import properties from such layers. "
|
||||
"By default, properties are not enabled on original layers. Alternatively you can apply \\filter_properties "
|
||||
"or \\map_properties to enable properties with a specific name key.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.28.4."
|
||||
) +
|
||||
gsi::method_ext ("remove_properties", &remove_properties<Container>,
|
||||
"@brief Removes properties for the given container.\n"
|
||||
"This will remove all properties on the given container.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.28.4."
|
||||
) +
|
||||
gsi::method_ext ("filter_properties", &filter_properties<Container>, gsi::arg ("keys"),
|
||||
"@brief Filters properties by certain keys.\n"
|
||||
"Calling this method on a container will reduce the properties to values with name keys from the 'keys' list.\n"
|
||||
"As a side effect, this method enables properties on original layers.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.28.4."
|
||||
) +
|
||||
gsi::method_ext ("map_properties", &map_properties<Container>, gsi::arg ("key_map"),
|
||||
"@brief Maps properties by name key.\n"
|
||||
"Calling this method on a container will reduce the properties to values with name keys from the 'keys' hash and "
|
||||
"renames the properties. Properties not listed in the key map will be removed.\n"
|
||||
"As a side effect, this method enables properties on original layers.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.28.4."
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -31,6 +31,8 @@
|
|||
#include "dbEdgesUtils.h"
|
||||
#include "dbEdgePairFilters.h"
|
||||
|
||||
#include "gsiDeclDbContainerHelpers.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
|
|
@ -912,7 +914,9 @@ Class<db::EdgePairs> decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
|
|||
method_ext ("to_s", &to_string1, gsi::arg ("max_count"),
|
||||
"@brief Converts the edge pair collection to a string\n"
|
||||
"This version allows specification of the maximum number of edge pairs contained in the string."
|
||||
),
|
||||
) +
|
||||
gsi::make_property_methods<db::EdgePairs> ()
|
||||
,
|
||||
"@brief EdgePairs (a collection of edge pairs)\n"
|
||||
"\n"
|
||||
"Edge pairs are used mainly in the context of the DRC functions (width_check, space_check etc.) of \\Region and \\Edges. "
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
#include "dbOriginalLayerRegion.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
|
||||
#include "gsiDeclDbContainerHelpers.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
|
|
@ -1750,7 +1752,9 @@ Class<db::Edges> decl_Edges (decl_dbShapeCollection, "db", "Edges",
|
|||
method ("disable_progress", &db::Edges::disable_progress,
|
||||
"@brief Disable progress reporting\n"
|
||||
"Calling this method will disable progress reporting. See \\enable_progress.\n"
|
||||
),
|
||||
) +
|
||||
gsi::make_property_methods<db::Edges> ()
|
||||
,
|
||||
"@brief A collection of edges (Not necessarily describing closed contours)\n"
|
||||
"\n\n"
|
||||
"This class was introduced to simplify operations on edges sets. "
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#include "dbCompoundOperation.h"
|
||||
#include "tlGlobPattern.h"
|
||||
|
||||
#include "gsiDeclDbContainerHelpers.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
|
@ -3030,7 +3032,9 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"This method is equivalent to \\Cell#fill_region, but is based on Region (with the cell being the first parameter).\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.27.\n"
|
||||
),
|
||||
) +
|
||||
gsi::make_property_methods<db::Region> ()
|
||||
,
|
||||
"@brief A region (a potentially complex area consisting of multiple polygons)\n"
|
||||
"\n\n"
|
||||
"This class was introduced to simplify operations on polygon sets like boolean or sizing operations. "
|
||||
|
|
|
|||
|
|
@ -448,7 +448,6 @@ static db::Layout *layout (db::Shapes *sh)
|
|||
|
||||
static unsigned int s_all () { return db::ShapeIterator::All; }
|
||||
static unsigned int s_all_with_properties () { return db::ShapeIterator::AllWithProperties; }
|
||||
static unsigned int s_regard_properties () { return db::ShapeIterator::RegardProperties; }
|
||||
static unsigned int s_properties () { return db::ShapeIterator::Properties; }
|
||||
static unsigned int s_polygons () { return db::ShapeIterator::Polygons; }
|
||||
static unsigned int s_regions () { return db::ShapeIterator::Regions; }
|
||||
|
|
@ -1336,10 +1335,6 @@ Class<db::Shapes> decl_Shapes ("db", "Shapes",
|
|||
gsi::method ("SProperties|#s_properties", &s_properties,
|
||||
"@brief Indicates that only shapes with properties shall be retrieved"
|
||||
) +
|
||||
gsi::method ("SRegardProperties|#s_regard_properties", &s_regard_properties,
|
||||
"@brief Special option to regard shapes with different properties as different entities (used by \\Region for example).\n"
|
||||
"This option has been introduced in version 0.28.4.\n"
|
||||
) +
|
||||
gsi::method_ext ("dump_mem_statistics", &dump_mem_statistics, gsi::arg<bool> ("detailed", false),
|
||||
"@hide"
|
||||
),
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include "dbDeepTexts.h"
|
||||
#include "dbTextsUtils.h"
|
||||
|
||||
#include "gsiDeclDbContainerHelpers.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
|
|
@ -506,7 +508,9 @@ Class<db::Texts> decl_Texts (decl_dbShapeCollection, "db", "Texts",
|
|||
method_ext ("to_s", &to_string1, gsi::arg ("max_count"),
|
||||
"@brief Converts the text collection to a string\n"
|
||||
"This version allows specification of the maximum number of texts contained in the string."
|
||||
),
|
||||
) +
|
||||
gsi::make_property_methods<db::Texts> ()
|
||||
,
|
||||
"@brief Texts (a collection of texts)\n"
|
||||
"\n"
|
||||
"Text objects are useful as labels for net names, to identify certain regions and to specify specific locations in general. "
|
||||
|
|
|
|||
|
|
@ -1660,15 +1660,15 @@ TEST(40_BoolWithProperties)
|
|||
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0)); // empty
|
||||
|
||||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1 (si1);
|
||||
|
||||
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
|
||||
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r2 (si2);
|
||||
|
||||
db::RecursiveShapeIterator si3 (ly, top_cell, l3);
|
||||
si3.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si3.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r3 (si3);
|
||||
|
||||
db::Layout target;
|
||||
|
|
@ -1735,7 +1735,7 @@ TEST(41_EdgesWithProperties)
|
|||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
|
||||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1wp (si1);
|
||||
db::Region r1wp_nomerge = r1wp;
|
||||
r1wp_nomerge.set_merged_semantics (false);
|
||||
|
|
@ -1744,7 +1744,7 @@ TEST(41_EdgesWithProperties)
|
|||
db::Region r1 (si1);
|
||||
|
||||
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
|
||||
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r2wp (si2);
|
||||
db::Region r2wp_nomerge = r2wp;
|
||||
r2wp_nomerge.set_merged_semantics (false);
|
||||
|
|
@ -1788,13 +1788,13 @@ TEST(42_DRCWithProperties)
|
|||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
|
||||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1 (si1);
|
||||
db::Region r1_nomerge (r1);
|
||||
r1_nomerge.set_merged_semantics (false);
|
||||
|
||||
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
|
||||
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r2 (si2);
|
||||
db::Region r2_nomerge (r2);
|
||||
r2_nomerge.set_merged_semantics (false);
|
||||
|
|
@ -1857,11 +1857,11 @@ TEST(43_ComplexOpsWithProperties)
|
|||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
|
||||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1 (si1);
|
||||
|
||||
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
|
||||
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r2 (si2);
|
||||
|
||||
db::Layout target;
|
||||
|
|
@ -1922,11 +1922,11 @@ TEST(44_SizeWithProperties)
|
|||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
|
||||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1 (si1);
|
||||
|
||||
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
|
||||
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r2 (si2);
|
||||
|
||||
db::Layout target;
|
||||
|
|
|
|||
|
|
@ -2148,15 +2148,15 @@ TEST(40_BoolWithProperties)
|
|||
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0)); // empty
|
||||
|
||||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1 (si1, dss);
|
||||
|
||||
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
|
||||
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r2 (si2, dss);
|
||||
|
||||
db::RecursiveShapeIterator si3 (ly, top_cell, l3);
|
||||
si3.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si3.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r3 (si3, dss);
|
||||
|
||||
db::Layout target;
|
||||
|
|
@ -2225,7 +2225,7 @@ TEST(41_EdgesWithProperties)
|
|||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
|
||||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1wp (si1, dss);
|
||||
db::Region r1wp_nomerge = r1wp;
|
||||
r1wp_nomerge.set_merged_semantics (false);
|
||||
|
|
@ -2234,7 +2234,7 @@ TEST(41_EdgesWithProperties)
|
|||
db::Region r1 (si1, dss);
|
||||
|
||||
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
|
||||
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r2wp (si2, dss);
|
||||
db::Region r2wp_nomerge = r2wp;
|
||||
r2wp_nomerge.set_merged_semantics (false);
|
||||
|
|
@ -2280,13 +2280,13 @@ TEST(42_DRCWithProperties)
|
|||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
|
||||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1 (si1, dss);
|
||||
db::Region r1_nomerge (r1);
|
||||
r1_nomerge.set_merged_semantics (false);
|
||||
|
||||
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
|
||||
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r2 (si2, dss);
|
||||
db::Region r2_nomerge (r2);
|
||||
r2_nomerge.set_merged_semantics (false);
|
||||
|
|
@ -2351,11 +2351,11 @@ TEST(43_ComplexOpsWithProperties)
|
|||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
|
||||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1 (si1, dss);
|
||||
|
||||
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
|
||||
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r2 (si2, dss);
|
||||
|
||||
db::Layout target;
|
||||
|
|
@ -2418,11 +2418,11 @@ TEST(44_SizeWithProperties)
|
|||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
|
||||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1 (si1, dss);
|
||||
|
||||
db::RecursiveShapeIterator si2 (ly, top_cell, l2);
|
||||
si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r2 (si2, dss);
|
||||
|
||||
db::Layout target;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
|
||||
#include "dbPropertiesRepository.h"
|
||||
#include "dbTestSupport.h"
|
||||
#include "tlString.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
|
|
@ -259,3 +260,135 @@ TEST(6)
|
|||
EXPECT_EQ (pid2, size_t (2));
|
||||
}
|
||||
|
||||
|
||||
TEST(10_PropertiesTranslator)
|
||||
{
|
||||
EXPECT_EQ (db::PropertiesTranslator ().is_null (), true);
|
||||
EXPECT_EQ (db::PropertiesTranslator ().is_pass (), true);
|
||||
EXPECT_EQ (db::PropertiesTranslator ().is_empty (), false);
|
||||
EXPECT_EQ (db::PropertiesTranslator::make_pass_all ().is_null (), false);
|
||||
EXPECT_EQ (db::PropertiesTranslator::make_pass_all ().is_pass (), true);
|
||||
EXPECT_EQ (db::PropertiesTranslator::make_pass_all ().is_empty (), false);
|
||||
EXPECT_EQ (db::PropertiesTranslator::make_remove_all ().is_null (), false);
|
||||
EXPECT_EQ (db::PropertiesTranslator::make_remove_all ().is_pass (), false);
|
||||
EXPECT_EQ (db::PropertiesTranslator::make_remove_all ().is_empty (), true);
|
||||
|
||||
db::PropertiesRepository rp;
|
||||
db::property_names_id_type key1 = rp.prop_name_id (1);
|
||||
db::property_names_id_type key2 = rp.prop_name_id (2);
|
||||
db::property_names_id_type key3 = rp.prop_name_id (3);
|
||||
|
||||
db::PropertiesRepository::properties_set ps;
|
||||
ps.insert (std::make_pair (key1, 100));
|
||||
ps.insert (std::make_pair (key2, 101));
|
||||
db::properties_id_type prop1a = rp.properties_id (ps);
|
||||
EXPECT_EQ (prop2string (rp, prop1a), "1=100\n2=101");
|
||||
|
||||
ps.clear ();
|
||||
ps.insert (std::make_pair (key1, 0));
|
||||
ps.insert (std::make_pair (key2, 101));
|
||||
db::properties_id_type prop1b = rp.properties_id (ps);
|
||||
EXPECT_EQ (prop2string (rp, prop1b), "1=0\n2=101");
|
||||
|
||||
ps.clear ();
|
||||
ps.insert (std::make_pair (key1, 100));
|
||||
ps.insert (std::make_pair (key3, 102));
|
||||
db::properties_id_type prop2 = rp.properties_id (ps);
|
||||
EXPECT_EQ (prop2string (rp, prop2), "1=100\n3=102");
|
||||
|
||||
ps.clear ();
|
||||
ps.insert (std::make_pair (key1, 100));
|
||||
db::properties_id_type prop3 = rp.properties_id (ps);
|
||||
EXPECT_EQ (prop2string (rp, prop3), "1=100");
|
||||
|
||||
db::PropertiesRepository rp_org = rp;
|
||||
|
||||
db::PropertiesTranslator t;
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100\n2=101");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0\n2=101");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "1=100\n3=102");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "1=100");
|
||||
|
||||
t = db::PropertiesTranslator::make_pass_all ();
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100\n2=101");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0\n2=101");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "1=100\n3=102");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "1=100");
|
||||
|
||||
t = db::PropertiesTranslator::make_remove_all ();
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "");
|
||||
|
||||
std::set<tl::Variant> kf;
|
||||
kf.insert (1);
|
||||
t = db::PropertiesTranslator::make_filter (rp, kf);
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "1=100");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "1=100");
|
||||
|
||||
kf.insert (3);
|
||||
t = db::PropertiesTranslator::make_filter (rp, kf);
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "1=100\n3=102");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "1=100");
|
||||
|
||||
std::map<tl::Variant, tl::Variant> km;
|
||||
km[1] = 4;
|
||||
km[3] = 1;
|
||||
|
||||
t = db::PropertiesTranslator::make_key_mapper (rp, km);
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "4=100");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "4=0");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "1=102\n4=100");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "4=100");
|
||||
|
||||
kf.clear ();
|
||||
kf.insert (4);
|
||||
t = db::PropertiesTranslator::make_filter (rp, kf) * db::PropertiesTranslator::make_key_mapper (rp, km);
|
||||
EXPECT_EQ (t.is_empty (), false);
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "4=100");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "4=0");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "4=100");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "4=100");
|
||||
|
||||
kf.clear ();
|
||||
kf.insert (3);
|
||||
|
||||
t = db::PropertiesTranslator::make_filter (rp, kf) * db::PropertiesTranslator::make_key_mapper (rp, km);
|
||||
EXPECT_EQ (t.is_empty (), true);
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "");
|
||||
|
||||
t = db::PropertiesTranslator::make_key_mapper (rp, km) * db::PropertiesTranslator::make_filter (rp, kf);
|
||||
EXPECT_EQ (t.is_empty (), false);
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "1=102");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "");
|
||||
|
||||
rp = rp_org;
|
||||
|
||||
t = db::PropertiesTranslator::make_key_mapper (rp, km);
|
||||
t = db::PropertiesTranslator::make_filter (rp, kf) * t;
|
||||
EXPECT_EQ (t.is_empty (), true);
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "");
|
||||
|
||||
rp = rp_org;
|
||||
|
||||
t = db::PropertiesTranslator::make_filter (rp, kf);
|
||||
t = db::PropertiesTranslator::make_key_mapper (rp, km) * t;
|
||||
EXPECT_EQ (t.is_empty (), false);
|
||||
EXPECT_EQ (prop2string (rp, t (prop1a)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop1b)), "");
|
||||
EXPECT_EQ (prop2string (rp, t (prop2)), "1=102");
|
||||
EXPECT_EQ (prop2string (rp, t (prop3)), "");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2153,7 +2153,7 @@ TEST(51_PropertiesFlatFromLayout)
|
|||
|
||||
// NOTE: now with regarding properties
|
||||
rsi = db::RecursiveShapeIterator (ly, top, li);
|
||||
rsi.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
rsi.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
r = db::Region (rsi);
|
||||
|
||||
EXPECT_EQ (r.count (), size_t (4));
|
||||
|
|
@ -2340,7 +2340,7 @@ TEST(53_PropertiesDeepFromLayout)
|
|||
|
||||
// NOTE: now with regarding properties
|
||||
rsi = db::RecursiveShapeIterator (ly, top, li);
|
||||
rsi.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties);
|
||||
rsi.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
r = db::Region (rsi, dss);
|
||||
|
||||
EXPECT_EQ (r.count (), size_t (4));
|
||||
|
|
|
|||
Loading…
Reference in New Issue