summaryrefslogtreecommitdiff
path: root/oox/source
diff options
context:
space:
mode:
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 );
}