Modified: 
incubator/ooo/branches/alg/aw080/main/filter/source/msfilter/eschesdo.cxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/branches/alg/aw080/main/filter/source/msfilter/eschesdo.cxx?rev=1412988&r1=1412987&r2=1412988&view=diff
==============================================================================
--- incubator/ooo/branches/alg/aw080/main/filter/source/msfilter/eschesdo.cxx 
(original)
+++ incubator/ooo/branches/alg/aw080/main/filter/source/msfilter/eschesdo.cxx 
Fri Nov 23 17:14:30 2012
@@ -85,8 +85,8 @@ ImplEESdrWriter::ImplEESdrWriter( Escher
                mnPagesWritten                  ( 0 ),
                mnShapeMasterTitle              ( 0 ),
                mnShapeMasterBody               ( 0 ),
-               mbStatusIndicator               ( sal_False ),
-               mbStatus                                ( sal_False )
+               mbStatusIndicator               ( false ),
+               mbStatus                                ( false )
 {
 }
 
@@ -95,29 +95,27 @@ ImplEESdrWriter::ImplEESdrWriter( Escher
 
 void ImplEESdrWriter::implPrepareLogicToLogic()
 {
-       if(maLogicToLogic.isIdentity())
-       {
-               maLogicToLogic = 
Application::GetDefaultDevice()->GetViewTransformation(maMapModeSrc);
-               maLogicToLogic.invert();
-               maLogicToLogic = 
Application::GetDefaultDevice()->GetViewTransformation(maMapModeDest) * 
maLogicToLogic;
-       }
+    if(maLogicToLogic.isIdentity())
+    {
+        maLogicToLogic = 
Application::GetDefaultDevice()->GetTransformLogicToLogic(maMapModeSrc, 
maMapModeDest);
+    }
 }
 
 // -------------------------------------------------------------------
-// TTTT not needed?
-//basegfx::B2DPoint ImplEESdrWriter::ImplMapB2DPoint( const basegfx::B2DPoint& 
rB2DPoint )
-//{
-//     if(maMapModeSrc == maMapModeDest)
-//     {
-//             return rB2DPoint;
-//     }
-//     else
-//     {
-//             implPrepareLogicToLogic();
-//
-//             return maLogicToLogic * rB2DPoint;
-//     }
-//}
+
+basegfx::B2DPoint ImplEESdrWriter::ImplMapB2DPoint( const basegfx::B2DPoint& 
rB2DPoint )
+{
+       if(maMapModeSrc == maMapModeDest)
+       {
+               return rB2DPoint;
+       }
+       else
+       {
+               implPrepareLogicToLogic();
+
+               return maLogicToLogic * rB2DPoint;
+       }
+}
 
 // -------------------------------------------------------------------
 
@@ -156,34 +154,56 @@ basegfx::B2DRange ImplEESdrWriter::ImplM
 
 // -------------------------------------------------------------------
 
-void ImplEESdrWriter::ImplFlipBoundingBox( ImplEESdrObject& rObj, 
EscherPropertyContainer& rPropOpt )
+void ImplEESdrWriter::ImplHandleRotation( ImplEESdrObject& rObj, 
EscherPropertyContainer& rPropOpt )
 {
-       sal_Int32 nAngle = rObj.GetAngle();
+    if(rObj.GetAngle())
+    {
+        const basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& 
rMat(rObj.getTransform());
 
-       if ( nAngle < 0 )
-               nAngle = ( 36000 + nAngle ) % 36000;
-       else
-               nAngle = ( 36000 - ( nAngle % 36000 ) );
+        // rObj.getObjectRange() is already mapped, while rMat is not. Thus, 
adapt aCurrentCenter, too.
+        // MS shape format rotates around the object center, so adapt adapt 
ObjectRange
+        // to be centered at the center of the original shape to do this
+        const basegfx::B2DPoint 
aCurrentCenter(ImplMapB2DPoint(rMat.getB2DHomMatrix() * basegfx::B2DPoint(0.5, 
0.5)));
+        const basegfx::B2DPoint 
aObjectRangeCenter(rObj.getObjectRange().getCenter());
+        basegfx::B2DRange aObjectRange(rObj.getObjectRange());
+        bool bChanged(false);
+
+        if(!aCurrentCenter.equal(aObjectRangeCenter))
+        {
+            const basegfx::B2DHomMatrix aAdaptToCenterRotation(
+                basegfx::tools::createTranslateB2DHomMatrix(
+                    aCurrentCenter - aObjectRangeCenter));
+
+            aObjectRange.transform(aAdaptToCenterRotation);
+            bChanged = true;
+        }
+
+        // do use inverted rotation here: The old model format (in which the 
value is here)
+        // was wrongly oriented. PPT uses the correct mathematical 
orientation, so invert
+        sal_Int32 nAngle(36000 - rObj.GetAngle());
+
+        // adapt angle to MS format
+        nAngle *= 655;
+        nAngle += 0x8000;
+        nAngle &=~0xffff; // round to full degrees
+        rPropOpt.AddOpt(ESCHER_Prop_Rotation, nAngle);
+        rObj.SetAngle( nAngle );
 
-       double fVal = (double)nAngle * F_PI18000;
-       double  fCos = cos( fVal );
-       double  fSin = sin( fVal );
-
-    basegfx::B2DPoint aPoint(rObj.getObjectRange().getMinimum());
-    const basegfx::B2DVector aScale(rObj.getObjectRange().getRange());
-       const basegfx::B2DVector aHalfScale(aScale * 0.5);
-       const double nXDiff(fCos * aHalfScale.getX() + fSin * 
(-aHalfScale.getY()));
-       const double nYDiff(-( fSin * aHalfScale.getX() - fCos * ( 
-aHalfScale.getY())));
-
-    aPoint -= basegfx::B2DPoint(aHalfScale.getX() - nXDiff, aHalfScale.getY() 
+ nYDiff);
-
-       nAngle *= 655;
-       nAngle += 0x8000;
-       nAngle &=~0xffff;                                                       
                // nAngle auf volle Gradzahl runden
-       rPropOpt.AddOpt( ESCHER_Prop_Rotation, nAngle );
+        if((nAngle >= (45 << 16) && nAngle < (135 << 16)) || (nAngle >= (225 
<< 16) && nAngle < (315 << 16)))
+        {
+            // in this region of rotation the ObjectRange is already rotated,
+            // so do this here, too
+            const basegfx::B2DHomMatrix aMirrorDiagonal(
+                basegfx::tools::createRotateAroundPoint(
+                    aObjectRange.getCenter(),
+                    F_PI2));
+
+            aObjectRange.transform(aMirrorDiagonal);
+            bChanged = true;
+        }
 
-       rObj.SetAngle( nAngle );
-       rObj.setObjectRange(basegfx::B2DRange(aPoint, aPoint + aScale));
+        rObj.setObjectRange(aObjectRange);
+    }
 }
 
 //     -----------------------------------------------------------------------
@@ -202,7 +222,7 @@ void ImplEESdrWriter::ImplFlipBoundingBo
        mpEscherEx->OpenContainer( ESCHER_SpContainer );                        
        \
        ADD_SHAPE( ESCHER_ShpInst_TextBox, 0xa00 );                             
                \
        if ( bFill )                                                            
                                        \
