diff options
Diffstat (limited to 'geometry')
-rw-r--r-- | geometry/geometry_tests/packer_test.cpp | 55 | ||||
-rw-r--r-- | geometry/packer.cpp | 41 | ||||
-rw-r--r-- | geometry/packer.hpp | 3 |
3 files changed, 99 insertions, 0 deletions
diff --git a/geometry/geometry_tests/packer_test.cpp b/geometry/geometry_tests/packer_test.cpp index dfc747da98..bc26a9df9a 100644 --- a/geometry/geometry_tests/packer_test.cpp +++ b/geometry/geometry_tests/packer_test.cpp @@ -51,3 +51,58 @@ UNIT_TEST(PackerTest_SimplePack) TEST_EQUAL(r2, m2::RectU(0, 0, 5, 5), ()); } + +UNIT_TEST(PackerTest_HasRoom_Sequence) +{ + m2::Packer p(20, 20); + + m2::PointU pts[] = { + m2::PointU(10, 10), + m2::PointU(11, 3), + m2::PointU(5, 5), + m2::PointU(5, 5) + }; + + TEST(p.hasRoom(pts, sizeof(pts) / sizeof(m2::PointU)), ()); + + m2::PointU pts1[] = { + m2::PointU(10, 10), + m2::PointU(11, 3), + m2::PointU(5, 5), + m2::PointU(5, 5), + m2::PointU(16, 5) + }; + + TEST(!p.hasRoom(pts1, sizeof(pts1) / sizeof(m2::PointU)), ()); + + m2::PointU pts2[] = { + m2::PointU(10, 10), + m2::PointU(11, 3), + m2::PointU(5, 5), + m2::PointU(5, 5), + m2::PointU(10, 6) + }; + + TEST(!p.hasRoom(pts2, sizeof(pts2) / sizeof(m2::PointU)), ()); + + m2::PointU pts3[] = { + m2::PointU(10, 10), + m2::PointU(11, 3), + m2::PointU(5, 5), + m2::PointU(5, 5), + m2::PointU(15, 5) + }; + + TEST(p.hasRoom(pts3, sizeof(pts3) / sizeof(m2::PointU)), ()); + + m2::PointU pts4[] = { + m2::PointU(10, 10), + m2::PointU(11, 3), + m2::PointU(5, 5), + m2::PointU(5, 5), + m2::PointU(16, 5) + }; + + TEST(!p.hasRoom(pts4, sizeof(pts4) / sizeof(m2::PointU)), ()); + +} diff --git a/geometry/packer.cpp b/geometry/packer.cpp index 785560a451..074d9fa6d1 100644 --- a/geometry/packer.cpp +++ b/geometry/packer.cpp @@ -80,6 +80,47 @@ namespace m2 || ((m_width - m_currentX >= width ) && (m_height - m_currentY >= height)); } + bool Packer::hasRoom(m2::PointU const * sizes, size_t cnt) const + { + unsigned currentX = m_currentX; + unsigned currentY = m_currentY; + unsigned yStep = m_yStep; + + for (unsigned i = 0; i < cnt; ++i) + { + unsigned width = sizes[i].x; + unsigned height = sizes[i].y; + + if (width <= m_width - currentX) + { + if (height <= m_height - currentY) + { + yStep = max(height, yStep); + currentX += width; + } + else + return false; + } + else + { + currentX = 0; + currentY += yStep; + yStep = 0; + + if (width <= m_width - currentX) + if (height <= m_height - currentY) + { + yStep = max(height, yStep); + currentX += width; + } + else + return false; + } + } + + return true; + } + bool Packer::isPacked(handle_t handle) { return m_rects.find(handle) != m_rects.end(); diff --git a/geometry/packer.hpp b/geometry/packer.hpp index e768913974..28c7652da6 100644 --- a/geometry/packer.hpp +++ b/geometry/packer.hpp @@ -77,6 +77,9 @@ namespace m2 /// Does we have room to pack another rectangle? bool hasRoom(unsigned width, unsigned height) const; + /// Does we have room to pack a sequence of rectangles? + bool hasRoom(m2::PointU const * sizes, size_t cnt) const; + /// is the handle present on the texture. bool isPacked(handle_t handle); |