Merged master into dvb branch

This commit is contained in:
Matthias Koefferlein 2019-02-22 23:16:44 +01:00
commit c7b17fb65a
12 changed files with 340 additions and 145 deletions

136
Changelog
View File

@ -3,21 +3,21 @@
* YET TO BE RELEASED * YET TO BE RELEASED
* Enhancement: Standalone Python modules provided * Enhancement: Standalone Python modules provided
For details see: For details see:
https://github.com/klayoutmatthias/klayout/wiki/klayout---Standalone-KLayout-Python-Module %GITHUB%/wiki/klayout---Standalone-KLayout-Python-Module
0.25.5 (2018-09-30): 0.25.5 (2018-09-30):
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/162 * Bugfix: %GITHUB%/issues/162
GDS2 LIBNAME was not maintained on "File/Save". GDS2 LIBNAME was not maintained on "File/Save".
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/166 * Bugfix: %GITHUB%/issues/166
Internal error when writing GDS files (breaking of polygons) Internal error when writing GDS files (breaking of polygons)
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/172 * Bugfix: %GITHUB%/issues/172
DEF reader did not pull vias from LEF DEF reader did not pull vias from LEF
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/174 * Bugfix: %GITHUB%/issues/174
Performance issue with many layers with width >1 Performance issue with many layers with width >1
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/176 * Bugfix: %GITHUB%/issues/176
Painting issue with texts Painting issue with texts
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/185 * Bugfix: %GITHUB%/issues/185
Hash values available as __hash__ standard method now Hash values available as __hash__ standard method now
for Python for Python
* Bugfix: some potential memory corruption issues fixed * Bugfix: some potential memory corruption issues fixed
@ -27,36 +27,36 @@
These fixes are included in this release. These fixes are included in this release.
0.25.4 (2018-08-25): 0.25.4 (2018-08-25):
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/121 * Bugfix: %GITHUB%/issues/121
Issue with multiple reads of GDS2 layouts including PCells Issue with multiple reads of GDS2 layouts including PCells
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/134 * Bugfix: %GITHUB%/issues/134
Error in cell.fill_region caused by big polygon with Error in cell.fill_region caused by big polygon with
spikes spikes
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/139 * Bugfix: %GITHUB%/issues/139
Libraries have not been reassigned when loading a GDS file Libraries have not been reassigned when loading a GDS file
from command line (does not happen on File/Open) from command line (does not happen on File/Open)
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/141 * Bugfix: %GITHUB%/issues/141
Issue with RBA::QHostAddress (ambiguous overload) on Qt5 Issue with RBA::QHostAddress (ambiguous overload) on Qt5
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/142 * Bugfix: %GITHUB%/issues/142
Issue with RBA::RecursiveShapeIterator#region= Issue with RBA::RecursiveShapeIterator#region=
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/144 * Bugfix: %GITHUB%/issues/144
The Salt package descriptions are not shown with Motif The Salt package descriptions are not shown with Motif
style style
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/148 * Bugfix: %GITHUB%/issues/148
Wrong font is used Wrong font is used
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/152 * Bugfix: %GITHUB%/issues/152
Shapes#size reported a wrong shape count in viewer mode Shapes#size reported a wrong shape count in viewer mode
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/153 * Bugfix: %GITHUB%/issues/153
Application crash when editing guiding shape properties Application crash when editing guiding shape properties
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/155 * Bugfix: %GITHUB%/issues/155
Program freezes after replacing nothing by something in Program freezes after replacing nothing by something in
Macro editor Macro editor
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/157 * Bugfix: %GITHUB%/issues/157
"Replace cell with ..." rejected cell names with a library "Replace cell with ..." rejected cell names with a library
prefix prefix
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/158 * Bugfix: %GITHUB%/issues/158
Repaint issue on cell context Repaint issue on cell context
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/159 * Bugfix: %GITHUB%/issues/159
Tech specific macros and DRC scripts were not shown in tech Tech specific macros and DRC scripts were not shown in tech
manager manager
* Bugfix: 8 bit indexed GIF images can be used for package icons now * Bugfix: 8 bit indexed GIF images can be used for package icons now
@ -118,41 +118,41 @@
* Bugfix: XOR progress is more realistic * Bugfix: XOR progress is more realistic
The progress is updated after the layer has been computed, The progress is updated after the layer has been computed,
not before. not before.
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/117 * Bugfix: %GITHUB%/issues/117
DTrans#itype was broken. DTrans#itype was broken.
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/116 * Bugfix: %GITHUB%/issues/116
Fixed a polygon decomposition bug when writing GDS files Fixed a polygon decomposition bug when writing GDS files
with big polygons with many holes. As a side effect, the with big polygons with many holes. As a side effect, the
polygons with many holes computed by a NOT operation for polygons with many holes computed by a NOT operation for
example are less complex and spikes in the cutlines are example are less complex and spikes in the cutlines are
avoided. avoided.
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/115 * Bugfix: %GITHUB%/issues/115
Reader options were not persisted. Reader options were not persisted.
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/114 * Bugfix: %GITHUB%/issues/114
Custom line styles not loaded from tech's layer properties Custom line styles not loaded from tech's layer properties
file. file.
* Enhancement: https://github.com/klayoutmatthias/klayout/issues/113 * Enhancement: %GITHUB%/issues/113
The XOR tool has an option now to heal result shapes which The XOR tool has an option now to heal result shapes which
cross tile boundaries. The result shape count of tiled cross tile boundaries. The result shape count of tiled
and non-tiled mode should basically be the same then. and non-tiled mode should basically be the same then.
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/112 * Bugfix: %GITHUB%/issues/112
Salt package repository relative paths have not been working. Salt package repository relative paths have not been working.
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/109 * Bugfix: %GITHUB%/issues/109
Issues with Python 3 and shape properties - property Issues with Python 3 and shape properties - property
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/108 * Bugfix: %GITHUB%/issues/108
Bugfix on Box#enlarge and Box#moved for empty boxes. Bugfix on Box#enlarge and Box#moved for empty boxes.
keys generated with Python 3 could not be written to GDS2. keys generated with Python 3 could not be written to GDS2.
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/107 * Bugfix: %GITHUB%/issues/107
Undo not working with shapes. Undo not working with shapes.
* Enhancement: https://github.com/klayoutmatthias/klayout/issues/106 * Enhancement: %GITHUB%/issues/106
Search & replace help page enhancements. Search & replace help page enhancements.
0.25.2 (2018-03-20): 0.25.2 (2018-03-20):
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/90 * Bugfix: %GITHUB%/issues/90
DRC: "extended" was not working as expected with "joined = true" DRC: "extended" was not working as expected with "joined = true"
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/89 * Bugfix: %GITHUB%/issues/89
Display issue on MacOS fixed Display issue on MacOS fixed
* Enhancement: https://github.com/klayoutmatthias/klayout/issues/85 * Enhancement: %GITHUB%/issues/85
IDE debugger: files can be excluded from showing exceptions when IDE debugger: files can be excluded from showing exceptions when
they are thrown. To exclude a file press the new "Ignore" button they are thrown. To exclude a file press the new "Ignore" button
when the debugger tells you an exception has been generated. when the debugger tells you an exception has been generated.
@ -160,7 +160,7 @@
in the IDE settings ("Debugging" tab) in the IDE settings ("Debugging" tab)
The macro IDE settings can now be edited in the File/Setup The macro IDE settings can now be edited in the File/Setup
dialog. dialog.
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/94 * Bugfix: %GITHUB%/issues/94
Retina displays are support to some extend on MacOS. Retina displays are support to some extend on MacOS.
An open topic is the quality of the icons. An open topic is the quality of the icons.
* Enhancement: build system for MacOS * Enhancement: build system for MacOS
@ -174,40 +174,40 @@
- A potential crash ob removing packages was fixed - A potential crash ob removing packages was fixed
* Enhancement: 64 bit coordinate support enabled on Windows builds * Enhancement: 64 bit coordinate support enabled on Windows builds
* Further bugfixes: See links * Further bugfixes: See links
- https://github.com/klayoutmatthias/klayout/issues/21 (Autorun(-early) doesn't seem to run when lym files are inside a package) - %GITHUB%/issues/21 (Autorun(-early) doesn't seem to run when lym files are inside a package)
- https://github.com/klayoutmatthias/klayout/issues/24 (Text insert dialog bug - Ok button isn't working) - %GITHUB%/issues/24 (Text insert dialog bug - Ok button isn't working)
- https://github.com/klayoutmatthias/klayout/issues/26 (Exceptions are reported every time they propagate up in the call chain in the ruby debugger) - %GITHUB%/issues/26 (Exceptions are reported every time they propagate up in the call chain in the ruby debugger)
- https://github.com/klayoutmatthias/klayout/issues/28 (CIF format detection failed) - %GITHUB%/issues/28 (CIF format detection failed)
- https://github.com/klayoutmatthias/klayout/issues/30 (Writer options dialog non-functional on a fresh configuration) - %GITHUB%/issues/30 (Writer options dialog non-functional on a fresh configuration)
- https://github.com/klayoutmatthias/klayout/issues/32 (Rounding issue with instance properties) - %GITHUB%/issues/32 (Rounding issue with instance properties)
- https://github.com/klayoutmatthias/klayout/issues/33 (Plugin factory not working when using with Python) - %GITHUB%/issues/33 (Plugin factory not working when using with Python)
- https://github.com/klayoutmatthias/klayout/issues/36 (Hardening against destruction of object inside event handler) - %GITHUB%/issues/36 (Hardening against destruction of object inside event handler)
- https://github.com/klayoutmatthias/klayout/issues/39 (Action cannot be reassigned) - %GITHUB%/issues/39 (Action cannot be reassigned)
- https://github.com/klayoutmatthias/klayout/issues/40 (Crash in Python binding) - %GITHUB%/issues/40 (Crash in Python binding)
- https://github.com/klayoutmatthias/klayout/issues/41 (Polygon#touches? issue) - %GITHUB%/issues/41 (Polygon#touches? issue)
- https://github.com/klayoutmatthias/klayout/issues/42 (Headless mode support with Qt5/-zz) - %GITHUB%/issues/42 (Headless mode support with Qt5/-zz)
- https://github.com/klayoutmatthias/klayout/issues/43 (Crash when using Qt specific command line options) - %GITHUB%/issues/43 (Crash when using Qt specific command line options)
- https://github.com/klayoutmatthias/klayout/issues/44 (Transformation constructor with x,y not working) - %GITHUB%/issues/44 (Transformation constructor with x,y not working)
- https://github.com/klayoutmatthias/klayout/issues/45 (Partial selection does not capture instance) - %GITHUB%/issues/45 (Partial selection does not capture instance)
- https://github.com/klayoutmatthias/klayout/issues/48 (Cancel does not reset current tool) - %GITHUB%/issues/48 (Cancel does not reset current tool)
- https://github.com/klayoutmatthias/klayout/issues/51 (Segmentation fault on return to main window and other opportunities) - %GITHUB%/issues/51 (Segmentation fault on return to main window and other opportunities)
- https://github.com/klayoutmatthias/klayout/issues/53 (Unreadable 'about' text) - %GITHUB%/issues/53 (Unreadable 'about' text)
- https://github.com/klayoutmatthias/klayout/issues/62 (QXmlSimpleReader#parse cannot be called) - %GITHUB%/issues/62 (QXmlSimpleReader#parse cannot be called)
- https://github.com/klayoutmatthias/klayout/issues/63 (Wrong output on DRC non_interacting with empty second input) - %GITHUB%/issues/63 (Wrong output on DRC non_interacting with empty second input)
- https://github.com/klayoutmatthias/klayout/issues/64 (Crash on exit) - %GITHUB%/issues/64 (Crash on exit)
- https://github.com/klayoutmatthias/klayout/issues/68 (OASIS reader issue with degenerated shapes) - %GITHUB%/issues/68 (OASIS reader issue with degenerated shapes)
- https://github.com/klayoutmatthias/klayout/issues/69 (DRC: 'inside' does not merge shapes of second input) - %GITHUB%/issues/69 (DRC: 'inside' does not merge shapes of second input)
- https://github.com/klayoutmatthias/klayout/issues/71 (Target cell argument is required) - %GITHUB%/issues/71 (Target cell argument is required)
- https://github.com/klayoutmatthias/klayout/issues/72 (Edges/Region NOT issue) - %GITHUB%/issues/72 (Edges/Region NOT issue)
- https://github.com/klayoutmatthias/klayout/issues/73 (Allow 'change layers' on PCells which support a single layer parameter) - %GITHUB%/issues/73 (Allow 'change layers' on PCells which support a single layer parameter)
- https://github.com/klayoutmatthias/klayout/issues/74 (Small-corner boolean issue) - %GITHUB%/issues/74 (Small-corner boolean issue)
- https://github.com/klayoutmatthias/klayout/issues/75 (Python PCell issue when parameters are called 'layer') - %GITHUB%/issues/75 (Python PCell issue when parameters are called 'layer')
- https://github.com/klayoutmatthias/klayout/issues/79 (Replace function enabled also for read-only macros) - %GITHUB%/issues/79 (Replace function enabled also for read-only macros)
* Further enhancements: see links * Further enhancements: see links
- https://github.com/klayoutmatthias/klayout/issues/29 (Permissive mode for OASIS writer on odd-width paths) - %GITHUB%/issues/29 (Permissive mode for OASIS writer on odd-width paths)
- https://github.com/klayoutmatthias/klayout/issues/59 (Async download of package index and details) - %GITHUB%/issues/59 (Async download of package index and details)
- https://github.com/klayoutmatthias/klayout/issues/66 (Authentication dialog indicates retry) - %GITHUB%/issues/66 (Authentication dialog indicates retry)
- https://github.com/klayoutmatthias/klayout/issues/77 (Layout#copy_tree now works in non-editable mode too) - %GITHUB%/issues/77 (Layout#copy_tree now works in non-editable mode too)
0.25 (2017-11-04): 0.25 (2017-11-04):
* Enhancement: Menu customization * Enhancement: Menu customization
@ -269,7 +269,7 @@
Packages can be published on GitHub or any server Packages can be published on GitHub or any server
supporting WebDAV. After registering a package, users supporting WebDAV. After registering a package, users
can install or update packages with a few clicks. can install or update packages with a few clicks.
For more information see https://github.com/klayoutmatthias/klayout/wiki For more information see %GITHUB%/wiki
or "About Packages" in the "Various Topics" area of the main or "About Packages" in the "Various Topics" area of the main
documentation. The package manager is found in the "Tools" documentation. The package manager is found in the "Tools"
menu under "Manage Packages". menu under "Manage Packages".