-               aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );      
\
+               aPropOpt.CreateFillProperties( rObj.mXPropSet, true );      \
        if( rObj.ImplGetText() )                                                
                                \
                aPropOpt.CreateTextProperties( rObj.mXPropSet,                  
        \
                        mpEscherEx->QueryTextID( rObj.GetShapeRef(),            
        \
@@ -222,8 +242,8 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
 {
        sal_uInt32 nShapeID = 0;
        sal_uInt16 nShapeType = 0;
-       sal_Bool bDontWriteText = sal_False;            // if a metafile is 
written as shape replacement, then the text is already part of the metafile
-       sal_Bool bAdditionalText = sal_False;
+       bool bDontWriteText(false);             // if a metafile is written as 
shape replacement, then the text is already part of the metafile
+       bool bAdditionalText(false);
        sal_uInt32 nGrpShapeID = 0;
 
        do {
@@ -261,7 +281,9 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                        }
                        break;
                }
-               rObj.SetAngle( rObj.ImplGetInt32PropertyValue( 
::rtl::OUString::createFromAscii("RotateAngle") ));
+
+        // TTTT: Moved to below (at transformation)
+        // rObj.SetAngle( rObj.ImplGetInt32PropertyValue( 
::rtl::OUString::createFromAscii("RotateAngle") ));
 
                if( ( rObj.ImplGetPropertyValue( 
::rtl::OUString::createFromAscii("IsFontwork") ) &&
                        ::cppu::any2bool( rObj.GetUsrAny() ) ) ||
@@ -285,26 +307,46 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
         basegfx::B2DRange aObjectRange(0.0, 0.0, 1.0, 1.0);
         sal_uInt32 nMirrorFlags(0);
 
-               
if(rObj.ImplGetPropertyValue(::rtl::OUString::createFromAscii("Transformation")))
         {
-                   drawing::HomogenMatrix3 aMatrix;
-            rObj.GetUsrAny() >>= aMatrix;
-            const basegfx::tools::B2DHomMatrixBufferedDecompose 
aMat(basegfx::tools::UnoHomogenMatrix3ToB2DHomMatrix(aMatrix));
-            // do not use absolute value of scale, it is WANTED
-            // that the range is really covering the unrotated, unmirrored 
shape
+            const basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& 
rMat(rObj.getTransform());
+            
+            // Use translation and scale to create range. Use signed scale
+            // to get the unrotated SnapRect
             aObjectRange = basegfx::B2DRange(
-                aMat.getTranslate(), 
-                aMat.getTranslate() + aMat.getScale()); 
+                rMat.getTranslate(), 
+                rMat.getTranslate() + rMat.getScale());
+
+            double fObjectRotation(rMat.getRotate());
+            bool bMirroredX(rMat.getScale().getX() < 0.0);
+            bool bMirroredY(rMat.getScale().getY() < 0.0);
+
+            // if mirror is X and Y, replace with 180 degree rotation. Prefer
+            // rotation export over mirror export.
+            if(bMirroredX && bMirroredY)
+            {
+                bMirroredX = bMirroredY = false;
+                fObjectRotation += F_PI;
+            }
 
-            if(aMat.getScale().getX() < 0.0)
+            if(bMirroredX)
             {
                 nMirrorFlags |= SHAPEFLAG_FLIPH;
             }
 
-            if(aMat.getScale().getY() < 0.0)
+            if(bMirroredY)
             {
                 nMirrorFlags |= SHAPEFLAG_FLIPV;
             }
+
+            if(bMirroredX != bMirroredY)
+            {
+                // if one axis is mirrored, invert the rotation
+                fObjectRotation = -fObjectRotation;
+            }
+
+            // convert rotation to old coordinate system and set
+            const double 
fSnappedRotation(basegfx::snapToZeroRange(-fObjectRotation / F_PI18000, 
36000.0));
+            rObj.SetAngle(basegfx::fround(fSnappedRotation));
         }
 
         if ( !mpPicStrm )
@@ -328,7 +370,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                                ADD_SHAPE( 
                     ESCHER_ShpInst_PictureFrame,
                     0xa00 ); // TTTT: no mirroring, metafile export version
-                               if ( aPropOpt.CreateGraphicProperties( 
rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False 
) )
+                               if ( aPropOpt.CreateGraphicProperties( 
rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), false ) )
                                {
                                        aPropOpt.AddOpt( 
ESCHER_Prop_LockAgainstGrouping, 0x800080 );
                                        aPropOpt.AddOpt( 
ESCHER_Prop_fNoFillHitTest, 0x100000 );                // no fill
@@ -340,7 +382,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                                                
                                                rObj.setObjectRange(aRange);
                                                rObj.SetAngle( 0 );
-                                               bDontWriteText = sal_True;
+                                               bDontWriteText = true;
                                        }
                                }
                        }
@@ -350,12 +392,12 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                     sal::static_int_cast< sal_uInt16 >(eShapeType),
                     nMirrorFlags | 0xa00 ); // Flags: mirror | Connector | 
HasSpt
                                aPropOpt.CreateCustomShapeProperties( 
eShapeType, rObj.GetShapeRef() );
-                               aPropOpt.CreateFillProperties( rObj.mXPropSet, 
sal_True );
+                               aPropOpt.CreateFillProperties( rObj.mXPropSet, 
true );
                                if ( rObj.ImplGetText() )
                                {
                                        if ( !aPropOpt.IsFontWork() )
                                                aPropOpt.CreateTextProperties( 
rObj.mXPropSet, mpEscherEx->QueryTextID(
-                                                       rObj.GetShapeRef(),     
rObj.GetShapeId() ), sal_True, sal_False );
+                                                       rObj.GetShapeRef(),     
rObj.GetShapeId() ), true, false );
                                }
                        }
                }
@@ -383,11 +425,11 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                     ESCHER_ShpInst_Rectangle, 
                     nMirrorFlags | 0xa00 );                    // Flags: 
mirror | Connector | HasSpt
                        }
-                       aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True 
);
+                       aPropOpt.CreateFillProperties( rObj.mXPropSet, true );
                        if( rObj.ImplGetText() )
                                aPropOpt.CreateTextProperties( rObj.mXPropSet,
                                        mpEscherEx->QueryTextID( 
rObj.GetShapeRef(),
-                                               rObj.GetShapeId() ), sal_False, 
sal_False );
+                                               rObj.GetShapeId() ), false, 
false );
                }
                else if ( rObj.GetType().EqualsAscii( "drawing.Ellipse" ))
                {
@@ -405,7 +447,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                                ADD_SHAPE( 
                     ESCHER_ShpInst_Ellipse, 
                     nMirrorFlags | 0xa00 );                    // Flags: 
mirror | Connector | HasSpt
-                               aPropOpt.CreateFillProperties( rObj.mXPropSet, 
sal_True );;
+                               aPropOpt.CreateFillProperties( rObj.mXPropSet, 
true );;
             }
                        else
                        {
@@ -431,13 +473,13 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
 
                 if(aOutline.isClosed())
                 {
-                                       aPropOpt.CreatePolygonProperties( 
rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, 
&aPolygon );
-                                       aPropOpt.CreateFillProperties( 
rObj.mXPropSet, sal_True  );
+                                       aPropOpt.CreatePolygonProperties( 
rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, false, aNewRect, &aPolygon );
+                                       aPropOpt.CreateFillProperties( 
rObj.mXPropSet, true  );
                 }
                 else
                 {
-                                       aPropOpt.CreatePolygonProperties( 
rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, &aPolygon );
-                                       aPropOpt.CreateLineProperties( 
rObj.mXPropSet, sal_False );
+                                       aPropOpt.CreatePolygonProperties( 
rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, false, aNewRect, &aPolygon );
+                                       aPropOpt.CreateLineProperties( 
rObj.mXPropSet, false );
                 }
                                
                 const basegfx::B2DRange 
aRange(ImplMapB2DRange(basegfx::B2DRange(aNewRect.X, aNewRect.Y, aNewRect.X + 
aNewRect.Width, aNewRect.Y + aNewRect.Height)));
@@ -447,7 +489,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                        if ( rObj.ImplGetText() )
                                aPropOpt.CreateTextProperties( rObj.mXPropSet,
                                        mpEscherEx->QueryTextID( 
rObj.GetShapeRef(),
-                                               rObj.GetShapeId() ), sal_False, 
sal_False );
+                                               rObj.GetShapeId() ), false, 
false );
 
                }
                else if ( rObj.GetType().EqualsAscii( "drawing.Control" ))
