[Libreoffice-commits] core.git: Branch 'libreoffice-6-0' - sw/qa sw/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Tue Sep 18 09:03:48 UTC 2018
sw/qa/extras/layout/data/tdf119875.odt |binary
sw/qa/extras/layout/layout.cxx | 15 +++++++++++++++
sw/source/core/layout/sectfrm.cxx | 28 ++++++++++++++++++++++++----
3 files changed, 39 insertions(+), 4 deletions(-)
New commits:
commit e850b5a1283485273b91135df15cae7faaac3861
Author: Miklos Vajna <vmiklos at collabora.co.uk>
AuthorDate: Fri Sep 14 17:38:32 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Sep 18 11:03:27 2018 +0200
tdf#119875 sw: fix invalid pos of frame after 0-sized section with laycache
The interesting part of the layout of page 2 is:
- frame #40 is a section frame with a text frame which is in a list
("A")
- frame #48 is a section frame after that, with the same top=19213
Given that frame #40 has height > 0, they overlap when the page is
rendered. What happens is:
- frame #40 grows
- there are other section frames between #40 and #48 in-between, but
they don't have an SwSection
- these frames are skipped
- then the position of #48 is invalidated
So the next time we calculate the position of #48, we look the last
skipped (previous) section frame (which still has top=19213, since its
position was not invalidated above), and since its height is 0, we
conclude that our current top=19213 is valid after all.
This is like this since commit 84a3db80b4fd66c6854b3135b5f69b61fd828e62
(initial import, 2000-09-18), so leave the code there that invalidates
not only the next frame, but all the way down to the first
non-SwSection-less-SwSectionFrame. But instead of just invalidating the
last frame, invalidate the in-between SwSection-less-SwSectionFrames as
well.
In practice this did not cause a problem in case the document has no
layout cache. If it does, then the frames are created on pages hinted by
the cache, then later moved to their final place. In practice this bug
was visible only in this later case. (I.e. such a layout cache can be
only created if the machine that saved the document last time does not
have the fonts needed by the document installed; and then the document
is opened on an other machine which has those fonts.)
(cherry picked from commit b5937112d4035fb9ffb472e1bf36567d9c78c820)
Conflicts:
sw/qa/extras/layout/layout.cxx
Change-Id: I02ae9f63d0b4b5e9d014df53ed2cf21a04b15090
Reviewed-on: https://gerrit.libreoffice.org/60658
Tested-by: Jenkins
Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>
diff --git a/sw/qa/extras/layout/data/tdf119875.odt b/sw/qa/extras/layout/data/tdf119875.odt
new file mode 100644
index 000000000000..6f579546e312
Binary files /dev/null and b/sw/qa/extras/layout/data/tdf119875.odt differ
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index d7a25e95886c..76b88d08af8c 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -20,12 +20,14 @@ public:
void testTdf116925();
void testTdf117028();
void testTdf118058();
+ void testTdf119875();
CPPUNIT_TEST_SUITE(SwLayoutWriter);
CPPUNIT_TEST(testTdf116830);
CPPUNIT_TEST(testTdf116925);
CPPUNIT_TEST(testTdf117028);
CPPUNIT_TEST(testTdf118058);
+ CPPUNIT_TEST(testTdf119875);
CPPUNIT_TEST_SUITE_END();
private:
@@ -117,6 +119,19 @@ void SwLayoutWriter::testTdf118058()
pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
}
+void SwLayoutWriter::testTdf119875()
+{
+ createDoc("tdf119875.odt");
+ xmlDocPtr pXmlDoc = parseLayoutDump();
+ sal_Int32 nFirstTop
+ = getXPath(pXmlDoc, "/root/page[2]/body/section[1]/infos/bounds", "top").toInt32();
+ sal_Int32 nSecondTop
+ = getXPath(pXmlDoc, "/root/page[2]/body/section[2]/infos/bounds", "top").toInt32();
+ // The first section had the same top value as the second one, so they
+ // overlapped.
+ CPPUNIT_ASSERT_LESS(nSecondTop, nFirstTop);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwLayoutWriter);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index 3790c92a199d..f456da19b54d 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -44,6 +44,21 @@
#include <flyfrms.hxx>
#include <sortedobjs.hxx>
+namespace
+{
+/**
+ * Performs the correct type of position invalidation depending on if we're in
+ * CalcContent().
+ */
+void InvalidateFramePos(SwFrame* pFrame, bool bInCalcContent)
+{
+ if (bInCalcContent)
+ pFrame->InvalidatePos_();
+ else
+ pFrame->InvalidatePos();
+}
+}
+
SwSectionFrame::SwSectionFrame( SwSection &rSect, SwFrame* pSib )
: SwLayoutFrame( rSect.GetFormat(), pSib )
, SwFlowFrame( static_cast<SwFrame&>(*this) )
@@ -2121,15 +2136,20 @@ SwTwips SwSectionFrame::Grow_( SwTwips nDist, bool bTst )
}
if( GetNext() )
{
+ // Own height changed, need to invalidate the position of
+ // next frames.
SwFrame *pFrame = GetNext();
while( pFrame && pFrame->IsSctFrame() && !static_cast<SwSectionFrame*>(pFrame)->GetSection() )
+ {
+ // Invalidate all in-between frames, otherwise position
+ // calculation (which only looks back to one relative
+ // frame) will have an incorrect result.
+ InvalidateFramePos(pFrame, bInCalcContent);
pFrame = pFrame->GetNext();
+ }
if( pFrame )
{
- if( bInCalcContent )
- pFrame->InvalidatePos_();
- else
- pFrame->InvalidatePos();
+ InvalidateFramePos(pFrame, bInCalcContent);
}
}
// #i28701# - Due to the new object positioning
More information about the Libreoffice-commits
mailing list