LCOV - code coverage report
Current view: top level - oox/source/drawingml - customshapepresetdata.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 470 470 100.0 %
Date: 2015-06-13 12:38:46 Functions: 25 25 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <config_folders.h>
      11             : #include <rtl/bootstrap.hxx>
      12             : #include <tools/stream.hxx>
      13             : #include <comphelper/sequence.hxx>
      14             : 
      15             : #include "drawingml/customshapeproperties.hxx"
      16             : #include "oox/token/tokenmap.hxx"
      17             : #include <com/sun/star/awt/Rectangle.hpp>
      18             : 
      19             : using namespace ::com::sun::star;
      20             : 
      21             : namespace
      22             : {
      23             : 
      24             : // Parses a string like: Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj"
      25        5100 : void lcl_parseAdjustmentValue(std::vector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
      26             : {
      27        5100 :     sal_Int32 nIndex = 0;
      28        5100 :     drawing::EnhancedCustomShapeAdjustmentValue aAdjustmentValue;
      29       15300 :     do
      30             :     {
      31       15300 :         OString aToken = rValue.getToken(0, ',', nIndex).trim();
      32             :         static const char aNamePrefix[] = "Name = \"";
      33             :         static const char aValuePrefix[] = "Value = (any) { (long) ";
      34       15300 :         if (aToken.startsWith(aNamePrefix))
      35             :         {
      36        5100 :             OString aName = aToken.copy(strlen(aNamePrefix), aToken.getLength() - strlen(aNamePrefix) - strlen("\""));
      37        5100 :             aAdjustmentValue.Name = OUString::fromUtf8(aName);
      38             :         }
      39       10200 :         else if (aToken.startsWith(aValuePrefix))
      40             :         {
      41        5100 :             OString aValue = aToken.copy(strlen(aValuePrefix), aToken.getLength() - strlen(aValuePrefix) - strlen(" }"));
      42        5100 :             aAdjustmentValue.Value = uno::makeAny(aValue.toInt32());
      43             :         }
      44        5100 :         else if (!aToken.startsWith("State = "))
      45       15300 :             SAL_WARN("oox", "lcl_parseAdjustmentValue: unexpected prefix: " << aToken);
      46             :     }
      47       15300 :     while (nIndex >= 0);
      48        5100 :     rAdjustmentValues.push_back(aAdjustmentValue);
      49        5100 : }
      50             : 
      51             : // Parses a string like: { Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj" }, { Value = ..., State = ..., Name = ... }
      52        2091 : void lcl_parseAdjustmentValues(std::vector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
      53             : {
      54        2091 :     sal_Int32 nLevel = 0;
      55        2091 :     sal_Int32 nStart = 0;
      56      548437 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
      57             :     {
      58      546346 :         if (rValue[i] == '{')
      59             :         {
      60       10200 :             if (!nLevel)
      61        5100 :                 nStart = i;
      62       10200 :             nLevel++;
      63             :         }
      64      536146 :         else if (rValue[i] == '}')
      65             :         {
      66       10200 :             nLevel--;
      67       10200 :             if (!nLevel)
      68             :             {
      69        5100 :                 lcl_parseAdjustmentValue(rAdjustmentValues, rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
      70             :             }
      71             :         }
      72             :     }
      73        2091 : }
      74             : 
      75       62628 : drawing::EnhancedCustomShapeParameterPair lcl_parseEnhancedCustomShapeParameterPair(const OString& rValue)
      76             : {
      77       62628 :     drawing::EnhancedCustomShapeParameterPair aPair;
      78      125256 :     OString aToken = rValue;
      79             :     // We expect the followings here: First.Value, First.Type, Second.Value, Second.Type
      80             :     static const char aExpectedFVPrefix[] = "First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
      81             :     assert(aToken.startsWith(aExpectedFVPrefix));
      82       62628 :     sal_Int32 nIndex = strlen(aExpectedFVPrefix);
      83       62628 :     aPair.First.Value = uno::makeAny(static_cast<sal_uInt32>(aToken.getToken(0, '}', nIndex).toInt32()));
      84             : 
      85             :     static const char aExpectedFTPrefix[] = ", Type = (short) ";
      86       62628 :     aToken = aToken.copy(nIndex);
      87             :     assert(aToken.startsWith(aExpectedFTPrefix));
      88       62628 :     nIndex = strlen(aExpectedFTPrefix);
      89       62628 :     aPair.First.Type = static_cast<sal_uInt16>(aToken.getToken(0, '}', nIndex).toInt32());
      90             : 
      91             :     static const char aExpectedSVPrefix[] = ", Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
      92       62628 :     aToken = aToken.copy(nIndex);
      93             :     assert(aToken.startsWith(aExpectedSVPrefix));
      94       62628 :     nIndex = strlen(aExpectedSVPrefix);
      95       62628 :     aPair.Second.Value = uno::makeAny(static_cast<sal_uInt32>(aToken.getToken(0, '}', nIndex).toInt32()));
      96             : 
      97             :     static const char aExpectedSTPrefix[] = ", Type = (short) ";
      98       62628 :     aToken = aToken.copy(nIndex);
      99             :     assert(aToken.startsWith(aExpectedSTPrefix));
     100       62628 :     nIndex = strlen(aExpectedSTPrefix);
     101       62628 :     aPair.Second.Type = static_cast<sal_uInt16>(aToken.getToken(0, '}', nIndex).toInt32());
     102      125256 :     return aPair;
     103             : }
     104             : 
     105       36890 : drawing::EnhancedCustomShapeSegment lcl_parseEnhancedCustomShapeSegment(const OString& rValue)
     106             : {
     107       36890 :     drawing::EnhancedCustomShapeSegment aSegment;
     108       36890 :     OString aToken = rValue;
     109             :     // We expect the followings here: Command, Count
     110             :     static const char aExpectedCommandPrefix[] = "Command = (short) ";
     111             :     assert(aToken.startsWith(aExpectedCommandPrefix));
     112       36890 :     sal_Int32 nIndex = strlen(aExpectedCommandPrefix);
     113       36890 :     aSegment.Command = static_cast<sal_Int16>(aToken.getToken(0, ',', nIndex).toInt32());
     114             : 
     115             :     static const char aExpectedCountPrefix[] = " Count = (short) ";
     116       36890 :     aToken = aToken.copy(nIndex);
     117             :     assert(aToken.startsWith(aExpectedCountPrefix));
     118       36890 :     nIndex = strlen(aExpectedCountPrefix);
     119       36890 :     aSegment.Count = static_cast<sal_Int16>(aToken.getToken(0, '}', nIndex).toInt32());
     120       36890 :     return aSegment;
     121             : }
     122             : 
     123        3179 : awt::Rectangle lcl_parseRectangle(const OString& rValue)
     124             : {
     125        3179 :     awt::Rectangle aRectangle;
     126        3179 :     OString aToken = rValue;
     127             :     // We expect the followings here: X, Y, Width, Height
     128             :     static const char aExpectedXPrefix[] = "X = (long) ";
     129             :     assert(aToken.startsWith(aExpectedXPrefix));
     130        3179 :     sal_Int32 nIndex = strlen(aExpectedXPrefix);
     131        3179 :     aRectangle.X = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
     132             : 
     133             :     static const char aExpectedYPrefix[] = " Y = (long) ";
     134        3179 :     aToken = aToken.copy(nIndex);
     135             :     assert(aToken.startsWith(aExpectedYPrefix));
     136        3179 :     nIndex = strlen(aExpectedYPrefix);
     137        3179 :     aRectangle.Y = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
     138             : 
     139             :     static const char aExpectedWidthPrefix[] = " Width = (long) ";
     140        3179 :     aToken = aToken.copy(nIndex);
     141             :     assert(aToken.startsWith(aExpectedWidthPrefix));
     142        3179 :     nIndex = strlen(aExpectedWidthPrefix);
     143        3179 :     aRectangle.Width = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
     144             : 
     145             :     static const char aExpectedHeightPrefix[] = " Height = (long) ";
     146        3179 :     aToken = aToken.copy(nIndex);
     147             :     assert(aToken.startsWith(aExpectedHeightPrefix));
     148        3179 :     nIndex = strlen(aExpectedHeightPrefix);
     149        3179 :     aRectangle.Height = static_cast<sal_Int32>(aToken.copy(nIndex).toInt32());
     150             : 
     151        3179 :     return aRectangle;
     152             : }
     153             : 
     154         901 : awt::Size lcl_parseSize(const OString& rValue)
     155             : {
     156         901 :     awt::Size aSize;
     157         901 :     OString aToken = rValue;
     158             :     // We expect the followings here: Width, Height
     159             :     static const char aExpectedWidthPrefix[] = "Width = (long) ";
     160             :     assert(aToken.startsWith(aExpectedWidthPrefix));
     161         901 :     sal_Int32 nIndex = strlen(aExpectedWidthPrefix);
     162         901 :     aSize.Width = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
     163             : 
     164             :     static const char aExpectedHeightPrefix[] = " Height = (long) ";
     165         901 :     aToken = aToken.copy(nIndex);
     166             :     assert(aToken.startsWith(aExpectedHeightPrefix));
     167         901 :     nIndex = strlen(aExpectedHeightPrefix);
     168         901 :     aSize.Height = static_cast<sal_Int32>(aToken.copy(nIndex).toInt32());
     169             : 
     170         901 :     return aSize;
     171             : }
     172             : 
     173        3094 : drawing::EnhancedCustomShapeTextFrame lcl_parseEnhancedCustomShapeTextFrame(const OString& rValue)
     174             : {
     175        3094 :     drawing::EnhancedCustomShapeTextFrame aTextFrame;
     176        3094 :     sal_Int32 nLevel = 0;
     177        3094 :     bool bIgnore = false;
     178        3094 :     sal_Int32 nStart = 0;
     179     1815481 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     180             :     {
     181     1812387 :         if (rValue[i] == '{')
     182             :         {
     183       30940 :             if (!nLevel)
     184        6188 :                 bIgnore = true;
     185       30940 :             nLevel++;
     186             :         }
     187     1781447 :         else if (rValue[i] == '}')
     188             :         {
     189       30940 :             nLevel--;
     190       30940 :             if (!nLevel)
     191        6188 :                 bIgnore = false;
     192             :         }
     193     1750507 :         else if (rValue[i] == ',' && !bIgnore)
     194             :         {
     195        3094 :             OString aToken = rValue.copy(nStart, i - nStart);
     196             :             static const char aExpectedPrefix[] = "TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
     197        3094 :             if (aToken.startsWith(aExpectedPrefix))
     198             :             {
     199        3094 :                 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" }"));
     200        3094 :                 aTextFrame.TopLeft = lcl_parseEnhancedCustomShapeParameterPair(aToken);
     201             :             }
     202             :             else
     203             :                 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token: " << aToken);
     204        3094 :             nStart = i + strlen(", ");
     205             :         }
     206             :     }
     207             : 
     208        6188 :     OString aToken = rValue.copy(nStart, rValue.getLength() - nStart);
     209             :     static const char aExpectedPrefix[] = "BottomRight = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
     210        3094 :     if (aToken.startsWith(aExpectedPrefix))
     211             :     {
     212        3094 :         aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" }"));
     213        3094 :         aTextFrame.BottomRight = lcl_parseEnhancedCustomShapeParameterPair(aToken);
     214             :     }
     215             :     else
     216             :         SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token at the end: " << aToken);
     217             : 
     218        6188 :     return aTextFrame;
     219             : }
     220             : 
     221             : // Parses a string like: Name = "Position", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
     222             : // where "{ ... }" may contain "," as well.
     223        4131 : void lcl_parseHandlePosition(std::vector<beans::PropertyValue>& rHandle, const OString& rValue)
     224             : {
     225        4131 :     sal_Int32 nLevel = 0;
     226        4131 :     bool bIgnore = false;
     227        4131 :     sal_Int32 nStart = 0;
     228     1627104 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     229             :     {
     230     1622973 :         if (rValue[i] == '{')
     231             :         {
     232       24786 :             if (!nLevel)
     233        4131 :                 bIgnore = true;
     234       24786 :             nLevel++;
     235             :         }
     236     1598187 :         else if (rValue[i] == '}')
     237             :         {
     238       24786 :             nLevel--;
     239       24786 :             if (!nLevel)
     240        4131 :                 bIgnore = false;
     241             :         }
     242     1573401 :         else if (rValue[i] == ',' && !bIgnore)
     243             :         {
     244       12393 :             OString aToken = rValue.copy(nStart, i - nStart);
     245             :             static const char aExpectedPrefix[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
     246       12393 :             if (aToken.startsWith(aExpectedPrefix))
     247             :             {
     248        4131 :                 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
     249             : 
     250        4131 :                 beans::PropertyValue aPropertyValue;
     251        4131 :                 aPropertyValue.Name = "Position";
     252        4131 :                 aPropertyValue.Value = uno::makeAny(lcl_parseEnhancedCustomShapeParameterPair(aToken));
     253        4131 :                 rHandle.push_back(aPropertyValue);
     254             :             }
     255        8262 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     256             :                 SAL_WARN("oox", "lcl_parseHandlePosition: unexpected token: " << aToken);
     257       12393 :             nStart = i + strlen(", ");
     258             :         }
     259             :     }
     260        4131 : }
     261             : 
     262             : // Parses a string like: Name = "RangeYMaximum", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
     263             : // where "{ ... }" may contain "," as well.
     264        9146 : void lcl_parseHandleRange(std::vector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
     265             : {
     266        9146 :     sal_Int32 nLevel = 0;
     267        9146 :     bool bIgnore = false;
     268        9146 :     sal_Int32 nStart = 0;
     269     2041377 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     270             :     {
     271     2032231 :         if (rValue[i] == '{')
     272             :         {
     273       27438 :             if (!nLevel)
     274        9146 :                 bIgnore = true;
     275       27438 :             nLevel++;
     276             :         }
     277     2004793 :         else if (rValue[i] == '}')
     278             :         {
     279       27438 :             nLevel--;
     280       27438 :             if (!nLevel)
     281        9146 :                 bIgnore = false;
     282             :         }
     283     1977355 :         else if (rValue[i] == ',' && !bIgnore)
     284             :         {
     285       27438 :             OString aToken = rValue.copy(nStart, i - nStart);
     286             :             static const char aExpectedPrefix[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameter) { ";
     287       27438 :             if (aToken.startsWith(aExpectedPrefix))
     288             :             {
     289        9146 :                 drawing::EnhancedCustomShapeParameter aParameter;
     290        9146 :                 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
     291             :                 // We expect the followings here: Value and Type
     292             :                 static const char aExpectedVPrefix[] = "Value = (any) { (long) ";
     293             :                 assert(aToken.startsWith(aExpectedVPrefix));
     294        9146 :                 sal_Int32 nIndex = strlen(aExpectedVPrefix);
     295        9146 :                 aParameter.Value = uno::makeAny(aToken.getToken(0, '}', nIndex).toInt32());
     296             : 
     297             :                 static const char aExpectedTPrefix[] = ", Type = (short) ";
     298        9146 :                 aToken = aToken.copy(nIndex);
     299             :                 assert(aToken.startsWith(aExpectedTPrefix));
     300        9146 :                 nIndex = strlen(aExpectedTPrefix);
     301        9146 :                 aParameter.Type = static_cast<sal_Int16>(aToken.getToken(0, '}', nIndex).toInt32());
     302             : 
     303       18292 :                 beans::PropertyValue aPropertyValue;
     304        9146 :                 aPropertyValue.Name = rName;
     305        9146 :                 aPropertyValue.Value = uno::makeAny(aParameter);
     306       18292 :                 rHandle.push_back(aPropertyValue);
     307             : 
     308             :             }
     309       18292 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     310             :                 SAL_WARN("oox", "lcl_parseHandleRange: unexpected token: " << aToken);
     311       27438 :             nStart = i + strlen(", ");
     312             :         }
     313             :     }
     314        9146 : }
     315             : 
     316             : // Parses a string like: Name = "RefY", Handle = (long) 0, Value = (any) { (long) 0 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
     317        4420 : void lcl_parseHandleRef(std::vector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
     318             : {
     319             :     static const char aExpectedXPrefix[] = "Name = \"RefX\", Handle = (long) 0, Value = (any) { (long) ";
     320             :     static const char aExpectedYPrefix[] = "Name = \"RefY\", Handle = (long) 0, Value = (any) { (long) ";
     321        4420 :     if (rValue.startsWith(aExpectedXPrefix) || rValue.startsWith(aExpectedYPrefix))
     322             :     {
     323        4420 :         sal_Int32 nIndex = strlen(aExpectedXPrefix);
     324        4420 :         beans::PropertyValue aPropertyValue;
     325        4420 :         aPropertyValue.Name = rName;
     326             :         // We only expect a Value here
     327        4420 :         aPropertyValue.Value = uno::makeAny(rValue.getToken(0, '}', nIndex).toInt32());
     328        4420 :         rHandle.push_back(aPropertyValue);
     329             :     }
     330             :     else
     331             :         SAL_WARN("oox", "lcl_parseHandleRef: unexpected value: " << rValue);
     332        4420 : }
     333             : 
     334        4131 : uno::Sequence<beans::PropertyValue> lcl_parseHandle(const OString& rValue)
     335             : {
     336        4131 :     std::vector<beans::PropertyValue> aRet;
     337        4131 :     sal_Int32 nLevel = 0;
     338        4131 :     sal_Int32 nStart = 0;
     339     4274395 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     340             :     {
     341     4270264 :         if (rValue[i] == '{')
     342             :         {
     343       74341 :             if (!nLevel)
     344       17697 :                 nStart = i;
     345       74341 :             nLevel++;
     346             :         }
     347     4195923 :         else if (rValue[i] == '}')
     348             :         {
     349       74341 :             nLevel--;
     350       74341 :             if (!nLevel)
     351             :             {
     352       17697 :                 OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
     353       17697 :                 if (aToken.startsWith("Name = \"Position\""))
     354        4131 :                     lcl_parseHandlePosition(aRet, aToken);
     355       13566 :                 else if (aToken.startsWith("Name = \"RangeXMaximum\""))
     356        2244 :                     lcl_parseHandleRange(aRet, aToken, "RangeXMaximum");
     357       11322 :                 else if (aToken.startsWith("Name = \"RangeXMinimum\""))
     358        2244 :                     lcl_parseHandleRange(aRet, aToken, "RangeXMinimum");
     359        9078 :                 else if (aToken.startsWith("Name = \"RangeYMaximum\""))
     360        2176 :                     lcl_parseHandleRange(aRet, aToken, "RangeYMaximum");
     361        6902 :                 else if (aToken.startsWith("Name = \"RangeYMinimum\""))
     362        2176 :                     lcl_parseHandleRange(aRet, aToken, "RangeYMinimum");
     363        4726 :                 else if (aToken.startsWith("Name = \"RadiusRangeMaximum\""))
     364         153 :                     lcl_parseHandleRange(aRet, aToken, "RadiusRangeMaximum");
     365        4573 :                 else if (aToken.startsWith("Name = \"RadiusRangeMinimum\""))
     366         153 :                     lcl_parseHandleRange(aRet, aToken, "RadiusRangeMinimum");
     367        4420 :                 else if (aToken.startsWith("Name = \"RefX\""))
     368        2244 :                     lcl_parseHandleRef(aRet, aToken, "RefX");
     369        2176 :                 else if (aToken.startsWith("Name = \"RefY\""))
     370        2176 :                     lcl_parseHandleRef(aRet, aToken, "RefY");
     371             :                 else
     372       17697 :                     SAL_WARN("oox", "lcl_parseHandle: unexpected token: " << aToken);
     373             :             }
     374             :         }
     375             :     }
     376        4131 :     return comphelper::containerToSequence(aRet);
     377             : }
     378             : 
     379        2040 : void lcl_parseHandles(std::vector< uno::Sequence<beans::PropertyValue> >& rHandles, const OString& rValue)
     380             : {
     381        2040 :     sal_Int32 nLevel = 0;
     382        2040 :     sal_Int32 nStart = 0;
     383     4293010 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     384             :     {
     385     4290970 :         if (rValue[i] == '{')
     386             :         {
     387       78472 :             if (!nLevel)
     388        4131 :                 nStart = i;
     389       78472 :             nLevel++;
     390             :         }
     391     4212498 :         else if (rValue[i] == '}')
     392             :         {
     393       78472 :             nLevel--;
     394       78472 :             if (!nLevel)
     395             :             {
     396        4131 :                 uno::Sequence<beans::PropertyValue> aHandle = lcl_parseHandle(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
     397        4131 :                 rHandles.push_back(aHandle);
     398             :             }
     399             :         }
     400             :     }
     401        2040 : }
     402             : 
     403        3128 : void lcl_parseEquations(std::vector<OUString>& rEquations, const OString& rValue)
     404             : {
     405        3128 :     bool bInString = false;
     406        3128 :     sal_Int32 nStart = 0;
     407     1728288 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     408             :     {
     409     1725160 :         if (rValue[i] == '"' && !bInString)
     410             :         {
     411       89250 :             nStart = i;
     412       89250 :             bInString = true;
     413             :         }
     414     1635910 :         else if (rValue[i] == '"' && bInString)
     415             :         {
     416       89250 :             bInString = false;
     417       89250 :             rEquations.push_back(OUString::fromUtf8(rValue.copy(nStart + strlen("\""), i - nStart - strlen("\""))));
     418             :         }
     419             :     }
     420        3128 : }
     421             : 
     422        3179 : void lcl_parsePathCoordinateValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
     423             : {
     424        3179 :     std::vector<drawing::EnhancedCustomShapeParameterPair> aPairs;
     425        3179 :     sal_Int32 nLevel = 0;
     426        3179 :     sal_Int32 nStart = 0;
     427    11845974 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     428             :     {
     429    11842795 :         if (rValue[i] == '{')
     430             :         {
     431      261545 :             if (!nLevel)
     432       52309 :                 nStart = i;
     433      261545 :             nLevel++;
     434             :         }
     435    11581250 :         else if (rValue[i] == '}')
     436             :         {
     437      261545 :             nLevel--;
     438      261545 :             if (!nLevel)
     439       52309 :                 aPairs.push_back(lcl_parseEnhancedCustomShapeParameterPair(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
     440             :         }
     441             :     }
     442             : 
     443        6358 :     beans::PropertyValue aPropertyValue;
     444        3179 :     aPropertyValue.Name = "Coordinates";
     445        3179 :     aPropertyValue.Value = uno::makeAny(comphelper::containerToSequence(aPairs));
     446        6358 :     rPath.push_back(aPropertyValue);
     447        3179 : }
     448             : 
     449             : // Parses a string like: Name = "Coordinates", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
     450             : // where "{ ... }" may contain "," as well.
     451        3179 : void lcl_parsePathCoordinates(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
     452             : {
     453        3179 :     sal_Int32 nLevel = 0;
     454        3179 :     bool bIgnore = false;
     455        3179 :     sal_Int32 nStart = 0;
     456    12411836 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     457             :     {
     458    12408657 :         if (rValue[i] == '{')
     459             :         {
     460      267903 :             if (!nLevel)
     461        3179 :                 bIgnore = true;
     462      267903 :             nLevel++;
     463             :         }
     464    12140754 :         else if (rValue[i] == '}')
     465             :         {
     466      267903 :             nLevel--;
     467      267903 :             if (!nLevel)
     468        3179 :                 bIgnore = false;
     469             :         }
     470    11872851 :         else if (rValue[i] == ',' && !bIgnore)
     471             :         {
     472        9537 :             OString aToken = rValue.copy(nStart, i - nStart);
     473             :             static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
     474        9537 :             if (aToken.startsWith(aExpectedPrefix))
     475             :             {
     476        3179 :                 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
     477        3179 :                 lcl_parsePathCoordinateValues(rPath, aToken);
     478             :             }
     479        6358 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     480             :                 SAL_WARN("oox", "lcl_parsePathCoordinates: unexpected token: " << aToken);
     481        9537 :             nStart = i + strlen(", ");
     482             :         }
     483             :     }
     484        3179 : }
     485             : 
     486        3179 : void lcl_parsePathSegmentValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
     487             : {
     488        3179 :     std::vector<drawing::EnhancedCustomShapeSegment> aSegments;
     489        3179 :     sal_Int32 nLevel = 0;
     490        3179 :     sal_Int32 nStart = 0;
     491     1626832 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     492             :     {
     493     1623653 :         if (rValue[i] == '{')
     494             :         {
     495       36890 :             if (!nLevel)
     496       36890 :                 nStart = i;
     497       36890 :             nLevel++;
     498             :         }
     499     1586763 :         else if (rValue[i] == '}')
     500             :         {
     501       36890 :             nLevel--;
     502       36890 :             if (!nLevel)
     503       36890 :                 aSegments.push_back(lcl_parseEnhancedCustomShapeSegment(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
     504             :         }
     505             :     }
     506             : 
     507        6358 :     beans::PropertyValue aPropertyValue;
     508        3179 :     aPropertyValue.Name = "Segments";
     509        3179 :     aPropertyValue.Value = uno::makeAny(comphelper::containerToSequence(aSegments));
     510        6358 :     rPath.push_back(aPropertyValue);
     511        3179 : }
     512             : 
     513             : // Parses a string like: Name = "Segments", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
     514             : // where "{ ... }" may contain "," as well.
     515        3179 : void lcl_parsePathSegments(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
     516             : {
     517        3179 :     sal_Int32 nLevel = 0;
     518        3179 :     bool bIgnore = false;
     519        3179 :     sal_Int32 nStart = 0;
     520     2164083 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     521             :     {
     522     2160904 :         if (rValue[i] == '{')
     523             :         {
     524       43248 :             if (!nLevel)
     525        3179 :                 bIgnore = true;
     526       43248 :             nLevel++;
     527             :         }
     528     2117656 :         else if (rValue[i] == '}')
     529             :         {
     530       43248 :             nLevel--;
     531       43248 :             if (!nLevel)
     532        3179 :                 bIgnore = false;
     533             :         }
     534     2074408 :         else if (rValue[i] == ',' && !bIgnore)
     535             :         {
     536        9537 :             OString aToken = rValue.copy(nStart, i - nStart);
     537             :             static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { ";
     538        9537 :             if (aToken.startsWith(aExpectedPrefix))
     539             :             {
     540        3179 :                 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
     541        3179 :                 lcl_parsePathSegmentValues(rPath, aToken);
     542             :             }
     543        6358 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     544             :                 SAL_WARN("oox", "lcl_parsePathSegments: unexpected token: " << aToken);
     545        9537 :             nStart = i + strlen(", ");
     546             :         }
     547             :     }
     548        3179 : }
     549             : 
     550        3094 : void lcl_parsePathTextFrameValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
     551             : {
     552        3094 :     std::vector<drawing::EnhancedCustomShapeTextFrame> aTextFrames;
     553        3094 :     sal_Int32 nLevel = 0;
     554        3094 :     sal_Int32 nStart = 0;
     555     1827857 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     556             :     {
     557     1824763 :         if (rValue[i] == '{')
     558             :         {
     559       34034 :             if (!nLevel)
     560        3094 :                 nStart = i;
     561       34034 :             nLevel++;
     562             :         }
     563     1790729 :         else if (rValue[i] == '}')
     564             :         {
     565       34034 :             nLevel--;
     566       34034 :             if (!nLevel)
     567        3094 :                 aTextFrames.push_back(lcl_parseEnhancedCustomShapeTextFrame(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
     568             :         }
     569             :     }
     570             : 
     571        6188 :     beans::PropertyValue aPropertyValue;
     572        3094 :     aPropertyValue.Name = "TextFrames";
     573        3094 :     aPropertyValue.Value = uno::makeAny(comphelper::containerToSequence(aTextFrames));
     574        6188 :     rPath.push_back(aPropertyValue);
     575        3094 : }
     576             : 
     577             : // Parses a string like: Name = "TextFrames", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
     578             : // where "{ ... }" may contain "," as well.
     579        3094 : void lcl_parsePathTextFrames(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
     580             : {
     581        3094 :     sal_Int32 nLevel = 0;
     582        3094 :     bool bIgnore = false;
     583        3094 :     sal_Int32 nStart = 0;
     584     2363119 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     585             :     {
     586     2360025 :         if (rValue[i] == '{')
     587             :         {
     588       40222 :             if (!nLevel)
     589        3094 :                 bIgnore = true;
     590       40222 :             nLevel++;
     591             :         }
     592     2319803 :         else if (rValue[i] == '}')
     593             :         {
     594       40222 :             nLevel--;
     595       40222 :             if (!nLevel)
     596        3094 :                 bIgnore = false;
     597             :         }
     598     2279581 :         else if (rValue[i] == ',' && !bIgnore)
     599             :         {
     600        9282 :             OString aToken = rValue.copy(nStart, i - nStart);
     601             :             static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { ";
     602        9282 :             if (aToken.startsWith(aExpectedPrefix))
     603             :             {
     604        3094 :                 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
     605        3094 :                 lcl_parsePathTextFrameValues(rPath, aToken);
     606             :             }
     607        6188 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     608             :                 SAL_WARN("oox", "lcl_parsePathTextFrames: unexpected token: " << aToken);
     609        9282 :             nStart = i + strlen(", ");
     610             :         }
     611             :     }
     612        3094 : }
     613             : 
     614         527 : void lcl_parsePathSubViewSizeValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
     615             : {
     616         527 :     std::vector<awt::Size> aSizes;
     617         527 :     sal_Int32 nLevel = 0;
     618         527 :     sal_Int32 nStart = 0;
     619       38352 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     620             :     {
     621       37825 :         if (rValue[i] == '{')
     622             :         {
     623         901 :             if (!nLevel)
     624         901 :                 nStart = i;
     625         901 :             nLevel++;
     626             :         }
     627       36924 :         else if (rValue[i] == '}')
     628             :         {
     629         901 :             nLevel--;
     630         901 :             if (!nLevel)
     631         901 :                 aSizes.push_back(lcl_parseSize(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
     632             :         }
     633             :     }
     634             : 
     635        1054 :     beans::PropertyValue aPropertyValue;
     636         527 :     aPropertyValue.Name = "SubViewSize";
     637         527 :     aPropertyValue.Value = uno::makeAny(comphelper::containerToSequence(aSizes));
     638        1054 :     rPath.push_back(aPropertyValue);
     639         527 : }
     640             : 
     641         527 : void lcl_parsePathSubViewSize(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
     642             : {
     643         527 :     sal_Int32 nLevel = 0;
     644         527 :     bool bIgnore = false;
     645         527 :     sal_Int32 nStart = 0;
     646      115294 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     647             :     {
     648      114767 :         if (rValue[i] == '{')
     649             :         {
     650        1955 :             if (!nLevel)
     651         527 :                 bIgnore = true;
     652        1955 :             nLevel++;
     653             :         }
     654      112812 :         else if (rValue[i] == '}')
     655             :         {
     656        1955 :             nLevel--;
     657        1955 :             if (!nLevel)
     658         527 :                 bIgnore = false;
     659             :         }
     660      110857 :         else if (rValue[i] == ',' && !bIgnore)
     661             :         {
     662        1581 :             OString aToken = rValue.copy(nStart, i - nStart);
     663             :             static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.awt.Size) { ";
     664        1581 :             if (aToken.startsWith(aExpectedPrefix))
     665             :             {
     666         527 :                 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
     667         527 :                 lcl_parsePathSubViewSizeValues(rPath, aToken);
     668             :             }
     669        1054 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     670             :                 SAL_WARN("oox", "lcl_parsePathSubViewSize: unexpected token: " << aToken);
     671        1581 :             nStart = i + strlen(", ");
     672             :         }
     673             :     }
     674         527 : }
     675             : 
     676        3179 : void lcl_parsePath(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
     677             : {
     678        3179 :     sal_Int32 nLevel = 0;
     679        3179 :     sal_Int32 nStart = 0;
     680    17101048 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     681             :     {
     682    17097869 :         if (rValue[i] == '{')
     683             :         {
     684      363307 :             if (!nLevel)
     685        9979 :                 nStart = i;
     686      363307 :             nLevel++;
     687             :         }
     688    16734562 :         else if (rValue[i] == '}')
     689             :         {
     690      363307 :             nLevel--;
     691      363307 :             if (!nLevel)
     692             :             {
     693        9979 :                 OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
     694        9979 :                 if (aToken.startsWith("Name = \"Coordinates\""))
     695        3179 :                     lcl_parsePathCoordinates(rPath, aToken);
     696        6800 :                 else if (aToken.startsWith("Name = \"Segments\""))
     697        3179 :                     lcl_parsePathSegments(rPath, aToken);
     698        3621 :                 else if (aToken.startsWith("Name = \"TextFrames\""))
     699        3094 :                     lcl_parsePathTextFrames(rPath, aToken);
     700         527 :                 else if (aToken.startsWith("Name = \"SubViewSize\""))
     701         527 :                     lcl_parsePathSubViewSize(rPath, aToken);
     702             :                 else
     703        9979 :                     SAL_WARN("oox", "lcl_parsePath: unexpected token: " << aToken);
     704             :             }
     705             :         }
     706             :     }
     707        3179 : }
     708             : 
     709             : }
     710             : 
     711             : namespace oox
     712             : {
     713             : namespace drawingml
     714             : {
     715             : 
     716          17 : void CustomShapeProperties::initializePresetDataMap()
     717             : {
     718          17 :     OUString aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/oox-drawingml-cs-presets");
     719          17 :     rtl::Bootstrap::expandMacros(aPath);
     720          34 :     SvFileStream aStream(aPath, StreamMode::READ);
     721          17 :     if (aStream.GetError() != ERRCODE_NONE)
     722             :         SAL_WARN("oox", "failed to open oox-drawingml-cs-presets");
     723          34 :     OString aLine;
     724          34 :     OUString aName;
     725          17 :     bool bNotDone = aStream.ReadLine(aLine);
     726          34 :     PropertyMap aPropertyMap;
     727          17 :     bool bFirst = true;
     728       28645 :     while (bNotDone)
     729             :     {
     730             :         static const char aCommentPrefix[] = "/* ";
     731       28611 :         if (aLine.startsWith(aCommentPrefix))
     732             :         {
     733        3179 :             if (bFirst)
     734          17 :                 bFirst = false;
     735             :             else
     736        3162 :                 maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap;
     737        3179 :             aName = OUString::fromUtf8(aLine.copy(strlen(aCommentPrefix), aLine.getLength() - strlen(aCommentPrefix) - strlen(" */")));
     738             :         }
     739             :         else
     740             :         {
     741       25432 :             if (aLine == "AdjustmentValues")
     742             :             {
     743        3179 :                 aStream.ReadLine(aLine);
     744        3179 :                 if (aLine != "([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) {}")
     745             :                 {
     746        2091 :                     std::vector<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustmentValues;
     747        4182 :                     OString aExpectedPrefix("([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) { ");
     748             :                     assert(aLine.startsWith(aExpectedPrefix));
     749             : 
     750        4182 :                     OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     751        2091 :                     lcl_parseAdjustmentValues(aAdjustmentValues, aValue);
     752        4182 :                     aPropertyMap.setProperty(PROP_AdjustmentValues, comphelper::containerToSequence(aAdjustmentValues));
     753             :                 }
     754             :                 else
     755        1088 :                     aPropertyMap.setProperty(PROP_AdjustmentValues, uno::Sequence<OUString>(0));
     756             :             }
     757       22253 :             else if (aLine == "Equations")
     758             :             {
     759        3179 :                 aStream.ReadLine(aLine);
     760        3179 :                 if (aLine != "([]string) {}")
     761             :                 {
     762        3128 :                     std::vector<OUString> aEquations;
     763        6256 :                     OString aExpectedPrefix("([]string) { ");
     764             :                     assert(aLine.startsWith(aExpectedPrefix));
     765             : 
     766        6256 :                     OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     767        3128 :                     lcl_parseEquations(aEquations, aValue);
     768        6256 :                     aPropertyMap.setProperty(PROP_Equations, comphelper::containerToSequence(aEquations));
     769             :                 }
     770             :                 else
     771          51 :                     aPropertyMap.setProperty(PROP_Equations, uno::Sequence<OUString>(0));
     772             :             }
     773       19074 :             else if (aLine == "Handles")
     774             :             {
     775        3179 :                 aStream.ReadLine(aLine);
     776        3179 :                 if (aLine != "([][]com.sun.star.beans.PropertyValue) {}")
     777             :                 {
     778        2040 :                     std::vector< uno::Sequence<beans::PropertyValue> > aHandles;
     779        4080 :                     OString aExpectedPrefix("([][]com.sun.star.beans.PropertyValue) { ");
     780             :                     assert(aLine.startsWith(aExpectedPrefix));
     781             : 
     782        4080 :                     OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     783        2040 :                     lcl_parseHandles(aHandles, aValue);
     784        4080 :                     aPropertyMap.setProperty(PROP_Handles, comphelper::containerToSequence(aHandles));
     785             :                 }
     786             :                 else
     787        1139 :                     aPropertyMap.setProperty(PROP_Handles, uno::Sequence<OUString>(0));
     788             :             }
     789       15895 :             else if (aLine == "MirroredX")
     790             :             {
     791        3179 :                 aStream.ReadLine(aLine);
     792        3179 :                 if (aLine == "true" || aLine == "false")
     793             :                 {
     794        3179 :                     aPropertyMap.setProperty(PROP_MirroredX, aLine == "true");
     795             :                 }
     796             :                 else
     797             :                     SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredX parameter");
     798             :             }
     799       12716 :             else if (aLine == "MirroredY")
     800             :             {
     801        3179 :                 aStream.ReadLine(aLine);
     802        3179 :                 if (aLine == "true" || aLine == "false")
     803             :                 {
     804        3179 :                     aPropertyMap.setProperty(PROP_MirroredY, aLine == "true");
     805             :                 }
     806             :                 else
     807             :                     SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredY parameter");
     808             :             }
     809        9537 :             else if (aLine == "Path")
     810             :             {
     811        3179 :                 aStream.ReadLine(aLine);
     812        3179 :                 OString aExpectedPrefix("([]com.sun.star.beans.PropertyValue) { ");
     813             :                 assert(aLine.startsWith(aExpectedPrefix));
     814             : 
     815        6358 :                 std::vector<beans::PropertyValue> aPathValue;
     816        6358 :                 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     817        3179 :                 lcl_parsePath(aPathValue, aValue);
     818        6358 :                 aPropertyMap.setProperty(PROP_Path, comphelper::containerToSequence(aPathValue));
     819             :             }
     820        6358 :             else if (aLine == "Type")
     821             :             {
     822             :                 // Just ignore the line here, we already know the correct type.
     823        3179 :                 aStream.ReadLine(aLine);
     824        3179 :                 aPropertyMap.setProperty(PROP_Type, "ooxml-" + aName);
     825             :             }
     826        3179 :             else if (aLine == "ViewBox")
     827             :             {
     828        3179 :                 aStream.ReadLine(aLine);
     829        3179 :                 OString aExpectedPrefix("(com.sun.star.awt.Rectangle) { ");
     830             :                 assert(aLine.startsWith(aExpectedPrefix));
     831             : 
     832        6358 :                 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     833        6358 :                 aPropertyMap.setProperty(PROP_ViewBox, lcl_parseRectangle(aValue));
     834             :             }
     835             :             else
     836             :                 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unhandled line: " << aLine);
     837             :         }
     838       28611 :         bNotDone = aStream.ReadLine(aLine);
     839             :     }
     840          34 :     maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap;
     841          17 : }
     842             : 
     843             : }
     844         246 : }
     845             : 
     846             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11