@@ -459,7 +501,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                        sal_uInt16 nSpType, nSpFlags;
                        ::com::sun::star::awt::Rectangle aNewRect;
                        if ( aPropOpt.CreateConnectorProperties( 
rObj.GetShapeRef(),
-                                                       rSolverContainer, 
aNewRect, nSpType, nSpFlags ) == sal_False )
+                                                       rSolverContainer, 
aNewRect, nSpType, nSpFlags ) == false )
                                break;
 
             const basegfx::B2DRange 
aRange(ImplMapB2DRange(basegfx::B2DRange(aNewRect.X, aNewRect.Y, aNewRect.X + 
aNewRect.Width, aNewRect.Y + aNewRect.Height)));
@@ -477,7 +519,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                        {
                                mpEscherEx->EnterGroup( &maRect );
                                mpEscherEx->OpenContainer( ESCHER_SpContainer );
-                               ImplWriteAny( ANY_FLAGS_LINE, sal_False );
+                               ImplWriteAny( ANY_FLAGS_LINE, false );
                                sal_uInt32 nFlags = 0xa00;                      
                                                                // Flags: 
Connector | HasSpt
                                if ( maRect.Top() > maRect.Bottom() )
                                        nFlags |= 0x80;                         
                                                                // Flags: 
VertMirror
@@ -488,7 +530,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                     ESCHER_ShpInst_Line, 
                     nMirrorFlags | nFlags ); // Flags: mirror | nFlags
                                aPropOpt.AddOpt( ESCHER_Prop_shapePath, 
ESCHER_ShapeComplex );
-                               aPropOpt.CreateLineProperties( rObj.mXPropSet, 
sal_False );
+                               aPropOpt.CreateLineProperties( rObj.mXPropSet, 
false );
                                mpEscherEx->EndCount( ESCHER_OPT, 3 );
                                maRect.Justify();
                                mpEscherEx->AddClientAnchor( maRect );
@@ -559,7 +601,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                else if ( rObj.GetType().EqualsAscii( "drawing.Line" ))
                {
                        ::com::sun::star::awt::Rectangle aNewRect;
-                       aPropOpt.CreatePolygonProperties( rObj.mXPropSet, 
ESCHER_CREATEPOLYGON_LINE, sal_False, aNewRect, NULL );
+                       aPropOpt.CreatePolygonProperties( rObj.mXPropSet, 
ESCHER_CREATEPOLYGON_LINE, false, aNewRect, NULL );
             MapRect(rObj);
                        //i27942: Poly/Lines/Bezier do not support text.
 
@@ -576,7 +618,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                 ESCHER_ShpInst_Line, 
                 nMirrorFlags ); // Flags: mirror
                        aPropOpt.AddOpt( ESCHER_Prop_shapePath, 
ESCHER_ShapeComplex );
-                       aPropOpt.CreateLineProperties( rObj.mXPropSet, 
sal_False );
+                       aPropOpt.CreateLineProperties( rObj.mXPropSet, false );
                        rObj.SetAngle( 0 );
                }
                else if ( rObj.GetType().EqualsAscii( "drawing.PolyPolygon" ))
@@ -584,16 +626,16 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                        if( rObj.ImplHasText() )
                        {
                                nGrpShapeID = ImplEnterAdditionalTextGroup(     
rObj.GetShapeRef(), &rObj.getObjectRange() );
-                               bAdditionalText = sal_True;
+                               bAdditionalText = true;
                        }
                        mpEscherEx->OpenContainer( ESCHER_SpContainer );
                        ADD_SHAPE( 
                 ESCHER_ShpInst_NotPrimitive, 
                 nMirrorFlags | 0xa00 );                // Flags: mirror | 
Connector | HasSpt
                        ::com::sun::star::awt::Rectangle aNewRect;
-                       aPropOpt.CreatePolygonProperties( rObj.mXPropSet, 
ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, NULL );
+                       aPropOpt.CreatePolygonProperties( rObj.mXPropSet, 
ESCHER_CREATEPOLYGON_POLYPOLYGON, false, aNewRect, NULL );
             MapRect(rObj);
-                       aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True 
);
+                       aPropOpt.CreateFillProperties( rObj.mXPropSet, true );
                        rObj.SetAngle( 0 );
                }
                else if ( rObj.GetType().EqualsAscii( "drawing.PolyLine" ))
@@ -605,9 +647,9 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                 ESCHER_ShpInst_NotPrimitive, 
                 nMirrorFlags | 0xa00 );                // Flags: mirror | 
Connector | HasSpt
                        ::com::sun::star::awt::Rectangle aNewRect;
-                       aPropOpt.CreatePolygonProperties( rObj.mXPropSet, 
ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, NULL );
+                       aPropOpt.CreatePolygonProperties( rObj.mXPropSet, 
ESCHER_CREATEPOLYGON_POLYLINE, false, aNewRect, NULL );
             MapRect(rObj);
-                       aPropOpt.CreateLineProperties( rObj.mXPropSet, 
sal_False );
+                       aPropOpt.CreateLineProperties( rObj.mXPropSet, false );
                        rObj.SetAngle( 0 );
                }
                else if ( rObj.GetType().EqualsAscii( "drawing.OpenBezier" ) )
@@ -619,9 +661,9 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                 ESCHER_ShpInst_NotPrimitive, 
                 nMirrorFlags | 0xa00 );                // Flags: mirror | 
Connector | HasSpt
                        ::com::sun::star::awt::Rectangle aNewRect;
-                       aPropOpt.CreatePolygonProperties( rObj.mXPropSet, 
ESCHER_CREATEPOLYGON_POLYLINE, sal_True, aNewRect, NULL );
+                       aPropOpt.CreatePolygonProperties( rObj.mXPropSet, 
ESCHER_CREATEPOLYGON_POLYLINE, true, aNewRect, NULL );
             MapRect(rObj);
-                       aPropOpt.CreateLineProperties( rObj.mXPropSet, 
sal_False );
+                       aPropOpt.CreateLineProperties( rObj.mXPropSet, false );
                        rObj.SetAngle( 0 );
                }
                else if ( rObj.GetType().EqualsAscii( "drawing.ClosedBezier" ) )
@@ -629,16 +671,16 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                        if ( rObj.ImplHasText() )
                        {
                                nGrpShapeID = ImplEnterAdditionalTextGroup(     
rObj.GetShapeRef(), &rObj.getObjectRange() );
-                               bAdditionalText = sal_True;
+                               bAdditionalText = true;
                        }
                        mpEscherEx->OpenContainer( ESCHER_SpContainer );
                        ADD_SHAPE( 
                 ESCHER_ShpInst_NotPrimitive, 
                 nMirrorFlags | 0xa00 );                // Flags: mirror | 