View File

@ -68,6 +68,8 @@ section
file *.dll file *.dll
file strm*.exe file strm*.exe
file .*-paths.txt file .*-paths.txt
file /r db_plugins
file /r lay_plugins
file /r audio file /r audio
file /r generic file /r generic
file /r iconengines file /r iconengines

View File

@ -309,7 +309,8 @@ HEADERS = \
dbDeepEdgePairs.h \ dbDeepEdgePairs.h \
dbRegionUtils.h \ dbRegionUtils.h \
dbEdgesUtils.h \ dbEdgesUtils.h \
dbRegionProcessors.h dbRegionProcessors.h \
gsiDeclDbHelpers.h
!equals(HAVE_QT, "0") { !equals(HAVE_QT, "0") {

View File

@ -72,13 +72,25 @@ struct SortedCellIndexIterator
SortedCellIndexIterator &operator++() SortedCellIndexIterator &operator++()
{ {
++m_n; ++m_n;
return *this; return *this;
} }
SortedCellIndexIterator &operator+=(size_t n) SortedCellIndexIterator &operator+=(size_t n)
{ {
m_n += n; m_n += n;
return *this; return *this;
}
SortedCellIndexIterator &operator--()
{
--m_n;
return *this;
}
SortedCellIndexIterator &operator-=(size_t n)
{
m_n -= n;
return *this;
} }
bool operator==(const SortedCellIndexIterator &d) const bool operator==(const SortedCellIndexIterator &d) const

View File

@ -1778,9 +1778,32 @@ public:
} }
} }
LayoutLocker (const LayoutLocker &other)
: mp_layout (other.mp_layout)
{
if (mp_layout) {
mp_layout->start_changes ();
}
}
LayoutLocker &operator= (const LayoutLocker &other)
{
if (this == &other) {
return *this;
}
if (mp_layout) {
mp_layout->end_changes ();
}
mp_layout = other.mp_layout;
if (mp_layout) {
mp_layout->start_changes ();
}
return *this;
}
private: private:
LayoutLocker (const LayoutLocker &);
LayoutLocker &operator= (const LayoutLocker &);
db::Layout *mp_layout; db::Layout *mp_layout;
}; };

