You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by al...@apache.org on 2012/09/07 15:22:12 UTC
svn commit: r1382015 -
/incubator/ooo/trunk/main/filter/source/msfilter/eschesdo.cxx
Author: alg
Date: Fri Sep 7 13:22:12 2012
New Revision: 1382015
URL: http://svn.apache.org/viewvc?rev=1382015&view=rev
Log:
#119703# Corercted bound rect for ms graphic object export for grouped objects to reflect rotated sub-objects better
Modified:
incubator/ooo/trunk/main/filter/source/msfilter/eschesdo.cxx
Modified: incubator/ooo/trunk/main/filter/source/msfilter/eschesdo.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/filter/source/msfilter/eschesdo.cxx?rev=1382015&r1=1382014&r2=1382015&view=diff
==============================================================================
--- incubator/ooo/trunk/main/filter/source/msfilter/eschesdo.cxx (original)
+++ incubator/ooo/trunk/main/filter/source/msfilter/eschesdo.cxx Fri Sep 7 13:22:12 2012
@@ -50,6 +50,10 @@
#include <comphelper/extract.hxx>
#include <svtools/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 ::rtl::OUString;
using namespace ::com::sun::star;
@@ -1154,6 +1158,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 );
@@ -1161,12 +1268,31 @@ void ImplEESdrObject::Init( ImplEESdrWri
{
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 ) ) );
- mType = String( mXShape->getShapeType() );
- mType.Erase( 0, nPrefix ); // strip "com.sun.star."
- xub_StrLen nPos = mType.SearchAscii( "Shape" );
- mType.Erase( nPos, 5 );
+
+ // 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 );
+
+ 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));
+ }
+
static const OUString sPresStr(rtl::OUString::createFromAscii("IsPresentationObject"));
static const OUString sEmptyPresStr(rtl::OUString::createFromAscii("IsEmptyPresentationObject"));