Connector | HasSpt
                        ::com::sun::star::awt::Rectangle aNewRect;
-                       aPropOpt.CreatePolygonProperties( rObj.mXPropSet, 
ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_True, aNewRect, NULL );
+                       aPropOpt.CreatePolygonProperties( rObj.mXPropSet, 
ESCHER_CREATEPOLYGON_POLYPOLYGON, true, aNewRect, NULL );
             MapRect(rObj);
-                       aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True 
);
+                       aPropOpt.CreateFillProperties( rObj.mXPropSet, true );
                        rObj.SetAngle( 0 );
                }
                else if ( rObj.GetType().EqualsAscii( "drawing.GraphicObject" ))
@@ -668,7 +710,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                                        ADD_SHAPE( 
                         ESCHER_ShpInst_Rectangle, 
                         nMirrorFlags | 0xa00 );                        // 
Flags: mirror | Connector | HasSpt
-                                       if ( aPropOpt.CreateGraphicProperties( 
rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), 
sal_True,  sal_True, sal_False ) )
+                                       if ( aPropOpt.CreateGraphicProperties( 
rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), true,  
true, false ) )
                                        {
                                                aPropOpt.AddOpt( 
ESCHER_Prop_WrapText, ESCHER_WrapNone );
                                                aPropOpt.AddOpt( 
ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
@@ -678,7 +720,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                                                if ( rObj.ImplGetText() )
                                                        
aPropOpt.CreateTextProperties( rObj.mXPropSet,
                                                                
mpEscherEx->QueryTextID( rObj.GetShapeRef(),
-                                                                       
rObj.GetShapeId() ), sal_False, sal_False );
+                                                                       
rObj.GetShapeId() ), false, false );
                                        }
                                }
                                else
@@ -686,14 +728,14 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                                        ADD_SHAPE( 
                         ESCHER_ShpInst_PictureFrame, 
                         nMirrorFlags | 0xa00 ); // Flags: mirror | Connector | 
HasSpt
-                                       if ( aPropOpt.CreateGraphicProperties( 
rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), 
sal_False, sal_True ) )
+                                       if ( aPropOpt.CreateGraphicProperties( 
rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), false, 
true ) )
                                                aPropOpt.AddOpt( 
ESCHER_Prop_LockAgainstGrouping, 0x800080 );
                                }
                        }
                }
                else if ( rObj.GetType().EqualsAscii(  "drawing.Text" ))
                {
-                       SHAPE_TEXT( sal_True );
+                       SHAPE_TEXT( true );
                }
                else if ( rObj.GetType().EqualsAscii( "drawing.Page" ))
                {
@@ -729,7 +771,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                        else
                        {
                                //2do: could be made an option in HostAppData 
whether OLE object should be written or not
-                               sal_Bool bAppOLE = sal_True;
+                               bool bAppOLE(true);
                                ADD_SHAPE( 
                     ESCHER_ShpInst_PictureFrame,
                                        nMirrorFlags | 0xa00 | (bAppOLE ? 
SHAPEFLAG_OLESHAPE : 0) ); // Flags: mirror | Connector | HasSpt | OLE
@@ -763,7 +805,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                 nMirrorFlags | ESCHER_ShpInst_PictureFrame, // TTTT: Probably 
nor mirror needed, check
                 0xa00 ); // Flags: Connector | HasSpt
 
-                if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( 
RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ), sal_False ) )
+                if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( 
RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ), false ) )
                                aPropOpt.AddOpt( 
ESCHER_Prop_LockAgainstGrouping, 0x800080 );
                }
                else if ( rObj.GetType().EqualsAscii( "drawing.dontknow" ))
@@ -773,7 +815,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                        ADD_SHAPE( 
                 ESCHER_ShpInst_PictureFrame, 
                 nMirrorFlags | 0xa00 ); // Flags: mirror | Connector | HasSpt
-                       if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, 
String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) )
+                       if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, 
String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), false ) )
                                aPropOpt.AddOpt( 
ESCHER_Prop_LockAgainstGrouping, 0x800080 );
                }
                else
@@ -790,7 +832,9 @@ sal_uInt32 ImplEESdrWriter::ImplWriteSha
                }
 
                if( rObj.GetAngle() )
-                       ImplFlipBoundingBox( rObj, aPropOpt );
+        {
+                       ImplHandleRotation( rObj, aPropOpt );
+        }
 
                aPropOpt.CreateShapeProperties( rObj.GetShapeRef() );
                mpEscherEx->Commit( aPropOpt, rObj.getObjectRange() );
@@ -835,22 +879,53 @@ void ImplEESdrWriter::ImplWriteAdditiona
 
         // TTTT: adapted to transformation
         basegfx::B2DRange aObjectRange(0.0, 0.0, 1.0, 1.0);
+        sal_uInt32 nMirrorFlags(0);
 
-               
if(rObj.ImplGetPropertyValue(::rtl::OUString::createFromAscii("Transformation")))
         {
-                   drawing::HomogenMatrix3 aMatrix;
-            rObj.GetUsrAny() >>= aMatrix;
-            const basegfx::tools::B2DHomMatrixBufferedDecompose 
aMat(basegfx::tools::UnoHomogenMatrix3ToB2DHomMatrix(aMatrix));
-            aObjectRange = basegfx::B2DRange(aMat.getTranslate(), 
aMat.getTranslate() + basegfx::absolute(aMat.getScale()));
+            const basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& 
rMat(rObj.getTransform());
+
+            // Use translation and scale to create range. Use signed scale
+            // to get the unrotated SnapRect
+            aObjectRange = basegfx::B2DRange(
+                rMat.getTranslate(), 
+                rMat.getTranslate() + rMat.getScale());
+
+            double fObjectRotation(rMat.getRotate());
+            bool bMirroredX(rMat.getScale().getX() < 0.0);
+            bool bMirroredY(rMat.getScale().getY() < 0.0);
+
+            // if mirror is X and Y, replace with 180 degree rotation. Prefer
+            // rotation export over mirror export.
+            if(bMirroredX && bMirroredY)
+            {
+                bMirroredX = bMirroredY = false;
+                fObjectRotation += F_PI;
+            }
+
+            if(bMirroredX)
+            {
+                nMirrorFlags |= SHAPEFLAG_FLIPH;
+            }
+
+            if(bMirroredY)
+            {
+                nMirrorFlags |= SHAPEFLAG_FLIPV;
+            }
+
+            // convert rotation to old coordinate system and set
+            const double 
fSnappedRotation(basegfx::snapToZeroRange(-fObjectRotation / F_PI18000, 
36000.0));
+            rObj.SetAngle(basegfx::fround(fSnappedRotation));
         }
-               
+
         if ( !mpPicStrm )
             mpPicStrm = mpEscherEx->QueryPictureStream();
         
         EscherPropertyContainer aPropOpt( mpEscherEx->GetGraphicProvider(), 
mpPicStrm, aObjectRange );
 
