LCOV - code coverage report
Current view: top level - libreoffice/filter/source/msfilter - escherex.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 640 2803 22.8 %
Date: 2012-12-27 Functions: 69 133 51.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "eschesdo.hxx"
      21             : #include <filter/msfilter/escherex.hxx>
      22             : #include <svx/unoapi.hxx>
      23             : #include <svx/svdobj.hxx>
      24             : #include <svx/svdoashp.hxx>
      25             : #include <svx/svdoole2.hxx>
      26             : #include <svx/svdmodel.hxx>
      27             : #include <vcl/gradient.hxx>
      28             : #include <vcl/graph.hxx>
      29             : #include <vcl/cvtgrf.hxx>
      30             : #include <vcl/svapp.hxx>
      31             : #include <vcl/wrkwin.hxx>
      32             : #include <tools/stream.hxx>
      33             : #include <tools/zcodec.hxx>
      34             : #include <svx/svdopath.hxx>
      35             : #include <stdlib.h>
      36             : #include <svtools/filter.hxx>
      37             : #include "svx/EnhancedCustomShapeTypeNames.hxx"
      38             : #include "svx/EnhancedCustomShapeGeometry.hxx"
      39             : #include <svx/EnhancedCustomShapeFunctionParser.hxx>
      40             : #include "svx/EnhancedCustomShape2d.hxx"
      41             : #include <com/sun/star/beans/PropertyValues.hpp>
      42             : #include <com/sun/star/beans/XPropertyState.hpp>
      43             : #include <com/sun/star/awt/GradientStyle.hpp>
      44             : #include <com/sun/star/awt/RasterOperation.hpp>
      45             : #include <com/sun/star/awt/Gradient.hpp>
      46             : #include <com/sun/star/drawing/LineStyle.hpp>
      47             : #include <com/sun/star/drawing/LineJoint.hpp>
      48             : #include <com/sun/star/drawing/LineCap.hpp>
      49             : #include <com/sun/star/drawing/FillStyle.hpp>
      50             : #include <com/sun/star/drawing/LineDash.hpp>
      51             : #include <com/sun/star/drawing/BezierPoint.hpp>
      52             : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
      53             : #include <com/sun/star/drawing/ConnectorType.hpp>
      54             : #include <com/sun/star/drawing/ConnectionType.hpp>
      55             : #include <com/sun/star/drawing/CircleKind.hpp>
      56             : #include <com/sun/star/drawing/PointSequence.hpp>
      57             : #include <com/sun/star/drawing/FlagSequence.hpp>
      58             : #include <com/sun/star/drawing/PolygonFlags.hpp>
      59             : #include <com/sun/star/text/WritingMode.hpp>
      60             : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
      61             : #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
      62             : #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
      63             : #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
      64             : #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
      65             : #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
      66             : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
      67             : #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
      68             : #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
      69             : #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
      70             : #include <com/sun/star/drawing/ProjectionMode.hpp>
      71             : #include <com/sun/star/text/XSimpleText.hpp>
      72             : #include <com/sun/star/drawing/ShadeMode.hpp>
      73             : #include <vcl/hatch.hxx>
      74             : #include <com/sun/star/awt/XGraphics.hpp>
      75             : #include <com/sun/star/awt/FontSlant.hpp>
      76             : #include <com/sun/star/awt/FontWeight.hpp>
      77             : #include <com/sun/star/drawing/ColorMode.hpp>
      78             : #include <com/sun/star/drawing/Position3D.hpp>
      79             : #include <com/sun/star/drawing/Direction3D.hpp>
      80             : #include <com/sun/star/text/GraphicCrop.hpp>
      81             : #include <unotools/ucbstreamhelper.hxx>
      82             : #include <unotools/localfilehelper.hxx>
      83             : #include <comphelper/extract.hxx>
      84             : #include <comphelper/string.hxx>
      85             : #include <toolkit/unohlp.hxx>
      86             : #include <vcl/virdev.hxx>
      87             : #include <rtl/crc.h>
      88             : #include <rtl/strbuf.hxx>
      89             : 
      90             : using namespace ::rtl;
      91             : using namespace ::com::sun::star;
      92             : 
      93             : 
      94           0 : EscherExContainer::EscherExContainer( SvStream& rSt, const sal_uInt16 nRecType, const sal_uInt16 nInstance ) :
      95           0 :     rStrm   ( rSt )
      96             : {
      97           0 :     rStrm << (sal_uInt32)( ( 0xf | ( nInstance << 4 ) ) | ( nRecType << 16 ) ) << (sal_uInt32)0;
      98           0 :     nContPos = rStrm.Tell();
      99           0 : }
     100           0 : EscherExContainer::~EscherExContainer()
     101             : {
     102           0 :     sal_uInt32 nPos = rStrm.Tell();
     103           0 :     sal_uInt32 nSize= nPos - nContPos;
     104           0 :     if ( nSize )
     105             :     {
     106           0 :         rStrm.Seek( nContPos - 4 );
     107           0 :         rStrm << nSize;
     108           0 :         rStrm.Seek( nPos );
     109             :     }
     110           0 : }
     111             : 
     112           0 : EscherExAtom::EscherExAtom( SvStream& rSt, const sal_uInt16 nRecType, const sal_uInt16 nInstance, const sal_uInt8 nVersion ) :
     113           0 :     rStrm   ( rSt )
     114             : {
     115           0 :     rStrm << (sal_uInt32)( ( nVersion | ( nInstance << 4 ) ) | ( nRecType << 16 ) ) << (sal_uInt32)0;
     116           0 :     nContPos = rStrm.Tell();
     117           0 : }
     118           0 : EscherExAtom::~EscherExAtom()
     119             : {
     120           0 :     sal_uInt32 nPos = rStrm.Tell();
     121           0 :     sal_uInt32 nSize= nPos - nContPos;
     122           0 :     if ( nSize )
     123             :     {
     124           0 :         rStrm.Seek( nContPos - 4 );
     125           0 :         rStrm << nSize;
     126           0 :         rStrm.Seek( nPos );
     127             :     }
     128           0 : }
     129             : 
     130           1 : EscherExClientRecord_Base::~EscherExClientRecord_Base()
     131             : {
     132           1 : }
     133             : 
     134           0 : EscherExClientAnchor_Base::~EscherExClientAnchor_Base()
     135             : {
     136           0 : }
     137             : 
     138           1 : void EscherPropertyContainer::ImplInit()
     139             : {
     140           1 :     nSortCount = 0;
     141           1 :     nCountCount = 0;
     142           1 :     nCountSize = 0;
     143           1 :     nSortBufSize = 64;
     144           1 :     bHasComplexData = sal_False;
     145           1 :     bSuppressRotation = sal_False;
     146           1 :     pSortStruct = new EscherPropSortStruct[ nSortBufSize ];
     147           1 : }
     148             : 
     149           0 : EscherPropertyContainer::EscherPropertyContainer() :
     150             :     pGraphicProvider    ( NULL ),
     151           0 :     pPicOutStrm         ( NULL )
     152             : {
     153           0 :     ImplInit();
     154           0 : };
     155             : 
     156           1 : EscherPropertyContainer::EscherPropertyContainer(
     157             :     EscherGraphicProvider& rGraphProv,
     158             :             SvStream* pPiOutStrm,
     159             :                 Rectangle& rBoundRect ) :
     160             : 
     161             :     pGraphicProvider    ( &rGraphProv ),
     162             :     pPicOutStrm         ( pPiOutStrm ),
     163           1 :     pShapeBoundRect     ( &rBoundRect )
     164             : {
     165           1 :     ImplInit();
     166           1 : }
     167             : 
     168           1 : EscherPropertyContainer::~EscherPropertyContainer()
     169             : {
     170           1 :     if ( bHasComplexData )
     171             :     {
     172          19 :         while ( nSortCount-- )
     173          17 :             delete[] pSortStruct[ nSortCount ].pBuf;
     174             :     }
     175           1 :     delete[] pSortStruct;
     176           1 : };
     177             : 
     178          15 : void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID, sal_uInt32 nPropValue, sal_Bool bBlib )
     179             : {
     180          15 :     AddOpt( nPropID, bBlib, nPropValue, NULL, 0 );
     181          15 : }
     182             : 
     183           0 : void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID, const rtl::OUString& rString )
     184             : {
     185           0 :     sal_Int32 j, i, nLen = rString.getLength() * 2 + 2;
     186           0 :     sal_uInt8* pBuf = new sal_uInt8[ nLen ];
     187           0 :     for ( j = i = 0; i < rString.getLength(); i++ )
     188             :     {
     189           0 :         sal_uInt16 nChar = (sal_uInt16)rString[ i ];
     190           0 :         pBuf[ j++ ] = (sal_uInt8)nChar;
     191           0 :         pBuf[ j++ ] = (sal_uInt8)( nChar >> 8 );
     192             :     }
     193           0 :     pBuf[ j++ ] = 0;
     194           0 :     pBuf[ j++ ] = 0;
     195           0 :     AddOpt( nPropID, sal_True, nLen, pBuf, nLen );
     196           0 : }
     197             : 
     198          17 : void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID, sal_Bool bBlib, sal_uInt32 nPropValue, sal_uInt8* pProp, sal_uInt32 nPropSize )
     199             : {
     200          17 :     if ( bBlib )                // bBlib is only valid when fComplex = 0
     201           1 :         nPropID |= 0x4000;
     202          17 :     if ( pProp )
     203           2 :         nPropID |= 0x8000;      // fComplex = sal_True;
     204             : 
     205             :     sal_uInt32 i;
     206         153 :     for( i = 0; i < nSortCount; i++ )
     207             :     {
     208         136 :         if ( ( pSortStruct[ i ].nPropId &~0xc000 ) == ( nPropID &~0xc000 ) )    // check, whether the Property only gets replaced
     209             :         {
     210           0 :             pSortStruct[ i ].nPropId = nPropID;
     211           0 :             if ( pSortStruct[ i ].pBuf )
     212             :             {
     213           0 :                 nCountSize -= pSortStruct[ i ].nPropSize;
     214           0 :                 delete[] pSortStruct[ i ].pBuf;
     215             :             }
     216           0 :             pSortStruct[ i ].pBuf = pProp;
     217           0 :             pSortStruct[ i ].nPropSize = nPropSize;
     218           0 :             pSortStruct[ i ].nPropValue = nPropValue;
     219           0 :             if ( pProp )
     220           0 :                 nCountSize += nPropSize;
     221          17 :             return;
     222             :         }
     223             :     }
     224          17 :     nCountCount++;
     225          17 :     nCountSize += 6;
     226          17 :     if ( nSortCount == nSortBufSize )                                           // increase buffer
     227             :     {
     228           0 :         nSortBufSize <<= 1;
     229           0 :         EscherPropSortStruct* pTemp = new EscherPropSortStruct[ nSortBufSize ];
     230           0 :         for( i = 0; i < nSortCount; i++ )
     231             :         {
     232           0 :             pTemp[ i ] = pSortStruct[ i ];
     233             :         }
     234           0 :         delete pSortStruct;
     235           0 :         pSortStruct = pTemp;
     236             :     }
     237          17 :     pSortStruct[ nSortCount ].nPropId = nPropID;                                // insert property
     238          17 :     pSortStruct[ nSortCount ].pBuf = pProp;
     239          17 :     pSortStruct[ nSortCount ].nPropSize = nPropSize;
     240          17 :     pSortStruct[ nSortCount++ ].nPropValue = nPropValue;
     241             : 
     242          17 :     if ( pProp )
     243             :     {
     244           2 :         nCountSize += nPropSize;
     245           2 :         bHasComplexData = sal_True;
     246             :     }
     247             : }
     248             : 
     249          14 : sal_Bool EscherPropertyContainer::GetOpt( sal_uInt16 nPropId, sal_uInt32& rPropValue ) const
     250             : {
     251             :     EscherPropSortStruct aPropStruct;
     252             : 
     253          14 :     if ( GetOpt( nPropId, aPropStruct ) )
     254             :     {
     255          10 :         rPropValue = aPropStruct.nPropValue;
     256          10 :         return sal_True;
     257             :     }
     258           4 :     return sal_False;
     259             : }
     260             : 
     261          18 : sal_Bool EscherPropertyContainer::GetOpt( sal_uInt16 nPropId, EscherPropSortStruct& rPropValue ) const
     262             : {
     263         117 :     for( sal_uInt32 i = 0; i < nSortCount; i++ )
     264             :     {
     265         113 :         if ( ( pSortStruct[ i ].nPropId &~0xc000 ) == ( nPropId &~0xc000 ) )
     266             :         {
     267          14 :             rPropValue = pSortStruct[ i ];
     268          14 :             return sal_True;
     269             :         }
     270             :     }
     271           4 :     return sal_False;
     272             : }
     273             : 
     274           1 : EscherProperties EscherPropertyContainer::GetOpts() const
     275             : {
     276           1 :     EscherProperties aVector;
     277             : 
     278          18 :     for ( sal_uInt32 i = 0; i < nSortCount; ++i )
     279          17 :         aVector.push_back( pSortStruct[ i ] );
     280             : 
     281           1 :     return aVector;
     282             : }
     283             : 
     284           0 : extern "C" int SAL_CALL EscherPropSortFunc( const void* p1, const void* p2 )
     285             : {
     286           0 :     sal_Int16   nID1 = ((EscherPropSortStruct*)p1)->nPropId &~0xc000;
     287           0 :     sal_Int16   nID2 = ((EscherPropSortStruct*)p2)->nPropId &~0xc000;
     288             : 
     289           0 :     if( nID1  < nID2 )
     290           0 :         return -1;
     291           0 :     else if( nID1 > nID2 )
     292           0 :         return 1;
     293             :     else
     294           0 :         return 0;
     295             : }
     296             : 
     297           0 : void EscherPropertyContainer::Commit( SvStream& rSt, sal_uInt16 nVersion, sal_uInt16 nRecType )
     298             : {
     299           0 :     rSt << (sal_uInt16)( ( nCountCount << 4 ) | ( nVersion & 0xf ) ) << nRecType << nCountSize;
     300           0 :     if ( nSortCount )
     301             :     {
     302           0 :         qsort( pSortStruct, nSortCount, sizeof( EscherPropSortStruct ), EscherPropSortFunc );
     303             :         sal_uInt32 i;
     304             : 
     305           0 :         for ( i = 0; i < nSortCount; i++ )
     306             :         {
     307           0 :             sal_uInt32 nPropValue = pSortStruct[ i ].nPropValue;
     308           0 :             sal_uInt16 nPropId = pSortStruct[ i ].nPropId;
     309             : 
     310           0 :             if ( bSuppressRotation && ( nPropId == ESCHER_Prop_Rotation ) )
     311           0 :                 nPropValue = 0;
     312             : 
     313           0 :             rSt << nPropId
     314           0 :                 << nPropValue;
     315             :         }
     316           0 :         if ( bHasComplexData )
     317             :         {
     318           0 :             for ( i = 0; i < nSortCount; i++ )
     319             :             {
     320           0 :                 if ( pSortStruct[ i ].pBuf )
     321           0 :                     rSt.Write( pSortStruct[ i ].pBuf, pSortStruct[ i ].nPropSize );
     322             :             }
     323             :         }
     324             :     }
     325           0 : }
     326             : 
     327           0 : sal_Bool EscherPropertyContainer::IsFontWork() const
     328             : {
     329           0 :     sal_uInt32 nTextPathFlags = 0;
     330           0 :     GetOpt( DFF_Prop_gtextFStrikethrough, nTextPathFlags );
     331           0 :     return ( nTextPathFlags & 0x4000 ) != 0;
     332             : }
     333             : 
     334           2 : sal_uInt32 EscherPropertyContainer::ImplGetColor( const sal_uInt32 nSOColor, sal_Bool bSwap )
     335             : {
     336           2 :     if ( bSwap )
     337             :     {
     338           2 :         sal_uInt32 nColor = nSOColor & 0xff00;      // green
     339           2 :         nColor |= (sal_uInt8)( nSOColor ) << 16;    // red
     340           2 :         nColor |= (sal_uInt8)( nSOColor >> 16 );    // blue
     341           2 :         return nColor;
     342             :     }
     343             :     else
     344           0 :         return nSOColor & 0xffffff;
     345             : }
     346             : 
     347           0 : sal_uInt32 EscherPropertyContainer::GetGradientColor(
     348             :     const ::com::sun::star::awt::Gradient* pGradient,
     349             :         sal_uInt32 nStartColor )
     350             : {
     351           0 :     sal_uInt32  nIntensity = 100;
     352           0 :     Color       aColor;
     353             : 
     354           0 :     if ( pGradient )
     355             :     {
     356           0 :         if ( nStartColor & 1 )
     357             :         {
     358           0 :             nIntensity = pGradient->StartIntensity;
     359           0 :             aColor = pGradient->StartColor;
     360             :         }
     361             :         else
     362             :         {
     363           0 :             nIntensity = pGradient->EndIntensity;
     364           0 :             aColor = pGradient->EndColor;
     365             :         }
     366             :     }
     367           0 :     sal_uInt32  nRed = ( ( aColor.GetRed() * nIntensity ) / 100 );
     368           0 :     sal_uInt32  nGreen = ( ( aColor.GetGreen() * nIntensity ) / 100 ) << 8;
     369           0 :     sal_uInt32  nBlue = ( ( aColor.GetBlue() * nIntensity ) / 100 ) << 16;
     370           0 :     return nRed | nGreen | nBlue;
     371             : }
     372             : 
     373           0 : void EscherPropertyContainer::CreateGradientProperties(
     374             :     const ::com::sun::star::awt::Gradient & rGradient )
     375             : {
     376           0 :     sal_uInt32  nFillType = ESCHER_FillShadeScale;
     377           0 :     sal_uInt32  nAngle = 0;
     378           0 :     sal_uInt32  nFillFocus = 0;
     379           0 :     sal_uInt32  nFillLR = 0;
     380           0 :     sal_uInt32  nFillTB = 0;
     381           0 :     sal_uInt32  nFirstColor = 0;
     382           0 :     bool        bWriteFillTo = false;
     383             : 
     384           0 :     switch ( rGradient.Style )
     385             :     {
     386             :         case ::com::sun::star::awt::GradientStyle_LINEAR :
     387             :         case ::com::sun::star::awt::GradientStyle_AXIAL :
     388             :         {
     389           0 :             nFillType = ESCHER_FillShadeScale;
     390           0 :             nAngle = (rGradient.Angle * 0x10000) / 10;
     391           0 :             nFillFocus = (sal::static_int_cast<int>(rGradient.Style) ==
     392           0 :                           sal::static_int_cast<int>(GradientStyle_LINEAR)) ? 0 : 50;
     393             :         }
     394           0 :         break;
     395             :         case ::com::sun::star::awt::GradientStyle_RADIAL :
     396             :         case ::com::sun::star::awt::GradientStyle_ELLIPTICAL :
     397             :         case ::com::sun::star::awt::GradientStyle_SQUARE :
     398             :         case ::com::sun::star::awt::GradientStyle_RECT :
     399             :         {
     400           0 :             nFillLR = (rGradient.XOffset * 0x10000) / 100;
     401           0 :             nFillTB = (rGradient.YOffset * 0x10000) / 100;
     402           0 :             if ( ((nFillLR > 0) && (nFillLR < 0x10000)) || ((nFillTB > 0) && (nFillTB < 0x10000)) )
     403           0 :                 nFillType = ESCHER_FillShadeShape;
     404             :             else
     405           0 :                 nFillType = ESCHER_FillShadeCenter;
     406           0 :             nFirstColor = 1;
     407           0 :             bWriteFillTo = true;
     408             :         }
     409           0 :         break;
     410           0 :         case ::com::sun::star::awt::GradientStyle_MAKE_FIXED_SIZE : break;
     411             :     }
     412           0 :     AddOpt( ESCHER_Prop_fillType, nFillType );
     413           0 :     AddOpt( ESCHER_Prop_fillAngle, nAngle );
     414           0 :     AddOpt( ESCHER_Prop_fillColor, GetGradientColor( &rGradient, nFirstColor ) );
     415           0 :     AddOpt( ESCHER_Prop_fillBackColor, GetGradientColor( &rGradient, nFirstColor ^ 1 ) );
     416           0 :     AddOpt( ESCHER_Prop_fillFocus, nFillFocus );
     417           0 :     if ( bWriteFillTo )
     418             :     {
     419           0 :         AddOpt( ESCHER_Prop_fillToLeft, nFillLR );
     420           0 :         AddOpt( ESCHER_Prop_fillToTop, nFillTB );
     421           0 :         AddOpt( ESCHER_Prop_fillToRight, nFillLR );
     422           0 :         AddOpt( ESCHER_Prop_fillToBottom, nFillTB );
     423             :     }
     424           0 : }
     425             : 
     426           0 : void EscherPropertyContainer::CreateGradientProperties(
     427             :     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet )
     428             : {
     429           0 :     ::com::sun::star::uno::Any aAny;
     430           0 :     ::com::sun::star::awt::Gradient aGradient;
     431           0 :     if ( EscherPropertyValueHelper::GetPropertyValue(
     432           0 :             aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillGradient" ) ), sal_False ) )
     433             :     {
     434           0 :         aGradient = *static_cast< const ::com::sun::star::awt::Gradient* >( aAny.getValue() );
     435             :     }
     436           0 :     CreateGradientProperties( aGradient );
     437           0 : };
     438             : 
     439           1 : void EscherPropertyContainer::CreateFillProperties(
     440             :     const uno::Reference< beans::XPropertySet > & rXPropSet,
     441             :         sal_Bool bEdge )
     442             : {
     443           1 :     ::com::sun::star::uno::Any aAny;
     444           1 :     AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapNone );
     445           1 :     AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
     446           1 :     const rtl::OUString aPropName( String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) );
     447             : 
     448           2 :     if ( EscherPropertyValueHelper::GetPropertyValue(
     449           2 :             aAny, rXPropSet, aPropName, sal_False ) )
     450             :     {
     451             :         ::com::sun::star::drawing::FillStyle eFS;
     452           1 :         if ( ! ( aAny >>= eFS ) )
     453           0 :             eFS = ::com::sun::star::drawing::FillStyle_SOLID;
     454           1 :         sal_uInt32 nFillBackColor = 0;
     455           1 :         switch( eFS )
     456             :         {
     457             :             case ::com::sun::star::drawing::FillStyle_GRADIENT :
     458             :             {
     459           0 :                 CreateGradientProperties( rXPropSet );
     460           0 :                 AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 );
     461             :             }
     462           0 :             break;
     463             : 
     464             :             case ::com::sun::star::drawing::FillStyle_BITMAP :
     465             :             {
     466           0 :                 CreateGraphicProperties( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ), sal_True );
     467           0 :                 AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 );
     468           0 :                 AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor  );
     469             :             }
     470           0 :             break;
     471             :             case ::com::sun::star::drawing::FillStyle_HATCH :
     472             :             {
     473           0 :                 CreateGraphicProperties( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillHatch" ) ), sal_True );
     474             :             }
     475           0 :             break;
     476             :             case ::com::sun::star::drawing::FillStyle_SOLID :
     477             :             default:
     478             :             {
     479             :                 ::com::sun::star::beans::PropertyState ePropState = EscherPropertyValueHelper::GetPropertyState(
     480           1 :                     rXPropSet, aPropName );
     481           1 :                 if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
     482           0 :                     AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid );
     483             : 
     484           2 :                 if ( EscherPropertyValueHelper::GetPropertyValue(
     485           2 :                         aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_False ) )
     486             :                 {
     487           1 :                     sal_uInt32 nFillColor = ImplGetColor( *((sal_uInt32*)aAny.getValue()) );
     488           1 :                     nFillBackColor = nFillColor ^ 0xffffff;
     489           1 :                     AddOpt( ESCHER_Prop_fillColor, nFillColor );
     490             :                 }
     491           1 :                 AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100010 );
     492           1 :                 AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor );
     493           1 :                 break;
     494             :             }
     495             :             case ::com::sun::star::drawing::FillStyle_NONE :
     496           0 :                 AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
     497           0 :             break;
     498             :         }
     499           1 :         if ( eFS != ::com::sun::star::drawing::FillStyle_NONE )
     500             :         {
     501             :             sal_uInt16 nTransparency = ( EscherPropertyValueHelper::GetPropertyValue(
     502           2 :                                     aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillTransparence" ) ), sal_True ) )
     503           1 :                                     ? *((sal_Int16*)aAny.getValue() )
     504           2 :                                     : 0;
     505           1 :             if (  nTransparency )
     506           0 :                 AddOpt( ESCHER_Prop_fillOpacity, ( ( 100 - nTransparency ) << 16 ) / 100 );
     507             :         }
     508             :     }
     509           1 :     CreateLineProperties( rXPropSet, bEdge );
     510           1 : }
     511             : 
     512           0 : void EscherPropertyContainer::CreateTextProperties(
     513             :     const uno::Reference< beans::XPropertySet > & rXPropSet, sal_uInt32 nTextId,
     514             :         const sal_Bool bIsCustomShape, const sal_Bool bIsTextFrame )
     515             : {
     516           0 :     uno::Any aAny;
     517           0 :     text::WritingMode               eWM( text::WritingMode_LR_TB );
     518           0 :     drawing::TextVerticalAdjust     eVA( drawing::TextVerticalAdjust_TOP );
     519           0 :     drawing::TextHorizontalAdjust   eHA( drawing::TextHorizontalAdjust_LEFT );
     520             : 
     521           0 :     sal_Int32 nLeft             ( 0 );
     522           0 :     sal_Int32 nTop              ( 0 );
     523           0 :     sal_Int32 nRight            ( 0 );
     524           0 :     sal_Int32 nBottom           ( 0 );
     525             : 
     526             :     // used with normal shapes:
     527           0 :     sal_Bool bAutoGrowWidth     ( sal_False );
     528           0 :     sal_Bool bAutoGrowHeight    ( sal_False );
     529             :     // used with ashapes:
     530           0 :     sal_Bool bWordWrap          ( sal_False );
     531           0 :     sal_Bool bAutoGrowSize      ( sal_False );
     532             : 
     533           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextWritingMode" ) ), sal_True ) )
     534           0 :         aAny >>= eWM;
     535           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextVerticalAdjust" ) ), sal_True ) )
     536           0 :         aAny >>= eVA;
     537           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextHorizontalAdjust" ) ), sal_True ) )
     538           0 :         aAny >>= eHA;
     539           0 :     if ( bIsCustomShape )
     540             :     {
     541           0 :         if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextWordWrap" ) ), sal_False ) )
     542           0 :             aAny >>= bWordWrap;
     543           0 :         if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) ), sal_True ) )
     544           0 :             aAny >>= bAutoGrowSize;
     545             :     }
     546           0 :     else if ( bIsTextFrame )
     547             :     {
     548           0 :         if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowWidth" ) ), sal_True ) )
     549           0 :             aAny >>= bAutoGrowWidth;
     550             : 
     551             : // i63936 not setting autogrowheight, because otherwise
     552             : // the minframeheight of the text will be ignored
     553             : //
     554             : //      if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) ), sal_True ) )
     555             : //          aAny >>= bAutoGrowHeight;
     556             :     }
     557           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextLeftDistance" ) ) ) )
     558           0 :         aAny >>= nLeft;
     559           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextUpperDistance" ) ) ) )
     560           0 :         aAny >>= nTop;
     561           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextRightDistance" ) ) ) )
     562           0 :         aAny >>= nRight;
     563           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextLowerDistance" ) ) ) )
     564           0 :         aAny >>= nBottom;
     565             : 
     566           0 :     ESCHER_AnchorText eAnchor = ESCHER_AnchorTop;
     567           0 :     ESCHER_WrapMode eWrapMode = ESCHER_WrapSquare;
     568           0 :     sal_uInt32 nTextAttr = 0x40004;     // rotate text with shape
     569             : 
     570           0 :     if ( eWM == text::WritingMode_TB_RL )
     571             :     {   // verical writing
     572           0 :         switch ( eHA )
     573             :         {
     574             :             case drawing::TextHorizontalAdjust_LEFT :
     575           0 :                 eAnchor = ESCHER_AnchorBottom;
     576           0 :             break;
     577             :             case drawing::TextHorizontalAdjust_CENTER :
     578           0 :                 eAnchor = ESCHER_AnchorMiddle;
     579           0 :             break;
     580             :             default :
     581             :             case drawing::TextHorizontalAdjust_BLOCK :
     582             :             case drawing::TextHorizontalAdjust_RIGHT :
     583           0 :                 eAnchor = ESCHER_AnchorTop;
     584           0 :             break;
     585             :         }
     586           0 :         if ( eVA == drawing::TextVerticalAdjust_CENTER )
     587             :         {
     588           0 :             switch ( eAnchor )
     589             :             {
     590             :                 case ESCHER_AnchorMiddle :
     591           0 :                     eAnchor = ESCHER_AnchorMiddleCentered;
     592           0 :                 break;
     593             :                 case ESCHER_AnchorBottom :
     594           0 :                     eAnchor = ESCHER_AnchorBottomCentered;
     595           0 :                 break;
     596             :                 default :
     597             :                 case ESCHER_AnchorTop :
     598           0 :                     eAnchor = ESCHER_AnchorTopCentered;
     599           0 :                 break;
     600             :             }
     601             :         }
     602           0 :         if ( bIsCustomShape )
     603             :         {
     604           0 :             if ( bWordWrap )
     605           0 :                 eWrapMode = ESCHER_WrapSquare;
     606             :             else
     607           0 :                 eWrapMode = ESCHER_WrapNone;
     608           0 :             if ( bAutoGrowSize )
     609           0 :                 nTextAttr |= 0x20002;
     610             :         }
     611             :         else
     612             :         {
     613           0 :             if ( bAutoGrowHeight )
     614           0 :                 eWrapMode = ESCHER_WrapNone;
     615           0 :             if ( bAutoGrowWidth )
     616           0 :                 nTextAttr |= 0x20002;
     617             :         }
     618             : 
     619           0 :         AddOpt( ESCHER_Prop_txflTextFlow, ESCHER_txflTtoBA ); // rotate text within shape by 90
     620             :     }
     621             :     else
     622             :     {   // normal from left to right
     623           0 :         switch ( eVA )
     624             :         {
     625             :             case drawing::TextVerticalAdjust_CENTER :
     626           0 :                 eAnchor = ESCHER_AnchorMiddle;
     627           0 :             break;
     628             : 
     629             :             case drawing::TextVerticalAdjust_BOTTOM :
     630           0 :                 eAnchor = ESCHER_AnchorBottom;
     631           0 :             break;
     632             : 
     633             :             default :
     634             :             case drawing::TextVerticalAdjust_TOP :
     635           0 :                 eAnchor = ESCHER_AnchorTop;
     636           0 :             break;
     637             :         }
     638           0 :         if ( eHA == drawing::TextHorizontalAdjust_CENTER )
     639             :         {
     640           0 :             switch( eAnchor )
     641             :             {
     642             :                 case ESCHER_AnchorMiddle :
     643           0 :                     eAnchor = ESCHER_AnchorMiddleCentered;
     644           0 :                 break;
     645             :                 case ESCHER_AnchorBottom :
     646           0 :                     eAnchor = ESCHER_AnchorBottomCentered;
     647           0 :                 break;
     648             :                 case ESCHER_AnchorTop :
     649           0 :                     eAnchor = ESCHER_AnchorTopCentered;
     650           0 :                 break;
     651           0 :                 default: break;
     652             :             }
     653             :         }
     654           0 :         if ( bIsCustomShape )
     655             :         {
     656           0 :             if ( bWordWrap )
     657           0 :                 eWrapMode = ESCHER_WrapSquare;
     658             :             else
     659           0 :                 eWrapMode = ESCHER_WrapNone;
     660           0 :             if ( bAutoGrowSize )
     661           0 :                 nTextAttr |= 0x20002;
     662             :         }
     663             :         else
     664             :         {
     665           0 :             if ( bAutoGrowWidth )
     666           0 :                 eWrapMode = ESCHER_WrapNone;
     667           0 :             if ( bAutoGrowHeight )
     668           0 :                 nTextAttr |= 0x20002;
     669             :         }
     670             :     }
     671           0 :     AddOpt( ESCHER_Prop_dxTextLeft, nLeft * 360 );
     672           0 :     AddOpt( ESCHER_Prop_dxTextRight, nRight * 360 );
     673           0 :     AddOpt( ESCHER_Prop_dyTextTop, nTop * 360 );
     674           0 :     AddOpt( ESCHER_Prop_dyTextBottom, nBottom * 360 );
     675             : 
     676           0 :     AddOpt( ESCHER_Prop_WrapText, eWrapMode );
     677           0 :     AddOpt( ESCHER_Prop_AnchorText, eAnchor );
     678           0 :     AddOpt( ESCHER_Prop_FitTextToShape, nTextAttr );
     679             : 
     680           0 :     if ( nTextId )
     681           0 :         AddOpt( ESCHER_Prop_lTxid, nTextId );
     682             : 
     683             :     // n#404221: In case of rotation we need to write the txtflTextFlow
     684             :     // attribute too.
     685           0 :     if (bIsTextFrame) {
     686             :         sal_uInt16 nAngle = EscherPropertyValueHelper::GetPropertyValue(
     687             :         aAny,
     688             :         rXPropSet,
     689             :         String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ),
     690           0 :         sal_True )
     691           0 :         ? (sal_uInt16)( ( *((sal_Int32*)aAny.getValue() ) ) + 5 ) / 10 : 0;
     692           0 :         if (nAngle==900) {
     693           0 :         AddOpt( ESCHER_Prop_txflTextFlow, ESCHER_txflBtoT );
     694             :         }
     695           0 :         if (nAngle==2700) {
     696           0 :         AddOpt( ESCHER_Prop_txflTextFlow, ESCHER_txflTtoBA );
     697             :         }
     698           0 :     }
     699           0 : }
     700             : 
     701           2 : sal_Bool EscherPropertyContainer::GetLineArrow( const sal_Bool bLineStart,
     702             :     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
     703             :         ESCHER_LineEnd& reLineEnd, sal_Int32& rnArrowLength, sal_Int32& rnArrowWidth )
     704             : {
     705           2 :     static String sLineStart    ( RTL_CONSTASCII_USTRINGPARAM( "LineStart" ) );
     706           2 :     static String sLineStartName( RTL_CONSTASCII_USTRINGPARAM( "LineStartName" ) );
     707           2 :     static String sLineEnd      ( RTL_CONSTASCII_USTRINGPARAM( "LineEnd" ) );
     708           2 :     static String sLineEndName  ( RTL_CONSTASCII_USTRINGPARAM( "LineEndName" ) );
     709             : 
     710           2 :     const String sLine      ( bLineStart ? sLineStart : sLineEnd );
     711           2 :     const String sLineName  ( bLineStart ? sLineStartName : sLineEndName );
     712             : 
     713           2 :     sal_Bool bIsArrow = sal_False;
     714             : 
     715           2 :     ::com::sun::star::uno::Any aAny;
     716           2 :     if ( EscherPropertyValueHelper::GetPropertyValue(
     717           2 :             aAny, rXPropSet, sLine, sal_False ) )
     718             :     {
     719           2 :         PolyPolygon aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aAny ) );
     720           2 :         if ( aPolyPoly.Count() && aPolyPoly[ 0 ].GetSize() )
     721             :         {
     722           0 :             bIsArrow = sal_True;
     723             : 
     724           0 :             reLineEnd     = ESCHER_LineArrowEnd;
     725           0 :             rnArrowLength = 1;
     726           0 :             rnArrowWidth  = 1;
     727             : 
     728           0 :             if ( EscherPropertyValueHelper::GetPropertyValue(
     729           0 :                 aAny, rXPropSet, sLineName, sal_False ) )
     730             :             {
     731           0 :                 String          aArrowStartName = *(::rtl::OUString*)aAny.getValue();
     732           0 :                 sal_Int16       nWhich = bLineStart ? XATTR_LINESTART : XATTR_LINEEND;
     733             : 
     734           0 :                 OUString aApiName = SvxUnogetApiNameForItem(nWhich, aArrowStartName);
     735           0 :                 if ( !aApiName.isEmpty() )
     736             :                 {
     737             : 
     738             :                     /* todo:
     739             :                     calculate the best option for ArrowLenght and ArrowWidth
     740             :                     */
     741           0 :                     if ( aApiName == "Arrow concave" )
     742           0 :                         reLineEnd = ESCHER_LineArrowStealthEnd;
     743           0 :                     else if ( aApiName == "Square 45" )
     744           0 :                         reLineEnd = ESCHER_LineArrowDiamondEnd;
     745           0 :                     else if ( aApiName == "Small Arrow" )
     746           0 :                         reLineEnd = ESCHER_LineArrowEnd;
     747           0 :                     else if ( aApiName == "Dimension Lines" )
     748             :                     {
     749           0 :                         rnArrowLength = 0;
     750           0 :                         rnArrowWidth  = 2;
     751           0 :                         reLineEnd = ESCHER_LineArrowOvalEnd;
     752             :                     }
     753           0 :                     else if ( aApiName == "Double Arrow" )
     754           0 :                         reLineEnd = ESCHER_LineArrowEnd;
     755           0 :                     else if ( aApiName == "Rounded short Arrow" )
     756           0 :                         reLineEnd = ESCHER_LineArrowEnd;
     757           0 :                     else if ( aApiName == "Symmetric Arrow" )
     758           0 :                         reLineEnd = ESCHER_LineArrowEnd;
     759           0 :                     else if ( aApiName == "Line Arrow" )
     760           0 :                         reLineEnd = ESCHER_LineArrowOpenEnd;
     761           0 :                     else if ( aApiName == "Rounded large Arrow" )
     762           0 :                         reLineEnd = ESCHER_LineArrowEnd;
     763           0 :                     else if ( aApiName == "Circle" )
     764           0 :                         reLineEnd = ESCHER_LineArrowOvalEnd;
     765           0 :                     else if ( aApiName == "Square" )
     766           0 :                         reLineEnd = ESCHER_LineArrowDiamondEnd;
     767           0 :                     else if ( aApiName == "Arrow" )
     768           0 :                         reLineEnd = ESCHER_LineArrowEnd;
     769             :                 }
     770           0 :                 else if ( comphelper::string::getTokenCount(aArrowStartName, ' ') == 2 )
     771             :                 {
     772           0 :                     sal_Bool b = sal_True;
     773           0 :                     String aArrowName( aArrowStartName.GetToken( 0, ' ' ) );
     774           0 :                     if (  aArrowName.EqualsAscii( "msArrowEnd" ) )
     775           0 :                         reLineEnd = ESCHER_LineArrowEnd;
     776           0 :                     else if (  aArrowName.EqualsAscii( "msArrowOpenEnd" ) )
     777           0 :                         reLineEnd = ESCHER_LineArrowOpenEnd;
     778           0 :                     else if ( aArrowName.EqualsAscii( "msArrowStealthEnd" ) )
     779           0 :                         reLineEnd = ESCHER_LineArrowStealthEnd;
     780           0 :                     else if ( aArrowName.EqualsAscii( "msArrowDiamondEnd" ) )
     781           0 :                         reLineEnd = ESCHER_LineArrowDiamondEnd;
     782           0 :                     else if ( aArrowName.EqualsAscii( "msArrowOvalEnd" ) )
     783           0 :                         reLineEnd = ESCHER_LineArrowOvalEnd;
     784             :                     else
     785           0 :                         b = sal_False;
     786             : 
     787             :                     // now we have the arrow, and try to determine the arrow size;
     788           0 :                     if ( b )
     789             :                     {
     790           0 :                         String aArrowSize( aArrowStartName.GetToken( 1, ' ' ) );
     791           0 :                         sal_Int32 nArrowSize = aArrowSize.ToInt32();
     792           0 :                         rnArrowWidth = ( nArrowSize - 1 ) / 3;
     793           0 :                         rnArrowLength = nArrowSize - ( rnArrowWidth * 3 ) - 1;
     794           0 :                     }
     795           0 :                 }
     796             :             }
     797           2 :         }
     798             :     }
     799           2 :     return bIsArrow;
     800             : }
     801             : 
     802           1 : void EscherPropertyContainer::CreateLineProperties(
     803             :     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
     804             :         sal_Bool bEdge )
     805             : {
     806           1 :     ::com::sun::star::uno::Any aAny;
     807           1 :     sal_uInt32 nLineFlags = 0x80008;
     808             : 
     809             :     ESCHER_LineEnd eLineEnd;
     810             :     sal_Int32 nArrowLength;
     811             :     sal_Int32 nArrowWidth;
     812             : 
     813           1 :     sal_Bool bSwapLineEnds = sal_False;
     814           1 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CircleKind" ) ), sal_True ) )
     815             :     {
     816             :         ::com::sun::star::drawing::CircleKind  eCircleKind;
     817           0 :         if ( aAny >>= eCircleKind )
     818             :         {
     819           0 :             if ( eCircleKind == ::com::sun::star::drawing::CircleKind_ARC )
     820           0 :                 bSwapLineEnds = sal_True;
     821             :         }
     822             :     }
     823           1 :     if ( GetLineArrow( bSwapLineEnds ? sal_False : sal_True, rXPropSet, eLineEnd, nArrowLength, nArrowWidth ) )
     824             :     {
     825           0 :         AddOpt( ESCHER_Prop_lineStartArrowLength, nArrowLength );
     826           0 :         AddOpt( ESCHER_Prop_lineStartArrowWidth, nArrowWidth );
     827           0 :         AddOpt( ESCHER_Prop_lineStartArrowhead, eLineEnd );
     828           0 :         nLineFlags |= 0x100010;
     829             :     }
     830           1 :     if ( GetLineArrow( bSwapLineEnds ? sal_True : sal_False, rXPropSet, eLineEnd, nArrowLength, nArrowWidth ) )
     831             :     {
     832           0 :         AddOpt( ESCHER_Prop_lineEndArrowLength, nArrowLength );
     833           0 :         AddOpt( ESCHER_Prop_lineEndArrowWidth, nArrowWidth );
     834           0 :         AddOpt( ESCHER_Prop_lineEndArrowhead, eLineEnd );
     835           0 :         nLineFlags |= 0x100010;
     836             :     }
     837             : 
     838             :     // support LineCaps
     839           1 :     if(EscherPropertyValueHelper::GetPropertyValue(aAny, rXPropSet, String(RTL_CONSTASCII_USTRINGPARAM("LineCap")), sal_False))
     840             :     {
     841           1 :         ::com::sun::star::drawing::LineCap aLineCap(com::sun::star::drawing::LineCap_BUTT);
     842             : 
     843           1 :         if(aAny >>= aLineCap)
     844             :         {
     845           1 :             switch (aLineCap)
     846             :             {
     847             :                 default: /* com::sun::star::drawing::LineCap_BUTT */
     848             :                 {
     849           1 :                     AddOpt(ESCHER_Prop_lineEndCapStyle, ESCHER_LineEndCapFlat);
     850           1 :                     break;
     851             :                 }
     852             :                 case com::sun::star::drawing::LineCap_ROUND:
     853             :                 {
     854           0 :                     AddOpt(ESCHER_Prop_lineEndCapStyle, ESCHER_LineEndCapRound);
     855           0 :                     break;
     856             :                 }
     857             :                 case com::sun::star::drawing::LineCap_SQUARE:
     858             :                 {
     859           0 :                     AddOpt(ESCHER_Prop_lineEndCapStyle, ESCHER_LineEndCapSquare);
     860           0 :                     break;
     861             :                 }
     862             :             }
     863             :         }
     864             :     }
     865             : 
     866           2 :     if ( EscherPropertyValueHelper::GetPropertyValue(
     867           2 :         aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineStyle"  ) ), sal_False ) )
     868             :     {
     869             :         ::com::sun::star::drawing::LineStyle eLS;
     870           1 :         if ( aAny >>= eLS )
     871             :         {
     872           1 :             switch ( eLS )
     873             :             {
     874             :                 case ::com::sun::star::drawing::LineStyle_NONE :
     875           0 :                     AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 );           // 80000
     876           0 :                 break;
     877             : 
     878             :                 case ::com::sun::star::drawing::LineStyle_DASH :
     879             :                 {
     880           0 :                     if ( EscherPropertyValueHelper::GetPropertyValue(
     881           0 :                         aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineDash" ) ), sal_False ) )
     882             :                     {
     883           0 :                         ESCHER_LineDashing eDash = ESCHER_LineSolid;
     884           0 :                         ::com::sun::star::drawing::LineDash* pLineDash = (::com::sun::star::drawing::LineDash*)aAny.getValue();
     885           0 :                         sal_Int32 nDistance = pLineDash->Distance << 1;
     886           0 :                         switch ( pLineDash->Style )
     887             :                         {
     888             :                             case ::com::sun::star::drawing::DashStyle_ROUND :
     889             :                             case ::com::sun::star::drawing::DashStyle_ROUNDRELATIVE :
     890           0 :                                 AddOpt( ESCHER_Prop_lineEndCapStyle, 0 ); // set Style Round
     891           0 :                             break;
     892           0 :                             default : break;
     893             :                         }
     894           0 :                         if ( ((!(pLineDash->Dots )) || (!(pLineDash->Dashes )) ) || ( pLineDash->DotLen == pLineDash->DashLen ) )
     895             :                         {
     896           0 :                             sal_Int32 nLen = pLineDash->DotLen;
     897           0 :                             if ( pLineDash->Dashes )
     898           0 :                                 nLen = pLineDash->DashLen;
     899             : 
     900           0 :                             if ( nLen >= nDistance )
     901           0 :                                 eDash = ESCHER_LineLongDashGEL;
     902           0 :                             else if ( pLineDash->Dots )
     903           0 :                                 eDash = ESCHER_LineDotSys;
     904             :                             else
     905           0 :                                 eDash = ESCHER_LineDashGEL;
     906             :                         }
     907             :                         else                                                            // X Y
     908             :                         {
     909           0 :                             if ( pLineDash->Dots != pLineDash->Dashes )
     910             :                             {
     911           0 :                                 if ( ( pLineDash->DashLen > nDistance ) || ( pLineDash->DotLen > nDistance ) )
     912           0 :                                     eDash = ESCHER_LineLongDashDotDotGEL;
     913             :                                 else
     914           0 :                                     eDash = ESCHER_LineDashDotDotSys;
     915             :                             }
     916             :                             else                                                        // X Y Y
     917             :                             {
     918           0 :                                 if ( ( pLineDash->DashLen > nDistance ) || ( pLineDash->DotLen > nDistance ) )
     919           0 :                                     eDash = ESCHER_LineLongDashDotGEL;
     920             :                                 else
     921           0 :                                     eDash = ESCHER_LineDashDotGEL;
     922             : 
     923             :                             }
     924             :                         }
     925           0 :                         AddOpt( ESCHER_Prop_lineDashing, eDash );
     926             :                     }
     927             :                 }
     928             :                 case ::com::sun::star::drawing::LineStyle_SOLID :
     929             :                 default:
     930             :                 {
     931           1 :                     AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags );
     932             :                 }
     933           1 :                 break;
     934             :             }
     935             :         }
     936           2 :         if ( EscherPropertyValueHelper::GetPropertyValue(
     937           2 :             aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineColor"  ) ), sal_False ) )
     938             :         {
     939           1 :             sal_uInt32 nLineColor = ImplGetColor( *((sal_uInt32*)aAny.getValue()) );
     940           1 :             AddOpt( ESCHER_Prop_lineColor, nLineColor );
     941           1 :             AddOpt( ESCHER_Prop_lineBackColor, nLineColor ^ 0xffffff );
     942             :         }
     943             :     }
     944             : 
     945             :     sal_uInt32 nLineSize = ( EscherPropertyValueHelper::GetPropertyValue(
     946           2 :         aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineWidth"  ) ), sal_False ) )
     947           1 :         ? *((sal_uInt32*)aAny.getValue())
     948           2 :         : 0;
     949           1 :     if ( nLineSize > 1 )
     950           0 :         AddOpt( ESCHER_Prop_lineWidth, nLineSize * 360 );       // 100TH MM -> PT , 1PT = 12700 EMU
     951             : 
     952           1 :     ESCHER_LineJoin eLineJoin = ESCHER_LineJoinMiter;
     953           2 :     if ( EscherPropertyValueHelper::GetPropertyValue(
     954           2 :         aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineJoint" ) ), sal_True ) )
     955             :     {
     956             :         ::com::sun::star::drawing::LineJoint eLJ;
     957           1 :         if ( aAny >>= eLJ )
     958             :         {
     959           1 :             switch ( eLJ )
     960             :             {
     961             :                 case com::sun::star::drawing::LineJoint_NONE :
     962             :                 case com::sun::star::drawing::LineJoint_MIDDLE :
     963             :                 case com::sun::star::drawing::LineJoint_BEVEL :
     964           0 :                     eLineJoin = ESCHER_LineJoinBevel;
     965           0 :                 break;
     966             :                 default:
     967             :                 case com::sun::star::drawing::LineJoint_MITER :
     968           0 :                     eLineJoin = ESCHER_LineJoinMiter;
     969           0 :                 break;
     970             :                 case com::sun::star::drawing::LineJoint_ROUND :
     971           1 :                     eLineJoin = ESCHER_LineJoinRound;
     972           1 :                 break;
     973             :             }
     974             :         }
     975             :     }
     976           1 :     AddOpt( ESCHER_Prop_lineJoinStyle, eLineJoin );
     977             : 
     978           1 :     if ( bEdge == sal_False )
     979             :     {
     980           0 :         AddOpt( ESCHER_Prop_fFillOK, 0x1001 );
     981           0 :         AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
     982           1 :     }
     983           1 : }
     984             : 
     985           0 : static Size lcl_SizeToEmu(Size aPrefSize, MapMode aPrefMapMode)
     986             : {
     987           0 :     Size aRetSize;
     988           0 :     if (aPrefMapMode == MAP_PIXEL)
     989           0 :         aRetSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM );
     990             :     else
     991           0 :         aRetSize = Application::GetDefaultDevice()->LogicToLogic( aPrefSize, aPrefMapMode, MAP_100TH_MM );
     992           0 :     return aRetSize;
     993             : }
     994             : 
     995           0 : void EscherPropertyContainer::ImplCreateGraphicAttributes( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
     996             :                                                             sal_uInt32 nBlibId, sal_Bool bCreateCroppingAttributes )
     997             : {
     998           0 :     ::com::sun::star::uno::Any aAny;
     999             : 
    1000           0 :     sal_uInt32 nPicFlags = 0;
    1001           0 :     ::com::sun::star::drawing::ColorMode eColorMode( ::com::sun::star::drawing::ColorMode_STANDARD );
    1002           0 :     sal_Int16 nLuminance = 0;
    1003           0 :     sal_Int32 nContrast = 0;
    1004           0 :     sal_Int16 nRed = 0;
    1005           0 :     sal_Int16 nGreen = 0;
    1006           0 :     sal_Int16 nBlue = 0;
    1007           0 :     double fGamma = 1.0;
    1008           0 :     sal_Int16 nTransparency = 0;
    1009             : 
    1010           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicColorMode" ) ) ) )
    1011           0 :         aAny >>= eColorMode;
    1012           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustLuminance" ) ) ) )
    1013           0 :         aAny >>= nLuminance;
    1014           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustContrast" ) ) ) )
    1015             :     {
    1016           0 :         sal_Int16 nC = sal_Int16();
    1017           0 :         aAny >>= nC;
    1018           0 :         nContrast = nC;
    1019             :     }
    1020           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustRed" ) ) ) )
    1021           0 :         aAny >>= nRed;
    1022           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustGreen" ) ) ) )
    1023           0 :         aAny >>= nGreen;
    1024           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustBlue" ) ) ) )
    1025           0 :         aAny >>= nBlue;
    1026           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Gamma" ) ) ) )
    1027           0 :         aAny >>= fGamma;
    1028           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Transparency" ) ) ) )
    1029           0 :         aAny >>= nTransparency;
    1030             : 
    1031           0 :     if ( eColorMode == ::com::sun::star::drawing::ColorMode_WATERMARK )
    1032             :     {
    1033           0 :         eColorMode = ::com::sun::star::drawing::ColorMode_STANDARD;
    1034           0 :         nLuminance += 70;
    1035           0 :         if ( nLuminance > 100 )
    1036           0 :             nLuminance = 100;
    1037           0 :         nContrast -= 70;
    1038           0 :         if ( nContrast < -100 )
    1039           0 :             nContrast = -100;
    1040             :     }
    1041           0 :     if ( eColorMode == ::com::sun::star::drawing::ColorMode_GREYS )
    1042           0 :         nPicFlags |= 0x40004;
    1043           0 :     else if ( eColorMode == ::com::sun::star::drawing::ColorMode_MONO )
    1044           0 :         nPicFlags |= 0x60006;
    1045             : 
    1046           0 :     if ( nContrast )
    1047             :     {
    1048           0 :         nContrast += 100;
    1049           0 :         if ( nContrast == 100)
    1050           0 :             nContrast = 0x10000;
    1051           0 :         else if ( nContrast < 100 )
    1052             :         {
    1053           0 :             nContrast *= 0x10000;
    1054           0 :             nContrast /= 100;
    1055             :         }
    1056           0 :         else if ( nContrast < 200 )
    1057           0 :             nContrast = ( 100 * 0x10000 ) / ( 200 - nContrast );
    1058             :         else
    1059           0 :             nContrast = 0x7fffffff;
    1060           0 :         AddOpt( ESCHER_Prop_pictureContrast, nContrast );
    1061             :     }
    1062           0 :     if ( nLuminance )
    1063           0 :         AddOpt( ESCHER_Prop_pictureBrightness, nLuminance * 327 );
    1064           0 :     if ( nPicFlags )
    1065           0 :         AddOpt( ESCHER_Prop_pictureActive, nPicFlags );
    1066             : 
    1067           0 :     if ( bCreateCroppingAttributes && pGraphicProvider )
    1068             :     {
    1069           0 :         Size    aPrefSize;
    1070           0 :         MapMode aPrefMapMode;
    1071           0 :         if ( pGraphicProvider->GetPrefSize( nBlibId, aPrefSize, aPrefMapMode ) )
    1072             :         {
    1073           0 :             Size aCropSize(lcl_SizeToEmu(aPrefSize, aPrefMapMode));
    1074           0 :             if ( aCropSize.Width() && aCropSize.Height() )
    1075             :             {
    1076           0 :                 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicCrop" ) ) ) )
    1077             :                 {
    1078           0 :                     ::com::sun::star::text::GraphicCrop aGraphCrop;
    1079           0 :                     if ( aAny >>= aGraphCrop )
    1080             :                     {
    1081           0 :                         if ( aGraphCrop.Left )
    1082             :                         {
    1083           0 :                             sal_uInt32 nLeft = ( aGraphCrop.Left * 65536 ) / aCropSize.Width();
    1084           0 :                             AddOpt( ESCHER_Prop_cropFromLeft, nLeft );
    1085             :                         }
    1086           0 :                         if ( aGraphCrop.Top )
    1087             :                         {
    1088           0 :                             sal_uInt32 nTop = ( aGraphCrop.Top * 65536 ) / aCropSize.Height();
    1089           0 :                             AddOpt( ESCHER_Prop_cropFromTop, nTop );
    1090             :                         }
    1091           0 :                         if ( aGraphCrop.Right )
    1092             :                         {
    1093           0 :                             sal_uInt32 nRight = ( aGraphCrop.Right * 65536 ) / aCropSize.Width();
    1094           0 :                             AddOpt( ESCHER_Prop_cropFromRight, nRight );
    1095             :                         }
    1096           0 :                         if ( aGraphCrop.Bottom )
    1097             :                         {
    1098           0 :                             sal_uInt32 nBottom = ( aGraphCrop.Bottom * 65536 ) / aCropSize.Height();
    1099           0 :                             AddOpt( ESCHER_Prop_cropFromBottom, nBottom );
    1100             :                         }
    1101             :                     }
    1102             :                 }
    1103             :             }
    1104           0 :         }
    1105           0 :     }
    1106           0 : }
    1107             : 
    1108           1 : sal_Bool EscherPropertyContainer::CreateShapeProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape )
    1109             : {
    1110           1 :     uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY );
    1111           1 :     if ( aXPropSet.is() )
    1112             :     {
    1113           1 :         sal_Bool bVal = false;
    1114           1 :         ::com::sun::star::uno::Any aAny;
    1115           1 :         sal_uInt32 nShapeAttr = 0;
    1116           1 :         EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) ), sal_True );
    1117           1 :         if ( aAny >>= bVal )
    1118             :         {
    1119           1 :             if ( !bVal )
    1120           0 :                 nShapeAttr |= 0x20002;  // set fHidden = true
    1121             :         }
    1122           1 :         EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Printable" ) ), sal_True );
    1123           1 :         if ( aAny >>= bVal )
    1124             :         {
    1125           1 :             if ( !bVal )
    1126           0 :                 nShapeAttr |= 0x10000;  // set fPrint = false;
    1127             :         }
    1128           1 :         if ( nShapeAttr )
    1129           0 :             AddOpt( ESCHER_Prop_fPrint, nShapeAttr );
    1130             :     }
    1131           1 :     return sal_True;
    1132             : }
    1133             : 
    1134           0 : sal_Bool EscherPropertyContainer::CreateOLEGraphicProperties(
    1135             :     const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape )
    1136             : {
    1137           0 :     sal_Bool    bRetValue = sal_False;
    1138             : 
    1139           0 :     if ( rXShape.is() )
    1140             :     {
    1141           0 :         SdrObject* pSdrOLE2( GetSdrObjectFromXShape( rXShape ) );   // SJ: leaving unoapi, because currently there is
    1142           0 :         if ( pSdrOLE2 && pSdrOLE2->ISA( SdrOle2Obj ) )              // no access to the native graphic object
    1143             :         {
    1144           0 :             Graphic* pGraphic = ((SdrOle2Obj*)pSdrOLE2)->GetGraphic();
    1145           0 :             if ( pGraphic )
    1146             :             {
    1147           0 :                 GraphicObject aGraphicObject( *pGraphic );
    1148           0 :                 rtl::OString aUniqueId( aGraphicObject.GetUniqueID() );
    1149           0 :                 if ( !aUniqueId.isEmpty() )
    1150             :                 {
    1151           0 :                     AddOpt( ESCHER_Prop_fillType, ESCHER_FillPicture );
    1152           0 :                     uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY );
    1153             : 
    1154           0 :                     if ( pGraphicProvider && pPicOutStrm && pShapeBoundRect && aXPropSet.is() )
    1155             :                     {
    1156           0 :                         ::com::sun::star::uno::Any aAny;
    1157           0 :                         ::com::sun::star::awt::Rectangle* pVisArea = NULL;
    1158           0 :                         if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "VisibleArea" ) ) ) )
    1159             :                         {
    1160           0 :                             pVisArea = new ::com::sun::star::awt::Rectangle;
    1161           0 :                             aAny >>= (*pVisArea);
    1162             :                         }
    1163           0 :                         Rectangle aRect( Point( 0, 0 ), pShapeBoundRect->GetSize() );
    1164           0 :                         sal_uInt32 nBlibId = pGraphicProvider->GetBlibID( *pPicOutStrm, aUniqueId, aRect, pVisArea, NULL );
    1165           0 :                         if ( nBlibId )
    1166             :                         {
    1167           0 :                             AddOpt( ESCHER_Prop_pib, nBlibId, sal_True );
    1168           0 :                             ImplCreateGraphicAttributes( aXPropSet, nBlibId, sal_False );
    1169           0 :                             bRetValue = sal_True;
    1170             :                         }
    1171           0 :                         delete pVisArea;
    1172           0 :                     }
    1173           0 :                 }
    1174             :             }
    1175             :         }
    1176             :     }
    1177           0 :     return bRetValue;
    1178             : }
    1179             : 
    1180             : 
    1181           0 : sal_Bool EscherPropertyContainer::ImplCreateEmbeddedBmp( const rtl::OString& rUniqueId )
    1182             : {
    1183           0 :     if( !rUniqueId.isEmpty() )
    1184             :     {
    1185           0 :         EscherGraphicProvider aProvider;
    1186           0 :         SvMemoryStream aMemStrm;
    1187           0 :         Rectangle aRect;
    1188           0 :         if ( aProvider.GetBlibID( aMemStrm, rUniqueId, aRect ) )
    1189             :         {
    1190             :             // grab BLIP from stream and insert directly as complex property
    1191             :             // ownership of stream memory goes to complex property
    1192           0 :             aMemStrm.ObjectOwnsMemory( sal_False );
    1193           0 :             sal_uInt8* pBuf = (sal_uInt8*) aMemStrm.GetData();
    1194           0 :             sal_uInt32 nSize = aMemStrm.Seek( STREAM_SEEK_TO_END );
    1195           0 :             AddOpt( ESCHER_Prop_fillBlip, sal_True, nSize, pBuf, nSize );
    1196           0 :             return sal_True;
    1197           0 :         }
    1198             :     }
    1199           0 :     return sal_False;
    1200             : }
    1201             : 
    1202           0 : sal_Bool EscherPropertyContainer::CreateEmbeddedBitmapProperties(
    1203             :     const ::rtl::OUString& rBitmapUrl, ::com::sun::star::drawing::BitmapMode eBitmapMode )
    1204             : {
    1205           0 :     sal_Bool bRetValue = sal_False;
    1206           0 :     String aVndUrl( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
    1207           0 :     String aBmpUrl( rBitmapUrl );
    1208           0 :     xub_StrLen nIndex = aBmpUrl.Search( aVndUrl, 0 );
    1209           0 :     if( nIndex != STRING_NOTFOUND )
    1210             :     {
    1211             :         // note: += ist not defined for xub_StrLen -> conversion to int and back to xub_StrLen
    1212           0 :         nIndex = nIndex + aVndUrl.Len();
    1213           0 :         if( aBmpUrl.Len() > nIndex )
    1214             :         {
    1215           0 :             rtl::OString aUniqueId(rtl::OUStringToOString(aBmpUrl.Copy(nIndex, aBmpUrl.Len() - nIndex), RTL_TEXTENCODING_UTF8));
    1216           0 :             bRetValue = ImplCreateEmbeddedBmp( aUniqueId );
    1217           0 :             if( bRetValue )
    1218             :             {
    1219             :                 // bitmap mode property
    1220           0 :                 bool bRepeat = eBitmapMode == ::com::sun::star::drawing::BitmapMode_REPEAT;
    1221           0 :                 AddOpt( ESCHER_Prop_fillType, bRepeat ? ESCHER_FillTexture : ESCHER_FillPicture );
    1222           0 :             }
    1223             :         }
    1224             :     }
    1225           0 :     return bRetValue;
    1226             : }
    1227             : 
    1228             : 
    1229             : namespace {
    1230             : 
    1231           0 : GraphicObject lclDrawHatch( const ::com::sun::star::drawing::Hatch& rHatch, const Color& rBackColor, bool bFillBackground )
    1232             : {
    1233           0 :     const MapMode aMap100( MAP_100TH_MM );
    1234           0 :     VirtualDevice aVDev( *Application::GetDefaultDevice(), 0, 1 );
    1235           0 :     aVDev.SetMapMode( aMap100 );
    1236             : 
    1237           0 :     const Size aOutSize = aVDev.PixelToLogic( Size( 28, 28 ) );
    1238           0 :     aVDev.SetOutputSize( aOutSize );
    1239             : 
    1240           0 :     Rectangle aRectangle( Point( 0, 0 ), aOutSize );
    1241           0 :     const PolyPolygon aPolyPoly( aRectangle );
    1242             : 
    1243           0 :     aVDev.SetLineColor();
    1244           0 :     aVDev.SetFillColor( bFillBackground ? rBackColor : Color( COL_TRANSPARENT ) );
    1245           0 :     aVDev.DrawRect( Rectangle( Point(), aOutSize ) );
    1246             : 
    1247           0 :     Hatch aVclHatch( (HatchStyle) rHatch.Style, Color( rHatch.Color ), rHatch.Distance, (sal_uInt16)rHatch.Angle );
    1248           0 :     aVDev.DrawHatch( aPolyPoly, aVclHatch );
    1249             : 
    1250           0 :     return GraphicObject( Graphic( aVDev.GetBitmapEx( Point(), aOutSize ) ) );
    1251             : }
    1252             : 
    1253             : } // namespace
    1254             : 
    1255             : 
    1256           0 : sal_Bool EscherPropertyContainer::CreateEmbeddedHatchProperties( const ::com::sun::star::drawing::Hatch& rHatch, const Color& rBackColor, bool bFillBackground )
    1257             : {
    1258           0 :     GraphicObject aGraphicObject = lclDrawHatch( rHatch, rBackColor, bFillBackground );
    1259           0 :     rtl::OString aUniqueId = aGraphicObject.GetUniqueID();
    1260           0 :     sal_Bool bRetValue = ImplCreateEmbeddedBmp( aUniqueId );
    1261           0 :     if ( bRetValue )
    1262           0 :         AddOpt( ESCHER_Prop_fillType, ESCHER_FillTexture );
    1263           0 :     return bRetValue;
    1264             : }
    1265             : 
    1266             : 
    1267           0 : sal_Bool EscherPropertyContainer::CreateGraphicProperties(
    1268             :     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
    1269             :         const String& rSource, const sal_Bool bCreateFillBitmap, const sal_Bool bCreateCroppingAttributes,
    1270             :             const sal_Bool bFillBitmapModeAllowed )
    1271             : {
    1272           0 :     sal_Bool        bRetValue = sal_False;
    1273           0 :     sal_Bool        bCreateFillStyles = sal_False;
    1274             : 
    1275           0 :     sal_Bool        bMirrored = sal_False;
    1276           0 :     sal_Bool        bRotate   = sal_True;
    1277           0 :     GraphicAttr*    pGraphicAttr = NULL;
    1278           0 :     GraphicObject   aGraphicObject;
    1279           0 :     String          aGraphicUrl;
    1280           0 :     rtl::OString    aUniqueId;
    1281           0 :     bool            bIsGraphicMtf(false);
    1282             : 
    1283           0 :     ::com::sun::star::drawing::BitmapMode   eBitmapMode( ::com::sun::star::drawing::BitmapMode_NO_REPEAT );
    1284           0 :     ::com::sun::star::uno::Any aAny;
    1285             : 
    1286           0 :     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, rSource ) )
    1287             :     {
    1288           0 :         sal_uInt16 nAngle = 0;
    1289           0 :         if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ) )
    1290             :         {
    1291           0 :             ::com::sun::star::uno::Sequence<sal_uInt8> aSeq = *(::com::sun::star::uno::Sequence<sal_uInt8>*)aAny.getValue();
    1292           0 :             const sal_uInt8*    pAry = aSeq.getArray();
    1293           0 :             sal_uInt32          nAryLen = aSeq.getLength();
    1294             : 
    1295             :             // the metafile is already rotated
    1296           0 :             bRotate = sal_False;
    1297             : 
    1298           0 :             if ( pAry && nAryLen )
    1299             :             {
    1300           0 :                 Graphic         aGraphic;
    1301           0 :                 SvMemoryStream  aTemp( (void*)pAry, nAryLen, STREAM_READ );
    1302           0 :                 sal_uInt32 nErrCode = GraphicConverter::Import( aTemp, aGraphic, CVT_WMF );
    1303           0 :                 if ( nErrCode == ERRCODE_NONE )
    1304             :                 {
    1305           0 :                     aGraphicObject = aGraphic;
    1306           0 :                     aUniqueId = aGraphicObject.GetUniqueID();
    1307           0 :                     bIsGraphicMtf = aGraphicObject.GetType() == GRAPHIC_GDIMETAFILE;
    1308           0 :                 }
    1309           0 :             }
    1310             :         }
    1311           0 :         else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ) )
    1312             :         {
    1313           0 :             ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap >xBitmap;
    1314           0 :             if ( ::cppu::extractInterface( xBitmap, aAny ) )
    1315             :             {
    1316           0 :                 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp;
    1317           0 :                 if ( aAny >>= xBmp )
    1318             :                 {
    1319           0 :                     BitmapEx    aBitmapEx( VCLUnoHelper::GetBitmap( xBmp ) );
    1320           0 :                     Graphic     aGraphic( aBitmapEx );
    1321           0 :                     aGraphicObject = aGraphic;
    1322           0 :                     aUniqueId = aGraphicObject.GetUniqueID();
    1323           0 :                     bIsGraphicMtf = aGraphicObject.GetType() == GRAPHIC_GDIMETAFILE;
    1324           0 :                 }
    1325           0 :             }
    1326             :         }
    1327           0 :         else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ) )
    1328             :         {
    1329           0 :             aGraphicUrl = *(::rtl::OUString*)aAny.getValue();
    1330             :         }
    1331           0 :         else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ) )
    1332             :         {
    1333           0 :             aGraphicUrl = *(::rtl::OUString*)aAny.getValue();
    1334           0 :             bCreateFillStyles = sal_True;
    1335             :         }
    1336           0 :         else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "FillHatch" ) ) )
    1337             :         {
    1338           0 :             ::com::sun::star::drawing::Hatch aHatch;
    1339           0 :             if ( aAny >>= aHatch )
    1340             :             {
    1341           0 :                 Color aBackColor;
    1342           0 :                 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
    1343           0 :                     String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_False ) )
    1344             :                 {
    1345           0 :                     aBackColor = ImplGetColor( *((sal_uInt32*)aAny.getValue()), sal_False );
    1346             :                 }
    1347           0 :                 bool bFillBackground = false;
    1348           0 :                 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
    1349           0 :                         String( RTL_CONSTASCII_USTRINGPARAM( "FillBackground" ) ), sal_True ) )
    1350             :                 {
    1351           0 :                     aAny >>= bFillBackground;
    1352             :                 }
    1353           0 :                 aGraphicObject = lclDrawHatch( aHatch, aBackColor, bFillBackground );
    1354           0 :                 aUniqueId = aGraphicObject.GetUniqueID();
    1355           0 :                 eBitmapMode = ::com::sun::star::drawing::BitmapMode_REPEAT;
    1356           0 :                 bIsGraphicMtf = aGraphicObject.GetType() == GRAPHIC_GDIMETAFILE;
    1357             :             }
    1358             :         }
    1359             : 
    1360           0 :         if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsMirrored" ) ), sal_True ) )
    1361           0 :             aAny >>= bMirrored;
    1362             : 
    1363           0 :         if ( bCreateFillBitmap && bFillBitmapModeAllowed )
    1364             :         {
    1365           0 :             if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapMode" ) ), sal_True ) )
    1366           0 :                 aAny >>= eBitmapMode;
    1367             :         }
    1368             :         else
    1369             :         {
    1370             :             nAngle = bRotate && EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
    1371           0 :                                                                              String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True )
    1372           0 :                 ? (sal_uInt16)( ( *((sal_Int32*)aAny.getValue() ) ) + 5 ) / 10
    1373           0 :                 : 0;
    1374             :         }
    1375             : 
    1376           0 :         if ( aGraphicUrl.Len() )
    1377             :         {
    1378           0 :             String aVndUrl( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
    1379           0 :             xub_StrLen nIndex = aGraphicUrl.Search( aVndUrl, 0 );
    1380           0 :             if ( nIndex != STRING_NOTFOUND )
    1381             :             {
    1382           0 :                 nIndex = nIndex + aVndUrl.Len();
    1383           0 :                 if ( aGraphicUrl.Len() > nIndex  )
    1384           0 :                     aUniqueId = rtl::OUStringToOString(aGraphicUrl.Copy(nIndex, aGraphicUrl.Len() - nIndex), RTL_TEXTENCODING_UTF8);
    1385             :             }
    1386             :             else
    1387             :             {
    1388             :                 // externally, linked graphic? convert to embedded
    1389             :                 // one, if transformations are needed. this is because
    1390             :                 // everything < msoxp cannot even handle rotated
    1391             :                 // bitmaps.
    1392             :                 // And check whether the graphic link target is
    1393             :                 // actually supported by mso.
    1394           0 :                 INetURLObject   aTmp( aGraphicUrl );
    1395           0 :                 GraphicDescriptor aDescriptor(aTmp);
    1396           0 :                 aDescriptor.Detect();
    1397           0 :                 const sal_uInt16 nFormat = aDescriptor.GetFileFormat();
    1398             : 
    1399             :                 // can MSO handle it?
    1400           0 :                 if ( bMirrored || nAngle ||
    1401             :                      (nFormat != GFF_BMP &&
    1402             :                       nFormat != GFF_GIF &&
    1403             :                       nFormat != GFF_JPG &&
    1404             :                       nFormat != GFF_PNG &&
    1405             :                       nFormat != GFF_TIF &&
    1406             :                       nFormat != GFF_PCT &&
    1407             :                       nFormat != GFF_WMF &&
    1408             :                       nFormat != GFF_EMF) )
    1409             :                 {
    1410             :                     SvStream* pIn = ::utl::UcbStreamHelper::CreateStream(
    1411           0 :                         aTmp.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );
    1412           0 :                     if ( pIn )
    1413             :                     {
    1414           0 :                         Graphic aGraphic;
    1415           0 :                         sal_uInt32 nErrCode = GraphicConverter::Import( *pIn, aGraphic );
    1416             : 
    1417           0 :                         if ( nErrCode == ERRCODE_NONE )
    1418             :                         {
    1419             :                             // no.
    1420           0 :                             aGraphicObject = aGraphic;
    1421           0 :                             aUniqueId = aGraphicObject.GetUniqueID();
    1422             :                         }
    1423             :                         // else: simply keep the graphic link
    1424           0 :                         delete pIn;
    1425             :                     }
    1426             :                 }
    1427           0 :                 if ( aUniqueId.isEmpty() )
    1428             :                 {
    1429           0 :                     if ( pGraphicProvider )
    1430             :                     {
    1431           0 :                         const rtl::OUString& rBaseURI( pGraphicProvider->GetBaseURI() );
    1432           0 :                         INetURLObject aBaseURI( rBaseURI );
    1433           0 :                         if( aBaseURI.GetProtocol() == aTmp.GetProtocol() )
    1434             :                         {
    1435             :                             rtl::OUString aRelUrl( INetURLObject::GetRelURL( rBaseURI, aGraphicUrl,
    1436           0 :                                                     INetURLObject::WAS_ENCODED, INetURLObject::DECODE_TO_IURI, RTL_TEXTENCODING_UTF8, INetURLObject::FSYS_DETECT ) );
    1437           0 :                             if ( !aRelUrl.isEmpty() )
    1438           0 :                                 aGraphicUrl = aRelUrl;
    1439           0 :                         }
    1440             :                     }
    1441           0 :                 }
    1442           0 :             }
    1443             :         }
    1444             : 
    1445           0 :         if ( aGraphicUrl.Len() || !aUniqueId.isEmpty() )
    1446             :         {
    1447           0 :             if ( bMirrored || nAngle )
    1448             :             {
    1449           0 :                 pGraphicAttr = new GraphicAttr;
    1450           0 :                 if ( bMirrored )
    1451           0 :                     pGraphicAttr->SetMirrorFlags( BMP_MIRROR_HORZ );
    1452           0 :                 if ( bIsGraphicMtf )
    1453           0 :                     AddOpt( ESCHER_Prop_Rotation, ( ( ((sal_Int32)nAngle << 16 ) / 10 ) + 0x8000 ) &~ 0xffff );
    1454             :                 else
    1455             :                 {
    1456           0 :                     pGraphicAttr->SetRotation( nAngle );
    1457           0 :                     if ( nAngle && pShapeBoundRect )   // up to xp ppoint does not rotate bitmaps !
    1458             :                     {
    1459           0 :                         Polygon aPoly( *pShapeBoundRect );
    1460           0 :                         aPoly.Rotate( pShapeBoundRect->TopLeft(), nAngle );
    1461           0 :                         *pShapeBoundRect = aPoly.GetBoundRect();
    1462           0 :                         bSuppressRotation = sal_True;
    1463             :                     }
    1464             :                 }
    1465             :             }
    1466             : 
    1467           0 :             if ( eBitmapMode == ::com::sun::star::drawing::BitmapMode_REPEAT )
    1468           0 :                 AddOpt( ESCHER_Prop_fillType, ESCHER_FillTexture );
    1469             :             else
    1470           0 :                 AddOpt( ESCHER_Prop_fillType, ESCHER_FillPicture );
    1471             : 
    1472           0 :             if ( !aUniqueId.isEmpty() )
    1473             :             {
    1474             :                 // write out embedded graphic
    1475           0 :                 if ( pGraphicProvider && pPicOutStrm && pShapeBoundRect )
    1476             :                 {
    1477           0 :                     Rectangle aRect( Point( 0, 0 ), pShapeBoundRect->GetSize() );
    1478             : 
    1479           0 :                     sal_uInt32 nBlibId = 0;
    1480           0 :                     nBlibId = pGraphicProvider->GetBlibID( *pPicOutStrm, aUniqueId, aRect, NULL, pGraphicAttr );
    1481           0 :                     if ( nBlibId )
    1482             :                     {
    1483           0 :                         if ( bCreateFillBitmap )
    1484           0 :                             AddOpt( ESCHER_Prop_fillBlip, nBlibId, sal_True );
    1485             :                         else
    1486             :                         {
    1487           0 :                             AddOpt( ESCHER_Prop_pib, nBlibId, sal_True );
    1488           0 :                             ImplCreateGraphicAttributes( rXPropSet, nBlibId, bCreateCroppingAttributes );
    1489             :                         }
    1490           0 :                         bRetValue = sal_True;
    1491           0 :                     }
    1492             :                 }
    1493             :                 else
    1494             :                 {
    1495           0 :                     EscherGraphicProvider aProvider;
    1496           0 :                     SvMemoryStream aMemStrm;
    1497           0 :                     Rectangle aRect;
    1498             : 
    1499           0 :                     if ( aProvider.GetBlibID( aMemStrm, aUniqueId, aRect, NULL, pGraphicAttr ) )
    1500             :                     {
    1501             :                         // grab BLIP from stream and insert directly as complex property
    1502             :                         // ownership of stream memory goes to complex property
    1503           0 :                         aMemStrm.ObjectOwnsMemory( sal_False );
    1504           0 :                         sal_uInt8* pBuf = (sal_uInt8*) aMemStrm.GetData();
    1505           0 :                         sal_uInt32 nSize = aMemStrm.Seek( STREAM_SEEK_TO_END );
    1506           0 :                         AddOpt( ESCHER_Prop_fillBlip, sal_True, nSize, pBuf, nSize );
    1507           0 :                         bRetValue = sal_True;
    1508           0 :                     }
    1509             :                 }
    1510             :             }
    1511             :             // write out link to graphic
    1512             :             else
    1513             :             {
    1514             :                 OSL_ASSERT(aGraphicUrl.Len());
    1515             : 
    1516           0 :                 AddOpt( ESCHER_Prop_pibName, aGraphicUrl );
    1517           0 :                 sal_uInt32  nPibFlags=0;
    1518           0 :                 GetOpt( ESCHER_Prop_pibFlags, nPibFlags );
    1519             :                 AddOpt( ESCHER_Prop_pibFlags,
    1520           0 :                         ESCHER_BlipFlagLinkToFile|ESCHER_BlipFlagFile|ESCHER_BlipFlagDoNotSave | nPibFlags );
    1521             :             }
    1522             :         }
    1523             :     }
    1524           0 :     delete pGraphicAttr;
    1525           0 :     if ( bCreateFillStyles )
    1526           0 :         CreateFillProperties( rXPropSet, sal_True );
    1527             : 
    1528           0 :     return bRetValue;
    1529             : }
    1530             : 
    1531           0 : PolyPolygon EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape )
    1532             : {
    1533           0 :     PolyPolygon aRetPolyPoly;
    1534           0 :     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXPropSet;
    1535           0 :     ::com::sun::star::uno::Any aAny( rXShape->queryInterface(
    1536           0 :         ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >*) 0 ) ));
    1537             : 
    1538           0 :     String sPolyPolygonBezier( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) );
    1539           0 :     String sPolyPolygon     ( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) );
    1540           0 :     String sPolygon         ( RTL_CONSTASCII_USTRINGPARAM( "Polygon" ) );
    1541             : 
    1542           0 :     if ( aAny >>= aXPropSet )
    1543             :     {
    1544           0 :         sal_Bool bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolyPolygonBezier, sal_True );
    1545           0 :         if ( !bHasProperty )
    1546           0 :             bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolyPolygon, sal_True );
    1547           0 :         if ( !bHasProperty )
    1548           0 :             bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolygon, sal_True );
    1549           0 :         if ( bHasProperty )
    1550           0 :             aRetPolyPoly = GetPolyPolygon( aAny );
    1551             :     }
    1552           0 :     return aRetPolyPoly;
    1553             : }
    1554             : 
    1555           2 : PolyPolygon EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno::Any& rAny )
    1556             : {
    1557           2 :     sal_Bool bNoError = sal_True;
    1558             : 
    1559           2 :     Polygon aPolygon;
    1560           2 :     PolyPolygon aPolyPolygon;
    1561             : 
    1562           2 :     if ( rAny.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PolyPolygonBezierCoords* ) 0 ) )
    1563             :     {
    1564             :         ::com::sun::star::drawing::PolyPolygonBezierCoords* pSourcePolyPolygon
    1565           2 :             = (::com::sun::star::drawing::PolyPolygonBezierCoords*)rAny.getValue();
    1566           2 :         sal_uInt16 nOuterSequenceCount = (sal_uInt16)pSourcePolyPolygon->Coordinates.getLength();
    1567             : 
    1568             :         // Zeiger auf innere sequences holen
    1569           2 :         ::com::sun::star::drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->Coordinates.getArray();
    1570           2 :         ::com::sun::star::drawing::FlagSequence*  pOuterFlags = pSourcePolyPolygon->Flags.getArray();
    1571             : 
    1572           2 :         bNoError = pOuterSequence && pOuterFlags;
    1573           2 :         if ( bNoError )
    1574             :         {
    1575             :             sal_uInt16  a, b, nInnerSequenceCount;
    1576             :             ::com::sun::star::awt::Point* pArray;
    1577             : 
    1578             :             // dies wird ein Polygon set
    1579           2 :             for ( a = 0; a < nOuterSequenceCount; a++ )
    1580             :             {
    1581           0 :                 ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++;
    1582           0 :                 ::com::sun::star::drawing::FlagSequence*  pInnerFlags = pOuterFlags++;
    1583             : 
    1584           0 :                 bNoError = pInnerSequence && pInnerFlags;
    1585           0 :                 if  ( bNoError )
    1586             :                 {
    1587             :                     // Zeiger auf Arrays holen
    1588           0 :                     pArray = pInnerSequence->getArray();
    1589           0 :                     ::com::sun::star::drawing::PolygonFlags* pFlags = pInnerFlags->getArray();
    1590             : 
    1591           0 :                     if ( pArray && pFlags )
    1592             :                     {
    1593           0 :                         nInnerSequenceCount = (sal_uInt16)pInnerSequence->getLength();
    1594           0 :                         aPolygon = Polygon( nInnerSequenceCount );
    1595           0 :                         for( b = 0; b < nInnerSequenceCount; b++)
    1596             :                         {
    1597           0 :                             PolyFlags   ePolyFlags( *( (PolyFlags*)pFlags++ ) );
    1598           0 :                             ::com::sun::star::awt::Point aPoint( (::com::sun::star::awt::Point)*(pArray++) );
    1599           0 :                             aPolygon[ b ] = Point( aPoint.X, aPoint.Y );
    1600           0 :                             aPolygon.SetFlags( b, ePolyFlags );
    1601             : 
    1602           0 :                             if ( ePolyFlags == POLY_CONTROL )
    1603           0 :                                 continue;
    1604             :                         }
    1605           0 :                         aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND );
    1606             :                     }
    1607             :                 }
    1608             :             }
    1609             :         }
    1610             :     }
    1611           0 :     else if ( rAny.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PointSequenceSequence* ) 0 ) )
    1612             :     {
    1613             :         ::com::sun::star::drawing::PointSequenceSequence* pSourcePolyPolygon
    1614           0 :             = (::com::sun::star::drawing::PointSequenceSequence*)rAny.getValue();
    1615           0 :         sal_uInt16 nOuterSequenceCount = (sal_uInt16)pSourcePolyPolygon->getLength();
    1616             : 
    1617             :         // Zeiger auf innere sequences holen
    1618           0 :         ::com::sun::star::drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray();
    1619           0 :         bNoError = pOuterSequence != NULL;
    1620           0 :         if ( bNoError )
    1621             :         {
    1622             :             sal_uInt16 a, b, nInnerSequenceCount;
    1623             : 
    1624             :             // dies wird ein Polygon set
    1625           0 :             for( a = 0; a < nOuterSequenceCount; a++ )
    1626             :             {
    1627           0 :                 ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++;
    1628           0 :                 bNoError = pInnerSequence != NULL;
    1629           0 :                 if ( bNoError )
    1630             :                 {
    1631             :                     // Zeiger auf Arrays holen
    1632             :                     ::com::sun::star::awt::Point* pArray =
    1633           0 :                           pInnerSequence->getArray();
    1634           0 :                     if ( pArray != NULL )
    1635             :                     {
    1636           0 :                         nInnerSequenceCount = (sal_uInt16)pInnerSequence->getLength();
    1637           0 :                         aPolygon = Polygon( nInnerSequenceCount );
    1638           0 :                         for( b = 0; b < nInnerSequenceCount; b++)
    1639             :                         {
    1640           0 :                             aPolygon[ b ] = Point( pArray->X, pArray->Y );
    1641           0 :                             pArray++;
    1642             :                         }
    1643           0 :                         aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND );
    1644             :                     }
    1645             :                 }
    1646             :             }
    1647             :         }
    1648             :     }
    1649           0 :     else if ( rAny.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PointSequence* ) 0 ) )
    1650             :     {
    1651             :         ::com::sun::star::drawing::PointSequence* pInnerSequence =
    1652           0 :             (::com::sun::star::drawing::PointSequence*)rAny.getValue();
    1653             : 
    1654           0 :         bNoError = pInnerSequence != NULL;
    1655           0 :         if ( bNoError )
    1656             :         {
    1657             :             sal_uInt16 a, nInnerSequenceCount;
    1658             : 
    1659             :             // Zeiger auf Arrays holen
    1660           0 :             ::com::sun::star::awt::Point* pArray = pInnerSequence->getArray();
    1661           0 :             if ( pArray != NULL )
    1662             :             {
    1663           0 :                 nInnerSequenceCount = (sal_uInt16)pInnerSequence->getLength();
    1664           0 :                 aPolygon = Polygon( nInnerSequenceCount );
    1665           0 :                 for( a = 0; a < nInnerSequenceCount; a++)
    1666             :                 {
    1667           0 :                     aPolygon[ a ] = Point( pArray->X, pArray->Y );
    1668           0 :                     pArray++;
    1669             :                 }
    1670           0 :                 aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND );
    1671             :             }
    1672             :         }
    1673             :     }
    1674           2 :     return aPolyPolygon;
    1675             : }
    1676             : 
    1677           0 : sal_Bool EscherPropertyContainer::CreatePolygonProperties(
    1678             :     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
    1679             :         sal_uInt32 nFlags,
    1680             :             sal_Bool bBezier,
    1681             :                 ::com::sun::star::awt::Rectangle& rGeoRect,
    1682             :                     Polygon* pPolygon )
    1683             : {
    1684           0 :     static String sPolyPolygonBezier( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) );
    1685           0 :     static String sPolyPolygon      ( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) );
    1686             : 
    1687           0 :     sal_Bool    bRetValue = sal_True;
    1688           0 :     sal_Bool    bLine = ( nFlags & ESCHER_CREATEPOLYGON_LINE ) != 0;
    1689             : 
    1690           0 :     PolyPolygon aPolyPolygon;
    1691             : 
    1692           0 :     if ( pPolygon )
    1693           0 :         aPolyPolygon.Insert( *pPolygon, POLYPOLY_APPEND );
    1694             :     else
    1695             :     {
    1696           0 :         ::com::sun::star::uno::Any aAny;
    1697             :         bRetValue = EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
    1698           0 :                         ( bBezier ) ? sPolyPolygonBezier : sPolyPolygon, sal_True );
    1699           0 :         if ( bRetValue )
    1700             :         {
    1701           0 :             aPolyPolygon = GetPolyPolygon( aAny );
    1702           0 :             bRetValue = aPolyPolygon.Count() != 0;
    1703           0 :         }
    1704             :     }
    1705           0 :     if ( bRetValue )
    1706             :     {
    1707           0 :         if ( bLine )
    1708             :         {
    1709           0 :             if ( ( aPolyPolygon.Count() == 1 ) && ( aPolyPolygon[ 0 ].GetSize() == 2 ) )
    1710             :             {
    1711           0 :                 const Polygon& rPoly = aPolyPolygon[ 0 ];
    1712             :                 rGeoRect = ::com::sun::star::awt::Rectangle(
    1713           0 :                     rPoly[ 0 ].X(),
    1714           0 :                         rPoly[ 0 ].Y(),
    1715           0 :                             rPoly[ 1 ].X() - rPoly[ 0 ].X(),
    1716           0 :                                 rPoly[ 1 ].Y() - rPoly[ 0 ].Y() );
    1717             :             }
    1718             :             else
    1719           0 :                 bRetValue = sal_False;
    1720             :         }
    1721             :         else
    1722             :         {
    1723           0 :             Polygon aPolygon;
    1724             : 
    1725           0 :             sal_uInt16 i, j, k, nPoints, nBezPoints, nPolyCount = aPolyPolygon.Count();
    1726           0 :             Rectangle aRect( aPolyPolygon.GetBoundRect() );
    1727           0 :             rGeoRect = ::com::sun::star::awt::Rectangle( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight() );
    1728             : 
    1729           0 :             for ( nBezPoints = nPoints = i = 0; i < nPolyCount; i++ )
    1730             :             {
    1731           0 :                 k = aPolyPolygon[ i ].GetSize();
    1732           0 :                 nPoints = nPoints + k;
    1733           0 :                 for ( j = 0; j < k; j++ )
    1734             :                 {
    1735           0 :                     if ( aPolyPolygon[ i ].GetFlags( j ) != POLY_CONTROL )
    1736           0 :                         nBezPoints++;
    1737             :                 }
    1738             :             }
    1739           0 :             sal_uInt32 nVerticesBufSize = ( nPoints << 2 ) + 6;
    1740           0 :             sal_uInt8* pVerticesBuf = new sal_uInt8[ nVerticesBufSize ];
    1741             : 
    1742             : 
    1743           0 :             sal_uInt32 nSegmentBufSize = ( ( nBezPoints << 2 ) + 8 );
    1744           0 :             if ( nPolyCount > 1 )
    1745           0 :                 nSegmentBufSize += ( nPolyCount << 1 );
    1746           0 :             sal_uInt8* pSegmentBuf = new sal_uInt8[ nSegmentBufSize ];
    1747             : 
    1748           0 :             sal_uInt8* pPtr = pVerticesBuf;
    1749           0 :             *pPtr++ = (sal_uInt8)( nPoints );                    // Little endian
    1750           0 :             *pPtr++ = (sal_uInt8)( nPoints >> 8 );
    1751           0 :             *pPtr++ = (sal_uInt8)( nPoints );
    1752           0 :             *pPtr++ = (sal_uInt8)( nPoints >> 8 );
    1753           0 :             *pPtr++ = (sal_uInt8)0xf0;
    1754           0 :             *pPtr++ = (sal_uInt8)0xff;
    1755             : 
    1756           0 :             for ( j = 0; j < nPolyCount; j++ )
    1757             :             {
    1758           0 :                 aPolygon = aPolyPolygon[ j ];
    1759           0 :                 nPoints = aPolygon.GetSize();
    1760           0 :                 for ( i = 0; i < nPoints; i++ )             // write points from polygon to buffer
    1761             :                 {
    1762           0 :                     Point aPoint = aPolygon[ i ];
    1763           0 :                     aPoint.X() -= rGeoRect.X;
    1764           0 :                     aPoint.Y() -= rGeoRect.Y;
    1765             : 
    1766           0 :                     *pPtr++ = (sal_uInt8)( aPoint.X() );
    1767           0 :                     *pPtr++ = (sal_uInt8)( aPoint.X() >> 8 );
    1768           0 :                     *pPtr++ = (sal_uInt8)( aPoint.Y() );
    1769           0 :                     *pPtr++ = (sal_uInt8)( aPoint.Y() >> 8 );
    1770             :                 }
    1771             :             }
    1772             : 
    1773           0 :             pPtr = pSegmentBuf;
    1774           0 :             *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 1 );
    1775           0 :             *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 9 );
    1776           0 :             *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 1 );
    1777           0 :             *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 9 );
    1778           0 :             *pPtr++ = (sal_uInt8)2;
    1779           0 :             *pPtr++ = (sal_uInt8)0;
    1780             : 
    1781           0 :             for ( j = 0; j < nPolyCount; j++ )
    1782             :             {
    1783           0 :                 *pPtr++ = 0x0;          // Polygon start
    1784           0 :                 *pPtr++ = 0x40;
    1785           0 :                 aPolygon = aPolyPolygon[ j ];
    1786           0 :                 nPoints = aPolygon.GetSize();
    1787           0 :                 for ( i = 0; i < nPoints; i++ )         // write Polyflags to Buffer
    1788             :                 {
    1789           0 :                     *pPtr++ = 0;
    1790           0 :                     if ( bBezier )
    1791           0 :                         *pPtr++ = 0xb3;
    1792             :                     else
    1793           0 :                         *pPtr++ = 0xac;
    1794           0 :                     if ( ( i + 1 ) != nPoints )
    1795             :                     {
    1796           0 :                         *pPtr++ = 1;
    1797           0 :                         if ( aPolygon.GetFlags( i + 1 ) == POLY_CONTROL )
    1798             :                         {
    1799           0 :                             *pPtr++ = 0x20;
    1800           0 :                             i += 2;
    1801             :                         }
    1802             :                         else
    1803           0 :                             *pPtr++ = 0;
    1804             :                     }
    1805             :                 }
    1806           0 :                 if ( nPolyCount > 1 )
    1807             :                 {
    1808           0 :                     *pPtr++ = 1;                        // end of polygon
    1809           0 :                     *pPtr++ = 0x60;
    1810             :                 }
    1811             :             }
    1812           0 :             *pPtr++ = 0;
    1813           0 :             *pPtr++ = 0x80;
    1814             : 
    1815           0 :             AddOpt( ESCHER_Prop_geoRight, rGeoRect.Width );
    1816           0 :             AddOpt( ESCHER_Prop_geoBottom, rGeoRect.Height );
    1817             : 
    1818           0 :             AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex );
    1819           0 :             AddOpt( ESCHER_Prop_pVertices, sal_True, nVerticesBufSize - 6, (sal_uInt8*)pVerticesBuf, nVerticesBufSize );
    1820           0 :             AddOpt( ESCHER_Prop_pSegmentInfo, sal_True, nSegmentBufSize, (sal_uInt8*)pSegmentBuf, nSegmentBufSize );
    1821             :         }
    1822             :     }
    1823           0 :     return bRetValue;
    1824             : }
    1825             : 
    1826           0 : sal_Bool EscherPropertyContainer::CreateConnectorProperties(
    1827             :     const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape,
    1828             :     EscherSolverContainer& rSolverContainer, ::com::sun::star::awt::Rectangle& rGeoRect,
    1829             :             sal_uInt16& rShapeType, sal_uInt16& rShapeFlags )
    1830             : {
    1831           0 :     static String sEdgeKind             ( RTL_CONSTASCII_USTRINGPARAM( "EdgeKind" ) );
    1832           0 :     static String sEdgeStartPoint       ( RTL_CONSTASCII_USTRINGPARAM( "EdgeStartPoint" ) );
    1833           0 :     static String sEdgeEndPoint         ( RTL_CONSTASCII_USTRINGPARAM( "EdgeEndPoint" ) );
    1834           0 :     static String sEdgeStartConnection  ( RTL_CONSTASCII_USTRINGPARAM( "EdgeStartConnection" ) );
    1835           0 :     static String sEdgeEndConnection    ( RTL_CONSTASCII_USTRINGPARAM( "EdgeEndConnection" ) );
    1836             : 
    1837           0 :     sal_Bool bRetValue = sal_False;
    1838           0 :     rShapeType = rShapeFlags = 0;
    1839             : 
    1840           0 :     if ( rXShape.is() )
    1841             :     {
    1842           0 :         ::com::sun::star::awt::Point aStartPoint, aEndPoint;
    1843           0 :         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXPropSet;
    1844           0 :         ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > aShapeA, aShapeB;
    1845           0 :         ::com::sun::star::uno::Any aAny( rXShape->queryInterface( ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >*) 0 ) ));
    1846           0 :         if ( aAny >>= aXPropSet )
    1847             :         {
    1848           0 :             if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeKind, sal_True ) )
    1849             :             {
    1850             :                 ::com::sun::star::drawing::ConnectorType eCt;
    1851           0 :                 aAny >>= eCt;
    1852           0 :                 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeStartPoint ) )
    1853             :                 {
    1854           0 :                     aStartPoint = *(::com::sun::star::awt::Point*)aAny.getValue();
    1855           0 :                     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeEndPoint ) )
    1856             :                     {
    1857           0 :                         aEndPoint = *(::com::sun::star::awt::Point*)aAny.getValue();
    1858             : 
    1859           0 :                         rShapeFlags = SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT | SHAPEFLAG_CONNECTOR;
    1860             :                         rGeoRect = ::com::sun::star::awt::Rectangle( aStartPoint.X, aStartPoint.Y,
    1861           0 :                                                             ( aEndPoint.X - aStartPoint.X ) + 1, ( aEndPoint.Y - aStartPoint.Y ) + 1 );
    1862           0 :                         if ( rGeoRect.Height < 0 )          // justify
    1863             :                         {
    1864           0 :                             rShapeFlags |= SHAPEFLAG_FLIPV;
    1865           0 :                             rGeoRect.Y = aEndPoint.Y;
    1866           0 :                             rGeoRect.Height = -rGeoRect.Height;
    1867             :                         }
    1868           0 :                         if ( rGeoRect.Width < 0 )
    1869             :                         {
    1870           0 :                             rShapeFlags |= SHAPEFLAG_FLIPH;
    1871           0 :                             rGeoRect.X = aEndPoint.X;
    1872           0 :                             rGeoRect.Width = -rGeoRect.Width;
    1873             :                         }
    1874             :                         sal_uInt32 nAdjustValue1, nAdjustValue2, nAdjustValue3;
    1875           0 :                         nAdjustValue1 = nAdjustValue2 = nAdjustValue3 = 0x2a30;
    1876             : 
    1877           0 :                         if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeStartConnection ) )
    1878           0 :                             aAny >>= aShapeA;
    1879           0 :                         if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeEndConnection ) )
    1880           0 :                             aAny >>= aShapeB;
    1881           0 :                         rSolverContainer.AddConnector( rXShape, aStartPoint, aShapeA, aEndPoint, aShapeB );
    1882           0 :                         switch ( eCt )
    1883             :                         {
    1884             :                             case ::com::sun::star::drawing::ConnectorType_CURVE :
    1885             :                             {
    1886           0 :                                 rShapeType = ESCHER_ShpInst_CurvedConnector3;
    1887           0 :                                 AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleCurved );
    1888           0 :                                 AddOpt( ESCHER_Prop_adjustValue, nAdjustValue1 );
    1889           0 :                                 AddOpt( ESCHER_Prop_adjust2Value, -(sal_Int32)nAdjustValue2 );
    1890             :                             }
    1891           0 :                             break;
    1892             : 
    1893             :                             case ::com::sun::star::drawing::ConnectorType_STANDARD :// Connector 2->5
    1894             :                             {
    1895           0 :                                 rShapeType = ESCHER_ShpInst_BentConnector3;
    1896           0 :                                 AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleBent );
    1897             :                             }
    1898           0 :                             break;
    1899             : 
    1900             :                             default:
    1901             :                             case ::com::sun::star::drawing::ConnectorType_LINE :
    1902             :                             case ::com::sun::star::drawing::ConnectorType_LINES :   // Connector 2->5
    1903             :                             {
    1904           0 :                                 rShapeType = ESCHER_ShpInst_StraightConnector1;
    1905           0 :                                 AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleStraight );
    1906             :                             }
    1907           0 :                             break;
    1908             :                         }
    1909           0 :                         CreateLineProperties( aXPropSet, sal_False );
    1910           0 :                         bRetValue = bSuppressRotation = sal_True;
    1911             :                     }
    1912             :                 }
    1913             :             }
    1914           0 :         }
    1915             :     }
    1916           0 :     return bRetValue;
    1917             : }
    1918             : 
    1919           1 : sal_Bool EscherPropertyContainer::CreateShadowProperties(
    1920             :     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet )
    1921             : {
    1922           1 :     ::com::sun::star::uno::Any aAny;
    1923             : 
    1924           1 :     sal_Bool    bHasShadow = sal_False; // shadow is possible only if at least a fillcolor, linecolor or graphic is set
    1925           1 :     sal_uInt32  nLineFlags = 0;         // default : shape has no line
    1926           1 :     sal_uInt32  nFillFlags = 0x10;      //           shape is filled
    1927             : 
    1928           1 :     GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags );
    1929           1 :     GetOpt( ESCHER_Prop_fNoFillHitTest, nFillFlags );
    1930             : 
    1931             :     sal_uInt32 nDummy;
    1932           1 :     sal_Bool bGraphic = GetOpt( DFF_Prop_pib, nDummy ) || GetOpt( DFF_Prop_pibName, nDummy ) || GetOpt( DFF_Prop_pibFlags, nDummy );
    1933             : 
    1934           1 :     sal_uInt32 nShadowFlags = 0x20000;
    1935           1 :     if ( ( nLineFlags & 8 ) || ( nFillFlags & 0x10 ) || bGraphic )
    1936             :     {
    1937           2 :         if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
    1938           2 :                 String( RTL_CONSTASCII_USTRINGPARAM( "Shadow" ) ), sal_True ) )
    1939             :         {
    1940           1 :             if ( aAny >>= bHasShadow )
    1941             :             {
    1942           1 :                 if ( bHasShadow )
    1943             :                 {
    1944           0 :                     nShadowFlags |= 2;
    1945           0 :                     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
    1946           0 :                             String( RTL_CONSTASCII_USTRINGPARAM( "ShadowColor" ) ), sal_False ) )
    1947           0 :                         AddOpt( ESCHER_Prop_shadowColor, ImplGetColor( *((sal_uInt32*)aAny.getValue()) ) );
    1948           0 :                     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
    1949           0 :                             String( RTL_CONSTASCII_USTRINGPARAM( "ShadowXDistance" ) ), sal_False ) )
    1950           0 :                         AddOpt( ESCHER_Prop_shadowOffsetX, *((sal_Int32*)aAny.getValue()) * 360 );
    1951           0 :                     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
    1952           0 :                             String( RTL_CONSTASCII_USTRINGPARAM( "ShadowYDistance" ) ), sal_False ) )
    1953           0 :                         AddOpt( ESCHER_Prop_shadowOffsetY, *((sal_Int32*)aAny.getValue()) * 360 );
    1954           0 :                     if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
    1955           0 :                             String( RTL_CONSTASCII_USTRINGPARAM( "ShadowTransparence" ) ), sal_False ) )
    1956           0 :                         AddOpt( ESCHER_Prop_shadowOpacity,  0x10000 - (((sal_uInt32)*((sal_uInt16*)aAny.getValue())) * 655 ) );
    1957             :                 }
    1958             :             }
    1959             :         }
    1960             :     }
    1961           1 :     AddOpt( ESCHER_Prop_fshadowObscured, nShadowFlags );
    1962           1 :     return bHasShadow;
    1963             : }
    1964             : 
    1965          32 : sal_Int32 GetValueForEnhancedCustomShapeParameter( const com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter, const std::vector< sal_Int32 >& rEquationOrder )
    1966             : {
    1967          32 :     sal_Int32 nValue = 0;
    1968          32 :     if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
    1969             :     {
    1970           0 :         double fValue(0.0);
    1971           0 :         if ( rParameter.Value >>= fValue )
    1972           0 :             nValue = (sal_Int32)fValue;
    1973             :     }
    1974             :     else
    1975          32 :         rParameter.Value >>= nValue;
    1976             : 
    1977          32 :     switch( rParameter.Type )
    1978             :     {
    1979             :         case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION :
    1980             :         {
    1981           0 :             nValue = (sal_uInt16)rEquationOrder[ nValue ];
    1982           0 :             nValue |= (sal_uInt32)0x80000000;
    1983             :         }
    1984           0 :         break;
    1985             :         case com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL :
    1986             :         {
    1987             : 
    1988             :         }
    1989          32 :         break;
    1990             :     }
    1991          32 :     return nValue;
    1992             : }
    1993             : 
    1994           0 : sal_Bool GetValueForEnhancedCustomShapeHandleParameter( sal_Int32& nRetValue, const com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter )
    1995             : {
    1996           0 :     sal_Bool bSpecial = sal_False;
    1997           0 :     nRetValue = 0;
    1998           0 :     if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
    1999             :     {
    2000           0 :         double fValue(0.0);
    2001           0 :         if ( rParameter.Value >>= fValue )
    2002           0 :             nRetValue = (sal_Int32)fValue;
    2003             :     }
    2004             :     else
    2005           0 :         rParameter.Value >>= nRetValue;
    2006             : 
    2007           0 :     switch( rParameter.Type )
    2008             :     {
    2009             :         case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION :
    2010             :         {
    2011           0 :             nRetValue += 3;
    2012           0 :             bSpecial = sal_True;
    2013             :         }
    2014           0 :         break;
    2015             :         case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT :
    2016             :         {
    2017           0 :             nRetValue += 0x100;
    2018           0 :             bSpecial = sal_True;
    2019             :         }
    2020           0 :         break;
    2021             :         case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP :
    2022             :         case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT :
    2023             :         {
    2024           0 :             nRetValue = 0;
    2025           0 :             bSpecial = sal_True;
    2026             :         }
    2027           0 :         break;
    2028             :         case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT :
    2029             :         case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM :
    2030             :         {
    2031           0 :             nRetValue = 1;
    2032           0 :             bSpecial = sal_True;
    2033             :         }
    2034           0 :         break;
    2035             :         case com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL :
    2036             :         {
    2037             : 
    2038             :         }
    2039           0 :         break;
    2040             :     }
    2041           0 :     return bSpecial;
    2042             : }
    2043             : 
    2044           1 : void ConvertEnhancedCustomShapeEquation( SdrObjCustomShape* pCustoShape,
    2045             :         std::vector< EnhancedCustomShapeEquation >& rEquations, std::vector< sal_Int32 >& rEquationOrder )
    2046             : {
    2047           1 :     if ( pCustoShape )
    2048             :     {
    2049           1 :         uno::Sequence< rtl::OUString > sEquationSource;
    2050           1 :         const rtl::OUString sEquations( "Equations"  );
    2051             :         SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)(const SdrCustomShapeGeometryItem&)
    2052           1 :             pCustoShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
    2053           1 :         const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sEquations );
    2054           1 :         if ( pAny )
    2055           0 :             *pAny >>= sEquationSource;
    2056           1 :         sal_Int32 nEquationSourceCount = sEquationSource.getLength();
    2057           1 :         if ( nEquationSourceCount )
    2058             :         {
    2059             :             sal_Int32 i;
    2060           0 :             for ( i = 0; i < nEquationSourceCount; i++ )
    2061             :             {
    2062           0 :                 EnhancedCustomShape2d aCustoShape2d( pCustoShape );
    2063             :                 try
    2064             :                 {
    2065             :                     ::boost::shared_ptr< EnhancedCustomShape::ExpressionNode > aExpressNode(
    2066           0 :                         EnhancedCustomShape::FunctionParser::parseFunction( sEquationSource[ i ], aCustoShape2d ) );
    2067           0 :                     com::sun::star::drawing::EnhancedCustomShapeParameter aPara( aExpressNode->fillNode( rEquations, NULL, 0 ) );
    2068           0 :                     if ( aPara.Type != com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION )
    2069             :                     {
    2070           0 :                         EnhancedCustomShapeEquation aEquation;
    2071           0 :                         aEquation.nOperation = 0;
    2072           0 :                         EnhancedCustomShape::FillEquationParameter( aPara, 0, aEquation );
    2073           0 :                         rEquations.push_back( aEquation );
    2074           0 :                     }
    2075             :                 }
    2076           0 :                 catch ( const EnhancedCustomShape::ParseError& )
    2077             :                 {
    2078           0 :                     EnhancedCustomShapeEquation aEquation;      // ups, we should not be here,
    2079           0 :                     aEquation.nOperation = 0;                   // creating a default equation with value 1
    2080           0 :                     aEquation.nPara[ 0 ] = 1;                   // hoping that this will not break anything
    2081           0 :                     rEquations.push_back( aEquation );
    2082             :                 }
    2083           0 :                 catch ( ... )
    2084             :                 {
    2085           0 :                     EnhancedCustomShapeEquation aEquation;      // #i112309# EnhancedCustomShape::Parse error
    2086           0 :                     aEquation.nOperation = 0;                   // not catched on linux platform
    2087           0 :                     aEquation.nPara[ 0 ] = 1;
    2088           0 :                     rEquations.push_back( aEquation );
    2089             :                 }
    2090           0 :                 rEquationOrder.push_back( rEquations.size() - 1 );
    2091           0 :             }
    2092             :             // now updating our old equation indices, they are marked with a bit in the hiword of nOperation
    2093           0 :             std::vector< EnhancedCustomShapeEquation >::iterator aIter( rEquations.begin() );
    2094           0 :             std::vector< EnhancedCustomShapeEquation >::iterator aEnd ( rEquations.end() );
    2095           0 :             while( aIter != aEnd )
    2096             :             {
    2097           0 :                 sal_Int32 nMask = 0x20000000;
    2098           0 :                 for( i = 0; i < 3; i++ )
    2099             :                 {
    2100           0 :                     if ( aIter->nOperation & nMask )
    2101             :                     {
    2102           0 :                         aIter->nOperation ^= nMask;
    2103           0 :                         aIter->nPara[ i ] = rEquationOrder[ aIter->nPara[ i ] & 0x3ff ] | 0x400;
    2104             :                     }
    2105           0 :                     nMask <<= 1;
    2106             :                 }
    2107           0 :                 ++aIter;
    2108             :             }
    2109           1 :         }
    2110             :     }
    2111           1 : }
    2112             : 
    2113           1 : sal_Bool EscherPropertyContainer::IsDefaultObject( SdrObjCustomShape* pCustoShape )
    2114             : {
    2115           1 :     sal_Bool bIsDefaultObject = sal_False;
    2116           1 :     if ( pCustoShape )
    2117             :     {
    2118           1 :     if (   pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_EQUATIONS )
    2119           0 :            && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_VIEWBOX )
    2120           0 :            && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_PATH )
    2121           0 :            && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_GLUEPOINTS )
    2122           0 :            && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_SEGMENTS )
    2123           0 :            && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_STRETCHX )
    2124           0 :            && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_STRETCHY )
    2125           0 :            && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_TEXTFRAMES ) )
    2126           0 :         bIsDefaultObject = sal_True;
    2127             :     }
    2128             : 
    2129           1 :     return bIsDefaultObject;
    2130             : }
    2131             : 
    2132           1 : void EscherPropertyContainer::LookForPolarHandles( const MSO_SPT eShapeType, sal_Int32& nAdjustmentsWhichNeedsToBeConverted )
    2133             : {
    2134           1 :     const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eShapeType );
    2135           1 :     if ( pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
    2136             :     {
    2137           0 :     sal_Int32 k, nkCount = pDefCustomShape->nHandles;
    2138           0 :     const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
    2139           0 :     for ( k = 0; k < nkCount; k++, pData++ )
    2140             :     {
    2141           0 :         if ( pData->nFlags & MSDFF_HANDLE_FLAGS_POLAR )
    2142             :         {
    2143           0 :         if ( ( pData->nPositionY >= 0x256 ) || ( pData->nPositionY <= 0x107 ) )
    2144           0 :             nAdjustmentsWhichNeedsToBeConverted |= ( 1 << k );
    2145             :         }
    2146             :     }
    2147             :     }
    2148           1 : }
    2149             : 
    2150           0 : sal_Bool EscherPropertyContainer::GetAdjustmentValue( const com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue & rkProp, sal_Int32 nIndex, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, sal_Int32& nValue )
    2151             : {
    2152           0 :     if ( rkProp.State != beans::PropertyState_DIRECT_VALUE )
    2153           0 :     return sal_False;
    2154             : 
    2155           0 :     sal_Bool bUseFixedFloat = ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << nIndex ) ) != 0;
    2156           0 :     if ( rkProp.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
    2157             :     {
    2158           0 :     double fValue(0.0);
    2159           0 :     rkProp.Value >>= fValue;
    2160           0 :     if ( bUseFixedFloat )
    2161           0 :         fValue *= 65536.0;
    2162           0 :     nValue = (sal_Int32)fValue;
    2163             :     }
    2164             :     else
    2165             :     {
    2166           0 :     rkProp.Value >>= nValue;
    2167           0 :     if ( bUseFixedFloat )
    2168           0 :         nValue <<= 16;
    2169             :     }
    2170             : 
    2171           0 :     return sal_True;
    2172             : }
    2173             : 
    2174           1 : void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeType, const uno::Reference< drawing::XShape > & rXShape )
    2175             : {
    2176           1 :     uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY );
    2177           1 :     if ( aXPropSet.is() )
    2178             :     {
    2179           1 :         SdrObjCustomShape* pCustoShape = (SdrObjCustomShape*)GetSdrObjectFromXShape( rXShape );
    2180           1 :         const rtl::OUString sCustomShapeGeometry( "CustomShapeGeometry"  );
    2181           1 :         uno::Any aGeoPropSet = aXPropSet->getPropertyValue( sCustomShapeGeometry );
    2182           1 :         uno::Sequence< beans::PropertyValue > aGeoPropSeq;
    2183           1 :         if ( aGeoPropSet >>= aGeoPropSeq )
    2184             :         {
    2185           1 :             const rtl::OUString sViewBox            ( "ViewBox"  );
    2186           1 :             const rtl::OUString sTextRotateAngle    ( "TextRotateAngle"  );
    2187           1 :             const rtl::OUString sExtrusion          ( "Extrusion"  );
    2188           1 :             const rtl::OUString sEquations          ( "Equations"  );
    2189           1 :             const rtl::OUString sPath               ( "Path"  );
    2190           1 :             const rtl::OUString sTextPath           ( "TextPath"  );
    2191           1 :             const rtl::OUString sHandles            ( "Handles"  );
    2192           1 :             const rtl::OUString sAdjustmentValues   ( "AdjustmentValues"  );
    2193             : 
    2194           1 :             const beans::PropertyValue* pAdjustmentValuesProp = NULL;
    2195           1 :             sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
    2196           1 :             uno::Sequence< beans::PropertyValues > aHandlesPropSeq;
    2197           1 :             sal_Bool bPredefinedHandlesUsed = sal_True;
    2198           1 :             sal_Bool bIsDefaultObject = IsDefaultObject( pCustoShape );
    2199             : 
    2200             :             // convert property "Equations" into std::vector< EnhancedCustomShapeEquationEquation >
    2201           1 :             std::vector< EnhancedCustomShapeEquation >  aEquations;
    2202           1 :             std::vector< sal_Int32 >                    aEquationOrder;
    2203           1 :             ConvertEnhancedCustomShapeEquation( pCustoShape, aEquations, aEquationOrder );
    2204             : 
    2205           1 :             sal_Int32 i, nCount = aGeoPropSeq.getLength();
    2206           5 :             for ( i = 0; i < nCount; i++ )
    2207             :             {
    2208           4 :                 const beans::PropertyValue& rProp = aGeoPropSeq[ i ];
    2209           4 :                 if ( rProp.Name.equals( sViewBox ) )
    2210             :                 {
    2211           1 :                     if ( !bIsDefaultObject )
    2212             :                     {
    2213           1 :                         awt::Rectangle aViewBox;
    2214           1 :                         if ( rProp.Value >>= aViewBox )
    2215             :                         {
    2216           1 :                             AddOpt( DFF_Prop_geoLeft,  aViewBox.X );
    2217           1 :                             AddOpt( DFF_Prop_geoTop,   aViewBox.Y );
    2218           1 :                             AddOpt( DFF_Prop_geoRight, aViewBox.X + aViewBox.Width );
    2219           1 :                             AddOpt( DFF_Prop_geoBottom,aViewBox.Y + aViewBox.Height );
    2220             :                         }
    2221             :                     }
    2222             :                 }
    2223           3 :                 else if ( rProp.Name.equals( sTextRotateAngle ) )
    2224             :                 {
    2225           0 :                     double f = 0;
    2226           0 :                     if ( rProp.Value >>= f )
    2227             :                     {
    2228           0 :                         double fTextRotateAngle = fmod( f, 360.0 );
    2229           0 :                         if ( fTextRotateAngle < 0 )
    2230           0 :                             fTextRotateAngle = 360 + fTextRotateAngle;
    2231           0 :                         if ( ( fTextRotateAngle < 271.0 ) && ( fTextRotateAngle > 269.0 ) )
    2232           0 :                             AddOpt( DFF_Prop_cdirFont, mso_cdir90 );
    2233           0 :                         else if ( ( fTextRotateAngle < 181.0 ) && ( fTextRotateAngle > 179.0 ) )
    2234           0 :                             AddOpt( DFF_Prop_cdirFont, mso_cdir180 );
    2235           0 :                         else if ( ( fTextRotateAngle < 91.0 ) && ( fTextRotateAngle > 79.0 ) )
    2236           0 :                             AddOpt( DFF_Prop_cdirFont, mso_cdir270 );
    2237             :                     }
    2238             :                 }
    2239           3 :                 else if ( rProp.Name.equals( sExtrusion ) )
    2240             :                 {
    2241           0 :                     uno::Sequence< beans::PropertyValue > aExtrusionPropSeq;
    2242           0 :                     if ( rProp.Value >>= aExtrusionPropSeq )
    2243             :                     {
    2244             :                         sal_uInt32 nLightFaceFlagsOrg, nLightFaceFlags;
    2245             :                         sal_uInt32 nFillHarshFlagsOrg, nFillHarshFlags;
    2246           0 :                         nLightFaceFlagsOrg = nLightFaceFlags = 0x000001;
    2247           0 :                         nFillHarshFlagsOrg = nFillHarshFlags = 0x00001e;
    2248           0 :                         if ( GetOpt( DFF_Prop_fc3DLightFace, nLightFaceFlags ) )
    2249           0 :                             nLightFaceFlagsOrg = nLightFaceFlags;
    2250           0 :                         if ( GetOpt( DFF_Prop_fc3DFillHarsh, nFillHarshFlags ) )
    2251           0 :                             nFillHarshFlagsOrg = nFillHarshFlags;
    2252             : 
    2253           0 :                         sal_Int32 r, nrCount = aExtrusionPropSeq.getLength();
    2254           0 :                         for ( r = 0; r < nrCount; r++ )
    2255             :                         {
    2256           0 :                             const beans::PropertyValue& rrProp = aExtrusionPropSeq[ r ];
    2257           0 :                             const rtl::OUString sExtrusionBrightness            ( "Brightness"  );
    2258           0 :                             const rtl::OUString sExtrusionDepth                 ( "Depth"  );
    2259           0 :                             const rtl::OUString sExtrusionDiffusion             ( "Diffusion"  );
    2260           0 :                             const rtl::OUString sExtrusionNumberOfLineSegments  ( "NumberOfLineSegments"  );
    2261           0 :                             const rtl::OUString sExtrusionLightFace             ( "LightFace"  );
    2262           0 :                             const rtl::OUString sExtrusionFirstLightHarsh       ( "FirstLightHarsh"  );
    2263           0 :                             const rtl::OUString sExtrusionSecondLightHarsh      ( "SecondLightHarsh"  );
    2264           0 :                             const rtl::OUString sExtrusionFirstLightLevel       ( "FirstLightLevel"  );
    2265           0 :                             const rtl::OUString sExtrusionSecondLightLevel      ( "SecondLightLevel"  );
    2266           0 :                             const rtl::OUString sExtrusionFirstLightDirection   ( "FirstLightDirection"  );
    2267           0 :                             const rtl::OUString sExtrusionSecondLightDirection  ( "SecondLightDirection"  );
    2268           0 :                             const rtl::OUString sExtrusionMetal                 ( "Metal"  );
    2269           0 :                             const rtl::OUString sExtrusionShadeMode             ( "ShadeMode"  );
    2270           0 :                             const rtl::OUString sExtrusionRotateAngle           ( "RotateAngle"  );
    2271           0 :                             const rtl::OUString sExtrusionRotationCenter        ( "RotationCenter"  );
    2272           0 :                             const rtl::OUString sExtrusionShininess             ( "Shininess"  );
    2273           0 :                             const rtl::OUString sExtrusionSkew                  ( "Skew"  );
    2274           0 :                             const rtl::OUString sExtrusionSpecularity           ( "Specularity"  );
    2275           0 :                             const rtl::OUString sExtrusionProjectionMode        ( "ProjectionMode"  );
    2276           0 :                             const rtl::OUString sExtrusionViewPoint             ( "ViewPoint"  );
    2277           0 :                             const rtl::OUString sExtrusionOrigin                ( "Origin"  );
    2278           0 :                             const rtl::OUString sExtrusionColor                 ( "Color"  );
    2279             : 
    2280           0 :                             if ( rrProp.Name.equals( sExtrusion ) )
    2281             :                             {
    2282           0 :                                 sal_Bool bExtrusionOn = sal_Bool();
    2283           0 :                                 if ( rrProp.Value >>= bExtrusionOn )
    2284             :                                 {
    2285           0 :                                     nLightFaceFlags |= 0x80000;
    2286           0 :                                     if ( bExtrusionOn )
    2287           0 :                                         nLightFaceFlags |= 8;
    2288             :                                     else
    2289           0 :                                         nLightFaceFlags &=~8;
    2290             :                                 }
    2291             :                             }
    2292           0 :                             else if ( rrProp.Name.equals( sExtrusionBrightness ) )
    2293             :                             {
    2294           0 :                                 double fExtrusionBrightness = 0;
    2295           0 :                                 if ( rrProp.Value >>= fExtrusionBrightness )
    2296           0 :                                     AddOpt( DFF_Prop_c3DAmbientIntensity, (sal_Int32)( fExtrusionBrightness * 655.36 ) );
    2297             :                             }
    2298           0 :                             else if ( rrProp.Name.equals( sExtrusionDepth ) )
    2299             :                             {
    2300           0 :                                 double fDepth = 0;
    2301           0 :                                 double fFraction = 0;
    2302           0 :                                 com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair;
    2303           0 :                                 if ( ( rrProp.Value >>= aDepthParaPair ) && ( aDepthParaPair.First.Value >>= fDepth ) && ( aDepthParaPair.Second.Value >>= fFraction ) )
    2304             :                                 {
    2305           0 :                                     double fForeDepth = fDepth * fFraction;
    2306           0 :                                     double fBackDepth = fDepth - fForeDepth;
    2307             : 
    2308           0 :                                     fBackDepth *= 360.0;
    2309           0 :                                     AddOpt( DFF_Prop_c3DExtrudeBackward, (sal_Int32)fBackDepth );
    2310             : 
    2311           0 :                                     if ( fForeDepth != 0.0 )
    2312             :                                     {
    2313           0 :                                         fForeDepth *= 360.0;
    2314           0 :                                         AddOpt( DFF_Prop_c3DExtrudeForward, (sal_Int32)fForeDepth );
    2315             :                                     }
    2316           0 :                                 }
    2317             :                             }
    2318           0 :                             else if ( rrProp.Name.equals( sExtrusionDiffusion ) )
    2319             :                             {
    2320           0 :                                 double fExtrusionDiffusion = 0;
    2321           0 :                                 if ( rrProp.Value >>= fExtrusionDiffusion )
    2322           0 :                                     AddOpt( DFF_Prop_c3DDiffuseAmt, (sal_Int32)( fExtrusionDiffusion * 655.36 ) );
    2323             :                             }
    2324           0 :                             else if ( rrProp.Name.equals( sExtrusionNumberOfLineSegments ) )
    2325             :                             {
    2326           0 :                                 sal_Int32 nExtrusionNumberOfLineSegments = 0;
    2327           0 :                                 if ( rrProp.Value >>= nExtrusionNumberOfLineSegments )
    2328           0 :                                     AddOpt( DFF_Prop_c3DTolerance, nExtrusionNumberOfLineSegments );
    2329             :                             }
    2330           0 :                             else if ( rrProp.Name.equals( sExtrusionLightFace ) )
    2331             :                             {
    2332           0 :                                 sal_Bool bExtrusionLightFace = sal_Bool();
    2333           0 :                                 if ( rrProp.Value >>= bExtrusionLightFace )
    2334             :                                 {
    2335           0 :                                     nLightFaceFlags |= 0x10000;
    2336           0 :                                     if ( bExtrusionLightFace )
    2337           0 :                                         nLightFaceFlags |= 1;
    2338             :                                     else
    2339           0 :                                         nLightFaceFlags &=~1;
    2340             :                                 }
    2341             :                             }
    2342           0 :                             else if ( rrProp.Name.equals( sExtrusionFirstLightHarsh ) )
    2343             :                             {
    2344           0 :                                 sal_Bool bExtrusionFirstLightHarsh = sal_Bool();
    2345           0 :                                 if ( rrProp.Value >>= bExtrusionFirstLightHarsh )
    2346             :                                 {
    2347           0 :                                     nFillHarshFlags |= 0x20000;
    2348           0 :                                     if ( bExtrusionFirstLightHarsh )
    2349           0 :                                         nFillHarshFlags |= 2;
    2350             :                                     else
    2351           0 :                                         nFillHarshFlags &=~2;
    2352             :                                 }
    2353             :                             }
    2354           0 :                             else if ( rrProp.Name.equals( sExtrusionSecondLightHarsh ) )
    2355             :                             {
    2356           0 :                                 sal_Bool bExtrusionSecondLightHarsh = sal_Bool();
    2357           0 :                                 if ( rrProp.Value >>= bExtrusionSecondLightHarsh )
    2358             :                                 {
    2359           0 :                                     nFillHarshFlags |= 0x10000;
    2360           0 :                                     if ( bExtrusionSecondLightHarsh )
    2361           0 :                                         nFillHarshFlags |= 1;
    2362             :                                     else
    2363           0 :                                         nFillHarshFlags &=~1;
    2364             :                                 }
    2365             :                             }
    2366           0 :                             else if ( rrProp.Name.equals( sExtrusionFirstLightLevel ) )
    2367             :                             {
    2368           0 :                                 double fExtrusionFirstLightLevel = 0;
    2369           0 :                                 if ( rrProp.Value >>= fExtrusionFirstLightLevel )
    2370           0 :                                     AddOpt( DFF_Prop_c3DKeyIntensity, (sal_Int32)( fExtrusionFirstLightLevel * 655.36 ) );
    2371             :                             }
    2372           0 :                             else if ( rrProp.Name.equals( sExtrusionSecondLightLevel ) )
    2373             :                             {
    2374           0 :                                 double fExtrusionSecondLightLevel = 0;
    2375           0 :                                 if ( rrProp.Value >>= fExtrusionSecondLightLevel )
    2376           0 :                                     AddOpt( DFF_Prop_c3DFillIntensity, (sal_Int32)( fExtrusionSecondLightLevel * 655.36 ) );
    2377             :                             }
    2378           0 :                             else if ( rrProp.Name.equals( sExtrusionFirstLightDirection ) )
    2379             :                             {
    2380           0 :                                 drawing::Direction3D aExtrusionFirstLightDirection;
    2381           0 :                                 if ( rrProp.Value >>= aExtrusionFirstLightDirection )
    2382             :                                 {
    2383           0 :                                     AddOpt( DFF_Prop_c3DKeyX, (sal_Int32)aExtrusionFirstLightDirection.DirectionX  );
    2384           0 :                                     AddOpt( DFF_Prop_c3DKeyY, (sal_Int32)aExtrusionFirstLightDirection.DirectionY  );
    2385           0 :                                     AddOpt( DFF_Prop_c3DKeyZ, (sal_Int32)aExtrusionFirstLightDirection.DirectionZ  );
    2386             :                                 }
    2387             :                             }
    2388           0 :                             else if ( rrProp.Name.equals( sExtrusionSecondLightDirection ) )
    2389             :                             {
    2390           0 :                                 drawing::Direction3D aExtrusionSecondLightPosition;
    2391           0 :                                 if ( rrProp.Value >>= aExtrusionSecondLightPosition )
    2392             :                                 {
    2393           0 :                                     AddOpt( DFF_Prop_c3DFillX, (sal_Int32)aExtrusionSecondLightPosition.DirectionX  );
    2394           0 :                                     AddOpt( DFF_Prop_c3DFillY, (sal_Int32)aExtrusionSecondLightPosition.DirectionY  );
    2395           0 :                                     AddOpt( DFF_Prop_c3DFillZ, (sal_Int32)aExtrusionSecondLightPosition.DirectionZ  );
    2396             :                                 }
    2397             :                             }
    2398           0 :                             else if ( rrProp.Name.equals( sExtrusionMetal ) )
    2399             :                             {
    2400           0 :                                 sal_Bool bExtrusionMetal = sal_Bool();
    2401           0 :                                 if ( rrProp.Value >>= bExtrusionMetal )
    2402             :                                 {
    2403           0 :                                     nLightFaceFlags |= 0x40000;
    2404           0 :                                     if ( bExtrusionMetal )
    2405           0 :                                         nLightFaceFlags |= 4;
    2406             :                                     else
    2407           0 :                                         nLightFaceFlags &=~4;
    2408             :                                 }
    2409             :                             }
    2410           0 :                             else if ( rrProp.Name.equals( sExtrusionShadeMode ) )
    2411             :                             {
    2412             :                                 drawing::ShadeMode eExtrusionShadeMode;
    2413           0 :                                 if ( rrProp.Value >>= eExtrusionShadeMode )
    2414             :                                 {
    2415             :                                     sal_uInt32 nRenderMode;
    2416           0 :                                     switch( eExtrusionShadeMode )
    2417             :                                     {
    2418             :                                         default:
    2419             :                                         case drawing::ShadeMode_FLAT :
    2420             :                                         case drawing::ShadeMode_PHONG :
    2421             :                                         case drawing::ShadeMode_SMOOTH :
    2422           0 :                                             nRenderMode = mso_FullRender;
    2423           0 :                                         break;
    2424             :                                         case drawing::ShadeMode_DRAFT :
    2425             :                                         {
    2426           0 :                                             nRenderMode = mso_Wireframe;
    2427             :                                         }
    2428           0 :                                         break;
    2429             :                                     }
    2430           0 :                                     AddOpt( DFF_Prop_c3DRenderMode, nRenderMode );
    2431             :                                 }
    2432             :                             }
    2433           0 :                             else if ( rrProp.Name.equals( sExtrusionRotateAngle ) )
    2434             :                             {
    2435           0 :                                 double fExtrusionAngleX = 0;
    2436           0 :                                 double fExtrusionAngleY = 0;
    2437           0 :                                 com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAnglePair;
    2438           0 :                                 if ( ( rrProp.Value >>= aRotateAnglePair ) && ( aRotateAnglePair.First.Value >>= fExtrusionAngleX ) && ( aRotateAnglePair.Second.Value >>= fExtrusionAngleY ) )
    2439             :                                 {
    2440           0 :                                     fExtrusionAngleX *= 65536;
    2441           0 :                                     fExtrusionAngleY *= 65536;
    2442           0 :                                     AddOpt( DFF_Prop_c3DXRotationAngle, (sal_Int32)fExtrusionAngleX );
    2443           0 :                                     AddOpt( DFF_Prop_c3DYRotationAngle, (sal_Int32)fExtrusionAngleY );
    2444           0 :                                 }
    2445             :                             }
    2446           0 :                             else if ( rrProp.Name.equals( sExtrusionRotationCenter ) )
    2447             :                             {
    2448           0 :                                 drawing::Direction3D aExtrusionRotationCenter;
    2449           0 :                                 if ( rrProp.Value >>= aExtrusionRotationCenter )
    2450             :                                 {
    2451           0 :                                     AddOpt( DFF_Prop_c3DRotationCenterX, (sal_Int32)( aExtrusionRotationCenter.DirectionX * 360.0 ) );
    2452           0 :                                     AddOpt( DFF_Prop_c3DRotationCenterY, (sal_Int32)( aExtrusionRotationCenter.DirectionY * 360.0 ) );
    2453           0 :                                     AddOpt( DFF_Prop_c3DRotationCenterZ, (sal_Int32)( aExtrusionRotationCenter.DirectionZ * 360.0 ) );
    2454           0 :                                     nFillHarshFlags &=~8; // don't use AutoRotationCenter;
    2455             :                                 }
    2456             :                             }
    2457           0 :                             else if ( rrProp.Name.equals( sExtrusionShininess ) )
    2458             :                             {
    2459           0 :                                 double fExtrusionShininess = 0;
    2460           0 :                                 if ( rrProp.Value >>= fExtrusionShininess )
    2461           0 :                                     AddOpt( DFF_Prop_c3DShininess, (sal_Int32)( fExtrusionShininess * 655.36 ) );
    2462             :                             }
    2463           0 :                             else if ( rrProp.Name.equals( sExtrusionSkew ) )
    2464             :                             {
    2465           0 :                                 double fSkewAmount = 0;
    2466           0 :                                 double fSkewAngle = 0;
    2467           0 :                                 com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair;
    2468           0 :                                 if ( ( rrProp.Value >>= aSkewParaPair ) && ( aSkewParaPair.First.Value >>= fSkewAmount ) && ( aSkewParaPair.Second.Value >>= fSkewAngle ) )
    2469             :                                 {
    2470           0 :                                     AddOpt( DFF_Prop_c3DSkewAmount, (sal_Int32)fSkewAmount );
    2471           0 :                                     AddOpt( DFF_Prop_c3DSkewAngle, (sal_Int32)( fSkewAngle * 65536 ) );
    2472           0 :                                 }
    2473             :                             }
    2474           0 :                             else if ( rrProp.Name.equals( sExtrusionSpecularity ) )
    2475             :                             {
    2476           0 :                                 double fExtrusionSpecularity = 0;
    2477           0 :                                 if ( rrProp.Value >>= fExtrusionSpecularity )
    2478           0 :                                     AddOpt( DFF_Prop_c3DSpecularAmt, (sal_Int32)( fExtrusionSpecularity * 1333 ) );
    2479             :                             }
    2480           0 :                             else if ( rrProp.Name.equals( sExtrusionProjectionMode ) )
    2481             :                             {
    2482             :                                 drawing::ProjectionMode eExtrusionProjectionMode;
    2483           0 :                                 if ( rrProp.Value >>= eExtrusionProjectionMode )
    2484             :                                 {
    2485           0 :                                     nFillHarshFlags |= 0x40000;
    2486           0 :                                     if ( eExtrusionProjectionMode == drawing::ProjectionMode_PARALLEL )
    2487           0 :                                         nFillHarshFlags |= 4;
    2488             :                                     else
    2489           0 :                                         nFillHarshFlags &=~4;
    2490             :                                 }
    2491             :                             }
    2492           0 :                             else if ( rrProp.Name.equals( sExtrusionViewPoint ) )
    2493             :                             {
    2494           0 :                                 drawing::Position3D aExtrusionViewPoint;
    2495           0 :                                 if ( rrProp.Value >>= aExtrusionViewPoint )
    2496             :                                 {
    2497           0 :                                     aExtrusionViewPoint.PositionX *= 360.0;
    2498           0 :                                     aExtrusionViewPoint.PositionY *= 360.0;
    2499           0 :                                     aExtrusionViewPoint.PositionZ *= 360.0;
    2500           0 :                                     AddOpt( DFF_Prop_c3DXViewpoint, (sal_Int32)aExtrusionViewPoint.PositionX  );
    2501           0 :                                     AddOpt( DFF_Prop_c3DYViewpoint, (sal_Int32)aExtrusionViewPoint.PositionY  );
    2502           0 :                                     AddOpt( DFF_Prop_c3DZViewpoint, (sal_Int32)aExtrusionViewPoint.PositionZ  );
    2503             :                                 }
    2504             :                             }
    2505           0 :                             else if ( rrProp.Name.equals( sExtrusionOrigin ) )
    2506             :                             {
    2507           0 :                                 double fExtrusionOriginX = 0;
    2508           0 :                                 double fExtrusionOriginY = 0;
    2509           0 :                                 com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginPair;
    2510           0 :                                 if ( ( rrProp.Value >>= aOriginPair ) && ( aOriginPair.First.Value >>= fExtrusionOriginX ) && ( aOriginPair.Second.Value >>= fExtrusionOriginY ) )
    2511             :                                 {
    2512           0 :                                     AddOpt( DFF_Prop_c3DOriginX, (sal_Int32)( fExtrusionOriginX * 65536 ) );
    2513           0 :                                     AddOpt( DFF_Prop_c3DOriginY, (sal_Int32)( fExtrusionOriginY * 65536 ) );
    2514           0 :                                 }
    2515             :                             }
    2516           0 :                             else if ( rrProp.Name.equals( sExtrusionColor ) )
    2517             :                             {
    2518           0 :                                 sal_Bool bExtrusionColor = sal_Bool();
    2519           0 :                                 if ( rrProp.Value >>= bExtrusionColor )
    2520             :                                 {
    2521           0 :                                     nLightFaceFlags |= 0x20000;
    2522           0 :                                     if ( bExtrusionColor )
    2523             :                                     {
    2524           0 :                                         nLightFaceFlags |= 2;
    2525           0 :                                         uno::Any aFillColor2;
    2526           0 :                                         if ( EscherPropertyValueHelper::GetPropertyValue( aFillColor2, aXPropSet,
    2527           0 :                                             String( RTL_CONSTASCII_USTRINGPARAM( "FillColor2" ) ), sal_True ) )
    2528             :                                         {
    2529           0 :                                             sal_uInt32 nFillColor = ImplGetColor( *((sal_uInt32*)aFillColor2.getValue()) );
    2530           0 :                                             AddOpt( DFF_Prop_c3DExtrusionColor, nFillColor );
    2531           0 :                                         }
    2532             :                                     }
    2533             :                                     else
    2534           0 :                                         nLightFaceFlags &=~2;
    2535             :                                 }
    2536             :                             }
    2537           0 :                         }
    2538           0 :                         if ( nLightFaceFlags != nLightFaceFlagsOrg )
    2539           0 :                             AddOpt( DFF_Prop_fc3DLightFace, nLightFaceFlags );
    2540           0 :                         if ( nFillHarshFlags != nFillHarshFlagsOrg )
    2541           0 :                             AddOpt( DFF_Prop_fc3DFillHarsh, nFillHarshFlags );
    2542           0 :                     }
    2543             :                 }
    2544           3 :                 else if ( rProp.Name.equals( sEquations ) )
    2545             :                 {
    2546           0 :                     if ( !bIsDefaultObject )
    2547             :                     {
    2548           0 :                         sal_uInt16 nElements = (sal_uInt16)aEquations.size();
    2549           0 :                         if ( nElements )
    2550             :                         {
    2551           0 :                             sal_uInt16 nElementSize = 8;
    2552           0 :                             sal_uInt32 nStreamSize = nElementSize * nElements + 6;
    2553           0 :                             SvMemoryStream aOut( nStreamSize );
    2554           0 :                             aOut << nElements
    2555           0 :                                 << nElements
    2556           0 :                                 << nElementSize;
    2557             : 
    2558           0 :                             std::vector< EnhancedCustomShapeEquation >::const_iterator aIter( aEquations.begin() );
    2559           0 :                             std::vector< EnhancedCustomShapeEquation >::const_iterator aEnd ( aEquations.end() );
    2560           0 :                             while( aIter != aEnd )
    2561             :                             {
    2562           0 :                                 aOut << (sal_uInt16)aIter->nOperation
    2563           0 :                                      << (sal_Int16)aIter->nPara[ 0 ]
    2564           0 :                                      << (sal_Int16)aIter->nPara[ 1 ]
    2565           0 :                                      << (sal_Int16)aIter->nPara[ 2 ];
    2566           0 :                                 ++aIter;
    2567             :                             }
    2568           0 :                             sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
    2569           0 :                             memcpy( pBuf, aOut.GetData(), nStreamSize );
    2570           0 :                             AddOpt( DFF_Prop_pFormulas, sal_True, nStreamSize - 6, pBuf, nStreamSize );
    2571             :                         }
    2572             :                         else
    2573             :                         {
    2574           0 :                             sal_uInt8* pBuf = new sal_uInt8[ 1 ];
    2575           0 :                             AddOpt( DFF_Prop_pFormulas, sal_True, 0, pBuf, 0 );
    2576             :                         }
    2577             :                     }
    2578             :                 }
    2579           3 :                 else if ( rProp.Name.equals( sPath ) )
    2580             :                 {
    2581           1 :                     uno::Sequence< beans::PropertyValue > aPathPropSeq;
    2582           1 :                     if ( rProp.Value >>= aPathPropSeq )
    2583             :                     {
    2584             :                         sal_uInt32 nPathFlags, nPathFlagsOrg;
    2585           1 :                         nPathFlagsOrg = nPathFlags = 0x39;
    2586           1 :                         if ( GetOpt( DFF_Prop_fFillOK, nPathFlags ) )
    2587           0 :                             nPathFlagsOrg = nPathFlags;
    2588             : 
    2589           1 :                         sal_Int32 r, nrCount = aPathPropSeq.getLength();
    2590           3 :                         for ( r = 0; r < nrCount; r++ )
    2591             :                         {
    2592           2 :                             const beans::PropertyValue& rrProp = aPathPropSeq[ r ];
    2593           2 :                             const rtl::OUString sPathExtrusionAllowed               ( "ExtrusionAllowed"  );
    2594           2 :                             const rtl::OUString sPathConcentricGradientFillAllowed  ( "ConcentricGradientFillAllowed"  );
    2595           2 :                             const rtl::OUString sPathTextPathAllowed                ( "TextPathAllowed"  );
    2596           2 :                             const rtl::OUString sPathCoordinates                    ( "Coordinates"  );
    2597           2 :                             const rtl::OUString sPathGluePoints                     ( "GluePoints"  );
    2598           2 :                             const rtl::OUString sPathGluePointType                  ( "GluePointType"  );
    2599           2 :                             const rtl::OUString sPathSegments                       ( "Segments"  );
    2600           2 :                             const rtl::OUString sPathStretchX                       ( "StretchX"  );
    2601           2 :                             const rtl::OUString sPathStretchY                       ( "StretchY"  );
    2602           2 :                             const rtl::OUString sPathTextFrames                     ( "TextFrames"  );
    2603             : 
    2604           2 :                             if ( rrProp.Name.equals( sPathExtrusionAllowed ) )
    2605             :                             {
    2606           0 :                                 sal_Bool bExtrusionAllowed = sal_Bool();
    2607           0 :                                 if ( rrProp.Value >>= bExtrusionAllowed )
    2608             :                                 {
    2609           0 :                                     nPathFlags |= 0x100000;
    2610           0 :                                     if ( bExtrusionAllowed )
    2611           0 :                                         nPathFlags |= 16;
    2612             :                                     else
    2613           0 :                                         nPathFlags &=~16;
    2614             :                                 }
    2615             :                             }
    2616           2 :                             else if ( rrProp.Name.equals( sPathConcentricGradientFillAllowed ) )
    2617             :                             {
    2618           0 :                                 sal_Bool bConcentricGradientFillAllowed = sal_Bool();
    2619           0 :                                 if ( rrProp.Value >>= bConcentricGradientFillAllowed )
    2620             :                                 {
    2621           0 :                                     nPathFlags |= 0x20000;
    2622           0 :                                     if ( bConcentricGradientFillAllowed )
    2623           0 :                                         nPathFlags |= 2;
    2624             :                                     else
    2625           0 :                                         nPathFlags &=~2;
    2626             :                                 }
    2627             :                             }
    2628           2 :                             else if ( rrProp.Name.equals( sPathTextPathAllowed ) )
    2629             :                             {
    2630           0 :                                 sal_Bool bTextPathAllowed = sal_Bool();
    2631           0 :                                 if ( rrProp.Value >>= bTextPathAllowed )
    2632             :                                 {
    2633           0 :                                     nPathFlags |= 0x40000;
    2634           0 :                                     if ( bTextPathAllowed )
    2635           0 :                                         nPathFlags |= 4;
    2636             :                                     else
    2637           0 :                                         nPathFlags &=~4;
    2638             :                                 }
    2639             :                             }
    2640           2 :                             else if ( rrProp.Name.equals( sPathCoordinates ) )
    2641             :                             {
    2642           1 :                                 if ( !bIsDefaultObject )
    2643             :                                 {
    2644           1 :                                     com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
    2645           1 :                                     if ( rrProp.Value >>= aCoordinates )
    2646             :                                     {
    2647             :                                         // creating the vertices
    2648           1 :                                         if ( (sal_uInt16)aCoordinates.getLength() )
    2649             :                                         {
    2650           1 :                                             sal_uInt16 j, nElements = (sal_uInt16)aCoordinates.getLength();
    2651           1 :                                             sal_uInt16 nElementSize = 8;
    2652           1 :                                             sal_uInt32 nStreamSize = nElementSize * nElements + 6;
    2653           1 :                                             SvMemoryStream aOut( nStreamSize );
    2654           1 :                                             aOut << nElements
    2655           2 :                                                 << nElements
    2656           2 :                                                 << nElementSize;
    2657          17 :                                             for( j = 0; j < nElements; j++ )
    2658             :                                             {
    2659          16 :                                                 sal_Int32 X = GetValueForEnhancedCustomShapeParameter( aCoordinates[ j ].First, aEquationOrder );
    2660          16 :                                                 sal_Int32 Y = GetValueForEnhancedCustomShapeParameter( aCoordinates[ j ].Second, aEquationOrder );
    2661          16 :                                                 aOut << X
    2662          16 :                                                     << Y;
    2663             :                                             }
    2664           1 :                                             sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
    2665           1 :                                             memcpy( pBuf, aOut.GetData(), nStreamSize );
    2666           1 :                                             AddOpt( DFF_Prop_pVertices, sal_True, nStreamSize - 6, pBuf, nStreamSize ); // -6
    2667             :                                         }
    2668             :                                         else
    2669             :                                         {
    2670           0 :                                             sal_uInt8* pBuf = new sal_uInt8[ 1 ];
    2671           0 :                                             AddOpt( DFF_Prop_pVertices, sal_True, 0, pBuf, 0 );
    2672             :                                         }
    2673           1 :                                     }
    2674             :                                 }
    2675             :                             }
    2676           1 :                             else if ( rrProp.Name.equals( sPathGluePoints ) )
    2677             :                             {
    2678           0 :                                 if ( !bIsDefaultObject )
    2679             :                                 {
    2680           0 :                                     com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> aGluePoints;
    2681           0 :                                     if ( rrProp.Value >>= aGluePoints )
    2682             :                                     {
    2683             :                                         // creating the vertices
    2684           0 :                                         sal_uInt16 nElements = (sal_uInt16)aGluePoints.getLength();
    2685           0 :                                         if ( nElements )
    2686             :                                         {
    2687           0 :                                             sal_uInt16 j, nElementSize = 8;
    2688           0 :                                             sal_uInt32 nStreamSize = nElementSize * nElements + 6;
    2689           0 :                                             SvMemoryStream aOut( nStreamSize );
    2690           0 :                                             aOut << nElements
    2691           0 :                                                 << nElements
    2692           0 :                                                 << nElementSize;
    2693           0 :                                             for( j = 0; j < nElements; j++ )
    2694             :                                             {
    2695           0 :                                                 sal_Int32 X = GetValueForEnhancedCustomShapeParameter( aGluePoints[ j ].First, aEquationOrder );
    2696           0 :                                                 sal_Int32 Y = GetValueForEnhancedCustomShapeParameter( aGluePoints[ j ].Second, aEquationOrder );
    2697           0 :                                                 aOut << X
    2698           0 :                                                     << Y;
    2699             :                                             }
    2700           0 :                                             sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
    2701           0 :                                             memcpy( pBuf, aOut.GetData(), nStreamSize );
    2702           0 :                                             AddOpt( DFF_Prop_connectorPoints, sal_True, nStreamSize - 6, pBuf, nStreamSize );   // -6
    2703             :                                         }
    2704             :                                         else
    2705             :                                         {
    2706           0 :                                             sal_uInt8* pBuf = new sal_uInt8[ 1 ];
    2707           0 :                                             AddOpt( DFF_Prop_connectorPoints, sal_True, 0, pBuf, 0 );
    2708             :                                         }
    2709           0 :                                     }
    2710             :                                 }
    2711             :                             }
    2712           1 :                             else if ( rrProp.Name.equals( sPathGluePointType ) )
    2713             :                             {
    2714           0 :                                 sal_Int16 nGluePointType = sal_Int16();
    2715           0 :                                 if ( rrProp.Value >>= nGluePointType )
    2716           0 :                                     AddOpt( DFF_Prop_connectorType, (sal_uInt16)nGluePointType );
    2717             :                             }
    2718           1 :                             else if ( rrProp.Name.equals( sPathSegments ) )
    2719             :                             {
    2720           1 :                                 if ( !bIsDefaultObject )
    2721             :                                 {
    2722           1 :                                     com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
    2723           1 :                                     if ( rrProp.Value >>= aSegments )
    2724             :                                     {
    2725             :                                         // creating seginfo
    2726           1 :                                         if ( (sal_uInt16)aSegments.getLength() )
    2727             :                                         {
    2728           1 :                                             sal_uInt16 j, nElements = (sal_uInt16)aSegments.getLength();
    2729           1 :                                             sal_uInt16 nElementSize = 2;
    2730           1 :                                             sal_uInt32 nStreamSize = nElementSize * nElements + 6;
    2731           1 :                                             SvMemoryStream aOut( nStreamSize );
    2732           1 :                                             aOut << nElements
    2733           2 :                                                 << nElements
    2734           2 :                                                 << nElementSize;
    2735           5 :                                             for ( j = 0; j < nElements; j++ )
    2736             :                                             {
    2737           4 :                                                 sal_uInt16 nVal = (sal_uInt16)aSegments[ j ].Count;
    2738           4 :                                                 switch( aSegments[ j ].Command )
    2739             :                                                 {
    2740             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::UNKNOWN :
    2741           1 :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO : break;
    2742             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
    2743             :                                                     {
    2744           1 :                                                         nVal = 0x4000;
    2745             :                                                     }
    2746           1 :                                                     break;
    2747             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
    2748             :                                                     {
    2749           0 :                                                         nVal |= 0x2000;
    2750             :                                                     }
    2751           0 :                                                     break;
    2752             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
    2753             :                                                     {
    2754           1 :                                                         nVal = 0x6001;
    2755             :                                                     }
    2756           1 :                                                     break;
    2757             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
    2758             :                                                     {
    2759           1 :                                                         nVal = 0x8000;
    2760             :                                                     }
    2761           1 :                                                     break;
    2762             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL :
    2763             :                                                     {
    2764           0 :                                                         nVal = 0xaa00;
    2765             :                                                     }
    2766           0 :                                                     break;
    2767             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE :
    2768             :                                                     {
    2769           0 :                                                         nVal = 0xab00;
    2770             :                                                     }
    2771           0 :                                                     break;
    2772             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
    2773             :                                                     {
    2774           0 :                                                         nVal *= 3;
    2775           0 :                                                         nVal |= 0xa100;
    2776             :                                                     }
    2777           0 :                                                     break;
    2778             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
    2779             :                                                     {
    2780           0 :                                                         nVal *= 3;
    2781           0 :                                                         nVal |= 0xa200;
    2782             :                                                     }
    2783           0 :                                                     break;
    2784             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
    2785             :                                                     {
    2786           0 :                                                         nVal <<= 2;
    2787           0 :                                                         nVal |= 0xa300;
    2788             :                                                     }
    2789           0 :                                                     break;
    2790             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC :
    2791             :                                                     {
    2792           0 :                                                         nVal <<= 2;
    2793           0 :                                                         nVal |= 0xa400;
    2794             :                                                     }
    2795           0 :                                                     break;
    2796             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
    2797             :                                                     {
    2798           0 :                                                         nVal <<= 2;
    2799           0 :                                                         nVal |= 0xa500;
    2800             :                                                     }
    2801           0 :                                                     break;
    2802             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
    2803             :                                                     {
    2804           0 :                                                         nVal <<= 2;
    2805           0 :                                                         nVal |= 0xa600;
    2806             :                                                     }
    2807           0 :                                                     break;
    2808             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
    2809             :                                                     {
    2810           0 :                                                         nVal |= 0xa700;
    2811             :                                                     }
    2812           0 :                                                     break;
    2813             :                                                     case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
    2814             :                                                     {
    2815           0 :                                                         nVal |= 0xa800;
    2816             :                                                     }
    2817           0 :                                                     break;
    2818             :                                                 }
    2819           4 :                                                 aOut << nVal;
    2820             :                                             }
    2821           1 :                                             sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
    2822           1 :                                             memcpy( pBuf, aOut.GetData(), nStreamSize );
    2823           1 :                                             AddOpt( DFF_Prop_pSegmentInfo, sal_False, nStreamSize - 6, pBuf, nStreamSize );
    2824             :                                         }
    2825             :                                         else
    2826             :                                         {
    2827           0 :                                             sal_uInt8* pBuf = new sal_uInt8[ 1 ];
    2828           0 :                                             AddOpt( DFF_Prop_pSegmentInfo, sal_True, 0, pBuf, 0 );
    2829             :                                         }
    2830           1 :                                     }
    2831             :                                 }
    2832             :                             }
    2833           0 :                             else if ( rrProp.Name.equals( sPathStretchX ) )
    2834             :                             {
    2835           0 :                                 if ( !bIsDefaultObject )
    2836             :                                 {
    2837           0 :                                     sal_Int32 nStretchX = 0;
    2838           0 :                                     if ( rrProp.Value >>= nStretchX )
    2839           0 :                                         AddOpt( DFF_Prop_stretchPointX, nStretchX );
    2840             :                                 }
    2841             :                             }
    2842           0 :                             else if ( rrProp.Name.equals( sPathStretchY ) )
    2843             :                             {
    2844           0 :                                 if ( !bIsDefaultObject )
    2845             :                                 {
    2846           0 :                                     sal_Int32 nStretchY = 0;
    2847           0 :                                     if ( rrProp.Value >>= nStretchY )
    2848           0 :                                         AddOpt( DFF_Prop_stretchPointY, nStretchY );
    2849             :                                 }
    2850             :                             }
    2851           0 :                             else if ( rrProp.Name.equals( sPathTextFrames ) )
    2852             :                             {
    2853           0 :                                 if ( !bIsDefaultObject )
    2854             :                                 {
    2855           0 :                                     com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aPathTextFrames;
    2856           0 :                                     if ( rrProp.Value >>= aPathTextFrames )
    2857             :                                     {
    2858           0 :                                         if ( (sal_uInt16)aPathTextFrames.getLength() )
    2859             :                                         {
    2860           0 :                                             sal_uInt16 j, nElements = (sal_uInt16)aPathTextFrames.getLength();
    2861           0 :                                             sal_uInt16 nElementSize = 16;
    2862           0 :                                             sal_uInt32 nStreamSize = nElementSize * nElements + 6;
    2863           0 :                                             SvMemoryStream aOut( nStreamSize );
    2864           0 :                                             aOut << nElements
    2865           0 :                                                 << nElements
    2866           0 :                                                 << nElementSize;
    2867           0 :                                             for ( j = 0; j < nElements; j++ )
    2868             :                                             {
    2869           0 :                                                 sal_Int32 nLeft = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].TopLeft.First, aEquationOrder );
    2870           0 :                                                 sal_Int32 nTop  = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].TopLeft.Second, aEquationOrder );
    2871           0 :                                                 sal_Int32 nRight = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].BottomRight.First, aEquationOrder );
    2872           0 :                                                 sal_Int32 nBottom = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].BottomRight.Second, aEquationOrder );
    2873             : 
    2874           0 :                                                 aOut << nLeft
    2875           0 :                                                     << nTop
    2876           0 :                                                     << nRight
    2877           0 :                                                     << nBottom;
    2878             :                                             }
    2879           0 :                                             sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
    2880           0 :                                             memcpy( pBuf, aOut.GetData(), nStreamSize );
    2881           0 :                                             AddOpt( DFF_Prop_textRectangles, sal_True, nStreamSize - 6, pBuf, nStreamSize );
    2882             :                                         }
    2883             :                                         else
    2884             :                                         {
    2885           0 :                                             sal_uInt8* pBuf = new sal_uInt8[ 1 ];
    2886           0 :                                             AddOpt( DFF_Prop_textRectangles, sal_True, 0, pBuf, 0 );
    2887             :                                         }
    2888           0 :                                     }
    2889             :                                 }
    2890             :                             }
    2891           2 :                         }
    2892           1 :                         if ( nPathFlags != nPathFlagsOrg )
    2893           0 :                             AddOpt( DFF_Prop_fFillOK, nPathFlags );
    2894           1 :                     }
    2895             :                 }
    2896           2 :                 else if ( rProp.Name.equals( sTextPath ) )
    2897             :                 {
    2898           0 :                     uno::Sequence< beans::PropertyValue > aTextPathPropSeq;
    2899           0 :                     if ( rProp.Value >>= aTextPathPropSeq )
    2900             :                     {
    2901             :                         sal_uInt32 nTextPathFlagsOrg, nTextPathFlags;
    2902           0 :                         nTextPathFlagsOrg = nTextPathFlags = 0xffff1000;        // default
    2903           0 :                         if ( GetOpt( DFF_Prop_gtextFStrikethrough, nTextPathFlags ) )
    2904           0 :                             nTextPathFlagsOrg = nTextPathFlags;
    2905             : 
    2906           0 :                         sal_Int32 r, nrCount = aTextPathPropSeq.getLength();
    2907           0 :                         for ( r = 0; r < nrCount; r++ )
    2908             :                         {
    2909           0 :                             const beans::PropertyValue& rrProp = aTextPathPropSeq[ r ];
    2910           0 :                             const rtl::OUString sTextPathMode       ( "TextPathMode"  );
    2911           0 :                             const rtl::OUString sTextPathScaleX     ( "ScaleX"  );
    2912           0 :                             const rtl::OUString sSameLetterHeights  ( "SameLetterHeights"  );
    2913             : 
    2914           0 :                             if ( rrProp.Name.equals( sTextPath ) )
    2915             :                             {
    2916           0 :                                 sal_Bool bTextPathOn = sal_Bool();
    2917           0 :                                 if ( rrProp.Value >>= bTextPathOn )
    2918             :                                 {
    2919           0 :                                     nTextPathFlags |= 0x40000000;
    2920           0 :                                     if ( bTextPathOn )
    2921             :                                     {
    2922           0 :                                         nTextPathFlags |= 0x4000;
    2923             : 
    2924           0 :                                         sal_uInt32 nPathFlags = 0x39;
    2925           0 :                                         GetOpt( DFF_Prop_fFillOK, nPathFlags ); // SJ: can be removed if we are supporting the TextPathAllowed property in XML
    2926           0 :                                         nPathFlags |= 0x40004;
    2927           0 :                                         AddOpt( DFF_Prop_fFillOK, nPathFlags );
    2928             :                                     }
    2929             :                                     else
    2930           0 :                                         nTextPathFlags &=~0x4000;
    2931             :                                 }
    2932             :                             }
    2933           0 :                             else if ( rrProp.Name.equals( sTextPathMode ) )
    2934             :                             {
    2935             :                                 com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode;
    2936           0 :                                 if ( rrProp.Value >>= eTextPathMode )
    2937             :                                 {
    2938           0 :                                     nTextPathFlags |= 0x05000000;
    2939           0 :                                     nTextPathFlags &=~0x500;    // TextPathMode_NORMAL
    2940           0 :                                     if ( eTextPathMode == com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH )
    2941           0 :                                         nTextPathFlags |= 0x100;
    2942           0 :                                     else if ( eTextPathMode == com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE )
    2943           0 :                                         nTextPathFlags |= 0x500;
    2944             :                                 }
    2945             :                             }
    2946           0 :                             else if ( rrProp.Name.equals( sTextPathScaleX ) )
    2947             :                             {
    2948           0 :                                 sal_Bool bTextPathScaleX = sal_Bool();
    2949           0 :                                 if ( rrProp.Value >>= bTextPathScaleX )
    2950             :                                 {
    2951           0 :                                     nTextPathFlags |= 0x00400000;
    2952           0 :                                     if ( bTextPathScaleX )
    2953           0 :                                         nTextPathFlags |= 0x40;
    2954             :                                     else
    2955           0 :                                         nTextPathFlags &=~0x40;
    2956             :                                 }
    2957             :                             }
    2958           0 :                             else if ( rrProp.Name.equals( sSameLetterHeights ) )
    2959             :                             {
    2960           0 :                                 sal_Bool bSameLetterHeights = sal_Bool();
    2961           0 :                                 if ( rrProp.Value >>= bSameLetterHeights )
    2962             :                                 {
    2963           0 :                                     nTextPathFlags |= 0x00800000;
    2964           0 :                                     if ( bSameLetterHeights )
    2965           0 :                                         nTextPathFlags |= 0x80;
    2966             :                                     else
    2967           0 :                                         nTextPathFlags &=~0x80;
    2968             :                                 }
    2969             :                             }
    2970           0 :                         }
    2971           0 :                         if ( nTextPathFlags & 0x4000 )      // Is FontWork ?
    2972             :                         {
    2973             :                             // FontWork Text
    2974           0 :                             rtl::OUString aText;
    2975           0 :                             uno::Reference< text::XSimpleText > xText( rXShape, uno::UNO_QUERY );
    2976           0 :                             if ( xText.is() )
    2977           0 :                                 aText = xText->getString();
    2978           0 :                             if ( aText.isEmpty() )
    2979           0 :                                 aText = ::rtl::OUString( "your text" );   // TODO: moving into a resource
    2980           0 :                             AddOpt( DFF_Prop_gtextUNICODE, aText );
    2981             : 
    2982             :                             // FontWork Font
    2983           0 :                             rtl::OUString aFontName;
    2984           0 :                             const rtl::OUString sCharFontName           ( "CharFontName"  );
    2985           0 :                             uno::Any aAny = aXPropSet->getPropertyValue( sCharFontName );
    2986           0 :                             aAny >>= aFontName;
    2987           0 :                             if ( aFontName.isEmpty() )
    2988           0 :                                 aFontName = ::rtl::OUString( "Arial Black" );
    2989           0 :                             AddOpt( DFF_Prop_gtextFont, aFontName );
    2990             : 
    2991           0 :                             if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharScaleWidth" ) ), sal_True ) )
    2992             :                             {
    2993           0 :                                 sal_Int16 nCharScaleWidth = 100;
    2994           0 :                                 if ( aAny >>= nCharScaleWidth )
    2995             :                                 {
    2996           0 :                                     if ( nCharScaleWidth != 100 )
    2997             :                                     {
    2998           0 :                                         sal_Int32 nVal = nCharScaleWidth * 655;
    2999           0 :                                         AddOpt( DFF_Prop_gtextSpacing, nVal );
    3000             :                                     }
    3001             :                                 }
    3002             :                             }
    3003           0 :                             if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharKerning" ) ), sal_True ) )
    3004             :                             {
    3005           0 :                                 sal_Int16 nCharKerning = sal_Int16();
    3006           0 :                                 if ( aAny >>= nCharKerning )
    3007             :                             {
    3008           0 :                                     nTextPathFlags |= 0x10000000;
    3009           0 :                                     if ( nCharKerning )
    3010           0 :                                         nTextPathFlags |= 0x1000;
    3011             :                                     else
    3012           0 :                                         nTextPathFlags &=~0x1000;
    3013             :                                 }
    3014             :                             }
    3015           0 :                             if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharPosture" ) ), sal_True ) )
    3016             :                             {
    3017             :                                 awt::FontSlant eFontSlant;
    3018           0 :                                 if ( aAny >>= eFontSlant )
    3019             :                                 {
    3020           0 :                                     nTextPathFlags |= 0x100010;
    3021           0 :                                     if ( eFontSlant != awt::FontSlant_NONE )
    3022           0 :                                         nTextPathFlags |= 0x10;
    3023             :                                     else
    3024           0 :                                         nTextPathFlags &=~0x10;
    3025             :                                 }
    3026             :                             }
    3027           0 :                             if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) ), sal_True ) )
    3028             :                             {
    3029           0 :                                 float fFontWidth = 0;
    3030           0 :                                 if ( aAny >>= fFontWidth )
    3031             :                                 {
    3032           0 :                                     nTextPathFlags |= 0x200020;
    3033           0 :                                     if ( fFontWidth > awt::FontWeight::NORMAL )
    3034           0 :                                         nTextPathFlags |= 0x20;
    3035             :                                     else
    3036           0 :                                         nTextPathFlags &=~0x20;
    3037             :                                 }
    3038           0 :                             }
    3039             :                         }
    3040           0 :                         if ( nTextPathFlags != nTextPathFlagsOrg )
    3041           0 :                             AddOpt( DFF_Prop_gtextFStrikethrough, nTextPathFlags );
    3042           0 :                     }
    3043             :                 }
    3044           2 :                 else if ( rProp.Name.equals( sHandles ) )
    3045             :                 {
    3046           0 :                     if ( !bIsDefaultObject )
    3047             :                     {
    3048           0 :                         bPredefinedHandlesUsed = sal_False;
    3049           0 :                         if ( rProp.Value >>= aHandlesPropSeq )
    3050             :                         {
    3051           0 :                             sal_uInt16 nElements = (sal_uInt16)aHandlesPropSeq.getLength();
    3052           0 :                             if ( nElements )
    3053             :                             {
    3054           0 :                                 sal_uInt16 k, j, nElementSize = 36;
    3055           0 :                                 sal_uInt32 nStreamSize = nElementSize * nElements + 6;
    3056           0 :                                 SvMemoryStream aOut( nStreamSize );
    3057           0 :                                 aOut << nElements
    3058           0 :                                     << nElements
    3059           0 :                                     << nElementSize;
    3060             : 
    3061           0 :                                 for ( k = 0; k < nElements; k++ )
    3062             :                                 {
    3063           0 :                                     sal_uInt32 nFlags = 0;
    3064           0 :                                     sal_Int32 nXPosition = 0;
    3065           0 :                                     sal_Int32 nYPosition = 0;
    3066           0 :                                     sal_Int32 nXMap = 0;
    3067           0 :                                     sal_Int32 nYMap = 0;
    3068           0 :                                     sal_Int32 nXRangeMin = 0x80000000;
    3069           0 :                                     sal_Int32 nXRangeMax = 0x7fffffff;
    3070           0 :                                     sal_Int32 nYRangeMin = 0x80000000;
    3071           0 :                                     sal_Int32 nYRangeMax = 0x7fffffff;
    3072             : 
    3073           0 :                                     const uno::Sequence< beans::PropertyValue >& rPropSeq = aHandlesPropSeq[ k ];
    3074           0 :                                     for ( j = 0; j < rPropSeq.getLength(); j++ )
    3075             :                                     {
    3076           0 :                                         const beans::PropertyValue& rPropVal = rPropSeq[ j ];
    3077             : 
    3078           0 :                                         const rtl::OUString sPosition           ( "Position"  );
    3079           0 :                                         const rtl::OUString sMirroredX          ( "MirroredX"  );
    3080           0 :                                         const rtl::OUString sMirroredY          ( "MirroredY"  );
    3081           0 :                                         const rtl::OUString sSwitched           ( "Switched"  );
    3082           0 :                                         const rtl::OUString sPolar              ( "Polar"  );
    3083           0 :                                         const rtl::OUString sRadiusRangeMinimum ( "RadiusRangeMinimum"  );
    3084           0 :                                         const rtl::OUString sRadiusRangeMaximum ( "RadiusRangeMaximum"  );
    3085           0 :                                         const rtl::OUString sRangeXMinimum      ( "RangeXMinimum"  );
    3086           0 :                                         const rtl::OUString sRangeXMaximum      ( "RangeXMaximum"  );
    3087           0 :                                         const rtl::OUString sRangeYMinimum      ( "RangeYMinimum"  );
    3088           0 :                                         const rtl::OUString sRangeYMaximum      ( "RangeYMaximum"  );
    3089             : 
    3090           0 :                                         if ( rPropVal.Name.equals( sPosition ) )
    3091             :                                         {
    3092           0 :                                             com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
    3093           0 :                                             if ( rPropVal.Value >>= aPosition )
    3094             :                                             {
    3095           0 :                                                 GetValueForEnhancedCustomShapeHandleParameter( nXPosition, aPosition.First );
    3096           0 :                                                 GetValueForEnhancedCustomShapeHandleParameter( nYPosition, aPosition.Second );
    3097           0 :                                             }
    3098             :                                         }
    3099           0 :                                         else if ( rPropVal.Name.equals( sMirroredX ) )
    3100             :                                         {
    3101           0 :                                             sal_Bool bMirroredX = sal_Bool();
    3102           0 :                                             if ( rPropVal.Value >>= bMirroredX )
    3103             :                                             {
    3104           0 :                                                 if ( bMirroredX )
    3105           0 :                                                     nFlags |= 1;
    3106             :                                             }
    3107             :                                         }
    3108           0 :                                         else if ( rPropVal.Name.equals( sMirroredY ) )
    3109             :                                         {
    3110           0 :                                             sal_Bool bMirroredY = sal_Bool();
    3111           0 :                                             if ( rPropVal.Value >>= bMirroredY )
    3112             :                                             {
    3113           0 :                                                 if ( bMirroredY )
    3114           0 :                                                     nFlags |= 2;
    3115             :                                             }
    3116             :                                         }
    3117           0 :                                         else if ( rPropVal.Name.equals( sSwitched ) )
    3118             :                                         {
    3119           0 :                                             sal_Bool bSwitched = sal_Bool();
    3120           0 :                                             if ( rPropVal.Value >>= bSwitched )
    3121             :                                             {
    3122           0 :                                                 if ( bSwitched )
    3123           0 :                                                     nFlags |= 4;
    3124             :                                             }
    3125             :                                         }
    3126           0 :                                         else if ( rPropVal.Name.equals( sPolar ) )
    3127             :                                         {
    3128           0 :                                             com::sun::star::drawing::EnhancedCustomShapeParameterPair aPolar;
    3129           0 :                                             if ( rPropVal.Value >>= aPolar )
    3130             :                                             {
    3131           0 :                                                 if ( GetValueForEnhancedCustomShapeHandleParameter( nXMap, aPolar.First ) )
    3132           0 :                                                     nFlags |= 0x800;
    3133           0 :                                                 if ( GetValueForEnhancedCustomShapeHandleParameter( nYMap, aPolar.Second ) )
    3134           0 :                                                     nFlags |= 0x1000;
    3135           0 :                                                 nFlags |= 8;
    3136           0 :                                             }
    3137             :                                         }
    3138           0 :                                         else if ( rPropVal.Name.equals( sRadiusRangeMinimum ) )
    3139             :                                         {
    3140           0 :                                             nYRangeMin = (sal_Int32)0xff4c0000; // the range of angles seems to be a not
    3141           0 :                                             nYRangeMax = (sal_Int32)0x00b40000; // used feature, so we are defaulting this
    3142             : 
    3143           0 :                                             com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
    3144           0 :                                             if ( rPropVal.Value >>= aRadiusRangeMinimum )
    3145             :                                             {
    3146           0 :                                                 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMin, aRadiusRangeMinimum ) )
    3147           0 :                                                     nFlags |= 0x80;
    3148           0 :                                                 nFlags |= 0x2000;
    3149           0 :                                             }
    3150             :                                         }
    3151           0 :                                         else if ( rPropVal.Name.equals( sRadiusRangeMaximum ) )
    3152             :                                         {
    3153           0 :                                             nYRangeMin = (sal_Int32)0xff4c0000; // the range of angles seems to be a not
    3154           0 :                                             nYRangeMax = (sal_Int32)0x00b40000; // used feature, so we are defaulting this
    3155             : 
    3156           0 :                                             com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
    3157           0 :                                             if ( rPropVal.Value >>= aRadiusRangeMaximum )
    3158             :                                             {
    3159           0 :                                                 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMax, aRadiusRangeMaximum ) )
    3160           0 :                                                     nFlags |= 0x100;
    3161           0 :                                                 nFlags |= 0x2000;
    3162           0 :                                             }
    3163             :                                         }
    3164           0 :                                         else if ( rPropVal.Name.equals( sRangeXMinimum ) )
    3165             :                                         {
    3166           0 :                                             com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMinimum;
    3167           0 :                                             if ( rPropVal.Value >>= aXRangeMinimum )
    3168             :                                             {
    3169           0 :                                                 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMin, aXRangeMinimum ) )
    3170           0 :                                                     nFlags |= 0x80;
    3171           0 :                                                 nFlags |= 0x20;
    3172           0 :                                             }
    3173             :                                         }
    3174           0 :                                         else if ( rPropVal.Name.equals( sRangeXMaximum ) )
    3175             :                                         {
    3176           0 :                                             com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMaximum;
    3177           0 :                                             if ( rPropVal.Value >>= aXRangeMaximum )
    3178             :                                             {
    3179           0 :                                                 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMax, aXRangeMaximum ) )
    3180           0 :                                                     nFlags |= 0x100;
    3181           0 :                                                 nFlags |= 0x20;
    3182           0 :                                             }
    3183             :                                         }
    3184           0 :                                         else if ( rPropVal.Name.equals( sRangeYMinimum ) )
    3185             :                                         {
    3186           0 :                                             com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMinimum;
    3187           0 :                                             if ( rPropVal.Value >>= aYRangeMinimum )
    3188             :                                             {
    3189           0 :                                                 if ( GetValueForEnhancedCustomShapeHandleParameter( nYRangeMin, aYRangeMinimum ) )
    3190           0 :                                                     nFlags |= 0x200;
    3191           0 :                                                 nFlags |= 0x20;
    3192           0 :                                             }
    3193             :                                         }
    3194           0 :                                         else if ( rPropVal.Name.equals( sRangeYMaximum ) )
    3195             :                                         {
    3196           0 :                                             com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMaximum;
    3197           0 :                                             if ( rPropVal.Value >>= aYRangeMaximum )
    3198             :                                             {
    3199           0 :                                                 if ( GetValueForEnhancedCustomShapeHandleParameter( nYRangeMax, aYRangeMaximum ) )
    3200           0 :                                                     nFlags |= 0x400;
    3201           0 :                                                 nFlags |= 0x20;
    3202           0 :                                             }
    3203             :                                         }
    3204           0 :                                     }
    3205           0 :                                     aOut << nFlags
    3206           0 :                                         << nXPosition
    3207           0 :                                         << nYPosition
    3208           0 :                                         << nXMap
    3209           0 :                                         << nYMap
    3210           0 :                                         << nXRangeMin
    3211           0 :                                         << nXRangeMax
    3212           0 :                                         << nYRangeMin
    3213           0 :                                         << nYRangeMax;
    3214             : 
    3215           0 :                                     if ( nFlags & 8 )
    3216           0 :                                         nAdjustmentsWhichNeedsToBeConverted |= ( 1 << ( nYPosition - 0x100 ) );
    3217             :                                 }
    3218           0 :                                 sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
    3219           0 :                                 memcpy( pBuf, aOut.GetData(), nStreamSize );
    3220           0 :                                 AddOpt( DFF_Prop_Handles, sal_True, nStreamSize - 6, pBuf, nStreamSize );
    3221             :                             }
    3222             :                             else
    3223             :                             {
    3224           0 :                                 sal_uInt8* pBuf = new sal_uInt8[ 1 ];
    3225           0 :                                 AddOpt( DFF_Prop_Handles, sal_True, 0, pBuf, 0 );
    3226             :                             }
    3227             :                         }
    3228             :                     }
    3229             :                 }
    3230           2 :                 else if ( rProp.Name.equals( sAdjustmentValues ) )
    3231             :                 {
    3232             :                     // it is required, that the information which handle is polar has already be read,
    3233             :                     // so we are able to change the polar value to a fixed float
    3234           1 :                     pAdjustmentValuesProp = &rProp;
    3235             :                 }
    3236             :             }
    3237           1 :             if ( pAdjustmentValuesProp )
    3238             :             {
    3239           1 :                 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq;
    3240           1 :                 if ( pAdjustmentValuesProp->Value >>= aAdjustmentSeq )
    3241             :                 {
    3242           1 :                     if ( bPredefinedHandlesUsed )
    3243           1 :                         LookForPolarHandles( eShapeType, nAdjustmentsWhichNeedsToBeConverted );
    3244             : 
    3245           1 :                     sal_Int32 k, nValue = 0, nAdjustmentValues = aAdjustmentSeq.getLength();
    3246           1 :                     for ( k = 0; k < nAdjustmentValues; k++ )
    3247           0 :                         if( GetAdjustmentValue( aAdjustmentSeq[ k ], k, nAdjustmentsWhichNeedsToBeConverted, nValue ) )
    3248           0 :                             AddOpt( (sal_uInt16)( DFF_Prop_adjustValue + k ), (sal_uInt32)nValue );
    3249           1 :                 }
    3250           1 :             }
    3251           1 :         }
    3252           1 :     }
    3253           1 : }
    3254             : 
    3255           1 : MSO_SPT EscherPropertyContainer::GetCustomShapeType( const uno::Reference< drawing::XShape > & rXShape, sal_uInt32& nMirrorFlags, rtl::OUString& rShapeType )
    3256             : {
    3257           1 :     MSO_SPT eShapeType = mso_sptNil;
    3258           1 :     nMirrorFlags = 0;
    3259           1 :     uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY );
    3260           1 :     if ( aXPropSet.is() )
    3261             :     {
    3262             :         try
    3263             :         {
    3264           1 :             const OUString  sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM ( "CustomShapeGeometry" ) );
    3265           1 :             uno::Any aGeoPropSet = aXPropSet->getPropertyValue( sCustomShapeGeometry );
    3266           1 :             uno::Sequence< beans::PropertyValue > aGeoPropSeq;
    3267           1 :             if ( aGeoPropSet >>= aGeoPropSeq )
    3268             :             {
    3269           1 :                 sal_Int32 i, nCount = aGeoPropSeq.getLength();
    3270           5 :                 for ( i = 0; i < nCount; i++ )
    3271             :                 {
    3272           4 :                     const beans::PropertyValue& rProp = aGeoPropSeq[ i ];
    3273           4 :                     if ( rProp.Name == "Type" )
    3274             :                     {
    3275           1 :                         if ( rProp.Value >>= rShapeType )
    3276           1 :                             eShapeType = EnhancedCustomShapeTypeNames::Get( rShapeType );
    3277             :                     }
    3278           3 :                     else if ( rProp.Name == "MirroredX" )
    3279             :                     {
    3280           0 :                         sal_Bool bMirroredX = sal_Bool();
    3281           0 :                         if ( ( rProp.Value >>= bMirroredX ) && bMirroredX )
    3282           0 :                             nMirrorFlags  |= SHAPEFLAG_FLIPH;
    3283             :                     }
    3284           3 :                     else if ( rProp.Name == "MirroredY" )
    3285             :                     {
    3286           0 :                         sal_Bool bMirroredY = sal_Bool();
    3287           0 :                         if ( ( rProp.Value >>= bMirroredY ) && bMirroredY )
    3288           0 :                             nMirrorFlags  |= SHAPEFLAG_FLIPV;
    3289             :                     }
    3290             :                 }
    3291           1 :             }
    3292             :         }
    3293           0 :         catch( const ::com::sun::star::uno::Exception& )
    3294             :         {
    3295             :         }
    3296             :     }
    3297           1 :     return eShapeType;
    3298             : }
    3299             : 
    3300           0 : MSO_SPT EscherPropertyContainer::GetCustomShapeType( const uno::Reference< drawing::XShape > & rXShape, sal_uInt32& nMirrorFlags )
    3301             : {
    3302           0 :     rtl::OUString aShapeType;
    3303           0 :     return GetCustomShapeType( rXShape, nMirrorFlags, aShapeType );
    3304             : }
    3305             : 
    3306          54 : EscherPersistTable::EscherPersistTable()
    3307             : {
    3308          54 : }
    3309             : 
    3310         108 : EscherPersistTable::~EscherPersistTable()
    3311             : {
    3312          59 :     for( size_t i = 0, n = maPersistTable.size(); i < n; ++i ) {
    3313           5 :         delete maPersistTable[ i ];
    3314             :     }
    3315          54 : }
    3316             : 
    3317           0 : sal_Bool EscherPersistTable::PtIsID( sal_uInt32 nID )
    3318             : {
    3319           0 :     for( size_t i = 0, n = maPersistTable.size(); i < n; ++i ) {
    3320           0 :         EscherPersistEntry* pPtr = maPersistTable[ i ];
    3321           0 :         if ( pPtr->mnID == nID ) {
    3322           0 :             return sal_True;
    3323             :         }
    3324             :     }
    3325           0 :     return sal_False;
    3326             : }
    3327             : 
    3328           7 : void EscherPersistTable::PtInsert( sal_uInt32 nID, sal_uInt32 nOfs )
    3329             : {
    3330           7 :     maPersistTable.push_back( new EscherPersistEntry( nID, nOfs ) );
    3331           7 : }
    3332             : 
    3333           3 : sal_uInt32 EscherPersistTable::PtDelete( sal_uInt32 nID )
    3334             : {
    3335           3 :     EscherPersistTable_impl::iterator it = maPersistTable.begin();
    3336          15 :     for( ; it != maPersistTable.end() ; ++it )
    3337             :     {
    3338          14 :         if ( (*it)->mnID == nID ) {
    3339           2 :             delete *it;
    3340           2 :             maPersistTable.erase( it );
    3341           2 :             break;
    3342             :         }
    3343             :     }
    3344           3 :     return 0;
    3345             : }
    3346             : 
    3347           4 : sal_uInt32 EscherPersistTable::PtGetOffsetByID( sal_uInt32 nID )
    3348             : {
    3349          17 :     for( size_t i = 0, n = maPersistTable.size(); i < n; ++i ) {
    3350          17 :         EscherPersistEntry* pPtr = maPersistTable[ i ];
    3351          17 :         if ( pPtr->mnID == nID ) {
    3352           4 :             return pPtr->mnOffset;
    3353             :         }
    3354             :     }
    3355           0 :     return 0;
    3356             : };
    3357             : 
    3358           2 : sal_uInt32 EscherPersistTable::PtReplace( sal_uInt32 nID, sal_uInt32 nOfs )
    3359             : {
    3360           6 :     for( size_t i = 0, n = maPersistTable.size(); i < n; ++i ) {
    3361           6 :         EscherPersistEntry* pPtr = maPersistTable[ i ];
    3362           6 :         if ( pPtr->mnID == nID ) {
    3363           2 :             sal_uInt32 nRetValue = pPtr->mnOffset;
    3364           2 :             pPtr->mnOffset = nOfs;
    3365           2 :             return nRetValue;
    3366             :         }
    3367             :     }
    3368           0 :     return 0;
    3369             : }
    3370             : 
    3371           4 : sal_uInt32 EscherPersistTable::PtReplaceOrInsert( sal_uInt32 nID, sal_uInt32 nOfs )
    3372             : {
    3373          20 :     for( size_t i = 0, n = maPersistTable.size(); i < n; ++i ) {
    3374          16 :         EscherPersistEntry* pPtr = maPersistTable[ i ];
    3375          16 :         if ( pPtr->mnID == nID ) {
    3376           0 :             sal_uInt32 nRetValue = pPtr->mnOffset;
    3377           0 :             pPtr->mnOffset = nOfs;
    3378           0 :             return nRetValue;
    3379             :         }
    3380             :     }
    3381           4 :     PtInsert( nID, nOfs );
    3382           4 :     return 0;
    3383             : }
    3384             : 
    3385          14 : sal_Bool EscherPropertyValueHelper::GetPropertyValue(
    3386             :     ::com::sun::star::uno::Any& rAny,
    3387             :     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
    3388             :     const String& rString,
    3389             :     sal_Bool bTestPropertyAvailability
    3390             : ) {
    3391          14 :     sal_Bool bRetValue = sal_True;
    3392          14 :     if ( bTestPropertyAvailability )
    3393             :     {
    3394           6 :         bRetValue = sal_False;
    3395             :         try
    3396             :         {
    3397             :             ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
    3398           6 :                 aXPropSetInfo( rXPropSet->getPropertySetInfo() );
    3399           6 :             if ( aXPropSetInfo.is() )
    3400           6 :                 bRetValue = aXPropSetInfo->hasPropertyByName( rString );
    3401             :         }
    3402           0 :         catch( const ::com::sun::star::uno::Exception& )
    3403             :         {
    3404           0 :             bRetValue = sal_False;
    3405             :         }
    3406             :     }
    3407          14 :     if ( bRetValue )
    3408             :     {
    3409             :         try
    3410             :         {
    3411          13 :             rAny = rXPropSet->getPropertyValue( rString );
    3412          13 :             if ( !rAny.hasValue() )
    3413           0 :                 bRetValue = sal_False;
    3414             :         }
    3415           0 :         catch( const ::com::sun::star::uno::Exception& )
    3416             :         {
    3417           0 :             bRetValue = sal_False;
    3418             :         }
    3419             :     }
    3420          14 :     return bRetValue;
    3421             : }
    3422             : 
    3423           1 : ::com::sun::star::beans::PropertyState EscherPropertyValueHelper::GetPropertyState(
    3424             :     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
    3425             :         const String& rPropertyName )
    3426             : {
    3427           1 :     ::com::sun::star::beans::PropertyState eRetValue = ::com::sun::star::beans::PropertyState_AMBIGUOUS_VALUE;
    3428             :     try
    3429             :     {
    3430             :         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState > aXPropState
    3431           1 :                 ( rXPropSet, ::com::sun::star::uno::UNO_QUERY );
    3432           1 :         if ( aXPropState.is() )
    3433           1 :             eRetValue = aXPropState->getPropertyState( rPropertyName );
    3434             :     }
    3435           0 :     catch( const ::com::sun::star::uno::Exception& )
    3436             :     {
    3437             :     }
    3438           1 :     return eRetValue;
    3439             : }
    3440             : 
    3441           0 : EscherBlibEntry::EscherBlibEntry( sal_uInt32 nPictureOffset, const GraphicObject& rObject, const rtl::OString& rId,
    3442             :                                         const GraphicAttr* pGraphicAttr ) :
    3443             :     mnPictureOffset ( nPictureOffset ),
    3444             :     mnRefCount      ( 1 ),
    3445             :     mnSizeExtra     ( 0 ),
    3446           0 :     maPrefSize      ( rObject.GetPrefSize() ),
    3447           0 :     maPrefMapMode   ( rObject.GetPrefMapMode() ),
    3448           0 :     mbIsEmpty       ( sal_True )
    3449             : {
    3450           0 :     mbIsNativeGraphicPossible = ( pGraphicAttr == NULL );
    3451           0 :     meBlibType = UNKNOWN;
    3452           0 :     mnSize = 0;
    3453             : 
    3454           0 :     sal_uInt32      nLen = static_cast<sal_uInt32>(rId.getLength());
    3455           0 :     const sal_Char* pData = rId.getStr();
    3456           0 :     GraphicType     eType( rObject.GetType() );
    3457           0 :     if ( nLen && pData && ( eType != GRAPHIC_NONE ) )
    3458             :     {
    3459           0 :         mnIdentifier[ 0 ] = rtl_crc32( 0,pData, nLen );
    3460           0 :         mnIdentifier[ 1 ] = 0;
    3461             : 
    3462           0 :         if ( pGraphicAttr )
    3463             :         {
    3464           0 :             if ( pGraphicAttr->IsSpecialDrawMode()
    3465           0 :                     || pGraphicAttr->IsMirrored()
    3466           0 :                          || pGraphicAttr->IsCropped()
    3467           0 :                             || pGraphicAttr->IsRotated()
    3468           0 :                                 || pGraphicAttr->IsTransparent()
    3469           0 :                                     || pGraphicAttr->IsAdjusted() )
    3470             :             {
    3471           0 :                 SvMemoryStream aSt( sizeof( GraphicAttr ) );
    3472           0 :                 aSt << static_cast<sal_uInt16>(pGraphicAttr->GetDrawMode())
    3473           0 :                     << static_cast<sal_uInt32>(pGraphicAttr->GetMirrorFlags())
    3474           0 :                     << static_cast<sal_Int32>(pGraphicAttr->GetLeftCrop())
    3475           0 :                     << static_cast<sal_Int32>(pGraphicAttr->GetTopCrop())
    3476           0 :                     << static_cast<sal_Int32>(pGraphicAttr->GetRightCrop())
    3477           0 :                     << static_cast<sal_Int32>(pGraphicAttr->GetBottomCrop())
    3478           0 :                     << pGraphicAttr->GetRotation()
    3479           0 :                     << pGraphicAttr->GetLuminance()
    3480           0 :                     << pGraphicAttr->GetContrast()
    3481           0 :                     << pGraphicAttr->GetChannelR()
    3482           0 :                     << pGraphicAttr->GetChannelG()
    3483           0 :                     << pGraphicAttr->GetChannelB()
    3484           0 :                     << pGraphicAttr->GetGamma()
    3485           0 :                     << (sal_Bool)( pGraphicAttr->IsInvert() == sal_True )
    3486           0 :                     << pGraphicAttr->GetTransparency();
    3487           0 :                 mnIdentifier[ 1 ] = rtl_crc32( 0, aSt.GetData(), aSt.Tell() );
    3488             :             }
    3489             :             else
    3490           0 :                 mbIsNativeGraphicPossible = sal_True;
    3491             :         }
    3492             :         sal_uInt32 i, nTmp, n1, n2;
    3493           0 :         n1 = n2 = 0;
    3494           0 :         for ( i = 0; i < nLen; i++ )
    3495             :         {
    3496           0 :             nTmp = n2 >> 28;    // rotating 4 bit
    3497           0 :             n2 <<= 4;
    3498           0 :             n2 |= n1 >> 28;
    3499           0 :             n1 <<= 4;
    3500           0 :             n1 |= nTmp;
    3501           0 :             n1 ^= *pData++ - '0';
    3502             :         }
    3503           0 :         mnIdentifier[ 2 ] = n1;
    3504           0 :         mnIdentifier[ 3 ] = n2;
    3505           0 :         mbIsEmpty = sal_False;
    3506             :     }
    3507           0 : };
    3508             : 
    3509           0 : void EscherBlibEntry::WriteBlibEntry( SvStream& rSt, sal_Bool bWritePictureOffset, sal_uInt32 nResize )
    3510             : {
    3511           0 :     sal_uInt32  nPictureOffset = ( bWritePictureOffset ) ? mnPictureOffset : 0;
    3512             : 
    3513           0 :     rSt << (sal_uInt32)( ( ESCHER_BSE << 16 ) | ( ( (sal_uInt16)meBlibType << 4 ) | 2 ) )
    3514           0 :         << (sal_uInt32)( 36 + nResize )
    3515           0 :         << (sal_uInt8)meBlibType;
    3516             : 
    3517           0 :     switch ( meBlibType )
    3518             :     {
    3519             :         case EMF :
    3520             :         case WMF :  // converting EMF/WMF on OS2 to Pict
    3521           0 :             rSt << (sal_uInt8)PICT;
    3522           0 :         break;
    3523             :         default:
    3524           0 :             rSt << (sal_uInt8)meBlibType;
    3525             :     };
    3526             : 
    3527           0 :     rSt.Write( &mnIdentifier[ 0 ], 16 );
    3528           0 :     rSt << (sal_uInt16)0
    3529           0 :         << (sal_uInt32)( mnSize + mnSizeExtra )
    3530           0 :         << mnRefCount
    3531           0 :         << nPictureOffset
    3532           0 :         << (sal_uInt32)0;
    3533           0 : }
    3534             : 
    3535           0 : EscherBlibEntry::~EscherBlibEntry()
    3536             : {
    3537           0 : };
    3538             : 
    3539           0 : sal_Bool EscherBlibEntry::operator==( const EscherBlibEntry& rEscherBlibEntry ) const
    3540             : {
    3541           0 :     for ( int i = 0; i < 3; i++ )
    3542             :     {
    3543           0 :         if ( mnIdentifier[ i ] != rEscherBlibEntry.mnIdentifier[ i ] )
    3544           0 :             return sal_False;
    3545             :     }
    3546           0 :     return sal_True;
    3547             : }
    3548             : 
    3549          54 : EscherGraphicProvider::EscherGraphicProvider( sal_uInt32 nFlags ) :
    3550             :     mnFlags         ( nFlags ),
    3551             :     mpBlibEntrys    ( NULL ),
    3552             :     mnBlibBufSize   ( 0 ),
    3553          54 :     mnBlibEntrys    ( 0 )
    3554             : {
    3555          54 : }
    3556             : 
    3557         108 : EscherGraphicProvider::~EscherGraphicProvider()
    3558             : {
    3559          54 :     for ( sal_uInt32 i = 0; i < mnBlibEntrys; delete mpBlibEntrys[ i++ ] ) ;
    3560          54 :     delete[] mpBlibEntrys;
    3561          54 : }
    3562             : 
    3563           0 : void EscherGraphicProvider::SetNewBlipStreamOffset( sal_Int32 nOffset )
    3564             : {
    3565           0 :     for( sal_uInt32 i = 0; i < mnBlibEntrys; i++ )
    3566             :     {
    3567           0 :         EscherBlibEntry* pBlibEntry = mpBlibEntrys[ i ];
    3568           0 :         pBlibEntry->mnPictureOffset += nOffset;
    3569             :     }
    3570           0 : }
    3571             : 
    3572           0 : sal_uInt32 EscherGraphicProvider::ImplInsertBlib( EscherBlibEntry* p_EscherBlibEntry )
    3573             : {
    3574           0 :     if ( mnBlibBufSize == mnBlibEntrys )
    3575             :     {
    3576           0 :         mnBlibBufSize += 64;
    3577           0 :         EscherBlibEntry** pTemp = new EscherBlibEntry*[ mnBlibBufSize ];
    3578           0 :         for ( sal_uInt32 i = 0; i < mnBlibEntrys; i++ )
    3579             :         {
    3580           0 :             pTemp[ i ] = mpBlibEntrys[ i ];
    3581             :         }
    3582           0 :         delete[] mpBlibEntrys;
    3583           0 :         mpBlibEntrys = pTemp;
    3584             :     }
    3585           0 :     mpBlibEntrys[ mnBlibEntrys++ ] = p_EscherBlibEntry;
    3586           0 :     return mnBlibEntrys;
    3587             : }
    3588             : 
    3589           0 : sal_uInt32 EscherGraphicProvider::GetBlibStoreContainerSize( SvStream* pMergePicStreamBSE ) const
    3590             : {
    3591           0 :     sal_uInt32 nSize = 44 * mnBlibEntrys + 8;
    3592           0 :     if ( pMergePicStreamBSE )
    3593             :     {
    3594           0 :         for ( sal_uInt32 i = 0; i < mnBlibEntrys; i++ )
    3595           0 :             nSize += mpBlibEntrys[ i ]->mnSize + mpBlibEntrys[ i ]->mnSizeExtra;
    3596             :     }
    3597           0 :     return nSize;
    3598             : }
    3599             : 
    3600           0 : sal_Bool EscherGraphicProvider::WriteBlibStoreEntry(SvStream& rSt,
    3601             :     sal_uInt32 nBlipId, sal_Bool bWritePictureOffSet, sal_uInt32 nResize)
    3602             : {
    3603           0 :     if (nBlipId > mnBlibEntrys || nBlipId == 0)
    3604           0 :         return sal_False;
    3605           0 :     mpBlibEntrys[nBlipId-1]->WriteBlibEntry(rSt, bWritePictureOffSet, nResize);
    3606           0 :     return sal_True;
    3607             : }
    3608             : 
    3609           0 : void EscherGraphicProvider::WriteBlibStoreContainer( SvStream& rSt, SvStream* pMergePicStreamBSE )
    3610             : {
    3611           0 :     sal_uInt32  nSize = GetBlibStoreContainerSize( pMergePicStreamBSE );
    3612           0 :     if ( nSize )
    3613             :     {
    3614           0 :         rSt << (sal_uInt32)( ( ESCHER_BstoreContainer << 16 ) | 0x1f )
    3615           0 :             << (sal_uInt32)( nSize - 8 );
    3616             : 
    3617           0 :         if ( pMergePicStreamBSE )
    3618             :         {
    3619           0 :             sal_uInt32 i, nBlipSize, nOldPos = pMergePicStreamBSE->Tell();
    3620           0 :             const sal_uInt32 nBuf = 0x40000;    // 256KB buffer
    3621           0 :             sal_uInt8* pBuf = new sal_uInt8[ nBuf ];
    3622             : 
    3623           0 :             for ( i = 0; i < mnBlibEntrys; i++ )
    3624             :             {
    3625           0 :                 EscherBlibEntry* pBlibEntry = mpBlibEntrys[ i ];
    3626             : 
    3627           0 :                 ESCHER_BlibType nBlibType = pBlibEntry->meBlibType;
    3628           0 :                 nBlipSize = pBlibEntry->mnSize + pBlibEntry->mnSizeExtra;
    3629           0 :                 pBlibEntry->WriteBlibEntry( rSt, sal_False, nBlipSize );
    3630             : 
    3631             :                 // BLIP
    3632           0 :                 pMergePicStreamBSE->Seek( pBlibEntry->mnPictureOffset );
    3633             :                 sal_uInt16 n16;
    3634             :                 // record version and instance
    3635           0 :                 *pMergePicStreamBSE >> n16;
    3636           0 :                 rSt << n16;
    3637             :                 // record type
    3638           0 :                 *pMergePicStreamBSE >> n16;
    3639           0 :                 rSt << sal_uInt16( ESCHER_BlipFirst + nBlibType );
    3640             :                 DBG_ASSERT( n16 == ESCHER_BlipFirst + nBlibType , "EscherGraphicProvider::WriteBlibStoreContainer: BLIP record types differ" );
    3641             :                 sal_uInt32 n32;
    3642             :                 // record size
    3643           0 :                 *pMergePicStreamBSE >> n32;
    3644           0 :                 nBlipSize -= 8;
    3645           0 :                 rSt << nBlipSize;
    3646             :                 DBG_ASSERT( nBlipSize == n32, "EscherGraphicProvider::WriteBlibStoreContainer: BLIP sizes differ" );
    3647             :                 // record
    3648           0 :                 while ( nBlipSize )
    3649             :                 {
    3650           0 :                     sal_uInt32 nBytes = ( nBlipSize > nBuf ? nBuf : nBlipSize );
    3651           0 :                     pMergePicStreamBSE->Read( pBuf, nBytes );
    3652           0 :                     rSt.Write( pBuf, nBytes );
    3653           0 :                     nBlipSize -= nBytes;
    3654             :                 }
    3655             :             }
    3656           0 :             delete[] pBuf;
    3657           0 :             pMergePicStreamBSE->Seek( nOldPos );
    3658             :         }
    3659             :         else
    3660             :         {
    3661           0 :             for ( sal_uInt32 i = 0; i < mnBlibEntrys; i++ )
    3662           0 :                 mpBlibEntrys[ i ]->WriteBlibEntry( rSt, sal_True );
    3663             :         }
    3664             :     }
    3665           0 : }
    3666             : 
    3667           0 : sal_Bool EscherGraphicProvider::GetPrefSize( const sal_uInt32 nBlibId, Size& rPrefSize, MapMode& rPrefMapMode )
    3668             : {
    3669           0 :     sal_Bool bInRange = nBlibId && ( ( nBlibId - 1 ) < mnBlibEntrys );
    3670           0 :     if ( bInRange )
    3671             :     {
    3672           0 :         EscherBlibEntry* pEntry = mpBlibEntrys[ nBlibId - 1 ];
    3673           0 :         rPrefSize = pEntry->maPrefSize;
    3674           0 :         rPrefMapMode = pEntry->maPrefMapMode;
    3675             :     }
    3676           0 :     return bInRange;
    3677             : }
    3678             : 
    3679           0 : sal_uInt32 EscherGraphicProvider::GetBlibID( SvStream& rPicOutStrm, const rtl::OString& rId,
    3680             :                                             const Rectangle& /* rBoundRect */, const com::sun::star::awt::Rectangle* pVisArea, const GraphicAttr* pGraphicAttr )
    3681             : {
    3682           0 :     sal_uInt32          nBlibId = 0;
    3683           0 :     GraphicObject       aGraphicObject( rId );
    3684             : 
    3685           0 :     EscherBlibEntry* p_EscherBlibEntry = new EscherBlibEntry( rPicOutStrm.Tell(), aGraphicObject, rId, pGraphicAttr );
    3686           0 :     if ( !p_EscherBlibEntry->IsEmpty() )
    3687             :     {
    3688           0 :         for ( sal_uInt32 i = 0; i < mnBlibEntrys; i++ )
    3689             :         {
    3690           0 :             if ( *( mpBlibEntrys[ i ] ) == *p_EscherBlibEntry )
    3691             :             {
    3692           0 :                 mpBlibEntrys[ i ]->mnRefCount++;
    3693           0 :                 delete p_EscherBlibEntry;
    3694           0 :                 return i + 1;
    3695             :             }
    3696             :         }
    3697             : 
    3698           0 :         sal_Bool            bUseNativeGraphic( sal_False );
    3699             : 
    3700           0 :         Graphic             aGraphic( aGraphicObject.GetTransformedGraphic( pGraphicAttr ) );
    3701           0 :         GfxLink             aGraphicLink;
    3702           0 :         SvMemoryStream      aStream;
    3703             : 
    3704           0 :         const sal_uInt8*    pGraphicAry = NULL;
    3705             : 
    3706           0 :         if ( p_EscherBlibEntry->mbIsNativeGraphicPossible && aGraphic.IsLink() )
    3707             :         {
    3708           0 :             aGraphicLink = aGraphic.GetLink();
    3709             : 
    3710           0 :             p_EscherBlibEntry->mnSize = aGraphicLink.GetDataSize();
    3711           0 :             pGraphicAry = aGraphicLink.GetData();
    3712             : 
    3713           0 :             if ( p_EscherBlibEntry->mnSize && pGraphicAry )
    3714             :             {
    3715           0 :                 switch ( aGraphicLink.GetType() )
    3716             :                 {
    3717           0 :                     case GFX_LINK_TYPE_NATIVE_JPG : p_EscherBlibEntry->meBlibType = PEG; break;
    3718           0 :                     case GFX_LINK_TYPE_NATIVE_PNG : p_EscherBlibEntry->meBlibType = PNG; break;
    3719             :                     case GFX_LINK_TYPE_NATIVE_WMF :
    3720             :                     {
    3721           0 :                         if ( pGraphicAry && ( p_EscherBlibEntry->mnSize > 0x2c ) )
    3722             :                         {
    3723           0 :                             if ( ( pGraphicAry[ 0x28 ] == 0x20 ) && ( pGraphicAry[ 0x29 ] == 0x45 )     // check the magic
    3724           0 :                                 && ( pGraphicAry[ 0x2a ] == 0x4d ) && ( pGraphicAry[ 0x2b ] == 0x46 ) ) // number ( emf detection )
    3725             :                             {
    3726           0 :                                 p_EscherBlibEntry->meBlibType = EMF;
    3727             :                             }
    3728             :                             else
    3729             :                             {
    3730           0 :                                 p_EscherBlibEntry->meBlibType = WMF;
    3731           0 :                                 if ( ( pGraphicAry[ 0 ] == 0xd7 ) && ( pGraphicAry[ 1 ] == 0xcd )
    3732           0 :                                     && ( pGraphicAry[ 2 ] == 0xc6 ) && ( pGraphicAry[ 3 ] == 0x9a ) )
    3733             :                                 {   // we have to get rid of the metafileheader
    3734           0 :                                     pGraphicAry += 22;
    3735           0 :                                     p_EscherBlibEntry->mnSize -= 22;
    3736             :                                 }
    3737             :                             }
    3738             :                         }
    3739             :                     }
    3740           0 :                     break;
    3741           0 :                     default: break;
    3742             :                 }
    3743           0 :                 if ( p_EscherBlibEntry->meBlibType != UNKNOWN )
    3744           0 :                     bUseNativeGraphic = sal_True;
    3745             :             }
    3746             :         }
    3747           0 :         if ( !bUseNativeGraphic )
    3748             :         {
    3749           0 :             GraphicType eGraphicType = aGraphic.GetType();
    3750           0 :             if ( ( eGraphicType == GRAPHIC_BITMAP ) || ( eGraphicType == GRAPHIC_GDIMETAFILE ) )
    3751             :             {
    3752             :                 sal_uInt32 nErrCode;
    3753           0 :                 if ( !aGraphic.IsAnimated() )
    3754           0 :                     nErrCode = GraphicConverter::Export( aStream, aGraphic, ( eGraphicType == GRAPHIC_BITMAP ) ? CVT_PNG  : CVT_EMF );
    3755             :                 else
    3756             :                 {   // to store a animation, a gif has to be included into the msOG chunk of a png  #I5583#
    3757           0 :                     GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
    3758           0 :                     SvMemoryStream  aGIFStream;
    3759           0 :                     aGIFStream.Write(RTL_CONSTASCII_STRINGPARAM("MSOFFICE9.0"));
    3760             :                     nErrCode = rFilter.ExportGraphic( aGraphic, String(), aGIFStream,
    3761           0 :                         rFilter.GetExportFormatNumberForShortName( String( RTL_CONSTASCII_USTRINGPARAM( "GIF" ) ) ), NULL );
    3762           0 :                     com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aFilterData( 1 );
    3763           0 :                     com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aAdditionalChunkSequence( 1 );
    3764           0 :                     sal_uInt32 nGIFSreamLen = aGIFStream.Tell();
    3765           0 :                     com::sun::star::uno::Sequence< sal_Int8 > aGIFSeq( nGIFSreamLen );
    3766           0 :                     sal_Int8* pSeq = aGIFSeq.getArray();
    3767           0 :                     aGIFStream.Seek( STREAM_SEEK_TO_BEGIN );
    3768           0 :                     aGIFStream.Read( pSeq, nGIFSreamLen );
    3769           0 :                     com::sun::star::beans::PropertyValue aChunkProp, aFilterProp;
    3770           0 :                     aChunkProp.Name = String( RTL_CONSTASCII_USTRINGPARAM( "msOG" ) );
    3771           0 :                     aChunkProp.Value <<= aGIFSeq;
    3772           0 :                     aAdditionalChunkSequence[ 0 ] = aChunkProp;
    3773           0 :                     aFilterProp.Name = String( RTL_CONSTASCII_USTRINGPARAM( "AdditionalChunks" ) );
    3774           0 :                     aFilterProp.Value <<= aAdditionalChunkSequence;
    3775           0 :                     aFilterData[ 0 ] = aFilterProp;
    3776             :                     nErrCode = rFilter.ExportGraphic( aGraphic, String(), aStream,
    3777           0 :                         rFilter.GetExportFormatNumberForShortName( String( RTL_CONSTASCII_USTRINGPARAM( "PNG" ) ) ), &aFilterData );
    3778             :                 }
    3779           0 :                 if ( nErrCode == ERRCODE_NONE )
    3780             :                 {
    3781           0 :                     p_EscherBlibEntry->meBlibType = ( eGraphicType == GRAPHIC_BITMAP ) ? PNG : EMF;
    3782           0 :                     aStream.Seek( STREAM_SEEK_TO_END );
    3783           0 :                     p_EscherBlibEntry->mnSize = aStream.Tell();
    3784           0 :                     pGraphicAry = (sal_uInt8*)aStream.GetData();
    3785             : 
    3786           0 :                     if ( p_EscherBlibEntry->meBlibType == WMF )     // the fileheader is not used
    3787             :                     {
    3788           0 :                         p_EscherBlibEntry->mnSize -= 22;
    3789           0 :                         pGraphicAry += 22;
    3790             :                     }
    3791             :                 }
    3792             :             }
    3793             :         }
    3794             : 
    3795           0 :         ESCHER_BlibType eBlibType = p_EscherBlibEntry->meBlibType;
    3796           0 :         if ( p_EscherBlibEntry->mnSize && pGraphicAry && ( eBlibType != UNKNOWN ) )
    3797             :         {
    3798           0 :             sal_uInt32 nExtra, nAtomSize = 0;
    3799           0 :             sal_uInt32 nInstance, nUncompressedSize = p_EscherBlibEntry->mnSize;
    3800             : 
    3801           0 :             if ( mnFlags & _E_GRAPH_PROV_USE_INSTANCES )
    3802             :             {
    3803           0 :                 rPicOutStrm << (sal_uInt32)( 0x7f90000 | (sal_uInt16)( mnBlibEntrys << 4 ) )
    3804           0 :                             << (sal_uInt32)0;
    3805           0 :                 nAtomSize = rPicOutStrm.Tell();
    3806           0 :                  if ( eBlibType == PNG )
    3807           0 :                     rPicOutStrm << (sal_uInt16)0x0606;
    3808           0 :                 else if ( eBlibType == WMF )
    3809           0 :                     rPicOutStrm << (sal_uInt16)0x0403;
    3810           0 :                 else if ( eBlibType == EMF )
    3811           0 :                     rPicOutStrm << (sal_uInt16)0x0402;
    3812           0 :                 else if ( eBlibType == PEG )
    3813           0 :                     rPicOutStrm << (sal_uInt16)0x0505;
    3814             :             }
    3815           0 :             if ( ( eBlibType == PEG ) || ( eBlibType == PNG ) )
    3816             :             {
    3817           0 :                 nExtra = 17;
    3818           0 :                 p_EscherBlibEntry->mnSizeExtra = nExtra + 8;
    3819           0 :                 nInstance = ( eBlibType == PNG ) ? 0xf01e6e00 : 0xf01d46a0;
    3820           0 :                 rPicOutStrm << nInstance << (sal_uInt32)( p_EscherBlibEntry->mnSize + nExtra );
    3821           0 :                 rPicOutStrm.Write( p_EscherBlibEntry->mnIdentifier, 16 );
    3822           0 :                 rPicOutStrm << (sal_uInt8)0xff;
    3823           0 :                 rPicOutStrm.Write( pGraphicAry, p_EscherBlibEntry->mnSize );
    3824             :             }
    3825             :             else
    3826             :             {
    3827           0 :                 ZCodec aZCodec( 0x8000, 0x8000 );
    3828           0 :                 aZCodec.BeginCompression();
    3829           0 :                 SvMemoryStream aDestStrm;
    3830           0 :                 aZCodec.Write( aDestStrm, pGraphicAry, p_EscherBlibEntry->mnSize );
    3831           0 :                 aZCodec.EndCompression();
    3832           0 :                 aDestStrm.Seek( STREAM_SEEK_TO_END );
    3833           0 :                 p_EscherBlibEntry->mnSize = aDestStrm.Tell();
    3834           0 :                 pGraphicAry = (sal_uInt8*)aDestStrm.GetData();
    3835           0 :                 if ( p_EscherBlibEntry->mnSize && pGraphicAry )
    3836             :                 {
    3837           0 :                     nExtra = eBlibType == WMF ? 0x42 : 0x32;                                    // !EMF -> no change
    3838           0 :                     p_EscherBlibEntry->mnSizeExtra = nExtra + 8;
    3839           0 :                     nInstance = ( eBlibType == WMF ) ? 0xf01b2170 : 0xf01a3d40;                 // !EMF -> no change
    3840           0 :                     rPicOutStrm << nInstance << (sal_uInt32)( p_EscherBlibEntry->mnSize + nExtra );
    3841           0 :                     if ( eBlibType == WMF )                                                     // !EMF -> no change
    3842           0 :                         rPicOutStrm.Write( p_EscherBlibEntry->mnIdentifier, 16 );
    3843           0 :                     rPicOutStrm.Write( p_EscherBlibEntry->mnIdentifier, 16 );
    3844             : 
    3845             :                     /*
    3846             :                      ##913##
    3847             :                      For Word the stored size of the graphic is critical the
    3848             :                      metafile boundaries must match the actual graphics
    3849             :                      boundaries, and the width and height must be in EMU's
    3850             : 
    3851             :                      If you don't do it this way then objects edited in the
    3852             :                      msoffice app may show strange behaviour as the size jumps
    3853             :                      around, and the original size and scaling factor in word
    3854             :                      will be a very strange figure
    3855             :                     */
    3856           0 :                     sal_uInt32 nPrefWidth = p_EscherBlibEntry->maPrefSize.Width();
    3857           0 :                     sal_uInt32 nPrefHeight = p_EscherBlibEntry->maPrefSize.Height();
    3858             :                     sal_uInt32 nWidth, nHeight;
    3859           0 :                     if ( pVisArea )
    3860             :                     {
    3861           0 :                         nWidth = pVisArea->Width * 360;
    3862           0 :                         nHeight = pVisArea->Height * 360;
    3863             :                     }
    3864             :                     else
    3865             :                     {
    3866           0 :                         Size aPrefSize(lcl_SizeToEmu(p_EscherBlibEntry->maPrefSize, p_EscherBlibEntry->maPrefMapMode));
    3867           0 :                         nWidth = aPrefSize.Width() * 360;
    3868           0 :                         nHeight = aPrefSize.Height() * 360;
    3869             :                     }
    3870           0 :                     rPicOutStrm << nUncompressedSize // WMFSize without FileHeader
    3871           0 :                     << (sal_Int32)0     // since we can't find out anymore what the original size of
    3872           0 :                     << (sal_Int32)0     // the WMF (without Fileheader) was we write 10cm / x
    3873           0 :                     << nPrefWidth
    3874           0 :                     << nPrefHeight
    3875           0 :                     << nWidth
    3876           0 :                     << nHeight
    3877           0 :                     << p_EscherBlibEntry->mnSize
    3878           0 :                     << (sal_uInt16)0xfe00;  // compression Flags
    3879           0 :                     rPicOutStrm.Write( pGraphicAry, p_EscherBlibEntry->mnSize );
    3880           0 :                 }
    3881             :             }
    3882           0 :             if ( nAtomSize )
    3883             :             {
    3884           0 :                 sal_uInt32  nPos = rPicOutStrm.Tell();
    3885           0 :                 rPicOutStrm.Seek( nAtomSize - 4 );
    3886           0 :                 rPicOutStrm << (sal_uInt32)( nPos - nAtomSize );
    3887           0 :                 rPicOutStrm.Seek( nPos );
    3888             :             }
    3889           0 :             nBlibId = ImplInsertBlib( p_EscherBlibEntry ), p_EscherBlibEntry = NULL;
    3890           0 :         }
    3891             :     }
    3892           0 :     if ( p_EscherBlibEntry )
    3893           0 :         delete p_EscherBlibEntry;
    3894           0 :     return nBlibId;
    3895             : }
    3896             : 
    3897             : struct EscherConnectorRule
    3898             : {
    3899             :     sal_uInt32  nRuleId;
    3900             :     sal_uInt32  nShapeA;        // SPID of shape A
    3901             :     sal_uInt32  nShapeB;        // SPID of shape B
    3902             :     sal_uInt32  nShapeC;        // SPID of connector shape
    3903             :     sal_uInt32  ncptiA;         // Connection site Index of shape A
    3904             :     sal_uInt32  ncptiB;         // Connection site Index of shape B
    3905             : };
    3906             : 
    3907           1 : struct EscherShapeListEntry
    3908             : {
    3909             :     ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >   aXShape;
    3910             :     sal_uInt32          n_EscherId;
    3911             : 
    3912           1 :                         EscherShapeListEntry( const ::com::sun::star::uno::Reference
    3913             :                             < ::com::sun::star::drawing::XShape > & rShape, sal_uInt32 nId ) :
    3914             :                                         aXShape     ( rShape ),
    3915           1 :                                         n_EscherId  ( nId ) {}
    3916             : };
    3917             : 
    3918           0 : sal_uInt32 EscherConnectorListEntry::GetClosestPoint( const Polygon& rPoly, const ::com::sun::star::awt::Point& rPoint )
    3919             : {
    3920           0 :     sal_uInt16 nCount = rPoly.GetSize();
    3921           0 :     sal_uInt16 nClosest = nCount;
    3922           0 :     double fDist = (sal_uInt32)0xffffffff;
    3923           0 :     while( nCount-- )
    3924             :     {
    3925           0 :         double fDistance = hypot( rPoint.X - rPoly[ nCount ].X(), rPoint.Y - rPoly[ nCount ].Y() );
    3926           0 :         if ( fDistance < fDist )
    3927             :         {
    3928           0 :             nClosest =  nCount;
    3929           0 :             fDist = fDistance;
    3930             :         }
    3931             :     }
    3932           0 :     return nClosest;
    3933             : };
    3934             : 
    3935             : // ---------------------------------------------------------------------------------------------
    3936             : // for rectangles          for ellipses     for polygons
    3937             : //
    3938             : // nRule =  0 ->Top         0 ->Top         nRule = Index auf ein (Poly)Polygon Punkt
    3939             : //          1 ->Left        2 ->Left
    3940             : //          2 ->Bottom      4 ->Bottom
    3941             : //          3 ->Right       6 ->Right
    3942             : 
    3943           0 : sal_uInt32 EscherConnectorListEntry::GetConnectorRule( sal_Bool bFirst )
    3944             : {
    3945           0 :     sal_uInt32 nRule = 0;
    3946             : 
    3947           0 :     ::com::sun::star::uno::Any aAny;
    3948           0 :     ::com::sun::star::awt::Point aRefPoint( ( bFirst ) ? maPointA : maPointB );
    3949             :     ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
    3950           0 :         aXShape( ( bFirst ) ? mXConnectToA : mXConnectToB );
    3951             : 
    3952           0 :     rtl::OUString aString(aXShape->getShapeType());
    3953           0 :     rtl::OStringBuffer aBuf(rtl::OUStringToOString(aString, RTL_TEXTENCODING_UTF8));
    3954           0 :     aBuf.remove( 0, 13 );   // removing "com.sun.star."
    3955           0 :     sal_Int16 nPos = aBuf.toString().indexOf("Shape");
    3956           0 :     aBuf.remove(nPos, 5);
    3957           0 :     rtl::OString aType = aBuf.makeStringAndClear();
    3958             : 
    3959             :     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
    3960           0 :         aPropertySet( aXShape, ::com::sun::star::uno::UNO_QUERY );
    3961             : 
    3962           0 :     if (aType.equalsL(RTL_CONSTASCII_STRINGPARAM("drawing.PolyPolygon")) || aType.equalsL(RTL_CONSTASCII_STRINGPARAM("drawing.PolyLine")))
    3963             :     {
    3964           0 :         if ( aPropertySet.is() )
    3965             :         {
    3966           0 :             if ( EscherPropertyValueHelper::GetPropertyValue( aAny,
    3967           0 :                     aPropertySet, String( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) ) ) )
    3968             :             {
    3969             :                 ::com::sun::star::drawing::PointSequenceSequence* pSourcePolyPolygon =
    3970           0 :                     (::com::sun::star::drawing::PointSequenceSequence*)aAny.getValue();
    3971           0 :                 sal_Int32 nOuterSequenceCount = pSourcePolyPolygon->getLength();
    3972           0 :                 ::com::sun::star::drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray();
    3973             : 
    3974           0 :                 if ( pOuterSequence )
    3975             :                 {
    3976           0 :                     sal_Int32 a, b, nIndex = 0;
    3977           0 :                     sal_uInt32 nDistance = 0xffffffff;
    3978           0 :                     for( a = 0; a < nOuterSequenceCount; a++ )
    3979             :                     {
    3980           0 :                         ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++;
    3981           0 :                         if ( pInnerSequence )
    3982             :                         {
    3983           0 :                             ::com::sun::star::awt::Point* pArray = pInnerSequence->getArray();
    3984           0 :                             if ( pArray )
    3985             :                             {
    3986           0 :                                 for ( b = 0; b < pInnerSequence->getLength(); b++, nIndex++, pArray++ )
    3987             :                                 {
    3988           0 :                                     sal_uInt32 nDist = (sal_uInt32)hypot( aRefPoint.X - pArray->X, aRefPoint.Y - pArray->Y );
    3989           0 :                                     if ( nDist < nDistance )
    3990             :                                     {
    3991           0 :                                         nRule = nIndex;
    3992           0 :                                         nDistance = nDist;
    3993             :                                     }
    3994             :                                 }
    3995             :                             }
    3996             :                         }
    3997             :                     }
    3998             :                 }
    3999             :             }
    4000             :         }
    4001             :     }
    4002           0 :     else if ( (aType.equalsL(RTL_CONSTASCII_STRINGPARAM("drawing.OpenBezier"))) || (aType.equalsL(RTL_CONSTASCII_STRINGPARAM("drawing.OpenFreeHand"))) || (aType.equalsL(RTL_CONSTASCII_STRINGPARAM("drawing.PolyLinePath")))
    4003           0 :         || (aType.equalsL(RTL_CONSTASCII_STRINGPARAM("drawing.ClosedBezier"))) || ( aType.equalsL(RTL_CONSTASCII_STRINGPARAM("drawing.ClosedFreeHand"))) || (aType.equalsL(RTL_CONSTASCII_STRINGPARAM("drawing.PolyPolygonPath"))) )
    4004             :     {
    4005             :         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
    4006           0 :             aPropertySet2( aXShape, ::com::sun::star::uno::UNO_QUERY );
    4007           0 :         if ( aPropertySet2.is() )
    4008             :         {
    4009           0 :             if ( EscherPropertyValueHelper::GetPropertyValue( aAny,
    4010           0 :                     aPropertySet2, String( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) ) ) )
    4011             :             {
    4012             :                 ::com::sun::star::drawing::PolyPolygonBezierCoords* pSourcePolyPolygon =
    4013           0 :                     (::com::sun::star::drawing::PolyPolygonBezierCoords*)aAny.getValue();
    4014           0 :                 sal_Int32 nOuterSequenceCount = pSourcePolyPolygon->Coordinates.getLength();
    4015             : 
    4016             :                 // Zeiger auf innere sequences holen
    4017             :                 ::com::sun::star::drawing::PointSequence* pOuterSequence =
    4018           0 :                     pSourcePolyPolygon->Coordinates.getArray();
    4019             :                 ::com::sun::star::drawing::FlagSequence*  pOuterFlags =
    4020           0 :                     pSourcePolyPolygon->Flags.getArray();
    4021             : 
    4022           0 :                 if ( pOuterSequence && pOuterFlags )
    4023             :                 {
    4024           0 :                     sal_Int32 a, b, nIndex = 0;
    4025           0 :                     sal_uInt32 nDistance = 0xffffffff;
    4026             : 
    4027           0 :                     for ( a = 0; a < nOuterSequenceCount; a++ )
    4028             :                     {
    4029           0 :                         ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++;
    4030           0 :                         ::com::sun::star::drawing::FlagSequence*  pInnerFlags = pOuterFlags++;
    4031           0 :                         if ( pInnerSequence && pInnerFlags )
    4032             :                         {
    4033           0 :                             ::com::sun::star::awt::Point* pArray = pInnerSequence->getArray();
    4034           0 :                             ::com::sun::star::drawing::PolygonFlags* pFlags = pInnerFlags->getArray();
    4035           0 :                             if ( pArray && pFlags )
    4036             :                             {
    4037           0 :                                 for ( b = 0; b < pInnerSequence->getLength(); b++, pArray++ )
    4038             :                                 {
    4039           0 :                                     PolyFlags ePolyFlags = *( (PolyFlags*)pFlags++ );
    4040           0 :                                     if ( ePolyFlags == POLY_CONTROL )
    4041           0 :                                         continue;
    4042           0 :                                     sal_uInt32 nDist = (sal_uInt32)hypot( aRefPoint.X - pArray->X, aRefPoint.Y - pArray->Y );
    4043           0 :                                     if ( nDist < nDistance )
    4044             :                                     {
    4045           0 :                                         nRule = nIndex;
    4046           0 :                                         nDistance = nDist;
    4047             :                                     }
    4048           0 :                                     nIndex++;
    4049             :                                 }
    4050             :                             }
    4051             :                         }
    4052             :                     }
    4053             :                 }
    4054             :             }
    4055           0 :         }
    4056             :     }
    4057             :     else
    4058             :     {
    4059           0 :         bool bRectangularConnection = true;
    4060             : 
    4061           0 :         if (aType.equalsL(RTL_CONSTASCII_STRINGPARAM("drawing.Custom")))
    4062             :         {
    4063           0 :             SdrObject* pCustoShape( GetSdrObjectFromXShape( aXShape ) );
    4064           0 :             if ( pCustoShape && pCustoShape->ISA( SdrObjCustomShape ) )
    4065             :             {
    4066             :                 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)(const SdrCustomShapeGeometryItem&)
    4067           0 :                     pCustoShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
    4068             : 
    4069           0 :                 const rtl::OUString sPath( "Path"  );
    4070           0 :                 const rtl::OUString sType( "Type"  );
    4071           0 :                 const rtl::OUString sGluePointType( "GluePointType"  );
    4072             : 
    4073           0 :                 rtl::OUString sShapeType;
    4074           0 :                 uno::Any* pType = rGeometryItem.GetPropertyValueByName( sType );
    4075           0 :                 if ( pType )
    4076           0 :                     *pType >>= sShapeType;
    4077           0 :                 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
    4078             : 
    4079           0 :                 uno::Any* pGluePointType = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sGluePointType );
    4080             : 
    4081           0 :                 sal_Int16 nGluePointType = sal_Int16();
    4082           0 :                 if ( !( pGluePointType &&
    4083           0 :                         ( *pGluePointType >>= nGluePointType ) ) )
    4084           0 :                     nGluePointType = GetCustomShapeConnectionTypeDefault( eSpType );
    4085             : 
    4086           0 :                 if ( nGluePointType == com::sun::star::drawing::EnhancedCustomShapeGluePointType::CUSTOM )
    4087             :                 {
    4088           0 :                     const SdrGluePointList* pList = pCustoShape->GetGluePointList();
    4089           0 :                     if ( pList )
    4090             :                     {
    4091           0 :                         Polygon aPoly;
    4092           0 :                         sal_uInt16 nNum, nAnz = pList->GetCount();
    4093           0 :                         if ( nAnz )
    4094             :                         {
    4095           0 :                             for ( nNum = 0; nNum < nAnz; nNum++ )
    4096             :                             {
    4097           0 :                                 const SdrGluePoint& rGP = (*pList)[ nNum ];
    4098           0 :                                 Point aPt( rGP.GetAbsolutePos( *pCustoShape ) );
    4099           0 :                                 aPoly.Insert( POLY_APPEND, aPt );
    4100             :                             }
    4101           0 :                             nRule = GetClosestPoint( aPoly, aRefPoint );
    4102           0 :                             bRectangularConnection = false;
    4103           0 :                         }
    4104             :                     }
    4105             :                 }
    4106           0 :                 else if ( nGluePointType == com::sun::star::drawing::EnhancedCustomShapeGluePointType::SEGMENTS )
    4107             :                 {
    4108           0 :                     SdrObject* pPoly = pCustoShape->DoConvertToPolyObj( sal_True, true );
    4109           0 :                     if ( pPoly && pPoly->ISA( SdrPathObj ) )
    4110             :                     {
    4111           0 :                         sal_Int16 a, b, nIndex = 0;
    4112           0 :                         sal_uInt32 nDistance = 0xffffffff;
    4113             : 
    4114             :                         // #i74631# use explicit constructor here. Also XPolyPolygon is not necessary,
    4115             :                         // reducing to PolyPolygon
    4116           0 :                         const PolyPolygon aPolyPoly(((SdrPathObj*)pPoly)->GetPathPoly());
    4117             : 
    4118           0 :                         for ( a = 0; a < aPolyPoly.Count(); a++ )
    4119             :                         {
    4120           0 :                             const Polygon& rPoly = aPolyPoly.GetObject( a );
    4121           0 :                             for ( b = 0; b < rPoly.GetSize(); b++ )
    4122             :                             {
    4123           0 :                                 if ( rPoly.GetFlags( b ) != POLY_NORMAL )
    4124           0 :                                     continue;
    4125           0 :                                 const Point& rPt = rPoly[ b ];
    4126           0 :                                 sal_uInt32 nDist = (sal_uInt32)hypot( aRefPoint.X - rPt.X(), aRefPoint.Y - rPt.Y() );
    4127           0 :                                 if ( nDist < nDistance )
    4128             :                                 {
    4129           0 :                                     nRule = nIndex;
    4130           0 :                                     nDistance = nDist;
    4131             :                                 }
    4132           0 :                                 nIndex++;
    4133             :                             }
    4134             :                         }
    4135           0 :                         if ( nDistance != 0xffffffff )
    4136           0 :                             bRectangularConnection = false;
    4137             :                     }
    4138           0 :                 }
    4139             :             }
    4140             :         }
    4141           0 :         if ( bRectangularConnection )
    4142             :         {
    4143           0 :             ::com::sun::star::awt::Point aPoint( aXShape->getPosition() );
    4144           0 :             ::com::sun::star::awt::Size  aSize( aXShape->getSize() );
    4145             : 
    4146           0 :             Rectangle   aRect( Point( aPoint.X, aPoint.Y ), Size( aSize.Width, aSize.Height ) );
    4147           0 :             Point       aCenter( aRect.Center() );
    4148           0 :             Polygon     aPoly( 4 );
    4149             : 
    4150           0 :             aPoly[ 0 ] = Point( aCenter.X(), aRect.Top() );
    4151           0 :             aPoly[ 1 ] = Point( aRect.Left(), aCenter.Y() );
    4152           0 :             aPoly[ 2 ] = Point( aCenter.X(), aRect.Bottom() );
    4153           0 :             aPoly[ 3 ] = Point( aRect.Right(), aCenter.Y() );
    4154             : 
    4155             :             sal_Int32 nAngle = ( EscherPropertyValueHelper::GetPropertyValue( aAny,
    4156           0 :                 aPropertySet, String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True ) )
    4157           0 :                     ? *((sal_Int32*)aAny.getValue() )
    4158           0 :                     : 0;
    4159           0 :             if ( nAngle )
    4160           0 :                 aPoly.Rotate( aRect.TopLeft(), (sal_uInt16)( ( nAngle + 5 ) / 10 ) );
    4161           0 :             nRule = GetClosestPoint( aPoly, aRefPoint );
    4162             : 
    4163           0 :             if (aType.equalsL(RTL_CONSTASCII_STRINGPARAM("drawing.Ellipse")))
    4164           0 :                 nRule <<= 1;    // In PPT an ellipse has 8 ways to connect
    4165             :         }
    4166             :     }
    4167           0 :     return nRule;
    4168             : }
    4169             : 
    4170           4 : EscherSolverContainer::~EscherSolverContainer()
    4171             : {
    4172           3 :     for( size_t i = 0, n = maShapeList.size(); i < n; ++i ) {
    4173           1 :         delete maShapeList[ i ];
    4174             :     }
    4175           2 :     for( size_t i = 0, n = maConnectorList.size(); i < n; ++i ) {
    4176           0 :         delete maConnectorList[ i ];
    4177             :     }
    4178           2 : }
    4179             : 
    4180           1 : void EscherSolverContainer::AddShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape, sal_uInt32 nId )
    4181             : {
    4182           1 :     maShapeList.push_back( new EscherShapeListEntry( rXShape, nId ) );
    4183           1 : }
    4184             : 
    4185           0 : void EscherSolverContainer::AddConnector(
    4186             :     const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rConnector,
    4187             :     const ::com::sun::star::awt::Point& rPA,
    4188             :     ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rConA,
    4189             :     const ::com::sun::star::awt::Point& rPB,
    4190             :     ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rConB
    4191             : )
    4192             : {
    4193           0 :     maConnectorList.push_back( new EscherConnectorListEntry( rConnector, rPA, rConA, rPB, rConB ) );
    4194           0 : }
    4195             : 
    4196           0 : sal_uInt32 EscherSolverContainer::GetShapeId( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape ) const
    4197             : {
    4198           0 :     for ( size_t i = 0, n = maShapeList.size(); i < n; ++i )
    4199             :     {
    4200           0 :         EscherShapeListEntry* pPtr = maShapeList[ i ];
    4201           0 :         if ( rXShape == pPtr->aXShape )
    4202           0 :             return ( pPtr->n_EscherId );
    4203             :     }
    4204           0 :     return 0;
    4205             : }
    4206             : 
    4207           1 : void EscherSolverContainer::WriteSolver( SvStream& rStrm )
    4208             : {
    4209           1 :     sal_uInt32 nCount = maConnectorList.size();
    4210           1 :     if ( nCount )
    4211             :     {
    4212             :         sal_uInt32  nRecHdPos, nCurrentPos, nSize;
    4213           0 :         rStrm   << (sal_uInt16)( ( nCount << 4 ) | 0xf )    // open an ESCHER_SolverContainer
    4214           0 :                 << (sal_uInt16)ESCHER_SolverContainer       //
    4215           0 :                 << (sal_uInt32)0;                           //
    4216             : 
    4217           0 :         nRecHdPos = rStrm.Tell() - 4;
    4218             : 
    4219             :         EscherConnectorRule aConnectorRule;
    4220           0 :         aConnectorRule.nRuleId = 2;
    4221           0 :         for ( size_t i = 0, n = maConnectorList.size(); i < n; ++i )
    4222             :         {
    4223           0 :             EscherConnectorListEntry* pPtr = maConnectorList[ i ];
    4224           0 :             aConnectorRule.ncptiA  = aConnectorRule.ncptiB = 0xffffffff;
    4225           0 :             aConnectorRule.nShapeC = GetShapeId( pPtr->mXConnector );
    4226           0 :             aConnectorRule.nShapeA = GetShapeId( pPtr->mXConnectToA );
    4227           0 :             aConnectorRule.nShapeB = GetShapeId( pPtr->mXConnectToB );
    4228             : 
    4229           0 :             if ( aConnectorRule.nShapeC )
    4230             :             {
    4231           0 :                 if ( aConnectorRule.nShapeA )
    4232           0 :                     aConnectorRule.ncptiA = pPtr->GetConnectorRule( sal_True );
    4233           0 :                 if ( aConnectorRule.nShapeB )
    4234           0 :                     aConnectorRule.ncptiB = pPtr->GetConnectorRule( sal_False );
    4235             :             }
    4236           0 :             rStrm   << (sal_uInt32)( ( ESCHER_ConnectorRule << 16 ) | 1 )   // atom hd
    4237           0 :                     << (sal_uInt32)24                                       //
    4238           0 :                     << aConnectorRule.nRuleId
    4239           0 :                     << aConnectorRule.nShapeA
    4240           0 :                     << aConnectorRule.nShapeB
    4241           0 :                     << aConnectorRule.nShapeC
    4242           0 :                     << aConnectorRule.ncptiA
    4243           0 :                     << aConnectorRule.ncptiB;
    4244             : 
    4245           0 :             aConnectorRule.nRuleId += 2;
    4246             :         }
    4247             : 
    4248           0 :         nCurrentPos = rStrm.Tell();             // close the ESCHER_SolverContainer
    4249           0 :         nSize = ( nCurrentPos - nRecHdPos ) - 4;//
    4250           0 :         rStrm.Seek( nRecHdPos );                //
    4251           0 :         rStrm << nSize;                         //
    4252           0 :         rStrm.Seek( nCurrentPos );              //
    4253             :     }
    4254           1 : }
    4255             : 
    4256          54 : EscherExGlobal::EscherExGlobal( sal_uInt32 nGraphicProvFlags ) :
    4257             :     EscherGraphicProvider( nGraphicProvFlags ),
    4258             :     mpPicStrm( 0 ),
    4259             :     mbHasDggCont( false ),
    4260          54 :     mbPicStrmQueried( false )
    4261             : {
    4262          54 : }
    4263             : 
    4264         107 : EscherExGlobal::~EscherExGlobal()
    4265             : {
    4266         107 : }
    4267             : 
    4268           1 : sal_uInt32 EscherExGlobal::GenerateDrawingId()
    4269             : {
    4270             :     // new drawing starts a new cluster in the cluster table (cluster identifiers are one-based)
    4271           1 :     sal_uInt32 nClusterId = static_cast< sal_uInt32 >( maClusterTable.size() + 1 );
    4272             :     // drawing identifiers are one-based
    4273           1 :     sal_uInt32 nDrawingId = static_cast< sal_uInt32 >( maDrawingInfos.size() + 1 );
    4274             :     // prepare new entries in the tables
    4275           1 :     maClusterTable.push_back( ClusterEntry( nDrawingId ) );
    4276           1 :     maDrawingInfos.push_back( DrawingInfo( nClusterId ) );
    4277             :     // return the new drawing identifier
    4278           1 :     return nDrawingId;
    4279             : }
    4280             : 
    4281           2 : sal_uInt32 EscherExGlobal::GenerateShapeId( sal_uInt32 nDrawingId, bool bIsInSpgr )
    4282             : {
    4283             :     // drawing identifier is one-based
    4284             :     // make sure the drawing is valid (bnc#656503)
    4285           2 :     if ( nDrawingId == 0 )
    4286           1 :         return 0;
    4287             :     // create index from the identifier
    4288           1 :     size_t nDrawingIdx = nDrawingId - 1;
    4289             :     OSL_ENSURE( nDrawingIdx < maDrawingInfos.size(), "EscherExGlobal::GenerateShapeId - invalid drawing ID" );
    4290           1 :     if( nDrawingIdx >= maDrawingInfos.size() )
    4291           0 :         return 0;
    4292           1 :     DrawingInfo& rDrawingInfo = maDrawingInfos[ nDrawingIdx ];
    4293             : 
    4294             :     // cluster identifier in drawing info struct is one-based
    4295           1 :     ClusterEntry* pClusterEntry = &maClusterTable[ rDrawingInfo.mnClusterId - 1 ];
    4296             : 
    4297             :     // check cluster overflow, create new cluster entry
    4298           1 :     if( pClusterEntry->mnNextShapeId == DFF_DGG_CLUSTER_SIZE )
    4299             :     {
    4300             :         // start a new cluster in the cluster table
    4301           0 :         maClusterTable.push_back( ClusterEntry( nDrawingId ) );
    4302           0 :         pClusterEntry = &maClusterTable.back();
    4303             :         // new size of maClusterTable is equal to one-based identifier of the new cluster
    4304           0 :         rDrawingInfo.mnClusterId = static_cast< sal_uInt32 >( maClusterTable.size() );
    4305             :     }
    4306             : 
    4307             :     // build shape identifier from cluster identifier and next free cluster shape identifier
    4308           1 :     rDrawingInfo.mnLastShapeId = static_cast< sal_uInt32 >( rDrawingInfo.mnClusterId * DFF_DGG_CLUSTER_SIZE + pClusterEntry->mnNextShapeId );
    4309             :     // update free shape identifier in cluster entry
    4310           1 :     ++pClusterEntry->mnNextShapeId;
    4311             :     /*  Old code has counted the shapes only, if we are in a SPGRCONTAINER. Is
    4312             :         this really intended? Maybe it's always true... */
    4313           1 :     if( bIsInSpgr )
    4314           1 :         ++rDrawingInfo.mnShapeCount;
    4315             : 
    4316             :     // return the new shape identifier
    4317           1 :     return rDrawingInfo.mnLastShapeId;
    4318             : }
    4319             : 
    4320           1 : sal_uInt32 EscherExGlobal::GetDrawingShapeCount( sal_uInt32 nDrawingId ) const
    4321             : {
    4322           1 :     size_t nDrawingIdx = nDrawingId - 1;
    4323             :     OSL_ENSURE( nDrawingIdx < maDrawingInfos.size(), "EscherExGlobal::GetDrawingShapeCount - invalid drawing ID" );
    4324           1 :     return (nDrawingIdx < maDrawingInfos.size()) ? maDrawingInfos[ nDrawingIdx ].mnShapeCount : 0;
    4325             : }
    4326             : 
    4327           1 : sal_uInt32 EscherExGlobal::GetLastShapeId( sal_uInt32 nDrawingId ) const
    4328             : {
    4329           1 :     size_t nDrawingIdx = nDrawingId - 1;
    4330             :     OSL_ENSURE( nDrawingIdx < maDrawingInfos.size(), "EscherExGlobal::GetLastShapeId - invalid drawing ID" );
    4331           1 :     return (nDrawingIdx < maDrawingInfos.size()) ? maDrawingInfos[ nDrawingIdx ].mnLastShapeId : 0;
    4332             : }
    4333             : 
    4334           2 : sal_uInt32 EscherExGlobal::GetDggAtomSize() const
    4335             : {
    4336             :     // 8 bytes header, 16 bytes fixed DGG data, 8 bytes for each cluster
    4337           2 :     return static_cast< sal_uInt32 >( 24 + 8 * maClusterTable.size() );
    4338             : }
    4339             : 
    4340           1 : void EscherExGlobal::WriteDggAtom( SvStream& rStrm ) const
    4341             : {
    4342           1 :     sal_uInt32 nDggSize = GetDggAtomSize();
    4343             : 
    4344             :     // write the DGG record header (do not include the 8 bytes of the header in the data size)
    4345           1 :     rStrm << static_cast< sal_uInt32 >( ESCHER_Dgg << 16 ) << static_cast< sal_uInt32 >( nDggSize - 8 );
    4346             : 
    4347             :     // claculate and write the fixed DGG data
    4348           1 :     sal_uInt32 nShapeCount = 0;
    4349           1 :     sal_uInt32 nLastShapeId = 0;
    4350           2 :     for( DrawingInfoVector::const_iterator aIt = maDrawingInfos.begin(), aEnd = maDrawingInfos.end(); aIt != aEnd; ++aIt )
    4351             :     {
    4352           1 :         nShapeCount += aIt->mnShapeCount;
    4353           1 :         nLastShapeId = ::std::max( nLastShapeId, aIt->mnLastShapeId );
    4354             :     }
    4355             :     // the non-existing cluster with index #0 is counted too
    4356           1 :     sal_uInt32 nClusterCount = static_cast< sal_uInt32 >( maClusterTable.size() + 1 );
    4357           1 :     sal_uInt32 nDrawingCount = static_cast< sal_uInt32 >( maDrawingInfos.size() );
    4358           1 :     rStrm << nLastShapeId << nClusterCount << nShapeCount << nDrawingCount;
    4359             : 
    4360             :     // write the cluster table
    4361           2 :     for( ClusterTable::const_iterator aIt = maClusterTable.begin(), aEnd = maClusterTable.end(); aIt != aEnd; ++aIt )
    4362           1 :         rStrm << aIt->mnDrawingId << aIt->mnNextShapeId;
    4363           1 : }
    4364             : 
    4365           1 : SvStream* EscherExGlobal::QueryPictureStream()
    4366             : {
    4367           1 :     if( !mbPicStrmQueried )
    4368             :     {
    4369           1 :         mpPicStrm = ImplQueryPictureStream();
    4370           1 :         mbPicStrmQueried = true;
    4371             :     }
    4372           1 :     return mpPicStrm;
    4373             : }
    4374             : 
    4375           1 : SvStream* EscherExGlobal::ImplQueryPictureStream()
    4376             : {
    4377           1 :     return 0;
    4378             : }
    4379             : 
    4380             : /// Implementation of an empty stream that silently succeeds, but does nothing.
    4381             : ///
    4382             : /// In fact, this is a hack.  The right solution is to abstract EscherEx to be
    4383             : /// able to work without SvStream; but at the moment it is better to live with
    4384             : /// this I guess.
    4385             : class SvNullStream : public SvStream
    4386             : {
    4387             : protected:
    4388           0 :     virtual sal_Size GetData( void* pData, sal_Size nSize ) { memset( pData, 0, nSize ); return nSize; }
    4389           4 :     virtual sal_Size PutData( const void*, sal_Size nSize ) { return nSize; }
    4390           2 :     virtual sal_Size SeekPos( sal_Size nPos ) { return nPos; }
    4391           0 :     virtual void SetSize( sal_Size ) {}
    4392           0 :     virtual void FlushData() {}
    4393             : 
    4394             : public:
    4395          53 :     SvNullStream() : SvStream() {}
    4396         106 :     virtual ~SvNullStream() {}
    4397             : };
    4398             : 
    4399          54 : EscherEx::EscherEx( const EscherExGlobalRef& rxGlobal, SvStream* pOutStrm ) :
    4400             :     mxGlobal                ( rxGlobal ),
    4401             :     mpOutStrm               ( pOutStrm ),
    4402             :     mbOwnsStrm              ( false ),
    4403             : 
    4404             :     mnCurrentDg                         ( 0 ),
    4405             : 
    4406             :     mnGroupLevel            ( 0 ),
    4407             :     mnHellLayerId           ( USHRT_MAX ),
    4408             : 
    4409             :     mbEscherSpgr            ( sal_False ),
    4410          54 :     mbEscherDg              ( sal_False )
    4411             : {
    4412          54 :     if (!mpOutStrm)
    4413             :     {
    4414          53 :         mpOutStrm = new SvNullStream();
    4415          53 :         mbOwnsStrm = true;
    4416             :     }
    4417          54 :     mnStrmStartOfs = mpOutStrm->Tell();
    4418          54 :     mpImplEscherExSdr.reset( new ImplEscherExSdr( *this ) );
    4419          54 : }
    4420             : 
    4421         108 : EscherEx::~EscherEx()
    4422             : {
    4423          54 :     if (mbOwnsStrm)
    4424          53 :         delete mpOutStrm;
    4425          54 : }
    4426             : 
    4427           1 : void EscherEx::Flush( SvStream* pPicStreamMergeBSE /* = NULL */ )
    4428             : {
    4429           1 :     if ( mxGlobal->HasDggContainer() )
    4430             :     {
    4431             :         // store the current stream position at ESCHER_Persist_CurrentPosition key
    4432           1 :         PtReplaceOrInsert( ESCHER_Persist_CurrentPosition, mpOutStrm->Tell() );
    4433           1 :         if ( DoSeek( ESCHER_Persist_Dgg ) )
    4434             :         {
    4435             :             /*  The DGG record is still not written. ESCHER_Persist_Dgg seeks
    4436             :                 to the place where the complete record has to be inserted. */
    4437           1 :             InsertAtCurrentPos( mxGlobal->GetDggAtomSize(), false );
    4438           1 :             mxGlobal->WriteDggAtom( *mpOutStrm );
    4439             : 
    4440           1 :             if ( mxGlobal->HasGraphics() )
    4441             :             {
    4442             :                 /*  Calculate the total size of the BSTORECONTAINER including
    4443             :                     all BSE records containing the picture data contained in
    4444             :                     the passed in pPicStreamMergeBSE. */
    4445           0 :                 sal_uInt32 nBSCSize = mxGlobal->GetBlibStoreContainerSize( pPicStreamMergeBSE );
    4446           0 :                 if ( nBSCSize > 0 )
    4447             :                 {
    4448           0 :                     InsertAtCurrentPos( nBSCSize, false );
    4449           0 :                     mxGlobal->WriteBlibStoreContainer( *mpOutStrm, pPicStreamMergeBSE );
    4450             :                 }
    4451             :             }
    4452             : 
    4453             :             /*  Forget the stream position stored for the DGG which is invalid
    4454             :                 after the call to InsertAtCurrentPos() anyway. */
    4455           1 :             PtDelete( ESCHER_Persist_Dgg );
    4456             :         }
    4457             :         // seek to initial position (may be different due to inserted DGG and BLIPs)
    4458           1 :         mpOutStrm->Seek( PtGetOffsetByID( ESCHER_Persist_CurrentPosition ) );
    4459             :     }
    4460           1 : }
    4461             : 
    4462           1 : void EscherEx::InsertAtCurrentPos( sal_uInt32 nBytes, bool bExpandEndOfAtom )
    4463             : {
    4464           1 :     sal_uInt32  nSize, nType, nSource, nBufSize, nToCopy, nCurPos = mpOutStrm->Tell();
    4465             :     sal_uInt8*  pBuf;
    4466             : 
    4467             :     // Persist table anpassen
    4468           7 :     for( size_t i = 0, n = maPersistTable.size(); i < n; ++i ) {
    4469           6 :         EscherPersistEntry* pPtr = maPersistTable[ i ];
    4470           6 :         sal_uInt32 nOfs = pPtr->mnOffset;
    4471           6 :         if ( nOfs >= nCurPos ) {
    4472           5 :             pPtr->mnOffset += nBytes;
    4473             :         }
    4474             :     }
    4475             : 
    4476             :     // adapt container and atom sizes
    4477           1 :     mpOutStrm->Seek( mnStrmStartOfs );
    4478           3 :     while ( mpOutStrm->Tell() < nCurPos )
    4479             :     {
    4480           1 :         *mpOutStrm >> nType >> nSize;
    4481           1 :         sal_uInt32 nEndOfRecord = mpOutStrm->Tell() + nSize;
    4482           1 :         bool bContainer = (nType & 0x0F) == 0x0F;
    4483             :         /*  Expand the record, if the insertion position is inside, or if the
    4484             :             position is at the end of a container (expands always), or at the
    4485             :             end of an atom and bExpandEndOfAtom is set. */
    4486           1 :         if ( (nCurPos < nEndOfRecord) || ((nCurPos == nEndOfRecord) && (bContainer || bExpandEndOfAtom)) )
    4487             :         {
    4488           1 :             mpOutStrm->SeekRel( -4 );
    4489           1 :             *mpOutStrm << (sal_uInt32)( nSize + nBytes );
    4490           2 :             if ( !bContainer )
    4491           0 :                 mpOutStrm->SeekRel( nSize );
    4492             :         }
    4493             :         else
    4494           0 :             mpOutStrm->SeekRel( nSize );
    4495             :     }
    4496           1 :     std::vector< sal_uInt32 >::iterator aIter( mOffsets.begin() );
    4497           1 :     std::vector< sal_uInt32 >::iterator aEnd( mOffsets.end() );
    4498           2 :     while( aIter != aEnd )
    4499             :     {
    4500           0 :         if ( *aIter > nCurPos )
    4501           0 :             *aIter += nBytes;
    4502           0 :         aIter++;
    4503             :     }
    4504           1 :     mpOutStrm->Seek( STREAM_SEEK_TO_END );
    4505           1 :     nSource = mpOutStrm->Tell();
    4506           1 :     nToCopy = nSource - nCurPos;                        // increase the size of the tream by nBytes
    4507           1 :     pBuf = new sal_uInt8[ 0x40000 ];                            // 256KB Buffer
    4508           3 :     while ( nToCopy )
    4509             :     {
    4510           1 :         nBufSize = ( nToCopy >= 0x40000 ) ? 0x40000 : nToCopy;
    4511           1 :         nToCopy -= nBufSize;
    4512           1 :         nSource -= nBufSize;
    4513           1 :         mpOutStrm->Seek( nSource );
    4514           1 :         mpOutStrm->Read( pBuf, nBufSize );
    4515           1 :         mpOutStrm->Seek( nSource + nBytes );
    4516           1 :         mpOutStrm->Write( pBuf, nBufSize );
    4517             :     }
    4518           1 :     delete[] pBuf;
    4519           1 :     mpOutStrm->Seek( nCurPos );
    4520           1 : }
    4521             : 
    4522           0 : sal_Bool EscherEx::SeekBehindRecHeader( sal_uInt16 nRecType )
    4523             : {
    4524             :     sal_uInt32  nOldPos, nStreamEnd, nType, nSize;
    4525             : 
    4526           0 :     nOldPos = mpOutStrm->Tell();
    4527           0 :     nStreamEnd = mpOutStrm->Seek( STREAM_SEEK_TO_END );
    4528           0 :     mpOutStrm->Seek( nOldPos );
    4529           0 :     while ( mpOutStrm->Tell() < nStreamEnd )
    4530             :     {
    4531           0 :         *mpOutStrm >> nType >> nSize;
    4532           0 :         if ( ( nType >> 16 ) == nRecType )
    4533           0 :             return sal_True;
    4534           0 :         if ( ( nType & 0xf ) != 0xf )
    4535           0 :             mpOutStrm->SeekRel( nSize );
    4536             :     }
    4537           0 :     mpOutStrm->Seek( nOldPos );
    4538           0 :     return sal_False;
    4539             : }
    4540             : 
    4541           3 : void EscherEx::InsertPersistOffset( sal_uInt32 nKey, sal_uInt32 nOffset )
    4542             : {
    4543           3 :     PtInsert( ESCHER_Persist_PrivateEntry | nKey, nOffset );
    4544           3 : }
    4545             : 
    4546           2 : void EscherEx::ReplacePersistOffset( sal_uInt32 nKey, sal_uInt32 nOffset )
    4547             : {
    4548           2 :     PtReplace( ESCHER_Persist_PrivateEntry | nKey, nOffset );
    4549           2 : }
    4550             : 
    4551           1 : sal_uInt32 EscherEx::GetPersistOffset( sal_uInt32 nKey )
    4552             : {
    4553           1 :     return PtGetOffsetByID( ESCHER_Persist_PrivateEntry | nKey );
    4554             : }
    4555             : 
    4556           2 : sal_Bool EscherEx::DoSeek( sal_uInt32 nKey )
    4557             : {
    4558           2 :     sal_uInt32 nPos = PtGetOffsetByID( nKey );
    4559           2 :     if ( nPos )
    4560           2 :         mpOutStrm->Seek( nPos );
    4561             :     else
    4562             :     {
    4563           0 :         if (! PtIsID( nKey ) )
    4564           0 :             return sal_False;
    4565           0 :         mpOutStrm->Seek( 0 );
    4566             :     }
    4567           2 :     return sal_True;
    4568             : }
    4569             : 
    4570           0 : sal_Bool EscherEx::SeekToPersistOffset( sal_uInt32 nKey )
    4571             : {
    4572           0 :     return DoSeek( ESCHER_Persist_PrivateEntry | nKey );
    4573             : }
    4574             : 
    4575           0 : sal_Bool EscherEx::InsertAtPersistOffset( sal_uInt32 nKey, sal_uInt32 nValue )
    4576             : {
    4577           0 :     sal_uInt32  nOldPos = mpOutStrm->Tell();
    4578           0 :     sal_Bool    bRetValue = SeekToPersistOffset( nKey );
    4579           0 :     if ( bRetValue )
    4580             :     {
    4581           0 :         *mpOutStrm << nValue;
    4582           0 :         mpOutStrm->Seek( nOldPos );
    4583             :     }
    4584           0 :     return bRetValue;
    4585             : }
    4586             : 
    4587           5 : void EscherEx::OpenContainer( sal_uInt16 nEscherContainer, int nRecInstance )
    4588             : {
    4589           5 :     *mpOutStrm << (sal_uInt16)( ( nRecInstance << 4 ) | 0xf  ) << nEscherContainer << (sal_uInt32)0;
    4590           5 :     mOffsets.push_back( mpOutStrm->Tell() - 4 );
    4591           5 :     mRecTypes.push_back( nEscherContainer );
    4592           5 :     switch( nEscherContainer )
    4593             :     {
    4594             :         case ESCHER_DggContainer :
    4595             :         {
    4596           1 :             mxGlobal->SetDggContainer();
    4597           1 :             mnCurrentDg = 0;
    4598             :             /*  Remember the current position as start position of the DGG
    4599             :                 record and BSTORECONTAINER, but do not write them actually.
    4600             :                 This will be done later in Flush() when the number of drawings,
    4601             :                 the size and contents of the FIDCL cluster table, and the size
    4602             :                 of the BLIP container are known. */
    4603           1 :             PtReplaceOrInsert( ESCHER_Persist_Dgg, mpOutStrm->Tell() );
    4604             :         }
    4605           1 :         break;
    4606             : 
    4607             :         case ESCHER_DgContainer :
    4608             :         {
    4609           1 :             if ( mxGlobal->HasDggContainer() )
    4610             :             {
    4611           1 :                 if ( !mbEscherDg )
    4612             :                 {
    4613           1 :                     mbEscherDg = sal_True;
    4614           1 :                     mnCurrentDg = mxGlobal->GenerateDrawingId();
    4615           1 :                     AddAtom( 8, ESCHER_Dg, 0, mnCurrentDg );
    4616           1 :                     PtReplaceOrInsert( ESCHER_Persist_Dg | mnCurrentDg, mpOutStrm->Tell() );
    4617           1 :                     *mpOutStrm << (sal_uInt32)0     // The number of shapes in this drawing
    4618           1 :                                << (sal_uInt32)0;    // The last MSOSPID given to an SP in this DG
    4619             :                 }
    4620             :             }
    4621             :         }
    4622           1 :         break;
    4623             : 
    4624             :         case ESCHER_SpgrContainer :
    4625             :         {
    4626           1 :             if ( mbEscherDg )
    4627             :             {
    4628           1 :                 mbEscherSpgr = sal_True;
    4629             :             }
    4630             :         }
    4631           1 :         break;
    4632             : 
    4633             :         case ESCHER_SpContainer :
    4634             :         {
    4635             :         }
    4636           2 :         break;
    4637             : 
    4638             :         default:
    4639           0 :         break;
    4640             :     }
    4641           5 : }
    4642             : 
    4643           5 : void EscherEx::CloseContainer()
    4644             : {
    4645           5 :     sal_uInt32 nSize, nPos = mpOutStrm->Tell();
    4646           5 :     nSize = ( nPos - mOffsets.back() ) - 4;
    4647           5 :     mpOutStrm->Seek( mOffsets.back() );
    4648           5 :     *mpOutStrm << nSize;
    4649             : 
    4650           5 :     switch( mRecTypes.back() )
    4651             :     {
    4652             :         case ESCHER_DgContainer :
    4653             :         {
    4654           1 :             if ( mbEscherDg )
    4655             :             {
    4656           1 :                 mbEscherDg = sal_False;
    4657           1 :                 if ( DoSeek( ESCHER_Persist_Dg | mnCurrentDg ) )
    4658           1 :                     *mpOutStrm << mxGlobal->GetDrawingShapeCount( mnCurrentDg ) << mxGlobal->GetLastShapeId( mnCurrentDg );
    4659             :             }
    4660             :         }
    4661           1 :         break;
    4662             : 
    4663             :         case ESCHER_SpgrContainer :
    4664             :         {
    4665           1 :             if ( mbEscherSpgr )
    4666             :             {
    4667           1 :                 mbEscherSpgr = sal_False;
    4668             : 
    4669             :             }
    4670             :         }
    4671           1 :         break;
    4672             : 
    4673             :         default:
    4674           3 :         break;
    4675             :     }
    4676           5 :     mOffsets.pop_back();
    4677           5 :     mRecTypes.pop_back();
    4678           5 :     mpOutStrm->Seek( nPos );
    4679           5 : }
    4680             : 
    4681           0 : void EscherEx::BeginAtom()
    4682             : {
    4683           0 :     mnCountOfs = mpOutStrm->Tell();
    4684           0 :     *mpOutStrm << (sal_uInt32)0 << (sal_uInt32)0;       // record header wird spaeter geschrieben
    4685           0 : }
    4686             : 
    4687           0 : void EscherEx::EndAtom( sal_uInt16 nRecType, int nRecVersion, int nRecInstance )
    4688             : {
    4689           0 :     sal_uInt32  nOldPos = mpOutStrm->Tell();
    4690           0 :     mpOutStrm->Seek( mnCountOfs );
    4691           0 :     sal_uInt32 nSize = nOldPos - mnCountOfs;
    4692           0 :     *mpOutStrm << (sal_uInt16)( ( nRecInstance << 4 ) | ( nRecVersion & 0xf ) ) << nRecType << (sal_uInt32)( nSize - 8 );
    4693           0 :     mpOutStrm->Seek( nOldPos );
    4694           0 : }
    4695             : 
    4696           5 : void EscherEx::AddAtom( sal_uInt32 nAtomSize, sal_uInt16 nRecType, int nRecVersion, int nRecInstance )
    4697             : {
    4698           5 :     *mpOutStrm << (sal_uInt16)( ( nRecInstance << 4 ) | ( nRecVersion & 0xf ) ) << nRecType << nAtomSize;
    4699           5 : }
    4700             : 
    4701           0 : void EscherEx::AddChildAnchor( const Rectangle& rRect )
    4702             : {
    4703           0 :     AddAtom( 16, ESCHER_ChildAnchor );
    4704           0 :     *mpOutStrm  << (sal_Int32)rRect.Left()
    4705           0 :                 << (sal_Int32)rRect.Top()
    4706           0 :                 << (sal_Int32)rRect.Right()
    4707           0 :                 << (sal_Int32)rRect.Bottom();
    4708           0 : }
    4709             : 
    4710           0 : void EscherEx::AddClientAnchor( const Rectangle& rRect )
    4711             : {
    4712           0 :     AddAtom( 8, ESCHER_ClientAnchor );
    4713           0 :     *mpOutStrm << (sal_Int16)rRect.Top()
    4714           0 :                << (sal_Int16)rRect.Left()
    4715           0 :                << (sal_Int16)( rRect.GetWidth()  + rRect.Left() )
    4716           0 :                << (sal_Int16)( rRect.GetHeight() + rRect.Top() );
    4717           0 : }
    4718             : 
    4719           0 : EscherExHostAppData* EscherEx::EnterAdditionalTextGroup()
    4720             : {
    4721           0 :     return NULL;
    4722             : }
    4723             : 
    4724           1 : sal_uInt32 EscherEx::EnterGroup( const String& rShapeName, const Rectangle* pBoundRect )
    4725             : {
    4726           1 :     Rectangle aRect;
    4727           1 :     if( pBoundRect )
    4728           1 :         aRect = *pBoundRect;
    4729             : 
    4730           1 :     OpenContainer( ESCHER_SpgrContainer );
    4731           1 :     OpenContainer( ESCHER_SpContainer );
    4732           1 :     AddAtom( 16, ESCHER_Spgr, 1 );
    4733             :     PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap | mnGroupLevel,
    4734           1 :                         mpOutStrm->Tell() );
    4735           1 :     *mpOutStrm  << (sal_Int32)aRect.Left()  // Bounding box for the grouped shapes the wich they will be attached
    4736           2 :                 << (sal_Int32)aRect.Top()
    4737           2 :                 << (sal_Int32)aRect.Right()
    4738           2 :                 << (sal_Int32)aRect.Bottom();
    4739             : 
    4740           1 :     sal_uInt32 nShapeId = GenerateShapeId();
    4741           1 :     if ( !mnGroupLevel )
    4742           1 :         AddShape( ESCHER_ShpInst_Min, 5, nShapeId );                    // Flags: Group | Patriarch
    4743             :     else
    4744             :     {
    4745           0 :         AddShape( ESCHER_ShpInst_Min, 0x201, nShapeId );                // Flags: Group | HaveAnchor
    4746           0 :         EscherPropertyContainer aPropOpt;
    4747           0 :         aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x00040004 );
    4748           0 :         aPropOpt.AddOpt( ESCHER_Prop_dxWrapDistLeft, 0 );
    4749           0 :         aPropOpt.AddOpt( ESCHER_Prop_dxWrapDistRight, 0 );
    4750             : 
    4751             :         // #i51348# shape name
    4752           0 :         if( rShapeName.Len() > 0 )
    4753           0 :             aPropOpt.AddOpt( ESCHER_Prop_wzName, rShapeName );
    4754             : 
    4755           0 :         Commit( aPropOpt, aRect );
    4756           0 :         if ( mnGroupLevel > 1 )
    4757           0 :             AddChildAnchor( aRect );
    4758             : 
    4759           0 :         EscherExHostAppData* pAppData = mpImplEscherExSdr->ImplGetHostData();
    4760           0 :         if( pAppData )
    4761             :         {
    4762           0 :             if ( mnGroupLevel <= 1 )
    4763           0 :                 pAppData->WriteClientAnchor( *this, aRect );
    4764           0 :             pAppData->WriteClientData( *this );
    4765           0 :         }
    4766             :     }
    4767           1 :     CloseContainer();                                               // ESCHER_SpContainer
    4768           1 :     mnGroupLevel++;
    4769           1 :     return nShapeId;
    4770             : }
    4771             : 
    4772           1 : sal_uInt32 EscherEx::EnterGroup( const Rectangle* pBoundRect )
    4773             : {
    4774           1 :     return EnterGroup( String::EmptyString(), pBoundRect );
    4775             : }
    4776             : 
    4777           0 : sal_Bool EscherEx::SetGroupSnapRect( sal_uInt32 nGroupLevel, const Rectangle& rRect )
    4778             : {
    4779           0 :     sal_Bool bRetValue = sal_False;
    4780           0 :     if ( nGroupLevel )
    4781             :     {
    4782           0 :         sal_uInt32 nCurrentPos = mpOutStrm->Tell();
    4783           0 :         if ( DoSeek( ESCHER_Persist_Grouping_Snap | ( nGroupLevel - 1 ) ) )
    4784             :         {
    4785           0 :             *mpOutStrm  << (sal_Int32)rRect.Left()  // Bounding box for the grouped shapes the wich they will be attached
    4786           0 :                         << (sal_Int32)rRect.Top()
    4787           0 :                         << (sal_Int32)rRect.Right()
    4788           0 :                         << (sal_Int32)rRect.Bottom();
    4789           0 :             mpOutStrm->Seek( nCurrentPos );
    4790             :         }
    4791             :     }
    4792           0 :     return bRetValue;
    4793             : }
    4794             : 
    4795           0 : sal_Bool EscherEx::SetGroupLogicRect( sal_uInt32 nGroupLevel, const Rectangle& rRect )
    4796             : {
    4797           0 :     sal_Bool bRetValue = sal_False;
    4798           0 :     if ( nGroupLevel )
    4799             :     {
    4800           0 :         sal_uInt32 nCurrentPos = mpOutStrm->Tell();
    4801           0 :         if ( DoSeek( ESCHER_Persist_Grouping_Logic | ( nGroupLevel - 1 ) ) )
    4802             :         {
    4803           0 :             *mpOutStrm << (sal_Int16)rRect.Top() << (sal_Int16)rRect.Left() << (sal_Int16)rRect.Right() << (sal_Int16)rRect.Bottom();
    4804           0 :             mpOutStrm->Seek( nCurrentPos );
    4805             :         }
    4806             :     }
    4807           0 :     return bRetValue;
    4808             : }
    4809             : 
    4810           1 : void EscherEx::LeaveGroup()
    4811             : {
    4812           1 :     --mnGroupLevel;
    4813           1 :     PtDelete( ESCHER_Persist_Grouping_Snap | mnGroupLevel );
    4814           1 :     PtDelete( ESCHER_Persist_Grouping_Logic | mnGroupLevel );
    4815           1 :     CloseContainer();
    4816           1 : }
    4817             : 
    4818           1 : void EscherEx::AddShape( sal_uInt32 nShpInstance, sal_uInt32 nFlags, sal_uInt32 nShapeID )
    4819             : {
    4820           1 :     AddAtom( 8, ESCHER_Sp, 2, nShpInstance );
    4821             : 
    4822           1 :     if ( !nShapeID )
    4823           0 :         nShapeID = GenerateShapeId();
    4824             : 
    4825           1 :     if ( nFlags ^ 1 )                           // is this a group shape ?
    4826             :     {                                           // if not
    4827           1 :         if ( mnGroupLevel > 1 )
    4828           0 :             nFlags |= 2;                        // this not a topmost shape
    4829             :     }
    4830           1 :     *mpOutStrm << nShapeID << nFlags;
    4831           1 : }
    4832             : 
    4833           0 : void EscherEx::Commit( EscherPropertyContainer& rProps, const Rectangle& )
    4834             : {
    4835           0 :     rProps.Commit( GetStream() );
    4836           0 : }
    4837             : 
    4838           0 : sal_uInt32 EscherEx::GetColor( const sal_uInt32 nSOColor, sal_Bool bSwap )
    4839             : {
    4840           0 :     if ( bSwap )
    4841             :     {
    4842           0 :         sal_uInt32 nColor = nSOColor & 0xff00;          // Green
    4843           0 :         nColor |= (sal_uInt8)( nSOColor ) << 16;        // Red
    4844           0 :         nColor |= (sal_uInt8)( nSOColor >> 16 );        // Blue
    4845           0 :         return nColor;
    4846             :     }
    4847             :     else
    4848           0 :         return nSOColor & 0xffffff;
    4849             : }
    4850             : 
    4851           0 : sal_uInt32 EscherEx::GetColor( const Color& rSOColor, sal_Bool bSwap )
    4852             : {
    4853           0 :     sal_uInt32 nColor = ( rSOColor.GetRed() << 16 );
    4854           0 :     nColor |= ( rSOColor.GetGreen() << 8 );
    4855           0 :     nColor |= rSOColor.GetBlue();
    4856             : 
    4857           0 :     if ( !bSwap )
    4858           0 :         nColor = GetColor( nColor, sal_True );
    4859             : 
    4860           0 :     return nColor;
    4861             : }
    4862             : 
    4863             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10