[Libreoffice-commits] core.git: filter/source

Armin Le Grand alg at apache.org
Sun May 19 06:01:43 PDT 2013


 filter/source/msfilter/eschesdo.cxx |  134 ++++++++++++++++++++++++++++++++++--
 1 file changed, 128 insertions(+), 6 deletions(-)

New commits:
commit 38109d24ab5261959b316b7dacc99521858f0749
Author: Armin Le Grand <alg at apache.org>
Date:   Fri Sep 7 12:22:12 2012 +0000

    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

diff --git a/filter/source/msfilter/eschesdo.cxx b/filter/source/msfilter/eschesdo.cxx
index 2a6d7f4..d0f3c2b 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;


More information about the Libreoffice-commits mailing list