-        rObj.SetAngle( rObj.ImplGetInt32PropertyValue( 
::rtl::OUString::createFromAscii("RotateAngle")));
-               sal_Int32 nAngle = rObj.GetAngle();
+        // TTTT: Done above, see transformation
+        // rObj.SetAngle( rObj.ImplGetInt32PropertyValue( 
::rtl::OUString::createFromAscii("RotateAngle")));
+
+        sal_Int32 nAngle = rObj.GetAngle();
                if( rObj.GetType().EqualsAscii( "drawing.Line" ))
                {
 //2do: this does not work right
@@ -859,7 +934,9 @@ void ImplEESdrWriter::ImplWriteAdditiona
             
             rObj.setObjectRange(aRange);
                        mpEscherEx->OpenContainer( ESCHER_SpContainer );
-                       mpEscherEx->AddShape( ESCHER_ShpInst_TextBox, 0xa00 );
+                       mpEscherEx->AddShape( 
+                ESCHER_ShpInst_TextBox, 
+                nMirrorFlags | 0xa00 ); // Flags: mirror | Connector | HasSpt
                        
             if ( rObj.ImplGetText() )
                                aPropOpt.CreateTextProperties( rObj.mXPropSet,
@@ -869,16 +946,25 @@ void ImplEESdrWriter::ImplWriteAdditiona
                        aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 );
                        aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
                        aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x60006 ); 
        // Size Shape To Fit Text
-                       if ( nAngle < 0 )
+                       
+            if ( nAngle < 0 )
+            {
                                nAngle = ( 36000 + nAngle ) % 36000;
+            }
+
                        if ( nAngle )
-                               ImplFlipBoundingBox( rObj, aPropOpt );
+            {
+                               ImplHandleRotation( rObj, aPropOpt );
+            }
                }
                else
                {
                        mpEscherEx->OpenContainer( ESCHER_SpContainer );
             nShapeID = mpEscherEx->GenerateShapeId();
-                       mpEscherEx->AddShape( nShapeType = 
ESCHER_ShpInst_TextBox, 0xa00, nShapeID );
+                       mpEscherEx->AddShape( 
+                nShapeType = ESCHER_ShpInst_TextBox, 
+                nMirrorFlags | 0xa00, // Flags: mirror | Connector | HasSpt
+                nShapeID );
                        if ( rObj.ImplGetText() )
                                aPropOpt.CreateTextProperties( rObj.mXPropSet,
                                        mpEscherEx->QueryTextID( 
rObj.GetShapeRef(),
@@ -898,7 +984,8 @@ void ImplEESdrWriter::ImplWriteAdditiona
                        mpEscherEx->SetGroupSnapPositionAndScale( 
mpEscherEx->GetGroupLevel(), rObj.getObjectRange() );
                        mpEscherEx->SetGroupLogicPositionAndScale( 
mpEscherEx->GetGroupLevel(), rObj.getObjectRange() );
                }
-               rObj.SetAngle( nAngle );
+
+        rObj.SetAngle( nAngle );
                aPropOpt.CreateShapeProperties( rObj.GetShapeRef() );
                mpEscherEx->Commit( aPropOpt, rObj.getObjectRange() );
 
@@ -944,14 +1031,14 @@ sal_uInt32 ImplEESdrWriter::ImplEnterAdd
 
 // -------------------------------------------------------------------
 
-sal_Bool ImplEESdrWriter::ImplInitPageValues()
+bool ImplEESdrWriter::ImplInitPageValues()
 {
        mnIndices = 0;
        mnOutlinerCount = 0;                            // die 
gliederungsobjekte muessen dem layout entsprechen,
        mnEffectCount = 0;
-       mbIsTitlePossible = sal_True;                   // bei mehr als einem 
title geht powerpoint in die knie
+       mbIsTitlePossible = true;                       // bei mehr als einem 
title geht powerpoint in die knie
 
-       return sal_True;
+       return true;
 }
 
 
@@ -959,7 +1046,7 @@ sal_Bool ImplEESdrWriter::ImplInitPageVa
 
 void ImplEESdrWriter::ImplWritePage(
                        EscherSolverContainer& rSolverContainer,
-                       ImplEESdrPageType ePageType, sal_Bool /* bBackGround */ 
)
+                       ImplEESdrPageType ePageType, bool /* bBackGround */ )
 {
        ImplInitPageValues();
 
@@ -1195,14 +1282,18 @@ const SdrObject* EscherEx::GetSdrObject(
 
 // -------------------------------------------------------------------
 
-ImplEESdrObject::ImplEESdrObject( ImplEscherExSdr& rEx,
-                                                                       const 
SdrObject& rObj ) :
-       mnShapeId( 0 ),
-       mnTextSize( 0 ),
-       mnAngle( 0 ),
-       mbValid( sal_False ),
-       mbPresObj( sal_False ),
-       mbEmptyPresObj( sal_False )
+ImplEESdrObject::ImplEESdrObject( ImplEscherExSdr& rEx, const SdrObject& rObj 
) 
+:   mXShape(),
+    mAny(),
+    maObjectRange(),
+    maObjTrans(),
+    mType(),
+       mnShapeId(0),
+       mnTextSize(0),
+       mnAngle(0),
+       mbValid(false),
+       mbPresObj(false),
+       mbEmptyPresObj( false)
 {
        SdrPage* pPage = rObj.getSdrPageFromSdrObject();
        DBG_ASSERT( pPage, "ImplEESdrObject::ImplEESdrObject: no SdrPage" );
@@ -1210,20 +1301,23 @@ ImplEESdrObject::ImplEESdrObject( ImplEs
     {
         // why not declare a const parameter if the object will
         // not be modified?
-        mXShape = uno::Reference< drawing::XShape >::query( 
((SdrObject*)&rObj)->getUnoShape() );;
+        mXShape = uno::Reference< drawing::XShape >::query( 
((SdrObject*)&rObj)->getUnoShape() );
         Init( rEx );
     }
 }
 
-ImplEESdrObject::ImplEESdrObject( ImplEESdrWriter& rEx,
-                                                                       const 
Reference< XShape >& rShape ) :
-       mXShape( rShape ),
-       mnShapeId( 0 ),
-       mnTextSize( 0 ),
-       mnAngle( 0 ),
-       mbValid( sal_False ),
-       mbPresObj( sal_False ),
-       mbEmptyPresObj( sal_False )
+ImplEESdrObject::ImplEESdrObject( ImplEESdrWriter& rEx, const Reference< 
XShape >& rShape ) 
+:   mXShape(rShape),
+    mAny(),
+    maObjectRange(),
+    maObjTrans(),
+    mType(),
+       mnShapeId(0),
+       mnTextSize(0),
+       mnAngle(0),
+       mbValid(false),
+       mbPresObj(false),
+       mbEmptyPresObj(false)
 {
        Init( rEx );
 }
@@ -1271,59 +1365,44 @@ basegfx::B2DRange getUnrotatedGroupBound
                 if(mXPropSet.is())
                 {
                     const Any aAny = 
mXPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation")));
-                    
-                    if(aAny.hasValue())
+                    HomogenMatrix3 aMatrix;
+
+                    if(aAny.hasValue() && (aAny >>= aMatrix))
                     {
-                        HomogenMatrix3 aMatrix;
+                        basegfx::B2DHomMatrix aHomogenMatrix(
+                            
basegfx::tools::UnoHomogenMatrix3ToB2DHomMatrix(aMatrix));
+                        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());
+                        }
 
-                        if(aAny >>= aMatrix)
+                        // check if shear needs to be corrected (always 
correct shear,
+                        // ppt does not know about it)
+                        if(!basegfx::fTools::equalZero(fShearX))
                         {
-                            basegfx::B2DHomMatrix aHomogenMatrix;
+                            const basegfx::B2DPoint aMinimum(aHomogenMatrix * 
basegfx::B2DPoint(0.0, 0.0));
 
-                            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));
+                            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));
                     }
                 }
             }
