Commits

Anonymous committed d662b51

dr81: DrawingML shape anchor coordinates are 64-bit EMUs

Comments (0)

Files changed (10)

oox/inc/oox/drawingml/diagram/diagram.hxx

 	const DiagramDataPtr & getStyleData() const
 		{ return mpStyleData; }
 
-	void layout( const dgm::PointsTreePtr & pTree, const com::sun::star::awt::Point & pt );
+	void layout( const dgm::PointsTreePtr & pTree, const EmuPoint & pt );
 private:
 	::rtl::OUString msDefStyle;
 	::rtl::OUString msMinVer;

oox/inc/oox/drawingml/drawingmltypes.hxx

 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
 #include <com/sun/star/geometry/IntegerRectangle2D.hpp>
 #include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
 #include <com/sun/star/awt/Size.hpp>
 #include <com/sun/star/xml/sax/XFastAttributeList.hpp>
 #include "oox/helper/helper.hxx"
 
     inline explicit     EmuPoint() : X( 0 ), Y( 0 ) {}
     inline explicit     EmuPoint( sal_Int64 nX, sal_Int64 nY ) : X( nX ), Y( nY ) {}
+
+    inline ::com::sun::star::awt::Point getPointHmm() const
+        { return ::com::sun::star::awt::Point( convertEmuToHmm( X ), convertEmuToHmm( Y ) ); }
 };
 
 // ============================================================================
 
     inline explicit     EmuSize() : Width( 0 ), Height( 0 ) {}
     inline explicit     EmuSize( sal_Int64 nWidth, sal_Int64 nHeight ) : Width( nWidth ), Height( nHeight ) {}
+
+    inline ::com::sun::star::awt::Size getSizeHmm() const
+        { return ::com::sun::star::awt::Size( convertEmuToHmm( Width ), convertEmuToHmm( Height ) ); }
 };
 
 // ============================================================================
     inline explicit     EmuRectangle( const EmuPoint& rPos, const EmuSize& rSize ) : EmuPoint( rPos ), EmuSize( rSize ) {}
     inline explicit     EmuRectangle( sal_Int64 nX, sal_Int64 nY, sal_Int64 nWidth, sal_Int64 nHeight ) : EmuPoint( nX, nY ), EmuSize( nWidth, nHeight ) {}
 
+    inline const EmuPoint& getPos() const { return *this; }
+    inline const EmuSize& getSize() const { return *this; }
+
     inline void         setPos( const EmuPoint& rPos ) { static_cast< EmuPoint& >( *this ) = rPos; }
     inline void         setSize( const EmuSize& rSize ) { static_cast< EmuSize& >( *this ) = rSize; }
+
+    inline ::com::sun::star::awt::Rectangle getRectangleHmm() const
+        { return ::com::sun::star::awt::Rectangle( convertEmuToHmm( X ), convertEmuToHmm( Y ), convertEmuToHmm( Width ), convertEmuToHmm( Height ) ); }
 };
 
 // ============================================================================

oox/inc/oox/drawingml/shape.hxx

 
 	table::TablePropertiesPtr		getTableProperties();
 
-    void                            setPosition( com::sun::star::awt::Point nPosition ){ maPosition = nPosition; }
-    void                            setSize( com::sun::star::awt::Size aSize ){ maSize = aSize; }
+    void                            setPosition( const EmuPoint& rPosition ) { maShapeRect.setPos( rPosition ); }
+    void                            setSize( const EmuSize& rSize ) { maShapeRect.setSize( rSize ); }
     void                            setRotation( sal_Int32 nRotation ) { mnRotation = nRotation; }
     void                            setFlip( sal_Bool bFlipH, sal_Bool bFlipV ) { mbFlipH = bFlipH; mbFlipV = bFlipV; }
     void                            addChild( const ShapePtr pChildPtr ) { maChildren.push_back( pChildPtr ); }
                             ::oox::core::XmlFilterBase& rFilterBase,
                             const Theme* pTheme,
                             const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
-                            const ::com::sun::star::awt::Rectangle* pShapeRect = 0,
+                            const EmuRectangle* pShapeRect = 0,
                             ShapeIdMap* pShapeMap = 0 );
 
     void				setXShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rXShape )
                             const ::rtl::OUString& rServiceName,
                             const Theme* pTheme,
                             const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
