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

Generated by: LCOV version 1.11