LCOV - code coverage report
Current view: top level - svx/source/customshapes - EnhancedCustomShape2d.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 815 1238 65.8 %
Date: 2014-11-03 Functions: 30 35 85.7 %
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 "svx/EnhancedCustomShape2d.hxx"
      21             : #include "svx/EnhancedCustomShapeGeometry.hxx"
      22             : #include "svx/EnhancedCustomShapeTypeNames.hxx"
      23             : #include <svx/svdoashp.hxx>
      24             : #include <svx/svdtrans.hxx>
      25             : #include <svx/svdocirc.hxx>
      26             : #include <svx/svdogrp.hxx>
      27             : #include <svx/svdopath.hxx>
      28             : #include <svx/svdocapt.hxx>
      29             : #include <svx/svdpage.hxx>
      30             : #include <svx/xflclit.hxx>
      31             : #include <svx/sdasaitm.hxx>
      32             : #include <svx/svdmodel.hxx>
      33             : #include <rtl/crc.h>
      34             : #include <rtl/math.hxx>
      35             : #include <svx/xfillit0.hxx>
      36             : #include <svx/xlnstit.hxx>
      37             : #include <svx/xlnedit.hxx>
      38             : #include <svx/xlnstwit.hxx>
      39             : #include <svx/xlnedwit.hxx>
      40             : #include <svx/xlnstcit.hxx>
      41             : #include <svx/xlnedcit.hxx>
      42             : #include <svx/xflgrit.hxx>
      43             : #include <svx/xflhtit.hxx>
      44             : #include <svx/xbtmpit.hxx>
      45             : #include <svx/xgrad.hxx>
      46             : #include <svx/xhatch.hxx>
      47             : #include <com/sun/star/awt/Size.hpp>
      48             : #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
      49             : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
      50             : #include <boost/shared_ptr.hpp>
      51             : #include <basegfx/numeric/ftools.hxx>
      52             : #include <basegfx/color/bcolortools.hxx>
      53             : #include <basegfx/polygon/b2dpolygon.hxx>
      54             : #include <basegfx/polygon/b2dpolygontools.hxx>
      55             : #include <rtl/strbuf.hxx>
      56             : #include <math.h>
      57             : 
      58             : using namespace ::com::sun::star;
      59             : using namespace ::com::sun::star::uno;
      60             : using namespace ::com::sun::star::drawing;
      61             : using namespace ::com::sun::star::drawing::EnhancedCustomShapeSegmentCommand;
      62             : 
      63       29948 : void EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( EnhancedCustomShapeParameter& rParameter, const sal_Int32 nValue )
      64             : {
      65       29948 :     sal_uInt32 nDat = (sal_uInt32)nValue;
      66       29948 :     sal_Int32  nNewValue = nValue;
      67             : 
      68             :     // check if this is a special point
      69       29948 :     if ( ( nDat >> 16 ) == 0x8000 )
      70             :     {
      71        3018 :         nNewValue = (sal_uInt16)nDat;
      72        3018 :         rParameter.Type = EnhancedCustomShapeParameterType::EQUATION;
      73             :     }
      74             :     else
      75       26930 :         rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
      76       29948 :     rParameter.Value <<= nNewValue;
      77       29948 : }
      78             : 
      79        2962 : OUString EnhancedCustomShape2d::GetEquation( const sal_uInt16 nFlags, sal_Int32 nP1, sal_Int32 nP2, sal_Int32 nP3 )
      80             : {
      81        2962 :     OUString aEquation;
      82        2962 :     bool b1Special = ( nFlags & 0x2000 ) != 0;
      83        2962 :     bool b2Special = ( nFlags & 0x4000 ) != 0;
      84        2962 :     bool b3Special = ( nFlags & 0x8000 ) != 0;
      85        2962 :     switch( nFlags & 0xff )
      86             :     {
      87             :         case 0 :
      88             :         case 14 :
      89             :         {
      90        1308 :             sal_Int32 nOptimize = 0;
      91        1308 :             if ( nP1 )
      92        1282 :                 nOptimize |= 1;
      93        1308 :             if ( nP2 )
      94         380 :                 nOptimize |= 2;
      95        1308 :             if ( b1Special )
      96         950 :                 nOptimize |= 4;
      97        1308 :             if ( b2Special )
      98         184 :                 nOptimize |= 8;
      99        1308 :             switch( nOptimize )
     100             :             {
     101             :                 case 0 :
     102           0 :                 break;
     103             :                 case 1 :
     104             :                 case 4 :
     105             :                 case 5 :
     106         928 :                     EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     107         928 :                 break;
     108             :                 case 2 :
     109             :                 case 8 :
     110             :                 case 10:
     111          26 :                     EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     112          26 :                 break;
     113             :                 default :
     114             :                 {
     115         354 :                     EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     116         354 :                     aEquation += OUString( (sal_Unicode)'+' );
     117         354 :                     EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     118             :                 }
     119         354 :                 break;
     120             :             }
     121        1308 :             if ( b3Special || nP3 )
     122             :             {
     123         674 :                 aEquation += OUString( (sal_Unicode)'-' );
     124         674 :                 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     125             :             }
     126             :         }
     127        1308 :         break;
     128             :         case 1 :
     129             :         {
     130         346 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     131         346 :             if ( b2Special || ( nP2 != 1 ) )
     132             :             {
     133         252 :                 aEquation += OUString( (sal_Unicode)'*' );
     134         252 :                 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     135             :             }
     136         346 :             if ( b3Special || ( ( nP3 != 1 ) && ( nP3 != 0 ) ) )
     137             :             {
     138         248 :                 aEquation += OUString( (sal_Unicode)'/' );
     139         248 :                 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     140             :             }
     141             :         }
     142         346 :         break;
     143             :         case 2 :
     144             :         {
     145          12 :             aEquation += "(";
     146          12 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     147          12 :             aEquation += "+";
     148          12 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     149          12 :             aEquation += ")/2";
     150             :         }
     151          12 :         break;
     152             :         case 3 :
     153             :         {
     154          76 :             aEquation += "abs(";
     155          76 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     156          76 :             aEquation += ")";
     157             :         }
     158          76 :         break;
     159             :         case 4 :
     160             :         {
     161           0 :             aEquation += "min(";
     162           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     163           0 :             aEquation += ",";
     164           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     165           0 :             aEquation += ")";
     166             :         }
     167           0 :         break;
     168             :         case 5 :
     169             :         {
     170           0 :             aEquation += "max(";
     171           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     172           0 :             aEquation += ",";
     173           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     174           0 :             aEquation += ")";
     175             :         }
     176           0 :         break;
     177             :         case 6 :
     178             :         {
     179         460 :             aEquation += "if(";
     180         460 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     181         460 :             aEquation += OUString( (sal_Unicode)',' );
     182         460 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     183         460 :             aEquation += OUString( (sal_Unicode)',' );
     184         460 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     185         460 :             aEquation += OUString( (sal_Unicode)')' );
     186             :         }
     187         460 :         break;
     188             :         case 7 :
     189             :         {
     190           0 :             aEquation += "sqrt(";
     191           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     192           0 :             aEquation += "*";
     193           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     194           0 :             aEquation += "+";
     195           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     196           0 :             aEquation += "*";
     197           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     198           0 :             aEquation += "+";
     199           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     200           0 :             aEquation += "*";
     201           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     202           0 :             aEquation += OUString( (sal_Unicode)')' );
     203             :         }
     204           0 :         break;
     205             :         case 8 :
     206             :         {
     207           6 :             aEquation += "atan2(";
     208           6 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     209           6 :             aEquation += ",";
     210           6 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     211           6 :             aEquation += ")/(pi/180)";
     212             :         }
     213           6 :         break;
     214             :         case 9 :
     215             :         {
     216          50 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     217          50 :             aEquation += "*sin(";
     218          50 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     219          50 :             aEquation += "*(pi/180))";
     220             :         }
     221          50 :         break;
     222             :         case 10 :
     223             :         {
     224          36 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     225          36 :             aEquation += "*cos(";
     226          36 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     227          36 :             aEquation += "*(pi/180))";
     228             :         }
     229          36 :         break;
     230             :         case 11 :
     231             :         {
     232           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     233           0 :             aEquation += "*cos(atan2(";
     234           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     235           0 :             aEquation += ",";
     236           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     237           0 :             aEquation += "))";
     238             :         }
     239           0 :         break;
     240             :         case 12 :
     241             :         {
     242           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     243           0 :             aEquation += "*sin(atan2(";
     244           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     245           0 :             aEquation += ",";
     246           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     247           0 :             aEquation += "))";
     248             :         }
     249           0 :         break;
     250             :         case 13 :
     251             :         {
     252          12 :             aEquation += "sqrt(";
     253          12 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     254          12 :             aEquation += ")";
     255             :         }
     256          12 :         break;
     257             :         case 15 :
     258             :         {
     259          24 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     260          24 :             aEquation += "*sqrt(1-(";
     261          24 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     262          24 :             aEquation += "/";
     263          24 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     264          24 :             aEquation += ")";
     265          24 :             aEquation += "*(";
     266          24 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     267          24 :             aEquation += "/";
     268          24 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     269          24 :             aEquation += "))";
     270             :         }
     271          24 :         break;
     272             :         case 16 :
     273             :         {
     274           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     275           0 :             aEquation += "*tan(";
     276           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     277           0 :             aEquation += ")";
     278             :         }
     279           0 :         break;
     280             :         case 0x80 :
     281             :         {
     282           0 :             aEquation += "sqrt(";
     283           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     284           0 :             aEquation += "*";
     285           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     286           0 :             aEquation += "-";
     287           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     288           0 :             aEquation += "*";
     289           0 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     290           0 :             aEquation += OUString( (sal_Unicode)')' );
     291             :         }
     292           0 :         break;
     293             :         case 0x81 :
     294             :         {
     295         318 :             aEquation += "(cos(";
     296         318 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     297         318 :             aEquation += "*(pi/180))*(";
     298         318 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     299         318 :             aEquation += "-10800)+sin(";
     300         318 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     301         318 :             aEquation += "*(pi/180))*(";
     302         318 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     303         318 :             aEquation += "-10800))+10800";
     304             :         }
     305         318 :         break;
     306             :         case 0x82 :
     307             :         {
     308         314 :             aEquation += "-(sin(";
     309         314 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     310         314 :             aEquation += "*(pi/180))*(";
     311         314 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
     312         314 :             aEquation += "-10800)-cos(";
     313         314 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
     314         314 :             aEquation += "*(pi/180))*(";
     315         314 :             EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
     316         314 :             aEquation += "-10800))+10800";
     317             :         }
     318         314 :         break;
     319             :     }
     320        2962 :     return aEquation;
     321             : }
     322             : 
     323        7506 : void EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( OUString& rParameter, const sal_Int32 nPara, const bool bIsSpecialValue )
     324             : {
     325        7506 :     if ( bIsSpecialValue )
     326             :     {
     327        3656 :         if ( nPara & 0x400 )
     328             :         {
     329        2594 :             rParameter += "?";
     330        2594 :             rParameter += OUString::number( ( nPara & 0xff ) );
     331        2594 :             rParameter += " ";
     332             :         }
     333             :         else
     334             :         {
     335        1062 :             switch( nPara )
     336             :             {
     337             :                 case DFF_Prop_adjustValue :
     338             :                 case DFF_Prop_adjust2Value :
     339             :                 case DFF_Prop_adjust3Value :
     340             :                 case DFF_Prop_adjust4Value :
     341             :                 case DFF_Prop_adjust5Value :
     342             :                 case DFF_Prop_adjust6Value :
     343             :                 case DFF_Prop_adjust7Value :
     344             :                 case DFF_Prop_adjust8Value :
     345             :                 case DFF_Prop_adjust9Value :
     346             :                 case DFF_Prop_adjust10Value :
     347             :                 {
     348         902 :                     rParameter += "$";
     349         902 :                     rParameter += OUString::number( ( nPara - DFF_Prop_adjustValue ) );
     350         902 :                     rParameter += " ";
     351             :                 }
     352         902 :                 break;
     353             :                 case DFF_Prop_geoLeft :
     354             :                 {
     355          32 :                     rParameter += "left";
     356             :                 }
     357          32 :                 break;
     358             :                 case DFF_Prop_geoTop :
     359             :                 {
     360          32 :                     rParameter += "top";
     361             :                 }
     362          32 :                 break;
     363             :                 case DFF_Prop_geoRight :
     364             :                 {
     365          46 :                     rParameter += "right";
     366             :                 }
     367          46 :                 break;
     368             :                 case DFF_Prop_geoBottom :
     369             :                 {
     370          50 :                     rParameter += "bottom";
     371             :                 }
     372          50 :                 break;
     373             :             }
     374             :         }
     375             :     }
     376             :     else
     377             :     {
     378        3850 :         rParameter += OUString::number( ( nPara ) );
     379             :     }
     380        7506 : }
     381             : 
     382         920 : void EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( EnhancedCustomShapeParameter& rParameter, const sal_Int32 nPara, const bool bIsSpecialValue, bool bHorz )
     383             : {
     384         920 :     sal_Int32 nValue = 0;
     385         920 :     if ( bIsSpecialValue )
     386             :     {
     387         516 :         if ( ( nPara >= 0x100 ) && ( nPara <= 0x107 ) )
     388             :         {
     389         286 :             nValue = nPara & 0xff;
     390         286 :             rParameter.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
     391             :         }
     392         230 :         else if ( ( nPara >= 3 ) && ( nPara <= 0x82 ) )
     393             :         {
     394          36 :             nValue = nPara - 3;
     395          36 :             rParameter.Type = EnhancedCustomShapeParameterType::EQUATION;
     396             :         }
     397         194 :         else if ( nPara == 0 )
     398             :         {
     399          48 :             nValue = 0;
     400          48 :             if ( bHorz )
     401          14 :                 rParameter.Type = EnhancedCustomShapeParameterType::LEFT;
     402             :             else
     403          34 :                 rParameter.Type = EnhancedCustomShapeParameterType::TOP;
     404             :         }
     405         146 :         else if ( nPara == 1 )
     406             :         {
     407           6 :             nValue = 0;
     408           6 :             if ( bHorz )
     409           6 :                 rParameter.Type = EnhancedCustomShapeParameterType::RIGHT;
     410             :             else
     411           0 :                 rParameter.Type = EnhancedCustomShapeParameterType::BOTTOM;
     412             :         }
     413         140 :         else if ( nPara == 2 )  // means to be centered, but should not be
     414             :         {                       // used in our implementation
     415           0 :             nValue = 5600;
     416           0 :             rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
     417             :         }
     418             :         else
     419             :         {
     420         140 :             nValue = nPara;
     421         140 :             rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
     422             :         }
     423             :     }
     424             :     else
     425             :     {
     426         404 :         nValue = nPara;
     427         404 :         rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
     428             :     }
     429         920 :     rParameter.Value <<= nValue;
     430         920 : }
     431             : 
     432         130 : bool EnhancedCustomShape2d::ConvertSequenceToEnhancedCustomShape2dHandle(
     433             :     const com::sun::star::beans::PropertyValues& rHandleProperties,
     434             :         EnhancedCustomShape2d::Handle& rDestinationHandle )
     435             : {
     436         130 :     bool bRetValue = false;
     437         130 :     sal_uInt32 i, nProperties = rHandleProperties.getLength();
     438         130 :     if ( nProperties )
     439             :     {
     440         130 :         rDestinationHandle.nFlags = 0;
     441         654 :         for ( i = 0; i < nProperties; i++ )
     442             :         {
     443         524 :             const com::sun::star::beans::PropertyValue& rPropVal = rHandleProperties[ i ];
     444             : 
     445         524 :             if ( rPropVal.Name == "Position" )
     446             :             {
     447         130 :                 if ( rPropVal.Value >>= rDestinationHandle.aPosition )
     448         130 :                     bRetValue = true;
     449             :             }
     450         394 :             else if ( rPropVal.Name == "MirroredX" )
     451             :             {
     452             :                 bool bMirroredX;
     453           0 :                 if ( rPropVal.Value >>= bMirroredX )
     454             :                 {
     455           0 :                     if ( bMirroredX )
     456           0 :                         rDestinationHandle.nFlags |= HANDLE_FLAGS_MIRRORED_X;
     457             :                 }
     458             :             }
     459         394 :             else if ( rPropVal.Name == "MirroredY" )
     460             :             {
     461             :                 bool bMirroredY;
     462           0 :                 if ( rPropVal.Value >>= bMirroredY )
     463             :                 {
     464           0 :                     if ( bMirroredY )
     465           0 :                         rDestinationHandle.nFlags |= HANDLE_FLAGS_MIRRORED_Y;
     466             :                 }
     467             :             }
     468         394 :             else if ( rPropVal.Name == "Switched" )
     469             :             {
     470             :                 bool bSwitched;
     471           0 :                 if ( rPropVal.Value >>= bSwitched )
     472             :                 {
     473           0 :                     if ( bSwitched )
     474           0 :                         rDestinationHandle.nFlags |= HANDLE_FLAGS_SWITCHED;
     475             :                 }
     476             :             }
     477         394 :             else if ( rPropVal.Name == "Polar" )
     478             :             {
     479           0 :                 if ( rPropVal.Value >>= rDestinationHandle.aPolar )
     480           0 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_POLAR;
     481             :             }
     482         394 :             else if ( rPropVal.Name == "RefX" )
     483             :             {
     484         110 :                 if ( rPropVal.Value >>= rDestinationHandle.nRefX )
     485         110 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_REFX;
     486             :             }
     487         284 :             else if ( rPropVal.Name == "RefY" )
     488             :             {
     489          16 :                 if ( rPropVal.Value >>= rDestinationHandle.nRefY )
     490          16 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_REFY;
     491             :             }
     492         268 :             else if ( rPropVal.Name == "RefAngle" )
     493             :             {
     494           0 :                 if ( rPropVal.Value >>= rDestinationHandle.nRefAngle )
     495           0 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_REFANGLE;
     496             :             }
     497         268 :             else if ( rPropVal.Name == "RefR" )
     498             :             {
     499           0 :                 if ( rPropVal.Value >>= rDestinationHandle.nRefR )
     500           0 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_REFR;
     501             :             }
     502         268 :             else if ( rPropVal.Name == "RadiusRangeMinimum" )
     503             :             {
     504           0 :                 if ( rPropVal.Value >>= rDestinationHandle.aRadiusRangeMinimum )
     505           0 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_RADIUS_RANGE_MINIMUM;
     506             :             }
     507         268 :             else if ( rPropVal.Name == "RadiusRangeMaximum" )
     508             :             {
     509           0 :                 if ( rPropVal.Value >>= rDestinationHandle.aRadiusRangeMaximum )
     510           0 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_RADIUS_RANGE_MAXIMUM;
     511             :             }
     512         268 :             else if ( rPropVal.Name == "RangeXMinimum" )
     513             :             {
     514         114 :                 if ( rPropVal.Value >>= rDestinationHandle.aXRangeMinimum )
     515         114 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_X_MINIMUM;
     516             :             }
     517         154 :             else if ( rPropVal.Name == "RangeXMaximum" )
     518             :             {
     519         114 :                 if ( rPropVal.Value >>= rDestinationHandle.aXRangeMaximum )
     520         114 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_X_MAXIMUM;
     521             :             }
     522          40 :             else if ( rPropVal.Name == "RangeYMinimum" )
     523             :             {
     524          20 :                 if ( rPropVal.Value >>= rDestinationHandle.aYRangeMinimum )
     525          20 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_Y_MINIMUM;
     526             :             }
     527          20 :             else if ( rPropVal.Name == "RangeYMaximum" )
     528             :             {
     529          20 :                 if ( rPropVal.Value >>= rDestinationHandle.aYRangeMaximum )
     530          20 :                     rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_Y_MAXIMUM;
     531             :             }
     532             :         }
     533             :     }
     534         130 :     return bRetValue;
     535             : }
     536             : 
     537       41610 : const sal_Int32* EnhancedCustomShape2d::ApplyShapeAttributes( const SdrCustomShapeGeometryItem& rGeometryItem )
     538             : {
     539       41610 :     const sal_Int32* pDefData = NULL;
     540       41610 :     const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
     541       41610 :     if ( pDefCustomShape )
     542       17488 :         pDefData = pDefCustomShape->pDefData;
     543             : 
     544             : 
     545             :     // AdjustmentValues
     546       41610 :     const Any* pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( "AdjustmentValues" );
     547       41610 :     if ( pAny )
     548       29606 :         *pAny >>= seqAdjustmentValues;
     549             : 
     550             : 
     551             :     // Coordsize
     552       41610 :     const Any* pViewBox = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( "ViewBox" );
     553       41610 :     com::sun::star::awt::Rectangle aViewBox;
     554       41610 :     if ( pViewBox && (*pViewBox >>= aViewBox ) )
     555             :     {
     556       27958 :         nCoordLeft    = aViewBox.X;
     557       27958 :         nCoordTop     = aViewBox.Y;
     558       27958 :         nCoordWidthG  = labs( aViewBox.Width );
     559       27958 :         nCoordHeightG = labs( aViewBox.Height);
     560             :     }
     561       41610 :     const OUString sPath( "Path" );
     562             : 
     563             : 
     564             :     // Path/Coordinates
     565       41610 :     pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "Coordinates" );
     566       41610 :     if ( pAny )
     567       27958 :         *pAny >>= seqCoordinates;
     568             : 
     569             : 
     570             :     // Path/GluePoints
     571       41610 :     pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "GluePoints" );
     572       41610 :     if ( pAny )
     573         252 :         *pAny >>= seqGluePoints;
     574             : 
     575             : 
     576             :     // Path/Segments
     577       41610 :     pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "Segments" );
     578       41610 :     if ( pAny )
     579       24272 :         *pAny >>= seqSegments;
     580             : 
     581             : 
     582             :     // Path/SubViewSize
     583       41610 :     pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "SubViewSize" );
     584       41610 :     if ( pAny )
     585        1136 :         *pAny >>= seqSubViewSize;
     586             : 
     587             : 
     588             :     // Path/StretchX
     589       41610 :     pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "StretchX" );
     590       41610 :     if ( pAny )
     591             :     {
     592          18 :         sal_Int32 nStretchX = 0;
     593          18 :         if ( *pAny >>= nStretchX )
     594          18 :             nXRef = nStretchX;
     595             :     }
     596             : 
     597             : 
     598             :     // Path/StretchY
     599       41610 :     pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "StretchY" );
     600       41610 :     if ( pAny )
     601             :     {
     602          18 :         sal_Int32 nStretchY = 0;
     603          18 :         if ( *pAny >>= nStretchY )
     604          18 :             nYRef = nStretchY;
     605             :     }
     606             : 
     607             : 
     608             :     // Path/TextFrames
     609       41610 :     pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "TextFrames" );
     610       41610 :     if ( pAny )
     611       23302 :         *pAny >>= seqTextFrames;
     612             : 
     613             : 
     614             :     // Equations
     615       41610 :     pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( "Equations" );
     616       41610 :     if ( pAny )
     617       23278 :         *pAny >>= seqEquations;
     618             : 
     619             : 
     620             :     // Handles
     621       41610 :     pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( "Handles" );
     622       41610 :     if ( pAny )
     623       23272 :         *pAny >>= seqHandles;
     624             : 
     625       41610 :     return pDefData;
     626             : }
     627             : 
     628       41610 : EnhancedCustomShape2d::~EnhancedCustomShape2d()
     629             : {
     630       41610 : }
     631             : 
     632       44676 : void EnhancedCustomShape2d::SetPathSize( sal_Int32 nIndex )
     633             : {
     634       44676 :     sal_Int32 nWidth = 0;
     635       44676 :     sal_Int32 nHeight = 0;
     636             : 
     637       44676 :     if ( seqSubViewSize.getLength() && nIndex < seqSubViewSize.getLength() ) {
     638        1774 :         nWidth = seqSubViewSize[ nIndex ].Width;
     639        1774 :         nHeight = seqSubViewSize[ nIndex ].Height;
     640             :         OSL_TRACE("set subpath %d size: %d x %d", nIndex, nWidth, nHeight);
     641             :     }
     642             : 
     643       44676 :     if ( nWidth && nHeight ) {
     644        1774 :         nCoordWidth = nWidth;
     645        1774 :         nCoordHeight = nHeight;
     646             :     } else {
     647       42902 :         nCoordWidth = nCoordWidthG;
     648       42902 :         nCoordHeight = nCoordHeightG;
     649             :     }
     650             : 
     651       44676 :     fXScale = nCoordWidth == 0 ? 0.0 : (double)aLogicRect.GetWidth() / (double)nCoordWidth;
     652       44676 :     fYScale = nCoordHeight == 0 ? 0.0 : (double)aLogicRect.GetHeight() / (double)nCoordHeight;
     653       44676 :     if ( bOOXMLShape )
     654             :     {
     655             :         OSL_TRACE("ooxml shape, path width: %d height: %d", nCoordWidth, nCoordHeight);
     656       24374 :         if ( nCoordWidth == 0 )
     657       22600 :             fXScale = 1.0;
     658       24374 :         if ( nCoordHeight == 0 )
     659       22600 :             fYScale = 1.0;
     660             :     }
     661       44676 :     if ( (sal_uInt32)nXRef != 0x80000000 && aLogicRect.GetHeight() )
     662             :     {
     663          18 :         fXRatio = (double)aLogicRect.GetWidth() / (double)aLogicRect.GetHeight();
     664          18 :         if ( fXRatio > 1 )
     665          18 :             fXScale /= fXRatio;
     666             :         else
     667           0 :             fXRatio = 1.0;
     668             :     }
     669             :     else
     670       44658 :         fXRatio = 1.0;
     671       44676 :     if ( (sal_uInt32)nYRef != 0x80000000 && aLogicRect.GetWidth() )
     672             :     {
     673          18 :         fYRatio = (double)aLogicRect.GetHeight() / (double)aLogicRect.GetWidth();
     674          18 :         if ( fYRatio > 1 )
     675           0 :             fYScale /= fYRatio;
     676             :         else
     677          18 :             fYRatio = 1.0;
     678             :     }
     679             :     else
     680       44658 :         fYRatio = 1.0;
     681       44676 : }
     682             : 
     683       41610 : EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
     684       41610 :     SfxItemSet          ( pAObj->GetMergedItemSet() ),
     685             :     pCustomShapeObj     ( pAObj ),
     686             :     eSpType             ( mso_sptNil ),
     687             :     nCoordLeft          ( 0 ),
     688             :     nCoordTop           ( 0 ),
     689             :     nCoordWidthG        ( 21600 ),
     690             :     nCoordHeightG       ( 21600 ),
     691             :     bOOXMLShape         ( false ),
     692             :     nXRef               ( 0x80000000 ),
     693             :     nYRef               ( 0x80000000 ),
     694             :     nFlags              ( 0 ),
     695             :     nColorData          ( 0 ),
     696             :     bTextFlow           ( false ),
     697       41610 :     bFilled             ( static_cast<const XFillStyleItem&>(pAObj->GetMergedItem( XATTR_FILLSTYLE )).GetValue() != drawing::FillStyle_NONE ),
     698       41610 :     bStroked            ( static_cast<const XLineStyleItem&>(pAObj->GetMergedItem( XATTR_LINESTYLE )).GetValue() != XLINE_NONE ),
     699             :     bFlipH              ( false ),
     700      124830 :     bFlipV              ( false )
     701             : {
     702             :     // bTextFlow needs to be set before clearing the TextDirection Item
     703             : 
     704       41610 :     ClearItem( SDRATTR_TEXTDIRECTION ); //SJ: vertical writing is not required, by removing this item no outliner is created
     705             : 
     706             :     // #i105323# For 2D AtoShapes, the shadow attirbute does not need to be applied to any
     707             :     // of the constucted helper SdrObjects. This would lead to problems since the shadow
     708             :     // of one helper object would fall on one helper object behind it (e.g. with the
     709             :     // eyes of the smiley shape). This is not wanted; instead a single shadow 'behind'
     710             :     // the AutoShape visualisation is wanted. This is done with primitive functionailty
     711             :     // now in SdrCustomShapePrimitive2D::create2DDecomposition, but only for 2D objects
     712             :     // (see there and in EnhancedCustomShape3d::Create3DObject to read more).
     713             :     // This exception may be removed later when AutoShapes will create primitives directly.
     714             :     // So, currently remove the ShadowAttribute from the ItemSet to not apply it to any
     715             :     // 2D helper shape.
     716       41610 :     ClearItem(SDRATTR_SHADOW);
     717             : 
     718       41610 :     Point aP( pCustomShapeObj->GetSnapRect().Center() );
     719       41610 :     Size aS( pCustomShapeObj->GetLogicRect().GetSize() );
     720       41610 :     aP.X() -= aS.Width() / 2;
     721       41610 :     aP.Y() -= aS.Height() / 2;
     722       41610 :     aLogicRect = Rectangle( aP, aS );
     723             : 
     724       41610 :     OUString sShapeType;
     725       41610 :     const SdrCustomShapeGeometryItem& rGeometryItem = static_cast<const SdrCustomShapeGeometryItem&>(pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
     726       41610 :     const Any* pAny = rGeometryItem.GetPropertyValueByName( "Type" );
     727       41610 :     if ( pAny ) {
     728       29456 :         *pAny >>= sShapeType;
     729       29456 :         bOOXMLShape = ( sShapeType.startsWith("ooxml-") );
     730             :         OSL_TRACE("shape type: %s %d", OUStringToOString( sShapeType, RTL_TEXTENCODING_ASCII_US ).getStr(), bOOXMLShape);
     731             :     }
     732       41610 :     eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
     733             : 
     734       41610 :     pAny = rGeometryItem.GetPropertyValueByName( "MirroredX" );
     735       41610 :     if ( pAny )
     736       23362 :         *pAny >>= bFlipH;
     737       41610 :     pAny = rGeometryItem.GetPropertyValueByName( "MirroredY" );
     738       41610 :     if ( pAny )
     739       23430 :         *pAny >>= bFlipV;
     740             : 
     741       41610 :     if ( pCustomShapeObj->ISA( SdrObjCustomShape ) )    // should always be a SdrObjCustomShape, but you don't know
     742       41610 :         nRotateAngle = (sal_Int32)(static_cast<SdrObjCustomShape*>(pCustomShapeObj)->GetObjectRotation() * 100.0);
     743             :     else
     744           0 :          nRotateAngle = pCustomShapeObj->GetRotateAngle();
     745             : 
     746       41610 :     /*const sal_Int32* pDefData =*/ ApplyShapeAttributes( rGeometryItem );
     747       41610 :     SetPathSize();
     748             : 
     749       41610 :     switch( eSpType )
     750             :     {
     751           0 :         case mso_sptCan :                       nColorData = 0x20400000; break;
     752           0 :         case mso_sptCube :                      nColorData = 0x302e0000; break;
     753           0 :         case mso_sptActionButtonBlank :         nColorData = 0x502ce400; break;
     754           0 :         case mso_sptActionButtonHome :          nColorData = 0x702ce4ce; break;
     755           0 :         case mso_sptActionButtonHelp :          nColorData = 0x602ce4c0; break;
     756           0 :         case mso_sptActionButtonInformation :   nColorData = 0x702ce4c5; break;
     757           0 :         case mso_sptActionButtonBackPrevious :  nColorData = 0x602ce4c0; break;
     758           0 :         case mso_sptActionButtonForwardNext :   nColorData = 0x602ce4c0; break;
     759           0 :         case mso_sptActionButtonBeginning :     nColorData = 0x602ce4c0; break;
     760           0 :         case mso_sptActionButtonEnd :           nColorData = 0x602ce4c0; break;
     761           0 :         case mso_sptActionButtonReturn :        nColorData = 0x602ce4c0; break;
     762           0 :         case mso_sptActionButtonDocument :      nColorData = 0x702ce4ec; break;
     763           0 :         case mso_sptActionButtonSound :         nColorData = 0x602ce4c0; break;
     764           0 :         case mso_sptActionButtonMovie :         nColorData = 0x602ce4c0; break;
     765           2 :         case mso_sptBevel :                     nColorData = 0x502ce400; break;
     766           0 :         case mso_sptFoldedCorner :              nColorData = 0x20e00000; break;
     767           8 :         case mso_sptSmileyFace :                nColorData = 0x20e00000; break;
     768             :         case mso_sptNil :
     769             :         {
     770       33256 :             if( sShapeType.getLength() > 4 &&
     771       10462 :                 sShapeType.match( "col-" ))
     772             :             {
     773           0 :                 nColorData = sShapeType.copy( 4 ).toUInt32( 16 );
     774             :             }
     775             :         }
     776       22794 :         break;
     777             :         case mso_sptCurvedLeftArrow :
     778             :         case mso_sptCurvedRightArrow :
     779             :         case mso_sptCurvedUpArrow :
     780          30 :         case mso_sptCurvedDownArrow :           nColorData = 0x20d00000; break;
     781           0 :         case mso_sptRibbon2 :                   nColorData = 0x30ee0000; break;
     782           0 :         case mso_sptRibbon :                    nColorData = 0x30ee0000; break;
     783             : 
     784           0 :         case mso_sptEllipseRibbon2 :            nColorData = 0x30ee0000; break;
     785           0 :         case mso_sptEllipseRibbon :             nColorData = 0x30ee0000; break;
     786             : 
     787           0 :         case mso_sptVerticalScroll :            nColorData = 0x30ee0000; break;
     788           8 :         case mso_sptHorizontalScroll :          nColorData = 0x30ee0000; break;
     789             :         default:
     790       18768 :             break;
     791             :     }
     792             : 
     793       41610 :     sal_Int32 i, nLength = seqEquations.getLength();
     794             : 
     795       41610 :     if ( nLength )
     796             :     {
     797       23278 :         vNodesSharedPtr.resize( nLength );
     798       23278 :         vEquationResults.resize( nLength );
     799      276930 :         for ( i = 0; i < seqEquations.getLength(); i++ )
     800             :         {
     801      253652 :             vEquationResults[ i ].bReady = false;
     802             :             try
     803             :             {
     804      253652 :                 vNodesSharedPtr[ i ] = EnhancedCustomShape::FunctionParser::parseFunction( seqEquations[ i ], *this );
     805             :             }
     806           0 :             catch ( EnhancedCustomShape::ParseError& )
     807             :             {
     808             :                 OSL_TRACE("error: equation number: %d, parser failed ( %s )",
     809             :                           i, OUStringToOString( seqEquations[ i ], RTL_TEXTENCODING_ASCII_US ).getStr());
     810             :             }
     811             :         }
     812       41610 :     }
     813       41610 : }
     814       38912 : double EnhancedCustomShape2d::GetEnumFunc( const EnumFunc eFunc ) const
     815             : {
     816       38912 :     double fRet = 0.0;
     817       38912 :     switch( eFunc )
     818             :     {
     819        1902 :         case ENUM_FUNC_PI :         fRet = F_PI; break;
     820          14 :         case ENUM_FUNC_LEFT :       fRet = 0.0; break;
     821          14 :         case ENUM_FUNC_TOP :        fRet = 0.0; break;
     822          24 :         case ENUM_FUNC_RIGHT :      fRet = (double)nCoordWidth * fXRatio;   break;
     823          24 :         case ENUM_FUNC_BOTTOM :     fRet = (double)nCoordHeight * fYRatio; break;
     824           0 :         case ENUM_FUNC_XSTRETCH :   fRet = nXRef; break;
     825           0 :         case ENUM_FUNC_YSTRETCH :   fRet = nYRef; break;
     826           0 :         case ENUM_FUNC_HASSTROKE :  fRet = bStroked ? 1.0 : 0.0; break;
     827           0 :         case ENUM_FUNC_HASFILL :    fRet = bFilled ? 1.0 : 0.0; break;
     828           0 :         case ENUM_FUNC_WIDTH :      fRet = nCoordWidth; break;
     829           0 :         case ENUM_FUNC_HEIGHT :     fRet = nCoordHeight; break;
     830       18352 :         case ENUM_FUNC_LOGWIDTH :   fRet = aLogicRect.GetWidth(); break;
     831       18582 :         case ENUM_FUNC_LOGHEIGHT :  fRet = aLogicRect.GetHeight(); break;
     832             :     }
     833       38912 :     return fRet;
     834             : }
     835       12732 : double EnhancedCustomShape2d::GetAdjustValueAsDouble( const sal_Int32 nIndex ) const
     836             : {
     837       12732 :     double fNumber = 0.0;
     838       12732 :     if ( nIndex < seqAdjustmentValues.getLength() )
     839             :     {
     840       12732 :         if ( seqAdjustmentValues[ nIndex ].Value.getValueTypeClass() == TypeClass_DOUBLE )
     841           0 :             seqAdjustmentValues[ nIndex ].Value >>= fNumber;
     842             :         else
     843             :         {
     844       12732 :             sal_Int32 nNumber = 0;
     845       12732 :             seqAdjustmentValues[ nIndex ].Value >>= nNumber;
     846       12732 :             fNumber = (double)nNumber;
     847             :         }
     848             :     }
     849       12732 :     return fNumber;
     850             : }
     851       78976 : double EnhancedCustomShape2d::GetEquationValueAsDouble( const sal_Int32 nIndex ) const
     852             : {
     853       78976 :     double fNumber = 0.0;
     854             : #if OSL_DEBUG_LEVEL > 1
     855             :     static sal_uInt32 nLevel = 0;
     856             : #endif
     857       78976 :     if ( nIndex < (sal_Int32)vNodesSharedPtr.size() )
     858             :     {
     859       78976 :         if ( vNodesSharedPtr[ nIndex ].get() ) {
     860             : #if OSL_DEBUG_LEVEL > 1
     861             :             nLevel ++;
     862             : #endif
     863             :             try
     864             :             {
     865       78976 :                 if ( vEquationResults[ nIndex ].bReady )
     866       24196 :                     fNumber = vEquationResults[ nIndex ].fValue;
     867             :                 else {
     868             :                     // cast to non const, so that we can optimize by caching
     869             :                     // equation results, without changing all the const in the stack
     870       54780 :                     struct EquationResult &aResult = ((EnhancedCustomShape2d*)this)->vEquationResults[ nIndex ];
     871             : 
     872       54780 :                     fNumber = aResult.fValue = (*vNodesSharedPtr[ nIndex ])();
     873       54780 :                     aResult.bReady = true;
     874             : 
     875       54780 :                     if ( !rtl::math::isFinite( fNumber ) )
     876           0 :                         fNumber = 0.0;
     877             : #if OSL_DEBUG_LEVEL > 1
     878             :                     OSL_TRACE("equation %d (level: %d): %s --> %f (angle: %f)", nIndex,
     879             :                               nLevel, OUStringToOString( seqEquations[ nIndex ],
     880             :                                                          RTL_TEXTENCODING_ASCII_US ).getStr(), fNumber, 180.0*fNumber/10800000.0);
     881             : #endif
     882             :                 }
     883             :             }
     884           0 :             catch ( ... )
     885             :             {
     886             :                 OSL_TRACE("error: EnhancedCustomShape2d::GetEquationValueAsDouble failed");
     887             :             }
     888             : #if OSL_DEBUG_LEVEL > 1
     889             :         nLevel --;
     890             : #endif
     891             :         }
     892             :         OSL_TRACE("  ?%d --> %f (angle: %f)", nIndex,
     893             :                   fNumber, 180.0*fNumber/10800000.0);
     894             :     }
     895             : 
     896       78976 :     return fNumber;
     897             : }
     898           0 : sal_Int32 EnhancedCustomShape2d::GetAdjustValueAsInteger( const sal_Int32 nIndex, const sal_Int32 nDefault ) const
     899             : {
     900           0 :     sal_Int32 nNumber = nDefault;
     901           0 :     if ( nIndex < seqAdjustmentValues.getLength() )
     902             :     {
     903           0 :         if ( seqAdjustmentValues[ nIndex ].Value.getValueTypeClass() == TypeClass_DOUBLE )
     904             :         {
     905           0 :             double fNumber = 0;
     906           0 :             seqAdjustmentValues[ nIndex ].Value >>= fNumber;
     907           0 :             nNumber = (sal_Int32)fNumber;
     908             :         }
     909             :         else
     910           0 :             seqAdjustmentValues[ nIndex ].Value >>= nNumber;
     911             :     }
     912           0 :     return nNumber;
     913             : }
     914           0 : bool EnhancedCustomShape2d::SetAdjustValueAsDouble( const double& rValue, const sal_Int32 nIndex )
     915             : {
     916           0 :     bool bRetValue = false;
     917           0 :     if ( nIndex < seqAdjustmentValues.getLength() )
     918             :     {
     919             :         // updating our local adjustment sequence
     920           0 :         seqAdjustmentValues[ nIndex ].Value <<= rValue;
     921           0 :         seqAdjustmentValues[ nIndex ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
     922           0 :         bRetValue = true;
     923             :     }
     924           0 :     return bRetValue;
     925             : }
     926             : 
     927       38128 : Point EnhancedCustomShape2d::GetPoint( const com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPair,
     928             :                                         const bool bScale, const bool bReplaceGeoSize ) const
     929             : {
     930       38128 :     Point       aRetValue;
     931       38128 :     bool    bExchange = ( nFlags & DFF_CUSTOMSHAPE_EXCH ) != 0; // x <-> y
     932       38128 :     sal_uInt32  nPass = 0;
     933       76256 :     do
     934             :     {
     935       76256 :         sal_uInt32  nIndex = nPass;
     936             : 
     937       76256 :         if ( bExchange )
     938           0 :             nIndex ^= 1;
     939             : 
     940             :         double      fVal;
     941       76256 :         const EnhancedCustomShapeParameter& rParameter = nIndex ? rPair.Second : rPair.First;
     942       76256 :         if ( nPass )    // height
     943             :         {
     944       38128 :             GetParameter( fVal, rParameter, false, bReplaceGeoSize );
     945       38128 :             fVal -= nCoordTop;
     946       38128 :             if ( bScale )
     947             :             {
     948       18036 :                 fVal *= fYScale;
     949             : 
     950       18036 :                 if ( nFlags & DFF_CUSTOMSHAPE_FLIP_V )
     951           0 :                     fVal = aLogicRect.GetHeight() - fVal;
     952             :             }
     953       38128 :             aRetValue.Y() = (sal_Int32)fVal;
     954             :         }
     955             :         else            // width
     956             :         {
     957       38128 :             GetParameter( fVal, rParameter, bReplaceGeoSize, false );
     958       38128 :             fVal -= nCoordLeft;
     959       38128 :             if ( bScale )
     960             :             {
     961       18036 :                 fVal *= fXScale;
     962             : 
     963       18036 :                 if ( nFlags & DFF_CUSTOMSHAPE_FLIP_H )
     964           0 :                     fVal = aLogicRect.GetWidth() - fVal;
     965             :             }
     966       38128 :             aRetValue.X() = static_cast<long>(fVal);
     967             :         }
     968             :     }
     969             :     while ( ++nPass < 2 );
     970       38128 :     return aRetValue;
     971             : }
     972             : 
     973       93944 : bool EnhancedCustomShape2d::GetParameter( double& rRetValue, const EnhancedCustomShapeParameter& rParameter,
     974             :                                               const bool bReplaceGeoWidth, const bool bReplaceGeoHeight ) const
     975             : {
     976       93944 :     rRetValue = 0.0;
     977       93944 :     bool bRetValue = false;
     978       93944 :     switch ( rParameter.Type )
     979             :     {
     980             :         case EnhancedCustomShapeParameterType::ADJUSTMENT :
     981             :         {
     982           8 :             sal_Int32 nAdjustmentIndex = 0;
     983           8 :             if ( rParameter.Value >>= nAdjustmentIndex )
     984             :             {
     985           8 :                 rRetValue = GetAdjustValueAsDouble( nAdjustmentIndex );
     986           8 :                 bRetValue = true;
     987             :             }
     988             :         }
     989           8 :         break;
     990             :         case EnhancedCustomShapeParameterType::EQUATION :
     991             :         {
     992       53836 :             sal_Int32 nEquationIndex = 0;
     993       53836 :             if ( rParameter.Value >>= nEquationIndex )
     994             :             {
     995       53836 :                 rRetValue = GetEquationValueAsDouble( nEquationIndex );
     996       53836 :                 bRetValue = true;
     997             :             }
     998             :         }
     999       53836 :         break;
    1000             :         case EnhancedCustomShapeParameterType::NORMAL :
    1001             :         {
    1002       40092 :             if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE )
    1003             :             {
    1004           0 :                 double fValue(0.0);
    1005           0 :                 if ( rParameter.Value >>= fValue )
    1006             :                 {
    1007           0 :                     rRetValue = fValue;
    1008           0 :                     bRetValue = true;
    1009             :                 }
    1010             :             }
    1011             :             else
    1012             :             {
    1013       40092 :                 sal_Int32 nValue = 0;
    1014       40092 :                 if ( rParameter.Value >>= nValue )
    1015             :                 {
    1016       40092 :                     rRetValue = nValue;
    1017       40092 :                     bRetValue = true;
    1018       40092 :                     if ( bReplaceGeoWidth && ( nValue == nCoordWidth ) )
    1019        9410 :                         rRetValue *= fXRatio;
    1020       30682 :                     else if ( bReplaceGeoHeight && ( nValue == nCoordHeight ) )
    1021        9146 :                         rRetValue *= fYRatio;
    1022             :                 }
    1023             :             }
    1024             :         }
    1025       40092 :         break;
    1026             :         case EnhancedCustomShapeParameterType::LEFT :
    1027             :         {
    1028           4 :             rRetValue  = 0.0;
    1029           4 :             bRetValue = true;
    1030             :         }
    1031           4 :         break;
    1032             :         case EnhancedCustomShapeParameterType::TOP :
    1033             :         {
    1034           4 :             rRetValue  = 0.0;
    1035           4 :             bRetValue = true;
    1036             :         }
    1037           4 :         break;
    1038             :         case EnhancedCustomShapeParameterType::RIGHT :
    1039             :         {
    1040           0 :             rRetValue = nCoordWidth;
    1041           0 :             bRetValue = true;
    1042             :         }
    1043           0 :         break;
    1044             :         case EnhancedCustomShapeParameterType::BOTTOM :
    1045             :         {
    1046           0 :             rRetValue = nCoordHeight;
    1047           0 :             bRetValue = true;
    1048             :         }
    1049           0 :         break;
    1050             :     }
    1051       93944 :     return bRetValue;
    1052             : }
    1053             : 
    1054             : // nLumDat 28-31 = number of luminance entries in nLumDat
    1055             : // nLumDat 27-24 = nLumDatEntry 0
    1056             : // nLumDat 23-20 = nLumDatEntry 1 ...
    1057             : // each 4bit entry is to be interpreted as a 10 percent signed luminance changing
    1058          24 : sal_Int32 EnhancedCustomShape2d::GetLuminanceChange( sal_uInt32 nIndex ) const
    1059             : {
    1060          24 :     const sal_uInt32 nCount = nColorData >> 28;
    1061          24 :     if ( !nCount )
    1062           0 :         return 0;
    1063             : 
    1064          24 :     if ( nIndex >= nCount )
    1065           0 :         nIndex = nCount - 1;
    1066             : 
    1067          24 :     const sal_Int32 nLumDat = nColorData << ( ( 1 + nIndex ) << 2 );
    1068          24 :     return ( nLumDat >> 28 ) * 10;
    1069             : }
    1070             : 
    1071          24 : Color EnhancedCustomShape2d::GetColorData( const Color& rFillColor, sal_uInt32 nIndex, double dBrightness ) const
    1072             : {
    1073          24 :     const sal_Int32 nLuminance = GetLuminanceChange(nIndex);
    1074          24 :     if( !nLuminance && dBrightness == 1.0 )
    1075          12 :         return rFillColor;
    1076             : 
    1077             :     basegfx::BColor aHSVColor=
    1078             :         basegfx::tools::rgb2hsv(
    1079          12 :             basegfx::BColor(rFillColor.GetRed()/255.0,
    1080          12 :                             rFillColor.GetGreen()/255.0,
    1081          36 :                             rFillColor.GetBlue()/255.0));
    1082          12 :     if (nLuminance ) {
    1083          12 :         if( nLuminance > 0 )
    1084             :         {
    1085             :             aHSVColor.setGreen(
    1086           0 :                 aHSVColor.getGreen() * (1.0-nLuminance/100.0));
    1087             :             aHSVColor.setBlue(
    1088           0 :                 nLuminance/100.0 +
    1089           0 :                 (1.0-nLuminance/100.0)*aHSVColor.getBlue());
    1090             :         }
    1091          12 :         else if( nLuminance < 0 )
    1092             :         {
    1093             :             aHSVColor.setBlue(
    1094          12 :                 (1.0+nLuminance/100.0)*aHSVColor.getBlue());
    1095             :         }
    1096             :     }
    1097             : 
    1098          12 :     aHSVColor = basegfx::tools::hsv2rgb(aHSVColor);
    1099          24 :     return Color( (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(dBrightness*aHSVColor.getRed(),0.0,1.0) * 255.0 + 0.5 ),
    1100          24 :                   (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(dBrightness*aHSVColor.getGreen(),0.0,1.0) * 255.0 + 0.5 ),
    1101          48 :                   (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(dBrightness*aHSVColor.getBlue(),0.0,1.0) * 255.0 + 0.5 ) );
    1102             : }
    1103             : 
    1104       22992 : Rectangle EnhancedCustomShape2d::GetTextRect() const
    1105             : {
    1106       22992 :     sal_Int32 nIndex, nSize = seqTextFrames.getLength();
    1107       22992 :     if ( !nSize )
    1108       12528 :         return aLogicRect;
    1109       10464 :     nIndex = 0;
    1110       10464 :     if ( bTextFlow && ( nSize > 1 ) )
    1111           0 :         nIndex++;
    1112       10464 :     Point aTopLeft( GetPoint( seqTextFrames[ nIndex ].TopLeft, !bOOXMLShape, true ) );
    1113       10464 :     Point aBottomRight( GetPoint( seqTextFrames[ nIndex ].BottomRight, !bOOXMLShape, true ) );
    1114       10464 :     if ( bFlipH )
    1115             :     {
    1116           8 :         aTopLeft.X() = aLogicRect.GetWidth() - aTopLeft.X();
    1117           8 :         aBottomRight.X() = aLogicRect.GetWidth() - aBottomRight.X();
    1118             :     }
    1119       10464 :     if ( bFlipV )
    1120             :     {
    1121         112 :         aTopLeft.Y() = aLogicRect.GetHeight() - aTopLeft.Y();
    1122         112 :         aBottomRight.Y() = aLogicRect.GetHeight() - aBottomRight.Y();
    1123             :     }
    1124       10464 :     Rectangle aRect( aTopLeft, aBottomRight );
    1125             :     OSL_TRACE("EnhancedCustomShape2d::GetTextRect: %d x %d", aRect.GetWidth(), aRect.GetHeight());
    1126       10464 :     if( aRect.GetWidth() <= 1 || aRect.GetHeight() <= 1 )
    1127         120 :         return aLogicRect;
    1128       10344 :     aRect.Move( aLogicRect.Left(), aLogicRect.Top() );
    1129       10344 :     aRect.Justify();
    1130       10344 :     return aRect;
    1131             : }
    1132             : 
    1133        2250 : sal_uInt32 EnhancedCustomShape2d::GetHdlCount() const
    1134             : {
    1135        2250 :     return seqHandles.getLength();
    1136             : }
    1137             : 
    1138         130 : bool EnhancedCustomShape2d::GetHandlePosition( const sal_uInt32 nIndex, Point& rReturnPosition ) const
    1139             : {
    1140         130 :     bool bRetValue = false;
    1141         130 :     if ( nIndex < GetHdlCount() )
    1142             :     {
    1143         130 :         Handle aHandle;
    1144         130 :         if ( ConvertSequenceToEnhancedCustomShape2dHandle( seqHandles[ nIndex ], aHandle ) )
    1145             :         {
    1146         130 :             if ( aHandle.nFlags & HANDLE_FLAGS_POLAR )
    1147             :             {
    1148           0 :                 Point aReferencePoint( GetPoint( aHandle.aPolar, true, false ) );
    1149             : 
    1150             :                 double      fAngle;
    1151             :                 double      fRadius;
    1152           0 :                 GetParameter( fRadius, aHandle.aPosition.First, false, false );
    1153           0 :                 GetParameter( fAngle,  aHandle.aPosition.Second, false, false );
    1154             : 
    1155           0 :                 double a = ( 360.0 - fAngle ) * F_PI180;
    1156           0 :                 double dx = fRadius * fXScale;
    1157           0 :                 double fX = dx * cos( a );
    1158           0 :                 double fY =-dx * sin( a );
    1159             :                 rReturnPosition =
    1160             :                     Point(
    1161           0 :                         Round( fX + aReferencePoint.X() ),
    1162           0 :                         basegfx::fTools::equalZero(fXScale) ? aReferencePoint.Y() :
    1163           0 :                         Round( ( fY * fYScale ) / fXScale + aReferencePoint.Y() ) );
    1164             :             }
    1165             :             else
    1166             :             {
    1167         130 :                 if ( aHandle.nFlags & HANDLE_FLAGS_SWITCHED )
    1168             :                 {
    1169           0 :                     if ( aLogicRect.GetHeight() > aLogicRect.GetWidth() )
    1170             :                     {
    1171           0 :                         com::sun::star::drawing::EnhancedCustomShapeParameter aFirst = aHandle.aPosition.First;
    1172           0 :                         com::sun::star::drawing::EnhancedCustomShapeParameter aSecond = aHandle.aPosition.Second;
    1173           0 :                         aHandle.aPosition.First = aSecond;
    1174           0 :                         aHandle.aPosition.Second = aFirst;
    1175             :                     }
    1176             :                 }
    1177         130 :                 rReturnPosition = GetPoint( aHandle.aPosition, true, false );
    1178             :             }
    1179         130 :             const GeoStat aGeoStat( static_cast<SdrObjCustomShape*>(pCustomShapeObj)->GetGeoStat() );
    1180         130 :             if ( aGeoStat.nShearAngle )
    1181             :             {
    1182           0 :                 double nTan = aGeoStat.nTan;
    1183           0 :                 if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV))
    1184           0 :                     nTan = -nTan;
    1185           0 :                 ShearPoint( rReturnPosition, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), nTan );
    1186             :             }
    1187         130 :             if ( nRotateAngle )
    1188             :             {
    1189          20 :                 double a = nRotateAngle * F_PI18000;
    1190          20 :                 RotatePoint( rReturnPosition, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), sin( a ), cos( a ) );
    1191             :             }
    1192         130 :             if ( bFlipH )
    1193           2 :                 rReturnPosition.X() = aLogicRect.GetWidth() - rReturnPosition.X();
    1194         130 :             if ( bFlipV )
    1195           4 :                 rReturnPosition.Y() = aLogicRect.GetHeight() - rReturnPosition.Y();
    1196         130 :             rReturnPosition.Move( aLogicRect.Left(), aLogicRect.Top() );
    1197         130 :             bRetValue = true;
    1198         130 :         }
    1199             :     }
    1200         130 :     return bRetValue;
    1201             : }
    1202             : 
    1203           0 : bool EnhancedCustomShape2d::SetHandleControllerPosition( const sal_uInt32 nIndex, const com::sun::star::awt::Point& rPosition )
    1204             : {
    1205           0 :     bool bRetValue = false;
    1206           0 :     if ( nIndex < GetHdlCount() )
    1207             :     {
    1208           0 :         Handle aHandle;
    1209           0 :         if ( ConvertSequenceToEnhancedCustomShape2dHandle( seqHandles[ nIndex ], aHandle ) )
    1210             :         {
    1211           0 :             Point aP( rPosition.X, rPosition.Y );
    1212             :             // apply the negative object rotation to the controller position
    1213             : 
    1214           0 :             aP.Move( -aLogicRect.Left(), -aLogicRect.Top() );
    1215           0 :             if ( bFlipH )
    1216           0 :                 aP.X() = aLogicRect.GetWidth() - aP.X();
    1217           0 :             if ( bFlipV )
    1218           0 :                 aP.Y() = aLogicRect.GetHeight() - aP.Y();
    1219           0 :             if ( nRotateAngle )
    1220             :             {
    1221           0 :                 double a = -nRotateAngle * F_PI18000;
    1222           0 :                 RotatePoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), sin( a ), cos( a ) );
    1223             :             }
    1224           0 :             const GeoStat aGeoStat( static_cast<SdrObjCustomShape*>(pCustomShapeObj)->GetGeoStat() );
    1225           0 :             if ( aGeoStat.nShearAngle )
    1226             :             {
    1227           0 :                 double nTan = -aGeoStat.nTan;
    1228           0 :                 if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV))
    1229           0 :                     nTan = -nTan;
    1230           0 :                 ShearPoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), nTan );
    1231             :             }
    1232             : 
    1233           0 :             double fPos1 = aP.X();  //( bFlipH ) ? aLogicRect.GetWidth() - aP.X() : aP.X();
    1234           0 :             double fPos2 = aP.Y();  //( bFlipV ) ? aLogicRect.GetHeight() -aP.Y() : aP.Y();
    1235           0 :             fPos1 /= fXScale;
    1236           0 :             fPos2 /= fYScale;
    1237             : 
    1238           0 :             if ( aHandle.nFlags & HANDLE_FLAGS_SWITCHED )
    1239             :             {
    1240           0 :                 if ( aLogicRect.GetHeight() > aLogicRect.GetWidth() )
    1241             :                 {
    1242           0 :                     double fX = fPos1;
    1243           0 :                     double fY = fPos2;
    1244           0 :                     fPos1 = fY;
    1245           0 :                     fPos2 = fX;
    1246             :                 }
    1247             :             }
    1248             : 
    1249           0 :             sal_Int32 nFirstAdjustmentValue = -1, nSecondAdjustmentValue = -1;
    1250             : 
    1251           0 :             if ( aHandle.aPosition.First.Type == EnhancedCustomShapeParameterType::ADJUSTMENT )
    1252           0 :                 aHandle.aPosition.First.Value >>= nFirstAdjustmentValue;
    1253           0 :             if ( aHandle.aPosition.Second.Type == EnhancedCustomShapeParameterType::ADJUSTMENT )
    1254           0 :                 aHandle.aPosition.Second.Value>>= nSecondAdjustmentValue;
    1255             : 
    1256           0 :             if ( aHandle.nFlags & HANDLE_FLAGS_POLAR )
    1257             :             {
    1258             :                 double fXRef, fYRef, fAngle;
    1259           0 :                 GetParameter( fXRef, aHandle.aPolar.First, false, false );
    1260           0 :                 GetParameter( fYRef, aHandle.aPolar.Second, false, false );
    1261           0 :                 const double fDX = fPos1 - fXRef;
    1262           0 :                 fAngle = -( atan2( -fPos2 + fYRef, ( ( fDX == 0.0L ) ? 0.000000001 : fDX ) ) / F_PI180 );
    1263           0 :                 double fX = ( fPos1 - fXRef );
    1264           0 :                 double fY = ( fPos2 - fYRef );
    1265           0 :                 double fRadius = sqrt( fX * fX + fY * fY );
    1266           0 :                 if ( aHandle.nFlags & HANDLE_FLAGS_RADIUS_RANGE_MINIMUM )
    1267             :                 {
    1268             :                     double fMin;
    1269           0 :                     GetParameter( fMin,  aHandle.aRadiusRangeMinimum, false, false );
    1270           0 :                     if ( fRadius < fMin )
    1271           0 :                         fRadius = fMin;
    1272             :                 }
    1273           0 :                 if ( aHandle.nFlags & HANDLE_FLAGS_RADIUS_RANGE_MAXIMUM )
    1274             :                 {
    1275             :                     double fMax;
    1276           0 :                     GetParameter( fMax, aHandle.aRadiusRangeMaximum, false, false );
    1277           0 :                     if ( fRadius > fMax )
    1278           0 :                         fRadius = fMax;
    1279             :                 }
    1280           0 :                 if ( nFirstAdjustmentValue >= 0 )
    1281           0 :                     SetAdjustValueAsDouble( fRadius, nFirstAdjustmentValue );
    1282           0 :                 if ( nSecondAdjustmentValue >= 0 )
    1283           0 :                     SetAdjustValueAsDouble( fAngle,  nSecondAdjustmentValue );
    1284             :             }
    1285             :             else
    1286             :             {
    1287           0 :                 if ( aHandle.nFlags & HANDLE_FLAGS_REFX )
    1288             :                 {
    1289           0 :                     nFirstAdjustmentValue = aHandle.nRefX;
    1290           0 :                     fPos1 *= 100000.0;
    1291           0 :                     fPos1 /= nCoordWidth;
    1292             :                 }
    1293           0 :                 if ( aHandle.nFlags & HANDLE_FLAGS_REFY )
    1294             :                 {
    1295           0 :                     nSecondAdjustmentValue = aHandle.nRefY;
    1296           0 :                     fPos2 *= 100000.0;
    1297           0 :                     fPos2 /= nCoordHeight;
    1298             :                 }
    1299           0 :                 if ( nFirstAdjustmentValue >= 0 )
    1300             :                 {
    1301           0 :                     if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_X_MINIMUM )        // check if horizontal handle needs to be within a range
    1302             :                     {
    1303             :                         double fXMin;
    1304           0 :                         GetParameter( fXMin, aHandle.aXRangeMinimum, false, false );
    1305           0 :                         if ( fPos1 < fXMin )
    1306           0 :                             fPos1 = fXMin;
    1307             :                     }
    1308           0 :                     if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_X_MAXIMUM )        // check if horizontal handle needs to be within a range
    1309             :                     {
    1310             :                         double fXMax;
    1311           0 :                         GetParameter( fXMax, aHandle.aXRangeMaximum, false, false );
    1312           0 :                         if ( fPos1 > fXMax )
    1313           0 :                             fPos1 = fXMax;
    1314             :                     }
    1315           0 :                     SetAdjustValueAsDouble( fPos1, nFirstAdjustmentValue );
    1316             :                 }
    1317           0 :                 if ( nSecondAdjustmentValue >= 0 )
    1318             :                 {
    1319           0 :                     if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_Y_MINIMUM )        // check if vertical handle needs to be within a range
    1320             :                     {
    1321             :                         double fYMin;
    1322           0 :                         GetParameter( fYMin, aHandle.aYRangeMinimum, false, false );
    1323           0 :                         if ( fPos2 < fYMin )
    1324           0 :                             fPos2 = fYMin;
    1325             :                     }
    1326           0 :                     if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_Y_MAXIMUM )        // check if vertical handle needs to be within a range
    1327             :                     {
    1328             :                         double fYMax;
    1329           0 :                         GetParameter( fYMax, aHandle.aYRangeMaximum, false, false );
    1330           0 :                         if ( fPos2 > fYMax )
    1331           0 :                             fPos2 = fYMax;
    1332             :                     }
    1333           0 :                     SetAdjustValueAsDouble( fPos2, nSecondAdjustmentValue );
    1334             :                 }
    1335             :             }
    1336             :             // and writing them back into the GeometryItem
    1337             :             SdrCustomShapeGeometryItem aGeometryItem(
    1338           0 :                 static_cast<const SdrCustomShapeGeometryItem&>(pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )));
    1339           0 :             com::sun::star::beans::PropertyValue aPropVal;
    1340           0 :             aPropVal.Name = "AdjustmentValues";
    1341           0 :             aPropVal.Value <<= seqAdjustmentValues;
    1342           0 :             aGeometryItem.SetPropertyValue( aPropVal );
    1343           0 :             pCustomShapeObj->SetMergedItem( aGeometryItem );
    1344           0 :             bRetValue = true;
    1345           0 :         }
    1346             :     }
    1347           0 :     return bRetValue;
    1348             : }
    1349             : 
    1350           0 : void EnhancedCustomShape2d::SwapStartAndEndArrow( SdrObject* pObj ) //#108274
    1351             : {
    1352           0 :     XLineStartItem       aLineStart;
    1353           0 :     aLineStart.SetLineStartValue(static_cast<const XLineStartItem&>(pObj->GetMergedItem( XATTR_LINEEND )).GetLineStartValue());
    1354           0 :     XLineStartWidthItem  aLineStartWidth(static_cast<const XLineStartWidthItem&>(pObj->GetMergedItem( XATTR_LINEENDWIDTH )).GetValue());
    1355           0 :     XLineStartCenterItem aLineStartCenter(static_cast<const XLineStartCenterItem&>(pObj->GetMergedItem( XATTR_LINEENDCENTER )).GetValue());
    1356             : 
    1357           0 :     XLineEndItem         aLineEnd;
    1358           0 :     aLineEnd.SetLineEndValue(static_cast<const XLineEndItem&>(pObj->GetMergedItem( XATTR_LINESTART )).GetLineEndValue());
    1359           0 :     XLineEndWidthItem    aLineEndWidth(static_cast<const XLineEndWidthItem&>(pObj->GetMergedItem( XATTR_LINESTARTWIDTH )).GetValue());
    1360           0 :     XLineEndCenterItem   aLineEndCenter(static_cast<const XLineEndCenterItem&>(pObj->GetMergedItem( XATTR_LINESTARTCENTER )).GetValue());
    1361             : 
    1362           0 :     pObj->SetMergedItem( aLineStart );
    1363           0 :     pObj->SetMergedItem( aLineStartWidth );
    1364           0 :     pObj->SetMergedItem( aLineStartCenter );
    1365           0 :     pObj->SetMergedItem( aLineEnd );
    1366           0 :     pObj->SetMergedItem( aLineEndWidth );
    1367           0 :     pObj->SetMergedItem( aLineEndCenter );
    1368           0 : }
    1369             : 
    1370        4526 : static basegfx::B2DPolygon CreateArc( const Rectangle& rRect, const Point& rStart, const Point& rEnd, const bool bClockwise, bool bFullCircle = false )
    1371             : {
    1372        4526 :     Rectangle aRect( rRect );
    1373        4526 :     Point aStart( rStart );
    1374        4526 :     Point aEnd( rEnd );
    1375             : 
    1376        4526 :     sal_Int32 bSwapStartEndAngle = 0;
    1377             : 
    1378        4526 :     if ( aRect.Left() > aRect.Right() )
    1379           0 :         bSwapStartEndAngle ^= 0x01;
    1380        4526 :     if ( aRect.Top() > aRect.Bottom() )
    1381           0 :         bSwapStartEndAngle ^= 0x11;
    1382        4526 :     if ( bSwapStartEndAngle )
    1383             :     {
    1384           0 :         aRect.Justify();
    1385           0 :         if ( bSwapStartEndAngle & 1 )
    1386             :         {
    1387           0 :             Point aTmp( aStart );
    1388           0 :             aStart = aEnd;
    1389           0 :             aEnd = aTmp;
    1390             :         }
    1391             :     }
    1392             : 
    1393        4526 :     Polygon aTempPoly( aRect, aStart, aEnd, POLY_ARC, bFullCircle );
    1394        4526 :     basegfx::B2DPolygon aRetval;
    1395             : 
    1396        4526 :     if ( bClockwise )
    1397             :     {
    1398      156440 :         for ( sal_uInt16 j = aTempPoly.GetSize(); j--; )
    1399             :         {
    1400      147516 :             aRetval.append(basegfx::B2DPoint(aTempPoly[ j ].X(), aTempPoly[ j ].Y()));
    1401             :         }
    1402             :     }
    1403             :     else
    1404             :     {
    1405        2068 :         for ( sal_uInt16 j = 0; j < aTempPoly.GetSize(); j++ )
    1406             :         {
    1407        2004 :             aRetval.append(basegfx::B2DPoint(aTempPoly[ j ].X(), aTempPoly[ j ].Y()));
    1408             :         }
    1409             :     }
    1410             : 
    1411        4526 :     return aRetval;
    1412             : }
    1413             : 
    1414        3066 : void EnhancedCustomShape2d::CreateSubPath( sal_uInt16& rSrcPt, sal_uInt16& rSegmentInd, std::vector< SdrPathObj* >& rObjectList,
    1415             :                                            const bool bLineGeometryNeededOnly,
    1416             :                                            const bool bSortFilledObjectsToBack,
    1417             :                                            sal_Int32 nIndex )
    1418             : {
    1419        3066 :     bool bNoFill = false;
    1420        3066 :     bool bNoStroke = false;
    1421        3066 :     double dBrightness = 1.0;
    1422             : 
    1423        3066 :     basegfx::B2DPolyPolygon aNewB2DPolyPolygon;
    1424        6132 :     basegfx::B2DPolygon aNewB2DPolygon;
    1425             : 
    1426        3066 :     SetPathSize( nIndex );
    1427             : 
    1428        3066 :     sal_Int32 nCoordSize = seqCoordinates.getLength();
    1429        3066 :     sal_Int32 nSegInfoSize = seqSegments.getLength();
    1430        3066 :     if ( !nSegInfoSize )
    1431             :     {
    1432          60 :         const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray();
    1433             : 
    1434         584 :         for ( sal_Int32 nPtNum(0L); nPtNum < nCoordSize; nPtNum++ )
    1435             :         {
    1436         524 :             const Point aTempPoint(GetPoint( *pTmp++, true, true ));
    1437         524 :             aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
    1438             :         }
    1439             : 
    1440          60 :         aNewB2DPolygon.setClosed(true);
    1441             :     }
    1442             :     else
    1443             :     {
    1444       19014 :         for ( ;rSegmentInd < nSegInfoSize; )
    1445             :         {
    1446       16008 :             sal_Int16 nCommand = seqSegments[ rSegmentInd ].Command;
    1447       16008 :             sal_Int16 nPntCount= seqSegments[ rSegmentInd++ ].Count;
    1448             : 
    1449       16008 :             switch ( nCommand )
    1450             :             {
    1451             :                 case NOFILL :
    1452          68 :                     bNoFill = true;
    1453          68 :                 break;
    1454             :                 case NOSTROKE :
    1455          12 :                     bNoStroke = true;
    1456          12 :                 break;
    1457             :                 case DARKEN :
    1458           0 :                     dBrightness = 0.66666666;
    1459           0 :                     break;
    1460             :                 case DARKENLESS :
    1461           0 :                     dBrightness = 0.83333333;
    1462           0 :                     break;
    1463             :                 case LIGHTEN :
    1464           0 :                     dBrightness = 1.16666666;
    1465           0 :                     break;
    1466             :                 case LIGHTENLESS :
    1467           0 :                     dBrightness = 1.33333333;
    1468           0 :                     break;
    1469             :                 case MOVETO :
    1470             :                 {
    1471        3054 :                     if(aNewB2DPolygon.count() > 1L)
    1472             :                     {
    1473             :                         // #i76201# Add conversion to closed polygon when first and last points are equal
    1474          86 :                         basegfx::tools::checkClosed(aNewB2DPolygon);
    1475          86 :                         aNewB2DPolyPolygon.append(aNewB2DPolygon);
    1476             :                     }
    1477             : 
    1478        3054 :                     aNewB2DPolygon.clear();
    1479             : 
    1480        3054 :                     if ( rSrcPt < nCoordSize )
    1481             :                     {
    1482        3054 :                         const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
    1483             :                         OSL_TRACE("moveTo: %d,%d", aTempPoint.X(), aTempPoint.Y());
    1484        3054 :                         aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
    1485             :                     }
    1486             :                 }
    1487        3054 :                 break;
    1488             :                 case ENDSUBPATH :
    1489        3006 :                 break;
    1490             :                 case CLOSESUBPATH :
    1491             :                 {
    1492        1444 :                     if(aNewB2DPolygon.count())
    1493             :                     {
    1494        1444 :                         if(aNewB2DPolygon.count() > 1L)
    1495             :                         {
    1496        1444 :                             aNewB2DPolygon.setClosed(true);
    1497        1444 :                             aNewB2DPolyPolygon.append(aNewB2DPolygon);
    1498             :                         }
    1499             : 
    1500        1444 :                         aNewB2DPolygon.clear();
    1501             :                     }
    1502             :                 }
    1503        1444 :                 break;
    1504             :                 case CURVETO :
    1505             :                 {
    1506        1780 :                     for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 2 ) < nCoordSize ); i++ )
    1507             :                     {
    1508        1018 :                         const Point aControlA(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
    1509        1018 :                         const Point aControlB(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
    1510        1018 :                         const Point aEnd(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
    1511             : 
    1512             :                         DBG_ASSERT(aNewB2DPolygon.count(), "EnhancedCustomShape2d::CreateSubPath: Error in adding control point (!)");
    1513             :                         aNewB2DPolygon.appendBezierSegment(
    1514        2036 :                             basegfx::B2DPoint(aControlA.X(), aControlA.Y()),
    1515        2036 :                             basegfx::B2DPoint(aControlB.X(), aControlB.Y()),
    1516        5090 :                             basegfx::B2DPoint(aEnd.X(), aEnd.Y()));
    1517             :                     }
    1518             :                 }
    1519         762 :                 break;
    1520             : 
    1521             :                 case ANGLEELLIPSE :
    1522             :                 {
    1523           6 :                     if ( nPntCount )
    1524             :                     {
    1525           6 :                         if(aNewB2DPolygon.count() > 1L)
    1526             :                         {
    1527             :                             // #i76201# Add conversion to closed polygon when first and last points are equal
    1528           0 :                             basegfx::tools::checkClosed(aNewB2DPolygon);
    1529           0 :                             aNewB2DPolyPolygon.append(aNewB2DPolygon);
    1530             :                         }
    1531           6 :                         aNewB2DPolygon.clear();
    1532             :                     }
    1533             :                 }
    1534             :                 case ANGLEELLIPSETO :
    1535             :                 {
    1536          12 :                     for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 2 ) < nCoordSize ); i++ )
    1537             :                     {
    1538             :                         // create a circle
    1539           6 :                         Point _aCenter;
    1540             :                         double fWidth, fHeight;
    1541           6 :                         const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( mso_sptEllipse  );
    1542           6 :                         bool bIsDefaultViewBox = false;
    1543           6 :                         bool bIsDefaultPath = false;
    1544           6 :                         bool bIsMSEllipse = false;
    1545             : 
    1546           6 :                         if( ( nCoordWidth == pDefCustomShape->nCoordWidth )
    1547           6 :                             && ( nCoordHeight == pDefCustomShape->nCoordHeight ) )
    1548           6 :                             bIsDefaultViewBox = true;
    1549           6 :                         sal_Int32 j, nCount = pDefCustomShape->nVertices;//==3
    1550          12 :                         com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates1, seqCoordinates2;
    1551             : 
    1552           6 :                         seqCoordinates1.realloc( nCount );
    1553          24 :                         for ( j = 0; j < nCount; j++ )
    1554             :                         {
    1555          18 :                             seqCoordinates1[j] = seqCoordinates[ rSrcPt + j];
    1556             :                         }
    1557             : 
    1558           6 :                         seqCoordinates2.realloc( nCount );
    1559          24 :                         for ( j = 0; j < nCount; j++ )
    1560             :                         {
    1561          18 :                             EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ j ].First, pDefCustomShape->pVertices[ j ].nValA );
    1562          18 :                             EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ j ].Second, pDefCustomShape->pVertices[ j ].nValB );
    1563             :                         }
    1564           6 :                         if(seqCoordinates1 == seqCoordinates2)
    1565           6 :                             bIsDefaultPath = true;
    1566             : 
    1567          12 :                         OUString sShpType;
    1568           6 :                         SdrCustomShapeGeometryItem& rGeometryItem = const_cast<SdrCustomShapeGeometryItem&>(static_cast<const SdrCustomShapeGeometryItem&>(pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )));
    1569           6 :                         Any* pAny = rGeometryItem.GetPropertyValueByName( "Type" );
    1570           6 :                         if ( pAny )
    1571           6 :                             *pAny >>= sShpType;
    1572          12 :                         if( sShpType.getLength() > 3 &&
    1573           6 :                             sShpType.startsWith( "mso" )){
    1574           0 :                                 bIsMSEllipse = true;
    1575             :                         }
    1576           6 :                         if( (! bIsDefaultPath   && ! bIsDefaultViewBox) || (bIsDefaultViewBox && bIsMSEllipse) /*&& (nGeneratorVersion == SfxObjectShell::Sym_L2)*/ )
    1577             :                         {
    1578           0 :                             _aCenter = GetPoint( seqCoordinates[ rSrcPt ], true, true );
    1579           0 :                             GetParameter( fWidth,  seqCoordinates[ rSrcPt + 1 ].First, true, false );
    1580           0 :                             GetParameter( fHeight,  seqCoordinates[ rSrcPt + 1 ].Second, false, true );
    1581           0 :                             fWidth /= 2;
    1582           0 :                             fHeight /= 2;
    1583           6 :                         }else if( bIsDefaultPath && !bIsDefaultViewBox /*&& (nGeneratorVersion == SfxObjectShell::Sym_L2)*/ )
    1584             :                         {
    1585           0 :                             _aCenter.X() = nCoordWidth/2 * fXScale;
    1586           0 :                             _aCenter.Y() = nCoordHeight/2 * fYScale;
    1587           0 :                             fWidth = nCoordWidth/2;
    1588           0 :                             fHeight = nCoordHeight/2;
    1589           0 :                             const Any* pViewBox = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( "ViewBox" );
    1590           0 :                             com::sun::star::awt::Rectangle aViewBox;
    1591           0 :                             if ( pViewBox && (*pViewBox >>= aViewBox ) )
    1592             :                             {
    1593           0 :                                 aViewBox.Width = pDefCustomShape->nCoordWidth;
    1594           0 :                                 aViewBox.Height = pDefCustomShape->nCoordHeight;
    1595             :                             }
    1596           0 :                             com::sun::star::beans::PropertyValue aPropVal;
    1597           0 :                             aPropVal.Name = "ViewBox";
    1598           0 :                             aPropVal.Value <<= aViewBox;
    1599           0 :                             rGeometryItem.SetPropertyValue( aPropVal );
    1600           0 :                             pCustomShapeObj->SetMergedItem( rGeometryItem );
    1601             :                         }else{
    1602           6 :                             _aCenter = GetPoint( seqCoordinates[ rSrcPt ], true, true );
    1603           6 :                             GetParameter( fWidth,  seqCoordinates[ rSrcPt + 1 ].First, true, false);
    1604           6 :                             GetParameter( fHeight,  seqCoordinates[ rSrcPt + 1 ].Second, false, true );
    1605             :                         }
    1606             : 
    1607           6 :                         fWidth *= fXScale;
    1608           6 :                         fHeight*= fYScale;
    1609           6 :                         Point aP( (sal_Int32)( _aCenter.X() - fWidth ), (sal_Int32)( _aCenter.Y() - fHeight ) );
    1610           6 :                         Size  aS( (sal_Int32)( fWidth * 2.0 ), (sal_Int32)( fHeight * 2.0 ) );
    1611           6 :                         Rectangle aRect( aP, aS );
    1612           6 :                         if ( aRect.GetWidth() && aRect.GetHeight() )
    1613             :                         {
    1614             :                             double fStartAngle, fEndAngle;
    1615           6 :                             GetParameter( fStartAngle, seqCoordinates[ rSrcPt + 2 ].First,  false, false );
    1616           6 :                             GetParameter( fEndAngle  , seqCoordinates[ rSrcPt + 2 ].Second, false, false );
    1617             : 
    1618           6 :                             if ( ((sal_Int32)fStartAngle % 360) != ((sal_Int32)fEndAngle % 360) )
    1619             :                             {
    1620           0 :                                 if ( (sal_Int32)fStartAngle & 0x7fff0000 )  // SJ: if the angle was imported from our escher import, then the
    1621           0 :                                     fStartAngle /= 65536.0;                 // value is shifted by 16. TODO: already change the fixed float to a
    1622           0 :                                 if ( (sal_Int32)fEndAngle & 0x7fff0000 )    // double in the import filter
    1623             :                                 {
    1624           0 :                                     fEndAngle /= 65536.0;
    1625           0 :                                     fEndAngle = fEndAngle + fStartAngle;
    1626           0 :                                     if ( fEndAngle < 0 )
    1627             :                                     {   // in the binary filter the endangle is the amount
    1628           0 :                                         double fTemp = fStartAngle;
    1629           0 :                                         fStartAngle = fEndAngle;
    1630           0 :                                         fEndAngle = fTemp;
    1631             :                                     }
    1632             :                                 }
    1633           0 :                                 double fCenterX = aRect.Center().X();
    1634           0 :                                 double fCenterY = aRect.Center().Y();
    1635           0 :                                 double fx1 = ( cos( fStartAngle * F_PI180 ) * 65536.0 * fXScale ) + fCenterX;
    1636           0 :                                 double fy1 = ( -sin( fStartAngle * F_PI180 ) * 65536.0 * fYScale ) + fCenterY;
    1637           0 :                                 double fx2 = ( cos( fEndAngle * F_PI180 ) * 65536.0 * fXScale ) + fCenterX;
    1638           0 :                                 double fy2 = ( -sin( fEndAngle * F_PI180 ) * 65536.0 * fYScale ) + fCenterY;
    1639           0 :                                 aNewB2DPolygon.append(CreateArc( aRect, Point( (sal_Int32)fx1, (sal_Int32)fy1 ), Point( (sal_Int32)fx2, (sal_Int32)fy2 ), false));
    1640             :                             }
    1641             :                             else
    1642             :                             {   /* SJ: TODO: this block should be replaced sometimes, because the current point
    1643             :                                    is not set correct, it also does not use the correct moveto
    1644             :                                    point if ANGLEELLIPSETO was used, but the method CreateArc
    1645             :                                    is at the moment not able to draw full circles (if startangle is 0
    1646             :                                    and endangle 360 nothing is painted :-( */
    1647           6 :                                 sal_Int32 nXControl = (sal_Int32)((double)aRect.GetWidth() * 0.2835 );
    1648           6 :                                 sal_Int32 nYControl = (sal_Int32)((double)aRect.GetHeight() * 0.2835 );
    1649           6 :                                 Point aCenter( aRect.Center() );
    1650             : 
    1651             :                                 // append start point
    1652           6 :                                 aNewB2DPolygon.append(basegfx::B2DPoint(aCenter.X(), aRect.Top()));
    1653             : 
    1654             :                                 // append four bezier segments
    1655             :                                 aNewB2DPolygon.appendBezierSegment(
    1656          12 :                                     basegfx::B2DPoint(aCenter.X() + nXControl, aRect.Top()),
    1657          12 :                                     basegfx::B2DPoint(aRect.Right(), aCenter.Y() - nYControl),
    1658          30 :                                     basegfx::B2DPoint(aRect.Right(), aCenter.Y()));
    1659             : 
    1660             :                                 aNewB2DPolygon.appendBezierSegment(
    1661          12 :                                     basegfx::B2DPoint(aRect.Right(), aCenter.Y() + nYControl),
    1662          12 :                                     basegfx::B2DPoint(aCenter.X() + nXControl, aRect.Bottom()),
    1663          30 :                                     basegfx::B2DPoint(aCenter.X(), aRect.Bottom()));
    1664             : 
    1665             :                                 aNewB2DPolygon.appendBezierSegment(
    1666          12 :                                     basegfx::B2DPoint(aCenter.X() - nXControl, aRect.Bottom()),
    1667          12 :                                     basegfx::B2DPoint(aRect.Left(), aCenter.Y() + nYControl),
    1668          30 :                                     basegfx::B2DPoint(aRect.Left(), aCenter.Y()));
    1669             : 
    1670             :                                 aNewB2DPolygon.appendBezierSegment(
    1671          12 :                                     basegfx::B2DPoint(aRect.Left(), aCenter.Y() - nYControl),
    1672          12 :                                     basegfx::B2DPoint(aCenter.X() - nXControl, aRect.Top()),
    1673          30 :                                     basegfx::B2DPoint(aCenter.X(), aRect.Top()));
    1674             : 
    1675             :                                 // close, rescue last controlpoint, remove double last point
    1676           6 :                                 basegfx::tools::closeWithGeometryChange(aNewB2DPolygon);
    1677             :                             }
    1678             :                         }
    1679           6 :                         rSrcPt += 3;
    1680           6 :                     }
    1681             :                 }
    1682           6 :                 break;
    1683             : 
    1684             :                 case QUADRATICCURVETO :
    1685             :                 {
    1686           0 :                     for ( sal_Int32 i(0L); ( i < nPntCount ) && ( rSrcPt + 1 < nCoordSize ); i++ )
    1687             :                     {
    1688           0 :                         if ( rSrcPt )
    1689             :                         {
    1690           0 :                             const Point aPreviousEndPoint(GetPoint( seqCoordinates[ rSrcPt - 1 ], true, true));
    1691           0 :                             const Point aControlQ(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
    1692           0 :                             const Point aEnd(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
    1693           0 :                             const Point aControlA((aPreviousEndPoint + (aControlQ * 2)) / 3);
    1694           0 :                             const Point aControlB(((aControlQ * 2) + aEnd) / 3);
    1695             : 
    1696             :                             DBG_ASSERT(aNewB2DPolygon.count(), "EnhancedCustomShape2d::CreateSubPath: Error in adding Q control point (!)");
    1697             :                             aNewB2DPolygon.appendBezierSegment(
    1698           0 :                                 basegfx::B2DPoint(aControlA.X(), aControlA.Y()),
    1699           0 :                                 basegfx::B2DPoint(aControlB.X(), aControlB.Y()),
    1700           0 :                                 basegfx::B2DPoint(aEnd.X(), aEnd.Y()));
    1701             :                         }
    1702             :                         else // no previous point , do a moveto
    1703             :                         {
    1704           0 :                             rSrcPt++; // skip control point
    1705           0 :                             const Point aEnd(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
    1706             : 
    1707             :                             DBG_ASSERT(aNewB2DPolygon.count(), "EnhancedCustomShape2d::CreateSubPath: Error in adding Q control point (!)");
    1708           0 :                             aNewB2DPolygon.append(basegfx::B2DPoint(aEnd.X(), aEnd.Y()));
    1709             :                         }
    1710             :                     }
    1711             :                 }
    1712           0 :                 break;
    1713             : 
    1714             :                 case LINETO :
    1715             :                 {
    1716       14200 :                     for ( sal_Int32 i(0L); ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ )
    1717             :                     {
    1718        9832 :                         const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
    1719             :                         OSL_TRACE("lineTo: %d,%d", aTempPoint.X(), aTempPoint.Y());
    1720        9832 :                         aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
    1721             :                     }
    1722             :                 }
    1723        4368 :                 break;
    1724             : 
    1725             :                 case ARC :
    1726             :                 case CLOCKWISEARC :
    1727             :                 {
    1728          24 :                     if(aNewB2DPolygon.count() > 1L)
    1729             :                     {
    1730             :                         // #i76201# Add conversion to closed polygon when first and last points are equal
    1731           0 :                         basegfx::tools::checkClosed(aNewB2DPolygon);
    1732           0 :                         aNewB2DPolyPolygon.append(aNewB2DPolygon);
    1733             :                     }
    1734             : 
    1735          24 :                     aNewB2DPolygon.clear();
    1736             :                 }
    1737             :                 case ARCTO :
    1738             :                 case CLOCKWISEARCTO :
    1739             :                 {
    1740          86 :                     bool bClockwise = ( nCommand == CLOCKWISEARC ) || ( nCommand == CLOCKWISEARCTO );
    1741          86 :                     sal_uInt32 nXor = bClockwise ? 3 : 2;
    1742         196 :                     for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 3 ) < nCoordSize ); i++ )
    1743             :                     {
    1744         110 :                         Rectangle aRect( GetPoint( seqCoordinates[ rSrcPt ], true, true ), GetPoint( seqCoordinates[ rSrcPt + 1 ], true, true ) );
    1745         110 :                         if ( aRect.GetWidth() && aRect.GetHeight() )
    1746             :                         {
    1747         110 :                             Point aCenter( aRect.Center() );
    1748         110 :                             Point aStart( GetPoint( seqCoordinates[ (sal_uInt16)( rSrcPt + nXor ) ], true, true ) );
    1749         110 :                             Point aEnd( GetPoint( seqCoordinates[ (sal_uInt16)( rSrcPt + ( nXor ^ 1 ) ) ], true, true ) );
    1750         110 :                             aStart.X() = (sal_Int32)( ( (double)( aStart.X() - aCenter.X() ) ) ) + aCenter.X();
    1751         110 :                             aStart.Y() = (sal_Int32)( ( (double)( aStart.Y() - aCenter.Y() ) ) ) + aCenter.Y();
    1752         110 :                             aEnd.X() = (sal_Int32)( ( (double)( aEnd.X() - aCenter.X() ) ) ) + aCenter.X();
    1753         110 :                             aEnd.Y() = (sal_Int32)( ( (double)( aEnd.Y() - aCenter.Y() ) ) ) + aCenter.Y();
    1754         110 :                             aNewB2DPolygon.append(CreateArc( aRect, aStart, aEnd, bClockwise));
    1755             :                         }
    1756         110 :                         rSrcPt += 4;
    1757             :                     }
    1758             :                 }
    1759          86 :                 break;
    1760             : 
    1761             :                 case ARCANGLETO :
    1762             :                 {
    1763             :                     double fWR, fHR, fStartAngle, fSwingAngle;
    1764             : 
    1765        7618 :                     for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( rSrcPt + 1 < nCoordSize ); i++ )
    1766             :                     {
    1767        4416 :                         GetParameter ( fWR, seqCoordinates[ (sal_uInt16)( rSrcPt ) ].First, true, false );
    1768        4416 :                         GetParameter ( fHR, seqCoordinates[ (sal_uInt16)( rSrcPt ) ].Second, false, true );
    1769             : 
    1770        4416 :                         GetParameter ( fStartAngle, seqCoordinates[ (sal_uInt16)( rSrcPt + 1) ].First, false, false );
    1771        4416 :                         GetParameter ( fSwingAngle, seqCoordinates[ (sal_uInt16)( rSrcPt + 1 ) ].Second, false, false );
    1772             : 
    1773        4416 :                         fWR *= fXScale;
    1774        4416 :                         fHR *= fYScale;
    1775             : 
    1776        4416 :                         fStartAngle *= F_PI180;
    1777        4416 :                         fSwingAngle *= F_PI180;
    1778             : 
    1779             :                         OSL_TRACE("ARCANGLETO scale: %f x %f angles: %f, %f", fWR, fHR, fStartAngle, fSwingAngle);
    1780             : 
    1781        4416 :                         bool bClockwise = fSwingAngle >= 0.0;
    1782             : 
    1783        4416 :                         if (aNewB2DPolygon.count() > 0)
    1784             :                         {
    1785        4416 :                             basegfx::B2DPoint aStartPointB2D( aNewB2DPolygon.getB2DPoint(aNewB2DPolygon.count() - 1 ) );
    1786        4416 :                             Point aStartPoint( aStartPointB2D.getX(), aStartPointB2D.getY() );
    1787             : 
    1788        4416 :                             double fT = atan2((fWR*sin(fStartAngle)), (fHR*cos(fStartAngle)));
    1789        4416 :                             double fTE = atan2((fWR*sin(fStartAngle + fSwingAngle)), fHR*cos(fStartAngle + fSwingAngle));
    1790             : 
    1791             :                             OSL_TRACE("ARCANGLETO angles: %f, %f --> parameters: %f, %f", fStartAngle, fSwingAngle, fT, fTE );
    1792             : 
    1793        8832 :                             Rectangle aRect ( Point ( aStartPoint.getX() - fWR*cos(fT) - fWR, aStartPoint.getY() - fHR*sin(fT) - fHR ),
    1794       13248 :                                               Point ( aStartPoint.getX() - fWR*cos(fT) + fWR, aStartPoint.getY() - fHR*sin(fT) + fHR) );
    1795             : 
    1796        4416 :                             Point aEndPoint ( aStartPoint.getX() - fWR*(cos(fT) - cos(fTE)), aStartPoint.getY() - fHR*(sin(fT) - sin(fTE)) );
    1797             : 
    1798             :                             OSL_TRACE("ARCANGLETO rect: %d, %d   x   %d, %d   start: %d, %d end: %d, %d clockwise: %d",
    1799             :                                       aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom(),
    1800             :                                       aStartPoint.X(), aStartPoint.Y(), aEndPoint.X(), aEndPoint.Y(), bClockwise);
    1801        4416 :                             aNewB2DPolygon.append(CreateArc( aRect, bClockwise ? aEndPoint : aStartPoint, bClockwise ? aStartPoint : aEndPoint, bClockwise, aStartPoint == aEndPoint && fSwingAngle > F_PI));
    1802             :                         }
    1803             : 
    1804        4416 :                         rSrcPt += 2;
    1805             :                     }
    1806             :                 }
    1807        3202 :                 break;
    1808             : 
    1809             :                 case ELLIPTICALQUADRANTX :
    1810             :                 case ELLIPTICALQUADRANTY :
    1811             :                 {
    1812           0 :                     bool bFirstDirection(true);
    1813           0 :                     basegfx::B2DPoint aControlPointA;
    1814           0 :                     basegfx::B2DPoint aControlPointB;
    1815             : 
    1816           0 :                     for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ )
    1817             :                     {
    1818           0 :                         sal_uInt32 nModT = ( nCommand == ELLIPTICALQUADRANTX ) ? 1 : 0;
    1819           0 :                         Point aCurrent( GetPoint( seqCoordinates[ rSrcPt ], true, true ) );
    1820             : 
    1821           0 :                         if ( rSrcPt )   // we need a previous point
    1822             :                         {
    1823           0 :                             Point aPrev( GetPoint( seqCoordinates[ rSrcPt - 1 ], true, true ) );
    1824             :                             sal_Int32 nX, nY;
    1825           0 :                             nX = aCurrent.X() - aPrev.X();
    1826           0 :                             nY = aCurrent.Y() - aPrev.Y();
    1827           0 :                             if ( ( nY ^ nX ) & 0x80000000 )
    1828             :                             {
    1829           0 :                                 if ( !i )
    1830           0 :                                     bFirstDirection = true;
    1831           0 :                                 else if ( !bFirstDirection )
    1832           0 :                                     nModT ^= 1;
    1833             :                             }
    1834             :                             else
    1835             :                             {
    1836           0 :                                 if ( !i )
    1837           0 :                                     bFirstDirection = false;
    1838           0 :                                 else if ( bFirstDirection )
    1839           0 :                                     nModT ^= 1;
    1840             :                             }
    1841           0 :                             if ( nModT )            // get the right corner
    1842             :                             {
    1843           0 :                                 nX = aCurrent.X();
    1844           0 :                                 nY = aPrev.Y();
    1845             :                             }
    1846             :                             else
    1847             :                             {
    1848           0 :                                 nX = aPrev.X();
    1849           0 :                                 nY = aCurrent.Y();
    1850             :                             }
    1851           0 :                             sal_Int32 nXVec = ( nX - aPrev.X() ) >> 1;
    1852           0 :                             sal_Int32 nYVec = ( nY - aPrev.Y() ) >> 1;
    1853           0 :                             Point aControl1( aPrev.X() + nXVec, aPrev.Y() + nYVec );
    1854             : 
    1855           0 :                             aControlPointA = basegfx::B2DPoint(aControl1.X(), aControl1.Y());
    1856             : 
    1857           0 :                             nXVec = ( nX - aCurrent.X() ) >> 1;
    1858           0 :                             nYVec = ( nY - aCurrent.Y() ) >> 1;
    1859           0 :                             Point aControl2( aCurrent.X() + nXVec, aCurrent.Y() + nYVec );
    1860             : 
    1861           0 :                             aControlPointB = basegfx::B2DPoint(aControl2.X(), aControl2.Y());
    1862             : 
    1863             :                             aNewB2DPolygon.appendBezierSegment(
    1864             :                                 aControlPointA,
    1865             :                                 aControlPointB,
    1866           0 :                                 basegfx::B2DPoint(aCurrent.X(), aCurrent.Y()));
    1867             :                         }
    1868             :                         else
    1869             :                         {
    1870           0 :                             aNewB2DPolygon.append(basegfx::B2DPoint(aCurrent.X(), aCurrent.Y()));
    1871             :                         }
    1872             : 
    1873           0 :                         rSrcPt++;
    1874           0 :                     }
    1875             :                 }
    1876           0 :                 break;
    1877             : 
    1878             : #ifdef DBG_CUSTOMSHAPE
    1879             :                 case UNKNOWN :
    1880             :                 default :
    1881             :                 {
    1882             :                     OStringBuffer aString("CustomShapes::unknown PolyFlagValue :");
    1883             :                     aString.append(static_cast<sal_Int32>(nCommand));
    1884             :                     OSL_FAIL(aString.getStr());
    1885             :                 }
    1886             :                 break;
    1887             : #endif
    1888             :             }
    1889       16008 :             if ( nCommand == ENDSUBPATH )
    1890        3006 :                 break;
    1891             :         }
    1892             :     }
    1893        3066 :     if ( rSegmentInd == nSegInfoSize )
    1894        2766 :         rSegmentInd++;
    1895             : 
    1896        3066 :     if(aNewB2DPolygon.count() > 1L)
    1897             :     {
    1898             :         // #i76201# Add conversion to closed polygon when first and last points are equal
    1899        1640 :         basegfx::tools::checkClosed(aNewB2DPolygon);
    1900        1640 :         aNewB2DPolyPolygon.append(aNewB2DPolygon);
    1901             :     }
    1902             : 
    1903        3066 :     if(aNewB2DPolyPolygon.count())
    1904             :     {
    1905        3066 :         if( !bLineGeometryNeededOnly )
    1906             :         {
    1907             :             // hack aNewB2DPolyPolygon to fill logic rect - this is
    1908             :             // needed to produce gradient fills that look like mso
    1909        2848 :             aNewB2DPolygon.clear();
    1910        2848 :             aNewB2DPolygon.append(basegfx::B2DPoint(0,0));
    1911        2848 :             aNewB2DPolygon.setClosed(true);
    1912        2848 :             aNewB2DPolyPolygon.append(aNewB2DPolygon);
    1913             : 
    1914        2848 :             aNewB2DPolygon.clear();
    1915        2848 :             aNewB2DPolygon.append(basegfx::B2DPoint(aLogicRect.GetWidth(),
    1916        5696 :                                                     aLogicRect.GetHeight()));
    1917        2848 :             aNewB2DPolygon.setClosed(true);
    1918        2848 :             aNewB2DPolyPolygon.append(aNewB2DPolygon);
    1919             :         }
    1920             : 
    1921             :         // #i37011#
    1922        3066 :         bool bForceCreateTwoObjects(false);
    1923             : 
    1924        3066 :         if(!bSortFilledObjectsToBack && !aNewB2DPolyPolygon.isClosed() && !bNoStroke)
    1925             :         {
    1926         912 :             bForceCreateTwoObjects = true;
    1927             :         }
    1928             : 
    1929        3066 :         if(bLineGeometryNeededOnly)
    1930             :         {
    1931         218 :             bForceCreateTwoObjects = true;
    1932         218 :             bNoFill = true;
    1933         218 :             bNoStroke = false;
    1934             :         }
    1935             : 
    1936        3066 :         if(bForceCreateTwoObjects || bSortFilledObjectsToBack)
    1937             :         {
    1938        2952 :             if(bFilled && !bNoFill)
    1939             :             {
    1940        1878 :                 basegfx::B2DPolyPolygon aClosedPolyPolygon(aNewB2DPolyPolygon);
    1941        1878 :                 aClosedPolyPolygon.setClosed(true);
    1942        1878 :                 SdrPathObj* pFill = new SdrPathObj(OBJ_POLY, aClosedPolyPolygon, dBrightness);
    1943        3756 :                 SfxItemSet aTempSet(*this);
    1944        1878 :                 aTempSet.Put(makeSdrShadowItem(false));
    1945        1878 :                 aTempSet.Put(XLineStyleItem(XLINE_NONE));
    1946        1878 :                 pFill->SetMergedItemSet(aTempSet);
    1947        3756 :                 rObjectList.push_back(pFill);
    1948             :             }
    1949             : 
    1950        2952 :             if(!bNoStroke)
    1951             :             {
    1952             :                 // there is no reason to use OBJ_PLIN here when the polygon is actually closed,
    1953             :                 // the non-fill is defined by XFILL_NONE. Since SdrPathObj::ImpForceKind() needs
    1954             :                 // to correct the polygon (here: open it) using the type, the last edge may get lost.
    1955             :                 // Thus, use a type that fits the polygon
    1956             :                 SdrPathObj* pStroke = new SdrPathObj(
    1957        2940 :                     aNewB2DPolyPolygon.isClosed() ? OBJ_POLY : OBJ_PLIN,
    1958        2940 :                     aNewB2DPolyPolygon, dBrightness);
    1959        2940 :                 SfxItemSet aTempSet(*this);
    1960        2940 :                 aTempSet.Put(makeSdrShadowItem(false));
    1961        2940 :                 aTempSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
    1962        2940 :                 pStroke->SetMergedItemSet(aTempSet);
    1963        2940 :                 rObjectList.push_back(pStroke);
    1964        2952 :             }
    1965             :         }
    1966             :         else
    1967             :         {
    1968         114 :             SdrPathObj* pObj = 0;
    1969         114 :             SfxItemSet aTempSet(*this);
    1970         114 :             aTempSet.Put(makeSdrShadowItem(false));
    1971             : 
    1972         114 :             if(bNoFill)
    1973             :             {
    1974             :                 // see comment above about OBJ_PLIN
    1975             :                 pObj = new SdrPathObj(
    1976           0 :                     aNewB2DPolyPolygon.isClosed() ? OBJ_POLY : OBJ_PLIN,
    1977           0 :                     aNewB2DPolyPolygon, dBrightness);
    1978           0 :                 aTempSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
    1979             :             }
    1980             :             else
    1981             :             {
    1982         114 :                 aNewB2DPolyPolygon.setClosed(true);
    1983         114 :                 pObj = new SdrPathObj(OBJ_POLY, aNewB2DPolyPolygon, dBrightness);
    1984             :             }
    1985             : 
    1986         114 :             if(bNoStroke)
    1987             :             {
    1988           0 :                 aTempSet.Put(XLineStyleItem(XLINE_NONE));
    1989             :             }
    1990             : 
    1991         114 :             if(pObj)
    1992             :             {
    1993         114 :                 pObj->SetMergedItemSet(aTempSet);
    1994         114 :                 rObjectList.push_back(pObj);
    1995         114 :             }
    1996             :         }
    1997        3066 :     }
    1998        3066 : }
    1999             : 
    2000         106 : void CorrectCalloutArrows( MSO_SPT eSpType, sal_uInt32 nLineObjectCount, std::vector< SdrPathObj* >& vObjectList )
    2001             : {
    2002         106 :     bool bAccent = false;
    2003         106 :     switch( eSpType )
    2004             :     {
    2005             :         case mso_sptCallout1 :
    2006             :         case mso_sptBorderCallout1 :
    2007             :         case mso_sptCallout90 :
    2008             :         case mso_sptBorderCallout90 :
    2009             :         default:
    2010         106 :         break;
    2011             : 
    2012             :         case mso_sptAccentCallout1 :
    2013             :         case mso_sptAccentBorderCallout1 :
    2014             :         case mso_sptAccentCallout90 :
    2015             :         case mso_sptAccentBorderCallout90 :
    2016             :         {
    2017           0 :             sal_uInt32 i, nLine = 0;
    2018           0 :             for ( i = 0; i < vObjectList.size(); i++ )
    2019             :             {
    2020           0 :                 SdrPathObj* pObj( vObjectList[ i ] );
    2021           0 :                 if(pObj->IsLine())
    2022             :                 {
    2023           0 :                     nLine++;
    2024           0 :                     if ( nLine == nLineObjectCount )
    2025             :                     {
    2026           0 :                         pObj->ClearMergedItem( XATTR_LINESTART );
    2027           0 :                         pObj->ClearMergedItem( XATTR_LINEEND );
    2028             :                     }
    2029             :                 }
    2030             :             }
    2031             :         }
    2032           0 :         break;
    2033             : 
    2034             :         // switch start & end
    2035             :         case mso_sptAccentCallout2 :
    2036             :         case mso_sptAccentBorderCallout2 :
    2037           0 :             bAccent = true;
    2038             :             //fall-through
    2039             :         case mso_sptCallout2 :
    2040             :         case mso_sptBorderCallout2 :
    2041             :         {
    2042           0 :             sal_uInt32 i, nLine = 0;
    2043           0 :             for ( i = 0; i < vObjectList.size(); i++ )
    2044             :             {
    2045           0 :                 SdrPathObj* pObj( vObjectList[ i ] );
    2046           0 :                 if(pObj->IsLine())
    2047             :                 {
    2048           0 :                     nLine++;
    2049           0 :                     if ( nLine == 1 )
    2050           0 :                         pObj->ClearMergedItem( XATTR_LINEEND );
    2051           0 :                     else if ( ( bAccent && ( nLine == nLineObjectCount - 1 ) ) || ( !bAccent && ( nLine == nLineObjectCount ) ) )
    2052           0 :                         pObj->ClearMergedItem( XATTR_LINESTART );
    2053             :                     else
    2054             :                     {
    2055           0 :                         pObj->ClearMergedItem( XATTR_LINESTART );
    2056           0 :                         pObj->ClearMergedItem( XATTR_LINEEND );
    2057             :                     }
    2058             :                 }
    2059             :             }
    2060             :         }
    2061           0 :         break;
    2062             : 
    2063             :         case mso_sptAccentCallout3 :
    2064             :         case mso_sptAccentBorderCallout3 :
    2065           0 :             bAccent = false;
    2066             :             //fall-through
    2067             :         case mso_sptCallout3 :
    2068             :         case mso_sptBorderCallout3 :
    2069             :         {
    2070           0 :             sal_uInt32 i, nLine = 0;
    2071           0 :             for ( i = 0; i < vObjectList.size(); i++ )
    2072             :             {
    2073           0 :                 SdrPathObj* pObj( vObjectList[ i ] );
    2074           0 :                 if(pObj->IsLine())
    2075             :                 {
    2076           0 :                     if ( nLine )
    2077             :                     {
    2078           0 :                         pObj->ClearMergedItem( XATTR_LINESTART );
    2079           0 :                         pObj->ClearMergedItem( XATTR_LINEEND );
    2080             :                     }
    2081             :                     else
    2082           0 :                         EnhancedCustomShape2d::SwapStartAndEndArrow( pObj );
    2083             : 
    2084           0 :                     nLine++;
    2085             :                 }
    2086             :             }
    2087             :         }
    2088           0 :         break;
    2089             :     }
    2090         106 : }
    2091             : 
    2092        4538 : void EnhancedCustomShape2d::AdaptObjColor(SdrPathObj& rObj, const SfxItemSet& rCustomShapeSet,
    2093             :                                           sal_uInt32& nColorIndex, sal_uInt32 nColorCount)
    2094             : {
    2095        4538 :     if ( !rObj.IsLine() )
    2096             :     {
    2097        3772 :         const drawing::FillStyle eFillStyle = static_cast<const XFillStyleItem&>(rObj.GetMergedItem(XATTR_FILLSTYLE)).GetValue();
    2098        3772 :         switch( eFillStyle )
    2099             :         {
    2100             :             default:
    2101             :             case drawing::FillStyle_SOLID:
    2102             :             {
    2103        3404 :                 Color aFillColor;
    2104        3404 :                 if ( nColorCount || rObj.GetBrightness() != 1.0 )
    2105             :                 {
    2106             :                     aFillColor = GetColorData(
    2107          24 :                         static_cast<const XFillColorItem&>(rCustomShapeSet.Get( XATTR_FILLCOLOR )).GetColorValue(),
    2108          48 :                         std::min(nColorIndex, nColorCount-1), rObj.GetBrightness() );
    2109          24 :                     rObj.SetMergedItem( XFillColorItem( "", aFillColor ) );
    2110             :                 }
    2111        3404 :                 break;
    2112             :             }
    2113             :             case drawing::FillStyle_GRADIENT:
    2114             :             {
    2115         274 :                 XGradient aXGradient(static_cast<const XFillGradientItem&>(rObj.GetMergedItem(XATTR_FILLGRADIENT)).GetGradientValue());
    2116         274 :                 if ( nColorCount || rObj.GetBrightness() != 1.0 )
    2117             :                 {
    2118             :                     aXGradient.SetStartColor(
    2119             :                         GetColorData(
    2120             :                             aXGradient.GetStartColor(),
    2121           0 :                             std::min(nColorIndex, nColorCount-1), rObj.GetBrightness() ));
    2122             :                     aXGradient.SetEndColor(
    2123             :                         GetColorData(
    2124             :                             aXGradient.GetEndColor(),
    2125           0 :                             std::min(nColorIndex, nColorCount-1), rObj.GetBrightness() ));
    2126             :                 }
    2127             : 
    2128         274 :                 rObj.SetMergedItem( XFillGradientItem( "", aXGradient ) );
    2129         274 :                 break;
    2130             :             }
    2131             :             case drawing::FillStyle_HATCH:
    2132             :             {
    2133           4 :                 XHatch aXHatch(static_cast<const XFillHatchItem&>(rObj.GetMergedItem(XATTR_FILLHATCH)).GetHatchValue());
    2134           4 :                 if ( nColorCount || rObj.GetBrightness() != 1.0 )
    2135             :                 {
    2136             :                     aXHatch.SetColor(
    2137             :                         GetColorData(
    2138             :                             aXHatch.GetColor(),
    2139           0 :                             std::min(nColorIndex, nColorCount-1), rObj.GetBrightness() ));
    2140             :                 }
    2141             : 
    2142           4 :                 rObj.SetMergedItem( XFillHatchItem( "", aXHatch ) );
    2143           4 :                 break;
    2144             :             }
    2145             :             case drawing::FillStyle_BITMAP:
    2146             :             {
    2147          90 :                 if ( nColorCount || rObj.GetBrightness() != 1.0 )
    2148             :                 {
    2149           0 :                     Bitmap aBitmap(static_cast<const XFillBitmapItem&>(rObj.GetMergedItem(XATTR_FILLBITMAP)).GetGraphicObject().GetGraphic().GetBitmapEx().GetBitmap());
    2150             : 
    2151             :                     aBitmap.Adjust(
    2152             :                         static_cast< short > ( GetLuminanceChange(
    2153           0 :                             std::min(nColorIndex, nColorCount-1))));
    2154             : 
    2155           0 :                     rObj.SetMergedItem(XFillBitmapItem(OUString(), Graphic(aBitmap)));
    2156             :                 }
    2157             : 
    2158          90 :                 break;
    2159             :             }
    2160             :         }
    2161             : 
    2162        3772 :         if ( nColorIndex < nColorCount )
    2163          24 :             nColorIndex++;
    2164             :     }
    2165        4538 : }
    2166             : 
    2167        7362 : SdrObject* EnhancedCustomShape2d::CreatePathObj( bool bLineGeometryNeededOnly )
    2168             : {
    2169        7362 :     sal_Int32 nCoordSize = seqCoordinates.getLength();
    2170        7362 :     if ( !nCoordSize )
    2171        4596 :         return NULL;
    2172             : 
    2173        2766 :     sal_uInt16 nSrcPt = 0;
    2174        2766 :     sal_uInt16 nSegmentInd = 0;
    2175             : 
    2176        2766 :     std::vector< SdrPathObj* > vObjectList;
    2177        2766 :     bool bSortFilledObjectsToBack = SortFilledObjectsToBackByDefault( eSpType );
    2178             : 
    2179        2766 :     sal_Int32 nSubPathIndex = 0;
    2180             : 
    2181        8598 :     while( nSegmentInd <= seqSegments.getLength() )
    2182             :     {
    2183        3066 :         CreateSubPath( nSrcPt, nSegmentInd, vObjectList, bLineGeometryNeededOnly, bSortFilledObjectsToBack, nSubPathIndex );
    2184        3066 :         nSubPathIndex ++;
    2185             :     }
    2186             : 
    2187        2766 :     SdrObject* pRet = NULL;
    2188             : 
    2189        2766 :     if ( !vObjectList.empty() )
    2190             :     {
    2191        2766 :         const SfxItemSet& rCustomShapeSet = pCustomShapeObj->GetMergedItemSet();
    2192        2766 :         sal_uInt32      nColorCount = nColorData >> 28;
    2193        2766 :         sal_uInt32      nColorIndex = 0;
    2194             : 
    2195             :         // #i37011# remove invisible objects
    2196        2766 :         if(!vObjectList.empty())
    2197             :         {
    2198        2766 :             std::vector< SdrPathObj* > vTempList;
    2199             : 
    2200        7698 :             for(size_t i = 0; i < vObjectList.size(); ++i)
    2201             :             {
    2202        4932 :                 SdrPathObj* pObj(vObjectList[i]);
    2203        4932 :                 const XLineStyle eLineStyle =static_cast<const XLineStyleItem&>(pObj->GetMergedItem(XATTR_LINESTYLE)).GetValue();
    2204        4932 :                 const drawing::FillStyle eFillStyle = static_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE)).GetValue();
    2205             : 
    2206             :                 //SJ: #i40600# if bLineGeometryNeededOnly is set linystyle does not matter
    2207        4932 :                 if( !bLineGeometryNeededOnly && ( XLINE_NONE == eLineStyle ) && ( drawing::FillStyle_NONE == eFillStyle ) )
    2208         182 :                     delete pObj;
    2209             :                 else
    2210        4750 :                     vTempList.push_back(pObj);
    2211             :             }
    2212             : 
    2213        2766 :             vObjectList = vTempList;
    2214             :         }
    2215             : 
    2216        2766 :         if(1L == vObjectList.size())
    2217             :         {
    2218             :             // a single object, correct some values
    2219         904 :             AdaptObjColor(*vObjectList[0L],rCustomShapeSet,nColorIndex,nColorCount);
    2220             :         }
    2221             :         else
    2222             :         {
    2223        1862 :             sal_Int32 nLineObjectCount = 0;
    2224        1862 :             sal_Int32 nAreaObjectCount = 0;
    2225             : 
    2226             :             // correct some values and collect content data
    2227        5708 :             for ( size_t i = 0; i < vObjectList.size(); ++i )
    2228             :             {
    2229        3846 :                 SdrPathObj* pObj( vObjectList[ i ] );
    2230             : 
    2231        3846 :                 if(pObj->IsLine())
    2232             :                 {
    2233         212 :                     nLineObjectCount++;
    2234             :                 }
    2235             :                 else
    2236             :                 {
    2237        3634 :                     nAreaObjectCount++;
    2238        3634 :                     AdaptObjColor(*pObj,rCustomShapeSet,nColorIndex,nColorCount);
    2239             :                 }
    2240             :             }
    2241             : 
    2242             :             // #i88870# correct line arrows for callouts
    2243        1862 :             if ( nLineObjectCount )
    2244         106 :                 CorrectCalloutArrows( eSpType, nLineObjectCount, vObjectList );
    2245             : 
    2246             :             // sort objects so that filled ones are in front. Necessary
    2247             :             // for some strange objects
    2248        1862 :             if ( bSortFilledObjectsToBack )
    2249             :             {
    2250        1732 :                 std::vector< SdrPathObj* > vTempList;
    2251        1732 :                 vTempList.reserve(vObjectList.size());
    2252             : 
    2253        5354 :                 for ( size_t i = 0; i < vObjectList.size(); ++i )
    2254             :                 {
    2255        3622 :                     SdrPathObj* pObj( vObjectList[ i ] );
    2256             : 
    2257        3622 :                     if ( !pObj->IsLine() )
    2258             :                     {
    2259        3602 :                         vTempList.push_back(pObj);
    2260             :                     }
    2261             :                 }
    2262             : 
    2263        5354 :                 for ( size_t i = 0; i < vObjectList.size(); ++i )
    2264             :                 {
    2265        3622 :                     SdrPathObj* pObj( vObjectList[ i ] );
    2266             : 
    2267        3622 :                     if ( pObj->IsLine() )
    2268             :                     {
    2269          20 :                         vTempList.push_back(pObj);
    2270             :                     }
    2271             :                 }
    2272             : 
    2273        1732 :                 vObjectList = vTempList;
    2274             :             }
    2275             :         }
    2276             :     }
    2277             : 
    2278             :     // #i37011#
    2279        2766 :     if(!vObjectList.empty())
    2280             :     {
    2281             :         // copy remaining objects to pRet
    2282        2654 :         if(vObjectList.size() > 1)
    2283             :         {
    2284        1750 :             pRet = new SdrObjGroup;
    2285             : 
    2286        5596 :             for (size_t i = 0; i < vObjectList.size(); ++i)
    2287             :             {
    2288        3846 :                 SdrObject* pObj(vObjectList[i]);
    2289        3846 :                 pRet->GetSubList()->NbcInsertObject(pObj);
    2290             :             }
    2291             :         }
    2292         904 :         else if(1 == vObjectList.size())
    2293             :         {
    2294         904 :             pRet = vObjectList[0L];
    2295             :         }
    2296             : 
    2297        2654 :         if(pRet)
    2298             :         {
    2299             :             // move to target position
    2300        2654 :             Rectangle aCurRect(pRet->GetSnapRect());
    2301        2654 :             aCurRect.Move(aLogicRect.Left(), aLogicRect.Top());
    2302        2654 :             pRet->NbcSetSnapRect(aCurRect);
    2303             :         }
    2304             :     }
    2305             : 
    2306        2766 :     return pRet;
    2307             : }
    2308             : 
    2309       10172 : SdrObject* EnhancedCustomShape2d::CreateObject( bool bLineGeometryNeededOnly )
    2310             : {
    2311       10172 :     SdrObject* pRet = NULL;
    2312             : 
    2313       10172 :     if ( eSpType == mso_sptRectangle )
    2314             :     {
    2315        2810 :         pRet = new SdrRectObj( aLogicRect );
    2316        2810 :         pRet->SetMergedItemSet( *this );
    2317             :     }
    2318       10172 :     if ( !pRet )
    2319        7362 :         pRet = CreatePathObj( bLineGeometryNeededOnly );
    2320             : 
    2321       10172 :     return pRet;
    2322             : }
    2323             : 
    2324        5448 : void EnhancedCustomShape2d::ApplyGluePoints( SdrObject* pObj )
    2325             : {
    2326        5448 :     if ( pObj && seqGluePoints.getLength() )
    2327             :     {
    2328          28 :         sal_uInt32 i, nCount = seqGluePoints.getLength();
    2329         188 :         for ( i = 0; i < nCount; i++ )
    2330             :         {
    2331         160 :             SdrGluePoint aGluePoint;
    2332             : 
    2333         160 :             aGluePoint.SetPos( GetPoint( seqGluePoints[ i ], true, true ) );
    2334         160 :             aGluePoint.SetPercent( false );
    2335         160 :             aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT );
    2336         160 :             aGluePoint.SetEscDir( SDRESC_SMART );
    2337         160 :             SdrGluePointList* pList = pObj->ForceGluePointList();
    2338         160 :             if( pList )
    2339         160 :                 /* sal_uInt16 nId = */ pList->Insert( aGluePoint );
    2340             :         }
    2341             :     }
    2342        5448 : }
    2343             : 
    2344       10156 : bool EnhancedCustomShape2d::IsPostRotate() const
    2345             : {
    2346       10156 :     return pCustomShapeObj->ISA( SdrObjCustomShape ) && static_cast<SdrObjCustomShape*>(pCustomShapeObj)->IsPostRotate();
    2347             : }
    2348             : 
    2349          16 : SdrObject* EnhancedCustomShape2d::CreateLineGeometry()
    2350             : {
    2351          16 :     return CreateObject( true );
    2352         651 : }
    2353             : 
    2354             : 
    2355             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10