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

Generated by: LCOV version 1.10