diff options
author | Miklos Vajna <vmiklos@suse.cz> | 2013-05-30 15:43:55 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@suse.cz> | 2013-05-30 15:54:14 +0200 |
commit | 9dc54d258cee67ce702f907504fcc776712cad47 (patch) | |
tree | 1ca197e09599023865aa2ac66604f5626457876f /oox/source | |
parent | bf32dfeffb79fc7c06189f9040f7a8db3ce56700 (diff) |
bnc#817956 fix VML import of rotation
In VML, positive rotation angles are clockwise, we have them as
counter-clockwise. This wasn't noticed earlier, as the n751117.docx
testcase also had flip:x. (For example, rotation with angle 90 + flip:x
is presented as 270 by the UI.)
Fix this, and also mirror the angle when flip:x is present.
Change-Id: I591ec3369a5bdca53f9684006a459d11e37fbc33
(cherry picked from commit b2c16f6c1b8bd3c96e0549eb3036c820094a795f
Diffstat (limited to 'oox/source')
-rw-r--r-- | oox/source/vml/vmlshape.cxx | 91 |
1 files changed, 50 insertions, 41 deletions
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index 3861ee19f3e3..4cf771e71999 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -18,6 +18,7 @@ */ #include <algorithm> +#include <boost/optional.hpp> #include "oox/vml/vmlshape.hxx" @@ -41,6 +42,7 @@ #include <com/sun/star/text/TextContentAnchorType.hpp> #include <rtl/math.hxx> #include <rtl/ustrbuf.hxx> +#include <svx/svdtrans.hxx> #include "oox/drawingml/shapepropertymap.hxx" #include "oox/helper/graphichelper.hxx" #include "oox/helper/propertyset.hxx" @@ -83,21 +85,21 @@ const sal_Int32 VML_SHAPETYPE_HOSTCONTROL = 201; // ---------------------------------------------------------------------------- -Point lclGetAbsPoint( const Point& rRelPoint, const Rectangle& rShapeRect, const Rectangle& rCoordSys ) +awt::Point lclGetAbsPoint( const awt::Point& rRelPoint, const awt::Rectangle& rShapeRect, const awt::Rectangle& rCoordSys ) { double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width; double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height; - Point aAbsPoint; + awt::Point aAbsPoint; aAbsPoint.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelPoint.X - rCoordSys.X) + 0.5 ); aAbsPoint.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelPoint.Y - rCoordSys.Y) + 0.5 ); return aAbsPoint; } -Rectangle lclGetAbsRect( const Rectangle& rRelRect, const Rectangle& rShapeRect, const Rectangle& rCoordSys ) +awt::Rectangle lclGetAbsRect( const awt::Rectangle& rRelRect, const awt::Rectangle& rShapeRect, const awt::Rectangle& rCoordSys ) { double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width; double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height; - Rectangle aAbsRect; + awt::Rectangle aAbsRect; aAbsRect.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelRect.X - rCoordSys.X) + 0.5 ); aAbsRect.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelRect.Y - rCoordSys.Y) + 0.5 ); aAbsRect.Width = static_cast< sal_Int32 >( fWidthRatio * rRelRect.Width + 0.5 ); @@ -149,21 +151,21 @@ OUString ShapeType::getGraphicPath() const return maTypeModel.moGraphicPath.get( OUString() ); } -Rectangle ShapeType::getCoordSystem() const +awt::Rectangle ShapeType::getCoordSystem() const { Int32Pair aCoordPos = maTypeModel.moCoordPos.get( Int32Pair( 0, 0 ) ); Int32Pair aCoordSize = maTypeModel.moCoordSize.get( Int32Pair( 1000, 1000 ) ); - return Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second ); + return awt::Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second ); } -Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const +awt::Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const { return pParentAnchor ? lclGetAbsRect( getRelRectangle(), pParentAnchor->maShapeRect, pParentAnchor->maCoordSys ) : getAbsRectangle(); } -Rectangle ShapeType::getAbsRectangle() const +awt::Rectangle ShapeType::getAbsRectangle() const { const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper(); @@ -180,15 +182,15 @@ Rectangle ShapeType::getAbsRectangle() const if (nLeft == 0 && maTypeModel.maPosition == "absolute") nLeft = 1; - return Rectangle( + return awt::Rectangle( nLeft, ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginTop, 0, false, true ), nWidth, nHeight ); } -Rectangle ShapeType::getRelRectangle() const +awt::Rectangle ShapeType::getRelRectangle() const { - return Rectangle( + return awt::Rectangle( maTypeModel.maLeft.toInt32(), maTypeModel.maTop.toInt32(), maTypeModel.maWidth.toInt32(), @@ -294,7 +296,7 @@ Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxS { /* Calculate shape rectangle. Applications may do something special according to some imported shape client data (e.g. Excel cell anchor). */ - Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); + awt::Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() ) { @@ -330,13 +332,13 @@ void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const Sha { /* Calculate shape rectangle. Applications may do something special according to some imported shape client data (e.g. Excel cell anchor). */ - Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); + awt::Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); // convert the shape, if the calculated rectangle is not empty if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) ) { - rxShape->setPosition( Point( aShapeRect.X, aShapeRect.Y ) ); - rxShape->setSize( Size( aShapeRect.Width, aShapeRect.Height ) ); + rxShape->setPosition( awt::Point( aShapeRect.X, aShapeRect.Y ) ); + rxShape->setSize( awt::Size( aShapeRect.Width, aShapeRect.Height ) ); convertShapeProperties( rxShape ); } } @@ -344,11 +346,11 @@ void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const Sha // protected ------------------------------------------------------------------ -Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const +awt::Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const { /* Calculate shape rectangle. Applications may do something special according to some imported shape client data (e.g. Excel cell anchor). */ - Rectangle aShapeRect; + awt::Rectangle aShapeRect; const ClientData* pClientData = getClientData(); if( !pClientData || !mrDrawing.convertClientAnchor( aShapeRect, pClientData->maAnchor ) ) aShapeRect = getRectangle( pParentAnchor ); @@ -448,15 +450,20 @@ void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel) lcl_setSurround( rPropSet, rTypeModel ); } -Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const { - Rectangle aShapeRect(rShapeRect); + awt::Rectangle aShapeRect(rShapeRect); + boost::optional<sal_Int32> oRotation; + if (!maTypeModel.maRotation.isEmpty()) + oRotation.reset(maTypeModel.maRotation.toInt32()); if (!maTypeModel.maFlip.isEmpty()) { if (maTypeModel.maFlip.equalsAscii("x")) { aShapeRect.X += aShapeRect.Width; aShapeRect.Width *= -1; + if (oRotation) + oRotation.reset(360 - *oRotation); } else if (maTypeModel.maFlip.equalsAscii("y")) { @@ -523,9 +530,11 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes } PropertySet aPropertySet(xShape); - if (xShape.is() && !maTypeModel.maRotation.isEmpty()) + if (xShape.is() && oRotation) { - aPropertySet.setAnyProperty(PROP_RotateAngle, makeAny(maTypeModel.maRotation.toInt32() * 100)); + // See DffPropertyReader::Fix16ToAngle(): in VML, positive rotation angles are clockwise, we have them as counter-clockwise. + // Additionally, VML type is 0..360, our is 0.36000. + aPropertySet.setAnyProperty(PROP_RotateAngle, makeAny(sal_Int32(NormAngle360((*oRotation) * -100)))); // If rotation is used, simple setPosition() is not enough. aPropertySet.setAnyProperty(PROP_HoriOrientPosition, makeAny( aShapeRect.X ) ); aPropertySet.setAnyProperty(PROP_VertOrientPosition, makeAny( aShapeRect.Y ) ); @@ -536,7 +545,7 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes return xShape; } -Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect, OUString& rGraphicPath ) const +Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect, OUString& rGraphicPath ) const { Reference< XShape > xShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.GraphicObjectShape", rxShapes, rShapeRect ); if( xShape.is() ) @@ -569,7 +578,7 @@ RectangleShape::RectangleShape( Drawing& rDrawing ) : { } -Reference<XShape> RectangleShape::implConvertAndInsert(const Reference<XShapes>& rxShapes, const Rectangle& rShapeRect) const +Reference<XShape> RectangleShape::implConvertAndInsert(const Reference<XShapes>& rxShapes, const awt::Rectangle& rShapeRect) const { OUString aGraphicPath = getGraphicPath(); @@ -610,14 +619,14 @@ PolyLineShape::PolyLineShape( Drawing& rDrawing ) : { } -Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const { Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect ); // polygon path - Rectangle aCoordSys = getCoordSystem(); + awt::Rectangle aCoordSys = getCoordSystem(); if( !maShapeModel.maPoints.empty() && (aCoordSys.Width > 0) && (aCoordSys.Height > 0) ) { - ::std::vector< Point > aAbsPoints; + ::std::vector< awt::Point > aAbsPoints; for( ShapeModel::PointVector::const_iterator aIt = maShapeModel.maPoints.begin(), aEnd = maShapeModel.maPoints.end(); aIt != aEnd; ++aIt ) aAbsPoints.push_back( lclGetAbsPoint( *aIt, rShapeRect, aCoordSys ) ); PointSequenceSequence aPointSeq( 1 ); @@ -667,17 +676,17 @@ BezierShape::BezierShape(Drawing& rDrawing) { } -Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const { Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect ); - Rectangle aCoordSys = getCoordSystem(); + awt::Rectangle aCoordSys = getCoordSystem(); if( (aCoordSys.Width > 0) && (aCoordSys.Height > 0) ) { const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper(); // Bezier paths may consist of one or more sub-paths - typedef ::std::vector< ::std::vector< Point > > SubPathList; + typedef ::std::vector< ::std::vector< awt::Point > > SubPathList; typedef ::std::vector< ::std::vector< PolygonFlags > > FlagsList; SubPathList aCoordLists; FlagsList aFlagLists; @@ -686,24 +695,24 @@ Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes // Curve defined by to, from, control1 and control2 attributes if ( maShapeModel.maVmlPath.isEmpty() ) { - aCoordLists.push_back( ::std::vector< Point >() ); + aCoordLists.push_back( ::std::vector< awt::Point >() ); aFlagLists.push_back( ::std::vector< PolygonFlags >() ); // Start point aCoordLists[ 0 ].push_back( - Point(ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, true, true ), + awt::Point(ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, true, true ), ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, false, true ) ) ); // Control point 1 aCoordLists[ 0 ].push_back( - Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, true, true ), + awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, true, true ), ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, false, true ) ) ); // Control point 2 aCoordLists[ 0 ].push_back( - Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, true, true ), + awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, true, true ), ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, false, true ) ) ); // End point aCoordLists[ 0 ].push_back( - Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, true, true ), + awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, true, true ), ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, false, true ) ) ); // First and last points are normals, points 2 and 4 are controls @@ -718,7 +727,7 @@ Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes ConversionHelper::decodeVmlPath( aCoordLists, aFlagLists, maShapeModel.maVmlPath ); for ( SubPathList::iterator aListIt = aCoordLists.begin(); aListIt != aCoordLists.end(); ++aListIt ) - for ( ::std::vector< Point >::iterator aPointIt = (*aListIt).begin(); aPointIt != (*aListIt).end(); ++aPointIt) + for ( ::std::vector< awt::Point >::iterator aPointIt = (*aListIt).begin(); aPointIt != (*aListIt).end(); ++aPointIt) { (*aPointIt) = lclGetAbsPoint( (*aPointIt), rShapeRect, aCoordSys ); } @@ -738,8 +747,8 @@ Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes } // Hacky way of ensuring the shape is correctly sized/positioned - xShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) ); - xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); + xShape->setSize( awt::Size( rShapeRect.Width, rShapeRect.Height ) ); + xShape->setPosition( awt::Point( rShapeRect.X, rShapeRect.Y ) ); return xShape; } @@ -750,7 +759,7 @@ CustomShape::CustomShape( Drawing& rDrawing ) : { } -Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const { // try to create a custom shape Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect ); @@ -775,7 +784,7 @@ ComplexShape::ComplexShape( Drawing& rDrawing ) : { } -Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const { XmlFilterBase& rFilter = mrDrawing.getFilter(); sal_Int32 nShapeType = getShapeType(); @@ -791,7 +800,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes return Reference< XShape >(); PropertyMap aOleProps; - Size aOleSize( rShapeRect.Width, rShapeRect.Height ); + awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height ); if( rFilter.getOleObjectHelper().importOleObject( aOleProps, *pOleObjectInfo, aOleSize ) ) { Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ), rxShapes, rShapeRect ); @@ -883,7 +892,7 @@ const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const return mxChildren->getShapeById( rShapeId, true ); } -Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const { Reference< XShape > xGroupShape; // check that this shape contains children and a valid coordinate system |