LCOV - code coverage report
Current view: top level - oox/source/drawingml - customshapegeometry.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 480 545 88.1 %
Date: 2014-04-11 Functions: 57 59 96.6 %
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 "oox/drawingml/customshapegeometry.hxx"
      21             : 
      22             : #include <com/sun/star/xml/sax/FastToken.hpp>
      23             : #include <boost/unordered_map.hpp>
      24             : #include "oox/helper/helper.hxx"
      25             : #include "oox/helper/attributelist.hxx"
      26             : #include "oox/helper/propertymap.hxx"
      27             : 
      28             : using namespace ::oox::core;
      29             : using namespace ::com::sun::star::uno;
      30             : using namespace ::com::sun::star::beans;
      31             : using namespace ::com::sun::star::drawing;
      32             : using namespace ::com::sun::star::xml::sax;
      33             : 
      34             : namespace oox { namespace drawingml {
      35             : 
      36             : enum FormularCommand
      37             : {
      38             :     FC_MULDIV = 0,
      39             :     FC_PLUSMINUS,
      40             :     FC_PLUSDIV,
      41             :     FC_IFELSE,
      42             :     FC_IFELSE1,
      43             :     FC_ABS,
      44             :     FC_AT2,
      45             :     FC_CAT2,
      46             :     FC_COS,
      47             :     FC_MAX,
      48             :     FC_MIN,
      49             :     FC_MOD,
      50             :     FC_PIN,
      51             :     FC_SAT2,
      52             :     FC_SIN,
      53             :     FC_SQRT,
      54             :     FC_TAN,
      55             :     FC_VAL,
      56             :     FC_LAST
      57             : };
      58             : struct FormularCommandNameTable
      59             : {
      60             :     const char*     pS;
      61             :     FormularCommand pE;
      62             : };
      63             : static const FormularCommandNameTable pFormularCommandNameTable[] =
      64             : {
      65             :     { "*/",     FC_MULDIV },
      66             :     { "+-",     FC_PLUSMINUS },
      67             :     { "+/",     FC_PLUSDIV },
      68             :     { "ifelse", FC_IFELSE },
      69             :     { "?:",     FC_IFELSE1 },
      70             :     { "abs",    FC_ABS },
      71             :     { "at2",    FC_AT2 },
      72             :     { "cat2",   FC_CAT2 },
      73             :     { "cos",    FC_COS },
      74             :     { "max",    FC_MAX },
      75             :     { "min",    FC_MIN },
      76             :     { "mod",    FC_MOD },
      77             :     { "pin",    FC_PIN },
      78             :     { "sat2",   FC_SAT2 },
      79             :     { "sin",    FC_SIN },
      80             :     { "sqrt",   FC_SQRT },
      81             :     { "tan",    FC_TAN },
      82             :     { "val",    FC_VAL }
      83             : 
      84             : };
      85             : typedef boost::unordered_map< OUString, FormularCommand, OUStringHash > FormulaCommandHMap;
      86             : 
      87             : static const FormulaCommandHMap* pCommandHashMap;
      88             : 
      89             : 
      90       12162 : OUString GetFormulaParameter( const EnhancedCustomShapeParameter& rParameter )
      91             : {
      92       12162 :     OUString aRet;
      93       12162 :     switch( rParameter.Type )
      94             :     {
      95             :         case EnhancedCustomShapeParameterType::NORMAL :
      96             :         {
      97        5250 :             if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE )
      98             :             {
      99           0 :                 double fValue = 0.0;
     100           0 :                 if ( rParameter.Value >>= fValue )
     101           0 :                     aRet = OUString::number( fValue );
     102             :             }
     103             :             else
     104             :             {
     105        5250 :                 sal_Int32 nValue = 0;
     106        5250 :                 if ( rParameter.Value >>= nValue )
     107        5250 :                     aRet = OUString::number( nValue );
     108             :             }
     109             :         }
     110        5250 :         break;
     111             :         case EnhancedCustomShapeParameterType::EQUATION :
     112             :         {
     113        5744 :             if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
     114             :             {
     115             :                 sal_Int32 nFormulaIndex;
     116        5744 :                 if ( rParameter.Value >>= nFormulaIndex )
     117             :                 {
     118       11488 :                     aRet = "?"
     119       11488 :                         + OUString::number( nFormulaIndex )
     120       17232 :                             + " ";
     121             :                 }
     122             :             }
     123             :             else
     124             :             {
     125             :                 // ups... we should have an index here and not the formula name
     126             :             }
     127             :         }
     128        5744 :         break;
     129             :         case EnhancedCustomShapeParameterType::ADJUSTMENT :
     130             :         {
     131         304 :             if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
     132             :             {
     133             :                 sal_Int32 nAdjustmentIndex;
     134         304 :                 if ( rParameter.Value >>= nAdjustmentIndex )
     135             :                 {
     136         608 :                     aRet = "$"
     137         608 :                         + OUString::number( nAdjustmentIndex )
     138         912 :                             + " ";
     139             :                 }
     140             :             }
     141             :             else
     142             :             {
     143             :                 // ups... we should have an index here and not the formula name
     144             :             }
     145             :         }
     146         304 :         break;
     147             :         case EnhancedCustomShapeParameterType::LEFT :
     148             :         {
     149           0 :             const OUString sLeft( "left" );
     150           0 :             aRet = sLeft;
     151             :         }
     152           0 :         break;
     153             :         case EnhancedCustomShapeParameterType::TOP :
     154             :         {
     155           0 :             const OUString sTop( "top" );
     156           0 :             aRet = sTop;
     157             :         }
     158           0 :         break;
     159             :         case EnhancedCustomShapeParameterType::RIGHT :
     160             :         {
     161           0 :             const OUString sRight( "right" );
     162           0 :             aRet = sRight;
     163             :         }
     164           0 :         break;
     165             :         case EnhancedCustomShapeParameterType::BOTTOM :
     166             :         {
     167           0 :             const OUString sBottom( "bottom" );
     168           0 :             aRet = sBottom;
     169             :         }
     170           0 :         break;
     171             :         case EnhancedCustomShapeParameterType::XSTRETCH :
     172             :         {
     173           0 :             const OUString sXStretch( "xstretch" );
     174           0 :             aRet = sXStretch;
     175             :         }
     176           0 :         break;
     177             :         case EnhancedCustomShapeParameterType::YSTRETCH :
     178             :         {
     179           0 :             const OUString sYStretch( "ystretch" );
     180           0 :             aRet = sYStretch;
     181             :         }
     182           0 :         break;
     183             :         case EnhancedCustomShapeParameterType::HASSTROKE :
     184             :         {
     185           0 :             const OUString sHasStroke( "hasstroke" );
     186           0 :             aRet = sHasStroke;
     187             :         }
     188           0 :         break;
     189             :         case EnhancedCustomShapeParameterType::HASFILL :
     190             :         {
     191           0 :             const OUString sHasFill( "hasfill"  );
     192           0 :             aRet = sHasFill;
     193             :         }
     194           0 :         break;
     195             :         case EnhancedCustomShapeParameterType::WIDTH :
     196             :         {
     197           0 :             const OUString sWidth( "width"  );
     198           0 :             aRet = sWidth;
     199             :         }
     200           0 :         break;
     201             :         case EnhancedCustomShapeParameterType::HEIGHT :
     202             :         {
     203           0 :             const OUString sHeight( "height"  );
     204           0 :             aRet = sHeight;
     205             :         }
     206           0 :         break;
     207             :         case EnhancedCustomShapeParameterType::LOGWIDTH :
     208             :         {
     209         449 :             const OUString sLogWidth( "logwidth"  );
     210         449 :             aRet = sLogWidth;
     211             :         }
     212         449 :         break;
     213             :         case EnhancedCustomShapeParameterType::LOGHEIGHT :
     214             :         {
     215         415 :             const OUString sLogHeight( "logheight"  );
     216         415 :             aRet = sLogHeight;
     217             :         }
     218         415 :         break;
     219             :     }
     220       12162 :     return aRet;
     221             : }
     222             : 
     223             : 
     224             : 
     225       26920 : static EnhancedCustomShapeParameter GetAdjCoordinate( CustomShapeProperties& rCustomShapeProperties, const OUString& rValue, bool bNoSymbols = true )
     226             : {
     227       26920 :     com::sun::star::drawing::EnhancedCustomShapeParameter aRet;
     228       26920 :     if ( !rValue.isEmpty() )
     229             :     {
     230       26920 :         bool        bConstant = true;
     231       26920 :         sal_Int32   nConstant = -1;
     232       26920 :         sal_Int32   nIntVal = 0;
     233             : 
     234             :         // first check if it's a constant value
     235       26920 :         switch( AttributeConversion::decodeToken( rValue ) )
     236             :         {
     237         299 :             case XML_3cd4 : nConstant = 270 * 60000; break;
     238           0 :             case XML_3cd8 : nConstant = 135 * 60000; break;
     239           0 :             case XML_5cd8 : nConstant = 225 * 60000; break;
     240           0 :             case XML_7cd8 : nConstant = 315 * 60000; break;
     241         335 :             case XML_cd2  : nConstant = 180 * 60000; break;
     242           1 :             case XML_cd3  : nConstant = 120 * 60000; break;
     243         454 :             case XML_cd4  : nConstant =  90 * 60000; break;
     244           0 :             case XML_cd8  : nConstant =  45 * 60000; break;
     245             : 
     246             :             case XML_b :    // variable height of the shape defined in spPr
     247             :             case XML_h :
     248             :             {
     249        1048 :                 if ( bNoSymbols )
     250             :                 {
     251         633 :                     CustomShapeGuide aGuide;
     252         633 :                     aGuide.maName = rValue;
     253         633 :                     aGuide.maFormula = "logheight" ;
     254             : 
     255         633 :                     aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     256         633 :                     aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     257             :                 }
     258             :                 else
     259         415 :                     aRet.Type = EnhancedCustomShapeParameterType::LOGHEIGHT;   // TODO: HEIGHT needs to be implemented
     260             :             }
     261        1048 :             break;
     262             : 
     263             : 
     264             :             case XML_hd10 :   // !!PASSTHROUGH INTENDED
     265           2 :                 nIntVal += 2; // */ h 1.0 10.0
     266             :             case XML_hd8 :    // */ h 1.0 8.0
     267           3 :                 nIntVal += 2;
     268             :             case XML_hd6 :    // */ h 1.0 6.0
     269           6 :                 nIntVal++;
     270             :             case XML_hd5 :    // */ h 1.0 5.0
     271           9 :                 nIntVal++;
     272             :             case XML_hd4 :    // */ h 1.0 4.0
     273          38 :                 nIntVal++;
     274             :             case XML_hd3 :    // */ h 1.0 3.0
     275          43 :                 nIntVal++;
     276             :             case XML_hd2 :    // */ h 1.0 2.0
     277             :             case XML_vc :     // */ h 1.0 2.0
     278             :             {
     279         818 :                 nIntVal += 2;
     280             : 
     281         818 :                 CustomShapeGuide aGuide;
     282         818 :                 aGuide.maName = rValue;
     283         818 :                 aGuide.maFormula = "logheight/" + OUString::number( nIntVal );
     284             : 
     285         818 :                 aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     286         818 :                 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     287             :             }
     288         818 :             break;
     289             : 
     290             :             case XML_t :
     291             :             case XML_l :
     292             :             {
     293        1075 :                 nConstant = 0;
     294        1075 :                 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
     295             :             }
     296        1075 :             break;
     297             : 
     298             :             case XML_ls :   // longest side: max w h
     299             :             {
     300           0 :                 CustomShapeGuide aGuide;
     301           0 :                 aGuide.maName = rValue;
     302           0 :                 aGuide.maFormula = "max(logwidth,logheight)";
     303             : 
     304           0 :                 aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     305           0 :                 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     306             :             }
     307           0 :             break;
     308             :             case XML_ss :   // shortest side: min w h
     309             :             {
     310         222 :                 CustomShapeGuide aGuide;
     311         222 :                 aGuide.maName = rValue;
     312         222 :                 aGuide.maFormula = "min(logwidth,logheight)";
     313             : 
     314         222 :                 aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     315         222 :                 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     316             :             }
     317         222 :             break;
     318             :             case XML_ssd32 : // */ ss 1.0 32.0
     319           2 :                 nIntVal += 16;
     320             :             case XML_ssd16 : // */ ss 1.0 16.0
     321           4 :                 nIntVal += 8;
     322             :             case XML_ssd8 :  // */ ss 1.0 8.0
     323           9 :                 nIntVal += 2;
     324             :             case XML_ssd6 :  // */ ss 1.0 6.0
     325          22 :                 nIntVal += 2;
     326             :             case XML_ssd4 :  // */ ss 1.0 4.0
     327          22 :                 nIntVal += 2;
     328             :             case XML_ssd2 :  // */ ss 1.0 2.0
     329             :             {
     330          24 :                 nIntVal += 2;
     331             : 
     332          24 :                 CustomShapeGuide aGuide;
     333          24 :                 aGuide.maName = rValue;
     334          24 :                 aGuide.maFormula = "min(logwidth,logheight)/" + OUString::number( nIntVal );
     335             : 
     336          24 :                 aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     337          24 :                 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     338             :             }
     339          24 :             break;
     340             : 
     341             :             case XML_r :    // variable width of the shape defined in spPr
     342             :             case XML_w :
     343             :             {
     344        1059 :                 if ( bNoSymbols )
     345             :                 {
     346         610 :                     CustomShapeGuide aGuide;
     347         610 :                     aGuide.maName = rValue;
     348         610 :                     aGuide.maFormula = "logwidth" ;
     349             : 
     350         610 :                     aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     351         610 :                     aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     352             :                 }
     353             :                 else
     354         449 :                     aRet.Type = EnhancedCustomShapeParameterType::LOGWIDTH;
     355             :             }
     356        1059 :             break;
     357             : 
     358             :             case XML_wd32 : // */ w 1.0 32.0
     359          51 :                 nIntVal += 20;
     360             :             case XML_wd12 : // */ w 1.0 12.0
     361          52 :                 nIntVal += 2;
     362             :             case XML_wd10 : // */ w 1.0 10.0
     363          54 :                 nIntVal += 2;
     364             :             case XML_wd8 :  // */ w 1.0 8.0
     365          78 :                 nIntVal += 2;
     366             :             case XML_wd6 :  // */ w 1.0 6.0
     367          82 :                 nIntVal++;
     368             :             case XML_wd5 :  // */ w 1.0 5.0
     369          85 :                 nIntVal++;
     370             :             case XML_wd4 :  // */ w 1.0 4.0
     371         101 :                 nIntVal++;
     372             :             case XML_wd3 :  // */ w 1.0 3.0
     373         104 :                 nIntVal++;
     374             :             case XML_hc :   // */ w 1.0 2.0
     375             :             case XML_wd2 :  // */ w 1.0 2.0
     376             :             {
     377         941 :                 nIntVal += 2;
     378             : 
     379         941 :                 CustomShapeGuide aGuide;
     380         941 :                 aGuide.maName = rValue;
     381         941 :                 aGuide.maFormula = "logwidth/" + OUString::number( nIntVal );
     382             : 
     383         941 :                 aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     384         941 :                 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     385             :             }
     386         941 :             break;
     387             : 
     388             :             default:
     389       20644 :                 bConstant = false;
     390       20644 :             break;
     391             :         }
     392       26920 :         if ( bConstant )
     393             :         {
     394        6276 :             if (nConstant != -1) {
     395        2164 :                 aRet.Value = Any( nConstant );
     396        2164 :                 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
     397             :             }
     398             :         }
     399             :         else
     400             :         {
     401       20644 :             sal_Unicode n = rValue[ 0 ];
     402       20644 :             if ( ( n == '+' ) || ( n == '-' ) )
     403             :             {
     404         276 :                 if ( rValue.getLength() > 1 )
     405         276 :                     n = rValue[ 1 ];
     406             :             }
     407       20644 :             if ( ( n >= '0' ) && ( n <= '9' ) )
     408             :             {   // seems to be a ST_Coordinate
     409       10913 :                 aRet.Value = Any( (sal_Int32)(rValue.toInt32() ) );
     410       10913 :                 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
     411             :             }
     412             :             else
     413             :             {
     414        9731 :                 sal_Int32 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getAdjustmentGuideList(), rValue );
     415        9731 :                 if ( nGuideIndex >= 0 )
     416             :                 {
     417         305 :                     aRet.Value = Any( nGuideIndex );
     418         305 :                     aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
     419             :                 }
     420             :                 else
     421             :                 {
     422        9426 :                     nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), rValue );
     423        9426 :                     if ( nGuideIndex >= 0 )
     424             :                     {
     425        9426 :                         aRet.Value = Any( nGuideIndex );
     426        9426 :                         aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     427             :                     }
     428             :                     else
     429             :                     {
     430             :                         OSL_TRACE("error: unhandled value '%s'", OUStringToOString( rValue, RTL_TEXTENCODING_ASCII_US ).getStr());
     431           0 :                         aRet.Value = Any( rValue );
     432             :                     }
     433             :                 }
     434             :             }
     435             :         }
     436             :     }
     437       26920 :     return aRet;
     438             : }
     439             : 
     440             : 
     441             : // CT_GeomGuideList
     442        4158 : class GeomGuideListContext : public ContextHandler2
     443             : {
     444             : public:
     445             :     GeomGuideListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList );
     446             :     virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
     447             : 
     448             : protected:
     449             :     std::vector< CustomShapeGuide >&    mrGuideList;
     450             :     CustomShapeProperties&              mrCustomShapeProperties;
     451             : };
     452             : 
     453        2079 : GeomGuideListContext::GeomGuideListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList )
     454             : : ContextHandler2( rParent )
     455             : , mrGuideList( rGuideList )
     456        2079 : , mrCustomShapeProperties( rCustomShapeProperties )
     457             : {
     458        2079 : }
     459             : 
     460        4294 : static OUString convertToOOEquation( CustomShapeProperties& rCustomShapeProperties, const OUString& rSource )
     461             : {
     462        4294 :     if ( !pCommandHashMap )
     463             :     {
     464           5 :         FormulaCommandHMap* pHM = new FormulaCommandHMap();
     465          95 :         for( sal_Int32 i = 0; i < FC_LAST; i++ )
     466          90 :             (*pHM)[ OUString::createFromAscii( pFormularCommandNameTable[ i ].pS ) ] =  pFormularCommandNameTable[ i ].pE;
     467           5 :         pCommandHashMap = pHM;
     468             :     }
     469             : 
     470        4294 :     std::vector< OUString > aTokens;
     471        4294 :     sal_Int32 nIndex = 0;
     472       15683 :     do
     473             :     {
     474       15683 :         OUString aToken( rSource.getToken( 0, ' ', nIndex ) );
     475       15683 :         if ( !aToken.isEmpty() )
     476       15678 :             aTokens.push_back( aToken );
     477             :     }
     478       15683 :     while ( nIndex >= 0 );
     479             : 
     480        4294 :     OUString aEquation;
     481        4294 :     if ( !aTokens.empty() )
     482             :     {
     483        4294 :         sal_Int32 i, nParameters = aTokens.size() - 1;
     484        4294 :         if ( nParameters > 3 )
     485           8 :             nParameters = 3;
     486             : 
     487       17176 :         OUString sParameters[ 3 ];
     488             : 
     489       15670 :         for ( i = 0; i < nParameters; i++ )
     490       11376 :             sParameters[ i ] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties, aTokens[ i + 1 ], false ) );
     491             : 
     492        4294 :         const FormulaCommandHMap::const_iterator aIter( pCommandHashMap->find( aTokens[ 0 ] ) );
     493        4294 :         if ( aIter != pCommandHashMap->end() )
     494             :         {
     495        4294 :             switch( aIter->second )
     496             :             {
     497             :                 case FC_MULDIV :
     498             :                 {
     499        1252 :                     if ( nParameters == 3 )
     500        5008 :                         aEquation = sParameters[ 0 ] + "*" + sParameters[ 1 ]
     501        3756 :                             + "/" + sParameters[ 2 ];
     502             :                 }
     503        1252 :                 break;
     504             :                 case FC_PLUSMINUS :
     505             :                 {
     506        1538 :                     if ( nParameters == 3 )
     507        6152 :                         aEquation = sParameters[ 0 ] + "+" + sParameters[ 1 ]
     508        4614 :                             + "-" + sParameters[ 2 ];
     509             :                 }
     510        1538 :                 break;
     511             :                 case FC_PLUSDIV :
     512             :                 {
     513         116 :                     if ( nParameters == 3 )
     514         464 :                         aEquation = "(" + sParameters[ 0 ] + "+"
     515         348 :                             + sParameters[ 1 ] + ")/" + sParameters[ 2 ];
     516             :                 }
     517         116 :                 break;
     518             :                 case FC_IFELSE :
     519             :                 case FC_IFELSE1 :
     520             :                 {
     521         140 :                     if ( nParameters == 3 )
     522         560 :                         aEquation = "if(" + sParameters[ 0 ] + ","
     523         420 :                             + sParameters[ 1 ] + "," + sParameters[ 2 ] + ")";
     524             :                 }
     525         140 :                 break;
     526             :                 case FC_ABS :
     527             :                 {
     528          16 :                     if ( nParameters == 1 )
     529          16 :                         aEquation = "abs(" + sParameters[ 0 ] + ")";
     530             :                 }
     531          16 :                 break;
     532             :                 case FC_AT2 :
     533             :                 {
     534          59 :                     if ( nParameters == 2 )
     535         236 :                         aEquation = "(10800000*atan2(" + sParameters[ 1 ] + ","
     536         177 :                         + sParameters[ 0 ] + "))/pi";
     537             :                 }
     538          59 :                 break;
     539             :                 case FC_CAT2 :
     540             :                 {
     541          27 :                     if ( nParameters == 3 )
     542         108 :                         aEquation = sParameters[ 0 ] + "*(cos(atan2(" +
     543          81 :                             sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
     544             :                 }
     545          27 :                 break;
     546             :                 case FC_COS :
     547             :                 {
     548         146 :                     if ( nParameters == 2 )
     549         584 :                         aEquation = sParameters[ 0 ] + "*cos(pi*(" +
     550         438 :                         sParameters[ 1 ] + ")/10800000)";
     551             :                 }
     552         146 :                 break;
     553             :                 case FC_MAX :
     554             :                 {
     555          21 :                     if ( nParameters == 2 )
     556          84 :                         aEquation = "max(" + sParameters[ 0 ] + "," +
     557          63 :                             sParameters[ 1 ] + ")";
     558             :                 }
     559          21 :                 break;
     560             :                 case FC_MIN :
     561             :                 {
     562          21 :                     if ( nParameters == 2 )
     563          84 :                         aEquation = "min(" + sParameters[ 0 ] + "," +
     564          63 :                             sParameters[ 1 ] + ")";
     565             :                 }
     566          21 :                 break;
     567             :                 case FC_MOD :
     568             :                 {
     569          48 :                     if ( nParameters == 3 )
     570          96 :                         aEquation = "sqrt("
     571          96 :                             + sParameters[ 0 ] + "*" + sParameters[ 0 ] + "+"
     572          96 :                             + sParameters[ 1 ] + "*" + sParameters[ 1 ] + "+"
     573         144 :                             + sParameters[ 2 ] + "*" + sParameters[ 2 ] + ")";
     574             :                 }
     575          48 :                 break;
     576             :                 case FC_PIN :
     577             :                 {
     578         194 :                     if ( nParameters == 3 ) // if(x-y,x,if(y-z,z,y))
     579         776 :                         aEquation = "if(" + sParameters[ 0 ] + "-" + sParameters[ 1 ]
     580         388 :                             + "," + sParameters[ 0 ] + ",if(" + sParameters[ 2 ]
     581         388 :                             + "-" + sParameters[ 1 ] + "," + sParameters[ 1 ]
     582         582 :                             + "," + sParameters[ 2 ] + "))";
     583             :                 }
     584         194 :                 break;
     585             :                 case FC_SAT2 :
     586             :                 {
     587          27 :                     if ( nParameters == 3 )
     588         108 :                         aEquation = sParameters[ 0 ] + "*(sin(atan2(" +
     589          81 :                             sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
     590             :                 }
     591          27 :                 break;
     592             :                 case FC_SIN :
     593             :                 {
     594         147 :                     if ( nParameters == 2 )
     595         588 :                         aEquation = sParameters[ 0 ] + "*sin(pi*(" +
     596         441 :                         sParameters[ 1 ] + ")/10800000)";
     597             :                 }
     598         147 :                 break;
     599             :                 case FC_SQRT :
     600             :                 {
     601          19 :                     if ( nParameters == 1 )
     602          19 :                         aEquation = "sqrt(" + sParameters[ 0 ] + ")";
     603             :                 }
     604          19 :                 break;
     605             :                 case FC_TAN :
     606             :                 {
     607           4 :                     if ( nParameters == 2 )
     608          16 :                         aEquation = sParameters[ 0 ] + "*tan(pi*(" +
     609          12 :                         sParameters[ 1 ] + ")/10800000)";
     610             :                 }
     611           4 :                 break;
     612             :                 case FC_VAL :
     613             :                 {
     614         519 :                     if ( nParameters == 1 )
     615         519 :                         aEquation = sParameters[ 0 ];
     616             :                 }
     617         519 :                 break;
     618             :                 default :
     619           0 :                     break;
     620             :             }
     621       17176 :         }
     622             :     }
     623        4294 :     return aEquation;
     624             : }
     625             : 
     626        4294 : ContextHandlerRef GeomGuideListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     627             : {
     628        4294 :     if ( aElementToken == A_TOKEN( gd ) )   // CT_GeomGuide
     629             :     {
     630        4294 :         CustomShapeGuide aGuide;
     631        4294 :         aGuide.maName = rAttribs.getString( XML_name ).get();
     632        4294 :         aGuide.maFormula = convertToOOEquation( mrCustomShapeProperties, rAttribs.getString( XML_fmla ).get() );
     633        4294 :         mrGuideList.push_back( aGuide );
     634             :     }
     635        4294 :     return this;
     636             : }
     637             : 
     638             : 
     639             : 
     640         285 : static const OUString GetGeomGuideName( const OUString& rValue )
     641             : {
     642         285 :     return rValue;
     643             : }
     644             : 
     645             : 
     646             : // CT_AdjPoint2D
     647       11230 : class AdjPoint2DContext : public ContextHandler2
     648             : {
     649             : public:
     650             :     AdjPoint2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
     651             : };
     652             : 
     653        5615 : AdjPoint2DContext::AdjPoint2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
     654        5615 : : ContextHandler2( rParent )
     655             : {
     656        5615 :     rAdjPoint2D.First = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_x ).get(), true );
     657        5615 :     rAdjPoint2D.Second = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_y ).get(), true );
     658        5615 : }
     659             : 
     660             : 
     661             : // CT_XYAdjustHandle
     662         436 : class XYAdjustHandleContext : public ContextHandler2
     663             : {
     664             : public:
     665             :     XYAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
     666             :     virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
     667             : 
     668             : protected:
     669             :     AdjustHandle& mrAdjustHandle;
     670             :     CustomShapeProperties& mrCustomShapeProperties;
     671             : };
     672             : 
     673         218 : XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
     674             : : ContextHandler2( rParent )
     675             : , mrAdjustHandle( rAdjustHandle )
     676         218 : , mrCustomShapeProperties( rCustomShapeProperties )
     677             : {
     678         218 :     const OUString aEmptyDefault;
     679         218 :     if ( rAttribs.hasAttribute( XML_gdRefX ) )
     680             :     {
     681         131 :         mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefX, aEmptyDefault ) );
     682             :     }
     683         218 :     if ( rAttribs.hasAttribute( XML_minX ) )
     684             :     {
     685          56 :         mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minX, aEmptyDefault ), true );
     686             :     }
     687         218 :     if ( rAttribs.hasAttribute( XML_maxX ) )
     688             :     {
     689         131 :         mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxX, aEmptyDefault ), true );
     690             :     }
     691         218 :     if ( rAttribs.hasAttribute( XML_gdRefY ) )
     692             :     {
     693         127 :         mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefY, aEmptyDefault ) );
     694             :     }
     695         218 :     if ( rAttribs.hasAttribute( XML_minY ) )
     696             :     {
     697          51 :         mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minY, aEmptyDefault ), true );
     698             :     }
     699         218 :     if ( rAttribs.hasAttribute( XML_maxY ) )
     700             :     {
     701         127 :         mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxY, aEmptyDefault ), true );
     702         218 :     }
     703         218 : }
     704             : 
     705         218 : ContextHandlerRef XYAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     706             : {
     707         218 :     if ( aElementToken == A_TOKEN( pos ) )
     708         218 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos );   // CT_AdjPoint2D
     709           0 :     return 0;
     710             : }
     711             : 
     712             : 
     713             : // CT_PolarAdjustHandle
     714          46 : class PolarAdjustHandleContext : public ContextHandler2
     715             : {
     716             : public:
     717             :     PolarAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
     718             :     virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
     719             : 
     720             : protected:
     721             :     AdjustHandle& mrAdjustHandle;
     722             :     CustomShapeProperties& mrCustomShapeProperties;
     723             : };
     724             : 
     725          23 : PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
     726             : : ContextHandler2( rParent )
     727             : , mrAdjustHandle( rAdjustHandle )
     728          23 : , mrCustomShapeProperties( rCustomShapeProperties )
     729             : {
     730          23 :     const OUString aEmptyDefault;
     731          23 :     if ( rAttribs.hasAttribute( XML_gdRefR ) )
     732             :     {
     733           9 :         mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefR, aEmptyDefault ) );
     734             :     }
     735          23 :     if ( rAttribs.hasAttribute( XML_minR ) )
     736             :     {
     737           0 :         mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minR, aEmptyDefault ), true );
     738             :     }
     739          23 :     if ( rAttribs.hasAttribute( XML_maxR ) )
     740             :     {
     741           9 :         mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxR, aEmptyDefault ), true );
     742             :     }
     743          23 :     if ( rAttribs.hasAttribute( XML_gdRefAng ) )
     744             :     {
     745          18 :         mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefAng, aEmptyDefault ) );
     746             :     }
     747          23 :     if ( rAttribs.hasAttribute( XML_minAng ) )
     748             :     {
     749          18 :         mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minAng, aEmptyDefault ) );
     750             :     }
     751          23 :     if ( rAttribs.hasAttribute( XML_maxAng ) )
     752             :     {
     753          18 :         mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxAng, aEmptyDefault ) );
     754          23 :     }
     755          23 : }
     756             : 
     757          23 : ContextHandlerRef PolarAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     758             : {
     759          23 :     if ( aElementToken == A_TOKEN( pos ) )
     760          23 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos );   // CT_AdjPoint2D
     761           0 :     return 0;
     762             : }
     763             : 
     764             : 
     765             : // CT_AdjustHandleList
     766         728 : class AdjustHandleListContext : public ContextHandler2
     767             : {
     768             : public:
     769             :     AdjustHandleListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList );
     770             :     virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
     771             : 
     772             : protected:
     773             :     std::vector< AdjustHandle >& mrAdjustHandleList;
     774             :     CustomShapeProperties& mrCustomShapeProperties;
     775             : };
     776             : 
     777         364 : AdjustHandleListContext::AdjustHandleListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList )
     778             : : ContextHandler2( rParent )
     779             : , mrAdjustHandleList( rAdjustHandleList )
     780         364 : , mrCustomShapeProperties( rCustomShapeProperties )
     781             : {
     782         364 : }
     783             : 
     784         241 : ContextHandlerRef AdjustHandleListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     785             : {
     786         241 :     if ( aElementToken == A_TOKEN( ahXY ) )         // CT_XYAdjustHandle
     787             :     {
     788         218 :         AdjustHandle aAdjustHandle( false );
     789         218 :         mrAdjustHandleList.push_back( aAdjustHandle );
     790         218 :         return new XYAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
     791             :     }
     792          23 :     else if ( aElementToken == A_TOKEN( ahPolar ) ) // CT_PolarAdjustHandle
     793             :     {
     794          23 :         AdjustHandle aAdjustHandle( true );
     795          23 :         mrAdjustHandleList.push_back( aAdjustHandle );
     796          23 :         return new PolarAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
     797             :     }
     798           0 :     return 0;
     799             : }
     800             : 
     801             : 
     802             : // CT_ConnectionSite
     803        1752 : class ConnectionSiteContext : public ContextHandler2
     804             : {
     805             : public:
     806             :     ConnectionSiteContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite );
     807             :     virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
     808             : 
     809             : protected:
     810             :     ConnectionSite& mrConnectionSite;
     811             :     CustomShapeProperties& mrCustomShapeProperties;
     812             : };
     813             : 
     814         876 : ConnectionSiteContext::ConnectionSiteContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite )
     815             : : ContextHandler2( rParent )
     816             : , mrConnectionSite( rConnectionSite )
     817         876 : , mrCustomShapeProperties( rCustomShapeProperties )
     818             : {
     819         876 :     mrConnectionSite.ang = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_ang ).get() );
     820         876 : }
     821             : 
     822         876 : ContextHandlerRef ConnectionSiteContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     823             : {
     824         876 :     if ( aElementToken == A_TOKEN( pos ) )
     825         876 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrConnectionSite.pos ); // CT_AdjPoint2D
     826           0 :     return 0;
     827             : }
     828             : 
     829             : 
     830             : // CT_Path2DMoveTo
     831        1310 : class Path2DMoveToContext : public ContextHandler2
     832             : {
     833             : public:
     834             :     Path2DMoveToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
     835             :     virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
     836             : 
     837             : protected:
     838             :     EnhancedCustomShapeParameterPair& mrAdjPoint2D;
     839             :     CustomShapeProperties& mrCustomShapeProperties;
     840             : };
     841             : 
     842         655 : Path2DMoveToContext::Path2DMoveToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
     843             : : ContextHandler2( rParent )
     844             : , mrAdjPoint2D( rAdjPoint2D )
     845         655 : , mrCustomShapeProperties( rCustomShapeProperties )
     846             : {
     847         655 : }
     848             : 
     849         655 : ContextHandlerRef Path2DMoveToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     850             : {
     851         655 :     if ( aElementToken == A_TOKEN( pt ) )
     852         655 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D );     // CT_AdjPoint2D
     853           0 :     return 0;
     854             : }
     855             : 
     856             : 
     857             : // CT_Path2DLineTo
     858        6024 : class Path2DLineToContext : public ContextHandler2
     859             : {
     860             : public:
     861             :     Path2DLineToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
     862             :     virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
     863             : 
     864             : protected:
     865             :     EnhancedCustomShapeParameterPair& mrAdjPoint2D;
     866             :     CustomShapeProperties& mrCustomShapeProperties;
     867             : };
     868             : 
     869        3012 : Path2DLineToContext::Path2DLineToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
     870             : : ContextHandler2( rParent )
     871             : , mrAdjPoint2D( rAdjPoint2D )
     872        3012 : , mrCustomShapeProperties( rCustomShapeProperties )
     873             : {
     874        3012 : }
     875             : 
     876        3012 : ContextHandlerRef Path2DLineToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     877             : {
     878        3012 :     if ( aElementToken == A_TOKEN( pt ) )
     879        3012 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D );     // CT_AdjPoint2D
     880           0 :     return 0;
     881             : }
     882             : 
     883             : 
     884             : // CT_Path2DQuadBezierTo
     885          66 : class Path2DQuadBezierToContext : public ContextHandler2
     886             : {
     887             : public:
     888             :     Path2DQuadBezierToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rPt1, EnhancedCustomShapeParameterPair& rPt2 );
     889             :     virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
     890             : 
     891             : protected:
     892             :     EnhancedCustomShapeParameterPair& mrPt1;
     893             :     EnhancedCustomShapeParameterPair& mrPt2;
     894             :     int nCount;
     895             :     CustomShapeProperties& mrCustomShapeProperties;
     896             : };
     897             : 
     898          33 : Path2DQuadBezierToContext::Path2DQuadBezierToContext( ContextHandler2Helper& rParent,
     899             :     CustomShapeProperties& rCustomShapeProperties,
     900             :         EnhancedCustomShapeParameterPair& rPt1,
     901             :             EnhancedCustomShapeParameterPair& rPt2 )
     902             : : ContextHandler2( rParent )
     903             : , mrPt1( rPt1 )
     904             : , mrPt2( rPt2 )
     905             : , nCount( 0 )
     906          33 : , mrCustomShapeProperties( rCustomShapeProperties )
     907             : {
     908          33 : }
     909             : 
     910          66 : ContextHandlerRef Path2DQuadBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     911             : {
     912          66 :     if ( aElementToken == A_TOKEN( pt ) )
     913          66 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, nCount++ ? mrPt2 : mrPt1 ); // CT_AdjPoint2D
     914           0 :     return 0;
     915             : }
     916             : 
     917             : 
     918             : // CT_Path2DCubicBezierTo
     919         510 : class Path2DCubicBezierToContext : public ContextHandler2
     920             : {
     921             : public:
     922             :     Path2DCubicBezierToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties,
     923             :         EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair& );
     924             :     virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
     925             : 
     926             : protected:
     927             :     CustomShapeProperties& mrCustomShapeProperties;
     928             :     EnhancedCustomShapeParameterPair& mrControlPt1;
     929             :     EnhancedCustomShapeParameterPair& mrControlPt2;
     930             :     EnhancedCustomShapeParameterPair& mrEndPt;
     931             :     int nCount;
     932             : };
     933             : 
     934         255 : Path2DCubicBezierToContext::Path2DCubicBezierToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties,
     935             :     EnhancedCustomShapeParameterPair& rControlPt1,
     936             :         EnhancedCustomShapeParameterPair& rControlPt2,
     937             :             EnhancedCustomShapeParameterPair& rEndPt )
     938             : : ContextHandler2( rParent )
     939             : , mrCustomShapeProperties( rCustomShapeProperties )
     940             : , mrControlPt1( rControlPt1 )
     941             : , mrControlPt2( rControlPt2 )
     942             : , mrEndPt( rEndPt )
     943         255 : , nCount( 0 )
     944             : {
     945         255 : }
     946             : 
     947         765 : ContextHandlerRef Path2DCubicBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     948             : {
     949         765 :     if ( aElementToken == A_TOKEN( pt ) )
     950             :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties,
     951         765 :             nCount++ ? nCount == 2 ? mrControlPt2 : mrEndPt : mrControlPt1 );   // CT_AdjPoint2D
     952           0 :     return 0;
     953             : }
     954             : 
     955             : 
     956             : // CT_Path2DContext
     957             : class Path2DContext : public ContextHandler2
     958             : {
     959             : public:
     960             :     Path2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D );
     961             :     virtual ~Path2DContext();
     962             :     virtual ::oox::core::ContextHandlerRef
     963             :         onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
     964             : 
     965             : protected:
     966             :     Path2D& mrPath2D;
     967             :     std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& mrSegments;
     968             :     CustomShapeProperties& mrCustomShapeProperties;
     969             : };
     970             : 
     971         529 : Path2DContext::Path2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D )
     972             : : ContextHandler2( rParent )
     973             : , mrPath2D( rPath2D )
     974             : , mrSegments( rSegments )
     975         529 : , mrCustomShapeProperties( rCustomShapeProperties )
     976             : {
     977         529 :     const OUString aEmptyString;
     978             : 
     979         529 :     rPath2D.w = rAttribs.getString( XML_w, aEmptyString ).toInt64();
     980         529 :     rPath2D.h = rAttribs.getString( XML_h, aEmptyString ).toInt64();
     981         529 :     rPath2D.fill = rAttribs.getToken( XML_fill, XML_norm );
     982         529 :     rPath2D.stroke = rAttribs.getBool( XML_stroke, true );
     983         529 :     rPath2D.extrusionOk = rAttribs.getBool( XML_extrusionOk, true );
     984         529 : }
     985             : 
     986        1587 : Path2DContext::~Path2DContext()
     987             : {
     988         529 :     EnhancedCustomShapeSegment aNewSegment;
     989         529 :     switch ( mrPath2D.fill )
     990             :     {
     991             :         case XML_none:
     992          96 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
     993          96 :             break;
     994             :         case XML_darken:
     995          12 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKEN;
     996          12 :             break;
     997             :         case XML_darkenLess:
     998          17 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKENLESS;
     999          17 :             break;
    1000             :         case XML_lighten:
    1001           3 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTEN;
    1002           3 :             break;
    1003             :         case XML_lightenLess:
    1004           2 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTENLESS;
    1005           2 :             break;
    1006             :     }
    1007         529 :     if (mrPath2D.fill != XML_norm) {
    1008         130 :         aNewSegment.Count = 0;
    1009         130 :         mrSegments.push_back( aNewSegment );
    1010             :     }
    1011         529 :     if ( !mrPath2D.stroke )
    1012             :     {
    1013          86 :         aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
    1014          86 :         aNewSegment.Count = 0;
    1015          86 :         mrSegments.push_back( aNewSegment );
    1016             :     }
    1017         529 :     aNewSegment.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
    1018         529 :     aNewSegment.Count = 0;
    1019         529 :     mrSegments.push_back( aNewSegment );
    1020        1058 : }
    1021             : 
    1022        4668 : ContextHandlerRef Path2DContext::onCreateContext( sal_Int32 aElementToken,
    1023             :     const AttributeList& rAttribs )
    1024             : {
    1025        4668 :     switch( aElementToken )
    1026             :     {
    1027             :         case A_TOKEN( close ) :
    1028             :         {
    1029             :             // ignore close after move to (ppt does seems to do the same, see accentCallout2 preset for example)
    1030         320 :             if ( mrSegments.empty() || ( mrSegments.back().Command != EnhancedCustomShapeSegmentCommand::MOVETO ) ) {
    1031         314 :                 EnhancedCustomShapeSegment aNewSegment;
    1032         314 :                 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
    1033         314 :                 aNewSegment.Count = 0;
    1034         314 :                 mrSegments.push_back( aNewSegment );
    1035             :             }
    1036             :         }
    1037         320 :         break;
    1038             :         case A_TOKEN( moveTo ) :
    1039             :         {
    1040         655 :             EnhancedCustomShapeSegment aNewSegment;
    1041         655 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
    1042         655 :             aNewSegment.Count = 1;
    1043         655 :             mrSegments.push_back( aNewSegment );
    1044             : 
    1045         655 :             EnhancedCustomShapeParameterPair aAdjPoint2D;
    1046         655 :             mrPath2D.parameter.push_back( aAdjPoint2D );
    1047         655 :             return new Path2DMoveToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
    1048             :         }
    1049             :         break;
    1050             :         case A_TOKEN( lnTo ) :
    1051             :         {
    1052        3012 :             if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::LINETO ) )
    1053        2172 :                 mrSegments.back().Count++;
    1054             :             else
    1055             :             {
    1056         840 :                 EnhancedCustomShapeSegment aSegment;
    1057         840 :                 aSegment.Command = EnhancedCustomShapeSegmentCommand::LINETO;
    1058         840 :                 aSegment.Count = 1;
    1059         840 :                 mrSegments.push_back( aSegment );
    1060             :             }
    1061        3012 :             EnhancedCustomShapeParameterPair aAdjPoint2D;
    1062        3012 :             mrPath2D.parameter.push_back( aAdjPoint2D );
    1063        3012 :             return new Path2DLineToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
    1064             :         }
    1065             :         break;
    1066             :         case A_TOKEN( arcTo ) : // CT_Path2DArcTo
    1067             :         {
    1068         393 :             if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::ARCANGLETO ) )
    1069          90 :                 mrSegments.back().Count++;
    1070             :             else
    1071             :             {
    1072         303 :                 EnhancedCustomShapeSegment aSegment;
    1073         303 :                 aSegment.Command = EnhancedCustomShapeSegmentCommand::ARCANGLETO;
    1074         303 :                 aSegment.Count = 1;
    1075         303 :                 mrSegments.push_back( aSegment );
    1076             :             }
    1077             : 
    1078         393 :             EnhancedCustomShapeParameterPair aScale;
    1079         786 :             EnhancedCustomShapeParameterPair aAngles;
    1080             : 
    1081         393 :             aScale.First = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_wR ).get(), true );
    1082         393 :             aScale.Second = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_hR ).get(), true );
    1083             : 
    1084         786 :             CustomShapeGuide aGuide;
    1085         393 :             sal_Int32 nArcNum = mrCustomShapeProperties.getArcNum();
    1086             : 
    1087             :             // start angle
    1088         393 :             aGuide.maName = "arctosa" + OUString::number( nArcNum );
    1089         786 :             aGuide.maFormula = "("
    1090         786 :                 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_stAng ).get() ) )
    1091        1179 :                 + ")/60000.0";
    1092         393 :             aAngles.First.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide ) );
    1093         393 :             aAngles.First.Type = EnhancedCustomShapeParameterType::EQUATION;
    1094             : 
    1095             :             // swing angle
    1096         393 :             aGuide.maName = "arctosw" + OUString::number( nArcNum );
    1097         786 :             aGuide.maFormula = "("
    1098         786 :                 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_swAng ).get() ) )
    1099        1179 :                 + ")/60000.0";
    1100         393 :             aAngles.Second.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide ) );
    1101         393 :             aAngles.Second.Type = EnhancedCustomShapeParameterType::EQUATION;
    1102             : 
    1103         393 :             mrPath2D.parameter.push_back( aScale );
    1104         786 :             mrPath2D.parameter.push_back( aAngles );
    1105             :         }
    1106         393 :         break;
    1107             :         case A_TOKEN( quadBezTo ) :
    1108             :         {
    1109          33 :             if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO ) )
    1110           1 :                 mrSegments.back().Count++;
    1111             :             else
    1112             :             {
    1113          32 :                 EnhancedCustomShapeSegment aSegment;
    1114          32 :                 aSegment.Command = EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
    1115          32 :                 aSegment.Count = 1;
    1116          32 :                 mrSegments.push_back( aSegment );
    1117             :             }
    1118          33 :             EnhancedCustomShapeParameterPair aPt1;
    1119          66 :             EnhancedCustomShapeParameterPair aPt2;
    1120          33 :             mrPath2D.parameter.push_back( aPt1 );
    1121          33 :             mrPath2D.parameter.push_back( aPt2 );
    1122             :             return new Path2DQuadBezierToContext( *this, mrCustomShapeProperties,
    1123          33 :                             mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
    1124          66 :                                 mrPath2D.parameter.back() );
    1125             :         }
    1126             :         break;
    1127             :         case A_TOKEN( cubicBezTo ) :
    1128             :         {
    1129         255 :             if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::CURVETO ) )
    1130          71 :                 mrSegments.back().Count++;
    1131             :             else
    1132             :             {
    1133         184 :                 EnhancedCustomShapeSegment aSegment;
    1134         184 :                 aSegment.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
    1135         184 :                 aSegment.Count = 1;
    1136         184 :                 mrSegments.push_back( aSegment );
    1137             :             }
    1138         255 :             EnhancedCustomShapeParameterPair aControlPt1;
    1139         510 :             EnhancedCustomShapeParameterPair aControlPt2;
    1140         510 :             EnhancedCustomShapeParameterPair aEndPt;
    1141         255 :             mrPath2D.parameter.push_back( aControlPt1 );
    1142         255 :             mrPath2D.parameter.push_back( aControlPt2 );
    1143         255 :             mrPath2D.parameter.push_back( aEndPt );
    1144             :             return new Path2DCubicBezierToContext( *this, mrCustomShapeProperties,
    1145         255 :                             mrPath2D.parameter[ mrPath2D.parameter.size() - 3 ],
    1146         255 :                                 mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
    1147         765 :                                     mrPath2D.parameter.back() );
    1148             :         }
    1149             :         break;
    1150             :     }
    1151         713 :     return 0;
    1152             : }
    1153             : 
    1154             : 
    1155             : // CT_Path2DList
    1156         728 : class Path2DListContext : public ContextHandler2
    1157             : {
    1158             : public:
    1159             :     Path2DListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
    1160             :         std::vector< Path2D >& rPath2DList );
    1161             : 
    1162             :     virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
    1163             : 
    1164             : protected:
    1165             : 
    1166             :     CustomShapeProperties& mrCustomShapeProperties;
    1167             :     std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& mrSegments;
    1168             :     std::vector< Path2D >& mrPath2DList;
    1169             : };
    1170             : 
    1171         364 : Path2DListContext::Path2DListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
    1172             :                                         std::vector< Path2D >& rPath2DList )
    1173             : : ContextHandler2( rParent )
    1174             : , mrCustomShapeProperties( rCustomShapeProperties )
    1175             : , mrSegments( rSegments )
    1176         364 : , mrPath2DList( rPath2DList )
    1177             : {
    1178         364 : }
    1179             : 
    1180         529 : ContextHandlerRef Path2DListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
    1181             : {
    1182         529 :     if ( aElementToken == A_TOKEN( path ) )
    1183             :     {
    1184         529 :         Path2D aPath2D;
    1185         529 :         mrPath2DList.push_back( aPath2D );
    1186         529 :         return new Path2DContext( *this, rAttribs, mrCustomShapeProperties,  mrSegments, mrPath2DList.back() );
    1187             :     }
    1188           0 :     return 0;
    1189             : }
    1190             : 
    1191             : 
    1192             : // CT_CustomGeometry2D
    1193         364 : CustomShapeGeometryContext::CustomShapeGeometryContext( ContextHandler2Helper& rParent, const AttributeList& /* rAttribs */, CustomShapeProperties& rCustomShapeProperties )
    1194             : : ContextHandler2( rParent )
    1195         364 : , mrCustomShapeProperties( rCustomShapeProperties )
    1196             : {
    1197         364 : }
    1198             : 
    1199        2949 : ContextHandlerRef CustomShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
    1200             : {
    1201        2949 :     switch( aElementToken )
    1202             :     {
    1203             :         case A_TOKEN( avLst ):          // CT_GeomGuideList adjust value list
    1204         364 :             return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
    1205             :         case A_TOKEN( gdLst ):          // CT_GeomGuideList guide list
    1206         364 :             return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getGuideList() );
    1207             :         case A_TOKEN( ahLst ):          // CT_AdjustHandleList adjust handle list
    1208         364 :             return new AdjustHandleListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustHandleList() );
    1209             :         case A_TOKEN( cxnLst ):         // CT_ConnectionSiteList connection site list
    1210         253 :             return this;
    1211             :         case A_TOKEN( rect ):           // CT_GeomRectList geometry rect list
    1212             :         {
    1213         364 :             GeomRect aGeomRect;
    1214         364 :             aGeomRect.l = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_l ).get(), true );
    1215         364 :             aGeomRect.t = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_t ).get(), true );
    1216         364 :             aGeomRect.r = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_r ).get(), true );
    1217         364 :             aGeomRect.b = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_b ).get(), true );
    1218         364 :             mrCustomShapeProperties.getTextRect() = aGeomRect;
    1219             :         }
    1220         364 :         break;
    1221             :         case A_TOKEN( pathLst ):        // CT_Path2DList 2d path list
    1222         364 :             return new Path2DListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getSegments(), mrCustomShapeProperties.getPath2DList() );
    1223             : 
    1224             :         // from cxnLst:
    1225             :         case A_TOKEN( cxn ):                // CT_ConnectionSite
    1226             :         {
    1227         876 :             ConnectionSite aConnectionSite;
    1228         876 :             mrCustomShapeProperties.getConnectionSiteList().push_back( aConnectionSite );
    1229         876 :             return new ConnectionSiteContext( *this, rAttribs, mrCustomShapeProperties, mrCustomShapeProperties.getConnectionSiteList().back() );
    1230             :         }
    1231             :     }
    1232         364 :     return 0;
    1233             : }
    1234             : 
    1235             : 
    1236             : // CT_PresetGeometry2D
    1237        1468 : PresetShapeGeometryContext::PresetShapeGeometryContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
    1238             : : ContextHandler2( rParent )
    1239        1468 : , mrCustomShapeProperties( rCustomShapeProperties )
    1240             : {
    1241        1468 :     sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
    1242             :     OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
    1243        1468 :     mrCustomShapeProperties.setShapePresetType( nShapeType );
    1244        1468 : }
    1245             : 
    1246        1351 : ContextHandlerRef PresetShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
    1247             : {
    1248        1351 :     if ( aElementToken == A_TOKEN( avLst ) )
    1249        1351 :         return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
    1250             :     else
    1251           0 :         return this;
    1252             : }
    1253             : 
    1254             : 
    1255             : // CT_PresetTextShape
    1256           0 : PresetTextShapeContext::PresetTextShapeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
    1257             : : ContextHandler2( rParent )
    1258           0 : , mrCustomShapeProperties( rCustomShapeProperties )
    1259             : {
    1260           0 :     sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
    1261             :     OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
    1262           0 :     mrCustomShapeProperties.setShapePresetType( nShapeType );
    1263           0 : }
    1264             : 
    1265           0 : ContextHandlerRef PresetTextShapeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
    1266             : {
    1267           0 :     if ( aElementToken == A_TOKEN( avLst ) )
    1268           0 :         return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
    1269             :     else
    1270           0 :         return this;
    1271             : }
    1272             : 
    1273         177 : } }
    1274             : 
    1275             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10