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

Generated by: LCOV version 1.10