configure.ac | 2 dev/null |binary download.lst | 16 drawinglayer/source/tools/emfphelperdata.cxx | 56 - drawinglayer/source/tools/emfphelperdata.hxx | 2 drawinglayer/source/tools/emfppath.cxx | 126 --- drawinglayer/source/tools/emfppath.hxx | 5 emfio/qa/cppunit/emf/EmfImportTest.cxx | 186 ----- emfio/qa/cppunit/emf/data/TestEmfPlusFillClosedCurve.emf |binary external/curl/README | 2 external/openssl/0001-x509-excessive-resource-use-verifying-policy-constra.patch.1 | 221 ------ external/openssl/README | 2 external/openssl/UnpackedTarball_openssl.mk | 2 external/openssl/openssl-no-_umul128-on-aarch64.patch.1 | 58 - external/python3/python-3.3.0-darwin.patch.1 | 2 filter/source/xslt/odf2xhtml/export/common/table/table_rows.xsl | 5 filter/source/xslt/odf2xhtml/export/common/table_of_content.xsl | 25 filter/source/xslt/odf2xhtml/export/xhtml/body.xsl | 345 +++++++++- filter/source/xslt/odf2xhtml/export/xhtml/header.xsl | 7 filter/source/xslt/odf2xhtml/export/xhtml/table.xsl | 6 include/vcl/bitmapex.hxx | 1 include/vcl/outdev.hxx | 2 include/xmloff/txtparae.hxx | 6 sc/CppunitTest_sc_html_export_test.mk | 5 sc/qa/extras/htmlexporttest.cxx | 25 sc/qa/extras/testdocuments/default-styles.ods |binary svgio/qa/cppunit/SvgImportTest.cxx | 18 svgio/qa/cppunit/data/tdf155819.svg | 15 svgio/source/svgreader/svgstyleattributes.cxx | 15 svtools/source/misc/unitconv.cxx | 2 sw/inc/numrule.hxx | 3 sw/qa/core/unocore/unocore.cxx | 41 - sw/qa/extras/htmlexport/xhtmlexport.cxx | 23 sw/qa/extras/ooxmlexport/data/tdf155690.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport13.cxx | 47 + sw/source/core/doc/number.cxx | 23 sw/source/core/unocore/unoparagraph.cxx | 18 sw/source/uibase/uno/unotxdoc.cxx | 28 vcl/source/bitmap/BitmapEx.cxx | 5 vcl/source/filter/png/PngImageWriter.cxx | 8 vcl/source/outdev/textline.cxx | 21 writerfilter/source/dmapper/DomainMapper_Impl.cxx | 6 xmloff/qa/unit/data/differentListStylesInOneList.fodt | 47 + xmloff/qa/unit/text.cxx | 105 +++ xmloff/source/text/XMLTextNumRuleInfo.cxx | 12 xmloff/source/text/XMLTextNumRuleInfo.hxx | 5 xmloff/source/text/txtparae.cxx | 146 +++- 47 files changed, 917 insertions(+), 778 deletions(-)
New commits: commit 9f66e8819fb3cb17acfac46aa6fc3cbd5293ee50 Author: Taichi Haradaguchi <20001...@ymail.ne.jp> AuthorDate: Thu Jun 15 07:09:06 2023 +0900 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Jun 18 11:55:03 2023 +0200 nss: upgrade to release 3.90 Change-Id: Ic446f33abd5355886b8c8c181a088c07ea4605c1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153096 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 3f6bb9565d4edce563dbd938c655ae853926d362) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153083 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit c5c9b792eef7982a83451f7d67022c57c1ffae48) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153133 diff --git a/download.lst b/download.lst index 5a3a228e35d7..5152c9afda6e 100644 --- a/download.lst +++ b/download.lst @@ -456,8 +456,8 @@ MYTHES_TARBALL := mythes-1.2.5.tar.xz # three static lines # so that git cherry-pick # will not run into conflicts -NSS_SHA256SUM := fcfa26d2738ec5b0cf72ab4be784eac832a75132cda2e295799c04d62a93607a -NSS_TARBALL := nss-3.88.1-with-nspr-4.35.tar.gz +NSS_SHA256SUM := f78ab1d911cae8bbc94758fb3bd0f731df4087423a4ff5db271ba65381f6b739 +NSS_TARBALL := nss-3.90-with-nspr-4.35.tar.gz # three static lines # so that git cherry-pick # will not run into conflicts commit 08d80793d69dafd230c024846f259b64f5686628 Author: Paris Oplopoios <paris.oplopo...@collabora.com> AuthorDate: Sat Jun 10 21:33:39 2023 +0300 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Jun 18 11:55:03 2023 +0200 tdf#154168 Export no transparency PNGs correctly When bTranslucent was false the function would simply return, causing a 0 byte png. Now we just remove the alpha channel. Change-Id: Ie2578185ac12fb38b6f1b674758e564721e3973f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152840 Tested-by: Jenkins Reviewed-by: Paris Oplopoios <parisop...@gmail.com> (cherry picked from commit 7588c1f33cdaab58a6b84f4f4e75922c5d4a8a7f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152886 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit e691869486cd4ee4ee1dfb8f7a41440f7f6500fd) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153081 diff --git a/include/vcl/bitmapex.hxx b/include/vcl/bitmapex.hxx index f847c9f6dcb2..9dcedc7ffb81 100644 --- a/include/vcl/bitmapex.hxx +++ b/include/vcl/bitmapex.hxx @@ -56,6 +56,7 @@ public: bool IsEmpty() const; void SetEmpty(); void Clear(); + void ClearAlpha(); void Draw( OutputDevice* pOutDev, const Point& rDestPt ) const; diff --git a/vcl/source/bitmap/BitmapEx.cxx b/vcl/source/bitmap/BitmapEx.cxx index 6ff2280cdb06..c19ed0f02c3a 100644 --- a/vcl/source/bitmap/BitmapEx.cxx +++ b/vcl/source/bitmap/BitmapEx.cxx @@ -190,6 +190,11 @@ void BitmapEx::Clear() SetEmpty(); } +void BitmapEx::ClearAlpha() +{ + maAlphaMask.SetEmpty(); +} + bool BitmapEx::IsAlpha() const { return !maAlphaMask.IsEmpty(); diff --git a/vcl/source/filter/png/PngImageWriter.cxx b/vcl/source/filter/png/PngImageWriter.cxx index f550d9951e64..29d79740009e 100644 --- a/vcl/source/filter/png/PngImageWriter.cxx +++ b/vcl/source/filter/png/PngImageWriter.cxx @@ -50,8 +50,6 @@ static bool pngWrite(SvStream& rStream, const BitmapEx& rBitmapEx, int nCompress bool bInterlaced, bool bTranslucent, const std::vector<PngChunk>& aAdditionalChunks) { - if (rBitmapEx.IsAlpha() && !bTranslucent) - return false; if (rBitmapEx.IsEmpty()) return false; @@ -78,6 +76,12 @@ static bool pngWrite(SvStream& rStream, const BitmapEx& rBitmapEx, int nCompress aBitmapEx = rBitmapEx; } + if (!bTranslucent) + { + // Clear alpha channel + aBitmapEx.ClearAlpha(); + } + Bitmap aBitmap; AlphaMask aAlphaMask; Bitmap::ScopedReadAccess pAccess; commit d75896d3838bd4dd1bf009c16b35231273c91acc Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Wed Jun 14 15:35:24 2023 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Jun 18 11:55:02 2023 +0200 tdf#155690 writerfilter: fix import of bookmark in table... ... at start of section. (regression from commit 2e8aad6d45c53d554ccaf26de998ede708cfc289) Change-Id: I1e0e720758b607b69645b29c46f4092264289f9e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153053 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 142aa77265361492e74707b08c5bcd366e7205ad) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153072 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/qa/extras/ooxmlexport/data/tdf155690.docx b/sw/qa/extras/ooxmlexport/data/tdf155690.docx new file mode 100644 index 000000000000..1839862688ee Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf155690.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx index a1610c35dbbb..37ffaa0b2979 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx @@ -58,6 +58,53 @@ DECLARE_OOXMLEXPORT_TEST(testTdf126994_lostPageBreak, "tdf126994_lostPageBreak.d CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Pages", 3, getPages() ); } +DECLARE_OOXMLEXPORT_TEST(testTdf155690, "tdf155690.docx") +{ + uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xBookmarks = xBookmarksSupplier->getBookmarks(); + { + uno::Reference<text::XTextContent> xMark(xBookmarks->getByName("row1_1"), uno::UNO_QUERY); + CPPUNIT_ASSERT(xMark.is()); + // the problem was that the start was after the H + CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark->getAnchor()->getString()); + } + { + uno::Reference<text::XTextContent> xMark(xBookmarks->getByName("row1_2"), uno::UNO_QUERY); + CPPUNIT_ASSERT(xMark.is()); + CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark->getAnchor()->getString()); + } + { + uno::Reference<text::XTextContent> xMark(xBookmarks->getByName("row1_3"), uno::UNO_QUERY); + CPPUNIT_ASSERT(xMark.is()); + CPPUNIT_ASSERT_EQUAL(OUString("ello world"), xMark->getAnchor()->getString()); + } + { + uno::Reference<text::XTextContent> xMark(xBookmarks->getByName("row1_4"), uno::UNO_QUERY); + CPPUNIT_ASSERT(xMark.is()); + CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark->getAnchor()->getString()); + } + { + uno::Reference<text::XTextContent> xMark(xBookmarks->getByName("row2_1"), uno::UNO_QUERY); + CPPUNIT_ASSERT(xMark.is()); + CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark->getAnchor()->getString()); + } + { + uno::Reference<text::XTextContent> xMark(xBookmarks->getByName("row2_1"), uno::UNO_QUERY); + CPPUNIT_ASSERT(xMark.is()); + CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark->getAnchor()->getString()); + } + { + uno::Reference<text::XTextContent> xMark(xBookmarks->getByName("row2_3"), uno::UNO_QUERY); + CPPUNIT_ASSERT(xMark.is()); + CPPUNIT_ASSERT_EQUAL(OUString("ello world"), xMark->getAnchor()->getString()); + } + { + uno::Reference<text::XTextContent> xMark(xBookmarks->getByName("row2_4"), uno::UNO_QUERY); + CPPUNIT_ASSERT(xMark.is()); + CPPUNIT_ASSERT_EQUAL(OUString("Hello world"), xMark->getAnchor()->getString()); + } +} + CPPUNIT_TEST_FIXTURE(Test, testTdf121374_sectionHF) { loadAndReload("tdf121374_sectionHF.odt"); diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 0aa49dec631b..e2061b7e0483 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -8196,6 +8196,9 @@ void DomainMapper_Impl::StartOrEndBookmark( const OUString& rId ) else { xCursor = xText->createTextCursorByRange( aBookmarkIter->second.m_xTextRange ); + } + if (!aBookmarkIter->second.m_bIsStartOfText) + { xCursor->goRight( 1, false ); } @@ -8337,6 +8340,9 @@ void DomainMapper_Impl::startOrEndPermissionRange(sal_Int32 permissinId) else { xCursor = xText->createTextCursorByRange(aPermIter->second.m_xTextRange); + } + if (!aPermIter->second.m_bIsStartOfText) + { xCursor->goRight(1, false); } commit 3780f966d01f7e7dd6c0e5eb807837bdbb695a75 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Tue Jun 13 23:15:08 2023 +0300 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Jun 18 11:55:02 2023 +0200 tdf#155823: Improve the check if the list id is not required The implementation introduced in commit 8f48f91009caa86d896f247059874242ed18bf39 (SwNumRule::HasContinueList) was a bit naive: it assumed that maTextNodeList is sorted (it is not, and so, valid cases to avoid the id were missed); it assumed that a given list can only consist of items of a single numbering style, and so only tested the list of nodes referenced from maTextNodeList of given SwNumRule. I.e., this implementation targeted a special case of a list style fully covering a single continuous list. This skipped ids for list items with list styles, in which maTextNodeList passed the check in HasContinueList, but which were followed by items with a different list style, continuing the same list. This constellation outputs continue-list attribute in the following items (see XMLTextParagraphExport::exportListChange), which references the skipped id. The resulting ODF is an invalid XML (an xml:id is missing that is referenced), and also does not allow to continue such a list. The change tries to fix this, using a list of nodes in XMLTextParagraphExport, and analyzing if the list of the current paragraph has a continuation that needs to reference this list id. Two new hidden properties introduced in SwXParagraph and SwXTextDocument: "ODFExport_NodeIndex" and "ODFExport_ListNodes", resp. They allow to pipe the data to the export. The previous special casing of property state for "ListId", used in SwNumRule::HasContinueList, is removed together with the mentioned function. The intention is to have a logic allowing to detect 100% cases where the list id is required, and where it's not required. A related unit test for tdf#149668 was fixed to not rely on the mentioned ListId property state workaround, and moved from sw/qa/core/unocore to xmloff/qa/unit. Change-Id: If6a6ac7a3dfe0b2ea143229678a603875153eedb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153044 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153065 Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/include/xmloff/txtparae.hxx b/include/xmloff/txtparae.hxx index e474a9c5b763..dd78b2bb1141 100644 --- a/include/xmloff/txtparae.hxx +++ b/include/xmloff/txtparae.hxx @@ -110,6 +110,9 @@ class XMLOFF_DLLPUBLIC XMLTextParagraphExport : public XMLStyleExport XMLTextListsHelper* mpTextListsHelper; ::std::vector< std::unique_ptr<XMLTextListsHelper> > maTextListsHelperStack; + struct DocumentListNodes; + std::unique_ptr<DocumentListNodes> mpDocumentListNodes; + bool mbCollected; enum class FrameType { Text, Graphic, Embedded, Shape }; @@ -532,6 +535,9 @@ public: void PopTextListsHelper(); private: + bool ShouldSkipListId(const css::uno::Reference<css::text::XTextContent>& xTextContent); + bool ExportListId() const; + XMLTextParagraphExport(XMLTextParagraphExport const &) = delete; }; diff --git a/sw/inc/numrule.hxx b/sw/inc/numrule.hxx index fde2c8de0fb8..f642e21e746c 100644 --- a/sw/inc/numrule.hxx +++ b/sw/inc/numrule.hxx @@ -272,9 +272,6 @@ public: void dumpAsXml(xmlTextWriterPtr w) const; void GetGrabBagItem(css::uno::Any& rVal) const; void SetGrabBagItem(const css::uno::Any& rVal); - - /// Is it possible that this numbering has multiple lists? - bool HasContinueList() const; }; /// namespace for static functions and methods for numbering and bullets diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx index 603d56d449a1..29bc60723f32 100644 --- a/sw/qa/core/unocore/unocore.cxx +++ b/sw/qa/core/unocore/unocore.cxx @@ -669,47 +669,6 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testContentControlDate) CPPUNIT_ASSERT_EQUAL(OUString("sdtContentLocked"), pContentControl->GetLock()); } -CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testListIdState) -{ - // Given a document with 3 paragraphs: an outer numbering on para 1 & 3, an inner numbering on - // para 2: - createSwDoc(); - SwDoc* pDoc = getSwDoc(); - SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - { - SfxItemSetFixed<RES_PARATR_NUMRULE, RES_PARATR_NUMRULE> aSet(pWrtShell->GetAttrPool()); - SwNumRuleItem aItem("Numbering ABC"); - aSet.Put(aItem); - pWrtShell->SetAttrSet(aSet); - } - pWrtShell->SplitNode(); - { - SfxItemSetFixed<RES_PARATR_NUMRULE, RES_PARATR_NUMRULE> aSet(pWrtShell->GetAttrPool()); - SwNumRuleItem aItem("Numbering 123"); - aSet.Put(aItem); - pWrtShell->SetAttrSet(aSet); - } - pWrtShell->SplitNode(); - { - SfxItemSetFixed<RES_PARATR_NUMRULE, RES_PARATR_NUMRULE> aSet(pWrtShell->GetAttrPool()); - SwNumRuleItem aItem("Numbering ABC"); - aSet.Put(aItem); - pWrtShell->SetAttrSet(aSet); - } - - // When checking if xml:id="..." needs writing for the first paragraph during ODT export: - uno::Reference<beans::XPropertyState> xPara(getParagraph(1), uno::UNO_QUERY); - beans::PropertyState eState = xPara->getPropertyState("ListId"); - - // Then make sure that xml:id="..." gets written for para 1, as it'll be continued in para 3. - // Without the accompanying fix in place, this test would have failed with: - // - Expected: 0 (DIRECT_VALUE) - // - Actual : 1 (DEFAULT_VALUE) - // i.e. para 1 didn't write an xml:id="..." but para 3 referred to it using continue-list="...", - // which is inconsistent. - CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, eState); -} - CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testContentControlPlainText) { // Given an empty document: diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx index 7dc2953608cf..f953a93dbde4 100644 --- a/sw/source/core/doc/number.cxx +++ b/sw/source/core/doc/number.cxx @@ -1153,29 +1153,6 @@ void SwNumRule::SetGrabBagItem(const uno::Any& rVal) mpGrabBagItem->PutValue(rVal, 0); } -bool SwNumRule::HasContinueList() const -{ - // In case all text nodes are after each other, then we won't have a later list that wants to - // continue us. - SwNodeOffset nIndex(0); - for (size_t i = 0; i < maTextNodeList.size(); ++i) - { - SwTextNode* pNode = maTextNodeList[i]; - if (i > 0) - { - if (pNode->GetIndex() != nIndex + 1) - { - // May have a continue list. - return true; - } - } - nIndex = pNode->GetIndex(); - } - - // Definitely won't have a continue list. - return false; -} - namespace numfunc { namespace { diff --git a/sw/source/core/unocore/unoparagraph.cxx b/sw/source/core/unocore/unoparagraph.cxx index c3d35d47075c..881a198d333a 100644 --- a/sw/source/core/unocore/unoparagraph.cxx +++ b/sw/source/core/unocore/unoparagraph.cxx @@ -554,6 +554,14 @@ uno::Sequence< uno::Any > SwXParagraph::Impl::GetPropertyValues_Impl( continue; } + if (pPropertyNames[nProp] == "ODFExport_NodeIndex") + { + // A hack to avoid writing random list ids to ODF when they are not referred later + // see XMLTextParagraphExport::DocumentListNodes::ShouldSkipListId + pValues[nProp] <<= rTextNode.GetIndex().get(); + continue; + } + SfxItemPropertyMapEntry const*const pEntry = rMap.getByName( pPropertyNames[nProp] ); if (!pEntry) @@ -943,16 +951,6 @@ static beans::PropertyState lcl_SwXParagraph_getPropertyState( bDone = true; break; } - case FN_UNO_LIST_ID: - { - SwNumRule* pNumRule = rTextNode.GetNumRule(); - if (pNumRule && pNumRule->HasContinueList()) - { - eRet = beans::PropertyState_DIRECT_VALUE; - } - bDone = true; - break; - } case FN_UNO_ANCHOR_TYPES: { bDone = true; diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx index 1a1c5c3ec41a..c68695ecddac 100644 --- a/sw/source/uibase/uno/unotxdoc.cxx +++ b/sw/source/uibase/uno/unotxdoc.cxx @@ -1971,6 +1971,34 @@ Any SwXTextDocument::getPropertyValue(const OUString& rPropertyName) if(!IsValid()) throw DisposedException("", static_cast< XTextDocument* >(this)); + if (rPropertyName == "ODFExport_ListNodes") + { + // A hack to avoid writing random list ids to ODF when they are not referred later + // see XMLTextParagraphExport::DocumentListNodes ctor + + // Sequence of nodes, each of them represented by four-element sequence: + // [ index, styleIntPtr, list_id, isRestart ] + std::vector<css::uno::Sequence<css::uno::Any>> nodes; + + const SwDoc& rDoc = *m_pDocShell->GetDoc(); + for (const SwNumRule* pNumRule : rDoc.GetNumRuleTable()) + { + SwNumRule::tTextNodeList textNodes; + pNumRule->GetTextNodeList(textNodes); + css::uno::Any styleIntPtr(reinterpret_cast<sal_uInt64>(pNumRule)); + + for (const SwTextNode* pTextNode : textNodes) + { + css::uno::Any index(pTextNode->GetIndex().get()); + css::uno::Any list_id(pTextNode->GetListId()); + css::uno::Any isRestart(pTextNode->IsListRestart()); + + nodes.push_back({ index, styleIntPtr, list_id, isRestart }); + } + } + return css::uno::Any(comphelper::containerToSequence(nodes)); + } + const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName); if(!pEntry) diff --git a/xmloff/qa/unit/data/differentListStylesInOneList.fodt b/xmloff/qa/unit/data/differentListStylesInOneList.fodt new file mode 100644 index 000000000000..5f90135fbb23 --- /dev/null +++ b/xmloff/qa/unit/data/differentListStylesInOneList.fodt @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:styles> + <text:list-style style:name="ListStyleOne"> + <text:list-level-style-number text:level="1" style:num-suffix="." style:num-format="1"> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab" fo:text-indent="-1cm" fo:margin-left="1cm"/> + </style:list-level-properties> + </text:list-level-style-number> + </text:list-style> + <text:list-style style:name="ListStyleAnother"> + <text:list-level-style-number text:level="1" style:num-suffix="." style:num-format="1"> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab" fo:text-indent="-1cm" fo:margin-left="1cm"/> + </style:list-level-properties> + </text:list-level-style-number> + </text:list-style> + </office:styles> + <office:body> + <office:text> + <text:list xml:id="list1" text:style-name="ListStyleOne"> + <text:list-item> + <text:p>Item1 (ListStyleOne)</text:p> + </text:list-item> + </text:list> + <text:p/> + <text:list xml:id="list2" text:continue-numbering="true" text:style-name="ListStyleOne"> + <text:list-item> + <text:p>Item2 (ListStyleOne)</text:p> + </text:list-item> + </text:list> + <text:p/> + <text:list xml:id="list3" text:continue-list="list2" text:style-name="ListStyleAnother"> + <text:list-item> + <text:p>Item3 (ListStyleAnother)</text:p> + </text:list-item> + </text:list> + <text:p/> + <text:list xml:id="list4" text:continue-list="list3" text:style-name="ListStyleOne"> + <text:list-item> + <text:p>Item4 (ListStyleOne)</text:p> + </text:list-item> + </text:list> + </office:text> + </office:body> +</office:document> \ No newline at end of file diff --git a/xmloff/qa/unit/text.cxx b/xmloff/qa/unit/text.cxx index 58a34996b6b2..ab8a28448701 100644 --- a/xmloff/qa/unit/text.cxx +++ b/xmloff/qa/unit/text.cxx @@ -13,6 +13,7 @@ #include <com/sun/star/beans/PropertyValues.hpp> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/ControlCharacter.hpp> #include <com/sun/star/text/BibliographyDataType.hpp> #include <com/sun/star/text/TextContentAnchorType.hpp> #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> @@ -203,6 +204,110 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testListId) assertXPathNoAttribute(pXmlDoc, "//text:list", "id"); } +CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testListId2) +{ + // tdf#155823 Given a document with a list consisting of items having different list styles: + loadFromURL(u"differentListStylesInOneList.fodt"); + + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY_THROW); + uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), + uno::UNO_QUERY_THROW); + auto xParaEnum(xParaEnumAccess->createEnumeration()); + + uno::Reference<beans::XPropertySet> xPara(xParaEnum->nextElement(), uno::UNO_QUERY_THROW); + auto aActual(xPara->getPropertyValue("ListLabelString").get<OUString>()); + CPPUNIT_ASSERT_EQUAL(OUString("1."), aActual); + xParaEnum->nextElement(); // Skip empty intermediate paragraph + xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); + aActual = xPara->getPropertyValue("ListLabelString").get<OUString>(); + CPPUNIT_ASSERT_EQUAL(OUString("2."), aActual); + xParaEnum->nextElement(); // Skip empty intermediate paragraph + xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); + aActual = xPara->getPropertyValue("ListLabelString").get<OUString>(); + CPPUNIT_ASSERT_EQUAL(OUString("3."), aActual); + xParaEnum->nextElement(); // Skip empty intermediate paragraph + xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); + aActual = xPara->getPropertyValue("ListLabelString").get<OUString>(); + CPPUNIT_ASSERT_EQUAL(OUString("4."), aActual); + + // When storing that document as ODF: + // Without the fix in place, automatic validation would fail with: + // Error: "list123456789012345" is referenced by an IDREF, but not defined. + saveAndReload("writer8"); + + xTextDocument.set(mxComponent, uno::UNO_QUERY_THROW); + xParaEnumAccess.set(xTextDocument->getText(), uno::UNO_QUERY_THROW); + xParaEnum.set(xParaEnumAccess->createEnumeration()); + + xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); + aActual = xPara->getPropertyValue("ListLabelString").get<OUString>(); + CPPUNIT_ASSERT_EQUAL(OUString("1."), aActual); + xParaEnum->nextElement(); // Skip empty intermediate paragraph + xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); + aActual = xPara->getPropertyValue("ListLabelString").get<OUString>(); + CPPUNIT_ASSERT_EQUAL(OUString("2."), aActual); + xParaEnum->nextElement(); // Skip empty intermediate paragraph + xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); + aActual = xPara->getPropertyValue("ListLabelString").get<OUString>(); + CPPUNIT_ASSERT_EQUAL(OUString("3."), aActual); + xParaEnum->nextElement(); // Skip empty intermediate paragraph + + // Check that the last item number is correct + + xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); + aActual = xPara->getPropertyValue("ListLabelString").get<OUString>(); + // Without the fix in place, this would fail with: + // - Expected: 4. + // - Actual : 1. + // i.e. the numbering was not continued. + CPPUNIT_ASSERT_EQUAL(OUString("4."), aActual); + + // Then make sure that required xml:id="..." attributes is written when the style changes: + xmlDocUniquePtr pXmlDoc = parseExport("content.xml"); + CPPUNIT_ASSERT(pXmlDoc); + // Without the fix in place, this would fail, + // i.e. xml:id="..." was omitted, even though it was needed for the next item. + OUString id + = getXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:list[3]", "id"); + CPPUNIT_ASSERT(!id.isEmpty()); + assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:list[4]", + "continue-list", id); +} + +CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testListIdState) +{ + // tdf#149668: given a document with 3 paragraphs: an outer numbering on para 1 & 3, an inner + // numbering on para 2: + mxComponent = loadFromDesktop("private:factory/swriter"); + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY_THROW); + auto xText(xTextDocument->getText()); + xText->insertControlCharacter(xText->getEnd(), css::text::ControlCharacter::PARAGRAPH_BREAK, + false); + xText->insertControlCharacter(xText->getEnd(), css::text::ControlCharacter::PARAGRAPH_BREAK, + false); + + uno::Reference<container::XEnumerationAccess> paraEnumAccess(xText, uno::UNO_QUERY_THROW); + auto paraEnum(paraEnumAccess->createEnumeration()); + uno::Reference<beans::XPropertySet> xParaProps(paraEnum->nextElement(), uno::UNO_QUERY_THROW); + xParaProps->setPropertyValue("NumberingStyleName", css::uno::Any(OUString("Numbering ABC"))); + xParaProps.set(paraEnum->nextElement(), uno::UNO_QUERY_THROW); + xParaProps->setPropertyValue("NumberingStyleName", css::uno::Any(OUString("Numbering 123"))); + xParaProps.set(paraEnum->nextElement(), uno::UNO_QUERY_THROW); + xParaProps->setPropertyValue("NumberingStyleName", css::uno::Any(OUString("Numbering ABC"))); + + // When storing that document as ODF: + save("writer8"); + xmlDocUniquePtr pXmlDoc = parseExport("content.xml"); + + // Make sure that xml:id="..." gets written for para 1, as it'll be continued in para 3. + // Without the accompanying fix in place, this test would have failed, + // i.e. para 1 didn't write an xml:id="..." but para 3 referred to it using continue-list="...", + // which is inconsistent. + OUString id + = getXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:list[1]", "id"); + CPPUNIT_ASSERT(!id.isEmpty()); +} + CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testClearingBreakExport) { // Given a document with a clearing break: diff --git a/xmloff/source/text/XMLTextNumRuleInfo.cxx b/xmloff/source/text/XMLTextNumRuleInfo.cxx index 062b92879ee2..5f9a5e2b7a54 100644 --- a/xmloff/source/text/XMLTextNumRuleInfo.cxx +++ b/xmloff/source/text/XMLTextNumRuleInfo.cxx @@ -54,14 +54,14 @@ void XMLTextNumRuleInfo::Set( const css::uno::Reference < css::text::XTextContent > & xTextContent, const bool bOutlineStyleAsNormalListStyle, const XMLTextListAutoStylePool& rListAutoPool, - const bool bExportTextNumberElement ) + const bool bExportTextNumberElement, + const bool bListIdIsDefault ) { Reset(); // Written OpenDocument file format doesn't fit to the created text document (#i69627#) mbOutlineStyleAsNormalListStyle = bOutlineStyleAsNormalListStyle; Reference< XPropertySet > xPropSet( xTextContent, UNO_QUERY ); - Reference<XPropertyState> xPropState(xTextContent, UNO_QUERY); Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); // check if this paragraph supports a numbering @@ -138,14 +138,10 @@ void XMLTextNumRuleInfo::Set( if( xPropSetInfo->hasPropertyByName( "ListId" ) ) { xPropSet->getPropertyValue( "ListId" ) >>= msListId; - - if (xPropState.is()) - { - mbListIdIsDefault - = xPropState->getPropertyState("ListId") == PropertyState_DEFAULT_VALUE; - } } + mbListIdIsDefault = bListIdIsDefault; + mbContinueingPreviousSubTree = false; if( xPropSetInfo->hasPropertyByName( "ContinueingPreviousSubTree" ) ) { diff --git a/xmloff/source/text/XMLTextNumRuleInfo.hxx b/xmloff/source/text/XMLTextNumRuleInfo.hxx index adb405411164..7cbc3cf8d4fb 100644 --- a/xmloff/source/text/XMLTextNumRuleInfo.hxx +++ b/xmloff/source/text/XMLTextNumRuleInfo.hxx @@ -66,9 +66,10 @@ public: inline XMLTextNumRuleInfo& operator=( const XMLTextNumRuleInfo& rInfo ); void Set( const css::uno::Reference < css::text::XTextContent > & rTextContent, - const bool bOutlineStyleAsNormalListStyle, + bool bOutlineStyleAsNormalListStyle, const XMLTextListAutoStylePool& rListAutoPool, - const bool bExportTextNumberElement ); + bool bExportTextNumberElement, + bool bListIdIsDefault ); inline void Reset(); const OUString& GetNumRulesName() const diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx index d8a622bdd888..b2f12b0635e9 100644 --- a/xmloff/source/text/txtparae.cxx +++ b/xmloff/source/text/txtparae.cxx @@ -997,7 +997,7 @@ void XMLTextParagraphExport::exportListChange( // end a list if ( rPrevInfo.GetLevel() > 0 ) { - sal_Int16 nListLevelsToBeClosed = 0; + sal_uInt32 nListLevelsToBeClosed = 0; // unsigned larger type to safely multiply and compare if ( !rNextInfo.BelongsToSameList( rPrevInfo ) || rNextInfo.GetLevel() <= 0 ) { @@ -1007,13 +1007,11 @@ void XMLTextParagraphExport::exportListChange( else if ( rPrevInfo.GetLevel() > rNextInfo.GetLevel() ) { // close corresponding sub lists - SAL_WARN_IF( rNextInfo.GetLevel() <= 0, "xmloff", - "<rPrevInfo.GetLevel() > 0> not hold. Serious defect." ); nListLevelsToBeClosed = rPrevInfo.GetLevel() - rNextInfo.GetLevel(); } if ( nListLevelsToBeClosed > 0 && - maListElements.size() >= sal::static_int_cast< sal_uInt32 >( 2 * nListLevelsToBeClosed ) ) + maListElements.size() >= 2 * nListLevelsToBeClosed ) { do { for(size_t j = 0; j < 2; ++j) @@ -1031,11 +1029,6 @@ void XMLTextParagraphExport::exportListChange( } } - const bool bExportODF = - bool( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ); - const SvtSaveOptions::ODFSaneDefaultVersion eODFDefaultVersion = - GetExport().getSaneDefaultVersion(); - // start a new list if ( rNextInfo.GetLevel() > 0 ) { @@ -1051,8 +1044,6 @@ void XMLTextParagraphExport::exportListChange( else if ( rNextInfo.GetLevel() > rPrevInfo.GetLevel() ) { // open corresponding sub lists - SAL_WARN_IF( rPrevInfo.GetLevel() <= 0, "xmloff", - "<rPrevInfo.GetLevel() > 0> not hold. Serious defect." ); nListLevelsToBeOpened = rNextInfo.GetLevel() - rPrevInfo.GetLevel(); } @@ -1074,8 +1065,7 @@ void XMLTextParagraphExport::exportListChange( { if ( !mpTextListsHelper->IsListProcessed( sListId ) ) { - if ( bExportODF && - eODFDefaultVersion >= SvtSaveOptions::ODFSVER_012 && + if ( ExportListId() && !sListId.isEmpty() && !rNextInfo.IsListIdDefault() ) { /* Property text:id at element <text:list> has to be @@ -1093,8 +1083,7 @@ void XMLTextParagraphExport::exportListChange( { const OUString sNewListId( mpTextListsHelper->GenerateNewListId() ); - if ( bExportODF && - eODFDefaultVersion >= SvtSaveOptions::ODFSVER_012 && + if ( ExportListId() && !sListId.isEmpty() && !rNextInfo.IsListIdDefault() ) { /* Property text:id at element <text:list> has to be @@ -1124,8 +1113,7 @@ void XMLTextParagraphExport::exportListChange( } else { - if ( bExportODF && - eODFDefaultVersion >= SvtSaveOptions::ODFSVER_012 && + if ( ExportListId() && !sListId.isEmpty() ) { GetExport().AddAttribute( XML_NAMESPACE_TEXT, @@ -1808,6 +1796,127 @@ void XMLTextParagraphExport::exportText( pRedlineExport->ExportStartOrEndRedline( xPropertySet, false ); } +bool XMLTextParagraphExport::ExportListId() const +{ + return (GetExport().getExportFlags() & SvXMLExportFlags::OASIS) + && GetExport().getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012; +} + +struct XMLTextParagraphExport::DocumentListNodes +{ + struct NodeData + { + sal_Int32 index; // see SwNode::GetIndex and SwNodeOffset + sal_uInt64 style_id; // actually a pointer to NumRule + OUString list_id; + bool isRestart; + }; + std::vector<NodeData> docListNodes; + DocumentListNodes(const css::uno::Reference<css::frame::XModel>& xModel) + { + // Sequence of nodes, each of them represented by four-element sequence, + // corresponding to NodeData members + css::uno::Sequence<css::uno::Sequence<css::uno::Any>> nodes; + if (uno::Reference<beans::XPropertySet> xPropSet{ xModel, uno::UNO_QUERY }) + { + try + { + // See SwXTextDocument::getPropertyValue + xPropSet->getPropertyValue("ODFExport_ListNodes") >>= nodes; + } + catch (css::beans::UnknownPropertyException&) + { + // That's absolutely fine! + } + } + + docListNodes.reserve(nodes.getLength()); + for (const auto& node : nodes) + { + assert(node.getLength() == 4); + docListNodes.push_back({ node[0].get<sal_Int32>(), node[1].get<sal_uInt64>(), + node[2].get<OUString>(), node[3].get<bool>() }); + } + + std::sort(docListNodes.begin(), docListNodes.end(), + [](const NodeData& lhs, const NodeData& rhs) { return lhs.index < rhs.index; }); + } + bool ShouldSkipListId(const Reference<XTextContent>& xTextContent) const + { + if (docListNodes.empty()) + return false; + + if (uno::Reference<beans::XPropertySet> xPropSet{ xTextContent, uno::UNO_QUERY }) + { + sal_Int32 index = 0; + try + { + // See SwXParagraph::Impl::GetPropertyValues_Impl + xPropSet->getPropertyValue("ODFExport_NodeIndex") >>= index; + } + catch (css::beans::UnknownPropertyException&) + { + // That's absolutely fine! + return false; + } + + auto it = std::lower_bound(docListNodes.begin(), docListNodes.end(), index, + [](const NodeData& lhs, sal_Int32 rhs) + { return lhs.index < rhs; }); + if (it == docListNodes.end() || it->index != index) + return false; + + // We need to write the id, when there will be continuation of the list either with + // a different list style, or after another list. + + for (auto next = it + 1; next != docListNodes.end(); ++next) + { + if (it->list_id != next->list_id) + { + // List changed. We will have to refer to this id, only if there will + // appear a continuation of this list + return std::find_if(next + 1, docListNodes.end(), + [list_id = it->list_id](const NodeData& data) + { return data.list_id == list_id; }) + == docListNodes.end(); + } + + if (it->style_id != next->style_id) + { + // Same list, new style -> this "next" will refer to the id, no skipping + return false; + } + if (it->index + 1 != next->index) + { + // we have a gap before the next node with the same list and style, + // with no other lists in between. There will be a continuation; + // in case of restart, there will be a reference to the id; + // otherwise, there will be simple 'text:continue-numbering="true"'. + return !next->isRestart; + } + it = next; // walk through adjacent nodes of the same list + } + // all nodes were adjacent and of the same list and style -> no continuation, skip id + return true; + } + + return false; + } +}; + +bool XMLTextParagraphExport::ShouldSkipListId(const Reference<XTextContent>& xTextContent) +{ + if (!mpDocumentListNodes) + { + if (ExportListId()) + mpDocumentListNodes.reset(new DocumentListNodes(GetExport().GetModel())); + else + mpDocumentListNodes.reset(new DocumentListNodes({})); + } + + return mpDocumentListNodes->ShouldSkipListId(xTextContent); +} + void XMLTextParagraphExport::exportTextContentEnumeration( const Reference < XEnumeration > & rContEnum, bool bAutoStyles, @@ -1866,7 +1975,8 @@ void XMLTextParagraphExport::exportTextContentEnumeration( aNextNumInfo.Set( xTxtCntnt, GetExport().writeOutlineStyleAsNormalListStyle(), GetListAutoStylePool(), - GetExport().exportTextNumberElement() ); + GetExport().exportTextNumberElement(), + ShouldSkipListId(xTxtCntnt) ); exportListAndSectionChange( xCurrentTextSection, aPropSetHelper, TEXT_SECTION, xTxtCntnt, commit cf406a4b69a9a63a49ab57ad3668908eb6b77e38 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Mon Jun 12 12:23:17 2023 +0300 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Jun 18 11:55:02 2023 +0200 tdf#154349: round before converting to an integer Commit cfff893b9c82843a90aac4ecdb3a3936721b74a0 (Move unit conversion code to o3tl, and unify on that in more places, 2021-02-14) changed a custom conversion code in CalcToUnit doing inexact conversion from points to mm/20 (with "* 10 / 567"), with correct conversion function. A side effect was, however, that the imprecise arithmetics provided floating-point values that rounded down to correct integers (or maybe it was all the chain of calculations down to this function), while the correctly converted values could round down to a smaller value. Fix this problem using rounding. Change-Id: I42e0d56b068832ef309f6b696f661642e62ddacb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152894 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit cf0fe26f95b5435d65623165cf7ba381eaa0738a) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152981 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/svtools/source/misc/unitconv.cxx b/svtools/source/misc/unitconv.cxx index 395c1b4ac810..cb4fdf6901dd 100644 --- a/svtools/source/misc/unitconv.cxx +++ b/svtools/source/misc/unitconv.cxx @@ -128,7 +128,7 @@ tools::Long CalcToUnit( float nIn, MapUnit eUnit ) eUnit == MapUnit::MapCM, "this unit is not implemented" ); if (const auto eTo = MapToO3tlLength(eUnit); eTo != o3tl::Length::invalid) - return o3tl::convert(nIn, o3tl::Length::pt, eTo); + return std::round(o3tl::convert(nIn, o3tl::Length::pt, eTo)); return 0; } commit 9cdaf24fee972f2c3d3a6a765a6b3cee87fe0c4d Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Wed Jun 14 01:10:50 2023 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Jun 18 11:55:02 2023 +0200 tdf#155819: check marker property comes from a style sheet Since 242b7d0162d55be0945ca849c3de841fbf6cb475 "svgio: simplify code" where bIsInStyleSheet was replaced by getCssStyleParent() incorrectly Change-Id: I48632e9374f4615e32d18a141aeabec2936e6ec8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153016 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153036 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx index 6e4ac0255677..c8305517ce00 100644 --- a/svgio/qa/cppunit/SvgImportTest.cxx +++ b/svgio/qa/cppunit/SvgImportTest.cxx @@ -135,6 +135,24 @@ CPPUNIT_TEST_FIXTURE(Test, testSymbol) assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#00d000"); } +CPPUNIT_TEST_FIXTURE(Test, testTdf155819) +{ + Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf155819.svg"); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); + + drawinglayer::Primitive2dXmlDump dumper; + xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequence); + + CPPUNIT_ASSERT (pDocument); + + assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/line", 1); + assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/polypolygon", 1); + // Without the fix in place, this test would have failed with + // - Expected: 4 + // - Actual : 0 + assertXPath(pDocument, "/primitive2D/transform/transform", 4); +} + CPPUNIT_TEST_FIXTURE(Test, testTdf87309) { Primitive2DSequence aSequenceTdf87309 = parseSvg(u"/svgio/qa/cppunit/data/tdf87309.svg"); diff --git a/svgio/qa/cppunit/data/tdf155819.svg b/svgio/qa/cppunit/data/tdf155819.svg new file mode 100644 index 000000000000..30c2da4d1a5a --- /dev/null +++ b/svgio/qa/cppunit/data/tdf155819.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 100 100"> + <style> + path { + fill: none; + stroke-width: 4px; + marker: url(#diamond); + } + </style> + <path d="M 10,50 v -20 h 40 v -20" stroke="red"/> + <marker id="diamond" markerWidth="12" markerHeight="12" refX="6" refY="6" markerUnits="userSpaceOnUse"> + <circle cx="6" cy="6" r="3" + fill="white" stroke="context-stroke" stroke-width="2"/> + </marker> +</svg> diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx index 8661b99d8895..6c42fbe744f9 100644 --- a/svgio/source/svgreader/svgstyleattributes.cxx +++ b/svgio/source/svgreader/svgstyleattributes.cxx @@ -1150,7 +1150,7 @@ namespace svgio::svgreader if(SVGToken::Path == mrOwner.getType() || // path SVGToken::Polygon == mrOwner.getType() || // polygon, polyline SVGToken::Line == mrOwner.getType() || // line - getCssStyleParent()) + SVGToken::Style == mrOwner.getType()) // tdf#150323 { // try to add markers add_markers(rPath, rTarget, pHelpPointIndices); @@ -1877,7 +1877,8 @@ namespace svgio::svgreader } case SVGToken::Marker: { - if(getCssStyleParent()) + // tdf#155819: Using the marker property from a style sheet is equivalent to using all three (start, mid, end). + if(mrOwner.getType() == SVGToken::Style) { readLocalUrl(aContent, maMarkerEndXLink); maMarkerStartXLink = maMarkerMidXLink = maMarkerEndXLink; commit c413170ea49aa6501184e2b33f8f712eeaee7ccc Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Thu Jun 8 13:49:11 2023 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Jun 18 11:55:01 2023 +0200 tdf#155733: no need to store these values Remove the unittest in libreoffice-7-5 since the sample file uses <filter id="myFilter"> <feGaussianBlur in="SourceGraphic" stdDeviation="5"/> </filter> which is not supported in this branch Change-Id: I1c22f8f344731eb5fbc5f77fc80267ebcdc81ed6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152740 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit 9662b23182174888045726fd57bf7d93c16cf4fb) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152757 Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153037 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx index ffdebc2f36a4..8661b99d8895 100644 --- a/svgio/source/svgreader/svgstyleattributes.cxx +++ b/svgio/source/svgreader/svgstyleattributes.cxx @@ -2866,7 +2866,7 @@ namespace svgio::svgreader if(!aClipPath.isEmpty()) { - const_cast< SvgStyleAttributes* >(this)->mpClipPathXLink = dynamic_cast< const SvgClipPathNode* >(mrOwner.getDocument().findSvgNodeById(aClipPath)); + return dynamic_cast< const SvgClipPathNode* >(mrOwner.getDocument().findSvgNodeById(aClipPath)); } } @@ -2901,7 +2901,7 @@ namespace svgio::svgreader if(!aMask.isEmpty()) { - const_cast< SvgStyleAttributes* >(this)->mpMaskXLink = dynamic_cast< const SvgMaskNode* >(mrOwner.getDocument().findSvgNodeById(aMask)); + return dynamic_cast< const SvgMaskNode* >(mrOwner.getDocument().findSvgNodeById(aMask)); } } @@ -2936,7 +2936,7 @@ namespace svgio::svgreader if(!aMarker.isEmpty()) { - const_cast< SvgStyleAttributes* >(this)->mpMarkerStartXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerStartXLink())); + return dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerStartXLink())); } } @@ -2971,7 +2971,7 @@ namespace svgio::svgreader if(!aMarker.isEmpty()) { - const_cast< SvgStyleAttributes* >(this)->mpMarkerMidXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerMidXLink())); + return dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerMidXLink())); } } @@ -3006,7 +3006,7 @@ namespace svgio::svgreader if(!aMarker.isEmpty()) { - const_cast< SvgStyleAttributes* >(this)->mpMarkerEndXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerEndXLink())); + return dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerEndXLink())); } } commit 11e6791b883e13a96caa7cf9275c2512187a551a Author: Taichi Haradaguchi <20001...@ymail.ne.jp> AuthorDate: Sun Jun 11 17:36:54 2023 +0900 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Jun 18 11:55:01 2023 +0200 openssl: upgrade to release 3.0.9 Fixes CVE-2023-1255, CVE-2023-2650 and 3 more CVEs that probably don't affect LibreOffice. Change-Id: Ic615b008298471267121a0f4deb227ddb3a0409e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152851 Tested-by: Jenkins Reviewed-by: Taichi Haradaguchi <20001...@ymail.ne.jp> (cherry picked from commit 2137d04d1ddb80691c29de0df99fc2ba58820ce0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152970 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit 66ccf3207806776d13203b7bdbea760128e37d10) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152977 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/download.lst b/download.lst index c814272aa577..5a3a228e35d7 100644 --- a/download.lst +++ b/download.lst @@ -482,8 +482,8 @@ OPENLDAP_TARBALL := openldap-2.4.59.tgz # three static lines # so that git cherry-pick # will not run into conflicts -OPENSSL_SHA256SUM := 6c13d2bf38fdf31eac3ce2a347073673f5d63263398f1f69d0df4a41253e4b3e -OPENSSL_TARBALL := openssl-3.0.8.tar.gz +OPENSSL_SHA256SUM := eb1ab04781474360f77c318ab89d8c5a03abc38e63d65a603cabbf1b00a1dc90 +OPENSSL_TARBALL := openssl-3.0.9.tar.gz # three static lines # so that git cherry-pick # will not run into conflicts diff --git a/external/openssl/0001-x509-excessive-resource-use-verifying-policy-constra.patch.1 b/external/openssl/0001-x509-excessive-resource-use-verifying-policy-constra.patch.1 deleted file mode 100644 index d96d1d76883e..000000000000 --- a/external/openssl/0001-x509-excessive-resource-use-verifying-policy-constra.patch.1 +++ /dev/null @@ -1,221 +0,0 @@ -From 959c59c7a0164117e7f8366466a32bb1f8d77ff1 Mon Sep 17 00:00:00 2001 -From: Pauli <pa...@openssl.org> -Date: Wed, 8 Mar 2023 15:28:20 +1100 -Subject: [PATCH] x509: excessive resource use verifying policy constraints - -A security vulnerability has been identified in all supported versions -of OpenSSL related to the verification of X.509 certificate chains -that include policy constraints. Attackers may be able to exploit this -vulnerability by creating a malicious certificate chain that triggers -exponential use of computational resources, leading to a denial-of-service -(DoS) attack on affected systems. - -Fixes CVE-2023-0464 - -Reviewed-by: Tomas Mraz <to...@openssl.org> -Reviewed-by: Shane Lontis <shane.lon...@oracle.com> -(Merged from https://github.com/openssl/openssl/pull/20568) ---- - crypto/x509/pcy_local.h | 8 +++++++- - crypto/x509/pcy_node.c | 12 +++++++++--- - crypto/x509/pcy_tree.c | 36 ++++++++++++++++++++++++++---------- - 3 files changed, 42 insertions(+), 14 deletions(-) - -diff --git a/crypto/x509/pcy_local.h b/crypto/x509/pcy_local.h -index 18b53cc09e..cba107ca03 100644 ---- a/crypto/x509/pcy_local.h -+++ b/crypto/x509/pcy_local.h -@@ -111,6 +111,11 @@ struct X509_POLICY_LEVEL_st { - }; - - struct X509_POLICY_TREE_st { -+ /* The number of nodes in the tree */ -+ size_t node_count; -+ /* The maximum number of nodes in the tree */ -+ size_t node_maximum; -+ - /* This is the tree 'level' data */ - X509_POLICY_LEVEL *levels; - int nlevel; -@@ -157,7 +162,8 @@ X509_POLICY_NODE *ossl_policy_tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, - X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, -- X509_POLICY_TREE *tree); -+ X509_POLICY_TREE *tree, -+ int extra_data); - void ossl_policy_node_free(X509_POLICY_NODE *node); - int ossl_policy_node_match(const X509_POLICY_LEVEL *lvl, - const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); -diff --git a/crypto/x509/pcy_node.c b/crypto/x509/pcy_node.c -index 9d9a7ea179..450f95a655 100644 ---- a/crypto/x509/pcy_node.c -+++ b/crypto/x509/pcy_node.c -@@ -59,10 +59,15 @@ X509_POLICY_NODE *ossl_policy_level_find_node(const X509_POLICY_LEVEL *level, - X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, -- X509_POLICY_TREE *tree) -+ X509_POLICY_TREE *tree, -+ int extra_data) - { - X509_POLICY_NODE *node; - -+ /* Verify that the tree isn't too large. This mitigates CVE-2023-0464 */ -+ if (tree->node_maximum > 0 && tree->node_count >= tree->node_maximum) -+ return NULL; -+ - node = OPENSSL_zalloc(sizeof(*node)); - if (node == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); -@@ -70,7 +75,7 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, - } - node->data = data; - node->parent = parent; -- if (level) { -+ if (level != NULL) { - if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { - if (level->anyPolicy) - goto node_error; -@@ -90,7 +95,7 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, - } - } - -- if (tree) { -+ if (extra_data) { - if (tree->extra_data == NULL) - tree->extra_data = sk_X509_POLICY_DATA_new_null(); - if (tree->extra_data == NULL){ -@@ -103,6 +108,7 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, - } - } - -+ tree->node_count++; - if (parent) - parent->nchild++; - -diff --git a/crypto/x509/pcy_tree.c b/crypto/x509/pcy_tree.c -index fa45da5117..f953a05a41 100644 ---- a/crypto/x509/pcy_tree.c -+++ b/crypto/x509/pcy_tree.c -@@ -14,6 +14,17 @@ - - #include "pcy_local.h" - -+/* -+ * If the maximum number of nodes in the policy tree isn't defined, set it to -+ * a generous default of 1000 nodes. -+ * -+ * Defining this to be zero means unlimited policy tree growth which opens the -+ * door on CVE-2023-0464. -+ */ -+#ifndef OPENSSL_POLICY_TREE_NODES_MAX -+# define OPENSSL_POLICY_TREE_NODES_MAX 1000 -+#endif -+ - static void expected_print(BIO *channel, - X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node, - int indent) -@@ -163,6 +174,9 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, - return X509_PCY_TREE_INTERNAL; - } - -+ /* Limit the growth of the tree to mitigate CVE-2023-0464 */ -+ tree->node_maximum = OPENSSL_POLICY_TREE_NODES_MAX; -+ - /* - * http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3. - * -@@ -180,7 +194,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, - if ((data = ossl_policy_data_new(NULL, - OBJ_nid2obj(NID_any_policy), 0)) == NULL) - goto bad_tree; -- if (ossl_policy_level_add_node(level, data, NULL, tree) == NULL) { -+ if (ossl_policy_level_add_node(level, data, NULL, tree, 1) == NULL) { - ossl_policy_data_free(data); - goto bad_tree; - } -@@ -239,7 +253,8 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, - * Return value: 1 on success, 0 otherwise - */ - static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, -- X509_POLICY_DATA *data) -+ X509_POLICY_DATA *data, -+ X509_POLICY_TREE *tree) - { - X509_POLICY_LEVEL *last = curr - 1; - int i, matched = 0; -@@ -249,13 +264,13 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, - X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i); - - if (ossl_policy_node_match(last, node, data->valid_policy)) { -- if (ossl_policy_level_add_node(curr, data, node, NULL) == NULL) -+ if (ossl_policy_level_add_node(curr, data, node, tree, 0) == NULL) - return 0; - matched = 1; - } - } - if (!matched && last->anyPolicy) { -- if (ossl_policy_level_add_node(curr, data, last->anyPolicy, NULL) == NULL) -+ if (ossl_policy_level_add_node(curr, data, last->anyPolicy, tree, 0) == NULL) - return 0; - } - return 1; -@@ -268,7 +283,8 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, - * Return value: 1 on success, 0 otherwise. - */ - static int tree_link_nodes(X509_POLICY_LEVEL *curr, -- const X509_POLICY_CACHE *cache) -+ const X509_POLICY_CACHE *cache, -+ X509_POLICY_TREE *tree) - { - int i; - -@@ -276,7 +292,7 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr, - X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i); - - /* Look for matching nodes in previous level */ -- if (!tree_link_matching_nodes(curr, data)) -+ if (!tree_link_matching_nodes(curr, data, tree)) - return 0; - } - return 1; -@@ -307,7 +323,7 @@ static int tree_add_unmatched(X509_POLICY_LEVEL *curr, - /* Curr may not have anyPolicy */ - data->qualifier_set = cache->anyPolicy->qualifier_set; - data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; -- if (ossl_policy_level_add_node(curr, data, node, tree) == NULL) { -+ if (ossl_policy_level_add_node(curr, data, node, tree, 1) == NULL) { - ossl_policy_data_free(data); - return 0; - } -@@ -370,7 +386,7 @@ static int tree_link_any(X509_POLICY_LEVEL *curr, - /* Finally add link to anyPolicy */ - if (last->anyPolicy && - ossl_policy_level_add_node(curr, cache->anyPolicy, -- last->anyPolicy, NULL) == NULL) -+ last->anyPolicy, tree, 0) == NULL) - return 0; - return 1; - } -@@ -553,7 +569,7 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree, - extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS - | POLICY_DATA_FLAG_EXTRA_NODE; - node = ossl_policy_level_add_node(NULL, extra, anyPolicy->parent, -- tree); -+ tree, 1); - } - if (!tree->user_policies) { - tree->user_policies = sk_X509_POLICY_NODE_new_null(); -@@ -580,7 +596,7 @@ static int tree_evaluate(X509_POLICY_TREE *tree) - - for (i = 1; i < tree->nlevel; i++, curr++) { - cache = ossl_policy_cache_set(curr->cert); -- if (!tree_link_nodes(curr, cache)) -+ if (!tree_link_nodes(curr, cache, tree)) - return X509_PCY_TREE_INTERNAL; - - if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) --- -2.34.1 - diff --git a/external/openssl/README b/external/openssl/README index 399bdd56fded..eda5e7eb17ec 100644 --- a/external/openssl/README +++ b/external/openssl/README @@ -1,6 +1,6 @@ Open Source toolkit implementing SSL and TLS. -From [http://www.openssl.org/]. +From [https://www.openssl.org/]. SSL = Secure Sockets Layer (SSL v2/v3) protocol. TLS = Transport Layer Security (TLS v1) protocol. diff --git a/external/openssl/UnpackedTarball_openssl.mk b/external/openssl/UnpackedTarball_openssl.mk index 99d3797dd81b..2a8f3bb3f905 100644 --- a/external/openssl/UnpackedTarball_openssl.mk +++ b/external/openssl/UnpackedTarball_openssl.mk @@ -12,12 +12,10 @@ $(eval $(call gb_UnpackedTarball_UnpackedTarball,openssl)) $(eval $(call gb_UnpackedTarball_set_tarball,openssl,$(OPENSSL_TARBALL),,openssl)) $(eval $(call gb_UnpackedTarball_add_patches,openssl,\ - external/openssl/0001-x509-excessive-resource-use-verifying-policy-constra.patch.1 \ external/openssl/openssl-no-multilib.patch.0 \ external/openssl/configurable-z-option.patch.0 \ external/openssl/openssl-no-ipc-cmd.patch.0 \ external/openssl/system-cannot-find-path-for-move.patch.0 \ - external/openssl/openssl-no-_umul128-on-aarch64.patch.1 \ )) # vim: set noet sw=4 ts=4: diff --git a/external/openssl/openssl-no-_umul128-on-aarch64.patch.1 b/external/openssl/openssl-no-_umul128-on-aarch64.patch.1 deleted file mode 100644 index c7ca53bc574c..000000000000 --- a/external/openssl/openssl-no-_umul128-on-aarch64.patch.1 +++ /dev/null @@ -1,58 +0,0 @@ -From 98f9a401c3964c7ff0e6ca048685e28a2a6401d4 Mon Sep 17 00:00:00 2001 -From: Hubert Kario <hka...@redhat.com> -Date: Wed, 8 Feb 2023 14:13:24 +0100 -Subject: [PATCH] rsa: add msvc intrinsic for non x64 platforms - -_umul128() is x86_64 (x64) only, while __umulh() works everywhere, but -doesn't generate optimal code on x64 - -Reviewed-by: Dmitry Belyavskiy <beld...@gmail.com> -Reviewed-by: Paul Dale <pa...@openssl.org> -Reviewed-by: Tomas Mraz <to...@openssl.org> -(Merged from https://github.com/openssl/openssl/pull/20244) - -(cherry picked from commit 075652f224479dad2e64b92e791b296177af8705) ---- - crypto/bn/rsa_sup_mul.c | 24 +++++++++++++++++++++++- - 1 file changed, 23 insertions(+), 1 deletion(-) - -diff --git a/crypto/bn/rsa_sup_mul.c b/crypto/bn/rsa_sup_mul.c -index 0e0d02e1946e..3b57161b4589 100644 ---- a/crypto/bn/rsa_sup_mul.c -+++ b/crypto/bn/rsa_sup_mul.c -@@ -110,12 +110,34 @@ static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b) - *lo = (limb_t)t; - } - #elif (BN_BYTES == 8) && (defined _MSC_VER) --/* https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-170 */ -+# if defined(_M_X64) -+/* -+ * on x86_64 (x64) we can use the _umul128 intrinsic to get one `mul` -+ * instruction to get both high and low 64 bits of the multiplication. -+ * https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-140 -+ */ -+#include <intrin.h> - #pragma intrinsic(_umul128) - static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b) - { - *lo = _umul128(a, b, hi); - } -+# elif defined(_M_ARM64) || defined (_M_IA64) -+/* -+ * We can't use the __umulh() on x86_64 as then msvc generates two `mul` -+ * instructions; so use this more portable intrinsic on platforms that -+ * don't support _umul128 (like aarch64 (ARM64) or ia64) -+ * https://learn.microsoft.com/en-us/cpp/intrinsics/umulh?view=msvc-140 -+ */ -+#include <intrin.h> -+static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b) -+{ -+ *lo = a * b; -+ *hi = __umulh(a, b); -+} -+# else -+# error Only x64, ARM64 and IA64 supported. -+# endif /* defined(_M_X64) */ - #else - /* - * if the compiler doesn't have either a 128bit data type nor a "return commit cbdb9359bc77ebe7f79340cf0322fb2e4d78b125 Author: Taichi Haradaguchi <20001...@ymail.ne.jp> AuthorDate: Sat Jun 10 15:57:28 2023 +0900 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Jun 18 11:55:01 2023 +0200 curl: upgrade to release 8.1.2 Fixes CVE-2023-28321, CVE-2023-28322, and 2 more CVEs that probably don't affect LibreOffice. Change-Id: If8720ba3647216063bffc8678aa64dad9a317128 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152809 Tested-by: Jenkins Reviewed-by: Taichi Haradaguchi <20001...@ymail.ne.jp> Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit dc19ef0d42e89edffcc21795194eb1eeb5957d0f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152888 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/download.lst b/download.lst index 3e85500ccc18..c814272aa577 100644 --- a/download.lst +++ b/download.lst @@ -75,8 +75,8 @@ CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz # three static lines # so that git cherry-pick # will not run into conflicts -CURL_SHA256SUM := 0a381cd82f4d00a9a334438b8ca239afea5bfefcfa9a1025f2bf118e79e0b5f0 -CURL_TARBALL := curl-8.0.1.tar.xz +CURL_SHA256SUM := 31b1118eb8bfd43cd95d9a3f146f814ff874f6ed3999b29d94f4d1e7dbac5ef6 +CURL_TARBALL := curl-8.1.2.tar.xz # three static lines # so that git cherry-pick # will not run into conflicts diff --git a/external/curl/README b/external/curl/README index 292e4edf57b6..4a7044623608 100644 --- a/external/curl/README +++ b/external/curl/README @@ -1 +1 @@ -A URL manipulation engine from [http://curl.haxx.se/]. +A URL manipulation engine from [https://curl.se/]. commit 363e27a6833d5c33b634566503529a9e6d866a96 Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Mon Jun 12 11:01:05 2023 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Jun 18 11:55:01 2023 +0200 Revert "tdf#143877 EMF+ Implement EmfPlusDrawCurve with cardinal spline" This reverts commit 62d5a612f1a3c8180c0e5059e8e05e0bedc9629b. Reason for revert: it seems it causes some builds to fail: see https://gerrit.libreoffice.org/c/core/+/152288. Reverting in libreoffice-7-5 branch for now. In master the test should be fixed instead. Change-Id: I7a1af911aa20761d4e94bfcabaaccc27401b0971 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152878 Reviewed-by: Bartosz Kosiorek <gan...@poczta.onet.pl> Tested-by: Jenkins Reviewed-by: René Engelhard <r...@debian.org> diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx index 03b270228628..94c4c32f026f 100644 --- a/drawinglayer/source/tools/emfphelperdata.cxx +++ b/drawinglayer/source/tools/emfphelperdata.cxx @@ -81,8 +81,6 @@ namespace emfplushelper case EmfPlusRecordTypeFillPolygon: return "EmfPlusRecordTypeFillPolygon"; case EmfPlusRecordTypeDrawLines: return "EmfPlusRecordTypeDrawLines"; case EmfPlusRecordTypeFillClosedCurve: return "EmfPlusRecordTypeFillClosedCurve"; - case EmfPlusRecordTypeDrawClosedCurve: return "EmfPlusRecordTypeDrawClosedCurve"; - case EmfPlusRecordTypeDrawCurve: return "EmfPlusRecordTypeDrawCurve"; case EmfPlusRecordTypeFillEllipse: return "EmfPlusRecordTypeFillEllipse"; case EmfPlusRecordTypeDrawEllipse: return "EmfPlusRecordTypeDrawEllipse"; case EmfPlusRecordTypeFillPie: return "EmfPlusRecordTypeFillPie"; @@ -92,6 +90,7 @@ namespace emfplushelper case EmfPlusRecordTypeFillPath: return "EmfPlusRecordTypeFillPath"; case EmfPlusRecordTypeDrawPath: return "EmfPlusRecordTypeDrawPath"; case EmfPlusRecordTypeDrawBeziers: return "EmfPlusRecordTypeDrawBeziers"; + case EmfPlusRecordTypeDrawClosedCurve: return "EmfPlusRecordTypeDrawClosedCurve"; case EmfPlusRecordTypeDrawImage: return "EmfPlusRecordTypeDrawImage"; case EmfPlusRecordTypeDrawImagePoints: return "EmfPlusRecordTypeDrawImagePoints"; case EmfPlusRecordTypeDrawString: return "EmfPlusRecordTypeDrawString"; @@ -1384,30 +1383,6 @@ namespace emfplushelper EMFPPlusDrawPolygon(::basegfx::B2DPolyPolygon(aPolygon), flags & 0xff); break; } - case EmfPlusRecordTypeDrawCurve: - { - sal_uInt32 aOffset, aNumSegments, points; - float aTension; - rMS.ReadFloat(aTension); - rMS.ReadUInt32(aOffset); - rMS.ReadUInt32(aNumSegments); - rMS.ReadUInt32(points); - SAL_WARN("drawinglayer.emf", - "EMF+\t Tension: " << aTension << " Offset: " << aOffset - << " NumSegments: " << aNumSegments - << " Points: " << points); - - EMFPPath path(points, true); - path.Read(rMS, flags); - - if (points >= 2) - EMFPPlusDrawPolygon( - path.GetCardinalSpline(*this, aTension, aOffset, aNumSegments), - flags & 0xff); - else - SAL_WARN("drawinglayer.emf", "Not enough number of points"); - break; - } case EmfPlusRecordTypeDrawClosedCurve: case EmfPlusRecordTypeFillClosedCurve: { @@ -1417,29 +1392,28 @@ namespace emfplushelper if (type == EmfPlusRecordTypeFillClosedCurve) { rMS.ReadUInt32(brushIndexOrColor); - SAL_INFO( - "drawinglayer.emf", + SAL_INFO("drawinglayer.emf", "EMF+\t Fill Mode: " << (flags & 0x2000 ? "Winding" : "Alternate")); } rMS.ReadFloat(aTension); rMS.ReadUInt32(points); SAL_WARN("drawinglayer.emf", - "EMF+\t Tension: " << aTension << " Points: " << points); + "EMF+\t Tension: " << aTension << " Points: " << points); + SAL_WARN_IF(aTension != 0, "drawinglayer.emf", + "EMF+\t TODO Add support for tension different than 0"); SAL_INFO("drawinglayer.emf", - "EMF+\t " << (flags & 0x8000 ? "Color" : "Brush index") << " : 0x" - << std::hex << brushIndexOrColor << std::dec); - if (points < 3) - { - SAL_WARN("drawinglayer.emf", "Not enough number of points"); - break; - } + "EMF+\t " << (flags & 0x8000 ? "Color" : "Brush index") << " : 0x" + << std::hex << brushIndexOrColor << std::dec); + EMFPPath path(points, true); path.Read(rMS, flags); if (type == EmfPlusRecordTypeFillClosedCurve) - EMFPPlusFillPolygon(path.GetClosedCardinalSpline(*this, aTension), + EMFPPlusFillPolygon(path.GetPolygon(*this, /* bMapIt */ true, + /*bAddLineToCloseShape */ true), flags & 0x8000, brushIndexOrColor); else - EMFPPlusDrawPolygon(path.GetClosedCardinalSpline(*this, aTension), + EMFPPlusDrawPolygon(path.GetPolygon(*this, /* bMapIt */ true, + /*bAddLineToCloseShape */ true), flags & 0xff); break; } @@ -1466,7 +1440,7 @@ namespace emfplushelper ::tools::Rectangle aSource(Point(sx, sy), Size(sw + 1, sh + 1)); SAL_INFO("drawinglayer.emf", - "EMF+\t " + "EMF+\t " << (type == EmfPlusRecordTypeDrawImage ? "DrawImage" : "DrawImagePoints") << " source rectangle: " << sx << "," << sy << " " << sw << "x" @@ -1544,8 +1518,8 @@ namespace emfplushelper SAL_INFO( "drawinglayer.emf", "EMF+\t TODO: Add support for SrcRect to ImageDataTypeMetafile"); - const ::basegfx::B2DPoint aDstPoint(dx, dy); - const ::basegfx::B2DSize aDstSize(dw, dh); + ::basegfx::B2DPoint aDstPoint(dx, dy); + ::basegfx::B2DSize aDstSize(dw, dh); const basegfx::B2DHomMatrix aTransformMatrix = maMapTransform diff --git a/drawinglayer/source/tools/emfphelperdata.hxx b/drawinglayer/source/tools/emfphelperdata.hxx index cf9e3b8855d6..ef870f31e687 100644 --- a/drawinglayer/source/tools/emfphelperdata.hxx +++ b/drawinglayer/source/tools/emfphelperdata.hxx @@ -56,7 +56,7 @@ namespace emfplushelper #define EmfPlusRecordTypeDrawPath 0x4015 #define EmfPlusRecordTypeFillClosedCurve 0x4016 #define EmfPlusRecordTypeDrawClosedCurve 0x4017 - #define EmfPlusRecordTypeDrawCurve 0x4018 + //TODO EmfPlusRecordTypeDrawCurve 0x4018 #define EmfPlusRecordTypeDrawBeziers 0x4019 #define EmfPlusRecordTypeDrawImage 0x401A #define EmfPlusRecordTypeDrawImagePoints 0x401B diff --git a/drawinglayer/source/tools/emfppath.cxx b/drawinglayer/source/tools/emfppath.cxx index bd5b2d357b0f..4217e3616087 100644 --- a/drawinglayer/source/tools/emfppath.cxx +++ b/drawinglayer/source/tools/emfppath.cxx @@ -34,8 +34,6 @@ namespace namespace emfplushelper { - typedef float matrix [4][4]; - // see 2.2.2.21 EmfPlusInteger7 // 2.2.2.22 EmfPlusInteger15 // and 2.2.2.37 EmfPlusPointR Object @@ -67,6 +65,7 @@ namespace emfplushelper } nPoints = _nPoints; + pPoints.reset( new float [nPoints*2] ); if (!bLines) pPointTypes.reset( new sal_uInt8 [_nPoints] ); @@ -78,8 +77,7 @@ namespace emfplushelper void EMFPPath::Read (SvStream& s, sal_uInt32 pathFlags) { - float fx, fy; - for (sal_uInt32 i = 0; i < nPoints; i++) + for (sal_uInt32 i = 0; i < nPoints; i ++) { if (pathFlags & 0x800) { @@ -88,8 +86,8 @@ namespace emfplushelper // If 0x800 bit is set, the 0x4000 bit is undefined and must be ignored sal_Int32 x = GetEmfPlusInteger(s); sal_Int32 y = GetEmfPlusInteger(s); - xPoints.push_back(x); - yPoints.push_back(y); + pPoints [i*2] = x; + pPoints [i*2 + 1] = y; SAL_INFO("drawinglayer.emf", "EMF+\t\t\t" << i << ". EmfPlusPointR [x,y]: " << x << ", " << y); } else if (pathFlags & 0x4000) @@ -97,18 +95,16 @@ namespace emfplushelper // EMFPlusPoint: stored in signed short 16bit integer format sal_Int16 x, y; - s.ReadInt16(x).ReadInt16(y); - SAL_INFO("drawinglayer.emf", "EMF+\t\t\t" << i << ". EmfPlusPoint [x,y]: " << x << ", " << y); - xPoints.push_back(x); - yPoints.push_back(y); + s.ReadInt16( x ).ReadInt16( y ); + SAL_INFO ("drawinglayer.emf", "EMF+\t\t\t" << i << ". EmfPlusPoint [x,y]: " << x << ", " << y); + pPoints [i*2] = x; + pPoints [i*2 + 1] = y; } else { // EMFPlusPointF: stored in Single (float) format - s.ReadFloat(fx).ReadFloat(fy); - SAL_INFO("drawinglayer.emf", "EMF+\t" << i << ". EMFPlusPointF [x,y]: " << fx << ", " << fy); - xPoints.push_back(fx); - yPoints.push_back(fy); + s.ReadFloat( pPoints [i*2] ).ReadFloat( pPoints [i*2 + 1] ); + SAL_INFO("drawinglayer.emf", "EMF+\t" << i << ". EMFPlusPointF [x,y]: " << pPoints [i * 2] << ", " << pPoints [i * 2 + 1]); } } @@ -132,7 +128,7 @@ namespace emfplushelper ::basegfx::B2DPoint prev, mapped; bool hasPrev = false; - for (sal_uInt32 i = 0; i < nPoints; i++) + for (sal_uInt32 i = 0; i < nPoints; i ++) { if (p && pPointTypes && (pPointTypes [i] == 0)) { @@ -143,9 +139,9 @@ namespace emfplushelper } if (bMapIt) - mapped = rR.Map(xPoints[i], yPoints [i]); + mapped = rR.Map (pPoints [i*2], pPoints [i*2 + 1]); else - mapped = ::basegfx::B2DPoint(xPoints[i], yPoints[i]); + mapped = ::basegfx::B2DPoint (pPoints [i*2], pPoints [i*2 + 1]); if (pPointTypes) { @@ -171,7 +167,7 @@ namespace emfplushelper } polygon.append (mapped); - SAL_INFO ("drawinglayer.emf", "EMF+\t\tPoint: " << xPoints[i] << "," << yPoints[i] << " mapped: " << mapped.getX () << ":" << mapped.getY ()); + SAL_INFO ("drawinglayer.emf", "EMF+\t\tPoint: " << pPoints [i*2] << "," << pPoints [i*2 + 1] << " mapped: " << mapped.getX () << ":" << mapped.getY ()); if (hasPrev) { @@ -225,100 +221,6 @@ namespace emfplushelper return aPolygon; } - - static void GetCardinalMatrix(float tension, matrix& m) - { - m[0][1] = 2. - tension; - m[0][2] = tension - 2.; - m[1][0] = 2. * tension; - m[1][1] = tension - 3.; - m[1][2] = 3. - 2 * tension; - m[3][1] = 1.; - m[0][3] = m[2][2] = tension; - m[0][0] = m[1][3] = m[2][0] = -tension; - m[2][1] = m[2][3] = m[3][0] = m[3][2] = m[3][3] = 0.; - } - - static float calculateSplineCoefficients(float p0, float p1, float p2, float p3, float alpha, matrix m) - { - float a, b, c, d; - a = m[0][0] * p0 + m[0][1] * p1 + m[0][2] * p2 + m[0][3] * p3; - b = m[1][0] * p0 + m[1][1] * p1 + m[1][2] * p2 + m[1][3] * p3; - c = m[2][0] * p0 + m[2][2] * p2; - d = p1; - return (d + alpha * (c + alpha * (b + alpha * a))); - } - - ::basegfx::B2DPolyPolygon& EMFPPath::GetCardinalSpline(EmfPlusHelperData const& rR, float fTension, - sal_uInt32 aOffset, sal_uInt32 aNumSegments) - { - ::basegfx::B2DPolygon polygon; - matrix mat; - float x, y; - constexpr sal_uInt32 nDetails = 8; - constexpr float alpha[nDetails] - = { 1. / nDetails, 2. / nDetails, 3. / nDetails, 4. / nDetails, - 5. / nDetails, 6. / nDetails, 7. / nDetails, 8. / nDetails }; - if (aNumSegments >= nPoints) - aNumSegments = nPoints - 1; - GetCardinalMatrix(fTension, mat); - // duplicate first point - xPoints.push_front(xPoints.front()); - yPoints.push_front(yPoints.front()); - // duplicate last point - xPoints.push_back(xPoints.back()); - yPoints.push_back(yPoints.back()); - - for (sal_uInt32 i = 3 + aOffset; i < aNumSegments + 3; i++) - { - for (sal_uInt32 s = 0; s < nDetails; s++) - { - x = calculateSplineCoefficients(xPoints[i - 3], xPoints[i - 2], xPoints[i - 1], - xPoints[i], alpha[s], mat); - y = calculateSplineCoefficients(yPoints[i - 3], yPoints[i - 2], yPoints[i - 1], - yPoints[i], alpha[s], mat); - polygon.append(rR.Map(x, y)); - } - } - if (polygon.count()) - aPolygon.append(polygon); - return aPolygon; - } - - ::basegfx::B2DPolyPolygon& EMFPPath::GetClosedCardinalSpline(EmfPlusHelperData const& rR, float fTension) - { - ::basegfx::B2DPolygon polygon; - matrix mat; - float x, y; - constexpr sal_uInt32 nDetails = 8; - constexpr float alpha[nDetails] - = { 1. / nDetails, 2. / nDetails, 3. / nDetails, 4. / nDetails, - 5. / nDetails, 6. / nDetails, 7. / nDetails, 8. / nDetails }; - GetCardinalMatrix(fTension, mat); - // add three first points at the end - xPoints.push_back(xPoints[0]); - yPoints.push_back(yPoints[0]); - xPoints.push_back(xPoints[1]); - yPoints.push_back(yPoints[1]); - xPoints.push_back(xPoints[2]); - yPoints.push_back(yPoints[2]); - - for (sal_uInt32 i = 3; i < nPoints + 3; i++) - { - for (sal_uInt32 s = 0; s < nDetails; s++) - { - x = calculateSplineCoefficients(xPoints[i - 3], xPoints[i - 2], xPoints[i - 1], - xPoints[i], alpha[s], mat); - y = calculateSplineCoefficients(yPoints[i - 3], yPoints[i - 2], yPoints[i - 1], - yPoints[i], alpha[s], mat); - polygon.append(rR.Map(x, y)); - } - } - polygon.setClosed(true); - if (polygon.count()) - aPolygon.append(polygon); - return aPolygon; - } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/drawinglayer/source/tools/emfppath.hxx b/drawinglayer/source/tools/emfppath.hxx index e6104fcb1fc7..94a3d342f887 100644 --- a/drawinglayer/source/tools/emfppath.hxx +++ b/drawinglayer/source/tools/emfppath.hxx @@ -27,7 +27,7 @@ namespace emfplushelper { ::basegfx::B2DPolyPolygon aPolygon; sal_uInt32 nPoints; - std::deque<float> xPoints, yPoints; + std::unique_ptr<float[]> pPoints; std::unique_ptr<sal_uInt8[]> pPointTypes; public: @@ -38,9 +38,6 @@ namespace emfplushelper void Read(SvStream& s, sal_uInt32 pathFlags); ::basegfx::B2DPolyPolygon& GetPolygon(EmfPlusHelperData const & rR, bool bMapIt = true, bool bAddLineToCloseShape = false); - ::basegfx::B2DPolyPolygon& GetCardinalSpline(EmfPlusHelperData const& rR, float fTension, - sal_uInt32 aOffset, sal_uInt32 aNumSegments); - ::basegfx::B2DPolyPolygon& GetClosedCardinalSpline(EmfPlusHelperData const& rR, float fTension); }; } diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index 1881b53f0a1a..930e4f0961dc 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -64,7 +64,6 @@ class Test : public UnoApiXmlTest void TestDrawPolyLine16WithClip(); void TestFillRegion(); void TestEmfPlusBrushPathGradientWithBlendColors(); - void testEmfPlusRecordTypeDrawCurve(); void TestEmfPlusGetDC(); void TestEmfPlusSave(); void TestEmfPlusDrawPathWithCustomCap(); @@ -120,7 +119,6 @@ public: CPPUNIT_TEST(TestDrawPolyLine16WithClip); CPPUNIT_TEST(TestFillRegion); CPPUNIT_TEST(TestEmfPlusBrushPathGradientWithBlendColors); - CPPUNIT_TEST(testEmfPlusRecordTypeDrawCurve); CPPUNIT_TEST(TestEmfPlusGetDC); CPPUNIT_TEST(TestEmfPlusSave); CPPUNIT_TEST(TestEmfPlusDrawPathWithCustomCap); @@ -1006,99 +1004,6 @@ void Test::TestEmfPlusBrushPathGradientWithBlendColors() assertXPath(pDocument, aXPathPrefix + "svgradialgradient", "spreadmethod", "pad"); } -void Test::testEmfPlusRecordTypeDrawCurve() -{ - // tdf#143877 EMF+ records: DrawCurve, DrawClosedCurve - Primitive2DSequence aSequence - = parseEmf(u"emfio/qa/cppunit/emf/data/TestEmfPlusRecordTypeDrawCurve.emf"); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); - drawinglayer::Primitive2dXmlDump dumper; - xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence)); - CPPUNIT_ASSERT(pDocument); - - assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke", 26); - assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[1]/line", "color", "#ff0000"); - assertXPath( - pDocument, aXPathPrefix + "mask/polypolygonstroke[1]/polypolygon", "path", - "m15171.856932876 0c2167.40813326801 2167.4834989758 2167.40813326801 4334.9669979516 0 " - "5418.7087474395-2167.40813326801-541.87087474395-2167.40813326801-2709.35437371975 " - "0-5418.7087474395"); - assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[5]/line", "color", "#ff0000"); - assertXPath( - pDocument, aXPathPrefix + "mask/polypolygonstroke[5]/polypolygon", "path", - "m9067.13138473787 655.113420833017 134.193869426752 101.812405648104 139.272492038215 " - "99.2724892764088 141.812836844685 105.622473993772 141.813870345419 120.862553588321 " - "139.272492038217 144.992857252138 134.19386942675 178.012997408972 126.573868508085 " - "219.923426231116 106.674845357667 213.255822775207 76.1979421852029 161.820449175038 " - "45.7189720112692 124.990111480451 15.2400018373355 102.765068075616-15.2400018373355 " - "95.1448021921942-45.7179385105337 102.129959790608-76.1979421852029 " - "123.72002410252-106.676912359138 159.915511896266"); - assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[10]/line", "color", "#ff0000"); - assertXPath( - pDocument, aXPathPrefix + "mask/polypolygonstroke[10]/polypolygon", "path", - "m9067.13138473787 4990.08041878461 134.193869426752 101.812664032273 139.272492038215 " - "99.2722308922403 141.812836844685 105.622796973982 141.813870345419 120.862295204153 " - "139.272492038217 144.992792656096 134.19386942675 178.013255793139 126.573868508085 " - "219.923684615284 106.674845357667 213.255306006871 76.1979421852029 161.820319982953 " - "45.7189720112692 124.990240672536 15.2400018373355 102.765068075615-15.2400018373355 " - "95.14531896053-45.7179385105337 102.129959790608-76.1979421852029 " - "123.720540870856-106.676912359138 159.915511896266-113.239642025967 " - "159.967188729871-101.809123897599 119.010714256079-99.2687790911332 " - "85.355142834027-105.618607606564 59.002541537061-120.857575943166 " - "39.9523935968437-144.987751102401 28.2052157817125-178.007066082802 " - "23.7599745549942-219.914487383636 26.6171866850245"); - assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[15]/line", "color", "#ff0000"); - assertXPath( - pDocument, aXPathPrefix + "mask/polypolygonstroke[15]/polypolygon", "path", - "m9067.13138473787 9325.04741673621 134.193869426752 101.812664032272 139.272492038215 " - "99.2722308922421 141.812836844685 105.623313742317 141.813870345419 120.862811972489 " - "139.272492038217 144.993826192769 134.19386942675 178.013255793139 126.573868508085 " - "219.924201383621 106.674845357667 213.252722165189 76.1979421852029 161.820836751291 " - "45.7189720112692 124.989723904198 15.2400018373355 102.765584843952-15.2400018373355 " - "95.1442854238576-45.7179385105337 102.130993327281-76.1979421852029 " - "123.719507334185-106.676912359138 159.916028664602-113.239642025967 " - "159.967705498208-101.809123897599 119.009680719406-99.2687790911332 " - "85.3556596023645-105.618607606564 59.0025415370601-120.857575943166 " - "39.9523935968446-144.987751102401 28.2052157817125-178.007066082802 " - "23.7599745549942-219.914487383636 26.6177034533594-219.91758788584 " - "15.0276232123888-178.007066082802-11.6417570745762-144.987751102401-31.9621215848092-120." - "858092693532-45.9314032449638-105.618607606566-53.5516691283865-99.2687790911314-54." - "8218856984004-101.808607147232-49.7410194183394-113.238608525233-38.3111373615429"); - assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[20]/line", "color", "#ff0000"); - assertXPath( - pDocument, aXPathPrefix + "mask/polypolygonstroke[20]/polypolygon", "path", - "m10130.9395287237 14843.7694408618 76.1979421852029 161.820836751291 45.7189720112692 " - "124.989723904198 15.2400018373355 102.765584843952-15.2400018373355 " - "95.1453189605309-45.7179385105337 102.129959790607-76.1979421852029 " - "123.720540870856-106.676912359138 159.916028664602-113.239642025967 " - "159.966671961536-101.809123897599 119.010714256079-99.2687790911332 " - "85.3546260656913-105.618607606564 59.0025415370601-120.857575943166 " - "39.953427133516-144.987751102401 28.2052157817125-178.007066082802 " - "23.7599745549942-219.914487383636 26.6177034533612"); - assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[25]/line", "color", "#ff0000"); - assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[25]/polypolygon", "path", - "m10130.9395287237 19178.7364388134 76.1979421852029 161.820836751289 " - "45.7189720112692 124.9897239042 15.2400018373355 " - "102.764551307278-15.2400018373355 95.1453189605309-45.7179385105337 " - "102.129959790607-76.1979421852029 123.720540870858-106.676912359138 " - "159.914995127929-113.239642025967 159.968739034881-101.809123897599 " - "119.009680719406-99.2687790911332 85.3556596023627-105.618607606564 " - "59.0025415370619-120.857575943166 39.9544606701893-144.987751102401 " - "28.2052157817125-178.007066082802 23.7610080916638-219.914487383636 " - "26.6177034533612-233.252847868691 45.0291257302197-210.390778111221 " - "61.2246453820844-184.991464049484 58.0496207253782-157.052321931652 " - "35.5081859067977-126.572835007349-6.40379322035369-93.5540367773156-67." - "6801154360437-57.9948937408126-148.324914886958-19.895922648212-248.340258646444 " - "19.8948891474765-321.473313564504 57.9954104911813-345.283931416434 " - "93.5540367773147-354.809005386542 126.573351757716-350.046468401488 " - "157.05283868202-330.996320461269 184.991980799852-297.658561565891 " - "210.390778111219-250.033191715345 233.250780867224-188.120210909645 " - "219.914487383634-96.7845081224878 178.007066082804 3.22670149030819 " - "144.987751102401 86.4140011546006 120.8586094439 152.773256723693 " - "105.618607606564 202.300334050906 99.2698125918669 235.005568502958 " - "101.809123897599 250.880691786475 113.238608525233 249.927770974791z"); -} - void Test::TestEmfPlusGetDC() { // tdf#147818 EMF+ records: GetDC, DrawPath, FillRects @@ -1247,77 +1152,38 @@ void Test::TestEmfPlusFillClosedCurve() assertXPath(pDocument, aXPathPrefix + "polypolygoncolor", 2); assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[1]", "color", "#808080"); - assertXPath( - pDocument, aXPathPrefix + "polypolygoncolor[1]/polypolygon", "path", - "m19296.3351298383 " - "18361.4321751005-414.061734443902-308.241977088233-546.349828515435-482.86833320689-607." - "202351788335-586.056634549728-596.619304262618-617.806881116761-514.600685938261-578." - "119072907972-361.146496815287-466.993209923374-136.25673689368-284.429292162964 " - "145.516903478681-148.167817312798 383.635472807451-105.834155223427 " - "542.381185693288-63.5004931340554 621.754042136206-21.1668310446876 621.758176139148 " - "21.1688981180305 542.381185693288 63.5004931340554 383.639606810386 105.836222296773 " - "145.516903478689 148.167817312798-136.265004899564 284.425158016275-361.146496815287 " - "466.993209923374-514.600685938261 578.119072907972-596.619304262618 " - "617.806881116761-607.202351788335 586.058701623075-546.349828515435 " - "482.868333206887-414.061734443902 308.244044161576-210.338069573736 " - "62.1775661937645-10.5830475257244-283.110499369355 116.413522782947-605.900538654125 " - "211.660950514459-817.568849100979 275.159235668783-918.111296563235 " - "306.912512248899-907.527881040893 306.908378245957-785.818602533949 " - "275.163369671733-552.983461042411 211.660950514452-209.022456566268 211.652682508575 " - "209.022456566268 275.159235668791 552.983461042411 306.908378245957 785.818602533949 " - "306.908378245957 907.527881040893 275.163369671733 918.113363636578 211.660950514452 " - "817.568849100979 116.417656785889 605.902605727468-10.5830475257171 283.106365222669z"); - assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[2]", "color", "#808080"); - assertXPath( - pDocument, aXPathPrefix + "polypolygoncolor[2]/polypolygon", "path", - "m24376.1979421852 " - "18361.4321751005-414.061734443902-308.241977088233-546.349828515435-482.86833320689-607." - "202351788335-586.056634549728-596.619304262618-617.806881116761-514.600685938261-578." - "119072907972-361.146496815287-466.993209923374-136.25673689368-284.429292162964 " - "145.516903478681-148.167817312798 383.635472807451-105.834155223427 " - "542.381185693288-63.5004931340554 621.754042136206-21.1668310446876 621.754042136206 " - "21.1688981180305 542.381185693288 63.5004931340554 383.635472807451 105.836222296773 " - "145.516903478681 148.167817312798-136.25673689368 284.425158016275-361.146496815287 " - "466.993209923374-514.600685938261 578.119072907972-596.619304262618 " - "617.806881116761-607.202351788335 586.058701623075-546.349828515435 " - "482.868333206887-414.061734443902 308.244044161576-210.338069573736 " - "62.1775661937645-10.5830475257244-283.110499369355 116.413522782947-605.900538654125 " - "211.660950514459-817.568849100979 275.159235668783-918.111296563235 " - "306.908378245964-907.527881040893 306.908378245957-785.818602533949 " - "275.159235668791-552.983461042411 211.660950514452-209.022456566268 211.660950514452 " - "209.022456566268 275.159235668791 552.983461042411 306.908378245957 785.818602533949 " - "306.908378245964 907.527881040893 275.159235668783 918.113363636578 211.660950514459 " - "817.568849100979 116.413522782947 605.902605727468-10.5830475257244 283.106365222669z"); + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[1]/polypolygon", "path", + "m18202.841744243 13758.4401790456 1269.96570308672 " + "3175.02465670283-2539.93140617345-2116.68310446856h2539.93140617345l-2539." + "93140617345 2116.68310446856z"); assertXPath(pDocument, aXPathPrefix + "polypolygonstroke", 2); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "color", "#00ff00"); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "width", "33"); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "color", "#000000"); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "width", "10"); assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "linejoin", "Miter"); assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "miterangle", "3"); assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "linecap", "BUTT"); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/polypolygon", "path", + "m18202.841744243 13758.4401790456 1269.96570308672 " + "3175.02465670283-2539.93140617345-2116.68310446856h2539.93140617345l-2539." + "93140617345 2116.68310446856z"); - assertXPath( - pDocument, aXPathPrefix + "polypolygonstroke[1]/polypolygon", "path", - "m19296.3351298383 " - "18361.4321751005-414.061734443902-308.241977088233-546.349828515435-482.86833320689-607." - "202351788335-586.056634549728-596.619304262618-617.806881116761-514.600685938261-578." - "119072907972-361.146496815287-466.993209923374-136.25673689368-284.429292162964 " - "145.516903478681-148.167817312798 383.635472807451-105.834155223427 " - "542.381185693288-63.5004931340554 621.754042136206-21.1668310446876 621.758176139148 " - "21.1688981180305 542.381185693288 63.5004931340554 383.639606810386 105.836222296773 " - "145.516903478689 148.167817312798-136.265004899564 284.425158016275-361.146496815287 " - "466.993209923374-514.600685938261 578.119072907972-596.619304262618 " - "617.806881116761-607.202351788335 586.058701623075-546.349828515435 " - "482.868333206887-414.061734443902 308.244044161576-210.338069573736 " - "62.1775661937645-10.5830475257244-283.110499369355 116.413522782947-605.900538654125 " - "211.660950514459-817.568849100979 275.159235668783-918.111296563235 " - "306.912512248899-907.527881040893 306.908378245957-785.818602533949 " - "275.163369671733-552.983461042411 211.660950514452-209.022456566268 211.652682508575 " - "209.022456566268 275.159235668791 552.983461042411 306.908378245957 785.818602533949 " - "306.908378245957 907.527881040893 275.163369671733 918.113363636578 211.660950514452 " - "817.568849100979 116.417656785889 605.902605727468-10.5830475257171 283.106365222669z"); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", "color", "#aaaa00"); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", "width", "33"); + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[2]", "color", "#808080"); + //TODO Check path with implemented Winding + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[2]/polypolygon", "path", + "m22012.7388535032 13758.4401790456 1269.96570308672 " + "3175.02465670283-2539.93140617344-2116.68310446856h2539.93140617344l-2539." + "93140617344 2116.68310446856z"); + + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", "color", "#000000"); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", "width", "10"); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", "linejoin", "Miter"); ... etc. - the rest is truncated