mirror of https://github.com/KLayout/klayout.git
WIP: trying to enhance layout layer lookup performance.
This commit is contained in:
parent
199dea536a
commit
ad27c9a51d
300
src/db/db/db.pro
300
src/db/db/db.pro
|
|
@ -39,6 +39,7 @@ SOURCES = \
|
||||||
dbLayerMapping.cc \
|
dbLayerMapping.cc \
|
||||||
dbLayerProperties.cc \
|
dbLayerProperties.cc \
|
||||||
dbLayout.cc \
|
dbLayout.cc \
|
||||||
|
dbLayoutLayers.cc \
|
||||||
dbLayoutContextHandler.cc \
|
dbLayoutContextHandler.cc \
|
||||||
dbLayoutDiff.cc \
|
dbLayoutDiff.cc \
|
||||||
dbLayoutQuery.cc \
|
dbLayoutQuery.cc \
|
||||||
|
|
@ -138,85 +139,85 @@ SOURCES = \
|
||||||
gsiDeclDbVector.cc \
|
gsiDeclDbVector.cc \
|
||||||
gsiDeclDbLayoutDiff.cc \
|
gsiDeclDbLayoutDiff.cc \
|
||||||
gsiDeclDbGlyphs.cc \
|
gsiDeclDbGlyphs.cc \
|
||||||
dbConverters.cc \
|
dbConverters.cc \
|
||||||
dbAsIfFlatRegion.cc \
|
dbAsIfFlatRegion.cc \
|
||||||
dbEmptyRegion.cc \
|
dbEmptyRegion.cc \
|
||||||
dbFlatRegion.cc \
|
dbFlatRegion.cc \
|
||||||
dbOriginalLayerRegion.cc \
|
dbOriginalLayerRegion.cc \
|
||||||
dbRegionDelegate.cc \
|
dbRegionDelegate.cc \
|
||||||
dbEdgesDelegate.cc \
|
dbEdgesDelegate.cc \
|
||||||
dbEmptyEdges.cc \
|
dbEmptyEdges.cc \
|
||||||
dbAsIfFlatEdges.cc \
|
dbAsIfFlatEdges.cc \
|
||||||
dbFlatEdges.cc \
|
dbFlatEdges.cc \
|
||||||
dbEdgeBoolean.cc \
|
dbEdgeBoolean.cc \
|
||||||
dbOriginalLayerEdges.cc \
|
dbOriginalLayerEdges.cc \
|
||||||
dbAsIfFlatEdgePairs.cc \
|
dbAsIfFlatEdgePairs.cc \
|
||||||
dbEmptyEdgePairs.cc \
|
dbEmptyEdgePairs.cc \
|
||||||
dbFlatEdgePairs.cc \
|
dbFlatEdgePairs.cc \
|
||||||
dbOriginalLayerEdgePairs.cc \
|
dbOriginalLayerEdgePairs.cc \
|
||||||
dbEdgePairsDelegate.cc \
|
dbEdgePairsDelegate.cc \
|
||||||
dbDeepShapeStore.cc \
|
dbDeepShapeStore.cc \
|
||||||
dbHierarchyBuilder.cc \
|
dbHierarchyBuilder.cc \
|
||||||
dbLocalOperation.cc \
|
dbLocalOperation.cc \
|
||||||
dbHierProcessor.cc \
|
dbHierProcessor.cc \
|
||||||
dbDeepRegion.cc \
|
dbDeepRegion.cc \
|
||||||
dbHierNetworkProcessor.cc \
|
dbHierNetworkProcessor.cc \
|
||||||
dbNetlist.cc \
|
dbNetlist.cc \
|
||||||
gsiDeclDbNetlist.cc \
|
gsiDeclDbNetlist.cc \
|
||||||
dbNetlistDeviceClasses.cc \
|
dbNetlistDeviceClasses.cc \
|
||||||
dbNetlistDeviceExtractor.cc \
|
dbNetlistDeviceExtractor.cc \
|
||||||
dbNetlistExtractor.cc \
|
dbNetlistExtractor.cc \
|
||||||
gsiDeclDbNetlistDeviceClasses.cc \
|
gsiDeclDbNetlistDeviceClasses.cc \
|
||||||
gsiDeclDbNetlistDeviceExtractor.cc \
|
gsiDeclDbNetlistDeviceExtractor.cc \
|
||||||
gsiDeclDbHierNetworkProcessor.cc \
|
gsiDeclDbHierNetworkProcessor.cc \
|
||||||
dbNetlistDeviceExtractorClasses.cc \
|
dbNetlistDeviceExtractorClasses.cc \
|
||||||
dbLayoutToNetlist.cc \
|
dbLayoutToNetlist.cc \
|
||||||
gsiDeclDbLayoutToNetlist.cc \
|
gsiDeclDbLayoutToNetlist.cc \
|
||||||
dbCircuit.cc \
|
dbCircuit.cc \
|
||||||
dbDevice.cc \
|
dbDevice.cc \
|
||||||
dbDeviceClass.cc \
|
dbDeviceClass.cc \
|
||||||
dbNet.cc \
|
dbNet.cc \
|
||||||
dbSubCircuit.cc \
|
dbSubCircuit.cc \
|
||||||
dbPin.cc \
|
dbPin.cc \
|
||||||
dbLayoutToNetlistReader.cc \
|
dbLayoutToNetlistReader.cc \
|
||||||
dbLayoutToNetlistWriter.cc \
|
dbLayoutToNetlistWriter.cc \
|
||||||
dbLayoutToNetlistFormatDefs.cc \
|
dbLayoutToNetlistFormatDefs.cc \
|
||||||
dbDeviceAbstract.cc \
|
dbDeviceAbstract.cc \
|
||||||
dbLocalOperationUtils.cc \
|
dbLocalOperationUtils.cc \
|
||||||
gsiDeclDbDeepShapeStore.cc \
|
gsiDeclDbDeepShapeStore.cc \
|
||||||
dbNetlistSpiceWriter.cc \
|
dbNetlistSpiceWriter.cc \
|
||||||
dbNetlistWriter.cc \
|
dbNetlistWriter.cc \
|
||||||
dbCellVariants.cc \
|
dbCellVariants.cc \
|
||||||
dbDeepEdges.cc \
|
dbDeepEdges.cc \
|
||||||
dbDeepEdgePairs.cc \
|
dbDeepEdgePairs.cc \
|
||||||
dbRegionUtils.cc \
|
dbRegionUtils.cc \
|
||||||
dbEdgesUtils.cc \
|
dbEdgesUtils.cc \
|
||||||
dbRegionProcessors.cc \
|
dbRegionProcessors.cc \
|
||||||
dbNetlistCompare.cc \
|
dbNetlistCompare.cc \
|
||||||
dbNetlistReader.cc \
|
dbNetlistReader.cc \
|
||||||
dbNetlistSpiceReader.cc \
|
dbNetlistSpiceReader.cc \
|
||||||
gsiDeclDbNetlistCompare.cc \
|
gsiDeclDbNetlistCompare.cc \
|
||||||
dbNetlistCrossReference.cc \
|
dbNetlistCrossReference.cc \
|
||||||
dbLayoutVsSchematicWriter.cc \
|
dbLayoutVsSchematicWriter.cc \
|
||||||
dbLayoutVsSchematicReader.cc \
|
dbLayoutVsSchematicReader.cc \
|
||||||
dbLayoutVsSchematicFormatDefs.cc \
|
dbLayoutVsSchematicFormatDefs.cc \
|
||||||
dbLayoutVsSchematic.cc \
|
dbLayoutVsSchematic.cc \
|
||||||
gsiDeclDbNetlistCrossReference.cc \
|
gsiDeclDbNetlistCrossReference.cc \
|
||||||
gsiDeclDbLayoutVsSchematic.cc \
|
gsiDeclDbLayoutVsSchematic.cc \
|
||||||
dbNetlistObject.cc \
|
dbNetlistObject.cc \
|
||||||
gsiDeclDbTexts.cc \
|
gsiDeclDbTexts.cc \
|
||||||
dbTexts.cc \
|
dbTexts.cc \
|
||||||
dbDeepTexts.cc \
|
dbDeepTexts.cc \
|
||||||
dbAsIfFlatTexts.cc \
|
dbAsIfFlatTexts.cc \
|
||||||
dbTextsDelegate.cc \
|
dbTextsDelegate.cc \
|
||||||
dbEmptyTexts.cc \
|
dbEmptyTexts.cc \
|
||||||
dbFlatTexts.cc \
|
dbFlatTexts.cc \
|
||||||
dbTextsUtils.cc \
|
dbTextsUtils.cc \
|
||||||
dbOriginalLayerTexts.cc \
|
dbOriginalLayerTexts.cc \
|
||||||
dbNetShape.cc \
|
dbNetShape.cc \
|
||||||
dbShapeCollection.cc \
|
dbShapeCollection.cc \
|
||||||
gsiDeclDbShapeCollection.cc \
|
gsiDeclDbShapeCollection.cc \
|
||||||
dbShapeCollectionUtils.cc
|
dbShapeCollectionUtils.cc
|
||||||
|
|
||||||
HEADERS = \
|
HEADERS = \
|
||||||
dbArray.h \
|
dbArray.h \
|
||||||
|
|
@ -256,6 +257,7 @@ HEADERS = \
|
||||||
dbLayerProperties.h \
|
dbLayerProperties.h \
|
||||||
dbLayoutDiff.h \
|
dbLayoutDiff.h \
|
||||||
dbLayout.h \
|
dbLayout.h \
|
||||||
|
dbLayoutLayers.h \
|
||||||
dbLayoutQuery.h \
|
dbLayoutQuery.h \
|
||||||
dbLayoutStateModel.h \
|
dbLayoutStateModel.h \
|
||||||
dbLayoutUtils.h \
|
dbLayoutUtils.h \
|
||||||
|
|
@ -321,76 +323,76 @@ HEADERS = \
|
||||||
dbForceLink.h \
|
dbForceLink.h \
|
||||||
dbPlugin.h \
|
dbPlugin.h \
|
||||||
dbInit.h \
|
dbInit.h \
|
||||||
dbConverters.h \
|
dbConverters.h \
|
||||||
dbAsIfFlatRegion.h \
|
dbAsIfFlatRegion.h \
|
||||||
dbEmptyRegion.h \
|
dbEmptyRegion.h \
|
||||||
dbFlatRegion.h \
|
dbFlatRegion.h \
|
||||||
dbOriginalLayerRegion.h \
|
dbOriginalLayerRegion.h \
|
||||||
dbRegionDelegate.h \
|
dbRegionDelegate.h \
|
||||||
dbEdgesDelegate.h \
|
dbEdgesDelegate.h \
|
||||||
dbEmptyEdges.h \
|
dbEmptyEdges.h \
|
||||||
dbAsIfFlatEdges.h \
|
dbAsIfFlatEdges.h \
|
||||||
dbFlatEdges.h \
|
dbFlatEdges.h \
|
||||||
dbEdgeBoolean.h \
|
dbEdgeBoolean.h \
|
||||||
dbOriginalLayerEdges.h \
|
dbOriginalLayerEdges.h \
|
||||||
dbAsIfFlatEdgePairs.h \
|
dbAsIfFlatEdgePairs.h \
|
||||||
dbEmptyEdgePairs.h \
|
dbEmptyEdgePairs.h \
|
||||||
dbFlatEdgePairs.h \
|
dbFlatEdgePairs.h \
|
||||||
dbOriginalLayerEdgePairs.h \
|
dbOriginalLayerEdgePairs.h \
|
||||||
dbEdgePairsDelegate.h \
|
dbEdgePairsDelegate.h \
|
||||||
dbDeepShapeStore.h \
|
dbDeepShapeStore.h \
|
||||||
dbHierarchyBuilder.h \
|
dbHierarchyBuilder.h \
|
||||||
dbLocalOperation.h \
|
dbLocalOperation.h \
|
||||||
dbHierProcessor.h \
|
dbHierProcessor.h \
|
||||||
dbNetlist.h \
|
dbNetlist.h \
|
||||||
dbNetlistDeviceClasses.h \
|
dbNetlistDeviceClasses.h \
|
||||||
dbNetlistDeviceExtractor.h \
|
dbNetlistDeviceExtractor.h \
|
||||||
dbNetlistExtractor.h \
|
dbNetlistExtractor.h \
|
||||||
dbNetlistDeviceExtractorClasses.h \
|
dbNetlistDeviceExtractorClasses.h \
|
||||||
dbLayoutToNetlist.h \
|
dbLayoutToNetlist.h \
|
||||||
dbHierNetworkProcessor.h \
|
dbHierNetworkProcessor.h \
|
||||||
dbNetlistUtils.h \
|
dbNetlistUtils.h \
|
||||||
dbNet.h \
|
dbNet.h \
|
||||||
dbCircuit.h \
|
dbCircuit.h \
|
||||||
dbDevice.h \
|
dbDevice.h \
|
||||||
dbDeviceClass.h \
|
dbDeviceClass.h \
|
||||||
dbPin.h \
|
dbPin.h \
|
||||||
dbSubCircuit.h \
|
dbSubCircuit.h \
|
||||||
dbLayoutToNetlistReader.h \
|
dbLayoutToNetlistReader.h \
|
||||||
dbLayoutToNetlistWriter.h \
|
dbLayoutToNetlistWriter.h \
|
||||||
dbLayoutToNetlistFormatDefs.h \
|
dbLayoutToNetlistFormatDefs.h \
|
||||||
dbDeviceAbstract.h \
|
dbDeviceAbstract.h \
|
||||||
dbLocalOperationUtils.h \
|
dbLocalOperationUtils.h \
|
||||||
dbDeepRegion.h \
|
dbDeepRegion.h \
|
||||||
dbNetlistSpiceWriter.h \
|
dbNetlistSpiceWriter.h \
|
||||||
dbNetlistWriter.h \
|
dbNetlistWriter.h \
|
||||||
dbCellVariants.h \
|
dbCellVariants.h \
|
||||||
dbDeepEdges.h \
|
dbDeepEdges.h \
|
||||||
dbDeepEdgePairs.h \
|
dbDeepEdgePairs.h \
|
||||||
dbRegionUtils.h \
|
dbRegionUtils.h \
|
||||||
dbEdgesUtils.h \
|
dbEdgesUtils.h \
|
||||||
dbRegionProcessors.h \
|
dbRegionProcessors.h \
|
||||||
gsiDeclDbHelpers.h \
|
gsiDeclDbHelpers.h \
|
||||||
dbNetlistCompare.h \
|
dbNetlistCompare.h \
|
||||||
dbNetlistReader.h \
|
dbNetlistReader.h \
|
||||||
dbNetlistSpiceReader.h \
|
dbNetlistSpiceReader.h \
|
||||||
dbNetlistCrossReference.h \
|
dbNetlistCrossReference.h \
|
||||||
dbLayoutVsSchematicWriter.h \
|
dbLayoutVsSchematicWriter.h \
|
||||||
dbLayoutVsSchematicReader.h \
|
dbLayoutVsSchematicReader.h \
|
||||||
dbLayoutVsSchematicFormatDefs.h \
|
dbLayoutVsSchematicFormatDefs.h \
|
||||||
dbLayoutVsSchematic.h \
|
dbLayoutVsSchematic.h \
|
||||||
dbNetlistObject.h \
|
dbNetlistObject.h \
|
||||||
dbTexts.h \
|
dbTexts.h \
|
||||||
dbDeepTexts.h \
|
dbDeepTexts.h \
|
||||||
dbAsIfFlatTexts.h \
|
dbAsIfFlatTexts.h \
|
||||||
dbTextsDelegate.h \
|
dbTextsDelegate.h \
|
||||||
dbEmptyTexts.h \
|
dbEmptyTexts.h \
|
||||||
dbFlatTexts.h \
|
dbFlatTexts.h \
|
||||||
dbTextsUtils.h \
|
dbTextsUtils.h \
|
||||||
dbOriginalLayerTexts.h \
|
dbOriginalLayerTexts.h \
|
||||||
dbNetShape.h \
|
dbNetShape.h \
|
||||||
dbShapeCollection.h \
|
dbShapeCollection.h \
|
||||||
dbShapeCollectionUtils.h
|
dbShapeCollectionUtils.h
|
||||||
|
|
||||||
!equals(HAVE_QT, "0") || !equals(HAVE_PYTHON, "0") {
|
!equals(HAVE_QT, "0") || !equals(HAVE_PYTHON, "0") {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -255,92 +255,6 @@ private:
|
||||||
bool m_insert;
|
bool m_insert;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// Implementation of the LayerIterator class
|
|
||||||
|
|
||||||
LayerIterator::LayerIterator (unsigned int layer_index, const db::Layout &layout)
|
|
||||||
: m_layer_index (layer_index), m_layout (layout)
|
|
||||||
{
|
|
||||||
while (m_layer_index < m_layout.layers () && ! m_layout.is_valid_layer (m_layer_index)) {
|
|
||||||
++m_layer_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerIterator &
|
|
||||||
LayerIterator::operator++()
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
++m_layer_index;
|
|
||||||
} while (m_layer_index < m_layout.layers () && ! m_layout.is_valid_layer (m_layer_index));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<unsigned int, const db::LayerProperties *>
|
|
||||||
LayerIterator::operator*() const
|
|
||||||
{
|
|
||||||
return std::pair<unsigned int, const db::LayerProperties *> (m_layer_index, &m_layout.get_properties (m_layer_index));
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// Implementation of the ProxyContextInfo class
|
|
||||||
|
|
||||||
ProxyContextInfo
|
|
||||||
ProxyContextInfo::deserialize (std::vector<std::string>::const_iterator from, std::vector<std::string>::const_iterator to)
|
|
||||||
{
|
|
||||||
ProxyContextInfo info;
|
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator i = from; i != to; ++i) {
|
|
||||||
|
|
||||||
tl::Extractor ex (i->c_str ());
|
|
||||||
|
|
||||||
if (ex.test ("LIB=")) {
|
|
||||||
|
|
||||||
info.lib_name = ex.skip ();
|
|
||||||
|
|
||||||
} else if (ex.test ("P(")) {
|
|
||||||
|
|
||||||
std::pair<std::string, tl::Variant> vv;
|
|
||||||
|
|
||||||
ex.read_word_or_quoted (vv.first);
|
|
||||||
ex.test (")");
|
|
||||||
ex.test ("=");
|
|
||||||
ex.read (vv.second);
|
|
||||||
|
|
||||||
info.pcell_parameters.insert (vv);
|
|
||||||
|
|
||||||
} else if (ex.test ("PCELL=")) {
|
|
||||||
|
|
||||||
info.pcell_name = ex.skip ();
|
|
||||||
|
|
||||||
} else if (ex.test ("CELL=")) {
|
|
||||||
|
|
||||||
info.cell_name = ex.skip ();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ProxyContextInfo::serialize (std::vector<std::string> &strings)
|
|
||||||
{
|
|
||||||
if (! lib_name.empty ()) {
|
|
||||||
strings.push_back ("LIB=" + lib_name);
|
|
||||||
}
|
|
||||||
for (std::map<std::string, tl::Variant> ::const_iterator p = pcell_parameters.begin (); p != pcell_parameters.end (); ++p) {
|
|
||||||
strings.push_back ("P(" + tl::to_word_or_quoted_string (p->first) + ")=" + p->second.to_parsable_string ());
|
|
||||||
}
|
|
||||||
if (! pcell_name.empty ()) {
|
|
||||||
strings.push_back ("PCELL=" + pcell_name);
|
|
||||||
}
|
|
||||||
if (! cell_name.empty ()) {
|
|
||||||
strings.push_back ("CELL=" + cell_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
// Implementation of the Layout class
|
// Implementation of the Layout class
|
||||||
|
|
||||||
|
|
@ -353,9 +267,6 @@ Layout::Layout (db::Manager *manager)
|
||||||
m_dbu (0.001),
|
m_dbu (0.001),
|
||||||
m_prop_id (0),
|
m_prop_id (0),
|
||||||
m_properties_repository (this),
|
m_properties_repository (this),
|
||||||
m_guiding_shape_layer (-1),
|
|
||||||
m_waste_layer (-1),
|
|
||||||
m_error_layer (-1),
|
|
||||||
m_do_cleanup (false),
|
m_do_cleanup (false),
|
||||||
m_editable (db::default_editable_mode ())
|
m_editable (db::default_editable_mode ())
|
||||||
{
|
{
|
||||||
|
|
@ -371,9 +282,6 @@ Layout::Layout (bool editable, db::Manager *manager)
|
||||||
m_dbu (0.001),
|
m_dbu (0.001),
|
||||||
m_prop_id (0),
|
m_prop_id (0),
|
||||||
m_properties_repository (this),
|
m_properties_repository (this),
|
||||||
m_guiding_shape_layer (-1),
|
|
||||||
m_waste_layer (-1),
|
|
||||||
m_error_layer (-1),
|
|
||||||
m_do_cleanup (false),
|
m_do_cleanup (false),
|
||||||
m_editable (editable)
|
m_editable (editable)
|
||||||
{
|
{
|
||||||
|
|
@ -393,9 +301,6 @@ Layout::Layout (const db::Layout &layout)
|
||||||
m_dbu (0.001),
|
m_dbu (0.001),
|
||||||
m_prop_id (0),
|
m_prop_id (0),
|
||||||
m_properties_repository (this),
|
m_properties_repository (this),
|
||||||
m_guiding_shape_layer (-1),
|
|
||||||
m_waste_layer (-1),
|
|
||||||
m_error_layer (-1),
|
|
||||||
m_do_cleanup (false),
|
m_do_cleanup (false),
|
||||||
m_editable (layout.m_editable)
|
m_editable (layout.m_editable)
|
||||||
{
|
{
|
||||||
|
|
@ -437,8 +342,7 @@ Layout::clear ()
|
||||||
|
|
||||||
m_top_down_list.clear ();
|
m_top_down_list.clear ();
|
||||||
|
|
||||||
m_free_indices.clear ();
|
m_layers.clear ();
|
||||||
m_layer_states.clear ();
|
|
||||||
|
|
||||||
for (std::vector<const char *>::const_iterator p = m_cell_names.begin (); p != m_cell_names.end (); ++p) {
|
for (std::vector<const char *>::const_iterator p = m_cell_names.begin (); p != m_cell_names.end (); ++p) {
|
||||||
if (*p) {
|
if (*p) {
|
||||||
|
|
@ -459,10 +363,6 @@ Layout::clear ()
|
||||||
m_pcells.clear ();
|
m_pcells.clear ();
|
||||||
m_pcell_ids.clear ();
|
m_pcell_ids.clear ();
|
||||||
|
|
||||||
m_guiding_shape_layer = -1;
|
|
||||||
m_waste_layer = -1;
|
|
||||||
m_error_layer = -1;
|
|
||||||
|
|
||||||
m_lib_proxy_map.clear ();
|
m_lib_proxy_map.clear ();
|
||||||
m_meta_info.clear ();
|
m_meta_info.clear ();
|
||||||
}
|
}
|
||||||
|
|
@ -476,9 +376,8 @@ Layout::operator= (const Layout &d)
|
||||||
|
|
||||||
clear ();
|
clear ();
|
||||||
|
|
||||||
m_guiding_shape_layer = d.m_guiding_shape_layer;
|
m_layers = d.m_layers;
|
||||||
m_waste_layer = d.m_waste_layer;
|
|
||||||
m_error_layer = d.m_error_layer;
|
|
||||||
m_editable = d.m_editable;
|
m_editable = d.m_editable;
|
||||||
|
|
||||||
m_pcell_ids = d.m_pcell_ids;
|
m_pcell_ids = d.m_pcell_ids;
|
||||||
|
|
@ -504,9 +403,6 @@ Layout::operator= (const Layout &d)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_properties_repository = d.m_properties_repository; // because the cell assign operator does not map property ID's ..
|
m_properties_repository = d.m_properties_repository; // because the cell assign operator does not map property ID's ..
|
||||||
m_free_indices = d.m_free_indices;
|
|
||||||
m_layer_states = d.m_layer_states;
|
|
||||||
m_layer_props = d.m_layer_props;
|
|
||||||
m_top_down_list = d.m_top_down_list;
|
m_top_down_list = d.m_top_down_list;
|
||||||
m_top_cells = d.m_top_cells;
|
m_top_cells = d.m_top_cells;
|
||||||
|
|
||||||
|
|
@ -720,14 +616,13 @@ Layout::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat
|
||||||
stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat);
|
stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_layers.mem_stat (stat, purpose, cat, true, (void *) this);
|
||||||
|
|
||||||
db::mem_stat (stat, purpose, cat, m_cell_ptrs, true, (void *) this);
|
db::mem_stat (stat, purpose, cat, m_cell_ptrs, true, (void *) this);
|
||||||
db::mem_stat (stat, purpose, cat, m_free_cell_indices, true, (void *) this);
|
db::mem_stat (stat, purpose, cat, m_free_cell_indices, true, (void *) this);
|
||||||
db::mem_stat (stat, purpose, cat, m_top_down_list, true, (void *) this);
|
db::mem_stat (stat, purpose, cat, m_top_down_list, true, (void *) this);
|
||||||
db::mem_stat (stat, purpose, cat, m_free_indices, true, (void *) this);
|
|
||||||
db::mem_stat (stat, purpose, cat, m_layer_states, true, (void *) this);
|
|
||||||
db::mem_stat (stat, purpose, cat, m_cell_names, true, (void *) this);
|
db::mem_stat (stat, purpose, cat, m_cell_names, true, (void *) this);
|
||||||
db::mem_stat (stat, purpose, cat, m_cell_map, true, (void *) this);
|
db::mem_stat (stat, purpose, cat, m_cell_map, true, (void *) this);
|
||||||
db::mem_stat (stat, purpose, cat, m_layer_props, true, (void *) this);
|
|
||||||
db::mem_stat (stat, purpose, cat, m_pcells, true, (void *) this);
|
db::mem_stat (stat, purpose, cat, m_pcells, true, (void *) this);
|
||||||
db::mem_stat (stat, purpose, cat, m_pcell_ids, true, (void *) this);
|
db::mem_stat (stat, purpose, cat, m_pcell_ids, true, (void *) this);
|
||||||
db::mem_stat (stat, purpose, cat, m_lib_proxy_map, true, (void *) this);
|
db::mem_stat (stat, purpose, cat, m_lib_proxy_map, true, (void *) this);
|
||||||
|
|
@ -1839,8 +1734,8 @@ Layout::meta_info_value (const std::string &name) const
|
||||||
void
|
void
|
||||||
Layout::swap_layers (unsigned int a, unsigned int b)
|
Layout::swap_layers (unsigned int a, unsigned int b)
|
||||||
{
|
{
|
||||||
tl_assert (a < layers () && m_layer_states [a] != Free);
|
tl_assert (m_layers.layer_state (a) != LayoutLayers::Free);
|
||||||
tl_assert (b < layers () && m_layer_states [b] != Free);
|
tl_assert (m_layers.layer_state (b) != LayoutLayers::Free);
|
||||||
|
|
||||||
// clear the shapes
|
// clear the shapes
|
||||||
for (iterator c = begin (); c != end (); ++c) {
|
for (iterator c = begin (); c != end (); ++c) {
|
||||||
|
|
@ -1851,8 +1746,8 @@ Layout::swap_layers (unsigned int a, unsigned int b)
|
||||||
void
|
void
|
||||||
Layout::move_layer (unsigned int src, unsigned int dest)
|
Layout::move_layer (unsigned int src, unsigned int dest)
|
||||||
{
|
{
|
||||||
tl_assert (src < layers () && m_layer_states [src] != Free);
|
tl_assert (m_layers.layer_state (src) != LayoutLayers::Free);
|
||||||
tl_assert (dest < layers () && m_layer_states [dest] != Free);
|
tl_assert (m_layers.layer_state (dest) != LayoutLayers::Free);
|
||||||
|
|
||||||
// move the shapes
|
// move the shapes
|
||||||
for (iterator c = begin (); c != end (); ++c) {
|
for (iterator c = begin (); c != end (); ++c) {
|
||||||
|
|
@ -1863,8 +1758,8 @@ Layout::move_layer (unsigned int src, unsigned int dest)
|
||||||
void
|
void
|
||||||
Layout::copy_layer (unsigned int src, unsigned int dest)
|
Layout::copy_layer (unsigned int src, unsigned int dest)
|
||||||
{
|
{
|
||||||
tl_assert (src < layers () && m_layer_states [src] != Free);
|
tl_assert (m_layers.layer_state (src) != LayoutLayers::Free);
|
||||||
tl_assert (dest < layers () && m_layer_states [dest] != Free);
|
tl_assert (m_layers.layer_state (dest) != LayoutLayers::Free);
|
||||||
|
|
||||||
// copy the shapes
|
// copy the shapes
|
||||||
for (iterator c = begin (); c != end (); ++c) {
|
for (iterator c = begin (); c != end (); ++c) {
|
||||||
|
|
@ -1875,7 +1770,7 @@ Layout::copy_layer (unsigned int src, unsigned int dest)
|
||||||
void
|
void
|
||||||
Layout::clear_layer (unsigned int n)
|
Layout::clear_layer (unsigned int n)
|
||||||
{
|
{
|
||||||
tl_assert (n < layers () && m_layer_states [n] != Free);
|
tl_assert (m_layers.layer_state (n) != LayoutLayers::Free);
|
||||||
|
|
||||||
// clear the shapes
|
// clear the shapes
|
||||||
for (iterator c = begin (); c != end (); ++c) {
|
for (iterator c = begin (); c != end (); ++c) {
|
||||||
|
|
@ -1886,14 +1781,13 @@ Layout::clear_layer (unsigned int n)
|
||||||
void
|
void
|
||||||
Layout::delete_layer (unsigned int n)
|
Layout::delete_layer (unsigned int n)
|
||||||
{
|
{
|
||||||
tl_assert (n < layers () && m_layer_states [n] != Free);
|
tl_assert (m_layers.layer_state (n) != LayoutLayers::Free);
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
manager ()->queue (this, new InsertRemoveLayerOp (n, m_layer_props [n], false /*delete*/));
|
manager ()->queue (this, new InsertRemoveLayerOp (n, m_layers.get_properties (n), false /*delete*/));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_free_indices.push_back (n);
|
m_layers.delete_layer (n);
|
||||||
m_layer_states [n] = Free;
|
|
||||||
|
|
||||||
// clear the shapes
|
// clear the shapes
|
||||||
for (iterator c = begin (); c != end (); ++c) {
|
for (iterator c = begin (); c != end (); ++c) {
|
||||||
|
|
@ -1906,11 +1800,7 @@ Layout::delete_layer (unsigned int n)
|
||||||
unsigned int
|
unsigned int
|
||||||
Layout::insert_layer (const LayerProperties &props)
|
Layout::insert_layer (const LayerProperties &props)
|
||||||
{
|
{
|
||||||
unsigned int i = do_insert_layer ();
|
unsigned int i = m_layers.insert_layer (props);
|
||||||
while (m_layer_props.size () <= i) {
|
|
||||||
m_layer_props.push_back (LayerProperties ());
|
|
||||||
}
|
|
||||||
m_layer_props [i] = props;
|
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
manager ()->queue (this, new InsertRemoveLayerOp (i, props, true/*insert*/));
|
manager ()->queue (this, new InsertRemoveLayerOp (i, props, true/*insert*/));
|
||||||
|
|
@ -1924,11 +1814,7 @@ Layout::insert_layer (const LayerProperties &props)
|
||||||
void
|
void
|
||||||
Layout::insert_layer (unsigned int index, const LayerProperties &props)
|
Layout::insert_layer (unsigned int index, const LayerProperties &props)
|
||||||
{
|
{
|
||||||
do_insert_layer (index);
|
m_layers.insert_layer (index, props);
|
||||||
while (m_layer_props.size () <= index) {
|
|
||||||
m_layer_props.push_back (LayerProperties ());
|
|
||||||
}
|
|
||||||
m_layer_props [index] = props;
|
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
manager ()->queue (this, new InsertRemoveLayerOp (index, props, true/*insert*/));
|
manager ()->queue (this, new InsertRemoveLayerOp (index, props, true/*insert*/));
|
||||||
|
|
@ -1940,68 +1826,13 @@ Layout::insert_layer (unsigned int index, const LayerProperties &props)
|
||||||
unsigned int
|
unsigned int
|
||||||
Layout::get_layer (const db::LayerProperties &lp)
|
Layout::get_layer (const db::LayerProperties &lp)
|
||||||
{
|
{
|
||||||
if (lp.is_null ()) {
|
return m_layers.get_layer (lp);
|
||||||
// for a null layer info always create a layer
|
|
||||||
return insert_layer ();
|
|
||||||
} else {
|
|
||||||
// if we have a layer with the requested properties already, return this.
|
|
||||||
for (db::Layout::layer_iterator li = begin_layers (); li != end_layers (); ++li) {
|
|
||||||
if ((*li).second->log_equal (lp)) {
|
|
||||||
return (*li).first;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// otherwise create a new layer
|
|
||||||
return insert_layer (lp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
Layout::error_layer () const
|
|
||||||
{
|
|
||||||
if (m_error_layer < 0) {
|
|
||||||
// create the waste layer (since that layer is cached we can do
|
|
||||||
// this in a "const" fashion.
|
|
||||||
db::Layout *self = const_cast<db::Layout *> (this);
|
|
||||||
self->m_error_layer = (int) self->insert_special_layer (db::LayerProperties ("WASTE"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (unsigned int) m_error_layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
Layout::waste_layer () const
|
|
||||||
{
|
|
||||||
if (m_waste_layer < 0) {
|
|
||||||
// create the waste layer (since that layer is cached we can do
|
|
||||||
// this in a "const" fashion.
|
|
||||||
db::Layout *self = const_cast<db::Layout *> (this);
|
|
||||||
self->m_waste_layer = (int) self->insert_special_layer (db::LayerProperties ("WASTE"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (unsigned int) m_waste_layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
Layout::guiding_shape_layer () const
|
|
||||||
{
|
|
||||||
if (m_guiding_shape_layer < 0) {
|
|
||||||
// create the guiding shape layer (since that layer is cached we can do
|
|
||||||
// this in a "const" fashion.
|
|
||||||
db::Layout *self = const_cast<db::Layout *> (this);
|
|
||||||
self->m_guiding_shape_layer = (int) self->insert_special_layer (db::LayerProperties ("GUIDING_SHAPES"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (unsigned int) m_guiding_shape_layer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
Layout::insert_special_layer (const LayerProperties &props)
|
Layout::insert_special_layer (const LayerProperties &props)
|
||||||
{
|
{
|
||||||
unsigned int i = do_insert_layer (true /*special*/);
|
unsigned int i = m_layers.insert_special_layer (props);
|
||||||
while (m_layer_props.size () <= i) {
|
|
||||||
m_layer_props.push_back (LayerProperties ());
|
|
||||||
}
|
|
||||||
m_layer_props [i] = props;
|
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
manager ()->queue (this, new InsertRemoveLayerOp (i, props, true/*insert*/));
|
manager ()->queue (this, new InsertRemoveLayerOp (i, props, true/*insert*/));
|
||||||
|
|
@ -2013,13 +1844,13 @@ Layout::insert_special_layer (const LayerProperties &props)
|
||||||
void
|
void
|
||||||
Layout::set_properties (unsigned int i, const LayerProperties &props)
|
Layout::set_properties (unsigned int i, const LayerProperties &props)
|
||||||
{
|
{
|
||||||
if (m_layer_props [i] != props) {
|
if (m_layers.get_properties (i) != props) {
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
manager ()->queue (this, new SetLayerPropertiesOp (i, props, m_layer_props [i]));
|
manager ()->queue (this, new SetLayerPropertiesOp (i, props, m_layers.get_properties (i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_layer_props [i] = props;
|
m_layers.set_properties (i, props);
|
||||||
|
|
||||||
layer_properties_changed ();
|
layer_properties_changed ();
|
||||||
|
|
||||||
|
|
@ -2029,60 +1860,13 @@ Layout::set_properties (unsigned int i, const LayerProperties &props)
|
||||||
void
|
void
|
||||||
Layout::insert_special_layer (unsigned int index, const LayerProperties &props)
|
Layout::insert_special_layer (unsigned int index, const LayerProperties &props)
|
||||||
{
|
{
|
||||||
do_insert_layer (index, true /*special*/);
|
m_layers.insert_special_layer (index, props);
|
||||||
while (m_layer_props.size () <= index) {
|
|
||||||
m_layer_props.push_back (LayerProperties ());
|
|
||||||
}
|
|
||||||
m_layer_props [index] = props;
|
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
manager ()->queue (this, new InsertRemoveLayerOp (index, props, true/*insert*/));
|
manager ()->queue (this, new InsertRemoveLayerOp (index, props, true/*insert*/));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
|
||||||
Layout::do_insert_layer (bool special)
|
|
||||||
{
|
|
||||||
if (m_free_indices.size () > 0) {
|
|
||||||
unsigned int i = m_free_indices.back ();
|
|
||||||
m_free_indices.pop_back ();
|
|
||||||
m_layer_states [i] = special ? Special : Normal;
|
|
||||||
return i;
|
|
||||||
} else {
|
|
||||||
m_layer_states.push_back (special ? Special : Normal);
|
|
||||||
unsigned int i = layers () - 1;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Layout::do_insert_layer (unsigned int index, bool special)
|
|
||||||
{
|
|
||||||
if (index >= layers ()) {
|
|
||||||
|
|
||||||
// add layer to the end of the list.
|
|
||||||
// add as may freelist entries as required.
|
|
||||||
while (index > layers ()) {
|
|
||||||
m_free_indices.push_back (layers ());
|
|
||||||
m_layer_states.push_back (Free);
|
|
||||||
}
|
|
||||||
m_layer_states.push_back (special ? Special : Normal);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
tl_assert (m_layer_states [index] == Free);
|
|
||||||
m_layer_states [index] = special ? Special : Normal;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Layout::reserve_layers (unsigned int n)
|
|
||||||
{
|
|
||||||
m_layer_states.reserve (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const std::vector<tl::Variant> &gauge_parameters (const std::vector<tl::Variant> &p, const db::PCellDeclaration *pcell_decl, std::vector<tl::Variant> &buffer)
|
static const std::vector<tl::Variant> &gauge_parameters (const std::vector<tl::Variant> &p, const db::PCellDeclaration *pcell_decl, std::vector<tl::Variant> &buffer)
|
||||||
{
|
{
|
||||||
const std::vector<db::PCellParameterDeclaration> &pcp = pcell_decl->parameter_declarations ();
|
const std::vector<db::PCellParameterDeclaration> &pcp = pcell_decl->parameter_declarations ();
|
||||||
|
|
@ -2354,8 +2138,8 @@ Layout::convert_cell_to_static (db::cell_index_type ci)
|
||||||
new_cell.set_cell_index (ret_ci);
|
new_cell.set_cell_index (ret_ci);
|
||||||
|
|
||||||
// remove guiding shapes.
|
// remove guiding shapes.
|
||||||
if (m_guiding_shape_layer >= 0) {
|
if (m_layers.guiding_shape_layer_maybe () >= 0) {
|
||||||
new_cell.shapes (m_guiding_shape_layer).clear ();
|
new_cell.shapes (m_layers.guiding_shape_layer_maybe ()).clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "dbText.h"
|
#include "dbText.h"
|
||||||
#include "dbCell.h"
|
#include "dbCell.h"
|
||||||
#include "dbLayoutStateModel.h"
|
#include "dbLayoutStateModel.h"
|
||||||
|
#include "dbLayoutLayers.h"
|
||||||
#include "dbLayerProperties.h"
|
#include "dbLayerProperties.h"
|
||||||
#include "dbMetaInfo.h"
|
#include "dbMetaInfo.h"
|
||||||
#include "dbCellInst.h"
|
#include "dbCellInst.h"
|
||||||
|
|
@ -393,50 +394,6 @@ private:
|
||||||
cell_type *mp_first, *mp_last;
|
cell_type *mp_first, *mp_last;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A layer iterator (for valid layers)
|
|
||||||
*
|
|
||||||
* The layer iterator delivers layer indices and layer properties of layer layers.
|
|
||||||
*/
|
|
||||||
class DB_PUBLIC LayerIterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Constructor
|
|
||||||
*/
|
|
||||||
LayerIterator (unsigned int layer_index, const db::Layout &layout);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Increment operator
|
|
||||||
*/
|
|
||||||
LayerIterator &operator++();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Equality
|
|
||||||
*/
|
|
||||||
bool operator== (const LayerIterator &i)
|
|
||||||
{
|
|
||||||
return i.m_layer_index == m_layer_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Inequality
|
|
||||||
*/
|
|
||||||
bool operator!= (const LayerIterator &i)
|
|
||||||
{
|
|
||||||
return i.m_layer_index != m_layer_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Access operator
|
|
||||||
*/
|
|
||||||
std::pair<unsigned int, const db::LayerProperties *> operator*() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned int m_layer_index;
|
|
||||||
const db::Layout &m_layout;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief An interface that is used to map layer between libraries and PCells and the layout
|
* @brief An interface that is used to map layer between libraries and PCells and the layout
|
||||||
*/
|
*/
|
||||||
|
|
@ -1426,7 +1383,7 @@ public:
|
||||||
*/
|
*/
|
||||||
bool is_valid_layer (unsigned int n) const
|
bool is_valid_layer (unsigned int n) const
|
||||||
{
|
{
|
||||||
return (n < layers () && m_layer_states [n] == Normal);
|
return m_layers.layer_state (n) == db::LayoutLayers::Normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1434,7 +1391,7 @@ public:
|
||||||
*/
|
*/
|
||||||
bool is_free_layer (unsigned int n) const
|
bool is_free_layer (unsigned int n) const
|
||||||
{
|
{
|
||||||
return (n >= layers () || m_layer_states [n] == Free);
|
return m_layers.layer_state (n) == db::LayoutLayers::Free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1442,7 +1399,7 @@ public:
|
||||||
*/
|
*/
|
||||||
bool is_special_layer (unsigned int n) const
|
bool is_special_layer (unsigned int n) const
|
||||||
{
|
{
|
||||||
return (n < layers () && m_layer_states [n] == Special);
|
return m_layers.layer_state (n) == db::LayoutLayers::Special;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1454,7 +1411,7 @@ public:
|
||||||
*/
|
*/
|
||||||
unsigned int layers () const
|
unsigned int layers () const
|
||||||
{
|
{
|
||||||
return (cell_index_type) m_layer_states.size ();
|
return m_layers.layers ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1462,7 +1419,7 @@ public:
|
||||||
*/
|
*/
|
||||||
layer_iterator begin_layers () const
|
layer_iterator begin_layers () const
|
||||||
{
|
{
|
||||||
return layer_iterator (0, *this);
|
return m_layers.begin_layers ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1470,13 +1427,16 @@ public:
|
||||||
*/
|
*/
|
||||||
layer_iterator end_layers () const
|
layer_iterator end_layers () const
|
||||||
{
|
{
|
||||||
return layer_iterator (layers (), *this);
|
return m_layers.end_layers ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reserve space for n layers
|
* @brief Reserve space for n layers
|
||||||
*/
|
*/
|
||||||
void reserve_layers (unsigned int n);
|
void reserve_layers (unsigned int n)
|
||||||
|
{
|
||||||
|
m_layers.reserve_layers (n);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief begin iterator of the unsorted cell list
|
* @brief begin iterator of the unsorted cell list
|
||||||
|
|
@ -1705,21 +1665,30 @@ public:
|
||||||
*
|
*
|
||||||
* The guiding shape layer is used to store the guiding shapes of PCells
|
* The guiding shape layer is used to store the guiding shapes of PCells
|
||||||
*/
|
*/
|
||||||
unsigned int guiding_shape_layer () const;
|
unsigned int guiding_shape_layer () const
|
||||||
|
{
|
||||||
|
return m_layers.guiding_shape_layer ();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the waste layer
|
* @brief Gets the waste layer
|
||||||
*
|
*
|
||||||
* The waste layer is used to store shapes that should not be visible and can be cleared at any time.
|
* The waste layer is used to store shapes that should not be visible and can be cleared at any time.
|
||||||
*/
|
*/
|
||||||
unsigned int waste_layer () const;
|
unsigned int waste_layer () const
|
||||||
|
{
|
||||||
|
return m_layers.waste_layer ();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the error layer
|
* @brief Gets the error layer
|
||||||
*
|
*
|
||||||
* The error layer is used to display error messages.
|
* The error layer is used to display error messages.
|
||||||
*/
|
*/
|
||||||
unsigned int error_layer () const;
|
unsigned int error_layer () const
|
||||||
|
{
|
||||||
|
return m_layers.error_layer ();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the properties for a specified layer
|
* @brief Set the properties for a specified layer
|
||||||
|
|
@ -1731,7 +1700,7 @@ public:
|
||||||
*/
|
*/
|
||||||
const LayerProperties &get_properties (unsigned int i) const
|
const LayerProperties &get_properties (unsigned int i) const
|
||||||
{
|
{
|
||||||
return m_layer_props [i];
|
return m_layers.get_properties (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1877,8 +1846,6 @@ protected:
|
||||||
virtual void do_update ();
|
virtual void do_update ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum LayerState { Normal, Free, Special };
|
|
||||||
|
|
||||||
db::Library *mp_library;
|
db::Library *mp_library;
|
||||||
cell_list m_cells;
|
cell_list m_cells;
|
||||||
size_t m_cells_size;
|
size_t m_cells_size;
|
||||||
|
|
@ -1887,11 +1854,9 @@ private:
|
||||||
mutable unsigned int m_invalid;
|
mutable unsigned int m_invalid;
|
||||||
cell_index_vector m_top_down_list;
|
cell_index_vector m_top_down_list;
|
||||||
size_t m_top_cells;
|
size_t m_top_cells;
|
||||||
std::vector<unsigned int> m_free_indices;
|
LayoutLayers m_layers;
|
||||||
std::vector<LayerState> m_layer_states;
|
|
||||||
std::vector<const char *> m_cell_names;
|
std::vector<const char *> m_cell_names;
|
||||||
cell_map_type m_cell_map;
|
cell_map_type m_cell_map;
|
||||||
std::vector<LayerProperties> m_layer_props;
|
|
||||||
double m_dbu;
|
double m_dbu;
|
||||||
db::properties_id_type m_prop_id;
|
db::properties_id_type m_prop_id;
|
||||||
StringRepository m_string_repository;
|
StringRepository m_string_repository;
|
||||||
|
|
@ -1901,9 +1866,6 @@ private:
|
||||||
std::vector<pcell_header_type *> m_pcells;
|
std::vector<pcell_header_type *> m_pcells;
|
||||||
pcell_name_map m_pcell_ids;
|
pcell_name_map m_pcell_ids;
|
||||||
lib_proxy_map m_lib_proxy_map;
|
lib_proxy_map m_lib_proxy_map;
|
||||||
int m_guiding_shape_layer;
|
|
||||||
int m_waste_layer;
|
|
||||||
int m_error_layer;
|
|
||||||
bool m_do_cleanup;
|
bool m_do_cleanup;
|
||||||
bool m_editable;
|
bool m_editable;
|
||||||
meta_info m_meta_info;
|
meta_info m_meta_info;
|
||||||
|
|
@ -1937,21 +1899,6 @@ private:
|
||||||
*/
|
*/
|
||||||
cell_index_type allocate_new_cell ();
|
cell_index_type allocate_new_cell ();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Insert a new layer
|
|
||||||
*
|
|
||||||
* This creates a new index number, either from the free list
|
|
||||||
* of by creating a new one.
|
|
||||||
*/
|
|
||||||
unsigned int do_insert_layer (bool special = false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Insert a new layer at the given index
|
|
||||||
*
|
|
||||||
* If the index is unused, create a new layer there.
|
|
||||||
*/
|
|
||||||
void do_insert_layer (unsigned int index, bool special = false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of prune_cell and prune_subcells
|
* @brief Implementation of prune_cell and prune_subcells
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,318 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
KLayoutLayers LayoutLayers Viewer
|
||||||
|
Copyright (C) 2006-2022 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 "dbLayoutLayers.h"
|
||||||
|
|
||||||
|
namespace db
|
||||||
|
{
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// Implementation of the LayerIterator class
|
||||||
|
|
||||||
|
LayerIterator::LayerIterator (unsigned int layer_index, const db::LayoutLayers &layout)
|
||||||
|
: m_layer_index (layer_index), m_layout (layout)
|
||||||
|
{
|
||||||
|
while (m_layer_index < m_layout.layers () && m_layout.layer_state (m_layer_index) != db::LayoutLayers::Normal) {
|
||||||
|
++m_layer_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerIterator &
|
||||||
|
LayerIterator::operator++()
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
++m_layer_index;
|
||||||
|
} while (m_layer_index < m_layout.layers () && m_layout.layer_state (m_layer_index) != db::LayoutLayers::Normal);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<unsigned int, const db::LayerProperties *>
|
||||||
|
LayerIterator::operator*() const
|
||||||
|
{
|
||||||
|
return std::pair<unsigned int, const db::LayerProperties *> (m_layer_index, &m_layout.get_properties (m_layer_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// Implementation of the LayoutLayers class
|
||||||
|
|
||||||
|
LayoutLayers::LayoutLayers ()
|
||||||
|
: m_guiding_shape_layer (-1),
|
||||||
|
m_waste_layer (-1),
|
||||||
|
m_error_layer (-1)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutLayers::LayoutLayers (const db::LayoutLayers &layout)
|
||||||
|
: m_guiding_shape_layer (-1),
|
||||||
|
m_waste_layer (-1),
|
||||||
|
m_error_layer (-1)
|
||||||
|
{
|
||||||
|
*this = layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutLayers::~LayoutLayers ()
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LayoutLayers::clear ()
|
||||||
|
{
|
||||||
|
m_free_indices.clear ();
|
||||||
|
m_layer_states.clear ();
|
||||||
|
m_layer_props.clear ();
|
||||||
|
m_layers_by_props.clear ();
|
||||||
|
|
||||||
|
m_guiding_shape_layer = -1;
|
||||||
|
m_waste_layer = -1;
|
||||||
|
m_error_layer = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutLayers &
|
||||||
|
LayoutLayers::operator= (const LayoutLayers &d)
|
||||||
|
{
|
||||||
|
if (&d != this) {
|
||||||
|
|
||||||
|
m_guiding_shape_layer = d.m_guiding_shape_layer;
|
||||||
|
m_waste_layer = d.m_waste_layer;
|
||||||
|
m_error_layer = d.m_error_layer;
|
||||||
|
|
||||||
|
m_free_indices = d.m_free_indices;
|
||||||
|
m_layer_states = d.m_layer_states;
|
||||||
|
m_layer_props = d.m_layer_props;
|
||||||
|
m_layers_by_props = d.m_layers_by_props;
|
||||||
|
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LayoutLayers::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const
|
||||||
|
{
|
||||||
|
if (!no_self) {
|
||||||
|
stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat);
|
||||||
|
}
|
||||||
|
|
||||||
|
db::mem_stat (stat, purpose, cat, m_free_indices, true, (void *) this);
|
||||||
|
db::mem_stat (stat, purpose, cat, m_layer_states, true, (void *) this);
|
||||||
|
db::mem_stat (stat, purpose, cat, m_layer_props, true, (void *) this);
|
||||||
|
db::mem_stat (stat, purpose, cat, m_layers_by_props, true, (void *) this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LayoutLayers::delete_layer (unsigned int n)
|
||||||
|
{
|
||||||
|
const db::LayerProperties &lp = m_layer_props [n];
|
||||||
|
if (! lp.is_null ()) {
|
||||||
|
for (auto i = m_layers_by_props.find (lp); i != m_layers_by_props.end () && i->first.log_equal (lp); ++i) {
|
||||||
|
if (i->second == n) {
|
||||||
|
m_layers_by_props.erase (i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_free_indices.push_back (n);
|
||||||
|
m_layer_props [n] = db::LayerProperties ();
|
||||||
|
m_layer_states [n] = Free;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
LayoutLayers::insert_layer (const LayerProperties &props)
|
||||||
|
{
|
||||||
|
unsigned int i = do_insert_layer ();
|
||||||
|
set_properties (i, props);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LayoutLayers::insert_layer (unsigned int index, const LayerProperties &props)
|
||||||
|
{
|
||||||
|
if (layer_state (index) == Normal) {
|
||||||
|
delete_layer (index);
|
||||||
|
}
|
||||||
|
do_insert_layer (index);
|
||||||
|
set_properties (index, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
LayoutLayers::get_layer (const db::LayerProperties &lp)
|
||||||
|
{
|
||||||
|
if (lp.is_null ()) {
|
||||||
|
// for a null layer info always create a layer
|
||||||
|
return insert_layer ();
|
||||||
|
} else {
|
||||||
|
auto i = m_layers_by_props.find (lp);
|
||||||
|
if (i != m_layers_by_props.end () && i->first.log_equal (lp)) {
|
||||||
|
return i->second;
|
||||||
|
} else {
|
||||||
|
// otherwise create a new layer
|
||||||
|
return insert_layer (lp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LayoutLayers::get_layer_maybe (const db::LayerProperties &lp)
|
||||||
|
{
|
||||||
|
if (lp.is_null ()) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
auto i = m_layers_by_props.find (lp);
|
||||||
|
if (i != m_layers_by_props.end () && i->first.log_equal (lp)) {
|
||||||
|
return int (i->second);
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
LayoutLayers::error_layer () const
|
||||||
|
{
|
||||||
|
if (m_error_layer < 0) {
|
||||||
|
// create the waste layer (since that layer is cached we can do
|
||||||
|
// this in a "const" fashion.
|
||||||
|
db::LayoutLayers *self = const_cast<db::LayoutLayers *> (this);
|
||||||
|
self->m_error_layer = (int) self->insert_special_layer (db::LayerProperties ("WASTE"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned int) m_error_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
LayoutLayers::waste_layer () const
|
||||||
|
{
|
||||||
|
if (m_waste_layer < 0) {
|
||||||
|
// create the waste layer (since that layer is cached we can do
|
||||||
|
// this in a "const" fashion.
|
||||||
|
db::LayoutLayers *self = const_cast<db::LayoutLayers *> (this);
|
||||||
|
self->m_waste_layer = (int) self->insert_special_layer (db::LayerProperties ("WASTE"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned int) m_waste_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
LayoutLayers::guiding_shape_layer () const
|
||||||
|
{
|
||||||
|
if (m_guiding_shape_layer < 0) {
|
||||||
|
// create the guiding shape layer (since that layer is cached we can do
|
||||||
|
// this in a "const" fashion.
|
||||||
|
db::LayoutLayers *self = const_cast<db::LayoutLayers *> (this);
|
||||||
|
self->m_guiding_shape_layer = (int) self->insert_special_layer (db::LayerProperties ("GUIDING_SHAPES"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned int) m_guiding_shape_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
LayoutLayers::insert_special_layer (const LayerProperties &props)
|
||||||
|
{
|
||||||
|
unsigned int i = do_insert_layer (true /*special*/);
|
||||||
|
set_properties (i, props);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LayoutLayers::insert_special_layer (unsigned int index, const LayerProperties &props)
|
||||||
|
{
|
||||||
|
if (layer_state (index) == Normal) {
|
||||||
|
delete_layer (index);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_insert_layer (index, true /*special*/);
|
||||||
|
set_properties (index, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
LayoutLayers::do_insert_layer (bool special)
|
||||||
|
{
|
||||||
|
if (m_free_indices.size () > 0) {
|
||||||
|
unsigned int i = m_free_indices.back ();
|
||||||
|
m_free_indices.pop_back ();
|
||||||
|
m_layer_states [i] = special ? Special : Normal;
|
||||||
|
return i;
|
||||||
|
} else {
|
||||||
|
m_layer_states.push_back (special ? Special : Normal);
|
||||||
|
unsigned int i = layers () - 1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LayoutLayers::do_insert_layer (unsigned int index, bool special)
|
||||||
|
{
|
||||||
|
if (index >= layers ()) {
|
||||||
|
|
||||||
|
// add layer to the end of the list.
|
||||||
|
// add as may freelist entries as required.
|
||||||
|
while (index > layers ()) {
|
||||||
|
m_free_indices.push_back (layers ());
|
||||||
|
m_layer_states.push_back (Free);
|
||||||
|
}
|
||||||
|
m_layer_states.push_back (special ? Special : Normal);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
tl_assert (m_layer_states [index] == Free);
|
||||||
|
m_layer_states [index] = special ? Special : Normal;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LayoutLayers::reserve_layers (unsigned int n)
|
||||||
|
{
|
||||||
|
m_layer_states.reserve (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LayoutLayers::set_properties (unsigned int n, const LayerProperties &props)
|
||||||
|
{
|
||||||
|
while (m_layer_props.size () <= n) {
|
||||||
|
m_layer_props.push_back (LayerProperties ());
|
||||||
|
}
|
||||||
|
|
||||||
|
const db::LayerProperties &lp = m_layer_props [n];
|
||||||
|
if (! lp.is_null ()) {
|
||||||
|
for (auto i = m_layers_by_props.find (lp); i != m_layers_by_props.end () && i->first.log_equal (lp); ++i) {
|
||||||
|
if (i->second == n) {
|
||||||
|
m_layers_by_props.erase (i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_layer_props [n] = props;
|
||||||
|
|
||||||
|
if (! props.is_null ()) {
|
||||||
|
m_layers_by_props.insert (std::make_pair (props, n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,282 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
KLayout Layout Viewer
|
||||||
|
Copyright (C) 2006-2022 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_dbLayoutLayers
|
||||||
|
#define HDR_dbLayoutLayers
|
||||||
|
|
||||||
|
#include "dbCommon.h"
|
||||||
|
|
||||||
|
#include "dbLayerProperties.h"
|
||||||
|
#include "dbMemStatistics.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace db
|
||||||
|
{
|
||||||
|
|
||||||
|
class MemStatistics;
|
||||||
|
class LayoutLayers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A layer iterator (for valid layers)
|
||||||
|
*
|
||||||
|
* The layer iterator delivers layer indices and layer properties of layer layers.
|
||||||
|
*/
|
||||||
|
class DB_PUBLIC LayerIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*/
|
||||||
|
LayerIterator (unsigned int layer_index, const db::LayoutLayers &layout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Increment operator
|
||||||
|
*/
|
||||||
|
LayerIterator &operator++();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equality
|
||||||
|
*/
|
||||||
|
bool operator== (const LayerIterator &i)
|
||||||
|
{
|
||||||
|
return i.m_layer_index == m_layer_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inequality
|
||||||
|
*/
|
||||||
|
bool operator!= (const LayerIterator &i)
|
||||||
|
{
|
||||||
|
return i.m_layer_index != m_layer_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Access operator
|
||||||
|
*/
|
||||||
|
std::pair<unsigned int, const db::LayerProperties *> operator*() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int m_layer_index;
|
||||||
|
const db::LayoutLayers &m_layout;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The layoutLayers object
|
||||||
|
*
|
||||||
|
* This object wraps the layer list and manages layer properties,
|
||||||
|
* layer states and the free layer list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DB_PUBLIC LayoutLayers
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef LayerIterator layer_iterator;
|
||||||
|
enum LayerState { Normal, Free, Special };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Standard constructor
|
||||||
|
*/
|
||||||
|
LayoutLayers ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The copy ctor
|
||||||
|
*/
|
||||||
|
LayoutLayers (const LayoutLayers &d);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
*/
|
||||||
|
~LayoutLayers ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assignment operator
|
||||||
|
*/
|
||||||
|
LayoutLayers &operator= (const LayoutLayers &d);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the layout layers
|
||||||
|
*/
|
||||||
|
void clear ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deletes a layer
|
||||||
|
*/
|
||||||
|
void delete_layer (unsigned int n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the layer's state
|
||||||
|
*/
|
||||||
|
LayerState layer_state (unsigned int l) const
|
||||||
|
{
|
||||||
|
return l < (unsigned int) m_layer_states.size () ? m_layer_states [l] : Free;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the number of layers defined so far
|
||||||
|
*
|
||||||
|
* TODO: the list of 0 to nlayers-1 also contains the free layers -
|
||||||
|
* we should get a vector containing the layers that are actually
|
||||||
|
* allocated.
|
||||||
|
*/
|
||||||
|
unsigned int layers () const
|
||||||
|
{
|
||||||
|
return (unsigned int) m_layer_states.size ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The iterator of valid layers: begin
|
||||||
|
*/
|
||||||
|
layer_iterator begin_layers () const
|
||||||
|
{
|
||||||
|
return layer_iterator (0, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The iterator of valid layers: end
|
||||||
|
*/
|
||||||
|
layer_iterator end_layers () const
|
||||||
|
{
|
||||||
|
return layer_iterator (layers (), *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reserve space for n layers
|
||||||
|
*/
|
||||||
|
void reserve_layers (unsigned int n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts a new layer with the given properties
|
||||||
|
*/
|
||||||
|
unsigned int insert_layer (const LayerProperties &props = LayerProperties ());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts a new layer with the given properties at the given index
|
||||||
|
*/
|
||||||
|
void insert_layer (unsigned int index, const LayerProperties &props = LayerProperties ());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets or creates a layer with the given properties
|
||||||
|
*
|
||||||
|
* If there already is a layer matching the given properties, it's index will be
|
||||||
|
* returned. Otherwise a new layer with these properties is created.
|
||||||
|
*/
|
||||||
|
unsigned int get_layer (const db::LayerProperties &props);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets or creates a layer with the given properties or -1 if such a layer does not exist.
|
||||||
|
*/
|
||||||
|
int get_layer_maybe (const db::LayerProperties &props);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Insert a new special layer with the given properties
|
||||||
|
*
|
||||||
|
* A special layers is used for example to represent rulers.
|
||||||
|
*/
|
||||||
|
unsigned int insert_special_layer (const LayerProperties &props = LayerProperties ());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Insert a new layer with the given properties at the given index
|
||||||
|
*
|
||||||
|
* A special layers is used for example to represent rulers.
|
||||||
|
*/
|
||||||
|
void insert_special_layer (unsigned int index, const LayerProperties &props = LayerProperties ());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the guiding shape layer or -1 if none is set yet.
|
||||||
|
*/
|
||||||
|
int guiding_shape_layer_maybe () const
|
||||||
|
{
|
||||||
|
return m_guiding_shape_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the guiding shape layer
|
||||||
|
*
|
||||||
|
* The guiding shape layer is used to store the guiding shapes of PCells
|
||||||
|
*/
|
||||||
|
unsigned int guiding_shape_layer () const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the waste layer
|
||||||
|
*
|
||||||
|
* The waste layer is used to store shapes that should not be visible and can be cleared at any time.
|
||||||
|
*/
|
||||||
|
unsigned int waste_layer () const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the error layer
|
||||||
|
*
|
||||||
|
* The error layer is used to display error messages.
|
||||||
|
*/
|
||||||
|
unsigned int error_layer () const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the properties for a specified layer
|
||||||
|
*/
|
||||||
|
void set_properties (unsigned int i, const LayerProperties &props);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the properties for a specified layer
|
||||||
|
*/
|
||||||
|
const LayerProperties &get_properties (unsigned int i) const
|
||||||
|
{
|
||||||
|
return m_layer_props [i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Collects memory statistics
|
||||||
|
*/
|
||||||
|
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<unsigned int> m_free_indices;
|
||||||
|
std::vector<LayerState> m_layer_states;
|
||||||
|
std::vector<LayerProperties> m_layer_props;
|
||||||
|
std::multimap<LayerProperties, unsigned int, db::LPLogicalLessFunc> m_layers_by_props;
|
||||||
|
int m_guiding_shape_layer;
|
||||||
|
int m_waste_layer;
|
||||||
|
int m_error_layer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Insert a new layer
|
||||||
|
*
|
||||||
|
* This creates a new index number, either from the free list
|
||||||
|
* of by creating a new one.
|
||||||
|
*/
|
||||||
|
unsigned int do_insert_layer (bool special = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Insert a new layer at the given index
|
||||||
|
*
|
||||||
|
* If the index is unused, create a new layer there.
|
||||||
|
*/
|
||||||
|
void do_insert_layer (unsigned int index, bool special = false);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -629,11 +629,7 @@ LayerProperties::do_realize (const LayoutViewBase *view) const
|
||||||
|
|
||||||
// lookup the layer with the given name/layer/datatype
|
// lookup the layer with the given name/layer/datatype
|
||||||
if (m_layer_index < 0 && ! m_source_real.is_wildcard_layer ()) {
|
if (m_layer_index < 0 && ! m_source_real.is_wildcard_layer ()) {
|
||||||
for (unsigned int i = 0; i < cv->layout ().layers () && m_layer_index < 0; ++i) {
|
m_layer_index = cv->layout ().get_layer_maybe (m_source_real.layer_props ());
|
||||||
if (cv->layout ().is_valid_layer (i) && m_source_real.match (cv->layout ().get_properties (i))) {
|
|
||||||
m_layer_index = int (i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue