From cf511303399d2a0008885407f4167d3e6f9026d1 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 30 Mar 2021 23:20:39 +0200 Subject: [PATCH] Fixed some build issues that appeared during merge --- src/db/db/dbDeepEdgePairs.cc | 12 +++++++ src/db/db/dbDeepEdgePairs.h | 2 ++ src/db/db/dbDeepEdges.cc | 12 +++++++ src/db/db/dbDeepEdges.h | 2 ++ src/db/db/dbDeepRegion.cc | 12 +++++++ src/db/db/dbDeepRegion.h | 2 ++ src/db/db/dbDeepTexts.cc | 12 +++++++ src/db/db/dbDeepTexts.h | 2 ++ src/db/db/dbFlatEdgePairs.h | 10 ++++++ src/db/db/dbFlatEdges.h | 12 ++++++- src/db/db/dbFlatRegion.h | 10 ++++++ src/db/db/dbFlatTexts.h | 10 ++++++ src/db/db/dbGlyphs.h | 4 +-- src/db/db/dbMatrix.cc | 8 ++--- src/db/db/dbMatrix.h | 54 ++++++++++++++++++++++++++---- src/db/db/dbMutableEdgePairs.h | 4 +++ src/db/db/dbMutableEdges.h | 4 +++ src/db/db/dbMutableRegion.h | 4 +++ src/db/db/dbMutableTexts.h | 4 +++ src/db/db/dbText.h | 10 +++--- src/db/db/dbTexts.cc | 2 ++ src/db/db/dbTrans.h | 43 ++++++++++++++++++++++-- src/db/unit_tests/dbMatrixTests.cc | 8 ++--- 23 files changed, 218 insertions(+), 25 deletions(-) diff --git a/src/db/db/dbDeepEdgePairs.cc b/src/db/db/dbDeepEdgePairs.cc index a0a53cf8f..8792a6505 100644 --- a/src/db/db/dbDeepEdgePairs.cc +++ b/src/db/db/dbDeepEdgePairs.cc @@ -196,6 +196,18 @@ void DeepEdgePairs::do_transform (const db::ICplxTrans &t) invalidate_bbox (); } +void DeepEdgePairs::do_transform (const db::IMatrix2d &t) +{ + transform_deep_layer (deep_layer (), t); + invalidate_bbox (); +} + +void DeepEdgePairs::do_transform (const db::IMatrix3d &t) +{ + transform_deep_layer (deep_layer (), t); + invalidate_bbox (); +} + void DeepEdgePairs::reserve (size_t) { // Not implemented for deep regions diff --git a/src/db/db/dbDeepEdgePairs.h b/src/db/db/dbDeepEdgePairs.h index af2d3d42d..75408ea94 100644 --- a/src/db/db/dbDeepEdgePairs.h +++ b/src/db/db/dbDeepEdgePairs.h @@ -54,6 +54,8 @@ public: virtual void do_transform (const db::Trans &t); virtual void do_transform (const db::ICplxTrans &t); + virtual void do_transform (const db::IMatrix2d &t); + virtual void do_transform (const db::IMatrix3d &t); virtual void flatten (); diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index d93bef028..9660c10b9 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -256,6 +256,18 @@ void DeepEdges::do_transform (const db::ICplxTrans &t) invalidate_bbox (); } +void DeepEdges::do_transform (const db::IMatrix2d &t) +{ + transform_deep_layer (deep_layer (), t); + invalidate_bbox (); +} + +void DeepEdges::do_transform (const db::IMatrix3d &t) +{ + transform_deep_layer (deep_layer (), t); + invalidate_bbox (); +} + void DeepEdges::reserve (size_t) { // Not implemented for deep regions diff --git a/src/db/db/dbDeepEdges.h b/src/db/db/dbDeepEdges.h index a0a01a429..08fbda231 100644 --- a/src/db/db/dbDeepEdges.h +++ b/src/db/db/dbDeepEdges.h @@ -55,6 +55,8 @@ public: virtual void do_transform (const db::Trans &t); virtual void do_transform (const db::ICplxTrans &t); + virtual void do_transform (const db::IMatrix2d &t); + virtual void do_transform (const db::IMatrix3d &t); virtual void flatten (); diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index f126e08fd..a4100ef19 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -267,6 +267,18 @@ void DeepRegion::do_transform (const db::ICplxTrans &t) invalidate_bbox (); } +void DeepRegion::do_transform (const db::IMatrix2d &t) +{ + transform_deep_layer (deep_layer (), t); + invalidate_bbox (); +} + +void DeepRegion::do_transform (const db::IMatrix3d &t) +{ + transform_deep_layer (deep_layer (), t); + invalidate_bbox (); +} + void DeepRegion::reserve (size_t) { // Not implemented for deep regions diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index a2c0f06ef..38252620d 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -57,6 +57,8 @@ public: virtual void do_transform (const db::Trans &t); virtual void do_transform (const db::ICplxTrans &t); + virtual void do_transform (const db::IMatrix2d &t); + virtual void do_transform (const db::IMatrix3d &t); virtual void flatten (); diff --git a/src/db/db/dbDeepTexts.cc b/src/db/db/dbDeepTexts.cc index 85796f48b..9dd0361a9 100644 --- a/src/db/db/dbDeepTexts.cc +++ b/src/db/db/dbDeepTexts.cc @@ -218,6 +218,18 @@ void DeepTexts::do_transform (const db::ICplxTrans &t) invalidate_bbox (); } +void DeepTexts::do_transform (const db::IMatrix2d &t) +{ + transform_deep_layer (deep_layer (), t); + invalidate_bbox (); +} + +void DeepTexts::do_transform (const db::IMatrix3d &t) +{ + transform_deep_layer (deep_layer (), t); + invalidate_bbox (); +} + void DeepTexts::reserve (size_t) { // Not implemented for deep regions diff --git a/src/db/db/dbDeepTexts.h b/src/db/db/dbDeepTexts.h index 009b032eb..bda0cf452 100644 --- a/src/db/db/dbDeepTexts.h +++ b/src/db/db/dbDeepTexts.h @@ -55,6 +55,8 @@ public: virtual void do_transform (const db::Trans &t); virtual void do_transform (const db::ICplxTrans &t); + virtual void do_transform (const db::IMatrix2d &t); + virtual void do_transform (const db::IMatrix3d &t); virtual void flatten (); diff --git a/src/db/db/dbFlatEdgePairs.h b/src/db/db/dbFlatEdgePairs.h index 93db999a4..f5ef4ffdd 100644 --- a/src/db/db/dbFlatEdgePairs.h +++ b/src/db/db/dbFlatEdgePairs.h @@ -94,6 +94,16 @@ public: transform_generic (t); } + virtual void do_transform (const db::IMatrix2d &t) + { + transform_generic (t); + } + + virtual void do_transform (const db::IMatrix3d &t) + { + transform_generic (t); + } + virtual void flatten () { } db::Shapes &raw_edge_pairs () { return *mp_edge_pairs; } diff --git a/src/db/db/dbFlatEdges.h b/src/db/db/dbFlatEdges.h index c93e926db..384250641 100644 --- a/src/db/db/dbFlatEdges.h +++ b/src/db/db/dbFlatEdges.h @@ -99,7 +99,17 @@ public: transform_generic (t); } - void do_transform(const db::ICplxTrans &t) + void do_transform (const db::ICplxTrans &t) + { + transform_generic (t); + } + + void do_transform (const db::IMatrix2d &t) + { + transform_generic (t); + } + + void do_transform (const db::IMatrix3d &t) { transform_generic (t); } diff --git a/src/db/db/dbFlatRegion.h b/src/db/db/dbFlatRegion.h index 09095cc0b..1f0e2fc93 100644 --- a/src/db/db/dbFlatRegion.h +++ b/src/db/db/dbFlatRegion.h @@ -109,6 +109,16 @@ public: transform_generic (t); } + virtual void do_transform (const db::IMatrix2d &t) + { + transform_generic (t); + } + + virtual void do_transform (const db::IMatrix3d &t) + { + transform_generic (t); + } + void flatten () { } db::Shapes &raw_polygons () { return *mp_polygons; } diff --git a/src/db/db/dbFlatTexts.h b/src/db/db/dbFlatTexts.h index ab7378d71..0b4839226 100644 --- a/src/db/db/dbFlatTexts.h +++ b/src/db/db/dbFlatTexts.h @@ -97,6 +97,16 @@ public: transform_generic (t); } + virtual void do_transform (const db::IMatrix2d &t) + { + transform_generic (t); + } + + virtual void do_transform (const db::IMatrix3d &t) + { + transform_generic (t); + } + db::Shapes &raw_texts () { return *mp_texts; } const db::Shapes &raw_texts () const { return *mp_texts; } diff --git a/src/db/db/dbGlyphs.h b/src/db/db/dbGlyphs.h index 2fa6d69a2..acb1dd49c 100644 --- a/src/db/db/dbGlyphs.h +++ b/src/db/db/dbGlyphs.h @@ -121,13 +121,13 @@ public: * @param char_spacing Additional spacing between the lines in µm * @param The resulting polygons will be put here (the vector will be cleared before) */ - void text (const std::string &t, double target_dbu, double mag, bool inv, double bias, double char_spacing, double line_spacing, std::vector &polygons) const; + void text (const std::string &t, double target_dbu, double mag2, bool inv, double bias, double char_spacing, double line_spacing, std::vector &polygons) const; /** * @brief Creates the given text as a region * For the parameters see "text" */ - db::Region text_as_region (const std::string &t, double target_dbu, double mag, bool inv, double bias, double char_spacing, double line_spacing) const; + db::Region text_as_region (const std::string &t, double target_dbu, double mag2, bool inv, double bias, double char_spacing, double line_spacing) const; /** * @brief Gets the glyph for a given character diff --git a/src/db/db/dbMatrix.cc b/src/db/db/dbMatrix.cc index 5c78bb240..20c492d6f 100644 --- a/src/db/db/dbMatrix.cc +++ b/src/db/db/dbMatrix.cc @@ -46,7 +46,7 @@ matrix_2d::to_string () const template std::pair -matrix_2d::mag () const +matrix_2d::mag2 () const { double s1 = sqrt (m_m11 * m_m11 + m_m21 * m_m21); double s2 = sqrt (m_m12 * m_m12 + m_m22 * m_m22); @@ -65,7 +65,7 @@ template double matrix_2d::angle () const { - std::pair m = mag (); + std::pair m = mag2 (); double u1 = m.first; double u2 = is_mirror () ? -m.second : m.second; double n11 = m_m11 / u1; @@ -98,7 +98,7 @@ template bool matrix_2d::has_shear () const { - std::pair m = mag (); + std::pair m = mag2 (); double u1 = m.first; double u2 = is_mirror () ? -m.second : m.second; double n11 = m_m11 / u1; @@ -114,7 +114,7 @@ template double matrix_2d::shear_angle () const { - std::pair m = mag (); + std::pair m = mag2 (); double u1 = m.first; double u2 = is_mirror () ? -m.second : m.second; double n11 = m_m11 / u1; diff --git a/src/db/db/dbMatrix.h b/src/db/db/dbMatrix.h index 8e5ab74c2..835134228 100644 --- a/src/db/db/dbMatrix.h +++ b/src/db/db/dbMatrix.h @@ -309,7 +309,15 @@ public: * into the geometrical base transformations. This member returns the x and y magnification * components. The order of the execution is mirror, magnification, shear and rotation. */ - std::pair mag () const; + std::pair mag2 () const; + + /** + * @brief For compatibility with other transformations + */ + double mag () const + { + return mag2 ().first; + } /** * @brief Return the x magnification component of the matrix @@ -320,7 +328,7 @@ public: */ double mag_x () const { - return mag ().first; + return mag2 ().first; } /** @@ -332,7 +340,7 @@ public: */ double mag_y () const { - return mag ().second; + return mag2 ().second; } /** @@ -356,6 +364,22 @@ public: return matrix_2d (m, 0.0, 0.0, m); } + /** + * @brief A dummy displacement accessor (matrix2d does not have a displacement) + */ + db::vector disp () const + { + return db::vector (); + } + + /** + * @brief For compatibility with other transformations + */ + coord_type ctrans (coord_type c) const + { + return db::coord_traits::rounded (mag2 ().first * c); + } + /** * @brief Return the mirror component of the matrix * @@ -759,9 +783,25 @@ public: * into the geometrical base transformations. This member returns the magnification * component for both x and y direction (anisotropic magnification). The order of the execution is mirror, magnification, shear, rotation, perspective and displacement. */ - std::pair mag () const + std::pair mag2 () const { - return m2d ().mag (); + return m2d ().mag2 (); + } + + /** + * @brief For compatibility with other transformations + */ + double mag () const + { + return mag2 ().first; + } + + /** + * @brief For compatibility with other transformations + */ + coord_type ctrans (coord_type c) const + { + return db::coord_traits::rounded (mag2 ().first * c); } /** @@ -769,7 +809,7 @@ public: */ double mag_x () const { - return mag ().first; + return mag2 ().first; } /** @@ -777,7 +817,7 @@ public: */ double mag_y () const { - return mag ().second; + return mag2 ().second; } /** diff --git a/src/db/db/dbMutableEdgePairs.h b/src/db/db/dbMutableEdgePairs.h index 2b5785155..854d61eb0 100644 --- a/src/db/db/dbMutableEdgePairs.h +++ b/src/db/db/dbMutableEdgePairs.h @@ -49,6 +49,8 @@ public: virtual void do_transform (const db::Trans &t) = 0; virtual void do_transform (const db::ICplxTrans &t) = 0; + virtual void do_transform (const db::IMatrix2d &t) = 0; + virtual void do_transform (const db::IMatrix3d &t) = 0; virtual void flatten () = 0; @@ -58,6 +60,8 @@ public: void transform (const db::Disp &t) { do_transform (db::Trans (t)); } void transform (const db::Trans &t) { do_transform (t); } void transform (const db::ICplxTrans &t) { do_transform (t); } + void transform (const db::IMatrix2d &t) { do_transform (t); } + void transform (const db::IMatrix3d &t) { do_transform (t); } void insert (const db::EdgePair &edge_pair) { do_insert (edge_pair); } void insert (const db::Shape &shape); diff --git a/src/db/db/dbMutableEdges.h b/src/db/db/dbMutableEdges.h index 2832901f1..e24bd57e2 100644 --- a/src/db/db/dbMutableEdges.h +++ b/src/db/db/dbMutableEdges.h @@ -47,6 +47,8 @@ public: virtual void do_transform (const db::Trans &t) = 0; virtual void do_transform (const db::ICplxTrans &t) = 0; + virtual void do_transform (const db::IMatrix2d &t) = 0; + virtual void do_transform (const db::IMatrix3d &t) = 0; virtual void flatten () = 0; @@ -58,6 +60,8 @@ public: void transform (const db::Disp &t) { do_transform (db::Trans (t)); } void transform (const db::Trans &t) { do_transform (t); } void transform (const db::ICplxTrans &t) { do_transform (t); } + void transform (const db::IMatrix2d &t) { do_transform (t); } + void transform (const db::IMatrix3d &t) { do_transform (t); } void insert (const db::Edge &edge) { do_insert (edge); } void insert (const db::Box &box); diff --git a/src/db/db/dbMutableRegion.h b/src/db/db/dbMutableRegion.h index 3863e3f19..68c90a45b 100644 --- a/src/db/db/dbMutableRegion.h +++ b/src/db/db/dbMutableRegion.h @@ -51,9 +51,13 @@ public: void transform (const db::Disp &t) { do_transform (db::Trans (t)); } void transform (const db::Trans &t) { do_transform (t); } void transform (const db::ICplxTrans &t) { do_transform (t); } + void transform (const db::IMatrix2d &t) { do_transform (t); } + void transform (const db::IMatrix3d &t) { do_transform (t); } virtual void do_transform (const db::Trans &t) = 0; virtual void do_transform (const db::ICplxTrans &t) = 0; + virtual void do_transform (const db::IMatrix2d &t) = 0; + virtual void do_transform (const db::IMatrix3d &t) = 0; virtual void flatten () = 0; diff --git a/src/db/db/dbMutableTexts.h b/src/db/db/dbMutableTexts.h index a4f830970..eadd63129 100644 --- a/src/db/db/dbMutableTexts.h +++ b/src/db/db/dbMutableTexts.h @@ -49,6 +49,8 @@ public: virtual void do_transform (const db::Trans &t) = 0; virtual void do_transform (const db::ICplxTrans &t) = 0; + virtual void do_transform (const db::IMatrix3d &t) = 0; + virtual void do_transform (const db::IMatrix2d &t) = 0; virtual void flatten () = 0; @@ -58,6 +60,8 @@ public: void transform (const db::Disp &t) { do_transform (db::Trans (t)); } void transform (const db::Trans &t) { do_transform (t); } void transform (const db::ICplxTrans &t) { do_transform (t); } + void transform (const db::IMatrix3d &t) { do_transform (t); } + void transform (const db::IMatrix2d &t) { do_transform (t); } void insert (const db::Text &text) { do_insert (text); } void insert (const db::Shape &shape); diff --git a/src/db/db/dbText.h b/src/db/db/dbText.h index 20eab0e0f..5d11d9511 100644 --- a/src/db/db/dbText.h +++ b/src/db/db/dbText.h @@ -688,7 +688,8 @@ public: text &transform (const Tr &t) { typedef typename Tr::target_coord_type target_coord_type; - m_trans = simple_trans ((t.fp_trans () * m_trans.fp_trans ()).rot (), t (point_type () + m_trans.disp ()) - point ()); + fixpoint_trans fp (t); + m_trans = simple_trans ((fp * m_trans.fp_trans ()).rot (), t (point_type () + m_trans.disp ()) - point ()); m_size = t.ctrans (m_size); return *this; } @@ -708,13 +709,14 @@ public: text transformed (const Tr &t) const { typedef typename Tr::target_coord_type target_coord_type; + fixpoint_trans fp (t); size_t p = (size_t) mp_ptr; if (p & 1) { - return text (reinterpret_cast (p - 1), simple_trans ((t.fp_trans () * m_trans.fp_trans ()).rot (), t (point_type () + m_trans.disp ()) - point ()), t.ctrans (m_size), m_font, m_halign, m_valign); + return text (reinterpret_cast (p - 1), simple_trans ((fp * m_trans.fp_trans ()).rot (), t (point_type () + m_trans.disp ()) - point ()), t.ctrans (m_size), m_font, m_halign, m_valign); } else if (mp_ptr) { - return text (mp_ptr, simple_trans ((t.fp_trans () * m_trans.fp_trans ()).rot (), t (point_type () + m_trans.disp ()) - point ()), t.ctrans (m_size), m_font, m_halign, m_valign); + return text (mp_ptr, simple_trans ((fp * m_trans.fp_trans ()).rot (), t (point_type () + m_trans.disp ()) - point ()), t.ctrans (m_size), m_font, m_halign, m_valign); } else { - return text (simple_trans ((t.fp_trans () * m_trans.fp_trans ()).rot (), t (point_type () + m_trans.disp ()) - point ()), t.ctrans (m_size), m_font, m_halign, m_valign); + return text (simple_trans ((fp * m_trans.fp_trans ()).rot (), t (point_type () + m_trans.disp ()) - point ()), t.ctrans (m_size), m_font, m_halign, m_valign); } } diff --git a/src/db/db/dbTexts.cc b/src/db/db/dbTexts.cc index 33a564f0b..8bf367a23 100644 --- a/src/db/db/dbTexts.cc +++ b/src/db/db/dbTexts.cc @@ -112,6 +112,8 @@ void Texts::insert (const db::Shape &shape, const T &trans) template DB_PUBLIC void Texts::insert (const db::Shape &, const db::ICplxTrans &); template DB_PUBLIC void Texts::insert (const db::Shape &, const db::Trans &); template DB_PUBLIC void Texts::insert (const db::Shape &, const db::Disp &); +template DB_PUBLIC void Texts::insert (const db::Shape &, const db::IMatrix2d &); +template DB_PUBLIC void Texts::insert (const db::Shape &, const db::IMatrix3d &); void Texts::clear () { diff --git a/src/db/db/dbTrans.h b/src/db/db/dbTrans.h index db83aa018..7b11e57ba 100644 --- a/src/db/db/dbTrans.h +++ b/src/db/db/dbTrans.h @@ -376,6 +376,32 @@ public: // .. nothing else .. } + /** + * @brief Reduction + */ + template + explicit fixpoint_trans (const T &t) + : m_f (0) + { + *this = t.fp_trans (); + } + + /** + * @brief Reduction from a matrix2d + */ + explicit fixpoint_trans (const db::matrix_2d &t) + { + m_f = ((int (floor (t.angle () / 90.0 + 0.5) + 4)) % 4) + (t.is_mirror () ? 4 : 0); + } + + /** + * @brief Reduction from a matrix3d + */ + explicit fixpoint_trans (const db::matrix_3d &t) + { + m_f = ((int (floor (t.angle () / 90.0 + 0.5) + 4)) % 4) + (t.is_mirror () ? 4 : 0); + } + /** * @brief Returns true, if the transformation is unity */ @@ -420,7 +446,18 @@ public: // .. nothing else .. } - /** + /** + * @brief The standard constructor using a code rather than angle and mirror and no displacement + * + * @param f The rotation/mirror code (r0 .. m135 constants) + */ + explicit fixpoint_trans (unsigned int f) + : m_f (f) + { + // .. nothing else .. + } + + /** * @brief The rotation/mirror codes */ static const int r0 = 0; // No rotation @@ -1651,7 +1688,7 @@ public: { tl_assert (! m.has_shear ()); tl_assert (! m.has_perspective ()); - std::pair mag = m.mag (); + std::pair mag = m.mag2 (); tl_assert (fabs (mag.first - mag.second) < 1e-10); double rot = m.angle () * M_PI / 180.0; m_mag = m.is_mirror () ? -mag.first : mag.first; @@ -1674,7 +1711,7 @@ public: : m_u (u) { tl_assert (! m.has_shear ()); - std::pair mag = m.mag (); + std::pair mag = m.mag2 (); tl_assert (fabs (mag.first - mag.second) < 1e-10); double rot = m.angle () * M_PI / 180.0; m_mag = m.is_mirror () ? -mag.first : mag.first; diff --git a/src/db/unit_tests/dbMatrixTests.cc b/src/db/unit_tests/dbMatrixTests.cc index 605b41f04..d64e249a2 100644 --- a/src/db/unit_tests/dbMatrixTests.cc +++ b/src/db/unit_tests/dbMatrixTests.cc @@ -114,10 +114,10 @@ TEST(1) EXPECT_EQ (tl::to_string (db::Matrix2d::shear (17).has_shear ()), "true"); EXPECT_EQ (tl::to_string (db::Matrix2d::shear (40).shear_angle ()), "40"); EXPECT_EQ (tl::to_string (db::Matrix2d::shear (-40).shear_angle ()), "-40"); - EXPECT_EQ (tl::to_string (1.0 / db::Matrix2d::mag (17.5).inverted ().mag ().first), "17.5"); - EXPECT_EQ (tl::to_string (1.0 / db::Matrix2d::mag (17.5).inverted ().mag ().second), "17.5"); - EXPECT_EQ (tl::to_string (1.0 / db::Matrix2d::mag (27.5, 7.5).inverted ().mag ().first), "27.5"); - EXPECT_EQ (tl::to_string (1.0 / db::Matrix2d::mag (27.5, 7.5).inverted ().mag ().second), "7.5"); + EXPECT_EQ (tl::to_string (1.0 / db::Matrix2d::mag (17.5).inverted ().mag2 ().first), "17.5"); + EXPECT_EQ (tl::to_string (1.0 / db::Matrix2d::mag (17.5).inverted ().mag2 ().second), "17.5"); + EXPECT_EQ (tl::to_string (1.0 / db::Matrix2d::mag (27.5, 7.5).inverted ().mag2 ().first), "27.5"); + EXPECT_EQ (tl::to_string (1.0 / db::Matrix2d::mag (27.5, 7.5).inverted ().mag2 ().second), "7.5"); EXPECT_EQ (tl::to_string (db::Matrix2d::mirror (true).inverted ().is_mirror ()), "true"); EXPECT_EQ (tl::to_string (db::Matrix2d::mirror (false).inverted ().is_mirror ()), "false"); EXPECT_EQ (tl::to_string (db::Matrix2d::rotation (25).inverted ().angle ()), "-25");