-                            const ::com::sun::star::awt::Rectangle* pShapeRect,
+                            const EmuRectangle* pShapeRect,
 							sal_Bool bClearText );
 
     void                addChildren(
                             Shape& rMaster,
                             const Theme* pTheme,
                             const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
-                            const ::com::sun::star::awt::Rectangle& rClientRect,
+                            const EmuRectangle& rClientRect,
                             ShapeIdMap* pShapeMap );
 
     virtual ::rtl::OUString finalizeServiceName(
 
     ShapeStyleRefMap   maShapeStyleRefs;
 
-    com::sun::star::awt::Size       maSize;
-    com::sun::star::awt::Point      maPosition;
+    EmuRectangle        maShapeRect;
 
 private:
     enum FrameType

oox/inc/oox/ppt/pptshape.hxx

             const SlidePersist& rPersist,
             const oox::drawingml::Theme* pTheme,
             const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
-            const com::sun::star::awt::Rectangle* pShapeRect = 0,
+            const ::oox::drawingml::EmuRectangle* pShapeRect = 0,
             ::oox::drawingml::ShapeIdMap* pShapeMap = 0 );
 
 	virtual void applyShapeReference( const oox::drawingml::Shape& rReferencedShape );

oox/source/drawingml/chart/chartdrawingfragment.cxx

         {
             EmuRectangle aShapeRectEmu = mxAnchor->calcAnchorRectEmu( maChartRectEmu );
             if( (aShapeRectEmu.X >= 0) && (aShapeRectEmu.Y >= 0) && (aShapeRectEmu.Width >= 0) && (aShapeRectEmu.Height >= 0) )
-            {
-                // TODO: DrawingML implementation expects 32-bit coordinates for EMU rectangles (change that to EmuRectangle)
-                Rectangle aShapeRectEmu32(
-                    getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.X, 0, SAL_MAX_INT32 ),
-                    getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Y, 0, SAL_MAX_INT32 ),
-                    getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Width, 0, SAL_MAX_INT32 ),
-                    getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Height, 0, SAL_MAX_INT32 ) );
-                mxShape->addShape( getFilter(), getFilter().getCurrentTheme(), mxDrawPage, &aShapeRectEmu32 );
-            }
+                mxShape->addShape( getFilter(), getFilter().getCurrentTheme(), mxDrawPage, &aShapeRectEmu );
         }
         mxShape.reset();
         mxAnchor.reset();

oox/source/drawingml/diagram/diagram.cxx

 				  boost::bind( &dgm::Point::dump, _1 ) );
 }
 
-static void setPosition( const dgm::PointPtr & pPoint, const awt::Point & pt )
+static void setPosition( const dgm::PointPtr & pPoint, const EmuPoint & pt )
 {
 	ShapePtr pShape = pPoint->getShape();
-	awt::Size sz;
-	sz.Width = 50;
-	sz.Height = 50;
 	pShape->setPosition( pt );
-	pShape->setSize( sz );
+	pShape->setSize( EmuSize( 50, 50 ) );
 }
 
-void DiagramLayout::layout( const dgm::PointsTreePtr & pTree, const awt::Point & pt )
+void DiagramLayout::layout( const dgm::PointsTreePtr & pTree, const EmuPoint & pt )
 {
 	setPosition( pTree->getPoint(), pt );
-	awt::Point nextPt = pt;
+	EmuPoint nextPt = pt;
 	nextPt.Y += 50;
 	dgm::PointsTree::Childrens::const_iterator iter;
 	for( iter = pTree->beginChild(); iter != pTree->endChild(); iter++ )
 	dgm::Points::iterator aPointsIter;
 	build( );
     if( mpRoot.get() )
-        mpLayout->layout( mpRoot, awt::Point( 0, 0 ) );
+        mpLayout->layout( mpRoot, EmuPoint( 0, 0 ) );
 
 	for( aPointsIter = aPoints.begin(); aPointsIter != aPoints.end(); ++aPointsIter )
 	{

oox/source/drawingml/shape.cxx

         ::oox::core::XmlFilterBase& rFilterBase,
         const Theme* pTheme,
         const Reference< XShapes >& rxShapes,
-        const awt::Rectangle* pShapeRect,
+        const EmuRectangle* pShapeRect,
         ShapeIdMap* pShapeMap )
 {
     try
             // if this is a group shape, we have to add also each child shape
             Reference< XShapes > xShapes( xShape, UNO_QUERY );
             if ( xShapes.is() )
-                addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap );
+                addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : maShapeRect, pShapeMap );
         }
-		Reference< document::XActionLockable > xLockable( mxShape, UNO_QUERY );
-        if( xLockable.is() )
-			xLockable->removeActionLock();
     }
     catch( const Exception&  )
     {
     mpTablePropertiesPtr = table::TablePropertiesPtr( rReferencedShape.mpTablePropertiesPtr.get() ? new table::TableProperties( *rReferencedShape.mpTablePropertiesPtr.get() ) : NULL );
     mpMasterTextListStyle = TextListStylePtr( new TextListStyle( *rReferencedShape.mpMasterTextListStyle.get() ) );
     maShapeStyleRefs = rReferencedShape.maShapeStyleRefs;
-    maSize = rReferencedShape.maSize;
-    maPosition = rReferencedShape.maPosition;
+    maShapeRect = rReferencedShape.maShapeRect;
     mnRotation = rReferencedShape.mnRotation;
     mbFlipH = rReferencedShape.mbFlipH;
     mbFlipV = rReferencedShape.mbFlipV;
         Shape& rMaster,
         const Theme* pTheme,
         const Reference< XShapes >& rxShapes,
-        const awt::Rectangle& rClientRect,
+        const EmuRectangle& rClientRect,
         ShapeIdMap* pShapeMap )
 {
-    // first the global child union needs to be calculated
-    sal_Int32 nGlobalLeft  = SAL_MAX_INT32;
-    sal_Int32 nGlobalRight = SAL_MIN_INT32;
-    sal_Int32 nGlobalTop   = SAL_MAX_INT32;
-    sal_Int32 nGlobalBottom= SAL_MIN_INT32;
-    std::vector< ShapePtr >::iterator aIter( rMaster.maChildren.begin() );
-    while( aIter != rMaster.maChildren.end() )
+    // calculate the bounding rectangle containing all child shapes
+    sal_Int64 nGlobalLeft   = SAL_MAX_INT64;
+    sal_Int64 nGlobalRight  = SAL_MIN_INT64;
+    sal_Int64 nGlobalTop    = SAL_MAX_INT64;
+    sal_Int64 nGlobalBottom = SAL_MIN_INT64;
+    for( std::vector< ShapePtr >::iterator aIter = rMaster.maChildren.begin(), aEnd = rMaster.maChildren.end(); aIter != aEnd; ++aIter )
     {
-        sal_Int32 l = (*aIter)->maPosition.X;
-        sal_Int32 t = (*aIter)->maPosition.Y;
-        sal_Int32 r = l + (*aIter)->maSize.Width;
-        sal_Int32 b = t + (*aIter)->maSize.Height;
+        const EmuRectangle& rChildRect = (*aIter)->maShapeRect;
+        sal_Int64 l = rChildRect.X;
+        sal_Int64 t = rChildRect.Y;
+        sal_Int64 r = l + rChildRect.Width;
+        sal_Int64 b = t + rChildRect.Height;
         if ( nGlobalLeft > l )
             nGlobalLeft = l;
         if ( nGlobalRight < r )
             nGlobalTop = t;
         if ( nGlobalBottom < b )
             nGlobalBottom = b;
-        aIter++;
     }
-    aIter = rMaster.maChildren.begin();
-    while( aIter != rMaster.maChildren.end() )
+
+    bool bValidGlobalRect = (nGlobalLeft < nGlobalRight) && (nGlobalTop < nGlobalBottom);
+    sal_Int64 nGlobalWidth = nGlobalRight - nGlobalLeft;
+    sal_Int64 nGlobalHeight = nGlobalBottom - nGlobalTop;
+    double fXScale = bValidGlobalRect ? static_cast< double >( rClientRect.Width ) / static_cast< double >( nGlobalWidth ) : 1.0;
+    double fYScale = bValidGlobalRect ? static_cast< double >( rClientRect.Height ) / static_cast< double >( nGlobalHeight ) : 1.0;
+
+    for( std::vector< ShapePtr >::iterator aIter = rMaster.maChildren.begin(), aEnd = rMaster.maChildren.end(); aIter != aEnd; ++aIter )
     {
-        awt::Rectangle aShapeRect;
-        awt::Rectangle* pShapeRect = 0;
-        if ( ( nGlobalLeft != SAL_MAX_INT32 ) && ( nGlobalRight != SAL_MIN_INT32 ) && ( nGlobalTop != SAL_MAX_INT32 ) && ( nGlobalBottom != SAL_MIN_INT32 ) )
+        if( bValidGlobalRect )
         {
-            sal_Int32 nGlobalWidth = nGlobalRight - nGlobalLeft;
-            sal_Int32 nGlobalHeight = nGlobalBottom - nGlobalTop;
-            if ( nGlobalWidth && nGlobalHeight )
-            {
-                double fWidth = (*aIter)->maSize.Width;
-                double fHeight= (*aIter)->maSize.Height;
-                double fXScale = (double)rClientRect.Width / (double)nGlobalWidth;
-                double fYScale = (double)rClientRect.Height / (double)nGlobalHeight;
-                aShapeRect.X = static_cast< sal_Int32 >( ( ( (*aIter)->maPosition.X - nGlobalLeft ) * fXScale ) + rClientRect.X );
-                aShapeRect.Y = static_cast< sal_Int32 >( ( ( (*aIter)->maPosition.Y - nGlobalTop  ) * fYScale ) + rClientRect.Y );
-                fWidth *= fXScale;
-                fHeight *= fYScale;
-                aShapeRect.Width = static_cast< sal_Int32 >( fWidth );
-                aShapeRect.Height = static_cast< sal_Int32 >( fHeight );
-                pShapeRect = &aShapeRect;
-            }
+            const EmuRectangle& rChildRect = (*aIter)->maShapeRect;
+            EmuRectangle aShapeRect(
+                static_cast< sal_Int64 >( static_cast< double >( rChildRect.X - nGlobalLeft ) * fXScale + static_cast< double >( rClientRect.X ) ),
+                static_cast< sal_Int64 >( static_cast< double >( rChildRect.Y - nGlobalTop ) * fYScale + static_cast< double >( rClientRect.Y ) ),
+                static_cast< sal_Int64 >( static_cast< double >( rChildRect.Width ) * fXScale ),
+                static_cast< sal_Int64 >( static_cast< double >( rChildRect.Height ) * fYScale ) );
+            (*aIter)->addShape( rFilterBase, pTheme, rxShapes, &aShapeRect, pShapeMap );
         }
-        (*aIter++)->addShape( rFilterBase, pTheme, rxShapes, pShapeRect, pShapeMap );
+        else
+            (*aIter)->addShape( rFilterBase, pTheme, rxShapes, 0, pShapeMap );
     }
 }
 
         const rtl::OUString& rServiceName,
         const Theme* pTheme,
         const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
-        const awt::Rectangle* pShapeRect,
+        const EmuRectangle* pShapeRect,
 		sal_Bool bClearText )
 {
-    awt::Size aSize( pShapeRect ? awt::Size( pShapeRect->Width, pShapeRect->Height ) : maSize );
-    awt::Point aPosition( pShapeRect ? awt::Point( pShapeRect->X, pShapeRect->Y ) : maPosition );
-    awt::Rectangle aShapeRectHmm( aPosition.X / 360, aPosition.Y / 360, aSize.Width / 360, aSize.Height / 360 );
+    const EmuRectangle& rShapeRect = pShapeRect ? *pShapeRect : maShapeRect;
+    awt::Rectangle aShapeRectHmm = rShapeRect.getRectangleHmm();
 
     OUString aServiceName = finalizeServiceName( rFilterBase, rServiceName, aShapeRectHmm );
 	sal_Bool bIsCustomShape = aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.CustomShape" ) );
 
     basegfx::B2DHomMatrix aTransformation;
-    if( aSize.Width != 1 || aSize.Height != 1)
+    if( rShapeRect.Width != 1 || rShapeRect.Height != 1)
     {
         // take care there are no zeros used by error
         aTransformation.scale(
-            aSize.Width ? aSize.Width / 360.0 : 1.0,
-            aSize.Height ? aSize.Height / 360.0 : 1.0 );
+            rShapeRect.Width ? (double)rShapeRect.Width / 360.0 : 1.0,
+            rShapeRect.Height ? (double)rShapeRect.Height / 360.0 : 1.0 );
     }
 
     if( mbFlipH || mbFlipV || mnRotation != 0)
         aTransformation.translate( aCenter.getX(), aCenter.getY() );
     }
 
