sw/qa/extras/rtfexport/data/tdf127806.rtf | 86 +++++++++++++++++++++++++ sw/qa/extras/rtfexport/rtfexport3.cxx | 23 ++++++ writerfilter/source/rtftok/rtfdocumentimpl.cxx | 23 ++++-- writerfilter/source/rtftok/rtfsdrimport.cxx | 38 +++++------ 4 files changed, 144 insertions(+), 26 deletions(-)
New commits: commit 8a3c37ad5d39fb48e259edb13dc2934d5ae4986c Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Tue Aug 30 15:42:44 2022 +0300 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Mon Sep 5 15:04:58 2022 +0200 tdf#127806: RTF import: use shape dimensions for pib picture If RTF shape contains pib (embedded picture) we should override any picture sizes by values from shape. Values provided inside \pict are ignored by MS Word; only shape values matter. To achieve this we need to know shape dimensions so it's calculation is moved to earlier step before internal picture eval. Change-Id: I99c1af7ba62c343b64b3db734b837ff101483ad8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139043 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> (cherry picked from commit 57d9cc81b058757421cd082e5dbe32a919716807) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139417 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/qa/extras/rtfexport/data/tdf127806.rtf b/sw/qa/extras/rtfexport/data/tdf127806.rtf new file mode 100644 index 000000000000..2cc165f4110a --- /dev/null +++ b/sw/qa/extras/rtfexport/data/tdf127806.rtf @@ -0,0 +1,86 @@ +{\rtf1\ansi\ansicpg1252 +{\shpgrp{\*\shpinst +\shplid67 +\shpleft0\shptop21\shpright11906\shpbottom16137\shpfhdr0 +\shpbxpage\shpbypage\shpwr3\shpwrk0\shpfblwtxt1\shpz0 +\shpwr3\shpfblwtxt1 +{\sp{\sn groupLeft}{\sv 0}} +{\sp{\sn groupTop}{\sv 21}} +{\sp{\sn groupRight}{\sv 11906}} +{\sp{\sn groupBottom}{\sv 16137}} +{\sp{\sn fFlipH}{\sv 0}} +{\sp{\sn fFlipV}{\sv 0}} +{\sp{\sn posrelh}{\sv 1}} +{\sp{\sn posrelv}{\sv 1}} +{\sp{\sn fBehindDocument}{\sv 1}} + +{\shp{\*\shpinst\shplid70 +{\sp{\sn relLeft}{\sv 979}} +{\sp{\sn relTop}{\sv 14827}} +{\sp{\sn relRight}{\sv 10918}} +{\sp{\sn relBottom}{\sv 15176}} +{\sp{\sn fRelFlipH}{\sv 0}} +{\sp{\sn fRelFlipV}{\sv 0}} +{\sp{\sn shapeType}{\sv 0}} +{\sp{\sn rotation}{\sv 0}} +{\sp{\sn geoRight}{\sv 9939}} +{\sp{\sn geoBottom}{\sv 349}} +{\sp{\sn shapePath}{\sv 4}} +{\sp{\sn pVerticies}{\sv 8;5;(9938,0);(0,0);(0,348);(9938,348);(9938,0)}} +{\sp{\sn pSegmentInfo}{\sv 2;12;16384;45824;1;45824;1;45824;1;45824;1;45824;24577;32768}} +{\sp{\sn fFillOK}{\sv 1}} +{\sp{\sn fFilled}{\sv 1}} +{\sp{\sn fillColor}{\sv 5987168}} +{\sp{\sn fLine}{\sv 0}}{\sp{\sn lineType}{\sv 0}} +{\sp{\sn posrelh}{\sv 1}} +{\sp{\sn posrelv}{\sv 1}} +{\sp{\sn fArrowheadsOK}{\sv 1}} +{\sp{\sn fBehindDocument}{\sv 1}} +}} + +{\shp{\*\shpinst\shplid72 +{\sp{\sn relLeft}{\sv 830}} +{\sp{\sn relTop}{\sv 816}} +{\sp{\sn relRight}{\sv 1190}} +{\sp{\sn relBottom}{\sv 1156}} +{\sp{\sn pib}{\sv{\pict\picscalex500\picscaley9\piccropl0\piccropr0\piccropt0\piccropb0\picw1270\pich1243\picwgoal720\pichgoal705 +\pngblip{\*\blipuid c0d486c26efd24459c14592d8249a32b} +89504e470d0a1a0a0000000d49484452000000300000002f0806000000a58249 +c900000006624b474400ff00ff00ffa0bda793000000097048597300000ec400 +000ec401952b0e1b0000041e494441546881cd984d6c1b4514c7ff33ebf5b7e3 +943a6da2a290402528a5520f9168f9101c00b5a71e2ace9c7be28022242e1542 +e28038708023070e1c901007041c8a904088b6082808921450212d4e9438561c +3bb1d7ebddd9791ce275b7eeaee38f59dbbfd3ee7b3b6fe6bff366e6ed322282 +8bf5fb4b5764f9eb17110276310ae3a72c00a62c66e4686a87bb37246d5deefe +f0b4b2e81e9c3d0dc6af1350397800489fbbbc785740f5e7054823a9b40700d2 +62307ec902821ffc700fe8c7260bb113af7cd88a2acbdf3da7b407002401e346 +16d288a80e8df4f9b75f0580bb022adf3eafb20322a0be9481538aaa0c0b00d0 +e7a6f2d1e3173f019a0288444475fe5bb713b0d7122a43b6489f7ff7927bbd2f +c0f8f33138d5b4aa0eecad28cc9bcac2dd83968bef461f3af7a57bbf2fa0b6f4 +84aa0e9c5a383b8e4bfcd40b5f78ef3900c8da1fa754042702cc9534e0a8dd71 +5a3042e2cc1b97bda6e60ca811200a3188624c45285ff4071fd8d4b28fdcf2da +94092001d457c2c97b97f8e98b1fb7db3889bd0c356ecf0d1abc712b0532b541 +c304a311e20b8b6fb59b3999ff3e3c686ca7aaa1b1aafc10bf87c8e15499c726 +2bed764ed6fab141021301f5e50c40e1ec3a2e9199f9bffdec9c1a8309b03762 +70b6d59fb6ede8b367bff7b3730c300324586807563bd1e3173ef5b30f3403d6 +5a1cd40871e1366131483eb5f0a39faf6f01448075279c5aa79d486eb2c83927 +3f1f27bb38d54f50a7a443d6d497c97ef0c9231b813ec87a5fafb131a4b70f00 +3c91dd09f4f523409a1ca2105ec9d00e4b1e2a05f938f521c0cac743dff7bdf0 +646e2bd0d7eb0c9004acfcf0d2070078eae866a00f4e6f02c45634dc9ac7079e +9e590ff4811a3d25b37527dc9ac70f96c815837c1c2c6a751b886c06b1adab19 +550f50a37c28c8c7c1e366b781444947589f8a9d90b5c274908f8327eadd0612 +3bc37ffb004046f148908fb31e66208c7f3cdd20ebdb81d542d7294402702ac3 +291deeebdb281d0ef27168a95a37419cb23ed4c3cb8b344ab9201f67d1e9c043 +c28b1851fa008028aecd07f938d3bb1430a2050c004ea9d22185623381a5aa0b +49c019a10032c19dd2ca493f5f5733e05422801c4dfebb58ab5f5df0b377b506 +a431dcdac70f91bff6ac9f9db3f8fcea418dc90ae95f670fd8ebcba7fdec9c25 +1ffdeba0c6648f8380d2b4acdffff9cb9996ae2236fb5fa7c6648d36ff010092 +c1bcf1deebed660e003c79e266c7b663904200602e7dfe72bb8d03003b40c038 +ac0100b0f38559d92867bdb6a68093cb9d1a8e8b000806f3b7f75ff39af65368 +e249dfbf5e2e63b1069ad4af7f74c97bdf9c81c757a065f6fc1a108dc72ee422 +367673d63f9fb5d6c2be00a6393c73e6ba7f0b36b22a3488da376fbee35eb75e +2d9b387bcdef6112e3357800b05637e6c4e6d567008f003ef1d455dfa7c76ffc +003154af2c7e0000ff03fbe27bc1eb13f80b0000000049454e44ae426082}}}}} +}} + +} \ No newline at end of file diff --git a/sw/qa/extras/rtfexport/rtfexport3.cxx b/sw/qa/extras/rtfexport/rtfexport3.cxx index bd8a1c8dc795..a3fd0101d80f 100644 --- a/sw/qa/extras/rtfexport/rtfexport3.cxx +++ b/sw/qa/extras/rtfexport/rtfexport3.cxx @@ -492,6 +492,29 @@ CPPUNIT_TEST_FIXTURE(Test, testNegativePageBorder) CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-646), nTopBorderDistance); } +CPPUNIT_TEST_FIXTURE(Test, testTdf127806) +{ + load(mpTestDocumentPath, "tdf127806.rtf"); + CPPUNIT_ASSERT_EQUAL(2, getShapes()); + + CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.GroupShape"), getShape(1)->getShapeType()); + auto xImage = getShape(2); + CPPUNIT_ASSERT_EQUAL(OUString("FrameShape"), xImage->getShapeType()); + awt::Size aSize(xImage->getSize()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(600), aSize.Height); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(635), aSize.Width); + + reload(mpFilter, "tdf127806.rtf"); + CPPUNIT_ASSERT_EQUAL(1, getShapes()); // FIXME: We lost one shape on export, that's sucks + + xImage = getShape(1); + CPPUNIT_ASSERT_EQUAL(OUString("FrameShape"), xImage->getShapeType()); + + aSize = xImage->getSize(); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(600), aSize.Height); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(635), aSize.Width); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index 214be28dfb53..c428759e4c7c 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -959,8 +959,23 @@ void RTFDocumentImpl::resolvePict(bool const bInline, uno::Reference<drawing::XS m_aStates.top().getPicture().nHeight = aSize.Height(); } - // Wrap it in an XShape. uno::Reference<drawing::XShape> xShape(rShape); + if (m_aStates.top().getInShape() && xShape.is()) + { + awt::Size aSize = xShape->getSize(); + if (aSize.Width || aSize.Height) + { + // resolvePict() is processing pib structure inside shape + // So if shape has dimensions we should use them instead of + // \picwN, \pichN, \picscalexN, \picscaleyN given with picture + m_aStates.top().getPicture().nGoalWidth = aSize.Width; + m_aStates.top().getPicture().nGoalHeight = aSize.Height; + m_aStates.top().getPicture().nScaleX = 100; + m_aStates.top().getPicture().nScaleY = 100; + } + } + + // Wrap it in an XShape. if (xShape.is()) { uno::Reference<lang::XServiceInfo> xSI(xShape, uno::UNO_QUERY_THROW); @@ -1060,12 +1075,6 @@ void RTFDocumentImpl::resolvePict(bool const bInline, uno::Reference<drawing::XS * (nYExt - (m_aStates.top().getPicture().nCropT + m_aStates.top().getPicture().nCropB))) / 100L; - if (m_aStates.top().getInShape()) - { - // Picture in shape: it looks like pib picture, so we will stretch the picture to shape size (tdf#49893) - nXExt = m_aStates.top().getShape().getRight() - m_aStates.top().getShape().getLeft(); - nYExt = m_aStates.top().getShape().getBottom() - m_aStates.top().getShape().getTop(); - } auto pXExtValue = new RTFValue(oox::drawingml::convertHmmToEmu(nXExt)); auto pYExtValue = new RTFValue(oox::drawingml::convertHmmToEmu(nYExt)); aExtentAttributes.set(NS_ooxml::LN_CT_PositiveSize2D_cx, pXExtValue); diff --git a/writerfilter/source/rtftok/rtfsdrimport.cxx b/writerfilter/source/rtftok/rtfsdrimport.cxx index feb56a68a0b3..e928377f9d9c 100644 --- a/writerfilter/source/rtftok/rtfsdrimport.cxx +++ b/writerfilter/source/rtftok/rtfsdrimport.cxx @@ -911,25 +911,6 @@ void RTFSdrImport::resolve(RTFShape& rShape, bool bClose, ShapeOrPict const shap xPropertySet->setPropertyValue("GraphicColorMode", uno::Any(drawing::ColorMode_WATERMARK)); } - if (bPib) - { - m_rImport.resolvePict(false, xShape); - } - - if (nType == ESCHER_ShpInst_PictureFrame) // picture frame - { - assert(!m_bTextFrame); - if (!bPib) // ??? not sure if the early return should be removed on else? - { - m_xShape = xShape; // store it for later resolvePict call - } - - // Handle horizontal flip. - if (obFlipH && xPropertySet.is()) - xPropertySet->setPropertyValue("IsMirrored", uno::Any(true)); - return; - } - if (bCustom && xShape.is() && !bPib) { uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY); @@ -1132,6 +1113,25 @@ void RTFSdrImport::resolve(RTFShape& rShape, bool bClose, ShapeOrPict const shap } } + if (bPib) + { + m_rImport.resolvePict(false, xShape); + } + + if (nType == ESCHER_ShpInst_PictureFrame) // picture frame + { + assert(!m_bTextFrame); + if (!bPib) // ??? not sure if the early return should be removed on else? + { + m_xShape = xShape; // store it for later resolvePict call + } + + // Handle horizontal flip. + if (obFlipH && xPropertySet.is()) + xPropertySet->setPropertyValue("IsMirrored", uno::Any(true)); + return; + } + if (m_rImport.isInBackground()) { RTFSprms aAttributes;