sc/qa/unit/tiledrendering/tiledrendering.cxx | 42 +++++++++++++++++++++++++-- sc/source/ui/view/tabview.cxx | 8 +++-- 2 files changed, 44 insertions(+), 6 deletions(-)
New commits: commit 6ece9bae17307644774e53ef15b150e626239d9f Author: Caolán McNamara <[email protected]> AuthorDate: Mon Jan 22 17:30:27 2024 +0000 Commit: Miklos Vajna <[email protected]> CommitDate: Tue Jan 23 14:44:59 2024 +0100 produce non-overlapping invalidation rects on extending calc tiled area the intent is to create two rects, one for the area extended to the right and another for the area extended to the bottom, but they overlap so they end up merged and a single rect of the entire sheet is created which is defeats the original intention. Change-Id: Ie5b46ee1a36780d9f7a90ed11ebfd1264c17477a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162412 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx index 8b092c49c0d2..7ec0d730180d 100644 --- a/sc/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx @@ -177,6 +177,7 @@ public: void testCellMinimalInvalidations(); void testCellInvalidationDocWithExistingZoom(); void testOptimalRowHeight(); + void testExtendedAreasDontOverlap(); CPPUNIT_TEST_SUITE(ScTiledRenderingTest); CPPUNIT_TEST(testRowColumnHeaders); @@ -255,6 +256,7 @@ public: CPPUNIT_TEST(testCellMinimalInvalidations); CPPUNIT_TEST(testCellInvalidationDocWithExistingZoom); CPPUNIT_TEST(testOptimalRowHeight); + CPPUNIT_TEST(testExtendedAreasDontOverlap); CPPUNIT_TEST_SUITE_END(); private: @@ -2107,7 +2109,7 @@ void ScTiledRenderingTest::testGetRowColumnHeadersInvalidation() Scheduler::ProcessEventsToIdle(); CPPUNIT_ASSERT(aView1.m_bInvalidateTiles); CPPUNIT_ASSERT_EQUAL(size_t(1), aView1.m_aInvalidations.size()); - CPPUNIT_ASSERT_EQUAL(tools::Rectangle(26775, 0, 49725, 13005), aView1.m_aInvalidations[0]); + CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(26775, 0), Size(22950, 13005)), aView1.m_aInvalidations[0]); // Extend area top-to-bottom aView1.m_bInvalidateTiles = false; @@ -2118,7 +2120,7 @@ void ScTiledRenderingTest::testGetRowColumnHeadersInvalidation() Scheduler::ProcessEventsToIdle(); CPPUNIT_ASSERT(aView1.m_bInvalidateTiles); CPPUNIT_ASSERT_EQUAL(size_t(1), aView1.m_aInvalidations.size()); - CPPUNIT_ASSERT_EQUAL(tools::Rectangle(0, 13005, 49725, 19380), aView1.m_aInvalidations[0]); + CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(0, 13005), Size(49725, 6375)), aView1.m_aInvalidations[0]); // Extend area left-to-right aView1.m_bInvalidateTiles = false; @@ -2129,7 +2131,7 @@ void ScTiledRenderingTest::testGetRowColumnHeadersInvalidation() Scheduler::ProcessEventsToIdle(); CPPUNIT_ASSERT(aView1.m_bInvalidateTiles); CPPUNIT_ASSERT_EQUAL(size_t(1), aView1.m_aInvalidations.size()); - CPPUNIT_ASSERT_EQUAL(tools::Rectangle(49725, 0, 75225, 19380), aView1.m_aInvalidations[0]); + CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(49725, 0), Size(25500, 19380)), aView1.m_aInvalidations[0]); } void ScTiledRenderingTest::testJumpHorizontallyInvalidation() @@ -3917,6 +3919,40 @@ void ScTiledRenderingTest::testOptimalRowHeight() CPPUNIT_ASSERT_EQUAL_MESSAGE("After setOptimalHeight: Row#306 height is invalid!", sal_uInt16(504), pDoc->GetRowHeight(nRow, 0)); } +// if we extend the tiled area to the right and bottom we want two resulting area +// that don't overlap. If they overlap that typically creates an unnecessary full +// screen invalidation. +void ScTiledRenderingTest::testExtendedAreasDontOverlap() +{ + ScModelObj* pModelObj = createDoc("empty.ods"); + ScTabViewShell* pView = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()); + CPPUNIT_ASSERT(pModelObj && pView); + + Scheduler::ProcessEventsToIdle(); + + // register to track View #1 invalidations + ViewCallback aView1; + + // extend to the right and bottom + pModelObj->setClientVisibleArea(tools::Rectangle(0, 0, 39750, 12780)); + + Scheduler::ProcessEventsToIdle(); + + // we should get two rectangles for the two new areas + CPPUNIT_ASSERT_EQUAL(size_t(2), aView1.m_aInvalidations.size()); + + // And those should not overlap, otherwise they would merge to form + // a mega rectangle, which defeats the purpose of creating two rects + // in the first place. + CPPUNIT_ASSERT_MESSAGE("Invalidations should not overlap", + !aView1.m_aInvalidations[0].Overlaps(aView1.m_aInvalidations[1])); + + // But they should be adjacent + CPPUNIT_ASSERT_EQUAL(aView1.m_aInvalidations[0].Top() + + aView1.m_aInvalidations[0].GetSize().Height(), + aView1.m_aInvalidations[1].Top()); +} + } CPPUNIT_TEST_SUITE_REGISTRATION(ScTiledRenderingTest); diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index 05e08345075a..94892ca70c63 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -2689,10 +2689,12 @@ void lcl_ExtendTiledDimension(bool bColumn, const SCCOLROW nEnd, const SCCOLROW } // New area extended to the right/bottom of the sheet after last col/row + tools::Rectangle aNewArea(Point(0, 0), aNewSize); // excluding overlapping area with aNewArea - tools::Rectangle aNewArea = bColumn ? - tools::Rectangle(aOldSize.getWidth(), 0, aNewSize.getWidth(), aNewSize.getHeight()): - tools::Rectangle(0, aOldSize.getHeight(), aNewSize.getWidth(), aNewSize.getHeight()); + if (bColumn) + aNewArea.SetLeft(aOldSize.getWidth()); + else + aNewArea.SetTop(aOldSize.getHeight()); // Only invalidate if spreadsheet has extended to the right or bottom if ((bColumn && aNewArea.getOpenWidth()) || (!bColumn && aNewArea.getOpenHeight()))