@@ -1360,12 +1439,34 @@ void ImplEESdrObject::Init( ImplEESdrWri
         else
         {
             // if it's no group, use position and size directly, 
roated/sheared or not
-            const ::com::sun::star::awt::Point aPoint(mXShape->getPosition());
-            const ::com::sun::star::awt::Size aSize(mXShape->getSize());
-            const basegfx::B2DRange aRange(
-                basegfx::B2DRange(
+            const Any aAny = 
mXPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation")));
+            drawing::HomogenMatrix3 aMatrix;
+            basegfx::B2DRange aRange;
+
+            if(aAny.hasValue() && (aAny >>= aMatrix))
+            {
+                maObjTrans = 
basegfx::tools::UnoHomogenMatrix3ToB2DHomMatrix(aMatrix);
+
+                // Use translation and scale to create range. Use signed scale
+                // to get the unrotated SnapRect
+                aRange = basegfx::B2DRange(
+                    maObjTrans.getTranslate(), 
+                    maObjTrans.getTranslate() + maObjTrans.getScale());
+            }
+            else
+            {
+                // fallback to getPosition/getSize(), but will miss mirrorings
+                // and should not be necessary
+                const ::com::sun::star::awt::Point 
aPoint(mXShape->getPosition());
+                const ::com::sun::star::awt::Size aSize(mXShape->getSize());
+
+                maObjTrans = basegfx::tools::createScaleTranslateB2DHomMatrix(
+                    aSize.Width, aSize.Height,
+                    aPoint.X, aPoint.Y);
+                aRange = basegfx::B2DRange(
                     aPoint.X, aPoint.Y, 
-                    aPoint.X + aSize.Width, aPoint.Y + aSize.Height));
+                    aPoint.X + aSize.Width, aPoint.Y + aSize.Height);
+            }
 
             setObjectRange(rEx.ImplMapB2DRange(aRange));
         }
@@ -1374,51 +1475,55 @@ void ImplEESdrObject::Init( ImplEESdrWri
                static const OUString 
sEmptyPresStr(rtl::OUString::createFromAscii("IsEmptyPresentationObject"));
 
                if( ImplGetPropertyValue( sPresStr ) )
+        {
                        mbPresObj = ::cppu::any2bool( mAny );
+        }
 
                if( mbPresObj && ImplGetPropertyValue( sEmptyPresStr ) )
+        {
                        mbEmptyPresObj = ::cppu::any2bool( mAny );
+        }
 
-               mbValid = sal_True;
+               mbValid = true;
        }
 }
 
-//sal_Bool ImplEESdrObject::ImplGetPropertyValue( const OUString& rString )
-sal_Bool ImplEESdrObject::ImplGetPropertyValue( const sal_Unicode* rString )
+//bool ImplEESdrObject::ImplGetPropertyValue( const OUString& rString )
+bool ImplEESdrObject::ImplGetPropertyValue( const sal_Unicode* rString )
 {
-       sal_Bool bRetValue = sal_False;
+       bool bRetValue(false);
        if( mbValid )
        {
                try
                {
                        mAny = mXPropSet->getPropertyValue( rString );
                        if( mAny.hasValue() )
-                               bRetValue = sal_True;
+                               bRetValue = true;
                }
                catch( ::com::sun::star::uno::Exception& )
                {
-                       bRetValue = sal_False;
+                       bRetValue = false;
                }
        }
        return bRetValue;
 }
 
 #ifdef USED
-sal_Bool ImplEESdrObject::ImplGetPropertyValue( const Reference< XPropertySet 
>& rXPropSet,
+bool ImplEESdrObject::ImplGetPropertyValue( const Reference< XPropertySet >& 
rXPropSet,
                                                                                
        const OUString& rString )
 {
-       sal_Bool bRetValue = sal_False;
+       bool bRetValue(false);
        if( mbValid )
        {
                try
                {
                        mAny = rXPropSet->getPropertyValue( rString );
                        if( 0 != mAny.get() )
-                               bRetValue = sal_True;
+                               bRetValue = true;
                }
                catch( ::com::sun::star::uno::Exception& )
                {
-                       bRetValue = sal_False;
+                       bRetValue = false;
                }
        }
        return bRetValue;
@@ -1440,9 +1545,10 @@ sal_uInt32 ImplEESdrObject::ImplGetText(
        return mnTextSize;
 }
 
-sal_Bool ImplEESdrObject::ImplHasText() const
+bool ImplEESdrObject::ImplHasText() const
 {
        Reference< XText > xXText( mXShape, UNO_QUERY );
        return xXText.is() && xXText->getString().getLength();
 }
 
+// eof

Modified: 
incubator/ooo/branches/alg/aw080/main/filter/source/msfilter/eschesdo.hxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/branches/alg/aw080/main/filter/source/msfilter/eschesdo.hxx?rev=1412988&r1=1412987&r2=1412988&view=diff
==============================================================================
--- incubator/ooo/branches/alg/aw080/main/filter/source/msfilter/eschesdo.hxx 
(original)
+++ incubator/ooo/branches/alg/aw080/main/filter/source/msfilter/eschesdo.hxx 
Fri Nov 23 17:14:30 2012
@@ -37,20 +37,24 @@ class ImplEscherExSdr;
 
 class ImplEESdrObject
 {
+private:
        ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >   
                mXShape;
 //     XTextRef                        mXText; // TextRef des globalen Text
        ::com::sun::star::uno::Any                              mAny;
        
     // the object range, split in pos and scale to keep the evtl. negative 
size (mirroring)
     basegfx::B2DRange   maObjectRange;
+    basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose   maObjTrans;
 
     String                             mType;
-       sal_uInt32                              mnShapeId;
-       sal_uInt32                              mnTextSize;
-       sal_Int32                               mnAngle;
-       sal_Bool                                mbValid : 1;
-       sal_Bool                                mbPresObj : 1;
-       sal_Bool                                mbEmptyPresObj : 1;
+       sal_uInt32                      mnShapeId;
+       sal_uInt32                      mnTextSize;
+       sal_Int32                       mnAngle;
+
+    /// bitfield
+       bool                mbValid : 1;
+       bool                mbPresObj : 1;
+       bool                mbEmptyPresObj : 1;
 
        void Init( ImplEESdrWriter& rEx );
 public:
@@ -60,7 +64,7 @@ public:
        ImplEESdrObject( ImplEESdrWriter& rEx, const 
::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rShape );
        ~ImplEESdrObject();
 
-       sal_Bool ImplGetPropertyValue( const sal_Unicode* pString );
+       bool ImplGetPropertyValue( const sal_Unicode* pString );
 
        sal_Int32 ImplGetInt32PropertyValue( const sal_Unicode* pStr, 
sal_uInt32 nDef = 0 )
        { return ImplGetPropertyValue( pStr ) ? *(sal_Int32*)mAny.getValue() : 
nDef; }
@@ -78,16 +82,18 @@ public:
 
        sal_uInt32                              GetTextSize() const     { 
return mnTextSize; }
 
-       sal_Bool                                IsValid() const                 
{ return mbValid; }
-       sal_Bool                                IsPresObj() const               
{ return mbPresObj; }
-       sal_Bool                                IsEmptyPresObj() const  { 
return mbEmptyPresObj; }
+       bool                            IsValid() const                 { 
return mbValid; }
+       bool                            IsPresObj() const               { 
return mbPresObj; }
+       bool                            IsEmptyPresObj() const  { return 
mbEmptyPresObj; }
        sal_uInt32                              GetShapeId() const              
{ return mnShapeId; }
        void                            SetShapeId( sal_uInt32 nVal ) { 
mnShapeId = nVal; }
 
        const SdrObject*        GetSdrObject() const;
 
        sal_uInt32                              ImplGetText();
-       sal_Bool                                ImplHasText() const;
+       bool                            ImplHasText() const;
+
+    basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& getTransform() { 
return maObjTrans; }
 };
 
 
@@ -141,26 +147,27 @@ protected:
 
                sal_uInt16                              mnEffectCount;
 
-               sal_Bool                                mbIsTitlePossible;
-               sal_Bool                                mbStatusIndicator;
-               sal_Bool                                mbStatus;
+        /// bitfield
+               bool                            mbIsTitlePossible : 1;
+               bool                            mbStatusIndicator : 1;
+               bool                            mbStatus : 1;
 
 
                                                                
ImplEESdrWriter( EscherEx& rEx );
 
-                       sal_Bool                                
ImplInitPageValues();
+                       bool                            ImplInitPageValues();
 
                        void                            ImplWritePage(
                                                                        
EscherSolverContainer& rSolver,
                                                                        
ImplEESdrPageType ePageType,
-                                                                       
sal_Bool bBackGround = sal_False );
+                                                                       bool 
bBackGround = false );
 
                        sal_uInt32                              ImplWriteShape( 
ImplEESdrObject& rObj,
                                                                        
EscherSolverContainer& rSolver,
                                                                        
ImplEESdrPageType ePageType );  // returns ShapeID
 
-                       void                            ImplFlipBoundingBox( 
ImplEESdrObject& rObj, EscherPropertyContainer& rPropOpt );
-                       sal_Bool                                ImplGetText( 
ImplEESdrObject& rObj );
+                       void                            ImplHandleRotation( 
ImplEESdrObject& rObj, EscherPropertyContainer& rPropOpt );
+                       bool                            ImplGetText( 
ImplEESdrObject& rObj );
                        void                            ImplWriteAdditionalText(
                                                                                
                ImplEESdrObject& rObj,
                                                                                
                const Point& rTextRefPoint );
@@ -170,7 +177,7 @@ protected:
 
 
 public:
-//                     basegfx::B2DPoint ImplMapB2DPoint( const 
basegfx::B2DPoint& rPoint );
+                       basegfx::B2DPoint ImplMapB2DPoint( const 
basegfx::B2DPoint& rPoint );
                        basegfx::B2DVector ImplMapB2DVector( const 
basegfx::B2DVector& rScale );
                        basegfx::B2DRange ImplMapB2DRange(const 
basegfx::B2DRange& rRange);
 