View File

@ -23,6 +23,8 @@
#include "gsiDecl.h" #include "gsiDecl.h"
#include "gsiDeclDbHelpers.h"
#include "dbLayout.h" #include "dbLayout.h"
#include "dbBoxConvert.h" #include "dbBoxConvert.h"
#include "dbRegion.h" #include "dbRegion.h"
@ -711,70 +713,70 @@ static void dump_mem_statistics (const db::Cell *cell, bool detailed)
ms.print (); ms.print ();
} }
static db::Shapes::shape_iterator begin_shapes (const db::Cell *s, unsigned int layer_index, unsigned int flags) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin_shapes (const db::Cell *s, unsigned int layer_index, unsigned int flags)
{ {
return s->begin (layer_index, flags); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin (layer_index, flags));
} }
static db::Shapes::shape_iterator begin_shapes_all (const db::Cell *s, unsigned int layer_index) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin_shapes_all (const db::Cell *s, unsigned int layer_index)
{ {
return s->begin (layer_index, db::ShapeIterator::All); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin (layer_index, db::ShapeIterator::All));
} }
static db::Shapes::shape_iterator begin_touching_shapes (const db::Cell *s, unsigned int layer_index, const db::Box &box, unsigned int flags) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin_touching_shapes (const db::Cell *s, unsigned int layer_index, const db::Box &box, unsigned int flags)
{ {
return s->begin_touching (layer_index, box, flags); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_touching (layer_index, box, flags));
} }
static db::Shapes::shape_iterator begin_touching_shapes_all (const db::Cell *s, unsigned int layer_index, const db::Box &box) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin_touching_shapes_all (const db::Cell *s, unsigned int layer_index, const db::Box &box)
{ {
return s->begin_touching (layer_index, box, db::ShapeIterator::All); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_touching (layer_index, box, db::ShapeIterator::All));
} }
static db::Shapes::shape_iterator begin_overlapping_shapes (const db::Cell *s, unsigned int layer_index, const db::Box &box, unsigned int flags) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin_overlapping_shapes (const db::Cell *s, unsigned int layer_index, const db::Box &box, unsigned int flags)
{ {
return s->begin_overlapping (layer_index, box, flags); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_overlapping (layer_index, box, flags));
} }
static db::Shapes::shape_iterator begin_overlapping_shapes_all (const db::Cell *s, unsigned int layer_index, const db::Box &box) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin_overlapping_shapes_all (const db::Cell *s, unsigned int layer_index, const db::Box &box)
{ {
return s->begin_overlapping (layer_index, box, db::ShapeIterator::All); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_overlapping (layer_index, box, db::ShapeIterator::All));
} }
static db::Shapes::shape_iterator begin_touching_shapes_um (const db::Cell *s, unsigned int layer_index, const db::DBox &box, unsigned int flags) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin_touching_shapes_um (const db::Cell *s, unsigned int layer_index, const db::DBox &box, unsigned int flags)
{ {
const db::Layout *layout = s->layout (); const db::Layout *layout = s->layout ();
if (! layout) { if (! layout) {
throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot use a micrometer search box"))); throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot use a micrometer search box")));
} }
return s->begin_touching (layer_index, db::CplxTrans (layout->dbu ()).inverted () * box, flags); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_touching (layer_index, db::CplxTrans (layout->dbu ()).inverted () * box, flags));
} }
static db::Shapes::shape_iterator begin_touching_shapes_all_um (const db::Cell *s, unsigned int layer_index, const db::DBox &box) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin_touching_shapes_all_um (const db::Cell *s, unsigned int layer_index, const db::DBox &box)
{ {
const db::Layout *layout = s->layout (); const db::Layout *layout = s->layout ();
if (! layout) { if (! layout) {
throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot use a micrometer search box"))); throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot use a micrometer search box")));
} }
return s->begin_touching (layer_index, db::CplxTrans (layout->dbu ()).inverted () * box, db::ShapeIterator::All); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_touching (layer_index, db::CplxTrans (layout->dbu ()).inverted () * box, db::ShapeIterator::All));
} }
static db::Shapes::shape_iterator begin_overlapping_shapes_um (const db::Cell *s, unsigned int layer_index, const db::DBox &box, unsigned int flags) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin_overlapping_shapes_um (const db::Cell *s, unsigned int layer_index, const db::DBox &box, unsigned int flags)
{ {
const db::Layout *layout = s->layout (); const db::Layout *layout = s->layout ();
if (! layout) { if (! layout) {
throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot use a micrometer search box"))); throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot use a micrometer search box")));
} }
return s->begin_overlapping (layer_index, db::CplxTrans (layout->dbu ()).inverted () * box, flags); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_overlapping (layer_index, db::CplxTrans (layout->dbu ()).inverted () * box, flags));
} }
static db::Shapes::shape_iterator begin_overlapping_shapes_all_um (const db::Cell *s, unsigned int layer_index, const db::DBox &box) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin_overlapping_shapes_all_um (const db::Cell *s, unsigned int layer_index, const db::DBox &box)
{ {
const db::Layout *layout = s->layout (); const db::Layout *layout = s->layout ();
if (! layout) { if (! layout) {
throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot use a micrometer search box"))); throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot use a micrometer search box")));
} }
return s->begin_overlapping (layer_index, db::CplxTrans (layout->dbu ()).inverted () * box, db::ShapeIterator::All); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_overlapping (layer_index, db::CplxTrans (layout->dbu ()).inverted () * box, db::ShapeIterator::All));
} }
static db::Instance insert_inst_with_props (db::Cell *c, const db::Cell::cell_inst_array_type &inst, db::properties_id_type id) static db::Instance insert_inst_with_props (db::Cell *c, const db::Cell::cell_inst_array_type &inst, db::properties_id_type id)
@ -1676,18 +1678,12 @@ static db::DBox cell_dbbox_per_layer (const db::Cell *cell, unsigned int layer_i
return cell->bbox (layer_index) * layout->dbu (); return cell->bbox (layer_index) * layout->dbu ();
} }
static db::Cell::overlapping_iterator cell_begin_overlapping_inst_um (const db::Cell *cell, const db::DBox &db) gsi::layout_locking_iterator1<db::Cell::overlapping_iterator> begin_overlapping_inst (const db::Cell *cell, const db::Cell::box_type &b)
{ {
const db::Layout *layout = cell->layout (); return gsi::layout_locking_iterator1<db::Cell::overlapping_iterator> (cell->layout (), cell->begin_overlapping (b));
if (! layout) {
throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot use a micrometer-unit search boxes")));
}
db::CplxTrans dbu_trans (layout->dbu ());
return cell->begin_overlapping (dbu_trans.inverted () * db);
} }
static db::Cell::touching_iterator cell_begin_touching_inst_um (const db::Cell *cell, const db::DBox &db) gsi::layout_locking_iterator1<db::Cell::overlapping_iterator> begin_overlapping_inst_um (const db::Cell *cell, const db::DBox &dbox)
{ {
const db::Layout *layout = cell->layout (); const db::Layout *layout = cell->layout ();
if (! layout) { if (! layout) {
@ -1695,7 +1691,43 @@ static db::Cell::touching_iterator cell_begin_touching_inst_um (const db::Cell *
} }
db::CplxTrans dbu_trans (layout->dbu ()); db::CplxTrans dbu_trans (layout->dbu ());
return cell->begin_touching (dbu_trans.inverted () * db); return gsi::layout_locking_iterator1<db::Cell::overlapping_iterator> (cell->layout (), cell->begin_overlapping (dbu_trans.inverted () * dbox));
}
gsi::layout_locking_iterator1<db::Cell::touching_iterator> begin_touching_inst (const db::Cell *cell, const db::Cell::box_type &b)
{
return gsi::layout_locking_iterator1<db::Cell::touching_iterator> (cell->layout (), cell->begin_touching (b));
}
gsi::layout_locking_iterator1<db::Cell::touching_iterator> begin_touching_inst_um (const db::Cell *cell, const db::DBox &dbox)
{
const db::Layout *layout = cell->layout ();
if (! layout) {
throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot use a micrometer-unit search boxes")));
}
db::CplxTrans dbu_trans (layout->dbu ());
return gsi::layout_locking_iterator1<db::Cell::touching_iterator> (cell->layout (), cell->begin_touching (dbu_trans.inverted () * dbox));
}
gsi::layout_locking_iterator1<db::Cell::child_cell_iterator> begin_child_cells (const db::Cell *cell)
{
return gsi::layout_locking_iterator1<db::Cell::child_cell_iterator> (cell->layout (), cell->begin_child_cells ());
}
gsi::layout_locking_iterator1<db::Cell::parent_inst_iterator> begin_parent_insts (const db::Cell *cell)
{
return gsi::layout_locking_iterator1<db::Cell::parent_inst_iterator> (cell->layout (), cell->begin_parent_insts ());
}
gsi::layout_locking_iterator2<db::Cell::parent_cell_iterator> begin_parent_cells (const db::Cell *cell)
{
return gsi::layout_locking_iterator2<db::Cell::parent_cell_iterator> (cell->layout (), cell->begin_parent_cells (), cell->end_parent_cells ());
}
static layout_locking_iterator1<db::Cell::const_iterator> begin_inst (db::Cell *cell)
{
return layout_locking_iterator1<db::Cell::const_iterator> (cell->layout (), cell->begin ());
} }
Class<db::Cell> decl_Cell ("db", "Cell", Class<db::Cell> decl_Cell ("db", "Cell",
@ -2566,7 +2598,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"\n" "\n"
"This method has been introduced in version 0.25." "This method has been introduced in version 0.25."
) + ) +
gsi::iterator ("each_overlapping_inst", (db::Cell::overlapping_iterator (db::Cell::*) (const db::Cell::box_type &b) const) &db::Cell::begin_overlapping, gsi::arg ("b"), gsi::iterator_ext ("each_overlapping_inst", &begin_overlapping_inst, gsi::arg ("b"),
"@brief Gets the instances overlapping the given rectangle\n" "@brief Gets the instances overlapping the given rectangle\n"
"\n" "\n"
"This will iterate over all child cell\n" "This will iterate over all child cell\n"
@ -2576,7 +2608,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"\n" "\n"
"Starting with version 0.15, this iterator delivers \\Instance objects rather than \\CellInstArray objects." "Starting with version 0.15, this iterator delivers \\Instance objects rather than \\CellInstArray objects."
) + ) +
gsi::iterator_ext ("each_overlapping_inst", &cell_begin_overlapping_inst_um, gsi::arg ("b"), gsi::iterator_ext ("each_overlapping_inst", &begin_overlapping_inst_um, gsi::arg ("b"),
"@brief Gets the instances overlapping the given rectangle, with the rectangle in micrometer units\n" "@brief Gets the instances overlapping the given rectangle, with the rectangle in micrometer units\n"
"\n" "\n"
"This will iterate over all child cell\n" "This will iterate over all child cell\n"
@ -2589,7 +2621,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"\n" "\n"
"This variant has been introduced in version 0.25." "This variant has been introduced in version 0.25."
) + ) +
gsi::iterator ("each_touching_inst", (db::Cell::touching_iterator (db::Cell::*) (const db::Cell::box_type &b) const) &db::Cell::begin_touching, gsi::arg ("b"), gsi::iterator_ext ("each_touching_inst", &begin_touching_inst, gsi::arg ("b"),
"@brief Gets the instances touching the given rectangle\n" "@brief Gets the instances touching the given rectangle\n"
"\n" "\n"
"This will iterate over all child cell\n" "This will iterate over all child cell\n"
@ -2599,7 +2631,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"\n" "\n"
"Starting with version 0.15, this iterator delivers \\Instance objects rather than \\CellInstArray objects." "Starting with version 0.15, this iterator delivers \\Instance objects rather than \\CellInstArray objects."
) + ) +
gsi::iterator_ext ("each_touching_inst", &cell_begin_touching_inst_um, gsi::arg ("b"), gsi::iterator_ext ("each_touching_inst", &begin_touching_inst_um, gsi::arg ("b"),
"@brief Gets the instances touching the given rectangle, with the rectangle in micrometer units\n" "@brief Gets the instances touching the given rectangle, with the rectangle in micrometer units\n"
"\n" "\n"
"This will iterate over all child cell\n" "This will iterate over all child cell\n"
@ -2612,7 +2644,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"\n" "\n"
"This variant has been introduced in version 0.25." "This variant has been introduced in version 0.25."
) + ) +
gsi::iterator ("each_child_cell", &db::Cell::begin_child_cells, gsi::iterator_ext ("each_child_cell", &begin_child_cells,
"@brief Iterates over all child cells\n" "@brief Iterates over all child cells\n"
"\n" "\n"
"This iterator will report the child cell indices, not every instance.\n" "This iterator will report the child cell indices, not every instance.\n"
@ -2623,12 +2655,12 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"The number of child cells (not child instances!) is returned.\n" "The number of child cells (not child instances!) is returned.\n"
"CAUTION: this method is SLOW, in particular if many instances are present.\n" "CAUTION: this method is SLOW, in particular if many instances are present.\n"
) + ) +
gsi::iterator ("each_inst", (db::Cell::const_iterator (db::Cell::*) () const) &db::Cell::begin, gsi::iterator_ext ("each_inst", &begin_inst,
"@brief Iterates over all child instances (which may actually be instance arrays)\n" "@brief Iterates over all child instances (which may actually be instance arrays)\n"
"\n" "\n"
"Starting with version 0.15, this iterator delivers \\Instance objects rather than \\CellInstArray objects." "Starting with version 0.15, this iterator delivers \\Instance objects rather than \\CellInstArray objects."
) + ) +
gsi::iterator ("each_parent_inst", &db::Cell::begin_parent_insts, gsi::iterator_ext ("each_parent_inst", &begin_parent_insts,
"@brief Iterates over the parent instance list (which may actually be instance arrays)\n" "@brief Iterates over the parent instance list (which may actually be instance arrays)\n"
"\n" "\n"
"The parent instances are basically inversions of the instances. Using parent instances " "The parent instances are basically inversions of the instances. Using parent instances "
@ -2639,7 +2671,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"\n" "\n"
"The number of parent cells (cells which reference our cell) is reported." "The number of parent cells (cells which reference our cell) is reported."
) + ) +
gsi::iterator ("each_parent_cell", &db::Cell::begin_parent_cells, &db::Cell::end_parent_cells, gsi::iterator_ext ("each_parent_cell", &begin_parent_cells,
"@brief Iterates over all parent cells\n" "@brief Iterates over all parent cells\n"
"\n" "\n"
"This iterator will iterate over the parent cells, just returning their\n" "This iterator will iterate over the parent cells, just returning their\n"

View File

@ -0,0 +1,83 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2019 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_gsiDeclDbHelpers
#define HDR_gsiDeclDbHelpers
#include "dbLayoutUtils.h"
namespace gsi
{
/**
* @brief A safe iterator locking the layout while iterating a container within it
*/
template <class I>
class layout_locking_iterator2
: private db::LayoutLocker
{
public:
typedef typename I::value_type value_type;
typedef typename I::reference reference;
typedef typename I::pointer pointer;
typedef typename I::difference_type difference_type;
typedef typename I::iterator_category iterator_category;
layout_locking_iterator2 (const db::Layout *layout, const I &b, const I &e) : db::LayoutLocker (const_cast<db::Layout *> (layout)), m_b (b), m_e (e) {}
bool at_end () const { return m_b == m_e; }
void operator++ () { ++m_b; }
reference operator* () const { return *m_b; }
pointer operator-> () const { return m_b.operator-> (); }
private:
I m_b, m_e;
};
/**
* @brief A safe iterator locking the layout while iterating a container within it
*/
template <class I>
class layout_locking_iterator1
: private db::LayoutLocker
{
public:
typedef typename I::value_type value_type;
typedef typename I::reference reference;
typedef typename I::pointer pointer;
typedef typename I::difference_type difference_type;
typedef typename I::iterator_category iterator_category;
layout_locking_iterator1 (const db::Layout *layout, const I &i) : db::LayoutLocker (const_cast<db::Layout *> (layout)), m_i (i) { }
bool at_end () const { return m_i.at_end (); }
void operator++ () { ++m_i; }
reference operator* () const { return *m_i; }
pointer operator-> () const { return m_i.operator-> (); }
private:
I m_i;
};
}
#endif

View File

@ -22,6 +22,8 @@
#include "gsiDecl.h" #include "gsiDecl.h"
#include "gsiDeclDbHelpers.h"
#include "dbShapes.h" #include "dbShapes.h"
#include "dbShape.h" #include "dbShape.h"
#include "dbLayout.h" #include "dbLayout.h"
@ -101,54 +103,54 @@ static db::Shape dinsert_with_properties (db::Shapes *s, const Sh &p, db::proper
return s->insert (db::object_with_properties<ISh> (db::CplxTrans (shapes_dbu (s)).inverted () * p, id)); return s->insert (db::object_with_properties<ISh> (db::CplxTrans (shapes_dbu (s)).inverted () * p, id));
} }
static db::Shapes::shape_iterator begin (const db::Shapes *s, unsigned int flags) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator> begin (const db::Shapes *s, unsigned int flags)
{ {
return s->begin (flags); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin (flags));
} }
static db::Shapes::shape_iterator begin_all (const db::Shapes *s) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator>begin_all (const db::Shapes *s)
{ {
return s->begin (db::ShapeIterator::All); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin (db::ShapeIterator::All));
} }
static db::Shapes::shape_iterator begin_overlapping (const db::Shapes *s, unsigned int flags, const db::Box &region) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator>begin_overlapping (const db::Shapes *s, unsigned int flags, const db::Box &region)
{ {
return s->begin_overlapping (region, flags); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_overlapping (region, flags));
} }
static db::Shapes::shape_iterator begin_doverlapping (const db::Shapes *s, unsigned int flags, const db::DBox &region) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator>begin_doverlapping (const db::Shapes *s, unsigned int flags, const db::DBox &region)
{ {
return s->begin_overlapping (db::CplxTrans (shapes_dbu (s)).inverted () * region, flags); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_overlapping (db::CplxTrans (shapes_dbu (s)).inverted () * region, flags));
} }
static db::Shapes::shape_iterator begin_overlapping_all (const db::Shapes *s, const db::Box &region) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator>begin_overlapping_all (const db::Shapes *s, const db::Box &region)
{ {
return s->begin_overlapping (region, db::ShapeIterator::All); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_overlapping (region, db::ShapeIterator::All));
} }
static db::Shapes::shape_iterator begin_doverlapping_all (const db::Shapes *s, const db::DBox &region) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator>begin_doverlapping_all (const db::Shapes *s, const db::DBox &region)
{ {
return s->begin_overlapping (db::CplxTrans (shapes_dbu (s)).inverted () * region, db::ShapeIterator::All); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_overlapping (db::CplxTrans (shapes_dbu (s)).inverted () * region, db::ShapeIterator::All));
} }
static db::Shapes::shape_iterator begin_touching (const db::Shapes *s, unsigned int flags, const db::Box &region) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator>begin_touching (const db::Shapes *s, unsigned int flags, const db::Box &region)
{ {
return s->begin_touching (region, flags); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_touching (region, flags));
} }
static db::Shapes::shape_iterator begin_dtouching (const db::Shapes *s, unsigned int flags, const db::DBox &region) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator>begin_dtouching (const db::Shapes *s, unsigned int flags, const db::DBox &region)
{ {
return s->begin_touching (db::CplxTrans (shapes_dbu (s)).inverted () * region, flags); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_touching (db::CplxTrans (shapes_dbu (s)).inverted () * region, flags));
} }
static db::Shapes::shape_iterator begin_touching_all (const db::Shapes *s, const db::Box &region) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator>begin_touching_all (const db::Shapes *s, const db::Box &region)
{ {
return s->begin_touching (region, db::ShapeIterator::All); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_touching (region, db::ShapeIterator::All));
} }
static db::Shapes::shape_iterator begin_dtouching_all (const db::Shapes *s, const db::DBox &region) static gsi::layout_locking_iterator1<db::Shapes::shape_iterator>begin_dtouching_all (const db::Shapes *s, const db::DBox &region)
{ {
return s->begin_touching (db::CplxTrans (shapes_dbu (s)).inverted () * region, db::ShapeIterator::All); return gsi::layout_locking_iterator1<db::Shapes::shape_iterator> (s->layout (), s->begin_touching (db::CplxTrans (shapes_dbu (s)).inverted () * region, db::ShapeIterator::All));
} }
static void transform_shapes (db::Shapes *s, const db::Trans &trans) static void transform_shapes (db::Shapes *s, const db::Trans &trans)

