sw/qa/extras/layout/data/tdf69647_images.odt |binary sw/qa/extras/layout/data/tdf69647_text.docx |binary sw/qa/extras/layout/layout.cxx | 19 +++++++++++++++- sw/source/core/text/itrform2.cxx | 23 +++++++++++--------- sw/source/core/text/porlay.cxx | 31 +++++++++++++++++---------- sw/source/core/text/porlay.hxx | 7 ++++++ sw/source/core/text/possiz.hxx | 6 +++-- 7 files changed, 62 insertions(+), 24 deletions(-)
New commits: commit d336e6c26012255015d3fc0caf8e7fafe14bd8f2 Author: Daniel Arato (NISZ) <arato.dan...@nisz.hu> AuthorDate: Mon Aug 24 11:05:17 2020 +0200 Commit: László Németh <nem...@numbertext.org> CommitDate: Fri Aug 28 13:13:58 2020 +0200 tdf#69647 sw layout: fix line spacing with inline pictures Line height is now based on (the biggest) font size in the line rather than on the size of the tallest object there, according to ODF and like MSO does. Note: handling of first paragraph line is still different. Co-authored-by: Attila Bánhegyi (NISZ) Change-Id: I6cebea7dbdedd21ea173a0a867434525e7b86337 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101272 Tested-by: László Németh <nem...@numbertext.org> Reviewed-by: László Németh <nem...@numbertext.org> diff --git a/sw/qa/extras/layout/data/tdf69647_images.odt b/sw/qa/extras/layout/data/tdf69647_images.odt new file mode 100644 index 000000000000..e4f7fbe8039a Binary files /dev/null and b/sw/qa/extras/layout/data/tdf69647_images.odt differ diff --git a/sw/qa/extras/layout/data/tdf69647_text.docx b/sw/qa/extras/layout/data/tdf69647_text.docx new file mode 100644 index 000000000000..587089ff29cf Binary files /dev/null and b/sw/qa/extras/layout/data/tdf69647_text.docx differ diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index 438a60bc633a..5e8f2d89eed4 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -2076,6 +2076,22 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineSections) CheckRedlineSectionsHidden(); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TDF69647_images) +{ + createDoc("tdf69647_images.odt"); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of pages does not match!", 2, getPages()); +} + +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TDF69647_text) +{ + createDoc("tdf69647_text.docx"); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of pages does not match!", 2, getPages()); +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineTables) { createDoc("redline_table.fodt"); @@ -3756,7 +3772,8 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf123651) xmlDocUniquePtr pXmlDoc = parseLayoutDump(); // Without the accompanying fix in place, this test would have failed with 'Expected: 7639; // Actual: 12926'. The shape was below the second "Lorem ipsum" text, not above it. - assertXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds", "top", "7639"); + const sal_Int32 nTopValue = getXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds", "top").toInt32(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7639, nTopValue, 10); } CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf116501) diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 577b4d8ecbbc..a78d4f730e7f 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -324,7 +324,7 @@ void SwTextFormatter::InsertPortion( SwTextFormatInfo &rInf, // Adjust maxima if( m_pCurr->Height() < pPor->Height() ) - m_pCurr->Height( pPor->Height() ); + m_pCurr->Height( pPor->Height(), pPor->IsTextPortion() ); if( m_pCurr->GetAscent() < pPor->GetAscent() ) m_pCurr->SetAscent( pPor->GetAscent() ); @@ -776,7 +776,7 @@ void SwTextFormatter::CalcAscent( SwTextFormatInfo &rInf, SwLinePortion *pPor ) // height (example: n758883.docx) SwLinePortion const*const pLast = rInf.GetLast(); assert(pLast); - pPor->Height( pLast->Height() ); + pPor->Height( pLast->Height(), false ); pPor->SetAscent( pLast->GetAscent() ); } else @@ -1523,7 +1523,7 @@ SwLinePortion *SwTextFormatter::NewPortion( SwTextFormatInfo &rInf ) if( !m_pCurr->Height() ) { OSL_ENSURE( m_pCurr->Height(), "SwTextFormatter::NewPortion: limbo dance" ); - m_pCurr->Height( pPor->Height() ); + m_pCurr->Height( pPor->Height(), false ); m_pCurr->SetAscent( pPor->GetAscent() ); } @@ -1613,7 +1613,7 @@ TextFrameIndex SwTextFormatter::FormatLine(TextFrameIndex const nStartPos) if( GetInfo().IsStop() ) { m_pCurr->SetLen(TextFrameIndex(0)); - m_pCurr->Height( GetFrameRstHeight() + 1 ); + m_pCurr->Height( GetFrameRstHeight() + 1, false ); m_pCurr->SetRealHeight( GetFrameRstHeight() + 1 ); m_pCurr->Width(0); m_pCurr->Truncate(); @@ -1770,7 +1770,7 @@ void SwTextFormatter::CalcRealHeight( bool bNewLine ) ( nLineHeight - m_pCurr->Height() + nRubyHeight ) / 2 : ( nLineHeight - m_pCurr->Height() - nRubyHeight ) / 2 ); - m_pCurr->Height( nLineHeight ); + m_pCurr->Height( nLineHeight, false ); m_pCurr->SetAscent( nAsc ); m_pInf->GetParaPortion()->SetFixLineHeight(); @@ -1831,7 +1831,7 @@ void SwTextFormatter::CalcRealHeight( bool bNewLine ) pCurr->SetClipping( true ); #endif m_pCurr->SetAscent( nAsc ); - m_pCurr->Height( nLineHeight ); + m_pCurr->Height( nLineHeight, false ); m_pInf->GetParaPortion()->SetFixLineHeight(); } } @@ -1849,7 +1849,7 @@ void SwTextFormatter::CalcRealHeight( bool bNewLine ) if( nAsc < m_pCurr->GetAscent() || nLineHeight - nAsc < m_pCurr->Height() - m_pCurr->GetAscent() ) m_pCurr->SetClipping( true ); - m_pCurr->Height( nLineHeight ); + m_pCurr->Height( nLineHeight, false ); m_pCurr->SetAscent( nAsc ); m_pInf->GetParaPortion()->SetFixLineHeight(); } @@ -1871,10 +1871,13 @@ void SwTextFormatter::CalcRealHeight( bool bNewLine ) if( nTmp < 50 ) nTmp = nTmp ? 50 : 100; - nTmp *= nLineHeight; + // extend line height by (nPropLineSpace - 100) percent of the font height + nTmp -= 100; + nTmp *= m_pCurr->GetTextHeight(); nTmp /= 100; - if( !nTmp ) - ++nTmp; + nTmp += nLineHeight; + if (nTmp < 1) + nTmp = 1; nLineHeight = static_cast<sal_uInt16>(nTmp); break; } diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx index 5a023427fee4..cb619ecd4dcc 100644 --- a/sw/source/core/text/porlay.cxx +++ b/sw/source/core/text/porlay.cxx @@ -193,6 +193,13 @@ void SwLineLayout::DeleteNext() delete a; } +void SwLineLayout::Height(const sal_uInt16 nNew, const bool bText) +{ + SwPosSize::Height(nNew); + if (bText) + m_nTextHeight = nNew; +} + // class SwLineLayout: This is the layout of a single line, which is made // up of its dimension, the character count and the word spacing in the line. // Line objects are managed in an own pool, in order to store them continuously @@ -382,7 +389,7 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, SwTextFormatInfo &rInf ) if( !pPos->GetNextPortion() ) { if( !Height() ) - Height( pPos->Height() ); + Height( pPos->Height(), false ); if( !GetAscent() ) SetAscent( pPos->GetAscent() ); } @@ -469,7 +476,7 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, SwTextFormatInfo &rInf ) if( nTmp > nPosHeight ) nPosHeight = nTmp; } - Height( nPosHeight ); + Height( nPosHeight, false ); nAscent = nPosAscent; nMaxDescent = nPosHeight - nPosAscent; } @@ -479,12 +486,12 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, SwTextFormatInfo &rInf ) if( Height() < nPosHeight ) { // Height is set to 0 when Init() is called. - if (bIgnoreBlanksAndTabsForLineHeightCalculation && pPos->GetWhichPor() == PortionType::FlyCnt) + if (bIgnoreBlanksAndTabsForLineHeightCalculation && pPos->IsFlyCntPortion()) // Compat flag set: take the line height, if it's larger. - Height(std::max(nPosHeight, nLineHeight)); + Height(std::max(nPosHeight, nLineHeight), false); else // Just care about the portion height. - Height(nPosHeight); + Height(nPosHeight, pPos->IsTextPortion()); } SwFlyCntPortion* pAsFly(nullptr); if(pPos->IsFlyCntPortion()) @@ -549,12 +556,12 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, SwTextFormatInfo &rInf ) { nAscent = nFlyAscent; if( nFlyDescent > nFlyHeight - nFlyAscent ) - Height( nFlyHeight + nFlyDescent ); + Height( nFlyHeight + nFlyDescent, false ); else - Height( nFlyHeight ); + Height( nFlyHeight, false ); } else if( nMaxDescent > Height() - nAscent ) - Height( nMaxDescent + nAscent ); + Height( nMaxDescent + nAscent, false ); if( bOnlyPostIts && !( bHasBlankPortion && bHasOnlyBlankPortions ) ) { @@ -582,7 +589,7 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, SwTextFormatInfo &rInf ) sal_uInt16 nTmpHeight = Height(); rLine.GetAttrHandler().GetDefaultAscentAndHeight( rInf.GetVsh(), *rInf.GetOut(), nTmpAscent, nTmpHeight ); SetAscent( nTmpAscent ); - Height( nTmpHeight ); + Height( nTmpHeight, false ); } // Robust: @@ -660,7 +667,9 @@ void SwLineLayout::ResetFlags() } SwLineLayout::SwLineLayout() - : m_pNext( nullptr ), m_nRealHeight( 0 ), + : m_pNext( nullptr ), + m_nRealHeight( 0 ), + m_nTextHeight( 0 ), m_bUnderscore( false ) { ResetFlags(); @@ -2408,7 +2417,7 @@ const SwDropPortion *SwParaPortion::FindDropPortion() const void SwLineLayout::Init( SwLinePortion* pNextPortion ) { - Height( 0 ); + Height( 0, false ); Width( 0 ); SetLen(TextFrameIndex(0)); SetAscent( 0 ); diff --git a/sw/source/core/text/porlay.hxx b/sw/source/core/text/porlay.hxx index ea82202470c1..2836ffe991d3 100644 --- a/sw/source/core/text/porlay.hxx +++ b/sw/source/core/text/porlay.hxx @@ -82,6 +82,7 @@ private: std::unique_ptr<std::vector<long>> m_pLLSpaceAdd; // Used for justified alignment std::unique_ptr<std::deque<sal_uInt16>> m_pKanaComp; // Used for Kana compression sal_uInt16 m_nRealHeight; // The height resulting from line spacing and register + sal_uInt16 m_nTextHeight; // The max height of all non-FlyCnt portions in this Line bool m_bFormatAdj : 1; bool m_bDummy : 1; bool m_bEndHyph : 1; @@ -100,6 +101,10 @@ private: void DeleteNext(); public: + // From SwPosSize + using SwPosSize::Height; + virtual void Height(const sal_uInt16 nNew, const bool bText = true) override; + // From SwLinePortion virtual SwLinePortion *Insert( SwLinePortion *pPortion ) override; virtual SwLinePortion *Append( SwLinePortion *pPortion ) override; @@ -152,6 +157,8 @@ public: void SetRealHeight( sal_uInt16 nNew ) { m_nRealHeight = nNew; } sal_uInt16 GetRealHeight() const { return m_nRealHeight; } + sal_uInt16 GetTextHeight() const { return m_nTextHeight; } + // Creates the glue chain for short lines SwMarginPortion *CalcLeftMargin(); diff --git a/sw/source/core/text/possiz.hxx b/sw/source/core/text/possiz.hxx index eaad3597f460..c2ae3aabe2e6 100644 --- a/sw/source/core/text/possiz.hxx +++ b/sw/source/core/text/possiz.hxx @@ -39,10 +39,12 @@ public: { } #if defined(__COVERITY__) - ~SwPosSize() COVERITY_NOEXCEPT_FALSE {} + virtual ~SwPosSize() COVERITY_NOEXCEPT_FALSE {} +#else + virtual ~SwPosSize() {} #endif sal_uInt16 Height() const { return nHeight; } - void Height( const sal_uInt16 nNew ) { nHeight = nNew; } + virtual void Height(const sal_uInt16 nNew, const bool = true) { nHeight = nNew; } sal_uInt16 Width() const { return nWidth; } void Width( const sal_uInt16 nNew ) { nWidth = nNew; } Size SvLSize() const { return Size( nWidth, nHeight ); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits