From de98a30f385221427df799cb8a2276d9b1ca9649 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Mon, 7 Feb 2022 19:46:13 +0100
Subject: [PATCH 01/17] Text/DText enhancements
* Enums for alignment values.
* bbox
* position
* typos fixed
---
src/db/db/gsiDeclDbText.cc | 126 ++++++++++++++++++++++++++++++------
testdata/ruby/dbTextTest.rb | 44 +++++++++++++
2 files changed, 150 insertions(+), 20 deletions(-)
diff --git a/src/db/db/gsiDeclDbText.cc b/src/db/db/gsiDeclDbText.cc
index 9b6cbe08f..4bf0e354b 100644
--- a/src/db/db/gsiDeclDbText.cc
+++ b/src/db/db/gsiDeclDbText.cc
@@ -22,6 +22,7 @@
#include "gsiDecl.h"
+#include "gsiEnums.h"
#include "dbPoint.h"
#include "dbText.h"
#include "dbHash.h"
@@ -36,6 +37,7 @@ template
struct text_defs
{
typedef typename C::coord_type coord_type;
+ typedef typename C::box_type box_type;
typedef typename C::point_type point_type;
typedef typename C::vector_type vector_type;
typedef db::simple_trans simple_trans_type;
@@ -101,22 +103,43 @@ struct text_defs
return t->font ();
}
- static void set_halign (C *t, int f)
+ static point_type get_pos (C *t)
+ {
+ return t->trans () * point_type ();
+ }
+
+ static box_type get_bbox (C *t)
+ {
+ point_type p = get_pos (t);
+ return box_type (p, p);
+ }
+
+ static void set_halign (C *t, db::HAlign f)
+ {
+ t->halign (f);
+ }
+
+ static void set_halign_int (C *t, int f)
{
t->halign (db::HAlign (f));
}
- static int get_halign (C *t)
+ static db::HAlign get_halign (C *t)
{
return t->halign ();
}
- static void set_valign (C *t, int f)
+ static void set_valign (C *t, db::VAlign f)
+ {
+ t->valign (f);
+ }
+
+ static void set_valign_int (C *t, int f)
{
t->valign (db::VAlign (f));
}
- static int get_valign (C *t)
+ static db::VAlign get_valign (C *t)
{
return t->valign ();
}
@@ -186,6 +209,18 @@ struct text_defs
method ("string", (const char *(C::*) () const) &C::string,
"@brief Get the text string\n"
) +
+ method_ext ("position", get_pos,
+ "@brief Gets the position of the text\n"
+ "\n"
+ "This convenience method has been added in version 0.28."
+ ) +
+ method_ext ("bbox", get_bbox,
+ "@brief Gets the bounding box of the text\n"
+ "The bounding box of the text is a single point - the location of the text. "
+ "Both points of the box are identical.\n"
+ "\n"
+ "This method has been added in version 0.28."
+ ) +
method_ext ("x=", set_x, gsi::arg ("x"),
"@brief Sets the x location of the text\n"
"\n"
@@ -210,43 +245,54 @@ struct text_defs
"@brief Assign a transformation (text position and orientation) to this object\n"
) +
method ("trans", (const simple_trans_type & (C::*) () const) &C::trans,
- "@brief Get the transformation\n"
+ "@brief Gets the transformation\n"
) +
method ("size=", (void (C::*) (coord_type)) &C::size, gsi::arg ("s"),
- "@brief Set the text height of this object\n"
+ "@brief Sets the text height of this object\n"
) +
method ("size", (coord_type (C::*) () const) &C::size,
- "@brief Get the text height\n"
+ "@brief Gets the text height\n"
) +
method_ext ("font=", &set_font, gsi::arg ("f"),
- "@brief Set the font number\n"
+ "@brief Sets the font number\n"
+ "The font number does not play a role for KLayout. This property is provided "
+ "for compatibility with other systems which allow using different fonts for the text objects."
) +
method_ext ("font", &get_font,
- "@brief Get the font number\n"
+ "@brief Gets the font number\n"
+ "See \\font= for a description of this property."
+ ) +
+ method_ext ("#halign=", &set_halign_int, gsi::arg ("a"),
+ "@brief Sets the horizontal alignment\n"
+ "\n"
+ "This is the version accepting integer values. It's provided for backward compatibility.\n"
) +
method_ext ("halign=", &set_halign, gsi::arg ("a"),
- "@brief Set the horizontal alignment\n"
+ "@brief Sets the horizontal alignment\n"
"\n"
"This property specifies how the text is aligned relative to the anchor point. "
- "Allowed values for this property are 0 (left), 1 (center) and 2 (right)."
"\n"
- "This property has been introduced in version 0.22.\n"
+ "This property has been introduced in version 0.22 and extended to enums in 0.28.\n"
) +
method_ext ("halign", &get_halign,
- "@brief Get the horizontal alignment\n"
+ "@brief Gets the horizontal alignment\n"
"\n"
"See \\halign= for a description of this property.\n"
) +
+ method_ext ("#valign=", &set_valign_int, gsi::arg ("a"),
+ "@brief Sets the vertical alignment\n"
+ "\n"
+ "This is the version accepting integer values. It's provided for backward compatibility.\n"
+ ) +
method_ext ("valign=", &set_valign, gsi::arg ("a"),
- "@brief Set the vertical alignment\n"
+ "@brief Sets the vertical alignment\n"
"\n"
"This property specifies how the text is aligned relative to the anchor point. "
- "Allowed values for this property are 0 (top), 1 (center) and 2 (bottom)."
"\n"
- "This property has been introduced in version 0.22.\n"
+ "This property has been introduced in version 0.22 and extended to enums in 0.28.\n"
) +
method_ext ("valign", &get_valign,
- "@brief Get the vertical alignment\n"
+ "@brief Gets the vertical alignment\n"
"\n"
"See \\valign= for a description of this property.\n"
) +
@@ -303,14 +349,14 @@ struct text_defs
"This method was introduced in version 0.23."
) +
method ("transformed", &C::template transformed, gsi::arg ("t"),
- "@brief Transform the text with the given simple transformation\n"
+ "@brief Transforms the text with the given simple transformation\n"
"\n"
"\n"
"@param t The transformation to apply\n"
"@return The transformed text\n"
) +
method ("transformed", &C::template transformed, gsi::arg ("t"),
- "@brief Transform the text with the given complex transformation\n"
+ "@brief Transforms the text with the given complex transformation\n"
"\n"
"\n"
"@param t The magnifying transformation to apply\n"
@@ -346,7 +392,7 @@ struct text_defs
"This method has been added in version 0.23.\n"
) +
method ("to_s", &C::to_string, gsi::arg ("dbu", 0.0),
- "@brief Convert to a string.\n"
+ "@brief Converts the object to a string.\n"
"If a DBU is given, the output units will be micrometers.\n"
"\n"
"The DBU argument has been added in version 0.27.6.\n"
@@ -451,4 +497,44 @@ Class decl_DText ("db", "DText",
"database objects."
);
+gsi::Enum decl_HAlign ("db", "HAlign",
+ gsi::enum_const ("HAlignLeft", db::HAlignLeft,
+ "@brief Left horizontal alignment\n"
+ ) +
+ gsi::enum_const ("HAlignCenter", db::HAlignCenter,
+ "@brief Centered horizontal alignment\n"
+ ) +
+ gsi::enum_const ("HAlignRight", db::HAlignRight,
+ "@brief Right horizontal alignment\n"
+ ) +
+ gsi::enum_const ("NoHAlign", db::NoHAlign,
+ "@brief Undefined horizontal alignment\n"
+ ),
+ "@brief This class represents the horizontal alignment modes.\n"
+ "This enum has been introduced in version 0.28."
+);
+
+gsi::Enum decl_VAlign ("db", "VAlign",
+ gsi::enum_const ("VAlignBottom", db::VAlignBottom,
+ "@brief Bottom vertical alignment\n"
+ ) +
+ gsi::enum_const ("VAlignCenter", db::VAlignCenter,
+ "@brief Centered vertical alignment\n"
+ ) +
+ gsi::enum_const ("VAlignTop", db::VAlignTop,
+ "@brief Top vertical alignment\n"
+ ) +
+ gsi::enum_const ("NoVAlign", db::NoVAlign,
+ "@brief Undefined vertical alignment\n"
+ ),
+ "@brief This class represents the vertical alignment modes.\n"
+ "This enum has been introduced in version 0.28."
+);
+
+// Inject the alignment enums
+gsi::ClassExt inject_Text_HAlign_in_parent (decl_HAlign.defs ());
+gsi::ClassExt inject_DText_HAlign_in_parent (decl_HAlign.defs ());
+gsi::ClassExt inject_Text_VAlign_in_parent (decl_VAlign.defs ());
+gsi::ClassExt inject_DText_VAlign_in_parent (decl_VAlign.defs ());
+
}
diff --git a/testdata/ruby/dbTextTest.rb b/testdata/ruby/dbTextTest.rb
index 75eedbf76..fff844660 100644
--- a/testdata/ruby/dbTextTest.rb
+++ b/testdata/ruby/dbTextTest.rb
@@ -69,12 +69,34 @@ class DBText_TestClass < TestBase
a = RBA::DText::new( "hallo", a.trans, 22.0, 7 )
assert_equal( a.string, "hallo" )
assert_equal( a.trans.to_s, "m45 5,7" )
+ assert_equal( a.position.to_s, "5,7" )
+ assert_equal( a.bbox.to_s, "(5,7;5,7)" )
assert_equal( a.font, 7 )
assert_equal( a.size, 22.0 )
a.font = 8
assert_equal( a.font, 8 )
+ a.halign = 1
+ assert_equal( a.halign.to_i, 1 )
+ assert_equal( a.halign, RBA::DText::HAlignCenter )
+ assert_equal( a.halign.to_s, "HAlignCenter" )
+
+ a.halign = RBA::DText::HAlignRight
+ assert_equal( a.halign.to_i, 2 )
+ assert_equal( a.halign, RBA::DText::HAlignRight )
+ assert_equal( a.halign.to_s, "HAlignRight" )
+
+ a.valign = 1
+ assert_equal( a.valign.to_i, 1 )
+ assert_equal( a.valign, RBA::DText::VAlignCenter )
+ assert_equal( a.valign.to_s, "VAlignCenter" )
+
+ a.valign = RBA::DText::VAlignBottom
+ assert_equal( a.valign.to_i, 2 )
+ assert_equal( a.valign, RBA::DText::VAlignBottom )
+ assert_equal( a.valign.to_s, "VAlignBottom" )
+
a.size = 23.0
assert_equal( a.size, 23.0 )
@@ -141,12 +163,34 @@ class DBText_TestClass < TestBase
a = RBA::Text::new( "hallo", a.trans, 22, 7 )
assert_equal( a.string, "hallo" )
assert_equal( a.trans.to_s, "m45 5,7" )
+ assert_equal( a.position.to_s, "5,7" )
+ assert_equal( a.bbox.to_s, "(5,7;5,7)" )
assert_equal( a.font, 7 )
assert_equal( a.size, 22.0 )
a.font = 8
assert_equal( a.font, 8 )
+ a.halign = 1
+ assert_equal( a.halign.to_i, 1 )
+ assert_equal( a.halign, RBA::Text::HAlignCenter )
+ assert_equal( a.halign.to_s, "HAlignCenter" )
+
+ a.halign = RBA::Text::HAlignLeft
+ assert_equal( a.halign.to_i, 0 )
+ assert_equal( a.halign, RBA::Text::HAlignLeft )
+ assert_equal( a.halign.to_s, "HAlignLeft" )
+
+ a.valign = 1
+ assert_equal( a.valign.to_i, 1 )
+ assert_equal( a.valign, RBA::Text::VAlignCenter )
+ assert_equal( a.valign.to_s, "VAlignCenter" )
+
+ a.valign = RBA::Text::VAlignTop
+ assert_equal( a.valign.to_i, 0 )
+ assert_equal( a.valign, RBA::Text::VAlignTop )
+ assert_equal( a.valign.to_s, "VAlignTop" )
+
a.size = 23
assert_equal( a.size, 23 )
From e2c6e7aedc72314bf6fb1e8047c0343da23a3758 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Mon, 7 Feb 2022 20:59:09 +0100
Subject: [PATCH 02/17] size/sized versions with Vector/DVector
Adds variants to size/sized which take a vector instead
of dx, dy and where the mode parameter is optional. So far
anisotropic sizing had to come with a mode argument.
---
src/db/db/gsiDeclDbPolygon.cc | 58 +++++++++++++-------------
src/db/db/gsiDeclDbRegion.cc | 74 +++++++++++++++++++---------------
testdata/ruby/dbPolygonTest.rb | 11 +++++
testdata/ruby/dbRegionTest.rb | 10 +++++
4 files changed, 92 insertions(+), 61 deletions(-)
diff --git a/src/db/db/gsiDeclDbPolygon.cc b/src/db/db/gsiDeclDbPolygon.cc
index b1573b595..4f84f11cf 100644
--- a/src/db/db/gsiDeclDbPolygon.cc
+++ b/src/db/db/gsiDeclDbPolygon.cc
@@ -965,9 +965,9 @@ struct polygon_defs
poly->size (d, d, mode);
}
- static void size_d (C *poly, coord_type d)
+ static void size_dvm (C *poly, const db::Vector &dv, unsigned int mode)
{
- poly->size (d, d, 2);
+ poly->size (dv.x (), dv.y (), mode);
}
static C sized_xy (const C *poly, coord_type dx, coord_type dy, unsigned int mode)
@@ -980,9 +980,9 @@ struct polygon_defs
return poly->sized (d, d, mode);
}
- static C sized_d (const C *poly, coord_type d)
+ static C sized_dvm (const C *poly, const db::Vector &dv, unsigned int mode)
{
- return poly->sized (d, d, 2);
+ return poly->sized (dv.x (), dv.y (), mode);
}
static bool inside (const C *poly, point_type pt)
@@ -1272,7 +1272,19 @@ struct polygon_defs
"result = ep.simple_merge_p2p([ poly ], false, false, 1)\n"
"@/code\n"
) +
- method_ext ("size", &size_dm, gsi::arg ("d"), gsi::arg ("mode"),
+ method_ext ("size", &size_dvm, gsi::arg ("dv"), gsi::arg ("mode", (unsigned int) 2),
+ "@brief Sizes the polygon (biasing)\n"
+ "\n"
+ "This method is equivalent to\n"
+ "@code\n"
+ "size(dv.x, dv.y, mode)\n"
+ "@/code\n"
+ "\n"
+ "See \\size for a detailed description.\n"
+ "\n"
+ "This version has been introduced in version 0.28.\n"
+ ) +
+ method_ext ("size", &size_dm, gsi::arg ("d"), gsi::arg ("mode", (unsigned int) 2),
"@brief Sizes the polygon (biasing)\n"
"\n"
"Shifts the contour outwards (d>0) or inwards (d<0).\n"
@@ -1294,7 +1306,19 @@ struct polygon_defs
"\n"
"This method has been introduced in version 0.23.\n"
) +
- method_ext ("sized", &sized_dm, gsi::arg ("d"), gsi::arg ("mode"),
+ method_ext ("sized", &sized_dvm, gsi::arg ("dv"), gsi::arg ("mode", (unsigned int) 2),
+ "@brief Sizes the polygon (biasing) without modifying self\n"
+ "\n"
+ "This method is equivalent to\n"
+ "@code\n"
+ "sized(dv.x, dv.y, mode)\n"
+ "@/code\n"
+ "\n"
+ "See \\size and \\sized for a detailed description.\n"
+ "\n"
+ "This version has been introduced in version 0.28.\n"
+ ) +
+ method_ext ("sized", &sized_dm, gsi::arg ("d"), gsi::arg ("mode", (unsigned int) 2),
"@brief Sizes the polygon (biasing) without modifying self\n"
"\n"
"Shifts the contour outwards (d>0) or inwards (d<0).\n"
@@ -1305,28 +1329,6 @@ struct polygon_defs
"\n"
"See \\size and \\sized for a detailed description.\n"
) +
- method_ext ("sized", &sized_d, gsi::arg ("d"),
- "@brief Sizes the polygon (biasing)\n"
- "\n"
- "@brief Sizing (biasing) without modifying self\n"
- "This method is equivalent to\n"
- "@code\n"
- "sized(d, d, 2)\n"
- "@/code\n"
- "\n"
- "See \\size and \\sized for a detailed description.\n"
- ) +
- method_ext ("size", &size_d, gsi::arg ("d"),
- "@brief Sizes the polygon (biasing)\n"
- "\n"
- "Shifts the contour outwards (d>0) or inwards (d<0).\n"
- "This method is equivalent to\n"
- "@code\n"
- "size(d, d, 2)\n"
- "@/code\n"
- "\n"
- "See \\size for a detailed description.\n"
- ) +
method ("holes", &C::holes,
"@brief Returns the number of holes"
) +
diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc
index 2c78f30f4..0cc777b8b 100644
--- a/src/db/db/gsiDeclDbRegion.cc
+++ b/src/db/db/gsiDeclDbRegion.cc
@@ -471,17 +471,6 @@ static void break_polygons (db::Region *r, size_t max_vertex_count, double max_a
r->process (db::PolygonBreaker (max_vertex_count, max_area_ratio));
}
-static db::Region &size_ext (db::Region *r, db::Coord d)
-{
- r->size (d);
- return *r;
-}
-
-static db::Region sized_ext (db::Region *r, db::Coord d)
-{
- return r->sized (d);
-}
-
static db::Region &merge_ext1 (db::Region *r, int min_wc)
{
r->merge (false, std::max (0, min_wc - 1));
@@ -740,6 +729,19 @@ fill_region_multi (const db::Region *fr, db::Cell *cell, db::cell_index_type fil
db::fill_region_repeat (cell, *fr, fill_cell_index, fc_box, row_step, column_step, fill_margin, remaining_polygons, glue_box);
}
+static db::Region
+sized_dvm (const db::Region *region, const db::Vector &dv, unsigned int mode)
+{
+ return region->sized (dv.x (), dv.y (), mode);
+}
+
+static db::Region &
+size_dvm (db::Region *region, const db::Vector &dv, unsigned int mode)
+{
+ region->size (dv.x (), dv.y (), mode);
+ return *region;
+}
+
static db::Point default_origin;
// provided by gsiDeclDbPolygon.cc:
@@ -1537,7 +1539,18 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region",
"# r now is (50,-50;50,100;100,100;100,-50)\n"
"@/code\n"
) +
- method ("size", (db::Region & (db::Region::*) (db::Coord, unsigned int)) &db::Region::size, gsi::arg ("d"), gsi::arg ("mode"),
+ method_ext ("size", &size_dvm, gsi::arg ("dv"), gsi::arg ("mode", (unsigned int) 2),
+ "@brief Anisotropic sizing (biasing)\n"
+ "\n"
+ "@return The region after the sizing has applied (self)\n"
+ "\n"
+ "This method is equivalent to \"size(dv.x, dv.y, mode)\".\n"
+ "\n"
+ "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
+ "\n"
+ "This variant has been introduced in version 0.28."
+ ) +
+ method ("size", (db::Region & (db::Region::*) (db::Coord, unsigned int)) &db::Region::size, gsi::arg ("d"), gsi::arg ("mode", (unsigned int) 2),
"@brief Isotropic sizing (biasing)\n"
"\n"
"@return The region after the sizing has applied (self)\n"
@@ -1546,39 +1559,34 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region",
"\n"
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
) +
- method_ext ("size", size_ext, gsi::arg ("d"),
- "@brief Isotropic sizing (biasing)\n"
- "\n"
- "@return The region after the sizing has applied (self)\n"
- "\n"
- "This method is equivalent to \"size(d, d, 2)\".\n"
- "\n"
- "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
- ) +
method ("sized", (db::Region (db::Region::*) (db::Coord, db::Coord, unsigned int) const) &db::Region::sized, gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("mode"),
"@brief Returns the anisotropically sized region\n"
"\n"
"@return The sized region\n"
"\n"
- "This method is returns the sized region (see \\size), but does not modify self.\n"
+ "This method returns the sized region (see \\size), but does not modify self.\n"
"\n"
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
) +
- method ("sized", (db::Region (db::Region::*) (db::Coord, unsigned int) const) &db::Region::sized, gsi::arg ("d"), gsi::arg ("mode"),
+ method_ext ("sized", &sized_dvm, gsi::arg ("dv"), gsi::arg ("mode", (unsigned int) 2),
+ "@brief Returns the (an)isotropically sized region\n"
+ "\n"
+ "@return The sized region\n"
+ "\n"
+ "This method is equivalent to \"sized(dv.x, dv.y, mode)\".\n"
+ "This method returns the sized region (see \\size), but does not modify self.\n"
+ "\n"
+ "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
+ "\n"
+ "This variant has been introduced in version 0.28."
+ ) +
+ method ("sized", (db::Region (db::Region::*) (db::Coord, unsigned int) const) &db::Region::sized, gsi::arg ("d"), gsi::arg ("mode", (unsigned int) 2),
"@brief Returns the isotropically sized region\n"
"\n"
"@return The sized region\n"
"\n"
- "This method is returns the sized region (see \\size), but does not modify self.\n"
- "\n"
- "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
- ) +
- method_ext ("sized", sized_ext, gsi::arg ("d"),
- "@brief Isotropic sizing (biasing)\n"
- "\n"
- "@return The region after the sizing has applied (self)\n"
- "\n"
- "This method is equivalent to \"sized(d, d, 2)\".\n"
+ "This method is equivalent to \"sized(d, d, mode)\".\n"
+ "This method returns the sized region (see \\size), but does not modify self.\n"
"\n"
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
) +
diff --git a/testdata/ruby/dbPolygonTest.rb b/testdata/ruby/dbPolygonTest.rb
index ac2d7c037..3f30f0cf4 100644
--- a/testdata/ruby/dbPolygonTest.rb
+++ b/testdata/ruby/dbPolygonTest.rb
@@ -277,8 +277,19 @@ class DBPolygon_TestClass < TestBase
a = RBA::Polygon::new( [ RBA::Point::new( 0, 1 ), RBA::Point::new( 1, 5 ), RBA::Point::new( 5, 5 ) ] )
assert_equal( a.to_s, "(0,1;1,5;5,5)" )
assert_equal( a.sized(2, 0, 2).to_s, "(-2,1;-1,5;7,5;2,1)" )
+ assert_equal( a.sized(RBA::Vector::new(2, 0), 2).to_s, "(-2,1;-1,5;7,5;2,1)" )
+ assert_equal( a.sized(RBA::Vector::new(2, 0)).to_s, "(-2,1;-1,5;7,5;2,1)" )
+ aa = a.dup
a.size(2, 0, 2);
assert_equal( a.to_s, "(-2,1;-1,5;7,5;2,1)" )
+ a = aa
+ aa = a.dup
+ a.size(RBA::Vector::new(2, 0), 2);
+ assert_equal( a.to_s, "(-2,1;-1,5;7,5;2,1)" )
+ a = aa
+ aa = a.dup
+ a.size(RBA::Vector::new(2, 0));
+ assert_equal( a.to_s, "(-2,1;-1,5;7,5;2,1)" )
a = RBA::Polygon::new
assert_equal( a.to_s, "()" )
diff --git a/testdata/ruby/dbRegionTest.rb b/testdata/ruby/dbRegionTest.rb
index 47b5808eb..be086fd1c 100644
--- a/testdata/ruby/dbRegionTest.rb
+++ b/testdata/ruby/dbRegionTest.rb
@@ -318,6 +318,16 @@ class DBRegion_TestClass < TestBase
rr.size(10, 20, 2)
assert_equal(rr.to_s, "(-20,-40;-20,180;0,180;0,220;110,220;110,0;90,0;90,-40)")
+ assert_equal((r1 | r2).sized(RBA::Vector::new(10, 20)).to_s, "(-20,-40;-20,180;0,180;0,220;110,220;110,0;90,0;90,-40)")
+ rr = (r1 | r2).dup
+ rr.size(10, 20, 2)
+ assert_equal(rr.to_s, "(-20,-40;-20,180;0,180;0,220;110,220;110,0;90,0;90,-40)")
+
+ assert_equal((r1 | r2).sized(RBA::Vector::new(10, 20), 2).to_s, "(-20,-40;-20,180;0,180;0,220;110,220;110,0;90,0;90,-40)")
+ rr = (r1 | r2).dup
+ rr.size(10, 20, 2)
+ assert_equal(rr.to_s, "(-20,-40;-20,180;0,180;0,220;110,220;110,0;90,0;90,-40)")
+
r1.merged_semantics = false
assert_equal((r1 | r2).sized(10, 2).to_s, "(-20,-30;-20,170;0,170;0,210;110,210;110,10;90,10;90,-30)")
From c0b38f370639cb3f91bd78aebec6b9c7deb22b2c Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Mon, 7 Feb 2022 21:56:25 +0100
Subject: [PATCH 03/17] Using a weak Layout pointer to avoid segfaults in
RecursiveShapeIterator
---
src/db/db/dbRecursiveShapeIterator.cc | 26 ++++++-------
src/db/db/dbRecursiveShapeIterator.h | 5 ++-
.../dbRecursiveShapeIteratorTests.cc | 39 +++++++++++++++++++
3 files changed, 55 insertions(+), 15 deletions(-)
diff --git a/src/db/db/dbRecursiveShapeIterator.cc b/src/db/db/dbRecursiveShapeIterator.cc
index 6b91ff9b2..ee23140ac 100644
--- a/src/db/db/dbRecursiveShapeIterator.cc
+++ b/src/db/db/dbRecursiveShapeIterator.cc
@@ -93,7 +93,6 @@ RecursiveShapeIterator::RecursiveShapeIterator ()
// anything. Not necessary reasonable.
m_layer = 0;
m_has_layers = false;
- mp_layout = 0;
mp_shapes = 0;
mp_top_cell = 0;
mp_cell = 0;
@@ -113,7 +112,6 @@ RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes)
{
m_layer = 0;
m_has_layers = false;
- mp_layout = 0;
mp_shapes = &shapes;
mp_top_cell = 0;
m_overlapping = false;
@@ -125,7 +123,6 @@ RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const
{
m_layer = 0;
m_has_layers = false;
- mp_layout = 0;
mp_shapes = &shapes;
mp_top_cell = 0;
m_overlapping = overlapping;
@@ -137,7 +134,6 @@ RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const
{
m_layer = 0;
m_has_layers = false;
- mp_layout = 0;
mp_shapes = &shapes;
mp_top_cell = 0;
m_overlapping = overlapping;
@@ -150,7 +146,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
{
m_layer = layer;
m_has_layers = false;
- mp_layout = &layout;
+ mp_layout.reset (const_cast (&layout));
mp_shapes = 0;
mp_top_cell = &cell;
m_overlapping = overlapping;
@@ -163,7 +159,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
{
m_layer = layer;
m_has_layers = false;
- mp_layout = &layout;
+ mp_layout.reset (const_cast (&layout));
mp_shapes = 0;
mp_top_cell = &cell;
m_overlapping = overlapping;
@@ -176,7 +172,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
{
m_layer = layer;
m_has_layers = false;
- mp_layout = &layout;
+ mp_layout.reset (const_cast (&layout));
mp_shapes = 0;
mp_top_cell = &cell;
m_overlapping = false;
@@ -190,7 +186,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
m_layer = 0;
m_layers = layers;
m_has_layers = true;
- mp_layout = &layout;
+ mp_layout.reset (const_cast (&layout));
mp_shapes = 0;
mp_top_cell = &cell;
m_overlapping = overlapping;
@@ -204,7 +200,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
m_layer = 0;
m_layers = layers;
m_has_layers = true;
- mp_layout = &layout;
+ mp_layout.reset (const_cast (&layout));
mp_shapes = 0;
mp_top_cell = &cell;
m_overlapping = overlapping;
@@ -218,7 +214,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
m_layer = 0;
m_layers = layers;
m_has_layers = true;
- mp_layout = &layout;
+ mp_layout.reset (const_cast (&layout));
mp_shapes = 0;
mp_top_cell = &cell;
m_overlapping = false;
@@ -232,7 +228,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
m_layer = 0;
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
m_has_layers = true;
- mp_layout = &layout;
+ mp_layout.reset (const_cast (&layout));
mp_shapes = 0;
mp_top_cell = &cell;
m_overlapping = overlapping;
@@ -246,7 +242,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
m_layer = 0;
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
m_has_layers = true;
- mp_layout = &layout;
+ mp_layout.reset (const_cast (&layout));
mp_shapes = 0;
mp_top_cell = &cell;
m_overlapping = overlapping;
@@ -260,7 +256,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
m_layer = 0;
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
m_has_layers = true;
- mp_layout = &layout;
+ mp_layout.reset (const_cast (&layout));
mp_shapes = 0;
mp_top_cell = &cell;
m_overlapping = false;
@@ -691,6 +687,8 @@ RecursiveShapeIterator::next_shape (RecursiveShapeReceiver *receiver) const
if (! m_inst.at_end () && int (m_inst_iterators.size ()) < m_max_depth) {
+ tl_assert (mp_layout);
+
// determine whether the cell is empty with respect to the layers specified
bool is_empty = false;
if (! m_has_layers) {
@@ -754,6 +752,8 @@ RecursiveShapeIterator::next_shape (RecursiveShapeReceiver *receiver) const
void
RecursiveShapeIterator::down (RecursiveShapeReceiver *receiver) const
{
+ tl_assert (mp_layout);
+
m_trans_stack.push_back (m_trans);
m_cells.push_back (mp_cell);
diff --git a/src/db/db/dbRecursiveShapeIterator.h b/src/db/db/dbRecursiveShapeIterator.h
index 2370f65a7..330563c20 100644
--- a/src/db/db/dbRecursiveShapeIterator.h
+++ b/src/db/db/dbRecursiveShapeIterator.h
@@ -29,6 +29,7 @@
#include "dbLayout.h"
#include "dbInstElement.h"
#include "tlAssert.h"
+#include "tlObject.h"
#include
@@ -603,10 +603,20 @@ delete shapes on layer 6 of cell TOP
|
The cell's bounding box. |
+
+ | dbbox |
+ |
+ The cell's bounding box in micrometer units. |
+
| cell_bbox |
|
- Same as "bbox" (disambiguator for shape and instance bounding boxes). |
+ Same as "bbox" (disambiguator from shape and instance bounding boxes). |
+
+
+ | cell_dbbox |
+ |
+ Same as "dbbox" (disambiguator from shape and instance bounding boxes). |
@@ -631,16 +641,32 @@ delete shapes on layer 6 of cell TOP
The transformation of that instance into the top cell.
For a plain cell that is a unit transformation. |
+
+ | path_dtrans |
+ |
+ The transformation of that instance into the top cell in micrometer units.
+ For a plain cell that is a unit transformation. |
+
| trans |
|
The transformation of that instance (first instance if an array). |
+
+ | dtrans |
+ |
+ The transformation of that instance (first instance if an array) in micrometer units. |
+
| inst_bbox |
|
The instance bounding box in the initial cell. |
+
+ | inst_dbbox |
+ |
+ The instance bounding box in the initial cell in micrometer units. |
+
| inst |
|
@@ -648,9 +674,14 @@ delete shapes on layer 6 of cell TOP
| array_a |
- |
+ |
The a vector for an array instance or nil if the instance is not an array. |
+
+ | array_da |
+ |
+ The a vector for an array instance in micrometer units or nil if the instance is not an array. |
+
| array_na |
Integer |
@@ -658,9 +689,14 @@ delete shapes on layer 6 of cell TOP
| array_b |
- |
+ |
The b vector for an array instance or nil if the instance is not an array. |
+
+ | array_db |
+ |
+ The b vector for an array instance in micrometer units or nil if the instance is not an array. |
+
| array_nb |
Integer |
@@ -689,14 +725,24 @@ delete shapes on layer 6 of cell TOP
| Name | Value type | Description |
| bbox |
- |
+ |
The shape's bounding box |
+
+ | dbbox |
+ |
+ The shape's bounding box in micrometer units |
+
| shape_bbox |
|
Same as "bbox" (disambiguator for cell or instance bounding boxes) |
+
+ | shape_dbbox |
+ |
+ Same as "dbbox" (disambiguator for cell or instance bounding boxes) |
+
| shape |
|
From 5dd50d2f59c57b58b97e091ae4ae577dcea87782 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Thu, 10 Feb 2022 23:56:08 +0100
Subject: [PATCH 13/17] Search/replace: also highlight results from data
queries
---
src/lay/lay/laySearchReplaceDialog.cc | 49 +++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/src/lay/lay/laySearchReplaceDialog.cc b/src/lay/lay/laySearchReplaceDialog.cc
index 701c9094e..f2f46bdb2 100644
--- a/src/lay/lay/laySearchReplaceDialog.cc
+++ b/src/lay/lay/laySearchReplaceDialog.cc
@@ -1699,6 +1699,55 @@ SearchReplaceDialog::result_selection_changed ()
}
+ } else if (index < int (m_model.data ().size ())) {
+
+ db::DCplxTrans as_dbu = db::DCplxTrans (layout.dbu ()).inverted ();
+
+ const tl::Variant &dr = m_model.data () [index];
+ for (tl::Variant::const_iterator v = dr.begin (); v != dr.end (); ++v) {
+
+ lay::Marker *marker = new lay::Marker (view (), cv_index);
+
+ if (v->is_user ()) {
+ marker->set (v->to_user (), as_dbu, global_trans);
+ } else if (v->is_user ()) {
+ marker->set (v->to_user (), db::ICplxTrans (), global_trans);
+ } else if (v->is_user ()) {
+ marker->set (v->to_user (), as_dbu, global_trans);
+ } else if (v->is_user ()) {
+ marker->set (v->to_user (), db::ICplxTrans (), global_trans);
+ } else if (v->is_user ()) {
+ marker->set (v->to_user (), as_dbu, global_trans);
+ } else if (v->is_user ()) {
+ marker->set (v->to_user (), db::ICplxTrans (), global_trans);
+ } else if (v->is_user ()) {
+ marker->set (v->to_user (), as_dbu, global_trans);
+ } else if (v->is_user ()) {
+ marker->set (v->to_user (), db::ICplxTrans (), global_trans);
+ } else if (v->is_user ()) {
+ db::DPoint p = v->to_user ();
+ marker->set (db::DBox (p, p), as_dbu, global_trans);
+ } else if (v->is_user ()) {
+ db::Point p = v->to_user ();
+ marker->set (db::Box (p, p), db::ICplxTrans (), global_trans);
+ } else if (v->is_user ()) {
+ db::DPoint p = db::DPoint () + v->to_user ();
+ marker->set (db::DBox (p, p), as_dbu, global_trans);
+ } else if (v->is_user ()) {
+ db::Point p = db::Point () + v->to_user ();
+ marker->set (db::Box (p, p), db::ICplxTrans (), global_trans);
+ } else {
+ delete marker;
+ marker = 0;
+ }
+
+ if (marker) {
+ mp_markers.push_back (marker);
+ dbox += marker->bbox ();
+ }
+
+ }
+
}
}
From 75aaf10512caa17a84ef0f58692b2098e5d959b2 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Fri, 11 Feb 2022 00:30:08 +0100
Subject: [PATCH 14/17] Query parser is somewhat more restrictive now and
doesn't read everything as cell expression.
---
src/db/db/dbLayoutQuery.cc | 124 +++++++++++++++++++++++++++----------
1 file changed, 93 insertions(+), 31 deletions(-)
diff --git a/src/db/db/dbLayoutQuery.cc b/src/db/db/dbLayoutQuery.cc
index 6024c7a28..901e615ca 100644
--- a/src/db/db/dbLayoutQuery.cc
+++ b/src/db/db/dbLayoutQuery.cc
@@ -42,10 +42,69 @@ namespace db
// --------------------------------------------------------------------------------
// Some utilities
-bool check_trailing_reserved_word (const tl::Extractor &ex0)
+static const char *s_select = "select";
+static const char *s_delete = "delete";
+static const char *s_or = "or";
+static const char *s_of = "of";
+static const char *s_on = "on";
+static const char *s_do = "do";
+static const char *s_from = "from";
+static const char *s_layer = "layer";
+static const char *s_layers = "layers";
+static const char *s_cell = "cell";
+static const char *s_cells = "cells";
+static const char *s_where = "where";
+static const char *s_shapes = "shapes";
+static const char *s_polygons = "polygons";
+static const char *s_boxes = "boxes";
+static const char *s_edges = "edges";
+static const char *s_paths = "paths";
+static const char *s_texts = "texts";
+static const char *s_instances = "instances";
+static const char *s_arrays = "arrays";
+static const char *s_sorted = "sorted";
+static const char *s_unique = "unique";
+static const char *s_by = "by";
+static const char *s_with = "with";
+static const char *s_pass = "pass";
+
+const char *s_reserved_words[] = {
+ s_select,
+ s_delete,
+ s_or,
+ s_of,
+ s_on,
+ s_do,
+ s_from,
+ s_layer,
+ s_layers,
+ s_cell,
+ s_cells,
+ s_where,
+ s_shapes,
+ s_polygons,
+ s_boxes,
+ s_edges,
+ s_paths,
+ s_texts,
+ s_instances,
+ s_arrays,
+ s_sorted,
+ s_unique,
+ s_by,
+ s_with,
+ s_pass
+};
+
+bool check_trailing_reserved_word (const tl::Extractor &ex0)
{
tl::Extractor ex = ex0;
- return (ex.test ("do") || ex.test ("sorted") || ex.test ("pass") || ex.test ("where"));
+ for (size_t i = 0; i < sizeof (s_reserved_words) / sizeof (s_reserved_words[0]); ++i) {
+ if (ex.test (s_reserved_words[i])) {
+ return true;
+ }
+ }
+ return false;
}
// --------------------------------------------------------------------------------
@@ -2370,7 +2429,7 @@ parse_cell_name_filter_element (tl::Extractor &ex, LayoutQuery *q, ChildCellFilt
std::unique_ptr b (new FilterBracket (q));
do {
parse_cell_name_filter_seq (ex, q, b.get (), instance_mode, reading);
- } while (ex.test (",") || ex.test ("or"));
+ } while (ex.test (",") || ex.test (s_or));
// TODO: do this in the optimization
if (b->children ().size () == 1 && dynamic_cast (b->children ()[0])) {
@@ -2507,21 +2566,21 @@ parse_cell_filter (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bo
std::unique_ptr b (new FilterBracket (q));
- if (ex.test ("instances")) {
- (ex.test ("of") || ex.test ("from")) && (ex.test ("cells") || ex.test ("cell"));
+ if (ex.test (s_instances)) {
+ (ex.test (s_of) || ex.test (s_from)) && (ex.test (s_cells) || ex.test (s_cell));
// Because an array member cannot be modified we use ArrayInstances in the modification case always
parse_cell_name_filter_seq (ex, q, b.get (), reading ? ExplodedInstances : ArrayInstances, reading);
- } else if (ex.test ("arrays")) {
- (ex.test ("of") || ex.test ("from")) && (ex.test ("cells") || ex.test ("cell"));
+ } else if (ex.test (s_arrays)) {
+ (ex.test (s_of) || ex.test (s_from)) && (ex.test (s_cells) || ex.test (s_cell));
parse_cell_name_filter_seq (ex, q, b.get (), ArrayInstances, reading);
} else {
- ex.test ("cells") || ex.test ("cell");
+ ex.test (s_cells) || ex.test (s_cell);
parse_cell_name_filter_seq (ex, q, b.get (), NoInstances, reading);
}
FilterBase *fl = 0, *f = 0;
- if (with_where_clause && ex.test ("where")) {
+ if (with_where_clause && ex.test (s_where)) {
std::string expr = tl::Eval::parse_expr (ex, true);
@@ -2552,22 +2611,22 @@ parse_filter (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool re
{
unsigned int sf = (unsigned int) db::ShapeIterator::Nothing;
do {
- if (ex.test ("shapes")) {
+ if (ex.test (s_shapes)) {
sf |= (unsigned int) db::ShapeIterator::All;
- } else if (ex.test ("polygons")) {
+ } else if (ex.test (s_polygons)) {
sf |= (unsigned int) db::ShapeIterator::Polygons;
- } else if (ex.test ("boxes")) {
+ } else if (ex.test (s_boxes)) {
sf |= (unsigned int) db::ShapeIterator::Boxes;
- } else if (ex.test ("edges")) {
+ } else if (ex.test (s_edges)) {
sf |= (unsigned int) db::ShapeIterator::Edges;
- } else if (ex.test ("paths")) {
+ } else if (ex.test (s_paths)) {
sf |= (unsigned int) db::ShapeIterator::Paths;
- } else if (ex.test ("texts")) {
+ } else if (ex.test (s_texts)) {
sf |= (unsigned int) db::ShapeIterator::Texts;
} else {
break;
}
- } while (ex.test (",") || ex.test ("or"));
+ } while (ex.test (",") || ex.test (s_or));
db::ShapeIterator::flags_type shapes = (db::ShapeIterator::flags_type) sf;
@@ -2575,12 +2634,12 @@ parse_filter (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool re
db::LayerMap lm;
- if (ex.test ("on")) {
- ex.test ("layer") || ex.test ("layers");
+ if (ex.test (s_on)) {
+ ex.test (s_layer) || ex.test (s_layers);
lm.map_expr (ex, 0);
}
- ex.test ("of") || ex.test ("from");
+ ex.test (s_of) || ex.test (s_from);
std::unique_ptr b (new FilterBracket (q));
parse_cell_filter (ex, q, b.get (), false, reading);
@@ -2596,7 +2655,7 @@ parse_filter (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool re
bracket->add_child (f);
fl->connect (f);
- if (ex.test ("where")) {
+ if (ex.test (s_where)) {
std::string expr = tl::Eval::parse_expr (ex, true);
@@ -2617,7 +2676,7 @@ parse_filter (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool re
void
parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool reading)
{
- if (ex.test ("select")) {
+ if (ex.test (s_select)) {
std::vector expressions;
@@ -2625,7 +2684,7 @@ parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool
expressions.push_back (tl::Eval::parse_expr (ex, true));
} while (ex.test (","));
- ex.expect ("from");
+ ex.expect (s_from);
std::unique_ptr b (new FilterBracket (q));
parse_filter (ex, q, b.get (), true);
@@ -2633,10 +2692,10 @@ parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool
bool unique = false;
std::string sort_expression;
- if (ex.test ("sorted")) {
- ex.test ("by");
+ if (ex.test (s_sorted)) {
+ ex.test (s_by);
sort_expression = tl::Eval::parse_expr (ex, true);
- unique = ex.test ("unique");
+ unique = ex.test (s_unique);
}
FilterBase *f = b.release ();
@@ -2649,16 +2708,16 @@ parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool
bracket->connect_exit (ff);
- } else if (! reading && ex.test ("with")) {
+ } else if (! reading && ex.test (s_with)) {
std::unique_ptr b (new FilterBracket (q));
parse_filter (ex, q, b.get (), false);
- ex.expect ("do");
+ ex.expect (s_do);
std::string expression = tl::Eval::parse_expr (ex, true);
- bool transparent = ex.test ("pass");
+ bool transparent = ex.test (s_pass);
FilterBase *f = b.release ();
bracket->add_child (f);
@@ -2670,12 +2729,12 @@ parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool
bracket->connect_exit (ff);
- } else if (! reading && ex.test ("delete")) {
+ } else if (! reading && ex.test (s_delete)) {
std::unique_ptr b (new FilterBracket (q));
parse_filter (ex, q, b.get (), false);
- bool transparent = ex.test ("pass");
+ bool transparent = ex.test (s_pass);
FilterBase *f = b.release ();
bracket->add_child (f);
@@ -2699,7 +2758,10 @@ LayoutQuery::LayoutQuery (const std::string &query)
tl::Extractor ex (query.c_str ());
parse_statement (ex, this, r.get (), false);
- ex.expect_end ();
+
+ if (! ex.at_end ()) {
+ ex.error (tl::to_string (tr ("Unexpected text")));
+ }
r->optimize ();
mp_root = r.release ();
From 8091464916dab6a15cf885268850e607234043fb Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Fri, 11 Feb 2022 19:12:57 +0100
Subject: [PATCH 15/17] Fixed unit tests
---
testdata/ruby/dbLayoutQuery.rb | 2 +-
testdata/ruby/dbTransTest.rb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/testdata/ruby/dbLayoutQuery.rb b/testdata/ruby/dbLayoutQuery.rb
index d55b7fc28..42d363aff 100644
--- a/testdata/ruby/dbLayoutQuery.rb
+++ b/testdata/ruby/dbLayoutQuery.rb
@@ -64,7 +64,7 @@ class DBLayoutQuery_TestClass < TestBase
def test_3
q = RBA::LayoutQuery::new("delete TOP")
- assert_equal(q.property_names.sort.join(","), "bbox,cell,cell_bbox,cell_index,cell_name,hier_levels,initial_cell,initial_cell_index,initial_cell_name,inst,instances,path,path_names,path_trans,references,shape,tot_weight,weight")
+ assert_equal(q.property_names.sort.join(","), "bbox,cell,cell_bbox,cell_dbbox,cell_index,cell_name,dbbox,hier_levels,initial_cell,initial_cell_index,initial_cell_name,inst,instances,path,path_dtrans,path_names,path_trans,references,shape,tot_weight,weight")
end
diff --git a/testdata/ruby/dbTransTest.rb b/testdata/ruby/dbTransTest.rb
index df24c8716..f97d32096 100644
--- a/testdata/ruby/dbTransTest.rb
+++ b/testdata/ruby/dbTransTest.rb
@@ -80,7 +80,7 @@ class DBTrans_TestClass < TestBase
assert_equal( RBA::Trans::new(RBA::Trans::R180, RBA::DVector::new(5,-7)).to_s, "r180 5,-7" )
assert_equal( RBA::Trans::new(RBA::Trans::R180).to_s, "r180 0,0" )
- assert_equal( e.trans( 2.0 ).to_s, "2" )
+ assert_equal( e.ctrans( 2.0 ).to_s, "2" )
assert_equal( (e * 2.0).to_s, "2" )
assert_equal( e.trans( RBA::Edge::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
assert_equal( ( e * RBA::Edge::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
From 72d0f717fe93b57805b1f1250b3e9e2a2ff16aca Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Sat, 12 Feb 2022 18:20:38 +0100
Subject: [PATCH 16/17] Fixed units tests
---
src/db/db/gsiDeclDbTrans.cc | 6 +++++-
testdata/ruby/dbTransTest.rb | 4 ++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/db/db/gsiDeclDbTrans.cc b/src/db/db/gsiDeclDbTrans.cc
index ed6296625..a6bfe92c7 100644
--- a/src/db/db/gsiDeclDbTrans.cc
+++ b/src/db/db/gsiDeclDbTrans.cc
@@ -219,7 +219,7 @@ struct trans_defs
"\n"
"@return The inverted transformation\n"
) +
- method ("ctrans", &C::ctrans, arg ("d"),
+ method ("ctrans|*", &C::ctrans, arg ("d"),
"@brief Transforms a distance\n"
"\n"
"The \"ctrans\" method transforms the given distance.\n"
@@ -229,6 +229,8 @@ struct trans_defs
"\n"
"@param d The distance to transform\n"
"@return The transformed distance\n"
+ "\n"
+ "The product '*' has been added as a synonym in version 0.28."
) +
method ("trans|*", (point_type (C::*) (const point_type &) const) &C::trans, arg ("p"),
"@brief Transforms a point\n"
@@ -752,6 +754,8 @@ struct cplx_trans_defs
"\n"
"@param d The distance to transform\n"
"@return The transformed distance\n"
+ "\n"
+ "The product '*' has been added as a synonym in version 0.28."
) +
method ("trans|*", (target_point_type (C::*) (const point_type &) const) &C::trans, arg ("p"),
"@brief Transforms a point\n"
diff --git a/testdata/ruby/dbTransTest.rb b/testdata/ruby/dbTransTest.rb
index f97d32096..6b8a96472 100644
--- a/testdata/ruby/dbTransTest.rb
+++ b/testdata/ruby/dbTransTest.rb
@@ -80,8 +80,8 @@ class DBTrans_TestClass < TestBase
assert_equal( RBA::Trans::new(RBA::Trans::R180, RBA::DVector::new(5,-7)).to_s, "r180 5,-7" )
assert_equal( RBA::Trans::new(RBA::Trans::R180).to_s, "r180 0,0" )
- assert_equal( e.ctrans( 2.0 ).to_s, "2" )
- assert_equal( (e * 2.0).to_s, "2" )
+ assert_equal( e.ctrans( 2.0 ), 2.0 )
+ assert_equal( e * 2.0, 2.0 )
assert_equal( e.trans( RBA::Edge::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
assert_equal( ( e * RBA::Edge::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
assert_equal( e.trans( RBA::Box::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
From 4e511293beebfae82e22b265a102fc98d1387868 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Mon, 14 Feb 2022 18:31:49 +0100
Subject: [PATCH 17/17] PyPI deployment: corrected branch filter
---
Jenkinsfile-pypi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Jenkinsfile-pypi b/Jenkinsfile-pypi
index 8bc51a963..632fab52e 100644
--- a/Jenkinsfile-pypi
+++ b/Jenkinsfile-pypi
@@ -33,7 +33,7 @@ node("master") {
stage("Publish and test") {
// publish for release tags
- if (BRANCH_NAME.startsWith('pypi_v')) {
+ if (BRANCH_NAME.startsWith('pypi_')) {
sh("twine upload --skip-existing wheelhouse/klayout-*manylinux2014*.whl wheelhouse/*.zip")
}