From 8b09892ed6310756bc4d76d62d6233900e6e26b0 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Fri, 28 Feb 2020 18:39:41 +0100 Subject: sw: layout: fix wrongly positioned table rows in --convert-to pdf If the document is loaded via UI, the first layout action is triggered from resizing the Window and the table is positioned properly on the first try. If the document is loaded via --convert-to, only getRendererCount() formats the content of the table, and the table is positioned 3 times but its first row is only positioned 2 times. The first time the table id="56" is positioned, the previous table id="50" is at correct Y 5988 but its content isn't formatted yet, so its height is almost 0 (just table's border etc.), so the table ends up at y = 6271. The second time the table id="56" is positioned, the previous table id="50" is at wrong Y 7937 and its content is valid, so its height is 1203, so the table ends up at y = 9140. The third time the table id="56" is positioned, the previous table id="50" is at correct Y 5988 and its content is valid, so its height is 1203, so the table ends up at correct y = 7191 ... but the first SwRowFrame remains at y = 9140 and is never repositioned, and the lower rows are cut off (invisible). Change SwTabFrame::MakeAll() so that a MakePos() that moves the table itself does not leave the first SwRowFrame's position valid, which should ensure that all rows are repositioned. (And work around C++'s particularly unhelpful type system.) This happens since the earliest version checked, OOo 3.3. Change-Id: If3dfe1ffcb81e03aa4f4bffcf33a237f0c92bd08 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89735 Tested-by: Jenkins Reviewed-by: Michael Stahl --- sw/source/core/inc/frame.hxx | 2 ++ sw/source/core/layout/tabfrm.cxx | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index ec78d7b40188..0f1b1dd07e6c 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -129,6 +129,8 @@ namespace drawinglayer { namespace attribute { class SW_DLLPUBLIC SwFrameAreaDefinition { private: + friend void FriendHackInvalidateRowFrame(SwFrameAreaDefinition &); + // The absolute position and size of the SwFrame in the document. // This values are set by the layouter implementations SwRect maFrameArea; diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index a3449bfaad1e..ff891826b58d 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -1770,6 +1770,14 @@ namespace { return bRet; } } + +// extern because static can't be friend +void FriendHackInvalidateRowFrame(SwFrameAreaDefinition & rRowFrame) +{ + // hilariously static_cast(GetLower()) would not require friend declaration, but it's UB... + rRowFrame.setFrameAreaPositionValid(false); +} + void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) { if ( IsJoinLocked() || StackHack::IsLocked() || StackHack::Count() > 50 ) @@ -1961,6 +1969,10 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) { m_bCalcLowers = true; } + if (GetLower()) + { // it's possible that the rows already have valid pos - but it is surely wrong if the table's pos changed! + FriendHackInvalidateRowFrame(*GetLower()); + } } //We need to know the height of the first row, because the master needs -- cgit