LCOV - code coverage report
Current view: top level - oox/source/drawingml - customshapegeometry.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 545 0.0 %
Date: 2014-04-14 Functions: 0 59 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "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           0 : OUString GetFormulaParameter( const EnhancedCustomShapeParameter& rParameter )
      91             : {
      92           0 :     OUString aRet;
      93           0 :     switch( rParameter.Type )
      94             :     {
      95             :         case EnhancedCustomShapeParameterType::NORMAL :
      96             :         {
      97           0 :             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           0 :                 sal_Int32 nValue = 0;
     106           0 :                 if ( rParameter.Value >>= nValue )
     107           0 :                     aRet = OUString::number( nValue );
     108             :             }
     109             :         }
     110           0 :         break;
     111             :         case EnhancedCustomShapeParameterType::EQUATION :
     112             :         {
     113           0 :             if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
     114             :             {
     115             :                 sal_Int32 nFormulaIndex;
     116           0 :                 if ( rParameter.Value >>= nFormulaIndex )
     117             :                 {
     118           0 :                     aRet = "?"
     119           0 :                         + OUString::number( nFormulaIndex )
     120           0 :                             + " ";
     121             :                 }
     122             :             }
     123             :             else
     124             :             {
     125             :                 // ups... we should have an index here and not the formula name
     126             :             }
     127             :         }
     128           0 :         break;
     129             :         case EnhancedCustomShapeParameterType::ADJUSTMENT :
     130             :         {
     131           0 :             if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
     132             :             {
     133             :                 sal_Int32 nAdjustmentIndex;
     134           0 :                 if ( rParameter.Value >>= nAdjustmentIndex )
     135             :                 {
     136           0 :                     aRet = "$"
     137           0 :                         + OUString::number( nAdjustmentIndex )
     138           0 :                             + " ";
     139             :                 }
     140             :             }
     141             :             else
     142             :             {
     143             :                 // ups... we should have an index here and not the formula name
     144             :             }
     145             :         }
     146           0 :         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           0 :             const OUString sLogWidth( "logwidth"  );
     210           0 :             aRet = sLogWidth;
     211             :         }
     212           0 :         break;
     213             :         case EnhancedCustomShapeParameterType::LOGHEIGHT :
     214             :         {
     215           0 :             const OUString sLogHeight( "logheight"  );
     216           0 :             aRet = sLogHeight;
     217             :         }
     218           0 :         break;
     219             :     }
     220           0 :     return aRet;
     221             : }
     222             : 
     223             : 
     224             : 
     225           0 : static EnhancedCustomShapeParameter GetAdjCoordinate( CustomShapeProperties& rCustomShapeProperties, const OUString& rValue, bool bNoSymbols = true )
     226             : {
     227           0 :     com::sun::star::drawing::EnhancedCustomShapeParameter aRet;
     228           0 :     if ( !rValue.isEmpty() )
     229             :     {
     230           0 :         bool        bConstant = true;
     231           0 :         sal_Int32   nConstant = -1;
     232           0 :         sal_Int32   nIntVal = 0;
     233             : 
     234             :         // first check if it's a constant value
     235           0 :         switch( AttributeConversion::decodeToken( rValue ) )
     236             :         {
     237           0 :             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           0 :             case XML_cd2  : nConstant = 180 * 60000; break;
     242           0 :             case XML_cd3  : nConstant = 120 * 60000; break;
     243           0 :             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           0 :                 if ( bNoSymbols )
     250             :                 {
     251           0 :                     CustomShapeGuide aGuide;
     252           0 :                     aGuide.maName = rValue;
     253           0 :                     aGuide.maFormula = "logheight" ;
     254             : 
     255           0 :                     aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     256           0 :                     aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     257             :                 }
     258             :                 else
     259           0 :                     aRet.Type = EnhancedCustomShapeParameterType::LOGHEIGHT;   // TODO: HEIGHT needs to be implemented
     260             :             }
     261           0 :             break;
     262             : 
     263             : 
     264             :             case XML_hd10 :   // !!PASSTHROUGH INTENDED
     265           0 :                 nIntVal += 2; // */ h 1.0 10.0
     266             :             case XML_hd8 :    // */ h 1.0 8.0
     267           0 :                 nIntVal += 2;
     268             :             case XML_hd6 :    // */ h 1.0 6.0
     269           0 :                 nIntVal++;
     270             :             case XML_hd5 :    // */ h 1.0 5.0
     271           0 :                 nIntVal++;
     272             :             case XML_hd4 :    // */ h 1.0 4.0
     273           0 :                 nIntVal++;
     274             :             case XML_hd3 :    // */ h 1.0 3.0
     275           0 :                 nIntVal++;
     276             :             case XML_hd2 :    // */ h 1.0 2.0
     277             :             case XML_vc :     // */ h 1.0 2.0
     278             :             {
     279           0 :                 nIntVal += 2;
     280             : 
     281           0 :                 CustomShapeGuide aGuide;
     282           0 :                 aGuide.maName = rValue;
     283           0 :                 aGuide.maFormula = "logheight/" + OUString::number( nIntVal );
     284             : 
     285           0 :                 aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     286           0 :                 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     287             :             }
     288           0 :             break;
     289             : 
     290             :             case XML_t :
     291             :             case XML_l :
     292             :             {
     293           0 :                 nConstant = 0;
     294           0 :                 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
     295             :             }
     296           0 :             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           0 :                 CustomShapeGuide aGuide;
     311           0 :                 aGuide.maName = rValue;
     312           0 :                 aGuide.maFormula = "min(logwidth,logheight)";
     313             : 
     314           0 :                 aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     315           0 :                 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     316             :             }
     317           0 :             break;
     318             :             case XML_ssd32 : // */ ss 1.0 32.0
     319           0 :                 nIntVal += 16;
     320             :             case XML_ssd16 : // */ ss 1.0 16.0
     321           0 :                 nIntVal += 8;
     322             :             case XML_ssd8 :  // */ ss 1.0 8.0
     323           0 :                 nIntVal += 2;
     324             :             case XML_ssd6 :  // */ ss 1.0 6.0
     325           0 :                 nIntVal += 2;
     326             :             case XML_ssd4 :  // */ ss 1.0 4.0
     327           0 :                 nIntVal += 2;
     328             :             case XML_ssd2 :  // */ ss 1.0 2.0
     329             :             {
     330           0 :                 nIntVal += 2;
     331             : 
     332           0 :                 CustomShapeGuide aGuide;
     333           0 :                 aGuide.maName = rValue;
     334           0 :                 aGuide.maFormula = "min(logwidth,logheight)/" + OUString::number( nIntVal );
     335             : 
     336           0 :                 aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     337           0 :                 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     338             :             }
     339           0 :             break;
     340             : 
     341             :             case XML_r :    // variable width of the shape defined in spPr
     342             :             case XML_w :
     343             :             {
     344           0 :                 if ( bNoSymbols )
     345             :                 {
     346           0 :                     CustomShapeGuide aGuide;
     347           0 :                     aGuide.maName = rValue;
     348           0 :                     aGuide.maFormula = "logwidth" ;
     349             : 
     350           0 :                     aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     351           0 :                     aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     352             :                 }
     353             :                 else
     354           0 :                     aRet.Type = EnhancedCustomShapeParameterType::LOGWIDTH;
     355             :             }
     356           0 :             break;
     357             : 
     358             :             case XML_wd32 : // */ w 1.0 32.0
     359           0 :                 nIntVal += 20;
     360             :             case XML_wd12 : // */ w 1.0 12.0
     361           0 :                 nIntVal += 2;
     362             :             case XML_wd10 : // */ w 1.0 10.0
     363           0 :                 nIntVal += 2;
     364             :             case XML_wd8 :  // */ w 1.0 8.0
     365           0 :                 nIntVal += 2;
     366             :             case XML_wd6 :  // */ w 1.0 6.0
     367           0 :                 nIntVal++;
     368             :             case XML_wd5 :  // */ w 1.0 5.0
     369           0 :                 nIntVal++;
     370             :             case XML_wd4 :  // */ w 1.0 4.0
     371           0 :                 nIntVal++;
     372             :             case XML_wd3 :  // */ w 1.0 3.0
     373           0 :                 nIntVal++;
     374             :             case XML_hc :   // */ w 1.0 2.0
     375             :             case XML_wd2 :  // */ w 1.0 2.0
     376             :             {
     377           0 :                 nIntVal += 2;
     378             : 
     379           0 :                 CustomShapeGuide aGuide;
     380           0 :                 aGuide.maName = rValue;
     381           0 :                 aGuide.maFormula = "logwidth/" + OUString::number( nIntVal );
     382             : 
     383           0 :                 aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
     384           0 :                 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
     385             :             }
     386           0 :             break;
     387             : 
     388             :             default:
     389           0 :                 bConstant = false;
     390           0 :             break;
     391             :         }
     392           0 :         if ( bConstant )
     393             :         {
     394           0 :             if (nConstant != -1) {
     395           0 :                 aRet.Value = Any( nConstant );
     396           0 :                 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
     397             :             }
     398             :         }
     399             :         else
     400             :         {
     401           0 :             sal_Unicode n = rValue[ 0 ];
     402           0 :             if ( ( n == '+' ) || ( n == '-' ) )
     403             :             {
     404           0 :                 if ( rValue.getLength() > 1 )
     405           0 :                     n = rValue[ 1 ];
     406             :             }
     407           0 :             if ( ( n >= '0' ) && ( n <= '9' ) )
     408             :             {   // seems to be a ST_Coordinate
     409           0 :                 aRet.Value = Any( (sal_Int32)(rValue.toInt32() ) );
     410           0 :                 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
     411             :             }
     412             :             else
     413             :             {
     414           0 :                 sal_Int32 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getAdjustmentGuideList(), rValue );
     415           0 :                 if ( nGuideIndex >= 0 )
     416             :                 {
     417           0 :                     aRet.Value = Any( nGuideIndex );
     418           0 :                     aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
     419             :                 }
     420             :                 else
     421             :                 {
     422           0 :                     nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), rValue );
     423           0 :                     if ( nGuideIndex >= 0 )
     424             :                     {
     425           0 :                         aRet.Value = Any( nGuideIndex );
     426           0 :                         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           0 :     return aRet;
     438             : }
     439             : 
     440             : 
     441             : // CT_GeomGuideList
     442           0 : 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           0 : GeomGuideListContext::GeomGuideListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList )
     454             : : ContextHandler2( rParent )
     455             : , mrGuideList( rGuideList )
     456           0 : , mrCustomShapeProperties( rCustomShapeProperties )
     457             : {
     458           0 : }
     459             : 
     460           0 : static OUString convertToOOEquation( CustomShapeProperties& rCustomShapeProperties, const OUString& rSource )
     461             : {
     462           0 :     if ( !pCommandHashMap )
     463             :     {
     464           0 :         FormulaCommandHMap* pHM = new FormulaCommandHMap();
     465           0 :         for( sal_Int32 i = 0; i < FC_LAST; i++ )
     466           0 :             (*pHM)[ OUString::createFromAscii( pFormularCommandNameTable[ i ].pS ) ] =  pFormularCommandNameTable[ i ].pE;
     467           0 :         pCommandHashMap = pHM;
     468             :     }
     469             : 
     470           0 :     std::vector< OUString > aTokens;
     471           0 :     sal_Int32 nIndex = 0;
     472           0 :     do
     473             :     {
     474           0 :         OUString aToken( rSource.getToken( 0, ' ', nIndex ) );
     475           0 :         if ( !aToken.isEmpty() )
     476           0 :             aTokens.push_back( aToken );
     477             :     }
     478           0 :     while ( nIndex >= 0 );
     479             : 
     480           0 :     OUString aEquation;
     481           0 :     if ( !aTokens.empty() )
     482             :     {
     483           0 :         sal_Int32 i, nParameters = aTokens.size() - 1;
     484           0 :         if ( nParameters > 3 )
     485           0 :             nParameters = 3;
     486             : 
     487           0 :         OUString sParameters[ 3 ];
     488             : 
     489           0 :         for ( i = 0; i < nParameters; i++ )
     490           0 :             sParameters[ i ] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties, aTokens[ i + 1 ], false ) );
     491             : 
     492           0 :         const FormulaCommandHMap::const_iterator aIter( pCommandHashMap->find( aTokens[ 0 ] ) );
     493           0 :         if ( aIter != pCommandHashMap->end() )
     494             :         {
     495           0 :             switch( aIter->second )
     496             :             {
     497             :                 case FC_MULDIV :
     498             :                 {
     499           0 :                     if ( nParameters == 3 )
     500           0 :                         aEquation = sParameters[ 0 ] + "*" + sParameters[ 1 ]
     501           0 :                             + "/" + sParameters[ 2 ];
     502             :                 }
     503           0 :                 break;
     504             :                 case FC_PLUSMINUS :
     505             :                 {
     506           0 :                     if ( nParameters == 3 )
     507           0 :                         aEquation = sParameters[ 0 ] + "+" + sParameters[ 1 ]
     508           0 :                             + "-" + sParameters[ 2 ];
     509             :                 }
     510           0 :                 break;
     511             :                 case FC_PLUSDIV :
     512             :                 {
     513           0 :                     if ( nParameters == 3 )
     514           0 :                         aEquation = "(" + sParameters[ 0 ] + "+"
     515           0 :                             + sParameters[ 1 ] + ")/" + sParameters[ 2 ];
     516             :                 }
     517           0 :                 break;
     518             :                 case FC_IFELSE :
     519             :                 case FC_IFELSE1 :
     520             :                 {
     521           0 :                     if ( nParameters == 3 )
     522           0 :                         aEquation = "if(" + sParameters[ 0 ] + ","
     523           0 :                             + sParameters[ 1 ] + "," + sParameters[ 2 ] + ")";
     524             :                 }
     525           0 :                 break;
     526             :                 case FC_ABS :
     527             :                 {
     528           0 :                     if ( nParameters == 1 )
     529           0 :                         aEquation = "abs(" + sParameters[ 0 ] + ")";
     530             :                 }
     531           0 :                 break;
     532             :                 case FC_AT2 :
     533             :                 {
     534           0 :                     if ( nParameters == 2 )
     535           0 :                         aEquation = "(10800000*atan2(" + sParameters[ 1 ] + ","
     536           0 :                         + sParameters[ 0 ] + "))/pi";
     537             :                 }
     538           0 :                 break;
     539             :                 case FC_CAT2 :
     540             :                 {
     541           0 :                     if ( nParameters == 3 )
     542           0 :                         aEquation = sParameters[ 0 ] + "*(cos(atan2(" +
     543           0 :                             sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
     544             :                 }
     545           0 :                 break;
     546             :                 case FC_COS :
     547             :                 {
     548           0 :                     if ( nParameters == 2 )
     549           0 :                         aEquation = sParameters[ 0 ] + "*cos(pi*(" +
     550           0 :                         sParameters[ 1 ] + ")/10800000)";
     551             :                 }
     552           0 :                 break;
     553             :                 case FC_MAX :
     554             :                 {
     555           0 :                     if ( nParameters == 2 )
     556           0 :                         aEquation = "max(" + sParameters[ 0 ] + "," +
     557           0 :                             sParameters[ 1 ] + ")";
     558             :                 }
     559           0 :                 break;
     560             :                 case FC_MIN :
     561             :                 {
     562           0 :                     if ( nParameters == 2 )
     563           0 :                         aEquation = "min(" + sParameters[ 0 ] + "," +
     564           0 :                             sParameters[ 1 ] + ")";
     565             :                 }
     566           0 :                 break;
     567             :                 case FC_MOD :
     568             :                 {
     569           0 :                     if ( nParameters == 3 )
     570           0 :                         aEquation = "sqrt("
     571           0 :                             + sParameters[ 0 ] + "*" + sParameters[ 0 ] + "+"
     572           0 :                             + sParameters[ 1 ] + "*" + sParameters[ 1 ] + "+"
     573           0 :                             + sParameters[ 2 ] + "*" + sParameters[ 2 ] + ")";
     574             :                 }
     575           0 :                 break;
     576             :                 case FC_PIN :
     577             :                 {
     578           0 :                     if ( nParameters == 3 ) // if(x-y,x,if(y-z,z,y))
     579           0 :                         aEquation = "if(" + sParameters[ 0 ] + "-" + sParameters[ 1 ]
     580           0 :                             + "," + sParameters[ 0 ] + ",if(" + sParameters[ 2 ]
     581           0 :                             + "-" + sParameters[ 1 ] + "," + sParameters[ 1 ]
     582           0 :                             + "," + sParameters[ 2 ] + "))";
     583             :                 }
     584           0 :                 break;
     585             :                 case FC_SAT2 :
     586             :                 {
     587           0 :                     if ( nParameters == 3 )
     588           0 :                         aEquation = sParameters[ 0 ] + "*(sin(atan2(" +
     589           0 :                             sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
     590             :                 }
     591           0 :                 break;
     592             :                 case FC_SIN :
     593             :                 {
     594           0 :                     if ( nParameters == 2 )
     595           0 :                         aEquation = sParameters[ 0 ] + "*sin(pi*(" +
     596           0 :                         sParameters[ 1 ] + ")/10800000)";
     597             :                 }
     598           0 :                 break;
     599             :                 case FC_SQRT :
     600             :                 {
     601           0 :                     if ( nParameters == 1 )
     602           0 :                         aEquation = "sqrt(" + sParameters[ 0 ] + ")";
     603             :                 }
     604           0 :                 break;
     605             :                 case FC_TAN :
     606             :                 {
     607           0 :                     if ( nParameters == 2 )
     608           0 :                         aEquation = sParameters[ 0 ] + "*tan(pi*(" +
     609           0 :                         sParameters[ 1 ] + ")/10800000)";
     610             :                 }
     611           0 :                 break;
     612             :                 case FC_VAL :
     613             :                 {
     614           0 :                     if ( nParameters == 1 )
     615           0 :                         aEquation = sParameters[ 0 ];
     616             :                 }
     617           0 :                 break;
     618             :                 default :
     619           0 :                     break;
     620             :             }
     621           0 :         }
     622             :     }
     623           0 :     return aEquation;
     624             : }
     625             : 
     626           0 : ContextHandlerRef GeomGuideListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     627             : {
     628           0 :     if ( aElementToken == A_TOKEN( gd ) )   // CT_GeomGuide
     629             :     {
     630           0 :         CustomShapeGuide aGuide;
     631           0 :         aGuide.maName = rAttribs.getString( XML_name ).get();
     632           0 :         aGuide.maFormula = convertToOOEquation( mrCustomShapeProperties, rAttribs.getString( XML_fmla ).get() );
     633           0 :         mrGuideList.push_back( aGuide );
     634             :     }
     635           0 :     return this;
     636             : }
     637             : 
     638             : 
     639             : 
     640           0 : static const OUString GetGeomGuideName( const OUString& rValue )
     641             : {
     642           0 :     return rValue;
     643             : }
     644             : 
     645             : 
     646             : // CT_AdjPoint2D
     647           0 : class AdjPoint2DContext : public ContextHandler2
     648             : {
     649             : public:
     650             :     AdjPoint2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
     651             : };
     652             : 
     653           0 : AdjPoint2DContext::AdjPoint2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
     654           0 : : ContextHandler2( rParent )
     655             : {
     656           0 :     rAdjPoint2D.First = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_x ).get(), true );
     657           0 :     rAdjPoint2D.Second = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_y ).get(), true );
     658           0 : }
     659             : 
     660             : 
     661             : // CT_XYAdjustHandle
     662           0 : 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           0 : XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
     674             : : ContextHandler2( rParent )
     675             : , mrAdjustHandle( rAdjustHandle )
     676           0 : , mrCustomShapeProperties( rCustomShapeProperties )
     677             : {
     678           0 :     const OUString aEmptyDefault;
     679           0 :     if ( rAttribs.hasAttribute( XML_gdRefX ) )
     680             :     {
     681           0 :         mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefX, aEmptyDefault ) );
     682             :     }
     683           0 :     if ( rAttribs.hasAttribute( XML_minX ) )
     684             :     {
     685           0 :         mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minX, aEmptyDefault ), true );
     686             :     }
     687           0 :     if ( rAttribs.hasAttribute( XML_maxX ) )
     688             :     {
     689           0 :         mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxX, aEmptyDefault ), true );
     690             :     }
     691           0 :     if ( rAttribs.hasAttribute( XML_gdRefY ) )
     692             :     {
     693           0 :         mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefY, aEmptyDefault ) );
     694             :     }
     695           0 :     if ( rAttribs.hasAttribute( XML_minY ) )
     696             :     {
     697           0 :         mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minY, aEmptyDefault ), true );
     698             :     }
     699           0 :     if ( rAttribs.hasAttribute( XML_maxY ) )
     700             :     {
     701           0 :         mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxY, aEmptyDefault ), true );
     702           0 :     }
     703           0 : }
     704             : 
     705           0 : ContextHandlerRef XYAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     706             : {
     707           0 :     if ( aElementToken == A_TOKEN( pos ) )
     708           0 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos );   // CT_AdjPoint2D
     709           0 :     return 0;
     710             : }
     711             : 
     712             : 
     713             : // CT_PolarAdjustHandle
     714           0 : 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           0 : PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
     726             : : ContextHandler2( rParent )
     727             : , mrAdjustHandle( rAdjustHandle )
     728           0 : , mrCustomShapeProperties( rCustomShapeProperties )
     729             : {
     730           0 :     const OUString aEmptyDefault;
     731           0 :     if ( rAttribs.hasAttribute( XML_gdRefR ) )
     732             :     {
     733           0 :         mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefR, aEmptyDefault ) );
     734             :     }
     735           0 :     if ( rAttribs.hasAttribute( XML_minR ) )
     736             :     {
     737           0 :         mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minR, aEmptyDefault ), true );
     738             :     }
     739           0 :     if ( rAttribs.hasAttribute( XML_maxR ) )
     740             :     {
     741           0 :         mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxR, aEmptyDefault ), true );
     742             :     }
     743           0 :     if ( rAttribs.hasAttribute( XML_gdRefAng ) )
     744             :     {
     745           0 :         mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefAng, aEmptyDefault ) );
     746             :     }
     747           0 :     if ( rAttribs.hasAttribute( XML_minAng ) )
     748             :     {
     749           0 :         mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minAng, aEmptyDefault ) );
     750             :     }
     751           0 :     if ( rAttribs.hasAttribute( XML_maxAng ) )
     752             :     {
     753           0 :         mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxAng, aEmptyDefault ) );
     754           0 :     }
     755           0 : }
     756             : 
     757           0 : ContextHandlerRef PolarAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     758             : {
     759           0 :     if ( aElementToken == A_TOKEN( pos ) )
     760           0 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos );   // CT_AdjPoint2D
     761           0 :     return 0;
     762             : }
     763             : 
     764             : 
     765             : // CT_AdjustHandleList
     766           0 : 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           0 : AdjustHandleListContext::AdjustHandleListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList )
     778             : : ContextHandler2( rParent )
     779             : , mrAdjustHandleList( rAdjustHandleList )
     780           0 : , mrCustomShapeProperties( rCustomShapeProperties )
     781             : {
     782           0 : }
     783             : 
     784           0 : ContextHandlerRef AdjustHandleListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     785             : {
     786           0 :     if ( aElementToken == A_TOKEN( ahXY ) )         // CT_XYAdjustHandle
     787             :     {
     788           0 :         AdjustHandle aAdjustHandle( false );
     789           0 :         mrAdjustHandleList.push_back( aAdjustHandle );
     790           0 :         return new XYAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
     791             :     }
     792           0 :     else if ( aElementToken == A_TOKEN( ahPolar ) ) // CT_PolarAdjustHandle
     793             :     {
     794           0 :         AdjustHandle aAdjustHandle( true );
     795           0 :         mrAdjustHandleList.push_back( aAdjustHandle );
     796           0 :         return new PolarAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
     797             :     }
     798           0 :     return 0;
     799             : }
     800             : 
     801             : 
     802             : // CT_ConnectionSite
     803           0 : 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           0 : ConnectionSiteContext::ConnectionSiteContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite )
     815             : : ContextHandler2( rParent )
     816             : , mrConnectionSite( rConnectionSite )
     817           0 : , mrCustomShapeProperties( rCustomShapeProperties )
     818             : {
     819           0 :     mrConnectionSite.ang = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_ang ).get() );
     820           0 : }
     821             : 
     822           0 : ContextHandlerRef ConnectionSiteContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     823             : {
     824           0 :     if ( aElementToken == A_TOKEN( pos ) )
     825           0 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrConnectionSite.pos ); // CT_AdjPoint2D
     826           0 :     return 0;
     827             : }
     828             : 
     829             : 
     830             : // CT_Path2DMoveTo
     831           0 : 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           0 : Path2DMoveToContext::Path2DMoveToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
     843             : : ContextHandler2( rParent )
     844             : , mrAdjPoint2D( rAdjPoint2D )
     845           0 : , mrCustomShapeProperties( rCustomShapeProperties )
     846             : {
     847           0 : }
     848             : 
     849           0 : ContextHandlerRef Path2DMoveToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     850             : {
     851           0 :     if ( aElementToken == A_TOKEN( pt ) )
     852           0 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D );     // CT_AdjPoint2D
     853           0 :     return 0;
     854             : }
     855             : 
     856             : 
     857             : // CT_Path2DLineTo
     858           0 : 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           0 : Path2DLineToContext::Path2DLineToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
     870             : : ContextHandler2( rParent )
     871             : , mrAdjPoint2D( rAdjPoint2D )
     872           0 : , mrCustomShapeProperties( rCustomShapeProperties )
     873             : {
     874           0 : }
     875             : 
     876           0 : ContextHandlerRef Path2DLineToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     877             : {
     878           0 :     if ( aElementToken == A_TOKEN( pt ) )
     879           0 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D );     // CT_AdjPoint2D
     880           0 :     return 0;
     881             : }
     882             : 
     883             : 
     884             : // CT_Path2DQuadBezierTo
     885           0 : 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           0 : 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           0 : , mrCustomShapeProperties( rCustomShapeProperties )
     907             : {
     908           0 : }
     909             : 
     910           0 : ContextHandlerRef Path2DQuadBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     911             : {
     912           0 :     if ( aElementToken == A_TOKEN( pt ) )
     913           0 :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, nCount++ ? mrPt2 : mrPt1 ); // CT_AdjPoint2D
     914           0 :     return 0;
     915             : }
     916             : 
     917             : 
     918             : // CT_Path2DCubicBezierTo
     919           0 : 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           0 : 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           0 : , nCount( 0 )
     944             : {
     945           0 : }
     946             : 
     947           0 : ContextHandlerRef Path2DCubicBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
     948             : {
     949           0 :     if ( aElementToken == A_TOKEN( pt ) )
     950             :         return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties,
     951           0 :             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           0 : 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           0 : , mrCustomShapeProperties( rCustomShapeProperties )
     976             : {
     977           0 :     const OUString aEmptyString;
     978             : 
     979           0 :     rPath2D.w = rAttribs.getString( XML_w, aEmptyString ).toInt64();
     980           0 :     rPath2D.h = rAttribs.getString( XML_h, aEmptyString ).toInt64();
     981           0 :     rPath2D.fill = rAttribs.getToken( XML_fill, XML_norm );
     982           0 :     rPath2D.stroke = rAttribs.getBool( XML_stroke, true );
     983           0 :     rPath2D.extrusionOk = rAttribs.getBool( XML_extrusionOk, true );
     984           0 : }
     985             : 
     986           0 : Path2DContext::~Path2DContext()
     987             : {
     988           0 :     EnhancedCustomShapeSegment aNewSegment;
     989           0 :     switch ( mrPath2D.fill )
     990             :     {
     991             :         case XML_none:
     992           0 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
     993           0 :             break;
     994             :         case XML_darken:
     995           0 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKEN;
     996           0 :             break;
     997             :         case XML_darkenLess:
     998           0 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKENLESS;
     999           0 :             break;
    1000             :         case XML_lighten:
    1001           0 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTEN;
    1002           0 :             break;
    1003             :         case XML_lightenLess:
    1004           0 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTENLESS;
    1005           0 :             break;
    1006             :     }
    1007           0 :     if (mrPath2D.fill != XML_norm) {
    1008           0 :         aNewSegment.Count = 0;
    1009           0 :         mrSegments.push_back( aNewSegment );
    1010             :     }
    1011           0 :     if ( !mrPath2D.stroke )
    1012             :     {
    1013           0 :         aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
    1014           0 :         aNewSegment.Count = 0;
    1015           0 :         mrSegments.push_back( aNewSegment );
    1016             :     }
    1017           0 :     aNewSegment.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
    1018           0 :     aNewSegment.Count = 0;
    1019           0 :     mrSegments.push_back( aNewSegment );
    1020           0 : }
    1021             : 
    1022           0 : ContextHandlerRef Path2DContext::onCreateContext( sal_Int32 aElementToken,
    1023             :     const AttributeList& rAttribs )
    1024             : {
    1025           0 :     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           0 :             if ( mrSegments.empty() || ( mrSegments.back().Command != EnhancedCustomShapeSegmentCommand::MOVETO ) ) {
    1031           0 :                 EnhancedCustomShapeSegment aNewSegment;
    1032           0 :                 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
    1033           0 :                 aNewSegment.Count = 0;
    1034           0 :                 mrSegments.push_back( aNewSegment );
    1035             :             }
    1036             :         }
    1037           0 :         break;
    1038             :         case A_TOKEN( moveTo ) :
    1039             :         {
    1040           0 :             EnhancedCustomShapeSegment aNewSegment;
    1041           0 :             aNewSegment.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
    1042           0 :             aNewSegment.Count = 1;
    1043           0 :             mrSegments.push_back( aNewSegment );
    1044             : 
    1045           0 :             EnhancedCustomShapeParameterPair aAdjPoint2D;
    1046           0 :             mrPath2D.parameter.push_back( aAdjPoint2D );
    1047           0 :             return new Path2DMoveToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
    1048             :         }
    1049             :         break;
    1050             :         case A_TOKEN( lnTo ) :
    1051             :         {
    1052           0 :             if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::LINETO ) )
    1053           0 :                 mrSegments.back().Count++;
    1054             :             else
    1055             :             {
    1056           0 :                 EnhancedCustomShapeSegment aSegment;
    1057           0 :                 aSegment.Command = EnhancedCustomShapeSegmentCommand::LINETO;
    1058           0 :                 aSegment.Count = 1;
    1059           0 :                 mrSegments.push_back( aSegment );
    1060             :             }
    1061           0 :             EnhancedCustomShapeParameterPair aAdjPoint2D;
    1062           0 :             mrPath2D.parameter.push_back( aAdjPoint2D );
    1063           0 :             return new Path2DLineToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
    1064             :         }
    1065             :         break;
    1066             :         case A_TOKEN( arcTo ) : // CT_Path2DArcTo
    1067             :         {
    1068           0 :             if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::ARCANGLETO ) )
    1069           0 :                 mrSegments.back().Count++;
    1070             :             else
    1071             :             {
    1072           0 :                 EnhancedCustomShapeSegment aSegment;
    1073           0 :                 aSegment.Command = EnhancedCustomShapeSegmentCommand::ARCANGLETO;
    1074           0 :                 aSegment.Count = 1;
    1075           0 :                 mrSegments.push_back( aSegment );
    1076             :             }
    1077             : 
    1078           0 :             EnhancedCustomShapeParameterPair aScale;
    1079           0 :             EnhancedCustomShapeParameterPair aAngles;
    1080             : 
    1081           0 :             aScale.First = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_wR ).get(), true );
    1082           0 :             aScale.Second = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_hR ).get(), true );
    1083             : 
    1084           0 :             CustomShapeGuide aGuide;
    1085           0 :             sal_Int32 nArcNum = mrCustomShapeProperties.getArcNum();
    1086             : 
    1087             :             // start angle
    1088           0 :             aGuide.maName = "arctosa" + OUString::number( nArcNum );
    1089           0 :             aGuide.maFormula = "("
    1090           0 :                 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_stAng ).get() ) )
    1091           0 :                 + ")/60000.0";
    1092           0 :             aAngles.First.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide ) );
    1093           0 :             aAngles.First.Type = EnhancedCustomShapeParameterType::EQUATION;
    1094             : 
    1095             :             // swing angle
    1096           0 :             aGuide.maName = "arctosw" + OUString::number( nArcNum );
    1097           0 :             aGuide.maFormula = "("
    1098           0 :                 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_swAng ).get() ) )
    1099           0 :                 + ")/60000.0";
    1100           0 :             aAngles.Second.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide ) );
    1101           0 :             aAngles.Second.Type = EnhancedCustomShapeParameterType::EQUATION;
    1102             : 
    1103           0 :             mrPath2D.parameter.push_back( aScale );
    1104           0 :             mrPath2D.parameter.push_back( aAngles );
    1105             :         }
    1106           0 :         break;
    1107             :         case A_TOKEN( quadBezTo ) :
    1108             :         {
    1109           0 :             if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO ) )
    1110           0 :                 mrSegments.back().Count++;
    1111             :             else
    1112             :             {
    1113           0 :                 EnhancedCustomShapeSegment aSegment;
    1114           0 :                 aSegment.Command = EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
    1115           0 :                 aSegment.Count = 1;
    1116           0 :                 mrSegments.push_back( aSegment );
    1117             :             }
    1118           0 :             EnhancedCustomShapeParameterPair aPt1;
    1119           0 :             EnhancedCustomShapeParameterPair aPt2;
    1120           0 :             mrPath2D.parameter.push_back( aPt1 );
    1121           0 :             mrPath2D.parameter.push_back( aPt2 );
    1122             :             return new Path2DQuadBezierToContext( *this, mrCustomShapeProperties,
    1123           0 :                             mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
    1124           0 :                                 mrPath2D.parameter.back() );
    1125             :         }
    1126             :         break;
    1127             :         case A_TOKEN( cubicBezTo ) :
    1128             :         {
    1129           0 :             if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::CURVETO ) )
    1130           0 :                 mrSegments.back().Count++;
    1131             :             else
    1132             :             {
    1133           0 :                 EnhancedCustomShapeSegment aSegment;
    1134           0 :                 aSegment.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
    1135           0 :                 aSegment.Count = 1;
    1136           0 :                 mrSegments.push_back( aSegment );
    1137             :             }
    1138           0 :             EnhancedCustomShapeParameterPair aControlPt1;
    1139           0 :             EnhancedCustomShapeParameterPair aControlPt2;
    1140           0 :             EnhancedCustomShapeParameterPair aEndPt;
    1141           0 :             mrPath2D.parameter.push_back( aControlPt1 );
    1142           0 :             mrPath2D.parameter.push_back( aControlPt2 );
    1143           0 :             mrPath2D.parameter.push_back( aEndPt );
    1144             :             return new Path2DCubicBezierToContext( *this, mrCustomShapeProperties,
    1145           0 :                             mrPath2D.parameter[ mrPath2D.parameter.size() - 3 ],
    1146           0 :                                 mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
    1147           0 :                                     mrPath2D.parameter.back() );
    1148             :         }
    1149             :         break;
    1150             :     }
    1151           0 :     return 0;
    1152             : }
    1153             : 
    1154             : 
    1155             : // CT_Path2DList
    1156           0 : 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           0 : 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           0 : , mrPath2DList( rPath2DList )
    1177             : {
    1178           0 : }
    1179             : 
    1180           0 : ContextHandlerRef Path2DListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
    1181             : {
    1182           0 :     if ( aElementToken == A_TOKEN( path ) )
    1183             :     {
    1184           0 :         Path2D aPath2D;
    1185           0 :         mrPath2DList.push_back( aPath2D );
    1186           0 :         return new Path2DContext( *this, rAttribs, mrCustomShapeProperties,  mrSegments, mrPath2DList.back() );
    1187             :     }
    1188           0 :     return 0;
    1189             : }
    1190             : 
    1191             : 
    1192             : // CT_CustomGeometry2D
    1193           0 : CustomShapeGeometryContext::CustomShapeGeometryContext( ContextHandler2Helper& rParent, const AttributeList& /* rAttribs */, CustomShapeProperties& rCustomShapeProperties )
    1194             : : ContextHandler2( rParent )
    1195           0 : , mrCustomShapeProperties( rCustomShapeProperties )
    1196             : {
    1197           0 : }
    1198             : 
    1199           0 : ContextHandlerRef CustomShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
    1200             : {
    1201           0 :     switch( aElementToken )
    1202             :     {
    1203             :         case A_TOKEN( avLst ):          // CT_GeomGuideList adjust value list
    1204           0 :             return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
    1205             :         case A_TOKEN( gdLst ):          // CT_GeomGuideList guide list
    1206           0 :             return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getGuideList() );
    1207             :         case A_TOKEN( ahLst ):          // CT_AdjustHandleList adjust handle list
    1208           0 :             return new AdjustHandleListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustHandleList() );
    1209             :         case A_TOKEN( cxnLst ):         // CT_ConnectionSiteList connection site list
    1210           0 :             return this;
    1211             :         case A_TOKEN( rect ):           // CT_GeomRectList geometry rect list
    1212             :         {
    1213           0 :             GeomRect aGeomRect;
    1214           0 :             aGeomRect.l = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_l ).get(), true );
    1215           0 :             aGeomRect.t = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_t ).get(), true );
    1216           0 :             aGeomRect.r = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_r ).get(), true );
    1217           0 :             aGeomRect.b = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_b ).get(), true );
    1218           0 :             mrCustomShapeProperties.getTextRect() = aGeomRect;
    1219             :         }
    1220           0 :         break;
    1221             :         case A_TOKEN( pathLst ):        // CT_Path2DList 2d path list
    1222           0 :             return new Path2DListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getSegments(), mrCustomShapeProperties.getPath2DList() );
    1223             : 
    1224             :         // from cxnLst:
    1225             :         case A_TOKEN( cxn ):                // CT_ConnectionSite
    1226             :         {
    1227           0 :             ConnectionSite aConnectionSite;
    1228           0 :             mrCustomShapeProperties.getConnectionSiteList().push_back( aConnectionSite );
    1229           0 :             return new ConnectionSiteContext( *this, rAttribs, mrCustomShapeProperties, mrCustomShapeProperties.getConnectionSiteList().back() );
    1230             :         }
    1231             :     }
    1232           0 :     return 0;
    1233             : }
    1234             : 
    1235             : 
    1236             : // CT_PresetGeometry2D
    1237           0 : PresetShapeGeometryContext::PresetShapeGeometryContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
    1238             : : ContextHandler2( rParent )
    1239           0 : , mrCustomShapeProperties( rCustomShapeProperties )
    1240             : {
    1241           0 :     sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
    1242             :     OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
    1243           0 :     mrCustomShapeProperties.setShapePresetType( nShapeType );
    1244           0 : }
    1245             : 
    1246           0 : ContextHandlerRef PresetShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
    1247             : {
    1248           0 :     if ( aElementToken == A_TOKEN( avLst ) )
    1249           0 :         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           0 : } }
    1274             : 
    1275             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10