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 <[email protected]> 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() |* *************************************************************************/ _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
