From 3f80d7bbe19a6c360b84d524fa75f8fd1351bfa1 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 5 Aug 2023 22:17:28 +0200 Subject: [PATCH] Added lay::Margin object --- src/laybasic/laybasic/layMargin.cc | 106 ++++++++++++++++++ src/laybasic/laybasic/layMargin.h | 127 ++++++++++++++++++++++ src/laybasic/laybasic/laybasic.pro | 2 + src/laybasic/unit_tests/layMarginTests.cc | 82 ++++++++++++++ src/laybasic/unit_tests/unit_tests.pro | 1 + 5 files changed, 318 insertions(+) create mode 100644 src/laybasic/laybasic/layMargin.cc create mode 100644 src/laybasic/laybasic/layMargin.h create mode 100644 src/laybasic/unit_tests/layMarginTests.cc diff --git a/src/laybasic/laybasic/layMargin.cc b/src/laybasic/laybasic/layMargin.cc new file mode 100644 index 000000000..f6e88b22b --- /dev/null +++ b/src/laybasic/laybasic/layMargin.cc @@ -0,0 +1,106 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "layMargin.h" + +#include + +namespace lay +{ + +Margin::Margin (double value, bool relative) + : m_relative_value (0.0), m_absolute_value (0.0), m_relative_mode (relative) +{ + if (relative) { + m_relative_value = value; + } else { + m_absolute_value = value; + } +} + +std::string +Margin::to_string () const +{ + const double min_value = 1e-10; + + std::string res; + if (m_relative_mode) { + res = std::string ("*") + tl::to_string (m_relative_value); + if (fabs (m_absolute_value) > min_value) { + res += " "; + res += tl::to_string (m_absolute_value); + } + } else { + res = tl::to_string (m_absolute_value); + if (fabs (m_relative_value) > min_value) { + res += " *"; + res += tl::to_string (m_relative_value); + } + } + + return res; +} + +Margin +Margin::from_string (const std::string &s) +{ + Margin res; + + tl::Extractor ex (s.c_str ()); + if (ex.test ("*")) { + double v = 0.0; + ex.read (v); + res.set_relative_mode (true); + res.set_relative_value (v); + if (! ex.at_end ()) { + ex.read (v); + res.set_absolute_value (v); + } + } else { + double v = 0.0; + ex.read (v); + res.set_relative_mode (false); + res.set_absolute_value (v); + if (ex.test ("*")) { + ex.read (v); + res.set_relative_value (v); + } + } + + return res; +} + +double +Margin::get (double dim) const +{ + return m_relative_mode ? dim * m_relative_value : m_absolute_value; +} + +double +Margin::get (const db::DBox &box) const +{ + return get (std::max (box.width (), box.height ())); +} + +} + diff --git a/src/laybasic/laybasic/layMargin.h b/src/laybasic/laybasic/layMargin.h new file mode 100644 index 000000000..5b8959dd4 --- /dev/null +++ b/src/laybasic/laybasic/layMargin.h @@ -0,0 +1,127 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#ifndef HDR_layMargin +#define HDR_layMargin + +#include "laybasicCommon.h" + +#include "dbBox.h" + +namespace lay +{ + +/** + * @brief A class represeting a margin on size + * + * Margin or size can be specified absolutely (in micron units) or relative + * to some object (given by a size or a box). + * + * The object keeps relative and absolute values so it can be easily + * switched. + */ + +class LAYBASIC_PUBLIC Margin +{ +public: + /** + * @brief The constructor + */ + Margin (double value = 0.0, bool relative = false); + + /** + * @brief Gets the relative value + */ + double relative_value () const + { + return m_relative_value; + } + + /** + * @brief Sets the relative value + */ + void set_relative_value (double v) + { + m_relative_value = v; + } + + /** + * @brief Gets the absolute value + */ + double absolute_value () const + { + return m_absolute_value; + } + + /** + * @brief Sets the absolute value + */ + void set_absolute_value (double v) + { + m_absolute_value = v; + } + + /** + * @brief Gets a value indicating whether the relative value shall be used + */ + bool relative_mode () const + { + return m_relative_mode; + } + + /** + * @brief Sets a value indicating whether the relative value shall be used + */ + void set_relative_mode (bool mode) + { + m_relative_mode = mode; + } + + /** + * @brief Converts the object to a string + */ + std::string to_string () const; + + /** + * @brief Creates the object from a string + */ + static Margin from_string (const std::string &s); + + /** + * @brief Gets the resulting value for a given object dimension + */ + double get (double dim) const; + + /** + * @brief Gets the resulting value for a given box + */ + double get (const db::DBox &box) const; + +private: + double m_relative_value, m_absolute_value; + bool m_relative_mode; +}; + +} + +#endif diff --git a/src/laybasic/laybasic/laybasic.pro b/src/laybasic/laybasic/laybasic.pro index bcd01c6d1..4262ca687 100644 --- a/src/laybasic/laybasic/laybasic.pro +++ b/src/laybasic/laybasic/laybasic.pro @@ -36,6 +36,7 @@ SOURCES += \ gsiDeclLayRdbAdded.cc \ layAbstractMenu.cc \ layLayoutViewConfig.cc \ + layMargin.cc \ laybasicForceLink.cc \ layAnnotationShapes.cc \ layBitmap.cc \ @@ -86,6 +87,7 @@ SOURCES += \ layUtils.cc \ HEADERS += \ + layMargin.h \ laybasicConfig.h \ laybasicForceLink.h \ layAbstractMenu.h \ diff --git a/src/laybasic/unit_tests/layMarginTests.cc b/src/laybasic/unit_tests/layMarginTests.cc new file mode 100644 index 000000000..92693d493 --- /dev/null +++ b/src/laybasic/unit_tests/layMarginTests.cc @@ -0,0 +1,82 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "layMargin.h" + +#include "tlUnitTest.h" + +TEST(1) +{ + lay::Margin m; + + EXPECT_EQ (m.relative_mode (), false); + EXPECT_EQ (m.to_string (), "0"); + EXPECT_EQ (m.get (1.0), 0.0); + EXPECT_EQ (lay::Margin::from_string (m.to_string ()).to_string (), m.to_string ()); + + m.set_relative_mode (true); + EXPECT_EQ (m.get (1.0), 0.0); + EXPECT_EQ (m.relative_mode (), true); + EXPECT_EQ (m.to_string (), "*0"); + EXPECT_EQ (lay::Margin::from_string (m.to_string ()).to_string (), m.to_string ()); + + m = lay::Margin (1.0); + EXPECT_EQ (m.get (2.0), 1.0); + EXPECT_EQ (m.relative_mode (), false); + EXPECT_EQ (m.absolute_value (), 1.0); + EXPECT_EQ (m.to_string (), "1"); + EXPECT_EQ (lay::Margin::from_string (m.to_string ()).to_string (), m.to_string ()); + + m.set_absolute_value (2.0); + EXPECT_EQ (m.get (1.0), 2.0); + EXPECT_EQ (m.absolute_value (), 2.0); + EXPECT_EQ (m.to_string (), "2"); + EXPECT_EQ (lay::Margin::from_string (m.to_string ()).to_string (), m.to_string ()); + + m = lay::Margin (1.5, true); + EXPECT_EQ (m.get (1.0), 1.5); + EXPECT_EQ (m.get (db::DBox (0.0, 0.0, 1.0, 0.5)), 1.5); + EXPECT_EQ (m.get (db::DBox (0.0, 0.0, 1.0, 2.0)), 3.0); + EXPECT_EQ (m.relative_mode (), true); + EXPECT_EQ (m.relative_value (), 1.5); + EXPECT_EQ (m.to_string (), "*1.5"); + EXPECT_EQ (lay::Margin::from_string (m.to_string ()).to_string (), m.to_string ()); + + m.set_absolute_value (2.5); + EXPECT_EQ (m.get (1.0), 1.5); + EXPECT_EQ (m.to_string (), "*1.5 2.5"); + EXPECT_EQ (lay::Margin::from_string (m.to_string ()).to_string (), m.to_string ()); + EXPECT_EQ (m.absolute_value (), 2.5); + + m.set_relative_value (2.0); + EXPECT_EQ (m.get (1.0), 2.0); + EXPECT_EQ (m.to_string (), "*2 2.5"); + EXPECT_EQ (lay::Margin::from_string (m.to_string ()).to_string (), m.to_string ()); + EXPECT_EQ (m.relative_value (), 2.0); + + m.set_relative_mode (false); + EXPECT_EQ (m.get (1.0), 2.5); + EXPECT_EQ (m.absolute_value (), 2.5); + EXPECT_EQ (m.to_string (), "2.5 *2"); + EXPECT_EQ (lay::Margin::from_string (m.to_string ()).to_string (), m.to_string ()); + EXPECT_EQ (m.relative_value (), 2.0); +} diff --git a/src/laybasic/unit_tests/unit_tests.pro b/src/laybasic/unit_tests/unit_tests.pro index face73fbb..d0132ce06 100644 --- a/src/laybasic/unit_tests/unit_tests.pro +++ b/src/laybasic/unit_tests/unit_tests.pro @@ -11,6 +11,7 @@ SOURCES = \ layBitmap.cc \ layBitmapsToImage.cc \ layLayerProperties.cc \ + layMarginTests.cc \ layParsedLayerSource.cc \ layRenderer.cc \ layAbstractMenuTests.cc \