sw/qa/core/layout/data/fly-rel-width-rounding.odt |binary
 sw/qa/core/layout/fly.cxx                         |   25 ++++++++++++++++++++++
 sw/source/core/layout/fly.cxx                     |    5 ++--
 xmloff/qa/unit/text.cxx                           |    4 +--
 4 files changed, 30 insertions(+), 4 deletions(-)

New commits:
commit 991341f9f69fded9c9573d91b2d65fc6a37b3132
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed May 22 08:47:32 2024 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu May 23 09:20:46 2024 +0200

    Related: tdf#145972 sw images: fix rounding error in relative size 
calculation
    
    Open the bugdoc, see that the image is roughly half of the page width,
    right click, properties, UI shows that the width of the image is 5% of
    the width of the entire page. This only happens if tools -> options ->
    writer -> general sets the UI units to points, the default cm case is
    fine.
    
    This went wrong with commit 9e8712ed6f9fb5dbd971e352a5709bd45fadc74f (sw
    image dialog: fix fallback width/height for images with relative sizes,
    2022-03-17), because the layout size started to matter more after that
    commit. This lead to the nWidth !=
    m_xWidthED->get_value(FieldUnit::TWIP) check in SwFramePage::Init() to
    be true, because 11906 * 0.48 is 5714.88, so you got 5714 in the layout,
    but got 5715 with rounding in SwFramePage::Reset() (which tries to calc
    the page width based on the 48% and the fly width). And once we had that
    mismatch, we went down the wrong path.
    
    Fix the problem by using rtl::math::round() in SwFlyFrame::CalcRel(), so
    the relative width twips value is 5715 everywhere: once we have
    consisteny, the UI value is correct, too.
    
    Note that the original bugdoc needs more fixing, this just fixes the
    bugdoc where KeepRatio is false.
    
    Change-Id: I1e8782c95a0cf9d97375c36d41134735c01f3e46
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167916
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167926
    (cherry picked from commit 3046bd0e30406d37813ce3eaa65f71f5ed10ab13)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167980
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/sw/qa/core/layout/data/fly-rel-width-rounding.odt 
b/sw/qa/core/layout/data/fly-rel-width-rounding.odt
new file mode 100644
index 000000000000..b70b9e51a917
Binary files /dev/null and b/sw/qa/core/layout/data/fly-rel-width-rounding.odt 
differ
diff --git a/sw/qa/core/layout/fly.cxx b/sw/qa/core/layout/fly.cxx
index 47cfb40fa6e7..81df20af3b35 100644
--- a/sw/qa/core/layout/fly.cxx
+++ b/sw/qa/core/layout/fly.cxx
@@ -86,6 +86,31 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyNegativeHeight)
         }
     }
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testFlyRelWithRounding)
+{
+    // Given a document where page width is 21.001cm (11906 twips), and the 
image width is 48% of
+    // the page width:
+    createSwDoc("fly-rel-width-rounding.odt");
+
+    // When laying out that document:
+    SwDoc* pDoc = getSwDoc();
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+
+    // Then make sure that we calculate the width of the fly correctly:
+    auto pPage = pLayout->GetLower()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage->GetSortedObjs());
+    SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPageObjs.size());
+    auto pFly = rPageObjs[0]->DynCastFlyFrame()->DynCastFlyAtContentFrame();
+    CPPUNIT_ASSERT(pFly);
+    tools::Long nFlyWidth = pFly->getFrameArea().Width();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 5715
+    // - Actual  : 5714
+    // i.e. 5714.88 was truncated, not rounded.
+    CPPUNIT_ASSERT_EQUAL(static_cast<tools::Long>(5715), nFlyWidth);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index b454bd95917f..fd95ce192cf7 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -70,6 +70,7 @@
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <osl/diagnose.h>
 #include <o3tl/string_view.hxx>
+#include <rtl/math.hxx>
 
 #include <wrtsh.hxx>
 #include <view.hxx>
@@ -2845,9 +2846,9 @@ Size SwFlyFrame::CalcRel( const SwFormatFrameSize &rSz ) 
const
         }
 
         if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 
SwFormatFrameSize::SYNCED )
-            aRet.setWidth( nRelWidth * rSz.GetWidthPercent() / 100 );
+            aRet.setWidth(rtl::math::round(double(nRelWidth) * 
rSz.GetWidthPercent() / 100));
         if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 
SwFormatFrameSize::SYNCED )
-            aRet.setHeight( nRelHeight * rSz.GetHeightPercent() / 100 );
+            aRet.setHeight(rtl::math::round(double(nRelHeight) * 
rSz.GetHeightPercent() / 100));
 
         if ( rSz.GetHeight() && rSz.GetWidthPercent() == 
SwFormatFrameSize::SYNCED )
         {
diff --git a/xmloff/qa/unit/text.cxx b/xmloff/qa/unit/text.cxx
index e6433b2b70f9..2da04387d707 100644
--- a/xmloff/qa/unit/text.cxx
+++ b/xmloff/qa/unit/text.cxx
@@ -505,11 +505,11 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testRelativeWidth)
 
     xmlDocUniquePtr pXmlDoc = parseExport("content.xml");
     // Without the accompanying fix in place, this failed with:
-    // - Expected: 3.1492in (8cm)
+    // - Expected: 3.15in (8cm)
     // - Actual  : 0.0161in (0.04 cm)
     // i.e. the fallback width value wasn't the expected half of the body 
frame width, but a smaller
     // value.
-    assertXPath(pXmlDoc, "//draw:frame"_ostr, "width"_ostr, "3.1492in");
+    assertXPath(pXmlDoc, "//draw:frame"_ostr, "width"_ostr, "3.15in");
 }
 
 CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testScaleWidthAndHeight)

Reply via email to