[Libreoffice-commits] core.git: Branch 'libreoffice-4-0' - sc/CppunitTest_sc_subsequent_export_test.mk sc/qa sc/source xmloff/inc

Noel Power noel.power at suse.com
Thu Mar 28 07:50:26 PDT 2013


 sc/CppunitTest_sc_subsequent_export_test.mk |    1 
 sc/qa/unit/data/ods/rotflipshapes.ods       |binary
 sc/qa/unit/helper/qahelper.hxx              |    5 +
 sc/qa/unit/subsequent_export-test.cxx       |   78 ++++++++++++++++++++++++++++
 sc/source/filter/xml/xmlexprt.cxx           |   32 +++++++++++
 xmloff/inc/xmloff/shapeexport.hxx           |    2 
 6 files changed, 117 insertions(+), 1 deletion(-)

New commits:
commit 2058479575e4a3e003eb1917c4f0947db9145623
Author: Noel Power <noel.power at suse.com>
Date:   Tue Mar 26 18:21:27 2013 +0000

    hacky fix for export of cell anchored flipped custom shapes (fdo#62448)
    
    On export it is assumed the translate co-ords are the same as
    the topleft of the logical rectangle. What rectangle to use
    at any given time, the transformations and the fact that
    different object types seems to handle rotation etc. in their
    own way leaves me confused as to what the correct fix might be.
    This fix though won't make things worse ( afaict )
    
    Change-Id: I6c704f9aebd650d530ebc32fbe73c251719494fe
    Reviewed-on: https://gerrit.libreoffice.org/3064
    Tested-by: Petr Mladek <pmladek at suse.cz>
    Reviewed-by: Petr Mladek <pmladek at suse.cz>

diff --git a/sc/CppunitTest_sc_subsequent_export_test.mk b/sc/CppunitTest_sc_subsequent_export_test.mk
index 41a6855..02d1aeb 100644
--- a/sc/CppunitTest_sc_subsequent_export_test.mk
+++ b/sc/CppunitTest_sc_subsequent_export_test.mk
@@ -101,6 +101,7 @@ $(eval $(call gb_CppunitTest_use_components,sc_subsequent_export_test,\
     framework/util/fwk \
     i18npool/util/i18npool \
     i18npool/source/search/i18nsearch \
+    linguistic/source/lng \
     oox/util/oox \
     package/source/xstor/xstor \
     package/util/package2 \
diff --git a/sc/qa/unit/data/ods/rotflipshapes.ods b/sc/qa/unit/data/ods/rotflipshapes.ods
new file mode 100644
index 0000000..2bd104f
Binary files /dev/null and b/sc/qa/unit/data/ods/rotflipshapes.ods differ
diff --git a/sc/qa/unit/helper/qahelper.hxx b/sc/qa/unit/helper/qahelper.hxx
index 32f7f7a..8557452 100644
--- a/sc/qa/unit/helper/qahelper.hxx
+++ b/sc/qa/unit/helper/qahelper.hxx
@@ -38,6 +38,11 @@
 
 #include <osl/detail/android-bootstrap.h>
 
+bool testEqualsWithTolerance( long nVal1, long nVal2, long nTol )
+{
+    return ( labs( nVal1 - nVal2 ) <= nTol );
+}
+
 // Why is this here and not in osl, and using the already existing file
 // handling APIs? Do we really want to add arbitrary new file handling
 // wrappers here and there (and then having to handle the Android (and
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index 844020d..aee44e0 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -34,6 +34,9 @@
 #include "scitems.hxx"
 #include "document.hxx"
 #include "cellform.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "svx/svdpage.hxx"
 
 #define ODS_FORMAT_TYPE 50331943
 #define XLS_FORMAT_TYPE 318767171
@@ -78,6 +81,7 @@ public:
     void testPasswordExport();
     void testConditionalFormatExportXLSX();
     void testMiscRowHeightExport();
+    void testRotatedFlippedShapes();
 
     CPPUNIT_TEST_SUITE(ScExportTest);
     CPPUNIT_TEST(test);
@@ -86,6 +90,7 @@ public:
 #endif
     CPPUNIT_TEST(testConditionalFormatExportXLSX);
     CPPUNIT_TEST(testMiscRowHeightExport);
+    CPPUNIT_TEST(testRotatedFlippedShapes);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -371,6 +376,79 @@ void ScExportTest::testMiscRowHeightExport()
     }
 }
 
+void ScExportTest::testRotatedFlippedShapes()
+{
+    ScDocShellRef xShell = loadDocument("rotflipshapes.", ODS);
+    CPPUNIT_ASSERT(xShell.Is());
+    ScDocShellRef xDocSh = saveAndReload(&(*xShell), ODS);
+    CPPUNIT_ASSERT(xDocSh.Is());
+    ScDocument* pDoc = xDocSh->GetDocument();
+    ScDrawLayer *pDrawLayer = pDoc->GetDrawLayer();
+    CPPUNIT_ASSERT_MESSAGE("must have a draw layer", pDrawLayer != NULL);
+    SdrPage* pPage = pDrawLayer->GetPage(0);
+    CPPUNIT_ASSERT_MESSAGE("must have a draw page", pPage != NULL);
+    struct TestData
+    {
+        long mnShapeX;
+        long mnShapeY;
+        long mnShapeWidth;
+        long mnShapeHeight;
+        SCROW startAnchorRow;
+        SCCOL startAnchorCol;
+        SCROW endAnchorRow;
+        SCCOL endAnchorCol;
+    };
+
+    TestData testData[] =
+    {
+        { 1, 1356, 2194, 1255, 3, 0, 5, 0  },
+        { 2194, 5771, 2195, 1205, 12, 0, 15, 1 },
+        { 5154, 1382, 904, 1170, 3, 2, 5, 2 },
+        { 6085, 5712, 903, 1120, 12, 2, 15, 3 },
+        { 9367, 1906, 1382, 772, 4, 4, 5, 4 },
+        { 10557, 5732, 1383, 745, 12, 4, 14, 5 },
+        { 14106, 1674, 957, 957, 3, 6, 5, 6 },
+        { 15087, 5447, 956, 932, 12, 6, 14, 7 },
+        { 18087, 2050, 904, 1010, 4, 8, 6, 8 },
+        { 19122, 5569, 904, 985, 12, 8, 14, 8 }
+    };
+
+    int nCount( pPage->GetObjCount() );
+    int nData = SAL_N_ELEMENTS(testData);
+    CPPUNIT_ASSERT_MESSAGE("must have test data for all objects", nCount == nData );
+
+    for (int i = 0; i < nData; ++i )
+
+    {
+        SdrObject* pObj = pPage->GetObj(i);
+        CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
+        ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj, false);
+        Point aObjPos( pObj->GetLogicRect().TopLeft() );
+
+       long nTol = 20; // 20hmm
+       printf( "comparing object[%d] pos ( %ld, %ld ) with expected ( %ld, %ld ) - with tolerance %ld\n",
+            i, aObjPos.X(), aObjPos.Y(), testData[ i ].mnShapeX, testData[ i ].mnShapeY, nTol );
+       CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aObjPos.X(), testData[ i ].mnShapeX, nTol  ) );
+       CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aObjPos.Y(), testData[ i ].mnShapeY, nTol  ) );
+
+       printf( "comparing object[%d] Width, Height ( %ld, %ld ) with expected ( %ld, %ld ) - with tolerance %ld\n",
+             i, pObj->GetLogicRect().GetWidth(), pObj->GetLogicRect().GetHeight(),
+             testData[ i ].mnShapeWidth, testData[ i ].mnShapeHeight, nTol );
+       CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance(pObj->GetLogicRect().GetWidth(), testData[ i ].mnShapeWidth, nTol  ) );
+       CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance(pObj->GetLogicRect().GetHeight(), testData[ i ].mnShapeHeight, nTol  ) );
+
+       printf( "comparing object[%d] anchor start ( %" SAL_PRIdINT32 ", %d ) with expected ( %" SAL_PRIdINT32 ", %d ) \n",
+             i, pData->maStart.Row(), pData->maStart.Col(),  testData[ i ].startAnchorRow, testData[ i ].startAnchorCol );
+
+       CPPUNIT_ASSERT_EQUAL( pData->maStart.Row(), testData[ i ].startAnchorRow );
+       CPPUNIT_ASSERT_EQUAL( pData->maStart.Col(), testData[ i ].startAnchorCol );
+
+       printf( "comparing object[%d] anchor end ( %" SAL_PRIdINT32 ", %d ) with expected ( %" SAL_PRIdINT32 ", %d ) \n",
+             i, pData->maEnd.Row(), pData->maEnd.Col(),  testData[ i ].endAnchorRow, testData[ i ].endAnchorCol );
+       CPPUNIT_ASSERT_EQUAL( pData->maEnd.Row(), testData[ i ].endAnchorRow );
+       CPPUNIT_ASSERT_EQUAL( pData->maEnd.Col(), testData[ i ].endAnchorCol );
+    }
+}
 ScExportTest::ScExportTest()
       : m_aBaseString(RTL_CONSTASCII_USTRINGPARAM("/sc/qa/unit/data"))
 {
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 3882e2f..620383c 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -128,6 +128,7 @@
 
 #include <vector>
 #include <vbahelper/vbaaccesshelper.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
 
 //! not found in unonames.hxx
 #define SC_LAYERID "LayerID"
@@ -3149,6 +3150,37 @@ void ScXMLExport::WriteShapes(const ScMyCell& rMyCell)
         {
             if (aItr->xShape.is())
             {
+                SdrObject* pObj = SdrObject::getSdrObjectFromXShape( aItr->xShape );
+                if ( pObj )
+                {
+                    // Sometimes the position indicated by aTRTranslate and
+                    // the position reported by the object are different
+                    // ( seems to happen when objects are flipped say
+                    // vertically ) This doesn't seem to happen when the
+                    // objects are just rotated in a similar way e.g.
+                    // although a rotation of 180 deg. is roughly equivalent
+                    // to a vertical flip, the Transformation and Obj position
+                    // are equal wheras in the vertical flip case they are not.
+                    // This difference when exporting ( which attempts to
+                    // output the position of the object relative to the top
+                    // left corner of the nearest cell ) results in incorrect
+                    // values being generated.
+                    basegfx::B2DPolyPolygon aTmp;
+                    basegfx::B2DHomMatrix aTmpMatrix;
+                    uno::Reference<beans::XPropertySet> xPropertySet(aItr->xShape, uno::UNO_QUERY);
+                    GetShapeExport()->ImpExportNewTrans_GetB2DHomMatrix( aTmpMatrix, xPropertySet );
+                    double fTRShear(0.0);
+                    double fTRRotate(0.0);
+                    basegfx::B2DTuple aTRTranslate;
+                    basegfx::B2DTuple aTRScale;
+
+                    aTmpMatrix.decompose(aTRScale, aTRTranslate, fTRRotate, fTRShear);
+                    Point aObjPos = pObj->GetLogicRect().TopLeft();
+                    Point aTransPos( aTRTranslate.getX(), aTRTranslate.getY() );
+                    aObjPos -= aTransPos;
+                    aPoint.X = aPoint.X - aObjPos.X();
+                    aPoint.Y = aPoint.Y - aObjPos.Y();
+                }
                 if (bNegativePage)
                     aPoint.X = 2 * aItr->xShape->getPosition().X + aItr->xShape->getSize().Width - aPoint.X;
                 if ( !aItr->xShape->getShapeType().equals(sCaptionShape) )
diff --git a/xmloff/inc/xmloff/shapeexport.hxx b/xmloff/inc/xmloff/shapeexport.hxx
index 55cc160..d89acba 100644
--- a/xmloff/inc/xmloff/shapeexport.hxx
+++ b/xmloff/inc/xmloff/shapeexport.hxx
@@ -210,7 +210,6 @@ private:
     SAL_DLLPRIVATE void ImpCalcShapeType(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType& eShapeType);
 
     SAL_DLLPRIVATE void ImpExportNewTrans(const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint);
-    SAL_DLLPRIVATE void ImpExportNewTrans_GetB2DHomMatrix(::basegfx::B2DHomMatrix& rMatrix, const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet);
     SAL_DLLPRIVATE void ImpExportNewTrans_DecomposeAndRefPoint(const ::basegfx::B2DHomMatrix& rMat, ::basegfx::B2DTuple& rTRScale, double& fTRShear, double& fTRRotate, ::basegfx::B2DTuple& rTRTranslate, com::sun::star::awt::Point* pRefPoint);
     SAL_DLLPRIVATE void ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple& rTRScale, double fTRShear, double fTRRotate, ::basegfx::B2DTuple& rTRTranslate, const sal_Int32 nFeatures);
     SAL_DLLPRIVATE sal_Bool ImpExportPresentationAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet, const rtl::OUString& rClass );
@@ -323,6 +322,7 @@ public:
     virtual void onExport( const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape );
 
     const rtl::Reference< XMLTableExport >&     GetShapeTableExport();
+    void ImpExportNewTrans_GetB2DHomMatrix(::basegfx::B2DHomMatrix& rMatrix, const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet);
 };
 
 


More information about the Libreoffice-commits mailing list