diff options
author | Armin Le Grand <alg@apache.org> | 2012-09-07 12:22:12 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-05-19 14:01:05 +0100 |
commit | 38109d24ab5261959b316b7dacc99521858f0749 (patch) | |
tree | 8c229f737d7e23aa0fc46555a5b1dd8f2890ab2c /filter | |
parent | da99d73abfefd704f40ad6bc46172e267407a5ab (diff) |
Resolves: #i119703# Corrected bound rect for ms graphic object...
export for grouped objects to reflect rotated sub-objects better
(cherry picked from commit 6b30b279363793da14e320e7c0dc9bf8409da23c)
Conflicts:
filter/source/msfilter/eschesdo.cxx
Change-Id: I39289c271bc13b1edd5922f53db968312a345fad
Diffstat (limited to 'filter')
-rw-r--r-- | filter/source/msfilter/eschesdo.cxx | 134 |
1 files changed, 128 insertions, 6 deletions
diff --git a/filter/source/msfilter/eschesdo.cxx b/filter/source/msfilter/eschesdo.cxx index 2a6d7f499d2b..d0f3c2b7ff43 100644 --- a/filter/source/msfilter/eschesdo.cxx +++ b/filter/source/msfilter/eschesdo.cxx @@ -44,6 +44,10 @@ #include <comphelper/extract.hxx> #include <vcl/fltcall.hxx> #include <vcl/cvtgrf.hxx> +#include <com/sun/star/drawing/HomogenMatrix3.hpp> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::beans; @@ -1024,6 +1028,109 @@ ImplEESdrObject::~ImplEESdrObject() { } +basegfx::B2DRange getUnrotatedGroupBoundRange(const Reference< XShape >& rxShape) +{ + basegfx::B2DRange aRetval; + + try + { + if(rxShape.is()) + { + if(rxShape->getShapeType().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.GroupShape"))) + { + // it's a group shape, iterate over children + const Reference< XIndexAccess > xXIndexAccess(rxShape, UNO_QUERY); + + if(xXIndexAccess.is()) + { + for(sal_uInt32 n(0), nCnt = xXIndexAccess->getCount(); n < nCnt; ++n) + { + const Reference< XShape > axShape(xXIndexAccess->getByIndex(n), UNO_QUERY); + + if(axShape.is()) + { + // we are calculating the bound for a group, correct rotation for sub-objects + // to get the unrotated bounds for the group + const basegfx::B2DRange aExtend(getUnrotatedGroupBoundRange(axShape)); + + aRetval.expand(aExtend); + } + } + } + } + else + { + // iT#s a xShape, get it's transformation + const Reference< XPropertySet > mXPropSet(rxShape, UNO_QUERY); + + if(mXPropSet.is()) + { + const Any aAny = mXPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation"))); + + if(aAny.hasValue()) + { + HomogenMatrix3 aMatrix; + + if(aAny >>= aMatrix) + { + basegfx::B2DHomMatrix aHomogenMatrix; + + aHomogenMatrix.set(0, 0, aMatrix.Line1.Column1); + aHomogenMatrix.set(0, 1, aMatrix.Line1.Column2); + aHomogenMatrix.set(0, 2, aMatrix.Line1.Column3); + aHomogenMatrix.set(1, 0, aMatrix.Line2.Column1); + aHomogenMatrix.set(1, 1, aMatrix.Line2.Column2); + aHomogenMatrix.set(1, 2, aMatrix.Line2.Column3); + aHomogenMatrix.set(2, 0, aMatrix.Line3.Column1); + aHomogenMatrix.set(2, 1, aMatrix.Line3.Column2); + aHomogenMatrix.set(2, 2, aMatrix.Line3.Column3); + + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + + // decopose transformation + aHomogenMatrix.decompose(aScale, aTranslate, fRotate, fShearX); + + // check if rotation needs to be corrected + if(!basegfx::fTools::equalZero(fRotate)) + { + // to correct, keep in mind that ppt graphics are rotated around their center + const basegfx::B2DPoint aCenter(aHomogenMatrix * basegfx::B2DPoint(0.5, 0.5)); + + aHomogenMatrix.translate(-aCenter.getX(), -aCenter.getY()); + aHomogenMatrix.rotate(-fRotate); + aHomogenMatrix.translate(aCenter.getX(), aCenter.getY()); + } + + + // check if shear needs to be corrected (always correct shear, + // ppt does not know about it) + if(!basegfx::fTools::equalZero(fShearX)) + { + const basegfx::B2DPoint aMinimum(aHomogenMatrix * basegfx::B2DPoint(0.0, 0.0)); + + aHomogenMatrix.translate(-aMinimum.getX(), -aMinimum.getY()); + aHomogenMatrix.shearX(-fShearX); + aHomogenMatrix.translate(aMinimum.getX(), aMinimum.getY()); + } + + // create range. It's no longer rotated (or sheared), so use + // minimum and maximum values + aRetval.expand(aHomogenMatrix * basegfx::B2DPoint(0.0, 0.0)); + aRetval.expand(aHomogenMatrix * basegfx::B2DPoint(1.0, 1.0)); + } + } + } + } + } + } + catch(::com::sun::star::uno::Exception&) + { + } + + return aRetval; +} + void ImplEESdrObject::Init( ImplEESdrWriter& rEx ) { mXPropSet = Reference< XPropertySet >::query( mXShape ); @@ -1031,20 +1138,35 @@ void ImplEESdrObject::Init( ImplEESdrWriter& rEx ) { static const sal_Char aPrefix[] = "com.sun.star."; static const xub_StrLen nPrefix = sizeof(aPrefix)-1; - SetRect( rEx.ImplMapPoint( Point( mXShape->getPosition().X, mXShape->getPosition().Y ) ), - rEx.ImplMapSize( Size( mXShape->getSize().Width, mXShape->getSize().Height ) ) ); + + // detect name first to make below test (is group) work mType = String( mXShape->getShapeType() ); mType.Erase( 0, nPrefix ); // strip "com.sun.star." xub_StrLen nPos = mType.SearchAscii( "Shape" ); mType.Erase( nPos, 5 ); - static const OUString sPresStr("IsPresentationObject" ); - static const OUString sEmptyPresStr("IsEmptyPresentationObject" ); + if(GetType().EqualsAscii("drawing.Group")) + { + // if it's a group, the unrotated range is needed for that group + const basegfx::B2DRange aUnroatedRange(getUnrotatedGroupBoundRange(mXShape)); + const Point aNewP(basegfx::fround(aUnroatedRange.getMinX()), basegfx::fround(aUnroatedRange.getMinY())); + const Size aNewS(basegfx::fround(aUnroatedRange.getWidth()), basegfx::fround(aUnroatedRange.getHeight())); + + SetRect(rEx.ImplMapPoint(aNewP), rEx.ImplMapSize(aNewS)); + } + else + { + // if it's no group, use position and size directly, roated/sheared or not + const Point aOldP(mXShape->getPosition().X, mXShape->getPosition().Y); + const Size aOldS(mXShape->getSize().Width, mXShape->getSize().Height); + + SetRect(rEx.ImplMapPoint(aOldP), rEx.ImplMapSize(aOldS)); + } - if( ImplGetPropertyValue( sPresStr ) ) + if( ImplGetPropertyValue( OUString("IsPresentationObject")) ) mbPresObj = ::cppu::any2bool( mAny ); - if( mbPresObj && ImplGetPropertyValue( sEmptyPresStr ) ) + if( mbPresObj && ImplGetPropertyValue( OUString("IsEmptyPresentationObject") ) ) mbEmptyPresObj = ::cppu::any2bool( mAny ); mbValid = sal_True; |