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

Generated by: LCOV version 1.11