Modified: incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/eppt.cxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/eppt.cxx?rev=1412988&r1=1412987&r2=1412988&view=diff
==============================================================================
--- incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/eppt.cxx 
(original)
+++ incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/eppt.cxx Fri 
Nov 23 17:14:30 2012
@@ -150,6 +150,7 @@ PPTWriter::PPTWriter( const std::vector<
     mXCursorPropSet(),
     mXTextField(),
     maObjectRange(),
+    maObjTrans(),
     mnMirrorFlags(0),
     mfObjectRotation(0.0),
     mType(),

Modified: incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/eppt.hxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/eppt.hxx?rev=1412988&r1=1412987&r2=1412988&view=diff
==============================================================================
--- incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/eppt.hxx 
(original)
+++ incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/eppt.hxx Fri 
Nov 23 17:14:30 2012
@@ -709,6 +709,7 @@ class PPTWriter : public GroupTable, pub
                
         // the object range, split in pos and scale to keep the evtl. negative 
size (mirroring)
         basegfx::B2DRange               maObjectRange;
+        basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose   maObjTrans;
 //        basegfx::B2DRange               maObjectRange; // TTTT mirrored 
needed here ?!?
         sal_uInt32                      mnMirrorFlags;
 //        bool                            mbMirroredX;

Modified: incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/epptso.cxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/epptso.cxx?rev=1412988&r1=1412987&r2=1412988&view=diff
==============================================================================
--- incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/epptso.cxx 
(original)
+++ incubator/ooo/branches/alg/aw080/main/sd/source/filter/eppt/epptso.cxx Fri 
Nov 23 17:14:30 2012
@@ -1138,40 +1138,56 @@ bool PPTWriter::ImplGetShapeByIndex( sal
             break;
         
         // get object transformation
-        basegfx::tools::B2DHomMatrixBufferedDecompose 
aObjTrans(ImplGetObjectTransformation());
+        maObjTrans = ImplGetObjectTransformation();
 
         // map to PPt metrics
-        aObjTrans = basegfx::tools::B2DHomMatrixBufferedDecompose(
-            basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
-                maMap100thMmToMs* aObjTrans.getScale(),
-                aObjTrans.getShearX(),
-                aObjTrans.getRotate(),
-                maMap100thMmToMs * aObjTrans.getTranslate()));
-
-        // Use translation and scale to create range.
-        // Do not use absolute value of scale, it is WANTED
-        // that the range is really covering the unrotated, unmirrored shape
+        maObjTrans.setScale(maMap100thMmToMs* maObjTrans.getScale());
+        maObjTrans.setTranslate(maMap100thMmToMs * maObjTrans.getTranslate());
+
+        // Use translation and scale to create range. Use signed scale
+        // to get the unrotated SnapRect
         maObjectRange = basegfx::B2DRange(
-            aObjTrans.getTranslate(), 
-            aObjTrans.getTranslate() + aObjTrans.getScale());
+            maObjTrans.getTranslate(), 
+            maObjTrans.getTranslate() + maObjTrans.getScale());
+
+        // check mirroring
+        bool bMirroredX(maObjTrans.getScale().getX() < 0.0);
+        bool bMirroredY(maObjTrans.getScale().getY() < 0.0);
 
-        // use scale to detect mirrorings
-        if(aObjTrans.getScale().getX() < 0.0)
+        // get rotation
+        mfObjectRotation = maObjTrans.getRotate();
+
+        // if mirror is X and Y, replace with 180 degree rotation. Prefer
+        // rotation export over mirror export.
+        if(bMirroredX && bMirroredY)
+        {
+            bMirroredX = bMirroredY = false;
+            mfObjectRotation += F_PI;
+        }
+
+        // reset mirror flags
+        mnMirrorFlags = 0;
+
+        // set mirror flags
+        if(bMirroredX)
         {
             mnMirrorFlags |= SHAPEFLAG_FLIPH;
         }
 
-        if(aObjTrans.getScale().getY() < 0.0)
+        if(bMirroredY)
         {
             mnMirrorFlags |= SHAPEFLAG_FLIPV;
         }
 
+        if(bMirroredX != bMirroredY)
+        {
+            // if one axis is mirrored, invert the rotation
+            mfObjectRotation = -mfObjectRotation;
+        }
+
 //        mbMirroredX = aObjTrans.getScale().getX() < 0.0;
 //        mbMirroredY = aObjTrans.getScale().getY() < 0.0;
 
-        // get rotation
-        mfObjectRotation = aObjTrans.getRotate();
-
         // mbMirroredX and mbMirroredY are new aspects to handle. The text
         // in offices before transformation ignored mirrorX and used a 180
         // deg rotation for mirrorY. To get close to the old behaviour, use
@@ -1188,7 +1204,7 @@ bool PPTWriter::ImplGetShapeByIndex( sal
 //        }
 
         // assert shear (not supported yet)
-        if(!basegfx::fTools::equalZero(aObjTrans.getShearX()))
+        if(!basegfx::fTools::equalZero(maObjTrans.getShearX()))
         {
             OSL_ENSURE(false, "PPt export: shear is not supported (!)");
         }
@@ -1754,39 +1770,39 @@ void PPTWriter::ImplHandleRotation( Esch
 {
     if(!basegfx::fTools::equalZero(mfObjectRotation))
     {
-        sal_Int32 
nAngle(basegfx::fround(basegfx::snapToZeroRange(-mfObjectRotation / F_PI18000, 
36000.0)));
-        
-        nAngle = ( 36000 - ( nAngle % 36000 ) );
-
-        double  fCos = cos( (double)nAngle * F_PI18000 );
-        double  fSin = sin( (double)nAngle * F_PI18000 );
+        // MS shape format rotates around the object center, so adapt adapt 
ObjectRange
+        // to be centered at the center of the original shape to do this
+        const basegfx::B2DPoint aCurrentCenter(maObjTrans.getB2DHomMatrix() * 
basegfx::B2DPoint(0.5, 0.5));
+        const basegfx::B2DPoint aObjectRangeCenter(maObjectRange.getCenter());
 
-        const double fWidthHalf(maObjectRange.getWidth() * 0.5);
-        const double fHeightHalf(maObjectRange.getHeight() * 0.5);
+        if(!aCurrentCenter.equal(aObjectRangeCenter))
+        {
+            const basegfx::B2DHomMatrix aAdaptToCenterRotation(
+                basegfx::tools::createTranslateB2DHomMatrix(
+                    aCurrentCenter - aObjectRangeCenter));
 
-        double  fXDiff = fCos * fWidthHalf + fSin * (-fHeightHalf);
-        double  fYDiff = - ( fSin * fWidthHalf - fCos * ( -fHeightHalf ) );
+            maObjectRange.transform(aAdaptToCenterRotation);
+        }
 
-        maObjectRange.transform(
-            basegfx::tools::createTranslateB2DHomMatrix(
-                -(fWidthHalf - fXDiff),
-                -(fHeightHalf + fYDiff)));
+        // do not use negative mfObjectRotation here, PPT uses the correct 
orientation, too
+        sal_Int32 
nAngle(basegfx::fround(basegfx::snapToZeroRange(mfObjectRotation / F_PI18000, 
36000.0)));
 
+        // adapt angle to MS format
         nAngle *= 655;
         nAngle += 0x8000;
-        nAngle &=~0xffff;                                  // nAngle auf volle 
Gradzahl runden
-        rPropOpt.AddOpt( ESCHER_Prop_Rotation, nAngle );
+        nAngle &=~0xffff; // round to full degrees
+        rPropOpt.AddOpt(ESCHER_Prop_Rotation, nAngle);
 
-        if ( ( nAngle >= ( 45 << 16 ) && nAngle < ( 135 << 16 ) ) ||
-                ( nAngle >= ( 225 << 16 ) && nAngle < ( 315 << 16 ) ) )
+        if((nAngle >= (45 << 16) && nAngle < (135 << 16)) || (nAngle >= (225 
<< 16) && nAngle < (315 << 16)))
         {
-            // In diesen beiden Bereichen steht in PPT gemeinerweise die
-            // BoundingBox bereits senkrecht. Daher muss diese VOR
-            // DER ROTATION flachgelegt werden.
-            const basegfx::B2DPoint aPoint(maObjectRange.getMinX() + 
fWidthHalf - fHeightHalf, maObjectRange.getMinY() + fHeightHalf - fWidthHalf);
-            const basegfx::B2DVector aScale(maObjectRange.getHeight(), 
maObjectRange.getWidth());
+            // in this region of rotation the ObjectRange is already rotated,
+            // so do this here, too
+            const basegfx::B2DHomMatrix aMirrorDiagonal(
+                basegfx::tools::createRotateAroundPoint(
+                    maObjectRange.getCenter(),
+                    F_PI2));
 
-            maObjectRange = basegfx::B2DRange(aPoint, aPoint + aScale);
+            maObjectRange.transform(aMirrorDiagonal);
         }
     }
 }
@@ -4503,7 +4519,7 @@ void PPTWriter::ImplWritePage( const PHL
                                }
                                else
                                {
-                       ImplCreateShape( eShapeType, /*nMirrorFlags | */0xa00, 
aSolverContainer );
+                       ImplCreateShape( eShapeType, /*nMirrorFlags | */0xa00, 
aSolverContainer ); // Flags: Connector | HasSpt
                                        aPropOpt.CreateCustomShapeProperties( 
eShapeType, mXShape );
                                        aPropOpt.CreateFillProperties( 
mXPropSet, true, mXShape);
                                        if ( ImplGetText() )

Modified: incubator/ooo/branches/alg/aw080/main/svx/source/svdraw/svdlegacy.cxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/branches/alg/aw080/main/svx/source/svdraw/svdlegacy.cxx?rev=1412988&r1=1412987&r2=1412988&view=diff
==============================================================================
--- incubator/ooo/branches/alg/aw080/main/svx/source/svdraw/svdlegacy.cxx 
(original)
+++ incubator/ooo/branches/alg/aw080/main/svx/source/svdraw/svdlegacy.cxx Fri 
Nov 23 17:14:30 2012
@@ -290,7 +290,7 @@ namespace sdr
                        if(rObject.isRotated())
                        {
                                const double 
fRotate(rObject.getSdrObjectRotate());
-                const double fSnapped(basegfx::snapToNearestMultiple(-fRotate 
/ F_PI18000, 360000.0));
+                const double fSnapped(basegfx::snapToZeroRange(-fRotate / 
F_PI18000, 36000.0));
 
                 return basegfx::fround(fSnapped);
                        }

Modified: incubator/ooo/branches/alg/aw080/main/vcl/source/gdi/outmap.cxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/branches/alg/aw080/main/vcl/source/gdi/outmap.cxx?rev=1412988&r1=1412987&r2=1412988&view=diff
==============================================================================
--- incubator/ooo/branches/alg/aw080/main/vcl/source/gdi/outmap.cxx (original)
+++ incubator/ooo/branches/alg/aw080/main/vcl/source/gdi/outmap.cxx Fri Nov 23 
17:14:30 2012
@@ -2508,9 +2508,11 @@ basegfx::B2DHomMatrix OutputDevice::GetT
 
        if(rMapModeSource != rMapModeDest)
        {
-               aRetval = GetViewTransformation(rMapModeSource);
+        // GetViewTransformation converts from unit to pixel, thus it's 
[inv(rMapModeDest) * rMapModeSource]
+        // read right to left
+               aRetval = GetViewTransformation(rMapModeDest);
                aRetval.invert();
-               aRetval = GetViewTransformation(rMapModeDest) * aRetval;
+               aRetval = aRetval * GetViewTransformation(rMapModeSource);
        }
 
        return aRetval;


Reply via email to