From 7c926242fb2ae81c67032042eaba503f27c13865 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 19 Sep 2022 16:08:25 +0200 Subject: sw HTML import: fix height of images when it is missing and width is relative This is similar to commit 456abae730a787693c3ad98f7e57eba5f6163a76 (sw HTML import: fix height of OLE objs when it is missing and width is relative, 2022-09-06), but this is for images, while that was for OLE objects. The idea is still that in case only axis is specified in the HTML and that's a relative percentage, then the ratio should be taken from the bitmap and it should be kept. Change-Id: I36184ff6531bff2775013462cd8cc711e1a249c5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140178 Reviewed-by: Miklos Vajna Tested-by: Jenkins (cherry picked from commit 2e6144fc350fd94f8e66be5a9007c7f06c0213e0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140163 Reviewed-by: Michael Stahl --- .../html/data/relative-keep-aspect-image.xhtml | 3 ++ sw/qa/filter/html/html.cxx | 27 ++++++++++++ sw/source/filter/html/htmlgrin.cxx | 51 +++++++++++++++++----- 3 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 sw/qa/filter/html/data/relative-keep-aspect-image.xhtml diff --git a/sw/qa/filter/html/data/relative-keep-aspect-image.xhtml b/sw/qa/filter/html/data/relative-keep-aspect-image.xhtml new file mode 100644 index 000000000000..96b8d14047bb --- /dev/null +++ b/sw/qa/filter/html/data/relative-keep-aspect-image.xhtml @@ -0,0 +1,3 @@ + + + diff --git a/sw/qa/filter/html/html.cxx b/sw/qa/filter/html/html.cxx index 6739341d2566..973feeec2951 100644 --- a/sw/qa/filter/html/html.cxx +++ b/sw/qa/filter/html/html.cxx @@ -78,6 +78,33 @@ CPPUNIT_TEST_FIXTURE(Test, testRelativeKeepAspect) CPPUNIT_ASSERT_EQUAL(static_cast(SwFormatFrameSize::SYNCED), static_cast(rSize.GetHeightPercent())); } + +CPPUNIT_TEST_FIXTURE(Test, testRelativeKeepAspectImage) +{ + // Given a document with an image, width set to 100%, height is not set: + OUString aURL + = m_directories.getURLFromSrc(DATA_DIRECTORY) + "relative-keep-aspect-image.xhtml"; + uno::Sequence aLoadArgs = { + comphelper::makePropertyValue("FilterName", OUString("HTML (StarWriter)")), + comphelper::makePropertyValue("FilterOptions", OUString("xhtmlns=reqif-xhtml")), + }; + + // When loading that file: + mxComponent = loadFromDesktop(aURL, OUString(), aLoadArgs); + + // Then make sure that the aspect ratio of the image is kept: + auto pTextDocument = dynamic_cast(mxComponent.get()); + SwDoc* pDoc = pTextDocument->GetDocShell()->GetDoc(); + const SwFrameFormats& rFormats = *pDoc->GetSpzFrameFormats(); + const SwFrameFormat* pFormat = rFormats[0]; + const SwFormatFrameSize& rSize = pFormat->GetFrameSize(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 255 + // - Actual : 0 + // i.e. the height had a fixed value, not "keep aspect". + CPPUNIT_ASSERT_EQUAL(static_cast(SwFormatFrameSize::SYNCED), + static_cast(rSize.GetHeightPercent())); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/html/htmlgrin.cxx b/sw/source/filter/html/htmlgrin.cxx index 5a11fa9c6da6..cbf3727cd775 100644 --- a/sw/source/filter/html/htmlgrin.cxx +++ b/sw/source/filter/html/htmlgrin.cxx @@ -527,10 +527,30 @@ IMAGE_SETEVENT: if (!bHeightProvided) nHeight = aPixelSize.Height(); // tdf#142781 - calculate the width/height keeping the aspect ratio - if (!bPercentWidth && bWidthProvided && !bHeightProvided && aPixelSize.Width()) - nHeight = nWidth * aPixelSize.Height() / aPixelSize.Width(); - else if (!bPercentHeight && !bWidthProvided && bHeightProvided && aPixelSize.Height()) - nWidth = nHeight * aPixelSize.Width() / aPixelSize.Height(); + if (bWidthProvided && !bHeightProvided && aPixelSize.Width()) + { + if (bPercentWidth) + { + nHeight = SwFormatFrameSize::SYNCED; + bPercentHeight = true; + } + else + { + nHeight = nWidth * aPixelSize.Height() / aPixelSize.Width(); + } + } + else if (!bWidthProvided && bHeightProvided && aPixelSize.Height()) + { + if (bPercentHeight) + { + nWidth = SwFormatFrameSize::SYNCED; + bPercentWidth = true; + } + else + { + nWidth = nHeight * aPixelSize.Width() / aPixelSize.Height(); + } + } } SfxItemSet aItemSet( m_xDoc->GetAttrPool(), m_pCSS1Parser->GetWhichMap() ); @@ -648,7 +668,11 @@ IMAGE_SETEVENT: // bPercentWidth / bPercentHeight means we have a percent size. If that's not the case and we have no // size from nWidth / nHeight either, then inspect the image header. - if ((!bPercentWidth && !nWidth) && (!bPercentHeight && !nHeight) && !m_bFuzzing && allowAccessLink(*m_xDoc)) + bool bRelWidthScale = bPercentWidth && nWidth == SwFormatFrameSize::SYNCED; + bool bNeedWidth = (!bPercentWidth && !nWidth) || bRelWidthScale; + bool bRelHeightScale = bPercentHeight && nHeight == SwFormatFrameSize::SYNCED; + bool bNeedHeight = (!bPercentHeight && !nHeight) || bRelHeightScale; + if ((bNeedWidth || bNeedHeight) && !m_bFuzzing && allowAccessLink(*m_xDoc)) { GraphicDescriptor aDescriptor(aGraphicURL); if (aDescriptor.Detect(/*bExtendedInfo=*/true)) @@ -657,12 +681,18 @@ IMAGE_SETEVENT: // HTML_DFLT_IMG_WIDTH/HEIGHT. aTwipSz = Application::GetDefaultDevice()->PixelToLogic(aDescriptor.GetSizePixel(), MapMode(MapUnit::MapTwip)); - nWidth = aTwipSz.getWidth(); - nHeight = aTwipSz.getHeight(); + if (!bPercentWidth && !nWidth) + { + nWidth = aTwipSz.getWidth(); + } + if (!bPercentHeight && !nHeight) + { + nHeight = aTwipSz.getHeight(); + } } } - if( !nWidth || !nHeight ) + if( !(nWidth && !bRelWidthScale) || !(nHeight && !bRelHeightScale) ) { // When the graphic is in a table, it will be requested immediately, // so that it is available before the table is layouted. @@ -753,9 +783,10 @@ IMAGE_SETEVENT: } // observe minimum values !! + bool bRelSizeScale = bRelWidthScale || bRelHeightScale; if( nPercentWidth ) { - OSL_ENSURE( !aTwipSz.Width(), + OSL_ENSURE( !aTwipSz.Width() || bRelSizeScale, "Why is a width set if we already have percentage value?" ); aTwipSz.setWidth( aGrfSz.Width() ? aGrfSz.Width() : HTML_DFLT_IMG_WIDTH ); @@ -768,7 +799,7 @@ IMAGE_SETEVENT: } if( nPercentHeight ) { - OSL_ENSURE( !aTwipSz.Height(), + OSL_ENSURE( !aTwipSz.Height() || bRelSizeScale, "Why is a height set if we already have percentage value?" ); aTwipSz.setHeight( aGrfSz.Height() ? aGrfSz.Height() : HTML_DFLT_IMG_HEIGHT ); -- cgit