-    if( aPosition.X != 0 || aPosition.Y != 0)
+    if( rShapeRect.X != 0 || rShapeRect.Y != 0)
     {
         // if global position is used, add it to transformation
-        aTransformation.translate( aPosition.X / 360.0, aPosition.Y / 360.0 );
+        aTransformation.translate( (double)rShapeRect.X / 360.0, (double)rShapeRect.Y / 360.0 );
     }
 
     // special for lineshape
     {
         ::basegfx::B2DPolygon aPoly;
         aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
-        aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
+        aPoly.insert( 1, ::basegfx::B2DPoint( maShapeRect.Width ? 1 : 0, maShapeRect.Height ? 1 : 0 ) );
         aPoly.transform( aTransformation );
 
         // now creating the corresponding PolyPolygon
     {
         ::basegfx::B2DPolygon aPoly;
         aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
-        aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
+        aPoly.insert( 1, ::basegfx::B2DPoint( maShapeRect.Width ? 1 : 0, maShapeRect.Height ? 1 : 0 ) );
         aPoly.transform( aTransformation );
 
         basegfx::B2DPoint aStartPosition( aPoly.getB2DPoint( 0 ) );

oox/source/drawingml/transform2dcontext.cxx

 
 Reference< XFastContextHandler > Transform2DContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
 {
+    AttributeList aAttribs( xAttribs );
 	switch( aElementToken )
 	{
 	case A_TOKEN( off ):		// horz/vert translation
-		mrShape.setPosition( Point( xAttribs->getOptionalValue( XML_x ).toInt32(), xAttribs->getOptionalValue( XML_y ).toInt32() ) );
+		mrShape.setPosition( EmuPoint( aAttribs.getHyper( XML_x, 0 ), aAttribs.getHyper( XML_y, 0 ) ) );
 		break;
 	case A_TOKEN( ext ):		// horz/vert size
-		mrShape.setSize( Size( xAttribs->getOptionalValue( XML_cx ).toInt32(), xAttribs->getOptionalValue( XML_cy ).toInt32() ) );
+		mrShape.setSize( EmuSize( aAttribs.getHyper( XML_cx, 0 ), aAttribs.getHyper( XML_cy, 0 ) ) );
 		break;
 /* todo: what to do?
 	case A_TOKEN( chOff ):	// horz/vert translation of children

oox/source/ppt/pptshape.cxx

         const SlidePersist& rSlidePersist,
         const oox::drawingml::Theme* pTheme,
         const Reference< XShapes >& rxShapes,
-        const awt::Rectangle* pShapeRect,
+        const ::oox::drawingml::EmuRectangle* pShapeRect,
         ::oox::drawingml::ShapeIdMap* pShapeMap )
 {
 	// only placeholder from layout are being inserted
 				// if this is a group shape, we have to add also each child shape
 				Reference< XShapes > xShapes( xShape, UNO_QUERY );
 				if ( xShapes.is() )
-					addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap );
+					addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : maShapeRect, pShapeMap );
             }
 		}
 	}

oox/source/xls/drawingfragment.cxx

                 EmuRectangle aShapeRectEmu = mxAnchor->calcAnchorRectEmu( getDrawPageSize() );
                 if( (aShapeRectEmu.X >= 0) && (aShapeRectEmu.Y >= 0) && (aShapeRectEmu.Width >= 0) && (aShapeRectEmu.Height >= 0) )
                 {
-                    // TODO: DrawingML implementation expects 32-bit coordinates for EMU rectangles (change that to EmuRectangle)
-                    Rectangle aShapeRectEmu32(
-                        getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.X, 0, SAL_MAX_INT32 ),
-                        getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Y, 0, SAL_MAX_INT32 ),
-                        getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Width, 0, SAL_MAX_INT32 ),
-                        getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Height, 0, SAL_MAX_INT32 ) );
-                    mxShape->addShape( getOoxFilter(), &getTheme(), mxDrawPage, &aShapeRectEmu32 );
-                    /*  Collect all shape positions in the WorksheetHelper base
-                        class. But first, scale EMUs to 1/100 mm. */
-                    Rectangle aShapeRectHmm(
-                        convertEmuToHmm( aShapeRectEmu.X ), convertEmuToHmm( aShapeRectEmu.Y ),
-                        convertEmuToHmm( aShapeRectEmu.Width ), convertEmuToHmm( aShapeRectEmu.Height ) );
-                    extendShapeBoundingBox( aShapeRectHmm );
+                    mxShape->addShape( getOoxFilter(), &getTheme(), mxDrawPage, &aShapeRectEmu );
+                    // collect all shape positions in the WorksheetHelper base (expects 1/100 mm)
+                    extendShapeBoundingBox( aShapeRectEmu.getRectangleHmm() );
                 }
             }
             mxShape.reset();