diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2019-08-20 10:43:46 +0200 |
---|---|---|
committer | Regina Henschel <rb.henschel@t-online.de> | 2019-08-23 23:38:33 +0200 |
commit | 72b50be0197159c5afc5da4daf01ba303519b14a (patch) | |
tree | db2d45de370f19bafc2b50aa568f5527e7967d75 /oox/source | |
parent | 7b4b70afba2d6bde66dd59da5950d45efb4a645b (diff) |
tdf#99497 CircleKind ARC, CUT, SECTION to OOXML arc, chord, pie
Before this patch, a classical ellipse or circle was exported as
OOXML preset type 'ellipse', regardless of the value of property
CircleKind. Now the property is evaluated and the corresponding
preset type is used.
Change-Id: I49ff43cf7e2ce02654979e82f7d83d60ace39e23
Reviewed-on: https://gerrit.libreoffice.org/77785
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
Diffstat (limited to 'oox/source')
-rw-r--r-- | oox/source/export/shapes.cxx | 74 |
1 files changed, 71 insertions, 3 deletions
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index a5928223ff1c..5e9d069c3290 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -47,6 +47,7 @@ #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/document/XExporter.hpp> #include <com/sun/star/document/XStorageBasedDocument.hpp> +#include <com/sun/star/drawing/CircleKind.hpp> #include <com/sun/star/drawing/FillStyle.hpp> #include <com/sun/star/drawing/BitmapMode.hpp> #include <com/sun/star/drawing/ConnectorType.hpp> @@ -102,6 +103,7 @@ #include <oox/export/chartexport.hxx> #include <oox/mathml/export.hxx> #include <drawingml/presetgeometrynames.hxx> +#include <basegfx/numeric/ftools.hxx> using namespace ::css; using namespace ::css::beans; @@ -697,6 +699,21 @@ static sal_Int32 lcl_NormalizeAngle( sal_Int32 nAngle ) return nAngle < 0 ? ( nAngle + 360 ) : nAngle ; } +static sal_Int32 lcl_CircleAngle2CustomShapeEllipseAngleOOX(const sal_Int32 nInternAngle, const sal_Int32 nWidth, const sal_Int32 nHeight) +{ + if (nWidth != 0 || nHeight != 0) + { + double fAngle = basegfx::deg2rad(nInternAngle / 100.0); // intern 1/100 deg to degree to rad + fAngle = atan2(nHeight * sin(fAngle), nWidth * cos(fAngle)); // circle to ellipse + fAngle = basegfx::rad2deg(fAngle) * 60000.0; // rad to degree to OOXML angle unit + sal_Int32 nAngle = basegfx::fround(fAngle); // normalize + nAngle = nAngle % 21600000; + return nAngle < 0 ? (nAngle + 21600000) : nAngle; + } + else // should be handled by caller, dummy value + return 0; +} + ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape ) { // First check, if this is a Fontwork-shape. For DrawingML, such a shape is a @@ -1055,7 +1072,7 @@ ShapeExport& ShapeExport::WriteEllipseShape( const Reference< XShape >& xShape ) pFS->startElementNS(mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp)); - // TODO: arc, section, cut, connector + // TODO: connector ? // non visual shape properties if (GetDocumentType() != DOCUMENT_DOCX) @@ -1071,13 +1088,64 @@ ShapeExport& ShapeExport::WriteEllipseShape( const Reference< XShape >& xShape ) else pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr); + Reference< XPropertySet > xProps( xShape, UNO_QUERY ); + CircleKind eCircleKind(CircleKind_FULL); + if (xProps.is()) + xProps->getPropertyValue("CircleKind" ) >>= eCircleKind; + // visual shape properties pFS->startElementNS( mnXmlNamespace, XML_spPr ); WriteShapeTransformation( xShape, XML_a ); - WritePresetShape( "ellipse" ); - Reference< XPropertySet > xProps( xShape, UNO_QUERY ); + + if (CircleKind_FULL == eCircleKind) + WritePresetShape("ellipse"); + else + { + sal_Int32 nStartAngleIntern(9000); + sal_Int32 nEndAngleIntern(0); + if (xProps.is()) + { + xProps->getPropertyValue("CircleStartAngle" ) >>= nStartAngleIntern; + xProps->getPropertyValue("CircleEndAngle") >>= nEndAngleIntern; + } + std::vector< std::pair<sal_Int32,sal_Int32>> aAvList; + awt::Size aSize = xShape->getSize(); + if (aSize.Width != 0 || aSize.Height != 0) + { + // Our arc has 90° up, OOXML has 90° down, so mirror it. + // API angles are 1/100 degree. + sal_Int32 nStartAngleOOXML(lcl_CircleAngle2CustomShapeEllipseAngleOOX(36000 - nEndAngleIntern, aSize.Width, aSize.Height)); + sal_Int32 nEndAngleOOXML(lcl_CircleAngle2CustomShapeEllipseAngleOOX(36000 - nStartAngleIntern, aSize.Width, aSize.Height)); + lcl_AppendAdjustmentValue( aAvList, 1, nStartAngleOOXML); + lcl_AppendAdjustmentValue( aAvList, 2, nEndAngleOOXML); + } + switch (eCircleKind) + { + case CircleKind_ARC : + WritePresetShape("arc", aAvList); + break; + case CircleKind_SECTION : + WritePresetShape("pie", aAvList); + break; + case CircleKind_CUT : + WritePresetShape("chord", aAvList); + break; + default : + WritePresetShape("ellipse"); + } + } if( xProps.is() ) { + if (CircleKind_ARC == eCircleKind) + { + // An arc in ODF is never filled, even if a fill style other than + // "none" is set. OOXML arc can be filled, so set fill explicit to + // NONE, otherwise some hidden or inherited filling is shown. + FillStyle eFillStyle(FillStyle_NONE); + uno::Any aNewValue; + aNewValue <<= eFillStyle; + xProps->setPropertyValue("FillStyle", aNewValue); + } WriteFill( xProps ); WriteOutline( xProps ); } |