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

Sun Ying sunying at apache.org
Wed Jun 5 00:59:55 PDT 2013


 filter/source/msfilter/escherex.cxx |  212 +++++++++++++++++++++++++++++++++---
 include/svx/xpoly.hxx               |    3 
 svx/source/xoutdev/_xpoly.cxx       |   38 ++++++
 3 files changed, 236 insertions(+), 17 deletions(-)

New commits:
commit 5f554bcec10287659e34b64ddf88813144214e17
Author: Sun Ying <sunying at apache.org>
Date:   Sat Sep 29 04:44:20 2012 +0000

    Resolves: #i119860# fix bent connector's type lost when save .ppt file
    
    Reported by: Li Feng Wang
    Patch by: Ying Sun
    Review by: Jian Yuan Li
    (cherry picked from commit 8037c7164c747ea240b563af39a11f4f6bf037ef)
    
    Conflicts:
    	filter/source/msfilter/escherex.cxx
    
    Change-Id: Iee39fc5c95f354a6fe68cd93b69f40e01d9fa9f8

diff --git a/filter/source/msfilter/escherex.cxx b/filter/source/msfilter/escherex.cxx
index 3f31b25..c530081 100644
--- a/filter/source/msfilter/escherex.cxx
+++ b/filter/source/msfilter/escherex.cxx
@@ -2067,6 +2067,156 @@ sal_Bool EscherPropertyContainer::CreatePolygonProperties(
     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,
@@ -2077,6 +2227,7 @@ sal_Bool EscherPropertyContainer::CreateConnectorProperties(
     static OUString sEdgeEndPoint         ( "EdgeEndPoint" );
     static OUString sEdgeStartConnection  ( "EdgeStartConnection" );
     static OUString sEdgeEndConnection    ( "EdgeEndConnection" );
+    static OUString sEdgePath             ( "PolyPolygonBezier" );
 
     sal_Bool bRetValue = sal_False;
     rShapeType = rShapeFlags = 0;
@@ -2103,17 +2254,21 @@ sal_Bool EscherPropertyContainer::CreateConnectorProperties(
                         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;
@@ -2135,12 +2290,34 @@ sal_Bool EscherPropertyContainer::CreateConnectorProperties(
                             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
@@ -2151,7 +2328,8 @@ sal_Bool EscherPropertyContainer::CreateConnectorProperties(
                             break;
                         }
                         CreateLineProperties( aXPropSet, sal_False );
-                        bRetValue = bSuppressRotation = sal_True;
+                        bRetValue = sal_True;
+                        bSuppressRotation = sal_False;
                     }
                 }
             }
diff --git a/include/svx/xpoly.hxx b/include/svx/xpoly.hxx
index f6a846f..4eefabc 100644
--- a/include/svx/xpoly.hxx
+++ b/include/svx/xpoly.hxx
@@ -74,6 +74,7 @@ protected:
 public:
     XPolygon( sal_uInt16 nSize=16, sal_uInt16 nResize=16 );
     XPolygon( const XPolygon& rXPoly );
+    XPolygon( const Polygon& rPoly );
     XPolygon( const Rectangle& rRect, long nRx = 0, long nRy = 0 );
     XPolygon( const Point& rCenter, long nRx, long nRy,
               sal_uInt16 nStartAngle = 0, sal_uInt16 nEndAngle = 3600,
@@ -81,6 +82,8 @@ public:
 
     ~XPolygon();
 
+    sal_uInt16      GetSize() const;
+
     void        SetPointCount( sal_uInt16 nPoints );
     sal_uInt16      GetPointCount() const;
 
diff --git a/svx/source/xoutdev/_xpoly.cxx b/svx/source/xoutdev/_xpoly.cxx
index 2573ba3..6dd8462 100644
--- a/svx/source/xoutdev/_xpoly.cxx
+++ b/svx/source/xoutdev/_xpoly.cxx
@@ -261,6 +261,32 @@ XPolygon::XPolygon( const XPolygon& rXPoly )
 }
 
 /*************************************************************************
+ * |*
+ * |*    XPolygon::XPolygon()
+ * |*
+ * |*    XPolygon aus einem Standardpolygon erstellen
+ * |*    Ersterstellung    18.01.95 ESO
+ * |*    Letzte Aenderung  18.01.95 ESO
+ * |*
+ * *************************************************************************/
+
+XPolygon::XPolygon( const Polygon& rPoly )
+{
+    DBG_CTOR(XPolygon,NULL);
+
+    sal_uInt16 nSize = rPoly.GetSize();
+    pImpXPolygon = new ImpXPolygon( nSize );
+    pImpXPolygon->nPoints = nSize;
+
+    for( sal_uInt16 i = 0; i < nSize;  i++ )
+    {
+        pImpXPolygon->pPointAry[i] = rPoly[i];
+        pImpXPolygon->pFlagAry[i] = (sal_uInt8) rPoly.GetFlags( i );
+    }
+}
+
+
+/*************************************************************************
 |*
 |*    XPolygon::XPolygon()
 |*
@@ -434,6 +460,18 @@ void XPolygon::SetPointCount( sal_uInt16 nPoints )
 
 /*************************************************************************
 |*
+|*    XPolygon::GetSize()
+|*
+*************************************************************************/
+
+sal_uInt16 XPolygon::GetSize() const
+{
+    pImpXPolygon->CheckPointDelete();
+    return pImpXPolygon->nSize;
+}
+
+/*************************************************************************
+|*
 |*    XPolygon::GetPointCount()
 |*
 *************************************************************************/


More information about the Libreoffice-commits mailing list