mirror of https://github.com/KLayout/klayout.git
Merge remote-tracking branch 'origin/master' into dvb
This commit is contained in:
commit
a4d2be7fbf
2
setup.py
2
setup.py
|
|
@ -326,7 +326,7 @@ class Config(object):
|
||||||
"""
|
"""
|
||||||
Gets the version string
|
Gets the version string
|
||||||
"""
|
"""
|
||||||
return "0.26.0.dev15"
|
return "0.26.0.dev16"
|
||||||
|
|
||||||
|
|
||||||
config = Config()
|
config = Config()
|
||||||
|
|
|
||||||
|
|
@ -450,7 +450,7 @@ AsIfFlatEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Co
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeRelationFilter check (rel, d, metrics);
|
EdgeRelationFilter check (rel, d, metrics);
|
||||||
check.set_include_zero (other != 0);
|
check.set_include_zero (false);
|
||||||
check.set_whole_edges (whole_edges);
|
check.set_whole_edges (whole_edges);
|
||||||
check.set_ignore_angle (ignore_angle);
|
check.set_ignore_angle (ignore_angle);
|
||||||
check.set_min_projection (min_projection);
|
check.set_min_projection (min_projection);
|
||||||
|
|
|
||||||
|
|
@ -642,7 +642,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeRelationFilter check (rel, d, metrics);
|
EdgeRelationFilter check (rel, d, metrics);
|
||||||
check.set_include_zero (other != 0);
|
check.set_include_zero (false);
|
||||||
check.set_whole_edges (whole_edges);
|
check.set_whole_edges (whole_edges);
|
||||||
check.set_ignore_angle (ignore_angle);
|
check.set_ignore_angle (ignore_angle);
|
||||||
check.set_min_projection (min_projection);
|
check.set_min_projection (min_projection);
|
||||||
|
|
@ -664,6 +664,7 @@ AsIfFlatRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord
|
||||||
std::auto_ptr<FlatEdgePairs> result (new FlatEdgePairs ());
|
std::auto_ptr<FlatEdgePairs> result (new FlatEdgePairs ());
|
||||||
|
|
||||||
EdgeRelationFilter check (rel, d, metrics);
|
EdgeRelationFilter check (rel, d, metrics);
|
||||||
|
check.set_include_zero (false);
|
||||||
check.set_whole_edges (whole_edges);
|
check.set_whole_edges (whole_edges);
|
||||||
check.set_ignore_angle (ignore_angle);
|
check.set_ignore_angle (ignore_angle);
|
||||||
check.set_min_projection (min_projection);
|
check.set_min_projection (min_projection);
|
||||||
|
|
@ -764,7 +765,7 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
|
||||||
db::Box b = bbox ().enlarged (db::Vector (dx, dy));
|
db::Box b = bbox ().enlarged (db::Vector (dx, dy));
|
||||||
return region_from_box (b);
|
return region_from_box (b);
|
||||||
|
|
||||||
} else if (! merged_semantics ()) {
|
} else if (! merged_semantics () || is_merged ()) {
|
||||||
|
|
||||||
// Generic case
|
// Generic case
|
||||||
std::auto_ptr<FlatRegion> new_region (new FlatRegion (false /*output isn't merged*/));
|
std::auto_ptr<FlatRegion> new_region (new FlatRegion (false /*output isn't merged*/));
|
||||||
|
|
@ -801,7 +802,7 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
|
||||||
db::ShapeGenerator pc (new_region->raw_polygons (), true /*clear*/);
|
db::ShapeGenerator pc (new_region->raw_polygons (), true /*clear*/);
|
||||||
db::PolygonGenerator pg2 (pc, false /*don't resolve holes*/, true /*min. coherence*/);
|
db::PolygonGenerator pg2 (pc, false /*don't resolve holes*/, true /*min. coherence*/);
|
||||||
db::SizingPolygonFilter siz (pg2, dx, dy, mode);
|
db::SizingPolygonFilter siz (pg2, dx, dy, mode);
|
||||||
db::PolygonGenerator pg (siz, false /*don't resolve holes*/, false /*min. coherence*/);
|
db::PolygonGenerator pg (siz, false /*don't resolve holes*/, min_coherence () /*min. coherence*/);
|
||||||
db::BooleanOp op (db::BooleanOp::Or);
|
db::BooleanOp op (db::BooleanOp::Or);
|
||||||
ep.process (pg, op);
|
ep.process (pg, op);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1404,6 +1404,7 @@ DeepEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Coord
|
||||||
ensure_merged_edges_valid ();
|
ensure_merged_edges_valid ();
|
||||||
|
|
||||||
EdgeRelationFilter check (rel, d, metrics);
|
EdgeRelationFilter check (rel, d, metrics);
|
||||||
|
check.set_include_zero (false);
|
||||||
check.set_whole_edges (whole_edges);
|
check.set_whole_edges (whole_edges);
|
||||||
check.set_ignore_angle (ignore_angle);
|
check.set_ignore_angle (ignore_angle);
|
||||||
check.set_min_projection (min_projection);
|
check.set_min_projection (min_projection);
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,11 @@ void DeepRegion::merged_semantics_changed ()
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeepRegion::min_coherence_changed ()
|
||||||
|
{
|
||||||
|
set_is_merged (false);
|
||||||
|
}
|
||||||
|
|
||||||
RegionIteratorDelegate *
|
RegionIteratorDelegate *
|
||||||
DeepRegion::begin () const
|
DeepRegion::begin () const
|
||||||
{
|
{
|
||||||
|
|
@ -1461,6 +1466,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
|
||||||
ensure_merged_polygons_valid ();
|
ensure_merged_polygons_valid ();
|
||||||
|
|
||||||
EdgeRelationFilter check (rel, d, metrics);
|
EdgeRelationFilter check (rel, d, metrics);
|
||||||
|
check.set_include_zero (false);
|
||||||
check.set_whole_edges (whole_edges);
|
check.set_whole_edges (whole_edges);
|
||||||
check.set_ignore_angle (ignore_angle);
|
check.set_ignore_angle (ignore_angle);
|
||||||
check.set_min_projection (min_projection);
|
check.set_min_projection (min_projection);
|
||||||
|
|
@ -1489,6 +1495,7 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, b
|
||||||
ensure_merged_polygons_valid ();
|
ensure_merged_polygons_valid ();
|
||||||
|
|
||||||
EdgeRelationFilter check (rel, d, metrics);
|
EdgeRelationFilter check (rel, d, metrics);
|
||||||
|
check.set_include_zero (false);
|
||||||
check.set_whole_edges (whole_edges);
|
check.set_whole_edges (whole_edges);
|
||||||
check.set_ignore_angle (ignore_angle);
|
check.set_ignore_angle (ignore_angle);
|
||||||
check.set_min_projection (min_projection);
|
check.set_min_projection (min_projection);
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void merged_semantics_changed ();
|
virtual void merged_semantics_changed ();
|
||||||
|
virtual void min_coherence_changed ();
|
||||||
void set_is_merged (bool f);
|
void set_is_merged (bool f);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,12 @@ bool euclidian_near_part_of_edge (bool include_zero, db::Coord d, const db::Edge
|
||||||
db::Edge g (other);
|
db::Edge g (other);
|
||||||
int s1 = e.side_of (g.p1 ());
|
int s1 = e.side_of (g.p1 ());
|
||||||
int s2 = e.side_of (g.p2 ());
|
int s2 = e.side_of (g.p2 ());
|
||||||
|
|
||||||
|
// "kissing corner" issue: force include zero if the edges are collinear and overlap.
|
||||||
|
if (! include_zero && s1 == 0 && s2 == 0 && e.intersect (g)) {
|
||||||
|
include_zero = true;
|
||||||
|
}
|
||||||
|
|
||||||
int thr = include_zero ? 0 : -1;
|
int thr = include_zero ? 0 : -1;
|
||||||
|
|
||||||
// keep only part of other which is on the "inside" side of e
|
// keep only part of other which is on the "inside" side of e
|
||||||
|
|
@ -203,6 +209,12 @@ static bool var_near_part_of_edge (bool include_zero, db::Coord d, db::Coord dd,
|
||||||
db::Edge g (other);
|
db::Edge g (other);
|
||||||
int s1 = e.side_of (g.p1 ());
|
int s1 = e.side_of (g.p1 ());
|
||||||
int s2 = e.side_of (g.p2 ());
|
int s2 = e.side_of (g.p2 ());
|
||||||
|
|
||||||
|
// "kissing corner" issue: force include zero if the edges are collinear and overlap
|
||||||
|
if (! include_zero && s1 == 0 && s2 == 0 && e.intersect (g)) {
|
||||||
|
include_zero = true;
|
||||||
|
}
|
||||||
|
|
||||||
int thr = include_zero ? 0 : -1;
|
int thr = include_zero ? 0 : -1;
|
||||||
|
|
||||||
// keep only part of other which is on the "inside" side of e
|
// keep only part of other which is on the "inside" side of e
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,13 @@ void FlatRegion::merged_semantics_changed ()
|
||||||
m_merged_polygons_valid = false;
|
m_merged_polygons_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlatRegion::min_coherence_changed ()
|
||||||
|
{
|
||||||
|
m_is_merged = false;
|
||||||
|
m_merged_polygons.clear ();
|
||||||
|
m_merged_polygons_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
void FlatRegion::reserve (size_t n)
|
void FlatRegion::reserve (size_t n)
|
||||||
{
|
{
|
||||||
m_polygons.reserve (db::Polygon::tag (), n);
|
m_polygons.reserve (db::Polygon::tag (), n);
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void merged_semantics_changed ();
|
virtual void merged_semantics_changed ();
|
||||||
|
virtual void min_coherence_changed ();
|
||||||
virtual Box compute_bbox () const;
|
virtual Box compute_bbox () const;
|
||||||
void invalidate_cache ();
|
void invalidate_cache ();
|
||||||
void set_is_merged (bool m);
|
void set_is_merged (bool m);
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,14 @@ OriginalLayerRegion::merged_semantics_changed ()
|
||||||
m_merged_polygons_valid = false;
|
m_merged_polygons_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OriginalLayerRegion::min_coherence_changed ()
|
||||||
|
{
|
||||||
|
m_is_merged = false;
|
||||||
|
m_merged_polygons.clear ();
|
||||||
|
m_merged_polygons_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
RegionIteratorDelegate *
|
RegionIteratorDelegate *
|
||||||
OriginalLayerRegion::begin () const
|
OriginalLayerRegion::begin () const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void merged_semantics_changed ();
|
virtual void merged_semantics_changed ();
|
||||||
|
virtual void min_coherence_changed ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OriginalLayerRegion &operator= (const OriginalLayerRegion &other);
|
OriginalLayerRegion &operator= (const OriginalLayerRegion &other);
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,10 @@ void RegionDelegate::set_base_verbosity (int vb)
|
||||||
|
|
||||||
void RegionDelegate::set_min_coherence (bool f)
|
void RegionDelegate::set_min_coherence (bool f)
|
||||||
{
|
{
|
||||||
m_merge_min_coherence = f;
|
if (f != m_merge_min_coherence) {
|
||||||
|
m_merge_min_coherence = f;
|
||||||
|
min_coherence_changed ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegionDelegate::set_merged_semantics (bool f)
|
void RegionDelegate::set_merged_semantics (bool f)
|
||||||
|
|
|
||||||
|
|
@ -319,6 +319,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void merged_semantics_changed () { }
|
virtual void merged_semantics_changed () { }
|
||||||
|
virtual void min_coherence_changed () { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_merged_semantics;
|
bool m_merged_semantics;
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,21 @@ Edge2EdgeCheckBase::prepare_next_pass ()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool shields (const db::EdgePair &ep, const db::Edge &q)
|
||||||
|
{
|
||||||
|
db::Edge pe1 (ep.first ().p1 (), ep.second ().p2 ());
|
||||||
|
db::Edge pe2 (ep.second ().p1 (), ep.first ().p2 ());
|
||||||
|
|
||||||
|
std::pair<bool, db::Point> ip1 = pe1.intersect_point (q);
|
||||||
|
std::pair<bool, db::Point> ip2 = pe2.intersect_point (q);
|
||||||
|
|
||||||
|
if (ip1.first && ip2.first) {
|
||||||
|
return ip1.second != ip2.second || (ip1.second != q.p1 () && ip2.second != q.p2 ());
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size_t p2)
|
Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size_t p2)
|
||||||
{
|
{
|
||||||
|
|
@ -128,8 +143,7 @@ Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size
|
||||||
for (std::vector<size_t>::const_iterator i = nn.begin (); i != nn.end (); ++i) {
|
for (std::vector<size_t>::const_iterator i = nn.begin (); i != nn.end (); ++i) {
|
||||||
if (! m_ep_discarded [*i]) {
|
if (! m_ep_discarded [*i]) {
|
||||||
db::EdgePair ep = m_ep [*i].normalized ();
|
db::EdgePair ep = m_ep [*i].normalized ();
|
||||||
if (db::Edge (ep.first ().p1 (), ep.second ().p2 ()).intersect (*o2) &&
|
if (shields (ep, *o2)) {
|
||||||
db::Edge (ep.second ().p1 (), ep.first ().p2 ()).intersect (*o2)) {
|
|
||||||
m_ep_discarded [*i] = true;
|
m_ep_discarded [*i] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1406,3 +1406,30 @@ TEST(101_DeepFlatCollaboration)
|
||||||
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au101.gds");
|
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au101.gds");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(issue_277)
|
||||||
|
{
|
||||||
|
db::Layout ly;
|
||||||
|
db::cell_index_type top_cell_index = ly.add_cell ("TOP");
|
||||||
|
db::Cell &top_cell = ly.cell (top_cell_index);
|
||||||
|
unsigned int l1 = ly.insert_layer ();
|
||||||
|
|
||||||
|
db::Shapes &s = top_cell.shapes (l1);
|
||||||
|
s.insert (db::Box (0, 0, 400, 400));
|
||||||
|
s.insert (db::Box (400, 400, 800, 800));
|
||||||
|
|
||||||
|
|
||||||
|
db::DeepShapeStore dss;
|
||||||
|
|
||||||
|
db::Region r (db::RecursiveShapeIterator (ly, top_cell, l1), dss);
|
||||||
|
|
||||||
|
EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "");
|
||||||
|
|
||||||
|
r.set_min_coherence (true);
|
||||||
|
EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "(399,399;399,401;401,401;401,399)");
|
||||||
|
|
||||||
|
r.merge ();
|
||||||
|
EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "(399,399;399,401;401,401;401,399)");
|
||||||
|
|
||||||
|
r.set_min_coherence (false); // needs to merge again
|
||||||
|
EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "");
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,7 @@ TEST(7)
|
||||||
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (-1, 30), db::Point (-1, -20)), &output);
|
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (-1, 30), db::Point (-1, -20)), &output);
|
||||||
EXPECT_EQ (res, false);
|
EXPECT_EQ (res, false);
|
||||||
f.set_include_zero (false);
|
f.set_include_zero (false);
|
||||||
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (0, 30), db::Point (0, -20)), &output);
|
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (0, 30), db::Point (0, 11)), &output);
|
||||||
EXPECT_EQ (res, false);
|
EXPECT_EQ (res, false);
|
||||||
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (1, 30), db::Point (1, -20)), &output);
|
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (1, 30), db::Point (1, -20)), &output);
|
||||||
EXPECT_EQ (res, true);
|
EXPECT_EQ (res, true);
|
||||||
|
|
@ -355,3 +355,50 @@ TEST(7)
|
||||||
EXPECT_EQ (res, false);
|
EXPECT_EQ (res, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(8_KissingCornerProblem)
|
||||||
|
{
|
||||||
|
// The kissing corner problem is solved by allowing distance-0 width and space relations and checking them
|
||||||
|
// if the projection is >0.
|
||||||
|
|
||||||
|
db::EdgeRelationFilter f (db::WidthRelation, 10);
|
||||||
|
f.set_include_zero (false);
|
||||||
|
db::EdgePair output;
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
f.set_metrics (db::Euclidian);
|
||||||
|
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 201), db::Point (0, 101)), &output);
|
||||||
|
EXPECT_EQ (res, false);
|
||||||
|
res = f.check (db::Edge (db::Point (1, 0), db::Point (1, 100)), db::Edge (db::Point (0, 201), db::Point (0, 0)), &output);
|
||||||
|
EXPECT_EQ (res, false);
|
||||||
|
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 100)), &output);
|
||||||
|
EXPECT_EQ (res, true);
|
||||||
|
EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,90;0,100):(0,110;0,100)");
|
||||||
|
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 50)), &output);
|
||||||
|
EXPECT_EQ (res, true);
|
||||||
|
EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,40;0,100):(0,110;0,50)");
|
||||||
|
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 0), db::Point (0, -100)), &output);
|
||||||
|
EXPECT_EQ (res, true);
|
||||||
|
EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(0,0;0,-10)");
|
||||||
|
res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, -1), db::Point (0, -100)), &output);
|
||||||
|
EXPECT_EQ (res, false);
|
||||||
|
|
||||||
|
f = db::EdgeRelationFilter (db::SpaceRelation, 10);
|
||||||
|
f.set_include_zero (false);
|
||||||
|
|
||||||
|
f.set_metrics (db::Euclidian);
|
||||||
|
res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 101), db::Point (0, 201)), &output);
|
||||||
|
EXPECT_EQ (res, false);
|
||||||
|
res = f.check (db::Edge (db::Point (1, 100), db::Point (1, 0)), db::Edge (db::Point (0, 0), db::Point (0, 200)), &output);
|
||||||
|
EXPECT_EQ (res, false);
|
||||||
|
res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 100), db::Point (0, 200)), &output);
|
||||||
|
EXPECT_EQ (res, true);
|
||||||
|
EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,100;0,90):(0,100;0,110)");
|
||||||
|
res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 50), db::Point (0, 200)), &output);
|
||||||
|
EXPECT_EQ (res, true);
|
||||||
|
EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,100;0,40):(0,50;0,110)");
|
||||||
|
res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, 0)), &output);
|
||||||
|
EXPECT_EQ (res, true);
|
||||||
|
EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,10;0,0):(0,-10;0,0)");
|
||||||
|
res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, -1)), &output);
|
||||||
|
EXPECT_EQ (res, false);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -740,7 +740,7 @@ TEST(20)
|
||||||
EXPECT_EQ (r1.has_valid_edges (), false);
|
EXPECT_EQ (r1.has_valid_edges (), false);
|
||||||
db::Edges r2 (db::RecursiveShapeIterator (ly, ly.cell (top), l2), false);
|
db::Edges r2 (db::RecursiveShapeIterator (ly, ly.cell (top), l2), false);
|
||||||
EXPECT_EQ (r2.has_valid_edges (), false);
|
EXPECT_EQ (r2.has_valid_edges (), false);
|
||||||
EXPECT_EQ (r1.separation_check (r2, 20).to_string (), "(50,0;50,30)/(40,40;40,10);(63,30;80,30)/(97,40;80,40);(80,30;80,20)/(80,40;80,50);(50,40;50,57)/(40,40;40,23);(80,70;80,40)/(80,40;80,70);(60,40;50,40)/(30,40;40,40)");
|
EXPECT_EQ (r1.separation_check (r2, 20).to_string (), "(50,0;50,30)/(40,40;40,10);(63,30;80,30)/(97,40;80,40);(50,40;50,57)/(40,40;40,23);(80,70;80,40)/(80,40;80,70)");
|
||||||
EXPECT_EQ (r1.separation_check (r2, 20, false, db::Projection).to_string (), "(50,10;50,30)/(40,30;40,10);(80,70;80,40)/(80,40;80,70)");
|
EXPECT_EQ (r1.separation_check (r2, 20, false, db::Projection).to_string (), "(50,10;50,30)/(40,30;40,10);(80,70;80,40)/(80,40;80,70)");
|
||||||
EXPECT_EQ (r1.separation_check (r2, 20, false, db::Euclidian, 90, 1).to_string (), "(50,0;50,30)/(40,40;40,10);(80,70;80,40)/(80,40;80,70)");
|
EXPECT_EQ (r1.separation_check (r2, 20, false, db::Euclidian, 90, 1).to_string (), "(50,0;50,30)/(40,40;40,10);(80,70;80,40)/(80,40;80,70)");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1397,3 +1397,21 @@ TEST(issue_228)
|
||||||
EXPECT_EQ (r.selected_interacting (rr).to_string (), r.to_string ());
|
EXPECT_EQ (r.selected_interacting (rr).to_string (), r.to_string ());
|
||||||
EXPECT_EQ (rr.selected_interacting (r).to_string (), rr.to_string ());
|
EXPECT_EQ (rr.selected_interacting (r).to_string (), rr.to_string ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(issue_277)
|
||||||
|
{
|
||||||
|
db::Region r;
|
||||||
|
r.insert (db::Box (0, 0, 400, 400));
|
||||||
|
r.insert (db::Box (400, 400, 800, 800));
|
||||||
|
|
||||||
|
EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "");
|
||||||
|
|
||||||
|
r.set_min_coherence (true);
|
||||||
|
EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "(399,399;399,401;401,401;401,399)");
|
||||||
|
|
||||||
|
r.merge ();
|
||||||
|
EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "(399,399;399,401;401,401;401,399)");
|
||||||
|
|
||||||
|
r.set_min_coherence (false); // needs to merge again
|
||||||
|
EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "");
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -533,3 +533,89 @@ TEST(12_NetlistJoinLabels)
|
||||||
CHECKPOINT ();
|
CHECKPOINT ();
|
||||||
compare_netlists (_this, output, au);
|
compare_netlists (_this, output, au);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(13a_KissingCorners)
|
||||||
|
{
|
||||||
|
std::string rs = tl::testsrc ();
|
||||||
|
rs += "/testdata/drc/drcSimpleTests_13a.drc";
|
||||||
|
|
||||||
|
std::string input = tl::testsrc ();
|
||||||
|
input += "/testdata/drc/kissing_corners.gds";
|
||||||
|
|
||||||
|
std::string au = tl::testsrc ();
|
||||||
|
au += "/testdata/drc/drcSimpleTests_au13a.gds";
|
||||||
|
|
||||||
|
std::string output = this->tmp_file ("tmp.gds");
|
||||||
|
|
||||||
|
{
|
||||||
|
// Set some variables
|
||||||
|
lym::Macro config;
|
||||||
|
config.set_text (tl::sprintf (
|
||||||
|
"$drc_test_source = '%s'\n"
|
||||||
|
"$drc_test_target = '%s'\n"
|
||||||
|
, input, output)
|
||||||
|
);
|
||||||
|
config.set_interpreter (lym::Macro::Ruby);
|
||||||
|
EXPECT_EQ (config.run (), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
lym::Macro drc;
|
||||||
|
drc.load_from (rs);
|
||||||
|
EXPECT_EQ (drc.run (), 0);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
|
||||||
|
db::Layout layout;
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::InputStream stream (output);
|
||||||
|
db::Reader reader (stream);
|
||||||
|
reader.read (layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECKPOINT ();
|
||||||
|
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(13b_KissingCornersDeep)
|
||||||
|
{
|
||||||
|
std::string rs = tl::testsrc ();
|
||||||
|
rs += "/testdata/drc/drcSimpleTests_13b.drc";
|
||||||
|
|
||||||
|
std::string input = tl::testsrc ();
|
||||||
|
input += "/testdata/drc/kissing_corners.gds";
|
||||||
|
|
||||||
|
std::string au = tl::testsrc ();
|
||||||
|
au += "/testdata/drc/drcSimpleTests_au13b.gds";
|
||||||
|
|
||||||
|
std::string output = this->tmp_file ("tmp.gds");
|
||||||
|
|
||||||
|
{
|
||||||
|
// Set some variables
|
||||||
|
lym::Macro config;
|
||||||
|
config.set_text (tl::sprintf (
|
||||||
|
"$drc_test_source = '%s'\n"
|
||||||
|
"$drc_test_target = '%s'\n"
|
||||||
|
, input, output)
|
||||||
|
);
|
||||||
|
config.set_interpreter (lym::Macro::Ruby);
|
||||||
|
EXPECT_EQ (config.run (), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
lym::Macro drc;
|
||||||
|
drc.load_from (rs);
|
||||||
|
EXPECT_EQ (drc.run (), 0);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
|
||||||
|
db::Layout layout;
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::InputStream stream (output);
|
||||||
|
db::Reader reader (stream);
|
||||||
|
reader.read (layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECKPOINT ();
|
||||||
|
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,351 @@
|
||||||
<ui version="4.0" >
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
<class>MakeCellOptionsDialog</class>
|
<class>MakeCellOptionsDialog</class>
|
||||||
<widget class="QDialog" name="MakeCellOptionsDialog" >
|
<widget class="QDialog" name="MakeCellOptionsDialog">
|
||||||
<property name="geometry" >
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>462</width>
|
<width>483</width>
|
||||||
<height>159</height>
|
<height>367</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle" >
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>Make Cell</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" >
|
<layout class="QVBoxLayout">
|
||||||
<property name="margin" >
|
<property name="spacing">
|
||||||
<number>9</number>
|
|
||||||
</property>
|
|
||||||
<property name="spacing" >
|
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox" >
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title" >
|
<property name="title">
|
||||||
<string>Make Cell</string>
|
<string>Name of cell to make from selected shapes and instances:</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" >
|
<layout class="QVBoxLayout">
|
||||||
<property name="margin" >
|
<property name="spacing">
|
||||||
<number>9</number>
|
|
||||||
</property>
|
|
||||||
<property name="spacing" >
|
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label" >
|
<widget class="QLineEdit" name="cell_name_le"/>
|
||||||
<property name="text" >
|
|
||||||
<string>Name of cell to make from selected shapes and instances:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="origin_groupbox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Put origin relative to cell's bounding bo&x at ...</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="cell_name_le" />
|
<widget class="QFrame" name="frame_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="frame_3">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::Box</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QToolButton" name="ct">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/ct.png</normaloff>:/ct.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>31</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QToolButton" name="lt">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/lt.png</normaloff>:/lt.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>31</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QToolButton" name="rt">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/rt.png</normaloff>:/rt.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>31</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QToolButton" name="lc">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/lc.png</normaloff>:/lc.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>31</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QToolButton" name="cc">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/cc.png</normaloff>:/cc.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>31</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="3">
|
||||||
|
<widget class="QToolButton" name="rc">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/rc.png</normaloff>:/rc.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>31</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QToolButton" name="lb">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/lb.png</normaloff>:/lb.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>31</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QToolButton" name="cb">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/cb.png</normaloff>:/cb.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>31</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="3">
|
||||||
|
<widget class="QToolButton" name="rb">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/rb.png</normaloff>:/rb.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>31</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>88</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation" >
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" >
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>20</width>
|
<width>20</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
|
|
@ -58,18 +354,20 @@
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation" >
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons" >
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources>
|
||||||
|
<include location="../../lay/lay/layResources.qrc"/>
|
||||||
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>buttonBox</sender>
|
<sender>buttonBox</sender>
|
||||||
|
|
@ -77,11 +375,11 @@
|
||||||
<receiver>MakeCellOptionsDialog</receiver>
|
<receiver>MakeCellOptionsDialog</receiver>
|
||||||
<slot>accept()</slot>
|
<slot>accept()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel">
|
||||||
<x>248</x>
|
<x>248</x>
|
||||||
<y>254</y>
|
<y>254</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel">
|
||||||
<x>157</x>
|
<x>157</x>
|
||||||
<y>274</y>
|
<y>274</y>
|
||||||
</hint>
|
</hint>
|
||||||
|
|
@ -93,11 +391,11 @@
|
||||||
<receiver>MakeCellOptionsDialog</receiver>
|
<receiver>MakeCellOptionsDialog</receiver>
|
||||||
<slot>reject()</slot>
|
<slot>reject()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel">
|
||||||
<x>316</x>
|
<x>316</x>
|
||||||
<y>260</y>
|
<y>260</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel">
|
||||||
<x>286</x>
|
<x>286</x>
|
||||||
<y>274</y>
|
<y>274</y>
|
||||||
</hint>
|
</hint>
|
||||||
|
|
|
||||||
|
|
@ -336,28 +336,80 @@ MakeCellOptionsDialog::MakeCellOptionsDialog (QWidget *parent)
|
||||||
: QDialog (parent)
|
: QDialog (parent)
|
||||||
{
|
{
|
||||||
setupUi (this);
|
setupUi (this);
|
||||||
|
|
||||||
|
setObjectName (QString::fromUtf8 ("make_cell_options_dialog"));
|
||||||
|
|
||||||
|
QToolButton *buttons[3][3] = { { lb, cb, rb }, { lc, cc, rc }, { lt, ct, rt } };
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
connect (buttons[i][j], SIGNAL (clicked ()), this, SLOT (button_clicked ()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MakeCellOptionsDialog::exec_dialog (const db::Layout &layout, std::string &name)
|
MakeCellOptionsDialog::exec_dialog (const db::Layout &layout, std::string &name, int &mode_x, int &mode_y)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
BEGIN_PROTECTED
|
BEGIN_PROTECTED
|
||||||
|
|
||||||
|
QToolButton *buttons[3][3] = { { lb, cb, rb }, { lc, cc, rc }, { lt, ct, rt } };
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
buttons[i][j]->setChecked (j - 1 == mode_x && i - 1 == mode_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
origin_groupbox->setChecked (mode_x >= -1);
|
||||||
|
|
||||||
if (QDialog::exec ()) {
|
if (QDialog::exec ()) {
|
||||||
|
|
||||||
|
if (origin_groupbox->isChecked ()) {
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
if (buttons[i][j]->isChecked ()) {
|
||||||
|
mode_x = j - 1;
|
||||||
|
mode_y = i - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mode_x = mode_y = -2;
|
||||||
|
}
|
||||||
|
|
||||||
name = tl::to_string (cell_name_le->text ());
|
name = tl::to_string (cell_name_le->text ());
|
||||||
if (name.empty ()) {
|
if (name.empty ()) {
|
||||||
throw tl::Exception (tl::to_string (QObject::tr ("Cell name must not be empty")));
|
throw tl::Exception (tl::to_string (QObject::tr ("Cell name must not be empty")));
|
||||||
} else if (layout.cell_by_name (name.c_str ()).first) {
|
} else if (layout.cell_by_name (name.c_str ()).first) {
|
||||||
throw tl::Exception (tl::to_string (QObject::tr ("A cell with that name already exists: ")) + name);
|
throw tl::Exception (tl::to_string (QObject::tr ("A cell with that name already exists: ")) + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
END_PROTECTED
|
END_PROTECTED
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MakeCellOptionsDialog::button_clicked ()
|
||||||
|
{
|
||||||
|
QToolButton *buttons[3][3] = { { lb, cb, rb }, { lc, cc, rc }, { lt, ct, rt } };
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
if (buttons [i][j] != sender ()) {
|
||||||
|
buttons [i][j]->setChecked (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
// RoundCornerOptionsDialog implementation
|
// RoundCornerOptionsDialog implementation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,9 +134,14 @@ class MakeCellOptionsDialog
|
||||||
: public QDialog,
|
: public QDialog,
|
||||||
private Ui::MakeCellOptionsDialog
|
private Ui::MakeCellOptionsDialog
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MakeCellOptionsDialog (QWidget *parent);
|
MakeCellOptionsDialog (QWidget *parent);
|
||||||
bool exec_dialog (const db::Layout &layout, std::string &name);
|
bool exec_dialog (const db::Layout &layout, std::string &name, int &mode_x, int &mode_y);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void button_clicked ();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -146,6 +151,8 @@ class MakeArrayOptionsDialog
|
||||||
: public QDialog,
|
: public QDialog,
|
||||||
private Ui::MakeArrayOptionsDialog
|
private Ui::MakeArrayOptionsDialog
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MakeArrayOptionsDialog (QWidget *parent);
|
MakeArrayOptionsDialog (QWidget *parent);
|
||||||
bool exec_dialog (db::DVector &a, unsigned int &na, db::DVector &b, unsigned int &nb);
|
bool exec_dialog (db::DVector &a, unsigned int &na, db::DVector &b, unsigned int &nb);
|
||||||
|
|
@ -160,6 +167,8 @@ class RoundCornerOptionsDialog
|
||||||
: public QDialog,
|
: public QDialog,
|
||||||
private Ui::RoundCornerOptionsDialog
|
private Ui::RoundCornerOptionsDialog
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RoundCornerOptionsDialog (QWidget *parent);
|
RoundCornerOptionsDialog (QWidget *parent);
|
||||||
~RoundCornerOptionsDialog ();
|
~RoundCornerOptionsDialog ();
|
||||||
|
|
|
||||||
|
|
@ -58,11 +58,11 @@ MainService::MainService (db::Manager *manager, lay::LayoutView *view, lay::Plug
|
||||||
m_flatten_insts_levels (std::numeric_limits<int>::max ()),
|
m_flatten_insts_levels (std::numeric_limits<int>::max ()),
|
||||||
m_flatten_prune (false),
|
m_flatten_prune (false),
|
||||||
m_align_hmode (0), m_align_vmode (0), m_align_visible_layers (false),
|
m_align_hmode (0), m_align_vmode (0), m_align_visible_layers (false),
|
||||||
|
m_origin_mode_x (-1), m_origin_mode_y (-1), m_origin_visible_layers_for_bbox (false),
|
||||||
m_array_a (0.0, 1.0), m_array_b (1.0, 0.0),
|
m_array_a (0.0, 1.0), m_array_b (1.0, 0.0),
|
||||||
m_array_na (1), m_array_nb (1)
|
m_array_na (1), m_array_nb (1)
|
||||||
{
|
{
|
||||||
// collect the options pages and build the options dialog
|
// .. nothing yet ..
|
||||||
std::vector<edt::Service *> edt_services = mp_view->get_plugins <edt::Service> ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MainService::~MainService ()
|
MainService::~MainService ()
|
||||||
|
|
@ -912,7 +912,7 @@ MainService::cm_make_cell ()
|
||||||
|
|
||||||
const lay::CellView &cv = view ()->cellview (cv_index);
|
const lay::CellView &cv = view ()->cellview (cv_index);
|
||||||
|
|
||||||
if (dialog.exec_dialog (cv->layout (), m_make_cell_name)) {
|
if (dialog.exec_dialog (cv->layout (), m_make_cell_name, m_origin_mode_x, m_origin_mode_y)) {
|
||||||
|
|
||||||
// Compute the selection's bbox to establish a good origin for the new cell
|
// Compute the selection's bbox to establish a good origin for the new cell
|
||||||
db::Box selection_bbox;
|
db::Box selection_bbox;
|
||||||
|
|
@ -940,8 +940,13 @@ MainService::cm_make_cell ()
|
||||||
db::Cell &target_cell = cv->layout ().cell (target_ci);
|
db::Cell &target_cell = cv->layout ().cell (target_ci);
|
||||||
|
|
||||||
// create target cell instance
|
// create target cell instance
|
||||||
db::Instance target_cell_inst = cv.cell ()->insert (db::CellInstArray (db::CellInst (target_ci), db::Trans (selection_bbox.lower_left () - db::Point ())));
|
db::Vector ref;
|
||||||
db::ICplxTrans to = db::ICplxTrans (db::Trans (db::Point () - selection_bbox.lower_left ()));
|
if (m_origin_mode_x >= -1) {
|
||||||
|
ref = db::Vector (selection_bbox.left () + ((m_origin_mode_x + 1) * selection_bbox.width ()) / 2, selection_bbox.bottom () + ((m_origin_mode_y + 1) * selection_bbox.height ()) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Instance target_cell_inst = cv.cell ()->insert (db::CellInstArray (db::CellInst (target_ci), db::Trans (ref)));
|
||||||
|
db::ICplxTrans to = db::ICplxTrans (db::Trans (-ref));
|
||||||
|
|
||||||
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
|
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,8 @@ private:
|
||||||
int m_align_vmode;
|
int m_align_vmode;
|
||||||
bool m_align_visible_layers;
|
bool m_align_visible_layers;
|
||||||
std::string m_make_cell_name;
|
std::string m_make_cell_name;
|
||||||
|
int m_origin_mode_x, m_origin_mode_y;
|
||||||
|
bool m_origin_visible_layers_for_bbox;
|
||||||
db::DVector m_array_a, m_array_b;
|
db::DVector m_array_a, m_array_b;
|
||||||
unsigned int m_array_na, m_array_nb;
|
unsigned int m_array_na, m_array_nb;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,7 @@ gsi::Class<lay::ObjectInstPath> decl_ObjectInstPath ("lay", "ObjectInstPath",
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.24."
|
"This method has been introduced in version 0.24."
|
||||||
) +
|
) +
|
||||||
gsi::method ("shape", (db::Shape &(lay::ObjectInstPath::*) ()) &lay::ObjectInstPath::shape,
|
gsi::method ("shape", (const db::Shape &(lay::ObjectInstPath::*) () const) &lay::ObjectInstPath::shape,
|
||||||
"@brief Gets the shape object that describes the selected shape geometrically\n"
|
"@brief Gets the shape object that describes the selected shape geometrically\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This method delivers valid results only for object selections that represent shapes, i.e for "
|
"This method delivers valid results only for object selections that represent shapes, i.e for "
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
<ui version="4.0" >
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
<class>AlignCellOptionsDialog</class>
|
<class>AlignCellOptionsDialog</class>
|
||||||
<widget class="QDialog" name="AlignCellOptionsDialog" >
|
<widget class="QDialog" name="AlignCellOptionsDialog">
|
||||||
<property name="geometry" >
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
|
|
@ -9,52 +10,68 @@
|
||||||
<height>342</height>
|
<height>342</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle" >
|
<property name="windowTitle">
|
||||||
<string>Align Cell</string>
|
<string>Adjust Cell Origin</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" >
|
<layout class="QVBoxLayout">
|
||||||
<property name="margin" >
|
<property name="spacing">
|
||||||
<number>9</number>
|
|
||||||
</property>
|
|
||||||
<property name="spacing" >
|
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label" >
|
<widget class="QLabel" name="label">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Put origin relative to cell's bounding box at ...</string>
|
<string>Put origin relative to cell's bounding box at ...</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="frame_2" >
|
<widget class="QFrame" name="frame_2">
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy">
|
||||||
<sizepolicy>
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
<hsizetype>0</hsizetype>
|
|
||||||
<vsizetype>0</vsizetype>
|
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShape" >
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow" >
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" >
|
<layout class="QHBoxLayout">
|
||||||
<property name="margin" >
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
<number>9</number>
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="spacing" >
|
<property name="topMargin">
|
||||||
<number>6</number>
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation" >
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" >
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>64</width>
|
<width>64</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
|
|
@ -63,187 +80,205 @@
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="frame_3" >
|
<widget class="QFrame" name="frame_3">
|
||||||
<property name="frameShape" >
|
<property name="frameShape">
|
||||||
<enum>QFrame::Box</enum>
|
<enum>QFrame::Box</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow" >
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Plain</enum>
|
<enum>QFrame::Plain</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" >
|
<layout class="QGridLayout">
|
||||||
<property name="margin" >
|
<property name="leftMargin">
|
||||||
<number>15</number>
|
<number>15</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="spacing" >
|
<property name="topMargin">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="0" column="2" >
|
<item row="0" column="2">
|
||||||
<widget class="QToolButton" name="ct" >
|
<widget class="QToolButton" name="ct">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="layResources.qrc" >:/ct.png</iconset>
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/ct.png</normaloff>:/ct.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>31</width>
|
<width>31</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable" >
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0" >
|
<item row="0" column="0">
|
||||||
<widget class="QToolButton" name="lt" >
|
<widget class="QToolButton" name="lt">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="layResources.qrc" >:/lt.png</iconset>
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/lt.png</normaloff>:/lt.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>31</width>
|
<width>31</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable" >
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="3" >
|
<item row="0" column="3">
|
||||||
<widget class="QToolButton" name="rt" >
|
<widget class="QToolButton" name="rt">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="layResources.qrc" >:/rt.png</iconset>
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/rt.png</normaloff>:/rt.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>31</width>
|
<width>31</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable" >
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" >
|
<item row="1" column="0">
|
||||||
<widget class="QToolButton" name="lc" >
|
<widget class="QToolButton" name="lc">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="layResources.qrc" >:/lc.png</iconset>
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/lc.png</normaloff>:/lc.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>31</width>
|
<width>31</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable" >
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2" >
|
<item row="1" column="2">
|
||||||
<widget class="QToolButton" name="cc" >
|
<widget class="QToolButton" name="cc">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="layResources.qrc" >:/cc.png</iconset>
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/cc.png</normaloff>:/cc.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>31</width>
|
<width>31</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable" >
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="3" >
|
<item row="1" column="3">
|
||||||
<widget class="QToolButton" name="rc" >
|
<widget class="QToolButton" name="rc">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="layResources.qrc" >:/rc.png</iconset>
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/rc.png</normaloff>:/rc.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>31</width>
|
<width>31</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable" >
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" >
|
<item row="2" column="0">
|
||||||
<widget class="QToolButton" name="lb" >
|
<widget class="QToolButton" name="lb">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="layResources.qrc" >:/lb.png</iconset>
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/lb.png</normaloff>:/lb.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>31</width>
|
<width>31</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable" >
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="2" >
|
<item row="2" column="2">
|
||||||
<widget class="QToolButton" name="cb" >
|
<widget class="QToolButton" name="cb">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="layResources.qrc" >:/cb.png</iconset>
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/cb.png</normaloff>:/cb.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>31</width>
|
<width>31</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable" >
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="3" >
|
<item row="2" column="3">
|
||||||
<widget class="QToolButton" name="rb" >
|
<widget class="QToolButton" name="rb">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="layResources.qrc" >:/rb.png</iconset>
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/rb.png</normaloff>:/rb.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>31</width>
|
<width>31</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable" >
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
@ -253,10 +288,10 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation" >
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" >
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>88</width>
|
<width>88</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
|
|
@ -268,28 +303,28 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="vis_only_cbx" >
|
<widget class="QCheckBox" name="vis_only_cbx">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Use visible layers only for bounding box</string>
|
<string>Use visible layers only for bounding box</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="adjust_calls_cbx" >
|
<widget class="QCheckBox" name="adjust_calls_cbx">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Adjust instances in parents</string>
|
<string>Adjust instances in parents</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation" >
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeType" >
|
<property name="sizeType">
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" >
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>20</width>
|
<width>20</width>
|
||||||
<height>8</height>
|
<height>8</height>
|
||||||
|
|
@ -298,26 +333,35 @@
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="frame" >
|
<widget class="QFrame" name="frame">
|
||||||
<property name="frameShape" >
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow" >
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" >
|
<layout class="QHBoxLayout">
|
||||||
<property name="margin" >
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="spacing" >
|
<property name="topMargin">
|
||||||
<number>6</number>
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation" >
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" >
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>209</width>
|
<width>209</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
|
|
@ -326,18 +370,18 @@
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButton" >
|
<widget class="QPushButton" name="pushButton">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Ok</string>
|
<string>Ok</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="default" >
|
<property name="default">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButton_2" >
|
<widget class="QPushButton" name="pushButton_2">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Cancel</string>
|
<string>Cancel</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
@ -362,7 +406,7 @@
|
||||||
<tabstop>vis_only_cbx</tabstop>
|
<tabstop>vis_only_cbx</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="layResources.qrc" />
|
<include location="../../lay/lay/layResources.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
|
|
@ -371,11 +415,11 @@
|
||||||
<receiver>AlignCellOptionsDialog</receiver>
|
<receiver>AlignCellOptionsDialog</receiver>
|
||||||
<slot>accept()</slot>
|
<slot>accept()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel">
|
||||||
<x>237</x>
|
<x>237</x>
|
||||||
<y>203</y>
|
<y>203</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel">
|
||||||
<x>147</x>
|
<x>147</x>
|
||||||
<y>81</y>
|
<y>81</y>
|
||||||
</hint>
|
</hint>
|
||||||
|
|
@ -387,11 +431,11 @@
|
||||||
<receiver>AlignCellOptionsDialog</receiver>
|
<receiver>AlignCellOptionsDialog</receiver>
|
||||||
<slot>reject()</slot>
|
<slot>reject()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel">
|
||||||
<x>325</x>
|
<x>325</x>
|
||||||
<y>202</y>
|
<y>202</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel">
|
||||||
<x>325</x>
|
<x>325</x>
|
||||||
<y>57</y>
|
<y>57</y>
|
||||||
</hint>
|
</hint>
|
||||||
|
|
|
||||||
|
|
@ -1388,9 +1388,9 @@ Class<lay::LayerPropertiesNodeRef> decl_LayerPropertiesNodeRef (
|
||||||
"This class has been introduced in version 0.25.\n"
|
"This class has been introduced in version 0.25.\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
static lay::LayerPropertiesNodeRef current (lay::LayerPropertiesConstIterator *iter)
|
static lay::LayerPropertiesNodeRef current (const lay::LayerPropertiesConstIterator *iter)
|
||||||
{
|
{
|
||||||
return lay::LayerPropertiesNodeRef (iter);
|
return lay::LayerPropertiesNodeRef (*iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<lay::LayerPropertiesConstIterator> decl_LayerPropertiesIterator (
|
Class<lay::LayerPropertiesConstIterator> decl_LayerPropertiesIterator (
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ namespace {
|
||||||
|
|
||||||
reference operator* () const
|
reference operator* () const
|
||||||
{
|
{
|
||||||
return lay::LayerPropertiesNodeRef (&const_cast<LayerPropertiesConstIteratorWrapper *> (this)->m_iter);
|
return lay::LayerPropertiesNodeRef (m_iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool at_end () const
|
bool at_end () const
|
||||||
|
|
|
||||||
|
|
@ -197,12 +197,15 @@ LayerProperties::operator= (const LayerProperties &d)
|
||||||
flags += nr_source;
|
flags += nr_source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_name != d.m_name) {
|
||||||
|
m_name = d.m_name;
|
||||||
|
flags += nr_meta;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags) {
|
if (flags) {
|
||||||
need_realize (flags, true /*force on children*/);
|
need_realize (flags, true /*force on children*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_name = d.m_name;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -806,13 +809,13 @@ LayerPropertiesNode::add_child (const LayerPropertiesNode &child)
|
||||||
// LayerPropertiesConstIterator implementation
|
// LayerPropertiesConstIterator implementation
|
||||||
|
|
||||||
LayerPropertiesConstIterator::LayerPropertiesConstIterator ()
|
LayerPropertiesConstIterator::LayerPropertiesConstIterator ()
|
||||||
: m_uint (0), m_list (), mp_obj (0)
|
: m_uint (0), m_list ()
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerPropertiesConstIterator::LayerPropertiesConstIterator (const lay::LayerPropertiesNode *node)
|
LayerPropertiesConstIterator::LayerPropertiesConstIterator (const lay::LayerPropertiesNode *node)
|
||||||
: m_uint (0), m_list (), mp_obj (0)
|
: m_uint (0), m_list ()
|
||||||
{
|
{
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -874,7 +877,7 @@ LayerPropertiesConstIterator::LayerPropertiesConstIterator (const lay::LayerProp
|
||||||
|
|
||||||
LayerPropertiesConstIterator::LayerPropertiesConstIterator (const LayerPropertiesList &list, bool last)
|
LayerPropertiesConstIterator::LayerPropertiesConstIterator (const LayerPropertiesList &list, bool last)
|
||||||
// NOTE: there should be some "const_weak_ptr"
|
// NOTE: there should be some "const_weak_ptr"
|
||||||
: m_uint (0), m_list (const_cast<LayerPropertiesList *> (&list)), mp_obj (0)
|
: m_uint (0), m_list (const_cast<LayerPropertiesList *> (&list))
|
||||||
{
|
{
|
||||||
if (last) {
|
if (last) {
|
||||||
m_uint = (list.end_const () - list.begin_const ()) + 1;
|
m_uint = (list.end_const () - list.begin_const ()) + 1;
|
||||||
|
|
@ -885,7 +888,7 @@ LayerPropertiesConstIterator::LayerPropertiesConstIterator (const LayerPropertie
|
||||||
|
|
||||||
LayerPropertiesConstIterator::LayerPropertiesConstIterator (const LayerPropertiesList &list, size_t uint)
|
LayerPropertiesConstIterator::LayerPropertiesConstIterator (const LayerPropertiesList &list, size_t uint)
|
||||||
// NOTE: there should be some "const_weak_ptr"
|
// NOTE: there should be some "const_weak_ptr"
|
||||||
: m_uint (uint), m_list (const_cast<LayerPropertiesList *> (&list)), mp_obj (0)
|
: m_uint (uint), m_list (const_cast<LayerPropertiesList *> (&list))
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
@ -991,7 +994,7 @@ LayerPropertiesConstIterator &
|
||||||
LayerPropertiesConstIterator::up ()
|
LayerPropertiesConstIterator::up ()
|
||||||
{
|
{
|
||||||
m_uint %= factor ().first;
|
m_uint %= factor ().first;
|
||||||
mp_obj = 0;
|
mp_obj.reset (0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -999,7 +1002,7 @@ LayerPropertiesConstIterator &
|
||||||
LayerPropertiesConstIterator::next_sibling (ptrdiff_t n)
|
LayerPropertiesConstIterator::next_sibling (ptrdiff_t n)
|
||||||
{
|
{
|
||||||
m_uint += factor ().first * n;
|
m_uint += factor ().first * n;
|
||||||
mp_obj = 0;
|
mp_obj.reset (0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1008,7 +1011,7 @@ LayerPropertiesConstIterator::to_sibling (size_t n)
|
||||||
{
|
{
|
||||||
std::pair <size_t, size_t> f = factor ();
|
std::pair <size_t, size_t> f = factor ();
|
||||||
m_uint = (m_uint % f.first) + (1 + n) * f.first;
|
m_uint = (m_uint % f.first) + (1 + n) * f.first;
|
||||||
mp_obj = 0;
|
mp_obj.reset (0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1024,7 +1027,7 @@ LayerPropertiesConstIterator::down_first_child ()
|
||||||
{
|
{
|
||||||
std::pair <size_t, size_t> f = factor ();
|
std::pair <size_t, size_t> f = factor ();
|
||||||
m_uint += f.first * f.second;
|
m_uint += f.first * f.second;
|
||||||
mp_obj = 0;
|
mp_obj.reset (0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1034,7 +1037,7 @@ LayerPropertiesConstIterator::down_last_child ()
|
||||||
std::pair <size_t, size_t> f = factor ();
|
std::pair <size_t, size_t> f = factor ();
|
||||||
const LayerPropertiesNode *o = obj ();
|
const LayerPropertiesNode *o = obj ();
|
||||||
m_uint += f.first * f.second * ((o->end_children () - o->begin_children ()) + 1);
|
m_uint += f.first * f.second * ((o->end_children () - o->begin_children ()) + 1);
|
||||||
mp_obj = 0;
|
mp_obj.reset (0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1067,8 +1070,8 @@ LayerPropertiesConstIterator::parent_obj () const
|
||||||
void
|
void
|
||||||
LayerPropertiesConstIterator::invalidate ()
|
LayerPropertiesConstIterator::invalidate ()
|
||||||
{
|
{
|
||||||
mp_obj = 0;
|
mp_obj.reset (0);
|
||||||
|
|
||||||
// the iterator may be parked at a position behind the last element.
|
// the iterator may be parked at a position behind the last element.
|
||||||
// Move one step further in this case.
|
// Move one step further in this case.
|
||||||
std::pair <size_t, size_t> f = factor ();
|
std::pair <size_t, size_t> f = factor ();
|
||||||
|
|
@ -1083,7 +1086,7 @@ LayerPropertiesConstIterator::set_obj () const
|
||||||
{
|
{
|
||||||
if (is_null () || !m_list) {
|
if (is_null () || !m_list) {
|
||||||
|
|
||||||
mp_obj = 0;
|
mp_obj.reset (0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -1104,7 +1107,7 @@ LayerPropertiesConstIterator::set_obj () const
|
||||||
iter = iter[rem - 1].begin_children ();
|
iter = iter[rem - 1].begin_children ();
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj = &iter[uint - 1];
|
mp_obj.reset (const_cast<lay::LayerPropertiesNode *> (&iter[uint - 1]));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1122,7 +1125,7 @@ LayerPropertiesConstIterator::inc (unsigned int d)
|
||||||
while (true) {
|
while (true) {
|
||||||
std::pair <size_t, size_t> f = factor ();
|
std::pair <size_t, size_t> f = factor ();
|
||||||
m_uint += f.first;
|
m_uint += f.first;
|
||||||
mp_obj = 0;
|
mp_obj.reset (0);
|
||||||
if (m_uint / f.first < f.second - 1) {
|
if (m_uint / f.first < f.second - 1) {
|
||||||
break;
|
break;
|
||||||
} else if (at_top ()) {
|
} else if (at_top ()) {
|
||||||
|
|
@ -1908,32 +1911,11 @@ LayerPropertiesNodeRef::LayerPropertiesNodeRef (LayerPropertiesNode *node)
|
||||||
attach_view (node->view (), node->list_index ());
|
attach_view (node->view (), node->list_index ());
|
||||||
set_parent (node->parent ());
|
set_parent (node->parent ());
|
||||||
|
|
||||||
mp_iter.reset (&m_iter);
|
|
||||||
mp_node.reset (node);
|
mp_node.reset (node);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerPropertiesNodeRef::LayerPropertiesNodeRef (LayerPropertiesConstIterator *iter)
|
|
||||||
{
|
|
||||||
if (iter && !iter->at_end () && !iter->is_null ()) {
|
|
||||||
|
|
||||||
const lay::LayerPropertiesNode *node = (*iter).operator-> ();
|
|
||||||
|
|
||||||
// NOTE: we do assignment before we set the iterator reference - hence there won't be
|
|
||||||
// updates triggered.
|
|
||||||
LayerPropertiesNode::operator= (*node);
|
|
||||||
|
|
||||||
// Makes ourself a perfect copy of the original (including reference into the view)
|
|
||||||
attach_view (node->view (), node->list_index ());
|
|
||||||
set_parent (node->parent ());
|
|
||||||
|
|
||||||
mp_iter.reset (iter);
|
|
||||||
mp_node.reset (const_cast<lay::LayerPropertiesNode *> (node));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerPropertiesNodeRef::LayerPropertiesNodeRef (const LayerPropertiesConstIterator &iter)
|
LayerPropertiesNodeRef::LayerPropertiesNodeRef (const LayerPropertiesConstIterator &iter)
|
||||||
: m_iter (iter)
|
: m_iter (iter)
|
||||||
{
|
{
|
||||||
|
|
@ -1949,7 +1931,6 @@ LayerPropertiesNodeRef::LayerPropertiesNodeRef (const LayerPropertiesConstIterat
|
||||||
attach_view (node->view (), node->list_index ());
|
attach_view (node->view (), node->list_index ());
|
||||||
set_parent (node->parent ());
|
set_parent (node->parent ());
|
||||||
|
|
||||||
mp_iter.reset (&m_iter);
|
|
||||||
mp_node.reset (const_cast<lay::LayerPropertiesNode *> (node));
|
mp_node.reset (const_cast<lay::LayerPropertiesNode *> (node));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1961,7 +1942,7 @@ LayerPropertiesNodeRef::LayerPropertiesNodeRef ()
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerPropertiesNodeRef::LayerPropertiesNodeRef (const LayerPropertiesNodeRef &other)
|
LayerPropertiesNodeRef::LayerPropertiesNodeRef (const LayerPropertiesNodeRef &other)
|
||||||
: LayerPropertiesNode (other), m_iter (other.m_iter), mp_iter (other.mp_iter), mp_node (other.mp_node)
|
: LayerPropertiesNode (other), m_iter (other.m_iter), mp_node (other.mp_node)
|
||||||
{
|
{
|
||||||
attach_view (other.view (), other.list_index ());
|
attach_view (other.view (), other.list_index ());
|
||||||
set_parent (other.parent ());
|
set_parent (other.parent ());
|
||||||
|
|
@ -1971,7 +1952,6 @@ LayerPropertiesNodeRef &LayerPropertiesNodeRef::operator= (const LayerProperties
|
||||||
{
|
{
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
|
|
||||||
mp_iter = other.mp_iter;
|
|
||||||
mp_node = other.mp_node;
|
mp_node = other.mp_node;
|
||||||
m_iter = other.m_iter;
|
m_iter = other.m_iter;
|
||||||
attach_view (other.view (), other.list_index ());
|
attach_view (other.view (), other.list_index ());
|
||||||
|
|
@ -1988,25 +1968,20 @@ void
|
||||||
LayerPropertiesNodeRef::erase ()
|
LayerPropertiesNodeRef::erase ()
|
||||||
{
|
{
|
||||||
if (is_valid ()) {
|
if (is_valid ()) {
|
||||||
view ()->delete_layer ((unsigned int) list_index (), *mp_iter);
|
view ()->delete_layer ((unsigned int) list_index (), m_iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const lay::LayerPropertiesConstIterator &
|
const lay::LayerPropertiesConstIterator &
|
||||||
LayerPropertiesNodeRef::iter () const
|
LayerPropertiesNodeRef::iter () const
|
||||||
{
|
{
|
||||||
if (mp_iter) {
|
return m_iter;
|
||||||
return *mp_iter;
|
|
||||||
} else {
|
|
||||||
static lay::LayerPropertiesConstIterator null_iter;
|
|
||||||
return null_iter;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LayerPropertiesNodeRef::is_valid () const
|
LayerPropertiesNodeRef::is_valid () const
|
||||||
{
|
{
|
||||||
return mp_iter && !mp_iter->at_end () && !mp_iter->is_null () && view ();
|
return !m_iter.is_null () && !m_iter.at_end () && view ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2015,11 +1990,11 @@ LayerPropertiesNodeRef::need_realize (unsigned int flags, bool force)
|
||||||
LayerPropertiesNode::need_realize (flags, force);
|
LayerPropertiesNode::need_realize (flags, force);
|
||||||
if (is_valid ()) {
|
if (is_valid ()) {
|
||||||
|
|
||||||
if ((flags & (nr_visual + nr_source)) != 0) {
|
if ((flags & (nr_visual + nr_source + nr_meta)) != 0) {
|
||||||
view ()->set_properties ((unsigned int) list_index (), *mp_iter, *this);
|
view ()->set_properties ((unsigned int) list_index (), m_iter, *this);
|
||||||
}
|
}
|
||||||
if ((flags & nr_hierarchy) != 0) {
|
if ((flags & nr_hierarchy) != 0) {
|
||||||
view ()->replace_layer_node ((unsigned int) list_index (), *mp_iter, *this);
|
view ()->replace_layer_node ((unsigned int) list_index (), m_iter, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (mp_node) {
|
} else if (mp_node) {
|
||||||
|
|
|
||||||
|
|
@ -637,7 +637,10 @@ public:
|
||||||
*/
|
*/
|
||||||
void set_name (const std::string &n)
|
void set_name (const std::string &n)
|
||||||
{
|
{
|
||||||
m_name = n;
|
if (m_name != n) {
|
||||||
|
m_name = n;
|
||||||
|
need_realize (nr_meta);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -916,7 +919,8 @@ protected:
|
||||||
enum {
|
enum {
|
||||||
nr_visual = 1,
|
nr_visual = 1,
|
||||||
nr_source = 2,
|
nr_source = 2,
|
||||||
nr_hierarchy = 4
|
nr_meta = 4,
|
||||||
|
nr_hierarchy = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable bool m_realize_needed_source : 1;
|
mutable bool m_realize_needed_source : 1;
|
||||||
|
|
@ -1407,7 +1411,7 @@ public:
|
||||||
if (! mp_obj) {
|
if (! mp_obj) {
|
||||||
set_obj ();
|
set_obj ();
|
||||||
}
|
}
|
||||||
return mp_obj;
|
return mp_obj.get ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1423,7 +1427,7 @@ private:
|
||||||
|
|
||||||
size_t m_uint;
|
size_t m_uint;
|
||||||
tl::weak_ptr<LayerPropertiesList> m_list;
|
tl::weak_ptr<LayerPropertiesList> m_list;
|
||||||
mutable const LayerPropertiesNode *mp_obj;
|
mutable tl::weak_ptr<LayerPropertiesNode> mp_obj;
|
||||||
|
|
||||||
void inc (unsigned int d);
|
void inc (unsigned int d);
|
||||||
std::pair <size_t, size_t> factor () const;
|
std::pair <size_t, size_t> factor () const;
|
||||||
|
|
@ -1888,14 +1892,6 @@ public:
|
||||||
*/
|
*/
|
||||||
LayerPropertiesNodeRef (LayerPropertiesNode *node);
|
LayerPropertiesNodeRef (LayerPropertiesNode *node);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructor from an iterator
|
|
||||||
* The iterator is a pointer since the erase implementation requires us to
|
|
||||||
* modify the iterator. Hence with this version, the original iterator will
|
|
||||||
* follow up after the erase.
|
|
||||||
*/
|
|
||||||
LayerPropertiesNodeRef (LayerPropertiesConstIterator *iter);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor from an iterator with an iterator copy
|
* @brief Constructor from an iterator with an iterator copy
|
||||||
*/
|
*/
|
||||||
|
|
@ -1919,7 +1915,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deletes the current node
|
* @brief Deletes the current node
|
||||||
* After this operation, the reference will point to the
|
* After this operation, the reference will point to the next element.
|
||||||
*/
|
*/
|
||||||
void erase ();
|
void erase ();
|
||||||
|
|
||||||
|
|
@ -1947,7 +1943,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LayerPropertiesConstIterator m_iter;
|
LayerPropertiesConstIterator m_iter;
|
||||||
tl::weak_ptr<LayerPropertiesConstIterator> mp_iter;
|
|
||||||
tl::weak_ptr<LayerPropertiesNode> mp_node;
|
tl::weak_ptr<LayerPropertiesNode> mp_node;
|
||||||
|
|
||||||
void need_realize (unsigned int flags, bool force);
|
void need_realize (unsigned int flags, bool force);
|
||||||
|
|
|
||||||
|
|
@ -1014,7 +1014,7 @@ bool Macro::can_run () const
|
||||||
int Macro::run () const
|
int Macro::run () const
|
||||||
{
|
{
|
||||||
if (tl::verbosity () >= 20) {
|
if (tl::verbosity () >= 20) {
|
||||||
tl::log << "Running macro " << path ();
|
tl::log << tl::to_string (tr ("Running macro ")) << path ();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -1029,6 +1029,8 @@ int Macro::run () const
|
||||||
}
|
}
|
||||||
} else if (interpreter () == lym::Macro::DSLInterpreter) {
|
} else if (interpreter () == lym::Macro::DSLInterpreter) {
|
||||||
lym::MacroInterpreter::execute_macro (this);
|
lym::MacroInterpreter::execute_macro (this);
|
||||||
|
} else {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Can't run macro (no interpreter): ")) + path ());
|
||||||
}
|
}
|
||||||
} catch (tl::ExitException &ex) {
|
} catch (tl::ExitException &ex) {
|
||||||
return ex.status ();
|
return ex.status ();
|
||||||
|
|
@ -1843,10 +1845,10 @@ static void autorun_for (lym::MacroCollection &collection, bool early)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (lym::MacroCollection::iterator c = collection.begin (); c != collection.end (); ++c) {
|
for (lym::MacroCollection::iterator c = collection.begin (); c != collection.end (); ++c) {
|
||||||
if (((early && c->second->is_autorun_early ()) || (!early && c->second->is_autorun () && !c->second->is_autorun_early ())) && c->second->can_run ()) {
|
if ((early && c->second->is_autorun_early ()) || (!early && c->second->is_autorun () && !c->second->is_autorun_early ())) {
|
||||||
BEGIN_PROTECTED_SILENT
|
BEGIN_PROTECTED_SILENT
|
||||||
c->second->install_doc ();
|
|
||||||
c->second->run ();
|
c->second->run ();
|
||||||
|
c->second->install_doc ();
|
||||||
END_PROTECTED_SILENT
|
END_PROTECTED_SILENT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1343,20 +1343,24 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit property name required for the PCell context information
|
if (options.write_context_info ()) {
|
||||||
std::vector <std::string> context_prop_strings;
|
|
||||||
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) {
|
|
||||||
|
|
||||||
const db::Cell &cref (layout.cell (*cell));
|
// emit property name required for the PCell context information
|
||||||
if (cref.is_proxy () && ! cref.is_top () && layout.get_context_info (*cell, context_prop_strings)) {
|
std::vector <std::string> context_prop_strings;
|
||||||
|
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) {
|
||||||
|
|
||||||
|
const db::Cell &cref (layout.cell (*cell));
|
||||||
|
if (cref.is_proxy () && ! cref.is_top () && layout.get_context_info (*cell, context_prop_strings)) {
|
||||||
|
|
||||||
|
if (m_propnames.insert (std::make_pair (std::string (klayout_context_name), m_propname_id)).second) {
|
||||||
|
begin_table (propnames_table_pos);
|
||||||
|
write_record_id (7);
|
||||||
|
write_nstring (klayout_context_name);
|
||||||
|
++m_propname_id;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
if (m_propnames.insert (std::make_pair (std::string (klayout_context_name), m_propname_id)).second) {
|
|
||||||
begin_table (propnames_table_pos);
|
|
||||||
write_record_id (7);
|
|
||||||
write_nstring (klayout_context_name);
|
|
||||||
++m_propname_id;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1422,25 +1426,29 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit property string id's required for the PCell context information
|
if (options.write_context_info ()) {
|
||||||
std::vector <std::string> context_prop_strings;
|
|
||||||
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) {
|
|
||||||
|
|
||||||
m_progress.set (mp_stream->pos ());
|
// emit property string id's required for the PCell context information
|
||||||
|
std::vector <std::string> context_prop_strings;
|
||||||
|
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) {
|
||||||
|
|
||||||
const db::Cell &cref (layout.cell (*cell));
|
m_progress.set (mp_stream->pos ());
|
||||||
if (cref.is_proxy () && ! cref.is_top ()) {
|
|
||||||
|
|
||||||
context_prop_strings.clear ();
|
const db::Cell &cref (layout.cell (*cell));
|
||||||
if (layout.get_context_info (*cell, context_prop_strings)) {
|
if (cref.is_proxy () && ! cref.is_top ()) {
|
||||||
|
|
||||||
for (std::vector <std::string>::const_iterator c = context_prop_strings.begin (); c != context_prop_strings.end (); ++c) {
|
context_prop_strings.clear ();
|
||||||
if (m_propstrings.insert (std::make_pair (*c, m_propstring_id)).second) {
|
if (layout.get_context_info (*cell, context_prop_strings)) {
|
||||||
begin_table (propstrings_table_pos);
|
|
||||||
write_record_id (9);
|
for (std::vector <std::string>::const_iterator c = context_prop_strings.begin (); c != context_prop_strings.end (); ++c) {
|
||||||
write_bstring (c->c_str ());
|
if (m_propstrings.insert (std::make_pair (*c, m_propstring_id)).second) {
|
||||||
++m_propstring_id;
|
begin_table (propstrings_table_pos);
|
||||||
|
write_record_id (9);
|
||||||
|
write_bstring (c->c_str ());
|
||||||
|
++m_propstring_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1604,7 +1612,7 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save
|
||||||
}
|
}
|
||||||
|
|
||||||
// context information as property named KLAYOUT_CONTEXT
|
// context information as property named KLAYOUT_CONTEXT
|
||||||
if (cref.is_proxy ()) {
|
if (cref.is_proxy () && options.write_context_info ()) {
|
||||||
|
|
||||||
context_prop_strings.clear ();
|
context_prop_strings.clear ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
#include "dbLayoutDiff.h"
|
#include "dbLayoutDiff.h"
|
||||||
#include "dbWriter.h"
|
#include "dbWriter.h"
|
||||||
#include "dbTextWriter.h"
|
#include "dbTextWriter.h"
|
||||||
|
#include "dbLibraryProxy.h"
|
||||||
|
#include "dbTestSupport.h"
|
||||||
|
|
||||||
#include "tlUnitTest.h"
|
#include "tlUnitTest.h"
|
||||||
|
|
||||||
|
|
@ -1258,61 +1260,6 @@ TEST(115)
|
||||||
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(118)
|
|
||||||
{
|
|
||||||
// 1x1 arrays (#902)
|
|
||||||
|
|
||||||
db::Manager m;
|
|
||||||
db::Layout g (&m);
|
|
||||||
|
|
||||||
db::LayerProperties lp1;
|
|
||||||
lp1.layer = 1;
|
|
||||||
lp1.datatype = 0;
|
|
||||||
|
|
||||||
g.insert_layer (0, lp1);
|
|
||||||
|
|
||||||
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
||||||
c1.shapes (0).insert (db::Box (100, 0, 100, 200));
|
|
||||||
|
|
||||||
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
||||||
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), db::Trans (), db::Vector (0, 1), db::Vector (1, 0), 1, 1));
|
|
||||||
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), db::Trans (db::Vector (17, -42)), db::Vector (0, 1), db::Vector (1, 0), 1, 1));
|
|
||||||
|
|
||||||
std::string tmp_file = tl::TestBase::tmp_file ("tmp.oas");
|
|
||||||
|
|
||||||
{
|
|
||||||
tl::OutputStream out (tmp_file);
|
|
||||||
db::SaveLayoutOptions options;
|
|
||||||
options.set_format ("OASIS");
|
|
||||||
db::Writer writer (options);
|
|
||||||
writer.write (g, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
tl::InputStream in (tmp_file);
|
|
||||||
db::Reader reader (in);
|
|
||||||
db::Layout gg;
|
|
||||||
reader.set_warnings_as_errors (true);
|
|
||||||
reader.read (gg);
|
|
||||||
|
|
||||||
const char *expected =
|
|
||||||
"begin_lib 0.001\n"
|
|
||||||
"begin_cell {$1}\n"
|
|
||||||
"box 1 0 {100 0} {100 200}\n"
|
|
||||||
"end_cell\n"
|
|
||||||
"begin_cell {$2}\n"
|
|
||||||
"sref {$1} 0 0 1 {0 0}\n"
|
|
||||||
"sref {$1} 0 0 1 {17 -42}\n"
|
|
||||||
"end_cell\n"
|
|
||||||
"end_lib\n"
|
|
||||||
;
|
|
||||||
|
|
||||||
tl::OutputStringStream os;
|
|
||||||
tl::OutputStream stream (os);
|
|
||||||
db::TextWriter textwriter (stream);
|
|
||||||
textwriter.write (gg);
|
|
||||||
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(116)
|
TEST(116)
|
||||||
{
|
{
|
||||||
db::Manager m;
|
db::Manager m;
|
||||||
|
|
@ -1728,3 +1675,133 @@ TEST(117)
|
||||||
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(118)
|
||||||
|
{
|
||||||
|
// 1x1 arrays (#902)
|
||||||
|
|
||||||
|
db::Manager m;
|
||||||
|
db::Layout g (&m);
|
||||||
|
|
||||||
|
db::LayerProperties lp1;
|
||||||
|
lp1.layer = 1;
|
||||||
|
lp1.datatype = 0;
|
||||||
|
|
||||||
|
g.insert_layer (0, lp1);
|
||||||
|
|
||||||
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
||||||
|
c1.shapes (0).insert (db::Box (100, 0, 100, 200));
|
||||||
|
|
||||||
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
||||||
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), db::Trans (), db::Vector (0, 1), db::Vector (1, 0), 1, 1));
|
||||||
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), db::Trans (db::Vector (17, -42)), db::Vector (0, 1), db::Vector (1, 0), 1, 1));
|
||||||
|
|
||||||
|
std::string tmp_file = tl::TestBase::tmp_file ("tmp.oas");
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::OutputStream out (tmp_file);
|
||||||
|
db::SaveLayoutOptions options;
|
||||||
|
options.set_format ("OASIS");
|
||||||
|
db::Writer writer (options);
|
||||||
|
writer.write (g, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
tl::InputStream in (tmp_file);
|
||||||
|
db::Reader reader (in);
|
||||||
|
db::Layout gg;
|
||||||
|
reader.set_warnings_as_errors (true);
|
||||||
|
reader.read (gg);
|
||||||
|
|
||||||
|
const char *expected =
|
||||||
|
"begin_lib 0.001\n"
|
||||||
|
"begin_cell {$1}\n"
|
||||||
|
"box 1 0 {100 0} {100 200}\n"
|
||||||
|
"end_cell\n"
|
||||||
|
"begin_cell {$2}\n"
|
||||||
|
"sref {$1} 0 0 1 {0 0}\n"
|
||||||
|
"sref {$1} 0 0 1 {17 -42}\n"
|
||||||
|
"end_cell\n"
|
||||||
|
"end_lib\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
tl::OutputStringStream os;
|
||||||
|
tl::OutputStream stream (os);
|
||||||
|
db::TextWriter textwriter (stream);
|
||||||
|
textwriter.write (gg);
|
||||||
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(119_WithAndWithoutContext)
|
||||||
|
{
|
||||||
|
// PCells with context and without
|
||||||
|
|
||||||
|
db::Manager m;
|
||||||
|
db::Layout g (&m);
|
||||||
|
|
||||||
|
// Note: this sample requires the BASIC lib
|
||||||
|
|
||||||
|
{
|
||||||
|
std::string fn (tl::testsrc ());
|
||||||
|
fn += "/testdata/oasis/pcell_test.gds";
|
||||||
|
tl::InputStream stream (fn);
|
||||||
|
db::Reader reader (stream);
|
||||||
|
reader.read (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string tmp_file = tl::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter119a.oas"));
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::OutputStream out (tmp_file);
|
||||||
|
db::SaveLayoutOptions options;
|
||||||
|
options.set_format ("OASIS");
|
||||||
|
db::Writer writer (options);
|
||||||
|
writer.write (g, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::InputStream in (tmp_file);
|
||||||
|
db::Reader reader (in);
|
||||||
|
db::Layout gg;
|
||||||
|
reader.set_warnings_as_errors (true);
|
||||||
|
reader.read (gg);
|
||||||
|
|
||||||
|
std::pair<bool, db::cell_index_type> tc = gg.cell_by_name ("TEXT");
|
||||||
|
tl_assert (tc.first);
|
||||||
|
|
||||||
|
const db::Cell &text_cell = gg.cell (tc.second);
|
||||||
|
EXPECT_EQ (text_cell.is_proxy (), true);
|
||||||
|
EXPECT_EQ (text_cell.get_display_name (), "Basic.TEXT('KLAYOUT RULES')");
|
||||||
|
|
||||||
|
CHECKPOINT ();
|
||||||
|
db::compare_layouts (_this, gg, tl::testsrc () + "/testdata/oasis/dbOASISWriter119_au.gds", db::NoNormalization);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_file = tl::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter119b.oas"));
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::OutputStream out (tmp_file);
|
||||||
|
db::SaveLayoutOptions options;
|
||||||
|
options.set_write_context_info (false);
|
||||||
|
options.set_format ("OASIS");
|
||||||
|
db::Writer writer (options);
|
||||||
|
writer.write (g, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::InputStream in (tmp_file);
|
||||||
|
db::Reader reader (in);
|
||||||
|
db::Layout gg;
|
||||||
|
reader.set_warnings_as_errors (true);
|
||||||
|
reader.read (gg);
|
||||||
|
|
||||||
|
std::pair<bool, db::cell_index_type> tc = gg.cell_by_name ("TEXT");
|
||||||
|
tl_assert (tc.first);
|
||||||
|
|
||||||
|
const db::Cell &text_cell = gg.cell (tc.second);
|
||||||
|
EXPECT_EQ (text_cell.is_proxy (), false);
|
||||||
|
EXPECT_EQ (text_cell.get_display_name (), "TEXT");
|
||||||
|
|
||||||
|
CHECKPOINT ();
|
||||||
|
db::compare_layouts (_this, gg, tl::testsrc () + "/testdata/oasis/dbOASISWriter119_au.gds", db::NoNormalization);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -362,7 +362,7 @@ pya_plain_iterator_next (PyObject *self)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment on first visit
|
// increment except on first visit
|
||||||
if (! iter->first) {
|
if (! iter->first) {
|
||||||
iter->iter->inc ();
|
iter->iter->inc ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ PYTHONTEST (dbTransTest, "dbTransTest.py")
|
||||||
PYTHONTEST (dbLayoutToNetlist, "dbLayoutToNetlist.py")
|
PYTHONTEST (dbLayoutToNetlist, "dbLayoutToNetlist.py")
|
||||||
PYTHONTEST (dbLayoutVsSchematic, "dbLayoutVsSchematic.py")
|
PYTHONTEST (dbLayoutVsSchematic, "dbLayoutVsSchematic.py")
|
||||||
PYTHONTEST (dbNetlistCrossReference, "dbNetlistCrossReference.py")
|
PYTHONTEST (dbNetlistCrossReference, "dbNetlistCrossReference.py")
|
||||||
|
PYTHONTEST (layLayers, "layLayers.py")
|
||||||
PYTHONTEST (tlTest, "tlTest.py")
|
PYTHONTEST (tlTest, "tlTest.py")
|
||||||
#if defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
|
#if defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
|
||||||
PYTHONTEST (qtbinding, "qtbinding.py")
|
PYTHONTEST (qtbinding, "qtbinding.py")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
source($drc_test_source)
|
||||||
|
target($drc_test_target, "TOP")
|
||||||
|
|
||||||
|
l1 = input(1, 0)
|
||||||
|
l2 = input(2, 0)
|
||||||
|
l3 = input(3, 0)
|
||||||
|
|
||||||
|
l1.output(1, 0)
|
||||||
|
l2.output(2, 0)
|
||||||
|
l3.output(3, 0)
|
||||||
|
|
||||||
|
l1.width(100.nm).output(100, 0)
|
||||||
|
l1.space(100.nm).output(101, 0)
|
||||||
|
l1.notch(100.nm).output(102, 0)
|
||||||
|
l2.separation(l3, 100.nm).output(103, 0)
|
||||||
|
l2.overlap(l3, 100.nm).output(104, 0)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
source($drc_test_source)
|
||||||
|
target($drc_test_target, "TOP")
|
||||||
|
|
||||||
|
deep
|
||||||
|
|
||||||
|
l1 = input(1, 0)
|
||||||
|
l2 = input(2, 0)
|
||||||
|
l3 = input(3, 0)
|
||||||
|
|
||||||
|
l1.output(1, 0)
|
||||||
|
l2.output(2, 0)
|
||||||
|
l3.output(3, 0)
|
||||||
|
|
||||||
|
l1.width(100.nm).output(100, 0)
|
||||||
|
l1.space(100.nm).output(101, 0)
|
||||||
|
l1.notch(100.nm).output(102, 0)
|
||||||
|
l2.separation(l3, 100.nm).output(103, 0)
|
||||||
|
l2.overlap(l3, 100.nm).output(104, 0)
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,956 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
|
||||||
|
import pya
|
||||||
|
import unittest
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
class LAYLayersTest(unittest.TestCase):
|
||||||
|
|
||||||
|
def lnode_str(self, space, l):
|
||||||
|
return space + l.current().source_(True) + "\n";
|
||||||
|
|
||||||
|
def lnodes_str(self, space, l):
|
||||||
|
res = ""
|
||||||
|
while not l.at_end():
|
||||||
|
res += self.lnode_str(space, l)
|
||||||
|
if l.current().has_children():
|
||||||
|
l.down_first_child()
|
||||||
|
res += self.lnodes_str(" " + space, l)
|
||||||
|
l.up()
|
||||||
|
l.next_sibling(1)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def lnodes_str2(self, v):
|
||||||
|
res = []
|
||||||
|
for c in v.each_layer():
|
||||||
|
res.append(c.source_(True))
|
||||||
|
return "\n".join(res)
|
||||||
|
|
||||||
|
def lnodes_str3(self, v, index):
|
||||||
|
res = []
|
||||||
|
for c in v.each_layer(index):
|
||||||
|
res.append(c.source_(True))
|
||||||
|
return "\n".join(res)
|
||||||
|
|
||||||
|
def test_1(self):
|
||||||
|
|
||||||
|
app = pya.Application.instance()
|
||||||
|
mw = app.main_window()
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", 1)
|
||||||
|
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t10.gds", 2)
|
||||||
|
|
||||||
|
cv = mw.current_view()
|
||||||
|
|
||||||
|
cv.clear_layers()
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "")
|
||||||
|
|
||||||
|
pos = cv.end_layers()
|
||||||
|
self.assertEqual(pos.parent().is_null(), True)
|
||||||
|
p = pos.dup()
|
||||||
|
p.up()
|
||||||
|
self.assertEqual(p.is_null(), True)
|
||||||
|
self.assertEqual(pos.is_null(), False)
|
||||||
|
|
||||||
|
self.assertEqual(pos == cv.begin_layers(), True)
|
||||||
|
self.assertEqual(pos != cv.begin_layers(), False)
|
||||||
|
|
||||||
|
l1 = cv.insert_layer(pos, pya.LayerProperties())
|
||||||
|
|
||||||
|
self.assertEqual(pos == cv.begin_layers(), True)
|
||||||
|
self.assertEqual(pos != cv.begin_layers(), False)
|
||||||
|
self.assertEqual(pos == cv.end_layers(), False)
|
||||||
|
self.assertEqual(pos != cv.end_layers(), True)
|
||||||
|
self.assertEqual(pos < cv.end_layers(), True)
|
||||||
|
self.assertEqual(cv.end_layers() < pos, False)
|
||||||
|
self.assertEqual(pos < cv.begin_layers(), False)
|
||||||
|
self.assertEqual(cv.begin_layers() < pos, False)
|
||||||
|
self.assertEqual(pos.at_top(), True)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n")
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "1/0@1"
|
||||||
|
l11 = cv.insert_layer(pos.last_child(), new_p)
|
||||||
|
|
||||||
|
p12 = pos.last_child()
|
||||||
|
self.assertEqual(p12.parent().is_null(), False)
|
||||||
|
self.assertEqual(p12.parent() == pos, True)
|
||||||
|
|
||||||
|
pp = pos.dup()
|
||||||
|
pp.down_last_child()
|
||||||
|
self.assertEqual(pp == p12, True)
|
||||||
|
self.assertEqual(pp == pos, False)
|
||||||
|
self.assertEqual(pp.parent() == pos, True)
|
||||||
|
pp.up()
|
||||||
|
self.assertEqual(pp == pos, True)
|
||||||
|
|
||||||
|
self.assertEqual(p12.at_top(), False)
|
||||||
|
p12.to_sibling(0)
|
||||||
|
self.assertEqual(p12 == pos.first_child(), True)
|
||||||
|
self.assertEqual(p12.child_index(), 0)
|
||||||
|
p12.to_sibling(1)
|
||||||
|
self.assertEqual(p12.child_index(), 1)
|
||||||
|
self.assertEqual(p12 == pos.last_child(), True)
|
||||||
|
self.assertEqual(p12.num_siblings(), 1)
|
||||||
|
|
||||||
|
l12 = cv.insert_layer(p12, pya.LayerProperties())
|
||||||
|
l12_new = pya.LayerProperties()
|
||||||
|
l12_new.source = "1/0@2"
|
||||||
|
cv.set_layer_properties(p12, l12_new)
|
||||||
|
|
||||||
|
self.assertEqual(p12.current().cellview(), 1)
|
||||||
|
self.assertEqual(p12.current().has_upper_hier_level(True), False)
|
||||||
|
self.assertEqual(p12.current().has_lower_hier_level(True), False)
|
||||||
|
|
||||||
|
l12_new.source = "@* #1..2"
|
||||||
|
cv.set_layer_properties(p12, l12_new)
|
||||||
|
|
||||||
|
self.assertEqual(p12.current().cellview(), 0)
|
||||||
|
self.assertEqual(p12.current().has_upper_hier_level(True), True)
|
||||||
|
self.assertEqual(p12.current().has_upper_hier_level(), True)
|
||||||
|
self.assertEqual(p12.current().upper_hier_level_(True), 2)
|
||||||
|
self.assertEqual(p12.current().upper_hier_level, 2)
|
||||||
|
self.assertEqual(p12.current().has_lower_hier_level(True), True)
|
||||||
|
self.assertEqual(p12.current().has_lower_hier_level(), True)
|
||||||
|
self.assertEqual(p12.current().lower_hier_level_(True), 1)
|
||||||
|
self.assertEqual(p12.current().lower_hier_level, 1)
|
||||||
|
|
||||||
|
l12_new.source = "@* (0,0 *0.5) (0,5 r45 *2.5)"
|
||||||
|
cv.set_layer_properties(p12, l12_new)
|
||||||
|
trans = p12.current().trans_(True)
|
||||||
|
self.assertEqual(str(trans), str(p12.current().trans))
|
||||||
|
self.assertEqual(len(trans), 2)
|
||||||
|
self.assertEqual(str(trans [0]), "r0 *0.5 0,0")
|
||||||
|
self.assertEqual(str(trans [1]), "r45 *2.5 0,5")
|
||||||
|
|
||||||
|
l12_new.source = "1/0@2"
|
||||||
|
cv.set_layer_properties(p12, l12_new)
|
||||||
|
|
||||||
|
self.assertEqual(p12.num_siblings(), 2)
|
||||||
|
|
||||||
|
pos = cv.end_layers()
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "@1"
|
||||||
|
l2 = cv.insert_layer(pos, new_p)
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "7/0@*"
|
||||||
|
l21 = cv.insert_layer(pos.first_child(), new_p)
|
||||||
|
|
||||||
|
p22 = pos.last_child()
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
l22 = cv.insert_layer(pos.last_child(), new_p)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@1\n 7/0@1\n */*@1\n")
|
||||||
|
|
||||||
|
new_p = l2.dup()
|
||||||
|
new_p.source = "@2"
|
||||||
|
cv.set_layer_properties(pos, new_p)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n */*@2\n")
|
||||||
|
|
||||||
|
pos.first_child().current().source = "7/0@1"
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@1\n */*@2\n")
|
||||||
|
pos.current().source = "@*"
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@*\n 7/0@1\n */*@*\n")
|
||||||
|
pos.current().source = "@2"
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@1\n */*@2\n")
|
||||||
|
pos.first_child().current().source = "7/1@*"
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/1@2\n */*@2\n")
|
||||||
|
pos.first_child().current().source = "7/0@*"
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n */*@2\n")
|
||||||
|
|
||||||
|
l22_new = pya.LayerProperties()
|
||||||
|
l22_new.source = "7/1@*"
|
||||||
|
cv.replace_layer_node(p22, l22_new)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n 7/1@2\n")
|
||||||
|
|
||||||
|
cv.delete_layer(p22)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n")
|
||||||
|
|
||||||
|
new_p = l2.dup()
|
||||||
|
new_p.source = "%5@2"
|
||||||
|
cv.set_layer_properties(pos, new_p)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n%5@2\n %5@2\n")
|
||||||
|
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
def test_1a(self):
|
||||||
|
|
||||||
|
app = pya.Application.instance()
|
||||||
|
mw = app.main_window()
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", 1)
|
||||||
|
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t10.gds", 2)
|
||||||
|
|
||||||
|
cv = mw.current_view()
|
||||||
|
|
||||||
|
cv.clear_layers()
|
||||||
|
|
||||||
|
cv.insert_layer_list(1)
|
||||||
|
cv.rename_layer_list(1, "x")
|
||||||
|
self.assertEqual(cv.current_layer_list, 1)
|
||||||
|
cv.set_current_layer_list(0)
|
||||||
|
self.assertEqual(cv.current_layer_list, 0)
|
||||||
|
cv.set_current_layer_list(1)
|
||||||
|
self.assertEqual(cv.current_layer_list, 1)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "")
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers(1)), "")
|
||||||
|
|
||||||
|
pos = cv.end_layers(0)
|
||||||
|
self.assertEqual(pos.parent().is_null(), True)
|
||||||
|
p = pos.dup()
|
||||||
|
p.up()
|
||||||
|
self.assertEqual(p.is_null(), True)
|
||||||
|
self.assertEqual(pos.is_null(), False)
|
||||||
|
|
||||||
|
self.assertEqual(pos == cv.begin_layers(0), True)
|
||||||
|
self.assertEqual(pos != cv.begin_layers(0), False)
|
||||||
|
|
||||||
|
l1 = cv.insert_layer(0, pos, pya.LayerProperties())
|
||||||
|
|
||||||
|
self.assertEqual(pos == cv.begin_layers(0), True)
|
||||||
|
self.assertEqual(pos != cv.begin_layers(0), False)
|
||||||
|
self.assertEqual(pos == cv.end_layers(0), False)
|
||||||
|
self.assertEqual(pos != cv.end_layers(0), True)
|
||||||
|
self.assertEqual(pos < cv.end_layers(0), True)
|
||||||
|
self.assertEqual(cv.end_layers(0) < pos, False)
|
||||||
|
self.assertEqual(pos < cv.begin_layers(0), False)
|
||||||
|
self.assertEqual(cv.begin_layers(0) < pos, False)
|
||||||
|
self.assertEqual(pos.at_top(), True)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n")
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers(1)), "")
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "")
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "1/0@1"
|
||||||
|
l11 = cv.insert_layer(0, pos.last_child(), new_p)
|
||||||
|
|
||||||
|
p12 = pos.last_child()
|
||||||
|
self.assertEqual(p12.parent().is_null(), False)
|
||||||
|
self.assertEqual(p12.parent() == pos, True)
|
||||||
|
|
||||||
|
pp = pos.dup()
|
||||||
|
pp.down_last_child()
|
||||||
|
self.assertEqual(pp == p12, True)
|
||||||
|
self.assertEqual(pp == pos, False)
|
||||||
|
self.assertEqual(pp.parent() == pos, True)
|
||||||
|
pp.up()
|
||||||
|
self.assertEqual(pp == pos, True)
|
||||||
|
|
||||||
|
self.assertEqual(p12.at_top(), False)
|
||||||
|
p12.to_sibling(0)
|
||||||
|
self.assertEqual(p12 == pos.first_child(), True)
|
||||||
|
self.assertEqual(p12.child_index(), 0)
|
||||||
|
p12.to_sibling(1)
|
||||||
|
self.assertEqual(p12.child_index(), 1)
|
||||||
|
self.assertEqual(p12 == pos.last_child(), True)
|
||||||
|
self.assertEqual(p12.num_siblings(), 1)
|
||||||
|
|
||||||
|
l12 = cv.insert_layer(0, p12, pya.LayerProperties())
|
||||||
|
l12_new = pya.LayerProperties()
|
||||||
|
l12_new.source = "1/0@2"
|
||||||
|
cv.set_layer_properties(0, p12, l12_new)
|
||||||
|
|
||||||
|
self.assertEqual(p12.current().cellview(), 1)
|
||||||
|
self.assertEqual(p12.current().has_upper_hier_level(True), False)
|
||||||
|
self.assertEqual(p12.current().has_upper_hier_level(), False)
|
||||||
|
self.assertEqual(p12.current().has_lower_hier_level(True), False)
|
||||||
|
self.assertEqual(p12.current().has_lower_hier_level(), False)
|
||||||
|
|
||||||
|
l12_new.source = "@* #1..2"
|
||||||
|
cv.set_layer_properties(0, p12, l12_new)
|
||||||
|
|
||||||
|
self.assertEqual(p12.current().cellview(), 0)
|
||||||
|
self.assertEqual(p12.current().has_upper_hier_level(True), True)
|
||||||
|
self.assertEqual(p12.current().has_upper_hier_level(), True)
|
||||||
|
self.assertEqual(p12.current().upper_hier_level_(True), 2)
|
||||||
|
self.assertEqual(p12.current().upper_hier_level, 2)
|
||||||
|
self.assertEqual(p12.current().has_lower_hier_level(True), True)
|
||||||
|
self.assertEqual(p12.current().has_lower_hier_level(), True)
|
||||||
|
self.assertEqual(p12.current().lower_hier_level_(True), 1)
|
||||||
|
self.assertEqual(p12.current().lower_hier_level, 1)
|
||||||
|
|
||||||
|
l12_new.source = "@* (0,0 *0.5) (0,5 r45 *2.5)"
|
||||||
|
cv.set_layer_properties(0, p12, l12_new)
|
||||||
|
trans = p12.current().trans_(True)
|
||||||
|
self.assertEqual(len(trans), 2)
|
||||||
|
self.assertEqual(str(trans [0]), "r0 *0.5 0,0")
|
||||||
|
self.assertEqual(str(trans [1]), "r45 *2.5 0,5")
|
||||||
|
|
||||||
|
l12_new.source = "1/0@2"
|
||||||
|
cv.set_layer_properties(0, p12, l12_new)
|
||||||
|
|
||||||
|
self.assertEqual(p12.num_siblings(), 2)
|
||||||
|
|
||||||
|
pos = cv.end_layers(0)
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "@1"
|
||||||
|
l2 = cv.insert_layer(0, pos, new_p)
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "7/0@*"
|
||||||
|
l21 = cv.insert_layer(0, pos.first_child(), new_p)
|
||||||
|
|
||||||
|
p22 = pos.last_child()
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
l22 = cv.insert_layer(0, pos.last_child(), new_p)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n 1/0@1\n 1/0@2\n*/*@1\n 7/0@1\n */*@1\n")
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers(1)), "")
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "")
|
||||||
|
|
||||||
|
new_p = l2.dup()
|
||||||
|
new_p.source = "@2"
|
||||||
|
cv.set_layer_properties(0, pos, new_p)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n */*@2\n")
|
||||||
|
|
||||||
|
l22_new = pya.LayerProperties()
|
||||||
|
l22_new.source = "7/1@*"
|
||||||
|
cv.replace_layer_node(0, p22, l22_new)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n 7/1@2\n")
|
||||||
|
|
||||||
|
cv.delete_layer(0, p22)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n")
|
||||||
|
|
||||||
|
new_p = l2.dup()
|
||||||
|
new_p.source = "%5@2"
|
||||||
|
cv.set_layer_properties(0, pos, new_p)
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n 1/0@1\n 1/0@2\n%5@2\n %5@2\n")
|
||||||
|
|
||||||
|
# build a tree by building a separate tree
|
||||||
|
new_p = pya.LayerPropertiesNode()
|
||||||
|
self.assertEqual(new_p.has_children(), False)
|
||||||
|
n1 = new_p.add_child(pya.LayerProperties())
|
||||||
|
self.assertEqual(n1.has_children(), False)
|
||||||
|
n1.source = "101/0"
|
||||||
|
n2 = pya.LayerPropertiesNode()
|
||||||
|
self.assertEqual(n2.has_children(), False)
|
||||||
|
n21 = n2.add_child(pya.LayerProperties())
|
||||||
|
n21.source = "102/0"
|
||||||
|
self.assertEqual(n2.has_children(), True)
|
||||||
|
n22 = n2.add_child(pya.LayerProperties())
|
||||||
|
self.assertEqual(n2.has_children(), True)
|
||||||
|
n22.source = "103/0"
|
||||||
|
new_p.add_child(n2)
|
||||||
|
self.assertEqual(new_p.has_children(), True)
|
||||||
|
|
||||||
|
p = pos.last_child()
|
||||||
|
ll = cv.insert_layer(0, p, new_p)
|
||||||
|
self.assertEqual(p.current().has_children(), True)
|
||||||
|
self.assertEqual(p.first_child().current().has_children(), False)
|
||||||
|
self.assertEqual(p.first_child().current().source_(False), "101/0@1")
|
||||||
|
self.assertEqual(p.first_child().current().source, "%5@1")
|
||||||
|
|
||||||
|
# (test clear_children):
|
||||||
|
new_p.clear_children()
|
||||||
|
self.assertEqual(new_p.has_children(), False)
|
||||||
|
|
||||||
|
self.assertEqual(ll.has_children(), False)
|
||||||
|
|
||||||
|
cv.transaction("Delete")
|
||||||
|
li = cv.begin_layers(0)
|
||||||
|
a = []
|
||||||
|
while not li.at_end():
|
||||||
|
a.append(li.dup())
|
||||||
|
li.next()
|
||||||
|
self.assertEqual(len(a), 10)
|
||||||
|
cv.delete_layers(0, a)
|
||||||
|
self.assertEqual(cv.begin_layers(0).at_end(), True)
|
||||||
|
cv.commit()
|
||||||
|
mw.cm_undo()
|
||||||
|
self.assertEqual(cv.begin_layers(0).at_end(), False)
|
||||||
|
|
||||||
|
cv.transaction("Delete")
|
||||||
|
i = 0
|
||||||
|
while not cv.begin_layers(0).at_end():
|
||||||
|
cv.delete_layer(0, cv.begin_layers(0))
|
||||||
|
i += 1
|
||||||
|
self.assertEqual(i, 2)
|
||||||
|
self.assertEqual(cv.begin_layers(0).at_end(), True)
|
||||||
|
cv.commit()
|
||||||
|
mw.cm_undo()
|
||||||
|
self.assertEqual(cv.begin_layers(0).at_end(), False)
|
||||||
|
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
def test_2(self):
|
||||||
|
|
||||||
|
p = pya.LayerPropertiesNode()
|
||||||
|
|
||||||
|
self.assertEqual(p.source_(False), "*/*@*")
|
||||||
|
self.assertEqual(p.source, "*/*@*")
|
||||||
|
self.assertEqual(p.has_source_name(False), False)
|
||||||
|
self.assertEqual(p.has_source_name(), False)
|
||||||
|
self.assertEqual(p.has_frame_color(), False)
|
||||||
|
self.assertEqual(p.has_frame_color(True), False)
|
||||||
|
self.assertEqual(p.has_fill_color(), False)
|
||||||
|
self.assertEqual(p.has_fill_color(True), False)
|
||||||
|
self.assertEqual(p.has_dither_pattern(), False)
|
||||||
|
self.assertEqual(p.has_dither_pattern(True), False)
|
||||||
|
self.assertEqual(p.has_line_style(), False)
|
||||||
|
self.assertEqual(p.has_line_style(True), False)
|
||||||
|
|
||||||
|
p.name = "u"
|
||||||
|
self.assertEqual(p.name, "u")
|
||||||
|
|
||||||
|
p.source_name = "x"
|
||||||
|
self.assertEqual(p.source_name_(False), "x")
|
||||||
|
self.assertEqual(p.source_name, "x")
|
||||||
|
self.assertEqual(p.source_(False), "x@*")
|
||||||
|
self.assertEqual(p.source, "x@*")
|
||||||
|
self.assertEqual(p.flat().source, "x@*")
|
||||||
|
self.assertEqual(p.dup().source, "x@*")
|
||||||
|
self.assertEqual(p.has_source_name(False), True)
|
||||||
|
self.assertEqual(p.has_source_name(), True)
|
||||||
|
|
||||||
|
p.clear_source_name()
|
||||||
|
self.assertEqual(p.source_(False), "*/*@*")
|
||||||
|
self.assertEqual(p.has_source_name(False), False)
|
||||||
|
|
||||||
|
p.source_layer_index = 6
|
||||||
|
self.assertEqual(p.source_(False), "%6@*")
|
||||||
|
self.assertEqual(p.source_layer_index_(False), 6)
|
||||||
|
self.assertEqual(p.source_layer_index, 6)
|
||||||
|
|
||||||
|
p.source_layer = 6
|
||||||
|
p.source_datatype = 5
|
||||||
|
self.assertEqual(p.source_(False), "%6@*")
|
||||||
|
|
||||||
|
p.source_layer_index = -1
|
||||||
|
self.assertEqual(p.source_(False), "6/5@*")
|
||||||
|
self.assertEqual(p.source_layer_index_(False), -1)
|
||||||
|
self.assertEqual(p.source_layer_index, -1)
|
||||||
|
self.assertEqual(p.source_layer_(False), 6)
|
||||||
|
self.assertEqual(p.source_layer, 6)
|
||||||
|
self.assertEqual(p.source_datatype_(False), 5)
|
||||||
|
self.assertEqual(p.source_datatype, 5)
|
||||||
|
|
||||||
|
arr = [ pya.CplxTrans.new(pya.CplxTrans.M45), pya.CplxTrans.new(pya.CplxTrans.R270) ]
|
||||||
|
p.trans = arr
|
||||||
|
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0)")
|
||||||
|
self.assertEqual(arr == p.trans_(False), True)
|
||||||
|
|
||||||
|
p.source_cellview = 1
|
||||||
|
self.assertEqual(p.source_(False), "6/5@2 (m45 *1 0,0) (r270 *1 0,0)")
|
||||||
|
self.assertEqual(p.flat().source, "6/5@2 (m45 *1 0,0) (r270 *1 0,0)")
|
||||||
|
self.assertEqual(p.source_cellview_(False), 1)
|
||||||
|
self.assertEqual(p.source_cellview, 1)
|
||||||
|
p.source_cellview = -1
|
||||||
|
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0)")
|
||||||
|
|
||||||
|
p.upper_hier_level = 17
|
||||||
|
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0) #..17")
|
||||||
|
self.assertEqual(p.upper_hier_level_(False), 17)
|
||||||
|
self.assertEqual(p.upper_hier_level, 17)
|
||||||
|
self.assertEqual(p.has_upper_hier_level(False), True)
|
||||||
|
self.assertEqual(p.upper_hier_level_relative(), False)
|
||||||
|
self.assertEqual(p.upper_hier_level_relative(True), False)
|
||||||
|
p.set_upper_hier_level(11, True)
|
||||||
|
self.assertEqual(p.upper_hier_level_mode(False), 0)
|
||||||
|
self.assertEqual(p.upper_hier_level_mode(), 0)
|
||||||
|
self.assertEqual(p.upper_hier_level, 11)
|
||||||
|
self.assertEqual(p.upper_hier_level_relative(), True)
|
||||||
|
self.assertEqual(p.upper_hier_level_relative(True), True)
|
||||||
|
p.set_upper_hier_level(11, True, 1)
|
||||||
|
self.assertEqual(p.upper_hier_level, 11)
|
||||||
|
self.assertEqual(p.upper_hier_level_mode(False), 1)
|
||||||
|
self.assertEqual(p.upper_hier_level_mode(), 1)
|
||||||
|
p.set_upper_hier_level(11, True, 2)
|
||||||
|
self.assertEqual(p.upper_hier_level_mode(False), 2)
|
||||||
|
self.assertEqual(p.upper_hier_level_mode(), 2)
|
||||||
|
p.clear_upper_hier_level()
|
||||||
|
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0)")
|
||||||
|
self.assertEqual(p.has_upper_hier_level(False), False)
|
||||||
|
self.assertEqual(p.has_upper_hier_level(), False)
|
||||||
|
|
||||||
|
p.lower_hier_level = 17
|
||||||
|
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0) #17..")
|
||||||
|
self.assertEqual(p.source, "6/5@* (m45 *1 0,0) (r270 *1 0,0) #17..")
|
||||||
|
self.assertEqual(p.lower_hier_level_(False), 17)
|
||||||
|
self.assertEqual(p.lower_hier_level, 17)
|
||||||
|
self.assertEqual(p.has_lower_hier_level(False), True)
|
||||||
|
self.assertEqual(p.has_lower_hier_level(), True)
|
||||||
|
self.assertEqual(p.lower_hier_level_relative(), False)
|
||||||
|
self.assertEqual(p.lower_hier_level_relative(True), False)
|
||||||
|
p.set_lower_hier_level(10, True)
|
||||||
|
self.assertEqual(p.lower_hier_level, 10)
|
||||||
|
self.assertEqual(p.lower_hier_level_relative(), True)
|
||||||
|
self.assertEqual(p.lower_hier_level_relative(True), True)
|
||||||
|
p.set_lower_hier_level(11, True, 1)
|
||||||
|
self.assertEqual(p.lower_hier_level, 11)
|
||||||
|
self.assertEqual(p.lower_hier_level_mode(False), 1)
|
||||||
|
self.assertEqual(p.lower_hier_level_mode(), 1)
|
||||||
|
p.set_lower_hier_level(11, True, 2)
|
||||||
|
self.assertEqual(p.lower_hier_level_mode(False), 2)
|
||||||
|
self.assertEqual(p.lower_hier_level_mode(), 2)
|
||||||
|
p.clear_lower_hier_level()
|
||||||
|
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0)")
|
||||||
|
self.assertEqual(p.source, "6/5@* (m45 *1 0,0) (r270 *1 0,0)")
|
||||||
|
self.assertEqual(p.has_lower_hier_level(False), False)
|
||||||
|
self.assertEqual(p.has_lower_hier_level(), False)
|
||||||
|
|
||||||
|
p.dither_pattern = 18
|
||||||
|
self.assertEqual(p.dither_pattern_(True), 18)
|
||||||
|
self.assertEqual(p.flat().dither_pattern_(True), 18)
|
||||||
|
self.assertEqual(p.dither_pattern, 18)
|
||||||
|
self.assertEqual(p.eff_dither_pattern(), 18)
|
||||||
|
self.assertEqual(p.eff_dither_pattern(True), 18)
|
||||||
|
self.assertEqual(p.has_dither_pattern(), True)
|
||||||
|
self.assertEqual(p.has_dither_pattern(True), True)
|
||||||
|
|
||||||
|
p.line_style = 12
|
||||||
|
self.assertEqual(p.line_style_(True), 12)
|
||||||
|
self.assertEqual(p.flat().line_style_(True), 12)
|
||||||
|
self.assertEqual(p.line_style, 12)
|
||||||
|
self.assertEqual(p.eff_line_style(), 12)
|
||||||
|
self.assertEqual(p.eff_line_style(True), 12)
|
||||||
|
self.assertEqual(p.has_line_style(), True)
|
||||||
|
self.assertEqual(p.has_line_style(True), True)
|
||||||
|
|
||||||
|
p.animation = 2
|
||||||
|
self.assertEqual(p.animation_(True), 2)
|
||||||
|
self.assertEqual(p.flat().animation_(True), 2)
|
||||||
|
self.assertEqual(p.animation, 2)
|
||||||
|
|
||||||
|
p.marked = True
|
||||||
|
self.assertEqual(p.marked_(True), True)
|
||||||
|
self.assertEqual(p.flat().marked_(True), True)
|
||||||
|
self.assertEqual(p.marked, True)
|
||||||
|
|
||||||
|
p.marked = False
|
||||||
|
self.assertEqual(p.marked_(False), False)
|
||||||
|
self.assertEqual(p.flat().marked_(False), False)
|
||||||
|
self.assertEqual(p.marked, False)
|
||||||
|
|
||||||
|
p.transparent = True
|
||||||
|
self.assertEqual(p.transparent_(True), True)
|
||||||
|
self.assertEqual(p.flat().transparent_(True), True)
|
||||||
|
self.assertEqual(p.transparent, True)
|
||||||
|
|
||||||
|
p.transparent = False
|
||||||
|
self.assertEqual(p.transparent_(False), False)
|
||||||
|
self.assertEqual(p.flat().transparent_(False), False)
|
||||||
|
self.assertEqual(p.transparent, False)
|
||||||
|
|
||||||
|
p.visible = True
|
||||||
|
self.assertEqual(p.visible_(True), True)
|
||||||
|
self.assertEqual(p.flat().visible_(True), True)
|
||||||
|
self.assertEqual(p.visible, True)
|
||||||
|
|
||||||
|
p.visible = False
|
||||||
|
self.assertEqual(p.visible_(False), False)
|
||||||
|
self.assertEqual(p.flat().visible_(False), False)
|
||||||
|
self.assertEqual(p.visible, False)
|
||||||
|
|
||||||
|
p.valid = True
|
||||||
|
self.assertEqual(p.valid_(True), True)
|
||||||
|
self.assertEqual(p.flat().valid_(True), True)
|
||||||
|
self.assertEqual(p.valid, True)
|
||||||
|
|
||||||
|
p.valid = False
|
||||||
|
self.assertEqual(p.valid_(False), False)
|
||||||
|
self.assertEqual(p.flat().valid_(False), False)
|
||||||
|
self.assertEqual(p.valid, False)
|
||||||
|
|
||||||
|
p.xfill = True
|
||||||
|
self.assertEqual(p.xfill_(True), True)
|
||||||
|
self.assertEqual(p.flat().xfill_(True), True)
|
||||||
|
self.assertEqual(p.xfill, True)
|
||||||
|
|
||||||
|
p.xfill = False
|
||||||
|
self.assertEqual(p.xfill_(False), False)
|
||||||
|
self.assertEqual(p.flat().xfill_(False), False)
|
||||||
|
self.assertEqual(p.xfill, False)
|
||||||
|
|
||||||
|
p.width = 3
|
||||||
|
self.assertEqual(p.width_(True), 3)
|
||||||
|
self.assertEqual(p.flat().width_(True), 3)
|
||||||
|
self.assertEqual(p.width, 3)
|
||||||
|
|
||||||
|
p.frame_color = 0xff000031
|
||||||
|
self.assertEqual(p.frame_color_(True), 0xff000031)
|
||||||
|
self.assertEqual(p.flat().frame_color_(True), 0xff000031)
|
||||||
|
self.assertEqual(p.frame_color, 0xff000031)
|
||||||
|
self.assertEqual(p.has_frame_color(), True)
|
||||||
|
self.assertEqual(p.has_frame_color(True), True)
|
||||||
|
self.assertEqual(p.has_fill_color(), False)
|
||||||
|
self.assertEqual(p.has_fill_color(True), False)
|
||||||
|
|
||||||
|
p.fill_color = 0xff000032
|
||||||
|
self.assertEqual(p.fill_color_(True), 0xff000032)
|
||||||
|
self.assertEqual(p.flat().fill_color_(True), 0xff000032)
|
||||||
|
self.assertEqual(p.fill_color, 0xff000032)
|
||||||
|
self.assertEqual(p.has_frame_color(), True)
|
||||||
|
self.assertEqual(p.has_fill_color(), True)
|
||||||
|
|
||||||
|
p.frame_brightness = 41
|
||||||
|
self.assertEqual(p.frame_brightness_(True), 41)
|
||||||
|
self.assertEqual(p.flat().frame_brightness_(True), 41)
|
||||||
|
self.assertEqual(p.frame_brightness, 41)
|
||||||
|
|
||||||
|
p.fill_brightness = 42
|
||||||
|
self.assertEqual(p.fill_brightness_(True), 42)
|
||||||
|
self.assertEqual(p.flat().fill_brightness_(True), 42)
|
||||||
|
self.assertEqual(p.fill_brightness, 42)
|
||||||
|
self.assertEqual("#%06x" % p.eff_frame_color(), "#33335b")
|
||||||
|
self.assertEqual("#%06x" % p.eff_fill_color(), "#34345c")
|
||||||
|
self.assertEqual("#%06x" % p.eff_frame_color(True), "#33335b")
|
||||||
|
self.assertEqual("#%06x" % p.eff_fill_color(True), "#34345c")
|
||||||
|
|
||||||
|
p.clear_fill_color()
|
||||||
|
self.assertEqual(p.has_fill_color(), False)
|
||||||
|
p.clear_frame_color()
|
||||||
|
self.assertEqual(p.has_frame_color(), False)
|
||||||
|
p.clear_dither_pattern()
|
||||||
|
self.assertEqual(p.has_dither_pattern(), False)
|
||||||
|
p.clear_line_style()
|
||||||
|
self.assertEqual(p.has_line_style(), False)
|
||||||
|
|
||||||
|
pp = pya.LayerPropertiesNode()
|
||||||
|
self.assertEqual(pp == p, False)
|
||||||
|
self.assertEqual(pp != p, True)
|
||||||
|
pp = p.dup()
|
||||||
|
self.assertEqual(pp == p, True)
|
||||||
|
self.assertEqual(pp != p, False)
|
||||||
|
|
||||||
|
# direct replacement of objects and attributes
|
||||||
|
def test_3(self):
|
||||||
|
|
||||||
|
app = pya.Application.instance()
|
||||||
|
mw = app.main_window()
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", pya.LoadLayoutOptions(), "", 1)
|
||||||
|
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t10.gds", pya.LoadLayoutOptions(), "", 2)
|
||||||
|
|
||||||
|
cv = mw.current_view()
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "1/0@1\n2/0@1\n1/0@2\n2/0@2\n3/0@2\n3/1@2\n4/0@2\n5/0@2\n6/0@2\n6/1@2\n7/0@2\n8/0@2\n8/1@2\n")
|
||||||
|
|
||||||
|
cv.clear_layers()
|
||||||
|
|
||||||
|
pos = cv.end_layers()
|
||||||
|
self.assertEqual(pos.current().is_valid(), False)
|
||||||
|
|
||||||
|
cv.insert_layer(pos, pya.LayerProperties())
|
||||||
|
self.assertEqual(pos.current().is_valid(), True)
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n")
|
||||||
|
self.assertEqual(self.lnodes_str2(cv), "*/*@*")
|
||||||
|
|
||||||
|
self.assertEqual(cv.begin_layers().current().name, "")
|
||||||
|
self.assertEqual(cv.begin_layers().current().visible, True)
|
||||||
|
self.assertEqual(cv.begin_layers().current().dither_pattern, -1)
|
||||||
|
self.assertEqual(cv.begin_layers().current().line_style, -1)
|
||||||
|
self.assertEqual(cv.begin_layers().current().valid, True)
|
||||||
|
self.assertEqual(cv.begin_layers().current().transparent, False)
|
||||||
|
|
||||||
|
# test LayerPropertiesNodeRef
|
||||||
|
pos.current().name = "NAME"
|
||||||
|
pos.current().visible = False
|
||||||
|
pos.current().fill_color = 0xff012345
|
||||||
|
pos.current().frame_color = 0xff123456
|
||||||
|
pos.current().fill_brightness = 42
|
||||||
|
pos.current().frame_brightness = 17
|
||||||
|
pos.current().dither_pattern = 4
|
||||||
|
pos.current().line_style = 3
|
||||||
|
pos.current().valid = False
|
||||||
|
pos.current().transparent = True
|
||||||
|
pos.current().marked = False
|
||||||
|
pos.current().xfill = False
|
||||||
|
pos.current().width = 2
|
||||||
|
pos.current().animation = 2
|
||||||
|
|
||||||
|
self.assertEqual(cv.begin_layers().current().name, "NAME")
|
||||||
|
self.assertEqual(cv.begin_layers().current().visible, False)
|
||||||
|
self.assertEqual(cv.begin_layers().current().fill_color, 0xff012345)
|
||||||
|
self.assertEqual(cv.begin_layers().current().frame_color, 0xff123456)
|
||||||
|
self.assertEqual(cv.begin_layers().current().fill_brightness, 42)
|
||||||
|
self.assertEqual(cv.begin_layers().current().frame_brightness, 17)
|
||||||
|
self.assertEqual(cv.begin_layers().current().dither_pattern, 4)
|
||||||
|
self.assertEqual(cv.begin_layers().current().line_style, 3)
|
||||||
|
self.assertEqual(cv.begin_layers().current().valid, False)
|
||||||
|
self.assertEqual(cv.begin_layers().current().transparent, True)
|
||||||
|
self.assertEqual(cv.begin_layers().current().marked, False)
|
||||||
|
self.assertEqual(cv.begin_layers().current().xfill, False)
|
||||||
|
self.assertEqual(cv.begin_layers().current().width, 2)
|
||||||
|
self.assertEqual(cv.begin_layers().current().animation, 2)
|
||||||
|
|
||||||
|
pos.current().valid = True
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "1/0@1"
|
||||||
|
self.assertEqual(new_p.flat().source, "1/0@1")
|
||||||
|
self.assertEqual(new_p == new_p.flat(), True)
|
||||||
|
self.assertEqual(new_p != new_p.flat(), False)
|
||||||
|
new_p_ref = pos.current().add_child(new_p)
|
||||||
|
self.assertEqual(new_p_ref.layer_index(), cv.cellview(0).layout().layer(1, 0))
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n")
|
||||||
|
self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1")
|
||||||
|
|
||||||
|
p = pos.current().add_child()
|
||||||
|
p.source = "1/0@2"
|
||||||
|
self.assertEqual(p.is_valid(), True)
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n")
|
||||||
|
self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1\n1/0@2")
|
||||||
|
self.assertEqual(p.layer_index(), cv.cellview(1).layout().layer(1, 0))
|
||||||
|
self.assertEqual(str(p.bbox()), "(-1.4,1.8;25.16,3.8)")
|
||||||
|
self.assertEqual(p.view() == cv, True)
|
||||||
|
self.assertEqual(p.list_index(), 0)
|
||||||
|
|
||||||
|
l12_new = pya.LayerProperties()
|
||||||
|
l12_new.source = "@* #1..2"
|
||||||
|
self.assertEqual(l12_new.flat().source, "*/*@* #1..2")
|
||||||
|
self.assertEqual(pos.first_child().current().source, "1/0@1")
|
||||||
|
self.assertEqual(pos.first_child().current().is_valid(), True)
|
||||||
|
self.assertEqual(pos.last_child().current().is_valid(), False)
|
||||||
|
pos.first_child().next().current().assign(l12_new)
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n */*@* #1..2\n")
|
||||||
|
self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1\n*/*@* #1..2")
|
||||||
|
|
||||||
|
pos.first_child().next_sibling(1).current().source = "@* #3..4"
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n */*@* #3..4\n")
|
||||||
|
self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1\n*/*@* #3..4")
|
||||||
|
|
||||||
|
pos.first_child().to_sibling(1).next_sibling(-1).current().source = "7/0"
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 7/0@1\n */*@* #3..4\n")
|
||||||
|
self.assertEqual(self.lnodes_str2(cv), "*/*@*\n7/0@1\n*/*@* #3..4")
|
||||||
|
self.assertEqual(self.lnodes_str3(cv, 0), "*/*@*\n7/0@1\n*/*@* #3..4")
|
||||||
|
self.assertEqual(self.lnodes_str3(cv, 1), "")
|
||||||
|
|
||||||
|
nn = pya.LayerPropertiesNode()
|
||||||
|
nn.source = "TOP"
|
||||||
|
|
||||||
|
nn1 = pya.LayerPropertiesNode()
|
||||||
|
nn1.source = "nn1"
|
||||||
|
|
||||||
|
nn2 = pya.LayerProperties()
|
||||||
|
nn2.source = "nn1"
|
||||||
|
nn1.add_child(nn2)
|
||||||
|
|
||||||
|
nn.add_child(nn1)
|
||||||
|
|
||||||
|
pos.current().assign(nn)
|
||||||
|
self.assertEqual(pos.current().id(), nn.id())
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "TOP@1\n nn1@1\n nn1@1\n")
|
||||||
|
self.assertEqual(self.lnodes_str2(cv), "TOP@1\nnn1@1\nnn1@1")
|
||||||
|
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
# propagation of "real" attributes through the hierarchy
|
||||||
|
def test_4(self):
|
||||||
|
|
||||||
|
app = pya.Application.instance()
|
||||||
|
mw = app.main_window()
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", 1)
|
||||||
|
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t10.gds", 2)
|
||||||
|
|
||||||
|
cv = mw.current_view()
|
||||||
|
|
||||||
|
cv.clear_layers()
|
||||||
|
|
||||||
|
pos = cv.end_layers()
|
||||||
|
self.assertEqual(pos.current().is_valid(), False)
|
||||||
|
|
||||||
|
cv.insert_layer(pos, pya.LayerProperties())
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "1/0@1"
|
||||||
|
pos.current().add_child(new_p)
|
||||||
|
|
||||||
|
self.assertEqual(pos.current().visible_(True), True)
|
||||||
|
self.assertEqual(pos.current().visible_(False), True)
|
||||||
|
self.assertEqual(pos.first_child().current().visible_(True), True)
|
||||||
|
self.assertEqual(pos.first_child().current().visible_(False), True)
|
||||||
|
pos.current().visible = False
|
||||||
|
self.assertEqual(pos.current().visible_(True), False)
|
||||||
|
self.assertEqual(pos.current().visible_(False), False)
|
||||||
|
self.assertEqual(pos.first_child().current().visible_(True), False)
|
||||||
|
self.assertEqual(pos.first_child().current().visible_(False), True)
|
||||||
|
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
# delete method of iterator
|
||||||
|
def test_5(self):
|
||||||
|
|
||||||
|
app = pya.Application.instance()
|
||||||
|
mw = app.main_window()
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", 1)
|
||||||
|
|
||||||
|
cv = mw.current_view()
|
||||||
|
cv.clear_layers()
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "1/0@1"
|
||||||
|
cv.insert_layer(0, cv.end_layers(), new_p)
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "2/0@1"
|
||||||
|
cv.insert_layer(0, cv.end_layers(), new_p)
|
||||||
|
|
||||||
|
pos = cv.begin_layers()
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "1/0@1\n2/0@1\n")
|
||||||
|
self.assertEqual(pos.at_end(), False)
|
||||||
|
self.assertEqual(pos.current().source, "1/0@1")
|
||||||
|
self.assertEqual(pos.current().is_valid(), True)
|
||||||
|
|
||||||
|
pos.current().delete()
|
||||||
|
|
||||||
|
self.assertEqual(pos.current().source, "2/0@1")
|
||||||
|
self.assertEqual(pos.current().is_valid(), True)
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "2/0@1\n")
|
||||||
|
self.assertEqual(pos.at_end(), False)
|
||||||
|
|
||||||
|
pos.current().delete()
|
||||||
|
|
||||||
|
self.assertEqual(pos.current().is_valid(), False)
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "")
|
||||||
|
self.assertEqual(pos.at_end(), True)
|
||||||
|
|
||||||
|
pos.current().delete()
|
||||||
|
|
||||||
|
self.assertEqual(pos.current().is_valid(), False)
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "")
|
||||||
|
self.assertEqual(pos.at_end(), True)
|
||||||
|
|
||||||
|
# With hierarchy
|
||||||
|
cv.clear_layers()
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "1/0@1"
|
||||||
|
cv.insert_layer(0, cv.end_layers(), new_p)
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "2/0@1"
|
||||||
|
cv.insert_layer(0, cv.end_layers(), new_p)
|
||||||
|
|
||||||
|
new_p = pya.LayerProperties()
|
||||||
|
new_p.source = "3/0@1"
|
||||||
|
cv.insert_layer(0, cv.end_layers(), new_p)
|
||||||
|
|
||||||
|
pos = cv.begin_layers()
|
||||||
|
pos.next_sibling(1)
|
||||||
|
c1 = pos.current().add_child()
|
||||||
|
c1.source = "21/0@1"
|
||||||
|
c2 = pos.current().add_child()
|
||||||
|
c2.source = "22/0@1"
|
||||||
|
|
||||||
|
posn = cv.begin_layers()
|
||||||
|
posn.next_sibling(2)
|
||||||
|
c3 = posn.current().add_child()
|
||||||
|
c3.source = "31/0@1"
|
||||||
|
|
||||||
|
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "1/0@1\n2/0@1\n 21/0@1\n 22/0@1\n3/0@1\n 31/0@1\n")
|
||||||
|
|
||||||
|
pc = pos.first_child()
|
||||||
|
|
||||||
|
self.assertEqual(pc.current().source, "21/0@1")
|
||||||
|
self.assertEqual(pc.current().is_valid(), True)
|
||||||
|
self.assertEqual(pc.at_end(), False)
|
||||||
|
pc.current().delete()
|
||||||
|
|
||||||
|
self.assertEqual(pc.current().source, "22/0@1")
|
||||||
|
self.assertEqual(pc.current().is_valid(), True)
|
||||||
|
self.assertEqual(pc.at_end(), False)
|
||||||
|
pc.current().delete()
|
||||||
|
|
||||||
|
self.assertEqual(pc.at_end(), True)
|
||||||
|
self.assertEqual(pc.current().is_valid(), False)
|
||||||
|
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
# custom stipples and line styles
|
||||||
|
def test_6(self):
|
||||||
|
|
||||||
|
app = pya.Application.instance()
|
||||||
|
mw = app.main_window()
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", 1)
|
||||||
|
|
||||||
|
cv = mw.current_view()
|
||||||
|
|
||||||
|
cv.clear_stipples()
|
||||||
|
|
||||||
|
self.assertEqual(cv.get_stipple(0), "*\n")
|
||||||
|
|
||||||
|
index = cv.add_stipple("something", [ 0x1, 0x2, 0x4, 0x8 ], 4)
|
||||||
|
self.assertEqual(cv.get_stipple(index), "...*\n..*.\n.*..\n*...\n")
|
||||||
|
|
||||||
|
cv.remove_stipple(index)
|
||||||
|
self.assertEqual(cv.get_stipple(index), "*\n")
|
||||||
|
|
||||||
|
index = cv.add_stipple("something", ".**.\n*..*\n.*.*\n*.*.")
|
||||||
|
self.assertEqual(cv.get_stipple(index), ".**.\n*..*\n.*.*\n*.*.\n")
|
||||||
|
|
||||||
|
cv.clear_stipples()
|
||||||
|
self.assertEqual(cv.get_stipple(index), "*\n")
|
||||||
|
|
||||||
|
cv.clear_line_styles()
|
||||||
|
|
||||||
|
self.assertEqual(cv.get_line_style(0), "")
|
||||||
|
|
||||||
|
index = cv.add_line_style("something", 0x5, 4)
|
||||||
|
self.assertEqual(cv.get_line_style(index), "*.*.")
|
||||||
|
|
||||||
|
cv.remove_line_style(index)
|
||||||
|
self.assertEqual(cv.get_line_style(index), "")
|
||||||
|
|
||||||
|
index = cv.add_line_style("something", ".**.*..*")
|
||||||
|
self.assertEqual(cv.get_line_style(index), ".**.*..*")
|
||||||
|
|
||||||
|
cv.clear_line_styles()
|
||||||
|
self.assertEqual(cv.get_line_style(index), "")
|
||||||
|
|
||||||
|
mw.close_all()
|
||||||
|
|
||||||
|
|
||||||
|
# run unit tests
|
||||||
|
if __name__ == '__main__':
|
||||||
|
suite = unittest.TestSuite()
|
||||||
|
# NOTE: Use this instead of loadTestsfromTestCase to select a specific test:
|
||||||
|
# suite.addTest(BasicTest("test_26"))
|
||||||
|
suite = unittest.TestLoader().loadTestsFromTestCase(LAYLayersTest)
|
||||||
|
|
||||||
|
# Only runs with Application available
|
||||||
|
if "Application" in pya.__all__ and not unittest.TextTestRunner(verbosity = 1).run(suite).wasSuccessful():
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -703,6 +703,44 @@ class LAYLayers_TestClass < TestBase
|
||||||
assert_equal( lnodes_str( "", cv.begin_layers ), "*/*@*\n" )
|
assert_equal( lnodes_str( "", cv.begin_layers ), "*/*@*\n" )
|
||||||
assert_equal( lnodes_str2(cv), "*/*@*" )
|
assert_equal( lnodes_str2(cv), "*/*@*" )
|
||||||
|
|
||||||
|
assert_equal( cv.begin_layers.current.name, "" )
|
||||||
|
assert_equal( cv.begin_layers.current.visible?, true )
|
||||||
|
assert_equal( cv.begin_layers.current.dither_pattern, -1 )
|
||||||
|
assert_equal( cv.begin_layers.current.line_style, -1 )
|
||||||
|
assert_equal( cv.begin_layers.current.valid?, true )
|
||||||
|
assert_equal( cv.begin_layers.current.transparent?, false )
|
||||||
|
|
||||||
|
# test LayerPropertiesNodeRef
|
||||||
|
pos.current.name = "NAME"
|
||||||
|
pos.current.visible = false
|
||||||
|
pos.current.fill_color = 0xff012345
|
||||||
|
pos.current.frame_color = 0xff123456
|
||||||
|
pos.current.fill_brightness = 42
|
||||||
|
pos.current.frame_brightness = 17
|
||||||
|
pos.current.dither_pattern = 4
|
||||||
|
pos.current.line_style = 3
|
||||||
|
pos.current.valid = false
|
||||||
|
pos.current.transparent = true
|
||||||
|
pos.current.marked = false
|
||||||
|
pos.current.xfill = false
|
||||||
|
pos.current.width = 2
|
||||||
|
pos.current.animation = 2
|
||||||
|
|
||||||
|
assert_equal( cv.begin_layers.current.name, "NAME" )
|
||||||
|
assert_equal( cv.begin_layers.current.visible?, false )
|
||||||
|
assert_equal( cv.begin_layers.current.fill_color, 0xff012345 )
|
||||||
|
assert_equal( cv.begin_layers.current.frame_color, 0xff123456 )
|
||||||
|
assert_equal( cv.begin_layers.current.fill_brightness, 42 )
|
||||||
|
assert_equal( cv.begin_layers.current.frame_brightness, 17 )
|
||||||
|
assert_equal( cv.begin_layers.current.dither_pattern, 4 )
|
||||||
|
assert_equal( cv.begin_layers.current.line_style, 3 )
|
||||||
|
assert_equal( cv.begin_layers.current.valid?, false )
|
||||||
|
assert_equal( cv.begin_layers.current.transparent?, true )
|
||||||
|
assert_equal( cv.begin_layers.current.marked?, false )
|
||||||
|
assert_equal( cv.begin_layers.current.xfill?, false )
|
||||||
|
assert_equal( cv.begin_layers.current.width, 2 )
|
||||||
|
assert_equal( cv.begin_layers.current.animation, 2 )
|
||||||
|
|
||||||
new_p = RBA::LayerProperties::new
|
new_p = RBA::LayerProperties::new
|
||||||
new_p.source = "1/0@1"
|
new_p.source = "1/0@1"
|
||||||
assert_equal( new_p.flat.source, "1/0@1" )
|
assert_equal( new_p.flat.source, "1/0@1" )
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue