Author: sunying
Date: Sat Sep 29 05:44:20 2012
New Revision: 1391755

URL: http://svn.apache.org/viewvc?rev=1391755&view=rev
Log:
#119860# fix bent connector's type lost when save .ppt file
Reported by: Li Feng Wang
Patch by: Ying Sun
Review by: Jian Yuan Li

Modified:
    incubator/ooo/trunk/main/filter/source/msfilter/escherex.cxx

Modified: incubator/ooo/trunk/main/filter/source/msfilter/escherex.cxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/trunk/main/filter/source/msfilter/escherex.cxx?rev=1391755&r1=1391754&r2=1391755&view=diff
==============================================================================
--- incubator/ooo/trunk/main/filter/source/msfilter/escherex.cxx (original)
+++ incubator/ooo/trunk/main/filter/source/msfilter/escherex.cxx Sat Sep 29 
05:44:20 2012
@@ -2103,6 +2103,156 @@ sal_Bool EscherPropertyContainer::Create
        return bRetValue;
 }
 
+
+/*
+in MS,the connector including 9 types :
+"straightConnector1",
+"bentConnector2","bentConnector3","bentConnector4","bentConnector5"
+"curvedConnector2","curvedConnector3","curvedConnector4","curvedConnector5"
+in AOO,including 4 types:"standard","lines","line","curve"
+when save as MS file, the connector must be convert to corresponding type.
+"line" and "lines" <-> "straightConnector1"
+"standard" <->  "bentConnector2-5"
+"curve" <-> "curvedConnector2-5"
+*/
+sal_Int32 lcl_GetAdjustValueCount( const XPolygon& rPoly ) 
+{
+       int nRet = 0;
+       switch (  rPoly.GetSize() )
+       {
+       case 2 :
+       case 3:
+               nRet =  0;
+               break;
+       case 4:
+               nRet = 1;
+               break;
+       case 5:
+               nRet = 2;
+               break;
+       default:
+               if ( rPoly.GetSize()>=6 )
+                       nRet = 3;
+               break;
+       }
+       return nRet;
+}
+/*
+ Adjust value decide the position which connector should turn a corner
+*/
+sal_Int32 lcl_GetConnectorAdjustValue ( const XPolygon& rPoly, sal_uInt16 
nIndex )
+{
+       sal_uInt16 k =  rPoly.GetSize();
+       OSL_ASSERT ( k >= ( 3 + nIndex ) );
+
+       Point aPt;
+       Point aStart = rPoly[0];
+       Point aEnd = rPoly[k-1];
+       if ( aEnd.Y() == aStart.Y() ) 
+               aEnd.Y() = aStart.Y() +4;
+       if ( aEnd.X() == aStart.X() )
+               aEnd.X() = aStart.X() +4;
+
+       sal_Bool bVertical = ( rPoly[1].X()-aStart.X() ) == 0 ;
+       //vertical and horizon alternate  
+       if ( nIndex%2 == 1 ) bVertical = !bVertical;
+       aPt = rPoly[ nIndex + 1];
+
+       sal_Int32 nAdjustValue;
+       if ( bVertical ) 
+               nAdjustValue = ( aPt.Y()-aStart.Y())* 21600 
/(aEnd.Y()-aStart.Y());
+       else
+               nAdjustValue = ( aPt.X()-aStart.X() )* 21600 
/(aEnd.X()-aStart.X());
+
+       return nAdjustValue;
+}
+
+
+void lcl_Rotate(sal_Int32 nAngle, Point center, Point& pt)
+{
+       while ( nAngle<0)
+               nAngle +=36000;
+       while (nAngle>=36000)
+               nAngle -=36000;
+
+       int cs, sn;
+       switch (nAngle)
+       {
+       case 0:
+               cs =1;
+               sn =0;
+               break;
+       case 9000:
+               cs =0;
+               sn =1;
+               break;
+       case 18000:
+               cs = -1;
+               sn = 0;
+               break;
+       case 27000:
+               cs = 0;
+               sn = -1;
+               break;
+       default:
+               return;
+               break;
+       }
+       sal_Int32 x0 =pt.X()-center.X();
+       sal_Int32 y0 =pt.Y()-center.Y();
+       pt.X()=center.X()+ x0*cs-y0*sn;
+       pt.Y()=center.Y()+ y0*cs+x0*sn;
+}
+/*
+ FlipV defines that the shape will be flipped vertically about the center of 
its bounding box.
+Generally, draw the connector from top to bottom, from left to right when meet 
the adjust value,
+but when (X1>X2 or Y1>Y2),the draw director must be reverse, FlipV or FlipH 
should be set to true.
+*/
+sal_Bool lcl_GetAngle(Polygon &rPoly,sal_uInt16& rShapeFlags,sal_Int32& nAngle 
)
+{
+       Point aStart = rPoly[0];
+       Point aEnd = rPoly[rPoly.GetSize()-1];
+       nAngle = ( rPoly[1].X() == aStart.X() ) ? 9000: 0 ;
+       Point p1(aStart.X(),aStart.Y());
+       Point p2(aEnd.X(),aEnd.Y());
+       if ( nAngle )
+       {
+               Point center((aEnd.X()+aStart.X())>>1,(aEnd.Y()+aStart.Y())>>1);
+               lcl_Rotate(-nAngle, center,p1); 
+               lcl_Rotate(-nAngle, center,p2);
+       }
+       if (  p1.X() > p2.X() )
+       {
+               if ( nAngle )
+                       rShapeFlags |= SHAPEFLAG_FLIPV;
+               else 
+                       rShapeFlags |= SHAPEFLAG_FLIPH;
+
+       }
+       if (  p1.Y() > p2.Y()  )
+       {
+               if ( nAngle )
+                       rShapeFlags |= SHAPEFLAG_FLIPH;
+               else 
+                       rShapeFlags |= SHAPEFLAG_FLIPV;
+       }
+
+       if ( (rShapeFlags&SHAPEFLAG_FLIPH) && (rShapeFlags&SHAPEFLAG_FLIPV) )
+       {
+               rShapeFlags  &= ~( SHAPEFLAG_FLIPH | SHAPEFLAG_FLIPV );
+               nAngle +=18000;
+       }
+
+       if ( nAngle )
+       {
+               // Set angle properties
+               nAngle *= 655;
+               nAngle += 0x8000;
+               nAngle &=~0xffff;                                  // nAngle 
auf volle Gradzahl runden
+               return sal_True;
+       }
+       return sal_False;
+}
 sal_Bool EscherPropertyContainer::CreateConnectorProperties(
        const ::com::sun::star::uno::Reference< 
::com::sun::star::drawing::XShape > & rXShape,
        EscherSolverContainer& rSolverContainer, 
::com::sun::star::awt::Rectangle& rGeoRect,
@@ -2113,7 +2263,7 @@ sal_Bool EscherPropertyContainer::Create
        static String sEdgeEndPoint                     ( 
RTL_CONSTASCII_USTRINGPARAM( "EdgeEndPoint" ) );
        static String sEdgeStartConnection      ( RTL_CONSTASCII_USTRINGPARAM( 
"EdgeStartConnection" ) );
        static String sEdgeEndConnection        ( RTL_CONSTASCII_USTRINGPARAM( 
"EdgeEndConnection" ) );
-
+       static String sEdgePath             ( RTL_CONSTASCII_USTRINGPARAM( 
"PolyPolygonBezier") );
        sal_Bool bRetValue = sal_False;
        rShapeType = rShapeFlags = 0;
 
@@ -2139,17 +2289,21 @@ sal_Bool EscherPropertyContainer::Create
                                                rShapeFlags = 
SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT | SHAPEFLAG_CONNECTOR;
                                                rGeoRect = 
::com::sun::star::awt::Rectangle( aStartPoint.X, aStartPoint.Y,
                                                                                
                                        ( aEndPoint.X - aStartPoint.X ) + 1, ( 
aEndPoint.Y - aStartPoint.Y ) + 1 );
-                                               if ( rGeoRect.Height < 0 )      
                // justify
-                                               {
-                                                       rShapeFlags |= 
SHAPEFLAG_FLIPV;
-                                                       rGeoRect.Y = 
aEndPoint.Y;
-                                                       rGeoRect.Height = 
-rGeoRect.Height;
-                                               }
-                                               if ( rGeoRect.Width < 0 )
+                                               //set standard's FLIP in below 
code
+                                               if ( eCt != 
::com::sun::star::drawing::ConnectorType_STANDARD)
                                                {
-                                                       rShapeFlags |= 
SHAPEFLAG_FLIPH;
-                                                       rGeoRect.X = 
aEndPoint.X;
-                                                       rGeoRect.Width = 
-rGeoRect.Width;
+                                                       if ( rGeoRect.Height < 
0 )                      // justify
+                                                       {
+                                                               rShapeFlags |= 
SHAPEFLAG_FLIPV;
+                                                               rGeoRect.Y = 
aEndPoint.Y;
+                                                               rGeoRect.Height 
= -rGeoRect.Height;
+                                                       }
+                                                       if ( rGeoRect.Width < 0 
)
+                                                       {
+                                                               rShapeFlags |= 
SHAPEFLAG_FLIPH;
+                                                               rGeoRect.X = 
aEndPoint.X;
+                                                               rGeoRect.Width 
= -rGeoRect.Width;
+                                                       }
                                                }
                                                sal_uInt32 nAdjustValue1, 
nAdjustValue2, nAdjustValue3;
                                                nAdjustValue1 = nAdjustValue2 = 
nAdjustValue3 = 0x2a30;
@@ -2194,12 +2348,34 @@ sal_Bool EscherPropertyContainer::Create
                                                        break;
 
                                                        case 
::com::sun::star::drawing::ConnectorType_STANDARD :// Connector 2->5
-                                                       {
-                                                               rShapeType = 
ESCHER_ShpInst_BentConnector3;
-                                                               AddOpt( 
ESCHER_Prop_cxstyle, ESCHER_cxstyleBent );
-                                                       }
-                                                       break;
-
+                                                               {
+                                                                       if ( 
EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgePath ) )
+                                                                       {
+                                                                               
PolyPolygon aPolyPolygon = GetPolyPolygon( aAny );
+                                                                               
Polygon aPoly;
+                                                                               
if ( aPolyPolygon.Count() > 0 )
+                                                                               
{
+                                                                               
        AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleBent );
+                                                                               
        aPoly = aPolyPolygon[ 0 ];
+                                                                               
        sal_Int32 nAdjCount = lcl_GetAdjustValueCount( aPoly );
+                                                                               
        rShapeType = ( sal_uInt16 )( ESCHER_ShpInst_BentConnector2 + 
nAdjCount);        
+                                                                               
        for ( sal_Int32 i = 0 ; i < nAdjCount; ++ i) 
+                                                                               
                AddOpt( (sal_uInt16) ( ESCHER_Prop_adjustValue+i) , 
lcl_GetConnectorAdjustValue( aPoly, i ) );
+                                                                               
        bRetValue = sal_True; 
+                                                                               
}
+                                                                               
sal_Int32 nAngle=0;
+                                                                               
if (lcl_GetAngle(aPoly,rShapeFlags,nAngle ))
+                                                                               
{
+                                                                               
        AddOpt( ESCHER_Prop_Rotation, nAngle );
+                                                                               
}
+                                                                       }
+                                                                       else 
+                                                                       {
+                                                                               
rShapeType = ESCHER_ShpInst_BentConnector3;
+                                                                               
AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleBent );
+                                                                       }
+                                                               }
+                                                               break;
                                                        default:
                                                        case 
::com::sun::star::drawing::ConnectorType_LINE :
                                                        case 
::com::sun::star::drawing::ConnectorType_LINES :   // Connector 2->5
@@ -2210,7 +2386,8 @@ sal_Bool EscherPropertyContainer::Create
                                                        break;
                                                }
                                                CreateLineProperties( 
aXPropSet, sal_False );
-                                               bRetValue = bSuppressRotation = 
sal_True;
+                                               bRetValue = sal_True;
+                                               bSuppressRotation = sal_False;
                                        }
                                }
                        }


Reply via email to