LCOV - code coverage report
Current view: top level - oox/source/drawingml - customshapegeometry.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 480 545 88.1 %
Date: 2014-11-03 Functions: 57 59 96.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10