summaryrefslogtreecommitdiff
path: root/oox/source
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2019-08-20 10:43:46 +0200
committerRegina Henschel <rb.henschel@t-online.de>2019-08-23 23:38:33 +0200
commit72b50be0197159c5afc5da4daf01ba303519b14a (patch)
treedb2d45de370f19bafc2b50aa568f5527e7967d75 /oox/source
parent7b4b70afba2d6bde66dd59da5950d45efb4a645b (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.cxx74
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 );
}