include/oox/export/drawingml.hxx | 4 oox/source/export/drawingml.cxx | 47 +++++++++- oox/source/export/shapes.cxx | 4 sw/qa/extras/ooxmlexport/data/tdf101122_noFillForCustomShape.odt |binary sw/qa/extras/ooxmlexport/ooxmlexport11.cxx | 16 +++ 5 files changed, 67 insertions(+), 4 deletions(-)
New commits: commit 9310e47e2ce71348a16e5412131946348833f4b2 Author: Regényi Balázs <regenyi.bal...@nisz.hu> AuthorDate: Mon Oct 12 09:58:35 2020 +0200 Commit: László Németh <nem...@numbertext.org> CommitDate: Tue Oct 13 15:19:57 2020 +0200 tdf#101122 DOCX custom shape export: remove bad fill of (simplified export) of not filled custom shapes by adding missing fill="none" to a:path. Note: in OpenDocument, unfilled shape path is defined by draw:enhanced-path command "F", see section 19.145 in ODF v1.2. Co-authored-by: Szabolcs Tóth Change-Id: I0be2aada3deb06828216e0441c91c389a673f87c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104205 Tested-by: László Németh <nem...@numbertext.org> Reviewed-by: László Németh <nem...@numbertext.org> diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index 11bf303e92ff..a4ef6af0530f 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -171,6 +171,7 @@ protected: void WriteGlowEffect(const css::uno::Reference<css::beans::XPropertySet>& rXPropSet); void WriteSoftEdgeEffect(const css::uno::Reference<css::beans::XPropertySet>& rXPropSet); + bool HasEnhancedCustomShapeSegmentCommand(const css::uno::Reference<css::drawing::XShape>& rXShape, const sal_Int16 nCommand); public: DrawingML( ::sax_fastparser::FSHelperPtr pFS, ::oox::core::XmlFilterBase* pFB, DocumentType eDocumentType = DOCUMENT_PPTX, DMLTextExport* pTextExport = nullptr ) @@ -275,7 +276,8 @@ public: static sal_Int32 GetCustomGeometryPointValue( const css::drawing::EnhancedCustomShapeParameter& rParam, const SdrObjCustomShape& rSdrObjCustomShape); - void WritePolyPolygon( const tools::PolyPolygon& rPolyPolygon, const bool bClosed ); + void WritePolyPolygon(const css::uno::Reference<css::drawing::XShape>& rXShape, + const tools::PolyPolygon& rPolyPolygon, const bool bClosed); void WriteFill( const css::uno::Reference< css::beans::XPropertySet >& xPropSet ); void WriteShapeStyle( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet ); void WriteShapeEffects( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet ); diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index c19b030ad642..8b7c4add1f78 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -3582,7 +3582,8 @@ sal_Int32 DrawingML::GetCustomGeometryPointValue( return nValue; } -void DrawingML::WritePolyPolygon( const tools::PolyPolygon& rPolyPolygon, const bool bClosed ) +void DrawingML::WritePolyPolygon(const css::uno::Reference<css::drawing::XShape>& rXShape, + const tools::PolyPolygon& rPolyPolygon, const bool bClosed) { // In case of Writer, the parent element is <wps:spPr>, and there the // <a:custGeom> element is not optional. @@ -3599,9 +3600,15 @@ void DrawingML::WritePolyPolygon( const tools::PolyPolygon& rPolyPolygon, const const tools::Rectangle aRect( rPolyPolygon.GetBoundRect() ); + // tdf#101122 + std::optional<OString> sFill; + if (HasEnhancedCustomShapeSegmentCommand(rXShape, css::drawing::EnhancedCustomShapeSegmentCommand::NOFILL)) + sFill = "none"; // for possible values see ST_PathFillMode in OOXML standard + // Put all polygons of rPolyPolygon in the same path element // to subtract the overlapped areas. mpFS->startElementNS( XML_a, XML_path, + XML_fill, sFill, XML_w, OString::number(aRect.GetWidth()), XML_h, OString::number(aRect.GetHeight()) ); @@ -4191,6 +4198,44 @@ void DrawingML::WriteSoftEdgeEffect(const css::uno::Reference<css::beans::XPrope WriteShapeEffect("softEdge", aProps); } +bool DrawingML::HasEnhancedCustomShapeSegmentCommand( + const css::uno::Reference<css::drawing::XShape>& rXShape, const sal_Int16 nCommand) +{ + try + { + uno::Reference<beans::XPropertySet> xPropSet(rXShape, uno::UNO_QUERY_THROW); + if (!GetProperty(xPropSet, "CustomShapeGeometry")) + return false; + Sequence<PropertyValue> aCustomShapeGeometryProps; + mAny >>= aCustomShapeGeometryProps; + for (const beans::PropertyValue& rGeomProp : std::as_const(aCustomShapeGeometryProps)) + { + if (rGeomProp.Name == "Path") + { + uno::Sequence<beans::PropertyValue> aPathProps; + rGeomProp.Value >>= aPathProps; + for (const beans::PropertyValue& rPathProp : std::as_const(aPathProps)) + { + if (rPathProp.Name == "Segments") + { + uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments; + rPathProp.Value >>= aSegments; + for (const auto& rSegment : std::as_const(aSegments)) + { + if (rSegment.Command == nCommand) + return true; + } + } + } + } + } + } + catch (const ::uno::Exception&) + { + } + return false; +} + void DrawingML::WriteShape3DEffects( const Reference< XPropertySet >& xPropSet ) { // check existence of the grab bag diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index 00a44d3fccfa..2b1251660cee 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -427,7 +427,7 @@ ShapeExport& ShapeExport::WritePolyPolygonShape( const Reference< XShape >& xSha // visual shape properties pFS->startElementNS(mnXmlNamespace, XML_spPr); WriteTransformation( aRect, XML_a ); - WritePolyPolygon( aPolyPolygon, bClosed ); + WritePolyPolygon(xShape, aPolyPolygon, bClosed); Reference< XPropertySet > xProps( xShape, UNO_QUERY ); if( xProps.is() ) { if( bClosed ) @@ -845,7 +845,7 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape ) bool bInvertRotation = bFlipH != bFlipV; if (nRotation != 0) aPolyPolygon.Rotate(Point(0,0), static_cast<sal_uInt16>(bInvertRotation ? nRotation/10 : 3600-nRotation/10)); - WritePolyPolygon( aPolyPolygon, false ); + WritePolyPolygon(xShape, aPolyPolygon, false); } else if (bCustGeom) { diff --git a/sw/qa/extras/ooxmlexport/data/tdf101122_noFillForCustomShape.odt b/sw/qa/extras/ooxmlexport/data/tdf101122_noFillForCustomShape.odt new file mode 100644 index 000000000000..8cc2a13f85e8 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf101122_noFillForCustomShape.odt differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx index 6e4560493d87..f26d7570d38a 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx @@ -1380,6 +1380,22 @@ DECLARE_OOXMLEXPORT_TEST(testTdf67207_MERGEFIELD_DATABASE, "tdf67207.docx") CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.text.fieldmaster.DataBase.database.Sheet1.c1"), sValue); } +DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf101122_noFillForCustomShape, "tdf101122_noFillForCustomShape.odt") +{ + // tdf#101122 check whether the "F" (noFill) option has been exported to docx + xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); + + assertXPath(pXmlDoc, + "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/" + "a:graphic/a:graphicData/wps:wsp/wps:spPr/a:custGeom/a:pathLst/a:path", + "fill", "none"); + assertXPathNoAttribute( + pXmlDoc, + "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/a:graphic/" + "a:graphicData/wps:wsp/wps:spPr/a:custGeom/a:pathLst/a:path", + "fill"); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits