summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2012-09-07 12:22:12 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-05-19 14:01:05 +0100
commit38109d24ab5261959b316b7dacc99521858f0749 (patch)
tree8c229f737d7e23aa0fc46555a5b1dd8f2890ab2c /filter
parentda99d73abfefd704f40ad6bc46172e267407a5ab (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.cxx134
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;