View File

@ -726,8 +726,6 @@ DitherPatternInfo::from_strings (const std::vector<std::string> &strv)
uint_from_string (strv [strv.size () - 1 - i].c_str (), data [i], w); uint_from_string (strv [strv.size () - 1 - i].c_str (), data [i], w);
} }
std::reverse (&data[0], &data[h]);
set_pattern (data, w, h); set_pattern (data, w, h);
} }

View File

@ -887,6 +887,21 @@ public:
init (); init ();
} }
/**
* @brief Returns a value indicating whether the given index is valid
*/
bool is_used (size_type n) const
{
if (n >= first () && n < last ()) {
if (mp_rdata) {
return mp_rdata->is_used (n);
} else {
return true;
}
}
return false;
}
/** /**
* @brief For diagnostics purposes only * @brief For diagnostics purposes only
*/ */
@ -908,18 +923,6 @@ private:
mp_rdata = 0; mp_rdata = 0;
} }
bool is_used (size_type n) const
{
if (n >= first () && n < last ()) {
if (mp_rdata) {
return mp_rdata->is_used (n);
} else {
return true;
}
}
return false;
}
size_type first () const size_type first () const
{ {
if (mp_rdata) { if (mp_rdata) {

BIN
testdata/gds/t200.gds vendored Normal file

Binary file not shown.

View File

@ -1994,6 +1994,45 @@ END
end end
# Iterating while flatten
def test_issue200
ly = RBA::Layout.new
ly.read(ENV["TESTSRC"] + "/testdata/gds/t200.gds")
l1 = ly.layer(1, 0)
l2 = ly.layer(2, 0)
l3 = ly.layer(3, 0)
tc_name = ly.top_cell.name
r1 = RBA::Region::new(ly.top_cell.begin_shapes_rec(l1))
r2 = RBA::Region::new(ly.top_cell.begin_shapes_rec(l2))
r3 = RBA::Region::new(ly.top_cell.begin_shapes_rec(l3))
assert_equal(r1.size > 0, true)
assert_equal(r2.size > 0, true)
assert_equal(r3.size == 0, true)
ly.top_cell.each_inst do |ci|
ci.flatten
end
tc = ly.cell(tc_name)
assert_equal(ly.top_cells.size, 4)
assert_equal(tc.child_cells, 0)
assert_equal(tc.parent_cells, 0)
rr1 = RBA::Region::new(tc.begin_shapes_rec(l1))
rr2 = RBA::Region::new(tc.begin_shapes_rec(l2))
rr3 = RBA::Region::new(tc.begin_shapes_rec(l3))
assert_equal(r1.size, rr1.size)
assert_equal(r2.size, rr2.size)
assert_equal(r3.size, rr3.size)
assert_equal((rr1 ^ r1).is_empty?, true)
assert_equal((rr2 ^ r2).is_empty?, true)
assert_equal((rr3 ^ r3).is_empty?, true)
end
end end
load("test_epilogue.rb") load("test_epilogue.rb")