sw/qa/filter/md/data/embedded-image.md | 1 + sw/qa/filter/md/md.cxx | 23 +++++++++++++++++++++++ sw/source/filter/md/swmd.cxx | 18 +++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-)
New commits: commit 169e1f3b914ac590b3719b8129b4f0913d4da228 Author: Miklos Vajna <[email protected]> AuthorDate: Wed Oct 1 08:35:21 2025 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Wed Oct 1 11:40:34 2025 +0200 sw markdown filter: import images with 'data:' URLs Open the bugdoc which contains a data:image/png;base64,... image, the result in Writer is a placeholder image with bad size. Checking what the HTML import does, sw::DocumentContentOperationsManager::InsertGraphic() doesn't get this 'data:' URL, instead SwHTMLParser::InsertImage() checks for INetProtocol::Data and in that case initializes the Graphic and clears the URL. Fix the problem by handling this similar in SwMarkdownParser::InsertImage(): we can feed the 'data:' URL into an unloaded graphic, set its size and clear the URL. The export side of this is still missing. Change-Id: Iea4f6531dfa190e4bc3af14239f97ec9fcad4ae8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191709 Tested-by: Jenkins Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sw/qa/filter/md/data/embedded-image.md b/sw/qa/filter/md/data/embedded-image.md new file mode 100644 index 000000000000..d0b83e416fa5 --- /dev/null +++ b/sw/qa/filter/md/data/embedded-image.md @@ -0,0 +1 @@ +A  Z diff --git a/sw/qa/filter/md/md.cxx b/sw/qa/filter/md/md.cxx index 217d212a90f8..847ad0bf5ad1 100644 --- a/sw/qa/filter/md/md.cxx +++ b/sw/qa/filter/md/md.cxx @@ -27,6 +27,7 @@ #include <ndtxt.hxx> #include <fmturl.hxx> #include <textcontentcontrol.hxx> +#include <fmtfsize.hxx> namespace { @@ -817,6 +818,28 @@ CPPUNIT_TEST_FIXTURE(Test, testTastListItemsMdExport) CPPUNIT_ASSERT_EQUAL(aExpected, aActual); } +CPPUNIT_TEST_FIXTURE(Test, testEmbeddedImageMdImport) +{ + // Given a document with an embedded image: + // When importing that document: + setImportFilterName("Markdown"); + createSwDoc("embedded-image.md"); + + // Then make sure the embedded image gets imported, with the correct size: + SwDocShell* pDocShell = getSwDocShell(); + SwDoc* pDoc = pDocShell->GetDoc(); + sw::FrameFormats<sw::SpzFrameFormat*>& rFlys = *pDoc->GetSpzFrameFormats(); + CPPUNIT_ASSERT(!rFlys.empty()); + sw::SpzFrameFormat& rFly = *rFlys[0]; + const SwFormatFrameSize& rSize = rFly.GetFrameSize(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 960 + // - Actual : 500 (MD_MIN_IMAGE_WIDTH_IN_TWIPS) + // i.e. the image wasn't imported, had the default minimal size. + CPPUNIT_ASSERT_EQUAL(static_cast<SwTwips>(960), rSize.GetWidth()); + CPPUNIT_ASSERT_EQUAL(static_cast<SwTwips>(960), rSize.GetHeight()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/filter/md/swmd.cxx b/sw/source/filter/md/swmd.cxx index 22d494d54e92..ccccdd2cb141 100644 --- a/sw/source/filter/md/swmd.cxx +++ b/sw/source/filter/md/swmd.cxx @@ -632,6 +632,17 @@ void SwMarkdownParser::InsertImage(const MDImage& rImg) Graphic aGraphic; INetURLObject aGraphicURL(sGrfNm); + if (aGraphicURL.GetProtocol() == INetProtocol::Data) + { + // 'data:' URL: read that here, initialize aGraphic anc clear sGrfNm. + std::unique_ptr<SvMemoryStream> pStream = aGraphicURL.getData(); + if (pStream) + { + GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); + aGraphic = rFilter.ImportUnloadedGraphic(*pStream); + sGrfNm.clear(); + } + } if (!sGrfNm.isEmpty()) { @@ -639,13 +650,18 @@ void SwMarkdownParser::InsertImage(const MDImage& rImg) } Size aGrfSz(0, 0); - if (allowAccessLink(*m_xDoc) && !aGraphicURL.IsExoticProtocol()) + if (allowAccessLink(*m_xDoc) && !aGraphicURL.IsExoticProtocol() && !sGrfNm.isEmpty()) { GraphicDescriptor aDescriptor(aGraphicURL); if (aDescriptor.Detect(true)) aGrfSz = o3tl::convert(aDescriptor.GetSizePixel(), o3tl::Length::px, o3tl::Length::twip); } + else if (aGraphic.GetType() == GraphicType::Bitmap) + { + // We have an unloaded graphic in aGraphic, read its size. + aGrfSz = o3tl::convert(aGraphic.GetSizePixel(), o3tl::Length::px, o3tl::Length::twip); + } tools::Long nWidth = 0; tools::Long nHeight = 0;
